incanto 0.36.0 → 0.36.1
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.
- package/dist/2d.js +1 -1
- package/dist/3d.js +1 -1
- package/dist/{create-game-WmNFluFz.js → create-game-D-StzrTj.js} +1 -1
- package/dist/{create-game-BBD3iUFZ.js → create-game-DnOu2aAa.js} +1 -1
- package/dist/editor.js +1 -1
- package/dist/index.js +1 -1
- package/dist/react.js +1 -1
- package/dist/{teardown-ByzfDPyu.js → teardown-CCtAMDLB.js} +26 -1
- package/editor/assets/{agent8-BfxUNrEe.js → agent8-tvTJH3IX.js} +1 -1
- package/editor/assets/{debug-wSa-vYHO.js → debug-CPbraUYm.js} +1 -1
- package/editor/assets/{index-BkIuXIjp.js → index-DPJkbebq.js} +61 -61
- package/editor/index.html +1 -1
- package/package.json +1 -1
- package/templates-app/beacon-isle-3d/package.json +1 -1
- package/templates-app/tps-3d/package.json +1 -1
- package/templates-app/village-quest-3d/package.json +1 -1
|
@@ -4103,12 +4103,12 @@ void main() {
|
|
|
4103
4103
|
|
|
4104
4104
|
}
|
|
4105
4105
|
|
|
4106
|
-
}`,om=class{constructor(){this.texture=null,this.mesh=null,this.depthNear=0,this.depthFar=0}init(e,t){if(this.texture===null){let n=new tl(e.texture);(e.depthNear!==t.depthNear||e.depthFar!==t.depthFar)&&(this.depthNear=e.depthNear,this.depthFar=e.depthFar),this.texture=n}}getMesh(e){if(this.texture!==null&&this.mesh===null){let t=e.cameras[0].viewport,n=new vl({vertexShader:im,fragmentShader:am,uniforms:{depthColor:{value:this.texture},depthWidth:{value:t.z},depthHeight:{value:t.w}}});this.mesh=new Ys(new cl(20,20),n)}return this.mesh}reset(){this.texture=null,this.mesh=null}getDepthTexture(){return this.texture}},sm=class extends qi{constructor(e,t){super();let n=this,r=null,i=1,a=null,o=`local-floor`,s=1,c=null,l=null,u=null,d=null,f=null,p=null,m=typeof XRWebGLBinding<`u`,h=new om,g={},_=t.getContextAttributes(),v=null,y=null,b=[],x=[],S=new V,C=null,w=new pu;w.viewport=new Ra;let T=new pu;T.viewport=new Ra;let E=[w,T],D=new Ou,O=null,k=null;this.cameraAutoUpdate=!0,this.enabled=!1,this.isPresenting=!1,this.getController=function(e){let t=b[e];return t===void 0&&(t=new yo,b[e]=t),t.getTargetRaySpace()},this.getControllerGrip=function(e){let t=b[e];return t===void 0&&(t=new yo,b[e]=t),t.getGripSpace()},this.getHand=function(e){let t=b[e];return t===void 0&&(t=new yo,b[e]=t),t.getHandSpace()};function A(e){let t=x.indexOf(e.inputSource);if(t===-1)return;let n=b[t];n!==void 0&&(n.update(e.inputSource,e.frame,c||a),n.dispatchEvent({type:e.type,data:e.inputSource}))}function ee(){r.removeEventListener(`select`,A),r.removeEventListener(`selectstart`,A),r.removeEventListener(`selectend`,A),r.removeEventListener(`squeeze`,A),r.removeEventListener(`squeezestart`,A),r.removeEventListener(`squeezeend`,A),r.removeEventListener(`end`,ee),r.removeEventListener(`inputsourceschange`,te);for(let e=0;e<b.length;e++){let t=x[e];t!==null&&(x[e]=null,b[e].disconnect(t))}O=null,k=null,h.reset();for(let e in g)delete g[e];e.setRenderTarget(v),f=null,d=null,u=null,r=null,y=null,se.stop(),n.isPresenting=!1,e.setPixelRatio(C),e.setSize(S.width,S.height,!1),n.dispatchEvent({type:`sessionend`})}this.setFramebufferScaleFactor=function(e){i=e,n.isPresenting===!0&&z(`WebXRManager: Cannot change framebuffer scale while presenting.`)},this.setReferenceSpaceType=function(e){o=e,n.isPresenting===!0&&z(`WebXRManager: Cannot change reference space type while presenting.`)},this.getReferenceSpace=function(){return c||a},this.setReferenceSpace=function(e){c=e},this.getBaseLayer=function(){return d===null?f:d},this.getBinding=function(){return u===null&&m&&(u=new XRWebGLBinding(r,t)),u},this.getFrame=function(){return p},this.getSession=function(){return r},this.setSession=async function(l){if(r=l,r!==null){if(v=e.getRenderTarget(),r.addEventListener(`select`,A),r.addEventListener(`selectstart`,A),r.addEventListener(`selectend`,A),r.addEventListener(`squeeze`,A),r.addEventListener(`squeezestart`,A),r.addEventListener(`squeezeend`,A),r.addEventListener(`end`,ee),r.addEventListener(`inputsourceschange`,te),_.xrCompatible!==!0&&await t.makeXRCompatible(),C=e.getPixelRatio(),e.getSize(S),m&&`createProjectionLayer`in XRWebGLBinding.prototype){let n=null,a=null,o=null;_.depth&&(o=_.stencil?t.DEPTH24_STENCIL8:t.DEPTH_COMPONENT24,n=_.stencil?Er:Tr,a=_.stencil?yr:mr);let s={colorFormat:t.RGBA8,depthFormat:o,scaleFactor:i};u=this.getBinding(),d=u.createProjectionLayer(s),r.updateRenderState({layers:[d]}),e.setPixelRatio(1),e.setSize(d.textureWidth,d.textureHeight,!1),y=new Ba(d.textureWidth,d.textureHeight,{format:wr,type:lr,depthTexture:new $c(d.textureWidth,d.textureHeight,a,void 0,void 0,void 0,void 0,void 0,void 0,n),stencilBuffer:_.stencil,colorSpace:e.outputColorSpace,samples:_.antialias?4:0,resolveDepthBuffer:d.ignoreDepthValues===!1,resolveStencilBuffer:d.ignoreDepthValues===!1})}else{let n={antialias:_.antialias,alpha:!0,depth:_.depth,stencil:_.stencil,framebufferScaleFactor:i};f=new XRWebGLLayer(r,t,n),r.updateRenderState({baseLayer:f}),e.setPixelRatio(1),e.setSize(f.framebufferWidth,f.framebufferHeight,!1),y=new Ba(f.framebufferWidth,f.framebufferHeight,{format:wr,type:lr,colorSpace:e.outputColorSpace,stencilBuffer:_.stencil,resolveDepthBuffer:f.ignoreDepthValues===!1,resolveStencilBuffer:f.ignoreDepthValues===!1})}y.isXRRenderTarget=!0,this.setFoveation(s),c=null,a=await r.requestReferenceSpace(o),se.setContext(r),se.start(),n.isPresenting=!0,n.dispatchEvent({type:`sessionstart`})}},this.getEnvironmentBlendMode=function(){if(r!==null)return r.environmentBlendMode},this.getDepthTexture=function(){return h.getDepthTexture()};function te(e){for(let t=0;t<e.removed.length;t++){let n=e.removed[t],r=x.indexOf(n);r>=0&&(x[r]=null,b[r].disconnect(n))}for(let t=0;t<e.added.length;t++){let n=e.added[t],r=x.indexOf(n);if(r===-1){for(let e=0;e<b.length;e++)if(e>=x.length){x.push(n),r=e;break}else if(x[e]===null){x[e]=n,r=e;break}if(r===-1)break}let i=b[r];i&&i.connect(n)}}let ne=new U,re=new U;function j(e,t,n){ne.setFromMatrixPosition(t.matrixWorld),re.setFromMatrixPosition(n.matrixWorld);let r=ne.distanceTo(re),i=t.projectionMatrix.elements,a=n.projectionMatrix.elements,o=i[14]/(i[10]-1),s=i[14]/(i[10]+1),c=(i[9]+1)/i[5],l=(i[9]-1)/i[5],u=(i[8]-1)/i[0],d=(a[8]+1)/a[0],f=o*u,p=o*d,m=r/(-u+d),h=m*-u;if(t.matrixWorld.decompose(e.position,e.quaternion,e.scale),e.translateX(h),e.translateZ(m),e.matrixWorld.compose(e.position,e.quaternion,e.scale),e.matrixWorldInverse.copy(e.matrixWorld).invert(),i[10]===-1)e.projectionMatrix.copy(t.projectionMatrix),e.projectionMatrixInverse.copy(t.projectionMatrixInverse);else{let t=o+m,n=s+m,i=f-h,a=p+(r-h),u=c*s/n*t,d=l*s/n*t;e.projectionMatrix.makePerspective(i,a,u,d,t,n),e.projectionMatrixInverse.copy(e.projectionMatrix).invert()}}function ie(e,t){t===null?e.matrixWorld.copy(e.matrix):e.matrixWorld.multiplyMatrices(t.matrixWorld,e.matrix),e.matrixWorldInverse.copy(e.matrixWorld).invert()}this.updateCamera=function(e){if(r===null)return;let t=e.near,n=e.far;h.texture!==null&&(h.depthNear>0&&(t=h.depthNear),h.depthFar>0&&(n=h.depthFar)),D.near=T.near=w.near=t,D.far=T.far=w.far=n,(O!==D.near||k!==D.far)&&(r.updateRenderState({depthNear:D.near,depthFar:D.far}),O=D.near,k=D.far),D.layers.mask=e.layers.mask|6,w.layers.mask=D.layers.mask&-5,T.layers.mask=D.layers.mask&-3;let i=e.parent,a=D.cameras;ie(D,i);for(let e=0;e<a.length;e++)ie(a[e],i);a.length===2?j(D,w,T):D.projectionMatrix.copy(w.projectionMatrix),ae(e,D,i)};function ae(e,t,n){n===null?e.matrix.copy(t.matrixWorld):(e.matrix.copy(n.matrixWorld),e.matrix.invert(),e.matrix.multiply(t.matrixWorld)),e.matrix.decompose(e.position,e.quaternion,e.scale),e.updateMatrixWorld(!0),e.projectionMatrix.copy(t.projectionMatrix),e.projectionMatrixInverse.copy(t.projectionMatrixInverse),e.isPerspectiveCamera&&(e.fov=Zi*2*Math.atan(1/e.projectionMatrix.elements[5]),e.zoom=1)}this.getCamera=function(){return D},this.getFoveation=function(){if(!(d===null&&f===null))return s},this.setFoveation=function(e){s=e,d!==null&&(d.fixedFoveation=e),f!==null&&f.fixedFoveation!==void 0&&(f.fixedFoveation=e)},this.hasDepthSensing=function(){return h.texture!==null},this.getDepthSensingMesh=function(){return h.getMesh(D)},this.getCameraTexture=function(e){return g[e]};let M=null;function oe(t,i){if(l=i.getViewerPose(c||a),p=i,l!==null){let t=l.views;f!==null&&(e.setRenderTargetFramebuffer(y,f.framebuffer),e.setRenderTarget(y));let i=!1;t.length!==D.cameras.length&&(D.cameras.length=0,i=!0);for(let n=0;n<t.length;n++){let r=t[n],a=null;if(f!==null)a=f.getViewport(r);else{let t=u.getViewSubImage(d,r);a=t.viewport,n===0&&(e.setRenderTargetTextures(y,t.colorTexture,t.depthStencilTexture),e.setRenderTarget(y))}let o=E[n];o===void 0&&(o=new pu,o.layers.enable(n),o.viewport=new Ra,E[n]=o),o.matrix.fromArray(r.transform.matrix),o.matrix.decompose(o.position,o.quaternion,o.scale),o.projectionMatrix.fromArray(r.projectionMatrix),o.projectionMatrixInverse.copy(o.projectionMatrix).invert(),o.viewport.set(a.x,a.y,a.width,a.height),n===0&&(D.matrix.copy(o.matrix),D.matrix.decompose(D.position,D.quaternion,D.scale)),i===!0&&D.cameras.push(o)}let a=r.enabledFeatures;if(a&&a.includes(`depth-sensing`)&&r.depthUsage==`gpu-optimized`&&m){u=n.getBinding();let e=u.getDepthInformation(t[0]);e&&e.isValid&&e.texture&&h.init(e,r.renderState)}if(a&&a.includes(`camera-access`)&&m){e.state.unbindTexture(),u=n.getBinding();for(let e=0;e<t.length;e++){let n=t[e].camera;if(n){let e=g[n];e||(e=new tl,g[n]=e);let t=u.getCameraImage(n);e.sourceTexture=t}}}}for(let e=0;e<b.length;e++){let t=x[e],n=b[e];t!==null&&n!==void 0&&n.update(t,i,c||a)}M&&M(t,i),i.detectedPlanes&&n.dispatchEvent({type:`planesdetected`,data:i}),p=null}let se=new $u;se.setAnimationLoop(oe),this.setAnimationLoop=function(e){M=e},this.dispose=function(){}}},cm=new G,lm=new W;lm.set(-1,0,0,0,1,0,0,0,1);function um(e,t){function n(e,t){e.matrixAutoUpdate===!0&&e.updateMatrix(),t.value.copy(e.matrix)}function r(t,n){n.color.getRGB(t.fogColor.value,ml(e)),n.isFog?(t.fogNear.value=n.near,t.fogFar.value=n.far):n.isFogExp2&&(t.fogDensity.value=n.density)}function i(e,t,n,r,i){t.isNodeMaterial?t.uniformsNeedUpdate=!1:t.isMeshBasicMaterial?a(e,t):t.isMeshLambertMaterial?(a(e,t),t.envMap&&(e.envMapIntensity.value=t.envMapIntensity)):t.isMeshToonMaterial?(a(e,t),d(e,t)):t.isMeshPhongMaterial?(a(e,t),u(e,t),t.envMap&&(e.envMapIntensity.value=t.envMapIntensity)):t.isMeshStandardMaterial?(a(e,t),f(e,t),t.isMeshPhysicalMaterial&&p(e,t,i)):t.isMeshMatcapMaterial?(a(e,t),m(e,t)):t.isMeshDepthMaterial?a(e,t):t.isMeshDistanceMaterial?(a(e,t),h(e,t)):t.isMeshNormalMaterial?a(e,t):t.isLineBasicMaterial?(o(e,t),t.isLineDashedMaterial&&s(e,t)):t.isPointsMaterial?c(e,t,n,r):t.isSpriteMaterial?l(e,t):t.isShadowMaterial?(e.color.value.copy(t.color),e.opacity.value=t.opacity):t.isShaderMaterial&&(t.uniformsNeedUpdate=!1)}function a(e,r){e.opacity.value=r.opacity,r.color&&e.diffuse.value.copy(r.color),r.emissive&&e.emissive.value.copy(r.emissive).multiplyScalar(r.emissiveIntensity),r.map&&(e.map.value=r.map,n(r.map,e.mapTransform)),r.alphaMap&&(e.alphaMap.value=r.alphaMap,n(r.alphaMap,e.alphaMapTransform)),r.bumpMap&&(e.bumpMap.value=r.bumpMap,n(r.bumpMap,e.bumpMapTransform),e.bumpScale.value=r.bumpScale,r.side===1&&(e.bumpScale.value*=-1)),r.normalMap&&(e.normalMap.value=r.normalMap,n(r.normalMap,e.normalMapTransform),e.normalScale.value.copy(r.normalScale),r.side===1&&e.normalScale.value.negate()),r.displacementMap&&(e.displacementMap.value=r.displacementMap,n(r.displacementMap,e.displacementMapTransform),e.displacementScale.value=r.displacementScale,e.displacementBias.value=r.displacementBias),r.emissiveMap&&(e.emissiveMap.value=r.emissiveMap,n(r.emissiveMap,e.emissiveMapTransform)),r.specularMap&&(e.specularMap.value=r.specularMap,n(r.specularMap,e.specularMapTransform)),r.alphaTest>0&&(e.alphaTest.value=r.alphaTest);let i=t.get(r),a=i.envMap,o=i.envMapRotation;a&&(e.envMap.value=a,e.envMapRotation.value.setFromMatrix4(cm.makeRotationFromEuler(o)).transpose(),a.isCubeTexture&&a.isRenderTargetTexture===!1&&e.envMapRotation.value.premultiply(lm),e.reflectivity.value=r.reflectivity,e.ior.value=r.ior,e.refractionRatio.value=r.refractionRatio),r.lightMap&&(e.lightMap.value=r.lightMap,e.lightMapIntensity.value=r.lightMapIntensity,n(r.lightMap,e.lightMapTransform)),r.aoMap&&(e.aoMap.value=r.aoMap,e.aoMapIntensity.value=r.aoMapIntensity,n(r.aoMap,e.aoMapTransform))}function o(e,t){e.diffuse.value.copy(t.color),e.opacity.value=t.opacity,t.map&&(e.map.value=t.map,n(t.map,e.mapTransform))}function s(e,t){e.dashSize.value=t.dashSize,e.totalSize.value=t.dashSize+t.gapSize,e.scale.value=t.scale}function c(e,t,r,i){e.diffuse.value.copy(t.color),e.opacity.value=t.opacity,e.size.value=t.size*r,e.scale.value=i*.5,t.map&&(e.map.value=t.map,n(t.map,e.uvTransform)),t.alphaMap&&(e.alphaMap.value=t.alphaMap,n(t.alphaMap,e.alphaMapTransform)),t.alphaTest>0&&(e.alphaTest.value=t.alphaTest)}function l(e,t){e.diffuse.value.copy(t.color),e.opacity.value=t.opacity,e.rotation.value=t.rotation,t.map&&(e.map.value=t.map,n(t.map,e.mapTransform)),t.alphaMap&&(e.alphaMap.value=t.alphaMap,n(t.alphaMap,e.alphaMapTransform)),t.alphaTest>0&&(e.alphaTest.value=t.alphaTest)}function u(e,t){e.specular.value.copy(t.specular),e.shininess.value=Math.max(t.shininess,1e-4)}function d(e,t){t.gradientMap&&(e.gradientMap.value=t.gradientMap)}function f(e,t){e.metalness.value=t.metalness,t.metalnessMap&&(e.metalnessMap.value=t.metalnessMap,n(t.metalnessMap,e.metalnessMapTransform)),e.roughness.value=t.roughness,t.roughnessMap&&(e.roughnessMap.value=t.roughnessMap,n(t.roughnessMap,e.roughnessMapTransform)),t.envMap&&(e.envMapIntensity.value=t.envMapIntensity)}function p(e,t,r){e.ior.value=t.ior,t.sheen>0&&(e.sheenColor.value.copy(t.sheenColor).multiplyScalar(t.sheen),e.sheenRoughness.value=t.sheenRoughness,t.sheenColorMap&&(e.sheenColorMap.value=t.sheenColorMap,n(t.sheenColorMap,e.sheenColorMapTransform)),t.sheenRoughnessMap&&(e.sheenRoughnessMap.value=t.sheenRoughnessMap,n(t.sheenRoughnessMap,e.sheenRoughnessMapTransform))),t.clearcoat>0&&(e.clearcoat.value=t.clearcoat,e.clearcoatRoughness.value=t.clearcoatRoughness,t.clearcoatMap&&(e.clearcoatMap.value=t.clearcoatMap,n(t.clearcoatMap,e.clearcoatMapTransform)),t.clearcoatRoughnessMap&&(e.clearcoatRoughnessMap.value=t.clearcoatRoughnessMap,n(t.clearcoatRoughnessMap,e.clearcoatRoughnessMapTransform)),t.clearcoatNormalMap&&(e.clearcoatNormalMap.value=t.clearcoatNormalMap,n(t.clearcoatNormalMap,e.clearcoatNormalMapTransform),e.clearcoatNormalScale.value.copy(t.clearcoatNormalScale),t.side===1&&e.clearcoatNormalScale.value.negate())),t.dispersion>0&&(e.dispersion.value=t.dispersion),t.iridescence>0&&(e.iridescence.value=t.iridescence,e.iridescenceIOR.value=t.iridescenceIOR,e.iridescenceThicknessMinimum.value=t.iridescenceThicknessRange[0],e.iridescenceThicknessMaximum.value=t.iridescenceThicknessRange[1],t.iridescenceMap&&(e.iridescenceMap.value=t.iridescenceMap,n(t.iridescenceMap,e.iridescenceMapTransform)),t.iridescenceThicknessMap&&(e.iridescenceThicknessMap.value=t.iridescenceThicknessMap,n(t.iridescenceThicknessMap,e.iridescenceThicknessMapTransform))),t.transmission>0&&(e.transmission.value=t.transmission,e.transmissionSamplerMap.value=r.texture,e.transmissionSamplerSize.value.set(r.width,r.height),t.transmissionMap&&(e.transmissionMap.value=t.transmissionMap,n(t.transmissionMap,e.transmissionMapTransform)),e.thickness.value=t.thickness,t.thicknessMap&&(e.thicknessMap.value=t.thicknessMap,n(t.thicknessMap,e.thicknessMapTransform)),e.attenuationDistance.value=t.attenuationDistance,e.attenuationColor.value.copy(t.attenuationColor)),t.anisotropy>0&&(e.anisotropyVector.value.set(t.anisotropy*Math.cos(t.anisotropyRotation),t.anisotropy*Math.sin(t.anisotropyRotation)),t.anisotropyMap&&(e.anisotropyMap.value=t.anisotropyMap,n(t.anisotropyMap,e.anisotropyMapTransform))),e.specularIntensity.value=t.specularIntensity,e.specularColor.value.copy(t.specularColor),t.specularColorMap&&(e.specularColorMap.value=t.specularColorMap,n(t.specularColorMap,e.specularColorMapTransform)),t.specularIntensityMap&&(e.specularIntensityMap.value=t.specularIntensityMap,n(t.specularIntensityMap,e.specularIntensityMapTransform))}function m(e,t){t.matcap&&(e.matcap.value=t.matcap)}function h(e,n){let r=t.get(n).light;e.referencePosition.value.setFromMatrixPosition(r.matrixWorld),e.nearDistance.value=r.shadow.camera.near,e.farDistance.value=r.shadow.camera.far}return{refreshFogUniforms:r,refreshMaterialUniforms:i}}function dm(e,t,n,r){let i={},a={},o=[],s=e.getParameter(e.MAX_UNIFORM_BUFFER_BINDINGS);function c(e,t){let n=t.program;r.uniformBlockBinding(e,n)}function l(e,n){let o=i[e.id];o===void 0&&(m(e),o=u(e),i[e.id]=o,e.addEventListener(`dispose`,g));let s=n.program;r.updateUBOMapping(e,s);let c=t.render.frame;a[e.id]!==c&&(f(e),a[e.id]=c)}function u(t){let n=d();t.__bindingPointIndex=n;let r=e.createBuffer(),i=t.__size,a=t.usage;return e.bindBuffer(e.UNIFORM_BUFFER,r),e.bufferData(e.UNIFORM_BUFFER,i,a),e.bindBuffer(e.UNIFORM_BUFFER,null),e.bindBufferBase(e.UNIFORM_BUFFER,n,r),r}function d(){for(let e=0;e<s;e++)if(o.indexOf(e)===-1)return o.push(e),e;return B(`WebGLRenderer: Maximum number of simultaneously usable uniforms groups reached.`),0}function f(t){let n=i[t.id],r=t.uniforms,a=t.__cache;e.bindBuffer(e.UNIFORM_BUFFER,n);for(let t=0,n=r.length;t<n;t++){let n=Array.isArray(r[t])?r[t]:[r[t]];for(let r=0,i=n.length;r<i;r++){let i=n[r];if(p(i,t,r,a)===!0){let t=i.__offset,n=Array.isArray(i.value)?i.value:[i.value],r=0;for(let a=0;a<n.length;a++){let o=n[a],s=h(o);typeof o==`number`||typeof o==`boolean`?(i.__data[0]=o,e.bufferSubData(e.UNIFORM_BUFFER,t+r,i.__data)):o.isMatrix3?(i.__data[0]=o.elements[0],i.__data[1]=o.elements[1],i.__data[2]=o.elements[2],i.__data[3]=0,i.__data[4]=o.elements[3],i.__data[5]=o.elements[4],i.__data[6]=o.elements[5],i.__data[7]=0,i.__data[8]=o.elements[6],i.__data[9]=o.elements[7],i.__data[10]=o.elements[8],i.__data[11]=0):ArrayBuffer.isView(o)?i.__data.set(new o.constructor(o.buffer,o.byteOffset,i.__data.length)):(o.toArray(i.__data,r),r+=s.storage/Float32Array.BYTES_PER_ELEMENT)}e.bufferSubData(e.UNIFORM_BUFFER,t,i.__data)}}}e.bindBuffer(e.UNIFORM_BUFFER,null)}function p(e,t,n,r){let i=e.value,a=t+`_`+n;if(r[a]===void 0)return typeof i==`number`||typeof i==`boolean`?r[a]=i:ArrayBuffer.isView(i)?r[a]=i.slice():r[a]=i.clone(),!0;{let e=r[a];if(typeof i==`number`||typeof i==`boolean`){if(e!==i)return r[a]=i,!0}else if(ArrayBuffer.isView(i))return!0;else if(e.equals(i)===!1)return e.copy(i),!0}return!1}function m(e){let t=e.uniforms,n=0;for(let e=0,r=t.length;e<r;e++){let r=Array.isArray(t[e])?t[e]:[t[e]];for(let e=0,t=r.length;e<t;e++){let t=r[e],i=Array.isArray(t.value)?t.value:[t.value];for(let e=0,r=i.length;e<r;e++){let r=i[e],a=h(r),o=n%16,s=o%a.boundary,c=o+s;n+=s,c!==0&&16-c<a.storage&&(n+=16-c),t.__data=new Float32Array(a.storage/Float32Array.BYTES_PER_ELEMENT),t.__offset=n,n+=a.storage}}}let r=n%16;return r>0&&(n+=16-r),e.__size=n,e.__cache={},this}function h(e){let t={boundary:0,storage:0};return typeof e==`number`||typeof e==`boolean`?(t.boundary=4,t.storage=4):e.isVector2?(t.boundary=8,t.storage=8):e.isVector3||e.isColor?(t.boundary=16,t.storage=12):e.isVector4?(t.boundary=16,t.storage=16):e.isMatrix3?(t.boundary=48,t.storage=48):e.isMatrix4?(t.boundary=64,t.storage=64):e.isTexture?z(`WebGLRenderer: Texture samplers can not be part of an uniforms group.`):ArrayBuffer.isView(e)?(t.boundary=16,t.storage=e.byteLength):z(`WebGLRenderer: Unsupported uniform value type.`,e),t}function g(t){let n=t.target;n.removeEventListener(`dispose`,g);let r=o.indexOf(n.__bindingPointIndex);o.splice(r,1),e.deleteBuffer(i[n.id]),delete i[n.id],delete a[n.id]}function _(){for(let t in i)e.deleteBuffer(i[t]);o=[],i={},a={}}return{bind:c,update:l,dispose:_}}var fm=new Uint16Array([12469,15057,12620,14925,13266,14620,13807,14376,14323,13990,14545,13625,14713,13328,14840,12882,14931,12528,14996,12233,15039,11829,15066,11525,15080,11295,15085,10976,15082,10705,15073,10495,13880,14564,13898,14542,13977,14430,14158,14124,14393,13732,14556,13410,14702,12996,14814,12596,14891,12291,14937,11834,14957,11489,14958,11194,14943,10803,14921,10506,14893,10278,14858,9960,14484,14039,14487,14025,14499,13941,14524,13740,14574,13468,14654,13106,14743,12678,14818,12344,14867,11893,14889,11509,14893,11180,14881,10751,14852,10428,14812,10128,14765,9754,14712,9466,14764,13480,14764,13475,14766,13440,14766,13347,14769,13070,14786,12713,14816,12387,14844,11957,14860,11549,14868,11215,14855,10751,14825,10403,14782,10044,14729,9651,14666,9352,14599,9029,14967,12835,14966,12831,14963,12804,14954,12723,14936,12564,14917,12347,14900,11958,14886,11569,14878,11247,14859,10765,14828,10401,14784,10011,14727,9600,14660,9289,14586,8893,14508,8533,15111,12234,15110,12234,15104,12216,15092,12156,15067,12010,15028,11776,14981,11500,14942,11205,14902,10752,14861,10393,14812,9991,14752,9570,14682,9252,14603,8808,14519,8445,14431,8145,15209,11449,15208,11451,15202,11451,15190,11438,15163,11384,15117,11274,15055,10979,14994,10648,14932,10343,14871,9936,14803,9532,14729,9218,14645,8742,14556,8381,14461,8020,14365,7603,15273,10603,15272,10607,15267,10619,15256,10631,15231,10614,15182,10535,15118,10389,15042,10167,14963,9787,14883,9447,14800,9115,14710,8665,14615,8318,14514,7911,14411,7507,14279,7198,15314,9675,15313,9683,15309,9712,15298,9759,15277,9797,15229,9773,15166,9668,15084,9487,14995,9274,14898,8910,14800,8539,14697,8234,14590,7790,14479,7409,14367,7067,14178,6621,15337,8619,15337,8631,15333,8677,15325,8769,15305,8871,15264,8940,15202,8909,15119,8775,15022,8565,14916,8328,14804,8009,14688,7614,14569,7287,14448,6888,14321,6483,14088,6171,15350,7402,15350,7419,15347,7480,15340,7613,15322,7804,15287,7973,15229,8057,15148,8012,15046,7846,14933,7611,14810,7357,14682,7069,14552,6656,14421,6316,14251,5948,14007,5528,15356,5942,15356,5977,15353,6119,15348,6294,15332,6551,15302,6824,15249,7044,15171,7122,15070,7050,14949,6861,14818,6611,14679,6349,14538,6067,14398,5651,14189,5311,13935,4958,15359,4123,15359,4153,15356,4296,15353,4646,15338,5160,15311,5508,15263,5829,15188,6042,15088,6094,14966,6001,14826,5796,14678,5543,14527,5287,14377,4985,14133,4586,13869,4257,15360,1563,15360,1642,15358,2076,15354,2636,15341,3350,15317,4019,15273,4429,15203,4732,15105,4911,14981,4932,14836,4818,14679,4621,14517,4386,14359,4156,14083,3795,13808,3437,15360,122,15360,137,15358,285,15355,636,15344,1274,15322,2177,15281,2765,15215,3223,15120,3451,14995,3569,14846,3567,14681,3466,14511,3305,14344,3121,14037,2800,13753,2467,15360,0,15360,1,15359,21,15355,89,15346,253,15325,479,15287,796,15225,1148,15133,1492,15008,1749,14856,1882,14685,1886,14506,1783,14324,1608,13996,1398,13702,1183]),pm=null;function mm(){return pm===null&&(pm=new lc(fm,16,16,kr,gr),pm.name=`DFG_LUT`,pm.minFilter=or,pm.magFilter=or,pm.wrapS=tr,pm.wrapT=tr,pm.generateMipmaps=!1,pm.needsUpdate=!0),pm}var hm=class{constructor(e={}){let{canvas:t=zi(),context:n=null,depth:r=!0,stencil:i=!1,alpha:a=!1,antialias:o=!1,premultipliedAlpha:s=!0,preserveDrawingBuffer:c=!1,powerPreference:l=`default`,failIfMajorPerformanceCaveat:u=!1,reversedDepthBuffer:d=!1,outputBufferType:f=lr}=e;this.isWebGLRenderer=!0;let p;if(n!==null){if(typeof WebGLRenderingContext<`u`&&n instanceof WebGLRenderingContext)throw Error(`THREE.WebGLRenderer: WebGL 1 is not supported since r163.`);p=n.getContextAttributes().alpha}else p=a;let m=f,h=new Set([jr,Ar,Or]),g=new Set([lr,mr,fr,yr,_r,vr]),_=new Uint32Array(4),v=new Int32Array(4),y=new U,b=null,x=null,S=[],C=[],w=null;this.domElement=t,this.debug={checkShaderErrors:!0,onShaderError:null},this.autoClear=!0,this.autoClearColor=!0,this.autoClearDepth=!0,this.autoClearStencil=!0,this.sortObjects=!0,this.clippingPlanes=[],this.localClippingEnabled=!1,this.toneMapping=0,this.toneMappingExposure=1,this.transmissionResolutionScale=1;let T=this,E=!1,D=null;this._outputColorSpace=Oi;let O=0,k=0,A=null,ee=-1,te=null,ne=new Ra,re=new Ra,j=null,ie=new K(0),ae=0,M=t.width,oe=t.height,se=1,ce=null,le=null,ue=new Ra(0,0,M,oe),de=new Ra(0,0,M,oe),fe=!1,pe=new kc,me=!1,he=!1,ge=new G,_e=new U,ve=new Ra,ye={background:null,fog:null,environment:null,overrideMaterial:null,isScene:!0},N=!1;function P(){return A===null?se:1}let F=n;function be(e,n){return t.getContext(e,n)}try{let e={alpha:!0,depth:r,stencil:i,antialias:o,premultipliedAlpha:s,preserveDrawingBuffer:c,powerPreference:l,failIfMajorPerformanceCaveat:u};if(`setAttribute`in t&&t.setAttribute(`data-engine`,`three.js r184`),t.addEventListener(`webglcontextlost`,We,!1),t.addEventListener(`webglcontextrestored`,R,!1),t.addEventListener(`webglcontextcreationerror`,Ge,!1),F===null){let t=`webgl2`;if(F=be(t,e),F===null)throw be(t)?Error(`Error creating WebGL context with your selected attributes.`):Error(`Error creating WebGL context.`)}}catch(e){throw B(`WebGLRenderer: `+e.message),e}let xe,Se,I,Ce,L,we,Te,Ee,De,Oe,ke,Ae,je,Me,Ne,Pe,Fe,Ie,Le,Re,ze,Be,Ve;function He(){xe=new Md(F),xe.init(),ze=new rm(F,xe),Se=new cd(F,xe,e,ze),I=new tm(F,xe),Se.reversedDepthBuffer&&d&&I.buffers.depth.setReversed(!0),Ce=new Fd(F),L=new Fp,we=new nm(F,xe,I,L,Se,ze,Ce),Te=new jd(T),Ee=new ed(F),Be=new od(F,Ee),De=new Nd(F,Ee,Ce,Be),Oe=new Ld(F,De,Ee,Be,Ce),Ie=new Id(F,Se,we),Ne=new ld(L),ke=new Pp(T,Te,xe,Se,Be,Ne),Ae=new um(T,L),je=new zp,Me=new Kp(xe),Fe=new ad(T,Te,I,Oe,p,s),Pe=new em(T,Oe,Se),Ve=new dm(F,Ce,Se,I),Le=new sd(F,xe,Ce),Re=new Pd(F,xe,Ce),Ce.programs=ke.programs,T.capabilities=Se,T.extensions=xe,T.properties=L,T.renderLists=je,T.shadowMap=Pe,T.state=I,T.info=Ce}He(),m!==1009&&(w=new zd(m,t.width,t.height,r,i));let Ue=new sm(T,F);this.xr=Ue,this.getContext=function(){return F},this.getContextAttributes=function(){return F.getContextAttributes()},this.forceContextLoss=function(){let e=xe.get(`WEBGL_lose_context`);e&&e.loseContext()},this.forceContextRestore=function(){let e=xe.get(`WEBGL_lose_context`);e&&e.restoreContext()},this.getPixelRatio=function(){return se},this.setPixelRatio=function(e){e!==void 0&&(se=e,this.setSize(M,oe,!1))},this.getSize=function(e){return e.set(M,oe)},this.setSize=function(e,n,r=!0){if(Ue.isPresenting){z(`WebGLRenderer: Can't change size while VR device is presenting.`);return}M=e,oe=n,t.width=Math.floor(e*se),t.height=Math.floor(n*se),r===!0&&(t.style.width=e+`px`,t.style.height=n+`px`),w!==null&&w.setSize(t.width,t.height),this.setViewport(0,0,e,n)},this.getDrawingBufferSize=function(e){return e.set(M*se,oe*se).floor()},this.setDrawingBufferSize=function(e,n,r){M=e,oe=n,se=r,t.width=Math.floor(e*r),t.height=Math.floor(n*r),this.setViewport(0,0,e,n)},this.setEffects=function(e){if(m===1009){B(`THREE.WebGLRenderer: setEffects() requires outputBufferType set to HalfFloatType or FloatType.`);return}if(e){for(let t=0;t<e.length;t++)if(e[t].isOutputPass===!0){z(`THREE.WebGLRenderer: OutputPass is not needed in setEffects(). Tone mapping and color space conversion are applied automatically.`);break}}w.setEffects(e||[])},this.getCurrentViewport=function(e){return e.copy(ne)},this.getViewport=function(e){return e.copy(ue)},this.setViewport=function(e,t,n,r){e.isVector4?ue.set(e.x,e.y,e.z,e.w):ue.set(e,t,n,r),I.viewport(ne.copy(ue).multiplyScalar(se).round())},this.getScissor=function(e){return e.copy(de)},this.setScissor=function(e,t,n,r){e.isVector4?de.set(e.x,e.y,e.z,e.w):de.set(e,t,n,r),I.scissor(re.copy(de).multiplyScalar(se).round())},this.getScissorTest=function(){return fe},this.setScissorTest=function(e){I.setScissorTest(fe=e)},this.setOpaqueSort=function(e){ce=e},this.setTransparentSort=function(e){le=e},this.getClearColor=function(e){return e.copy(Fe.getClearColor())},this.setClearColor=function(){Fe.setClearColor(...arguments)},this.getClearAlpha=function(){return Fe.getClearAlpha()},this.setClearAlpha=function(){Fe.setClearAlpha(...arguments)},this.clear=function(e=!0,t=!0,n=!0){let r=0;if(e){let e=!1;if(A!==null){let t=A.texture.format;e=h.has(t)}if(e){let e=A.texture.type,t=g.has(e),n=Fe.getClearColor(),r=Fe.getClearAlpha(),i=n.r,a=n.g,o=n.b;t?(_[0]=i,_[1]=a,_[2]=o,_[3]=r,F.clearBufferuiv(F.COLOR,0,_)):(v[0]=i,v[1]=a,v[2]=o,v[3]=r,F.clearBufferiv(F.COLOR,0,v))}else r|=F.COLOR_BUFFER_BIT}t&&(r|=F.DEPTH_BUFFER_BIT,this.state.buffers.depth.setMask(!0)),n&&(r|=F.STENCIL_BUFFER_BIT,this.state.buffers.stencil.setMask(4294967295)),r!==0&&F.clear(r)},this.clearColor=function(){this.clear(!0,!1,!1)},this.clearDepth=function(){this.clear(!1,!0,!1)},this.clearStencil=function(){this.clear(!1,!1,!0)},this.setNodesHandler=function(e){e.setRenderer(this),D=e},this.dispose=function(){t.removeEventListener(`webglcontextlost`,We,!1),t.removeEventListener(`webglcontextrestored`,R,!1),t.removeEventListener(`webglcontextcreationerror`,Ge,!1),Fe.dispose(),je.dispose(),Me.dispose(),L.dispose(),Te.dispose(),Oe.dispose(),Be.dispose(),Ve.dispose(),ke.dispose(),Ue.dispose(),Ue.removeEventListener(`sessionstart`,Qe),Ue.removeEventListener(`sessionend`,$e),et.stop()};function We(e){e.preventDefault(),Hi(`WebGLRenderer: Context Lost.`),E=!0}function R(){Hi(`WebGLRenderer: Context Restored.`),E=!1;let e=Ce.autoReset,t=Pe.enabled,n=Pe.autoUpdate,r=Pe.needsUpdate,i=Pe.type;He(),Ce.autoReset=e,Pe.enabled=t,Pe.autoUpdate=n,Pe.needsUpdate=r,Pe.type=i}function Ge(e){B(`WebGLRenderer: A WebGL context could not be created. Reason: `,e.statusMessage)}function Ke(e){let t=e.target;t.removeEventListener(`dispose`,Ke),qe(t)}function qe(e){Je(e),L.remove(e)}function Je(e){let t=L.get(e).programs;t!==void 0&&(t.forEach(function(e){ke.releaseProgram(e)}),e.isShaderMaterial&&ke.releaseShaderCache(e))}this.renderBufferDirect=function(e,t,n,r,i,a){t===null&&(t=ye);let o=i.isMesh&&i.matrixWorld.determinant()<0,s=ut(e,t,n,r,i);I.setMaterial(r,o);let c=n.index,l=1;if(r.wireframe===!0){if(c=De.getWireframeAttribute(n),c===void 0)return;l=2}let u=n.drawRange,d=n.attributes.position,f=u.start*l,p=(u.start+u.count)*l;a!==null&&(f=Math.max(f,a.start*l),p=Math.min(p,(a.start+a.count)*l)),c===null?d!=null&&(f=Math.max(f,0),p=Math.min(p,d.count)):(f=Math.max(f,0),p=Math.min(p,c.count));let m=p-f;if(m<0||m===1/0)return;Be.setup(i,r,s,n,c);let h,g=Le;if(c!==null&&(h=Ee.get(c),g=Re,g.setIndex(h)),i.isMesh)r.wireframe===!0?(I.setLineWidth(r.wireframeLinewidth*P()),g.setMode(F.LINES)):g.setMode(F.TRIANGLES);else if(i.isLine){let e=r.linewidth;e===void 0&&(e=1),I.setLineWidth(e*P()),i.isLineSegments?g.setMode(F.LINES):i.isLineLoop?g.setMode(F.LINE_LOOP):g.setMode(F.LINE_STRIP)}else i.isPoints?g.setMode(F.POINTS):i.isSprite&&g.setMode(F.TRIANGLES);if(i.isBatchedMesh)if(xe.get(`WEBGL_multi_draw`))g.renderMultiDraw(i._multiDrawStarts,i._multiDrawCounts,i._multiDrawCount);else{let e=i._multiDrawStarts,t=i._multiDrawCounts,n=i._multiDrawCount,a=c?Ee.get(c).bytesPerElement:1,o=L.get(r).currentProgram.getUniforms();for(let r=0;r<n;r++)o.setValue(F,`_gl_DrawID`,r),g.render(e[r]/a,t[r])}else if(i.isInstancedMesh)g.renderInstances(f,m,i.count);else if(n.isInstancedBufferGeometry){let e=n._maxInstanceCount===void 0?1/0:n._maxInstanceCount,t=Math.min(n.instanceCount,e);g.renderInstances(f,m,t)}else g.render(f,m)};function Ye(e,t,n){e.transparent===!0&&e.side===2&&e.forceSinglePass===!1?(e.side=1,e.needsUpdate=!0,ot(e,t,n),e.side=0,e.needsUpdate=!0,ot(e,t,n),e.side=2):ot(e,t,n)}this.compile=function(e,t,n=null){n===null&&(n=e),x=Me.get(n),x.init(t),C.push(x),n.traverseVisible(function(e){e.isLight&&e.layers.test(t.layers)&&(x.pushLight(e),e.castShadow&&x.pushShadow(e))}),e!==n&&e.traverseVisible(function(e){e.isLight&&e.layers.test(t.layers)&&(x.pushLight(e),e.castShadow&&x.pushShadow(e))}),x.setupLights();let r=new Set;return e.traverse(function(e){if(!(e.isMesh||e.isPoints||e.isLine||e.isSprite))return;let t=e.material;if(t)if(Array.isArray(t))for(let i=0;i<t.length;i++){let a=t[i];Ye(a,n,e),r.add(a)}else Ye(t,n,e),r.add(t)}),x=C.pop(),r},this.compileAsync=function(e,t,n=null){let r=this.compile(e,t,n);return new Promise(t=>{function n(){if(r.forEach(function(e){L.get(e).currentProgram.isReady()&&r.delete(e)}),r.size===0){t(e);return}setTimeout(n,10)}xe.get(`KHR_parallel_shader_compile`)===null?setTimeout(n,10):n()})};let Xe=null;function Ze(e){Xe&&Xe(e)}function Qe(){et.stop()}function $e(){et.start()}let et=new $u;et.setAnimationLoop(Ze),typeof self<`u`&&et.setContext(self),this.setAnimationLoop=function(e){Xe=e,Ue.setAnimationLoop(e),e===null?et.stop():et.start()},Ue.addEventListener(`sessionstart`,Qe),Ue.addEventListener(`sessionend`,$e),this.render=function(e,t){if(t!==void 0&&t.isCamera!==!0){B(`WebGLRenderer.render: camera is not an instance of THREE.Camera.`);return}if(E===!0)return;D!==null&&D.renderStart(e,t);let n=Ue.enabled===!0&&Ue.isPresenting===!0,r=w!==null&&(A===null||n)&&w.begin(T,A);if(e.matrixWorldAutoUpdate===!0&&e.updateMatrixWorld(),t.parent===null&&t.matrixWorldAutoUpdate===!0&&t.updateMatrixWorld(),Ue.enabled===!0&&Ue.isPresenting===!0&&(w===null||w.isCompositing()===!1)&&(Ue.cameraAutoUpdate===!0&&Ue.updateCamera(t),t=Ue.getCamera()),e.isScene===!0&&e.onBeforeRender(T,e,t,A),x=Me.get(e,C.length),x.init(t),x.state.textureUnits=we.getTextureUnits(),C.push(x),ge.multiplyMatrices(t.projectionMatrix,t.matrixWorldInverse),pe.setFromProjectionMatrix(ge,Fi,t.reversedDepth),he=this.localClippingEnabled,me=Ne.init(this.clippingPlanes,he),b=je.get(e,S.length),b.init(),S.push(b),Ue.enabled===!0&&Ue.isPresenting===!0){let e=T.xr.getDepthSensingMesh();e!==null&&tt(e,t,-1/0,T.sortObjects)}tt(e,t,0,T.sortObjects),b.finish(),T.sortObjects===!0&&b.sort(ce,le),N=Ue.enabled===!1||Ue.isPresenting===!1||Ue.hasDepthSensing()===!1,N&&Fe.addToRenderList(b,e),this.info.render.frame++,me===!0&&Ne.beginShadows();let i=x.state.shadowsArray;if(Pe.render(i,e,t),me===!0&&Ne.endShadows(),this.info.autoReset===!0&&this.info.reset(),(r&&w.hasRenderPass())===!1){let n=b.opaque,r=b.transmissive;if(x.setupLights(),t.isArrayCamera){let i=t.cameras;if(r.length>0)for(let t=0,a=i.length;t<a;t++){let a=i[t];rt(n,r,e,a)}N&&Fe.render(e);for(let t=0,n=i.length;t<n;t++){let n=i[t];nt(b,e,n,n.viewport)}}else r.length>0&&rt(n,r,e,t),N&&Fe.render(e),nt(b,e,t)}A!==null&&k===0&&(we.updateMultisampleRenderTarget(A),we.updateRenderTargetMipmap(A)),r&&w.end(T),e.isScene===!0&&e.onAfterRender(T,e,t),Be.resetDefaultState(),ee=-1,te=null,C.pop(),C.length>0?(x=C[C.length-1],we.setTextureUnits(x.state.textureUnits),me===!0&&Ne.setGlobalState(T.clippingPlanes,x.state.camera)):x=null,S.pop(),b=S.length>0?S[S.length-1]:null,D!==null&&D.renderEnd()};function tt(e,t,n,r){if(e.visible===!1)return;if(e.layers.test(t.layers)){if(e.isGroup)n=e.renderOrder;else if(e.isLOD)e.autoUpdate===!0&&e.update(t);else if(e.isLightProbeGrid)x.pushLightProbeGrid(e);else if(e.isLight)x.pushLight(e),e.castShadow&&x.pushShadow(e);else if(e.isSprite){if(!e.frustumCulled||pe.intersectsSprite(e)){r&&ve.setFromMatrixPosition(e.matrixWorld).applyMatrix4(ge);let t=Oe.update(e),i=e.material;i.visible&&b.push(e,t,i,n,ve.z,null)}}else if((e.isMesh||e.isLine||e.isPoints)&&(!e.frustumCulled||pe.intersectsObject(e))){let t=Oe.update(e),i=e.material;if(r&&(e.boundingSphere===void 0?(t.boundingSphere===null&&t.computeBoundingSphere(),ve.copy(t.boundingSphere.center)):(e.boundingSphere===null&&e.computeBoundingSphere(),ve.copy(e.boundingSphere.center)),ve.applyMatrix4(e.matrixWorld).applyMatrix4(ge)),Array.isArray(i)){let r=t.groups;for(let a=0,o=r.length;a<o;a++){let o=r[a],s=i[o.materialIndex];s&&s.visible&&b.push(e,t,s,n,ve.z,o)}}else i.visible&&b.push(e,t,i,n,ve.z,null)}}let i=e.children;for(let e=0,a=i.length;e<a;e++)tt(i[e],t,n,r)}function nt(e,t,n,r){let{opaque:i,transmissive:a,transparent:o}=e;x.setupLightsView(n),me===!0&&Ne.setGlobalState(T.clippingPlanes,n),r&&I.viewport(ne.copy(r)),i.length>0&&it(i,t,n),a.length>0&&it(a,t,n),o.length>0&&it(o,t,n),I.buffers.depth.setTest(!0),I.buffers.depth.setMask(!0),I.buffers.color.setMask(!0),I.setPolygonOffset(!1)}function rt(e,t,n,r){if((n.isScene===!0?n.overrideMaterial:null)!==null)return;if(x.state.transmissionRenderTarget[r.id]===void 0){let e=xe.has(`EXT_color_buffer_half_float`)||xe.has(`EXT_color_buffer_float`);x.state.transmissionRenderTarget[r.id]=new Ba(1,1,{generateMipmaps:!0,type:e?gr:lr,minFilter:cr,samples:Math.max(4,Se.samples),stencilBuffer:i,resolveDepthBuffer:!1,resolveStencilBuffer:!1,colorSpace:Da.workingColorSpace})}let a=x.state.transmissionRenderTarget[r.id],o=r.viewport||ne;a.setSize(o.z*T.transmissionResolutionScale,o.w*T.transmissionResolutionScale);let s=T.getRenderTarget(),c=T.getActiveCubeFace(),l=T.getActiveMipmapLevel();T.setRenderTarget(a),T.getClearColor(ie),ae=T.getClearAlpha(),ae<1&&T.setClearColor(16777215,.5),T.clear(),N&&Fe.render(n);let u=T.toneMapping;T.toneMapping=0;let d=r.viewport;if(r.viewport!==void 0&&(r.viewport=void 0),x.setupLightsView(r),me===!0&&Ne.setGlobalState(T.clippingPlanes,r),it(e,n,r),we.updateMultisampleRenderTarget(a),we.updateRenderTargetMipmap(a),xe.has(`WEBGL_multisampled_render_to_texture`)===!1){let e=!1;for(let i=0,a=t.length;i<a;i++){let{object:a,geometry:o,material:s,group:c}=t[i];if(s.side===2&&a.layers.test(r.layers)){let t=s.side;s.side=1,s.needsUpdate=!0,at(a,n,r,o,s,c),s.side=t,s.needsUpdate=!0,e=!0}}e===!0&&(we.updateMultisampleRenderTarget(a),we.updateRenderTargetMipmap(a))}T.setRenderTarget(s,c,l),T.setClearColor(ie,ae),d!==void 0&&(r.viewport=d),T.toneMapping=u}function it(e,t,n){let r=t.isScene===!0?t.overrideMaterial:null;for(let i=0,a=e.length;i<a;i++){let a=e[i],{object:o,geometry:s,group:c}=a,l=a.material;l.allowOverride===!0&&r!==null&&(l=r),o.layers.test(n.layers)&&at(o,t,n,s,l,c)}}function at(e,t,n,r,i,a){e.onBeforeRender(T,t,n,r,i,a),e.modelViewMatrix.multiplyMatrices(n.matrixWorldInverse,e.matrixWorld),e.normalMatrix.getNormalMatrix(e.modelViewMatrix),i.onBeforeRender(T,t,n,r,e,a),i.transparent===!0&&i.side===2&&i.forceSinglePass===!1?(i.side=1,i.needsUpdate=!0,T.renderBufferDirect(n,t,r,i,e,a),i.side=0,i.needsUpdate=!0,T.renderBufferDirect(n,t,r,i,e,a),i.side=2):T.renderBufferDirect(n,t,r,i,e,a),e.onAfterRender(T,t,n,r,i,a)}function ot(e,t,n){t.isScene!==!0&&(t=ye);let r=L.get(e),i=x.state.lights,a=x.state.shadowsArray,o=i.state.version,s=ke.getParameters(e,i.state,a,t,n,x.state.lightProbeGridArray),c=ke.getProgramCacheKey(s),l=r.programs;r.environment=e.isMeshStandardMaterial||e.isMeshLambertMaterial||e.isMeshPhongMaterial?t.environment:null,r.fog=t.fog;let u=e.isMeshStandardMaterial||e.isMeshLambertMaterial&&!e.envMap||e.isMeshPhongMaterial&&!e.envMap;r.envMap=Te.get(e.envMap||r.environment,u),r.envMapRotation=r.environment!==null&&e.envMap===null?t.environmentRotation:e.envMapRotation,l===void 0&&(e.addEventListener(`dispose`,Ke),l=new Map,r.programs=l);let d=l.get(c);if(d!==void 0){if(r.currentProgram===d&&r.lightsStateVersion===o)return ct(e,s),d}else s.uniforms=ke.getUniforms(e),D!==null&&e.isNodeMaterial&&D.build(e,n,s),e.onBeforeCompile(s,T),d=ke.acquireProgram(s,c),l.set(c,d),r.uniforms=s.uniforms;let f=r.uniforms;return(!e.isShaderMaterial&&!e.isRawShaderMaterial||e.clipping===!0)&&(f.clippingPlanes=Ne.uniform),ct(e,s),r.needsLights=ft(e),r.lightsStateVersion=o,r.needsLights&&(f.ambientLightColor.value=i.state.ambient,f.lightProbe.value=i.state.probe,f.directionalLights.value=i.state.directional,f.directionalLightShadows.value=i.state.directionalShadow,f.spotLights.value=i.state.spot,f.spotLightShadows.value=i.state.spotShadow,f.rectAreaLights.value=i.state.rectArea,f.ltc_1.value=i.state.rectAreaLTC1,f.ltc_2.value=i.state.rectAreaLTC2,f.pointLights.value=i.state.point,f.pointLightShadows.value=i.state.pointShadow,f.hemisphereLights.value=i.state.hemi,f.directionalShadowMatrix.value=i.state.directionalShadowMatrix,f.spotLightMatrix.value=i.state.spotLightMatrix,f.spotLightMap.value=i.state.spotLightMap,f.pointShadowMatrix.value=i.state.pointShadowMatrix),r.lightProbeGrid=x.state.lightProbeGridArray.length>0,r.currentProgram=d,r.uniformsList=null,d}function st(e){if(e.uniformsList===null){let t=e.currentProgram.getUniforms();e.uniformsList=qf.seqWithValue(t.seq,e.uniforms)}return e.uniformsList}function ct(e,t){let n=L.get(e);n.outputColorSpace=t.outputColorSpace,n.batching=t.batching,n.batchingColor=t.batchingColor,n.instancing=t.instancing,n.instancingColor=t.instancingColor,n.instancingMorph=t.instancingMorph,n.skinning=t.skinning,n.morphTargets=t.morphTargets,n.morphNormals=t.morphNormals,n.morphColors=t.morphColors,n.morphTargetsCount=t.morphTargetsCount,n.numClippingPlanes=t.numClippingPlanes,n.numIntersection=t.numClipIntersection,n.vertexAlphas=t.vertexAlphas,n.vertexTangents=t.vertexTangents,n.toneMapping=t.toneMapping}function lt(e,t){if(e.length===0)return null;if(e.length===1)return e[0].texture===null?null:e[0];y.setFromMatrixPosition(t.matrixWorld);for(let t=0,n=e.length;t<n;t++){let n=e[t];if(n.texture!==null&&n.boundingBox.containsPoint(y))return n}return null}function ut(e,t,n,r,i){t.isScene!==!0&&(t=ye),we.resetTextureUnits();let a=t.fog,o=r.isMeshStandardMaterial||r.isMeshLambertMaterial||r.isMeshPhongMaterial?t.environment:null,s=A===null?T.outputColorSpace:A.isXRRenderTarget===!0?A.texture.colorSpace:Da.workingColorSpace,c=r.isMeshStandardMaterial||r.isMeshLambertMaterial&&!r.envMap||r.isMeshPhongMaterial&&!r.envMap,l=Te.get(r.envMap||o,c),u=r.vertexColors===!0&&!!n.attributes.color&&n.attributes.color.itemSize===4,d=!!n.attributes.tangent&&(!!r.normalMap||r.anisotropy>0),f=!!n.morphAttributes.position,p=!!n.morphAttributes.normal,m=!!n.morphAttributes.color,h=0;r.toneMapped&&(A===null||A.isXRRenderTarget===!0)&&(h=T.toneMapping);let g=n.morphAttributes.position||n.morphAttributes.normal||n.morphAttributes.color,_=g===void 0?0:g.length,v=L.get(r),y=x.state.lights;if(me===!0&&(he===!0||e!==te)){let t=e===te&&r.id===ee;Ne.setState(r,e,t)}let b=!1;r.version===v.__version?v.needsLights&&v.lightsStateVersion!==y.state.version?b=!0:v.outputColorSpace===s?i.isBatchedMesh&&v.batching===!1||!i.isBatchedMesh&&v.batching===!0||i.isBatchedMesh&&v.batchingColor===!0&&i.colorTexture===null||i.isBatchedMesh&&v.batchingColor===!1&&i.colorTexture!==null||i.isInstancedMesh&&v.instancing===!1||!i.isInstancedMesh&&v.instancing===!0||i.isSkinnedMesh&&v.skinning===!1||!i.isSkinnedMesh&&v.skinning===!0||i.isInstancedMesh&&v.instancingColor===!0&&i.instanceColor===null||i.isInstancedMesh&&v.instancingColor===!1&&i.instanceColor!==null||i.isInstancedMesh&&v.instancingMorph===!0&&i.morphTexture===null||i.isInstancedMesh&&v.instancingMorph===!1&&i.morphTexture!==null?b=!0:v.envMap===l?r.fog===!0&&v.fog!==a||v.numClippingPlanes!==void 0&&(v.numClippingPlanes!==Ne.numPlanes||v.numIntersection!==Ne.numIntersection)?b=!0:v.vertexAlphas===u&&v.vertexTangents===d&&v.morphTargets===f&&v.morphNormals===p&&v.morphColors===m&&v.toneMapping===h&&v.morphTargetsCount===_?!!v.lightProbeGrid!=x.state.lightProbeGridArray.length>0&&(b=!0):b=!0:b=!0:b=!0:(b=!0,v.__version=r.version);let S=v.currentProgram;b===!0&&(S=ot(r,t,i),D&&r.isNodeMaterial&&D.onUpdateProgram(r,S,v));let C=!1,w=!1,E=!1,O=S.getUniforms(),k=v.uniforms;if(I.useProgram(S.program)&&(C=!0,w=!0,E=!0),r.id!==ee&&(ee=r.id,w=!0),v.needsLights){let e=lt(x.state.lightProbeGridArray,i);v.lightProbeGrid!==e&&(v.lightProbeGrid=e,w=!0)}if(C||te!==e){I.buffers.depth.getReversed()&&e.reversedDepth!==!0&&(e._reversedDepth=!0,e.updateProjectionMatrix()),O.setValue(F,`projectionMatrix`,e.projectionMatrix),O.setValue(F,`viewMatrix`,e.matrixWorldInverse);let t=O.map.cameraPosition;t!==void 0&&t.setValue(F,_e.setFromMatrixPosition(e.matrixWorld)),Se.logarithmicDepthBuffer&&O.setValue(F,`logDepthBufFC`,2/(Math.log(e.far+1)/Math.LN2)),(r.isMeshPhongMaterial||r.isMeshToonMaterial||r.isMeshLambertMaterial||r.isMeshBasicMaterial||r.isMeshStandardMaterial||r.isShaderMaterial)&&O.setValue(F,`isOrthographic`,e.isOrthographicCamera===!0),te!==e&&(te=e,w=!0,E=!0)}if(v.needsLights&&(y.state.directionalShadowMap.length>0&&O.setValue(F,`directionalShadowMap`,y.state.directionalShadowMap,we),y.state.spotShadowMap.length>0&&O.setValue(F,`spotShadowMap`,y.state.spotShadowMap,we),y.state.pointShadowMap.length>0&&O.setValue(F,`pointShadowMap`,y.state.pointShadowMap,we)),i.isSkinnedMesh){O.setOptional(F,i,`bindMatrix`),O.setOptional(F,i,`bindMatrixInverse`);let e=i.skeleton;e&&(e.boneTexture===null&&e.computeBoneTexture(),O.setValue(F,`boneTexture`,e.boneTexture,we))}i.isBatchedMesh&&(O.setOptional(F,i,`batchingTexture`),O.setValue(F,`batchingTexture`,i._matricesTexture,we),O.setOptional(F,i,`batchingIdTexture`),O.setValue(F,`batchingIdTexture`,i._indirectTexture,we),O.setOptional(F,i,`batchingColorTexture`),i._colorsTexture!==null&&O.setValue(F,`batchingColorTexture`,i._colorsTexture,we));let ne=n.morphAttributes;if((ne.position!==void 0||ne.normal!==void 0||ne.color!==void 0)&&Ie.update(i,n,S),(w||v.receiveShadow!==i.receiveShadow)&&(v.receiveShadow=i.receiveShadow,O.setValue(F,`receiveShadow`,i.receiveShadow)),(r.isMeshStandardMaterial||r.isMeshLambertMaterial||r.isMeshPhongMaterial)&&r.envMap===null&&t.environment!==null&&(k.envMapIntensity.value=t.environmentIntensity),k.dfgLUT!==void 0&&(k.dfgLUT.value=mm()),w){if(O.setValue(F,`toneMappingExposure`,T.toneMappingExposure),v.needsLights&&dt(k,E),a&&r.fog===!0&&Ae.refreshFogUniforms(k,a),Ae.refreshMaterialUniforms(k,r,se,oe,x.state.transmissionRenderTarget[e.id]),v.needsLights&&v.lightProbeGrid){let e=v.lightProbeGrid;k.probesSH.value=e.texture,k.probesMin.value.copy(e.boundingBox.min),k.probesMax.value.copy(e.boundingBox.max),k.probesResolution.value.copy(e.resolution)}qf.upload(F,st(v),k,we)}if(r.isShaderMaterial&&r.uniformsNeedUpdate===!0&&(qf.upload(F,st(v),k,we),r.uniformsNeedUpdate=!1),r.isSpriteMaterial&&O.setValue(F,`center`,i.center),O.setValue(F,`modelViewMatrix`,i.modelViewMatrix),O.setValue(F,`normalMatrix`,i.normalMatrix),O.setValue(F,`modelMatrix`,i.matrixWorld),r.uniformsGroups!==void 0){let e=r.uniformsGroups;for(let t=0,n=e.length;t<n;t++){let n=e[t];Ve.update(n,S),Ve.bind(n,S)}}return S}function dt(e,t){e.ambientLightColor.needsUpdate=t,e.lightProbe.needsUpdate=t,e.directionalLights.needsUpdate=t,e.directionalLightShadows.needsUpdate=t,e.pointLights.needsUpdate=t,e.pointLightShadows.needsUpdate=t,e.spotLights.needsUpdate=t,e.spotLightShadows.needsUpdate=t,e.rectAreaLights.needsUpdate=t,e.hemisphereLights.needsUpdate=t}function ft(e){return e.isMeshLambertMaterial||e.isMeshToonMaterial||e.isMeshPhongMaterial||e.isMeshStandardMaterial||e.isShadowMaterial||e.isShaderMaterial&&e.lights===!0}this.getActiveCubeFace=function(){return O},this.getActiveMipmapLevel=function(){return k},this.getRenderTarget=function(){return A},this.setRenderTargetTextures=function(e,t,n){let r=L.get(e);r.__autoAllocateDepthBuffer=e.resolveDepthBuffer===!1,r.__autoAllocateDepthBuffer===!1&&(r.__useRenderToTexture=!1),L.get(e.texture).__webglTexture=t,L.get(e.depthTexture).__webglTexture=r.__autoAllocateDepthBuffer?void 0:n,r.__hasExternalTextures=!0},this.setRenderTargetFramebuffer=function(e,t){let n=L.get(e);n.__webglFramebuffer=t,n.__useDefaultFramebuffer=t===void 0};let pt=F.createFramebuffer();this.setRenderTarget=function(e,t=0,n=0){A=e,O=t,k=n;let r=null,i=!1,a=!1;if(e){let o=L.get(e);if(o.__useDefaultFramebuffer!==void 0){I.bindFramebuffer(F.FRAMEBUFFER,o.__webglFramebuffer),ne.copy(e.viewport),re.copy(e.scissor),j=e.scissorTest,I.viewport(ne),I.scissor(re),I.setScissorTest(j),ee=-1;return}else if(o.__webglFramebuffer===void 0)we.setupRenderTarget(e);else if(o.__hasExternalTextures)we.rebindTextures(e,L.get(e.texture).__webglTexture,L.get(e.depthTexture).__webglTexture);else if(e.depthBuffer){let t=e.depthTexture;if(o.__boundDepthTexture!==t){if(t!==null&&L.has(t)&&(e.width!==t.image.width||e.height!==t.image.height))throw Error(`WebGLRenderTarget: Attached DepthTexture is initialized to the incorrect size.`);we.setupDepthRenderbuffer(e)}}let s=e.texture;(s.isData3DTexture||s.isDataArrayTexture||s.isCompressedArrayTexture)&&(a=!0);let c=L.get(e).__webglFramebuffer;e.isWebGLCubeRenderTarget?(r=Array.isArray(c[t])?c[t][n]:c[t],i=!0):r=e.samples>0&&we.useMultisampledRTT(e)===!1?L.get(e).__webglMultisampledFramebuffer:Array.isArray(c)?c[n]:c,ne.copy(e.viewport),re.copy(e.scissor),j=e.scissorTest}else ne.copy(ue).multiplyScalar(se).floor(),re.copy(de).multiplyScalar(se).floor(),j=fe;if(n!==0&&(r=pt),I.bindFramebuffer(F.FRAMEBUFFER,r)&&I.drawBuffers(e,r),I.viewport(ne),I.scissor(re),I.setScissorTest(j),i){let r=L.get(e.texture);F.framebufferTexture2D(F.FRAMEBUFFER,F.COLOR_ATTACHMENT0,F.TEXTURE_CUBE_MAP_POSITIVE_X+t,r.__webglTexture,n)}else if(a){let r=t;for(let t=0;t<e.textures.length;t++){let i=L.get(e.textures[t]);F.framebufferTextureLayer(F.FRAMEBUFFER,F.COLOR_ATTACHMENT0+t,i.__webglTexture,n,r)}}else if(e!==null&&n!==0){let t=L.get(e.texture);F.framebufferTexture2D(F.FRAMEBUFFER,F.COLOR_ATTACHMENT0,F.TEXTURE_2D,t.__webglTexture,n)}ee=-1},this.readRenderTargetPixels=function(e,t,n,r,i,a,o,s=0){if(!(e&&e.isWebGLRenderTarget)){B(`WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.`);return}let c=L.get(e).__webglFramebuffer;if(e.isWebGLCubeRenderTarget&&o!==void 0&&(c=c[o]),c){I.bindFramebuffer(F.FRAMEBUFFER,c);try{let o=e.textures[s],c=o.format,l=o.type;if(e.textures.length>1&&F.readBuffer(F.COLOR_ATTACHMENT0+s),!Se.textureFormatReadable(c)){B(`WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format.`);return}if(!Se.textureTypeReadable(l)){B(`WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type.`);return}t>=0&&t<=e.width-r&&n>=0&&n<=e.height-i&&F.readPixels(t,n,r,i,ze.convert(c),ze.convert(l),a)}finally{let e=A===null?null:L.get(A).__webglFramebuffer;I.bindFramebuffer(F.FRAMEBUFFER,e)}}},this.readRenderTargetPixelsAsync=async function(e,t,n,r,i,a,o,s=0){if(!(e&&e.isWebGLRenderTarget))throw Error(`THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.`);let c=L.get(e).__webglFramebuffer;if(e.isWebGLCubeRenderTarget&&o!==void 0&&(c=c[o]),c)if(t>=0&&t<=e.width-r&&n>=0&&n<=e.height-i){I.bindFramebuffer(F.FRAMEBUFFER,c);let o=e.textures[s],l=o.format,u=o.type;if(e.textures.length>1&&F.readBuffer(F.COLOR_ATTACHMENT0+s),!Se.textureFormatReadable(l))throw Error(`THREE.WebGLRenderer.readRenderTargetPixelsAsync: renderTarget is not in RGBA or implementation defined format.`);if(!Se.textureTypeReadable(u))throw Error(`THREE.WebGLRenderer.readRenderTargetPixelsAsync: renderTarget is not in UnsignedByteType or implementation defined type.`);let d=F.createBuffer();F.bindBuffer(F.PIXEL_PACK_BUFFER,d),F.bufferData(F.PIXEL_PACK_BUFFER,a.byteLength,F.STREAM_READ),F.readPixels(t,n,r,i,ze.convert(l),ze.convert(u),0);let f=A===null?null:L.get(A).__webglFramebuffer;I.bindFramebuffer(F.FRAMEBUFFER,f);let p=F.fenceSync(F.SYNC_GPU_COMMANDS_COMPLETE,0);return F.flush(),await Gi(F,p,4),F.bindBuffer(F.PIXEL_PACK_BUFFER,d),F.getBufferSubData(F.PIXEL_PACK_BUFFER,0,a),F.deleteBuffer(d),F.deleteSync(p),a}else throw Error(`THREE.WebGLRenderer.readRenderTargetPixelsAsync: requested read bounds are out of range.`)},this.copyFramebufferToTexture=function(e,t=null,n=0){let r=2**-n,i=Math.floor(e.image.width*r),a=Math.floor(e.image.height*r),o=t===null?0:t.x,s=t===null?0:t.y;we.setTexture2D(e,0),F.copyTexSubImage2D(F.TEXTURE_2D,n,0,0,o,s,i,a),I.unbindTexture()};let mt=F.createFramebuffer(),ht=F.createFramebuffer();this.copyTextureToTexture=function(e,t,n=null,r=null,i=0,a=0){let o,s,c,l,u,d,f,p,m,h=e.isCompressedTexture?e.mipmaps[a]:e.image;if(n!==null)o=n.max.x-n.min.x,s=n.max.y-n.min.y,c=n.isBox3?n.max.z-n.min.z:1,l=n.min.x,u=n.min.y,d=n.isBox3?n.min.z:0;else{let t=2**-i;o=Math.floor(h.width*t),s=Math.floor(h.height*t),c=e.isDataArrayTexture?h.depth:e.isData3DTexture?Math.floor(h.depth*t):1,l=0,u=0,d=0}r===null?(f=0,p=0,m=0):(f=r.x,p=r.y,m=r.z);let g=ze.convert(t.format),_=ze.convert(t.type),v;t.isData3DTexture?(we.setTexture3D(t,0),v=F.TEXTURE_3D):t.isDataArrayTexture||t.isCompressedArrayTexture?(we.setTexture2DArray(t,0),v=F.TEXTURE_2D_ARRAY):(we.setTexture2D(t,0),v=F.TEXTURE_2D),I.activeTexture(F.TEXTURE0),I.pixelStorei(F.UNPACK_FLIP_Y_WEBGL,t.flipY),I.pixelStorei(F.UNPACK_PREMULTIPLY_ALPHA_WEBGL,t.premultiplyAlpha),I.pixelStorei(F.UNPACK_ALIGNMENT,t.unpackAlignment);let y=I.getParameter(F.UNPACK_ROW_LENGTH),b=I.getParameter(F.UNPACK_IMAGE_HEIGHT),x=I.getParameter(F.UNPACK_SKIP_PIXELS),S=I.getParameter(F.UNPACK_SKIP_ROWS),C=I.getParameter(F.UNPACK_SKIP_IMAGES);I.pixelStorei(F.UNPACK_ROW_LENGTH,h.width),I.pixelStorei(F.UNPACK_IMAGE_HEIGHT,h.height),I.pixelStorei(F.UNPACK_SKIP_PIXELS,l),I.pixelStorei(F.UNPACK_SKIP_ROWS,u),I.pixelStorei(F.UNPACK_SKIP_IMAGES,d);let w=e.isDataArrayTexture||e.isData3DTexture,T=t.isDataArrayTexture||t.isData3DTexture;if(e.isDepthTexture){let n=L.get(e),r=L.get(t),h=L.get(n.__renderTarget),g=L.get(r.__renderTarget);I.bindFramebuffer(F.READ_FRAMEBUFFER,h.__webglFramebuffer),I.bindFramebuffer(F.DRAW_FRAMEBUFFER,g.__webglFramebuffer);for(let n=0;n<c;n++)w&&(F.framebufferTextureLayer(F.READ_FRAMEBUFFER,F.COLOR_ATTACHMENT0,L.get(e).__webglTexture,i,d+n),F.framebufferTextureLayer(F.DRAW_FRAMEBUFFER,F.COLOR_ATTACHMENT0,L.get(t).__webglTexture,a,m+n)),F.blitFramebuffer(l,u,o,s,f,p,o,s,F.DEPTH_BUFFER_BIT,F.NEAREST);I.bindFramebuffer(F.READ_FRAMEBUFFER,null),I.bindFramebuffer(F.DRAW_FRAMEBUFFER,null)}else if(i!==0||e.isRenderTargetTexture||L.has(e)){let n=L.get(e),r=L.get(t);I.bindFramebuffer(F.READ_FRAMEBUFFER,mt),I.bindFramebuffer(F.DRAW_FRAMEBUFFER,ht);for(let e=0;e<c;e++)w?F.framebufferTextureLayer(F.READ_FRAMEBUFFER,F.COLOR_ATTACHMENT0,n.__webglTexture,i,d+e):F.framebufferTexture2D(F.READ_FRAMEBUFFER,F.COLOR_ATTACHMENT0,F.TEXTURE_2D,n.__webglTexture,i),T?F.framebufferTextureLayer(F.DRAW_FRAMEBUFFER,F.COLOR_ATTACHMENT0,r.__webglTexture,a,m+e):F.framebufferTexture2D(F.DRAW_FRAMEBUFFER,F.COLOR_ATTACHMENT0,F.TEXTURE_2D,r.__webglTexture,a),i===0?T?F.copyTexSubImage3D(v,a,f,p,m+e,l,u,o,s):F.copyTexSubImage2D(v,a,f,p,l,u,o,s):F.blitFramebuffer(l,u,o,s,f,p,o,s,F.COLOR_BUFFER_BIT,F.NEAREST);I.bindFramebuffer(F.READ_FRAMEBUFFER,null),I.bindFramebuffer(F.DRAW_FRAMEBUFFER,null)}else T?e.isDataTexture||e.isData3DTexture?F.texSubImage3D(v,a,f,p,m,o,s,c,g,_,h.data):t.isCompressedArrayTexture?F.compressedTexSubImage3D(v,a,f,p,m,o,s,c,g,h.data):F.texSubImage3D(v,a,f,p,m,o,s,c,g,_,h):e.isDataTexture?F.texSubImage2D(F.TEXTURE_2D,a,f,p,o,s,g,_,h.data):e.isCompressedTexture?F.compressedTexSubImage2D(F.TEXTURE_2D,a,f,p,h.width,h.height,g,h.data):F.texSubImage2D(F.TEXTURE_2D,a,f,p,o,s,g,_,h);I.pixelStorei(F.UNPACK_ROW_LENGTH,y),I.pixelStorei(F.UNPACK_IMAGE_HEIGHT,b),I.pixelStorei(F.UNPACK_SKIP_PIXELS,x),I.pixelStorei(F.UNPACK_SKIP_ROWS,S),I.pixelStorei(F.UNPACK_SKIP_IMAGES,C),a===0&&t.generateMipmaps&&F.generateMipmap(v),I.unbindTexture()},this.initRenderTarget=function(e){L.get(e).__webglFramebuffer===void 0&&we.setupRenderTarget(e)},this.initTexture=function(e){e.isCubeTexture?we.setTextureCube(e,0):e.isData3DTexture?we.setTexture3D(e,0):e.isDataArrayTexture||e.isCompressedArrayTexture?we.setTexture2DArray(e,0):we.setTexture2D(e,0),I.unbindTexture()},this.resetState=function(){O=0,k=0,A=null,I.reset(),Be.reset()},typeof __THREE_DEVTOOLS__<`u`&&__THREE_DEVTOOLS__.dispatchEvent(new CustomEvent(`observe`,{detail:this}))}get coordinateSystem(){return Fi}get outputColorSpace(){return this._outputColorSpace}set outputColorSpace(e){this._outputColorSpace=e;let t=this.getContext();t.drawingBufferColorSpace=Da._getDrawingBufferColorSpace(e),t.unpackColorSpace=Da._getUnpackColorSpace()}},gm=class{engine;entries=new Map;loader;constructor(e,t=null){this.engine=t,this.loader=e??((e,t)=>new eu().load(e,()=>t?.onLoad?.(),void 0,e=>t?.onError?.(e)))}load(e){for(let[t,n]of Object.entries(e)){let e=n.type;if(e!==`texture`&&e!==`spritesheet`)throw new N(`BAD_FORMAT`,`Asset '${t}': "type" must be 'texture' or 'spritesheet', got ${JSON.stringify(e)}.`);if(typeof n.url!=`string`||n.url===``)throw new N(`BAD_FORMAT`,`Asset '${t}': "url" must be a non-empty string.`);let r,i;if(e===`spritesheet`){if(typeof n.frameWidth!=`number`||typeof n.frameHeight!=`number`)throw new N(`BAD_FORMAT`,`Asset '${t}': spritesheets need numeric "frameWidth" and "frameHeight".`);r=n.frameWidth,i=n.frameHeight}let a=this.entries.get(t),o={status:`loading`},s=this.loader(n.url,{onLoad:()=>{o.status=`ready`},onError:e=>{o.status=`error`,lt(this.engine,`error`,`[incanto] failed to load texture '${t}' (${n.url}):`,e)}});a&&a.texture!==s&&a.texture.dispose(),s.colorSpace=Oi,n.filter===`nearest`?(s.magFilter=rr,s.minFilter=rr,s.generateMipmaps=!1):s.magFilter=or,s.needsUpdate=!0,this.entries.set(t,{texture:s,type:e,frameWidth:r,frameHeight:i,state:o})}}status(e){return this.entries.get(e)?.state.status}getTexture(e){return this.resolve(e).texture}getSheet(e){let t=this.resolve(e);if(t.type!==`spritesheet`)throw new N(`BAD_FORMAT`,`Asset '${e}' is a plain texture; a spritesheet (with frameWidth/frameHeight) is required here.`);return{texture:t.texture,frameWidth:t.frameWidth,frameHeight:t.frameHeight}}resolve(e){if(!e.startsWith(`$`))throw new N(`UNKNOWN_ASSET`,`Asset reference '${e}' must use the '$key' form (e.g. '$${e}').`);let t=this.entries.get(e.slice(1));if(!t)throw new N(`UNKNOWN_ASSET`,`Unknown asset '${e}'. Declared assets: [${[...this.entries.keys()].join(`, `)}].`);return t}},_m=`modulepreload`,vm=function(e,t){return new URL(e,t).href},ym={},bm=function(e,t,n){let r=Promise.resolve();if(t&&t.length>0){let e=document.getElementsByTagName(`link`),i=document.querySelector(`meta[property=csp-nonce]`),a=i?.nonce||i?.getAttribute(`nonce`);function o(e){return Promise.all(e.map(e=>Promise.resolve(e).then(e=>({status:`fulfilled`,value:e}),e=>({status:`rejected`,reason:e}))))}r=o(t.map(t=>{if(t=vm(t,n),t in ym)return;ym[t]=!0;let r=t.endsWith(`.css`),i=r?`[rel="stylesheet"]`:``;if(n)for(let n=e.length-1;n>=0;n--){let i=e[n];if(i.href===t&&(!r||i.rel===`stylesheet`))return}else if(document.querySelector(`link[href="${t}"]${i}`))return;let o=document.createElement(`link`);if(o.rel=r?`stylesheet`:_m,r||(o.as=`script`),o.crossOrigin=``,o.href=t,a&&o.setAttribute(`nonce`,a),document.head.appendChild(o),r)return new Promise((e,n)=>{o.addEventListener(`load`,e),o.addEventListener(`error`,()=>n(Error(`Unable to preload CSS for ${t}`)))})}))}function i(e){let t=new Event(`vite:preloadError`,{cancelable:!0});if(t.payload=e,window.dispatchEvent(t),!t.defaultPrevented)throw e}return r.then(t=>{for(let e of t||[])e.status===`rejected`&&i(e.reason);return e().catch(i)})},xm=160;function Sm(e=``,t=`#0b0d14`){if(typeof document>`u`)return{lift:()=>{}};let n=document.createElement(`div`);if(n.dataset.incantoSwitch=``,n.style.cssText=`position:fixed;inset:0;z-index:2147483646;background:${t};display:flex;align-items:center;justify-content:center;opacity:0;transition:opacity ${xm}ms ease;pointer-events:auto;`,e){let t=document.createElement(`div`);t.textContent=e,t.style.cssText=`font:13px/1 ui-monospace,SFMono-Regular,Menlo,monospace;color:#5d6680;letter-spacing:0.04em;`,n.appendChild(t)}document.body.appendChild(n),requestAnimationFrame(()=>{n.style.opacity=`1`});let r=!1;return{lift(){r||(r=!0,requestAnimationFrame(()=>{n.style.opacity=`0`,setTimeout(()=>n.remove(),200)}))}}}async function Cm(e=xm){typeof requestAnimationFrame==`function`&&await new Promise(t=>setTimeout(t,e))}function wm(e){return async t=>{let n=new URLSearchParams({tags:t.tags.join(`,`),page:String(t.page??1),limit:String(t.limit??24)});t.keyword?.trim()&&n.set(`keyword`,t.keyword.trim());let r=await fetch(`/api/library?${n}`,{headers:e?{"x-incanto-v8-token":e}:{}});if(r.status===401){let e=await r.json().catch(()=>({})),t=Error(e.error??`the asset library needs a Verse8 access token`);throw t.needsToken=!0,t}if(!r.ok)throw Error(`asset library: HTTP ${r.status}`);return await r.json()}}async function Tm(){try{let e=await fetch(`/api/scenes`);if(!e.ok)return null;let t=await e.json();return Array.isArray(t)?t:null}catch{return null}}var Em=`this dev server does not serve the project's scenes yet. Add incantoScenes() to vite.config.ts and restart:
|
|
4106
|
+
}`,om=class{constructor(){this.texture=null,this.mesh=null,this.depthNear=0,this.depthFar=0}init(e,t){if(this.texture===null){let n=new tl(e.texture);(e.depthNear!==t.depthNear||e.depthFar!==t.depthFar)&&(this.depthNear=e.depthNear,this.depthFar=e.depthFar),this.texture=n}}getMesh(e){if(this.texture!==null&&this.mesh===null){let t=e.cameras[0].viewport,n=new vl({vertexShader:im,fragmentShader:am,uniforms:{depthColor:{value:this.texture},depthWidth:{value:t.z},depthHeight:{value:t.w}}});this.mesh=new Ys(new cl(20,20),n)}return this.mesh}reset(){this.texture=null,this.mesh=null}getDepthTexture(){return this.texture}},sm=class extends qi{constructor(e,t){super();let n=this,r=null,i=1,a=null,o=`local-floor`,s=1,c=null,l=null,u=null,d=null,f=null,p=null,m=typeof XRWebGLBinding<`u`,h=new om,g={},_=t.getContextAttributes(),v=null,y=null,b=[],x=[],S=new V,C=null,w=new pu;w.viewport=new Ra;let T=new pu;T.viewport=new Ra;let E=[w,T],D=new Ou,O=null,k=null;this.cameraAutoUpdate=!0,this.enabled=!1,this.isPresenting=!1,this.getController=function(e){let t=b[e];return t===void 0&&(t=new yo,b[e]=t),t.getTargetRaySpace()},this.getControllerGrip=function(e){let t=b[e];return t===void 0&&(t=new yo,b[e]=t),t.getGripSpace()},this.getHand=function(e){let t=b[e];return t===void 0&&(t=new yo,b[e]=t),t.getHandSpace()};function A(e){let t=x.indexOf(e.inputSource);if(t===-1)return;let n=b[t];n!==void 0&&(n.update(e.inputSource,e.frame,c||a),n.dispatchEvent({type:e.type,data:e.inputSource}))}function ee(){r.removeEventListener(`select`,A),r.removeEventListener(`selectstart`,A),r.removeEventListener(`selectend`,A),r.removeEventListener(`squeeze`,A),r.removeEventListener(`squeezestart`,A),r.removeEventListener(`squeezeend`,A),r.removeEventListener(`end`,ee),r.removeEventListener(`inputsourceschange`,te);for(let e=0;e<b.length;e++){let t=x[e];t!==null&&(x[e]=null,b[e].disconnect(t))}O=null,k=null,h.reset();for(let e in g)delete g[e];e.setRenderTarget(v),f=null,d=null,u=null,r=null,y=null,se.stop(),n.isPresenting=!1,e.setPixelRatio(C),e.setSize(S.width,S.height,!1),n.dispatchEvent({type:`sessionend`})}this.setFramebufferScaleFactor=function(e){i=e,n.isPresenting===!0&&z(`WebXRManager: Cannot change framebuffer scale while presenting.`)},this.setReferenceSpaceType=function(e){o=e,n.isPresenting===!0&&z(`WebXRManager: Cannot change reference space type while presenting.`)},this.getReferenceSpace=function(){return c||a},this.setReferenceSpace=function(e){c=e},this.getBaseLayer=function(){return d===null?f:d},this.getBinding=function(){return u===null&&m&&(u=new XRWebGLBinding(r,t)),u},this.getFrame=function(){return p},this.getSession=function(){return r},this.setSession=async function(l){if(r=l,r!==null){if(v=e.getRenderTarget(),r.addEventListener(`select`,A),r.addEventListener(`selectstart`,A),r.addEventListener(`selectend`,A),r.addEventListener(`squeeze`,A),r.addEventListener(`squeezestart`,A),r.addEventListener(`squeezeend`,A),r.addEventListener(`end`,ee),r.addEventListener(`inputsourceschange`,te),_.xrCompatible!==!0&&await t.makeXRCompatible(),C=e.getPixelRatio(),e.getSize(S),m&&`createProjectionLayer`in XRWebGLBinding.prototype){let n=null,a=null,o=null;_.depth&&(o=_.stencil?t.DEPTH24_STENCIL8:t.DEPTH_COMPONENT24,n=_.stencil?Er:Tr,a=_.stencil?yr:mr);let s={colorFormat:t.RGBA8,depthFormat:o,scaleFactor:i};u=this.getBinding(),d=u.createProjectionLayer(s),r.updateRenderState({layers:[d]}),e.setPixelRatio(1),e.setSize(d.textureWidth,d.textureHeight,!1),y=new Ba(d.textureWidth,d.textureHeight,{format:wr,type:lr,depthTexture:new $c(d.textureWidth,d.textureHeight,a,void 0,void 0,void 0,void 0,void 0,void 0,n),stencilBuffer:_.stencil,colorSpace:e.outputColorSpace,samples:_.antialias?4:0,resolveDepthBuffer:d.ignoreDepthValues===!1,resolveStencilBuffer:d.ignoreDepthValues===!1})}else{let n={antialias:_.antialias,alpha:!0,depth:_.depth,stencil:_.stencil,framebufferScaleFactor:i};f=new XRWebGLLayer(r,t,n),r.updateRenderState({baseLayer:f}),e.setPixelRatio(1),e.setSize(f.framebufferWidth,f.framebufferHeight,!1),y=new Ba(f.framebufferWidth,f.framebufferHeight,{format:wr,type:lr,colorSpace:e.outputColorSpace,stencilBuffer:_.stencil,resolveDepthBuffer:f.ignoreDepthValues===!1,resolveStencilBuffer:f.ignoreDepthValues===!1})}y.isXRRenderTarget=!0,this.setFoveation(s),c=null,a=await r.requestReferenceSpace(o),se.setContext(r),se.start(),n.isPresenting=!0,n.dispatchEvent({type:`sessionstart`})}},this.getEnvironmentBlendMode=function(){if(r!==null)return r.environmentBlendMode},this.getDepthTexture=function(){return h.getDepthTexture()};function te(e){for(let t=0;t<e.removed.length;t++){let n=e.removed[t],r=x.indexOf(n);r>=0&&(x[r]=null,b[r].disconnect(n))}for(let t=0;t<e.added.length;t++){let n=e.added[t],r=x.indexOf(n);if(r===-1){for(let e=0;e<b.length;e++)if(e>=x.length){x.push(n),r=e;break}else if(x[e]===null){x[e]=n,r=e;break}if(r===-1)break}let i=b[r];i&&i.connect(n)}}let ne=new U,re=new U;function j(e,t,n){ne.setFromMatrixPosition(t.matrixWorld),re.setFromMatrixPosition(n.matrixWorld);let r=ne.distanceTo(re),i=t.projectionMatrix.elements,a=n.projectionMatrix.elements,o=i[14]/(i[10]-1),s=i[14]/(i[10]+1),c=(i[9]+1)/i[5],l=(i[9]-1)/i[5],u=(i[8]-1)/i[0],d=(a[8]+1)/a[0],f=o*u,p=o*d,m=r/(-u+d),h=m*-u;if(t.matrixWorld.decompose(e.position,e.quaternion,e.scale),e.translateX(h),e.translateZ(m),e.matrixWorld.compose(e.position,e.quaternion,e.scale),e.matrixWorldInverse.copy(e.matrixWorld).invert(),i[10]===-1)e.projectionMatrix.copy(t.projectionMatrix),e.projectionMatrixInverse.copy(t.projectionMatrixInverse);else{let t=o+m,n=s+m,i=f-h,a=p+(r-h),u=c*s/n*t,d=l*s/n*t;e.projectionMatrix.makePerspective(i,a,u,d,t,n),e.projectionMatrixInverse.copy(e.projectionMatrix).invert()}}function ie(e,t){t===null?e.matrixWorld.copy(e.matrix):e.matrixWorld.multiplyMatrices(t.matrixWorld,e.matrix),e.matrixWorldInverse.copy(e.matrixWorld).invert()}this.updateCamera=function(e){if(r===null)return;let t=e.near,n=e.far;h.texture!==null&&(h.depthNear>0&&(t=h.depthNear),h.depthFar>0&&(n=h.depthFar)),D.near=T.near=w.near=t,D.far=T.far=w.far=n,(O!==D.near||k!==D.far)&&(r.updateRenderState({depthNear:D.near,depthFar:D.far}),O=D.near,k=D.far),D.layers.mask=e.layers.mask|6,w.layers.mask=D.layers.mask&-5,T.layers.mask=D.layers.mask&-3;let i=e.parent,a=D.cameras;ie(D,i);for(let e=0;e<a.length;e++)ie(a[e],i);a.length===2?j(D,w,T):D.projectionMatrix.copy(w.projectionMatrix),ae(e,D,i)};function ae(e,t,n){n===null?e.matrix.copy(t.matrixWorld):(e.matrix.copy(n.matrixWorld),e.matrix.invert(),e.matrix.multiply(t.matrixWorld)),e.matrix.decompose(e.position,e.quaternion,e.scale),e.updateMatrixWorld(!0),e.projectionMatrix.copy(t.projectionMatrix),e.projectionMatrixInverse.copy(t.projectionMatrixInverse),e.isPerspectiveCamera&&(e.fov=Zi*2*Math.atan(1/e.projectionMatrix.elements[5]),e.zoom=1)}this.getCamera=function(){return D},this.getFoveation=function(){if(!(d===null&&f===null))return s},this.setFoveation=function(e){s=e,d!==null&&(d.fixedFoveation=e),f!==null&&f.fixedFoveation!==void 0&&(f.fixedFoveation=e)},this.hasDepthSensing=function(){return h.texture!==null},this.getDepthSensingMesh=function(){return h.getMesh(D)},this.getCameraTexture=function(e){return g[e]};let M=null;function oe(t,i){if(l=i.getViewerPose(c||a),p=i,l!==null){let t=l.views;f!==null&&(e.setRenderTargetFramebuffer(y,f.framebuffer),e.setRenderTarget(y));let i=!1;t.length!==D.cameras.length&&(D.cameras.length=0,i=!0);for(let n=0;n<t.length;n++){let r=t[n],a=null;if(f!==null)a=f.getViewport(r);else{let t=u.getViewSubImage(d,r);a=t.viewport,n===0&&(e.setRenderTargetTextures(y,t.colorTexture,t.depthStencilTexture),e.setRenderTarget(y))}let o=E[n];o===void 0&&(o=new pu,o.layers.enable(n),o.viewport=new Ra,E[n]=o),o.matrix.fromArray(r.transform.matrix),o.matrix.decompose(o.position,o.quaternion,o.scale),o.projectionMatrix.fromArray(r.projectionMatrix),o.projectionMatrixInverse.copy(o.projectionMatrix).invert(),o.viewport.set(a.x,a.y,a.width,a.height),n===0&&(D.matrix.copy(o.matrix),D.matrix.decompose(D.position,D.quaternion,D.scale)),i===!0&&D.cameras.push(o)}let a=r.enabledFeatures;if(a&&a.includes(`depth-sensing`)&&r.depthUsage==`gpu-optimized`&&m){u=n.getBinding();let e=u.getDepthInformation(t[0]);e&&e.isValid&&e.texture&&h.init(e,r.renderState)}if(a&&a.includes(`camera-access`)&&m){e.state.unbindTexture(),u=n.getBinding();for(let e=0;e<t.length;e++){let n=t[e].camera;if(n){let e=g[n];e||(e=new tl,g[n]=e);let t=u.getCameraImage(n);e.sourceTexture=t}}}}for(let e=0;e<b.length;e++){let t=x[e],n=b[e];t!==null&&n!==void 0&&n.update(t,i,c||a)}M&&M(t,i),i.detectedPlanes&&n.dispatchEvent({type:`planesdetected`,data:i}),p=null}let se=new $u;se.setAnimationLoop(oe),this.setAnimationLoop=function(e){M=e},this.dispose=function(){}}},cm=new G,lm=new W;lm.set(-1,0,0,0,1,0,0,0,1);function um(e,t){function n(e,t){e.matrixAutoUpdate===!0&&e.updateMatrix(),t.value.copy(e.matrix)}function r(t,n){n.color.getRGB(t.fogColor.value,ml(e)),n.isFog?(t.fogNear.value=n.near,t.fogFar.value=n.far):n.isFogExp2&&(t.fogDensity.value=n.density)}function i(e,t,n,r,i){t.isNodeMaterial?t.uniformsNeedUpdate=!1:t.isMeshBasicMaterial?a(e,t):t.isMeshLambertMaterial?(a(e,t),t.envMap&&(e.envMapIntensity.value=t.envMapIntensity)):t.isMeshToonMaterial?(a(e,t),d(e,t)):t.isMeshPhongMaterial?(a(e,t),u(e,t),t.envMap&&(e.envMapIntensity.value=t.envMapIntensity)):t.isMeshStandardMaterial?(a(e,t),f(e,t),t.isMeshPhysicalMaterial&&p(e,t,i)):t.isMeshMatcapMaterial?(a(e,t),m(e,t)):t.isMeshDepthMaterial?a(e,t):t.isMeshDistanceMaterial?(a(e,t),h(e,t)):t.isMeshNormalMaterial?a(e,t):t.isLineBasicMaterial?(o(e,t),t.isLineDashedMaterial&&s(e,t)):t.isPointsMaterial?c(e,t,n,r):t.isSpriteMaterial?l(e,t):t.isShadowMaterial?(e.color.value.copy(t.color),e.opacity.value=t.opacity):t.isShaderMaterial&&(t.uniformsNeedUpdate=!1)}function a(e,r){e.opacity.value=r.opacity,r.color&&e.diffuse.value.copy(r.color),r.emissive&&e.emissive.value.copy(r.emissive).multiplyScalar(r.emissiveIntensity),r.map&&(e.map.value=r.map,n(r.map,e.mapTransform)),r.alphaMap&&(e.alphaMap.value=r.alphaMap,n(r.alphaMap,e.alphaMapTransform)),r.bumpMap&&(e.bumpMap.value=r.bumpMap,n(r.bumpMap,e.bumpMapTransform),e.bumpScale.value=r.bumpScale,r.side===1&&(e.bumpScale.value*=-1)),r.normalMap&&(e.normalMap.value=r.normalMap,n(r.normalMap,e.normalMapTransform),e.normalScale.value.copy(r.normalScale),r.side===1&&e.normalScale.value.negate()),r.displacementMap&&(e.displacementMap.value=r.displacementMap,n(r.displacementMap,e.displacementMapTransform),e.displacementScale.value=r.displacementScale,e.displacementBias.value=r.displacementBias),r.emissiveMap&&(e.emissiveMap.value=r.emissiveMap,n(r.emissiveMap,e.emissiveMapTransform)),r.specularMap&&(e.specularMap.value=r.specularMap,n(r.specularMap,e.specularMapTransform)),r.alphaTest>0&&(e.alphaTest.value=r.alphaTest);let i=t.get(r),a=i.envMap,o=i.envMapRotation;a&&(e.envMap.value=a,e.envMapRotation.value.setFromMatrix4(cm.makeRotationFromEuler(o)).transpose(),a.isCubeTexture&&a.isRenderTargetTexture===!1&&e.envMapRotation.value.premultiply(lm),e.reflectivity.value=r.reflectivity,e.ior.value=r.ior,e.refractionRatio.value=r.refractionRatio),r.lightMap&&(e.lightMap.value=r.lightMap,e.lightMapIntensity.value=r.lightMapIntensity,n(r.lightMap,e.lightMapTransform)),r.aoMap&&(e.aoMap.value=r.aoMap,e.aoMapIntensity.value=r.aoMapIntensity,n(r.aoMap,e.aoMapTransform))}function o(e,t){e.diffuse.value.copy(t.color),e.opacity.value=t.opacity,t.map&&(e.map.value=t.map,n(t.map,e.mapTransform))}function s(e,t){e.dashSize.value=t.dashSize,e.totalSize.value=t.dashSize+t.gapSize,e.scale.value=t.scale}function c(e,t,r,i){e.diffuse.value.copy(t.color),e.opacity.value=t.opacity,e.size.value=t.size*r,e.scale.value=i*.5,t.map&&(e.map.value=t.map,n(t.map,e.uvTransform)),t.alphaMap&&(e.alphaMap.value=t.alphaMap,n(t.alphaMap,e.alphaMapTransform)),t.alphaTest>0&&(e.alphaTest.value=t.alphaTest)}function l(e,t){e.diffuse.value.copy(t.color),e.opacity.value=t.opacity,e.rotation.value=t.rotation,t.map&&(e.map.value=t.map,n(t.map,e.mapTransform)),t.alphaMap&&(e.alphaMap.value=t.alphaMap,n(t.alphaMap,e.alphaMapTransform)),t.alphaTest>0&&(e.alphaTest.value=t.alphaTest)}function u(e,t){e.specular.value.copy(t.specular),e.shininess.value=Math.max(t.shininess,1e-4)}function d(e,t){t.gradientMap&&(e.gradientMap.value=t.gradientMap)}function f(e,t){e.metalness.value=t.metalness,t.metalnessMap&&(e.metalnessMap.value=t.metalnessMap,n(t.metalnessMap,e.metalnessMapTransform)),e.roughness.value=t.roughness,t.roughnessMap&&(e.roughnessMap.value=t.roughnessMap,n(t.roughnessMap,e.roughnessMapTransform)),t.envMap&&(e.envMapIntensity.value=t.envMapIntensity)}function p(e,t,r){e.ior.value=t.ior,t.sheen>0&&(e.sheenColor.value.copy(t.sheenColor).multiplyScalar(t.sheen),e.sheenRoughness.value=t.sheenRoughness,t.sheenColorMap&&(e.sheenColorMap.value=t.sheenColorMap,n(t.sheenColorMap,e.sheenColorMapTransform)),t.sheenRoughnessMap&&(e.sheenRoughnessMap.value=t.sheenRoughnessMap,n(t.sheenRoughnessMap,e.sheenRoughnessMapTransform))),t.clearcoat>0&&(e.clearcoat.value=t.clearcoat,e.clearcoatRoughness.value=t.clearcoatRoughness,t.clearcoatMap&&(e.clearcoatMap.value=t.clearcoatMap,n(t.clearcoatMap,e.clearcoatMapTransform)),t.clearcoatRoughnessMap&&(e.clearcoatRoughnessMap.value=t.clearcoatRoughnessMap,n(t.clearcoatRoughnessMap,e.clearcoatRoughnessMapTransform)),t.clearcoatNormalMap&&(e.clearcoatNormalMap.value=t.clearcoatNormalMap,n(t.clearcoatNormalMap,e.clearcoatNormalMapTransform),e.clearcoatNormalScale.value.copy(t.clearcoatNormalScale),t.side===1&&e.clearcoatNormalScale.value.negate())),t.dispersion>0&&(e.dispersion.value=t.dispersion),t.iridescence>0&&(e.iridescence.value=t.iridescence,e.iridescenceIOR.value=t.iridescenceIOR,e.iridescenceThicknessMinimum.value=t.iridescenceThicknessRange[0],e.iridescenceThicknessMaximum.value=t.iridescenceThicknessRange[1],t.iridescenceMap&&(e.iridescenceMap.value=t.iridescenceMap,n(t.iridescenceMap,e.iridescenceMapTransform)),t.iridescenceThicknessMap&&(e.iridescenceThicknessMap.value=t.iridescenceThicknessMap,n(t.iridescenceThicknessMap,e.iridescenceThicknessMapTransform))),t.transmission>0&&(e.transmission.value=t.transmission,e.transmissionSamplerMap.value=r.texture,e.transmissionSamplerSize.value.set(r.width,r.height),t.transmissionMap&&(e.transmissionMap.value=t.transmissionMap,n(t.transmissionMap,e.transmissionMapTransform)),e.thickness.value=t.thickness,t.thicknessMap&&(e.thicknessMap.value=t.thicknessMap,n(t.thicknessMap,e.thicknessMapTransform)),e.attenuationDistance.value=t.attenuationDistance,e.attenuationColor.value.copy(t.attenuationColor)),t.anisotropy>0&&(e.anisotropyVector.value.set(t.anisotropy*Math.cos(t.anisotropyRotation),t.anisotropy*Math.sin(t.anisotropyRotation)),t.anisotropyMap&&(e.anisotropyMap.value=t.anisotropyMap,n(t.anisotropyMap,e.anisotropyMapTransform))),e.specularIntensity.value=t.specularIntensity,e.specularColor.value.copy(t.specularColor),t.specularColorMap&&(e.specularColorMap.value=t.specularColorMap,n(t.specularColorMap,e.specularColorMapTransform)),t.specularIntensityMap&&(e.specularIntensityMap.value=t.specularIntensityMap,n(t.specularIntensityMap,e.specularIntensityMapTransform))}function m(e,t){t.matcap&&(e.matcap.value=t.matcap)}function h(e,n){let r=t.get(n).light;e.referencePosition.value.setFromMatrixPosition(r.matrixWorld),e.nearDistance.value=r.shadow.camera.near,e.farDistance.value=r.shadow.camera.far}return{refreshFogUniforms:r,refreshMaterialUniforms:i}}function dm(e,t,n,r){let i={},a={},o=[],s=e.getParameter(e.MAX_UNIFORM_BUFFER_BINDINGS);function c(e,t){let n=t.program;r.uniformBlockBinding(e,n)}function l(e,n){let o=i[e.id];o===void 0&&(m(e),o=u(e),i[e.id]=o,e.addEventListener(`dispose`,g));let s=n.program;r.updateUBOMapping(e,s);let c=t.render.frame;a[e.id]!==c&&(f(e),a[e.id]=c)}function u(t){let n=d();t.__bindingPointIndex=n;let r=e.createBuffer(),i=t.__size,a=t.usage;return e.bindBuffer(e.UNIFORM_BUFFER,r),e.bufferData(e.UNIFORM_BUFFER,i,a),e.bindBuffer(e.UNIFORM_BUFFER,null),e.bindBufferBase(e.UNIFORM_BUFFER,n,r),r}function d(){for(let e=0;e<s;e++)if(o.indexOf(e)===-1)return o.push(e),e;return B(`WebGLRenderer: Maximum number of simultaneously usable uniforms groups reached.`),0}function f(t){let n=i[t.id],r=t.uniforms,a=t.__cache;e.bindBuffer(e.UNIFORM_BUFFER,n);for(let t=0,n=r.length;t<n;t++){let n=Array.isArray(r[t])?r[t]:[r[t]];for(let r=0,i=n.length;r<i;r++){let i=n[r];if(p(i,t,r,a)===!0){let t=i.__offset,n=Array.isArray(i.value)?i.value:[i.value],r=0;for(let a=0;a<n.length;a++){let o=n[a],s=h(o);typeof o==`number`||typeof o==`boolean`?(i.__data[0]=o,e.bufferSubData(e.UNIFORM_BUFFER,t+r,i.__data)):o.isMatrix3?(i.__data[0]=o.elements[0],i.__data[1]=o.elements[1],i.__data[2]=o.elements[2],i.__data[3]=0,i.__data[4]=o.elements[3],i.__data[5]=o.elements[4],i.__data[6]=o.elements[5],i.__data[7]=0,i.__data[8]=o.elements[6],i.__data[9]=o.elements[7],i.__data[10]=o.elements[8],i.__data[11]=0):ArrayBuffer.isView(o)?i.__data.set(new o.constructor(o.buffer,o.byteOffset,i.__data.length)):(o.toArray(i.__data,r),r+=s.storage/Float32Array.BYTES_PER_ELEMENT)}e.bufferSubData(e.UNIFORM_BUFFER,t,i.__data)}}}e.bindBuffer(e.UNIFORM_BUFFER,null)}function p(e,t,n,r){let i=e.value,a=t+`_`+n;if(r[a]===void 0)return typeof i==`number`||typeof i==`boolean`?r[a]=i:ArrayBuffer.isView(i)?r[a]=i.slice():r[a]=i.clone(),!0;{let e=r[a];if(typeof i==`number`||typeof i==`boolean`){if(e!==i)return r[a]=i,!0}else if(ArrayBuffer.isView(i))return!0;else if(e.equals(i)===!1)return e.copy(i),!0}return!1}function m(e){let t=e.uniforms,n=0;for(let e=0,r=t.length;e<r;e++){let r=Array.isArray(t[e])?t[e]:[t[e]];for(let e=0,t=r.length;e<t;e++){let t=r[e],i=Array.isArray(t.value)?t.value:[t.value];for(let e=0,r=i.length;e<r;e++){let r=i[e],a=h(r),o=n%16,s=o%a.boundary,c=o+s;n+=s,c!==0&&16-c<a.storage&&(n+=16-c),t.__data=new Float32Array(a.storage/Float32Array.BYTES_PER_ELEMENT),t.__offset=n,n+=a.storage}}}let r=n%16;return r>0&&(n+=16-r),e.__size=n,e.__cache={},this}function h(e){let t={boundary:0,storage:0};return typeof e==`number`||typeof e==`boolean`?(t.boundary=4,t.storage=4):e.isVector2?(t.boundary=8,t.storage=8):e.isVector3||e.isColor?(t.boundary=16,t.storage=12):e.isVector4?(t.boundary=16,t.storage=16):e.isMatrix3?(t.boundary=48,t.storage=48):e.isMatrix4?(t.boundary=64,t.storage=64):e.isTexture?z(`WebGLRenderer: Texture samplers can not be part of an uniforms group.`):ArrayBuffer.isView(e)?(t.boundary=16,t.storage=e.byteLength):z(`WebGLRenderer: Unsupported uniform value type.`,e),t}function g(t){let n=t.target;n.removeEventListener(`dispose`,g);let r=o.indexOf(n.__bindingPointIndex);o.splice(r,1),e.deleteBuffer(i[n.id]),delete i[n.id],delete a[n.id]}function _(){for(let t in i)e.deleteBuffer(i[t]);o=[],i={},a={}}return{bind:c,update:l,dispose:_}}var fm=new Uint16Array([12469,15057,12620,14925,13266,14620,13807,14376,14323,13990,14545,13625,14713,13328,14840,12882,14931,12528,14996,12233,15039,11829,15066,11525,15080,11295,15085,10976,15082,10705,15073,10495,13880,14564,13898,14542,13977,14430,14158,14124,14393,13732,14556,13410,14702,12996,14814,12596,14891,12291,14937,11834,14957,11489,14958,11194,14943,10803,14921,10506,14893,10278,14858,9960,14484,14039,14487,14025,14499,13941,14524,13740,14574,13468,14654,13106,14743,12678,14818,12344,14867,11893,14889,11509,14893,11180,14881,10751,14852,10428,14812,10128,14765,9754,14712,9466,14764,13480,14764,13475,14766,13440,14766,13347,14769,13070,14786,12713,14816,12387,14844,11957,14860,11549,14868,11215,14855,10751,14825,10403,14782,10044,14729,9651,14666,9352,14599,9029,14967,12835,14966,12831,14963,12804,14954,12723,14936,12564,14917,12347,14900,11958,14886,11569,14878,11247,14859,10765,14828,10401,14784,10011,14727,9600,14660,9289,14586,8893,14508,8533,15111,12234,15110,12234,15104,12216,15092,12156,15067,12010,15028,11776,14981,11500,14942,11205,14902,10752,14861,10393,14812,9991,14752,9570,14682,9252,14603,8808,14519,8445,14431,8145,15209,11449,15208,11451,15202,11451,15190,11438,15163,11384,15117,11274,15055,10979,14994,10648,14932,10343,14871,9936,14803,9532,14729,9218,14645,8742,14556,8381,14461,8020,14365,7603,15273,10603,15272,10607,15267,10619,15256,10631,15231,10614,15182,10535,15118,10389,15042,10167,14963,9787,14883,9447,14800,9115,14710,8665,14615,8318,14514,7911,14411,7507,14279,7198,15314,9675,15313,9683,15309,9712,15298,9759,15277,9797,15229,9773,15166,9668,15084,9487,14995,9274,14898,8910,14800,8539,14697,8234,14590,7790,14479,7409,14367,7067,14178,6621,15337,8619,15337,8631,15333,8677,15325,8769,15305,8871,15264,8940,15202,8909,15119,8775,15022,8565,14916,8328,14804,8009,14688,7614,14569,7287,14448,6888,14321,6483,14088,6171,15350,7402,15350,7419,15347,7480,15340,7613,15322,7804,15287,7973,15229,8057,15148,8012,15046,7846,14933,7611,14810,7357,14682,7069,14552,6656,14421,6316,14251,5948,14007,5528,15356,5942,15356,5977,15353,6119,15348,6294,15332,6551,15302,6824,15249,7044,15171,7122,15070,7050,14949,6861,14818,6611,14679,6349,14538,6067,14398,5651,14189,5311,13935,4958,15359,4123,15359,4153,15356,4296,15353,4646,15338,5160,15311,5508,15263,5829,15188,6042,15088,6094,14966,6001,14826,5796,14678,5543,14527,5287,14377,4985,14133,4586,13869,4257,15360,1563,15360,1642,15358,2076,15354,2636,15341,3350,15317,4019,15273,4429,15203,4732,15105,4911,14981,4932,14836,4818,14679,4621,14517,4386,14359,4156,14083,3795,13808,3437,15360,122,15360,137,15358,285,15355,636,15344,1274,15322,2177,15281,2765,15215,3223,15120,3451,14995,3569,14846,3567,14681,3466,14511,3305,14344,3121,14037,2800,13753,2467,15360,0,15360,1,15359,21,15355,89,15346,253,15325,479,15287,796,15225,1148,15133,1492,15008,1749,14856,1882,14685,1886,14506,1783,14324,1608,13996,1398,13702,1183]),pm=null;function mm(){return pm===null&&(pm=new lc(fm,16,16,kr,gr),pm.name=`DFG_LUT`,pm.minFilter=or,pm.magFilter=or,pm.wrapS=tr,pm.wrapT=tr,pm.generateMipmaps=!1,pm.needsUpdate=!0),pm}var hm=class{constructor(e={}){let{canvas:t=zi(),context:n=null,depth:r=!0,stencil:i=!1,alpha:a=!1,antialias:o=!1,premultipliedAlpha:s=!0,preserveDrawingBuffer:c=!1,powerPreference:l=`default`,failIfMajorPerformanceCaveat:u=!1,reversedDepthBuffer:d=!1,outputBufferType:f=lr}=e;this.isWebGLRenderer=!0;let p;if(n!==null){if(typeof WebGLRenderingContext<`u`&&n instanceof WebGLRenderingContext)throw Error(`THREE.WebGLRenderer: WebGL 1 is not supported since r163.`);p=n.getContextAttributes().alpha}else p=a;let m=f,h=new Set([jr,Ar,Or]),g=new Set([lr,mr,fr,yr,_r,vr]),_=new Uint32Array(4),v=new Int32Array(4),y=new U,b=null,x=null,S=[],C=[],w=null;this.domElement=t,this.debug={checkShaderErrors:!0,onShaderError:null},this.autoClear=!0,this.autoClearColor=!0,this.autoClearDepth=!0,this.autoClearStencil=!0,this.sortObjects=!0,this.clippingPlanes=[],this.localClippingEnabled=!1,this.toneMapping=0,this.toneMappingExposure=1,this.transmissionResolutionScale=1;let T=this,E=!1,D=null;this._outputColorSpace=Oi;let O=0,k=0,A=null,ee=-1,te=null,ne=new Ra,re=new Ra,j=null,ie=new K(0),ae=0,M=t.width,oe=t.height,se=1,ce=null,le=null,ue=new Ra(0,0,M,oe),de=new Ra(0,0,M,oe),fe=!1,pe=new kc,me=!1,he=!1,ge=new G,_e=new U,ve=new Ra,ye={background:null,fog:null,environment:null,overrideMaterial:null,isScene:!0},N=!1;function P(){return A===null?se:1}let F=n;function be(e,n){return t.getContext(e,n)}try{let e={alpha:!0,depth:r,stencil:i,antialias:o,premultipliedAlpha:s,preserveDrawingBuffer:c,powerPreference:l,failIfMajorPerformanceCaveat:u};if(`setAttribute`in t&&t.setAttribute(`data-engine`,`three.js r184`),t.addEventListener(`webglcontextlost`,We,!1),t.addEventListener(`webglcontextrestored`,R,!1),t.addEventListener(`webglcontextcreationerror`,Ge,!1),F===null){let t=`webgl2`;if(F=be(t,e),F===null)throw be(t)?Error(`Error creating WebGL context with your selected attributes.`):Error(`Error creating WebGL context.`)}}catch(e){throw B(`WebGLRenderer: `+e.message),e}let xe,Se,I,Ce,L,we,Te,Ee,De,Oe,ke,Ae,je,Me,Ne,Pe,Fe,Ie,Le,Re,ze,Be,Ve;function He(){xe=new Md(F),xe.init(),ze=new rm(F,xe),Se=new cd(F,xe,e,ze),I=new tm(F,xe),Se.reversedDepthBuffer&&d&&I.buffers.depth.setReversed(!0),Ce=new Fd(F),L=new Fp,we=new nm(F,xe,I,L,Se,ze,Ce),Te=new jd(T),Ee=new ed(F),Be=new od(F,Ee),De=new Nd(F,Ee,Ce,Be),Oe=new Ld(F,De,Ee,Be,Ce),Ie=new Id(F,Se,we),Ne=new ld(L),ke=new Pp(T,Te,xe,Se,Be,Ne),Ae=new um(T,L),je=new zp,Me=new Kp(xe),Fe=new ad(T,Te,I,Oe,p,s),Pe=new em(T,Oe,Se),Ve=new dm(F,Ce,Se,I),Le=new sd(F,xe,Ce),Re=new Pd(F,xe,Ce),Ce.programs=ke.programs,T.capabilities=Se,T.extensions=xe,T.properties=L,T.renderLists=je,T.shadowMap=Pe,T.state=I,T.info=Ce}He(),m!==1009&&(w=new zd(m,t.width,t.height,r,i));let Ue=new sm(T,F);this.xr=Ue,this.getContext=function(){return F},this.getContextAttributes=function(){return F.getContextAttributes()},this.forceContextLoss=function(){let e=xe.get(`WEBGL_lose_context`);e&&e.loseContext()},this.forceContextRestore=function(){let e=xe.get(`WEBGL_lose_context`);e&&e.restoreContext()},this.getPixelRatio=function(){return se},this.setPixelRatio=function(e){e!==void 0&&(se=e,this.setSize(M,oe,!1))},this.getSize=function(e){return e.set(M,oe)},this.setSize=function(e,n,r=!0){if(Ue.isPresenting){z(`WebGLRenderer: Can't change size while VR device is presenting.`);return}M=e,oe=n,t.width=Math.floor(e*se),t.height=Math.floor(n*se),r===!0&&(t.style.width=e+`px`,t.style.height=n+`px`),w!==null&&w.setSize(t.width,t.height),this.setViewport(0,0,e,n)},this.getDrawingBufferSize=function(e){return e.set(M*se,oe*se).floor()},this.setDrawingBufferSize=function(e,n,r){M=e,oe=n,se=r,t.width=Math.floor(e*r),t.height=Math.floor(n*r),this.setViewport(0,0,e,n)},this.setEffects=function(e){if(m===1009){B(`THREE.WebGLRenderer: setEffects() requires outputBufferType set to HalfFloatType or FloatType.`);return}if(e){for(let t=0;t<e.length;t++)if(e[t].isOutputPass===!0){z(`THREE.WebGLRenderer: OutputPass is not needed in setEffects(). Tone mapping and color space conversion are applied automatically.`);break}}w.setEffects(e||[])},this.getCurrentViewport=function(e){return e.copy(ne)},this.getViewport=function(e){return e.copy(ue)},this.setViewport=function(e,t,n,r){e.isVector4?ue.set(e.x,e.y,e.z,e.w):ue.set(e,t,n,r),I.viewport(ne.copy(ue).multiplyScalar(se).round())},this.getScissor=function(e){return e.copy(de)},this.setScissor=function(e,t,n,r){e.isVector4?de.set(e.x,e.y,e.z,e.w):de.set(e,t,n,r),I.scissor(re.copy(de).multiplyScalar(se).round())},this.getScissorTest=function(){return fe},this.setScissorTest=function(e){I.setScissorTest(fe=e)},this.setOpaqueSort=function(e){ce=e},this.setTransparentSort=function(e){le=e},this.getClearColor=function(e){return e.copy(Fe.getClearColor())},this.setClearColor=function(){Fe.setClearColor(...arguments)},this.getClearAlpha=function(){return Fe.getClearAlpha()},this.setClearAlpha=function(){Fe.setClearAlpha(...arguments)},this.clear=function(e=!0,t=!0,n=!0){let r=0;if(e){let e=!1;if(A!==null){let t=A.texture.format;e=h.has(t)}if(e){let e=A.texture.type,t=g.has(e),n=Fe.getClearColor(),r=Fe.getClearAlpha(),i=n.r,a=n.g,o=n.b;t?(_[0]=i,_[1]=a,_[2]=o,_[3]=r,F.clearBufferuiv(F.COLOR,0,_)):(v[0]=i,v[1]=a,v[2]=o,v[3]=r,F.clearBufferiv(F.COLOR,0,v))}else r|=F.COLOR_BUFFER_BIT}t&&(r|=F.DEPTH_BUFFER_BIT,this.state.buffers.depth.setMask(!0)),n&&(r|=F.STENCIL_BUFFER_BIT,this.state.buffers.stencil.setMask(4294967295)),r!==0&&F.clear(r)},this.clearColor=function(){this.clear(!0,!1,!1)},this.clearDepth=function(){this.clear(!1,!0,!1)},this.clearStencil=function(){this.clear(!1,!1,!0)},this.setNodesHandler=function(e){e.setRenderer(this),D=e},this.dispose=function(){t.removeEventListener(`webglcontextlost`,We,!1),t.removeEventListener(`webglcontextrestored`,R,!1),t.removeEventListener(`webglcontextcreationerror`,Ge,!1),Fe.dispose(),je.dispose(),Me.dispose(),L.dispose(),Te.dispose(),Oe.dispose(),Be.dispose(),Ve.dispose(),ke.dispose(),Ue.dispose(),Ue.removeEventListener(`sessionstart`,Qe),Ue.removeEventListener(`sessionend`,$e),et.stop()};function We(e){e.preventDefault(),Hi(`WebGLRenderer: Context Lost.`),E=!0}function R(){Hi(`WebGLRenderer: Context Restored.`),E=!1;let e=Ce.autoReset,t=Pe.enabled,n=Pe.autoUpdate,r=Pe.needsUpdate,i=Pe.type;He(),Ce.autoReset=e,Pe.enabled=t,Pe.autoUpdate=n,Pe.needsUpdate=r,Pe.type=i}function Ge(e){B(`WebGLRenderer: A WebGL context could not be created. Reason: `,e.statusMessage)}function Ke(e){let t=e.target;t.removeEventListener(`dispose`,Ke),qe(t)}function qe(e){Je(e),L.remove(e)}function Je(e){let t=L.get(e).programs;t!==void 0&&(t.forEach(function(e){ke.releaseProgram(e)}),e.isShaderMaterial&&ke.releaseShaderCache(e))}this.renderBufferDirect=function(e,t,n,r,i,a){t===null&&(t=ye);let o=i.isMesh&&i.matrixWorld.determinant()<0,s=ut(e,t,n,r,i);I.setMaterial(r,o);let c=n.index,l=1;if(r.wireframe===!0){if(c=De.getWireframeAttribute(n),c===void 0)return;l=2}let u=n.drawRange,d=n.attributes.position,f=u.start*l,p=(u.start+u.count)*l;a!==null&&(f=Math.max(f,a.start*l),p=Math.min(p,(a.start+a.count)*l)),c===null?d!=null&&(f=Math.max(f,0),p=Math.min(p,d.count)):(f=Math.max(f,0),p=Math.min(p,c.count));let m=p-f;if(m<0||m===1/0)return;Be.setup(i,r,s,n,c);let h,g=Le;if(c!==null&&(h=Ee.get(c),g=Re,g.setIndex(h)),i.isMesh)r.wireframe===!0?(I.setLineWidth(r.wireframeLinewidth*P()),g.setMode(F.LINES)):g.setMode(F.TRIANGLES);else if(i.isLine){let e=r.linewidth;e===void 0&&(e=1),I.setLineWidth(e*P()),i.isLineSegments?g.setMode(F.LINES):i.isLineLoop?g.setMode(F.LINE_LOOP):g.setMode(F.LINE_STRIP)}else i.isPoints?g.setMode(F.POINTS):i.isSprite&&g.setMode(F.TRIANGLES);if(i.isBatchedMesh)if(xe.get(`WEBGL_multi_draw`))g.renderMultiDraw(i._multiDrawStarts,i._multiDrawCounts,i._multiDrawCount);else{let e=i._multiDrawStarts,t=i._multiDrawCounts,n=i._multiDrawCount,a=c?Ee.get(c).bytesPerElement:1,o=L.get(r).currentProgram.getUniforms();for(let r=0;r<n;r++)o.setValue(F,`_gl_DrawID`,r),g.render(e[r]/a,t[r])}else if(i.isInstancedMesh)g.renderInstances(f,m,i.count);else if(n.isInstancedBufferGeometry){let e=n._maxInstanceCount===void 0?1/0:n._maxInstanceCount,t=Math.min(n.instanceCount,e);g.renderInstances(f,m,t)}else g.render(f,m)};function Ye(e,t,n){e.transparent===!0&&e.side===2&&e.forceSinglePass===!1?(e.side=1,e.needsUpdate=!0,ot(e,t,n),e.side=0,e.needsUpdate=!0,ot(e,t,n),e.side=2):ot(e,t,n)}this.compile=function(e,t,n=null){n===null&&(n=e),x=Me.get(n),x.init(t),C.push(x),n.traverseVisible(function(e){e.isLight&&e.layers.test(t.layers)&&(x.pushLight(e),e.castShadow&&x.pushShadow(e))}),e!==n&&e.traverseVisible(function(e){e.isLight&&e.layers.test(t.layers)&&(x.pushLight(e),e.castShadow&&x.pushShadow(e))}),x.setupLights();let r=new Set;return e.traverse(function(e){if(!(e.isMesh||e.isPoints||e.isLine||e.isSprite))return;let t=e.material;if(t)if(Array.isArray(t))for(let i=0;i<t.length;i++){let a=t[i];Ye(a,n,e),r.add(a)}else Ye(t,n,e),r.add(t)}),x=C.pop(),r},this.compileAsync=function(e,t,n=null){let r=this.compile(e,t,n);return new Promise(t=>{function n(){if(r.forEach(function(e){L.get(e).currentProgram.isReady()&&r.delete(e)}),r.size===0){t(e);return}setTimeout(n,10)}xe.get(`KHR_parallel_shader_compile`)===null?setTimeout(n,10):n()})};let Xe=null;function Ze(e){Xe&&Xe(e)}function Qe(){et.stop()}function $e(){et.start()}let et=new $u;et.setAnimationLoop(Ze),typeof self<`u`&&et.setContext(self),this.setAnimationLoop=function(e){Xe=e,Ue.setAnimationLoop(e),e===null?et.stop():et.start()},Ue.addEventListener(`sessionstart`,Qe),Ue.addEventListener(`sessionend`,$e),this.render=function(e,t){if(t!==void 0&&t.isCamera!==!0){B(`WebGLRenderer.render: camera is not an instance of THREE.Camera.`);return}if(E===!0)return;D!==null&&D.renderStart(e,t);let n=Ue.enabled===!0&&Ue.isPresenting===!0,r=w!==null&&(A===null||n)&&w.begin(T,A);if(e.matrixWorldAutoUpdate===!0&&e.updateMatrixWorld(),t.parent===null&&t.matrixWorldAutoUpdate===!0&&t.updateMatrixWorld(),Ue.enabled===!0&&Ue.isPresenting===!0&&(w===null||w.isCompositing()===!1)&&(Ue.cameraAutoUpdate===!0&&Ue.updateCamera(t),t=Ue.getCamera()),e.isScene===!0&&e.onBeforeRender(T,e,t,A),x=Me.get(e,C.length),x.init(t),x.state.textureUnits=we.getTextureUnits(),C.push(x),ge.multiplyMatrices(t.projectionMatrix,t.matrixWorldInverse),pe.setFromProjectionMatrix(ge,Fi,t.reversedDepth),he=this.localClippingEnabled,me=Ne.init(this.clippingPlanes,he),b=je.get(e,S.length),b.init(),S.push(b),Ue.enabled===!0&&Ue.isPresenting===!0){let e=T.xr.getDepthSensingMesh();e!==null&&tt(e,t,-1/0,T.sortObjects)}tt(e,t,0,T.sortObjects),b.finish(),T.sortObjects===!0&&b.sort(ce,le),N=Ue.enabled===!1||Ue.isPresenting===!1||Ue.hasDepthSensing()===!1,N&&Fe.addToRenderList(b,e),this.info.render.frame++,me===!0&&Ne.beginShadows();let i=x.state.shadowsArray;if(Pe.render(i,e,t),me===!0&&Ne.endShadows(),this.info.autoReset===!0&&this.info.reset(),(r&&w.hasRenderPass())===!1){let n=b.opaque,r=b.transmissive;if(x.setupLights(),t.isArrayCamera){let i=t.cameras;if(r.length>0)for(let t=0,a=i.length;t<a;t++){let a=i[t];rt(n,r,e,a)}N&&Fe.render(e);for(let t=0,n=i.length;t<n;t++){let n=i[t];nt(b,e,n,n.viewport)}}else r.length>0&&rt(n,r,e,t),N&&Fe.render(e),nt(b,e,t)}A!==null&&k===0&&(we.updateMultisampleRenderTarget(A),we.updateRenderTargetMipmap(A)),r&&w.end(T),e.isScene===!0&&e.onAfterRender(T,e,t),Be.resetDefaultState(),ee=-1,te=null,C.pop(),C.length>0?(x=C[C.length-1],we.setTextureUnits(x.state.textureUnits),me===!0&&Ne.setGlobalState(T.clippingPlanes,x.state.camera)):x=null,S.pop(),b=S.length>0?S[S.length-1]:null,D!==null&&D.renderEnd()};function tt(e,t,n,r){if(e.visible===!1)return;if(e.layers.test(t.layers)){if(e.isGroup)n=e.renderOrder;else if(e.isLOD)e.autoUpdate===!0&&e.update(t);else if(e.isLightProbeGrid)x.pushLightProbeGrid(e);else if(e.isLight)x.pushLight(e),e.castShadow&&x.pushShadow(e);else if(e.isSprite){if(!e.frustumCulled||pe.intersectsSprite(e)){r&&ve.setFromMatrixPosition(e.matrixWorld).applyMatrix4(ge);let t=Oe.update(e),i=e.material;i.visible&&b.push(e,t,i,n,ve.z,null)}}else if((e.isMesh||e.isLine||e.isPoints)&&(!e.frustumCulled||pe.intersectsObject(e))){let t=Oe.update(e),i=e.material;if(r&&(e.boundingSphere===void 0?(t.boundingSphere===null&&t.computeBoundingSphere(),ve.copy(t.boundingSphere.center)):(e.boundingSphere===null&&e.computeBoundingSphere(),ve.copy(e.boundingSphere.center)),ve.applyMatrix4(e.matrixWorld).applyMatrix4(ge)),Array.isArray(i)){let r=t.groups;for(let a=0,o=r.length;a<o;a++){let o=r[a],s=i[o.materialIndex];s&&s.visible&&b.push(e,t,s,n,ve.z,o)}}else i.visible&&b.push(e,t,i,n,ve.z,null)}}let i=e.children;for(let e=0,a=i.length;e<a;e++)tt(i[e],t,n,r)}function nt(e,t,n,r){let{opaque:i,transmissive:a,transparent:o}=e;x.setupLightsView(n),me===!0&&Ne.setGlobalState(T.clippingPlanes,n),r&&I.viewport(ne.copy(r)),i.length>0&&it(i,t,n),a.length>0&&it(a,t,n),o.length>0&&it(o,t,n),I.buffers.depth.setTest(!0),I.buffers.depth.setMask(!0),I.buffers.color.setMask(!0),I.setPolygonOffset(!1)}function rt(e,t,n,r){if((n.isScene===!0?n.overrideMaterial:null)!==null)return;if(x.state.transmissionRenderTarget[r.id]===void 0){let e=xe.has(`EXT_color_buffer_half_float`)||xe.has(`EXT_color_buffer_float`);x.state.transmissionRenderTarget[r.id]=new Ba(1,1,{generateMipmaps:!0,type:e?gr:lr,minFilter:cr,samples:Math.max(4,Se.samples),stencilBuffer:i,resolveDepthBuffer:!1,resolveStencilBuffer:!1,colorSpace:Da.workingColorSpace})}let a=x.state.transmissionRenderTarget[r.id],o=r.viewport||ne;a.setSize(o.z*T.transmissionResolutionScale,o.w*T.transmissionResolutionScale);let s=T.getRenderTarget(),c=T.getActiveCubeFace(),l=T.getActiveMipmapLevel();T.setRenderTarget(a),T.getClearColor(ie),ae=T.getClearAlpha(),ae<1&&T.setClearColor(16777215,.5),T.clear(),N&&Fe.render(n);let u=T.toneMapping;T.toneMapping=0;let d=r.viewport;if(r.viewport!==void 0&&(r.viewport=void 0),x.setupLightsView(r),me===!0&&Ne.setGlobalState(T.clippingPlanes,r),it(e,n,r),we.updateMultisampleRenderTarget(a),we.updateRenderTargetMipmap(a),xe.has(`WEBGL_multisampled_render_to_texture`)===!1){let e=!1;for(let i=0,a=t.length;i<a;i++){let{object:a,geometry:o,material:s,group:c}=t[i];if(s.side===2&&a.layers.test(r.layers)){let t=s.side;s.side=1,s.needsUpdate=!0,at(a,n,r,o,s,c),s.side=t,s.needsUpdate=!0,e=!0}}e===!0&&(we.updateMultisampleRenderTarget(a),we.updateRenderTargetMipmap(a))}T.setRenderTarget(s,c,l),T.setClearColor(ie,ae),d!==void 0&&(r.viewport=d),T.toneMapping=u}function it(e,t,n){let r=t.isScene===!0?t.overrideMaterial:null;for(let i=0,a=e.length;i<a;i++){let a=e[i],{object:o,geometry:s,group:c}=a,l=a.material;l.allowOverride===!0&&r!==null&&(l=r),o.layers.test(n.layers)&&at(o,t,n,s,l,c)}}function at(e,t,n,r,i,a){e.onBeforeRender(T,t,n,r,i,a),e.modelViewMatrix.multiplyMatrices(n.matrixWorldInverse,e.matrixWorld),e.normalMatrix.getNormalMatrix(e.modelViewMatrix),i.onBeforeRender(T,t,n,r,e,a),i.transparent===!0&&i.side===2&&i.forceSinglePass===!1?(i.side=1,i.needsUpdate=!0,T.renderBufferDirect(n,t,r,i,e,a),i.side=0,i.needsUpdate=!0,T.renderBufferDirect(n,t,r,i,e,a),i.side=2):T.renderBufferDirect(n,t,r,i,e,a),e.onAfterRender(T,t,n,r,i,a)}function ot(e,t,n){t.isScene!==!0&&(t=ye);let r=L.get(e),i=x.state.lights,a=x.state.shadowsArray,o=i.state.version,s=ke.getParameters(e,i.state,a,t,n,x.state.lightProbeGridArray),c=ke.getProgramCacheKey(s),l=r.programs;r.environment=e.isMeshStandardMaterial||e.isMeshLambertMaterial||e.isMeshPhongMaterial?t.environment:null,r.fog=t.fog;let u=e.isMeshStandardMaterial||e.isMeshLambertMaterial&&!e.envMap||e.isMeshPhongMaterial&&!e.envMap;r.envMap=Te.get(e.envMap||r.environment,u),r.envMapRotation=r.environment!==null&&e.envMap===null?t.environmentRotation:e.envMapRotation,l===void 0&&(e.addEventListener(`dispose`,Ke),l=new Map,r.programs=l);let d=l.get(c);if(d!==void 0){if(r.currentProgram===d&&r.lightsStateVersion===o)return ct(e,s),d}else s.uniforms=ke.getUniforms(e),D!==null&&e.isNodeMaterial&&D.build(e,n,s),e.onBeforeCompile(s,T),d=ke.acquireProgram(s,c),l.set(c,d),r.uniforms=s.uniforms;let f=r.uniforms;return(!e.isShaderMaterial&&!e.isRawShaderMaterial||e.clipping===!0)&&(f.clippingPlanes=Ne.uniform),ct(e,s),r.needsLights=ft(e),r.lightsStateVersion=o,r.needsLights&&(f.ambientLightColor.value=i.state.ambient,f.lightProbe.value=i.state.probe,f.directionalLights.value=i.state.directional,f.directionalLightShadows.value=i.state.directionalShadow,f.spotLights.value=i.state.spot,f.spotLightShadows.value=i.state.spotShadow,f.rectAreaLights.value=i.state.rectArea,f.ltc_1.value=i.state.rectAreaLTC1,f.ltc_2.value=i.state.rectAreaLTC2,f.pointLights.value=i.state.point,f.pointLightShadows.value=i.state.pointShadow,f.hemisphereLights.value=i.state.hemi,f.directionalShadowMatrix.value=i.state.directionalShadowMatrix,f.spotLightMatrix.value=i.state.spotLightMatrix,f.spotLightMap.value=i.state.spotLightMap,f.pointShadowMatrix.value=i.state.pointShadowMatrix),r.lightProbeGrid=x.state.lightProbeGridArray.length>0,r.currentProgram=d,r.uniformsList=null,d}function st(e){if(e.uniformsList===null){let t=e.currentProgram.getUniforms();e.uniformsList=qf.seqWithValue(t.seq,e.uniforms)}return e.uniformsList}function ct(e,t){let n=L.get(e);n.outputColorSpace=t.outputColorSpace,n.batching=t.batching,n.batchingColor=t.batchingColor,n.instancing=t.instancing,n.instancingColor=t.instancingColor,n.instancingMorph=t.instancingMorph,n.skinning=t.skinning,n.morphTargets=t.morphTargets,n.morphNormals=t.morphNormals,n.morphColors=t.morphColors,n.morphTargetsCount=t.morphTargetsCount,n.numClippingPlanes=t.numClippingPlanes,n.numIntersection=t.numClipIntersection,n.vertexAlphas=t.vertexAlphas,n.vertexTangents=t.vertexTangents,n.toneMapping=t.toneMapping}function lt(e,t){if(e.length===0)return null;if(e.length===1)return e[0].texture===null?null:e[0];y.setFromMatrixPosition(t.matrixWorld);for(let t=0,n=e.length;t<n;t++){let n=e[t];if(n.texture!==null&&n.boundingBox.containsPoint(y))return n}return null}function ut(e,t,n,r,i){t.isScene!==!0&&(t=ye),we.resetTextureUnits();let a=t.fog,o=r.isMeshStandardMaterial||r.isMeshLambertMaterial||r.isMeshPhongMaterial?t.environment:null,s=A===null?T.outputColorSpace:A.isXRRenderTarget===!0?A.texture.colorSpace:Da.workingColorSpace,c=r.isMeshStandardMaterial||r.isMeshLambertMaterial&&!r.envMap||r.isMeshPhongMaterial&&!r.envMap,l=Te.get(r.envMap||o,c),u=r.vertexColors===!0&&!!n.attributes.color&&n.attributes.color.itemSize===4,d=!!n.attributes.tangent&&(!!r.normalMap||r.anisotropy>0),f=!!n.morphAttributes.position,p=!!n.morphAttributes.normal,m=!!n.morphAttributes.color,h=0;r.toneMapped&&(A===null||A.isXRRenderTarget===!0)&&(h=T.toneMapping);let g=n.morphAttributes.position||n.morphAttributes.normal||n.morphAttributes.color,_=g===void 0?0:g.length,v=L.get(r),y=x.state.lights;if(me===!0&&(he===!0||e!==te)){let t=e===te&&r.id===ee;Ne.setState(r,e,t)}let b=!1;r.version===v.__version?v.needsLights&&v.lightsStateVersion!==y.state.version?b=!0:v.outputColorSpace===s?i.isBatchedMesh&&v.batching===!1||!i.isBatchedMesh&&v.batching===!0||i.isBatchedMesh&&v.batchingColor===!0&&i.colorTexture===null||i.isBatchedMesh&&v.batchingColor===!1&&i.colorTexture!==null||i.isInstancedMesh&&v.instancing===!1||!i.isInstancedMesh&&v.instancing===!0||i.isSkinnedMesh&&v.skinning===!1||!i.isSkinnedMesh&&v.skinning===!0||i.isInstancedMesh&&v.instancingColor===!0&&i.instanceColor===null||i.isInstancedMesh&&v.instancingColor===!1&&i.instanceColor!==null||i.isInstancedMesh&&v.instancingMorph===!0&&i.morphTexture===null||i.isInstancedMesh&&v.instancingMorph===!1&&i.morphTexture!==null?b=!0:v.envMap===l?r.fog===!0&&v.fog!==a||v.numClippingPlanes!==void 0&&(v.numClippingPlanes!==Ne.numPlanes||v.numIntersection!==Ne.numIntersection)?b=!0:v.vertexAlphas===u&&v.vertexTangents===d&&v.morphTargets===f&&v.morphNormals===p&&v.morphColors===m&&v.toneMapping===h&&v.morphTargetsCount===_?!!v.lightProbeGrid!=x.state.lightProbeGridArray.length>0&&(b=!0):b=!0:b=!0:b=!0:(b=!0,v.__version=r.version);let S=v.currentProgram;b===!0&&(S=ot(r,t,i),D&&r.isNodeMaterial&&D.onUpdateProgram(r,S,v));let C=!1,w=!1,E=!1,O=S.getUniforms(),k=v.uniforms;if(I.useProgram(S.program)&&(C=!0,w=!0,E=!0),r.id!==ee&&(ee=r.id,w=!0),v.needsLights){let e=lt(x.state.lightProbeGridArray,i);v.lightProbeGrid!==e&&(v.lightProbeGrid=e,w=!0)}if(C||te!==e){I.buffers.depth.getReversed()&&e.reversedDepth!==!0&&(e._reversedDepth=!0,e.updateProjectionMatrix()),O.setValue(F,`projectionMatrix`,e.projectionMatrix),O.setValue(F,`viewMatrix`,e.matrixWorldInverse);let t=O.map.cameraPosition;t!==void 0&&t.setValue(F,_e.setFromMatrixPosition(e.matrixWorld)),Se.logarithmicDepthBuffer&&O.setValue(F,`logDepthBufFC`,2/(Math.log(e.far+1)/Math.LN2)),(r.isMeshPhongMaterial||r.isMeshToonMaterial||r.isMeshLambertMaterial||r.isMeshBasicMaterial||r.isMeshStandardMaterial||r.isShaderMaterial)&&O.setValue(F,`isOrthographic`,e.isOrthographicCamera===!0),te!==e&&(te=e,w=!0,E=!0)}if(v.needsLights&&(y.state.directionalShadowMap.length>0&&O.setValue(F,`directionalShadowMap`,y.state.directionalShadowMap,we),y.state.spotShadowMap.length>0&&O.setValue(F,`spotShadowMap`,y.state.spotShadowMap,we),y.state.pointShadowMap.length>0&&O.setValue(F,`pointShadowMap`,y.state.pointShadowMap,we)),i.isSkinnedMesh){O.setOptional(F,i,`bindMatrix`),O.setOptional(F,i,`bindMatrixInverse`);let e=i.skeleton;e&&(e.boneTexture===null&&e.computeBoneTexture(),O.setValue(F,`boneTexture`,e.boneTexture,we))}i.isBatchedMesh&&(O.setOptional(F,i,`batchingTexture`),O.setValue(F,`batchingTexture`,i._matricesTexture,we),O.setOptional(F,i,`batchingIdTexture`),O.setValue(F,`batchingIdTexture`,i._indirectTexture,we),O.setOptional(F,i,`batchingColorTexture`),i._colorsTexture!==null&&O.setValue(F,`batchingColorTexture`,i._colorsTexture,we));let ne=n.morphAttributes;if((ne.position!==void 0||ne.normal!==void 0||ne.color!==void 0)&&Ie.update(i,n,S),(w||v.receiveShadow!==i.receiveShadow)&&(v.receiveShadow=i.receiveShadow,O.setValue(F,`receiveShadow`,i.receiveShadow)),(r.isMeshStandardMaterial||r.isMeshLambertMaterial||r.isMeshPhongMaterial)&&r.envMap===null&&t.environment!==null&&(k.envMapIntensity.value=t.environmentIntensity),k.dfgLUT!==void 0&&(k.dfgLUT.value=mm()),w){if(O.setValue(F,`toneMappingExposure`,T.toneMappingExposure),v.needsLights&&dt(k,E),a&&r.fog===!0&&Ae.refreshFogUniforms(k,a),Ae.refreshMaterialUniforms(k,r,se,oe,x.state.transmissionRenderTarget[e.id]),v.needsLights&&v.lightProbeGrid){let e=v.lightProbeGrid;k.probesSH.value=e.texture,k.probesMin.value.copy(e.boundingBox.min),k.probesMax.value.copy(e.boundingBox.max),k.probesResolution.value.copy(e.resolution)}qf.upload(F,st(v),k,we)}if(r.isShaderMaterial&&r.uniformsNeedUpdate===!0&&(qf.upload(F,st(v),k,we),r.uniformsNeedUpdate=!1),r.isSpriteMaterial&&O.setValue(F,`center`,i.center),O.setValue(F,`modelViewMatrix`,i.modelViewMatrix),O.setValue(F,`normalMatrix`,i.normalMatrix),O.setValue(F,`modelMatrix`,i.matrixWorld),r.uniformsGroups!==void 0){let e=r.uniformsGroups;for(let t=0,n=e.length;t<n;t++){let n=e[t];Ve.update(n,S),Ve.bind(n,S)}}return S}function dt(e,t){e.ambientLightColor.needsUpdate=t,e.lightProbe.needsUpdate=t,e.directionalLights.needsUpdate=t,e.directionalLightShadows.needsUpdate=t,e.pointLights.needsUpdate=t,e.pointLightShadows.needsUpdate=t,e.spotLights.needsUpdate=t,e.spotLightShadows.needsUpdate=t,e.rectAreaLights.needsUpdate=t,e.hemisphereLights.needsUpdate=t}function ft(e){return e.isMeshLambertMaterial||e.isMeshToonMaterial||e.isMeshPhongMaterial||e.isMeshStandardMaterial||e.isShadowMaterial||e.isShaderMaterial&&e.lights===!0}this.getActiveCubeFace=function(){return O},this.getActiveMipmapLevel=function(){return k},this.getRenderTarget=function(){return A},this.setRenderTargetTextures=function(e,t,n){let r=L.get(e);r.__autoAllocateDepthBuffer=e.resolveDepthBuffer===!1,r.__autoAllocateDepthBuffer===!1&&(r.__useRenderToTexture=!1),L.get(e.texture).__webglTexture=t,L.get(e.depthTexture).__webglTexture=r.__autoAllocateDepthBuffer?void 0:n,r.__hasExternalTextures=!0},this.setRenderTargetFramebuffer=function(e,t){let n=L.get(e);n.__webglFramebuffer=t,n.__useDefaultFramebuffer=t===void 0};let pt=F.createFramebuffer();this.setRenderTarget=function(e,t=0,n=0){A=e,O=t,k=n;let r=null,i=!1,a=!1;if(e){let o=L.get(e);if(o.__useDefaultFramebuffer!==void 0){I.bindFramebuffer(F.FRAMEBUFFER,o.__webglFramebuffer),ne.copy(e.viewport),re.copy(e.scissor),j=e.scissorTest,I.viewport(ne),I.scissor(re),I.setScissorTest(j),ee=-1;return}else if(o.__webglFramebuffer===void 0)we.setupRenderTarget(e);else if(o.__hasExternalTextures)we.rebindTextures(e,L.get(e.texture).__webglTexture,L.get(e.depthTexture).__webglTexture);else if(e.depthBuffer){let t=e.depthTexture;if(o.__boundDepthTexture!==t){if(t!==null&&L.has(t)&&(e.width!==t.image.width||e.height!==t.image.height))throw Error(`WebGLRenderTarget: Attached DepthTexture is initialized to the incorrect size.`);we.setupDepthRenderbuffer(e)}}let s=e.texture;(s.isData3DTexture||s.isDataArrayTexture||s.isCompressedArrayTexture)&&(a=!0);let c=L.get(e).__webglFramebuffer;e.isWebGLCubeRenderTarget?(r=Array.isArray(c[t])?c[t][n]:c[t],i=!0):r=e.samples>0&&we.useMultisampledRTT(e)===!1?L.get(e).__webglMultisampledFramebuffer:Array.isArray(c)?c[n]:c,ne.copy(e.viewport),re.copy(e.scissor),j=e.scissorTest}else ne.copy(ue).multiplyScalar(se).floor(),re.copy(de).multiplyScalar(se).floor(),j=fe;if(n!==0&&(r=pt),I.bindFramebuffer(F.FRAMEBUFFER,r)&&I.drawBuffers(e,r),I.viewport(ne),I.scissor(re),I.setScissorTest(j),i){let r=L.get(e.texture);F.framebufferTexture2D(F.FRAMEBUFFER,F.COLOR_ATTACHMENT0,F.TEXTURE_CUBE_MAP_POSITIVE_X+t,r.__webglTexture,n)}else if(a){let r=t;for(let t=0;t<e.textures.length;t++){let i=L.get(e.textures[t]);F.framebufferTextureLayer(F.FRAMEBUFFER,F.COLOR_ATTACHMENT0+t,i.__webglTexture,n,r)}}else if(e!==null&&n!==0){let t=L.get(e.texture);F.framebufferTexture2D(F.FRAMEBUFFER,F.COLOR_ATTACHMENT0,F.TEXTURE_2D,t.__webglTexture,n)}ee=-1},this.readRenderTargetPixels=function(e,t,n,r,i,a,o,s=0){if(!(e&&e.isWebGLRenderTarget)){B(`WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.`);return}let c=L.get(e).__webglFramebuffer;if(e.isWebGLCubeRenderTarget&&o!==void 0&&(c=c[o]),c){I.bindFramebuffer(F.FRAMEBUFFER,c);try{let o=e.textures[s],c=o.format,l=o.type;if(e.textures.length>1&&F.readBuffer(F.COLOR_ATTACHMENT0+s),!Se.textureFormatReadable(c)){B(`WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format.`);return}if(!Se.textureTypeReadable(l)){B(`WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type.`);return}t>=0&&t<=e.width-r&&n>=0&&n<=e.height-i&&F.readPixels(t,n,r,i,ze.convert(c),ze.convert(l),a)}finally{let e=A===null?null:L.get(A).__webglFramebuffer;I.bindFramebuffer(F.FRAMEBUFFER,e)}}},this.readRenderTargetPixelsAsync=async function(e,t,n,r,i,a,o,s=0){if(!(e&&e.isWebGLRenderTarget))throw Error(`THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.`);let c=L.get(e).__webglFramebuffer;if(e.isWebGLCubeRenderTarget&&o!==void 0&&(c=c[o]),c)if(t>=0&&t<=e.width-r&&n>=0&&n<=e.height-i){I.bindFramebuffer(F.FRAMEBUFFER,c);let o=e.textures[s],l=o.format,u=o.type;if(e.textures.length>1&&F.readBuffer(F.COLOR_ATTACHMENT0+s),!Se.textureFormatReadable(l))throw Error(`THREE.WebGLRenderer.readRenderTargetPixelsAsync: renderTarget is not in RGBA or implementation defined format.`);if(!Se.textureTypeReadable(u))throw Error(`THREE.WebGLRenderer.readRenderTargetPixelsAsync: renderTarget is not in UnsignedByteType or implementation defined type.`);let d=F.createBuffer();F.bindBuffer(F.PIXEL_PACK_BUFFER,d),F.bufferData(F.PIXEL_PACK_BUFFER,a.byteLength,F.STREAM_READ),F.readPixels(t,n,r,i,ze.convert(l),ze.convert(u),0);let f=A===null?null:L.get(A).__webglFramebuffer;I.bindFramebuffer(F.FRAMEBUFFER,f);let p=F.fenceSync(F.SYNC_GPU_COMMANDS_COMPLETE,0);return F.flush(),await Gi(F,p,4),F.bindBuffer(F.PIXEL_PACK_BUFFER,d),F.getBufferSubData(F.PIXEL_PACK_BUFFER,0,a),F.deleteBuffer(d),F.deleteSync(p),a}else throw Error(`THREE.WebGLRenderer.readRenderTargetPixelsAsync: requested read bounds are out of range.`)},this.copyFramebufferToTexture=function(e,t=null,n=0){let r=2**-n,i=Math.floor(e.image.width*r),a=Math.floor(e.image.height*r),o=t===null?0:t.x,s=t===null?0:t.y;we.setTexture2D(e,0),F.copyTexSubImage2D(F.TEXTURE_2D,n,0,0,o,s,i,a),I.unbindTexture()};let mt=F.createFramebuffer(),ht=F.createFramebuffer();this.copyTextureToTexture=function(e,t,n=null,r=null,i=0,a=0){let o,s,c,l,u,d,f,p,m,h=e.isCompressedTexture?e.mipmaps[a]:e.image;if(n!==null)o=n.max.x-n.min.x,s=n.max.y-n.min.y,c=n.isBox3?n.max.z-n.min.z:1,l=n.min.x,u=n.min.y,d=n.isBox3?n.min.z:0;else{let t=2**-i;o=Math.floor(h.width*t),s=Math.floor(h.height*t),c=e.isDataArrayTexture?h.depth:e.isData3DTexture?Math.floor(h.depth*t):1,l=0,u=0,d=0}r===null?(f=0,p=0,m=0):(f=r.x,p=r.y,m=r.z);let g=ze.convert(t.format),_=ze.convert(t.type),v;t.isData3DTexture?(we.setTexture3D(t,0),v=F.TEXTURE_3D):t.isDataArrayTexture||t.isCompressedArrayTexture?(we.setTexture2DArray(t,0),v=F.TEXTURE_2D_ARRAY):(we.setTexture2D(t,0),v=F.TEXTURE_2D),I.activeTexture(F.TEXTURE0),I.pixelStorei(F.UNPACK_FLIP_Y_WEBGL,t.flipY),I.pixelStorei(F.UNPACK_PREMULTIPLY_ALPHA_WEBGL,t.premultiplyAlpha),I.pixelStorei(F.UNPACK_ALIGNMENT,t.unpackAlignment);let y=I.getParameter(F.UNPACK_ROW_LENGTH),b=I.getParameter(F.UNPACK_IMAGE_HEIGHT),x=I.getParameter(F.UNPACK_SKIP_PIXELS),S=I.getParameter(F.UNPACK_SKIP_ROWS),C=I.getParameter(F.UNPACK_SKIP_IMAGES);I.pixelStorei(F.UNPACK_ROW_LENGTH,h.width),I.pixelStorei(F.UNPACK_IMAGE_HEIGHT,h.height),I.pixelStorei(F.UNPACK_SKIP_PIXELS,l),I.pixelStorei(F.UNPACK_SKIP_ROWS,u),I.pixelStorei(F.UNPACK_SKIP_IMAGES,d);let w=e.isDataArrayTexture||e.isData3DTexture,T=t.isDataArrayTexture||t.isData3DTexture;if(e.isDepthTexture){let n=L.get(e),r=L.get(t),h=L.get(n.__renderTarget),g=L.get(r.__renderTarget);I.bindFramebuffer(F.READ_FRAMEBUFFER,h.__webglFramebuffer),I.bindFramebuffer(F.DRAW_FRAMEBUFFER,g.__webglFramebuffer);for(let n=0;n<c;n++)w&&(F.framebufferTextureLayer(F.READ_FRAMEBUFFER,F.COLOR_ATTACHMENT0,L.get(e).__webglTexture,i,d+n),F.framebufferTextureLayer(F.DRAW_FRAMEBUFFER,F.COLOR_ATTACHMENT0,L.get(t).__webglTexture,a,m+n)),F.blitFramebuffer(l,u,o,s,f,p,o,s,F.DEPTH_BUFFER_BIT,F.NEAREST);I.bindFramebuffer(F.READ_FRAMEBUFFER,null),I.bindFramebuffer(F.DRAW_FRAMEBUFFER,null)}else if(i!==0||e.isRenderTargetTexture||L.has(e)){let n=L.get(e),r=L.get(t);I.bindFramebuffer(F.READ_FRAMEBUFFER,mt),I.bindFramebuffer(F.DRAW_FRAMEBUFFER,ht);for(let e=0;e<c;e++)w?F.framebufferTextureLayer(F.READ_FRAMEBUFFER,F.COLOR_ATTACHMENT0,n.__webglTexture,i,d+e):F.framebufferTexture2D(F.READ_FRAMEBUFFER,F.COLOR_ATTACHMENT0,F.TEXTURE_2D,n.__webglTexture,i),T?F.framebufferTextureLayer(F.DRAW_FRAMEBUFFER,F.COLOR_ATTACHMENT0,r.__webglTexture,a,m+e):F.framebufferTexture2D(F.DRAW_FRAMEBUFFER,F.COLOR_ATTACHMENT0,F.TEXTURE_2D,r.__webglTexture,a),i===0?T?F.copyTexSubImage3D(v,a,f,p,m+e,l,u,o,s):F.copyTexSubImage2D(v,a,f,p,l,u,o,s):F.blitFramebuffer(l,u,o,s,f,p,o,s,F.COLOR_BUFFER_BIT,F.NEAREST);I.bindFramebuffer(F.READ_FRAMEBUFFER,null),I.bindFramebuffer(F.DRAW_FRAMEBUFFER,null)}else T?e.isDataTexture||e.isData3DTexture?F.texSubImage3D(v,a,f,p,m,o,s,c,g,_,h.data):t.isCompressedArrayTexture?F.compressedTexSubImage3D(v,a,f,p,m,o,s,c,g,h.data):F.texSubImage3D(v,a,f,p,m,o,s,c,g,_,h):e.isDataTexture?F.texSubImage2D(F.TEXTURE_2D,a,f,p,o,s,g,_,h.data):e.isCompressedTexture?F.compressedTexSubImage2D(F.TEXTURE_2D,a,f,p,h.width,h.height,g,h.data):F.texSubImage2D(F.TEXTURE_2D,a,f,p,o,s,g,_,h);I.pixelStorei(F.UNPACK_ROW_LENGTH,y),I.pixelStorei(F.UNPACK_IMAGE_HEIGHT,b),I.pixelStorei(F.UNPACK_SKIP_PIXELS,x),I.pixelStorei(F.UNPACK_SKIP_ROWS,S),I.pixelStorei(F.UNPACK_SKIP_IMAGES,C),a===0&&t.generateMipmaps&&F.generateMipmap(v),I.unbindTexture()},this.initRenderTarget=function(e){L.get(e).__webglFramebuffer===void 0&&we.setupRenderTarget(e)},this.initTexture=function(e){e.isCubeTexture?we.setTextureCube(e,0):e.isData3DTexture?we.setTexture3D(e,0):e.isDataArrayTexture||e.isCompressedArrayTexture?we.setTexture2DArray(e,0):we.setTexture2D(e,0),I.unbindTexture()},this.resetState=function(){O=0,k=0,A=null,I.reset(),Be.reset()},typeof __THREE_DEVTOOLS__<`u`&&__THREE_DEVTOOLS__.dispatchEvent(new CustomEvent(`observe`,{detail:this}))}get coordinateSystem(){return Fi}get outputColorSpace(){return this._outputColorSpace}set outputColorSpace(e){this._outputColorSpace=e;let t=this.getContext();t.drawingBufferColorSpace=Da._getDrawingBufferColorSpace(e),t.unpackColorSpace=Da._getUnpackColorSpace()}},gm=class{engine;entries=new Map;loader;constructor(e,t=null){this.engine=t,this.loader=e??((e,t)=>new eu().load(e,()=>t?.onLoad?.(),void 0,e=>t?.onError?.(e)))}load(e){for(let[t,n]of Object.entries(e)){let e=n.type;if(e!==`texture`&&e!==`spritesheet`)throw new N(`BAD_FORMAT`,`Asset '${t}': "type" must be 'texture' or 'spritesheet', got ${JSON.stringify(e)}.`);if(typeof n.url!=`string`||n.url===``)throw new N(`BAD_FORMAT`,`Asset '${t}': "url" must be a non-empty string.`);let r,i;if(e===`spritesheet`){if(typeof n.frameWidth!=`number`||typeof n.frameHeight!=`number`)throw new N(`BAD_FORMAT`,`Asset '${t}': spritesheets need numeric "frameWidth" and "frameHeight".`);r=n.frameWidth,i=n.frameHeight}let a=this.entries.get(t),o={status:`loading`},s=this.loader(n.url,{onLoad:()=>{o.status=`ready`},onError:e=>{o.status=`error`,lt(this.engine,`error`,`[incanto] failed to load texture '${t}' (${n.url}):`,e)}});a&&a.texture!==s&&a.texture.dispose(),s.colorSpace=Oi,n.filter===`nearest`?(s.magFilter=rr,s.minFilter=rr,s.generateMipmaps=!1):s.magFilter=or,s.needsUpdate=!0,this.entries.set(t,{texture:s,type:e,frameWidth:r,frameHeight:i,state:o})}}status(e){return this.entries.get(e)?.state.status}getTexture(e){return this.resolve(e).texture}getSheet(e){let t=this.resolve(e);if(t.type!==`spritesheet`)throw new N(`BAD_FORMAT`,`Asset '${e}' is a plain texture; a spritesheet (with frameWidth/frameHeight) is required here.`);return{texture:t.texture,frameWidth:t.frameWidth,frameHeight:t.frameHeight}}resolve(e){if(!e.startsWith(`$`))throw new N(`UNKNOWN_ASSET`,`Asset reference '${e}' must use the '$key' form (e.g. '$${e}').`);let t=this.entries.get(e.slice(1));if(!t)throw new N(`UNKNOWN_ASSET`,`Unknown asset '${e}'. Declared assets: [${[...this.entries.keys()].join(`, `)}].`);return t}},_m=`modulepreload`,vm=function(e,t){return new URL(e,t).href},ym={},bm=function(e,t,n){let r=Promise.resolve();if(t&&t.length>0){let e=document.getElementsByTagName(`link`),i=document.querySelector(`meta[property=csp-nonce]`),a=i?.nonce||i?.getAttribute(`nonce`);function o(e){return Promise.all(e.map(e=>Promise.resolve(e).then(e=>({status:`fulfilled`,value:e}),e=>({status:`rejected`,reason:e}))))}r=o(t.map(t=>{if(t=vm(t,n),t in ym)return;ym[t]=!0;let r=t.endsWith(`.css`),i=r?`[rel="stylesheet"]`:``;if(n)for(let n=e.length-1;n>=0;n--){let i=e[n];if(i.href===t&&(!r||i.rel===`stylesheet`))return}else if(document.querySelector(`link[href="${t}"]${i}`))return;let o=document.createElement(`link`);if(o.rel=r?`stylesheet`:_m,r||(o.as=`script`),o.crossOrigin=``,o.href=t,a&&o.setAttribute(`nonce`,a),document.head.appendChild(o),r)return new Promise((e,n)=>{o.addEventListener(`load`,e),o.addEventListener(`error`,()=>n(Error(`Unable to preload CSS for ${t}`)))})}))}function i(e){let t=new Event(`vite:preloadError`,{cancelable:!0});if(t.payload=e,window.dispatchEvent(t),!t.defaultPrevented)throw e}return r.then(t=>{for(let e of t||[])e.status===`rejected`&&i(e.reason);return e().catch(i)})},xm=160;function Sm(e=``,t=`#0b0d14`){if(typeof document>`u`)return{lift:()=>{}};let n=document.createElement(`div`);if(n.dataset.incantoSwitch=``,n.style.cssText=`position:fixed;inset:0;z-index:2147483646;background:${t};display:flex;align-items:center;justify-content:center;opacity:0;transition:opacity ${xm}ms ease;pointer-events:auto;`,e){let t=document.createElement(`div`);t.textContent=e,t.style.cssText=`font:13px/1 ui-monospace,SFMono-Regular,Menlo,monospace;color:#5d6680;letter-spacing:0.04em;`,n.appendChild(t)}document.body.appendChild(n),requestAnimationFrame(()=>{n.style.opacity=`1`});let r=!1;return{lift(){r||(r=!0,requestAnimationFrame(()=>{n.style.opacity=`0`,setTimeout(()=>n.remove(),200)}))}}}async function Cm(e=xm){typeof requestAnimationFrame==`function`&&await new Promise(t=>setTimeout(t,e))}function wm(e){return async t=>{let n=new URLSearchParams({tags:t.tags.join(`,`),page:String(t.page??1),limit:String(t.limit??24)});t.keyword?.trim()&&n.set(`keyword`,t.keyword.trim());let r=await fetch(`/api/library?${n}`,{headers:e?{"x-incanto-v8-token":e}:{}});if(r.status===401){let e=await r.json().catch(()=>({})),t=Error(e.error??`the asset library needs a Verse8 access token`);throw t.needsToken=!0,t}if(!r.ok)throw Error(`asset library: HTTP ${r.status}`);return await r.json()}}async function Tm(){try{let e=await fetch(`/api/scenes`);if(!e.ok)return null;let t=await e.json();return Array.isArray(t)?t:null}catch{return null}}function Em(e,t){let n=typeof t.name==`string`?t.name:null;if(!e||!n)return null;let r=e.filter(e=>e.scene?.name===n);return r.length===1?r[0].rel:null}function Dm(e,t){let n=typeof t.name==`string`?t.name:`(unnamed)`;if(!e)return`Save: this dev server does not serve the project's scenes, so there is no file to write. ${Om}`;let r=e.filter(e=>e.scene?.name===n);return r.length>1?`Save: ${r.length} scenes in this project are named "${n}" (${r.map(e=>e.rel).join(`, `)}), so which file this is cannot be told from the scene alone. Open the one you mean from the scene browser and save there.`:`Save: no file in this project contains a scene named "${n}", so there is nowhere to write it. Open a scene from the scene browser first, or pass editor: { save } to createGame so the game decides where edits go.`}var Om=`this dev server does not serve the project's scenes yet. Add incantoScenes() to vite.config.ts and restart:
|
|
4107
4107
|
|
|
4108
4108
|
import { incantoScenes } from 'incanto/vite';
|
|
4109
4109
|
export default defineConfig({ plugins: [incantoScenes()] });
|
|
4110
4110
|
|
|
4111
|
-
It also validates every scene you save, before the page reloads into a broken one.`;async function
|
|
4111
|
+
It also validates every scene you save, before the page reloads into a broken one.`;async function km(e){let t=await fetch(`/api/scene?file=${encodeURIComponent(e)}`);if(t.ok)return await t.json();let n=await t.json().catch(()=>null);throw Error(n?.error??`could not open ${e}: HTTP ${t.status}`)}async function Am(e){let t;try{t=await bm(()=>Promise.resolve().then(()=>QB),void 0,import.meta.url)}catch(e){throw Error(`createGame3D editor: could not load 'incanto/editor'. If this app aliases incanto to the engine SOURCE (the examples and playground do), add an alias for 'incanto/editor' → packages/editor/src/main.ts — or pass editor: { open } and load it yourself. (${e instanceof Error?e.message:String(e)})`)}let n=null,r=await Tm(),i=t.formatSceneJson??(e=>JSON.stringify(e,null,2)),a=async(e,t)=>{let n=await fetch(`/api/scene?file=${encodeURIComponent(e)}`,{method:`PUT`,body:i(t)});if(!n.ok)throw Error(`could not save ${e}: HTTP ${n.status} ${await n.text()}`)};n=await t.mountEditor({...e.camera?{camera:e.camera}:{},api:{meta:async()=>({version:`live`,mode:`project`,root:``,input:null,output:null}),loadScene:async t=>t?await km(t):e.scene,...e.save||r?{saveScene:async(t,n)=>{if(n)return a(n,t);if(e.save)return void await e.save(t);let i=Em(r,e.scene);if(i)return a(i,t);throw Error(Dm(r,e.scene))}}:{},scenes:async()=>{let e=await Tm();if(!e)throw Error(Om);return e},createScene:async e=>{let t=await fetch(`/api/scenes`,{method:`POST`,body:JSON.stringify({path:e})});if(t.status===404)throw Error(Om);if(!t.ok)throw Error(`could not create ${e}: ${await t.text()}`);return await t.json()},...e.library?{library:e.library}:{}},onPlay:(t,r)=>{if(t!==`debug`)return;let i=n?.camera();return jm(async()=>{n?.dispose(),n=null,await e.play(r,i)},`starting the game…`)},...e.exit?{onExit:()=>jm(async()=>{n?.dispose(),n=null,await e.exit?.()},`back to the game…`)}:{}})}async function jm(e,t=``){let n=Sm(t);await Cm();try{await e()}finally{await Cm(0),n.lift()}}function Mm(e,t=8){let n=e.cameraBasis,r=e.lastCameraPosition;if(typeof n!=`function`||typeof r!=`function`)return;let i=r.call(e);if(!i)return;let{forward:a}=n.call(e);return{position:[i.x,i.y,i.z],target:[i.x+a.x*t,i.y+a.y*t,i.z+a.z*t]}}function Nm(e,t=Pm){let n=[];for(let r of e){if(!r)continue;let[e,i]=r;try{i()}catch(r){n.push({what:e,error:r});try{t(e,r)}catch{}}}return{failures:n}}function Pm(e,t){console.error(`[incanto] teardown: ${e} failed (continuing)`,t)}var Fm=new kc,Im=new G,Lm=new gs;function Rm(e,t,n){return Im.multiplyMatrices(e.projectionMatrix,e.matrixWorldInverse),Fm.setFromProjectionMatrix(Im),Lm.center.set(t.x,t.y,t.z),Lm.radius=n,Fm.intersectsSphere(Lm)}function zm(e){if(!e||typeof e!=`object`)return 0;switch(e.shape){case`capsule`:return(e.height??0)/2+(e.radius??0);case`sphere`:return e.radius??0;case`box`:return(e.size?.[1]??0)/2;default:return 0}}function Bm(e){return .55+Math.min(Math.max(e,0),12)/12*.45}function Vm(e,t,n=0){let r=[],i=[],a=new Set;for(let o of t){let t=e.has(o.id);(t?o.y<=o.waterline+n:o.y<o.waterline)?(a.add(o.id),t||r.push(o)):t&&i.push(o)}return{entered:r,exited:i,inWater:a}}function Hm(e,t,n,r,i=0,a=8){if(e.length>=a){let t=0;for(let n=1;n<e.length;n++)e[n].age>e[t].age&&(t=n);e.splice(t,1)}e.push({x:t,z:n,age:0,amp:r,foam:i})}function Um(e,t,n=3){for(let r=e.length-1;r>=0;r--){let i=e[r];i.age+=t,i.age>=n&&e.splice(r,1)}}function Wm(e,t,n){let r=e-n.x,i=t-n.z,a=Math.sqrt(r*r+i*i);return n.amp*Math.sin(6*a-8*n.age)*Math.exp(-1.1*n.age)*Math.exp(-.15*a*a)}function Gm(e,t,n){let r=0;for(let i of n)r+=Wm(e,t,i);return r}function Km(e,t,n,r){let i=[];for(let n of e.keys())t.has(n)||e.delete(n);for(let a of t){let t=(e.get(a)??0)+n;t>=r?(i.push(a),e.set(a,t-r)):e.set(a,t)}return i}var qm=`
|
|
4112
4112
|
precision highp float;
|
|
4113
4113
|
|
|
4114
4114
|
// atmosphere: three's linear fog rides the standard chunks (compiled out
|
|
@@ -4132,7 +4132,7 @@ void main() {
|
|
|
4132
4132
|
// atmosphere: fog depth from the displaced surface position
|
|
4133
4133
|
#include <fog_vertex>
|
|
4134
4134
|
}
|
|
4135
|
-
`,
|
|
4135
|
+
`,Jm=`
|
|
4136
4136
|
precision highp float;
|
|
4137
4137
|
|
|
4138
4138
|
// atmosphere: standard fog chunk (compiled out without scene fog)
|
|
@@ -4327,13 +4327,13 @@ void main() {
|
|
|
4327
4327
|
#include <colorspace_fragment>
|
|
4328
4328
|
#include <fog_fragment>
|
|
4329
4329
|
}
|
|
4330
|
-
`,
|
|
4330
|
+
`,Ym=new Set([`Foliage3D`,`Flowers3D`,`Particles3D`,`Trail3D`]);function Xm(e,t){return t.length=0,typeof e?.traverse==`function`&&e.traverse(e=>{if(!e.visible)return;if(e.userData?.incantoWaterPassSkip===!0){e.visible=!1,t.push(e);return}let n=(e.userData?.incantoNode)?.constructor?.typeName;n&&Ym.has(n)&&(e.visible=!1,t.push(e))}),t}function Zm(e){for(let t=0;t<e.length;t++){let n=e[t];n&&(n.visible=!0)}e.length=0}var Qm=`
|
|
4331
4331
|
varying vec2 vUv;
|
|
4332
4332
|
void main() {
|
|
4333
4333
|
vUv = uv;
|
|
4334
4334
|
gl_Position = vec4(position.xy, 0.0, 1.0);
|
|
4335
4335
|
}
|
|
4336
|
-
|
|
4336
|
+
`,$m=`
|
|
4337
4337
|
float caustic(vec2 uv, float t) {
|
|
4338
4338
|
vec2 p = mod(uv * 6.28318, 6.28318) - 250.0;
|
|
4339
4339
|
vec2 i = p;
|
|
@@ -4348,7 +4348,7 @@ float caustic(vec2 uv, float t) {
|
|
|
4348
4348
|
c = 1.17 - pow(c, 1.4);
|
|
4349
4349
|
return clamp(pow(abs(c), 8.0), 0.0, 1.0);
|
|
4350
4350
|
}
|
|
4351
|
-
`,
|
|
4351
|
+
`,eh=`
|
|
4352
4352
|
precision highp float;
|
|
4353
4353
|
varying vec2 vUv;
|
|
4354
4354
|
uniform sampler2D tColor;
|
|
@@ -4367,7 +4367,7 @@ uniform float uMaxDist;
|
|
|
4367
4367
|
uniform vec3 uSunDirection;
|
|
4368
4368
|
uniform float uRayStrength;
|
|
4369
4369
|
|
|
4370
|
-
${
|
|
4370
|
+
${$m}
|
|
4371
4371
|
|
|
4372
4372
|
/** Cheap 2-octave value noise — the shaft pattern (the caustic loop is far too
|
|
4373
4373
|
* expensive to run once per ray step). */
|
|
@@ -4453,7 +4453,7 @@ void main() {
|
|
|
4453
4453
|
|
|
4454
4454
|
gl_FragColor = color;
|
|
4455
4455
|
}
|
|
4456
|
-
`;function
|
|
4456
|
+
`;function th(){let e=new vl({vertexShader:Qm,fragmentShader:eh,depthTest:!1,depthWrite:!1,uniforms:{tColor:{value:null},tDepth:{value:null},uInvViewProj:{value:new G},uCameraPos:{value:new U},uWaterLevel:{value:0},uTime:{value:0},uCausticColor:{value:new K(`#cdeeff`)},uCausticIntensity:{value:.55},uCausticScale:{value:.32},uMaxDist:{value:22},uSunDirection:{value:new U(.4,.85,.35)},uRayStrength:{value:0}}}),t=new Ys(new cl(2,2),e);return t.frustumCulled=!1,{mesh:t,uniforms:e.uniforms}}var nh=`
|
|
4457
4457
|
precision highp float;
|
|
4458
4458
|
|
|
4459
4459
|
// incanto atmosphere: three's linear fog rides the standard chunks (compiled
|
|
@@ -4701,7 +4701,7 @@ void main() {
|
|
|
4701
4701
|
vec4 mvPosition = viewMatrix * modelPosition;
|
|
4702
4702
|
#include <fog_vertex>
|
|
4703
4703
|
}
|
|
4704
|
-
`,
|
|
4704
|
+
`,rh=`
|
|
4705
4705
|
precision highp float;
|
|
4706
4706
|
|
|
4707
4707
|
// incanto atmosphere: standard fog chunk (compiled out without scene fog)
|
|
@@ -4805,7 +4805,7 @@ const float SHORE_MAX_COLUMN = 2.2;
|
|
|
4805
4805
|
// different optical world (Snell's window), not the top shaded darker.
|
|
4806
4806
|
uniform float uCameraSubmerged;
|
|
4807
4807
|
|
|
4808
|
-
${
|
|
4808
|
+
${$m}
|
|
4809
4809
|
|
|
4810
4810
|
// 🎨 Contact surface color customization uniforms
|
|
4811
4811
|
uniform vec3 uEdgeColor;
|
|
@@ -5731,7 +5731,7 @@ void main() {
|
|
|
5731
5731
|
#include <colorspace_fragment>
|
|
5732
5732
|
#include <fog_fragment>
|
|
5733
5733
|
}
|
|
5734
|
-
`;function nh(e,t,n,r,i=0){return t>=r.centerY?!1:Math.abs(e-r.centerX)<=r.halfW+i&&Math.abs(n-r.centerZ)<=r.halfD+i}var rh=22,ih={enabled:!0,strength:.6},ah={enabled:!0,color:`#cdeeff`,intensity:.55,scale:.32,speed:1};function oh(e,t){if(e===!1)return{enabled:!1,color:lh(t),visibility:rh,caustics:ah,rays:{...ih,enabled:!1}};let n=e&&typeof e==`object`?e:{};return{enabled:!0,color:n.color??lh(t),visibility:n.visibility??rh,caustics:ch(n.caustics),rays:sh(n.rays)}}function sh(e){return e===!1?{...ih,enabled:!1}:typeof e==`number`?{enabled:e>0,strength:e}:{...ih}}function ch(e){if(e===!1)return{...ah,enabled:!1};let t=e&&typeof e==`object`?e:{};return{enabled:!0,color:typeof t.color==`string`?t.color:ah.color,intensity:typeof t.intensity==`number`?t.intensity:ah.intensity,scale:typeof t.scale==`number`?t.scale:ah.scale,speed:typeof t.speed==`number`?t.speed:ah.speed}}function lh(e){let{r:t,g:n,b:r}=uh(e),i=(e,t,n)=>Math.round(e*(1-n)+t*n);return dh(Math.round(i(t,6,.45)*.7),Math.round(i(n,40,.4)*.78),Math.round(i(r,70,.35)*.82))}function uh(e){let t=e.replace(`#`,``),n=t.length===3?t.split(``).map(e=>e+e).join(``):t;return{r:Number.parseInt(n.slice(0,2),16)||0,g:Number.parseInt(n.slice(2,4),16)||0,b:Number.parseInt(n.slice(4,6),16)||0}}function dh(e,t,n){let r=e=>Math.max(0,Math.min(255,e)).toString(16).padStart(2,`0`);return`#${r(e)}${r(t)}${r(n)}`}var fh={frequency:6.7,persistence:.3,lacunarity:2.18,iterations:9,speed:.5},ph=.525,mh=.08,hh={freqX:.7,freqZ:.5,cross:.6};function gh(e,t){return e-Math.floor(e/t)*t}function _h(e){return e-Math.floor(e)}function vh(e){return gh((e*34+1)*e,289)}var yh=.211324865405187,bh=.366025403784439,xh=-.577350269189626,Sh=.024390243902439;function Ch(e,t){let n=Math.floor(e+(e+t)*bh),r=Math.floor(t+(e+t)*bh),i=e-n+(n+r)*yh,a=t-r+(n+r)*yh,o=+(i>a),s=i>a?0:1,c=i+yh-o,l=a+yh-s,u=i+xh,d=a+xh;n=gh(n,289),r=gh(r,289);let f=vh(vh(r)+n),p=vh(vh(r+s)+n+o),m=vh(vh(r+1)+n+1),h=Math.max(.5-(i*i+a*a),0),g=Math.max(.5-(c*c+l*l),0),_=Math.max(.5-(u*u+d*d),0);h*=h,h*=h,g*=g,g*=g,_*=_,_*=_;let v=2*_h(f*Sh)-1,y=2*_h(p*Sh)-1,b=2*_h(m*Sh)-1,x=Math.abs(v)-.5,S=Math.abs(y)-.5,C=Math.abs(b)-.5,w=v-Math.floor(v+.5),T=y-Math.floor(y+.5),E=b-Math.floor(b+.5);h*=1.79284291400159-.85373472095314*(w*w+x*x),g*=1.79284291400159-.85373472095314*(T*T+S*S),_*=1.79284291400159-.85373472095314*(E*E+C*C);let D=w*i+x*a,O=T*c+S*l,k=E*u+C*d;return 130*(h*D+g*O+_*k)}function wh(e,t,n,r){let i=Math.max(r.scaleNorm,1e-6),a=e/i,o=t/i,s=0,c=1,l=r.frequency,u=n*r.speed;for(let e=0;e<r.iterations;e++)s+=c*Ch(a*l+u,o*l+u),c*=r.persistence,l*=r.lacunarity;return s*r.amplitude}function Th(e,t,n,r){return r*(Math.sin(e*hh.freqX+n)+hh.cross*Math.sin(t*hh.freqZ+n*1.3))}function Eh(e,t){let n=e.shape;if(n!==void 0){if(n===`box`){let n=e.size;if(!Array.isArray(n)||n.length!==3||n.some(e=>typeof e!=`number`))throw new N(`BAD_FORMAT`,`Collider on '${t}': box needs "size": [x, y, z].`);return}if(n===`sphere`){if(typeof e.radius!=`number`)throw new N(`BAD_FORMAT`,`Collider on '${t}': sphere needs "radius".`);return}if(n===`capsule`){if(typeof e.radius!=`number`||typeof e.height!=`number`)throw new N(`BAD_FORMAT`,`Collider on '${t}': capsule needs "radius" and "height".`);return}if(n===`trimesh`){let n=e.vertices,r=e.indices;if(!Array.isArray(n)||n.length%3!=0||!Array.isArray(r)||r.length%3!=0)throw new N(`BAD_FORMAT`,`Collider on '${t}': trimesh needs "vertices" (flat xyz floats) and "indices" (triangle triplets).`);return}if(n!==`heightfield`&&n!==`auto`)throw new N(`BAD_FORMAT`,`Collider on '${t}': "shape" must be 'auto', 'box', 'sphere', 'capsule', 'trimesh', or 'heightfield', got ${JSON.stringify(n)}.`)}}function Dh(e){let t=e;if(t.constructor?.typeName===`Terrain3D`&&typeof t.heightAt==`function`)return e;for(let t of e.children){let e=Dh(t);if(e)return e}return null}var Oh=class e extends Nt{static typeName=`Node3D`;static props={position:{default:[0,0,0]},rotation:{default:[0,0,0]},static:{default:!1},scale:{default:[1,1,1]},visible:{default:!0},renderOrder:{default:0},orderGroup:{default:`default`,options:[`background`,`terrain`,`default`,`characters`,`effects`,`overlay`]},snapToGround:{default:null}};position=[0,0,0];rotation=[0,0,0];static=!1;scale=[1,1,1];visible=!0;renderOrder=0;orderGroup=`default`;snapToGround=null;get effectiveRenderOrder(){return _t(this.orderGroup,this.renderOrder,this.tree?.engine?.orderGroups)}_object3D=null;_interpPrev=null;_interpCurr=null;onReady(){this.applyGroundSnap()}applyGroundSnap(){if(this.snapToGround===null||this.snapToGround===!1)return;let t=this.snapToGround===!0?0:this.snapToGround,n=Dh(this.getRoot());if(!n)return;let r=this.position[0]??0,i=0,a=this.position[2]??0;for(let t=this.parent;t;t=t.parent){if(!(t instanceof e))continue;let n=(t.rotation[1]??0)*Math.PI/180;if(n!==0){let e=Math.cos(n),t=Math.sin(n),i=r*e+a*t,o=-r*t+a*e;r=i,a=o}r+=t.position[0]??0,i+=t.position[1]??0,a+=t.position[2]??0}let o=r,s=a;this.position=[this.position[0]??0,n.heightAt(o,s)+t-i,this.position[2]??0]}get _builtObject3D(){return this._object3D}_ensureObject3D(){return this._object3D||(this._object3D=this._createObject3D(),this._object3D.userData.incantoNode=this),this._object3D}_createObject3D(){return new go}_syncObject3D(e=1,t=null){let n=this._ensureObject3D(),r=this._interpPrev,i=this._interpCurr;r&&i?n.position.set((r[0]??0)+((i[0]??0)-(r[0]??0))*e,(r[1]??0)+((i[1]??0)-(r[1]??0))*e,(r[2]??0)+((i[2]??0)-(r[2]??0))*e):n.position.set(this.position[0]??0,this.position[1]??0,this.position[2]??0),n.rotation.set(ba.degToRad(this.rotation[0]??0),ba.degToRad(this.rotation[1]??0),ba.degToRad(this.rotation[2]??0)),n.scale.set(this.scale[0]??1,this.scale[1]??1,this.scale[2]??1),n.visible=this.visible,n.renderOrder=this.effectiveRenderOrder}free(){super.free(),this._object3D?.removeFromParent(),this._object3D=null,this._interpPrev=null,this._interpCurr=null}},kh=class extends Oh{static props={collider:{default:{},variants:{tag:`shape`,byTag:{auto:{shape:`auto`},box:{shape:`box`,size:[1,1,1]},sphere:{shape:`sphere`,radius:.5},capsule:{shape:`capsule`,radius:.35,height:1},trimesh:{shape:`trimesh`,vertices:[],indices:[]},heightfield:{shape:`heightfield`}}}}};static signals=[`triggerEnter`,`triggerExit`];_collider={};_colliderChanged=!1;get collider(){return this._collider}set collider(e){this._collider=e,this._colliderChanged=!0}static validateJson(e){let t=e;if(Eh(t.collider,e.name),t.collider.shape===`heightfield`&&!(t instanceof Ah))throw new N(`BAD_FORMAT`,`Collider on '${e.name}': heightfield is static terrain — put it on a StaticBody3D (with a Terrain3D child), not a ${t.constructor.typeName}.`,{prop:`collider`})}_physics=null},Ah=class extends kh{static typeName=`StaticBody3D`},jh=class extends kh{static typeName=`Area3D`},Mh=class extends kh{static typeName=`RigidBody3D`;static props={mass:{default:1},gravityScale:{default:1},fixedRotation:{default:!1},friction:{default:.5},restitution:{default:0},linearVelocity:{default:[0,0,0]}};mass=1;gravityScale=1;fixedRotation=!1;friction=.5;restitution=0;linearVelocity=[0,0,0];_physics3d=null;applyImpulse(e){this._physics3d?.applyImpulse(this,e)}},Nh=class extends kh{static typeName=`CharacterBody3D`;static props={velocity:{default:[0,0,0]},snapToGround:{default:!0},slopeLimitDeg:{default:45}};velocity=[0,0,0];snapToGround=!0;slopeLimitDeg=45;_grounded=!1;moveAndSlide(){if(!this._physics)throw new N(`TREE_VIOLATION`,this.collider.shape===void 0?`CharacterBody3D '${this.name}' has no collider — set a collider prop (physics skips collider-less bodies).`:`CharacterBody3D '${this.name}' has no physics world — await enablePhysics3D(engine) first.`);this._physics.moveAndSlide(this)}isOnFloor(){return this._grounded}},Ph=class extends Oh{static typeName=`WaterCutout3D`;static props={size:{default:[2,1,1]},enabled:{default:!0}};size=[2,1,1];enabled=!0;static validateJson(e){let t=e;if(!Array.isArray(t.size)||t.size.length!==3||t.size.some(e=>!(e>0)))throw new N(`BAD_FORMAT`,`WaterCutout3D '${e.name}' size must be three positive meters [x, y, z], got ${JSON.stringify(t.size)}.`,{prop:`size`})}onReady(){if(!this.parent?.parent)throw new N(`BAD_FORMAT`,`WaterCutout3D '${this.name}' must be a CHILD of the object that holds the water back (a hull, a diving bell, a dock's well) — it re-draws that object to keep water out of it, so at the scene root it has nothing to stand in for.`,{prop:`parent`})}},Fh=[`fancy`,`simple`],Ih=[`trough`,`surface`,`peak`],Lh=[`custom`,`ocean`,`pool`,`lake`,`pond`],Rh={ocean:{waveHeight:.045,swell:.34,swellWavelength:52,whitecaps:.15,absorption:.17,opacity:.85,detailStrength:.17,sunIntensity:.85,colors:{trough:`#175360`,surface:`#2f8792`,peak:`#9bd8d2`},color:`#2f8792`,causticsAbove:.3,shoreWaves:.7,reflectionInterval:400,_look:{fresnelScale:1.15,reflectivityMax:.93,foamRangeScale:.35,foamIntensity:.55}},pool:{waveHeight:.006,swell:0,whitecaps:0,absorption:.3,opacity:.5,detailStrength:.16,sunIntensity:1.25,colors:{trough:`#1e8dbe`,surface:`#3fb6dc`,peak:`#bdeef7`},color:`#3fb6dc`,causticsAbove:1,reflectionInterval:600,_look:{fresnelScale:.85,reflectivityMax:.5,edgeFade:!1}},lake:{waveHeight:.028,swell:.14,swellWavelength:24,whitecaps:0,absorption:.5,opacity:.88,detailStrength:.3,colors:{trough:`#12343a`,surface:`#25565c`,peak:`#7fb2ab`},color:`#25565c`,causticsAbove:.15,reflectionInterval:300,_look:{fresnelScale:1.25,reflectivityMax:.78}},pond:{waveHeight:.006,swell:0,whitecaps:0,absorption:.85,opacity:.93,detailStrength:.14,sunIntensity:.7,colors:{trough:`#1c2e1e`,surface:`#39543c`,peak:`#6f8a68`},color:`#39543c`,causticsAbove:0,reflectionInterval:800,_look:{fresnelScale:1.05,reflectivityMax:.78,edgeFade:!1}}},zh={trough:`#135a72`,surface:`#2a86a0`,peak:`#a5ddd6`},Bh={peakThreshold:.08,peakTransition:.05,troughThreshold:-.01,troughTransition:.15,fresnelScale:1,fresnelPower:5},Vh={color:`#dcebe8`,intensity:.32,rangeMin:.45,rangeMax:1.4,scale:.35,edgeColor:`#ffffff`,edgeIntensity:.6,edgeWidth:.5};function Hh(e,t){return Math.min(Vh.rangeMax,Math.max(Vh.rangeMin,Math.min(e,t)*.012))}var Uh=128,Wh=ph/mh,Gh=256,Kh=2e3,qh=3,Jh=640,Yh=.06,Xh=1024,Zh=.02,Qh=1.5,$h=24,eg=160,tg=32,ng=.05,rg=.08,ig=.02,ag=.18,og=.04,sg=1.4,cg=.04,lg=.45,ug=.08,dg=.4,fg=.22,pg=.09,mg=.85,hg=class e extends Oh{static typeName=`Water3D`;static signals=[`entered`,`exited`];static props={size:{default:[40,40]},color:{default:`#2a6fbe`},opacity:{default:.8},renderOrder:{default:1},waveHeight:{default:.04},waveSpeed:{default:1},quality:{default:`fancy`,options:Fh},colors:{default:{}},reflection:{default:!0},reflectionInterval:{default:1e3},mirror:{default:!1},mirrorInterval:{default:33},swellSteepness:{default:.35},foam:{default:!0},reflectivity:{default:null},interaction:{default:!0},splash:{default:!0},sunDirection:{default:[.5,.8,.3]},sunColor:{default:`#fff5d6`},sunIntensity:{default:1},detailStrength:{default:.26},absorption:{default:.15},refraction:{default:!0},underwater:{default:!0},swell:{default:0},swellDirectionDeg:{default:0},swellWavelength:{default:30},whitecaps:{default:0},preset:{default:`custom`,options:Lh},causticsAbove:{default:0},shoreWaves:{default:0}};size=[40,40];color=`#2a6fbe`;opacity=.8;renderOrder=1;waveHeight=.04;waveSpeed=1;quality=`fancy`;colors={};reflection=!0;mirror=!1;mirrorInterval=33;reflectionInterval=1e3;foam=!0;reflectivity=null;interaction=!0;splash=!0;sunDirection=[.5,.8,.3];sunColor=`#fff5d6`;sunIntensity=1;detailStrength=.26;absorption=.15;refraction=!0;underwater=!0;swell=0;swellDirectionDeg=0;swellWavelength=30;swellSteepness=.35;whitecaps=0;preset=`custom`;causticsAbove=0;shoreWaves=0;rp(t){let n=Rh[this.preset],r=this;if(n&&t in n){let i=e.props[t]?.default,a=r[t];if(typeof a==`object`&&a?JSON.stringify(a)===JSON.stringify(i):a===i)return n[t]}return r[t]}presetLook(){let e=Rh[this.preset]?._look,t=this.rp(`reflectivity`);return{fresnelScale:e?.fresnelScale??Bh.fresnelScale,reflectivityMax:typeof t==`number`?Math.min(Math.max(t,0),1):e?.reflectivityMax??.6,edgeFade:e?.edgeFade??!0,foamRangeScale:e?.foamRangeScale??1,foamIntensity:e?.foamIntensity??Vh.intensity}}static validateJson(e){let t=e;if(!((t.size[0]??0)>0)||!((t.size[1]??0)>0))throw new N(`BAD_FORMAT`,`Water3D '${e.name}' size must be positive [width, depth] meters, got ${JSON.stringify(t.size)}.`,{prop:`size`});if(!Fh.includes(t.quality))throw new N(`BAD_FORMAT`,`Water3D '${e.name}' quality must be one of [${Fh.join(`, `)}], got '${t.quality}'.`,{prop:`quality`,validOptions:Fh});for(let[n,r]of Object.entries(t.colors)){if(!Ih.includes(n))throw new N(`BAD_FORMAT`,`Water3D '${e.name}' colors has unknown key '${n}'. Valid keys: [${Ih.join(`, `)}].`,{prop:`colors`,validOptions:Ih});if(typeof r!=`string`)throw new N(`BAD_FORMAT`,`Water3D '${e.name}' colors.${n} must be a hex color string, got ${JSON.stringify(r)}.`,{prop:`colors`})}if(!(t.reflectionInterval>0))throw new N(`BAD_FORMAT`,`Water3D '${e.name}' reflectionInterval must be > 0 ms, got ${t.reflectionInterval}.`,{prop:`reflectionInterval`});let n=t.sunDirection;if(!Array.isArray(n)||n.length!==3||!n.every(e=>Number.isFinite(e))||Math.hypot(n[0]??0,n[1]??0,n[2]??0)===0)throw new N(`BAD_FORMAT`,`Water3D '${e.name}' sunDirection must be a non-zero [x, y, z] vector, got ${JSON.stringify(n)}.`,{prop:`sunDirection`});if(!(t.sunIntensity>=0))throw new N(`BAD_FORMAT`,`Water3D '${e.name}' sunIntensity must be >= 0, got ${t.sunIntensity}.`,{prop:`sunIntensity`});if(!(t.detailStrength>=0))throw new N(`BAD_FORMAT`,`Water3D '${e.name}' detailStrength must be >= 0, got ${t.detailStrength}.`,{prop:`detailStrength`});if(!(t.absorption>=0))throw new N(`BAD_FORMAT`,`Water3D '${e.name}' absorption must be >= 0 (per-meter Beer's-law constant), got ${t.absorption}.`,{prop:`absorption`});if(!(t.swell>=0)||!Number.isFinite(t.swell))throw new N(`BAD_FORMAT`,`Water3D '${e.name}' swell must be >= 0 meters (0 = off), got ${JSON.stringify(t.swell)}.`,{prop:`swell`});if(!(t.swellWavelength>=2))throw new N(`BAD_FORMAT`,`Water3D '${e.name}' swellWavelength must be >= 2 meters, got ${JSON.stringify(t.swellWavelength)}.`,{prop:`swellWavelength`});if(!(t.whitecaps>=0)||!(t.whitecaps<=1))throw new N(`BAD_FORMAT`,`Water3D '${e.name}' whitecaps must be in [0, 1], got ${JSON.stringify(t.whitecaps)}.`,{prop:`whitecaps`});if(!Lh.includes(t.preset))throw new N(`BAD_FORMAT`,`Water3D '${e.name}' preset must be one of [${Lh.join(`, `)}], got '${t.preset}'.`,{prop:`preset`,validOptions:Lh});if(!(t.shoreWaves>=0)||!(t.shoreWaves<=1))throw new N(`BAD_FORMAT`,`Water3D '${e.name}' shoreWaves must be in [0, 1] (0 = off), got ${JSON.stringify(t.shoreWaves)}.`,{prop:`shoreWaves`});if(!(t.causticsAbove>=0)||!(t.causticsAbove<=3))throw new N(`BAD_FORMAT`,`Water3D '${e.name}' causticsAbove must be in [0, 3] (0 = off), got ${JSON.stringify(t.causticsAbove)}.`,{prop:`causticsAbove`});let r=t.underwater;if(typeof r!=`boolean`){if(typeof r!=`object`||!r||Array.isArray(r))throw new N(`BAD_FORMAT`,`Water3D '${e.name}' underwater must be true, false or an object ({ color?, visibility? }), got ${JSON.stringify(r)}.`,{prop:`underwater`});let t=r;if(t.color!==void 0&&typeof t.color!=`string`)throw new N(`BAD_FORMAT`,`Water3D '${e.name}' underwater.color must be a hex color string, got ${JSON.stringify(t.color)}.`,{prop:`underwater`});if(t.visibility!==void 0&&!(t.visibility>0))throw new N(`BAD_FORMAT`,`Water3D '${e.name}' underwater.visibility must be > 0 meters, got ${JSON.stringify(t.visibility)}.`,{prop:`underwater`})}}time=0;surfaceKey=``;_ripples=[];inWater=new Set;bobTimers=new Map;wadeAnchors=new Map;_scratchA={x:0,y:0,z:0};_scratchB={x:0,y:0,z:0};_bodies=[];_cutouts=[];_maskMeshes=[];_maskSaved=[];_passHidden=[];cubeTarget=null;cubeCamera=null;reflectionNear=0;lastReflectionAt=0;scenePassTarget=null;mirrorTarget=null;mirrorCamera=new pu;mirrorMatrix=new G;lastMirrorAt=0;lastMirrorEye=new U(1/0,1/0,1/0);lastMirrorQuat=new H;_createObject3D(){return new Ys}update(e){this.time+=e*this.waveSpeed,Vm(this._ripples,e),this.interaction&&this.stepInteraction(e)}_syncObject3D(){super._syncObject3D();let e=this._ensureObject3D();this.rebuildSurfaceIfNeeded(e),this.quality===`simple`?this.syncSimple(e):this.syncFancy(e)}_onRender3D(e){let t=this._ensureObject3D(),n=t.material;if(e.camera.updateWorldMatrix(!0,!1),e.camera.getWorldPosition(Ng),this.underwaterAt(Ng.x,Ng.y,Ng.z)){if(n.isShaderMaterial){let e=n.uniforms;e.uUseSceneDepth&&(e.uUseSceneDepth.value=0),e.uUseRefraction&&(e.uUseRefraction.value=0),e.uUseMirror&&(e.uUseMirror.value=0),e.uCameraSubmerged&&(e.uCameraSubmerged.value=1)}return}if(this.quality!==`fancy`||!n.isShaderMaterial)return;let r=Math.hypot((this.size[0]??1)/2,(this.size[1]??1)/2);if(!Im(e.camera,wg(this),r+1))return;let i=n.uniforms;i.uCameraSubmerged&&(i.uCameraSubmerged.value=0);let a=Date.now();if(this.reflection){this.cubeTarget||=new Ad(Gh,{generateMipmaps:!0,minFilter:cr,type:gr});let n=Math.max((this.size[0]??1)/2,(this.size[1]??1)/2);(!this.cubeCamera||this.reflectionNear!==n)&&(this.reflectionNear=n,this.cubeCamera=new Du(n,1e3,this.cubeTarget),this.lastReflectionAt=0);let r=this.mirror?Math.max(this.rp(`reflectionInterval`),Kh):this.rp(`reflectionInterval`);if(this.lastReflectionAt===0||a-this.lastReflectionAt>=r){this.lastReflectionAt=a;let n=wg(this),r=this.cubeCamera;r.position.set(n.x,n.y+.1,n.z);let i=t.visible;t.visible=!1,r.update(e.gl,e.scene),t.visible=i}i.uEnvironmentMap&&i.uUseEnvironmentMap&&(i.uEnvironmentMap.value=this.cubeTarget.texture,i.uUseEnvironmentMap.value=1)}if(this.mirror&&i.uMirrorMap&&i.uMirrorMatrix&&i.uUseMirror){e.gl.getDrawingBufferSize(Mg);let n=Math.max(1,Math.min(Math.round(Mg.x/qh),Jh)),r=Math.max(1,Math.min(Math.round(Mg.y/qh),Jh));this.mirrorTarget&&(this.mirrorTarget.width!==n||this.mirrorTarget.height!==r)&&(this.mirrorTarget.dispose(),this.mirrorTarget=null),this.mirrorTarget||=new Ba(n,r,{depthBuffer:!0,stencilBuffer:!1,type:gr,samples:4});let o=wg(this).y,s=e.camera;s.getWorldPosition(Fg),s.getWorldQuaternion(zg),Lg.set(0,0,-1).applyQuaternion(zg).add(Fg),Rg.set(0,1,0).applyQuaternion(zg),Fg.y=2*o-Fg.y,Lg.y=2*o-Lg.y,Rg.y=-Rg.y;let c=this.mirrorCamera;c.fov=s.fov??50,c.aspect=s.aspect??n/r,c.near=s.near??.1,c.far=s.far??1e3,c.position.copy(Fg),c.up.copy(Rg),c.lookAt(Lg),c.updateMatrixWorld(!0),c.updateProjectionMatrix(),s.getWorldPosition(Ig);let l=Ig.distanceToSquared(this.lastMirrorEye)>1e-6||Math.abs(zg.dot(this.lastMirrorQuat))<.9999995;if(this.lastMirrorAt===0||l||a-this.lastMirrorAt>=this.rp(`mirrorInterval`)){this.lastMirrorAt=a,this.lastMirrorEye.copy(Ig),this.lastMirrorQuat.copy(zg),this.mirrorMatrix.set(.5,0,0,.5,0,.5,0,.5,0,0,.5,.5,0,0,0,1),this.mirrorMatrix.multiply(c.projectionMatrix),this.mirrorMatrix.multiply(c.matrixWorldInverse);let n=e.gl.getRenderTarget(),r=e.gl.clippingPlanes,i=t.visible;t.visible=!1,Bg.constant=-(o-Zh),e.gl.clippingPlanes=Vg,e.gl.setRenderTarget(this.mirrorTarget),e.gl.clear(!0,!0,!1),Jm(e.scene,this._passHidden),e.gl.render(e.scene,c),Ym(this._passHidden),e.gl.setRenderTarget(n),e.gl.clippingPlanes=r,t.visible=i}i.uMirrorMap.value=this.mirrorTarget.texture,i.uMirrorMatrix.value.copy(this.mirrorMatrix),i.uUseMirror.value=1}else i.uUseMirror&&(i.uUseMirror.value=0);e.gl.getDrawingBufferSize(Mg);let o=Math.max(1,Math.min(Math.round(Mg.x/2),Xh)),s=Math.max(1,Math.min(Math.round(Mg.y/2),Xh));if(this.scenePassTarget&&(this.scenePassTarget.width!==o||this.scenePassTarget.height!==s)&&(this.scenePassTarget.depthTexture?.dispose(),this.scenePassTarget.dispose(),this.scenePassTarget=null),!this.scenePassTarget){let e=new $c(o,s);e.type=hr,this.scenePassTarget=new Ba(o,s,{depthTexture:e,depthBuffer:!0,stencilBuffer:!1,generateMipmaps:!0,minFilter:cr})}let c=e.gl.getRenderTarget(),l=e.gl.autoClear,u=e.gl.clippingPlanes,d=t.visible;t.visible=!1;let f=wg(this).y;Hg.constant=f+Zh,e.gl.clippingPlanes=Ug,e.gl.setRenderTarget(this.scenePassTarget),e.gl.autoClear=!0,e.gl.clear(!0,!0,!1),e.gl.render(e.scene,e.camera),Gg.constant=-(f-Zh),e.gl.clippingPlanes=Kg;let p=e.scene.overrideMaterial,m=e.scene.background;e.scene.overrideMaterial=qg,e.scene.background=null,e.gl.autoClear=!1,Jm(e.scene,this._passHidden),e.gl.render(e.scene,e.camera),Ym(this._passHidden),e.scene.overrideMaterial=p,e.scene.background=m,this.renderCutoutMasks(e),e.gl.setRenderTarget(c),e.gl.autoClear=l,e.gl.clippingPlanes=u,t.visible=d,i.uDepthTexture&&i.uSceneColor&&i.uCameraNear&&i.uCameraFar&&i.uUseSceneDepth&&(i.uDepthTexture.value=this.scenePassTarget.depthTexture,(i.uScenePassTexel?.value)?.set(1/o,1/s),i.uSceneColor.value=this.scenePassTarget.texture,i.uCameraNear.value=e.camera.near,i.uCameraFar.value=e.camera.far,i.uUseSceneDepth.value=1,i.uUseRefraction&&(i.uUseRefraction.value=+!!this.refraction),i.uEnableFoam&&(i.uEnableFoam.value=+!!this.foam))}underwaterAt(e,t,n){if(this.underwater===!1)return null;let r=wg(this,this._scratchA);if(!nh(e,t,n,{centerX:r.x,centerY:r.y,centerZ:r.z,halfW:(this.size[0]??1)/2,halfD:(this.size[1]??1)/2},Pg))return null;let i=oh(this.underwater,this.rp(`color`));return i.enabled?{...i,surfaceY:r.y}:null}free(){let e=this._builtObject3D;e?.geometry?.dispose(),(e?.material)?.dispose?.(),this.cubeTarget?.dispose(),this.cubeTarget=null,this.cubeCamera=null,this.scenePassTarget?.depthTexture?.dispose(),this.scenePassTarget?.dispose(),this.scenePassTarget=null,this.mirrorTarget?.dispose(),this.mirrorTarget=null,super.free()}rebuildSurfaceIfNeeded(e){let t=JSON.stringify([this.size,this.quality]);if(t===this.surfaceKey&&e.geometry.getAttribute(`position`))return;this.surfaceKey=t,e.geometry?.dispose(),e.material?.dispose?.();let n=this.size[0]??1,r=this.size[1]??1;this.quality===`simple`?(e.geometry=Dg(n,r,tg),e.material=this.buildLakeMaterial()):(e.geometry=Dg(n,r,Math.min(Math.max(Math.round(Math.max(n,r)*Qh),$h),eg)),e.material=this.buildFancyMaterial())}buildFancyMaterial(){return new vl({vertexShader:eh,fragmentShader:th,fog:!0,uniforms:{fogColor:{value:new K(`#ffffff`)},fogNear:{value:1},fogFar:{value:1e3},fogDensity:{value:25e-5},uTime:{value:0},uOpacity:{value:this.rp(`opacity`)},uEnvironmentMap:{value:null},uUseEnvironmentMap:{value:0},uMirrorMap:{value:null},uMirrorMatrix:{value:new G},uUseMirror:{value:0},uMirrorDistort:{value:Yh},uWavesAmplitude:{value:this.rp(`waveHeight`)*Wh},uWavesSpeed:{value:fh.speed},uWavesFrequency:{value:fh.frequency},uWavesPersistence:{value:fh.persistence},uWavesLacunarity:{value:fh.lacunarity},uWavesIterations:{value:fh.iterations},uTroughColor:{value:new K(zh.trough)},uSurfaceColor:{value:new K(zh.surface)},uPeakColor:{value:new K(zh.peak)},uPeakThreshold:{value:Bh.peakThreshold},uPeakTransition:{value:Bh.peakTransition},uTroughThreshold:{value:Bh.troughThreshold},uTroughTransition:{value:Bh.troughTransition},uFresnelScale:{value:Bh.fresnelScale},uFresnelPower:{value:Bh.fresnelPower},uScale:{value:new U(1,1,1)},uWaterCenter:{value:new U},uRipples:{value:Array.from({length:8},()=>new Ra)},uRippleFoam:{value:Array.from({length:8},()=>0)},uSplashFoam:{value:+!!this.splash},uSunDirection:{value:new U(.5,.8,.3)},uSunColor:{value:new K(this.sunColor)},uSunIntensity:{value:this.rp(`sunIntensity`)},uDetailStrength:{value:this.rp(`detailStrength`)},uAbsorption:{value:this.rp(`absorption`)},uUseSceneDepth:{value:0},uUseRefraction:{value:0},uSceneColor:{value:null},uEnableFoam:{value:0},uFoamColor:{value:new K(Vh.color)},uFoamIntensity:{value:Vh.intensity},uFoamRange:{value:Hh(this.size[0]??1,this.size[1]??1)},uFoamScale:{value:Vh.scale},uDepthTexture:{value:null},uScenePassTexel:{value:new V(1/512,1/512)},uCameraNear:{value:.1},uCameraFar:{value:1e3},uEdgeColor:{value:new K(Vh.edgeColor)},uEdgeIntensity:{value:Vh.edgeIntensity},uEdgeWidth:{value:Vh.edgeWidth},uSwellAmplitude:{value:this.rp(`swell`)},uSwellDir:{value:new V(0,1)},uSwellWavelength:{value:this.rp(`swellWavelength`)},uSwellSteepness:{value:this.rp(`swellSteepness`)},uWhitecaps:{value:this.rp(`whitecaps`)},uWaveEnvelope:{value:0},uCausticsAbove:{value:this.rp(`causticsAbove`)},uShoreWaves:{value:this.rp(`shoreWaves`)},uReflectivityMax:{value:.6},uCameraSubmerged:{value:0},uEdgeFadeOn:{value:1}},transparent:!0,depthTest:!0,depthWrite:!0,side:2})}buildLakeMaterial(){return new vl({vertexShader:Gm,fragmentShader:Km,fog:!0,uniforms:{fogColor:{value:new K(`#ffffff`)},fogNear:{value:1},fogFar:{value:1e3},fogDensity:{value:25e-5},uTime:{value:0},uOpacity:{value:this.rp(`opacity`)},uColor:{value:new K(this.rp(`color`))},uSurfaceColor:{value:new K(this.rp(`color`))},uSkyColor:{value:new K(this.rp(`color`))},uSunDirection:{value:new U(.5,.8,.3).normalize()},uSunColor:{value:new K(this.sunColor)},uSunIntensity:{value:this.rp(`sunIntensity`)},uDetailStrength:{value:this.rp(`detailStrength`)},uFresnelPower:{value:Bh.fresnelPower},uScale:{value:new U(1,1,1)},uWaterCenter:{value:new U},uRipples:{value:Array.from({length:8},()=>new Ra)},uRippleFoam:{value:Array.from({length:8},()=>0)},uSplashFoam:{value:+!!this.splash},uFoamColor:{value:new K(Vh.color)}},transparent:!0,depthTest:!0,depthWrite:!1,side:2})}renderCutoutMasks(e){let t=this._cutouts;t.length=0;let n=this;for(;n.parent;)n=n.parent;if(yg(n,t),t.length===0)return;let r=Jg.uniforms,i=this._maskSaved,a=this._maskMeshes,o=e.gl.clippingPlanes;e.gl.clippingPlanes=Wg;let s=0;for(let n of t){if(s>=4)break;let t=bg(n);if(!t)continue;n._syncObject3D();let o=n._ensureObject3D();if(o.updateWorldMatrix(!0,!1),o.getWorldPosition(gg),o.getWorldQuaternion(_g),(r.uCenter?.value)?.copy(gg),(r.uHalf?.value)?.set((n.size[0]??1)/2,(n.size[1]??1)/2,(n.size[2]??1)/2),vg.setFromQuaternion(_g,`YXZ`),(r.uYaw?.value)?.set(Math.cos(vg.y),Math.sin(vg.y)),a.length=0,i.length=0,Sg(t,a),a.length!==0){for(let e of a)i.push(e.material),e.material=Jg;e.gl.render(t,e.camera);for(let e=0;e<a.length;e++){let t=a[e],n=i[e];t&&n&&(t.material=n)}s++}}a.length=0,i.length=0,e.gl.clippingPlanes=o}syncFancy(e){let t=e.material.uniforms,n=this.size[0]??1,r=this.size[1]??1,i=wg(this);t.uTime&&(t.uTime.value=this.time),t.uOpacity&&(t.uOpacity.value=this.rp(`opacity`)),t.uWavesAmplitude&&(t.uWavesAmplitude.value=this.rp(`waveHeight`)*Wh),(t.uScale?.value)?.set(n/2,r/2,r/2),(t.uWaterCenter?.value)?.set(i.x,i.y,i.z);let a=this.resolvePalette();(t.uTroughColor?.value)?.copy(a.trough),(t.uSurfaceColor?.value)?.copy(a.surface),(t.uPeakColor?.value)?.copy(a.peak),(t.uSunDirection?.value)?.set(this.sunDirection[0]??0,this.sunDirection[1]??1,this.sunDirection[2]??0).normalize(),(t.uSunColor?.value)?.set(this.sunColor),t.uSunIntensity&&(t.uSunIntensity.value=this.rp(`sunIntensity`)),t.uDetailStrength&&(t.uDetailStrength.value=this.rp(`detailStrength`)),t.uAbsorption&&(t.uAbsorption.value=this.rp(`absorption`)),t.uSwellAmplitude&&(t.uSwellAmplitude.value=this.rp(`swell`)),t.uSwellWavelength&&(t.uSwellWavelength.value=this.rp(`swellWavelength`)),t.uSwellSteepness&&(t.uSwellSteepness.value=this.rp(`swellSteepness`)),t.uWhitecaps&&(t.uWhitecaps.value=this.rp(`whitecaps`)),t.uCausticsAbove&&(t.uCausticsAbove.value=this.rp(`causticsAbove`)),t.uShoreWaves&&(t.uShoreWaves.value=this.rp(`shoreWaves`));let o=this.presetLook();t.uFresnelScale&&(t.uFresnelScale.value=o.fresnelScale),t.uReflectivityMax&&(t.uReflectivityMax.value=o.reflectivityMax),t.uEdgeFadeOn&&(t.uEdgeFadeOn.value=+!!o.edgeFade),t.uFoamRange&&(t.uFoamRange.value=Hh(n,r)*o.foamRangeScale),t.uFoamIntensity&&(t.uFoamIntensity.value=o.foamIntensity);let s=this.swellDirectionDeg*Math.PI/180;(t.uSwellDir?.value)?.set(Math.sin(s),Math.cos(s)),t.uWaveEnvelope&&(t.uWaveEnvelope.value=this.rp(`waveHeight`)*Wh*1.5+this.rp(`swell`)*1.03),!this.reflection&&t.uUseEnvironmentMap&&(t.uUseEnvironmentMap.value=0),!this.foam&&t.uEnableFoam&&(t.uEnableFoam.value=0),!this.refraction&&t.uUseRefraction&&(t.uUseRefraction.value=0),t.uSplashFoam&&(t.uSplashFoam.value=+!!this.splash);let c=t.uRipples?.value,l=t.uRippleFoam?.value;if(c)for(let e=0;e<c.length;e++){let t=this._ripples[e];t?c[e].set(t.x,t.z,t.age,t.amp):c[e].set(0,0,0,0),l&&(l[e]=t?t.foam??0:0)}}_applySunDirection(t){let n=e.props.sunDirection?.default;this.sunDirection.every((e,t)=>e===n[t])&&(this._ensureObject3D().material.uniforms?.uSunDirection?.value)?.set(t[0],t[1],t[2])}resolvePalette(){let t=this.rp(`colors`),n=this.rp(`color`),r=n===e.props.color?.default?null:n,i=t.surface??r??zh.surface;return jg.surface.set(i),t.trough?jg.trough.set(t.trough):r?jg.trough.set(r).lerp(Og,.45):jg.trough.set(zh.trough),t.peak?jg.peak.set(t.peak):r?jg.peak.set(r).lerp(kg,.3):jg.peak.set(zh.peak),jg}syncSimple(e){let t=e.material;t.opacity=this.rp(`opacity`);let n=t.uniforms,r=this.size[0]??1,i=this.size[1]??1,a=wg(this,this._scratchA);n.uTime&&(n.uTime.value=this.time),n.uOpacity&&(n.uOpacity.value=this.rp(`opacity`)),(n.uSurfaceColor?.value)?.set(this.rp(`color`)).lerp(kg,.12),(n.uColor?.value)?.set(this.rp(`color`)).lerp(Og,.4),(n.uSkyColor?.value)?.set(this.rp(`color`)).lerp(Ag,.82),(n.uScale?.value)?.set(r/2,i/2,i/2),(n.uWaterCenter?.value)?.set(a.x,a.y,a.z),(n.uSunDirection?.value)?.set(this.sunDirection[0]??0,this.sunDirection[1]??1,this.sunDirection[2]??0).normalize(),(n.uSunColor?.value)?.set(this.sunColor),n.uSunIntensity&&(n.uSunIntensity.value=this.rp(`sunIntensity`)),n.uDetailStrength&&(n.uDetailStrength.value=this.rp(`detailStrength`)),n.uSplashFoam&&(n.uSplashFoam.value=+!!this.splash);let o=n.uRipples?.value,s=n.uRippleFoam?.value;if(o)for(let e=0;e<o.length;e++){let t=this._ripples[e];t?o[e].set(t.x,t.z,t.age,t.amp):o[e].set(0,0,0,0),s&&(s[e]=t?t.foam??0:0)}let c=e.geometry,l=c.getAttribute(`position`),u=c.getAttribute(`normal`),d=this.time,f=this.rp(`waveHeight`),p=a.x,m=a.z,h=this._ripples,g=.5;for(let e=0;e<l.count;e++){let t=l.getX(e),n=l.getZ(e),r=Th(t,n,d,f)+Um(t+p,n+m,h);l.setY(e,r);let i=Th(t+g,n,d,f)+Um(t+p+g,n+m,h),a=Th(t,n+g,d,f)+Um(t+p,n+m+g,h),o=(r-i)/g,s=(r-a)/g,c=1/Math.hypot(o,1,s);u.setXYZ(e,o*c,c,s*c)}l.needsUpdate=!0,u.needsUpdate=!0}stepInteraction(e){let t=this;for(;t.parent;)t=t.parent;let n=this._bodies;n.length=0,Cg(t,n);let r=wg(this,this._scratchA),i=(this.size[0]??0)/2,a=(this.size[1]??0)/2,o=[];for(let e of n){let t=wg(e,this._scratchB);if(Math.abs(t.x-r.x)>i||Math.abs(t.z-r.z)>a)continue;let n=Lm(e.collider);o.push({id:e,x:t.x,y:t.y,z:t.z,waterline:r.y+this.waveOffsetAt(t.x,t.z,r)+n})}let{entered:s,exited:c,inWater:l}=zm(this.inWater,o,ng);this.inWater=l;let u=this.splash;for(let e of s){let t=Math.abs(Tg(e.id)?.[1]??0);Bm(this._ripples,e.x,e.z,Eg(e.id),u?Rm(t):0),this.emit(`entered`,e.id)}for(let e of c)Bm(this._ripples,e.x,e.z,og,u?dg:0),this.emit(`exited`,e.id);for(let t of Wm(this.bobTimers,l,e,sg)){let e=wg(t,this._scratchB);Bm(this._ripples,e.x,e.z,cg)}for(let e of l){let t=wg(e,this._scratchB),n=this.wadeAnchors.get(e);if(!n){this.wadeAnchors.set(e,{x:t.x,z:t.z});continue}let r=t.x-n.x,i=t.z-n.z;if(r*r+i*i>=lg*lg){let r=Tg(e),i=Math.hypot(r?.[0]??0,r?.[2]??0),a=u?Math.min(fg+pg*i,mg):0;Bm(this._ripples,t.x,t.z,ug,a),n.x=t.x,n.z=t.z}}for(let e of this.wadeAnchors.keys())l.has(e)||this.wadeAnchors.delete(e)}heightAt(e,t){let n=wg(this,this._scratchA);return n.y+this.waveOffsetAt(e,t,n)}_waterYAt(e,t){let n=wg(this,this._scratchA),r=(this.size[0]??0)/2,i=(this.size[1]??0)/2;return Math.abs(e-n.x)>r||Math.abs(t-n.z)>i?null:n.y}waveOffsetAt(e,t,n){return this.quality===`simple`?Th(e-n.x,t-n.z,this.time,this.rp(`waveHeight`)):wh(e,t,this.time,{amplitude:this.rp(`waveHeight`)*Wh,frequency:fh.frequency,persistence:fh.persistence,lacunarity:fh.lacunarity,iterations:fh.iterations,speed:fh.speed,scaleNorm:Uh})}},gg=new U,_g=new H,vg=new Qa;function yg(e,t){e instanceof Ph&&e.enabled&&e.visible&&t.push(e);for(let n of e.children)yg(n,t)}function bg(e){let t=e.parent;if(!(t instanceof Oh)||!t.parent)return null;let n=t._ensureObject3D();return typeof n?.traverse==`function`?n:null}var xg=new Set([`Terrain3D`,`Water3D`,`River3D`]);function Sg(e,t){return e.traverse(e=>{let n=e;if(!n.isMesh||!n.visible||!n.material)return;let r=(e.userData?.incantoNode)?.constructor?.typeName;r&&xg.has(r)||t.push(n)}),t}function Cg(e,t){(e instanceof Nh||e instanceof Mh)&&t.push(e);for(let n of e.children)Cg(n,t)}function wg(e,t={x:0,y:0,z:0}){let n=0,r=0,i=0,a=e;for(;a;)a instanceof Oh&&(n+=a.position[0]??0,r+=a.position[1]??0,i+=a.position[2]??0),a=a.parent;return t.x=n,t.y=r,t.z=i,t}function Tg(e){return e.velocity??e.linearVelocity}function Eg(e){let t=Math.abs(Tg(e)?.[1]??0);return Math.min(rg+ig*t,ag)}function Dg(e,t,n){let r=new cl(e,t,n,n);return r.rotateX(-Math.PI/2),r}var Og=new K(`#000000`),kg=new K(`#ffffff`),Ag=new K(`#cfe3f0`),jg={trough:new K,surface:new K,peak:new K},Mg=new V,Ng=new U,Pg=3,Fg=new U,Ig=new U,Lg=new U,Rg=new U,zg=new H,Bg=new Tc(new U(0,1,0),0),Vg=[Bg],Hg=new Tc(new U(0,-1,0),0),Ug=[Hg],Wg=[],Gg=new Tc(new U(0,1,0),0),Kg=[Gg],qg=new Sl;qg.colorWrite=!1;var Jg=new vl({uniforms:{uCenter:{value:new U},uHalf:{value:new U(1,1,1)},uYaw:{value:new V(1,0)}},vertexShader:`
|
|
5734
|
+
`;function ih(e,t,n,r,i=0){return t>=r.centerY?!1:Math.abs(e-r.centerX)<=r.halfW+i&&Math.abs(n-r.centerZ)<=r.halfD+i}var ah=22,oh={enabled:!0,strength:.6},sh={enabled:!0,color:`#cdeeff`,intensity:.55,scale:.32,speed:1};function ch(e,t){if(e===!1)return{enabled:!1,color:dh(t),visibility:ah,caustics:sh,rays:{...oh,enabled:!1}};let n=e&&typeof e==`object`?e:{};return{enabled:!0,color:n.color??dh(t),visibility:n.visibility??ah,caustics:uh(n.caustics),rays:lh(n.rays)}}function lh(e){return e===!1?{...oh,enabled:!1}:typeof e==`number`?{enabled:e>0,strength:e}:{...oh}}function uh(e){if(e===!1)return{...sh,enabled:!1};let t=e&&typeof e==`object`?e:{};return{enabled:!0,color:typeof t.color==`string`?t.color:sh.color,intensity:typeof t.intensity==`number`?t.intensity:sh.intensity,scale:typeof t.scale==`number`?t.scale:sh.scale,speed:typeof t.speed==`number`?t.speed:sh.speed}}function dh(e){let{r:t,g:n,b:r}=fh(e),i=(e,t,n)=>Math.round(e*(1-n)+t*n);return ph(Math.round(i(t,6,.45)*.7),Math.round(i(n,40,.4)*.78),Math.round(i(r,70,.35)*.82))}function fh(e){let t=e.replace(`#`,``),n=t.length===3?t.split(``).map(e=>e+e).join(``):t;return{r:Number.parseInt(n.slice(0,2),16)||0,g:Number.parseInt(n.slice(2,4),16)||0,b:Number.parseInt(n.slice(4,6),16)||0}}function ph(e,t,n){let r=e=>Math.max(0,Math.min(255,e)).toString(16).padStart(2,`0`);return`#${r(e)}${r(t)}${r(n)}`}var mh={frequency:6.7,persistence:.3,lacunarity:2.18,iterations:9,speed:.5},hh=.525,gh=.08,_h={freqX:.7,freqZ:.5,cross:.6};function vh(e,t){return e-Math.floor(e/t)*t}function yh(e){return e-Math.floor(e)}function bh(e){return vh((e*34+1)*e,289)}var xh=.211324865405187,Sh=.366025403784439,Ch=-.577350269189626,wh=.024390243902439;function Th(e,t){let n=Math.floor(e+(e+t)*Sh),r=Math.floor(t+(e+t)*Sh),i=e-n+(n+r)*xh,a=t-r+(n+r)*xh,o=+(i>a),s=i>a?0:1,c=i+xh-o,l=a+xh-s,u=i+Ch,d=a+Ch;n=vh(n,289),r=vh(r,289);let f=bh(bh(r)+n),p=bh(bh(r+s)+n+o),m=bh(bh(r+1)+n+1),h=Math.max(.5-(i*i+a*a),0),g=Math.max(.5-(c*c+l*l),0),_=Math.max(.5-(u*u+d*d),0);h*=h,h*=h,g*=g,g*=g,_*=_,_*=_;let v=2*yh(f*wh)-1,y=2*yh(p*wh)-1,b=2*yh(m*wh)-1,x=Math.abs(v)-.5,S=Math.abs(y)-.5,C=Math.abs(b)-.5,w=v-Math.floor(v+.5),T=y-Math.floor(y+.5),E=b-Math.floor(b+.5);h*=1.79284291400159-.85373472095314*(w*w+x*x),g*=1.79284291400159-.85373472095314*(T*T+S*S),_*=1.79284291400159-.85373472095314*(E*E+C*C);let D=w*i+x*a,O=T*c+S*l,k=E*u+C*d;return 130*(h*D+g*O+_*k)}function Eh(e,t,n,r){let i=Math.max(r.scaleNorm,1e-6),a=e/i,o=t/i,s=0,c=1,l=r.frequency,u=n*r.speed;for(let e=0;e<r.iterations;e++)s+=c*Th(a*l+u,o*l+u),c*=r.persistence,l*=r.lacunarity;return s*r.amplitude}function Dh(e,t,n,r){return r*(Math.sin(e*_h.freqX+n)+_h.cross*Math.sin(t*_h.freqZ+n*1.3))}function Oh(e,t){let n=e.shape;if(n!==void 0){if(n===`box`){let n=e.size;if(!Array.isArray(n)||n.length!==3||n.some(e=>typeof e!=`number`))throw new N(`BAD_FORMAT`,`Collider on '${t}': box needs "size": [x, y, z].`);return}if(n===`sphere`){if(typeof e.radius!=`number`)throw new N(`BAD_FORMAT`,`Collider on '${t}': sphere needs "radius".`);return}if(n===`capsule`){if(typeof e.radius!=`number`||typeof e.height!=`number`)throw new N(`BAD_FORMAT`,`Collider on '${t}': capsule needs "radius" and "height".`);return}if(n===`trimesh`){let n=e.vertices,r=e.indices;if(!Array.isArray(n)||n.length%3!=0||!Array.isArray(r)||r.length%3!=0)throw new N(`BAD_FORMAT`,`Collider on '${t}': trimesh needs "vertices" (flat xyz floats) and "indices" (triangle triplets).`);return}if(n!==`heightfield`&&n!==`auto`)throw new N(`BAD_FORMAT`,`Collider on '${t}': "shape" must be 'auto', 'box', 'sphere', 'capsule', 'trimesh', or 'heightfield', got ${JSON.stringify(n)}.`)}}function kh(e){let t=e;if(t.constructor?.typeName===`Terrain3D`&&typeof t.heightAt==`function`)return e;for(let t of e.children){let e=kh(t);if(e)return e}return null}var Ah=class e extends Nt{static typeName=`Node3D`;static props={position:{default:[0,0,0]},rotation:{default:[0,0,0]},static:{default:!1},scale:{default:[1,1,1]},visible:{default:!0},renderOrder:{default:0},orderGroup:{default:`default`,options:[`background`,`terrain`,`default`,`characters`,`effects`,`overlay`]},snapToGround:{default:null}};position=[0,0,0];rotation=[0,0,0];static=!1;scale=[1,1,1];visible=!0;renderOrder=0;orderGroup=`default`;snapToGround=null;get effectiveRenderOrder(){return _t(this.orderGroup,this.renderOrder,this.tree?.engine?.orderGroups)}_object3D=null;_interpPrev=null;_interpCurr=null;onReady(){this.applyGroundSnap()}applyGroundSnap(){if(this.snapToGround===null||this.snapToGround===!1)return;let t=this.snapToGround===!0?0:this.snapToGround,n=kh(this.getRoot());if(!n)return;let r=this.position[0]??0,i=0,a=this.position[2]??0;for(let t=this.parent;t;t=t.parent){if(!(t instanceof e))continue;let n=(t.rotation[1]??0)*Math.PI/180;if(n!==0){let e=Math.cos(n),t=Math.sin(n),i=r*e+a*t,o=-r*t+a*e;r=i,a=o}r+=t.position[0]??0,i+=t.position[1]??0,a+=t.position[2]??0}let o=r,s=a;this.position=[this.position[0]??0,n.heightAt(o,s)+t-i,this.position[2]??0]}get _builtObject3D(){return this._object3D}_ensureObject3D(){return this._object3D||(this._object3D=this._createObject3D(),this._object3D.userData.incantoNode=this),this._object3D}_createObject3D(){return new go}_syncObject3D(e=1,t=null){let n=this._ensureObject3D(),r=this._interpPrev,i=this._interpCurr;r&&i?n.position.set((r[0]??0)+((i[0]??0)-(r[0]??0))*e,(r[1]??0)+((i[1]??0)-(r[1]??0))*e,(r[2]??0)+((i[2]??0)-(r[2]??0))*e):n.position.set(this.position[0]??0,this.position[1]??0,this.position[2]??0),n.rotation.set(ba.degToRad(this.rotation[0]??0),ba.degToRad(this.rotation[1]??0),ba.degToRad(this.rotation[2]??0)),n.scale.set(this.scale[0]??1,this.scale[1]??1,this.scale[2]??1),n.visible=this.visible,n.renderOrder=this.effectiveRenderOrder}free(){super.free(),this._object3D?.removeFromParent(),this._object3D=null,this._interpPrev=null,this._interpCurr=null}},jh=class extends Ah{static props={collider:{default:{},variants:{tag:`shape`,byTag:{auto:{shape:`auto`},box:{shape:`box`,size:[1,1,1]},sphere:{shape:`sphere`,radius:.5},capsule:{shape:`capsule`,radius:.35,height:1},trimesh:{shape:`trimesh`,vertices:[],indices:[]},heightfield:{shape:`heightfield`}}}}};static signals=[`triggerEnter`,`triggerExit`];_collider={};_colliderChanged=!1;get collider(){return this._collider}set collider(e){this._collider=e,this._colliderChanged=!0}static validateJson(e){let t=e;if(Oh(t.collider,e.name),t.collider.shape===`heightfield`&&!(t instanceof Mh))throw new N(`BAD_FORMAT`,`Collider on '${e.name}': heightfield is static terrain — put it on a StaticBody3D (with a Terrain3D child), not a ${t.constructor.typeName}.`,{prop:`collider`})}_physics=null},Mh=class extends jh{static typeName=`StaticBody3D`},Nh=class extends jh{static typeName=`Area3D`},Ph=class extends jh{static typeName=`RigidBody3D`;static props={mass:{default:1},gravityScale:{default:1},fixedRotation:{default:!1},friction:{default:.5},restitution:{default:0},linearVelocity:{default:[0,0,0]}};mass=1;gravityScale=1;fixedRotation=!1;friction=.5;restitution=0;linearVelocity=[0,0,0];_physics3d=null;applyImpulse(e){this._physics3d?.applyImpulse(this,e)}},Fh=class extends jh{static typeName=`CharacterBody3D`;static props={velocity:{default:[0,0,0]},snapToGround:{default:!0},slopeLimitDeg:{default:45}};velocity=[0,0,0];snapToGround=!0;slopeLimitDeg=45;_grounded=!1;moveAndSlide(){if(!this._physics)throw new N(`TREE_VIOLATION`,this.collider.shape===void 0?`CharacterBody3D '${this.name}' has no collider — set a collider prop (physics skips collider-less bodies).`:`CharacterBody3D '${this.name}' has no physics world — await enablePhysics3D(engine) first.`);this._physics.moveAndSlide(this)}isOnFloor(){return this._grounded}},Ih=class extends Ah{static typeName=`WaterCutout3D`;static props={size:{default:[2,1,1]},enabled:{default:!0}};size=[2,1,1];enabled=!0;static validateJson(e){let t=e;if(!Array.isArray(t.size)||t.size.length!==3||t.size.some(e=>!(e>0)))throw new N(`BAD_FORMAT`,`WaterCutout3D '${e.name}' size must be three positive meters [x, y, z], got ${JSON.stringify(t.size)}.`,{prop:`size`})}onReady(){if(!this.parent?.parent)throw new N(`BAD_FORMAT`,`WaterCutout3D '${this.name}' must be a CHILD of the object that holds the water back (a hull, a diving bell, a dock's well) — it re-draws that object to keep water out of it, so at the scene root it has nothing to stand in for.`,{prop:`parent`})}},Lh=[`fancy`,`simple`],Rh=[`trough`,`surface`,`peak`],zh=[`custom`,`ocean`,`pool`,`lake`,`pond`],Bh={ocean:{waveHeight:.045,swell:.34,swellWavelength:52,whitecaps:.15,absorption:.17,opacity:.85,detailStrength:.17,sunIntensity:.85,colors:{trough:`#175360`,surface:`#2f8792`,peak:`#9bd8d2`},color:`#2f8792`,causticsAbove:.3,shoreWaves:.7,reflectionInterval:400,_look:{fresnelScale:1.15,reflectivityMax:.93,foamRangeScale:.35,foamIntensity:.55}},pool:{waveHeight:.006,swell:0,whitecaps:0,absorption:.3,opacity:.5,detailStrength:.16,sunIntensity:1.25,colors:{trough:`#1e8dbe`,surface:`#3fb6dc`,peak:`#bdeef7`},color:`#3fb6dc`,causticsAbove:1,reflectionInterval:600,_look:{fresnelScale:.85,reflectivityMax:.5,edgeFade:!1}},lake:{waveHeight:.028,swell:.14,swellWavelength:24,whitecaps:0,absorption:.5,opacity:.88,detailStrength:.3,colors:{trough:`#12343a`,surface:`#25565c`,peak:`#7fb2ab`},color:`#25565c`,causticsAbove:.15,reflectionInterval:300,_look:{fresnelScale:1.25,reflectivityMax:.78}},pond:{waveHeight:.006,swell:0,whitecaps:0,absorption:.85,opacity:.93,detailStrength:.14,sunIntensity:.7,colors:{trough:`#1c2e1e`,surface:`#39543c`,peak:`#6f8a68`},color:`#39543c`,causticsAbove:0,reflectionInterval:800,_look:{fresnelScale:1.05,reflectivityMax:.78,edgeFade:!1}}},Vh={trough:`#135a72`,surface:`#2a86a0`,peak:`#a5ddd6`},Hh={peakThreshold:.08,peakTransition:.05,troughThreshold:-.01,troughTransition:.15,fresnelScale:1,fresnelPower:5},Uh={color:`#dcebe8`,intensity:.32,rangeMin:.45,rangeMax:1.4,scale:.35,edgeColor:`#ffffff`,edgeIntensity:.6,edgeWidth:.5};function Wh(e,t){return Math.min(Uh.rangeMax,Math.max(Uh.rangeMin,Math.min(e,t)*.012))}var Gh=128,Kh=hh/gh,qh=256,Jh=2e3,Yh=3,Xh=640,Zh=.06,Qh=1024,$h=.02,eg=1.5,tg=24,ng=160,rg=32,ig=.05,ag=.08,og=.02,sg=.18,cg=.04,lg=1.4,ug=.04,dg=.45,fg=.08,pg=.4,mg=.22,hg=.09,gg=.85,_g=class e extends Ah{static typeName=`Water3D`;static signals=[`entered`,`exited`];static props={size:{default:[40,40]},color:{default:`#2a6fbe`},opacity:{default:.8},renderOrder:{default:1},waveHeight:{default:.04},waveSpeed:{default:1},quality:{default:`fancy`,options:Lh},colors:{default:{}},reflection:{default:!0},reflectionInterval:{default:1e3},mirror:{default:!1},mirrorInterval:{default:33},swellSteepness:{default:.35},foam:{default:!0},reflectivity:{default:null},interaction:{default:!0},splash:{default:!0},sunDirection:{default:[.5,.8,.3]},sunColor:{default:`#fff5d6`},sunIntensity:{default:1},detailStrength:{default:.26},absorption:{default:.15},refraction:{default:!0},underwater:{default:!0},swell:{default:0},swellDirectionDeg:{default:0},swellWavelength:{default:30},whitecaps:{default:0},preset:{default:`custom`,options:zh},causticsAbove:{default:0},shoreWaves:{default:0}};size=[40,40];color=`#2a6fbe`;opacity=.8;renderOrder=1;waveHeight=.04;waveSpeed=1;quality=`fancy`;colors={};reflection=!0;mirror=!1;mirrorInterval=33;reflectionInterval=1e3;foam=!0;reflectivity=null;interaction=!0;splash=!0;sunDirection=[.5,.8,.3];sunColor=`#fff5d6`;sunIntensity=1;detailStrength=.26;absorption=.15;refraction=!0;underwater=!0;swell=0;swellDirectionDeg=0;swellWavelength=30;swellSteepness=.35;whitecaps=0;preset=`custom`;causticsAbove=0;shoreWaves=0;rp(t){let n=Bh[this.preset],r=this;if(n&&t in n){let i=e.props[t]?.default,a=r[t];if(typeof a==`object`&&a?JSON.stringify(a)===JSON.stringify(i):a===i)return n[t]}return r[t]}presetLook(){let e=Bh[this.preset]?._look,t=this.rp(`reflectivity`);return{fresnelScale:e?.fresnelScale??Hh.fresnelScale,reflectivityMax:typeof t==`number`?Math.min(Math.max(t,0),1):e?.reflectivityMax??.6,edgeFade:e?.edgeFade??!0,foamRangeScale:e?.foamRangeScale??1,foamIntensity:e?.foamIntensity??Uh.intensity}}static validateJson(e){let t=e;if(!((t.size[0]??0)>0)||!((t.size[1]??0)>0))throw new N(`BAD_FORMAT`,`Water3D '${e.name}' size must be positive [width, depth] meters, got ${JSON.stringify(t.size)}.`,{prop:`size`});if(!Lh.includes(t.quality))throw new N(`BAD_FORMAT`,`Water3D '${e.name}' quality must be one of [${Lh.join(`, `)}], got '${t.quality}'.`,{prop:`quality`,validOptions:Lh});for(let[n,r]of Object.entries(t.colors)){if(!Rh.includes(n))throw new N(`BAD_FORMAT`,`Water3D '${e.name}' colors has unknown key '${n}'. Valid keys: [${Rh.join(`, `)}].`,{prop:`colors`,validOptions:Rh});if(typeof r!=`string`)throw new N(`BAD_FORMAT`,`Water3D '${e.name}' colors.${n} must be a hex color string, got ${JSON.stringify(r)}.`,{prop:`colors`})}if(!(t.reflectionInterval>0))throw new N(`BAD_FORMAT`,`Water3D '${e.name}' reflectionInterval must be > 0 ms, got ${t.reflectionInterval}.`,{prop:`reflectionInterval`});let n=t.sunDirection;if(!Array.isArray(n)||n.length!==3||!n.every(e=>Number.isFinite(e))||Math.hypot(n[0]??0,n[1]??0,n[2]??0)===0)throw new N(`BAD_FORMAT`,`Water3D '${e.name}' sunDirection must be a non-zero [x, y, z] vector, got ${JSON.stringify(n)}.`,{prop:`sunDirection`});if(!(t.sunIntensity>=0))throw new N(`BAD_FORMAT`,`Water3D '${e.name}' sunIntensity must be >= 0, got ${t.sunIntensity}.`,{prop:`sunIntensity`});if(!(t.detailStrength>=0))throw new N(`BAD_FORMAT`,`Water3D '${e.name}' detailStrength must be >= 0, got ${t.detailStrength}.`,{prop:`detailStrength`});if(!(t.absorption>=0))throw new N(`BAD_FORMAT`,`Water3D '${e.name}' absorption must be >= 0 (per-meter Beer's-law constant), got ${t.absorption}.`,{prop:`absorption`});if(!(t.swell>=0)||!Number.isFinite(t.swell))throw new N(`BAD_FORMAT`,`Water3D '${e.name}' swell must be >= 0 meters (0 = off), got ${JSON.stringify(t.swell)}.`,{prop:`swell`});if(!(t.swellWavelength>=2))throw new N(`BAD_FORMAT`,`Water3D '${e.name}' swellWavelength must be >= 2 meters, got ${JSON.stringify(t.swellWavelength)}.`,{prop:`swellWavelength`});if(!(t.whitecaps>=0)||!(t.whitecaps<=1))throw new N(`BAD_FORMAT`,`Water3D '${e.name}' whitecaps must be in [0, 1], got ${JSON.stringify(t.whitecaps)}.`,{prop:`whitecaps`});if(!zh.includes(t.preset))throw new N(`BAD_FORMAT`,`Water3D '${e.name}' preset must be one of [${zh.join(`, `)}], got '${t.preset}'.`,{prop:`preset`,validOptions:zh});if(!(t.shoreWaves>=0)||!(t.shoreWaves<=1))throw new N(`BAD_FORMAT`,`Water3D '${e.name}' shoreWaves must be in [0, 1] (0 = off), got ${JSON.stringify(t.shoreWaves)}.`,{prop:`shoreWaves`});if(!(t.causticsAbove>=0)||!(t.causticsAbove<=3))throw new N(`BAD_FORMAT`,`Water3D '${e.name}' causticsAbove must be in [0, 3] (0 = off), got ${JSON.stringify(t.causticsAbove)}.`,{prop:`causticsAbove`});let r=t.underwater;if(typeof r!=`boolean`){if(typeof r!=`object`||!r||Array.isArray(r))throw new N(`BAD_FORMAT`,`Water3D '${e.name}' underwater must be true, false or an object ({ color?, visibility? }), got ${JSON.stringify(r)}.`,{prop:`underwater`});let t=r;if(t.color!==void 0&&typeof t.color!=`string`)throw new N(`BAD_FORMAT`,`Water3D '${e.name}' underwater.color must be a hex color string, got ${JSON.stringify(t.color)}.`,{prop:`underwater`});if(t.visibility!==void 0&&!(t.visibility>0))throw new N(`BAD_FORMAT`,`Water3D '${e.name}' underwater.visibility must be > 0 meters, got ${JSON.stringify(t.visibility)}.`,{prop:`underwater`})}}time=0;surfaceKey=``;_ripples=[];inWater=new Set;bobTimers=new Map;wadeAnchors=new Map;_scratchA={x:0,y:0,z:0};_scratchB={x:0,y:0,z:0};_bodies=[];_cutouts=[];_maskMeshes=[];_maskSaved=[];_passHidden=[];cubeTarget=null;cubeCamera=null;reflectionNear=0;lastReflectionAt=0;scenePassTarget=null;mirrorTarget=null;mirrorCamera=new pu;mirrorMatrix=new G;lastMirrorAt=0;lastMirrorEye=new U(1/0,1/0,1/0);lastMirrorQuat=new H;_createObject3D(){return new Ys}update(e){this.time+=e*this.waveSpeed,Um(this._ripples,e),this.interaction&&this.stepInteraction(e)}_syncObject3D(){super._syncObject3D();let e=this._ensureObject3D();this.rebuildSurfaceIfNeeded(e),this.quality===`simple`?this.syncSimple(e):this.syncFancy(e)}_onRender3D(e){let t=this._ensureObject3D(),n=t.material;if(e.camera.updateWorldMatrix(!0,!1),e.camera.getWorldPosition(Fg),this.underwaterAt(Fg.x,Fg.y,Fg.z)){if(n.isShaderMaterial){let e=n.uniforms;e.uUseSceneDepth&&(e.uUseSceneDepth.value=0),e.uUseRefraction&&(e.uUseRefraction.value=0),e.uUseMirror&&(e.uUseMirror.value=0),e.uCameraSubmerged&&(e.uCameraSubmerged.value=1)}return}if(this.quality!==`fancy`||!n.isShaderMaterial)return;let r=Math.hypot((this.size[0]??1)/2,(this.size[1]??1)/2);if(!Rm(e.camera,Eg(this),r+1))return;let i=n.uniforms;i.uCameraSubmerged&&(i.uCameraSubmerged.value=0);let a=Date.now();if(this.reflection){this.cubeTarget||=new Ad(qh,{generateMipmaps:!0,minFilter:cr,type:gr});let n=Math.max((this.size[0]??1)/2,(this.size[1]??1)/2);(!this.cubeCamera||this.reflectionNear!==n)&&(this.reflectionNear=n,this.cubeCamera=new Du(n,1e3,this.cubeTarget),this.lastReflectionAt=0);let r=this.mirror?Math.max(this.rp(`reflectionInterval`),Jh):this.rp(`reflectionInterval`);if(this.lastReflectionAt===0||a-this.lastReflectionAt>=r){this.lastReflectionAt=a;let n=Eg(this),r=this.cubeCamera;r.position.set(n.x,n.y+.1,n.z);let i=t.visible;t.visible=!1,r.update(e.gl,e.scene),t.visible=i}i.uEnvironmentMap&&i.uUseEnvironmentMap&&(i.uEnvironmentMap.value=this.cubeTarget.texture,i.uUseEnvironmentMap.value=1)}if(this.mirror&&i.uMirrorMap&&i.uMirrorMatrix&&i.uUseMirror){e.gl.getDrawingBufferSize(Pg);let n=Math.max(1,Math.min(Math.round(Pg.x/Yh),Xh)),r=Math.max(1,Math.min(Math.round(Pg.y/Yh),Xh));this.mirrorTarget&&(this.mirrorTarget.width!==n||this.mirrorTarget.height!==r)&&(this.mirrorTarget.dispose(),this.mirrorTarget=null),this.mirrorTarget||=new Ba(n,r,{depthBuffer:!0,stencilBuffer:!1,type:gr,samples:4});let o=Eg(this).y,s=e.camera;s.getWorldPosition(Lg),s.getWorldQuaternion(Vg),zg.set(0,0,-1).applyQuaternion(Vg).add(Lg),Bg.set(0,1,0).applyQuaternion(Vg),Lg.y=2*o-Lg.y,zg.y=2*o-zg.y,Bg.y=-Bg.y;let c=this.mirrorCamera;c.fov=s.fov??50,c.aspect=s.aspect??n/r,c.near=s.near??.1,c.far=s.far??1e3,c.position.copy(Lg),c.up.copy(Bg),c.lookAt(zg),c.updateMatrixWorld(!0),c.updateProjectionMatrix(),s.getWorldPosition(Rg);let l=Rg.distanceToSquared(this.lastMirrorEye)>1e-6||Math.abs(Vg.dot(this.lastMirrorQuat))<.9999995;if(this.lastMirrorAt===0||l||a-this.lastMirrorAt>=this.rp(`mirrorInterval`)){this.lastMirrorAt=a,this.lastMirrorEye.copy(Rg),this.lastMirrorQuat.copy(Vg),this.mirrorMatrix.set(.5,0,0,.5,0,.5,0,.5,0,0,.5,.5,0,0,0,1),this.mirrorMatrix.multiply(c.projectionMatrix),this.mirrorMatrix.multiply(c.matrixWorldInverse);let n=e.gl.getRenderTarget(),r=e.gl.clippingPlanes,i=t.visible;t.visible=!1,Hg.constant=-(o-$h),e.gl.clippingPlanes=Ug,e.gl.setRenderTarget(this.mirrorTarget),e.gl.clear(!0,!0,!1),Xm(e.scene,this._passHidden),e.gl.render(e.scene,c),Zm(this._passHidden),e.gl.setRenderTarget(n),e.gl.clippingPlanes=r,t.visible=i}i.uMirrorMap.value=this.mirrorTarget.texture,i.uMirrorMatrix.value.copy(this.mirrorMatrix),i.uUseMirror.value=1}else i.uUseMirror&&(i.uUseMirror.value=0);e.gl.getDrawingBufferSize(Pg);let o=Math.max(1,Math.min(Math.round(Pg.x/2),Qh)),s=Math.max(1,Math.min(Math.round(Pg.y/2),Qh));if(this.scenePassTarget&&(this.scenePassTarget.width!==o||this.scenePassTarget.height!==s)&&(this.scenePassTarget.depthTexture?.dispose(),this.scenePassTarget.dispose(),this.scenePassTarget=null),!this.scenePassTarget){let e=new $c(o,s);e.type=hr,this.scenePassTarget=new Ba(o,s,{depthTexture:e,depthBuffer:!0,stencilBuffer:!1,generateMipmaps:!0,minFilter:cr})}let c=e.gl.getRenderTarget(),l=e.gl.autoClear,u=e.gl.clippingPlanes,d=t.visible;t.visible=!1;let f=Eg(this).y;Wg.constant=f+$h,e.gl.clippingPlanes=Gg,e.gl.setRenderTarget(this.scenePassTarget),e.gl.autoClear=!0,e.gl.clear(!0,!0,!1),e.gl.render(e.scene,e.camera),qg.constant=-(f-$h),e.gl.clippingPlanes=Jg;let p=e.scene.overrideMaterial,m=e.scene.background;e.scene.overrideMaterial=Yg,e.scene.background=null,e.gl.autoClear=!1,Xm(e.scene,this._passHidden),e.gl.render(e.scene,e.camera),Zm(this._passHidden),e.scene.overrideMaterial=p,e.scene.background=m,this.renderCutoutMasks(e),e.gl.setRenderTarget(c),e.gl.autoClear=l,e.gl.clippingPlanes=u,t.visible=d,i.uDepthTexture&&i.uSceneColor&&i.uCameraNear&&i.uCameraFar&&i.uUseSceneDepth&&(i.uDepthTexture.value=this.scenePassTarget.depthTexture,(i.uScenePassTexel?.value)?.set(1/o,1/s),i.uSceneColor.value=this.scenePassTarget.texture,i.uCameraNear.value=e.camera.near,i.uCameraFar.value=e.camera.far,i.uUseSceneDepth.value=1,i.uUseRefraction&&(i.uUseRefraction.value=+!!this.refraction),i.uEnableFoam&&(i.uEnableFoam.value=+!!this.foam))}underwaterAt(e,t,n){if(this.underwater===!1)return null;let r=Eg(this,this._scratchA);if(!ih(e,t,n,{centerX:r.x,centerY:r.y,centerZ:r.z,halfW:(this.size[0]??1)/2,halfD:(this.size[1]??1)/2},Ig))return null;let i=ch(this.underwater,this.rp(`color`));return i.enabled?{...i,surfaceY:r.y}:null}free(){let e=this._builtObject3D;e?.geometry?.dispose(),(e?.material)?.dispose?.(),this.cubeTarget?.dispose(),this.cubeTarget=null,this.cubeCamera=null,this.scenePassTarget?.depthTexture?.dispose(),this.scenePassTarget?.dispose(),this.scenePassTarget=null,this.mirrorTarget?.dispose(),this.mirrorTarget=null,super.free()}rebuildSurfaceIfNeeded(e){let t=JSON.stringify([this.size,this.quality]);if(t===this.surfaceKey&&e.geometry.getAttribute(`position`))return;this.surfaceKey=t,e.geometry?.dispose(),e.material?.dispose?.();let n=this.size[0]??1,r=this.size[1]??1;this.quality===`simple`?(e.geometry=kg(n,r,rg),e.material=this.buildLakeMaterial()):(e.geometry=kg(n,r,Math.min(Math.max(Math.round(Math.max(n,r)*eg),tg),ng)),e.material=this.buildFancyMaterial())}buildFancyMaterial(){return new vl({vertexShader:nh,fragmentShader:rh,fog:!0,uniforms:{fogColor:{value:new K(`#ffffff`)},fogNear:{value:1},fogFar:{value:1e3},fogDensity:{value:25e-5},uTime:{value:0},uOpacity:{value:this.rp(`opacity`)},uEnvironmentMap:{value:null},uUseEnvironmentMap:{value:0},uMirrorMap:{value:null},uMirrorMatrix:{value:new G},uUseMirror:{value:0},uMirrorDistort:{value:Zh},uWavesAmplitude:{value:this.rp(`waveHeight`)*Kh},uWavesSpeed:{value:mh.speed},uWavesFrequency:{value:mh.frequency},uWavesPersistence:{value:mh.persistence},uWavesLacunarity:{value:mh.lacunarity},uWavesIterations:{value:mh.iterations},uTroughColor:{value:new K(Vh.trough)},uSurfaceColor:{value:new K(Vh.surface)},uPeakColor:{value:new K(Vh.peak)},uPeakThreshold:{value:Hh.peakThreshold},uPeakTransition:{value:Hh.peakTransition},uTroughThreshold:{value:Hh.troughThreshold},uTroughTransition:{value:Hh.troughTransition},uFresnelScale:{value:Hh.fresnelScale},uFresnelPower:{value:Hh.fresnelPower},uScale:{value:new U(1,1,1)},uWaterCenter:{value:new U},uRipples:{value:Array.from({length:8},()=>new Ra)},uRippleFoam:{value:Array.from({length:8},()=>0)},uSplashFoam:{value:+!!this.splash},uSunDirection:{value:new U(.5,.8,.3)},uSunColor:{value:new K(this.sunColor)},uSunIntensity:{value:this.rp(`sunIntensity`)},uDetailStrength:{value:this.rp(`detailStrength`)},uAbsorption:{value:this.rp(`absorption`)},uUseSceneDepth:{value:0},uUseRefraction:{value:0},uSceneColor:{value:null},uEnableFoam:{value:0},uFoamColor:{value:new K(Uh.color)},uFoamIntensity:{value:Uh.intensity},uFoamRange:{value:Wh(this.size[0]??1,this.size[1]??1)},uFoamScale:{value:Uh.scale},uDepthTexture:{value:null},uScenePassTexel:{value:new V(1/512,1/512)},uCameraNear:{value:.1},uCameraFar:{value:1e3},uEdgeColor:{value:new K(Uh.edgeColor)},uEdgeIntensity:{value:Uh.edgeIntensity},uEdgeWidth:{value:Uh.edgeWidth},uSwellAmplitude:{value:this.rp(`swell`)},uSwellDir:{value:new V(0,1)},uSwellWavelength:{value:this.rp(`swellWavelength`)},uSwellSteepness:{value:this.rp(`swellSteepness`)},uWhitecaps:{value:this.rp(`whitecaps`)},uWaveEnvelope:{value:0},uCausticsAbove:{value:this.rp(`causticsAbove`)},uShoreWaves:{value:this.rp(`shoreWaves`)},uReflectivityMax:{value:.6},uCameraSubmerged:{value:0},uEdgeFadeOn:{value:1}},transparent:!0,depthTest:!0,depthWrite:!0,side:2})}buildLakeMaterial(){return new vl({vertexShader:qm,fragmentShader:Jm,fog:!0,uniforms:{fogColor:{value:new K(`#ffffff`)},fogNear:{value:1},fogFar:{value:1e3},fogDensity:{value:25e-5},uTime:{value:0},uOpacity:{value:this.rp(`opacity`)},uColor:{value:new K(this.rp(`color`))},uSurfaceColor:{value:new K(this.rp(`color`))},uSkyColor:{value:new K(this.rp(`color`))},uSunDirection:{value:new U(.5,.8,.3).normalize()},uSunColor:{value:new K(this.sunColor)},uSunIntensity:{value:this.rp(`sunIntensity`)},uDetailStrength:{value:this.rp(`detailStrength`)},uFresnelPower:{value:Hh.fresnelPower},uScale:{value:new U(1,1,1)},uWaterCenter:{value:new U},uRipples:{value:Array.from({length:8},()=>new Ra)},uRippleFoam:{value:Array.from({length:8},()=>0)},uSplashFoam:{value:+!!this.splash},uFoamColor:{value:new K(Uh.color)}},transparent:!0,depthTest:!0,depthWrite:!1,side:2})}renderCutoutMasks(e){let t=this._cutouts;t.length=0;let n=this;for(;n.parent;)n=n.parent;if(xg(n,t),t.length===0)return;let r=Xg.uniforms,i=this._maskSaved,a=this._maskMeshes,o=e.gl.clippingPlanes;e.gl.clippingPlanes=Kg;let s=0;for(let n of t){if(s>=4)break;let t=Sg(n);if(!t)continue;n._syncObject3D();let o=n._ensureObject3D();if(o.updateWorldMatrix(!0,!1),o.getWorldPosition(vg),o.getWorldQuaternion(yg),(r.uCenter?.value)?.copy(vg),(r.uHalf?.value)?.set((n.size[0]??1)/2,(n.size[1]??1)/2,(n.size[2]??1)/2),bg.setFromQuaternion(yg,`YXZ`),(r.uYaw?.value)?.set(Math.cos(bg.y),Math.sin(bg.y)),a.length=0,i.length=0,wg(t,a),a.length!==0){for(let e of a)i.push(e.material),e.material=Xg;e.gl.render(t,e.camera);for(let e=0;e<a.length;e++){let t=a[e],n=i[e];t&&n&&(t.material=n)}s++}}a.length=0,i.length=0,e.gl.clippingPlanes=o}syncFancy(e){let t=e.material.uniforms,n=this.size[0]??1,r=this.size[1]??1,i=Eg(this);t.uTime&&(t.uTime.value=this.time),t.uOpacity&&(t.uOpacity.value=this.rp(`opacity`)),t.uWavesAmplitude&&(t.uWavesAmplitude.value=this.rp(`waveHeight`)*Kh),(t.uScale?.value)?.set(n/2,r/2,r/2),(t.uWaterCenter?.value)?.set(i.x,i.y,i.z);let a=this.resolvePalette();(t.uTroughColor?.value)?.copy(a.trough),(t.uSurfaceColor?.value)?.copy(a.surface),(t.uPeakColor?.value)?.copy(a.peak),(t.uSunDirection?.value)?.set(this.sunDirection[0]??0,this.sunDirection[1]??1,this.sunDirection[2]??0).normalize(),(t.uSunColor?.value)?.set(this.sunColor),t.uSunIntensity&&(t.uSunIntensity.value=this.rp(`sunIntensity`)),t.uDetailStrength&&(t.uDetailStrength.value=this.rp(`detailStrength`)),t.uAbsorption&&(t.uAbsorption.value=this.rp(`absorption`)),t.uSwellAmplitude&&(t.uSwellAmplitude.value=this.rp(`swell`)),t.uSwellWavelength&&(t.uSwellWavelength.value=this.rp(`swellWavelength`)),t.uSwellSteepness&&(t.uSwellSteepness.value=this.rp(`swellSteepness`)),t.uWhitecaps&&(t.uWhitecaps.value=this.rp(`whitecaps`)),t.uCausticsAbove&&(t.uCausticsAbove.value=this.rp(`causticsAbove`)),t.uShoreWaves&&(t.uShoreWaves.value=this.rp(`shoreWaves`));let o=this.presetLook();t.uFresnelScale&&(t.uFresnelScale.value=o.fresnelScale),t.uReflectivityMax&&(t.uReflectivityMax.value=o.reflectivityMax),t.uEdgeFadeOn&&(t.uEdgeFadeOn.value=+!!o.edgeFade),t.uFoamRange&&(t.uFoamRange.value=Wh(n,r)*o.foamRangeScale),t.uFoamIntensity&&(t.uFoamIntensity.value=o.foamIntensity);let s=this.swellDirectionDeg*Math.PI/180;(t.uSwellDir?.value)?.set(Math.sin(s),Math.cos(s)),t.uWaveEnvelope&&(t.uWaveEnvelope.value=this.rp(`waveHeight`)*Kh*1.5+this.rp(`swell`)*1.03),!this.reflection&&t.uUseEnvironmentMap&&(t.uUseEnvironmentMap.value=0),!this.foam&&t.uEnableFoam&&(t.uEnableFoam.value=0),!this.refraction&&t.uUseRefraction&&(t.uUseRefraction.value=0),t.uSplashFoam&&(t.uSplashFoam.value=+!!this.splash);let c=t.uRipples?.value,l=t.uRippleFoam?.value;if(c)for(let e=0;e<c.length;e++){let t=this._ripples[e];t?c[e].set(t.x,t.z,t.age,t.amp):c[e].set(0,0,0,0),l&&(l[e]=t?t.foam??0:0)}}_applySunDirection(t){let n=e.props.sunDirection?.default;this.sunDirection.every((e,t)=>e===n[t])&&(this._ensureObject3D().material.uniforms?.uSunDirection?.value)?.set(t[0],t[1],t[2])}resolvePalette(){let t=this.rp(`colors`),n=this.rp(`color`),r=n===e.props.color?.default?null:n,i=t.surface??r??Vh.surface;return Ng.surface.set(i),t.trough?Ng.trough.set(t.trough):r?Ng.trough.set(r).lerp(Ag,.45):Ng.trough.set(Vh.trough),t.peak?Ng.peak.set(t.peak):r?Ng.peak.set(r).lerp(jg,.3):Ng.peak.set(Vh.peak),Ng}syncSimple(e){let t=e.material;t.opacity=this.rp(`opacity`);let n=t.uniforms,r=this.size[0]??1,i=this.size[1]??1,a=Eg(this,this._scratchA);n.uTime&&(n.uTime.value=this.time),n.uOpacity&&(n.uOpacity.value=this.rp(`opacity`)),(n.uSurfaceColor?.value)?.set(this.rp(`color`)).lerp(jg,.12),(n.uColor?.value)?.set(this.rp(`color`)).lerp(Ag,.4),(n.uSkyColor?.value)?.set(this.rp(`color`)).lerp(Mg,.82),(n.uScale?.value)?.set(r/2,i/2,i/2),(n.uWaterCenter?.value)?.set(a.x,a.y,a.z),(n.uSunDirection?.value)?.set(this.sunDirection[0]??0,this.sunDirection[1]??1,this.sunDirection[2]??0).normalize(),(n.uSunColor?.value)?.set(this.sunColor),n.uSunIntensity&&(n.uSunIntensity.value=this.rp(`sunIntensity`)),n.uDetailStrength&&(n.uDetailStrength.value=this.rp(`detailStrength`)),n.uSplashFoam&&(n.uSplashFoam.value=+!!this.splash);let o=n.uRipples?.value,s=n.uRippleFoam?.value;if(o)for(let e=0;e<o.length;e++){let t=this._ripples[e];t?o[e].set(t.x,t.z,t.age,t.amp):o[e].set(0,0,0,0),s&&(s[e]=t?t.foam??0:0)}let c=e.geometry,l=c.getAttribute(`position`),u=c.getAttribute(`normal`),d=this.time,f=this.rp(`waveHeight`),p=a.x,m=a.z,h=this._ripples,g=.5;for(let e=0;e<l.count;e++){let t=l.getX(e),n=l.getZ(e),r=Dh(t,n,d,f)+Gm(t+p,n+m,h);l.setY(e,r);let i=Dh(t+g,n,d,f)+Gm(t+p+g,n+m,h),a=Dh(t,n+g,d,f)+Gm(t+p,n+m+g,h),o=(r-i)/g,s=(r-a)/g,c=1/Math.hypot(o,1,s);u.setXYZ(e,o*c,c,s*c)}l.needsUpdate=!0,u.needsUpdate=!0}stepInteraction(e){let t=this;for(;t.parent;)t=t.parent;let n=this._bodies;n.length=0,Tg(t,n);let r=Eg(this,this._scratchA),i=(this.size[0]??0)/2,a=(this.size[1]??0)/2,o=[];for(let e of n){let t=Eg(e,this._scratchB);if(Math.abs(t.x-r.x)>i||Math.abs(t.z-r.z)>a)continue;let n=zm(e.collider);o.push({id:e,x:t.x,y:t.y,z:t.z,waterline:r.y+this.waveOffsetAt(t.x,t.z,r)+n})}let{entered:s,exited:c,inWater:l}=Vm(this.inWater,o,ig);this.inWater=l;let u=this.splash;for(let e of s){let t=Math.abs(Dg(e.id)?.[1]??0);Hm(this._ripples,e.x,e.z,Og(e.id),u?Bm(t):0),this.emit(`entered`,e.id)}for(let e of c)Hm(this._ripples,e.x,e.z,cg,u?pg:0),this.emit(`exited`,e.id);for(let t of Km(this.bobTimers,l,e,lg)){let e=Eg(t,this._scratchB);Hm(this._ripples,e.x,e.z,ug)}for(let e of l){let t=Eg(e,this._scratchB),n=this.wadeAnchors.get(e);if(!n){this.wadeAnchors.set(e,{x:t.x,z:t.z});continue}let r=t.x-n.x,i=t.z-n.z;if(r*r+i*i>=dg*dg){let r=Dg(e),i=Math.hypot(r?.[0]??0,r?.[2]??0),a=u?Math.min(mg+hg*i,gg):0;Hm(this._ripples,t.x,t.z,fg,a),n.x=t.x,n.z=t.z}}for(let e of this.wadeAnchors.keys())l.has(e)||this.wadeAnchors.delete(e)}heightAt(e,t){let n=Eg(this,this._scratchA);return n.y+this.waveOffsetAt(e,t,n)}_waterYAt(e,t){let n=Eg(this,this._scratchA),r=(this.size[0]??0)/2,i=(this.size[1]??0)/2;return Math.abs(e-n.x)>r||Math.abs(t-n.z)>i?null:n.y}waveOffsetAt(e,t,n){return this.quality===`simple`?Dh(e-n.x,t-n.z,this.time,this.rp(`waveHeight`)):Eh(e,t,this.time,{amplitude:this.rp(`waveHeight`)*Kh,frequency:mh.frequency,persistence:mh.persistence,lacunarity:mh.lacunarity,iterations:mh.iterations,speed:mh.speed,scaleNorm:Gh})}},vg=new U,yg=new H,bg=new Qa;function xg(e,t){e instanceof Ih&&e.enabled&&e.visible&&t.push(e);for(let n of e.children)xg(n,t)}function Sg(e){let t=e.parent;if(!(t instanceof Ah)||!t.parent)return null;let n=t._ensureObject3D();return typeof n?.traverse==`function`?n:null}var Cg=new Set([`Terrain3D`,`Water3D`,`River3D`]);function wg(e,t){return e.traverse(e=>{let n=e;if(!n.isMesh||!n.visible||!n.material)return;let r=(e.userData?.incantoNode)?.constructor?.typeName;r&&Cg.has(r)||t.push(n)}),t}function Tg(e,t){(e instanceof Fh||e instanceof Ph)&&t.push(e);for(let n of e.children)Tg(n,t)}function Eg(e,t={x:0,y:0,z:0}){let n=0,r=0,i=0,a=e;for(;a;)a instanceof Ah&&(n+=a.position[0]??0,r+=a.position[1]??0,i+=a.position[2]??0),a=a.parent;return t.x=n,t.y=r,t.z=i,t}function Dg(e){return e.velocity??e.linearVelocity}function Og(e){let t=Math.abs(Dg(e)?.[1]??0);return Math.min(ag+og*t,sg)}function kg(e,t,n){let r=new cl(e,t,n,n);return r.rotateX(-Math.PI/2),r}var Ag=new K(`#000000`),jg=new K(`#ffffff`),Mg=new K(`#cfe3f0`),Ng={trough:new K,surface:new K,peak:new K},Pg=new V,Fg=new U,Ig=3,Lg=new U,Rg=new U,zg=new U,Bg=new U,Vg=new H,Hg=new Tc(new U(0,1,0),0),Ug=[Hg],Wg=new Tc(new U(0,-1,0),0),Gg=[Wg],Kg=[],qg=new Tc(new U(0,1,0),0),Jg=[qg],Yg=new Sl;Yg.colorWrite=!1;var Xg=new vl({uniforms:{uCenter:{value:new U},uHalf:{value:new U(1,1,1)},uYaw:{value:new V(1,0)}},vertexShader:`
|
|
5735
5735
|
uniform vec3 uCenter;
|
|
5736
5736
|
uniform vec2 uYaw;
|
|
5737
5737
|
varying vec3 vCutLocal;
|
|
@@ -5753,7 +5753,7 @@ void main() {
|
|
|
5753
5753
|
if (any(greaterThan(abs(vCutLocal), uHalf))) discard;
|
|
5754
5754
|
gl_FragColor = vec4(0.0);
|
|
5755
5755
|
}
|
|
5756
|
-
`,colorWrite:!1,depthWrite:!0,depthTest:!1,side:2}),Yg=9.81,Xg=6,Zg=.15,Qg=class extends et{static props={water:{default:``,nodePath:!0},draft:{default:.35},stiffness:{default:3},damping:{default:3.5},drift:{default:.6},drag:{default:.9},samples:{default:4},size:{default:[1,1]}};static signals=[`submerged`,`surfaced`];water=``;draft=.35;stiffness=3;damping=3.5;drift=.6;drag=.9;samples=4;size=[1,1];surface=null;wet=!1;update(e){if(e<=0)return;let t=this.resolveWater();if(!t)return;let n=this.node;if(!n.applyImpulse)return;let[r,i,a]=[n.position[0]??0,n.position[1]??0,n.position[2]??0],o=[(this.size[0]??1)/2,(this.size[1]??1)/2],s=this.samplePoints(r,a,o[0],o[1]),c=n.mass??1,l=n.linearVelocity??[0,0,0],u=0,d=0,f=0,p=0;for(let[e,n]of s){let r=t.heightAt(e,n)-(i-this.draft);if(r<=0)continue;p++,u+=Yg*(1+this.stiffness*(r/Math.max(this.draft,Zg)));let a=.6;d+=t.heightAt(e+a,n)-t.heightAt(e-a,n),f+=t.heightAt(e,n+a)-t.heightAt(e,n-a)}let m=p>0;if(m!==this.wet&&(this.wet=m,this.emit(m?`submerged`:`surfaced`,this.node)),!m)return;let h=p/s.length,g=Math.min(u/s.length-this.damping*(l[1]??0),Xg*Yg)*e*c,_=(-d*this.drift*12-(l[0]??0)*this.drag)*h*e*c,v=(-f*this.drift*12-(l[2]??0)*this.drag)*h*e*c;n.applyImpulse([_,g,v])}samplePoints(e,t,n,r){let i=Math.max(1,Math.round(this.samples));if(i===1)return[[e,t]];let a=[];for(let o=0;o<i;o++){let s=o/i*Math.PI*2+Math.PI/4;a.push([e+Math.cos(s)*n,t+Math.sin(s)*r])}return a}resolveWater(){if(this.surface)return this.surface;if(this.water!==``){let e=this.node.getNodeOrNull(this.water);if(!(e instanceof hg))throw new N(`NODE_NOT_FOUND`,`Buoyancy on '${this.node.getPath()}': water '${this.water}' is not a Water3D in the tree.`,{prop:`water`});return this.surface=e,e}return this.surface=$g(this.node.getRoot()),this.surface}};function $g(e){if(e instanceof hg)return e;for(let t of e.children){let e=$g(t);if(e)return e}return null}function e_(e){return Array.isArray(e.position)}function t_(e){let t=e.node;if(!e_(t)){let n=e.constructor.name;throw new N(`PROP_TYPE_MISMATCH`,`${n} on '${t.getPath()}' needs a spatial node with a numeric 'position' array (a Node2D/Node3D subtype). '${t.name}' has none.`,{path:t.getPath()})}return t}function n_(e,t){let n=0,r=Math.max(e.length,t.length);for(let i=0;i<r;i++){let r=(e[i]??0)-(t[i]??0);n+=r*r}return Math.sqrt(n)}function r_(e,t){let n=Math.max(e.length,t.length),r=Array(n);for(let i=0;i<n;i++)r[i]=(e[i]??0)+(t[i]??0);return r}function i_(e){let t=0;for(let n of e)t+=n*n;return Math.sqrt(t)}function a_(e){let t=i_(e);return t===0?e.map(()=>0):e.map(e=>e/t)}function o_(e,t,n){let r=Math.max(e.length,t.length),i=0;for(let n=0;n<r;n++){let r=(t[n]??0)-(e[n]??0);i+=r*r}let a=Math.sqrt(i),o=Array(r);if(a<=n||a===0){for(let e=0;e<r;e++)o[e]=t[e]??0;return{position:o,reached:!0}}let s=n/a;for(let n=0;n<r;n++){let r=e[n]??0;o[n]=r+((t[n]??0)-r)*s}return{position:o,reached:!1}}function s_(e,t){let n=Math.min(Math.max(e,0),.99);return n<=0?1:1-n**(t*60)}var c_=class extends et{static props={target:{default:``,nodePath:!0},speed:{default:60},stopRange:{default:0},loseRange:{default:0},moveParent:{default:!1}};static signals=[`reachedTarget`,`lostTarget`];target=``;speed=60;stopRange=0;loseRange=0;moveParent=!1;inRange=!1;lost=!1;onReady(){if(this.target===``)throw new N(`PROP_TYPE_MISMATCH`,`Chase on '${this.node.getPath()}': "target" (a node path) is required.`,{prop:`target`});if(this.moveParent){let e=this.node.parent;if(!e||!e_(e))throw new N(`PROP_TYPE_MISMATCH`,`Chase on '${this.node.getPath()}': "moveParent" needs a spatial parent (a Node2D/Node3D) to move. '${this.node.name}' has none.`,{prop:`moveParent`,path:this.node.getPath()})}else t_(this)}update(e){let t=this.moveParent?this.node.parent:this.node;if(!t||!e_(t))return;let n=this.node.getNodeOrNull(this.target);if(!n||!e_(n))return;let r=n_(t.position,n.position);if(this.loseRange>0&&r>this.loseRange){this.lost||(this.lost=!0,this.inRange=!1,this.emit(`lostTarget`));return}if(this.lost=!1,this.stopRange>0&&r<=this.stopRange){this.inRange||(this.inRange=!0,this.emit(`reachedTarget`));return}this.inRange=!1;let i=Math.min(this.speed*e,this.stopRange>0?r-this.stopRange:r),{position:a}=o_(t.position,n.position,Math.max(0,i));t.position=a}},l_=class extends et{static props={button:{default:0},maxDistance:{default:0},enabled:{default:!0}};static signals=[`clicked`,`hovered`,`unhovered`];button=0;maxDistance=0;enabled=!0;hovering=!1;pressedHere=!1;update(){let e=this.node.tree?.engine;if(!e||!this.enabled)return;let t=e.picker,n=e.input.pointerPosition();if(!t||!n){this.hovering&&this.setHover(!1);return}let r=t(n.x,n.y),i=r!==null&&this.isSelfOrDescendant(r)&&this.withinRange(r);i!==this.hovering&&this.setHover(i),e.input.mouseJustPressed(this.button)&&(this.pressedHere=i),e.input.mouseJustReleased(this.button)&&(this.pressedHere&&i&&this.emit(`clicked`,this.node),this.pressedHere=!1)}setHover(e){this.hovering=e,this.emit(e?`hovered`:`unhovered`,this.node)}isSelfOrDescendant(e){for(let t=e;t;t=t.parent)if(t===this.node)return!0;return!1}withinRange(e){if(this.maxDistance<=0||!this.node.tree?.engine?.scene?.root)return!0;let t=this.node.position,n=e.position;if(!Array.isArray(t)||!Array.isArray(n))return!0;let r=0;for(let e=0;e<Math.max(t.length,n.length);e++){let i=(t[e]??0)-(n[e]??0);r+=i*i}return Math.sqrt(r)<=this.maxDistance}},u_=class extends et{static props={group:{default:`player`}};static signals=[`totalChanged`];group=`player`;total=0;onReady(){this.node.addToGroup(this.group)}collect(e){this.total+=e,this.emit(`totalChanged`,this.total)}serialize(){return{total:this.total}}deserialize(e){let t=e;typeof t.total==`number`&&(this.total=t.total)}},d_=class extends et{static props={max:{default:100},regenPerSec:{default:0},invulnerableFor:{default:0},freeOnDeath:{default:!1}};static signals=[`damaged`,`healed`,`died`];max=100;regenPerSec=0;invulnerableFor=0;freeOnDeath=!1;current=0;invulnTimer=0;dead=!1;get isDead(){return this.dead}get invulnerableRemaining(){return this.invulnTimer}onReady(){if(!(this.max>0))throw new N(`PROP_TYPE_MISMATCH`,`Health on '${this.node.getPath()}': "max" must be > 0, got ${this.max}.`,{prop:`max`});if(this.regenPerSec<0)throw new N(`PROP_TYPE_MISMATCH`,`Health on '${this.node.getPath()}': "regenPerSec" must be >= 0, got ${this.regenPerSec}.`,{prop:`regenPerSec`});if(this.invulnerableFor<0)throw new N(`PROP_TYPE_MISMATCH`,`Health on '${this.node.getPath()}': "invulnerableFor" must be >= 0, got ${this.invulnerableFor}.`,{prop:`invulnerableFor`});this.current=this.max}update(e){this.invulnTimer>0&&(this.invulnTimer=Math.max(0,this.invulnTimer-e)),this.regenPerSec>0&&!this.dead&&this.current<this.max&&this.setCurrent(this.current+this.regenPerSec*e)}damage(e){this.dead||e<=0||this.invulnTimer>0||(this.setCurrent(this.current-e),this.emit(`damaged`,e,this.current),this.invulnerableFor>0&&(this.invulnTimer=this.invulnerableFor),this.current<=0&&this.die())}heal(e){this.dead||e<=0||(this.setCurrent(this.current+e),this.emit(`healed`,e,this.current))}kill(){this.dead||(this.setCurrent(0),this.die())}setCurrent(e){this.current=Math.max(0,Math.min(this.max,e))}die(){this.dead||(this.dead=!0,this.current=0,this.emit(`died`),this.freeOnDeath&&this.node.queueFree())}serialize(){return{current:this.current,dead:this.dead}}deserialize(e){let t=e;typeof t.current==`number`&&(this.current=Math.min(this.max,Math.max(0,t.current))),typeof t.dead==`boolean`&&(this.dead=t.dead)}};function f_(e,t){let n=e.node;if(!n.declaredSignalNames().includes(`triggerEnter`)){let t=e.constructor.name;throw new N(`UNKNOWN_SIGNAL`,`${t} on '${n.getPath()}' needs a node that emits 'triggerEnter' — attach it to an Area2D/Area3D (or another body that declares the collision signals). '${n.name}' declares: [${n.declaredSignalNames().join(`, `)}].`,{signal:`triggerEnter`,path:n.getPath()})}n.on(`triggerEnter`,e=>t(e))}var p_=class extends et{static props={amount:{default:10},targetGroup:{default:``},oncePerTarget:{default:!0},repeatEvery:{default:0},destroySelf:{default:!1}};static signals=[`dealtDamage`];amount=10;targetGroup=``;oncePerTarget=!0;repeatEvery=0;destroySelf=!1;hit=new WeakSet;inside=new Map;onReady(){f_(this,e=>{this.inside.set(e,this.repeatEvery),this.tryDamage(e)}),this.node.on(`triggerExit`,e=>{this.inside.delete(e)})}update(e){if(!(this.repeatEvery<=0||this.inside.size===0))for(let[t,n]of this.inside){if(!t.tree){this.inside.delete(t);continue}let r=n-e;r>0?this.inside.set(t,r):(this.inside.set(t,this.repeatEvery),this.tryDamage(t,{repeat:!0}))}}tryDamage(e,t){if(!t?.repeat&&this.oncePerTarget&&this.hit.has(e))return;let n=m_(e);n&&(this.targetGroup!==``&&!n.owner.isInGroup(this.targetGroup)||(this.oncePerTarget&&this.hit.add(e),n.health.damage(this.amount),this.emit(`dealtDamage`,this.amount,n.owner),this.destroySelf&&this.node.queueFree()))}};function m_(e){let t=[e];for(;t.length>0;){let e=t.shift();if(e.behavior instanceof d_)return{health:e.behavior,owner:e};t.push(...e.children)}for(let t=e.parent;t;t=t.parent)if(t.behavior instanceof d_)return{health:t.behavior,owner:t};return null}var h_=class extends et{static signals=[`dayPhaseChanged`];static props={daySeconds:{default:240},startHour:{default:10},maxSunElevationDeg:{default:55},nightDarkness:{default:.75},paused:{default:!1}};daySeconds=240;startHour=10;maxSunElevationDeg=55;nightDarkness=.75;paused=!1;hour=0;phase=``;applyClock=0;baseAmbient=.3;baseExposure=1;captured=!1;onReady(){this.hour=this.startHour}update(e){if(this.paused||(this.hour=(this.hour+e/this.daySeconds*24)%24),this.applyClock-=e,this.applyClock>0)return;this.applyClock=.2,this.applyHour();let t=g_(this.hour);t!==this.phase&&(this.phase=t,this.emit(`dayPhaseChanged`,t))}applyHour(){let e=this.node.tree?.engine,t=e?.scene?.environment;if(!e||!t?.sky)return;this.captured||(this.captured=!0,this.baseAmbient=t.ambient?.intensity??.3,this.baseExposure=t.exposure??1);let n=(this.hour-6)/12*Math.PI,r=Math.sin(n);t.sky.elevationDeg=r*this.maxSunElevationDeg+(r<0?r*10:0),t.sky.azimuthDeg=this.hour/24*360+90;let i=Math.max(0,r),a=this.nightDarkness;t.ambient={...t.ambient??{},intensity:this.baseAmbient*(1-a+a*i)},t.exposure=this.baseExposure*(1-a*.55*(1-i))}};function g_(e){return e<5||e>=20?`night`:e<7.5?`dawn`:e<17.5?`day`:`dusk`}var __=class extends et{static props={target:{default:``,nodePath:!0},offset:{default:[]},smoothing:{default:0},deadzone:{default:0}};static signals=[];target=``;offset=[];smoothing=0;deadzone=0;onReady(){if(this.target===``)throw new N(`PROP_TYPE_MISMATCH`,`FollowCamera on '${this.node.getPath()}': "target" (a node path) is required.`,{prop:`target`});if(this.deadzone<0)throw new N(`PROP_TYPE_MISMATCH`,`FollowCamera on '${this.node.getPath()}': "deadzone" must be >= 0, got ${this.deadzone}.`,{prop:`deadzone`});t_(this)}shakeMag=0;shakeT=0;shakeFalloff=.28;shake(e,t=.28){this.shakeMag=Math.max(this.shakeMag,e),this.shakeT=t,this.shakeFalloff=t}update(e){let t=this.node;if(!e_(t))return;let n=t.getNodeOrNull(this.target);if(!n||!e_(n))return;let r=r_(n.position,this.offset);if(!(this.deadzone>0&&n_(t.position,r)<=this.deadzone)){let n=s_(this.smoothing,e);n>=1?t.position=[...r]:t.position=t.position.map((e,t)=>e+((r[t]??e)-e)*n)}if(this.shakeT>0){this.shakeT-=e;let n=this.shakeMag*Math.max(0,this.shakeT)/this.shakeFalloff;this.shakeT<=0&&(this.shakeMag=0);let r=t.position.slice();for(let e=0;e<r.length;e++){let t=r.length>=3&&e===1?.5:1;r[e]=(r[e]??0)+(this.engine.rng.next()*2-1)*n*t}t.position=r}}};function v_(e){let t=e.scene?.source;t&&(e.timeScale=1,e.setScene(An(He(t))))}function y_(e,t,n){let r=n?.fadeSeconds??.4,i=()=>{e.timeScale=1,e.setScene(An(He(t)))};if(typeof document>`u`||r<=0){i();return}let a=`incanto-scene-fade`,o=document.getElementById(a);o||(o=document.createElement(`div`),o.id=a,o.style.cssText=`position:fixed;inset:0;z-index:10001;background:#000;opacity:0;pointer-events:none;`,document.body.appendChild(o)),o.style.transition=`opacity ${r/2}s`,o.style.opacity=`1`,setTimeout(()=>{i();let e=document.getElementById(a);e&&(e.style.opacity=`0`,setTimeout(()=>e.remove(),r*500+60))},r*500+30)}var b_=class extends et{static signals=[`flowChanged`];static props={restartAction:{default:`restart`},freezeOnEnd:{default:!0},bannerPath:{default:`%Banner`,nodePath:!0}};restartAction=`restart`;freezeOnEnd=!0;bannerPath=`%Banner`;state=`playing`;frozeScale=!1;gameOver(e=`GAME OVER`,t=`#ef4444`){this.transition(`gameover`,e,t)}win(e=`YOU WIN`,t=`#4ade80`){this.transition(`won`,e,t)}pause(){this.state===`playing`&&(this.state=`paused`,this.freeze(),this.node.emit(`flowChanged`,this.state))}resume(){this.state===`paused`&&(this.state=`playing`,this.thaw(),this.node.emit(`flowChanged`,this.state))}restart(){this.thaw(),v_(this.engine)}goToScene(e,t){this.thaw(),y_(this.engine,e,t)}transition(e,t,n){this.state===`gameover`||this.state===`won`||(this.state=e,this.freezeOnEnd&&this.freeze(),this.bannerPath!==``&&this.node.getNodeOrNull(this.bannerPath)?.show(t,{color:n,seconds:0}),this.node.emit(`flowChanged`,e))}freeze(){this.frozeScale||(this.frozeScale=!0,this.engine.timeScale=0)}thaw(){this.frozeScale&&(this.frozeScale=!1,this.engine.timeScale=1)}update(){if(!(this.state!==`gameover`&&this.state!==`won`))try{this.engine.input.justPressed(this.restartAction)&&this.restart()}catch{}}};function x_(e){return Array.isArray(e.position)}function S_(e,t){let n=0,r=Math.max(e.length,t.length);for(let i=0;i<r;i++){let r=(e[i]??0)-(t[i]??0);n+=r*r}return Math.sqrt(n)}var C_=class extends et{static props={action:{default:`interact`},range:{default:2},actorGroup:{default:`player`}};static signals=[`interacted`];action=`interact`;range=2;actorGroup=`player`;update(){let e=this.node.tree?.engine;if(!e?.scene||!e.input.justPressed(this.action)||!x_(this.node))return;let t=this.node.position,n=null,r=1/0,i=this.node.tree?.getNodesInGroup(this.actorGroup)??w_(this.node.getRoot(),this.actorGroup);for(let e of i){if(!x_(e))continue;let i=S_(t,e.position);i<=this.range&&i<r&&(n=e,r=i)}n&&this.emit(`interacted`,n)}};function w_(e,t){let n=[],r=e=>{e.isInGroup(t)&&n.push(e);for(let t of e.children)r(t)};return r(e),n}var T_=.28,E_=class extends et{static props={falloff:{default:T_}};falloff=T_;magnitude=0;t=0;prev=[];shake(e,t){this.magnitude=Math.max(this.magnitude,e),this.t=t??this.falloff}update(e){let t=t_(this),n=t.position;for(let e=0;e<this.prev.length;e++)n[e]=(n[e]??0)-(this.prev[e]??0);if(this.t<=0){this.prev.length>0&&(t.position=n.slice(),this.prev.length=0);return}this.t-=e;let r=this.magnitude*Math.max(0,this.t)/this.falloff;this.t<=0&&(this.magnitude=0);let i=n.slice();this.prev.length!==i.length&&(this.prev=Array(i.length).fill(0));for(let e=0;e<i.length;e++){let t=i.length>=3&&e===1?.5:1;this.prev[e]=(this.engine.rng.next()*2-1)*r*t,i[e]=(i[e]??0)+this.prev[e]}t.position=i}},D_=class extends et{static props={seconds:{default:1},startOnSignal:{default:!1}};static signals=[`expired`];seconds=1;startOnSignal=!1;elapsed=0;running=!1;fired=!1;onReady(){if(!(this.seconds>0))throw new N(`PROP_TYPE_MISMATCH`,`Lifetime on '${this.node.getPath()}': "seconds" must be > 0, got ${this.seconds}.`,{prop:`seconds`});this.running=!this.startOnSignal}startTimer(){this.elapsed=0,this.fired=!1,this.running=!0}update(e){!this.running||this.fired||(this.elapsed+=e,this.elapsed>=this.seconds&&(this.fired=!0,this.running=!1,this.emit(`expired`),this.node.queueFree()))}},O_=[`linear`,`easeIn`,`easeOut`,`easeInOut`];function k_(e,t){let n=t<0?0:t>1?1:t;switch(e){case`linear`:return n;case`easeIn`:return n*n;case`easeOut`:return 1-(1-n)*(1-n);case`easeInOut`:return n<.5?2*n*n:1-(-2*n+2)**2/2}}var A_=class extends et{static props={to:{default:[]},duration:{default:1},ease:{default:`easeInOut`,options:[...O_]},startOnSignal:{default:!1}};static signals=[`arrived`];to=[];duration=1;ease=`easeInOut`;startOnSignal=!1;from=[];elapsed=0;running=!1;arrivedFired=!1;onReady(){if(!(this.duration>0))throw new N(`PROP_TYPE_MISMATCH`,`MoveTo on '${this.node.getPath()}': "duration" must be > 0, got ${this.duration}.`,{prop:`duration`});if(!O_.includes(this.ease))throw new N(`PROP_TYPE_MISMATCH`,`MoveTo on '${this.node.getPath()}': "ease" must be one of [${O_.join(`, `)}], got '${this.ease}'.`,{prop:`ease`});let e=t_(this);this.from=[...e.position],this.startOnSignal||(this.running=!0)}start(){let e=this.node;this.from=[...e.position],this.elapsed=0,this.arrivedFired=!1,this.running=!0}update(e){if(!this.running)return;let t=this.node;this.elapsed+=e;let n=Math.min(1,this.elapsed/this.duration),r=k_(this.ease,n);t.position=this.from.map((e,t)=>e+((this.to[t]??e)-e)*r),n>=1&&!this.arrivedFired&&(this.arrivedFired=!0,this.running=!1,this.emit(`arrived`))}},j_=[`x`,`y`,`z`],M_=[`position`,`rotation`,`scale`],N_={x:0,y:1,z:2},P_=class extends et{static props={axis:{default:`y`,options:[...j_]},amplitude:{default:1},frequency:{default:1},mode:{default:`position`,options:[...M_]}};static signals=[];axis=`y`;amplitude=1;frequency=1;mode=`position`;base=0;time=0;onReady(){if(!j_.includes(this.axis))throw new N(`PROP_TYPE_MISMATCH`,`Oscillate on '${this.node.getPath()}': "axis" must be one of [${j_.join(`, `)}], got '${this.axis}'.`,{prop:`axis`});if(!M_.includes(this.mode))throw new N(`PROP_TYPE_MISMATCH`,`Oscillate on '${this.node.getPath()}': "mode" must be one of [${M_.join(`, `)}], got '${this.mode}'.`,{prop:`mode`});this.base=this.readChannel()}update(e){this.time+=e;let t=this.amplitude*Math.sin(2*Math.PI*this.frequency*this.time);this.writeChannel(this.base+t)}isScalarRotation(){return this.mode===`rotation`&&typeof this.node.rotation==`number`}readChannel(){if(this.isScalarRotation())return this.node.rotation;let e=this.node[this.mode];if(!Array.isArray(e))throw new N(`PROP_TYPE_MISMATCH`,`Oscillate on '${this.node.getPath()}': node has no '${this.mode}' array to oscillate.`,{prop:`mode`});return e[N_[this.axis]]??0}writeChannel(e){if(this.isScalarRotation()){this.node.rotation=e;return}let t=[...this.node[this.mode]];t[N_[this.axis]]=e,this.node[this.mode]=t}},F_=class extends et{static signals=[`waypointReached`,`arrived`];static props={speed:{default:120},loop:{default:!1}};speed=120;loop=!1;waypoints=[];index=0;get moving(){return this.index<this.waypoints.length}setPath(e){this.waypoints=e.map(e=>[...e]),this.index=0}stop(){this.waypoints=[],this.index=0}update(e){if(!this.moving)return;let t=t_(this),n=this.speed*e;for(;n>0&&this.index<this.waypoints.length;){let e=this.waypoints[this.index],r=o_(t.position,e,n),i=I_(t.position,r.position);if(t.position=r.position,n-=i,r.reached){if(this.node.emit(`waypointReached`,this.index),this.index+=1,this.index>=this.waypoints.length)if(this.loop&&this.waypoints.length>1)this.index=0;else{this.node.emit(`arrived`);return}}else return}}};function I_(e,t){let n=0,r=Math.max(e.length,t.length);for(let i=0;i<r;i++){let r=(t[i]??0)-(e[i]??0);n+=r*r}return Math.sqrt(n)}var L_=class extends et{static props={points:{default:[]},speed:{default:60},loop:{default:!0},mode:{default:`loop`,options:[`loop`,`pingpong`]},pauseAt:{default:0}};static signals=[`reachedPoint`];points=[];speed=60;loop=!0;mode=`loop`;pauseAt=0;index=0;direction=1;pauseTimer=0;onReady(){if(!Array.isArray(this.points)||this.points.length===0)throw new N(`PROP_TYPE_MISMATCH`,`Patrol on '${this.node.getPath()}': "points" must be a non-empty array of position arrays or node paths.`,{prop:`points`});if(this.mode!==`loop`&&this.mode!==`pingpong`)throw new N(`PROP_TYPE_MISMATCH`,`Patrol on '${this.node.getPath()}': "mode" must be 'loop' or 'pingpong', got '${this.mode}'.`,{prop:`mode`});t_(this)}update(e){if(this.pauseTimer>0){this.pauseTimer=Math.max(0,this.pauseTimer-e);return}let t=this.node,n=this.pointAt(this.index);if(!n)return;let{position:r,reached:i}=o_(t.position,n,this.speed*e);t.position=r,i&&(this.emit(`reachedPoint`,this.index),this.advance(),this.pauseAt>0&&(this.pauseTimer=this.pauseAt))}pointAt(e){let t=this.points[e];if(Array.isArray(t))return t;if(typeof t==`string`){let e=this.node.getNodeOrNull(t);return Array.isArray(e?.position)?e.position:null}return null}advance(){let e=this.points.length-1;if(this.mode===`pingpong`){this.index>=e?this.direction=-1:this.index<=0&&(this.direction=1),this.index=Math.min(e,Math.max(0,this.index+this.direction));return}this.index<e?this.index+=1:this.loop&&(this.index=0)}},R_=class extends et{static props={value:{default:1},kind:{default:`coin`},collectorGroup:{default:`player`}};static signals=[`collected`];value=1;kind=`coin`;collectorGroup=`player`;collectedAlready=!1;onReady(){f_(this,e=>this.tryCollect(e))}tryCollect(e){this.collectedAlready||e.isInGroup(this.collectorGroup)&&(this.collectedAlready=!0,this.emit(`collected`,this.value,e),this.node.queueFree())}},z_=class extends et{static props={speed:{default:300},direction:{default:null},gravity:{default:0}};static signals=[];speed=300;direction=null;gravity=0;velocity=[];onReady(){if(this.speed===0&&this.gravity===0)throw new N(`PROP_TYPE_MISMATCH`,`Projectile on '${this.node.getPath()}': a projectile with "speed" 0 and "gravity" 0 never moves — set one of them.`,{prop:`speed`});let e=t_(this),t=this.resolveDirection();for(this.velocity=t.map(e=>e*this.speed);this.velocity.length<e.position.length;)this.velocity.push(0)}update(e){let t=this.node;this.gravity!==0&&(this.velocity[1]=(this.velocity[1]??0)+this.gravity*e);let n=t.position,r=Math.max(n.length,this.velocity.length),i=Array(r);for(let t=0;t<r;t++)i[t]=(n[t]??0)+(this.velocity[t]??0)*e;t.position=i}resolveDirection(){if(Array.isArray(this.direction))return a_(this.direction);if(this.direction===null||this.direction===`forward`)return this.forwardFromRotation();throw new N(`PROP_TYPE_MISMATCH`,`Projectile on '${this.node.getPath()}': "direction" must be a vector or 'forward', got ${JSON.stringify(this.direction)}.`,{prop:`direction`})}forwardFromRotation(){let e=this.node.rotation;if(typeof e==`number`){let t=e*Math.PI/180;return[Math.cos(t),Math.sin(t)]}if(Array.isArray(e)){let t=(e[1]??0)*Math.PI/180,n=(e[0]??0)*Math.PI/180;return a_([-Math.sin(t)*Math.cos(n),Math.sin(n),-Math.cos(t)*Math.cos(n)])}return[1,0]}},B_=class extends et{static props={score:{default:0},lives:{default:0},scoreToWin:{default:0}};static signals=[`scoreChanged`,`won`,`lost`,`lifeLost`];score=0;lives=0;scoreToWin=0;hasWon=!1;hasLost=!1;onReady(){if(this.lives<0)throw new N(`PROP_TYPE_MISMATCH`,`ScoreKeeper on '${this.node.getPath()}': "lives" must be >= 0, got ${this.lives}.`,{prop:`lives`});if(this.scoreToWin<0)throw new N(`PROP_TYPE_MISMATCH`,`ScoreKeeper on '${this.node.getPath()}': "scoreToWin" must be >= 0, got ${this.scoreToWin}.`,{prop:`scoreToWin`})}addScore(e){this.setScore(this.score+e)}setScore(e){this.score=e,this.emit(`scoreChanged`,this.score),this.scoreToWin>0&&!this.hasWon&&this.score>=this.scoreToWin&&(this.hasWon=!0,this.emit(`won`))}loseLife(){this.lives<=0||this.hasLost||(--this.lives,this.emit(`lifeLost`,this.lives),this.lives<=0&&(this.hasLost=!0,this.emit(`lost`)))}serialize(){return{score:this.score,lives:this.lives,hasWon:this.hasWon,hasLost:this.hasLost}}deserialize(e){let t=e;typeof t.score==`number`&&(this.score=t.score),typeof t.lives==`number`&&(this.lives=t.lives),typeof t.hasWon==`boolean`&&(this.hasWon=t.hasWon),typeof t.hasLost==`boolean`&&(this.hasLost=t.hasLost)}},V_=class{behavior;detached=new Map;constructor(e){this.behavior=e}resolveTemplate(e){let t=this.detached.get(e);if(t)return t;let n=this.behavior.node,r=e===``?null:n.getNodeOrNull(e);if(!r){let t=this.behavior.constructor.name;throw new N(`NODE_NOT_FOUND`,`${t} on '${n.getPath()}': "prefab" '${e}' does not resolve to a template node. Point it at a (usually hidden) child node to clone.`,{prop:`prefab`,path:n.getPath()})}return r.parent&&r.parent.removeChild(r),this.detached.set(e,r),r}spawn(e,t){let n=Wn(e),r=t?.at;return r&&r.length>0&&e_(n)&&(n.position=r_(e_(this.behavior.node)?this.behavior.node.position:[],r)),typeof n.visible==`boolean`&&(n.visible=!0),(t?.parent??this.behavior.node).addChild(n),n}},H_={CameraShake:E_,DayNight:h_,GameFlow:b_,PathFollow:F_,Health:d_,Lifetime:D_,ScoreKeeper:B_,Pickup:R_,Collector:u_,DamageOnContact:p_,Interactable:C_,Clickable:l_,FollowCamera:__,Patrol:L_,Chase:c_,Wander:class extends et{static props={speed:{default:40},radius:{default:50},changeEvery:{default:2}};static signals=[];speed=40;radius=50;changeEvery=2;origin=[];goal=[];timer=0;onReady(){if(!(this.radius>0))throw new N(`PROP_TYPE_MISMATCH`,`Wander on '${this.node.getPath()}': "radius" must be > 0, got ${this.radius}.`,{prop:`radius`});let e=t_(this);this.origin=[...e.position],this.goal=[...e.position],this.pickGoal()}update(e){let t=this.node;this.timer-=e;let{position:n,reached:r}=o_(t.position,this.goal,this.speed*e);t.position=n,(r||this.timer<=0)&&this.pickGoal()}pickGoal(){this.timer=this.changeEvery;let e=this.origin.length,t=Array(e);for(let n=0;n<8;n++){for(let n=0;n<e;n++)t[n]=(this.origin[n]??0)+this.rng.range(-this.radius,this.radius);if(n_(t,this.origin)<=this.radius){this.goal=t;return}}this.goal=t.map((e,n)=>{let r=this.origin[n]??0,i=n_(t,this.origin)||1;return r+(e-r)/i*this.radius})}},ZombieAI:class extends et{static props={aggroTarget:{default:``,nodePath:!0},aggroRange:{default:12},deAggroRange:{default:0},chaseSpeed:{default:4},wanderSpeed:{default:1.4},wanderRadius:{default:8},wanderChangeEvery:{default:3},goalTarget:{default:``,nodePath:!0},stopRange:{default:1.2},moveParent:{default:!1}};static signals=[`enteredAggro`,`exitedAggro`,`movementStateChanged`];aggroTarget=``;aggroRange=12;deAggroRange=0;chaseSpeed=4;wanderSpeed=1.4;wanderRadius=8;wanderChangeEvery=3;goalTarget=``;stopRange=1.2;moveParent=!1;aggro=!1;started=!1;home=[];goal=[];timer=0;lastState=``;mover(){let e=this.moveParent?this.node.parent:this.node;return e&&e_(e)?e:null}effectiveDeAggro(){return this.deAggroRange>0?this.deAggroRange:this.aggroRange*1.5}onReady(){if(this.moveParent){let e=this.node.parent;if(!e||!e_(e))throw new N(`PROP_TYPE_MISMATCH`,`ZombieAI on '${this.node.getPath()}': "moveParent" needs a spatial parent (a Node2D/Node3D) to move. '${this.node.name}' has none.`,{prop:`moveParent`,path:this.node.getPath()})}else t_(this)}update(e){let t=this.mover();if(!t)return;this.started||(this.started=!0,this.home=[...t.position],this.pickGoal());let n=this.aggroTarget?this.node.getNodeOrNull(this.aggroTarget):null,r=n&&e_(n)?n.position:null,i=r?this.groundDistance(t.position,r):1/0;if(!this.aggro&&i<=this.aggroRange?(this.aggro=!0,this.emit(`enteredAggro`)):this.aggro&&i>=this.effectiveDeAggro()&&(this.aggro=!1,this.emit(`exitedAggro`),this.pickGoal()),this.aggro&&r){let n=this.approach(t,r,this.chaseSpeed,e);this.setState(n?`idle`:`run`);return}this.timer-=e;let a=this.approach(t,this.goal,this.wanderSpeed,e);this.setState(a?`idle`:`walk`),(a||this.timer<=0)&&this.pickGoal()}approach(e,t,n,r){let i=e.position;if(this.groundDistance(i,t)<=this.stopRange)return!0;let a=i.length>=3?1:-1,o=[...t];a>=0&&(o[a]=i[a]??0);let s=this.groundDistance(i,o),{position:c}=o_(i,o,Math.min(n*r,Math.max(0,s-this.stopRange)));return e.position=c,!1}groundDistance(e,t){if(e.length>=3){let n=(e[0]??0)-(t[0]??0),r=(e[2]??0)-(t[2]??0);return Math.hypot(n,r)}return n_(e,t)}setState(e){e!==this.lastState&&(this.lastState=e,this.emit(`movementStateChanged`,e))}pickGoal(){this.timer=this.wanderChangeEvery;let e=this.mover(),t=e?e.position:this.home,n=t.length>=3?1:-1,r=this.home,i=this.goalTarget?this.node.getNodeOrNull(this.goalTarget):null;if(i&&e_(i)){let e=i.position;r=t.map((t,n)=>t+((e[n]??0)-t)*.4)}let a=[...r];for(let e=0;e<a.length;e++)e!==n&&(a[e]=(r[e]??0)+this.rng.range(-this.wanderRadius,this.wanderRadius));n>=0&&(a[n]=t[n]??0),this.goal=a}},MoveTo:A_,Oscillate:P_,Spawner:class extends et{static props={prefab:{default:``,nodePath:!0},interval:{default:1},max:{default:0},at:{default:[]},autoStart:{default:!0},total:{default:0}};static signals=[`spawned`,`finished`];prefab=``;interval=1;max=0;at=[];autoStart=!0;total=0;source=new V_(this);template;live=new Set;timer=0;running=!1;spawnedCount=0;done=!1;get liveCount(){return this.prune(),this.live.size}_templateForTest(){return this.template}onReady(){this.template=this.source.resolveTemplate(this.prefab),this.running=this.autoStart,this.timer=this.interval}start(){this.done||(this.running=!0)}stop(){this.running=!1}spawn(){if(this.prune(),this.done||this.max>0&&this.live.size>=this.max)return null;let e=this.source.spawn(this.template,this.at.length>0?{at:this.at}:void 0);return this.live.add(e),this.spawnedCount+=1,this.emit(`spawned`,e),this.total>0&&this.spawnedCount>=this.total&&(this.done=!0,this.running=!1,this.emit(`finished`)),e}update(e){this.running&&(this.timer-=e,!(this.timer>0)&&(this.timer+=this.interval,this.spawn()))}prune(){for(let e of this.live)e.parent===null&&this.live.delete(e)}},WaveSpawner:class extends et{static props={waves:{default:[]},autoStart:{default:!0}};static signals=[`waveStarted`,`waveCleared`,`allCleared`];waves=[];autoStart=!0;source=new V_(this);parsed=[];live=new Set;waveIndex=-1;phase=`idle`;timer=0;spawnedThisWave=0;announced=!1;onReady(){if(!Array.isArray(this.waves)||this.waves.length===0)throw new N(`PROP_TYPE_MISMATCH`,`WaveSpawner on '${this.node.getPath()}': "waves" must be a non-empty array of { prefab, count, interval, delayBefore }.`,{prop:`waves`});this.parsed=this.waves.map((e,t)=>this.parseWave(e,t));for(let e of this.parsed)this.source.resolveTemplate(e.prefab);this.autoStart&&this.beginWave(0)}start(){this.beginWave(0)}update(e){if(this.phase===`idle`||this.phase===`done`)return;let t=this.parsed[this.waveIndex];if(t){if(this.announced||(this.announced=!0,this.emit(`waveStarted`,this.waveIndex)),this.phase===`delay`){this.timer-=e,this.timer<=0&&(this.phase=`spawning`,this.timer=0);return}if(this.phase===`spawning`){for(this.timer-=e;this.timer<=0&&this.spawnedThisWave<t.count;){let e=this.source.spawn(this.source.resolveTemplate(t.prefab));this.live.add(e),this.spawnedThisWave+=1,this.timer+=t.interval}this.spawnedThisWave>=t.count&&(this.phase=`clearing`);return}if(this.phase===`clearing`&&(this.prune(),this.live.size===0)){this.emit(`waveCleared`,this.waveIndex);let e=this.waveIndex+1;e<this.parsed.length?this.beginWave(e):(this.phase=`done`,this.emit(`allCleared`))}}}beginWave(e){this.waveIndex=e,this.spawnedThisWave=0,this.announced=!1,this.live.clear();let t=this.parsed[e];t&&(t.delayBefore>0?(this.phase=`delay`,this.timer=t.delayBefore):(this.phase=`spawning`,this.timer=0))}prune(){for(let e of this.live)e.parent===null&&this.live.delete(e)}parseWave(e,t){let n=e,r=typeof n?.prefab==`string`?n.prefab:``;if(r===``)throw new N(`PROP_TYPE_MISMATCH`,`WaveSpawner on '${this.node.getPath()}': wave ${t} needs a "prefab" template path.`,{prop:`waves`});return{prefab:r,count:typeof n?.count==`number`?n.count:1,interval:typeof n?.interval==`number`?n.interval:.5,delayBefore:typeof n?.delayBefore==`number`?n.delayBefore:0}}},Projectile:z_,Buoyancy:Qg};function U_(e){let t=e?.replace??!0;for(let[e,n]of Object.entries(H_))it(e,n,{replace:t})}function W_(e,t){let n=e.shape;if(n!==void 0){if(e.oneWay!==void 0&&typeof e.oneWay!=`boolean`)throw new N(`BAD_FORMAT`,`Collider on '${t}': "oneWay" must be a boolean (platforms you jump up through), got ${JSON.stringify(e.oneWay)}.`);if(n===`rect`){let n=e.size;if(!Array.isArray(n)||n.length!==2||n.some(e=>typeof e!=`number`))throw new N(`BAD_FORMAT`,`Collider on '${t}': rect needs "size": [width, height].`);return}if(n===`circle`){if(typeof e.radius!=`number`)throw new N(`BAD_FORMAT`,`Collider on '${t}': circle needs "radius".`);return}if(n===`capsule`){if(typeof e.radius!=`number`||typeof e.height!=`number`)throw new N(`BAD_FORMAT`,`Collider on '${t}': capsule needs "radius" and "height".`);return}throw new N(`BAD_FORMAT`,`Collider on '${t}': "shape" must be 'rect', 'circle', or 'capsule', got ${JSON.stringify(n)}.`)}}var G_=class extends Nt{static typeName=`Node2D`;static props={position:{default:[0,0]},rotation:{default:0},static:{default:!1},scale:{default:[1,1]},renderOrder:{default:0},orderGroup:{default:`default`,options:[`background`,`terrain`,`default`,`characters`,`effects`,`overlay`]},visible:{default:!0}};static propAliases={zIndex:`renderOrder`};position=[0,0];rotation=0;static=!1;scale=[1,1];renderOrder=0;orderGroup=`default`;get effectiveRenderOrder(){return _t(this.orderGroup,this.renderOrder,this.tree?.engine?.orderGroups)}visible=!0;_object2D=null;_ensureObject2D(){return this._object2D||(this._object2D=this._createObject2D(),this._object2D.userData.incantoNode=this),this._object2D}_createObject2D(){return new go}_syncObject2D(e){let t=this._ensureObject2D();t.position.set(this.position[0]??0,-(this.position[1]??0),0),t.rotation.z=-ba.degToRad(this.rotation),t.scale.set(this.scale[0]??1,this.scale[1]??1,1),t.visible=this.visible}free(){super.free(),this._object2D?.removeFromParent(),this._object2D=null}},K_=class extends G_{static props={collider:{default:{},variants:{tag:`shape`,byTag:{rect:{shape:`rect`,size:[32,32]},circle:{shape:`circle`,radius:16},capsule:{shape:`capsule`,radius:12,height:32}}}}};static signals=[`triggerEnter`,`triggerExit`];_collider={};_colliderChanged=!1;get collider(){return this._collider}set collider(e){this._collider=e,this._colliderChanged=!0}static validateJson(e){W_(e.collider,e.name)}_physics=null},q_=class extends K_{static typeName=`StaticBody2D`},J_=class extends K_{static typeName=`Area2D`},Y_=class extends K_{static typeName=`RigidBody2D`;static props={mass:{default:1},gravityScale:{default:1},fixedRotation:{default:!1},friction:{default:.5},restitution:{default:0},linearVelocity:{default:[0,0]}};mass=1;gravityScale=1;fixedRotation=!1;friction=.5;restitution=0;linearVelocity=[0,0]},X_=class extends K_{static typeName=`CharacterBody2D`;static props={velocity:{default:[0,0]},snapToGround:{default:!0},slopeLimitDeg:{default:45}};velocity=[0,0];snapToGround=!0;slopeLimitDeg=45;_grounded=!1;moveAndSlide(){if(!this._physics)throw new N(`TREE_VIOLATION`,this.collider.shape===void 0?`CharacterBody2D '${this.name}' has no collider — set a collider prop (physics skips collider-less bodies).`:`CharacterBody2D '${this.name}' has no physics world — await enablePhysics2D(engine) first.`);this._physics.moveAndSlide(this)}_onWall=0;_onCeiling=!1;isOnWall(){return this._onWall!==0}wallSide(){return this._onWall}isOnCeiling(){return this._onCeiling}isOnFloor(){return this._grounded}},Z_=new Set;function Q_(e){return Z_.add(e),()=>Z_.delete(e)}function $_(e,t){return[...Z_].filter(n=>n.dimension===e&&(t===void 0||n.engine===t))}var ev=class extends G_{static typeName=`Joint2D`;static props={type:{default:`revolute`,options:[`fixed`,`revolute`,`rope`,`spring`]},target:{default:``,nodePath:!0},anchor:{default:[0,0]},targetAnchor:{default:[0,0]},length:{default:0},stiffness:{default:50},damping:{default:5}};type=`revolute`;target=``;anchor=[0,0];targetAnchor=[0,0];length=0;stiffness=50;damping=5;onEnterTree(){if(!(this.parent instanceof K_))throw new N(`TREE_VIOLATION`,`Joint2D '${this.name}' must be a child of a physics body (its body A); parent is '${this.parent?.name??`none`}'.`);if(this.target===``)throw new N(`BAD_FORMAT`,`Joint2D '${this.name}' needs a "target" node path to the body it links to.`)}_resolveBodies(){let e=this.parent,t=this.getNodeOrNull(this.target);if(!(t instanceof K_))throw new N(`NODE_NOT_FOUND`,`Joint2D '${this.name}': target '${this.target}' is not a physics body.`);return{a:e,b:t}}},Z=100,tv=Math.PI/180;async function nv(e,t){let n=await bm(()=>import(`./rapier-CEuLKeCu.js`),[],import.meta.url);return await n.init({}),new rv(n,e,t)}var rv=class{R;engine;debugDraw=!1;debugScope=null;dimension=`2d`;unregisterDebug;warnedNoCollider=new WeakSet;entries=new Map;byColliderHandle=new Map;world;events;kcc;disconnect;lastDt=1/60;optsGravity;lastScene=null;constructor(e,t,n){this.R=e,this.engine=t,this.optsGravity=n?.gravity,this.simulate=n?.simulate??!0,this.lastScene=t.scene;let r=t.scene?.physics?.gravity,i=n?.gravity??r??[0,980];this.world=new e.World({x:(i[0]??0)/Z,y:(i[1]??0)/Z}),this.kcc=this.world.createCharacterController(.01),this.kcc.setUp({x:0,y:-1}),this.events=new e.EventQueue(!0),this.unregisterDebug=Q_(this),this.disconnect=t.fixedUpdated.connect(e=>this.step(e)),this.syncBodies()}simulate;step(e){if(this.lastDt=e,!this.simulate){this.syncBodies(),this.poseFromTree();return}if(this.engine.scene!==this.lastScene&&(this.lastScene=this.engine.scene,!this.optsGravity)){let e=this.engine.scene?.physics?.gravity??[0,980];this.world.gravity={x:(e[0]??0)/Z,y:(e[1]??0)/Z}}this.syncBodies(),this.world.timestep=e,this.world.step(this.events);for(let[e,t]of this.entries){let n=t.body.translation();if(!t.body.isFixed()){let[t,r]=uv(e);e.position=[n.x*Z-t,n.y*Z-r]}if(e instanceof Y_){e.fixedRotation||(e.rotation=t.body.rotation()/tv);let n=t.body.linvel();e.linearVelocity=[n.x*Z,n.y*Z],t.lastVX=e.linearVelocity[0]??0,t.lastVY=e.linearVelocity[1]??0}let[r,i]=lv(e);t.lastX=r,t.lastY=i}this.events.drainCollisionEvents((e,t,n)=>{let r=this.byColliderHandle.get(e),i=this.byColliderHandle.get(t);if(!r||!i)return;let a=n?`triggerEnter`:`triggerExit`;try{r.emit(a,i),i.emit(a,r)}catch(e){lt(this.engine,`error`,`incanto: error in a '${a}' handler (${r.name} ↔ ${i.name}):`,e)}})}moveAndSlide(e){let t=this.ensureEntry(e),n=e.velocity[1]??0;e.snapToGround&&n>=0?this.kcc.enableSnapToGround(.05):this.kcc.disableSnapToGround(),this.kcc.setMaxSlopeClimbAngle(e.slopeLimitDeg*tv);let r=0,i=0;if(t.ground&&t.ground._physics===this){let[e,n]=lv(t.ground);r=e-(t.groundX??e),i=n-(t.groundY??n)}else t.ground=null;let a={x:((e.velocity[0]??0)*this.lastDt+r)/Z*1,y:(n*this.lastDt+i)/Z*1},o=t.body.translation().y*Z+sv(e);this.kcc.computeColliderMovement(t.collider,a,this.R.QueryFilterFlags.EXCLUDE_SENSORS,void 0,t=>{let r=this.byColliderHandle.get(t.handle);return!(r&&r!==e&&r.collider.oneWay===!0&&(n<0||o>cv(r)+ov))});let s=this.kcc.computedMovement(),c=t.body.translation();t.body.setNextKinematicTranslation({x:c.x+s.x,y:c.y+s.y}),e._grounded=this.kcc.computedGrounded(),e._onWall=0,e._onCeiling=!1;let l=this.kcc.numComputedCollisions();for(let t=0;t<l;t++){let n=this.kcc.computedCollision(t)?.normal1;n&&(Math.abs(n.y)>.7?e._grounded||(e._onCeiling=!0):Math.abs(n.x)>.7&&(e._onWall=n.x>0?-1:1))}if(e._grounded){let n=(c.x+s.x)*Z,r=(c.y+s.y)*Z+sv(e)-2,i=this.castRay([n,r],[0,1],8,e);if(i?.node&&!(i.node instanceof X_)){t.ground=i.node;let[e,n]=lv(i.node);t.groundX=e,t.groundY=n}else t.ground=null}else t.ground=null}debugLines(){if(!this.debugDraw)return null;let e=this.debugScope?this.scopedLines(this.debugScope):this.world.debugRender().vertices,t=new Float32Array(e.length);for(let n=0;n<e.length;n++)t[n]=e[n]*Z;return t}scopedLines(e){let t=[],n=[],r=e=>{let t=this.entries.get(e);t&&n.push(t.body);for(let t of e.children)r(t)};r(e);for(let t=e.parent;t&&n.length===0;t=t.parent){let e=this.entries.get(t);e&&n.push(e.body)}for(let e of n)for(let n=0;n<e.numColliders();n++){let r=e.collider(n);if(!r)continue;let i=r.translation(),a=r.rotation(),o=Math.cos(a),s=Math.sin(a),c=(e,n)=>{t.push(i.x+e*o-n*s,i.y+e*s+n*o)},l=(e,t,n,r)=>{c(e,t),c(n,r)},u=r.shape;if(u.halfExtents){let{x:e,y:t}=u.halfExtents;l(-e,-t,e,-t),l(e,-t,e,t),l(e,t,-e,t),l(-e,t,-e,-t)}else if(u.radius!==void 0){let e=u.radius,t=u.halfHeight??0;for(let n=0;n<24;n++){let r=n/24*Math.PI*2,i=(n+1)/24*Math.PI*2,a=e=>e>=0?t:-t;l(Math.cos(r)*e,Math.sin(r)*e+a(Math.sin(r)),Math.cos(i)*e,Math.sin(i)*e+a(Math.sin(i)))}t>0&&(l(-e,-t,-e,t),l(e,-t,e,t))}}return new Float32Array(t)}syncJoints(e){let t=this.R;if(e)for(let[e,t]of this.joints)this.jointSet.has(e)||(this.world.removeImpulseJoint(t,!0),this.joints.delete(e));for(let e of this.jointSet){if(this.joints.has(e))continue;let{a:n,b:r}=e._resolveBodies(),i=this.entries.get(n),a=this.entries.get(r);if(!i||!a)continue;let o={x:(e.anchor[0]??0)/Z,y:(e.anchor[1]??0)/Z},s={x:(e.targetAnchor[0]??0)/Z,y:(e.targetAnchor[1]??0)/Z},c=e.length/Z;if(e.length===0&&(e.type===`rope`||e.type===`spring`)){let e=i.body.translation(),t=a.body.translation();c=Math.hypot(t.x-e.x,t.y-e.y)}let l;l=e.type===`fixed`?t.JointData.fixed(o,0,s,0):e.type===`rope`?t.JointData.rope(c,o,s):e.type===`spring`?t.JointData.spring(c,e.stiffness,e.damping,o,s):t.JointData.revolute(o,s),this.joints.set(e,this.world.createImpulseJoint(l,i.body,a.body,!0))}}castRay(e,t,n,r,i){let a=Math.hypot(t[0],t[1])||1,o=new this.R.Ray({x:e[0]/Z,y:e[1]/Z},{x:t[0]/a,y:t[1]/a}),s=r?this.entries.get(r)?.collider:void 0,c=i?.staticOnly?this.R.QueryFilterFlags.EXCLUDE_DYNAMIC|this.R.QueryFilterFlags.EXCLUDE_KINEMATIC:void 0,l=this.world.castRayAndGetNormal(o,n/Z,!0,c,void 0,s,void 0,e=>!e.isSensor());return l?{distance:l.timeOfImpact*Z,normal:[l.normal.x,l.normal.y],node:this.byColliderHandle.get(l.collider.handle)??null}:null}dispose(){this.disconnect(),this.unregisterDebug(),this.world.free()}lastStructure=-1;lastRoot=null;jointSet=new Set;joints=new Map;bodySet=new Set;poseFromTree(){for(let[e,t]of this.entries){let[n,r]=lv(e);t.body.setTranslation({x:n/Z,y:r/Z},!1),t.body.setRotation(e.rotation*tv,!1)}this.world.propagateModifiedBodyPositionsToColliders()}syncBodies(){let e=this.engine.scene;if(!e)return;let t=e.tree._structureVersion,n=e.root===this.lastRoot,r=t!==this.lastStructure||!n;if(r){let r=n?e.tree._structureSince(this.lastStructure):null;if(this.lastStructure=t,this.lastRoot=e.root,r){let t=!1;for(let{node:e,added:n}of r)e instanceof K_&&(n?this.bodySet.add(e):this.bodySet.delete(e)),e instanceof ev&&(t=!0);t&&(this.jointSet.clear(),iv(e.root,this.jointSet))}else this.bodySet.clear(),av(e.root,this.bodySet),this.jointSet.clear(),iv(e.root,this.jointSet)}let i=this.bodySet;for(let e of i){if(e.collider.shape===void 0){let t=this.entries.get(e);t&&(this.byColliderHandle.delete(t.collider.handle),this.world.removeRigidBody(t.body),this.entries.delete(e),e._physics=null),this.warnedNoCollider.has(e)||(this.warnedNoCollider.add(e),lt(this.engine,`warn`,`[incanto] '${e.name}' has no collider — physics skips it.`));continue}let t=this.entries.get(e);t&&e._colliderChanged&&(this.byColliderHandle.delete(t.collider.handle),this.world.removeRigidBody(t.body),this.entries.delete(e),e._physics=null),this.ensureEntry(e)}if(this.syncJoints(r),r)for(let[e,t]of this.entries)i.has(e)||(this.byColliderHandle.delete(t.collider.handle),this.world.removeRigidBody(t.body),this.entries.delete(e),e._physics=null)}ensureEntry(e){let t=this.entries.get(e),n=this.R;if(!t){let[r,i]=lv(e),a=r/Z,o=i/Z,s;s=e instanceof Y_?n.RigidBodyDesc.dynamic():e instanceof X_||e instanceof J_?n.RigidBodyDesc.kinematicPositionBased():n.RigidBodyDesc.fixed(),s.setTranslation(a,o).setRotation(e.rotation*tv),e instanceof Y_&&(s.setGravityScale(e.gravityScale),s.setLinvel((e.linearVelocity[0]??0)/Z,(e.linearVelocity[1]??0)/Z),e.fixedRotation&&s.lockRotations());let c=this.world.createRigidBody(s),l=dv(n,e.collider,e.name);l.setActiveEvents(n.ActiveEvents.COLLISION_EVENTS),l.setActiveCollisionTypes(n.ActiveCollisionTypes.ALL),e instanceof J_&&l.setSensor(!0),e instanceof Y_&&l.setMass(e.mass).setFriction(e.friction).setRestitution(e.restitution);let u=this.world.createCollider(l,c);return t={body:c,collider:u,lastX:r,lastY:i,lastVX:0,lastVY:0},this.entries.set(e,t),this.byColliderHandle.set(u.handle,e),e._colliderChanged=!1,e._physics=this,t}let[r,i]=lv(e);if((r!==t.lastX||i!==t.lastY)&&(t.body.setTranslation({x:r/Z,y:i/Z},!0),t.lastX=r,t.lastY=i),e instanceof Y_){let n=e.linearVelocity[0]??0,r=e.linearVelocity[1]??0;(n!==t.lastVX||r!==t.lastVY)&&(t.body.setLinvel({x:n/Z,y:r/Z},!0),t.lastVX=n,t.lastVY=r)}return t}};function iv(e,t){e instanceof ev&&t.add(e);for(let n of e.children)iv(n,t)}function av(e,t){e instanceof K_&&t.add(e);for(let n of e.children)av(n,t)}var ov=4;function sv(e){let t=e.collider;return t.shape===`rect`?(t.size?.[1]??32)/2:t.shape===`capsule`?(t.height??32)/2+(t.radius??8):t.radius??16}function cv(e){let[,t]=lv(e),n=e.collider;return t-(n.shape===`rect`?(n.size?.[1]??32)/2:n.shape===`capsule`?(n.height??32)/2+(n.radius??8):n.radius??16)}function lv(e){let t=0,n=0;for(let r=e;r;r=r.parent)r instanceof G_&&(t+=r.position[0]??0,n+=r.position[1]??0);return[t,n]}function uv(e){let t=0,n=0;for(let r=e.parent;r;r=r.parent)r instanceof G_&&(t+=r.position[0]??0,n+=r.position[1]??0);return[t,n]}function dv(e,t,n){W_(t,n);let r=fv(e,t,n),i=t.offset;return Array.isArray(i)&&r.setTranslation((i[0]??0)/Z,(i[1]??0)/Z),r}function fv(e,t,n){let r=t.shape;if(r===`rect`){let r=t.size;if(!Array.isArray(r)||r.length!==2||r.some(e=>typeof e!=`number`))throw new N(`BAD_FORMAT`,`Collider on '${n}': rect needs "size": [width, height].`);return e.ColliderDesc.cuboid(r[0]/2/Z,r[1]/2/Z)}if(r===`circle`){if(typeof t.radius!=`number`)throw new N(`BAD_FORMAT`,`Collider on '${n}': circle needs "radius".`);return e.ColliderDesc.ball(t.radius/Z)}if(r===`capsule`){if(typeof t.radius!=`number`||typeof t.height!=`number`)throw new N(`BAD_FORMAT`,`Collider on '${n}': capsule needs "radius" and "height".`);return e.ColliderDesc.capsule(t.height/2/Z,t.radius/Z)}throw new N(`BAD_FORMAT`,`Collider on '${n}': "shape" must be 'rect', 'circle', or 'capsule', got ${JSON.stringify(r)}.`)}var pv=new cl(1,1),mv=class extends G_{static typeName=`Sprite2D`;static props={texture:{default:``},anchor:{default:[.5,.5]},flipX:{default:!1},flipY:{default:!1},tint:{default:`#ffffff`},opacity:{default:1}};texture=``;anchor=[.5,.5];flipX=!1;flipY=!1;tint=`#ffffff`;opacity=1;quadMesh=null;_quad(){return this.quadMesh||(this.quadMesh=new Ys(pv,new Ls({transparent:!0,depthWrite:!1})),this._ensureObject2D().add(this.quadMesh)),this.quadMesh}_createObject2D(){return super._createObject2D()}resolveTexture(e){if(!this.texture||!e)return null;let t=e.getTexture(this.texture),n=t.image;return!n?.width||!n.height?null:{texture:t,width:n.width,height:n.height}}_syncObject2D(e){super._syncObject2D(e);let t=this._quad(),n=t.material,r=this.resolveTexture(e);if(!r){t.visible=!1;return}t.visible=!0,n.map!==r.texture&&(n.map=r.texture,n.needsUpdate=!0);let i=r.width,a=r.height;t.scale.set(this.flipX?-i:i,this.flipY?-a:a,1);let o=this.anchor[0]??.5,s=this.anchor[1]??.5;t.position.set((.5-o)*i,(s-.5)*a,0),t.renderOrder=this.effectiveRenderOrder,n.color.set(this.tint),n.opacity=this.opacity}},hv=class extends mv{static typeName=`AnimatedSprite2D`;static signals=[`animationFinished`];static props={sheet:{default:``},animations:{default:{}},autoplay:{default:``}};sheet=``;animations={};autoplay=``;playing=!1;currentFrame=0;currentAnimation=``;frameList=[];frameIndex=0;frameTime=0;ownTexture=null;loadedSheetRef=``;play(e){let t=this.animations[e];if(!t)throw new N(`UNKNOWN_ANIMATION`,`No animation '${e}' on '${this.name}'. Available: [${Object.keys(this.animations).join(`, `)}].`);this.currentAnimation=e,this.frameList=gv(t.frames,e),this.frameIndex=0,this.currentFrame=this.frameList[0]??0,this.frameTime=0,this.playing=!0}stop(){this.playing=!1}onReady(){this.autoplay&&this.play(this.autoplay)}update(e){if(!this.playing||this.currentAnimation===``)return;let t=this.animations[this.currentAnimation];if(!t||!Number.isFinite(t.fps)||t.fps<=0)return;let n=1/t.fps;for(this.frameTime+=e;this.frameTime>=n;)if(this.frameTime-=n,this.frameIndex+=1,this.frameIndex>=this.frameList.length)if(t.loop)this.frameIndex=0;else{this.frameIndex=this.frameList.length-1,this.playing=!1,this.emit(`animationFinished`,this.currentAnimation);break}this.currentFrame=this.frameList[this.frameIndex]??0}resolveTexture(e){if(!this.sheet||!e)return null;let t=e.getSheet(this.sheet);this.loadedSheetRef!==this.sheet&&(this.ownTexture=t.texture.clone(),this.ownTexture.needsUpdate=!0,this.loadedSheetRef=this.sheet);let n=this.ownTexture,r=t.texture.image;if(!r?.width||!r.height)return null;let i=Math.max(1,Math.floor(r.width/t.frameWidth)),a=this.currentFrame%i,o=Math.floor(this.currentFrame/i);return n.repeat.set(t.frameWidth/r.width,t.frameHeight/r.height),n.offset.set(a*t.frameWidth/r.width,1-(o+1)*t.frameHeight/r.height),{texture:n,width:t.frameWidth,height:t.frameHeight}}};function gv(e,t){if(!Array.isArray(e)||e.length===0)throw new N(`BAD_FORMAT`,`Animation '${t}': "frames" must be a non-empty array.`);if(e.length===2){let[t,n]=e;if(n>=t){let e=[];for(let r=t;r<=n;r++)e.push(r);return e}}return[...e]}var _v=class extends G_{static typeName=`Camera2D`;static props={follow:{default:``,nodePath:!0},smoothing:{default:0},zoom:{default:1},limits:{default:[]},current:{default:!1}};follow=``;smoothing=0;zoom=1;limits=[];current=!1;get effectiveZoom(){return Math.max(.01,this.zoom)}update(e){if(!this.follow)return;let t=this.getNodeOrNull(this.follow);if(!(t instanceof G_))return;let n=t.position[0]??0,r=t.position[1]??0,i=Math.min(Math.max(this.smoothing,0),.99),a=i<=0?1:1-i**(e*60),o=this.position[0]??0,s=this.position[1]??0;this.position=[o+(n-o)*a,s+(r-s)*a]}clampedCenter(e,t){let n=this.position[0]??0,r=this.position[1]??0;if(this.limits.length!==0&&this.limits.length!==4)throw new N(`BAD_FORMAT`,`Camera2D '${this.name}' limits must be [] or [minX,minY,maxX,maxY], got length ${this.limits.length}.`);if(this.limits.length===4){let[i,a,o,s]=this.limits,c=e/(2*this.effectiveZoom),l=t/(2*this.effectiveZoom);n=vv(n,i+c,o-c),r=vv(r,a+l,s-l)}return{x:n,y:r}}};function vv(e,t,n){return t>n?(t+n)/2:Math.min(n,Math.max(t,e))}var yv=class extends Nt{static typeName=`CharacterController2D`;static props={mode:{default:`platformer`,options:[`platformer`,`topDown`]},maxSpeed:{default:220},jumpHeight:{default:64},moveAction:{default:`move`},jumpAction:{default:`jump`},coyoteSeconds:{default:0},jumpBufferSeconds:{default:0},jumpCutMultiplier:{default:1},maxJumps:{default:1},dashSpeed:{default:0},dashSeconds:{default:.15},dashAction:{default:`dash`},wallSlideSpeed:{default:0},wallJumpImpulse:{default:[0,0]}};static signals=[`movementStateChanged`];mode=`platformer`;maxSpeed=220;jumpHeight=64;moveAction=`move`;jumpAction=`jump`;coyoteSeconds=0;jumpBufferSeconds=0;jumpCutMultiplier=1;maxJumps=1;dashSpeed=0;dashSeconds=.15;dashAction=`dash`;wallSlideSpeed=0;wallJumpImpulse=[0,0];state=`idle`;coyoteLeft=0;bufferLeft=0;jumpsUsed=0;dashLeft=0;dashDir=1;rising=!1;onReady(){if(!(this.parent instanceof X_))throw new N(`TREE_VIOLATION`,`CharacterController2D '${this.name}' must be a child of a CharacterBody2D (parent is '${this.parent?.name??`none`}').`);if(this.mode!==`platformer`&&this.mode!==`topDown`)throw new N(`PROP_TYPE_MISMATCH`,`CharacterController2D.mode must be 'platformer' or 'topDown', got '${this.mode}'.`)}fixedUpdate(e){let t=this.tree?.engine;if(!t?.scene)return;let n=this.parent;if(!(n instanceof X_))return;let r=t.input,i=r.getVector(this.moveAction);if(this.mode===`topDown`){n.velocity=[i.x*this.maxSpeed,i.y*this.maxSpeed],n.moveAndSlide();return}let a=t.scene.physics?.gravity?.[1]??980,o=n.isOnFloor(),s=-Math.sqrt(2*a*this.jumpHeight);if(this.dashLeft>0){this.dashLeft-=e,n.velocity[0]=this.dashDir*this.dashSpeed,n.velocity[1]=0,n.moveAndSlide(),this.setState(`dash`);return}if(this.dashSpeed>0&&r.justPressed(this.dashAction)){this.dashLeft=this.dashSeconds,this.dashDir=i.x===0?this.dashDir:Math.sign(i.x),n.velocity[0]=this.dashDir*this.dashSpeed,n.velocity[1]=0,n.moveAndSlide(),this.setState(`dash`);return}n.velocity[0]=i.x*this.maxSpeed,o?(this.coyoteLeft=this.coyoteSeconds,this.jumpsUsed=0):(this.coyoteLeft=Math.max(0,this.coyoteLeft-e),this.coyoteLeft<=0&&this.jumpsUsed===0&&(this.jumpsUsed=1)),r.justPressed(this.jumpAction)?this.bufferLeft=Math.max(this.jumpBufferSeconds,0):this.bufferLeft=Math.max(0,this.bufferLeft-e);let c=this.bufferLeft>0||r.justPressed(this.jumpAction),l=this.wallSlideSpeed>0||this.wallJumpImpulse.some(e=>e!==0)?n.isOnWall():!1;if(c&&l&&!o&&this.wallJumpImpulse.some(e=>e!==0)){let e=-n.wallSide();n.velocity[0]=e*(this.wallJumpImpulse[0]??0),n.velocity[1]=-(this.wallJumpImpulse[1]??0),this.bufferLeft=0,this.rising=!0,this.jumpsUsed=1}else c&&(o||this.coyoteLeft>0||this.jumpsUsed<this.maxJumps)?(n.velocity[1]=s,this.bufferLeft=0,this.coyoteLeft=0,this.rising=!0,this.jumpsUsed=o?1:this.jumpsUsed+1):o?(n.velocity[1]=20,this.rising=!1):(n.velocity[1]=(n.velocity[1]??0)+a*e,this.rising&&this.jumpCutMultiplier<1&&!r.isPressed(this.jumpAction)&&(n.velocity[1]=(n.velocity[1]??0)*this.jumpCutMultiplier,this.rising=!1),(n.velocity[1]??0)>=0&&(this.rising=!1),this.wallSlideSpeed>0&&l&&(n.velocity[1]??0)>this.wallSlideSpeed&&(n.velocity[1]=this.wallSlideSpeed));n.isOnCeiling()&&(n.velocity[1]??0)<0&&(n.velocity[1]=0,this.rising=!1),n.moveAndSlide();let u=n.velocity[1]??0;this.wallSlideSpeed>0&&!n.isOnFloor()&&n.isOnWall()&&u>0?this.setState(`wallSlide`):n.isOnFloor()?this.setState(Math.abs(i.x)>.01?`run`:`idle`):this.setState(u<0?`jump`:`fall`)}setState(e){e!==this.state&&(this.state=e,this.emit(`movementStateChanged`,e))}},bv=new cl(1,1),xv=class extends G_{static typeName=`ColorRect2D`;static props={size:{default:[100,100]},color:{default:`#ffffff`},opacity:{default:1},anchor:{default:[.5,.5]}};size=[100,100];color=`#ffffff`;opacity=1;anchor=[.5,.5];quadMesh=null;_quad(){return this.quadMesh||(this.quadMesh=new Ys(bv,new Ls({transparent:!0,depthWrite:!1})),this._ensureObject2D().add(this.quadMesh)),this.quadMesh}_syncObject2D(e){super._syncObject2D(e);let t=this._quad(),n=this.size[0]??0,r=this.size[1]??0;t.visible=n>0&&r>0&&this.opacity>0,t.scale.set(n,r,1);let i=this.anchor[0]??.5,a=this.anchor[1]??.5;t.position.set((.5-i)*n,(a-.5)*r,0),t.renderOrder=this.effectiveRenderOrder;let o=t.material;o.color.set(this.color),o.opacity=this.opacity}},Sv=new cl(1,1),Cv=class extends G_{static typeName=`Label`;static props={text:{default:``},fontSize:{default:16},color:{default:`#ffffff`},font:{default:`monospace`},align:{default:`left`}};text=``;fontSize=16;color=`#ffffff`;font=`monospace`;align=`left`;quadMesh=null;canvas=null;lastKey=``;_quad(){return this.quadMesh||(this.quadMesh=new Ys(Sv,new Ls({transparent:!0,depthWrite:!1})),this._ensureObject2D().add(this.quadMesh)),this.quadMesh}_syncObject2D(e){super._syncObject2D(e);let t=this._quad();if(typeof document>`u`||this.text===``){t.visible=!1;return}let n=`${this.text}\0${this.fontSize}\0${this.color}\0${this.font}\0${this.align}`;n!==this.lastKey&&(this.lastKey=n,this.rasterize()),t.visible=!0,t.renderOrder=this.effectiveRenderOrder}rasterize(){let e=Math.min(globalThis.devicePixelRatio??1,2);this.canvas??=document.createElement(`canvas`);let t=this.canvas.getContext(`2d`);if(!t)return;let n=`${this.fontSize*e}px ${this.font}`;t.font=n;let r=t.measureText(this.text),i=Math.max(1,Math.ceil(r.width)),a=Math.ceil(this.fontSize*e*1.4);this.canvas.width=i,this.canvas.height=a,t.font=n,t.fillStyle=this.color,t.textBaseline=`middle`,t.fillText(this.text,0,a/2);let o=this._quad(),s=o.material;s.map?.dispose(),s.map=new Qc(this.canvas),s.needsUpdate=!0;let c=i/e,l=a/e;o.scale.set(c,l,1);let u=this.align===`center`?.5:+(this.align===`right`);o.position.set((.5-u)*c,0,0)}},wv=new cl(1,1),Tv=class e extends G_{orderGroup=`effects`;static typeName=`Particles2D`;static signals=[`finished`];static props={orderGroup:{default:`effects`,options:[`background`,`terrain`,`default`,`characters`,`effects`,`overlay`]},preset:{default:`custom`,options:[`custom`,...pn]},emitting:{default:!0},rate:{default:40},burst:{default:0},lifetime:{default:[.6,1.2]},speed:{default:[40,120]},directionDeg:{default:-90},spreadDeg:{default:30},gravity:{default:[0,0]},drag:{default:0},sizeStart:{default:8},sizeEnd:{default:2},colorStart:{default:`#ffffff`},colorEnd:{default:`#ffffff`},paletteColors:{default:[]},alphaStart:{default:1},alphaEnd:{default:0},shimmer:{default:0},blend:{default:`add`,options:[`add`,`normal`]},maxParticles:{default:256}};preset=`custom`;emitting=!0;rate=40;burst=0;lifetime=[.6,1.2];speed=[40,120];directionDeg=-90;spreadDeg=30;gravity=[0,0];drag=0;sizeStart=8;sizeEnd=2;colorStart=`#ffffff`;colorEnd=`#ffffff`;paletteColors=[];alphaStart=1;alphaEnd=0;shimmer=0;blend=`add`;maxParticles=256;static validateJson(e){let t=e;if(t.preset!==`custom`&&!pn.includes(t.preset))throw new N(`BAD_FORMAT`,`Particles2D '${e.name}' preset must be 'custom' or one of [${pn.join(`, `)}], got '${t.preset}'.`,{prop:`preset`,validOptions:pn});if(t.blend!==`add`&&t.blend!==`normal`)throw new N(`BAD_FORMAT`,`Particles2D '${e.name}' blend must be 'add' or 'normal', got '${t.blend}'.`,{prop:`blend`,validOptions:[`add`,`normal`]})}sim=null;bursted=!1;finishedEmitted=!1;_ensureSim(){if(!this.sim){mn(this,this.preset,qe(e.typeName));let t=this.tree?.engine?.rng??new P(4660);this.sim=new gn({rate:this.emitting?this.rate:0,lifetime:[this.lifetime[0]??1,this.lifetime[1]??1],speed:[this.speed[0]??0,this.speed[1]??0],directionDeg:this.directionDeg,spreadDeg:this.spreadDeg,gravity:[this.gravity[0]??0,this.gravity[1]??0,0],drag:this.drag,maxParticles:this.maxParticles},t)}return this.sim}update(e){let t=this._ensureSim();this.burst>0&&!this.bursted&&(this.bursted=!0,t.burst(this.burst)),t.update(e),(!this.emitting||this.rate===0)&&this.bursted&&t.done&&!this.finishedEmitted&&(this.finishedEmitted=!0,this.emit(`finished`))}replay(){this.bursted=!1,this.finishedEmitted=!1}mesh=null;paletteCache=[];paletteCacheKey=``;refreshPalette(){let e=this.paletteColors;if(e.length===0)return null;let t=e.join(`|`);if(t!==this.paletteCacheKey){this.paletteCacheKey=t;for(let t=0;t<e.length;t++){let n=this.paletteCache[t];n||(n=new K,this.paletteCache[t]=n),n.set(e[t])}this.paletteCache.length=e.length}return this.paletteCache}_syncObject2D(e){super._syncObject2D(e);let t=this._ensureSim();if(!this.mesh||this.mesh.count!==this.maxParticles){this.mesh&&this.mesh.removeFromParent();let e=new Ls({transparent:!0,depthWrite:!1,blending:this.blend===`add`?2:1});this.mesh=new xc(wv,e,this.maxParticles),this.mesh.instanceMatrix.setUsage(Pi),this.mesh.frustumCulled=!1,this._ensureObject2D().add(this.mesh)}let n=this.mesh,r=this.refreshPalette(),i=r?null:Dv.set(this.colorStart),a=Ov.set(this.colorEnd),o=this.shimmer,s=0;t.forEach(e=>{let t=this.sizeStart+(this.sizeEnd-this.sizeStart)*e.t;Ev.makeScale(t,t,1),Ev.setPosition(e.x,-e.y,0),n.setMatrixAt(s,Ev);let c=r?r[Math.floor(e.seed*r.length)]:i,l=Math.max(0,this.alphaStart+(this.alphaEnd-this.alphaStart)*e.t);o>0&&(l*=.5+.5*Math.sin(2*Math.PI*(e.age*o+e.seed))),kv.copy(c).lerp(a,e.t).multiplyScalar(l),n.setColorAt(s,kv),s+=1}),n.count=s,n.instanceMatrix.needsUpdate=!0,n.instanceColor&&(n.instanceColor.needsUpdate=!0),n.renderOrder=this.effectiveRenderOrder}},Ev=new G,Dv=new K,Ov=new K,kv=new K;function Av(e,t){let n=[],r=0;for(let i of e){let e=[];if(typeof i==`string`)for(let n of i){let r=t[n];if(r!==void 0)e.push(r);else if(n===`.`||n===` `)e.push(-1);else if(n>=`0`&&n<=`9`)e.push(n.charCodeAt(0)-48);else throw new N(`BAD_FORMAT`,`TileMap2D: unknown tile char '${n}' — add it to "legend" (char → tile index), or use '.'/' ' for empty and digits 0-9.`)}else for(let t of i)e.push(t);r=Math.max(r,e.length),n.push(e)}for(let e of n)for(;e.length<r;)e.push(-1);return n}function jv(e,t){let n=e.length,r=n>0?e[0].length:0,i=e.map(e=>e.map(()=>!1)),a=(n,r)=>t.has(e[r][n]),o=[];for(let e=0;e<n;e++)for(let t=0;t<r;t++){if(!a(t,e)||i[e][t])continue;let s=1;for(;t+s<r&&a(t+s,e)&&!i[e][t+s];)s++;let c=1;grow:for(;e+c<n;){for(let n=0;n<s;n++)if(!a(t+n,e+c)||i[e+c][t+n])break grow;c++}for(let n=0;n<c;n++)for(let r=0;r<s;r++)i[e+n][t+r]=!0;o.push({x:t,y:e,w:s,h:c})}return o}var Mv=class extends G_{static typeName=`TileMap2D`;static props={texture:{default:``},tileSize:{default:32},columns:{default:0},cells:{default:[]},legend:{default:{}},solid:{default:[]},opacity:{default:1}};texture=``;tileSize=32;columns=0;_cells=[];_legend={};_solid=[];geometryDirty=!0;collidersDirty=!0;get cells(){return this._cells}set cells(e){this._cells=e,this.geometryDirty=!0,this.collidersDirty=!0}get legend(){return this._legend}set legend(e){this._legend=e,this.geometryDirty=!0,this.collidersDirty=!0}get solid(){return this._solid}set solid(e){this._solid=e,this.collidersDirty=!0}opacity=1;tileMesh=null;builtColumns=0;builtRows=0;static validateJson(e){let t=e;Av(t._cells,t._legend)}grid(){return Av(this._cells,this._legend)}onReady(){this.rebuildColliders()}update(e){this.collidersDirty&&this.rebuildColliders()}rebuildColliders(){this.collidersDirty=!1;for(let e of[...this.children])e.name.startsWith(`__tileSolid`)&&e.free();if(this._solid.length===0)return;let e=this.tileSize;jv(this.grid(),new Set(this._solid)).forEach((t,n)=>{let r=new q_(`__tileSolid${n}`);r.position=[(t.x+t.w/2)*e,(t.y+t.h/2)*e],r.collider={shape:`rect`,size:[t.w*e,t.h*e]},this.addChild(r)})}_mesh(){return this.tileMesh||(this.tileMesh=new Ys(new J,new Ls({transparent:!0,depthWrite:!1})),this._ensureObject2D().add(this.tileMesh)),this.tileMesh}_syncObject2D(e){super._syncObject2D(e);let t=this._mesh(),n=t.material;if(!this.texture||!e){t.visible=!1;return}let r=e.getTexture(this.texture),i=r.image;if(!i?.width||!i.height){t.visible=!1;return}t.visible=this.opacity>0,t.renderOrder=this.effectiveRenderOrder,n.opacity=this.opacity,n.map!==r&&(r.magFilter=rr,n.map=r,n.needsUpdate=!0,this.geometryDirty=!0);let a=this.columns>0?this.columns:Math.max(1,Math.floor(i.width/this.tileSize)),o=Math.max(1,Math.floor(i.height/this.tileSize));(a!==this.builtColumns||o!==this.builtRows)&&(this.geometryDirty=!0),this.geometryDirty&&(this.geometryDirty=!1,this.builtColumns=a,this.builtRows=o,this.buildGeometry(t.geometry,a,o))}buildGeometry(e,t,n){let r=this.grid(),i=this.tileSize,a=[],o=[],s=[];for(let e=0;e<r.length;e++){let c=r[e];for(let r=0;r<c.length;r++){let l=c[r];if(l<0)continue;let u=r*i,d=u+i,f=-(e*i),p=-((e+1)*i),m=a.length/3;a.push(u,f,0,d,f,0,d,p,0,u,p,0);let h=l%t,g=Math.floor(l/t),_=h/t,v=(h+1)/t,y=1-g/n,b=1-(g+1)/n;o.push(_,y,v,y,v,b,_,b),s.push(m,m+2,m+1,m,m+3,m+2)}}e.setAttribute(`position`,new q(new Float32Array(a),3)),e.setAttribute(`uv`,new q(new Float32Array(o),2)),e.setIndex(s),e.computeBoundingSphere()}get renderedTileCount(){let e=this.tileMesh?.geometry.getAttribute(`position`);return e?e.count/4:0}free(){this.tileMesh?.geometry.dispose(),super.free()}},Nv=[`top-left`,`top`,`top-right`,`left`,`center`,`right`,`bottom-left`,`bottom`,`bottom-right`],Pv=class extends Nt{static typeName=`UILayer`;static props={anchor:{default:`top-left`,options:Nv}};anchor=`top-left`;group=null;_ensureGroup(){return this.group||(this.group=new _o,this.group.userData.incantoNode=this),this.group}static validateJson(e){let t=e.anchor;if(!Nv.includes(t))throw new N(`BAD_FORMAT`,`UILayer '${e.name}' anchor must be one of [${Nv.join(`, `)}], got '${t}'.`,{prop:`anchor`,validOptions:Nv})}_anchorOrigin(e,t){let n=this.anchor;return{x:n.includes(`right`)?e:n===`top`||n===`center`||n===`bottom`?e/2:0,y:n.includes(`bottom`)?t:n===`left`||n===`center`||n===`right`?t/2:0}}};function Fv(){_n(),R(G_),R(mv),R(xv),R(Tv),R(hv),R(_v),R(Cv),R(Pv),R(q_),R(Y_),R(J_),R(X_),R(yv),R(ev),R(Mv)}function Iv(e,t,n){return{x:(t-e.cx)*e.zoom+e.w/2,y:(n-e.cy)*e.zoom+e.h/2}}function Lv(e,t,n){return{x:(t-e.w/2)/e.zoom+e.cx,y:(n-e.h/2)/e.zoom+e.cy}}var Rv=new Vo,zv=new U,Bv=12,Vv=new Float32Array(16);function Hv(e){if(!(e instanceof G_))return null;let t=e._ensureObject2D();t.updateWorldMatrix(!0,!0),Rv.setFromObject(t),Rv.getSize(zv);let n,r,i,a;if(!Number.isFinite(zv.x)||zv.x===0&&zv.y===0){let e=new U().setFromMatrixPosition(t.matrixWorld);n=e.x-Bv,i=e.x+Bv,r=e.y-Bv,a=e.y+Bv}else n=Rv.min.x-2,i=Rv.max.x+2,r=Rv.min.y-2,a=Rv.max.y+2;let o=[n,r,i,r,i,r,i,a,i,a,n,a,n,a,n,r];return Vv.set(o),Vv}function Uv(){return{visited:new Set,cameras:[]}}function Wv(e,t,n,r,i,a,o){let s=a??Uv();s.visited.clear(),s.cameras.length=0,Gv(e,t,n,!1,s.visited,s.cameras,r,i,o?.ignoreStatic===!0),Kv(t,s.visited),Kv(n,s.visited);let c=null;for(let e=0;e<s.cameras.length;e++){let t=s.cameras[e];if(t.current){c=t;break}}return c||=s.cameras[0]??null,{activeCamera:c}}function Gv(e,t,n,r,i,a,o,s,c){let l=t,u=r;if(e instanceof G_&&!(e instanceof Pv)){let t=e._ensureObject2D();if(e.static&&!c&&t.userData.incantoStaticSynced===!0){t.userData.incantoStatic=!0,i.add(t);return}}if(e instanceof Pv){let t=e._ensureGroup();t.parent!==n&&n.add(t);let r=s?e._anchorOrigin(s.width,s.height):{x:0,y:0};t.position.set(r.x,-r.y,0),i.add(t),u=!0,l=t}else if(e instanceof G_){let n=e._ensureObject2D();n.parent!==t&&t.add(n),e._syncObject2D(o),i.add(n),e instanceof _v&&!r&&a.push(e),l=n}for(let t of e.children)Gv(t,l,n,u,i,a,o,s,c);if(e instanceof G_&&!(e instanceof Pv)){let t=e._ensureObject2D();e.static&&!c?(t.userData.incantoStaticSynced=!0,t.userData.incantoStatic=!0):t.userData.incantoStaticSynced===!0&&(t.userData.incantoStaticSynced=!1,t.userData.incantoStatic=!1)}}function Kv(e,t){let n=e.children;for(let r=n.length-1;r>=0;r--){let i=n[r];i.userData.incantoNode&&!t.has(i)?e.remove(i):i.userData.incantoStatic!==!0&&Kv(i,t)}}var qv=class{viewOverride=null;webgl;worldScene=new Eo;syncScratch=Uv();ignoreStatic=!1;uiScene=new Eo;worldCam=new vu(-1,1,1,-1,-1e3,1e3);uiCam=new vu(-1,1,1,-1,-1e3,1e3);engine;assets;loadedAssetScenes=new WeakSet;disconnect;canvas;constructor(e){this.canvas=e.canvas,this.engine=e.engine,this.assets=e.assets??new gm(void 0,this.engine);let t=vn(e.engine.scene?.environment,{antialias:!0,pixelRatio:1,preserveDrawingBuffer:!1},globalThis.devicePixelRatio??1,e);this.webgl=new hm({canvas:e.canvas,antialias:t.antialias,preserveDrawingBuffer:t.preserveDrawingBuffer}),this.webgl.info.autoReset=!1,this.engine.picker=(e,t)=>this.pick(e,t),this.webgl.setPixelRatio(t.pixelRatio),this.webgl.info.autoReset=!1,this.debugLines=new Hc(new J,new Ac({color:`#00ff6e`,transparent:!0,depthTest:!1})),this.debugLines.frustumCulled=!1,this.debugLines.renderOrder=9999,this.debugLines.visible=!1,this.worldScene.add(this.debugLines),this.selectionLines=new Hc(new J,new Ac({color:`#ffb020`,transparent:!0,depthTest:!1})),this.selectionLines.frustumCulled=!1,this.selectionLines.renderOrder=1e4,this.selectionLines.visible=!1,this.worldScene.add(this.selectionLines),this.disconnect=this.engine.updated.connect(()=>this.render())}debugLines;selectionLines;syncSelectionOutline(){let e=this.engine.debugSelection;e&&e.tree!==this.engine.scene?.tree&&(this.engine.debugSelection=null);let t=this.engine.debugSelection,n=t?Hv(t):null;if(this.selectionLines.visible=n!==null,!n)return;let r=new Float32Array(n.length/2*3);for(let e=0,t=0;e<n.length;e+=2,t+=3)r[t]=n[e],r[t+1]=n[e+1],r[t+2]=0;this.selectionLines.geometry.setAttribute(`position`,new q(r,3)),this.selectionLines.geometry.getAttribute(`position`).needsUpdate=!0}syncDebugLines(){let e=null;for(let t of $_(`2d`,this.engine))if(e=t.debugLines(),e)break;if(this.debugLines.visible=e!==null,!e)return;let t=new Float32Array(e.length/2*3);for(let n=0,r=0;n<e.length;n+=2,r+=3)t[r]=e[n],t[r+1]=e[n+1],t[r+2]=0;this.debugLines.geometry.setAttribute(`position`,new q(t,3))}render(){let e=this.engine.scene;if(!e)return;this.webgl.info.reset(),this.syncDebugLines(),this.syncSelectionOutline(),e.assets&&!this.loadedAssetScenes.has(e)&&(this.assets.load(e.assets),this.loadedAssetScenes.add(e));let t=e.environment?.background;this.worldScene.background=typeof t==`string`?new K(t):null;let n=this.canvas.clientWidth||this.canvas.width,r=this.canvas.clientHeight||this.canvas.height,i=this.webgl.getSize(Yv);(i.x!==n||i.y!==r)&&this.webgl.setSize(n,r,!1);let a=this.viewOverride?null:Tn(e.viewport),o=a?En(n,r,a):null,s=o?o.viewW:n,c=o?o.viewH:r,{activeCamera:l}=Wv(e.root,this.worldScene,this.uiScene,this.assets,{width:s,height:c},this.syncScratch),u=a?{x:a.design[0]/2,y:a.design[1]/2}:{x:n/2,y:r/2},d=1;this.viewOverride?(u={x:this.viewOverride.cx,y:this.viewOverride.cy},d=this.viewOverride.zoom):l&&(u=l.clampedCenter(s,c),d=l.effectiveZoom);let f=o?.scale??1;this.lastView={cx:u.x,cy:u.y,zoom:d*f,w:n,h:r},this.lastViewport=o,o&&(o.offsetX>.5||o.offsetY>.5)?(this.webgl.setScissorTest(!1),this.webgl.setViewport(0,0,n,r),this.webgl.clear(),this.webgl.setViewport(o.offsetX,o.offsetY,o.contentW,o.contentH),this.webgl.setScissor(o.offsetX,o.offsetY,o.contentW,o.contentH),this.webgl.setScissorTest(!0)):(this.webgl.setScissorTest(!1),this.webgl.setViewport(0,0,n,r)),Jv(this.worldCam,u.x,u.y,s/d,c/d),Jv(this.uiCam,s/2,c/2,s,c),this.webgl.info.reset(),this.webgl.autoClear=!0,this.webgl.render(this.worldScene,this.worldCam),this.webgl.autoClear=!1,this.webgl.render(this.uiScene,this.uiCam),this.webgl.autoClear=!0}lastViewport=null;lastView={cx:0,cy:0,zoom:1,w:1,h:1};view(){return{...this.lastView}}stats(){let e=this.webgl.info;return{triangles:e.render.triangles,drawCalls:e.render.calls,geometries:e.memory.geometries,textures:e.memory.textures}}worldFromScreen(e,t){return Lv(this.lastView,e,t)}screenFromWorld(e,t){return Iv(this.lastView,e,t)}pick(e,t){let{w:n,h:r}=this.lastView,i=this.lastViewport?.offsetX??0,a=this.lastViewport?.offsetY??0,o=this.lastViewport?.contentW??n,s=this.lastViewport?.contentH??r;Zv.set((e-i)/o*2-1,-((t-a)/s*2-1)),Qv.setFromCamera(Zv,this.worldCam);let c=Qv.intersectObjects(this.worldScene.children,!0),l=null;for(let e of c){let t=e.object;for(;t&&!t.userData.incantoNode;)t=t.parent;let n=t?.userData.incantoNode;if(!n)continue;let r=e.object.renderOrder??0;(!l||r>=l.order)&&(l={node:n,order:r})}return l?.node??null}boundsOf(e){let t=e._object2D;if(!t||($v.makeEmpty(),$v.expandByObject(t),$v.isEmpty())||($v.getSize(Xv),Xv.x===0&&Xv.y===0))return null;let n=this.screenFromWorld($v.min.x,-$v.max.y),r=this.screenFromWorld($v.max.x,-$v.min.y);return{x:n.x,y:n.y,w:r.x-n.x,h:r.y-n.y}}dispose(){this.engine.picker&&(this.engine.picker=null),this.disconnect();for(let e of[this.worldScene,this.uiScene])e.traverse(e=>{let t=e;if(!t.isMesh)return;let n=Array.isArray(t.material)?t.material:[t.material];for(let e of n)e?.map?.dispose(),e?.dispose()});this.webgl.dispose()}};function Jv(e,t,n,r,i){e.position.set(t,-n,10),e.left=-r/2,e.right=r/2,e.top=i/2,e.bottom=-i/2,e.updateProjectionMatrix()}var Yv=new V,Xv=new U,Zv=new V,Qv=new qu,$v=new Vo;async function ey(e){Fv(),(e.gameplay??!0)&&U_();for(let[t,n]of Object.entries(e.behaviors??{}))it(t,n,{replace:!0});let t=new kt({seed:e.seed,fixedHz:e.fixedHz,...e._scheduler?{scheduler:e._scheduler}:{}}),n=ty(e.scene),r=An(ty(n),{resolveScene:e.resolveScene,engine:t});t.setScene(r);let i=null;(e.physics===!0||(e.physics??`auto`)===`auto`&&ny(r.root))&&(i=await nv(t));let a=[],o=e.keyboard??(typeof window<`u`?window:!1);o&&t.input.attachKeyboard(o),a.push(ry(t,r.root,e.canvas)),a.push(t.settings.bindAudio(t.audio)),a.push(t.settings.bindLocale(t.locale));let s=e.touch??`auto`;if(s!==!1){let n=e.touchContainer??e.canvas.parentElement??null;if(n){let r={force:s===!0,...e._touchDoc?{doc:e._touchDoc}:{}},i=qn(t,n,r),o=t.sceneChanged.connect(()=>{i?.dispose(),i=qn(t,n,r)});a.push(()=>{o(),i?.dispose()})}}let c=e._rendererFactory?e._rendererFactory(t,e.canvas):new qv({canvas:e.canvas,engine:t,...e.pixelRatio===void 0?{}:{pixelRatio:e.pixelRatio},...e.antialias===void 0?{}:{antialias:e.antialias}}),l=e.debug??!1,u=e.editor??l,d=u===!0?{}:u||null,f={label:`✎ edit this scene`,run:async()=>{if(!d)return;let t=d.open??Om,r=async t=>{await ey({...e,scene:t})};await km(async()=>{p();try{await t({scene:n,play:r,exit:()=>r(n),...d.save?{save:d.save}:{},...d.library?{library:d.library===!0?wm():d.library}:{}})}catch(e){console.error(`[incanto] could not open the editor:`,e),await r(n)}},`opening the editor…`)}};if(l){let n=e.touchContainer??e.canvas.parentElement??(typeof document<`u`?document.body:null);if(n){let{attachDebugOverlay:r}=await bm(async()=>{let{attachDebugOverlay:e}=await import(`./debug-wSa-vYHO.js`);return{attachDebugOverlay:e}},[],import.meta.url),i=r(t,{container:n,statsSource:()=>c.stats?.()??{},...d?{actions:[f]}:{},...e._debugDoc?{doc:e._debugDoc}:{}});i&&a.push(()=>i.dispose())}}t.start();function p(){jm([i?[`physics`,()=>i?.dispose()]:null,[`app cleanups`,()=>{for(let e of a)e()}],[`engine`,()=>t.dispose()],[`renderer`,()=>c.dispose()]])}return{engine:t,scene:r,sourceJson:n,renderer:c,physics:i,pick(e,n){return t.picker?.(e,n)??null},stats(){return{triangles:0,drawCalls:0,geometries:0,textures:0,...t.stats(),...c.stats?.()}},openEditor:d?f.run:null,dispose:p}}function ty(e){try{return structuredClone(e)}catch{throw new N(`BAD_FORMAT`,`createGame "scene" must be plain scene JSON (the imported *.scene.json object) — got something unclonable (a loaded Scene, class instances, or functions).`)}}function ny(e){if(e instanceof K_)return!0;for(let t of e.children)if(ny(t))return!0;return!1}function ry(e,t,n){let r=[],i=n;if(i.addEventListener&&r.push({target:i,type:`pointerdown`}),typeof window<`u`&&r.push({target:window,type:`keydown`}),r.length===0)return()=>{};function a(){for(let e of r)e.target.removeEventListener?.(e.type,o)}function o(){e.sfx.unlock(),e.music.unlock();let n=!1,r=e=>{e instanceof Rt&&(e.retryPending(),e.pendingGesture&&(n=!0));for(let t of e.children)r(t)};r(t),n||a()}for(let e of r)e.target.addEventListener?.(e.type,o,{passive:!0});return a}function iy(e,t){let n=e;if(typeof n?.frame?.width!=`number`||typeof n.frame.height!=`number`||!n.animations||Object.keys(n.animations).length===0)throw new N(`BAD_FORMAT`,`Library sprite metadata needs {frame: {width, height}, animations: {<name>: {start, end, frameRate, repeat}}} — got ${JSON.stringify(e).slice(0,120)}.`);let r={},i=null,a=null;for(let[e,t]of Object.entries(n.animations)){if(typeof t.start!=`number`||typeof t.end!=`number`||typeof t.frameRate!=`number`)throw new N(`BAD_FORMAT`,`Library animation '${e}' needs numeric start/end/frameRate, got ${JSON.stringify(t)}.`);let n=t.repeat===-1;r[e]={frames:[t.start,t.end],fps:t.frameRate,loop:n},i??=e,n&&a===null&&(a=e)}let o=t.autoplay??a??i;return{asset:{type:`spritesheet`,url:t.url,frameWidth:n.frame.width,frameHeight:n.frame.height},props:{sheet:`$${t.assetKey}`,autoplay:o,animations:r}}}var ay=e({createGame2D:()=>ey,enablePhysics2D:()=>nv}),oy=(e,t,n)=>new Promise((r,i)=>{var a=e=>{try{s(n.next(e))}catch(e){i(e)}},o=e=>{try{s(n.throw(e))}catch(e){i(e)}},s=e=>e.done?r(e.value):Promise.resolve(e.value).then(a,o);s((n=n.apply(e,t)).next())}),sy=(e,t,n)=>new Promise((r,i)=>{var a=e=>{try{s(n.next(e))}catch(e){i(e)}},o=e=>{try{s(n.throw(e))}catch(e){i(e)}},s=e=>e.done?r(e.value):Promise.resolve(e.value).then(a,o);s((n=n.apply(e,t)).next())}),cy=class extends go{constructor(e){super(),this.weight=0,this.isBinary=!1,this.overrideBlink=`none`,this.overrideLookAt=`none`,this.overrideMouth=`none`,this._binds=[],this.name=`VRMExpression_${e}`,this.expressionName=e,this.type=`VRMExpression`,this.visible=!1}get binds(){return this._binds}get overrideBlinkAmount(){return this.overrideBlink===`block`?+(0<this.outputWeight):this.overrideBlink===`blend`?this.outputWeight:0}get overrideLookAtAmount(){return this.overrideLookAt===`block`?+(0<this.outputWeight):this.overrideLookAt===`blend`?this.outputWeight:0}get overrideMouthAmount(){return this.overrideMouth===`block`?+(0<this.outputWeight):this.overrideMouth===`blend`?this.outputWeight:0}get outputWeight(){return this.isBinary?+(this.weight>.5):this.weight}addBind(e){this._binds.push(e)}deleteBind(e){let t=this._binds.indexOf(e);t>=0&&this._binds.splice(t,1)}applyWeight(e){let t=this.outputWeight;t*=e?.multiplier??1,this.isBinary&&t<1&&(t=0),this._binds.forEach(e=>e.applyWeight(t))}clearAppliedWeight(){this._binds.forEach(e=>e.clearAppliedWeight())}};function ly(e,t,n){let r=e.parser.json,i=r.nodes?.[t];if(i==null)return console.warn(`extractPrimitivesInternal: Attempt to use nodes[${t}] of glTF but the node doesn't exist`),null;let a=i.mesh;if(a==null)return null;let o=r.meshes?.[a];if(o==null)return console.warn(`extractPrimitivesInternal: Attempt to use meshes[${a}] of glTF but the mesh doesn't exist`),null;let s=o.primitives.length,c=[];return n.traverse(e=>{c.length<s&&e.isMesh&&c.push(e)}),c}function uy(e,t){return sy(this,null,function*(){return ly(e,t,yield e.parser.getDependency(`node`,t))})}function dy(e){return sy(this,null,function*(){let t=yield e.parser.getDependencies(`node`),n=new Map;return t.forEach((t,r)=>{let i=ly(e,r,t);i!=null&&n.set(r,i)}),n})}var fy={Aa:`aa`,Ih:`ih`,Ou:`ou`,Ee:`ee`,Oh:`oh`,Blink:`blink`,Happy:`happy`,Angry:`angry`,Sad:`sad`,Relaxed:`relaxed`,LookUp:`lookUp`,Surprised:`surprised`,LookDown:`lookDown`,LookLeft:`lookLeft`,LookRight:`lookRight`,BlinkLeft:`blinkLeft`,BlinkRight:`blinkRight`,Neutral:`neutral`};function py(e){return Math.max(Math.min(e,1),0)}var my=class e{constructor(){this.blinkExpressionNames=[`blink`,`blinkLeft`,`blinkRight`],this.lookAtExpressionNames=[`lookLeft`,`lookRight`,`lookUp`,`lookDown`],this.mouthExpressionNames=[`aa`,`ee`,`ih`,`oh`,`ou`],this._expressions=[],this._expressionMap={}}get expressions(){return this._expressions.concat()}get expressionMap(){return Object.assign({},this._expressionMap)}get presetExpressionMap(){let e={},t=new Set(Object.values(fy));return Object.entries(this._expressionMap).forEach(([n,r])=>{t.has(n)&&(e[n]=r)}),e}get customExpressionMap(){let e={},t=new Set(Object.values(fy));return Object.entries(this._expressionMap).forEach(([n,r])=>{t.has(n)||(e[n]=r)}),e}copy(e){return this._expressions.concat().forEach(e=>{this.unregisterExpression(e)}),e._expressions.forEach(e=>{this.registerExpression(e)}),this.blinkExpressionNames=e.blinkExpressionNames.concat(),this.lookAtExpressionNames=e.lookAtExpressionNames.concat(),this.mouthExpressionNames=e.mouthExpressionNames.concat(),this}clone(){return new e().copy(this)}getExpression(e){return this._expressionMap[e]??null}registerExpression(e){this._expressions.push(e),this._expressionMap[e.expressionName]=e}unregisterExpression(e){let t=this._expressions.indexOf(e);t===-1&&console.warn(`VRMExpressionManager: The specified expressions is not registered`),this._expressions.splice(t,1),delete this._expressionMap[e.expressionName]}getValue(e){return this.getExpression(e)?.weight??null}setValue(e,t){let n=this.getExpression(e);n&&(n.weight=py(t))}resetValues(){this._expressions.forEach(e=>{e.weight=0})}getExpressionTrackName(e){let t=this.getExpression(e);return t?`${t.name}.weight`:null}update(){let e=this._calculateWeightMultipliers();this._expressions.forEach(e=>{e.clearAppliedWeight()}),this._expressions.forEach(t=>{let n=1,r=t.expressionName;this.blinkExpressionNames.indexOf(r)!==-1&&(n*=e.blink),this.lookAtExpressionNames.indexOf(r)!==-1&&(n*=e.lookAt),this.mouthExpressionNames.indexOf(r)!==-1&&(n*=e.mouth),t.applyWeight({multiplier:n})})}_calculateWeightMultipliers(){let e=1,t=1,n=1;return this._expressions.forEach(r=>{e-=r.overrideBlinkAmount,t-=r.overrideLookAtAmount,n-=r.overrideMouthAmount}),e=Math.max(0,e),t=Math.max(0,t),n=Math.max(0,n),{blink:e,lookAt:t,mouth:n}}},hy={Color:`color`,EmissionColor:`emissionColor`,ShadeColor:`shadeColor`,MatcapColor:`matcapColor`,RimColor:`rimColor`,OutlineColor:`outlineColor`},gy={_Color:hy.Color,_EmissionColor:hy.EmissionColor,_ShadeColor:hy.ShadeColor,_RimColor:hy.RimColor,_OutlineColor:hy.OutlineColor},_y=new K,vy=class e{constructor({material:e,type:t,targetValue:n,targetAlpha:r}){this.material=e,this.type=t,this.targetValue=n,this.targetAlpha=r??1;let i=this._initColorBindState(),a=this._initAlphaBindState();this._state={color:i,alpha:a}}applyWeight(e){let{color:t,alpha:n}=this._state;if(t!=null){let{propertyName:n,deltaValue:r}=t;this.material[n]?.add(_y.copy(r).multiplyScalar(e))}if(n!=null){let{propertyName:t,deltaValue:r}=n;this.material[t]!=null&&(this.material[t]+=r*e)}}clearAppliedWeight(){let{color:e,alpha:t}=this._state;if(e!=null){let{propertyName:t,initialValue:n}=e;this.material[t]?.copy(n)}if(t!=null){let{propertyName:e,initialValue:n}=t;this.material[e]!=null&&(this.material[e]=n)}}_initColorBindState(){let{material:e,type:t,targetValue:n}=this,r=this._getPropertyNameMap()?.[t]?.[0]??null;if(r==null)return console.warn(`Tried to add a material color bind to the material ${e.name??`(no name)`}, the type ${t} but the material or the type is not supported.`),null;let i=e[r].clone();return{propertyName:r,initialValue:i,deltaValue:new K(n.r-i.r,n.g-i.g,n.b-i.b)}}_initAlphaBindState(){let{material:e,type:t,targetAlpha:n}=this,r=this._getPropertyNameMap()?.[t]?.[1]??null;if(r==null&&n!==1)return console.warn(`Tried to add a material alpha bind to the material ${e.name??`(no name)`}, the type ${t} but the material or the type does not support alpha.`),null;if(r==null)return null;let i=e[r];return{propertyName:r,initialValue:i,deltaValue:n-i}}_getPropertyNameMap(){return Object.entries(e._propertyNameMapMap).find(([e])=>this.material[e]===!0)?.[1]??null}};vy._propertyNameMapMap={isMeshStandardMaterial:{color:[`color`,`opacity`],emissionColor:[`emissive`,null]},isMeshBasicMaterial:{color:[`color`,`opacity`]},isMToonMaterial:{color:[`color`,`opacity`],emissionColor:[`emissive`,null],outlineColor:[`outlineColorFactor`,null],matcapColor:[`matcapFactor`,null],rimColor:[`parametricRimColorFactor`,null],shadeColor:[`shadeColorFactor`,null]}};var yy=vy,by=class{constructor({primitives:e,index:t,weight:n}){this.primitives=e,this.index=t,this.weight=n}applyWeight(e){this.primitives.forEach(t=>{t.morphTargetInfluences?.[this.index]!=null&&(t.morphTargetInfluences[this.index]+=this.weight*e)})}clearAppliedWeight(){this.primitives.forEach(e=>{e.morphTargetInfluences?.[this.index]!=null&&(e.morphTargetInfluences[this.index]=0)})}},xy=new V,Sy=class e{constructor({material:t,scale:n,offset:r}){this.material=t,this.scale=n,this.offset=r;let i=Object.entries(e._propertyNamesMap).find(([e])=>t[e]===!0)?.[1];i==null?(console.warn(`Tried to add a texture transform bind to the material ${t.name??`(no name)`} but the material is not supported.`),this._properties=[]):(this._properties=[],i.forEach(e=>{let i=t[e]?.clone();if(!i)return null;t[e]=i;let a=i.offset.clone(),o=i.repeat.clone(),s=r.clone().sub(a),c=n.clone().sub(o);this._properties.push({name:e,initialOffset:a,deltaOffset:s,initialScale:o,deltaScale:c})}))}applyWeight(e){this._properties.forEach(t=>{let n=this.material[t.name];n!==void 0&&(n.offset.add(xy.copy(t.deltaOffset).multiplyScalar(e)),n.repeat.add(xy.copy(t.deltaScale).multiplyScalar(e)))})}clearAppliedWeight(){this._properties.forEach(e=>{let t=this.material[e.name];t!==void 0&&(t.offset.copy(e.initialOffset),t.repeat.copy(e.initialScale))})}};Sy._propertyNamesMap={isMeshStandardMaterial:[`map`,`emissiveMap`,`bumpMap`,`normalMap`,`displacementMap`,`roughnessMap`,`metalnessMap`,`alphaMap`],isMeshBasicMaterial:[`map`,`specularMap`,`alphaMap`],isMToonMaterial:[`map`,`normalMap`,`emissiveMap`,`shadeMultiplyTexture`,`rimMultiplyTexture`,`outlineWidthMultiplyTexture`,`uvAnimationMaskTexture`]};var Cy=Sy,wy=new Set([`1.0`,`1.0-beta`]),Ty=class e{get name(){return`VRMExpressionLoaderPlugin`}constructor(e){this.parser=e}afterRoot(e){return sy(this,null,function*(){e.userData.vrmExpressionManager=yield this._import(e)})}_import(e){return sy(this,null,function*(){return(yield this._v1Import(e))||(yield this._v0Import(e))||null})}_v1Import(e){return sy(this,null,function*(){let t=this.parser.json;if(t.extensionsUsed?.indexOf(`VRMC_vrm`)===-1)return null;let n=t.extensions?.VRMC_vrm;if(!n)return null;let r=n.specVersion;if(!wy.has(r))return console.warn(`VRMExpressionLoaderPlugin: Unknown VRMC_vrm specVersion "${r}"`),null;let i=n.expressions;if(!i)return null;let a=new Set(Object.values(fy)),o=new Map;i.preset!=null&&Object.entries(i.preset).forEach(([e,t])=>{if(t!=null){if(!a.has(e)){console.warn(`VRMExpressionLoaderPlugin: Unknown preset name "${e}" detected. Ignoring the expression`);return}o.set(e,t)}}),i.custom!=null&&Object.entries(i.custom).forEach(([e,t])=>{if(a.has(e)){console.warn(`VRMExpressionLoaderPlugin: Custom expression cannot have preset name "${e}". Ignoring the expression`);return}o.set(e,t)});let s=new my;return yield Promise.all(Array.from(o.entries()).map(t=>sy(this,[t],function*([t,n]){var r,i,a;let o=new cy(t);if(e.scene.add(o),o.isBinary=n.isBinary??!1,o.overrideBlink=n.overrideBlink??`none`,o.overrideLookAt=n.overrideLookAt??`none`,o.overrideMouth=n.overrideMouth??`none`,(r=n.morphTargetBinds)==null||r.forEach(t=>sy(this,null,function*(){if(t.node===void 0||t.index===void 0)return;let r=yield uy(e,t.node),i=t.index;if(!r.every(e=>Array.isArray(e.morphTargetInfluences)&&i<e.morphTargetInfluences.length)){console.warn(`VRMExpressionLoaderPlugin: ${n.name} attempts to index morph #${i} but not found.`);return}o.addBind(new by({primitives:r,index:i,weight:t.weight??1}))})),n.materialColorBinds||n.textureTransformBinds){let t=[];e.scene.traverse(e=>{let n=e.material;n&&(Array.isArray(n)?t.push(...n):t.push(n))}),(i=n.materialColorBinds)==null||i.forEach(e=>sy(this,null,function*(){t.filter(t=>{let n=this.parser.associations.get(t)?.materials;return e.material===n}).forEach(t=>{o.addBind(new yy({material:t,type:e.type,targetValue:new K().fromArray(e.targetValue),targetAlpha:e.targetValue[3]}))})})),(a=n.textureTransformBinds)==null||a.forEach(e=>sy(this,null,function*(){t.filter(t=>{let n=this.parser.associations.get(t)?.materials;return e.material===n}).forEach(t=>{o.addBind(new Cy({material:t,offset:new V().fromArray(e.offset??[0,0]),scale:new V().fromArray(e.scale??[1,1])}))})}))}s.registerExpression(o)}))),s})}_v0Import(t){return sy(this,null,function*(){let n=this.parser.json,r=n.extensions?.VRM;if(!r)return null;let i=r.blendShapeMaster;if(!i)return null;let a=new my,o=i.blendShapeGroups;if(!o)return a;let s=new Set;return yield Promise.all(o.map(r=>sy(this,null,function*(){let i=r.presetName,o=(i!=null&&e.v0v1PresetNameMap[i]||null)??r.name;if(o==null){console.warn(`VRMExpressionLoaderPlugin: One of custom expressions has no name. Ignoring the expression`);return}if(s.has(o)){console.warn(`VRMExpressionLoaderPlugin: An expression preset ${i} has duplicated entries. Ignoring the expression`);return}s.add(o);let c=new cy(o);t.scene.add(c),c.isBinary=r.isBinary??!1,r.binds&&r.binds.forEach(e=>sy(this,null,function*(){var i;if(e.mesh===void 0||e.index===void 0)return;let a=[];(i=n.nodes)==null||i.forEach((t,n)=>{t.mesh===e.mesh&&a.push(n)});let o=e.index;yield Promise.all(a.map(n=>sy(this,null,function*(){let i=yield uy(t,n);if(!i.every(e=>Array.isArray(e.morphTargetInfluences)&&o<e.morphTargetInfluences.length)){console.warn(`VRMExpressionLoaderPlugin: ${r.name} attempts to index ${o}th morph but not found.`);return}c.addBind(new by({primitives:i,index:o,weight:.01*(e.weight??100)}))})))}));let l=r.materialValues;l&&l.length!==0&&l.forEach(e=>{if(e.materialName===void 0||e.propertyName===void 0||e.targetValue===void 0)return;let n=[];t.scene.traverse(t=>{if(t.material){let r=t.material;Array.isArray(r)?n.push(...r.filter(t=>(t.name===e.materialName||t.name===e.materialName+` (Outline)`)&&n.indexOf(t)===-1)):r.name===e.materialName&&n.indexOf(r)===-1&&n.push(r)}});let r=e.propertyName;n.forEach(t=>{if(r===`_MainTex_ST`){let n=new V(e.targetValue[0],e.targetValue[1]),r=new V(e.targetValue[2],e.targetValue[3]);r.y=1-r.y-n.y,c.addBind(new Cy({material:t,scale:n,offset:r}));return}let n=gy[r];if(n){c.addBind(new yy({material:t,type:n,targetValue:new K().fromArray(e.targetValue),targetAlpha:e.targetValue[3]}));return}console.warn(r+` is not supported`)})}),a.registerExpression(c)}))),a})}};Ty.v0v1PresetNameMap={a:`aa`,e:`ee`,i:`ih`,o:`oh`,u:`ou`,blink:`blink`,joy:`happy`,angry:`angry`,sorrow:`sad`,fun:`relaxed`,lookup:`lookUp`,lookdown:`lookDown`,lookleft:`lookLeft`,lookright:`lookRight`,blink_l:`blinkLeft`,blink_r:`blinkRight`,neutral:`neutral`};var Ey=Ty,Dy=class e{constructor(t,n){this._firstPersonOnlyLayer=e.DEFAULT_FIRSTPERSON_ONLY_LAYER,this._thirdPersonOnlyLayer=e.DEFAULT_THIRDPERSON_ONLY_LAYER,this._initializedLayers=!1,this.humanoid=t,this.meshAnnotations=n}copy(e){if(this.humanoid!==e.humanoid)throw Error(`VRMFirstPerson: humanoid must be same in order to copy`);return this.meshAnnotations=e.meshAnnotations.map(e=>({meshes:e.meshes.concat(),type:e.type})),this}clone(){return new e(this.humanoid,this.meshAnnotations).copy(this)}get firstPersonOnlyLayer(){return this._firstPersonOnlyLayer}get thirdPersonOnlyLayer(){return this._thirdPersonOnlyLayer}setup({firstPersonOnlyLayer:t=e.DEFAULT_FIRSTPERSON_ONLY_LAYER,thirdPersonOnlyLayer:n=e.DEFAULT_THIRDPERSON_ONLY_LAYER}={}){this._initializedLayers||=(this._firstPersonOnlyLayer=t,this._thirdPersonOnlyLayer=n,this.meshAnnotations.forEach(e=>{e.meshes.forEach(t=>{e.type===`firstPersonOnly`?(t.layers.set(this._firstPersonOnlyLayer),t.traverse(e=>e.layers.set(this._firstPersonOnlyLayer))):e.type===`thirdPersonOnly`?(t.layers.set(this._thirdPersonOnlyLayer),t.traverse(e=>e.layers.set(this._thirdPersonOnlyLayer))):e.type===`auto`&&this._createHeadlessModel(t)})}),!0)}_excludeTriangles(e,t,n,r){let i=0;if(t!=null&&t.length>0)for(let a=0;a<e.length;a+=3){let o=e[a],s=e[a+1],c=e[a+2],l=t[o],u=n[o];if(l[0]>0&&r.includes(u[0])||l[1]>0&&r.includes(u[1])||l[2]>0&&r.includes(u[2])||l[3]>0&&r.includes(u[3]))continue;let d=t[s],f=n[s];if(d[0]>0&&r.includes(f[0])||d[1]>0&&r.includes(f[1])||d[2]>0&&r.includes(f[2])||d[3]>0&&r.includes(f[3]))continue;let p=t[c],m=n[c];p[0]>0&&r.includes(m[0])||p[1]>0&&r.includes(m[1])||p[2]>0&&r.includes(m[2])||p[3]>0&&r.includes(m[3])||(e[i++]=o,e[i++]=s,e[i++]=c)}return i}_createErasedMesh(e,t){let n=new sc(e.geometry.clone(),e.material);n.name=`${e.name}(erase)`,n.frustumCulled=e.frustumCulled,n.layers.set(this._firstPersonOnlyLayer);let r=n.geometry,i=r.getAttribute(`skinIndex`),a=i instanceof Gu?[]:i.array,o=[];for(let e=0;e<a.length;e+=4)o.push([a[e],a[e+1],a[e+2],a[e+3]]);let s=r.getAttribute(`skinWeight`),c=s instanceof Gu?[]:s.array,l=[];for(let e=0;e<c.length;e+=4)l.push([c[e],c[e+1],c[e+2],c[e+3]]);let u=r.getIndex();if(!u)throw Error(`The geometry doesn't have an index buffer`);let d=Array.from(u.array),f=this._excludeTriangles(d,l,o,t),p=[];for(let e=0;e<f;e++)p[e]=d[e];return r.setIndex(p),e.onBeforeRender&&(n.onBeforeRender=e.onBeforeRender),n.bind(new fc(e.skeleton.bones,e.skeleton.boneInverses),new G),n}_createHeadlessModelForSkinnedMesh(e,t){let n=[];if(t.skeleton.bones.forEach((e,t)=>{this._isEraseTarget(e)&&n.push(t)}),!n.length){t.layers.enable(this._thirdPersonOnlyLayer),t.layers.enable(this._firstPersonOnlyLayer);return}t.layers.set(this._thirdPersonOnlyLayer);let r=this._createErasedMesh(t,n);e.add(r)}_createHeadlessModel(e){if(e.type===`Group`)if(e.layers.set(this._thirdPersonOnlyLayer),this._isEraseTarget(e))e.traverse(e=>e.layers.set(this._thirdPersonOnlyLayer));else{let t=new _o;t.name=`_headless_${e.name}`,t.layers.set(this._firstPersonOnlyLayer),e.parent.add(t),e.children.filter(e=>e.type===`SkinnedMesh`).forEach(e=>{let n=e;this._createHeadlessModelForSkinnedMesh(t,n)})}else if(e.type===`SkinnedMesh`){let t=e;this._createHeadlessModelForSkinnedMesh(e.parent,t)}else this._isEraseTarget(e)&&(e.layers.set(this._thirdPersonOnlyLayer),e.traverse(e=>e.layers.set(this._thirdPersonOnlyLayer)))}_isEraseTarget(e){return e===this.humanoid.getRawBoneNode(`head`)?!0:e.parent?this._isEraseTarget(e.parent):!1}};Dy.DEFAULT_FIRSTPERSON_ONLY_LAYER=9,Dy.DEFAULT_THIRDPERSON_ONLY_LAYER=10;var Oy=Dy,ky=new Set([`1.0`,`1.0-beta`]),Ay=class{get name(){return`VRMFirstPersonLoaderPlugin`}constructor(e){this.parser=e}afterRoot(e){return sy(this,null,function*(){let t=e.userData.vrmHumanoid;if(t!==null){if(t===void 0)throw Error(`VRMFirstPersonLoaderPlugin: vrmHumanoid is undefined. VRMHumanoidLoaderPlugin have to be used first`);e.userData.vrmFirstPerson=yield this._import(e,t)}})}_import(e,t){return sy(this,null,function*(){return t==null?null:(yield this._v1Import(e,t))||(yield this._v0Import(e,t))||null})}_v1Import(e,t){return sy(this,null,function*(){let n=this.parser.json;if(n.extensionsUsed?.indexOf(`VRMC_vrm`)===-1)return null;let r=n.extensions?.VRMC_vrm;if(!r)return null;let i=r.specVersion;if(!ky.has(i))return console.warn(`VRMFirstPersonLoaderPlugin: Unknown VRMC_vrm specVersion "${i}"`),null;let a=r.firstPerson,o=[],s=yield dy(e);return Array.from(s.entries()).forEach(([e,t])=>{let n=(a?.meshAnnotations)?.find(t=>t.node===e);o.push({meshes:t,type:n?.type??`auto`})}),new Oy(t,o)})}_v0Import(e,t){return sy(this,null,function*(){let n=this.parser.json,r=n.extensions?.VRM;if(!r)return null;let i=r.firstPerson;if(!i)return null;let a=[],o=yield dy(e);return Array.from(o.entries()).forEach(([e,t])=>{let r=n.nodes[e],o=i.meshAnnotations?i.meshAnnotations.find(e=>e.mesh===r.mesh):void 0;a.push({meshes:t,type:this._convertV0FlagToV1Type(o?.firstPersonFlag)})}),new Oy(t,a)})}_convertV0FlagToV1Type(e){return e===`FirstPersonOnly`?`firstPersonOnly`:e===`ThirdPersonOnly`?`thirdPersonOnly`:e===`Both`?`both`:`auto`}},jy=new U,My=new U,Ny=new H,Py=class extends _o{constructor(e){super(),this.vrmHumanoid=e,this._boneAxesMap=new Map,Object.values(e.humanBones).forEach(e=>{let t=new Xu(1);t.matrixAutoUpdate=!1,t.material.depthTest=!1,t.material.depthWrite=!1,this.add(t),this._boneAxesMap.set(e,t)})}dispose(){Array.from(this._boneAxesMap.values()).forEach(e=>{e.geometry.dispose(),e.material.dispose()})}updateMatrixWorld(e){Array.from(this._boneAxesMap.entries()).forEach(([e,t])=>{e.node.updateWorldMatrix(!0,!1),e.node.matrixWorld.decompose(jy,Ny,My);let n=jy.set(.1,.1,.1).divide(My);t.matrix.copy(e.node.matrixWorld).scale(n)}),super.updateMatrixWorld(e)}},Fy=`hips.spine.chest.upperChest.neck.head.leftEye.rightEye.jaw.leftUpperLeg.leftLowerLeg.leftFoot.leftToes.rightUpperLeg.rightLowerLeg.rightFoot.rightToes.leftShoulder.leftUpperArm.leftLowerArm.leftHand.rightShoulder.rightUpperArm.rightLowerArm.rightHand.leftThumbMetacarpal.leftThumbProximal.leftThumbDistal.leftIndexProximal.leftIndexIntermediate.leftIndexDistal.leftMiddleProximal.leftMiddleIntermediate.leftMiddleDistal.leftRingProximal.leftRingIntermediate.leftRingDistal.leftLittleProximal.leftLittleIntermediate.leftLittleDistal.rightThumbMetacarpal.rightThumbProximal.rightThumbDistal.rightIndexProximal.rightIndexIntermediate.rightIndexDistal.rightMiddleProximal.rightMiddleIntermediate.rightMiddleDistal.rightRingProximal.rightRingIntermediate.rightRingDistal.rightLittleProximal.rightLittleIntermediate.rightLittleDistal`.split(`.`),Iy={hips:null,spine:`hips`,chest:`spine`,upperChest:`chest`,neck:`upperChest`,head:`neck`,leftEye:`head`,rightEye:`head`,jaw:`head`,leftUpperLeg:`hips`,leftLowerLeg:`leftUpperLeg`,leftFoot:`leftLowerLeg`,leftToes:`leftFoot`,rightUpperLeg:`hips`,rightLowerLeg:`rightUpperLeg`,rightFoot:`rightLowerLeg`,rightToes:`rightFoot`,leftShoulder:`upperChest`,leftUpperArm:`leftShoulder`,leftLowerArm:`leftUpperArm`,leftHand:`leftLowerArm`,rightShoulder:`upperChest`,rightUpperArm:`rightShoulder`,rightLowerArm:`rightUpperArm`,rightHand:`rightLowerArm`,leftThumbMetacarpal:`leftHand`,leftThumbProximal:`leftThumbMetacarpal`,leftThumbDistal:`leftThumbProximal`,leftIndexProximal:`leftHand`,leftIndexIntermediate:`leftIndexProximal`,leftIndexDistal:`leftIndexIntermediate`,leftMiddleProximal:`leftHand`,leftMiddleIntermediate:`leftMiddleProximal`,leftMiddleDistal:`leftMiddleIntermediate`,leftRingProximal:`leftHand`,leftRingIntermediate:`leftRingProximal`,leftRingDistal:`leftRingIntermediate`,leftLittleProximal:`leftHand`,leftLittleIntermediate:`leftLittleProximal`,leftLittleDistal:`leftLittleIntermediate`,rightThumbMetacarpal:`rightHand`,rightThumbProximal:`rightThumbMetacarpal`,rightThumbDistal:`rightThumbProximal`,rightIndexProximal:`rightHand`,rightIndexIntermediate:`rightIndexProximal`,rightIndexDistal:`rightIndexIntermediate`,rightMiddleProximal:`rightHand`,rightMiddleIntermediate:`rightMiddleProximal`,rightMiddleDistal:`rightMiddleIntermediate`,rightRingProximal:`rightHand`,rightRingIntermediate:`rightRingProximal`,rightRingDistal:`rightRingIntermediate`,rightLittleProximal:`rightHand`,rightLittleIntermediate:`rightLittleProximal`,rightLittleDistal:`rightLittleIntermediate`};function Ly(e){return e.invert?e.invert():e.inverse(),e}var Ry=new U,zy=new H,By=class{constructor(e){this.humanBones=e,this.restPose=this.getAbsolutePose()}getAbsolutePose(){let e={};return Object.keys(this.humanBones).forEach(t=>{let n=t,r=this.getBoneNode(n);r&&(Ry.copy(r.position),zy.copy(r.quaternion),e[n]={position:Ry.toArray(),rotation:zy.toArray()})}),e}getPose(){let e={};return Object.keys(this.humanBones).forEach(t=>{let n=t,r=this.getBoneNode(n);if(!r)return;Ry.set(0,0,0),zy.identity();let i=this.restPose[n];i?.position&&Ry.fromArray(i.position).negate(),i?.rotation&&Ly(zy.fromArray(i.rotation)),Ry.add(r.position),zy.premultiply(r.quaternion),e[n]={position:Ry.toArray(),rotation:zy.toArray()}}),e}setPose(e){Object.entries(e).forEach(([e,t])=>{let n=e,r=this.getBoneNode(n);if(!r)return;let i=this.restPose[n];i&&(t?.position&&(r.position.fromArray(t.position),i.position&&r.position.add(Ry.fromArray(i.position))),t?.rotation&&(r.quaternion.fromArray(t.rotation),i.rotation&&r.quaternion.multiply(zy.fromArray(i.rotation))))})}resetPose(){Object.entries(this.restPose).forEach(([e,t])=>{let n=this.getBoneNode(e);n&&(t?.position&&n.position.fromArray(t.position),t?.rotation&&n.quaternion.fromArray(t.rotation))})}getBone(e){return this.humanBones[e]??void 0}getBoneNode(e){return this.humanBones[e]?.node??null}},Vy=new U,Hy=new H,Uy=new U,Wy=class e extends By{static _setupTransforms(e){let t=new go;t.name=`VRMHumanoidRig`;let n={},r={},i={},a={};Fy.forEach(t=>{var o;let s=e.getBoneNode(t);if(s){let e=new U,c=new H;s.updateWorldMatrix(!0,!1),s.matrixWorld.decompose(e,c,Vy),n[t]=e,r[t]=c,i[t]=s.quaternion.clone();let l=new H;(o=s.parent)==null||o.matrixWorld.decompose(Vy,l,Vy),a[t]=l}});let o={};return Fy.forEach(r=>{let i=e.getBoneNode(r);if(i){let e=n[r],a=r,s;for(;s==null&&(a=Iy[a],a!=null);)s=n[a];let c=new go;c.name=`Normalized_`+i.name,(a?o[a]?.node:t).add(c),c.position.copy(e),s&&c.position.sub(s),o[r]={node:c}}}),{rigBones:o,root:t,parentWorldRotations:a,boneRotations:i}}constructor(t){let{rigBones:n,root:r,parentWorldRotations:i,boneRotations:a}=e._setupTransforms(t);super(n),this.original=t,this.root=r,this._parentWorldRotations=i,this._boneRotations=a}update(){Fy.forEach(e=>{let t=this.original.getBoneNode(e);if(t!=null){let n=this.getBoneNode(e),r=this._parentWorldRotations[e],i=Hy.copy(r).invert(),a=this._boneRotations[e];if(t.quaternion.copy(n.quaternion).multiply(r).premultiply(i).multiply(a),e===`hips`){let e=n.getWorldPosition(Uy);t.parent.updateWorldMatrix(!0,!1);let r=t.parent.matrixWorld,i=e.applyMatrix4(r.invert());t.position.copy(i)}}})}},Gy=class e{get restPose(){return console.warn(`VRMHumanoid: restPose is deprecated. Use either rawRestPose or normalizedRestPose instead.`),this.rawRestPose}get rawRestPose(){return this._rawHumanBones.restPose}get normalizedRestPose(){return this._normalizedHumanBones.restPose}get humanBones(){return this._rawHumanBones.humanBones}get rawHumanBones(){return this._rawHumanBones.humanBones}get normalizedHumanBones(){return this._normalizedHumanBones.humanBones}get normalizedHumanBonesRoot(){return this._normalizedHumanBones.root}constructor(e,t){this.autoUpdateHumanBones=t?.autoUpdateHumanBones??!0,this._rawHumanBones=new By(e),this._normalizedHumanBones=new Wy(this._rawHumanBones)}copy(e){return this.autoUpdateHumanBones=e.autoUpdateHumanBones,this._rawHumanBones=new By(e.humanBones),this._normalizedHumanBones=new Wy(this._rawHumanBones),this}clone(){return new e(this.humanBones,{autoUpdateHumanBones:this.autoUpdateHumanBones}).copy(this)}getAbsolutePose(){return console.warn(`VRMHumanoid: getAbsolutePose() is deprecated. Use either getRawAbsolutePose() or getNormalizedAbsolutePose() instead.`),this.getRawAbsolutePose()}getRawAbsolutePose(){return this._rawHumanBones.getAbsolutePose()}getNormalizedAbsolutePose(){return this._normalizedHumanBones.getAbsolutePose()}getPose(){return console.warn(`VRMHumanoid: getPose() is deprecated. Use either getRawPose() or getNormalizedPose() instead.`),this.getRawPose()}getRawPose(){return this._rawHumanBones.getPose()}getNormalizedPose(){return this._normalizedHumanBones.getPose()}setPose(e){return console.warn(`VRMHumanoid: setPose() is deprecated. Use either setRawPose() or setNormalizedPose() instead.`),this.setRawPose(e)}setRawPose(e){return this._rawHumanBones.setPose(e)}setNormalizedPose(e){return this._normalizedHumanBones.setPose(e)}resetPose(){return console.warn(`VRMHumanoid: resetPose() is deprecated. Use either resetRawPose() or resetNormalizedPose() instead.`),this.resetRawPose()}resetRawPose(){return this._rawHumanBones.resetPose()}resetNormalizedPose(){return this._normalizedHumanBones.resetPose()}getBone(e){return console.warn(`VRMHumanoid: getBone() is deprecated. Use either getRawBone() or getNormalizedBone() instead.`),this.getRawBone(e)}getRawBone(e){return this._rawHumanBones.getBone(e)}getNormalizedBone(e){return this._normalizedHumanBones.getBone(e)}getBoneNode(e){return console.warn(`VRMHumanoid: getBoneNode() is deprecated. Use either getRawBoneNode() or getNormalizedBoneNode() instead.`),this.getRawBoneNode(e)}getRawBoneNode(e){return this._rawHumanBones.getBoneNode(e)}getNormalizedBoneNode(e){return this._normalizedHumanBones.getBoneNode(e)}update(){this.autoUpdateHumanBones&&this._normalizedHumanBones.update()}},Ky={Hips:`hips`,Spine:`spine`,Head:`head`,LeftUpperLeg:`leftUpperLeg`,LeftLowerLeg:`leftLowerLeg`,LeftFoot:`leftFoot`,RightUpperLeg:`rightUpperLeg`,RightLowerLeg:`rightLowerLeg`,RightFoot:`rightFoot`,LeftUpperArm:`leftUpperArm`,LeftLowerArm:`leftLowerArm`,LeftHand:`leftHand`,RightUpperArm:`rightUpperArm`,RightLowerArm:`rightLowerArm`,RightHand:`rightHand`},qy=new Set([`1.0`,`1.0-beta`]),Jy={leftThumbProximal:`leftThumbMetacarpal`,leftThumbIntermediate:`leftThumbProximal`,rightThumbProximal:`rightThumbMetacarpal`,rightThumbIntermediate:`rightThumbProximal`},Yy=class{get name(){return`VRMHumanoidLoaderPlugin`}constructor(e,t){this.parser=e,this.helperRoot=t?.helperRoot,this.autoUpdateHumanBones=t?.autoUpdateHumanBones}afterRoot(e){return sy(this,null,function*(){e.userData.vrmHumanoid=yield this._import(e)})}_import(e){return sy(this,null,function*(){return(yield this._v1Import(e))||(yield this._v0Import(e))||null})}_v1Import(e){return sy(this,null,function*(){let t=this.parser.json;if(t.extensionsUsed?.indexOf(`VRMC_vrm`)===-1)return null;let n=t.extensions?.VRMC_vrm;if(!n)return null;let r=n.specVersion;if(!qy.has(r))return console.warn(`VRMHumanoidLoaderPlugin: Unknown VRMC_vrm specVersion "${r}"`),null;let i=n.humanoid;if(!i)return null;let a=i.humanBones.leftThumbIntermediate!=null||i.humanBones.rightThumbIntermediate!=null,o={};i.humanBones!=null&&(yield Promise.all(Object.entries(i.humanBones).map(e=>sy(this,[e],function*([e,t]){let n=e,r=t.node;if(a){let e=Jy[n];e!=null&&(n=e)}let i=yield this.parser.getDependency(`node`,r);if(i==null){console.warn(`A glTF node bound to the humanoid bone ${n} (index = ${r}) does not exist`);return}o[n]={node:i}}))));let s=new Gy(this._ensureRequiredBonesExist(o),{autoUpdateHumanBones:this.autoUpdateHumanBones});if(e.scene.add(s.normalizedHumanBonesRoot),this.helperRoot){let e=new Py(s);this.helperRoot.add(e),e.renderOrder=this.helperRoot.renderOrder}return s})}_v0Import(e){return sy(this,null,function*(){let t=this.parser.json.extensions?.VRM;if(!t)return null;let n=t.humanoid;if(!n)return null;let r={};n.humanBones!=null&&(yield Promise.all(n.humanBones.map(e=>sy(this,null,function*(){let t=e.bone,n=e.node;if(t==null||n==null)return;let i=yield this.parser.getDependency(`node`,n);if(i==null){console.warn(`A glTF node bound to the humanoid bone ${t} (index = ${n}) does not exist`);return}let a=Jy[t]??t;if(r[a]!=null){console.warn(`Multiple bone entries for ${a} detected (index = ${n}), ignoring duplicated entries.`);return}r[a]={node:i}}))));let i=new Gy(this._ensureRequiredBonesExist(r),{autoUpdateHumanBones:this.autoUpdateHumanBones});if(e.scene.add(i.normalizedHumanBonesRoot),this.helperRoot){let e=new Py(i);this.helperRoot.add(e),e.renderOrder=this.helperRoot.renderOrder}return i})}_ensureRequiredBonesExist(e){let t=Object.values(Ky).filter(t=>e[t]==null);if(t.length>0)throw Error(`VRMHumanoidLoaderPlugin: These humanoid bones are required but not exist: ${t.join(`, `)}`);return e}},Xy=class extends J{constructor(){super(),this._currentTheta=0,this._currentRadius=0,this.theta=0,this.radius=0,this._currentTheta=0,this._currentRadius=0,this._attrPos=new q(new Float32Array(195),3),this.setAttribute(`position`,this._attrPos),this._attrIndex=new q(new Uint16Array(189),1),this.setIndex(this._attrIndex),this._buildIndex(),this.update()}update(){let e=!1;this._currentTheta!==this.theta&&(this._currentTheta=this.theta,e=!0),this._currentRadius!==this.radius&&(this._currentRadius=this.radius,e=!0),e&&this._buildPosition()}_buildPosition(){this._attrPos.setXYZ(0,0,0,0);for(let e=0;e<64;e++){let t=e/63*this._currentTheta;this._attrPos.setXYZ(e+1,this._currentRadius*Math.sin(t),0,this._currentRadius*Math.cos(t))}this._attrPos.needsUpdate=!0}_buildIndex(){for(let e=0;e<63;e++)this._attrIndex.setXYZ(e*3,0,e+1,e+2);this._attrIndex.needsUpdate=!0}},Zy=class extends J{constructor(){super(),this.radius=0,this._currentRadius=0,this.tail=new U,this._currentTail=new U,this._attrPos=new q(new Float32Array(294),3),this.setAttribute(`position`,this._attrPos),this._attrIndex=new q(new Uint16Array(194),1),this.setIndex(this._attrIndex),this._buildIndex(),this.update()}update(){let e=!1;this._currentRadius!==this.radius&&(this._currentRadius=this.radius,e=!0),this._currentTail.equals(this.tail)||(this._currentTail.copy(this.tail),e=!0),e&&this._buildPosition()}_buildPosition(){for(let e=0;e<32;e++){let t=e/16*Math.PI;this._attrPos.setXYZ(e,Math.cos(t),Math.sin(t),0),this._attrPos.setXYZ(32+e,0,Math.cos(t),Math.sin(t)),this._attrPos.setXYZ(64+e,Math.sin(t),0,Math.cos(t))}this.scale(this._currentRadius,this._currentRadius,this._currentRadius),this.translate(this._currentTail.x,this._currentTail.y,this._currentTail.z),this._attrPos.setXYZ(96,0,0,0),this._attrPos.setXYZ(97,this._currentTail.x,this._currentTail.y,this._currentTail.z),this._attrPos.needsUpdate=!0}_buildIndex(){for(let e=0;e<32;e++){let t=(e+1)%32;this._attrIndex.setXY(e*2,e,t),this._attrIndex.setXY(64+e*2,32+e,32+t),this._attrIndex.setXY(128+e*2,64+e,64+t)}this._attrIndex.setXY(192,96,97),this._attrIndex.needsUpdate=!0}},Qy=new H,$y=new H,eb=new U,tb=new U,nb=Math.sqrt(2)/2,rb=new H(0,0,-nb,nb),ib=new U(0,1,0),ab=class extends _o{constructor(e){super(),this.matrixAutoUpdate=!1,this.vrmLookAt=e;{let e=new Xy;e.radius=.5;let t=new Ls({color:65280,transparent:!0,opacity:.5,side:2,depthTest:!1,depthWrite:!1});this._meshPitch=new Ys(e,t),this.add(this._meshPitch)}{let e=new Xy;e.radius=.5;let t=new Ls({color:16711680,transparent:!0,opacity:.5,side:2,depthTest:!1,depthWrite:!1});this._meshYaw=new Ys(e,t),this.add(this._meshYaw)}{let e=new Zy;e.radius=.1;let t=new Ac({color:16777215,depthTest:!1,depthWrite:!1});this._lineTarget=new Hc(e,t),this._lineTarget.frustumCulled=!1,this.add(this._lineTarget)}}dispose(){this._meshYaw.geometry.dispose(),this._meshYaw.material.dispose(),this._meshPitch.geometry.dispose(),this._meshPitch.material.dispose(),this._lineTarget.geometry.dispose(),this._lineTarget.material.dispose()}updateMatrixWorld(e){let t=ba.DEG2RAD*this.vrmLookAt.yaw;this._meshYaw.geometry.theta=t,this._meshYaw.geometry.update();let n=ba.DEG2RAD*this.vrmLookAt.pitch;this._meshPitch.geometry.theta=n,this._meshPitch.geometry.update(),this.vrmLookAt.getLookAtWorldPosition(eb),this.vrmLookAt.getLookAtWorldQuaternion(Qy),Qy.multiply(this.vrmLookAt.getFaceFrontQuaternion($y)),this._meshYaw.position.copy(eb),this._meshYaw.quaternion.copy(Qy),this._meshPitch.position.copy(eb),this._meshPitch.quaternion.copy(Qy),this._meshPitch.quaternion.multiply($y.setFromAxisAngle(ib,t)),this._meshPitch.quaternion.multiply(rb);let{target:r,autoUpdate:i}=this.vrmLookAt;r!=null&&i&&(r.getWorldPosition(tb).sub(eb),this._lineTarget.geometry.tail.copy(tb),this._lineTarget.geometry.update(),this._lineTarget.position.copy(eb)),super.updateMatrixWorld(e)}},ob=new U,sb=new U;function cb(e,t){return e.matrixWorld.decompose(ob,t,sb),t}function lb(e){return[Math.atan2(-e.z,e.x),Math.atan2(e.y,Math.sqrt(e.x*e.x+e.z*e.z))]}function ub(e){let t=Math.round(e/2/Math.PI);return e-2*Math.PI*t}var db=new U(0,0,1),fb=new U,pb=new U,mb=new U,hb=new H,gb=new H,_b=new H,vb=new H,yb=new Qa,bb=class e{constructor(e,t){this.offsetFromHeadBone=new U,this.autoUpdate=!0,this.faceFront=new U(0,0,1),this.humanoid=e,this.applier=t,this._yaw=0,this._pitch=0,this._needsUpdate=!0,this._restHeadWorldQuaternion=this.getLookAtWorldQuaternion(new H)}get yaw(){return this._yaw}set yaw(e){this._yaw=e,this._needsUpdate=!0}get pitch(){return this._pitch}set pitch(e){this._pitch=e,this._needsUpdate=!0}get euler(){return console.warn(`VRMLookAt: euler is deprecated. use getEuler() instead.`),this.getEuler(new Qa)}getEuler(e){return e.set(ba.DEG2RAD*this._pitch,ba.DEG2RAD*this._yaw,0,`YXZ`)}copy(e){if(this.humanoid!==e.humanoid)throw Error(`VRMLookAt: humanoid must be same in order to copy`);return this.offsetFromHeadBone.copy(e.offsetFromHeadBone),this.applier=e.applier,this.autoUpdate=e.autoUpdate,this.target=e.target,this.faceFront.copy(e.faceFront),this}clone(){return new e(this.humanoid,this.applier).copy(this)}reset(){this._yaw=0,this._pitch=0,this._needsUpdate=!0}getLookAtWorldPosition(e){let t=this.humanoid.getRawBoneNode(`head`);return e.copy(this.offsetFromHeadBone).applyMatrix4(t.matrixWorld)}getLookAtWorldQuaternion(e){return cb(this.humanoid.getRawBoneNode(`head`),e)}getFaceFrontQuaternion(e){if(this.faceFront.distanceToSquared(db)<.01)return e.copy(this._restHeadWorldQuaternion).invert();let[t,n]=lb(this.faceFront);return yb.set(0,.5*Math.PI+t,n,`YZX`),e.setFromEuler(yb).premultiply(vb.copy(this._restHeadWorldQuaternion).invert())}getLookAtWorldDirection(e){return this.getLookAtWorldQuaternion(gb),this.getFaceFrontQuaternion(_b),e.copy(db).applyQuaternion(gb).applyQuaternion(_b).applyEuler(this.getEuler(yb))}lookAt(e){let t=hb.copy(this._restHeadWorldQuaternion).multiply(Ly(this.getLookAtWorldQuaternion(gb))),n=this.getLookAtWorldPosition(pb),r=mb.copy(e).sub(n).applyQuaternion(t).normalize(),[i,a]=lb(this.faceFront),[o,s]=lb(r),c=ub(o-i),l=ub(a-s);this._yaw=ba.RAD2DEG*c,this._pitch=ba.RAD2DEG*l,this._needsUpdate=!0}update(e){this.target!=null&&this.autoUpdate&&this.lookAt(this.target.getWorldPosition(fb)),this._needsUpdate&&(this._needsUpdate=!1,this.applier.applyYawPitch(this._yaw,this._pitch))}};bb.EULER_ORDER=`YXZ`;var xb=bb,Sb=new U(0,0,1),Cb=new H,wb=new H,Tb=new Qa(0,0,0,`YXZ`),Eb=class{constructor(e,t,n,r,i){this.humanoid=e,this.rangeMapHorizontalInner=t,this.rangeMapHorizontalOuter=n,this.rangeMapVerticalDown=r,this.rangeMapVerticalUp=i,this.faceFront=new U(0,0,1),this._restQuatLeftEye=new H,this._restQuatRightEye=new H,this._restLeftEyeParentWorldQuat=new H,this._restRightEyeParentWorldQuat=new H;let a=this.humanoid.getRawBoneNode(`leftEye`),o=this.humanoid.getRawBoneNode(`rightEye`);a&&(this._restQuatLeftEye.copy(a.quaternion),cb(a.parent,this._restLeftEyeParentWorldQuat)),o&&(this._restQuatRightEye.copy(o.quaternion),cb(o.parent,this._restRightEyeParentWorldQuat))}applyYawPitch(e,t){let n=this.humanoid.getRawBoneNode(`leftEye`),r=this.humanoid.getRawBoneNode(`rightEye`),i=this.humanoid.getNormalizedBoneNode(`leftEye`),a=this.humanoid.getNormalizedBoneNode(`rightEye`);n&&(t<0?Tb.x=-ba.DEG2RAD*this.rangeMapVerticalDown.map(-t):Tb.x=ba.DEG2RAD*this.rangeMapVerticalUp.map(t),e<0?Tb.y=-ba.DEG2RAD*this.rangeMapHorizontalInner.map(-e):Tb.y=ba.DEG2RAD*this.rangeMapHorizontalOuter.map(e),Cb.setFromEuler(Tb),this._getWorldFaceFrontQuat(wb),i.quaternion.copy(wb).multiply(Cb).multiply(wb.invert()),Cb.copy(this._restLeftEyeParentWorldQuat),n.quaternion.copy(i.quaternion).multiply(Cb).premultiply(Cb.invert()).multiply(this._restQuatLeftEye)),r&&(t<0?Tb.x=-ba.DEG2RAD*this.rangeMapVerticalDown.map(-t):Tb.x=ba.DEG2RAD*this.rangeMapVerticalUp.map(t),e<0?Tb.y=-ba.DEG2RAD*this.rangeMapHorizontalOuter.map(-e):Tb.y=ba.DEG2RAD*this.rangeMapHorizontalInner.map(e),Cb.setFromEuler(Tb),this._getWorldFaceFrontQuat(wb),a.quaternion.copy(wb).multiply(Cb).multiply(wb.invert()),Cb.copy(this._restRightEyeParentWorldQuat),r.quaternion.copy(a.quaternion).multiply(Cb).premultiply(Cb.invert()).multiply(this._restQuatRightEye))}lookAt(e){console.warn(`VRMLookAtBoneApplier: lookAt() is deprecated. use apply() instead.`);let t=ba.RAD2DEG*e.y,n=ba.RAD2DEG*e.x;this.applyYawPitch(t,n)}_getWorldFaceFrontQuat(e){if(this.faceFront.distanceToSquared(Sb)<.01)return e.identity();let[t,n]=lb(this.faceFront);return Tb.set(0,.5*Math.PI+t,n,`YZX`),e.setFromEuler(Tb)}};Eb.type=`bone`;var Db=class{constructor(e,t,n,r,i){this.expressions=e,this.rangeMapHorizontalInner=t,this.rangeMapHorizontalOuter=n,this.rangeMapVerticalDown=r,this.rangeMapVerticalUp=i}applyYawPitch(e,t){t<0?(this.expressions.setValue(`lookDown`,0),this.expressions.setValue(`lookUp`,this.rangeMapVerticalUp.map(-t))):(this.expressions.setValue(`lookUp`,0),this.expressions.setValue(`lookDown`,this.rangeMapVerticalDown.map(t))),e<0?(this.expressions.setValue(`lookLeft`,0),this.expressions.setValue(`lookRight`,this.rangeMapHorizontalOuter.map(-e))):(this.expressions.setValue(`lookRight`,0),this.expressions.setValue(`lookLeft`,this.rangeMapHorizontalOuter.map(e)))}lookAt(e){console.warn(`VRMLookAtBoneApplier: lookAt() is deprecated. use apply() instead.`);let t=ba.RAD2DEG*e.y,n=ba.RAD2DEG*e.x;this.applyYawPitch(t,n)}};Db.type=`expression`;var Ob=class{constructor(e,t){this.inputMaxValue=e,this.outputScale=t}map(e){return this.outputScale*py(e/this.inputMaxValue)}},kb=new Set([`1.0`,`1.0-beta`]),Ab=.01,jb=class{get name(){return`VRMLookAtLoaderPlugin`}constructor(e,t){this.parser=e,this.helperRoot=t?.helperRoot}afterRoot(e){return sy(this,null,function*(){let t=e.userData.vrmHumanoid;if(t===null)return;if(t===void 0)throw Error(`VRMLookAtLoaderPlugin: vrmHumanoid is undefined. VRMHumanoidLoaderPlugin have to be used first`);let n=e.userData.vrmExpressionManager;if(n!==null){if(n===void 0)throw Error(`VRMLookAtLoaderPlugin: vrmExpressionManager is undefined. VRMExpressionLoaderPlugin have to be used first`);e.userData.vrmLookAt=yield this._import(e,t,n)}})}_import(e,t,n){return sy(this,null,function*(){return t==null||n==null?null:(yield this._v1Import(e,t,n))||(yield this._v0Import(e,t,n))||null})}_v1Import(e,t,n){return sy(this,null,function*(){let e=this.parser.json;if(e.extensionsUsed?.indexOf(`VRMC_vrm`)===-1)return null;let r=e.extensions?.VRMC_vrm;if(!r)return null;let i=r.specVersion;if(!kb.has(i))return console.warn(`VRMLookAtLoaderPlugin: Unknown VRMC_vrm specVersion "${i}"`),null;let a=r.lookAt;if(!a)return null;let o=a.type===`expression`?1:10,s=this._v1ImportRangeMap(a.rangeMapHorizontalInner,o),c=this._v1ImportRangeMap(a.rangeMapHorizontalOuter,o),l=this._v1ImportRangeMap(a.rangeMapVerticalDown,o),u=this._v1ImportRangeMap(a.rangeMapVerticalUp,o),d;d=a.type===`expression`?new Db(n,s,c,l,u):new Eb(t,s,c,l,u);let f=this._importLookAt(t,d);return f.offsetFromHeadBone.fromArray(a.offsetFromHeadBone??[0,.06,0]),f})}_v1ImportRangeMap(e,t){let n=e?.inputMaxValue??90,r=e?.outputScale??t;return n<Ab&&(console.warn(`VRMLookAtLoaderPlugin: inputMaxValue of a range map is too small. Consider reviewing the range map!`),n=Ab),new Ob(n,r)}_v0Import(e,t,n){return sy(this,null,function*(){let e=this.parser.json.extensions?.VRM;if(!e)return null;let r=e.firstPerson;if(!r)return null;let i=r.lookAtTypeName===`BlendShape`?1:10,a=this._v0ImportDegreeMap(r.lookAtHorizontalInner,i),o=this._v0ImportDegreeMap(r.lookAtHorizontalOuter,i),s=this._v0ImportDegreeMap(r.lookAtVerticalDown,i),c=this._v0ImportDegreeMap(r.lookAtVerticalUp,i),l;l=r.lookAtTypeName===`BlendShape`?new Db(n,a,o,s,c):new Eb(t,a,o,s,c);let u=this._importLookAt(t,l);return r.firstPersonBoneOffset?u.offsetFromHeadBone.set(r.firstPersonBoneOffset.x??0,r.firstPersonBoneOffset.y??.06,-(r.firstPersonBoneOffset.z??0)):u.offsetFromHeadBone.set(0,.06,0),u.faceFront.set(0,0,-1),l instanceof Eb&&l.faceFront.set(0,0,-1),u})}_v0ImportDegreeMap(e,t){let n=e?.curve;JSON.stringify(n)!==`[0,0,0,1,1,1,1,0]`&&console.warn(`Curves of LookAtDegreeMap defined in VRM 0.0 are not supported`);let r=e?.xRange??90,i=e?.yRange??t;return r<Ab&&(console.warn(`VRMLookAtLoaderPlugin: xRange of a degree map is too small. Consider reviewing the degree map!`),r=Ab),new Ob(r,i)}_importLookAt(e,t){let n=new xb(e,t);if(this.helperRoot){let e=new ab(n);this.helperRoot.add(e),e.renderOrder=this.helperRoot.renderOrder}return n}};function Mb(e,t){return typeof e!=`string`||e===``?``:(/^https?:\/\//i.test(t)&&/^\//.test(e)&&(t=t.replace(/(^https?:\/\/[^/]+).*/i,`$1`)),/^(https?:)?\/\//i.test(e)||/^data:.*,.*$/i.test(e)||/^blob:.*$/i.test(e)?e:t+e)}var Nb=new Set([`1.0`,`1.0-beta`]),Pb=class{get name(){return`VRMMetaLoaderPlugin`}constructor(e,t){this.parser=e,this.needThumbnailImage=t?.needThumbnailImage??!1,this.acceptLicenseUrls=t?.acceptLicenseUrls??[`https://vrm.dev/licenses/1.0/`],this.acceptV0Meta=t?.acceptV0Meta??!0}afterRoot(e){return sy(this,null,function*(){e.userData.vrmMeta=yield this._import(e)})}_import(e){return sy(this,null,function*(){return(yield this._v1Import(e))??(yield this._v0Import(e))??null})}_v1Import(e){return sy(this,null,function*(){let e=this.parser.json;if(e.extensionsUsed?.indexOf(`VRMC_vrm`)===-1)return null;let t=e.extensions?.VRMC_vrm;if(t==null)return null;let n=t.specVersion;if(!Nb.has(n))return console.warn(`VRMMetaLoaderPlugin: Unknown VRMC_vrm specVersion "${n}"`),null;let r=t.meta;if(!r)return null;let i=r.licenseUrl;if(!new Set(this.acceptLicenseUrls).has(i))throw Error(`VRMMetaLoaderPlugin: The license url "${i}" is not accepted`);let a;return this.needThumbnailImage&&r.thumbnailImage!=null&&(a=(yield this._extractGLTFImage(r.thumbnailImage))??void 0),{metaVersion:`1`,name:r.name,version:r.version,authors:r.authors,copyrightInformation:r.copyrightInformation,contactInformation:r.contactInformation,references:r.references,thirdPartyLicenses:r.thirdPartyLicenses,thumbnailImage:a,licenseUrl:r.licenseUrl,avatarPermission:r.avatarPermission,allowExcessivelyViolentUsage:r.allowExcessivelyViolentUsage,allowExcessivelySexualUsage:r.allowExcessivelySexualUsage,commercialUsage:r.commercialUsage,allowPoliticalOrReligiousUsage:r.allowPoliticalOrReligiousUsage,allowAntisocialOrHateUsage:r.allowAntisocialOrHateUsage,creditNotation:r.creditNotation,allowRedistribution:r.allowRedistribution,modification:r.modification,otherLicenseUrl:r.otherLicenseUrl}})}_v0Import(e){return sy(this,null,function*(){let e=this.parser.json.extensions?.VRM;if(!e)return null;let t=e.meta;if(!t)return null;if(!this.acceptV0Meta)throw Error(`VRMMetaLoaderPlugin: Attempted to load VRM0.0 meta but acceptV0Meta is false`);let n;return this.needThumbnailImage&&t.texture!=null&&t.texture!==-1&&(n=yield this.parser.getDependency(`texture`,t.texture)),{metaVersion:`0`,allowedUserName:t.allowedUserName,author:t.author,commercialUssageName:t.commercialUssageName,contactInformation:t.contactInformation,licenseName:t.licenseName,otherLicenseUrl:t.otherLicenseUrl,otherPermissionUrl:t.otherPermissionUrl,reference:t.reference,sexualUssageName:t.sexualUssageName,texture:n??void 0,title:t.title,version:t.version,violentUssageName:t.violentUssageName}})}_extractGLTFImage(e){return sy(this,null,function*(){let t=this.parser.json.images?.[e];if(t==null)return console.warn(`VRMMetaLoaderPlugin: Attempt to use images[${e}] of glTF as a thumbnail but the image doesn't exist`),null;let n=t.uri;if(t.bufferView!=null){let e=yield this.parser.getDependency(`bufferView`,t.bufferView),r=new Blob([e],{type:t.mimeType});n=URL.createObjectURL(r)}return n==null?(console.warn(`VRMMetaLoaderPlugin: Attempt to use images[${e}] of glTF as a thumbnail but the image couldn't load properly`),null):yield new Ql().loadAsync(Mb(n,this.parser.options.path)).catch(e=>(console.error(e),console.warn(`VRMMetaLoaderPlugin: Failed to load a thumbnail image`),null))})}},Fb=class{constructor(e){this.scene=e.scene,this.meta=e.meta,this.humanoid=e.humanoid,this.expressionManager=e.expressionManager,this.firstPerson=e.firstPerson,this.lookAt=e.lookAt}update(e){this.humanoid.update(),this.lookAt&&this.lookAt.update(e),this.expressionManager&&this.expressionManager.update()}},Ib=class extends Fb{constructor(e){super(e),this.materials=e.materials,this.springBoneManager=e.springBoneManager,this.nodeConstraintManager=e.nodeConstraintManager}update(e){super.update(e),this.nodeConstraintManager&&this.nodeConstraintManager.update(),this.springBoneManager&&this.springBoneManager.update(e),this.materials&&this.materials.forEach(t=>{t.update&&t.update(e)})}},Lb=Object.defineProperty,Rb=Object.getOwnPropertySymbols,zb=Object.prototype.hasOwnProperty,Bb=Object.prototype.propertyIsEnumerable,Vb=(e,t,n)=>t in e?Lb(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,Hb=(e,t)=>{for(var n in t||={})zb.call(t,n)&&Vb(e,n,t[n]);if(Rb)for(var n of Rb(t))Bb.call(t,n)&&Vb(e,n,t[n]);return e},Ub=(e,t,n)=>new Promise((r,i)=>{var a=e=>{try{s(n.next(e))}catch(e){i(e)}},o=e=>{try{s(n.throw(e))}catch(e){i(e)}},s=e=>e.done?r(e.value):Promise.resolve(e.value).then(a,o);s((n=n.apply(e,t)).next())});function Wb(e,t){e.colorSpace=t}var Gb=class{get pending(){return Promise.all(this._pendings)}constructor(e,t){this._parser=e,this._materialParams=t,this._pendings=[]}assignPrimitive(e,t){t!=null&&(this._materialParams[e]=t)}assignColor(e,t,n){if(t!=null){let r=new K().fromArray(t);n&&r.convertSRGBToLinear(),this._materialParams[e]=r}}assignTexture(e,t,n){return Ub(this,null,function*(){let r=Ub(this,null,function*(){if(t!=null){let r=yield this._parser.assignTexture(this._materialParams,e,t);if(r==null){console.warn(`GLTFMToonMaterialParamsAssignHelper: Failed to load texture. The rendering result may be wrong`);return}n&&Wb(r,`srgb`)}});return this._pendings.push(r),r})}assignTextureByIndex(e,t,n){return Ub(this,null,function*(){return this.assignTexture(e,t==null?void 0:{index:t},n)})}},Kb=`// #define PHONG
|
|
5756
|
+
`,colorWrite:!1,depthWrite:!0,depthTest:!1,side:2}),Zg=9.81,Qg=6,$g=.15,e_=class extends et{static props={water:{default:``,nodePath:!0},draft:{default:.35},stiffness:{default:3},damping:{default:3.5},drift:{default:.6},drag:{default:.9},samples:{default:4},size:{default:[1,1]}};static signals=[`submerged`,`surfaced`];water=``;draft=.35;stiffness=3;damping=3.5;drift=.6;drag=.9;samples=4;size=[1,1];surface=null;wet=!1;update(e){if(e<=0)return;let t=this.resolveWater();if(!t)return;let n=this.node;if(!n.applyImpulse)return;let[r,i,a]=[n.position[0]??0,n.position[1]??0,n.position[2]??0],o=[(this.size[0]??1)/2,(this.size[1]??1)/2],s=this.samplePoints(r,a,o[0],o[1]),c=n.mass??1,l=n.linearVelocity??[0,0,0],u=0,d=0,f=0,p=0;for(let[e,n]of s){let r=t.heightAt(e,n)-(i-this.draft);if(r<=0)continue;p++,u+=Zg*(1+this.stiffness*(r/Math.max(this.draft,$g)));let a=.6;d+=t.heightAt(e+a,n)-t.heightAt(e-a,n),f+=t.heightAt(e,n+a)-t.heightAt(e,n-a)}let m=p>0;if(m!==this.wet&&(this.wet=m,this.emit(m?`submerged`:`surfaced`,this.node)),!m)return;let h=p/s.length,g=Math.min(u/s.length-this.damping*(l[1]??0),Qg*Zg)*e*c,_=(-d*this.drift*12-(l[0]??0)*this.drag)*h*e*c,v=(-f*this.drift*12-(l[2]??0)*this.drag)*h*e*c;n.applyImpulse([_,g,v])}samplePoints(e,t,n,r){let i=Math.max(1,Math.round(this.samples));if(i===1)return[[e,t]];let a=[];for(let o=0;o<i;o++){let s=o/i*Math.PI*2+Math.PI/4;a.push([e+Math.cos(s)*n,t+Math.sin(s)*r])}return a}resolveWater(){if(this.surface)return this.surface;if(this.water!==``){let e=this.node.getNodeOrNull(this.water);if(!(e instanceof _g))throw new N(`NODE_NOT_FOUND`,`Buoyancy on '${this.node.getPath()}': water '${this.water}' is not a Water3D in the tree.`,{prop:`water`});return this.surface=e,e}return this.surface=t_(this.node.getRoot()),this.surface}};function t_(e){if(e instanceof _g)return e;for(let t of e.children){let e=t_(t);if(e)return e}return null}function n_(e){return Array.isArray(e.position)}function r_(e){let t=e.node;if(!n_(t)){let n=e.constructor.name;throw new N(`PROP_TYPE_MISMATCH`,`${n} on '${t.getPath()}' needs a spatial node with a numeric 'position' array (a Node2D/Node3D subtype). '${t.name}' has none.`,{path:t.getPath()})}return t}function i_(e,t){let n=0,r=Math.max(e.length,t.length);for(let i=0;i<r;i++){let r=(e[i]??0)-(t[i]??0);n+=r*r}return Math.sqrt(n)}function a_(e,t){let n=Math.max(e.length,t.length),r=Array(n);for(let i=0;i<n;i++)r[i]=(e[i]??0)+(t[i]??0);return r}function o_(e){let t=0;for(let n of e)t+=n*n;return Math.sqrt(t)}function s_(e){let t=o_(e);return t===0?e.map(()=>0):e.map(e=>e/t)}function c_(e,t,n){let r=Math.max(e.length,t.length),i=0;for(let n=0;n<r;n++){let r=(t[n]??0)-(e[n]??0);i+=r*r}let a=Math.sqrt(i),o=Array(r);if(a<=n||a===0){for(let e=0;e<r;e++)o[e]=t[e]??0;return{position:o,reached:!0}}let s=n/a;for(let n=0;n<r;n++){let r=e[n]??0;o[n]=r+((t[n]??0)-r)*s}return{position:o,reached:!1}}function l_(e,t){let n=Math.min(Math.max(e,0),.99);return n<=0?1:1-n**(t*60)}var u_=class extends et{static props={target:{default:``,nodePath:!0},speed:{default:60},stopRange:{default:0},loseRange:{default:0},moveParent:{default:!1}};static signals=[`reachedTarget`,`lostTarget`];target=``;speed=60;stopRange=0;loseRange=0;moveParent=!1;inRange=!1;lost=!1;onReady(){if(this.target===``)throw new N(`PROP_TYPE_MISMATCH`,`Chase on '${this.node.getPath()}': "target" (a node path) is required.`,{prop:`target`});if(this.moveParent){let e=this.node.parent;if(!e||!n_(e))throw new N(`PROP_TYPE_MISMATCH`,`Chase on '${this.node.getPath()}': "moveParent" needs a spatial parent (a Node2D/Node3D) to move. '${this.node.name}' has none.`,{prop:`moveParent`,path:this.node.getPath()})}else r_(this)}update(e){let t=this.moveParent?this.node.parent:this.node;if(!t||!n_(t))return;let n=this.node.getNodeOrNull(this.target);if(!n||!n_(n))return;let r=i_(t.position,n.position);if(this.loseRange>0&&r>this.loseRange){this.lost||(this.lost=!0,this.inRange=!1,this.emit(`lostTarget`));return}if(this.lost=!1,this.stopRange>0&&r<=this.stopRange){this.inRange||(this.inRange=!0,this.emit(`reachedTarget`));return}this.inRange=!1;let i=Math.min(this.speed*e,this.stopRange>0?r-this.stopRange:r),{position:a}=c_(t.position,n.position,Math.max(0,i));t.position=a}},d_=class extends et{static props={button:{default:0},maxDistance:{default:0},enabled:{default:!0}};static signals=[`clicked`,`hovered`,`unhovered`];button=0;maxDistance=0;enabled=!0;hovering=!1;pressedHere=!1;update(){let e=this.node.tree?.engine;if(!e||!this.enabled)return;let t=e.picker,n=e.input.pointerPosition();if(!t||!n){this.hovering&&this.setHover(!1);return}let r=t(n.x,n.y),i=r!==null&&this.isSelfOrDescendant(r)&&this.withinRange(r);i!==this.hovering&&this.setHover(i),e.input.mouseJustPressed(this.button)&&(this.pressedHere=i),e.input.mouseJustReleased(this.button)&&(this.pressedHere&&i&&this.emit(`clicked`,this.node),this.pressedHere=!1)}setHover(e){this.hovering=e,this.emit(e?`hovered`:`unhovered`,this.node)}isSelfOrDescendant(e){for(let t=e;t;t=t.parent)if(t===this.node)return!0;return!1}withinRange(e){if(this.maxDistance<=0||!this.node.tree?.engine?.scene?.root)return!0;let t=this.node.position,n=e.position;if(!Array.isArray(t)||!Array.isArray(n))return!0;let r=0;for(let e=0;e<Math.max(t.length,n.length);e++){let i=(t[e]??0)-(n[e]??0);r+=i*i}return Math.sqrt(r)<=this.maxDistance}},f_=class extends et{static props={group:{default:`player`}};static signals=[`totalChanged`];group=`player`;total=0;onReady(){this.node.addToGroup(this.group)}collect(e){this.total+=e,this.emit(`totalChanged`,this.total)}serialize(){return{total:this.total}}deserialize(e){let t=e;typeof t.total==`number`&&(this.total=t.total)}},p_=class extends et{static props={max:{default:100},regenPerSec:{default:0},invulnerableFor:{default:0},freeOnDeath:{default:!1}};static signals=[`damaged`,`healed`,`died`];max=100;regenPerSec=0;invulnerableFor=0;freeOnDeath=!1;current=0;invulnTimer=0;dead=!1;get isDead(){return this.dead}get invulnerableRemaining(){return this.invulnTimer}onReady(){if(!(this.max>0))throw new N(`PROP_TYPE_MISMATCH`,`Health on '${this.node.getPath()}': "max" must be > 0, got ${this.max}.`,{prop:`max`});if(this.regenPerSec<0)throw new N(`PROP_TYPE_MISMATCH`,`Health on '${this.node.getPath()}': "regenPerSec" must be >= 0, got ${this.regenPerSec}.`,{prop:`regenPerSec`});if(this.invulnerableFor<0)throw new N(`PROP_TYPE_MISMATCH`,`Health on '${this.node.getPath()}': "invulnerableFor" must be >= 0, got ${this.invulnerableFor}.`,{prop:`invulnerableFor`});this.current=this.max}update(e){this.invulnTimer>0&&(this.invulnTimer=Math.max(0,this.invulnTimer-e)),this.regenPerSec>0&&!this.dead&&this.current<this.max&&this.setCurrent(this.current+this.regenPerSec*e)}damage(e){this.dead||e<=0||this.invulnTimer>0||(this.setCurrent(this.current-e),this.emit(`damaged`,e,this.current),this.invulnerableFor>0&&(this.invulnTimer=this.invulnerableFor),this.current<=0&&this.die())}heal(e){this.dead||e<=0||(this.setCurrent(this.current+e),this.emit(`healed`,e,this.current))}kill(){this.dead||(this.setCurrent(0),this.die())}setCurrent(e){this.current=Math.max(0,Math.min(this.max,e))}die(){this.dead||(this.dead=!0,this.current=0,this.emit(`died`),this.freeOnDeath&&this.node.queueFree())}serialize(){return{current:this.current,dead:this.dead}}deserialize(e){let t=e;typeof t.current==`number`&&(this.current=Math.min(this.max,Math.max(0,t.current))),typeof t.dead==`boolean`&&(this.dead=t.dead)}};function m_(e,t){let n=e.node;if(!n.declaredSignalNames().includes(`triggerEnter`)){let t=e.constructor.name;throw new N(`UNKNOWN_SIGNAL`,`${t} on '${n.getPath()}' needs a node that emits 'triggerEnter' — attach it to an Area2D/Area3D (or another body that declares the collision signals). '${n.name}' declares: [${n.declaredSignalNames().join(`, `)}].`,{signal:`triggerEnter`,path:n.getPath()})}n.on(`triggerEnter`,e=>t(e))}var h_=class extends et{static props={amount:{default:10},targetGroup:{default:``},oncePerTarget:{default:!0},repeatEvery:{default:0},destroySelf:{default:!1}};static signals=[`dealtDamage`];amount=10;targetGroup=``;oncePerTarget=!0;repeatEvery=0;destroySelf=!1;hit=new WeakSet;inside=new Map;onReady(){m_(this,e=>{this.inside.set(e,this.repeatEvery),this.tryDamage(e)}),this.node.on(`triggerExit`,e=>{this.inside.delete(e)})}update(e){if(!(this.repeatEvery<=0||this.inside.size===0))for(let[t,n]of this.inside){if(!t.tree){this.inside.delete(t);continue}let r=n-e;r>0?this.inside.set(t,r):(this.inside.set(t,this.repeatEvery),this.tryDamage(t,{repeat:!0}))}}tryDamage(e,t){if(!t?.repeat&&this.oncePerTarget&&this.hit.has(e))return;let n=g_(e);n&&(this.targetGroup!==``&&!n.owner.isInGroup(this.targetGroup)||(this.oncePerTarget&&this.hit.add(e),n.health.damage(this.amount),this.emit(`dealtDamage`,this.amount,n.owner),this.destroySelf&&this.node.queueFree()))}};function g_(e){let t=[e];for(;t.length>0;){let e=t.shift();if(e.behavior instanceof p_)return{health:e.behavior,owner:e};t.push(...e.children)}for(let t=e.parent;t;t=t.parent)if(t.behavior instanceof p_)return{health:t.behavior,owner:t};return null}var __=class extends et{static signals=[`dayPhaseChanged`];static props={daySeconds:{default:240},startHour:{default:10},maxSunElevationDeg:{default:55},nightDarkness:{default:.75},paused:{default:!1}};daySeconds=240;startHour=10;maxSunElevationDeg=55;nightDarkness=.75;paused=!1;hour=0;phase=``;applyClock=0;baseAmbient=.3;baseExposure=1;captured=!1;onReady(){this.hour=this.startHour}update(e){if(this.paused||(this.hour=(this.hour+e/this.daySeconds*24)%24),this.applyClock-=e,this.applyClock>0)return;this.applyClock=.2,this.applyHour();let t=v_(this.hour);t!==this.phase&&(this.phase=t,this.emit(`dayPhaseChanged`,t))}applyHour(){let e=this.node.tree?.engine,t=e?.scene?.environment;if(!e||!t?.sky)return;this.captured||(this.captured=!0,this.baseAmbient=t.ambient?.intensity??.3,this.baseExposure=t.exposure??1);let n=(this.hour-6)/12*Math.PI,r=Math.sin(n);t.sky.elevationDeg=r*this.maxSunElevationDeg+(r<0?r*10:0),t.sky.azimuthDeg=this.hour/24*360+90;let i=Math.max(0,r),a=this.nightDarkness;t.ambient={...t.ambient??{},intensity:this.baseAmbient*(1-a+a*i)},t.exposure=this.baseExposure*(1-a*.55*(1-i))}};function v_(e){return e<5||e>=20?`night`:e<7.5?`dawn`:e<17.5?`day`:`dusk`}var y_=class extends et{static props={target:{default:``,nodePath:!0},offset:{default:[]},smoothing:{default:0},deadzone:{default:0}};static signals=[];target=``;offset=[];smoothing=0;deadzone=0;onReady(){if(this.target===``)throw new N(`PROP_TYPE_MISMATCH`,`FollowCamera on '${this.node.getPath()}': "target" (a node path) is required.`,{prop:`target`});if(this.deadzone<0)throw new N(`PROP_TYPE_MISMATCH`,`FollowCamera on '${this.node.getPath()}': "deadzone" must be >= 0, got ${this.deadzone}.`,{prop:`deadzone`});r_(this)}shakeMag=0;shakeT=0;shakeFalloff=.28;shake(e,t=.28){this.shakeMag=Math.max(this.shakeMag,e),this.shakeT=t,this.shakeFalloff=t}update(e){let t=this.node;if(!n_(t))return;let n=t.getNodeOrNull(this.target);if(!n||!n_(n))return;let r=a_(n.position,this.offset);if(!(this.deadzone>0&&i_(t.position,r)<=this.deadzone)){let n=l_(this.smoothing,e);n>=1?t.position=[...r]:t.position=t.position.map((e,t)=>e+((r[t]??e)-e)*n)}if(this.shakeT>0){this.shakeT-=e;let n=this.shakeMag*Math.max(0,this.shakeT)/this.shakeFalloff;this.shakeT<=0&&(this.shakeMag=0);let r=t.position.slice();for(let e=0;e<r.length;e++){let t=r.length>=3&&e===1?.5:1;r[e]=(r[e]??0)+(this.engine.rng.next()*2-1)*n*t}t.position=r}}};function b_(e){let t=e.scene?.source;t&&(e.timeScale=1,e.setScene(An(He(t))))}function x_(e,t,n){let r=n?.fadeSeconds??.4,i=()=>{e.timeScale=1,e.setScene(An(He(t)))};if(typeof document>`u`||r<=0){i();return}let a=`incanto-scene-fade`,o=document.getElementById(a);o||(o=document.createElement(`div`),o.id=a,o.style.cssText=`position:fixed;inset:0;z-index:10001;background:#000;opacity:0;pointer-events:none;`,document.body.appendChild(o)),o.style.transition=`opacity ${r/2}s`,o.style.opacity=`1`,setTimeout(()=>{i();let e=document.getElementById(a);e&&(e.style.opacity=`0`,setTimeout(()=>e.remove(),r*500+60))},r*500+30)}var S_=class extends et{static signals=[`flowChanged`];static props={restartAction:{default:`restart`},freezeOnEnd:{default:!0},bannerPath:{default:`%Banner`,nodePath:!0}};restartAction=`restart`;freezeOnEnd=!0;bannerPath=`%Banner`;state=`playing`;frozeScale=!1;gameOver(e=`GAME OVER`,t=`#ef4444`){this.transition(`gameover`,e,t)}win(e=`YOU WIN`,t=`#4ade80`){this.transition(`won`,e,t)}pause(){this.state===`playing`&&(this.state=`paused`,this.freeze(),this.node.emit(`flowChanged`,this.state))}resume(){this.state===`paused`&&(this.state=`playing`,this.thaw(),this.node.emit(`flowChanged`,this.state))}restart(){this.thaw(),b_(this.engine)}goToScene(e,t){this.thaw(),x_(this.engine,e,t)}transition(e,t,n){this.state===`gameover`||this.state===`won`||(this.state=e,this.freezeOnEnd&&this.freeze(),this.bannerPath!==``&&this.node.getNodeOrNull(this.bannerPath)?.show(t,{color:n,seconds:0}),this.node.emit(`flowChanged`,e))}freeze(){this.frozeScale||(this.frozeScale=!0,this.engine.timeScale=0)}thaw(){this.frozeScale&&(this.frozeScale=!1,this.engine.timeScale=1)}update(){if(!(this.state!==`gameover`&&this.state!==`won`))try{this.engine.input.justPressed(this.restartAction)&&this.restart()}catch{}}};function C_(e){return Array.isArray(e.position)}function w_(e,t){let n=0,r=Math.max(e.length,t.length);for(let i=0;i<r;i++){let r=(e[i]??0)-(t[i]??0);n+=r*r}return Math.sqrt(n)}var T_=class extends et{static props={action:{default:`interact`},range:{default:2},actorGroup:{default:`player`}};static signals=[`interacted`];action=`interact`;range=2;actorGroup=`player`;update(){let e=this.node.tree?.engine;if(!e?.scene||!e.input.justPressed(this.action)||!C_(this.node))return;let t=this.node.position,n=null,r=1/0,i=this.node.tree?.getNodesInGroup(this.actorGroup)??E_(this.node.getRoot(),this.actorGroup);for(let e of i){if(!C_(e))continue;let i=w_(t,e.position);i<=this.range&&i<r&&(n=e,r=i)}n&&this.emit(`interacted`,n)}};function E_(e,t){let n=[],r=e=>{e.isInGroup(t)&&n.push(e);for(let t of e.children)r(t)};return r(e),n}var D_=.28,O_=class extends et{static props={falloff:{default:D_}};falloff=D_;magnitude=0;t=0;prev=[];shake(e,t){this.magnitude=Math.max(this.magnitude,e),this.t=t??this.falloff}update(e){let t=r_(this),n=t.position;for(let e=0;e<this.prev.length;e++)n[e]=(n[e]??0)-(this.prev[e]??0);if(this.t<=0){this.prev.length>0&&(t.position=n.slice(),this.prev.length=0);return}this.t-=e;let r=this.magnitude*Math.max(0,this.t)/this.falloff;this.t<=0&&(this.magnitude=0);let i=n.slice();this.prev.length!==i.length&&(this.prev=Array(i.length).fill(0));for(let e=0;e<i.length;e++){let t=i.length>=3&&e===1?.5:1;this.prev[e]=(this.engine.rng.next()*2-1)*r*t,i[e]=(i[e]??0)+this.prev[e]}t.position=i}},k_=class extends et{static props={seconds:{default:1},startOnSignal:{default:!1}};static signals=[`expired`];seconds=1;startOnSignal=!1;elapsed=0;running=!1;fired=!1;onReady(){if(!(this.seconds>0))throw new N(`PROP_TYPE_MISMATCH`,`Lifetime on '${this.node.getPath()}': "seconds" must be > 0, got ${this.seconds}.`,{prop:`seconds`});this.running=!this.startOnSignal}startTimer(){this.elapsed=0,this.fired=!1,this.running=!0}update(e){!this.running||this.fired||(this.elapsed+=e,this.elapsed>=this.seconds&&(this.fired=!0,this.running=!1,this.emit(`expired`),this.node.queueFree()))}},A_=[`linear`,`easeIn`,`easeOut`,`easeInOut`];function j_(e,t){let n=t<0?0:t>1?1:t;switch(e){case`linear`:return n;case`easeIn`:return n*n;case`easeOut`:return 1-(1-n)*(1-n);case`easeInOut`:return n<.5?2*n*n:1-(-2*n+2)**2/2}}var M_=class extends et{static props={to:{default:[]},duration:{default:1},ease:{default:`easeInOut`,options:[...A_]},startOnSignal:{default:!1}};static signals=[`arrived`];to=[];duration=1;ease=`easeInOut`;startOnSignal=!1;from=[];elapsed=0;running=!1;arrivedFired=!1;onReady(){if(!(this.duration>0))throw new N(`PROP_TYPE_MISMATCH`,`MoveTo on '${this.node.getPath()}': "duration" must be > 0, got ${this.duration}.`,{prop:`duration`});if(!A_.includes(this.ease))throw new N(`PROP_TYPE_MISMATCH`,`MoveTo on '${this.node.getPath()}': "ease" must be one of [${A_.join(`, `)}], got '${this.ease}'.`,{prop:`ease`});let e=r_(this);this.from=[...e.position],this.startOnSignal||(this.running=!0)}start(){let e=this.node;this.from=[...e.position],this.elapsed=0,this.arrivedFired=!1,this.running=!0}update(e){if(!this.running)return;let t=this.node;this.elapsed+=e;let n=Math.min(1,this.elapsed/this.duration),r=j_(this.ease,n);t.position=this.from.map((e,t)=>e+((this.to[t]??e)-e)*r),n>=1&&!this.arrivedFired&&(this.arrivedFired=!0,this.running=!1,this.emit(`arrived`))}},N_=[`x`,`y`,`z`],P_=[`position`,`rotation`,`scale`],F_={x:0,y:1,z:2},I_=class extends et{static props={axis:{default:`y`,options:[...N_]},amplitude:{default:1},frequency:{default:1},mode:{default:`position`,options:[...P_]}};static signals=[];axis=`y`;amplitude=1;frequency=1;mode=`position`;base=0;time=0;onReady(){if(!N_.includes(this.axis))throw new N(`PROP_TYPE_MISMATCH`,`Oscillate on '${this.node.getPath()}': "axis" must be one of [${N_.join(`, `)}], got '${this.axis}'.`,{prop:`axis`});if(!P_.includes(this.mode))throw new N(`PROP_TYPE_MISMATCH`,`Oscillate on '${this.node.getPath()}': "mode" must be one of [${P_.join(`, `)}], got '${this.mode}'.`,{prop:`mode`});this.base=this.readChannel()}update(e){this.time+=e;let t=this.amplitude*Math.sin(2*Math.PI*this.frequency*this.time);this.writeChannel(this.base+t)}isScalarRotation(){return this.mode===`rotation`&&typeof this.node.rotation==`number`}readChannel(){if(this.isScalarRotation())return this.node.rotation;let e=this.node[this.mode];if(!Array.isArray(e))throw new N(`PROP_TYPE_MISMATCH`,`Oscillate on '${this.node.getPath()}': node has no '${this.mode}' array to oscillate.`,{prop:`mode`});return e[F_[this.axis]]??0}writeChannel(e){if(this.isScalarRotation()){this.node.rotation=e;return}let t=[...this.node[this.mode]];t[F_[this.axis]]=e,this.node[this.mode]=t}},L_=class extends et{static signals=[`waypointReached`,`arrived`];static props={speed:{default:120},loop:{default:!1}};speed=120;loop=!1;waypoints=[];index=0;get moving(){return this.index<this.waypoints.length}setPath(e){this.waypoints=e.map(e=>[...e]),this.index=0}stop(){this.waypoints=[],this.index=0}update(e){if(!this.moving)return;let t=r_(this),n=this.speed*e;for(;n>0&&this.index<this.waypoints.length;){let e=this.waypoints[this.index],r=c_(t.position,e,n),i=R_(t.position,r.position);if(t.position=r.position,n-=i,r.reached){if(this.node.emit(`waypointReached`,this.index),this.index+=1,this.index>=this.waypoints.length)if(this.loop&&this.waypoints.length>1)this.index=0;else{this.node.emit(`arrived`);return}}else return}}};function R_(e,t){let n=0,r=Math.max(e.length,t.length);for(let i=0;i<r;i++){let r=(t[i]??0)-(e[i]??0);n+=r*r}return Math.sqrt(n)}var z_=class extends et{static props={points:{default:[]},speed:{default:60},loop:{default:!0},mode:{default:`loop`,options:[`loop`,`pingpong`]},pauseAt:{default:0}};static signals=[`reachedPoint`];points=[];speed=60;loop=!0;mode=`loop`;pauseAt=0;index=0;direction=1;pauseTimer=0;onReady(){if(!Array.isArray(this.points)||this.points.length===0)throw new N(`PROP_TYPE_MISMATCH`,`Patrol on '${this.node.getPath()}': "points" must be a non-empty array of position arrays or node paths.`,{prop:`points`});if(this.mode!==`loop`&&this.mode!==`pingpong`)throw new N(`PROP_TYPE_MISMATCH`,`Patrol on '${this.node.getPath()}': "mode" must be 'loop' or 'pingpong', got '${this.mode}'.`,{prop:`mode`});r_(this)}update(e){if(this.pauseTimer>0){this.pauseTimer=Math.max(0,this.pauseTimer-e);return}let t=this.node,n=this.pointAt(this.index);if(!n)return;let{position:r,reached:i}=c_(t.position,n,this.speed*e);t.position=r,i&&(this.emit(`reachedPoint`,this.index),this.advance(),this.pauseAt>0&&(this.pauseTimer=this.pauseAt))}pointAt(e){let t=this.points[e];if(Array.isArray(t))return t;if(typeof t==`string`){let e=this.node.getNodeOrNull(t);return Array.isArray(e?.position)?e.position:null}return null}advance(){let e=this.points.length-1;if(this.mode===`pingpong`){this.index>=e?this.direction=-1:this.index<=0&&(this.direction=1),this.index=Math.min(e,Math.max(0,this.index+this.direction));return}this.index<e?this.index+=1:this.loop&&(this.index=0)}},B_=class extends et{static props={value:{default:1},kind:{default:`coin`},collectorGroup:{default:`player`}};static signals=[`collected`];value=1;kind=`coin`;collectorGroup=`player`;collectedAlready=!1;onReady(){m_(this,e=>this.tryCollect(e))}tryCollect(e){this.collectedAlready||e.isInGroup(this.collectorGroup)&&(this.collectedAlready=!0,this.emit(`collected`,this.value,e),this.node.queueFree())}},V_=class extends et{static props={speed:{default:300},direction:{default:null},gravity:{default:0}};static signals=[];speed=300;direction=null;gravity=0;velocity=[];onReady(){if(this.speed===0&&this.gravity===0)throw new N(`PROP_TYPE_MISMATCH`,`Projectile on '${this.node.getPath()}': a projectile with "speed" 0 and "gravity" 0 never moves — set one of them.`,{prop:`speed`});let e=r_(this),t=this.resolveDirection();for(this.velocity=t.map(e=>e*this.speed);this.velocity.length<e.position.length;)this.velocity.push(0)}update(e){let t=this.node;this.gravity!==0&&(this.velocity[1]=(this.velocity[1]??0)+this.gravity*e);let n=t.position,r=Math.max(n.length,this.velocity.length),i=Array(r);for(let t=0;t<r;t++)i[t]=(n[t]??0)+(this.velocity[t]??0)*e;t.position=i}resolveDirection(){if(Array.isArray(this.direction))return s_(this.direction);if(this.direction===null||this.direction===`forward`)return this.forwardFromRotation();throw new N(`PROP_TYPE_MISMATCH`,`Projectile on '${this.node.getPath()}': "direction" must be a vector or 'forward', got ${JSON.stringify(this.direction)}.`,{prop:`direction`})}forwardFromRotation(){let e=this.node.rotation;if(typeof e==`number`){let t=e*Math.PI/180;return[Math.cos(t),Math.sin(t)]}if(Array.isArray(e)){let t=(e[1]??0)*Math.PI/180,n=(e[0]??0)*Math.PI/180;return s_([-Math.sin(t)*Math.cos(n),Math.sin(n),-Math.cos(t)*Math.cos(n)])}return[1,0]}},H_=class extends et{static props={score:{default:0},lives:{default:0},scoreToWin:{default:0}};static signals=[`scoreChanged`,`won`,`lost`,`lifeLost`];score=0;lives=0;scoreToWin=0;hasWon=!1;hasLost=!1;onReady(){if(this.lives<0)throw new N(`PROP_TYPE_MISMATCH`,`ScoreKeeper on '${this.node.getPath()}': "lives" must be >= 0, got ${this.lives}.`,{prop:`lives`});if(this.scoreToWin<0)throw new N(`PROP_TYPE_MISMATCH`,`ScoreKeeper on '${this.node.getPath()}': "scoreToWin" must be >= 0, got ${this.scoreToWin}.`,{prop:`scoreToWin`})}addScore(e){this.setScore(this.score+e)}setScore(e){this.score=e,this.emit(`scoreChanged`,this.score),this.scoreToWin>0&&!this.hasWon&&this.score>=this.scoreToWin&&(this.hasWon=!0,this.emit(`won`))}loseLife(){this.lives<=0||this.hasLost||(--this.lives,this.emit(`lifeLost`,this.lives),this.lives<=0&&(this.hasLost=!0,this.emit(`lost`)))}serialize(){return{score:this.score,lives:this.lives,hasWon:this.hasWon,hasLost:this.hasLost}}deserialize(e){let t=e;typeof t.score==`number`&&(this.score=t.score),typeof t.lives==`number`&&(this.lives=t.lives),typeof t.hasWon==`boolean`&&(this.hasWon=t.hasWon),typeof t.hasLost==`boolean`&&(this.hasLost=t.hasLost)}},U_=class{behavior;detached=new Map;constructor(e){this.behavior=e}resolveTemplate(e){let t=this.detached.get(e);if(t)return t;let n=this.behavior.node,r=e===``?null:n.getNodeOrNull(e);if(!r){let t=this.behavior.constructor.name;throw new N(`NODE_NOT_FOUND`,`${t} on '${n.getPath()}': "prefab" '${e}' does not resolve to a template node. Point it at a (usually hidden) child node to clone.`,{prop:`prefab`,path:n.getPath()})}return r.parent&&r.parent.removeChild(r),this.detached.set(e,r),r}spawn(e,t){let n=Wn(e),r=t?.at;return r&&r.length>0&&n_(n)&&(n.position=a_(n_(this.behavior.node)?this.behavior.node.position:[],r)),typeof n.visible==`boolean`&&(n.visible=!0),(t?.parent??this.behavior.node).addChild(n),n}},W_={CameraShake:O_,DayNight:__,GameFlow:S_,PathFollow:L_,Health:p_,Lifetime:k_,ScoreKeeper:H_,Pickup:B_,Collector:f_,DamageOnContact:h_,Interactable:T_,Clickable:d_,FollowCamera:y_,Patrol:z_,Chase:u_,Wander:class extends et{static props={speed:{default:40},radius:{default:50},changeEvery:{default:2}};static signals=[];speed=40;radius=50;changeEvery=2;origin=[];goal=[];timer=0;onReady(){if(!(this.radius>0))throw new N(`PROP_TYPE_MISMATCH`,`Wander on '${this.node.getPath()}': "radius" must be > 0, got ${this.radius}.`,{prop:`radius`});let e=r_(this);this.origin=[...e.position],this.goal=[...e.position],this.pickGoal()}update(e){let t=this.node;this.timer-=e;let{position:n,reached:r}=c_(t.position,this.goal,this.speed*e);t.position=n,(r||this.timer<=0)&&this.pickGoal()}pickGoal(){this.timer=this.changeEvery;let e=this.origin.length,t=Array(e);for(let n=0;n<8;n++){for(let n=0;n<e;n++)t[n]=(this.origin[n]??0)+this.rng.range(-this.radius,this.radius);if(i_(t,this.origin)<=this.radius){this.goal=t;return}}this.goal=t.map((e,n)=>{let r=this.origin[n]??0,i=i_(t,this.origin)||1;return r+(e-r)/i*this.radius})}},ZombieAI:class extends et{static props={aggroTarget:{default:``,nodePath:!0},aggroRange:{default:12},deAggroRange:{default:0},chaseSpeed:{default:4},wanderSpeed:{default:1.4},wanderRadius:{default:8},wanderChangeEvery:{default:3},goalTarget:{default:``,nodePath:!0},stopRange:{default:1.2},moveParent:{default:!1}};static signals=[`enteredAggro`,`exitedAggro`,`movementStateChanged`];aggroTarget=``;aggroRange=12;deAggroRange=0;chaseSpeed=4;wanderSpeed=1.4;wanderRadius=8;wanderChangeEvery=3;goalTarget=``;stopRange=1.2;moveParent=!1;aggro=!1;started=!1;home=[];goal=[];timer=0;lastState=``;mover(){let e=this.moveParent?this.node.parent:this.node;return e&&n_(e)?e:null}effectiveDeAggro(){return this.deAggroRange>0?this.deAggroRange:this.aggroRange*1.5}onReady(){if(this.moveParent){let e=this.node.parent;if(!e||!n_(e))throw new N(`PROP_TYPE_MISMATCH`,`ZombieAI on '${this.node.getPath()}': "moveParent" needs a spatial parent (a Node2D/Node3D) to move. '${this.node.name}' has none.`,{prop:`moveParent`,path:this.node.getPath()})}else r_(this)}update(e){let t=this.mover();if(!t)return;this.started||(this.started=!0,this.home=[...t.position],this.pickGoal());let n=this.aggroTarget?this.node.getNodeOrNull(this.aggroTarget):null,r=n&&n_(n)?n.position:null,i=r?this.groundDistance(t.position,r):1/0;if(!this.aggro&&i<=this.aggroRange?(this.aggro=!0,this.emit(`enteredAggro`)):this.aggro&&i>=this.effectiveDeAggro()&&(this.aggro=!1,this.emit(`exitedAggro`),this.pickGoal()),this.aggro&&r){let n=this.approach(t,r,this.chaseSpeed,e);this.setState(n?`idle`:`run`);return}this.timer-=e;let a=this.approach(t,this.goal,this.wanderSpeed,e);this.setState(a?`idle`:`walk`),(a||this.timer<=0)&&this.pickGoal()}approach(e,t,n,r){let i=e.position;if(this.groundDistance(i,t)<=this.stopRange)return!0;let a=i.length>=3?1:-1,o=[...t];a>=0&&(o[a]=i[a]??0);let s=this.groundDistance(i,o),{position:c}=c_(i,o,Math.min(n*r,Math.max(0,s-this.stopRange)));return e.position=c,!1}groundDistance(e,t){if(e.length>=3){let n=(e[0]??0)-(t[0]??0),r=(e[2]??0)-(t[2]??0);return Math.hypot(n,r)}return i_(e,t)}setState(e){e!==this.lastState&&(this.lastState=e,this.emit(`movementStateChanged`,e))}pickGoal(){this.timer=this.wanderChangeEvery;let e=this.mover(),t=e?e.position:this.home,n=t.length>=3?1:-1,r=this.home,i=this.goalTarget?this.node.getNodeOrNull(this.goalTarget):null;if(i&&n_(i)){let e=i.position;r=t.map((t,n)=>t+((e[n]??0)-t)*.4)}let a=[...r];for(let e=0;e<a.length;e++)e!==n&&(a[e]=(r[e]??0)+this.rng.range(-this.wanderRadius,this.wanderRadius));n>=0&&(a[n]=t[n]??0),this.goal=a}},MoveTo:M_,Oscillate:I_,Spawner:class extends et{static props={prefab:{default:``,nodePath:!0},interval:{default:1},max:{default:0},at:{default:[]},autoStart:{default:!0},total:{default:0}};static signals=[`spawned`,`finished`];prefab=``;interval=1;max=0;at=[];autoStart=!0;total=0;source=new U_(this);template;live=new Set;timer=0;running=!1;spawnedCount=0;done=!1;get liveCount(){return this.prune(),this.live.size}_templateForTest(){return this.template}onReady(){this.template=this.source.resolveTemplate(this.prefab),this.running=this.autoStart,this.timer=this.interval}start(){this.done||(this.running=!0)}stop(){this.running=!1}spawn(){if(this.prune(),this.done||this.max>0&&this.live.size>=this.max)return null;let e=this.source.spawn(this.template,this.at.length>0?{at:this.at}:void 0);return this.live.add(e),this.spawnedCount+=1,this.emit(`spawned`,e),this.total>0&&this.spawnedCount>=this.total&&(this.done=!0,this.running=!1,this.emit(`finished`)),e}update(e){this.running&&(this.timer-=e,!(this.timer>0)&&(this.timer+=this.interval,this.spawn()))}prune(){for(let e of this.live)e.parent===null&&this.live.delete(e)}},WaveSpawner:class extends et{static props={waves:{default:[]},autoStart:{default:!0}};static signals=[`waveStarted`,`waveCleared`,`allCleared`];waves=[];autoStart=!0;source=new U_(this);parsed=[];live=new Set;waveIndex=-1;phase=`idle`;timer=0;spawnedThisWave=0;announced=!1;onReady(){if(!Array.isArray(this.waves)||this.waves.length===0)throw new N(`PROP_TYPE_MISMATCH`,`WaveSpawner on '${this.node.getPath()}': "waves" must be a non-empty array of { prefab, count, interval, delayBefore }.`,{prop:`waves`});this.parsed=this.waves.map((e,t)=>this.parseWave(e,t));for(let e of this.parsed)this.source.resolveTemplate(e.prefab);this.autoStart&&this.beginWave(0)}start(){this.beginWave(0)}update(e){if(this.phase===`idle`||this.phase===`done`)return;let t=this.parsed[this.waveIndex];if(t){if(this.announced||(this.announced=!0,this.emit(`waveStarted`,this.waveIndex)),this.phase===`delay`){this.timer-=e,this.timer<=0&&(this.phase=`spawning`,this.timer=0);return}if(this.phase===`spawning`){for(this.timer-=e;this.timer<=0&&this.spawnedThisWave<t.count;){let e=this.source.spawn(this.source.resolveTemplate(t.prefab));this.live.add(e),this.spawnedThisWave+=1,this.timer+=t.interval}this.spawnedThisWave>=t.count&&(this.phase=`clearing`);return}if(this.phase===`clearing`&&(this.prune(),this.live.size===0)){this.emit(`waveCleared`,this.waveIndex);let e=this.waveIndex+1;e<this.parsed.length?this.beginWave(e):(this.phase=`done`,this.emit(`allCleared`))}}}beginWave(e){this.waveIndex=e,this.spawnedThisWave=0,this.announced=!1,this.live.clear();let t=this.parsed[e];t&&(t.delayBefore>0?(this.phase=`delay`,this.timer=t.delayBefore):(this.phase=`spawning`,this.timer=0))}prune(){for(let e of this.live)e.parent===null&&this.live.delete(e)}parseWave(e,t){let n=e,r=typeof n?.prefab==`string`?n.prefab:``;if(r===``)throw new N(`PROP_TYPE_MISMATCH`,`WaveSpawner on '${this.node.getPath()}': wave ${t} needs a "prefab" template path.`,{prop:`waves`});return{prefab:r,count:typeof n?.count==`number`?n.count:1,interval:typeof n?.interval==`number`?n.interval:.5,delayBefore:typeof n?.delayBefore==`number`?n.delayBefore:0}}},Projectile:V_,Buoyancy:e_};function G_(e){let t=e?.replace??!0;for(let[e,n]of Object.entries(W_))it(e,n,{replace:t})}function K_(e,t){let n=e.shape;if(n!==void 0){if(e.oneWay!==void 0&&typeof e.oneWay!=`boolean`)throw new N(`BAD_FORMAT`,`Collider on '${t}': "oneWay" must be a boolean (platforms you jump up through), got ${JSON.stringify(e.oneWay)}.`);if(n===`rect`){let n=e.size;if(!Array.isArray(n)||n.length!==2||n.some(e=>typeof e!=`number`))throw new N(`BAD_FORMAT`,`Collider on '${t}': rect needs "size": [width, height].`);return}if(n===`circle`){if(typeof e.radius!=`number`)throw new N(`BAD_FORMAT`,`Collider on '${t}': circle needs "radius".`);return}if(n===`capsule`){if(typeof e.radius!=`number`||typeof e.height!=`number`)throw new N(`BAD_FORMAT`,`Collider on '${t}': capsule needs "radius" and "height".`);return}throw new N(`BAD_FORMAT`,`Collider on '${t}': "shape" must be 'rect', 'circle', or 'capsule', got ${JSON.stringify(n)}.`)}}var q_=class extends Nt{static typeName=`Node2D`;static props={position:{default:[0,0]},rotation:{default:0},static:{default:!1},scale:{default:[1,1]},renderOrder:{default:0},orderGroup:{default:`default`,options:[`background`,`terrain`,`default`,`characters`,`effects`,`overlay`]},visible:{default:!0}};static propAliases={zIndex:`renderOrder`};position=[0,0];rotation=0;static=!1;scale=[1,1];renderOrder=0;orderGroup=`default`;get effectiveRenderOrder(){return _t(this.orderGroup,this.renderOrder,this.tree?.engine?.orderGroups)}visible=!0;_object2D=null;_ensureObject2D(){return this._object2D||(this._object2D=this._createObject2D(),this._object2D.userData.incantoNode=this),this._object2D}_createObject2D(){return new go}_syncObject2D(e){let t=this._ensureObject2D();t.position.set(this.position[0]??0,-(this.position[1]??0),0),t.rotation.z=-ba.degToRad(this.rotation),t.scale.set(this.scale[0]??1,this.scale[1]??1,1),t.visible=this.visible}free(){super.free(),this._object2D?.removeFromParent(),this._object2D=null}},J_=class extends q_{static props={collider:{default:{},variants:{tag:`shape`,byTag:{rect:{shape:`rect`,size:[32,32]},circle:{shape:`circle`,radius:16},capsule:{shape:`capsule`,radius:12,height:32}}}}};static signals=[`triggerEnter`,`triggerExit`];_collider={};_colliderChanged=!1;get collider(){return this._collider}set collider(e){this._collider=e,this._colliderChanged=!0}static validateJson(e){K_(e.collider,e.name)}_physics=null},Y_=class extends J_{static typeName=`StaticBody2D`},X_=class extends J_{static typeName=`Area2D`},Z_=class extends J_{static typeName=`RigidBody2D`;static props={mass:{default:1},gravityScale:{default:1},fixedRotation:{default:!1},friction:{default:.5},restitution:{default:0},linearVelocity:{default:[0,0]}};mass=1;gravityScale=1;fixedRotation=!1;friction=.5;restitution=0;linearVelocity=[0,0]},Q_=class extends J_{static typeName=`CharacterBody2D`;static props={velocity:{default:[0,0]},snapToGround:{default:!0},slopeLimitDeg:{default:45}};velocity=[0,0];snapToGround=!0;slopeLimitDeg=45;_grounded=!1;moveAndSlide(){if(!this._physics)throw new N(`TREE_VIOLATION`,this.collider.shape===void 0?`CharacterBody2D '${this.name}' has no collider — set a collider prop (physics skips collider-less bodies).`:`CharacterBody2D '${this.name}' has no physics world — await enablePhysics2D(engine) first.`);this._physics.moveAndSlide(this)}_onWall=0;_onCeiling=!1;isOnWall(){return this._onWall!==0}wallSide(){return this._onWall}isOnCeiling(){return this._onCeiling}isOnFloor(){return this._grounded}},$_=new Set;function ev(e){return $_.add(e),()=>$_.delete(e)}function tv(e,t){return[...$_].filter(n=>n.dimension===e&&(t===void 0||n.engine===t))}var nv=class extends q_{static typeName=`Joint2D`;static props={type:{default:`revolute`,options:[`fixed`,`revolute`,`rope`,`spring`]},target:{default:``,nodePath:!0},anchor:{default:[0,0]},targetAnchor:{default:[0,0]},length:{default:0},stiffness:{default:50},damping:{default:5}};type=`revolute`;target=``;anchor=[0,0];targetAnchor=[0,0];length=0;stiffness=50;damping=5;onEnterTree(){if(!(this.parent instanceof J_))throw new N(`TREE_VIOLATION`,`Joint2D '${this.name}' must be a child of a physics body (its body A); parent is '${this.parent?.name??`none`}'.`);if(this.target===``)throw new N(`BAD_FORMAT`,`Joint2D '${this.name}' needs a "target" node path to the body it links to.`)}_resolveBodies(){let e=this.parent,t=this.getNodeOrNull(this.target);if(!(t instanceof J_))throw new N(`NODE_NOT_FOUND`,`Joint2D '${this.name}': target '${this.target}' is not a physics body.`);return{a:e,b:t}}},Z=100,rv=Math.PI/180;async function iv(e,t){let n=await bm(()=>import(`./rapier-CEuLKeCu.js`),[],import.meta.url);return await n.init({}),new av(n,e,t)}var av=class{R;engine;debugDraw=!1;debugScope=null;dimension=`2d`;unregisterDebug;warnedNoCollider=new WeakSet;entries=new Map;byColliderHandle=new Map;world;events;kcc;disconnect;lastDt=1/60;optsGravity;lastScene=null;constructor(e,t,n){this.R=e,this.engine=t,this.optsGravity=n?.gravity,this.simulate=n?.simulate??!0,this.lastScene=t.scene;let r=t.scene?.physics?.gravity,i=n?.gravity??r??[0,980];this.world=new e.World({x:(i[0]??0)/Z,y:(i[1]??0)/Z}),this.kcc=this.world.createCharacterController(.01),this.kcc.setUp({x:0,y:-1}),this.events=new e.EventQueue(!0),this.unregisterDebug=ev(this),this.disconnect=t.fixedUpdated.connect(e=>this.step(e)),this.syncBodies()}simulate;step(e){if(this.lastDt=e,!this.simulate){this.syncBodies(),this.poseFromTree();return}if(this.engine.scene!==this.lastScene&&(this.lastScene=this.engine.scene,!this.optsGravity)){let e=this.engine.scene?.physics?.gravity??[0,980];this.world.gravity={x:(e[0]??0)/Z,y:(e[1]??0)/Z}}this.syncBodies(),this.world.timestep=e,this.world.step(this.events);for(let[e,t]of this.entries){let n=t.body.translation();if(!t.body.isFixed()){let[t,r]=fv(e);e.position=[n.x*Z-t,n.y*Z-r]}if(e instanceof Z_){e.fixedRotation||(e.rotation=t.body.rotation()/rv);let n=t.body.linvel();e.linearVelocity=[n.x*Z,n.y*Z],t.lastVX=e.linearVelocity[0]??0,t.lastVY=e.linearVelocity[1]??0}let[r,i]=dv(e);t.lastX=r,t.lastY=i}this.events.drainCollisionEvents((e,t,n)=>{let r=this.byColliderHandle.get(e),i=this.byColliderHandle.get(t);if(!r||!i)return;let a=n?`triggerEnter`:`triggerExit`;try{r.emit(a,i),i.emit(a,r)}catch(e){lt(this.engine,`error`,`incanto: error in a '${a}' handler (${r.name} ↔ ${i.name}):`,e)}})}moveAndSlide(e){let t=this.ensureEntry(e),n=e.velocity[1]??0;e.snapToGround&&n>=0?this.kcc.enableSnapToGround(.05):this.kcc.disableSnapToGround(),this.kcc.setMaxSlopeClimbAngle(e.slopeLimitDeg*rv);let r=0,i=0;if(t.ground&&t.ground._physics===this){let[e,n]=dv(t.ground);r=e-(t.groundX??e),i=n-(t.groundY??n)}else t.ground=null;let a={x:((e.velocity[0]??0)*this.lastDt+r)/Z*1,y:(n*this.lastDt+i)/Z*1},o=t.body.translation().y*Z+lv(e);this.kcc.computeColliderMovement(t.collider,a,this.R.QueryFilterFlags.EXCLUDE_SENSORS,void 0,t=>{let r=this.byColliderHandle.get(t.handle);return!(r&&r!==e&&r.collider.oneWay===!0&&(n<0||o>uv(r)+cv))});let s=this.kcc.computedMovement(),c=t.body.translation();t.body.setNextKinematicTranslation({x:c.x+s.x,y:c.y+s.y}),e._grounded=this.kcc.computedGrounded(),e._onWall=0,e._onCeiling=!1;let l=this.kcc.numComputedCollisions();for(let t=0;t<l;t++){let n=this.kcc.computedCollision(t)?.normal1;n&&(Math.abs(n.y)>.7?e._grounded||(e._onCeiling=!0):Math.abs(n.x)>.7&&(e._onWall=n.x>0?-1:1))}if(e._grounded){let n=(c.x+s.x)*Z,r=(c.y+s.y)*Z+lv(e)-2,i=this.castRay([n,r],[0,1],8,e);if(i?.node&&!(i.node instanceof Q_)){t.ground=i.node;let[e,n]=dv(i.node);t.groundX=e,t.groundY=n}else t.ground=null}else t.ground=null}debugLines(){if(!this.debugDraw)return null;let e=this.debugScope?this.scopedLines(this.debugScope):this.world.debugRender().vertices,t=new Float32Array(e.length);for(let n=0;n<e.length;n++)t[n]=e[n]*Z;return t}scopedLines(e){let t=[],n=[],r=e=>{let t=this.entries.get(e);t&&n.push(t.body);for(let t of e.children)r(t)};r(e);for(let t=e.parent;t&&n.length===0;t=t.parent){let e=this.entries.get(t);e&&n.push(e.body)}for(let e of n)for(let n=0;n<e.numColliders();n++){let r=e.collider(n);if(!r)continue;let i=r.translation(),a=r.rotation(),o=Math.cos(a),s=Math.sin(a),c=(e,n)=>{t.push(i.x+e*o-n*s,i.y+e*s+n*o)},l=(e,t,n,r)=>{c(e,t),c(n,r)},u=r.shape;if(u.halfExtents){let{x:e,y:t}=u.halfExtents;l(-e,-t,e,-t),l(e,-t,e,t),l(e,t,-e,t),l(-e,t,-e,-t)}else if(u.radius!==void 0){let e=u.radius,t=u.halfHeight??0;for(let n=0;n<24;n++){let r=n/24*Math.PI*2,i=(n+1)/24*Math.PI*2,a=e=>e>=0?t:-t;l(Math.cos(r)*e,Math.sin(r)*e+a(Math.sin(r)),Math.cos(i)*e,Math.sin(i)*e+a(Math.sin(i)))}t>0&&(l(-e,-t,-e,t),l(e,-t,e,t))}}return new Float32Array(t)}syncJoints(e){let t=this.R;if(e)for(let[e,t]of this.joints)this.jointSet.has(e)||(this.world.removeImpulseJoint(t,!0),this.joints.delete(e));for(let e of this.jointSet){if(this.joints.has(e))continue;let{a:n,b:r}=e._resolveBodies(),i=this.entries.get(n),a=this.entries.get(r);if(!i||!a)continue;let o={x:(e.anchor[0]??0)/Z,y:(e.anchor[1]??0)/Z},s={x:(e.targetAnchor[0]??0)/Z,y:(e.targetAnchor[1]??0)/Z},c=e.length/Z;if(e.length===0&&(e.type===`rope`||e.type===`spring`)){let e=i.body.translation(),t=a.body.translation();c=Math.hypot(t.x-e.x,t.y-e.y)}let l;l=e.type===`fixed`?t.JointData.fixed(o,0,s,0):e.type===`rope`?t.JointData.rope(c,o,s):e.type===`spring`?t.JointData.spring(c,e.stiffness,e.damping,o,s):t.JointData.revolute(o,s),this.joints.set(e,this.world.createImpulseJoint(l,i.body,a.body,!0))}}castRay(e,t,n,r,i){let a=Math.hypot(t[0],t[1])||1,o=new this.R.Ray({x:e[0]/Z,y:e[1]/Z},{x:t[0]/a,y:t[1]/a}),s=r?this.entries.get(r)?.collider:void 0,c=i?.staticOnly?this.R.QueryFilterFlags.EXCLUDE_DYNAMIC|this.R.QueryFilterFlags.EXCLUDE_KINEMATIC:void 0,l=this.world.castRayAndGetNormal(o,n/Z,!0,c,void 0,s,void 0,e=>!e.isSensor());return l?{distance:l.timeOfImpact*Z,normal:[l.normal.x,l.normal.y],node:this.byColliderHandle.get(l.collider.handle)??null}:null}dispose(){this.disconnect(),this.unregisterDebug(),this.world.free()}lastStructure=-1;lastRoot=null;jointSet=new Set;joints=new Map;bodySet=new Set;poseFromTree(){for(let[e,t]of this.entries){let[n,r]=dv(e);t.body.setTranslation({x:n/Z,y:r/Z},!1),t.body.setRotation(e.rotation*rv,!1)}this.world.propagateModifiedBodyPositionsToColliders()}syncBodies(){let e=this.engine.scene;if(!e)return;let t=e.tree._structureVersion,n=e.root===this.lastRoot,r=t!==this.lastStructure||!n;if(r){let r=n?e.tree._structureSince(this.lastStructure):null;if(this.lastStructure=t,this.lastRoot=e.root,r){let t=!1;for(let{node:e,added:n}of r)e instanceof J_&&(n?this.bodySet.add(e):this.bodySet.delete(e)),e instanceof nv&&(t=!0);t&&(this.jointSet.clear(),ov(e.root,this.jointSet))}else this.bodySet.clear(),sv(e.root,this.bodySet),this.jointSet.clear(),ov(e.root,this.jointSet)}let i=this.bodySet;for(let e of i){if(e.collider.shape===void 0){let t=this.entries.get(e);t&&(this.byColliderHandle.delete(t.collider.handle),this.world.removeRigidBody(t.body),this.entries.delete(e),e._physics=null),this.warnedNoCollider.has(e)||(this.warnedNoCollider.add(e),lt(this.engine,`warn`,`[incanto] '${e.name}' has no collider — physics skips it.`));continue}let t=this.entries.get(e);t&&e._colliderChanged&&(this.byColliderHandle.delete(t.collider.handle),this.world.removeRigidBody(t.body),this.entries.delete(e),e._physics=null),this.ensureEntry(e)}if(this.syncJoints(r),r)for(let[e,t]of this.entries)i.has(e)||(this.byColliderHandle.delete(t.collider.handle),this.world.removeRigidBody(t.body),this.entries.delete(e),e._physics=null)}ensureEntry(e){let t=this.entries.get(e),n=this.R;if(!t){let[r,i]=dv(e),a=r/Z,o=i/Z,s;s=e instanceof Z_?n.RigidBodyDesc.dynamic():e instanceof Q_||e instanceof X_?n.RigidBodyDesc.kinematicPositionBased():n.RigidBodyDesc.fixed(),s.setTranslation(a,o).setRotation(e.rotation*rv),e instanceof Z_&&(s.setGravityScale(e.gravityScale),s.setLinvel((e.linearVelocity[0]??0)/Z,(e.linearVelocity[1]??0)/Z),e.fixedRotation&&s.lockRotations());let c=this.world.createRigidBody(s),l=pv(n,e.collider,e.name);l.setActiveEvents(n.ActiveEvents.COLLISION_EVENTS),l.setActiveCollisionTypes(n.ActiveCollisionTypes.ALL),e instanceof X_&&l.setSensor(!0),e instanceof Z_&&l.setMass(e.mass).setFriction(e.friction).setRestitution(e.restitution);let u=this.world.createCollider(l,c);return t={body:c,collider:u,lastX:r,lastY:i,lastVX:0,lastVY:0},this.entries.set(e,t),this.byColliderHandle.set(u.handle,e),e._colliderChanged=!1,e._physics=this,t}let[r,i]=dv(e);if((r!==t.lastX||i!==t.lastY)&&(t.body.setTranslation({x:r/Z,y:i/Z},!0),t.lastX=r,t.lastY=i),e instanceof Z_){let n=e.linearVelocity[0]??0,r=e.linearVelocity[1]??0;(n!==t.lastVX||r!==t.lastVY)&&(t.body.setLinvel({x:n/Z,y:r/Z},!0),t.lastVX=n,t.lastVY=r)}return t}};function ov(e,t){e instanceof nv&&t.add(e);for(let n of e.children)ov(n,t)}function sv(e,t){e instanceof J_&&t.add(e);for(let n of e.children)sv(n,t)}var cv=4;function lv(e){let t=e.collider;return t.shape===`rect`?(t.size?.[1]??32)/2:t.shape===`capsule`?(t.height??32)/2+(t.radius??8):t.radius??16}function uv(e){let[,t]=dv(e),n=e.collider;return t-(n.shape===`rect`?(n.size?.[1]??32)/2:n.shape===`capsule`?(n.height??32)/2+(n.radius??8):n.radius??16)}function dv(e){let t=0,n=0;for(let r=e;r;r=r.parent)r instanceof q_&&(t+=r.position[0]??0,n+=r.position[1]??0);return[t,n]}function fv(e){let t=0,n=0;for(let r=e.parent;r;r=r.parent)r instanceof q_&&(t+=r.position[0]??0,n+=r.position[1]??0);return[t,n]}function pv(e,t,n){K_(t,n);let r=mv(e,t,n),i=t.offset;return Array.isArray(i)&&r.setTranslation((i[0]??0)/Z,(i[1]??0)/Z),r}function mv(e,t,n){let r=t.shape;if(r===`rect`){let r=t.size;if(!Array.isArray(r)||r.length!==2||r.some(e=>typeof e!=`number`))throw new N(`BAD_FORMAT`,`Collider on '${n}': rect needs "size": [width, height].`);return e.ColliderDesc.cuboid(r[0]/2/Z,r[1]/2/Z)}if(r===`circle`){if(typeof t.radius!=`number`)throw new N(`BAD_FORMAT`,`Collider on '${n}': circle needs "radius".`);return e.ColliderDesc.ball(t.radius/Z)}if(r===`capsule`){if(typeof t.radius!=`number`||typeof t.height!=`number`)throw new N(`BAD_FORMAT`,`Collider on '${n}': capsule needs "radius" and "height".`);return e.ColliderDesc.capsule(t.height/2/Z,t.radius/Z)}throw new N(`BAD_FORMAT`,`Collider on '${n}': "shape" must be 'rect', 'circle', or 'capsule', got ${JSON.stringify(r)}.`)}var hv=new cl(1,1),gv=class extends q_{static typeName=`Sprite2D`;static props={texture:{default:``},anchor:{default:[.5,.5]},flipX:{default:!1},flipY:{default:!1},tint:{default:`#ffffff`},opacity:{default:1}};texture=``;anchor=[.5,.5];flipX=!1;flipY=!1;tint=`#ffffff`;opacity=1;quadMesh=null;_quad(){return this.quadMesh||(this.quadMesh=new Ys(hv,new Ls({transparent:!0,depthWrite:!1})),this._ensureObject2D().add(this.quadMesh)),this.quadMesh}_createObject2D(){return super._createObject2D()}resolveTexture(e){if(!this.texture||!e)return null;let t=e.getTexture(this.texture),n=t.image;return!n?.width||!n.height?null:{texture:t,width:n.width,height:n.height}}_syncObject2D(e){super._syncObject2D(e);let t=this._quad(),n=t.material,r=this.resolveTexture(e);if(!r){t.visible=!1;return}t.visible=!0,n.map!==r.texture&&(n.map=r.texture,n.needsUpdate=!0);let i=r.width,a=r.height;t.scale.set(this.flipX?-i:i,this.flipY?-a:a,1);let o=this.anchor[0]??.5,s=this.anchor[1]??.5;t.position.set((.5-o)*i,(s-.5)*a,0),t.renderOrder=this.effectiveRenderOrder,n.color.set(this.tint),n.opacity=this.opacity}},_v=class extends gv{static typeName=`AnimatedSprite2D`;static signals=[`animationFinished`];static props={sheet:{default:``},animations:{default:{}},autoplay:{default:``}};sheet=``;animations={};autoplay=``;playing=!1;currentFrame=0;currentAnimation=``;frameList=[];frameIndex=0;frameTime=0;ownTexture=null;loadedSheetRef=``;play(e){let t=this.animations[e];if(!t)throw new N(`UNKNOWN_ANIMATION`,`No animation '${e}' on '${this.name}'. Available: [${Object.keys(this.animations).join(`, `)}].`);this.currentAnimation=e,this.frameList=vv(t.frames,e),this.frameIndex=0,this.currentFrame=this.frameList[0]??0,this.frameTime=0,this.playing=!0}stop(){this.playing=!1}onReady(){this.autoplay&&this.play(this.autoplay)}update(e){if(!this.playing||this.currentAnimation===``)return;let t=this.animations[this.currentAnimation];if(!t||!Number.isFinite(t.fps)||t.fps<=0)return;let n=1/t.fps;for(this.frameTime+=e;this.frameTime>=n;)if(this.frameTime-=n,this.frameIndex+=1,this.frameIndex>=this.frameList.length)if(t.loop)this.frameIndex=0;else{this.frameIndex=this.frameList.length-1,this.playing=!1,this.emit(`animationFinished`,this.currentAnimation);break}this.currentFrame=this.frameList[this.frameIndex]??0}resolveTexture(e){if(!this.sheet||!e)return null;let t=e.getSheet(this.sheet);this.loadedSheetRef!==this.sheet&&(this.ownTexture=t.texture.clone(),this.ownTexture.needsUpdate=!0,this.loadedSheetRef=this.sheet);let n=this.ownTexture,r=t.texture.image;if(!r?.width||!r.height)return null;let i=Math.max(1,Math.floor(r.width/t.frameWidth)),a=this.currentFrame%i,o=Math.floor(this.currentFrame/i);return n.repeat.set(t.frameWidth/r.width,t.frameHeight/r.height),n.offset.set(a*t.frameWidth/r.width,1-(o+1)*t.frameHeight/r.height),{texture:n,width:t.frameWidth,height:t.frameHeight}}};function vv(e,t){if(!Array.isArray(e)||e.length===0)throw new N(`BAD_FORMAT`,`Animation '${t}': "frames" must be a non-empty array.`);if(e.length===2){let[t,n]=e;if(n>=t){let e=[];for(let r=t;r<=n;r++)e.push(r);return e}}return[...e]}var yv=class extends q_{static typeName=`Camera2D`;static props={follow:{default:``,nodePath:!0},smoothing:{default:0},zoom:{default:1},limits:{default:[]},current:{default:!1}};follow=``;smoothing=0;zoom=1;limits=[];current=!1;get effectiveZoom(){return Math.max(.01,this.zoom)}update(e){if(!this.follow)return;let t=this.getNodeOrNull(this.follow);if(!(t instanceof q_))return;let n=t.position[0]??0,r=t.position[1]??0,i=Math.min(Math.max(this.smoothing,0),.99),a=i<=0?1:1-i**(e*60),o=this.position[0]??0,s=this.position[1]??0;this.position=[o+(n-o)*a,s+(r-s)*a]}clampedCenter(e,t){let n=this.position[0]??0,r=this.position[1]??0;if(this.limits.length!==0&&this.limits.length!==4)throw new N(`BAD_FORMAT`,`Camera2D '${this.name}' limits must be [] or [minX,minY,maxX,maxY], got length ${this.limits.length}.`);if(this.limits.length===4){let[i,a,o,s]=this.limits,c=e/(2*this.effectiveZoom),l=t/(2*this.effectiveZoom);n=bv(n,i+c,o-c),r=bv(r,a+l,s-l)}return{x:n,y:r}}};function bv(e,t,n){return t>n?(t+n)/2:Math.min(n,Math.max(t,e))}var xv=class extends Nt{static typeName=`CharacterController2D`;static props={mode:{default:`platformer`,options:[`platformer`,`topDown`]},maxSpeed:{default:220},jumpHeight:{default:64},moveAction:{default:`move`},jumpAction:{default:`jump`},coyoteSeconds:{default:0},jumpBufferSeconds:{default:0},jumpCutMultiplier:{default:1},maxJumps:{default:1},dashSpeed:{default:0},dashSeconds:{default:.15},dashAction:{default:`dash`},wallSlideSpeed:{default:0},wallJumpImpulse:{default:[0,0]}};static signals=[`movementStateChanged`];mode=`platformer`;maxSpeed=220;jumpHeight=64;moveAction=`move`;jumpAction=`jump`;coyoteSeconds=0;jumpBufferSeconds=0;jumpCutMultiplier=1;maxJumps=1;dashSpeed=0;dashSeconds=.15;dashAction=`dash`;wallSlideSpeed=0;wallJumpImpulse=[0,0];state=`idle`;coyoteLeft=0;bufferLeft=0;jumpsUsed=0;dashLeft=0;dashDir=1;rising=!1;onReady(){if(!(this.parent instanceof Q_))throw new N(`TREE_VIOLATION`,`CharacterController2D '${this.name}' must be a child of a CharacterBody2D (parent is '${this.parent?.name??`none`}').`);if(this.mode!==`platformer`&&this.mode!==`topDown`)throw new N(`PROP_TYPE_MISMATCH`,`CharacterController2D.mode must be 'platformer' or 'topDown', got '${this.mode}'.`)}fixedUpdate(e){let t=this.tree?.engine;if(!t?.scene)return;let n=this.parent;if(!(n instanceof Q_))return;let r=t.input,i=r.getVector(this.moveAction);if(this.mode===`topDown`){n.velocity=[i.x*this.maxSpeed,i.y*this.maxSpeed],n.moveAndSlide();return}let a=t.scene.physics?.gravity?.[1]??980,o=n.isOnFloor(),s=-Math.sqrt(2*a*this.jumpHeight);if(this.dashLeft>0){this.dashLeft-=e,n.velocity[0]=this.dashDir*this.dashSpeed,n.velocity[1]=0,n.moveAndSlide(),this.setState(`dash`);return}if(this.dashSpeed>0&&r.justPressed(this.dashAction)){this.dashLeft=this.dashSeconds,this.dashDir=i.x===0?this.dashDir:Math.sign(i.x),n.velocity[0]=this.dashDir*this.dashSpeed,n.velocity[1]=0,n.moveAndSlide(),this.setState(`dash`);return}n.velocity[0]=i.x*this.maxSpeed,o?(this.coyoteLeft=this.coyoteSeconds,this.jumpsUsed=0):(this.coyoteLeft=Math.max(0,this.coyoteLeft-e),this.coyoteLeft<=0&&this.jumpsUsed===0&&(this.jumpsUsed=1)),r.justPressed(this.jumpAction)?this.bufferLeft=Math.max(this.jumpBufferSeconds,0):this.bufferLeft=Math.max(0,this.bufferLeft-e);let c=this.bufferLeft>0||r.justPressed(this.jumpAction),l=this.wallSlideSpeed>0||this.wallJumpImpulse.some(e=>e!==0)?n.isOnWall():!1;if(c&&l&&!o&&this.wallJumpImpulse.some(e=>e!==0)){let e=-n.wallSide();n.velocity[0]=e*(this.wallJumpImpulse[0]??0),n.velocity[1]=-(this.wallJumpImpulse[1]??0),this.bufferLeft=0,this.rising=!0,this.jumpsUsed=1}else c&&(o||this.coyoteLeft>0||this.jumpsUsed<this.maxJumps)?(n.velocity[1]=s,this.bufferLeft=0,this.coyoteLeft=0,this.rising=!0,this.jumpsUsed=o?1:this.jumpsUsed+1):o?(n.velocity[1]=20,this.rising=!1):(n.velocity[1]=(n.velocity[1]??0)+a*e,this.rising&&this.jumpCutMultiplier<1&&!r.isPressed(this.jumpAction)&&(n.velocity[1]=(n.velocity[1]??0)*this.jumpCutMultiplier,this.rising=!1),(n.velocity[1]??0)>=0&&(this.rising=!1),this.wallSlideSpeed>0&&l&&(n.velocity[1]??0)>this.wallSlideSpeed&&(n.velocity[1]=this.wallSlideSpeed));n.isOnCeiling()&&(n.velocity[1]??0)<0&&(n.velocity[1]=0,this.rising=!1),n.moveAndSlide();let u=n.velocity[1]??0;this.wallSlideSpeed>0&&!n.isOnFloor()&&n.isOnWall()&&u>0?this.setState(`wallSlide`):n.isOnFloor()?this.setState(Math.abs(i.x)>.01?`run`:`idle`):this.setState(u<0?`jump`:`fall`)}setState(e){e!==this.state&&(this.state=e,this.emit(`movementStateChanged`,e))}},Sv=new cl(1,1),Cv=class extends q_{static typeName=`ColorRect2D`;static props={size:{default:[100,100]},color:{default:`#ffffff`},opacity:{default:1},anchor:{default:[.5,.5]}};size=[100,100];color=`#ffffff`;opacity=1;anchor=[.5,.5];quadMesh=null;_quad(){return this.quadMesh||(this.quadMesh=new Ys(Sv,new Ls({transparent:!0,depthWrite:!1})),this._ensureObject2D().add(this.quadMesh)),this.quadMesh}_syncObject2D(e){super._syncObject2D(e);let t=this._quad(),n=this.size[0]??0,r=this.size[1]??0;t.visible=n>0&&r>0&&this.opacity>0,t.scale.set(n,r,1);let i=this.anchor[0]??.5,a=this.anchor[1]??.5;t.position.set((.5-i)*n,(a-.5)*r,0),t.renderOrder=this.effectiveRenderOrder;let o=t.material;o.color.set(this.color),o.opacity=this.opacity}},wv=new cl(1,1),Tv=class extends q_{static typeName=`Label`;static props={text:{default:``},fontSize:{default:16},color:{default:`#ffffff`},font:{default:`monospace`},align:{default:`left`}};text=``;fontSize=16;color=`#ffffff`;font=`monospace`;align=`left`;quadMesh=null;canvas=null;lastKey=``;_quad(){return this.quadMesh||(this.quadMesh=new Ys(wv,new Ls({transparent:!0,depthWrite:!1})),this._ensureObject2D().add(this.quadMesh)),this.quadMesh}_syncObject2D(e){super._syncObject2D(e);let t=this._quad();if(typeof document>`u`||this.text===``){t.visible=!1;return}let n=`${this.text}\0${this.fontSize}\0${this.color}\0${this.font}\0${this.align}`;n!==this.lastKey&&(this.lastKey=n,this.rasterize()),t.visible=!0,t.renderOrder=this.effectiveRenderOrder}rasterize(){let e=Math.min(globalThis.devicePixelRatio??1,2);this.canvas??=document.createElement(`canvas`);let t=this.canvas.getContext(`2d`);if(!t)return;let n=`${this.fontSize*e}px ${this.font}`;t.font=n;let r=t.measureText(this.text),i=Math.max(1,Math.ceil(r.width)),a=Math.ceil(this.fontSize*e*1.4);this.canvas.width=i,this.canvas.height=a,t.font=n,t.fillStyle=this.color,t.textBaseline=`middle`,t.fillText(this.text,0,a/2);let o=this._quad(),s=o.material;s.map?.dispose(),s.map=new Qc(this.canvas),s.needsUpdate=!0;let c=i/e,l=a/e;o.scale.set(c,l,1);let u=this.align===`center`?.5:+(this.align===`right`);o.position.set((.5-u)*c,0,0)}},Ev=new cl(1,1),Dv=class e extends q_{orderGroup=`effects`;static typeName=`Particles2D`;static signals=[`finished`];static props={orderGroup:{default:`effects`,options:[`background`,`terrain`,`default`,`characters`,`effects`,`overlay`]},preset:{default:`custom`,options:[`custom`,...pn]},emitting:{default:!0},rate:{default:40},burst:{default:0},lifetime:{default:[.6,1.2]},speed:{default:[40,120]},directionDeg:{default:-90},spreadDeg:{default:30},gravity:{default:[0,0]},drag:{default:0},sizeStart:{default:8},sizeEnd:{default:2},colorStart:{default:`#ffffff`},colorEnd:{default:`#ffffff`},paletteColors:{default:[]},alphaStart:{default:1},alphaEnd:{default:0},shimmer:{default:0},blend:{default:`add`,options:[`add`,`normal`]},maxParticles:{default:256}};preset=`custom`;emitting=!0;rate=40;burst=0;lifetime=[.6,1.2];speed=[40,120];directionDeg=-90;spreadDeg=30;gravity=[0,0];drag=0;sizeStart=8;sizeEnd=2;colorStart=`#ffffff`;colorEnd=`#ffffff`;paletteColors=[];alphaStart=1;alphaEnd=0;shimmer=0;blend=`add`;maxParticles=256;static validateJson(e){let t=e;if(t.preset!==`custom`&&!pn.includes(t.preset))throw new N(`BAD_FORMAT`,`Particles2D '${e.name}' preset must be 'custom' or one of [${pn.join(`, `)}], got '${t.preset}'.`,{prop:`preset`,validOptions:pn});if(t.blend!==`add`&&t.blend!==`normal`)throw new N(`BAD_FORMAT`,`Particles2D '${e.name}' blend must be 'add' or 'normal', got '${t.blend}'.`,{prop:`blend`,validOptions:[`add`,`normal`]})}sim=null;bursted=!1;finishedEmitted=!1;_ensureSim(){if(!this.sim){mn(this,this.preset,qe(e.typeName));let t=this.tree?.engine?.rng??new P(4660);this.sim=new gn({rate:this.emitting?this.rate:0,lifetime:[this.lifetime[0]??1,this.lifetime[1]??1],speed:[this.speed[0]??0,this.speed[1]??0],directionDeg:this.directionDeg,spreadDeg:this.spreadDeg,gravity:[this.gravity[0]??0,this.gravity[1]??0,0],drag:this.drag,maxParticles:this.maxParticles},t)}return this.sim}update(e){let t=this._ensureSim();this.burst>0&&!this.bursted&&(this.bursted=!0,t.burst(this.burst)),t.update(e),(!this.emitting||this.rate===0)&&this.bursted&&t.done&&!this.finishedEmitted&&(this.finishedEmitted=!0,this.emit(`finished`))}replay(){this.bursted=!1,this.finishedEmitted=!1}mesh=null;paletteCache=[];paletteCacheKey=``;refreshPalette(){let e=this.paletteColors;if(e.length===0)return null;let t=e.join(`|`);if(t!==this.paletteCacheKey){this.paletteCacheKey=t;for(let t=0;t<e.length;t++){let n=this.paletteCache[t];n||(n=new K,this.paletteCache[t]=n),n.set(e[t])}this.paletteCache.length=e.length}return this.paletteCache}_syncObject2D(e){super._syncObject2D(e);let t=this._ensureSim();if(!this.mesh||this.mesh.count!==this.maxParticles){this.mesh&&this.mesh.removeFromParent();let e=new Ls({transparent:!0,depthWrite:!1,blending:this.blend===`add`?2:1});this.mesh=new xc(Ev,e,this.maxParticles),this.mesh.instanceMatrix.setUsage(Pi),this.mesh.frustumCulled=!1,this._ensureObject2D().add(this.mesh)}let n=this.mesh,r=this.refreshPalette(),i=r?null:kv.set(this.colorStart),a=Av.set(this.colorEnd),o=this.shimmer,s=0;t.forEach(e=>{let t=this.sizeStart+(this.sizeEnd-this.sizeStart)*e.t;Ov.makeScale(t,t,1),Ov.setPosition(e.x,-e.y,0),n.setMatrixAt(s,Ov);let c=r?r[Math.floor(e.seed*r.length)]:i,l=Math.max(0,this.alphaStart+(this.alphaEnd-this.alphaStart)*e.t);o>0&&(l*=.5+.5*Math.sin(2*Math.PI*(e.age*o+e.seed))),jv.copy(c).lerp(a,e.t).multiplyScalar(l),n.setColorAt(s,jv),s+=1}),n.count=s,n.instanceMatrix.needsUpdate=!0,n.instanceColor&&(n.instanceColor.needsUpdate=!0),n.renderOrder=this.effectiveRenderOrder}},Ov=new G,kv=new K,Av=new K,jv=new K;function Mv(e,t){let n=[],r=0;for(let i of e){let e=[];if(typeof i==`string`)for(let n of i){let r=t[n];if(r!==void 0)e.push(r);else if(n===`.`||n===` `)e.push(-1);else if(n>=`0`&&n<=`9`)e.push(n.charCodeAt(0)-48);else throw new N(`BAD_FORMAT`,`TileMap2D: unknown tile char '${n}' — add it to "legend" (char → tile index), or use '.'/' ' for empty and digits 0-9.`)}else for(let t of i)e.push(t);r=Math.max(r,e.length),n.push(e)}for(let e of n)for(;e.length<r;)e.push(-1);return n}function Nv(e,t){let n=e.length,r=n>0?e[0].length:0,i=e.map(e=>e.map(()=>!1)),a=(n,r)=>t.has(e[r][n]),o=[];for(let e=0;e<n;e++)for(let t=0;t<r;t++){if(!a(t,e)||i[e][t])continue;let s=1;for(;t+s<r&&a(t+s,e)&&!i[e][t+s];)s++;let c=1;grow:for(;e+c<n;){for(let n=0;n<s;n++)if(!a(t+n,e+c)||i[e+c][t+n])break grow;c++}for(let n=0;n<c;n++)for(let r=0;r<s;r++)i[e+n][t+r]=!0;o.push({x:t,y:e,w:s,h:c})}return o}var Pv=class extends q_{static typeName=`TileMap2D`;static props={texture:{default:``},tileSize:{default:32},columns:{default:0},cells:{default:[]},legend:{default:{}},solid:{default:[]},opacity:{default:1}};texture=``;tileSize=32;columns=0;_cells=[];_legend={};_solid=[];geometryDirty=!0;collidersDirty=!0;get cells(){return this._cells}set cells(e){this._cells=e,this.geometryDirty=!0,this.collidersDirty=!0}get legend(){return this._legend}set legend(e){this._legend=e,this.geometryDirty=!0,this.collidersDirty=!0}get solid(){return this._solid}set solid(e){this._solid=e,this.collidersDirty=!0}opacity=1;tileMesh=null;builtColumns=0;builtRows=0;static validateJson(e){let t=e;Mv(t._cells,t._legend)}grid(){return Mv(this._cells,this._legend)}onReady(){this.rebuildColliders()}update(e){this.collidersDirty&&this.rebuildColliders()}rebuildColliders(){this.collidersDirty=!1;for(let e of[...this.children])e.name.startsWith(`__tileSolid`)&&e.free();if(this._solid.length===0)return;let e=this.tileSize;Nv(this.grid(),new Set(this._solid)).forEach((t,n)=>{let r=new Y_(`__tileSolid${n}`);r.position=[(t.x+t.w/2)*e,(t.y+t.h/2)*e],r.collider={shape:`rect`,size:[t.w*e,t.h*e]},this.addChild(r)})}_mesh(){return this.tileMesh||(this.tileMesh=new Ys(new J,new Ls({transparent:!0,depthWrite:!1})),this._ensureObject2D().add(this.tileMesh)),this.tileMesh}_syncObject2D(e){super._syncObject2D(e);let t=this._mesh(),n=t.material;if(!this.texture||!e){t.visible=!1;return}let r=e.getTexture(this.texture),i=r.image;if(!i?.width||!i.height){t.visible=!1;return}t.visible=this.opacity>0,t.renderOrder=this.effectiveRenderOrder,n.opacity=this.opacity,n.map!==r&&(r.magFilter=rr,n.map=r,n.needsUpdate=!0,this.geometryDirty=!0);let a=this.columns>0?this.columns:Math.max(1,Math.floor(i.width/this.tileSize)),o=Math.max(1,Math.floor(i.height/this.tileSize));(a!==this.builtColumns||o!==this.builtRows)&&(this.geometryDirty=!0),this.geometryDirty&&(this.geometryDirty=!1,this.builtColumns=a,this.builtRows=o,this.buildGeometry(t.geometry,a,o))}buildGeometry(e,t,n){let r=this.grid(),i=this.tileSize,a=[],o=[],s=[];for(let e=0;e<r.length;e++){let c=r[e];for(let r=0;r<c.length;r++){let l=c[r];if(l<0)continue;let u=r*i,d=u+i,f=-(e*i),p=-((e+1)*i),m=a.length/3;a.push(u,f,0,d,f,0,d,p,0,u,p,0);let h=l%t,g=Math.floor(l/t),_=h/t,v=(h+1)/t,y=1-g/n,b=1-(g+1)/n;o.push(_,y,v,y,v,b,_,b),s.push(m,m+2,m+1,m,m+3,m+2)}}e.setAttribute(`position`,new q(new Float32Array(a),3)),e.setAttribute(`uv`,new q(new Float32Array(o),2)),e.setIndex(s),e.computeBoundingSphere()}get renderedTileCount(){let e=this.tileMesh?.geometry.getAttribute(`position`);return e?e.count/4:0}free(){this.tileMesh?.geometry.dispose(),super.free()}},Fv=[`top-left`,`top`,`top-right`,`left`,`center`,`right`,`bottom-left`,`bottom`,`bottom-right`],Iv=class extends Nt{static typeName=`UILayer`;static props={anchor:{default:`top-left`,options:Fv}};anchor=`top-left`;group=null;_ensureGroup(){return this.group||(this.group=new _o,this.group.userData.incantoNode=this),this.group}static validateJson(e){let t=e.anchor;if(!Fv.includes(t))throw new N(`BAD_FORMAT`,`UILayer '${e.name}' anchor must be one of [${Fv.join(`, `)}], got '${t}'.`,{prop:`anchor`,validOptions:Fv})}_anchorOrigin(e,t){let n=this.anchor;return{x:n.includes(`right`)?e:n===`top`||n===`center`||n===`bottom`?e/2:0,y:n.includes(`bottom`)?t:n===`left`||n===`center`||n===`right`?t/2:0}}};function Lv(){_n(),R(q_),R(gv),R(Cv),R(Dv),R(_v),R(yv),R(Tv),R(Iv),R(Y_),R(Z_),R(X_),R(Q_),R(xv),R(nv),R(Pv)}function Rv(e,t,n){return{x:(t-e.cx)*e.zoom+e.w/2,y:(n-e.cy)*e.zoom+e.h/2}}function zv(e,t,n){return{x:(t-e.w/2)/e.zoom+e.cx,y:(n-e.h/2)/e.zoom+e.cy}}var Bv=new Vo,Vv=new U,Hv=12,Uv=new Float32Array(16);function Wv(e){if(!(e instanceof q_))return null;let t=e._ensureObject2D();t.updateWorldMatrix(!0,!0),Bv.setFromObject(t),Bv.getSize(Vv);let n,r,i,a;if(!Number.isFinite(Vv.x)||Vv.x===0&&Vv.y===0){let e=new U().setFromMatrixPosition(t.matrixWorld);n=e.x-Hv,i=e.x+Hv,r=e.y-Hv,a=e.y+Hv}else n=Bv.min.x-2,i=Bv.max.x+2,r=Bv.min.y-2,a=Bv.max.y+2;let o=[n,r,i,r,i,r,i,a,i,a,n,a,n,a,n,r];return Uv.set(o),Uv}function Gv(){return{visited:new Set,cameras:[]}}function Kv(e,t,n,r,i,a,o){let s=a??Gv();s.visited.clear(),s.cameras.length=0,qv(e,t,n,!1,s.visited,s.cameras,r,i,o?.ignoreStatic===!0),Jv(t,s.visited),Jv(n,s.visited);let c=null;for(let e=0;e<s.cameras.length;e++){let t=s.cameras[e];if(t.current){c=t;break}}return c||=s.cameras[0]??null,{activeCamera:c}}function qv(e,t,n,r,i,a,o,s,c){let l=t,u=r;if(e instanceof q_&&!(e instanceof Iv)){let t=e._ensureObject2D();if(e.static&&!c&&t.userData.incantoStaticSynced===!0){t.userData.incantoStatic=!0,i.add(t);return}}if(e instanceof Iv){let t=e._ensureGroup();t.parent!==n&&n.add(t);let r=s?e._anchorOrigin(s.width,s.height):{x:0,y:0};t.position.set(r.x,-r.y,0),i.add(t),u=!0,l=t}else if(e instanceof q_){let n=e._ensureObject2D();n.parent!==t&&t.add(n),e._syncObject2D(o),i.add(n),e instanceof yv&&!r&&a.push(e),l=n}for(let t of e.children)qv(t,l,n,u,i,a,o,s,c);if(e instanceof q_&&!(e instanceof Iv)){let t=e._ensureObject2D();e.static&&!c?(t.userData.incantoStaticSynced=!0,t.userData.incantoStatic=!0):t.userData.incantoStaticSynced===!0&&(t.userData.incantoStaticSynced=!1,t.userData.incantoStatic=!1)}}function Jv(e,t){let n=e.children;for(let r=n.length-1;r>=0;r--){let i=n[r];i.userData.incantoNode&&!t.has(i)?e.remove(i):i.userData.incantoStatic!==!0&&Jv(i,t)}}var Yv=class{viewOverride=null;webgl;worldScene=new Eo;syncScratch=Gv();ignoreStatic=!1;uiScene=new Eo;worldCam=new vu(-1,1,1,-1,-1e3,1e3);uiCam=new vu(-1,1,1,-1,-1e3,1e3);engine;assets;loadedAssetScenes=new WeakSet;disconnect;canvas;constructor(e){this.canvas=e.canvas,this.engine=e.engine,this.assets=e.assets??new gm(void 0,this.engine);let t=vn(e.engine.scene?.environment,{antialias:!0,pixelRatio:1,preserveDrawingBuffer:!1},globalThis.devicePixelRatio??1,e);this.webgl=new hm({canvas:e.canvas,antialias:t.antialias,preserveDrawingBuffer:t.preserveDrawingBuffer}),this.webgl.info.autoReset=!1,this.engine.picker=(e,t)=>this.pick(e,t),this.webgl.setPixelRatio(t.pixelRatio),this.webgl.info.autoReset=!1,this.debugLines=new Hc(new J,new Ac({color:`#00ff6e`,transparent:!0,depthTest:!1})),this.debugLines.frustumCulled=!1,this.debugLines.renderOrder=9999,this.debugLines.visible=!1,this.worldScene.add(this.debugLines),this.selectionLines=new Hc(new J,new Ac({color:`#ffb020`,transparent:!0,depthTest:!1})),this.selectionLines.frustumCulled=!1,this.selectionLines.renderOrder=1e4,this.selectionLines.visible=!1,this.worldScene.add(this.selectionLines),this.disconnect=this.engine.updated.connect(()=>this.render())}debugLines;selectionLines;syncSelectionOutline(){let e=this.engine.debugSelection;e&&e.tree!==this.engine.scene?.tree&&(this.engine.debugSelection=null);let t=this.engine.debugSelection,n=t?Wv(t):null;if(this.selectionLines.visible=n!==null,!n)return;let r=new Float32Array(n.length/2*3);for(let e=0,t=0;e<n.length;e+=2,t+=3)r[t]=n[e],r[t+1]=n[e+1],r[t+2]=0;this.selectionLines.geometry.setAttribute(`position`,new q(r,3)),this.selectionLines.geometry.getAttribute(`position`).needsUpdate=!0}syncDebugLines(){let e=null;for(let t of tv(`2d`,this.engine))if(e=t.debugLines(),e)break;if(this.debugLines.visible=e!==null,!e)return;let t=new Float32Array(e.length/2*3);for(let n=0,r=0;n<e.length;n+=2,r+=3)t[r]=e[n],t[r+1]=e[n+1],t[r+2]=0;this.debugLines.geometry.setAttribute(`position`,new q(t,3))}render(){let e=this.engine.scene;if(!e)return;this.webgl.info.reset(),this.syncDebugLines(),this.syncSelectionOutline(),e.assets&&!this.loadedAssetScenes.has(e)&&(this.assets.load(e.assets),this.loadedAssetScenes.add(e));let t=e.environment?.background;this.worldScene.background=typeof t==`string`?new K(t):null;let n=this.canvas.clientWidth||this.canvas.width,r=this.canvas.clientHeight||this.canvas.height,i=this.webgl.getSize(Zv);(i.x!==n||i.y!==r)&&this.webgl.setSize(n,r,!1);let a=this.viewOverride?null:Tn(e.viewport),o=a?En(n,r,a):null,s=o?o.viewW:n,c=o?o.viewH:r,{activeCamera:l}=Kv(e.root,this.worldScene,this.uiScene,this.assets,{width:s,height:c},this.syncScratch),u=a?{x:a.design[0]/2,y:a.design[1]/2}:{x:n/2,y:r/2},d=1;this.viewOverride?(u={x:this.viewOverride.cx,y:this.viewOverride.cy},d=this.viewOverride.zoom):l&&(u=l.clampedCenter(s,c),d=l.effectiveZoom);let f=o?.scale??1;this.lastView={cx:u.x,cy:u.y,zoom:d*f,w:n,h:r},this.lastViewport=o,o&&(o.offsetX>.5||o.offsetY>.5)?(this.webgl.setScissorTest(!1),this.webgl.setViewport(0,0,n,r),this.webgl.clear(),this.webgl.setViewport(o.offsetX,o.offsetY,o.contentW,o.contentH),this.webgl.setScissor(o.offsetX,o.offsetY,o.contentW,o.contentH),this.webgl.setScissorTest(!0)):(this.webgl.setScissorTest(!1),this.webgl.setViewport(0,0,n,r)),Xv(this.worldCam,u.x,u.y,s/d,c/d),Xv(this.uiCam,s/2,c/2,s,c),this.webgl.info.reset(),this.webgl.autoClear=!0,this.webgl.render(this.worldScene,this.worldCam),this.webgl.autoClear=!1,this.webgl.render(this.uiScene,this.uiCam),this.webgl.autoClear=!0}lastViewport=null;lastView={cx:0,cy:0,zoom:1,w:1,h:1};view(){return{...this.lastView}}stats(){let e=this.webgl.info;return{triangles:e.render.triangles,drawCalls:e.render.calls,geometries:e.memory.geometries,textures:e.memory.textures}}worldFromScreen(e,t){return zv(this.lastView,e,t)}screenFromWorld(e,t){return Rv(this.lastView,e,t)}pick(e,t){let{w:n,h:r}=this.lastView,i=this.lastViewport?.offsetX??0,a=this.lastViewport?.offsetY??0,o=this.lastViewport?.contentW??n,s=this.lastViewport?.contentH??r;$v.set((e-i)/o*2-1,-((t-a)/s*2-1)),ey.setFromCamera($v,this.worldCam);let c=ey.intersectObjects(this.worldScene.children,!0),l=null;for(let e of c){let t=e.object;for(;t&&!t.userData.incantoNode;)t=t.parent;let n=t?.userData.incantoNode;if(!n)continue;let r=e.object.renderOrder??0;(!l||r>=l.order)&&(l={node:n,order:r})}return l?.node??null}boundsOf(e){let t=e._object2D;if(!t||(ty.makeEmpty(),ty.expandByObject(t),ty.isEmpty())||(ty.getSize(Qv),Qv.x===0&&Qv.y===0))return null;let n=this.screenFromWorld(ty.min.x,-ty.max.y),r=this.screenFromWorld(ty.max.x,-ty.min.y);return{x:n.x,y:n.y,w:r.x-n.x,h:r.y-n.y}}dispose(){this.engine.picker&&(this.engine.picker=null),this.disconnect();for(let e of[this.worldScene,this.uiScene])e.traverse(e=>{let t=e;if(!t.isMesh)return;let n=Array.isArray(t.material)?t.material:[t.material];for(let e of n)e?.map?.dispose(),e?.dispose()});this.webgl.dispose()}};function Xv(e,t,n,r,i){e.position.set(t,-n,10),e.left=-r/2,e.right=r/2,e.top=i/2,e.bottom=-i/2,e.updateProjectionMatrix()}var Zv=new V,Qv=new U,$v=new V,ey=new qu,ty=new Vo;async function ny(e){Lv(),(e.gameplay??!0)&&G_();for(let[t,n]of Object.entries(e.behaviors??{}))it(t,n,{replace:!0});let t=new kt({seed:e.seed,fixedHz:e.fixedHz,...e._scheduler?{scheduler:e._scheduler}:{}}),n=ry(e.scene),r=An(ry(n),{resolveScene:e.resolveScene,engine:t});t.setScene(r);let i=null;(e.physics===!0||(e.physics??`auto`)===`auto`&&iy(r.root))&&(i=await iv(t));let a=[],o=e.keyboard??(typeof window<`u`?window:!1);o&&t.input.attachKeyboard(o),a.push(ay(t,r.root,e.canvas)),a.push(t.settings.bindAudio(t.audio)),a.push(t.settings.bindLocale(t.locale));let s=e.touch??`auto`;if(s!==!1){let n=e.touchContainer??e.canvas.parentElement??null;if(n){let r={force:s===!0,...e._touchDoc?{doc:e._touchDoc}:{}},i=qn(t,n,r),o=t.sceneChanged.connect(()=>{i?.dispose(),i=qn(t,n,r)});a.push(()=>{o(),i?.dispose()})}}let c=e._rendererFactory?e._rendererFactory(t,e.canvas):new Yv({canvas:e.canvas,engine:t,...e.pixelRatio===void 0?{}:{pixelRatio:e.pixelRatio},...e.antialias===void 0?{}:{antialias:e.antialias}}),l=e.debug??!1,u=e.editor??l,d=u===!0?{}:u||null,f={label:`✎ edit this scene`,run:async()=>{if(!d)return;let t=d.open??Am,r=async t=>{await ny({...e,scene:t})};await jm(async()=>{p();try{await t({scene:n,play:r,exit:()=>r(n),...d.save?{save:d.save}:{},...d.library?{library:d.library===!0?wm():d.library}:{}})}catch(e){console.error(`[incanto] could not open the editor:`,e),await r(n)}},`opening the editor…`)}};if(l){let n=e.touchContainer??e.canvas.parentElement??(typeof document<`u`?document.body:null);if(n){let{attachDebugOverlay:r}=await bm(async()=>{let{attachDebugOverlay:e}=await import(`./debug-CPbraUYm.js`);return{attachDebugOverlay:e}},[],import.meta.url),i=r(t,{container:n,statsSource:()=>c.stats?.()??{},...d?{actions:[f]}:{},...e._debugDoc?{doc:e._debugDoc}:{}});i&&a.push(()=>i.dispose())}}t.start();function p(){Nm([i?[`physics`,()=>i?.dispose()]:null,[`app cleanups`,()=>{for(let e of a)e()}],[`engine`,()=>t.dispose()],[`renderer`,()=>c.dispose()]])}return{engine:t,scene:r,sourceJson:n,renderer:c,physics:i,pick(e,n){return t.picker?.(e,n)??null},stats(){return{triangles:0,drawCalls:0,geometries:0,textures:0,...t.stats(),...c.stats?.()}},openEditor:d?f.run:null,dispose:p}}function ry(e){try{return structuredClone(e)}catch{throw new N(`BAD_FORMAT`,`createGame "scene" must be plain scene JSON (the imported *.scene.json object) — got something unclonable (a loaded Scene, class instances, or functions).`)}}function iy(e){if(e instanceof J_)return!0;for(let t of e.children)if(iy(t))return!0;return!1}function ay(e,t,n){let r=[],i=n;if(i.addEventListener&&r.push({target:i,type:`pointerdown`}),typeof window<`u`&&r.push({target:window,type:`keydown`}),r.length===0)return()=>{};function a(){for(let e of r)e.target.removeEventListener?.(e.type,o)}function o(){e.sfx.unlock(),e.music.unlock();let n=!1,r=e=>{e instanceof Rt&&(e.retryPending(),e.pendingGesture&&(n=!0));for(let t of e.children)r(t)};r(t),n||a()}for(let e of r)e.target.addEventListener?.(e.type,o,{passive:!0});return a}function oy(e,t){let n=e;if(typeof n?.frame?.width!=`number`||typeof n.frame.height!=`number`||!n.animations||Object.keys(n.animations).length===0)throw new N(`BAD_FORMAT`,`Library sprite metadata needs {frame: {width, height}, animations: {<name>: {start, end, frameRate, repeat}}} — got ${JSON.stringify(e).slice(0,120)}.`);let r={},i=null,a=null;for(let[e,t]of Object.entries(n.animations)){if(typeof t.start!=`number`||typeof t.end!=`number`||typeof t.frameRate!=`number`)throw new N(`BAD_FORMAT`,`Library animation '${e}' needs numeric start/end/frameRate, got ${JSON.stringify(t)}.`);let n=t.repeat===-1;r[e]={frames:[t.start,t.end],fps:t.frameRate,loop:n},i??=e,n&&a===null&&(a=e)}let o=t.autoplay??a??i;return{asset:{type:`spritesheet`,url:t.url,frameWidth:n.frame.width,frameHeight:n.frame.height},props:{sheet:`$${t.assetKey}`,autoplay:o,animations:r}}}var sy=e({createGame2D:()=>ny,enablePhysics2D:()=>iv}),cy=(e,t,n)=>new Promise((r,i)=>{var a=e=>{try{s(n.next(e))}catch(e){i(e)}},o=e=>{try{s(n.throw(e))}catch(e){i(e)}},s=e=>e.done?r(e.value):Promise.resolve(e.value).then(a,o);s((n=n.apply(e,t)).next())}),ly=(e,t,n)=>new Promise((r,i)=>{var a=e=>{try{s(n.next(e))}catch(e){i(e)}},o=e=>{try{s(n.throw(e))}catch(e){i(e)}},s=e=>e.done?r(e.value):Promise.resolve(e.value).then(a,o);s((n=n.apply(e,t)).next())}),uy=class extends go{constructor(e){super(),this.weight=0,this.isBinary=!1,this.overrideBlink=`none`,this.overrideLookAt=`none`,this.overrideMouth=`none`,this._binds=[],this.name=`VRMExpression_${e}`,this.expressionName=e,this.type=`VRMExpression`,this.visible=!1}get binds(){return this._binds}get overrideBlinkAmount(){return this.overrideBlink===`block`?+(0<this.outputWeight):this.overrideBlink===`blend`?this.outputWeight:0}get overrideLookAtAmount(){return this.overrideLookAt===`block`?+(0<this.outputWeight):this.overrideLookAt===`blend`?this.outputWeight:0}get overrideMouthAmount(){return this.overrideMouth===`block`?+(0<this.outputWeight):this.overrideMouth===`blend`?this.outputWeight:0}get outputWeight(){return this.isBinary?+(this.weight>.5):this.weight}addBind(e){this._binds.push(e)}deleteBind(e){let t=this._binds.indexOf(e);t>=0&&this._binds.splice(t,1)}applyWeight(e){let t=this.outputWeight;t*=e?.multiplier??1,this.isBinary&&t<1&&(t=0),this._binds.forEach(e=>e.applyWeight(t))}clearAppliedWeight(){this._binds.forEach(e=>e.clearAppliedWeight())}};function dy(e,t,n){let r=e.parser.json,i=r.nodes?.[t];if(i==null)return console.warn(`extractPrimitivesInternal: Attempt to use nodes[${t}] of glTF but the node doesn't exist`),null;let a=i.mesh;if(a==null)return null;let o=r.meshes?.[a];if(o==null)return console.warn(`extractPrimitivesInternal: Attempt to use meshes[${a}] of glTF but the mesh doesn't exist`),null;let s=o.primitives.length,c=[];return n.traverse(e=>{c.length<s&&e.isMesh&&c.push(e)}),c}function fy(e,t){return ly(this,null,function*(){return dy(e,t,yield e.parser.getDependency(`node`,t))})}function py(e){return ly(this,null,function*(){let t=yield e.parser.getDependencies(`node`),n=new Map;return t.forEach((t,r)=>{let i=dy(e,r,t);i!=null&&n.set(r,i)}),n})}var my={Aa:`aa`,Ih:`ih`,Ou:`ou`,Ee:`ee`,Oh:`oh`,Blink:`blink`,Happy:`happy`,Angry:`angry`,Sad:`sad`,Relaxed:`relaxed`,LookUp:`lookUp`,Surprised:`surprised`,LookDown:`lookDown`,LookLeft:`lookLeft`,LookRight:`lookRight`,BlinkLeft:`blinkLeft`,BlinkRight:`blinkRight`,Neutral:`neutral`};function hy(e){return Math.max(Math.min(e,1),0)}var gy=class e{constructor(){this.blinkExpressionNames=[`blink`,`blinkLeft`,`blinkRight`],this.lookAtExpressionNames=[`lookLeft`,`lookRight`,`lookUp`,`lookDown`],this.mouthExpressionNames=[`aa`,`ee`,`ih`,`oh`,`ou`],this._expressions=[],this._expressionMap={}}get expressions(){return this._expressions.concat()}get expressionMap(){return Object.assign({},this._expressionMap)}get presetExpressionMap(){let e={},t=new Set(Object.values(my));return Object.entries(this._expressionMap).forEach(([n,r])=>{t.has(n)&&(e[n]=r)}),e}get customExpressionMap(){let e={},t=new Set(Object.values(my));return Object.entries(this._expressionMap).forEach(([n,r])=>{t.has(n)||(e[n]=r)}),e}copy(e){return this._expressions.concat().forEach(e=>{this.unregisterExpression(e)}),e._expressions.forEach(e=>{this.registerExpression(e)}),this.blinkExpressionNames=e.blinkExpressionNames.concat(),this.lookAtExpressionNames=e.lookAtExpressionNames.concat(),this.mouthExpressionNames=e.mouthExpressionNames.concat(),this}clone(){return new e().copy(this)}getExpression(e){return this._expressionMap[e]??null}registerExpression(e){this._expressions.push(e),this._expressionMap[e.expressionName]=e}unregisterExpression(e){let t=this._expressions.indexOf(e);t===-1&&console.warn(`VRMExpressionManager: The specified expressions is not registered`),this._expressions.splice(t,1),delete this._expressionMap[e.expressionName]}getValue(e){return this.getExpression(e)?.weight??null}setValue(e,t){let n=this.getExpression(e);n&&(n.weight=hy(t))}resetValues(){this._expressions.forEach(e=>{e.weight=0})}getExpressionTrackName(e){let t=this.getExpression(e);return t?`${t.name}.weight`:null}update(){let e=this._calculateWeightMultipliers();this._expressions.forEach(e=>{e.clearAppliedWeight()}),this._expressions.forEach(t=>{let n=1,r=t.expressionName;this.blinkExpressionNames.indexOf(r)!==-1&&(n*=e.blink),this.lookAtExpressionNames.indexOf(r)!==-1&&(n*=e.lookAt),this.mouthExpressionNames.indexOf(r)!==-1&&(n*=e.mouth),t.applyWeight({multiplier:n})})}_calculateWeightMultipliers(){let e=1,t=1,n=1;return this._expressions.forEach(r=>{e-=r.overrideBlinkAmount,t-=r.overrideLookAtAmount,n-=r.overrideMouthAmount}),e=Math.max(0,e),t=Math.max(0,t),n=Math.max(0,n),{blink:e,lookAt:t,mouth:n}}},_y={Color:`color`,EmissionColor:`emissionColor`,ShadeColor:`shadeColor`,MatcapColor:`matcapColor`,RimColor:`rimColor`,OutlineColor:`outlineColor`},vy={_Color:_y.Color,_EmissionColor:_y.EmissionColor,_ShadeColor:_y.ShadeColor,_RimColor:_y.RimColor,_OutlineColor:_y.OutlineColor},yy=new K,by=class e{constructor({material:e,type:t,targetValue:n,targetAlpha:r}){this.material=e,this.type=t,this.targetValue=n,this.targetAlpha=r??1;let i=this._initColorBindState(),a=this._initAlphaBindState();this._state={color:i,alpha:a}}applyWeight(e){let{color:t,alpha:n}=this._state;if(t!=null){let{propertyName:n,deltaValue:r}=t;this.material[n]?.add(yy.copy(r).multiplyScalar(e))}if(n!=null){let{propertyName:t,deltaValue:r}=n;this.material[t]!=null&&(this.material[t]+=r*e)}}clearAppliedWeight(){let{color:e,alpha:t}=this._state;if(e!=null){let{propertyName:t,initialValue:n}=e;this.material[t]?.copy(n)}if(t!=null){let{propertyName:e,initialValue:n}=t;this.material[e]!=null&&(this.material[e]=n)}}_initColorBindState(){let{material:e,type:t,targetValue:n}=this,r=this._getPropertyNameMap()?.[t]?.[0]??null;if(r==null)return console.warn(`Tried to add a material color bind to the material ${e.name??`(no name)`}, the type ${t} but the material or the type is not supported.`),null;let i=e[r].clone();return{propertyName:r,initialValue:i,deltaValue:new K(n.r-i.r,n.g-i.g,n.b-i.b)}}_initAlphaBindState(){let{material:e,type:t,targetAlpha:n}=this,r=this._getPropertyNameMap()?.[t]?.[1]??null;if(r==null&&n!==1)return console.warn(`Tried to add a material alpha bind to the material ${e.name??`(no name)`}, the type ${t} but the material or the type does not support alpha.`),null;if(r==null)return null;let i=e[r];return{propertyName:r,initialValue:i,deltaValue:n-i}}_getPropertyNameMap(){return Object.entries(e._propertyNameMapMap).find(([e])=>this.material[e]===!0)?.[1]??null}};by._propertyNameMapMap={isMeshStandardMaterial:{color:[`color`,`opacity`],emissionColor:[`emissive`,null]},isMeshBasicMaterial:{color:[`color`,`opacity`]},isMToonMaterial:{color:[`color`,`opacity`],emissionColor:[`emissive`,null],outlineColor:[`outlineColorFactor`,null],matcapColor:[`matcapFactor`,null],rimColor:[`parametricRimColorFactor`,null],shadeColor:[`shadeColorFactor`,null]}};var xy=by,Sy=class{constructor({primitives:e,index:t,weight:n}){this.primitives=e,this.index=t,this.weight=n}applyWeight(e){this.primitives.forEach(t=>{t.morphTargetInfluences?.[this.index]!=null&&(t.morphTargetInfluences[this.index]+=this.weight*e)})}clearAppliedWeight(){this.primitives.forEach(e=>{e.morphTargetInfluences?.[this.index]!=null&&(e.morphTargetInfluences[this.index]=0)})}},Cy=new V,wy=class e{constructor({material:t,scale:n,offset:r}){this.material=t,this.scale=n,this.offset=r;let i=Object.entries(e._propertyNamesMap).find(([e])=>t[e]===!0)?.[1];i==null?(console.warn(`Tried to add a texture transform bind to the material ${t.name??`(no name)`} but the material is not supported.`),this._properties=[]):(this._properties=[],i.forEach(e=>{let i=t[e]?.clone();if(!i)return null;t[e]=i;let a=i.offset.clone(),o=i.repeat.clone(),s=r.clone().sub(a),c=n.clone().sub(o);this._properties.push({name:e,initialOffset:a,deltaOffset:s,initialScale:o,deltaScale:c})}))}applyWeight(e){this._properties.forEach(t=>{let n=this.material[t.name];n!==void 0&&(n.offset.add(Cy.copy(t.deltaOffset).multiplyScalar(e)),n.repeat.add(Cy.copy(t.deltaScale).multiplyScalar(e)))})}clearAppliedWeight(){this._properties.forEach(e=>{let t=this.material[e.name];t!==void 0&&(t.offset.copy(e.initialOffset),t.repeat.copy(e.initialScale))})}};wy._propertyNamesMap={isMeshStandardMaterial:[`map`,`emissiveMap`,`bumpMap`,`normalMap`,`displacementMap`,`roughnessMap`,`metalnessMap`,`alphaMap`],isMeshBasicMaterial:[`map`,`specularMap`,`alphaMap`],isMToonMaterial:[`map`,`normalMap`,`emissiveMap`,`shadeMultiplyTexture`,`rimMultiplyTexture`,`outlineWidthMultiplyTexture`,`uvAnimationMaskTexture`]};var Ty=wy,Ey=new Set([`1.0`,`1.0-beta`]),Dy=class e{get name(){return`VRMExpressionLoaderPlugin`}constructor(e){this.parser=e}afterRoot(e){return ly(this,null,function*(){e.userData.vrmExpressionManager=yield this._import(e)})}_import(e){return ly(this,null,function*(){return(yield this._v1Import(e))||(yield this._v0Import(e))||null})}_v1Import(e){return ly(this,null,function*(){let t=this.parser.json;if(t.extensionsUsed?.indexOf(`VRMC_vrm`)===-1)return null;let n=t.extensions?.VRMC_vrm;if(!n)return null;let r=n.specVersion;if(!Ey.has(r))return console.warn(`VRMExpressionLoaderPlugin: Unknown VRMC_vrm specVersion "${r}"`),null;let i=n.expressions;if(!i)return null;let a=new Set(Object.values(my)),o=new Map;i.preset!=null&&Object.entries(i.preset).forEach(([e,t])=>{if(t!=null){if(!a.has(e)){console.warn(`VRMExpressionLoaderPlugin: Unknown preset name "${e}" detected. Ignoring the expression`);return}o.set(e,t)}}),i.custom!=null&&Object.entries(i.custom).forEach(([e,t])=>{if(a.has(e)){console.warn(`VRMExpressionLoaderPlugin: Custom expression cannot have preset name "${e}". Ignoring the expression`);return}o.set(e,t)});let s=new gy;return yield Promise.all(Array.from(o.entries()).map(t=>ly(this,[t],function*([t,n]){var r,i,a;let o=new uy(t);if(e.scene.add(o),o.isBinary=n.isBinary??!1,o.overrideBlink=n.overrideBlink??`none`,o.overrideLookAt=n.overrideLookAt??`none`,o.overrideMouth=n.overrideMouth??`none`,(r=n.morphTargetBinds)==null||r.forEach(t=>ly(this,null,function*(){if(t.node===void 0||t.index===void 0)return;let r=yield fy(e,t.node),i=t.index;if(!r.every(e=>Array.isArray(e.morphTargetInfluences)&&i<e.morphTargetInfluences.length)){console.warn(`VRMExpressionLoaderPlugin: ${n.name} attempts to index morph #${i} but not found.`);return}o.addBind(new Sy({primitives:r,index:i,weight:t.weight??1}))})),n.materialColorBinds||n.textureTransformBinds){let t=[];e.scene.traverse(e=>{let n=e.material;n&&(Array.isArray(n)?t.push(...n):t.push(n))}),(i=n.materialColorBinds)==null||i.forEach(e=>ly(this,null,function*(){t.filter(t=>{let n=this.parser.associations.get(t)?.materials;return e.material===n}).forEach(t=>{o.addBind(new xy({material:t,type:e.type,targetValue:new K().fromArray(e.targetValue),targetAlpha:e.targetValue[3]}))})})),(a=n.textureTransformBinds)==null||a.forEach(e=>ly(this,null,function*(){t.filter(t=>{let n=this.parser.associations.get(t)?.materials;return e.material===n}).forEach(t=>{o.addBind(new Ty({material:t,offset:new V().fromArray(e.offset??[0,0]),scale:new V().fromArray(e.scale??[1,1])}))})}))}s.registerExpression(o)}))),s})}_v0Import(t){return ly(this,null,function*(){let n=this.parser.json,r=n.extensions?.VRM;if(!r)return null;let i=r.blendShapeMaster;if(!i)return null;let a=new gy,o=i.blendShapeGroups;if(!o)return a;let s=new Set;return yield Promise.all(o.map(r=>ly(this,null,function*(){let i=r.presetName,o=(i!=null&&e.v0v1PresetNameMap[i]||null)??r.name;if(o==null){console.warn(`VRMExpressionLoaderPlugin: One of custom expressions has no name. Ignoring the expression`);return}if(s.has(o)){console.warn(`VRMExpressionLoaderPlugin: An expression preset ${i} has duplicated entries. Ignoring the expression`);return}s.add(o);let c=new uy(o);t.scene.add(c),c.isBinary=r.isBinary??!1,r.binds&&r.binds.forEach(e=>ly(this,null,function*(){var i;if(e.mesh===void 0||e.index===void 0)return;let a=[];(i=n.nodes)==null||i.forEach((t,n)=>{t.mesh===e.mesh&&a.push(n)});let o=e.index;yield Promise.all(a.map(n=>ly(this,null,function*(){let i=yield fy(t,n);if(!i.every(e=>Array.isArray(e.morphTargetInfluences)&&o<e.morphTargetInfluences.length)){console.warn(`VRMExpressionLoaderPlugin: ${r.name} attempts to index ${o}th morph but not found.`);return}c.addBind(new Sy({primitives:i,index:o,weight:.01*(e.weight??100)}))})))}));let l=r.materialValues;l&&l.length!==0&&l.forEach(e=>{if(e.materialName===void 0||e.propertyName===void 0||e.targetValue===void 0)return;let n=[];t.scene.traverse(t=>{if(t.material){let r=t.material;Array.isArray(r)?n.push(...r.filter(t=>(t.name===e.materialName||t.name===e.materialName+` (Outline)`)&&n.indexOf(t)===-1)):r.name===e.materialName&&n.indexOf(r)===-1&&n.push(r)}});let r=e.propertyName;n.forEach(t=>{if(r===`_MainTex_ST`){let n=new V(e.targetValue[0],e.targetValue[1]),r=new V(e.targetValue[2],e.targetValue[3]);r.y=1-r.y-n.y,c.addBind(new Ty({material:t,scale:n,offset:r}));return}let n=vy[r];if(n){c.addBind(new xy({material:t,type:n,targetValue:new K().fromArray(e.targetValue),targetAlpha:e.targetValue[3]}));return}console.warn(r+` is not supported`)})}),a.registerExpression(c)}))),a})}};Dy.v0v1PresetNameMap={a:`aa`,e:`ee`,i:`ih`,o:`oh`,u:`ou`,blink:`blink`,joy:`happy`,angry:`angry`,sorrow:`sad`,fun:`relaxed`,lookup:`lookUp`,lookdown:`lookDown`,lookleft:`lookLeft`,lookright:`lookRight`,blink_l:`blinkLeft`,blink_r:`blinkRight`,neutral:`neutral`};var Oy=Dy,ky=class e{constructor(t,n){this._firstPersonOnlyLayer=e.DEFAULT_FIRSTPERSON_ONLY_LAYER,this._thirdPersonOnlyLayer=e.DEFAULT_THIRDPERSON_ONLY_LAYER,this._initializedLayers=!1,this.humanoid=t,this.meshAnnotations=n}copy(e){if(this.humanoid!==e.humanoid)throw Error(`VRMFirstPerson: humanoid must be same in order to copy`);return this.meshAnnotations=e.meshAnnotations.map(e=>({meshes:e.meshes.concat(),type:e.type})),this}clone(){return new e(this.humanoid,this.meshAnnotations).copy(this)}get firstPersonOnlyLayer(){return this._firstPersonOnlyLayer}get thirdPersonOnlyLayer(){return this._thirdPersonOnlyLayer}setup({firstPersonOnlyLayer:t=e.DEFAULT_FIRSTPERSON_ONLY_LAYER,thirdPersonOnlyLayer:n=e.DEFAULT_THIRDPERSON_ONLY_LAYER}={}){this._initializedLayers||=(this._firstPersonOnlyLayer=t,this._thirdPersonOnlyLayer=n,this.meshAnnotations.forEach(e=>{e.meshes.forEach(t=>{e.type===`firstPersonOnly`?(t.layers.set(this._firstPersonOnlyLayer),t.traverse(e=>e.layers.set(this._firstPersonOnlyLayer))):e.type===`thirdPersonOnly`?(t.layers.set(this._thirdPersonOnlyLayer),t.traverse(e=>e.layers.set(this._thirdPersonOnlyLayer))):e.type===`auto`&&this._createHeadlessModel(t)})}),!0)}_excludeTriangles(e,t,n,r){let i=0;if(t!=null&&t.length>0)for(let a=0;a<e.length;a+=3){let o=e[a],s=e[a+1],c=e[a+2],l=t[o],u=n[o];if(l[0]>0&&r.includes(u[0])||l[1]>0&&r.includes(u[1])||l[2]>0&&r.includes(u[2])||l[3]>0&&r.includes(u[3]))continue;let d=t[s],f=n[s];if(d[0]>0&&r.includes(f[0])||d[1]>0&&r.includes(f[1])||d[2]>0&&r.includes(f[2])||d[3]>0&&r.includes(f[3]))continue;let p=t[c],m=n[c];p[0]>0&&r.includes(m[0])||p[1]>0&&r.includes(m[1])||p[2]>0&&r.includes(m[2])||p[3]>0&&r.includes(m[3])||(e[i++]=o,e[i++]=s,e[i++]=c)}return i}_createErasedMesh(e,t){let n=new sc(e.geometry.clone(),e.material);n.name=`${e.name}(erase)`,n.frustumCulled=e.frustumCulled,n.layers.set(this._firstPersonOnlyLayer);let r=n.geometry,i=r.getAttribute(`skinIndex`),a=i instanceof Gu?[]:i.array,o=[];for(let e=0;e<a.length;e+=4)o.push([a[e],a[e+1],a[e+2],a[e+3]]);let s=r.getAttribute(`skinWeight`),c=s instanceof Gu?[]:s.array,l=[];for(let e=0;e<c.length;e+=4)l.push([c[e],c[e+1],c[e+2],c[e+3]]);let u=r.getIndex();if(!u)throw Error(`The geometry doesn't have an index buffer`);let d=Array.from(u.array),f=this._excludeTriangles(d,l,o,t),p=[];for(let e=0;e<f;e++)p[e]=d[e];return r.setIndex(p),e.onBeforeRender&&(n.onBeforeRender=e.onBeforeRender),n.bind(new fc(e.skeleton.bones,e.skeleton.boneInverses),new G),n}_createHeadlessModelForSkinnedMesh(e,t){let n=[];if(t.skeleton.bones.forEach((e,t)=>{this._isEraseTarget(e)&&n.push(t)}),!n.length){t.layers.enable(this._thirdPersonOnlyLayer),t.layers.enable(this._firstPersonOnlyLayer);return}t.layers.set(this._thirdPersonOnlyLayer);let r=this._createErasedMesh(t,n);e.add(r)}_createHeadlessModel(e){if(e.type===`Group`)if(e.layers.set(this._thirdPersonOnlyLayer),this._isEraseTarget(e))e.traverse(e=>e.layers.set(this._thirdPersonOnlyLayer));else{let t=new _o;t.name=`_headless_${e.name}`,t.layers.set(this._firstPersonOnlyLayer),e.parent.add(t),e.children.filter(e=>e.type===`SkinnedMesh`).forEach(e=>{let n=e;this._createHeadlessModelForSkinnedMesh(t,n)})}else if(e.type===`SkinnedMesh`){let t=e;this._createHeadlessModelForSkinnedMesh(e.parent,t)}else this._isEraseTarget(e)&&(e.layers.set(this._thirdPersonOnlyLayer),e.traverse(e=>e.layers.set(this._thirdPersonOnlyLayer)))}_isEraseTarget(e){return e===this.humanoid.getRawBoneNode(`head`)?!0:e.parent?this._isEraseTarget(e.parent):!1}};ky.DEFAULT_FIRSTPERSON_ONLY_LAYER=9,ky.DEFAULT_THIRDPERSON_ONLY_LAYER=10;var Ay=ky,jy=new Set([`1.0`,`1.0-beta`]),My=class{get name(){return`VRMFirstPersonLoaderPlugin`}constructor(e){this.parser=e}afterRoot(e){return ly(this,null,function*(){let t=e.userData.vrmHumanoid;if(t!==null){if(t===void 0)throw Error(`VRMFirstPersonLoaderPlugin: vrmHumanoid is undefined. VRMHumanoidLoaderPlugin have to be used first`);e.userData.vrmFirstPerson=yield this._import(e,t)}})}_import(e,t){return ly(this,null,function*(){return t==null?null:(yield this._v1Import(e,t))||(yield this._v0Import(e,t))||null})}_v1Import(e,t){return ly(this,null,function*(){let n=this.parser.json;if(n.extensionsUsed?.indexOf(`VRMC_vrm`)===-1)return null;let r=n.extensions?.VRMC_vrm;if(!r)return null;let i=r.specVersion;if(!jy.has(i))return console.warn(`VRMFirstPersonLoaderPlugin: Unknown VRMC_vrm specVersion "${i}"`),null;let a=r.firstPerson,o=[],s=yield py(e);return Array.from(s.entries()).forEach(([e,t])=>{let n=(a?.meshAnnotations)?.find(t=>t.node===e);o.push({meshes:t,type:n?.type??`auto`})}),new Ay(t,o)})}_v0Import(e,t){return ly(this,null,function*(){let n=this.parser.json,r=n.extensions?.VRM;if(!r)return null;let i=r.firstPerson;if(!i)return null;let a=[],o=yield py(e);return Array.from(o.entries()).forEach(([e,t])=>{let r=n.nodes[e],o=i.meshAnnotations?i.meshAnnotations.find(e=>e.mesh===r.mesh):void 0;a.push({meshes:t,type:this._convertV0FlagToV1Type(o?.firstPersonFlag)})}),new Ay(t,a)})}_convertV0FlagToV1Type(e){return e===`FirstPersonOnly`?`firstPersonOnly`:e===`ThirdPersonOnly`?`thirdPersonOnly`:e===`Both`?`both`:`auto`}},Ny=new U,Py=new U,Fy=new H,Iy=class extends _o{constructor(e){super(),this.vrmHumanoid=e,this._boneAxesMap=new Map,Object.values(e.humanBones).forEach(e=>{let t=new Xu(1);t.matrixAutoUpdate=!1,t.material.depthTest=!1,t.material.depthWrite=!1,this.add(t),this._boneAxesMap.set(e,t)})}dispose(){Array.from(this._boneAxesMap.values()).forEach(e=>{e.geometry.dispose(),e.material.dispose()})}updateMatrixWorld(e){Array.from(this._boneAxesMap.entries()).forEach(([e,t])=>{e.node.updateWorldMatrix(!0,!1),e.node.matrixWorld.decompose(Ny,Fy,Py);let n=Ny.set(.1,.1,.1).divide(Py);t.matrix.copy(e.node.matrixWorld).scale(n)}),super.updateMatrixWorld(e)}},Ly=`hips.spine.chest.upperChest.neck.head.leftEye.rightEye.jaw.leftUpperLeg.leftLowerLeg.leftFoot.leftToes.rightUpperLeg.rightLowerLeg.rightFoot.rightToes.leftShoulder.leftUpperArm.leftLowerArm.leftHand.rightShoulder.rightUpperArm.rightLowerArm.rightHand.leftThumbMetacarpal.leftThumbProximal.leftThumbDistal.leftIndexProximal.leftIndexIntermediate.leftIndexDistal.leftMiddleProximal.leftMiddleIntermediate.leftMiddleDistal.leftRingProximal.leftRingIntermediate.leftRingDistal.leftLittleProximal.leftLittleIntermediate.leftLittleDistal.rightThumbMetacarpal.rightThumbProximal.rightThumbDistal.rightIndexProximal.rightIndexIntermediate.rightIndexDistal.rightMiddleProximal.rightMiddleIntermediate.rightMiddleDistal.rightRingProximal.rightRingIntermediate.rightRingDistal.rightLittleProximal.rightLittleIntermediate.rightLittleDistal`.split(`.`),Ry={hips:null,spine:`hips`,chest:`spine`,upperChest:`chest`,neck:`upperChest`,head:`neck`,leftEye:`head`,rightEye:`head`,jaw:`head`,leftUpperLeg:`hips`,leftLowerLeg:`leftUpperLeg`,leftFoot:`leftLowerLeg`,leftToes:`leftFoot`,rightUpperLeg:`hips`,rightLowerLeg:`rightUpperLeg`,rightFoot:`rightLowerLeg`,rightToes:`rightFoot`,leftShoulder:`upperChest`,leftUpperArm:`leftShoulder`,leftLowerArm:`leftUpperArm`,leftHand:`leftLowerArm`,rightShoulder:`upperChest`,rightUpperArm:`rightShoulder`,rightLowerArm:`rightUpperArm`,rightHand:`rightLowerArm`,leftThumbMetacarpal:`leftHand`,leftThumbProximal:`leftThumbMetacarpal`,leftThumbDistal:`leftThumbProximal`,leftIndexProximal:`leftHand`,leftIndexIntermediate:`leftIndexProximal`,leftIndexDistal:`leftIndexIntermediate`,leftMiddleProximal:`leftHand`,leftMiddleIntermediate:`leftMiddleProximal`,leftMiddleDistal:`leftMiddleIntermediate`,leftRingProximal:`leftHand`,leftRingIntermediate:`leftRingProximal`,leftRingDistal:`leftRingIntermediate`,leftLittleProximal:`leftHand`,leftLittleIntermediate:`leftLittleProximal`,leftLittleDistal:`leftLittleIntermediate`,rightThumbMetacarpal:`rightHand`,rightThumbProximal:`rightThumbMetacarpal`,rightThumbDistal:`rightThumbProximal`,rightIndexProximal:`rightHand`,rightIndexIntermediate:`rightIndexProximal`,rightIndexDistal:`rightIndexIntermediate`,rightMiddleProximal:`rightHand`,rightMiddleIntermediate:`rightMiddleProximal`,rightMiddleDistal:`rightMiddleIntermediate`,rightRingProximal:`rightHand`,rightRingIntermediate:`rightRingProximal`,rightRingDistal:`rightRingIntermediate`,rightLittleProximal:`rightHand`,rightLittleIntermediate:`rightLittleProximal`,rightLittleDistal:`rightLittleIntermediate`};function zy(e){return e.invert?e.invert():e.inverse(),e}var By=new U,Vy=new H,Hy=class{constructor(e){this.humanBones=e,this.restPose=this.getAbsolutePose()}getAbsolutePose(){let e={};return Object.keys(this.humanBones).forEach(t=>{let n=t,r=this.getBoneNode(n);r&&(By.copy(r.position),Vy.copy(r.quaternion),e[n]={position:By.toArray(),rotation:Vy.toArray()})}),e}getPose(){let e={};return Object.keys(this.humanBones).forEach(t=>{let n=t,r=this.getBoneNode(n);if(!r)return;By.set(0,0,0),Vy.identity();let i=this.restPose[n];i?.position&&By.fromArray(i.position).negate(),i?.rotation&&zy(Vy.fromArray(i.rotation)),By.add(r.position),Vy.premultiply(r.quaternion),e[n]={position:By.toArray(),rotation:Vy.toArray()}}),e}setPose(e){Object.entries(e).forEach(([e,t])=>{let n=e,r=this.getBoneNode(n);if(!r)return;let i=this.restPose[n];i&&(t?.position&&(r.position.fromArray(t.position),i.position&&r.position.add(By.fromArray(i.position))),t?.rotation&&(r.quaternion.fromArray(t.rotation),i.rotation&&r.quaternion.multiply(Vy.fromArray(i.rotation))))})}resetPose(){Object.entries(this.restPose).forEach(([e,t])=>{let n=this.getBoneNode(e);n&&(t?.position&&n.position.fromArray(t.position),t?.rotation&&n.quaternion.fromArray(t.rotation))})}getBone(e){return this.humanBones[e]??void 0}getBoneNode(e){return this.humanBones[e]?.node??null}},Uy=new U,Wy=new H,Gy=new U,Ky=class e extends Hy{static _setupTransforms(e){let t=new go;t.name=`VRMHumanoidRig`;let n={},r={},i={},a={};Ly.forEach(t=>{var o;let s=e.getBoneNode(t);if(s){let e=new U,c=new H;s.updateWorldMatrix(!0,!1),s.matrixWorld.decompose(e,c,Uy),n[t]=e,r[t]=c,i[t]=s.quaternion.clone();let l=new H;(o=s.parent)==null||o.matrixWorld.decompose(Uy,l,Uy),a[t]=l}});let o={};return Ly.forEach(r=>{let i=e.getBoneNode(r);if(i){let e=n[r],a=r,s;for(;s==null&&(a=Ry[a],a!=null);)s=n[a];let c=new go;c.name=`Normalized_`+i.name,(a?o[a]?.node:t).add(c),c.position.copy(e),s&&c.position.sub(s),o[r]={node:c}}}),{rigBones:o,root:t,parentWorldRotations:a,boneRotations:i}}constructor(t){let{rigBones:n,root:r,parentWorldRotations:i,boneRotations:a}=e._setupTransforms(t);super(n),this.original=t,this.root=r,this._parentWorldRotations=i,this._boneRotations=a}update(){Ly.forEach(e=>{let t=this.original.getBoneNode(e);if(t!=null){let n=this.getBoneNode(e),r=this._parentWorldRotations[e],i=Wy.copy(r).invert(),a=this._boneRotations[e];if(t.quaternion.copy(n.quaternion).multiply(r).premultiply(i).multiply(a),e===`hips`){let e=n.getWorldPosition(Gy);t.parent.updateWorldMatrix(!0,!1);let r=t.parent.matrixWorld,i=e.applyMatrix4(r.invert());t.position.copy(i)}}})}},qy=class e{get restPose(){return console.warn(`VRMHumanoid: restPose is deprecated. Use either rawRestPose or normalizedRestPose instead.`),this.rawRestPose}get rawRestPose(){return this._rawHumanBones.restPose}get normalizedRestPose(){return this._normalizedHumanBones.restPose}get humanBones(){return this._rawHumanBones.humanBones}get rawHumanBones(){return this._rawHumanBones.humanBones}get normalizedHumanBones(){return this._normalizedHumanBones.humanBones}get normalizedHumanBonesRoot(){return this._normalizedHumanBones.root}constructor(e,t){this.autoUpdateHumanBones=t?.autoUpdateHumanBones??!0,this._rawHumanBones=new Hy(e),this._normalizedHumanBones=new Ky(this._rawHumanBones)}copy(e){return this.autoUpdateHumanBones=e.autoUpdateHumanBones,this._rawHumanBones=new Hy(e.humanBones),this._normalizedHumanBones=new Ky(this._rawHumanBones),this}clone(){return new e(this.humanBones,{autoUpdateHumanBones:this.autoUpdateHumanBones}).copy(this)}getAbsolutePose(){return console.warn(`VRMHumanoid: getAbsolutePose() is deprecated. Use either getRawAbsolutePose() or getNormalizedAbsolutePose() instead.`),this.getRawAbsolutePose()}getRawAbsolutePose(){return this._rawHumanBones.getAbsolutePose()}getNormalizedAbsolutePose(){return this._normalizedHumanBones.getAbsolutePose()}getPose(){return console.warn(`VRMHumanoid: getPose() is deprecated. Use either getRawPose() or getNormalizedPose() instead.`),this.getRawPose()}getRawPose(){return this._rawHumanBones.getPose()}getNormalizedPose(){return this._normalizedHumanBones.getPose()}setPose(e){return console.warn(`VRMHumanoid: setPose() is deprecated. Use either setRawPose() or setNormalizedPose() instead.`),this.setRawPose(e)}setRawPose(e){return this._rawHumanBones.setPose(e)}setNormalizedPose(e){return this._normalizedHumanBones.setPose(e)}resetPose(){return console.warn(`VRMHumanoid: resetPose() is deprecated. Use either resetRawPose() or resetNormalizedPose() instead.`),this.resetRawPose()}resetRawPose(){return this._rawHumanBones.resetPose()}resetNormalizedPose(){return this._normalizedHumanBones.resetPose()}getBone(e){return console.warn(`VRMHumanoid: getBone() is deprecated. Use either getRawBone() or getNormalizedBone() instead.`),this.getRawBone(e)}getRawBone(e){return this._rawHumanBones.getBone(e)}getNormalizedBone(e){return this._normalizedHumanBones.getBone(e)}getBoneNode(e){return console.warn(`VRMHumanoid: getBoneNode() is deprecated. Use either getRawBoneNode() or getNormalizedBoneNode() instead.`),this.getRawBoneNode(e)}getRawBoneNode(e){return this._rawHumanBones.getBoneNode(e)}getNormalizedBoneNode(e){return this._normalizedHumanBones.getBoneNode(e)}update(){this.autoUpdateHumanBones&&this._normalizedHumanBones.update()}},Jy={Hips:`hips`,Spine:`spine`,Head:`head`,LeftUpperLeg:`leftUpperLeg`,LeftLowerLeg:`leftLowerLeg`,LeftFoot:`leftFoot`,RightUpperLeg:`rightUpperLeg`,RightLowerLeg:`rightLowerLeg`,RightFoot:`rightFoot`,LeftUpperArm:`leftUpperArm`,LeftLowerArm:`leftLowerArm`,LeftHand:`leftHand`,RightUpperArm:`rightUpperArm`,RightLowerArm:`rightLowerArm`,RightHand:`rightHand`},Yy=new Set([`1.0`,`1.0-beta`]),Xy={leftThumbProximal:`leftThumbMetacarpal`,leftThumbIntermediate:`leftThumbProximal`,rightThumbProximal:`rightThumbMetacarpal`,rightThumbIntermediate:`rightThumbProximal`},Zy=class{get name(){return`VRMHumanoidLoaderPlugin`}constructor(e,t){this.parser=e,this.helperRoot=t?.helperRoot,this.autoUpdateHumanBones=t?.autoUpdateHumanBones}afterRoot(e){return ly(this,null,function*(){e.userData.vrmHumanoid=yield this._import(e)})}_import(e){return ly(this,null,function*(){return(yield this._v1Import(e))||(yield this._v0Import(e))||null})}_v1Import(e){return ly(this,null,function*(){let t=this.parser.json;if(t.extensionsUsed?.indexOf(`VRMC_vrm`)===-1)return null;let n=t.extensions?.VRMC_vrm;if(!n)return null;let r=n.specVersion;if(!Yy.has(r))return console.warn(`VRMHumanoidLoaderPlugin: Unknown VRMC_vrm specVersion "${r}"`),null;let i=n.humanoid;if(!i)return null;let a=i.humanBones.leftThumbIntermediate!=null||i.humanBones.rightThumbIntermediate!=null,o={};i.humanBones!=null&&(yield Promise.all(Object.entries(i.humanBones).map(e=>ly(this,[e],function*([e,t]){let n=e,r=t.node;if(a){let e=Xy[n];e!=null&&(n=e)}let i=yield this.parser.getDependency(`node`,r);if(i==null){console.warn(`A glTF node bound to the humanoid bone ${n} (index = ${r}) does not exist`);return}o[n]={node:i}}))));let s=new qy(this._ensureRequiredBonesExist(o),{autoUpdateHumanBones:this.autoUpdateHumanBones});if(e.scene.add(s.normalizedHumanBonesRoot),this.helperRoot){let e=new Iy(s);this.helperRoot.add(e),e.renderOrder=this.helperRoot.renderOrder}return s})}_v0Import(e){return ly(this,null,function*(){let t=this.parser.json.extensions?.VRM;if(!t)return null;let n=t.humanoid;if(!n)return null;let r={};n.humanBones!=null&&(yield Promise.all(n.humanBones.map(e=>ly(this,null,function*(){let t=e.bone,n=e.node;if(t==null||n==null)return;let i=yield this.parser.getDependency(`node`,n);if(i==null){console.warn(`A glTF node bound to the humanoid bone ${t} (index = ${n}) does not exist`);return}let a=Xy[t]??t;if(r[a]!=null){console.warn(`Multiple bone entries for ${a} detected (index = ${n}), ignoring duplicated entries.`);return}r[a]={node:i}}))));let i=new qy(this._ensureRequiredBonesExist(r),{autoUpdateHumanBones:this.autoUpdateHumanBones});if(e.scene.add(i.normalizedHumanBonesRoot),this.helperRoot){let e=new Iy(i);this.helperRoot.add(e),e.renderOrder=this.helperRoot.renderOrder}return i})}_ensureRequiredBonesExist(e){let t=Object.values(Jy).filter(t=>e[t]==null);if(t.length>0)throw Error(`VRMHumanoidLoaderPlugin: These humanoid bones are required but not exist: ${t.join(`, `)}`);return e}},Qy=class extends J{constructor(){super(),this._currentTheta=0,this._currentRadius=0,this.theta=0,this.radius=0,this._currentTheta=0,this._currentRadius=0,this._attrPos=new q(new Float32Array(195),3),this.setAttribute(`position`,this._attrPos),this._attrIndex=new q(new Uint16Array(189),1),this.setIndex(this._attrIndex),this._buildIndex(),this.update()}update(){let e=!1;this._currentTheta!==this.theta&&(this._currentTheta=this.theta,e=!0),this._currentRadius!==this.radius&&(this._currentRadius=this.radius,e=!0),e&&this._buildPosition()}_buildPosition(){this._attrPos.setXYZ(0,0,0,0);for(let e=0;e<64;e++){let t=e/63*this._currentTheta;this._attrPos.setXYZ(e+1,this._currentRadius*Math.sin(t),0,this._currentRadius*Math.cos(t))}this._attrPos.needsUpdate=!0}_buildIndex(){for(let e=0;e<63;e++)this._attrIndex.setXYZ(e*3,0,e+1,e+2);this._attrIndex.needsUpdate=!0}},$y=class extends J{constructor(){super(),this.radius=0,this._currentRadius=0,this.tail=new U,this._currentTail=new U,this._attrPos=new q(new Float32Array(294),3),this.setAttribute(`position`,this._attrPos),this._attrIndex=new q(new Uint16Array(194),1),this.setIndex(this._attrIndex),this._buildIndex(),this.update()}update(){let e=!1;this._currentRadius!==this.radius&&(this._currentRadius=this.radius,e=!0),this._currentTail.equals(this.tail)||(this._currentTail.copy(this.tail),e=!0),e&&this._buildPosition()}_buildPosition(){for(let e=0;e<32;e++){let t=e/16*Math.PI;this._attrPos.setXYZ(e,Math.cos(t),Math.sin(t),0),this._attrPos.setXYZ(32+e,0,Math.cos(t),Math.sin(t)),this._attrPos.setXYZ(64+e,Math.sin(t),0,Math.cos(t))}this.scale(this._currentRadius,this._currentRadius,this._currentRadius),this.translate(this._currentTail.x,this._currentTail.y,this._currentTail.z),this._attrPos.setXYZ(96,0,0,0),this._attrPos.setXYZ(97,this._currentTail.x,this._currentTail.y,this._currentTail.z),this._attrPos.needsUpdate=!0}_buildIndex(){for(let e=0;e<32;e++){let t=(e+1)%32;this._attrIndex.setXY(e*2,e,t),this._attrIndex.setXY(64+e*2,32+e,32+t),this._attrIndex.setXY(128+e*2,64+e,64+t)}this._attrIndex.setXY(192,96,97),this._attrIndex.needsUpdate=!0}},eb=new H,tb=new H,nb=new U,rb=new U,ib=Math.sqrt(2)/2,ab=new H(0,0,-ib,ib),ob=new U(0,1,0),sb=class extends _o{constructor(e){super(),this.matrixAutoUpdate=!1,this.vrmLookAt=e;{let e=new Qy;e.radius=.5;let t=new Ls({color:65280,transparent:!0,opacity:.5,side:2,depthTest:!1,depthWrite:!1});this._meshPitch=new Ys(e,t),this.add(this._meshPitch)}{let e=new Qy;e.radius=.5;let t=new Ls({color:16711680,transparent:!0,opacity:.5,side:2,depthTest:!1,depthWrite:!1});this._meshYaw=new Ys(e,t),this.add(this._meshYaw)}{let e=new $y;e.radius=.1;let t=new Ac({color:16777215,depthTest:!1,depthWrite:!1});this._lineTarget=new Hc(e,t),this._lineTarget.frustumCulled=!1,this.add(this._lineTarget)}}dispose(){this._meshYaw.geometry.dispose(),this._meshYaw.material.dispose(),this._meshPitch.geometry.dispose(),this._meshPitch.material.dispose(),this._lineTarget.geometry.dispose(),this._lineTarget.material.dispose()}updateMatrixWorld(e){let t=ba.DEG2RAD*this.vrmLookAt.yaw;this._meshYaw.geometry.theta=t,this._meshYaw.geometry.update();let n=ba.DEG2RAD*this.vrmLookAt.pitch;this._meshPitch.geometry.theta=n,this._meshPitch.geometry.update(),this.vrmLookAt.getLookAtWorldPosition(nb),this.vrmLookAt.getLookAtWorldQuaternion(eb),eb.multiply(this.vrmLookAt.getFaceFrontQuaternion(tb)),this._meshYaw.position.copy(nb),this._meshYaw.quaternion.copy(eb),this._meshPitch.position.copy(nb),this._meshPitch.quaternion.copy(eb),this._meshPitch.quaternion.multiply(tb.setFromAxisAngle(ob,t)),this._meshPitch.quaternion.multiply(ab);let{target:r,autoUpdate:i}=this.vrmLookAt;r!=null&&i&&(r.getWorldPosition(rb).sub(nb),this._lineTarget.geometry.tail.copy(rb),this._lineTarget.geometry.update(),this._lineTarget.position.copy(nb)),super.updateMatrixWorld(e)}},cb=new U,lb=new U;function ub(e,t){return e.matrixWorld.decompose(cb,t,lb),t}function db(e){return[Math.atan2(-e.z,e.x),Math.atan2(e.y,Math.sqrt(e.x*e.x+e.z*e.z))]}function fb(e){let t=Math.round(e/2/Math.PI);return e-2*Math.PI*t}var pb=new U(0,0,1),mb=new U,hb=new U,gb=new U,_b=new H,vb=new H,yb=new H,bb=new H,xb=new Qa,Sb=class e{constructor(e,t){this.offsetFromHeadBone=new U,this.autoUpdate=!0,this.faceFront=new U(0,0,1),this.humanoid=e,this.applier=t,this._yaw=0,this._pitch=0,this._needsUpdate=!0,this._restHeadWorldQuaternion=this.getLookAtWorldQuaternion(new H)}get yaw(){return this._yaw}set yaw(e){this._yaw=e,this._needsUpdate=!0}get pitch(){return this._pitch}set pitch(e){this._pitch=e,this._needsUpdate=!0}get euler(){return console.warn(`VRMLookAt: euler is deprecated. use getEuler() instead.`),this.getEuler(new Qa)}getEuler(e){return e.set(ba.DEG2RAD*this._pitch,ba.DEG2RAD*this._yaw,0,`YXZ`)}copy(e){if(this.humanoid!==e.humanoid)throw Error(`VRMLookAt: humanoid must be same in order to copy`);return this.offsetFromHeadBone.copy(e.offsetFromHeadBone),this.applier=e.applier,this.autoUpdate=e.autoUpdate,this.target=e.target,this.faceFront.copy(e.faceFront),this}clone(){return new e(this.humanoid,this.applier).copy(this)}reset(){this._yaw=0,this._pitch=0,this._needsUpdate=!0}getLookAtWorldPosition(e){let t=this.humanoid.getRawBoneNode(`head`);return e.copy(this.offsetFromHeadBone).applyMatrix4(t.matrixWorld)}getLookAtWorldQuaternion(e){return ub(this.humanoid.getRawBoneNode(`head`),e)}getFaceFrontQuaternion(e){if(this.faceFront.distanceToSquared(pb)<.01)return e.copy(this._restHeadWorldQuaternion).invert();let[t,n]=db(this.faceFront);return xb.set(0,.5*Math.PI+t,n,`YZX`),e.setFromEuler(xb).premultiply(bb.copy(this._restHeadWorldQuaternion).invert())}getLookAtWorldDirection(e){return this.getLookAtWorldQuaternion(vb),this.getFaceFrontQuaternion(yb),e.copy(pb).applyQuaternion(vb).applyQuaternion(yb).applyEuler(this.getEuler(xb))}lookAt(e){let t=_b.copy(this._restHeadWorldQuaternion).multiply(zy(this.getLookAtWorldQuaternion(vb))),n=this.getLookAtWorldPosition(hb),r=gb.copy(e).sub(n).applyQuaternion(t).normalize(),[i,a]=db(this.faceFront),[o,s]=db(r),c=fb(o-i),l=fb(a-s);this._yaw=ba.RAD2DEG*c,this._pitch=ba.RAD2DEG*l,this._needsUpdate=!0}update(e){this.target!=null&&this.autoUpdate&&this.lookAt(this.target.getWorldPosition(mb)),this._needsUpdate&&(this._needsUpdate=!1,this.applier.applyYawPitch(this._yaw,this._pitch))}};Sb.EULER_ORDER=`YXZ`;var Cb=Sb,wb=new U(0,0,1),Tb=new H,Eb=new H,Db=new Qa(0,0,0,`YXZ`),Ob=class{constructor(e,t,n,r,i){this.humanoid=e,this.rangeMapHorizontalInner=t,this.rangeMapHorizontalOuter=n,this.rangeMapVerticalDown=r,this.rangeMapVerticalUp=i,this.faceFront=new U(0,0,1),this._restQuatLeftEye=new H,this._restQuatRightEye=new H,this._restLeftEyeParentWorldQuat=new H,this._restRightEyeParentWorldQuat=new H;let a=this.humanoid.getRawBoneNode(`leftEye`),o=this.humanoid.getRawBoneNode(`rightEye`);a&&(this._restQuatLeftEye.copy(a.quaternion),ub(a.parent,this._restLeftEyeParentWorldQuat)),o&&(this._restQuatRightEye.copy(o.quaternion),ub(o.parent,this._restRightEyeParentWorldQuat))}applyYawPitch(e,t){let n=this.humanoid.getRawBoneNode(`leftEye`),r=this.humanoid.getRawBoneNode(`rightEye`),i=this.humanoid.getNormalizedBoneNode(`leftEye`),a=this.humanoid.getNormalizedBoneNode(`rightEye`);n&&(t<0?Db.x=-ba.DEG2RAD*this.rangeMapVerticalDown.map(-t):Db.x=ba.DEG2RAD*this.rangeMapVerticalUp.map(t),e<0?Db.y=-ba.DEG2RAD*this.rangeMapHorizontalInner.map(-e):Db.y=ba.DEG2RAD*this.rangeMapHorizontalOuter.map(e),Tb.setFromEuler(Db),this._getWorldFaceFrontQuat(Eb),i.quaternion.copy(Eb).multiply(Tb).multiply(Eb.invert()),Tb.copy(this._restLeftEyeParentWorldQuat),n.quaternion.copy(i.quaternion).multiply(Tb).premultiply(Tb.invert()).multiply(this._restQuatLeftEye)),r&&(t<0?Db.x=-ba.DEG2RAD*this.rangeMapVerticalDown.map(-t):Db.x=ba.DEG2RAD*this.rangeMapVerticalUp.map(t),e<0?Db.y=-ba.DEG2RAD*this.rangeMapHorizontalOuter.map(-e):Db.y=ba.DEG2RAD*this.rangeMapHorizontalInner.map(e),Tb.setFromEuler(Db),this._getWorldFaceFrontQuat(Eb),a.quaternion.copy(Eb).multiply(Tb).multiply(Eb.invert()),Tb.copy(this._restRightEyeParentWorldQuat),r.quaternion.copy(a.quaternion).multiply(Tb).premultiply(Tb.invert()).multiply(this._restQuatRightEye))}lookAt(e){console.warn(`VRMLookAtBoneApplier: lookAt() is deprecated. use apply() instead.`);let t=ba.RAD2DEG*e.y,n=ba.RAD2DEG*e.x;this.applyYawPitch(t,n)}_getWorldFaceFrontQuat(e){if(this.faceFront.distanceToSquared(wb)<.01)return e.identity();let[t,n]=db(this.faceFront);return Db.set(0,.5*Math.PI+t,n,`YZX`),e.setFromEuler(Db)}};Ob.type=`bone`;var kb=class{constructor(e,t,n,r,i){this.expressions=e,this.rangeMapHorizontalInner=t,this.rangeMapHorizontalOuter=n,this.rangeMapVerticalDown=r,this.rangeMapVerticalUp=i}applyYawPitch(e,t){t<0?(this.expressions.setValue(`lookDown`,0),this.expressions.setValue(`lookUp`,this.rangeMapVerticalUp.map(-t))):(this.expressions.setValue(`lookUp`,0),this.expressions.setValue(`lookDown`,this.rangeMapVerticalDown.map(t))),e<0?(this.expressions.setValue(`lookLeft`,0),this.expressions.setValue(`lookRight`,this.rangeMapHorizontalOuter.map(-e))):(this.expressions.setValue(`lookRight`,0),this.expressions.setValue(`lookLeft`,this.rangeMapHorizontalOuter.map(e)))}lookAt(e){console.warn(`VRMLookAtBoneApplier: lookAt() is deprecated. use apply() instead.`);let t=ba.RAD2DEG*e.y,n=ba.RAD2DEG*e.x;this.applyYawPitch(t,n)}};kb.type=`expression`;var Ab=class{constructor(e,t){this.inputMaxValue=e,this.outputScale=t}map(e){return this.outputScale*hy(e/this.inputMaxValue)}},jb=new Set([`1.0`,`1.0-beta`]),Mb=.01,Nb=class{get name(){return`VRMLookAtLoaderPlugin`}constructor(e,t){this.parser=e,this.helperRoot=t?.helperRoot}afterRoot(e){return ly(this,null,function*(){let t=e.userData.vrmHumanoid;if(t===null)return;if(t===void 0)throw Error(`VRMLookAtLoaderPlugin: vrmHumanoid is undefined. VRMHumanoidLoaderPlugin have to be used first`);let n=e.userData.vrmExpressionManager;if(n!==null){if(n===void 0)throw Error(`VRMLookAtLoaderPlugin: vrmExpressionManager is undefined. VRMExpressionLoaderPlugin have to be used first`);e.userData.vrmLookAt=yield this._import(e,t,n)}})}_import(e,t,n){return ly(this,null,function*(){return t==null||n==null?null:(yield this._v1Import(e,t,n))||(yield this._v0Import(e,t,n))||null})}_v1Import(e,t,n){return ly(this,null,function*(){let e=this.parser.json;if(e.extensionsUsed?.indexOf(`VRMC_vrm`)===-1)return null;let r=e.extensions?.VRMC_vrm;if(!r)return null;let i=r.specVersion;if(!jb.has(i))return console.warn(`VRMLookAtLoaderPlugin: Unknown VRMC_vrm specVersion "${i}"`),null;let a=r.lookAt;if(!a)return null;let o=a.type===`expression`?1:10,s=this._v1ImportRangeMap(a.rangeMapHorizontalInner,o),c=this._v1ImportRangeMap(a.rangeMapHorizontalOuter,o),l=this._v1ImportRangeMap(a.rangeMapVerticalDown,o),u=this._v1ImportRangeMap(a.rangeMapVerticalUp,o),d;d=a.type===`expression`?new kb(n,s,c,l,u):new Ob(t,s,c,l,u);let f=this._importLookAt(t,d);return f.offsetFromHeadBone.fromArray(a.offsetFromHeadBone??[0,.06,0]),f})}_v1ImportRangeMap(e,t){let n=e?.inputMaxValue??90,r=e?.outputScale??t;return n<Mb&&(console.warn(`VRMLookAtLoaderPlugin: inputMaxValue of a range map is too small. Consider reviewing the range map!`),n=Mb),new Ab(n,r)}_v0Import(e,t,n){return ly(this,null,function*(){let e=this.parser.json.extensions?.VRM;if(!e)return null;let r=e.firstPerson;if(!r)return null;let i=r.lookAtTypeName===`BlendShape`?1:10,a=this._v0ImportDegreeMap(r.lookAtHorizontalInner,i),o=this._v0ImportDegreeMap(r.lookAtHorizontalOuter,i),s=this._v0ImportDegreeMap(r.lookAtVerticalDown,i),c=this._v0ImportDegreeMap(r.lookAtVerticalUp,i),l;l=r.lookAtTypeName===`BlendShape`?new kb(n,a,o,s,c):new Ob(t,a,o,s,c);let u=this._importLookAt(t,l);return r.firstPersonBoneOffset?u.offsetFromHeadBone.set(r.firstPersonBoneOffset.x??0,r.firstPersonBoneOffset.y??.06,-(r.firstPersonBoneOffset.z??0)):u.offsetFromHeadBone.set(0,.06,0),u.faceFront.set(0,0,-1),l instanceof Ob&&l.faceFront.set(0,0,-1),u})}_v0ImportDegreeMap(e,t){let n=e?.curve;JSON.stringify(n)!==`[0,0,0,1,1,1,1,0]`&&console.warn(`Curves of LookAtDegreeMap defined in VRM 0.0 are not supported`);let r=e?.xRange??90,i=e?.yRange??t;return r<Mb&&(console.warn(`VRMLookAtLoaderPlugin: xRange of a degree map is too small. Consider reviewing the degree map!`),r=Mb),new Ab(r,i)}_importLookAt(e,t){let n=new Cb(e,t);if(this.helperRoot){let e=new sb(n);this.helperRoot.add(e),e.renderOrder=this.helperRoot.renderOrder}return n}};function Pb(e,t){return typeof e!=`string`||e===``?``:(/^https?:\/\//i.test(t)&&/^\//.test(e)&&(t=t.replace(/(^https?:\/\/[^/]+).*/i,`$1`)),/^(https?:)?\/\//i.test(e)||/^data:.*,.*$/i.test(e)||/^blob:.*$/i.test(e)?e:t+e)}var Fb=new Set([`1.0`,`1.0-beta`]),Ib=class{get name(){return`VRMMetaLoaderPlugin`}constructor(e,t){this.parser=e,this.needThumbnailImage=t?.needThumbnailImage??!1,this.acceptLicenseUrls=t?.acceptLicenseUrls??[`https://vrm.dev/licenses/1.0/`],this.acceptV0Meta=t?.acceptV0Meta??!0}afterRoot(e){return ly(this,null,function*(){e.userData.vrmMeta=yield this._import(e)})}_import(e){return ly(this,null,function*(){return(yield this._v1Import(e))??(yield this._v0Import(e))??null})}_v1Import(e){return ly(this,null,function*(){let e=this.parser.json;if(e.extensionsUsed?.indexOf(`VRMC_vrm`)===-1)return null;let t=e.extensions?.VRMC_vrm;if(t==null)return null;let n=t.specVersion;if(!Fb.has(n))return console.warn(`VRMMetaLoaderPlugin: Unknown VRMC_vrm specVersion "${n}"`),null;let r=t.meta;if(!r)return null;let i=r.licenseUrl;if(!new Set(this.acceptLicenseUrls).has(i))throw Error(`VRMMetaLoaderPlugin: The license url "${i}" is not accepted`);let a;return this.needThumbnailImage&&r.thumbnailImage!=null&&(a=(yield this._extractGLTFImage(r.thumbnailImage))??void 0),{metaVersion:`1`,name:r.name,version:r.version,authors:r.authors,copyrightInformation:r.copyrightInformation,contactInformation:r.contactInformation,references:r.references,thirdPartyLicenses:r.thirdPartyLicenses,thumbnailImage:a,licenseUrl:r.licenseUrl,avatarPermission:r.avatarPermission,allowExcessivelyViolentUsage:r.allowExcessivelyViolentUsage,allowExcessivelySexualUsage:r.allowExcessivelySexualUsage,commercialUsage:r.commercialUsage,allowPoliticalOrReligiousUsage:r.allowPoliticalOrReligiousUsage,allowAntisocialOrHateUsage:r.allowAntisocialOrHateUsage,creditNotation:r.creditNotation,allowRedistribution:r.allowRedistribution,modification:r.modification,otherLicenseUrl:r.otherLicenseUrl}})}_v0Import(e){return ly(this,null,function*(){let e=this.parser.json.extensions?.VRM;if(!e)return null;let t=e.meta;if(!t)return null;if(!this.acceptV0Meta)throw Error(`VRMMetaLoaderPlugin: Attempted to load VRM0.0 meta but acceptV0Meta is false`);let n;return this.needThumbnailImage&&t.texture!=null&&t.texture!==-1&&(n=yield this.parser.getDependency(`texture`,t.texture)),{metaVersion:`0`,allowedUserName:t.allowedUserName,author:t.author,commercialUssageName:t.commercialUssageName,contactInformation:t.contactInformation,licenseName:t.licenseName,otherLicenseUrl:t.otherLicenseUrl,otherPermissionUrl:t.otherPermissionUrl,reference:t.reference,sexualUssageName:t.sexualUssageName,texture:n??void 0,title:t.title,version:t.version,violentUssageName:t.violentUssageName}})}_extractGLTFImage(e){return ly(this,null,function*(){let t=this.parser.json.images?.[e];if(t==null)return console.warn(`VRMMetaLoaderPlugin: Attempt to use images[${e}] of glTF as a thumbnail but the image doesn't exist`),null;let n=t.uri;if(t.bufferView!=null){let e=yield this.parser.getDependency(`bufferView`,t.bufferView),r=new Blob([e],{type:t.mimeType});n=URL.createObjectURL(r)}return n==null?(console.warn(`VRMMetaLoaderPlugin: Attempt to use images[${e}] of glTF as a thumbnail but the image couldn't load properly`),null):yield new Ql().loadAsync(Pb(n,this.parser.options.path)).catch(e=>(console.error(e),console.warn(`VRMMetaLoaderPlugin: Failed to load a thumbnail image`),null))})}},Lb=class{constructor(e){this.scene=e.scene,this.meta=e.meta,this.humanoid=e.humanoid,this.expressionManager=e.expressionManager,this.firstPerson=e.firstPerson,this.lookAt=e.lookAt}update(e){this.humanoid.update(),this.lookAt&&this.lookAt.update(e),this.expressionManager&&this.expressionManager.update()}},Rb=class extends Lb{constructor(e){super(e),this.materials=e.materials,this.springBoneManager=e.springBoneManager,this.nodeConstraintManager=e.nodeConstraintManager}update(e){super.update(e),this.nodeConstraintManager&&this.nodeConstraintManager.update(),this.springBoneManager&&this.springBoneManager.update(e),this.materials&&this.materials.forEach(t=>{t.update&&t.update(e)})}},zb=Object.defineProperty,Bb=Object.getOwnPropertySymbols,Vb=Object.prototype.hasOwnProperty,Hb=Object.prototype.propertyIsEnumerable,Ub=(e,t,n)=>t in e?zb(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,Wb=(e,t)=>{for(var n in t||={})Vb.call(t,n)&&Ub(e,n,t[n]);if(Bb)for(var n of Bb(t))Hb.call(t,n)&&Ub(e,n,t[n]);return e},Gb=(e,t,n)=>new Promise((r,i)=>{var a=e=>{try{s(n.next(e))}catch(e){i(e)}},o=e=>{try{s(n.throw(e))}catch(e){i(e)}},s=e=>e.done?r(e.value):Promise.resolve(e.value).then(a,o);s((n=n.apply(e,t)).next())});function Kb(e,t){e.colorSpace=t}var qb=class{get pending(){return Promise.all(this._pendings)}constructor(e,t){this._parser=e,this._materialParams=t,this._pendings=[]}assignPrimitive(e,t){t!=null&&(this._materialParams[e]=t)}assignColor(e,t,n){if(t!=null){let r=new K().fromArray(t);n&&r.convertSRGBToLinear(),this._materialParams[e]=r}}assignTexture(e,t,n){return Gb(this,null,function*(){let r=Gb(this,null,function*(){if(t!=null){let r=yield this._parser.assignTexture(this._materialParams,e,t);if(r==null){console.warn(`GLTFMToonMaterialParamsAssignHelper: Failed to load texture. The rendering result may be wrong`);return}n&&Kb(r,`srgb`)}});return this._pendings.push(r),r})}assignTextureByIndex(e,t,n){return Gb(this,null,function*(){return this.assignTexture(e,t==null?void 0:{index:t},n)})}},Jb=`// #define PHONG
|
|
5757
5757
|
|
|
5758
5758
|
varying vec3 vViewPosition;
|
|
5759
5759
|
|
|
@@ -5871,7 +5871,7 @@ void main() {
|
|
|
5871
5871
|
#include <shadowmap_vertex>
|
|
5872
5872
|
#include <fog_vertex>
|
|
5873
5873
|
|
|
5874
|
-
}`,
|
|
5874
|
+
}`,Yb=`// #define PHONG
|
|
5875
5875
|
|
|
5876
5876
|
uniform vec3 litFactor;
|
|
5877
5877
|
|
|
@@ -6684,17 +6684,17 @@ void main() {
|
|
|
6684
6684
|
gl_FragColor = vec4( col, diffuseColor.a );
|
|
6685
6685
|
postCorrection();
|
|
6686
6686
|
}
|
|
6687
|
-
`,
|
|
6687
|
+
`,Xb={None:`none`,Normal:`normal`,LitShadeRate:`litShadeRate`,UV:`uv`},Zb={None:`none`,WorldCoordinates:`worldCoordinates`,ScreenCoordinates:`screenCoordinates`};function Qb(e){return e.colorSpace}var $b=class extends vl{constructor(e={}){super({vertexShader:Jb,fragmentShader:Yb}),this.uvAnimationScrollXSpeedFactor=0,this.uvAnimationScrollYSpeedFactor=0,this.uvAnimationRotationSpeedFactor=0,this.fog=!0,this.normalMapType=0,this._ignoreVertexColor=!0,this._v0CompatShade=!1,this._debugMode=Xb.None,this._outlineWidthMode=Zb.None,this._isOutline=!1,e.transparentWithZWrite&&(e.depthWrite=!0),delete e.transparentWithZWrite,e.fog=!0,e.lights=!0,e.clipping=!0,this.uniforms=hl.merge([X.common,X.normalmap,X.emissivemap,X.fog,X.lights,{litFactor:{value:new K(1,1,1)},mapUvTransform:{value:new W},colorAlpha:{value:1},normalMapUvTransform:{value:new W},shadeColorFactor:{value:new K(0,0,0)},shadeMultiplyTexture:{value:null},shadeMultiplyTextureUvTransform:{value:new W},shadingShiftFactor:{value:0},shadingShiftTexture:{value:null},shadingShiftTextureUvTransform:{value:new W},shadingShiftTextureScale:{value:1},shadingToonyFactor:{value:.9},giEqualizationFactor:{value:.9},matcapFactor:{value:new K(1,1,1)},matcapTexture:{value:null},matcapTextureUvTransform:{value:new W},parametricRimColorFactor:{value:new K(0,0,0)},rimMultiplyTexture:{value:null},rimMultiplyTextureUvTransform:{value:new W},rimLightingMixFactor:{value:1},parametricRimFresnelPowerFactor:{value:5},parametricRimLiftFactor:{value:0},emissive:{value:new K(0,0,0)},emissiveIntensity:{value:1},emissiveMapUvTransform:{value:new W},outlineWidthMultiplyTexture:{value:null},outlineWidthMultiplyTextureUvTransform:{value:new W},outlineWidthFactor:{value:0},outlineColorFactor:{value:new K(0,0,0)},outlineLightingMixFactor:{value:1},uvAnimationMaskTexture:{value:null},uvAnimationMaskTextureUvTransform:{value:new W},uvAnimationScrollXOffset:{value:0},uvAnimationScrollYOffset:{value:0},uvAnimationRotationPhase:{value:0}},e.uniforms??{}]),this.setValues(e),this._uploadUniformsWorkaround(),this.customProgramCacheKey=()=>[...Object.entries(this._generateDefines()).map(([e,t])=>`${e}:${t}`),this.matcapTexture?`matcapTextureColorSpace:${Qb(this.matcapTexture)}`:``,this.shadeMultiplyTexture?`shadeMultiplyTextureColorSpace:${Qb(this.shadeMultiplyTexture)}`:``,this.rimMultiplyTexture?`rimMultiplyTextureColorSpace:${Qb(this.rimMultiplyTexture)}`:``].join(`,`),this.onBeforeCompile=e=>{let t=Object.entries(Wb(Wb({},this._generateDefines()),this.defines)).filter(([e,t])=>!!t).map(([e,t])=>`#define ${e} ${t}`).join(`
|
|
6688
6688
|
`)+`
|
|
6689
|
-
`;e.vertexShader=t+e.vertexShader,e.fragmentShader=t+e.fragmentShader}}get color(){return this.uniforms.litFactor.value}set color(e){this.uniforms.litFactor.value=e}get map(){return this.uniforms.map.value}set map(e){this.uniforms.map.value=e}get normalMap(){return this.uniforms.normalMap.value}set normalMap(e){this.uniforms.normalMap.value=e}get normalScale(){return this.uniforms.normalScale.value}set normalScale(e){this.uniforms.normalScale.value=e}get emissive(){return this.uniforms.emissive.value}set emissive(e){this.uniforms.emissive.value=e}get emissiveIntensity(){return this.uniforms.emissiveIntensity.value}set emissiveIntensity(e){this.uniforms.emissiveIntensity.value=e}get emissiveMap(){return this.uniforms.emissiveMap.value}set emissiveMap(e){this.uniforms.emissiveMap.value=e}get shadeColorFactor(){return this.uniforms.shadeColorFactor.value}set shadeColorFactor(e){this.uniforms.shadeColorFactor.value=e}get shadeMultiplyTexture(){return this.uniforms.shadeMultiplyTexture.value}set shadeMultiplyTexture(e){this.uniforms.shadeMultiplyTexture.value=e}get shadingShiftFactor(){return this.uniforms.shadingShiftFactor.value}set shadingShiftFactor(e){this.uniforms.shadingShiftFactor.value=e}get shadingShiftTexture(){return this.uniforms.shadingShiftTexture.value}set shadingShiftTexture(e){this.uniforms.shadingShiftTexture.value=e}get shadingShiftTextureScale(){return this.uniforms.shadingShiftTextureScale.value}set shadingShiftTextureScale(e){this.uniforms.shadingShiftTextureScale.value=e}get shadingToonyFactor(){return this.uniforms.shadingToonyFactor.value}set shadingToonyFactor(e){this.uniforms.shadingToonyFactor.value=e}get giEqualizationFactor(){return this.uniforms.giEqualizationFactor.value}set giEqualizationFactor(e){this.uniforms.giEqualizationFactor.value=e}get matcapFactor(){return this.uniforms.matcapFactor.value}set matcapFactor(e){this.uniforms.matcapFactor.value=e}get matcapTexture(){return this.uniforms.matcapTexture.value}set matcapTexture(e){this.uniforms.matcapTexture.value=e}get parametricRimColorFactor(){return this.uniforms.parametricRimColorFactor.value}set parametricRimColorFactor(e){this.uniforms.parametricRimColorFactor.value=e}get rimMultiplyTexture(){return this.uniforms.rimMultiplyTexture.value}set rimMultiplyTexture(e){this.uniforms.rimMultiplyTexture.value=e}get rimLightingMixFactor(){return this.uniforms.rimLightingMixFactor.value}set rimLightingMixFactor(e){this.uniforms.rimLightingMixFactor.value=e}get parametricRimFresnelPowerFactor(){return this.uniforms.parametricRimFresnelPowerFactor.value}set parametricRimFresnelPowerFactor(e){this.uniforms.parametricRimFresnelPowerFactor.value=e}get parametricRimLiftFactor(){return this.uniforms.parametricRimLiftFactor.value}set parametricRimLiftFactor(e){this.uniforms.parametricRimLiftFactor.value=e}get outlineWidthMultiplyTexture(){return this.uniforms.outlineWidthMultiplyTexture.value}set outlineWidthMultiplyTexture(e){this.uniforms.outlineWidthMultiplyTexture.value=e}get outlineWidthFactor(){return this.uniforms.outlineWidthFactor.value}set outlineWidthFactor(e){this.uniforms.outlineWidthFactor.value=e}get outlineColorFactor(){return this.uniforms.outlineColorFactor.value}set outlineColorFactor(e){this.uniforms.outlineColorFactor.value=e}get outlineLightingMixFactor(){return this.uniforms.outlineLightingMixFactor.value}set outlineLightingMixFactor(e){this.uniforms.outlineLightingMixFactor.value=e}get uvAnimationMaskTexture(){return this.uniforms.uvAnimationMaskTexture.value}set uvAnimationMaskTexture(e){this.uniforms.uvAnimationMaskTexture.value=e}get uvAnimationScrollXOffset(){return this.uniforms.uvAnimationScrollXOffset.value}set uvAnimationScrollXOffset(e){this.uniforms.uvAnimationScrollXOffset.value=e}get uvAnimationScrollYOffset(){return this.uniforms.uvAnimationScrollYOffset.value}set uvAnimationScrollYOffset(e){this.uniforms.uvAnimationScrollYOffset.value=e}get uvAnimationRotationPhase(){return this.uniforms.uvAnimationRotationPhase.value}set uvAnimationRotationPhase(e){this.uniforms.uvAnimationRotationPhase.value=e}get ignoreVertexColor(){return this._ignoreVertexColor}set ignoreVertexColor(e){this._ignoreVertexColor=e,this.needsUpdate=!0}get v0CompatShade(){return this._v0CompatShade}set v0CompatShade(e){this._v0CompatShade=e,this.needsUpdate=!0}get debugMode(){return this._debugMode}set debugMode(e){this._debugMode=e,this.needsUpdate=!0}get outlineWidthMode(){return this._outlineWidthMode}set outlineWidthMode(e){this._outlineWidthMode=e,this.needsUpdate=!0}get isOutline(){return this._isOutline}set isOutline(e){this._isOutline=e,this.needsUpdate=!0}get isMToonMaterial(){return!0}update(e){this._uploadUniformsWorkaround(),this._updateUVAnimation(e)}copy(e){return super.copy(e),this.map=e.map,this.normalMap=e.normalMap,this.emissiveMap=e.emissiveMap,this.shadeMultiplyTexture=e.shadeMultiplyTexture,this.shadingShiftTexture=e.shadingShiftTexture,this.matcapTexture=e.matcapTexture,this.rimMultiplyTexture=e.rimMultiplyTexture,this.outlineWidthMultiplyTexture=e.outlineWidthMultiplyTexture,this.uvAnimationMaskTexture=e.uvAnimationMaskTexture,this.normalMapType=e.normalMapType,this.uvAnimationScrollXSpeedFactor=e.uvAnimationScrollXSpeedFactor,this.uvAnimationScrollYSpeedFactor=e.uvAnimationScrollYSpeedFactor,this.uvAnimationRotationSpeedFactor=e.uvAnimationRotationSpeedFactor,this.ignoreVertexColor=e.ignoreVertexColor,this.v0CompatShade=e.v0CompatShade,this.debugMode=e.debugMode,this.outlineWidthMode=e.outlineWidthMode,this.isOutline=e.isOutline,this.needsUpdate=!0,this}_updateUVAnimation(e){this.uniforms.uvAnimationScrollXOffset.value+=e*this.uvAnimationScrollXSpeedFactor,this.uniforms.uvAnimationScrollYOffset.value+=e*this.uvAnimationScrollYSpeedFactor,this.uniforms.uvAnimationRotationPhase.value+=e*this.uvAnimationRotationSpeedFactor,this.uniforms.alphaTest.value=this.alphaTest,this.uniformsNeedUpdate=!0}_uploadUniformsWorkaround(){this.uniforms.opacity.value=this.opacity,this._updateTextureMatrix(this.uniforms.map,this.uniforms.mapUvTransform),this._updateTextureMatrix(this.uniforms.normalMap,this.uniforms.normalMapUvTransform),this._updateTextureMatrix(this.uniforms.emissiveMap,this.uniforms.emissiveMapUvTransform),this._updateTextureMatrix(this.uniforms.shadeMultiplyTexture,this.uniforms.shadeMultiplyTextureUvTransform),this._updateTextureMatrix(this.uniforms.shadingShiftTexture,this.uniforms.shadingShiftTextureUvTransform),this._updateTextureMatrix(this.uniforms.matcapTexture,this.uniforms.matcapTextureUvTransform),this._updateTextureMatrix(this.uniforms.rimMultiplyTexture,this.uniforms.rimMultiplyTextureUvTransform),this._updateTextureMatrix(this.uniforms.outlineWidthMultiplyTexture,this.uniforms.outlineWidthMultiplyTextureUvTransform),this._updateTextureMatrix(this.uniforms.uvAnimationMaskTexture,this.uniforms.uvAnimationMaskTextureUvTransform),this.uniformsNeedUpdate=!0}_generateDefines(){let e=this.outlineWidthMultiplyTexture!==null,t=this.map!==null||this.normalMap!==null||this.emissiveMap!==null||this.shadeMultiplyTexture!==null||this.shadingShiftTexture!==null||this.rimMultiplyTexture!==null||this.uvAnimationMaskTexture!==null;return{THREE_VRM_THREE_REVISION:184,OUTLINE:this._isOutline,MTOON_USE_UV:e||t,MTOON_UVS_VERTEX_ONLY:e&&!t,V0_COMPAT_SHADE:this._v0CompatShade,USE_SHADEMULTIPLYTEXTURE:this.shadeMultiplyTexture!==null,USE_SHADINGSHIFTTEXTURE:this.shadingShiftTexture!==null,USE_MATCAPTEXTURE:this.matcapTexture!==null,USE_RIMMULTIPLYTEXTURE:this.rimMultiplyTexture!==null,USE_OUTLINEWIDTHMULTIPLYTEXTURE:this._isOutline&&this.outlineWidthMultiplyTexture!==null,USE_UVANIMATIONMASKTEXTURE:this.uvAnimationMaskTexture!==null,IGNORE_VERTEX_COLOR:this._ignoreVertexColor===!0,DEBUG_NORMAL:this._debugMode===`normal`,DEBUG_LITSHADERATE:this._debugMode===`litShadeRate`,DEBUG_UV:this._debugMode===`uv`,OUTLINE_WIDTH_SCREEN:this._isOutline&&this._outlineWidthMode===Yb.ScreenCoordinates}}_updateTextureMatrix(e,t){e.value&&(e.value.matrixAutoUpdate&&e.value.updateMatrix(),t.value.copy(e.value.matrix))}},Qb=new Set([`1.0`,`1.0-beta`]),$b=class e{get name(){return e.EXTENSION_NAME}constructor(e,t={}){this.parser=e,this.materialType=t.materialType??Zb,this.renderOrderOffset=t.renderOrderOffset??0,this.v0CompatShade=t.v0CompatShade??!1,this.debugMode=t.debugMode??`none`,this._mToonMaterialSet=new Set}beforeRoot(){return Ub(this,null,function*(){this._removeUnlitExtensionIfMToonExists()})}afterRoot(e){return Ub(this,null,function*(){e.userData.vrmMToonMaterials=Array.from(this._mToonMaterialSet)})}getMaterialType(e){return this._getMToonExtension(e)?this.materialType:null}extendMaterialParams(e,t){let n=this._getMToonExtension(e);return n?this._extendMaterialParams(n,t):null}loadMesh(e){return Ub(this,null,function*(){let t=this.parser,n=t.json.meshes?.[e];if(n==null)throw Error(`MToonMaterialLoaderPlugin: Attempt to use meshes[${e}] of glTF but the mesh doesn't exist`);let r=n.primitives,i=yield t.loadMesh(e);if(r.length===1){let e=i,t=r[0].material;t!=null&&this._setupPrimitive(e,t)}else{let e=i;for(let t=0;t<r.length;t++){let n=e.children[t],i=r[t].material;i!=null&&this._setupPrimitive(n,i)}}return i})}_removeUnlitExtensionIfMToonExists(){this.parser.json.materials?.map((e,t)=>{this._getMToonExtension(t)&&e.extensions?.KHR_materials_unlit&&delete e.extensions.KHR_materials_unlit})}_getMToonExtension(t){let n=this.parser.json.materials?.[t];if(n==null){console.warn(`MToonMaterialLoaderPlugin: Attempt to use materials[${t}] of glTF but the material doesn't exist`);return}let r=n.extensions?.[e.EXTENSION_NAME];if(r==null)return;let i=r.specVersion;if(!Qb.has(i)){console.warn(`MToonMaterialLoaderPlugin: Unknown ${e.EXTENSION_NAME} specVersion "${i}"`);return}return r}_extendMaterialParams(e,t){return Ub(this,null,function*(){delete t.metalness,delete t.roughness;let n=new Gb(this.parser,t);n.assignPrimitive(`transparentWithZWrite`,e.transparentWithZWrite),n.assignColor(`shadeColorFactor`,e.shadeColorFactor),n.assignTexture(`shadeMultiplyTexture`,e.shadeMultiplyTexture,!0),n.assignPrimitive(`shadingShiftFactor`,e.shadingShiftFactor),n.assignTexture(`shadingShiftTexture`,e.shadingShiftTexture,!0),n.assignPrimitive(`shadingShiftTextureScale`,e.shadingShiftTexture?.scale),n.assignPrimitive(`shadingToonyFactor`,e.shadingToonyFactor),n.assignPrimitive(`giEqualizationFactor`,e.giEqualizationFactor),n.assignColor(`matcapFactor`,e.matcapFactor),n.assignTexture(`matcapTexture`,e.matcapTexture,!0),n.assignColor(`parametricRimColorFactor`,e.parametricRimColorFactor),n.assignTexture(`rimMultiplyTexture`,e.rimMultiplyTexture,!0),n.assignPrimitive(`rimLightingMixFactor`,e.rimLightingMixFactor),n.assignPrimitive(`parametricRimFresnelPowerFactor`,e.parametricRimFresnelPowerFactor),n.assignPrimitive(`parametricRimLiftFactor`,e.parametricRimLiftFactor),n.assignPrimitive(`outlineWidthMode`,e.outlineWidthMode),n.assignPrimitive(`outlineWidthFactor`,e.outlineWidthFactor),n.assignTexture(`outlineWidthMultiplyTexture`,e.outlineWidthMultiplyTexture,!1),n.assignColor(`outlineColorFactor`,e.outlineColorFactor),n.assignPrimitive(`outlineLightingMixFactor`,e.outlineLightingMixFactor),n.assignTexture(`uvAnimationMaskTexture`,e.uvAnimationMaskTexture,!1),n.assignPrimitive(`uvAnimationScrollXSpeedFactor`,e.uvAnimationScrollXSpeedFactor),n.assignPrimitive(`uvAnimationScrollYSpeedFactor`,e.uvAnimationScrollYSpeedFactor),n.assignPrimitive(`uvAnimationRotationSpeedFactor`,e.uvAnimationRotationSpeedFactor),n.assignPrimitive(`v0CompatShade`,this.v0CompatShade),n.assignPrimitive(`debugMode`,this.debugMode),yield n.pending})}_setupPrimitive(e,t){let n=this._getMToonExtension(t);if(n){e.renderOrder=this._parseRenderOrder(n)+this.renderOrderOffset,this._generateOutline(e),this._addToMaterialSet(e);return}}_shouldGenerateOutline(e){return typeof e.outlineWidthMode==`string`&&e.outlineWidthMode!==`none`&&typeof e.outlineWidthFactor==`number`&&e.outlineWidthFactor>0}_generateOutline(e){let t=e.material;if(!(t instanceof Os)||!this._shouldGenerateOutline(t))return;e.material=[t];let n=t.clone();n.name+=` (Outline)`,n.isOutline=!0,n.side=1,e.material.push(n);let r=e.geometry,i=r.index?r.index.count:r.attributes.position.count/3;r.addGroup(0,i,0),r.addGroup(0,i,1)}_addToMaterialSet(e){let t=e.material,n=new Set;Array.isArray(t)?t.forEach(e=>n.add(e)):n.add(t);for(let e of n)this._mToonMaterialSet.add(e)}_parseRenderOrder(e){return(e.transparentWithZWrite?0:19)+(e.renderQueueOffsetNumber??0)}};$b.EXTENSION_NAME=`VRMC_materials_mtoon`;var ex=$b,tx=(e,t,n)=>new Promise((r,i)=>{var a=e=>{try{s(n.next(e))}catch(e){i(e)}},o=e=>{try{s(n.throw(e))}catch(e){i(e)}},s=e=>e.done?r(e.value):Promise.resolve(e.value).then(a,o);s((n=n.apply(e,t)).next())}),nx=class e{get name(){return e.EXTENSION_NAME}constructor(e){this.parser=e}extendMaterialParams(e,t){return tx(this,null,function*(){let n=this._getHDREmissiveMultiplierExtension(e);n!=null&&(console.warn("VRMMaterialsHDREmissiveMultiplierLoaderPlugin: `VRMC_materials_hdr_emissiveMultiplier` is archived. Use `KHR_materials_emissive_strength` instead."),t.emissiveIntensity=n.emissiveMultiplier)})}_getHDREmissiveMultiplierExtension(t){let n=this.parser.json.materials?.[t];if(n==null){console.warn(`VRMMaterialsHDREmissiveMultiplierLoaderPlugin: Attempt to use materials[${t}] of glTF but the material doesn't exist`);return}let r=n.extensions?.[e.EXTENSION_NAME];if(r!=null)return r}};nx.EXTENSION_NAME=`VRMC_materials_hdr_emissiveMultiplier`;var rx=nx,ix=Object.defineProperty,ax=Object.defineProperties,ox=Object.getOwnPropertyDescriptors,sx=Object.getOwnPropertySymbols,cx=Object.prototype.hasOwnProperty,lx=Object.prototype.propertyIsEnumerable,ux=(e,t,n)=>t in e?ix(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,dx=(e,t)=>{for(var n in t||={})cx.call(t,n)&&ux(e,n,t[n]);if(sx)for(var n of sx(t))lx.call(t,n)&&ux(e,n,t[n]);return e},fx=(e,t)=>ax(e,ox(t)),px=(e,t,n)=>new Promise((r,i)=>{var a=e=>{try{s(n.next(e))}catch(e){i(e)}},o=e=>{try{s(n.throw(e))}catch(e){i(e)}},s=e=>e.done?r(e.value):Promise.resolve(e.value).then(a,o);s((n=n.apply(e,t)).next())});function mx(e){return e**2.2}var hx=class{get name(){return`VRMMaterialsV0CompatPlugin`}constructor(e){this.parser=e,this._renderQueueMapTransparent=new Map,this._renderQueueMapTransparentZWrite=new Map;let t=this.parser.json;t.extensionsUsed=t.extensionsUsed??[],t.extensionsUsed.indexOf(`KHR_texture_transform`)===-1&&t.extensionsUsed.push(`KHR_texture_transform`)}beforeRoot(){return px(this,null,function*(){let e=this.parser.json,t=e.extensions?.VRM?.materialProperties;t&&(this._populateRenderQueueMap(t),t.forEach((t,n)=>{let r=e.materials?.[n];if(r==null){console.warn(`VRMMaterialsV0CompatPlugin: Attempt to use materials[${n}] of glTF but the material doesn't exist`);return}if(t.shader===`VRM/MToon`){let i=this._parseV0MToonProperties(t,r);e.materials[n]=i}else if(t.shader?.startsWith(`VRM/Unlit`)){let i=this._parseV0UnlitProperties(t,r);e.materials[n]=i}else t.shader===`VRM_USE_GLTFSHADER`||console.warn(`VRMMaterialsV0CompatPlugin: Unknown shader: ${t.shader}`)}))})}_parseV0MToonProperties(e,t){let n=e.keywordMap?._ALPHABLEND_ON??!1,r=e.floatProperties?._ZWrite===1&&n,i=this._v0ParseRenderQueue(e),a=e.keywordMap?._ALPHATEST_ON??!1,o=n?`BLEND`:a?`MASK`:`OPAQUE`,s=a?e.floatProperties?._Cutoff??.5:void 0,c=(e.floatProperties?._CullMode??2)===0,l=this._portTextureTransform(e),u=(e.vectorProperties?._Color??[1,1,1,1]).map((e,t)=>t===3?e:mx(e)),d=e.textureProperties?._MainTex,f=d==null?void 0:{index:d,extensions:dx({},l)},p=e.floatProperties?._BumpScale??1,m=e.textureProperties?._BumpMap,h=m==null?void 0:{index:m,scale:p,extensions:dx({},l)},g=(e.vectorProperties?._EmissionColor??[0,0,0,1]).map(mx),_=e.textureProperties?._EmissionMap,v=_==null?void 0:{index:_,extensions:dx({},l)},y=(e.vectorProperties?._ShadeColor??[.97,.81,.86,1]).map(mx),b=e.textureProperties?._ShadeTexture,x=b==null?void 0:{index:b,extensions:dx({},l)},S=e.floatProperties?._ShadeShift??0,C=e.floatProperties?._ShadeToony??.9;C=ba.lerp(C,1,.5+.5*S),S=-S-(1-C);let w=e.floatProperties?._IndirectLightIntensity??.1,T=w?1-w:void 0,E=e.textureProperties?._SphereAdd,D=E==null?void 0:[1,1,1],O=E==null?void 0:{index:E},k=e.floatProperties?._RimLightingMix??0,A=e.textureProperties?._RimTexture,ee=A==null?void 0:{index:A,extensions:dx({},l)},te=(e.vectorProperties?._RimColor??[0,0,0,1]).map(mx),ne=e.floatProperties?._RimFresnelPower??1,re=e.floatProperties?._RimLift??0,j=[`none`,`worldCoordinates`,`screenCoordinates`][e.floatProperties?._OutlineWidthMode??0],ie=e.floatProperties?._OutlineWidth??0;ie=.01*ie;let ae=e.textureProperties?._OutlineWidthTexture,M=ae==null?void 0:{index:ae,extensions:dx({},l)},oe=(e.vectorProperties?._OutlineColor??[0,0,0]).map(mx),se=(e.floatProperties?._OutlineColorMode??0)===1?e.floatProperties?._OutlineLightingMix??1:0,ce=e.textureProperties?._UvAnimMaskTexture,le=ce==null?void 0:{index:ce,extensions:dx({},l)},ue=e.floatProperties?._UvAnimScrollX??0,de=e.floatProperties?._UvAnimScrollY??0;de!=null&&(de=-de);let fe=e.floatProperties?._UvAnimRotation??0,pe={specVersion:`1.0`,transparentWithZWrite:r,renderQueueOffsetNumber:i,shadeColorFactor:y,shadeMultiplyTexture:x,shadingShiftFactor:S,shadingToonyFactor:C,giEqualizationFactor:T,matcapFactor:D,matcapTexture:O,rimLightingMixFactor:k,rimMultiplyTexture:ee,parametricRimColorFactor:te,parametricRimFresnelPowerFactor:ne,parametricRimLiftFactor:re,outlineWidthMode:j,outlineWidthFactor:ie,outlineWidthMultiplyTexture:M,outlineColorFactor:oe,outlineLightingMixFactor:se,uvAnimationMaskTexture:le,uvAnimationScrollXSpeedFactor:ue,uvAnimationScrollYSpeedFactor:de,uvAnimationRotationSpeedFactor:fe};return fx(dx({},t),{pbrMetallicRoughness:{baseColorFactor:u,baseColorTexture:f},normalTexture:h,emissiveTexture:v,emissiveFactor:g,alphaMode:o,alphaCutoff:s,doubleSided:c,extensions:{VRMC_materials_mtoon:pe}})}_parseV0UnlitProperties(e,t){let n=e.shader===`VRM/UnlitTransparentZWrite`,r=e.shader===`VRM/UnlitTransparent`||n,i=this._v0ParseRenderQueue(e),a=e.shader===`VRM/UnlitCutout`,o=r?`BLEND`:a?`MASK`:`OPAQUE`,s=a?e.floatProperties?._Cutoff??.5:void 0,c=this._portTextureTransform(e),l=(e.vectorProperties?._Color??[1,1,1,1]).map(mx),u=e.textureProperties?._MainTex,d=u==null?void 0:{index:u,extensions:dx({},c)},f={specVersion:`1.0`,transparentWithZWrite:n,renderQueueOffsetNumber:i,shadeColorFactor:l,shadeMultiplyTexture:d};return fx(dx({},t),{pbrMetallicRoughness:{baseColorFactor:l,baseColorTexture:d},alphaMode:o,alphaCutoff:s,extensions:{VRMC_materials_mtoon:f}})}_portTextureTransform(e){let t=e.vectorProperties?._MainTex;if(t==null)return{};let n=[t?.[0]??0,t?.[1]??0],r=[t?.[2]??1,t?.[3]??1];return n[1]=1-r[1]-n[1],{KHR_texture_transform:{offset:n,scale:r}}}_v0ParseRenderQueue(e){let t=e.shader===`VRM/UnlitTransparentZWrite`,n=e.keywordMap?._ALPHABLEND_ON!=null||e.shader===`VRM/UnlitTransparent`||t,r=e.floatProperties?._ZWrite===1||t,i=0;if(n){let t=e.renderQueue;t!=null&&(i=r?this._renderQueueMapTransparentZWrite.get(t):this._renderQueueMapTransparent.get(t))}return i}_populateRenderQueueMap(e){let t=new Set,n=new Set;e.forEach(e=>{let r=e.shader===`VRM/UnlitTransparentZWrite`,i=e.keywordMap?._ALPHABLEND_ON!=null||e.shader===`VRM/UnlitTransparent`||r,a=e.floatProperties?._ZWrite===1||r;if(i){let r=e.renderQueue;r!=null&&(a?n.add(r):t.add(r))}}),t.size>10&&console.warn(`VRMMaterialsV0CompatPlugin: This VRM uses ${t.size} render queues for Transparent materials while VRM 1.0 only supports up to 10 render queues. The model might not be rendered correctly.`),n.size>10&&console.warn(`VRMMaterialsV0CompatPlugin: This VRM uses ${n.size} render queues for TransparentZWrite materials while VRM 1.0 only supports up to 10 render queues. The model might not be rendered correctly.`),Array.from(t).sort().forEach((e,n)=>{let r=Math.min(Math.max(n-t.size+1,-9),0);this._renderQueueMapTransparent.set(e,r)}),Array.from(n).sort().forEach((e,t)=>{let n=Math.min(Math.max(t,0),9);this._renderQueueMapTransparentZWrite.set(e,n)})}},gx=(e,t,n)=>new Promise((r,i)=>{var a=e=>{try{s(n.next(e))}catch(e){i(e)}},o=e=>{try{s(n.throw(e))}catch(e){i(e)}},s=e=>e.done?r(e.value):Promise.resolve(e.value).then(a,o);s((n=n.apply(e,t)).next())}),_x=new U,vx=class extends _o{constructor(e){super(),this._attrPosition=new q(new Float32Array([0,0,0,0,0,0]),3),this._attrPosition.setUsage(Pi);let t=new J;t.setAttribute(`position`,this._attrPosition);let n=new Ac({color:16711935,depthTest:!1,depthWrite:!1});this._line=new Rc(t,n),this.add(this._line),this.constraint=e}updateMatrixWorld(e){_x.setFromMatrixPosition(this.constraint.destination.matrixWorld),this._attrPosition.setXYZ(0,_x.x,_x.y,_x.z),this.constraint.source&&_x.setFromMatrixPosition(this.constraint.source.matrixWorld),this._attrPosition.setXYZ(1,_x.x,_x.y,_x.z),this._attrPosition.needsUpdate=!0,super.updateMatrixWorld(e)}};function yx(e,t){return t.set(e.elements[12],e.elements[13],e.elements[14])}var bx=new U,xx=new U;function Sx(e,t){return e.decompose(bx,t,xx),t}function Cx(e){return e.invert?e.invert():e.inverse(),e}var wx=class{constructor(e,t){this.destination=e,this.source=t,this.weight=1}},Tx=new U,Ex=new U,Dx=new U,Ox=new H,kx=new H,Ax=new H,jx=class extends wx{get aimAxis(){return this._aimAxis}set aimAxis(e){this._aimAxis=e,this._v3AimAxis.set(e===`PositiveX`?1:e===`NegativeX`?-1:0,e===`PositiveY`?1:e===`NegativeY`?-1:0,e===`PositiveZ`?1:e===`NegativeZ`?-1:0)}get dependencies(){let e=new Set([this.source]);return this.destination.parent&&e.add(this.destination.parent),e}constructor(e,t){super(e,t),this._aimAxis=`PositiveX`,this._v3AimAxis=new U(1,0,0),this._dstRestQuat=new H}setInitState(){this._dstRestQuat.copy(this.destination.quaternion)}update(){this.destination.updateWorldMatrix(!0,!1),this.source.updateWorldMatrix(!0,!1);let e=Ox.identity(),t=kx.identity();this.destination.parent&&(Sx(this.destination.parent.matrixWorld,e),Cx(t.copy(e)));let n=Tx.copy(this._v3AimAxis).applyQuaternion(this._dstRestQuat).applyQuaternion(e),r=yx(this.source.matrixWorld,Ex).sub(yx(this.destination.matrixWorld,Dx)).normalize(),i=Ax.setFromUnitVectors(n,r).premultiply(t).multiply(e).multiply(this._dstRestQuat);this.destination.quaternion.copy(this._dstRestQuat).slerp(i,this.weight)}};function Mx(e,t){let n=[e],r=e.parent;for(;r!==null;)n.unshift(r),r=r.parent;n.forEach(e=>{t(e)})}var Nx=class{constructor(){this._constraints=new Set,this._objectConstraintsMap=new Map}get constraints(){return this._constraints}addConstraint(e){this._constraints.add(e);let t=this._objectConstraintsMap.get(e.destination);t??(t=new Set,this._objectConstraintsMap.set(e.destination,t)),t.add(e)}deleteConstraint(e){this._constraints.delete(e),this._objectConstraintsMap.get(e.destination).delete(e)}setInitState(){let e=new Set,t=new Set;for(let n of this._constraints)this._processConstraint(n,e,t,e=>e.setInitState())}update(){let e=new Set,t=new Set;for(let n of this._constraints)this._processConstraint(n,e,t,e=>e.update())}_processConstraint(e,t,n,r){if(n.has(e))return;if(t.has(e))throw Error(`VRMNodeConstraintManager: Circular dependency detected while updating constraints`);t.add(e);let i=e.dependencies;for(let e of i)Mx(e,e=>{let i=this._objectConstraintsMap.get(e);if(i)for(let e of i)this._processConstraint(e,t,n,r)});r(e),n.add(e)}},Px=new H,Fx=new H,Ix=class extends wx{get dependencies(){return new Set([this.source])}constructor(e,t){super(e,t),this._dstRestQuat=new H,this._invSrcRestQuat=new H}setInitState(){this._dstRestQuat.copy(this.destination.quaternion),Cx(this._invSrcRestQuat.copy(this.source.quaternion))}update(){let e=Px.copy(this._invSrcRestQuat).multiply(this.source.quaternion),t=Fx.copy(this._dstRestQuat).multiply(e);this.destination.quaternion.copy(this._dstRestQuat).slerp(t,this.weight)}},Lx=new U,Rx=new H,zx=new H,Bx=class extends wx{get rollAxis(){return this._rollAxis}set rollAxis(e){this._rollAxis=e,this._v3RollAxis.set(+(e===`X`),+(e===`Y`),+(e===`Z`))}get dependencies(){return new Set([this.source])}constructor(e,t){super(e,t),this._rollAxis=`X`,this._v3RollAxis=new U(1,0,0),this._dstRestQuat=new H,this._invDstRestQuat=new H,this._invSrcRestQuatMulDstRestQuat=new H}setInitState(){this._dstRestQuat.copy(this.destination.quaternion),Cx(this._invDstRestQuat.copy(this._dstRestQuat)),Cx(this._invSrcRestQuatMulDstRestQuat.copy(this.source.quaternion)).multiply(this._dstRestQuat)}update(){let e=Rx.copy(this._invDstRestQuat).multiply(this.source.quaternion).multiply(this._invSrcRestQuatMulDstRestQuat),t=Lx.copy(this._v3RollAxis).applyQuaternion(e),n=zx.setFromUnitVectors(t,this._v3RollAxis).premultiply(this._dstRestQuat).multiply(e);this.destination.quaternion.copy(this._dstRestQuat).slerp(n,this.weight)}},Vx=new Set([`1.0`,`1.0-beta`]),Hx=class e{get name(){return e.EXTENSION_NAME}constructor(e,t){this.parser=e,this.helperRoot=t?.helperRoot}afterRoot(e){return gx(this,null,function*(){e.userData.vrmNodeConstraintManager=yield this._import(e)})}_import(t){return gx(this,null,function*(){let n=this.parser.json;if(n.extensionsUsed?.indexOf(e.EXTENSION_NAME)===-1)return null;let r=new Nx,i=yield this.parser.getDependencies(`node`);return i.forEach((t,a)=>{let o=n.nodes[a]?.extensions?.[e.EXTENSION_NAME];if(o==null)return;let s=o.specVersion;if(!Vx.has(s)){console.warn(`VRMNodeConstraintLoaderPlugin: Unknown ${e.EXTENSION_NAME} specVersion "${s}"`);return}let c=o.constraint;if(c.roll!=null){let e=this._importRollConstraint(t,i,c.roll);r.addConstraint(e)}else if(c.aim!=null){let e=this._importAimConstraint(t,i,c.aim);r.addConstraint(e)}else if(c.rotation!=null){let e=this._importRotationConstraint(t,i,c.rotation);r.addConstraint(e)}}),t.scene.updateMatrixWorld(),r.setInitState(),r})}_importRollConstraint(e,t,n){let{source:r,rollAxis:i,weight:a}=n,o=t[r],s=new Bx(e,o);if(i!=null&&(s.rollAxis=i),a!=null&&(s.weight=a),this.helperRoot){let e=new vx(s);this.helperRoot.add(e)}return s}_importAimConstraint(e,t,n){let{source:r,aimAxis:i,weight:a}=n,o=t[r],s=new jx(e,o);if(i!=null&&(s.aimAxis=i),a!=null&&(s.weight=a),this.helperRoot){let e=new vx(s);this.helperRoot.add(e)}return s}_importRotationConstraint(e,t,n){let{source:r,weight:i}=n,a=t[r],o=new Ix(e,a);if(i!=null&&(o.weight=i),this.helperRoot){let e=new vx(o);this.helperRoot.add(e)}return o}};Hx.EXTENSION_NAME=`VRMC_node_constraint`;var Ux=Hx,Wx=(e,t,n)=>new Promise((r,i)=>{var a=e=>{try{s(n.next(e))}catch(e){i(e)}},o=e=>{try{s(n.throw(e))}catch(e){i(e)}},s=e=>e.done?r(e.value):Promise.resolve(e.value).then(a,o);s((n=n.apply(e,t)).next())}),Gx=class{},Kx=new U,qx=new U,Jx=class extends Gx{get type(){return`capsule`}constructor(e){super(),this.offset=e?.offset??new U(0,0,0),this.tail=e?.tail??new U(0,0,0),this.radius=e?.radius??0,this.inside=e?.inside??!1}calculateCollision(e,t,n,r){Kx.setFromMatrixPosition(e),qx.subVectors(this.tail,this.offset).applyMatrix4(e),qx.sub(Kx);let i=qx.lengthSq();r.copy(t).sub(Kx);let a=qx.dot(r);a<=0||(i<=a||qx.multiplyScalar(a/i),r.sub(qx));let o=r.length(),s=this.inside?this.radius-n-o:o-n-this.radius;return s<0&&(r.multiplyScalar(1/o),this.inside&&r.negate()),s}},Yx=new U,Xx=new W,Zx=class extends Gx{get type(){return`plane`}constructor(e){super(),this.offset=e?.offset??new U(0,0,0),this.normal=e?.normal??new U(0,0,1)}calculateCollision(e,t,n,r){r.setFromMatrixPosition(e),r.negate().add(t),Xx.getNormalMatrix(e),Yx.copy(this.normal).applyNormalMatrix(Xx).normalize();let i=r.dot(Yx)-n;return r.copy(Yx),i}},Qx=new U,$x=class extends Gx{get type(){return`sphere`}constructor(e){super(),this.offset=e?.offset??new U(0,0,0),this.radius=e?.radius??0,this.inside=e?.inside??!1}calculateCollision(e,t,n,r){r.subVectors(t,Qx.setFromMatrixPosition(e));let i=r.length(),a=this.inside?this.radius-n-i:i-n-this.radius;return a<0&&(r.multiplyScalar(1/i),this.inside&&r.negate()),a}},eS=new U,tS=class extends J{constructor(e){super(),this.worldScale=1,this._currentRadius=0,this._currentOffset=new U,this._currentTail=new U,this._shape=e,this._attrPos=new q(new Float32Array(396),3),this.setAttribute(`position`,this._attrPos),this._attrIndex=new q(new Uint16Array(264),1),this.setIndex(this._attrIndex),this._buildIndex(),this.update()}update(){let e=!1,t=this._shape.radius/this.worldScale;this._currentRadius!==t&&(this._currentRadius=t,e=!0),this._currentOffset.equals(this._shape.offset)||(this._currentOffset.copy(this._shape.offset),e=!0);let n=eS.copy(this._shape.tail).divideScalar(this.worldScale);this._currentTail.distanceToSquared(n)>1e-10&&(this._currentTail.copy(n),e=!0),e&&this._buildPosition()}_buildPosition(){eS.copy(this._currentTail).sub(this._currentOffset);let e=eS.length()/this._currentRadius;for(let t=0;t<=16;t++){let n=t/16*Math.PI;this._attrPos.setXYZ(t,-Math.sin(n),-Math.cos(n),0),this._attrPos.setXYZ(17+t,e+Math.sin(n),Math.cos(n),0),this._attrPos.setXYZ(34+t,-Math.sin(n),0,-Math.cos(n)),this._attrPos.setXYZ(51+t,e+Math.sin(n),0,Math.cos(n))}for(let t=0;t<32;t++){let n=t/16*Math.PI;this._attrPos.setXYZ(68+t,0,Math.sin(n),Math.cos(n)),this._attrPos.setXYZ(100+t,e,Math.sin(n),Math.cos(n))}let t=Math.atan2(eS.y,Math.sqrt(eS.x*eS.x+eS.z*eS.z)),n=-Math.atan2(eS.z,eS.x);this.rotateZ(t),this.rotateY(n),this.scale(this._currentRadius,this._currentRadius,this._currentRadius),this.translate(this._currentOffset.x,this._currentOffset.y,this._currentOffset.z),this._attrPos.needsUpdate=!0}_buildIndex(){for(let e=0;e<34;e++){let t=(e+1)%34;this._attrIndex.setXY(e*2,e,t),this._attrIndex.setXY(68+e*2,34+e,34+t)}for(let e=0;e<32;e++){let t=(e+1)%32;this._attrIndex.setXY(136+e*2,68+e,68+t),this._attrIndex.setXY(200+e*2,100+e,100+t)}this._attrIndex.needsUpdate=!0}},nS=class extends J{constructor(e){super(),this.worldScale=1,this._currentOffset=new U,this._currentNormal=new U,this._shape=e,this._attrPos=new q(new Float32Array(18),3),this.setAttribute(`position`,this._attrPos),this._attrIndex=new q(new Uint16Array(10),1),this.setIndex(this._attrIndex),this._buildIndex(),this.update()}update(){let e=!1;this._currentOffset.equals(this._shape.offset)||(this._currentOffset.copy(this._shape.offset),e=!0),this._currentNormal.equals(this._shape.normal)||(this._currentNormal.copy(this._shape.normal),e=!0),e&&this._buildPosition()}_buildPosition(){this._attrPos.setXYZ(0,-.5,-.5,0),this._attrPos.setXYZ(1,.5,-.5,0),this._attrPos.setXYZ(2,.5,.5,0),this._attrPos.setXYZ(3,-.5,.5,0),this._attrPos.setXYZ(4,0,0,0),this._attrPos.setXYZ(5,0,0,.25),this.translate(this._currentOffset.x,this._currentOffset.y,this._currentOffset.z),this.lookAt(this._currentNormal),this._attrPos.needsUpdate=!0}_buildIndex(){this._attrIndex.setXY(0,0,1),this._attrIndex.setXY(2,1,2),this._attrIndex.setXY(4,2,3),this._attrIndex.setXY(6,3,0),this._attrIndex.setXY(8,4,5),this._attrIndex.needsUpdate=!0}},rS=class extends J{constructor(e){super(),this.worldScale=1,this._currentRadius=0,this._currentOffset=new U,this._shape=e,this._attrPos=new q(new Float32Array(288),3),this.setAttribute(`position`,this._attrPos),this._attrIndex=new q(new Uint16Array(192),1),this.setIndex(this._attrIndex),this._buildIndex(),this.update()}update(){let e=!1,t=this._shape.radius/this.worldScale;this._currentRadius!==t&&(this._currentRadius=t,e=!0),this._currentOffset.equals(this._shape.offset)||(this._currentOffset.copy(this._shape.offset),e=!0),e&&this._buildPosition()}_buildPosition(){for(let e=0;e<32;e++){let t=e/16*Math.PI;this._attrPos.setXYZ(e,Math.cos(t),Math.sin(t),0),this._attrPos.setXYZ(32+e,0,Math.cos(t),Math.sin(t)),this._attrPos.setXYZ(64+e,Math.sin(t),0,Math.cos(t))}this.scale(this._currentRadius,this._currentRadius,this._currentRadius),this.translate(this._currentOffset.x,this._currentOffset.y,this._currentOffset.z),this._attrPos.needsUpdate=!0}_buildIndex(){for(let e=0;e<32;e++){let t=(e+1)%32;this._attrIndex.setXY(e*2,e,t),this._attrIndex.setXY(64+e*2,32+e,32+t),this._attrIndex.setXY(128+e*2,64+e,64+t)}this._attrIndex.needsUpdate=!0}},iS=new U,aS=class extends _o{constructor(e){if(super(),this.matrixAutoUpdate=!1,this.collider=e,this.collider.shape instanceof $x)this._geometry=new rS(this.collider.shape);else if(this.collider.shape instanceof Jx)this._geometry=new tS(this.collider.shape);else if(this.collider.shape instanceof Zx)this._geometry=new nS(this.collider.shape);else throw Error(`VRMSpringBoneColliderHelper: Unknown collider shape type detected`);let t=new Ac({color:16711935,depthTest:!1,depthWrite:!1});this._line=new Hc(this._geometry,t),this.add(this._line)}dispose(){this._geometry.dispose()}updateMatrixWorld(e){this.collider.updateWorldMatrix(!0,!1),this.matrix.copy(this.collider.matrixWorld);let t=this.matrix.elements;this._geometry.worldScale=iS.set(t[0],t[1],t[2]).length(),this._geometry.update(),super.updateMatrixWorld(e)}},oS=class extends J{constructor(e){super(),this.worldScale=1,this._currentRadius=0,this._currentTail=new U,this._springBone=e,this._attrPos=new q(new Float32Array(294),3),this.setAttribute(`position`,this._attrPos),this._attrIndex=new q(new Uint16Array(194),1),this.setIndex(this._attrIndex),this._buildIndex(),this.update()}update(){let e=!1,t=this._springBone.settings.hitRadius/this.worldScale;this._currentRadius!==t&&(this._currentRadius=t,e=!0),this._currentTail.equals(this._springBone.initialLocalChildPosition)||(this._currentTail.copy(this._springBone.initialLocalChildPosition),e=!0),e&&this._buildPosition()}_buildPosition(){for(let e=0;e<32;e++){let t=e/16*Math.PI;this._attrPos.setXYZ(e,Math.cos(t),Math.sin(t),0),this._attrPos.setXYZ(32+e,0,Math.cos(t),Math.sin(t)),this._attrPos.setXYZ(64+e,Math.sin(t),0,Math.cos(t))}this.scale(this._currentRadius,this._currentRadius,this._currentRadius),this.translate(this._currentTail.x,this._currentTail.y,this._currentTail.z),this._attrPos.setXYZ(96,0,0,0),this._attrPos.setXYZ(97,this._currentTail.x,this._currentTail.y,this._currentTail.z),this._attrPos.needsUpdate=!0}_buildIndex(){for(let e=0;e<32;e++){let t=(e+1)%32;this._attrIndex.setXY(e*2,e,t),this._attrIndex.setXY(64+e*2,32+e,32+t),this._attrIndex.setXY(128+e*2,64+e,64+t)}this._attrIndex.setXY(192,96,97),this._attrIndex.needsUpdate=!0}},sS=new U,cS=class extends _o{constructor(e){super(),this.matrixAutoUpdate=!1,this.springBone=e,this._geometry=new oS(this.springBone);let t=new Ac({color:16776960,depthTest:!1,depthWrite:!1});this._line=new Hc(this._geometry,t),this.add(this._line)}dispose(){this._geometry.dispose()}updateMatrixWorld(e){this.springBone.bone.updateWorldMatrix(!0,!1),this.matrix.copy(this.springBone.bone.matrixWorld);let t=this.matrix.elements;this._geometry.worldScale=sS.set(t[0],t[1],t[2]).length(),this._geometry.update(),super.updateMatrixWorld(e)}},lS=class extends go{constructor(e){super(),this.colliderMatrix=new G,this.shape=e}updateWorldMatrix(e,t){super.updateWorldMatrix(e,t),uS(this.colliderMatrix,this.matrixWorld,this.shape.offset)}};function uS(e,t,n){let r=t.elements;e.copy(t),n&&(e.elements[12]=r[0]*n.x+r[4]*n.y+r[8]*n.z+r[12],e.elements[13]=r[1]*n.x+r[5]*n.y+r[9]*n.z+r[13],e.elements[14]=r[2]*n.x+r[6]*n.y+r[10]*n.z+r[14])}var dS=new G;function fS(e){return e.invert?e.invert():e.getInverse(dS.copy(e)),e}var pS=class{constructor(e){this._inverseCache=new G,this._shouldUpdateInverse=!0,this.matrix=e;let t={set:(e,t,n)=>(this._shouldUpdateInverse=!0,e[t]=n,!0)};this._originalElements=e.elements,e.elements=new Proxy(e.elements,t)}get inverse(){return this._shouldUpdateInverse&&=(fS(this._inverseCache.copy(this.matrix)),!1),this._inverseCache}revert(){this.matrix.elements=this._originalElements}},mS=new G,hS=new U,gS=new U,_S=new U,vS=new U,yS=new G,bS=class{constructor(e,t,n={},r=[]){this._currentTail=new U,this._prevTail=new U,this._boneAxis=new U,this._worldSpaceBoneLength=0,this._center=null,this._initialLocalMatrix=new G,this._initialLocalRotation=new H,this._initialLocalChildPosition=new U,this.bone=e,this.bone.matrixAutoUpdate=!1,this.child=t,this.settings={hitRadius:n.hitRadius??0,stiffness:n.stiffness??1,gravityPower:n.gravityPower??0,gravityDir:n.gravityDir?.clone()??new U(0,-1,0),dragForce:n.dragForce??.4},this.colliderGroups=r}get dependencies(){let e=new Set,t=this.bone.parent;t&&e.add(t);for(let t=0;t<this.colliderGroups.length;t++)for(let n=0;n<this.colliderGroups[t].colliders.length;n++)e.add(this.colliderGroups[t].colliders[n]);return e}get center(){return this._center}set center(e){this._center?.userData.inverseCacheProxy&&(this._center.userData.inverseCacheProxy.revert(),delete this._center.userData.inverseCacheProxy),this._center=e,this._center&&(this._center.userData.inverseCacheProxy||(this._center.userData.inverseCacheProxy=new pS(this._center.matrixWorld)))}get initialLocalChildPosition(){return this._initialLocalChildPosition}get _parentMatrixWorld(){return this.bone.parent?this.bone.parent.matrixWorld:mS}setInitState(){this._initialLocalMatrix.copy(this.bone.matrix),this._initialLocalRotation.copy(this.bone.quaternion),this.child?this._initialLocalChildPosition.copy(this.child.position):this._initialLocalChildPosition.copy(this.bone.position).normalize().multiplyScalar(.07);let e=this._getMatrixWorldToCenter();this.bone.localToWorld(this._currentTail.copy(this._initialLocalChildPosition)).applyMatrix4(e),this._prevTail.copy(this._currentTail),this._boneAxis.copy(this._initialLocalChildPosition).normalize()}reset(){this.bone.quaternion.copy(this._initialLocalRotation),this.bone.updateMatrix(),this.bone.matrixWorld.multiplyMatrices(this._parentMatrixWorld,this.bone.matrix);let e=this._getMatrixWorldToCenter();this.bone.localToWorld(this._currentTail.copy(this._initialLocalChildPosition)).applyMatrix4(e),this._prevTail.copy(this._currentTail)}update(e){if(e<=0)return;this._calcWorldSpaceBoneLength();let t=gS.copy(this._boneAxis).transformDirection(this._initialLocalMatrix).transformDirection(this._parentMatrixWorld);vS.copy(this._currentTail).add(hS.subVectors(this._currentTail,this._prevTail).multiplyScalar(1-this.settings.dragForce)).applyMatrix4(this._getMatrixCenterToWorld()).addScaledVector(t,this.settings.stiffness*e).addScaledVector(this.settings.gravityDir,this.settings.gravityPower*e),_S.setFromMatrixPosition(this.bone.matrixWorld),vS.sub(_S).normalize().multiplyScalar(this._worldSpaceBoneLength).add(_S),this._collision(vS),this._prevTail.copy(this._currentTail),this._currentTail.copy(vS).applyMatrix4(this._getMatrixWorldToCenter());let n=yS.multiplyMatrices(this._parentMatrixWorld,this._initialLocalMatrix).invert();this.bone.quaternion.setFromUnitVectors(this._boneAxis,hS.copy(vS).applyMatrix4(n).normalize()).premultiply(this._initialLocalRotation),this.bone.updateMatrix(),this.bone.matrixWorld.multiplyMatrices(this._parentMatrixWorld,this.bone.matrix)}_collision(e){for(let t=0;t<this.colliderGroups.length;t++)for(let n=0;n<this.colliderGroups[t].colliders.length;n++){let r=this.colliderGroups[t].colliders[n],i=r.shape.calculateCollision(r.colliderMatrix,e,this.settings.hitRadius,hS);if(i<0){e.addScaledVector(hS,-i),e.sub(_S);let t=e.length();e.multiplyScalar(this._worldSpaceBoneLength/t).add(_S)}}}_calcWorldSpaceBoneLength(){hS.setFromMatrixPosition(this.bone.matrixWorld),this.child?gS.setFromMatrixPosition(this.child.matrixWorld):(gS.copy(this._initialLocalChildPosition),gS.applyMatrix4(this.bone.matrixWorld)),this._worldSpaceBoneLength=hS.sub(gS).length()}_getMatrixCenterToWorld(){return this._center?this._center.matrixWorld:mS}_getMatrixWorldToCenter(){return this._center?this._center.userData.inverseCacheProxy.inverse:mS}};function xS(e,t){let n=[],r=e;for(;r!==null;)n.unshift(r),r=r.parent;n.forEach(e=>{t(e)})}function SS(e,t){e.children.forEach(e=>{t(e)||SS(e,t)})}function CS(e){let t=new Map;for(let n of e){let r=n;do{let n=(t.get(r)??0)+1;if(n===e.size)return r;t.set(r,n),r=r.parent}while(r!==null)}return null}var wS=class{constructor(){this._joints=new Set,this._sortedJoints=[],this._hasWarnedCircularDependency=!1,this._ancestors=[],this._objectSpringBonesMap=new Map,this._isSortedJointsDirty=!1,this._relevantChildrenUpdated=this._relevantChildrenUpdated.bind(this)}get joints(){return this._joints}get springBones(){return console.warn(`VRMSpringBoneManager: springBones is deprecated. use joints instead.`),this._joints}get colliderGroups(){let e=new Set;return this._joints.forEach(t=>{t.colliderGroups.forEach(t=>{e.add(t)})}),Array.from(e)}get colliders(){let e=new Set;return this.colliderGroups.forEach(t=>{t.colliders.forEach(t=>{e.add(t)})}),Array.from(e)}addJoint(e){this._joints.add(e);let t=this._objectSpringBonesMap.get(e.bone);t??(t=new Set,this._objectSpringBonesMap.set(e.bone,t)),t.add(e),this._isSortedJointsDirty=!0}addSpringBone(e){console.warn(`VRMSpringBoneManager: addSpringBone() is deprecated. use addJoint() instead.`),this.addJoint(e)}deleteJoint(e){this._joints.delete(e),this._objectSpringBonesMap.get(e.bone).delete(e),this._isSortedJointsDirty=!0}deleteSpringBone(e){console.warn(`VRMSpringBoneManager: deleteSpringBone() is deprecated. use deleteJoint() instead.`),this.deleteJoint(e)}setInitState(){this._sortJoints();for(let e=0;e<this._sortedJoints.length;e++){let t=this._sortedJoints[e];t.bone.updateMatrix(),t.bone.updateWorldMatrix(!1,!1),t.setInitState()}}reset(){this._sortJoints();for(let e=0;e<this._sortedJoints.length;e++){let t=this._sortedJoints[e];t.bone.updateMatrix(),t.bone.updateWorldMatrix(!1,!1),t.reset()}}update(e){this._sortJoints();for(let e=0;e<this._ancestors.length;e++)this._ancestors[e].updateWorldMatrix(e===0,!1);for(let t=0;t<this._sortedJoints.length;t++){let n=this._sortedJoints[t];n.bone.updateMatrix(),n.bone.updateWorldMatrix(!1,!1),n.update(e),SS(n.bone,this._relevantChildrenUpdated)}}_sortJoints(){if(!this._isSortedJointsDirty)return;let e=[],t=new Set,n=new Set,r=new Set;for(let i of this._joints)this._insertJointSort(i,t,n,e,r);this._sortedJoints=e;let i=CS(r);this._ancestors=[],i&&(this._ancestors.push(i),SS(i,e=>(this._objectSpringBonesMap.get(e)?.size??0)>0?!0:(this._ancestors.push(e),!1))),this._isSortedJointsDirty=!1}_insertJointSort(e,t,n,r,i){if(n.has(e))return;if(t.has(e)){this._hasWarnedCircularDependency||=(console.warn(`VRMSpringBoneManager: Circular dependency detected`),!0);return}t.add(e);let a=e.dependencies;for(let e of a){let a=!1,o=null;xS(e,e=>{let s=this._objectSpringBonesMap.get(e);if(s)for(let e of s)a=!0,this._insertJointSort(e,t,n,r,i);else a||(o=e)}),o&&i.add(o)}r.push(e),n.add(e)}_relevantChildrenUpdated(e){return(this._objectSpringBonesMap.get(e)?.size??0)>0?!0:(e.updateWorldMatrix(!1,!1),!1)}},TS=`VRMC_springBone_extended_collider`,ES=new Set([`1.0`,`1.0-beta`]),DS=new Set([`1.0`]),OS=class e{get name(){return e.EXTENSION_NAME}constructor(e,t){this.parser=e,this.jointHelperRoot=t?.jointHelperRoot,this.colliderHelperRoot=t?.colliderHelperRoot,this.useExtendedColliders=t?.useExtendedColliders??!0}afterRoot(e){return Wx(this,null,function*(){e.userData.vrmSpringBoneManager=yield this._import(e)})}_import(e){return Wx(this,null,function*(){return(yield this._v1Import(e))??(yield this._v0Import(e))??null})}_v1Import(t){return Wx(this,null,function*(){var n;let r=t.parser.json;if(r.extensionsUsed?.indexOf(e.EXTENSION_NAME)===-1)return null;let i=new wS,a=yield t.parser.getDependencies(`node`),o=r.extensions?.[e.EXTENSION_NAME];if(!o)return null;let s=o.specVersion;if(!ES.has(s))return console.warn(`VRMSpringBoneLoaderPlugin: Unknown ${e.EXTENSION_NAME} specVersion "${s}"`),null;let c=o.colliders?.map((t,n)=>{let r=a[t.node];if(r==null)return console.warn(`VRMSpringBoneLoaderPlugin: The collider #${n} attempted to reference a node #${t.node} but not found. Skipping the collider`),null;let i=t.shape,o=t.extensions?.[TS];if(this.useExtendedColliders&&o!=null){let t=o.specVersion;if(!DS.has(t))console.warn(`VRMSpringBoneLoaderPlugin: Unknown ${TS} specVersion "${t}". Fallbacking to the ${e.EXTENSION_NAME} definition`);else{let e=o.shape;if(e.sphere)return this._importSphereCollider(r,{offset:new U().fromArray(e.sphere.offset??[0,0,0]),radius:e.sphere.radius??0,inside:e.sphere.inside??!1});if(e.capsule)return this._importCapsuleCollider(r,{offset:new U().fromArray(e.capsule.offset??[0,0,0]),radius:e.capsule.radius??0,tail:new U().fromArray(e.capsule.tail??[0,0,0]),inside:e.capsule.inside??!1});if(e.plane)return this._importPlaneCollider(r,{offset:new U().fromArray(e.plane.offset??[0,0,0]),normal:new U().fromArray(e.plane.normal??[0,0,1])})}}if(i.sphere)return this._importSphereCollider(r,{offset:new U().fromArray(i.sphere.offset??[0,0,0]),radius:i.sphere.radius??0,inside:!1});if(i.capsule)return this._importCapsuleCollider(r,{offset:new U().fromArray(i.capsule.offset??[0,0,0]),radius:i.capsule.radius??0,tail:new U().fromArray(i.capsule.tail??[0,0,0]),inside:!1});console.warn(`VRMSpringBoneLoaderPlugin: The collider #${n} has no valid shape. Skipping the collider`)}),l=o.colliderGroups?.map((e,t)=>({colliders:(e.colliders??[]).map(e=>c?.[e]??(console.warn(`VRMSpringBoneLoaderPlugin: The collider group #${t} attempted to reference a collider #${e} but not found. Skipping the collider`),null)).filter(e=>e!=null),name:e.name}));return(n=o.springs)==null||n.forEach((e,t)=>{let n=e.joints,r=e.colliderGroups?.map(e=>l?.[e]??(console.warn(`VRMSpringBoneLoaderPlugin: The spring #${t} attempted to reference a collider group #${e} but not found. Skipping the collider group`),null)).filter(e=>e!=null),o=e.center==null?void 0:a[e.center],s;n.forEach(e=>{if(s){let t=a[s.node],n=a[e.node],c={hitRadius:s.hitRadius,dragForce:s.dragForce,gravityPower:s.gravityPower,stiffness:s.stiffness,gravityDir:s.gravityDir==null?void 0:new U().fromArray(s.gravityDir)},l=this._importJoint(t,n,c,r);o&&(l.center=o),i.addJoint(l)}s=e})}),i.setInitState(),i})}_v0Import(e){return Wx(this,null,function*(){let t=e.parser.json;if(t.extensionsUsed?.indexOf(`VRM`)===-1)return null;let n=t.extensions?.VRM?.secondaryAnimation;if(!n)return null;let r=n?.boneGroups;if(!r)return null;let i=new wS,a=yield e.parser.getDependencies(`node`),o=n.colliderGroups?.map((e,t)=>{let n=a[e.node];return n==null?(console.warn(`VRMSpringBoneLoaderPlugin: The collider group #${t} attempted to reference a node #${e.node} but not found. Skipping the collider group`),null):{colliders:(e.colliders??[]).map((e,t)=>{let r=new U(0,0,0);return e.offset&&r.set(e.offset.x??0,e.offset.y??0,e.offset.z?-e.offset.z:0),this._importSphereCollider(n,{offset:r,radius:e.radius??0,inside:!1})})}});return r?.forEach((e,t)=>{let n=e.bones;n&&n.forEach(n=>{let r=a[n];if(r==null){console.warn(`VRMSpringBoneLoaderPlugin: The spring bone group #${t} attempted to reference a node #${n} but not found. Skipping the node`);return}let s=new U;e.gravityDir?s.set(e.gravityDir.x??0,e.gravityDir.y??0,e.gravityDir.z??0):s.set(0,-1,0);let c=e.center==null?void 0:a[e.center],l={hitRadius:e.hitRadius,dragForce:e.dragForce,gravityPower:e.gravityPower,stiffness:e.stiffiness,gravityDir:s},u=e.colliderGroups?.map(e=>o?.[e]??(console.warn(`VRMSpringBoneLoaderPlugin: The spring #${t} attempted to reference a collider group #${e} but not found. Skipping the collider group`),null)).filter(e=>e!=null);r.traverse(e=>{let t=e.children[0]??null,n=this._importJoint(e,t,l,u);c&&(n.center=c),i.addJoint(n)})})}),e.scene.updateMatrixWorld(),i.setInitState(),i})}_importJoint(e,t,n,r){let i=new bS(e,t,n,r);if(this.jointHelperRoot){let e=new cS(i);this.jointHelperRoot.add(e),e.renderOrder=this.jointHelperRoot.renderOrder}return i}_importSphereCollider(e,t){let n=new lS(new $x(t));if(e.add(n),this.colliderHelperRoot){let e=new aS(n);this.colliderHelperRoot.add(e),e.renderOrder=this.colliderHelperRoot.renderOrder}return n}_importCapsuleCollider(e,t){let n=new lS(new Jx(t));if(e.add(n),this.colliderHelperRoot){let e=new aS(n);this.colliderHelperRoot.add(e),e.renderOrder=this.colliderHelperRoot.renderOrder}return n}_importPlaneCollider(e,t){let n=new lS(new Zx(t));if(e.add(n),this.colliderHelperRoot){let e=new aS(n);this.colliderHelperRoot.add(e),e.renderOrder=this.colliderHelperRoot.renderOrder}return n}};OS.EXTENSION_NAME=`VRMC_springBone`;var kS=OS,AS=class{get name(){return`VRMLoaderPlugin`}constructor(e,t){this.parser=e;let n=t?.helperRoot,r=t?.autoUpdateHumanBones;this.expressionPlugin=t?.expressionPlugin??new Ey(e),this.firstPersonPlugin=t?.firstPersonPlugin??new Ay(e),this.humanoidPlugin=t?.humanoidPlugin??new Yy(e,{helperRoot:n,autoUpdateHumanBones:r}),this.lookAtPlugin=t?.lookAtPlugin??new jb(e,{helperRoot:n}),this.metaPlugin=t?.metaPlugin??new Pb(e),this.mtoonMaterialPlugin=t?.mtoonMaterialPlugin??new ex(e),this.materialsHDREmissiveMultiplierPlugin=t?.materialsHDREmissiveMultiplierPlugin??new rx(e),this.materialsV0CompatPlugin=t?.materialsV0CompatPlugin??new hx(e),this.springBonePlugin=t?.springBonePlugin??new kS(e,{colliderHelperRoot:n,jointHelperRoot:n}),this.nodeConstraintPlugin=t?.nodeConstraintPlugin??new Ux(e,{helperRoot:n})}beforeRoot(){return oy(this,null,function*(){yield this.materialsV0CompatPlugin.beforeRoot(),yield this.mtoonMaterialPlugin.beforeRoot()})}loadMesh(e){return oy(this,null,function*(){return yield this.mtoonMaterialPlugin.loadMesh(e)})}getMaterialType(e){return this.mtoonMaterialPlugin.getMaterialType(e)??null}extendMaterialParams(e,t){return oy(this,null,function*(){yield this.materialsHDREmissiveMultiplierPlugin.extendMaterialParams(e,t),yield this.mtoonMaterialPlugin.extendMaterialParams(e,t)})}afterRoot(e){return oy(this,null,function*(){yield this.metaPlugin.afterRoot(e),yield this.humanoidPlugin.afterRoot(e),yield this.expressionPlugin.afterRoot(e),yield this.lookAtPlugin.afterRoot(e),yield this.firstPersonPlugin.afterRoot(e),yield this.springBonePlugin.afterRoot(e),yield this.nodeConstraintPlugin.afterRoot(e),yield this.mtoonMaterialPlugin.afterRoot(e);let t=e.userData.vrmMeta,n=e.userData.vrmHumanoid;if(t&&n){let r=new Ib({scene:e.scene,expressionManager:e.userData.vrmExpressionManager,firstPerson:e.userData.vrmFirstPerson,humanoid:n,lookAt:e.userData.vrmLookAt,meta:t,materials:e.userData.vrmMToonMaterials,springBoneManager:e.userData.vrmSpringBoneManager,nodeConstraintManager:e.userData.vrmNodeConstraintManager});e.userData.vrm=r}})}};function jS(e){let t=new Set;return e.traverse(e=>{if(!e.isMesh)return;let n=e;t.add(n)}),t}function MS(e,t,n){if(t.size===1){let n=t.values().next().value;if(n.weight===1)return e[n.index]}let r=new Float32Array(e[0].count*3),i=0;if(n)i=1;else for(let e of t)i+=e.weight;for(let n of t){let t=e[n.index],a=n.weight/i;for(let e=0;e<t.count;e++)r[e*3+0]+=t.getX(e)*a,r[e*3+1]+=t.getY(e)*a,r[e*3+2]+=t.getZ(e)*a}return new q(r,3)}function NS(e){let t=jS(e.scene),n=new Map,r=e.expressionManager?.expressionMap;if(r!=null)for(let[e,t]of Object.entries(r)){let r=new Set;for(let i of t.binds)if(i instanceof by){if(i.weight!==0)for(let t of i.primitives){let r=n.get(t);r??(r=new Map,n.set(t,r));let a=r.get(e);a??(a=new Set,r.set(e,a)),a.add(i)}r.add(i)}for(let e of r)t.deleteBind(e)}for(let e of t){let t=n.get(e);if(t==null)continue;let i=e.geometry.morphAttributes;e.geometry.morphAttributes={};let a=e.geometry.clone();e.geometry=a;let o=a.morphTargetsRelative,s=i.position!=null,c=i.normal!=null,l={},u={},d=[];if(s||c){s&&(l.position=[]),c&&(l.normal=[]);let n=0;for(let[a,f]of t)s&&(l.position[n]=MS(i.position,f,o)),c&&(l.normal[n]=MS(i.normal,f,o)),r?.[a].addBind(new by({index:n,weight:1,primitives:[e]})),u[a]=n,d.push(0),n++}a.morphAttributes=l,e.morphTargetDictionary=u,e.morphTargetInfluences=d}}function PS(e,t,n){if(e.getComponent)return e.getComponent(t,n);{let r=e.array[t*e.itemSize+n];return e.normalized&&(r=ba.denormalize(r,e.array)),r}}function FS(e,t,n,r){e.setComponent?e.setComponent(t,n,r):(e.normalized&&(r=ba.normalize(r,e.array)),e.array[t*e.itemSize+n]=r)}function IS(e){let t=LS(e),n=new Set;for(let e of t)n.has(e.geometry)&&(e.geometry=WS(e.geometry)),n.add(e.geometry);let r=new Map;for(let e of n){let t=e.getAttribute(`skinIndex`),n=r.get(t)??new Map;r.set(t,n);let i=e.getAttribute(`skinWeight`),a=RS(t,i);n.set(i,a)}let i=new Map;for(let e of t){let t=zS(e,r);i.set(e,t)}let a=[];for(let[e,t]of i){let n=!1;for(let r of a)if(BS(t,r.boneInverseMap)){n=!0,r.meshes.add(e);for(let[e,n]of t)r.boneInverseMap.set(e,n);break}n||a.push({boneInverseMap:t,meshes:new Set([e])})}let o=new Map,s=new US,c=new US,l=new US;for(let e of a){let{boneInverseMap:t,meshes:n}=e,r=Array.from(t.keys()),i=new fc(r,Array.from(t.values())),a=c.getOrCreate(i);for(let e of n){let t=e.geometry.getAttribute(`skinIndex`),n=s.getOrCreate(t),i=e.skeleton.bones,c=`${n};${a};${i.map(e=>l.getOrCreate(e)).join(`,`)}`,u=o.get(c);u??(u=t.clone(),VS(u,i,r),o.set(c,u)),e.geometry.setAttribute(`skinIndex`,u)}for(let e of n)e.bind(i,new G)}}function LS(e){let t=new Set;return e.traverse(e=>{if(!e.isSkinnedMesh)return;let n=e;t.add(n)}),t}function RS(e,t){let n=new Set;for(let r=0;r<e.count;r++)for(let i=0;i<e.itemSize;i++){let a=PS(e,r,i);PS(t,r,i)!==0&&n.add(a)}return n}function zS(e,t){let n=new Map,r=e.skeleton,i=e.geometry,a=i.getAttribute(`skinIndex`),o=i.getAttribute(`skinWeight`),s=t.get(a)?.get(o);if(!s)throw Error(`Unreachable. attributeUsedIndexSetMap does not know the skin index attribute or the skin weight attribute.`);for(let e of s)n.set(r.bones[e],r.boneInverses[e]);return n}function BS(e,t){for(let[n,r]of e.entries()){let e=t.get(n);if(e!=null&&!HS(r,e))return!1}return!0}function VS(e,t,n){let r=new Map;for(let e of t)r.set(e,r.size);let i=new Map;for(let[e,t]of n.entries()){let n=r.get(t);i.set(n,e)}for(let t=0;t<e.count;t++)for(let n=0;n<e.itemSize;n++){let r=PS(e,t,n),a=i.get(r);FS(e,t,n,a)}e.needsUpdate=!0}function HS(e,t,n){if(n||=1e-4,e.elements.length!=t.elements.length)return!1;for(let r=0,i=e.elements.length;r<i;r++)if(Math.abs(e.elements[r]-t.elements[r])>n)return!1;return!0}var US=class{constructor(){this._objectIndexMap=new Map,this._index=0}get(e){return this._objectIndexMap.get(e)}getOrCreate(e){let t=this._objectIndexMap.get(e);return t??(t=this._index,this._objectIndexMap.set(e,t),this._index++),t}};function WS(e){let t=new J;t.name=e.name,t.setIndex(e.index);for(let[n,r]of Object.entries(e.attributes))t.setAttribute(n,r);for(let[n,r]of Object.entries(e.morphAttributes)){let e=n;t.morphAttributes[e]=r.concat()}t.morphTargetsRelative=e.morphTargetsRelative,t.groups=[];for(let n of e.groups)t.addGroup(n.start,n.count,n.materialIndex);return t.boundingSphere=e.boundingSphere?.clone()??null,t.boundingBox=e.boundingBox?.clone()??null,t.drawRange.start=e.drawRange.start,t.drawRange.count=e.drawRange.count,t.userData=e.userData,t}function GS(e){if(Object.values(e).forEach(e=>{e?.isTexture&&e.dispose()}),e.isShaderMaterial){let t=e.uniforms;t&&Object.values(t).forEach(e=>{let t=e.value;t?.isTexture&&t.dispose()})}e.dispose()}function KS(e){let t=e.geometry;t&&t.dispose();let n=e.skeleton;n&&n.dispose();let r=e.material;r&&(Array.isArray(r)?r.forEach(e=>GS(e)):r&&GS(r))}function qS(e){e.traverse(KS)}function JS(e,t){console.warn(`VRMUtils.removeUnnecessaryJoints: removeUnnecessaryJoints is deprecated. Use combineSkeletons instead. combineSkeletons contributes more to the performance improvement. This function will be removed in the next major version.`);let n=t?.experimentalSameBoneCounts??!1,r=[];e.traverse(e=>{e.type===`SkinnedMesh`&&r.push(e)});let i=new Map,a=0;for(let e of r){let t=e.geometry.getAttribute(`skinIndex`);if(i.has(t))continue;let n=new Map,r=new Map;for(let e=0;e<t.count;e++)for(let i=0;i<t.itemSize;i++){let a=PS(t,e,i),o=n.get(a);o??(o=n.size,n.set(a,o),r.set(o,a)),FS(t,e,i,o)}t.needsUpdate=!0,i.set(t,r),a=Math.max(a,n.size)}for(let e of r){let t=e.geometry.getAttribute(`skinIndex`),r=i.get(t),o=[],s=[],c=n?a:r.size;for(let t=0;t<c;t++){let n=r.get(t)??0;o.push(e.skeleton.bones[n]),s.push(e.skeleton.boneInverses[n])}let l=new fc(o,s);e.bind(l,new G)}}function YS(e,t){let n=e.position.count,r=Array(n),i=0,a=t.array;for(let e=0;e<a.length;e++){let t=a[e];r[t]||(r[t]=!0,i++)}return{isVertexUsed:r,vertexCount:n,verticesUsed:i}}function XS(e){let t=[],n=[],r=0;for(let i=0;i<e.length;i++)if(e[i]){let e=r++;t[i]=e,n[e]=i}return{originalIndexNewIndexMap:t,newIndexOriginalIndexMap:n}}function ZS(e,t){t.name=e.name,t.morphTargetsRelative=e.morphTargetsRelative,e.groups.forEach(e=>{t.addGroup(e.start,e.count,e.materialIndex)}),t.boundingBox=e.boundingBox?.clone()??null,t.boundingSphere=e.boundingSphere?.clone()??null,t.setDrawRange(e.drawRange.start,e.drawRange.count),t.userData=e.userData}function QS(e,t,n){let r=t.array,i=new r.constructor(r.length);for(let e=0;e<r.length;e++)i[e]=n[r[e]];e.setIndex(new q(i,t.itemSize,t.normalized))}function $S(e,t,n){let r=e.constructor,i=new r(t.length*n),a=!0;for(let r=0;r<t.length;r++){let o=t[r]*n,s=r*n;for(let t=0;t<n;t++){let n=e[o+t];i[s+t]=n,a&&=n===0}}return[i,a]}function eC(e){let t=new Map,n=[];for(let[r,i]of Object.entries(e))if(i.isInterleavedBufferAttribute){let e=i,n=e.data,a=t.get(n)??[];t.set(n,a),a.push([r,e])}else{let e=i;n.push([r,e])}return[t,n]}function tC(e,t,n){let[r,i]=eC(t);for(let[t,i]of r){let r=t.array,{stride:a}=t,[o,s]=$S(r,n,a),c=new ws(o,a);c.setUsage(t.usage);for(let[t,n]of i){let{itemSize:r,offset:i,normalized:a}=n,o=new Es(c,r,i,a);e.setAttribute(t,o)}}for(let[t,r]of i){let i=r.array,{itemSize:a,normalized:o}=r,[s,c]=$S(i,n,a);e.setAttribute(t,new q(s,a,o))}}function nC(e){let t=new Map,n=[];for(let[r,i]of Object.entries(e)){let e=r;for(let r=0;r<i.length;r++){let a=i[r];if(a.isInterleavedBufferAttribute){let n=a,i=n.data,o=t.get(i)??[];t.set(i,o),o.push([e,r,n])}else{let t=a;n.push([e,r,t])}}}return[t,n]}function rC(e,t,n){let r=!0,[i,a]=nC(t),o={};for(let[e,t]of i){let i=e.array,{stride:a}=e,[s,c]=$S(i,n,a);r&&=c;let l=new ws(s,a);l.setUsage(e.usage);for(let[e,n,r]of t){let{itemSize:t,offset:i,normalized:a}=r,s=new Es(l,t,i,a);o[e]??(o[e]=[]),o[e][n]=s}}for(let[e,t,i]of a){let a=i,s=a.array,{itemSize:c,normalized:l}=a,[u,d]=$S(s,n,c);r&&=d,o[e]??(o[e]=[]),o[e][t]=new q(u,c,l)}e.morphAttributes=r?{}:o}function iC(e){let t=new Map;e.traverse(e=>{if(!e.isMesh)return;let n=e,r=n.geometry,i=r.index;if(i==null)return;let a=t.get(r);if(a!=null){n.geometry=a;return}let{isVertexUsed:o,vertexCount:s,verticesUsed:c}=YS(r.attributes,i);if(c===s)return;let{originalIndexNewIndexMap:l,newIndexOriginalIndexMap:u}=XS(o),d=new J;ZS(r,d),t.set(r,d),QS(d,i,l),tC(d,r.attributes,u),rC(d,r.morphAttributes,u),n.geometry=d}),Array.from(t.keys()).forEach(e=>{e.dispose()})}function aC(e){e.meta?.metaVersion===`0`&&(e.scene.rotation.y=Math.PI)}var oC=class{constructor(){}};oC.combineMorphs=NS,oC.combineSkeletons=IS,oC.deepDispose=qS,oC.removeUnnecessaryJoints=JS,oC.removeUnnecessaryVertices=iC,oC.rotateVRM0=aC;function sC(e,t){if(t===0)return console.warn(`THREE.BufferGeometryUtils.toTrianglesDrawMode(): Geometry already defined as triangles.`),e;if(t===2||t===1){let n=e.getIndex();if(n===null){let t=[],r=e.getAttribute(`position`);if(r!==void 0){for(let e=0;e<r.count;e++)t.push(e);e.setIndex(t),n=e.getIndex()}else return console.error(`THREE.BufferGeometryUtils.toTrianglesDrawMode(): Undefined position attribute. Processing not possible.`),e}let r=n.count-2,i=[];if(t===2)for(let e=1;e<=r;e++)i.push(n.getX(0)),i.push(n.getX(e)),i.push(n.getX(e+1));else for(let e=0;e<r;e++)e%2==0?(i.push(n.getX(e)),i.push(n.getX(e+1)),i.push(n.getX(e+2))):(i.push(n.getX(e+2)),i.push(n.getX(e+1)),i.push(n.getX(e)));i.length/3!==r&&console.error(`THREE.BufferGeometryUtils.toTrianglesDrawMode(): Unable to generate correct amount of triangles.`);let a=e.clone();return a.setIndex(i),a.clearGroups(),a}else return console.error(`THREE.BufferGeometryUtils.toTrianglesDrawMode(): Unknown draw mode:`,t),e}function cC(e){let t=new Map,n=new Map,r=e.clone();return lC(e,r,function(e,r){t.set(r,e),n.set(e,r)}),r.traverse(function(e){if(!e.isSkinnedMesh)return;let r=e,i=t.get(e),a=i.skeleton.bones;r.skeleton=i.skeleton.clone(),r.bindMatrix.copy(i.bindMatrix),r.skeleton.bones=a.map(function(e){return n.get(e)}),r.bind(r.skeleton,r.bindMatrix)}),r}function lC(e,t,n){n(e,t);for(let r=0;r<e.children.length;r++)lC(e.children[r],t.children[r],n)}var uC=class extends ql{constructor(e){super(e),this.dracoLoader=null,this.ktx2Loader=null,this.meshoptDecoder=null,this.pluginCallbacks=[],this.register(function(e){return new _C(e)}),this.register(function(e){return new vC(e)}),this.register(function(e){return new DC(e)}),this.register(function(e){return new OC(e)}),this.register(function(e){return new kC(e)}),this.register(function(e){return new bC(e)}),this.register(function(e){return new xC(e)}),this.register(function(e){return new SC(e)}),this.register(function(e){return new CC(e)}),this.register(function(e){return new gC(e)}),this.register(function(e){return new wC(e)}),this.register(function(e){return new yC(e)}),this.register(function(e){return new EC(e)}),this.register(function(e){return new TC(e)}),this.register(function(e){return new mC(e)}),this.register(function(e){return new AC(e,pC.EXT_MESHOPT_COMPRESSION)}),this.register(function(e){return new AC(e,pC.KHR_MESHOPT_COMPRESSION)}),this.register(function(e){return new jC(e)})}load(e,t,n,r){let i=this,a;if(this.resourcePath!==``)a=this.resourcePath;else if(this.path!==``){let t=Su.extractUrlBase(e);a=Su.resolveURL(t,this.path)}else a=Su.extractUrlBase(e);this.manager.itemStart(e);let o=function(t){r?r(t):console.error(t),i.manager.itemError(e),i.manager.itemEnd(e)},s=new Xl(this.manager);s.setPath(this.path),s.setResponseType(`arraybuffer`),s.setRequestHeader(this.requestHeader),s.setWithCredentials(this.withCredentials),s.load(e,function(n){try{i.parse(n,a,function(n){t(n),i.manager.itemEnd(e)},o)}catch(e){o(e)}},n,o)}setDRACOLoader(e){return this.dracoLoader=e,this}setKTX2Loader(e){return this.ktx2Loader=e,this}setMeshoptDecoder(e){return this.meshoptDecoder=e,this}register(e){return this.pluginCallbacks.indexOf(e)===-1&&this.pluginCallbacks.push(e),this}unregister(e){return this.pluginCallbacks.indexOf(e)!==-1&&this.pluginCallbacks.splice(this.pluginCallbacks.indexOf(e),1),this}parse(e,t,n,r){let i,a={},o={},s=new TextDecoder;if(typeof e==`string`)i=JSON.parse(e);else if(e instanceof ArrayBuffer)if(s.decode(new Uint8Array(e,0,4))===MC){try{a[pC.KHR_BINARY_GLTF]=new FC(e)}catch(e){r&&r(e);return}i=JSON.parse(a[pC.KHR_BINARY_GLTF].content)}else i=JSON.parse(s.decode(e));else i=e;if(i.asset===void 0||i.asset.version[0]<2){r&&r(Error(`THREE.GLTFLoader: Unsupported asset. glTF versions >=2.0 are supported.`));return}let c=new sw(i,{path:t||this.resourcePath||``,crossOrigin:this.crossOrigin,requestHeader:this.requestHeader,manager:this.manager,ktx2Loader:this.ktx2Loader,meshoptDecoder:this.meshoptDecoder});c.fileLoader.setRequestHeader(this.requestHeader);for(let e=0;e<this.pluginCallbacks.length;e++){let t=this.pluginCallbacks[e](c);t.name||console.error(`THREE.GLTFLoader: Invalid plugin found: missing name`),o[t.name]=t,a[t.name]=!0}if(i.extensionsUsed)for(let e=0;e<i.extensionsUsed.length;++e){let t=i.extensionsUsed[e],n=i.extensionsRequired||[];switch(t){case pC.KHR_MATERIALS_UNLIT:a[t]=new hC;break;case pC.KHR_DRACO_MESH_COMPRESSION:a[t]=new IC(i,this.dracoLoader);break;case pC.KHR_TEXTURE_TRANSFORM:a[t]=new LC;break;case pC.KHR_MESH_QUANTIZATION:a[t]=new RC;break;default:n.indexOf(t)>=0&&o[t]===void 0&&console.warn(`THREE.GLTFLoader: Unknown extension "`+t+`".`)}}c.setExtensions(a),c.setPlugins(o),c.parse(n,r)}parseAsync(e,t){let n=this;return new Promise(function(r,i){n.parse(e,t,r,i)})}};function dC(){let e={};return{get:function(t){return e[t]},add:function(t,n){e[t]=n},remove:function(t){delete e[t]},removeAll:function(){e={}}}}function fC(e,t,n){let r=e.json.materials[t];return r.extensions&&r.extensions[n]?r.extensions[n]:null}var pC={KHR_BINARY_GLTF:`KHR_binary_glTF`,KHR_DRACO_MESH_COMPRESSION:`KHR_draco_mesh_compression`,KHR_LIGHTS_PUNCTUAL:`KHR_lights_punctual`,KHR_MATERIALS_CLEARCOAT:`KHR_materials_clearcoat`,KHR_MATERIALS_DISPERSION:`KHR_materials_dispersion`,KHR_MATERIALS_IOR:`KHR_materials_ior`,KHR_MATERIALS_SHEEN:`KHR_materials_sheen`,KHR_MATERIALS_SPECULAR:`KHR_materials_specular`,KHR_MATERIALS_TRANSMISSION:`KHR_materials_transmission`,KHR_MATERIALS_IRIDESCENCE:`KHR_materials_iridescence`,KHR_MATERIALS_ANISOTROPY:`KHR_materials_anisotropy`,KHR_MATERIALS_UNLIT:`KHR_materials_unlit`,KHR_MATERIALS_VOLUME:`KHR_materials_volume`,KHR_TEXTURE_BASISU:`KHR_texture_basisu`,KHR_TEXTURE_TRANSFORM:`KHR_texture_transform`,KHR_MESH_QUANTIZATION:`KHR_mesh_quantization`,KHR_MATERIALS_EMISSIVE_STRENGTH:`KHR_materials_emissive_strength`,EXT_MATERIALS_BUMP:`EXT_materials_bump`,EXT_TEXTURE_WEBP:`EXT_texture_webp`,EXT_TEXTURE_AVIF:`EXT_texture_avif`,EXT_MESHOPT_COMPRESSION:`EXT_meshopt_compression`,KHR_MESHOPT_COMPRESSION:`KHR_meshopt_compression`,EXT_MESH_GPU_INSTANCING:`EXT_mesh_gpu_instancing`},mC=class{constructor(e){this.parser=e,this.name=pC.KHR_LIGHTS_PUNCTUAL,this.cache={refs:{},uses:{}}}_markDefs(){let e=this.parser,t=this.parser.json.nodes||[];for(let n=0,r=t.length;n<r;n++){let r=t[n];r.extensions&&r.extensions[this.name]&&r.extensions[this.name].light!==void 0&&e._addNodeRef(this.cache,r.extensions[this.name].light)}}_loadLight(e){let t=this.parser,n=`light:`+e,r=t.cache.get(n);if(r)return r;let i=t.json,a=((i.extensions&&i.extensions[this.name]||{}).lights||[])[e],o,s=new K(16777215);a.color!==void 0&&s.setRGB(a.color[0],a.color[1],a.color[2],ki);let c=a.range===void 0?0:a.range;switch(a.type){case`directional`:o=new bu(s),o.target.position.set(0,0,-1),o.add(o.target);break;case`point`:o=new _u(s),o.distance=c;break;case`spot`:o=new hu(s),o.distance=c,a.spot=a.spot||{},a.spot.innerConeAngle=a.spot.innerConeAngle===void 0?0:a.spot.innerConeAngle,a.spot.outerConeAngle=a.spot.outerConeAngle===void 0?Math.PI/4:a.spot.outerConeAngle,o.angle=a.spot.outerConeAngle,o.penumbra=1-a.spot.innerConeAngle/a.spot.outerConeAngle,o.target.position.set(0,0,-1),o.add(o.target);break;default:throw Error(`THREE.GLTFLoader: Unexpected light type: `+a.type)}return o.position.set(0,0,0),$C(o,a),a.intensity!==void 0&&(o.intensity=a.intensity),o.name=t.createUniqueName(a.name||`light_`+e),r=Promise.resolve(o),t.cache.add(n,r),r}getDependency(e,t){if(e===`light`)return this._loadLight(t)}createNodeAttachment(e){let t=this,n=this.parser,r=n.json.nodes[e],i=(r.extensions&&r.extensions[this.name]||{}).light;return i===void 0?null:this._loadLight(i).then(function(e){return n._getNodeRef(t.cache,i,e)})}},hC=class{constructor(){this.name=pC.KHR_MATERIALS_UNLIT}getMaterialType(){return Ls}extendParams(e,t,n){let r=[];e.color=new K(1,1,1),e.opacity=1;let i=t.pbrMetallicRoughness;if(i){if(Array.isArray(i.baseColorFactor)){let t=i.baseColorFactor;e.color.setRGB(t[0],t[1],t[2],ki),e.opacity=t[3]}i.baseColorTexture!==void 0&&r.push(n.assignTexture(e,`map`,i.baseColorTexture,Oi))}return Promise.all(r)}},gC=class{constructor(e){this.parser=e,this.name=pC.KHR_MATERIALS_EMISSIVE_STRENGTH}extendMaterialParams(e,t){let n=fC(this.parser,e,this.name);return n===null||n.emissiveStrength!==void 0&&(t.emissiveIntensity=n.emissiveStrength),Promise.resolve()}},_C=class{constructor(e){this.parser=e,this.name=pC.KHR_MATERIALS_CLEARCOAT}getMaterialType(e){return fC(this.parser,e,this.name)===null?null:xl}extendMaterialParams(e,t){let n=fC(this.parser,e,this.name);if(n===null)return Promise.resolve();let r=[];if(n.clearcoatFactor!==void 0&&(t.clearcoat=n.clearcoatFactor),n.clearcoatTexture!==void 0&&r.push(this.parser.assignTexture(t,`clearcoatMap`,n.clearcoatTexture)),n.clearcoatRoughnessFactor!==void 0&&(t.clearcoatRoughness=n.clearcoatRoughnessFactor),n.clearcoatRoughnessTexture!==void 0&&r.push(this.parser.assignTexture(t,`clearcoatRoughnessMap`,n.clearcoatRoughnessTexture)),n.clearcoatNormalTexture!==void 0&&(r.push(this.parser.assignTexture(t,`clearcoatNormalMap`,n.clearcoatNormalTexture)),n.clearcoatNormalTexture.scale!==void 0)){let e=n.clearcoatNormalTexture.scale;t.clearcoatNormalScale=new V(e,e)}return Promise.all(r)}},vC=class{constructor(e){this.parser=e,this.name=pC.KHR_MATERIALS_DISPERSION}getMaterialType(e){return fC(this.parser,e,this.name)===null?null:xl}extendMaterialParams(e,t){let n=fC(this.parser,e,this.name);return n===null||(t.dispersion=n.dispersion===void 0?0:n.dispersion),Promise.resolve()}},yC=class{constructor(e){this.parser=e,this.name=pC.KHR_MATERIALS_IRIDESCENCE}getMaterialType(e){return fC(this.parser,e,this.name)===null?null:xl}extendMaterialParams(e,t){let n=fC(this.parser,e,this.name);if(n===null)return Promise.resolve();let r=[];return n.iridescenceFactor!==void 0&&(t.iridescence=n.iridescenceFactor),n.iridescenceTexture!==void 0&&r.push(this.parser.assignTexture(t,`iridescenceMap`,n.iridescenceTexture)),n.iridescenceIor!==void 0&&(t.iridescenceIOR=n.iridescenceIor),t.iridescenceThicknessRange===void 0&&(t.iridescenceThicknessRange=[100,400]),n.iridescenceThicknessMinimum!==void 0&&(t.iridescenceThicknessRange[0]=n.iridescenceThicknessMinimum),n.iridescenceThicknessMaximum!==void 0&&(t.iridescenceThicknessRange[1]=n.iridescenceThicknessMaximum),n.iridescenceThicknessTexture!==void 0&&r.push(this.parser.assignTexture(t,`iridescenceThicknessMap`,n.iridescenceThicknessTexture)),Promise.all(r)}},bC=class{constructor(e){this.parser=e,this.name=pC.KHR_MATERIALS_SHEEN}getMaterialType(e){return fC(this.parser,e,this.name)===null?null:xl}extendMaterialParams(e,t){let n=fC(this.parser,e,this.name);if(n===null)return Promise.resolve();let r=[];if(t.sheenColor=new K(0,0,0),t.sheenRoughness=0,t.sheen=1,n.sheenColorFactor!==void 0){let e=n.sheenColorFactor;t.sheenColor.setRGB(e[0],e[1],e[2],ki)}return n.sheenRoughnessFactor!==void 0&&(t.sheenRoughness=n.sheenRoughnessFactor),n.sheenColorTexture!==void 0&&r.push(this.parser.assignTexture(t,`sheenColorMap`,n.sheenColorTexture,Oi)),n.sheenRoughnessTexture!==void 0&&r.push(this.parser.assignTexture(t,`sheenRoughnessMap`,n.sheenRoughnessTexture)),Promise.all(r)}},xC=class{constructor(e){this.parser=e,this.name=pC.KHR_MATERIALS_TRANSMISSION}getMaterialType(e){return fC(this.parser,e,this.name)===null?null:xl}extendMaterialParams(e,t){let n=fC(this.parser,e,this.name);if(n===null)return Promise.resolve();let r=[];return n.transmissionFactor!==void 0&&(t.transmission=n.transmissionFactor),n.transmissionTexture!==void 0&&r.push(this.parser.assignTexture(t,`transmissionMap`,n.transmissionTexture)),Promise.all(r)}},SC=class{constructor(e){this.parser=e,this.name=pC.KHR_MATERIALS_VOLUME}getMaterialType(e){return fC(this.parser,e,this.name)===null?null:xl}extendMaterialParams(e,t){let n=fC(this.parser,e,this.name);if(n===null)return Promise.resolve();let r=[];t.thickness=n.thicknessFactor===void 0?0:n.thicknessFactor,n.thicknessTexture!==void 0&&r.push(this.parser.assignTexture(t,`thicknessMap`,n.thicknessTexture)),t.attenuationDistance=n.attenuationDistance||1/0;let i=n.attenuationColor||[1,1,1];return t.attenuationColor=new K().setRGB(i[0],i[1],i[2],ki),Promise.all(r)}},CC=class{constructor(e){this.parser=e,this.name=pC.KHR_MATERIALS_IOR}getMaterialType(e){return fC(this.parser,e,this.name)===null?null:xl}extendMaterialParams(e,t){let n=fC(this.parser,e,this.name);return n===null?Promise.resolve():(t.ior=n.ior===void 0?1.5:n.ior,t.ior===0&&(t.ior=1e3),Promise.resolve())}},wC=class{constructor(e){this.parser=e,this.name=pC.KHR_MATERIALS_SPECULAR}getMaterialType(e){return fC(this.parser,e,this.name)===null?null:xl}extendMaterialParams(e,t){let n=fC(this.parser,e,this.name);if(n===null)return Promise.resolve();let r=[];t.specularIntensity=n.specularFactor===void 0?1:n.specularFactor,n.specularTexture!==void 0&&r.push(this.parser.assignTexture(t,`specularIntensityMap`,n.specularTexture));let i=n.specularColorFactor||[1,1,1];return t.specularColor=new K().setRGB(i[0],i[1],i[2],ki),n.specularColorTexture!==void 0&&r.push(this.parser.assignTexture(t,`specularColorMap`,n.specularColorTexture,Oi)),Promise.all(r)}},TC=class{constructor(e){this.parser=e,this.name=pC.EXT_MATERIALS_BUMP}getMaterialType(e){return fC(this.parser,e,this.name)===null?null:xl}extendMaterialParams(e,t){let n=fC(this.parser,e,this.name);if(n===null)return Promise.resolve();let r=[];return t.bumpScale=n.bumpFactor===void 0?1:n.bumpFactor,n.bumpTexture!==void 0&&r.push(this.parser.assignTexture(t,`bumpMap`,n.bumpTexture)),Promise.all(r)}},EC=class{constructor(e){this.parser=e,this.name=pC.KHR_MATERIALS_ANISOTROPY}getMaterialType(e){return fC(this.parser,e,this.name)===null?null:xl}extendMaterialParams(e,t){let n=fC(this.parser,e,this.name);if(n===null)return Promise.resolve();let r=[];return n.anisotropyStrength!==void 0&&(t.anisotropy=n.anisotropyStrength),n.anisotropyRotation!==void 0&&(t.anisotropyRotation=n.anisotropyRotation),n.anisotropyTexture!==void 0&&r.push(this.parser.assignTexture(t,`anisotropyMap`,n.anisotropyTexture)),Promise.all(r)}},DC=class{constructor(e){this.parser=e,this.name=pC.KHR_TEXTURE_BASISU}loadTexture(e){let t=this.parser,n=t.json,r=n.textures[e];if(!r.extensions||!r.extensions[this.name])return null;let i=r.extensions[this.name],a=t.options.ktx2Loader;if(!a){if(n.extensionsRequired&&n.extensionsRequired.indexOf(this.name)>=0)throw Error(`THREE.GLTFLoader: setKTX2Loader must be called before loading KTX2 textures`);return null}return t.loadTextureImage(e,i.source,a)}},OC=class{constructor(e){this.parser=e,this.name=pC.EXT_TEXTURE_WEBP}loadTexture(e){let t=this.name,n=this.parser,r=n.json,i=r.textures[e];if(!i.extensions||!i.extensions[t])return null;let a=i.extensions[t],o=r.images[a.source],s=n.textureLoader;if(o.uri){let e=n.options.manager.getHandler(o.uri);e!==null&&(s=e)}return n.loadTextureImage(e,a.source,s)}},kC=class{constructor(e){this.parser=e,this.name=pC.EXT_TEXTURE_AVIF}loadTexture(e){let t=this.name,n=this.parser,r=n.json,i=r.textures[e];if(!i.extensions||!i.extensions[t])return null;let a=i.extensions[t],o=r.images[a.source],s=n.textureLoader;if(o.uri){let e=n.options.manager.getHandler(o.uri);e!==null&&(s=e)}return n.loadTextureImage(e,a.source,s)}},AC=class{constructor(e,t){this.name=t,this.parser=e}loadBufferView(e){let t=this.parser.json,n=t.bufferViews[e];if(n.extensions&&n.extensions[this.name]){let e=n.extensions[this.name],r=this.parser.getDependency(`buffer`,e.buffer),i=this.parser.options.meshoptDecoder;if(!i||!i.supported){if(t.extensionsRequired&&t.extensionsRequired.indexOf(this.name)>=0)throw Error(`THREE.GLTFLoader: setMeshoptDecoder must be called before loading compressed files`);return null}return r.then(function(t){let n=e.byteOffset||0,r=e.byteLength||0,a=e.count,o=e.byteStride,s=new Uint8Array(t,n,r);return i.decodeGltfBufferAsync?i.decodeGltfBufferAsync(a,o,s,e.mode,e.filter).then(function(e){return e.buffer}):i.ready.then(function(){let t=new ArrayBuffer(a*o);return i.decodeGltfBuffer(new Uint8Array(t),a,o,s,e.mode,e.filter),t})})}else return null}},jC=class{constructor(e){this.name=pC.EXT_MESH_GPU_INSTANCING,this.parser=e}createNodeMesh(e){let t=this.parser.json,n=t.nodes[e];if(!n.extensions||!n.extensions[this.name]||n.mesh===void 0)return null;let r=t.meshes[n.mesh];for(let e of r.primitives)if(e.mode!==HC.TRIANGLES&&e.mode!==HC.TRIANGLE_STRIP&&e.mode!==HC.TRIANGLE_FAN&&e.mode!==void 0)return null;let i=n.extensions[this.name].attributes,a=[],o={};for(let e in i)a.push(this.parser.getDependency(`accessor`,i[e]).then(t=>(o[e]=t,o[e])));return a.length<1?null:(a.push(this.parser.createNodeMesh(e)),Promise.all(a).then(e=>{let t=e.pop(),n=t.isGroup?t.children:[t],r=e[0].count,i=[];for(let e of n){let t=new G,n=new U,a=new H,s=new U(1,1,1),c=new xc(e.geometry,e.material,r);for(let e=0;e<r;e++)o.TRANSLATION&&n.fromBufferAttribute(o.TRANSLATION,e),o.ROTATION&&a.fromBufferAttribute(o.ROTATION,e),o.SCALE&&s.fromBufferAttribute(o.SCALE,e),c.setMatrixAt(e,t.compose(n,a,s));for(let t in o)if(t===`_COLOR_0`){let e=o[t];c.instanceColor=new pc(e.array,e.itemSize,e.normalized)}else t!==`TRANSLATION`&&t!==`ROTATION`&&t!==`SCALE`&&e.geometry.setAttribute(t,o[t]);go.prototype.copy.call(c,e),this.parser.assignFinalMaterial(c),i.push(c)}return t.isGroup?(t.clear(),t.add(...i),t):i[0]}))}},MC=`glTF`,NC=12,PC={JSON:1313821514,BIN:5130562},FC=class{constructor(e){this.name=pC.KHR_BINARY_GLTF,this.content=null,this.body=null;let t=new DataView(e,0,NC),n=new TextDecoder;if(this.header={magic:n.decode(new Uint8Array(e.slice(0,4))),version:t.getUint32(4,!0),length:t.getUint32(8,!0)},this.header.magic!==MC)throw Error(`THREE.GLTFLoader: Unsupported glTF-Binary header.`);if(this.header.version<2)throw Error(`THREE.GLTFLoader: Legacy binary file detected.`);let r=this.header.length-NC,i=new DataView(e,NC),a=0;for(;a<r;){let t=i.getUint32(a,!0);a+=4;let r=i.getUint32(a,!0);if(a+=4,r===PC.JSON){let r=new Uint8Array(e,NC+a,t);this.content=n.decode(r)}else if(r===PC.BIN){let n=NC+a;this.body=e.slice(n,n+t)}a+=t}if(this.content===null)throw Error(`THREE.GLTFLoader: JSON content not found.`)}},IC=class{constructor(e,t){if(!t)throw Error(`THREE.GLTFLoader: No DRACOLoader instance provided.`);this.name=pC.KHR_DRACO_MESH_COMPRESSION,this.json=e,this.dracoLoader=t,this.dracoLoader.preload()}decodePrimitive(e,t){let n=this.json,r=this.dracoLoader,i=e.extensions[this.name].bufferView,a=e.extensions[this.name].attributes,o={},s={},c={};for(let e in a){let t=qC[e]||e.toLowerCase();o[t]=a[e]}for(let t in e.attributes){let r=qC[t]||t.toLowerCase();if(a[t]!==void 0){let i=n.accessors[e.attributes[t]];c[r]=UC[i.componentType].name,s[r]=i.normalized===!0}}return t.getDependency(`bufferView`,i).then(function(e){return new Promise(function(t,n){r.decodeDracoFile(e,function(e){for(let t in e.attributes){let n=e.attributes[t],r=s[t];r!==void 0&&(n.normalized=r)}t(e)},o,c,ki,n)})})}},LC=class{constructor(){this.name=pC.KHR_TEXTURE_TRANSFORM}extendTexture(e,t){return(t.texCoord===void 0||t.texCoord===e.channel)&&t.offset===void 0&&t.rotation===void 0&&t.scale===void 0?e:(e=e.clone(),t.texCoord!==void 0&&(e.channel=t.texCoord),t.offset!==void 0&&e.offset.fromArray(t.offset),t.rotation!==void 0&&(e.rotation=t.rotation),t.scale!==void 0&&e.repeat.fromArray(t.scale),e.needsUpdate=!0,e)}},RC=class{constructor(){this.name=pC.KHR_MESH_QUANTIZATION}},zC=class extends Ol{constructor(e,t,n,r){super(e,t,n,r)}copySampleValue_(e){let t=this.resultBuffer,n=this.sampleValues,r=this.valueSize,i=e*r*3+r;for(let e=0;e!==r;e++)t[e]=n[i+e];return t}interpolate_(e,t,n,r){let i=this.resultBuffer,a=this.sampleValues,o=this.valueSize,s=o*2,c=o*3,l=r-t,u=(n-t)/l,d=u*u,f=d*u,p=e*c,m=p-c,h=-2*f+3*d,g=f-d,_=1-h,v=g-d+u;for(let e=0;e!==o;e++){let t=a[m+e+o],n=a[m+e+s]*l,r=a[p+e+o],c=a[p+e]*l;i[e]=_*t+v*n+h*r+g*c}return i}},BC=new H,VC=class extends zC{interpolate_(e,t,n,r){let i=super.interpolate_(e,t,n,r);return BC.fromArray(i).normalize().toArray(i),i}},HC={FLOAT:5126,FLOAT_MAT3:35675,FLOAT_MAT4:35676,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,LINEAR:9729,REPEAT:10497,SAMPLER_2D:35678,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,UNSIGNED_BYTE:5121,UNSIGNED_SHORT:5123},UC={5120:Int8Array,5121:Uint8Array,5122:Int16Array,5123:Uint16Array,5125:Uint32Array,5126:Float32Array},WC={9728:rr,9729:or,9984:ir,9985:sr,9986:ar,9987:cr},GC={33071:tr,33648:nr,10497:er},KC={SCALAR:1,VEC2:2,VEC3:3,VEC4:4,MAT2:4,MAT3:9,MAT4:16},qC={POSITION:`position`,NORMAL:`normal`,TANGENT:`tangent`,TEXCOORD_0:`uv`,TEXCOORD_1:`uv1`,TEXCOORD_2:`uv2`,TEXCOORD_3:`uv3`,COLOR_0:`color`,WEIGHTS_0:`skinWeight`,JOINTS_0:`skinIndex`},JC={scale:`scale`,translation:`position`,rotation:`quaternion`,weights:`morphTargetInfluences`},YC={CUBICSPLINE:void 0,LINEAR:vi,STEP:_i},XC={OPAQUE:`OPAQUE`,MASK:`MASK`,BLEND:`BLEND`};function ZC(e){return e.DefaultMaterial===void 0&&(e.DefaultMaterial=new bl({color:16777215,emissive:0,metalness:1,roughness:1,transparent:!1,depthTest:!0,side:0})),e.DefaultMaterial}function QC(e,t,n){for(let r in n.extensions)e[r]===void 0&&(t.userData.gltfExtensions=t.userData.gltfExtensions||{},t.userData.gltfExtensions[r]=n.extensions[r])}function $C(e,t){t.extras!==void 0&&(typeof t.extras==`object`?Object.assign(e.userData,t.extras):console.warn(`THREE.GLTFLoader: Ignoring primitive type .extras, `+t.extras))}function ew(e,t,n){let r=!1,i=!1,a=!1;for(let e=0,n=t.length;e<n;e++){let n=t[e];if(n.POSITION!==void 0&&(r=!0),n.NORMAL!==void 0&&(i=!0),n.COLOR_0!==void 0&&(a=!0),r&&i&&a)break}if(!r&&!i&&!a)return Promise.resolve(e);let o=[],s=[],c=[];for(let l=0,u=t.length;l<u;l++){let u=t[l];if(r){let t=u.POSITION===void 0?e.attributes.position:n.getDependency(`accessor`,u.POSITION);o.push(t)}if(i){let t=u.NORMAL===void 0?e.attributes.normal:n.getDependency(`accessor`,u.NORMAL);s.push(t)}if(a){let t=u.COLOR_0===void 0?e.attributes.color:n.getDependency(`accessor`,u.COLOR_0);c.push(t)}}return Promise.all([Promise.all(o),Promise.all(s),Promise.all(c)]).then(function(t){let n=t[0],o=t[1],s=t[2];return r&&(e.morphAttributes.position=n),i&&(e.morphAttributes.normal=o),a&&(e.morphAttributes.color=s),e.morphTargetsRelative=!0,e})}function tw(e,t){if(e.updateMorphTargets(),t.weights!==void 0)for(let n=0,r=t.weights.length;n<r;n++)e.morphTargetInfluences[n]=t.weights[n];if(t.extras&&Array.isArray(t.extras.targetNames)){let n=t.extras.targetNames;if(e.morphTargetInfluences.length===n.length){e.morphTargetDictionary={};for(let t=0,r=n.length;t<r;t++)e.morphTargetDictionary[n[t]]=t}else console.warn(`THREE.GLTFLoader: Invalid extras.targetNames length. Ignoring names.`)}}function nw(e){let t,n=e.extensions&&e.extensions[pC.KHR_DRACO_MESH_COMPRESSION];if(t=n?`draco:`+n.bufferView+`:`+n.indices+`:`+rw(n.attributes):e.indices+`:`+rw(e.attributes)+`:`+e.mode,e.targets!==void 0)for(let n=0,r=e.targets.length;n<r;n++)t+=`:`+rw(e.targets[n]);return t}function rw(e){let t=``,n=Object.keys(e).sort();for(let r=0,i=n.length;r<i;r++)t+=n[r]+`:`+e[n[r]]+`;`;return t}function iw(e){switch(e){case Int8Array:return 1/127;case Uint8Array:return 1/255;case Int16Array:return 1/32767;case Uint16Array:return 1/65535;default:throw Error(`THREE.GLTFLoader: Unsupported normalized accessor component type.`)}}function aw(e){return e.search(/\.jpe?g($|\?)/i)>0||e.search(/^data\:image\/jpeg/)===0?`image/jpeg`:e.search(/\.webp($|\?)/i)>0||e.search(/^data\:image\/webp/)===0?`image/webp`:e.search(/\.ktx2($|\?)/i)>0||e.search(/^data\:image\/ktx2/)===0?`image/ktx2`:`image/png`}var ow=new G,sw=class{constructor(e={},t={}){this.json=e,this.extensions={},this.plugins={},this.options=t,this.cache=new dC,this.associations=new Map,this.primitiveCache={},this.nodeCache={},this.meshCache={refs:{},uses:{}},this.cameraCache={refs:{},uses:{}},this.lightCache={refs:{},uses:{}},this.sourceCache={},this.textureCache={},this.nodeNamesUsed={};let n=!1,r=-1,i=!1,a=-1;if(typeof navigator<`u`&&navigator.userAgent!==void 0){let e=navigator.userAgent;n=/^((?!chrome|android).)*safari/i.test(e)===!0;let t=e.match(/Version\/(\d+)/);r=n&&t?parseInt(t[1],10):-1,i=e.indexOf(`Firefox`)>-1,a=i?e.match(/Firefox\/([0-9]+)\./)[1]:-1}typeof createImageBitmap>`u`||n&&r<17||i&&a<98?this.textureLoader=new eu(this.options.manager):this.textureLoader=new wu(this.options.manager),this.textureLoader.setCrossOrigin(this.options.crossOrigin),this.textureLoader.setRequestHeader(this.options.requestHeader),this.fileLoader=new Xl(this.options.manager),this.fileLoader.setResponseType(`arraybuffer`),this.options.crossOrigin===`use-credentials`&&this.fileLoader.setWithCredentials(!0)}setExtensions(e){this.extensions=e}setPlugins(e){this.plugins=e}parse(e,t){let n=this,r=this.json,i=this.extensions;this.cache.removeAll(),this.nodeCache={},this._invokeAll(function(e){return e._markDefs&&e._markDefs()}),Promise.all(this._invokeAll(function(e){return e.beforeRoot&&e.beforeRoot()})).then(function(){return Promise.all([n.getDependencies(`scene`),n.getDependencies(`animation`),n.getDependencies(`camera`)])}).then(function(t){let a={scene:t[0][r.scene||0],scenes:t[0],animations:t[1],cameras:t[2],asset:r.asset,parser:n,userData:{}};return QC(i,a,r),$C(a,r),Promise.all(n._invokeAll(function(e){return e.afterRoot&&e.afterRoot(a)})).then(function(){for(let e of a.scenes)e.updateMatrixWorld();e(a)})}).catch(t)}_markDefs(){let e=this.json.nodes||[],t=this.json.skins||[],n=this.json.meshes||[];for(let n=0,r=t.length;n<r;n++){let r=t[n].joints;for(let t=0,n=r.length;t<n;t++)e[r[t]].isBone=!0}for(let t=0,r=e.length;t<r;t++){let r=e[t];r.mesh!==void 0&&(this._addNodeRef(this.meshCache,r.mesh),r.skin!==void 0&&(n[r.mesh].isSkinnedMesh=!0)),r.camera!==void 0&&this._addNodeRef(this.cameraCache,r.camera)}}_addNodeRef(e,t){t!==void 0&&(e.refs[t]===void 0&&(e.refs[t]=e.uses[t]=0),e.refs[t]++)}_getNodeRef(e,t,n){if(e.refs[t]<=1)return n;let r=n.clone(),i=(e,t)=>{let n=this.associations.get(e);n!=null&&this.associations.set(t,n);for(let[n,r]of e.children.entries())i(r,t.children[n])};return i(n,r),r.name+=`_instance_`+ e.uses[t]++,r}_invokeOne(e){let t=Object.values(this.plugins);t.push(this);for(let n=0;n<t.length;n++){let r=e(t[n]);if(r)return r}return null}_invokeAll(e){let t=Object.values(this.plugins);t.unshift(this);let n=[];for(let r=0;r<t.length;r++){let i=e(t[r]);i&&n.push(i)}return n}getDependency(e,t){let n=e+`:`+t,r=this.cache.get(n);if(!r){switch(e){case`scene`:r=this.loadScene(t);break;case`node`:r=this._invokeOne(function(e){return e.loadNode&&e.loadNode(t)});break;case`mesh`:r=this._invokeOne(function(e){return e.loadMesh&&e.loadMesh(t)});break;case`accessor`:r=this.loadAccessor(t);break;case`bufferView`:r=this._invokeOne(function(e){return e.loadBufferView&&e.loadBufferView(t)});break;case`buffer`:r=this.loadBuffer(t);break;case`material`:r=this._invokeOne(function(e){return e.loadMaterial&&e.loadMaterial(t)});break;case`texture`:r=this._invokeOne(function(e){return e.loadTexture&&e.loadTexture(t)});break;case`skin`:r=this.loadSkin(t);break;case`animation`:r=this._invokeOne(function(e){return e.loadAnimation&&e.loadAnimation(t)});break;case`camera`:r=this.loadCamera(t);break;default:if(r=this._invokeOne(function(n){return n!=this&&n.getDependency&&n.getDependency(e,t)}),!r)throw Error(`Unknown type: `+e);break}this.cache.add(n,r)}return r}getDependencies(e){let t=this.cache.get(e);if(!t){let n=this,r=this.json[e+(e===`mesh`?`es`:`s`)]||[];t=Promise.all(r.map(function(t,r){return n.getDependency(e,r)})),this.cache.add(e,t)}return t}loadBuffer(e){let t=this.json.buffers[e],n=this.fileLoader;if(t.type&&t.type!==`arraybuffer`)throw Error(`THREE.GLTFLoader: `+t.type+` buffer type is not supported.`);if(t.uri===void 0&&e===0)return Promise.resolve(this.extensions[pC.KHR_BINARY_GLTF].body);let r=this.options;return new Promise(function(e,i){n.load(Su.resolveURL(t.uri,r.path),e,void 0,function(){i(Error(`THREE.GLTFLoader: Failed to load buffer "`+t.uri+`".`))})})}loadBufferView(e){let t=this.json.bufferViews[e];return this.getDependency(`buffer`,t.buffer).then(function(e){let n=t.byteLength||0,r=t.byteOffset||0;return e.slice(r,r+n)})}loadAccessor(e){let t=this,n=this.json,r=this.json.accessors[e];if(r.bufferView===void 0&&r.sparse===void 0){let e=KC[r.type],t=UC[r.componentType],n=r.normalized===!0,i=new t(r.count*e);return Promise.resolve(new q(i,e,n))}let i=[];return r.bufferView===void 0?i.push(null):i.push(this.getDependency(`bufferView`,r.bufferView)),r.sparse!==void 0&&(i.push(this.getDependency(`bufferView`,r.sparse.indices.bufferView)),i.push(this.getDependency(`bufferView`,r.sparse.values.bufferView))),Promise.all(i).then(function(e){let i=e[0],a=KC[r.type],o=UC[r.componentType],s=o.BYTES_PER_ELEMENT,c=s*a,l=r.byteOffset||0,u=r.bufferView===void 0?void 0:n.bufferViews[r.bufferView].byteStride,d=r.normalized===!0,f,p;if(u&&u!==c){let e=Math.floor(l/u),n=`InterleavedBuffer:`+r.bufferView+`:`+r.componentType+`:`+e+`:`+r.count,c=t.cache.get(n);c||(f=new o(i,e*u,r.count*u/s),c=new ws(f,u/s),t.cache.add(n,c)),p=new Es(c,a,l%u/s,d)}else f=i===null?new o(r.count*a):new o(i,l,r.count*a),p=new q(f,a,d);if(r.sparse!==void 0){let t=KC.SCALAR,n=UC[r.sparse.indices.componentType],s=r.sparse.indices.byteOffset||0,c=r.sparse.values.byteOffset||0,l=new n(e[1],s,r.sparse.count*t),u=new o(e[2],c,r.sparse.count*a);i!==null&&(p=new q(p.array.slice(),p.itemSize,p.normalized)),p.normalized=!1;for(let e=0,t=l.length;e<t;e++){let t=l[e];if(p.setX(t,u[e*a]),a>=2&&p.setY(t,u[e*a+1]),a>=3&&p.setZ(t,u[e*a+2]),a>=4&&p.setW(t,u[e*a+3]),a>=5)throw Error(`THREE.GLTFLoader: Unsupported itemSize in sparse BufferAttribute.`)}p.normalized=d}return p})}loadTexture(e){let t=this.json,n=this.options,r=t.textures[e].source,i=t.images[r],a=this.textureLoader;if(i.uri){let e=n.manager.getHandler(i.uri);e!==null&&(a=e)}return this.loadTextureImage(e,r,a)}loadTextureImage(e,t,n){let r=this,i=this.json,a=i.textures[e],o=i.images[t],s=(o.uri||o.bufferView)+`:`+a.sampler;if(this.textureCache[s])return this.textureCache[s];let c=this.loadImageSource(t,n).then(function(t){t.flipY=!1,t.name=a.name||o.name||``,t.name===``&&typeof o.uri==`string`&&o.uri.startsWith(`data:image/`)===!1&&(t.name=o.uri);let n=(i.samplers||{})[a.sampler]||{};return t.magFilter=WC[n.magFilter]||1006,t.minFilter=WC[n.minFilter]||1008,t.wrapS=GC[n.wrapS]||1e3,t.wrapT=GC[n.wrapT]||1e3,t.generateMipmaps=!t.isCompressedTexture&&t.minFilter!==1003&&t.minFilter!==1006,r.associations.set(t,{textures:e}),t}).catch(function(){return null});return this.textureCache[s]=c,c}loadImageSource(e,t){let n=this,r=this.json,i=this.options;if(this.sourceCache[e]!==void 0)return this.sourceCache[e].then(e=>e.clone());let a=r.images[e],o=self.URL||self.webkitURL,s=a.uri||``,c=!1;if(a.bufferView!==void 0)s=n.getDependency(`bufferView`,a.bufferView).then(function(e){c=!0;let t=new Blob([e],{type:a.mimeType});return s=o.createObjectURL(t),s});else if(a.uri===void 0)throw Error(`THREE.GLTFLoader: Image `+e+` is missing URI and bufferView`);let l=Promise.resolve(s).then(function(e){return new Promise(function(n,r){let a=n;t.isImageBitmapLoader===!0&&(a=function(e){let t=new La(e);t.needsUpdate=!0,n(t)}),t.load(Su.resolveURL(e,i.path),a,void 0,r)})}).then(function(e){return c===!0&&o.revokeObjectURL(s),$C(e,a),e.userData.mimeType=a.mimeType||aw(a.uri),e}).catch(function(e){throw console.error(`THREE.GLTFLoader: Couldn't load texture`,s),e});return this.sourceCache[e]=l,l}assignTexture(e,t,n,r){let i=this;return this.getDependency(`texture`,n.index).then(function(a){if(!a)return null;if(n.texCoord!==void 0&&n.texCoord>0&&(a=a.clone(),a.channel=n.texCoord),i.extensions[pC.KHR_TEXTURE_TRANSFORM]){let e=n.extensions===void 0?void 0:n.extensions[pC.KHR_TEXTURE_TRANSFORM];if(e){let t=i.associations.get(a);a=i.extensions[pC.KHR_TEXTURE_TRANSFORM].extendTexture(a,e),i.associations.set(a,t)}}return r!==void 0&&(a.colorSpace=r),e[t]=a,a})}assignFinalMaterial(e){let t=e.geometry,n=e.material,r=t.attributes.tangent===void 0,i=t.attributes.color!==void 0,a=t.attributes.normal===void 0;if(e.isPoints){let e=`PointsMaterial:`+n.uuid,t=this.cache.get(e);t||(t=new Wc,Os.prototype.copy.call(t,n),t.color.copy(n.color),t.map=n.map,t.sizeAttenuation=!1,this.cache.add(e,t)),n=t}else if(e.isLine){let e=`LineBasicMaterial:`+n.uuid,t=this.cache.get(e);t||(t=new Ac,Os.prototype.copy.call(t,n),t.color.copy(n.color),t.map=n.map,this.cache.add(e,t)),n=t}if(r||i||a){let e=`ClonedMaterial:`+n.uuid+`:`;r&&(e+=`derivative-tangents:`),i&&(e+=`vertex-colors:`),a&&(e+=`flat-shading:`);let t=this.cache.get(e);t||(t=n.clone(),i&&(t.vertexColors=!0),a&&(t.flatShading=!0),r&&(t.normalScale&&(t.normalScale.y*=-1),t.clearcoatNormalScale&&(t.clearcoatNormalScale.y*=-1)),this.cache.add(e,t),this.associations.set(t,this.associations.get(n))),n=t}e.material=n}getMaterialType(){return bl}loadMaterial(e){let t=this,n=this.json,r=this.extensions,i=n.materials[e],a,o={},s=i.extensions||{},c=[];if(s[pC.KHR_MATERIALS_UNLIT]){let e=r[pC.KHR_MATERIALS_UNLIT];a=e.getMaterialType(),c.push(e.extendParams(o,i,t))}else{let n=i.pbrMetallicRoughness||{};if(o.color=new K(1,1,1),o.opacity=1,Array.isArray(n.baseColorFactor)){let e=n.baseColorFactor;o.color.setRGB(e[0],e[1],e[2],ki),o.opacity=e[3]}n.baseColorTexture!==void 0&&c.push(t.assignTexture(o,`map`,n.baseColorTexture,Oi)),o.metalness=n.metallicFactor===void 0?1:n.metallicFactor,o.roughness=n.roughnessFactor===void 0?1:n.roughnessFactor,n.metallicRoughnessTexture!==void 0&&(c.push(t.assignTexture(o,`metalnessMap`,n.metallicRoughnessTexture)),c.push(t.assignTexture(o,`roughnessMap`,n.metallicRoughnessTexture))),a=this._invokeOne(function(t){return t.getMaterialType&&t.getMaterialType(e)}),c.push(Promise.all(this._invokeAll(function(t){return t.extendMaterialParams&&t.extendMaterialParams(e,o)})))}i.doubleSided===!0&&(o.side=2);let l=i.alphaMode||XC.OPAQUE;if(l===XC.BLEND?(o.transparent=!0,o.depthWrite=!1):(o.transparent=!1,l===XC.MASK&&(o.alphaTest=i.alphaCutoff===void 0?.5:i.alphaCutoff)),i.normalTexture!==void 0&&a!==Ls&&(c.push(t.assignTexture(o,`normalMap`,i.normalTexture)),o.normalScale=new V(1,1),i.normalTexture.scale!==void 0)){let e=i.normalTexture.scale;o.normalScale.set(e,e)}if(i.occlusionTexture!==void 0&&a!==Ls&&(c.push(t.assignTexture(o,`aoMap`,i.occlusionTexture)),i.occlusionTexture.strength!==void 0&&(o.aoMapIntensity=i.occlusionTexture.strength)),i.emissiveFactor!==void 0&&a!==Ls){let e=i.emissiveFactor;o.emissive=new K().setRGB(e[0],e[1],e[2],ki)}return i.emissiveTexture!==void 0&&a!==Ls&&c.push(t.assignTexture(o,`emissiveMap`,i.emissiveTexture,Oi)),Promise.all(c).then(function(){let n=new a(o);return i.name&&(n.name=i.name),$C(n,i),t.associations.set(n,{materials:e}),i.extensions&&QC(r,n,i),n})}createUniqueName(e){let t=Vu.sanitizeNodeName(e||``);return t in this.nodeNamesUsed?t+`_`+ ++this.nodeNamesUsed[t]:(this.nodeNamesUsed[t]=0,t)}loadGeometries(e){let t=this,n=this.extensions,r=this.primitiveCache;function i(e){return n[pC.KHR_DRACO_MESH_COMPRESSION].decodePrimitive(e,t).then(function(n){return lw(n,e,t)})}let a=[];for(let n=0,o=e.length;n<o;n++){let o=e[n],s=nw(o),c=r[s];if(c)a.push(c.promise);else{let e;e=o.extensions&&o.extensions[pC.KHR_DRACO_MESH_COMPRESSION]?i(o):lw(new J,o,t),r[s]={primitive:o,promise:e},a.push(e)}}return Promise.all(a)}loadMesh(e){let t=this,n=this.json,r=this.extensions,i=n.meshes[e],a=i.primitives,o=[];for(let e=0,t=a.length;e<t;e++){let t=a[e].material===void 0?ZC(this.cache):this.getDependency(`material`,a[e].material);o.push(t)}return o.push(t.loadGeometries(a)),Promise.all(o).then(function(n){let o=n.slice(0,n.length-1),s=n[n.length-1],c=[];for(let n=0,l=s.length;n<l;n++){let l=s[n],u=a[n],d,f=o[n];if(u.mode===HC.TRIANGLES||u.mode===HC.TRIANGLE_STRIP||u.mode===HC.TRIANGLE_FAN||u.mode===void 0)d=i.isSkinnedMesh===!0?new sc(l,f):new Ys(l,f),d.isSkinnedMesh===!0&&d.normalizeSkinWeights(),u.mode===HC.TRIANGLE_STRIP?d.geometry=sC(d.geometry,1):u.mode===HC.TRIANGLE_FAN&&(d.geometry=sC(d.geometry,2));else if(u.mode===HC.LINES)d=new Hc(l,f);else if(u.mode===HC.LINE_STRIP)d=new Rc(l,f);else if(u.mode===HC.LINE_LOOP)d=new Uc(l,f);else if(u.mode===HC.POINTS)d=new Yc(l,f);else throw Error(`THREE.GLTFLoader: Primitive mode unsupported: `+u.mode);Object.keys(d.geometry.morphAttributes).length>0&&tw(d,i),d.name=t.createUniqueName(i.name||`mesh_`+e),$C(d,i),u.extensions&&QC(r,d,u),t.assignFinalMaterial(d),c.push(d)}for(let n=0,r=c.length;n<r;n++)t.associations.set(c[n],{meshes:e,primitives:n});if(c.length===1)return i.extensions&&QC(r,c[0],i),c[0];let l=new _o;i.extensions&&QC(r,l,i),t.associations.set(l,{meshes:e});for(let e=0,t=c.length;e<t;e++)l.add(c[e]);return l})}loadCamera(e){let t,n=this.json.cameras[e],r=n[n.type];if(!r){console.warn(`THREE.GLTFLoader: Missing camera parameters.`);return}return n.type===`perspective`?t=new pu(ba.radToDeg(r.yfov),r.aspectRatio||1,r.znear||1,r.zfar||2e6):n.type===`orthographic`&&(t=new vu(-r.xmag,r.xmag,r.ymag,-r.ymag,r.znear,r.zfar)),n.name&&(t.name=this.createUniqueName(n.name)),$C(t,n),Promise.resolve(t)}loadSkin(e){let t=this.json.skins[e],n=[];for(let e=0,r=t.joints.length;e<r;e++)n.push(this._loadNodeShallow(t.joints[e]));return t.inverseBindMatrices===void 0?n.push(null):n.push(this.getDependency(`accessor`,t.inverseBindMatrices)),Promise.all(n).then(function(e){let n=e.pop(),r=e,i=[],a=[];for(let e=0,o=r.length;e<o;e++){let o=r[e];if(o){i.push(o);let t=new G;n!==null&&t.fromArray(n.array,e*16),a.push(t)}else console.warn(`THREE.GLTFLoader: Joint "%s" could not be found.`,t.joints[e])}return new fc(i,a)})}loadAnimation(e){let t=this.json,n=this,r=t.animations[e],i=r.name?r.name:`animation_`+e,a=[],o=[],s=[],c=[],l=[];for(let e=0,t=r.channels.length;e<t;e++){let t=r.channels[e],n=r.samplers[t.sampler],i=t.target,u=i.node,d=r.parameters===void 0?n.input:r.parameters[n.input],f=r.parameters===void 0?n.output:r.parameters[n.output];i.node!==void 0&&(a.push(this.getDependency(`node`,u)),o.push(this.getDependency(`accessor`,d)),s.push(this.getDependency(`accessor`,f)),c.push(n),l.push(i))}return Promise.all([Promise.all(a),Promise.all(o),Promise.all(s),Promise.all(c),Promise.all(l)]).then(function(e){let t=e[0],a=e[1],o=e[2],s=e[3],c=e[4],l=[];for(let e=0,r=t.length;e<r;e++){let r=t[e],i=a[e],u=o[e],d=s[e],f=c[e];if(r===void 0)continue;r.updateMatrix&&r.updateMatrix();let p=n._createAnimationTracks(r,i,u,d,f);if(p)for(let e=0;e<p.length;e++)l.push(p[e])}let u=new Vl(i,void 0,l);return $C(u,r),u})}createNodeMesh(e){let t=this.json,n=this,r=t.nodes[e];return r.mesh===void 0?null:n.getDependency(`mesh`,r.mesh).then(function(e){let t=n._getNodeRef(n.meshCache,r.mesh,e);return r.weights!==void 0&&t.traverse(function(e){if(e.isMesh)for(let t=0,n=r.weights.length;t<n;t++)e.morphTargetInfluences[t]=r.weights[t]}),t})}loadNode(e){let t=this.json,n=this,r=t.nodes[e],i=n._loadNodeShallow(e),a=[],o=r.children||[];for(let e=0,t=o.length;e<t;e++)a.push(n.getDependency(`node`,o[e]));let s=r.skin===void 0?Promise.resolve(null):n.getDependency(`skin`,r.skin);return Promise.all([i,Promise.all(a),s]).then(function(e){let t=e[0],n=e[1],r=e[2];r!==null&&t.traverse(function(e){e.isSkinnedMesh&&e.bind(r,ow)});for(let e=0,r=n.length;e<r;e++)t.add(n[e]);if(t.userData.pivot!==void 0&&n.length>0){let e=t.userData.pivot,r=n[0];t.pivot=new U().fromArray(e),t.position.x-=e[0],t.position.y-=e[1],t.position.z-=e[2],r.position.set(0,0,0),delete t.userData.pivot}return t})}_loadNodeShallow(e){let t=this.json,n=this.extensions,r=this;if(this.nodeCache[e]!==void 0)return this.nodeCache[e];let i=t.nodes[e],a=i.name?r.createUniqueName(i.name):``,o=[],s=r._invokeOne(function(t){return t.createNodeMesh&&t.createNodeMesh(e)});return s&&o.push(s),i.camera!==void 0&&o.push(r.getDependency(`camera`,i.camera).then(function(e){return r._getNodeRef(r.cameraCache,i.camera,e)})),r._invokeAll(function(t){return t.createNodeAttachment&&t.createNodeAttachment(e)}).forEach(function(e){o.push(e)}),this.nodeCache[e]=Promise.all(o).then(function(t){let o;if(o=i.isBone===!0?new cc:t.length>1?new _o:t.length===1?t[0]:new go,o!==t[0])for(let e=0,n=t.length;e<n;e++)o.add(t[e]);if(i.name&&(o.userData.name=i.name,o.name=a),$C(o,i),i.extensions&&QC(n,o,i),i.matrix!==void 0){let e=new G;e.fromArray(i.matrix),o.applyMatrix4(e)}else i.translation!==void 0&&o.position.fromArray(i.translation),i.rotation!==void 0&&o.quaternion.fromArray(i.rotation),i.scale!==void 0&&o.scale.fromArray(i.scale);if(!r.associations.has(o))r.associations.set(o,{});else if(i.mesh!==void 0&&r.meshCache.refs[i.mesh]>1){let e=r.associations.get(o);r.associations.set(o,{...e})}return r.associations.get(o).nodes=e,o}),this.nodeCache[e]}loadScene(e){let t=this.extensions,n=this.json.scenes[e],r=this,i=new _o;n.name&&(i.name=r.createUniqueName(n.name)),$C(i,n),n.extensions&&QC(t,i,n);let a=n.nodes||[],o=[];for(let e=0,t=a.length;e<t;e++)o.push(r.getDependency(`node`,a[e]));return Promise.all(o).then(function(e){for(let t=0,n=e.length;t<n;t++){let n=e[t];n.parent===null?i.add(n):i.add(cC(n))}return r.associations=(e=>{let t=new Map;for(let[e,n]of r.associations)(e instanceof Os||e instanceof La)&&t.set(e,n);return e.traverse(e=>{let n=r.associations.get(e);n!=null&&t.set(e,n)}),t})(i),i})}_createAnimationTracks(e,t,n,r,i){let a=[],o=e.name?e.name:e.uuid,s=[];function c(e){e.morphTargetInfluences&&s.push(e.name?e.name:e.uuid)}JC[i.path]===JC.weights?(c(e),e.isGroup&&e.children.forEach(c)):s.push(o);let l;switch(JC[i.path]){case JC.weights:l=Il;break;case JC.rotation:l=Rl;break;case JC.translation:case JC.scale:l=Bl;break;default:switch(n.itemSize){case 1:l=Il;break;default:l=Bl;break}break}let u=r.interpolation===void 0?vi:YC[r.interpolation],d=this._getArrayFromAccessor(n);for(let e=0,n=s.length;e<n;e++){let n=new l(s[e]+`.`+JC[i.path],t.array,d,u);r.interpolation===`CUBICSPLINE`&&this._createCubicSplineTrackInterpolant(n),a.push(n)}return a}_getArrayFromAccessor(e){let t=e.array;if(e.normalized){let e=iw(t.constructor),n=new Float32Array(t.length);for(let r=0,i=t.length;r<i;r++)n[r]=t[r]*e;t=n}return t}_createCubicSplineTrackInterpolant(e){e.createInterpolant=function(e){return new(this instanceof Rl?VC:zC)(this.times,this.values,this.getValueSize()/3,e)},e.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline=!0}};function cw(e,t,n){let r=t.attributes,i=new Vo;if(r.POSITION!==void 0){let e=n.json.accessors[r.POSITION],t=e.min,a=e.max;if(t!==void 0&&a!==void 0){if(i.set(new U(t[0],t[1],t[2]),new U(a[0],a[1],a[2])),e.normalized){let t=iw(UC[e.componentType]);i.min.multiplyScalar(t),i.max.multiplyScalar(t)}}else{console.warn(`THREE.GLTFLoader: Missing min/max properties for accessor POSITION.`);return}}else return;let a=t.targets;if(a!==void 0){let e=new U,t=new U;for(let r=0,i=a.length;r<i;r++){let i=a[r];if(i.POSITION!==void 0){let r=n.json.accessors[i.POSITION],a=r.min,o=r.max;if(a!==void 0&&o!==void 0){if(t.setX(Math.max(Math.abs(a[0]),Math.abs(o[0]))),t.setY(Math.max(Math.abs(a[1]),Math.abs(o[1]))),t.setZ(Math.max(Math.abs(a[2]),Math.abs(o[2]))),r.normalized){let e=iw(UC[r.componentType]);t.multiplyScalar(e)}e.max(t)}else console.warn(`THREE.GLTFLoader: Missing min/max properties for accessor POSITION.`)}}i.expandByVector(e)}e.boundingBox=i;let o=new gs;i.getCenter(o.center),o.radius=i.min.distanceTo(i.max)/2,e.boundingSphere=o}function lw(e,t,n){let r=t.attributes,i=[];function a(t,r){return n.getDependency(`accessor`,t).then(function(t){e.setAttribute(r,t)})}for(let t in r){let n=qC[t]||t.toLowerCase();n in e.attributes||i.push(a(r[t],n))}if(t.indices!==void 0&&!e.index){let r=n.getDependency(`accessor`,t.indices).then(function(t){e.setIndex(t)});i.push(r)}return Da.workingColorSpace!==`srgb-linear`&&`COLOR_0`in r&&console.warn(`THREE.GLTFLoader: Converting vertex colors from "srgb-linear" to "${Da.workingColorSpace}" not supported.`),$C(e,t),cw(e,t,n),Promise.all(i).then(function(){return t.targets===void 0?e:ew(e,t.targets,n)})}var uw=(e,t)=>new eu().load(e,void 0,void 0,t);function dw(e,t){return[e,t?.colorSpace??`srgb`,t?.filter??`linear`,t?.wrap??`clamp`,String(t?.anisotropy??1),t?.process?.id??``].join(`|`)}function fw(e,t){e.colorSpace=(t?.colorSpace??`srgb`)===`srgb`?Oi:``;let n=t?.filter===`nearest`;e.magFilter=n?rr:or,e.generateMipmaps=!n,e.minFilter=n?rr:cr;let r=t?.wrap===`repeat`?er:tr;e.wrapS=r,e.wrapT=r,t?.anisotropy&&(e.anisotropy=t.anisotropy)}var pw=class{entries=new Map;load;diagnostics;constructor(e){this.load=e?.loader??uw,this.diagnostics=e?.diagnostics??null}acquire(e,t){if(e===``||typeof document>`u`&&this.load===uw)return null;let n=dw(e,t),r=this.entries.get(n);if(r)return r.texture;let i={url:e,texture:null,error:null};return i.texture=this.load(e,t=>{i.error=t instanceof Error?t.message:String(t),this.diagnostics?.warn(`texture failed to load: ${e} — ${i.error}`)}),fw(i.texture,t),t?.process?.run(i.texture),this.entries.set(n,i),i.texture}acquireOwn(e,t){let n=this.acquire(e,t);return n?n.clone():null}errors(){let e=[];for(let t of this.entries.values())t.error!==null&&e.push({url:t.url,error:t.error});return e}size(){return this.entries.size}dispose(){for(let e of this.entries.values())e.texture.dispose();this.entries.clear()}};function mw(e,t,n){return e?e.textures.acquire(t,n):gw().acquire(t,n)}function hw(e,t,n){return e?e.textures.acquireOwn(t,n):gw().acquireOwn(t,n)}function gw(){return new pw}var _w=class{engine;models=new Map;animations=new Map;modelKeys=new Map;animationKeys=new Map;loader;textures;constructor(e=null){this.engine=e,this.loader=new uC,this.loader.register(e=>new AS(e)),this.textures=new pw({diagnostics:e?{warn:(...t)=>lt(e,`warn`,...t)}:null})}errors(){let e=[];for(let{url:t,error:n}of this.textures.errors())e.push({ref:t,url:t,error:n});for(let[t,n]of this.modelKeys){let r=this.models.get(n);r?.error&&e.push({ref:t,url:n,error:String(r.error)})}for(let[t,n]of this.animationKeys){let r=this.animations.get(n.url);r?.error&&e.push({ref:t,url:n.url,error:String(r.error)})}return e}load(e){for(let[t,n]of Object.entries(e)){let e=n;typeof e.url==`string`&&(e.type===`model`?this.modelKeys.set(`$${t}`,e.url):e.type===`animation`&&this.animationKeys.set(`$${t}`,{url:e.url,clip:e.clip}))}}animationRefs(){return[...this.animationKeys.keys()]}modelRefs(){return[...this.modelKeys.keys()]}getModel(e){let t=this.modelKeys.get(e)??e,n=this.models.get(t);return n||(n={status:`loading`,scene:null,animations:[],isVrm:!1,vrm:null,claimedBy:null,retargeted:new Map},this.models.set(t,n),this.loader.load(t,e=>{let t=e.userData.vrm;t?(oC.removeUnnecessaryVertices(e.scene),oC.combineSkeletons(e.scene),oC.rotateVRM0(t),n.scene=t.scene,n.vrm=t,n.isVrm=!0):n.scene=e.scene,n.animations=e.animations??[],n.status=`ready`},void 0,e=>{n.status=`error`,n.error=e instanceof Error?e.message:String(e),lt(this.engine,`error`,`incanto: failed to load model '${t}':`,e)}),n)}getAnimation(e){let t=this.animationKeys.get(e)??{url:e},n=this.animations.get(t.url);return n||(n={status:`loading`,clips:[],scene:null,clip:t.clip},this.animations.set(t.url,n),this.loader.load(t.url,e=>{n.clips=e.animations??[],n.scene=e.scene,n.status=`ready`,n.clips.length===0&<(this.engine,`warn`,`incanto: animation asset '${t.url}' contains no clips`)},void 0,e=>{n.status=`error`,n.error=e instanceof Error?e.message:String(e),lt(this.engine,`error`,`incanto: failed to load animation '${t.url}':`,e)}),n)}dispose(){this.textures.dispose();for(let e of this.models.values())e.scene?.traverse(e=>{let t=e;t.geometry?.dispose();let n=Array.isArray(t.material)?t.material:[t.material];for(let e of n)if(e){for(let t of Object.values(e))t?.isTexture&&t.dispose();e.dispose()}});this.models.clear(),this.animations.clear()}},vw=Math.atan(1/Math.SQRT2);function yw(e,t,n,r,i,a){let o=[t[0],t[1]+n,t[2]];if(e===`firstPerson`)return{position:o,rotation:[-i,r,0]};if(e===`quarter`){let e=vw;return{position:[o[0],o[1]+a*Math.sin(e),o[2]+a*Math.cos(e)],rotation:[-e,0,0]}}if(e===`side`)return{position:[o[0],o[1],o[2]+a],rotation:[0,0,0]};let s=Math.cos(i);return{position:[o[0]+Math.sin(r)*s*a,o[1]+Math.sin(i)*a,o[2]+Math.cos(r)*s*a],rotation:[-i,r,0]}}function bw(e,t,n,r,i){let a=t[0]-e[0],o=t[1]-e[1],s=t[2]-e[2],c=Math.hypot(a,o,s);if(c<1e-4)return[t[0],t[1],t[2]];let l=[a/c,o/c,s/c],u=n(e,l,c);if(u===null)return[t[0],t[1],t[2]];let d=Math.min(c,Math.max(i,u-r));return[e[0]+l[0]*d,e[1]+l[1]*d,e[2]+l[2]*d]}function xw(e,t,n){let r=t(e,n);return r===null||r>=n?[e[0],e[1],e[2]]:[e[0],e[1]+(n-r),e[2]]}function Sw(e,t,n){let r=Math.sin(n),i=Math.cos(n);return[e*i-t*r,0,-e*r-t*i]}function Cw(e,t){return e?Math.min(.6+(t?.4:0),1):0}function ww(e,t){return e?t<=0?`idle`:t<.3?`walk`:t<.7?`run`:`fastRun`:`airborne`}var Tw=[`color`,`metalness`,`roughness`,`emissive`,`emissiveIntensity`,`wireframe`,`flatShading`,`opacity`,`clearcoat`,`clearcoatRoughness`,`envMapIntensity`,`depthTest`,`depthWrite`,`map`,`normalMap`,`repeat`],Ew=class extends Oh{static typeName=`MeshInstance3D`;static props={mesh:{default:`box`,options:[`box`,`sphere`,`capsule`,`plane`,`cylinder`,`gem`]},size:{default:[1,1,1]},material:{default:{}},castShadow:{default:!1},receiveShadow:{default:!1}};mesh=`box`;size=[1,1,1];material={};castShadow=!1;receiveShadow=!1;static validateJson(e){Ow(e.material,e.name)}geometryKey=``;textureKey=``;loadedTextures=[];_createObject3D(){return new Ys(new nl(1,1,1),new xl)}_syncObject3D(e=1,t=null){super._syncObject3D(e,t);let n=this._ensureObject3D(),r=`${this.mesh}:${JSON.stringify(this.size)}`;r!==this.geometryKey&&(n.geometry.dispose(),n.geometry=kw(this.mesh,this.size),this.geometryKey=r);let i=n.material;Dw(i,this.material),this.syncTextures(i,t),n.castShadow=this.castShadow,n.receiveShadow=this.receiveShadow}syncTextures(e,t){let n=JSON.stringify([this.material.map??``,this.material.normalMap??``,this.material.repeat??null]);if(n===this.textureKey)return;this.textureKey=n;for(let e of this.loadedTextures)e.dispose();this.loadedTextures=[];let r=e.map!==null||e.normalMap!==null;e.map=null,e.normalMap=null,this.material.map&&(e.map=this.loadTexture(t,this.material.map,!0)),this.material.normalMap&&(e.normalMap=this.loadTexture(t,this.material.normalMap,!1)),(r||e.map||e.normalMap)&&(e.needsUpdate=!0)}loadTexture(e,t,n){let r=hw(e,t,{wrap:`repeat`,anisotropy:4,colorSpace:n?`srgb`:`linear`});if(!r)return null;let[i,a]=this.material.repeat??[1,1];return r.repeat.set(i,a),this.loadedTextures.push(r),r}free(){for(let e of this.loadedTextures)e.dispose();this.loadedTextures=[];let e=this._builtObject3D;if(e){e.geometry?.dispose();let t=Array.isArray(e.material)?e.material:[e.material];for(let e of t)e?.dispose()}super.free()}};function Dw(e,t){e.color.set(t.color??`#ffffff`),e.metalness=t.metalness??0,e.roughness=t.roughness??1,e.wireframe=t.wireframe??!1,e.emissive.set(t.emissive??`#000000`),e.emissiveIntensity=t.emissiveIntensity??1;let n=t.opacity??1;e.opacity=n,e.transparent=n<1;let r=t.clearcoat??0;e.clearcoat>0!=r>0&&(e.needsUpdate=!0),e.clearcoat=r,e.clearcoatRoughness=t.clearcoatRoughness??0,e.envMapIntensity=t.envMapIntensity??1,e.depthTest=t.depthTest??!0,e.depthWrite=t.depthWrite??!0;let i=t.flatShading??!1;e.flatShading!==i&&(e.flatShading=i,e.needsUpdate=!0)}function Ow(e,t,n=`MeshInstance3D`){let r=e=>{throw new N(`BAD_FORMAT`,`${n} '${t}' ${e}`,{prop:`material`,validOptions:[...Tw]})};(typeof e!=`object`||!e||Array.isArray(e))&&r(`material must be an object, got ${JSON.stringify(e)}.`);for(let t of Object.keys(e))Tw.includes(t)||r(`material has unknown key '${t}' — must be one of [${Tw.join(`, `)}].`);for(let t of[`map`,`normalMap`]){let n=e[t];n!==void 0&&(typeof n!=`string`||n.length===0)&&r(`material.${t} must be a non-empty texture URL string, got ${JSON.stringify(n)}.`)}if(e.repeat!==void 0){let t=e.repeat;(!Array.isArray(t)||t.length!==2||!t.every(e=>typeof e==`number`&&Number.isFinite(e)&&e>0))&&r(`material.repeat must be [u, v] with positive numbers, got ${JSON.stringify(t)}.`),!e.map&&!e.normalMap&&r(`material.repeat tiles nothing — add a 'map' and/or 'normalMap' texture URL.`)}for(let t of[`metalness`,`roughness`,`opacity`,`clearcoat`,`clearcoatRoughness`]){let n=e[t];n!==void 0&&!(typeof n==`number`&&n>=0&&n<=1)&&r(`material.${t} must be a number in 0..1, got ${JSON.stringify(n)}.`)}e.envMapIntensity!==void 0&&!(typeof e.envMapIntensity==`number`&&Number.isFinite(e.envMapIntensity)&&e.envMapIntensity>=0)&&r(`material.envMapIntensity must be a number >= 0, got ${JSON.stringify(e.envMapIntensity)}.`);for(let t of[`wireframe`,`flatShading`,`depthTest`,`depthWrite`]){let n=e[t];n!==void 0&&typeof n!=`boolean`&&r(`material.${t} must be a boolean, got ${JSON.stringify(n)}.`)}}function kw(e,t){let n=t[0]??1,r=t[1]??1,i=t[2]??1;switch(e){case`box`:return new nl(n,r,i);case`sphere`:return new ll(n,32,16);case`gem`:return new sl(n,0);case`capsule`:return new rl(n,r,8,16);case`plane`:{let e=new cl(n,i);return e.rotateX(-Math.PI/2),e}case`cylinder`:return new il(n,n,r,24);default:throw new N(`PROP_TYPE_MISMATCH`,`MeshInstance3D.mesh must be one of box|sphere|capsule|plane|cylinder|gem, got '${e}'.`)}}var Aw=class extends Oh{static typeName=`InstancedMesh3D`;static props={mesh:{default:`box`,options:[`box`,`sphere`,`capsule`,`plane`,`cylinder`,`gem`]},size:{default:[1,1,1]},material:{default:{}},transforms:{default:[]},castShadow:{default:!1},receiveShadow:{default:!1},collider:{default:null}};mesh=`box`;size=[1,1,1];material={};castShadow=!1;receiveShadow=!1;collider=null;_transforms=[];transformsDirty=!0;get transforms(){return this._transforms}set transforms(e){this._transforms=e,this.transformsDirty=!0}instanced=null;builtKey=``;static validateJson(e){let t=e;Ow(t.material,e.name);for(let[n,r]of t._transforms.entries())if(!Array.isArray(r)||r.length<3||r.length>5||r.some(e=>typeof e!=`number`))throw new N(`BAD_FORMAT`,`InstancedMesh3D '${e.name}': transforms[${n}] must be [x, y, z, yawDeg?, scale?] (numbers), got ${JSON.stringify(r)}.`)}get instanceCount(){return this.instanced?.count??0}_syncObject3D(e){super._syncObject3D(e);let t=this._ensureObject3D(),n=`${this.mesh} ${JSON.stringify(this.size)} ${this._transforms.length}`;if(n!==this.builtKey){if(this.builtKey=n,this.instanced&&=(t.remove(this.instanced),this.instanced.geometry.dispose(),this.instanced.material.dispose(),null),this._transforms.length>0){let e=kw(this.mesh,this.size),n=new xl;this.instanced=new xc(e,n,this._transforms.length),this.instanced.instanceMatrix.setUsage(Pi),t.add(this.instanced)}this.transformsDirty=!0}let r=this.instanced;if(r&&(r.castShadow=this.castShadow,r.receiveShadow=this.receiveShadow,Dw(r.material,this.material),this.transformsDirty)){this.transformsDirty=!1;for(let e=0;e<this._transforms.length;e++){let t=this._transforms[e];Mw.set(t[0]??0,t[1]??0,t[2]??0),Nw.setFromAxisAngle(jw,(t[3]??0)*Math.PI/180);let n=t[4]??1;Pw.set(n,n,n),Fw.compose(Mw,Nw,Pw),r.setMatrixAt(e,Fw)}r.instanceMatrix.needsUpdate=!0,r.computeBoundingSphere()}}free(){this.instanced&&(this.instanced.geometry.dispose(),this.instanced.material.dispose()),super.free()}},jw=new U(0,1,0),Mw=new U,Nw=new H,Pw=new U,Fw=new G,Iw=class extends Oh{static typeName=`Joint3D`;static props={type:{default:`spherical`,options:[`fixed`,`spherical`,`rope`,`spring`]},target:{default:``,nodePath:!0},anchor:{default:[0,0,0]},targetAnchor:{default:[0,0,0]},length:{default:0},stiffness:{default:50},damping:{default:5}};type=`spherical`;target=``;anchor=[0,0,0];targetAnchor=[0,0,0];length=0;stiffness=50;damping=5;onEnterTree(){if(!(this.parent instanceof kh))throw new N(`TREE_VIOLATION`,`Joint3D '${this.name}' must be a child of a physics body (its body A); parent is '${this.parent?.name??`none`}'.`);if(this.target===``)throw new N(`BAD_FORMAT`,`Joint3D '${this.name}' needs a "target" node path to the body it links to.`)}_resolveBodies(){let e=this.parent,t=this.getNodeOrNull(this.target);if(!(t instanceof kh))throw new N(`NODE_NOT_FOUND`,`Joint3D '${this.name}': target '${this.target}' is not a physics body.`);return{a:e,b:t}}},Lw=256,Rw=.3,zw=.6,Bw=45;function Vw(e){let{width:t,depth:n,segsX:r,segsZ:i,maxHeight:a,seed:o}=e,s=e.roughness??.5,c=e.detail??4,l=e.flatThreshold??.95,u=e.islandEdge??!1,d=Math.max(0,Math.min(e.edgeWrapRadius??20,Bw)),f=e.edgeBottom??-50,p=e.edgeCornerSmoothness??1,m=(e.basins??[]).map(e=>({cx:e.x+t/2,cz:e.z+n/2,radius:e.radius,depth:e.depth})),h=(e.channels??[]).map(e=>({half:Math.max(e.width,0)/2,taper:Math.max(e.taper??e.width,.001),depth:e.depth,segs:e.path.map(e=>({x:(e[0]??0)+t/2,z:(e[1]??0)+n/2})).flatMap((e,t,n)=>t===0?[]:[{ax:n[t-1].x,az:n[t-1].z,bx:e.x,bz:e.z}])})).filter(e=>e.segs.length>0&&e.depth!==0),g=dn(o),_=(e,t)=>(g(e,t)+1)*.5,v=(e,t)=>{let n=e/Lw,r=t/Lw,i=0,o=.2,u=5;for(let e=0;e<5;e++)i+=_(n*o,r*o)*u,u*=.5,o*=2;let d=0;o=.5,u=.1;for(let e=0;e<c;e++)d+=_(n*o,r*o)*u,u*=s,o*=2;i=Math.abs(i)**1.5*Math.sign(i),i<Rw&&(i*=.3);let f=a*(i+d*(i*.5+.5)+1)/2,p=a*l;if(Math.abs(f-p)<zw&&(f=p),m.length>0){let n=0,r=0;for(let i of m){let a=Math.hypot(e-i.cx,t-i.cz);if(a<i.radius){let e=a/i.radius,t=1-e*e*(3-2*e);i.depth>=0?n=Math.max(n,i.depth*t):r=Math.max(r,-i.depth*t)}}f+=r-n}if(h.length>0){let n=0;for(let r of h){let i=1/0;for(let n of r.segs){let a=n.bx-n.ax,o=n.bz-n.az,s=a*a+o*o,c=s>1e-9?Math.min(1,Math.max(0,((e-n.ax)*a+(t-n.az)*o)/s)):0,l=n.ax+a*c,u=n.az+o*c,d=Math.hypot(e-l,t-u);if(d<i&&(i=d),i<=r.half)break}if(i>=r.half+r.taper)continue;let a=Math.min(1,Math.max(0,(i-r.half)/r.taper));n=Math.max(n,r.depth*(1-a*a*(3-2*a)))}f-=n}return f},y=(e,a,o)=>{if(!u||d<=0)return o;let s=d,c=Math.min(e,t-e),l=Math.min(a,n-a),m=(t/r+n/i)*.002,h=Math.max(0,s-c+m),g=Math.max(0,s-l+m);if(h<=0&&g<=0)return o;let _=2+(1-Math.min(1,Math.max(0,p)))*30,v=(h**_+g**_)**(1/_),y=o-(s-Math.sqrt(Math.max(0,s*s-v*v)));return v>=s&&(y=Math.min(y,f)),y},b=r+1,x=i+1,S=new Float32Array(b*x),C=1/0,w=-1/0;for(let e=0;e<x;e++){let a=e/i*n;for(let n=0;n<b;n++){let i=n/r*t,o=v(i,a);o<C&&(C=o),o>w&&(w=o),S[e*b+n]=y(i,a,o)}}let T=(e,a)=>{let o=Math.min(Math.max((e+t/2)/t*r,0),r),s=Math.min(Math.max((a+n/2)/n*i,0),i),c=Math.min(Math.floor(o),r-1),l=Math.min(Math.floor(s),i-1),u=o-c,d=s-l,f=S[l*b+c],p=S[l*b+c+1],m=S[(l+1)*b+c],h=S[(l+1)*b+c+1];return(f*(1-u)+p*u)*(1-d)+(m*(1-u)+h*u)*d},E=(e,r)=>v(e+t/2,r+n/2);return{width:t,depth:n,segsX:r,segsZ:i,heights:S,minHeight:C,maxHeight:w,heightAt:T,baseHeight:E,slopeAt:(e,t)=>{let n=(E(e+1,t)-E(e-1,t))/2,r=(E(e,t+1)-E(e,t-1))/2;return Math.atan(Math.sqrt(n*n+r*r))}}}function Hw(e,t,n,r){return e<t-r||e>n+r?0:e>=t&&e<=n?1:e<t?(e-(t-r))/r:(n+r-e)/r}function Uw(e,t,n,r=1.2){let i=[0,0,0,0],a=Math.min(n.length,4),o=0;for(let s=0;s<a;s++){let a=n[s],[c,l]=a.heightRange??[0,1],[u,d]=a.slopeRange??[0,Math.PI/2],f=Hw(e,c,l,a.heightBlendRange??.1)*Hw(t,u,d,a.slopeBlendRange??.1);f**=1/r,i[s]=f,o+=f}if(o===0)return[1,0,0,0];for(let e=0;e<4;e++)i[e]=i[e]/o;return i}function Ww(e,t,n){let r=e.indexOf(t);if(r===-1)throw new N(`BAD_FORMAT`,`Terrain3D shader patch: marker '${t}' not found in the three.js shader — the installed three version moved its chunks.`);let i=r+t.length;return`${e.slice(0,i)}\n${n}${e.slice(i)}`}var Gw=`
|
|
6689
|
+
`;e.vertexShader=t+e.vertexShader,e.fragmentShader=t+e.fragmentShader}}get color(){return this.uniforms.litFactor.value}set color(e){this.uniforms.litFactor.value=e}get map(){return this.uniforms.map.value}set map(e){this.uniforms.map.value=e}get normalMap(){return this.uniforms.normalMap.value}set normalMap(e){this.uniforms.normalMap.value=e}get normalScale(){return this.uniforms.normalScale.value}set normalScale(e){this.uniforms.normalScale.value=e}get emissive(){return this.uniforms.emissive.value}set emissive(e){this.uniforms.emissive.value=e}get emissiveIntensity(){return this.uniforms.emissiveIntensity.value}set emissiveIntensity(e){this.uniforms.emissiveIntensity.value=e}get emissiveMap(){return this.uniforms.emissiveMap.value}set emissiveMap(e){this.uniforms.emissiveMap.value=e}get shadeColorFactor(){return this.uniforms.shadeColorFactor.value}set shadeColorFactor(e){this.uniforms.shadeColorFactor.value=e}get shadeMultiplyTexture(){return this.uniforms.shadeMultiplyTexture.value}set shadeMultiplyTexture(e){this.uniforms.shadeMultiplyTexture.value=e}get shadingShiftFactor(){return this.uniforms.shadingShiftFactor.value}set shadingShiftFactor(e){this.uniforms.shadingShiftFactor.value=e}get shadingShiftTexture(){return this.uniforms.shadingShiftTexture.value}set shadingShiftTexture(e){this.uniforms.shadingShiftTexture.value=e}get shadingShiftTextureScale(){return this.uniforms.shadingShiftTextureScale.value}set shadingShiftTextureScale(e){this.uniforms.shadingShiftTextureScale.value=e}get shadingToonyFactor(){return this.uniforms.shadingToonyFactor.value}set shadingToonyFactor(e){this.uniforms.shadingToonyFactor.value=e}get giEqualizationFactor(){return this.uniforms.giEqualizationFactor.value}set giEqualizationFactor(e){this.uniforms.giEqualizationFactor.value=e}get matcapFactor(){return this.uniforms.matcapFactor.value}set matcapFactor(e){this.uniforms.matcapFactor.value=e}get matcapTexture(){return this.uniforms.matcapTexture.value}set matcapTexture(e){this.uniforms.matcapTexture.value=e}get parametricRimColorFactor(){return this.uniforms.parametricRimColorFactor.value}set parametricRimColorFactor(e){this.uniforms.parametricRimColorFactor.value=e}get rimMultiplyTexture(){return this.uniforms.rimMultiplyTexture.value}set rimMultiplyTexture(e){this.uniforms.rimMultiplyTexture.value=e}get rimLightingMixFactor(){return this.uniforms.rimLightingMixFactor.value}set rimLightingMixFactor(e){this.uniforms.rimLightingMixFactor.value=e}get parametricRimFresnelPowerFactor(){return this.uniforms.parametricRimFresnelPowerFactor.value}set parametricRimFresnelPowerFactor(e){this.uniforms.parametricRimFresnelPowerFactor.value=e}get parametricRimLiftFactor(){return this.uniforms.parametricRimLiftFactor.value}set parametricRimLiftFactor(e){this.uniforms.parametricRimLiftFactor.value=e}get outlineWidthMultiplyTexture(){return this.uniforms.outlineWidthMultiplyTexture.value}set outlineWidthMultiplyTexture(e){this.uniforms.outlineWidthMultiplyTexture.value=e}get outlineWidthFactor(){return this.uniforms.outlineWidthFactor.value}set outlineWidthFactor(e){this.uniforms.outlineWidthFactor.value=e}get outlineColorFactor(){return this.uniforms.outlineColorFactor.value}set outlineColorFactor(e){this.uniforms.outlineColorFactor.value=e}get outlineLightingMixFactor(){return this.uniforms.outlineLightingMixFactor.value}set outlineLightingMixFactor(e){this.uniforms.outlineLightingMixFactor.value=e}get uvAnimationMaskTexture(){return this.uniforms.uvAnimationMaskTexture.value}set uvAnimationMaskTexture(e){this.uniforms.uvAnimationMaskTexture.value=e}get uvAnimationScrollXOffset(){return this.uniforms.uvAnimationScrollXOffset.value}set uvAnimationScrollXOffset(e){this.uniforms.uvAnimationScrollXOffset.value=e}get uvAnimationScrollYOffset(){return this.uniforms.uvAnimationScrollYOffset.value}set uvAnimationScrollYOffset(e){this.uniforms.uvAnimationScrollYOffset.value=e}get uvAnimationRotationPhase(){return this.uniforms.uvAnimationRotationPhase.value}set uvAnimationRotationPhase(e){this.uniforms.uvAnimationRotationPhase.value=e}get ignoreVertexColor(){return this._ignoreVertexColor}set ignoreVertexColor(e){this._ignoreVertexColor=e,this.needsUpdate=!0}get v0CompatShade(){return this._v0CompatShade}set v0CompatShade(e){this._v0CompatShade=e,this.needsUpdate=!0}get debugMode(){return this._debugMode}set debugMode(e){this._debugMode=e,this.needsUpdate=!0}get outlineWidthMode(){return this._outlineWidthMode}set outlineWidthMode(e){this._outlineWidthMode=e,this.needsUpdate=!0}get isOutline(){return this._isOutline}set isOutline(e){this._isOutline=e,this.needsUpdate=!0}get isMToonMaterial(){return!0}update(e){this._uploadUniformsWorkaround(),this._updateUVAnimation(e)}copy(e){return super.copy(e),this.map=e.map,this.normalMap=e.normalMap,this.emissiveMap=e.emissiveMap,this.shadeMultiplyTexture=e.shadeMultiplyTexture,this.shadingShiftTexture=e.shadingShiftTexture,this.matcapTexture=e.matcapTexture,this.rimMultiplyTexture=e.rimMultiplyTexture,this.outlineWidthMultiplyTexture=e.outlineWidthMultiplyTexture,this.uvAnimationMaskTexture=e.uvAnimationMaskTexture,this.normalMapType=e.normalMapType,this.uvAnimationScrollXSpeedFactor=e.uvAnimationScrollXSpeedFactor,this.uvAnimationScrollYSpeedFactor=e.uvAnimationScrollYSpeedFactor,this.uvAnimationRotationSpeedFactor=e.uvAnimationRotationSpeedFactor,this.ignoreVertexColor=e.ignoreVertexColor,this.v0CompatShade=e.v0CompatShade,this.debugMode=e.debugMode,this.outlineWidthMode=e.outlineWidthMode,this.isOutline=e.isOutline,this.needsUpdate=!0,this}_updateUVAnimation(e){this.uniforms.uvAnimationScrollXOffset.value+=e*this.uvAnimationScrollXSpeedFactor,this.uniforms.uvAnimationScrollYOffset.value+=e*this.uvAnimationScrollYSpeedFactor,this.uniforms.uvAnimationRotationPhase.value+=e*this.uvAnimationRotationSpeedFactor,this.uniforms.alphaTest.value=this.alphaTest,this.uniformsNeedUpdate=!0}_uploadUniformsWorkaround(){this.uniforms.opacity.value=this.opacity,this._updateTextureMatrix(this.uniforms.map,this.uniforms.mapUvTransform),this._updateTextureMatrix(this.uniforms.normalMap,this.uniforms.normalMapUvTransform),this._updateTextureMatrix(this.uniforms.emissiveMap,this.uniforms.emissiveMapUvTransform),this._updateTextureMatrix(this.uniforms.shadeMultiplyTexture,this.uniforms.shadeMultiplyTextureUvTransform),this._updateTextureMatrix(this.uniforms.shadingShiftTexture,this.uniforms.shadingShiftTextureUvTransform),this._updateTextureMatrix(this.uniforms.matcapTexture,this.uniforms.matcapTextureUvTransform),this._updateTextureMatrix(this.uniforms.rimMultiplyTexture,this.uniforms.rimMultiplyTextureUvTransform),this._updateTextureMatrix(this.uniforms.outlineWidthMultiplyTexture,this.uniforms.outlineWidthMultiplyTextureUvTransform),this._updateTextureMatrix(this.uniforms.uvAnimationMaskTexture,this.uniforms.uvAnimationMaskTextureUvTransform),this.uniformsNeedUpdate=!0}_generateDefines(){let e=this.outlineWidthMultiplyTexture!==null,t=this.map!==null||this.normalMap!==null||this.emissiveMap!==null||this.shadeMultiplyTexture!==null||this.shadingShiftTexture!==null||this.rimMultiplyTexture!==null||this.uvAnimationMaskTexture!==null;return{THREE_VRM_THREE_REVISION:184,OUTLINE:this._isOutline,MTOON_USE_UV:e||t,MTOON_UVS_VERTEX_ONLY:e&&!t,V0_COMPAT_SHADE:this._v0CompatShade,USE_SHADEMULTIPLYTEXTURE:this.shadeMultiplyTexture!==null,USE_SHADINGSHIFTTEXTURE:this.shadingShiftTexture!==null,USE_MATCAPTEXTURE:this.matcapTexture!==null,USE_RIMMULTIPLYTEXTURE:this.rimMultiplyTexture!==null,USE_OUTLINEWIDTHMULTIPLYTEXTURE:this._isOutline&&this.outlineWidthMultiplyTexture!==null,USE_UVANIMATIONMASKTEXTURE:this.uvAnimationMaskTexture!==null,IGNORE_VERTEX_COLOR:this._ignoreVertexColor===!0,DEBUG_NORMAL:this._debugMode===`normal`,DEBUG_LITSHADERATE:this._debugMode===`litShadeRate`,DEBUG_UV:this._debugMode===`uv`,OUTLINE_WIDTH_SCREEN:this._isOutline&&this._outlineWidthMode===Zb.ScreenCoordinates}}_updateTextureMatrix(e,t){e.value&&(e.value.matrixAutoUpdate&&e.value.updateMatrix(),t.value.copy(e.value.matrix))}},ex=new Set([`1.0`,`1.0-beta`]),tx=class e{get name(){return e.EXTENSION_NAME}constructor(e,t={}){this.parser=e,this.materialType=t.materialType??$b,this.renderOrderOffset=t.renderOrderOffset??0,this.v0CompatShade=t.v0CompatShade??!1,this.debugMode=t.debugMode??`none`,this._mToonMaterialSet=new Set}beforeRoot(){return Gb(this,null,function*(){this._removeUnlitExtensionIfMToonExists()})}afterRoot(e){return Gb(this,null,function*(){e.userData.vrmMToonMaterials=Array.from(this._mToonMaterialSet)})}getMaterialType(e){return this._getMToonExtension(e)?this.materialType:null}extendMaterialParams(e,t){let n=this._getMToonExtension(e);return n?this._extendMaterialParams(n,t):null}loadMesh(e){return Gb(this,null,function*(){let t=this.parser,n=t.json.meshes?.[e];if(n==null)throw Error(`MToonMaterialLoaderPlugin: Attempt to use meshes[${e}] of glTF but the mesh doesn't exist`);let r=n.primitives,i=yield t.loadMesh(e);if(r.length===1){let e=i,t=r[0].material;t!=null&&this._setupPrimitive(e,t)}else{let e=i;for(let t=0;t<r.length;t++){let n=e.children[t],i=r[t].material;i!=null&&this._setupPrimitive(n,i)}}return i})}_removeUnlitExtensionIfMToonExists(){this.parser.json.materials?.map((e,t)=>{this._getMToonExtension(t)&&e.extensions?.KHR_materials_unlit&&delete e.extensions.KHR_materials_unlit})}_getMToonExtension(t){let n=this.parser.json.materials?.[t];if(n==null){console.warn(`MToonMaterialLoaderPlugin: Attempt to use materials[${t}] of glTF but the material doesn't exist`);return}let r=n.extensions?.[e.EXTENSION_NAME];if(r==null)return;let i=r.specVersion;if(!ex.has(i)){console.warn(`MToonMaterialLoaderPlugin: Unknown ${e.EXTENSION_NAME} specVersion "${i}"`);return}return r}_extendMaterialParams(e,t){return Gb(this,null,function*(){delete t.metalness,delete t.roughness;let n=new qb(this.parser,t);n.assignPrimitive(`transparentWithZWrite`,e.transparentWithZWrite),n.assignColor(`shadeColorFactor`,e.shadeColorFactor),n.assignTexture(`shadeMultiplyTexture`,e.shadeMultiplyTexture,!0),n.assignPrimitive(`shadingShiftFactor`,e.shadingShiftFactor),n.assignTexture(`shadingShiftTexture`,e.shadingShiftTexture,!0),n.assignPrimitive(`shadingShiftTextureScale`,e.shadingShiftTexture?.scale),n.assignPrimitive(`shadingToonyFactor`,e.shadingToonyFactor),n.assignPrimitive(`giEqualizationFactor`,e.giEqualizationFactor),n.assignColor(`matcapFactor`,e.matcapFactor),n.assignTexture(`matcapTexture`,e.matcapTexture,!0),n.assignColor(`parametricRimColorFactor`,e.parametricRimColorFactor),n.assignTexture(`rimMultiplyTexture`,e.rimMultiplyTexture,!0),n.assignPrimitive(`rimLightingMixFactor`,e.rimLightingMixFactor),n.assignPrimitive(`parametricRimFresnelPowerFactor`,e.parametricRimFresnelPowerFactor),n.assignPrimitive(`parametricRimLiftFactor`,e.parametricRimLiftFactor),n.assignPrimitive(`outlineWidthMode`,e.outlineWidthMode),n.assignPrimitive(`outlineWidthFactor`,e.outlineWidthFactor),n.assignTexture(`outlineWidthMultiplyTexture`,e.outlineWidthMultiplyTexture,!1),n.assignColor(`outlineColorFactor`,e.outlineColorFactor),n.assignPrimitive(`outlineLightingMixFactor`,e.outlineLightingMixFactor),n.assignTexture(`uvAnimationMaskTexture`,e.uvAnimationMaskTexture,!1),n.assignPrimitive(`uvAnimationScrollXSpeedFactor`,e.uvAnimationScrollXSpeedFactor),n.assignPrimitive(`uvAnimationScrollYSpeedFactor`,e.uvAnimationScrollYSpeedFactor),n.assignPrimitive(`uvAnimationRotationSpeedFactor`,e.uvAnimationRotationSpeedFactor),n.assignPrimitive(`v0CompatShade`,this.v0CompatShade),n.assignPrimitive(`debugMode`,this.debugMode),yield n.pending})}_setupPrimitive(e,t){let n=this._getMToonExtension(t);if(n){e.renderOrder=this._parseRenderOrder(n)+this.renderOrderOffset,this._generateOutline(e),this._addToMaterialSet(e);return}}_shouldGenerateOutline(e){return typeof e.outlineWidthMode==`string`&&e.outlineWidthMode!==`none`&&typeof e.outlineWidthFactor==`number`&&e.outlineWidthFactor>0}_generateOutline(e){let t=e.material;if(!(t instanceof Os)||!this._shouldGenerateOutline(t))return;e.material=[t];let n=t.clone();n.name+=` (Outline)`,n.isOutline=!0,n.side=1,e.material.push(n);let r=e.geometry,i=r.index?r.index.count:r.attributes.position.count/3;r.addGroup(0,i,0),r.addGroup(0,i,1)}_addToMaterialSet(e){let t=e.material,n=new Set;Array.isArray(t)?t.forEach(e=>n.add(e)):n.add(t);for(let e of n)this._mToonMaterialSet.add(e)}_parseRenderOrder(e){return(e.transparentWithZWrite?0:19)+(e.renderQueueOffsetNumber??0)}};tx.EXTENSION_NAME=`VRMC_materials_mtoon`;var nx=tx,rx=(e,t,n)=>new Promise((r,i)=>{var a=e=>{try{s(n.next(e))}catch(e){i(e)}},o=e=>{try{s(n.throw(e))}catch(e){i(e)}},s=e=>e.done?r(e.value):Promise.resolve(e.value).then(a,o);s((n=n.apply(e,t)).next())}),ix=class e{get name(){return e.EXTENSION_NAME}constructor(e){this.parser=e}extendMaterialParams(e,t){return rx(this,null,function*(){let n=this._getHDREmissiveMultiplierExtension(e);n!=null&&(console.warn("VRMMaterialsHDREmissiveMultiplierLoaderPlugin: `VRMC_materials_hdr_emissiveMultiplier` is archived. Use `KHR_materials_emissive_strength` instead."),t.emissiveIntensity=n.emissiveMultiplier)})}_getHDREmissiveMultiplierExtension(t){let n=this.parser.json.materials?.[t];if(n==null){console.warn(`VRMMaterialsHDREmissiveMultiplierLoaderPlugin: Attempt to use materials[${t}] of glTF but the material doesn't exist`);return}let r=n.extensions?.[e.EXTENSION_NAME];if(r!=null)return r}};ix.EXTENSION_NAME=`VRMC_materials_hdr_emissiveMultiplier`;var ax=ix,ox=Object.defineProperty,sx=Object.defineProperties,cx=Object.getOwnPropertyDescriptors,lx=Object.getOwnPropertySymbols,ux=Object.prototype.hasOwnProperty,dx=Object.prototype.propertyIsEnumerable,fx=(e,t,n)=>t in e?ox(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,px=(e,t)=>{for(var n in t||={})ux.call(t,n)&&fx(e,n,t[n]);if(lx)for(var n of lx(t))dx.call(t,n)&&fx(e,n,t[n]);return e},mx=(e,t)=>sx(e,cx(t)),hx=(e,t,n)=>new Promise((r,i)=>{var a=e=>{try{s(n.next(e))}catch(e){i(e)}},o=e=>{try{s(n.throw(e))}catch(e){i(e)}},s=e=>e.done?r(e.value):Promise.resolve(e.value).then(a,o);s((n=n.apply(e,t)).next())});function gx(e){return e**2.2}var _x=class{get name(){return`VRMMaterialsV0CompatPlugin`}constructor(e){this.parser=e,this._renderQueueMapTransparent=new Map,this._renderQueueMapTransparentZWrite=new Map;let t=this.parser.json;t.extensionsUsed=t.extensionsUsed??[],t.extensionsUsed.indexOf(`KHR_texture_transform`)===-1&&t.extensionsUsed.push(`KHR_texture_transform`)}beforeRoot(){return hx(this,null,function*(){let e=this.parser.json,t=e.extensions?.VRM?.materialProperties;t&&(this._populateRenderQueueMap(t),t.forEach((t,n)=>{let r=e.materials?.[n];if(r==null){console.warn(`VRMMaterialsV0CompatPlugin: Attempt to use materials[${n}] of glTF but the material doesn't exist`);return}if(t.shader===`VRM/MToon`){let i=this._parseV0MToonProperties(t,r);e.materials[n]=i}else if(t.shader?.startsWith(`VRM/Unlit`)){let i=this._parseV0UnlitProperties(t,r);e.materials[n]=i}else t.shader===`VRM_USE_GLTFSHADER`||console.warn(`VRMMaterialsV0CompatPlugin: Unknown shader: ${t.shader}`)}))})}_parseV0MToonProperties(e,t){let n=e.keywordMap?._ALPHABLEND_ON??!1,r=e.floatProperties?._ZWrite===1&&n,i=this._v0ParseRenderQueue(e),a=e.keywordMap?._ALPHATEST_ON??!1,o=n?`BLEND`:a?`MASK`:`OPAQUE`,s=a?e.floatProperties?._Cutoff??.5:void 0,c=(e.floatProperties?._CullMode??2)===0,l=this._portTextureTransform(e),u=(e.vectorProperties?._Color??[1,1,1,1]).map((e,t)=>t===3?e:gx(e)),d=e.textureProperties?._MainTex,f=d==null?void 0:{index:d,extensions:px({},l)},p=e.floatProperties?._BumpScale??1,m=e.textureProperties?._BumpMap,h=m==null?void 0:{index:m,scale:p,extensions:px({},l)},g=(e.vectorProperties?._EmissionColor??[0,0,0,1]).map(gx),_=e.textureProperties?._EmissionMap,v=_==null?void 0:{index:_,extensions:px({},l)},y=(e.vectorProperties?._ShadeColor??[.97,.81,.86,1]).map(gx),b=e.textureProperties?._ShadeTexture,x=b==null?void 0:{index:b,extensions:px({},l)},S=e.floatProperties?._ShadeShift??0,C=e.floatProperties?._ShadeToony??.9;C=ba.lerp(C,1,.5+.5*S),S=-S-(1-C);let w=e.floatProperties?._IndirectLightIntensity??.1,T=w?1-w:void 0,E=e.textureProperties?._SphereAdd,D=E==null?void 0:[1,1,1],O=E==null?void 0:{index:E},k=e.floatProperties?._RimLightingMix??0,A=e.textureProperties?._RimTexture,ee=A==null?void 0:{index:A,extensions:px({},l)},te=(e.vectorProperties?._RimColor??[0,0,0,1]).map(gx),ne=e.floatProperties?._RimFresnelPower??1,re=e.floatProperties?._RimLift??0,j=[`none`,`worldCoordinates`,`screenCoordinates`][e.floatProperties?._OutlineWidthMode??0],ie=e.floatProperties?._OutlineWidth??0;ie=.01*ie;let ae=e.textureProperties?._OutlineWidthTexture,M=ae==null?void 0:{index:ae,extensions:px({},l)},oe=(e.vectorProperties?._OutlineColor??[0,0,0]).map(gx),se=(e.floatProperties?._OutlineColorMode??0)===1?e.floatProperties?._OutlineLightingMix??1:0,ce=e.textureProperties?._UvAnimMaskTexture,le=ce==null?void 0:{index:ce,extensions:px({},l)},ue=e.floatProperties?._UvAnimScrollX??0,de=e.floatProperties?._UvAnimScrollY??0;de!=null&&(de=-de);let fe=e.floatProperties?._UvAnimRotation??0,pe={specVersion:`1.0`,transparentWithZWrite:r,renderQueueOffsetNumber:i,shadeColorFactor:y,shadeMultiplyTexture:x,shadingShiftFactor:S,shadingToonyFactor:C,giEqualizationFactor:T,matcapFactor:D,matcapTexture:O,rimLightingMixFactor:k,rimMultiplyTexture:ee,parametricRimColorFactor:te,parametricRimFresnelPowerFactor:ne,parametricRimLiftFactor:re,outlineWidthMode:j,outlineWidthFactor:ie,outlineWidthMultiplyTexture:M,outlineColorFactor:oe,outlineLightingMixFactor:se,uvAnimationMaskTexture:le,uvAnimationScrollXSpeedFactor:ue,uvAnimationScrollYSpeedFactor:de,uvAnimationRotationSpeedFactor:fe};return mx(px({},t),{pbrMetallicRoughness:{baseColorFactor:u,baseColorTexture:f},normalTexture:h,emissiveTexture:v,emissiveFactor:g,alphaMode:o,alphaCutoff:s,doubleSided:c,extensions:{VRMC_materials_mtoon:pe}})}_parseV0UnlitProperties(e,t){let n=e.shader===`VRM/UnlitTransparentZWrite`,r=e.shader===`VRM/UnlitTransparent`||n,i=this._v0ParseRenderQueue(e),a=e.shader===`VRM/UnlitCutout`,o=r?`BLEND`:a?`MASK`:`OPAQUE`,s=a?e.floatProperties?._Cutoff??.5:void 0,c=this._portTextureTransform(e),l=(e.vectorProperties?._Color??[1,1,1,1]).map(gx),u=e.textureProperties?._MainTex,d=u==null?void 0:{index:u,extensions:px({},c)},f={specVersion:`1.0`,transparentWithZWrite:n,renderQueueOffsetNumber:i,shadeColorFactor:l,shadeMultiplyTexture:d};return mx(px({},t),{pbrMetallicRoughness:{baseColorFactor:l,baseColorTexture:d},alphaMode:o,alphaCutoff:s,extensions:{VRMC_materials_mtoon:f}})}_portTextureTransform(e){let t=e.vectorProperties?._MainTex;if(t==null)return{};let n=[t?.[0]??0,t?.[1]??0],r=[t?.[2]??1,t?.[3]??1];return n[1]=1-r[1]-n[1],{KHR_texture_transform:{offset:n,scale:r}}}_v0ParseRenderQueue(e){let t=e.shader===`VRM/UnlitTransparentZWrite`,n=e.keywordMap?._ALPHABLEND_ON!=null||e.shader===`VRM/UnlitTransparent`||t,r=e.floatProperties?._ZWrite===1||t,i=0;if(n){let t=e.renderQueue;t!=null&&(i=r?this._renderQueueMapTransparentZWrite.get(t):this._renderQueueMapTransparent.get(t))}return i}_populateRenderQueueMap(e){let t=new Set,n=new Set;e.forEach(e=>{let r=e.shader===`VRM/UnlitTransparentZWrite`,i=e.keywordMap?._ALPHABLEND_ON!=null||e.shader===`VRM/UnlitTransparent`||r,a=e.floatProperties?._ZWrite===1||r;if(i){let r=e.renderQueue;r!=null&&(a?n.add(r):t.add(r))}}),t.size>10&&console.warn(`VRMMaterialsV0CompatPlugin: This VRM uses ${t.size} render queues for Transparent materials while VRM 1.0 only supports up to 10 render queues. The model might not be rendered correctly.`),n.size>10&&console.warn(`VRMMaterialsV0CompatPlugin: This VRM uses ${n.size} render queues for TransparentZWrite materials while VRM 1.0 only supports up to 10 render queues. The model might not be rendered correctly.`),Array.from(t).sort().forEach((e,n)=>{let r=Math.min(Math.max(n-t.size+1,-9),0);this._renderQueueMapTransparent.set(e,r)}),Array.from(n).sort().forEach((e,t)=>{let n=Math.min(Math.max(t,0),9);this._renderQueueMapTransparentZWrite.set(e,n)})}},vx=(e,t,n)=>new Promise((r,i)=>{var a=e=>{try{s(n.next(e))}catch(e){i(e)}},o=e=>{try{s(n.throw(e))}catch(e){i(e)}},s=e=>e.done?r(e.value):Promise.resolve(e.value).then(a,o);s((n=n.apply(e,t)).next())}),yx=new U,bx=class extends _o{constructor(e){super(),this._attrPosition=new q(new Float32Array([0,0,0,0,0,0]),3),this._attrPosition.setUsage(Pi);let t=new J;t.setAttribute(`position`,this._attrPosition);let n=new Ac({color:16711935,depthTest:!1,depthWrite:!1});this._line=new Rc(t,n),this.add(this._line),this.constraint=e}updateMatrixWorld(e){yx.setFromMatrixPosition(this.constraint.destination.matrixWorld),this._attrPosition.setXYZ(0,yx.x,yx.y,yx.z),this.constraint.source&&yx.setFromMatrixPosition(this.constraint.source.matrixWorld),this._attrPosition.setXYZ(1,yx.x,yx.y,yx.z),this._attrPosition.needsUpdate=!0,super.updateMatrixWorld(e)}};function xx(e,t){return t.set(e.elements[12],e.elements[13],e.elements[14])}var Sx=new U,Cx=new U;function wx(e,t){return e.decompose(Sx,t,Cx),t}function Tx(e){return e.invert?e.invert():e.inverse(),e}var Ex=class{constructor(e,t){this.destination=e,this.source=t,this.weight=1}},Dx=new U,Ox=new U,kx=new U,Ax=new H,jx=new H,Mx=new H,Nx=class extends Ex{get aimAxis(){return this._aimAxis}set aimAxis(e){this._aimAxis=e,this._v3AimAxis.set(e===`PositiveX`?1:e===`NegativeX`?-1:0,e===`PositiveY`?1:e===`NegativeY`?-1:0,e===`PositiveZ`?1:e===`NegativeZ`?-1:0)}get dependencies(){let e=new Set([this.source]);return this.destination.parent&&e.add(this.destination.parent),e}constructor(e,t){super(e,t),this._aimAxis=`PositiveX`,this._v3AimAxis=new U(1,0,0),this._dstRestQuat=new H}setInitState(){this._dstRestQuat.copy(this.destination.quaternion)}update(){this.destination.updateWorldMatrix(!0,!1),this.source.updateWorldMatrix(!0,!1);let e=Ax.identity(),t=jx.identity();this.destination.parent&&(wx(this.destination.parent.matrixWorld,e),Tx(t.copy(e)));let n=Dx.copy(this._v3AimAxis).applyQuaternion(this._dstRestQuat).applyQuaternion(e),r=xx(this.source.matrixWorld,Ox).sub(xx(this.destination.matrixWorld,kx)).normalize(),i=Mx.setFromUnitVectors(n,r).premultiply(t).multiply(e).multiply(this._dstRestQuat);this.destination.quaternion.copy(this._dstRestQuat).slerp(i,this.weight)}};function Px(e,t){let n=[e],r=e.parent;for(;r!==null;)n.unshift(r),r=r.parent;n.forEach(e=>{t(e)})}var Fx=class{constructor(){this._constraints=new Set,this._objectConstraintsMap=new Map}get constraints(){return this._constraints}addConstraint(e){this._constraints.add(e);let t=this._objectConstraintsMap.get(e.destination);t??(t=new Set,this._objectConstraintsMap.set(e.destination,t)),t.add(e)}deleteConstraint(e){this._constraints.delete(e),this._objectConstraintsMap.get(e.destination).delete(e)}setInitState(){let e=new Set,t=new Set;for(let n of this._constraints)this._processConstraint(n,e,t,e=>e.setInitState())}update(){let e=new Set,t=new Set;for(let n of this._constraints)this._processConstraint(n,e,t,e=>e.update())}_processConstraint(e,t,n,r){if(n.has(e))return;if(t.has(e))throw Error(`VRMNodeConstraintManager: Circular dependency detected while updating constraints`);t.add(e);let i=e.dependencies;for(let e of i)Px(e,e=>{let i=this._objectConstraintsMap.get(e);if(i)for(let e of i)this._processConstraint(e,t,n,r)});r(e),n.add(e)}},Ix=new H,Lx=new H,Rx=class extends Ex{get dependencies(){return new Set([this.source])}constructor(e,t){super(e,t),this._dstRestQuat=new H,this._invSrcRestQuat=new H}setInitState(){this._dstRestQuat.copy(this.destination.quaternion),Tx(this._invSrcRestQuat.copy(this.source.quaternion))}update(){let e=Ix.copy(this._invSrcRestQuat).multiply(this.source.quaternion),t=Lx.copy(this._dstRestQuat).multiply(e);this.destination.quaternion.copy(this._dstRestQuat).slerp(t,this.weight)}},zx=new U,Bx=new H,Vx=new H,Hx=class extends Ex{get rollAxis(){return this._rollAxis}set rollAxis(e){this._rollAxis=e,this._v3RollAxis.set(+(e===`X`),+(e===`Y`),+(e===`Z`))}get dependencies(){return new Set([this.source])}constructor(e,t){super(e,t),this._rollAxis=`X`,this._v3RollAxis=new U(1,0,0),this._dstRestQuat=new H,this._invDstRestQuat=new H,this._invSrcRestQuatMulDstRestQuat=new H}setInitState(){this._dstRestQuat.copy(this.destination.quaternion),Tx(this._invDstRestQuat.copy(this._dstRestQuat)),Tx(this._invSrcRestQuatMulDstRestQuat.copy(this.source.quaternion)).multiply(this._dstRestQuat)}update(){let e=Bx.copy(this._invDstRestQuat).multiply(this.source.quaternion).multiply(this._invSrcRestQuatMulDstRestQuat),t=zx.copy(this._v3RollAxis).applyQuaternion(e),n=Vx.setFromUnitVectors(t,this._v3RollAxis).premultiply(this._dstRestQuat).multiply(e);this.destination.quaternion.copy(this._dstRestQuat).slerp(n,this.weight)}},Ux=new Set([`1.0`,`1.0-beta`]),Wx=class e{get name(){return e.EXTENSION_NAME}constructor(e,t){this.parser=e,this.helperRoot=t?.helperRoot}afterRoot(e){return vx(this,null,function*(){e.userData.vrmNodeConstraintManager=yield this._import(e)})}_import(t){return vx(this,null,function*(){let n=this.parser.json;if(n.extensionsUsed?.indexOf(e.EXTENSION_NAME)===-1)return null;let r=new Fx,i=yield this.parser.getDependencies(`node`);return i.forEach((t,a)=>{let o=n.nodes[a]?.extensions?.[e.EXTENSION_NAME];if(o==null)return;let s=o.specVersion;if(!Ux.has(s)){console.warn(`VRMNodeConstraintLoaderPlugin: Unknown ${e.EXTENSION_NAME} specVersion "${s}"`);return}let c=o.constraint;if(c.roll!=null){let e=this._importRollConstraint(t,i,c.roll);r.addConstraint(e)}else if(c.aim!=null){let e=this._importAimConstraint(t,i,c.aim);r.addConstraint(e)}else if(c.rotation!=null){let e=this._importRotationConstraint(t,i,c.rotation);r.addConstraint(e)}}),t.scene.updateMatrixWorld(),r.setInitState(),r})}_importRollConstraint(e,t,n){let{source:r,rollAxis:i,weight:a}=n,o=t[r],s=new Hx(e,o);if(i!=null&&(s.rollAxis=i),a!=null&&(s.weight=a),this.helperRoot){let e=new bx(s);this.helperRoot.add(e)}return s}_importAimConstraint(e,t,n){let{source:r,aimAxis:i,weight:a}=n,o=t[r],s=new Nx(e,o);if(i!=null&&(s.aimAxis=i),a!=null&&(s.weight=a),this.helperRoot){let e=new bx(s);this.helperRoot.add(e)}return s}_importRotationConstraint(e,t,n){let{source:r,weight:i}=n,a=t[r],o=new Rx(e,a);if(i!=null&&(o.weight=i),this.helperRoot){let e=new bx(o);this.helperRoot.add(e)}return o}};Wx.EXTENSION_NAME=`VRMC_node_constraint`;var Gx=Wx,Kx=(e,t,n)=>new Promise((r,i)=>{var a=e=>{try{s(n.next(e))}catch(e){i(e)}},o=e=>{try{s(n.throw(e))}catch(e){i(e)}},s=e=>e.done?r(e.value):Promise.resolve(e.value).then(a,o);s((n=n.apply(e,t)).next())}),qx=class{},Jx=new U,Yx=new U,Xx=class extends qx{get type(){return`capsule`}constructor(e){super(),this.offset=e?.offset??new U(0,0,0),this.tail=e?.tail??new U(0,0,0),this.radius=e?.radius??0,this.inside=e?.inside??!1}calculateCollision(e,t,n,r){Jx.setFromMatrixPosition(e),Yx.subVectors(this.tail,this.offset).applyMatrix4(e),Yx.sub(Jx);let i=Yx.lengthSq();r.copy(t).sub(Jx);let a=Yx.dot(r);a<=0||(i<=a||Yx.multiplyScalar(a/i),r.sub(Yx));let o=r.length(),s=this.inside?this.radius-n-o:o-n-this.radius;return s<0&&(r.multiplyScalar(1/o),this.inside&&r.negate()),s}},Zx=new U,Qx=new W,$x=class extends qx{get type(){return`plane`}constructor(e){super(),this.offset=e?.offset??new U(0,0,0),this.normal=e?.normal??new U(0,0,1)}calculateCollision(e,t,n,r){r.setFromMatrixPosition(e),r.negate().add(t),Qx.getNormalMatrix(e),Zx.copy(this.normal).applyNormalMatrix(Qx).normalize();let i=r.dot(Zx)-n;return r.copy(Zx),i}},eS=new U,tS=class extends qx{get type(){return`sphere`}constructor(e){super(),this.offset=e?.offset??new U(0,0,0),this.radius=e?.radius??0,this.inside=e?.inside??!1}calculateCollision(e,t,n,r){r.subVectors(t,eS.setFromMatrixPosition(e));let i=r.length(),a=this.inside?this.radius-n-i:i-n-this.radius;return a<0&&(r.multiplyScalar(1/i),this.inside&&r.negate()),a}},nS=new U,rS=class extends J{constructor(e){super(),this.worldScale=1,this._currentRadius=0,this._currentOffset=new U,this._currentTail=new U,this._shape=e,this._attrPos=new q(new Float32Array(396),3),this.setAttribute(`position`,this._attrPos),this._attrIndex=new q(new Uint16Array(264),1),this.setIndex(this._attrIndex),this._buildIndex(),this.update()}update(){let e=!1,t=this._shape.radius/this.worldScale;this._currentRadius!==t&&(this._currentRadius=t,e=!0),this._currentOffset.equals(this._shape.offset)||(this._currentOffset.copy(this._shape.offset),e=!0);let n=nS.copy(this._shape.tail).divideScalar(this.worldScale);this._currentTail.distanceToSquared(n)>1e-10&&(this._currentTail.copy(n),e=!0),e&&this._buildPosition()}_buildPosition(){nS.copy(this._currentTail).sub(this._currentOffset);let e=nS.length()/this._currentRadius;for(let t=0;t<=16;t++){let n=t/16*Math.PI;this._attrPos.setXYZ(t,-Math.sin(n),-Math.cos(n),0),this._attrPos.setXYZ(17+t,e+Math.sin(n),Math.cos(n),0),this._attrPos.setXYZ(34+t,-Math.sin(n),0,-Math.cos(n)),this._attrPos.setXYZ(51+t,e+Math.sin(n),0,Math.cos(n))}for(let t=0;t<32;t++){let n=t/16*Math.PI;this._attrPos.setXYZ(68+t,0,Math.sin(n),Math.cos(n)),this._attrPos.setXYZ(100+t,e,Math.sin(n),Math.cos(n))}let t=Math.atan2(nS.y,Math.sqrt(nS.x*nS.x+nS.z*nS.z)),n=-Math.atan2(nS.z,nS.x);this.rotateZ(t),this.rotateY(n),this.scale(this._currentRadius,this._currentRadius,this._currentRadius),this.translate(this._currentOffset.x,this._currentOffset.y,this._currentOffset.z),this._attrPos.needsUpdate=!0}_buildIndex(){for(let e=0;e<34;e++){let t=(e+1)%34;this._attrIndex.setXY(e*2,e,t),this._attrIndex.setXY(68+e*2,34+e,34+t)}for(let e=0;e<32;e++){let t=(e+1)%32;this._attrIndex.setXY(136+e*2,68+e,68+t),this._attrIndex.setXY(200+e*2,100+e,100+t)}this._attrIndex.needsUpdate=!0}},iS=class extends J{constructor(e){super(),this.worldScale=1,this._currentOffset=new U,this._currentNormal=new U,this._shape=e,this._attrPos=new q(new Float32Array(18),3),this.setAttribute(`position`,this._attrPos),this._attrIndex=new q(new Uint16Array(10),1),this.setIndex(this._attrIndex),this._buildIndex(),this.update()}update(){let e=!1;this._currentOffset.equals(this._shape.offset)||(this._currentOffset.copy(this._shape.offset),e=!0),this._currentNormal.equals(this._shape.normal)||(this._currentNormal.copy(this._shape.normal),e=!0),e&&this._buildPosition()}_buildPosition(){this._attrPos.setXYZ(0,-.5,-.5,0),this._attrPos.setXYZ(1,.5,-.5,0),this._attrPos.setXYZ(2,.5,.5,0),this._attrPos.setXYZ(3,-.5,.5,0),this._attrPos.setXYZ(4,0,0,0),this._attrPos.setXYZ(5,0,0,.25),this.translate(this._currentOffset.x,this._currentOffset.y,this._currentOffset.z),this.lookAt(this._currentNormal),this._attrPos.needsUpdate=!0}_buildIndex(){this._attrIndex.setXY(0,0,1),this._attrIndex.setXY(2,1,2),this._attrIndex.setXY(4,2,3),this._attrIndex.setXY(6,3,0),this._attrIndex.setXY(8,4,5),this._attrIndex.needsUpdate=!0}},aS=class extends J{constructor(e){super(),this.worldScale=1,this._currentRadius=0,this._currentOffset=new U,this._shape=e,this._attrPos=new q(new Float32Array(288),3),this.setAttribute(`position`,this._attrPos),this._attrIndex=new q(new Uint16Array(192),1),this.setIndex(this._attrIndex),this._buildIndex(),this.update()}update(){let e=!1,t=this._shape.radius/this.worldScale;this._currentRadius!==t&&(this._currentRadius=t,e=!0),this._currentOffset.equals(this._shape.offset)||(this._currentOffset.copy(this._shape.offset),e=!0),e&&this._buildPosition()}_buildPosition(){for(let e=0;e<32;e++){let t=e/16*Math.PI;this._attrPos.setXYZ(e,Math.cos(t),Math.sin(t),0),this._attrPos.setXYZ(32+e,0,Math.cos(t),Math.sin(t)),this._attrPos.setXYZ(64+e,Math.sin(t),0,Math.cos(t))}this.scale(this._currentRadius,this._currentRadius,this._currentRadius),this.translate(this._currentOffset.x,this._currentOffset.y,this._currentOffset.z),this._attrPos.needsUpdate=!0}_buildIndex(){for(let e=0;e<32;e++){let t=(e+1)%32;this._attrIndex.setXY(e*2,e,t),this._attrIndex.setXY(64+e*2,32+e,32+t),this._attrIndex.setXY(128+e*2,64+e,64+t)}this._attrIndex.needsUpdate=!0}},oS=new U,sS=class extends _o{constructor(e){if(super(),this.matrixAutoUpdate=!1,this.collider=e,this.collider.shape instanceof tS)this._geometry=new aS(this.collider.shape);else if(this.collider.shape instanceof Xx)this._geometry=new rS(this.collider.shape);else if(this.collider.shape instanceof $x)this._geometry=new iS(this.collider.shape);else throw Error(`VRMSpringBoneColliderHelper: Unknown collider shape type detected`);let t=new Ac({color:16711935,depthTest:!1,depthWrite:!1});this._line=new Hc(this._geometry,t),this.add(this._line)}dispose(){this._geometry.dispose()}updateMatrixWorld(e){this.collider.updateWorldMatrix(!0,!1),this.matrix.copy(this.collider.matrixWorld);let t=this.matrix.elements;this._geometry.worldScale=oS.set(t[0],t[1],t[2]).length(),this._geometry.update(),super.updateMatrixWorld(e)}},cS=class extends J{constructor(e){super(),this.worldScale=1,this._currentRadius=0,this._currentTail=new U,this._springBone=e,this._attrPos=new q(new Float32Array(294),3),this.setAttribute(`position`,this._attrPos),this._attrIndex=new q(new Uint16Array(194),1),this.setIndex(this._attrIndex),this._buildIndex(),this.update()}update(){let e=!1,t=this._springBone.settings.hitRadius/this.worldScale;this._currentRadius!==t&&(this._currentRadius=t,e=!0),this._currentTail.equals(this._springBone.initialLocalChildPosition)||(this._currentTail.copy(this._springBone.initialLocalChildPosition),e=!0),e&&this._buildPosition()}_buildPosition(){for(let e=0;e<32;e++){let t=e/16*Math.PI;this._attrPos.setXYZ(e,Math.cos(t),Math.sin(t),0),this._attrPos.setXYZ(32+e,0,Math.cos(t),Math.sin(t)),this._attrPos.setXYZ(64+e,Math.sin(t),0,Math.cos(t))}this.scale(this._currentRadius,this._currentRadius,this._currentRadius),this.translate(this._currentTail.x,this._currentTail.y,this._currentTail.z),this._attrPos.setXYZ(96,0,0,0),this._attrPos.setXYZ(97,this._currentTail.x,this._currentTail.y,this._currentTail.z),this._attrPos.needsUpdate=!0}_buildIndex(){for(let e=0;e<32;e++){let t=(e+1)%32;this._attrIndex.setXY(e*2,e,t),this._attrIndex.setXY(64+e*2,32+e,32+t),this._attrIndex.setXY(128+e*2,64+e,64+t)}this._attrIndex.setXY(192,96,97),this._attrIndex.needsUpdate=!0}},lS=new U,uS=class extends _o{constructor(e){super(),this.matrixAutoUpdate=!1,this.springBone=e,this._geometry=new cS(this.springBone);let t=new Ac({color:16776960,depthTest:!1,depthWrite:!1});this._line=new Hc(this._geometry,t),this.add(this._line)}dispose(){this._geometry.dispose()}updateMatrixWorld(e){this.springBone.bone.updateWorldMatrix(!0,!1),this.matrix.copy(this.springBone.bone.matrixWorld);let t=this.matrix.elements;this._geometry.worldScale=lS.set(t[0],t[1],t[2]).length(),this._geometry.update(),super.updateMatrixWorld(e)}},dS=class extends go{constructor(e){super(),this.colliderMatrix=new G,this.shape=e}updateWorldMatrix(e,t){super.updateWorldMatrix(e,t),fS(this.colliderMatrix,this.matrixWorld,this.shape.offset)}};function fS(e,t,n){let r=t.elements;e.copy(t),n&&(e.elements[12]=r[0]*n.x+r[4]*n.y+r[8]*n.z+r[12],e.elements[13]=r[1]*n.x+r[5]*n.y+r[9]*n.z+r[13],e.elements[14]=r[2]*n.x+r[6]*n.y+r[10]*n.z+r[14])}var pS=new G;function mS(e){return e.invert?e.invert():e.getInverse(pS.copy(e)),e}var hS=class{constructor(e){this._inverseCache=new G,this._shouldUpdateInverse=!0,this.matrix=e;let t={set:(e,t,n)=>(this._shouldUpdateInverse=!0,e[t]=n,!0)};this._originalElements=e.elements,e.elements=new Proxy(e.elements,t)}get inverse(){return this._shouldUpdateInverse&&=(mS(this._inverseCache.copy(this.matrix)),!1),this._inverseCache}revert(){this.matrix.elements=this._originalElements}},gS=new G,_S=new U,vS=new U,yS=new U,bS=new U,xS=new G,SS=class{constructor(e,t,n={},r=[]){this._currentTail=new U,this._prevTail=new U,this._boneAxis=new U,this._worldSpaceBoneLength=0,this._center=null,this._initialLocalMatrix=new G,this._initialLocalRotation=new H,this._initialLocalChildPosition=new U,this.bone=e,this.bone.matrixAutoUpdate=!1,this.child=t,this.settings={hitRadius:n.hitRadius??0,stiffness:n.stiffness??1,gravityPower:n.gravityPower??0,gravityDir:n.gravityDir?.clone()??new U(0,-1,0),dragForce:n.dragForce??.4},this.colliderGroups=r}get dependencies(){let e=new Set,t=this.bone.parent;t&&e.add(t);for(let t=0;t<this.colliderGroups.length;t++)for(let n=0;n<this.colliderGroups[t].colliders.length;n++)e.add(this.colliderGroups[t].colliders[n]);return e}get center(){return this._center}set center(e){this._center?.userData.inverseCacheProxy&&(this._center.userData.inverseCacheProxy.revert(),delete this._center.userData.inverseCacheProxy),this._center=e,this._center&&(this._center.userData.inverseCacheProxy||(this._center.userData.inverseCacheProxy=new hS(this._center.matrixWorld)))}get initialLocalChildPosition(){return this._initialLocalChildPosition}get _parentMatrixWorld(){return this.bone.parent?this.bone.parent.matrixWorld:gS}setInitState(){this._initialLocalMatrix.copy(this.bone.matrix),this._initialLocalRotation.copy(this.bone.quaternion),this.child?this._initialLocalChildPosition.copy(this.child.position):this._initialLocalChildPosition.copy(this.bone.position).normalize().multiplyScalar(.07);let e=this._getMatrixWorldToCenter();this.bone.localToWorld(this._currentTail.copy(this._initialLocalChildPosition)).applyMatrix4(e),this._prevTail.copy(this._currentTail),this._boneAxis.copy(this._initialLocalChildPosition).normalize()}reset(){this.bone.quaternion.copy(this._initialLocalRotation),this.bone.updateMatrix(),this.bone.matrixWorld.multiplyMatrices(this._parentMatrixWorld,this.bone.matrix);let e=this._getMatrixWorldToCenter();this.bone.localToWorld(this._currentTail.copy(this._initialLocalChildPosition)).applyMatrix4(e),this._prevTail.copy(this._currentTail)}update(e){if(e<=0)return;this._calcWorldSpaceBoneLength();let t=vS.copy(this._boneAxis).transformDirection(this._initialLocalMatrix).transformDirection(this._parentMatrixWorld);bS.copy(this._currentTail).add(_S.subVectors(this._currentTail,this._prevTail).multiplyScalar(1-this.settings.dragForce)).applyMatrix4(this._getMatrixCenterToWorld()).addScaledVector(t,this.settings.stiffness*e).addScaledVector(this.settings.gravityDir,this.settings.gravityPower*e),yS.setFromMatrixPosition(this.bone.matrixWorld),bS.sub(yS).normalize().multiplyScalar(this._worldSpaceBoneLength).add(yS),this._collision(bS),this._prevTail.copy(this._currentTail),this._currentTail.copy(bS).applyMatrix4(this._getMatrixWorldToCenter());let n=xS.multiplyMatrices(this._parentMatrixWorld,this._initialLocalMatrix).invert();this.bone.quaternion.setFromUnitVectors(this._boneAxis,_S.copy(bS).applyMatrix4(n).normalize()).premultiply(this._initialLocalRotation),this.bone.updateMatrix(),this.bone.matrixWorld.multiplyMatrices(this._parentMatrixWorld,this.bone.matrix)}_collision(e){for(let t=0;t<this.colliderGroups.length;t++)for(let n=0;n<this.colliderGroups[t].colliders.length;n++){let r=this.colliderGroups[t].colliders[n],i=r.shape.calculateCollision(r.colliderMatrix,e,this.settings.hitRadius,_S);if(i<0){e.addScaledVector(_S,-i),e.sub(yS);let t=e.length();e.multiplyScalar(this._worldSpaceBoneLength/t).add(yS)}}}_calcWorldSpaceBoneLength(){_S.setFromMatrixPosition(this.bone.matrixWorld),this.child?vS.setFromMatrixPosition(this.child.matrixWorld):(vS.copy(this._initialLocalChildPosition),vS.applyMatrix4(this.bone.matrixWorld)),this._worldSpaceBoneLength=_S.sub(vS).length()}_getMatrixCenterToWorld(){return this._center?this._center.matrixWorld:gS}_getMatrixWorldToCenter(){return this._center?this._center.userData.inverseCacheProxy.inverse:gS}};function CS(e,t){let n=[],r=e;for(;r!==null;)n.unshift(r),r=r.parent;n.forEach(e=>{t(e)})}function wS(e,t){e.children.forEach(e=>{t(e)||wS(e,t)})}function TS(e){let t=new Map;for(let n of e){let r=n;do{let n=(t.get(r)??0)+1;if(n===e.size)return r;t.set(r,n),r=r.parent}while(r!==null)}return null}var ES=class{constructor(){this._joints=new Set,this._sortedJoints=[],this._hasWarnedCircularDependency=!1,this._ancestors=[],this._objectSpringBonesMap=new Map,this._isSortedJointsDirty=!1,this._relevantChildrenUpdated=this._relevantChildrenUpdated.bind(this)}get joints(){return this._joints}get springBones(){return console.warn(`VRMSpringBoneManager: springBones is deprecated. use joints instead.`),this._joints}get colliderGroups(){let e=new Set;return this._joints.forEach(t=>{t.colliderGroups.forEach(t=>{e.add(t)})}),Array.from(e)}get colliders(){let e=new Set;return this.colliderGroups.forEach(t=>{t.colliders.forEach(t=>{e.add(t)})}),Array.from(e)}addJoint(e){this._joints.add(e);let t=this._objectSpringBonesMap.get(e.bone);t??(t=new Set,this._objectSpringBonesMap.set(e.bone,t)),t.add(e),this._isSortedJointsDirty=!0}addSpringBone(e){console.warn(`VRMSpringBoneManager: addSpringBone() is deprecated. use addJoint() instead.`),this.addJoint(e)}deleteJoint(e){this._joints.delete(e),this._objectSpringBonesMap.get(e.bone).delete(e),this._isSortedJointsDirty=!0}deleteSpringBone(e){console.warn(`VRMSpringBoneManager: deleteSpringBone() is deprecated. use deleteJoint() instead.`),this.deleteJoint(e)}setInitState(){this._sortJoints();for(let e=0;e<this._sortedJoints.length;e++){let t=this._sortedJoints[e];t.bone.updateMatrix(),t.bone.updateWorldMatrix(!1,!1),t.setInitState()}}reset(){this._sortJoints();for(let e=0;e<this._sortedJoints.length;e++){let t=this._sortedJoints[e];t.bone.updateMatrix(),t.bone.updateWorldMatrix(!1,!1),t.reset()}}update(e){this._sortJoints();for(let e=0;e<this._ancestors.length;e++)this._ancestors[e].updateWorldMatrix(e===0,!1);for(let t=0;t<this._sortedJoints.length;t++){let n=this._sortedJoints[t];n.bone.updateMatrix(),n.bone.updateWorldMatrix(!1,!1),n.update(e),wS(n.bone,this._relevantChildrenUpdated)}}_sortJoints(){if(!this._isSortedJointsDirty)return;let e=[],t=new Set,n=new Set,r=new Set;for(let i of this._joints)this._insertJointSort(i,t,n,e,r);this._sortedJoints=e;let i=TS(r);this._ancestors=[],i&&(this._ancestors.push(i),wS(i,e=>(this._objectSpringBonesMap.get(e)?.size??0)>0?!0:(this._ancestors.push(e),!1))),this._isSortedJointsDirty=!1}_insertJointSort(e,t,n,r,i){if(n.has(e))return;if(t.has(e)){this._hasWarnedCircularDependency||=(console.warn(`VRMSpringBoneManager: Circular dependency detected`),!0);return}t.add(e);let a=e.dependencies;for(let e of a){let a=!1,o=null;CS(e,e=>{let s=this._objectSpringBonesMap.get(e);if(s)for(let e of s)a=!0,this._insertJointSort(e,t,n,r,i);else a||(o=e)}),o&&i.add(o)}r.push(e),n.add(e)}_relevantChildrenUpdated(e){return(this._objectSpringBonesMap.get(e)?.size??0)>0?!0:(e.updateWorldMatrix(!1,!1),!1)}},DS=`VRMC_springBone_extended_collider`,OS=new Set([`1.0`,`1.0-beta`]),kS=new Set([`1.0`]),AS=class e{get name(){return e.EXTENSION_NAME}constructor(e,t){this.parser=e,this.jointHelperRoot=t?.jointHelperRoot,this.colliderHelperRoot=t?.colliderHelperRoot,this.useExtendedColliders=t?.useExtendedColliders??!0}afterRoot(e){return Kx(this,null,function*(){e.userData.vrmSpringBoneManager=yield this._import(e)})}_import(e){return Kx(this,null,function*(){return(yield this._v1Import(e))??(yield this._v0Import(e))??null})}_v1Import(t){return Kx(this,null,function*(){var n;let r=t.parser.json;if(r.extensionsUsed?.indexOf(e.EXTENSION_NAME)===-1)return null;let i=new ES,a=yield t.parser.getDependencies(`node`),o=r.extensions?.[e.EXTENSION_NAME];if(!o)return null;let s=o.specVersion;if(!OS.has(s))return console.warn(`VRMSpringBoneLoaderPlugin: Unknown ${e.EXTENSION_NAME} specVersion "${s}"`),null;let c=o.colliders?.map((t,n)=>{let r=a[t.node];if(r==null)return console.warn(`VRMSpringBoneLoaderPlugin: The collider #${n} attempted to reference a node #${t.node} but not found. Skipping the collider`),null;let i=t.shape,o=t.extensions?.[DS];if(this.useExtendedColliders&&o!=null){let t=o.specVersion;if(!kS.has(t))console.warn(`VRMSpringBoneLoaderPlugin: Unknown ${DS} specVersion "${t}". Fallbacking to the ${e.EXTENSION_NAME} definition`);else{let e=o.shape;if(e.sphere)return this._importSphereCollider(r,{offset:new U().fromArray(e.sphere.offset??[0,0,0]),radius:e.sphere.radius??0,inside:e.sphere.inside??!1});if(e.capsule)return this._importCapsuleCollider(r,{offset:new U().fromArray(e.capsule.offset??[0,0,0]),radius:e.capsule.radius??0,tail:new U().fromArray(e.capsule.tail??[0,0,0]),inside:e.capsule.inside??!1});if(e.plane)return this._importPlaneCollider(r,{offset:new U().fromArray(e.plane.offset??[0,0,0]),normal:new U().fromArray(e.plane.normal??[0,0,1])})}}if(i.sphere)return this._importSphereCollider(r,{offset:new U().fromArray(i.sphere.offset??[0,0,0]),radius:i.sphere.radius??0,inside:!1});if(i.capsule)return this._importCapsuleCollider(r,{offset:new U().fromArray(i.capsule.offset??[0,0,0]),radius:i.capsule.radius??0,tail:new U().fromArray(i.capsule.tail??[0,0,0]),inside:!1});console.warn(`VRMSpringBoneLoaderPlugin: The collider #${n} has no valid shape. Skipping the collider`)}),l=o.colliderGroups?.map((e,t)=>({colliders:(e.colliders??[]).map(e=>c?.[e]??(console.warn(`VRMSpringBoneLoaderPlugin: The collider group #${t} attempted to reference a collider #${e} but not found. Skipping the collider`),null)).filter(e=>e!=null),name:e.name}));return(n=o.springs)==null||n.forEach((e,t)=>{let n=e.joints,r=e.colliderGroups?.map(e=>l?.[e]??(console.warn(`VRMSpringBoneLoaderPlugin: The spring #${t} attempted to reference a collider group #${e} but not found. Skipping the collider group`),null)).filter(e=>e!=null),o=e.center==null?void 0:a[e.center],s;n.forEach(e=>{if(s){let t=a[s.node],n=a[e.node],c={hitRadius:s.hitRadius,dragForce:s.dragForce,gravityPower:s.gravityPower,stiffness:s.stiffness,gravityDir:s.gravityDir==null?void 0:new U().fromArray(s.gravityDir)},l=this._importJoint(t,n,c,r);o&&(l.center=o),i.addJoint(l)}s=e})}),i.setInitState(),i})}_v0Import(e){return Kx(this,null,function*(){let t=e.parser.json;if(t.extensionsUsed?.indexOf(`VRM`)===-1)return null;let n=t.extensions?.VRM?.secondaryAnimation;if(!n)return null;let r=n?.boneGroups;if(!r)return null;let i=new ES,a=yield e.parser.getDependencies(`node`),o=n.colliderGroups?.map((e,t)=>{let n=a[e.node];return n==null?(console.warn(`VRMSpringBoneLoaderPlugin: The collider group #${t} attempted to reference a node #${e.node} but not found. Skipping the collider group`),null):{colliders:(e.colliders??[]).map((e,t)=>{let r=new U(0,0,0);return e.offset&&r.set(e.offset.x??0,e.offset.y??0,e.offset.z?-e.offset.z:0),this._importSphereCollider(n,{offset:r,radius:e.radius??0,inside:!1})})}});return r?.forEach((e,t)=>{let n=e.bones;n&&n.forEach(n=>{let r=a[n];if(r==null){console.warn(`VRMSpringBoneLoaderPlugin: The spring bone group #${t} attempted to reference a node #${n} but not found. Skipping the node`);return}let s=new U;e.gravityDir?s.set(e.gravityDir.x??0,e.gravityDir.y??0,e.gravityDir.z??0):s.set(0,-1,0);let c=e.center==null?void 0:a[e.center],l={hitRadius:e.hitRadius,dragForce:e.dragForce,gravityPower:e.gravityPower,stiffness:e.stiffiness,gravityDir:s},u=e.colliderGroups?.map(e=>o?.[e]??(console.warn(`VRMSpringBoneLoaderPlugin: The spring #${t} attempted to reference a collider group #${e} but not found. Skipping the collider group`),null)).filter(e=>e!=null);r.traverse(e=>{let t=e.children[0]??null,n=this._importJoint(e,t,l,u);c&&(n.center=c),i.addJoint(n)})})}),e.scene.updateMatrixWorld(),i.setInitState(),i})}_importJoint(e,t,n,r){let i=new SS(e,t,n,r);if(this.jointHelperRoot){let e=new uS(i);this.jointHelperRoot.add(e),e.renderOrder=this.jointHelperRoot.renderOrder}return i}_importSphereCollider(e,t){let n=new dS(new tS(t));if(e.add(n),this.colliderHelperRoot){let e=new sS(n);this.colliderHelperRoot.add(e),e.renderOrder=this.colliderHelperRoot.renderOrder}return n}_importCapsuleCollider(e,t){let n=new dS(new Xx(t));if(e.add(n),this.colliderHelperRoot){let e=new sS(n);this.colliderHelperRoot.add(e),e.renderOrder=this.colliderHelperRoot.renderOrder}return n}_importPlaneCollider(e,t){let n=new dS(new $x(t));if(e.add(n),this.colliderHelperRoot){let e=new sS(n);this.colliderHelperRoot.add(e),e.renderOrder=this.colliderHelperRoot.renderOrder}return n}};AS.EXTENSION_NAME=`VRMC_springBone`;var jS=AS,MS=class{get name(){return`VRMLoaderPlugin`}constructor(e,t){this.parser=e;let n=t?.helperRoot,r=t?.autoUpdateHumanBones;this.expressionPlugin=t?.expressionPlugin??new Oy(e),this.firstPersonPlugin=t?.firstPersonPlugin??new My(e),this.humanoidPlugin=t?.humanoidPlugin??new Zy(e,{helperRoot:n,autoUpdateHumanBones:r}),this.lookAtPlugin=t?.lookAtPlugin??new Nb(e,{helperRoot:n}),this.metaPlugin=t?.metaPlugin??new Ib(e),this.mtoonMaterialPlugin=t?.mtoonMaterialPlugin??new nx(e),this.materialsHDREmissiveMultiplierPlugin=t?.materialsHDREmissiveMultiplierPlugin??new ax(e),this.materialsV0CompatPlugin=t?.materialsV0CompatPlugin??new _x(e),this.springBonePlugin=t?.springBonePlugin??new jS(e,{colliderHelperRoot:n,jointHelperRoot:n}),this.nodeConstraintPlugin=t?.nodeConstraintPlugin??new Gx(e,{helperRoot:n})}beforeRoot(){return cy(this,null,function*(){yield this.materialsV0CompatPlugin.beforeRoot(),yield this.mtoonMaterialPlugin.beforeRoot()})}loadMesh(e){return cy(this,null,function*(){return yield this.mtoonMaterialPlugin.loadMesh(e)})}getMaterialType(e){return this.mtoonMaterialPlugin.getMaterialType(e)??null}extendMaterialParams(e,t){return cy(this,null,function*(){yield this.materialsHDREmissiveMultiplierPlugin.extendMaterialParams(e,t),yield this.mtoonMaterialPlugin.extendMaterialParams(e,t)})}afterRoot(e){return cy(this,null,function*(){yield this.metaPlugin.afterRoot(e),yield this.humanoidPlugin.afterRoot(e),yield this.expressionPlugin.afterRoot(e),yield this.lookAtPlugin.afterRoot(e),yield this.firstPersonPlugin.afterRoot(e),yield this.springBonePlugin.afterRoot(e),yield this.nodeConstraintPlugin.afterRoot(e),yield this.mtoonMaterialPlugin.afterRoot(e);let t=e.userData.vrmMeta,n=e.userData.vrmHumanoid;if(t&&n){let r=new Rb({scene:e.scene,expressionManager:e.userData.vrmExpressionManager,firstPerson:e.userData.vrmFirstPerson,humanoid:n,lookAt:e.userData.vrmLookAt,meta:t,materials:e.userData.vrmMToonMaterials,springBoneManager:e.userData.vrmSpringBoneManager,nodeConstraintManager:e.userData.vrmNodeConstraintManager});e.userData.vrm=r}})}};function NS(e){let t=new Set;return e.traverse(e=>{if(!e.isMesh)return;let n=e;t.add(n)}),t}function PS(e,t,n){if(t.size===1){let n=t.values().next().value;if(n.weight===1)return e[n.index]}let r=new Float32Array(e[0].count*3),i=0;if(n)i=1;else for(let e of t)i+=e.weight;for(let n of t){let t=e[n.index],a=n.weight/i;for(let e=0;e<t.count;e++)r[e*3+0]+=t.getX(e)*a,r[e*3+1]+=t.getY(e)*a,r[e*3+2]+=t.getZ(e)*a}return new q(r,3)}function FS(e){let t=NS(e.scene),n=new Map,r=e.expressionManager?.expressionMap;if(r!=null)for(let[e,t]of Object.entries(r)){let r=new Set;for(let i of t.binds)if(i instanceof Sy){if(i.weight!==0)for(let t of i.primitives){let r=n.get(t);r??(r=new Map,n.set(t,r));let a=r.get(e);a??(a=new Set,r.set(e,a)),a.add(i)}r.add(i)}for(let e of r)t.deleteBind(e)}for(let e of t){let t=n.get(e);if(t==null)continue;let i=e.geometry.morphAttributes;e.geometry.morphAttributes={};let a=e.geometry.clone();e.geometry=a;let o=a.morphTargetsRelative,s=i.position!=null,c=i.normal!=null,l={},u={},d=[];if(s||c){s&&(l.position=[]),c&&(l.normal=[]);let n=0;for(let[a,f]of t)s&&(l.position[n]=PS(i.position,f,o)),c&&(l.normal[n]=PS(i.normal,f,o)),r?.[a].addBind(new Sy({index:n,weight:1,primitives:[e]})),u[a]=n,d.push(0),n++}a.morphAttributes=l,e.morphTargetDictionary=u,e.morphTargetInfluences=d}}function IS(e,t,n){if(e.getComponent)return e.getComponent(t,n);{let r=e.array[t*e.itemSize+n];return e.normalized&&(r=ba.denormalize(r,e.array)),r}}function LS(e,t,n,r){e.setComponent?e.setComponent(t,n,r):(e.normalized&&(r=ba.normalize(r,e.array)),e.array[t*e.itemSize+n]=r)}function RS(e){let t=zS(e),n=new Set;for(let e of t)n.has(e.geometry)&&(e.geometry=KS(e.geometry)),n.add(e.geometry);let r=new Map;for(let e of n){let t=e.getAttribute(`skinIndex`),n=r.get(t)??new Map;r.set(t,n);let i=e.getAttribute(`skinWeight`),a=BS(t,i);n.set(i,a)}let i=new Map;for(let e of t){let t=VS(e,r);i.set(e,t)}let a=[];for(let[e,t]of i){let n=!1;for(let r of a)if(HS(t,r.boneInverseMap)){n=!0,r.meshes.add(e);for(let[e,n]of t)r.boneInverseMap.set(e,n);break}n||a.push({boneInverseMap:t,meshes:new Set([e])})}let o=new Map,s=new GS,c=new GS,l=new GS;for(let e of a){let{boneInverseMap:t,meshes:n}=e,r=Array.from(t.keys()),i=new fc(r,Array.from(t.values())),a=c.getOrCreate(i);for(let e of n){let t=e.geometry.getAttribute(`skinIndex`),n=s.getOrCreate(t),i=e.skeleton.bones,c=`${n};${a};${i.map(e=>l.getOrCreate(e)).join(`,`)}`,u=o.get(c);u??(u=t.clone(),US(u,i,r),o.set(c,u)),e.geometry.setAttribute(`skinIndex`,u)}for(let e of n)e.bind(i,new G)}}function zS(e){let t=new Set;return e.traverse(e=>{if(!e.isSkinnedMesh)return;let n=e;t.add(n)}),t}function BS(e,t){let n=new Set;for(let r=0;r<e.count;r++)for(let i=0;i<e.itemSize;i++){let a=IS(e,r,i);IS(t,r,i)!==0&&n.add(a)}return n}function VS(e,t){let n=new Map,r=e.skeleton,i=e.geometry,a=i.getAttribute(`skinIndex`),o=i.getAttribute(`skinWeight`),s=t.get(a)?.get(o);if(!s)throw Error(`Unreachable. attributeUsedIndexSetMap does not know the skin index attribute or the skin weight attribute.`);for(let e of s)n.set(r.bones[e],r.boneInverses[e]);return n}function HS(e,t){for(let[n,r]of e.entries()){let e=t.get(n);if(e!=null&&!WS(r,e))return!1}return!0}function US(e,t,n){let r=new Map;for(let e of t)r.set(e,r.size);let i=new Map;for(let[e,t]of n.entries()){let n=r.get(t);i.set(n,e)}for(let t=0;t<e.count;t++)for(let n=0;n<e.itemSize;n++){let r=IS(e,t,n),a=i.get(r);LS(e,t,n,a)}e.needsUpdate=!0}function WS(e,t,n){if(n||=1e-4,e.elements.length!=t.elements.length)return!1;for(let r=0,i=e.elements.length;r<i;r++)if(Math.abs(e.elements[r]-t.elements[r])>n)return!1;return!0}var GS=class{constructor(){this._objectIndexMap=new Map,this._index=0}get(e){return this._objectIndexMap.get(e)}getOrCreate(e){let t=this._objectIndexMap.get(e);return t??(t=this._index,this._objectIndexMap.set(e,t),this._index++),t}};function KS(e){let t=new J;t.name=e.name,t.setIndex(e.index);for(let[n,r]of Object.entries(e.attributes))t.setAttribute(n,r);for(let[n,r]of Object.entries(e.morphAttributes)){let e=n;t.morphAttributes[e]=r.concat()}t.morphTargetsRelative=e.morphTargetsRelative,t.groups=[];for(let n of e.groups)t.addGroup(n.start,n.count,n.materialIndex);return t.boundingSphere=e.boundingSphere?.clone()??null,t.boundingBox=e.boundingBox?.clone()??null,t.drawRange.start=e.drawRange.start,t.drawRange.count=e.drawRange.count,t.userData=e.userData,t}function qS(e){if(Object.values(e).forEach(e=>{e?.isTexture&&e.dispose()}),e.isShaderMaterial){let t=e.uniforms;t&&Object.values(t).forEach(e=>{let t=e.value;t?.isTexture&&t.dispose()})}e.dispose()}function JS(e){let t=e.geometry;t&&t.dispose();let n=e.skeleton;n&&n.dispose();let r=e.material;r&&(Array.isArray(r)?r.forEach(e=>qS(e)):r&&qS(r))}function YS(e){e.traverse(JS)}function XS(e,t){console.warn(`VRMUtils.removeUnnecessaryJoints: removeUnnecessaryJoints is deprecated. Use combineSkeletons instead. combineSkeletons contributes more to the performance improvement. This function will be removed in the next major version.`);let n=t?.experimentalSameBoneCounts??!1,r=[];e.traverse(e=>{e.type===`SkinnedMesh`&&r.push(e)});let i=new Map,a=0;for(let e of r){let t=e.geometry.getAttribute(`skinIndex`);if(i.has(t))continue;let n=new Map,r=new Map;for(let e=0;e<t.count;e++)for(let i=0;i<t.itemSize;i++){let a=IS(t,e,i),o=n.get(a);o??(o=n.size,n.set(a,o),r.set(o,a)),LS(t,e,i,o)}t.needsUpdate=!0,i.set(t,r),a=Math.max(a,n.size)}for(let e of r){let t=e.geometry.getAttribute(`skinIndex`),r=i.get(t),o=[],s=[],c=n?a:r.size;for(let t=0;t<c;t++){let n=r.get(t)??0;o.push(e.skeleton.bones[n]),s.push(e.skeleton.boneInverses[n])}let l=new fc(o,s);e.bind(l,new G)}}function ZS(e,t){let n=e.position.count,r=Array(n),i=0,a=t.array;for(let e=0;e<a.length;e++){let t=a[e];r[t]||(r[t]=!0,i++)}return{isVertexUsed:r,vertexCount:n,verticesUsed:i}}function QS(e){let t=[],n=[],r=0;for(let i=0;i<e.length;i++)if(e[i]){let e=r++;t[i]=e,n[e]=i}return{originalIndexNewIndexMap:t,newIndexOriginalIndexMap:n}}function $S(e,t){t.name=e.name,t.morphTargetsRelative=e.morphTargetsRelative,e.groups.forEach(e=>{t.addGroup(e.start,e.count,e.materialIndex)}),t.boundingBox=e.boundingBox?.clone()??null,t.boundingSphere=e.boundingSphere?.clone()??null,t.setDrawRange(e.drawRange.start,e.drawRange.count),t.userData=e.userData}function eC(e,t,n){let r=t.array,i=new r.constructor(r.length);for(let e=0;e<r.length;e++)i[e]=n[r[e]];e.setIndex(new q(i,t.itemSize,t.normalized))}function tC(e,t,n){let r=e.constructor,i=new r(t.length*n),a=!0;for(let r=0;r<t.length;r++){let o=t[r]*n,s=r*n;for(let t=0;t<n;t++){let n=e[o+t];i[s+t]=n,a&&=n===0}}return[i,a]}function nC(e){let t=new Map,n=[];for(let[r,i]of Object.entries(e))if(i.isInterleavedBufferAttribute){let e=i,n=e.data,a=t.get(n)??[];t.set(n,a),a.push([r,e])}else{let e=i;n.push([r,e])}return[t,n]}function rC(e,t,n){let[r,i]=nC(t);for(let[t,i]of r){let r=t.array,{stride:a}=t,[o,s]=tC(r,n,a),c=new ws(o,a);c.setUsage(t.usage);for(let[t,n]of i){let{itemSize:r,offset:i,normalized:a}=n,o=new Es(c,r,i,a);e.setAttribute(t,o)}}for(let[t,r]of i){let i=r.array,{itemSize:a,normalized:o}=r,[s,c]=tC(i,n,a);e.setAttribute(t,new q(s,a,o))}}function iC(e){let t=new Map,n=[];for(let[r,i]of Object.entries(e)){let e=r;for(let r=0;r<i.length;r++){let a=i[r];if(a.isInterleavedBufferAttribute){let n=a,i=n.data,o=t.get(i)??[];t.set(i,o),o.push([e,r,n])}else{let t=a;n.push([e,r,t])}}}return[t,n]}function aC(e,t,n){let r=!0,[i,a]=iC(t),o={};for(let[e,t]of i){let i=e.array,{stride:a}=e,[s,c]=tC(i,n,a);r&&=c;let l=new ws(s,a);l.setUsage(e.usage);for(let[e,n,r]of t){let{itemSize:t,offset:i,normalized:a}=r,s=new Es(l,t,i,a);o[e]??(o[e]=[]),o[e][n]=s}}for(let[e,t,i]of a){let a=i,s=a.array,{itemSize:c,normalized:l}=a,[u,d]=tC(s,n,c);r&&=d,o[e]??(o[e]=[]),o[e][t]=new q(u,c,l)}e.morphAttributes=r?{}:o}function oC(e){let t=new Map;e.traverse(e=>{if(!e.isMesh)return;let n=e,r=n.geometry,i=r.index;if(i==null)return;let a=t.get(r);if(a!=null){n.geometry=a;return}let{isVertexUsed:o,vertexCount:s,verticesUsed:c}=ZS(r.attributes,i);if(c===s)return;let{originalIndexNewIndexMap:l,newIndexOriginalIndexMap:u}=QS(o),d=new J;$S(r,d),t.set(r,d),eC(d,i,l),rC(d,r.attributes,u),aC(d,r.morphAttributes,u),n.geometry=d}),Array.from(t.keys()).forEach(e=>{e.dispose()})}function sC(e){e.meta?.metaVersion===`0`&&(e.scene.rotation.y=Math.PI)}var cC=class{constructor(){}};cC.combineMorphs=FS,cC.combineSkeletons=RS,cC.deepDispose=YS,cC.removeUnnecessaryJoints=XS,cC.removeUnnecessaryVertices=oC,cC.rotateVRM0=sC;function lC(e,t){if(t===0)return console.warn(`THREE.BufferGeometryUtils.toTrianglesDrawMode(): Geometry already defined as triangles.`),e;if(t===2||t===1){let n=e.getIndex();if(n===null){let t=[],r=e.getAttribute(`position`);if(r!==void 0){for(let e=0;e<r.count;e++)t.push(e);e.setIndex(t),n=e.getIndex()}else return console.error(`THREE.BufferGeometryUtils.toTrianglesDrawMode(): Undefined position attribute. Processing not possible.`),e}let r=n.count-2,i=[];if(t===2)for(let e=1;e<=r;e++)i.push(n.getX(0)),i.push(n.getX(e)),i.push(n.getX(e+1));else for(let e=0;e<r;e++)e%2==0?(i.push(n.getX(e)),i.push(n.getX(e+1)),i.push(n.getX(e+2))):(i.push(n.getX(e+2)),i.push(n.getX(e+1)),i.push(n.getX(e)));i.length/3!==r&&console.error(`THREE.BufferGeometryUtils.toTrianglesDrawMode(): Unable to generate correct amount of triangles.`);let a=e.clone();return a.setIndex(i),a.clearGroups(),a}else return console.error(`THREE.BufferGeometryUtils.toTrianglesDrawMode(): Unknown draw mode:`,t),e}function uC(e){let t=new Map,n=new Map,r=e.clone();return dC(e,r,function(e,r){t.set(r,e),n.set(e,r)}),r.traverse(function(e){if(!e.isSkinnedMesh)return;let r=e,i=t.get(e),a=i.skeleton.bones;r.skeleton=i.skeleton.clone(),r.bindMatrix.copy(i.bindMatrix),r.skeleton.bones=a.map(function(e){return n.get(e)}),r.bind(r.skeleton,r.bindMatrix)}),r}function dC(e,t,n){n(e,t);for(let r=0;r<e.children.length;r++)dC(e.children[r],t.children[r],n)}var fC=class extends ql{constructor(e){super(e),this.dracoLoader=null,this.ktx2Loader=null,this.meshoptDecoder=null,this.pluginCallbacks=[],this.register(function(e){return new yC(e)}),this.register(function(e){return new bC(e)}),this.register(function(e){return new kC(e)}),this.register(function(e){return new AC(e)}),this.register(function(e){return new jC(e)}),this.register(function(e){return new SC(e)}),this.register(function(e){return new CC(e)}),this.register(function(e){return new wC(e)}),this.register(function(e){return new TC(e)}),this.register(function(e){return new vC(e)}),this.register(function(e){return new EC(e)}),this.register(function(e){return new xC(e)}),this.register(function(e){return new OC(e)}),this.register(function(e){return new DC(e)}),this.register(function(e){return new gC(e)}),this.register(function(e){return new MC(e,hC.EXT_MESHOPT_COMPRESSION)}),this.register(function(e){return new MC(e,hC.KHR_MESHOPT_COMPRESSION)}),this.register(function(e){return new NC(e)})}load(e,t,n,r){let i=this,a;if(this.resourcePath!==``)a=this.resourcePath;else if(this.path!==``){let t=Su.extractUrlBase(e);a=Su.resolveURL(t,this.path)}else a=Su.extractUrlBase(e);this.manager.itemStart(e);let o=function(t){r?r(t):console.error(t),i.manager.itemError(e),i.manager.itemEnd(e)},s=new Xl(this.manager);s.setPath(this.path),s.setResponseType(`arraybuffer`),s.setRequestHeader(this.requestHeader),s.setWithCredentials(this.withCredentials),s.load(e,function(n){try{i.parse(n,a,function(n){t(n),i.manager.itemEnd(e)},o)}catch(e){o(e)}},n,o)}setDRACOLoader(e){return this.dracoLoader=e,this}setKTX2Loader(e){return this.ktx2Loader=e,this}setMeshoptDecoder(e){return this.meshoptDecoder=e,this}register(e){return this.pluginCallbacks.indexOf(e)===-1&&this.pluginCallbacks.push(e),this}unregister(e){return this.pluginCallbacks.indexOf(e)!==-1&&this.pluginCallbacks.splice(this.pluginCallbacks.indexOf(e),1),this}parse(e,t,n,r){let i,a={},o={},s=new TextDecoder;if(typeof e==`string`)i=JSON.parse(e);else if(e instanceof ArrayBuffer)if(s.decode(new Uint8Array(e,0,4))===PC){try{a[hC.KHR_BINARY_GLTF]=new LC(e)}catch(e){r&&r(e);return}i=JSON.parse(a[hC.KHR_BINARY_GLTF].content)}else i=JSON.parse(s.decode(e));else i=e;if(i.asset===void 0||i.asset.version[0]<2){r&&r(Error(`THREE.GLTFLoader: Unsupported asset. glTF versions >=2.0 are supported.`));return}let c=new lw(i,{path:t||this.resourcePath||``,crossOrigin:this.crossOrigin,requestHeader:this.requestHeader,manager:this.manager,ktx2Loader:this.ktx2Loader,meshoptDecoder:this.meshoptDecoder});c.fileLoader.setRequestHeader(this.requestHeader);for(let e=0;e<this.pluginCallbacks.length;e++){let t=this.pluginCallbacks[e](c);t.name||console.error(`THREE.GLTFLoader: Invalid plugin found: missing name`),o[t.name]=t,a[t.name]=!0}if(i.extensionsUsed)for(let e=0;e<i.extensionsUsed.length;++e){let t=i.extensionsUsed[e],n=i.extensionsRequired||[];switch(t){case hC.KHR_MATERIALS_UNLIT:a[t]=new _C;break;case hC.KHR_DRACO_MESH_COMPRESSION:a[t]=new RC(i,this.dracoLoader);break;case hC.KHR_TEXTURE_TRANSFORM:a[t]=new zC;break;case hC.KHR_MESH_QUANTIZATION:a[t]=new BC;break;default:n.indexOf(t)>=0&&o[t]===void 0&&console.warn(`THREE.GLTFLoader: Unknown extension "`+t+`".`)}}c.setExtensions(a),c.setPlugins(o),c.parse(n,r)}parseAsync(e,t){let n=this;return new Promise(function(r,i){n.parse(e,t,r,i)})}};function pC(){let e={};return{get:function(t){return e[t]},add:function(t,n){e[t]=n},remove:function(t){delete e[t]},removeAll:function(){e={}}}}function mC(e,t,n){let r=e.json.materials[t];return r.extensions&&r.extensions[n]?r.extensions[n]:null}var hC={KHR_BINARY_GLTF:`KHR_binary_glTF`,KHR_DRACO_MESH_COMPRESSION:`KHR_draco_mesh_compression`,KHR_LIGHTS_PUNCTUAL:`KHR_lights_punctual`,KHR_MATERIALS_CLEARCOAT:`KHR_materials_clearcoat`,KHR_MATERIALS_DISPERSION:`KHR_materials_dispersion`,KHR_MATERIALS_IOR:`KHR_materials_ior`,KHR_MATERIALS_SHEEN:`KHR_materials_sheen`,KHR_MATERIALS_SPECULAR:`KHR_materials_specular`,KHR_MATERIALS_TRANSMISSION:`KHR_materials_transmission`,KHR_MATERIALS_IRIDESCENCE:`KHR_materials_iridescence`,KHR_MATERIALS_ANISOTROPY:`KHR_materials_anisotropy`,KHR_MATERIALS_UNLIT:`KHR_materials_unlit`,KHR_MATERIALS_VOLUME:`KHR_materials_volume`,KHR_TEXTURE_BASISU:`KHR_texture_basisu`,KHR_TEXTURE_TRANSFORM:`KHR_texture_transform`,KHR_MESH_QUANTIZATION:`KHR_mesh_quantization`,KHR_MATERIALS_EMISSIVE_STRENGTH:`KHR_materials_emissive_strength`,EXT_MATERIALS_BUMP:`EXT_materials_bump`,EXT_TEXTURE_WEBP:`EXT_texture_webp`,EXT_TEXTURE_AVIF:`EXT_texture_avif`,EXT_MESHOPT_COMPRESSION:`EXT_meshopt_compression`,KHR_MESHOPT_COMPRESSION:`KHR_meshopt_compression`,EXT_MESH_GPU_INSTANCING:`EXT_mesh_gpu_instancing`},gC=class{constructor(e){this.parser=e,this.name=hC.KHR_LIGHTS_PUNCTUAL,this.cache={refs:{},uses:{}}}_markDefs(){let e=this.parser,t=this.parser.json.nodes||[];for(let n=0,r=t.length;n<r;n++){let r=t[n];r.extensions&&r.extensions[this.name]&&r.extensions[this.name].light!==void 0&&e._addNodeRef(this.cache,r.extensions[this.name].light)}}_loadLight(e){let t=this.parser,n=`light:`+e,r=t.cache.get(n);if(r)return r;let i=t.json,a=((i.extensions&&i.extensions[this.name]||{}).lights||[])[e],o,s=new K(16777215);a.color!==void 0&&s.setRGB(a.color[0],a.color[1],a.color[2],ki);let c=a.range===void 0?0:a.range;switch(a.type){case`directional`:o=new bu(s),o.target.position.set(0,0,-1),o.add(o.target);break;case`point`:o=new _u(s),o.distance=c;break;case`spot`:o=new hu(s),o.distance=c,a.spot=a.spot||{},a.spot.innerConeAngle=a.spot.innerConeAngle===void 0?0:a.spot.innerConeAngle,a.spot.outerConeAngle=a.spot.outerConeAngle===void 0?Math.PI/4:a.spot.outerConeAngle,o.angle=a.spot.outerConeAngle,o.penumbra=1-a.spot.innerConeAngle/a.spot.outerConeAngle,o.target.position.set(0,0,-1),o.add(o.target);break;default:throw Error(`THREE.GLTFLoader: Unexpected light type: `+a.type)}return o.position.set(0,0,0),tw(o,a),a.intensity!==void 0&&(o.intensity=a.intensity),o.name=t.createUniqueName(a.name||`light_`+e),r=Promise.resolve(o),t.cache.add(n,r),r}getDependency(e,t){if(e===`light`)return this._loadLight(t)}createNodeAttachment(e){let t=this,n=this.parser,r=n.json.nodes[e],i=(r.extensions&&r.extensions[this.name]||{}).light;return i===void 0?null:this._loadLight(i).then(function(e){return n._getNodeRef(t.cache,i,e)})}},_C=class{constructor(){this.name=hC.KHR_MATERIALS_UNLIT}getMaterialType(){return Ls}extendParams(e,t,n){let r=[];e.color=new K(1,1,1),e.opacity=1;let i=t.pbrMetallicRoughness;if(i){if(Array.isArray(i.baseColorFactor)){let t=i.baseColorFactor;e.color.setRGB(t[0],t[1],t[2],ki),e.opacity=t[3]}i.baseColorTexture!==void 0&&r.push(n.assignTexture(e,`map`,i.baseColorTexture,Oi))}return Promise.all(r)}},vC=class{constructor(e){this.parser=e,this.name=hC.KHR_MATERIALS_EMISSIVE_STRENGTH}extendMaterialParams(e,t){let n=mC(this.parser,e,this.name);return n===null||n.emissiveStrength!==void 0&&(t.emissiveIntensity=n.emissiveStrength),Promise.resolve()}},yC=class{constructor(e){this.parser=e,this.name=hC.KHR_MATERIALS_CLEARCOAT}getMaterialType(e){return mC(this.parser,e,this.name)===null?null:xl}extendMaterialParams(e,t){let n=mC(this.parser,e,this.name);if(n===null)return Promise.resolve();let r=[];if(n.clearcoatFactor!==void 0&&(t.clearcoat=n.clearcoatFactor),n.clearcoatTexture!==void 0&&r.push(this.parser.assignTexture(t,`clearcoatMap`,n.clearcoatTexture)),n.clearcoatRoughnessFactor!==void 0&&(t.clearcoatRoughness=n.clearcoatRoughnessFactor),n.clearcoatRoughnessTexture!==void 0&&r.push(this.parser.assignTexture(t,`clearcoatRoughnessMap`,n.clearcoatRoughnessTexture)),n.clearcoatNormalTexture!==void 0&&(r.push(this.parser.assignTexture(t,`clearcoatNormalMap`,n.clearcoatNormalTexture)),n.clearcoatNormalTexture.scale!==void 0)){let e=n.clearcoatNormalTexture.scale;t.clearcoatNormalScale=new V(e,e)}return Promise.all(r)}},bC=class{constructor(e){this.parser=e,this.name=hC.KHR_MATERIALS_DISPERSION}getMaterialType(e){return mC(this.parser,e,this.name)===null?null:xl}extendMaterialParams(e,t){let n=mC(this.parser,e,this.name);return n===null||(t.dispersion=n.dispersion===void 0?0:n.dispersion),Promise.resolve()}},xC=class{constructor(e){this.parser=e,this.name=hC.KHR_MATERIALS_IRIDESCENCE}getMaterialType(e){return mC(this.parser,e,this.name)===null?null:xl}extendMaterialParams(e,t){let n=mC(this.parser,e,this.name);if(n===null)return Promise.resolve();let r=[];return n.iridescenceFactor!==void 0&&(t.iridescence=n.iridescenceFactor),n.iridescenceTexture!==void 0&&r.push(this.parser.assignTexture(t,`iridescenceMap`,n.iridescenceTexture)),n.iridescenceIor!==void 0&&(t.iridescenceIOR=n.iridescenceIor),t.iridescenceThicknessRange===void 0&&(t.iridescenceThicknessRange=[100,400]),n.iridescenceThicknessMinimum!==void 0&&(t.iridescenceThicknessRange[0]=n.iridescenceThicknessMinimum),n.iridescenceThicknessMaximum!==void 0&&(t.iridescenceThicknessRange[1]=n.iridescenceThicknessMaximum),n.iridescenceThicknessTexture!==void 0&&r.push(this.parser.assignTexture(t,`iridescenceThicknessMap`,n.iridescenceThicknessTexture)),Promise.all(r)}},SC=class{constructor(e){this.parser=e,this.name=hC.KHR_MATERIALS_SHEEN}getMaterialType(e){return mC(this.parser,e,this.name)===null?null:xl}extendMaterialParams(e,t){let n=mC(this.parser,e,this.name);if(n===null)return Promise.resolve();let r=[];if(t.sheenColor=new K(0,0,0),t.sheenRoughness=0,t.sheen=1,n.sheenColorFactor!==void 0){let e=n.sheenColorFactor;t.sheenColor.setRGB(e[0],e[1],e[2],ki)}return n.sheenRoughnessFactor!==void 0&&(t.sheenRoughness=n.sheenRoughnessFactor),n.sheenColorTexture!==void 0&&r.push(this.parser.assignTexture(t,`sheenColorMap`,n.sheenColorTexture,Oi)),n.sheenRoughnessTexture!==void 0&&r.push(this.parser.assignTexture(t,`sheenRoughnessMap`,n.sheenRoughnessTexture)),Promise.all(r)}},CC=class{constructor(e){this.parser=e,this.name=hC.KHR_MATERIALS_TRANSMISSION}getMaterialType(e){return mC(this.parser,e,this.name)===null?null:xl}extendMaterialParams(e,t){let n=mC(this.parser,e,this.name);if(n===null)return Promise.resolve();let r=[];return n.transmissionFactor!==void 0&&(t.transmission=n.transmissionFactor),n.transmissionTexture!==void 0&&r.push(this.parser.assignTexture(t,`transmissionMap`,n.transmissionTexture)),Promise.all(r)}},wC=class{constructor(e){this.parser=e,this.name=hC.KHR_MATERIALS_VOLUME}getMaterialType(e){return mC(this.parser,e,this.name)===null?null:xl}extendMaterialParams(e,t){let n=mC(this.parser,e,this.name);if(n===null)return Promise.resolve();let r=[];t.thickness=n.thicknessFactor===void 0?0:n.thicknessFactor,n.thicknessTexture!==void 0&&r.push(this.parser.assignTexture(t,`thicknessMap`,n.thicknessTexture)),t.attenuationDistance=n.attenuationDistance||1/0;let i=n.attenuationColor||[1,1,1];return t.attenuationColor=new K().setRGB(i[0],i[1],i[2],ki),Promise.all(r)}},TC=class{constructor(e){this.parser=e,this.name=hC.KHR_MATERIALS_IOR}getMaterialType(e){return mC(this.parser,e,this.name)===null?null:xl}extendMaterialParams(e,t){let n=mC(this.parser,e,this.name);return n===null?Promise.resolve():(t.ior=n.ior===void 0?1.5:n.ior,t.ior===0&&(t.ior=1e3),Promise.resolve())}},EC=class{constructor(e){this.parser=e,this.name=hC.KHR_MATERIALS_SPECULAR}getMaterialType(e){return mC(this.parser,e,this.name)===null?null:xl}extendMaterialParams(e,t){let n=mC(this.parser,e,this.name);if(n===null)return Promise.resolve();let r=[];t.specularIntensity=n.specularFactor===void 0?1:n.specularFactor,n.specularTexture!==void 0&&r.push(this.parser.assignTexture(t,`specularIntensityMap`,n.specularTexture));let i=n.specularColorFactor||[1,1,1];return t.specularColor=new K().setRGB(i[0],i[1],i[2],ki),n.specularColorTexture!==void 0&&r.push(this.parser.assignTexture(t,`specularColorMap`,n.specularColorTexture,Oi)),Promise.all(r)}},DC=class{constructor(e){this.parser=e,this.name=hC.EXT_MATERIALS_BUMP}getMaterialType(e){return mC(this.parser,e,this.name)===null?null:xl}extendMaterialParams(e,t){let n=mC(this.parser,e,this.name);if(n===null)return Promise.resolve();let r=[];return t.bumpScale=n.bumpFactor===void 0?1:n.bumpFactor,n.bumpTexture!==void 0&&r.push(this.parser.assignTexture(t,`bumpMap`,n.bumpTexture)),Promise.all(r)}},OC=class{constructor(e){this.parser=e,this.name=hC.KHR_MATERIALS_ANISOTROPY}getMaterialType(e){return mC(this.parser,e,this.name)===null?null:xl}extendMaterialParams(e,t){let n=mC(this.parser,e,this.name);if(n===null)return Promise.resolve();let r=[];return n.anisotropyStrength!==void 0&&(t.anisotropy=n.anisotropyStrength),n.anisotropyRotation!==void 0&&(t.anisotropyRotation=n.anisotropyRotation),n.anisotropyTexture!==void 0&&r.push(this.parser.assignTexture(t,`anisotropyMap`,n.anisotropyTexture)),Promise.all(r)}},kC=class{constructor(e){this.parser=e,this.name=hC.KHR_TEXTURE_BASISU}loadTexture(e){let t=this.parser,n=t.json,r=n.textures[e];if(!r.extensions||!r.extensions[this.name])return null;let i=r.extensions[this.name],a=t.options.ktx2Loader;if(!a){if(n.extensionsRequired&&n.extensionsRequired.indexOf(this.name)>=0)throw Error(`THREE.GLTFLoader: setKTX2Loader must be called before loading KTX2 textures`);return null}return t.loadTextureImage(e,i.source,a)}},AC=class{constructor(e){this.parser=e,this.name=hC.EXT_TEXTURE_WEBP}loadTexture(e){let t=this.name,n=this.parser,r=n.json,i=r.textures[e];if(!i.extensions||!i.extensions[t])return null;let a=i.extensions[t],o=r.images[a.source],s=n.textureLoader;if(o.uri){let e=n.options.manager.getHandler(o.uri);e!==null&&(s=e)}return n.loadTextureImage(e,a.source,s)}},jC=class{constructor(e){this.parser=e,this.name=hC.EXT_TEXTURE_AVIF}loadTexture(e){let t=this.name,n=this.parser,r=n.json,i=r.textures[e];if(!i.extensions||!i.extensions[t])return null;let a=i.extensions[t],o=r.images[a.source],s=n.textureLoader;if(o.uri){let e=n.options.manager.getHandler(o.uri);e!==null&&(s=e)}return n.loadTextureImage(e,a.source,s)}},MC=class{constructor(e,t){this.name=t,this.parser=e}loadBufferView(e){let t=this.parser.json,n=t.bufferViews[e];if(n.extensions&&n.extensions[this.name]){let e=n.extensions[this.name],r=this.parser.getDependency(`buffer`,e.buffer),i=this.parser.options.meshoptDecoder;if(!i||!i.supported){if(t.extensionsRequired&&t.extensionsRequired.indexOf(this.name)>=0)throw Error(`THREE.GLTFLoader: setMeshoptDecoder must be called before loading compressed files`);return null}return r.then(function(t){let n=e.byteOffset||0,r=e.byteLength||0,a=e.count,o=e.byteStride,s=new Uint8Array(t,n,r);return i.decodeGltfBufferAsync?i.decodeGltfBufferAsync(a,o,s,e.mode,e.filter).then(function(e){return e.buffer}):i.ready.then(function(){let t=new ArrayBuffer(a*o);return i.decodeGltfBuffer(new Uint8Array(t),a,o,s,e.mode,e.filter),t})})}else return null}},NC=class{constructor(e){this.name=hC.EXT_MESH_GPU_INSTANCING,this.parser=e}createNodeMesh(e){let t=this.parser.json,n=t.nodes[e];if(!n.extensions||!n.extensions[this.name]||n.mesh===void 0)return null;let r=t.meshes[n.mesh];for(let e of r.primitives)if(e.mode!==WC.TRIANGLES&&e.mode!==WC.TRIANGLE_STRIP&&e.mode!==WC.TRIANGLE_FAN&&e.mode!==void 0)return null;let i=n.extensions[this.name].attributes,a=[],o={};for(let e in i)a.push(this.parser.getDependency(`accessor`,i[e]).then(t=>(o[e]=t,o[e])));return a.length<1?null:(a.push(this.parser.createNodeMesh(e)),Promise.all(a).then(e=>{let t=e.pop(),n=t.isGroup?t.children:[t],r=e[0].count,i=[];for(let e of n){let t=new G,n=new U,a=new H,s=new U(1,1,1),c=new xc(e.geometry,e.material,r);for(let e=0;e<r;e++)o.TRANSLATION&&n.fromBufferAttribute(o.TRANSLATION,e),o.ROTATION&&a.fromBufferAttribute(o.ROTATION,e),o.SCALE&&s.fromBufferAttribute(o.SCALE,e),c.setMatrixAt(e,t.compose(n,a,s));for(let t in o)if(t===`_COLOR_0`){let e=o[t];c.instanceColor=new pc(e.array,e.itemSize,e.normalized)}else t!==`TRANSLATION`&&t!==`ROTATION`&&t!==`SCALE`&&e.geometry.setAttribute(t,o[t]);go.prototype.copy.call(c,e),this.parser.assignFinalMaterial(c),i.push(c)}return t.isGroup?(t.clear(),t.add(...i),t):i[0]}))}},PC=`glTF`,FC=12,IC={JSON:1313821514,BIN:5130562},LC=class{constructor(e){this.name=hC.KHR_BINARY_GLTF,this.content=null,this.body=null;let t=new DataView(e,0,FC),n=new TextDecoder;if(this.header={magic:n.decode(new Uint8Array(e.slice(0,4))),version:t.getUint32(4,!0),length:t.getUint32(8,!0)},this.header.magic!==PC)throw Error(`THREE.GLTFLoader: Unsupported glTF-Binary header.`);if(this.header.version<2)throw Error(`THREE.GLTFLoader: Legacy binary file detected.`);let r=this.header.length-FC,i=new DataView(e,FC),a=0;for(;a<r;){let t=i.getUint32(a,!0);a+=4;let r=i.getUint32(a,!0);if(a+=4,r===IC.JSON){let r=new Uint8Array(e,FC+a,t);this.content=n.decode(r)}else if(r===IC.BIN){let n=FC+a;this.body=e.slice(n,n+t)}a+=t}if(this.content===null)throw Error(`THREE.GLTFLoader: JSON content not found.`)}},RC=class{constructor(e,t){if(!t)throw Error(`THREE.GLTFLoader: No DRACOLoader instance provided.`);this.name=hC.KHR_DRACO_MESH_COMPRESSION,this.json=e,this.dracoLoader=t,this.dracoLoader.preload()}decodePrimitive(e,t){let n=this.json,r=this.dracoLoader,i=e.extensions[this.name].bufferView,a=e.extensions[this.name].attributes,o={},s={},c={};for(let e in a){let t=YC[e]||e.toLowerCase();o[t]=a[e]}for(let t in e.attributes){let r=YC[t]||t.toLowerCase();if(a[t]!==void 0){let i=n.accessors[e.attributes[t]];c[r]=GC[i.componentType].name,s[r]=i.normalized===!0}}return t.getDependency(`bufferView`,i).then(function(e){return new Promise(function(t,n){r.decodeDracoFile(e,function(e){for(let t in e.attributes){let n=e.attributes[t],r=s[t];r!==void 0&&(n.normalized=r)}t(e)},o,c,ki,n)})})}},zC=class{constructor(){this.name=hC.KHR_TEXTURE_TRANSFORM}extendTexture(e,t){return(t.texCoord===void 0||t.texCoord===e.channel)&&t.offset===void 0&&t.rotation===void 0&&t.scale===void 0?e:(e=e.clone(),t.texCoord!==void 0&&(e.channel=t.texCoord),t.offset!==void 0&&e.offset.fromArray(t.offset),t.rotation!==void 0&&(e.rotation=t.rotation),t.scale!==void 0&&e.repeat.fromArray(t.scale),e.needsUpdate=!0,e)}},BC=class{constructor(){this.name=hC.KHR_MESH_QUANTIZATION}},VC=class extends Ol{constructor(e,t,n,r){super(e,t,n,r)}copySampleValue_(e){let t=this.resultBuffer,n=this.sampleValues,r=this.valueSize,i=e*r*3+r;for(let e=0;e!==r;e++)t[e]=n[i+e];return t}interpolate_(e,t,n,r){let i=this.resultBuffer,a=this.sampleValues,o=this.valueSize,s=o*2,c=o*3,l=r-t,u=(n-t)/l,d=u*u,f=d*u,p=e*c,m=p-c,h=-2*f+3*d,g=f-d,_=1-h,v=g-d+u;for(let e=0;e!==o;e++){let t=a[m+e+o],n=a[m+e+s]*l,r=a[p+e+o],c=a[p+e]*l;i[e]=_*t+v*n+h*r+g*c}return i}},HC=new H,UC=class extends VC{interpolate_(e,t,n,r){let i=super.interpolate_(e,t,n,r);return HC.fromArray(i).normalize().toArray(i),i}},WC={FLOAT:5126,FLOAT_MAT3:35675,FLOAT_MAT4:35676,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,LINEAR:9729,REPEAT:10497,SAMPLER_2D:35678,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,UNSIGNED_BYTE:5121,UNSIGNED_SHORT:5123},GC={5120:Int8Array,5121:Uint8Array,5122:Int16Array,5123:Uint16Array,5125:Uint32Array,5126:Float32Array},KC={9728:rr,9729:or,9984:ir,9985:sr,9986:ar,9987:cr},qC={33071:tr,33648:nr,10497:er},JC={SCALAR:1,VEC2:2,VEC3:3,VEC4:4,MAT2:4,MAT3:9,MAT4:16},YC={POSITION:`position`,NORMAL:`normal`,TANGENT:`tangent`,TEXCOORD_0:`uv`,TEXCOORD_1:`uv1`,TEXCOORD_2:`uv2`,TEXCOORD_3:`uv3`,COLOR_0:`color`,WEIGHTS_0:`skinWeight`,JOINTS_0:`skinIndex`},XC={scale:`scale`,translation:`position`,rotation:`quaternion`,weights:`morphTargetInfluences`},ZC={CUBICSPLINE:void 0,LINEAR:vi,STEP:_i},QC={OPAQUE:`OPAQUE`,MASK:`MASK`,BLEND:`BLEND`};function $C(e){return e.DefaultMaterial===void 0&&(e.DefaultMaterial=new bl({color:16777215,emissive:0,metalness:1,roughness:1,transparent:!1,depthTest:!0,side:0})),e.DefaultMaterial}function ew(e,t,n){for(let r in n.extensions)e[r]===void 0&&(t.userData.gltfExtensions=t.userData.gltfExtensions||{},t.userData.gltfExtensions[r]=n.extensions[r])}function tw(e,t){t.extras!==void 0&&(typeof t.extras==`object`?Object.assign(e.userData,t.extras):console.warn(`THREE.GLTFLoader: Ignoring primitive type .extras, `+t.extras))}function nw(e,t,n){let r=!1,i=!1,a=!1;for(let e=0,n=t.length;e<n;e++){let n=t[e];if(n.POSITION!==void 0&&(r=!0),n.NORMAL!==void 0&&(i=!0),n.COLOR_0!==void 0&&(a=!0),r&&i&&a)break}if(!r&&!i&&!a)return Promise.resolve(e);let o=[],s=[],c=[];for(let l=0,u=t.length;l<u;l++){let u=t[l];if(r){let t=u.POSITION===void 0?e.attributes.position:n.getDependency(`accessor`,u.POSITION);o.push(t)}if(i){let t=u.NORMAL===void 0?e.attributes.normal:n.getDependency(`accessor`,u.NORMAL);s.push(t)}if(a){let t=u.COLOR_0===void 0?e.attributes.color:n.getDependency(`accessor`,u.COLOR_0);c.push(t)}}return Promise.all([Promise.all(o),Promise.all(s),Promise.all(c)]).then(function(t){let n=t[0],o=t[1],s=t[2];return r&&(e.morphAttributes.position=n),i&&(e.morphAttributes.normal=o),a&&(e.morphAttributes.color=s),e.morphTargetsRelative=!0,e})}function rw(e,t){if(e.updateMorphTargets(),t.weights!==void 0)for(let n=0,r=t.weights.length;n<r;n++)e.morphTargetInfluences[n]=t.weights[n];if(t.extras&&Array.isArray(t.extras.targetNames)){let n=t.extras.targetNames;if(e.morphTargetInfluences.length===n.length){e.morphTargetDictionary={};for(let t=0,r=n.length;t<r;t++)e.morphTargetDictionary[n[t]]=t}else console.warn(`THREE.GLTFLoader: Invalid extras.targetNames length. Ignoring names.`)}}function iw(e){let t,n=e.extensions&&e.extensions[hC.KHR_DRACO_MESH_COMPRESSION];if(t=n?`draco:`+n.bufferView+`:`+n.indices+`:`+aw(n.attributes):e.indices+`:`+aw(e.attributes)+`:`+e.mode,e.targets!==void 0)for(let n=0,r=e.targets.length;n<r;n++)t+=`:`+aw(e.targets[n]);return t}function aw(e){let t=``,n=Object.keys(e).sort();for(let r=0,i=n.length;r<i;r++)t+=n[r]+`:`+e[n[r]]+`;`;return t}function ow(e){switch(e){case Int8Array:return 1/127;case Uint8Array:return 1/255;case Int16Array:return 1/32767;case Uint16Array:return 1/65535;default:throw Error(`THREE.GLTFLoader: Unsupported normalized accessor component type.`)}}function sw(e){return e.search(/\.jpe?g($|\?)/i)>0||e.search(/^data\:image\/jpeg/)===0?`image/jpeg`:e.search(/\.webp($|\?)/i)>0||e.search(/^data\:image\/webp/)===0?`image/webp`:e.search(/\.ktx2($|\?)/i)>0||e.search(/^data\:image\/ktx2/)===0?`image/ktx2`:`image/png`}var cw=new G,lw=class{constructor(e={},t={}){this.json=e,this.extensions={},this.plugins={},this.options=t,this.cache=new pC,this.associations=new Map,this.primitiveCache={},this.nodeCache={},this.meshCache={refs:{},uses:{}},this.cameraCache={refs:{},uses:{}},this.lightCache={refs:{},uses:{}},this.sourceCache={},this.textureCache={},this.nodeNamesUsed={};let n=!1,r=-1,i=!1,a=-1;if(typeof navigator<`u`&&navigator.userAgent!==void 0){let e=navigator.userAgent;n=/^((?!chrome|android).)*safari/i.test(e)===!0;let t=e.match(/Version\/(\d+)/);r=n&&t?parseInt(t[1],10):-1,i=e.indexOf(`Firefox`)>-1,a=i?e.match(/Firefox\/([0-9]+)\./)[1]:-1}typeof createImageBitmap>`u`||n&&r<17||i&&a<98?this.textureLoader=new eu(this.options.manager):this.textureLoader=new wu(this.options.manager),this.textureLoader.setCrossOrigin(this.options.crossOrigin),this.textureLoader.setRequestHeader(this.options.requestHeader),this.fileLoader=new Xl(this.options.manager),this.fileLoader.setResponseType(`arraybuffer`),this.options.crossOrigin===`use-credentials`&&this.fileLoader.setWithCredentials(!0)}setExtensions(e){this.extensions=e}setPlugins(e){this.plugins=e}parse(e,t){let n=this,r=this.json,i=this.extensions;this.cache.removeAll(),this.nodeCache={},this._invokeAll(function(e){return e._markDefs&&e._markDefs()}),Promise.all(this._invokeAll(function(e){return e.beforeRoot&&e.beforeRoot()})).then(function(){return Promise.all([n.getDependencies(`scene`),n.getDependencies(`animation`),n.getDependencies(`camera`)])}).then(function(t){let a={scene:t[0][r.scene||0],scenes:t[0],animations:t[1],cameras:t[2],asset:r.asset,parser:n,userData:{}};return ew(i,a,r),tw(a,r),Promise.all(n._invokeAll(function(e){return e.afterRoot&&e.afterRoot(a)})).then(function(){for(let e of a.scenes)e.updateMatrixWorld();e(a)})}).catch(t)}_markDefs(){let e=this.json.nodes||[],t=this.json.skins||[],n=this.json.meshes||[];for(let n=0,r=t.length;n<r;n++){let r=t[n].joints;for(let t=0,n=r.length;t<n;t++)e[r[t]].isBone=!0}for(let t=0,r=e.length;t<r;t++){let r=e[t];r.mesh!==void 0&&(this._addNodeRef(this.meshCache,r.mesh),r.skin!==void 0&&(n[r.mesh].isSkinnedMesh=!0)),r.camera!==void 0&&this._addNodeRef(this.cameraCache,r.camera)}}_addNodeRef(e,t){t!==void 0&&(e.refs[t]===void 0&&(e.refs[t]=e.uses[t]=0),e.refs[t]++)}_getNodeRef(e,t,n){if(e.refs[t]<=1)return n;let r=n.clone(),i=(e,t)=>{let n=this.associations.get(e);n!=null&&this.associations.set(t,n);for(let[n,r]of e.children.entries())i(r,t.children[n])};return i(n,r),r.name+=`_instance_`+ e.uses[t]++,r}_invokeOne(e){let t=Object.values(this.plugins);t.push(this);for(let n=0;n<t.length;n++){let r=e(t[n]);if(r)return r}return null}_invokeAll(e){let t=Object.values(this.plugins);t.unshift(this);let n=[];for(let r=0;r<t.length;r++){let i=e(t[r]);i&&n.push(i)}return n}getDependency(e,t){let n=e+`:`+t,r=this.cache.get(n);if(!r){switch(e){case`scene`:r=this.loadScene(t);break;case`node`:r=this._invokeOne(function(e){return e.loadNode&&e.loadNode(t)});break;case`mesh`:r=this._invokeOne(function(e){return e.loadMesh&&e.loadMesh(t)});break;case`accessor`:r=this.loadAccessor(t);break;case`bufferView`:r=this._invokeOne(function(e){return e.loadBufferView&&e.loadBufferView(t)});break;case`buffer`:r=this.loadBuffer(t);break;case`material`:r=this._invokeOne(function(e){return e.loadMaterial&&e.loadMaterial(t)});break;case`texture`:r=this._invokeOne(function(e){return e.loadTexture&&e.loadTexture(t)});break;case`skin`:r=this.loadSkin(t);break;case`animation`:r=this._invokeOne(function(e){return e.loadAnimation&&e.loadAnimation(t)});break;case`camera`:r=this.loadCamera(t);break;default:if(r=this._invokeOne(function(n){return n!=this&&n.getDependency&&n.getDependency(e,t)}),!r)throw Error(`Unknown type: `+e);break}this.cache.add(n,r)}return r}getDependencies(e){let t=this.cache.get(e);if(!t){let n=this,r=this.json[e+(e===`mesh`?`es`:`s`)]||[];t=Promise.all(r.map(function(t,r){return n.getDependency(e,r)})),this.cache.add(e,t)}return t}loadBuffer(e){let t=this.json.buffers[e],n=this.fileLoader;if(t.type&&t.type!==`arraybuffer`)throw Error(`THREE.GLTFLoader: `+t.type+` buffer type is not supported.`);if(t.uri===void 0&&e===0)return Promise.resolve(this.extensions[hC.KHR_BINARY_GLTF].body);let r=this.options;return new Promise(function(e,i){n.load(Su.resolveURL(t.uri,r.path),e,void 0,function(){i(Error(`THREE.GLTFLoader: Failed to load buffer "`+t.uri+`".`))})})}loadBufferView(e){let t=this.json.bufferViews[e];return this.getDependency(`buffer`,t.buffer).then(function(e){let n=t.byteLength||0,r=t.byteOffset||0;return e.slice(r,r+n)})}loadAccessor(e){let t=this,n=this.json,r=this.json.accessors[e];if(r.bufferView===void 0&&r.sparse===void 0){let e=JC[r.type],t=GC[r.componentType],n=r.normalized===!0,i=new t(r.count*e);return Promise.resolve(new q(i,e,n))}let i=[];return r.bufferView===void 0?i.push(null):i.push(this.getDependency(`bufferView`,r.bufferView)),r.sparse!==void 0&&(i.push(this.getDependency(`bufferView`,r.sparse.indices.bufferView)),i.push(this.getDependency(`bufferView`,r.sparse.values.bufferView))),Promise.all(i).then(function(e){let i=e[0],a=JC[r.type],o=GC[r.componentType],s=o.BYTES_PER_ELEMENT,c=s*a,l=r.byteOffset||0,u=r.bufferView===void 0?void 0:n.bufferViews[r.bufferView].byteStride,d=r.normalized===!0,f,p;if(u&&u!==c){let e=Math.floor(l/u),n=`InterleavedBuffer:`+r.bufferView+`:`+r.componentType+`:`+e+`:`+r.count,c=t.cache.get(n);c||(f=new o(i,e*u,r.count*u/s),c=new ws(f,u/s),t.cache.add(n,c)),p=new Es(c,a,l%u/s,d)}else f=i===null?new o(r.count*a):new o(i,l,r.count*a),p=new q(f,a,d);if(r.sparse!==void 0){let t=JC.SCALAR,n=GC[r.sparse.indices.componentType],s=r.sparse.indices.byteOffset||0,c=r.sparse.values.byteOffset||0,l=new n(e[1],s,r.sparse.count*t),u=new o(e[2],c,r.sparse.count*a);i!==null&&(p=new q(p.array.slice(),p.itemSize,p.normalized)),p.normalized=!1;for(let e=0,t=l.length;e<t;e++){let t=l[e];if(p.setX(t,u[e*a]),a>=2&&p.setY(t,u[e*a+1]),a>=3&&p.setZ(t,u[e*a+2]),a>=4&&p.setW(t,u[e*a+3]),a>=5)throw Error(`THREE.GLTFLoader: Unsupported itemSize in sparse BufferAttribute.`)}p.normalized=d}return p})}loadTexture(e){let t=this.json,n=this.options,r=t.textures[e].source,i=t.images[r],a=this.textureLoader;if(i.uri){let e=n.manager.getHandler(i.uri);e!==null&&(a=e)}return this.loadTextureImage(e,r,a)}loadTextureImage(e,t,n){let r=this,i=this.json,a=i.textures[e],o=i.images[t],s=(o.uri||o.bufferView)+`:`+a.sampler;if(this.textureCache[s])return this.textureCache[s];let c=this.loadImageSource(t,n).then(function(t){t.flipY=!1,t.name=a.name||o.name||``,t.name===``&&typeof o.uri==`string`&&o.uri.startsWith(`data:image/`)===!1&&(t.name=o.uri);let n=(i.samplers||{})[a.sampler]||{};return t.magFilter=KC[n.magFilter]||1006,t.minFilter=KC[n.minFilter]||1008,t.wrapS=qC[n.wrapS]||1e3,t.wrapT=qC[n.wrapT]||1e3,t.generateMipmaps=!t.isCompressedTexture&&t.minFilter!==1003&&t.minFilter!==1006,r.associations.set(t,{textures:e}),t}).catch(function(){return null});return this.textureCache[s]=c,c}loadImageSource(e,t){let n=this,r=this.json,i=this.options;if(this.sourceCache[e]!==void 0)return this.sourceCache[e].then(e=>e.clone());let a=r.images[e],o=self.URL||self.webkitURL,s=a.uri||``,c=!1;if(a.bufferView!==void 0)s=n.getDependency(`bufferView`,a.bufferView).then(function(e){c=!0;let t=new Blob([e],{type:a.mimeType});return s=o.createObjectURL(t),s});else if(a.uri===void 0)throw Error(`THREE.GLTFLoader: Image `+e+` is missing URI and bufferView`);let l=Promise.resolve(s).then(function(e){return new Promise(function(n,r){let a=n;t.isImageBitmapLoader===!0&&(a=function(e){let t=new La(e);t.needsUpdate=!0,n(t)}),t.load(Su.resolveURL(e,i.path),a,void 0,r)})}).then(function(e){return c===!0&&o.revokeObjectURL(s),tw(e,a),e.userData.mimeType=a.mimeType||sw(a.uri),e}).catch(function(e){throw console.error(`THREE.GLTFLoader: Couldn't load texture`,s),e});return this.sourceCache[e]=l,l}assignTexture(e,t,n,r){let i=this;return this.getDependency(`texture`,n.index).then(function(a){if(!a)return null;if(n.texCoord!==void 0&&n.texCoord>0&&(a=a.clone(),a.channel=n.texCoord),i.extensions[hC.KHR_TEXTURE_TRANSFORM]){let e=n.extensions===void 0?void 0:n.extensions[hC.KHR_TEXTURE_TRANSFORM];if(e){let t=i.associations.get(a);a=i.extensions[hC.KHR_TEXTURE_TRANSFORM].extendTexture(a,e),i.associations.set(a,t)}}return r!==void 0&&(a.colorSpace=r),e[t]=a,a})}assignFinalMaterial(e){let t=e.geometry,n=e.material,r=t.attributes.tangent===void 0,i=t.attributes.color!==void 0,a=t.attributes.normal===void 0;if(e.isPoints){let e=`PointsMaterial:`+n.uuid,t=this.cache.get(e);t||(t=new Wc,Os.prototype.copy.call(t,n),t.color.copy(n.color),t.map=n.map,t.sizeAttenuation=!1,this.cache.add(e,t)),n=t}else if(e.isLine){let e=`LineBasicMaterial:`+n.uuid,t=this.cache.get(e);t||(t=new Ac,Os.prototype.copy.call(t,n),t.color.copy(n.color),t.map=n.map,this.cache.add(e,t)),n=t}if(r||i||a){let e=`ClonedMaterial:`+n.uuid+`:`;r&&(e+=`derivative-tangents:`),i&&(e+=`vertex-colors:`),a&&(e+=`flat-shading:`);let t=this.cache.get(e);t||(t=n.clone(),i&&(t.vertexColors=!0),a&&(t.flatShading=!0),r&&(t.normalScale&&(t.normalScale.y*=-1),t.clearcoatNormalScale&&(t.clearcoatNormalScale.y*=-1)),this.cache.add(e,t),this.associations.set(t,this.associations.get(n))),n=t}e.material=n}getMaterialType(){return bl}loadMaterial(e){let t=this,n=this.json,r=this.extensions,i=n.materials[e],a,o={},s=i.extensions||{},c=[];if(s[hC.KHR_MATERIALS_UNLIT]){let e=r[hC.KHR_MATERIALS_UNLIT];a=e.getMaterialType(),c.push(e.extendParams(o,i,t))}else{let n=i.pbrMetallicRoughness||{};if(o.color=new K(1,1,1),o.opacity=1,Array.isArray(n.baseColorFactor)){let e=n.baseColorFactor;o.color.setRGB(e[0],e[1],e[2],ki),o.opacity=e[3]}n.baseColorTexture!==void 0&&c.push(t.assignTexture(o,`map`,n.baseColorTexture,Oi)),o.metalness=n.metallicFactor===void 0?1:n.metallicFactor,o.roughness=n.roughnessFactor===void 0?1:n.roughnessFactor,n.metallicRoughnessTexture!==void 0&&(c.push(t.assignTexture(o,`metalnessMap`,n.metallicRoughnessTexture)),c.push(t.assignTexture(o,`roughnessMap`,n.metallicRoughnessTexture))),a=this._invokeOne(function(t){return t.getMaterialType&&t.getMaterialType(e)}),c.push(Promise.all(this._invokeAll(function(t){return t.extendMaterialParams&&t.extendMaterialParams(e,o)})))}i.doubleSided===!0&&(o.side=2);let l=i.alphaMode||QC.OPAQUE;if(l===QC.BLEND?(o.transparent=!0,o.depthWrite=!1):(o.transparent=!1,l===QC.MASK&&(o.alphaTest=i.alphaCutoff===void 0?.5:i.alphaCutoff)),i.normalTexture!==void 0&&a!==Ls&&(c.push(t.assignTexture(o,`normalMap`,i.normalTexture)),o.normalScale=new V(1,1),i.normalTexture.scale!==void 0)){let e=i.normalTexture.scale;o.normalScale.set(e,e)}if(i.occlusionTexture!==void 0&&a!==Ls&&(c.push(t.assignTexture(o,`aoMap`,i.occlusionTexture)),i.occlusionTexture.strength!==void 0&&(o.aoMapIntensity=i.occlusionTexture.strength)),i.emissiveFactor!==void 0&&a!==Ls){let e=i.emissiveFactor;o.emissive=new K().setRGB(e[0],e[1],e[2],ki)}return i.emissiveTexture!==void 0&&a!==Ls&&c.push(t.assignTexture(o,`emissiveMap`,i.emissiveTexture,Oi)),Promise.all(c).then(function(){let n=new a(o);return i.name&&(n.name=i.name),tw(n,i),t.associations.set(n,{materials:e}),i.extensions&&ew(r,n,i),n})}createUniqueName(e){let t=Vu.sanitizeNodeName(e||``);return t in this.nodeNamesUsed?t+`_`+ ++this.nodeNamesUsed[t]:(this.nodeNamesUsed[t]=0,t)}loadGeometries(e){let t=this,n=this.extensions,r=this.primitiveCache;function i(e){return n[hC.KHR_DRACO_MESH_COMPRESSION].decodePrimitive(e,t).then(function(n){return dw(n,e,t)})}let a=[];for(let n=0,o=e.length;n<o;n++){let o=e[n],s=iw(o),c=r[s];if(c)a.push(c.promise);else{let e;e=o.extensions&&o.extensions[hC.KHR_DRACO_MESH_COMPRESSION]?i(o):dw(new J,o,t),r[s]={primitive:o,promise:e},a.push(e)}}return Promise.all(a)}loadMesh(e){let t=this,n=this.json,r=this.extensions,i=n.meshes[e],a=i.primitives,o=[];for(let e=0,t=a.length;e<t;e++){let t=a[e].material===void 0?$C(this.cache):this.getDependency(`material`,a[e].material);o.push(t)}return o.push(t.loadGeometries(a)),Promise.all(o).then(function(n){let o=n.slice(0,n.length-1),s=n[n.length-1],c=[];for(let n=0,l=s.length;n<l;n++){let l=s[n],u=a[n],d,f=o[n];if(u.mode===WC.TRIANGLES||u.mode===WC.TRIANGLE_STRIP||u.mode===WC.TRIANGLE_FAN||u.mode===void 0)d=i.isSkinnedMesh===!0?new sc(l,f):new Ys(l,f),d.isSkinnedMesh===!0&&d.normalizeSkinWeights(),u.mode===WC.TRIANGLE_STRIP?d.geometry=lC(d.geometry,1):u.mode===WC.TRIANGLE_FAN&&(d.geometry=lC(d.geometry,2));else if(u.mode===WC.LINES)d=new Hc(l,f);else if(u.mode===WC.LINE_STRIP)d=new Rc(l,f);else if(u.mode===WC.LINE_LOOP)d=new Uc(l,f);else if(u.mode===WC.POINTS)d=new Yc(l,f);else throw Error(`THREE.GLTFLoader: Primitive mode unsupported: `+u.mode);Object.keys(d.geometry.morphAttributes).length>0&&rw(d,i),d.name=t.createUniqueName(i.name||`mesh_`+e),tw(d,i),u.extensions&&ew(r,d,u),t.assignFinalMaterial(d),c.push(d)}for(let n=0,r=c.length;n<r;n++)t.associations.set(c[n],{meshes:e,primitives:n});if(c.length===1)return i.extensions&&ew(r,c[0],i),c[0];let l=new _o;i.extensions&&ew(r,l,i),t.associations.set(l,{meshes:e});for(let e=0,t=c.length;e<t;e++)l.add(c[e]);return l})}loadCamera(e){let t,n=this.json.cameras[e],r=n[n.type];if(!r){console.warn(`THREE.GLTFLoader: Missing camera parameters.`);return}return n.type===`perspective`?t=new pu(ba.radToDeg(r.yfov),r.aspectRatio||1,r.znear||1,r.zfar||2e6):n.type===`orthographic`&&(t=new vu(-r.xmag,r.xmag,r.ymag,-r.ymag,r.znear,r.zfar)),n.name&&(t.name=this.createUniqueName(n.name)),tw(t,n),Promise.resolve(t)}loadSkin(e){let t=this.json.skins[e],n=[];for(let e=0,r=t.joints.length;e<r;e++)n.push(this._loadNodeShallow(t.joints[e]));return t.inverseBindMatrices===void 0?n.push(null):n.push(this.getDependency(`accessor`,t.inverseBindMatrices)),Promise.all(n).then(function(e){let n=e.pop(),r=e,i=[],a=[];for(let e=0,o=r.length;e<o;e++){let o=r[e];if(o){i.push(o);let t=new G;n!==null&&t.fromArray(n.array,e*16),a.push(t)}else console.warn(`THREE.GLTFLoader: Joint "%s" could not be found.`,t.joints[e])}return new fc(i,a)})}loadAnimation(e){let t=this.json,n=this,r=t.animations[e],i=r.name?r.name:`animation_`+e,a=[],o=[],s=[],c=[],l=[];for(let e=0,t=r.channels.length;e<t;e++){let t=r.channels[e],n=r.samplers[t.sampler],i=t.target,u=i.node,d=r.parameters===void 0?n.input:r.parameters[n.input],f=r.parameters===void 0?n.output:r.parameters[n.output];i.node!==void 0&&(a.push(this.getDependency(`node`,u)),o.push(this.getDependency(`accessor`,d)),s.push(this.getDependency(`accessor`,f)),c.push(n),l.push(i))}return Promise.all([Promise.all(a),Promise.all(o),Promise.all(s),Promise.all(c),Promise.all(l)]).then(function(e){let t=e[0],a=e[1],o=e[2],s=e[3],c=e[4],l=[];for(let e=0,r=t.length;e<r;e++){let r=t[e],i=a[e],u=o[e],d=s[e],f=c[e];if(r===void 0)continue;r.updateMatrix&&r.updateMatrix();let p=n._createAnimationTracks(r,i,u,d,f);if(p)for(let e=0;e<p.length;e++)l.push(p[e])}let u=new Vl(i,void 0,l);return tw(u,r),u})}createNodeMesh(e){let t=this.json,n=this,r=t.nodes[e];return r.mesh===void 0?null:n.getDependency(`mesh`,r.mesh).then(function(e){let t=n._getNodeRef(n.meshCache,r.mesh,e);return r.weights!==void 0&&t.traverse(function(e){if(e.isMesh)for(let t=0,n=r.weights.length;t<n;t++)e.morphTargetInfluences[t]=r.weights[t]}),t})}loadNode(e){let t=this.json,n=this,r=t.nodes[e],i=n._loadNodeShallow(e),a=[],o=r.children||[];for(let e=0,t=o.length;e<t;e++)a.push(n.getDependency(`node`,o[e]));let s=r.skin===void 0?Promise.resolve(null):n.getDependency(`skin`,r.skin);return Promise.all([i,Promise.all(a),s]).then(function(e){let t=e[0],n=e[1],r=e[2];r!==null&&t.traverse(function(e){e.isSkinnedMesh&&e.bind(r,cw)});for(let e=0,r=n.length;e<r;e++)t.add(n[e]);if(t.userData.pivot!==void 0&&n.length>0){let e=t.userData.pivot,r=n[0];t.pivot=new U().fromArray(e),t.position.x-=e[0],t.position.y-=e[1],t.position.z-=e[2],r.position.set(0,0,0),delete t.userData.pivot}return t})}_loadNodeShallow(e){let t=this.json,n=this.extensions,r=this;if(this.nodeCache[e]!==void 0)return this.nodeCache[e];let i=t.nodes[e],a=i.name?r.createUniqueName(i.name):``,o=[],s=r._invokeOne(function(t){return t.createNodeMesh&&t.createNodeMesh(e)});return s&&o.push(s),i.camera!==void 0&&o.push(r.getDependency(`camera`,i.camera).then(function(e){return r._getNodeRef(r.cameraCache,i.camera,e)})),r._invokeAll(function(t){return t.createNodeAttachment&&t.createNodeAttachment(e)}).forEach(function(e){o.push(e)}),this.nodeCache[e]=Promise.all(o).then(function(t){let o;if(o=i.isBone===!0?new cc:t.length>1?new _o:t.length===1?t[0]:new go,o!==t[0])for(let e=0,n=t.length;e<n;e++)o.add(t[e]);if(i.name&&(o.userData.name=i.name,o.name=a),tw(o,i),i.extensions&&ew(n,o,i),i.matrix!==void 0){let e=new G;e.fromArray(i.matrix),o.applyMatrix4(e)}else i.translation!==void 0&&o.position.fromArray(i.translation),i.rotation!==void 0&&o.quaternion.fromArray(i.rotation),i.scale!==void 0&&o.scale.fromArray(i.scale);if(!r.associations.has(o))r.associations.set(o,{});else if(i.mesh!==void 0&&r.meshCache.refs[i.mesh]>1){let e=r.associations.get(o);r.associations.set(o,{...e})}return r.associations.get(o).nodes=e,o}),this.nodeCache[e]}loadScene(e){let t=this.extensions,n=this.json.scenes[e],r=this,i=new _o;n.name&&(i.name=r.createUniqueName(n.name)),tw(i,n),n.extensions&&ew(t,i,n);let a=n.nodes||[],o=[];for(let e=0,t=a.length;e<t;e++)o.push(r.getDependency(`node`,a[e]));return Promise.all(o).then(function(e){for(let t=0,n=e.length;t<n;t++){let n=e[t];n.parent===null?i.add(n):i.add(uC(n))}return r.associations=(e=>{let t=new Map;for(let[e,n]of r.associations)(e instanceof Os||e instanceof La)&&t.set(e,n);return e.traverse(e=>{let n=r.associations.get(e);n!=null&&t.set(e,n)}),t})(i),i})}_createAnimationTracks(e,t,n,r,i){let a=[],o=e.name?e.name:e.uuid,s=[];function c(e){e.morphTargetInfluences&&s.push(e.name?e.name:e.uuid)}XC[i.path]===XC.weights?(c(e),e.isGroup&&e.children.forEach(c)):s.push(o);let l;switch(XC[i.path]){case XC.weights:l=Il;break;case XC.rotation:l=Rl;break;case XC.translation:case XC.scale:l=Bl;break;default:switch(n.itemSize){case 1:l=Il;break;default:l=Bl;break}break}let u=r.interpolation===void 0?vi:ZC[r.interpolation],d=this._getArrayFromAccessor(n);for(let e=0,n=s.length;e<n;e++){let n=new l(s[e]+`.`+XC[i.path],t.array,d,u);r.interpolation===`CUBICSPLINE`&&this._createCubicSplineTrackInterpolant(n),a.push(n)}return a}_getArrayFromAccessor(e){let t=e.array;if(e.normalized){let e=ow(t.constructor),n=new Float32Array(t.length);for(let r=0,i=t.length;r<i;r++)n[r]=t[r]*e;t=n}return t}_createCubicSplineTrackInterpolant(e){e.createInterpolant=function(e){return new(this instanceof Rl?UC:VC)(this.times,this.values,this.getValueSize()/3,e)},e.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline=!0}};function uw(e,t,n){let r=t.attributes,i=new Vo;if(r.POSITION!==void 0){let e=n.json.accessors[r.POSITION],t=e.min,a=e.max;if(t!==void 0&&a!==void 0){if(i.set(new U(t[0],t[1],t[2]),new U(a[0],a[1],a[2])),e.normalized){let t=ow(GC[e.componentType]);i.min.multiplyScalar(t),i.max.multiplyScalar(t)}}else{console.warn(`THREE.GLTFLoader: Missing min/max properties for accessor POSITION.`);return}}else return;let a=t.targets;if(a!==void 0){let e=new U,t=new U;for(let r=0,i=a.length;r<i;r++){let i=a[r];if(i.POSITION!==void 0){let r=n.json.accessors[i.POSITION],a=r.min,o=r.max;if(a!==void 0&&o!==void 0){if(t.setX(Math.max(Math.abs(a[0]),Math.abs(o[0]))),t.setY(Math.max(Math.abs(a[1]),Math.abs(o[1]))),t.setZ(Math.max(Math.abs(a[2]),Math.abs(o[2]))),r.normalized){let e=ow(GC[r.componentType]);t.multiplyScalar(e)}e.max(t)}else console.warn(`THREE.GLTFLoader: Missing min/max properties for accessor POSITION.`)}}i.expandByVector(e)}e.boundingBox=i;let o=new gs;i.getCenter(o.center),o.radius=i.min.distanceTo(i.max)/2,e.boundingSphere=o}function dw(e,t,n){let r=t.attributes,i=[];function a(t,r){return n.getDependency(`accessor`,t).then(function(t){e.setAttribute(r,t)})}for(let t in r){let n=YC[t]||t.toLowerCase();n in e.attributes||i.push(a(r[t],n))}if(t.indices!==void 0&&!e.index){let r=n.getDependency(`accessor`,t.indices).then(function(t){e.setIndex(t)});i.push(r)}return Da.workingColorSpace!==`srgb-linear`&&`COLOR_0`in r&&console.warn(`THREE.GLTFLoader: Converting vertex colors from "srgb-linear" to "${Da.workingColorSpace}" not supported.`),tw(e,t),uw(e,t,n),Promise.all(i).then(function(){return t.targets===void 0?e:nw(e,t.targets,n)})}var fw=(e,t)=>new eu().load(e,void 0,void 0,t);function pw(e,t){return[e,t?.colorSpace??`srgb`,t?.filter??`linear`,t?.wrap??`clamp`,String(t?.anisotropy??1),t?.process?.id??``].join(`|`)}function mw(e,t){e.colorSpace=(t?.colorSpace??`srgb`)===`srgb`?Oi:``;let n=t?.filter===`nearest`;e.magFilter=n?rr:or,e.generateMipmaps=!n,e.minFilter=n?rr:cr;let r=t?.wrap===`repeat`?er:tr;e.wrapS=r,e.wrapT=r,t?.anisotropy&&(e.anisotropy=t.anisotropy)}var hw=class{entries=new Map;load;diagnostics;constructor(e){this.load=e?.loader??fw,this.diagnostics=e?.diagnostics??null}acquire(e,t){if(e===``||typeof document>`u`&&this.load===fw)return null;let n=pw(e,t),r=this.entries.get(n);if(r)return r.texture;let i={url:e,texture:null,error:null};return i.texture=this.load(e,t=>{i.error=t instanceof Error?t.message:String(t),this.diagnostics?.warn(`texture failed to load: ${e} — ${i.error}`)}),mw(i.texture,t),t?.process?.run(i.texture),this.entries.set(n,i),i.texture}acquireOwn(e,t){let n=this.acquire(e,t);return n?n.clone():null}errors(){let e=[];for(let t of this.entries.values())t.error!==null&&e.push({url:t.url,error:t.error});return e}size(){return this.entries.size}dispose(){for(let e of this.entries.values())e.texture.dispose();this.entries.clear()}};function gw(e,t,n){return e?e.textures.acquire(t,n):vw().acquire(t,n)}function _w(e,t,n){return e?e.textures.acquireOwn(t,n):vw().acquireOwn(t,n)}function vw(){return new hw}var yw=class{engine;models=new Map;animations=new Map;modelKeys=new Map;animationKeys=new Map;loader;textures;constructor(e=null){this.engine=e,this.loader=new fC,this.loader.register(e=>new MS(e)),this.textures=new hw({diagnostics:e?{warn:(...t)=>lt(e,`warn`,...t)}:null})}errors(){let e=[];for(let{url:t,error:n}of this.textures.errors())e.push({ref:t,url:t,error:n});for(let[t,n]of this.modelKeys){let r=this.models.get(n);r?.error&&e.push({ref:t,url:n,error:String(r.error)})}for(let[t,n]of this.animationKeys){let r=this.animations.get(n.url);r?.error&&e.push({ref:t,url:n.url,error:String(r.error)})}return e}load(e){for(let[t,n]of Object.entries(e)){let e=n;typeof e.url==`string`&&(e.type===`model`?this.modelKeys.set(`$${t}`,e.url):e.type===`animation`&&this.animationKeys.set(`$${t}`,{url:e.url,clip:e.clip}))}}animationRefs(){return[...this.animationKeys.keys()]}modelRefs(){return[...this.modelKeys.keys()]}getModel(e){let t=this.modelKeys.get(e)??e,n=this.models.get(t);return n||(n={status:`loading`,scene:null,animations:[],isVrm:!1,vrm:null,claimedBy:null,retargeted:new Map},this.models.set(t,n),this.loader.load(t,e=>{let t=e.userData.vrm;t?(cC.removeUnnecessaryVertices(e.scene),cC.combineSkeletons(e.scene),cC.rotateVRM0(t),n.scene=t.scene,n.vrm=t,n.isVrm=!0):n.scene=e.scene,n.animations=e.animations??[],n.status=`ready`},void 0,e=>{n.status=`error`,n.error=e instanceof Error?e.message:String(e),lt(this.engine,`error`,`incanto: failed to load model '${t}':`,e)}),n)}getAnimation(e){let t=this.animationKeys.get(e)??{url:e},n=this.animations.get(t.url);return n||(n={status:`loading`,clips:[],scene:null,clip:t.clip},this.animations.set(t.url,n),this.loader.load(t.url,e=>{n.clips=e.animations??[],n.scene=e.scene,n.status=`ready`,n.clips.length===0&<(this.engine,`warn`,`incanto: animation asset '${t.url}' contains no clips`)},void 0,e=>{n.status=`error`,n.error=e instanceof Error?e.message:String(e),lt(this.engine,`error`,`incanto: failed to load animation '${t.url}':`,e)}),n)}dispose(){this.textures.dispose();for(let e of this.models.values())e.scene?.traverse(e=>{let t=e;t.geometry?.dispose();let n=Array.isArray(t.material)?t.material:[t.material];for(let e of n)if(e){for(let t of Object.values(e))t?.isTexture&&t.dispose();e.dispose()}});this.models.clear(),this.animations.clear()}},bw=Math.atan(1/Math.SQRT2);function xw(e,t,n,r,i,a){let o=[t[0],t[1]+n,t[2]];if(e===`firstPerson`)return{position:o,rotation:[-i,r,0]};if(e===`quarter`){let e=bw;return{position:[o[0],o[1]+a*Math.sin(e),o[2]+a*Math.cos(e)],rotation:[-e,0,0]}}if(e===`side`)return{position:[o[0],o[1],o[2]+a],rotation:[0,0,0]};let s=Math.cos(i);return{position:[o[0]+Math.sin(r)*s*a,o[1]+Math.sin(i)*a,o[2]+Math.cos(r)*s*a],rotation:[-i,r,0]}}function Sw(e,t,n,r,i){let a=t[0]-e[0],o=t[1]-e[1],s=t[2]-e[2],c=Math.hypot(a,o,s);if(c<1e-4)return[t[0],t[1],t[2]];let l=[a/c,o/c,s/c],u=n(e,l,c);if(u===null)return[t[0],t[1],t[2]];let d=Math.min(c,Math.max(i,u-r));return[e[0]+l[0]*d,e[1]+l[1]*d,e[2]+l[2]*d]}function Cw(e,t,n){let r=t(e,n);return r===null||r>=n?[e[0],e[1],e[2]]:[e[0],e[1]+(n-r),e[2]]}function ww(e,t,n){let r=Math.sin(n),i=Math.cos(n);return[e*i-t*r,0,-e*r-t*i]}function Tw(e,t){return e?Math.min(.6+(t?.4:0),1):0}function Ew(e,t){return e?t<=0?`idle`:t<.3?`walk`:t<.7?`run`:`fastRun`:`airborne`}var Dw=[`color`,`metalness`,`roughness`,`emissive`,`emissiveIntensity`,`wireframe`,`flatShading`,`opacity`,`clearcoat`,`clearcoatRoughness`,`envMapIntensity`,`depthTest`,`depthWrite`,`map`,`normalMap`,`repeat`],Ow=class extends Ah{static typeName=`MeshInstance3D`;static props={mesh:{default:`box`,options:[`box`,`sphere`,`capsule`,`plane`,`cylinder`,`gem`]},size:{default:[1,1,1]},material:{default:{}},castShadow:{default:!1},receiveShadow:{default:!1}};mesh=`box`;size=[1,1,1];material={};castShadow=!1;receiveShadow=!1;static validateJson(e){Aw(e.material,e.name)}geometryKey=``;textureKey=``;loadedTextures=[];_createObject3D(){return new Ys(new nl(1,1,1),new xl)}_syncObject3D(e=1,t=null){super._syncObject3D(e,t);let n=this._ensureObject3D(),r=`${this.mesh}:${JSON.stringify(this.size)}`;r!==this.geometryKey&&(n.geometry.dispose(),n.geometry=jw(this.mesh,this.size),this.geometryKey=r);let i=n.material;kw(i,this.material),this.syncTextures(i,t),n.castShadow=this.castShadow,n.receiveShadow=this.receiveShadow}syncTextures(e,t){let n=JSON.stringify([this.material.map??``,this.material.normalMap??``,this.material.repeat??null]);if(n===this.textureKey)return;this.textureKey=n;for(let e of this.loadedTextures)e.dispose();this.loadedTextures=[];let r=e.map!==null||e.normalMap!==null;e.map=null,e.normalMap=null,this.material.map&&(e.map=this.loadTexture(t,this.material.map,!0)),this.material.normalMap&&(e.normalMap=this.loadTexture(t,this.material.normalMap,!1)),(r||e.map||e.normalMap)&&(e.needsUpdate=!0)}loadTexture(e,t,n){let r=_w(e,t,{wrap:`repeat`,anisotropy:4,colorSpace:n?`srgb`:`linear`});if(!r)return null;let[i,a]=this.material.repeat??[1,1];return r.repeat.set(i,a),this.loadedTextures.push(r),r}free(){for(let e of this.loadedTextures)e.dispose();this.loadedTextures=[];let e=this._builtObject3D;if(e){e.geometry?.dispose();let t=Array.isArray(e.material)?e.material:[e.material];for(let e of t)e?.dispose()}super.free()}};function kw(e,t){e.color.set(t.color??`#ffffff`),e.metalness=t.metalness??0,e.roughness=t.roughness??1,e.wireframe=t.wireframe??!1,e.emissive.set(t.emissive??`#000000`),e.emissiveIntensity=t.emissiveIntensity??1;let n=t.opacity??1;e.opacity=n,e.transparent=n<1;let r=t.clearcoat??0;e.clearcoat>0!=r>0&&(e.needsUpdate=!0),e.clearcoat=r,e.clearcoatRoughness=t.clearcoatRoughness??0,e.envMapIntensity=t.envMapIntensity??1,e.depthTest=t.depthTest??!0,e.depthWrite=t.depthWrite??!0;let i=t.flatShading??!1;e.flatShading!==i&&(e.flatShading=i,e.needsUpdate=!0)}function Aw(e,t,n=`MeshInstance3D`){let r=e=>{throw new N(`BAD_FORMAT`,`${n} '${t}' ${e}`,{prop:`material`,validOptions:[...Dw]})};(typeof e!=`object`||!e||Array.isArray(e))&&r(`material must be an object, got ${JSON.stringify(e)}.`);for(let t of Object.keys(e))Dw.includes(t)||r(`material has unknown key '${t}' — must be one of [${Dw.join(`, `)}].`);for(let t of[`map`,`normalMap`]){let n=e[t];n!==void 0&&(typeof n!=`string`||n.length===0)&&r(`material.${t} must be a non-empty texture URL string, got ${JSON.stringify(n)}.`)}if(e.repeat!==void 0){let t=e.repeat;(!Array.isArray(t)||t.length!==2||!t.every(e=>typeof e==`number`&&Number.isFinite(e)&&e>0))&&r(`material.repeat must be [u, v] with positive numbers, got ${JSON.stringify(t)}.`),!e.map&&!e.normalMap&&r(`material.repeat tiles nothing — add a 'map' and/or 'normalMap' texture URL.`)}for(let t of[`metalness`,`roughness`,`opacity`,`clearcoat`,`clearcoatRoughness`]){let n=e[t];n!==void 0&&!(typeof n==`number`&&n>=0&&n<=1)&&r(`material.${t} must be a number in 0..1, got ${JSON.stringify(n)}.`)}e.envMapIntensity!==void 0&&!(typeof e.envMapIntensity==`number`&&Number.isFinite(e.envMapIntensity)&&e.envMapIntensity>=0)&&r(`material.envMapIntensity must be a number >= 0, got ${JSON.stringify(e.envMapIntensity)}.`);for(let t of[`wireframe`,`flatShading`,`depthTest`,`depthWrite`]){let n=e[t];n!==void 0&&typeof n!=`boolean`&&r(`material.${t} must be a boolean, got ${JSON.stringify(n)}.`)}}function jw(e,t){let n=t[0]??1,r=t[1]??1,i=t[2]??1;switch(e){case`box`:return new nl(n,r,i);case`sphere`:return new ll(n,32,16);case`gem`:return new sl(n,0);case`capsule`:return new rl(n,r,8,16);case`plane`:{let e=new cl(n,i);return e.rotateX(-Math.PI/2),e}case`cylinder`:return new il(n,n,r,24);default:throw new N(`PROP_TYPE_MISMATCH`,`MeshInstance3D.mesh must be one of box|sphere|capsule|plane|cylinder|gem, got '${e}'.`)}}var Mw=class extends Ah{static typeName=`InstancedMesh3D`;static props={mesh:{default:`box`,options:[`box`,`sphere`,`capsule`,`plane`,`cylinder`,`gem`]},size:{default:[1,1,1]},material:{default:{}},transforms:{default:[]},castShadow:{default:!1},receiveShadow:{default:!1},collider:{default:null}};mesh=`box`;size=[1,1,1];material={};castShadow=!1;receiveShadow=!1;collider=null;_transforms=[];transformsDirty=!0;get transforms(){return this._transforms}set transforms(e){this._transforms=e,this.transformsDirty=!0}instanced=null;builtKey=``;static validateJson(e){let t=e;Aw(t.material,e.name);for(let[n,r]of t._transforms.entries())if(!Array.isArray(r)||r.length<3||r.length>5||r.some(e=>typeof e!=`number`))throw new N(`BAD_FORMAT`,`InstancedMesh3D '${e.name}': transforms[${n}] must be [x, y, z, yawDeg?, scale?] (numbers), got ${JSON.stringify(r)}.`)}get instanceCount(){return this.instanced?.count??0}_syncObject3D(e){super._syncObject3D(e);let t=this._ensureObject3D(),n=`${this.mesh} ${JSON.stringify(this.size)} ${this._transforms.length}`;if(n!==this.builtKey){if(this.builtKey=n,this.instanced&&=(t.remove(this.instanced),this.instanced.geometry.dispose(),this.instanced.material.dispose(),null),this._transforms.length>0){let e=jw(this.mesh,this.size),n=new xl;this.instanced=new xc(e,n,this._transforms.length),this.instanced.instanceMatrix.setUsage(Pi),t.add(this.instanced)}this.transformsDirty=!0}let r=this.instanced;if(r&&(r.castShadow=this.castShadow,r.receiveShadow=this.receiveShadow,kw(r.material,this.material),this.transformsDirty)){this.transformsDirty=!1;for(let e=0;e<this._transforms.length;e++){let t=this._transforms[e];Pw.set(t[0]??0,t[1]??0,t[2]??0),Fw.setFromAxisAngle(Nw,(t[3]??0)*Math.PI/180);let n=t[4]??1;Iw.set(n,n,n),Lw.compose(Pw,Fw,Iw),r.setMatrixAt(e,Lw)}r.instanceMatrix.needsUpdate=!0,r.computeBoundingSphere()}}free(){this.instanced&&(this.instanced.geometry.dispose(),this.instanced.material.dispose()),super.free()}},Nw=new U(0,1,0),Pw=new U,Fw=new H,Iw=new U,Lw=new G,Rw=class extends Ah{static typeName=`Joint3D`;static props={type:{default:`spherical`,options:[`fixed`,`spherical`,`rope`,`spring`]},target:{default:``,nodePath:!0},anchor:{default:[0,0,0]},targetAnchor:{default:[0,0,0]},length:{default:0},stiffness:{default:50},damping:{default:5}};type=`spherical`;target=``;anchor=[0,0,0];targetAnchor=[0,0,0];length=0;stiffness=50;damping=5;onEnterTree(){if(!(this.parent instanceof jh))throw new N(`TREE_VIOLATION`,`Joint3D '${this.name}' must be a child of a physics body (its body A); parent is '${this.parent?.name??`none`}'.`);if(this.target===``)throw new N(`BAD_FORMAT`,`Joint3D '${this.name}' needs a "target" node path to the body it links to.`)}_resolveBodies(){let e=this.parent,t=this.getNodeOrNull(this.target);if(!(t instanceof jh))throw new N(`NODE_NOT_FOUND`,`Joint3D '${this.name}': target '${this.target}' is not a physics body.`);return{a:e,b:t}}},zw=256,Bw=.3,Vw=.6,Hw=45;function Uw(e){let{width:t,depth:n,segsX:r,segsZ:i,maxHeight:a,seed:o}=e,s=e.roughness??.5,c=e.detail??4,l=e.flatThreshold??.95,u=e.islandEdge??!1,d=Math.max(0,Math.min(e.edgeWrapRadius??20,Hw)),f=e.edgeBottom??-50,p=e.edgeCornerSmoothness??1,m=(e.basins??[]).map(e=>({cx:e.x+t/2,cz:e.z+n/2,radius:e.radius,depth:e.depth})),h=(e.channels??[]).map(e=>({half:Math.max(e.width,0)/2,taper:Math.max(e.taper??e.width,.001),depth:e.depth,segs:e.path.map(e=>({x:(e[0]??0)+t/2,z:(e[1]??0)+n/2})).flatMap((e,t,n)=>t===0?[]:[{ax:n[t-1].x,az:n[t-1].z,bx:e.x,bz:e.z}])})).filter(e=>e.segs.length>0&&e.depth!==0),g=dn(o),_=(e,t)=>(g(e,t)+1)*.5,v=(e,t)=>{let n=e/zw,r=t/zw,i=0,o=.2,u=5;for(let e=0;e<5;e++)i+=_(n*o,r*o)*u,u*=.5,o*=2;let d=0;o=.5,u=.1;for(let e=0;e<c;e++)d+=_(n*o,r*o)*u,u*=s,o*=2;i=Math.abs(i)**1.5*Math.sign(i),i<Bw&&(i*=.3);let f=a*(i+d*(i*.5+.5)+1)/2,p=a*l;if(Math.abs(f-p)<Vw&&(f=p),m.length>0){let n=0,r=0;for(let i of m){let a=Math.hypot(e-i.cx,t-i.cz);if(a<i.radius){let e=a/i.radius,t=1-e*e*(3-2*e);i.depth>=0?n=Math.max(n,i.depth*t):r=Math.max(r,-i.depth*t)}}f+=r-n}if(h.length>0){let n=0;for(let r of h){let i=1/0;for(let n of r.segs){let a=n.bx-n.ax,o=n.bz-n.az,s=a*a+o*o,c=s>1e-9?Math.min(1,Math.max(0,((e-n.ax)*a+(t-n.az)*o)/s)):0,l=n.ax+a*c,u=n.az+o*c,d=Math.hypot(e-l,t-u);if(d<i&&(i=d),i<=r.half)break}if(i>=r.half+r.taper)continue;let a=Math.min(1,Math.max(0,(i-r.half)/r.taper));n=Math.max(n,r.depth*(1-a*a*(3-2*a)))}f-=n}return f},y=(e,a,o)=>{if(!u||d<=0)return o;let s=d,c=Math.min(e,t-e),l=Math.min(a,n-a),m=(t/r+n/i)*.002,h=Math.max(0,s-c+m),g=Math.max(0,s-l+m);if(h<=0&&g<=0)return o;let _=2+(1-Math.min(1,Math.max(0,p)))*30,v=(h**_+g**_)**(1/_),y=o-(s-Math.sqrt(Math.max(0,s*s-v*v)));return v>=s&&(y=Math.min(y,f)),y},b=r+1,x=i+1,S=new Float32Array(b*x),C=1/0,w=-1/0;for(let e=0;e<x;e++){let a=e/i*n;for(let n=0;n<b;n++){let i=n/r*t,o=v(i,a);o<C&&(C=o),o>w&&(w=o),S[e*b+n]=y(i,a,o)}}let T=(e,a)=>{let o=Math.min(Math.max((e+t/2)/t*r,0),r),s=Math.min(Math.max((a+n/2)/n*i,0),i),c=Math.min(Math.floor(o),r-1),l=Math.min(Math.floor(s),i-1),u=o-c,d=s-l,f=S[l*b+c],p=S[l*b+c+1],m=S[(l+1)*b+c],h=S[(l+1)*b+c+1];return(f*(1-u)+p*u)*(1-d)+(m*(1-u)+h*u)*d},E=(e,r)=>v(e+t/2,r+n/2);return{width:t,depth:n,segsX:r,segsZ:i,heights:S,minHeight:C,maxHeight:w,heightAt:T,baseHeight:E,slopeAt:(e,t)=>{let n=(E(e+1,t)-E(e-1,t))/2,r=(E(e,t+1)-E(e,t-1))/2;return Math.atan(Math.sqrt(n*n+r*r))}}}function Ww(e,t,n,r){return e<t-r||e>n+r?0:e>=t&&e<=n?1:e<t?(e-(t-r))/r:(n+r-e)/r}function Gw(e,t,n,r=1.2){let i=[0,0,0,0],a=Math.min(n.length,4),o=0;for(let s=0;s<a;s++){let a=n[s],[c,l]=a.heightRange??[0,1],[u,d]=a.slopeRange??[0,Math.PI/2],f=Ww(e,c,l,a.heightBlendRange??.1)*Ww(t,u,d,a.slopeBlendRange??.1);f**=1/r,i[s]=f,o+=f}if(o===0)return[1,0,0,0];for(let e=0;e<4;e++)i[e]=i[e]/o;return i}function Kw(e,t,n){let r=e.indexOf(t);if(r===-1)throw new N(`BAD_FORMAT`,`Terrain3D shader patch: marker '${t}' not found in the three.js shader — the installed three version moved its chunks.`);let i=r+t.length;return`${e.slice(0,i)}\n${n}${e.slice(i)}`}var qw=`
|
|
6690
6690
|
varying vec3 vSplatColor;
|
|
6691
6691
|
varying vec3 vWorldPosition;
|
|
6692
6692
|
varying vec2 vUvSplat;
|
|
6693
|
-
`,
|
|
6693
|
+
`,Jw=`
|
|
6694
6694
|
vSplatColor = color;
|
|
6695
6695
|
vWorldPosition = (modelMatrix * vec4(position, 1.0)).xyz;
|
|
6696
6696
|
vUvSplat = uv;
|
|
6697
|
-
`,
|
|
6697
|
+
`,Yw=`
|
|
6698
6698
|
uniform sampler2D splatTexture1;
|
|
6699
6699
|
uniform sampler2D splatTexture2;
|
|
6700
6700
|
uniform sampler2D splatTexture3;
|
|
@@ -6815,7 +6815,7 @@ vec3 perturbSplatNormal(vec3 normal, vec3 viewPos, vec2 uv, vec3 normalSample) {
|
|
|
6815
6815
|
|
|
6816
6816
|
return normalize(TBN * normalMap);
|
|
6817
6817
|
}
|
|
6818
|
-
`,
|
|
6818
|
+
`,Xw=`
|
|
6819
6819
|
// World-based UVs per layer (texture repeat baked in)
|
|
6820
6820
|
vec2 baseWorldUV1 = vec2(vWorldPosition.x, vWorldPosition.z) * (splatTextureRepeat1 * 0.1);
|
|
6821
6821
|
vec2 baseWorldUV2 = vec2(vWorldPosition.x, vWorldPosition.z) * (splatTextureRepeat2 * 0.1);
|
|
@@ -6921,14 +6921,14 @@ if (uWetlineY > -1.0e8) {
|
|
|
6921
6921
|
}
|
|
6922
6922
|
|
|
6923
6923
|
diffuseColor = vec4(splatColor.rgb, diffuseColor.a);
|
|
6924
|
-
`,
|
|
6924
|
+
`,Zw=`
|
|
6925
6925
|
roughnessFactor = blendedRoughness;
|
|
6926
|
-
`,
|
|
6926
|
+
`,Qw=`
|
|
6927
6927
|
iblIrradiance *= splatEnvCut;
|
|
6928
6928
|
radiance *= splatEnvCut;
|
|
6929
|
-
|
|
6929
|
+
`,$w=`
|
|
6930
6930
|
metalnessFactor = blendedMetalness;
|
|
6931
|
-
`,
|
|
6931
|
+
`,eT=`
|
|
6932
6932
|
#ifdef USE_TERRAIN_NORMALMAP
|
|
6933
6933
|
vec3 normalSample1 = vec3(0.5, 0.5, 1.0);
|
|
6934
6934
|
vec3 normalSample2 = vec3(0.5, 0.5, 1.0);
|
|
@@ -6973,7 +6973,7 @@ if (splatDetailAmount > 0.001) {
|
|
|
6973
6973
|
|
|
6974
6974
|
normal = perturbSplatNormal(normal, vViewPosition, vUvSplat, blendedNormalSample);
|
|
6975
6975
|
#endif
|
|
6976
|
-
`;function $w(e,t){for(let n=0;n<4;n++){let r=n+1;e.uniforms[`splatTexture${r}`]={value:t.textures[n]??t.textures[0]??null},e.uniforms[`splatNormalMap${r}`]={value:t.normalMaps[n]??null},e.uniforms[`splatTextureRepeat${r}`]={value:t.repeats[n]??1},e.uniforms[`splatRoughness${r}`]={value:t.roughness[n]??1},e.uniforms[`splatMetalness${r}`]={value:t.metalness[n]??0},e.uniforms[`uvNoiseIntensity${r}`]={value:t.uvNoiseIntensity[n]??.15}}e.uniforms.splatTextureCount={value:Math.min(4,t.layerCount)},e.uniforms.uWetlineY={value:-1e9},e.uniforms.uWetlineBand={value:1.1},e.uniforms.uWetTime={value:0},e.uniforms.splatEnvCut={value:t.envCut},e.vertexShader=Ww(e.vertexShader,`#include <common>`,Gw),e.vertexShader=Ww(e.vertexShader,`#include <begin_vertex>`,Kw);let n=e.fragmentShader;n=Ww(n,`#include <common>`,qw),n=Ww(n,`#include <color_fragment>`,Jw),n=Ww(n,`#include <roughnessmap_fragment>`,Yw),n=Ww(n,`#include <metalnessmap_fragment>`,Zw),n=Ww(n,`#include <normal_fragment_maps>`,Qw),n=Ww(n,`#include <lights_fragment_maps>`,Xw),t.hasNormalMaps&&(n=`#define USE_TERRAIN_NORMALMAP\n${n}`),e.fragmentShader=n}var eT=[`island`,`alpine`,`plains`,`desert`,`grassland`,`forest`,`savanna`,`snow`,`wetland`,`volcanic`,`custom`],tT=`https://agent8-games.verse8.io/assets/3D/default/textures/terrain`,nT=`https://agent8-games.verse8.io/assets/3D/default/textures/vegetation/ground`,rT=1/3,iT=Math.PI/4;function aT(e,t,n){return{texture:`${e}/${t}.png`,normalMap:`${e}/${t}_normal.png`,...n}}function oT(e,t){let n=t.replace(/\/$/,``);switch(e){case`island`:return[aT(n,`sand`,{heightRange:[0,.12],slopeRange:[0,Math.PI/2],heightBlendRange:.05,roughness:.9}),aT(n,`grass`,{heightRange:[.1,.7],slopeRange:[0,iT],heightBlendRange:.1,slopeBlendRange:.1,roughness:.8}),aT(n,`stone`,{heightRange:[0,1],slopeRange:[iT,Math.PI],heightBlendRange:.5,slopeBlendRange:.5,roughness:.85}),aT(n,`snow`,{heightRange:[.8,1],slopeRange:[0,Math.PI/3],heightBlendRange:.1,roughness:.6})];case`alpine`:return[aT(n,`grass`,{heightRange:[0,.45],slopeRange:[0,Math.PI/5],heightBlendRange:.1,roughness:.8}),aT(n,`stone`,{heightRange:[.3,1],slopeRange:[0,Math.PI],heightBlendRange:.25,slopeBlendRange:.5,roughness:.85}),aT(n,`gravel`,{heightRange:[0,1],slopeRange:[Math.PI/5,Math.PI],heightBlendRange:.5,slopeBlendRange:.15,roughness:.9}),aT(n,`snow`,{heightRange:[.55,1],slopeRange:[0,Math.PI/3],heightBlendRange:.12,roughness:.55})];case`plains`:return[aT(n,`grass`,{heightRange:[0,1],slopeRange:[0,iT],heightBlendRange:.1,slopeBlendRange:.1,roughness:.8}),aT(n,`dirt`,{heightRange:[.35,.65],slopeRange:[0,Math.PI/5],heightBlendRange:.2,roughness:.9}),aT(n,`gravel`,{heightRange:[0,1],slopeRange:[iT,Math.PI],heightBlendRange:.5,slopeBlendRange:.3,roughness:.9})];case`desert`:return[aT(n,`sand`,{heightRange:[0,1],slopeRange:[0,iT],heightBlendRange:.1,slopeBlendRange:.15,roughness:.95}),aT(n,`gravel`,{heightRange:[0,.15],slopeRange:[0,Math.PI/3],heightBlendRange:.08,roughness:.9}),aT(n,`stone`,{heightRange:[0,1],slopeRange:[iT,Math.PI],heightBlendRange:.5,slopeBlendRange:.4,roughness:.85})];case`grassland`:return n===`https://agent8-games.verse8.io/assets/3D/default/textures/terrain`?[{texture:`${nT}/grass.jpg`,heightRange:[0,1],slopeRange:[0,iT],heightBlendRange:.1,slopeBlendRange:.15,roughness:1,repeat:rT,uvNoiseIntensity:0},{texture:`${nT}/dirt_color.jpg`,heightRange:[0,1],slopeRange:[iT,Math.PI],heightBlendRange:.5,slopeBlendRange:.3,roughness:1,repeat:rT,uvNoiseIntensity:0}]:[aT(n,`grass`,{heightRange:[0,1],slopeRange:[0,iT],heightBlendRange:.1,slopeBlendRange:.15,roughness:.8}),aT(n,`dirt`,{heightRange:[0,1],slopeRange:[iT,Math.PI],heightBlendRange:.5,slopeBlendRange:.3,roughness:.9})];case`forest`:return n===`https://agent8-games.verse8.io/assets/3D/default/textures/terrain`?[{texture:`${nT}/dirt_color.jpg`,heightRange:[0,1],slopeRange:[0,Math.PI],heightBlendRange:.1,roughness:1,repeat:rT,uvNoiseIntensity:0},{texture:`${nT}/grass.jpg`,heightRange:[-2,-1],roughness:1,repeat:rT,uvNoiseIntensity:0}]:[aT(n,`dirt`,{heightRange:[0,1],slopeRange:[0,Math.PI],heightBlendRange:.1,roughness:.9}),aT(n,`grass`,{heightRange:[-2,-1],roughness:.8})];case`savanna`:return[aT(n,`grass`,{heightRange:[0,1],slopeRange:[0,iT],heightBlendRange:.1,slopeBlendRange:.15,roughness:.95}),aT(n,`sand`,{heightRange:[0,.22],slopeRange:[0,Math.PI/4],heightBlendRange:.12,roughness:.95}),aT(n,`dirt`,{heightRange:[0,1],slopeRange:[iT,Math.PI],heightBlendRange:.5,slopeBlendRange:.3,roughness:.95})];case`snow`:return[aT(n,`snow`,{heightRange:[0,1],slopeRange:[0,iT],heightBlendRange:.1,slopeBlendRange:.18,roughness:.55}),aT(n,`stone`,{heightRange:[0,1],slopeRange:[iT,Math.PI],heightBlendRange:.5,slopeBlendRange:.35,roughness:.85})];case`wetland`:return[aT(n,`grass`,{heightRange:[0,1],slopeRange:[0,iT],heightBlendRange:.1,slopeBlendRange:.15,roughness:.95}),aT(n,`dirt`,{heightRange:[0,1],slopeRange:[iT,Math.PI],heightBlendRange:.5,slopeBlendRange:.3,roughness:.95})];case`volcanic`:return[aT(n,`stone`,{heightRange:[0,1],slopeRange:[0,Math.PI],heightBlendRange:.1,roughness:.95}),aT(n,`gravel`,{heightRange:[0,.28],slopeRange:[0,Math.PI/3],heightBlendRange:.14,slopeBlendRange:.2,roughness:.95})];case`custom`:return[]}}var sT={scale:100,threshold:.7,blend:.1},cT={scale:55,threshold:.58,blend:.12},lT={scale:85,threshold:.62,blend:.12},uT={scale:48,threshold:.5,blend:.14};function dT(e,t){let n=dn(e+27927);return(e,r)=>{let i=(.5+.5*n(e/t.scale,r/t.scale)-(t.threshold-t.blend))/(2*t.blend),a=Math.min(1,Math.max(0,i));return a*a*(3-2*a)}}function fT(e,t){return e===`grassland`?dT(t,sT):e===`forest`?dT(t,cT):e===`savanna`?dT(t,lT):e===`wetland`?dT(t,uT):null}function pT(e){return e===`savanna`?{from:0,to:2}:e===`grassland`||e===`forest`||e===`wetland`?{from:0,to:1}:null}var mT=256,hT=class extends Oh{orderGroup=`terrain`;static typeName=`Terrain3D`;static props={orderGroup:{default:`terrain`,options:[`background`,`terrain`,`default`,`characters`,`effects`,`overlay`]},size:{default:[200,200]},maxHeight:{default:28},seed:{default:1},resolution:{default:128},theme:{default:`island`,options:eT},roughness:{default:.5},detail:{default:4},flatThreshold:{default:.95},islandEdge:{default:null},layers:{default:[]},textureBase:{default:tT},basins:{default:[]},channels:{default:[]},wetline:{default:null}};size=[200,200];maxHeight=28;seed=1;resolution=128;theme=`island`;roughness=.5;detail=4;flatThreshold=.95;islandEdge=null;layers=[];textureBase=tT;basins=[];channels=[];externalChannels=new Map;externalRev=0;shapeStamp=null;wetline=null;splatUniforms=null;wetTime=0;update(e){this.wetTime+=e;let t=this.splatUniforms;if(!t)return;let n=this.wetline;t.uWetlineY&&(t.uWetlineY.value=typeof n?.y==`number`?n.y:-1e9),t.uWetlineBand&&(t.uWetlineBand.value=typeof n?.band==`number`?n.band:1.1),t.uWetTime&&(t.uWetTime.value=this.wetTime)}static validateJson(e){let t=e;if(!eT.includes(t.theme))throw new N(`BAD_FORMAT`,`Terrain3D '${e.name}' theme must be one of [${eT.join(`, `)}], got '${t.theme}'.`,{prop:`theme`,validOptions:eT});if(!((t.size[0]??0)>0)||!((t.size[1]??0)>0))throw new N(`BAD_FORMAT`,`Terrain3D '${e.name}' size must be positive [width, depth] meters, got ${JSON.stringify(t.size)}.`,{prop:`size`});if(!(t.maxHeight>0))throw new N(`BAD_FORMAT`,`Terrain3D '${e.name}' maxHeight must be > 0, got ${t.maxHeight}.`,{prop:`maxHeight`});if(!Number.isInteger(t.resolution)||t.resolution<2||t.resolution>mT)throw new N(`BAD_FORMAT`,`Terrain3D '${e.name}' resolution must be an integer in [2, ${mT}] (grid segments per side), got ${t.resolution}.`,{prop:`resolution`});if(!(t.roughness>0)||!Number.isFinite(t.roughness))throw new N(`BAD_FORMAT`,`Terrain3D '${e.name}' roughness must be a finite number > 0, got ${t.roughness}.`,{prop:`roughness`});if(!Number.isInteger(t.detail)||t.detail<0)throw new N(`BAD_FORMAT`,`Terrain3D '${e.name}' detail must be an integer ≥ 0 (octave count), got ${t.detail}.`,{prop:`detail`});if(!(t.flatThreshold>=0)||!Number.isFinite(t.flatThreshold))throw new N(`BAD_FORMAT`,`Terrain3D '${e.name}' flatThreshold must be a finite number ≥ 0, got ${t.flatThreshold}.`,{prop:`flatThreshold`});if(t.islandEdge!==null&&typeof t.islandEdge!=`boolean`)throw new N(`BAD_FORMAT`,`Terrain3D '${e.name}' islandEdge must be true, false or null (null = theme default), got ${JSON.stringify(t.islandEdge)}.`,{prop:`islandEdge`});let n=t.wetline;if(n!==null){if(typeof n!=`object`||Array.isArray(n)||!Number.isFinite(n.y))throw new N(`BAD_FORMAT`,`Terrain3D '${e.name}' wetline must be null or { y, band? } with a finite y, got ${JSON.stringify(t.wetline)}.`,{prop:`wetline`});if(n.band!==void 0&&!(n.band>0))throw new N(`BAD_FORMAT`,`Terrain3D '${e.name}' wetline.band must be > 0 meters, got ${JSON.stringify(n.band)}.`,{prop:`wetline`})}if(!Array.isArray(t.basins))throw new N(`BAD_FORMAT`,`Terrain3D '${e.name}' basins must be an array of { x, z, radius, depth }, got ${JSON.stringify(t.basins)}.`,{prop:`basins`});if(t.basins.forEach((t,n)=>{if(!t||typeof t!=`object`||!Number.isFinite(t.x)||!Number.isFinite(t.z)||!(t.radius>0)||!Number.isFinite(t.depth)||t.depth===0)throw new N(`BAD_FORMAT`,`Terrain3D '${e.name}' basins[${n}] needs finite x, z, positive radius and nonzero depth (negative = mound), got ${JSON.stringify(t)}.`,{prop:`basins`})}),!Array.isArray(t.channels))throw new N(`BAD_FORMAT`,`Terrain3D '${e.name}' channels must be an array of { path, width, depth, taper? }, got ${JSON.stringify(t.channels)}.`,{prop:`channels`});if(t.channels.forEach((t,n)=>{let r=t.path;if(!(t&&typeof t==`object`&&Array.isArray(r)&&r.length>=2&&r.every(e=>Array.isArray(e)&&Number.isFinite(e[0])&&Number.isFinite(e[1]))&&t.width>0&&t.depth>0&&(t.taper===void 0||t.taper>0)))throw new N(`BAD_FORMAT`,`Terrain3D '${e.name}' channels[${n}] needs a path of 2+ [x, z] points plus positive width and depth, got ${JSON.stringify(t)}.`,{prop:`channels`})}),t.theme===`custom`){if(!Array.isArray(t.layers)||t.layers.length<1||t.layers.length>4)throw new N(`BAD_FORMAT`,`Terrain3D '${e.name}' theme 'custom' needs 1–4 layers, got ${Array.isArray(t.layers)?t.layers.length:typeof t.layers}.`,{prop:`layers`});t.layers.forEach((t,n)=>{vT(e.name,t,n)})}else if(Array.isArray(t.layers)&&t.layers.length>0)throw new N(`BAD_FORMAT`,`Terrain3D '${e.name}' layers is only read with theme 'custom' — preset theme '${t.theme}' defines its own. Drop layers or switch to theme: 'custom'.`,{prop:`layers`})}heightmap=null;heightmapKey=``;builtKey=``;_createObject3D(){let e=new J;return e.setAttribute(`position`,new q(new Float32Array,3)),new Ys(e,new bl({vertexColors:!0}))}heightAt(e,t){let n=0,r=0,i=0;for(let e=this;e;e=e.parent)e instanceof Oh&&(n+=e.position[0]??0,r+=e.position[1]??0,i+=e.position[2]??0);return this._heightmap().heightAt(e-n,t-i)+r}_setExternalChannel(e,t){t===null||t.length===0?this.externalChannels.delete(e):this.externalChannels.set(e,t),this.externalRev++}allChannels(){return this.externalChannels.size===0?this.channels:[...this.channels,...[...this.externalChannels.values()].flat()]}_heightmap(){if(this.heightmap&&this.shapeUnchanged())return this.heightmap;let e=this.segments(),t=JSON.stringify([this.size,this.maxHeight,this.seed,e,this.roughness,this.detail,this.flatThreshold,this.effectiveIslandEdge(),this.basins,this.allChannels()]);return(!this.heightmap||t!==this.heightmapKey)&&(this.heightmap=Vw({width:this.size[0]??1,depth:this.size[1]??1,segsX:e,segsZ:e,maxHeight:this.maxHeight,seed:this.seed,roughness:this.roughness,detail:this.detail,flatThreshold:this.flatThreshold,islandEdge:this.effectiveIslandEdge(),basins:this.basins,channels:this.allChannels()}),this.heightmapKey=t),this.rememberShape(),this.heightmap}shapeUnchanged(){let e=this.shapeStamp;return e!==null&&e.sizeX===(this.size[0]??0)&&e.sizeZ===(this.size[1]??0)&&e.maxHeight===this.maxHeight&&e.seed===this.seed&&e.segments===this.segments()&&e.roughness===this.roughness&&e.detail===this.detail&&e.flatThreshold===this.flatThreshold&&e.islandEdge===this.effectiveIslandEdge()&&e.basins===this.basins&&e.channels===this.channels&&e.externalRev===this.externalRev}rememberShape(){this.shapeStamp={sizeX:this.size[0]??0,sizeZ:this.size[1]??0,maxHeight:this.maxHeight,seed:this.seed,segments:this.segments(),roughness:this.roughness,detail:this.detail,flatThreshold:this.flatThreshold,islandEdge:this.effectiveIslandEdge(),basins:this.basins,channels:this.channels,externalRev:this.externalRev}}resolvedLayers(){return this.theme===`custom`?this.layers:oT(this.theme,this.textureBase)}_syncObject3D(e=1,t=null){super._syncObject3D(e,t),this.rebuildIfNeeded(t)}effectiveIslandEdge(){return this.islandEdge??this.theme===`island`}segments(){return Math.max(2,Math.min(Math.floor(this.resolution),mT))}rebuildIfNeeded(e){let t=JSON.stringify([this.size,this.maxHeight,this.seed,this.segments(),this.theme,this.roughness,this.detail,this.flatThreshold,this.islandEdge,this.layers,this.textureBase,this.basins,this.allChannels()]);if(t===this.builtKey)return;this.builtKey=t;let n=this._ensureObject3D();n.geometry.dispose(),n.geometry=this.buildGeometry(),n.material.dispose(),n.material=this.buildMaterial(e),n.receiveShadow=!0,n.castShadow=!0}buildGeometry(){let e=this._heightmap(),t=new cl(e.width,e.depth,e.segsX,e.segsZ);t.rotateX(-Math.PI/2);let n=t.getAttribute(`position`);for(let t=0;t<n.count;t++)n.setY(t,e.heights[t]);n.needsUpdate=!0,t.computeVertexNormals();let r=this.resolvedLayers(),i=e.maxHeight-e.minHeight||1,a=new Float32Array(n.count*3),o=this.theme===`custom`?null:pT(this.theme),s=o?fT(this.theme,this.seed):null;for(let t=0;t<n.count;t++){let c=n.getX(t),l=n.getZ(t),u=Uw(Math.min(1,Math.max(0,(n.getY(t)-e.minHeight)/i)),e.slopeAt(c,l),r);if(s&&o){let e=(u[o.from]??0)*s(c,l);u[o.from]=(u[o.from]??0)-e,u[o.to]=(u[o.to]??0)+e}a[t*3]=u[0],a[t*3+1]=u[1],a[t*3+2]=u[2]}return t.setAttribute(`color`,new q(a,3)),t}buildMaterial(e){let t=this.resolvedLayers(),n=new bl({vertexColors:!0}),r=(t,n)=>t?mw(e,t,{wrap:`repeat`,anisotropy:8,colorSpace:n?`srgb`:`linear`}):null,i=t.map(e=>r(e.texture,!0)),a=t.map(e=>r(e.normalMap,!1)),o=a.some(e=>e!==null);if(o)for(let e=0;e<a.length;e++)a[e]||(a[e]=_T());let s={textures:i,normalMaps:a,repeats:t.map(e=>e.repeat??2),roughness:t.map(e=>e.roughness??1),metalness:t.map(e=>e.metalness??0),uvNoiseIntensity:t.map(e=>e.uvNoiseIntensity??.15),envCut:.45,layerCount:Math.min(4,t.length),hasNormalMaps:o};return n.onBeforeCompile=e=>{$w(e,s),this.splatUniforms=e.uniforms},n.customProgramCacheKey=()=>`incanto-terrain-splat:${+!!o}`,n}free(){let e=this._ensureObject3D();e.geometry.dispose(),e.material.dispose(),this.heightmap=null,super.free()}},gT=null;function _T(){return gT||(gT=new lc(new Uint8Array([128,128,255,255]),1,1),gT.needsUpdate=!0),gT}function vT(e,t,n){let r=`layers[${n}]`;if(typeof t!=`object`||!t||Array.isArray(t))throw new N(`BAD_FORMAT`,`Terrain3D '${e}' ${r} must be an object ({texture, heightRange?, slopeRange?, …}).`,{prop:`layers`});let i=t;if(typeof i.texture!=`string`||i.texture.length===0)throw new N(`BAD_FORMAT`,`Terrain3D '${e}' ${r} needs "texture": a texture URL string.`,{prop:`layers`});for(let t of[`heightRange`,`slopeRange`]){let n=i[t];if(n!==void 0&&(!Array.isArray(n)||n.length!==2||n.some(e=>typeof e!=`number`||!Number.isFinite(e))))throw new N(`BAD_FORMAT`,`Terrain3D '${e}' ${r}.${t} must be [min, max] numbers, got ${JSON.stringify(n)}.`,{prop:`layers`})}}var yT=16,bT=new U,xT=new H;function ST(e,t){let n=e.translation(),r=e.rotation();xT.set(r.x,r.y,r.z,r.w);let i=(e,r,i)=>{bT.set(e,r,i).applyQuaternion(xT),t.push(bT.x+n.x,bT.y+n.y,bT.z+n.z)};return(e,t,n,r,a,o)=>{i(e,t,n),i(r,a,o)}}function CT(e,t,n,r,i=Math.PI*2,a=0){let o=e=>{let i=Math.cos(e)*t,a=Math.sin(e)*t;return n===`xy`?[i,a,r]:n===`xz`?[i,r,a]:[r,i,a]},s=Math.max(3,Math.round(yT*i/(Math.PI*2)));for(let t=0;t<s;t++){let[n,r,c]=o(a+i*t/s),[l,u,d]=o(a+i*(t+1)/s);e(n,r,c,l,u,d)}}function wT(e,t,n){let r=e=>[t[e*3],t[e*3+1],t[e*3+2]];if(n){for(let t=0;t<n.length;t+=3){let i=r(n[t]),a=r(n[t+1]),o=r(n[t+2]);e(...i,...a),e(...a,...o),e(...o,...i)}return}for(let n=0;n+5<t.length;n+=9){let t=r(n/3),i=r(n/3+1),a=r(n/3+2);e(...t,...i),e(...i,...a),e(...a,...t)}}function TT(e,t){let{nrows:n,ncols:r,heights:i,scale:a}=t,o=n+1,s=r+1,c=(e,t)=>[(e/n-.5)*a.x,i[t*o+e]*a.y,(t/r-.5)*a.z];for(let t=0;t<s;t++)for(let n=0;n<o;n++)n+1<o&&e(...c(n,t),...c(n+1,t)),t+1<s&&e(...c(n,t),...c(n,t+1))}function ET(e,t){let n=ST(e,t),r=e.shape;switch(e.shape.type){case 0:{let e=r.radius;CT(n,e,`xy`,0),CT(n,e,`xz`,0),CT(n,e,`yz`,0);return}case 1:{let e=r.halfExtents;for(let[t,r]of[[-1,-1],[-1,1],[1,-1],[1,1]])n(-e.x,t*e.y,r*e.z,e.x,t*e.y,r*e.z);for(let[t,r]of[[-1,-1],[-1,1],[1,-1],[1,1]])n(t*e.x,-e.y,r*e.z,t*e.x,e.y,r*e.z);for(let[t,r]of[[-1,-1],[-1,1],[1,-1],[1,1]])n(t*e.x,r*e.y,-e.z,t*e.x,r*e.y,e.z);return}case 2:{let{radius:e,halfHeight:t}=r;for(let r of[-1,1]){CT(n,e,`xz`,r*t);for(let i of[`xy`,`yz`])CT((e,i,a,o,s,c)=>n(e,i+r*t,a,o,s+r*t,c),e,i,0,Math.PI,r>0?0:Math.PI)}for(let[r,i]of[[1,0],[-1,0],[0,1],[0,-1]])n(r*e,-t,i*e,r*e,t,i*e);return}case 3:{let e=r;n(e.a.x,e.a.y,e.a.z,e.b.x,e.b.y,e.b.z);return}case 6:case 9:case 16:{let e=r;wT(n,e.vertices,e.indices);return}case 7:TT(n,r);return;case 10:case 14:{let{radius:e,halfHeight:t}=r;CT(n,e,`xz`,-t),CT(n,e,`xz`,t);for(let[r,i]of[[1,0],[-1,0],[0,1],[0,-1]])n(r*e,-t,i*e,r*e,t,i*e);return}case 11:case 15:{let{radius:e,halfHeight:t}=r;CT(n,e,`xz`,-t);for(let r=0;r<4;r++){let i=r/4*Math.PI*2;n(Math.cos(i)*e,-t,Math.sin(i)*e,0,t,0)}return}default:if(e.shape.type===12||e.shape.type===13){let e=r.halfExtents;e&&n(-e.x,-e.y,-e.z,e.x,e.y,e.z)}return}}var DT=Math.PI/180;async function OT(e,t){let n=await bm(()=>import(`./rapier-DE6a0vmv.js`),[],import.meta.url);return await n.init({}),new kT(n,e,t)}var kT=class{R;engine;debugDraw=!1;debugScope=null;dimension=`3d`;unregisterDebug;warnedNoCollider=new WeakSet;entries=new Map;byColliderHandle=new Map;world;events;kcc;disconnect;lastDt=1/60;optsGravity;lastScene=null;constructor(e,t,n){this.R=e,this.engine=t,this.optsGravity=n?.gravity,this.simulate=n?.simulate??!0,this.lastScene=t.scene;let r=t.scene?.physics?.gravity,i=n?.gravity??r??[0,-9.81,0];this.world=new e.World({x:i[0]??0,y:i[1]??0,z:i[2]??0}),this.kcc=this.world.createCharacterController(.01),this.events=new e.EventQueue(!0),this.unregisterDebug=Q_(this),this.disconnect=t.fixedUpdated.connect(e=>this.step(e)),this.syncBodies()}simulate;step(e){if(this.lastDt=e,!this.simulate){this.syncBodies(),this.poseFromTree();return}if(this.engine.scene!==this.lastScene&&(this.lastScene=this.engine.scene,!this.optsGravity)){let e=this.engine.scene?.physics?.gravity??[0,-9.81,0];this.world.gravity={x:e[0]??0,y:e[1]??0,z:e[2]??0}}this.syncBodies(),this.world.timestep=e,this.world.step(this.events);for(let[e,t]of this.entries){let n=t.body.translation();if(!t.body.isFixed()){let[t,r,i]=YT(e),a=[n.x-t,n.y-r,n.z-i];e._interpPrev=e._interpCurr??a,e._interpCurr=a;let o=e.position;o[0]=a[0],o[1]=a[1],o[2]=a[2]}if(e instanceof Mh){if(!e.fixedRotation){let n=t.body.rotation();jT.setFromQuaternion(AT.set(n.x,n.y,n.z,n.w),`XYZ`);let r=e.rotation;r[0]=jT.x/DT,r[1]=jT.y/DT,r[2]=jT.z/DT}let n=t.body.linvel(),r=e.linearVelocity;r[0]=n.x,r[1]=n.y,r[2]=n.z,t.lastV[0]=n.x,t.lastV[1]=n.y,t.lastV[2]=n.z}let r=qT(e);t.last[0]=r[0],t.last[1]=r[1],t.last[2]=r[2]}this.events.drainCollisionEvents((e,t,n)=>{let r=this.byColliderHandle.get(e),i=this.byColliderHandle.get(t);if(!r||!i)return;let a=n?`triggerEnter`:`triggerExit`;try{r.emit(a,i),i.emit(a,r)}catch(e){lt(this.engine,`error`,`incanto: error in a '${a}' handler (${r.name} ↔ ${i.name}):`,e)}})}poseFromTree(){for(let[e,t]of this.entries){let[n,r,i]=qT(e);t.body.setTranslation({x:n,y:r,z:i},!1),AT.setFromEuler(jT.set((e.rotation[0]??0)*DT,(e.rotation[1]??0)*DT,(e.rotation[2]??0)*DT,`XYZ`)),t.body.setRotation({x:AT.x,y:AT.y,z:AT.z,w:AT.w},!1)}this.world.propagateModifiedBodyPositionsToColliders()}moveAndSlide(e){let t=this.ensureEntry(e);if(!t)return;let n=e.velocity[1]??0;e.snapToGround&&n<=0?this.kcc.enableSnapToGround(.1):this.kcc.disableSnapToGround(),this.kcc.setMaxSlopeClimbAngle(e.slopeLimitDeg*DT);let r=0,i=0,a=0;if(t.ground&&t.ground._physics===this&&t.groundAt){let[e,n,o]=qT(t.ground);r=e-t.groundAt[0],i=n-t.groundAt[1],a=o-t.groundAt[2]}else t.ground=null;let o={x:(e.velocity[0]??0)*this.lastDt+r,y:n*this.lastDt+i,z:(e.velocity[2]??0)*this.lastDt+a};this.kcc.computeColliderMovement(t.collider,o,this.R.QueryFilterFlags.EXCLUDE_SENSORS);let s=this.kcc.computedMovement(),c=t.body.translation(),l=c.x+s.x,u=c.y+s.y,d=c.z+s.z;if(t.body.setNextKinematicTranslation({x:l,y:u,z:d}),e._grounded=this.kcc.computedGrounded(),e._grounded){let n=KT(e),r=this.castRay([l,u-n+.05,d],[0,-1,0],.4,e);if(r?.node&&!(r.node instanceof Nh)){t.ground=r.node;let e=qT(r.node);t.groundAt=[e[0],e[1],e[2]]}else t.ground=null}else t.ground=null}debugLines(){if(!this.debugDraw)return null;let e=this.debugScope;if(!e)return this.world.debugRender().vertices;let t=this.scopedBodies(e),n=[];for(let e of t)for(let t=0;t<e.numColliders();t++){let r=e.collider(t);r&&ET(r,n)}return new Float32Array(n)}scopedBodies(e){let t=[],n=e=>{let r=this.entries.get(e);r&&t.push(r.body);let i=this.scatterBodies.get(e);i&&t.push(i);for(let t of e.children)n(t)};n(e);for(let n=e.parent;n&&t.length===0;n=n.parent){let e=this.entries.get(n);e&&t.push(e.body)}return t}dispose(){this.disconnect(),this.unregisterDebug(),this.world.free()}lastStructure=-1;lastRoot=null;jointSet=new Set;joints=new Map;scatterBodies=new Map;bodySet=new Set;syncScatters(e){for(let[,e]of this.scatterBodies)this.world.removeRigidBody(e);this.scatterBodies.clear();let t=new Set;WT(e,t);for(let e of t){let t=e.collider;if(!t)continue;let[n,r,i]=qT(e),a=this.world.createRigidBody(this.R.RigidBodyDesc.fixed().setTranslation(0,0,0)),[o,s,c]=e.size,l=null;for(let u of e.transforms){let d=u[4]??1,f=n+(u[0]??0),p=r+(u[1]??0),m=i+(u[2]??0),h=null;if(t.shape===`sphere`)h=this.R.ColliderDesc.ball(Math.max((t.radius??Math.max(o,c)/2)*d,.01));else if(t.shape===`box`){let e=t.size??[o,s,c];h=this.R.ColliderDesc.cuboid(Math.max((e[0]??1)*d/2,.01),Math.max((e[1]??1)*d/2,.01),Math.max((e[2]??1)*d/2,.01))}else{l??=FT(e.mesh,e.size);let t=new Float32Array(l.length);for(let e=0;e<t.length;e++)t[e]=l[e]*d;h=this.R.ColliderDesc.convexHull(t)}if(!h)continue;h.setTranslation(f,p,m);let g=(u[3]??0)*Math.PI/180;g!==0&&h.setRotation({x:0,y:Math.sin(g/2),z:0,w:Math.cos(g/2)}),this.world.createCollider(h,a)}this.scatterBodies.set(e,a)}}syncBodies(){let e=this.engine.scene;if(!e)return;let t=e.tree._structureVersion,n=e.root===this.lastRoot,r=t!==this.lastStructure||!n;if(r){let r=n?e.tree._structureSince(this.lastStructure):null;if(this.lastStructure=t,this.lastRoot=e.root,r){let t=!1,n=!1;for(let{node:e,added:i}of r)e instanceof kh&&(i?this.bodySet.add(e):this.bodySet.delete(e)),e instanceof Iw&&(t=!0),e instanceof Aw&&(n=!0);t&&(this.jointSet.clear(),MT(e.root,this.jointSet)),n&&this.syncScatters(e.root)}else this.bodySet.clear(),NT(e.root,this.bodySet),this.jointSet.clear(),MT(e.root,this.jointSet),this.syncScatters(e.root)}let i=this.bodySet;for(let e of i){if(e.collider.shape===void 0){let t=this.entries.get(e);t&&(this.byColliderHandle.delete(t.collider.handle),this.world.removeRigidBody(t.body),this.entries.delete(e),e._physics=null,e._interpPrev=e._interpCurr=null),this.warnedNoCollider.has(e)||(this.warnedNoCollider.add(e),lt(this.engine,`warn`,`[incanto] '${e.name}' has no collider — physics skips it.`));continue}let t=this.entries.get(e);t&&e._colliderChanged&&(this.byColliderHandle.delete(t.collider.handle),this.world.removeRigidBody(t.body),this.entries.delete(e),e._physics=null,e._interpPrev=e._interpCurr=null),this.ensureEntry(e)}if(this.syncJoints(r),r)for(let[e,t]of this.entries)i.has(e)||(this.byColliderHandle.delete(t.collider.handle),this.world.removeRigidBody(t.body),this.entries.delete(e),e._physics=null,e._interpPrev=e._interpCurr=null)}ensureEntry(e){let t=this.entries.get(e),n=this.R;if(!t){let r=XT(n,e);if(!r)return null;let i;i=e instanceof Mh?n.RigidBodyDesc.dynamic():e instanceof Nh||e instanceof jh?n.RigidBodyDesc.kinematicPositionBased():n.RigidBodyDesc.fixed();let[a,o,s]=qT(e);i.setTranslation(a,o,s),AT.setFromEuler(jT.set((e.rotation[0]??0)*DT,(e.rotation[1]??0)*DT,(e.rotation[2]??0)*DT,`XYZ`)),i.setRotation({x:AT.x,y:AT.y,z:AT.z,w:AT.w}),e instanceof Mh&&(i.setGravityScale(e.gravityScale),i.setLinvel(e.linearVelocity[0]??0,e.linearVelocity[1]??0,e.linearVelocity[2]??0),e.fixedRotation&&i.lockRotations());let c=this.world.createRigidBody(i);r.setActiveEvents(n.ActiveEvents.COLLISION_EVENTS),r.setActiveCollisionTypes(n.ActiveCollisionTypes.ALL),e instanceof jh&&r.setSensor(!0),e instanceof Mh&&r.setMass(e.mass).setFriction(e.friction).setRestitution(e.restitution);let l=this.world.createCollider(r,c);return t={body:c,collider:l,last:[a,o,s],lastV:[0,0,0]},this.entries.set(e,t),this.byColliderHandle.set(l.handle,e),e._colliderChanged=!1,e._physics=this,e instanceof Mh&&(e._physics3d=this),t}let r=qT(e);if((r[0]!==t.last[0]||r[1]!==t.last[1]||r[2]!==t.last[2])&&(t.body.setTranslation({x:r[0],y:r[1],z:r[2]},!0),t.last[0]=r[0],t.last[1]=r[1],t.last[2]=r[2],e._interpPrev=e._interpCurr=null),e instanceof Mh){let n=[e.linearVelocity[0]??0,e.linearVelocity[1]??0,e.linearVelocity[2]??0];(n[0]!==t.lastV[0]||n[1]!==t.lastV[1]||n[2]!==t.lastV[2])&&(t.body.setLinvel({x:n[0],y:n[1],z:n[2]},!0),t.lastV=n),e.gravityScale!==t.body.gravityScale()&&t.body.setGravityScale(e.gravityScale,!0)}return t}applyImpulse(e,t){this.entries.get(e)?.body.applyImpulse({x:t[0],y:t[1],z:t[2]},!0)}massOf(e){return this.entries.get(e)?.body.mass()??1}velocityOf(e){let t=this.entries.get(e)?.body.linvel();return t?[t.x,t.y,t.z]:[0,0,0]}syncJoints(e){let t=this.R;if(e)for(let[e,t]of this.joints)this.jointSet.has(e)||(this.world.removeImpulseJoint(t,!0),this.joints.delete(e));for(let e of this.jointSet){if(this.joints.has(e))continue;let{a:n,b:r}=e._resolveBodies(),i=this.entries.get(n),a=this.entries.get(r);if(!i||!a)continue;let o={x:e.anchor[0]??0,y:e.anchor[1]??0,z:e.anchor[2]??0},s={x:e.targetAnchor[0]??0,y:e.targetAnchor[1]??0,z:e.targetAnchor[2]??0},c=e.length;if(e.length===0&&(e.type===`rope`||e.type===`spring`)){let e=i.body.translation(),t=a.body.translation();c=Math.hypot(t.x-e.x,t.y-e.y,t.z-e.z)}let l={x:0,y:0,z:0,w:1},u;u=e.type===`fixed`?t.JointData.fixed(o,l,s,l):e.type===`rope`?t.JointData.rope(c,o,s):e.type===`spring`?t.JointData.spring(c,e.stiffness,e.damping,o,s):t.JointData.spherical(o,s),this.joints.set(e,this.world.createImpulseJoint(u,i.body,a.body,!0))}}castRay(e,t,n,r,i){let a=new this.R.Ray({x:e[0],y:e[1],z:e[2]},{x:t[0],y:t[1],z:t[2]}),o=r?this.entries.get(r)?.collider:void 0,s=i?.staticOnly?this.R.QueryFilterFlags.EXCLUDE_DYNAMIC|this.R.QueryFilterFlags.EXCLUDE_KINEMATIC:void 0,c=this.world.castRayAndGetNormal(a,n,!0,s,void 0,o,void 0,e=>!e.isSensor());return c?{distance:c.timeOfImpact,normal:[c.normal.x,c.normal.y,c.normal.z],node:this.byColliderHandle.get(c.collider.handle)??null}:null}castSphere(e,t,n,r,i,a){let o=this.R,s=i?this.entries.get(i):void 0,c=a?.staticOnly?o.QueryFilterFlags.EXCLUDE_DYNAMIC|o.QueryFilterFlags.EXCLUDE_KINEMATIC:void 0,l=this.world.castShape({x:e[0],y:e[1],z:e[2]},{x:0,y:0,z:0,w:1},{x:t[0],y:t[1],z:t[2]},new o.Ball(n),0,r,!0,c,void 0,s?.collider,s?.body,e=>!e.isSensor());return l?{distance:l.time_of_impact,node:this.byColliderHandle.get(l.collider.handle)??null}:null}},AT=new H,jT=new Qa;function MT(e,t){e instanceof Iw&&t.add(e);for(let n of e.children)MT(n,t)}function NT(e,t){e instanceof kh&&t.add(e);for(let n of e.children)NT(n,t)}function PT(e,t,n,r){let i=(n[0]??1)*r,a=(n[1]??1)*r,o=(n[2]??1)*r;switch(t){case`box`:return e.ColliderDesc.cuboid(i/2,a/2,o/2);case`sphere`:return e.ColliderDesc.ball(i);case`capsule`:return e.ColliderDesc.capsule(a/2,i);case`cylinder`:return e.ColliderDesc.cylinder(a/2,i);case`plane`:return e.ColliderDesc.cuboid(i/2,.01,o/2);default:return e.ColliderDesc.convexHull(FT(t,[i,a,o]))}}function FT(e,t){let n=kw(e,t),r=n.getAttribute(`position`),i=new Float32Array(r.count*3);for(let e=0;e<r.count;e++)i[e*3]=r.getX(e),i[e*3+1]=r.getY(e),i[e*3+2]=r.getZ(e);return n.dispose(),i}function IT(e){return typeof e._mountedObject3D==`function`}var LT=new G,RT=new G,zT=new U;function BT(e,t){let n=t._mountedObject3D();if(!n)return null;let r=e._ensureObject3D();r.updateWorldMatrix(!0,!0),LT.copy(r.matrixWorld).invert();let i=[],a=[];return n.traverse(e=>{let t=e;if(!t.isMesh)return;let n=t.geometry?.getAttribute(`position`);if(!n)return;RT.multiplyMatrices(LT,t.matrixWorld);let r=i.length/3;for(let e=0;e<n.count;e++)zT.set(n.getX(e),n.getY(e),n.getZ(e)).applyMatrix4(RT),i.push(zT.x,zT.y,zT.z);let o=t.geometry.getIndex();if(o)for(let e=0;e<o.count;e++)a.push(r+o.getX(e));else for(let e=0;e<n.count;e++)a.push(r+e)}),a.length<3?null:{vertices:new Float32Array(i),indices:new Uint32Array(a),triangles:a.length/3}}var VT=2e4;function HT(e){return!(e instanceof Mh||e instanceof Nh)}function UT(e,t,n){if(IT(e))n.push(e);else{let n=e;typeof n.mesh==`string`&&Array.isArray(n.size)&&t.push({name:e.name,mesh:n.mesh,size:n.size})}for(let r of e.children)UT(r,t,n)}function WT(e,t){e instanceof Aw&&e.collider&&t.add(e);for(let n of e.children)WT(n,t)}var GT=[0,0,0];function KT(e){let t=e.collider;return t?t.shape===`capsule`&&typeof t.height==`number`?t.height/2+(t.radius??0):t.shape===`box`&&Array.isArray(t.size)?(t.size[1]??2)/2:t.shape===`sphere`&&typeof t.radius==`number`?t.radius:1:1}function qT(e){let t=0,n=0,r=0;for(let i=e;i;i=i.parent)i instanceof Oh&&(t+=i.position[0]??0,n+=i.position[1]??0,r+=i.position[2]??0);return GT[0]=t,GT[1]=n,GT[2]=r,GT}var JT=[0,0,0];function YT(e){let t=0,n=0,r=0;for(let i=e.parent;i;i=i.parent)i instanceof Oh&&(t+=i.position[0]??0,n+=i.position[1]??0,r+=i.position[2]??0);return JT[0]=t,JT[1]=n,JT[2]=r,JT}function XT(e,t){let n=t.collider;if(Eh(n,t.name),n.shape===`heightfield`)return ZT(e,t);let r=QT(e,n,t.name,t);if(!r)return null;let i=n.offset;return Array.isArray(i)&&r.setTranslation(i[0]??0,i[1]??0,i[2]??0),r}function ZT(e,t){let n=t.children.find(e=>e instanceof hT);if(!n)throw new N(`BAD_FORMAT`,`Collider on '${t.name}': heightfield needs a Terrain3D CHILD of this body — add { "type": "Terrain3D" } under the StaticBody3D; the collider reads its height grid.`,{prop:`collider`});let r=n._heightmap(),i=r.segsZ,a=r.segsX,o=new Float32Array((i+1)*(a+1));for(let e=0;e<=a;e++)for(let t=0;t<=i;t++)o[e*(i+1)+t]=r.heights[t*(a+1)+e];let s=e.ColliderDesc.heightfield(i,a,o,{x:r.width,y:1,z:r.depth}),c=Array.isArray(t.collider.offset)?t.collider.offset:[];return s.setTranslation((n.position[0]??0)+(c[0]??0),(n.position[1]??0)+(c[1]??0),(n.position[2]??0)+(c[2]??0)),s}function QT(e,t,n,r){let i=t.shape;if(i===`box`){let r=t.size;if(!Array.isArray(r)||r.length!==3||r.some(e=>typeof e!=`number`))throw new N(`BAD_FORMAT`,`Collider on '${n}': box needs "size": [x, y, z].`);return e.ColliderDesc.cuboid(r[0]/2,r[1]/2,r[2]/2)}if(i===`sphere`){if(typeof t.radius!=`number`)throw new N(`BAD_FORMAT`,`Collider on '${n}': sphere needs "radius".`);return e.ColliderDesc.ball(t.radius)}if(i===`capsule`){if(typeof t.radius!=`number`||typeof t.height!=`number`)throw new N(`BAD_FORMAT`,`Collider on '${n}': capsule needs "radius" and "height".`);return e.ColliderDesc.capsule(t.height/2,t.radius)}if(i===`auto`){let t=[],i=[];r&&UT(r,t,i);let a=t[0],o=i[0];if(!a&&!o)throw new N(`BAD_FORMAT`,`Collider on '${n}': shape 'auto' needs a MeshInstance3D or ModelInstance3D on the body (or as a child) to take its shape from.`);let s=t.length+i.length;if(s>1&&console.warn(`[incanto] Collider on '${n}': shape 'auto' fits ONE mesh and took '${(a??o)?.name}'; ${s-1} other mesh(es) here are not solid. Give each part its own body.`),a){let t=PT(e,a.mesh,a.size,1);if(t)return t}else if(o&&r){let t=BT(r,o);return t?HT(r)?(t.triangles>VT&&console.warn(`[incanto] Collider on '${n}': shape 'auto' built a ${t.triangles}-triangle mesh from '${o.name}'. Consider a low-poly collision model or an explicit box.`),e.ColliderDesc.trimesh(t.vertices,t.indices)):e.ColliderDesc.convexHull(t.vertices):null}}if(i===`trimesh`){let r=t.vertices,i=t.indices;if(!Array.isArray(r)||!Array.isArray(i))throw new N(`BAD_FORMAT`,`Collider on '${n}': trimesh needs "vertices" (flat xyz) and "indices" (triangles).`);return e.ColliderDesc.trimesh(new Float32Array(r),new Uint32Array(i))}throw new N(`BAD_FORMAT`,`Collider on '${n}': "shape" must be 'auto', 'box', 'sphere', 'capsule', 'trimesh', or 'heightfield', got ${JSON.stringify(i)}.`)}var $T=new cl(1,1),eE=null;function tE(){if(eE)return eE;if(typeof document>`u`)return null;let e=document.createElement(`canvas`);e.width=64,e.height=64;let t=e.getContext(`2d`);if(!t)return null;let n=t.createRadialGradient(32,32,0,32,32,31);return n.addColorStop(0,`rgba(0,0,0,0.55)`),n.addColorStop(.55,`rgba(0,0,0,0.34)`),n.addColorStop(1,`rgba(0,0,0,0)`),t.fillStyle=n,t.fillRect(0,0,64,64),eE=new Qc(e),eE}var nE=new U(0,0,1),rE=new U,iE=new U,aE=new H,oE=new H,sE=new U,cE=.5,lE=class extends Oh{static typeName=`Sprite3D`;static props={texture:{default:``},size:{default:[1,1]},billboard:{default:`y`,options:[`y`,`full`,`none`]},anchor:{default:[.5,0]},tint:{default:`#ffffff`},opacity:{default:1},flipX:{default:!1},pixelArt:{default:!0},alphaTest:{default:.5},castShadow:{default:!1},shadowMode:{default:`silhouette`,options:[`silhouette`,`blob`]}};texture=``;size=[1,1];billboard=`y`;anchor=[.5,0];tint=`#ffffff`;opacity=1;flipX=!1;pixelArt=!0;alphaTest=.5;castShadow=!1;shadowMode=`silhouette`;quadMesh=null;textureRef=``;loadedTexture=null;shadowMesh=null;blobMesh=null;_quad(){return this.quadMesh||(this.quadMesh=new Ys($T,new Ls({transparent:!1,depthWrite:!0,side:2})),this._ensureObject3D().add(this.quadMesh)),this.quadMesh}resolveTexture(e){return this.texture?(this.textureRef!==this.texture&&(this.textureRef=this.texture,this.loadedTexture=mw(e,this.texture,{filter:this.pixelArt?`nearest`:`linear`})),this.loadedTexture):null}_syncObject3D(e=1,t=null){super._syncObject3D(e,t);let n=this._quad(),r=n.material,i=this.size[0]??1,a=this.size[1]??1;n.scale.set(this.flipX?-i:i,a,1);let o=this.anchor[0]??.5,s=this.anchor[1]??0;n.position.set((.5-o)*i,(.5-s)*a,0);let c=this.resolveTexture(t);r.map!==c&&(r.map=c,r.needsUpdate=!0),n.visible=c!==null,r.color.set(this.tint),r.opacity=this.opacity,r.transparent=this.opacity<1,r.alphaTest=this.alphaTest,n.renderOrder=this.renderOrder;let l=this.castShadow&&c!==null;if(n.castShadow=!1,l&&this.shadowMode===`silhouette`){let e=this._shadowCaster();e.visible=!0,e.castShadow=!0,e.scale.set(this.flipX?-i:i,a,1),e.position.set((.5-o)*i,(.5-s)*a,0);let t=e.material;t.map!==c&&(t.map=c,t.needsUpdate=!0);let n=e.customDepthMaterial;n.map!==c&&(n.map=c,n.needsUpdate=!0),t.alphaTest=this.alphaTest,n.alphaTest=this.alphaTest}else this.shadowMesh&&(this.shadowMesh.visible=!1,this.shadowMesh.castShadow=!1);if(l&&this.shadowMode===`blob`){let e=this._blob();e.visible=!0,e.scale.set(i*.52,i*.52,1)}else this.blobMesh&&(this.blobMesh.visible=!1)}_shadowCaster(){return this.shadowMesh||(this.shadowMesh=new Ys($T,new Ls({colorWrite:!1,depthWrite:!1,side:2})),this.shadowMesh.customDepthMaterial=new Sl({depthPacking:Di,side:2}),this._ensureObject3D().add(this.shadowMesh)),this.shadowMesh}_blob(){return this.blobMesh||(this.blobMesh=new Ys($T,new Ls({map:tE(),color:0,transparent:!0,depthWrite:!1})),this.blobMesh.rotation.x=-Math.PI/2,this.blobMesh.position.y=.02,this.blobMesh.renderOrder=-1,this._ensureObject3D().add(this.blobMesh)),this.blobMesh}_onRender3D(e){this.billboard===`y`?(e.camera.getWorldDirection(iE),iE.y=0,iE.lengthSq()>=1e-6&&this._faceDir(this._quad(),iE.negate())):this.billboard===`full`&&this._faceToward(this._quad(),e.camera.position);let t=this.shadowMesh;t?.castShadow&&e.sunDir&&(this._faceDir(t,e.sunDir),t.parent?.getWorldQuaternion(oE),sE.copy(e.sunDir).applyQuaternion(oE.invert()),t.position.addScaledVector(sE,cE))}_faceToward(e,t){e.getWorldPosition(rE),iE.copy(t).sub(rE),this.billboard===`y`&&(iE.y=0),!(iE.lengthSq()<1e-12)&&(iE.normalize(),aE.setFromUnitVectors(nE,iE),e.parent?.getWorldQuaternion(oE),e.quaternion.copy(oE.invert()).multiply(aE))}_faceDir(e,t){iE.copy(t),this.billboard===`y`&&(iE.y=0),!(iE.lengthSq()<1e-12)&&(iE.normalize(),aE.setFromUnitVectors(nE,iE),e.parent?.getWorldQuaternion(oE),e.quaternion.copy(oE.invert()).multiply(aE))}free(){this.loadedTexture?.dispose(),this.loadedTexture=null,this.shadowMesh&&(this.shadowMesh.material.dispose(),this.shadowMesh.customDepthMaterial?.dispose()),this.blobMesh&&this.blobMesh.material.dispose(),super.free()}},uE=class extends lE{static typeName=`AnimatedSprite3D`;static signals=[`animationFinished`];static props={sheet:{default:``},frameWidth:{default:0},frameHeight:{default:0},animations:{default:{}},autoplay:{default:``}};sheet=``;frameWidth=0;frameHeight=0;animations={};autoplay=``;playing=!1;currentFrame=0;currentAnimation=``;frameList=[];frameIndex=0;frameTime=0;sheetTexture=null;loadedSheetRef=``;play(e){let t=this.animations[e];if(!t)throw new N(`UNKNOWN_ANIMATION`,`No animation '${e}' on '${this.name}'. Available: [${Object.keys(this.animations).join(`, `)}].`);this.currentAnimation=e,this.frameList=dE(t.frames,e),this.frameIndex=0,this.currentFrame=this.frameList[0]??0,this.frameTime=0,this.playing=!0}stop(){this.playing=!1}onReady(){this.autoplay&&this.play(this.autoplay)}update(e){if(!this.playing||this.currentAnimation===``)return;let t=this.animations[this.currentAnimation];if(!t||!Number.isFinite(t.fps)||t.fps<=0)return;let n=1/t.fps;for(this.frameTime+=e;this.frameTime>=n;)if(this.frameTime-=n,this.frameIndex+=1,this.frameIndex>=this.frameList.length)if(t.loop)this.frameIndex=0;else{this.frameIndex=this.frameList.length-1,this.playing=!1,this.emit(`animationFinished`,this.currentAnimation);break}this.currentFrame=this.frameList[this.frameIndex]??0}resolveTexture(e){if(!this.sheet||this.frameWidth<=0||this.frameHeight<=0)return null;this.loadedSheetRef!==this.sheet&&(this.sheetTexture?.dispose(),this.loadedSheetRef=this.sheet,this.sheetTexture=hw(e,this.sheet,{filter:this.pixelArt?`nearest`:`linear`}));let t=this.sheetTexture;if(!t)return null;let n=t.image;if(!n?.width||!n.height)return t;let r=Math.max(1,Math.floor(n.width/this.frameWidth)),i=this.currentFrame%r,a=Math.floor(this.currentFrame/r);return t.repeat.set(this.frameWidth/n.width,this.frameHeight/n.height),t.offset.set(i*this.frameWidth/n.width,1-(a+1)*this.frameHeight/n.height),t}free(){this.sheetTexture?.dispose(),this.sheetTexture=null,super.free()}};function dE(e,t){if(!Array.isArray(e)||e.length===0)throw new N(`BAD_FORMAT`,`Animation '${t}': "frames" must be a non-empty array.`);if(e.length===2){let[t,n]=e;if(n>=t){let e=[];for(let r=t;r<=n;r++)e.push(r);return e}}return[...e]}var fE=new H,pE=new H,mE=new U,hE=new U(0,0,1),gE=[`screen`,`y`,`none`],_E=class extends Oh{static typeName=`Billboard3D`;static props={mode:{default:`screen`,options:gE}};mode=`screen`;_lastDesired=null;static validateJson(e){let t=e;if(!gE.includes(t.mode))throw new N(`BAD_FORMAT`,`Billboard3D '${e.name}' mode must be one of [${gE.join(`, `)}], got '${t.mode}'.`,{prop:`mode`,validOptions:gE})}_onRender3D(e){if(this.mode===`none`)return;let t=this._ensureObject3D();if(this.mode===`screen`)e.camera.getWorldQuaternion(pE);else if(e.camera.getWorldDirection(mE),mE.y=0,mE.lengthSq()>=1e-6)pE.setFromUnitVectors(hE,mE.negate().normalize());else if(this._lastDesired)pE.copy(this._lastDesired);else return;this._lastDesired||=new H,this._lastDesired.copy(pE),t.parent?.getWorldQuaternion(fE),t.parent?t.quaternion.copy(fE.invert()).multiply(pE):t.quaternion.copy(pE)}},vE=class extends Oh{static typeName=`BoneAttachment3D`;static props={target:{default:``,nodePath:!0},bone:{default:``}};target=``;bone=``;boneObj=null;lookedUpFor=``;get attachedBone(){return this.boneObj}_onRender3D(e){if(this.target===``||this.bone===``)return;let t=`${this.target} ${this.bone}`;if(this.lookedUpFor!==t||this.boneObj===null||!this.boneObj.parent){this.lookedUpFor=t,this.boneObj=null;let e=this.getNodeOrNull(this.target);e&&typeof e.findBone==`function`&&(this.boneObj=e.findBone(this.bone))}let n=this.boneObj;if(!n)return;let r=this._ensureObject3D(),i=r.parent;i&&(n.updateWorldMatrix(!0,!1),i.updateWorldMatrix(!0,!1),r.matrixAutoUpdate=!1,n.matrixWorld.decompose(xE,SE,CE),bE.compose(xE,SE,wE),r.updateMatrix(),yE.copy(r.matrix),r.matrix.copy(i.matrixWorld).invert().multiply(bE).multiply(yE))}free(){this.boneObj=null,super.free()}},yE=new G,bE=new G,xE=new U,SE=new H,CE=new U,wE=new U(1,1,1),TE=class extends Oh{static typeName=`BoneLookAt3D`;static props={target:{default:``,nodePath:!0},bone:{default:`Head`},lookAt:{default:``,nodePath:!0},maxAngleDeg:{default:75},weight:{default:.85},forwardAxis:{default:`+z`,options:[`+x`,`-x`,`+y`,`-y`,`+z`,`-z`]}};target=``;bone=`Head`;lookAt=``;maxAngleDeg=75;weight=.85;forwardAxis=`+z`;boneObj=null;lookedUpFor=``;engage=0;get attachedBone(){return this.boneObj}_onRender3D(e){if(this.target===``||this.bone===``)return;let t=`${this.target} ${this.bone}`;if(this.lookedUpFor!==t||this.boneObj===null||!this.boneObj.parent){this.lookedUpFor=t,this.boneObj=null;let e=this.getNodeOrNull(this.target);e&&typeof e.findBone==`function`&&(this.boneObj=e.findBone(this.bone))}let n=this.boneObj;if(!n?.parent)return;let r=this.lookAt===``?null:this.getNodeOrNull(this.lookAt),i=!1;if(r&&Array.isArray(r.position)&&(n.updateWorldMatrix(!0,!1),n.getWorldPosition(jE),ME.set(r.position[0]??0,r.position[1]??0,r.position[2]??0),NE.copy(ME).sub(jE),NE.lengthSq()>1e-6&&(NE.normalize(),PE.copy(DE[this.forwardAxis]??kE),FE.copy(PE).applyQuaternion(n.getWorldQuaternion(BE)),FE.angleTo(NE)<this.maxAngleDeg*Math.PI/180))){i=!0,IE.lookAt(jE,ME,OE),LE.setFromRotationMatrix(IE),RE.setFromUnitVectors(PE,AE),LE.multiply(RE),n.parent.getWorldQuaternion(zE).invert(),LE.premultiply(zE);let e=this.weight*this.engage;n.quaternion.slerp(LE,e)}this.engage+=(+!!i-this.engage)*EE}},EE=.18,DE={"+x":new U(1,0,0),"-x":new U(-1,0,0),"+y":new U(0,1,0),"-y":new U(0,-1,0),"+z":new U(0,0,1),"-z":new U(0,0,-1)},OE=new U(0,1,0),kE=new U(0,0,1),AE=new U(0,0,-1),jE=new U,ME=new U,NE=new U,PE=new U,FE=new U,IE=new G,LE=new H,RE=new H,zE=new H,BE=new H,VE=class extends Oh{static typeName=`Camera3D`;static props={fov:{default:60},near:{default:.1},far:{default:1e3},current:{default:!1}};fov=60;near=.1;far=1e3;current=!1;_createObject3D(){return new pu(this.fov,1,this.near,this.far)}_syncObject3D(){super._syncObject3D();let e=this._ensureObject3D();(e.fov!==this.fov||e.near!==this.near||e.far!==this.far)&&(e.fov=this.fov,e.near=this.near,e.far=this.far,e.updateProjectionMatrix())}},HE=8,UE=.2,WE=.15,GE=1.2,KE=.08,qE=2.5,JE=-20,YE=.002,XE=180/Math.PI,ZE=.3,QE=.4,$E=.3,eD=.25,tD=new Qa,nD=new H,rD=new G,iD=new U,aD=new U,oD=new U(0,1,0),sD=class extends Oh{static typeName=`CharacterController3D`;static signals=[`movementStateChanged`];static props={view:{default:`free`,options:[`free`,`firstPerson`,`quarter`,`side`]},camDistance:{default:4},eyeHeight:{default:.64},maxSpeed:{default:2.5},sprintMultiplier:{default:2},jumpVelocity:{default:4},sprintJumpMultiplier:{default:1.2},floatHeight:{default:.01},mouseLook:{default:!0},zoomMin:{default:0},zoomMax:{default:0},pitchMin:{default:-1.3},pitchMax:{default:1.5},cameraCollision:{default:!0},turnSpeed:{default:100},camLerp:{default:25},moveAction:{default:`move`},jumpAction:{default:`jump`},sprintAction:{default:`sprint`},skinPath:{default:`../Skin`,nodePath:!0},skinYawOffset:{default:0},animations:{default:{}}};view=`free`;camDistance=4;eyeHeight=.64;maxSpeed=2.5;sprintMultiplier=2;jumpVelocity=4;sprintJumpMultiplier=1.2;floatHeight=.01;mouseLook=!0;zoomMin=0;zoomMax=0;pitchMin=-1.3;pitchMax=1.5;cameraCollision=!0;turnSpeed=100;camLerp=25;moveAction=`move`;jumpAction=`jump`;sprintAction=`sprint`;skinPath=`../Skin`;skinYawOffset=0;animations={};yaw=0;pitch=0;state=`idle`;grounded=!1;get body(){let e=this.parent;if(!(e instanceof Mh))throw new N(`TREE_VIOLATION`,`CharacterController3D '${this.name}' must be a child of a RigidBody3D (parent is '${e?.name??`none`}').`);return e}onEnterTree(){if(this.body,this.skinPath!==``){let e=this.getNodeOrNull(this.skinPath);e&&(e.rotation=[e.rotation[0]??0,180+this.skinYawOffset,e.rotation[2]??0])}}fixedUpdate(e){let t=this.body,n=t._physics3d,r=this.tree?.engine?.input;if(!n||!r)return;let i=t.collider.radius??.32,a=(t.collider.height??1)/2,o=lD(t),s=n.velocityOf(t),c=n.massOf(t),l=i+this.floatHeight,u=i+2,d=o[1]-a,f=null;for(let[e,r]of[[0,0],[i,0],[-i,0],[0,i],[0,-i]]){let i=n.castRay([o[0]+e,d,o[2]+r],[0,-1,0],u,t);if(i){let t=i.distance;if(f=f===null?t:Math.min(f,t),e===0&&r===0)break}}this.grounded=f!==null&&f<l*2;let p=0,m=0,h=!1;try{let e=r.getVector(this.moveAction);h=e.x!==0||e.y!==0;let t=this.view===`free`||this.view===`firstPerson`?this.yaw:0,n=this.view===`side`?[e.x,0,0]:Sw(e.x,-e.y,t),i=Math.hypot(n[0],n[2])||1;p=n[0]/i,m=n[2]/i}catch{}let g=uD(r,this.sprintAction),_=Cw(h,g),v=1+(this.sprintMultiplier-1)*_,y=h?this.maxSpeed*v:0,b=this.grounded?1:UE,x=(p*y-s[0])/HE*b,S=(m*y-s[2])/HE*b;if(t.applyImpulse([x*c,0,S*c]),!h&&this.grounded&&t.applyImpulse([-s[0]*WE*c,0,-s[2]*WE*c]),f!==null&&f<l*2){let e=GE*(l-f)-s[1]*KE;t.applyImpulse([0,e*c,0])}if(this.grounded&&uD(r,this.jumpAction)){let e=this.jumpVelocity*(1+(this.sprintJumpMultiplier-1)*_);t.linearVelocity=[s[0],e,s[2]],this.grounded=!1}s[1]<JE?t.gravityScale=0:s[1]<0&&!this.grounded?t.gravityScale=qE:t.gravityScale=1,this.view===`side`&&Math.abs(o[2])>.01&&(t.position=[t.position[0]??0,t.position[1]??0,0]);let C=ww(this.grounded,h?_:0);if(C!==this.state){this.state=C;let e=this.animations[C];if(e&&this.skinPath!==``){let t=this.getNodeOrNull(this.skinPath);t&&`animation`in t&&(t.animation=e)}this.emit(`movementStateChanged`,C)}if(h&&this.skinPath!==``){let t=this.getNodeOrNull(this.skinPath);if(t){let n=Math.atan2(p,m)*XE+this.skinYawOffset,r=t.rotation[1]??0,i=(n-r+540)%360-180,a=this.turnSpeed*e*XE;Math.abs(i)>a&&(i=Math.sign(i)*a),t.rotation=[t.rotation[0]??0,r+i,t.rotation[2]??0]}}}update(e){let t=this.tree?.engine?.input;if(!t)return;if(this.mouseLook){let e=t.pointerDelta();this.yaw-=e.x*YE,this.pitch=cD(this.pitch+e.y*YE,-this.pitchMax,-this.pitchMin);let n=t.wheelDelta();n!==0&&this.zoomMax>this.zoomMin&&(this.camDistance=cD(this.camDistance+n*YE,this.zoomMin,this.zoomMax))}let n=this.findCamera();if(!n)return;let r=this.parent instanceof Mh?this.parent:null;if(!r)return;let i=lD(r),a=this.view===`free`?11:1e3,o=1-Math.exp(-a*e),s=this.pivot??[i[0],i[1],i[2]];this.pivot=s,s[0]+=(i[0]-s[0])*o,s[1]+=(i[1]-s[1])*o,s[2]+=(i[2]-s[2])*o;let c=yw(this.view,s,this.eyeHeight,this.yaw,this.pitch,this.camDistance),l=[s[0],s[1]+this.eyeHeight,s[2]],u=[c.position[0],c.position[1],c.position[2]];if(this.cameraCollision&&this.view!==`firstPerson`){let e=r._physics3d;e&&(u=bw(l,u,(t,n,i)=>e.castSphere(t,n,eD,i,r,{staticOnly:!0})?.distance??null,ZE,QE),u=xw(u,(t,n)=>e.castRay(t,[0,-1,0],n,r,{staticOnly:!0})?.distance??null,$E))}let d=this.view===`firstPerson`?1e3:this.camLerp,f=1-Math.exp(-d*e),p=n.position;n.position=[(p[0]??0)+(u[0]-(p[0]??0))*f,(p[1]??0)+(u[1]-(p[1]??0))*f,(p[2]??0)+(u[2]-(p[2]??0))*f],this.view===`free`?(iD.set(n.position[0]??0,n.position[1]??0,n.position[2]??0),aD.set(l[0],l[1],l[2]),rD.lookAt(iD,aD,oD),nD.setFromRotationMatrix(rD),tD.setFromQuaternion(nD,`XYZ`)):(tD.set(c.rotation[0],c.rotation[1],c.rotation[2],`YXZ`),nD.setFromEuler(tD),tD.setFromQuaternion(nD,`XYZ`)),n.rotation=[tD.x*XE,tD.y*XE,tD.z*XE]}pivot=null;cameraCache=null;findCamera(){if(this.cameraCache?.tree===this.tree&&this.cameraCache.current)return this.cameraCache;this.cameraCache=null;let e=this.tree?.root;if(!e)return null;let t=e=>{if(!this.cameraCache){if(e instanceof VE&&e.current){this.cameraCache=e;return}for(let n of e.children)t(n)}};return t(e),this.cameraCache}};function cD(e,t,n){return Math.min(n,Math.max(t,e))}function lD(e){let t=0,n=0,r=0;for(let i=e;i&&i instanceof Oh;i=i.parent)t+=i.position[0]??0,n+=i.position[1]??0,r+=i.position[2]??0;return[t,n,r]}function uD(e,t){try{return e.isPressed(t)}catch{return!1}}var dD=.15,fD=.7,pD=.5,mD=.7,hD=.5;function gD(e,t,n=3){let r=0,i=1,a=1,o=.65;for(let s=0;s<n;s++){let n=e*a,s=t*a,c=Math.sin(n*.1+s*.2)*.5+.5,l=Math.cos(n*.3+s*.1)*.5+.5,u=Math.sin((n+s)*.15)*.5+.5,d=Math.cos(n*n*.01+s*.2)*.5+.5,f=c*l*.7+u*d*.3;r+=f*i,i*=o,a*=2}return r/((1-o**n)/(1-o))}function _D(e,t){let n=gD(e*dD,t*dD,4),r=gD(e*dD*.2,t*dD*.2,2);return n>pD-fD*.5-r*hD}var vD=.9;function yD(e,t,n){let r=(Math.imul(e,2246822507)^Math.imul(t,3266489909)^Math.imul(n+1,668265263))>>>0;return r=Math.imul(r^r>>>15,739982445)>>>0,r=Math.imul(r^r>>>12,695872825)>>>0,r^=r>>>15,(r>>>0)/4294967296}function bD(e,t,n=vD){let r=Math.floor(e/n),i=Math.floor(t/n),a=1/0,o=r,s=i;for(let c=-1;c<=1;c++)for(let l=-1;l<=1;l++){let u=r+l,d=i+c,f=(u+yD(u,d,0))*n,p=(d+yD(u,d,1))*n,m=(e-f)*(e-f)+(t-p)*(t-p);m<a&&(a=m,o=u,s=d)}return{id:Math.imul(o,2654435761)^Math.imul(s,2246822519)|0,hue:yD(o,s,2)*2-1,leanDir:yD(o,s,3)*Math.PI*2,lean:yD(o,s,4)}}function xD(e,t,n,r){let i=e*r,a=t*r,o=Math.floor(i),s=Math.floor(a),c=i-o,l=a-s,u=c*c*(3-2*c),d=l*l*(3-2*l),f=yD(o,s,n),p=yD(o+1,s,n),m=yD(o,s+1,n),h=yD(o+1,s+1,n),g=f+(p-f)*u;return g+(m+(h-m)*u-g)*d}var SD=[.55,1.7],CD=.17,wD=.23,TD=.28;function ED(e,t,n){let r=xD(e,t,n^6877377|0,CD),i=r*r*(3-2*r);return SD[0]+(SD[1]-SD[0])*i}function DD(e,t,n){return xD(e,t,n^3001105|0,wD)}function OD(e,t,n){let r=xD(e,t,n^7840757|0,TD)*.72+xD(e,t,n^1688295|0,TD*3.1)*.28,i=Math.min(1,Math.max(0,(r-.18)/.64));return i*i*(3-2*i)}function kD(e){let{seed:t,areaX:n,areaZ:r,count:i,density:a}=e,o=new P(t),s=n/2,c=r/2,l=[],u=Math.floor(i*mD);for(let e=0;e<u&&l.length<i;e++){let e=o.range(-s,s),t=o.range(-c,c),n=o.next()<.3,r=_D(e,t);if(!n&&!r&&o.next()>.15)continue;let i=o.next()*Math.PI*2,a=.5+o.next()*.7,u=r?a*(1+o.next()*.2):a*(.9+o.next()*.2);l.push({x:e,z:t,rotY:i,scale:u})}let d=Math.min(3,Math.max(1,a*10)),f=Math.ceil(Math.sqrt(i*d)),p=n/f,m=r/f,h=Math.floor((i-l.length)*.8),g=0;for(let e=0;e<f&&l.length<i;e++)for(let t=0;t<f&&l.length<i;t++){let i=t/f*n-s+p/2,a=e/f*r-c+m/2,u=i+(o.next()-.5)*p*1.5,d=a+(o.next()-.5)*m*1.5;if(u<-s||u>s||d<-c||d>c)continue;let _=_D(u,d);if(g<h){if(!_&&o.next()>.05)continue}else if(_){if(o.next()>.2)continue}else if(o.next()>.4)continue;if(o.next()<.2)continue;let v=o.next()*Math.PI*2,y=_?.5:.3;l.push({x:u,z:d,rotY:v,scale:.5+o.next()*y}),g++}for(;l.length<i;)l.push({x:o.range(-s,s),z:o.range(-c,c),rotY:o.next()*Math.PI*2,scale:.4+o.next()*.6});return l.sort((e,t)=>t.z-e.z),l}var AD=[`daisy`,`cosmos`,`bellflower`],jD={daisy:{petals:8,blooms:3,leaves:3,petalLength:.1,petalWidth:.052,cupDeg:16,nodDeg:14,centerRadius:.024,centerColor:`#e0a72e`},cosmos:{petals:8,blooms:2,leaves:2,petalLength:.12,petalWidth:.064,cupDeg:26,nodDeg:18,centerRadius:.023,centerColor:`#d2941f`},bellflower:{petals:5,blooms:3,leaves:2,petalLength:.088,petalWidth:.058,cupDeg:46,nodDeg:52,centerRadius:.015,centerColor:`#cfe06a`}},MD=[1,.78,.62],ND=[0,.07,.11],PD=[.6,2.7,4.9],FD=.07,ID=.011,LD=.17,RD=.05,zD=[.12,.2,.28],BD=new K(`#3e6a26`),VD=new K(`#548331`);function HD(e){let t=jD[e],n=new UD(!0),r=new UD(!1),i=new K(t.centerColor);for(let e=0;e<t.blooms;e++){let a=MD[e],o=PD[e],s=ND[e]*Math.cos(o),c=ND[e]*Math.sin(o),l=FD*Math.cos(o),u=FD*Math.sin(o),d=new U(s,0,c),f=new U(s+l,a,c+u),p=new U(s+l*.25,a*.55,c+u*.25);n.addStem(d,p,f,ID,BD);let m=t.nodDeg*Math.PI/180,h=new U(Math.sin(m)*Math.cos(o),Math.cos(m),Math.sin(m)*Math.sin(o)),g=new U(-Math.sin(o),0,Math.cos(o)),_=new U().crossVectors(h,g).normalize(),v=f.clone().addScaledVector(h,.012),y=t.cupDeg*Math.PI/180,b=e*.45;for(let e=0;e<t.petals;e++){let n=e/t.petals*Math.PI*2+b,i=g.clone().multiplyScalar(Math.cos(n)).addScaledVector(_,Math.sin(n)).normalize();r.addPetal(v,i,h,t,y)}n.addDisc(v.clone().addScaledVector(h,.004),g,_,t.centerRadius,i)}for(let e=0;e<t.leaves;e++){let t=zD[e%zD.length],r=1.1+e*2.3;n.addLeaf(new U(0,t,0),r,VD)}return{structure:n.build(),petals:r.build()}}var UD=class{positions=[];colors;indices=[];constructor(e){this.colors=e?[]:null}vertex(e,t){let n=this.positions.length/3;return this.positions.push(e.x,e.y,e.z),this.colors&&t&&this.colors.push(t.r,t.g,t.b),n}addStem(e,t,n,r,i){for(let a of[0,Math.PI/2]){let o=new U(Math.cos(a),0,Math.sin(a)),s=[];for(let a=0;a<=5;a++){let c=a/5,l=1-c,u=new U(l*l*e.x+2*l*c*t.x+c*c*n.x,l*l*e.y+2*l*c*t.y+c*c*n.y,l*l*e.z+2*l*c*t.z+c*c*n.z),d=r/2*(1-.4*c);s.push(this.vertex(u.clone().addScaledVector(o,-d),i),this.vertex(u.clone().addScaledVector(o,d),i))}for(let e=0;e<5;e++){let t=s[e*2],n=s[e*2+1],r=s[e*2+2],i=s[e*2+3];this.indices.push(t,n,r,r,n,i)}}}addPetal(e,t,n,r,i){let a=new U().crossVectors(n,t).normalize(),o=r.centerRadius*.85,s=Math.sin(i)*r.petalLength*.45,c=Math.sin(i)*r.petalLength*.95,l=Math.cos(i),u=e.clone().addScaledVector(t,o),d=o+r.petalLength*l*.55,f=o+r.petalLength*l,p=e.clone().addScaledVector(t,d).addScaledVector(a,r.petalWidth/2).addScaledVector(n,s),m=e.clone().addScaledVector(t,d).addScaledVector(a,-r.petalWidth/2).addScaledVector(n,s),h=e.clone().addScaledVector(t,f).addScaledVector(n,c),g=this.vertex(u,null),_=this.vertex(p,null),v=this.vertex(m,null),y=this.vertex(h,null);this.indices.push(g,_,y,g,y,v)}addDisc(e,t,n,r,i){let a=this.vertex(e,i),o=[];for(let a=0;a<6;a++){let s=a/6*Math.PI*2;o.push(this.vertex(e.clone().addScaledVector(t,Math.cos(s)*r).addScaledVector(n,Math.sin(s)*r),i))}for(let e=0;e<6;e++)this.indices.push(a,o[e],o[(e+1)%6])}addLeaf(e,t,n){let r=new U(Math.cos(t),0,Math.sin(t)),i=new U(-Math.sin(t),0,Math.cos(t)),a=Math.sin(.6),o=Math.cos(.6),s=e.clone().addScaledVector(r,LD*o*.5).add(new U(0,LD*a*.5,0)),c=e.clone().addScaledVector(r,LD*o).add(new U(0,LD*a*.8,0)),l=this.vertex(e,n),u=this.vertex(s.clone().addScaledVector(i,RD/2),n),d=this.vertex(s.clone().addScaledVector(i,-.05/2),n),f=this.vertex(c,n);this.indices.push(l,u,f,l,f,d)}build(){let e=new J;return e.setAttribute(`position`,new q(new Float32Array(this.positions),3)),this.colors&&e.setAttribute(`color`,new q(new Float32Array(this.colors),3)),e.setIndex(this.indices),e.computeVertexNormals(),e}},WD=2.6;function GD(e){let{seed:t,areaX:n,areaZ:r,count:i,clustering:a}=e,o=new P(t),s=n/2,c=r/2,l=1-.74*Math.min(Math.max(a,0),1),u=[];for(let e=0;e<i*16&&u.length<i;e++){let e=o.range(-s,s),t=o.range(-c,c),n=bD(e,t,WD);n.lean>l&&o.next()>.06||u.push({x:e,z:t,rotY:o.next()*Math.PI*2,scale:.75+o.next()*.5,variety01:(n.hue+1)/2,color01:n.leanDir/(Math.PI*2)})}return u}var KD=1.05,qD=1;function JD(e,t=qD){e.computeBoundingSphere();let n=e.boundingSphere;n&&n.radius>=0&&(n.radius=n.radius*KD+t),e.frustumCulled=!0}function YD(e){let t=0,n=0,r=0;for(let i=e;i;i=i.parent)i instanceof Oh&&(t+=i.position[0]??0,n+=i.position[1]??0,r+=i.position[2]??0);return[t,n,r]}function XD(e,t){if(t!==``){let n=e.getNodeOrNull(t);return n instanceof hT?n:null}return ZD(e.getRoot())}function ZD(e){if(e instanceof hT)return e;for(let t of e.children){let e=ZD(t);if(e)return e}return null}function QD(e){return typeof e?._waterYAt==`function`}function $D(e){let t=e;for(;t.parent;)t=t.parent;let n=[],r=e=>{e.visible!==!1&&QD(e)&&n.push(e);for(let t of e.children)r(t)};return r(t),n}function eO(e,t,n,r,i=.06){for(let a=0;a<e.length;a++){let o=e[a]?._waterYAt(t,n);if(o!=null&&o-r>i)return!0}return!1}var tO={lush:2.2,sparse:.35,none:0},nO=[`lush`,`sparse`,`none`];function rO(e){if(typeof e==`number`)return e;let t=tO[e];if(t===void 0)throw new N(`BAD_FORMAT`,`Flowers3D density must be one of [${nO.join(`, `)}] or a number (plants/m²), got '${e}'.`,{prop:`density`,validOptions:nO});return t}var iO=1e4,aO=[`#f5f1e2`,`#e9d052`,`#8d7bd9`],oO=/^#[0-9a-fA-F]{6}$/,sO=class extends Oh{static typeName=`Flowers3D`;static props={density:{default:`sparse`,options:nO},area:{default:[20,20]},seed:{default:1},varieties:{default:[]},palette:{default:[]},height:{default:.45},clustering:{default:.6},sway:{default:.5},drape:{default:null},avoidWater:{default:!0},terrain:{default:``,nodePath:!0}};density=`sparse`;area=[20,20];seed=1;varieties=[];palette=[];height=.45;clustering=.6;sway=.5;drape=null;avoidWater=!0;terrain=``;drapeTerrain=null;drapeWorld=[0,0,0];static validateJson(e){let t=e;if(typeof t.density==`string`)rO(t.density);else if(!(Number.isFinite(t.density)&&t.density>=0))throw new N(`BAD_FORMAT`,`Flowers3D '${e.name}' density must be one of [${nO.join(`, `)}] or a number >= 0 (plants/m²), got ${t.density}.`,{prop:`density`,validOptions:nO});if(!((t.area[0]??0)>0)||!((t.area[1]??0)>0))throw new N(`BAD_FORMAT`,`Flowers3D '${e.name}' area must be positive [x, z] meters, got ${JSON.stringify(t.area)}.`,{prop:`area`});let n=Math.floor((t.area[0]??0)*(t.area[1]??0)*rO(t.density));if(n>iO)throw new N(`BAD_FORMAT`,`Flowers3D '${e.name}' blows the plant budget: area ${t.area[0]}×${t.area[1]} m × density ${rO(t.density)} = ${n} plants > ${iO}. Lower the density or split the field into multiple nodes.`,{prop:`density`});if(!Array.isArray(t.varieties)||new Set(t.varieties).size!==t.varieties.length||!t.varieties.every(e=>AD.includes(e)))throw new N(`BAD_FORMAT`,`Flowers3D '${e.name}' varieties must be a unique subset of [${AD.join(`, `)}] ([] = all three), got ${JSON.stringify(t.varieties)}.`,{prop:`varieties`,validOptions:[...AD]});if(!Array.isArray(t.palette)||!t.palette.every(e=>typeof e==`string`&&oO.test(e)))throw new N(`BAD_FORMAT`,`Flowers3D '${e.name}' palette must be an array of '#rrggbb' head colors ([] = white/yellow/violet), got ${JSON.stringify(t.palette)}.`,{prop:`palette`});if(!(t.height>0))throw new N(`BAD_FORMAT`,`Flowers3D '${e.name}' height must be > 0 meters, got ${t.height}.`,{prop:`height`});if(!(t.clustering>=0)||!(t.clustering<=1))throw new N(`BAD_FORMAT`,`Flowers3D '${e.name}' clustering must be in [0, 1] (0 uniform … 1 tight patches), got ${t.clustering}.`,{prop:`clustering`});if(!(t.sway>=0))throw new N(`BAD_FORMAT`,`Flowers3D '${e.name}' sway must be >= 0, got ${t.sway}.`,{prop:`sway`});if(t.drape!==null&&typeof t.drape!=`boolean`)throw new N(`BAD_FORMAT`,`Flowers3D '${e.name}' drape must be true, false or null (null = auto: drape whenever the scene has a Terrain3D), got ${JSON.stringify(t.drape)}.`,{prop:`drape`});if(typeof t.terrain!=`string`)throw new N(`BAD_FORMAT`,`Flowers3D '${e.name}' terrain must be a node-path string (empty = auto-find), got ${JSON.stringify(t.terrain)}.`,{prop:`terrain`})}time=0;field=null;varietyMeshes=[];fieldKey=``;timeUniform={value:0};swayUniform={value:.5};_createObject3D(){return new _o}_varietyMeshes(){return this.rebuildIfNeeded(),this.varietyMeshes}update(e){this.time+=e,this.timeUniform.value=this.time}_syncObject3D(){super._syncObject3D(),this.rebuildIfNeeded(),this.swayUniform.value=this.sway}rebuildIfNeeded(){this.field||(this.field=new _o,this._ensureObject3D().add(this.field));let e=JSON.stringify([this.density,this.area,this.seed,this.varieties,this.palette,this.height,this.clustering,this.drape,this.terrain]);e!==this.fieldKey&&(this.fieldKey=e,this.disposeMeshes(),this.resolveDrape(),this.buildField())}resolveDrape(){if(this.drapeTerrain=null,this.drape===!1)return;let e=XD(this,this.terrain);if(e)this.drapeTerrain=e,this.drapeWorld=YD(this);else if(this.terrain!==``)throw new N(`NODE_NOT_FOUND`,`Flowers3D '${this.name}' drape terrain '${this.terrain}' is not a Terrain3D in the tree.`,{prop:`terrain`})}bedY(e,t){let n=this.drapeTerrain;return n?n.heightAt(this.drapeWorld[0]+e,this.drapeWorld[2]+t)-this.drapeWorld[1]:0}buildField(){let e=rO(this.density),t=Math.min(Math.floor((this.area[0]??0)*(this.area[1]??0)*e),iO);if(t<=0)return;let n=GD({seed:this.seed,areaX:this.area[0]??0,areaZ:this.area[1]??0,count:t,clustering:this.clustering});if(this.avoidWater){let e=$D(this);if(e.length>0){let[t,r,i]=YD(this);n=n.filter(n=>!eO(e,n.x+t,n.z+i,this.bedY(n.x,n.z)+r))}}let r=this.varieties.length>0?this.varieties:AD,i=r.map(()=>[]);for(let e of n)i[Math.min(Math.floor(e.variety01*r.length),r.length-1)].push(e);let a=this.palette.length>0?this.palette:aO,o=new P(this.seed+15797765);for(let e=0;e<r.length;e++){let t=i[e];if(t.length===0)continue;let{structure:n,petals:s}=HD(r[e]),c=new bl({vertexColors:!0,roughness:1,side:2}),l=new bl({roughness:.85,side:2});cO(c,this.timeUniform,this.swayUniform),cO(l,this.timeUniform,this.swayUniform);let u=new xc(n,c,t.length),d=new xc(s,l,t.length);u.receiveShadow=!0,d.receiveShadow=!0;for(let e=0;e<t.length;e++){let n=t[e];dO.set(n.x,this.bedY(n.x,n.z),n.z),fO.setFromAxisAngle(lO,n.rotY),pO.setScalar(this.height*n.scale),uO.compose(dO,fO,pO),u.setMatrixAt(e,uO),d.setMatrixAt(e,uO);let r=Math.min(Math.floor(n.color01*a.length),a.length-1);mO.set(a[r]).offsetHSL(o.range(-.02,.02),0,o.range(-.05,.05)),d.setColorAt(e,mO),mO.setRGB(1,1,1).offsetHSL(o.range(-.02,.02),0,o.range(-.06,.04)),u.setColorAt(e,mO)}u.instanceMatrix.needsUpdate=!0,d.instanceMatrix.needsUpdate=!0,u.instanceColor&&(u.instanceColor.needsUpdate=!0),d.instanceColor&&(d.instanceColor.needsUpdate=!0),JD(u),JD(d),this.varietyMeshes.push({variety:r[e],structure:u,petals:d}),this.field.add(u),this.field.add(d)}}disposeMeshes(){for(let{structure:e,petals:t}of this.varietyMeshes)for(let n of[e,t])n.removeFromParent(),n.geometry.dispose(),n.material.dispose(),n.dispose();this.varietyMeshes=[]}free(){this.disposeMeshes(),this.field=null,super.free()}};function cO(e,t,n){e.userData.sway=!0,e.userData.timeUniform=t,e.onBeforeCompile=e=>{e.uniforms.uFlowerTime=t,e.uniforms.uFlowerSway=n,e.vertexShader=`uniform float uFlowerTime;\nuniform float uFlowerSway;\n${e.vertexShader}`.replace(`#include <project_vertex>`,`
|
|
6976
|
+
`;function tT(e,t){for(let n=0;n<4;n++){let r=n+1;e.uniforms[`splatTexture${r}`]={value:t.textures[n]??t.textures[0]??null},e.uniforms[`splatNormalMap${r}`]={value:t.normalMaps[n]??null},e.uniforms[`splatTextureRepeat${r}`]={value:t.repeats[n]??1},e.uniforms[`splatRoughness${r}`]={value:t.roughness[n]??1},e.uniforms[`splatMetalness${r}`]={value:t.metalness[n]??0},e.uniforms[`uvNoiseIntensity${r}`]={value:t.uvNoiseIntensity[n]??.15}}e.uniforms.splatTextureCount={value:Math.min(4,t.layerCount)},e.uniforms.uWetlineY={value:-1e9},e.uniforms.uWetlineBand={value:1.1},e.uniforms.uWetTime={value:0},e.uniforms.splatEnvCut={value:t.envCut},e.vertexShader=Kw(e.vertexShader,`#include <common>`,qw),e.vertexShader=Kw(e.vertexShader,`#include <begin_vertex>`,Jw);let n=e.fragmentShader;n=Kw(n,`#include <common>`,Yw),n=Kw(n,`#include <color_fragment>`,Xw),n=Kw(n,`#include <roughnessmap_fragment>`,Zw),n=Kw(n,`#include <metalnessmap_fragment>`,$w),n=Kw(n,`#include <normal_fragment_maps>`,eT),n=Kw(n,`#include <lights_fragment_maps>`,Qw),t.hasNormalMaps&&(n=`#define USE_TERRAIN_NORMALMAP\n${n}`),e.fragmentShader=n}var nT=[`island`,`alpine`,`plains`,`desert`,`grassland`,`forest`,`savanna`,`snow`,`wetland`,`volcanic`,`custom`],rT=`https://agent8-games.verse8.io/assets/3D/default/textures/terrain`,iT=`https://agent8-games.verse8.io/assets/3D/default/textures/vegetation/ground`,aT=1/3,oT=Math.PI/4;function sT(e,t,n){return{texture:`${e}/${t}.png`,normalMap:`${e}/${t}_normal.png`,...n}}function cT(e,t){let n=t.replace(/\/$/,``);switch(e){case`island`:return[sT(n,`sand`,{heightRange:[0,.12],slopeRange:[0,Math.PI/2],heightBlendRange:.05,roughness:.9}),sT(n,`grass`,{heightRange:[.1,.7],slopeRange:[0,oT],heightBlendRange:.1,slopeBlendRange:.1,roughness:.8}),sT(n,`stone`,{heightRange:[0,1],slopeRange:[oT,Math.PI],heightBlendRange:.5,slopeBlendRange:.5,roughness:.85}),sT(n,`snow`,{heightRange:[.8,1],slopeRange:[0,Math.PI/3],heightBlendRange:.1,roughness:.6})];case`alpine`:return[sT(n,`grass`,{heightRange:[0,.45],slopeRange:[0,Math.PI/5],heightBlendRange:.1,roughness:.8}),sT(n,`stone`,{heightRange:[.3,1],slopeRange:[0,Math.PI],heightBlendRange:.25,slopeBlendRange:.5,roughness:.85}),sT(n,`gravel`,{heightRange:[0,1],slopeRange:[Math.PI/5,Math.PI],heightBlendRange:.5,slopeBlendRange:.15,roughness:.9}),sT(n,`snow`,{heightRange:[.55,1],slopeRange:[0,Math.PI/3],heightBlendRange:.12,roughness:.55})];case`plains`:return[sT(n,`grass`,{heightRange:[0,1],slopeRange:[0,oT],heightBlendRange:.1,slopeBlendRange:.1,roughness:.8}),sT(n,`dirt`,{heightRange:[.35,.65],slopeRange:[0,Math.PI/5],heightBlendRange:.2,roughness:.9}),sT(n,`gravel`,{heightRange:[0,1],slopeRange:[oT,Math.PI],heightBlendRange:.5,slopeBlendRange:.3,roughness:.9})];case`desert`:return[sT(n,`sand`,{heightRange:[0,1],slopeRange:[0,oT],heightBlendRange:.1,slopeBlendRange:.15,roughness:.95}),sT(n,`gravel`,{heightRange:[0,.15],slopeRange:[0,Math.PI/3],heightBlendRange:.08,roughness:.9}),sT(n,`stone`,{heightRange:[0,1],slopeRange:[oT,Math.PI],heightBlendRange:.5,slopeBlendRange:.4,roughness:.85})];case`grassland`:return n===`https://agent8-games.verse8.io/assets/3D/default/textures/terrain`?[{texture:`${iT}/grass.jpg`,heightRange:[0,1],slopeRange:[0,oT],heightBlendRange:.1,slopeBlendRange:.15,roughness:1,repeat:aT,uvNoiseIntensity:0},{texture:`${iT}/dirt_color.jpg`,heightRange:[0,1],slopeRange:[oT,Math.PI],heightBlendRange:.5,slopeBlendRange:.3,roughness:1,repeat:aT,uvNoiseIntensity:0}]:[sT(n,`grass`,{heightRange:[0,1],slopeRange:[0,oT],heightBlendRange:.1,slopeBlendRange:.15,roughness:.8}),sT(n,`dirt`,{heightRange:[0,1],slopeRange:[oT,Math.PI],heightBlendRange:.5,slopeBlendRange:.3,roughness:.9})];case`forest`:return n===`https://agent8-games.verse8.io/assets/3D/default/textures/terrain`?[{texture:`${iT}/dirt_color.jpg`,heightRange:[0,1],slopeRange:[0,Math.PI],heightBlendRange:.1,roughness:1,repeat:aT,uvNoiseIntensity:0},{texture:`${iT}/grass.jpg`,heightRange:[-2,-1],roughness:1,repeat:aT,uvNoiseIntensity:0}]:[sT(n,`dirt`,{heightRange:[0,1],slopeRange:[0,Math.PI],heightBlendRange:.1,roughness:.9}),sT(n,`grass`,{heightRange:[-2,-1],roughness:.8})];case`savanna`:return[sT(n,`grass`,{heightRange:[0,1],slopeRange:[0,oT],heightBlendRange:.1,slopeBlendRange:.15,roughness:.95}),sT(n,`sand`,{heightRange:[0,.22],slopeRange:[0,Math.PI/4],heightBlendRange:.12,roughness:.95}),sT(n,`dirt`,{heightRange:[0,1],slopeRange:[oT,Math.PI],heightBlendRange:.5,slopeBlendRange:.3,roughness:.95})];case`snow`:return[sT(n,`snow`,{heightRange:[0,1],slopeRange:[0,oT],heightBlendRange:.1,slopeBlendRange:.18,roughness:.55}),sT(n,`stone`,{heightRange:[0,1],slopeRange:[oT,Math.PI],heightBlendRange:.5,slopeBlendRange:.35,roughness:.85})];case`wetland`:return[sT(n,`grass`,{heightRange:[0,1],slopeRange:[0,oT],heightBlendRange:.1,slopeBlendRange:.15,roughness:.95}),sT(n,`dirt`,{heightRange:[0,1],slopeRange:[oT,Math.PI],heightBlendRange:.5,slopeBlendRange:.3,roughness:.95})];case`volcanic`:return[sT(n,`stone`,{heightRange:[0,1],slopeRange:[0,Math.PI],heightBlendRange:.1,roughness:.95}),sT(n,`gravel`,{heightRange:[0,.28],slopeRange:[0,Math.PI/3],heightBlendRange:.14,slopeBlendRange:.2,roughness:.95})];case`custom`:return[]}}var lT={scale:100,threshold:.7,blend:.1},uT={scale:55,threshold:.58,blend:.12},dT={scale:85,threshold:.62,blend:.12},fT={scale:48,threshold:.5,blend:.14};function pT(e,t){let n=dn(e+27927);return(e,r)=>{let i=(.5+.5*n(e/t.scale,r/t.scale)-(t.threshold-t.blend))/(2*t.blend),a=Math.min(1,Math.max(0,i));return a*a*(3-2*a)}}function mT(e,t){return e===`grassland`?pT(t,lT):e===`forest`?pT(t,uT):e===`savanna`?pT(t,dT):e===`wetland`?pT(t,fT):null}function hT(e){return e===`savanna`?{from:0,to:2}:e===`grassland`||e===`forest`||e===`wetland`?{from:0,to:1}:null}var gT=256,_T=class extends Ah{orderGroup=`terrain`;static typeName=`Terrain3D`;static props={orderGroup:{default:`terrain`,options:[`background`,`terrain`,`default`,`characters`,`effects`,`overlay`]},size:{default:[200,200]},maxHeight:{default:28},seed:{default:1},resolution:{default:128},theme:{default:`island`,options:nT},roughness:{default:.5},detail:{default:4},flatThreshold:{default:.95},islandEdge:{default:null},layers:{default:[]},textureBase:{default:rT},basins:{default:[]},channels:{default:[]},wetline:{default:null}};size=[200,200];maxHeight=28;seed=1;resolution=128;theme=`island`;roughness=.5;detail=4;flatThreshold=.95;islandEdge=null;layers=[];textureBase=rT;basins=[];channels=[];externalChannels=new Map;externalRev=0;shapeStamp=null;wetline=null;splatUniforms=null;wetTime=0;update(e){this.wetTime+=e;let t=this.splatUniforms;if(!t)return;let n=this.wetline;t.uWetlineY&&(t.uWetlineY.value=typeof n?.y==`number`?n.y:-1e9),t.uWetlineBand&&(t.uWetlineBand.value=typeof n?.band==`number`?n.band:1.1),t.uWetTime&&(t.uWetTime.value=this.wetTime)}static validateJson(e){let t=e;if(!nT.includes(t.theme))throw new N(`BAD_FORMAT`,`Terrain3D '${e.name}' theme must be one of [${nT.join(`, `)}], got '${t.theme}'.`,{prop:`theme`,validOptions:nT});if(!((t.size[0]??0)>0)||!((t.size[1]??0)>0))throw new N(`BAD_FORMAT`,`Terrain3D '${e.name}' size must be positive [width, depth] meters, got ${JSON.stringify(t.size)}.`,{prop:`size`});if(!(t.maxHeight>0))throw new N(`BAD_FORMAT`,`Terrain3D '${e.name}' maxHeight must be > 0, got ${t.maxHeight}.`,{prop:`maxHeight`});if(!Number.isInteger(t.resolution)||t.resolution<2||t.resolution>gT)throw new N(`BAD_FORMAT`,`Terrain3D '${e.name}' resolution must be an integer in [2, ${gT}] (grid segments per side), got ${t.resolution}.`,{prop:`resolution`});if(!(t.roughness>0)||!Number.isFinite(t.roughness))throw new N(`BAD_FORMAT`,`Terrain3D '${e.name}' roughness must be a finite number > 0, got ${t.roughness}.`,{prop:`roughness`});if(!Number.isInteger(t.detail)||t.detail<0)throw new N(`BAD_FORMAT`,`Terrain3D '${e.name}' detail must be an integer ≥ 0 (octave count), got ${t.detail}.`,{prop:`detail`});if(!(t.flatThreshold>=0)||!Number.isFinite(t.flatThreshold))throw new N(`BAD_FORMAT`,`Terrain3D '${e.name}' flatThreshold must be a finite number ≥ 0, got ${t.flatThreshold}.`,{prop:`flatThreshold`});if(t.islandEdge!==null&&typeof t.islandEdge!=`boolean`)throw new N(`BAD_FORMAT`,`Terrain3D '${e.name}' islandEdge must be true, false or null (null = theme default), got ${JSON.stringify(t.islandEdge)}.`,{prop:`islandEdge`});let n=t.wetline;if(n!==null){if(typeof n!=`object`||Array.isArray(n)||!Number.isFinite(n.y))throw new N(`BAD_FORMAT`,`Terrain3D '${e.name}' wetline must be null or { y, band? } with a finite y, got ${JSON.stringify(t.wetline)}.`,{prop:`wetline`});if(n.band!==void 0&&!(n.band>0))throw new N(`BAD_FORMAT`,`Terrain3D '${e.name}' wetline.band must be > 0 meters, got ${JSON.stringify(n.band)}.`,{prop:`wetline`})}if(!Array.isArray(t.basins))throw new N(`BAD_FORMAT`,`Terrain3D '${e.name}' basins must be an array of { x, z, radius, depth }, got ${JSON.stringify(t.basins)}.`,{prop:`basins`});if(t.basins.forEach((t,n)=>{if(!t||typeof t!=`object`||!Number.isFinite(t.x)||!Number.isFinite(t.z)||!(t.radius>0)||!Number.isFinite(t.depth)||t.depth===0)throw new N(`BAD_FORMAT`,`Terrain3D '${e.name}' basins[${n}] needs finite x, z, positive radius and nonzero depth (negative = mound), got ${JSON.stringify(t)}.`,{prop:`basins`})}),!Array.isArray(t.channels))throw new N(`BAD_FORMAT`,`Terrain3D '${e.name}' channels must be an array of { path, width, depth, taper? }, got ${JSON.stringify(t.channels)}.`,{prop:`channels`});if(t.channels.forEach((t,n)=>{let r=t.path;if(!(t&&typeof t==`object`&&Array.isArray(r)&&r.length>=2&&r.every(e=>Array.isArray(e)&&Number.isFinite(e[0])&&Number.isFinite(e[1]))&&t.width>0&&t.depth>0&&(t.taper===void 0||t.taper>0)))throw new N(`BAD_FORMAT`,`Terrain3D '${e.name}' channels[${n}] needs a path of 2+ [x, z] points plus positive width and depth, got ${JSON.stringify(t)}.`,{prop:`channels`})}),t.theme===`custom`){if(!Array.isArray(t.layers)||t.layers.length<1||t.layers.length>4)throw new N(`BAD_FORMAT`,`Terrain3D '${e.name}' theme 'custom' needs 1–4 layers, got ${Array.isArray(t.layers)?t.layers.length:typeof t.layers}.`,{prop:`layers`});t.layers.forEach((t,n)=>{bT(e.name,t,n)})}else if(Array.isArray(t.layers)&&t.layers.length>0)throw new N(`BAD_FORMAT`,`Terrain3D '${e.name}' layers is only read with theme 'custom' — preset theme '${t.theme}' defines its own. Drop layers or switch to theme: 'custom'.`,{prop:`layers`})}heightmap=null;heightmapKey=``;builtKey=``;_createObject3D(){let e=new J;return e.setAttribute(`position`,new q(new Float32Array,3)),new Ys(e,new bl({vertexColors:!0}))}heightAt(e,t){let n=0,r=0,i=0;for(let e=this;e;e=e.parent)e instanceof Ah&&(n+=e.position[0]??0,r+=e.position[1]??0,i+=e.position[2]??0);return this._heightmap().heightAt(e-n,t-i)+r}_setExternalChannel(e,t){t===null||t.length===0?this.externalChannels.delete(e):this.externalChannels.set(e,t),this.externalRev++}allChannels(){return this.externalChannels.size===0?this.channels:[...this.channels,...[...this.externalChannels.values()].flat()]}_heightmap(){if(this.heightmap&&this.shapeUnchanged())return this.heightmap;let e=this.segments(),t=JSON.stringify([this.size,this.maxHeight,this.seed,e,this.roughness,this.detail,this.flatThreshold,this.effectiveIslandEdge(),this.basins,this.allChannels()]);return(!this.heightmap||t!==this.heightmapKey)&&(this.heightmap=Uw({width:this.size[0]??1,depth:this.size[1]??1,segsX:e,segsZ:e,maxHeight:this.maxHeight,seed:this.seed,roughness:this.roughness,detail:this.detail,flatThreshold:this.flatThreshold,islandEdge:this.effectiveIslandEdge(),basins:this.basins,channels:this.allChannels()}),this.heightmapKey=t),this.rememberShape(),this.heightmap}shapeUnchanged(){let e=this.shapeStamp;return e!==null&&e.sizeX===(this.size[0]??0)&&e.sizeZ===(this.size[1]??0)&&e.maxHeight===this.maxHeight&&e.seed===this.seed&&e.segments===this.segments()&&e.roughness===this.roughness&&e.detail===this.detail&&e.flatThreshold===this.flatThreshold&&e.islandEdge===this.effectiveIslandEdge()&&e.basins===this.basins&&e.channels===this.channels&&e.externalRev===this.externalRev}rememberShape(){this.shapeStamp={sizeX:this.size[0]??0,sizeZ:this.size[1]??0,maxHeight:this.maxHeight,seed:this.seed,segments:this.segments(),roughness:this.roughness,detail:this.detail,flatThreshold:this.flatThreshold,islandEdge:this.effectiveIslandEdge(),basins:this.basins,channels:this.channels,externalRev:this.externalRev}}resolvedLayers(){return this.theme===`custom`?this.layers:cT(this.theme,this.textureBase)}_syncObject3D(e=1,t=null){super._syncObject3D(e,t),this.rebuildIfNeeded(t)}effectiveIslandEdge(){return this.islandEdge??this.theme===`island`}segments(){return Math.max(2,Math.min(Math.floor(this.resolution),gT))}rebuildIfNeeded(e){let t=JSON.stringify([this.size,this.maxHeight,this.seed,this.segments(),this.theme,this.roughness,this.detail,this.flatThreshold,this.islandEdge,this.layers,this.textureBase,this.basins,this.allChannels()]);if(t===this.builtKey)return;this.builtKey=t;let n=this._ensureObject3D();n.geometry.dispose(),n.geometry=this.buildGeometry(),n.material.dispose(),n.material=this.buildMaterial(e),n.receiveShadow=!0,n.castShadow=!0}buildGeometry(){let e=this._heightmap(),t=new cl(e.width,e.depth,e.segsX,e.segsZ);t.rotateX(-Math.PI/2);let n=t.getAttribute(`position`);for(let t=0;t<n.count;t++)n.setY(t,e.heights[t]);n.needsUpdate=!0,t.computeVertexNormals();let r=this.resolvedLayers(),i=e.maxHeight-e.minHeight||1,a=new Float32Array(n.count*3),o=this.theme===`custom`?null:hT(this.theme),s=o?mT(this.theme,this.seed):null;for(let t=0;t<n.count;t++){let c=n.getX(t),l=n.getZ(t),u=Gw(Math.min(1,Math.max(0,(n.getY(t)-e.minHeight)/i)),e.slopeAt(c,l),r);if(s&&o){let e=(u[o.from]??0)*s(c,l);u[o.from]=(u[o.from]??0)-e,u[o.to]=(u[o.to]??0)+e}a[t*3]=u[0],a[t*3+1]=u[1],a[t*3+2]=u[2]}return t.setAttribute(`color`,new q(a,3)),t}buildMaterial(e){let t=this.resolvedLayers(),n=new bl({vertexColors:!0}),r=(t,n)=>t?gw(e,t,{wrap:`repeat`,anisotropy:8,colorSpace:n?`srgb`:`linear`}):null,i=t.map(e=>r(e.texture,!0)),a=t.map(e=>r(e.normalMap,!1)),o=a.some(e=>e!==null);if(o)for(let e=0;e<a.length;e++)a[e]||(a[e]=yT());let s={textures:i,normalMaps:a,repeats:t.map(e=>e.repeat??2),roughness:t.map(e=>e.roughness??1),metalness:t.map(e=>e.metalness??0),uvNoiseIntensity:t.map(e=>e.uvNoiseIntensity??.15),envCut:.45,layerCount:Math.min(4,t.length),hasNormalMaps:o};return n.onBeforeCompile=e=>{tT(e,s),this.splatUniforms=e.uniforms},n.customProgramCacheKey=()=>`incanto-terrain-splat:${+!!o}`,n}free(){let e=this._ensureObject3D();e.geometry.dispose(),e.material.dispose(),this.heightmap=null,super.free()}},vT=null;function yT(){return vT||(vT=new lc(new Uint8Array([128,128,255,255]),1,1),vT.needsUpdate=!0),vT}function bT(e,t,n){let r=`layers[${n}]`;if(typeof t!=`object`||!t||Array.isArray(t))throw new N(`BAD_FORMAT`,`Terrain3D '${e}' ${r} must be an object ({texture, heightRange?, slopeRange?, …}).`,{prop:`layers`});let i=t;if(typeof i.texture!=`string`||i.texture.length===0)throw new N(`BAD_FORMAT`,`Terrain3D '${e}' ${r} needs "texture": a texture URL string.`,{prop:`layers`});for(let t of[`heightRange`,`slopeRange`]){let n=i[t];if(n!==void 0&&(!Array.isArray(n)||n.length!==2||n.some(e=>typeof e!=`number`||!Number.isFinite(e))))throw new N(`BAD_FORMAT`,`Terrain3D '${e}' ${r}.${t} must be [min, max] numbers, got ${JSON.stringify(n)}.`,{prop:`layers`})}}var xT=16,ST=new U,CT=new H;function wT(e,t){let n=e.translation(),r=e.rotation();CT.set(r.x,r.y,r.z,r.w);let i=(e,r,i)=>{ST.set(e,r,i).applyQuaternion(CT),t.push(ST.x+n.x,ST.y+n.y,ST.z+n.z)};return(e,t,n,r,a,o)=>{i(e,t,n),i(r,a,o)}}function TT(e,t,n,r,i=Math.PI*2,a=0){let o=e=>{let i=Math.cos(e)*t,a=Math.sin(e)*t;return n===`xy`?[i,a,r]:n===`xz`?[i,r,a]:[r,i,a]},s=Math.max(3,Math.round(xT*i/(Math.PI*2)));for(let t=0;t<s;t++){let[n,r,c]=o(a+i*t/s),[l,u,d]=o(a+i*(t+1)/s);e(n,r,c,l,u,d)}}function ET(e,t,n){let r=e=>[t[e*3],t[e*3+1],t[e*3+2]];if(n){for(let t=0;t<n.length;t+=3){let i=r(n[t]),a=r(n[t+1]),o=r(n[t+2]);e(...i,...a),e(...a,...o),e(...o,...i)}return}for(let n=0;n+5<t.length;n+=9){let t=r(n/3),i=r(n/3+1),a=r(n/3+2);e(...t,...i),e(...i,...a),e(...a,...t)}}function DT(e,t){let{nrows:n,ncols:r,heights:i,scale:a}=t,o=n+1,s=r+1,c=(e,t)=>[(e/n-.5)*a.x,i[t*o+e]*a.y,(t/r-.5)*a.z];for(let t=0;t<s;t++)for(let n=0;n<o;n++)n+1<o&&e(...c(n,t),...c(n+1,t)),t+1<s&&e(...c(n,t),...c(n,t+1))}function OT(e,t){let n=wT(e,t),r=e.shape;switch(e.shape.type){case 0:{let e=r.radius;TT(n,e,`xy`,0),TT(n,e,`xz`,0),TT(n,e,`yz`,0);return}case 1:{let e=r.halfExtents;for(let[t,r]of[[-1,-1],[-1,1],[1,-1],[1,1]])n(-e.x,t*e.y,r*e.z,e.x,t*e.y,r*e.z);for(let[t,r]of[[-1,-1],[-1,1],[1,-1],[1,1]])n(t*e.x,-e.y,r*e.z,t*e.x,e.y,r*e.z);for(let[t,r]of[[-1,-1],[-1,1],[1,-1],[1,1]])n(t*e.x,r*e.y,-e.z,t*e.x,r*e.y,e.z);return}case 2:{let{radius:e,halfHeight:t}=r;for(let r of[-1,1]){TT(n,e,`xz`,r*t);for(let i of[`xy`,`yz`])TT((e,i,a,o,s,c)=>n(e,i+r*t,a,o,s+r*t,c),e,i,0,Math.PI,r>0?0:Math.PI)}for(let[r,i]of[[1,0],[-1,0],[0,1],[0,-1]])n(r*e,-t,i*e,r*e,t,i*e);return}case 3:{let e=r;n(e.a.x,e.a.y,e.a.z,e.b.x,e.b.y,e.b.z);return}case 6:case 9:case 16:{let e=r;ET(n,e.vertices,e.indices);return}case 7:DT(n,r);return;case 10:case 14:{let{radius:e,halfHeight:t}=r;TT(n,e,`xz`,-t),TT(n,e,`xz`,t);for(let[r,i]of[[1,0],[-1,0],[0,1],[0,-1]])n(r*e,-t,i*e,r*e,t,i*e);return}case 11:case 15:{let{radius:e,halfHeight:t}=r;TT(n,e,`xz`,-t);for(let r=0;r<4;r++){let i=r/4*Math.PI*2;n(Math.cos(i)*e,-t,Math.sin(i)*e,0,t,0)}return}default:if(e.shape.type===12||e.shape.type===13){let e=r.halfExtents;e&&n(-e.x,-e.y,-e.z,e.x,e.y,e.z)}return}}var kT=Math.PI/180;async function AT(e,t){let n=await bm(()=>import(`./rapier-DE6a0vmv.js`),[],import.meta.url);return await n.init({}),new jT(n,e,t)}var jT=class{R;engine;debugDraw=!1;debugScope=null;dimension=`3d`;unregisterDebug;warnedNoCollider=new WeakSet;entries=new Map;byColliderHandle=new Map;world;events;kcc;disconnect;lastDt=1/60;optsGravity;lastScene=null;constructor(e,t,n){this.R=e,this.engine=t,this.optsGravity=n?.gravity,this.simulate=n?.simulate??!0,this.lastScene=t.scene;let r=t.scene?.physics?.gravity,i=n?.gravity??r??[0,-9.81,0];this.world=new e.World({x:i[0]??0,y:i[1]??0,z:i[2]??0}),this.kcc=this.world.createCharacterController(.01),this.events=new e.EventQueue(!0),this.unregisterDebug=ev(this),this.disconnect=t.fixedUpdated.connect(e=>this.step(e)),this.syncBodies()}simulate;step(e){if(this.lastDt=e,!this.simulate){this.syncBodies(),this.poseFromTree();return}if(this.engine.scene!==this.lastScene&&(this.lastScene=this.engine.scene,!this.optsGravity)){let e=this.engine.scene?.physics?.gravity??[0,-9.81,0];this.world.gravity={x:e[0]??0,y:e[1]??0,z:e[2]??0}}this.syncBodies(),this.world.timestep=e,this.world.step(this.events);for(let[e,t]of this.entries){let n=t.body.translation();if(!t.body.isFixed()){let[t,r,i]=ZT(e),a=[n.x-t,n.y-r,n.z-i];e._interpPrev=e._interpCurr??a,e._interpCurr=a;let o=e.position;o[0]=a[0],o[1]=a[1],o[2]=a[2]}if(e instanceof Ph){if(!e.fixedRotation){let n=t.body.rotation();NT.setFromQuaternion(MT.set(n.x,n.y,n.z,n.w),`XYZ`);let r=e.rotation;r[0]=NT.x/kT,r[1]=NT.y/kT,r[2]=NT.z/kT}let n=t.body.linvel(),r=e.linearVelocity;r[0]=n.x,r[1]=n.y,r[2]=n.z,t.lastV[0]=n.x,t.lastV[1]=n.y,t.lastV[2]=n.z}let r=YT(e);t.last[0]=r[0],t.last[1]=r[1],t.last[2]=r[2]}this.events.drainCollisionEvents((e,t,n)=>{let r=this.byColliderHandle.get(e),i=this.byColliderHandle.get(t);if(!r||!i)return;let a=n?`triggerEnter`:`triggerExit`;try{r.emit(a,i),i.emit(a,r)}catch(e){lt(this.engine,`error`,`incanto: error in a '${a}' handler (${r.name} ↔ ${i.name}):`,e)}})}poseFromTree(){for(let[e,t]of this.entries){let[n,r,i]=YT(e);t.body.setTranslation({x:n,y:r,z:i},!1),MT.setFromEuler(NT.set((e.rotation[0]??0)*kT,(e.rotation[1]??0)*kT,(e.rotation[2]??0)*kT,`XYZ`)),t.body.setRotation({x:MT.x,y:MT.y,z:MT.z,w:MT.w},!1)}this.world.propagateModifiedBodyPositionsToColliders()}moveAndSlide(e){let t=this.ensureEntry(e);if(!t)return;let n=e.velocity[1]??0;e.snapToGround&&n<=0?this.kcc.enableSnapToGround(.1):this.kcc.disableSnapToGround(),this.kcc.setMaxSlopeClimbAngle(e.slopeLimitDeg*kT);let r=0,i=0,a=0;if(t.ground&&t.ground._physics===this&&t.groundAt){let[e,n,o]=YT(t.ground);r=e-t.groundAt[0],i=n-t.groundAt[1],a=o-t.groundAt[2]}else t.ground=null;let o={x:(e.velocity[0]??0)*this.lastDt+r,y:n*this.lastDt+i,z:(e.velocity[2]??0)*this.lastDt+a};this.kcc.computeColliderMovement(t.collider,o,this.R.QueryFilterFlags.EXCLUDE_SENSORS);let s=this.kcc.computedMovement(),c=t.body.translation(),l=c.x+s.x,u=c.y+s.y,d=c.z+s.z;if(t.body.setNextKinematicTranslation({x:l,y:u,z:d}),e._grounded=this.kcc.computedGrounded(),e._grounded){let n=JT(e),r=this.castRay([l,u-n+.05,d],[0,-1,0],.4,e);if(r?.node&&!(r.node instanceof Fh)){t.ground=r.node;let e=YT(r.node);t.groundAt=[e[0],e[1],e[2]]}else t.ground=null}else t.ground=null}debugLines(){if(!this.debugDraw)return null;let e=this.debugScope;if(!e)return this.world.debugRender().vertices;let t=this.scopedBodies(e),n=[];for(let e of t)for(let t=0;t<e.numColliders();t++){let r=e.collider(t);r&&OT(r,n)}return new Float32Array(n)}scopedBodies(e){let t=[],n=e=>{let r=this.entries.get(e);r&&t.push(r.body);let i=this.scatterBodies.get(e);i&&t.push(i);for(let t of e.children)n(t)};n(e);for(let n=e.parent;n&&t.length===0;n=n.parent){let e=this.entries.get(n);e&&t.push(e.body)}return t}dispose(){this.disconnect(),this.unregisterDebug(),this.world.free()}lastStructure=-1;lastRoot=null;jointSet=new Set;joints=new Map;scatterBodies=new Map;bodySet=new Set;syncScatters(e){for(let[,e]of this.scatterBodies)this.world.removeRigidBody(e);this.scatterBodies.clear();let t=new Set;KT(e,t);for(let e of t){let t=e.collider;if(!t)continue;let[n,r,i]=YT(e),a=this.world.createRigidBody(this.R.RigidBodyDesc.fixed().setTranslation(0,0,0)),[o,s,c]=e.size,l=null;for(let u of e.transforms){let d=u[4]??1,f=n+(u[0]??0),p=r+(u[1]??0),m=i+(u[2]??0),h=null;if(t.shape===`sphere`)h=this.R.ColliderDesc.ball(Math.max((t.radius??Math.max(o,c)/2)*d,.01));else if(t.shape===`box`){let e=t.size??[o,s,c];h=this.R.ColliderDesc.cuboid(Math.max((e[0]??1)*d/2,.01),Math.max((e[1]??1)*d/2,.01),Math.max((e[2]??1)*d/2,.01))}else{l??=LT(e.mesh,e.size);let t=new Float32Array(l.length);for(let e=0;e<t.length;e++)t[e]=l[e]*d;h=this.R.ColliderDesc.convexHull(t)}if(!h)continue;h.setTranslation(f,p,m);let g=(u[3]??0)*Math.PI/180;g!==0&&h.setRotation({x:0,y:Math.sin(g/2),z:0,w:Math.cos(g/2)}),this.world.createCollider(h,a)}this.scatterBodies.set(e,a)}}syncBodies(){let e=this.engine.scene;if(!e)return;let t=e.tree._structureVersion,n=e.root===this.lastRoot,r=t!==this.lastStructure||!n;if(r){let r=n?e.tree._structureSince(this.lastStructure):null;if(this.lastStructure=t,this.lastRoot=e.root,r){let t=!1,n=!1;for(let{node:e,added:i}of r)e instanceof jh&&(i?this.bodySet.add(e):this.bodySet.delete(e)),e instanceof Rw&&(t=!0),e instanceof Mw&&(n=!0);t&&(this.jointSet.clear(),PT(e.root,this.jointSet)),n&&this.syncScatters(e.root)}else this.bodySet.clear(),FT(e.root,this.bodySet),this.jointSet.clear(),PT(e.root,this.jointSet),this.syncScatters(e.root)}let i=this.bodySet;for(let e of i){if(e.collider.shape===void 0){let t=this.entries.get(e);t&&(this.byColliderHandle.delete(t.collider.handle),this.world.removeRigidBody(t.body),this.entries.delete(e),e._physics=null,e._interpPrev=e._interpCurr=null),this.warnedNoCollider.has(e)||(this.warnedNoCollider.add(e),lt(this.engine,`warn`,`[incanto] '${e.name}' has no collider — physics skips it.`));continue}let t=this.entries.get(e);t&&e._colliderChanged&&(this.byColliderHandle.delete(t.collider.handle),this.world.removeRigidBody(t.body),this.entries.delete(e),e._physics=null,e._interpPrev=e._interpCurr=null),this.ensureEntry(e)}if(this.syncJoints(r),r)for(let[e,t]of this.entries)i.has(e)||(this.byColliderHandle.delete(t.collider.handle),this.world.removeRigidBody(t.body),this.entries.delete(e),e._physics=null,e._interpPrev=e._interpCurr=null)}ensureEntry(e){let t=this.entries.get(e),n=this.R;if(!t){let r=QT(n,e);if(!r)return null;let i;i=e instanceof Ph?n.RigidBodyDesc.dynamic():e instanceof Fh||e instanceof Nh?n.RigidBodyDesc.kinematicPositionBased():n.RigidBodyDesc.fixed();let[a,o,s]=YT(e);i.setTranslation(a,o,s),MT.setFromEuler(NT.set((e.rotation[0]??0)*kT,(e.rotation[1]??0)*kT,(e.rotation[2]??0)*kT,`XYZ`)),i.setRotation({x:MT.x,y:MT.y,z:MT.z,w:MT.w}),e instanceof Ph&&(i.setGravityScale(e.gravityScale),i.setLinvel(e.linearVelocity[0]??0,e.linearVelocity[1]??0,e.linearVelocity[2]??0),e.fixedRotation&&i.lockRotations());let c=this.world.createRigidBody(i);r.setActiveEvents(n.ActiveEvents.COLLISION_EVENTS),r.setActiveCollisionTypes(n.ActiveCollisionTypes.ALL),e instanceof Nh&&r.setSensor(!0),e instanceof Ph&&r.setMass(e.mass).setFriction(e.friction).setRestitution(e.restitution);let l=this.world.createCollider(r,c);return t={body:c,collider:l,last:[a,o,s],lastV:[0,0,0]},this.entries.set(e,t),this.byColliderHandle.set(l.handle,e),e._colliderChanged=!1,e._physics=this,e instanceof Ph&&(e._physics3d=this),t}let r=YT(e);if((r[0]!==t.last[0]||r[1]!==t.last[1]||r[2]!==t.last[2])&&(t.body.setTranslation({x:r[0],y:r[1],z:r[2]},!0),t.last[0]=r[0],t.last[1]=r[1],t.last[2]=r[2],e._interpPrev=e._interpCurr=null),e instanceof Ph){let n=[e.linearVelocity[0]??0,e.linearVelocity[1]??0,e.linearVelocity[2]??0];(n[0]!==t.lastV[0]||n[1]!==t.lastV[1]||n[2]!==t.lastV[2])&&(t.body.setLinvel({x:n[0],y:n[1],z:n[2]},!0),t.lastV=n),e.gravityScale!==t.body.gravityScale()&&t.body.setGravityScale(e.gravityScale,!0)}return t}applyImpulse(e,t){this.entries.get(e)?.body.applyImpulse({x:t[0],y:t[1],z:t[2]},!0)}massOf(e){return this.entries.get(e)?.body.mass()??1}velocityOf(e){let t=this.entries.get(e)?.body.linvel();return t?[t.x,t.y,t.z]:[0,0,0]}syncJoints(e){let t=this.R;if(e)for(let[e,t]of this.joints)this.jointSet.has(e)||(this.world.removeImpulseJoint(t,!0),this.joints.delete(e));for(let e of this.jointSet){if(this.joints.has(e))continue;let{a:n,b:r}=e._resolveBodies(),i=this.entries.get(n),a=this.entries.get(r);if(!i||!a)continue;let o={x:e.anchor[0]??0,y:e.anchor[1]??0,z:e.anchor[2]??0},s={x:e.targetAnchor[0]??0,y:e.targetAnchor[1]??0,z:e.targetAnchor[2]??0},c=e.length;if(e.length===0&&(e.type===`rope`||e.type===`spring`)){let e=i.body.translation(),t=a.body.translation();c=Math.hypot(t.x-e.x,t.y-e.y,t.z-e.z)}let l={x:0,y:0,z:0,w:1},u;u=e.type===`fixed`?t.JointData.fixed(o,l,s,l):e.type===`rope`?t.JointData.rope(c,o,s):e.type===`spring`?t.JointData.spring(c,e.stiffness,e.damping,o,s):t.JointData.spherical(o,s),this.joints.set(e,this.world.createImpulseJoint(u,i.body,a.body,!0))}}castRay(e,t,n,r,i){let a=new this.R.Ray({x:e[0],y:e[1],z:e[2]},{x:t[0],y:t[1],z:t[2]}),o=r?this.entries.get(r)?.collider:void 0,s=i?.staticOnly?this.R.QueryFilterFlags.EXCLUDE_DYNAMIC|this.R.QueryFilterFlags.EXCLUDE_KINEMATIC:void 0,c=this.world.castRayAndGetNormal(a,n,!0,s,void 0,o,void 0,e=>!e.isSensor());return c?{distance:c.timeOfImpact,normal:[c.normal.x,c.normal.y,c.normal.z],node:this.byColliderHandle.get(c.collider.handle)??null}:null}castSphere(e,t,n,r,i,a){let o=this.R,s=i?this.entries.get(i):void 0,c=a?.staticOnly?o.QueryFilterFlags.EXCLUDE_DYNAMIC|o.QueryFilterFlags.EXCLUDE_KINEMATIC:void 0,l=this.world.castShape({x:e[0],y:e[1],z:e[2]},{x:0,y:0,z:0,w:1},{x:t[0],y:t[1],z:t[2]},new o.Ball(n),0,r,!0,c,void 0,s?.collider,s?.body,e=>!e.isSensor());return l?{distance:l.time_of_impact,node:this.byColliderHandle.get(l.collider.handle)??null}:null}},MT=new H,NT=new Qa;function PT(e,t){e instanceof Rw&&t.add(e);for(let n of e.children)PT(n,t)}function FT(e,t){e instanceof jh&&t.add(e);for(let n of e.children)FT(n,t)}function IT(e,t,n,r){let i=(n[0]??1)*r,a=(n[1]??1)*r,o=(n[2]??1)*r;switch(t){case`box`:return e.ColliderDesc.cuboid(i/2,a/2,o/2);case`sphere`:return e.ColliderDesc.ball(i);case`capsule`:return e.ColliderDesc.capsule(a/2,i);case`cylinder`:return e.ColliderDesc.cylinder(a/2,i);case`plane`:return e.ColliderDesc.cuboid(i/2,.01,o/2);default:return e.ColliderDesc.convexHull(LT(t,[i,a,o]))}}function LT(e,t){let n=jw(e,t),r=n.getAttribute(`position`),i=new Float32Array(r.count*3);for(let e=0;e<r.count;e++)i[e*3]=r.getX(e),i[e*3+1]=r.getY(e),i[e*3+2]=r.getZ(e);return n.dispose(),i}function RT(e){return typeof e._mountedObject3D==`function`}var zT=new G,BT=new G,VT=new U;function HT(e,t){let n=t._mountedObject3D();if(!n)return null;let r=e._ensureObject3D();r.updateWorldMatrix(!0,!0),zT.copy(r.matrixWorld).invert();let i=[],a=[];return n.traverse(e=>{let t=e;if(!t.isMesh)return;let n=t.geometry?.getAttribute(`position`);if(!n)return;BT.multiplyMatrices(zT,t.matrixWorld);let r=i.length/3;for(let e=0;e<n.count;e++)VT.set(n.getX(e),n.getY(e),n.getZ(e)).applyMatrix4(BT),i.push(VT.x,VT.y,VT.z);let o=t.geometry.getIndex();if(o)for(let e=0;e<o.count;e++)a.push(r+o.getX(e));else for(let e=0;e<n.count;e++)a.push(r+e)}),a.length<3?null:{vertices:new Float32Array(i),indices:new Uint32Array(a),triangles:a.length/3}}var UT=2e4;function WT(e){return!(e instanceof Ph||e instanceof Fh)}function GT(e,t,n){if(RT(e))n.push(e);else{let n=e;typeof n.mesh==`string`&&Array.isArray(n.size)&&t.push({name:e.name,mesh:n.mesh,size:n.size})}for(let r of e.children)GT(r,t,n)}function KT(e,t){e instanceof Mw&&e.collider&&t.add(e);for(let n of e.children)KT(n,t)}var qT=[0,0,0];function JT(e){let t=e.collider;return t?t.shape===`capsule`&&typeof t.height==`number`?t.height/2+(t.radius??0):t.shape===`box`&&Array.isArray(t.size)?(t.size[1]??2)/2:t.shape===`sphere`&&typeof t.radius==`number`?t.radius:1:1}function YT(e){let t=0,n=0,r=0;for(let i=e;i;i=i.parent)i instanceof Ah&&(t+=i.position[0]??0,n+=i.position[1]??0,r+=i.position[2]??0);return qT[0]=t,qT[1]=n,qT[2]=r,qT}var XT=[0,0,0];function ZT(e){let t=0,n=0,r=0;for(let i=e.parent;i;i=i.parent)i instanceof Ah&&(t+=i.position[0]??0,n+=i.position[1]??0,r+=i.position[2]??0);return XT[0]=t,XT[1]=n,XT[2]=r,XT}function QT(e,t){let n=t.collider;if(Oh(n,t.name),n.shape===`heightfield`)return $T(e,t);let r=eE(e,n,t.name,t);if(!r)return null;let i=n.offset;return Array.isArray(i)&&r.setTranslation(i[0]??0,i[1]??0,i[2]??0),r}function $T(e,t){let n=t.children.find(e=>e instanceof _T);if(!n)throw new N(`BAD_FORMAT`,`Collider on '${t.name}': heightfield needs a Terrain3D CHILD of this body — add { "type": "Terrain3D" } under the StaticBody3D; the collider reads its height grid.`,{prop:`collider`});let r=n._heightmap(),i=r.segsZ,a=r.segsX,o=new Float32Array((i+1)*(a+1));for(let e=0;e<=a;e++)for(let t=0;t<=i;t++)o[e*(i+1)+t]=r.heights[t*(a+1)+e];let s=e.ColliderDesc.heightfield(i,a,o,{x:r.width,y:1,z:r.depth}),c=Array.isArray(t.collider.offset)?t.collider.offset:[];return s.setTranslation((n.position[0]??0)+(c[0]??0),(n.position[1]??0)+(c[1]??0),(n.position[2]??0)+(c[2]??0)),s}function eE(e,t,n,r){let i=t.shape;if(i===`box`){let r=t.size;if(!Array.isArray(r)||r.length!==3||r.some(e=>typeof e!=`number`))throw new N(`BAD_FORMAT`,`Collider on '${n}': box needs "size": [x, y, z].`);return e.ColliderDesc.cuboid(r[0]/2,r[1]/2,r[2]/2)}if(i===`sphere`){if(typeof t.radius!=`number`)throw new N(`BAD_FORMAT`,`Collider on '${n}': sphere needs "radius".`);return e.ColliderDesc.ball(t.radius)}if(i===`capsule`){if(typeof t.radius!=`number`||typeof t.height!=`number`)throw new N(`BAD_FORMAT`,`Collider on '${n}': capsule needs "radius" and "height".`);return e.ColliderDesc.capsule(t.height/2,t.radius)}if(i===`auto`){let t=[],i=[];r&>(r,t,i);let a=t[0],o=i[0];if(!a&&!o)throw new N(`BAD_FORMAT`,`Collider on '${n}': shape 'auto' needs a MeshInstance3D or ModelInstance3D on the body (or as a child) to take its shape from.`);let s=t.length+i.length;if(s>1&&console.warn(`[incanto] Collider on '${n}': shape 'auto' fits ONE mesh and took '${(a??o)?.name}'; ${s-1} other mesh(es) here are not solid. Give each part its own body.`),a){let t=IT(e,a.mesh,a.size,1);if(t)return t}else if(o&&r){let t=HT(r,o);return t?WT(r)?(t.triangles>UT&&console.warn(`[incanto] Collider on '${n}': shape 'auto' built a ${t.triangles}-triangle mesh from '${o.name}'. Consider a low-poly collision model or an explicit box.`),e.ColliderDesc.trimesh(t.vertices,t.indices)):e.ColliderDesc.convexHull(t.vertices):null}}if(i===`trimesh`){let r=t.vertices,i=t.indices;if(!Array.isArray(r)||!Array.isArray(i))throw new N(`BAD_FORMAT`,`Collider on '${n}': trimesh needs "vertices" (flat xyz) and "indices" (triangles).`);return e.ColliderDesc.trimesh(new Float32Array(r),new Uint32Array(i))}throw new N(`BAD_FORMAT`,`Collider on '${n}': "shape" must be 'auto', 'box', 'sphere', 'capsule', 'trimesh', or 'heightfield', got ${JSON.stringify(i)}.`)}var tE=new cl(1,1),nE=null;function rE(){if(nE)return nE;if(typeof document>`u`)return null;let e=document.createElement(`canvas`);e.width=64,e.height=64;let t=e.getContext(`2d`);if(!t)return null;let n=t.createRadialGradient(32,32,0,32,32,31);return n.addColorStop(0,`rgba(0,0,0,0.55)`),n.addColorStop(.55,`rgba(0,0,0,0.34)`),n.addColorStop(1,`rgba(0,0,0,0)`),t.fillStyle=n,t.fillRect(0,0,64,64),nE=new Qc(e),nE}var iE=new U(0,0,1),aE=new U,oE=new U,sE=new H,cE=new H,lE=new U,uE=.5,dE=class extends Ah{static typeName=`Sprite3D`;static props={texture:{default:``},size:{default:[1,1]},billboard:{default:`y`,options:[`y`,`full`,`none`]},anchor:{default:[.5,0]},tint:{default:`#ffffff`},opacity:{default:1},flipX:{default:!1},pixelArt:{default:!0},alphaTest:{default:.5},castShadow:{default:!1},shadowMode:{default:`silhouette`,options:[`silhouette`,`blob`]}};texture=``;size=[1,1];billboard=`y`;anchor=[.5,0];tint=`#ffffff`;opacity=1;flipX=!1;pixelArt=!0;alphaTest=.5;castShadow=!1;shadowMode=`silhouette`;quadMesh=null;textureRef=``;loadedTexture=null;shadowMesh=null;blobMesh=null;_quad(){return this.quadMesh||(this.quadMesh=new Ys(tE,new Ls({transparent:!1,depthWrite:!0,side:2})),this._ensureObject3D().add(this.quadMesh)),this.quadMesh}resolveTexture(e){return this.texture?(this.textureRef!==this.texture&&(this.textureRef=this.texture,this.loadedTexture=gw(e,this.texture,{filter:this.pixelArt?`nearest`:`linear`})),this.loadedTexture):null}_syncObject3D(e=1,t=null){super._syncObject3D(e,t);let n=this._quad(),r=n.material,i=this.size[0]??1,a=this.size[1]??1;n.scale.set(this.flipX?-i:i,a,1);let o=this.anchor[0]??.5,s=this.anchor[1]??0;n.position.set((.5-o)*i,(.5-s)*a,0);let c=this.resolveTexture(t);r.map!==c&&(r.map=c,r.needsUpdate=!0),n.visible=c!==null,r.color.set(this.tint),r.opacity=this.opacity,r.transparent=this.opacity<1,r.alphaTest=this.alphaTest,n.renderOrder=this.renderOrder;let l=this.castShadow&&c!==null;if(n.castShadow=!1,l&&this.shadowMode===`silhouette`){let e=this._shadowCaster();e.visible=!0,e.castShadow=!0,e.scale.set(this.flipX?-i:i,a,1),e.position.set((.5-o)*i,(.5-s)*a,0);let t=e.material;t.map!==c&&(t.map=c,t.needsUpdate=!0);let n=e.customDepthMaterial;n.map!==c&&(n.map=c,n.needsUpdate=!0),t.alphaTest=this.alphaTest,n.alphaTest=this.alphaTest}else this.shadowMesh&&(this.shadowMesh.visible=!1,this.shadowMesh.castShadow=!1);if(l&&this.shadowMode===`blob`){let e=this._blob();e.visible=!0,e.scale.set(i*.52,i*.52,1)}else this.blobMesh&&(this.blobMesh.visible=!1)}_shadowCaster(){return this.shadowMesh||(this.shadowMesh=new Ys(tE,new Ls({colorWrite:!1,depthWrite:!1,side:2})),this.shadowMesh.customDepthMaterial=new Sl({depthPacking:Di,side:2}),this._ensureObject3D().add(this.shadowMesh)),this.shadowMesh}_blob(){return this.blobMesh||(this.blobMesh=new Ys(tE,new Ls({map:rE(),color:0,transparent:!0,depthWrite:!1})),this.blobMesh.rotation.x=-Math.PI/2,this.blobMesh.position.y=.02,this.blobMesh.renderOrder=-1,this._ensureObject3D().add(this.blobMesh)),this.blobMesh}_onRender3D(e){this.billboard===`y`?(e.camera.getWorldDirection(oE),oE.y=0,oE.lengthSq()>=1e-6&&this._faceDir(this._quad(),oE.negate())):this.billboard===`full`&&this._faceToward(this._quad(),e.camera.position);let t=this.shadowMesh;t?.castShadow&&e.sunDir&&(this._faceDir(t,e.sunDir),t.parent?.getWorldQuaternion(cE),lE.copy(e.sunDir).applyQuaternion(cE.invert()),t.position.addScaledVector(lE,uE))}_faceToward(e,t){e.getWorldPosition(aE),oE.copy(t).sub(aE),this.billboard===`y`&&(oE.y=0),!(oE.lengthSq()<1e-12)&&(oE.normalize(),sE.setFromUnitVectors(iE,oE),e.parent?.getWorldQuaternion(cE),e.quaternion.copy(cE.invert()).multiply(sE))}_faceDir(e,t){oE.copy(t),this.billboard===`y`&&(oE.y=0),!(oE.lengthSq()<1e-12)&&(oE.normalize(),sE.setFromUnitVectors(iE,oE),e.parent?.getWorldQuaternion(cE),e.quaternion.copy(cE.invert()).multiply(sE))}free(){this.loadedTexture?.dispose(),this.loadedTexture=null,this.shadowMesh&&(this.shadowMesh.material.dispose(),this.shadowMesh.customDepthMaterial?.dispose()),this.blobMesh&&this.blobMesh.material.dispose(),super.free()}},fE=class extends dE{static typeName=`AnimatedSprite3D`;static signals=[`animationFinished`];static props={sheet:{default:``},frameWidth:{default:0},frameHeight:{default:0},animations:{default:{}},autoplay:{default:``}};sheet=``;frameWidth=0;frameHeight=0;animations={};autoplay=``;playing=!1;currentFrame=0;currentAnimation=``;frameList=[];frameIndex=0;frameTime=0;sheetTexture=null;loadedSheetRef=``;play(e){let t=this.animations[e];if(!t)throw new N(`UNKNOWN_ANIMATION`,`No animation '${e}' on '${this.name}'. Available: [${Object.keys(this.animations).join(`, `)}].`);this.currentAnimation=e,this.frameList=pE(t.frames,e),this.frameIndex=0,this.currentFrame=this.frameList[0]??0,this.frameTime=0,this.playing=!0}stop(){this.playing=!1}onReady(){this.autoplay&&this.play(this.autoplay)}update(e){if(!this.playing||this.currentAnimation===``)return;let t=this.animations[this.currentAnimation];if(!t||!Number.isFinite(t.fps)||t.fps<=0)return;let n=1/t.fps;for(this.frameTime+=e;this.frameTime>=n;)if(this.frameTime-=n,this.frameIndex+=1,this.frameIndex>=this.frameList.length)if(t.loop)this.frameIndex=0;else{this.frameIndex=this.frameList.length-1,this.playing=!1,this.emit(`animationFinished`,this.currentAnimation);break}this.currentFrame=this.frameList[this.frameIndex]??0}resolveTexture(e){if(!this.sheet||this.frameWidth<=0||this.frameHeight<=0)return null;this.loadedSheetRef!==this.sheet&&(this.sheetTexture?.dispose(),this.loadedSheetRef=this.sheet,this.sheetTexture=_w(e,this.sheet,{filter:this.pixelArt?`nearest`:`linear`}));let t=this.sheetTexture;if(!t)return null;let n=t.image;if(!n?.width||!n.height)return t;let r=Math.max(1,Math.floor(n.width/this.frameWidth)),i=this.currentFrame%r,a=Math.floor(this.currentFrame/r);return t.repeat.set(this.frameWidth/n.width,this.frameHeight/n.height),t.offset.set(i*this.frameWidth/n.width,1-(a+1)*this.frameHeight/n.height),t}free(){this.sheetTexture?.dispose(),this.sheetTexture=null,super.free()}};function pE(e,t){if(!Array.isArray(e)||e.length===0)throw new N(`BAD_FORMAT`,`Animation '${t}': "frames" must be a non-empty array.`);if(e.length===2){let[t,n]=e;if(n>=t){let e=[];for(let r=t;r<=n;r++)e.push(r);return e}}return[...e]}var mE=new H,hE=new H,gE=new U,_E=new U(0,0,1),vE=[`screen`,`y`,`none`],yE=class extends Ah{static typeName=`Billboard3D`;static props={mode:{default:`screen`,options:vE}};mode=`screen`;_lastDesired=null;static validateJson(e){let t=e;if(!vE.includes(t.mode))throw new N(`BAD_FORMAT`,`Billboard3D '${e.name}' mode must be one of [${vE.join(`, `)}], got '${t.mode}'.`,{prop:`mode`,validOptions:vE})}_onRender3D(e){if(this.mode===`none`)return;let t=this._ensureObject3D();if(this.mode===`screen`)e.camera.getWorldQuaternion(hE);else if(e.camera.getWorldDirection(gE),gE.y=0,gE.lengthSq()>=1e-6)hE.setFromUnitVectors(_E,gE.negate().normalize());else if(this._lastDesired)hE.copy(this._lastDesired);else return;this._lastDesired||=new H,this._lastDesired.copy(hE),t.parent?.getWorldQuaternion(mE),t.parent?t.quaternion.copy(mE.invert()).multiply(hE):t.quaternion.copy(hE)}},bE=class extends Ah{static typeName=`BoneAttachment3D`;static props={target:{default:``,nodePath:!0},bone:{default:``}};target=``;bone=``;boneObj=null;lookedUpFor=``;get attachedBone(){return this.boneObj}_onRender3D(e){if(this.target===``||this.bone===``)return;let t=`${this.target} ${this.bone}`;if(this.lookedUpFor!==t||this.boneObj===null||!this.boneObj.parent){this.lookedUpFor=t,this.boneObj=null;let e=this.getNodeOrNull(this.target);e&&typeof e.findBone==`function`&&(this.boneObj=e.findBone(this.bone))}let n=this.boneObj;if(!n)return;let r=this._ensureObject3D(),i=r.parent;i&&(n.updateWorldMatrix(!0,!1),i.updateWorldMatrix(!0,!1),r.matrixAutoUpdate=!1,n.matrixWorld.decompose(CE,wE,TE),SE.compose(CE,wE,EE),r.updateMatrix(),xE.copy(r.matrix),r.matrix.copy(i.matrixWorld).invert().multiply(SE).multiply(xE))}free(){this.boneObj=null,super.free()}},xE=new G,SE=new G,CE=new U,wE=new H,TE=new U,EE=new U(1,1,1),DE=class extends Ah{static typeName=`BoneLookAt3D`;static props={target:{default:``,nodePath:!0},bone:{default:`Head`},lookAt:{default:``,nodePath:!0},maxAngleDeg:{default:75},weight:{default:.85},forwardAxis:{default:`+z`,options:[`+x`,`-x`,`+y`,`-y`,`+z`,`-z`]}};target=``;bone=`Head`;lookAt=``;maxAngleDeg=75;weight=.85;forwardAxis=`+z`;boneObj=null;lookedUpFor=``;engage=0;get attachedBone(){return this.boneObj}_onRender3D(e){if(this.target===``||this.bone===``)return;let t=`${this.target} ${this.bone}`;if(this.lookedUpFor!==t||this.boneObj===null||!this.boneObj.parent){this.lookedUpFor=t,this.boneObj=null;let e=this.getNodeOrNull(this.target);e&&typeof e.findBone==`function`&&(this.boneObj=e.findBone(this.bone))}let n=this.boneObj;if(!n?.parent)return;let r=this.lookAt===``?null:this.getNodeOrNull(this.lookAt),i=!1;if(r&&Array.isArray(r.position)&&(n.updateWorldMatrix(!0,!1),n.getWorldPosition(NE),PE.set(r.position[0]??0,r.position[1]??0,r.position[2]??0),FE.copy(PE).sub(NE),FE.lengthSq()>1e-6&&(FE.normalize(),IE.copy(kE[this.forwardAxis]??jE),LE.copy(IE).applyQuaternion(n.getWorldQuaternion(HE)),LE.angleTo(FE)<this.maxAngleDeg*Math.PI/180))){i=!0,RE.lookAt(NE,PE,AE),zE.setFromRotationMatrix(RE),BE.setFromUnitVectors(IE,ME),zE.multiply(BE),n.parent.getWorldQuaternion(VE).invert(),zE.premultiply(VE);let e=this.weight*this.engage;n.quaternion.slerp(zE,e)}this.engage+=(+!!i-this.engage)*OE}},OE=.18,kE={"+x":new U(1,0,0),"-x":new U(-1,0,0),"+y":new U(0,1,0),"-y":new U(0,-1,0),"+z":new U(0,0,1),"-z":new U(0,0,-1)},AE=new U(0,1,0),jE=new U(0,0,1),ME=new U(0,0,-1),NE=new U,PE=new U,FE=new U,IE=new U,LE=new U,RE=new G,zE=new H,BE=new H,VE=new H,HE=new H,UE=class extends Ah{static typeName=`Camera3D`;static props={fov:{default:60},near:{default:.1},far:{default:1e3},current:{default:!1}};fov=60;near=.1;far=1e3;current=!1;_createObject3D(){return new pu(this.fov,1,this.near,this.far)}_syncObject3D(){super._syncObject3D();let e=this._ensureObject3D();(e.fov!==this.fov||e.near!==this.near||e.far!==this.far)&&(e.fov=this.fov,e.near=this.near,e.far=this.far,e.updateProjectionMatrix())}},WE=8,GE=.2,KE=.15,qE=1.2,JE=.08,YE=2.5,XE=-20,ZE=.002,QE=180/Math.PI,$E=.3,eD=.4,tD=.3,nD=.25,rD=new Qa,iD=new H,aD=new G,oD=new U,sD=new U,cD=new U(0,1,0),lD=class extends Ah{static typeName=`CharacterController3D`;static signals=[`movementStateChanged`];static props={view:{default:`free`,options:[`free`,`firstPerson`,`quarter`,`side`]},camDistance:{default:4},eyeHeight:{default:.64},maxSpeed:{default:2.5},sprintMultiplier:{default:2},jumpVelocity:{default:4},sprintJumpMultiplier:{default:1.2},floatHeight:{default:.01},mouseLook:{default:!0},zoomMin:{default:0},zoomMax:{default:0},pitchMin:{default:-1.3},pitchMax:{default:1.5},cameraCollision:{default:!0},turnSpeed:{default:100},camLerp:{default:25},moveAction:{default:`move`},jumpAction:{default:`jump`},sprintAction:{default:`sprint`},skinPath:{default:`../Skin`,nodePath:!0},skinYawOffset:{default:0},animations:{default:{}}};view=`free`;camDistance=4;eyeHeight=.64;maxSpeed=2.5;sprintMultiplier=2;jumpVelocity=4;sprintJumpMultiplier=1.2;floatHeight=.01;mouseLook=!0;zoomMin=0;zoomMax=0;pitchMin=-1.3;pitchMax=1.5;cameraCollision=!0;turnSpeed=100;camLerp=25;moveAction=`move`;jumpAction=`jump`;sprintAction=`sprint`;skinPath=`../Skin`;skinYawOffset=0;animations={};yaw=0;pitch=0;state=`idle`;grounded=!1;get body(){let e=this.parent;if(!(e instanceof Ph))throw new N(`TREE_VIOLATION`,`CharacterController3D '${this.name}' must be a child of a RigidBody3D (parent is '${e?.name??`none`}').`);return e}onEnterTree(){if(this.body,this.skinPath!==``){let e=this.getNodeOrNull(this.skinPath);e&&(e.rotation=[e.rotation[0]??0,180+this.skinYawOffset,e.rotation[2]??0])}}fixedUpdate(e){let t=this.body,n=t._physics3d,r=this.tree?.engine?.input;if(!n||!r)return;let i=t.collider.radius??.32,a=(t.collider.height??1)/2,o=dD(t),s=n.velocityOf(t),c=n.massOf(t),l=i+this.floatHeight,u=i+2,d=o[1]-a,f=null;for(let[e,r]of[[0,0],[i,0],[-i,0],[0,i],[0,-i]]){let i=n.castRay([o[0]+e,d,o[2]+r],[0,-1,0],u,t);if(i){let t=i.distance;if(f=f===null?t:Math.min(f,t),e===0&&r===0)break}}this.grounded=f!==null&&f<l*2;let p=0,m=0,h=!1;try{let e=r.getVector(this.moveAction);h=e.x!==0||e.y!==0;let t=this.view===`free`||this.view===`firstPerson`?this.yaw:0,n=this.view===`side`?[e.x,0,0]:ww(e.x,-e.y,t),i=Math.hypot(n[0],n[2])||1;p=n[0]/i,m=n[2]/i}catch{}let g=fD(r,this.sprintAction),_=Tw(h,g),v=1+(this.sprintMultiplier-1)*_,y=h?this.maxSpeed*v:0,b=this.grounded?1:GE,x=(p*y-s[0])/WE*b,S=(m*y-s[2])/WE*b;if(t.applyImpulse([x*c,0,S*c]),!h&&this.grounded&&t.applyImpulse([-s[0]*KE*c,0,-s[2]*KE*c]),f!==null&&f<l*2){let e=qE*(l-f)-s[1]*JE;t.applyImpulse([0,e*c,0])}if(this.grounded&&fD(r,this.jumpAction)){let e=this.jumpVelocity*(1+(this.sprintJumpMultiplier-1)*_);t.linearVelocity=[s[0],e,s[2]],this.grounded=!1}s[1]<XE?t.gravityScale=0:s[1]<0&&!this.grounded?t.gravityScale=YE:t.gravityScale=1,this.view===`side`&&Math.abs(o[2])>.01&&(t.position=[t.position[0]??0,t.position[1]??0,0]);let C=Ew(this.grounded,h?_:0);if(C!==this.state){this.state=C;let e=this.animations[C];if(e&&this.skinPath!==``){let t=this.getNodeOrNull(this.skinPath);t&&`animation`in t&&(t.animation=e)}this.emit(`movementStateChanged`,C)}if(h&&this.skinPath!==``){let t=this.getNodeOrNull(this.skinPath);if(t){let n=Math.atan2(p,m)*QE+this.skinYawOffset,r=t.rotation[1]??0,i=(n-r+540)%360-180,a=this.turnSpeed*e*QE;Math.abs(i)>a&&(i=Math.sign(i)*a),t.rotation=[t.rotation[0]??0,r+i,t.rotation[2]??0]}}}update(e){let t=this.tree?.engine?.input;if(!t)return;if(this.mouseLook){let e=t.pointerDelta();this.yaw-=e.x*ZE,this.pitch=uD(this.pitch+e.y*ZE,-this.pitchMax,-this.pitchMin);let n=t.wheelDelta();n!==0&&this.zoomMax>this.zoomMin&&(this.camDistance=uD(this.camDistance+n*ZE,this.zoomMin,this.zoomMax))}let n=this.findCamera();if(!n)return;let r=this.parent instanceof Ph?this.parent:null;if(!r)return;let i=dD(r),a=this.view===`free`?11:1e3,o=1-Math.exp(-a*e),s=this.pivot??[i[0],i[1],i[2]];this.pivot=s,s[0]+=(i[0]-s[0])*o,s[1]+=(i[1]-s[1])*o,s[2]+=(i[2]-s[2])*o;let c=xw(this.view,s,this.eyeHeight,this.yaw,this.pitch,this.camDistance),l=[s[0],s[1]+this.eyeHeight,s[2]],u=[c.position[0],c.position[1],c.position[2]];if(this.cameraCollision&&this.view!==`firstPerson`){let e=r._physics3d;e&&(u=Sw(l,u,(t,n,i)=>e.castSphere(t,n,nD,i,r,{staticOnly:!0})?.distance??null,$E,eD),u=Cw(u,(t,n)=>e.castRay(t,[0,-1,0],n,r,{staticOnly:!0})?.distance??null,tD))}let d=this.view===`firstPerson`?1e3:this.camLerp,f=1-Math.exp(-d*e),p=n.position;n.position=[(p[0]??0)+(u[0]-(p[0]??0))*f,(p[1]??0)+(u[1]-(p[1]??0))*f,(p[2]??0)+(u[2]-(p[2]??0))*f],this.view===`free`?(oD.set(n.position[0]??0,n.position[1]??0,n.position[2]??0),sD.set(l[0],l[1],l[2]),aD.lookAt(oD,sD,cD),iD.setFromRotationMatrix(aD),rD.setFromQuaternion(iD,`XYZ`)):(rD.set(c.rotation[0],c.rotation[1],c.rotation[2],`YXZ`),iD.setFromEuler(rD),rD.setFromQuaternion(iD,`XYZ`)),n.rotation=[rD.x*QE,rD.y*QE,rD.z*QE]}pivot=null;cameraCache=null;findCamera(){if(this.cameraCache?.tree===this.tree&&this.cameraCache.current)return this.cameraCache;this.cameraCache=null;let e=this.tree?.root;if(!e)return null;let t=e=>{if(!this.cameraCache){if(e instanceof UE&&e.current){this.cameraCache=e;return}for(let n of e.children)t(n)}};return t(e),this.cameraCache}};function uD(e,t,n){return Math.min(n,Math.max(t,e))}function dD(e){let t=0,n=0,r=0;for(let i=e;i&&i instanceof Ah;i=i.parent)t+=i.position[0]??0,n+=i.position[1]??0,r+=i.position[2]??0;return[t,n,r]}function fD(e,t){try{return e.isPressed(t)}catch{return!1}}var pD=.15,mD=.7,hD=.5,gD=.7,_D=.5;function vD(e,t,n=3){let r=0,i=1,a=1,o=.65;for(let s=0;s<n;s++){let n=e*a,s=t*a,c=Math.sin(n*.1+s*.2)*.5+.5,l=Math.cos(n*.3+s*.1)*.5+.5,u=Math.sin((n+s)*.15)*.5+.5,d=Math.cos(n*n*.01+s*.2)*.5+.5,f=c*l*.7+u*d*.3;r+=f*i,i*=o,a*=2}return r/((1-o**n)/(1-o))}function yD(e,t){let n=vD(e*pD,t*pD,4),r=vD(e*pD*.2,t*pD*.2,2);return n>hD-mD*.5-r*_D}var bD=.9;function xD(e,t,n){let r=(Math.imul(e,2246822507)^Math.imul(t,3266489909)^Math.imul(n+1,668265263))>>>0;return r=Math.imul(r^r>>>15,739982445)>>>0,r=Math.imul(r^r>>>12,695872825)>>>0,r^=r>>>15,(r>>>0)/4294967296}function SD(e,t,n=bD){let r=Math.floor(e/n),i=Math.floor(t/n),a=1/0,o=r,s=i;for(let c=-1;c<=1;c++)for(let l=-1;l<=1;l++){let u=r+l,d=i+c,f=(u+xD(u,d,0))*n,p=(d+xD(u,d,1))*n,m=(e-f)*(e-f)+(t-p)*(t-p);m<a&&(a=m,o=u,s=d)}return{id:Math.imul(o,2654435761)^Math.imul(s,2246822519)|0,hue:xD(o,s,2)*2-1,leanDir:xD(o,s,3)*Math.PI*2,lean:xD(o,s,4)}}function CD(e,t,n,r){let i=e*r,a=t*r,o=Math.floor(i),s=Math.floor(a),c=i-o,l=a-s,u=c*c*(3-2*c),d=l*l*(3-2*l),f=xD(o,s,n),p=xD(o+1,s,n),m=xD(o,s+1,n),h=xD(o+1,s+1,n),g=f+(p-f)*u;return g+(m+(h-m)*u-g)*d}var wD=[.55,1.7],TD=.17,ED=.23,DD=.28;function OD(e,t,n){let r=CD(e,t,n^6877377|0,TD),i=r*r*(3-2*r);return wD[0]+(wD[1]-wD[0])*i}function kD(e,t,n){return CD(e,t,n^3001105|0,ED)}function AD(e,t,n){let r=CD(e,t,n^7840757|0,DD)*.72+CD(e,t,n^1688295|0,DD*3.1)*.28,i=Math.min(1,Math.max(0,(r-.18)/.64));return i*i*(3-2*i)}function jD(e){let{seed:t,areaX:n,areaZ:r,count:i,density:a}=e,o=new P(t),s=n/2,c=r/2,l=[],u=Math.floor(i*gD);for(let e=0;e<u&&l.length<i;e++){let e=o.range(-s,s),t=o.range(-c,c),n=o.next()<.3,r=yD(e,t);if(!n&&!r&&o.next()>.15)continue;let i=o.next()*Math.PI*2,a=.5+o.next()*.7,u=r?a*(1+o.next()*.2):a*(.9+o.next()*.2);l.push({x:e,z:t,rotY:i,scale:u})}let d=Math.min(3,Math.max(1,a*10)),f=Math.ceil(Math.sqrt(i*d)),p=n/f,m=r/f,h=Math.floor((i-l.length)*.8),g=0;for(let e=0;e<f&&l.length<i;e++)for(let t=0;t<f&&l.length<i;t++){let i=t/f*n-s+p/2,a=e/f*r-c+m/2,u=i+(o.next()-.5)*p*1.5,d=a+(o.next()-.5)*m*1.5;if(u<-s||u>s||d<-c||d>c)continue;let _=yD(u,d);if(g<h){if(!_&&o.next()>.05)continue}else if(_){if(o.next()>.2)continue}else if(o.next()>.4)continue;if(o.next()<.2)continue;let v=o.next()*Math.PI*2,y=_?.5:.3;l.push({x:u,z:d,rotY:v,scale:.5+o.next()*y}),g++}for(;l.length<i;)l.push({x:o.range(-s,s),z:o.range(-c,c),rotY:o.next()*Math.PI*2,scale:.4+o.next()*.6});return l.sort((e,t)=>t.z-e.z),l}var MD=[`daisy`,`cosmos`,`bellflower`],ND={daisy:{petals:8,blooms:3,leaves:3,petalLength:.1,petalWidth:.052,cupDeg:16,nodDeg:14,centerRadius:.024,centerColor:`#e0a72e`},cosmos:{petals:8,blooms:2,leaves:2,petalLength:.12,petalWidth:.064,cupDeg:26,nodDeg:18,centerRadius:.023,centerColor:`#d2941f`},bellflower:{petals:5,blooms:3,leaves:2,petalLength:.088,petalWidth:.058,cupDeg:46,nodDeg:52,centerRadius:.015,centerColor:`#cfe06a`}},PD=[1,.78,.62],FD=[0,.07,.11],ID=[.6,2.7,4.9],LD=.07,RD=.011,zD=.17,BD=.05,VD=[.12,.2,.28],HD=new K(`#3e6a26`),UD=new K(`#548331`);function WD(e){let t=ND[e],n=new GD(!0),r=new GD(!1),i=new K(t.centerColor);for(let e=0;e<t.blooms;e++){let a=PD[e],o=ID[e],s=FD[e]*Math.cos(o),c=FD[e]*Math.sin(o),l=LD*Math.cos(o),u=LD*Math.sin(o),d=new U(s,0,c),f=new U(s+l,a,c+u),p=new U(s+l*.25,a*.55,c+u*.25);n.addStem(d,p,f,RD,HD);let m=t.nodDeg*Math.PI/180,h=new U(Math.sin(m)*Math.cos(o),Math.cos(m),Math.sin(m)*Math.sin(o)),g=new U(-Math.sin(o),0,Math.cos(o)),_=new U().crossVectors(h,g).normalize(),v=f.clone().addScaledVector(h,.012),y=t.cupDeg*Math.PI/180,b=e*.45;for(let e=0;e<t.petals;e++){let n=e/t.petals*Math.PI*2+b,i=g.clone().multiplyScalar(Math.cos(n)).addScaledVector(_,Math.sin(n)).normalize();r.addPetal(v,i,h,t,y)}n.addDisc(v.clone().addScaledVector(h,.004),g,_,t.centerRadius,i)}for(let e=0;e<t.leaves;e++){let t=VD[e%VD.length],r=1.1+e*2.3;n.addLeaf(new U(0,t,0),r,UD)}return{structure:n.build(),petals:r.build()}}var GD=class{positions=[];colors;indices=[];constructor(e){this.colors=e?[]:null}vertex(e,t){let n=this.positions.length/3;return this.positions.push(e.x,e.y,e.z),this.colors&&t&&this.colors.push(t.r,t.g,t.b),n}addStem(e,t,n,r,i){for(let a of[0,Math.PI/2]){let o=new U(Math.cos(a),0,Math.sin(a)),s=[];for(let a=0;a<=5;a++){let c=a/5,l=1-c,u=new U(l*l*e.x+2*l*c*t.x+c*c*n.x,l*l*e.y+2*l*c*t.y+c*c*n.y,l*l*e.z+2*l*c*t.z+c*c*n.z),d=r/2*(1-.4*c);s.push(this.vertex(u.clone().addScaledVector(o,-d),i),this.vertex(u.clone().addScaledVector(o,d),i))}for(let e=0;e<5;e++){let t=s[e*2],n=s[e*2+1],r=s[e*2+2],i=s[e*2+3];this.indices.push(t,n,r,r,n,i)}}}addPetal(e,t,n,r,i){let a=new U().crossVectors(n,t).normalize(),o=r.centerRadius*.85,s=Math.sin(i)*r.petalLength*.45,c=Math.sin(i)*r.petalLength*.95,l=Math.cos(i),u=e.clone().addScaledVector(t,o),d=o+r.petalLength*l*.55,f=o+r.petalLength*l,p=e.clone().addScaledVector(t,d).addScaledVector(a,r.petalWidth/2).addScaledVector(n,s),m=e.clone().addScaledVector(t,d).addScaledVector(a,-r.petalWidth/2).addScaledVector(n,s),h=e.clone().addScaledVector(t,f).addScaledVector(n,c),g=this.vertex(u,null),_=this.vertex(p,null),v=this.vertex(m,null),y=this.vertex(h,null);this.indices.push(g,_,y,g,y,v)}addDisc(e,t,n,r,i){let a=this.vertex(e,i),o=[];for(let a=0;a<6;a++){let s=a/6*Math.PI*2;o.push(this.vertex(e.clone().addScaledVector(t,Math.cos(s)*r).addScaledVector(n,Math.sin(s)*r),i))}for(let e=0;e<6;e++)this.indices.push(a,o[e],o[(e+1)%6])}addLeaf(e,t,n){let r=new U(Math.cos(t),0,Math.sin(t)),i=new U(-Math.sin(t),0,Math.cos(t)),a=Math.sin(.6),o=Math.cos(.6),s=e.clone().addScaledVector(r,zD*o*.5).add(new U(0,zD*a*.5,0)),c=e.clone().addScaledVector(r,zD*o).add(new U(0,zD*a*.8,0)),l=this.vertex(e,n),u=this.vertex(s.clone().addScaledVector(i,BD/2),n),d=this.vertex(s.clone().addScaledVector(i,-.05/2),n),f=this.vertex(c,n);this.indices.push(l,u,f,l,f,d)}build(){let e=new J;return e.setAttribute(`position`,new q(new Float32Array(this.positions),3)),this.colors&&e.setAttribute(`color`,new q(new Float32Array(this.colors),3)),e.setIndex(this.indices),e.computeVertexNormals(),e}},KD=2.6;function qD(e){let{seed:t,areaX:n,areaZ:r,count:i,clustering:a}=e,o=new P(t),s=n/2,c=r/2,l=1-.74*Math.min(Math.max(a,0),1),u=[];for(let e=0;e<i*16&&u.length<i;e++){let e=o.range(-s,s),t=o.range(-c,c),n=SD(e,t,KD);n.lean>l&&o.next()>.06||u.push({x:e,z:t,rotY:o.next()*Math.PI*2,scale:.75+o.next()*.5,variety01:(n.hue+1)/2,color01:n.leanDir/(Math.PI*2)})}return u}var JD=1.05,YD=1;function XD(e,t=YD){e.computeBoundingSphere();let n=e.boundingSphere;n&&n.radius>=0&&(n.radius=n.radius*JD+t),e.frustumCulled=!0}function ZD(e){let t=0,n=0,r=0;for(let i=e;i;i=i.parent)i instanceof Ah&&(t+=i.position[0]??0,n+=i.position[1]??0,r+=i.position[2]??0);return[t,n,r]}function QD(e,t){if(t!==``){let n=e.getNodeOrNull(t);return n instanceof _T?n:null}return $D(e.getRoot())}function $D(e){if(e instanceof _T)return e;for(let t of e.children){let e=$D(t);if(e)return e}return null}function eO(e){return typeof e?._waterYAt==`function`}function tO(e){let t=e;for(;t.parent;)t=t.parent;let n=[],r=e=>{e.visible!==!1&&eO(e)&&n.push(e);for(let t of e.children)r(t)};return r(t),n}function nO(e,t,n,r,i=.06){for(let a=0;a<e.length;a++){let o=e[a]?._waterYAt(t,n);if(o!=null&&o-r>i)return!0}return!1}var rO={lush:2.2,sparse:.35,none:0},iO=[`lush`,`sparse`,`none`];function aO(e){if(typeof e==`number`)return e;let t=rO[e];if(t===void 0)throw new N(`BAD_FORMAT`,`Flowers3D density must be one of [${iO.join(`, `)}] or a number (plants/m²), got '${e}'.`,{prop:`density`,validOptions:iO});return t}var oO=1e4,sO=[`#f5f1e2`,`#e9d052`,`#8d7bd9`],cO=/^#[0-9a-fA-F]{6}$/,lO=class extends Ah{static typeName=`Flowers3D`;static props={density:{default:`sparse`,options:iO},area:{default:[20,20]},seed:{default:1},varieties:{default:[]},palette:{default:[]},height:{default:.45},clustering:{default:.6},sway:{default:.5},drape:{default:null},avoidWater:{default:!0},terrain:{default:``,nodePath:!0}};density=`sparse`;area=[20,20];seed=1;varieties=[];palette=[];height=.45;clustering=.6;sway=.5;drape=null;avoidWater=!0;terrain=``;drapeTerrain=null;drapeWorld=[0,0,0];static validateJson(e){let t=e;if(typeof t.density==`string`)aO(t.density);else if(!(Number.isFinite(t.density)&&t.density>=0))throw new N(`BAD_FORMAT`,`Flowers3D '${e.name}' density must be one of [${iO.join(`, `)}] or a number >= 0 (plants/m²), got ${t.density}.`,{prop:`density`,validOptions:iO});if(!((t.area[0]??0)>0)||!((t.area[1]??0)>0))throw new N(`BAD_FORMAT`,`Flowers3D '${e.name}' area must be positive [x, z] meters, got ${JSON.stringify(t.area)}.`,{prop:`area`});let n=Math.floor((t.area[0]??0)*(t.area[1]??0)*aO(t.density));if(n>oO)throw new N(`BAD_FORMAT`,`Flowers3D '${e.name}' blows the plant budget: area ${t.area[0]}×${t.area[1]} m × density ${aO(t.density)} = ${n} plants > ${oO}. Lower the density or split the field into multiple nodes.`,{prop:`density`});if(!Array.isArray(t.varieties)||new Set(t.varieties).size!==t.varieties.length||!t.varieties.every(e=>MD.includes(e)))throw new N(`BAD_FORMAT`,`Flowers3D '${e.name}' varieties must be a unique subset of [${MD.join(`, `)}] ([] = all three), got ${JSON.stringify(t.varieties)}.`,{prop:`varieties`,validOptions:[...MD]});if(!Array.isArray(t.palette)||!t.palette.every(e=>typeof e==`string`&&cO.test(e)))throw new N(`BAD_FORMAT`,`Flowers3D '${e.name}' palette must be an array of '#rrggbb' head colors ([] = white/yellow/violet), got ${JSON.stringify(t.palette)}.`,{prop:`palette`});if(!(t.height>0))throw new N(`BAD_FORMAT`,`Flowers3D '${e.name}' height must be > 0 meters, got ${t.height}.`,{prop:`height`});if(!(t.clustering>=0)||!(t.clustering<=1))throw new N(`BAD_FORMAT`,`Flowers3D '${e.name}' clustering must be in [0, 1] (0 uniform … 1 tight patches), got ${t.clustering}.`,{prop:`clustering`});if(!(t.sway>=0))throw new N(`BAD_FORMAT`,`Flowers3D '${e.name}' sway must be >= 0, got ${t.sway}.`,{prop:`sway`});if(t.drape!==null&&typeof t.drape!=`boolean`)throw new N(`BAD_FORMAT`,`Flowers3D '${e.name}' drape must be true, false or null (null = auto: drape whenever the scene has a Terrain3D), got ${JSON.stringify(t.drape)}.`,{prop:`drape`});if(typeof t.terrain!=`string`)throw new N(`BAD_FORMAT`,`Flowers3D '${e.name}' terrain must be a node-path string (empty = auto-find), got ${JSON.stringify(t.terrain)}.`,{prop:`terrain`})}time=0;field=null;varietyMeshes=[];fieldKey=``;timeUniform={value:0};swayUniform={value:.5};_createObject3D(){return new _o}_varietyMeshes(){return this.rebuildIfNeeded(),this.varietyMeshes}update(e){this.time+=e,this.timeUniform.value=this.time}_syncObject3D(){super._syncObject3D(),this.rebuildIfNeeded(),this.swayUniform.value=this.sway}rebuildIfNeeded(){this.field||(this.field=new _o,this._ensureObject3D().add(this.field));let e=JSON.stringify([this.density,this.area,this.seed,this.varieties,this.palette,this.height,this.clustering,this.drape,this.terrain]);e!==this.fieldKey&&(this.fieldKey=e,this.disposeMeshes(),this.resolveDrape(),this.buildField())}resolveDrape(){if(this.drapeTerrain=null,this.drape===!1)return;let e=QD(this,this.terrain);if(e)this.drapeTerrain=e,this.drapeWorld=ZD(this);else if(this.terrain!==``)throw new N(`NODE_NOT_FOUND`,`Flowers3D '${this.name}' drape terrain '${this.terrain}' is not a Terrain3D in the tree.`,{prop:`terrain`})}bedY(e,t){let n=this.drapeTerrain;return n?n.heightAt(this.drapeWorld[0]+e,this.drapeWorld[2]+t)-this.drapeWorld[1]:0}buildField(){let e=aO(this.density),t=Math.min(Math.floor((this.area[0]??0)*(this.area[1]??0)*e),oO);if(t<=0)return;let n=qD({seed:this.seed,areaX:this.area[0]??0,areaZ:this.area[1]??0,count:t,clustering:this.clustering});if(this.avoidWater){let e=tO(this);if(e.length>0){let[t,r,i]=ZD(this);n=n.filter(n=>!nO(e,n.x+t,n.z+i,this.bedY(n.x,n.z)+r))}}let r=this.varieties.length>0?this.varieties:MD,i=r.map(()=>[]);for(let e of n)i[Math.min(Math.floor(e.variety01*r.length),r.length-1)].push(e);let a=this.palette.length>0?this.palette:sO,o=new P(this.seed+15797765);for(let e=0;e<r.length;e++){let t=i[e];if(t.length===0)continue;let{structure:n,petals:s}=WD(r[e]),c=new bl({vertexColors:!0,roughness:1,side:2}),l=new bl({roughness:.85,side:2});uO(c,this.timeUniform,this.swayUniform),uO(l,this.timeUniform,this.swayUniform);let u=new xc(n,c,t.length),d=new xc(s,l,t.length);u.receiveShadow=!0,d.receiveShadow=!0;for(let e=0;e<t.length;e++){let n=t[e];pO.set(n.x,this.bedY(n.x,n.z),n.z),mO.setFromAxisAngle(dO,n.rotY),hO.setScalar(this.height*n.scale),fO.compose(pO,mO,hO),u.setMatrixAt(e,fO),d.setMatrixAt(e,fO);let r=Math.min(Math.floor(n.color01*a.length),a.length-1);gO.set(a[r]).offsetHSL(o.range(-.02,.02),0,o.range(-.05,.05)),d.setColorAt(e,gO),gO.setRGB(1,1,1).offsetHSL(o.range(-.02,.02),0,o.range(-.06,.04)),u.setColorAt(e,gO)}u.instanceMatrix.needsUpdate=!0,d.instanceMatrix.needsUpdate=!0,u.instanceColor&&(u.instanceColor.needsUpdate=!0),d.instanceColor&&(d.instanceColor.needsUpdate=!0),XD(u),XD(d),this.varietyMeshes.push({variety:r[e],structure:u,petals:d}),this.field.add(u),this.field.add(d)}}disposeMeshes(){for(let{structure:e,petals:t}of this.varietyMeshes)for(let n of[e,t])n.removeFromParent(),n.geometry.dispose(),n.material.dispose(),n.dispose();this.varietyMeshes=[]}free(){this.disposeMeshes(),this.field=null,super.free()}};function uO(e,t,n){e.userData.sway=!0,e.userData.timeUniform=t,e.onBeforeCompile=e=>{e.uniforms.uFlowerTime=t,e.uniforms.uFlowerSway=n,e.vertexShader=`uniform float uFlowerTime;\nuniform float uFlowerSway;\n${e.vertexShader}`.replace(`#include <project_vertex>`,`
|
|
6977
6977
|
vec4 mvPosition = vec4(transformed, 1.0);
|
|
6978
6978
|
#ifdef USE_INSTANCING
|
|
6979
6979
|
mvPosition = instanceMatrix * mvPosition;
|
|
@@ -6986,7 +6986,7 @@ normal = perturbSplatNormal(normal, vViewPosition, vUvSplat, blendedNormalSample
|
|
|
6986
6986
|
mvPosition.z += uFlowerSway * swayW * 0.020 * cos(uFlowerTime * 1.3 + swayPhase * 1.4);
|
|
6987
6987
|
mvPosition = modelViewMatrix * mvPosition;
|
|
6988
6988
|
gl_Position = projectionMatrix * mvPosition;
|
|
6989
|
-
`)},e.customProgramCacheKey=()=>`incanto-flowers-sway`}var
|
|
6989
|
+
`)},e.customProgramCacheKey=()=>`incanto-flowers-sway`}var dO=new U(0,1,0),fO=new G,pO=new U,mO=new H,hO=new U,gO=new K;function _O(e,t,n=4){let r=t.areaX/2,i=t.areaZ/2,a=e.filter(e=>Math.abs(e.x-t.x)<=r+e.radius&&Math.abs(e.z-t.z)<=i+e.radius);return a.sort((e,n)=>(e.x-t.x)**2+(e.z-t.z)**2-((n.x-t.x)**2+(n.z-t.z)**2)),a.slice(0,n)}var vO=[1,.78,.42];function yO(e){let t=new Float32Array(21),n=new Float32Array(14);for(let r=0;r<3;r++){let i=r/3,a=vO[r]*e/2;for(let e=0;e<2;e++){let o=r*2+e;t[o*3]=e===0?-a:a,t[o*3+1]=i,t[o*3+2]=0,n[o*2]=e,n[o*2+1]=i}}t[18]=0,t[19]=1,t[20]=0,n[12]=.5,n[13]=1;let r=new J;return r.setAttribute(`position`,new q(t,3)),r.setAttribute(`uv`,new q(n,2)),r.setIndex([0,1,2,2,1,3,2,3,4,4,3,5,4,5,6]),r}function bO(e){let t=new Float32Array([0,1.025,0,-e,.985,0,0,.985,e,e,.985,0,0,.985,-e]),n=new J;return n.setAttribute(`position`,new q(t,3)),n.setIndex([0,1,2,0,2,3,0,3,4,0,4,1]),n.computeVertexNormals(),n}var xO=`
|
|
6990
6990
|
uniform float time;
|
|
6991
6991
|
uniform float windStrength;
|
|
6992
6992
|
uniform float grassHeight;
|
|
@@ -7064,7 +7064,7 @@ void main() {
|
|
|
7064
7064
|
gl_Position = projectionMatrix * mvPosition;
|
|
7065
7065
|
#include <fog_vertex>
|
|
7066
7066
|
}
|
|
7067
|
-
`,
|
|
7067
|
+
`,SO=`
|
|
7068
7068
|
uniform float time;
|
|
7069
7069
|
varying vec2 vUv;
|
|
7070
7070
|
varying float vHeight;
|
|
@@ -7222,7 +7222,7 @@ void main() {
|
|
|
7222
7222
|
// patches melt into the same fog as the terrain instead of staying vivid.
|
|
7223
7223
|
#include <fog_fragment>
|
|
7224
7224
|
}
|
|
7225
|
-
`,
|
|
7225
|
+
`,CO=`
|
|
7226
7226
|
// incanto atmosphere: standard fog + shadow-receive chunks — both compile
|
|
7227
7227
|
// out unless the scene declares fog / a light casts (USE_FOG, USE_SHADOWMAP)
|
|
7228
7228
|
#include <common>
|
|
@@ -7326,7 +7326,7 @@ void main() {
|
|
|
7326
7326
|
#include <fog_vertex>
|
|
7327
7327
|
#include <shadowmap_vertex>
|
|
7328
7328
|
}
|
|
7329
|
-
`,
|
|
7329
|
+
`,wO=`
|
|
7330
7330
|
// incanto atmosphere: fog + shadow-receive (grass RECEIVES, never casts —
|
|
7331
7331
|
// per-blade casting would double the vertex bill for invisible gain).
|
|
7332
7332
|
// receiveShadow is declared by lights_pars_begin in BUILT-IN materials; a
|
|
@@ -7398,7 +7398,7 @@ void main() {
|
|
|
7398
7398
|
#include <colorspace_fragment>
|
|
7399
7399
|
#include <fog_fragment>
|
|
7400
7400
|
}
|
|
7401
|
-
`,
|
|
7401
|
+
`,TO=.4;function EO(e){if(typeof e.radius==`number`)return e.radius;let t=e.size;if(Array.isArray(t)){let e=typeof t[0]==`number`?t[0]:0,n=typeof t[2]==`number`?t[2]:0;if(e>0||n>0)return Math.max(e,n)/2}return TO}function DO(e){let t=typeof e.radius==`number`?e.radius:0,n=typeof e.height==`number`?e.height:0;if(n>0)return n/2+t;if(t>0)return t;let r=e.size;return Array.isArray(r)&&typeof r[1]==`number`?r[1]/2:TO}function OO(e,t){t.length=0,kO(e,t)}function kO(e,t){if(e instanceof Fh||e instanceof Ph){let[n,r,i]=ZD(e);t.push({x:n,y:r,z:i,radius:EO(e.collider),footY:r-DO(e.collider)})}for(let n of e.children)kO(n,t)}function AO(e){let t=e.tree;if(!t){let t=[];return OO(e.getRoot(),t),t}let n=t._frameScratch;if(n&&n.frameId===t.frameId)return n.bodies;let r=n?.bodies??[],i=t.root;return i?OO(i,r):r.length=0,t._frameScratch={frameId:t.frameId,bodies:r},r}var jO=6,MO=512;function NO(e,t=`grass`){if(t===`fern`)return PO(e);let n=new P(e+28919),r=[];for(let e=0;e<180;e++){let e=.5+(n.next()+n.next()-1)*.17,t=(e>=.5?1:-1)*n.range(.04,.5)+n.range(-.1,.1),i=n.range(.45,1),a=Math.min(1,Math.max(0,e+t*(1.5-.9*i)));r.push({rootX:e,tipX:a,height:i,width:n.range(.0028,.0085),shade:n.range(.45,.98),bow:t*n.range(.25,.6)})}return r}function PO(e){let t=new P(e+65121),n=[];for(let e=0;e<56;e++){let r=.5+(t.next()+t.next()-1)*.1,i=(e%2==0?1:-1)*t.range(.12,.55)+t.range(-.06,.06),a=t.range(.32,.85),o=Math.min(1,Math.max(0,r+i*(1.6-.7*a)));n.push({rootX:r,tipX:o,height:a,width:t.range(.014,.03),shade:t.range(.4,.85),bow:i*t.range(.5,.85)})}return n}function FO(e,t=`grass`){let n=e.shade,r=Math.max(.3,e.shade*.62);if(t===`fern`){let e=[{offset:0,gray:r,alpha:0}],t=.14;for(let i=0;i<jO;i++){let a=t+(1-t)*i/jO,o=t+(1-t)*(i+1)/jO,s=r+(n-r)*((a+o)/2);e.push({offset:a+(o-a)*.12,gray:s,alpha:1}),e.push({offset:a+(o-a)*.74,gray:s,alpha:1}),i<jO-1&&e.push({offset:a+(o-a)*.92,gray:s,alpha:.2})}return e[e.length-1].offset<1&&e.push({offset:1,gray:n,alpha:1}),e}return[{offset:0,gray:r,alpha:0},{offset:.22,gray:r,alpha:1},{offset:1,gray:n,alpha:1}]}function IO(e,t=`grass`){if(typeof document>`u`)return null;let n=MO,r=document.createElement(`canvas`);r.width=n,r.height=n;let i=r.getContext(`2d`);if(!i)return null;i.clearRect(0,0,n,n);for(let r of NO(e,t)){let e=r.rootX*n,a=n,o=r.tipX*n,s=(1-r.height)*n,c=(e+o)/2+r.bow*n,l=(a+s)/2,u=Math.max(r.width*n,.75);i.beginPath(),i.moveTo(e-u,a),i.quadraticCurveTo(c-u*.55,l,o,s),i.quadraticCurveTo(c+u*.55,l,e+u,a),i.closePath();let d=i.createLinearGradient(e,a,o,s);for(let e of FO(r,t)){let t=Math.round(e.gray*255);d.addColorStop(e.offset,`rgba(${t},${t},${t},${e.alpha})`)}i.fillStyle=d,i.fill()}let a=new Qc(r);return a.colorSpace=Oi,a}var LO=.08,RO=.5,zO=12,BO=`
|
|
7402
7402
|
// GLSL Simplex Noise 3D — https://github.com/ashima/webgl-noise (MIT)
|
|
7403
7403
|
vec3 ezMod289(vec3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }
|
|
7404
7404
|
vec4 ezMod289(vec4 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }
|
|
@@ -7450,9 +7450,9 @@ float ezSimplex3(vec3 v) {
|
|
|
7450
7450
|
m = m * m;
|
|
7451
7451
|
return 42.0 * dot(m * m, vec4(dot(g0, x0), dot(g1, x1), dot(g2, x2), dot(g3, x3)));
|
|
7452
7452
|
}
|
|
7453
|
-
`;function
|
|
7453
|
+
`;function VO(e){return`#include <lights_fragment_maps>
|
|
7454
7454
|
iblIrradiance *= ${e.toFixed(3)};
|
|
7455
|
-
radiance *= ${e.toFixed(3)};`}function
|
|
7455
|
+
radiance *= ${e.toFixed(3)};`}function HO(e,t){e.userData.envCut=t,e.onBeforeCompile=e=>{e.fragmentShader=e.fragmentShader.replace(`#include <lights_fragment_maps>`,VO(t))},e.customProgramCacheKey=()=>`incanto-env-cut-${t.toFixed(3)}`}function UO(e,t,n=1,r){e.userData.sway=!0,e.userData.timeUniform=t,e.userData.envCut=n,r&&(e.userData.leafFade=r);let i=r?`uniform float uLeafFadeStart;
|
|
7456
7456
|
uniform float uLeafFadeEnd;
|
|
7457
7457
|
attribute vec3 anchor;
|
|
7458
7458
|
`:``,a=r?`
|
|
@@ -7462,16 +7462,16 @@ attribute vec3 anchor;
|
|
|
7462
7462
|
#endif
|
|
7463
7463
|
vec4 ezAnchorWorld = modelMatrix * ezAnchor;
|
|
7464
7464
|
float ezFade = step(uLeafFadeStart + 1e-4, uLeafFadeEnd) * smoothstep(uLeafFadeStart, max(uLeafFadeEnd, uLeafFadeStart + 1e-4), distance(cameraPosition, ezAnchorWorld.xyz));
|
|
7465
|
-
mvPosition.xyz = mix(mvPosition.xyz, ezAnchor.xyz, ezFade);`:``;e.onBeforeCompile=e=>{e.uniforms.uTreeTime=t,r&&(e.uniforms.uLeafFadeStart=r.start,e.uniforms.uLeafFadeEnd=r.end),e.vertexShader=`uniform float uTreeTime;\n${i}${e.vertexShader}`.replace(`void main() {`,`${
|
|
7465
|
+
mvPosition.xyz = mix(mvPosition.xyz, ezAnchor.xyz, ezFade);`:``;e.onBeforeCompile=e=>{e.uniforms.uTreeTime=t,r&&(e.uniforms.uLeafFadeStart=r.start,e.uniforms.uLeafFadeEnd=r.end),e.vertexShader=`uniform float uTreeTime;\n${i}${e.vertexShader}`.replace(`void main() {`,`${BO}\nvoid main() {`).replace(`#include <project_vertex>`,`
|
|
7466
7466
|
vec4 mvPosition = vec4(transformed, 1.0);
|
|
7467
7467
|
#ifdef USE_INSTANCING
|
|
7468
7468
|
mvPosition = instanceMatrix * mvPosition;
|
|
7469
7469
|
#endif
|
|
7470
|
-
float windOffset = 2.0 * 3.14 * ezSimplex3(mvPosition.xyz / ${
|
|
7471
|
-
mvPosition.xyz += uv.y * ${
|
|
7472
|
-
0.5 * sin(uTreeTime * ${
|
|
7473
|
-
0.3 * sin(2.0 * uTreeTime * ${
|
|
7474
|
-
0.2 * sin(5.0 * uTreeTime * ${
|
|
7470
|
+
float windOffset = 2.0 * 3.14 * ezSimplex3(mvPosition.xyz / ${zO.toFixed(1)});
|
|
7471
|
+
mvPosition.xyz += uv.y * ${LO.toFixed(3)} * vec3(1.0, 0.0, 1.0) * (
|
|
7472
|
+
0.5 * sin(uTreeTime * ${RO.toFixed(2)} + windOffset) +
|
|
7473
|
+
0.3 * sin(2.0 * uTreeTime * ${RO.toFixed(2)} + 1.3 * windOffset) +
|
|
7474
|
+
0.2 * sin(5.0 * uTreeTime * ${RO.toFixed(2)} + 1.5 * windOffset)
|
|
7475
7475
|
);${a}
|
|
7476
7476
|
mvPosition = modelViewMatrix * mvPosition;
|
|
7477
7477
|
gl_Position = projectionMatrix * mvPosition;
|
|
@@ -7485,18 +7485,18 @@ attribute vec3 anchor;
|
|
|
7485
7485
|
if (diffuseColor.a < ezCutoff) discard;
|
|
7486
7486
|
#endif
|
|
7487
7487
|
#endif
|
|
7488
|
-
`).replace(`#include <lights_fragment_maps>`,
|
|
7488
|
+
`).replace(`#include <lights_fragment_maps>`,VO(n))},e.customProgramCacheKey=r?()=>`incanto-eztree-leaf-wind-v5-fade-${n.toFixed(3)}`:()=>`incanto-eztree-leaf-wind-v4-${n.toFixed(3)}`}var WO=40,GO=1;function KO(e,t,n){e.userData.sway=!0,e.userData.timeUniform=t,e.userData.strengthUniform=n,e.onBeforeCompile=e=>{e.uniforms.uTuftTime=t,e.uniforms.uTuftWind=n,e.vertexShader=`uniform float uTuftTime;\nuniform float uTuftWind;\n${e.vertexShader}`.replace(`void main() {`,`${BO}\nvoid main() {`).replace(`#include <project_vertex>`,`
|
|
7489
7489
|
vec4 mvPosition = vec4(transformed, 1.0);
|
|
7490
7490
|
#ifdef USE_INSTANCING
|
|
7491
7491
|
mvPosition = instanceMatrix * mvPosition;
|
|
7492
7492
|
#endif
|
|
7493
|
-
float tuftPhase = 6.2832 * ezSimplex3(vec3(mvPosition.xz / ${
|
|
7493
|
+
float tuftPhase = 6.2832 * ezSimplex3(vec3(mvPosition.xz / ${WO.toFixed(1)}, 0.0));
|
|
7494
7494
|
mvPosition.xz += uv.y * uTuftWind *
|
|
7495
|
-
sin(uTuftTime * ${
|
|
7496
|
-
cos(uTuftTime * ${(1.4*
|
|
7495
|
+
sin(uTuftTime * ${GO.toFixed(1)} + tuftPhase) *
|
|
7496
|
+
cos(uTuftTime * ${(1.4*GO).toFixed(1)} + tuftPhase) * vec2(1.0, 0.8);
|
|
7497
7497
|
mvPosition = modelViewMatrix * mvPosition;
|
|
7498
7498
|
gl_Position = projectionMatrix * mvPosition;
|
|
7499
|
-
`)},e.customProgramCacheKey=()=>`incanto-tuft-wind`}var GO=[`grass`,`flowers`,`reeds`],KO=[`blades`,`simple`,`mesh`,`tufts`],qO=[`grass`,`fern`],JO={grass:.08,flowers:.14,reeds:.05},YO=[.75,1.25],XO=.05,ZO=.25,QO=2e5,$O=8,ek=.05,tk=.38,nk=[.75,1.3],rk=.1,ik=.42,ak=[.6,1.6],ok=.8,sk=.9,ck=.04,lk=[`#f5f1e2`,`#e9d052`,`#8d7bd9`],uk=1/3,dk=1.5,fk=1.45,pk=.4,mk=.13,hk=[.85,1.2],gk=[.8,1.3],_k=`#b3a24e`,vk=.8,yk=.5,bk=class e extends Oh{static typeName=`Foliage3D`;static props={kind:{default:`grass`,options:GO},style:{default:`mesh`,options:KO},tuftStyle:{default:`grass`,options:qO},area:{default:[20,20]},density:{default:12},maxInstances:{default:5e4},height:{default:.25},colorA:{default:`#4d7232`},colorB:{default:`#9aab55`},groundColor:{default:`#1f3015`},sunDirection:{default:[.5,.8,.3]},fadeStart:{default:60},fadeEnd:{default:90},sway:{default:.6},interaction:{default:!0},coverage:{default:.85},flowers:{default:0},seed:{default:1},drape:{default:null},avoidWater:{default:!0},terrain:{default:``,nodePath:!0},renderOrder:{default:2}};renderOrder=2;kind=`grass`;style=`mesh`;tuftStyle=`grass`;area=[20,20];density=12;maxInstances=5e4;height=.25;colorA=`#4d7232`;colorB=`#9aab55`;groundColor=`#1f3015`;sunDirection=[.5,.8,.3];fadeStart=60;fadeEnd=90;sway=.6;interaction=!0;coverage=.85;flowers=0;seed=1;drape=null;avoidWater=!0;terrain=``;drapeTerrain=null;drapeWorld=[0,0,0];static validateJson(e){let t=e;if(!GO.includes(t.kind))throw new N(`BAD_FORMAT`,`Foliage3D '${e.name}' kind must be one of [${GO.join(`, `)}], got '${t.kind}'.`,{prop:`kind`,validOptions:GO});if(!KO.includes(t.style))throw new N(`BAD_FORMAT`,`Foliage3D '${e.name}' style must be one of [${KO.join(`, `)}], got '${t.style}'.`,{prop:`style`,validOptions:KO});if(!qO.includes(t.tuftStyle))throw new N(`BAD_FORMAT`,`Foliage3D '${e.name}' tuftStyle must be one of [${qO.join(`, `)}], got '${t.tuftStyle}'.`,{prop:`tuftStyle`,validOptions:qO});if(!((t.area[0]??0)>0)||!((t.area[1]??0)>0))throw new N(`BAD_FORMAT`,`Foliage3D '${e.name}' area must be positive [x, z] meters, got ${JSON.stringify(t.area)}.`,{prop:`area`});if(!(t.density>0)||!(t.maxInstances>=1))throw new N(`BAD_FORMAT`,`Foliage3D '${e.name}' needs density > 0 and maxInstances >= 1, got density ${t.density}, maxInstances ${t.maxInstances}.`,{prop:`density`});if(t.maxInstances>QO)throw new N(`BAD_FORMAT`,`Foliage3D '${e.name}' maxInstances is capped at ${QO} (got ${t.maxInstances}) — split giant fields into multiple nodes.`,{prop:`maxInstances`});if(!(t.fadeStart>=0)||!(t.fadeEnd>t.fadeStart))throw new N(`BAD_FORMAT`,`Foliage3D '${e.name}' needs fadeStart >= 0 and fadeEnd > fadeStart (the LOD fade window), got fadeStart ${t.fadeStart}, fadeEnd ${t.fadeEnd}.`,{prop:`fadeStart`});let n=t.sunDirection;if(!Array.isArray(n)||n.length!==3||!n.every(e=>Number.isFinite(e))||Math.hypot(n[0]??0,n[1]??0,n[2]??0)===0)throw new N(`BAD_FORMAT`,`Foliage3D '${e.name}' sunDirection must be a non-zero [x, y, z] vector, got ${JSON.stringify(n)}.`,{prop:`sunDirection`});if(!(t.coverage>0)||!(t.coverage<=1))throw new N(`BAD_FORMAT`,`Foliage3D '${e.name}' coverage must be in (0, 1] (carpet fill — 1 is solid, lower carves dirt patches), got ${t.coverage}.`,{prop:`coverage`});if(!(t.flowers>=0)||!(t.flowers<=.2))throw new N(`BAD_FORMAT`,`Foliage3D '${e.name}' flowers must be in [0, 0.2] (fraction of instances rendered as flower heads — for a whole flower FIELD use kind: 'flowers'), got ${t.flowers}.`,{prop:`flowers`});if(t.drape!==null&&typeof t.drape!=`boolean`)throw new N(`BAD_FORMAT`,`Foliage3D '${e.name}' drape must be true, false or null (null = auto: drape whenever the scene has a Terrain3D), got ${JSON.stringify(t.drape)}.`,{prop:`drape`});if(typeof t.terrain!=`string`)throw new N(`BAD_FORMAT`,`Foliage3D '${e.name}' terrain must be a node-path string (empty = auto-find), got ${JSON.stringify(t.terrain)}.`,{prop:`terrain`})}time=0;pivot=null;meshes=[];bladesMaterial=null;benderSlots=null;pickedBenders=[];fieldKey=``;tuftTime=null;tuftStrength=null;tuftTexture=null;_createObject3D(){return new _o}get isBlades(){return this.kind===`grass`&&this.style===`blades`}get isMesh(){return this.kind===`grass`&&this.style===`mesh`}get isTufts(){return this.kind===`grass`&&this.style===`tufts`}get isShaderField(){return this.isMesh||this.isBlades}_field(){return this.rebuildIfNeeded(),this.meshes[0]}_fields(){return this.rebuildIfNeeded(),this.meshes}update(e){this.time+=e,this.pickedBenders=this.computeBenders(),this.writeAnimationUniforms()}writeAnimationUniforms(){if(this.isShaderField&&this.bladesMaterial){let e=this.bladesMaterial.uniforms;e.time&&(e.time.value=this.time),e.windStrength&&(e.windStrength.value=this.sway*(this.isMesh?tk:ZO));let t=this.benderSlots;if(t)for(let e=0;e<4;e++){let n=this.pickedBenders[e];n?t[e]?.set(n.x,n.y,n.z,n.radius):t[e]?.set(0,0,0,0)}}else this.isTufts&&(this.tuftTime&&(this.tuftTime.value=this.time),this.tuftStrength&&(this.tuftStrength.value=this.sway*mk))}_syncObject3D(){super._syncObject3D(),this.rebuildIfNeeded();let e=this.pivot;if(this.writeAnimationUniforms(),this.isShaderField){e.matrix.identity();let t=this.bladesMaterial.uniforms;(t.bottomColor?.value).set(this.colorA),(t.topColor?.value).set(this.colorB),this.isMesh&&((t.groundColor?.value).set(this.groundColor),(t.sunDirection?.value).set(this.sunDirection[0]??0,this.sunDirection[1]??1,this.sunDirection[2]??0).normalize(),t.fadeStart&&(t.fadeStart.value=this.fadeStart),t.fadeEnd&&(t.fadeEnd.value=this.fadeEnd))}else if(this.isTufts)e.matrix.identity();else if(this.sway>0){let t=Math.sin(this.time*1.7)*XO*this.sway,n=Math.sin(this.time*1.3+1.7)*XO*this.sway*.6;e.matrix.makeShear(0,0,t,n,0,0)}else e.matrix.identity();e.matrixWorldNeedsUpdate=!0}_applySunDirection(t){if(!this.isMesh||!this.bladesMaterial)return;let n=e.props.sunDirection?.default;this.sunDirection.every((e,t)=>e===n[t])&&(this.bladesMaterial.uniforms.sunDirection?.value)?.set(t[0],t[1],t[2])}computeBenders(){if(!this.interaction||!this.isShaderField)return[];let[e,t,n]=YD(this);this.drape===!0&&!this.drapeTerrain&&this.resolveDrape();let r=this.drapeTerrain,i=[];for(let e of OO(this)){let n=r?r.heightAt(e.x,e.z):t,a=e.footY-n;a<=yk&&a>=-2.5&&i.push({x:e.x,y:e.y,z:e.z,radius:e.radius+vk})}return hO(i,{x:e,z:n,areaX:this.area[0]??0,areaZ:this.area[1]??0})}rebuildIfNeeded(){this.pivot||(this.pivot=new _o,this.pivot.matrixAutoUpdate=!1,this._ensureObject3D().add(this.pivot));let e=JSON.stringify([this.kind,this.style,this.tuftStyle,this.area,this.density,this.maxInstances,this.height,this.colorA,this.colorB,this.coverage,this.flowers,this.seed,this.drape,this.terrain]);if(e===this.fieldKey&&this.meshes.length>0)return;this.fieldKey=e,this.disposeMeshes(),this.resolveDrape();let t=this.isMesh?$O:this.isTufts?uk:1,n=Math.min(Math.floor((this.area[0]??0)*(this.area[1]??0)*this.density*t),this.maxInstances);this.isMesh?this.buildMeshField(n):this.isTufts?this.buildTuftField(n):this.isBlades?this.buildBladesField(n):this.buildSimpleField(n);for(let e of this.meshes)JD(e),this.pivot.add(e)}resolveDrape(){if(this.drapeTerrain=null,this.drape===!1)return;let e=XD(this,this.terrain);if(e)this.drapeTerrain=e,this.drapeWorld=YD(this);else if(this.terrain!==``)throw new N(`NODE_NOT_FOUND`,`Foliage3D '${this.name}' drape terrain '${this.terrain}' is not a Terrain3D in the tree.`,{prop:`terrain`})}bedY(e,t){let n=this.drapeTerrain;return n?n.heightAt(this.drapeWorld[0]+e,this.drapeWorld[2]+t)-this.drapeWorld[1]:0}dryOnly(e){if(!this.avoidWater)return e;let t=$D(this);if(t.length===0)return e;let[n,,r]=YD(this);return e.filter(e=>!eO(t,e.x+n,e.z+r,this.bedY(e.x,e.z)+this.worldY()))}worldY(){return YD(this)[1]}buildMeshField(e){let t=kD({seed:this.seed,areaX:this.area[0]??0,areaZ:this.area[1]??0,count:e,density:this.density*$O}),n=this.dryOnly(this.coverage>=1?t:t.filter(e=>OD(e.x,e.z,this.seed)<=this.coverage)),r=this.flowers>0?Math.floor(n.length*this.flowers):0,i=new Set;for(let e=0;e<r;e++)i.add(Math.floor((e+.5)*n.length/r));let a=n.filter((e,t)=>!i.has(t)),o=n.filter((e,t)=>i.has(t));this.benderSlots=Array.from({length:4},()=>new Ra(0,0,0,0));let s=hl.merge([X.lights,X.fog]);Object.assign(s,{time:{value:0},windStrength:{value:this.sway*tk},topColor:{value:new K(this.colorB)},bottomColor:{value:new K(this.colorA)},groundColor:{value:new K(this.groundColor)},sunDirection:{value:new U(this.sunDirection[0]??0,this.sunDirection[1]??1,this.sunDirection[2]??0).normalize()},fadeStart:{value:this.fadeStart},fadeEnd:{value:this.fadeEnd},benders:{value:this.benderSlots}}),this.bladesMaterial=new vl({vertexShader:xO,fragmentShader:SO,uniforms:s,fog:!0,lights:!0,side:2});let c=_O(ek),l=a.length,u=Math.max(l,1),d=new xc(c,this.bladesMaterial,u);d.count=l,d.receiveShadow=!0;let f=new P(this.seed+5352221),p=new Float32Array(u*4),m=new Float32Array(u),h=new Float32Array(u);for(let e=0;e<l;e++){let t=a[e],n=bD(t.x,t.z),r=ED(t.x,t.z,this.seed),i=(r-.55)/1.15,o=f.range(nk[0],nk[1]),s=this.height*r*(.55+t.scale*.6);Ek.set(t.x,this.bedY(t.x,t.z),t.z),Dk.setFromAxisAngle(wk,t.rotY),Ok.set(o,s,o),d.setMatrixAt(e,Tk.compose(Ek,Dk,Ok));let c=n.leanDir+f.range(-.6,.6),l=(rk+ik*(.5*n.lean+.5*f.next()))*(1+ok*i);p[e*4]=Math.cos(c)*l,p[e*4+1]=Math.sin(c)*l,p[e*4+2]=f.range(ak[0],ak[1])*(1+sk*i),p[e*4+3]=f.next(),m[e]=n.hue;let u=DD(t.x,t.z,this.seed)*.85+(f.next()-.5)*.3;h[e]=Math.min(1,Math.max(0,u))}c.setAttribute(`aBlade`,new pc(p,4)),c.setAttribute(`aClumpHue`,new pc(m,1)),c.setAttribute(`aDry`,new pc(h,1)),d.instanceMatrix.needsUpdate=!0,this.meshes=[d],o.length>0&&this.meshes.push(this.buildFlowerMesh(o))}buildFlowerMesh(e){let t=new xc(vO(ck),new bl({roughness:1,side:2}),Math.max(e.length,1));t.count=e.length,t.receiveShadow=!0;let n=new P(this.seed+15797765);for(let r=0;r<e.length;r++){let i=e[r],a=ED(i.x,i.z,this.seed),o=this.height*a*(.85+n.next()*.35);Ek.set(i.x,this.bedY(i.x,i.z),i.z),Dk.setFromAxisAngle(wk,i.rotY),Ok.set(1,o,1),t.setMatrixAt(r,Tk.compose(Ek,Dk,Ok));let s=n.next(),c=lk[s<.45?0:s<.75?1:2];t.setColorAt(r,jk.set(c))}return t.instanceMatrix.needsUpdate=!0,t.instanceColor&&(t.instanceColor.needsUpdate=!0),t}buildTuftField(e){let t=kD({seed:this.seed,areaX:this.area[0]??0,areaZ:this.area[1]??0,count:e,density:this.density*uk}),n=this.dryOnly(this.coverage>=1?t:t.filter(e=>OD(e.x,e.z,this.seed)<=this.coverage));this.tuftTime={value:this.time},this.tuftStrength={value:this.sway*mk};let r=new bl({alphaTest:.5,side:2,roughness:1}),i=PO(this.seed,this.tuftStyle);i&&(r.map=i,this.tuftTexture=i),WO(r,this.tuftTime,this.tuftStrength);let a=new xc(Sk(),r,Math.max(n.length,1));a.count=n.length,a.castShadow=!1,a.receiveShadow=!0;let o=new P(this.seed+7403357),s=kk.set(this.colorA),c=Ak.set(this.colorB);for(let e=0;e<n.length;e++){let t=n[e],r=1+(ED(t.x,t.z,this.seed)-1)*pk,i=this.height*dk*r*o.range(hk[0],hk[1]),l=i*fk*o.range(gk[0],gk[1]);Ek.set(t.x,this.bedY(t.x,t.z),t.z),Dk.setFromAxisAngle(wk,t.rotY),Ok.set(l,i,l),a.setMatrixAt(e,Tk.compose(Ek,Dk,Ok));let u=bD(t.x,t.z),d=Math.min(1,Math.max(0,.5+.35*u.hue+(o.next()-.5)*.3)),f=Math.min(1,Math.max(0,DD(t.x,t.z,this.seed)*.8-.1));jk.copy(s).lerp(c,d).lerp(Mk.set(_k),f*.5).multiplyScalar(o.range(.62,1.18)),a.setColorAt(e,jk)}a.instanceMatrix.needsUpdate=!0,a.instanceColor&&(a.instanceColor.needsUpdate=!0),this.meshes=[a]}buildBladesField(e){let t=kD({seed:this.seed,areaX:this.area[0]??0,areaZ:this.area[1]??0,count:e,density:this.density});this.benderSlots=Array.from({length:4},()=>new Ra(0,0,0,0));let n=hl.merge([X.fog]);Object.assign(n,{time:{value:0},windStrength:{value:this.sway*ZO},topColor:{value:new K(this.colorB)},bottomColor:{value:new K(this.colorA)},grassHeight:{value:this.height},grassScale:{value:1},benders:{value:this.benderSlots}}),this.bladesMaterial=new vl({vertexShader:yO,fragmentShader:bO,uniforms:n,fog:!0,transparent:!0,side:2,depthWrite:!0,depthTest:!0,alphaTest:.1,blending:0});let r=xk(this.height),i=new xc(r,this.bladesMaterial,Math.max(e,1)),a=new xc(r,this.bladesMaterial,Math.max(e,1));i.count=e,a.count=e,i.renderOrder=this.renderOrder,a.renderOrder=this.renderOrder;for(let n=0;n<e;n++){let e=t[n];Ek.set(e.x,this.bedY(e.x,e.z),e.z),Ok.setScalar(e.scale),Dk.setFromAxisAngle(wk,e.rotY),i.setMatrixAt(n,Tk.compose(Ek,Dk,Ok)),Dk.setFromAxisAngle(wk,e.rotY+Math.PI/2),a.setMatrixAt(n,Tk.compose(Ek,Dk,Ok))}i.instanceMatrix.needsUpdate=!0,a.instanceMatrix.needsUpdate=!0,this.meshes=[i,a]}buildSimpleField(e){let t=new bl({side:2,roughness:1}),n=new xc(Ck(JO[this.kind]??.08),t,Math.max(e,1));n.receiveShadow=!0;let r=new P(this.seed),i=(this.area[0]??0)/2,a=(this.area[1]??0)/2,o=kk.set(this.colorA),s=Ak.set(this.colorB),c=this.avoidWater?$D(this):[],[l,u,d]=YD(this),f=0;for(let t=0;t<e;t++){let e=r.range(-i,i),t=r.range(-a,a),p=r.range(0,Math.PI*2),m=r.range(YO[0],YO[1]),h=r.next(),g=this.bedY(e,t);c.length>0&&eO(c,e+l,t+d,g+u)||(Ek.set(e,g,t),Dk.setFromAxisAngle(wk,p),Ok.set(1,this.height*m,1),Tk.compose(Ek,Dk,Ok),n.setMatrixAt(f,Tk),n.setColorAt(f,jk.copy(o).lerp(s,h)),f++)}n.count=f,n.instanceMatrix.needsUpdate=!0,n.instanceColor&&(n.instanceColor.needsUpdate=!0),this.meshes=[n]}disposeMeshes(){let e=new Set(this.meshes.map(e=>e.geometry)),t=new Set(this.meshes.map(e=>e.material));for(let e of this.meshes)e.removeFromParent(),e.dispose();for(let t of e)t.dispose();for(let e of t)e.dispose?.();this.bladesMaterial?.dispose(),this.bladesMaterial=null,this.benderSlots=null,this.tuftTexture?.dispose(),this.tuftTexture=null,this.tuftTime=null,this.tuftStrength=null,this.meshes=[]}free(){this.disposeMeshes(),this.pivot=null,super.free()}};function xk(e){let t=new cl(1,e,1,1);return t.translate(0,e/2,0),t}function Sk(){let e=[],t=[],n=[],r=[];for(let i=0;i<3;i++){let a=i*Math.PI/3,o=Math.cos(a)/2,s=Math.sin(a)/2,c=-Math.sin(a),l=Math.cos(a),u=i*4;e.push(-o,0,-s,o,0,s,-o,1,-s,o,1,s);for(let e=0;e<4;e++)t.push(c,0,l);n.push(0,0,1,0,0,1,1,1),r.push(u,u+1,u+3,u,u+3,u+2)}let i=new J;return i.setAttribute(`position`,new q(new Float32Array(e),3)),i.setAttribute(`normal`,new q(new Float32Array(t),3)),i.setAttribute(`uv`,new q(new Float32Array(n),2)),i.setIndex(r),i}function Ck(e){let t=e/2,n=new Float32Array([-t,0,0,t,0,0,-t,1,0,t,1,0,0,0,-t,0,0,t,0,1,-t,0,1,t]),r=new Float32Array([0,0,1,0,0,1,0,0,1,0,0,1,1,0,0,1,0,0,1,0,0,1,0,0]),i=new J;return i.setAttribute(`position`,new q(n,3)),i.setAttribute(`normal`,new q(r,3)),i.setIndex([0,1,2,2,1,3,4,5,6,6,5,7]),i}var wk=new U(0,1,0),Tk=new G,Ek=new U,Dk=new H,Ok=new U,kk=new K,Ak=new K,jk=new K,Mk=new K,Nk=class extends Oh{static typeName=`DirectionalLight3D`;static props={color:{default:`#ffffff`},intensity:{default:1},castShadow:{default:!1},shadowArea:{default:75},shadowMapSize:{default:2048},shadowFollowsCamera:{default:!1}};color=`#ffffff`;intensity=1;castShadow=!1;shadowArea=75;shadowMapSize=2048;shadowFollowsCamera=!1;_createObject3D(){return new bu}_syncObject3D(){super._syncObject3D();let e=this._ensureObject3D();if(e.color.set(this.color),e.intensity=this.intensity,e.castShadow=this.castShadow,this.castShadow&&`shadow`in e){let t=e.shadow.camera;`left`in t&&(t.left=-this.shadowArea,t.right=this.shadowArea,t.top=this.shadowArea,t.bottom=-this.shadowArea,t.near=.5,t.far=500,t.updateProjectionMatrix()),e.shadow.mapSize.set(this.shadowMapSize,this.shadowMapSize),e.shadow.bias=-2e-4,e.shadow.normalBias=.002}}},Pk=class extends Oh{static typeName=`OmniLight3D`;static props={color:{default:`#ffffff`},intensity:{default:1},range:{default:0}};color=`#ffffff`;intensity=1;range=0;_createObject3D(){return new _u}_syncObject3D(){super._syncObject3D();let e=this._ensureObject3D();e.color.set(this.color),e.intensity=this.intensity,e.distance=this.range}},Fk=class extends Oh{static typeName=`LoftMesh3D`;static props={sections:{default:[]},slices:{default:24},smooth:{default:4},material:{default:{}},castShadow:{default:!1},receiveShadow:{default:!1}};sections=[];slices=24;smooth=4;material={};castShadow=!1;receiveShadow=!1;static validateJson(e){let t=e;Ik(t.sections,e.name),Ow(t.material,e.name,`LoftMesh3D`);for(let n of[`map`,`normalMap`,`repeat`])if(t.material[n]!==void 0)throw new N(`BAD_FORMAT`,`LoftMesh3D '${e.name}' material does not support '${n}' — a loft has no UVs; use color/metalness/roughness/clearcoat/envMapIntensity instead.`,{prop:`material`})}geometryKey=``;_createObject3D(){return new Ys(new J,new xl)}_syncObject3D(){super._syncObject3D();let e=this._ensureObject3D(),t=JSON.stringify([this.sections,this.slices,this.smooth]);t!==this.geometryKey&&this.sections.length>=2&&(e.geometry.dispose(),e.geometry=zk(this.sections,this.slices,this.smooth),this.geometryKey=t),Dw(e.material,this.material),e.castShadow=this.castShadow,e.receiveShadow=this.receiveShadow}};function Ik(e,t){let n=e=>{throw new N(`BAD_FORMAT`,`LoftMesh3D '${t}' ${e}`,{prop:`sections`})};(!Array.isArray(e)||e.length<2)&&n(`sections needs at least 2 stations, got ${JSON.stringify(e)}.`);for(let[t,r]of e.entries()){(typeof r!=`object`||!r)&&n(`sections[${t}] must be an object.`);for(let e of[`z`,`width`,`height`,`y`])(typeof r[e]!=`number`||!Number.isFinite(r[e]))&&n(`sections[${t}].${e} must be a finite number, got ${JSON.stringify(r[e])}.`);(r.width<=0||r.height<=0)&&n(`sections[${t}] width/height must be positive, got ${r.width}×${r.height}.`),r.corner!==void 0&&!(typeof r.corner==`number`&&r.corner>=0&&r.corner<=1)&&n(`sections[${t}].corner must be in 0..1, got ${JSON.stringify(r.corner)}.`),t>0&&r.z<=e[t-1].z&&n(`sections[].z must be strictly ascending (sections[${t}].z=${r.z}).`)}}function Lk(e,t,n,r,i){let a=i*i,o=a*i;return .5*(2*t+(n-e)*i+(2*e-5*t+4*n-r)*a+(-e+3*t-3*n+r)*o)}function Rk(e,t){let n=t=>{let n=e[Math.max(0,Math.min(e.length-1,t))];return{z:n.z,width:n.width,height:n.height,y:n.y,corner:n.corner??.7}},r=[];for(let i=0;i<e.length-1;i++){let a=n(i-1),o=n(i),s=n(i+1),c=n(i+2),l=i===e.length-2?t+1:t;for(let e=0;e<l;e++){let n=e/t;r.push({z:Lk(a.z,o.z,s.z,c.z,n),width:Math.max(1e-4,Lk(a.width,o.width,s.width,c.width,n)),height:Math.max(1e-4,Lk(a.height,o.height,s.height,c.height,n)),y:Lk(a.y,o.y,s.y,c.y,n),corner:Math.min(1,Math.max(0,Lk(a.corner,o.corner,s.corner,c.corner,n)))})}}return r}function zk(e,t,n){let r=Math.max(8,Math.min(64,Math.round(t))),i=Rk(e,Math.max(1,Math.min(16,Math.round(n)))),a=i.length,o=new Float32Array((a*r+2)*3),s=i[0],c=i[a-1];o.set([0,s.y,s.z],0),o.set([0,c.y,c.z],3);for(let e=0;e<a;e++){let t=i[e],n=8-6*t.corner,a=Math.max(n,5);for(let i=0;i<r;i++){let s=i/r*Math.PI*2,c=Math.cos(s),l=Math.sin(s),u=l>=0?n:a,d=t.width/2*Math.sign(c)*Math.abs(c)**(2/u),f=t.height/2*Math.sign(l)*Math.abs(l)**(2/u),p=(2+e*r+i)*3;o[p]=d,o[p+1]=t.y+f,o[p+2]=t.z}}let l=[],u=(e,t)=>2+e*r+t%r;for(let e=0;e<a-1;e++)for(let t=0;t<r;t++){let n=u(e,t),r=u(e,t+1),i=u(e+1,t),a=u(e+1,t+1);l.push(n,r,i,r,a,i)}for(let e=0;e<r;e++)l.push(0,u(0,e+1),u(0,e)),l.push(1,u(a-1,e),u(a-1,e+1));let d=new J;return d.setAttribute(`position`,new q(o,3)),d.setIndex(l),d.computeVertexNormals(),d}function Bk(e){let t=e.lastIndexOf(`.`);return t===-1?e:e.slice(0,t)}function Vk(e,t,n){let r=e.tracks.filter(e=>{let r=t.has(Bk(e.name));return n===`keep`?r:!r});return new Vl(`${e.name}#${n}`,e.duration,r)}function Hk(e){let t=new Set,n=e=>{t.add(e.name);for(let t of e.children)n(t)};return n(e),t}var Uk={Hips:`hips`,Spine:`spine`,Spine1:`chest`,Spine2:`upperChest`,Neck:`neck`,Head:`head`,LeftShoulder:`leftShoulder`,LeftArm:`leftUpperArm`,LeftForeArm:`leftLowerArm`,LeftHand:`leftHand`,RightShoulder:`rightShoulder`,RightArm:`rightUpperArm`,RightForeArm:`rightLowerArm`,RightHand:`rightHand`,LeftUpLeg:`leftUpperLeg`,LeftLeg:`leftLowerLeg`,LeftFoot:`leftFoot`,LeftToeBase:`leftToes`,RightUpLeg:`rightUpperLeg`,RightLeg:`rightLowerLeg`,RightFoot:`rightFoot`,RightToeBase:`rightToes`,LeftHandThumb1:`leftThumbMetacarpal`,LeftHandThumb2:`leftThumbProximal`,LeftHandThumb3:`leftThumbDistal`,LeftHandIndex1:`leftIndexProximal`,LeftHandIndex2:`leftIndexIntermediate`,LeftHandIndex3:`leftIndexDistal`,LeftHandMiddle1:`leftMiddleProximal`,LeftHandMiddle2:`leftMiddleIntermediate`,LeftHandMiddle3:`leftMiddleDistal`,LeftHandRing1:`leftRingProximal`,LeftHandRing2:`leftRingIntermediate`,LeftHandRing3:`leftRingDistal`,LeftHandPinky1:`leftLittleProximal`,LeftHandPinky2:`leftLittleIntermediate`,LeftHandPinky3:`leftLittleDistal`,RightHandThumb1:`rightThumbMetacarpal`,RightHandThumb2:`rightThumbProximal`,RightHandThumb3:`rightThumbDistal`,RightHandIndex1:`rightIndexProximal`,RightHandIndex2:`rightIndexIntermediate`,RightHandIndex3:`rightIndexDistal`,RightHandMiddle1:`rightMiddleProximal`,RightHandMiddle2:`rightMiddleIntermediate`,RightHandMiddle3:`rightMiddleDistal`,RightHandRing1:`rightRingProximal`,RightHandRing2:`rightRingIntermediate`,RightHandRing3:`rightRingDistal`,RightHandPinky1:`rightLittleProximal`,RightHandPinky2:`rightLittleIntermediate`,RightHandPinky3:`rightLittleDistal`},Wk={};for(let[e,t]of Object.entries(Uk))Wk[`mixamorig${e}`]=t,Wk[`mixamorig:${e}`]=t;function Gk(e,t,n){let r=[],i=new Set,a=new H,o=new H,s=new H,c=n.meta?.metaVersion===`0`,l=t.getObjectByName(`mixamorigHips`)??t.getObjectByName(`mixamorig:Hips`),u=n.humanoid?.getNormalizedBoneNode(`hips`),d=l&&u?Math.abs(u.getWorldPosition(new U).y)/Math.max(1e-6,Math.abs(l.getWorldPosition(new U).y)):1;for(let l of e.tracks){let e=l.name.lastIndexOf(`.`),u=l.name.slice(0,e),f=l.name.slice(e+1),p=Wk[u],m=p?n.humanoid?.getNormalizedBoneNode(p)?.name:void 0,h=t.getObjectByName(u);if(!m||!h){i.add(u);continue}if(h.getWorldQuaternion(a).invert(),h.parent?h.parent.getWorldQuaternion(o):o.identity(),l instanceof Rl&&f===`quaternion`){let e=Float32Array.from(l.values);for(let t=0;t<e.length;t+=4)s.set(e[t]??0,e[t+1]??0,e[t+2]??0,e[t+3]??1),s.premultiply(o).multiply(a),e[t]=c?-s.x:s.x,e[t+1]=s.y,e[t+2]=c?-s.z:s.z,e[t+3]=s.w;r.push(new Rl(`${m}.quaternion`,[...l.times],[...e]))}else if(l instanceof Bl&&f===`position`){let e=Float32Array.from(l.values);for(let t=0;t<e.length;t+=3)e[t]=(c?-(e[t]??0):e[t]??0)*d,e[t+1]=(e[t+1]??0)*d,e[t+2]=(c?-(e[t+2]??0):e[t+2]??0)*d;r.push(new Bl(`${m}.position`,[...l.times],[...e]))}}return{clip:new Vl(`${e.name} (VRM)`,e.duration,r),retargetedTracks:r.length,skippedBones:[...i]}}function Kk(e,t){let n=e.getClip().duration;if(!Number.isFinite(t)||t===0||n<=0)return 0;let r=t%n;return r<0?r+n:r}var qk=.2,Jk=.12,Yk=class extends Oh{static typeName=`ModelInstance3D`;static signals=[`animationFinished`];static props={...Oh.props,model:{default:``},animation:{default:``},targetHeight:{default:0},castShadow:{default:!1},animationLoop:{default:!0},animationSpeed:{default:1},animationOffset:{default:0},animationUpper:{default:``},animationUpperLoop:{default:!1},upperBodyRoot:{default:`Spine`},receiveShadow:{default:!1},tint:{default:``},metalness:{default:-1},roughness:{default:-1}};model=``;animation=``;targetHeight=0;castShadow=!1;animationLoop=!0;animationSpeed=1;animationOffset=0;animationUpper=``;animationUpperLoop=!1;upperBodyRoot=`Spine`;receiveShadow=!1;tint=``;metalness=-1;roughness=-1;store=null;entry=null;mountedRef=``;fittedHeight=-1;fitGroup=null;_mountedObject3D(){return this.fitGroup}mixer=null;appliedOffset=0;get _mixer(){return this.mixer}get _playingClip(){return this.playing}get _currentActionTime(){return this.currentAction?.time??0}playing=``;currentAction=null;playingUpper=``;upperAction=null;baseMode=`full`;maskCache=new Map;actionKeys=new WeakMap;warnedClaim=!1;tintTargets=[];tintedClones=[];appliedMods=``;nodePoses=new Map;poseNode(e,t){this.nodePoses.set(e,t),this.applyPoses()}_createObject3D(){return new _o}findBone(e){let t=this.fitGroup;if(!t||e===``)return null;let n=t.getObjectByName(e)??t.getObjectByName(`mixamorig${e}`)??t.getObjectByName(`mixamorig:${e}`);if(n)return n;let r=e.toLowerCase(),i=null;return t.traverse(e=>{!i&&e.name.toLowerCase().endsWith(r)&&(i=e)}),i}boneNames(){let e=[];return this.fitGroup?.traverse(t=>{t.isBone&&e.push(t.name)}),e}availableAnimations(){let e=this.entry?.animations.map(e=>e.name)??[],t=this.store?.animationRefs()??[];return[...e,...t]}_syncModel(e){this.store=e;let t=this._ensureObject3D();if(this.model===``){this.fitGroup&&this.unmount(t);return}let n=e.getModel(this.model);if(!(n.status!==`ready`||!n.scene)){if(this.mountedRef!==this.model){this.unmount(t);let e;if(n.isVrm){if(n.claimedBy&&n.claimedBy!==this){this.warnedClaim||(this.warnedClaim=!0,this.diagnose(`warn`,`incanto: VRM '${this.model}' is already displayed by another node — a VRM asset can back only one ModelInstance3D.`));return}n.claimedBy=this,e=n.scene}else e=cC(n.scene);let r=new _o;r.add(e),t.add(r),this.fitGroup=r,this.entry=n,this.mountedRef=this.model,this.mixer=new Wu(e),this.mixer.addEventListener(`finished`,e=>{let t=e.action,n=(t&&this.actionKeys.get(t))??this.animation;t&&t===this.upperAction&&(t.fadeOut(Jk),this.upperAction=null,this.playingUpper=``,this.animationUpper=``),this.emit(`animationFinished`,n)}),this.playing=``,this.currentAction=null,this.fittedHeight=-1,e.traverse(e=>{e.userData.incantoModelShared=!0}),this.tintTargets=[],this.tintedClones=[],this.appliedMods=``,e.traverse(e=>{let t=e;t.isMesh&&t.material&&this.tintTargets.push({mesh:t,original:t.material})})}if(this.fitGroup&&this.fittedHeight!==this.targetHeight)if(this.fittedHeight=this.targetHeight,this.targetHeight>0){let e=this.fitGroup.scale.x;this.fitGroup.scale.setScalar(1);let t=Xk(this.fitGroup).getSize(new U),n=t.y>0?this.targetHeight/t.y:e;n<.05||n>20?(this.fitGroup.scale.setScalar(1),this.diagnose(`warn`,`[incanto] ModelInstance3D '${this.name}': targetHeight fit measured an implausible scale (${n.toFixed(2)}x) — skinned rigs defeat bounding-box measurement. Rendering at the model's authored scale instead.`)):this.fitGroup.scale.setScalar(n)}else this.fitGroup.scale.setScalar(1);this.fitGroup&&this.fitGroup.traverse(e=>{let t=e;t.isMesh&&(t.castShadow=this.castShadow,t.receiveShadow=this.receiveShadow)}),this.applyMaterialMods(),this.applyPoses(),this.syncAnimation(e),this.syncUpperAnimation(e)}}applyMaterialMods(){let e=`${this.tint}|${this.metalness}|${this.roughness}`;if(e===this.appliedMods)return;for(let e of this.tintedClones)e.dispose();this.tintedClones=[];let t=this.tint?new K(this.tint):null,n=t!==null||this.metalness>=0||this.roughness>=0;for(let e of this.tintTargets){if(!n){e.mesh.material=e.original;continue}let r=e=>{let n=e.clone();if(t){let r=n,i=e.color;r.color&&=i?i.clone().multiply(t):t.clone()}let r=n;return this.metalness>=0&&typeof r.metalness==`number`&&(r.metalness=this.metalness),this.roughness>=0&&typeof r.roughness==`number`&&(r.roughness=this.roughness),n.userData.incantoTinted=!0,this.tintedClones.push(n),n};e.mesh.material=Array.isArray(e.original)?e.original.map(r):r(e.original)}this.appliedMods=e}applyPoses(){if(!this.fitGroup||this.nodePoses.size===0)return;let e=Math.PI/180;for(let[t,n]of this.nodePoses){let r=this.fitGroup.getObjectByName(t);r&&r.rotation.set(n[0]*e,n[1]*e,n[2]*e)}}resolveClip(e,t){if(!this.entry)return null;let n=this.entry.animations.find(t=>t.name===e);if(n)return n;if(!(e.startsWith(`$`)||/\.(glb|gltf)$/i.test(e)))return null;let r=t.getAnimation(e);if(r.status===`loading`)return`loading`;if(r.status!==`ready`||!r.scene)return null;let i=(r.clip?r.clips.find(e=>e.name===r.clip):void 0)??r.clips[0];if(!i)return null;if(this.entry.isVrm&&this.entry.vrm){let t=this.entry.retargeted.get(e);if(t)return t;let n=Gk(i,r.scene,this.entry.vrm);return n.skippedBones.length>0&&this.diagnose(`warn`,`incanto: retarget '${e}' skipped bones: ${n.skippedBones.join(`, `)}`),this.entry.retargeted.set(e,n.clip),n.clip}return i}layerVariants(e){let t=this.findBone(this.upperBodyRoot);if(!t)return null;let n=`${e.uuid} ${t.name}`,r=this.maskCache.get(n);if(!r){let i=Hk(t);r={upper:Vk(e,i,`keep`),lower:Vk(e,i,`drop`)},this.maskCache.set(n,r)}return r}upperLayerActive(){return this.animationUpper!==``||this.upperAction!==null}syncAnimation(e){if(!this.mixer||!this.entry)return;let t=this.upperLayerActive()?`lower`:`full`;if(this.playing===this.animation&&this.baseMode===t)return;if(this.animation===``){this.currentAction&&this.currentAction.fadeOut(qk),this.currentAction=null,this.playing=``,this.baseMode=t;return}let n=this.resolveClip(this.animation,e);if(n===`loading`)return;let r=n;if(r&&t===`lower`){let e=this.layerVariants(r);e&&(r=e.lower)}let i=this.playing===this.animation;if(this.playing=this.animation,this.baseMode=t,r){let e=this.mixer.clipAction(r);if(e.reset(),this.animationLoop?e.setLoop(hi,1/0):(e.setLoop(mi,1),e.clampWhenFinished=!0),e.setEffectiveWeight(1),e.time=Kk(e,this.animationOffset),this.appliedOffset=this.animationOffset,e.play(),this.actionKeys.set(e,this.animation),this.currentAction&&this.currentAction!==e){i&&r.duration>0&&(e.time=this.currentAction.time%r.duration);let t=r.duration>0&&this.currentAction.getClip().duration>0;e.crossFadeFrom(this.currentAction,qk,t)}this.currentAction=e}else this.diagnose(`warn`,`incanto: model '${this.model}' has no animation '${this.animation}' — embedded: ${this.entry.animations.map(e=>e.name).join(`, `)||`(none)`}; assets: ${e.animationRefs().join(`, `)||`(none)`}`)}syncUpperAnimation(e){if(!this.mixer||!this.entry||this.playingUpper===this.animationUpper)return;if(this.animationUpper===``){this.upperAction?.fadeOut(Jk),this.upperAction=null,this.playingUpper=``;return}let t=this.resolveClip(this.animationUpper,e);if(t===`loading`)return;if(!t){this.diagnose(`warn`,`incanto: model '${this.model}' has no animation '${this.animationUpper}' for the upper layer.`),this.playingUpper=this.animationUpper;return}let n=this.layerVariants(t);if(!n){this.diagnose(`warn`,`incanto: upperBodyRoot '${this.upperBodyRoot}' not found in '${this.model}' — upper layer skipped.`),this.playingUpper=this.animationUpper;return}let r=this.mixer.clipAction(n.upper);r.reset(),this.animationUpperLoop?r.setLoop(hi,1/0):(r.setLoop(mi,1),r.clampWhenFinished=!0),r.setEffectiveWeight(1),r.time=Kk(r,this.animationOffset),r.fadeIn(Jk),r.play(),this.actionKeys.set(r,this.animationUpper),this.upperAction&&this.upperAction!==r&&this.upperAction.fadeOut(Jk),this.upperAction=r,this.playingUpper=this.animationUpper}update(e){this.mixer&&this.mixer.timeScale!==this.animationSpeed&&(this.mixer.timeScale=this.animationSpeed),this.currentAction&&this.animationOffset!==this.appliedOffset&&(this.appliedOffset=this.animationOffset,this.currentAction.time=Kk(this.currentAction,this.animationOffset)),this.mixer?.update(e),this.entry?.isVrm&&this.entry.claimedBy===this&&this.entry.vrm?.update(e)}onExitTree(){this.unmount(this._ensureObject3D())}unmount(e){this.entry?.claimedBy===this&&(this.entry.claimedBy=null),this.fitGroup&&e.remove(this.fitGroup);for(let e of this.tintedClones)e.dispose();this.tintedClones=[],this.tintTargets=[],this.appliedMods=``,this.fitGroup=null,this.mixer=null,this.currentAction=null,this.upperAction=null,this.playingUpper=``,this.baseMode=`full`,this.maskCache.clear(),this.entry=null,this.mountedRef=``,this.playing=``,this.fittedHeight=-1}};function Xk(e){e.updateWorldMatrix(!0,!0);let t=new Vo,n=new Vo,r=e.matrixWorld.clone().invert(),i=new G,a=new U;return e.traverse(e=>{let o=e;if(o.isSkinnedMesh&&o.skeleton){for(let e of o.skeleton.boneInverses)i.copy(e).invert().premultiply(o.matrixWorld).premultiply(r),a.setFromMatrixPosition(i),t.expandByPoint(a);return}let s=e;s.isMesh&&s.geometry&&(s.geometry.computeBoundingBox(),s.geometry.boundingBox&&(n.copy(s.geometry.boundingBox).applyMatrix4(s.matrixWorld).applyMatrix4(r),t.union(n)))}),t}var Zk=.01,Qk=class e extends Oh{orderGroup=`effects`;static typeName=`Particles3D`;static signals=[`finished`];static props={orderGroup:{default:`effects`,options:[`background`,`terrain`,`default`,`characters`,`effects`,`overlay`]},preset:{default:`custom`,options:[`custom`,...pn]},emitting:{default:!0},rate:{default:40},burst:{default:0},lifetime:{default:[.6,1.2]},speed:{default:[40,120]},directionDeg:{default:-90},spreadDeg:{default:30},gravity:{default:[0,0]},drag:{default:0},sizeStart:{default:8},sizeEnd:{default:2},colorStart:{default:`#ffffff`},colorEnd:{default:`#ffffff`},paletteColors:{default:[]},alphaStart:{default:1},alphaEnd:{default:0},shimmer:{default:0},blend:{default:`add`,options:[`add`,`normal`]},depthTest:{default:!0},maxParticles:{default:256}};preset=`custom`;emitting=!0;rate=40;burst=0;lifetime=[.6,1.2];speed=[40,120];directionDeg=-90;spreadDeg=30;gravity=[0,0];drag=0;sizeStart=8;sizeEnd=2;colorStart=`#ffffff`;colorEnd=`#ffffff`;paletteColors=[];alphaStart=1;alphaEnd=0;shimmer=0;blend=`add`;depthTest=!0;maxParticles=256;static validateJson(e){let t=e;if(t.preset!==`custom`&&!pn.includes(t.preset))throw new N(`BAD_FORMAT`,`Particles3D '${e.name}' preset must be 'custom' or one of [${pn.join(`, `)}], got '${t.preset}'.`,{prop:`preset`,validOptions:pn});if(t.blend!==`add`&&t.blend!==`normal`)throw new N(`BAD_FORMAT`,`Particles3D '${e.name}' blend must be 'add' or 'normal', got '${t.blend}'.`,{prop:`blend`,validOptions:[`add`,`normal`]})}sim=null;bursted=!1;finishedEmitted=!1;_ensureSim(){if(!this.sim){mn(this,this.preset,qe(e.typeName));let t=this.tree?.engine?.rng??new P(4660);this.sim=new gn({rate:this.emitting?this.rate:0,lifetime:[this.lifetime[0]??1,this.lifetime[1]??1],speed:[(this.speed[0]??0)*Zk,(this.speed[1]??0)*Zk],directionDeg:this.directionDeg,spreadDeg:this.spreadDeg,gravity:[(this.gravity[0]??0)*Zk,(this.gravity[1]??0)*Zk,(this.gravity[2]??0)*Zk],drag:this.drag,maxParticles:this.maxParticles,spreadZ:!0},t)}return this.sim}update(e){let t=this._ensureSim();t.setRate(this.emitting?this.rate:0),this.burst>0&&!this.bursted&&(this.bursted=!0,t.burst(this.burst)),t.update(e),(!this.emitting||this.rate===0)&&this.bursted&&t.done&&!this.finishedEmitted&&(this.finishedEmitted=!0,this.emit(`finished`))}replay(){this.bursted=!1,this.finishedEmitted=!1}points=null;positions=null;colors=null;paletteCache=[];paletteCacheKey=``;_syncObject3D(){super._syncObject3D(),this.syncParticles()}refreshPalette(){let e=this.paletteColors;if(e.length===0)return null;let t=e.join(`|`);if(t!==this.paletteCacheKey){this.paletteCacheKey=t;for(let t=0;t<e.length;t++){let n=this.paletteCache[t];n||(n=new K,this.paletteCache[t]=n),n.set(e[t])}this.paletteCache.length=e.length}return this.paletteCache}syncParticles(){let e=this._ensureSim();if(!this.points||(this.positions?.length??0)!==this.maxParticles*3){this.points?.removeFromParent(),this.positions=new Float32Array(this.maxParticles*3),this.colors=new Float32Array(this.maxParticles*4);let e=new J;e.setAttribute(`position`,new q(this.positions,3)),e.setAttribute(`color`,new q(this.colors,4));let t=new Wc({size:(this.sizeStart+this.sizeEnd)/2*Zk,map:rA(),vertexColors:!0,transparent:!0,depthWrite:!1,depthTest:this.depthTest,alphaTest:.02,sizeAttenuation:!0,blending:this.blend===`add`?2:1});this.points=new Yc(e,t),this.points.frustumCulled=!1,this._ensureObject3D().add(this.points)}this.points.renderOrder=this.renderOrder;let t=this.points.material;t.depthTest=this.depthTest,t.blending=this.blend===`add`?2:1;let n=this.positions,r=this.colors,i=this.refreshPalette(),a=i?null:$k.set(this.colorStart),o=eA.set(this.colorEnd),s=this.shimmer,c=0;e.forEach(e=>{n[c*3]=e.x,n[c*3+1]=-e.y,n[c*3+2]=e.z;let t=i?i[Math.floor(e.seed*i.length)]:a,l=Math.max(0,this.alphaStart+(this.alphaEnd-this.alphaStart)*e.t);s>0&&(l*=.5+.5*Math.sin(2*Math.PI*(e.age*s+e.seed))),tA.copy(t).lerp(o,e.t),r[c*4]=tA.r,r[c*4+1]=tA.g,r[c*4+2]=tA.b,r[c*4+3]=l,c+=1});let l=this.points.geometry;l.setDrawRange(0,c),l.getAttribute(`position`).needsUpdate=!0,l.getAttribute(`color`).needsUpdate=!0}},$k=new K,eA=new K,tA=new K,nA=null;function rA(){if(nA)return nA;let e=63/2,t=new Uint8Array(4096*4);for(let n=0;n<64;n++)for(let r=0;r<64;r++){let i=(r-e)/e,a=(n-e)/e,o=Math.hypot(i,a),s=.35,c;if(o<=s)c=1;else{let e=Math.max(0,1-(o-s)/(1-s));c=e*e}let l=Math.round(c*255),u=(n*64+r)*4;t[u]=255,t[u+1]=255,t[u+2]=255,t[u+3]=l}let n=new lc(t,64,64,wr);return n.magFilter=or,n.minFilter=or,n.generateMipmaps=!1,n.needsUpdate=!0,nA=n,n}var iA=2.2,aA=2,oA=.52,sA=.3,cA=1.5,lA=7,uA=.004;function dA(e){if(e.path.length<2)return[];let t=TA(e.path,Math.max(e.cell,e.depth));if(t.length<2)return[];let n=t[t.length-1].along||1,r=t.map(t=>Math.max(EA(e.widths,t.along/n),.05)/2);fA(t,r);let i=t.map(t=>e.groundAt(t.x,t.z)),a=e.depth*iA,o=e.depth*lA,s=Array(t.length);for(let e=0;e<t.length;e++){let n=i[e]-a;if(e===0){s[e]=n;continue}let r=t[e].along-t[e-1].along,c=s[e-1]-r*uA;s[e]=Math.max(Math.min(n,c),i[e]-o)}let c=[];for(let n=1;n<t.length;n++){let a=t[n-1],o=t[n],l=Math.max((i[n-1]+i[n])/2-(s[n-1]+s[n])/2,0);if(l<=.001)continue;let u=Math.min(r[n-1],r[n]),d=Math.max(e.depth*aA,e.cell*cA),f=Math.max(u-d*oA,u*sA,e.cell*.5);c.push({path:[[a.x,a.z],[o.x,o.z]],width:f*2,depth:l,taper:d})}return c}function fA(e,t){let n=e.length,r=Array(n).fill(1/0),i=Array(n).fill(1/0);if(n<3)return{left:r,right:i};let a=t=>e[t].along,o=Array(n).fill(0);for(let t=1;t<n-1;t++){let n=e[t-1],r=e[t],i=e[t+1],a=r.x-n.x,s=r.z-n.z,c=i.x-r.x,l=i.z-r.z,u=Math.hypot(a,s),d=Math.hypot(c,l);if(u<1e-4||d<1e-4)continue;let f=(a*l-s*c)/(u*d);o[t]=Math.asin(Math.max(-1,Math.min(1,f)))/((u+d)/2)}let s=(e,t)=>{let r=Array(n);for(let i=0;i<n;i++){let o=0,s=0;for(let n=i;n>=0&&a(i)-a(n)<=3;n--){let r=e(n);o=t===`max`?Math.max(o,r):o+r,s++}for(let r=i+1;r<n&&a(r)-a(i)<=3;r++){let n=e(r);o=t===`max`?Math.max(o,n):o+n,s++}r[i]=t===`max`?o:o/Math.max(s,1)}return r},c=s(e=>Math.max(o[e],0),`max`),l=s(e=>Math.max(-o[e],0),`max`),u=s(e=>c[e],`mean`),d=s(e=>l[e],`mean`),f=e=>e>1e-5?Math.min(1/e*DA,OA):OA;for(let e=0;e<n;e++)r[e]=f(Math.max(u[e],c[e]*.6)),i[e]=f(Math.max(d[e],l[e]*.6));for(let e=0;e<n;e++)t[e]=Math.min(t[e],Math.max(r[e],i[e]));return{left:r,right:i}}function pA(e,t=.6){let n=[];for(let r of e){let e=Math.max(r.wettedLeft??r.halfLeft,r.wettedRight??r.halfRight),i=Math.max(r.halfLeft,r.halfRight);e-i>t&&n.push({along:r.along,wettedHalfWidth:e,carriedHalfWidth:i})}return n}var mA=24,hA=3,gA=4,_A=.05,vA=12,yA=14,bA=3,xA=5,SA=.04,CA=2;function wA(e,t){return Math.max(e*bA,e+t*xA)}function TA(e,t){let n=e.map(e=>({x:e[0]??0,z:e[1]??0})).filter((e,t,n)=>t===0||Math.hypot(e.x-(n[t-1]?.x??0),e.z-(n[t-1]?.z??0))>1e-6);if(n.length<2||t<=0)return[];let r=[],i=0;for(let e=0;e<n.length-1;e++){let t=n[Math.max(0,e-1)],a=n[e],o=n[e+1],s=n[Math.min(n.length-1,e+2)];for(let e=0;e<mA;e++){let n=e/mA,c=BA(t.x,a.x,o.x,s.x,n),l=BA(t.z,a.z,o.z,s.z,n),u=r[r.length-1];u&&(i+=Math.hypot(c-u.x,l-u.z)),r.push({x:c,z:l,along:i})}}let a=n[n.length-1],o=r[r.length-1];o&&(i+=Math.hypot(a.x-o.x,a.z-o.z)),r.push({x:a.x,z:a.z,along:i});let s=i;if(s<1e-6)return[];let c=Math.max(1,Math.round(s/t)),l=s/c,u=[],d=0;for(let e=0;e<=c;e++){let t=Math.min(e*l,s);for(;d<r.length-2&&r[d+1].along<t;)d++;let n=r[d],i=r[Math.min(d+1,r.length-1)],a=i.along-n.along,o=a>1e-9?(t-n.along)/a:0;u.push({x:n.x+(i.x-n.x)*o,z:n.z+(i.z-n.z)*o,tx:1,tz:0,along:t})}for(let e=0;e<u.length;e++){let t=u[Math.max(0,e-1)],n=u[Math.min(u.length-1,e+1)],r=n.x-t.x,i=n.z-t.z,a=Math.hypot(r,i)||1,o=u[e];o.tx=r/a,o.tz=i/a}return u}function EA(e,t){if(e.length===0)return 0;if(e.length===1)return e[0];let n=Math.min(Math.max(t,0),1)*(e.length-1),r=Math.min(Math.floor(n),e.length-2),i=n-r,a=e[r];return a+(e[r+1]-a)*i}var DA=.85,OA=1e4,kA=1.2,AA=.35,jA=.4;function MA(e,t){let n=Math.min(...e);return Math.min(Math.max(Math.min(n*.45,t*.45),.3),2.5)}function NA(e){let t=TA(e.path,e.step);if(t.length===0)return[];let n=t[t.length-1].along||1,r=t.map(t=>Math.max(EA(e.widths,t.along/n),.05)/2),i=fA(t,r),a=t.map(t=>e.bedAt(t.x,t.z)),o=Array(a.length);for(let e=0;e<a.length;e++){let t=a[e];o[e]=e===0?t:Math.min(t,o[e-1])}let s=Math.max(.5,e.depth*1.5),c=o.map((e,t)=>{let n=0,r=0;for(let i=-3;i<=hA;i++){let a=o[Math.min(Math.max(t+i,0),o.length-1)];Math.abs(a-e)>s||(n+=a,r++)}return r>0?n/r:e}),l=Array(c.length);for(let e=0;e<c.length;e++){let t=c[e];l[e]=e===0?t:Math.min(t,l[e-1])}let u=e.fit===!0,d=Array(t.length),f=Array(t.length);for(let n=0;n<t.length;n++){let i=t[n],a=l[n]+e.depth;if(!u){f[n]=[1/0,1/0],d[n]=a;continue}let o=wA(r[n],e.depth),s=-i.tz,c=i.tx,p=-1/0,m=-1/0;for(let t=1;t<=yA;t++){let n=t/yA*o;p=Math.max(p,e.bedAt(i.x+s*n,i.z+c*n)),m=Math.max(m,e.bedAt(i.x-s*n,i.z-c*n))}f[n]=[p,m],d[n]=Math.min(a,p,m)}for(let e=0;e<d.length;e++){let t=d[e];u&&(t=Math.max(t,a[e]+SA)),e>0&&(t=Math.min(t,d[e-1]));let n=f[e];t=Math.min(t,Math.max(Math.min(n[0],n[1]),a[e]+SA)),d[e]=t}let p=t.map((t,n)=>{let i=r[n];if(!u)return[i,i];let a=wA(i,e.depth),o=d[n],s=-t.tz,c=t.tx,l=n=>{for(let r=1;r<=yA;r++){let i=r/yA*a;if(e.bedAt(t.x+s*i*n,t.z+c*i*n)>=o)return i}return-i};return[l(1),l(-1)]}),m=p.map(e=>[Math.abs(e[0]),Math.abs(e[1])]);for(let e of[0,1]){for(let n=1;n<m.length;n++){let r=Math.max(t[n].along-t[n-1].along,1e-4),i=m[n-1][e],a=m[n][e];m[n][e]=Math.min(a,i+r*kA)}for(let n=m.length-2;n>=0;n--){let r=Math.max(t[n+1].along-t[n].along,1e-4),i=m[n+1][e],a=m[n][e];m[n][e]=Math.min(a,i+r*kA)}}let h=m.map((e,t)=>{let n=0,r=0,i=0;for(let e=-2;e<=CA;e++){let a=m[Math.min(Math.max(t+e,0),m.length-1)];n+=Math.abs(a[0]),r+=Math.abs(a[1]),i++}let a=m[t];return[Math.min(n/i,Math.abs(a[0])),Math.min(r/i,Math.abs(a[1]))]}),g=t.map((e,t)=>[Math.min(h[t][0],i.left[t]),Math.min(h[t][1],i.right[t])]),_=g.reduce((e,t)=>Math.max(e,t[0],t[1]),0);for(let e=0;e<t.length;e++){let n=g[e];for(let r=e+1;r<t.length;r++){let i=g[r],a=Math.max(n[0],n[1],i[0],i[1]);if(t[r].along-t[e].along<a*3)continue;let o=Math.hypot(t[e].x-t[r].x,t[e].z-t[r].z);if(!(o>_*2+AA))for(let e of[0,1]){if(o>=n[e]+i[e]+AA)continue;let t=Math.max((o-AA)/2,jA);n[e]>t&&(n[e]=t),i[e]>t&&(i[e]=t)}}}for(let e of[0,1]){for(let n=1;n<g.length;n++){let r=Math.max(t[n].along-t[n-1].along,1e-4),i=g[n-1][e],a=g[n][e];g[n][e]=Math.min(a,i+r*kA)}for(let n=g.length-2;n>=0;n--){let r=Math.max(t[n+1].along-t[n].along,1e-4),i=g[n+1][e],a=g[n][e];g[n][e]=Math.min(a,i+r*kA)}}let v=r.reduce((e,t)=>e+t,0)/r.length||1;return t.map((n,i)=>{let a=d[i],o=Math.max(0,i-1),s=Math.min(t.length-1,i+1),c=t[s].along-t[o].along,l=(d[o]-d[s])/(c||1),u=Math.max(0,l),f=r[i],m=h[i],_=Math.min(Math.max(e.flowSpeed*Math.sqrt(v/f)*(1+gA*u),_A),vA),y=p[i];return{...n,halfWidth:f,halfLeft:Math.max(g[i][0],.05),halfRight:Math.max(g[i][1],.05),wettedLeft:Math.max(m[0],.05),wettedRight:Math.max(m[1],.05),spillLeft:y[0]<0,spillRight:y[1]<0,surfaceY:a,slope:u,speed:_}})}function PA(e,t){let n=Math.max(1,Math.round(t.acrossSegments)),r=n+1,i=e.length*r,a=new Float32Array(i*3),o=new Float32Array(i*3),s=new Float32Array(i*2),c=new Float32Array(i*2),l=new Float32Array(i*4),u=Math.max(0,e.length-1)*n,d=new Uint32Array(u*6);for(let i=0;i<e.length;i++){let u=e[i],d=Math.max(u.surfaceY-FA(t,u.x,u.z),SA),f=-u.tz,p=u.tx,m=Math.hypot(u.slope,1),h=u.tx*u.slope/m,g=1/m,_=u.tz*u.slope/m;for(let e=0;e<=n;e++){let m=e/n*2-1,v=m*(m<0?u.halfRight:u.halfLeft)*t.bankOvershoot,y=u.x+f*v,b=u.z+p*v,x=i*r+e,S=FA(t,y,b),C=(m<0?u.spillRight:u.spillLeft)?d+(SA-d)*Math.abs(m):d,w=Math.min(u.surfaceY,S+C);a[x*3]=y,a[x*3+1]=w,a[x*3+2]=b,o[x*3]=h,o[x*3+1]=g,o[x*3+2]=_,s[x*2]=u.along,s[x*2+1]=v,c[x*2]=u.tx,c[x*2+1]=u.tz,l[x*4]=u.speed,l[x*4+1]=Math.max(0,w-S),l[x*4+2]=u.slope,l[x*4+3]=m*t.bankOvershoot}}let f=0;for(let t=0;t+1<e.length;t++)for(let e=0;e<n;e++){let n=t*r+e,i=n+1,a=n+r,o=a+1;d[f++]=n,d[f++]=i,d[f++]=a,d[f++]=i,d[f++]=o,d[f++]=a}return{positions:a,normals:o,uvs:s,flow:c,river:l,indices:d}}function FA(e,t,n){let r=e.bedBlur??0;return r<=0?e.bedAt(t,n):(e.bedAt(t,n)+e.bedAt(t+r,n)+e.bedAt(t-r,n)+e.bedAt(t,n+r)+e.bedAt(t,n-r))/5}function IA(e,t,n){if(e.length===0)return null;let r=0,i=1/0,a=Math.max(1,Math.floor(Math.sqrt(e.length)/2));if(a>1){for(let o=0;o<e.length;o+=a){let a=e[o],s=(a.x-t)**2+(a.z-n)**2;s<i&&(i=s,r=o)}let o=Math.max(0,r-a),s=Math.min(e.length-1,r+a);i=1/0;for(let a=o;a<=s;a++){let o=e[a],s=(o.x-t)**2+(o.z-n)**2;s<i&&(i=s,r=a)}return LA(e,r,t,n)}for(let a=0;a<e.length;a++){let o=e[a],s=(o.x-t)**2+(o.z-n)**2;s<i&&(i=s,r=a)}if(e.length===1){let r=e[0];return RA(r,r,0,t,n,!1)}return LA(e,r,t,n)}function LA(e,t,n,r){let i=null,a=1/0;for(let o of[t-1,t]){if(o<0||o+1>=e.length)continue;let t=e[o],s=e[o+1],c=s.x-t.x,l=s.z-t.z,u=c*c+l*l,d=u>1e-9?((n-t.x)*c+(r-t.z)*l)/u:0,f=Math.min(Math.max(d,0),1),p=o===0&&d<0||o+2===e.length&&d>1,m=t.x+c*f,h=t.z+l*f,g=(m-n)**2+(h-r)**2;g<a&&(a=g,i=RA(t,s,f,n,r,p))}return i}function RA(e,t,n,r,i,a){let o=e.x+(t.x-e.x)*n,s=e.z+(t.z-e.z)*n,c=e.tx+(t.tx-e.tx)*n,l=e.tz+(t.tz-e.tz)*n,u=Math.hypot(c,l)||1;c/=u,l/=u;let d=(r-o)*-l+(i-s)*c,f=(e,t)=>e+(t-e)*n,p=d<0?f(e.halfRight,t.halfRight):f(e.halfLeft,t.halfLeft),m=d/(p||1);return{inside:!a&&Math.abs(m)<=1,across:m,along:e.along+(t.along-e.along)*n,surfaceY:e.surfaceY+(t.surfaceY-e.surfaceY)*n,dirX:c,dirZ:l,speed:e.speed+(t.speed-e.speed)*n,halfWidth:p}}function zA(e,t={}){let n=t.minGrade??.45,r=t.minDrop??1.2,i=[],a=-1;for(let t=0;t<=e.length;t++){let o=t<e.length&&e[t].slope>=n;if(o&&a<0&&(a=t),o||a<0)continue;let s=e[Math.max(0,a-1)],c=e[Math.min(e.length-1,t)],l=s.surfaceY-c.surfaceY;l>=r&&i.push({x:c.x,z:c.z,lipX:s.x,lipZ:s.z,lipHalfWidth:Math.min((s.halfLeft+s.halfRight)/2,s.halfWidth),lipDirX:s.tx,lipDirZ:s.tz,lipSpeed:s.speed,topY:s.surfaceY,baseY:c.surfaceY,drop:l,halfWidth:(c.halfLeft+c.halfRight)/2,dirX:c.tx,dirZ:c.tz,speed:c.speed}),a=-1}return i}function BA(e,t,n,r,i){let a=i*i,o=a*i;return .5*(2*t+(-e+n)*i+(2*e-5*t+4*n-r)*a+(-e+3*t-3*n+r)*o)}var VA=`
|
|
7499
|
+
`)},e.customProgramCacheKey=()=>`incanto-tuft-wind`}var qO=[`grass`,`flowers`,`reeds`],JO=[`blades`,`simple`,`mesh`,`tufts`],YO=[`grass`,`fern`],XO={grass:.08,flowers:.14,reeds:.05},ZO=[.75,1.25],QO=.05,$O=.25,ek=2e5,tk=8,nk=.05,rk=.38,ik=[.75,1.3],ak=.1,ok=.42,sk=[.6,1.6],ck=.8,lk=.9,uk=.04,dk=[`#f5f1e2`,`#e9d052`,`#8d7bd9`],fk=1/3,pk=1.5,mk=1.45,hk=.4,gk=.13,_k=[.85,1.2],vk=[.8,1.3],yk=`#b3a24e`,bk=.8,xk=.5,Sk=class e extends Ah{static typeName=`Foliage3D`;static props={kind:{default:`grass`,options:qO},style:{default:`mesh`,options:JO},tuftStyle:{default:`grass`,options:YO},area:{default:[20,20]},density:{default:12},maxInstances:{default:5e4},height:{default:.25},colorA:{default:`#4d7232`},colorB:{default:`#9aab55`},groundColor:{default:`#1f3015`},sunDirection:{default:[.5,.8,.3]},fadeStart:{default:60},fadeEnd:{default:90},sway:{default:.6},interaction:{default:!0},coverage:{default:.85},flowers:{default:0},seed:{default:1},drape:{default:null},avoidWater:{default:!0},terrain:{default:``,nodePath:!0},renderOrder:{default:2}};renderOrder=2;kind=`grass`;style=`mesh`;tuftStyle=`grass`;area=[20,20];density=12;maxInstances=5e4;height=.25;colorA=`#4d7232`;colorB=`#9aab55`;groundColor=`#1f3015`;sunDirection=[.5,.8,.3];fadeStart=60;fadeEnd=90;sway=.6;interaction=!0;coverage=.85;flowers=0;seed=1;drape=null;avoidWater=!0;terrain=``;drapeTerrain=null;drapeWorld=[0,0,0];static validateJson(e){let t=e;if(!qO.includes(t.kind))throw new N(`BAD_FORMAT`,`Foliage3D '${e.name}' kind must be one of [${qO.join(`, `)}], got '${t.kind}'.`,{prop:`kind`,validOptions:qO});if(!JO.includes(t.style))throw new N(`BAD_FORMAT`,`Foliage3D '${e.name}' style must be one of [${JO.join(`, `)}], got '${t.style}'.`,{prop:`style`,validOptions:JO});if(!YO.includes(t.tuftStyle))throw new N(`BAD_FORMAT`,`Foliage3D '${e.name}' tuftStyle must be one of [${YO.join(`, `)}], got '${t.tuftStyle}'.`,{prop:`tuftStyle`,validOptions:YO});if(!((t.area[0]??0)>0)||!((t.area[1]??0)>0))throw new N(`BAD_FORMAT`,`Foliage3D '${e.name}' area must be positive [x, z] meters, got ${JSON.stringify(t.area)}.`,{prop:`area`});if(!(t.density>0)||!(t.maxInstances>=1))throw new N(`BAD_FORMAT`,`Foliage3D '${e.name}' needs density > 0 and maxInstances >= 1, got density ${t.density}, maxInstances ${t.maxInstances}.`,{prop:`density`});if(t.maxInstances>ek)throw new N(`BAD_FORMAT`,`Foliage3D '${e.name}' maxInstances is capped at ${ek} (got ${t.maxInstances}) — split giant fields into multiple nodes.`,{prop:`maxInstances`});if(!(t.fadeStart>=0)||!(t.fadeEnd>t.fadeStart))throw new N(`BAD_FORMAT`,`Foliage3D '${e.name}' needs fadeStart >= 0 and fadeEnd > fadeStart (the LOD fade window), got fadeStart ${t.fadeStart}, fadeEnd ${t.fadeEnd}.`,{prop:`fadeStart`});let n=t.sunDirection;if(!Array.isArray(n)||n.length!==3||!n.every(e=>Number.isFinite(e))||Math.hypot(n[0]??0,n[1]??0,n[2]??0)===0)throw new N(`BAD_FORMAT`,`Foliage3D '${e.name}' sunDirection must be a non-zero [x, y, z] vector, got ${JSON.stringify(n)}.`,{prop:`sunDirection`});if(!(t.coverage>0)||!(t.coverage<=1))throw new N(`BAD_FORMAT`,`Foliage3D '${e.name}' coverage must be in (0, 1] (carpet fill — 1 is solid, lower carves dirt patches), got ${t.coverage}.`,{prop:`coverage`});if(!(t.flowers>=0)||!(t.flowers<=.2))throw new N(`BAD_FORMAT`,`Foliage3D '${e.name}' flowers must be in [0, 0.2] (fraction of instances rendered as flower heads — for a whole flower FIELD use kind: 'flowers'), got ${t.flowers}.`,{prop:`flowers`});if(t.drape!==null&&typeof t.drape!=`boolean`)throw new N(`BAD_FORMAT`,`Foliage3D '${e.name}' drape must be true, false or null (null = auto: drape whenever the scene has a Terrain3D), got ${JSON.stringify(t.drape)}.`,{prop:`drape`});if(typeof t.terrain!=`string`)throw new N(`BAD_FORMAT`,`Foliage3D '${e.name}' terrain must be a node-path string (empty = auto-find), got ${JSON.stringify(t.terrain)}.`,{prop:`terrain`})}time=0;pivot=null;meshes=[];bladesMaterial=null;benderSlots=null;pickedBenders=[];fieldKey=``;tuftTime=null;tuftStrength=null;tuftTexture=null;_createObject3D(){return new _o}get isBlades(){return this.kind===`grass`&&this.style===`blades`}get isMesh(){return this.kind===`grass`&&this.style===`mesh`}get isTufts(){return this.kind===`grass`&&this.style===`tufts`}get isShaderField(){return this.isMesh||this.isBlades}_field(){return this.rebuildIfNeeded(),this.meshes[0]}_fields(){return this.rebuildIfNeeded(),this.meshes}update(e){this.time+=e,this.pickedBenders=this.computeBenders(),this.writeAnimationUniforms()}writeAnimationUniforms(){if(this.isShaderField&&this.bladesMaterial){let e=this.bladesMaterial.uniforms;e.time&&(e.time.value=this.time),e.windStrength&&(e.windStrength.value=this.sway*(this.isMesh?rk:$O));let t=this.benderSlots;if(t)for(let e=0;e<4;e++){let n=this.pickedBenders[e];n?t[e]?.set(n.x,n.y,n.z,n.radius):t[e]?.set(0,0,0,0)}}else this.isTufts&&(this.tuftTime&&(this.tuftTime.value=this.time),this.tuftStrength&&(this.tuftStrength.value=this.sway*gk))}_syncObject3D(){super._syncObject3D(),this.rebuildIfNeeded();let e=this.pivot;if(this.writeAnimationUniforms(),this.isShaderField){e.matrix.identity();let t=this.bladesMaterial.uniforms;(t.bottomColor?.value).set(this.colorA),(t.topColor?.value).set(this.colorB),this.isMesh&&((t.groundColor?.value).set(this.groundColor),(t.sunDirection?.value).set(this.sunDirection[0]??0,this.sunDirection[1]??1,this.sunDirection[2]??0).normalize(),t.fadeStart&&(t.fadeStart.value=this.fadeStart),t.fadeEnd&&(t.fadeEnd.value=this.fadeEnd))}else if(this.isTufts)e.matrix.identity();else if(this.sway>0){let t=Math.sin(this.time*1.7)*QO*this.sway,n=Math.sin(this.time*1.3+1.7)*QO*this.sway*.6;e.matrix.makeShear(0,0,t,n,0,0)}else e.matrix.identity();e.matrixWorldNeedsUpdate=!0}_applySunDirection(t){if(!this.isMesh||!this.bladesMaterial)return;let n=e.props.sunDirection?.default;this.sunDirection.every((e,t)=>e===n[t])&&(this.bladesMaterial.uniforms.sunDirection?.value)?.set(t[0],t[1],t[2])}computeBenders(){if(!this.interaction||!this.isShaderField)return[];let[e,t,n]=ZD(this);this.drape===!0&&!this.drapeTerrain&&this.resolveDrape();let r=this.drapeTerrain,i=[];for(let e of AO(this)){let n=r?r.heightAt(e.x,e.z):t,a=e.footY-n;a<=xk&&a>=-2.5&&i.push({x:e.x,y:e.y,z:e.z,radius:e.radius+bk})}return _O(i,{x:e,z:n,areaX:this.area[0]??0,areaZ:this.area[1]??0})}rebuildIfNeeded(){this.pivot||(this.pivot=new _o,this.pivot.matrixAutoUpdate=!1,this._ensureObject3D().add(this.pivot));let e=JSON.stringify([this.kind,this.style,this.tuftStyle,this.area,this.density,this.maxInstances,this.height,this.colorA,this.colorB,this.coverage,this.flowers,this.seed,this.drape,this.terrain]);if(e===this.fieldKey&&this.meshes.length>0)return;this.fieldKey=e,this.disposeMeshes(),this.resolveDrape();let t=this.isMesh?tk:this.isTufts?fk:1,n=Math.min(Math.floor((this.area[0]??0)*(this.area[1]??0)*this.density*t),this.maxInstances);this.isMesh?this.buildMeshField(n):this.isTufts?this.buildTuftField(n):this.isBlades?this.buildBladesField(n):this.buildSimpleField(n);for(let e of this.meshes)XD(e),this.pivot.add(e)}resolveDrape(){if(this.drapeTerrain=null,this.drape===!1)return;let e=QD(this,this.terrain);if(e)this.drapeTerrain=e,this.drapeWorld=ZD(this);else if(this.terrain!==``)throw new N(`NODE_NOT_FOUND`,`Foliage3D '${this.name}' drape terrain '${this.terrain}' is not a Terrain3D in the tree.`,{prop:`terrain`})}bedY(e,t){let n=this.drapeTerrain;return n?n.heightAt(this.drapeWorld[0]+e,this.drapeWorld[2]+t)-this.drapeWorld[1]:0}dryOnly(e){if(!this.avoidWater)return e;let t=tO(this);if(t.length===0)return e;let[n,,r]=ZD(this);return e.filter(e=>!nO(t,e.x+n,e.z+r,this.bedY(e.x,e.z)+this.worldY()))}worldY(){return ZD(this)[1]}buildMeshField(e){let t=jD({seed:this.seed,areaX:this.area[0]??0,areaZ:this.area[1]??0,count:e,density:this.density*tk}),n=this.dryOnly(this.coverage>=1?t:t.filter(e=>AD(e.x,e.z,this.seed)<=this.coverage)),r=this.flowers>0?Math.floor(n.length*this.flowers):0,i=new Set;for(let e=0;e<r;e++)i.add(Math.floor((e+.5)*n.length/r));let a=n.filter((e,t)=>!i.has(t)),o=n.filter((e,t)=>i.has(t));this.benderSlots=Array.from({length:4},()=>new Ra(0,0,0,0));let s=hl.merge([X.lights,X.fog]);Object.assign(s,{time:{value:0},windStrength:{value:this.sway*rk},topColor:{value:new K(this.colorB)},bottomColor:{value:new K(this.colorA)},groundColor:{value:new K(this.groundColor)},sunDirection:{value:new U(this.sunDirection[0]??0,this.sunDirection[1]??1,this.sunDirection[2]??0).normalize()},fadeStart:{value:this.fadeStart},fadeEnd:{value:this.fadeEnd},benders:{value:this.benderSlots}}),this.bladesMaterial=new vl({vertexShader:CO,fragmentShader:wO,uniforms:s,fog:!0,lights:!0,side:2});let c=yO(nk),l=a.length,u=Math.max(l,1),d=new xc(c,this.bladesMaterial,u);d.count=l,d.receiveShadow=!0;let f=new P(this.seed+5352221),p=new Float32Array(u*4),m=new Float32Array(u),h=new Float32Array(u);for(let e=0;e<l;e++){let t=a[e],n=SD(t.x,t.z),r=OD(t.x,t.z,this.seed),i=(r-.55)/1.15,o=f.range(ik[0],ik[1]),s=this.height*r*(.55+t.scale*.6);Ok.set(t.x,this.bedY(t.x,t.z),t.z),kk.setFromAxisAngle(Ek,t.rotY),Ak.set(o,s,o),d.setMatrixAt(e,Dk.compose(Ok,kk,Ak));let c=n.leanDir+f.range(-.6,.6),l=(ak+ok*(.5*n.lean+.5*f.next()))*(1+ck*i);p[e*4]=Math.cos(c)*l,p[e*4+1]=Math.sin(c)*l,p[e*4+2]=f.range(sk[0],sk[1])*(1+lk*i),p[e*4+3]=f.next(),m[e]=n.hue;let u=kD(t.x,t.z,this.seed)*.85+(f.next()-.5)*.3;h[e]=Math.min(1,Math.max(0,u))}c.setAttribute(`aBlade`,new pc(p,4)),c.setAttribute(`aClumpHue`,new pc(m,1)),c.setAttribute(`aDry`,new pc(h,1)),d.instanceMatrix.needsUpdate=!0,this.meshes=[d],o.length>0&&this.meshes.push(this.buildFlowerMesh(o))}buildFlowerMesh(e){let t=new xc(bO(uk),new bl({roughness:1,side:2}),Math.max(e.length,1));t.count=e.length,t.receiveShadow=!0;let n=new P(this.seed+15797765);for(let r=0;r<e.length;r++){let i=e[r],a=OD(i.x,i.z,this.seed),o=this.height*a*(.85+n.next()*.35);Ok.set(i.x,this.bedY(i.x,i.z),i.z),kk.setFromAxisAngle(Ek,i.rotY),Ak.set(1,o,1),t.setMatrixAt(r,Dk.compose(Ok,kk,Ak));let s=n.next(),c=dk[s<.45?0:s<.75?1:2];t.setColorAt(r,Nk.set(c))}return t.instanceMatrix.needsUpdate=!0,t.instanceColor&&(t.instanceColor.needsUpdate=!0),t}buildTuftField(e){let t=jD({seed:this.seed,areaX:this.area[0]??0,areaZ:this.area[1]??0,count:e,density:this.density*fk}),n=this.dryOnly(this.coverage>=1?t:t.filter(e=>AD(e.x,e.z,this.seed)<=this.coverage));this.tuftTime={value:this.time},this.tuftStrength={value:this.sway*gk};let r=new bl({alphaTest:.5,side:2,roughness:1}),i=IO(this.seed,this.tuftStyle);i&&(r.map=i,this.tuftTexture=i),KO(r,this.tuftTime,this.tuftStrength);let a=new xc(wk(),r,Math.max(n.length,1));a.count=n.length,a.castShadow=!1,a.receiveShadow=!0;let o=new P(this.seed+7403357),s=jk.set(this.colorA),c=Mk.set(this.colorB);for(let e=0;e<n.length;e++){let t=n[e],r=1+(OD(t.x,t.z,this.seed)-1)*hk,i=this.height*pk*r*o.range(_k[0],_k[1]),l=i*mk*o.range(vk[0],vk[1]);Ok.set(t.x,this.bedY(t.x,t.z),t.z),kk.setFromAxisAngle(Ek,t.rotY),Ak.set(l,i,l),a.setMatrixAt(e,Dk.compose(Ok,kk,Ak));let u=SD(t.x,t.z),d=Math.min(1,Math.max(0,.5+.35*u.hue+(o.next()-.5)*.3)),f=Math.min(1,Math.max(0,kD(t.x,t.z,this.seed)*.8-.1));Nk.copy(s).lerp(c,d).lerp(Pk.set(yk),f*.5).multiplyScalar(o.range(.62,1.18)),a.setColorAt(e,Nk)}a.instanceMatrix.needsUpdate=!0,a.instanceColor&&(a.instanceColor.needsUpdate=!0),this.meshes=[a]}buildBladesField(e){let t=jD({seed:this.seed,areaX:this.area[0]??0,areaZ:this.area[1]??0,count:e,density:this.density});this.benderSlots=Array.from({length:4},()=>new Ra(0,0,0,0));let n=hl.merge([X.fog]);Object.assign(n,{time:{value:0},windStrength:{value:this.sway*$O},topColor:{value:new K(this.colorB)},bottomColor:{value:new K(this.colorA)},grassHeight:{value:this.height},grassScale:{value:1},benders:{value:this.benderSlots}}),this.bladesMaterial=new vl({vertexShader:xO,fragmentShader:SO,uniforms:n,fog:!0,transparent:!0,side:2,depthWrite:!0,depthTest:!0,alphaTest:.1,blending:0});let r=Ck(this.height),i=new xc(r,this.bladesMaterial,Math.max(e,1)),a=new xc(r,this.bladesMaterial,Math.max(e,1));i.count=e,a.count=e,i.renderOrder=this.renderOrder,a.renderOrder=this.renderOrder;for(let n=0;n<e;n++){let e=t[n];Ok.set(e.x,this.bedY(e.x,e.z),e.z),Ak.setScalar(e.scale),kk.setFromAxisAngle(Ek,e.rotY),i.setMatrixAt(n,Dk.compose(Ok,kk,Ak)),kk.setFromAxisAngle(Ek,e.rotY+Math.PI/2),a.setMatrixAt(n,Dk.compose(Ok,kk,Ak))}i.instanceMatrix.needsUpdate=!0,a.instanceMatrix.needsUpdate=!0,this.meshes=[i,a]}buildSimpleField(e){let t=new bl({side:2,roughness:1}),n=new xc(Tk(XO[this.kind]??.08),t,Math.max(e,1));n.receiveShadow=!0;let r=new P(this.seed),i=(this.area[0]??0)/2,a=(this.area[1]??0)/2,o=jk.set(this.colorA),s=Mk.set(this.colorB),c=this.avoidWater?tO(this):[],[l,u,d]=ZD(this),f=0;for(let t=0;t<e;t++){let e=r.range(-i,i),t=r.range(-a,a),p=r.range(0,Math.PI*2),m=r.range(ZO[0],ZO[1]),h=r.next(),g=this.bedY(e,t);c.length>0&&nO(c,e+l,t+d,g+u)||(Ok.set(e,g,t),kk.setFromAxisAngle(Ek,p),Ak.set(1,this.height*m,1),Dk.compose(Ok,kk,Ak),n.setMatrixAt(f,Dk),n.setColorAt(f,Nk.copy(o).lerp(s,h)),f++)}n.count=f,n.instanceMatrix.needsUpdate=!0,n.instanceColor&&(n.instanceColor.needsUpdate=!0),this.meshes=[n]}disposeMeshes(){let e=new Set(this.meshes.map(e=>e.geometry)),t=new Set(this.meshes.map(e=>e.material));for(let e of this.meshes)e.removeFromParent(),e.dispose();for(let t of e)t.dispose();for(let e of t)e.dispose?.();this.bladesMaterial?.dispose(),this.bladesMaterial=null,this.benderSlots=null,this.tuftTexture?.dispose(),this.tuftTexture=null,this.tuftTime=null,this.tuftStrength=null,this.meshes=[]}free(){this.disposeMeshes(),this.pivot=null,super.free()}};function Ck(e){let t=new cl(1,e,1,1);return t.translate(0,e/2,0),t}function wk(){let e=[],t=[],n=[],r=[];for(let i=0;i<3;i++){let a=i*Math.PI/3,o=Math.cos(a)/2,s=Math.sin(a)/2,c=-Math.sin(a),l=Math.cos(a),u=i*4;e.push(-o,0,-s,o,0,s,-o,1,-s,o,1,s);for(let e=0;e<4;e++)t.push(c,0,l);n.push(0,0,1,0,0,1,1,1),r.push(u,u+1,u+3,u,u+3,u+2)}let i=new J;return i.setAttribute(`position`,new q(new Float32Array(e),3)),i.setAttribute(`normal`,new q(new Float32Array(t),3)),i.setAttribute(`uv`,new q(new Float32Array(n),2)),i.setIndex(r),i}function Tk(e){let t=e/2,n=new Float32Array([-t,0,0,t,0,0,-t,1,0,t,1,0,0,0,-t,0,0,t,0,1,-t,0,1,t]),r=new Float32Array([0,0,1,0,0,1,0,0,1,0,0,1,1,0,0,1,0,0,1,0,0,1,0,0]),i=new J;return i.setAttribute(`position`,new q(n,3)),i.setAttribute(`normal`,new q(r,3)),i.setIndex([0,1,2,2,1,3,4,5,6,6,5,7]),i}var Ek=new U(0,1,0),Dk=new G,Ok=new U,kk=new H,Ak=new U,jk=new K,Mk=new K,Nk=new K,Pk=new K,Fk=class extends Ah{static typeName=`DirectionalLight3D`;static props={color:{default:`#ffffff`},intensity:{default:1},castShadow:{default:!1},shadowArea:{default:75},shadowMapSize:{default:2048},shadowFollowsCamera:{default:!1}};color=`#ffffff`;intensity=1;castShadow=!1;shadowArea=75;shadowMapSize=2048;shadowFollowsCamera=!1;_createObject3D(){return new bu}_syncObject3D(){super._syncObject3D();let e=this._ensureObject3D();if(e.color.set(this.color),e.intensity=this.intensity,e.castShadow=this.castShadow,this.castShadow&&`shadow`in e){let t=e.shadow.camera;`left`in t&&(t.left=-this.shadowArea,t.right=this.shadowArea,t.top=this.shadowArea,t.bottom=-this.shadowArea,t.near=.5,t.far=500,t.updateProjectionMatrix()),e.shadow.mapSize.set(this.shadowMapSize,this.shadowMapSize),e.shadow.bias=-2e-4,e.shadow.normalBias=.002}}},Ik=class extends Ah{static typeName=`OmniLight3D`;static props={color:{default:`#ffffff`},intensity:{default:1},range:{default:0}};color=`#ffffff`;intensity=1;range=0;_createObject3D(){return new _u}_syncObject3D(){super._syncObject3D();let e=this._ensureObject3D();e.color.set(this.color),e.intensity=this.intensity,e.distance=this.range}},Lk=class extends Ah{static typeName=`LoftMesh3D`;static props={sections:{default:[]},slices:{default:24},smooth:{default:4},material:{default:{}},castShadow:{default:!1},receiveShadow:{default:!1}};sections=[];slices=24;smooth=4;material={};castShadow=!1;receiveShadow=!1;static validateJson(e){let t=e;Rk(t.sections,e.name),Aw(t.material,e.name,`LoftMesh3D`);for(let n of[`map`,`normalMap`,`repeat`])if(t.material[n]!==void 0)throw new N(`BAD_FORMAT`,`LoftMesh3D '${e.name}' material does not support '${n}' — a loft has no UVs; use color/metalness/roughness/clearcoat/envMapIntensity instead.`,{prop:`material`})}geometryKey=``;_createObject3D(){return new Ys(new J,new xl)}_syncObject3D(){super._syncObject3D();let e=this._ensureObject3D(),t=JSON.stringify([this.sections,this.slices,this.smooth]);t!==this.geometryKey&&this.sections.length>=2&&(e.geometry.dispose(),e.geometry=Vk(this.sections,this.slices,this.smooth),this.geometryKey=t),kw(e.material,this.material),e.castShadow=this.castShadow,e.receiveShadow=this.receiveShadow}};function Rk(e,t){let n=e=>{throw new N(`BAD_FORMAT`,`LoftMesh3D '${t}' ${e}`,{prop:`sections`})};(!Array.isArray(e)||e.length<2)&&n(`sections needs at least 2 stations, got ${JSON.stringify(e)}.`);for(let[t,r]of e.entries()){(typeof r!=`object`||!r)&&n(`sections[${t}] must be an object.`);for(let e of[`z`,`width`,`height`,`y`])(typeof r[e]!=`number`||!Number.isFinite(r[e]))&&n(`sections[${t}].${e} must be a finite number, got ${JSON.stringify(r[e])}.`);(r.width<=0||r.height<=0)&&n(`sections[${t}] width/height must be positive, got ${r.width}×${r.height}.`),r.corner!==void 0&&!(typeof r.corner==`number`&&r.corner>=0&&r.corner<=1)&&n(`sections[${t}].corner must be in 0..1, got ${JSON.stringify(r.corner)}.`),t>0&&r.z<=e[t-1].z&&n(`sections[].z must be strictly ascending (sections[${t}].z=${r.z}).`)}}function zk(e,t,n,r,i){let a=i*i,o=a*i;return .5*(2*t+(n-e)*i+(2*e-5*t+4*n-r)*a+(-e+3*t-3*n+r)*o)}function Bk(e,t){let n=t=>{let n=e[Math.max(0,Math.min(e.length-1,t))];return{z:n.z,width:n.width,height:n.height,y:n.y,corner:n.corner??.7}},r=[];for(let i=0;i<e.length-1;i++){let a=n(i-1),o=n(i),s=n(i+1),c=n(i+2),l=i===e.length-2?t+1:t;for(let e=0;e<l;e++){let n=e/t;r.push({z:zk(a.z,o.z,s.z,c.z,n),width:Math.max(1e-4,zk(a.width,o.width,s.width,c.width,n)),height:Math.max(1e-4,zk(a.height,o.height,s.height,c.height,n)),y:zk(a.y,o.y,s.y,c.y,n),corner:Math.min(1,Math.max(0,zk(a.corner,o.corner,s.corner,c.corner,n)))})}}return r}function Vk(e,t,n){let r=Math.max(8,Math.min(64,Math.round(t))),i=Bk(e,Math.max(1,Math.min(16,Math.round(n)))),a=i.length,o=new Float32Array((a*r+2)*3),s=i[0],c=i[a-1];o.set([0,s.y,s.z],0),o.set([0,c.y,c.z],3);for(let e=0;e<a;e++){let t=i[e],n=8-6*t.corner,a=Math.max(n,5);for(let i=0;i<r;i++){let s=i/r*Math.PI*2,c=Math.cos(s),l=Math.sin(s),u=l>=0?n:a,d=t.width/2*Math.sign(c)*Math.abs(c)**(2/u),f=t.height/2*Math.sign(l)*Math.abs(l)**(2/u),p=(2+e*r+i)*3;o[p]=d,o[p+1]=t.y+f,o[p+2]=t.z}}let l=[],u=(e,t)=>2+e*r+t%r;for(let e=0;e<a-1;e++)for(let t=0;t<r;t++){let n=u(e,t),r=u(e,t+1),i=u(e+1,t),a=u(e+1,t+1);l.push(n,r,i,r,a,i)}for(let e=0;e<r;e++)l.push(0,u(0,e+1),u(0,e)),l.push(1,u(a-1,e),u(a-1,e+1));let d=new J;return d.setAttribute(`position`,new q(o,3)),d.setIndex(l),d.computeVertexNormals(),d}function Hk(e){let t=e.lastIndexOf(`.`);return t===-1?e:e.slice(0,t)}function Uk(e,t,n){let r=e.tracks.filter(e=>{let r=t.has(Hk(e.name));return n===`keep`?r:!r});return new Vl(`${e.name}#${n}`,e.duration,r)}function Wk(e){let t=new Set,n=e=>{t.add(e.name);for(let t of e.children)n(t)};return n(e),t}var Gk={Hips:`hips`,Spine:`spine`,Spine1:`chest`,Spine2:`upperChest`,Neck:`neck`,Head:`head`,LeftShoulder:`leftShoulder`,LeftArm:`leftUpperArm`,LeftForeArm:`leftLowerArm`,LeftHand:`leftHand`,RightShoulder:`rightShoulder`,RightArm:`rightUpperArm`,RightForeArm:`rightLowerArm`,RightHand:`rightHand`,LeftUpLeg:`leftUpperLeg`,LeftLeg:`leftLowerLeg`,LeftFoot:`leftFoot`,LeftToeBase:`leftToes`,RightUpLeg:`rightUpperLeg`,RightLeg:`rightLowerLeg`,RightFoot:`rightFoot`,RightToeBase:`rightToes`,LeftHandThumb1:`leftThumbMetacarpal`,LeftHandThumb2:`leftThumbProximal`,LeftHandThumb3:`leftThumbDistal`,LeftHandIndex1:`leftIndexProximal`,LeftHandIndex2:`leftIndexIntermediate`,LeftHandIndex3:`leftIndexDistal`,LeftHandMiddle1:`leftMiddleProximal`,LeftHandMiddle2:`leftMiddleIntermediate`,LeftHandMiddle3:`leftMiddleDistal`,LeftHandRing1:`leftRingProximal`,LeftHandRing2:`leftRingIntermediate`,LeftHandRing3:`leftRingDistal`,LeftHandPinky1:`leftLittleProximal`,LeftHandPinky2:`leftLittleIntermediate`,LeftHandPinky3:`leftLittleDistal`,RightHandThumb1:`rightThumbMetacarpal`,RightHandThumb2:`rightThumbProximal`,RightHandThumb3:`rightThumbDistal`,RightHandIndex1:`rightIndexProximal`,RightHandIndex2:`rightIndexIntermediate`,RightHandIndex3:`rightIndexDistal`,RightHandMiddle1:`rightMiddleProximal`,RightHandMiddle2:`rightMiddleIntermediate`,RightHandMiddle3:`rightMiddleDistal`,RightHandRing1:`rightRingProximal`,RightHandRing2:`rightRingIntermediate`,RightHandRing3:`rightRingDistal`,RightHandPinky1:`rightLittleProximal`,RightHandPinky2:`rightLittleIntermediate`,RightHandPinky3:`rightLittleDistal`},Kk={};for(let[e,t]of Object.entries(Gk))Kk[`mixamorig${e}`]=t,Kk[`mixamorig:${e}`]=t;function qk(e,t,n){let r=[],i=new Set,a=new H,o=new H,s=new H,c=n.meta?.metaVersion===`0`,l=t.getObjectByName(`mixamorigHips`)??t.getObjectByName(`mixamorig:Hips`),u=n.humanoid?.getNormalizedBoneNode(`hips`),d=l&&u?Math.abs(u.getWorldPosition(new U).y)/Math.max(1e-6,Math.abs(l.getWorldPosition(new U).y)):1;for(let l of e.tracks){let e=l.name.lastIndexOf(`.`),u=l.name.slice(0,e),f=l.name.slice(e+1),p=Kk[u],m=p?n.humanoid?.getNormalizedBoneNode(p)?.name:void 0,h=t.getObjectByName(u);if(!m||!h){i.add(u);continue}if(h.getWorldQuaternion(a).invert(),h.parent?h.parent.getWorldQuaternion(o):o.identity(),l instanceof Rl&&f===`quaternion`){let e=Float32Array.from(l.values);for(let t=0;t<e.length;t+=4)s.set(e[t]??0,e[t+1]??0,e[t+2]??0,e[t+3]??1),s.premultiply(o).multiply(a),e[t]=c?-s.x:s.x,e[t+1]=s.y,e[t+2]=c?-s.z:s.z,e[t+3]=s.w;r.push(new Rl(`${m}.quaternion`,[...l.times],[...e]))}else if(l instanceof Bl&&f===`position`){let e=Float32Array.from(l.values);for(let t=0;t<e.length;t+=3)e[t]=(c?-(e[t]??0):e[t]??0)*d,e[t+1]=(e[t+1]??0)*d,e[t+2]=(c?-(e[t+2]??0):e[t+2]??0)*d;r.push(new Bl(`${m}.position`,[...l.times],[...e]))}}return{clip:new Vl(`${e.name} (VRM)`,e.duration,r),retargetedTracks:r.length,skippedBones:[...i]}}function Jk(e,t){let n=e.getClip().duration;if(!Number.isFinite(t)||t===0||n<=0)return 0;let r=t%n;return r<0?r+n:r}var Yk=.2,Xk=.12,Zk=class extends Ah{static typeName=`ModelInstance3D`;static signals=[`animationFinished`];static props={...Ah.props,model:{default:``},animation:{default:``},targetHeight:{default:0},castShadow:{default:!1},animationLoop:{default:!0},animationSpeed:{default:1},animationOffset:{default:0},animationUpper:{default:``},animationUpperLoop:{default:!1},upperBodyRoot:{default:`Spine`},receiveShadow:{default:!1},tint:{default:``},metalness:{default:-1},roughness:{default:-1}};model=``;animation=``;targetHeight=0;castShadow=!1;animationLoop=!0;animationSpeed=1;animationOffset=0;animationUpper=``;animationUpperLoop=!1;upperBodyRoot=`Spine`;receiveShadow=!1;tint=``;metalness=-1;roughness=-1;store=null;entry=null;mountedRef=``;fittedHeight=-1;fitGroup=null;_mountedObject3D(){return this.fitGroup}mixer=null;appliedOffset=0;get _mixer(){return this.mixer}get _playingClip(){return this.playing}get _currentActionTime(){return this.currentAction?.time??0}playing=``;currentAction=null;playingUpper=``;upperAction=null;baseMode=`full`;maskCache=new Map;actionKeys=new WeakMap;warnedClaim=!1;tintTargets=[];tintedClones=[];appliedMods=``;nodePoses=new Map;poseNode(e,t){this.nodePoses.set(e,t),this.applyPoses()}_createObject3D(){return new _o}findBone(e){let t=this.fitGroup;if(!t||e===``)return null;let n=t.getObjectByName(e)??t.getObjectByName(`mixamorig${e}`)??t.getObjectByName(`mixamorig:${e}`);if(n)return n;let r=e.toLowerCase(),i=null;return t.traverse(e=>{!i&&e.name.toLowerCase().endsWith(r)&&(i=e)}),i}boneNames(){let e=[];return this.fitGroup?.traverse(t=>{t.isBone&&e.push(t.name)}),e}availableAnimations(){let e=this.entry?.animations.map(e=>e.name)??[],t=this.store?.animationRefs()??[];return[...e,...t]}_syncModel(e){this.store=e;let t=this._ensureObject3D();if(this.model===``){this.fitGroup&&this.unmount(t);return}let n=e.getModel(this.model);if(!(n.status!==`ready`||!n.scene)){if(this.mountedRef!==this.model){this.unmount(t);let e;if(n.isVrm){if(n.claimedBy&&n.claimedBy!==this){this.warnedClaim||(this.warnedClaim=!0,this.diagnose(`warn`,`incanto: VRM '${this.model}' is already displayed by another node — a VRM asset can back only one ModelInstance3D.`));return}n.claimedBy=this,e=n.scene}else e=uC(n.scene);let r=new _o;r.add(e),t.add(r),this.fitGroup=r,this.entry=n,this.mountedRef=this.model,this.mixer=new Wu(e),this.mixer.addEventListener(`finished`,e=>{let t=e.action,n=(t&&this.actionKeys.get(t))??this.animation;t&&t===this.upperAction&&(t.fadeOut(Xk),this.upperAction=null,this.playingUpper=``,this.animationUpper=``),this.emit(`animationFinished`,n)}),this.playing=``,this.currentAction=null,this.fittedHeight=-1,e.traverse(e=>{e.userData.incantoModelShared=!0}),this.tintTargets=[],this.tintedClones=[],this.appliedMods=``,e.traverse(e=>{let t=e;t.isMesh&&t.material&&this.tintTargets.push({mesh:t,original:t.material})})}if(this.fitGroup&&this.fittedHeight!==this.targetHeight)if(this.fittedHeight=this.targetHeight,this.targetHeight>0){let e=this.fitGroup.scale.x;this.fitGroup.scale.setScalar(1);let t=Qk(this.fitGroup).getSize(new U),n=t.y>0?this.targetHeight/t.y:e;n<.05||n>20?(this.fitGroup.scale.setScalar(1),this.diagnose(`warn`,`[incanto] ModelInstance3D '${this.name}': targetHeight fit measured an implausible scale (${n.toFixed(2)}x) — skinned rigs defeat bounding-box measurement. Rendering at the model's authored scale instead.`)):this.fitGroup.scale.setScalar(n)}else this.fitGroup.scale.setScalar(1);this.fitGroup&&this.fitGroup.traverse(e=>{let t=e;t.isMesh&&(t.castShadow=this.castShadow,t.receiveShadow=this.receiveShadow)}),this.applyMaterialMods(),this.applyPoses(),this.syncAnimation(e),this.syncUpperAnimation(e)}}applyMaterialMods(){let e=`${this.tint}|${this.metalness}|${this.roughness}`;if(e===this.appliedMods)return;for(let e of this.tintedClones)e.dispose();this.tintedClones=[];let t=this.tint?new K(this.tint):null,n=t!==null||this.metalness>=0||this.roughness>=0;for(let e of this.tintTargets){if(!n){e.mesh.material=e.original;continue}let r=e=>{let n=e.clone();if(t){let r=n,i=e.color;r.color&&=i?i.clone().multiply(t):t.clone()}let r=n;return this.metalness>=0&&typeof r.metalness==`number`&&(r.metalness=this.metalness),this.roughness>=0&&typeof r.roughness==`number`&&(r.roughness=this.roughness),n.userData.incantoTinted=!0,this.tintedClones.push(n),n};e.mesh.material=Array.isArray(e.original)?e.original.map(r):r(e.original)}this.appliedMods=e}applyPoses(){if(!this.fitGroup||this.nodePoses.size===0)return;let e=Math.PI/180;for(let[t,n]of this.nodePoses){let r=this.fitGroup.getObjectByName(t);r&&r.rotation.set(n[0]*e,n[1]*e,n[2]*e)}}resolveClip(e,t){if(!this.entry)return null;let n=this.entry.animations.find(t=>t.name===e);if(n)return n;if(!(e.startsWith(`$`)||/\.(glb|gltf)$/i.test(e)))return null;let r=t.getAnimation(e);if(r.status===`loading`)return`loading`;if(r.status!==`ready`||!r.scene)return null;let i=(r.clip?r.clips.find(e=>e.name===r.clip):void 0)??r.clips[0];if(!i)return null;if(this.entry.isVrm&&this.entry.vrm){let t=this.entry.retargeted.get(e);if(t)return t;let n=qk(i,r.scene,this.entry.vrm);return n.skippedBones.length>0&&this.diagnose(`warn`,`incanto: retarget '${e}' skipped bones: ${n.skippedBones.join(`, `)}`),this.entry.retargeted.set(e,n.clip),n.clip}return i}layerVariants(e){let t=this.findBone(this.upperBodyRoot);if(!t)return null;let n=`${e.uuid} ${t.name}`,r=this.maskCache.get(n);if(!r){let i=Wk(t);r={upper:Uk(e,i,`keep`),lower:Uk(e,i,`drop`)},this.maskCache.set(n,r)}return r}upperLayerActive(){return this.animationUpper!==``||this.upperAction!==null}syncAnimation(e){if(!this.mixer||!this.entry)return;let t=this.upperLayerActive()?`lower`:`full`;if(this.playing===this.animation&&this.baseMode===t)return;if(this.animation===``){this.currentAction&&this.currentAction.fadeOut(Yk),this.currentAction=null,this.playing=``,this.baseMode=t;return}let n=this.resolveClip(this.animation,e);if(n===`loading`)return;let r=n;if(r&&t===`lower`){let e=this.layerVariants(r);e&&(r=e.lower)}let i=this.playing===this.animation;if(this.playing=this.animation,this.baseMode=t,r){let e=this.mixer.clipAction(r);if(e.reset(),this.animationLoop?e.setLoop(hi,1/0):(e.setLoop(mi,1),e.clampWhenFinished=!0),e.setEffectiveWeight(1),e.time=Jk(e,this.animationOffset),this.appliedOffset=this.animationOffset,e.play(),this.actionKeys.set(e,this.animation),this.currentAction&&this.currentAction!==e){i&&r.duration>0&&(e.time=this.currentAction.time%r.duration);let t=r.duration>0&&this.currentAction.getClip().duration>0;e.crossFadeFrom(this.currentAction,Yk,t)}this.currentAction=e}else this.diagnose(`warn`,`incanto: model '${this.model}' has no animation '${this.animation}' — embedded: ${this.entry.animations.map(e=>e.name).join(`, `)||`(none)`}; assets: ${e.animationRefs().join(`, `)||`(none)`}`)}syncUpperAnimation(e){if(!this.mixer||!this.entry||this.playingUpper===this.animationUpper)return;if(this.animationUpper===``){this.upperAction?.fadeOut(Xk),this.upperAction=null,this.playingUpper=``;return}let t=this.resolveClip(this.animationUpper,e);if(t===`loading`)return;if(!t){this.diagnose(`warn`,`incanto: model '${this.model}' has no animation '${this.animationUpper}' for the upper layer.`),this.playingUpper=this.animationUpper;return}let n=this.layerVariants(t);if(!n){this.diagnose(`warn`,`incanto: upperBodyRoot '${this.upperBodyRoot}' not found in '${this.model}' — upper layer skipped.`),this.playingUpper=this.animationUpper;return}let r=this.mixer.clipAction(n.upper);r.reset(),this.animationUpperLoop?r.setLoop(hi,1/0):(r.setLoop(mi,1),r.clampWhenFinished=!0),r.setEffectiveWeight(1),r.time=Jk(r,this.animationOffset),r.fadeIn(Xk),r.play(),this.actionKeys.set(r,this.animationUpper),this.upperAction&&this.upperAction!==r&&this.upperAction.fadeOut(Xk),this.upperAction=r,this.playingUpper=this.animationUpper}update(e){this.mixer&&this.mixer.timeScale!==this.animationSpeed&&(this.mixer.timeScale=this.animationSpeed),this.currentAction&&this.animationOffset!==this.appliedOffset&&(this.appliedOffset=this.animationOffset,this.currentAction.time=Jk(this.currentAction,this.animationOffset)),this.mixer?.update(e),this.entry?.isVrm&&this.entry.claimedBy===this&&this.entry.vrm?.update(e)}onExitTree(){this.unmount(this._ensureObject3D())}unmount(e){this.entry?.claimedBy===this&&(this.entry.claimedBy=null),this.fitGroup&&e.remove(this.fitGroup);for(let e of this.tintedClones)e.dispose();this.tintedClones=[],this.tintTargets=[],this.appliedMods=``,this.fitGroup=null,this.mixer=null,this.currentAction=null,this.upperAction=null,this.playingUpper=``,this.baseMode=`full`,this.maskCache.clear(),this.entry=null,this.mountedRef=``,this.playing=``,this.fittedHeight=-1}};function Qk(e){e.updateWorldMatrix(!0,!0);let t=new Vo,n=new Vo,r=e.matrixWorld.clone().invert(),i=new G,a=new U;return e.traverse(e=>{let o=e;if(o.isSkinnedMesh&&o.skeleton){for(let e of o.skeleton.boneInverses)i.copy(e).invert().premultiply(o.matrixWorld).premultiply(r),a.setFromMatrixPosition(i),t.expandByPoint(a);return}let s=e;s.isMesh&&s.geometry&&(s.geometry.computeBoundingBox(),s.geometry.boundingBox&&(n.copy(s.geometry.boundingBox).applyMatrix4(s.matrixWorld).applyMatrix4(r),t.union(n)))}),t}var $k=.01,eA=class e extends Ah{orderGroup=`effects`;static typeName=`Particles3D`;static signals=[`finished`];static props={orderGroup:{default:`effects`,options:[`background`,`terrain`,`default`,`characters`,`effects`,`overlay`]},preset:{default:`custom`,options:[`custom`,...pn]},emitting:{default:!0},rate:{default:40},burst:{default:0},lifetime:{default:[.6,1.2]},speed:{default:[40,120]},directionDeg:{default:-90},spreadDeg:{default:30},gravity:{default:[0,0]},drag:{default:0},sizeStart:{default:8},sizeEnd:{default:2},colorStart:{default:`#ffffff`},colorEnd:{default:`#ffffff`},paletteColors:{default:[]},alphaStart:{default:1},alphaEnd:{default:0},shimmer:{default:0},blend:{default:`add`,options:[`add`,`normal`]},depthTest:{default:!0},maxParticles:{default:256}};preset=`custom`;emitting=!0;rate=40;burst=0;lifetime=[.6,1.2];speed=[40,120];directionDeg=-90;spreadDeg=30;gravity=[0,0];drag=0;sizeStart=8;sizeEnd=2;colorStart=`#ffffff`;colorEnd=`#ffffff`;paletteColors=[];alphaStart=1;alphaEnd=0;shimmer=0;blend=`add`;depthTest=!0;maxParticles=256;static validateJson(e){let t=e;if(t.preset!==`custom`&&!pn.includes(t.preset))throw new N(`BAD_FORMAT`,`Particles3D '${e.name}' preset must be 'custom' or one of [${pn.join(`, `)}], got '${t.preset}'.`,{prop:`preset`,validOptions:pn});if(t.blend!==`add`&&t.blend!==`normal`)throw new N(`BAD_FORMAT`,`Particles3D '${e.name}' blend must be 'add' or 'normal', got '${t.blend}'.`,{prop:`blend`,validOptions:[`add`,`normal`]})}sim=null;bursted=!1;finishedEmitted=!1;_ensureSim(){if(!this.sim){mn(this,this.preset,qe(e.typeName));let t=this.tree?.engine?.rng??new P(4660);this.sim=new gn({rate:this.emitting?this.rate:0,lifetime:[this.lifetime[0]??1,this.lifetime[1]??1],speed:[(this.speed[0]??0)*$k,(this.speed[1]??0)*$k],directionDeg:this.directionDeg,spreadDeg:this.spreadDeg,gravity:[(this.gravity[0]??0)*$k,(this.gravity[1]??0)*$k,(this.gravity[2]??0)*$k],drag:this.drag,maxParticles:this.maxParticles,spreadZ:!0},t)}return this.sim}update(e){let t=this._ensureSim();t.setRate(this.emitting?this.rate:0),this.burst>0&&!this.bursted&&(this.bursted=!0,t.burst(this.burst)),t.update(e),(!this.emitting||this.rate===0)&&this.bursted&&t.done&&!this.finishedEmitted&&(this.finishedEmitted=!0,this.emit(`finished`))}replay(){this.bursted=!1,this.finishedEmitted=!1}points=null;positions=null;colors=null;paletteCache=[];paletteCacheKey=``;_syncObject3D(){super._syncObject3D(),this.syncParticles()}refreshPalette(){let e=this.paletteColors;if(e.length===0)return null;let t=e.join(`|`);if(t!==this.paletteCacheKey){this.paletteCacheKey=t;for(let t=0;t<e.length;t++){let n=this.paletteCache[t];n||(n=new K,this.paletteCache[t]=n),n.set(e[t])}this.paletteCache.length=e.length}return this.paletteCache}syncParticles(){let e=this._ensureSim();if(!this.points||(this.positions?.length??0)!==this.maxParticles*3){this.points?.removeFromParent(),this.positions=new Float32Array(this.maxParticles*3),this.colors=new Float32Array(this.maxParticles*4);let e=new J;e.setAttribute(`position`,new q(this.positions,3)),e.setAttribute(`color`,new q(this.colors,4));let t=new Wc({size:(this.sizeStart+this.sizeEnd)/2*$k,map:aA(),vertexColors:!0,transparent:!0,depthWrite:!1,depthTest:this.depthTest,alphaTest:.02,sizeAttenuation:!0,blending:this.blend===`add`?2:1});this.points=new Yc(e,t),this.points.frustumCulled=!1,this._ensureObject3D().add(this.points)}this.points.renderOrder=this.renderOrder;let t=this.points.material;t.depthTest=this.depthTest,t.blending=this.blend===`add`?2:1;let n=this.positions,r=this.colors,i=this.refreshPalette(),a=i?null:tA.set(this.colorStart),o=nA.set(this.colorEnd),s=this.shimmer,c=0;e.forEach(e=>{n[c*3]=e.x,n[c*3+1]=-e.y,n[c*3+2]=e.z;let t=i?i[Math.floor(e.seed*i.length)]:a,l=Math.max(0,this.alphaStart+(this.alphaEnd-this.alphaStart)*e.t);s>0&&(l*=.5+.5*Math.sin(2*Math.PI*(e.age*s+e.seed))),rA.copy(t).lerp(o,e.t),r[c*4]=rA.r,r[c*4+1]=rA.g,r[c*4+2]=rA.b,r[c*4+3]=l,c+=1});let l=this.points.geometry;l.setDrawRange(0,c),l.getAttribute(`position`).needsUpdate=!0,l.getAttribute(`color`).needsUpdate=!0}},tA=new K,nA=new K,rA=new K,iA=null;function aA(){if(iA)return iA;let e=63/2,t=new Uint8Array(4096*4);for(let n=0;n<64;n++)for(let r=0;r<64;r++){let i=(r-e)/e,a=(n-e)/e,o=Math.hypot(i,a),s=.35,c;if(o<=s)c=1;else{let e=Math.max(0,1-(o-s)/(1-s));c=e*e}let l=Math.round(c*255),u=(n*64+r)*4;t[u]=255,t[u+1]=255,t[u+2]=255,t[u+3]=l}let n=new lc(t,64,64,wr);return n.magFilter=or,n.minFilter=or,n.generateMipmaps=!1,n.needsUpdate=!0,iA=n,n}var oA=2.2,sA=2,cA=.52,lA=.3,uA=1.5,dA=7,fA=.004;function pA(e){if(e.path.length<2)return[];let t=DA(e.path,Math.max(e.cell,e.depth));if(t.length<2)return[];let n=t[t.length-1].along||1,r=t.map(t=>Math.max(OA(e.widths,t.along/n),.05)/2);mA(t,r);let i=t.map(t=>e.groundAt(t.x,t.z)),a=e.depth*oA,o=e.depth*dA,s=Array(t.length);for(let e=0;e<t.length;e++){let n=i[e]-a;if(e===0){s[e]=n;continue}let r=t[e].along-t[e-1].along,c=s[e-1]-r*fA;s[e]=Math.max(Math.min(n,c),i[e]-o)}let c=[];for(let n=1;n<t.length;n++){let a=t[n-1],o=t[n],l=Math.max((i[n-1]+i[n])/2-(s[n-1]+s[n])/2,0);if(l<=.001)continue;let u=Math.min(r[n-1],r[n]),d=Math.max(e.depth*sA,e.cell*uA),f=Math.max(u-d*cA,u*lA,e.cell*.5);c.push({path:[[a.x,a.z],[o.x,o.z]],width:f*2,depth:l,taper:d})}return c}function mA(e,t){let n=e.length,r=Array(n).fill(1/0),i=Array(n).fill(1/0);if(n<3)return{left:r,right:i};let a=t=>e[t].along,o=Array(n).fill(0);for(let t=1;t<n-1;t++){let n=e[t-1],r=e[t],i=e[t+1],a=r.x-n.x,s=r.z-n.z,c=i.x-r.x,l=i.z-r.z,u=Math.hypot(a,s),d=Math.hypot(c,l);if(u<1e-4||d<1e-4)continue;let f=(a*l-s*c)/(u*d);o[t]=Math.asin(Math.max(-1,Math.min(1,f)))/((u+d)/2)}let s=(e,t)=>{let r=Array(n);for(let i=0;i<n;i++){let o=0,s=0;for(let n=i;n>=0&&a(i)-a(n)<=3;n--){let r=e(n);o=t===`max`?Math.max(o,r):o+r,s++}for(let r=i+1;r<n&&a(r)-a(i)<=3;r++){let n=e(r);o=t===`max`?Math.max(o,n):o+n,s++}r[i]=t===`max`?o:o/Math.max(s,1)}return r},c=s(e=>Math.max(o[e],0),`max`),l=s(e=>Math.max(-o[e],0),`max`),u=s(e=>c[e],`mean`),d=s(e=>l[e],`mean`),f=e=>e>1e-5?Math.min(1/e*kA,AA):AA;for(let e=0;e<n;e++)r[e]=f(Math.max(u[e],c[e]*.6)),i[e]=f(Math.max(d[e],l[e]*.6));for(let e=0;e<n;e++)t[e]=Math.min(t[e],Math.max(r[e],i[e]));return{left:r,right:i}}function hA(e,t=.6){let n=[];for(let r of e){let e=Math.max(r.wettedLeft??r.halfLeft,r.wettedRight??r.halfRight),i=Math.max(r.halfLeft,r.halfRight);e-i>t&&n.push({along:r.along,wettedHalfWidth:e,carriedHalfWidth:i})}return n}var gA=24,_A=3,vA=4,yA=.05,bA=12,xA=14,SA=3,CA=5,wA=.04,TA=2;function EA(e,t){return Math.max(e*SA,e+t*CA)}function DA(e,t){let n=e.map(e=>({x:e[0]??0,z:e[1]??0})).filter((e,t,n)=>t===0||Math.hypot(e.x-(n[t-1]?.x??0),e.z-(n[t-1]?.z??0))>1e-6);if(n.length<2||t<=0)return[];let r=[],i=0;for(let e=0;e<n.length-1;e++){let t=n[Math.max(0,e-1)],a=n[e],o=n[e+1],s=n[Math.min(n.length-1,e+2)];for(let e=0;e<gA;e++){let n=e/gA,c=HA(t.x,a.x,o.x,s.x,n),l=HA(t.z,a.z,o.z,s.z,n),u=r[r.length-1];u&&(i+=Math.hypot(c-u.x,l-u.z)),r.push({x:c,z:l,along:i})}}let a=n[n.length-1],o=r[r.length-1];o&&(i+=Math.hypot(a.x-o.x,a.z-o.z)),r.push({x:a.x,z:a.z,along:i});let s=i;if(s<1e-6)return[];let c=Math.max(1,Math.round(s/t)),l=s/c,u=[],d=0;for(let e=0;e<=c;e++){let t=Math.min(e*l,s);for(;d<r.length-2&&r[d+1].along<t;)d++;let n=r[d],i=r[Math.min(d+1,r.length-1)],a=i.along-n.along,o=a>1e-9?(t-n.along)/a:0;u.push({x:n.x+(i.x-n.x)*o,z:n.z+(i.z-n.z)*o,tx:1,tz:0,along:t})}for(let e=0;e<u.length;e++){let t=u[Math.max(0,e-1)],n=u[Math.min(u.length-1,e+1)],r=n.x-t.x,i=n.z-t.z,a=Math.hypot(r,i)||1,o=u[e];o.tx=r/a,o.tz=i/a}return u}function OA(e,t){if(e.length===0)return 0;if(e.length===1)return e[0];let n=Math.min(Math.max(t,0),1)*(e.length-1),r=Math.min(Math.floor(n),e.length-2),i=n-r,a=e[r];return a+(e[r+1]-a)*i}var kA=.85,AA=1e4,jA=1.2,MA=.35,NA=.4;function PA(e,t){let n=Math.min(...e);return Math.min(Math.max(Math.min(n*.45,t*.45),.3),2.5)}function FA(e){let t=DA(e.path,e.step);if(t.length===0)return[];let n=t[t.length-1].along||1,r=t.map(t=>Math.max(OA(e.widths,t.along/n),.05)/2),i=mA(t,r),a=t.map(t=>e.bedAt(t.x,t.z)),o=Array(a.length);for(let e=0;e<a.length;e++){let t=a[e];o[e]=e===0?t:Math.min(t,o[e-1])}let s=Math.max(.5,e.depth*1.5),c=o.map((e,t)=>{let n=0,r=0;for(let i=-3;i<=_A;i++){let a=o[Math.min(Math.max(t+i,0),o.length-1)];Math.abs(a-e)>s||(n+=a,r++)}return r>0?n/r:e}),l=Array(c.length);for(let e=0;e<c.length;e++){let t=c[e];l[e]=e===0?t:Math.min(t,l[e-1])}let u=e.fit===!0,d=Array(t.length),f=Array(t.length);for(let n=0;n<t.length;n++){let i=t[n],a=l[n]+e.depth;if(!u){f[n]=[1/0,1/0],d[n]=a;continue}let o=EA(r[n],e.depth),s=-i.tz,c=i.tx,p=-1/0,m=-1/0;for(let t=1;t<=xA;t++){let n=t/xA*o;p=Math.max(p,e.bedAt(i.x+s*n,i.z+c*n)),m=Math.max(m,e.bedAt(i.x-s*n,i.z-c*n))}f[n]=[p,m],d[n]=Math.min(a,p,m)}for(let e=0;e<d.length;e++){let t=d[e];u&&(t=Math.max(t,a[e]+wA)),e>0&&(t=Math.min(t,d[e-1]));let n=f[e];t=Math.min(t,Math.max(Math.min(n[0],n[1]),a[e]+wA)),d[e]=t}let p=t.map((t,n)=>{let i=r[n];if(!u)return[i,i];let a=EA(i,e.depth),o=d[n],s=-t.tz,c=t.tx,l=n=>{for(let r=1;r<=xA;r++){let i=r/xA*a;if(e.bedAt(t.x+s*i*n,t.z+c*i*n)>=o)return i}return-i};return[l(1),l(-1)]}),m=p.map(e=>[Math.abs(e[0]),Math.abs(e[1])]);for(let e of[0,1]){for(let n=1;n<m.length;n++){let r=Math.max(t[n].along-t[n-1].along,1e-4),i=m[n-1][e],a=m[n][e];m[n][e]=Math.min(a,i+r*jA)}for(let n=m.length-2;n>=0;n--){let r=Math.max(t[n+1].along-t[n].along,1e-4),i=m[n+1][e],a=m[n][e];m[n][e]=Math.min(a,i+r*jA)}}let h=m.map((e,t)=>{let n=0,r=0,i=0;for(let e=-2;e<=TA;e++){let a=m[Math.min(Math.max(t+e,0),m.length-1)];n+=Math.abs(a[0]),r+=Math.abs(a[1]),i++}let a=m[t];return[Math.min(n/i,Math.abs(a[0])),Math.min(r/i,Math.abs(a[1]))]}),g=t.map((e,t)=>[Math.min(h[t][0],i.left[t]),Math.min(h[t][1],i.right[t])]),_=g.reduce((e,t)=>Math.max(e,t[0],t[1]),0);for(let e=0;e<t.length;e++){let n=g[e];for(let r=e+1;r<t.length;r++){let i=g[r],a=Math.max(n[0],n[1],i[0],i[1]);if(t[r].along-t[e].along<a*3)continue;let o=Math.hypot(t[e].x-t[r].x,t[e].z-t[r].z);if(!(o>_*2+MA))for(let e of[0,1]){if(o>=n[e]+i[e]+MA)continue;let t=Math.max((o-MA)/2,NA);n[e]>t&&(n[e]=t),i[e]>t&&(i[e]=t)}}}for(let e of[0,1]){for(let n=1;n<g.length;n++){let r=Math.max(t[n].along-t[n-1].along,1e-4),i=g[n-1][e],a=g[n][e];g[n][e]=Math.min(a,i+r*jA)}for(let n=g.length-2;n>=0;n--){let r=Math.max(t[n+1].along-t[n].along,1e-4),i=g[n+1][e],a=g[n][e];g[n][e]=Math.min(a,i+r*jA)}}let v=r.reduce((e,t)=>e+t,0)/r.length||1;return t.map((n,i)=>{let a=d[i],o=Math.max(0,i-1),s=Math.min(t.length-1,i+1),c=t[s].along-t[o].along,l=(d[o]-d[s])/(c||1),u=Math.max(0,l),f=r[i],m=h[i],_=Math.min(Math.max(e.flowSpeed*Math.sqrt(v/f)*(1+vA*u),yA),bA),y=p[i];return{...n,halfWidth:f,halfLeft:Math.max(g[i][0],.05),halfRight:Math.max(g[i][1],.05),wettedLeft:Math.max(m[0],.05),wettedRight:Math.max(m[1],.05),spillLeft:y[0]<0,spillRight:y[1]<0,surfaceY:a,slope:u,speed:_}})}function IA(e,t){let n=Math.max(1,Math.round(t.acrossSegments)),r=n+1,i=e.length*r,a=new Float32Array(i*3),o=new Float32Array(i*3),s=new Float32Array(i*2),c=new Float32Array(i*2),l=new Float32Array(i*4),u=Math.max(0,e.length-1)*n,d=new Uint32Array(u*6);for(let i=0;i<e.length;i++){let u=e[i],d=Math.max(u.surfaceY-LA(t,u.x,u.z),wA),f=-u.tz,p=u.tx,m=Math.hypot(u.slope,1),h=u.tx*u.slope/m,g=1/m,_=u.tz*u.slope/m;for(let e=0;e<=n;e++){let m=e/n*2-1,v=m*(m<0?u.halfRight:u.halfLeft)*t.bankOvershoot,y=u.x+f*v,b=u.z+p*v,x=i*r+e,S=LA(t,y,b),C=(m<0?u.spillRight:u.spillLeft)?d+(wA-d)*Math.abs(m):d,w=Math.min(u.surfaceY,S+C);a[x*3]=y,a[x*3+1]=w,a[x*3+2]=b,o[x*3]=h,o[x*3+1]=g,o[x*3+2]=_,s[x*2]=u.along,s[x*2+1]=v,c[x*2]=u.tx,c[x*2+1]=u.tz,l[x*4]=u.speed,l[x*4+1]=Math.max(0,w-S),l[x*4+2]=u.slope,l[x*4+3]=m*t.bankOvershoot}}let f=0;for(let t=0;t+1<e.length;t++)for(let e=0;e<n;e++){let n=t*r+e,i=n+1,a=n+r,o=a+1;d[f++]=n,d[f++]=i,d[f++]=a,d[f++]=i,d[f++]=o,d[f++]=a}return{positions:a,normals:o,uvs:s,flow:c,river:l,indices:d}}function LA(e,t,n){let r=e.bedBlur??0;return r<=0?e.bedAt(t,n):(e.bedAt(t,n)+e.bedAt(t+r,n)+e.bedAt(t-r,n)+e.bedAt(t,n+r)+e.bedAt(t,n-r))/5}function RA(e,t,n){if(e.length===0)return null;let r=0,i=1/0,a=Math.max(1,Math.floor(Math.sqrt(e.length)/2));if(a>1){for(let o=0;o<e.length;o+=a){let a=e[o],s=(a.x-t)**2+(a.z-n)**2;s<i&&(i=s,r=o)}let o=Math.max(0,r-a),s=Math.min(e.length-1,r+a);i=1/0;for(let a=o;a<=s;a++){let o=e[a],s=(o.x-t)**2+(o.z-n)**2;s<i&&(i=s,r=a)}return zA(e,r,t,n)}for(let a=0;a<e.length;a++){let o=e[a],s=(o.x-t)**2+(o.z-n)**2;s<i&&(i=s,r=a)}if(e.length===1){let r=e[0];return BA(r,r,0,t,n,!1)}return zA(e,r,t,n)}function zA(e,t,n,r){let i=null,a=1/0;for(let o of[t-1,t]){if(o<0||o+1>=e.length)continue;let t=e[o],s=e[o+1],c=s.x-t.x,l=s.z-t.z,u=c*c+l*l,d=u>1e-9?((n-t.x)*c+(r-t.z)*l)/u:0,f=Math.min(Math.max(d,0),1),p=o===0&&d<0||o+2===e.length&&d>1,m=t.x+c*f,h=t.z+l*f,g=(m-n)**2+(h-r)**2;g<a&&(a=g,i=BA(t,s,f,n,r,p))}return i}function BA(e,t,n,r,i,a){let o=e.x+(t.x-e.x)*n,s=e.z+(t.z-e.z)*n,c=e.tx+(t.tx-e.tx)*n,l=e.tz+(t.tz-e.tz)*n,u=Math.hypot(c,l)||1;c/=u,l/=u;let d=(r-o)*-l+(i-s)*c,f=(e,t)=>e+(t-e)*n,p=d<0?f(e.halfRight,t.halfRight):f(e.halfLeft,t.halfLeft),m=d/(p||1);return{inside:!a&&Math.abs(m)<=1,across:m,along:e.along+(t.along-e.along)*n,surfaceY:e.surfaceY+(t.surfaceY-e.surfaceY)*n,dirX:c,dirZ:l,speed:e.speed+(t.speed-e.speed)*n,halfWidth:p}}function VA(e,t={}){let n=t.minGrade??.45,r=t.minDrop??1.2,i=[],a=-1;for(let t=0;t<=e.length;t++){let o=t<e.length&&e[t].slope>=n;if(o&&a<0&&(a=t),o||a<0)continue;let s=e[Math.max(0,a-1)],c=e[Math.min(e.length-1,t)],l=s.surfaceY-c.surfaceY;l>=r&&i.push({x:c.x,z:c.z,lipX:s.x,lipZ:s.z,lipHalfWidth:Math.min((s.halfLeft+s.halfRight)/2,s.halfWidth),lipDirX:s.tx,lipDirZ:s.tz,lipSpeed:s.speed,topY:s.surfaceY,baseY:c.surfaceY,drop:l,halfWidth:(c.halfLeft+c.halfRight)/2,dirX:c.tx,dirZ:c.tz,speed:c.speed}),a=-1}return i}function HA(e,t,n,r,i){let a=i*i,o=a*i;return .5*(2*t+(-e+n)*i+(2*e-5*t+4*n-r)*a+(-e+3*t-3*n+r)*o)}var UA=`
|
|
7500
7500
|
float riverHash(vec2 p) {
|
|
7501
7501
|
p = fract(p * vec2(127.31, 311.7));
|
|
7502
7502
|
p += dot(p, p + 34.23);
|
|
@@ -7513,7 +7513,7 @@ float riverNoise(vec2 p) {
|
|
|
7513
7513
|
float d = riverHash(i + vec2(1.0, 1.0));
|
|
7514
7514
|
return mix(mix(a, b, u.x), mix(c, d, u.x), u.y);
|
|
7515
7515
|
}
|
|
7516
|
-
`,
|
|
7516
|
+
`,WA=`
|
|
7517
7517
|
precision highp float;
|
|
7518
7518
|
|
|
7519
7519
|
#include <fog_pars_vertex>
|
|
@@ -7574,7 +7574,7 @@ void main() {
|
|
|
7574
7574
|
|
|
7575
7575
|
#include <fog_vertex>
|
|
7576
7576
|
}
|
|
7577
|
-
`,
|
|
7577
|
+
`,GA=`
|
|
7578
7578
|
precision highp float;
|
|
7579
7579
|
|
|
7580
7580
|
#include <fog_pars_fragment>
|
|
@@ -7614,7 +7614,7 @@ varying vec2 vFlowUv;
|
|
|
7614
7614
|
varying vec2 vFlow;
|
|
7615
7615
|
varying vec4 vRiver;
|
|
7616
7616
|
|
|
7617
|
-
${
|
|
7617
|
+
${UA}
|
|
7618
7618
|
|
|
7619
7619
|
/**
|
|
7620
7620
|
* Ripple field in flow space: (height, d/d-downstream, d/d-across).
|
|
@@ -7894,7 +7894,7 @@ void main() {
|
|
|
7894
7894
|
#include <colorspace_fragment>
|
|
7895
7895
|
#include <fog_fragment>
|
|
7896
7896
|
}
|
|
7897
|
-
`,WA=1.25,GA=4,KA=12,qA=1.5,JA=.35,YA=1.2,XA=8,ZA=.5,QA=.35,$A=42,ej=26,tj=6,nj=.05,rj=1.5,ij={shallow:`#74b2a2`,deep:`#123f4b`,sky:`#8ab6d8`,horizon:`#9fb6c2`,bank:`#465447`},aj=`#e9f2ef`,oj=new U,sj={rippleScale:.85,rippleStrength:.09,flowRate:.42,fresnelScale:.95,standingAmp:.11,glideAmp:.025},cj=class e extends Oh{static typeName=`River3D`;static props={path:{default:[]},width:{default:6},widths:{default:[]},depth:{default:.8},flowSpeed:{default:1.6},colors:{default:{}},absorption:{default:.5},opacity:{default:.85},foam:{default:1},ripples:{default:1},sunDirection:{default:[.5,.8,.3]},sunColor:{default:`#fff6e0`},sunIntensity:{default:1},terrain:{default:``,nodePath:!0},carve:{default:!0},flowForce:{default:1},spray:{default:1}};path=[];width=6;widths=[];depth=.8;flowSpeed=1.6;colors={};absorption=.5;opacity=.85;foam=1;ripples=1;sunDirection=[.5,.8,.3];sunColor=`#fff6e0`;sunIntensity=1;terrain=``;carve=!0;flowForce=1;spray=1;renderOrder=1;time=0;rings=[];falls=[];sprayKey=``;courseKey=``;bedAt=null;fitted=!1;bounds=null;boundsKey=``;rocks=[];rockScanAt=-1;world=[0,0,0];_bodies=[];static validateJson(e){let t=e;if(!Array.isArray(t.path))throw new N(`BAD_FORMAT`,`River3D '${e.name}' path must be an array of [x, z] points, got ${JSON.stringify(t.path)}.`,{prop:`path`});if(t.path.length>0&&t.path.length<2)throw new N(`BAD_FORMAT`,`River3D '${e.name}' path needs at least 2 points (source → mouth), got ${t.path.length}.`,{prop:`path`});if(t.path.forEach((t,n)=>{if(!Array.isArray(t)||t.length<2||!Number.isFinite(t[0])||!Number.isFinite(t[1]))throw new N(`BAD_FORMAT`,`River3D '${e.name}' path[${n}] must be [x, z] with finite numbers, got ${JSON.stringify(t)}.`,{prop:`path`})}),!(typeof t.width==`number`&&t.width>0))throw new N(`BAD_FORMAT`,`River3D '${e.name}' width must be a positive number of meters, got ${JSON.stringify(t.width)}.`,{prop:`width`});if(!Array.isArray(t.widths)||t.widths.some(e=>!(typeof e==`number`&&e>0)))throw new N(`BAD_FORMAT`,`River3D '${e.name}' widths must be a list of positive meters (source→mouth), got ${JSON.stringify(t.widths)}.`,{prop:`widths`});if(!(t.depth>0))throw new N(`BAD_FORMAT`,`River3D '${e.name}' depth must be > 0 meters, got ${JSON.stringify(t.depth)}.`,{prop:`depth`});if(!(t.flowSpeed>=0))throw new N(`BAD_FORMAT`,`River3D '${e.name}' flowSpeed must be >= 0 m/s, got ${JSON.stringify(t.flowSpeed)}.`,{prop:`flowSpeed`});for(let n of[`absorption`,`foam`,`ripples`,`flowForce`,`spray`,`sunIntensity`]){let r=t[n];if(!(typeof r==`number`&&r>=0))throw new N(`BAD_FORMAT`,`River3D '${e.name}' ${n} must be a number >= 0, got ${JSON.stringify(r)}.`,{prop:n})}if(!(t.opacity>=0&&t.opacity<=1))throw new N(`BAD_FORMAT`,`River3D '${e.name}' opacity must be within [0, 1], got ${JSON.stringify(t.opacity)}.`,{prop:`opacity`});let n=t.colors;if(typeof n!=`object`||!n||Array.isArray(n))throw new N(`BAD_FORMAT`,`River3D '${e.name}' colors must be an object of { shallow, deep, sky, horizon, bank } hex strings.`,{prop:`colors`});for(let t of Object.keys(n)){if(!(t in ij))throw new N(`BAD_FORMAT`,`River3D '${e.name}' colors has unknown key '${t}' — expected shallow, deep, sky, horizon or bank.`,{prop:`colors`});if(typeof n[t]!=`string`)throw new N(`BAD_FORMAT`,`River3D '${e.name}' colors.${t} must be a hex string, got ${JSON.stringify(n[t])}.`,{prop:`colors`})}}_createObject3D(){return new Ys(new J,this.buildMaterial())}onReady(){this.ensureCourse()}onExitTree(){XD(this,this.terrain)?._setExternalChannel(this,null)}update(e){this.time+=e,this.ensureCourse(),this.syncSpray(),this.flowForce>0&&this.rings.length>1&&this.sweepBodies(e)}_syncObject3D(){super._syncObject3D();let e=this._ensureObject3D();this.rebuildIfNeeded(e),this.syncUniforms(e)}_onRender3D(e){if(this.rings.length===0)return;(this.rockScanAt<0||this.time-this.rockScanAt>ZA)&&(this.rockScanAt=this.time,this.scanRocks());let t=this._ensureObject3D().material.uniforms;this.syncRocks(t,e.camera.getWorldPosition(oj))}_waterYAt(e,t){if(this.rings.length===0)return null;let[n,r,i]=this.world,a=e-n,o=t-i,s=this.ringBounds();if(a<s.minX||a>s.maxX||o<s.minZ||o>s.maxZ)return null;let c=IA(this.rings,a,o);return c?.inside?c.surfaceY+r:null}ringBounds(){if(this.boundsKey===this.courseKey&&this.bounds)return this.bounds;let e=1/0,t=-1/0,n=1/0,r=-1/0,i=0;for(let a of this.rings)a.x<e&&(e=a.x),a.x>t&&(t=a.x),a.z<n&&(n=a.z),a.z>r&&(r=a.z),i=Math.max(i,a.halfLeft,a.halfRight);return this.bounds={minX:e-i,maxX:t+i,minZ:n-i,maxZ:r+i},this.boundsKey=this.courseKey,this.bounds}sampleAt(e,t){if(this.ensureCourse(),this.rings.length===0)return null;let[n,r,i]=this.world,a=IA(this.rings,e-n,t-i);return a?{...a,surfaceY:a.surfaceY+r}:null}fallsAt(){this.ensureCourse();let[e,t,n]=this.world;return this.falls.map(r=>({...r,worldX:r.x+e,worldY:r.baseY+t,worldZ:r.z+n}))}_rings(){return this.rings}_applySunDirection(t){let n=e.props.sunDirection?.default;this.sunDirection.every((e,t)=>e===n[t])&&(this._ensureObject3D().material.uniforms?.uSunDirection?.value)?.set(t[0],t[1],t[2])}free(){let e=this._ensureObject3D();e.geometry?.dispose(),e.material?.dispose?.(),super.free()}widthProfile(){return this.widths.length>0?this.widths:[this.width]}applyCarve(e){if(!e)return;if(!this.carve||this.path.length<2){e._setExternalChannel(this,null);return}e._setExternalChannel(this,null);let[t,,n]=YD(this),[r,,i]=YD(e),a=e._heightmap();e._setExternalChannel(this,dA({path:this.path.map(e=>[(e[0]??0)+t-r,(e[1]??0)+n-i]),widths:this.widthProfile(),depth:this.depth,cell:(e.size[0]??1)/Math.max(1,a.segsX),groundAt:(e,t)=>a.heightAt(e,t)}))}resolveTerrain(){let e=XD(this,this.terrain);if(!e&&this.terrain!==``)throw new N(`NODE_NOT_FOUND`,`River3D '${this.name}' terrain '${this.terrain}' is not a Terrain3D in the tree.`,{prop:`terrain`});return e}ensureCourse(){let e=this.resolveTerrain(),t=YD(this),n=JSON.stringify([this.path,this.width,this.widths,this.depth,this.flowSpeed,this.carve,e?e.name:``,t]);if(n===this.courseKey)return!1;if(this.courseKey=n,this.world=t,this.bedAt=null,this.applyCarve(e),this.path.length<2)return this.rings=[],this.falls=[],!0;let[r,i,a]=t;this.bedAt=e?(t,n)=>e.heightAt(t+r,n+a)-i:()=>-this.depth,this.fitted=e!==null;let o=this.widthProfile();return this.rings=NA({path:this.path,widths:o,depth:this.depth,flowSpeed:this.flowSpeed,step:MA(o,this.depth),bedAt:this.bedAt,fit:this.fitted}),this.falls=zA(this.rings),this.warnUncoveredWater(),!0}warnUncoveredWater(){if(this.warnedCoverage)return;let e=pA(this.rings);if(e.length*3<this.rings.length)return;this.warnedCoverage=!0;let t=e.reduce((e,t)=>t.wettedHalfWidth-t.carriedHalfWidth>e.wettedHalfWidth-e.carriedHalfWidth?t:e);this.diagnose(`warn`,`[incanto] River3D '${this.name}': the course is too tight for the water it holds — ${e.length} of ${this.rings.length} stations leave bare channel beside the ribbon (worst at ${t.along.toFixed(0)} m: ground wet to ${t.wettedHalfWidth.toFixed(1)} m from the centre, a bend that can only carry ${t.carriedHalfWidth.toFixed(1)} m). Fix by EASING THE BENDS in \`path\` (fewer, straighter points), NARROWING \`widths\` there, or placing standing water (a Water3D) if that reach is really a pool.`)}warnedCoverage=!1;rebuildIfNeeded(e){if(!this.ensureCourse()&&e.geometry.getAttribute(`position`))return;if(this.rings.length===0||!this.bedAt){e.geometry.dispose();let t=new J;t.setAttribute(`position`,new q(new Float32Array,3)),e.geometry=t;return}let t=this.widthProfile(),n=Math.min(...t),r=Math.max(...t),i=PA(this.rings,{acrossSegments:Math.min(KA,Math.max(GA,Math.round(r/qA))),bankOvershoot:this.fitted?1:WA,bedBlur:Math.min(n/2*JA,YA),bedAt:this.bedAt}),a=new J;a.setAttribute(`position`,new q(i.positions,3)),a.setAttribute(`normal`,new q(i.normals,3)),a.setAttribute(`aFlowUv`,new q(i.uvs,2)),a.setAttribute(`aFlow`,new q(i.flow,2)),a.setAttribute(`aRiver`,new q(i.river,4)),a.setIndex(new q(i.indices,1)),a.computeBoundingSphere(),e.geometry.dispose(),e.geometry=a}buildMaterial(){return new vl({vertexShader:HA,fragmentShader:UA,fog:!0,uniforms:{fogColor:{value:new K(`#ffffff`)},fogNear:{value:1},fogFar:{value:1e3},fogDensity:{value:25e-5},uTime:{value:0},uShallowColor:{value:new K(ij.shallow)},uDeepColor:{value:new K(ij.deep)},uFoamColor:{value:new K(aj)},uSkyColor:{value:new K(ij.sky)},uHorizonColor:{value:new K(ij.horizon)},uBankColor:{value:new K(ij.bank)},uSunDirection:{value:new U(.5,.8,.3)},uSunColor:{value:new K(this.sunColor)},uSunIntensity:{value:this.sunIntensity},uMaxDepth:{value:this.depth},uAbsorption:{value:this.absorption},uOpacity:{value:this.opacity},uFoam:{value:this.foam},uRippleScale:{value:sj.rippleScale},uRippleStrength:{value:sj.rippleStrength*this.ripples},uFlowRate:{value:sj.flowRate},uSparkle:{value:this.ripples},uRockCount:{value:0},uRocks:{value:Array.from({length:XA},()=>new Ra)},uFresnelScale:{value:sj.fresnelScale},uStandingAmp:{value:sj.standingAmp},uGlideAmp:{value:sj.glideAmp}},transparent:!0,depthTest:!0,depthWrite:!1,side:2})}scanRocks(){let e=[],[t,n,r]=this.world,i=(i,a,o,s,c)=>{if(o<=.02)return;let l=IA(this.rings,i-t,a-r);if(!l?.inside)return;let u=l.surfaceY+n;if(s>u||c<u-this.depth)return;let d=(c-u)/Math.max(this.depth*QA,.02),f=Math.min(Math.max(d+1,0),1);e.push({x:i,z:a,radius:o,breaks:f})},a=this;for(;a.parent;)a=a.parent;let o=e=>{if(e instanceof Nh||e instanceof Mh){let t=e.collider,n=Lm(t),[r,a,o]=YD(e);i(r,o,t?.shape===`box`?Math.max(t.size?.[0]??.4,t.size?.[2]??.4)/2:t?.radius??.35,a-n,a+n)}else if(e instanceof Aw){let[t,n,r]=e.size,[a,o,s]=YD(e);for(let c of e.transforms){let e=c[4]??1,l=a+(c[0]??0),u=o+(c[1]??0),d=s+(c[2]??0),f=(n??1)*e/2;i(l,d,Math.max(t,r)*e/2,u-f,u+f)}}else if(e instanceof Ew){let[t,n,r]=e.size,[a,o,s]=YD(e),c=(n??1)/2;i(a,s,Math.max(t,r)/2,o-c,o+c)}for(let t of e.children)o(t)};o(a),this.rocks=e}syncRocks(e,t){let n=e.uRocks?.value,r=e.uRockCount;if(!n||!r)return;if(this.rocks.length===0){r.value=0;return}let i=[...this.rocks].map(e=>({r:e,d:(e.x-t.x)**2+(e.z-t.z)**2})).sort((e,t)=>e.d-t.d).slice(0,XA),a=0;for(let{r:e,d:t}of i){let r=Math.max(e.radius*$A,ej),i=Math.min(Math.sqrt(t)/r,1),o=Math.min(Math.max((i-.6)/.4,0),1),s=1-o*o*(3-2*o);s<=.01||(n[a]?.set(e.x,e.z,e.radius,e.breaks*s),a++)}r.value=a}syncUniforms(e){let t=e.material.uniforms,n=(e,n)=>{let r=t[e];r&&(r.value=n)},r=(e,n)=>{(t[e]?.value)?.set(n)},i=this.colors;n(`uTime`,this.time),r(`uShallowColor`,i.shallow??ij.shallow),r(`uDeepColor`,i.deep??ij.deep),r(`uSkyColor`,i.sky??ij.sky),r(`uHorizonColor`,i.horizon??ij.horizon),r(`uBankColor`,i.bank??ij.bank),r(`uSunColor`,this.sunColor),(t.uSunDirection?.value)?.set(this.sunDirection[0]??.5,this.sunDirection[1]??.8,this.sunDirection[2]??.3),n(`uSunIntensity`,this.sunIntensity),n(`uMaxDepth`,this.depth),n(`uAbsorption`,this.absorption),n(`uOpacity`,this.opacity),n(`uFoam`,this.foam),n(`uRippleStrength`,sj.rippleStrength*this.ripples),n(`uSparkle`,this.ripples)}syncSpray(){let e=this.spray>0?`${this.spray}|${JSON.stringify(this.falls)}`:``;if(e!==this.sprayKey){this.sprayKey=e;for(let e of[...this.children])e.name.startsWith(`__spray`)&&e.free();this.spray<=0||this.falls.forEach((e,t)=>{let n=new Qk(`__spray${t}`);n.position=[e.x+e.dirX*.6,e.baseY+.15,e.z+e.dirZ*.6];let r=Math.min(1.6,.4+e.drop*.12)*this.spray;n.rate=Math.round(Math.min(22,5+e.drop*1.6)*this.spray),n.maxParticles=160,n.lifetime=[1,2.1],n.speed=[45*r,130*r],n.directionDeg=-90,n.spreadDeg=52,n.gravity=[0,-240,0],n.drag=1.2,n.sizeStart=7*r,n.sizeEnd=30*r,n.colorStart=`#ffffff`,n.colorEnd=`#dfe9ec`,n.alphaStart=.085,n.alphaEnd=0,n.blend=`normal`,n.depthTest=!0,this.addChild(n)})}}sweepBodies(e){let t=this;for(;t.parent;)t=t.parent;let n=this._bodies;if(n.length=0,lj(t,n),n.length===0)return;let[r,i,a]=this.world;for(let t of n){let n=YD(t),o=IA(this.rings,n[0]-r,n[2]-a);if(!o?.inside)continue;let s=o.surfaceY+i,c=n[1]-Lm(t.collider);if(c>s+nj||c<s-this.depth-rj)continue;let l=uj(t);if(!l)continue;let u=Math.min(1,this.flowForce*tj*e),d=(o.dirX*o.speed-(l[0]??0))*u,f=(o.dirZ*o.speed-(l[2]??0))*u;if(t instanceof Mh){let e=t.mass||1;t.applyImpulse([d*e,0,f*e])}else l[0]=(l[0]??0)+d,l[2]=(l[2]??0)+f}}};function lj(e,t){(e instanceof Nh||e instanceof Mh)&&t.push(e);for(let n of e.children)lj(n,t)}function uj(e){return e.velocity??e.linearVelocity}var dj=128,fj=class extends Oh{static typeName=`Trail3D`;static props={width:{default:.3},color:{default:`#ffffff`},opacity:{default:.8},seconds:{default:.6},emitting:{default:!0},additive:{default:!1},minDistance:{default:.05}};width=.3;color=`#ffffff`;opacity=.8;seconds=.6;emitting=!0;additive=!1;minDistance=.05;points=[];clock=0;mesh=null;lastColor=``;_createObject3D(){let e=new _o,t=new J;t.setAttribute(`position`,new q(new Float32Array(dj*2*3),3));let n=new Ls({color:this.color,transparent:!0,opacity:this.opacity,side:2,depthWrite:!1,blending:this.additive?2:1});return this.mesh=new Ys(t,n),this.mesh.frustumCulled=!1,this.mesh.matrixAutoUpdate=!1,this.mesh.matrixWorld.identity(),this.mesh.updateMatrixWorld=()=>{},e.add(this.mesh),e}update(e){for(this.clock+=e;this.points.length>0&&this.clock-this.points[0].t>this.seconds;)this.points.shift()}_onRender3D(e){let t=this._ensureObject3D();if(this.emitting){t.getWorldPosition(pj);let e=this.points[this.points.length-1];(!e||(e.x-pj.x)**2+(e.y-pj.y)**2+(e.z-pj.z)**2>this.minDistance*this.minDistance)&&(this.points.push({x:pj.x,y:pj.y,z:pj.z,t:this.clock}),this.points.length>dj&&this.points.shift())}let n=this.mesh;if(!n)return;n.matrixWorld.identity();let r=n.material;this.color!==this.lastColor&&(this.lastColor=this.color,r.color=new K(this.color)),r.opacity=this.opacity;let i=this.points.length,a=n.geometry,o=a.getAttribute(`position`);if(i<2){a.setDrawRange(0,0);return}for(let t=0;t<i;t++){let n=this.points[t],r=this.points[Math.min(t+1,i-1)]??n;mj.set(r.x-n.x,r.y-n.y,r.z-n.z),mj.lengthSq()<1e-8&&mj.set(0,1,0),hj.set(e.camera.position.x-n.x,e.camera.position.y-n.y,e.camera.position.z-n.z),gj.crossVectors(mj,hj).normalize();let a=(this.clock-n.t)/this.seconds,s=this.width/2*Math.max(0,1-a);o.setXYZ(t*2,n.x+gj.x*s,n.y+gj.y*s,n.z+gj.z*s),o.setXYZ(t*2+1,n.x-gj.x*s,n.y-gj.y*s,n.z-gj.z*s)}if(o.needsUpdate=!0,!a.index||a.index.count<(dj-1)*6){let e=[];for(let t=0;t<dj-1;t++){let n=t*2;e.push(n,n+1,n+2,n+1,n+3,n+2)}a.setIndex(e)}a.setDrawRange(0,(i-1)*6)}get pointCount(){return this.points.length}},pj=new U,mj=new U,hj=new U,gj=new U;function _j(e){let{branch:t,leaves:n,type:r}=e,i=0,a=0,o=[{level:0,sections:t.sections[0],segments:t.segments[0]}];for(;o.length>0;){let e=o.shift();if(i+=e.sections*e.segments*2,e.level>=t.levels){a+=n.count===0?0:n.count+ +(r===`deciduous`);continue}r===`deciduous`&&o.push({level:e.level+1,sections:e.sections,segments:e.segments});let s=t.children[e.level]??0;for(let n=0;n<s;n++)o.push({level:e.level+1,sections:t.sections[e.level+1]??1,segments:t.segments[e.level+1]??3})}let s=n.billboard===`double`?2:1,c=a*s*2;return{branches:i,leaves:c,total:i+c}}var vj={ash:{type:`deciduous`,branch:{levels:3,angle:[0,48,75,60],children:[7,4,3,0],force:{direction:{x:0,y:1,z:0},strength:-.06},gnarliness:[.03,.25,.2,.09],length:[43.47,27.14,9.51,4.6],radius:[2,.63,.76,.7],sections:[12,8,6,4],segments:[12,6,4,3],start:[0,.23,.33,0],taper:[.7,.7,.7,.7],twist:[.09,-.07,0,0]},leaves:{style:`ash`,billboard:`double`,angle:55,count:16,start:0,size:2.67,sizeVariance:.72,alphaTest:.5}},aspen:{type:`deciduous`,branch:{levels:2,angle:[0,75,32,7],children:[10,3,3,0],force:{direction:{x:0,y:1,z:0},strength:.0148},gnarliness:[.05,.12,.12,.02],length:[50,6.07,11.19,1],radius:[.72,.41,.7,.7],sections:[12,10,8,6],segments:[8,6,4,3],start:[0,.59,.35,0],taper:[.37,.13,.7,.7],twist:[0,0,0,0]},leaves:{style:`aspen`,billboard:`double`,angle:30,count:11,start:.124,size:2.5,sizeVariance:.7,alphaTest:.5}},oak:{type:`deciduous`,branch:{levels:3,angle:[0,54,58,32],children:[6,4,3,0],force:{direction:{x:0,y:1,z:0},strength:-.01},gnarliness:[0,-.1,-.15,.09],length:[37.24,11.08,12.39,7.16],radius:[1.41,.9,.69,1.19],sections:[8,6,3,1],segments:[7,5,3,3],start:[0,.49,.06,.12],taper:[.73,.42,.69,.75],twist:[-.23,.42,0,0]},leaves:{style:`oak`,billboard:`double`,angle:42,count:18,start:.16,size:2.5,sizeVariance:.7,alphaTest:.5}},pine:{type:`evergreen`,branch:{levels:1,angle:[0,110,16,60],children:[82,3,5,0],force:{direction:{x:0,y:1,z:0},strength:-.003},gnarliness:[.05,.08,0,0],length:[50,23.87,14.08,1],radius:[1.05,.36,.7,.7],sections:[12,10,8,6],segments:[8,6,4,3],start:[0,.27,.14,.3],taper:[.7,.7,.7,.7],twist:[0,0,0,0]},leaves:{style:`pine`,billboard:`double`,angle:39,count:30,start:.09,size:1.435,sizeVariance:.201,alphaTest:.3}},bush:{type:`deciduous`,branch:{levels:3,angle:[0,21.5,62.6,60],children:[7,3,2,0],force:{direction:{x:0,y:1,z:0},strength:-.02},gnarliness:[.11,.09,.05,.09],length:[.1,15.3,5.59,4.6],radius:[.58,.95,.76,.7],sections:[6,6,4,3],segments:[4,4,4,3],start:[0,.53,.33,0],taper:[.7,.7,.7,.7],twist:[.3,-.07,0,0]},leaves:{style:`ash`,billboard:`double`,angle:55,count:8,start:0,size:2.45,sizeVariance:.717,alphaTest:.5}},"ash-forest":{type:`deciduous`,branch:{levels:2,angle:[0,48,75,60],children:[5,3,0,0],force:{direction:{x:0,y:1,z:0},strength:-.06},gnarliness:[.03,.25,.2,.09],length:[43.47,27.14,9.51,4.6],radius:[2,.63,.76,.7],sections:[6,5,4,4],segments:[6,4,3,3],start:[0,.3,.33,0],taper:[.7,.7,.7,.7],twist:[.09,-.07,0,0]},leaves:{style:`ash`,billboard:`double`,angle:55,count:15,start:0,size:3,sizeVariance:.6,alphaTest:.5}},"oak-forest":{type:`deciduous`,branch:{levels:2,angle:[0,54,58,32],children:[5,3,0,0],force:{direction:{x:0,y:1,z:0},strength:-.01},gnarliness:[0,-.1,-.15,.09],length:[37.24,11.08,12.39,7.16],radius:[1.41,.9,.69,1.19],sections:[6,4,3,1],segments:[6,4,3,3],start:[0,.49,.06,.12],taper:[.73,.42,.69,.75],twist:[-.23,.42,0,0]},leaves:{style:`oak`,billboard:`double`,angle:42,count:16,start:.1,size:2.9,sizeVariance:.7,alphaTest:.5}},"pine-forest":{type:`evergreen`,branch:{levels:1,angle:[0,110,16,60],children:[44,3,5,0],force:{direction:{x:0,y:1,z:0},strength:-.005},gnarliness:[.07,.09,0,0],length:[50,23.87,14.08,1],radius:[1.05,.36,.7,.7],sections:[6,5,8,6],segments:[6,3,4,3],start:[0,.27,.14,.3],taper:[.7,.7,.7,.7],twist:[0,0,0,0]},leaves:{style:`pine`,billboard:`double`,angle:39,count:9,start:.09,size:1.8,sizeVariance:.201,alphaTest:.3}},"bush-forest":{type:`deciduous`,branch:{levels:2,angle:[0,21.5,62.6,60],children:[6,3,0,0],force:{direction:{x:0,y:1,z:0},strength:-.02},gnarliness:[.11,.09,.05,.09],length:[.1,15.3,5.59,4.6],radius:[.58,.95,.76,.7],sections:[5,4,3,3],segments:[4,3,3,3],start:[0,.53,.33,0],taper:[.7,.7,.7,.7],twist:[.3,-.07,0,0]},leaves:{style:`ash`,billboard:`double`,angle:55,count:10,start:0,size:3.2,sizeVariance:.6,alphaTest:.5}}},yj=[`ash`,`aspen`,`oak`,`pine`,`bush`,`ash-forest`,`oak-forest`,`pine-forest`,`bush-forest`];function bj(e){let t=vj[e];if(!t)throw new N(`BAD_FORMAT`,`Unknown eztree preset '${e}' — must be one of [${yj.join(`, `)}].`,{prop:`preset`,validOptions:yj});return structuredClone(t)}var xj={ash:{texture:`oak`,tint:`#cecbbe`,repeat:[.5,1/5]},aspen:{texture:`birch`,tint:`#ffffff`,repeat:[1,1]},oak:{texture:`oak`,tint:`#fff3d1`,repeat:[1,1/10]},pine:{texture:`pine`,tint:`#ffffff`,repeat:[1,1]},bush:{texture:`oak`,tint:`#cecbbe`,repeat:[.5,1/5]}};function Sj(e){if(!yj.includes(e))throw new N(`BAD_FORMAT`,`Unknown eztree preset '${e}' — must be one of [${yj.join(`, `)}].`,{prop:`preset`,validOptions:yj});return structuredClone(xj[e.replace(/-forest$/,``)])}var Cj=.45,wj=.45,Tj=.55,Ej=.15,Dj=.07,Oj=.035;function kj(e,t){let n=Math.imul(e+1,374761393)+Math.imul(t+1,668265263)>>>0;return n=Math.imul(n^n>>>13,1274126177)>>>0,((n^n>>>16)>>>0)/4294967296}function Aj(e,t,n){let r=e.length/3,i=new Float32Array(e.length),a=new Float32Array(e.length),o=1/0,s=1/0,c=1/0,l=-1/0,u=-1/0,d=-1/0;for(let t=0;t<r;t++){let n=e[t*3],r=e[t*3+1],i=e[t*3+2];n<o&&(o=n),n>l&&(l=n),r<s&&(s=r),r>u&&(u=r),i<c&&(c=i),i>d&&(d=i)}let f=(o+l)/2,p=(s+u)/2,m=(c+d)/2,h=Math.max((l-o)/2,.001),g=Math.max((u-s)/2,.001),_=Math.max((d-c)/2,.001),v=new Map;for(let n=0;n<r;n++){let r=t[n],i=v.get(r);i||(i={x:0,y:0,z:0,n:0},v.set(r,i)),i.x+=e[n*3],i.y+=e[n*3+1],i.z+=e[n*3+2],i.n++}for(let e of v.values())e.x/=e.n,e.y/=e.n,e.z/=e.n;for(let o=0;o<r;o++){let r=e[o*3],c=e[o*3+1],l=e[o*3+2],d=(r-f)/h,y=(c-p)/g,b=(l-m)/_,x,S,C,w;if(n===`evergreen`){let e=Math.hypot(r-f,l-m);if(e<1e-6)x=0,S=1,C=0;else{let t=1/Math.hypot(1,wj);x=(r-f)/e*t,S=wj*t,C=(l-m)/e*t}let t=(c-s)/Math.max(u-s,.001),n=Math.max(Ej,1-t);w=Math.min(1,Math.hypot(d,b)/n)}else{let e=d/h,t=y/g,n=b/_,r=Math.hypot(e,t,n);r<1e-6?(x=0,S=1,C=0):(x=e/r,S=t/r,C=n/r),w=Math.min(1,Math.hypot(d,y,b))}let T=v.get(t[o]);if(T){let e=r-T.x,t=c-T.y,n=l-T.z,i=Math.hypot(e,t,n);if(i>1e-6){x=x*(1-Tj)+e/i*Tj,S=S*(1-Tj)+t/i*Tj,C=C*(1-Tj)+n/i*Tj;let r=Math.hypot(x,S,C);r>1e-6?(x/=r,S/=r,C/=r):(x=0,S=1,C=0)}}i[o*3]=x,i[o*3+1]=S,i[o*3+2]=C;let E=Cj+(1-Cj)*w,D=t[o],O=E*(1-Dj*kj(D,1)),k=(kj(D,2)-.5)*2*Oj;a[o*3]=O*(1+k),a[o*3+1]=O,a[o*3+2]=O*(1-k)}return{normals:i,colors:a}}var jj=class e{static MASK=4294967295;mW;mZ;constructor(t){this.mW=123456789+t&e.MASK,this.mZ=987654321-t&e.MASK}random(t=1,n=0){this.mZ=36969*(this.mZ&65535)+(this.mZ>>16)&e.MASK,this.mW=18e3*(this.mW&65535)+(this.mW>>16)&e.MASK;let r=((this.mZ<<16)+(this.mW&65535)>>>0)/4294967296;return(t-n)*r+n}};function Mj(e,t,n){let r=new jj(t),i={branchVerts:[],branchNormals:[],branchUvs:[],branchIndices:[],leafVerts:[],leafIndices:[],leafUvs:[],leafAnchors:[],leafClusters:[],leafClusterNext:0},a=[{origin:new U,orientation:new Qa,length:e.branch.length[0],radius:e.branch.radius[0],level:0,sectionCount:e.branch.sections[0],segmentCount:e.branch.segments[0]}];for(;a.length>0;)Nj(e,r,i,a,a.shift());Bj(i,n);let o=new J;o.setAttribute(`position`,new q(new Float32Array(i.branchVerts),3)),o.setAttribute(`normal`,new q(new Float32Array(i.branchNormals),3)),o.setAttribute(`uv`,new q(new Float32Array(i.branchUvs),2)),o.setIndex(new q(Vj(i.branchIndices,i.branchVerts),1)),o.computeBoundingSphere();let s=null;if(i.leafVerts.length>0){s=new J,s.setAttribute(`position`,new q(new Float32Array(i.leafVerts),3)),s.setAttribute(`anchor`,new q(new Float32Array(i.leafAnchors),3)),s.setAttribute(`uv`,new q(new Float32Array(i.leafUvs),2)),s.setIndex(new q(Vj(i.leafIndices,i.leafVerts),1));let t=Aj(i.leafVerts,i.leafClusters,e.type);s.setAttribute(`normal`,new q(t.normals,3)),s.setAttribute(`color`,new q(t.colors,3)),s.computeBoundingSphere()}return{branches:o,leaves:s}}function Nj(e,t,n,r,i){let a=n.branchVerts.length/3,o=i.orientation.clone(),s=i.origin.clone(),c=i.length/i.sectionCount,l=[];for(let r=0;r<=i.sectionCount;r++){let a=i.radius;r===i.sectionCount&&i.level===e.branch.levels?a=.001:e.type===`deciduous`?a*=1-(e.branch.taper[i.level]??0)*(r/i.sectionCount):a*=1-r/i.sectionCount;let u=new U,d=new U,f=0;for(let e=0;e<i.segmentCount;e++){let t=2*Math.PI*e/i.segmentCount,c=new U(Math.cos(t),0,Math.sin(t)).multiplyScalar(a).applyEuler(o).add(s),l=new U(Math.cos(t),0,Math.sin(t)).applyEuler(o).normalize(),p=r%2==0?0:1;n.branchVerts.push(c.x,c.y,c.z),n.branchNormals.push(l.x,l.y,l.z),n.branchUvs.push(e/i.segmentCount,p),e===0&&(u=c,d=l,f=p)}n.branchVerts.push(u.x,u.y,u.z),n.branchNormals.push(d.x,d.y,d.z),n.branchUvs.push(1,f),l.push({origin:s.clone(),orientation:o.clone(),radius:a}),s.add(new U(0,c,0).applyEuler(o));let p=Math.max(1,1/Math.sqrt(a))*(e.branch.gnarliness[i.level]??0);o.x+=t.random(p,-p),o.z+=t.random(p,-p);let m=new H().setFromEuler(o),h=new H().setFromAxisAngle(new U(0,1,0),e.branch.twist[i.level]??0),g=e.branch.force,_=new H().setFromUnitVectors(new U(0,1,0),new U(g.direction.x,g.direction.y,g.direction.z));m.multiply(h),m.rotateTowards(_,g.strength/a),o.setFromQuaternion(m)}zj(n,a,i);let u=i.level===e.branch.levels?n.leafClusterNext++:0;if(e.type===`deciduous`){let a=l[l.length-1];i.level<e.branch.levels?r.push({origin:a.origin,orientation:a.orientation,length:e.branch.length[i.level+1]??0,radius:a.radius,level:i.level+1,sectionCount:i.sectionCount,segmentCount:i.segmentCount}):e.leaves.count>0&&Rj(e,t,n,a.origin,a.orientation,u)}i.level===e.branch.levels?Lj(e,t,n,l,u):i.level<e.branch.levels&&Ij(e,t,r,e.branch.children[i.level]??0,i.level+1,l)}function Pj(e,t){let n=Math.floor(t*(e.length-1)),r=e[n],i=n===e.length-1?r:e[n+1],a=(t-n/(e.length-1))/(1/(e.length-1)),o=new U().lerpVectors(r.origin,i.origin,a),s=new H().setFromEuler(r.orientation),c=new H().setFromEuler(i.orientation);return{origin:o,orientation:new Qa().setFromQuaternion(c.slerp(s,a)),radius:{a:r.radius,b:i.radius,alpha:a}}}function Fj(e,t,n){let r=new H().setFromAxisAngle(new U(1,0,0),t/(180/Math.PI)),i=new H().setFromAxisAngle(new U(0,1,0),n),a=new H().setFromEuler(e);return new Qa().setFromQuaternion(a.multiply(i.multiply(r)))}function Ij(e,t,n,r,i,a){let o=t.random();for(let s=0;s<r;s++){let c=t.random(1,e.branch.start[i]??0),l=Pj(a,c),u=(e.branch.radius[i]??0)*((1-l.radius.alpha)*l.radius.a+l.radius.alpha*l.radius.b),d=2*Math.PI*(o+s/r),f=Fj(l.orientation,e.branch.angle[i]??0,d),p=(e.branch.length[i]??0)*(e.type===`evergreen`?1-c:1);n.push({origin:l.origin,orientation:f,length:p,radius:u,level:i,sectionCount:e.branch.sections[i]??1,segmentCount:e.branch.segments[i]??3})}}function Lj(e,t,n,r,i){let a=t.random();for(let o=0;o<e.leaves.count;o++){let s=Pj(r,t.random(1,e.leaves.start)),c=2*Math.PI*(a+o/e.leaves.count),l=Fj(s.orientation,e.leaves.angle,c);Rj(e,t,n,s.origin,l,i)}}function Rj(e,t,n,r,i,a){let o=n.leafVerts.length/3,s=e.leaves.size*(1+t.random(e.leaves.sizeVariance,-e.leaves.sizeVariance)),c=e=>{let t=s/2,c=[new U(-t,s,0),new U(-t,0,0),new U(t,0,0),new U(t,s,0)];for(let t of c)t.applyEuler(new Qa(0,e,0)).applyEuler(i).add(r),n.leafVerts.push(t.x,t.y,t.z),n.leafAnchors.push(r.x,r.y,r.z),n.leafClusters.push(a);n.leafUvs.push(0,1,0,0,1,0,1,1),n.leafIndices.push(o,o+1,o+2,o,o+2,o+3),o+=4};c(0),e.leaves.billboard===`double`&&c(Math.PI/2)}function zj(e,t,n){let r=n.segmentCount+1;for(let i=0;i<n.sectionCount;i++)for(let a=0;a<n.segmentCount;a++){let n=t+i*r+a,o=t+i*r+(a+1),s=n+r,c=o+r;e.branchIndices.push(n,s,o,o,s,c)}}function Bj(e,t){let n=0;for(let t=1;t<e.branchVerts.length;t+=3){let r=e.branchVerts[t];r>n&&(n=r)}for(let t=1;t<e.leafVerts.length;t+=3){let r=e.leafVerts[t];r>n&&(n=r)}if(n<=0)return;let r=t/n;for(let t=0;t<e.branchVerts.length;t++)e.branchVerts[t]=e.branchVerts[t]*r;for(let t=0;t<e.leafVerts.length;t++)e.leafVerts[t]=e.leafVerts[t]*r;for(let t=0;t<e.leafAnchors.length;t++)e.leafAnchors[t]=e.leafAnchors[t]*r}function Vj(e,t){return t.length/3>65535?new Uint32Array(e):new Uint16Array(e)}var Hj=[`simple`,`medium`,`high`],Uj=[`conifer`,`broadleaf`,`dead`,`bush`];function Wj(e,t,n){return new N(`BAD_FORMAT`,`Tree3D ${e} must be one of [${n.join(`, `)}], got '${t}'.`,{prop:e,validOptions:n})}var Gj={simple:0,medium:1,high:2},Kj=[5,7,10],qj=[2,3,4],Jj=[6,8,12],Yj=[2,3,3],Xj=[0,1,2],Zj=[3,4,5],Qj=3;function $j(e,t){if(!Hj.includes(e))throw Wj(`tier`,e,Hj);if(!Uj.includes(t))throw Wj(`type`,t,Uj);let n=e,r=t,i=Gj[n];return{tier:n,type:r,trunkRadialSegments:Kj[i],canopyLayers:r===`conifer`?qj[i]:0,canopySegments:Jj[i],blobCount:r===`broadleaf`||r===`bush`?Yj[i]:0,blobDetail:Xj[i],branchCount:r===`dead`?Zj[i]:r===`conifer`&&n===`high`?Qj:0,hasCanopy:r!==`dead`,canopySway:n!==`simple`}}var eM=.02,tM={conifer:{trunkHeight:.4,trunkRadiusBottom:.05,trunkRadiusTop:.035},broadleaf:{trunkHeight:.42,trunkRadiusBottom:.05,trunkRadiusTop:.032},dead:{trunkHeight:.72,trunkRadiusBottom:.045,trunkRadiusTop:.018},bush:{trunkHeight:.14,trunkRadiusBottom:.045,trunkRadiusTop:.035}};function nM(e,t,n){let{trunkHeight:r,trunkRadiusBottom:i,trunkRadiusTop:a}=tM[e.type],o=[],s=new il(a,i,r,e.trunkRadialSegments).toNonIndexed();if(s.translate(0,r/2,0),o.push(s),e.type===`dead`)for(let n=0;n<e.branchCount;n++){let r=.22+t.next()*.14,a=new il(.006,.02,r,5).toNonIndexed();a.translate(0,r/2,0);let s=.7+t.next()*.6,c=n/e.branchCount*Math.PI*2+t.next()*.8,l=.34+(n+t.next())/e.branchCount*.34;a.applyMatrix4(new G().makeRotationY(c).multiply(new G().makeRotationX(s)).setPosition(Math.sin(c)*i*.6,l,Math.cos(c)*i*.6)),o.push(a)}let c=iM(o);return oM(c,new K(n),.7,1.05,t),c}function rM(e,t,n){if(!e.hasCanopy)return null;let r=[];if(e.type===`conifer`){let n=.74;for(let i=0;i<e.canopyLayers;i++){let a=i/e.canopyLayers,o=.3*(1-a*.62)*(.92+t.next()*.16),s=n/e.canopyLayers*1.7,c=new al(o,s,e.canopySegments).toNonIndexed();aM(c,t,eM),c.translate(0,.26+n*a+s/2,0),r.push(c)}for(let n=0;n<e.branchCount;n++){let i=new al(.06,.2,5).toNonIndexed(),a=n/Math.max(e.branchCount,1)*Math.PI*2+t.next(),o=1.1+t.next()*.4;i.applyMatrix4(new G().makeRotationY(a).multiply(new G().makeRotationX(o)).setPosition(Math.sin(a)*.22,.34+t.next()*.18,Math.cos(a)*.22)),r.push(i)}}else{let{trunkHeight:n}=tM[e.type];for(let i=0;i<e.blobCount;i++){let a=new sl((i===0?.3:.24-i*.02)*(.92+t.next()*.16),e.blobDetail).toNonIndexed();a.scale(1,.72,1),aM(a,t,eM);let o=i===0?0:.13,s=t.next()*Math.PI*2;a.translate(Math.cos(s)*o,n+.16+i*.1+t.next()*.05,Math.sin(s)*o),r.push(a)}}let i=iM(r);return oM(i,new K(n),.62,1.18,t),i}function iM(e){let t=0;for(let n of e)t+=n.getAttribute(`position`).count;let n=new Float32Array(t*3),r=new Float32Array(t*3),i=0;for(let t of e)n.set(t.getAttribute(`position`).array,i),r.set(t.getAttribute(`normal`).array,i),i+=t.getAttribute(`position`).count*3,t.dispose();let a=new J;return a.setAttribute(`position`,new q(n,3)),a.setAttribute(`normal`,new q(r,3)),a}function aM(e,t,n){let r=e.getAttribute(`position`);for(let e=0;e<r.count;e++)r.setXYZ(e,r.getX(e)+t.range(-n,n),r.getY(e)+t.range(-n,n),r.getZ(e)+t.range(-n,n))}function oM(e,t,n,r,i){let a=e.getAttribute(`position`),o=new Float32Array(a.count*3),s=1/0,c=-1/0;for(let e=0;e<a.count;e++){let t=a.getY(e);t<s&&(s=t),t>c&&(c=t)}let l=Math.max(c-s,1e-6),u=new K;for(let e=0;e<a.count;e++){let c=(a.getY(e)-s)/l,d=(n+(r-n)*c)*(.96+i.next()*.08);u.copy(t).multiplyScalar(d),o[e*3]=u.r,o[e*3+1]=u.g,o[e*3+2]=u.b}e.setAttribute(`color`,new q(o,3))}var sM=500,cM=15e5,lM=[.8,1.2],uM=.28,dM=.12,fM=.055,pM=.11,mM=3,hM=101,gM=[.78,.7,.45],_M=.45,vM=.55,yM=`https://agent8-games.verse8.io/assets/3D/default/textures/vegetation`,bM=`https://agent8-games.verse8.io/assets/3D/default/textures/vegetation/bark`,xM={high:{conifer:[`pine`,`pine`,`pine`],broadleaf:[`oak`,`ash`,`oak`],dead:[`ash`,`ash`,`ash`],bush:[`bush`,`bush`,`bush`]},medium:{conifer:[`pine-forest`,`pine-forest`,`pine-forest`],broadleaf:[`oak-forest`,`ash-forest`,`oak-forest`],dead:[`ash-forest`,`ash-forest`,`ash-forest`],bush:[`bush-forest`,`bush-forest`,`bush-forest`]}},SM=class e extends Oh{static typeName=`Tree3D`;static props={tier:{default:`medium`,options:Hj},type:{default:`conifer`,options:Uj},seed:{default:1},height:{default:6},count:{default:1},area:{default:[10,10]},trunkColor:{default:`#7a5a3a`},canopyColor:{default:`#4a7c3f`},leafTexture:{default:``},leafFadeStart:{default:0},leafFadeEnd:{default:0},leafShadows:{default:!0},drape:{default:null},terrain:{default:``,nodePath:!0}};tier=`medium`;type=`conifer`;seed=1;height=6;count=1;area=[10,10];trunkColor=`#7a5a3a`;canopyColor=`#4a7c3f`;leafTexture=``;leafFadeStart=0;leafFadeEnd=0;leafShadows=!0;drape=null;terrain=``;drapeTerrain=null;drapeWorld=[0,0,0];static validateJson(e){let t=e;if($j(t.tier,t.type),!(t.height>0))throw new N(`BAD_FORMAT`,`Tree3D '${e.name}' height must be > 0 meters, got ${t.height}.`,{prop:`height`});if(!Number.isInteger(t.count)||t.count<1||t.count>sM)throw new N(`BAD_FORMAT`,`Tree3D '${e.name}' count must be an integer in 1..${sM}, got ${t.count}.`,{prop:`count`});if(!((t.area[0]??0)>0)||!((t.area[1]??0)>0))throw new N(`BAD_FORMAT`,`Tree3D '${e.name}' area must be positive [x, z] meters, got ${JSON.stringify(t.area)}.`,{prop:`area`});if(t.leafFadeEnd!==0&&!(t.leafFadeEnd>t.leafFadeStart&&t.leafFadeStart>=0))throw new N(`BAD_FORMAT`,`Tree3D '${e.name}' needs leafFadeEnd > leafFadeStart >= 0 (the leaf LOD window) or 0/0 to disable, got start ${t.leafFadeStart}, end ${t.leafFadeEnd}.`,{prop:`leafFadeStart`});if(typeof t.leafShadows!=`boolean`)throw new N(`BAD_FORMAT`,`Tree3D '${e.name}' leafShadows must be a boolean, got ${JSON.stringify(t.leafShadows)}.`,{prop:`leafShadows`});if(t.drape!==null&&typeof t.drape!=`boolean`)throw new N(`BAD_FORMAT`,`Tree3D '${e.name}' drape must be true, false or null (null = auto: drape whenever the scene has a Terrain3D), got ${JSON.stringify(t.drape)}.`,{prop:`drape`});if(typeof t.terrain!=`string`)throw new N(`BAD_FORMAT`,`Tree3D '${e.name}' terrain must be a node-path string (empty = auto-find), got ${JSON.stringify(t.terrain)}.`,{prop:`terrain`});if(t.tier===`simple`)return;let n=TM(t.tier,t.type),r=n*t.count;if(r>cM)throw new N(`BAD_FORMAT`,`Tree3D '${e.name}' blows the grove triangle budget: count ${t.count} × ${n} tris/tree (tier '${t.tier}', type '${t.type}') = ${r} > ${cM}. Lower count (max ${Math.floor(cM/n)} at this tier), drop tier to 'medium'/'simple', or split the grove into multiple nodes.`,{prop:`count`})}time=0;grove=null;variants=[];simpleTrunk=null;simpleCanopy=null;swayUniform=null;leafFadeUniform=null;loadedTextures=[];groveKey=``;_createObject3D(){return new _o}_trunk(){return this.rebuildIfNeeded(),this.simpleTrunk??this.variants[0]?.branches}_canopy(){return this.rebuildIfNeeded(),this.simpleTrunk?this.simpleCanopy:this.variants[0]?.leaves??null}_variantMeshes(){return this.rebuildIfNeeded(),this.variants}update(e){this.time+=e,this.swayUniform&&(this.swayUniform.value=this.time),this.leafFadeUniform&&(this.leafFadeUniform.start.value=this.leafFadeStart,this.leafFadeUniform.end.value=this.leafFadeEnd)}_syncObject3D(){super._syncObject3D(),this.rebuildIfNeeded()}rebuildIfNeeded(){this.grove||(this.grove=new _o,this._ensureObject3D().add(this.grove));let e=JSON.stringify([this.tier,this.type,this.seed,this.height,this.count,this.area,this.trunkColor,this.canopyColor,this.leafTexture,this.leafShadows,this.leafFadeEnd>this.leafFadeStart,this.drape,this.terrain]);e===this.groveKey&&(this.simpleTrunk||this.variants.length>0)||(this.groveKey=e,this.disposeMeshes(),this.resolveDrape(),this.tier===`simple`?this.buildSimpleGrove():this.buildEzGrove())}resolveDrape(){if(this.drapeTerrain=null,this.drape===!1)return;let e=XD(this,this.terrain);if(e)this.drapeTerrain=e,this.drapeWorld=YD(this);else if(this.terrain!==``)throw new N(`NODE_NOT_FOUND`,`Tree3D '${this.name}' drape terrain '${this.terrain}' is not a Terrain3D in the tree.`,{prop:`terrain`})}bedY(e,t){let n=this.drapeTerrain;return n?n.heightAt(this.drapeWorld[0]+e,this.drapeWorld[2]+t)-this.drapeWorld[1]:0}buildSimpleGrove(){let e=$j(this.tier,this.type),t=new P(this.seed),n=nM(e,t,this.trunkColor),r=rM(e,t,this.canopyColor),i=new xc(n,jM(),this.count);NM(i);let a=null;r&&(a=new xc(r,jM(),this.count),NM(a)),this.scatter(t,(e,t,n)=>{i.setMatrixAt(e,t),i.setColorAt(e,n),a?.setMatrixAt(e,t),a?.setColorAt(e,n)}),MM(i),a&&MM(a),this.simpleTrunk=i,this.simpleCanopy=a,this.grove.add(i),a&&this.grove.add(a)}buildEzGrove(){let e=xM[this.tier][this.type],t=Math.min(mM,this.count),n=Array.from({length:t},(e,n)=>Math.floor(this.count/t)+ +(n<this.count%t));this.swayUniform={value:this.time},this.leafFadeUniform=this.leafFadeEnd>this.leafFadeStart?{start:{value:this.leafFadeStart},end:{value:this.leafFadeEnd}}:null;let r=OM(this.canopyColor),i=null;typeof document<`u`&&typeof createImageBitmap==`function`&&(i=new wu,i.setOptions({imageOrientation:`flipY`}));for(let a=0;a<t;a++){let t=n[a],o=e[a],s=bj(o);this.type===`dead`&&(s.leaves.count=0);let c=Mj(s,this.seed+a*hM,1),l=this.buildBarkMaterial(o,i),u=new xc(c.branches,l,t);NM(u);let d=null;if(c.leaves){let e=new bl({color:r.clone().multiply(new K(gM[0],gM[1],gM[2])),roughness:1,side:2,vertexColors:!0,alphaTest:s.leaves.alphaTest}),n=this.leafTexture||EM(s.leaves.style);i&&(e.map=wM(i,n,e=>{e.colorSpace=Oi,e.flipY=!1},e=>DM(e))),VO(e,this.swayUniform,_M,this.leafFadeUniform??void 0),d=new xc(c.leaves,e,t),d.userData.incantoWaterPassSkip=!0,NM(d),this.leafShadows||(d.castShadow=!1)}this.variants.push({branches:u,leaves:d}),this.grove.add(u),d&&this.grove.add(d)}let a=Array(t).fill(0),o=new P(this.seed);this.scatter(o,(e,n,r)=>{let i=e%t,o=this.variants[i],s=a[i];a[i]=s+1,o.branches.setMatrixAt(s,n),o.branches.setColorAt(s,r),o.leaves?.setMatrixAt(s,n),o.leaves?.setColorAt(s,r)});for(let e of this.variants)MM(e.branches),e.leaves&&MM(e.leaves)}buildBarkMaterial(t,n){if(this.type===`dead`||!n)return new bl({color:new K(this.trunkColor),roughness:1});let r=Sj(t),i=new bl({color:this.trunkColor===e.props.trunkColor?.default?new K(r.tint):AM(this.trunkColor),roughness:1});return BO(i,vM),i.map=this.loadBarkTexture(n,r,`color`,!0),i.normalMap=this.loadBarkTexture(n,r,`normal`,!1),i.roughnessMap=this.loadBarkTexture(n,r,`roughness`,!1),i}loadBarkTexture(e,t,n,r){return wM(e,`${bM}/${t.texture}_${n}_1k.jpg`,e=>{e.wrapS=er,e.wrapT=er,e.repeat.set(t.repeat[0],t.repeat[1]),e.anisotropy=4,e.flipY=!1,r&&(e.colorSpace=Oi)})}scatter(e,t){let n=(this.area[0]??0)/2,r=(this.area[1]??0)/2;for(let i=0;i<this.count;i++){let a=this.count===1?0:e.range(-n,n),o=this.count===1?0:e.range(-r,r);IM.set(a,this.drape?this.bedY(a,o):0,o),LM.setFromAxisAngle(PM,e.range(0,Math.PI*2));let s=this.height*e.range(lM[0],lM[1]),c=s*e.range(.9,1.1);RM.set(c,s,c),FM.compose(IM,LM,RM),zM.setHSL(uM,dM,.92).offsetHSL(e.range(-.055,fM),0,e.range(-.11,pM)),t(i,FM,zM)}}disposeMeshes(){let e=[this.simpleTrunk,this.simpleCanopy];for(let t of this.variants)e.push(t.branches,t.leaves);let t=new Set;for(let n of e)n&&(n.removeFromParent(),n.geometry.dispose(),t.add(n.material),n.dispose());for(let e of t)e.dispose();for(let e of this.loadedTextures)e.dispose();this.loadedTextures=[],this.simpleTrunk=null,this.simpleCanopy=null,this.variants=[],this.swayUniform=null,this.leafFadeUniform=null}free(){this.disposeMeshes(),this.grove=null,super.free()}},CM=new Map;function wM(e,t,n,r){let i=CM.get(t);if(i)return i;let a=new La;return n(a),e.load(t,e=>{a.image=e,r?r(a):a.needsUpdate=!0}),CM.set(t,a),a}function TM(e,t){let n=0;for(let r of new Set(xM[e][t]??[])){let e=bj(r);t===`dead`&&(e.leaves.count=0),n=Math.max(n,_j(e).total)}return n}function EM(e){return`${yM}/${e}_color.png`}function DM(e){let t=e.image;if(!t||typeof document>`u`)return;let n=document.createElement(`canvas`);n.width=t.naturalWidth||t.width,n.height=t.naturalHeight||t.height;let r=n.getContext(`2d`,{willReadFrequently:!0});if(!r)return;r.drawImage(t,0,0);let i;try{i=r.getImageData(0,0,n.width,n.height)}catch{return}let a=i.data,o=0,s=0,c=0,l=0;for(let e=0;e<a.length;e+=4)a[e+3]>240&&(o+=a[e],s+=a[e+1],c+=a[e+2],l++);if(l!==0){o=Math.round(o/l),s=Math.round(s/l),c=Math.round(c/l);for(let e=0;e<a.length;e+=4)a[e+3]<=240&&(a[e]=o,a[e+1]=s,a[e+2]=c);r.putImageData(i,0,0),e.image=n,e.needsUpdate=!0}}function OM(e){let t=new K(e),n=Math.max(t.r,t.g,t.b);return n>0?t.multiplyScalar(1/n):t.setRGB(1,1,1),t.lerp(kM,.18)}var kM=new K(1,1,1);function AM(e){let t=new K(e),n=Math.max(t.r,t.g,t.b);return n>0?t.multiplyScalar(1/n):t.setRGB(1,1,1),t}function jM(){return new bl({vertexColors:!0,roughness:1,flatShading:!0})}function MM(e){e.instanceMatrix.needsUpdate=!0,e.instanceColor&&(e.instanceColor.needsUpdate=!0),JD(e)}function NM(e){e.castShadow=!0,e.receiveShadow=!0}var PM=new U(0,1,0),FM=new G,IM=new U,LM=new H,RM=new U,zM=new K,BM=[[[.4,.4,.4],[.4,.4,.4],[.4,.4,.4],[.4,.4,.4],[.4,.4,.4],[.4,.4,.4]],[[.6,.3,0],[.6,.3,0],[.6,.3,0],[.6,.3,0],[0,.8,0],[.6,.3,0]],[[.6,.3,0],[.6,.3,0],[.6,.3,0],[.6,.3,0],[.6,.3,0],[.6,.3,0]],[[.6,.55,.5],[.55,.5,.45],[.5,.45,.4],[.55,.5,.45],[.65,.6,.55],[.5,.45,.4]],[[.45,.45,.4],[.4,.4,.35],[.35,.35,.3],[.4,.4,.35],[.5,.5,.45],[.35,.35,.3]],[[.2,.2,.2],[.2,.2,.2],[.2,.2,.2],[.2,.2,.2],[.2,.2,.2],[.2,.2,.2]],[[.8,.5,.2],[.75,.45,.15],[.7,.4,.1],[.75,.45,.15],[.85,.55,.25],[.7,.4,.1]],[[0,.7,.1],[0,.65,.1],[0,.6,.1],[0,.65,.1],[0,.75,.1],[0,.6,.1]],[[.3,.3,.3],[.3,.3,.3],[.3,.3,.3],[.3,.3,.3],[.3,.3,.3],[.3,.3,.3]],[[0,0,.7],[0,0,.7],[0,0,.7],[0,0,.7],[0,.2,.9],[0,0,.6]],[[.9,.3,0],[.9,.3,0],[.9,.3,0],[.9,.3,0],[1,.4,0],[.7,.2,0]],[[.9,.8,.2],[.85,.75,.18],[.85,.75,.18],[.85,.75,.18],[.95,.85,.25],[.85,.75,.18]],[[.6,.6,.6],[.55,.55,.55],[.5,.5,.5],[.55,.55,.55],[.65,.65,.65],[.5,.5,.5]],[[.7,.7,.4],[.65,.65,.35],[.6,.6,.3],[.65,.65,.35],[.75,.75,.45],[.6,.6,.3]],[[.7,.5,.5],[.65,.45,.45],[.6,.4,.4],[.65,.45,.45],[.75,.55,.55],[.6,.4,.4]],[[.35,.3,.25],[.3,.25,.2],[.25,.2,.15],[.3,.25,.2],[.4,.35,.3],[.25,.2,.15]],[[.5,.3,0],[.5,.3,0],[.5,.3,0],[.5,.3,0],[.7,.4,.1],[.7,.4,.1]],[[0,.5,0],[0,.45,0],[0,.45,0],[0,.45,0],[0,.6,0],[0,.4,0]],[[.2,.8,.8],[.15,.7,.7],[.1,.6,.6],[.15,.7,.7],[.3,.9,.9],[.1,.6,.6]],[[1,.5,.8],[.9,.4,.7],[.8,.3,.6],[.9,.4,.7],[1,.6,.9],[.8,.3,.6]],[[1,.9,.3],[.95,.85,.25],[.9,.8,.2],[.95,.85,.25],[1,1,.4],[.9,.8,.2]],[[1,0,0],[.9,0,0],[.8,0,0],[.9,0,0],[1,.2,.2],[.8,0,0]],[[.6,.4,.2],[.5,.3,.15],[.4,.25,.1],[.5,.3,.15],[.7,.45,.25],[.4,.25,.1]],[[.6,.2,.8],[.5,.15,.7],[.4,.1,.6],[.5,.15,.7],[.7,.25,.9],[.4,.1,.6]],[[1,.8,0],[.95,.75,0],[.95,.75,0],[.95,.75,0],[1,.9,0],[.9,.7,0]],[[.6,.65,.7],[.55,.6,.65],[.5,.55,.6],[.55,.6,.65],[.65,.7,.75],[.5,.55,.6]]],VM=2e5,HM=class extends Oh{static typeName=`VoxelGrid3D`;static signals=[`blocksChanged`];static props={voxels:{default:[]}};voxels=[];appliedVoxels=null;map=new Map;mesh=null;dirty=!1;blockCount(){return this.map.size}tileAt(e,t,n){return this.map.get(`${e},${t},${n}`)}setBlocks(e){this.map.clear();for(let t of e)this.map.set(`${t.x},${t.y},${t.z}`,t.tile);this.dirty=!0,this.emit(`blocksChanged`)}addBlock(e){this.map.set(`${e.x},${e.y},${e.z}`,e.tile),this.dirty=!0,this.emit(`blocksChanged`)}removeBlockAt(e,t,n){let r=this.map.delete(`${e},${t},${n}`);return r&&(this.dirty=!0,this.emit(`blocksChanged`)),r}blocks(){let e=[];for(let[t,n]of this.map){let[r,i,a]=t.split(`,`).map(Number);e.push({x:r,y:i,z:a,tile:n})}return e}_createObject3D(){let e=new nl(1,1,1),t=new vl({vertexShader:WM,fragmentShader:GM});this.mesh=new xc(e,t,VM),this.mesh.count=0,this.mesh.frustumCulled=!1;for(let e of UM)this.mesh.geometry.setAttribute(e,new pc(new Float32Array(VM*3),3));return this.dirty=!0,this.mesh}update(){if(this.voxels.length>0&&this.voxels!==this.appliedVoxels&&(this.appliedVoxels=this.voxels,this.setBlocks(this.voxels.map(e=>({x:e[0]??0,y:e[1]??0,z:e[2]??0,tile:e[3]??0})))),!this.dirty||!this.mesh)return;this.dirty=!1;let e=new G,t=0;for(let[n,r]of this.map){if(t>=VM)break;let[i,a,o]=n.split(`,`).map(Number);e.setPosition(i,a,o),this.mesh.setMatrixAt(t,e);let s=BM[r]??BM[0];for(let e=0;e<6;e++){let n=this.mesh.geometry.getAttribute(UM[e]),r=s[e];n.setXYZ(t,r[0],r[1],r[2]),n.needsUpdate=!0}t++}this.mesh.count=t,this.mesh.instanceMatrix.needsUpdate=!0}},UM=[`colorFront`,`colorRight`,`colorBack`,`colorLeft`,`colorTop`,`colorBottom`],WM=`
|
|
7897
|
+
`,KA=1.25,qA=4,JA=12,YA=1.5,XA=.35,ZA=1.2,QA=8,$A=.5,ej=.35,tj=42,nj=26,rj=6,ij=.05,aj=1.5,oj={shallow:`#74b2a2`,deep:`#123f4b`,sky:`#8ab6d8`,horizon:`#9fb6c2`,bank:`#465447`},sj=`#e9f2ef`,cj=new U,lj={rippleScale:.85,rippleStrength:.09,flowRate:.42,fresnelScale:.95,standingAmp:.11,glideAmp:.025},uj=class e extends Ah{static typeName=`River3D`;static props={path:{default:[]},width:{default:6},widths:{default:[]},depth:{default:.8},flowSpeed:{default:1.6},colors:{default:{}},absorption:{default:.5},opacity:{default:.85},foam:{default:1},ripples:{default:1},sunDirection:{default:[.5,.8,.3]},sunColor:{default:`#fff6e0`},sunIntensity:{default:1},terrain:{default:``,nodePath:!0},carve:{default:!0},flowForce:{default:1},spray:{default:1}};path=[];width=6;widths=[];depth=.8;flowSpeed=1.6;colors={};absorption=.5;opacity=.85;foam=1;ripples=1;sunDirection=[.5,.8,.3];sunColor=`#fff6e0`;sunIntensity=1;terrain=``;carve=!0;flowForce=1;spray=1;renderOrder=1;time=0;rings=[];falls=[];sprayKey=``;courseKey=``;bedAt=null;fitted=!1;bounds=null;boundsKey=``;rocks=[];rockScanAt=-1;world=[0,0,0];_bodies=[];static validateJson(e){let t=e;if(!Array.isArray(t.path))throw new N(`BAD_FORMAT`,`River3D '${e.name}' path must be an array of [x, z] points, got ${JSON.stringify(t.path)}.`,{prop:`path`});if(t.path.length>0&&t.path.length<2)throw new N(`BAD_FORMAT`,`River3D '${e.name}' path needs at least 2 points (source → mouth), got ${t.path.length}.`,{prop:`path`});if(t.path.forEach((t,n)=>{if(!Array.isArray(t)||t.length<2||!Number.isFinite(t[0])||!Number.isFinite(t[1]))throw new N(`BAD_FORMAT`,`River3D '${e.name}' path[${n}] must be [x, z] with finite numbers, got ${JSON.stringify(t)}.`,{prop:`path`})}),!(typeof t.width==`number`&&t.width>0))throw new N(`BAD_FORMAT`,`River3D '${e.name}' width must be a positive number of meters, got ${JSON.stringify(t.width)}.`,{prop:`width`});if(!Array.isArray(t.widths)||t.widths.some(e=>!(typeof e==`number`&&e>0)))throw new N(`BAD_FORMAT`,`River3D '${e.name}' widths must be a list of positive meters (source→mouth), got ${JSON.stringify(t.widths)}.`,{prop:`widths`});if(!(t.depth>0))throw new N(`BAD_FORMAT`,`River3D '${e.name}' depth must be > 0 meters, got ${JSON.stringify(t.depth)}.`,{prop:`depth`});if(!(t.flowSpeed>=0))throw new N(`BAD_FORMAT`,`River3D '${e.name}' flowSpeed must be >= 0 m/s, got ${JSON.stringify(t.flowSpeed)}.`,{prop:`flowSpeed`});for(let n of[`absorption`,`foam`,`ripples`,`flowForce`,`spray`,`sunIntensity`]){let r=t[n];if(!(typeof r==`number`&&r>=0))throw new N(`BAD_FORMAT`,`River3D '${e.name}' ${n} must be a number >= 0, got ${JSON.stringify(r)}.`,{prop:n})}if(!(t.opacity>=0&&t.opacity<=1))throw new N(`BAD_FORMAT`,`River3D '${e.name}' opacity must be within [0, 1], got ${JSON.stringify(t.opacity)}.`,{prop:`opacity`});let n=t.colors;if(typeof n!=`object`||!n||Array.isArray(n))throw new N(`BAD_FORMAT`,`River3D '${e.name}' colors must be an object of { shallow, deep, sky, horizon, bank } hex strings.`,{prop:`colors`});for(let t of Object.keys(n)){if(!(t in oj))throw new N(`BAD_FORMAT`,`River3D '${e.name}' colors has unknown key '${t}' — expected shallow, deep, sky, horizon or bank.`,{prop:`colors`});if(typeof n[t]!=`string`)throw new N(`BAD_FORMAT`,`River3D '${e.name}' colors.${t} must be a hex string, got ${JSON.stringify(n[t])}.`,{prop:`colors`})}}_createObject3D(){return new Ys(new J,this.buildMaterial())}onReady(){this.ensureCourse()}onExitTree(){QD(this,this.terrain)?._setExternalChannel(this,null)}update(e){this.time+=e,this.ensureCourse(),this.syncSpray(),this.flowForce>0&&this.rings.length>1&&this.sweepBodies(e)}_syncObject3D(){super._syncObject3D();let e=this._ensureObject3D();this.rebuildIfNeeded(e),this.syncUniforms(e)}_onRender3D(e){if(this.rings.length===0)return;(this.rockScanAt<0||this.time-this.rockScanAt>$A)&&(this.rockScanAt=this.time,this.scanRocks());let t=this._ensureObject3D().material.uniforms;this.syncRocks(t,e.camera.getWorldPosition(cj))}_waterYAt(e,t){if(this.rings.length===0)return null;let[n,r,i]=this.world,a=e-n,o=t-i,s=this.ringBounds();if(a<s.minX||a>s.maxX||o<s.minZ||o>s.maxZ)return null;let c=RA(this.rings,a,o);return c?.inside?c.surfaceY+r:null}ringBounds(){if(this.boundsKey===this.courseKey&&this.bounds)return this.bounds;let e=1/0,t=-1/0,n=1/0,r=-1/0,i=0;for(let a of this.rings)a.x<e&&(e=a.x),a.x>t&&(t=a.x),a.z<n&&(n=a.z),a.z>r&&(r=a.z),i=Math.max(i,a.halfLeft,a.halfRight);return this.bounds={minX:e-i,maxX:t+i,minZ:n-i,maxZ:r+i},this.boundsKey=this.courseKey,this.bounds}sampleAt(e,t){if(this.ensureCourse(),this.rings.length===0)return null;let[n,r,i]=this.world,a=RA(this.rings,e-n,t-i);return a?{...a,surfaceY:a.surfaceY+r}:null}fallsAt(){this.ensureCourse();let[e,t,n]=this.world;return this.falls.map(r=>({...r,worldX:r.x+e,worldY:r.baseY+t,worldZ:r.z+n}))}_rings(){return this.rings}_applySunDirection(t){let n=e.props.sunDirection?.default;this.sunDirection.every((e,t)=>e===n[t])&&(this._ensureObject3D().material.uniforms?.uSunDirection?.value)?.set(t[0],t[1],t[2])}free(){let e=this._ensureObject3D();e.geometry?.dispose(),e.material?.dispose?.(),super.free()}widthProfile(){return this.widths.length>0?this.widths:[this.width]}applyCarve(e){if(!e)return;if(!this.carve||this.path.length<2){e._setExternalChannel(this,null);return}e._setExternalChannel(this,null);let[t,,n]=ZD(this),[r,,i]=ZD(e),a=e._heightmap();e._setExternalChannel(this,pA({path:this.path.map(e=>[(e[0]??0)+t-r,(e[1]??0)+n-i]),widths:this.widthProfile(),depth:this.depth,cell:(e.size[0]??1)/Math.max(1,a.segsX),groundAt:(e,t)=>a.heightAt(e,t)}))}resolveTerrain(){let e=QD(this,this.terrain);if(!e&&this.terrain!==``)throw new N(`NODE_NOT_FOUND`,`River3D '${this.name}' terrain '${this.terrain}' is not a Terrain3D in the tree.`,{prop:`terrain`});return e}ensureCourse(){let e=this.resolveTerrain(),t=ZD(this),n=JSON.stringify([this.path,this.width,this.widths,this.depth,this.flowSpeed,this.carve,e?e.name:``,t]);if(n===this.courseKey)return!1;if(this.courseKey=n,this.world=t,this.bedAt=null,this.applyCarve(e),this.path.length<2)return this.rings=[],this.falls=[],!0;let[r,i,a]=t;this.bedAt=e?(t,n)=>e.heightAt(t+r,n+a)-i:()=>-this.depth,this.fitted=e!==null;let o=this.widthProfile();return this.rings=FA({path:this.path,widths:o,depth:this.depth,flowSpeed:this.flowSpeed,step:PA(o,this.depth),bedAt:this.bedAt,fit:this.fitted}),this.falls=VA(this.rings),this.warnUncoveredWater(),!0}warnUncoveredWater(){if(this.warnedCoverage)return;let e=hA(this.rings);if(e.length*3<this.rings.length)return;this.warnedCoverage=!0;let t=e.reduce((e,t)=>t.wettedHalfWidth-t.carriedHalfWidth>e.wettedHalfWidth-e.carriedHalfWidth?t:e);this.diagnose(`warn`,`[incanto] River3D '${this.name}': the course is too tight for the water it holds — ${e.length} of ${this.rings.length} stations leave bare channel beside the ribbon (worst at ${t.along.toFixed(0)} m: ground wet to ${t.wettedHalfWidth.toFixed(1)} m from the centre, a bend that can only carry ${t.carriedHalfWidth.toFixed(1)} m). Fix by EASING THE BENDS in \`path\` (fewer, straighter points), NARROWING \`widths\` there, or placing standing water (a Water3D) if that reach is really a pool.`)}warnedCoverage=!1;rebuildIfNeeded(e){if(!this.ensureCourse()&&e.geometry.getAttribute(`position`))return;if(this.rings.length===0||!this.bedAt){e.geometry.dispose();let t=new J;t.setAttribute(`position`,new q(new Float32Array,3)),e.geometry=t;return}let t=this.widthProfile(),n=Math.min(...t),r=Math.max(...t),i=IA(this.rings,{acrossSegments:Math.min(JA,Math.max(qA,Math.round(r/YA))),bankOvershoot:this.fitted?1:KA,bedBlur:Math.min(n/2*XA,ZA),bedAt:this.bedAt}),a=new J;a.setAttribute(`position`,new q(i.positions,3)),a.setAttribute(`normal`,new q(i.normals,3)),a.setAttribute(`aFlowUv`,new q(i.uvs,2)),a.setAttribute(`aFlow`,new q(i.flow,2)),a.setAttribute(`aRiver`,new q(i.river,4)),a.setIndex(new q(i.indices,1)),a.computeBoundingSphere(),e.geometry.dispose(),e.geometry=a}buildMaterial(){return new vl({vertexShader:WA,fragmentShader:GA,fog:!0,uniforms:{fogColor:{value:new K(`#ffffff`)},fogNear:{value:1},fogFar:{value:1e3},fogDensity:{value:25e-5},uTime:{value:0},uShallowColor:{value:new K(oj.shallow)},uDeepColor:{value:new K(oj.deep)},uFoamColor:{value:new K(sj)},uSkyColor:{value:new K(oj.sky)},uHorizonColor:{value:new K(oj.horizon)},uBankColor:{value:new K(oj.bank)},uSunDirection:{value:new U(.5,.8,.3)},uSunColor:{value:new K(this.sunColor)},uSunIntensity:{value:this.sunIntensity},uMaxDepth:{value:this.depth},uAbsorption:{value:this.absorption},uOpacity:{value:this.opacity},uFoam:{value:this.foam},uRippleScale:{value:lj.rippleScale},uRippleStrength:{value:lj.rippleStrength*this.ripples},uFlowRate:{value:lj.flowRate},uSparkle:{value:this.ripples},uRockCount:{value:0},uRocks:{value:Array.from({length:QA},()=>new Ra)},uFresnelScale:{value:lj.fresnelScale},uStandingAmp:{value:lj.standingAmp},uGlideAmp:{value:lj.glideAmp}},transparent:!0,depthTest:!0,depthWrite:!1,side:2})}scanRocks(){let e=[],[t,n,r]=this.world,i=(i,a,o,s,c)=>{if(o<=.02)return;let l=RA(this.rings,i-t,a-r);if(!l?.inside)return;let u=l.surfaceY+n;if(s>u||c<u-this.depth)return;let d=(c-u)/Math.max(this.depth*ej,.02),f=Math.min(Math.max(d+1,0),1);e.push({x:i,z:a,radius:o,breaks:f})},a=this;for(;a.parent;)a=a.parent;let o=e=>{if(e instanceof Fh||e instanceof Ph){let t=e.collider,n=zm(t),[r,a,o]=ZD(e);i(r,o,t?.shape===`box`?Math.max(t.size?.[0]??.4,t.size?.[2]??.4)/2:t?.radius??.35,a-n,a+n)}else if(e instanceof Mw){let[t,n,r]=e.size,[a,o,s]=ZD(e);for(let c of e.transforms){let e=c[4]??1,l=a+(c[0]??0),u=o+(c[1]??0),d=s+(c[2]??0),f=(n??1)*e/2;i(l,d,Math.max(t,r)*e/2,u-f,u+f)}}else if(e instanceof Ow){let[t,n,r]=e.size,[a,o,s]=ZD(e),c=(n??1)/2;i(a,s,Math.max(t,r)/2,o-c,o+c)}for(let t of e.children)o(t)};o(a),this.rocks=e}syncRocks(e,t){let n=e.uRocks?.value,r=e.uRockCount;if(!n||!r)return;if(this.rocks.length===0){r.value=0;return}let i=[...this.rocks].map(e=>({r:e,d:(e.x-t.x)**2+(e.z-t.z)**2})).sort((e,t)=>e.d-t.d).slice(0,QA),a=0;for(let{r:e,d:t}of i){let r=Math.max(e.radius*tj,nj),i=Math.min(Math.sqrt(t)/r,1),o=Math.min(Math.max((i-.6)/.4,0),1),s=1-o*o*(3-2*o);s<=.01||(n[a]?.set(e.x,e.z,e.radius,e.breaks*s),a++)}r.value=a}syncUniforms(e){let t=e.material.uniforms,n=(e,n)=>{let r=t[e];r&&(r.value=n)},r=(e,n)=>{(t[e]?.value)?.set(n)},i=this.colors;n(`uTime`,this.time),r(`uShallowColor`,i.shallow??oj.shallow),r(`uDeepColor`,i.deep??oj.deep),r(`uSkyColor`,i.sky??oj.sky),r(`uHorizonColor`,i.horizon??oj.horizon),r(`uBankColor`,i.bank??oj.bank),r(`uSunColor`,this.sunColor),(t.uSunDirection?.value)?.set(this.sunDirection[0]??.5,this.sunDirection[1]??.8,this.sunDirection[2]??.3),n(`uSunIntensity`,this.sunIntensity),n(`uMaxDepth`,this.depth),n(`uAbsorption`,this.absorption),n(`uOpacity`,this.opacity),n(`uFoam`,this.foam),n(`uRippleStrength`,lj.rippleStrength*this.ripples),n(`uSparkle`,this.ripples)}syncSpray(){let e=this.spray>0?`${this.spray}|${JSON.stringify(this.falls)}`:``;if(e!==this.sprayKey){this.sprayKey=e;for(let e of[...this.children])e.name.startsWith(`__spray`)&&e.free();this.spray<=0||this.falls.forEach((e,t)=>{let n=new eA(`__spray${t}`);n.position=[e.x+e.dirX*.6,e.baseY+.15,e.z+e.dirZ*.6];let r=Math.min(1.6,.4+e.drop*.12)*this.spray;n.rate=Math.round(Math.min(22,5+e.drop*1.6)*this.spray),n.maxParticles=160,n.lifetime=[1,2.1],n.speed=[45*r,130*r],n.directionDeg=-90,n.spreadDeg=52,n.gravity=[0,-240,0],n.drag=1.2,n.sizeStart=7*r,n.sizeEnd=30*r,n.colorStart=`#ffffff`,n.colorEnd=`#dfe9ec`,n.alphaStart=.085,n.alphaEnd=0,n.blend=`normal`,n.depthTest=!0,this.addChild(n)})}}sweepBodies(e){let t=this;for(;t.parent;)t=t.parent;let n=this._bodies;if(n.length=0,dj(t,n),n.length===0)return;let[r,i,a]=this.world;for(let t of n){let n=ZD(t),o=RA(this.rings,n[0]-r,n[2]-a);if(!o?.inside)continue;let s=o.surfaceY+i,c=n[1]-zm(t.collider);if(c>s+ij||c<s-this.depth-aj)continue;let l=fj(t);if(!l)continue;let u=Math.min(1,this.flowForce*rj*e),d=(o.dirX*o.speed-(l[0]??0))*u,f=(o.dirZ*o.speed-(l[2]??0))*u;if(t instanceof Ph){let e=t.mass||1;t.applyImpulse([d*e,0,f*e])}else l[0]=(l[0]??0)+d,l[2]=(l[2]??0)+f}}};function dj(e,t){(e instanceof Fh||e instanceof Ph)&&t.push(e);for(let n of e.children)dj(n,t)}function fj(e){return e.velocity??e.linearVelocity}var pj=128,mj=class extends Ah{static typeName=`Trail3D`;static props={width:{default:.3},color:{default:`#ffffff`},opacity:{default:.8},seconds:{default:.6},emitting:{default:!0},additive:{default:!1},minDistance:{default:.05}};width=.3;color=`#ffffff`;opacity=.8;seconds=.6;emitting=!0;additive=!1;minDistance=.05;points=[];clock=0;mesh=null;lastColor=``;_createObject3D(){let e=new _o,t=new J;t.setAttribute(`position`,new q(new Float32Array(pj*2*3),3));let n=new Ls({color:this.color,transparent:!0,opacity:this.opacity,side:2,depthWrite:!1,blending:this.additive?2:1});return this.mesh=new Ys(t,n),this.mesh.frustumCulled=!1,this.mesh.matrixAutoUpdate=!1,this.mesh.matrixWorld.identity(),this.mesh.updateMatrixWorld=()=>{},e.add(this.mesh),e}update(e){for(this.clock+=e;this.points.length>0&&this.clock-this.points[0].t>this.seconds;)this.points.shift()}_onRender3D(e){let t=this._ensureObject3D();if(this.emitting){t.getWorldPosition(hj);let e=this.points[this.points.length-1];(!e||(e.x-hj.x)**2+(e.y-hj.y)**2+(e.z-hj.z)**2>this.minDistance*this.minDistance)&&(this.points.push({x:hj.x,y:hj.y,z:hj.z,t:this.clock}),this.points.length>pj&&this.points.shift())}let n=this.mesh;if(!n)return;n.matrixWorld.identity();let r=n.material;this.color!==this.lastColor&&(this.lastColor=this.color,r.color=new K(this.color)),r.opacity=this.opacity;let i=this.points.length,a=n.geometry,o=a.getAttribute(`position`);if(i<2){a.setDrawRange(0,0);return}for(let t=0;t<i;t++){let n=this.points[t],r=this.points[Math.min(t+1,i-1)]??n;gj.set(r.x-n.x,r.y-n.y,r.z-n.z),gj.lengthSq()<1e-8&&gj.set(0,1,0),_j.set(e.camera.position.x-n.x,e.camera.position.y-n.y,e.camera.position.z-n.z),vj.crossVectors(gj,_j).normalize();let a=(this.clock-n.t)/this.seconds,s=this.width/2*Math.max(0,1-a);o.setXYZ(t*2,n.x+vj.x*s,n.y+vj.y*s,n.z+vj.z*s),o.setXYZ(t*2+1,n.x-vj.x*s,n.y-vj.y*s,n.z-vj.z*s)}if(o.needsUpdate=!0,!a.index||a.index.count<(pj-1)*6){let e=[];for(let t=0;t<pj-1;t++){let n=t*2;e.push(n,n+1,n+2,n+1,n+3,n+2)}a.setIndex(e)}a.setDrawRange(0,(i-1)*6)}get pointCount(){return this.points.length}},hj=new U,gj=new U,_j=new U,vj=new U;function yj(e){let{branch:t,leaves:n,type:r}=e,i=0,a=0,o=[{level:0,sections:t.sections[0],segments:t.segments[0]}];for(;o.length>0;){let e=o.shift();if(i+=e.sections*e.segments*2,e.level>=t.levels){a+=n.count===0?0:n.count+ +(r===`deciduous`);continue}r===`deciduous`&&o.push({level:e.level+1,sections:e.sections,segments:e.segments});let s=t.children[e.level]??0;for(let n=0;n<s;n++)o.push({level:e.level+1,sections:t.sections[e.level+1]??1,segments:t.segments[e.level+1]??3})}let s=n.billboard===`double`?2:1,c=a*s*2;return{branches:i,leaves:c,total:i+c}}var bj={ash:{type:`deciduous`,branch:{levels:3,angle:[0,48,75,60],children:[7,4,3,0],force:{direction:{x:0,y:1,z:0},strength:-.06},gnarliness:[.03,.25,.2,.09],length:[43.47,27.14,9.51,4.6],radius:[2,.63,.76,.7],sections:[12,8,6,4],segments:[12,6,4,3],start:[0,.23,.33,0],taper:[.7,.7,.7,.7],twist:[.09,-.07,0,0]},leaves:{style:`ash`,billboard:`double`,angle:55,count:16,start:0,size:2.67,sizeVariance:.72,alphaTest:.5}},aspen:{type:`deciduous`,branch:{levels:2,angle:[0,75,32,7],children:[10,3,3,0],force:{direction:{x:0,y:1,z:0},strength:.0148},gnarliness:[.05,.12,.12,.02],length:[50,6.07,11.19,1],radius:[.72,.41,.7,.7],sections:[12,10,8,6],segments:[8,6,4,3],start:[0,.59,.35,0],taper:[.37,.13,.7,.7],twist:[0,0,0,0]},leaves:{style:`aspen`,billboard:`double`,angle:30,count:11,start:.124,size:2.5,sizeVariance:.7,alphaTest:.5}},oak:{type:`deciduous`,branch:{levels:3,angle:[0,54,58,32],children:[6,4,3,0],force:{direction:{x:0,y:1,z:0},strength:-.01},gnarliness:[0,-.1,-.15,.09],length:[37.24,11.08,12.39,7.16],radius:[1.41,.9,.69,1.19],sections:[8,6,3,1],segments:[7,5,3,3],start:[0,.49,.06,.12],taper:[.73,.42,.69,.75],twist:[-.23,.42,0,0]},leaves:{style:`oak`,billboard:`double`,angle:42,count:18,start:.16,size:2.5,sizeVariance:.7,alphaTest:.5}},pine:{type:`evergreen`,branch:{levels:1,angle:[0,110,16,60],children:[82,3,5,0],force:{direction:{x:0,y:1,z:0},strength:-.003},gnarliness:[.05,.08,0,0],length:[50,23.87,14.08,1],radius:[1.05,.36,.7,.7],sections:[12,10,8,6],segments:[8,6,4,3],start:[0,.27,.14,.3],taper:[.7,.7,.7,.7],twist:[0,0,0,0]},leaves:{style:`pine`,billboard:`double`,angle:39,count:30,start:.09,size:1.435,sizeVariance:.201,alphaTest:.3}},bush:{type:`deciduous`,branch:{levels:3,angle:[0,21.5,62.6,60],children:[7,3,2,0],force:{direction:{x:0,y:1,z:0},strength:-.02},gnarliness:[.11,.09,.05,.09],length:[.1,15.3,5.59,4.6],radius:[.58,.95,.76,.7],sections:[6,6,4,3],segments:[4,4,4,3],start:[0,.53,.33,0],taper:[.7,.7,.7,.7],twist:[.3,-.07,0,0]},leaves:{style:`ash`,billboard:`double`,angle:55,count:8,start:0,size:2.45,sizeVariance:.717,alphaTest:.5}},"ash-forest":{type:`deciduous`,branch:{levels:2,angle:[0,48,75,60],children:[5,3,0,0],force:{direction:{x:0,y:1,z:0},strength:-.06},gnarliness:[.03,.25,.2,.09],length:[43.47,27.14,9.51,4.6],radius:[2,.63,.76,.7],sections:[6,5,4,4],segments:[6,4,3,3],start:[0,.3,.33,0],taper:[.7,.7,.7,.7],twist:[.09,-.07,0,0]},leaves:{style:`ash`,billboard:`double`,angle:55,count:15,start:0,size:3,sizeVariance:.6,alphaTest:.5}},"oak-forest":{type:`deciduous`,branch:{levels:2,angle:[0,54,58,32],children:[5,3,0,0],force:{direction:{x:0,y:1,z:0},strength:-.01},gnarliness:[0,-.1,-.15,.09],length:[37.24,11.08,12.39,7.16],radius:[1.41,.9,.69,1.19],sections:[6,4,3,1],segments:[6,4,3,3],start:[0,.49,.06,.12],taper:[.73,.42,.69,.75],twist:[-.23,.42,0,0]},leaves:{style:`oak`,billboard:`double`,angle:42,count:16,start:.1,size:2.9,sizeVariance:.7,alphaTest:.5}},"pine-forest":{type:`evergreen`,branch:{levels:1,angle:[0,110,16,60],children:[44,3,5,0],force:{direction:{x:0,y:1,z:0},strength:-.005},gnarliness:[.07,.09,0,0],length:[50,23.87,14.08,1],radius:[1.05,.36,.7,.7],sections:[6,5,8,6],segments:[6,3,4,3],start:[0,.27,.14,.3],taper:[.7,.7,.7,.7],twist:[0,0,0,0]},leaves:{style:`pine`,billboard:`double`,angle:39,count:9,start:.09,size:1.8,sizeVariance:.201,alphaTest:.3}},"bush-forest":{type:`deciduous`,branch:{levels:2,angle:[0,21.5,62.6,60],children:[6,3,0,0],force:{direction:{x:0,y:1,z:0},strength:-.02},gnarliness:[.11,.09,.05,.09],length:[.1,15.3,5.59,4.6],radius:[.58,.95,.76,.7],sections:[5,4,3,3],segments:[4,3,3,3],start:[0,.53,.33,0],taper:[.7,.7,.7,.7],twist:[.3,-.07,0,0]},leaves:{style:`ash`,billboard:`double`,angle:55,count:10,start:0,size:3.2,sizeVariance:.6,alphaTest:.5}}},xj=[`ash`,`aspen`,`oak`,`pine`,`bush`,`ash-forest`,`oak-forest`,`pine-forest`,`bush-forest`];function Sj(e){let t=bj[e];if(!t)throw new N(`BAD_FORMAT`,`Unknown eztree preset '${e}' — must be one of [${xj.join(`, `)}].`,{prop:`preset`,validOptions:xj});return structuredClone(t)}var Cj={ash:{texture:`oak`,tint:`#cecbbe`,repeat:[.5,1/5]},aspen:{texture:`birch`,tint:`#ffffff`,repeat:[1,1]},oak:{texture:`oak`,tint:`#fff3d1`,repeat:[1,1/10]},pine:{texture:`pine`,tint:`#ffffff`,repeat:[1,1]},bush:{texture:`oak`,tint:`#cecbbe`,repeat:[.5,1/5]}};function wj(e){if(!xj.includes(e))throw new N(`BAD_FORMAT`,`Unknown eztree preset '${e}' — must be one of [${xj.join(`, `)}].`,{prop:`preset`,validOptions:xj});return structuredClone(Cj[e.replace(/-forest$/,``)])}var Tj=.45,Ej=.45,Dj=.55,Oj=.15,kj=.07,Aj=.035;function jj(e,t){let n=Math.imul(e+1,374761393)+Math.imul(t+1,668265263)>>>0;return n=Math.imul(n^n>>>13,1274126177)>>>0,((n^n>>>16)>>>0)/4294967296}function Mj(e,t,n){let r=e.length/3,i=new Float32Array(e.length),a=new Float32Array(e.length),o=1/0,s=1/0,c=1/0,l=-1/0,u=-1/0,d=-1/0;for(let t=0;t<r;t++){let n=e[t*3],r=e[t*3+1],i=e[t*3+2];n<o&&(o=n),n>l&&(l=n),r<s&&(s=r),r>u&&(u=r),i<c&&(c=i),i>d&&(d=i)}let f=(o+l)/2,p=(s+u)/2,m=(c+d)/2,h=Math.max((l-o)/2,.001),g=Math.max((u-s)/2,.001),_=Math.max((d-c)/2,.001),v=new Map;for(let n=0;n<r;n++){let r=t[n],i=v.get(r);i||(i={x:0,y:0,z:0,n:0},v.set(r,i)),i.x+=e[n*3],i.y+=e[n*3+1],i.z+=e[n*3+2],i.n++}for(let e of v.values())e.x/=e.n,e.y/=e.n,e.z/=e.n;for(let o=0;o<r;o++){let r=e[o*3],c=e[o*3+1],l=e[o*3+2],d=(r-f)/h,y=(c-p)/g,b=(l-m)/_,x,S,C,w;if(n===`evergreen`){let e=Math.hypot(r-f,l-m);if(e<1e-6)x=0,S=1,C=0;else{let t=1/Math.hypot(1,Ej);x=(r-f)/e*t,S=Ej*t,C=(l-m)/e*t}let t=(c-s)/Math.max(u-s,.001),n=Math.max(Oj,1-t);w=Math.min(1,Math.hypot(d,b)/n)}else{let e=d/h,t=y/g,n=b/_,r=Math.hypot(e,t,n);r<1e-6?(x=0,S=1,C=0):(x=e/r,S=t/r,C=n/r),w=Math.min(1,Math.hypot(d,y,b))}let T=v.get(t[o]);if(T){let e=r-T.x,t=c-T.y,n=l-T.z,i=Math.hypot(e,t,n);if(i>1e-6){x=x*(1-Dj)+e/i*Dj,S=S*(1-Dj)+t/i*Dj,C=C*(1-Dj)+n/i*Dj;let r=Math.hypot(x,S,C);r>1e-6?(x/=r,S/=r,C/=r):(x=0,S=1,C=0)}}i[o*3]=x,i[o*3+1]=S,i[o*3+2]=C;let E=Tj+(1-Tj)*w,D=t[o],O=E*(1-kj*jj(D,1)),k=(jj(D,2)-.5)*2*Aj;a[o*3]=O*(1+k),a[o*3+1]=O,a[o*3+2]=O*(1-k)}return{normals:i,colors:a}}var Nj=class e{static MASK=4294967295;mW;mZ;constructor(t){this.mW=123456789+t&e.MASK,this.mZ=987654321-t&e.MASK}random(t=1,n=0){this.mZ=36969*(this.mZ&65535)+(this.mZ>>16)&e.MASK,this.mW=18e3*(this.mW&65535)+(this.mW>>16)&e.MASK;let r=((this.mZ<<16)+(this.mW&65535)>>>0)/4294967296;return(t-n)*r+n}};function Pj(e,t,n){let r=new Nj(t),i={branchVerts:[],branchNormals:[],branchUvs:[],branchIndices:[],leafVerts:[],leafIndices:[],leafUvs:[],leafAnchors:[],leafClusters:[],leafClusterNext:0},a=[{origin:new U,orientation:new Qa,length:e.branch.length[0],radius:e.branch.radius[0],level:0,sectionCount:e.branch.sections[0],segmentCount:e.branch.segments[0]}];for(;a.length>0;)Fj(e,r,i,a,a.shift());Hj(i,n);let o=new J;o.setAttribute(`position`,new q(new Float32Array(i.branchVerts),3)),o.setAttribute(`normal`,new q(new Float32Array(i.branchNormals),3)),o.setAttribute(`uv`,new q(new Float32Array(i.branchUvs),2)),o.setIndex(new q(Uj(i.branchIndices,i.branchVerts),1)),o.computeBoundingSphere();let s=null;if(i.leafVerts.length>0){s=new J,s.setAttribute(`position`,new q(new Float32Array(i.leafVerts),3)),s.setAttribute(`anchor`,new q(new Float32Array(i.leafAnchors),3)),s.setAttribute(`uv`,new q(new Float32Array(i.leafUvs),2)),s.setIndex(new q(Uj(i.leafIndices,i.leafVerts),1));let t=Mj(i.leafVerts,i.leafClusters,e.type);s.setAttribute(`normal`,new q(t.normals,3)),s.setAttribute(`color`,new q(t.colors,3)),s.computeBoundingSphere()}return{branches:o,leaves:s}}function Fj(e,t,n,r,i){let a=n.branchVerts.length/3,o=i.orientation.clone(),s=i.origin.clone(),c=i.length/i.sectionCount,l=[];for(let r=0;r<=i.sectionCount;r++){let a=i.radius;r===i.sectionCount&&i.level===e.branch.levels?a=.001:e.type===`deciduous`?a*=1-(e.branch.taper[i.level]??0)*(r/i.sectionCount):a*=1-r/i.sectionCount;let u=new U,d=new U,f=0;for(let e=0;e<i.segmentCount;e++){let t=2*Math.PI*e/i.segmentCount,c=new U(Math.cos(t),0,Math.sin(t)).multiplyScalar(a).applyEuler(o).add(s),l=new U(Math.cos(t),0,Math.sin(t)).applyEuler(o).normalize(),p=r%2==0?0:1;n.branchVerts.push(c.x,c.y,c.z),n.branchNormals.push(l.x,l.y,l.z),n.branchUvs.push(e/i.segmentCount,p),e===0&&(u=c,d=l,f=p)}n.branchVerts.push(u.x,u.y,u.z),n.branchNormals.push(d.x,d.y,d.z),n.branchUvs.push(1,f),l.push({origin:s.clone(),orientation:o.clone(),radius:a}),s.add(new U(0,c,0).applyEuler(o));let p=Math.max(1,1/Math.sqrt(a))*(e.branch.gnarliness[i.level]??0);o.x+=t.random(p,-p),o.z+=t.random(p,-p);let m=new H().setFromEuler(o),h=new H().setFromAxisAngle(new U(0,1,0),e.branch.twist[i.level]??0),g=e.branch.force,_=new H().setFromUnitVectors(new U(0,1,0),new U(g.direction.x,g.direction.y,g.direction.z));m.multiply(h),m.rotateTowards(_,g.strength/a),o.setFromQuaternion(m)}Vj(n,a,i);let u=i.level===e.branch.levels?n.leafClusterNext++:0;if(e.type===`deciduous`){let a=l[l.length-1];i.level<e.branch.levels?r.push({origin:a.origin,orientation:a.orientation,length:e.branch.length[i.level+1]??0,radius:a.radius,level:i.level+1,sectionCount:i.sectionCount,segmentCount:i.segmentCount}):e.leaves.count>0&&Bj(e,t,n,a.origin,a.orientation,u)}i.level===e.branch.levels?zj(e,t,n,l,u):i.level<e.branch.levels&&Rj(e,t,r,e.branch.children[i.level]??0,i.level+1,l)}function Ij(e,t){let n=Math.floor(t*(e.length-1)),r=e[n],i=n===e.length-1?r:e[n+1],a=(t-n/(e.length-1))/(1/(e.length-1)),o=new U().lerpVectors(r.origin,i.origin,a),s=new H().setFromEuler(r.orientation),c=new H().setFromEuler(i.orientation);return{origin:o,orientation:new Qa().setFromQuaternion(c.slerp(s,a)),radius:{a:r.radius,b:i.radius,alpha:a}}}function Lj(e,t,n){let r=new H().setFromAxisAngle(new U(1,0,0),t/(180/Math.PI)),i=new H().setFromAxisAngle(new U(0,1,0),n),a=new H().setFromEuler(e);return new Qa().setFromQuaternion(a.multiply(i.multiply(r)))}function Rj(e,t,n,r,i,a){let o=t.random();for(let s=0;s<r;s++){let c=t.random(1,e.branch.start[i]??0),l=Ij(a,c),u=(e.branch.radius[i]??0)*((1-l.radius.alpha)*l.radius.a+l.radius.alpha*l.radius.b),d=2*Math.PI*(o+s/r),f=Lj(l.orientation,e.branch.angle[i]??0,d),p=(e.branch.length[i]??0)*(e.type===`evergreen`?1-c:1);n.push({origin:l.origin,orientation:f,length:p,radius:u,level:i,sectionCount:e.branch.sections[i]??1,segmentCount:e.branch.segments[i]??3})}}function zj(e,t,n,r,i){let a=t.random();for(let o=0;o<e.leaves.count;o++){let s=Ij(r,t.random(1,e.leaves.start)),c=2*Math.PI*(a+o/e.leaves.count),l=Lj(s.orientation,e.leaves.angle,c);Bj(e,t,n,s.origin,l,i)}}function Bj(e,t,n,r,i,a){let o=n.leafVerts.length/3,s=e.leaves.size*(1+t.random(e.leaves.sizeVariance,-e.leaves.sizeVariance)),c=e=>{let t=s/2,c=[new U(-t,s,0),new U(-t,0,0),new U(t,0,0),new U(t,s,0)];for(let t of c)t.applyEuler(new Qa(0,e,0)).applyEuler(i).add(r),n.leafVerts.push(t.x,t.y,t.z),n.leafAnchors.push(r.x,r.y,r.z),n.leafClusters.push(a);n.leafUvs.push(0,1,0,0,1,0,1,1),n.leafIndices.push(o,o+1,o+2,o,o+2,o+3),o+=4};c(0),e.leaves.billboard===`double`&&c(Math.PI/2)}function Vj(e,t,n){let r=n.segmentCount+1;for(let i=0;i<n.sectionCount;i++)for(let a=0;a<n.segmentCount;a++){let n=t+i*r+a,o=t+i*r+(a+1),s=n+r,c=o+r;e.branchIndices.push(n,s,o,o,s,c)}}function Hj(e,t){let n=0;for(let t=1;t<e.branchVerts.length;t+=3){let r=e.branchVerts[t];r>n&&(n=r)}for(let t=1;t<e.leafVerts.length;t+=3){let r=e.leafVerts[t];r>n&&(n=r)}if(n<=0)return;let r=t/n;for(let t=0;t<e.branchVerts.length;t++)e.branchVerts[t]=e.branchVerts[t]*r;for(let t=0;t<e.leafVerts.length;t++)e.leafVerts[t]=e.leafVerts[t]*r;for(let t=0;t<e.leafAnchors.length;t++)e.leafAnchors[t]=e.leafAnchors[t]*r}function Uj(e,t){return t.length/3>65535?new Uint32Array(e):new Uint16Array(e)}var Wj=[`simple`,`medium`,`high`],Gj=[`conifer`,`broadleaf`,`dead`,`bush`];function Kj(e,t,n){return new N(`BAD_FORMAT`,`Tree3D ${e} must be one of [${n.join(`, `)}], got '${t}'.`,{prop:e,validOptions:n})}var qj={simple:0,medium:1,high:2},Jj=[5,7,10],Yj=[2,3,4],Xj=[6,8,12],Zj=[2,3,3],Qj=[0,1,2],$j=[3,4,5],eM=3;function tM(e,t){if(!Wj.includes(e))throw Kj(`tier`,e,Wj);if(!Gj.includes(t))throw Kj(`type`,t,Gj);let n=e,r=t,i=qj[n];return{tier:n,type:r,trunkRadialSegments:Jj[i],canopyLayers:r===`conifer`?Yj[i]:0,canopySegments:Xj[i],blobCount:r===`broadleaf`||r===`bush`?Zj[i]:0,blobDetail:Qj[i],branchCount:r===`dead`?$j[i]:r===`conifer`&&n===`high`?eM:0,hasCanopy:r!==`dead`,canopySway:n!==`simple`}}var nM=.02,rM={conifer:{trunkHeight:.4,trunkRadiusBottom:.05,trunkRadiusTop:.035},broadleaf:{trunkHeight:.42,trunkRadiusBottom:.05,trunkRadiusTop:.032},dead:{trunkHeight:.72,trunkRadiusBottom:.045,trunkRadiusTop:.018},bush:{trunkHeight:.14,trunkRadiusBottom:.045,trunkRadiusTop:.035}};function iM(e,t,n){let{trunkHeight:r,trunkRadiusBottom:i,trunkRadiusTop:a}=rM[e.type],o=[],s=new il(a,i,r,e.trunkRadialSegments).toNonIndexed();if(s.translate(0,r/2,0),o.push(s),e.type===`dead`)for(let n=0;n<e.branchCount;n++){let r=.22+t.next()*.14,a=new il(.006,.02,r,5).toNonIndexed();a.translate(0,r/2,0);let s=.7+t.next()*.6,c=n/e.branchCount*Math.PI*2+t.next()*.8,l=.34+(n+t.next())/e.branchCount*.34;a.applyMatrix4(new G().makeRotationY(c).multiply(new G().makeRotationX(s)).setPosition(Math.sin(c)*i*.6,l,Math.cos(c)*i*.6)),o.push(a)}let c=oM(o);return cM(c,new K(n),.7,1.05,t),c}function aM(e,t,n){if(!e.hasCanopy)return null;let r=[];if(e.type===`conifer`){let n=.74;for(let i=0;i<e.canopyLayers;i++){let a=i/e.canopyLayers,o=.3*(1-a*.62)*(.92+t.next()*.16),s=n/e.canopyLayers*1.7,c=new al(o,s,e.canopySegments).toNonIndexed();sM(c,t,nM),c.translate(0,.26+n*a+s/2,0),r.push(c)}for(let n=0;n<e.branchCount;n++){let i=new al(.06,.2,5).toNonIndexed(),a=n/Math.max(e.branchCount,1)*Math.PI*2+t.next(),o=1.1+t.next()*.4;i.applyMatrix4(new G().makeRotationY(a).multiply(new G().makeRotationX(o)).setPosition(Math.sin(a)*.22,.34+t.next()*.18,Math.cos(a)*.22)),r.push(i)}}else{let{trunkHeight:n}=rM[e.type];for(let i=0;i<e.blobCount;i++){let a=new sl((i===0?.3:.24-i*.02)*(.92+t.next()*.16),e.blobDetail).toNonIndexed();a.scale(1,.72,1),sM(a,t,nM);let o=i===0?0:.13,s=t.next()*Math.PI*2;a.translate(Math.cos(s)*o,n+.16+i*.1+t.next()*.05,Math.sin(s)*o),r.push(a)}}let i=oM(r);return cM(i,new K(n),.62,1.18,t),i}function oM(e){let t=0;for(let n of e)t+=n.getAttribute(`position`).count;let n=new Float32Array(t*3),r=new Float32Array(t*3),i=0;for(let t of e)n.set(t.getAttribute(`position`).array,i),r.set(t.getAttribute(`normal`).array,i),i+=t.getAttribute(`position`).count*3,t.dispose();let a=new J;return a.setAttribute(`position`,new q(n,3)),a.setAttribute(`normal`,new q(r,3)),a}function sM(e,t,n){let r=e.getAttribute(`position`);for(let e=0;e<r.count;e++)r.setXYZ(e,r.getX(e)+t.range(-n,n),r.getY(e)+t.range(-n,n),r.getZ(e)+t.range(-n,n))}function cM(e,t,n,r,i){let a=e.getAttribute(`position`),o=new Float32Array(a.count*3),s=1/0,c=-1/0;for(let e=0;e<a.count;e++){let t=a.getY(e);t<s&&(s=t),t>c&&(c=t)}let l=Math.max(c-s,1e-6),u=new K;for(let e=0;e<a.count;e++){let c=(a.getY(e)-s)/l,d=(n+(r-n)*c)*(.96+i.next()*.08);u.copy(t).multiplyScalar(d),o[e*3]=u.r,o[e*3+1]=u.g,o[e*3+2]=u.b}e.setAttribute(`color`,new q(o,3))}var lM=500,uM=15e5,dM=[.8,1.2],fM=.28,pM=.12,mM=.055,hM=.11,gM=3,_M=101,vM=[.78,.7,.45],yM=.45,bM=.55,xM=`https://agent8-games.verse8.io/assets/3D/default/textures/vegetation`,SM=`https://agent8-games.verse8.io/assets/3D/default/textures/vegetation/bark`,CM={high:{conifer:[`pine`,`pine`,`pine`],broadleaf:[`oak`,`ash`,`oak`],dead:[`ash`,`ash`,`ash`],bush:[`bush`,`bush`,`bush`]},medium:{conifer:[`pine-forest`,`pine-forest`,`pine-forest`],broadleaf:[`oak-forest`,`ash-forest`,`oak-forest`],dead:[`ash-forest`,`ash-forest`,`ash-forest`],bush:[`bush-forest`,`bush-forest`,`bush-forest`]}},wM=class e extends Ah{static typeName=`Tree3D`;static props={tier:{default:`medium`,options:Wj},type:{default:`conifer`,options:Gj},seed:{default:1},height:{default:6},count:{default:1},area:{default:[10,10]},trunkColor:{default:`#7a5a3a`},canopyColor:{default:`#4a7c3f`},leafTexture:{default:``},leafFadeStart:{default:0},leafFadeEnd:{default:0},leafShadows:{default:!0},drape:{default:null},terrain:{default:``,nodePath:!0}};tier=`medium`;type=`conifer`;seed=1;height=6;count=1;area=[10,10];trunkColor=`#7a5a3a`;canopyColor=`#4a7c3f`;leafTexture=``;leafFadeStart=0;leafFadeEnd=0;leafShadows=!0;drape=null;terrain=``;drapeTerrain=null;drapeWorld=[0,0,0];static validateJson(e){let t=e;if(tM(t.tier,t.type),!(t.height>0))throw new N(`BAD_FORMAT`,`Tree3D '${e.name}' height must be > 0 meters, got ${t.height}.`,{prop:`height`});if(!Number.isInteger(t.count)||t.count<1||t.count>lM)throw new N(`BAD_FORMAT`,`Tree3D '${e.name}' count must be an integer in 1..${lM}, got ${t.count}.`,{prop:`count`});if(!((t.area[0]??0)>0)||!((t.area[1]??0)>0))throw new N(`BAD_FORMAT`,`Tree3D '${e.name}' area must be positive [x, z] meters, got ${JSON.stringify(t.area)}.`,{prop:`area`});if(t.leafFadeEnd!==0&&!(t.leafFadeEnd>t.leafFadeStart&&t.leafFadeStart>=0))throw new N(`BAD_FORMAT`,`Tree3D '${e.name}' needs leafFadeEnd > leafFadeStart >= 0 (the leaf LOD window) or 0/0 to disable, got start ${t.leafFadeStart}, end ${t.leafFadeEnd}.`,{prop:`leafFadeStart`});if(typeof t.leafShadows!=`boolean`)throw new N(`BAD_FORMAT`,`Tree3D '${e.name}' leafShadows must be a boolean, got ${JSON.stringify(t.leafShadows)}.`,{prop:`leafShadows`});if(t.drape!==null&&typeof t.drape!=`boolean`)throw new N(`BAD_FORMAT`,`Tree3D '${e.name}' drape must be true, false or null (null = auto: drape whenever the scene has a Terrain3D), got ${JSON.stringify(t.drape)}.`,{prop:`drape`});if(typeof t.terrain!=`string`)throw new N(`BAD_FORMAT`,`Tree3D '${e.name}' terrain must be a node-path string (empty = auto-find), got ${JSON.stringify(t.terrain)}.`,{prop:`terrain`});if(t.tier===`simple`)return;let n=DM(t.tier,t.type),r=n*t.count;if(r>uM)throw new N(`BAD_FORMAT`,`Tree3D '${e.name}' blows the grove triangle budget: count ${t.count} × ${n} tris/tree (tier '${t.tier}', type '${t.type}') = ${r} > ${uM}. Lower count (max ${Math.floor(uM/n)} at this tier), drop tier to 'medium'/'simple', or split the grove into multiple nodes.`,{prop:`count`})}time=0;grove=null;variants=[];simpleTrunk=null;simpleCanopy=null;swayUniform=null;leafFadeUniform=null;loadedTextures=[];groveKey=``;_createObject3D(){return new _o}_trunk(){return this.rebuildIfNeeded(),this.simpleTrunk??this.variants[0]?.branches}_canopy(){return this.rebuildIfNeeded(),this.simpleTrunk?this.simpleCanopy:this.variants[0]?.leaves??null}_variantMeshes(){return this.rebuildIfNeeded(),this.variants}update(e){this.time+=e,this.swayUniform&&(this.swayUniform.value=this.time),this.leafFadeUniform&&(this.leafFadeUniform.start.value=this.leafFadeStart,this.leafFadeUniform.end.value=this.leafFadeEnd)}_syncObject3D(){super._syncObject3D(),this.rebuildIfNeeded()}rebuildIfNeeded(){this.grove||(this.grove=new _o,this._ensureObject3D().add(this.grove));let e=JSON.stringify([this.tier,this.type,this.seed,this.height,this.count,this.area,this.trunkColor,this.canopyColor,this.leafTexture,this.leafShadows,this.leafFadeEnd>this.leafFadeStart,this.drape,this.terrain]);e===this.groveKey&&(this.simpleTrunk||this.variants.length>0)||(this.groveKey=e,this.disposeMeshes(),this.resolveDrape(),this.tier===`simple`?this.buildSimpleGrove():this.buildEzGrove())}resolveDrape(){if(this.drapeTerrain=null,this.drape===!1)return;let e=QD(this,this.terrain);if(e)this.drapeTerrain=e,this.drapeWorld=ZD(this);else if(this.terrain!==``)throw new N(`NODE_NOT_FOUND`,`Tree3D '${this.name}' drape terrain '${this.terrain}' is not a Terrain3D in the tree.`,{prop:`terrain`})}bedY(e,t){let n=this.drapeTerrain;return n?n.heightAt(this.drapeWorld[0]+e,this.drapeWorld[2]+t)-this.drapeWorld[1]:0}buildSimpleGrove(){let e=tM(this.tier,this.type),t=new P(this.seed),n=iM(e,t,this.trunkColor),r=aM(e,t,this.canopyColor),i=new xc(n,NM(),this.count);FM(i);let a=null;r&&(a=new xc(r,NM(),this.count),FM(a)),this.scatter(t,(e,t,n)=>{i.setMatrixAt(e,t),i.setColorAt(e,n),a?.setMatrixAt(e,t),a?.setColorAt(e,n)}),PM(i),a&&PM(a),this.simpleTrunk=i,this.simpleCanopy=a,this.grove.add(i),a&&this.grove.add(a)}buildEzGrove(){let e=CM[this.tier][this.type],t=Math.min(gM,this.count),n=Array.from({length:t},(e,n)=>Math.floor(this.count/t)+ +(n<this.count%t));this.swayUniform={value:this.time},this.leafFadeUniform=this.leafFadeEnd>this.leafFadeStart?{start:{value:this.leafFadeStart},end:{value:this.leafFadeEnd}}:null;let r=AM(this.canopyColor),i=null;typeof document<`u`&&typeof createImageBitmap==`function`&&(i=new wu,i.setOptions({imageOrientation:`flipY`}));for(let a=0;a<t;a++){let t=n[a],o=e[a],s=Sj(o);this.type===`dead`&&(s.leaves.count=0);let c=Pj(s,this.seed+a*_M,1),l=this.buildBarkMaterial(o,i),u=new xc(c.branches,l,t);FM(u);let d=null;if(c.leaves){let e=new bl({color:r.clone().multiply(new K(vM[0],vM[1],vM[2])),roughness:1,side:2,vertexColors:!0,alphaTest:s.leaves.alphaTest}),n=this.leafTexture||OM(s.leaves.style);i&&(e.map=EM(i,n,e=>{e.colorSpace=Oi,e.flipY=!1},e=>kM(e))),UO(e,this.swayUniform,yM,this.leafFadeUniform??void 0),d=new xc(c.leaves,e,t),d.userData.incantoWaterPassSkip=!0,FM(d),this.leafShadows||(d.castShadow=!1)}this.variants.push({branches:u,leaves:d}),this.grove.add(u),d&&this.grove.add(d)}let a=Array(t).fill(0),o=new P(this.seed);this.scatter(o,(e,n,r)=>{let i=e%t,o=this.variants[i],s=a[i];a[i]=s+1,o.branches.setMatrixAt(s,n),o.branches.setColorAt(s,r),o.leaves?.setMatrixAt(s,n),o.leaves?.setColorAt(s,r)});for(let e of this.variants)PM(e.branches),e.leaves&&PM(e.leaves)}buildBarkMaterial(t,n){if(this.type===`dead`||!n)return new bl({color:new K(this.trunkColor),roughness:1});let r=wj(t),i=new bl({color:this.trunkColor===e.props.trunkColor?.default?new K(r.tint):MM(this.trunkColor),roughness:1});return HO(i,bM),i.map=this.loadBarkTexture(n,r,`color`,!0),i.normalMap=this.loadBarkTexture(n,r,`normal`,!1),i.roughnessMap=this.loadBarkTexture(n,r,`roughness`,!1),i}loadBarkTexture(e,t,n,r){return EM(e,`${SM}/${t.texture}_${n}_1k.jpg`,e=>{e.wrapS=er,e.wrapT=er,e.repeat.set(t.repeat[0],t.repeat[1]),e.anisotropy=4,e.flipY=!1,r&&(e.colorSpace=Oi)})}scatter(e,t){let n=(this.area[0]??0)/2,r=(this.area[1]??0)/2;for(let i=0;i<this.count;i++){let a=this.count===1?0:e.range(-n,n),o=this.count===1?0:e.range(-r,r);RM.set(a,this.drape?this.bedY(a,o):0,o),zM.setFromAxisAngle(IM,e.range(0,Math.PI*2));let s=this.height*e.range(dM[0],dM[1]),c=s*e.range(.9,1.1);BM.set(c,s,c),LM.compose(RM,zM,BM),VM.setHSL(fM,pM,.92).offsetHSL(e.range(-.055,mM),0,e.range(-.11,hM)),t(i,LM,VM)}}disposeMeshes(){let e=[this.simpleTrunk,this.simpleCanopy];for(let t of this.variants)e.push(t.branches,t.leaves);let t=new Set;for(let n of e)n&&(n.removeFromParent(),n.geometry.dispose(),t.add(n.material),n.dispose());for(let e of t)e.dispose();for(let e of this.loadedTextures)e.dispose();this.loadedTextures=[],this.simpleTrunk=null,this.simpleCanopy=null,this.variants=[],this.swayUniform=null,this.leafFadeUniform=null}free(){this.disposeMeshes(),this.grove=null,super.free()}},TM=new Map;function EM(e,t,n,r){let i=TM.get(t);if(i)return i;let a=new La;return n(a),e.load(t,e=>{a.image=e,r?r(a):a.needsUpdate=!0}),TM.set(t,a),a}function DM(e,t){let n=0;for(let r of new Set(CM[e][t]??[])){let e=Sj(r);t===`dead`&&(e.leaves.count=0),n=Math.max(n,yj(e).total)}return n}function OM(e){return`${xM}/${e}_color.png`}function kM(e){let t=e.image;if(!t||typeof document>`u`)return;let n=document.createElement(`canvas`);n.width=t.naturalWidth||t.width,n.height=t.naturalHeight||t.height;let r=n.getContext(`2d`,{willReadFrequently:!0});if(!r)return;r.drawImage(t,0,0);let i;try{i=r.getImageData(0,0,n.width,n.height)}catch{return}let a=i.data,o=0,s=0,c=0,l=0;for(let e=0;e<a.length;e+=4)a[e+3]>240&&(o+=a[e],s+=a[e+1],c+=a[e+2],l++);if(l!==0){o=Math.round(o/l),s=Math.round(s/l),c=Math.round(c/l);for(let e=0;e<a.length;e+=4)a[e+3]<=240&&(a[e]=o,a[e+1]=s,a[e+2]=c);r.putImageData(i,0,0),e.image=n,e.needsUpdate=!0}}function AM(e){let t=new K(e),n=Math.max(t.r,t.g,t.b);return n>0?t.multiplyScalar(1/n):t.setRGB(1,1,1),t.lerp(jM,.18)}var jM=new K(1,1,1);function MM(e){let t=new K(e),n=Math.max(t.r,t.g,t.b);return n>0?t.multiplyScalar(1/n):t.setRGB(1,1,1),t}function NM(){return new bl({vertexColors:!0,roughness:1,flatShading:!0})}function PM(e){e.instanceMatrix.needsUpdate=!0,e.instanceColor&&(e.instanceColor.needsUpdate=!0),XD(e)}function FM(e){e.castShadow=!0,e.receiveShadow=!0}var IM=new U(0,1,0),LM=new G,RM=new U,zM=new H,BM=new U,VM=new K,HM=[[[.4,.4,.4],[.4,.4,.4],[.4,.4,.4],[.4,.4,.4],[.4,.4,.4],[.4,.4,.4]],[[.6,.3,0],[.6,.3,0],[.6,.3,0],[.6,.3,0],[0,.8,0],[.6,.3,0]],[[.6,.3,0],[.6,.3,0],[.6,.3,0],[.6,.3,0],[.6,.3,0],[.6,.3,0]],[[.6,.55,.5],[.55,.5,.45],[.5,.45,.4],[.55,.5,.45],[.65,.6,.55],[.5,.45,.4]],[[.45,.45,.4],[.4,.4,.35],[.35,.35,.3],[.4,.4,.35],[.5,.5,.45],[.35,.35,.3]],[[.2,.2,.2],[.2,.2,.2],[.2,.2,.2],[.2,.2,.2],[.2,.2,.2],[.2,.2,.2]],[[.8,.5,.2],[.75,.45,.15],[.7,.4,.1],[.75,.45,.15],[.85,.55,.25],[.7,.4,.1]],[[0,.7,.1],[0,.65,.1],[0,.6,.1],[0,.65,.1],[0,.75,.1],[0,.6,.1]],[[.3,.3,.3],[.3,.3,.3],[.3,.3,.3],[.3,.3,.3],[.3,.3,.3],[.3,.3,.3]],[[0,0,.7],[0,0,.7],[0,0,.7],[0,0,.7],[0,.2,.9],[0,0,.6]],[[.9,.3,0],[.9,.3,0],[.9,.3,0],[.9,.3,0],[1,.4,0],[.7,.2,0]],[[.9,.8,.2],[.85,.75,.18],[.85,.75,.18],[.85,.75,.18],[.95,.85,.25],[.85,.75,.18]],[[.6,.6,.6],[.55,.55,.55],[.5,.5,.5],[.55,.55,.55],[.65,.65,.65],[.5,.5,.5]],[[.7,.7,.4],[.65,.65,.35],[.6,.6,.3],[.65,.65,.35],[.75,.75,.45],[.6,.6,.3]],[[.7,.5,.5],[.65,.45,.45],[.6,.4,.4],[.65,.45,.45],[.75,.55,.55],[.6,.4,.4]],[[.35,.3,.25],[.3,.25,.2],[.25,.2,.15],[.3,.25,.2],[.4,.35,.3],[.25,.2,.15]],[[.5,.3,0],[.5,.3,0],[.5,.3,0],[.5,.3,0],[.7,.4,.1],[.7,.4,.1]],[[0,.5,0],[0,.45,0],[0,.45,0],[0,.45,0],[0,.6,0],[0,.4,0]],[[.2,.8,.8],[.15,.7,.7],[.1,.6,.6],[.15,.7,.7],[.3,.9,.9],[.1,.6,.6]],[[1,.5,.8],[.9,.4,.7],[.8,.3,.6],[.9,.4,.7],[1,.6,.9],[.8,.3,.6]],[[1,.9,.3],[.95,.85,.25],[.9,.8,.2],[.95,.85,.25],[1,1,.4],[.9,.8,.2]],[[1,0,0],[.9,0,0],[.8,0,0],[.9,0,0],[1,.2,.2],[.8,0,0]],[[.6,.4,.2],[.5,.3,.15],[.4,.25,.1],[.5,.3,.15],[.7,.45,.25],[.4,.25,.1]],[[.6,.2,.8],[.5,.15,.7],[.4,.1,.6],[.5,.15,.7],[.7,.25,.9],[.4,.1,.6]],[[1,.8,0],[.95,.75,0],[.95,.75,0],[.95,.75,0],[1,.9,0],[.9,.7,0]],[[.6,.65,.7],[.55,.6,.65],[.5,.55,.6],[.55,.6,.65],[.65,.7,.75],[.5,.55,.6]]],UM=2e5,WM=class extends Ah{static typeName=`VoxelGrid3D`;static signals=[`blocksChanged`];static props={voxels:{default:[]}};voxels=[];appliedVoxels=null;map=new Map;mesh=null;dirty=!1;blockCount(){return this.map.size}tileAt(e,t,n){return this.map.get(`${e},${t},${n}`)}setBlocks(e){this.map.clear();for(let t of e)this.map.set(`${t.x},${t.y},${t.z}`,t.tile);this.dirty=!0,this.emit(`blocksChanged`)}addBlock(e){this.map.set(`${e.x},${e.y},${e.z}`,e.tile),this.dirty=!0,this.emit(`blocksChanged`)}removeBlockAt(e,t,n){let r=this.map.delete(`${e},${t},${n}`);return r&&(this.dirty=!0,this.emit(`blocksChanged`)),r}blocks(){let e=[];for(let[t,n]of this.map){let[r,i,a]=t.split(`,`).map(Number);e.push({x:r,y:i,z:a,tile:n})}return e}_createObject3D(){let e=new nl(1,1,1),t=new vl({vertexShader:KM,fragmentShader:qM});this.mesh=new xc(e,t,UM),this.mesh.count=0,this.mesh.frustumCulled=!1;for(let e of GM)this.mesh.geometry.setAttribute(e,new pc(new Float32Array(UM*3),3));return this.dirty=!0,this.mesh}update(){if(this.voxels.length>0&&this.voxels!==this.appliedVoxels&&(this.appliedVoxels=this.voxels,this.setBlocks(this.voxels.map(e=>({x:e[0]??0,y:e[1]??0,z:e[2]??0,tile:e[3]??0})))),!this.dirty||!this.mesh)return;this.dirty=!1;let e=new G,t=0;for(let[n,r]of this.map){if(t>=UM)break;let[i,a,o]=n.split(`,`).map(Number);e.setPosition(i,a,o),this.mesh.setMatrixAt(t,e);let s=HM[r]??HM[0];for(let e=0;e<6;e++){let n=this.mesh.geometry.getAttribute(GM[e]),r=s[e];n.setXYZ(t,r[0],r[1],r[2]),n.needsUpdate=!0}t++}this.mesh.count=t,this.mesh.instanceMatrix.needsUpdate=!0}},GM=[`colorFront`,`colorRight`,`colorBack`,`colorLeft`,`colorTop`,`colorBottom`],KM=`
|
|
7898
7898
|
attribute vec3 colorFront;
|
|
7899
7899
|
attribute vec3 colorRight;
|
|
7900
7900
|
attribute vec3 colorBack;
|
|
@@ -7915,7 +7915,7 @@ void main() {
|
|
|
7915
7915
|
if (abs(n.x) > 0.5) vUv2 = p.zy; else if (abs(n.y) > 0.5) vUv2 = p.xz; else vUv2 = p.xy;
|
|
7916
7916
|
gl_Position = projectionMatrix * modelViewMatrix * instanceMatrix * vec4(position, 1.0);
|
|
7917
7917
|
}
|
|
7918
|
-
`,
|
|
7918
|
+
`,qM=`
|
|
7919
7919
|
varying vec3 vColor;
|
|
7920
7920
|
varying vec3 vNormal;
|
|
7921
7921
|
varying vec2 vUv2;
|
|
@@ -7926,13 +7926,13 @@ void main() {
|
|
|
7926
7926
|
if (vUv2.x < edge || vUv2.x > 1.0 - edge || vUv2.y < edge || vUv2.y > 1.0 - edge) color *= 0.75;
|
|
7927
7927
|
gl_FragColor = vec4(color, 1.0);
|
|
7928
7928
|
}
|
|
7929
|
-
`;function
|
|
7929
|
+
`;function JM(){_n(),R(Ah),R(eA),R(Ow),R(Lk),R(dE),R(fE),R(yE),R(lD),R(WM),R(Rw),R(mj),R(bE),R(DE),R(Mw),R(uj),R(_T),R(_g),R(Ih),R(Sk),R(lO),R(wM),R(Zk),R(UE),R(Fk),R(Ik),R(Mh),R(Ph),R(Nh),R(Fh)}var YM={slowMs:20,fastMs:13,minScale:.6,step:.15,window:45},XM=class{opts;samples=[];scale=1;constructor(e={}){this.opts={...YM,...e}}current(){return this.scale}push(e){if(!(e>0)||!Number.isFinite(e)||(this.samples.push(e),this.samples.length<this.opts.window))return null;let t=[...this.samples].sort((e,t)=>e-t),n=t[Math.floor(t.length/2)];this.samples=[];let r=this.scale;return n>this.opts.slowMs?this.scale=Math.max(this.opts.minScale,this.scale-this.opts.step):n<this.opts.fastMs&&this.scale<1&&(this.scale=Math.min(1,this.scale+this.opts.step)),this.scale===r?null:this.scale}reset(){this.samples=[]}},ZM=`
|
|
7930
7930
|
varying vec2 vUv;
|
|
7931
7931
|
void main() {
|
|
7932
7932
|
vUv = uv;
|
|
7933
7933
|
gl_Position = vec4(position.xy, 0.0, 1.0);
|
|
7934
7934
|
}
|
|
7935
|
-
`,
|
|
7935
|
+
`,QM=`
|
|
7936
7936
|
precision highp float;
|
|
7937
7937
|
varying vec2 vUv;
|
|
7938
7938
|
uniform sampler2D tScene;
|
|
@@ -7946,7 +7946,7 @@ void main() {
|
|
|
7946
7946
|
float k = max(l - uThreshold, 0.0);
|
|
7947
7947
|
gl_FragColor = vec4(c * (k / max(l, 1e-4)), 1.0);
|
|
7948
7948
|
}
|
|
7949
|
-
|
|
7949
|
+
`,$M=`
|
|
7950
7950
|
precision highp float;
|
|
7951
7951
|
varying vec2 vUv;
|
|
7952
7952
|
uniform sampler2D tTex;
|
|
@@ -7960,7 +7960,7 @@ void main() {
|
|
|
7960
7960
|
sum += texture2D(tTex, vUv - uDir * 3.2308) * 0.0702703;
|
|
7961
7961
|
gl_FragColor = sum;
|
|
7962
7962
|
}
|
|
7963
|
-
`,
|
|
7963
|
+
`,eN=`
|
|
7964
7964
|
precision highp float;
|
|
7965
7965
|
varying vec2 vUv;
|
|
7966
7966
|
uniform sampler2D tScene;
|
|
@@ -7990,13 +7990,13 @@ void main() {
|
|
|
7990
7990
|
gl_FragColor.rgb = max(graded, 0.0);
|
|
7991
7991
|
#include <colorspace_fragment>
|
|
7992
7992
|
}
|
|
7993
|
-
`;function
|
|
7993
|
+
`;function tN(e,t){let n=new vl({vertexShader:ZM,fragmentShader:e,depthTest:!1,depthWrite:!1,uniforms:t}),r=new Ys(new cl(2,2),n);return r.frustumCulled=!1,r}function nN(){let e=tN(QM,{tScene:{value:null},uThreshold:{value:1}});return{mesh:e,uniforms:e.material.uniforms}}function rN(){let e=tN($M,{tTex:{value:null},uDir:{value:new V}});return{mesh:e,uniforms:e.material.uniforms}}function iN(){let e=tN(eN,{tScene:{value:null},tBloom:{value:null},uStrength:{value:.85},uVignette:{value:0},uSaturation:{value:1},uContrast:{value:1}});return{mesh:e,uniforms:e.material.uniforms}}var aN=`
|
|
7994
7994
|
varying vec2 vUv;
|
|
7995
7995
|
void main() {
|
|
7996
7996
|
vUv = uv;
|
|
7997
7997
|
gl_Position = vec4(position.xy, 0.0, 1.0);
|
|
7998
7998
|
}
|
|
7999
|
-
`,
|
|
7999
|
+
`,oN=`
|
|
8000
8000
|
precision highp float;
|
|
8001
8001
|
varying vec2 vUv;
|
|
8002
8002
|
uniform sampler2D tDepth;
|
|
@@ -8158,7 +8158,7 @@ void main() {
|
|
|
8158
8158
|
// a separate full-res pass (this raymarch runs at HALF res for performance)
|
|
8159
8159
|
gl_FragColor = vec4(accum, alpha);
|
|
8160
8160
|
}
|
|
8161
|
-
`,
|
|
8161
|
+
`,sN=`
|
|
8162
8162
|
precision highp float;
|
|
8163
8163
|
varying vec2 vUv;
|
|
8164
8164
|
uniform sampler2D tTex;
|
|
@@ -8176,7 +8176,7 @@ void main() {
|
|
|
8176
8176
|
c += texture2D(tTex, vUv - uDir * 4.0) * 0.015;
|
|
8177
8177
|
gl_FragColor = c;
|
|
8178
8178
|
}
|
|
8179
|
-
`,
|
|
8179
|
+
`,cN=`
|
|
8180
8180
|
precision highp float;
|
|
8181
8181
|
varying vec2 vUv;
|
|
8182
8182
|
uniform sampler2D tScene;
|
|
@@ -8186,11 +8186,11 @@ void main() {
|
|
|
8186
8186
|
vec4 cloud = texture2D(tClouds, vUv); // already separable-blurred + premultiplied
|
|
8187
8187
|
gl_FragColor = vec4(scene.rgb * (1.0 - cloud.a) + cloud.rgb, 1.0);
|
|
8188
8188
|
}
|
|
8189
|
-
`;function
|
|
8189
|
+
`;function lN(){let e=new vl({vertexShader:aN,fragmentShader:sN,depthTest:!1,depthWrite:!1,uniforms:{tTex:{value:null},uDir:{value:new V}}}),t=new Ys(new cl(2,2),e);return t.frustumCulled=!1,{mesh:t,uniforms:e.uniforms}}function uN(){let e=new vl({vertexShader:aN,fragmentShader:oN,depthTest:!1,depthWrite:!1,uniforms:{tDepth:{value:null},uInvViewProj:{value:new G},uCameraPos:{value:new U},uTime:{value:0},uSunDir:{value:new U(0,1,0)},uSunColor:{value:new K(`#fff3da`)},uCloudColor:{value:new K(`#ffffff`)},uShadeColor:{value:new K(`#9fb0c8`)},uHorizonColor:{value:new K(`#cdd9e6`)},uBase:{value:120},uTop:{value:320},uCoverage:{value:.5},uDensity:{value:1},uScale:{value:240},uWind:{value:new V(1,.3)},uFarFade:{value:6e3}}}),t=new Ys(new cl(2,2),e);return t.frustumCulled=!1,{mesh:t,uniforms:e.uniforms}}function dN(){let e=new vl({vertexShader:aN,fragmentShader:cN,depthTest:!1,depthWrite:!1,uniforms:{tScene:{value:null},tClouds:{value:null}}}),t=new Ys(new cl(2,2),e);return t.frustumCulled=!1,{mesh:t,uniforms:e.uniforms}}var fN=class extends $l{constructor(e){super(e),this.type=gr}parse(e){let t=function(e,t){switch(e){case 1:throw Error(`THREE.HDRLoader: Read Error: `+(t||``));case 2:throw Error(`THREE.HDRLoader: Write Error: `+(t||``));case 3:throw Error(`THREE.HDRLoader: Bad File Format: `+(t||``));default:case 4:throw Error(`THREE.HDRLoader: Memory Error: `+(t||``))}},n=function(e,t,n){t||=1024;let r=e.pos,i=-1,a=0,o=``,s=String.fromCharCode.apply(null,new Uint16Array(e.subarray(r,r+128)));for(;0>(i=s.indexOf(`
|
|
8190
8190
|
`))&&a<t&&r<e.byteLength;)o+=s,a+=s.length,r+=128,s=String.fromCharCode.apply(null,new Uint16Array(e.subarray(r,r+128)));return-1<i?(!1!==n&&(e.pos+=a+i+1),o+s.slice(0,i)):!1},r=function(e){let r=/^#\?(\S+)/,i=/^\s*GAMMA\s*=\s*(\d+(\.\d+)?)\s*$/,a=/^\s*EXPOSURE\s*=\s*(\d+(\.\d+)?)\s*$/,o=/^\s*FORMAT=(\S+)\s*$/,s=/^\s*\-Y\s+(\d+)\s+\+X\s+(\d+)\s*$/,c={valid:0,string:``,comments:``,programtype:`RGBE`,format:``,gamma:1,exposure:1,width:0,height:0},l,u;for((e.pos>=e.byteLength||!(l=n(e)))&&t(1,`no header found`),(u=l.match(r))||t(3,`bad initial token`),c.valid|=1,c.programtype=u[1],c.string+=l+`
|
|
8191
8191
|
`;l=n(e),!1!==l;){if(c.string+=l+`
|
|
8192
8192
|
`,l.charAt(0)===`#`){c.comments+=l+`
|
|
8193
|
-
`;continue}if((u=l.match(i))&&(c.gamma=parseFloat(u[1])),(u=l.match(a))&&(c.exposure=parseFloat(u[1])),(u=l.match(o))&&(c.valid|=2,c.format=u[1]),(u=l.match(s))&&(c.valid|=4,c.height=parseInt(u[1],10),c.width=parseInt(u[2],10)),c.valid&2&&c.valid&4)break}return c.valid&2||t(3,`missing format specifier`),c.valid&4||t(3,`missing image size specifier`),c},i=function(e,n,r){let i=n;if(i<8||i>32767||e[0]!==2||e[1]!==2||e[2]&128)return new Uint8Array(e);i!==(e[2]<<8|e[3])&&t(3,`wrong scanline width`);let a=new Uint8Array(4*n*r);a.length||t(4,`unable to allocate buffer space`);let o=0,s=0,c=4*i,l=new Uint8Array(4),u=new Uint8Array(c),d=r;for(;d>0&&s<e.byteLength;){s+4>e.byteLength&&t(1),l[0]=e[s++],l[1]=e[s++],l[2]=e[s++],l[3]=e[s++],(l[0]!=2||l[1]!=2||(l[2]<<8|l[3])!=i)&&t(3,`bad rgbe scanline format`);let n=0,r;for(;n<c&&s<e.byteLength;){r=e[s++];let i=r>128;if(i&&(r-=128),(r===0||n+r>c)&&t(3,`bad scanline data`),i){let t=e[s++];for(let e=0;e<r;e++)u[n++]=t}else u.set(e.subarray(s,s+r),n),n+=r,s+=r}let f=i;for(let e=0;e<f;e++){let t=0;a[o]=u[e+t],t+=i,a[o+1]=u[e+t],t+=i,a[o+2]=u[e+t],t+=i,a[o+3]=u[e+t],o+=4}d--}return a},a=function(e,t,n,r){let i=2**(e[t+3]-128)/255;n[r+0]=e[t+0]*i,n[r+1]=e[t+1]*i,n[r+2]=e[t+2]*i,n[r+3]=1},o=function(e,t,n,r){let i=2**(e[t+3]-128)/255;n[r+0]=os.toHalfFloat(Math.min(e[t+0]*i,65504)),n[r+1]=os.toHalfFloat(Math.min(e[t+1]*i,65504)),n[r+2]=os.toHalfFloat(Math.min(e[t+2]*i,65504)),n[r+3]=os.toHalfFloat(1)},s=new Uint8Array(e);s.pos=0;let c=r(s),l=c.width,u=c.height,d=i(s.subarray(s.pos),l,u),f,p,m;switch(this.type){case hr:m=d.length/4;let e=new Float32Array(m*4);for(let t=0;t<m;t++)a(d,t*4,e,t*4);f=e,p=hr;break;case gr:m=d.length/4;let t=new Uint16Array(m*4);for(let e=0;e<m;e++)o(d,e*4,t,e*4);f=t,p=gr;break;default:throw Error(`THREE.HDRLoader: Unsupported type: `+this.type)}return{width:l,height:u,data:f,header:c.string,gamma:c.gamma,exposure:c.exposure,type:p}}setDataType(e){return this.type=e,this}load(e,t,n,r){function i(e,n){switch(e.type){case hr:case gr:e.colorSpace=ki,e.minFilter=or,e.magFilter=or,e.generateMipmaps=!1,e.flipY=!0;break}t&&t(e,n)}return super.load(e,i,n,r)}},
|
|
8193
|
+
`;continue}if((u=l.match(i))&&(c.gamma=parseFloat(u[1])),(u=l.match(a))&&(c.exposure=parseFloat(u[1])),(u=l.match(o))&&(c.valid|=2,c.format=u[1]),(u=l.match(s))&&(c.valid|=4,c.height=parseInt(u[1],10),c.width=parseInt(u[2],10)),c.valid&2&&c.valid&4)break}return c.valid&2||t(3,`missing format specifier`),c.valid&4||t(3,`missing image size specifier`),c},i=function(e,n,r){let i=n;if(i<8||i>32767||e[0]!==2||e[1]!==2||e[2]&128)return new Uint8Array(e);i!==(e[2]<<8|e[3])&&t(3,`wrong scanline width`);let a=new Uint8Array(4*n*r);a.length||t(4,`unable to allocate buffer space`);let o=0,s=0,c=4*i,l=new Uint8Array(4),u=new Uint8Array(c),d=r;for(;d>0&&s<e.byteLength;){s+4>e.byteLength&&t(1),l[0]=e[s++],l[1]=e[s++],l[2]=e[s++],l[3]=e[s++],(l[0]!=2||l[1]!=2||(l[2]<<8|l[3])!=i)&&t(3,`bad rgbe scanline format`);let n=0,r;for(;n<c&&s<e.byteLength;){r=e[s++];let i=r>128;if(i&&(r-=128),(r===0||n+r>c)&&t(3,`bad scanline data`),i){let t=e[s++];for(let e=0;e<r;e++)u[n++]=t}else u.set(e.subarray(s,s+r),n),n+=r,s+=r}let f=i;for(let e=0;e<f;e++){let t=0;a[o]=u[e+t],t+=i,a[o+1]=u[e+t],t+=i,a[o+2]=u[e+t],t+=i,a[o+3]=u[e+t],o+=4}d--}return a},a=function(e,t,n,r){let i=2**(e[t+3]-128)/255;n[r+0]=e[t+0]*i,n[r+1]=e[t+1]*i,n[r+2]=e[t+2]*i,n[r+3]=1},o=function(e,t,n,r){let i=2**(e[t+3]-128)/255;n[r+0]=os.toHalfFloat(Math.min(e[t+0]*i,65504)),n[r+1]=os.toHalfFloat(Math.min(e[t+1]*i,65504)),n[r+2]=os.toHalfFloat(Math.min(e[t+2]*i,65504)),n[r+3]=os.toHalfFloat(1)},s=new Uint8Array(e);s.pos=0;let c=r(s),l=c.width,u=c.height,d=i(s.subarray(s.pos),l,u),f,p,m;switch(this.type){case hr:m=d.length/4;let e=new Float32Array(m*4);for(let t=0;t<m;t++)a(d,t*4,e,t*4);f=e,p=hr;break;case gr:m=d.length/4;let t=new Uint16Array(m*4);for(let e=0;e<m;e++)o(d,e*4,t,e*4);f=t,p=gr;break;default:throw Error(`THREE.HDRLoader: Unsupported type: `+this.type)}return{width:l,height:u,data:f,header:c.string,gamma:c.gamma,exposure:c.exposure,type:p}}setDataType(e){return this.type=e,this}load(e,t,n,r){function i(e,n){switch(e.type){case hr:case gr:e.colorSpace=ki,e.minFilter=or,e.magFilter=or,e.generateMipmaps=!1,e.flipY=!0;break}t&&t(e,n)}return super.load(e,i,n,r)}},pN=class extends fN{constructor(e){console.warn(`RGBELoader has been deprecated. Please use HDRLoader instead.`),super(e)}},mN=class e extends Ys{constructor(){let t=e.SkyShader,n=new vl({name:t.name,uniforms:hl.clone(t.uniforms),vertexShader:t.vertexShader,fragmentShader:t.fragmentShader,side:1,depthWrite:!1});super(new nl(1,1,1),n),this.isSky=!0}};mN.SkyShader={name:`SkyShader`,uniforms:{turbidity:{value:2},rayleigh:{value:1},mieCoefficient:{value:.005},mieDirectionalG:{value:.8},sunPosition:{value:new U},up:{value:new U(0,1,0)},cloudScale:{value:2e-4},cloudSpeed:{value:1e-4},cloudCoverage:{value:.4},cloudDensity:{value:.4},cloudElevation:{value:.5},showSunDisc:{value:1},time:{value:0}},vertexShader:`
|
|
8194
8194
|
uniform vec3 sunPosition;
|
|
8195
8195
|
uniform float rayleigh;
|
|
8196
8196
|
uniform float turbidity;
|
|
@@ -8410,7 +8410,7 @@ void main() {
|
|
|
8410
8410
|
#include <tonemapping_fragment>
|
|
8411
8411
|
#include <colorspace_fragment>
|
|
8412
8412
|
|
|
8413
|
-
}`};var pN=[`type`,`sunPosition`,`elevationDeg`,`azimuthDeg`,`turbidity`,`rayleigh`],mN=[`color`,`near`,`far`],hN=[`coverage`,`density`,`base`,`top`,`color`,`shadeColor`,`speed`,`scale`],gN=[`threshold`,`strength`],_N=[`vignette`,`saturation`,`contrast`],vN=[`mapSize`,`radius`,`static`],yN=[1024,2048],bN=2,xN=1,SN=50,CN=800,wN=`#cfd8e0`,TN=Math.PI/180;function EN(e){return{exposure:AN(e?.exposure),sky:jN(e?.sky),fog:MN(e?.fog,e?.sky!==void 0),clouds:NN(e?.clouds),bloom:PN(e?.bloom),post:FN(e?.post),shadows:IN(e?.shadows)}}function DN(e,t){let n=(90-e)*TN,r=t*TN;return[Math.sin(n)*Math.sin(r),Math.cos(n),Math.sin(n)*Math.cos(r)]}function ON(e){let[t,n,r]=e.sunPosition,i=Math.hypot(t,n,r)||1;return[t/i,n/i,r/i]}function kN(e){let t=[191,213,232],n=[233,228,217],r=[242,201,150],i=zN((e.turbidity-bN)/8),a=ON(e),o=zN((18-Math.asin(RN(a[1],-1,1))/TN)/18)*.8,s=e=>Math.round(BN(BN(t[e],n[e],i),r[e],o));return`#${[s(0),s(1),s(2)].map(e=>e.toString(16).padStart(2,`0`)).join(``)}`}function AN(e){if(e===void 0)return 1;if(typeof e!=`number`||!Number.isFinite(e)||e<=0)throw new N(`BAD_FORMAT`,`environment.exposure must be a finite number > 0 (tone-mapping exposure, default 1), got ${JSON.stringify(e)}.`,{prop:`exposure`});return e}function jN(e){if(e===void 0)return null;if(typeof e!=`object`||!e||Array.isArray(e))throw new N(`BAD_FORMAT`,`environment.sky must be an object ({ type?: "atmosphere", sunPosition? | elevationDeg?+azimuthDeg?, turbidity?, rayleigh? }), got ${JSON.stringify(e)}.`,{prop:`sky`});let t=e;for(let e of Object.keys(t))if(!pN.includes(e))throw new N(`BAD_FORMAT`,`environment.sky has unknown key '${e}'. Valid keys: [${pN.join(`, `)}].`,{prop:`sky`,validOptions:pN});if(t.type!==void 0&&t.type!==`atmosphere`)throw new N(`BAD_FORMAT`,`environment.sky.type must be 'atmosphere' (the only sky type so far), got ${JSON.stringify(t.type)}.`,{prop:`sky`,validOptions:[`atmosphere`]});let n=t.elevationDeg!==void 0||t.azimuthDeg!==void 0;if(t.sunPosition!==void 0&&n)throw new N(`BAD_FORMAT`,`environment.sky takes sunPosition OR elevationDeg/azimuthDeg, not both.`,{prop:`sky`,validOptions:[`sunPosition`,`elevationDeg+azimuthDeg`]});let r;if(t.sunPosition!==void 0){let e=t.sunPosition;if(!Array.isArray(e)||e.length!==3||!e.every(e=>typeof e==`number`&&Number.isFinite(e))||Math.hypot(e[0],e[1],e[2])===0)throw new N(`BAD_FORMAT`,`environment.sky.sunPosition must be a non-zero [x, y, z] vector, got ${JSON.stringify(e)}.`,{prop:`sky`});r=[e[0],e[1],e[2]]}else{let e=LN(t.elevationDeg,32,`sky.elevationDeg`),n=LN(t.azimuthDeg,135,`sky.azimuthDeg`);if(e<-90||e>90)throw new N(`BAD_FORMAT`,`environment.sky.elevationDeg must be in [-90, 90] (degrees above the horizon), got ${e}.`,{prop:`sky`});r=DN(e,n)}let i=LN(t.turbidity,bN,`sky.turbidity`);if(i<=0)throw new N(`BAD_FORMAT`,`environment.sky.turbidity must be > 0 (atmospheric haze; 2 ≈ clear day), got ${i}.`,{prop:`sky`});let a=LN(t.rayleigh,xN,`sky.rayleigh`);if(a<0)throw new N(`BAD_FORMAT`,`environment.sky.rayleigh must be >= 0 (Rayleigh scattering; 1 ≈ earth-like), got ${a}.`,{prop:`sky`});return{sunPosition:r,turbidity:i,rayleigh:a}}function MN(e,t){if(e===void 0)return null;if(typeof e!=`object`||!e||Array.isArray(e))throw new N(`BAD_FORMAT`,`environment.fog must be an object ({ color?, near?, far? }), got ${JSON.stringify(e)}.`,{prop:`fog`});let n=e;for(let e of Object.keys(n))if(!mN.includes(e))throw new N(`BAD_FORMAT`,`environment.fog has unknown key '${e}'. Valid keys: [${mN.join(`, `)}].`,{prop:`fog`,validOptions:mN});if(n.color!==void 0&&typeof n.color!=`string`)throw new N(`BAD_FORMAT`,`environment.fog.color must be a hex color string, got ${JSON.stringify(n.color)}.`,{prop:`fog`});let r=LN(n.near,SN,`fog.near`),i=LN(n.far,CN,`fog.far`);if(r<0)throw new N(`BAD_FORMAT`,`environment.fog.near must be >= 0 meters, got ${r}.`,{prop:`fog`});if(i<=r)throw new N(`BAD_FORMAT`,`environment.fog.far must be > near (got near ${r}, far ${i}).`,{prop:`fog`});return{color:n.color??(t?``:wN),near:r,far:i}}function NN(e){if(e===void 0)return null;if(typeof e!=`object`||!e||Array.isArray(e))throw new N(`BAD_FORMAT`,`environment.clouds must be an object ({ coverage?, density?, base?, top?, color?, shadeColor?, speed?, scale? }), got ${JSON.stringify(e)}.`,{prop:`clouds`});let t=e;for(let e of Object.keys(t))if(!hN.includes(e))throw new N(`BAD_FORMAT`,`environment.clouds has unknown key '${e}'. Valid keys: [${hN.join(`, `)}].`,{prop:`clouds`,validOptions:hN});for(let e of[`color`,`shadeColor`])if(t[e]!==void 0&&typeof t[e]!=`string`)throw new N(`BAD_FORMAT`,`environment.clouds.${e} must be a hex color string, got ${JSON.stringify(t[e])}.`,{prop:`clouds`});let n=LN(t.coverage,.5,`clouds.coverage`);if(n<0||n>1)throw new N(`BAD_FORMAT`,`environment.clouds.coverage must be in [0, 1] (how much sky is cloudy), got ${n}.`,{prop:`clouds`});let r=LN(t.density,1,`clouds.density`);if(r<0)throw new N(`BAD_FORMAT`,`environment.clouds.density must be >= 0 (optical thickness), got ${r}.`,{prop:`clouds`});let i=LN(t.base,120,`clouds.base`),a=LN(t.top,320,`clouds.top`);if(a<=i)throw new N(`BAD_FORMAT`,`environment.clouds.top must be > base (got base ${i}, top ${a}).`,{prop:`clouds`});let o=LN(t.speed,1,`clouds.speed`),s=LN(t.scale,240,`clouds.scale`);if(s<=0)throw new N(`BAD_FORMAT`,`environment.clouds.scale must be > 0 (feature size in world units), got ${s}.`,{prop:`clouds`});return{coverage:n,density:r,base:i,top:a,color:t.color??`#ffffff`,shadeColor:t.shadeColor??`#9fb0c8`,speed:o,scale:s}}function PN(e){if(e===void 0)return null;if(typeof e!=`object`||!e||Array.isArray(e))throw new N(`BAD_FORMAT`,`environment.bloom must be an object ({ threshold?, strength? }), got ${JSON.stringify(e)}.`,{prop:`bloom`});let t=e;for(let e of Object.keys(t))if(!gN.includes(e))throw new N(`BAD_FORMAT`,`environment.bloom has unknown key '${e}'. Valid keys: [${gN.join(`, `)}].`,{prop:`bloom`,validOptions:gN});let n=LN(t.threshold,1,`bloom.threshold`);if(n<0||n>8)throw new N(`BAD_FORMAT`,`environment.bloom.threshold must be in [0, 8] (linear-HDR luminance; 1 = white), got ${n}.`,{prop:`bloom`});let r=LN(t.strength,.8,`bloom.strength`);if(r<0)throw new N(`BAD_FORMAT`,`environment.bloom.strength must be >= 0, got ${r}.`,{prop:`bloom`});return{threshold:n,strength:r}}function FN(e){if(e===void 0)return null;if(typeof e!=`object`||!e||Array.isArray(e))throw new N(`BAD_FORMAT`,`environment.post must be an object ({ vignette?, saturation?, contrast? }), got ${JSON.stringify(e)}.`,{prop:`post`});let t=e;for(let e of Object.keys(t))if(!_N.includes(e))throw new N(`BAD_FORMAT`,`environment.post has unknown key '${e}'. Valid keys: [${_N.join(`, `)}].`,{prop:`post`,validOptions:_N});let n=LN(t.vignette,0,`post.vignette`);if(n<0||n>1)throw new N(`BAD_FORMAT`,`environment.post.vignette must be in [0, 1], got ${n}.`,{prop:`post`});let r=LN(t.saturation,1,`post.saturation`);if(r<0||r>4)throw new N(`BAD_FORMAT`,`environment.post.saturation must be in [0, 4] (1 = neutral), got ${r}.`,{prop:`post`});let i=LN(t.contrast,1,`post.contrast`);if(i<.2||i>3)throw new N(`BAD_FORMAT`,`environment.post.contrast must be in [0.2, 3] (1 = neutral), got ${i}.`,{prop:`post`});return{vignette:n,saturation:r,contrast:i}}function IN(e){if(e===void 0)return null;if(e===!1)return!1;if(e===!0)return{mapSize:2048,radius:1,static:!1};if(typeof e!=`object`||!e||Array.isArray(e))throw new N(`BAD_FORMAT`,`environment.shadows must be true, false or an object ({ mapSize?, radius? }), got ${JSON.stringify(e)}.`,{prop:`shadows`});let t=e;for(let e of Object.keys(t))if(!vN.includes(e))throw new N(`BAD_FORMAT`,`environment.shadows has unknown key '${e}'. Valid keys: [${vN.join(`, `)}].`,{prop:`shadows`,validOptions:vN});let n=t.mapSize===void 0?2048:t.mapSize;if(!yN.includes(n))throw new N(`BAD_FORMAT`,`environment.shadows.mapSize must be one of [${yN.join(`, `)}], got ${JSON.stringify(t.mapSize)}.`,{prop:`shadows`,validOptions:yN.map(String)});let r=LN(t.radius,1,`shadows.radius`);if(r<0)throw new N(`BAD_FORMAT`,`environment.shadows.radius must be >= 0, got ${r}.`,{prop:`shadows`});let i=t.static===void 0?!1:t.static;if(typeof i!=`boolean`)throw new N(`BAD_FORMAT`,`environment.shadows.static must be a boolean, got ${JSON.stringify(t.static)}.`,{prop:`shadows`});return{mapSize:n,radius:r,static:i}}function LN(e,t,n){if(e===void 0)return t;if(typeof e!=`number`||!Number.isFinite(e))throw new N(`BAD_FORMAT`,`environment.${n} must be a finite number, got ${JSON.stringify(e)}.`,{prop:n});return e}function RN(e,t,n){return Math.min(Math.max(e,t),n)}function zN(e){return RN(e,0,1)}function BN(e,t,n){return e+(t-e)*n}var VN=`https://agent8-games.verse8.io/assets/3D/default/textures/hdri`,HN={apartment:`lebombo_1k.hdr`,city:`potsdamer_platz_1k.hdr`,dawn:`kiara_1_dawn_1k.hdr`,forest:`forest_slope_1k.hdr`,lobby:`st_fagans_interior_1k.hdr`,night:`dikhololo_night_1k.hdr`,park:`rooitou_park_1k.hdr`,studio:`studio_small_03_1k.hdr`,sunset:`venice_sunset_1k.hdr`,warehouse:`empty_warehouse_01_1k.hdr`};function UN(e){if(typeof e.hdri==`string`&&e.hdri!==``)return e.hdri;if(typeof e.preset==`string`){let t=HN[e.preset];if(!t)throw Error(`Unknown environment preset '${e.preset}'. Available: ${Object.keys(HN).join(`, `)}.`);return`${VN}/${t}`}return null}var WN=75,GN=class{scene;ambient=new xu(`#ffffff`,0);envKey=null;config=EN(void 0);hdriUrl=null;hdriTexture=null;_sky=null;skyKey=``;skyEnvKey=``;skyEnvTarget=null;fog=new To(`#ffffff`,1,1e3);underwaterFog=null;underwaterBg=new K;constructor(e){this.scene=e,this.scene.add(this.ambient)}get sunDirection(){return this.config.sky?ON(this.config.sky):null}get clouds(){return this.config.clouds}get bloom(){return this.config.bloom}get post(){return this.config.post}get sceneFog(){return this.scene.fog instanceof To?this.scene.fog:null}apply(e,t){let n=e===void 0?``:JSON.stringify(e);n!==this.envKey&&(this.envKey=n,this.config=EN(e));let r=this.config,i=e?.ambient;if(this.ambient.color.set(i?.color??`#ffffff`),this.ambient.intensity=i?.intensity??0,t&&(t.toneMappingExposure=r.exposure,t.shadowMap.enabled=r.shadows!==!1,r.shadows!==!1&&r.shadows!==null&&r.shadows.static?t.shadowMap.autoUpdate&&(t.shadowMap.autoUpdate=!1,t.shadowMap.needsUpdate=!0):t.shadowMap.autoUpdate||(t.shadowMap.autoUpdate=!0)),this.applyHdri(e),this.applySky(r.sky,t),this._sky&&(this._sky.visible=!0),this.applyFog(r),this.scene.environment=this.hdriTexture??this.skyEnvTarget?.texture??null,this.scene.environmentIntensity=(this.scene.environment===this.skyEnvTarget?.texture&&this.skyEnvTarget?.55:1)*KN(e?.iblIntensity),e?.skybox===!0&&this.hdriTexture)this.scene.background=this.hdriTexture;else{let t=e?.background;this.scene.background=typeof t==`string`?new K(t):null}}applySunLight(e,t=null){if(!e)return;let n=this.sunDirection;if(t){let r=e.position.length()||100,i,a,o;if(n)[i,a,o]=n;else{i=e.position.x-e.target.position.x,a=e.position.y-e.target.position.y,o=e.position.z-e.target.position.z;let t=Math.hypot(i,a,o)||1;i/=t,a/=t,o/=t}e.target.position.set(t.x,t.y,t.z),e.target.updateMatrixWorld(),e.position.set(t.x+i*r,t.y+a*r,t.z+o*r)}else if(n){let t=e.position.length()||100;e.position.set(n[0],n[1],n[2]).multiplyScalar(t)}let r=this.config.shadows;if(r&&typeof r==`object`){if(!e.castShadow){let t=e.shadow.camera;`left`in t&&t.left===-5&&(t.left=-75,t.right=WN,t.top=WN,t.bottom=-75,t.near=.5,t.far=500,t.updateProjectionMatrix()),e.castShadow=!0}e.shadow.mapSize.x!==r.mapSize&&(e.shadow.mapSize.set(r.mapSize,r.mapSize),e.shadow.map?.dispose(),e.shadow.map=null),e.shadow.radius=r.radius}}applyUnderwater(e){e&&(this.underwaterFog||=new To(`#000000`,.5,e.visibility),this.underwaterFog.color.set(e.color),this.underwaterFog.near=.5,this.underwaterFog.far=e.visibility,this.scene.fog=this.underwaterFog,this.scene.background=this.underwaterBg.set(e.color),this._sky&&(this._sky.visible=!1))}applyHdri(e){let t=UN(e??{});t!==this.hdriUrl&&(this.hdriUrl=t,this.hdriTexture?.dispose(),this.hdriTexture=null,t&&new dN().load(t,e=>{if(this.hdriUrl!==t){e.dispose();return}e.mapping=303,this.hdriTexture=e}))}applySky(e,t){let n=e?JSON.stringify(e):``;if(n!==this.skyKey&&(this.skyKey=n,this._sky&&=(this.scene.remove(this._sky),this._sky.material.dispose(),this._sky.geometry.dispose(),null),e)){this._sky=new fN,this._sky.scale.setScalar(45e4);let t=this._sky.material.uniforms;(t.sunPosition?.value).set(...e.sunPosition),t.turbidity&&(t.turbidity.value=e.turbidity),t.rayleigh&&(t.rayleigh.value=e.rayleigh),this.scene.add(this._sky)}if(e&&t&&this._sky&&this.skyEnvKey!==n){this.skyEnvKey=n,this.skyEnvTarget?.dispose();let e=new xd(t),r=new Eo;r.add(this._sky),this.skyEnvTarget=e.fromScene(r),e.dispose(),this.scene.add(this._sky)}!e&&this.skyEnvTarget&&(this.skyEnvTarget.dispose(),this.skyEnvTarget=null,this.skyEnvKey=``)}applyFog(e){if(!e.fog){this.scene.fog=null;return}let t=e.fog.color||(e.sky?kN(e.sky):`#cfd8e0`);this.fog.color.set(t),this.fog.near=e.fog.near,this.fog.far=e.fog.far,this.scene.fog=this.fog}dispose(){this.hdriTexture?.dispose(),this.hdriTexture=null,this.skyEnvTarget?.dispose(),this.skyEnvTarget=null,this._sky&&=(this.scene.remove(this._sky),this._sky.material.dispose(),this._sky.geometry.dispose(),null)}};function KN(e){if(e===void 0)return 1;if(typeof e!=`number`||!Number.isFinite(e)||e<0)throw new N(`BAD_FORMAT`,`environment.iblIntensity must be a finite number >= 0 (multiplies the image-based ambience: sky-derived base 0.55, HDRI base 1; default 1), got ${JSON.stringify(e)}.`,{prop:`iblIntensity`});return e}var qN=new Vo,JN=new Vo,YN=new G,XN=new G,ZN=new U,QN=Array.from({length:8},()=>new U),$N=.4,eP=new Float32Array(72),tP=[[0,0,0],[1,0,0],[1,0,1],[0,0,1],[0,1,0],[1,1,0],[1,1,1],[0,1,1]],nP=[[0,1],[1,2],[2,3],[3,0],[4,5],[5,6],[6,7],[7,4],[0,4],[1,5],[2,6],[3,7]];function rP(e,t){t.makeEmpty(),YN.copy(e.matrixWorld).invert(),e.traverse(e=>{let n=e,r;n.isInstancedMesh?(n.boundingBox||n.computeBoundingBox?.(),r=n.boundingBox):n.geometry&&(n.geometry.boundingBox||n.geometry.computeBoundingBox(),r=n.geometry.boundingBox),r&&(JN.copy(r).applyMatrix4(XN.multiplyMatrices(YN,e.matrixWorld)),t.union(JN))})}function iP(e){if(!(e instanceof Oh))return null;let t=e._ensureObject3D();t.updateWorldMatrix(!0,!0),rP(t,qN);let n=!0;qN.isEmpty()?(n=!1,ZN.setFromMatrixPosition(t.matrixWorld),qN.min.set(ZN.x-$N,ZN.y-$N,ZN.z-$N),qN.max.set(ZN.x+$N,ZN.y+$N,ZN.z+$N)):qN.expandByScalar(.02);let{min:r,max:i}=qN;for(let e=0;e<8;e++){let[a,o,s]=tP[e],c=QN[e].set(a?i.x:r.x,o?i.y:r.y,s?i.z:r.z);n&&c.applyMatrix4(t.matrixWorld)}let a=0;for(let[e,t]of nP){let n=QN[e],r=QN[t];eP[a++]=n.x,eP[a++]=n.y,eP[a++]=n.z,eP[a++]=r.x,eP[a++]=r.y,eP[a++]=r.z}return eP}function aP(e){return e.spatial===!0&&typeof e._setSpatialPose==`function`}function oP(){let e=new Set,t=[],n=[],r=[];return{visited:e,cameras:t,renderHooks:n,emitters:r,state:{visited:e,cameras:t,renderHooks:n,emitters:r,assets:void 0,sunDirection:null,sunLight:null,alpha:1,ignoreStatic:!1}}}function sP(e,t,n,r,i){let a=i??oP();a.visited.clear(),a.cameras.length=0,a.renderHooks.length=0,a.emitters.length=0;let o=a.state;o.assets=n,o.sunDirection=r?.sunDirection??null,o.ignoreStatic=r?.ignoreStatic===!0,o.sunLight=null,o.alpha=r?.alpha??1,pP(e,t,o),gP(t,a.visited);let s=null;for(let e=0;e<a.cameras.length;e++){let t=a.cameras[e];if(t.current){s=t;break}}s||=a.cameras[0]??null;let c=s?s._ensureObject3D():null;return fP(a.emitters,c),{activeCamera:c,renderHooks:a.renderHooks,sunLight:o.sunLight}}var cP=new U,lP=new U,uP=new U,dP=new U;function fP(e,t){if(e.length===0||!t)return;t.updateWorldMatrix(!0,!1),t.getWorldPosition(lP),t.getWorldDirection(uP),dP.set(0,1,0).applyQuaternion(t.quaternion);let n={position:[lP.x,lP.y,lP.z],forward:[uP.x,uP.y,uP.z],up:[dP.x,dP.y,dP.z]};for(let{node:t,parent:r}of e)r.updateWorldMatrix(!0,!1),r.getWorldPosition(cP),t._setSpatialPose({position:[cP.x,cP.y,cP.z],listener:n})}function pP(e,t,n){let r=t;if(e instanceof Oh){let i=e._ensureObject3D();if(e.static&&!n.ignoreStatic&&i.userData.incantoStaticSynced===!0){i.userData.incantoStatic=!0,n.visited.add(i);return}if(i.parent!==t&&t.add(i),e._syncObject3D(n.alpha,n.assets??null),n.assets&&e instanceof Yk&&e._syncModel(n.assets),typeof e._onRender3D==`function`&&n.renderHooks.push(e),n.sunDirection){let t=e._applySunDirection;typeof t==`function`&&t.call(e,n.sunDirection)}e instanceof Nk&&(!n.sunLight||e.intensity>n.sunLight.intensity)&&(n.sunLight=e),n.visited.add(i),e instanceof VE&&n.cameras.push(e),r=i}else aP(e)&&n.emitters.push({node:e,parent:r});for(let t of e.children)pP(t,r,n);if(e instanceof Oh){let t=e._ensureObject3D();e.static&&!n.ignoreStatic?(t.userData.incantoStaticSynced=!0,t.userData.incantoStatic=!0,hP(e)):t.userData.incantoStaticSynced===!0&&(t.userData.incantoStaticSynced=!1,t.userData.incantoStatic=!1)}}var mP=new WeakSet;function hP(e){if(mP.has(e))return;mP.add(e);let t=[],n=e=>{(typeof e._onRender3D==`function`||e instanceof VE)&&t.push(`${e.name} (${e.constructor.typeName??`?`})`);for(let t of e.children)n(t)};n(e),t.length>0&&console.warn(`[incanto] static subtree '${e.name}' freezes animated/per-frame nodes: ${t.join(`, `)} — they will stop updating. Unmark static or move them out.`)}function gP(e,t){let n=e.children;for(let r=n.length-1;r>=0;r--){let i=n[r];i.userData.incantoNode&&!t.has(i)?e.remove(i):i.userData.incantoStatic!==!0&&gP(i,t)}}var _P=class{viewOverride=null;overrideCam=new pu(60,1,.05,5e3);lastCamera=null;lastSize={w:1,h:1};webgl;threeScene=new Eo;environment=new GN(this.threeScene);engine;disconnect;canvas;assets;ownsAssets;loadedAssetScenes=new WeakSet;compiledScene=null;warmCamera=null;deferCompile=!1;syncScratch=oP();ignoreStatic=!1;renderCtx=null;causticsTarget=null;causticsScene=null;causticsUniforms=null;cloudsTarget=null;cloudsHalfTarget=null;cloudsBlurTarget=null;cloudsScene=null;cloudsUniforms=null;cloudsBlurScene=null;cloudsBlurUniforms=null;cloudsCompositeScene=null;cloudsCompositeUniforms=null;bloomTarget=null;bloomBrightTarget=null;bloomBlurTarget=null;bloomBrightScene=null;bloomBrightUniforms=null;bloomBlurScene=null;bloomBlurUniforms=null;bloomCompositeScene=null;bloomCompositeUniforms=null;constructor(e){this.canvas=e.canvas,this.engine=e.engine,this.ownsAssets=!e.assets,this.assets=e.assets??new _w(this.engine);let t=vn(e.engine.scene?.environment,{antialias:!0,pixelRatio:Math.min(globalThis.devicePixelRatio??1,2),preserveDrawingBuffer:!1},globalThis.devicePixelRatio??1,{pixelRatio:e.pixelRatio,preserveDrawingBuffer:e.preserveDrawingBuffer});this.webgl=new hm({canvas:e.canvas,antialias:t.antialias,preserveDrawingBuffer:t.preserveDrawingBuffer}),this.webgl.info.autoReset=!1,this.engine.picker=(e,t)=>this.pick(e,t),this.basePixelRatio=t.pixelRatio,this.webgl.setPixelRatio(t.pixelRatio),this.adaptive=e.adaptiveResolution===!1?null:new JM,this.webgl.shadowMap.enabled=!0,this.webgl.shadowMap.type=1,this.webgl.toneMapping=4,this.webgl.toneMappingExposure=1,this.debugLines=new Hc(new J,new Ac({color:`#00ff6e`,depthTest:!1})),this.debugLines.frustumCulled=!1,this.debugLines.renderOrder=9999,this.debugLines.visible=!1,this.threeScene.add(this.debugLines),this.selectionLines=new Hc(new J,new Ac({color:`#ffb020`,transparent:!0,depthTest:!1})),this.selectionLines.frustumCulled=!1,this.selectionLines.renderOrder=1e4,this.selectionLines.visible=!1,this.threeScene.add(this.selectionLines),this.disconnect=this.engine.updated.connect(()=>this.render())}basePixelRatio;adaptive;lastFrameAt=0;debugLines;selectionLines;syncSelectionOutline(){let e=this.engine.debugSelection;e&&e.tree!==this.engine.scene?.tree&&(this.engine.debugSelection=null);let t=this.engine.debugSelection,n=t?iP(t):null;if(this.selectionLines.visible=n!==null,n){this.selectionLines.geometry.setAttribute(`position`,new q(n,3));let e=this.selectionLines.geometry.getAttribute(`position`);e.needsUpdate=!0}}syncDebugLines(){let e=null;for(let t of $_(`3d`,this.engine))if(e=t.debugLines(),e)break;this.debugLines.visible=e!==null,e&&this.debugLines.geometry.setAttribute(`position`,new q(e,3))}governResolution(){let e=this.adaptive;if(!e)return;let t=globalThis.performance?.now?.()??0,n=this.lastFrameAt;if(this.lastFrameAt=t,n===0)return;let r=t-n;if(r>500){e.reset();return}let i=e.push(r);if(i===null)return;this.webgl.setPixelRatio(this.basePixelRatio*i);let a=this.lastSize;a.w>0&&a.h>0&&this.webgl.setSize(a.w,a.h,!1)}deferFirstCompile(){this.deferCompile=!0}async warmUp(e){this.deferCompile=!1;let t=this.warmCamera;if(!t)return;let n=[];this.threeScene.traverse(e=>{(e.isMesh||e.isPoints)&&n.push(e)});let r=n.filter(e=>e.visible);if(r.length===0){this.webgl.compile(this.threeScene,t),e?.(1);return}for(let e of r)e.visible=!1;let i=Math.min(vP,r.length),a=Math.ceil(r.length/i);try{for(let n=0;n<i;n++){for(let e=n*a;e<Math.min((n+1)*a,r.length);e++)r[e].visible=!0;this.webgl.compile(this.threeScene,t),e?.((n+1)/i),typeof requestAnimationFrame==`function`&&await new Promise(e=>{requestAnimationFrame(()=>setTimeout(e,0))})}}finally{for(let e of r)e.visible=!0}}render(){let e=this.engine.scene;if(!e)return;this.webgl.info.reset(),this.governResolution(),this.syncDebugLines(),this.syncSelectionOutline(),e.assets&&!this.loadedAssetScenes.has(e)&&(this.assets.load(e.assets),this.loadedAssetScenes.add(e)),this.environment.apply(e.environment,this.webgl);let{activeCamera:t,renderHooks:n,sunLight:r}=sP(e.root,this.threeScene,this.assets,{sunDirection:this.environment.sunDirection,alpha:this.engine.interpolationAlpha,ignoreStatic:this.ignoreStatic},this.syncScratch),i=t;if(this.viewOverride){let[e,t,n]=this.viewOverride.position,[r,a,o]=this.viewOverride.target;this.overrideCam.position.set(e,t,n),this.overrideCam.lookAt(bP.set(r,a,o)),i=this.overrideCam}if(!i)return;this.lastCamera=i,i.updateWorldMatrix(!0,!1);let a=i.getWorldPosition(EP),o=r?r._ensureObject3D():null,s=!!o&&r.shadowFollowsCamera===!0;this.environment.applySunLight(o,s?a:null),this.compiledScene!==e&&!this.deferCompile&&(this.compiledScene=e,this.webgl.compile(this.threeScene,i)),this.warmCamera=i;let c=this.canvas.clientWidth||this.canvas.width,l=this.canvas.clientHeight||this.canvas.height,u=this.webgl.getSize(yP);(u.x!==c||u.y!==l)&&this.webgl.setSize(c,l,!1),this.lastSize={w:c,h:l};let d=l===0?1:c/l;i.aspect!==d&&(i.aspect=d,i.updateProjectionMatrix()),this.renderCtx||={gl:this.webgl,scene:this.threeScene,camera:i};let f=this.renderCtx;f.camera=i,o?(o.updateWorldMatrix(!0,!1),o.target.updateWorldMatrix(!0,!1),f.sunDir=SP.setFromMatrixPosition(o.matrixWorld).sub(CP.setFromMatrixPosition(o.target.matrixWorld)).normalize()):f.sunDir=null;for(let e=0;e<n.length;e++)n[e]?._onRender3D(f);let p=null;for(let e=0;e<n.length;e++){let t=n[e].underwaterAt?.(a.x,a.y,a.z);if(t){p=t;break}}this.environment.applyUnderwater(p);let m=this.environment.clouds,h=this.environment.bloom,g=this.environment.post;p?.caustics.enabled?this.renderWithCaustics(i,p):m&&!p?this.renderWithClouds(i,m,o):(h||g)&&!p?this.renderWithBloom(i,h,g):this.webgl.render(this.threeScene,i)}renderWithBloom(e,t,n=null){let r=this.webgl.getDrawingBufferSize(yP),i=Math.max(1,r.x),a=Math.max(1,r.y),o=Math.max(1,Math.ceil(i/2)),s=Math.max(1,Math.ceil(a/2));if(this.bloomTarget&&(this.bloomTarget.width!==i||this.bloomTarget.height!==a)&&(this.bloomTarget.dispose(),this.bloomTarget=null,this.bloomBrightTarget?.dispose(),this.bloomBrightTarget=null,this.bloomBlurTarget?.dispose(),this.bloomBlurTarget=null),this.bloomTarget||(this.bloomTarget=new Ba(i,a,{type:gr,samples:4}),this.bloomBrightTarget=new Ba(o,s,{type:gr}),this.bloomBlurTarget=new Ba(o,s,{type:gr})),!this.bloomBrightScene){let e=eN();this.bloomBrightScene=new Eo,this.bloomBrightScene.add(e.mesh),this.bloomBrightUniforms=e.uniforms;let t=tN();this.bloomBlurScene=new Eo,this.bloomBlurScene.add(t.mesh),this.bloomBlurUniforms=t.uniforms;let n=nN();this.bloomCompositeScene=new Eo,this.bloomCompositeScene.add(n.mesh),this.bloomCompositeUniforms=n.uniforms}let c=this.bloomBrightTarget,l=this.bloomBlurTarget;if(this.webgl.setRenderTarget(this.bloomTarget),this.webgl.render(this.threeScene,e),t){let n=this.bloomBrightUniforms;n.tScene.value=this.bloomTarget.texture,n.uThreshold.value=t.threshold,this.webgl.setRenderTarget(c),this.webgl.render(this.bloomBrightScene,e);let r=this.bloomBlurUniforms;r.tTex.value=c.texture,r.uDir.value.set(1/o,0),this.webgl.setRenderTarget(l),this.webgl.render(this.bloomBlurScene,e),r.tTex.value=l.texture,r.uDir.value.set(0,1/s),this.webgl.setRenderTarget(c),this.webgl.render(this.bloomBlurScene,e)}let u=this.bloomCompositeUniforms;u.tScene.value=this.bloomTarget.texture,u.tBloom.value=t?c.texture:this.bloomTarget.texture,u.uStrength.value=t?t.strength:0,u.uVignette.value=n?.vignette??0,u.uSaturation.value=n?.saturation??1,u.uContrast.value=n?.contrast??1,this.webgl.setRenderTarget(null),this.webgl.render(this.bloomCompositeScene,e)}renderWithClouds(e,t,n){let r=this.webgl.getDrawingBufferSize(yP),i=Math.max(1,r.x),a=Math.max(1,r.y),o=Math.max(1,Math.ceil(i/3)),s=Math.max(1,Math.ceil(a/3));if(this.cloudsTarget&&(this.cloudsTarget.width!==i||this.cloudsTarget.height!==a)&&(this.cloudsTarget.depthTexture?.dispose(),this.cloudsTarget.dispose(),this.cloudsTarget=null,this.cloudsHalfTarget?.dispose(),this.cloudsHalfTarget=null,this.cloudsBlurTarget?.dispose(),this.cloudsBlurTarget=null),!this.cloudsTarget){let e=new $c(i,a);e.type=hr,this.cloudsTarget=new Ba(i,a,{depthTexture:e,depthBuffer:!0})}if(this.cloudsHalfTarget||(this.cloudsHalfTarget=new Ba(o,s,{depthBuffer:!1}),this.cloudsBlurTarget=new Ba(o,s,{depthBuffer:!1})),!this.cloudsScene){let{mesh:e,uniforms:t}=cN();this.cloudsScene=new Eo,this.cloudsScene.add(e),this.cloudsUniforms=t}if(!this.cloudsBlurScene){let{mesh:e,uniforms:t}=sN();this.cloudsBlurScene=new Eo,this.cloudsBlurScene.add(e),this.cloudsBlurUniforms=t}if(!this.cloudsCompositeScene){let{mesh:e,uniforms:t}=lN();this.cloudsCompositeScene=new Eo,this.cloudsCompositeScene.add(e),this.cloudsCompositeUniforms=t}this.webgl.setRenderTarget(this.cloudsTarget),this.webgl.render(this.threeScene,e);let c=this.cloudsUniforms;c.tDepth.value=this.cloudsTarget.depthTexture,c.uInvViewProj.value.multiplyMatrices(e.projectionMatrix,e.matrixWorldInverse).invert(),e.getWorldPosition(c.uCameraPos.value),c.uTime.value=(globalThis.performance?.now()??0)*.001*t.speed;let l=this.environment.sunDirection??[.4,.8,.3];c.uSunDir.value.set(l[0],l[1],l[2]).normalize(),n&&c.uSunColor.value.copy(n.color),c.uCloudColor.value.set(t.color),c.uShadeColor.value.set(t.shadeColor);let u=this.environment.sceneFog;u?(c.uHorizonColor.value.copy(u.color),c.uFarFade.value=u.far):(c.uHorizonColor.value.set(`#cdd9e6`),c.uFarFade.value=6e3),c.uBase.value=t.base,c.uTop.value=t.top,c.uCoverage.value=t.coverage,c.uDensity.value=t.density,c.uScale.value=t.scale,c.uWind.value.set(1,.35),this.webgl.setRenderTarget(this.cloudsHalfTarget),this.webgl.render(this.cloudsScene,e);let d=this.cloudsBlurUniforms,f=this.cloudsBlurScene;d.tTex.value=this.cloudsHalfTarget.texture,d.uDir.value.set(1/o,0),this.webgl.setRenderTarget(this.cloudsBlurTarget),this.webgl.render(f,e),d.tTex.value=this.cloudsBlurTarget.texture,d.uDir.value.set(0,1/s),this.webgl.setRenderTarget(this.cloudsHalfTarget),this.webgl.render(f,e),this.webgl.setRenderTarget(null);let p=this.cloudsCompositeUniforms;p.tScene.value=this.cloudsTarget.texture,p.tClouds.value=this.cloudsHalfTarget.texture,this.webgl.render(this.cloudsCompositeScene,e)}renderWithCaustics(e,t){let n=this.webgl.getDrawingBufferSize(yP),r=Math.max(1,n.x),i=Math.max(1,n.y);if(this.causticsTarget&&(this.causticsTarget.width!==r||this.causticsTarget.height!==i)&&(this.causticsTarget.depthTexture?.dispose(),this.causticsTarget.dispose(),this.causticsTarget=null),!this.causticsTarget){let e=new $c(r,i);e.type=hr,this.causticsTarget=new Ba(r,i,{depthTexture:e,depthBuffer:!0})}if(!this.causticsScene){let{mesh:e,uniforms:t}=$m();this.causticsScene=new Eo,this.causticsScene.add(e),this.causticsUniforms=t}this.webgl.setRenderTarget(this.causticsTarget),this.webgl.render(this.threeScene,e),this.webgl.setRenderTarget(null);let a=this.causticsUniforms;a.tColor.value=this.causticsTarget.texture,a.tDepth.value=this.causticsTarget.depthTexture,a.uInvViewProj.value.multiplyMatrices(e.projectionMatrix,e.matrixWorldInverse).invert(),e.getWorldPosition(a.uCameraPos.value),a.uWaterLevel.value=t.surfaceY,a.uTime.value=(globalThis.performance?.now()??0)*.001*t.caustics.speed,a.uCausticColor.value.set(t.caustics.color),a.uCausticIntensity.value=t.caustics.intensity,a.uCausticScale.value=t.caustics.scale,a.uMaxDist.value=t.visibility;let o=this.environment.sunDirection;o&&a.uSunDirection.value.set(o[0],o[1],o[2]),a.uRayStrength.value=t.rays.enabled?t.rays.strength:0,this.webgl.render(this.causticsScene,e)}screenFromWorld(e,t,n){let r=this.lastCamera;return r?(xP.set(e,t,n).project(r),{x:(xP.x+1)/2*this.lastSize.w,y:(1-xP.y)/2*this.lastSize.h,behind:xP.z>1}):{x:0,y:0,behind:!0}}pick(e,t){let n=this.lastCamera;if(!n)return null;OP.set(e/this.lastSize.w*2-1,-(t/this.lastSize.h*2-1)),DP.setFromCamera(OP,n);let r=DP.intersectObjects(this.threeScene.children,!0);for(let e of r){let t=e.object;for(;t&&!t.userData.incantoNode;)t=t.parent;let n=t?.userData.incantoNode;if(n)return n}return null}stats(){let e=this.webgl.info;return{triangles:e.render.triangles,drawCalls:e.render.calls,geometries:e.memory.geometries,textures:e.memory.textures}}lastCameraPosition(){let e=this.lastCamera;return e?(e.getWorldPosition(TP),{x:TP.x,y:TP.y,z:TP.z}):null}cameraBasis(){let e=this.lastCamera,t=e?e.getWorldQuaternion(wP):wP.identity();return{right:new U(1,0,0).applyQuaternion(t),up:new U(0,1,0).applyQuaternion(t),forward:new U(0,0,-1).applyQuaternion(t)}}refreshShadows(){this.webgl.shadowMap.needsUpdate=!0}dispose(){this.engine.picker&&(this.engine.picker=null),this.disconnect(),this.threeScene.traverse(e=>{let t=e;if(!(!t.isMesh||t.userData?.incantoModelShared))if(t.geometry?.dispose(),Array.isArray(t.material))for(let e of t.material)e.dispose();else t.material?.dispose()}),this.causticsTarget?.depthTexture?.dispose(),this.causticsTarget?.dispose();let e=this.causticsScene?.children[0];e?.geometry?.dispose(),e?.material?.dispose(),this.cloudsTarget?.depthTexture?.dispose(),this.cloudsTarget?.dispose(),this.cloudsHalfTarget?.dispose(),this.cloudsBlurTarget?.dispose(),this.bloomTarget?.dispose(),this.bloomBrightTarget?.dispose(),this.bloomBlurTarget?.dispose();for(let e of[this.cloudsScene,this.cloudsBlurScene,this.cloudsCompositeScene,this.bloomBrightScene,this.bloomBlurScene,this.bloomCompositeScene]){let t=e?.children[0];t?.geometry?.dispose(),t?.material?.dispose()}this.ownsAssets&&this.assets.dispose(),this.environment.dispose(),this.webgl.dispose()}},vP=12,yP=new V,bP=new U,xP=new U,SP=new U,CP=new U,wP=new H,TP=new U,EP=new U,DP=new qu,OP=new V;async function kP(e){let t=async(t,n)=>{e.onProgress&&(e.onProgress(t,n),typeof requestAnimationFrame==`function`&&await new Promise(e=>{requestAnimationFrame(()=>setTimeout(e,0))}))};KM(),(e.gameplay??!0)&&U_();for(let[t,n]of Object.entries(e.behaviors??{}))it(t,n,{replace:!0});let n=new kt({seed:e.seed,fixedHz:e.fixedHz,...e._scheduler?{scheduler:e._scheduler}:{}}),r=AP(e.scene),i=An(AP(r),{resolveScene:e.resolveScene,engine:n});n.setScene(i),await t(.06,`scene`);let a=null;(e.physics===!0||(e.physics??`auto`)===`auto`&&jP(i.root))&&(a=await OT(n)),await t(.1,`physics`);let o=[],s=e.keyboard??(typeof window<`u`?window:!1);if(s&&n.input.attachKeyboard(s),e.pointer){let t=typeof e.pointer==`object`?e.pointer.lockOnClick??!0:!0;n.input.attachPointer(e.canvas,{lockOnClick:t})}o.push(MP(n,i.root,e.canvas));let c=e.touch??`auto`;if(c!==!1){let t=e.touchContainer??e.canvas.parentElement??null;if(t){let r={force:c===!0,...e._touchDoc?{doc:e._touchDoc}:{}},i=qn(n,t,r),a=n.sceneChanged.connect(()=>{i?.dispose(),i=qn(n,t,r)});o.push(()=>{a(),i?.dispose()})}}let l=e._rendererFactory?e._rendererFactory(n,e.canvas):new _P({canvas:e.canvas,engine:n,...e.pixelRatio===void 0?{}:{pixelRatio:e.pixelRatio},...e.adaptiveResolution===void 0?{}:{adaptiveResolution:e.adaptiveResolution},...e.preserveDrawingBuffer===void 0?{}:{preserveDrawingBuffer:e.preserveDrawingBuffer}});await t(.14,`renderer`);let u=e.debug??!1,d=e.editor??u,f=d===!0?{}:d||null,p={label:`✎ edit this scene`,run:async()=>{if(!f)return;let t=Am(l),n=f.open??Om,i=async t=>{await kP({...e,scene:t})};await km(async()=>{m();try{await n({scene:r,...t?{camera:t}:{},play:i,exit:()=>i(r),...f.save?{save:f.save}:{},...f.library?{library:f.library===!0?wm():f.library}:{}})}catch(e){console.error(`[incanto] could not open the editor:`,e),await i(r)}},`opening the editor…`)}};if(u){let t=e.touchContainer??e.canvas.parentElement??(typeof document<`u`?document.body:null);if(t){let{attachDebugOverlay:r}=await bm(async()=>{let{attachDebugOverlay:e}=await import(`./debug-wSa-vYHO.js`);return{attachDebugOverlay:e}},[],import.meta.url),i=r(n,{container:t,statsSource:()=>l.stats?.()??{},...f?{actions:[p]}:{},...e._debugDoc?{doc:e._debugDoc}:{}});i&&o.push(()=>i.dispose())}}n.start(),await t(.16,`shaders`);try{l.deferFirstCompile?.();let t=globalThis.performance?.now?.()??0;n.tick(t),n.tick(t+16),await l.warmUp?.(t=>{e.onProgress?.(.16+t*.82,`shaders`)})}catch{}o.push(n.settings.bindAudio(n.audio)),o.push(n.settings.bindLocale(n.locale)),await t(1,`ready`);function m(){jm([a?[`physics`,()=>a?.dispose()]:null,[`app cleanups`,()=>{for(let e of o)e()}],[`engine`,()=>n.dispose()],[`renderer`,()=>l.dispose()]])}return{engine:n,scene:i,sourceJson:r,renderer:l,physics:a,assetErrors(){return l.assets?.errors()??[]},pick(e,t){return n.picker?.(e,t)??null},stats(){return{triangles:0,drawCalls:0,geometries:0,textures:0,...n.stats(),...l.stats?.()}},openEditor:f?p.run:null,dispose:m}}function AP(e){try{return structuredClone(e)}catch{throw new N(`BAD_FORMAT`,`createGame "scene" must be plain scene JSON (the imported *.scene.json object) — got something unclonable (a loaded Scene, class instances, or functions).`)}}function jP(e){if(e instanceof kh)return!0;for(let t of e.children)if(jP(t))return!0;return!1}function MP(e,t,n){let r=[],i=n;if(i.addEventListener&&r.push({target:i,type:`pointerdown`}),typeof window<`u`&&r.push({target:window,type:`keydown`}),r.length===0)return()=>{};function a(){for(let e of r)e.target.removeEventListener?.(e.type,o)}function o(){e.sfx.unlock(),e.music.unlock();let n=!1,r=e=>{e instanceof Rt&&(e.retryPending(),e.pendingGesture&&(n=!0));for(let t of e.children)r(t)};r(t),n||a()}for(let e of r)e.target.addEventListener?.(e.type,o,{passive:!0});return a}var NP=e({DEFAULT_TERRAIN_TEXTURE_BASE:()=>tT,WATER_CUTOUT_MAX:()=>4,WATER_MAX_RIPPLES:()=>8,createGame3D:()=>kP,enablePhysics3D:()=>OT}),PP=new WeakMap,FP=class e{account;roomId;roomState=new j;allUserStates=new j;userJoined=new j;userLeft=new j;globalState=new j;globalMyState=new j;asset=new j;latestUserStates={};latestRoomState={};latestGlobalState={};latestGlobalMyState={};latestAsset={};server;engine;throttleMs;subs=[];messageSignals=new Map;collectionSignals=new Map;latestCollections=new Map;globalMessageSignals=new Map;globalCollectionSignals=new Map;latestGlobalCollections=new Map;scenes=new Map;lastSent=new Map;sendAccumulator=0;detachReplication=null;lastOwner=null;boundScene=null;static get(e){return PP.get(e)??null}static async create(t,n={}){await PP.get(t)?.dispose();let r=n.transport??await BP(n.config);await r.connect();let i=n.room??t.scene?.multiplayer?.room??`auto`,a=new e(t,r,await r.remoteFunction(`joinRoom`,[i===`auto`?void 0:i],{needResponse:!0}),n.throttleMs??50);return PP.set(t,a),a}constructor(e,t,n,r){this.engine=e,this.server=t,this.roomId=n,this.account=t.account,this.throttleMs=Math.max(30,r),this.boundScene=e.scene,this.subs.push(t.subscribeRoomState(n,e=>{this.latestRoomState=e,this.roomState.emit(e)}),t.subscribeRoomAllUserStates(n,e=>{this.latestUserStates=e,this.allUserStates.emit(e)}),t.onRoomUserJoin(n,e=>this.userJoined.emit(e)),t.onRoomUserLeave(n,e=>this.userLeft.emit(e))),t.subscribeGlobalState&&this.subs.push(t.subscribeGlobalState(e=>{this.latestGlobalState=e,this.globalState.emit(e)})),t.subscribeGlobalMyState&&this.subs.push(t.subscribeGlobalMyState(e=>{this.latestGlobalMyState=e,this.globalMyState.emit(e)})),t.subscribeAsset&&this.subs.push(t.subscribeAsset(this.account,e=>{this.latestAsset=e,this.asset.emit(e)})),this.detachReplication=e.fixedUpdated.connect(e=>this.replicate(e))}message(e){let t=this.messageSignals.get(e);return t||(t=new j,this.messageSignals.set(e,t),this.subs.push(this.server.onRoomMessage(this.roomId,e,e=>t?.emit(e)))),t}collection(e){let t=this.collectionSignals.get(e);return t||(t=new j,this.collectionSignals.set(e,t),this.subs.push(this.server.subscribeRoomCollection(this.roomId,e,n=>{this.latestCollections.set(e,n),t?.emit(n)}))),t}latestCollection(e){return this.collection(e),this.latestCollections.get(e)??{}}globalMessage(e){let t=this.globalMessageSignals.get(e);if(!t){t=new j,this.globalMessageSignals.set(e,t);let n=this.server.onGlobalMessage?.(e,e=>t?.emit(e));n&&this.subs.push(n)}return t}globalCollection(e){let t=this.globalCollectionSignals.get(e);if(!t){t=new j,this.globalCollectionSignals.set(e,t);let n=this.server.subscribeGlobalCollection?.(e,n=>{this.latestGlobalCollections.set(e,n),t?.emit(n)});n&&this.subs.push(n)}return t}latestGlobalCollection(e){return this.globalCollection(e),this.latestGlobalCollections.get(e)??{}}setMyState(e){return this.server.remoteFunction(`setMyState`,[this.roomId,e],{throttle:this.throttleMs,throttleKey:`incanto:myState`})}patchRoomState(e){return this.server.remoteFunction(`patchRoomState`,[this.roomId,e])}addEntity(e,t){return this.server.remoteFunction(`addEntity`,[this.roomId,e,t])}updateEntity(e,t,n){return this.server.remoteFunction(`updateEntity`,[this.roomId,e,t,n])}removeEntity(e,t){return this.server.remoteFunction(`removeEntity`,[this.roomId,e,t])}sendEvent(e,t){return this.server.remoteFunction(`sendEvent`,[this.roomId,e,t])}call(e,...t){return this.server.remoteFunction(e,[this.roomId,...t],{needResponse:!0})}registerScene(e,t){this.scenes.set(e,t)}resolveScene(e){let t=this.scenes.get(e);if(!t)throw new N(`UNRESOLVED_INSTANCE`,`No scene registered for '${e}'. Registered: [${[...this.scenes.keys()].join(`, `)}]. Call manager.registerScene('${e}', sceneJson).`);return t}async dispose(){this.detachReplication?.();for(let e of this.subs)e();await this.server.remoteFunction(`leaveRoom`,[this.roomId]),PP.delete(this.engine)}replicate(e){let t=this.engine.scene;if(!t||t!==this.boundScene)return;this.sendAccumulator+=e*1e3;let n=IP(t.root,!0);if(!n)return;n!==this.lastOwner&&(this.lastOwner=n,this.lastSent.clear());let r=n.network,i=Math.max(30,typeof r.throttleMs==`number`?r.throttleMs:this.throttleMs),a=Array.isArray(r.sync)?r.sync:[],o={};for(let e of a){let t=RP(n,e);t!==void 0&&(Ve(this.lastSent.get(e)??null,t)||(o[e]=He(t)))}if(!(this.sendAccumulator<i)&&Object.keys(o).length!==0){for(let[e,t]of Object.entries(o))this.lastSent.set(e,He(t));this.sendAccumulator=0,this.setMyState({sync:o})}}};function IP(e,t=!1){let n=[];if(LP(e,n),t&&n.length>1)throw new N(`BAD_FORMAT`,`Multiple network owner nodes found (${n.map(e=>e.getPath()).join(`, `)}). Exactly ONE node per player may declare network.mode 'owner' — replicate spawned entities through collections instead.`);return n[0]??null}function LP(e,t){e.network?.mode===`owner`&&t.push(e);for(let n of e.children)LP(n,t)}function RP(e,t){let n=t.lastIndexOf(`.`),r=n===-1?e:e.getNodeOrNull(t.slice(0,n))??void 0,i=n===-1?t:t.slice(n+1);if(r)return r[i]}function zP(e,t,n){for(let[r,i]of Object.entries(t)){let t=r.lastIndexOf(`.`),a=t===-1?e:e.getNodeOrNull(r.slice(0,t)),o=t===-1?r:r.slice(t+1);a&&n(a,o,i)}}async function BP(e){let{createAgent8Server:t}=await bm(async()=>{let{createAgent8Server:e}=await import(`./agent8-BfxUNrEe.js`);return{createAgent8Server:e}},[],import.meta.url);return t(e)}var VP=class extends Nt{static typeName=`NetworkSpawner`;static signals=[`spawned`,`despawned`];static props={source:{default:`users`},scene:{default:``},interpolate:{default:!0}};source=`users`;scene=``;interpolate=!0;spawned=new Map;positionTargets=new Map;failedKeys=new Set;update(e){let t=this.tree?.engine;if(!t)return;let n=FP.get(t);if(!n||this.scene===``)return;let r=this.currentEntries(n);for(let[e,t]of Object.entries(r)){let r=this.spawned.get(e);if(!r){if(this.failedKeys.has(e))continue;try{r=jn(n.resolveScene(this.scene).root)}catch(t){throw this.failedKeys.add(e),t}r.name=HP(e),this.addChild(r),this.spawned.set(e,r),this.emit(`spawned`,r,e)}let i=t.sync;i&&zP(r,i,(e,t,n)=>this.setProp(e,t,n))}for(let[e,t]of[...this.spawned.entries()])e in r||(this.spawned.delete(e),this.positionTargets.delete(t),this.emit(`despawned`,t,e),t.free());this.interpolate&&this.stepInterpolation(e)}currentEntries(e){if(this.source===`users`){let t={};for(let[n,r]of Object.entries(e.latestUserStates))n!==e.account&&(t[n]=r);return t}return this.source.startsWith(`collection:`)?e.latestCollection(this.source.slice(11)):{}}setProp(e,t,n){if(this.interpolate&&t===`position`&&Array.isArray(n)){this.positionTargets.set(e,n);return}e[t]=n}stepInterpolation(e){let t=Math.min(1,e*8);for(let[e,n]of this.positionTargets){let r=e.position;Array.isArray(r)&&(e.position=r.map((e,r)=>e+((n[r]??e)-e)*t))}}};function HP(e){return e.replace(/[/%]/g,`_`)||`remote`}function UP(){_n(),R(VP)}function WP(){try{return typeof localStorage>`u`?null:localStorage}catch{return null}}var GP=WP()?.getItem(`incanto-editor-lang`)??`en`,KP=new Set;function qP(){return GP}function JP(e){GP=e,WP()?.setItem(`incanto-editor-lang`,e);for(let e of KP)e()}function YP(e){KP.add(e)}function XP(e){return e[GP]}var ZP={node:{paths:[`M5 5h14v14H5z`]},move:{paths:[`M12 3v18M3 12h18`,`M8 7l4-4 4 4M8 17l4 4 4-4M7 8l-4 4 4 4M17 8l4 4-4 4`]},image:{paths:[`M4 5h16v14H4z`,`M4 15l5-5 4 4 3-3 4 4`],circles:[[9,9,1.6]]},film:{paths:[`M4 4h16v16H4z`,`M4 9h16M4 15h16`,`M9 4v16M15 4v16`]},video:{paths:[`M3 7h12v10H3z`,`M15 10l6-3v10l-6-3`]},text:{paths:[`M5 7V5h14v2`,`M12 5v14`,`M9 19h6`]},layers:{paths:[`M12 3 3 8l9 5 9-5-9-5z`,`M3 12l9 5 9-5`,`M3 16l9 5 9-5`]},square:{paths:[`M5 5h14v14H5z`,`M5 12h14`]},ball:{paths:[`M12 8v0`],circles:[[12,12,8],[12,12,1.4]]},person:{paths:[`M5 21v-1a7 7 0 0 1 14 0v1`],circles:[[12,7,4]]},area:{paths:[`M5 5h14v14H5z`],dashed:!0},gamepad:{paths:[`M7 9h-0M6 12h4M8 10v4`,`M4 8h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2z`],circles:[[16,11,1],[18.5,13.5,1]]},clock:{paths:[`M12 7v5l3 2`],circles:[[12,12,9]]},cube:{paths:[`M21 16V8l-9-5-9 5v8l9 5 9-5z`,`M3.3 7.5 12 12.5l8.7-5`,`M12 22V12.5`]},sun:{paths:[`M12 2v3M12 19v3M2 12h3M19 12h3M4.9 4.9l2.1 2.1M17 17l2.1 2.1M19.1 4.9 17 7M7 17l-2.1 2.1`],circles:[[12,12,4]]},bulb:{paths:[`M9 18h6M10 21h4`,`M8 13a6 6 0 1 1 8 0c-1 1-1.5 2-1.5 3h-5c0-1-.5-2-1.5-3z`]},globe:{paths:[`M2 12h20`,`M12 2a15 15 0 0 1 0 20a15 15 0 0 1 0-20z`],circles:[[12,12,10]]},link:{paths:[`M10 14a5 5 0 0 0 7 0l3-3a5 5 0 0 0-7-7l-1 1`,`M14 10a5 5 0 0 0-7 0l-3 3a5 5 0 0 0 7 7l1-1`]},speaker:{paths:[`M11 5 6 9H3v6h3l5 4V5z`,`M15.5 8.5a5 5 0 0 1 0 7M18.5 5.5a9 9 0 0 1 0 13`]},swatch:{paths:[`M4 4h16v16H4z`,`M4 4l16 16`]},sparkles:{paths:[`M12 4v5M12 15v5M5 12h5M14 12h5`],circles:[[6,5,1],[18,19,1]]},waves:{paths:[`M2 8c3-3 5 3 8 0s5 3 8 0`,`M2 14c3-3 5 3 8 0s5 3 8 0`,`M2 20c3-3 5 3 8 0s5 3 8 0`]},plant:{paths:[`M12 21v-8`,`M12 13c0-4-3-6-7-6 0 4 3 6 7 6z`,`M12 11c0-4 3-6 7-6 0 4-3 6-7 6z`]},flower:{paths:[`M12 21v-7`],circles:[[12,9,2],[12,4.5,2.2],[16.3,7.5,2.2],[14.7,12.6,2.2],[9.3,12.6,2.2],[7.7,7.5,2.2]]},voxels:{paths:[`M4 14h8v8H4z`,`M12 14h8v8h-8z`,`M8 6h8v8H8z`]}},QP={Node:`node`,Timer:`clock`,AudioPlayer:`speaker`,ColorRect2D:`swatch`,Particles2D:`sparkles`,Particles3D:`sparkles`,Water3D:`waves`,Foliage3D:`plant`,Flowers3D:`flower`,VoxelGrid3D:`voxels`,ModelInstance3D:`person`,CharacterController3D:`gamepad`,Node2D:`move`,Sprite2D:`image`,AnimatedSprite2D:`film`,Camera2D:`video`,Label:`text`,UILayer:`layers`,StaticBody2D:`square`,RigidBody2D:`ball`,CharacterBody2D:`person`,Area2D:`area`,CharacterController2D:`gamepad`,Node3D:`move`,Billboard3D:`layers`,MeshInstance3D:`cube`,LoftMesh3D:`cube`,Camera3D:`video`,DirectionalLight3D:`sun`,OmniLight3D:`bulb`,StaticBody3D:`square`,RigidBody3D:`ball`,CharacterBody3D:`person`,Area3D:`area`,NetworkSpawner:`globe`};function $P(e){let t=ZP[QP[e??``]??(e?`node`:`link`)],n=document.createElementNS(`http://www.w3.org/2000/svg`,`svg`);n.setAttribute(`viewBox`,`0 0 24 24`),n.setAttribute(`width`,`13`),n.setAttribute(`height`,`13`),n.setAttribute(`fill`,`none`),n.setAttribute(`stroke`,`currentColor`),n.setAttribute(`stroke-width`,`2`),n.setAttribute(`stroke-linecap`,`round`),n.setAttribute(`stroke-linejoin`,`round`),t.dashed&&n.setAttribute(`stroke-dasharray`,`3 2.4`);for(let e of t.paths){let t=document.createElementNS(`http://www.w3.org/2000/svg`,`path`);t.setAttribute(`d`,e),n.appendChild(t)}for(let[e,r,i]of t.circles??[]){let t=document.createElementNS(`http://www.w3.org/2000/svg`,`circle`);t.setAttribute(`cx`,String(e)),t.setAttribute(`cy`,String(r)),t.setAttribute(`r`,String(i)),n.appendChild(t)}return n}function eF(){let e=document.createElementNS(`http://www.w3.org/2000/svg`,`svg`);e.setAttribute(`viewBox`,`0 0 24 24`),e.setAttribute(`width`,`12`),e.setAttribute(`height`,`12`),e.setAttribute(`fill`,`none`),e.setAttribute(`stroke`,`currentColor`),e.setAttribute(`stroke-width`,`2.4`),e.setAttribute(`aria-hidden`,`true`);let t=document.createElementNS(`http://www.w3.org/2000/svg`,`path`);return t.setAttribute(`d`,`m6 9 6 6 6-6`),e.appendChild(t),e}var tF=[{type:`texture`,label:`image (texture)`,metaHints:[`filter`]},{type:`spritesheet`,label:`spritesheet`,metaHints:[`filter`,`frameWidth`,`frameHeight`]},{type:`model`,label:`3D model (GLB/VRM)`,metaHints:[]},{type:`animation`,label:`animation (GLB clips)`,metaHints:[`clip`]}],nF=new Set,rF=null,iF=null;function aF(e,t,n){let r=document.createElement(`input`);r.className=`rename-input`,r.value=e;let i=()=>{let i=r.value.trim().replace(/\//g,``);i&&i!==e?t(i):n()};r.addEventListener(`keydown`,e=>{e.stopPropagation(),e.key===`/`&&e.preventDefault(),e.key===`Enter`&&i(),e.key===`Escape`&&n()});for(let e of[`click`,`pointerdown`,`dblclick`,`mousedown`])r.addEventListener(e,e=>e.stopPropagation());return r.addEventListener(`blur`,i),queueMicrotask(()=>{r.focus(),r.select()}),r}function oF(e,t){let n={path:``,name:``,folders:new Map,assets:[]},r=e=>{let t=n;if(e===``)return t;for(let n of e.split(`/`)){let e=t.folders.get(n);e||(e={path:t.path?`${t.path}/${n}`:n,name:n,folders:new Map,assets:[]},t.folders.set(n,e)),t=e}return t};for(let t of e){let e=t.lastIndexOf(`/`);r(e===-1?``:t.slice(0,e)).assets.push(t)}for(let e of t)r(e);return n}function sF(e){let t=e.assets.length;for(let n of e.folders.values())t+=sF(n);return t}function cF(e,t){e.textContent=``;let n=t.working.assets??{},r=Object.keys(n);if(r.length===0&&t.pendingGroups.size===0&&!t.addingAsset&&!t.addingGroup){let t=document.createElement(`div`);t.className=`muted-note explorer-empty`,t.textContent=`no assets yet — + adds textures, models, animations`,e.appendChild(t);return}let i=(e,n)=>{e.addEventListener(`dragover`,t=>{t.preventDefault(),t.stopPropagation(),e.classList.add(`drop-target`)}),e.addEventListener(`dragleave`,()=>e.classList.remove(`drop-target`)),e.addEventListener(`drop`,r=>{r.preventDefault(),r.stopPropagation(),e.classList.remove(`drop-target`);let i=r.dataTransfer?.getData(`text/incanto-asset`);i&&t.moveAsset(i,n);let a=r.dataTransfer?.getData(`text/incanto-group`);a&&t.moveGroup(a,n)})};i(e,``);let a=(e,r)=>{let i=n[e],a=e.includes(`/`)?e.slice(e.lastIndexOf(`/`)+1):e,o=document.createElement(`div`);o.className=`tree-row asset-row${t.selectedAsset===e?` selected`:``}`,o.draggable=!0,o.addEventListener(`dragstart`,t=>{t.dataTransfer?.setData(`text/incanto-asset`,e)});let s=document.createElement(`span`);if(s.className=`tree-icon`,s.appendChild(wF(i.type??``)),s.addEventListener(`click`,e=>{e.stopPropagation(),TF(s,i.type??``)}),rF===e){let n=e.includes(`/`)?e.slice(0,e.lastIndexOf(`/`)+1):``;o.appendChild(aF(a,r=>{rF=null,t.renameAssetKey(e,n+r)},()=>{rF=null,t.selectAsset(t.selectedAsset)})),o.draggable=!1,o.insertBefore(s,o.firstChild),r.appendChild(o);return}let c=document.createElement(`span`);c.className=`tree-name asset-key`,c.textContent=`$${a}`,c.title=`$${e}`,c.addEventListener(`dblclick`,n=>{n.stopPropagation(),rF=e,t.selectAsset(e)}),o.append(s,c),o.addEventListener(`click`,()=>t.selectAsset(e)),r.appendChild(o)},o=(e,n)=>{let r=nF.has(e.path),s=document.createElement(`div`);s.className=`asset-folder${r?` collapsed`:``}${t.selectedGroup===e.path?` selected`:``}`,s.draggable=!0,s.addEventListener(`dragstart`,t=>{t.stopPropagation(),t.dataTransfer?.setData(`text/incanto-group`,e.path)});let c=document.createElement(`span`);c.className=`chev`,c.appendChild(eF());let l=document.createElementNS(`http://www.w3.org/2000/svg`,`svg`);l.setAttribute(`viewBox`,`0 0 24 24`),l.setAttribute(`width`,`12`),l.setAttribute(`height`,`12`),l.setAttribute(`fill`,`none`),l.setAttribute(`stroke`,`currentColor`),l.setAttribute(`stroke-width`,`1.8`),l.setAttribute(`aria-hidden`,`true`);let u=document.createElementNS(`http://www.w3.org/2000/svg`,`path`);if(u.setAttribute(`d`,`M3 6a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z`),l.appendChild(u),iF===e.path){let i=e.path.includes(`/`)?e.path.slice(0,e.path.lastIndexOf(`/`)+1):``;if(s.append(c,l,aF(e.name,n=>{iF=null,t.renameGroup(e.path,i+n)},()=>{iF=null,t.selectGroup(t.selectedGroup)})),s.draggable=!1,n.appendChild(s),!r){let t=document.createElement(`div`);t.className=`tree-children`;for(let n of e.folders.values())o(n,t);for(let n of e.assets)a(n,t);t.children.length>0&&n.appendChild(t)}return}let d=document.createElement(`span`);d.textContent=e.name,d.addEventListener(`dblclick`,n=>{n.stopPropagation(),iF=e.path,t.selectGroup(e.path)});let f=document.createElement(`span`);if(f.className=`count`,f.textContent=`(${sF(e)})`,s.append(c,l,d,f),s.addEventListener(`click`,()=>{nF.has(e.path)?nF.delete(e.path):nF.add(e.path),t.selectGroup(e.path)}),i(s,e.path),n.appendChild(s),!r){let t=document.createElement(`div`);t.className=`tree-children`;for(let n of e.folders.values())o(n,t);for(let n of e.assets)a(n,t);t.children.length>0&&n.appendChild(t)}},s=oF(r,t.pendingGroups);for(let t of s.assets)a(t,e);for(let t of s.folders.values())o(t,e)}function lF(e,t,n,r){if(t.selection!==null)return!1;if(t.addingGroup){e.appendChild(kF(t.newGroupParent?`NEW GROUP IN ${t.newGroupParent}/`:`NEW GROUP`));let n=document.createElement(`input`);n.placeholder=t.newGroupParent?`heroes`:`characters (or a/b to nest)`,n.className=`mono`,e.appendChild(yF(`name`,n));let r=document.createElement(`button`);r.type=`button`,r.className=`primary`,r.textContent=`add`;let i=()=>{let e=n.value.trim().replace(/^\/+|\/+$/g,``);e&&(t.cancelAddForms(),t.addGroup(t.newGroupParent?`${t.newGroupParent}/${e}`:e))};r.addEventListener(`click`,i),n.addEventListener(`keydown`,e=>{e.key===`Enter`&&i()});let a=document.createElement(`div`);return a.className=`pop-actions`,a.appendChild(r),e.appendChild(a),setTimeout(()=>n.focus(),0),!0}if(t.addingAsset)return pF(e,t,r);if(t.selectedGroup!==null){let r=t.selectedGroup,i=t.groupCount(r);e.appendChild(kF(`GROUP (${i} asset${i===1?``:`s`})`));let a=r.includes(`/`)?r.slice(0,r.lastIndexOf(`/`)+1):``,o=r.includes(`/`)?r.slice(r.lastIndexOf(`/`)+1):r;e.appendChild(bF(`name`,o,e=>{let n=e.trim().replace(/\/+/g,``);n&&n!==o&&t.renameGroup(r,a+n)}));let s=document.createElement(`button`);return s.type=`button`,s.className=`ghost danger`,s.textContent=`delete group`,s.addEventListener(`click`,()=>{if(i===0){t.deleteGroup(r);return}n(`'${r}/' contains ${i} asset${i===1?``:`s`} — deleting the group deletes them too.`,`delete group & assets`,()=>t.deleteGroup(r))}),e.appendChild(s),!0}let i=t.selectedAsset;if(i===null)return!1;let a=t.working.assets??{};if(!(i in a))return!1;e.appendChild(kF(`ASSET — ${String(a[i].type??`?`)}`)),e.appendChild(EF(i)),e.appendChild(DF(t,i)),e.appendChild(uF(t,a,i,r));let o=document.createElement(`button`);return o.type=`button`,o.className=`ghost danger`,o.textContent=`delete asset`,o.addEventListener(`click`,()=>{t.selectAsset(null),t.mutate(()=>{delete a[i],Object.keys(a).length===0&&delete t.working.assets})}),e.appendChild(o),!0}function uF(e,t,n,r){let i=t[n],a=document.createElement(`div`);a.className=`asset-editor`;let o=n.includes(`/`)?n.slice(n.lastIndexOf(`/`)+1):n,s=n.includes(`/`)?n.slice(0,n.lastIndexOf(`/`)+1):``,c=bF(`name`,o,t=>{let r=t.trim().replace(/^\$/,``).replace(/\//g,``);r&&r!==o&&e.renameAssetKey(n,s+r)});OF(c.querySelector(`input`)),a.appendChild(c);let l=bF(`url`,String(i.url??``),t=>{e.mutate(()=>{i.url=t.trim()})}),u=l.querySelector(`input`);if(r&&u){let t=hF(String(i.type??``));l.appendChild(vF(()=>t,`asset url`,r,t=>{u.value=t,e.mutate(()=>{i.url=t})},()=>_F(t,e)))}a.appendChild(l);let d=document.createElement(`div`);d.className=`muted-note`,d.textContent=`meta (key · value)`,a.appendChild(d);for(let[t,n]of Object.entries(i))t===`type`||t===`url`||a.appendChild(dF(e,i,t,n));return a.appendChild(fF(e,i)),a}function dF(e,t,n,r){let i=document.createElement(`div`);i.className=`meta-row`;let a=document.createElement(`input`);a.value=n,a.className=`mono`;let o=document.createElement(`input`);o.value=typeof r==`string`?r:JSON.stringify(r),o.className=`mono`;let s=()=>{let r=a.value.trim();e.mutate(()=>{delete t[n],r&&(t[r]=xF(o.value))})};a.addEventListener(`change`,s),o.addEventListener(`change`,s);let c=document.createElement(`button`);return c.type=`button`,c.className=`linklike danger-link`,c.textContent=`✕`,c.addEventListener(`click`,()=>{e.mutate(()=>{delete t[n]})}),i.append(a,o,c),i}function fF(e,t){let n=document.createElement(`div`);n.className=`meta-row`;let r=document.createElement(`input`);r.placeholder=`filter…`,r.className=`mono`;let i=document.createElement(`input`);i.placeholder=`nearest`,i.className=`mono`;let a=()=>{let n=r.value.trim();!n||i.value.trim()===``||e.mutate(()=>{t[n]=xF(i.value)})};return r.addEventListener(`change`,a),i.addEventListener(`change`,a),n.append(r,i,document.createElement(`span`)),n}function pF(e,t,n){return e.appendChild(kF(`NEW ASSET`)),e.appendChild(mF(t,n)),!0}function mF(e,t){let n=document.createElement(`div`);n.className=`asset-editor`;let r=document.createElement(`select`);for(let e of tF){let t=document.createElement(`option`);t.value=e.type,t.textContent=e.label,r.appendChild(t)}n.appendChild(yF(`type`,r));let i=document.createElement(`input`);i.placeholder=`(optional) characters`,i.className=`mono`,i.value=e.newAssetGroup;let a=`asset-groups-list`;i.setAttribute(`list`,a);let o=document.createElement(`datalist`);o.id=a;let s=new Set;for(let t of Object.keys(e.working.assets??{})){let e=t.lastIndexOf(`/`);e!==-1&&s.add(t.slice(0,e))}for(let t of e.pendingGroups)s.add(t);for(let e of s){let t=document.createElement(`option`);t.value=e,o.appendChild(t)}n.appendChild(yF(`group`,i)),n.appendChild(o);let c=document.createElement(`input`);c.placeholder=`coin`,c.className=`mono`,OF(c),n.appendChild(yF(`key`,c));let l=document.createElement(`input`);l.placeholder=`/textures/coin.png · https://… · data:…`,l.className=`mono`;let u=yF(`url`,l);t&&u.appendChild(vF(()=>hF(r.value),`new asset`,t,e=>{l.value=e,c.value.trim()||(c.value=gF(e))},()=>_F(hF(r.value),e))),n.appendChild(u);let d=document.createElement(`textarea`);d.rows=2,d.placeholder=`or paste a JSON object: { "type": "model", "url": "/m.glb" }`,n.appendChild(d);let f=document.createElement(`button`);f.type=`button`,f.className=`primary`,f.textContent=`add`,f.addEventListener(`click`,()=>{let t=c.value.trim().replace(/^\$/,``);if(!t)return;let n=i.value.trim().replace(/\/+$/,``),a=n?`${n}/${t}`:t,o=null,s=d.value.trim();if(s)try{o=JSON.parse(s)}catch{d.classList.add(`invalid`);return}else l.value.trim()&&(o={type:r.value,url:l.value.trim()});o&&(e.cancelAddForms(),e.selectedAsset=a,e.mutate(()=>{e.working.assets||(e.working.assets={});let t=e.working.assets;t[a]=o}))});let p=document.createElement(`div`);return p.className=`pop-actions`,p.appendChild(f),n.appendChild(p),n}function hF(e){return e===`model`||e===`animation`?`model`:e===`audio`?`audio`:e===`texture`||e===`spritesheet`?`image`:`any`}function gF(e){return((e.split(/[?#]/)[0]??``).split(`/`).pop()??``).replace(/\.[^.]+$/,``).replace(/[^a-zA-Z0-9_-]+/g,`_`).replace(/_{2,}/g,`_`).replace(/^_+|_+$/g,``).toLowerCase()||`asset`}function _F(e,t){let n=(t.working.dimension??`2d`)===`3d`;if(e===`image`)return n?[`3d`,`textures`]:[`2d`,`sprite_characters`];if(e===`model`)return[`3d`,`characters`]}function vF(e,t,n,r,i){let a=document.createElement(`button`);return a.type=`button`,a.className=`asset-lib`,a.textContent=`📚`,a.title=`Browse the agent8 library`,a.addEventListener(`click`,a=>{a.preventDefault();let o=i?.();n({kind:e(),target:t,...o?{shelf:o}:{}}).then(e=>{e&&r(e)})}),a}function yF(e,t){let n=document.createElement(`label`);n.className=`field`;let r=document.createElement(`span`);return r.textContent=e,n.append(r,t),n}function bF(e,t,n){let r=document.createElement(`input`);return r.value=t,r.className=`mono`,r.addEventListener(`change`,()=>n(r.value)),yF(e,r)}function xF(e){let t=e.trim();if(t===`true`)return!0;if(t===`false`)return!1;if(t!==``&&Number.isFinite(Number(t)))return Number(t);if(t.startsWith(`{`)||t.startsWith(`[`))try{return JSON.parse(t)}catch{return e}return e}var SF={texture:`M3 5h18v14H3z M3 15l5-5 4 4 3-3 6 6 M8.5 9.5h.01`,spritesheet:`M3 4h18v16H3z M9 4v16 M15 4v16 M3 12h18`,model:`M12 2l9 5v10l-9 5-9-5V7z M12 12l9-5 M12 12L3 7 M12 12v10`,animation:`M12 2a10 10 0 1 0 10 10 M22 12l-3-3m3 3l3-3 M12 7v5l3 3`},CF={texture:{en:`image (texture) — Sprite2D.texture references it as "$key".`,ko:`이미지(텍스처) — Sprite2D.texture에서 "$키"로 참조합니다.`},spritesheet:{en:`spritesheet — AnimatedSprite2D slices it into named frame animations.`,ko:`스프라이트시트 — AnimatedSprite2D가 이름 붙은 프레임 애니메이션으로 자릅니다.`},model:{en:`3D model (GLB/glTF/VRM) — ModelInstance3D.model references it as "$key".`,ko:`3D 모델(GLB/glTF/VRM) — ModelInstance3D.model에서 "$키"로 참조합니다.`},animation:{en:`animation clips (GLB, in memory — drawn nowhere) — any model can play them; mixamo retargets onto VRM.`,ko:`애니메이션 클립(GLB, 메모리 전용 — 그려지지 않음) — 어떤 모델이든 재생 가능, mixamo는 VRM에 자동 리타게팅.`}};function wF(e){let t=document.createElementNS(`http://www.w3.org/2000/svg`,`svg`);t.setAttribute(`viewBox`,`0 0 24 24`),t.setAttribute(`width`,`13`),t.setAttribute(`height`,`13`),t.setAttribute(`fill`,`none`),t.setAttribute(`stroke`,`currentColor`),t.setAttribute(`stroke-width`,`1.8`),t.setAttribute(`aria-hidden`,`true`);let n=document.createElementNS(`http://www.w3.org/2000/svg`,`path`);return n.setAttribute(`d`,SF[e]??`M4 4h16v16H4z`),t.appendChild(n),t.classList.add(`asset-icon-${e}`),t}function TF(e,t){document.querySelector(`.balloon`)?.remove();let n=CF[t];if(!n)return;let r=document.createElement(`div`);r.className=`balloon floating`;let i=document.createElement(`div`);i.className=`balloon-title`,i.textContent=t;let a=document.createElement(`span`);a.textContent=XP(n),r.append(i,a),document.body.appendChild(r);let o=e.getBoundingClientRect();r.style.left=`${o.right+8}px`,r.style.top=`${Math.max(8,o.top-8)}px`;let s=()=>{r.remove(),document.removeEventListener(`pointerdown`,s,!0)};setTimeout(()=>document.addEventListener(`pointerdown`,s,!0),0)}function EF(e){let t=document.createElement(`div`);t.className=`field uid-line`;let n=document.createElement(`span`);n.textContent=`key`;let r=document.createElement(`div`);r.className=`uid-value`;let i=document.createElement(`code`);i.textContent=`$${e}`;let a=document.createElement(`button`);return a.type=`button`,a.className=`uid-copy`,a.title=`Copy key`,a.innerHTML=`<svg aria-hidden="true" width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>`,a.addEventListener(`click`,()=>{navigator.clipboard?.writeText(`$${e}`),a.classList.add(`copied`),setTimeout(()=>a.classList.remove(`copied`),600)}),r.append(i,a),t.append(n,r),t}function DF(e,t){let n=t.includes(`/`)?t.slice(0,t.lastIndexOf(`/`)):``,r=document.createElement(`select`),i=new Set([``]);for(let t of Object.keys(e.working.assets??{})){let e=t.split(`/`);for(let t=1;t<e.length;t++)i.add(e.slice(0,t).join(`/`))}for(let t of e.pendingGroups)i.add(t);for(let e of[...i].sort()){let t=document.createElement(`option`);t.value=e,t.textContent=e===``?`(root)`:`${e}/`,e===n&&(t.selected=!0),r.appendChild(t)}r.addEventListener(`change`,()=>{e.moveAsset(t,r.value)});let a=document.createElement(`label`);a.className=`field`;let o=document.createElement(`span`);return o.textContent=`group`,a.append(o,r),a}function OF(e){e&&(e.addEventListener(`keydown`,e=>{e.key===`/`&&e.preventDefault()}),e.addEventListener(`input`,()=>{e.value.includes(`/`)&&(e.value=e.value.replace(/\//g,``))}))}function kF(e){let t=document.createElement(`div`);t.className=`section-title`,t.textContent=e;let n=document.createElement(`span`);return n.className=`rule`,t.appendChild(n),t}var AF=window.parent!==window,jF=new URLSearchParams(window.location.search).get(`parentOrigin`),MF=!1;function NF(e){if(AF){if(!jF){MF||(MF=!0,console.warn(`incanto-editor: embedded without ?parentOrigin=<origin> — postMessage disabled`));return}window.parent.postMessage(e,jF)}}var PF={ready(e,t,n){NF({type:`incanto-editor:ready`,input:e,output:t,version:n})},open(e,t){NF({type:`incanto-editor:open`,input:e,output:t})},change(e){NF({type:`incanto-editor:change`,dirty:e})},save(e,t,n){NF({type:`incanto-editor:save`,input:e,output:t,data:n})},error(e){NF({type:`incanto-editor:error`,message:e})}},FF=[[`Core`,e=>!e.endsWith(`2D`)&&!e.endsWith(`3D`)&&e!==`Label`&&e!==`UILayer`&&e!==`NetworkSpawner`],[`2D`,e=>e.endsWith(`2D`)&&!/Body|Area|Controller/.test(e)||e===`Label`||e===`UILayer`],[`2D Physics`,e=>e.endsWith(`2D`)&&/Body|Area|Controller/.test(e)],[`3D`,e=>e.endsWith(`3D`)&&!/Body|Area|Controller/.test(e)],[`3D Physics`,e=>e.endsWith(`3D`)&&/Body|Area|Controller/.test(e)],[`Network`,e=>e===`NetworkSpawner`]],IF=[...FF,[`Other`,e=>FF.every(([,t])=>!t(e))]],LF={title:{en:`How Incanto scenes work`,ko:`Incanto 씬은 어떻게 동작하나`},sections:[{heading:{en:`Everything is a node in a tree`,ko:`모든 것은 트리 위의 노드`},text:{en:`A scene is ONE tree of typed nodes (Godot-style). Each node has a name (unique among its siblings), a type that defines its props and behavior, optional children, and an optional scene-wide-unique uid. The whole structure lives in a *.scene.json file — there is no hidden state: what you see in this editor IS the file.`,ko:`씬은 타입을 가진 노드들의 단일 트리입니다(Godot 방식). 각 노드는 이름(형제 간 유일), props와 동작을 결정하는 타입, 선택적 자식들, 그리고 선택적인 씬 전역 유일 uid를 가집니다. 전체 구조가 *.scene.json 파일 하나에 들어있고 숨겨진 상태는 없습니다 — 이 에디터에서 보는 것이 곧 파일 그 자체입니다.`}},{heading:{en:`Props are delta-only`,ko:`Props는 변경분만 기록`},text:{en:`Every prop has a default defined by the engine. The JSON only stores values that DIFFER from the default — so files stay small and diffs stay meaningful. This editor follows the same rule: set a value back to its default and it disappears from the file.`,ko:`모든 prop에는 엔진이 정의한 기본값이 있습니다. JSON에는 기본값과 다른 값만 기록되어 파일이 작고 diff가 의미를 가집니다. 이 에디터도 같은 규칙을 따릅니다 — 값을 기본값으로 되돌리면 파일에서 사라집니다.`}},{heading:{en:`Addressing: paths, names, uid, groups`,ko:`노드 찾기: 경로·이름·uid·그룹`},text:{en:`Code reaches nodes four ways: a path like "Player/Skin" (relative) or "%Unique" (marked-unique name), getNodesByName("Enemy") which returns a LIST (names repeat across the tree), getNodeByUid("n_x1y2") which returns exactly one node and survives moves/renames, and groups — free tags for queries like "every coin".`,ko:`코드는 네 가지 방법으로 노드에 접근합니다: "Player/Skin" 같은 경로(상대) 또는 "%Unique"(유일 표시 이름), 트리 전체에서 같은 이름을 모두 찾는 getNodesByName("Enemy") — 이름은 중복될 수 있어 리스트가 돌아옵니다 —, 정확히 한 노드를 돌려주고 이동/개명에도 살아남는 getNodeByUid("n_x1y2"), 그리고 "모든 코인"처럼 묶어 조회하는 자유 태그 groups.`}},{heading:{en:`Signals connect, behaviors act`,ko:`시그널로 잇고 비헤이비어로 움직인다`},text:{en:`Nodes emit signals (an Area2D fires triggerEnter, a Timer fires timeout). The scene's "connections" wire a signal to a handler — declaratively, in JSON. Game logic itself is a Behavior: a TypeScript class in YOUR game, attached by name via "script". The inspector's CONNECTIONS section shows and edits these links on the selected node — what it emits, what reaches it, and any end that no longer resolves. The handler code itself lives in your game.`,ko:`노드는 시그널을 발산합니다(Area2D의 triggerEnter, Timer의 timeout). 씬의 "connections"가 시그널을 핸들러에 선언적으로(JSON으로) 연결합니다. 게임 로직 자체는 Behavior — 게임 쪽 TypeScript 클래스이며 "script"에 이름으로 연결됩니다. 인스펙터의 CONNECTIONS 섹션이 선택한 노드의 연결을 보여주고 편집합니다 — 나가는 것, 들어오는 것, 그리고 더 이상 찾을 수 없는 끝. 핸들러 코드 자체는 게임에 있습니다.`}},{heading:{en:`Assets are declared, then referenced`,ko:`에셋은 선언하고 $키로 참조`},text:{en:`The scene header declares assets (textures, spritesheets, 3D models, animation clips) under a key; nodes reference them as "$key". Animations are data too: an {type:"animation"} asset loads GLB clips into memory and any ModelInstance3D can play them — Mixamo clips retarget onto VRM avatars automatically.`,ko:`씬 헤더에서 에셋(텍스처·스프라이트시트·3D 모델·애니메이션 클립)을 키로 선언하고, 노드는 "$key"로 참조합니다. 애니메이션도 데이터입니다 — {type:"animation"} 에셋이 GLB 클립을 메모리에 올리고 어떤 ModelInstance3D든 재생할 수 있으며, Mixamo 클립은 VRM 아바타에 자동 리타게팅됩니다.`}}]},Q=(e,t,...n)=>({type:e,summary:t,body:n}),RF=[{id:`core`,label:{en:`Core`,ko:`Core`},intro:{en:`Dimension-free building blocks: plain containers and the game clock. They render nothing themselves.`,ko:`차원과 무관한 기본 블록 — 순수 컨테이너와 게임 시계입니다. 스스로는 아무것도 그리지 않습니다.`},nodes:[Q(`Node`,{en:`A plain container with no transform.`,ko:`변환 없이 자식을 묶는 순수 컨테이너.`},{en:`Use it to group related nodes (all coins, all UI) without affecting their positions. Lifecycle, signals, groups, script — everything works; it just has no visual or spatial meaning of its own.`,ko:`위치에 영향을 주지 않으면서 관련 노드(코인 전부, UI 전부)를 묶을 때 씁니다. 라이프사이클·시그널·그룹·스크립트가 모두 동작하며, 시각적·공간적 의미만 없습니다.`}),Q(`Timer`,{en:"A serializable countdown that emits `timeout`.",ko:"`timeout` 시그널을 쏘는 직렬화 가능한 카운트다운."},{en:`Set waitTime (seconds), optionally autostart or oneShot, and connect its timeout signal to any handler. Because it is a node, the whole timing setup lives in the scene file — agents can read and tune it.`,ko:`waitTime(초)을 정하고 autostart·oneShot을 선택한 뒤 timeout 시그널을 핸들러에 연결하세요. 노드이기 때문에 타이밍 설정 전체가 씬 파일에 남아 에이전트가 읽고 조정할 수 있습니다.`}),Q(`HudLayer`,{en:`Screen-space HUD overlay above the canvas — parent for UiText/UiBar/UiBanner.`,ko:`캔버스 위 화면 고정 HUD 오버레이 — UiText/UiBar/UiBanner의 부모.`},{en:`A DOM overlay (position:fixed) that never blocks pointer input. Put UI widgets as children; each picks one of 9 anchors (topLeft…bottomRight). Works identically over 2D and 3D renderers; in headless/tests it is a silent no-op. zIndex lifts it above the canvas.`,ko:`포인터 입력을 가로막지 않는 DOM 오버레이(position:fixed)입니다. UI 위젯을 자식으로 두면 각자 9개 앵커(topLeft…bottomRight) 중 하나에 붙습니다. 2D·3D 렌더러 어디서나 동일하게 동작하고, 헤드리스/테스트에서는 조용히 no-op입니다. zIndex로 캔버스 위에 올립니다.`}),Q(`UiText`,{en:`A HUD text line — score, timers, hints.`,ko:`HUD 텍스트 한 줄 — 점수, 타이머, 힌트.`},{en:`Child of HudLayer. Set text/size/color in JSON; update from behaviors: (getNode('%Score') as UiText).text = String(score). shadow adds a soft outline for readability over any scene.`,ko:`HudLayer의 자식. text/size/color를 JSON으로 정하고, 비헤이비어에서 (getNode('%Score') as UiText).text = String(score) 로 갱신하세요. shadow는 어떤 화면 위에서도 읽히도록 부드러운 그림자를 더합니다.`}),Q(`UiBar`,{en:`A labeled progress bar — health, stamina, reload, boss HP.`,ko:`라벨 달린 진행 바 — 체력, 스태미나, 재장전, 보스 HP.`},{en:`Child of HudLayer. Drive value/max from behaviors; the fill animates and turns lowColor under lowThreshold (default 30%). width/height/color/background style it; label prefixes a small caption.`,ko:`HudLayer의 자식. 비헤이비어에서 value/max를 갱신하면 채움이 애니메이션되고 lowThreshold(기본 30%) 아래로 떨어지면 lowColor로 바뀝니다. width/height/color/background로 스타일, label로 작은 캡션을 붙입니다.`}),Q(`UiBanner`,{en:`Center-screen announcements with fade and a queue — "WAVE 2", "YOU DIED".`,ko:`페이드·큐가 있는 중앙 공지 — "WAVE 2", "YOU DIED".`},{en:`Child of HudLayer. Call show('WAVE 2', { color, seconds }) from behaviors; messages queue and fade in/out. seconds 0 = sticky until the next show(). clear() drops everything. Emits bannerShown(text).`,ko:`HudLayer의 자식. 비헤이비어에서 show('WAVE 2', { color, seconds })를 호출하면 메시지가 큐에 쌓여 페이드 인/아웃됩니다. seconds 0이면 다음 show()까지 고정, clear()로 전부 제거. bannerShown(text) 시그널을 냅니다.`}),Q(`UiButton`,{en:`A clickable HUD button — menus, START screens, dialog choices.`,ko:`클릭 가능한 HUD 버튼 — 메뉴, 시작 화면, 대화 선택지.`},{en:`Child of HudLayer. Set text/size/color/background; disabled greys it out. Emits the 'pressed' signal (behaviors: node.on('pressed', ...)); press() triggers it programmatically (gamepad menus, tests).`,ko:`HudLayer의 자식. text/size/color/background를 설정하고 disabled로 비활성화합니다. 'pressed' 시그널을 내며(비헤이비어에서 node.on('pressed', ...)), press()로 코드에서도 누를 수 있습니다(게임패드 메뉴, 테스트).`}),Q(`UiPanel`,{en:`A box that holds other widgets — the thing a menu, options screen or inventory actually is.`,ko:`다른 위젯을 담는 상자 — 메뉴·설정 화면·인벤토리가 실제로 이것입니다.`},{en:`Child of HudLayer. Widgets under it mount INSIDE it, so tree structure becomes screen structure; panels nest. layout column|row|grid with columns (an inventory is a grid panel, one child per slot), plus gap/padding/background/radius/width/height/border. width or height 0 = size to the contents.`,ko:`HudLayer의 자식. 그 아래 위젯들이 이 안에 마운트되어 트리 구조가 화면 구조가 됩니다(중첩 가능). layout은 column|row|grid이고 columns와 함께 씁니다(인벤토리 = grid 패널, 슬롯당 자식 하나). gap/padding/background/radius/width/height/border 지원. width·height가 0이면 내용에 맞춰집니다.`}),Q(`UiImage`,{en:`A picture in the HUD — item icons, portraits, a logo.`,ko:`HUD 안의 그림 — 아이템 아이콘, 초상화, 로고.`},{en:`src takes a url or a $assetKey (declare the icon once like any other asset). fit contain|cover|fill; tint multiplies through the picture, which is how an unaffordable item greys out in one prop; opacity for disabled states.`,ko:`src는 url 또는 $assetKey(아이콘도 다른 에셋처럼 한 번만 선언). fit은 contain|cover|fill, tint는 그림에 곱해져서 살 수 없는 아이템을 프롭 하나로 회색 처리합니다. opacity로 비활성 표현.`}),Q(`UiSlider`,{en:`A value the player sets — volume, sensitivity, difficulty.`,ko:`플레이어가 조절하는 값 — 볼륨, 감도, 난이도.`},{en:`Emits changed(value). label/value/min/max/step/width/color. Setting .value from a behavior updates the control WITHOUT re-emitting, so restoring a saved setting does not fire the handler that saved it.`,ko:`changed(value) 시그널. label/value/min/max/step/width/color. 비헤이비어에서 .value를 설정하면 컨트롤만 갱신되고 changed는 다시 발생하지 않습니다 — 저장된 설정을 복원할 때 저장 핸들러가 다시 도는 것을 막습니다.`}),Q(`UiToggle`,{en:`An on/off switch — mute, invert-Y, fullscreen.`,ko:`켜기/끄기 스위치 — 음소거, Y축 반전, 전체화면.`},{en:`Emits changed(boolean). label/value. Same no-re-emit rule as UiSlider when set from code.`,ko:`changed(boolean) 시그널. label/value. 코드에서 설정할 때 재발생하지 않는 규칙은 UiSlider와 같습니다.`}),Q(`UiLanguageSelect`,{en:`The language picker, already wired.`,ko:`이미 연결된 언어 선택기.`},{en:`Options are the locales the scene declares in "strings", each labeled with its own endonym. Picking one switches the game live and persists it. English is the base: any key a locale omits falls back to it, on purpose.`,ko:`옵션은 씬의 "strings"가 선언한 로케일이며, 각 언어의 자기 이름으로 표시됩니다. 선택하면 즉시 바뀌고 저장됩니다. 영어가 기준이라 로케일이 빠뜨린 키는 의도적으로 영어로 표시됩니다.`}),Q(`UiSelect`,{en:`One of several — quality, resolution, language.`,ko:`여러 개 중 하나 — 품질, 해상도, 언어.`},{en:`options is a comma-separated list ("low,medium,high"); value is the current one. Emits changed(value).`,ko:`options는 쉼표로 구분된 목록("low,medium,high"), value가 현재 선택입니다. changed(value) 시그널.`}),Q(`UiDialogue`,{en:`A typewriter dialogue box with a queue and choice buttons — the RPG conversation layer.`,ko:`타자기 효과·큐·선택지 버튼을 갖춘 대화창 — RPG 대화 레이어.`},{en:`Child of HudLayer (anchor bottom by default). say(speaker, text, choices?) queues lines; clicking (or advance()) reveals then advances; choice lines wait for choose(i). Signals: lineShown(text), choiceMade(index), dialogueFinished. charsPerSecond 0 = instant. Check .active to pause player input during conversations.`,ko:`HudLayer의 자식(기본 anchor bottom). say(화자, 텍스트, 선택지?)로 줄을 큐에 넣고, 클릭(또는 advance())이 전체 공개→다음 줄로 진행하며, 선택지 줄은 choose(i)를 기다립니다. 시그널: lineShown(text), choiceMade(index), dialogueFinished. charsPerSecond 0이면 즉시 표시. 대화 중 플레이어 입력을 멈추려면 .active를 확인하세요.`}),Q(`AudioPlayer`,{en:`Plays a sound: zero-asset procedural SFX, BGM loops, or one-shot effects.`,ko:`소리 재생 — 무에셋 절차적 효과음, 배경음 루프, 단발 효과음.`},{en:`Set preset (coin/jump/hurt/explosion/…) for an instant zero-asset SFX (pitch/seed vary it), or leave it "custom" and set src (URL or "$assetKey"). volume 0..1; bus routes through engine.audio (sfx|music) for global volume/mute; loop for music; autoplay starts on ready (browsers may hold it until the first user gesture). Call play()/stop() from game code. Dimension-free — 2D and 3D alike.`,ko:`preset(coin/jump/hurt/explosion/…)을 설정하면 즉시 무에셋 효과음이 납니다(pitch·seed로 변형). 아니면 "custom"으로 두고 src(URL 또는 "$에셋키")를 쓰세요. volume은 0..1, bus는 engine.audio(sfx|music)를 통해 전역 볼륨/음소거에 연결, 음악은 loop, autoplay는 준비되면 재생합니다(브라우저가 첫 입력까지 보류 가능). 게임 코드에서 play()/stop()을 부르세요. 2D·3D 어디서나 동작합니다.`})]},{id:`2d`,label:{en:`2D`,ko:`2D`},intro:{en:`The 2D world is y-down pixels: 1 unit = 1 px, (0,0) top-left, rotation in clockwise degrees. Rendering needs a current Camera2D.`,ko:`2D 세계는 y-아래 픽셀 좌표입니다: 1유닛=1px, (0,0)은 좌상단, 회전은 시계방향 도(degree). 렌더링에는 current 카메라(Camera2D)가 필요합니다.`},nodes:[Q(`Node2D`,{en:`The 2D transform container (position/rotation/scale).`,ko:`2D 변환 컨테이너(position/rotation/scale).`},{en:`Children inherit its transform — move the parent, everything follows. renderOrder orders drawing; visible hides the subtree.`,ko:`자식은 변환을 상속합니다 — 부모를 움직이면 전부 따라옵니다. renderOrder로 그리기 순서를, visible로 서브트리 표시를 제어합니다.`}),Q(`Sprite2D`,{en:`A textured quad.`,ko:`텍스처 사각형(스프라이트).`},{en:`texture is "$assetKey" from the scene assets. anchor [0.5,0.5] centers; flipX/flipY mirror; tint multiplies color; opacity fades. Size comes from the texture × scale.`,ko:`texture는 씬 에셋의 "$키"입니다. anchor [0.5,0.5]면 중앙 기준, flipX/flipY로 반전, tint로 색 곱, opacity로 투명도. 크기는 텍스처 × scale로 정해집니다.`}),Q(`ColorRect2D`,{en:`A flat colored rectangle — no texture needed.`,ko:`단색 사각형 — 텍스처 불필요.`},{en:`size [w,h] px, color, opacity, anchor. Backgrounds, platforms, walls, UI panels, generated-level tiles (maze2d/dungeon2d emit these) — blocky art without any asset.`,ko:`size [w,h] px, color, opacity, anchor. 배경·플랫폼·벽·UI 패널·생성 레벨 타일(maze2d/dungeon2d가 이걸 만듭니다) — 에셋 없이 만드는 블록 그래픽입니다.`}),Q(`TileMap2D`,{en:`A whole tile level as ONE node — grid render + merged static colliders.`,ko:`타일 레벨 전체를 노드 하나로 — 그리드 렌더 + 병합된 정적 콜라이더.`},{en:`Author cells as rows of characters: "." / space = empty, digits 0-9 = atlas tile index, other chars map through legend ({"G": 12}). texture is a "$atlas" asset read left-to-right top-to-bottom in tileSize squares (columns: 0 derives from the texture width). Tile indices listed in solid become static colliders, greedy-merged into a few rectangles. Cell (0,0) hangs its top-left on the node origin.`,ko:`cells를 문자 행으로 작성합니다: "."/공백 = 빈 칸, 숫자 0-9 = 아틀라스 타일 번호, 그 외 문자는 legend({"G": 12})로 매핑. texture는 tileSize 정사각형을 좌→우, 상→하로 읽는 "$아틀라스" 에셋입니다(columns: 0이면 텍스처 폭에서 유도). solid에 나열된 타일 번호는 정적 콜라이더가 되며 소수의 직사각형으로 탐욕 병합됩니다. (0,0) 칸의 좌상단이 노드 원점에 걸립니다.`}),Q(`AnimatedSprite2D`,{en:`Spritesheet animation player.`,ko:`스프라이트시트 애니메이션 플레이어.`},{en:`Point sheet at a "$sheet" asset, define animations as named frame ranges with fps/loop in JSON, set autoplay. Emits animationFinished(name) for one-shot chains.`,ko:`sheet에 "$시트" 에셋을 연결하고, JSON에 fps/loop를 가진 이름별 프레임 구간으로 animations를 정의한 뒤 autoplay를 지정하세요. 단발 애니메이션 연결을 위해 animationFinished(name)를 발산합니다.`}),Q(`Camera2D`,{en:`The 2D view: follow, zoom, limits.`,ko:`2D 시점 — 추적·줌·경계.`},{en:`position is the view CENTER. follow tracks a node path with smoothing (0..1, higher = snappier). limits [minX,minY,maxX,maxY] clamps the view inside a world region. current: true makes it THE camera.`,ko:`position은 화면의 중심입니다. follow가 노드 경로를 smoothing(0..1, 높을수록 빠릿)으로 추적합니다. limits [minX,minY,maxX,maxY]가 시점을 월드 영역 안에 가둡니다. current: true인 카메라가 실제 시점이 됩니다.`}),Q(`Particles2D`,{en:`A 2D particle emitter (fire, sparks, smoke…).`,ko:`2D 파티클 이미터(불·스파크·연기…).`},{en:`Start from a preset (fire/smoke/sparks/…) then override any prop: rate, lifetime/speed ranges, direction + spread, gravity, size/color/alpha start→end, additive blend. burst > 0 with emitting: false makes a one-shot that emits finished. Animates LIVE in this editor.`,ko:`preset(fire/smoke/sparks/…)에서 시작해 어떤 prop이든 덮어쓰세요: rate, lifetime/speed 구간, direction+spread, gravity, size/color/alpha 시작→끝, additive blend. emitting: false에 burst > 0이면 단발 발사 후 finished를 발산합니다. 이 에디터에서 라이브로 움직입니다.`}),Q(`Label`,{en:`Text rendered to a quad.`,ko:`텍스트를 그리는 노드.`},{en:`text/fontSize/color/font/align — rendered via CanvasTexture, so any system font string works. Inside a UILayer it pins to the screen (HUD).`,ko:`text/fontSize/color/font/align — CanvasTexture로 그려져 시스템 폰트 문자열을 그대로 쓸 수 있습니다. UILayer 아래에 두면 화면에 고정됩니다(HUD).`}),Q(`UILayer`,{en:`A screen-space subtree (HUD).`,ko:`화면 고정 서브트리(HUD).`},{en:`Everything under it ignores the camera: positions are screen pixels from the top-left. Score counters, prompts, menus go here.`,ko:`이 아래의 모든 것은 카메라를 무시합니다 — 좌상단 기준 화면 픽셀 좌표입니다. 점수, 안내 문구, 메뉴를 여기에 둡니다.`})]},{id:`2d-physics`,label:{en:`2D Physics`,ko:`2D 물리`},intro:{en:`Rapier-backed. Colliders are PROPS ({shape, …}) — the green dashed wireframes in this editor. Physics runs when the game calls enablePhysics2D (and in play mode). Gravity lives on the scene row.`,ko:`Rapier 기반입니다. 콜라이더는 prop({shape, …})이며 에디터의 초록 점선이 그것입니다. 물리는 게임이 enablePhysics2D를 부를 때(그리고 플레이 모드에서) 돌고, 중력은 씬 행에 있습니다.`},nodes:[Q(`StaticBody2D`,{en:`Immovable collision: ground, walls, platforms.`,ko:`움직이지 않는 충돌체 — 바닥·벽·플랫폼.`},{en:`Other bodies collide with it; it never moves. Cheapest body type — use it for all level geometry.`,ko:`다른 바디가 부딪히지만 자신은 절대 움직이지 않습니다. 가장 저렴한 바디 — 레벨 지형 전부에 쓰세요.`}),Q(`RigidBody2D`,{en:`Fully simulated: falls, bounces, pushes.`,ko:`완전 시뮬레이션 — 떨어지고 튕기고 밀립니다.`},{en:`Gravity and collisions drive it. Set linearVelocity to launch. For player characters prefer CharacterBody2D (direct control).`,ko:`중력과 충돌이 움직임을 결정합니다. linearVelocity로 발사하세요. 플레이어 캐릭터에는 직접 제어가 가능한 CharacterBody2D를 권합니다.`}),Q(`CharacterBody2D`,{en:`Kinematic character: you set velocity, it slides.`,ko:`키네마틱 캐릭터 — 속도를 주면 미끄러지듯 이동.`},{en:`moveAndSlide() resolves collisions without physics pushing back; isOnFloor() gates jumps. Sensors (Area2D) do not block it but still fire triggers.`,ko:`moveAndSlide()가 밀려나지 않으면서 충돌을 처리하고 isOnFloor()로 점프를 판정합니다. 센서(Area2D)는 길을 막지 않으면서 트리거를 발사합니다.`}),Q(`Area2D`,{en:`A sensor: overlap triggers, no collision response.`,ko:`센서 — 겹침 감지만, 충돌 반응 없음.`},{en:`Fires triggerEnter(other)/triggerExit(other). Coins, checkpoints, damage zones. Filter with other.isInGroup("player").`,ko:`triggerEnter(other)/triggerExit(other)를 발산합니다. 코인·체크포인트·데미지 존에 쓰고, other.isInGroup("player")로 거릅니다.`}),Q(`CharacterController2D`,{en:`Zero-code platformer/top-down movement.`,ko:`코드 없는 플랫포머/탑다운 이동.`},{en:`Put it UNDER a CharacterBody2D. mode "platformer" (gravity + jump via jumpAction) or "topDown" (free 2-axis). Reads the scene input map actions (moveAction/jumpAction). maxSpeed/jumpHeight are intent-level numbers.`,ko:`CharacterBody2D의 자식으로 두세요. mode는 "platformer"(중력+jumpAction 점프) 또는 "topDown"(자유 2축)이며 씬 입력 맵의 액션(moveAction/jumpAction)을 읽습니다. maxSpeed/jumpHeight는 의도 그대로의 숫자입니다.`}),Q(`Joint2D`,{en:`A physics joint linking its parent body to a target body — weld, hinge, rope, spring.`,ko:`부모 바디와 대상 바디를 잇는 물리 조인트 — 용접, 힌지, 로프, 스프링.`},{en:`Child of body A (a physics body); "target" is a node path to body B. type: fixed (rigid weld) / revolute (pin at the anchors) / rope (caps anchor distance at length px; 0 = measured at creation) / spring (pulls toward length with stiffness/damping). anchor/targetAnchor are LOCAL px offsets.`,ko:`바디 A(물리 바디)의 자식으로 두고 "target"에 바디 B의 노드 경로를 줍니다. type: fixed(강체 용접) / revolute(앵커 핀 힌지) / rope(앵커 간 거리를 length px로 제한, 0이면 생성 시 실측) / spring(stiffness/damping으로 length를 향해 당김). anchor/targetAnchor는 로컬 px 오프셋.`})]},{id:`3d`,label:{en:`3D`,ko:`3D`},intro:{en:`Meters, y-up, rotations in degrees. Standard materials need LIGHT — add a DirectionalLight3D or scene ambient, or you get silhouettes.`,ko:`미터 단위, y-위, 회전은 도(degree)입니다. 표준 머티리얼은 빛이 필요합니다 — DirectionalLight3D나 씬 ambient가 없으면 실루엣만 보입니다.`},nodes:[Q(`Node3D`,{en:`The 3D transform container.`,ko:`3D 변환 컨테이너.`},{en:`position [x,y,z] in meters, rotation [x,y,z] in degrees, scale per axis. Children inherit.`,ko:`position [x,y,z] 미터, rotation [x,y,z] 도, scale은 축별. 자식이 상속합니다.`}),Q(`MeshInstance3D`,{en:`A primitive mesh + material.`,ko:`프리미티브 메시 + 머티리얼.`},{en:`mesh: box/sphere/plane/cylinder…, size per primitive, material {color, roughness, metalness, emissive, emissiveIntensity, wireframe, map, normalMap, repeat} (this editor gives it swatches, sliders, texture-URL fields, and a repeat [u,v] tiling vector). map/normalMap are texture URLs; repeat only takes effect with a map. castShadow/receiveShadow per node.`,ko:`mesh: box/sphere/plane/cylinder…, 프리미티브별 size, material {color, roughness, metalness, emissive, emissiveIntensity, wireframe, map, normalMap, repeat}(에디터가 스와치·슬라이더·텍스처 URL 입력·repeat [u,v] 타일링 벡터 제공). map/normalMap은 텍스처 URL, repeat는 map이 있을 때만 적용. 그림자는 castShadow/receiveShadow.`}),Q(`LoftMesh3D`,{en:`A smooth swept hull (loft).`,ko:`부드러운 스윕 선체(로프트).`},{en:`sections: ≥2 cross-section stations {z, width, height, y, corner 0..1} interpolated into ONE smooth curved surface — vehicle bodies, glass canopies, boat hulls. slices/smooth control tessellation. Same material as MeshInstance3D minus textures (no UVs); pair clearcoat paint or high-envMapIntensity glass with the smooth normals for the automotive look.`,ko:`sections: 단면 스테이션 {z, width, height, y, corner 0..1} 2개 이상을 보간해 하나의 매끈한 곡면을 만듭니다 — 차체, 유리 캐노피, 선체. slices/smooth로 테셀레이션 조절. material은 MeshInstance3D와 동일하되 텍스처 제외(UV 없음). clearcoat 도장이나 높은 envMapIntensity 유리를 곡면 법선과 조합하면 자동차 룩이 납니다.`}),Q(`ModelInstance3D`,{en:`A GLB/glTF/VRM model file.`,ko:`GLB/glTF/VRM 모델 파일.`},{en:'model: "$assetKey" or URL. targetHeight scales the model to stand N units tall (run `npx incanto-model file.glb` to read its real size first). animation plays an embedded clip name OR an "$animation" asset — Mixamo clips retarget onto VRM humanoids automatically. One node per VRM asset (the avatar runtime mounts live). To make it SOLID, park it under a body with collider {shape:"auto"}: the collider is built from the model\'s own triangles — a triangle mesh on a static body (keeps its holes, so you walk through an archway) and a convex hull on a moving one.',ko:'model은 "$에셋키" 또는 URL입니다. targetHeight가 모델을 N유닛 높이로 맞춥니다(먼저 `npx incanto-model 파일.glb`로 실제 크기를 확인하세요). animation은 내장 클립 이름 또는 "$애니메이션" 에셋을 재생하며, Mixamo 클립은 VRM 휴머노이드에 자동 리타게팅됩니다. VRM 에셋은 노드 하나만 쓸 수 있습니다(아바타 런타임이 라이브로 마운트됨). 단단하게 만들려면 collider {shape:"auto"}인 바디 아래에 두세요 — 모델 자신의 삼각형에서 콜라이더가 만들어집니다(정적 바디는 트라이메시라 아치 구멍도 그대로, 움직이는 바디는 볼록 껍질).'}),Q(`Sprite3D`,{en:`A 2D image as a camera-facing billboard (the 2.5D look).`,ko:`카메라를 향하는 2D 빌보드 스프라이트(2.5D 룩).`},{en:`A textured quad that turns to face the camera inside the 3D world (Octopath / Don't Starve / MapleStory-in-3D). texture is an image URL; size is [w,h] in METERS. billboard: "y" stays upright with a screen-aligned yaw — off-center sprites never roll (characters/props), "full" faces it completely (items/FX), "none" is fixed to the node rotation. anchor [0.5,0] plants the feet on the ground. pixelArt nearest-filters for crisp pixels; alphaTest is a hard cutout that depth-sorts against 3D geometry (a tree occludes it); flipX mirrors left/right; tint/opacity recolor.`,ko:`3D 월드 안에서 카메라를 향해 도는 텍스처 쿼드(Octopath/Don't Starve, 3D 속 메이플스토리 룩). texture는 이미지 URL, size는 [너비,높이] 미터. billboard: "y"는 세로로 선 채 카메라 방향과 정렬된 yaw — 화면 가장자리에서도 기울지 않음(캐릭터/사물), "full"은 완전히 향함(아이템/FX), "none"은 노드 회전에 고정. anchor [0.5,0]은 발을 바닥에 둡니다. pixelArt는 nearest 필터로 픽셀을 또렷하게, alphaTest는 3D 지형과 깊이정렬되는 하드 컷아웃(나무가 가림), flipX는 좌우 반전, tint/opacity로 색·투명도.`}),Q(`AnimatedSprite3D`,{en:`A billboard sprite that plays spritesheet animations.`,ko:`스프라이트시트 애니를 재생하는 빌보드 스프라이트.`},{en:`Everything Sprite3D does, plus frame animation. sheet is a spritesheet image URL whose cells are frameWidth×frameHeight; animations maps a name to {frames, fps, loop} where frames is an inclusive [start,end] range or an explicit list; autoplay starts one on load. Game code calls play("walk") / stop(); a non-looping clip clamps on its last frame and emits animationFinished(name) — chain attack→idle from it.`,ko:`Sprite3D의 모든 기능 + 프레임 애니. sheet는 frameWidth×frameHeight 칸을 가진 스프라이트시트 URL, animations는 이름→{frames, fps, loop}(frames는 포함 [시작,끝] 범위 또는 명시 목록), autoplay는 로드 시 하나를 시작. 게임 코드에서 play("walk")/stop() 호출, 비반복 클립은 마지막 프레임에 머물며 animationFinished(name)를 emit(attack→idle 연결).`}),Q(`Billboard3D`,{en:`A group that turns toward the camera — children follow.`,ko:`카메라를 향해 도는 그룹 — 자식들이 함께 회전.`},{en:`A transform container that orients itself toward the camera every frame; children inherit the rotation, so hang world-space UI under it — HP bars, markers, floating icons (text is a canvas-rendered texture on a child Sprite3D). mode: "screen" (default) copies the camera orientation so a child rectangle stays an upright rectangle anywhere on screen (a yaw-only look-at visibly tilts off-center shapes under a pitched camera); "y" stays upright with a screen-aligned yaw (no off-center roll); "none" turns billboarding off. While billboarding, the node's own rotation prop (and the rotate gizmo) is overwritten every frame — switch to "none" to pose children, then switch back. Unlike Sprite3D (a textured quad that spins only its own image), Billboard3D rotates the whole group.`,ko:`매 프레임 카메라를 향해 자신을 회전시키는 변환 컨테이너로, 자식이 회전을 상속합니다 — HP바·마커·아이콘 같은 월드 UI를 자식으로 붙이세요(텍스트는 캔버스로 그린 텍스처를 자식 Sprite3D에). mode: "screen"(기본)은 카메라 자세를 그대로 복사해 자식 직사각형이 화면 어디서든 똑바른 직사각형으로 보입니다(yaw만 도는 look-at은 기울어진 카메라에서 중앙 밖 도형이 눈에 띄게 비스듬해짐); "y"는 세로로 선 채 카메라로 yaw만; "none"은 빌보드 끔. 빌보드 중에는 노드 자신의 rotation(회전 기즈모 포함)이 매 프레임 덮어써집니다 — 자식을 배치할 땐 "none"으로 바꿨다가 되돌리세요. 자기 그림만 도는 Sprite3D(텍스처 쿼드)와 달리 그룹 전체가 회전합니다.`}),Q(`Camera3D`,{en:`The 3D view.`,ko:`3D 시점.`},{en:`Perspective camera; fov in degrees; current: true selects it. Use the editor's "game cam" (0) to preview exactly what it renders.`,ko:`원근 카메라이며 fov는 도 단위, current: true가 실제 시점이 됩니다. 에디터의 "game cam"(0)으로 정확한 렌더 결과를 미리 보세요.`}),Q(`DirectionalLight3D`,{en:`Sun-like light from a direction.`,ko:`태양광 — 방향에서 평행하게.`},{en:`Position sets the direction toward the origin. intensity/color; pair with scene ambient for soft fill.`,ko:`위치가 원점을 향한 방향을 정합니다. intensity/color를 조절하고 부드러운 채움광은 씬 ambient와 함께 쓰세요.`}),Q(`OmniLight3D`,{en:`A point light radiating everywhere.`,ko:`점광 — 사방으로 퍼지는 빛.`},{en:`Lamps, torches, glows. range limits reach; intensity/color shape the falloff.`,ko:`램프·횃불·발광체. range로 도달 거리를, intensity/color로 감쇠를 만듭니다.`}),Q(`Particles3D`,{en:`A 3D particle emitter (fire, magic, weather…).`,ko:`3D 파티클 이미터(불·마법·날씨…).`},{en:`The same preset + override model as Particles2D, in meters with [x,y,z] gravity. Camera-facing billboard quads, instanced — hundreds are cheap. Animates LIVE in this editor.`,ko:`Particles2D와 같은 preset+덮어쓰기 모델을 미터 단위와 [x,y,z] 중력으로. 카메라를 향하는 빌보드 쿼드를 인스턴싱해 수백 개도 가볍습니다. 이 에디터에서 라이브로 움직입니다.`}),Q(`Terrain3D`,{en:`Procedural heightfield terrain with biome texture splatting.`,ko:`바이옴 텍스처 스플래팅이 적용된 절차적 하이트필드 지형.`},{en:`Seeded simplex hills displaced once on the CPU; theme (island/alpine/plains/desert/custom) picks the 4 blended biome textures by height and slope. heightAt(x,z) answers the surface height anywhere. For physics, parent it under a StaticBody3D with collider {shape:'heightfield'}.`,ko:`시드 기반 심플렉스 언덕을 CPU에서 한 번 변위합니다. theme(island/alpine/plains/desert/custom)이 높이·경사로 블렌딩되는 바이옴 텍스처 4장을 고릅니다. heightAt(x,z)로 어디서든 지표 높이를 얻고, 물리는 StaticBody3D 아래에 두고 collider {shape:'heightfield'}를 쓰세요.`}),Q(`Water3D`,{en:`A shader-water surface with splash signals.`,ko:`스플래시 신호를 내는 셰이더 물 표면.`},{en:`size [w,d] meters on XZ. quality 'fancy' (default) = FBM wave shader with a trough/surface/peak ramp (colors), CubeCamera reflections (reflection/reflectionInterval) and opt-in shoreline foam; 'simple' = the cheap sine material (color). Bodies crossing the surface emit entered/exited(body) and raise ripples (interaction). Volumetric gameplay still wants an Area3D. Waves animate LIVE in this editor.`,ko:`XZ 평면에 size [w,d] 미터. quality 'fancy'(기본)는 FBM 파도 셰이더 — trough/surface/peak 램프(colors), CubeCamera 반사(reflection/reflectionInterval), 옵트인 해안 거품(foam). 'simple'은 저사양용 사인파 머티리얼(color). 바디가 수면을 지나면 entered/exited(body) 신호와 물결이 일어납니다(interaction). 부피 기반 게임플레이엔 여전히 Area3D를 쓰세요. 이 에디터에서 파도가 라이브로 움직입니다.`}),Q(`River3D`,{en:`Running water derived from a path and the ground under it.`,ko:`경로와 그 아래 지형에서 유도되는 흐르는 물.`},{en:`Author a centerline path [[x,z],…] plus width/widths (a profile source→mouth) and depth; the node samples the Terrain3D underneath and derives the rest. It CARVES ITS OWN BED by default (carve): a trench per reach that heightAt, the collider, the splat and draped vegetation all see, with a floor that only ever falls, so a path over a rise digs through instead of burying the water. Its surface is then FITTED to that ground — never higher than the lowest rim holding it, ending where the ground comes up to meet it (asymmetric on a sloping reach), lying down as a film where a bank has fallen away, so a river can never hang in the air. Plus a current that speeds up where the channel pinches or tips (flowSpeed is the mean) and whitewater from grade, bank shear and thinning column. Boulders in the channel are answered without wiring: the node finds MeshInstance3D/InstancedMesh3D footprints standing in the water column and the current piles a white cushion on the upstream face, tears a wake downstream and bends its sheen around them. A trench thinner than a terrain cell cannot survive the grid: a 2.4 m creek on a 260 m map wants Terrain3D resolution 256. flowForce drags bodies downstream (drag, never thrust) and sampleAt(x,z) answers where a world point sits in the channel. No extra render passes — a map can carry a dozen.`,ko:`중심선 path [[x,z],…]와 width/widths(상류→하류 프로파일), depth만 주면 나머지는 아래 Terrain3D를 샘플링해 유도합니다. 기본적으로 강이 자기 바닥을 직접 팝니다(carve) — 구간마다 하나씩 도랑을 내고, heightAt·콜라이더·스플랫·식생 드레이프가 모두 그 지형을 봅니다. 파낸 바닥은 계속 내려가기만 하므로 경로가 언덕을 넘어도 물이 묻히지 않고 뚫고 흐릅니다. 그리고 수면은 그 지형에 맞춰집니다 — 자기를 담는 가장 낮은 둑보다 높아질 수 없고, 지면이 올라오는 지점에서 끝나며(비스듬한 구간에서는 좌우 폭이 다릅니다), 둑이 아예 없는 쪽에서는 경사면에 얇은 막처럼 누워버립니다. 그래서 강이 공중에 뜨는 일이 없습니다. 여기에 폭이 좁아지거나 경사가 급해지면 빨라지는 유속(flowSpeed는 평균)과 경사·둑 전단·얕아지는 수심에서 나오는 흰 물살이 더해집니다. 수로에 놓인 바위도 배선 없이 반응합니다 — MeshInstance3D/InstancedMesh3D 중 실제로 물기둥과 겹치는 것을 찾아, 상류면에 흰 물이 쌓이고 하류로 후류가 찢어지며 수면 광택이 바위를 돌아 휩니다. 지형 셀보다 얇은 도랑은 그리드에서 살아남지 못합니다 — 260 m 맵의 2.4 m 개울이라면 Terrain3D resolution 256이 필요합니다. flowForce가 바디를 하류로 끌고(밀지 않고 끌어당김), sampleAt(x,z)로 월드 좌표가 수로 어디에 있는지 알 수 있습니다. 추가 렌더 패스가 없어 한 맵에 여러 개를 둘 수 있습니다.`}),Q(`WaterCutout3D`,{en:`Marks its parent as something that holds the water back — a dry hull, a diving bell, a well.`,ko:`부모 오브젝트가 물을 막는다고 표시 — 마른 선실, 잠수종, 우물.`},{en:`Water is ONE surface and knows nothing about interiors, so an open hull floating on it fills with sea every time a crest clears its floor — freeboard alone can never promise otherwise. This node names the geometry that keeps the water out: it MUST be a CHILD of that thing (a hull, a bell, a dock's well, a cave mouth), and the water re-draws the part of it inside the box into its depth pre-pass, then hides behind it exactly as it hides behind any solid object. Nothing is ever cut OUT of the water, so a hole in open sea is impossible: overshoot the box and more of that hull holds water back, undershoot and water stands in the bow. size is the box extent in meters; enabled toggles it live (a scuttled hull starts letting the sea in). Four per water surface; needs quality fancy.`,ko:`물은 하나의 표면이라 '안쪽'이라는 개념이 없습니다. 그래서 뚜껑 없는 배를 띄우면 파도 마루가 바닥을 넘을 때마다 배 안에 바다가 차 보이고, 건현(freeboard)만으로는 절대 막을 수 없습니다. 이 노드는 '물을 막는 지오메트리'를 지정합니다. 반드시 그 물체(선체·잠수종·부두 우물·동굴 입구)의 자식이어야 하며, 물이 상자 안쪽의 그 지오메트리를 자기 깊이 프리패스에 다시 그린 뒤 평범한 불투명 물체 뒤에 숨듯 그 뒤로 숨습니다. 물에서 무언가를 '도려내지' 않으므로 열린 바다에 구멍이 나는 일은 원리적으로 불가능합니다 — 상자가 크면 그 배가 물을 더 많이 막을 뿐이고, 작으면 뱃머리에 물이 남습니다. size는 미터 단위 상자 크기, enabled는 런타임 토글(침수 시작 연출). 수면 하나당 4개, quality fancy 필요.`}),Q(`Foliage3D`,{en:`An instanced grass/flower carpet that sways.`,ko:`바람에 흔들리는 인스턴스 풀밭/꽃밭. `},{en:`kind grass/flowers/reeds scattered over area [w,d] at density (capped by maxInstances — instanced, tens of thousands of blades cheap). Grass defaults to style 'mesh': every instance is a REAL tapered blade curved by a bezier vertex shader — Voronoi-clump hue/lean, groundColor soil roots (match the terrain), sunDirection tip sheen, 2-octave rolling wind, fadeStart/fadeEnd camera LOD, and (interaction) blade-bending around moving bodies. style 'blades' keeps the 8-SDF-blades-per-quad ported shader, 'simple' the legacy quads. colorA/colorB tint bottom→top, sway sets the wind, seed makes the scatter reproducible. avoidWater (on by default) keeps blades OUT of standing and running water — a creek cutting its bed through the field gets banks, not blades waving in the current; turn it off for reeds and paddy fields.`,ko:`kind grass/flowers/reeds를 area [w,d]에 density로 흩뿌립니다(maxInstances 상한 — 인스턴싱이라 수만 가닥도 가벼움). grass는 기본 style 'mesh': 인스턴스 하나하나가 베지어 버텍스 셰이더로 휘어지는 진짜 잎 메시 — 보로노이 클럼프 색/기울기, groundColor 흙빛 뿌리(지형 색에 맞추세요), sunDirection 잎끝 광택, 2옥타브 굽이치는 바람, fadeStart/fadeEnd 카메라 LOD, (interaction) 움직이는 바디 주변 풀 눕힘까지. style 'blades'는 쿼드당 8가닥 SDF 셰이더, 'simple'은 기존 쿼드 룩. colorA/colorB가 아래→위 색, sway가 바람 세기, seed가 배치를 재현 가능하게 합니다. avoidWater(기본 켜짐)는 고인 물·흐르는 물 안에 잎을 심지 않습니다 — 개울이 들판을 가르고 지나가면 물살 속에 풀이 서 있는 대신 둑이 생깁니다. 갈대·논은 꺼서 쓰세요.`}),Q(`Flowers3D`,{en:`Instanced flower PLANTS — stems, leaves, multi-petal heads.`,ko:`인스턴스 꽃밭 — 줄기·잎·여러 장 꽃잎의 진짜 꽃 식물.`},{en:`Real procedural flower plants (curved stem, 2-3 leaves, a 5-8 petal head around a contrasting center disc, 1-3 blooms per plant) scattered over area [w,d]. density is the vibe dial: 'lush' / 'sparse' (default) / 'none', or a number in plants/m². varieties picks a subset of daisy/cosmos/bellflower ([] = all three); palette sets the head colors ([] = white/yellow/violet). clustering 0-1 gathers plants into Voronoi patches that bloom one species + color together; sway bobs the heads in a gentle wind; seed makes the field reproducible. ≤3 varieties → ≤6 draw calls. avoidWater (on by default) keeps plants out of standing and running water — a meadow a stream runs through has a bank of flowers, not flowers in the current.`,ko:`진짜 프로시저럴 꽃 식물(휘어진 줄기, 잎 2-3장, 대비되는 중심 원반을 두른 꽃잎 5-8장 머리, 포기당 꽃 1-3송이)을 area [w,d]에 흩뿌립니다. density가 바이브 다이얼: 'lush'(풍성하게) / 'sparse'(듬성듬성, 기본) / 'none'(없게) 또는 m²당 개수. varieties는 daisy/cosmos/bellflower 부분집합([] = 셋 다), palette는 꽃 색([] = 흰/노랑/보라). clustering 0-1이 보로노이 패치로 모아 한 패치가 같은 종·같은 색으로 피고, sway가 바람에 머리를 끄덕이며, seed로 배치가 재현됩니다. 품종 ≤3 → 드로우 콜 ≤6. avoidWater(기본 켜짐)는 고인 물·흐르는 물 안에 꽃을 심지 않습니다 — 시내가 지나는 들판에는 물살 속 꽃이 아니라 꽃이 핀 둑이 생깁니다.`}),Q(`Tree3D`,{en:`Procedural tree groves — real branching trunks, textured leaves, one node per forest.`,ko:`프로시저럴 나무 숲 — 진짜 가지가 뻗은 줄기와 텍스처 잎, 숲 하나가 노드 하나.`},{en:`type conifer/broadleaf/dead picks the recipe family; tier is the cost dial: simple = primitive low-poly, medium = light forest presets (≤3k tris/tree), high = full ez-tree presets (8–20k, hero trees). count > 1 scatters a forest patch over area [w,d] — up to 3 seed variants, each branches + leaves InstancedMesh (≤6 draw calls); count × tris/tree is budget-checked at load. seed makes every branch and leaf reproducible; height jitters ±20% per instance; leaves sway in a simplex wind.`,ko:`type conifer/broadleaf/dead가 수종을, tier가 비용을 정합니다: simple = 기존 로우폴리, medium = 가벼운 forest 프리셋(나무당 ≤3k tris), high = 풀 ez-tree 프리셋(8–20k, 주인공 나무). count > 1이면 area [w,d]에 숲 패치를 흩뿌립니다 — 시드 변형 최대 3종, 변형마다 가지+잎 InstancedMesh(드로우 콜 ≤6), count × tris는 로드 시 예산 검사. seed로 가지와 잎이 전부 재현되고 height는 인스턴스마다 ±20% 지터링, 잎은 심플렉스 바람에 흔들립니다.`}),Q(`VoxelGrid3D`,{en:`A Minecraft-style block grid in ONE node.`,ko:`마인크래프트식 블록 그리드 — 노드 하나로.`},{en:`voxels is a list of [x,y,z,palette] integer cells (terrain/island generators emit these). Greedy-meshed and instanced — large worlds stay one draw batch. Game code edits blocks via setBlock/getBlock; emits blocksChanged.`,ko:`voxels는 [x,y,z,팔레트] 정수 셀 목록입니다(terrain/island 생성기가 만들어 냅니다). 그리디 메싱+인스턴싱으로 큰 월드도 드로우 배치 하나를 유지합니다. 게임 코드는 setBlock/getBlock으로 수정하고 blocksChanged가 발산됩니다.`})]},{id:`3d-physics`,label:{en:`3D Physics`,ko:`3D 물리`},intro:{en:`Same model as 2D, in meters with y-up gravity ([0,-9.81,0] default). Colliders: box {size}, sphere {radius}, capsule {radius,height}.`,ko:`2D와 같은 모델을 미터·y-위 중력([0,-9.81,0] 기본)으로. 콜라이더는 box {size}, sphere {radius}, capsule {radius,height}.`},nodes:[Q(`StaticBody3D`,{en:`Immovable 3D collision.`,ko:`움직이지 않는 3D 충돌체.`},{en:`Floors, walls, level geometry. collider {shape:"auto"} takes the shape from the MeshInstance3D or ModelInstance3D the body carries as a child, so the blocker can never be bigger or smaller than what the player sees — the fix for hand-typed extents that leave you stopping in mid-air. A GLB becomes a triangle mesh here, holes and all.`,ko:`바닥·벽·레벨 지형. collider {shape:"auto"}는 바디가 자식으로 들고 있는 MeshInstance3D 또는 ModelInstance3D의 생김새를 그대로 씁니다 — 보이는 것보다 크거나 작은 콜라이더가 생길 수 없습니다. 손으로 적은 크기 때문에 허공에서 막히는 문제의 해법입니다. GLB는 여기서 구멍까지 살아있는 트라이메시가 됩니다.`}),Q(`RigidBody3D`,{en:`Simulated 3D body.`,ko:`시뮬레이션되는 3D 바디.`},{en:`Crates, balls, debris — gravity and impacts drive it.`,ko:`상자·공·파편 — 중력과 충격이 움직입니다.`}),Q(`CharacterBody3D`,{en:`Kinematic 3D character.`,ko:`키네마틱 3D 캐릭터.`},{en:`moveAndSlide with up = +y; isOnFloor for jumps.`,ko:`+y를 위로 moveAndSlide, 점프 판정은 isOnFloor.`}),Q(`Area3D`,{en:`3D overlap sensor.`,ko:`3D 겹침 센서.`},{en:`triggerEnter/Exit — pickups, zones, goals.`,ko:`triggerEnter/Exit — 아이템·존·골인 지점.`}),Q(`CharacterController3D`,{en:`Zero-code 3D movement + camera rig.`,ko:`코드 없는 3D 이동 + 카메라 리그.`},{en:`Put it UNDER a CharacterBody3D. view: thirdPerson (orbit + zoom), firstPerson (eyeHeight, mouseLook), sideView or flightView. Reads moveAction/jumpAction/sprintAction from the scene input map; skinPath turns the visual child to face travel. Intent-level numbers: maxSpeed, jumpVelocity, camDistance.`,ko:`CharacterBody3D의 자식으로 두세요. view는 thirdPerson(궤도+줌), firstPerson(eyeHeight, mouseLook), sideView, flightView 중 하나입니다. 씬 입력 맵의 moveAction/jumpAction/sprintAction을 읽고 skinPath의 비주얼 자식을 진행 방향으로 돌립니다. maxSpeed·jumpVelocity·camDistance 같은 의도 수준의 숫자만 만집니다.`}),Q(`BoneLookAt3D`,{en:`Look-at IK for one bone — the head turns toward a target on top of the animation.`,ko:`본 하나의 룩앳 IK — 애니메이션 위에서 머리가 대상을 향해 돌아갑니다.`},{en:`"target" = ModelInstance3D path, "bone" = bone name (default Head), "lookAt" = the node to watch (e.g. "%Player"). Blends in/out smoothly and DISENGAGES beyond maxAngleDeg (no owl necks); weight sets how far it commits. forwardAxis names the bone's facing axis (mixamo heads: +z). Purely visual — headless no-op.`,ko:`"target"에 ModelInstance3D 경로, "bone"에 본 이름(기본 Head), "lookAt"에 바라볼 노드(예: "%Player")를 줍니다. 부드럽게 페이드 인/아웃하고 maxAngleDeg 밖에서는 해제됩니다(목이 돌아가지 않음). weight로 몰입도를 조절하고 forwardAxis는 본의 정면 축입니다(mixamo 머리: +z). 순수 시각 기능 — 헤드리스에서는 no-op.`}),Q(`InstancedMesh3D`,{en:`Hundreds of copies of one mesh in ONE draw call — rocks, posts, crates.`,ko:`메시 하나의 수백 개 복사본을 드로우콜 1개로 — 바위, 말뚝, 상자.`},{en:`Same mesh/size/material surface as MeshInstance3D; "transforms" places the copies — each row [x, y, z, yawDeg?, scale?]. Replace the whole array to update (mutations are not watched). The scattering workhorse for open worlds. collider: {} makes the whole field solid — every row gets its own collider SHAPED LIKE THE MESH (a faceted gem stone collides as that stone's hull, not as a ball tucked inside it), all hanging off one fixed body. A boulder field the player walks straight through is the tell that a world is scenery rather than a place.`,ko:`MeshInstance3D와 같은 mesh/size/material 표면에 "transforms"로 복사본을 배치합니다 — 각 행은 [x, y, z, yawDeg?, scale?]. 갱신은 배열 전체 교체로 하세요(내부 변경은 감지되지 않음). 오픈월드 스캐터링의 주력입니다. collider: {}를 주면 필드 전체가 단단해집니다 — 행마다 메시 생김새 그대로의 콜라이더가 생기고(각진 gem 바위는 안에 박힌 구가 아니라 그 바위 자신의 볼록 껍질로 부딪힙니다), 전부 하나의 고정 바디에 붙습니다. 플레이어가 통과해버리는 바위밭은 그 세계가 배경 그림이라는 신호입니다.`}),Q(`BoneAttachment3D`,{en:`Rides a skeleton bone of an animated model — swords in hands, hats on heads.`,ko:`애니메이션 모델의 스켈레톤 본을 따라다님 — 손에 쥔 검, 머리 위 모자.`},{en:`"target" is a node path to the ModelInstance3D, "bone" the bone name ("RightHand" also matches the Mixamo spellings). Children inherit the live animated transform; this node's own position/rotation become a bone-space offset. Purely visual — headless it stays where its props put it, so keep gameplay checks range-based.`,ko:`"target"에 ModelInstance3D 노드 경로, "bone"에 본 이름을 줍니다("RightHand"는 Mixamo 표기도 자동 매칭). 자식들이 살아있는 애니메이션 트랜스폼을 물려받고, 이 노드의 position/rotation은 본 기준 오프셋이 됩니다. 순수 시각 기능 — 헤드리스에서는 prop 위치에 머무니 게임 판정은 거리 기반으로 유지하세요.`}),Q(`Trail3D`,{en:`A fading world-space ribbon behind the parent — wingtip trails, sword arcs, tyre streaks.`,ko:`부모 뒤로 남는 페이드아웃 월드 리본 — 날개끝 궤적, 검격 궤적, 타이어 자국.`},{en:"Child of the moving node. Records the world position over `seconds` and renders a camera-facing strip that tapers and fades to the tail. width (m), color, opacity, additive for glowing energy trails, minDistance filters jitter. emitting: false stops laying new ribbon while the old tail fades out.",ko:`움직이는 노드의 자식으로 두세요. seconds 동안의 월드 위치를 기록해 꼬리로 갈수록 가늘어지고 투명해지는 카메라 지향 스트립을 그립니다. width(m), color, opacity, 빛나는 에너지 궤적에는 additive, minDistance로 떨림을 걸러냅니다. emitting: false면 새 리본만 멈추고 기존 꼬리는 자연스럽게 사라집니다.`}),Q(`Joint3D`,{en:`A physics joint linking its parent body to a target body — weld, ball joint, rope, spring.`,ko:`부모 바디와 대상 바디를 잇는 물리 조인트 — 용접, 볼 조인트, 로프, 스프링.`},{en:`Child of body A; "target" is a node path to body B. type: fixed (rigid weld) / spherical (ball joint at the anchors) / rope (caps anchor distance at length m; 0 = measured at creation) / spring (pulls toward length with stiffness/damping). anchor/targetAnchor are LOCAL meter offsets.`,ko:`바디 A의 자식으로 두고 "target"에 바디 B의 노드 경로를 줍니다. type: fixed(강체 용접) / spherical(앵커 볼 조인트) / rope(앵커 간 거리를 length m로 제한, 0이면 생성 시 실측) / spring(stiffness/damping으로 length를 향해 당김). anchor/targetAnchor는 로컬 미터 오프셋.`})]},{id:`network`,label:{en:`Network`,ko:`네트워크`},intro:{en:`Multiplayer is transport-agnostic: the engine speaks one NetworkTransport interface (built-in offline Loopback + an @agent8/gameserver adapter). The scene declares replication; one owner node per player broadcasts its sync keys.`,ko:`멀티플레이어는 트랜스포트 불가지론입니다 — 엔진은 NetworkTransport 인터페이스 하나만 사용합니다(내장 오프라인 Loopback + @agent8/gameserver 어댑터). 복제는 씬이 선언하며, 플레이어당 하나의 owner 노드가 sync 키를 송출합니다.`},nodes:[Q(`NetworkSpawner`,{en:`Spawns a registered scene per remote player/entity.`,ko:`원격 플레이어/엔티티마다 등록된 씬을 생성.`},{en:`source "users" mirrors every OTHER account in the room (self skipped); "collection:<id>" mirrors a room collection. Replicated sync patches apply to each instance; position interpolates. Emits spawned/despawned.`,ko:`source "users"는 방의 다른 모든 계정을 미러링하고(자신 제외) "collection:<id>"는 방 컬렉션을 미러링합니다. 복제 sync 패치가 인스턴스에 적용되고 position은 보간됩니다. spawned/despawned를 발산합니다.`})]}],zF=`overview`,BF=null;function VF(){document.querySelector(`#docs`)?.removeAttribute(`hidden`),WF()}function HF(){document.querySelector(`#docs`)?.setAttribute(`hidden`,``)}function UF(){let e=document.querySelector(`#docs`);e&&(e.addEventListener(`pointerdown`,t=>{t.target===e&&HF()}),document.querySelector(`#docs-close`)?.addEventListener(`click`,HF))}function WF(){let e=document.querySelector(`#docs-tabs`),t=document.querySelector(`#docs-body`);if(!e||!t)return;e.textContent=``;let n=(t,n)=>{let r=document.createElement(`button`);r.type=`button`,r.className=`docs-tab${zF===t?` active`:``}`,r.textContent=n,r.addEventListener(`click`,()=>{zF=t,BF=null,WF()}),e.appendChild(r)};n(`overview`,XP({en:`Overview`,ko:`개요`}));for(let e of RF)n(e.id,XP(e.label));if(t.textContent=``,zF===`overview`){GF(t);return}let r=RF.find(e=>e.id===zF);r&&KF(t,r)}function GF(e){let t=document.createElement(`h2`);t.textContent=XP(LF.title),e.appendChild(t);for(let t of LF.sections){let n=document.createElement(`h3`);n.textContent=XP(t.heading);let r=document.createElement(`p`);r.textContent=XP(t.text),e.append(n,r)}}function KF(e,t){let n=document.createElement(`p`);n.className=`docs-intro`,n.textContent=XP(t.intro),e.appendChild(n);for(let n of t.nodes){let t=document.createElement(`div`);t.className=`docs-node${BF===n.type?` open`:``}`;let r=document.createElement(`button`);r.type=`button`,r.className=`docs-node-head`;let i=document.createElement(`span`);i.className=`tree-icon`,i.appendChild($P(n.type));let a=document.createElement(`strong`);a.textContent=n.type;let o=document.createElement(`span`);if(o.className=`docs-summary`,o.textContent=XP(n.summary),r.append(i,a,o),r.addEventListener(`click`,()=>{BF=BF===n.type?null:n.type,WF()}),t.appendChild(r),BF===n.type){let e=document.createElement(`div`);e.className=`docs-detail`;for(let t of n.body){let n=document.createElement(`p`);n.textContent=XP(t),e.appendChild(n)}e.appendChild(qF(n.type)),t.appendChild(e)}e.appendChild(t)}}function qF(e){let t=document.createElement(`table`);t.className=`docs-props`;let n=document.createElement(`tr`);for(let e of[XP({en:`prop`,ko:`prop`}),XP({en:`default`,ko:`기본값`})]){let t=document.createElement(`th`);t.textContent=e,n.appendChild(t)}t.appendChild(n);try{let n=qe(e);for(let[e,r]of Object.entries(n)){let n=document.createElement(`tr`),i=document.createElement(`td`);i.className=`mono`,i.textContent=e;let a=document.createElement(`td`);a.className=`mono`,a.textContent=JSON.stringify(r.default),n.append(i,a),t.appendChild(n)}}catch{}return t}function $(e){return Math.round(e*100)/100}function JF(e,t,n,r,i){return{name:e,type:`StaticBody3D`,props:{collider:{shape:`box`,size:t},position:n,...i?{rotation:i}:{}},children:[{name:`Skin`,type:`MeshInstance3D`,props:{mesh:`box`,size:t,...r}}]}}function YF(e,t,n,r,i,a){let o=$(r.range(i[0],i[1])),s=$(r.range(.5,.7));return{name:`Rock${e}`,type:`MeshInstance3D`,props:{mesh:`sphere`,size:[1,1,1],position:[t,$(o*s*.6),n],rotation:[0,r.int(0,359),0],scale:[o,$(o*s),$(o*r.range(.8,1.1))],material:{color:a??XF(r),roughness:1},castShadow:!0}}}function XF(e){let t=Math.round(e.range(110,160)).toString(16).padStart(2,`0`);return`#${t}${t}${t}`}function ZF(e){return[{name:`Sun`,type:`DirectionalLight3D`,props:{position:[$(e*.8),$(e*1.5),$(e*.6)],intensity:1,castShadow:!0,shadowArea:$(e*1.2)}},{name:`FillLight`,type:`DirectionalLight3D`,props:{position:[$(-e*.8),$(e*.8),$(-e*.6)],intensity:.4,color:`#b9d4ff`}}]}function QF(e,t){return e===void 0?t:typeof e==`number`?[e,e]:e}function $F(e,t,n){return Math.min(Math.max(e,t),n)}var eI=[`boxes`,`ruins`,`garden`],tI=.5,nI=.1,rI=2,iI={boxes:{floor:`#3f3f3f`,wall:`#55504a`,obstacles:[`#b0413e`,`#5b8266`,`#3e6990`,`#a26b38`,`#6d5a96`,`#878787`]},ruins:{floor:`#7d766b`,wall:`#8a8378`,obstacles:[`#8a8378`,`#979085`,`#a39a8d`,`#7b746a`]},garden:{floor:`#4d7c3a`,wall:`#2f6b2f`,obstacles:[`#2f6b2f`,`#3a7a38`,`#356e33`]}};function aI(e){let{seed:t,width:n=30,depth:r=30,wallHeight:i=3,obstacles:a=8,theme:o=`boxes`}=e;if(!eI.includes(o))throw new N(`BAD_FORMAT`,`generateArena theme must be one of [${eI.join(`, `)}], got '${o}'.`,{prop:`theme`,validOptions:[...eI]});let s=iI[o],c=new P(t),l=[JF(`Floor`,[n,nI,r],[0,-.1/2,0],{material:{color:s.floor,roughness:1},receiveShadow:!0})],u=i/2,d=[n+tI*2,i,tI],f=[tI,i,r],p={material:{color:s.wall,roughness:.9},receiveShadow:!0};l.push(JF(`Wall1`,d,[0,u,-(r+tI)/2],p),JF(`Wall2`,d,[0,u,(r+tI)/2],p),JF(`Wall3`,f,[-(n+tI)/2,u,0],p),JF(`Wall4`,f,[(n+tI)/2,u,0],p)),o===`ruins`?l.push(...sI(c,s,n,r,i,a)):l.push(...oI(c,s,n,r,i,a,o)),o===`garden`&&l.push(...cI(c,n,r));let m=Math.max(n,r);return l.push({name:`Sun`,type:`DirectionalLight3D`,props:{position:[$(m*.8),$(m*1.5),$(m*.6)],intensity:1,castShadow:!0,shadowArea:$(m*1.2)}},{name:`FillLight`,type:`DirectionalLight3D`,props:{position:[$(-m*.8),$(m*.8),$(-m*.6)],intensity:.4,color:`#b9d4ff`}},{name:`Lamp`,type:`OmniLight3D`,props:{position:[0,$(i+2),0],intensity:.5,color:`#fff3d6`,range:$(m)}}),{name:`Arena`,type:`Node3D`,children:l}}function oI(e,t,n,r,i,a,o){let s=[],c=o===`garden`?Math.min(n,r)*.16:0;for(let o=1;o<=a;o++){let a=[$(e.range(.8,2.6)),$(e.range(.8,Math.max(1.2,i*.8))),$(e.range(.8,2.6))],l=$(e.range(-(n/2-rI),n/2-rI)),u=$(e.range(-(r/2-rI),r/2-rI));if(c>0&&Math.hypot(l,u)<c+1.5){let t=Math.max(Math.hypot(l,u),.001);l=$(l/t*(c+1.5+e.range(0,2))),u=$(u/t*(c+1.5+e.range(0,2)))}let d=e.int(0,359);s.push(JF(`Obstacle${o}`,a,[l,$(a[1]/2),u],{material:{color:e.pick(t.obstacles),roughness:.8},castShadow:!0},[0,d,0]))}return s}function sI(e,t,n,r,i,a){let o=[];if(a<=0)return o;let s=Math.max(1,Math.round(Math.sqrt(a/2))),c=Math.ceil(a/s),l=n-rI*2,u=r-rI*2,d=0;for(let n=0;n<s&&d<a;n++){let r=$(s===1?0:-u/2+n/(s-1)*u);for(let n=0;n<c&&d<a;n++){d++;let a=$((c===1?0:-l/2+n/(c-1)*l)+e.range(-.4,.4)),s=$(e.next()>.35?e.range(i*.7,i*1.2):e.range(.4,.9)),u=$(e.range(.8,1.2));o.push(JF(`Obstacle${d}`,[u,s,u],[a,$(s/2),$(r+e.range(-.4,.4))],{material:{color:e.pick(t.obstacles),roughness:.95},castShadow:!0},[0,e.int(-8,8),0]))}}return o}function cI(e,t,n){let r=[],i=Math.min(t,n)*.16,a=r=>{let a=Math.min(t,n)/2-r/2-1,o=$(e.range(-a,a)),s=$(e.range(-a,a)),c=Math.max(Math.hypot(o,s),.001);return c<i+r/2&&(o=$(o/c*(i+r/2+.5)),s=$(s/c*(i+r/2+.5))),[o,s]};for(let i=1;i<=3;i++){let o=$(Math.min(t,n)*e.range(.18,.26)),[s,c]=a(o);r.push({name:`Grass${i}`,type:`Foliage3D`,props:{kind:`grass`,area:[o,o],density:10,seed:e.int(1,1e9),position:[s,0,c]}})}for(let i=1;i<=2;i++){let o=$(Math.min(t,n)*e.range(.12,.18)),[s,c]=a(o);r.push({name:`FlowerBed${i}`,type:`Flowers3D`,props:{density:`lush`,clustering:.3,area:[o,o],seed:e.int(1,1e9),position:[s,0,c]}})}return r.push({name:`Pool`,type:`Water3D`,props:{size:[$(i*2),$(i*2)],position:[0,.3,0],waveHeight:.04}}),r}var lI=32,uI=[4,8],dI=`#332f3a`,fI=`#6b6357`;function pI(e){let{seed:t,rooms:n=5}=e,[r,i]=QF(e.size,[960,720]),a=Math.max(8,Math.floor(r/lI)),o=Math.max(8,Math.floor(i/lI)),s=new P(t),c=[];for(let e=0;e<n*12&&c.length<n;e++){let e=s.int(uI[0],uI[1]),t=s.int(uI[0],uI[1]),n={x:s.int(1,Math.max(1,a-e-1)),y:s.int(1,Math.max(1,o-t-1)),w:e,h:t};c.some(e=>mI(e,n,1))||c.push(n)}let l=new Set,u=e=>{for(let t=e.y;t<e.y+e.h;t++)for(let n=e.x;n<e.x+e.w;n++)l.add(`${n},${t}`)};for(let e of c)u(e);let d=[];for(let e=1;e<c.length;e++){let[t,n]=hI(c[e-1]),[r,i]=hI(c[e]),a={x:Math.min(t,r),y:n,w:Math.abs(t-r)+1,h:1},o={x:r,y:Math.min(n,i),w:1,h:Math.abs(n-i)+1};for(let[t,n]of[[`H`,a],[`V`,o]])u(n),(n.w>1||n.h>1)&&d.push({name:`Corridor${e}${t}`,rect:n})}let f=new Set;for(let e of l){let[t,n]=e.split(`,`).map(Number);for(let e=-1;e<=1;e++)for(let r=-1;r<=1;r++){let i=`${t+r},${n+e}`;l.has(i)||f.add(i)}}let p=-(a*lI)/2,m=-(o*lI)/2,h=(e,t,n)=>({name:e,type:`ColorRect2D`,props:{position:[p+(t.x+t.w/2)*lI,m+(t.y+t.h/2)*lI],size:[t.w*lI,t.h*lI],color:n}}),g=c.map((e,t)=>h(`Room${t+1}`,e,dI));for(let e of d)g.push(h(e.name,e.rect,dI));let _=0;for(let e=-1;e<=o;e++){let t=-1;for(;t<=a;){if(!f.has(`${t},${e}`)){t++;continue}let n=1;for(;t+n<=a&&f.has(`${t+n},${e}`);)n++;_++;let r=[n*lI,lI];g.push({name:`Wall${_}`,type:`StaticBody2D`,props:{position:[p+(t+n/2)*lI,m+(e+.5)*lI],collider:{shape:`rect`,size:r}},children:[{name:`Skin`,type:`ColorRect2D`,props:{size:r,color:fI}}]}),t+=n}}return{name:`Dungeon`,type:`Node2D`,children:g}}function mI(e,t,n){return e.x-n<t.x+t.w&&e.x+e.w+n>t.x&&e.y-n<t.y+t.h&&e.y+e.h+n>t.y}function hI(e){return[Math.floor(e.x+e.w/2),Math.floor(e.y+e.h/2)]}var gI=[[0,-1],[1,0],[0,1],[-1,0]];function _I(e,t,n){let r=2*t+1,i=2*n+1,a=Array.from({length:i},()=>Array(r).fill(!1)),o=(e,t)=>{a[t][e]=!0};o(1,1);let s=new Set([`0,0`]),c=[[0,0]];for(;c.length>0;){let[r,i]=c[c.length-1],a=[];for(let[e,o]of gI){let c=r+e,l=i+o;c>=0&&c<t&&l>=0&&l<n&&!s.has(`${c},${l}`)&&a.push([c,l])}if(a.length===0){c.pop();continue}let[l,u]=e.pick(a);s.add(`${l},${u}`),o(2*l+1,2*u+1),o(r+l+1,i+u+1),c.push([l,u])}return o(0,1),o(2*t,2*n-1),{cols:t,rows:n,cells:a}}var vI=[`stone`,`hedge`,`canyon`],yI=.1,bI=`https://agent8-games.verse8.io/assets/3D/default/textures/wall`,xI=`https://agent8-games.verse8.io/assets/3D/default/textures/terrain`,SI={stone:{wall:{color:`#e8e2d8`,map:`${bI}/blocks.png`,normalMap:`${bI}/blocks_normal.png`,tile:2,roughness:.95},floor:{color:`#99938a`,map:`${xI}/stone.png`,normalMap:`${xI}/stone_normal.png`,tile:3,roughness:1},cap:`#6b5848`,pillar:`#cfc8bb`,path:`#665f55`,sun:{color:`#c9d6ea`,intensity:.75,height:.5},fill:`#9fb4cc`,mood:{sky:{elevationDeg:10,azimuthDeg:150,turbidity:16,rayleigh:3.2},fog:{near:.5,far:3.5,color:`#86909c`},exposure:.82,ambient:{color:`#c9d4e2`,intensity:.12}}},hedge:{wall:{color:`#55a83e`,map:`${xI}/grass.png`,normalMap:`${xI}/grass_normal.png`,tile:1.4,roughness:1},floor:{color:`#86b06d`,map:`${xI}/grass.png`,normalMap:`${xI}/grass_normal.png`,tile:3,roughness:1},pillar:`#3d7531`,path:`#7d6845`,sun:{color:`#e9eee6`,intensity:.7,height:1},fill:`#b9c8b4`,mood:{sky:{elevationDeg:35,azimuthDeg:150,turbidity:18,rayleigh:4.2},fog:{near:.8,far:5,color:`#aab8a6`},exposure:.88,ambient:{color:`#dde5d8`,intensity:.15}}},canyon:{wall:{color:`#f0b070`,map:`${xI}/stone.png`,normalMap:`${xI}/stone_normal.png`,tile:2.4,roughness:1},floor:{color:`#e3c193`,map:`${xI}/sand.png`,normalMap:`${xI}/sand_normal.png`,tile:3.5,roughness:1},pillar:`#d8a868`,path:`#a98a58`,sun:{color:`#ffb572`,intensity:1.15,height:.35},fill:`#caa37e`,mood:{sky:{elevationDeg:9,azimuthDeg:230,turbidity:9,rayleigh:3.5},fog:{near:.7,far:4.5,color:`#c79c6e`},exposure:.92,ambient:{color:`#ffdcb6`,intensity:.13}}}};function CI(e,t,n){return{color:e.color,roughness:e.roughness,map:e.map,...e.normalMap?{normalMap:e.normalMap}:{},repeat:[$(t/e.tile),$(n/e.tile)]}}var wI=10;function TI(e){let{seed:t,width:n=8,depth:r=8,cellSize:i=2,wallHeight:a=2.5,theme:o=`stone`}=e;if(!vI.includes(o))throw new N(`BAD_FORMAT`,`generateMaze theme must be one of [${vI.join(`, `)}], got '${o}'.`,{prop:`theme`,validOptions:[...vI]});let s=SI[o],c=new P(t),l=_I(c,n,r),u=2*n+1,d=2*r+1,f=$(u*i),p=$(d*i),m=(e,t)=>[$((e+.5)*i-f/2),$((t+.5)*i-p/2)],h=[JF(`Floor`,[f,yI,p],[0,-.1/2,0],{material:CI(s.floor,f,p),receiveShadow:!0})],g=[],_=0;for(let e=0;e<d;e++){let t=0;for(;t<u;){if(l.cells[e]?.[t]){t++;continue}let n=1;for(;t+n<u&&!l.cells[e]?.[t+n];)n++;g.push({gx:t,gz:e,run:n}),_++;let r=$(n*i);h.push(JF(`Wall${_}`,[r,a,i],[$((t+n/2)*i-f/2),$(a/2),$((e+.5)*i-p/2)],{material:CI(s.wall,r,a),castShadow:!0,receiveShadow:!0})),t+=n}}return s.cap&&h.push(...EI(g,i,a,f,p,s.cap)),h.push(...DI(c,l,i,a,m,s)),o===`hedge`?(h.push(...jI(c,g,i,a,m)),h.push(...MI(c,l,i,m,n,r))):o===`canyon`&&h.push(...NI(c,g,i,a,m)),h.push(...kI(l,i,a,m,s)),h.push(...ZF(Math.max(f,p)).map((e,t)=>{if(t!==0)return{...e,props:{...e.props,color:s.fill}};let n=e.props?.position;return{...e,props:{...e.props,color:s.sun.color,intensity:s.sun.intensity,position:[n[0]??0,$((n[1]??0)*s.sun.height),n[2]??0]}}})),{name:`Maze`,type:`Node3D`,children:h}}function EI(e,t,n,r,i,a){return e.map((e,o)=>({name:`Cap${o+1}`,type:`MeshInstance3D`,props:{mesh:`box`,size:[$(e.run*t+.16),.12,$(t+.16)],position:[$((e.gx+e.run/2)*t-r/2),$(n+.06),$((e.gz+.5)*t-i/2)],material:{color:a,roughness:1},castShadow:!0,receiveShadow:!0}}))}function DI(e,t,n,r,i,a){let o=[],s=(e,n)=>t.cells[n]?.[e]===!1;for(let e=2;e<t.cells.length-1;e+=2)for(let n=2;n<(t.cells[e]?.length??0)-1;n+=2)s(n,e)&&Number(s(n-1,e))+Number(s(n+1,e))+Number(s(n,e-1))+Number(s(n,e+1))>=3&&o.push([n,e]);let c=Math.min(wI,o.length),l=[],u=new Set,d=$(n*1.2),f=$(r*1.12);for(let t=1;t<=c;t++){let n=e.int(0,o.length-1);for(;u.has(n);)n=(n+1)%o.length;u.add(n);let[r,s]=o[n],[c,p]=i(r,s);l.push(OI(`Pillar${t}`,c,p,d,f,a))}return l}function OI(e,t,n,r,i,a){return{name:e,type:`MeshInstance3D`,props:{mesh:`box`,size:[r,i,r],position:[t,$(i/2),n],material:{...CI(a.wall,r,i),color:a.pillar},castShadow:!0,receiveShadow:!0}}}function kI(e,t,n,r,i){let a=2*e.cols,o=2*e.rows-1,s=$(t*1.1),c=$(n*1.25),l=[[0,0],[0,2],[a,o-1],[a,o+1]].map(([e,t],n)=>{let[a,o]=r(e,t);return OI(`Gate${n+1}`,a,o,s,c,i)});for(let[e,n,s]of[[`EntrancePath`,0,1],[`ExitPath`,a,o]]){let[a,o]=r(n,s);l.push({name:e,type:`MeshInstance3D`,props:{mesh:`box`,size:[$(t*.96),.04,$(t*.96)],position:[a,.02,o],material:{...CI(i.floor,t,t),color:i.path},receiveShadow:!0}})}return l}var AI=10;function jI(e,t,n,r,i){return[...t].filter(e=>e.run>=2).sort((e,t)=>t.run-e.run||e.gz-t.gz||e.gx-t.gx).slice(0,AI).map((t,a)=>{let[,o]=i(t.gx,t.gz),[s]=i(t.gx,t.gz),[c]=i(t.gx+t.run-1,t.gz);return{name:`HedgeTop${a+1}`,type:`Foliage3D`,props:{kind:`grass`,style:`tufts`,area:[$(t.run*n*.92),$(n*.7)],density:14,height:.35,sway:.4,colorA:`#2f5e26`,colorB:`#5d8a3c`,seed:e.int(1,1e9),position:[$((s+c)/2),r,o]}}})}function MI(e,t,n,r,i,a){let o=[];for(let e=0;e<t.cells.length;e++)for(let n=0;n<(t.cells[e]?.length??0);n++)t.cells[e]?.[n]&&o.push([n,e]);let s=Math.min(o.length,Math.max(3,Math.floor(i*a/12))),c=[],l=new Set;for(let t=1;t<=s&&l.size<o.length;t++){let i=e.int(0,o.length-1);for(;l.has(i);)i=(i+1)%o.length;l.add(i);let[a,s]=o[i],[u,d]=r(a,s),f=$(n*.8);c.push({name:`Grass${t}`,type:`Foliage3D`,props:{kind:`grass`,area:[f,f],density:8,seed:e.int(1,1e9),position:[u,0,d]}})}return c}function NI(e,t,n,r,i){let a=[];if(t.length===0)return a;let o=Math.min(8,t.length);for(let s=1;s<=o;s++){let o=e.pick(t),[c,l]=i(o.gx+e.int(0,o.run-1),o.gz),u=YF(s,c,l,e,[.3,$(n*.35)],`#8f7355`),d=u.props?.position;d[1]=$(d[1]+r),a.push(u)}return a}var PI=`#23222b`,FI=`#5f6672`;function II(e){let{seed:t,cols:n=10,rows:r=8,cellPx:i=64}=e,a=_I(new P(t),n,r),o=2*n+1,s=2*r+1,c=$(o*i),l=$(s*i),u=[{name:`Floor`,type:`ColorRect2D`,props:{size:[c,l],color:PI}}],d=0;for(let e=0;e<s;e++){let t=0;for(;t<o;){if(a.cells[e]?.[t]){t++;continue}let n=1;for(;t+n<o&&!a.cells[e]?.[t+n];)n++;d++;let r=[$(n*i),i];u.push({name:`Wall${d}`,type:`StaticBody2D`,props:{position:[$((t+n/2)*i-c/2),$((e+.5)*i-l/2)],collider:{shape:`rect`,size:r}},children:[{name:`Skin`,type:`ColorRect2D`,props:{size:r,color:FI}}]}),t+=n}}return{name:`Maze2D`,type:`Node2D`,children:u}}var LI=16,RI=[`#5b8266`,`#3e6990`,`#a26b38`,`#6d5a96`,`#b0413e`];function zI(e){let{seed:t,count:n=10,width:r=[80,160],gapX:i=[40,120],stepY:a=[-80,40],start:o=[0,300]}=e,s=new P(t),c=[],l=$(s.range(r[0],r[1])),u=o[0],d=o[1];for(let e=1;e<=n&&(c.push(BI(e,u,d,l,s.pick(RI))),e!==n);e++){let e=$(s.range(r[0],r[1])),t=$(s.range(i[0],i[1]));u=$(u+l/2+t+e/2),d=$(d+s.range(a[0],a[1])),l=e}return{name:`Platforms`,type:`Node2D`,children:c}}function BI(e,t,n,r,i){return{name:`Platform${e}`,type:`StaticBody2D`,props:{position:[t,n],collider:{shape:`rect`,size:[r,LI]}},children:[{name:`Skin`,type:`ColorRect2D`,props:{size:[r,LI],color:i}}]}}var VI=[3,5],HI=3,UI={color:`#ffffff`,roughness:1,emissive:`#ffffff`,emissiveIntensity:.25};function WI(e){let{seed:t,count:n=8,altitude:r=18}=e,[i,a]=QF(e.area,[60,60]),o=new P(t),s=[];for(let e=1;e<=n;e++){let t=o.int(VI[0],VI[1]),n=[];for(let e=1;e<=t;e++){let r=$(o.range(1,2.2));n.push({name:`Puff${e}`,type:`MeshInstance3D`,props:{mesh:`sphere`,size:[1,1,1],position:[$((e-(t+1)/2)*o.range(1,1.6)),$(o.range(-.3,.3)),$(o.range(-.6,.6))],scale:[$(r*o.range(1.1,1.6)),$(r*.55),r],material:UI}})}s.push({name:`Cloud${e}`,type:`Node3D`,props:{position:[$(o.range(-i/2,i/2)),$(r+o.range(-3,HI)),$(o.range(-a/2,a/2))]},children:n})}return{name:`Clouds`,type:`Node3D`,children:s}}var GI=[`island`,`alpine`,`plains`,`desert`,`meadow`,`forest`,`savanna`,`snow`,`wetland`,`volcanic`],KI=128,qI=20,JI=.8,YI=.12,XI={island:{splat:`island`,maxHeight:4.5,sun:`#fff4d6`,fill:`#b9d4ff`,sky:{elevationDeg:38,azimuthDeg:145,turbidity:2.6,rayleigh:1.1},fog:{near:1,far:4},iblIntensity:.72},alpine:{splat:`alpine`,maxHeight:8,roughness:.65,detail:5,sun:`#f4f7ff`,fill:`#c9d8f2`,sky:{elevationDeg:45,azimuthDeg:35,turbidity:1.4,rayleigh:1.3},fog:{near:1.8,far:6.5},sunIntensity:1.1,exposure:.92,iblIntensity:.72},plains:{splat:`plains`,maxHeight:4,sun:`#fff2cf`,fill:`#bcd3ef`,sky:{elevationDeg:36,azimuthDeg:140,turbidity:2.4,rayleigh:1},fog:{near:.9,far:4},iblIntensity:.58},desert:{splat:`desert`,maxHeight:5,sun:`#ffe3b3`,fill:`#e8c9a6`,sky:{elevationDeg:42,azimuthDeg:160,turbidity:7,rayleigh:.6},fog:{near:.8,far:3.2,color:`#e8d3ae`},sunIntensity:1.35,iblIntensity:.75},meadow:{splat:`grassland`,maxHeight:1.2,sun:`#fff8e2`,fill:`#bfe0c9`,sky:{elevationDeg:55,azimuthDeg:125,turbidity:2.4,rayleigh:.95},fog:{near:1,far:4.4},sunIntensity:2.6,exposure:1.12,iblIntensity:.62},forest:{splat:`forest`,maxHeight:2.5,sun:`#ffdca8`,fill:`#a9c8b4`,sky:{elevationDeg:29,azimuthDeg:120,turbidity:5.5,rayleigh:1},fog:{near:.22,far:1.8,color:`#9fb494`},sunIntensity:2.6,ambient:.26,iblIntensity:.55},savanna:{splat:`savanna`,maxHeight:3,sun:`#ffdca0`,fill:`#e6d2a4`,sky:{elevationDeg:34,azimuthDeg:150,turbidity:5,rayleigh:.7},fog:{near:1,far:4.2,color:`#e3cf9f`},sunIntensity:2,exposure:1.05,iblIntensity:.6},snow:{splat:`snow`,maxHeight:2.2,sun:`#dfe9ff`,fill:`#c2d2f0`,sky:{elevationDeg:22,azimuthDeg:35,turbidity:1.6,rayleigh:1.6},fog:{near:1.2,far:5,color:`#dbe6f5`},sunIntensity:1,exposure:.9,iblIntensity:.72},wetland:{splat:`wetland`,maxHeight:1.4,sun:`#d6ddc8`,fill:`#9fb29a`,sky:{elevationDeg:24,azimuthDeg:115,turbidity:9,rayleigh:1.1},fog:{near:.5,far:2,color:`#92a288`},sunIntensity:1.5,exposure:.94,ambient:.24,iblIntensity:.66},volcanic:{splat:`volcanic`,maxHeight:4,roughness:.7,sun:`#ff8a4a`,fill:`#7a4a3a`,sky:{elevationDeg:14,azimuthDeg:135,turbidity:10,rayleigh:.3},fog:{near:.18,far:1.4,color:`#2a211c`},sunIntensity:1.7,exposure:.86,ambient:.22,iblIntensity:.5}};function ZI(e){let{seed:t,theme:n=`island`,size:r=200,water:i=!1}=e,a=XI[n];if(!a)throw new N(`BAD_FORMAT`,`generateTerrain theme must be one of [${GI.join(`, `)}], got '${n}'.`,{prop:`theme`,validOptions:[...GI]});let o=Math.max(2,Math.round(e.resolution??KI)),s=e.maxHeight||a.maxHeight,c=new P(t),l=n===`island`,u=e=>Vw({width:r,depth:r,segsX:o,segsZ:o,maxHeight:e,seed:t,...a.roughness===void 0?{}:{roughness:a.roughness},...a.detail===void 0?{}:{detail:a.detail},islandEdge:l}),d=u(s);if(l)for(let e=0;e<3;e++){let e=$I(d)-qI,t=d.maxHeight-d.minHeight,n=d.minHeight+YI*t;if(e+JI<=n)break;let r=qI-JI,i=$I(d)-d.minHeight-YI*t;s=$(s*Math.min(r/i*.95,.9)),d=u(s)}let f=[{name:`Ground`,type:`StaticBody3D`,props:{collider:{shape:`heightfield`}},children:[{name:`Surface`,type:`Terrain3D`,props:{size:[r,r],maxHeight:s,seed:t,theme:a.splat,...a.roughness===void 0?{}:{roughness:a.roughness},...a.detail===void 0?{}:{detail:a.detail},...o===KI?{}:{resolution:o}}}]}],p=n===`wetland`;if(l)f.push({name:`Sea`,type:`Water3D`,props:{size:[r*8,r*8],position:[0,QI(d),0],opacity:1}});else if(p){let e=d.maxHeight-d.minHeight||1,t=$(d.minHeight+.22*e);f.push({name:`Swamp`,type:`Water3D`,props:{size:[r,r],position:[0,t,0],waveHeight:.02,quality:`simple`,color:`#3a4a30`,opacity:.95}})}else if(i){let e=$(d.minHeight+.1*(d.maxHeight-d.minHeight));f.push({name:`Lake`,type:`Water3D`,props:{size:[r,r],position:[0,e,0],waveHeight:.04}})}return f.push(...hL(n,c,d,r)),l&&f.push(WI({seed:c.int(1,1e9),count:6,area:r,altitude:Math.round(d.maxHeight+12)})),f.push(...ZF(r).map((e,t)=>gL(e,t===0?a.sun:a.fill,t===0?a.sunIntensity??1.7:void 0))),{name:`Terrain`,type:`Node3D`,children:f}}function QI(e){let t=$I(e)-qI,n=e.minHeight+YI*(e.maxHeight-e.minHeight);return $(Math.max(Math.min(t+JI,n),t+.55))}function $I(e){let t=-1/0,n=e.width/2,r=e.depth/2,i=e.segsX;for(let a=0;a<=i;a++){let o=-n+a/i*e.width,s=-r+a/i*e.depth;t=Math.max(t,e.baseHeight(o,-r),e.baseHeight(o,r),e.baseHeight(-n,s),e.baseHeight(n,s))}return t}function eL(e,t,n){let r=Math.min(t.width/2-n.margin,n.within??1/0),i=t.maxHeight-t.minHeight||1,a=[];for(let o=0;o<n.count*30&&a.length<n.count;o++){let o=$(e.range(-r,r)),s=$(e.range(-r,r));if(n.clearing&&Math.hypot(o,s)<n.clearing||n.within&&Math.hypot(o,s)>n.within)continue;let c=t.heightAt(o,s),l=(c-t.minHeight)/i;l<n.band[0]||l>n.band[1]||t.slopeAt(o,s)>n.maxSlope||a.push({x:o,z:s,y:c})}return a}var tL=[{canopy:`#2f5d44`,trunk:`#6e4a32`},{canopy:`#356a4c`,trunk:`#71503a`},{canopy:`#2c5740`,trunk:`#5f4530`},{canopy:`#3a6b4a`,trunk:`#6a4c34`}],nL=[{canopy:`#4a7c3f`,trunk:`#7a5a3a`},{canopy:`#56883c`,trunk:`#806044`},{canopy:`#7a9d3e`,trunk:`#9a9488`},{canopy:`#86a346`,trunk:`#a39c8e`},{canopy:`#b8862f`,trunk:`#7e5e38`},{canopy:`#a8702c`,trunk:`#74552f`}],rL={canopy:`#9aa052`,trunk:`#8a6a44`},iL={canopy:`#39513f`,trunk:`#5a5650`};function aL(e,t){return e===`conifer`?t.pick(tL):e===`broadleaf`?t.pick(nL):null}function oL(e,t,n,r,i){let a=i?.height??[4.5,7],o=i?.sink??(i?.count===void 0?.05:.3),s={};i?.tier!==void 0&&(s.tier=i.tier),i?.count!==void 0&&i.area!==void 0&&(s.count=i.count,s.area=[i.area,i.area]);let c=aL(r,n),l=i?.palette??c;return l&&(s.canopyColor=l.canopy,s.trunkColor=l.trunk),{name:e,type:`Tree3D`,props:{type:r,seed:n.int(1,1e9),height:$(n.range(a[0],a[1])),position:[t.x,$(t.y-o),t.z],...s}}}function sL(e,t,n,r,i,a=0,o){return{name:e,type:`Foliage3D`,props:{kind:`grass`,style:`tufts`,area:[r,r],density:i,height:o?.height??.3,...o?.colors?{colorA:o.colors[0],colorB:o.colors[1]}:{},seed:n.int(1,1e9),position:[t.x,$(t.y+.02),t.z],...a>0?{flowers:a}:{}}}}function cL(e,t,n,r,i){return{name:e,type:`Foliage3D`,props:{kind:`reeds`,style:`simple`,area:[r,r],density:i,height:.9,colorA:`#2f4a26`,colorB:`#5a6f33`,seed:n.int(1,1e9),position:[t.x,$(t.y+.02),t.z]}}}function lL(e,t,n,r,i){return{name:e,type:`Flowers3D`,props:{density:i,area:[r,r],seed:n.int(1,1e9),position:[t.x,$(t.y+.02),t.z]}}}function uL(e,t,n,r){return e.map((e,i)=>{let a=YF(i+1,e.x,e.z,t,n,r?.(t)),o=a.props?.position;return o[1]=$(o[1]+e.y),a})}function dL(e){let t=Math.round(e.range(104,128)),n=Math.round(t-e.range(10,18)),r=Math.round(t-e.range(20,30)),i=e=>e.toString(16).padStart(2,`0`);return`#${i(n)}${i(t)}${i(r)}`}function fL(e){let t=Math.round(e.range(196,224)),n=Math.min(255,t+Math.round(e.range(4,12))),r=e=>e.toString(16).padStart(2,`0`);return`#${r(t)}${r(t)}${r(n)}`}function pL(e){let t=Math.round(e.range(34,56)),n=Math.min(255,t+Math.round(e.range(2,8))),r=e=>e.toString(16).padStart(2,`0`);return`#${r(n)}${r(t)}${r(t)}`}var mL=[`#6f5b41`,`#7a644a`,`#665439`];function hL(e,t,n,r){let i=[];switch(e){case`island`:{let e=eL(t,n,{count:7,band:[.18,.6],maxSlope:.5,margin:26});i.push(...e.map((e,n)=>oL(`Tree${n+1}`,e,t,`conifer`)));break}case`alpine`:{let e=eL(t,n,{count:10,band:[.2,.5],maxSlope:.55,margin:6});i.push(...e.map((e,n)=>oL(`Tree${n+1}`,e,t,`conifer`)));let r=eL(t,n,{count:8,band:[.55,1],maxSlope:.9,margin:6});i.push(...uL(r,t,[.6,1.8]));break}case`plains`:{let e=eL(t,n,{count:8,band:[0,1],maxSlope:.4,margin:6});i.push(...e.map((e,n)=>oL(`Tree${n+1}`,e,t,`broadleaf`)));let r=eL(t,n,{count:6,band:[0,1],maxSlope:.5,margin:6});i.push(...uL(r,t,[.4,1.2]));break}case`desert`:{let e=eL(t,n,{count:6,band:[0,1],maxSlope:.45,margin:6});i.push(...e.map((e,n)=>oL(`Tree${n+1}`,e,t,`dead`)));let r=eL(t,n,{count:8,band:[0,1],maxSlope:.6,margin:6});i.push(...uL(r,t,[.5,1.6]));break}case`meadow`:{let e=$(r*.09),a=eL(t,n,{count:7,band:[0,1],maxSlope:.05,margin:e/2+8});i.push(...a.map((n,r)=>sL(`Carpet${r+1}`,n,t,e,30)));let o=$(r*.07),s=eL(t,n,{count:3,band:[0,1],maxSlope:.05,margin:o/2+8});i.push(...s.map((e,n)=>lL(`Flowers${n+1}`,e,t,o,`sparse`)));let c=eL(t,n,{count:4,band:[0,1],maxSlope:.1,margin:12});i.push(...c.map((e,n)=>oL(`Grove${n+1}`,e,t,`broadleaf`,{count:3,area:6})));let l=eL(t,n,{count:6,band:[0,1],maxSlope:.2,margin:8});i.push(...uL(l,t,[.3,.9]));break}case`forest`:{let e=$(r*.12),a=r/2-8,o=dn(t.int(1,1e9)),s=(e,t,n)=>{let r=o(e/70,t/70);return r>.12?`conifer`:r<-.12?`broadleaf`:n%2==0?`conifer`:`broadleaf`},c=eL(t,n,{count:40,band:[0,1],maxSlope:.18,margin:8,clearing:e+6}),l=c.map((e,t)=>s(e.x,e.z,t));i.push(...c.map((e,n)=>oL(`Grove${n+1}`,e,t,l[n],{count:12,area:13,height:[5.5,8]}))),c.forEach((e,n)=>{n%3==0&&i.push(oL(`Sapling${n+1}`,e,t,l[n],{count:4,area:19,height:[2.5,3.4],sink:.12}))});let u=eL(t,n,{count:6,band:[0,1],maxSlope:.2,margin:12,clearing:e+4});i.push(...u.map((e,n)=>oL(`Elder${n+1}`,e,t,s(e.x,e.z,n),{tier:`high`,height:[8.4,9.8]})));let d=eL(t,n,{count:3,band:[0,1],maxSlope:.18,margin:10,clearing:e+6});i.push(...d.map((e,n)=>oL(`Accent${n+1}`,e,t,`broadleaf`,{tier:`high`,count:3,area:7,height:[5.6,6.8]})));let f=eL(t,n,{count:10,band:[0,1],maxSlope:.14,margin:9,clearing:e+2});i.push(...f.map((e,n)=>oL(`Bush${n+1}`,e,t,`bush`,{count:4,area:10,height:[2.1,3.1],sink:.12})));let p=0;c.forEach((e,r)=>{if(r%3==2)return;let o=t.range(0,Math.PI*2),s=t.range(2,4.5),c=t.int(1,1e9),l=$($F(e.x+Math.cos(o)*s,-a,a)),u=$($F(e.z+Math.sin(o)*s,-a,a));n.slopeAt(l,u)>.09||(p++,i.push({name:`Fern${p}`,type:`Foliage3D`,props:{kind:`grass`,style:`tufts`,tuftStyle:`fern`,area:[8,8],density:9,height:.4,colorA:`#4a6b34`,colorB:`#82a258`,seed:c,position:[l,$(n.heightAt(l,u)+.02),u]}}))});let m=$(r*.08),h=eL(t,n,{count:5,band:[0,1],maxSlope:.06,margin:m/2+8});i.push(...h.map((e,n)=>sL(`Grass${n+1}`,e,t,m,20,0,{height:.24,colors:[`#4f7034`,`#85a154`]})));let g=u.length>0?t.int(3,5):0;for(let e=0;e<g;e++){let r=u[e%u.length],o=t.range(0,Math.PI*2),s=t.range(2.5,4.5),c=$($F(r.x+Math.cos(o)*s,-a,a)),l=$($F(r.z+Math.sin(o)*s,-a,a));i.push({name:`Log${e+1}`,type:`Tree3D`,props:{type:`dead`,seed:t.int(1,1e9),height:$(t.range(4.2,5.6)),trunkColor:`#4a4236`,position:[c,$(n.heightAt(c,l)+.12),l],rotation:[0,t.int(0,359),$(t.range(81,97))]}})}eL(t,n,{count:5,band:[0,1],maxSlope:.25,margin:9,clearing:e}).forEach((e,n)=>{let r=$(t.range(.16,.28)),a=$(t.range(.3,.55));i.push({name:`Stump${n+1}`,type:`MeshInstance3D`,props:{mesh:`cylinder`,size:[r,a,r],position:[e.x,$(e.y+a/2-.06),e.z],rotation:[0,t.int(0,359),0],material:{color:t.pick(mL),roughness:1},castShadow:!0}})});let _=eL(t,n,{count:8,band:[0,1],maxSlope:.2,margin:8});i.push(...uL(_,t,[.3,1],dL));let v=$(e*.75),y=eL(t,n,{count:3,band:[0,1],maxSlope:.06,margin:8,within:e-$(v/Math.SQRT2)});i.push(...y.map((e,n)=>sL(`Clearing${n+1}`,e,t,v,30,0,{colors:[`#5d8438`,`#a8bc60`]})));let b=$(e*.45),x=eL(t,n,{count:2,band:[0,1],maxSlope:.06,margin:8,within:e-$(b/Math.SQRT2)});i.push(...x.map((e,n)=>lL(`Flowers${n+1}`,e,t,b,`sparse`)));break}case`savanna`:{let e=eL(t,n,{count:7,band:[0,.85],maxSlope:.35,margin:8});i.push(...e.map((e,n)=>oL(`Tree${n+1}`,e,t,`broadleaf`,{height:[3.5,5],palette:rL})));let a=$(r*.09),o=eL(t,n,{count:6,band:[0,1],maxSlope:.05,margin:a/2+8});i.push(...o.map((e,n)=>sL(`Carpet${n+1}`,e,t,a,26,0,{height:.34,colors:[`#9a8f43`,`#c9bd6a`]})));let s=eL(t,n,{count:7,band:[0,1],maxSlope:.5,margin:8});i.push(...uL(s,t,[.4,1.4]));let c=eL(t,n,{count:4,band:[0,1],maxSlope:.2,margin:9});i.push(...c.map((e,n)=>oL(`Scrub${n+1}`,e,t,`bush`,{count:3,area:8,height:[1.4,2.2]})));break}case`snow`:{let e=eL(t,n,{count:8,band:[0,.9],maxSlope:.4,margin:8});i.push(...e.map((e,n)=>oL(`Tree${n+1}`,e,t,`conifer`,{height:[4,6.5],palette:iL})));let r=eL(t,n,{count:10,band:[0,1],maxSlope:.7,margin:8});i.push(...uL(r,t,[.5,1.8],fL));break}case`wetland`:{let e=$(r*.08),a=eL(t,n,{count:6,band:[0,.5],maxSlope:.06,margin:e/2+8});i.push(...a.map((n,r)=>cL(`Reeds${r+1}`,n,t,e,4)));let o=$(r*.08),s=eL(t,n,{count:4,band:[.2,1],maxSlope:.05,margin:o/2+8});i.push(...s.map((e,n)=>sL(`Moss${n+1}`,e,t,o,22,0,{height:.22,colors:[`#3a5a2c`,`#6f8a48`]})));let c=eL(t,n,{count:6,band:[.25,1],maxSlope:.35,margin:9});i.push(...c.map((e,n)=>oL(`Snag${n+1}`,e,t,`dead`,{height:[4,6]})));let l=eL(t,n,{count:6,band:[.2,1],maxSlope:.2,margin:9});i.push(...l.map((e,n)=>oL(`Bush${n+1}`,e,t,`bush`,{count:3,area:7,height:[1.6,2.6]})));let u=eL(t,n,{count:5,band:[.2,1],maxSlope:.3,margin:8});i.push(...uL(u,t,[.3,1],dL));break}case`volcanic`:{let e=eL(t,n,{count:7,band:[0,1],maxSlope:.45,margin:8});i.push(...e.map((e,n)=>oL(`Tree${n+1}`,e,t,`dead`,{height:[4,6.5]})));let r=eL(t,n,{count:12,band:[0,1],maxSlope:.7,margin:8});i.push(...uL(r,t,[.4,1.8],pL)),eL(t,n,{count:3,band:[0,.6],maxSlope:.18,margin:12}).forEach((e,n)=>{t.int(1,1e9),i.push({name:`Smoke${n+1}`,type:`Particles3D`,props:{preset:`smoke`,position:[e.x,$(e.y+.2),e.z],rate:8,maxParticles:64,colorStart:`#5a5048`,colorEnd:`#2a2422`,sizeStart:18,sizeEnd:44}}),i.push({name:`Embers${n+1}`,type:`Particles3D`,props:{position:[e.x,$(e.y+.1),e.z],rate:10,maxParticles:48,lifetime:[.8,1.8],speed:[12,34],directionDeg:-90,spreadDeg:40,gravity:[0,-18],sizeStart:4,sizeEnd:1,colorStart:`#ffce6a`,colorEnd:`#d83a14`,blend:`add`}})});break}}return i}function gL(e,t,n){return{...e,props:{...e.props,color:t,...n===void 0?{}:{intensity:n}}}}var _L={arena:{description:`FPS stage: floor, 4 perimeter walls, obstacles, lights — themes: boxes (crates), ruins (broken stone rows), garden (hedges, grass, pool)`,dimension:`3d`,params:{theme:{type:`string`,default:`boxes`,options:[...eI]},width:{type:`number`,default:30,min:4},depth:{type:`number`,default:30,min:4},wallHeight:{type:`number`,default:3,min:.5},obstacles:{type:`number`,default:8,min:0}}},terrain:{description:`Heightfield world: StaticBody3D{heightfield} + Terrain3D + theme dressing (trees, rocks, grass, sea/clouds on island, broad swamp water on wetland, smoke/ember emitters on volcanic; maxHeight 0 = theme default; water adds a lake to non-island themes)`,dimension:`3d`,params:{theme:{type:`string`,default:`island`,options:[...GI]},size:{type:`number`,default:200,min:40,max:400},maxHeight:{type:`number`,default:0,min:0},water:{type:`boolean`,default:!1}}},maze:{description:`Recursive-backtracker 3D maze, west→east — themes: stone, hedge (green + grass), canyon (sandstone + rim rocks)`,dimension:`3d`,params:{theme:{type:`string`,default:`stone`,options:[...vI]},width:{type:`number`,default:8,min:2,max:40},depth:{type:`number`,default:8,min:2,max:40},cellSize:{type:`number`,default:2,min:.5},wallHeight:{type:`number`,default:2.5,min:.5}}},maze2d:{description:`The same maze algorithm as 2D ColorRect2D + StaticBody2D tiles`,dimension:`2d`,params:{cols:{type:`number`,default:10,min:2,max:40},rows:{type:`number`,default:8,min:2,max:40},cellPx:{type:`number`,default:64,min:8}}},dungeon2d:{description:`Roguelike rooms + L-corridors: floor rects, wall bodies (32px tiles)`,dimension:`2d`,params:{rooms:{type:`number`,default:5,min:1,max:20},size:{type:`number`,default:960,min:256}}},platforms2d:{description:`Left-to-right 2D platform course (tune ranges via the library)`,dimension:`2d`,params:{count:{type:`number`,default:10,min:1}}}},vL={arena:aI,terrain:ZI,maze:TI,maze2d:II,dungeon2d:pI,platforms2d:zI};function yL(e,t){let n=vL[e];if(!n){let t=Object.keys(vL);throw new N(`BAD_FORMAT`,`Unknown generator '${e}'. Valid: [${t.join(`, `)}] — the old meadow/forest/island/rocks/clouds generators became themes (e.g. terrain theme: 'meadow', arena theme: 'garden'); scatter is library-only (needs item templates).`,{validOptions:t})}return n(t)}function bL(e){return Object.entries(_L).filter(([,t])=>t.dimension===e).map(([e,t])=>({name:e,meta:t}))}function xL(e,t){if(e.type===`boolean`)return t===!0||t===`true`;if(e.type===`number`){let n=typeof t==`boolean`?NaN:Number(t);return(t===``||!Number.isFinite(n))&&(n=e.default),e.min!==void 0&&(n=Math.max(e.min,n)),e.max!==void 0&&(n=Math.min(e.max,n)),n}let n=String(t);return e.options&&!e.options.includes(n)?e.default:n}function SL(){return Math.floor(Math.random()*1e6)}var CL=[],wL=new Map,TL=null;function EL(e){let t=document.querySelector(`#generate`);t&&(kL(e),t.removeAttribute(`hidden`))}function DL(){document.querySelector(`#generate`)?.setAttribute(`hidden`,``)}function OL(e){let t=document.querySelector(`#generate`);t&&(t.addEventListener(`pointerdown`,e=>{e.target===t&&DL()}),document.querySelector(`#generate-close`)?.addEventListener(`click`,DL),document.querySelector(`#generate-cancel`)?.addEventListener(`click`,DL),document.querySelector(`#generate-insert`)?.addEventListener(`click`,()=>AL(e)))}function kL(e){let t=document.querySelector(`#generate-body`),n=document.querySelector(`#generate-status`);if(!t)return;n&&(n.textContent=``),t.textContent=``;let r=e.working.dimension??`2d`;CL=bL(r);let i=document.createElement(`p`);i.className=`gen-hint`,i.textContent=XP({en:`Deterministic ${r.toUpperCase()} environment generators — the subtree inserts under the selected node (the root when nothing is selected). The same seed always generates the same level.`,ko:`결정적 ${r.toUpperCase()} 환경 생성기 — 생성된 서브트리는 선택한 노드 아래에(선택이 없으면 루트에) 들어갑니다. 같은 시드는 항상 같은 레벨을 만듭니다.`}),t.appendChild(i);let a=jL(XP({en:`generator`,ko:`생성기`})),o=document.createElement(`select`);o.id=`generate-name`;for(let{name:e}of CL){let t=document.createElement(`option`);t.value=e,t.textContent=e,o.appendChild(t)}a.appendChild(o),t.appendChild(a);let s=document.createElement(`p`);s.className=`gen-desc`,t.appendChild(s);let c=document.createElement(`div`);c.id=`generate-params`,t.appendChild(c);let l=jL(`seed`);TL=document.createElement(`input`),TL.type=`number`,TL.step=`1`,TL.value=String(SL());let u=document.createElement(`button`);u.type=`button`,u.className=`ghost`,u.textContent=`↻`,u.title=XP({en:`New random seed`,ko:`새 랜덤 시드`}),u.addEventListener(`click`,()=>{TL&&(TL.value=String(SL()))});let d=document.createElement(`div`);d.className=`gen-seed-row`,d.append(TL,u),l.appendChild(d),t.appendChild(l);let f=()=>{let e=CL.find(e=>e.name===o.value)??CL[0];if(e){s.textContent=e.meta.description,c.textContent=``,wL=new Map;for(let[t,n]of Object.entries(e.meta.params)){let e=jL(t),r;if(n.type===`boolean`)r=document.createElement(`input`),r.type=`checkbox`,r.checked=n.default===!0;else if(n.type===`string`&&n.options){r=document.createElement(`select`);for(let e of n.options){let t=document.createElement(`option`);t.value=e,t.textContent=e,r.appendChild(t)}r.value=String(n.default)}else r=document.createElement(`input`),r.type=n.type===`number`?`number`:`text`,n.type===`number`&&(r.step=`any`,n.min!==void 0&&(r.min=String(n.min)),n.max!==void 0&&(r.max=String(n.max))),r.value=String(n.default),(n.min!==void 0||n.max!==void 0)&&(r.title=`${n.min??``}–${n.max??``}`);wL.set(t,r),e.appendChild(r),c.appendChild(e)}}};o.addEventListener(`change`,f),f()}function AL(e){let t=document.querySelector(`#generate-status`),n=document.querySelector(`#generate-name`),r=CL.find(e=>e.name===n?.value);if(!r||!TL)return;let i={seed:xL({type:`number`,default:SL(),min:0},TL.value)};for(let[e,t]of wL){let n=r.meta.params[e];n&&(i[e]=xL(n,t.type===`checkbox`?t.checked:t.value))}let a;try{a=yL(r.name,i)}catch(e){t&&(t.textContent=e instanceof Error?e.message:String(e));return}let o=e.insertNode(a,e.selection??[]);if(o===null){t&&(t.textContent=XP({en:`Insert failed — see the error banner.`,ko:`삽입 실패 — 에러 배너를 확인하세요.`}));return}e.select(o),TL&&(TL.value=String(SL())),DL()}function jL(e){let t=document.createElement(`label`);t.className=`field`;let n=document.createElement(`span`);return n.textContent=e,t.appendChild(n),t}var ML={connections:{title:{en:`connections — wire a signal to a handler`,ko:`connections — 시그널을 핸들러에 연결`},body:{en:'A connection says "when THIS node emits THIS signal, call THIS method on THAT node" — declaratively, in the scene JSON, with no TypeScript. emits = leaving this node; receives = arriving at it. Paths resolve from the scene ROOT (`Player/Sword`, `.` for the root itself). A red target does not resolve and the game will refuse to load the scene. Handlers on a scripted node are free text: they live in your behavior, which the editor never loads.',ko:'연결은 "이 노드가 이 시그널을 보내면, 저 노드의 이 메서드를 호출한다"를 씬 JSON에 선언합니다 — TypeScript 없이. emits는 이 노드에서 나가는 것, receives는 들어오는 것입니다. 경로는 씬 루트 기준입니다(`Player/Sword`, 루트 자신은 `.`). 빨간 대상은 찾을 수 없다는 뜻이고, 게임은 그 씬을 열지 못합니다. 스크립트가 있는 노드의 핸들러는 자유 입력입니다 — 에디터가 읽지 않는 게임 코드에 있기 때문입니다.'}},groups:{title:{en:`groups — tag nodes for queries`,ko:`groups — 조회용 태그`},body:{en:`Free-form tags. Game code finds nodes with tree-wide queries like getNodesInGroup("coins"), and triggers can filter by group (e.g. only react to "player"). Type a name and press Enter.`,ko:`자유 형식 태그입니다. 게임 코드가 getNodesInGroup("coins")처럼 트리 전체에서 노드를 찾고, 트리거는 그룹으로 거릅니다(예: "player"에만 반응). 이름을 입력하고 Enter를 누르세요.`},example:`triggerEnter → if (other.isInGroup("player")) collect()`},script:{title:{en:`script — attach YOUR game logic`,ko:`script — 게임 로직 연결`},body:{en:`A Behavior is a TypeScript class living in YOUR game code, linked by name. The editor stores the link; the class itself must be registered in the game before loadScene. Props here are passed to the behavior instance.`,ko:`Behavior는 게임 코드에 있는 TypeScript 클래스이며 이름으로 연결됩니다. 에디터는 연결만 저장하고, 클래스 자체는 loadScene 전에 게임에서 등록되어야 합니다. 여기의 props가 비헤이비어 인스턴스로 전달됩니다.`},example:`registerBehavior('CoinCounter', CoinCounter) // in your main.ts`,copy:{label:`copy behavior boilerplate`,text:`import { Behavior, registerBehavior } from 'incanto';
|
|
8413
|
+
}`};var hN=[`type`,`sunPosition`,`elevationDeg`,`azimuthDeg`,`turbidity`,`rayleigh`],gN=[`color`,`near`,`far`],_N=[`coverage`,`density`,`base`,`top`,`color`,`shadeColor`,`speed`,`scale`],vN=[`threshold`,`strength`],yN=[`vignette`,`saturation`,`contrast`],bN=[`mapSize`,`radius`,`static`],xN=[1024,2048],SN=2,CN=1,wN=50,TN=800,EN=`#cfd8e0`,DN=Math.PI/180;function ON(e){return{exposure:MN(e?.exposure),sky:NN(e?.sky),fog:PN(e?.fog,e?.sky!==void 0),clouds:FN(e?.clouds),bloom:IN(e?.bloom),post:LN(e?.post),shadows:RN(e?.shadows)}}function kN(e,t){let n=(90-e)*DN,r=t*DN;return[Math.sin(n)*Math.sin(r),Math.cos(n),Math.sin(n)*Math.cos(r)]}function AN(e){let[t,n,r]=e.sunPosition,i=Math.hypot(t,n,r)||1;return[t/i,n/i,r/i]}function jN(e){let t=[191,213,232],n=[233,228,217],r=[242,201,150],i=VN((e.turbidity-SN)/8),a=AN(e),o=VN((18-Math.asin(BN(a[1],-1,1))/DN)/18)*.8,s=e=>Math.round(HN(HN(t[e],n[e],i),r[e],o));return`#${[s(0),s(1),s(2)].map(e=>e.toString(16).padStart(2,`0`)).join(``)}`}function MN(e){if(e===void 0)return 1;if(typeof e!=`number`||!Number.isFinite(e)||e<=0)throw new N(`BAD_FORMAT`,`environment.exposure must be a finite number > 0 (tone-mapping exposure, default 1), got ${JSON.stringify(e)}.`,{prop:`exposure`});return e}function NN(e){if(e===void 0)return null;if(typeof e!=`object`||!e||Array.isArray(e))throw new N(`BAD_FORMAT`,`environment.sky must be an object ({ type?: "atmosphere", sunPosition? | elevationDeg?+azimuthDeg?, turbidity?, rayleigh? }), got ${JSON.stringify(e)}.`,{prop:`sky`});let t=e;for(let e of Object.keys(t))if(!hN.includes(e))throw new N(`BAD_FORMAT`,`environment.sky has unknown key '${e}'. Valid keys: [${hN.join(`, `)}].`,{prop:`sky`,validOptions:hN});if(t.type!==void 0&&t.type!==`atmosphere`)throw new N(`BAD_FORMAT`,`environment.sky.type must be 'atmosphere' (the only sky type so far), got ${JSON.stringify(t.type)}.`,{prop:`sky`,validOptions:[`atmosphere`]});let n=t.elevationDeg!==void 0||t.azimuthDeg!==void 0;if(t.sunPosition!==void 0&&n)throw new N(`BAD_FORMAT`,`environment.sky takes sunPosition OR elevationDeg/azimuthDeg, not both.`,{prop:`sky`,validOptions:[`sunPosition`,`elevationDeg+azimuthDeg`]});let r;if(t.sunPosition!==void 0){let e=t.sunPosition;if(!Array.isArray(e)||e.length!==3||!e.every(e=>typeof e==`number`&&Number.isFinite(e))||Math.hypot(e[0],e[1],e[2])===0)throw new N(`BAD_FORMAT`,`environment.sky.sunPosition must be a non-zero [x, y, z] vector, got ${JSON.stringify(e)}.`,{prop:`sky`});r=[e[0],e[1],e[2]]}else{let e=zN(t.elevationDeg,32,`sky.elevationDeg`),n=zN(t.azimuthDeg,135,`sky.azimuthDeg`);if(e<-90||e>90)throw new N(`BAD_FORMAT`,`environment.sky.elevationDeg must be in [-90, 90] (degrees above the horizon), got ${e}.`,{prop:`sky`});r=kN(e,n)}let i=zN(t.turbidity,SN,`sky.turbidity`);if(i<=0)throw new N(`BAD_FORMAT`,`environment.sky.turbidity must be > 0 (atmospheric haze; 2 ≈ clear day), got ${i}.`,{prop:`sky`});let a=zN(t.rayleigh,CN,`sky.rayleigh`);if(a<0)throw new N(`BAD_FORMAT`,`environment.sky.rayleigh must be >= 0 (Rayleigh scattering; 1 ≈ earth-like), got ${a}.`,{prop:`sky`});return{sunPosition:r,turbidity:i,rayleigh:a}}function PN(e,t){if(e===void 0)return null;if(typeof e!=`object`||!e||Array.isArray(e))throw new N(`BAD_FORMAT`,`environment.fog must be an object ({ color?, near?, far? }), got ${JSON.stringify(e)}.`,{prop:`fog`});let n=e;for(let e of Object.keys(n))if(!gN.includes(e))throw new N(`BAD_FORMAT`,`environment.fog has unknown key '${e}'. Valid keys: [${gN.join(`, `)}].`,{prop:`fog`,validOptions:gN});if(n.color!==void 0&&typeof n.color!=`string`)throw new N(`BAD_FORMAT`,`environment.fog.color must be a hex color string, got ${JSON.stringify(n.color)}.`,{prop:`fog`});let r=zN(n.near,wN,`fog.near`),i=zN(n.far,TN,`fog.far`);if(r<0)throw new N(`BAD_FORMAT`,`environment.fog.near must be >= 0 meters, got ${r}.`,{prop:`fog`});if(i<=r)throw new N(`BAD_FORMAT`,`environment.fog.far must be > near (got near ${r}, far ${i}).`,{prop:`fog`});return{color:n.color??(t?``:EN),near:r,far:i}}function FN(e){if(e===void 0)return null;if(typeof e!=`object`||!e||Array.isArray(e))throw new N(`BAD_FORMAT`,`environment.clouds must be an object ({ coverage?, density?, base?, top?, color?, shadeColor?, speed?, scale? }), got ${JSON.stringify(e)}.`,{prop:`clouds`});let t=e;for(let e of Object.keys(t))if(!_N.includes(e))throw new N(`BAD_FORMAT`,`environment.clouds has unknown key '${e}'. Valid keys: [${_N.join(`, `)}].`,{prop:`clouds`,validOptions:_N});for(let e of[`color`,`shadeColor`])if(t[e]!==void 0&&typeof t[e]!=`string`)throw new N(`BAD_FORMAT`,`environment.clouds.${e} must be a hex color string, got ${JSON.stringify(t[e])}.`,{prop:`clouds`});let n=zN(t.coverage,.5,`clouds.coverage`);if(n<0||n>1)throw new N(`BAD_FORMAT`,`environment.clouds.coverage must be in [0, 1] (how much sky is cloudy), got ${n}.`,{prop:`clouds`});let r=zN(t.density,1,`clouds.density`);if(r<0)throw new N(`BAD_FORMAT`,`environment.clouds.density must be >= 0 (optical thickness), got ${r}.`,{prop:`clouds`});let i=zN(t.base,120,`clouds.base`),a=zN(t.top,320,`clouds.top`);if(a<=i)throw new N(`BAD_FORMAT`,`environment.clouds.top must be > base (got base ${i}, top ${a}).`,{prop:`clouds`});let o=zN(t.speed,1,`clouds.speed`),s=zN(t.scale,240,`clouds.scale`);if(s<=0)throw new N(`BAD_FORMAT`,`environment.clouds.scale must be > 0 (feature size in world units), got ${s}.`,{prop:`clouds`});return{coverage:n,density:r,base:i,top:a,color:t.color??`#ffffff`,shadeColor:t.shadeColor??`#9fb0c8`,speed:o,scale:s}}function IN(e){if(e===void 0)return null;if(typeof e!=`object`||!e||Array.isArray(e))throw new N(`BAD_FORMAT`,`environment.bloom must be an object ({ threshold?, strength? }), got ${JSON.stringify(e)}.`,{prop:`bloom`});let t=e;for(let e of Object.keys(t))if(!vN.includes(e))throw new N(`BAD_FORMAT`,`environment.bloom has unknown key '${e}'. Valid keys: [${vN.join(`, `)}].`,{prop:`bloom`,validOptions:vN});let n=zN(t.threshold,1,`bloom.threshold`);if(n<0||n>8)throw new N(`BAD_FORMAT`,`environment.bloom.threshold must be in [0, 8] (linear-HDR luminance; 1 = white), got ${n}.`,{prop:`bloom`});let r=zN(t.strength,.8,`bloom.strength`);if(r<0)throw new N(`BAD_FORMAT`,`environment.bloom.strength must be >= 0, got ${r}.`,{prop:`bloom`});return{threshold:n,strength:r}}function LN(e){if(e===void 0)return null;if(typeof e!=`object`||!e||Array.isArray(e))throw new N(`BAD_FORMAT`,`environment.post must be an object ({ vignette?, saturation?, contrast? }), got ${JSON.stringify(e)}.`,{prop:`post`});let t=e;for(let e of Object.keys(t))if(!yN.includes(e))throw new N(`BAD_FORMAT`,`environment.post has unknown key '${e}'. Valid keys: [${yN.join(`, `)}].`,{prop:`post`,validOptions:yN});let n=zN(t.vignette,0,`post.vignette`);if(n<0||n>1)throw new N(`BAD_FORMAT`,`environment.post.vignette must be in [0, 1], got ${n}.`,{prop:`post`});let r=zN(t.saturation,1,`post.saturation`);if(r<0||r>4)throw new N(`BAD_FORMAT`,`environment.post.saturation must be in [0, 4] (1 = neutral), got ${r}.`,{prop:`post`});let i=zN(t.contrast,1,`post.contrast`);if(i<.2||i>3)throw new N(`BAD_FORMAT`,`environment.post.contrast must be in [0.2, 3] (1 = neutral), got ${i}.`,{prop:`post`});return{vignette:n,saturation:r,contrast:i}}function RN(e){if(e===void 0)return null;if(e===!1)return!1;if(e===!0)return{mapSize:2048,radius:1,static:!1};if(typeof e!=`object`||!e||Array.isArray(e))throw new N(`BAD_FORMAT`,`environment.shadows must be true, false or an object ({ mapSize?, radius? }), got ${JSON.stringify(e)}.`,{prop:`shadows`});let t=e;for(let e of Object.keys(t))if(!bN.includes(e))throw new N(`BAD_FORMAT`,`environment.shadows has unknown key '${e}'. Valid keys: [${bN.join(`, `)}].`,{prop:`shadows`,validOptions:bN});let n=t.mapSize===void 0?2048:t.mapSize;if(!xN.includes(n))throw new N(`BAD_FORMAT`,`environment.shadows.mapSize must be one of [${xN.join(`, `)}], got ${JSON.stringify(t.mapSize)}.`,{prop:`shadows`,validOptions:xN.map(String)});let r=zN(t.radius,1,`shadows.radius`);if(r<0)throw new N(`BAD_FORMAT`,`environment.shadows.radius must be >= 0, got ${r}.`,{prop:`shadows`});let i=t.static===void 0?!1:t.static;if(typeof i!=`boolean`)throw new N(`BAD_FORMAT`,`environment.shadows.static must be a boolean, got ${JSON.stringify(t.static)}.`,{prop:`shadows`});return{mapSize:n,radius:r,static:i}}function zN(e,t,n){if(e===void 0)return t;if(typeof e!=`number`||!Number.isFinite(e))throw new N(`BAD_FORMAT`,`environment.${n} must be a finite number, got ${JSON.stringify(e)}.`,{prop:n});return e}function BN(e,t,n){return Math.min(Math.max(e,t),n)}function VN(e){return BN(e,0,1)}function HN(e,t,n){return e+(t-e)*n}var UN=`https://agent8-games.verse8.io/assets/3D/default/textures/hdri`,WN={apartment:`lebombo_1k.hdr`,city:`potsdamer_platz_1k.hdr`,dawn:`kiara_1_dawn_1k.hdr`,forest:`forest_slope_1k.hdr`,lobby:`st_fagans_interior_1k.hdr`,night:`dikhololo_night_1k.hdr`,park:`rooitou_park_1k.hdr`,studio:`studio_small_03_1k.hdr`,sunset:`venice_sunset_1k.hdr`,warehouse:`empty_warehouse_01_1k.hdr`};function GN(e){if(typeof e.hdri==`string`&&e.hdri!==``)return e.hdri;if(typeof e.preset==`string`){let t=WN[e.preset];if(!t)throw Error(`Unknown environment preset '${e.preset}'. Available: ${Object.keys(WN).join(`, `)}.`);return`${UN}/${t}`}return null}var KN=75,qN=class{scene;ambient=new xu(`#ffffff`,0);envKey=null;config=ON(void 0);hdriUrl=null;hdriTexture=null;_sky=null;skyKey=``;skyEnvKey=``;skyEnvTarget=null;fog=new To(`#ffffff`,1,1e3);underwaterFog=null;underwaterBg=new K;constructor(e){this.scene=e,this.scene.add(this.ambient)}get sunDirection(){return this.config.sky?AN(this.config.sky):null}get clouds(){return this.config.clouds}get bloom(){return this.config.bloom}get post(){return this.config.post}get sceneFog(){return this.scene.fog instanceof To?this.scene.fog:null}apply(e,t){let n=e===void 0?``:JSON.stringify(e);n!==this.envKey&&(this.envKey=n,this.config=ON(e));let r=this.config,i=e?.ambient;if(this.ambient.color.set(i?.color??`#ffffff`),this.ambient.intensity=i?.intensity??0,t&&(t.toneMappingExposure=r.exposure,t.shadowMap.enabled=r.shadows!==!1,r.shadows!==!1&&r.shadows!==null&&r.shadows.static?t.shadowMap.autoUpdate&&(t.shadowMap.autoUpdate=!1,t.shadowMap.needsUpdate=!0):t.shadowMap.autoUpdate||(t.shadowMap.autoUpdate=!0)),this.applyHdri(e),this.applySky(r.sky,t),this._sky&&(this._sky.visible=!0),this.applyFog(r),this.scene.environment=this.hdriTexture??this.skyEnvTarget?.texture??null,this.scene.environmentIntensity=(this.scene.environment===this.skyEnvTarget?.texture&&this.skyEnvTarget?.55:1)*JN(e?.iblIntensity),e?.skybox===!0&&this.hdriTexture)this.scene.background=this.hdriTexture;else{let t=e?.background;this.scene.background=typeof t==`string`?new K(t):null}}applySunLight(e,t=null){if(!e)return;let n=this.sunDirection;if(t){let r=e.position.length()||100,i,a,o;if(n)[i,a,o]=n;else{i=e.position.x-e.target.position.x,a=e.position.y-e.target.position.y,o=e.position.z-e.target.position.z;let t=Math.hypot(i,a,o)||1;i/=t,a/=t,o/=t}e.target.position.set(t.x,t.y,t.z),e.target.updateMatrixWorld(),e.position.set(t.x+i*r,t.y+a*r,t.z+o*r)}else if(n){let t=e.position.length()||100;e.position.set(n[0],n[1],n[2]).multiplyScalar(t)}let r=this.config.shadows;if(r&&typeof r==`object`){if(!e.castShadow){let t=e.shadow.camera;`left`in t&&t.left===-5&&(t.left=-75,t.right=KN,t.top=KN,t.bottom=-75,t.near=.5,t.far=500,t.updateProjectionMatrix()),e.castShadow=!0}e.shadow.mapSize.x!==r.mapSize&&(e.shadow.mapSize.set(r.mapSize,r.mapSize),e.shadow.map?.dispose(),e.shadow.map=null),e.shadow.radius=r.radius}}applyUnderwater(e){e&&(this.underwaterFog||=new To(`#000000`,.5,e.visibility),this.underwaterFog.color.set(e.color),this.underwaterFog.near=.5,this.underwaterFog.far=e.visibility,this.scene.fog=this.underwaterFog,this.scene.background=this.underwaterBg.set(e.color),this._sky&&(this._sky.visible=!1))}applyHdri(e){let t=GN(e??{});t!==this.hdriUrl&&(this.hdriUrl=t,this.hdriTexture?.dispose(),this.hdriTexture=null,t&&new pN().load(t,e=>{if(this.hdriUrl!==t){e.dispose();return}e.mapping=303,this.hdriTexture=e}))}applySky(e,t){let n=e?JSON.stringify(e):``;if(n!==this.skyKey&&(this.skyKey=n,this._sky&&=(this.scene.remove(this._sky),this._sky.material.dispose(),this._sky.geometry.dispose(),null),e)){this._sky=new mN,this._sky.scale.setScalar(45e4);let t=this._sky.material.uniforms;(t.sunPosition?.value).set(...e.sunPosition),t.turbidity&&(t.turbidity.value=e.turbidity),t.rayleigh&&(t.rayleigh.value=e.rayleigh),this.scene.add(this._sky)}if(e&&t&&this._sky&&this.skyEnvKey!==n){this.skyEnvKey=n,this.skyEnvTarget?.dispose();let e=new xd(t),r=new Eo;r.add(this._sky),this.skyEnvTarget=e.fromScene(r),e.dispose(),this.scene.add(this._sky)}!e&&this.skyEnvTarget&&(this.skyEnvTarget.dispose(),this.skyEnvTarget=null,this.skyEnvKey=``)}applyFog(e){if(!e.fog){this.scene.fog=null;return}let t=e.fog.color||(e.sky?jN(e.sky):`#cfd8e0`);this.fog.color.set(t),this.fog.near=e.fog.near,this.fog.far=e.fog.far,this.scene.fog=this.fog}dispose(){this.hdriTexture?.dispose(),this.hdriTexture=null,this.skyEnvTarget?.dispose(),this.skyEnvTarget=null,this._sky&&=(this.scene.remove(this._sky),this._sky.material.dispose(),this._sky.geometry.dispose(),null)}};function JN(e){if(e===void 0)return 1;if(typeof e!=`number`||!Number.isFinite(e)||e<0)throw new N(`BAD_FORMAT`,`environment.iblIntensity must be a finite number >= 0 (multiplies the image-based ambience: sky-derived base 0.55, HDRI base 1; default 1), got ${JSON.stringify(e)}.`,{prop:`iblIntensity`});return e}var YN=new Vo,XN=new Vo,ZN=new G,QN=new G,$N=new U,eP=Array.from({length:8},()=>new U),tP=.4,nP=new Float32Array(72),rP=[[0,0,0],[1,0,0],[1,0,1],[0,0,1],[0,1,0],[1,1,0],[1,1,1],[0,1,1]],iP=[[0,1],[1,2],[2,3],[3,0],[4,5],[5,6],[6,7],[7,4],[0,4],[1,5],[2,6],[3,7]];function aP(e,t){t.makeEmpty(),ZN.copy(e.matrixWorld).invert(),e.traverse(e=>{let n=e,r;n.isInstancedMesh?(n.boundingBox||n.computeBoundingBox?.(),r=n.boundingBox):n.geometry&&(n.geometry.boundingBox||n.geometry.computeBoundingBox(),r=n.geometry.boundingBox),r&&(XN.copy(r).applyMatrix4(QN.multiplyMatrices(ZN,e.matrixWorld)),t.union(XN))})}function oP(e){if(!(e instanceof Ah))return null;let t=e._ensureObject3D();t.updateWorldMatrix(!0,!0),aP(t,YN);let n=!0;YN.isEmpty()?(n=!1,$N.setFromMatrixPosition(t.matrixWorld),YN.min.set($N.x-tP,$N.y-tP,$N.z-tP),YN.max.set($N.x+tP,$N.y+tP,$N.z+tP)):YN.expandByScalar(.02);let{min:r,max:i}=YN;for(let e=0;e<8;e++){let[a,o,s]=rP[e],c=eP[e].set(a?i.x:r.x,o?i.y:r.y,s?i.z:r.z);n&&c.applyMatrix4(t.matrixWorld)}let a=0;for(let[e,t]of iP){let n=eP[e],r=eP[t];nP[a++]=n.x,nP[a++]=n.y,nP[a++]=n.z,nP[a++]=r.x,nP[a++]=r.y,nP[a++]=r.z}return nP}function sP(e){return e.spatial===!0&&typeof e._setSpatialPose==`function`}function cP(){let e=new Set,t=[],n=[],r=[];return{visited:e,cameras:t,renderHooks:n,emitters:r,state:{visited:e,cameras:t,renderHooks:n,emitters:r,assets:void 0,sunDirection:null,sunLight:null,alpha:1,ignoreStatic:!1}}}function lP(e,t,n,r,i){let a=i??cP();a.visited.clear(),a.cameras.length=0,a.renderHooks.length=0,a.emitters.length=0;let o=a.state;o.assets=n,o.sunDirection=r?.sunDirection??null,o.ignoreStatic=r?.ignoreStatic===!0,o.sunLight=null,o.alpha=r?.alpha??1,hP(e,t,o),vP(t,a.visited);let s=null;for(let e=0;e<a.cameras.length;e++){let t=a.cameras[e];if(t.current){s=t;break}}s||=a.cameras[0]??null;let c=s?s._ensureObject3D():null;return mP(a.emitters,c),{activeCamera:c,renderHooks:a.renderHooks,sunLight:o.sunLight}}var uP=new U,dP=new U,fP=new U,pP=new U;function mP(e,t){if(e.length===0||!t)return;t.updateWorldMatrix(!0,!1),t.getWorldPosition(dP),t.getWorldDirection(fP),pP.set(0,1,0).applyQuaternion(t.quaternion);let n={position:[dP.x,dP.y,dP.z],forward:[fP.x,fP.y,fP.z],up:[pP.x,pP.y,pP.z]};for(let{node:t,parent:r}of e)r.updateWorldMatrix(!0,!1),r.getWorldPosition(uP),t._setSpatialPose({position:[uP.x,uP.y,uP.z],listener:n})}function hP(e,t,n){let r=t;if(e instanceof Ah){let i=e._ensureObject3D();if(e.static&&!n.ignoreStatic&&i.userData.incantoStaticSynced===!0){i.userData.incantoStatic=!0,n.visited.add(i);return}if(i.parent!==t&&t.add(i),e._syncObject3D(n.alpha,n.assets??null),n.assets&&e instanceof Zk&&e._syncModel(n.assets),typeof e._onRender3D==`function`&&n.renderHooks.push(e),n.sunDirection){let t=e._applySunDirection;typeof t==`function`&&t.call(e,n.sunDirection)}e instanceof Fk&&(!n.sunLight||e.intensity>n.sunLight.intensity)&&(n.sunLight=e),n.visited.add(i),e instanceof UE&&n.cameras.push(e),r=i}else sP(e)&&n.emitters.push({node:e,parent:r});for(let t of e.children)hP(t,r,n);if(e instanceof Ah){let t=e._ensureObject3D();e.static&&!n.ignoreStatic?(t.userData.incantoStaticSynced=!0,t.userData.incantoStatic=!0,_P(e)):t.userData.incantoStaticSynced===!0&&(t.userData.incantoStaticSynced=!1,t.userData.incantoStatic=!1)}}var gP=new WeakSet;function _P(e){if(gP.has(e))return;gP.add(e);let t=[],n=e=>{(typeof e._onRender3D==`function`||e instanceof UE)&&t.push(`${e.name} (${e.constructor.typeName??`?`})`);for(let t of e.children)n(t)};n(e),t.length>0&&console.warn(`[incanto] static subtree '${e.name}' freezes animated/per-frame nodes: ${t.join(`, `)} — they will stop updating. Unmark static or move them out.`)}function vP(e,t){let n=e.children;for(let r=n.length-1;r>=0;r--){let i=n[r];i.userData.incantoNode&&!t.has(i)?e.remove(i):i.userData.incantoStatic!==!0&&vP(i,t)}}var yP=class{viewOverride=null;overrideCam=new pu(60,1,.05,5e3);lastCamera=null;lastSize={w:1,h:1};webgl;threeScene=new Eo;environment=new qN(this.threeScene);engine;disconnect;canvas;assets;ownsAssets;loadedAssetScenes=new WeakSet;compiledScene=null;warmCamera=null;deferCompile=!1;syncScratch=cP();ignoreStatic=!1;renderCtx=null;causticsTarget=null;causticsScene=null;causticsUniforms=null;cloudsTarget=null;cloudsHalfTarget=null;cloudsBlurTarget=null;cloudsScene=null;cloudsUniforms=null;cloudsBlurScene=null;cloudsBlurUniforms=null;cloudsCompositeScene=null;cloudsCompositeUniforms=null;bloomTarget=null;bloomBrightTarget=null;bloomBlurTarget=null;bloomBrightScene=null;bloomBrightUniforms=null;bloomBlurScene=null;bloomBlurUniforms=null;bloomCompositeScene=null;bloomCompositeUniforms=null;constructor(e){this.canvas=e.canvas,this.engine=e.engine,this.ownsAssets=!e.assets,this.assets=e.assets??new yw(this.engine);let t=vn(e.engine.scene?.environment,{antialias:!0,pixelRatio:Math.min(globalThis.devicePixelRatio??1,2),preserveDrawingBuffer:!1},globalThis.devicePixelRatio??1,{pixelRatio:e.pixelRatio,preserveDrawingBuffer:e.preserveDrawingBuffer});this.webgl=new hm({canvas:e.canvas,antialias:t.antialias,preserveDrawingBuffer:t.preserveDrawingBuffer}),this.webgl.info.autoReset=!1,this.engine.picker=(e,t)=>this.pick(e,t),this.basePixelRatio=t.pixelRatio,this.webgl.setPixelRatio(t.pixelRatio),this.adaptive=e.adaptiveResolution===!1?null:new XM,this.webgl.shadowMap.enabled=!0,this.webgl.shadowMap.type=1,this.webgl.toneMapping=4,this.webgl.toneMappingExposure=1,this.debugLines=new Hc(new J,new Ac({color:`#00ff6e`,depthTest:!1})),this.debugLines.frustumCulled=!1,this.debugLines.renderOrder=9999,this.debugLines.visible=!1,this.threeScene.add(this.debugLines),this.selectionLines=new Hc(new J,new Ac({color:`#ffb020`,transparent:!0,depthTest:!1})),this.selectionLines.frustumCulled=!1,this.selectionLines.renderOrder=1e4,this.selectionLines.visible=!1,this.threeScene.add(this.selectionLines),this.disconnect=this.engine.updated.connect(()=>this.render())}basePixelRatio;adaptive;lastFrameAt=0;debugLines;selectionLines;syncSelectionOutline(){let e=this.engine.debugSelection;e&&e.tree!==this.engine.scene?.tree&&(this.engine.debugSelection=null);let t=this.engine.debugSelection,n=t?oP(t):null;if(this.selectionLines.visible=n!==null,n){this.selectionLines.geometry.setAttribute(`position`,new q(n,3));let e=this.selectionLines.geometry.getAttribute(`position`);e.needsUpdate=!0}}syncDebugLines(){let e=null;for(let t of tv(`3d`,this.engine))if(e=t.debugLines(),e)break;this.debugLines.visible=e!==null,e&&this.debugLines.geometry.setAttribute(`position`,new q(e,3))}governResolution(){let e=this.adaptive;if(!e)return;let t=globalThis.performance?.now?.()??0,n=this.lastFrameAt;if(this.lastFrameAt=t,n===0)return;let r=t-n;if(r>500){e.reset();return}let i=e.push(r);if(i===null)return;this.webgl.setPixelRatio(this.basePixelRatio*i);let a=this.lastSize;a.w>0&&a.h>0&&this.webgl.setSize(a.w,a.h,!1)}deferFirstCompile(){this.deferCompile=!0}async warmUp(e){this.deferCompile=!1;let t=this.warmCamera;if(!t)return;let n=[];this.threeScene.traverse(e=>{(e.isMesh||e.isPoints)&&n.push(e)});let r=n.filter(e=>e.visible);if(r.length===0){this.webgl.compile(this.threeScene,t),e?.(1);return}for(let e of r)e.visible=!1;let i=Math.min(bP,r.length),a=Math.ceil(r.length/i);try{for(let n=0;n<i;n++){for(let e=n*a;e<Math.min((n+1)*a,r.length);e++)r[e].visible=!0;this.webgl.compile(this.threeScene,t),e?.((n+1)/i),typeof requestAnimationFrame==`function`&&await new Promise(e=>{requestAnimationFrame(()=>setTimeout(e,0))})}}finally{for(let e of r)e.visible=!0}}render(){let e=this.engine.scene;if(!e)return;this.webgl.info.reset(),this.governResolution(),this.syncDebugLines(),this.syncSelectionOutline(),e.assets&&!this.loadedAssetScenes.has(e)&&(this.assets.load(e.assets),this.loadedAssetScenes.add(e)),this.environment.apply(e.environment,this.webgl);let{activeCamera:t,renderHooks:n,sunLight:r}=lP(e.root,this.threeScene,this.assets,{sunDirection:this.environment.sunDirection,alpha:this.engine.interpolationAlpha,ignoreStatic:this.ignoreStatic},this.syncScratch),i=t;if(this.viewOverride){let[e,t,n]=this.viewOverride.position,[r,a,o]=this.viewOverride.target;this.overrideCam.position.set(e,t,n),this.overrideCam.lookAt(SP.set(r,a,o)),i=this.overrideCam}if(!i)return;this.lastCamera=i,i.updateWorldMatrix(!0,!1);let a=i.getWorldPosition(OP),o=r?r._ensureObject3D():null,s=!!o&&r.shadowFollowsCamera===!0;this.environment.applySunLight(o,s?a:null),this.compiledScene!==e&&!this.deferCompile&&(this.compiledScene=e,this.webgl.compile(this.threeScene,i)),this.warmCamera=i;let c=this.canvas.clientWidth||this.canvas.width,l=this.canvas.clientHeight||this.canvas.height,u=this.webgl.getSize(xP);(u.x!==c||u.y!==l)&&this.webgl.setSize(c,l,!1),this.lastSize={w:c,h:l};let d=l===0?1:c/l;i.aspect!==d&&(i.aspect=d,i.updateProjectionMatrix()),this.renderCtx||={gl:this.webgl,scene:this.threeScene,camera:i};let f=this.renderCtx;f.camera=i,o?(o.updateWorldMatrix(!0,!1),o.target.updateWorldMatrix(!0,!1),f.sunDir=wP.setFromMatrixPosition(o.matrixWorld).sub(TP.setFromMatrixPosition(o.target.matrixWorld)).normalize()):f.sunDir=null;for(let e=0;e<n.length;e++)n[e]?._onRender3D(f);let p=null;for(let e=0;e<n.length;e++){let t=n[e].underwaterAt?.(a.x,a.y,a.z);if(t){p=t;break}}this.environment.applyUnderwater(p);let m=this.environment.clouds,h=this.environment.bloom,g=this.environment.post;p?.caustics.enabled?this.renderWithCaustics(i,p):m&&!p?this.renderWithClouds(i,m,o):(h||g)&&!p?this.renderWithBloom(i,h,g):this.webgl.render(this.threeScene,i)}renderWithBloom(e,t,n=null){let r=this.webgl.getDrawingBufferSize(xP),i=Math.max(1,r.x),a=Math.max(1,r.y),o=Math.max(1,Math.ceil(i/2)),s=Math.max(1,Math.ceil(a/2));if(this.bloomTarget&&(this.bloomTarget.width!==i||this.bloomTarget.height!==a)&&(this.bloomTarget.dispose(),this.bloomTarget=null,this.bloomBrightTarget?.dispose(),this.bloomBrightTarget=null,this.bloomBlurTarget?.dispose(),this.bloomBlurTarget=null),this.bloomTarget||(this.bloomTarget=new Ba(i,a,{type:gr,samples:4}),this.bloomBrightTarget=new Ba(o,s,{type:gr}),this.bloomBlurTarget=new Ba(o,s,{type:gr})),!this.bloomBrightScene){let e=nN();this.bloomBrightScene=new Eo,this.bloomBrightScene.add(e.mesh),this.bloomBrightUniforms=e.uniforms;let t=rN();this.bloomBlurScene=new Eo,this.bloomBlurScene.add(t.mesh),this.bloomBlurUniforms=t.uniforms;let n=iN();this.bloomCompositeScene=new Eo,this.bloomCompositeScene.add(n.mesh),this.bloomCompositeUniforms=n.uniforms}let c=this.bloomBrightTarget,l=this.bloomBlurTarget;if(this.webgl.setRenderTarget(this.bloomTarget),this.webgl.render(this.threeScene,e),t){let n=this.bloomBrightUniforms;n.tScene.value=this.bloomTarget.texture,n.uThreshold.value=t.threshold,this.webgl.setRenderTarget(c),this.webgl.render(this.bloomBrightScene,e);let r=this.bloomBlurUniforms;r.tTex.value=c.texture,r.uDir.value.set(1/o,0),this.webgl.setRenderTarget(l),this.webgl.render(this.bloomBlurScene,e),r.tTex.value=l.texture,r.uDir.value.set(0,1/s),this.webgl.setRenderTarget(c),this.webgl.render(this.bloomBlurScene,e)}let u=this.bloomCompositeUniforms;u.tScene.value=this.bloomTarget.texture,u.tBloom.value=t?c.texture:this.bloomTarget.texture,u.uStrength.value=t?t.strength:0,u.uVignette.value=n?.vignette??0,u.uSaturation.value=n?.saturation??1,u.uContrast.value=n?.contrast??1,this.webgl.setRenderTarget(null),this.webgl.render(this.bloomCompositeScene,e)}renderWithClouds(e,t,n){let r=this.webgl.getDrawingBufferSize(xP),i=Math.max(1,r.x),a=Math.max(1,r.y),o=Math.max(1,Math.ceil(i/3)),s=Math.max(1,Math.ceil(a/3));if(this.cloudsTarget&&(this.cloudsTarget.width!==i||this.cloudsTarget.height!==a)&&(this.cloudsTarget.depthTexture?.dispose(),this.cloudsTarget.dispose(),this.cloudsTarget=null,this.cloudsHalfTarget?.dispose(),this.cloudsHalfTarget=null,this.cloudsBlurTarget?.dispose(),this.cloudsBlurTarget=null),!this.cloudsTarget){let e=new $c(i,a);e.type=hr,this.cloudsTarget=new Ba(i,a,{depthTexture:e,depthBuffer:!0})}if(this.cloudsHalfTarget||(this.cloudsHalfTarget=new Ba(o,s,{depthBuffer:!1}),this.cloudsBlurTarget=new Ba(o,s,{depthBuffer:!1})),!this.cloudsScene){let{mesh:e,uniforms:t}=uN();this.cloudsScene=new Eo,this.cloudsScene.add(e),this.cloudsUniforms=t}if(!this.cloudsBlurScene){let{mesh:e,uniforms:t}=lN();this.cloudsBlurScene=new Eo,this.cloudsBlurScene.add(e),this.cloudsBlurUniforms=t}if(!this.cloudsCompositeScene){let{mesh:e,uniforms:t}=dN();this.cloudsCompositeScene=new Eo,this.cloudsCompositeScene.add(e),this.cloudsCompositeUniforms=t}this.webgl.setRenderTarget(this.cloudsTarget),this.webgl.render(this.threeScene,e);let c=this.cloudsUniforms;c.tDepth.value=this.cloudsTarget.depthTexture,c.uInvViewProj.value.multiplyMatrices(e.projectionMatrix,e.matrixWorldInverse).invert(),e.getWorldPosition(c.uCameraPos.value),c.uTime.value=(globalThis.performance?.now()??0)*.001*t.speed;let l=this.environment.sunDirection??[.4,.8,.3];c.uSunDir.value.set(l[0],l[1],l[2]).normalize(),n&&c.uSunColor.value.copy(n.color),c.uCloudColor.value.set(t.color),c.uShadeColor.value.set(t.shadeColor);let u=this.environment.sceneFog;u?(c.uHorizonColor.value.copy(u.color),c.uFarFade.value=u.far):(c.uHorizonColor.value.set(`#cdd9e6`),c.uFarFade.value=6e3),c.uBase.value=t.base,c.uTop.value=t.top,c.uCoverage.value=t.coverage,c.uDensity.value=t.density,c.uScale.value=t.scale,c.uWind.value.set(1,.35),this.webgl.setRenderTarget(this.cloudsHalfTarget),this.webgl.render(this.cloudsScene,e);let d=this.cloudsBlurUniforms,f=this.cloudsBlurScene;d.tTex.value=this.cloudsHalfTarget.texture,d.uDir.value.set(1/o,0),this.webgl.setRenderTarget(this.cloudsBlurTarget),this.webgl.render(f,e),d.tTex.value=this.cloudsBlurTarget.texture,d.uDir.value.set(0,1/s),this.webgl.setRenderTarget(this.cloudsHalfTarget),this.webgl.render(f,e),this.webgl.setRenderTarget(null);let p=this.cloudsCompositeUniforms;p.tScene.value=this.cloudsTarget.texture,p.tClouds.value=this.cloudsHalfTarget.texture,this.webgl.render(this.cloudsCompositeScene,e)}renderWithCaustics(e,t){let n=this.webgl.getDrawingBufferSize(xP),r=Math.max(1,n.x),i=Math.max(1,n.y);if(this.causticsTarget&&(this.causticsTarget.width!==r||this.causticsTarget.height!==i)&&(this.causticsTarget.depthTexture?.dispose(),this.causticsTarget.dispose(),this.causticsTarget=null),!this.causticsTarget){let e=new $c(r,i);e.type=hr,this.causticsTarget=new Ba(r,i,{depthTexture:e,depthBuffer:!0})}if(!this.causticsScene){let{mesh:e,uniforms:t}=th();this.causticsScene=new Eo,this.causticsScene.add(e),this.causticsUniforms=t}this.webgl.setRenderTarget(this.causticsTarget),this.webgl.render(this.threeScene,e),this.webgl.setRenderTarget(null);let a=this.causticsUniforms;a.tColor.value=this.causticsTarget.texture,a.tDepth.value=this.causticsTarget.depthTexture,a.uInvViewProj.value.multiplyMatrices(e.projectionMatrix,e.matrixWorldInverse).invert(),e.getWorldPosition(a.uCameraPos.value),a.uWaterLevel.value=t.surfaceY,a.uTime.value=(globalThis.performance?.now()??0)*.001*t.caustics.speed,a.uCausticColor.value.set(t.caustics.color),a.uCausticIntensity.value=t.caustics.intensity,a.uCausticScale.value=t.caustics.scale,a.uMaxDist.value=t.visibility;let o=this.environment.sunDirection;o&&a.uSunDirection.value.set(o[0],o[1],o[2]),a.uRayStrength.value=t.rays.enabled?t.rays.strength:0,this.webgl.render(this.causticsScene,e)}screenFromWorld(e,t,n){let r=this.lastCamera;return r?(CP.set(e,t,n).project(r),{x:(CP.x+1)/2*this.lastSize.w,y:(1-CP.y)/2*this.lastSize.h,behind:CP.z>1}):{x:0,y:0,behind:!0}}pick(e,t){let n=this.lastCamera;if(!n)return null;AP.set(e/this.lastSize.w*2-1,-(t/this.lastSize.h*2-1)),kP.setFromCamera(AP,n);let r=kP.intersectObjects(this.threeScene.children,!0);for(let e of r){let t=e.object;for(;t&&!t.userData.incantoNode;)t=t.parent;let n=t?.userData.incantoNode;if(n)return n}return null}stats(){let e=this.webgl.info;return{triangles:e.render.triangles,drawCalls:e.render.calls,geometries:e.memory.geometries,textures:e.memory.textures}}lastCameraPosition(){let e=this.lastCamera;return e?(e.getWorldPosition(DP),{x:DP.x,y:DP.y,z:DP.z}):null}cameraBasis(){let e=this.lastCamera,t=e?e.getWorldQuaternion(EP):EP.identity();return{right:new U(1,0,0).applyQuaternion(t),up:new U(0,1,0).applyQuaternion(t),forward:new U(0,0,-1).applyQuaternion(t)}}refreshShadows(){this.webgl.shadowMap.needsUpdate=!0}dispose(){this.engine.picker&&(this.engine.picker=null),this.disconnect(),this.threeScene.traverse(e=>{let t=e;if(!(!t.isMesh||t.userData?.incantoModelShared))if(t.geometry?.dispose(),Array.isArray(t.material))for(let e of t.material)e.dispose();else t.material?.dispose()}),this.causticsTarget?.depthTexture?.dispose(),this.causticsTarget?.dispose();let e=this.causticsScene?.children[0];e?.geometry?.dispose(),e?.material?.dispose(),this.cloudsTarget?.depthTexture?.dispose(),this.cloudsTarget?.dispose(),this.cloudsHalfTarget?.dispose(),this.cloudsBlurTarget?.dispose(),this.bloomTarget?.dispose(),this.bloomBrightTarget?.dispose(),this.bloomBlurTarget?.dispose();for(let e of[this.cloudsScene,this.cloudsBlurScene,this.cloudsCompositeScene,this.bloomBrightScene,this.bloomBlurScene,this.bloomCompositeScene]){let t=e?.children[0];t?.geometry?.dispose(),t?.material?.dispose()}this.ownsAssets&&this.assets.dispose(),this.environment.dispose(),this.webgl.dispose()}},bP=12,xP=new V,SP=new U,CP=new U,wP=new U,TP=new U,EP=new H,DP=new U,OP=new U,kP=new qu,AP=new V;async function jP(e){let t=async(t,n)=>{e.onProgress&&(e.onProgress(t,n),typeof requestAnimationFrame==`function`&&await new Promise(e=>{requestAnimationFrame(()=>setTimeout(e,0))}))};JM(),(e.gameplay??!0)&&G_();for(let[t,n]of Object.entries(e.behaviors??{}))it(t,n,{replace:!0});let n=new kt({seed:e.seed,fixedHz:e.fixedHz,...e._scheduler?{scheduler:e._scheduler}:{}}),r=MP(e.scene),i=An(MP(r),{resolveScene:e.resolveScene,engine:n});n.setScene(i),await t(.06,`scene`);let a=null;(e.physics===!0||(e.physics??`auto`)===`auto`&&NP(i.root))&&(a=await AT(n)),await t(.1,`physics`);let o=[],s=e.keyboard??(typeof window<`u`?window:!1);if(s&&n.input.attachKeyboard(s),e.pointer){let t=typeof e.pointer==`object`?e.pointer.lockOnClick??!0:!0;n.input.attachPointer(e.canvas,{lockOnClick:t})}o.push(PP(n,i.root,e.canvas));let c=e.touch??`auto`;if(c!==!1){let t=e.touchContainer??e.canvas.parentElement??null;if(t){let r={force:c===!0,...e._touchDoc?{doc:e._touchDoc}:{}},i=qn(n,t,r),a=n.sceneChanged.connect(()=>{i?.dispose(),i=qn(n,t,r)});o.push(()=>{a(),i?.dispose()})}}let l=e._rendererFactory?e._rendererFactory(n,e.canvas):new yP({canvas:e.canvas,engine:n,...e.pixelRatio===void 0?{}:{pixelRatio:e.pixelRatio},...e.adaptiveResolution===void 0?{}:{adaptiveResolution:e.adaptiveResolution},...e.preserveDrawingBuffer===void 0?{}:{preserveDrawingBuffer:e.preserveDrawingBuffer}});await t(.14,`renderer`);let u=e.debug??!1,d=e.editor??u,f=d===!0?{}:d||null,p={label:`✎ edit this scene`,run:async()=>{if(!f)return;let t=Mm(l),n=f.open??Am,i=async t=>{await jP({...e,scene:t})};await jm(async()=>{m();try{await n({scene:r,...t?{camera:t}:{},play:i,exit:()=>i(r),...f.save?{save:f.save}:{},...f.library?{library:f.library===!0?wm():f.library}:{}})}catch(e){console.error(`[incanto] could not open the editor:`,e),await i(r)}},`opening the editor…`)}};if(u){let t=e.touchContainer??e.canvas.parentElement??(typeof document<`u`?document.body:null);if(t){let{attachDebugOverlay:r}=await bm(async()=>{let{attachDebugOverlay:e}=await import(`./debug-CPbraUYm.js`);return{attachDebugOverlay:e}},[],import.meta.url),i=r(n,{container:t,statsSource:()=>l.stats?.()??{},...f?{actions:[p]}:{},...e._debugDoc?{doc:e._debugDoc}:{}});i&&o.push(()=>i.dispose())}}n.start(),await t(.16,`shaders`);try{l.deferFirstCompile?.();let t=globalThis.performance?.now?.()??0;n.tick(t),n.tick(t+16),await l.warmUp?.(t=>{e.onProgress?.(.16+t*.82,`shaders`)})}catch{}o.push(n.settings.bindAudio(n.audio)),o.push(n.settings.bindLocale(n.locale)),await t(1,`ready`);function m(){Nm([a?[`physics`,()=>a?.dispose()]:null,[`app cleanups`,()=>{for(let e of o)e()}],[`engine`,()=>n.dispose()],[`renderer`,()=>l.dispose()]])}return{engine:n,scene:i,sourceJson:r,renderer:l,physics:a,assetErrors(){return l.assets?.errors()??[]},pick(e,t){return n.picker?.(e,t)??null},stats(){return{triangles:0,drawCalls:0,geometries:0,textures:0,...n.stats(),...l.stats?.()}},openEditor:f?p.run:null,dispose:m}}function MP(e){try{return structuredClone(e)}catch{throw new N(`BAD_FORMAT`,`createGame "scene" must be plain scene JSON (the imported *.scene.json object) — got something unclonable (a loaded Scene, class instances, or functions).`)}}function NP(e){if(e instanceof jh)return!0;for(let t of e.children)if(NP(t))return!0;return!1}function PP(e,t,n){let r=[],i=n;if(i.addEventListener&&r.push({target:i,type:`pointerdown`}),typeof window<`u`&&r.push({target:window,type:`keydown`}),r.length===0)return()=>{};function a(){for(let e of r)e.target.removeEventListener?.(e.type,o)}function o(){e.sfx.unlock(),e.music.unlock();let n=!1,r=e=>{e instanceof Rt&&(e.retryPending(),e.pendingGesture&&(n=!0));for(let t of e.children)r(t)};r(t),n||a()}for(let e of r)e.target.addEventListener?.(e.type,o,{passive:!0});return a}var FP=e({DEFAULT_TERRAIN_TEXTURE_BASE:()=>rT,WATER_CUTOUT_MAX:()=>4,WATER_MAX_RIPPLES:()=>8,createGame3D:()=>jP,enablePhysics3D:()=>AT}),IP=new WeakMap,LP=class e{account;roomId;roomState=new j;allUserStates=new j;userJoined=new j;userLeft=new j;globalState=new j;globalMyState=new j;asset=new j;latestUserStates={};latestRoomState={};latestGlobalState={};latestGlobalMyState={};latestAsset={};server;engine;throttleMs;subs=[];messageSignals=new Map;collectionSignals=new Map;latestCollections=new Map;globalMessageSignals=new Map;globalCollectionSignals=new Map;latestGlobalCollections=new Map;scenes=new Map;lastSent=new Map;sendAccumulator=0;detachReplication=null;lastOwner=null;boundScene=null;static get(e){return IP.get(e)??null}static async create(t,n={}){await IP.get(t)?.dispose();let r=n.transport??await HP(n.config);await r.connect();let i=n.room??t.scene?.multiplayer?.room??`auto`,a=new e(t,r,await r.remoteFunction(`joinRoom`,[i===`auto`?void 0:i],{needResponse:!0}),n.throttleMs??50);return IP.set(t,a),a}constructor(e,t,n,r){this.engine=e,this.server=t,this.roomId=n,this.account=t.account,this.throttleMs=Math.max(30,r),this.boundScene=e.scene,this.subs.push(t.subscribeRoomState(n,e=>{this.latestRoomState=e,this.roomState.emit(e)}),t.subscribeRoomAllUserStates(n,e=>{this.latestUserStates=e,this.allUserStates.emit(e)}),t.onRoomUserJoin(n,e=>this.userJoined.emit(e)),t.onRoomUserLeave(n,e=>this.userLeft.emit(e))),t.subscribeGlobalState&&this.subs.push(t.subscribeGlobalState(e=>{this.latestGlobalState=e,this.globalState.emit(e)})),t.subscribeGlobalMyState&&this.subs.push(t.subscribeGlobalMyState(e=>{this.latestGlobalMyState=e,this.globalMyState.emit(e)})),t.subscribeAsset&&this.subs.push(t.subscribeAsset(this.account,e=>{this.latestAsset=e,this.asset.emit(e)})),this.detachReplication=e.fixedUpdated.connect(e=>this.replicate(e))}message(e){let t=this.messageSignals.get(e);return t||(t=new j,this.messageSignals.set(e,t),this.subs.push(this.server.onRoomMessage(this.roomId,e,e=>t?.emit(e)))),t}collection(e){let t=this.collectionSignals.get(e);return t||(t=new j,this.collectionSignals.set(e,t),this.subs.push(this.server.subscribeRoomCollection(this.roomId,e,n=>{this.latestCollections.set(e,n),t?.emit(n)}))),t}latestCollection(e){return this.collection(e),this.latestCollections.get(e)??{}}globalMessage(e){let t=this.globalMessageSignals.get(e);if(!t){t=new j,this.globalMessageSignals.set(e,t);let n=this.server.onGlobalMessage?.(e,e=>t?.emit(e));n&&this.subs.push(n)}return t}globalCollection(e){let t=this.globalCollectionSignals.get(e);if(!t){t=new j,this.globalCollectionSignals.set(e,t);let n=this.server.subscribeGlobalCollection?.(e,n=>{this.latestGlobalCollections.set(e,n),t?.emit(n)});n&&this.subs.push(n)}return t}latestGlobalCollection(e){return this.globalCollection(e),this.latestGlobalCollections.get(e)??{}}setMyState(e){return this.server.remoteFunction(`setMyState`,[this.roomId,e],{throttle:this.throttleMs,throttleKey:`incanto:myState`})}patchRoomState(e){return this.server.remoteFunction(`patchRoomState`,[this.roomId,e])}addEntity(e,t){return this.server.remoteFunction(`addEntity`,[this.roomId,e,t])}updateEntity(e,t,n){return this.server.remoteFunction(`updateEntity`,[this.roomId,e,t,n])}removeEntity(e,t){return this.server.remoteFunction(`removeEntity`,[this.roomId,e,t])}sendEvent(e,t){return this.server.remoteFunction(`sendEvent`,[this.roomId,e,t])}call(e,...t){return this.server.remoteFunction(e,[this.roomId,...t],{needResponse:!0})}registerScene(e,t){this.scenes.set(e,t)}resolveScene(e){let t=this.scenes.get(e);if(!t)throw new N(`UNRESOLVED_INSTANCE`,`No scene registered for '${e}'. Registered: [${[...this.scenes.keys()].join(`, `)}]. Call manager.registerScene('${e}', sceneJson).`);return t}async dispose(){this.detachReplication?.();for(let e of this.subs)e();await this.server.remoteFunction(`leaveRoom`,[this.roomId]),IP.delete(this.engine)}replicate(e){let t=this.engine.scene;if(!t||t!==this.boundScene)return;this.sendAccumulator+=e*1e3;let n=RP(t.root,!0);if(!n)return;n!==this.lastOwner&&(this.lastOwner=n,this.lastSent.clear());let r=n.network,i=Math.max(30,typeof r.throttleMs==`number`?r.throttleMs:this.throttleMs),a=Array.isArray(r.sync)?r.sync:[],o={};for(let e of a){let t=BP(n,e);t!==void 0&&(Ve(this.lastSent.get(e)??null,t)||(o[e]=He(t)))}if(!(this.sendAccumulator<i)&&Object.keys(o).length!==0){for(let[e,t]of Object.entries(o))this.lastSent.set(e,He(t));this.sendAccumulator=0,this.setMyState({sync:o})}}};function RP(e,t=!1){let n=[];if(zP(e,n),t&&n.length>1)throw new N(`BAD_FORMAT`,`Multiple network owner nodes found (${n.map(e=>e.getPath()).join(`, `)}). Exactly ONE node per player may declare network.mode 'owner' — replicate spawned entities through collections instead.`);return n[0]??null}function zP(e,t){e.network?.mode===`owner`&&t.push(e);for(let n of e.children)zP(n,t)}function BP(e,t){let n=t.lastIndexOf(`.`),r=n===-1?e:e.getNodeOrNull(t.slice(0,n))??void 0,i=n===-1?t:t.slice(n+1);if(r)return r[i]}function VP(e,t,n){for(let[r,i]of Object.entries(t)){let t=r.lastIndexOf(`.`),a=t===-1?e:e.getNodeOrNull(r.slice(0,t)),o=t===-1?r:r.slice(t+1);a&&n(a,o,i)}}async function HP(e){let{createAgent8Server:t}=await bm(async()=>{let{createAgent8Server:e}=await import(`./agent8-tvTJH3IX.js`);return{createAgent8Server:e}},[],import.meta.url);return t(e)}var UP=class extends Nt{static typeName=`NetworkSpawner`;static signals=[`spawned`,`despawned`];static props={source:{default:`users`},scene:{default:``},interpolate:{default:!0}};source=`users`;scene=``;interpolate=!0;spawned=new Map;positionTargets=new Map;failedKeys=new Set;update(e){let t=this.tree?.engine;if(!t)return;let n=LP.get(t);if(!n||this.scene===``)return;let r=this.currentEntries(n);for(let[e,t]of Object.entries(r)){let r=this.spawned.get(e);if(!r){if(this.failedKeys.has(e))continue;try{r=jn(n.resolveScene(this.scene).root)}catch(t){throw this.failedKeys.add(e),t}r.name=WP(e),this.addChild(r),this.spawned.set(e,r),this.emit(`spawned`,r,e)}let i=t.sync;i&&VP(r,i,(e,t,n)=>this.setProp(e,t,n))}for(let[e,t]of[...this.spawned.entries()])e in r||(this.spawned.delete(e),this.positionTargets.delete(t),this.emit(`despawned`,t,e),t.free());this.interpolate&&this.stepInterpolation(e)}currentEntries(e){if(this.source===`users`){let t={};for(let[n,r]of Object.entries(e.latestUserStates))n!==e.account&&(t[n]=r);return t}return this.source.startsWith(`collection:`)?e.latestCollection(this.source.slice(11)):{}}setProp(e,t,n){if(this.interpolate&&t===`position`&&Array.isArray(n)){this.positionTargets.set(e,n);return}e[t]=n}stepInterpolation(e){let t=Math.min(1,e*8);for(let[e,n]of this.positionTargets){let r=e.position;Array.isArray(r)&&(e.position=r.map((e,r)=>e+((n[r]??e)-e)*t))}}};function WP(e){return e.replace(/[/%]/g,`_`)||`remote`}function GP(){_n(),R(UP)}function KP(){try{return typeof localStorage>`u`?null:localStorage}catch{return null}}var qP=KP()?.getItem(`incanto-editor-lang`)??`en`,JP=new Set;function YP(){return qP}function XP(e){qP=e,KP()?.setItem(`incanto-editor-lang`,e);for(let e of JP)e()}function ZP(e){JP.add(e)}function QP(e){return e[qP]}var $P={node:{paths:[`M5 5h14v14H5z`]},move:{paths:[`M12 3v18M3 12h18`,`M8 7l4-4 4 4M8 17l4 4 4-4M7 8l-4 4 4 4M17 8l4 4-4 4`]},image:{paths:[`M4 5h16v14H4z`,`M4 15l5-5 4 4 3-3 4 4`],circles:[[9,9,1.6]]},film:{paths:[`M4 4h16v16H4z`,`M4 9h16M4 15h16`,`M9 4v16M15 4v16`]},video:{paths:[`M3 7h12v10H3z`,`M15 10l6-3v10l-6-3`]},text:{paths:[`M5 7V5h14v2`,`M12 5v14`,`M9 19h6`]},layers:{paths:[`M12 3 3 8l9 5 9-5-9-5z`,`M3 12l9 5 9-5`,`M3 16l9 5 9-5`]},square:{paths:[`M5 5h14v14H5z`,`M5 12h14`]},ball:{paths:[`M12 8v0`],circles:[[12,12,8],[12,12,1.4]]},person:{paths:[`M5 21v-1a7 7 0 0 1 14 0v1`],circles:[[12,7,4]]},area:{paths:[`M5 5h14v14H5z`],dashed:!0},gamepad:{paths:[`M7 9h-0M6 12h4M8 10v4`,`M4 8h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2z`],circles:[[16,11,1],[18.5,13.5,1]]},clock:{paths:[`M12 7v5l3 2`],circles:[[12,12,9]]},cube:{paths:[`M21 16V8l-9-5-9 5v8l9 5 9-5z`,`M3.3 7.5 12 12.5l8.7-5`,`M12 22V12.5`]},sun:{paths:[`M12 2v3M12 19v3M2 12h3M19 12h3M4.9 4.9l2.1 2.1M17 17l2.1 2.1M19.1 4.9 17 7M7 17l-2.1 2.1`],circles:[[12,12,4]]},bulb:{paths:[`M9 18h6M10 21h4`,`M8 13a6 6 0 1 1 8 0c-1 1-1.5 2-1.5 3h-5c0-1-.5-2-1.5-3z`]},globe:{paths:[`M2 12h20`,`M12 2a15 15 0 0 1 0 20a15 15 0 0 1 0-20z`],circles:[[12,12,10]]},link:{paths:[`M10 14a5 5 0 0 0 7 0l3-3a5 5 0 0 0-7-7l-1 1`,`M14 10a5 5 0 0 0-7 0l-3 3a5 5 0 0 0 7 7l1-1`]},speaker:{paths:[`M11 5 6 9H3v6h3l5 4V5z`,`M15.5 8.5a5 5 0 0 1 0 7M18.5 5.5a9 9 0 0 1 0 13`]},swatch:{paths:[`M4 4h16v16H4z`,`M4 4l16 16`]},sparkles:{paths:[`M12 4v5M12 15v5M5 12h5M14 12h5`],circles:[[6,5,1],[18,19,1]]},waves:{paths:[`M2 8c3-3 5 3 8 0s5 3 8 0`,`M2 14c3-3 5 3 8 0s5 3 8 0`,`M2 20c3-3 5 3 8 0s5 3 8 0`]},plant:{paths:[`M12 21v-8`,`M12 13c0-4-3-6-7-6 0 4 3 6 7 6z`,`M12 11c0-4 3-6 7-6 0 4-3 6-7 6z`]},flower:{paths:[`M12 21v-7`],circles:[[12,9,2],[12,4.5,2.2],[16.3,7.5,2.2],[14.7,12.6,2.2],[9.3,12.6,2.2],[7.7,7.5,2.2]]},voxels:{paths:[`M4 14h8v8H4z`,`M12 14h8v8h-8z`,`M8 6h8v8H8z`]}},eF={Node:`node`,Timer:`clock`,AudioPlayer:`speaker`,ColorRect2D:`swatch`,Particles2D:`sparkles`,Particles3D:`sparkles`,Water3D:`waves`,Foliage3D:`plant`,Flowers3D:`flower`,VoxelGrid3D:`voxels`,ModelInstance3D:`person`,CharacterController3D:`gamepad`,Node2D:`move`,Sprite2D:`image`,AnimatedSprite2D:`film`,Camera2D:`video`,Label:`text`,UILayer:`layers`,StaticBody2D:`square`,RigidBody2D:`ball`,CharacterBody2D:`person`,Area2D:`area`,CharacterController2D:`gamepad`,Node3D:`move`,Billboard3D:`layers`,MeshInstance3D:`cube`,LoftMesh3D:`cube`,Camera3D:`video`,DirectionalLight3D:`sun`,OmniLight3D:`bulb`,StaticBody3D:`square`,RigidBody3D:`ball`,CharacterBody3D:`person`,Area3D:`area`,NetworkSpawner:`globe`};function tF(e){let t=$P[eF[e??``]??(e?`node`:`link`)],n=document.createElementNS(`http://www.w3.org/2000/svg`,`svg`);n.setAttribute(`viewBox`,`0 0 24 24`),n.setAttribute(`width`,`13`),n.setAttribute(`height`,`13`),n.setAttribute(`fill`,`none`),n.setAttribute(`stroke`,`currentColor`),n.setAttribute(`stroke-width`,`2`),n.setAttribute(`stroke-linecap`,`round`),n.setAttribute(`stroke-linejoin`,`round`),t.dashed&&n.setAttribute(`stroke-dasharray`,`3 2.4`);for(let e of t.paths){let t=document.createElementNS(`http://www.w3.org/2000/svg`,`path`);t.setAttribute(`d`,e),n.appendChild(t)}for(let[e,r,i]of t.circles??[]){let t=document.createElementNS(`http://www.w3.org/2000/svg`,`circle`);t.setAttribute(`cx`,String(e)),t.setAttribute(`cy`,String(r)),t.setAttribute(`r`,String(i)),n.appendChild(t)}return n}function nF(){let e=document.createElementNS(`http://www.w3.org/2000/svg`,`svg`);e.setAttribute(`viewBox`,`0 0 24 24`),e.setAttribute(`width`,`12`),e.setAttribute(`height`,`12`),e.setAttribute(`fill`,`none`),e.setAttribute(`stroke`,`currentColor`),e.setAttribute(`stroke-width`,`2.4`),e.setAttribute(`aria-hidden`,`true`);let t=document.createElementNS(`http://www.w3.org/2000/svg`,`path`);return t.setAttribute(`d`,`m6 9 6 6 6-6`),e.appendChild(t),e}var rF=[{type:`texture`,label:`image (texture)`,metaHints:[`filter`]},{type:`spritesheet`,label:`spritesheet`,metaHints:[`filter`,`frameWidth`,`frameHeight`]},{type:`model`,label:`3D model (GLB/VRM)`,metaHints:[]},{type:`animation`,label:`animation (GLB clips)`,metaHints:[`clip`]}],iF=new Set,aF=null,oF=null;function sF(e,t,n){let r=document.createElement(`input`);r.className=`rename-input`,r.value=e;let i=()=>{let i=r.value.trim().replace(/\//g,``);i&&i!==e?t(i):n()};r.addEventListener(`keydown`,e=>{e.stopPropagation(),e.key===`/`&&e.preventDefault(),e.key===`Enter`&&i(),e.key===`Escape`&&n()});for(let e of[`click`,`pointerdown`,`dblclick`,`mousedown`])r.addEventListener(e,e=>e.stopPropagation());return r.addEventListener(`blur`,i),queueMicrotask(()=>{r.focus(),r.select()}),r}function cF(e,t){let n={path:``,name:``,folders:new Map,assets:[]},r=e=>{let t=n;if(e===``)return t;for(let n of e.split(`/`)){let e=t.folders.get(n);e||(e={path:t.path?`${t.path}/${n}`:n,name:n,folders:new Map,assets:[]},t.folders.set(n,e)),t=e}return t};for(let t of e){let e=t.lastIndexOf(`/`);r(e===-1?``:t.slice(0,e)).assets.push(t)}for(let e of t)r(e);return n}function lF(e){let t=e.assets.length;for(let n of e.folders.values())t+=lF(n);return t}function uF(e,t){e.textContent=``;let n=t.working.assets??{},r=Object.keys(n);if(r.length===0&&t.pendingGroups.size===0&&!t.addingAsset&&!t.addingGroup){let t=document.createElement(`div`);t.className=`muted-note explorer-empty`,t.textContent=`no assets yet — + adds textures, models, animations`,e.appendChild(t);return}let i=(e,n)=>{e.addEventListener(`dragover`,t=>{t.preventDefault(),t.stopPropagation(),e.classList.add(`drop-target`)}),e.addEventListener(`dragleave`,()=>e.classList.remove(`drop-target`)),e.addEventListener(`drop`,r=>{r.preventDefault(),r.stopPropagation(),e.classList.remove(`drop-target`);let i=r.dataTransfer?.getData(`text/incanto-asset`);i&&t.moveAsset(i,n);let a=r.dataTransfer?.getData(`text/incanto-group`);a&&t.moveGroup(a,n)})};i(e,``);let a=(e,r)=>{let i=n[e],a=e.includes(`/`)?e.slice(e.lastIndexOf(`/`)+1):e,o=document.createElement(`div`);o.className=`tree-row asset-row${t.selectedAsset===e?` selected`:``}`,o.draggable=!0,o.addEventListener(`dragstart`,t=>{t.dataTransfer?.setData(`text/incanto-asset`,e)});let s=document.createElement(`span`);if(s.className=`tree-icon`,s.appendChild(EF(i.type??``)),s.addEventListener(`click`,e=>{e.stopPropagation(),DF(s,i.type??``)}),aF===e){let n=e.includes(`/`)?e.slice(0,e.lastIndexOf(`/`)+1):``;o.appendChild(sF(a,r=>{aF=null,t.renameAssetKey(e,n+r)},()=>{aF=null,t.selectAsset(t.selectedAsset)})),o.draggable=!1,o.insertBefore(s,o.firstChild),r.appendChild(o);return}let c=document.createElement(`span`);c.className=`tree-name asset-key`,c.textContent=`$${a}`,c.title=`$${e}`,c.addEventListener(`dblclick`,n=>{n.stopPropagation(),aF=e,t.selectAsset(e)}),o.append(s,c),o.addEventListener(`click`,()=>t.selectAsset(e)),r.appendChild(o)},o=(e,n)=>{let r=iF.has(e.path),s=document.createElement(`div`);s.className=`asset-folder${r?` collapsed`:``}${t.selectedGroup===e.path?` selected`:``}`,s.draggable=!0,s.addEventListener(`dragstart`,t=>{t.stopPropagation(),t.dataTransfer?.setData(`text/incanto-group`,e.path)});let c=document.createElement(`span`);c.className=`chev`,c.appendChild(nF());let l=document.createElementNS(`http://www.w3.org/2000/svg`,`svg`);l.setAttribute(`viewBox`,`0 0 24 24`),l.setAttribute(`width`,`12`),l.setAttribute(`height`,`12`),l.setAttribute(`fill`,`none`),l.setAttribute(`stroke`,`currentColor`),l.setAttribute(`stroke-width`,`1.8`),l.setAttribute(`aria-hidden`,`true`);let u=document.createElementNS(`http://www.w3.org/2000/svg`,`path`);if(u.setAttribute(`d`,`M3 6a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z`),l.appendChild(u),oF===e.path){let i=e.path.includes(`/`)?e.path.slice(0,e.path.lastIndexOf(`/`)+1):``;if(s.append(c,l,sF(e.name,n=>{oF=null,t.renameGroup(e.path,i+n)},()=>{oF=null,t.selectGroup(t.selectedGroup)})),s.draggable=!1,n.appendChild(s),!r){let t=document.createElement(`div`);t.className=`tree-children`;for(let n of e.folders.values())o(n,t);for(let n of e.assets)a(n,t);t.children.length>0&&n.appendChild(t)}return}let d=document.createElement(`span`);d.textContent=e.name,d.addEventListener(`dblclick`,n=>{n.stopPropagation(),oF=e.path,t.selectGroup(e.path)});let f=document.createElement(`span`);if(f.className=`count`,f.textContent=`(${lF(e)})`,s.append(c,l,d,f),s.addEventListener(`click`,()=>{iF.has(e.path)?iF.delete(e.path):iF.add(e.path),t.selectGroup(e.path)}),i(s,e.path),n.appendChild(s),!r){let t=document.createElement(`div`);t.className=`tree-children`;for(let n of e.folders.values())o(n,t);for(let n of e.assets)a(n,t);t.children.length>0&&n.appendChild(t)}},s=cF(r,t.pendingGroups);for(let t of s.assets)a(t,e);for(let t of s.folders.values())o(t,e)}function dF(e,t,n,r){if(t.selection!==null)return!1;if(t.addingGroup){e.appendChild(jF(t.newGroupParent?`NEW GROUP IN ${t.newGroupParent}/`:`NEW GROUP`));let n=document.createElement(`input`);n.placeholder=t.newGroupParent?`heroes`:`characters (or a/b to nest)`,n.className=`mono`,e.appendChild(xF(`name`,n));let r=document.createElement(`button`);r.type=`button`,r.className=`primary`,r.textContent=`add`;let i=()=>{let e=n.value.trim().replace(/^\/+|\/+$/g,``);e&&(t.cancelAddForms(),t.addGroup(t.newGroupParent?`${t.newGroupParent}/${e}`:e))};r.addEventListener(`click`,i),n.addEventListener(`keydown`,e=>{e.key===`Enter`&&i()});let a=document.createElement(`div`);return a.className=`pop-actions`,a.appendChild(r),e.appendChild(a),setTimeout(()=>n.focus(),0),!0}if(t.addingAsset)return hF(e,t,r);if(t.selectedGroup!==null){let r=t.selectedGroup,i=t.groupCount(r);e.appendChild(jF(`GROUP (${i} asset${i===1?``:`s`})`));let a=r.includes(`/`)?r.slice(0,r.lastIndexOf(`/`)+1):``,o=r.includes(`/`)?r.slice(r.lastIndexOf(`/`)+1):r;e.appendChild(SF(`name`,o,e=>{let n=e.trim().replace(/\/+/g,``);n&&n!==o&&t.renameGroup(r,a+n)}));let s=document.createElement(`button`);return s.type=`button`,s.className=`ghost danger`,s.textContent=`delete group`,s.addEventListener(`click`,()=>{if(i===0){t.deleteGroup(r);return}n(`'${r}/' contains ${i} asset${i===1?``:`s`} — deleting the group deletes them too.`,`delete group & assets`,()=>t.deleteGroup(r))}),e.appendChild(s),!0}let i=t.selectedAsset;if(i===null)return!1;let a=t.working.assets??{};if(!(i in a))return!1;e.appendChild(jF(`ASSET — ${String(a[i].type??`?`)}`)),e.appendChild(OF(i)),e.appendChild(kF(t,i)),e.appendChild(fF(t,a,i,r));let o=document.createElement(`button`);return o.type=`button`,o.className=`ghost danger`,o.textContent=`delete asset`,o.addEventListener(`click`,()=>{t.selectAsset(null),t.mutate(()=>{delete a[i],Object.keys(a).length===0&&delete t.working.assets})}),e.appendChild(o),!0}function fF(e,t,n,r){let i=t[n],a=document.createElement(`div`);a.className=`asset-editor`;let o=n.includes(`/`)?n.slice(n.lastIndexOf(`/`)+1):n,s=n.includes(`/`)?n.slice(0,n.lastIndexOf(`/`)+1):``,c=SF(`name`,o,t=>{let r=t.trim().replace(/^\$/,``).replace(/\//g,``);r&&r!==o&&e.renameAssetKey(n,s+r)});AF(c.querySelector(`input`)),a.appendChild(c);let l=SF(`url`,String(i.url??``),t=>{e.mutate(()=>{i.url=t.trim()})}),u=l.querySelector(`input`);if(r&&u){let t=_F(String(i.type??``));l.appendChild(bF(()=>t,`asset url`,r,t=>{u.value=t,e.mutate(()=>{i.url=t})},()=>yF(t,e)))}a.appendChild(l);let d=document.createElement(`div`);d.className=`muted-note`,d.textContent=`meta (key · value)`,a.appendChild(d);for(let[t,n]of Object.entries(i))t===`type`||t===`url`||a.appendChild(pF(e,i,t,n));return a.appendChild(mF(e,i)),a}function pF(e,t,n,r){let i=document.createElement(`div`);i.className=`meta-row`;let a=document.createElement(`input`);a.value=n,a.className=`mono`;let o=document.createElement(`input`);o.value=typeof r==`string`?r:JSON.stringify(r),o.className=`mono`;let s=()=>{let r=a.value.trim();e.mutate(()=>{delete t[n],r&&(t[r]=CF(o.value))})};a.addEventListener(`change`,s),o.addEventListener(`change`,s);let c=document.createElement(`button`);return c.type=`button`,c.className=`linklike danger-link`,c.textContent=`✕`,c.addEventListener(`click`,()=>{e.mutate(()=>{delete t[n]})}),i.append(a,o,c),i}function mF(e,t){let n=document.createElement(`div`);n.className=`meta-row`;let r=document.createElement(`input`);r.placeholder=`filter…`,r.className=`mono`;let i=document.createElement(`input`);i.placeholder=`nearest`,i.className=`mono`;let a=()=>{let n=r.value.trim();!n||i.value.trim()===``||e.mutate(()=>{t[n]=CF(i.value)})};return r.addEventListener(`change`,a),i.addEventListener(`change`,a),n.append(r,i,document.createElement(`span`)),n}function hF(e,t,n){return e.appendChild(jF(`NEW ASSET`)),e.appendChild(gF(t,n)),!0}function gF(e,t){let n=document.createElement(`div`);n.className=`asset-editor`;let r=document.createElement(`select`);for(let e of rF){let t=document.createElement(`option`);t.value=e.type,t.textContent=e.label,r.appendChild(t)}n.appendChild(xF(`type`,r));let i=document.createElement(`input`);i.placeholder=`(optional) characters`,i.className=`mono`,i.value=e.newAssetGroup;let a=`asset-groups-list`;i.setAttribute(`list`,a);let o=document.createElement(`datalist`);o.id=a;let s=new Set;for(let t of Object.keys(e.working.assets??{})){let e=t.lastIndexOf(`/`);e!==-1&&s.add(t.slice(0,e))}for(let t of e.pendingGroups)s.add(t);for(let e of s){let t=document.createElement(`option`);t.value=e,o.appendChild(t)}n.appendChild(xF(`group`,i)),n.appendChild(o);let c=document.createElement(`input`);c.placeholder=`coin`,c.className=`mono`,AF(c),n.appendChild(xF(`key`,c));let l=document.createElement(`input`);l.placeholder=`/textures/coin.png · https://… · data:…`,l.className=`mono`;let u=xF(`url`,l);t&&u.appendChild(bF(()=>_F(r.value),`new asset`,t,e=>{l.value=e,c.value.trim()||(c.value=vF(e))},()=>yF(_F(r.value),e))),n.appendChild(u);let d=document.createElement(`textarea`);d.rows=2,d.placeholder=`or paste a JSON object: { "type": "model", "url": "/m.glb" }`,n.appendChild(d);let f=document.createElement(`button`);f.type=`button`,f.className=`primary`,f.textContent=`add`,f.addEventListener(`click`,()=>{let t=c.value.trim().replace(/^\$/,``);if(!t)return;let n=i.value.trim().replace(/\/+$/,``),a=n?`${n}/${t}`:t,o=null,s=d.value.trim();if(s)try{o=JSON.parse(s)}catch{d.classList.add(`invalid`);return}else l.value.trim()&&(o={type:r.value,url:l.value.trim()});o&&(e.cancelAddForms(),e.selectedAsset=a,e.mutate(()=>{e.working.assets||(e.working.assets={});let t=e.working.assets;t[a]=o}))});let p=document.createElement(`div`);return p.className=`pop-actions`,p.appendChild(f),n.appendChild(p),n}function _F(e){return e===`model`||e===`animation`?`model`:e===`audio`?`audio`:e===`texture`||e===`spritesheet`?`image`:`any`}function vF(e){return((e.split(/[?#]/)[0]??``).split(`/`).pop()??``).replace(/\.[^.]+$/,``).replace(/[^a-zA-Z0-9_-]+/g,`_`).replace(/_{2,}/g,`_`).replace(/^_+|_+$/g,``).toLowerCase()||`asset`}function yF(e,t){let n=(t.working.dimension??`2d`)===`3d`;if(e===`image`)return n?[`3d`,`textures`]:[`2d`,`sprite_characters`];if(e===`model`)return[`3d`,`characters`]}function bF(e,t,n,r,i){let a=document.createElement(`button`);return a.type=`button`,a.className=`asset-lib`,a.textContent=`📚`,a.title=`Browse the agent8 library`,a.addEventListener(`click`,a=>{a.preventDefault();let o=i?.();n({kind:e(),target:t,...o?{shelf:o}:{}}).then(e=>{e&&r(e)})}),a}function xF(e,t){let n=document.createElement(`label`);n.className=`field`;let r=document.createElement(`span`);return r.textContent=e,n.append(r,t),n}function SF(e,t,n){let r=document.createElement(`input`);return r.value=t,r.className=`mono`,r.addEventListener(`change`,()=>n(r.value)),xF(e,r)}function CF(e){let t=e.trim();if(t===`true`)return!0;if(t===`false`)return!1;if(t!==``&&Number.isFinite(Number(t)))return Number(t);if(t.startsWith(`{`)||t.startsWith(`[`))try{return JSON.parse(t)}catch{return e}return e}var wF={texture:`M3 5h18v14H3z M3 15l5-5 4 4 3-3 6 6 M8.5 9.5h.01`,spritesheet:`M3 4h18v16H3z M9 4v16 M15 4v16 M3 12h18`,model:`M12 2l9 5v10l-9 5-9-5V7z M12 12l9-5 M12 12L3 7 M12 12v10`,animation:`M12 2a10 10 0 1 0 10 10 M22 12l-3-3m3 3l3-3 M12 7v5l3 3`},TF={texture:{en:`image (texture) — Sprite2D.texture references it as "$key".`,ko:`이미지(텍스처) — Sprite2D.texture에서 "$키"로 참조합니다.`},spritesheet:{en:`spritesheet — AnimatedSprite2D slices it into named frame animations.`,ko:`스프라이트시트 — AnimatedSprite2D가 이름 붙은 프레임 애니메이션으로 자릅니다.`},model:{en:`3D model (GLB/glTF/VRM) — ModelInstance3D.model references it as "$key".`,ko:`3D 모델(GLB/glTF/VRM) — ModelInstance3D.model에서 "$키"로 참조합니다.`},animation:{en:`animation clips (GLB, in memory — drawn nowhere) — any model can play them; mixamo retargets onto VRM.`,ko:`애니메이션 클립(GLB, 메모리 전용 — 그려지지 않음) — 어떤 모델이든 재생 가능, mixamo는 VRM에 자동 리타게팅.`}};function EF(e){let t=document.createElementNS(`http://www.w3.org/2000/svg`,`svg`);t.setAttribute(`viewBox`,`0 0 24 24`),t.setAttribute(`width`,`13`),t.setAttribute(`height`,`13`),t.setAttribute(`fill`,`none`),t.setAttribute(`stroke`,`currentColor`),t.setAttribute(`stroke-width`,`1.8`),t.setAttribute(`aria-hidden`,`true`);let n=document.createElementNS(`http://www.w3.org/2000/svg`,`path`);return n.setAttribute(`d`,wF[e]??`M4 4h16v16H4z`),t.appendChild(n),t.classList.add(`asset-icon-${e}`),t}function DF(e,t){document.querySelector(`.balloon`)?.remove();let n=TF[t];if(!n)return;let r=document.createElement(`div`);r.className=`balloon floating`;let i=document.createElement(`div`);i.className=`balloon-title`,i.textContent=t;let a=document.createElement(`span`);a.textContent=QP(n),r.append(i,a),document.body.appendChild(r);let o=e.getBoundingClientRect();r.style.left=`${o.right+8}px`,r.style.top=`${Math.max(8,o.top-8)}px`;let s=()=>{r.remove(),document.removeEventListener(`pointerdown`,s,!0)};setTimeout(()=>document.addEventListener(`pointerdown`,s,!0),0)}function OF(e){let t=document.createElement(`div`);t.className=`field uid-line`;let n=document.createElement(`span`);n.textContent=`key`;let r=document.createElement(`div`);r.className=`uid-value`;let i=document.createElement(`code`);i.textContent=`$${e}`;let a=document.createElement(`button`);return a.type=`button`,a.className=`uid-copy`,a.title=`Copy key`,a.innerHTML=`<svg aria-hidden="true" width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>`,a.addEventListener(`click`,()=>{navigator.clipboard?.writeText(`$${e}`),a.classList.add(`copied`),setTimeout(()=>a.classList.remove(`copied`),600)}),r.append(i,a),t.append(n,r),t}function kF(e,t){let n=t.includes(`/`)?t.slice(0,t.lastIndexOf(`/`)):``,r=document.createElement(`select`),i=new Set([``]);for(let t of Object.keys(e.working.assets??{})){let e=t.split(`/`);for(let t=1;t<e.length;t++)i.add(e.slice(0,t).join(`/`))}for(let t of e.pendingGroups)i.add(t);for(let e of[...i].sort()){let t=document.createElement(`option`);t.value=e,t.textContent=e===``?`(root)`:`${e}/`,e===n&&(t.selected=!0),r.appendChild(t)}r.addEventListener(`change`,()=>{e.moveAsset(t,r.value)});let a=document.createElement(`label`);a.className=`field`;let o=document.createElement(`span`);return o.textContent=`group`,a.append(o,r),a}function AF(e){e&&(e.addEventListener(`keydown`,e=>{e.key===`/`&&e.preventDefault()}),e.addEventListener(`input`,()=>{e.value.includes(`/`)&&(e.value=e.value.replace(/\//g,``))}))}function jF(e){let t=document.createElement(`div`);t.className=`section-title`,t.textContent=e;let n=document.createElement(`span`);return n.className=`rule`,t.appendChild(n),t}var MF=window.parent!==window,NF=new URLSearchParams(window.location.search).get(`parentOrigin`),PF=!1;function FF(e){if(MF){if(!NF){PF||(PF=!0,console.warn(`incanto-editor: embedded without ?parentOrigin=<origin> — postMessage disabled`));return}window.parent.postMessage(e,NF)}}var IF={ready(e,t,n){FF({type:`incanto-editor:ready`,input:e,output:t,version:n})},open(e,t){FF({type:`incanto-editor:open`,input:e,output:t})},change(e){FF({type:`incanto-editor:change`,dirty:e})},save(e,t,n){FF({type:`incanto-editor:save`,input:e,output:t,data:n})},error(e){FF({type:`incanto-editor:error`,message:e})}},LF=[[`Core`,e=>!e.endsWith(`2D`)&&!e.endsWith(`3D`)&&e!==`Label`&&e!==`UILayer`&&e!==`NetworkSpawner`],[`2D`,e=>e.endsWith(`2D`)&&!/Body|Area|Controller/.test(e)||e===`Label`||e===`UILayer`],[`2D Physics`,e=>e.endsWith(`2D`)&&/Body|Area|Controller/.test(e)],[`3D`,e=>e.endsWith(`3D`)&&!/Body|Area|Controller/.test(e)],[`3D Physics`,e=>e.endsWith(`3D`)&&/Body|Area|Controller/.test(e)],[`Network`,e=>e===`NetworkSpawner`]],RF=[...LF,[`Other`,e=>LF.every(([,t])=>!t(e))]],zF={title:{en:`How Incanto scenes work`,ko:`Incanto 씬은 어떻게 동작하나`},sections:[{heading:{en:`Everything is a node in a tree`,ko:`모든 것은 트리 위의 노드`},text:{en:`A scene is ONE tree of typed nodes (Godot-style). Each node has a name (unique among its siblings), a type that defines its props and behavior, optional children, and an optional scene-wide-unique uid. The whole structure lives in a *.scene.json file — there is no hidden state: what you see in this editor IS the file.`,ko:`씬은 타입을 가진 노드들의 단일 트리입니다(Godot 방식). 각 노드는 이름(형제 간 유일), props와 동작을 결정하는 타입, 선택적 자식들, 그리고 선택적인 씬 전역 유일 uid를 가집니다. 전체 구조가 *.scene.json 파일 하나에 들어있고 숨겨진 상태는 없습니다 — 이 에디터에서 보는 것이 곧 파일 그 자체입니다.`}},{heading:{en:`Props are delta-only`,ko:`Props는 변경분만 기록`},text:{en:`Every prop has a default defined by the engine. The JSON only stores values that DIFFER from the default — so files stay small and diffs stay meaningful. This editor follows the same rule: set a value back to its default and it disappears from the file.`,ko:`모든 prop에는 엔진이 정의한 기본값이 있습니다. JSON에는 기본값과 다른 값만 기록되어 파일이 작고 diff가 의미를 가집니다. 이 에디터도 같은 규칙을 따릅니다 — 값을 기본값으로 되돌리면 파일에서 사라집니다.`}},{heading:{en:`Addressing: paths, names, uid, groups`,ko:`노드 찾기: 경로·이름·uid·그룹`},text:{en:`Code reaches nodes four ways: a path like "Player/Skin" (relative) or "%Unique" (marked-unique name), getNodesByName("Enemy") which returns a LIST (names repeat across the tree), getNodeByUid("n_x1y2") which returns exactly one node and survives moves/renames, and groups — free tags for queries like "every coin".`,ko:`코드는 네 가지 방법으로 노드에 접근합니다: "Player/Skin" 같은 경로(상대) 또는 "%Unique"(유일 표시 이름), 트리 전체에서 같은 이름을 모두 찾는 getNodesByName("Enemy") — 이름은 중복될 수 있어 리스트가 돌아옵니다 —, 정확히 한 노드를 돌려주고 이동/개명에도 살아남는 getNodeByUid("n_x1y2"), 그리고 "모든 코인"처럼 묶어 조회하는 자유 태그 groups.`}},{heading:{en:`Signals connect, behaviors act`,ko:`시그널로 잇고 비헤이비어로 움직인다`},text:{en:`Nodes emit signals (an Area2D fires triggerEnter, a Timer fires timeout). The scene's "connections" wire a signal to a handler — declaratively, in JSON. Game logic itself is a Behavior: a TypeScript class in YOUR game, attached by name via "script". The inspector's CONNECTIONS section shows and edits these links on the selected node — what it emits, what reaches it, and any end that no longer resolves. The handler code itself lives in your game.`,ko:`노드는 시그널을 발산합니다(Area2D의 triggerEnter, Timer의 timeout). 씬의 "connections"가 시그널을 핸들러에 선언적으로(JSON으로) 연결합니다. 게임 로직 자체는 Behavior — 게임 쪽 TypeScript 클래스이며 "script"에 이름으로 연결됩니다. 인스펙터의 CONNECTIONS 섹션이 선택한 노드의 연결을 보여주고 편집합니다 — 나가는 것, 들어오는 것, 그리고 더 이상 찾을 수 없는 끝. 핸들러 코드 자체는 게임에 있습니다.`}},{heading:{en:`Assets are declared, then referenced`,ko:`에셋은 선언하고 $키로 참조`},text:{en:`The scene header declares assets (textures, spritesheets, 3D models, animation clips) under a key; nodes reference them as "$key". Animations are data too: an {type:"animation"} asset loads GLB clips into memory and any ModelInstance3D can play them — Mixamo clips retarget onto VRM avatars automatically.`,ko:`씬 헤더에서 에셋(텍스처·스프라이트시트·3D 모델·애니메이션 클립)을 키로 선언하고, 노드는 "$key"로 참조합니다. 애니메이션도 데이터입니다 — {type:"animation"} 에셋이 GLB 클립을 메모리에 올리고 어떤 ModelInstance3D든 재생할 수 있으며, Mixamo 클립은 VRM 아바타에 자동 리타게팅됩니다.`}}]},Q=(e,t,...n)=>({type:e,summary:t,body:n}),BF=[{id:`core`,label:{en:`Core`,ko:`Core`},intro:{en:`Dimension-free building blocks: plain containers and the game clock. They render nothing themselves.`,ko:`차원과 무관한 기본 블록 — 순수 컨테이너와 게임 시계입니다. 스스로는 아무것도 그리지 않습니다.`},nodes:[Q(`Node`,{en:`A plain container with no transform.`,ko:`변환 없이 자식을 묶는 순수 컨테이너.`},{en:`Use it to group related nodes (all coins, all UI) without affecting their positions. Lifecycle, signals, groups, script — everything works; it just has no visual or spatial meaning of its own.`,ko:`위치에 영향을 주지 않으면서 관련 노드(코인 전부, UI 전부)를 묶을 때 씁니다. 라이프사이클·시그널·그룹·스크립트가 모두 동작하며, 시각적·공간적 의미만 없습니다.`}),Q(`Timer`,{en:"A serializable countdown that emits `timeout`.",ko:"`timeout` 시그널을 쏘는 직렬화 가능한 카운트다운."},{en:`Set waitTime (seconds), optionally autostart or oneShot, and connect its timeout signal to any handler. Because it is a node, the whole timing setup lives in the scene file — agents can read and tune it.`,ko:`waitTime(초)을 정하고 autostart·oneShot을 선택한 뒤 timeout 시그널을 핸들러에 연결하세요. 노드이기 때문에 타이밍 설정 전체가 씬 파일에 남아 에이전트가 읽고 조정할 수 있습니다.`}),Q(`HudLayer`,{en:`Screen-space HUD overlay above the canvas — parent for UiText/UiBar/UiBanner.`,ko:`캔버스 위 화면 고정 HUD 오버레이 — UiText/UiBar/UiBanner의 부모.`},{en:`A DOM overlay (position:fixed) that never blocks pointer input. Put UI widgets as children; each picks one of 9 anchors (topLeft…bottomRight). Works identically over 2D and 3D renderers; in headless/tests it is a silent no-op. zIndex lifts it above the canvas.`,ko:`포인터 입력을 가로막지 않는 DOM 오버레이(position:fixed)입니다. UI 위젯을 자식으로 두면 각자 9개 앵커(topLeft…bottomRight) 중 하나에 붙습니다. 2D·3D 렌더러 어디서나 동일하게 동작하고, 헤드리스/테스트에서는 조용히 no-op입니다. zIndex로 캔버스 위에 올립니다.`}),Q(`UiText`,{en:`A HUD text line — score, timers, hints.`,ko:`HUD 텍스트 한 줄 — 점수, 타이머, 힌트.`},{en:`Child of HudLayer. Set text/size/color in JSON; update from behaviors: (getNode('%Score') as UiText).text = String(score). shadow adds a soft outline for readability over any scene.`,ko:`HudLayer의 자식. text/size/color를 JSON으로 정하고, 비헤이비어에서 (getNode('%Score') as UiText).text = String(score) 로 갱신하세요. shadow는 어떤 화면 위에서도 읽히도록 부드러운 그림자를 더합니다.`}),Q(`UiBar`,{en:`A labeled progress bar — health, stamina, reload, boss HP.`,ko:`라벨 달린 진행 바 — 체력, 스태미나, 재장전, 보스 HP.`},{en:`Child of HudLayer. Drive value/max from behaviors; the fill animates and turns lowColor under lowThreshold (default 30%). width/height/color/background style it; label prefixes a small caption.`,ko:`HudLayer의 자식. 비헤이비어에서 value/max를 갱신하면 채움이 애니메이션되고 lowThreshold(기본 30%) 아래로 떨어지면 lowColor로 바뀝니다. width/height/color/background로 스타일, label로 작은 캡션을 붙입니다.`}),Q(`UiBanner`,{en:`Center-screen announcements with fade and a queue — "WAVE 2", "YOU DIED".`,ko:`페이드·큐가 있는 중앙 공지 — "WAVE 2", "YOU DIED".`},{en:`Child of HudLayer. Call show('WAVE 2', { color, seconds }) from behaviors; messages queue and fade in/out. seconds 0 = sticky until the next show(). clear() drops everything. Emits bannerShown(text).`,ko:`HudLayer의 자식. 비헤이비어에서 show('WAVE 2', { color, seconds })를 호출하면 메시지가 큐에 쌓여 페이드 인/아웃됩니다. seconds 0이면 다음 show()까지 고정, clear()로 전부 제거. bannerShown(text) 시그널을 냅니다.`}),Q(`UiButton`,{en:`A clickable HUD button — menus, START screens, dialog choices.`,ko:`클릭 가능한 HUD 버튼 — 메뉴, 시작 화면, 대화 선택지.`},{en:`Child of HudLayer. Set text/size/color/background; disabled greys it out. Emits the 'pressed' signal (behaviors: node.on('pressed', ...)); press() triggers it programmatically (gamepad menus, tests).`,ko:`HudLayer의 자식. text/size/color/background를 설정하고 disabled로 비활성화합니다. 'pressed' 시그널을 내며(비헤이비어에서 node.on('pressed', ...)), press()로 코드에서도 누를 수 있습니다(게임패드 메뉴, 테스트).`}),Q(`UiPanel`,{en:`A box that holds other widgets — the thing a menu, options screen or inventory actually is.`,ko:`다른 위젯을 담는 상자 — 메뉴·설정 화면·인벤토리가 실제로 이것입니다.`},{en:`Child of HudLayer. Widgets under it mount INSIDE it, so tree structure becomes screen structure; panels nest. layout column|row|grid with columns (an inventory is a grid panel, one child per slot), plus gap/padding/background/radius/width/height/border. width or height 0 = size to the contents.`,ko:`HudLayer의 자식. 그 아래 위젯들이 이 안에 마운트되어 트리 구조가 화면 구조가 됩니다(중첩 가능). layout은 column|row|grid이고 columns와 함께 씁니다(인벤토리 = grid 패널, 슬롯당 자식 하나). gap/padding/background/radius/width/height/border 지원. width·height가 0이면 내용에 맞춰집니다.`}),Q(`UiImage`,{en:`A picture in the HUD — item icons, portraits, a logo.`,ko:`HUD 안의 그림 — 아이템 아이콘, 초상화, 로고.`},{en:`src takes a url or a $assetKey (declare the icon once like any other asset). fit contain|cover|fill; tint multiplies through the picture, which is how an unaffordable item greys out in one prop; opacity for disabled states.`,ko:`src는 url 또는 $assetKey(아이콘도 다른 에셋처럼 한 번만 선언). fit은 contain|cover|fill, tint는 그림에 곱해져서 살 수 없는 아이템을 프롭 하나로 회색 처리합니다. opacity로 비활성 표현.`}),Q(`UiSlider`,{en:`A value the player sets — volume, sensitivity, difficulty.`,ko:`플레이어가 조절하는 값 — 볼륨, 감도, 난이도.`},{en:`Emits changed(value). label/value/min/max/step/width/color. Setting .value from a behavior updates the control WITHOUT re-emitting, so restoring a saved setting does not fire the handler that saved it.`,ko:`changed(value) 시그널. label/value/min/max/step/width/color. 비헤이비어에서 .value를 설정하면 컨트롤만 갱신되고 changed는 다시 발생하지 않습니다 — 저장된 설정을 복원할 때 저장 핸들러가 다시 도는 것을 막습니다.`}),Q(`UiToggle`,{en:`An on/off switch — mute, invert-Y, fullscreen.`,ko:`켜기/끄기 스위치 — 음소거, Y축 반전, 전체화면.`},{en:`Emits changed(boolean). label/value. Same no-re-emit rule as UiSlider when set from code.`,ko:`changed(boolean) 시그널. label/value. 코드에서 설정할 때 재발생하지 않는 규칙은 UiSlider와 같습니다.`}),Q(`UiLanguageSelect`,{en:`The language picker, already wired.`,ko:`이미 연결된 언어 선택기.`},{en:`Options are the locales the scene declares in "strings", each labeled with its own endonym. Picking one switches the game live and persists it. English is the base: any key a locale omits falls back to it, on purpose.`,ko:`옵션은 씬의 "strings"가 선언한 로케일이며, 각 언어의 자기 이름으로 표시됩니다. 선택하면 즉시 바뀌고 저장됩니다. 영어가 기준이라 로케일이 빠뜨린 키는 의도적으로 영어로 표시됩니다.`}),Q(`UiSelect`,{en:`One of several — quality, resolution, language.`,ko:`여러 개 중 하나 — 품질, 해상도, 언어.`},{en:`options is a comma-separated list ("low,medium,high"); value is the current one. Emits changed(value).`,ko:`options는 쉼표로 구분된 목록("low,medium,high"), value가 현재 선택입니다. changed(value) 시그널.`}),Q(`UiDialogue`,{en:`A typewriter dialogue box with a queue and choice buttons — the RPG conversation layer.`,ko:`타자기 효과·큐·선택지 버튼을 갖춘 대화창 — RPG 대화 레이어.`},{en:`Child of HudLayer (anchor bottom by default). say(speaker, text, choices?) queues lines; clicking (or advance()) reveals then advances; choice lines wait for choose(i). Signals: lineShown(text), choiceMade(index), dialogueFinished. charsPerSecond 0 = instant. Check .active to pause player input during conversations.`,ko:`HudLayer의 자식(기본 anchor bottom). say(화자, 텍스트, 선택지?)로 줄을 큐에 넣고, 클릭(또는 advance())이 전체 공개→다음 줄로 진행하며, 선택지 줄은 choose(i)를 기다립니다. 시그널: lineShown(text), choiceMade(index), dialogueFinished. charsPerSecond 0이면 즉시 표시. 대화 중 플레이어 입력을 멈추려면 .active를 확인하세요.`}),Q(`AudioPlayer`,{en:`Plays a sound: zero-asset procedural SFX, BGM loops, or one-shot effects.`,ko:`소리 재생 — 무에셋 절차적 효과음, 배경음 루프, 단발 효과음.`},{en:`Set preset (coin/jump/hurt/explosion/…) for an instant zero-asset SFX (pitch/seed vary it), or leave it "custom" and set src (URL or "$assetKey"). volume 0..1; bus routes through engine.audio (sfx|music) for global volume/mute; loop for music; autoplay starts on ready (browsers may hold it until the first user gesture). Call play()/stop() from game code. Dimension-free — 2D and 3D alike.`,ko:`preset(coin/jump/hurt/explosion/…)을 설정하면 즉시 무에셋 효과음이 납니다(pitch·seed로 변형). 아니면 "custom"으로 두고 src(URL 또는 "$에셋키")를 쓰세요. volume은 0..1, bus는 engine.audio(sfx|music)를 통해 전역 볼륨/음소거에 연결, 음악은 loop, autoplay는 준비되면 재생합니다(브라우저가 첫 입력까지 보류 가능). 게임 코드에서 play()/stop()을 부르세요. 2D·3D 어디서나 동작합니다.`})]},{id:`2d`,label:{en:`2D`,ko:`2D`},intro:{en:`The 2D world is y-down pixels: 1 unit = 1 px, (0,0) top-left, rotation in clockwise degrees. Rendering needs a current Camera2D.`,ko:`2D 세계는 y-아래 픽셀 좌표입니다: 1유닛=1px, (0,0)은 좌상단, 회전은 시계방향 도(degree). 렌더링에는 current 카메라(Camera2D)가 필요합니다.`},nodes:[Q(`Node2D`,{en:`The 2D transform container (position/rotation/scale).`,ko:`2D 변환 컨테이너(position/rotation/scale).`},{en:`Children inherit its transform — move the parent, everything follows. renderOrder orders drawing; visible hides the subtree.`,ko:`자식은 변환을 상속합니다 — 부모를 움직이면 전부 따라옵니다. renderOrder로 그리기 순서를, visible로 서브트리 표시를 제어합니다.`}),Q(`Sprite2D`,{en:`A textured quad.`,ko:`텍스처 사각형(스프라이트).`},{en:`texture is "$assetKey" from the scene assets. anchor [0.5,0.5] centers; flipX/flipY mirror; tint multiplies color; opacity fades. Size comes from the texture × scale.`,ko:`texture는 씬 에셋의 "$키"입니다. anchor [0.5,0.5]면 중앙 기준, flipX/flipY로 반전, tint로 색 곱, opacity로 투명도. 크기는 텍스처 × scale로 정해집니다.`}),Q(`ColorRect2D`,{en:`A flat colored rectangle — no texture needed.`,ko:`단색 사각형 — 텍스처 불필요.`},{en:`size [w,h] px, color, opacity, anchor. Backgrounds, platforms, walls, UI panels, generated-level tiles (maze2d/dungeon2d emit these) — blocky art without any asset.`,ko:`size [w,h] px, color, opacity, anchor. 배경·플랫폼·벽·UI 패널·생성 레벨 타일(maze2d/dungeon2d가 이걸 만듭니다) — 에셋 없이 만드는 블록 그래픽입니다.`}),Q(`TileMap2D`,{en:`A whole tile level as ONE node — grid render + merged static colliders.`,ko:`타일 레벨 전체를 노드 하나로 — 그리드 렌더 + 병합된 정적 콜라이더.`},{en:`Author cells as rows of characters: "." / space = empty, digits 0-9 = atlas tile index, other chars map through legend ({"G": 12}). texture is a "$atlas" asset read left-to-right top-to-bottom in tileSize squares (columns: 0 derives from the texture width). Tile indices listed in solid become static colliders, greedy-merged into a few rectangles. Cell (0,0) hangs its top-left on the node origin.`,ko:`cells를 문자 행으로 작성합니다: "."/공백 = 빈 칸, 숫자 0-9 = 아틀라스 타일 번호, 그 외 문자는 legend({"G": 12})로 매핑. texture는 tileSize 정사각형을 좌→우, 상→하로 읽는 "$아틀라스" 에셋입니다(columns: 0이면 텍스처 폭에서 유도). solid에 나열된 타일 번호는 정적 콜라이더가 되며 소수의 직사각형으로 탐욕 병합됩니다. (0,0) 칸의 좌상단이 노드 원점에 걸립니다.`}),Q(`AnimatedSprite2D`,{en:`Spritesheet animation player.`,ko:`스프라이트시트 애니메이션 플레이어.`},{en:`Point sheet at a "$sheet" asset, define animations as named frame ranges with fps/loop in JSON, set autoplay. Emits animationFinished(name) for one-shot chains.`,ko:`sheet에 "$시트" 에셋을 연결하고, JSON에 fps/loop를 가진 이름별 프레임 구간으로 animations를 정의한 뒤 autoplay를 지정하세요. 단발 애니메이션 연결을 위해 animationFinished(name)를 발산합니다.`}),Q(`Camera2D`,{en:`The 2D view: follow, zoom, limits.`,ko:`2D 시점 — 추적·줌·경계.`},{en:`position is the view CENTER. follow tracks a node path with smoothing (0..1, higher = snappier). limits [minX,minY,maxX,maxY] clamps the view inside a world region. current: true makes it THE camera.`,ko:`position은 화면의 중심입니다. follow가 노드 경로를 smoothing(0..1, 높을수록 빠릿)으로 추적합니다. limits [minX,minY,maxX,maxY]가 시점을 월드 영역 안에 가둡니다. current: true인 카메라가 실제 시점이 됩니다.`}),Q(`Particles2D`,{en:`A 2D particle emitter (fire, sparks, smoke…).`,ko:`2D 파티클 이미터(불·스파크·연기…).`},{en:`Start from a preset (fire/smoke/sparks/…) then override any prop: rate, lifetime/speed ranges, direction + spread, gravity, size/color/alpha start→end, additive blend. burst > 0 with emitting: false makes a one-shot that emits finished. Animates LIVE in this editor.`,ko:`preset(fire/smoke/sparks/…)에서 시작해 어떤 prop이든 덮어쓰세요: rate, lifetime/speed 구간, direction+spread, gravity, size/color/alpha 시작→끝, additive blend. emitting: false에 burst > 0이면 단발 발사 후 finished를 발산합니다. 이 에디터에서 라이브로 움직입니다.`}),Q(`Label`,{en:`Text rendered to a quad.`,ko:`텍스트를 그리는 노드.`},{en:`text/fontSize/color/font/align — rendered via CanvasTexture, so any system font string works. Inside a UILayer it pins to the screen (HUD).`,ko:`text/fontSize/color/font/align — CanvasTexture로 그려져 시스템 폰트 문자열을 그대로 쓸 수 있습니다. UILayer 아래에 두면 화면에 고정됩니다(HUD).`}),Q(`UILayer`,{en:`A screen-space subtree (HUD).`,ko:`화면 고정 서브트리(HUD).`},{en:`Everything under it ignores the camera: positions are screen pixels from the top-left. Score counters, prompts, menus go here.`,ko:`이 아래의 모든 것은 카메라를 무시합니다 — 좌상단 기준 화면 픽셀 좌표입니다. 점수, 안내 문구, 메뉴를 여기에 둡니다.`})]},{id:`2d-physics`,label:{en:`2D Physics`,ko:`2D 물리`},intro:{en:`Rapier-backed. Colliders are PROPS ({shape, …}) — the green dashed wireframes in this editor. Physics runs when the game calls enablePhysics2D (and in play mode). Gravity lives on the scene row.`,ko:`Rapier 기반입니다. 콜라이더는 prop({shape, …})이며 에디터의 초록 점선이 그것입니다. 물리는 게임이 enablePhysics2D를 부를 때(그리고 플레이 모드에서) 돌고, 중력은 씬 행에 있습니다.`},nodes:[Q(`StaticBody2D`,{en:`Immovable collision: ground, walls, platforms.`,ko:`움직이지 않는 충돌체 — 바닥·벽·플랫폼.`},{en:`Other bodies collide with it; it never moves. Cheapest body type — use it for all level geometry.`,ko:`다른 바디가 부딪히지만 자신은 절대 움직이지 않습니다. 가장 저렴한 바디 — 레벨 지형 전부에 쓰세요.`}),Q(`RigidBody2D`,{en:`Fully simulated: falls, bounces, pushes.`,ko:`완전 시뮬레이션 — 떨어지고 튕기고 밀립니다.`},{en:`Gravity and collisions drive it. Set linearVelocity to launch. For player characters prefer CharacterBody2D (direct control).`,ko:`중력과 충돌이 움직임을 결정합니다. linearVelocity로 발사하세요. 플레이어 캐릭터에는 직접 제어가 가능한 CharacterBody2D를 권합니다.`}),Q(`CharacterBody2D`,{en:`Kinematic character: you set velocity, it slides.`,ko:`키네마틱 캐릭터 — 속도를 주면 미끄러지듯 이동.`},{en:`moveAndSlide() resolves collisions without physics pushing back; isOnFloor() gates jumps. Sensors (Area2D) do not block it but still fire triggers.`,ko:`moveAndSlide()가 밀려나지 않으면서 충돌을 처리하고 isOnFloor()로 점프를 판정합니다. 센서(Area2D)는 길을 막지 않으면서 트리거를 발사합니다.`}),Q(`Area2D`,{en:`A sensor: overlap triggers, no collision response.`,ko:`센서 — 겹침 감지만, 충돌 반응 없음.`},{en:`Fires triggerEnter(other)/triggerExit(other). Coins, checkpoints, damage zones. Filter with other.isInGroup("player").`,ko:`triggerEnter(other)/triggerExit(other)를 발산합니다. 코인·체크포인트·데미지 존에 쓰고, other.isInGroup("player")로 거릅니다.`}),Q(`CharacterController2D`,{en:`Zero-code platformer/top-down movement.`,ko:`코드 없는 플랫포머/탑다운 이동.`},{en:`Put it UNDER a CharacterBody2D. mode "platformer" (gravity + jump via jumpAction) or "topDown" (free 2-axis). Reads the scene input map actions (moveAction/jumpAction). maxSpeed/jumpHeight are intent-level numbers.`,ko:`CharacterBody2D의 자식으로 두세요. mode는 "platformer"(중력+jumpAction 점프) 또는 "topDown"(자유 2축)이며 씬 입력 맵의 액션(moveAction/jumpAction)을 읽습니다. maxSpeed/jumpHeight는 의도 그대로의 숫자입니다.`}),Q(`Joint2D`,{en:`A physics joint linking its parent body to a target body — weld, hinge, rope, spring.`,ko:`부모 바디와 대상 바디를 잇는 물리 조인트 — 용접, 힌지, 로프, 스프링.`},{en:`Child of body A (a physics body); "target" is a node path to body B. type: fixed (rigid weld) / revolute (pin at the anchors) / rope (caps anchor distance at length px; 0 = measured at creation) / spring (pulls toward length with stiffness/damping). anchor/targetAnchor are LOCAL px offsets.`,ko:`바디 A(물리 바디)의 자식으로 두고 "target"에 바디 B의 노드 경로를 줍니다. type: fixed(강체 용접) / revolute(앵커 핀 힌지) / rope(앵커 간 거리를 length px로 제한, 0이면 생성 시 실측) / spring(stiffness/damping으로 length를 향해 당김). anchor/targetAnchor는 로컬 px 오프셋.`})]},{id:`3d`,label:{en:`3D`,ko:`3D`},intro:{en:`Meters, y-up, rotations in degrees. Standard materials need LIGHT — add a DirectionalLight3D or scene ambient, or you get silhouettes.`,ko:`미터 단위, y-위, 회전은 도(degree)입니다. 표준 머티리얼은 빛이 필요합니다 — DirectionalLight3D나 씬 ambient가 없으면 실루엣만 보입니다.`},nodes:[Q(`Node3D`,{en:`The 3D transform container.`,ko:`3D 변환 컨테이너.`},{en:`position [x,y,z] in meters, rotation [x,y,z] in degrees, scale per axis. Children inherit.`,ko:`position [x,y,z] 미터, rotation [x,y,z] 도, scale은 축별. 자식이 상속합니다.`}),Q(`MeshInstance3D`,{en:`A primitive mesh + material.`,ko:`프리미티브 메시 + 머티리얼.`},{en:`mesh: box/sphere/plane/cylinder…, size per primitive, material {color, roughness, metalness, emissive, emissiveIntensity, wireframe, map, normalMap, repeat} (this editor gives it swatches, sliders, texture-URL fields, and a repeat [u,v] tiling vector). map/normalMap are texture URLs; repeat only takes effect with a map. castShadow/receiveShadow per node.`,ko:`mesh: box/sphere/plane/cylinder…, 프리미티브별 size, material {color, roughness, metalness, emissive, emissiveIntensity, wireframe, map, normalMap, repeat}(에디터가 스와치·슬라이더·텍스처 URL 입력·repeat [u,v] 타일링 벡터 제공). map/normalMap은 텍스처 URL, repeat는 map이 있을 때만 적용. 그림자는 castShadow/receiveShadow.`}),Q(`LoftMesh3D`,{en:`A smooth swept hull (loft).`,ko:`부드러운 스윕 선체(로프트).`},{en:`sections: ≥2 cross-section stations {z, width, height, y, corner 0..1} interpolated into ONE smooth curved surface — vehicle bodies, glass canopies, boat hulls. slices/smooth control tessellation. Same material as MeshInstance3D minus textures (no UVs); pair clearcoat paint or high-envMapIntensity glass with the smooth normals for the automotive look.`,ko:`sections: 단면 스테이션 {z, width, height, y, corner 0..1} 2개 이상을 보간해 하나의 매끈한 곡면을 만듭니다 — 차체, 유리 캐노피, 선체. slices/smooth로 테셀레이션 조절. material은 MeshInstance3D와 동일하되 텍스처 제외(UV 없음). clearcoat 도장이나 높은 envMapIntensity 유리를 곡면 법선과 조합하면 자동차 룩이 납니다.`}),Q(`ModelInstance3D`,{en:`A GLB/glTF/VRM model file.`,ko:`GLB/glTF/VRM 모델 파일.`},{en:'model: "$assetKey" or URL. targetHeight scales the model to stand N units tall (run `npx incanto-model file.glb` to read its real size first). animation plays an embedded clip name OR an "$animation" asset — Mixamo clips retarget onto VRM humanoids automatically. One node per VRM asset (the avatar runtime mounts live). To make it SOLID, park it under a body with collider {shape:"auto"}: the collider is built from the model\'s own triangles — a triangle mesh on a static body (keeps its holes, so you walk through an archway) and a convex hull on a moving one.',ko:'model은 "$에셋키" 또는 URL입니다. targetHeight가 모델을 N유닛 높이로 맞춥니다(먼저 `npx incanto-model 파일.glb`로 실제 크기를 확인하세요). animation은 내장 클립 이름 또는 "$애니메이션" 에셋을 재생하며, Mixamo 클립은 VRM 휴머노이드에 자동 리타게팅됩니다. VRM 에셋은 노드 하나만 쓸 수 있습니다(아바타 런타임이 라이브로 마운트됨). 단단하게 만들려면 collider {shape:"auto"}인 바디 아래에 두세요 — 모델 자신의 삼각형에서 콜라이더가 만들어집니다(정적 바디는 트라이메시라 아치 구멍도 그대로, 움직이는 바디는 볼록 껍질).'}),Q(`Sprite3D`,{en:`A 2D image as a camera-facing billboard (the 2.5D look).`,ko:`카메라를 향하는 2D 빌보드 스프라이트(2.5D 룩).`},{en:`A textured quad that turns to face the camera inside the 3D world (Octopath / Don't Starve / MapleStory-in-3D). texture is an image URL; size is [w,h] in METERS. billboard: "y" stays upright with a screen-aligned yaw — off-center sprites never roll (characters/props), "full" faces it completely (items/FX), "none" is fixed to the node rotation. anchor [0.5,0] plants the feet on the ground. pixelArt nearest-filters for crisp pixels; alphaTest is a hard cutout that depth-sorts against 3D geometry (a tree occludes it); flipX mirrors left/right; tint/opacity recolor.`,ko:`3D 월드 안에서 카메라를 향해 도는 텍스처 쿼드(Octopath/Don't Starve, 3D 속 메이플스토리 룩). texture는 이미지 URL, size는 [너비,높이] 미터. billboard: "y"는 세로로 선 채 카메라 방향과 정렬된 yaw — 화면 가장자리에서도 기울지 않음(캐릭터/사물), "full"은 완전히 향함(아이템/FX), "none"은 노드 회전에 고정. anchor [0.5,0]은 발을 바닥에 둡니다. pixelArt는 nearest 필터로 픽셀을 또렷하게, alphaTest는 3D 지형과 깊이정렬되는 하드 컷아웃(나무가 가림), flipX는 좌우 반전, tint/opacity로 색·투명도.`}),Q(`AnimatedSprite3D`,{en:`A billboard sprite that plays spritesheet animations.`,ko:`스프라이트시트 애니를 재생하는 빌보드 스프라이트.`},{en:`Everything Sprite3D does, plus frame animation. sheet is a spritesheet image URL whose cells are frameWidth×frameHeight; animations maps a name to {frames, fps, loop} where frames is an inclusive [start,end] range or an explicit list; autoplay starts one on load. Game code calls play("walk") / stop(); a non-looping clip clamps on its last frame and emits animationFinished(name) — chain attack→idle from it.`,ko:`Sprite3D의 모든 기능 + 프레임 애니. sheet는 frameWidth×frameHeight 칸을 가진 스프라이트시트 URL, animations는 이름→{frames, fps, loop}(frames는 포함 [시작,끝] 범위 또는 명시 목록), autoplay는 로드 시 하나를 시작. 게임 코드에서 play("walk")/stop() 호출, 비반복 클립은 마지막 프레임에 머물며 animationFinished(name)를 emit(attack→idle 연결).`}),Q(`Billboard3D`,{en:`A group that turns toward the camera — children follow.`,ko:`카메라를 향해 도는 그룹 — 자식들이 함께 회전.`},{en:`A transform container that orients itself toward the camera every frame; children inherit the rotation, so hang world-space UI under it — HP bars, markers, floating icons (text is a canvas-rendered texture on a child Sprite3D). mode: "screen" (default) copies the camera orientation so a child rectangle stays an upright rectangle anywhere on screen (a yaw-only look-at visibly tilts off-center shapes under a pitched camera); "y" stays upright with a screen-aligned yaw (no off-center roll); "none" turns billboarding off. While billboarding, the node's own rotation prop (and the rotate gizmo) is overwritten every frame — switch to "none" to pose children, then switch back. Unlike Sprite3D (a textured quad that spins only its own image), Billboard3D rotates the whole group.`,ko:`매 프레임 카메라를 향해 자신을 회전시키는 변환 컨테이너로, 자식이 회전을 상속합니다 — HP바·마커·아이콘 같은 월드 UI를 자식으로 붙이세요(텍스트는 캔버스로 그린 텍스처를 자식 Sprite3D에). mode: "screen"(기본)은 카메라 자세를 그대로 복사해 자식 직사각형이 화면 어디서든 똑바른 직사각형으로 보입니다(yaw만 도는 look-at은 기울어진 카메라에서 중앙 밖 도형이 눈에 띄게 비스듬해짐); "y"는 세로로 선 채 카메라로 yaw만; "none"은 빌보드 끔. 빌보드 중에는 노드 자신의 rotation(회전 기즈모 포함)이 매 프레임 덮어써집니다 — 자식을 배치할 땐 "none"으로 바꿨다가 되돌리세요. 자기 그림만 도는 Sprite3D(텍스처 쿼드)와 달리 그룹 전체가 회전합니다.`}),Q(`Camera3D`,{en:`The 3D view.`,ko:`3D 시점.`},{en:`Perspective camera; fov in degrees; current: true selects it. Use the editor's "game cam" (0) to preview exactly what it renders.`,ko:`원근 카메라이며 fov는 도 단위, current: true가 실제 시점이 됩니다. 에디터의 "game cam"(0)으로 정확한 렌더 결과를 미리 보세요.`}),Q(`DirectionalLight3D`,{en:`Sun-like light from a direction.`,ko:`태양광 — 방향에서 평행하게.`},{en:`Position sets the direction toward the origin. intensity/color; pair with scene ambient for soft fill.`,ko:`위치가 원점을 향한 방향을 정합니다. intensity/color를 조절하고 부드러운 채움광은 씬 ambient와 함께 쓰세요.`}),Q(`OmniLight3D`,{en:`A point light radiating everywhere.`,ko:`점광 — 사방으로 퍼지는 빛.`},{en:`Lamps, torches, glows. range limits reach; intensity/color shape the falloff.`,ko:`램프·횃불·발광체. range로 도달 거리를, intensity/color로 감쇠를 만듭니다.`}),Q(`Particles3D`,{en:`A 3D particle emitter (fire, magic, weather…).`,ko:`3D 파티클 이미터(불·마법·날씨…).`},{en:`The same preset + override model as Particles2D, in meters with [x,y,z] gravity. Camera-facing billboard quads, instanced — hundreds are cheap. Animates LIVE in this editor.`,ko:`Particles2D와 같은 preset+덮어쓰기 모델을 미터 단위와 [x,y,z] 중력으로. 카메라를 향하는 빌보드 쿼드를 인스턴싱해 수백 개도 가볍습니다. 이 에디터에서 라이브로 움직입니다.`}),Q(`Terrain3D`,{en:`Procedural heightfield terrain with biome texture splatting.`,ko:`바이옴 텍스처 스플래팅이 적용된 절차적 하이트필드 지형.`},{en:`Seeded simplex hills displaced once on the CPU; theme (island/alpine/plains/desert/custom) picks the 4 blended biome textures by height and slope. heightAt(x,z) answers the surface height anywhere. For physics, parent it under a StaticBody3D with collider {shape:'heightfield'}.`,ko:`시드 기반 심플렉스 언덕을 CPU에서 한 번 변위합니다. theme(island/alpine/plains/desert/custom)이 높이·경사로 블렌딩되는 바이옴 텍스처 4장을 고릅니다. heightAt(x,z)로 어디서든 지표 높이를 얻고, 물리는 StaticBody3D 아래에 두고 collider {shape:'heightfield'}를 쓰세요.`}),Q(`Water3D`,{en:`A shader-water surface with splash signals.`,ko:`스플래시 신호를 내는 셰이더 물 표면.`},{en:`size [w,d] meters on XZ. quality 'fancy' (default) = FBM wave shader with a trough/surface/peak ramp (colors), CubeCamera reflections (reflection/reflectionInterval) and opt-in shoreline foam; 'simple' = the cheap sine material (color). Bodies crossing the surface emit entered/exited(body) and raise ripples (interaction). Volumetric gameplay still wants an Area3D. Waves animate LIVE in this editor.`,ko:`XZ 평면에 size [w,d] 미터. quality 'fancy'(기본)는 FBM 파도 셰이더 — trough/surface/peak 램프(colors), CubeCamera 반사(reflection/reflectionInterval), 옵트인 해안 거품(foam). 'simple'은 저사양용 사인파 머티리얼(color). 바디가 수면을 지나면 entered/exited(body) 신호와 물결이 일어납니다(interaction). 부피 기반 게임플레이엔 여전히 Area3D를 쓰세요. 이 에디터에서 파도가 라이브로 움직입니다.`}),Q(`River3D`,{en:`Running water derived from a path and the ground under it.`,ko:`경로와 그 아래 지형에서 유도되는 흐르는 물.`},{en:`Author a centerline path [[x,z],…] plus width/widths (a profile source→mouth) and depth; the node samples the Terrain3D underneath and derives the rest. It CARVES ITS OWN BED by default (carve): a trench per reach that heightAt, the collider, the splat and draped vegetation all see, with a floor that only ever falls, so a path over a rise digs through instead of burying the water. Its surface is then FITTED to that ground — never higher than the lowest rim holding it, ending where the ground comes up to meet it (asymmetric on a sloping reach), lying down as a film where a bank has fallen away, so a river can never hang in the air. Plus a current that speeds up where the channel pinches or tips (flowSpeed is the mean) and whitewater from grade, bank shear and thinning column. Boulders in the channel are answered without wiring: the node finds MeshInstance3D/InstancedMesh3D footprints standing in the water column and the current piles a white cushion on the upstream face, tears a wake downstream and bends its sheen around them. A trench thinner than a terrain cell cannot survive the grid: a 2.4 m creek on a 260 m map wants Terrain3D resolution 256. flowForce drags bodies downstream (drag, never thrust) and sampleAt(x,z) answers where a world point sits in the channel. No extra render passes — a map can carry a dozen.`,ko:`중심선 path [[x,z],…]와 width/widths(상류→하류 프로파일), depth만 주면 나머지는 아래 Terrain3D를 샘플링해 유도합니다. 기본적으로 강이 자기 바닥을 직접 팝니다(carve) — 구간마다 하나씩 도랑을 내고, heightAt·콜라이더·스플랫·식생 드레이프가 모두 그 지형을 봅니다. 파낸 바닥은 계속 내려가기만 하므로 경로가 언덕을 넘어도 물이 묻히지 않고 뚫고 흐릅니다. 그리고 수면은 그 지형에 맞춰집니다 — 자기를 담는 가장 낮은 둑보다 높아질 수 없고, 지면이 올라오는 지점에서 끝나며(비스듬한 구간에서는 좌우 폭이 다릅니다), 둑이 아예 없는 쪽에서는 경사면에 얇은 막처럼 누워버립니다. 그래서 강이 공중에 뜨는 일이 없습니다. 여기에 폭이 좁아지거나 경사가 급해지면 빨라지는 유속(flowSpeed는 평균)과 경사·둑 전단·얕아지는 수심에서 나오는 흰 물살이 더해집니다. 수로에 놓인 바위도 배선 없이 반응합니다 — MeshInstance3D/InstancedMesh3D 중 실제로 물기둥과 겹치는 것을 찾아, 상류면에 흰 물이 쌓이고 하류로 후류가 찢어지며 수면 광택이 바위를 돌아 휩니다. 지형 셀보다 얇은 도랑은 그리드에서 살아남지 못합니다 — 260 m 맵의 2.4 m 개울이라면 Terrain3D resolution 256이 필요합니다. flowForce가 바디를 하류로 끌고(밀지 않고 끌어당김), sampleAt(x,z)로 월드 좌표가 수로 어디에 있는지 알 수 있습니다. 추가 렌더 패스가 없어 한 맵에 여러 개를 둘 수 있습니다.`}),Q(`WaterCutout3D`,{en:`Marks its parent as something that holds the water back — a dry hull, a diving bell, a well.`,ko:`부모 오브젝트가 물을 막는다고 표시 — 마른 선실, 잠수종, 우물.`},{en:`Water is ONE surface and knows nothing about interiors, so an open hull floating on it fills with sea every time a crest clears its floor — freeboard alone can never promise otherwise. This node names the geometry that keeps the water out: it MUST be a CHILD of that thing (a hull, a bell, a dock's well, a cave mouth), and the water re-draws the part of it inside the box into its depth pre-pass, then hides behind it exactly as it hides behind any solid object. Nothing is ever cut OUT of the water, so a hole in open sea is impossible: overshoot the box and more of that hull holds water back, undershoot and water stands in the bow. size is the box extent in meters; enabled toggles it live (a scuttled hull starts letting the sea in). Four per water surface; needs quality fancy.`,ko:`물은 하나의 표면이라 '안쪽'이라는 개념이 없습니다. 그래서 뚜껑 없는 배를 띄우면 파도 마루가 바닥을 넘을 때마다 배 안에 바다가 차 보이고, 건현(freeboard)만으로는 절대 막을 수 없습니다. 이 노드는 '물을 막는 지오메트리'를 지정합니다. 반드시 그 물체(선체·잠수종·부두 우물·동굴 입구)의 자식이어야 하며, 물이 상자 안쪽의 그 지오메트리를 자기 깊이 프리패스에 다시 그린 뒤 평범한 불투명 물체 뒤에 숨듯 그 뒤로 숨습니다. 물에서 무언가를 '도려내지' 않으므로 열린 바다에 구멍이 나는 일은 원리적으로 불가능합니다 — 상자가 크면 그 배가 물을 더 많이 막을 뿐이고, 작으면 뱃머리에 물이 남습니다. size는 미터 단위 상자 크기, enabled는 런타임 토글(침수 시작 연출). 수면 하나당 4개, quality fancy 필요.`}),Q(`Foliage3D`,{en:`An instanced grass/flower carpet that sways.`,ko:`바람에 흔들리는 인스턴스 풀밭/꽃밭. `},{en:`kind grass/flowers/reeds scattered over area [w,d] at density (capped by maxInstances — instanced, tens of thousands of blades cheap). Grass defaults to style 'mesh': every instance is a REAL tapered blade curved by a bezier vertex shader — Voronoi-clump hue/lean, groundColor soil roots (match the terrain), sunDirection tip sheen, 2-octave rolling wind, fadeStart/fadeEnd camera LOD, and (interaction) blade-bending around moving bodies. style 'blades' keeps the 8-SDF-blades-per-quad ported shader, 'simple' the legacy quads. colorA/colorB tint bottom→top, sway sets the wind, seed makes the scatter reproducible. avoidWater (on by default) keeps blades OUT of standing and running water — a creek cutting its bed through the field gets banks, not blades waving in the current; turn it off for reeds and paddy fields.`,ko:`kind grass/flowers/reeds를 area [w,d]에 density로 흩뿌립니다(maxInstances 상한 — 인스턴싱이라 수만 가닥도 가벼움). grass는 기본 style 'mesh': 인스턴스 하나하나가 베지어 버텍스 셰이더로 휘어지는 진짜 잎 메시 — 보로노이 클럼프 색/기울기, groundColor 흙빛 뿌리(지형 색에 맞추세요), sunDirection 잎끝 광택, 2옥타브 굽이치는 바람, fadeStart/fadeEnd 카메라 LOD, (interaction) 움직이는 바디 주변 풀 눕힘까지. style 'blades'는 쿼드당 8가닥 SDF 셰이더, 'simple'은 기존 쿼드 룩. colorA/colorB가 아래→위 색, sway가 바람 세기, seed가 배치를 재현 가능하게 합니다. avoidWater(기본 켜짐)는 고인 물·흐르는 물 안에 잎을 심지 않습니다 — 개울이 들판을 가르고 지나가면 물살 속에 풀이 서 있는 대신 둑이 생깁니다. 갈대·논은 꺼서 쓰세요.`}),Q(`Flowers3D`,{en:`Instanced flower PLANTS — stems, leaves, multi-petal heads.`,ko:`인스턴스 꽃밭 — 줄기·잎·여러 장 꽃잎의 진짜 꽃 식물.`},{en:`Real procedural flower plants (curved stem, 2-3 leaves, a 5-8 petal head around a contrasting center disc, 1-3 blooms per plant) scattered over area [w,d]. density is the vibe dial: 'lush' / 'sparse' (default) / 'none', or a number in plants/m². varieties picks a subset of daisy/cosmos/bellflower ([] = all three); palette sets the head colors ([] = white/yellow/violet). clustering 0-1 gathers plants into Voronoi patches that bloom one species + color together; sway bobs the heads in a gentle wind; seed makes the field reproducible. ≤3 varieties → ≤6 draw calls. avoidWater (on by default) keeps plants out of standing and running water — a meadow a stream runs through has a bank of flowers, not flowers in the current.`,ko:`진짜 프로시저럴 꽃 식물(휘어진 줄기, 잎 2-3장, 대비되는 중심 원반을 두른 꽃잎 5-8장 머리, 포기당 꽃 1-3송이)을 area [w,d]에 흩뿌립니다. density가 바이브 다이얼: 'lush'(풍성하게) / 'sparse'(듬성듬성, 기본) / 'none'(없게) 또는 m²당 개수. varieties는 daisy/cosmos/bellflower 부분집합([] = 셋 다), palette는 꽃 색([] = 흰/노랑/보라). clustering 0-1이 보로노이 패치로 모아 한 패치가 같은 종·같은 색으로 피고, sway가 바람에 머리를 끄덕이며, seed로 배치가 재현됩니다. 품종 ≤3 → 드로우 콜 ≤6. avoidWater(기본 켜짐)는 고인 물·흐르는 물 안에 꽃을 심지 않습니다 — 시내가 지나는 들판에는 물살 속 꽃이 아니라 꽃이 핀 둑이 생깁니다.`}),Q(`Tree3D`,{en:`Procedural tree groves — real branching trunks, textured leaves, one node per forest.`,ko:`프로시저럴 나무 숲 — 진짜 가지가 뻗은 줄기와 텍스처 잎, 숲 하나가 노드 하나.`},{en:`type conifer/broadleaf/dead picks the recipe family; tier is the cost dial: simple = primitive low-poly, medium = light forest presets (≤3k tris/tree), high = full ez-tree presets (8–20k, hero trees). count > 1 scatters a forest patch over area [w,d] — up to 3 seed variants, each branches + leaves InstancedMesh (≤6 draw calls); count × tris/tree is budget-checked at load. seed makes every branch and leaf reproducible; height jitters ±20% per instance; leaves sway in a simplex wind.`,ko:`type conifer/broadleaf/dead가 수종을, tier가 비용을 정합니다: simple = 기존 로우폴리, medium = 가벼운 forest 프리셋(나무당 ≤3k tris), high = 풀 ez-tree 프리셋(8–20k, 주인공 나무). count > 1이면 area [w,d]에 숲 패치를 흩뿌립니다 — 시드 변형 최대 3종, 변형마다 가지+잎 InstancedMesh(드로우 콜 ≤6), count × tris는 로드 시 예산 검사. seed로 가지와 잎이 전부 재현되고 height는 인스턴스마다 ±20% 지터링, 잎은 심플렉스 바람에 흔들립니다.`}),Q(`VoxelGrid3D`,{en:`A Minecraft-style block grid in ONE node.`,ko:`마인크래프트식 블록 그리드 — 노드 하나로.`},{en:`voxels is a list of [x,y,z,palette] integer cells (terrain/island generators emit these). Greedy-meshed and instanced — large worlds stay one draw batch. Game code edits blocks via setBlock/getBlock; emits blocksChanged.`,ko:`voxels는 [x,y,z,팔레트] 정수 셀 목록입니다(terrain/island 생성기가 만들어 냅니다). 그리디 메싱+인스턴싱으로 큰 월드도 드로우 배치 하나를 유지합니다. 게임 코드는 setBlock/getBlock으로 수정하고 blocksChanged가 발산됩니다.`})]},{id:`3d-physics`,label:{en:`3D Physics`,ko:`3D 물리`},intro:{en:`Same model as 2D, in meters with y-up gravity ([0,-9.81,0] default). Colliders: box {size}, sphere {radius}, capsule {radius,height}.`,ko:`2D와 같은 모델을 미터·y-위 중력([0,-9.81,0] 기본)으로. 콜라이더는 box {size}, sphere {radius}, capsule {radius,height}.`},nodes:[Q(`StaticBody3D`,{en:`Immovable 3D collision.`,ko:`움직이지 않는 3D 충돌체.`},{en:`Floors, walls, level geometry. collider {shape:"auto"} takes the shape from the MeshInstance3D or ModelInstance3D the body carries as a child, so the blocker can never be bigger or smaller than what the player sees — the fix for hand-typed extents that leave you stopping in mid-air. A GLB becomes a triangle mesh here, holes and all.`,ko:`바닥·벽·레벨 지형. collider {shape:"auto"}는 바디가 자식으로 들고 있는 MeshInstance3D 또는 ModelInstance3D의 생김새를 그대로 씁니다 — 보이는 것보다 크거나 작은 콜라이더가 생길 수 없습니다. 손으로 적은 크기 때문에 허공에서 막히는 문제의 해법입니다. GLB는 여기서 구멍까지 살아있는 트라이메시가 됩니다.`}),Q(`RigidBody3D`,{en:`Simulated 3D body.`,ko:`시뮬레이션되는 3D 바디.`},{en:`Crates, balls, debris — gravity and impacts drive it.`,ko:`상자·공·파편 — 중력과 충격이 움직입니다.`}),Q(`CharacterBody3D`,{en:`Kinematic 3D character.`,ko:`키네마틱 3D 캐릭터.`},{en:`moveAndSlide with up = +y; isOnFloor for jumps.`,ko:`+y를 위로 moveAndSlide, 점프 판정은 isOnFloor.`}),Q(`Area3D`,{en:`3D overlap sensor.`,ko:`3D 겹침 센서.`},{en:`triggerEnter/Exit — pickups, zones, goals.`,ko:`triggerEnter/Exit — 아이템·존·골인 지점.`}),Q(`CharacterController3D`,{en:`Zero-code 3D movement + camera rig.`,ko:`코드 없는 3D 이동 + 카메라 리그.`},{en:`Put it UNDER a CharacterBody3D. view: thirdPerson (orbit + zoom), firstPerson (eyeHeight, mouseLook), sideView or flightView. Reads moveAction/jumpAction/sprintAction from the scene input map; skinPath turns the visual child to face travel. Intent-level numbers: maxSpeed, jumpVelocity, camDistance.`,ko:`CharacterBody3D의 자식으로 두세요. view는 thirdPerson(궤도+줌), firstPerson(eyeHeight, mouseLook), sideView, flightView 중 하나입니다. 씬 입력 맵의 moveAction/jumpAction/sprintAction을 읽고 skinPath의 비주얼 자식을 진행 방향으로 돌립니다. maxSpeed·jumpVelocity·camDistance 같은 의도 수준의 숫자만 만집니다.`}),Q(`BoneLookAt3D`,{en:`Look-at IK for one bone — the head turns toward a target on top of the animation.`,ko:`본 하나의 룩앳 IK — 애니메이션 위에서 머리가 대상을 향해 돌아갑니다.`},{en:`"target" = ModelInstance3D path, "bone" = bone name (default Head), "lookAt" = the node to watch (e.g. "%Player"). Blends in/out smoothly and DISENGAGES beyond maxAngleDeg (no owl necks); weight sets how far it commits. forwardAxis names the bone's facing axis (mixamo heads: +z). Purely visual — headless no-op.`,ko:`"target"에 ModelInstance3D 경로, "bone"에 본 이름(기본 Head), "lookAt"에 바라볼 노드(예: "%Player")를 줍니다. 부드럽게 페이드 인/아웃하고 maxAngleDeg 밖에서는 해제됩니다(목이 돌아가지 않음). weight로 몰입도를 조절하고 forwardAxis는 본의 정면 축입니다(mixamo 머리: +z). 순수 시각 기능 — 헤드리스에서는 no-op.`}),Q(`InstancedMesh3D`,{en:`Hundreds of copies of one mesh in ONE draw call — rocks, posts, crates.`,ko:`메시 하나의 수백 개 복사본을 드로우콜 1개로 — 바위, 말뚝, 상자.`},{en:`Same mesh/size/material surface as MeshInstance3D; "transforms" places the copies — each row [x, y, z, yawDeg?, scale?]. Replace the whole array to update (mutations are not watched). The scattering workhorse for open worlds. collider: {} makes the whole field solid — every row gets its own collider SHAPED LIKE THE MESH (a faceted gem stone collides as that stone's hull, not as a ball tucked inside it), all hanging off one fixed body. A boulder field the player walks straight through is the tell that a world is scenery rather than a place.`,ko:`MeshInstance3D와 같은 mesh/size/material 표면에 "transforms"로 복사본을 배치합니다 — 각 행은 [x, y, z, yawDeg?, scale?]. 갱신은 배열 전체 교체로 하세요(내부 변경은 감지되지 않음). 오픈월드 스캐터링의 주력입니다. collider: {}를 주면 필드 전체가 단단해집니다 — 행마다 메시 생김새 그대로의 콜라이더가 생기고(각진 gem 바위는 안에 박힌 구가 아니라 그 바위 자신의 볼록 껍질로 부딪힙니다), 전부 하나의 고정 바디에 붙습니다. 플레이어가 통과해버리는 바위밭은 그 세계가 배경 그림이라는 신호입니다.`}),Q(`BoneAttachment3D`,{en:`Rides a skeleton bone of an animated model — swords in hands, hats on heads.`,ko:`애니메이션 모델의 스켈레톤 본을 따라다님 — 손에 쥔 검, 머리 위 모자.`},{en:`"target" is a node path to the ModelInstance3D, "bone" the bone name ("RightHand" also matches the Mixamo spellings). Children inherit the live animated transform; this node's own position/rotation become a bone-space offset. Purely visual — headless it stays where its props put it, so keep gameplay checks range-based.`,ko:`"target"에 ModelInstance3D 노드 경로, "bone"에 본 이름을 줍니다("RightHand"는 Mixamo 표기도 자동 매칭). 자식들이 살아있는 애니메이션 트랜스폼을 물려받고, 이 노드의 position/rotation은 본 기준 오프셋이 됩니다. 순수 시각 기능 — 헤드리스에서는 prop 위치에 머무니 게임 판정은 거리 기반으로 유지하세요.`}),Q(`Trail3D`,{en:`A fading world-space ribbon behind the parent — wingtip trails, sword arcs, tyre streaks.`,ko:`부모 뒤로 남는 페이드아웃 월드 리본 — 날개끝 궤적, 검격 궤적, 타이어 자국.`},{en:"Child of the moving node. Records the world position over `seconds` and renders a camera-facing strip that tapers and fades to the tail. width (m), color, opacity, additive for glowing energy trails, minDistance filters jitter. emitting: false stops laying new ribbon while the old tail fades out.",ko:`움직이는 노드의 자식으로 두세요. seconds 동안의 월드 위치를 기록해 꼬리로 갈수록 가늘어지고 투명해지는 카메라 지향 스트립을 그립니다. width(m), color, opacity, 빛나는 에너지 궤적에는 additive, minDistance로 떨림을 걸러냅니다. emitting: false면 새 리본만 멈추고 기존 꼬리는 자연스럽게 사라집니다.`}),Q(`Joint3D`,{en:`A physics joint linking its parent body to a target body — weld, ball joint, rope, spring.`,ko:`부모 바디와 대상 바디를 잇는 물리 조인트 — 용접, 볼 조인트, 로프, 스프링.`},{en:`Child of body A; "target" is a node path to body B. type: fixed (rigid weld) / spherical (ball joint at the anchors) / rope (caps anchor distance at length m; 0 = measured at creation) / spring (pulls toward length with stiffness/damping). anchor/targetAnchor are LOCAL meter offsets.`,ko:`바디 A의 자식으로 두고 "target"에 바디 B의 노드 경로를 줍니다. type: fixed(강체 용접) / spherical(앵커 볼 조인트) / rope(앵커 간 거리를 length m로 제한, 0이면 생성 시 실측) / spring(stiffness/damping으로 length를 향해 당김). anchor/targetAnchor는 로컬 미터 오프셋.`})]},{id:`network`,label:{en:`Network`,ko:`네트워크`},intro:{en:`Multiplayer is transport-agnostic: the engine speaks one NetworkTransport interface (built-in offline Loopback + an @agent8/gameserver adapter). The scene declares replication; one owner node per player broadcasts its sync keys.`,ko:`멀티플레이어는 트랜스포트 불가지론입니다 — 엔진은 NetworkTransport 인터페이스 하나만 사용합니다(내장 오프라인 Loopback + @agent8/gameserver 어댑터). 복제는 씬이 선언하며, 플레이어당 하나의 owner 노드가 sync 키를 송출합니다.`},nodes:[Q(`NetworkSpawner`,{en:`Spawns a registered scene per remote player/entity.`,ko:`원격 플레이어/엔티티마다 등록된 씬을 생성.`},{en:`source "users" mirrors every OTHER account in the room (self skipped); "collection:<id>" mirrors a room collection. Replicated sync patches apply to each instance; position interpolates. Emits spawned/despawned.`,ko:`source "users"는 방의 다른 모든 계정을 미러링하고(자신 제외) "collection:<id>"는 방 컬렉션을 미러링합니다. 복제 sync 패치가 인스턴스에 적용되고 position은 보간됩니다. spawned/despawned를 발산합니다.`})]}],VF=`overview`,HF=null;function UF(){document.querySelector(`#docs`)?.removeAttribute(`hidden`),KF()}function WF(){document.querySelector(`#docs`)?.setAttribute(`hidden`,``)}function GF(){let e=document.querySelector(`#docs`);e&&(e.addEventListener(`pointerdown`,t=>{t.target===e&&WF()}),document.querySelector(`#docs-close`)?.addEventListener(`click`,WF))}function KF(){let e=document.querySelector(`#docs-tabs`),t=document.querySelector(`#docs-body`);if(!e||!t)return;e.textContent=``;let n=(t,n)=>{let r=document.createElement(`button`);r.type=`button`,r.className=`docs-tab${VF===t?` active`:``}`,r.textContent=n,r.addEventListener(`click`,()=>{VF=t,HF=null,KF()}),e.appendChild(r)};n(`overview`,QP({en:`Overview`,ko:`개요`}));for(let e of BF)n(e.id,QP(e.label));if(t.textContent=``,VF===`overview`){qF(t);return}let r=BF.find(e=>e.id===VF);r&&JF(t,r)}function qF(e){let t=document.createElement(`h2`);t.textContent=QP(zF.title),e.appendChild(t);for(let t of zF.sections){let n=document.createElement(`h3`);n.textContent=QP(t.heading);let r=document.createElement(`p`);r.textContent=QP(t.text),e.append(n,r)}}function JF(e,t){let n=document.createElement(`p`);n.className=`docs-intro`,n.textContent=QP(t.intro),e.appendChild(n);for(let n of t.nodes){let t=document.createElement(`div`);t.className=`docs-node${HF===n.type?` open`:``}`;let r=document.createElement(`button`);r.type=`button`,r.className=`docs-node-head`;let i=document.createElement(`span`);i.className=`tree-icon`,i.appendChild(tF(n.type));let a=document.createElement(`strong`);a.textContent=n.type;let o=document.createElement(`span`);if(o.className=`docs-summary`,o.textContent=QP(n.summary),r.append(i,a,o),r.addEventListener(`click`,()=>{HF=HF===n.type?null:n.type,KF()}),t.appendChild(r),HF===n.type){let e=document.createElement(`div`);e.className=`docs-detail`;for(let t of n.body){let n=document.createElement(`p`);n.textContent=QP(t),e.appendChild(n)}e.appendChild(YF(n.type)),t.appendChild(e)}e.appendChild(t)}}function YF(e){let t=document.createElement(`table`);t.className=`docs-props`;let n=document.createElement(`tr`);for(let e of[QP({en:`prop`,ko:`prop`}),QP({en:`default`,ko:`기본값`})]){let t=document.createElement(`th`);t.textContent=e,n.appendChild(t)}t.appendChild(n);try{let n=qe(e);for(let[e,r]of Object.entries(n)){let n=document.createElement(`tr`),i=document.createElement(`td`);i.className=`mono`,i.textContent=e;let a=document.createElement(`td`);a.className=`mono`,a.textContent=JSON.stringify(r.default),n.append(i,a),t.appendChild(n)}}catch{}return t}function $(e){return Math.round(e*100)/100}function XF(e,t,n,r,i){return{name:e,type:`StaticBody3D`,props:{collider:{shape:`box`,size:t},position:n,...i?{rotation:i}:{}},children:[{name:`Skin`,type:`MeshInstance3D`,props:{mesh:`box`,size:t,...r}}]}}function ZF(e,t,n,r,i,a){let o=$(r.range(i[0],i[1])),s=$(r.range(.5,.7));return{name:`Rock${e}`,type:`MeshInstance3D`,props:{mesh:`sphere`,size:[1,1,1],position:[t,$(o*s*.6),n],rotation:[0,r.int(0,359),0],scale:[o,$(o*s),$(o*r.range(.8,1.1))],material:{color:a??QF(r),roughness:1},castShadow:!0}}}function QF(e){let t=Math.round(e.range(110,160)).toString(16).padStart(2,`0`);return`#${t}${t}${t}`}function $F(e){return[{name:`Sun`,type:`DirectionalLight3D`,props:{position:[$(e*.8),$(e*1.5),$(e*.6)],intensity:1,castShadow:!0,shadowArea:$(e*1.2)}},{name:`FillLight`,type:`DirectionalLight3D`,props:{position:[$(-e*.8),$(e*.8),$(-e*.6)],intensity:.4,color:`#b9d4ff`}}]}function eI(e,t){return e===void 0?t:typeof e==`number`?[e,e]:e}function tI(e,t,n){return Math.min(Math.max(e,t),n)}var nI=[`boxes`,`ruins`,`garden`],rI=.5,iI=.1,aI=2,oI={boxes:{floor:`#3f3f3f`,wall:`#55504a`,obstacles:[`#b0413e`,`#5b8266`,`#3e6990`,`#a26b38`,`#6d5a96`,`#878787`]},ruins:{floor:`#7d766b`,wall:`#8a8378`,obstacles:[`#8a8378`,`#979085`,`#a39a8d`,`#7b746a`]},garden:{floor:`#4d7c3a`,wall:`#2f6b2f`,obstacles:[`#2f6b2f`,`#3a7a38`,`#356e33`]}};function sI(e){let{seed:t,width:n=30,depth:r=30,wallHeight:i=3,obstacles:a=8,theme:o=`boxes`}=e;if(!nI.includes(o))throw new N(`BAD_FORMAT`,`generateArena theme must be one of [${nI.join(`, `)}], got '${o}'.`,{prop:`theme`,validOptions:[...nI]});let s=oI[o],c=new P(t),l=[XF(`Floor`,[n,iI,r],[0,-.1/2,0],{material:{color:s.floor,roughness:1},receiveShadow:!0})],u=i/2,d=[n+rI*2,i,rI],f=[rI,i,r],p={material:{color:s.wall,roughness:.9},receiveShadow:!0};l.push(XF(`Wall1`,d,[0,u,-(r+rI)/2],p),XF(`Wall2`,d,[0,u,(r+rI)/2],p),XF(`Wall3`,f,[-(n+rI)/2,u,0],p),XF(`Wall4`,f,[(n+rI)/2,u,0],p)),o===`ruins`?l.push(...lI(c,s,n,r,i,a)):l.push(...cI(c,s,n,r,i,a,o)),o===`garden`&&l.push(...uI(c,n,r));let m=Math.max(n,r);return l.push({name:`Sun`,type:`DirectionalLight3D`,props:{position:[$(m*.8),$(m*1.5),$(m*.6)],intensity:1,castShadow:!0,shadowArea:$(m*1.2)}},{name:`FillLight`,type:`DirectionalLight3D`,props:{position:[$(-m*.8),$(m*.8),$(-m*.6)],intensity:.4,color:`#b9d4ff`}},{name:`Lamp`,type:`OmniLight3D`,props:{position:[0,$(i+2),0],intensity:.5,color:`#fff3d6`,range:$(m)}}),{name:`Arena`,type:`Node3D`,children:l}}function cI(e,t,n,r,i,a,o){let s=[],c=o===`garden`?Math.min(n,r)*.16:0;for(let o=1;o<=a;o++){let a=[$(e.range(.8,2.6)),$(e.range(.8,Math.max(1.2,i*.8))),$(e.range(.8,2.6))],l=$(e.range(-(n/2-aI),n/2-aI)),u=$(e.range(-(r/2-aI),r/2-aI));if(c>0&&Math.hypot(l,u)<c+1.5){let t=Math.max(Math.hypot(l,u),.001);l=$(l/t*(c+1.5+e.range(0,2))),u=$(u/t*(c+1.5+e.range(0,2)))}let d=e.int(0,359);s.push(XF(`Obstacle${o}`,a,[l,$(a[1]/2),u],{material:{color:e.pick(t.obstacles),roughness:.8},castShadow:!0},[0,d,0]))}return s}function lI(e,t,n,r,i,a){let o=[];if(a<=0)return o;let s=Math.max(1,Math.round(Math.sqrt(a/2))),c=Math.ceil(a/s),l=n-aI*2,u=r-aI*2,d=0;for(let n=0;n<s&&d<a;n++){let r=$(s===1?0:-u/2+n/(s-1)*u);for(let n=0;n<c&&d<a;n++){d++;let a=$((c===1?0:-l/2+n/(c-1)*l)+e.range(-.4,.4)),s=$(e.next()>.35?e.range(i*.7,i*1.2):e.range(.4,.9)),u=$(e.range(.8,1.2));o.push(XF(`Obstacle${d}`,[u,s,u],[a,$(s/2),$(r+e.range(-.4,.4))],{material:{color:e.pick(t.obstacles),roughness:.95},castShadow:!0},[0,e.int(-8,8),0]))}}return o}function uI(e,t,n){let r=[],i=Math.min(t,n)*.16,a=r=>{let a=Math.min(t,n)/2-r/2-1,o=$(e.range(-a,a)),s=$(e.range(-a,a)),c=Math.max(Math.hypot(o,s),.001);return c<i+r/2&&(o=$(o/c*(i+r/2+.5)),s=$(s/c*(i+r/2+.5))),[o,s]};for(let i=1;i<=3;i++){let o=$(Math.min(t,n)*e.range(.18,.26)),[s,c]=a(o);r.push({name:`Grass${i}`,type:`Foliage3D`,props:{kind:`grass`,area:[o,o],density:10,seed:e.int(1,1e9),position:[s,0,c]}})}for(let i=1;i<=2;i++){let o=$(Math.min(t,n)*e.range(.12,.18)),[s,c]=a(o);r.push({name:`FlowerBed${i}`,type:`Flowers3D`,props:{density:`lush`,clustering:.3,area:[o,o],seed:e.int(1,1e9),position:[s,0,c]}})}return r.push({name:`Pool`,type:`Water3D`,props:{size:[$(i*2),$(i*2)],position:[0,.3,0],waveHeight:.04}}),r}var dI=32,fI=[4,8],pI=`#332f3a`,mI=`#6b6357`;function hI(e){let{seed:t,rooms:n=5}=e,[r,i]=eI(e.size,[960,720]),a=Math.max(8,Math.floor(r/dI)),o=Math.max(8,Math.floor(i/dI)),s=new P(t),c=[];for(let e=0;e<n*12&&c.length<n;e++){let e=s.int(fI[0],fI[1]),t=s.int(fI[0],fI[1]),n={x:s.int(1,Math.max(1,a-e-1)),y:s.int(1,Math.max(1,o-t-1)),w:e,h:t};c.some(e=>gI(e,n,1))||c.push(n)}let l=new Set,u=e=>{for(let t=e.y;t<e.y+e.h;t++)for(let n=e.x;n<e.x+e.w;n++)l.add(`${n},${t}`)};for(let e of c)u(e);let d=[];for(let e=1;e<c.length;e++){let[t,n]=_I(c[e-1]),[r,i]=_I(c[e]),a={x:Math.min(t,r),y:n,w:Math.abs(t-r)+1,h:1},o={x:r,y:Math.min(n,i),w:1,h:Math.abs(n-i)+1};for(let[t,n]of[[`H`,a],[`V`,o]])u(n),(n.w>1||n.h>1)&&d.push({name:`Corridor${e}${t}`,rect:n})}let f=new Set;for(let e of l){let[t,n]=e.split(`,`).map(Number);for(let e=-1;e<=1;e++)for(let r=-1;r<=1;r++){let i=`${t+r},${n+e}`;l.has(i)||f.add(i)}}let p=-(a*dI)/2,m=-(o*dI)/2,h=(e,t,n)=>({name:e,type:`ColorRect2D`,props:{position:[p+(t.x+t.w/2)*dI,m+(t.y+t.h/2)*dI],size:[t.w*dI,t.h*dI],color:n}}),g=c.map((e,t)=>h(`Room${t+1}`,e,pI));for(let e of d)g.push(h(e.name,e.rect,pI));let _=0;for(let e=-1;e<=o;e++){let t=-1;for(;t<=a;){if(!f.has(`${t},${e}`)){t++;continue}let n=1;for(;t+n<=a&&f.has(`${t+n},${e}`);)n++;_++;let r=[n*dI,dI];g.push({name:`Wall${_}`,type:`StaticBody2D`,props:{position:[p+(t+n/2)*dI,m+(e+.5)*dI],collider:{shape:`rect`,size:r}},children:[{name:`Skin`,type:`ColorRect2D`,props:{size:r,color:mI}}]}),t+=n}}return{name:`Dungeon`,type:`Node2D`,children:g}}function gI(e,t,n){return e.x-n<t.x+t.w&&e.x+e.w+n>t.x&&e.y-n<t.y+t.h&&e.y+e.h+n>t.y}function _I(e){return[Math.floor(e.x+e.w/2),Math.floor(e.y+e.h/2)]}var vI=[[0,-1],[1,0],[0,1],[-1,0]];function yI(e,t,n){let r=2*t+1,i=2*n+1,a=Array.from({length:i},()=>Array(r).fill(!1)),o=(e,t)=>{a[t][e]=!0};o(1,1);let s=new Set([`0,0`]),c=[[0,0]];for(;c.length>0;){let[r,i]=c[c.length-1],a=[];for(let[e,o]of vI){let c=r+e,l=i+o;c>=0&&c<t&&l>=0&&l<n&&!s.has(`${c},${l}`)&&a.push([c,l])}if(a.length===0){c.pop();continue}let[l,u]=e.pick(a);s.add(`${l},${u}`),o(2*l+1,2*u+1),o(r+l+1,i+u+1),c.push([l,u])}return o(0,1),o(2*t,2*n-1),{cols:t,rows:n,cells:a}}var bI=[`stone`,`hedge`,`canyon`],xI=.1,SI=`https://agent8-games.verse8.io/assets/3D/default/textures/wall`,CI=`https://agent8-games.verse8.io/assets/3D/default/textures/terrain`,wI={stone:{wall:{color:`#e8e2d8`,map:`${SI}/blocks.png`,normalMap:`${SI}/blocks_normal.png`,tile:2,roughness:.95},floor:{color:`#99938a`,map:`${CI}/stone.png`,normalMap:`${CI}/stone_normal.png`,tile:3,roughness:1},cap:`#6b5848`,pillar:`#cfc8bb`,path:`#665f55`,sun:{color:`#c9d6ea`,intensity:.75,height:.5},fill:`#9fb4cc`,mood:{sky:{elevationDeg:10,azimuthDeg:150,turbidity:16,rayleigh:3.2},fog:{near:.5,far:3.5,color:`#86909c`},exposure:.82,ambient:{color:`#c9d4e2`,intensity:.12}}},hedge:{wall:{color:`#55a83e`,map:`${CI}/grass.png`,normalMap:`${CI}/grass_normal.png`,tile:1.4,roughness:1},floor:{color:`#86b06d`,map:`${CI}/grass.png`,normalMap:`${CI}/grass_normal.png`,tile:3,roughness:1},pillar:`#3d7531`,path:`#7d6845`,sun:{color:`#e9eee6`,intensity:.7,height:1},fill:`#b9c8b4`,mood:{sky:{elevationDeg:35,azimuthDeg:150,turbidity:18,rayleigh:4.2},fog:{near:.8,far:5,color:`#aab8a6`},exposure:.88,ambient:{color:`#dde5d8`,intensity:.15}}},canyon:{wall:{color:`#f0b070`,map:`${CI}/stone.png`,normalMap:`${CI}/stone_normal.png`,tile:2.4,roughness:1},floor:{color:`#e3c193`,map:`${CI}/sand.png`,normalMap:`${CI}/sand_normal.png`,tile:3.5,roughness:1},pillar:`#d8a868`,path:`#a98a58`,sun:{color:`#ffb572`,intensity:1.15,height:.35},fill:`#caa37e`,mood:{sky:{elevationDeg:9,azimuthDeg:230,turbidity:9,rayleigh:3.5},fog:{near:.7,far:4.5,color:`#c79c6e`},exposure:.92,ambient:{color:`#ffdcb6`,intensity:.13}}}};function TI(e,t,n){return{color:e.color,roughness:e.roughness,map:e.map,...e.normalMap?{normalMap:e.normalMap}:{},repeat:[$(t/e.tile),$(n/e.tile)]}}var EI=10;function DI(e){let{seed:t,width:n=8,depth:r=8,cellSize:i=2,wallHeight:a=2.5,theme:o=`stone`}=e;if(!bI.includes(o))throw new N(`BAD_FORMAT`,`generateMaze theme must be one of [${bI.join(`, `)}], got '${o}'.`,{prop:`theme`,validOptions:[...bI]});let s=wI[o],c=new P(t),l=yI(c,n,r),u=2*n+1,d=2*r+1,f=$(u*i),p=$(d*i),m=(e,t)=>[$((e+.5)*i-f/2),$((t+.5)*i-p/2)],h=[XF(`Floor`,[f,xI,p],[0,-.1/2,0],{material:TI(s.floor,f,p),receiveShadow:!0})],g=[],_=0;for(let e=0;e<d;e++){let t=0;for(;t<u;){if(l.cells[e]?.[t]){t++;continue}let n=1;for(;t+n<u&&!l.cells[e]?.[t+n];)n++;g.push({gx:t,gz:e,run:n}),_++;let r=$(n*i);h.push(XF(`Wall${_}`,[r,a,i],[$((t+n/2)*i-f/2),$(a/2),$((e+.5)*i-p/2)],{material:TI(s.wall,r,a),castShadow:!0,receiveShadow:!0})),t+=n}}return s.cap&&h.push(...OI(g,i,a,f,p,s.cap)),h.push(...kI(c,l,i,a,m,s)),o===`hedge`?(h.push(...NI(c,g,i,a,m)),h.push(...PI(c,l,i,m,n,r))):o===`canyon`&&h.push(...FI(c,g,i,a,m)),h.push(...jI(l,i,a,m,s)),h.push(...$F(Math.max(f,p)).map((e,t)=>{if(t!==0)return{...e,props:{...e.props,color:s.fill}};let n=e.props?.position;return{...e,props:{...e.props,color:s.sun.color,intensity:s.sun.intensity,position:[n[0]??0,$((n[1]??0)*s.sun.height),n[2]??0]}}})),{name:`Maze`,type:`Node3D`,children:h}}function OI(e,t,n,r,i,a){return e.map((e,o)=>({name:`Cap${o+1}`,type:`MeshInstance3D`,props:{mesh:`box`,size:[$(e.run*t+.16),.12,$(t+.16)],position:[$((e.gx+e.run/2)*t-r/2),$(n+.06),$((e.gz+.5)*t-i/2)],material:{color:a,roughness:1},castShadow:!0,receiveShadow:!0}}))}function kI(e,t,n,r,i,a){let o=[],s=(e,n)=>t.cells[n]?.[e]===!1;for(let e=2;e<t.cells.length-1;e+=2)for(let n=2;n<(t.cells[e]?.length??0)-1;n+=2)s(n,e)&&Number(s(n-1,e))+Number(s(n+1,e))+Number(s(n,e-1))+Number(s(n,e+1))>=3&&o.push([n,e]);let c=Math.min(EI,o.length),l=[],u=new Set,d=$(n*1.2),f=$(r*1.12);for(let t=1;t<=c;t++){let n=e.int(0,o.length-1);for(;u.has(n);)n=(n+1)%o.length;u.add(n);let[r,s]=o[n],[c,p]=i(r,s);l.push(AI(`Pillar${t}`,c,p,d,f,a))}return l}function AI(e,t,n,r,i,a){return{name:e,type:`MeshInstance3D`,props:{mesh:`box`,size:[r,i,r],position:[t,$(i/2),n],material:{...TI(a.wall,r,i),color:a.pillar},castShadow:!0,receiveShadow:!0}}}function jI(e,t,n,r,i){let a=2*e.cols,o=2*e.rows-1,s=$(t*1.1),c=$(n*1.25),l=[[0,0],[0,2],[a,o-1],[a,o+1]].map(([e,t],n)=>{let[a,o]=r(e,t);return AI(`Gate${n+1}`,a,o,s,c,i)});for(let[e,n,s]of[[`EntrancePath`,0,1],[`ExitPath`,a,o]]){let[a,o]=r(n,s);l.push({name:e,type:`MeshInstance3D`,props:{mesh:`box`,size:[$(t*.96),.04,$(t*.96)],position:[a,.02,o],material:{...TI(i.floor,t,t),color:i.path},receiveShadow:!0}})}return l}var MI=10;function NI(e,t,n,r,i){return[...t].filter(e=>e.run>=2).sort((e,t)=>t.run-e.run||e.gz-t.gz||e.gx-t.gx).slice(0,MI).map((t,a)=>{let[,o]=i(t.gx,t.gz),[s]=i(t.gx,t.gz),[c]=i(t.gx+t.run-1,t.gz);return{name:`HedgeTop${a+1}`,type:`Foliage3D`,props:{kind:`grass`,style:`tufts`,area:[$(t.run*n*.92),$(n*.7)],density:14,height:.35,sway:.4,colorA:`#2f5e26`,colorB:`#5d8a3c`,seed:e.int(1,1e9),position:[$((s+c)/2),r,o]}}})}function PI(e,t,n,r,i,a){let o=[];for(let e=0;e<t.cells.length;e++)for(let n=0;n<(t.cells[e]?.length??0);n++)t.cells[e]?.[n]&&o.push([n,e]);let s=Math.min(o.length,Math.max(3,Math.floor(i*a/12))),c=[],l=new Set;for(let t=1;t<=s&&l.size<o.length;t++){let i=e.int(0,o.length-1);for(;l.has(i);)i=(i+1)%o.length;l.add(i);let[a,s]=o[i],[u,d]=r(a,s),f=$(n*.8);c.push({name:`Grass${t}`,type:`Foliage3D`,props:{kind:`grass`,area:[f,f],density:8,seed:e.int(1,1e9),position:[u,0,d]}})}return c}function FI(e,t,n,r,i){let a=[];if(t.length===0)return a;let o=Math.min(8,t.length);for(let s=1;s<=o;s++){let o=e.pick(t),[c,l]=i(o.gx+e.int(0,o.run-1),o.gz),u=ZF(s,c,l,e,[.3,$(n*.35)],`#8f7355`),d=u.props?.position;d[1]=$(d[1]+r),a.push(u)}return a}var II=`#23222b`,LI=`#5f6672`;function RI(e){let{seed:t,cols:n=10,rows:r=8,cellPx:i=64}=e,a=yI(new P(t),n,r),o=2*n+1,s=2*r+1,c=$(o*i),l=$(s*i),u=[{name:`Floor`,type:`ColorRect2D`,props:{size:[c,l],color:II}}],d=0;for(let e=0;e<s;e++){let t=0;for(;t<o;){if(a.cells[e]?.[t]){t++;continue}let n=1;for(;t+n<o&&!a.cells[e]?.[t+n];)n++;d++;let r=[$(n*i),i];u.push({name:`Wall${d}`,type:`StaticBody2D`,props:{position:[$((t+n/2)*i-c/2),$((e+.5)*i-l/2)],collider:{shape:`rect`,size:r}},children:[{name:`Skin`,type:`ColorRect2D`,props:{size:r,color:LI}}]}),t+=n}}return{name:`Maze2D`,type:`Node2D`,children:u}}var zI=16,BI=[`#5b8266`,`#3e6990`,`#a26b38`,`#6d5a96`,`#b0413e`];function VI(e){let{seed:t,count:n=10,width:r=[80,160],gapX:i=[40,120],stepY:a=[-80,40],start:o=[0,300]}=e,s=new P(t),c=[],l=$(s.range(r[0],r[1])),u=o[0],d=o[1];for(let e=1;e<=n&&(c.push(HI(e,u,d,l,s.pick(BI))),e!==n);e++){let e=$(s.range(r[0],r[1])),t=$(s.range(i[0],i[1]));u=$(u+l/2+t+e/2),d=$(d+s.range(a[0],a[1])),l=e}return{name:`Platforms`,type:`Node2D`,children:c}}function HI(e,t,n,r,i){return{name:`Platform${e}`,type:`StaticBody2D`,props:{position:[t,n],collider:{shape:`rect`,size:[r,zI]}},children:[{name:`Skin`,type:`ColorRect2D`,props:{size:[r,zI],color:i}}]}}var UI=[3,5],WI=3,GI={color:`#ffffff`,roughness:1,emissive:`#ffffff`,emissiveIntensity:.25};function KI(e){let{seed:t,count:n=8,altitude:r=18}=e,[i,a]=eI(e.area,[60,60]),o=new P(t),s=[];for(let e=1;e<=n;e++){let t=o.int(UI[0],UI[1]),n=[];for(let e=1;e<=t;e++){let r=$(o.range(1,2.2));n.push({name:`Puff${e}`,type:`MeshInstance3D`,props:{mesh:`sphere`,size:[1,1,1],position:[$((e-(t+1)/2)*o.range(1,1.6)),$(o.range(-.3,.3)),$(o.range(-.6,.6))],scale:[$(r*o.range(1.1,1.6)),$(r*.55),r],material:GI}})}s.push({name:`Cloud${e}`,type:`Node3D`,props:{position:[$(o.range(-i/2,i/2)),$(r+o.range(-3,WI)),$(o.range(-a/2,a/2))]},children:n})}return{name:`Clouds`,type:`Node3D`,children:s}}var qI=[`island`,`alpine`,`plains`,`desert`,`meadow`,`forest`,`savanna`,`snow`,`wetland`,`volcanic`],JI=128,YI=20,XI=.8,ZI=.12,QI={island:{splat:`island`,maxHeight:4.5,sun:`#fff4d6`,fill:`#b9d4ff`,sky:{elevationDeg:38,azimuthDeg:145,turbidity:2.6,rayleigh:1.1},fog:{near:1,far:4},iblIntensity:.72},alpine:{splat:`alpine`,maxHeight:8,roughness:.65,detail:5,sun:`#f4f7ff`,fill:`#c9d8f2`,sky:{elevationDeg:45,azimuthDeg:35,turbidity:1.4,rayleigh:1.3},fog:{near:1.8,far:6.5},sunIntensity:1.1,exposure:.92,iblIntensity:.72},plains:{splat:`plains`,maxHeight:4,sun:`#fff2cf`,fill:`#bcd3ef`,sky:{elevationDeg:36,azimuthDeg:140,turbidity:2.4,rayleigh:1},fog:{near:.9,far:4},iblIntensity:.58},desert:{splat:`desert`,maxHeight:5,sun:`#ffe3b3`,fill:`#e8c9a6`,sky:{elevationDeg:42,azimuthDeg:160,turbidity:7,rayleigh:.6},fog:{near:.8,far:3.2,color:`#e8d3ae`},sunIntensity:1.35,iblIntensity:.75},meadow:{splat:`grassland`,maxHeight:1.2,sun:`#fff8e2`,fill:`#bfe0c9`,sky:{elevationDeg:55,azimuthDeg:125,turbidity:2.4,rayleigh:.95},fog:{near:1,far:4.4},sunIntensity:2.6,exposure:1.12,iblIntensity:.62},forest:{splat:`forest`,maxHeight:2.5,sun:`#ffdca8`,fill:`#a9c8b4`,sky:{elevationDeg:29,azimuthDeg:120,turbidity:5.5,rayleigh:1},fog:{near:.22,far:1.8,color:`#9fb494`},sunIntensity:2.6,ambient:.26,iblIntensity:.55},savanna:{splat:`savanna`,maxHeight:3,sun:`#ffdca0`,fill:`#e6d2a4`,sky:{elevationDeg:34,azimuthDeg:150,turbidity:5,rayleigh:.7},fog:{near:1,far:4.2,color:`#e3cf9f`},sunIntensity:2,exposure:1.05,iblIntensity:.6},snow:{splat:`snow`,maxHeight:2.2,sun:`#dfe9ff`,fill:`#c2d2f0`,sky:{elevationDeg:22,azimuthDeg:35,turbidity:1.6,rayleigh:1.6},fog:{near:1.2,far:5,color:`#dbe6f5`},sunIntensity:1,exposure:.9,iblIntensity:.72},wetland:{splat:`wetland`,maxHeight:1.4,sun:`#d6ddc8`,fill:`#9fb29a`,sky:{elevationDeg:24,azimuthDeg:115,turbidity:9,rayleigh:1.1},fog:{near:.5,far:2,color:`#92a288`},sunIntensity:1.5,exposure:.94,ambient:.24,iblIntensity:.66},volcanic:{splat:`volcanic`,maxHeight:4,roughness:.7,sun:`#ff8a4a`,fill:`#7a4a3a`,sky:{elevationDeg:14,azimuthDeg:135,turbidity:10,rayleigh:.3},fog:{near:.18,far:1.4,color:`#2a211c`},sunIntensity:1.7,exposure:.86,ambient:.22,iblIntensity:.5}};function $I(e){let{seed:t,theme:n=`island`,size:r=200,water:i=!1}=e,a=QI[n];if(!a)throw new N(`BAD_FORMAT`,`generateTerrain theme must be one of [${qI.join(`, `)}], got '${n}'.`,{prop:`theme`,validOptions:[...qI]});let o=Math.max(2,Math.round(e.resolution??JI)),s=e.maxHeight||a.maxHeight,c=new P(t),l=n===`island`,u=e=>Uw({width:r,depth:r,segsX:o,segsZ:o,maxHeight:e,seed:t,...a.roughness===void 0?{}:{roughness:a.roughness},...a.detail===void 0?{}:{detail:a.detail},islandEdge:l}),d=u(s);if(l)for(let e=0;e<3;e++){let e=tL(d)-YI,t=d.maxHeight-d.minHeight,n=d.minHeight+ZI*t;if(e+XI<=n)break;let r=YI-XI,i=tL(d)-d.minHeight-ZI*t;s=$(s*Math.min(r/i*.95,.9)),d=u(s)}let f=[{name:`Ground`,type:`StaticBody3D`,props:{collider:{shape:`heightfield`}},children:[{name:`Surface`,type:`Terrain3D`,props:{size:[r,r],maxHeight:s,seed:t,theme:a.splat,...a.roughness===void 0?{}:{roughness:a.roughness},...a.detail===void 0?{}:{detail:a.detail},...o===JI?{}:{resolution:o}}}]}],p=n===`wetland`;if(l)f.push({name:`Sea`,type:`Water3D`,props:{size:[r*8,r*8],position:[0,eL(d),0],opacity:1}});else if(p){let e=d.maxHeight-d.minHeight||1,t=$(d.minHeight+.22*e);f.push({name:`Swamp`,type:`Water3D`,props:{size:[r,r],position:[0,t,0],waveHeight:.02,quality:`simple`,color:`#3a4a30`,opacity:.95}})}else if(i){let e=$(d.minHeight+.1*(d.maxHeight-d.minHeight));f.push({name:`Lake`,type:`Water3D`,props:{size:[r,r],position:[0,e,0],waveHeight:.04}})}return f.push(..._L(n,c,d,r)),l&&f.push(KI({seed:c.int(1,1e9),count:6,area:r,altitude:Math.round(d.maxHeight+12)})),f.push(...$F(r).map((e,t)=>vL(e,t===0?a.sun:a.fill,t===0?a.sunIntensity??1.7:void 0))),{name:`Terrain`,type:`Node3D`,children:f}}function eL(e){let t=tL(e)-YI,n=e.minHeight+ZI*(e.maxHeight-e.minHeight);return $(Math.max(Math.min(t+XI,n),t+.55))}function tL(e){let t=-1/0,n=e.width/2,r=e.depth/2,i=e.segsX;for(let a=0;a<=i;a++){let o=-n+a/i*e.width,s=-r+a/i*e.depth;t=Math.max(t,e.baseHeight(o,-r),e.baseHeight(o,r),e.baseHeight(-n,s),e.baseHeight(n,s))}return t}function nL(e,t,n){let r=Math.min(t.width/2-n.margin,n.within??1/0),i=t.maxHeight-t.minHeight||1,a=[];for(let o=0;o<n.count*30&&a.length<n.count;o++){let o=$(e.range(-r,r)),s=$(e.range(-r,r));if(n.clearing&&Math.hypot(o,s)<n.clearing||n.within&&Math.hypot(o,s)>n.within)continue;let c=t.heightAt(o,s),l=(c-t.minHeight)/i;l<n.band[0]||l>n.band[1]||t.slopeAt(o,s)>n.maxSlope||a.push({x:o,z:s,y:c})}return a}var rL=[{canopy:`#2f5d44`,trunk:`#6e4a32`},{canopy:`#356a4c`,trunk:`#71503a`},{canopy:`#2c5740`,trunk:`#5f4530`},{canopy:`#3a6b4a`,trunk:`#6a4c34`}],iL=[{canopy:`#4a7c3f`,trunk:`#7a5a3a`},{canopy:`#56883c`,trunk:`#806044`},{canopy:`#7a9d3e`,trunk:`#9a9488`},{canopy:`#86a346`,trunk:`#a39c8e`},{canopy:`#b8862f`,trunk:`#7e5e38`},{canopy:`#a8702c`,trunk:`#74552f`}],aL={canopy:`#9aa052`,trunk:`#8a6a44`},oL={canopy:`#39513f`,trunk:`#5a5650`};function sL(e,t){return e===`conifer`?t.pick(rL):e===`broadleaf`?t.pick(iL):null}function cL(e,t,n,r,i){let a=i?.height??[4.5,7],o=i?.sink??(i?.count===void 0?.05:.3),s={};i?.tier!==void 0&&(s.tier=i.tier),i?.count!==void 0&&i.area!==void 0&&(s.count=i.count,s.area=[i.area,i.area]);let c=sL(r,n),l=i?.palette??c;return l&&(s.canopyColor=l.canopy,s.trunkColor=l.trunk),{name:e,type:`Tree3D`,props:{type:r,seed:n.int(1,1e9),height:$(n.range(a[0],a[1])),position:[t.x,$(t.y-o),t.z],...s}}}function lL(e,t,n,r,i,a=0,o){return{name:e,type:`Foliage3D`,props:{kind:`grass`,style:`tufts`,area:[r,r],density:i,height:o?.height??.3,...o?.colors?{colorA:o.colors[0],colorB:o.colors[1]}:{},seed:n.int(1,1e9),position:[t.x,$(t.y+.02),t.z],...a>0?{flowers:a}:{}}}}function uL(e,t,n,r,i){return{name:e,type:`Foliage3D`,props:{kind:`reeds`,style:`simple`,area:[r,r],density:i,height:.9,colorA:`#2f4a26`,colorB:`#5a6f33`,seed:n.int(1,1e9),position:[t.x,$(t.y+.02),t.z]}}}function dL(e,t,n,r,i){return{name:e,type:`Flowers3D`,props:{density:i,area:[r,r],seed:n.int(1,1e9),position:[t.x,$(t.y+.02),t.z]}}}function fL(e,t,n,r){return e.map((e,i)=>{let a=ZF(i+1,e.x,e.z,t,n,r?.(t)),o=a.props?.position;return o[1]=$(o[1]+e.y),a})}function pL(e){let t=Math.round(e.range(104,128)),n=Math.round(t-e.range(10,18)),r=Math.round(t-e.range(20,30)),i=e=>e.toString(16).padStart(2,`0`);return`#${i(n)}${i(t)}${i(r)}`}function mL(e){let t=Math.round(e.range(196,224)),n=Math.min(255,t+Math.round(e.range(4,12))),r=e=>e.toString(16).padStart(2,`0`);return`#${r(t)}${r(t)}${r(n)}`}function hL(e){let t=Math.round(e.range(34,56)),n=Math.min(255,t+Math.round(e.range(2,8))),r=e=>e.toString(16).padStart(2,`0`);return`#${r(n)}${r(t)}${r(t)}`}var gL=[`#6f5b41`,`#7a644a`,`#665439`];function _L(e,t,n,r){let i=[];switch(e){case`island`:{let e=nL(t,n,{count:7,band:[.18,.6],maxSlope:.5,margin:26});i.push(...e.map((e,n)=>cL(`Tree${n+1}`,e,t,`conifer`)));break}case`alpine`:{let e=nL(t,n,{count:10,band:[.2,.5],maxSlope:.55,margin:6});i.push(...e.map((e,n)=>cL(`Tree${n+1}`,e,t,`conifer`)));let r=nL(t,n,{count:8,band:[.55,1],maxSlope:.9,margin:6});i.push(...fL(r,t,[.6,1.8]));break}case`plains`:{let e=nL(t,n,{count:8,band:[0,1],maxSlope:.4,margin:6});i.push(...e.map((e,n)=>cL(`Tree${n+1}`,e,t,`broadleaf`)));let r=nL(t,n,{count:6,band:[0,1],maxSlope:.5,margin:6});i.push(...fL(r,t,[.4,1.2]));break}case`desert`:{let e=nL(t,n,{count:6,band:[0,1],maxSlope:.45,margin:6});i.push(...e.map((e,n)=>cL(`Tree${n+1}`,e,t,`dead`)));let r=nL(t,n,{count:8,band:[0,1],maxSlope:.6,margin:6});i.push(...fL(r,t,[.5,1.6]));break}case`meadow`:{let e=$(r*.09),a=nL(t,n,{count:7,band:[0,1],maxSlope:.05,margin:e/2+8});i.push(...a.map((n,r)=>lL(`Carpet${r+1}`,n,t,e,30)));let o=$(r*.07),s=nL(t,n,{count:3,band:[0,1],maxSlope:.05,margin:o/2+8});i.push(...s.map((e,n)=>dL(`Flowers${n+1}`,e,t,o,`sparse`)));let c=nL(t,n,{count:4,band:[0,1],maxSlope:.1,margin:12});i.push(...c.map((e,n)=>cL(`Grove${n+1}`,e,t,`broadleaf`,{count:3,area:6})));let l=nL(t,n,{count:6,band:[0,1],maxSlope:.2,margin:8});i.push(...fL(l,t,[.3,.9]));break}case`forest`:{let e=$(r*.12),a=r/2-8,o=dn(t.int(1,1e9)),s=(e,t,n)=>{let r=o(e/70,t/70);return r>.12?`conifer`:r<-.12?`broadleaf`:n%2==0?`conifer`:`broadleaf`},c=nL(t,n,{count:40,band:[0,1],maxSlope:.18,margin:8,clearing:e+6}),l=c.map((e,t)=>s(e.x,e.z,t));i.push(...c.map((e,n)=>cL(`Grove${n+1}`,e,t,l[n],{count:12,area:13,height:[5.5,8]}))),c.forEach((e,n)=>{n%3==0&&i.push(cL(`Sapling${n+1}`,e,t,l[n],{count:4,area:19,height:[2.5,3.4],sink:.12}))});let u=nL(t,n,{count:6,band:[0,1],maxSlope:.2,margin:12,clearing:e+4});i.push(...u.map((e,n)=>cL(`Elder${n+1}`,e,t,s(e.x,e.z,n),{tier:`high`,height:[8.4,9.8]})));let d=nL(t,n,{count:3,band:[0,1],maxSlope:.18,margin:10,clearing:e+6});i.push(...d.map((e,n)=>cL(`Accent${n+1}`,e,t,`broadleaf`,{tier:`high`,count:3,area:7,height:[5.6,6.8]})));let f=nL(t,n,{count:10,band:[0,1],maxSlope:.14,margin:9,clearing:e+2});i.push(...f.map((e,n)=>cL(`Bush${n+1}`,e,t,`bush`,{count:4,area:10,height:[2.1,3.1],sink:.12})));let p=0;c.forEach((e,r)=>{if(r%3==2)return;let o=t.range(0,Math.PI*2),s=t.range(2,4.5),c=t.int(1,1e9),l=$(tI(e.x+Math.cos(o)*s,-a,a)),u=$(tI(e.z+Math.sin(o)*s,-a,a));n.slopeAt(l,u)>.09||(p++,i.push({name:`Fern${p}`,type:`Foliage3D`,props:{kind:`grass`,style:`tufts`,tuftStyle:`fern`,area:[8,8],density:9,height:.4,colorA:`#4a6b34`,colorB:`#82a258`,seed:c,position:[l,$(n.heightAt(l,u)+.02),u]}}))});let m=$(r*.08),h=nL(t,n,{count:5,band:[0,1],maxSlope:.06,margin:m/2+8});i.push(...h.map((e,n)=>lL(`Grass${n+1}`,e,t,m,20,0,{height:.24,colors:[`#4f7034`,`#85a154`]})));let g=u.length>0?t.int(3,5):0;for(let e=0;e<g;e++){let r=u[e%u.length],o=t.range(0,Math.PI*2),s=t.range(2.5,4.5),c=$(tI(r.x+Math.cos(o)*s,-a,a)),l=$(tI(r.z+Math.sin(o)*s,-a,a));i.push({name:`Log${e+1}`,type:`Tree3D`,props:{type:`dead`,seed:t.int(1,1e9),height:$(t.range(4.2,5.6)),trunkColor:`#4a4236`,position:[c,$(n.heightAt(c,l)+.12),l],rotation:[0,t.int(0,359),$(t.range(81,97))]}})}nL(t,n,{count:5,band:[0,1],maxSlope:.25,margin:9,clearing:e}).forEach((e,n)=>{let r=$(t.range(.16,.28)),a=$(t.range(.3,.55));i.push({name:`Stump${n+1}`,type:`MeshInstance3D`,props:{mesh:`cylinder`,size:[r,a,r],position:[e.x,$(e.y+a/2-.06),e.z],rotation:[0,t.int(0,359),0],material:{color:t.pick(gL),roughness:1},castShadow:!0}})});let _=nL(t,n,{count:8,band:[0,1],maxSlope:.2,margin:8});i.push(...fL(_,t,[.3,1],pL));let v=$(e*.75),y=nL(t,n,{count:3,band:[0,1],maxSlope:.06,margin:8,within:e-$(v/Math.SQRT2)});i.push(...y.map((e,n)=>lL(`Clearing${n+1}`,e,t,v,30,0,{colors:[`#5d8438`,`#a8bc60`]})));let b=$(e*.45),x=nL(t,n,{count:2,band:[0,1],maxSlope:.06,margin:8,within:e-$(b/Math.SQRT2)});i.push(...x.map((e,n)=>dL(`Flowers${n+1}`,e,t,b,`sparse`)));break}case`savanna`:{let e=nL(t,n,{count:7,band:[0,.85],maxSlope:.35,margin:8});i.push(...e.map((e,n)=>cL(`Tree${n+1}`,e,t,`broadleaf`,{height:[3.5,5],palette:aL})));let a=$(r*.09),o=nL(t,n,{count:6,band:[0,1],maxSlope:.05,margin:a/2+8});i.push(...o.map((e,n)=>lL(`Carpet${n+1}`,e,t,a,26,0,{height:.34,colors:[`#9a8f43`,`#c9bd6a`]})));let s=nL(t,n,{count:7,band:[0,1],maxSlope:.5,margin:8});i.push(...fL(s,t,[.4,1.4]));let c=nL(t,n,{count:4,band:[0,1],maxSlope:.2,margin:9});i.push(...c.map((e,n)=>cL(`Scrub${n+1}`,e,t,`bush`,{count:3,area:8,height:[1.4,2.2]})));break}case`snow`:{let e=nL(t,n,{count:8,band:[0,.9],maxSlope:.4,margin:8});i.push(...e.map((e,n)=>cL(`Tree${n+1}`,e,t,`conifer`,{height:[4,6.5],palette:oL})));let r=nL(t,n,{count:10,band:[0,1],maxSlope:.7,margin:8});i.push(...fL(r,t,[.5,1.8],mL));break}case`wetland`:{let e=$(r*.08),a=nL(t,n,{count:6,band:[0,.5],maxSlope:.06,margin:e/2+8});i.push(...a.map((n,r)=>uL(`Reeds${r+1}`,n,t,e,4)));let o=$(r*.08),s=nL(t,n,{count:4,band:[.2,1],maxSlope:.05,margin:o/2+8});i.push(...s.map((e,n)=>lL(`Moss${n+1}`,e,t,o,22,0,{height:.22,colors:[`#3a5a2c`,`#6f8a48`]})));let c=nL(t,n,{count:6,band:[.25,1],maxSlope:.35,margin:9});i.push(...c.map((e,n)=>cL(`Snag${n+1}`,e,t,`dead`,{height:[4,6]})));let l=nL(t,n,{count:6,band:[.2,1],maxSlope:.2,margin:9});i.push(...l.map((e,n)=>cL(`Bush${n+1}`,e,t,`bush`,{count:3,area:7,height:[1.6,2.6]})));let u=nL(t,n,{count:5,band:[.2,1],maxSlope:.3,margin:8});i.push(...fL(u,t,[.3,1],pL));break}case`volcanic`:{let e=nL(t,n,{count:7,band:[0,1],maxSlope:.45,margin:8});i.push(...e.map((e,n)=>cL(`Tree${n+1}`,e,t,`dead`,{height:[4,6.5]})));let r=nL(t,n,{count:12,band:[0,1],maxSlope:.7,margin:8});i.push(...fL(r,t,[.4,1.8],hL)),nL(t,n,{count:3,band:[0,.6],maxSlope:.18,margin:12}).forEach((e,n)=>{t.int(1,1e9),i.push({name:`Smoke${n+1}`,type:`Particles3D`,props:{preset:`smoke`,position:[e.x,$(e.y+.2),e.z],rate:8,maxParticles:64,colorStart:`#5a5048`,colorEnd:`#2a2422`,sizeStart:18,sizeEnd:44}}),i.push({name:`Embers${n+1}`,type:`Particles3D`,props:{position:[e.x,$(e.y+.1),e.z],rate:10,maxParticles:48,lifetime:[.8,1.8],speed:[12,34],directionDeg:-90,spreadDeg:40,gravity:[0,-18],sizeStart:4,sizeEnd:1,colorStart:`#ffce6a`,colorEnd:`#d83a14`,blend:`add`}})});break}}return i}function vL(e,t,n){return{...e,props:{...e.props,color:t,...n===void 0?{}:{intensity:n}}}}var yL={arena:{description:`FPS stage: floor, 4 perimeter walls, obstacles, lights — themes: boxes (crates), ruins (broken stone rows), garden (hedges, grass, pool)`,dimension:`3d`,params:{theme:{type:`string`,default:`boxes`,options:[...nI]},width:{type:`number`,default:30,min:4},depth:{type:`number`,default:30,min:4},wallHeight:{type:`number`,default:3,min:.5},obstacles:{type:`number`,default:8,min:0}}},terrain:{description:`Heightfield world: StaticBody3D{heightfield} + Terrain3D + theme dressing (trees, rocks, grass, sea/clouds on island, broad swamp water on wetland, smoke/ember emitters on volcanic; maxHeight 0 = theme default; water adds a lake to non-island themes)`,dimension:`3d`,params:{theme:{type:`string`,default:`island`,options:[...qI]},size:{type:`number`,default:200,min:40,max:400},maxHeight:{type:`number`,default:0,min:0},water:{type:`boolean`,default:!1}}},maze:{description:`Recursive-backtracker 3D maze, west→east — themes: stone, hedge (green + grass), canyon (sandstone + rim rocks)`,dimension:`3d`,params:{theme:{type:`string`,default:`stone`,options:[...bI]},width:{type:`number`,default:8,min:2,max:40},depth:{type:`number`,default:8,min:2,max:40},cellSize:{type:`number`,default:2,min:.5},wallHeight:{type:`number`,default:2.5,min:.5}}},maze2d:{description:`The same maze algorithm as 2D ColorRect2D + StaticBody2D tiles`,dimension:`2d`,params:{cols:{type:`number`,default:10,min:2,max:40},rows:{type:`number`,default:8,min:2,max:40},cellPx:{type:`number`,default:64,min:8}}},dungeon2d:{description:`Roguelike rooms + L-corridors: floor rects, wall bodies (32px tiles)`,dimension:`2d`,params:{rooms:{type:`number`,default:5,min:1,max:20},size:{type:`number`,default:960,min:256}}},platforms2d:{description:`Left-to-right 2D platform course (tune ranges via the library)`,dimension:`2d`,params:{count:{type:`number`,default:10,min:1}}}},bL={arena:sI,terrain:$I,maze:DI,maze2d:RI,dungeon2d:hI,platforms2d:VI};function xL(e,t){let n=bL[e];if(!n){let t=Object.keys(bL);throw new N(`BAD_FORMAT`,`Unknown generator '${e}'. Valid: [${t.join(`, `)}] — the old meadow/forest/island/rocks/clouds generators became themes (e.g. terrain theme: 'meadow', arena theme: 'garden'); scatter is library-only (needs item templates).`,{validOptions:t})}return n(t)}function SL(e){return Object.entries(yL).filter(([,t])=>t.dimension===e).map(([e,t])=>({name:e,meta:t}))}function CL(e,t){if(e.type===`boolean`)return t===!0||t===`true`;if(e.type===`number`){let n=typeof t==`boolean`?NaN:Number(t);return(t===``||!Number.isFinite(n))&&(n=e.default),e.min!==void 0&&(n=Math.max(e.min,n)),e.max!==void 0&&(n=Math.min(e.max,n)),n}let n=String(t);return e.options&&!e.options.includes(n)?e.default:n}function wL(){return Math.floor(Math.random()*1e6)}var TL=[],EL=new Map,DL=null;function OL(e){let t=document.querySelector(`#generate`);t&&(jL(e),t.removeAttribute(`hidden`))}function kL(){document.querySelector(`#generate`)?.setAttribute(`hidden`,``)}function AL(e){let t=document.querySelector(`#generate`);t&&(t.addEventListener(`pointerdown`,e=>{e.target===t&&kL()}),document.querySelector(`#generate-close`)?.addEventListener(`click`,kL),document.querySelector(`#generate-cancel`)?.addEventListener(`click`,kL),document.querySelector(`#generate-insert`)?.addEventListener(`click`,()=>ML(e)))}function jL(e){let t=document.querySelector(`#generate-body`),n=document.querySelector(`#generate-status`);if(!t)return;n&&(n.textContent=``),t.textContent=``;let r=e.working.dimension??`2d`;TL=SL(r);let i=document.createElement(`p`);i.className=`gen-hint`,i.textContent=QP({en:`Deterministic ${r.toUpperCase()} environment generators — the subtree inserts under the selected node (the root when nothing is selected). The same seed always generates the same level.`,ko:`결정적 ${r.toUpperCase()} 환경 생성기 — 생성된 서브트리는 선택한 노드 아래에(선택이 없으면 루트에) 들어갑니다. 같은 시드는 항상 같은 레벨을 만듭니다.`}),t.appendChild(i);let a=NL(QP({en:`generator`,ko:`생성기`})),o=document.createElement(`select`);o.id=`generate-name`;for(let{name:e}of TL){let t=document.createElement(`option`);t.value=e,t.textContent=e,o.appendChild(t)}a.appendChild(o),t.appendChild(a);let s=document.createElement(`p`);s.className=`gen-desc`,t.appendChild(s);let c=document.createElement(`div`);c.id=`generate-params`,t.appendChild(c);let l=NL(`seed`);DL=document.createElement(`input`),DL.type=`number`,DL.step=`1`,DL.value=String(wL());let u=document.createElement(`button`);u.type=`button`,u.className=`ghost`,u.textContent=`↻`,u.title=QP({en:`New random seed`,ko:`새 랜덤 시드`}),u.addEventListener(`click`,()=>{DL&&(DL.value=String(wL()))});let d=document.createElement(`div`);d.className=`gen-seed-row`,d.append(DL,u),l.appendChild(d),t.appendChild(l);let f=()=>{let e=TL.find(e=>e.name===o.value)??TL[0];if(e){s.textContent=e.meta.description,c.textContent=``,EL=new Map;for(let[t,n]of Object.entries(e.meta.params)){let e=NL(t),r;if(n.type===`boolean`)r=document.createElement(`input`),r.type=`checkbox`,r.checked=n.default===!0;else if(n.type===`string`&&n.options){r=document.createElement(`select`);for(let e of n.options){let t=document.createElement(`option`);t.value=e,t.textContent=e,r.appendChild(t)}r.value=String(n.default)}else r=document.createElement(`input`),r.type=n.type===`number`?`number`:`text`,n.type===`number`&&(r.step=`any`,n.min!==void 0&&(r.min=String(n.min)),n.max!==void 0&&(r.max=String(n.max))),r.value=String(n.default),(n.min!==void 0||n.max!==void 0)&&(r.title=`${n.min??``}–${n.max??``}`);EL.set(t,r),e.appendChild(r),c.appendChild(e)}}};o.addEventListener(`change`,f),f()}function ML(e){let t=document.querySelector(`#generate-status`),n=document.querySelector(`#generate-name`),r=TL.find(e=>e.name===n?.value);if(!r||!DL)return;let i={seed:CL({type:`number`,default:wL(),min:0},DL.value)};for(let[e,t]of EL){let n=r.meta.params[e];n&&(i[e]=CL(n,t.type===`checkbox`?t.checked:t.value))}let a;try{a=xL(r.name,i)}catch(e){t&&(t.textContent=e instanceof Error?e.message:String(e));return}let o=e.insertNode(a,e.selection??[]);if(o===null){t&&(t.textContent=QP({en:`Insert failed — see the error banner.`,ko:`삽입 실패 — 에러 배너를 확인하세요.`}));return}e.select(o),DL&&(DL.value=String(wL())),kL()}function NL(e){let t=document.createElement(`label`);t.className=`field`;let n=document.createElement(`span`);return n.textContent=e,t.appendChild(n),t}var PL={connections:{title:{en:`connections — wire a signal to a handler`,ko:`connections — 시그널을 핸들러에 연결`},body:{en:'A connection says "when THIS node emits THIS signal, call THIS method on THAT node" — declaratively, in the scene JSON, with no TypeScript. emits = leaving this node; receives = arriving at it. Paths resolve from the scene ROOT (`Player/Sword`, `.` for the root itself). A red target does not resolve and the game will refuse to load the scene. Handlers on a scripted node are free text: they live in your behavior, which the editor never loads.',ko:'연결은 "이 노드가 이 시그널을 보내면, 저 노드의 이 메서드를 호출한다"를 씬 JSON에 선언합니다 — TypeScript 없이. emits는 이 노드에서 나가는 것, receives는 들어오는 것입니다. 경로는 씬 루트 기준입니다(`Player/Sword`, 루트 자신은 `.`). 빨간 대상은 찾을 수 없다는 뜻이고, 게임은 그 씬을 열지 못합니다. 스크립트가 있는 노드의 핸들러는 자유 입력입니다 — 에디터가 읽지 않는 게임 코드에 있기 때문입니다.'}},groups:{title:{en:`groups — tag nodes for queries`,ko:`groups — 조회용 태그`},body:{en:`Free-form tags. Game code finds nodes with tree-wide queries like getNodesInGroup("coins"), and triggers can filter by group (e.g. only react to "player"). Type a name and press Enter.`,ko:`자유 형식 태그입니다. 게임 코드가 getNodesInGroup("coins")처럼 트리 전체에서 노드를 찾고, 트리거는 그룹으로 거릅니다(예: "player"에만 반응). 이름을 입력하고 Enter를 누르세요.`},example:`triggerEnter → if (other.isInGroup("player")) collect()`},script:{title:{en:`script — attach YOUR game logic`,ko:`script — 게임 로직 연결`},body:{en:`A Behavior is a TypeScript class living in YOUR game code, linked by name. The editor stores the link; the class itself must be registered in the game before loadScene. Props here are passed to the behavior instance.`,ko:`Behavior는 게임 코드에 있는 TypeScript 클래스이며 이름으로 연결됩니다. 에디터는 연결만 저장하고, 클래스 자체는 loadScene 전에 게임에서 등록되어야 합니다. 여기의 props가 비헤이비어 인스턴스로 전달됩니다.`},example:`registerBehavior('CoinCounter', CoinCounter) // in your main.ts`,copy:{label:`copy behavior boilerplate`,text:`import { Behavior, registerBehavior } from 'incanto';
|
|
8414
8414
|
|
|
8415
8415
|
export class MyBehavior extends Behavior {
|
|
8416
8416
|
static props = { speed: { default: 100 } };
|
|
@@ -8420,8 +8420,8 @@ export class MyBehavior extends Behavior {
|
|
|
8420
8420
|
update(dt: number): void {}
|
|
8421
8421
|
}
|
|
8422
8422
|
registerBehavior('MyBehavior', MyBehavior); // before loadScene()
|
|
8423
|
-
`}},network:{title:{en:`network — replicate to other players`,ko:`network — 다른 플레이어에게 복제`},body:{en:`mode "owner" means THIS player owns the node and broadcasts the listed sync keys to everyone in the room (one owner node per player — usually your player character). Other players see it via a NetworkSpawner. Keys are relative to this node: "position", or "Skin.animation" for a child prop.`,ko:`mode "owner"는 이 플레이어가 노드를 소유하고 sync 키 목록을 방의 모두에게 송출한다는 뜻입니다(플레이어당 owner 노드 하나 — 보통 내 캐릭터). 다른 플레이어는 NetworkSpawner로 봅니다. 키는 이 노드 기준 상대 표기입니다: "position", 자식 prop은 "Skin.animation".`},example:`{ "mode": "owner", "sync": ["position"], "throttleMs": 50 }`},collider:{title:{en:`collider — the physics shape`,ko:`collider — 물리 모양`},body:{en:`Shapes: rect (size [w,h]), circle (radius), capsule (radius + height — good for characters). offset shifts the shape from the node position. The green dashed outline in the viewport shows exactly where it is.`,ko:`모양: rect(size [w,h]), circle(radius), capsule(radius+height — 캐릭터에 적합). offset이 노드 위치에서 모양을 이동시킵니다. 뷰포트의 초록 점선이 정확한 위치를 보여줍니다.`},example:`{ "shape": "capsule", "radius": 12, "height": 16 }`},physics:{title:{en:`physics — scene gravity`,ko:`physics — 씬 중력`},body:{en:`World gravity in px/s² (y-down: positive y pulls DOWN). [0, 1400] feels platformer-y; [0, 0] for top-down. Takes effect when the game calls enablePhysics2D — and in the editor’s play mode.`,ko:`월드 중력, px/s² 단위(y-아래: 양수 y가 아래로 당김). [0, 1400]이면 플랫포머 느낌, 탑다운은 [0, 0]. 게임이 enablePhysics2D를 부를 때 — 그리고 에디터 플레이 모드에서 — 적용됩니다.`},example:`"physics": { "gravity": [0, 1400] }`}},NL=null;function PL(e){document.addEventListener(`click`,t=>{let n=t.target,r=n.closest(`[data-help]`);if(!r){e.contains(n)||(e.hidden=!0);return}let i=ML[r.dataset.help??``];if(!i)return;if(!e.hidden&&NL===r){e.hidden=!0;return}NL=r,e.textContent=``;let a=document.createElement(`h4`);a.textContent=XP(i.title);let o=document.createElement(`div`);if(o.textContent=XP(i.body),e.append(a,o),i.example){let t=document.createElement(`pre`);t.textContent=i.example,e.appendChild(t)}if(i.copy){let t=document.createElement(`div`);t.className=`pop-actions`;let n=document.createElement(`button`);n.type=`button`,n.className=`linklike`,n.textContent=`⧉ ${i.copy.label}`,n.addEventListener(`click`,()=>{navigator.clipboard.writeText(i.copy?.text??``),n.textContent=`✓ copied`}),t.appendChild(n),e.appendChild(t)}e.hidden=!1;let s=e.getBoundingClientRect(),{left:c,top:l}=FL(r.getBoundingClientRect(),{width:s.width,height:s.height},{width:innerWidth,height:innerHeight});e.style.left=`${c}px`,e.style.top=`${l}px`})}function FL(e,t,n,r=8){let i=t.width||300,a=e.left-i+20,o=Math.max(r,Math.min(n.width-i-r,a)),s=e.bottom+r,c=e.top-t.height-r,l;return l=s+t.height+r<=n.height?s:c>=r?c:r,{left:o,top:l}}function IL(e){let t=document.createElement(`button`);return t.type=`button`,t.className=`help-btn`,t.dataset.help=e,t.textContent=`?`,t.title=`What is this?`,t}var LL=JSON.parse('[{"name":"2dbasic","file":"characters/2dbasic.png","url":"incanto/assets/characters/2dbasic.png","kind":"character","bytes":30499,"description":"2dbasic sprite sheet image.anything,base character. (frame size 192x192)","animation":"characters/2dbasic.json","frameWidth":111,"frameHeight":83},{"name":"attacked","file":"audio/attacked.mp3","url":"incanto/assets/audio/attacked.mp3","kind":"audio","bytes":8757,"description":"Short hurt / took-damage SFX for the player or an enemy."},{"name":"bark_birch_color","file":"vegetation/bark/birch_color_1k.jpg","url":"https://agent8-games.verse8.io/assets/3D/default/textures/vegetation/bark/birch_color_1k.jpg","kind":"foliage","bytes":194186,"description":"Birch bark base color texture (1k), ambientcg Bark (CC0) packaged by ez-tree (MIT). Tree3D trunks/branches sample it by default from the agent8 CDN (the only sanctioned external host); the bundled `incanto/assets` copy (see this entry’s `file`) serves it offline."},{"name":"bark_birch_normal","file":"vegetation/bark/birch_normal_1k.jpg","url":"https://agent8-games.verse8.io/assets/3D/default/textures/vegetation/bark/birch_normal_1k.jpg","kind":"foliage","bytes":378046,"description":"Birch bark tangent-space normal texture (1k), ambientcg Bark (CC0) packaged by ez-tree (MIT). Tree3D trunks/branches sample it by default from the agent8 CDN (the only sanctioned external host); the bundled `incanto/assets` copy (see this entry’s `file`) serves it offline."},{"name":"bark_birch_roughness","file":"vegetation/bark/birch_roughness_1k.jpg","url":"https://agent8-games.verse8.io/assets/3D/default/textures/vegetation/bark/birch_roughness_1k.jpg","kind":"foliage","bytes":127387,"description":"Birch bark roughness texture (1k), ambientcg Bark (CC0) packaged by ez-tree (MIT). Tree3D trunks/branches sample it by default from the agent8 CDN (the only sanctioned external host); the bundled `incanto/assets` copy (see this entry’s `file`) serves it offline."},{"name":"bark_oak_color","file":"vegetation/bark/oak_color_1k.jpg","url":"https://agent8-games.verse8.io/assets/3D/default/textures/vegetation/bark/oak_color_1k.jpg","kind":"foliage","bytes":297877,"description":"Oak bark base color texture (1k), ambientcg Bark (CC0) packaged by ez-tree (MIT). Tree3D trunks/branches sample it by default from the agent8 CDN (the only sanctioned external host); the bundled `incanto/assets` copy (see this entry’s `file`) serves it offline."},{"name":"bark_oak_normal","file":"vegetation/bark/oak_normal_1k.jpg","url":"https://agent8-games.verse8.io/assets/3D/default/textures/vegetation/bark/oak_normal_1k.jpg","kind":"foliage","bytes":67610,"description":"Oak bark tangent-space normal texture (1k), ambientcg Bark (CC0) packaged by ez-tree (MIT). Tree3D trunks/branches sample it by default from the agent8 CDN (the only sanctioned external host); the bundled `incanto/assets` copy (see this entry’s `file`) serves it offline."},{"name":"bark_oak_roughness","file":"vegetation/bark/oak_roughness_1k.jpg","url":"https://agent8-games.verse8.io/assets/3D/default/textures/vegetation/bark/oak_roughness_1k.jpg","kind":"foliage","bytes":16648,"description":"Oak bark roughness texture (1k), ambientcg Bark (CC0) packaged by ez-tree (MIT). Tree3D trunks/branches sample it by default from the agent8 CDN (the only sanctioned external host); the bundled `incanto/assets` copy (see this entry’s `file`) serves it offline."},{"name":"bark_pine_color","file":"vegetation/bark/pine_color_1k.jpg","url":"https://agent8-games.verse8.io/assets/3D/default/textures/vegetation/bark/pine_color_1k.jpg","kind":"foliage","bytes":196361,"description":"Pine bark base color texture (1k), ambientcg Bark (CC0) packaged by ez-tree (MIT). Tree3D trunks/branches sample it by default from the agent8 CDN (the only sanctioned external host); the bundled `incanto/assets` copy (see this entry’s `file`) serves it offline."},{"name":"bark_pine_normal","file":"vegetation/bark/pine_normal_1k.jpg","url":"https://agent8-games.verse8.io/assets/3D/default/textures/vegetation/bark/pine_normal_1k.jpg","kind":"foliage","bytes":58237,"description":"Pine bark tangent-space normal texture (1k), ambientcg Bark (CC0) packaged by ez-tree (MIT). Tree3D trunks/branches sample it by default from the agent8 CDN (the only sanctioned external host); the bundled `incanto/assets` copy (see this entry’s `file`) serves it offline."},{"name":"bark_pine_roughness","file":"vegetation/bark/pine_roughness_1k.jpg","url":"https://agent8-games.verse8.io/assets/3D/default/textures/vegetation/bark/pine_roughness_1k.jpg","kind":"foliage","bytes":36136,"description":"Pine bark roughness texture (1k), ambientcg Bark (CC0) packaged by ez-tree (MIT). Tree3D trunks/branches sample it by default from the agent8 CDN (the only sanctioned external host); the bundled `incanto/assets` copy (see this entry’s `file`) serves it offline."},{"name":"box","file":"items/box.png","url":"incanto/assets/items/box.png","kind":"item","bytes":10861,"description":"Item box sprite for Dungeons and Dungeoners. Container sprite that holds random items or rewards when opened by player."},{"name":"buff_potion","file":"items/buff_potion.png","url":"incanto/assets/items/buff_potion.png","kind":"item","bytes":3809,"description":"Buff potion item sprite for Dungeons and Dungeoners. Consumable item that grants temporary stat boosts or positive effects to player character."},{"name":"coin","file":"items/coin.png","url":"incanto/assets/items/coin.png","kind":"item","bytes":1689,"description":"Gold coin collectible sprite for Dungeons and Dungeoners. Currency item with metallic sheen, used as in-game money or collectible reward."},{"name":"explosion","file":"audio/explosion.mp3","url":"incanto/assets/audio/explosion.mp3","kind":"audio","bytes":40124,"description":"Impactful explosion / large destructive hit SFX. Pair with the Particles2D \\"explosion\\" preset."},{"name":"floor00","file":"tiles/floor00.jpg","url":"incanto/assets/tiles/floor00.jpg","kind":"tile","bytes":28736,"description":"Basic floor tile texture for Dungeons and Dungeoners project, suitable for dungeon ground surfaces."},{"name":"gem","file":"items/gem.png","url":"incanto/assets/items/gem.png","kind":"item","bytes":8762,"description":"Gem collectible sprite for Dungeons and Dungeoners. Valuable gemstone item used as currency, crafting material, or quest objective."},{"name":"ghost","file":"characters/ghost.png","url":"incanto/assets/characters/ghost.png","kind":"character","bytes":22933,"description":"Ghost character with translucent appearance sprite sheet image (frame size 112x128)","animation":"characters/ghost.json","frameWidth":112,"frameHeight":128},{"name":"goblin","file":"characters/goblin.png","url":"incanto/assets/characters/goblin.png","kind":"character","bytes":57994,"description":"Medieval goblin with torch sprite sheet image (frame size 192x192)","animation":"characters/goblin.json","frameWidth":192,"frameHeight":192},{"name":"gold","file":"items/gold.png","url":"incanto/assets/items/gold.png","kind":"item","bytes":22313,"description":"Gold item sprite for Dungeons and Dungeoners. Gold pile or gold bar sprite representing valuable currency or treasure reward."},{"name":"gold-loot","file":"audio/gold_loot.mp3","url":"incanto/assets/audio/gold_loot.mp3","kind":"audio","bytes":7506,"description":"Metallic coin / gold pickup jingle — collecting currency."},{"name":"ground_dirt","file":"vegetation/ground/dirt_color.jpg","url":"https://agent8-games.verse8.io/assets/3D/default/textures/vegetation/ground/dirt_color.jpg","kind":"foliage","bytes":231383,"description":"Dense dirt/gravel ground texture (1024px) from the ez-tree demo app (MIT) — the reference meadow ground. Terrain3D grassland themes tile it for slope + noise-patch dirt by default; also bundled in `incanto/assets` (see `file`) for offline use."},{"name":"ground_dirt_normal","file":"vegetation/ground/dirt_normal.jpg","url":"https://agent8-games.verse8.io/assets/3D/default/textures/vegetation/ground/dirt_normal.jpg","kind":"foliage","bytes":123478,"description":"Dirt ground normal map (1024px) from the ez-tree demo app (MIT). Terrain3D grassland themes apply it across the whole ground band (demo parity); also bundled in `incanto/assets` (see `file`) for offline use."},{"name":"ground_grass","file":"vegetation/ground/grass.jpg","url":"https://agent8-games.verse8.io/assets/3D/default/textures/vegetation/ground/grass.jpg","kind":"foliage","bytes":322486,"description":"Mossy meadow grass ground texture (1024px) from the ez-tree demo app (MIT). Terrain3D grassland themes (meadow/forest generators) tile it as the grass splat layer by default; also bundled in `incanto/assets` (see `file`) for offline use."},{"name":"heal","file":"audio/heal.mp3","url":"incanto/assets/audio/heal.mp3","kind":"audio","bytes":29764,"description":"Soothing health-restore / heal spell SFX."},{"name":"hit-metal-bang","file":"audio/hit_metal_bang.mp3","url":"incanto/assets/audio/hit_metal_bang.mp3","kind":"audio","bytes":17972,"description":"Metallic impact — hitting armor, metal, or a blocked attack."},{"name":"hp_potion","file":"items/hp_potion.png","url":"incanto/assets/items/hp_potion.png","kind":"item","bytes":3513,"description":"Health potion item sprite for Dungeons and Dungeoners. Consumable healing item that restores player health points when used."},{"name":"ice-spear","file":"audio/ice_spear.mp3","url":"incanto/assets/audio/ice_spear.mp3","kind":"audio","bytes":21315,"description":"Sharp piercing ice projectile fire SFX."},{"name":"leaves_ash","file":"vegetation/ash_color.png","url":"https://agent8-games.verse8.io/assets/3D/default/textures/vegetation/ash_color.png","kind":"foliage","bytes":181423,"description":"Ash leaf-cluster alpha-cutout texture (1024px) from ez-tree by Dan Greenheck (MIT). Tree3D samples it for broadleaf/dead ash variants by default; copy it next to your game and set leafTexture to serve offline."},{"name":"leaves_aspen","file":"vegetation/aspen_color.png","url":"https://agent8-games.verse8.io/assets/3D/default/textures/vegetation/aspen_color.png","kind":"foliage","bytes":142116,"description":"Aspen leaf-cluster alpha-cutout texture (1024px) from ez-tree by Dan Greenheck (MIT). Tree3D samples it for high-tier broadleaf aspen variants; copy + leafTexture for offline serving."},{"name":"leaves_oak","file":"vegetation/oak_color.png","url":"https://agent8-games.verse8.io/assets/3D/default/textures/vegetation/oak_color.png","kind":"foliage","bytes":238115,"description":"Oak leaf-cluster alpha-cutout texture (1024px) from ez-tree by Dan Greenheck (MIT). Tree3D samples it for broadleaf oak variants by default; copy + leafTexture for offline serving."},{"name":"leaves_pine","file":"vegetation/pine_color.png","url":"https://agent8-games.verse8.io/assets/3D/default/textures/vegetation/pine_color.png","kind":"foliage","bytes":303684,"description":"Pine needle-cluster alpha-cutout texture (1024px) from ez-tree by Dan Greenheck (MIT). Tree3D samples it for conifer variants by default; copy + leafTexture for offline serving."},{"name":"locked_item_box","file":"items/locked_item_box.png","url":"incanto/assets/items/locked_item_box.png","kind":"item","bytes":11074,"description":"Locked item box sprite for Dungeons and Dungeoners. Container sprite requiring key or lockpick to open, containing valuable rewards."},{"name":"map","file":"items/map.png","url":"incanto/assets/items/map.png","kind":"item","bytes":3754,"description":"Map item sprite for Dungeons and Dungeoners. Navigation item revealing dungeon layout or providing exploration assistance."},{"name":"medieval-knight","file":"characters/medieval-knight.png","url":"incanto/assets/characters/medieval-knight.png","kind":"character","bytes":84367,"description":"(frame size 192x192) Using a medieval-themed SD(Super Deformed) knight sprite sheet image, you can apply idle, move, and attack animations, among others.","animation":"characters/medieval-knight.json","frameWidth":192,"frameHeight":192},{"name":"minecraft-tiles","file":"tiles/minecraft-tiles.png","url":"incanto/assets/tiles/minecraft-tiles.png","kind":"tile","bytes":10511,"description":"Minecraft-themed tiles sprite sheet image (frame size 16x16)"},{"name":"monster-died","file":"audio/monster_died.mp3","url":"incanto/assets/audio/monster_died.mp3","kind":"audio","bytes":16836,"description":"Enemy defeat / death SFX."},{"name":"resurrection_potion","file":"items/resurrection_potion.png","url":"incanto/assets/items/resurrection_potion.png","kind":"item","bytes":3471,"description":"Resurrection potion item sprite for Dungeons and Dungeoners. Rare consumable that revives fallen party members or prevents death."},{"name":"slash","file":"audio/slash.mp3","url":"incanto/assets/audio/slash.mp3","kind":"audio","bytes":10425,"description":"Quick sword swing / melee slash SFX."},{"name":"smite","file":"audio/smite.mp3","url":"incanto/assets/audio/smite.mp3","kind":"audio","bytes":12956,"description":"Powerful holy downward-strike SFX."},{"name":"spells-cast","file":"audio/spells_cast.mp3","url":"incanto/assets/audio/spells_cast.mp3","kind":"audio","bytes":22151,"description":"Generic magical spell-cast / chant SFX."},{"name":"super_box","file":"items/super_box.png","url":"incanto/assets/items/super_box.png","kind":"item","bytes":12184,"description":"Super item box sprite for Dungeons and Dungeoners. Premium container sprite containing rare or powerful items and equipment."},{"name":"swoosh","file":"effects/swoosh.png","url":"incanto/assets/effects/swoosh.png","kind":"effect","bytes":2599,"description":"Swoosh effect sprite for Dungeons and Dungeoners. Motion blur or attack trail effect used for melee attacks, sword slashes, or fast movement animations."},{"name":"trap","file":"items/trap.png","url":"incanto/assets/items/trap.png","kind":"item","bytes":3969,"description":"Trap object sprite for Dungeons and Dungeoners. Hazard sprite that damages players when triggered in dungeon exploration."},{"name":"ui-click","file":"audio/ui_click.wav","url":"incanto/assets/audio/ui_click.wav","kind":"audio","bytes":17332,"description":"Short tactile UI click for menus and buttons."},{"name":"walk","file":"audio/walk.mp3","url":"incanto/assets/audio/walk.mp3","kind":"audio","bytes":5642,"description":"Single footstep SFX for character movement (loop or one-shot)."},{"name":"wall00","file":"tiles/wall00.jpg","url":"incanto/assets/tiles/wall00.jpg","kind":"tile","bytes":44344,"description":"Basic wall tile texture for Dungeons and Dungeoners project, suitable for dungeon vertical boundaries."}]');function RL(e){let t=e.connections;return Array.isArray(t)?t:[]}function zL(e,t){if(!e||t===``)return null;if(t===`.`)return[];if(t.startsWith(`%`)){let n=t.slice(1);if(n===``||n.includes(`/`))return null;let r=[],i=(e,t)=>{e.name===n&&r.push(t),(e.children??[]).forEach((e,n)=>{i(e,[...t,n])})};return i(e,[]),r.length===1?r[0]:null}let n=t.startsWith(`/`),r=(n?t.slice(1):t).split(`/`);if(r.some(e=>e===``))return null;let i=r;if(n){if(r[0]!==e.name&&r[0]!==`root`)return null;i=r.slice(1)}let a=[],o=e;for(let t of i){if(t===`..`){if(a.length===0)return null;a.pop(),o=BL(e,a);continue}let n=(o.children??[]).findIndex(e=>e.name===t);if(n===-1)return null;a.push(n),o=o.children?.[n]}return a}function BL(e,t){let n=e;for(let e of t)n=n?.children?.[e];return n??null}function VL(e,t){if(!e)return``;if(t.length===0)return`.`;let n=[],r=e;for(let e of t){let t=r.children?.[e];if(!t)return``;n.push(String(t.name??``)),r=t}return n.join(`/`)}function HL(e,t){let n=e.root,r=e=>{if(typeof e!=`string`)return!1;let r=zL(n,e);return r!==null&&r.length===t.length&&r.every((e,n)=>e===t[n])},i=[],a=[];return RL(e).forEach((e,t)=>{r(e.from)&&i.push({index:t,conn:e}),r(e.to)&&a.push({index:t,conn:e})}),{outgoing:i,incoming:a}}function UL(e){if(!e)return[];let t=[];if(typeof e.type==`string`&&e.type!==``)try{t.push(...Ye(e.type))}catch{}let n=e.script;return typeof n?.name==`string`&&t.push(...st(n.name)),[...new Set(t)]}function WL(e){if(!e||e.script?.name)return[];let t=typeof e.type==`string`?e.type:``;if(!t)return[];let n=null;try{n=Ge(t)}catch{return[]}let r=new Set;for(let e=n.prototype;e&&e!==Object.prototype;){for(let t of Object.getOwnPropertyNames(e))t===`constructor`||t.startsWith(`_`)||typeof Object.getOwnPropertyDescriptor(e,t)?.value==`function`&&r.add(t);e=Object.getPrototypeOf(e)}for(let e of GL)r.delete(e);return[...r].sort()}var GL=new Set([`addChild`,`removeChild`,`addToGroup`,`removeFromGroup`,`isInGroup`,`getNode`,`getNodeOrNull`,`getPath`,`getRoot`,`find`,`findAll`,`on`,`off`,`once`,`emit`,`declareSignal`,`update`,`fixedUpdate`,`toJSON`,`diagnose`]);function KL(e){if(!e)return[];let t=[{path:`.`,label:`${e.name} (root)`}],n=(r,i)=>{(r.children??[]).forEach((r,a)=>{let o=[...i,a];t.push({path:VL(e,o),label:VL(e,o)}),n(r,o)})};return n(e,[]),t}function qL(e,t){Array.isArray(e.connections)||(e.connections=[]);let n=e.connections;return n.push(t),n.length-1}function JL(e,t,n){let r=RL(e)[t];r&&Object.assign(r,n)}function YL(e,t){let n=RL(e);t<0||t>=n.length||(n.splice(t,1),n.length===0&&delete e.connections)}function XL(e,t){let n=e.working.root;if(!n)return null;let r=e.nodeAt(t);if(!r)return null;let i=document.createElement(`div`);i.className=`connections`;let{outgoing:a,incoming:o}=HL(e.working,t),s=VL(n,t);i.appendChild(ZL(XP({en:`emits (${a.length})`,ko:`보냄 (${a.length})`})));for(let t of a)i.appendChild(QL(e,t,`out`));if(i.appendChild($L(e,r,s)),o.length>0){i.appendChild(ZL(XP({en:`receives (${o.length})`,ko:`받음 (${o.length})`})));for(let t of o)i.appendChild(QL(e,t,`in`))}return i}function ZL(e){let t=document.createElement(`div`);return t.className=`conn-group`,t.textContent=e,t}function QL(e,{index:t,conn:n},r){let i=e.working.root,a=document.createElement(`div`);a.className=`conn-row`;let o=e.nodeAt(zL(i,String(n.from??``))??[-1]),s=r===`out`?`to`:`from`,c=String(n[s]??``),l=zL(i,c)===null,u=eR(UL(o),String(n.signal??``),n=>{e.mutate(()=>JL(e.working,t,{signal:n}))});u.title=XP({en:`signal`,ko:`시그널`});let d=document.createElement(`span`);d.className=`conn-arrow`,d.textContent=r===`out`?`→`:`←`;let f=eR(KL(i).map(e=>e.path),c,n=>{e.mutate(()=>JL(e.working,t,{[s]:n}))});f.title=XP({en:s,ko:s===`to`?`대상`:`출처`}),l&&f.classList.add(`dangling`);let p=WL(e.nodeAt(zL(i,String(n.to??``))??[-1])),m=n=>{e.mutate(()=>JL(e.working,t,{handler:n.trim()}))},h;if(p.length>0){let e=eR(p,String(n.handler??``),m);e.title=XP({en:`handler method`,ko:`핸들러 메서드`}),h=e}else{let e=document.createElement(`input`);e.type=`text`,e.className=`conn-handler`,e.value=String(n.handler??``),e.placeholder=`onSomething`,e.title=XP({en:`handler method on the target (defined in your behavior)`,ko:`대상의 핸들러 메서드 (비헤이비어에 정의)`}),e.addEventListener(`change`,()=>m(e.value)),h=e}let g=document.createElement(`button`);if(g.type=`button`,g.className=`conn-remove`,g.textContent=`✕`,g.title=XP({en:`remove this connection`,ko:`이 연결 삭제`}),g.addEventListener(`click`,()=>{e.mutate(()=>YL(e.working,t))}),a.append(u,d,f,h,g),l){let e=document.createElement(`div`);e.className=`conn-warn`,e.textContent=XP({en:`'${c}' does not resolve — the game will refuse to load this scene.`,ko:`'${c}' 을(를) 찾을 수 없습니다 — 게임이 이 씬을 열지 못합니다.`});let t=document.createElement(`div`);return t.append(a,e),t}return a}function $L(e,t,n){let r=UL(t),i=document.createElement(`div`);i.className=`conn-add`;let a=document.createElement(`button`);return a.type=`button`,a.textContent=XP({en:`+ connect`,ko:`+ 연결`}),a.disabled=r.length===0,r.length===0&&(a.title=XP({en:`this node declares no signals`,ko:`이 노드는 시그널을 선언하지 않습니다`})),a.addEventListener(`click`,()=>{let i=r[0]??``,a={from:n,signal:i,to:n,handler:WL(t)[0]??`on${i.charAt(0).toUpperCase()}${i.slice(1)}`};e.mutate(()=>{qL(e.working,a)})}),i.appendChild(a),i}function eR(e,t,n){let r=document.createElement(`select`);r.className=`conn-select`;for(let n of e.includes(t)?e:[t,...e]){let e=document.createElement(`option`);e.value=n,e.textContent=n===``?`—`:n,n===t&&(e.selected=!0),r.appendChild(e)}return r.addEventListener(`change`,()=>n(r.value)),r}function tR(e,t,n,r){return{cx:Math.floor((n-e.x)/t),cy:Math.floor((r-e.y)/t)}}function nR(e,t,n,r){if(t<0||n<0||r.length!==1)return null;let i=e.map(e=>typeof e==`string`?e:e.map(e=>e>=0&&e<=9?String(e):`.`).join(``)),a=Math.max(t+1,...i.map(e=>e.length)),o=Math.max(n+1,i.length),s=[];for(let e=0;e<o;e++){let o=i[e]??``;o=o.padEnd(a,`.`),e===n&&(o=o.slice(0,t)+r+o.slice(t+1)),s.push(o)}return s}function rR(e,t){let n=new Set([`.`,`0`,`1`]);for(let t of e)if(typeof t==`string`)for(let e of t)e!==` `&&n.add(e);for(let e of Object.keys(t))n.add(e);return[...n]}var iR=LL;function aR(e){return(e.kind===`foliage`||e.kind===`tile`)&&!e.animation}function oR(e,t,n){if(e.textContent=``,t.selection===null){cR(e,t,n);return}let r=t.nodeAt(t.selection);r&&_R(e,t,r,n)}var sR=[`connections`,`input`,`multiplayer`];function cR(e,t,n){e.appendChild(UR(`scene`)),e.appendChild(YR(`name`,String(t.working.name??``),e=>{t.mutate(()=>{t.working.name=e})}));let r=document.createElement(`select`);for(let e of[`2d`,`3d`]){let n=document.createElement(`option`);n.value=e,n.textContent=e,(t.working.dimension??`2d`)===e&&(n.selected=!0),r.appendChild(n)}r.addEventListener(`change`,()=>{t.mutate(()=>{t.working.dimension=r.value})}),e.appendChild(GR(`dimension`,r)),e.appendChild(UR(`physics`,`physics`));let i=(t.working.physics??{}).gravity??(t.working.dimension===`3d`?[0,-9.81,0]:[0,980]),a=t.working.dimension===`3d`?[0,-9.81,0]:[0,980];e.appendChild(ZR(`gravity`,i,e=>{t.mutate(()=>{if(JSON.stringify(e)===JSON.stringify(a)){let e={...t.working.physics};delete e.gravity,Object.keys(e).length===0?delete t.working.physics:t.working.physics=e}else t.working.physics={...t.working.physics,gravity:e}})})),e.appendChild(UR(`environment`)),lR(e,t),e.appendChild(UR(`constants`)),LR(e,t,n),e.appendChild(UR(`draw order bands`)),IR(e,t),e.appendChild(UR(`advanced`));for(let n of sR)e.appendChild($R(n,t.working[n],e=>{t.mutate(()=>{e===void 0?delete t.working[n]:t.working[n]=e})}))}function lR(e,t){let n=t.working.environment??{},r=e=>{t.mutate(()=>{let n={...t.working.environment??{},...e};for(let e of Object.keys(n))n[e]===void 0&&delete n[e];Object.keys(n).length===0?delete t.working.environment:t.working.environment=n})};e.appendChild(uR(`background`,n.background??``,e=>{r({background:e===``?void 0:e})})),e.appendChild(uR(`ambient color`,n.ambient?.color??``,e=>{let t={...n.ambient,color:e===``?void 0:e};t.color===void 0&&delete t.color,r({ambient:Object.keys(t).length?t:void 0})})),e.appendChild(XR(`ambient power`,n.ambient?.intensity??0,e=>{r({ambient:{...n.ambient,intensity:e}})}));let i=n.rendering??{},a=e=>{let t={...i,...e};for(let e of Object.keys(t))t[e]===void 0&&delete t[e];r({rendering:Object.keys(t).length?t:void 0})},o=document.createElement(`input`);o.type=`checkbox`,o.checked=i.antialias!==!1,o.addEventListener(`change`,()=>{a({antialias:o.checked?void 0:!1})}),e.appendChild(GR(`antialias`,o));let s=document.createElement(`select`);for(let[e,t]of[[``,`1 — soft hiDPI upscale (default)`],[`device`,`device — crisp retina`],[`2`,`2`]]){let n=document.createElement(`option`);n.value=e,n.textContent=t,String(i.pixelRatio??``)===e&&(n.selected=!0),s.appendChild(n)}s.addEventListener(`change`,()=>{a({pixelRatio:s.value===``?void 0:s.value===`device`?`device`:Number(s.value)})}),e.appendChild(GR(`pixel ratio`,s))}function uR(e,t,n){let r=document.createElement(`div`);r.className=`color-row`;let i=document.createElement(`input`);i.type=`color`,i.value=/^#[0-9a-fA-F]{6}$/.test(t)?t:`#000000`;let a=document.createElement(`input`);return a.type=`text`,a.className=`mono`,a.placeholder=`unset`,a.value=t,i.addEventListener(`input`,()=>{a.value=i.value}),i.addEventListener(`change`,()=>n(i.value)),a.addEventListener(`change`,()=>n(a.value.trim())),r.append(i,a),GR(e,r)}function dR(e,t){let n=document.createElement(`div`);n.className=`subcard`;let r=document.createElement(`div`);r.className=`subcard-head`,r.textContent=`underwater`,n.appendChild(r);let i=t.props?.underwater,a=i!==!1,o=i&&typeof i==`object`&&!Array.isArray(i)?i:{},s=n=>{e.mutate(()=>{t.props||={},n===!0?delete t.props.underwater:t.props.underwater=n,Object.keys(t.props).length===0&&delete t.props})},c=(e,t)=>{let n={...o};t===void 0||t===``?delete n[e]:n[e]=t,s(Object.keys(n).length===0?!0:n)},l=document.createElement(`input`);if(l.type=`checkbox`,l.checked=a,l.addEventListener(`change`,()=>s(l.checked)),n.appendChild(GR(`enabled`,l)),a){n.appendChild(uR(`murk color`,String(o.color??``),e=>c(`color`,e))),n.appendChild(XR(`visibility (m)`,Number(o.visibility??22),e=>c(`visibility`,e===22?void 0:e),()=>c(`visibility`,void 0)));let e=document.createElement(`input`);e.type=`checkbox`,e.checked=(o.caustics??!0)!==!1,e.addEventListener(`change`,()=>c(`caustics`,e.checked?void 0:!1)),n.appendChild(GR(`caustics`,e))}return n}function fR(e,t,n){let r=document.createElement(`div`);r.className=`subcard`;let i=document.createElement(`div`);i.className=`subcard-head`,i.textContent=`material`,r.appendChild(i);let a=t.props?.material??{},o=(n,r)=>{let i={...t.props?.material??{}};r===void 0||r===``?delete i[n]:i[n]=r;let a=Object.keys(i).length===0?void 0:i;e.mutate(()=>{t.props||={},a===void 0?(delete t.props.material,Object.keys(t.props).length===0&&delete t.props):t.props.material=a},e.selection?{path:e.selection,key:`material`,value:a}:void 0)};r.appendChild(uR(`color`,String(a.color??``),e=>o(`color`,e))),r.appendChild(gR(`roughness`,Number(a.roughness??1),e=>o(`roughness`,e))),r.appendChild(gR(`metalness`,Number(a.metalness??0),e=>o(`metalness`,e))),r.appendChild(uR(`emissive`,String(a.emissive??``),e=>o(`emissive`,e))),r.appendChild(gR(`emissive power`,Number(a.emissiveIntensity??1),e=>o(`emissiveIntensity`,e===1?void 0:e),2)),r.appendChild(gR(`opacity`,Number(a.opacity??1),e=>o(`opacity`,e===1?void 0:e))),r.appendChild(gR(`clearcoat`,Number(a.clearcoat??0),e=>o(`clearcoat`,e===0?void 0:e))),r.appendChild(gR(`clearcoat rough`,Number(a.clearcoatRoughness??0),e=>o(`clearcoatRoughness`,e===0?void 0:e))),r.appendChild(gR(`reflection`,Number(a.envMapIntensity??1),e=>o(`envMapIntensity`,e===1?void 0:e),3));let s=document.createElement(`input`);s.type=`checkbox`,s.checked=a.wireframe===!0,s.addEventListener(`change`,()=>o(`wireframe`,s.checked||void 0)),r.appendChild(GR(`wireframe`,s));let c=document.createElement(`input`);c.type=`checkbox`,c.checked=a.flatShading===!0,c.addEventListener(`change`,()=>o(`flatShading`,c.checked||void 0)),r.appendChild(GR(`flatShading`,c));let l=document.createElement(`input`);l.type=`checkbox`,l.checked=a.depthTest===!1,l.addEventListener(`change`,()=>{o(`depthTest`,l.checked?!1:void 0),o(`depthWrite`,l.checked?!1:void 0)}),r.appendChild(GR(`draw on top (decal)`,l)),r.appendChild(DR(`map (texture)`,String(a.map??``),OR(e=>aR(e)&&!e.name.includes(`normal`)&&!e.name.includes(`roughness`)),e=>o(`map`,e.trim()),{placeholder:`built-in or custom URL`,library:{kind:`image`,target:`map`,shelf:[`3d`,`textures`]},ctx:n})),r.appendChild(DR(`normal map`,String(a.normalMap??``),OR(e=>aR(e)&&e.name.includes(`normal`)),e=>o(`normalMap`,e.trim()),{placeholder:`built-in or custom URL`,library:{kind:`image`,target:`normal map`,shelf:[`3d`,`textures`]},ctx:n}));let u=!!(a.map||a.normalMap),d=Array.isArray(a.repeat)?a.repeat:[1,1],f=ZR(`repeat [u,v]`,[d[0]??1,d[1]??1],e=>{let[t,n]=e;!Number.isFinite(t)||!Number.isFinite(n)||t===1&&n===1||!t&&!n?o(`repeat`,void 0):o(`repeat`,[t,n])});return f.title=u?`Texture tiling across the mesh UVs.`:`Only takes effect with a map/normal map set (engine validates).`,r.appendChild(f),r}var pR=new Set([`animationLoop`,`animationSpeed`,`animationOffset`,`animationUpper`,`animationUpperLoop`,`upperBodyRoot`]);function mR(e,t,n,r){let i=document.createElement(`div`);i.className=`subcard anim-card`;let a=document.createElement(`div`);a.className=`subcard-head`;let o=document.createElement(`strong`);o.textContent=`animation`,a.appendChild(o),i.appendChild(a);let s=String(t.props?.animation??``);if(i.appendChild(DR(`clip`,s,n.animationsForSelection().map(e=>({label:e,value:e,hint:e.startsWith(`$`)?`scene asset`:`clip in this model`})),n=>CR(e,t,`animation`,n.trim(),``),{placeholder:`clip name or $assetKey — empty = still`,library:{kind:`model`,target:`animation`,shelf:[`3d`,`animations`],asAsset:!0,assetType:`animation`},ctx:n})),!s){let a=document.createElement(`div`);return a.className=`muted-note`,a.textContent=`Pick a clip and it plays as soon as the scene loads — no script needed.`,i.appendChild(a),i.appendChild(hR(e,t,n,r)),i}i.appendChild(zR(e,t,`animationLoop`,r.animationLoop?.default??!0,void 0,`loop`));let c=gR(`speed`,Number(t.props?.animationSpeed??1),n=>CR(e,t,`animationSpeed`,n,1),3,-3);c.title=`1 = as authored · 0 freezes the pose · negative plays backwards (a closing door is an opening one reversed).`,i.appendChild(c);let l=zR(e,t,`animationOffset`,r.animationOffset?.default??0,void 0,`offset (s)`);return l.title=`Seconds into the clip to start at. Give copies different offsets so a row of torches stops flickering in lockstep.`,i.appendChild(l),i.appendChild(hR(e,t,n,r)),i}function hR(e,t,n,r){let i=document.createElement(`details`);i.className=`anim-upper`,t.props?.animationUpper&&(i.open=!0);let a=document.createElement(`summary`);return a.textContent=`upper-body layer`,a.title=`Play a second clip on the upper body only — attack while running, wave while walking.`,i.appendChild(a),i.appendChild(DR(`clip`,String(t.props?.animationUpper??``),n.animationsForSelection().map(e=>({label:e,value:e})),n=>CR(e,t,`animationUpper`,n.trim(),``),{placeholder:`empty = off`,ctx:n})),i.appendChild(zR(e,t,`animationUpperLoop`,r.animationUpperLoop?.default??!1,void 0,`loop`)),i.appendChild(zR(e,t,`upperBodyRoot`,r.upperBodyRoot?.default??`Spine`,void 0,`root bone`)),i}function gR(e,t,n,r=1,i=0){let a=document.createElement(`div`);a.className=`slider-row`;let o=document.createElement(`input`);o.type=`range`,o.min=String(i),o.max=String(r),o.step=`0.05`,o.value=String(Number.isFinite(t)?t:0);let s=document.createElement(`input`);return s.type=`number`,s.step=`0.05`,s.min=String(i),s.max=String(r),s.value=o.value,o.addEventListener(`input`,()=>{s.value=o.value}),o.addEventListener(`change`,()=>n(Number(o.value))),s.addEventListener(`change`,()=>{o.value=s.value,n(Number(s.value))}),a.append(o,s),GR(e,a)}function _R(e,t,n,r){if(e.appendChild(UR(n.type??`instance`)),e.appendChild(vR(n)),e.appendChild(YR(`name`,n.name??``,e=>{e.trim()===``||t.selection===null||t.renameNode(t.selection,e.trim())})),n.type===`TileMap2D`&&r?.paint&&e.appendChild(QR(n,r.paint)),n.type){let i;try{i=qe(n.type)}catch{i={}}for(let[a,o]of Object.entries(i))if(a===`collider`)e.appendChild(SR(t,n,o.default));else if(a===`material`)e.appendChild(fR(t,n,r));else if(n.type===`ModelInstance3D`&&a===`model`&&r)e.appendChild(DR(`model`,String(n.props?.model??``),r.modelRefs().map(e=>({label:e,value:e,hint:`scene asset`})),e=>CR(t,n,`model`,e.trim(),``),{placeholder:`$assetKey`,library:{kind:`model`,target:`model`,shelf:[`3d`,`characters`],asAsset:!0},ctx:r}));else if(n.type===`BoneAttachment3D`&&a===`bone`&&r?.bonesForSelection)e.appendChild(TR(`bone`,String(n.props?.bone??``),r.bonesForSelection(String(n.props?.target??``)),e=>CR(t,n,`bone`,e,``)));else if(n.type===`ModelInstance3D`&&a===`animation`&&r)e.appendChild(mR(t,n,r,i));else if(!(n.type===`ModelInstance3D`&&pR.has(a)))if((n.type===`Sprite3D`||n.type===`AnimatedSprite3D`)&&(a===`texture`||a===`sheet`))e.appendChild(DR(a===`sheet`?`sheet (image URL)`:`texture (image URL)`,String(n.props?.[a]??``),OR(e=>e.kind===`character`||e.kind===`item`),e=>CR(t,n,a,e.trim(),``),{placeholder:`image URL — empty hides the sprite`,library:{kind:`image`,target:a,shelf:[`2d`,`sprite_characters`]},ctx:r}));else if(n.type===`TileMap2D`&&a===`texture`)e.appendChild(DR(`texture (atlas $ref)`,String(n.props?.texture??``),(r?.assetRefs?.([`texture`,`spritesheet`])??[]).map(e=>({label:e,value:e,hint:`scene asset`})),e=>CR(t,n,`texture`,e.trim(),``),{placeholder:`$assetKey`,library:{kind:`image`,target:`tile atlas`,shelf:[`2d`,`sprite_characters`],asAsset:!0,assetType:`texture`},ctx:r}));else if(n.type===`Tree3D`&&a===`leafTexture`)e.appendChild(DR(`leaf texture`,String(n.props?.leafTexture??``),OR(e=>e.name.startsWith(`leaves_`)),e=>CR(t,n,`leafTexture`,e.trim(),``),{placeholder:`default (per-type) or URL`,library:{kind:`image`,target:`leaf texture`,shelf:[`3d`,`textures`]},ctx:r}));else if(n.type===`Terrain3D`&&a===`textureBase`)e.appendChild(DR(`texture base`,String(n.props?.textureBase??o.default??``),AR,e=>CR(t,n,`textureBase`,e.trim(),o.default),{placeholder:`splat texture base URL`}));else if(n.type===`AnimatedSprite2D`&&a===`sheet`||n.type===`Sprite2D`&&a===`texture`){let i=a===`sheet`;e.appendChild(jR(t,n,a,r,i))}else n.type===`AudioPlayer`&&a===`src`?e.appendChild(DR(`src (audio file)`,String(n.props?.src??``),kR(),e=>CR(t,n,`src`,e.trim(),``),{placeholder:`built-in or custom URL — or use preset`,note:"For zero-asset SFX, set the `preset` prop instead of src.",library:{kind:`audio`,target:`audio src`},ctx:r})):n.type===`Flowers3D`&&a===`varieties`?e.appendChild(MR(t,n)):n.type===`Water3D`&&a===`underwater`?e.appendChild(dR(t,n)):e.appendChild(zR(t,n,a,o.default,o.options))}if(e.appendChild(UR(`structure`)),e.appendChild(yR(t,n)),e.appendChild(bR(t,n)),e.appendChild(xR(t,n)),t.selection){let n=XL(t,t.selection);n&&(e.appendChild(UR(`connections`,`connections`)),e.appendChild(n))}}function vR(e){let t=document.createElement(`div`);t.className=`field uid-line`;let n=document.createElement(`span`);n.textContent=`uid`;let r=document.createElement(`div`);r.className=`uid-value`;let i=document.createElement(`code`);i.textContent=String(e.uid??``);let a=document.createElement(`button`);return a.type=`button`,a.className=`uid-copy`,a.title=`Copy uid`,a.innerHTML=`<svg aria-hidden="true" width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>`,a.addEventListener(`click`,()=>{navigator.clipboard?.writeText(String(e.uid??``)),a.classList.add(`copied`),a.innerHTML=`✓`,setTimeout(()=>{a.classList.remove(`copied`),a.innerHTML=`<svg aria-hidden="true" width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>`},800)}),r.append(i,a),t.append(n,r),t}function yR(e,t){let n=document.createElement(`label`);n.className=`field wide`;let r=document.createElement(`span`);r.append(`groups `,IL(`groups`));let i=document.createElement(`div`);i.className=`chips`;for(let n of t.groups??[])i.appendChild(WR(n,()=>{e.mutate(()=>{t.groups=(t.groups??[]).filter(e=>e!==n),t.groups.length===0&&delete t.groups})}));let a=document.createElement(`input`);return a.placeholder=(t.groups?.length??0)===0?`add a tag… (e.g. coins)`:``,a.addEventListener(`keydown`,n=>{if(n.key!==`Enter`)return;let r=a.value.trim();r&&e.mutate(()=>{t.groups=[...t.groups??[],r]})}),i.appendChild(a),i.addEventListener(`click`,()=>a.focus()),n.append(r,i),n}function bR(e,t){let n=document.createElement(`div`);n.className=`subcard`;let r=document.createElement(`div`);r.className=`subcard-head`,r.append(`script `,IL(`script`));let i=document.createElement(`span`);i.className=`spacer`,r.appendChild(i);let a=t.script;if(a){let n=document.createElement(`button`);n.type=`button`,n.className=`linklike`,n.textContent=`detach`,n.addEventListener(`click`,()=>{e.mutate(()=>{delete t.script})}),r.appendChild(n)}if(n.appendChild(r),!a){let r=document.createElement(`div`);r.className=`muted-note`,r.textContent=`No behavior attached. Behaviors are TypeScript classes in your game.`;let i=document.createElement(`button`);return i.type=`button`,i.className=`ghost`,i.textContent=`+ attach behavior`,i.addEventListener(`click`,()=>{e.mutate(()=>{t.script={name:`MyBehavior`}})}),n.append(r,i),n}n.appendChild(YR(`name`,a.name??``,n=>{e.mutate(()=>{t.script.name=n.trim()})})),n.appendChild($R(`props`,a.props,n=>{e.mutate(()=>{n===void 0?delete t.script.props:t.script.props=n})}));let o=document.createElement(`div`);return o.className=`muted-note`,o.textContent=`? has copy-paste boilerplate for the game side.`,n.appendChild(o),n}function xR(e,t){let n=document.createElement(`div`);n.className=`subcard`;let r=document.createElement(`div`);r.className=`subcard-head`,r.append(`network `,IL(`network`)),n.appendChild(r);let i=t.network,a=document.createElement(`select`);for(let[e,t]of[[``,`not replicated`],[`owner`,`owner — this player broadcasts it`]]){let n=document.createElement(`option`);n.value=e,n.textContent=t,(i?.mode??``)===e&&(n.selected=!0),a.appendChild(n)}if(a.addEventListener(`change`,()=>{e.mutate(()=>{a.value===``?delete t.network:t.network={mode:a.value,sync:i?.sync??[`position`]}})}),n.appendChild(GR(`mode`,a)),i?.mode===`owner`){let r=document.createElement(`div`);r.className=`chips`;for(let n of i.sync??[])r.appendChild(WR(n,()=>{e.mutate(()=>{t.network.sync=(i.sync??[]).filter(e=>e!==n)})}));let a=document.createElement(`input`);a.placeholder=`position · Skin.animation…`,a.addEventListener(`keydown`,n=>{if(n.key!==`Enter`)return;let r=a.value.trim();r&&e.mutate(()=>{t.network.sync=[...i.sync??[],r]})}),r.appendChild(a);let o=document.createElement(`label`);o.className=`field wide`;let s=document.createElement(`span`);s.textContent=`sync keys`,o.append(s,r),n.appendChild(o),n.appendChild(XR(`throttle ms`,i.throttleMs??50,n=>{e.mutate(()=>{t.network.throttleMs=n})}))}return n}function SR(e,t,n){let r=document.createElement(`div`);r.className=`subcard`;let i=document.createElement(`div`);i.className=`subcard-head`,i.append(`collider `,IL(`collider`)),r.appendChild(i);let a=t.props?.collider??{},o=n=>{e.mutate(()=>{t.props||={};let e=t.props;Object.keys(n).length===0?(delete e.collider,Object.keys(e).length===0&&delete t.props):e.collider=n})},s=(t.type??``).endsWith(`3D`),c=s?[[``,`none`],[`box`,`box — crates, floors`],[`sphere`,`sphere — balls, pickups`],[`capsule`,`capsule — characters`]]:[[``,`none`],[`rect`,`rect — boxes, platforms`],[`circle`,`circle — coins, balls`],[`capsule`,`capsule — characters`]],l=document.createElement(`select`);for(let[e,t]of c){let n=document.createElement(`option`);n.value=e,n.textContent=t,(a.shape??``)===e&&(n.selected=!0),l.appendChild(n)}return l.addEventListener(`change`,()=>{l.value===``?o({}):l.value===`rect`?o({shape:`rect`,size:a.size??[32,32]}):l.value===`box`?o({shape:`box`,size:a.size??[1,1,1]}):l.value===`circle`?o({shape:`circle`,radius:a.radius??16}):l.value===`sphere`?o({shape:`sphere`,radius:a.radius??.5}):o(s?{shape:`capsule`,radius:a.radius??.4,height:a.height??1}:{shape:`capsule`,radius:a.radius??12,height:a.height??16})}),r.appendChild(GR(`shape`,l)),a.shape===`rect`||a.shape===`box`?r.appendChild(ZR(`size`,a.size??(s?[1,1,1]:[32,32]),e=>o({...a,size:e}))):a.shape===`circle`||a.shape===`sphere`?r.appendChild(XR(`radius`,a.radius??(s?.5:16),e=>o({...a,radius:e}))):a.shape===`capsule`&&(r.appendChild(XR(`radius`,a.radius??12,e=>o({...a,radius:e}))),r.appendChild(XR(`height`,a.height??16,e=>o({...a,height:e})))),a.shape&&r.appendChild(ZR(`offset`,a.offset??(s?[0,0,0]:[0,0]),e=>o({...a,offset:e}))),r}function CR(e,t,n,r,i){e.mutate(()=>{t.props||={},JSON.stringify(r)===JSON.stringify(i)?(delete t.props[n],Object.keys(t.props).length===0&&delete t.props):t.props[n]=r})}var wR=0;function TR(e,t,n,r){let i=document.createElement(`input`);i.type=`text`,i.value=t;let a=`suggest-${wR++}`;i.setAttribute(`list`,a);let o=document.createElement(`datalist`);o.id=a;for(let e of n){let t=document.createElement(`option`);t.value=e,o.appendChild(t)}i.addEventListener(`change`,()=>r(i.value.trim()));let s=GR(e,i);return s.appendChild(o),s}var ER=0;function DR(e,t,n,r,i={}){let a=document.createElement(`label`);a.className=`field wide asset-field`;let o=document.createElement(`span`);o.textContent=e,a.appendChild(o);let s=document.createElement(`input`);s.type=`text`,s.value=t,i.placeholder&&(s.placeholder=i.placeholder),s.addEventListener(`change`,()=>r(s.value.trim()));let c=document.createElement(`button`);c.type=`button`,c.className=`asset-toggle`,c.title=`Browse built-in assets`,c.textContent=`▾`;let l=document.createElement(`div`);if(l.className=`asset-control`,l.append(s),i.library&&i.ctx?.openLibrary){let t=document.createElement(`button`);t.type=`button`,t.className=`asset-lib`,t.textContent=`📚`,t.title=`Browse the agent8 library for a ${i.library.kind}`,t.addEventListener(`click`,t=>{t.preventDefault();let n=i.ctx?.openLibrary;n&&n({kind:i.library?.kind??`any`,target:i.library?.target??e,...i.library?.shelf?{shelf:i.library.shelf}:{},...i.library?.asAsset?{asAsset:!0}:{},...i.library?.assetType?{assetType:i.library.assetType}:{},...i.library?.onProps?{onProps:i.library.onProps}:{}}).then(e=>{e!==null&&(s.value=e,r(e))})}),l.append(t)}l.append(c),a.appendChild(l);let u=document.createElement(`div`);u.className=`asset-panel`,u.hidden=!0;let d=document.createElement(`input`);d.type=`text`,d.className=`asset-search`,d.placeholder=`search ${n.length} built-in${n.length===1?``:`s`}…`;let f=document.createElement(`div`);f.className=`asset-options`,u.append(d,f),a.appendChild(u);let p=e=>{f.textContent=``;let t=e.trim().toLowerCase(),i=n.filter(e=>t===``||e.label.toLowerCase().includes(t)||(e.hint?.toLowerCase().includes(t)??!1)||e.value.toLowerCase().includes(t));if(i.length===0){let e=document.createElement(`div`);e.className=`asset-empty`,e.textContent=`no match — type a custom URL above`,f.appendChild(e);return}for(let e of i){let t=document.createElement(`button`);t.type=`button`,t.className=`asset-option`,t.title=[e.label,e.full??e.hint,e.value===e.label?null:e.value].filter(Boolean).join(`
|
|
8424
|
-
`);let n=document.createElement(`strong`);if(n.textContent=e.label,t.appendChild(n),e.hint){let n=document.createElement(`small`);n.textContent=e.hint,t.appendChild(n)}t.addEventListener(`click`,()=>{s.value=e.value,u.hidden=!0,r(e.value)}),f.appendChild(t)}};if(c.addEventListener(`click`,()=>{u.hidden=!u.hidden,u.hidden||(p(d.value),d.focus())}),d.addEventListener(`input`,()=>p(d.value)),d.addEventListener(`keydown`,e=>{e.key===`Escape`&&(u.hidden=!0)}),i.note){let e=document.createElement(`div`);e.className=`muted-note asset-note`,e.textContent=i.note,a.appendChild(e)}return s.id=`asset-input-${ER++}`,a.htmlFor=s.id,a}function OR(e){return iR.filter(e).map(e=>({label:e.name,value:e.url,hint:`${e.kind} · ${e.description}`,full:`${e.kind} · ${e.description}`}))}function kR(){return iR.filter(e=>e.kind===`audio`).map(e=>({label:e.name,value:e.url,hint:`audio · ${e.description}`,full:`audio · ${e.description}`}))}var AR=[{label:`agent8 default terrain`,value:`https://agent8-games.verse8.io/assets/3D/default/textures/terrain`,hint:`sand/grass/stone/snow splat set (Terrain3D default)`}];function jR(e,t,n,r,i){let a=String(t.props?.[n]??``),o=i?[`spritesheet`]:[`texture`,`spritesheet`],s=(r?.assetRefs?.(o)??[]).map(e=>({label:e,value:e,hint:`scene asset`})),c=iR.filter(e=>i?!!e.animation:e.kind===`character`||e.kind===`item`||e.kind===`tile`);for(let e of c)s.push({label:`built-in: ${e.name}`,value:`$${e.name}`,hint:`${e.kind} · creates a scene asset (${e.animation?`spritesheet`:`texture`})`});return DR(i?`sheet`:`texture`,a,s,i=>{let a=i.startsWith(`$`)&&c.find(e=>`$${e.name}`===i);if(a&&r?.addAsset){let i={type:a.animation?`spritesheet`:`texture`,url:a.url};if(a.animation){let e=a.frameWidth,t=a.frameHeight;e&&(i.frameWidth=e),t&&(i.frameHeight=t)}CR(e,t,n,`$${r.addAsset(a.name,i).replace(/^\$/,``)}`,``);return}CR(e,t,n,i.trim(),``)},{placeholder:`$assetKey`,note:"Picks a $asset ref. Built-ins create the scene asset; packaged sprites need `incanto-assets copy` (or a bundler import) to serve at runtime.",library:{kind:`image`,target:i?`sheet`:`texture`,shelf:[`2d`,`sprite_characters`],asAsset:!0,assetType:i?`spritesheet`:`texture`,onProps:n=>{for(let[r,i]of Object.entries(n))CR(e,t,r,i,void 0)}},ctx:r})}function MR(e,t){let n=document.createElement(`label`);n.className=`field wide`;let r=document.createElement(`span`);r.textContent=`varieties`,n.appendChild(r);let i=new Set(Array.isArray(t.props?.varieties)?t.props.varieties:[]),a=document.createElement(`div`);a.className=`chips varieties`;let o=()=>{let n=AD.filter(e=>i.has(e));CR(e,t,`varieties`,n.length===0||n.length===AD.length?[]:n,[])};for(let e of AD){let t=document.createElement(`label`);t.className=`variety-opt`;let n=document.createElement(`input`);n.type=`checkbox`,n.checked=i.size===0||i.has(e),n.addEventListener(`change`,()=>{if(i.size===0)for(let e of AD)i.add(e);n.checked?i.add(e):i.delete(e),o()});let r=document.createElement(`span`);r.textContent=e,t.append(n,r),a.appendChild(t)}n.appendChild(a);let s=document.createElement(`div`);return s.className=`muted-note`,s.textContent=`All (or none) = the default mix of all three.`,n.appendChild(s),n}var NR=[[`number`,()=>0],[`text`,()=>``],[`boolean`,()=>!1],[`color`,()=>`#ffffff`],[`vec2`,()=>[0,0]],[`vec3`,()=>[0,0,0]]];function PR(e,t){let n=0,r=e=>{if(bn(e)){e[`@const`]===t&&(n+=1);return}if(Array.isArray(e))for(let t of e)r(t);else if(e&&typeof e==`object`)for(let t of Object.values(e))r(t)};for(let[t,n]of Object.entries(e))t!==`constants`&&r(n);return n}function FR(e,t,n){let r=e=>{if(bn(e))return e[`@const`]===t?JSON.parse(JSON.stringify(n??null)):e;if(Array.isArray(e))return e.map(r);if(e&&typeof e==`object`){let t=e;for(let e of Object.keys(t))t[e]=r(t[e]);return t}return e};for(let t of Object.keys(e))t!==`constants`&&(e[t]=r(e[t]))}function IR(e,t){let n=t.working.orderGroups??{},r=Object.keys(n),i=e=>{t.mutate(()=>{Object.keys(e).length===0?delete t.working.orderGroups:t.working.orderGroups=e})},a=document.createElement(`div`);if(a.className=`hint`,a.textContent=`Built in: ${Object.entries(ht).map(([e,t])=>`${e} ${t}`).join(` · `)}`,e.appendChild(a),r.length===0){let t=document.createElement(`div`);t.className=`hint`,t.textContent=`No extra bands. Add one to sort between (or beyond) the built-ins — a band is the base offset, not just a name.`,e.appendChild(t)}for(let t of r){let r=document.createElement(`div`);r.className=`const-row`,r.appendChild(XR(t,n[t]??0,e=>i({...n,[t]:e})));let a=document.createElement(`button`);a.type=`button`,a.className=`const-del`,a.textContent=`✕`,a.title=`delete band "${t}"`,a.addEventListener(`click`,()=>{let e={...n};delete e[t],i(e)}),r.appendChild(a),e.appendChild(r)}let o=document.createElement(`div`);o.className=`const-add`;let s=document.createElement(`input`);s.type=`text`,s.placeholder=`new band name`;let c=document.createElement(`input`);c.type=`number`,c.placeholder=`base`,c.className=`band-base`;let l=document.createElement(`button`);l.type=`button`,l.textContent=`add`,l.addEventListener(`click`,()=>{let e=s.value.trim(),t=Number(c.value);!e||n[e]!==void 0||!Number.isFinite(t)||(i({...n,[e]:t}),s.value=``,c.value=``)}),o.append(s,c,l),e.appendChild(o)}function LR(e,t,n){let r=t.working.constants??{},i=Object.keys(r),a=(e,n)=>{t.mutate(()=>{let r={...t.working.constants??{}};r[e]=n,t.working.constants=r})},o=(e,n)=>{t.mutate(()=>{n&&FR(t.working,e,r[e]);let i={...t.working.constants??{}};delete i[e],Object.keys(i).length===0?delete t.working.constants:t.working.constants=i})},s=e=>{let r=PR(t.working,e);if(r>0&&n?.confirm){n.confirm(`"${e}" is used by ${r} prop${r===1?``:`s`}. Unlink them (inline its current value) and delete?`,`unlink & delete`,()=>o(e,!0));return}o(e,r>0)};if(i.length===0){let t=document.createElement(`div`);t.className=`hint`,t.textContent=`No constants yet. Add one, then bind props to it with the 🔗 picker.`,e.appendChild(t)}for(let t of i){let n=document.createElement(`div`);n.className=`const-row`,n.appendChild(RR(t,r[t],e=>a(t,e)));let i=document.createElement(`button`);i.type=`button`,i.className=`const-del`,i.textContent=`✕`,i.title=`delete constant "${t}"`,i.addEventListener(`click`,()=>s(t)),n.appendChild(i),e.appendChild(n)}let c=document.createElement(`div`);c.className=`const-add`;let l=document.createElement(`input`);l.type=`text`,l.placeholder=`new constant name`;let u=document.createElement(`select`);for(let[e]of NR){let t=document.createElement(`option`);t.value=e,t.textContent=e,u.appendChild(t)}let d=document.createElement(`button`);d.type=`button`,d.textContent=`+ add`,d.addEventListener(`click`,()=>{let e=l.value.trim();e&&(t.working.constants??{})[e]===void 0&&(a(e,(NR.find(([e])=>e===u.value)?.[1]??(()=>0))()),l.value=``)}),c.append(l,u,d),e.appendChild(c)}function RR(e,t,n){let r=Be(t);if(r===`number`)return XR(e,t,e=>n(e),()=>n(0));if(r===`boolean`){let r=document.createElement(`input`);return r.type=`checkbox`,r.checked=t===!0,r.addEventListener(`change`,()=>n(r.checked)),GR(e,r)}return r===`array`&&Array.isArray(t)&&t.every(e=>typeof e==`number`)?ZR(e,t,e=>n(e)):r===`string`?YR(e,String(t),e=>n(e)):$R(e,t,e=>n(e??null),JSON.stringify(t))}function zR(e,t,n,r,i,a){let o=t.props?.[n]??r,s=Be(r),c=s===`number`||s===`boolean`||s===`string`||s===`array`,l=i=>{let a=bn(i);e.mutate(()=>{t.props||={};let e=t.props;JSON.stringify(i)===JSON.stringify(r)?(delete e[n],Object.keys(e).length===0&&delete t.props):e[n]=i},e.selection&&c&&!a?{path:e.selection,key:n,value:i}:void 0)},u=BR(e,s,r);if(bn(o))return VR(n,o[`@const`],u,l,r);let d=e=>u.length>0?HR(e,u,l):e;if(s===`number`)return d(XR(a??n,o,e=>l(e),()=>l(r)));if(s===`boolean`){let e=document.createElement(`input`);return e.type=`checkbox`,e.checked=o===!0,e.addEventListener(`change`,()=>l(e.checked)),d(GR(a??n,e))}if(s===`string`){if(i&&i.length>0){let t=n===`orderGroup`?JR(e):[];return d(KR(a??n,String(o??``),t.length>0?[...i,...t]:i,e=>l(e),n===`orderGroup`?t=>qR(t,e):void 0))}return d(YR(a??n,String(o??``),e=>l(e)))}return s===`array`&&Array.isArray(r)&&r.length>0&&r.every(e=>typeof e==`number`)?d(ZR(n,o??r,e=>l(e))):$R(n,o===r?void 0:o,e=>{l(e===void 0?r:e)},JSON.stringify(r))}function BR(e,t,n){let r=e.working.constants??{};return Object.keys(r).filter(e=>{let i=r[e];return Be(i)===t?t===`array`&&Array.isArray(n)&&Array.isArray(i)?i.length===n.length:!0:!1})}function VR(e,t,n,r,i){let a=document.createElement(`select`),o=n.includes(t)?n:[t,...n];for(let e of o){let n=document.createElement(`option`);n.value=e,n.textContent=e,e===t&&(n.selected=!0),a.appendChild(n)}let s=document.createElement(`option`);s.value=``,s.textContent=`↺ custom value`,a.appendChild(s),a.addEventListener(`change`,()=>{r(a.value?{"@const":a.value}:i)});let c=GR(`🔗 ${e}`,a);return c.classList.add(`const-bound`),c}function HR(e,t,n){let r=document.createElement(`select`);r.className=`const-picker`,r.title=`Bind to a named constant`;let i=document.createElement(`option`);i.value=``,i.textContent=`🔗`,r.appendChild(i);for(let e of t){let t=document.createElement(`option`);t.value=e,t.textContent=e,r.appendChild(t)}return r.value=``,r.addEventListener(`change`,()=>{r.value&&n({"@const":r.value})}),e.classList.add(`has-const-picker`),e.appendChild(r),e}function UR(e,t){let n=document.createElement(`div`);n.className=`section-title`,n.textContent=e,t&&n.appendChild(IL(t));let r=document.createElement(`span`);return r.className=`rule`,n.appendChild(r),n}function WR(e,t){let n=document.createElement(`span`);n.className=`chip`,n.textContent=e;let r=document.createElement(`button`);return r.type=`button`,r.textContent=`✕`,r.addEventListener(`click`,e=>{e.stopPropagation(),t()}),n.appendChild(r),n}function GR(e,t){let n=document.createElement(`label`);n.className=`field`;let r=document.createElement(`span`);return r.textContent=e,n.append(r,t),n}function KR(e,t,n,r,i){let a=document.createElement(`select`);for(let e of n.includes(t)?n:[t,...n]){let n=document.createElement(`option`);n.value=e;let r=i?.(e);n.textContent=r?`${e} (${r})`:e,e===t&&(n.selected=!0),a.appendChild(n)}return a.addEventListener(`change`,()=>r(a.value)),GR(e,a)}function qR(e,t){let n={...ht,...t.working.orderGroups??{}}[e];return n===void 0?`unknown — sorts as default`:String(n)}function JR(e){return Object.keys(e.working.orderGroups??{})}function YR(e,t,n){let r=document.createElement(`input`);return r.type=`text`,r.value=t,r.addEventListener(`change`,()=>n(r.value)),GR(e,r)}function XR(e,t,n,r){let i=document.createElement(`input`);return i.type=`number`,i.step=`any`,i.value=String(t),i.addEventListener(`change`,()=>{if(i.value.trim()===``){r?.();return}let e=Number(i.value);Number.isFinite(e)&&n(e)}),GR(e,i)}function ZR(e,t,n){let r=document.createElement(`div`);r.className=`vector-row`;let i=[...t];return i.forEach((e,t)=>{let a=document.createElement(`input`);a.type=`number`,a.step=`any`,a.value=String(e??0),a.addEventListener(`change`,()=>{let e=Number(a.value);Number.isFinite(e)&&(i[t]=e,n([...i]))}),r.appendChild(a)}),GR(e,r)}function QR(e,t){let n=document.createElement(`div`);n.className=`field wide tile-paint`;let r=document.createElement(`button`);r.type=`button`,r.className=t.active()?`paint-toggle on`:`paint-toggle`,r.textContent=t.active()?`🖌 painting — click the canvas`:`🖌 paint tiles`,r.addEventListener(`click`,()=>t.toggle()),n.appendChild(r);let i=document.createElement(`div`);i.className=`paint-palette`;let a=e.props?.cells??[],o=e.props?.legend??{};for(let e of rR(a,o)){let n=document.createElement(`button`);n.type=`button`,n.className=t.brush()===e?`paint-chip on`:`paint-chip`,n.textContent=e===`.`?`␡`:e,n.title=e===`.`?`eraser (empty cell)`:`tile '${e}'`,n.addEventListener(`click`,()=>t.setBrush(e)),i.appendChild(n)}let s=document.createElement(`input`);s.type=`text`,s.maxLength=1,s.className=`paint-brush-input`,s.value=t.brush(),s.title=`brush char (digit or a legend char)`,s.addEventListener(`change`,()=>{s.value.length===1&&t.setBrush(s.value)}),i.appendChild(s),n.appendChild(i);let c=document.createElement(`div`);return c.className=`paint-hint`,c.textContent=`grid grows right/down; digits map to atlas tiles, others need legend`,n.appendChild(c),n}function $R(e,t,n,r=``){let i=document.createElement(`textarea`);i.rows=3,i.placeholder=r,i.value=t===void 0?``:JSON.stringify(t,null,2),i.addEventListener(`change`,()=>{let e=i.value.trim();if(e===``){i.classList.remove(`invalid`),n(void 0);return}try{let t=JSON.parse(e);i.classList.remove(`invalid`),n(t)}catch{i.classList.add(`invalid`)}});let a=GR(e,i);return a.className=`field wide`,a}var ez=2.4,tz=1.35,nz=[0,.5,0];function rz(e){return{format:1,type:`scene`,dimension:`3d`,name:`Preview`,environment:{sky:{type:`atmosphere`,elevationDeg:35,azimuthDeg:140,turbidity:3},ambient:{intensity:.55},exposure:1.05},assets:{model:{type:`model`,url:e}},root:{name:`Preview`,type:`Node3D`,children:[{name:`Cam`,type:`Camera3D`,props:{current:!0,position:[0,tz,ez]}},{name:`Sun`,type:`DirectionalLight3D`,props:{position:[3,6,4],intensity:2.2}},{name:`Model`,type:`ModelInstance3D`,props:{model:`$model`,targetHeight:1}}]}}}var iz=class{canvas=null;engine=null;renderer=null;raf=0;angle=.9;dragging=!1;lastX=0;url=``;mount(e){let t=document.createElement(`div`);t.className=`lib-preview3d`;let n=this.ensure();return t.appendChild(n),e!==this.url&&(this.url=e,this.load(e)),this.start(),t}detach(){this.stop(),this.canvas?.remove()}dispose(){this.stop(),this.renderer?.dispose(),this.engine?.dispose(),this.renderer=null,this.engine=null,this.canvas?.remove(),this.canvas=null,this.url=``}ensure(){if(this.canvas)return this.canvas;let e=document.createElement(`canvas`);e.className=`lib-preview-canvas`,this.canvas=e,this.engine=new kt({scheduler:()=>()=>{}}),this.renderer=new _P({canvas:e,engine:this.engine}),e.addEventListener(`pointerdown`,t=>{this.dragging=!0,this.lastX=t.clientX,e.setPointerCapture(t.pointerId)}),e.addEventListener(`pointermove`,e=>{this.dragging&&(this.angle-=(e.clientX-this.lastX)*.01,this.lastX=e.clientX)});let t=()=>{this.dragging=!1};return e.addEventListener(`pointerup`,t),e.addEventListener(`pointercancel`,t),e}load(e){if(this.engine)try{this.engine.setScene(An(rz(e)))}catch(t){console.warn(`[incanto] library preview could not load`,e,t)}}start(){if(this.raf)return;let e=0,t=n=>{this.raf=requestAnimationFrame(t);let r=e?Math.min(.05,(n-e)/1e3):0;e=n,this.dragging||(this.angle+=r*.5);let i=this.renderer;i&&(i.viewOverride={position:[Math.sin(this.angle)*ez,tz,Math.cos(this.angle)*ez],target:nz},this.engine?.tick(n))};this.raf=requestAnimationFrame(t)}stop(){this.raf&&cancelAnimationFrame(this.raf),this.raf=0}},az=`incanto-editor-v8-token`,oz=24;async function sz(e,t,n){if(!C(e.url)||n!==`spritesheet`&&n!==`texture`)return null;try{let n=iy(await(await fetch(e.url)).json(),{url:w(e.url),assetKey:t});return{asset:n.asset,props:Object.fromEntries(Object.entries(n.props).filter(([e])=>e!==`sheet`))}}catch(t){return console.warn(`[incanto] not a usable sprite config:`,e.url,t),null}}function cz(){try{return localStorage.getItem(az)??``}catch{return``}}function lz(e){try{e?localStorage.setItem(az,e):localStorage.removeItem(az)}catch{}}function uz(e,t){return new Promise(n=>{let r=[...t.shelf??[]],i=``,a=1,o=!1,c=[],u=[],d=null,f=!1,b=!1,x=document.createElement(`div`);x.className=`lib-backdrop`;let T=document.createElement(`div`);T.className=`lib-dialog`,x.appendChild(T);let E=document.createElement(`header`);E.className=`lib-head`;let D=document.createElement(`strong`);D.textContent=`agent8 library`;let O=document.createElement(`span`);O.className=`lib-sub`,O.textContent=t.target?`→ ${t.target}`:``;let k=document.createElement(`input`);k.type=`search`,k.className=`lib-search`,k.placeholder=`search descriptions…`;let A=document.createElement(`button`);A.type=`button`,A.className=`ghost`,A.id=`lib-close`,A.textContent=`✕`,A.title=`Close (Esc)`,E.append(D,O,k,A),T.appendChild(E);let ee=document.createElement(`div`);ee.className=`lib-body`,T.appendChild(ee);let te=document.createElement(`nav`);te.className=`lib-shelves`;let ne=document.createElement(`div`);ne.className=`lib-grid-pane`;let re=document.createElement(`div`);re.className=`lib-grid`;let j=document.createElement(`div`);j.className=`lib-status`;let ie=document.createElement(`button`);ie.type=`button`,ie.className=`ghost lib-more`,ie.textContent=`load more`,ie.hidden=!0,ne.append(j,re,ie);let ae=document.createElement(`aside`);ae.className=`lib-detail`,ee.append(te,ne,ae);let M=new iz,oe=e=>{b||(b=!0,M.dispose(),document.removeEventListener(`keydown`,se,!0),x.remove(),n(e))},se=e=>{e.key===`Escape`&&(e.stopPropagation(),oe(null))};document.addEventListener(`keydown`,se,!0),x.addEventListener(`pointerdown`,e=>{e.target===x&&oe(null)}),A.addEventListener(`click`,()=>oe(null));let ce=e=>{r=e,a=1,u=[],pe(!1)},le=()=>{te.textContent=``;let e=[[`Everything`,[]]];for(let t=0;t<r.length;t++)e.push([r[t],r.slice(0,t+1)]);for(let[t,n]of e){let e=document.createElement(`button`);e.type=`button`,e.className=`lib-shelf crumb`,e.style.paddingLeft=`${10+(n.length?n.length-1:0)*12}px`,e.textContent=t,e.classList.toggle(`active`,n.length===r.length),e.addEventListener(`click`,()=>{n.length!==r.length&&ce(n)}),te.appendChild(e)}let t=s(u,r);if(t.length>0){let e=document.createElement(`div`);e.className=`lib-shelf-head`,e.textContent=`in here`,te.appendChild(e)}for(let e of t){let t=document.createElement(`button`);t.type=`button`,t.className=`lib-shelf`,t.style.paddingLeft=`${16+r.length*12}px`;let n=document.createElement(`span`);n.textContent=e.tag;let i=document.createElement(`small`);i.className=`lib-shelf-count`,i.textContent=String(e.count),t.append(n,i),t.addEventListener(`click`,()=>ce([...r,e.tag])),te.appendChild(t)}},ue=()=>{if(ae.textContent=``,M.detach(),!d){let e=document.createElement(`div`);e.className=`lib-empty`,e.textContent=`pick an asset to preview it`,ae.appendChild(e);return}let e=d,n=document.createElement(`div`);n.className=`lib-stage`;let r=m(e.url);if(r===`image`||C(e.url)){let t=document.createElement(`img`);t.src=C(e.url)?w(e.url):e.url,t.alt=g(e),t.loading=`lazy`,n.appendChild(t)}else if(r===`audio`){let t=document.createElement(`audio`);t.controls=!0,t.src=e.url,n.appendChild(t)}else if(r===`model`)n.appendChild(M.mount(e.url));else{let t=document.createElement(`div`);t.className=`lib-empty`,t.textContent=`no preview for ${p(e.url)||`this file`}`,n.appendChild(t)}if(ae.appendChild(n),C(e.url)){let e=document.createElement(`p`);e.className=`lib-desc lib-note`,e.textContent=`Sprite config — picking it declares the sheet AND wires its named animations onto the node.`,ae.appendChild(e)}let i=document.createElement(`h3`);if(i.className=`lib-name`,i.textContent=g(e),ae.appendChild(i),e.description){let t=document.createElement(`p`);t.className=`lib-desc`,t.textContent=e.description,ae.appendChild(t)}let a=v(e);if(a.length){let e=document.createElement(`div`);e.className=`lib-tags`;for(let t of a){let n=document.createElement(`span`);n.className=`lib-tag`,n.textContent=t,e.appendChild(n)}ae.appendChild(e)}let o=y(e);if(o.length){let e=document.createElement(`dl`);e.className=`lib-facts`;for(let[t,n]of o){let r=document.createElement(`dt`);r.textContent=t;let i=document.createElement(`dd`);i.textContent=n,e.append(r,i)}ae.appendChild(e)}let s=document.createElement(`div`);s.className=`lib-url`;let c=document.createElement(`code`);c.textContent=e.url;let l=document.createElement(`button`);l.type=`button`,l.className=`ghost`,l.textContent=`copy`,l.addEventListener(`click`,()=>{navigator.clipboard?.writeText(e.url),l.textContent=`copied`,setTimeout(()=>{l.textContent=`copy`},1200)}),s.append(c,l),ae.appendChild(s);let u=document.createElement(`div`);u.className=`lib-actions`;let f=document.createElement(`button`);f.type=`button`,f.className=`primary`,f.id=`lib-use`,f.textContent=t.onAsset?`use as scene asset`:`use this`,f.addEventListener(`click`,()=>{if(!t.onAsset){oe(e.url);return}(async()=>{let n=_(e),r=await sz(e,n,t.assetType),i=r?.asset??S(e,t.kind,t.assetType),a=t.onAsset?.(e,i,n)??e.url;r&&t.onProps?.(r.props),oe(a)})()}),u.appendChild(f),ae.appendChild(u)},de=()=>{re.textContent=``;let e=c.filter(e=>h(e.url,t.kind));if(e.length===0&&!f){let e=document.createElement(`div`);e.className=`lib-empty`,e.textContent=c.length===0?`nothing on this shelf`:`this shelf has ${c.length} asset${c.length===1?``:`s`}, none of them a ${t.kind}`,re.appendChild(e)}for(let t of e){let e=document.createElement(`button`);e.type=`button`,e.className=`lib-card`,e.classList.toggle(`active`,t===d);let n=document.createElement(`div`);n.className=`lib-thumb`;let r=m(t.url);if(r===`image`){let e=document.createElement(`img`);e.src=t.url,e.alt=``,e.loading=`lazy`,n.appendChild(e)}else{let e=$P(r===`audio`?`AudioPlayer`:`ModelInstance3D`);e.classList.add(`lib-glyph`),n.appendChild(e)}if(C(t.url)){let e=document.createElement(`em`);e.className=`lib-badge`,e.textContent=`animated`,e.title=`A sprite config: frame grid + named animations. Picking it wires them up.`,n.appendChild(e)}let i=document.createElement(`span`);i.className=`lib-card-name`,i.textContent=g(t),e.append(n,i),e.title=t.description||t.url,e.addEventListener(`click`,()=>{d=t,de(),ue()}),re.appendChild(e)}ie.hidden=!o||f},fe=e=>{re.textContent=``,ie.hidden=!0;let t=document.createElement(`div`);t.className=`lib-token`;let n=document.createElement(`p`);n.className=`lib-token-line`,n.textContent=e;let r=document.createElement(`p`);r.className=`lib-token-line lib-token-how`,r.textContent=`The catalog is per-account. Paste a Verse8 access token to browse it here — it is kept in this browser and sent only to your own editor server. Starting the editor with --token (or INCANTO_V8_TOKEN) skips this.`;let i=document.createElement(`input`);i.type=`password`,i.className=`mono`,i.placeholder=`v8 access token`,i.value=cz();let o=document.createElement(`button`);o.type=`button`,o.className=`primary`,o.textContent=`connect`,o.addEventListener(`click`,()=>{lz(i.value.trim()),a=1,pe(!1)}),i.addEventListener(`keydown`,e=>{e.key===`Enter`&&o.click()});let s=document.createElement(`div`);s.className=`lib-token-row`,s.append(i,o),t.append(n,r,s),re.appendChild(t)},pe=async t=>{if(!(!e.library||f)){f=!0,j.textContent=t?`loading more…`:`loading ${l(r)}…`,t||(c=[],d=null,de(),ue()),le();try{let n=await e.library({tags:r,keyword:i.trim()||void 0,page:a,limit:oz},cz()||void 0);if(b)return;c=t?[...c,...n.items]:n.items,u=c,o=n.hasNext;let s=n.total===void 0?``:` of ${n.total}`;j.textContent=`${l(r)} · ${c.length}${s} loaded`,le(),de()}catch(e){if(b)return;let t=e.needsToken===!0;if(j.textContent=l(r),t)fe(e instanceof Error?e.message:String(e));else{re.textContent=``;let t=document.createElement(`div`);t.className=`lib-error`,t.textContent=e instanceof Error?e.message:String(e),re.appendChild(t)}}finally{f=!1,ie.hidden=!o}}};ie.addEventListener(`click`,()=>{a+=1,pe(!0)});let me=0;k.addEventListener(`input`,()=>{i=k.value,clearTimeout(me),me=window.setTimeout(()=>{a=1,pe(!1)},350)}),le(),ue(),document.body.appendChild(x),k.focus(),pe(!1)})}var dz=`.scene.json`;function fz(e){let t=e.split(`/`).pop()??e;return t.endsWith(dz)?t.slice(0,-11):t}function pz(e){let t=e.lastIndexOf(`/`);return t===-1?``:e.slice(0,t)}function mz(e,t){return{path:e,name:t,dirs:new Map,files:[]}}function hz(e){let t=mz(``,``);for(let n of e){let e=n.rel.split(`/`);if(!e.pop())continue;let r=t;for(let t of e){let e=r.path?`${r.path}/${t}`:t,n=r.dirs.get(t);n||(n=mz(e,t),r.dirs.set(t,n)),r=n}r.files.push(n)}return t}function gz(e){let t=e.files.length;for(let n of e.dirs.values())t+=gz(n);return t}function _z(e){let t=e.files.filter(e=>e.scene).length;for(let n of e.dirs.values())t+=_z(n);return t}function vz(e){let t=e,n=e.name;for(;t.files.length===0&&t.dirs.size===1;){let e=[...t.dirs.values()][0];if(!e)break;t=e,n=`${n} / ${e.name}`}return{dir:t,label:n}}function yz(e){let t=pz(e??``).split(`/`).filter(Boolean),n=[],r=``;for(let e of t)r=r?`${r}/${e}`:e,n.push(r);return n}function bz(e,t={}){let n=(t.query??``).trim().toLowerCase(),r=n?e.filter(e=>e.rel.toLowerCase().includes(n)):e,i=t.expanded??new Set,a=[],o=(e,r)=>{let s=[...e.dirs.values()].sort((e,t)=>e.name.localeCompare(t.name));for(let e of s){let{dir:t,label:s}=vz(e),c=gz(t);if(c===0)continue;let l=n!==``||i.has(t.path);a.push({kind:`folder`,path:t.path,label:s,depth:r,count:c,scenes:_z(t),open:l}),l&&o(t,r+1)}let c=[...e.files].sort((e,t)=>fz(e.rel).localeCompare(fz(t.rel)));for(let e of c)a.push({kind:`scene`,entry:e,label:fz(e.rel),folder:pz(e.rel),depth:r,current:e.rel===t.current})};return o(hz(r),0),a}function xz(e,t){let n=new Set(yz(t));if(e.length<=24)for(let t of e)for(let e of yz(t.rel))n.add(e);return n}function Sz(e){return typeof e!=`number`||!Number.isFinite(e)||e<0?``:e<1e3?`${e} B`:e<1e3*1e3?`${(e/1e3).toFixed(1)} kB`:`${(e/1e3/1e3).toFixed(1)} MB`}function Cz(e,t){if(typeof e!=`number`||!Number.isFinite(e)||e<=0)return``;let n=Math.round((t-e)/1e3);if(n<90)return`just now`;let r=Math.round(n/60);if(r<60)return`${r}m ago`;let i=Math.round(r/60);return i<24?`${i}h ago`:i<48?`yesterday`:new Date(e).toISOString().slice(0,10)}function wz(e,t=`new-level`){let n=e?e.kind===`folder`?e.path:e.folder:``;return n?`${n}/${t}${dz}`:`${t}${dz}`}function Tz(e,t){let n=document.createElement(`span`);return n.className=e,n.textContent=t,n}function Ez(e,t,n=()=>Date.now()){let r=[],i=new Set,a=[],o=0,s=!0,c=()=>{let c=t.current();if(a=bz(r,{expanded:i,query:e.search.value,current:c}),o>=a.length&&(o=a.length-1),o<0&&(o=0),s){let e=a.findIndex(e=>e.kind===`scene`&&e.current);e>=0&&(o=e),s=!1}if(e.list.textContent=``,a.length===0){let t=document.createElement(`div`);t.className=`scene-empty`,t.textContent=r.length?`no scene matches “${e.search.value.trim()}”`:`no .json files in this project yet — create a scene below`,e.list.appendChild(t)}let u=n();a.forEach((n,r)=>{let i=document.createElement(`div`);i.className=n.kind===`folder`?`scene-row scene-folder`:`scene-row`,i.style.paddingLeft=`${6+n.depth*14}px`,r===o&&i.classList.add(`active`);let a=Tz(`scene-caret`,``);n.kind===`folder`?(a.classList.add(`chevron`),n.open||a.classList.add(`collapsed`),a.appendChild(eF())):a.textContent=`◇`,i.append(a,Tz(`scene-name`,n.label),Tz(`scene-meta`,n.kind===`folder`?n.scenes>0?`${n.scenes} scene${n.scenes===1?``:`s`}`:`${n.count} file${n.count===1?``:`s`}`:[n.entry.scene?[n.entry.scene.dimension,`${n.entry.scene.nodes} node${n.entry.scene.nodes===1?``:`s`}`].filter(Boolean).join(` · `):`not a scene`,Cz(n.entry.modified,u),Sz(n.entry.size)].filter(Boolean).join(` · `))),n.kind===`scene`&&(n.current&&i.classList.add(`current`),n.entry.notScene?(i.classList.add(`not-scene`),i.title=`${n.entry.rel}\n\nnot a scene: ${n.entry.notScene}`):i.title=n.entry.rel),i.addEventListener(`click`,()=>{o=r,n.kind===`folder`?l(n.path):t.open(n.entry)}),e.list.appendChild(i)});let d=r.length,f=a.filter(e=>e.kind===`scene`).length;e.count.textContent=d===0?``:f===d?`${d}`:`${f} / ${d}`,e.path.placeholder=wz(a[o]),e.list.querySelector(`.active`)?.scrollIntoView({block:`nearest`})},l=e=>{i.has(e)?i.delete(e):i.add(e),c()},u=e=>{a.length!==0&&(o=Math.min(a.length-1,Math.max(0,o+e)),c())};return e.search.addEventListener(`input`,()=>{o=0,c()}),e.search.addEventListener(`keydown`,e=>{let n=a[o];switch(e.key){case`ArrowDown`:e.preventDefault(),u(1);return;case`ArrowUp`:e.preventDefault(),u(-1);return;case`ArrowRight`:n?.kind===`folder`&&!n.open&&(e.preventDefault(),l(n.path));return;case`ArrowLeft`:n?.kind===`folder`&&n.open&&(e.preventDefault(),l(n.path));return;case`Enter`:e.preventDefault(),n?.kind===`folder`?l(n.path):n&&t.open(n.entry);return;default:}}),{async refresh(){try{r=await t.entries()}catch(t){r=[],e.list.textContent=``;let n=document.createElement(`div`);n.className=`scene-empty`,n.textContent=`could not list scenes: ${t instanceof Error?t.message:String(t)}`,e.list.appendChild(n),e.count.textContent=``;return}if(i.size===0)i=xz(r,t.current());else for(let e of yz(t.current()))i.add(e);s=!0,c(),e.search.focus(),e.search.select()}}}var Dz=`
|
|
8423
|
+
`}},network:{title:{en:`network — replicate to other players`,ko:`network — 다른 플레이어에게 복제`},body:{en:`mode "owner" means THIS player owns the node and broadcasts the listed sync keys to everyone in the room (one owner node per player — usually your player character). Other players see it via a NetworkSpawner. Keys are relative to this node: "position", or "Skin.animation" for a child prop.`,ko:`mode "owner"는 이 플레이어가 노드를 소유하고 sync 키 목록을 방의 모두에게 송출한다는 뜻입니다(플레이어당 owner 노드 하나 — 보통 내 캐릭터). 다른 플레이어는 NetworkSpawner로 봅니다. 키는 이 노드 기준 상대 표기입니다: "position", 자식 prop은 "Skin.animation".`},example:`{ "mode": "owner", "sync": ["position"], "throttleMs": 50 }`},collider:{title:{en:`collider — the physics shape`,ko:`collider — 물리 모양`},body:{en:`Shapes: rect (size [w,h]), circle (radius), capsule (radius + height — good for characters). offset shifts the shape from the node position. The green dashed outline in the viewport shows exactly where it is.`,ko:`모양: rect(size [w,h]), circle(radius), capsule(radius+height — 캐릭터에 적합). offset이 노드 위치에서 모양을 이동시킵니다. 뷰포트의 초록 점선이 정확한 위치를 보여줍니다.`},example:`{ "shape": "capsule", "radius": 12, "height": 16 }`},physics:{title:{en:`physics — scene gravity`,ko:`physics — 씬 중력`},body:{en:`World gravity in px/s² (y-down: positive y pulls DOWN). [0, 1400] feels platformer-y; [0, 0] for top-down. Takes effect when the game calls enablePhysics2D — and in the editor’s play mode.`,ko:`월드 중력, px/s² 단위(y-아래: 양수 y가 아래로 당김). [0, 1400]이면 플랫포머 느낌, 탑다운은 [0, 0]. 게임이 enablePhysics2D를 부를 때 — 그리고 에디터 플레이 모드에서 — 적용됩니다.`},example:`"physics": { "gravity": [0, 1400] }`}},FL=null;function IL(e){document.addEventListener(`click`,t=>{let n=t.target,r=n.closest(`[data-help]`);if(!r){e.contains(n)||(e.hidden=!0);return}let i=PL[r.dataset.help??``];if(!i)return;if(!e.hidden&&FL===r){e.hidden=!0;return}FL=r,e.textContent=``;let a=document.createElement(`h4`);a.textContent=QP(i.title);let o=document.createElement(`div`);if(o.textContent=QP(i.body),e.append(a,o),i.example){let t=document.createElement(`pre`);t.textContent=i.example,e.appendChild(t)}if(i.copy){let t=document.createElement(`div`);t.className=`pop-actions`;let n=document.createElement(`button`);n.type=`button`,n.className=`linklike`,n.textContent=`⧉ ${i.copy.label}`,n.addEventListener(`click`,()=>{navigator.clipboard.writeText(i.copy?.text??``),n.textContent=`✓ copied`}),t.appendChild(n),e.appendChild(t)}e.hidden=!1;let s=e.getBoundingClientRect(),{left:c,top:l}=LL(r.getBoundingClientRect(),{width:s.width,height:s.height},{width:innerWidth,height:innerHeight});e.style.left=`${c}px`,e.style.top=`${l}px`})}function LL(e,t,n,r=8){let i=t.width||300,a=e.left-i+20,o=Math.max(r,Math.min(n.width-i-r,a)),s=e.bottom+r,c=e.top-t.height-r,l;return l=s+t.height+r<=n.height?s:c>=r?c:r,{left:o,top:l}}function RL(e){let t=document.createElement(`button`);return t.type=`button`,t.className=`help-btn`,t.dataset.help=e,t.textContent=`?`,t.title=`What is this?`,t}var zL=JSON.parse('[{"name":"2dbasic","file":"characters/2dbasic.png","url":"incanto/assets/characters/2dbasic.png","kind":"character","bytes":30499,"description":"2dbasic sprite sheet image.anything,base character. (frame size 192x192)","animation":"characters/2dbasic.json","frameWidth":111,"frameHeight":83},{"name":"attacked","file":"audio/attacked.mp3","url":"incanto/assets/audio/attacked.mp3","kind":"audio","bytes":8757,"description":"Short hurt / took-damage SFX for the player or an enemy."},{"name":"bark_birch_color","file":"vegetation/bark/birch_color_1k.jpg","url":"https://agent8-games.verse8.io/assets/3D/default/textures/vegetation/bark/birch_color_1k.jpg","kind":"foliage","bytes":194186,"description":"Birch bark base color texture (1k), ambientcg Bark (CC0) packaged by ez-tree (MIT). Tree3D trunks/branches sample it by default from the agent8 CDN (the only sanctioned external host); the bundled `incanto/assets` copy (see this entry’s `file`) serves it offline."},{"name":"bark_birch_normal","file":"vegetation/bark/birch_normal_1k.jpg","url":"https://agent8-games.verse8.io/assets/3D/default/textures/vegetation/bark/birch_normal_1k.jpg","kind":"foliage","bytes":378046,"description":"Birch bark tangent-space normal texture (1k), ambientcg Bark (CC0) packaged by ez-tree (MIT). Tree3D trunks/branches sample it by default from the agent8 CDN (the only sanctioned external host); the bundled `incanto/assets` copy (see this entry’s `file`) serves it offline."},{"name":"bark_birch_roughness","file":"vegetation/bark/birch_roughness_1k.jpg","url":"https://agent8-games.verse8.io/assets/3D/default/textures/vegetation/bark/birch_roughness_1k.jpg","kind":"foliage","bytes":127387,"description":"Birch bark roughness texture (1k), ambientcg Bark (CC0) packaged by ez-tree (MIT). Tree3D trunks/branches sample it by default from the agent8 CDN (the only sanctioned external host); the bundled `incanto/assets` copy (see this entry’s `file`) serves it offline."},{"name":"bark_oak_color","file":"vegetation/bark/oak_color_1k.jpg","url":"https://agent8-games.verse8.io/assets/3D/default/textures/vegetation/bark/oak_color_1k.jpg","kind":"foliage","bytes":297877,"description":"Oak bark base color texture (1k), ambientcg Bark (CC0) packaged by ez-tree (MIT). Tree3D trunks/branches sample it by default from the agent8 CDN (the only sanctioned external host); the bundled `incanto/assets` copy (see this entry’s `file`) serves it offline."},{"name":"bark_oak_normal","file":"vegetation/bark/oak_normal_1k.jpg","url":"https://agent8-games.verse8.io/assets/3D/default/textures/vegetation/bark/oak_normal_1k.jpg","kind":"foliage","bytes":67610,"description":"Oak bark tangent-space normal texture (1k), ambientcg Bark (CC0) packaged by ez-tree (MIT). Tree3D trunks/branches sample it by default from the agent8 CDN (the only sanctioned external host); the bundled `incanto/assets` copy (see this entry’s `file`) serves it offline."},{"name":"bark_oak_roughness","file":"vegetation/bark/oak_roughness_1k.jpg","url":"https://agent8-games.verse8.io/assets/3D/default/textures/vegetation/bark/oak_roughness_1k.jpg","kind":"foliage","bytes":16648,"description":"Oak bark roughness texture (1k), ambientcg Bark (CC0) packaged by ez-tree (MIT). Tree3D trunks/branches sample it by default from the agent8 CDN (the only sanctioned external host); the bundled `incanto/assets` copy (see this entry’s `file`) serves it offline."},{"name":"bark_pine_color","file":"vegetation/bark/pine_color_1k.jpg","url":"https://agent8-games.verse8.io/assets/3D/default/textures/vegetation/bark/pine_color_1k.jpg","kind":"foliage","bytes":196361,"description":"Pine bark base color texture (1k), ambientcg Bark (CC0) packaged by ez-tree (MIT). Tree3D trunks/branches sample it by default from the agent8 CDN (the only sanctioned external host); the bundled `incanto/assets` copy (see this entry’s `file`) serves it offline."},{"name":"bark_pine_normal","file":"vegetation/bark/pine_normal_1k.jpg","url":"https://agent8-games.verse8.io/assets/3D/default/textures/vegetation/bark/pine_normal_1k.jpg","kind":"foliage","bytes":58237,"description":"Pine bark tangent-space normal texture (1k), ambientcg Bark (CC0) packaged by ez-tree (MIT). Tree3D trunks/branches sample it by default from the agent8 CDN (the only sanctioned external host); the bundled `incanto/assets` copy (see this entry’s `file`) serves it offline."},{"name":"bark_pine_roughness","file":"vegetation/bark/pine_roughness_1k.jpg","url":"https://agent8-games.verse8.io/assets/3D/default/textures/vegetation/bark/pine_roughness_1k.jpg","kind":"foliage","bytes":36136,"description":"Pine bark roughness texture (1k), ambientcg Bark (CC0) packaged by ez-tree (MIT). Tree3D trunks/branches sample it by default from the agent8 CDN (the only sanctioned external host); the bundled `incanto/assets` copy (see this entry’s `file`) serves it offline."},{"name":"box","file":"items/box.png","url":"incanto/assets/items/box.png","kind":"item","bytes":10861,"description":"Item box sprite for Dungeons and Dungeoners. Container sprite that holds random items or rewards when opened by player."},{"name":"buff_potion","file":"items/buff_potion.png","url":"incanto/assets/items/buff_potion.png","kind":"item","bytes":3809,"description":"Buff potion item sprite for Dungeons and Dungeoners. Consumable item that grants temporary stat boosts or positive effects to player character."},{"name":"coin","file":"items/coin.png","url":"incanto/assets/items/coin.png","kind":"item","bytes":1689,"description":"Gold coin collectible sprite for Dungeons and Dungeoners. Currency item with metallic sheen, used as in-game money or collectible reward."},{"name":"explosion","file":"audio/explosion.mp3","url":"incanto/assets/audio/explosion.mp3","kind":"audio","bytes":40124,"description":"Impactful explosion / large destructive hit SFX. Pair with the Particles2D \\"explosion\\" preset."},{"name":"floor00","file":"tiles/floor00.jpg","url":"incanto/assets/tiles/floor00.jpg","kind":"tile","bytes":28736,"description":"Basic floor tile texture for Dungeons and Dungeoners project, suitable for dungeon ground surfaces."},{"name":"gem","file":"items/gem.png","url":"incanto/assets/items/gem.png","kind":"item","bytes":8762,"description":"Gem collectible sprite for Dungeons and Dungeoners. Valuable gemstone item used as currency, crafting material, or quest objective."},{"name":"ghost","file":"characters/ghost.png","url":"incanto/assets/characters/ghost.png","kind":"character","bytes":22933,"description":"Ghost character with translucent appearance sprite sheet image (frame size 112x128)","animation":"characters/ghost.json","frameWidth":112,"frameHeight":128},{"name":"goblin","file":"characters/goblin.png","url":"incanto/assets/characters/goblin.png","kind":"character","bytes":57994,"description":"Medieval goblin with torch sprite sheet image (frame size 192x192)","animation":"characters/goblin.json","frameWidth":192,"frameHeight":192},{"name":"gold","file":"items/gold.png","url":"incanto/assets/items/gold.png","kind":"item","bytes":22313,"description":"Gold item sprite for Dungeons and Dungeoners. Gold pile or gold bar sprite representing valuable currency or treasure reward."},{"name":"gold-loot","file":"audio/gold_loot.mp3","url":"incanto/assets/audio/gold_loot.mp3","kind":"audio","bytes":7506,"description":"Metallic coin / gold pickup jingle — collecting currency."},{"name":"ground_dirt","file":"vegetation/ground/dirt_color.jpg","url":"https://agent8-games.verse8.io/assets/3D/default/textures/vegetation/ground/dirt_color.jpg","kind":"foliage","bytes":231383,"description":"Dense dirt/gravel ground texture (1024px) from the ez-tree demo app (MIT) — the reference meadow ground. Terrain3D grassland themes tile it for slope + noise-patch dirt by default; also bundled in `incanto/assets` (see `file`) for offline use."},{"name":"ground_dirt_normal","file":"vegetation/ground/dirt_normal.jpg","url":"https://agent8-games.verse8.io/assets/3D/default/textures/vegetation/ground/dirt_normal.jpg","kind":"foliage","bytes":123478,"description":"Dirt ground normal map (1024px) from the ez-tree demo app (MIT). Terrain3D grassland themes apply it across the whole ground band (demo parity); also bundled in `incanto/assets` (see `file`) for offline use."},{"name":"ground_grass","file":"vegetation/ground/grass.jpg","url":"https://agent8-games.verse8.io/assets/3D/default/textures/vegetation/ground/grass.jpg","kind":"foliage","bytes":322486,"description":"Mossy meadow grass ground texture (1024px) from the ez-tree demo app (MIT). Terrain3D grassland themes (meadow/forest generators) tile it as the grass splat layer by default; also bundled in `incanto/assets` (see `file`) for offline use."},{"name":"heal","file":"audio/heal.mp3","url":"incanto/assets/audio/heal.mp3","kind":"audio","bytes":29764,"description":"Soothing health-restore / heal spell SFX."},{"name":"hit-metal-bang","file":"audio/hit_metal_bang.mp3","url":"incanto/assets/audio/hit_metal_bang.mp3","kind":"audio","bytes":17972,"description":"Metallic impact — hitting armor, metal, or a blocked attack."},{"name":"hp_potion","file":"items/hp_potion.png","url":"incanto/assets/items/hp_potion.png","kind":"item","bytes":3513,"description":"Health potion item sprite for Dungeons and Dungeoners. Consumable healing item that restores player health points when used."},{"name":"ice-spear","file":"audio/ice_spear.mp3","url":"incanto/assets/audio/ice_spear.mp3","kind":"audio","bytes":21315,"description":"Sharp piercing ice projectile fire SFX."},{"name":"leaves_ash","file":"vegetation/ash_color.png","url":"https://agent8-games.verse8.io/assets/3D/default/textures/vegetation/ash_color.png","kind":"foliage","bytes":181423,"description":"Ash leaf-cluster alpha-cutout texture (1024px) from ez-tree by Dan Greenheck (MIT). Tree3D samples it for broadleaf/dead ash variants by default; copy it next to your game and set leafTexture to serve offline."},{"name":"leaves_aspen","file":"vegetation/aspen_color.png","url":"https://agent8-games.verse8.io/assets/3D/default/textures/vegetation/aspen_color.png","kind":"foliage","bytes":142116,"description":"Aspen leaf-cluster alpha-cutout texture (1024px) from ez-tree by Dan Greenheck (MIT). Tree3D samples it for high-tier broadleaf aspen variants; copy + leafTexture for offline serving."},{"name":"leaves_oak","file":"vegetation/oak_color.png","url":"https://agent8-games.verse8.io/assets/3D/default/textures/vegetation/oak_color.png","kind":"foliage","bytes":238115,"description":"Oak leaf-cluster alpha-cutout texture (1024px) from ez-tree by Dan Greenheck (MIT). Tree3D samples it for broadleaf oak variants by default; copy + leafTexture for offline serving."},{"name":"leaves_pine","file":"vegetation/pine_color.png","url":"https://agent8-games.verse8.io/assets/3D/default/textures/vegetation/pine_color.png","kind":"foliage","bytes":303684,"description":"Pine needle-cluster alpha-cutout texture (1024px) from ez-tree by Dan Greenheck (MIT). Tree3D samples it for conifer variants by default; copy + leafTexture for offline serving."},{"name":"locked_item_box","file":"items/locked_item_box.png","url":"incanto/assets/items/locked_item_box.png","kind":"item","bytes":11074,"description":"Locked item box sprite for Dungeons and Dungeoners. Container sprite requiring key or lockpick to open, containing valuable rewards."},{"name":"map","file":"items/map.png","url":"incanto/assets/items/map.png","kind":"item","bytes":3754,"description":"Map item sprite for Dungeons and Dungeoners. Navigation item revealing dungeon layout or providing exploration assistance."},{"name":"medieval-knight","file":"characters/medieval-knight.png","url":"incanto/assets/characters/medieval-knight.png","kind":"character","bytes":84367,"description":"(frame size 192x192) Using a medieval-themed SD(Super Deformed) knight sprite sheet image, you can apply idle, move, and attack animations, among others.","animation":"characters/medieval-knight.json","frameWidth":192,"frameHeight":192},{"name":"minecraft-tiles","file":"tiles/minecraft-tiles.png","url":"incanto/assets/tiles/minecraft-tiles.png","kind":"tile","bytes":10511,"description":"Minecraft-themed tiles sprite sheet image (frame size 16x16)"},{"name":"monster-died","file":"audio/monster_died.mp3","url":"incanto/assets/audio/monster_died.mp3","kind":"audio","bytes":16836,"description":"Enemy defeat / death SFX."},{"name":"resurrection_potion","file":"items/resurrection_potion.png","url":"incanto/assets/items/resurrection_potion.png","kind":"item","bytes":3471,"description":"Resurrection potion item sprite for Dungeons and Dungeoners. Rare consumable that revives fallen party members or prevents death."},{"name":"slash","file":"audio/slash.mp3","url":"incanto/assets/audio/slash.mp3","kind":"audio","bytes":10425,"description":"Quick sword swing / melee slash SFX."},{"name":"smite","file":"audio/smite.mp3","url":"incanto/assets/audio/smite.mp3","kind":"audio","bytes":12956,"description":"Powerful holy downward-strike SFX."},{"name":"spells-cast","file":"audio/spells_cast.mp3","url":"incanto/assets/audio/spells_cast.mp3","kind":"audio","bytes":22151,"description":"Generic magical spell-cast / chant SFX."},{"name":"super_box","file":"items/super_box.png","url":"incanto/assets/items/super_box.png","kind":"item","bytes":12184,"description":"Super item box sprite for Dungeons and Dungeoners. Premium container sprite containing rare or powerful items and equipment."},{"name":"swoosh","file":"effects/swoosh.png","url":"incanto/assets/effects/swoosh.png","kind":"effect","bytes":2599,"description":"Swoosh effect sprite for Dungeons and Dungeoners. Motion blur or attack trail effect used for melee attacks, sword slashes, or fast movement animations."},{"name":"trap","file":"items/trap.png","url":"incanto/assets/items/trap.png","kind":"item","bytes":3969,"description":"Trap object sprite for Dungeons and Dungeoners. Hazard sprite that damages players when triggered in dungeon exploration."},{"name":"ui-click","file":"audio/ui_click.wav","url":"incanto/assets/audio/ui_click.wav","kind":"audio","bytes":17332,"description":"Short tactile UI click for menus and buttons."},{"name":"walk","file":"audio/walk.mp3","url":"incanto/assets/audio/walk.mp3","kind":"audio","bytes":5642,"description":"Single footstep SFX for character movement (loop or one-shot)."},{"name":"wall00","file":"tiles/wall00.jpg","url":"incanto/assets/tiles/wall00.jpg","kind":"tile","bytes":44344,"description":"Basic wall tile texture for Dungeons and Dungeoners project, suitable for dungeon vertical boundaries."}]');function BL(e){let t=e.connections;return Array.isArray(t)?t:[]}function VL(e,t){if(!e||t===``)return null;if(t===`.`)return[];if(t.startsWith(`%`)){let n=t.slice(1);if(n===``||n.includes(`/`))return null;let r=[],i=(e,t)=>{e.name===n&&r.push(t),(e.children??[]).forEach((e,n)=>{i(e,[...t,n])})};return i(e,[]),r.length===1?r[0]:null}let n=t.startsWith(`/`),r=(n?t.slice(1):t).split(`/`);if(r.some(e=>e===``))return null;let i=r;if(n){if(r[0]!==e.name&&r[0]!==`root`)return null;i=r.slice(1)}let a=[],o=e;for(let t of i){if(t===`..`){if(a.length===0)return null;a.pop(),o=HL(e,a);continue}let n=(o.children??[]).findIndex(e=>e.name===t);if(n===-1)return null;a.push(n),o=o.children?.[n]}return a}function HL(e,t){let n=e;for(let e of t)n=n?.children?.[e];return n??null}function UL(e,t){if(!e)return``;if(t.length===0)return`.`;let n=[],r=e;for(let e of t){let t=r.children?.[e];if(!t)return``;n.push(String(t.name??``)),r=t}return n.join(`/`)}function WL(e,t){let n=e.root,r=e=>{if(typeof e!=`string`)return!1;let r=VL(n,e);return r!==null&&r.length===t.length&&r.every((e,n)=>e===t[n])},i=[],a=[];return BL(e).forEach((e,t)=>{r(e.from)&&i.push({index:t,conn:e}),r(e.to)&&a.push({index:t,conn:e})}),{outgoing:i,incoming:a}}function GL(e){if(!e)return[];let t=[];if(typeof e.type==`string`&&e.type!==``)try{t.push(...Ye(e.type))}catch{}let n=e.script;return typeof n?.name==`string`&&t.push(...st(n.name)),[...new Set(t)]}function KL(e){if(!e||e.script?.name)return[];let t=typeof e.type==`string`?e.type:``;if(!t)return[];let n=null;try{n=Ge(t)}catch{return[]}let r=new Set;for(let e=n.prototype;e&&e!==Object.prototype;){for(let t of Object.getOwnPropertyNames(e))t===`constructor`||t.startsWith(`_`)||typeof Object.getOwnPropertyDescriptor(e,t)?.value==`function`&&r.add(t);e=Object.getPrototypeOf(e)}for(let e of qL)r.delete(e);return[...r].sort()}var qL=new Set([`addChild`,`removeChild`,`addToGroup`,`removeFromGroup`,`isInGroup`,`getNode`,`getNodeOrNull`,`getPath`,`getRoot`,`find`,`findAll`,`on`,`off`,`once`,`emit`,`declareSignal`,`update`,`fixedUpdate`,`toJSON`,`diagnose`]);function JL(e){if(!e)return[];let t=[{path:`.`,label:`${e.name} (root)`}],n=(r,i)=>{(r.children??[]).forEach((r,a)=>{let o=[...i,a];t.push({path:UL(e,o),label:UL(e,o)}),n(r,o)})};return n(e,[]),t}function YL(e,t){Array.isArray(e.connections)||(e.connections=[]);let n=e.connections;return n.push(t),n.length-1}function XL(e,t,n){let r=BL(e)[t];r&&Object.assign(r,n)}function ZL(e,t){let n=BL(e);t<0||t>=n.length||(n.splice(t,1),n.length===0&&delete e.connections)}function QL(e,t){let n=e.working.root;if(!n)return null;let r=e.nodeAt(t);if(!r)return null;let i=document.createElement(`div`);i.className=`connections`;let{outgoing:a,incoming:o}=WL(e.working,t),s=UL(n,t);i.appendChild($L(QP({en:`emits (${a.length})`,ko:`보냄 (${a.length})`})));for(let t of a)i.appendChild(eR(e,t,`out`));if(i.appendChild(tR(e,r,s)),o.length>0){i.appendChild($L(QP({en:`receives (${o.length})`,ko:`받음 (${o.length})`})));for(let t of o)i.appendChild(eR(e,t,`in`))}return i}function $L(e){let t=document.createElement(`div`);return t.className=`conn-group`,t.textContent=e,t}function eR(e,{index:t,conn:n},r){let i=e.working.root,a=document.createElement(`div`);a.className=`conn-row`;let o=e.nodeAt(VL(i,String(n.from??``))??[-1]),s=r===`out`?`to`:`from`,c=String(n[s]??``),l=VL(i,c)===null,u=nR(GL(o),String(n.signal??``),n=>{e.mutate(()=>XL(e.working,t,{signal:n}))});u.title=QP({en:`signal`,ko:`시그널`});let d=document.createElement(`span`);d.className=`conn-arrow`,d.textContent=r===`out`?`→`:`←`;let f=nR(JL(i).map(e=>e.path),c,n=>{e.mutate(()=>XL(e.working,t,{[s]:n}))});f.title=QP({en:s,ko:s===`to`?`대상`:`출처`}),l&&f.classList.add(`dangling`);let p=KL(e.nodeAt(VL(i,String(n.to??``))??[-1])),m=n=>{e.mutate(()=>XL(e.working,t,{handler:n.trim()}))},h;if(p.length>0){let e=nR(p,String(n.handler??``),m);e.title=QP({en:`handler method`,ko:`핸들러 메서드`}),h=e}else{let e=document.createElement(`input`);e.type=`text`,e.className=`conn-handler`,e.value=String(n.handler??``),e.placeholder=`onSomething`,e.title=QP({en:`handler method on the target (defined in your behavior)`,ko:`대상의 핸들러 메서드 (비헤이비어에 정의)`}),e.addEventListener(`change`,()=>m(e.value)),h=e}let g=document.createElement(`button`);if(g.type=`button`,g.className=`conn-remove`,g.textContent=`✕`,g.title=QP({en:`remove this connection`,ko:`이 연결 삭제`}),g.addEventListener(`click`,()=>{e.mutate(()=>ZL(e.working,t))}),a.append(u,d,f,h,g),l){let e=document.createElement(`div`);e.className=`conn-warn`,e.textContent=QP({en:`'${c}' does not resolve — the game will refuse to load this scene.`,ko:`'${c}' 을(를) 찾을 수 없습니다 — 게임이 이 씬을 열지 못합니다.`});let t=document.createElement(`div`);return t.append(a,e),t}return a}function tR(e,t,n){let r=GL(t),i=document.createElement(`div`);i.className=`conn-add`;let a=document.createElement(`button`);return a.type=`button`,a.textContent=QP({en:`+ connect`,ko:`+ 연결`}),a.disabled=r.length===0,r.length===0&&(a.title=QP({en:`this node declares no signals`,ko:`이 노드는 시그널을 선언하지 않습니다`})),a.addEventListener(`click`,()=>{let i=r[0]??``,a={from:n,signal:i,to:n,handler:KL(t)[0]??`on${i.charAt(0).toUpperCase()}${i.slice(1)}`};e.mutate(()=>{YL(e.working,a)})}),i.appendChild(a),i}function nR(e,t,n){let r=document.createElement(`select`);r.className=`conn-select`;for(let n of e.includes(t)?e:[t,...e]){let e=document.createElement(`option`);e.value=n,e.textContent=n===``?`—`:n,n===t&&(e.selected=!0),r.appendChild(e)}return r.addEventListener(`change`,()=>n(r.value)),r}function rR(e,t,n,r){return{cx:Math.floor((n-e.x)/t),cy:Math.floor((r-e.y)/t)}}function iR(e,t,n,r){if(t<0||n<0||r.length!==1)return null;let i=e.map(e=>typeof e==`string`?e:e.map(e=>e>=0&&e<=9?String(e):`.`).join(``)),a=Math.max(t+1,...i.map(e=>e.length)),o=Math.max(n+1,i.length),s=[];for(let e=0;e<o;e++){let o=i[e]??``;o=o.padEnd(a,`.`),e===n&&(o=o.slice(0,t)+r+o.slice(t+1)),s.push(o)}return s}function aR(e,t){let n=new Set([`.`,`0`,`1`]);for(let t of e)if(typeof t==`string`)for(let e of t)e!==` `&&n.add(e);for(let e of Object.keys(t))n.add(e);return[...n]}var oR=zL;function sR(e){return(e.kind===`foliage`||e.kind===`tile`)&&!e.animation}function cR(e,t,n){if(e.textContent=``,t.selection===null){uR(e,t,n);return}let r=t.nodeAt(t.selection);r&&yR(e,t,r,n)}var lR=[`connections`,`input`,`multiplayer`];function uR(e,t,n){e.appendChild(GR(`scene`)),e.appendChild(ZR(`name`,String(t.working.name??``),e=>{t.mutate(()=>{t.working.name=e})}));let r=document.createElement(`select`);for(let e of[`2d`,`3d`]){let n=document.createElement(`option`);n.value=e,n.textContent=e,(t.working.dimension??`2d`)===e&&(n.selected=!0),r.appendChild(n)}r.addEventListener(`change`,()=>{t.mutate(()=>{t.working.dimension=r.value})}),e.appendChild(qR(`dimension`,r)),e.appendChild(GR(`physics`,`physics`));let i=(t.working.physics??{}).gravity??(t.working.dimension===`3d`?[0,-9.81,0]:[0,980]),a=t.working.dimension===`3d`?[0,-9.81,0]:[0,980];e.appendChild($R(`gravity`,i,e=>{t.mutate(()=>{if(JSON.stringify(e)===JSON.stringify(a)){let e={...t.working.physics};delete e.gravity,Object.keys(e).length===0?delete t.working.physics:t.working.physics=e}else t.working.physics={...t.working.physics,gravity:e}})})),e.appendChild(GR(`environment`)),dR(e,t),e.appendChild(GR(`constants`)),zR(e,t,n),e.appendChild(GR(`draw order bands`)),RR(e,t),e.appendChild(GR(`advanced`));for(let n of lR)e.appendChild(tz(n,t.working[n],e=>{t.mutate(()=>{e===void 0?delete t.working[n]:t.working[n]=e})}))}function dR(e,t){let n=t.working.environment??{},r=e=>{t.mutate(()=>{let n={...t.working.environment??{},...e};for(let e of Object.keys(n))n[e]===void 0&&delete n[e];Object.keys(n).length===0?delete t.working.environment:t.working.environment=n})};e.appendChild(fR(`background`,n.background??``,e=>{r({background:e===``?void 0:e})})),e.appendChild(fR(`ambient color`,n.ambient?.color??``,e=>{let t={...n.ambient,color:e===``?void 0:e};t.color===void 0&&delete t.color,r({ambient:Object.keys(t).length?t:void 0})})),e.appendChild(QR(`ambient power`,n.ambient?.intensity??0,e=>{r({ambient:{...n.ambient,intensity:e}})}));let i=n.rendering??{},a=e=>{let t={...i,...e};for(let e of Object.keys(t))t[e]===void 0&&delete t[e];r({rendering:Object.keys(t).length?t:void 0})},o=document.createElement(`input`);o.type=`checkbox`,o.checked=i.antialias!==!1,o.addEventListener(`change`,()=>{a({antialias:o.checked?void 0:!1})}),e.appendChild(qR(`antialias`,o));let s=document.createElement(`select`);for(let[e,t]of[[``,`1 — soft hiDPI upscale (default)`],[`device`,`device — crisp retina`],[`2`,`2`]]){let n=document.createElement(`option`);n.value=e,n.textContent=t,String(i.pixelRatio??``)===e&&(n.selected=!0),s.appendChild(n)}s.addEventListener(`change`,()=>{a({pixelRatio:s.value===``?void 0:s.value===`device`?`device`:Number(s.value)})}),e.appendChild(qR(`pixel ratio`,s))}function fR(e,t,n){let r=document.createElement(`div`);r.className=`color-row`;let i=document.createElement(`input`);i.type=`color`,i.value=/^#[0-9a-fA-F]{6}$/.test(t)?t:`#000000`;let a=document.createElement(`input`);return a.type=`text`,a.className=`mono`,a.placeholder=`unset`,a.value=t,i.addEventListener(`input`,()=>{a.value=i.value}),i.addEventListener(`change`,()=>n(i.value)),a.addEventListener(`change`,()=>n(a.value.trim())),r.append(i,a),qR(e,r)}function pR(e,t){let n=document.createElement(`div`);n.className=`subcard`;let r=document.createElement(`div`);r.className=`subcard-head`,r.textContent=`underwater`,n.appendChild(r);let i=t.props?.underwater,a=i!==!1,o=i&&typeof i==`object`&&!Array.isArray(i)?i:{},s=n=>{e.mutate(()=>{t.props||={},n===!0?delete t.props.underwater:t.props.underwater=n,Object.keys(t.props).length===0&&delete t.props})},c=(e,t)=>{let n={...o};t===void 0||t===``?delete n[e]:n[e]=t,s(Object.keys(n).length===0?!0:n)},l=document.createElement(`input`);if(l.type=`checkbox`,l.checked=a,l.addEventListener(`change`,()=>s(l.checked)),n.appendChild(qR(`enabled`,l)),a){n.appendChild(fR(`murk color`,String(o.color??``),e=>c(`color`,e))),n.appendChild(QR(`visibility (m)`,Number(o.visibility??22),e=>c(`visibility`,e===22?void 0:e),()=>c(`visibility`,void 0)));let e=document.createElement(`input`);e.type=`checkbox`,e.checked=(o.caustics??!0)!==!1,e.addEventListener(`change`,()=>c(`caustics`,e.checked?void 0:!1)),n.appendChild(qR(`caustics`,e))}return n}function mR(e,t,n){let r=document.createElement(`div`);r.className=`subcard`;let i=document.createElement(`div`);i.className=`subcard-head`,i.textContent=`material`,r.appendChild(i);let a=t.props?.material??{},o=(n,r)=>{let i={...t.props?.material??{}};r===void 0||r===``?delete i[n]:i[n]=r;let a=Object.keys(i).length===0?void 0:i;e.mutate(()=>{t.props||={},a===void 0?(delete t.props.material,Object.keys(t.props).length===0&&delete t.props):t.props.material=a},e.selection?{path:e.selection,key:`material`,value:a}:void 0)};r.appendChild(fR(`color`,String(a.color??``),e=>o(`color`,e))),r.appendChild(vR(`roughness`,Number(a.roughness??1),e=>o(`roughness`,e))),r.appendChild(vR(`metalness`,Number(a.metalness??0),e=>o(`metalness`,e))),r.appendChild(fR(`emissive`,String(a.emissive??``),e=>o(`emissive`,e))),r.appendChild(vR(`emissive power`,Number(a.emissiveIntensity??1),e=>o(`emissiveIntensity`,e===1?void 0:e),2)),r.appendChild(vR(`opacity`,Number(a.opacity??1),e=>o(`opacity`,e===1?void 0:e))),r.appendChild(vR(`clearcoat`,Number(a.clearcoat??0),e=>o(`clearcoat`,e===0?void 0:e))),r.appendChild(vR(`clearcoat rough`,Number(a.clearcoatRoughness??0),e=>o(`clearcoatRoughness`,e===0?void 0:e))),r.appendChild(vR(`reflection`,Number(a.envMapIntensity??1),e=>o(`envMapIntensity`,e===1?void 0:e),3));let s=document.createElement(`input`);s.type=`checkbox`,s.checked=a.wireframe===!0,s.addEventListener(`change`,()=>o(`wireframe`,s.checked||void 0)),r.appendChild(qR(`wireframe`,s));let c=document.createElement(`input`);c.type=`checkbox`,c.checked=a.flatShading===!0,c.addEventListener(`change`,()=>o(`flatShading`,c.checked||void 0)),r.appendChild(qR(`flatShading`,c));let l=document.createElement(`input`);l.type=`checkbox`,l.checked=a.depthTest===!1,l.addEventListener(`change`,()=>{o(`depthTest`,l.checked?!1:void 0),o(`depthWrite`,l.checked?!1:void 0)}),r.appendChild(qR(`draw on top (decal)`,l)),r.appendChild(kR(`map (texture)`,String(a.map??``),AR(e=>sR(e)&&!e.name.includes(`normal`)&&!e.name.includes(`roughness`)),e=>o(`map`,e.trim()),{placeholder:`built-in or custom URL`,library:{kind:`image`,target:`map`,shelf:[`3d`,`textures`]},ctx:n})),r.appendChild(kR(`normal map`,String(a.normalMap??``),AR(e=>sR(e)&&e.name.includes(`normal`)),e=>o(`normalMap`,e.trim()),{placeholder:`built-in or custom URL`,library:{kind:`image`,target:`normal map`,shelf:[`3d`,`textures`]},ctx:n}));let u=!!(a.map||a.normalMap),d=Array.isArray(a.repeat)?a.repeat:[1,1],f=$R(`repeat [u,v]`,[d[0]??1,d[1]??1],e=>{let[t,n]=e;!Number.isFinite(t)||!Number.isFinite(n)||t===1&&n===1||!t&&!n?o(`repeat`,void 0):o(`repeat`,[t,n])});return f.title=u?`Texture tiling across the mesh UVs.`:`Only takes effect with a map/normal map set (engine validates).`,r.appendChild(f),r}var hR=new Set([`animationLoop`,`animationSpeed`,`animationOffset`,`animationUpper`,`animationUpperLoop`,`upperBodyRoot`]);function gR(e,t,n,r){let i=document.createElement(`div`);i.className=`subcard anim-card`;let a=document.createElement(`div`);a.className=`subcard-head`;let o=document.createElement(`strong`);o.textContent=`animation`,a.appendChild(o),i.appendChild(a);let s=String(t.props?.animation??``);if(i.appendChild(kR(`clip`,s,n.animationsForSelection().map(e=>({label:e,value:e,hint:e.startsWith(`$`)?`scene asset`:`clip in this model`})),n=>TR(e,t,`animation`,n.trim(),``),{placeholder:`clip name or $assetKey — empty = still`,library:{kind:`model`,target:`animation`,shelf:[`3d`,`animations`],asAsset:!0,assetType:`animation`},ctx:n})),!s){let a=document.createElement(`div`);return a.className=`muted-note`,a.textContent=`Pick a clip and it plays as soon as the scene loads — no script needed.`,i.appendChild(a),i.appendChild(_R(e,t,n,r)),i}i.appendChild(VR(e,t,`animationLoop`,r.animationLoop?.default??!0,void 0,`loop`));let c=vR(`speed`,Number(t.props?.animationSpeed??1),n=>TR(e,t,`animationSpeed`,n,1),3,-3);c.title=`1 = as authored · 0 freezes the pose · negative plays backwards (a closing door is an opening one reversed).`,i.appendChild(c);let l=VR(e,t,`animationOffset`,r.animationOffset?.default??0,void 0,`offset (s)`);return l.title=`Seconds into the clip to start at. Give copies different offsets so a row of torches stops flickering in lockstep.`,i.appendChild(l),i.appendChild(_R(e,t,n,r)),i}function _R(e,t,n,r){let i=document.createElement(`details`);i.className=`anim-upper`,t.props?.animationUpper&&(i.open=!0);let a=document.createElement(`summary`);return a.textContent=`upper-body layer`,a.title=`Play a second clip on the upper body only — attack while running, wave while walking.`,i.appendChild(a),i.appendChild(kR(`clip`,String(t.props?.animationUpper??``),n.animationsForSelection().map(e=>({label:e,value:e})),n=>TR(e,t,`animationUpper`,n.trim(),``),{placeholder:`empty = off`,ctx:n})),i.appendChild(VR(e,t,`animationUpperLoop`,r.animationUpperLoop?.default??!1,void 0,`loop`)),i.appendChild(VR(e,t,`upperBodyRoot`,r.upperBodyRoot?.default??`Spine`,void 0,`root bone`)),i}function vR(e,t,n,r=1,i=0){let a=document.createElement(`div`);a.className=`slider-row`;let o=document.createElement(`input`);o.type=`range`,o.min=String(i),o.max=String(r),o.step=`0.05`,o.value=String(Number.isFinite(t)?t:0);let s=document.createElement(`input`);return s.type=`number`,s.step=`0.05`,s.min=String(i),s.max=String(r),s.value=o.value,o.addEventListener(`input`,()=>{s.value=o.value}),o.addEventListener(`change`,()=>n(Number(o.value))),s.addEventListener(`change`,()=>{o.value=s.value,n(Number(s.value))}),a.append(o,s),qR(e,a)}function yR(e,t,n,r){if(e.appendChild(GR(n.type??`instance`)),e.appendChild(bR(n)),e.appendChild(ZR(`name`,n.name??``,e=>{e.trim()===``||t.selection===null||t.renameNode(t.selection,e.trim())})),n.type===`TileMap2D`&&r?.paint&&e.appendChild(ez(n,r.paint)),n.type){let i;try{i=qe(n.type)}catch{i={}}for(let[a,o]of Object.entries(i))if(a===`collider`)e.appendChild(wR(t,n,o.default));else if(a===`material`)e.appendChild(mR(t,n,r));else if(n.type===`ModelInstance3D`&&a===`model`&&r)e.appendChild(kR(`model`,String(n.props?.model??``),r.modelRefs().map(e=>({label:e,value:e,hint:`scene asset`})),e=>TR(t,n,`model`,e.trim(),``),{placeholder:`$assetKey`,library:{kind:`model`,target:`model`,shelf:[`3d`,`characters`],asAsset:!0},ctx:r}));else if(n.type===`BoneAttachment3D`&&a===`bone`&&r?.bonesForSelection)e.appendChild(DR(`bone`,String(n.props?.bone??``),r.bonesForSelection(String(n.props?.target??``)),e=>TR(t,n,`bone`,e,``)));else if(n.type===`ModelInstance3D`&&a===`animation`&&r)e.appendChild(gR(t,n,r,i));else if(!(n.type===`ModelInstance3D`&&hR.has(a)))if((n.type===`Sprite3D`||n.type===`AnimatedSprite3D`)&&(a===`texture`||a===`sheet`))e.appendChild(kR(a===`sheet`?`sheet (image URL)`:`texture (image URL)`,String(n.props?.[a]??``),AR(e=>e.kind===`character`||e.kind===`item`),e=>TR(t,n,a,e.trim(),``),{placeholder:`image URL — empty hides the sprite`,library:{kind:`image`,target:a,shelf:[`2d`,`sprite_characters`]},ctx:r}));else if(n.type===`TileMap2D`&&a===`texture`)e.appendChild(kR(`texture (atlas $ref)`,String(n.props?.texture??``),(r?.assetRefs?.([`texture`,`spritesheet`])??[]).map(e=>({label:e,value:e,hint:`scene asset`})),e=>TR(t,n,`texture`,e.trim(),``),{placeholder:`$assetKey`,library:{kind:`image`,target:`tile atlas`,shelf:[`2d`,`sprite_characters`],asAsset:!0,assetType:`texture`},ctx:r}));else if(n.type===`Tree3D`&&a===`leafTexture`)e.appendChild(kR(`leaf texture`,String(n.props?.leafTexture??``),AR(e=>e.name.startsWith(`leaves_`)),e=>TR(t,n,`leafTexture`,e.trim(),``),{placeholder:`default (per-type) or URL`,library:{kind:`image`,target:`leaf texture`,shelf:[`3d`,`textures`]},ctx:r}));else if(n.type===`Terrain3D`&&a===`textureBase`)e.appendChild(kR(`texture base`,String(n.props?.textureBase??o.default??``),MR,e=>TR(t,n,`textureBase`,e.trim(),o.default),{placeholder:`splat texture base URL`}));else if(n.type===`AnimatedSprite2D`&&a===`sheet`||n.type===`Sprite2D`&&a===`texture`){let i=a===`sheet`;e.appendChild(NR(t,n,a,r,i))}else n.type===`AudioPlayer`&&a===`src`?e.appendChild(kR(`src (audio file)`,String(n.props?.src??``),jR(),e=>TR(t,n,`src`,e.trim(),``),{placeholder:`built-in or custom URL — or use preset`,note:"For zero-asset SFX, set the `preset` prop instead of src.",library:{kind:`audio`,target:`audio src`},ctx:r})):n.type===`Flowers3D`&&a===`varieties`?e.appendChild(PR(t,n)):n.type===`Water3D`&&a===`underwater`?e.appendChild(pR(t,n)):e.appendChild(VR(t,n,a,o.default,o.options))}if(e.appendChild(GR(`structure`)),e.appendChild(xR(t,n)),e.appendChild(SR(t,n)),e.appendChild(CR(t,n)),t.selection){let n=QL(t,t.selection);n&&(e.appendChild(GR(`connections`,`connections`)),e.appendChild(n))}}function bR(e){let t=document.createElement(`div`);t.className=`field uid-line`;let n=document.createElement(`span`);n.textContent=`uid`;let r=document.createElement(`div`);r.className=`uid-value`;let i=document.createElement(`code`);i.textContent=String(e.uid??``);let a=document.createElement(`button`);return a.type=`button`,a.className=`uid-copy`,a.title=`Copy uid`,a.innerHTML=`<svg aria-hidden="true" width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>`,a.addEventListener(`click`,()=>{navigator.clipboard?.writeText(String(e.uid??``)),a.classList.add(`copied`),a.innerHTML=`✓`,setTimeout(()=>{a.classList.remove(`copied`),a.innerHTML=`<svg aria-hidden="true" width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>`},800)}),r.append(i,a),t.append(n,r),t}function xR(e,t){let n=document.createElement(`label`);n.className=`field wide`;let r=document.createElement(`span`);r.append(`groups `,RL(`groups`));let i=document.createElement(`div`);i.className=`chips`;for(let n of t.groups??[])i.appendChild(KR(n,()=>{e.mutate(()=>{t.groups=(t.groups??[]).filter(e=>e!==n),t.groups.length===0&&delete t.groups})}));let a=document.createElement(`input`);return a.placeholder=(t.groups?.length??0)===0?`add a tag… (e.g. coins)`:``,a.addEventListener(`keydown`,n=>{if(n.key!==`Enter`)return;let r=a.value.trim();r&&e.mutate(()=>{t.groups=[...t.groups??[],r]})}),i.appendChild(a),i.addEventListener(`click`,()=>a.focus()),n.append(r,i),n}function SR(e,t){let n=document.createElement(`div`);n.className=`subcard`;let r=document.createElement(`div`);r.className=`subcard-head`,r.append(`script `,RL(`script`));let i=document.createElement(`span`);i.className=`spacer`,r.appendChild(i);let a=t.script;if(a){let n=document.createElement(`button`);n.type=`button`,n.className=`linklike`,n.textContent=`detach`,n.addEventListener(`click`,()=>{e.mutate(()=>{delete t.script})}),r.appendChild(n)}if(n.appendChild(r),!a){let r=document.createElement(`div`);r.className=`muted-note`,r.textContent=`No behavior attached. Behaviors are TypeScript classes in your game.`;let i=document.createElement(`button`);return i.type=`button`,i.className=`ghost`,i.textContent=`+ attach behavior`,i.addEventListener(`click`,()=>{e.mutate(()=>{t.script={name:`MyBehavior`}})}),n.append(r,i),n}n.appendChild(ZR(`name`,a.name??``,n=>{e.mutate(()=>{t.script.name=n.trim()})})),n.appendChild(tz(`props`,a.props,n=>{e.mutate(()=>{n===void 0?delete t.script.props:t.script.props=n})}));let o=document.createElement(`div`);return o.className=`muted-note`,o.textContent=`? has copy-paste boilerplate for the game side.`,n.appendChild(o),n}function CR(e,t){let n=document.createElement(`div`);n.className=`subcard`;let r=document.createElement(`div`);r.className=`subcard-head`,r.append(`network `,RL(`network`)),n.appendChild(r);let i=t.network,a=document.createElement(`select`);for(let[e,t]of[[``,`not replicated`],[`owner`,`owner — this player broadcasts it`]]){let n=document.createElement(`option`);n.value=e,n.textContent=t,(i?.mode??``)===e&&(n.selected=!0),a.appendChild(n)}if(a.addEventListener(`change`,()=>{e.mutate(()=>{a.value===``?delete t.network:t.network={mode:a.value,sync:i?.sync??[`position`]}})}),n.appendChild(qR(`mode`,a)),i?.mode===`owner`){let r=document.createElement(`div`);r.className=`chips`;for(let n of i.sync??[])r.appendChild(KR(n,()=>{e.mutate(()=>{t.network.sync=(i.sync??[]).filter(e=>e!==n)})}));let a=document.createElement(`input`);a.placeholder=`position · Skin.animation…`,a.addEventListener(`keydown`,n=>{if(n.key!==`Enter`)return;let r=a.value.trim();r&&e.mutate(()=>{t.network.sync=[...i.sync??[],r]})}),r.appendChild(a);let o=document.createElement(`label`);o.className=`field wide`;let s=document.createElement(`span`);s.textContent=`sync keys`,o.append(s,r),n.appendChild(o),n.appendChild(QR(`throttle ms`,i.throttleMs??50,n=>{e.mutate(()=>{t.network.throttleMs=n})}))}return n}function wR(e,t,n){let r=document.createElement(`div`);r.className=`subcard`;let i=document.createElement(`div`);i.className=`subcard-head`,i.append(`collider `,RL(`collider`)),r.appendChild(i);let a=t.props?.collider??{},o=n=>{e.mutate(()=>{t.props||={};let e=t.props;Object.keys(n).length===0?(delete e.collider,Object.keys(e).length===0&&delete t.props):e.collider=n})},s=(t.type??``).endsWith(`3D`),c=s?[[``,`none`],[`box`,`box — crates, floors`],[`sphere`,`sphere — balls, pickups`],[`capsule`,`capsule — characters`]]:[[``,`none`],[`rect`,`rect — boxes, platforms`],[`circle`,`circle — coins, balls`],[`capsule`,`capsule — characters`]],l=document.createElement(`select`);for(let[e,t]of c){let n=document.createElement(`option`);n.value=e,n.textContent=t,(a.shape??``)===e&&(n.selected=!0),l.appendChild(n)}return l.addEventListener(`change`,()=>{l.value===``?o({}):l.value===`rect`?o({shape:`rect`,size:a.size??[32,32]}):l.value===`box`?o({shape:`box`,size:a.size??[1,1,1]}):l.value===`circle`?o({shape:`circle`,radius:a.radius??16}):l.value===`sphere`?o({shape:`sphere`,radius:a.radius??.5}):o(s?{shape:`capsule`,radius:a.radius??.4,height:a.height??1}:{shape:`capsule`,radius:a.radius??12,height:a.height??16})}),r.appendChild(qR(`shape`,l)),a.shape===`rect`||a.shape===`box`?r.appendChild($R(`size`,a.size??(s?[1,1,1]:[32,32]),e=>o({...a,size:e}))):a.shape===`circle`||a.shape===`sphere`?r.appendChild(QR(`radius`,a.radius??(s?.5:16),e=>o({...a,radius:e}))):a.shape===`capsule`&&(r.appendChild(QR(`radius`,a.radius??12,e=>o({...a,radius:e}))),r.appendChild(QR(`height`,a.height??16,e=>o({...a,height:e})))),a.shape&&r.appendChild($R(`offset`,a.offset??(s?[0,0,0]:[0,0]),e=>o({...a,offset:e}))),r}function TR(e,t,n,r,i){e.mutate(()=>{t.props||={},JSON.stringify(r)===JSON.stringify(i)?(delete t.props[n],Object.keys(t.props).length===0&&delete t.props):t.props[n]=r})}var ER=0;function DR(e,t,n,r){let i=document.createElement(`input`);i.type=`text`,i.value=t;let a=`suggest-${ER++}`;i.setAttribute(`list`,a);let o=document.createElement(`datalist`);o.id=a;for(let e of n){let t=document.createElement(`option`);t.value=e,o.appendChild(t)}i.addEventListener(`change`,()=>r(i.value.trim()));let s=qR(e,i);return s.appendChild(o),s}var OR=0;function kR(e,t,n,r,i={}){let a=document.createElement(`label`);a.className=`field wide asset-field`;let o=document.createElement(`span`);o.textContent=e,a.appendChild(o);let s=document.createElement(`input`);s.type=`text`,s.value=t,i.placeholder&&(s.placeholder=i.placeholder),s.addEventListener(`change`,()=>r(s.value.trim()));let c=document.createElement(`button`);c.type=`button`,c.className=`asset-toggle`,c.title=`Browse built-in assets`,c.textContent=`▾`;let l=document.createElement(`div`);if(l.className=`asset-control`,l.append(s),i.library&&i.ctx?.openLibrary){let t=document.createElement(`button`);t.type=`button`,t.className=`asset-lib`,t.textContent=`📚`,t.title=`Browse the agent8 library for a ${i.library.kind}`,t.addEventListener(`click`,t=>{t.preventDefault();let n=i.ctx?.openLibrary;n&&n({kind:i.library?.kind??`any`,target:i.library?.target??e,...i.library?.shelf?{shelf:i.library.shelf}:{},...i.library?.asAsset?{asAsset:!0}:{},...i.library?.assetType?{assetType:i.library.assetType}:{},...i.library?.onProps?{onProps:i.library.onProps}:{}}).then(e=>{e!==null&&(s.value=e,r(e))})}),l.append(t)}l.append(c),a.appendChild(l);let u=document.createElement(`div`);u.className=`asset-panel`,u.hidden=!0;let d=document.createElement(`input`);d.type=`text`,d.className=`asset-search`,d.placeholder=`search ${n.length} built-in${n.length===1?``:`s`}…`;let f=document.createElement(`div`);f.className=`asset-options`,u.append(d,f),a.appendChild(u);let p=e=>{f.textContent=``;let t=e.trim().toLowerCase(),i=n.filter(e=>t===``||e.label.toLowerCase().includes(t)||(e.hint?.toLowerCase().includes(t)??!1)||e.value.toLowerCase().includes(t));if(i.length===0){let e=document.createElement(`div`);e.className=`asset-empty`,e.textContent=`no match — type a custom URL above`,f.appendChild(e);return}for(let e of i){let t=document.createElement(`button`);t.type=`button`,t.className=`asset-option`,t.title=[e.label,e.full??e.hint,e.value===e.label?null:e.value].filter(Boolean).join(`
|
|
8424
|
+
`);let n=document.createElement(`strong`);if(n.textContent=e.label,t.appendChild(n),e.hint){let n=document.createElement(`small`);n.textContent=e.hint,t.appendChild(n)}t.addEventListener(`click`,()=>{s.value=e.value,u.hidden=!0,r(e.value)}),f.appendChild(t)}};if(c.addEventListener(`click`,()=>{u.hidden=!u.hidden,u.hidden||(p(d.value),d.focus())}),d.addEventListener(`input`,()=>p(d.value)),d.addEventListener(`keydown`,e=>{e.key===`Escape`&&(u.hidden=!0)}),i.note){let e=document.createElement(`div`);e.className=`muted-note asset-note`,e.textContent=i.note,a.appendChild(e)}return s.id=`asset-input-${OR++}`,a.htmlFor=s.id,a}function AR(e){return oR.filter(e).map(e=>({label:e.name,value:e.url,hint:`${e.kind} · ${e.description}`,full:`${e.kind} · ${e.description}`}))}function jR(){return oR.filter(e=>e.kind===`audio`).map(e=>({label:e.name,value:e.url,hint:`audio · ${e.description}`,full:`audio · ${e.description}`}))}var MR=[{label:`agent8 default terrain`,value:`https://agent8-games.verse8.io/assets/3D/default/textures/terrain`,hint:`sand/grass/stone/snow splat set (Terrain3D default)`}];function NR(e,t,n,r,i){let a=String(t.props?.[n]??``),o=i?[`spritesheet`]:[`texture`,`spritesheet`],s=(r?.assetRefs?.(o)??[]).map(e=>({label:e,value:e,hint:`scene asset`})),c=oR.filter(e=>i?!!e.animation:e.kind===`character`||e.kind===`item`||e.kind===`tile`);for(let e of c)s.push({label:`built-in: ${e.name}`,value:`$${e.name}`,hint:`${e.kind} · creates a scene asset (${e.animation?`spritesheet`:`texture`})`});return kR(i?`sheet`:`texture`,a,s,i=>{let a=i.startsWith(`$`)&&c.find(e=>`$${e.name}`===i);if(a&&r?.addAsset){let i={type:a.animation?`spritesheet`:`texture`,url:a.url};if(a.animation){let e=a.frameWidth,t=a.frameHeight;e&&(i.frameWidth=e),t&&(i.frameHeight=t)}TR(e,t,n,`$${r.addAsset(a.name,i).replace(/^\$/,``)}`,``);return}TR(e,t,n,i.trim(),``)},{placeholder:`$assetKey`,note:"Picks a $asset ref. Built-ins create the scene asset; packaged sprites need `incanto-assets copy` (or a bundler import) to serve at runtime.",library:{kind:`image`,target:i?`sheet`:`texture`,shelf:[`2d`,`sprite_characters`],asAsset:!0,assetType:i?`spritesheet`:`texture`,onProps:n=>{for(let[r,i]of Object.entries(n))TR(e,t,r,i,void 0)}},ctx:r})}function PR(e,t){let n=document.createElement(`label`);n.className=`field wide`;let r=document.createElement(`span`);r.textContent=`varieties`,n.appendChild(r);let i=new Set(Array.isArray(t.props?.varieties)?t.props.varieties:[]),a=document.createElement(`div`);a.className=`chips varieties`;let o=()=>{let n=MD.filter(e=>i.has(e));TR(e,t,`varieties`,n.length===0||n.length===MD.length?[]:n,[])};for(let e of MD){let t=document.createElement(`label`);t.className=`variety-opt`;let n=document.createElement(`input`);n.type=`checkbox`,n.checked=i.size===0||i.has(e),n.addEventListener(`change`,()=>{if(i.size===0)for(let e of MD)i.add(e);n.checked?i.add(e):i.delete(e),o()});let r=document.createElement(`span`);r.textContent=e,t.append(n,r),a.appendChild(t)}n.appendChild(a);let s=document.createElement(`div`);return s.className=`muted-note`,s.textContent=`All (or none) = the default mix of all three.`,n.appendChild(s),n}var FR=[[`number`,()=>0],[`text`,()=>``],[`boolean`,()=>!1],[`color`,()=>`#ffffff`],[`vec2`,()=>[0,0]],[`vec3`,()=>[0,0,0]]];function IR(e,t){let n=0,r=e=>{if(bn(e)){e[`@const`]===t&&(n+=1);return}if(Array.isArray(e))for(let t of e)r(t);else if(e&&typeof e==`object`)for(let t of Object.values(e))r(t)};for(let[t,n]of Object.entries(e))t!==`constants`&&r(n);return n}function LR(e,t,n){let r=e=>{if(bn(e))return e[`@const`]===t?JSON.parse(JSON.stringify(n??null)):e;if(Array.isArray(e))return e.map(r);if(e&&typeof e==`object`){let t=e;for(let e of Object.keys(t))t[e]=r(t[e]);return t}return e};for(let t of Object.keys(e))t!==`constants`&&(e[t]=r(e[t]))}function RR(e,t){let n=t.working.orderGroups??{},r=Object.keys(n),i=e=>{t.mutate(()=>{Object.keys(e).length===0?delete t.working.orderGroups:t.working.orderGroups=e})},a=document.createElement(`div`);if(a.className=`hint`,a.textContent=`Built in: ${Object.entries(ht).map(([e,t])=>`${e} ${t}`).join(` · `)}`,e.appendChild(a),r.length===0){let t=document.createElement(`div`);t.className=`hint`,t.textContent=`No extra bands. Add one to sort between (or beyond) the built-ins — a band is the base offset, not just a name.`,e.appendChild(t)}for(let t of r){let r=document.createElement(`div`);r.className=`const-row`,r.appendChild(QR(t,n[t]??0,e=>i({...n,[t]:e})));let a=document.createElement(`button`);a.type=`button`,a.className=`const-del`,a.textContent=`✕`,a.title=`delete band "${t}"`,a.addEventListener(`click`,()=>{let e={...n};delete e[t],i(e)}),r.appendChild(a),e.appendChild(r)}let o=document.createElement(`div`);o.className=`const-add`;let s=document.createElement(`input`);s.type=`text`,s.placeholder=`new band name`;let c=document.createElement(`input`);c.type=`number`,c.placeholder=`base`,c.className=`band-base`;let l=document.createElement(`button`);l.type=`button`,l.textContent=`add`,l.addEventListener(`click`,()=>{let e=s.value.trim(),t=Number(c.value);!e||n[e]!==void 0||!Number.isFinite(t)||(i({...n,[e]:t}),s.value=``,c.value=``)}),o.append(s,c,l),e.appendChild(o)}function zR(e,t,n){let r=t.working.constants??{},i=Object.keys(r),a=(e,n)=>{t.mutate(()=>{let r={...t.working.constants??{}};r[e]=n,t.working.constants=r})},o=(e,n)=>{t.mutate(()=>{n&&LR(t.working,e,r[e]);let i={...t.working.constants??{}};delete i[e],Object.keys(i).length===0?delete t.working.constants:t.working.constants=i})},s=e=>{let r=IR(t.working,e);if(r>0&&n?.confirm){n.confirm(`"${e}" is used by ${r} prop${r===1?``:`s`}. Unlink them (inline its current value) and delete?`,`unlink & delete`,()=>o(e,!0));return}o(e,r>0)};if(i.length===0){let t=document.createElement(`div`);t.className=`hint`,t.textContent=`No constants yet. Add one, then bind props to it with the 🔗 picker.`,e.appendChild(t)}for(let t of i){let n=document.createElement(`div`);n.className=`const-row`,n.appendChild(BR(t,r[t],e=>a(t,e)));let i=document.createElement(`button`);i.type=`button`,i.className=`const-del`,i.textContent=`✕`,i.title=`delete constant "${t}"`,i.addEventListener(`click`,()=>s(t)),n.appendChild(i),e.appendChild(n)}let c=document.createElement(`div`);c.className=`const-add`;let l=document.createElement(`input`);l.type=`text`,l.placeholder=`new constant name`;let u=document.createElement(`select`);for(let[e]of FR){let t=document.createElement(`option`);t.value=e,t.textContent=e,u.appendChild(t)}let d=document.createElement(`button`);d.type=`button`,d.textContent=`+ add`,d.addEventListener(`click`,()=>{let e=l.value.trim();e&&(t.working.constants??{})[e]===void 0&&(a(e,(FR.find(([e])=>e===u.value)?.[1]??(()=>0))()),l.value=``)}),c.append(l,u,d),e.appendChild(c)}function BR(e,t,n){let r=Be(t);if(r===`number`)return QR(e,t,e=>n(e),()=>n(0));if(r===`boolean`){let r=document.createElement(`input`);return r.type=`checkbox`,r.checked=t===!0,r.addEventListener(`change`,()=>n(r.checked)),qR(e,r)}return r===`array`&&Array.isArray(t)&&t.every(e=>typeof e==`number`)?$R(e,t,e=>n(e)):r===`string`?ZR(e,String(t),e=>n(e)):tz(e,t,e=>n(e??null),JSON.stringify(t))}function VR(e,t,n,r,i,a){let o=t.props?.[n]??r,s=Be(r),c=s===`number`||s===`boolean`||s===`string`||s===`array`,l=i=>{let a=bn(i);e.mutate(()=>{t.props||={};let e=t.props;JSON.stringify(i)===JSON.stringify(r)?(delete e[n],Object.keys(e).length===0&&delete t.props):e[n]=i},e.selection&&c&&!a?{path:e.selection,key:n,value:i}:void 0)},u=HR(e,s,r);if(bn(o))return UR(n,o[`@const`],u,l,r);let d=e=>u.length>0?WR(e,u,l):e;if(s===`number`)return d(QR(a??n,o,e=>l(e),()=>l(r)));if(s===`boolean`){let e=document.createElement(`input`);return e.type=`checkbox`,e.checked=o===!0,e.addEventListener(`change`,()=>l(e.checked)),d(qR(a??n,e))}if(s===`string`){if(i&&i.length>0){let t=n===`orderGroup`?XR(e):[];return d(JR(a??n,String(o??``),t.length>0?[...i,...t]:i,e=>l(e),n===`orderGroup`?t=>YR(t,e):void 0))}return d(ZR(a??n,String(o??``),e=>l(e)))}return s===`array`&&Array.isArray(r)&&r.length>0&&r.every(e=>typeof e==`number`)?d($R(n,o??r,e=>l(e))):tz(n,o===r?void 0:o,e=>{l(e===void 0?r:e)},JSON.stringify(r))}function HR(e,t,n){let r=e.working.constants??{};return Object.keys(r).filter(e=>{let i=r[e];return Be(i)===t?t===`array`&&Array.isArray(n)&&Array.isArray(i)?i.length===n.length:!0:!1})}function UR(e,t,n,r,i){let a=document.createElement(`select`),o=n.includes(t)?n:[t,...n];for(let e of o){let n=document.createElement(`option`);n.value=e,n.textContent=e,e===t&&(n.selected=!0),a.appendChild(n)}let s=document.createElement(`option`);s.value=``,s.textContent=`↺ custom value`,a.appendChild(s),a.addEventListener(`change`,()=>{r(a.value?{"@const":a.value}:i)});let c=qR(`🔗 ${e}`,a);return c.classList.add(`const-bound`),c}function WR(e,t,n){let r=document.createElement(`select`);r.className=`const-picker`,r.title=`Bind to a named constant`;let i=document.createElement(`option`);i.value=``,i.textContent=`🔗`,r.appendChild(i);for(let e of t){let t=document.createElement(`option`);t.value=e,t.textContent=e,r.appendChild(t)}return r.value=``,r.addEventListener(`change`,()=>{r.value&&n({"@const":r.value})}),e.classList.add(`has-const-picker`),e.appendChild(r),e}function GR(e,t){let n=document.createElement(`div`);n.className=`section-title`,n.textContent=e,t&&n.appendChild(RL(t));let r=document.createElement(`span`);return r.className=`rule`,n.appendChild(r),n}function KR(e,t){let n=document.createElement(`span`);n.className=`chip`,n.textContent=e;let r=document.createElement(`button`);return r.type=`button`,r.textContent=`✕`,r.addEventListener(`click`,e=>{e.stopPropagation(),t()}),n.appendChild(r),n}function qR(e,t){let n=document.createElement(`label`);n.className=`field`;let r=document.createElement(`span`);return r.textContent=e,n.append(r,t),n}function JR(e,t,n,r,i){let a=document.createElement(`select`);for(let e of n.includes(t)?n:[t,...n]){let n=document.createElement(`option`);n.value=e;let r=i?.(e);n.textContent=r?`${e} (${r})`:e,e===t&&(n.selected=!0),a.appendChild(n)}return a.addEventListener(`change`,()=>r(a.value)),qR(e,a)}function YR(e,t){let n={...ht,...t.working.orderGroups??{}}[e];return n===void 0?`unknown — sorts as default`:String(n)}function XR(e){return Object.keys(e.working.orderGroups??{})}function ZR(e,t,n){let r=document.createElement(`input`);return r.type=`text`,r.value=t,r.addEventListener(`change`,()=>n(r.value)),qR(e,r)}function QR(e,t,n,r){let i=document.createElement(`input`);return i.type=`number`,i.step=`any`,i.value=String(t),i.addEventListener(`change`,()=>{if(i.value.trim()===``){r?.();return}let e=Number(i.value);Number.isFinite(e)&&n(e)}),qR(e,i)}function $R(e,t,n){let r=document.createElement(`div`);r.className=`vector-row`;let i=[...t];return i.forEach((e,t)=>{let a=document.createElement(`input`);a.type=`number`,a.step=`any`,a.value=String(e??0),a.addEventListener(`change`,()=>{let e=Number(a.value);Number.isFinite(e)&&(i[t]=e,n([...i]))}),r.appendChild(a)}),qR(e,r)}function ez(e,t){let n=document.createElement(`div`);n.className=`field wide tile-paint`;let r=document.createElement(`button`);r.type=`button`,r.className=t.active()?`paint-toggle on`:`paint-toggle`,r.textContent=t.active()?`🖌 painting — click the canvas`:`🖌 paint tiles`,r.addEventListener(`click`,()=>t.toggle()),n.appendChild(r);let i=document.createElement(`div`);i.className=`paint-palette`;let a=e.props?.cells??[],o=e.props?.legend??{};for(let e of aR(a,o)){let n=document.createElement(`button`);n.type=`button`,n.className=t.brush()===e?`paint-chip on`:`paint-chip`,n.textContent=e===`.`?`␡`:e,n.title=e===`.`?`eraser (empty cell)`:`tile '${e}'`,n.addEventListener(`click`,()=>t.setBrush(e)),i.appendChild(n)}let s=document.createElement(`input`);s.type=`text`,s.maxLength=1,s.className=`paint-brush-input`,s.value=t.brush(),s.title=`brush char (digit or a legend char)`,s.addEventListener(`change`,()=>{s.value.length===1&&t.setBrush(s.value)}),i.appendChild(s),n.appendChild(i);let c=document.createElement(`div`);return c.className=`paint-hint`,c.textContent=`grid grows right/down; digits map to atlas tiles, others need legend`,n.appendChild(c),n}function tz(e,t,n,r=``){let i=document.createElement(`textarea`);i.rows=3,i.placeholder=r,i.value=t===void 0?``:JSON.stringify(t,null,2),i.addEventListener(`change`,()=>{let e=i.value.trim();if(e===``){i.classList.remove(`invalid`),n(void 0);return}try{let t=JSON.parse(e);i.classList.remove(`invalid`),n(t)}catch{i.classList.add(`invalid`)}});let a=qR(e,i);return a.className=`field wide`,a}var nz=2.4,rz=1.35,iz=[0,.5,0];function az(e){return{format:1,type:`scene`,dimension:`3d`,name:`Preview`,environment:{sky:{type:`atmosphere`,elevationDeg:35,azimuthDeg:140,turbidity:3},ambient:{intensity:.55},exposure:1.05},assets:{model:{type:`model`,url:e}},root:{name:`Preview`,type:`Node3D`,children:[{name:`Cam`,type:`Camera3D`,props:{current:!0,position:[0,rz,nz]}},{name:`Sun`,type:`DirectionalLight3D`,props:{position:[3,6,4],intensity:2.2}},{name:`Model`,type:`ModelInstance3D`,props:{model:`$model`,targetHeight:1}}]}}}var oz=class{canvas=null;engine=null;renderer=null;raf=0;angle=.9;dragging=!1;lastX=0;url=``;mount(e){let t=document.createElement(`div`);t.className=`lib-preview3d`;let n=this.ensure();return t.appendChild(n),e!==this.url&&(this.url=e,this.load(e)),this.start(),t}detach(){this.stop(),this.canvas?.remove()}dispose(){this.stop(),this.renderer?.dispose(),this.engine?.dispose(),this.renderer=null,this.engine=null,this.canvas?.remove(),this.canvas=null,this.url=``}ensure(){if(this.canvas)return this.canvas;let e=document.createElement(`canvas`);e.className=`lib-preview-canvas`,this.canvas=e,this.engine=new kt({scheduler:()=>()=>{}}),this.renderer=new yP({canvas:e,engine:this.engine}),e.addEventListener(`pointerdown`,t=>{this.dragging=!0,this.lastX=t.clientX,e.setPointerCapture(t.pointerId)}),e.addEventListener(`pointermove`,e=>{this.dragging&&(this.angle-=(e.clientX-this.lastX)*.01,this.lastX=e.clientX)});let t=()=>{this.dragging=!1};return e.addEventListener(`pointerup`,t),e.addEventListener(`pointercancel`,t),e}load(e){if(this.engine)try{this.engine.setScene(An(az(e)))}catch(t){console.warn(`[incanto] library preview could not load`,e,t)}}start(){if(this.raf)return;let e=0,t=n=>{this.raf=requestAnimationFrame(t);let r=e?Math.min(.05,(n-e)/1e3):0;e=n,this.dragging||(this.angle+=r*.5);let i=this.renderer;i&&(i.viewOverride={position:[Math.sin(this.angle)*nz,rz,Math.cos(this.angle)*nz],target:iz},this.engine?.tick(n))};this.raf=requestAnimationFrame(t)}stop(){this.raf&&cancelAnimationFrame(this.raf),this.raf=0}},sz=`incanto-editor-v8-token`,cz=24;async function lz(e,t,n){if(!C(e.url)||n!==`spritesheet`&&n!==`texture`)return null;try{let n=oy(await(await fetch(e.url)).json(),{url:w(e.url),assetKey:t});return{asset:n.asset,props:Object.fromEntries(Object.entries(n.props).filter(([e])=>e!==`sheet`))}}catch(t){return console.warn(`[incanto] not a usable sprite config:`,e.url,t),null}}function uz(){try{return localStorage.getItem(sz)??``}catch{return``}}function dz(e){try{e?localStorage.setItem(sz,e):localStorage.removeItem(sz)}catch{}}function fz(e,t){return new Promise(n=>{let r=[...t.shelf??[]],i=``,a=1,o=!1,c=[],u=[],d=null,f=!1,b=!1,x=document.createElement(`div`);x.className=`lib-backdrop`;let T=document.createElement(`div`);T.className=`lib-dialog`,x.appendChild(T);let E=document.createElement(`header`);E.className=`lib-head`;let D=document.createElement(`strong`);D.textContent=`agent8 library`;let O=document.createElement(`span`);O.className=`lib-sub`,O.textContent=t.target?`→ ${t.target}`:``;let k=document.createElement(`input`);k.type=`search`,k.className=`lib-search`,k.placeholder=`search descriptions…`;let A=document.createElement(`button`);A.type=`button`,A.className=`ghost`,A.id=`lib-close`,A.textContent=`✕`,A.title=`Close (Esc)`,E.append(D,O,k,A),T.appendChild(E);let ee=document.createElement(`div`);ee.className=`lib-body`,T.appendChild(ee);let te=document.createElement(`nav`);te.className=`lib-shelves`;let ne=document.createElement(`div`);ne.className=`lib-grid-pane`;let re=document.createElement(`div`);re.className=`lib-grid`;let j=document.createElement(`div`);j.className=`lib-status`;let ie=document.createElement(`button`);ie.type=`button`,ie.className=`ghost lib-more`,ie.textContent=`load more`,ie.hidden=!0,ne.append(j,re,ie);let ae=document.createElement(`aside`);ae.className=`lib-detail`,ee.append(te,ne,ae);let M=new oz,oe=e=>{b||(b=!0,M.dispose(),document.removeEventListener(`keydown`,se,!0),x.remove(),n(e))},se=e=>{e.key===`Escape`&&(e.stopPropagation(),oe(null))};document.addEventListener(`keydown`,se,!0),x.addEventListener(`pointerdown`,e=>{e.target===x&&oe(null)}),A.addEventListener(`click`,()=>oe(null));let ce=e=>{r=e,a=1,u=[],pe(!1)},le=()=>{te.textContent=``;let e=[[`Everything`,[]]];for(let t=0;t<r.length;t++)e.push([r[t],r.slice(0,t+1)]);for(let[t,n]of e){let e=document.createElement(`button`);e.type=`button`,e.className=`lib-shelf crumb`,e.style.paddingLeft=`${10+(n.length?n.length-1:0)*12}px`,e.textContent=t,e.classList.toggle(`active`,n.length===r.length),e.addEventListener(`click`,()=>{n.length!==r.length&&ce(n)}),te.appendChild(e)}let t=s(u,r);if(t.length>0){let e=document.createElement(`div`);e.className=`lib-shelf-head`,e.textContent=`in here`,te.appendChild(e)}for(let e of t){let t=document.createElement(`button`);t.type=`button`,t.className=`lib-shelf`,t.style.paddingLeft=`${16+r.length*12}px`;let n=document.createElement(`span`);n.textContent=e.tag;let i=document.createElement(`small`);i.className=`lib-shelf-count`,i.textContent=String(e.count),t.append(n,i),t.addEventListener(`click`,()=>ce([...r,e.tag])),te.appendChild(t)}},ue=()=>{if(ae.textContent=``,M.detach(),!d){let e=document.createElement(`div`);e.className=`lib-empty`,e.textContent=`pick an asset to preview it`,ae.appendChild(e);return}let e=d,n=document.createElement(`div`);n.className=`lib-stage`;let r=m(e.url);if(r===`image`||C(e.url)){let t=document.createElement(`img`);t.src=C(e.url)?w(e.url):e.url,t.alt=g(e),t.loading=`lazy`,n.appendChild(t)}else if(r===`audio`){let t=document.createElement(`audio`);t.controls=!0,t.src=e.url,n.appendChild(t)}else if(r===`model`)n.appendChild(M.mount(e.url));else{let t=document.createElement(`div`);t.className=`lib-empty`,t.textContent=`no preview for ${p(e.url)||`this file`}`,n.appendChild(t)}if(ae.appendChild(n),C(e.url)){let e=document.createElement(`p`);e.className=`lib-desc lib-note`,e.textContent=`Sprite config — picking it declares the sheet AND wires its named animations onto the node.`,ae.appendChild(e)}let i=document.createElement(`h3`);if(i.className=`lib-name`,i.textContent=g(e),ae.appendChild(i),e.description){let t=document.createElement(`p`);t.className=`lib-desc`,t.textContent=e.description,ae.appendChild(t)}let a=v(e);if(a.length){let e=document.createElement(`div`);e.className=`lib-tags`;for(let t of a){let n=document.createElement(`span`);n.className=`lib-tag`,n.textContent=t,e.appendChild(n)}ae.appendChild(e)}let o=y(e);if(o.length){let e=document.createElement(`dl`);e.className=`lib-facts`;for(let[t,n]of o){let r=document.createElement(`dt`);r.textContent=t;let i=document.createElement(`dd`);i.textContent=n,e.append(r,i)}ae.appendChild(e)}let s=document.createElement(`div`);s.className=`lib-url`;let c=document.createElement(`code`);c.textContent=e.url;let l=document.createElement(`button`);l.type=`button`,l.className=`ghost`,l.textContent=`copy`,l.addEventListener(`click`,()=>{navigator.clipboard?.writeText(e.url),l.textContent=`copied`,setTimeout(()=>{l.textContent=`copy`},1200)}),s.append(c,l),ae.appendChild(s);let u=document.createElement(`div`);u.className=`lib-actions`;let f=document.createElement(`button`);f.type=`button`,f.className=`primary`,f.id=`lib-use`,f.textContent=t.onAsset?`use as scene asset`:`use this`,f.addEventListener(`click`,()=>{if(!t.onAsset){oe(e.url);return}(async()=>{let n=_(e),r=await lz(e,n,t.assetType),i=r?.asset??S(e,t.kind,t.assetType),a=t.onAsset?.(e,i,n)??e.url;r&&t.onProps?.(r.props),oe(a)})()}),u.appendChild(f),ae.appendChild(u)},de=()=>{re.textContent=``;let e=c.filter(e=>h(e.url,t.kind));if(e.length===0&&!f){let e=document.createElement(`div`);e.className=`lib-empty`,e.textContent=c.length===0?`nothing on this shelf`:`this shelf has ${c.length} asset${c.length===1?``:`s`}, none of them a ${t.kind}`,re.appendChild(e)}for(let t of e){let e=document.createElement(`button`);e.type=`button`,e.className=`lib-card`,e.classList.toggle(`active`,t===d);let n=document.createElement(`div`);n.className=`lib-thumb`;let r=m(t.url);if(r===`image`){let e=document.createElement(`img`);e.src=t.url,e.alt=``,e.loading=`lazy`,n.appendChild(e)}else{let e=tF(r===`audio`?`AudioPlayer`:`ModelInstance3D`);e.classList.add(`lib-glyph`),n.appendChild(e)}if(C(t.url)){let e=document.createElement(`em`);e.className=`lib-badge`,e.textContent=`animated`,e.title=`A sprite config: frame grid + named animations. Picking it wires them up.`,n.appendChild(e)}let i=document.createElement(`span`);i.className=`lib-card-name`,i.textContent=g(t),e.append(n,i),e.title=t.description||t.url,e.addEventListener(`click`,()=>{d=t,de(),ue()}),re.appendChild(e)}ie.hidden=!o||f},fe=e=>{re.textContent=``,ie.hidden=!0;let t=document.createElement(`div`);t.className=`lib-token`;let n=document.createElement(`p`);n.className=`lib-token-line`,n.textContent=e;let r=document.createElement(`p`);r.className=`lib-token-line lib-token-how`,r.textContent=`The catalog is per-account. Paste a Verse8 access token to browse it here — it is kept in this browser and sent only to your own editor server. Starting the editor with --token (or INCANTO_V8_TOKEN) skips this.`;let i=document.createElement(`input`);i.type=`password`,i.className=`mono`,i.placeholder=`v8 access token`,i.value=uz();let o=document.createElement(`button`);o.type=`button`,o.className=`primary`,o.textContent=`connect`,o.addEventListener(`click`,()=>{dz(i.value.trim()),a=1,pe(!1)}),i.addEventListener(`keydown`,e=>{e.key===`Enter`&&o.click()});let s=document.createElement(`div`);s.className=`lib-token-row`,s.append(i,o),t.append(n,r,s),re.appendChild(t)},pe=async t=>{if(!(!e.library||f)){f=!0,j.textContent=t?`loading more…`:`loading ${l(r)}…`,t||(c=[],d=null,de(),ue()),le();try{let n=await e.library({tags:r,keyword:i.trim()||void 0,page:a,limit:cz},uz()||void 0);if(b)return;c=t?[...c,...n.items]:n.items,u=c,o=n.hasNext;let s=n.total===void 0?``:` of ${n.total}`;j.textContent=`${l(r)} · ${c.length}${s} loaded`,le(),de()}catch(e){if(b)return;let t=e.needsToken===!0;if(j.textContent=l(r),t)fe(e instanceof Error?e.message:String(e));else{re.textContent=``;let t=document.createElement(`div`);t.className=`lib-error`,t.textContent=e instanceof Error?e.message:String(e),re.appendChild(t)}}finally{f=!1,ie.hidden=!o}}};ie.addEventListener(`click`,()=>{a+=1,pe(!0)});let me=0;k.addEventListener(`input`,()=>{i=k.value,clearTimeout(me),me=window.setTimeout(()=>{a=1,pe(!1)},350)}),le(),ue(),document.body.appendChild(x),k.focus(),pe(!1)})}var pz=`.scene.json`;function mz(e){let t=e.split(`/`).pop()??e;return t.endsWith(pz)?t.slice(0,-11):t}function hz(e){let t=e.lastIndexOf(`/`);return t===-1?``:e.slice(0,t)}function gz(e,t){return{path:e,name:t,dirs:new Map,files:[]}}function _z(e){let t=gz(``,``);for(let n of e){let e=n.rel.split(`/`);if(!e.pop())continue;let r=t;for(let t of e){let e=r.path?`${r.path}/${t}`:t,n=r.dirs.get(t);n||(n=gz(e,t),r.dirs.set(t,n)),r=n}r.files.push(n)}return t}function vz(e){let t=e.files.length;for(let n of e.dirs.values())t+=vz(n);return t}function yz(e){let t=e.files.filter(e=>e.scene).length;for(let n of e.dirs.values())t+=yz(n);return t}function bz(e){let t=e,n=e.name;for(;t.files.length===0&&t.dirs.size===1;){let e=[...t.dirs.values()][0];if(!e)break;t=e,n=`${n} / ${e.name}`}return{dir:t,label:n}}function xz(e){let t=hz(e??``).split(`/`).filter(Boolean),n=[],r=``;for(let e of t)r=r?`${r}/${e}`:e,n.push(r);return n}function Sz(e,t={}){let n=(t.query??``).trim().toLowerCase(),r=n?e.filter(e=>e.rel.toLowerCase().includes(n)):e,i=t.expanded??new Set,a=[],o=(e,r)=>{let s=[...e.dirs.values()].sort((e,t)=>e.name.localeCompare(t.name));for(let e of s){let{dir:t,label:s}=bz(e),c=vz(t);if(c===0)continue;let l=n!==``||i.has(t.path);a.push({kind:`folder`,path:t.path,label:s,depth:r,count:c,scenes:yz(t),open:l}),l&&o(t,r+1)}let c=[...e.files].sort((e,t)=>mz(e.rel).localeCompare(mz(t.rel)));for(let e of c)a.push({kind:`scene`,entry:e,label:mz(e.rel),folder:hz(e.rel),depth:r,current:e.rel===t.current})};return o(_z(r),0),a}function Cz(e,t){let n=new Set(xz(t));if(e.length<=24)for(let t of e)for(let e of xz(t.rel))n.add(e);return n}function wz(e){return typeof e!=`number`||!Number.isFinite(e)||e<0?``:e<1e3?`${e} B`:e<1e3*1e3?`${(e/1e3).toFixed(1)} kB`:`${(e/1e3/1e3).toFixed(1)} MB`}function Tz(e,t){if(typeof e!=`number`||!Number.isFinite(e)||e<=0)return``;let n=Math.round((t-e)/1e3);if(n<90)return`just now`;let r=Math.round(n/60);if(r<60)return`${r}m ago`;let i=Math.round(r/60);return i<24?`${i}h ago`:i<48?`yesterday`:new Date(e).toISOString().slice(0,10)}function Ez(e,t=`new-level`){let n=e?e.kind===`folder`?e.path:e.folder:``;return n?`${n}/${t}${pz}`:`${t}${pz}`}function Dz(e,t){let n=document.createElement(`span`);return n.className=e,n.textContent=t,n}function Oz(e,t,n=()=>Date.now()){let r=[],i=new Set,a=[],o=0,s=!0,c=()=>{let c=t.current();if(a=Sz(r,{expanded:i,query:e.search.value,current:c}),o>=a.length&&(o=a.length-1),o<0&&(o=0),s){let e=a.findIndex(e=>e.kind===`scene`&&e.current);e>=0&&(o=e),s=!1}if(e.list.textContent=``,a.length===0){let t=document.createElement(`div`);t.className=`scene-empty`,t.textContent=r.length?`no scene matches “${e.search.value.trim()}”`:`no .json files in this project yet — create a scene below`,e.list.appendChild(t)}let u=n();a.forEach((n,r)=>{let i=document.createElement(`div`);i.className=n.kind===`folder`?`scene-row scene-folder`:`scene-row`,i.style.paddingLeft=`${6+n.depth*14}px`,r===o&&i.classList.add(`active`);let a=Dz(`scene-caret`,``);n.kind===`folder`?(a.classList.add(`chevron`),n.open||a.classList.add(`collapsed`),a.appendChild(nF())):a.textContent=`◇`,i.append(a,Dz(`scene-name`,n.label),Dz(`scene-meta`,n.kind===`folder`?n.scenes>0?`${n.scenes} scene${n.scenes===1?``:`s`}`:`${n.count} file${n.count===1?``:`s`}`:[n.entry.scene?[n.entry.scene.dimension,`${n.entry.scene.nodes} node${n.entry.scene.nodes===1?``:`s`}`].filter(Boolean).join(` · `):`not a scene`,Tz(n.entry.modified,u),wz(n.entry.size)].filter(Boolean).join(` · `))),n.kind===`scene`&&(n.current&&i.classList.add(`current`),n.entry.notScene?(i.classList.add(`not-scene`),i.title=`${n.entry.rel}\n\nnot a scene: ${n.entry.notScene}`):i.title=n.entry.rel),i.addEventListener(`click`,()=>{o=r,n.kind===`folder`?l(n.path):t.open(n.entry)}),e.list.appendChild(i)});let d=r.length,f=a.filter(e=>e.kind===`scene`).length;e.count.textContent=d===0?``:f===d?`${d}`:`${f} / ${d}`,e.path.placeholder=Ez(a[o]),e.list.querySelector(`.active`)?.scrollIntoView({block:`nearest`})},l=e=>{i.has(e)?i.delete(e):i.add(e),c()},u=e=>{a.length!==0&&(o=Math.min(a.length-1,Math.max(0,o+e)),c())};return e.search.addEventListener(`input`,()=>{o=0,c()}),e.search.addEventListener(`keydown`,e=>{let n=a[o];switch(e.key){case`ArrowDown`:e.preventDefault(),u(1);return;case`ArrowUp`:e.preventDefault(),u(-1);return;case`ArrowRight`:n?.kind===`folder`&&!n.open&&(e.preventDefault(),l(n.path));return;case`ArrowLeft`:n?.kind===`folder`&&n.open&&(e.preventDefault(),l(n.path));return;case`Enter`:e.preventDefault(),n?.kind===`folder`?l(n.path):n&&t.open(n.entry);return;default:}}),{async refresh(){try{r=await t.entries()}catch(t){r=[],e.list.textContent=``;let n=document.createElement(`div`);n.className=`scene-empty`,n.textContent=`could not list scenes: ${t instanceof Error?t.message:String(t)}`,e.list.appendChild(n),e.count.textContent=``;return}if(i.size===0)i=Cz(r,t.current());else for(let e of xz(t.current()))i.add(e);s=!0,c(),e.search.focus(),e.search.select()}}}var kz=`
|
|
8425
8425
|
<header id="topbar">
|
|
8426
8426
|
<div class="brand">
|
|
8427
8427
|
<span class="brand-mark">in</span>
|
|
@@ -8585,7 +8585,7 @@ registerBehavior('MyBehavior', MyBehavior); // before loadScene()
|
|
|
8585
8585
|
</div>
|
|
8586
8586
|
</div>
|
|
8587
8587
|
<div id="popover" hidden></div>
|
|
8588
|
-
`;function Oz(e,t){let n=[String(e.name??``)],r=e;for(let e of t){let t=r.children?.[e];if(!t)return n;n.push(String(t.name??``)),r=t}return n}function kz(e,t,n,r){if(e===``||e===`.`)return null;let i=n[n.length-1];if(i===void 0||i===r)return null;if(e.startsWith(`%`))return e.slice(1)===i?`%${r}`:null;let a=e.startsWith(`/`),o=(a?e.slice(1):e).split(`/`);if(o.some(e=>e===``))return null;let s,c=0;if(a)s=0;else{let e=0;for(;o[e]===`..`;)e++;if(c=e,s=t.length-e,s<0)return null}let l=[...t.slice(0,s),...o.slice(c)],u=a&&o[0]===`root`&&t[0]!==`root`;u&&(l[0]=t[0]??``);let d=n.length-1;for(let e=0;e<=d;e++)if(l[e]!==n[e])return null;let f=d-s+c;if(f<c||f>=o.length||u&&f===0)return null;let p=[...o];return p[f]=r,(a?`/`:``)+p.join(`/`)}function Az(e){let t=[],n=e=>{for(let[n,r]of Object.entries(e))r?.nodePath&&t.push(n)},r=typeof e.type==`string`?e.type:``;if(r)try{n(qe(r))}catch{}let i=e.script;return typeof i?.name==`string`&&n(ot(i.name)),t}function jz(e,t,n){let r=e.root;if(!r||t.length===0)return r&&t.length===0?Mz(e,r,n):[];let i=Oz(r,t),a=Nz(r,t);if(!a)return[];let o=Pz(e,r,i,n);return a.name=n,o}function Mz(e,t,n){let r=Pz(e,t,[String(t.name??``)],n);return t.name=n,r}function Nz(e,t){let n=e;for(let e of t)if(n=n?.children?.[e],!n)return null;return n??null}function Pz(e,t,n,r){let i=[],a=String(t.name??``),o=e.connections;Array.isArray(o)&&o.forEach((e,t)=>{let o=e;for(let e of[`from`,`to`]){let s=o[e];if(typeof s!=`string`)continue;let c=kz(s,[a],n,r);c!==null&&(o[e]=c,i.push({where:`connections[${t}].${e}`,from:s,to:c}))}});let s=(a,o)=>{let c=a.props;if(c)for(let s of Az(a)){let a=c[s],l=`${o.join(`/`)}.${s}`;if(typeof a==`string`){let e=kz(a,o,n,r);e!==null&&(c[s]=e,i.push({where:l,from:a,to:e}))}else Array.isArray(a)?a.forEach((e,t)=>{if(typeof e!=`string`)return;let s=kz(e,o,n,r);s!==null&&(a[t]=s,i.push({where:`${l}[${t}]`,from:e,to:s}))}):bn(a)&&Fz(e,t,a,n,r,l,i)}let l=a.children??[];for(let e of l)s(e,[...o,String(e.name??``)])};return s(t,[a]),i}function Fz(e,t,n,r,i,a,o){let s=n[`@const`];if(typeof s!=`string`)return;let c=e.constants,l=c?.[s];if(typeof l!=`string`||!l.startsWith(`%`)&&!l.startsWith(`/`))return;let u=kz(l,[String(t.name??``)],r,i);u!==null&&(c[s]=u,o.push({where:`constants.${s} (${a})`,from:l,to:u}))}var Iz=class{working;selection=[];extra=[];validator=null;selectedAsset=null;selectedGroup=null;pendingGroups=new Set;pendingLivePatch=null;addingAsset=!1;addingGroup=!1;newAssetGroup=``;newGroupParent=``;startAddingAsset(){this.addingAsset=!0,this.addingGroup=!1,this.newAssetGroup=this.selectedGroup??``,this.clearFocus()}startAddingGroup(){this.addingGroup=!0,this.addingAsset=!1,this.newGroupParent=this.selectedGroup??``,this.clearFocus()}cancelAddForms(){this.addingAsset=!1,this.addingGroup=!1}onError=null;original;undoStack=[];listeners=new Set;constructor(e){this.working=e,this.original=JSON.stringify(e),this.working.root&&Lz(this.working.root)}get dirty(){return JSON.stringify(this.working)!==this.original}get canUndo(){return this.undoStack.length>0}nodeAt(e){if(e===null)return null;let t=this.working.root;for(let n of e)t=t?.children?.[n];return t??null}parentOf(e){return e.length===0?null:this.nodeAt(e.slice(0,-1))}mutate(e,t,n){(!n?.coalesce||this.undoStack.length===0)&&(this.undoStack.push(JSON.stringify(this.working)),this.undoStack.length>100&&this.undoStack.shift()),e(),this.pendingLivePatch=t??null,this.emit()}undo(){let e=this.undoStack.pop();e!==void 0&&(this.working=JSON.parse(e),this.selection=[],this.emit())}transact(e){let t=JSON.stringify(this.working),n=e(),r=e=>(this.working=JSON.parse(t),e&&this.onError?.(e),null);if(n===null)return r();let i=this.validator?.(this.working)??null;return i&&i!==this.priorError(t)?r(i):(this.undoStack.push(t),this.undoStack.length>100&&this.undoStack.shift(),this.emit(),n)}renameNode(e,t){let n=this.nodeAt(e);if(!n)return null;let r=this.parentOf(e),i=r?Kz(r,t,n):t;return i===n.name?[]:this.transact(()=>jz(this.working,e,i))}priorError(e){if(!this.validator)return null;try{return this.validator(JSON.parse(e))}catch{return null}}moveNode(e,t,n){return this.moveNodes([e],t,n)?.[0]??null}moveNodes(e,t,n){let r=Hz(e).filter(e=>e.length>0);if(r.length===0)return null;for(let e of r)if(e.length<=t.length&&e.every((e,n)=>e===t[n]))return null;let i=this.working.root,a=r.map(e=>this.nodeAt(e)).filter(e=>e!==null);if(a.length!==r.length)return null;let o=this.nodeAt(t);return!o||a.includes(o)?null:this.transact(()=>{for(let e of a)Wz(i,e);let e,t;if(n===`into`)e=o,e.children||=[],t=e.children.length;else{let r=Uz(i,o);if(!r)return null;e=r.parent,t=r.index+ +(n===`after`)}let r=[];a.forEach((n,r)=>{n.name=Kz(e,n.name??`Node`),e.children?.splice(t+r,0,n)});for(let e of a){let t=Gz(i,e);if(!t)return null;r.push(t)}return r})}duplicateNode(e){if(e.length===0)return null;let t=this.nodeAt(e),n=this.parentOf(e);return!t||!n?.children?null:this.transact(()=>{let r=JSON.parse(JSON.stringify(t));r.name=Kz(n,t.name??`Node`),Rz(r);let i=e[e.length-1]+1;return n.children?.splice(i,0,r),[...e.slice(0,-1),i]})}removeNodes(e){let t=Hz(e).filter(e=>e.length>0);if(t.length===0)return!1;let n=this.working.root,r=t.map(e=>this.nodeAt(e)).filter(e=>e!==null);return this.transact(()=>{for(let e of r)Wz(n,e);return!0})===!0}deleteRoot(){this.undoStack.push(JSON.stringify(this.working)),delete this.working.root,this.selection=null,this.extra=[],this.emit()}insertNode(e,t){if(!this.working.root){let t=JSON.parse(JSON.stringify(e));return Rz(t),this.transact(()=>(this.working.root=t,[]))}let n=this.nodeAt(t);return n?this.transact(()=>{let r=JSON.parse(JSON.stringify(e));return r.name=Kz(n,r.name??`Node`),Rz(r),n.children||=[],n.children.push(r),[...t,n.children.length-1]}):null}findRemovalReferences(e){let t=Hz(e).filter(e=>e.length>0),n=this.working.root,r=t.map(e=>this.nodeAt(e)).filter(e=>e!==null),i=new Set,a=[];for(let e of t){let t=[],r=n;for(let n of e){let e=r.children?.[n];if(!e)break;t.push(String(e.name)),r=e}a.push(t.join(`/`))}let o=e=>{typeof e.uid==`string`&&i.add(e.uid);for(let t of e.children??[])o(t)};for(let e of r)o(e);let s=[];if((this.working.connections??[]).forEach((e,t)=>{for(let n of[`from`,`to`]){let r=String(e[n]??``);if(a.some(e=>r===e||r.startsWith(`${e}/`))){s.push({kind:`connection`,where:`connections[${t}] ${String(e.signal)}: ${String(e.from)} → ${String(e.to)}`,connectionIndex:t});return}}}),i.size>0){let e=(t,n,a)=>{if(typeof t==`string`){!a&&i.has(t)&&s.push({kind:`uid`,where:n,value:t});return}if(Array.isArray(t)){t.forEach((t,r)=>{e(t,`${n}[${r}]`,a)});return}if(typeof t==`object`&&t){let i=t,o=a||r.includes(i),s=typeof i.name==`string`&&(i.type||i.children||i.instance)?n?`${n} › ${i.name}`:String(i.name):n;for(let[n,r]of Object.entries(t))n!==`uid`&&e(r,n===`children`||n===`root`?s:`${s?`${s}.`:``}${n}`,o)}};e(this.working,``,!1)}return s}removeNodesUnlinking(e){let t=this.findRemovalReferences(e),n=Hz(e).filter(e=>e.length>0),r=this.working.root,i=n.map(e=>this.nodeAt(e)).filter(e=>e!==null),a=new Set(t.filter(e=>e.kind===`uid`).map(e=>e.value)),o=new Set(t.filter(e=>e.kind===`connection`).map(e=>e.connectionIndex));return this.transact(()=>{o.size>0&&(this.working.connections=(this.working.connections??[]).filter((e,t)=>!o.has(t))),a.size>0&&zz(this.working,a,i);for(let e of i)Wz(r,e);return!0})===!0}reset(e){this.working=e,this.original=JSON.stringify(e),this.working.root&&Lz(this.working.root),this.undoStack=[],this.selection=[],this.emit()}markSaved(){this.original=JSON.stringify(this.working),this.emit()}emitChange(){this.emit()}clearFocus(){this.selection=null,this.extra=[],this.selectedAsset=null,this.selectedGroup=null,this.emit()}selectAsset(e){this.selectedAsset=e,e!==null&&(this.cancelAddForms(),this.selectedGroup=null,this.selection=null,this.extra=[]),this.emit()}selectGroup(e){this.selectedGroup=e,e!==null&&(this.cancelAddForms(),this.selectedAsset=null,this.selection=null,this.extra=[]),this.emit()}assetMap(){return this.working.assets??{}}groupCount(e){return Object.keys(this.assetMap()).filter(t=>t.startsWith(`${e}/`)).length}addGroup(e){this.pendingGroups.add(e),this.selectGroup(e)}renameGroup(e,t){if(!t||t===e)return!1;let n=this.assetMap(),r=Object.keys(n).filter(t=>t.startsWith(`${e}/`));return this.pendingGroups.delete(e)&&this.pendingGroups.add(t),this.selectedGroup=t,this.mutate(()=>{for(let i of r){let r=`${t}/${i.slice(e.length+1)}`;n[r]=n[i],delete n[i],Bz(this.working,`$${i}`,`$${r}`)}}),r.length===0&&this.emit(),!0}moveGroup(e,t){if(t===e||t.startsWith(`${e}/`))return!1;let n=e.includes(`/`)?e.slice(e.lastIndexOf(`/`)+1):e,r=t?`${t}/${n}`:n;return r===e?!1:this.renameGroup(e,r)}renameAssetKey(e,t){let n=this.assetMap();return!(e in n)||!t||t===e||t in n?!1:(this.selectedAsset=t,this.mutate(()=>{n[t]=n[e],delete n[e],Bz(this.working,`$${e}`,`$${t}`)}),!0)}deleteGroup(e){let t=this.assetMap(),n=Object.keys(t).filter(t=>t.startsWith(`${e}/`));n.length>0&&this.mutate(()=>{for(let e of n)delete t[e];Object.keys(t).length===0&&delete this.working.assets}),this.pendingGroups.delete(e),this.selectedGroup===e&&(this.selectedGroup=null),this.emit()}moveAsset(e,t){let n=this.assetMap();if(!(e in n))return!1;let r=e.includes(`/`)?e.slice(e.lastIndexOf(`/`)+1):e,i=t?`${t}/${r}`:r;if(i===e)return!1;for(;i in n;)i=`${i}2`;return this.renameAssetKey(e,i)}select(e,t){if(this.cancelAddForms(),this.selectedAsset=null,this.selectedGroup=null,t?.toggle&&e!==null){let t=e.join(`.`);this.selection!==null&&this.selection.join(`.`)===t?this.selection=this.extra.shift()??this.selection:this.extra.some(e=>e.join(`.`)===t)?this.extra=this.extra.filter(e=>e.join(`.`)!==t):this.selection===null?this.selection=e:this.extra.push(e)}else this.selection=e,this.extra=[];this.emit()}allSelections(){return[...this.selection===null?[]:[this.selection,...this.extra]].sort(Vz)}isSelected(e){let t=e.join(`.`);return this.selection!==null&&this.selection.join(`.`)===t||this.extra.some(e=>e.join(`.`)===t)}onChange(e){this.listeners.add(e)}emit(){for(let e of this.listeners)e()}};function Lz(e){(typeof e.uid!=`string`||e.uid===``)&&(e.uid=Qn());for(let t of e.children??[])Lz(t)}function Rz(e){e.uid=Qn();for(let t of e.children??[])Rz(t)}function zz(e,t,n){if(Array.isArray(e)){for(let r=e.length-1;r>=0;r--)typeof e[r]==`string`&&t.has(e[r])?e.splice(r,1):zz(e[r],t,n);return}if(typeof e==`object`&&e){if(n.includes(e))return;for(let[r,i]of Object.entries(e))r!==`uid`&&(typeof i==`string`&&t.has(i)?delete e[r]:zz(i,t,n))}}function Bz(e,t,n){if(Array.isArray(e)){e.forEach((r,i)=>{r===t?e[i]=n:Bz(r,t,n)});return}if(typeof e==`object`&&e)for(let[r,i]of Object.entries(e))i===t?e[r]=n:Bz(i,t,n)}function Vz(e,t){for(let n=0;n<Math.min(e.length,t.length);n++)if(e[n]!==t[n])return e[n]-t[n];return e.length-t.length}function Hz(e){let t=[...e].sort(Vz),n=[];for(let e of t)n.some(t=>t.length<=e.length&&t.every((t,n)=>t===e[n]))||n.push(e);return n}function Uz(e,t){let n=e.children?.indexOf(t)??-1;if(n>=0)return{parent:e,index:n};for(let n of e.children??[]){let e=Uz(n,t);if(e)return e}return null}function Wz(e,t){let n=Uz(e,t);n?.parent.children?.splice(n.index,1)}function Gz(e,t){if(e===t)return[];for(let[n,r]of(e.children??[]).entries()){let e=Gz(r,t);if(e)return[n,...e]}return null}function Kz(e,t,n){let r=new Set((e.children??[]).filter(e=>e!==n).map(e=>e.name));if(!r.has(t))return t;let i=2;for(;r.has(`${t}${i}`);)i+=1;return`${t}${i}`}var qz=`
|
|
8588
|
+
`;function Az(e,t){let n=[String(e.name??``)],r=e;for(let e of t){let t=r.children?.[e];if(!t)return n;n.push(String(t.name??``)),r=t}return n}function jz(e,t,n,r){if(e===``||e===`.`)return null;let i=n[n.length-1];if(i===void 0||i===r)return null;if(e.startsWith(`%`))return e.slice(1)===i?`%${r}`:null;let a=e.startsWith(`/`),o=(a?e.slice(1):e).split(`/`);if(o.some(e=>e===``))return null;let s,c=0;if(a)s=0;else{let e=0;for(;o[e]===`..`;)e++;if(c=e,s=t.length-e,s<0)return null}let l=[...t.slice(0,s),...o.slice(c)],u=a&&o[0]===`root`&&t[0]!==`root`;u&&(l[0]=t[0]??``);let d=n.length-1;for(let e=0;e<=d;e++)if(l[e]!==n[e])return null;let f=d-s+c;if(f<c||f>=o.length||u&&f===0)return null;let p=[...o];return p[f]=r,(a?`/`:``)+p.join(`/`)}function Mz(e){let t=[],n=e=>{for(let[n,r]of Object.entries(e))r?.nodePath&&t.push(n)},r=typeof e.type==`string`?e.type:``;if(r)try{n(qe(r))}catch{}let i=e.script;return typeof i?.name==`string`&&n(ot(i.name)),t}function Nz(e,t,n){let r=e.root;if(!r||t.length===0)return r&&t.length===0?Pz(e,r,n):[];let i=Az(r,t),a=Fz(r,t);if(!a)return[];let o=Iz(e,r,i,n);return a.name=n,o}function Pz(e,t,n){let r=Iz(e,t,[String(t.name??``)],n);return t.name=n,r}function Fz(e,t){let n=e;for(let e of t)if(n=n?.children?.[e],!n)return null;return n??null}function Iz(e,t,n,r){let i=[],a=String(t.name??``),o=e.connections;Array.isArray(o)&&o.forEach((e,t)=>{let o=e;for(let e of[`from`,`to`]){let s=o[e];if(typeof s!=`string`)continue;let c=jz(s,[a],n,r);c!==null&&(o[e]=c,i.push({where:`connections[${t}].${e}`,from:s,to:c}))}});let s=(a,o)=>{let c=a.props;if(c)for(let s of Mz(a)){let a=c[s],l=`${o.join(`/`)}.${s}`;if(typeof a==`string`){let e=jz(a,o,n,r);e!==null&&(c[s]=e,i.push({where:l,from:a,to:e}))}else Array.isArray(a)?a.forEach((e,t)=>{if(typeof e!=`string`)return;let s=jz(e,o,n,r);s!==null&&(a[t]=s,i.push({where:`${l}[${t}]`,from:e,to:s}))}):bn(a)&&Lz(e,t,a,n,r,l,i)}let l=a.children??[];for(let e of l)s(e,[...o,String(e.name??``)])};return s(t,[a]),i}function Lz(e,t,n,r,i,a,o){let s=n[`@const`];if(typeof s!=`string`)return;let c=e.constants,l=c?.[s];if(typeof l!=`string`||!l.startsWith(`%`)&&!l.startsWith(`/`))return;let u=jz(l,[String(t.name??``)],r,i);u!==null&&(c[s]=u,o.push({where:`constants.${s} (${a})`,from:l,to:u}))}var Rz=class{working;selection=[];extra=[];validator=null;selectedAsset=null;selectedGroup=null;pendingGroups=new Set;pendingLivePatch=null;addingAsset=!1;addingGroup=!1;newAssetGroup=``;newGroupParent=``;startAddingAsset(){this.addingAsset=!0,this.addingGroup=!1,this.newAssetGroup=this.selectedGroup??``,this.clearFocus()}startAddingGroup(){this.addingGroup=!0,this.addingAsset=!1,this.newGroupParent=this.selectedGroup??``,this.clearFocus()}cancelAddForms(){this.addingAsset=!1,this.addingGroup=!1}onError=null;original;undoStack=[];listeners=new Set;constructor(e){this.working=e,this.working.root&&zz(this.working.root),this.original=JSON.stringify(this.working)}get dirty(){return JSON.stringify(this.working)!==this.original}get canUndo(){return this.undoStack.length>0}nodeAt(e){if(e===null)return null;let t=this.working.root;for(let n of e)t=t?.children?.[n];return t??null}parentOf(e){return e.length===0?null:this.nodeAt(e.slice(0,-1))}mutate(e,t,n){(!n?.coalesce||this.undoStack.length===0)&&(this.undoStack.push(JSON.stringify(this.working)),this.undoStack.length>100&&this.undoStack.shift()),e(),this.pendingLivePatch=t??null,this.emit()}undo(){let e=this.undoStack.pop();e!==void 0&&(this.working=JSON.parse(e),this.selection=[],this.emit())}transact(e){let t=JSON.stringify(this.working),n=e(),r=e=>(this.working=JSON.parse(t),e&&this.onError?.(e),null);if(n===null)return r();let i=this.validator?.(this.working)??null;return i&&i!==this.priorError(t)?r(i):(this.undoStack.push(t),this.undoStack.length>100&&this.undoStack.shift(),this.emit(),n)}renameNode(e,t){let n=this.nodeAt(e);if(!n)return null;let r=this.parentOf(e),i=r?Jz(r,t,n):t;return i===n.name?[]:this.transact(()=>Nz(this.working,e,i))}priorError(e){if(!this.validator)return null;try{return this.validator(JSON.parse(e))}catch{return null}}moveNode(e,t,n){return this.moveNodes([e],t,n)?.[0]??null}moveNodes(e,t,n){let r=Wz(e).filter(e=>e.length>0);if(r.length===0)return null;for(let e of r)if(e.length<=t.length&&e.every((e,n)=>e===t[n]))return null;let i=this.working.root,a=r.map(e=>this.nodeAt(e)).filter(e=>e!==null);if(a.length!==r.length)return null;let o=this.nodeAt(t);return!o||a.includes(o)?null:this.transact(()=>{for(let e of a)Kz(i,e);let e,t;if(n===`into`)e=o,e.children||=[],t=e.children.length;else{let r=Gz(i,o);if(!r)return null;e=r.parent,t=r.index+ +(n===`after`)}let r=[];a.forEach((n,r)=>{n.name=Jz(e,n.name??`Node`),e.children?.splice(t+r,0,n)});for(let e of a){let t=qz(i,e);if(!t)return null;r.push(t)}return r})}duplicateNode(e){if(e.length===0)return null;let t=this.nodeAt(e),n=this.parentOf(e);return!t||!n?.children?null:this.transact(()=>{let r=JSON.parse(JSON.stringify(t));r.name=Jz(n,t.name??`Node`),Bz(r);let i=e[e.length-1]+1;return n.children?.splice(i,0,r),[...e.slice(0,-1),i]})}removeNodes(e){let t=Wz(e).filter(e=>e.length>0);if(t.length===0)return!1;let n=this.working.root,r=t.map(e=>this.nodeAt(e)).filter(e=>e!==null);return this.transact(()=>{for(let e of r)Kz(n,e);return!0})===!0}deleteRoot(){this.undoStack.push(JSON.stringify(this.working)),delete this.working.root,this.selection=null,this.extra=[],this.emit()}insertNode(e,t){if(!this.working.root){let t=JSON.parse(JSON.stringify(e));return Bz(t),this.transact(()=>(this.working.root=t,[]))}let n=this.nodeAt(t);return n?this.transact(()=>{let r=JSON.parse(JSON.stringify(e));return r.name=Jz(n,r.name??`Node`),Bz(r),n.children||=[],n.children.push(r),[...t,n.children.length-1]}):null}findRemovalReferences(e){let t=Wz(e).filter(e=>e.length>0),n=this.working.root,r=t.map(e=>this.nodeAt(e)).filter(e=>e!==null),i=new Set,a=[];for(let e of t){let t=[],r=n;for(let n of e){let e=r.children?.[n];if(!e)break;t.push(String(e.name)),r=e}a.push(t.join(`/`))}let o=e=>{typeof e.uid==`string`&&i.add(e.uid);for(let t of e.children??[])o(t)};for(let e of r)o(e);let s=[];if((this.working.connections??[]).forEach((e,t)=>{for(let n of[`from`,`to`]){let r=String(e[n]??``);if(a.some(e=>r===e||r.startsWith(`${e}/`))){s.push({kind:`connection`,where:`connections[${t}] ${String(e.signal)}: ${String(e.from)} → ${String(e.to)}`,connectionIndex:t});return}}}),i.size>0){let e=(t,n,a)=>{if(typeof t==`string`){!a&&i.has(t)&&s.push({kind:`uid`,where:n,value:t});return}if(Array.isArray(t)){t.forEach((t,r)=>{e(t,`${n}[${r}]`,a)});return}if(typeof t==`object`&&t){let i=t,o=a||r.includes(i),s=typeof i.name==`string`&&(i.type||i.children||i.instance)?n?`${n} › ${i.name}`:String(i.name):n;for(let[n,r]of Object.entries(t))n!==`uid`&&e(r,n===`children`||n===`root`?s:`${s?`${s}.`:``}${n}`,o)}};e(this.working,``,!1)}return s}removeNodesUnlinking(e){let t=this.findRemovalReferences(e),n=Wz(e).filter(e=>e.length>0),r=this.working.root,i=n.map(e=>this.nodeAt(e)).filter(e=>e!==null),a=new Set(t.filter(e=>e.kind===`uid`).map(e=>e.value)),o=new Set(t.filter(e=>e.kind===`connection`).map(e=>e.connectionIndex));return this.transact(()=>{o.size>0&&(this.working.connections=(this.working.connections??[]).filter((e,t)=>!o.has(t))),a.size>0&&Vz(this.working,a,i);for(let e of i)Kz(r,e);return!0})===!0}reset(e){this.working=e,this.original=JSON.stringify(e),this.working.root&&zz(this.working.root),this.undoStack=[],this.selection=[],this.emit()}markSaved(){this.original=JSON.stringify(this.working),this.emit()}emitChange(){this.emit()}clearFocus(){this.selection=null,this.extra=[],this.selectedAsset=null,this.selectedGroup=null,this.emit()}selectAsset(e){this.selectedAsset=e,e!==null&&(this.cancelAddForms(),this.selectedGroup=null,this.selection=null,this.extra=[]),this.emit()}selectGroup(e){this.selectedGroup=e,e!==null&&(this.cancelAddForms(),this.selectedAsset=null,this.selection=null,this.extra=[]),this.emit()}assetMap(){return this.working.assets??{}}groupCount(e){return Object.keys(this.assetMap()).filter(t=>t.startsWith(`${e}/`)).length}addGroup(e){this.pendingGroups.add(e),this.selectGroup(e)}renameGroup(e,t){if(!t||t===e)return!1;let n=this.assetMap(),r=Object.keys(n).filter(t=>t.startsWith(`${e}/`));return this.pendingGroups.delete(e)&&this.pendingGroups.add(t),this.selectedGroup=t,this.mutate(()=>{for(let i of r){let r=`${t}/${i.slice(e.length+1)}`;n[r]=n[i],delete n[i],Hz(this.working,`$${i}`,`$${r}`)}}),r.length===0&&this.emit(),!0}moveGroup(e,t){if(t===e||t.startsWith(`${e}/`))return!1;let n=e.includes(`/`)?e.slice(e.lastIndexOf(`/`)+1):e,r=t?`${t}/${n}`:n;return r===e?!1:this.renameGroup(e,r)}renameAssetKey(e,t){let n=this.assetMap();return!(e in n)||!t||t===e||t in n?!1:(this.selectedAsset=t,this.mutate(()=>{n[t]=n[e],delete n[e],Hz(this.working,`$${e}`,`$${t}`)}),!0)}deleteGroup(e){let t=this.assetMap(),n=Object.keys(t).filter(t=>t.startsWith(`${e}/`));n.length>0&&this.mutate(()=>{for(let e of n)delete t[e];Object.keys(t).length===0&&delete this.working.assets}),this.pendingGroups.delete(e),this.selectedGroup===e&&(this.selectedGroup=null),this.emit()}moveAsset(e,t){let n=this.assetMap();if(!(e in n))return!1;let r=e.includes(`/`)?e.slice(e.lastIndexOf(`/`)+1):e,i=t?`${t}/${r}`:r;if(i===e)return!1;for(;i in n;)i=`${i}2`;return this.renameAssetKey(e,i)}select(e,t){if(this.cancelAddForms(),this.selectedAsset=null,this.selectedGroup=null,t?.toggle&&e!==null){let t=e.join(`.`);this.selection!==null&&this.selection.join(`.`)===t?this.selection=this.extra.shift()??this.selection:this.extra.some(e=>e.join(`.`)===t)?this.extra=this.extra.filter(e=>e.join(`.`)!==t):this.selection===null?this.selection=e:this.extra.push(e)}else this.selection=e,this.extra=[];this.emit()}allSelections(){return[...this.selection===null?[]:[this.selection,...this.extra]].sort(Uz)}isSelected(e){let t=e.join(`.`);return this.selection!==null&&this.selection.join(`.`)===t||this.extra.some(e=>e.join(`.`)===t)}onChange(e){this.listeners.add(e)}emit(){for(let e of this.listeners)e()}};function zz(e){(typeof e.uid!=`string`||e.uid===``)&&(e.uid=Qn());for(let t of e.children??[])zz(t)}function Bz(e){e.uid=Qn();for(let t of e.children??[])Bz(t)}function Vz(e,t,n){if(Array.isArray(e)){for(let r=e.length-1;r>=0;r--)typeof e[r]==`string`&&t.has(e[r])?e.splice(r,1):Vz(e[r],t,n);return}if(typeof e==`object`&&e){if(n.includes(e))return;for(let[r,i]of Object.entries(e))r!==`uid`&&(typeof i==`string`&&t.has(i)?delete e[r]:Vz(i,t,n))}}function Hz(e,t,n){if(Array.isArray(e)){e.forEach((r,i)=>{r===t?e[i]=n:Hz(r,t,n)});return}if(typeof e==`object`&&e)for(let[r,i]of Object.entries(e))i===t?e[r]=n:Hz(i,t,n)}function Uz(e,t){for(let n=0;n<Math.min(e.length,t.length);n++)if(e[n]!==t[n])return e[n]-t[n];return e.length-t.length}function Wz(e){let t=[...e].sort(Uz),n=[];for(let e of t)n.some(t=>t.length<=e.length&&t.every((t,n)=>t===e[n]))||n.push(e);return n}function Gz(e,t){let n=e.children?.indexOf(t)??-1;if(n>=0)return{parent:e,index:n};for(let n of e.children??[]){let e=Gz(n,t);if(e)return e}return null}function Kz(e,t){let n=Gz(e,t);n?.parent.children?.splice(n.index,1)}function qz(e,t){if(e===t)return[];for(let[n,r]of(e.children??[]).entries()){let e=qz(r,t);if(e)return[n,...e]}return null}function Jz(e,t,n){let r=new Set((e.children??[]).filter(e=>e!==n).map(e=>e.name));if(!r.has(t))return t;let i=2;for(;r.has(`${t}${i}`);)i+=1;return`${t}${i}`}var Yz=`
|
|
8589
8589
|
/* ─── incanto editor · design system ──────────────────────────────────────── */
|
|
8590
8590
|
:root {
|
|
8591
8591
|
--bg-0: #0b0d14;
|
|
@@ -10855,4 +10855,4 @@ body.playing #gameview-btn {
|
|
|
10855
10855
|
opacity: 0.4;
|
|
10856
10856
|
cursor: default;
|
|
10857
10857
|
}
|
|
10858
|
-
`,Jz=new Map(RF.flatMap(e=>e.nodes.map(e=>[e.type,e.summary]))),Yz=new Set,Xz=null,Zz=null,Qz=null;function $z(e){Zz=e}function eB(e){Xz=e}function tB(e){Qz=e}var nB=null,rB=null,iB=null;function aB(e){return e?e.includes(`Body`)||e.includes(`Area`)||e.includes(`Controller`)?`cat-body`:e===`NetworkSpawner`?`cat-net`:e.endsWith(`3D`)?`cat-3d`:e.endsWith(`2D`)||e===`Label`||e===`UILayer`?`cat-2d`:`cat-core`:`cat-core`}function oB(e,t){e.textContent=``;let n=document.createElement(`div`);n.className=`tree-row scene-row${t.selection===null&&t.selectedAsset===null&&t.selectedGroup===null&&!t.addingAsset&&!t.addingGroup?` selected`:``}`,n.textContent=`⚙ ${String(t.working.name??`scene`)}`,n.addEventListener(`click`,()=>t.select(null)),e.appendChild(n);let r=t.working.root;if(!r){let t=document.createElement(`div`);t.className=`muted-note explorer-empty`,t.textContent=`no root node — pick a type below and + to start the scene`,e.appendChild(t);return}uB(r,t.selection),e.appendChild(dB(r,[],t,``)),cB(e,t.selection)}var sB=null;function cB(e,t){let n=JSON.stringify(t);n!==sB&&(sB=n,e.querySelector(`.tree-row.selected`)?.scrollIntoView?.({block:`nearest`,inline:`nearest`}))}function lB(){sB=null}function uB(e,t){if(!t)return;let n=e,r=``;for(let e of t){r=r?`${r}/${n.name}`:String(n.name),Yz.delete(r);let t=n.children?.[e];if(!t)return;n=t}}function dB(e,t,n,r){let i=r?`${r}/${e.name}`:String(e.name),a=(e.children?.length??0)>0,o=Yz.has(i),s=document.createElement(`div`);s.className=`tree-branch`;let c=document.createElement(`div`);c.className=`tree-row${n.isSelected(t)?` selected`:``}`,c.draggable=t.length>0&&iB!==i;let l=document.createElement(`span`);l.className=`chevron${a?``:` leaf`}${o?` collapsed`:``}`,a?l.appendChild(eF()):l.textContent=`·`,a&&l.addEventListener(`click`,e=>{e.stopPropagation(),o?Yz.delete(i):Yz.add(i),n.select(n.selection)});let u=document.createElement(`span`);if(u.className=`tree-icon ${aB(e.type)}`,u.appendChild($P(e.type)),u.title=e.type??`instance`,u.addEventListener(`click`,t=>{t.stopPropagation(),fB(u,e.type??`instance`)}),c.append(l,u),iB===i){let r=document.createElement(`input`);r.className=`rename-input`,r.value=e.name??``;let i=()=>{iB=null;let i=r.value.trim();if(i&&i!==e.name){let e=n.renameNode(t,i)??[];e.length>0&&Qz?.(e)}else n.select(n.selection)};r.addEventListener(`keydown`,e=>{e.stopPropagation(),e.key===`Enter`&&i(),e.key===`Escape`&&(iB=null,n.select(n.selection))});for(let e of[`click`,`pointerdown`,`dblclick`,`mousedown`])r.addEventListener(e,e=>e.stopPropagation());r.addEventListener(`blur`,i),c.appendChild(r),queueMicrotask(()=>{r.focus(),r.select()})}else{let r=document.createElement(`span`);r.className=`tree-name`,r.textContent=e.name??`(unnamed)`,r.addEventListener(`dblclick`,e=>{e.stopPropagation(),iB=i,n.select(t)}),c.appendChild(r)}if(c.addEventListener(`click`,e=>{a&&!e.metaKey&&!e.ctrlKey&&(o?Yz.delete(i):Yz.add(i)),n.select(t,{toggle:e.metaKey||e.ctrlKey})}),c.addEventListener(`contextmenu`,e=>{e.preventDefault(),n.isSelected(t)||n.select(t),pB(e.clientX,e.clientY,n,t,i)}),SB(c,t,n),s.appendChild(c),a&&!o){let r=document.createElement(`div`);r.className=`tree-children`,(e.children??[]).forEach((e,a)=>{r.appendChild(dB(e,[...t,a],n,i))}),s.appendChild(r)}return s}function fB(e,t){vB();let n=document.createElement(`div`);n.className=`balloon floating`;let r=document.createElement(`span`);r.className=`balloon-title`,r.textContent=t,n.appendChild(r);let i=Jz.get(t);if(i){let e=document.createElement(`span`);e.textContent=XP(i),n.appendChild(e)}document.body.appendChild(n);let a=e.getBoundingClientRect();n.style.left=`${Math.min(innerWidth-240,a.right+8)}px`,n.style.top=`${Math.max(8,a.top-6)}px`,yB(n)}function pB(e,t,n,r,i){vB();let a=n.allSelections(),o=a.length===1&&r.length>0,s=document.createElement(`div`);s.className=`context-menu floating`;let c=(e,t,n)=>{let r=document.createElement(`button`);r.type=`button`,r.className=`menu-item${n?.danger?` danger`:``}`,r.disabled=t===null;let i=document.createElement(`span`);if(i.textContent=e,r.appendChild(i),n?.kbd){let e=document.createElement(`kbd`);e.textContent=n.kbd,r.appendChild(e)}t&&r.addEventListener(`click`,()=>{vB(),t()}),s.appendChild(r)};c(`duplicate${a.length>1?` ×${a.length}`:``}`,()=>{for(let e of[...a].reverse())n.duplicateNode(e)}),c(`frame in view`,Zz&&r.length>0?()=>{n.select(r),Zz?.()}:null,{kbd:`F`}),c(`rename`,o?()=>{iB=i,n.select(r)}:null,{kbd:`dbl-click`}),s.appendChild(mB()),c(`cut`,r.length>0?()=>hB(n,!0):null),c(`copy`,r.length>0?()=>hB(n,!1):null),c(`paste as child${rB?` (${rB.nodes.length})`:``}`,rB?()=>gB(n,r):null),s.appendChild(mB()),c(`delete`,r.length>0?()=>(Xz??(e=>n.removeNodes(e)))(a):null,{danger:!0}),document.body.appendChild(s),s.style.left=`${Math.min(innerWidth-200-8,e)}px`,s.style.top=`${Math.min(innerHeight-s.offsetHeight-8,t)}px`,yB(s)}function mB(){let e=document.createElement(`div`);return e.className=`menu-divider`,e}function hB(e,t){let n=e.allSelections().filter(e=>e.length>0).map(t=>e.nodeAt(t)).filter(e=>e!==null);rB={nodes:n.map(e=>JSON.parse(JSON.stringify(e))),cut:t?n:null}}function gB(e,t){if(rB){for(let n of rB.nodes)e.insertNode(n,t);if(rB.cut){let t=e.working.root,n=rB.cut.map(e=>_B(t,e)).filter(e=>e!==null);n.length>0&&e.removeNodes(n),rB={nodes:rB.nodes,cut:null}}}}function _B(e,t){if(e===t)return[];for(let[n,r]of(e.children??[]).entries()){let e=_B(r,t);if(e)return[n,...e]}return null}function vB(){for(let e of document.querySelectorAll(`.floating`))e.remove()}function yB(e){let t=r=>{e.contains(r.target)||(e.remove(),document.removeEventListener(`pointerdown`,t,!0),document.removeEventListener(`keydown`,n,!0))},n=r=>{r.key===`Escape`&&(e.remove(),document.removeEventListener(`pointerdown`,t,!0),document.removeEventListener(`keydown`,n,!0))};setTimeout(()=>{document.addEventListener(`pointerdown`,t,!0),document.addEventListener(`keydown`,n,!0)},0)}function bB(e,t){let n=t.getBoundingClientRect(),r=(e.clientY-n.top)/n.height;return r<.25?`before`:r>.75?`after`:`into`}function xB(e){e.classList.remove(`drop-into`,`drop-before`,`drop-after`)}function SB(e,t,n){e.addEventListener(`dragstart`,r=>{nB=n.isSelected(t)?n.allSelections():[t],r.dataTransfer?.setData(`text/plain`,``),r.dataTransfer&&(r.dataTransfer.effectAllowed=`move`),e.classList.add(`dragging`)}),e.addEventListener(`dragend`,()=>{nB=null,e.classList.remove(`dragging`)}),e.addEventListener(`dragover`,n=>{if(!nB||nB.some(e=>e.length<=t.length&&e.every((e,n)=>e===t[n])))return;n.preventDefault(),n.dataTransfer&&(n.dataTransfer.dropEffect=`move`),xB(e);let r=t.length===0?`into`:bB(n,e);e.classList.add(`drop-${r}`)}),e.addEventListener(`dragleave`,()=>xB(e)),e.addEventListener(`drop`,r=>{if(xB(e),!nB)return;r.preventDefault();let i=t.length===0?`into`:bB(r,e),a=n.moveNodes(nB,t,i);nB=null,a?.[0]&&n.select(a[0])})}var CB={x:`#fb7185`,y:`#86efac`,z:`#7aa2ff`};function wB(e,t,n){let r=t-e.origin.x,i=n-e.origin.y;if(Math.abs(r)<=e.centerSize&&Math.abs(i)<=e.centerSize)return{kind:`center`};for(let t of e.axes){let e=t.sx*t.sx+t.sy*t.sy;if(e<1)continue;let n=Math.max(0,Math.min(1,(r*t.sx+i*t.sy)/e)),a=r-t.sx*n,o=i-t.sy*n;if(n>.25&&Math.hypot(a,o)<=8)return{kind:`axis`,axis:t.axis}}return null}function TB(e,t,n){let r=e.sx*e.sx+e.sy*e.sy;return r<1?0:(t*e.sx+n*e.sy)/r*e.worldPerUnit}function EB(e,t,n,r=!1){let{origin:i,axes:a,centerSize:o}=t;for(let t of a){let a=n?.kind===`axis`&&n.axis===t.axis;e.strokeStyle=t.color,e.fillStyle=t.color,e.globalAlpha=a?1:.9,e.lineWidth=a?3:2,e.beginPath(),e.moveTo(i.x,i.y),e.lineTo(i.x+t.sx,i.y+t.sy),e.stroke();let o=Math.hypot(t.sx,t.sy)||1,s=t.sx/o,c=t.sy/o,l=i.x+t.sx,u=i.y+t.sy;e.beginPath(),r?e.rect(l-5,u-5,10,10):(e.moveTo(l+s*9,u+c*9),e.lineTo(l-c*4.5,u+s*4.5),e.lineTo(l+c*4.5,u-s*4.5),e.closePath()),e.fill(),e.font=`700 9px Inter, system-ui, sans-serif`,e.textAlign=`center`,e.textBaseline=`middle`,e.fillText(t.axis.toUpperCase(),l+s*18,u+c*18)}let s=n?.kind===`center`;e.globalAlpha=s?1:.95,e.fillStyle=s?`#ffffff`:`#e2e6f0`,e.strokeStyle=`#0b0d14`,e.lineWidth=1.5,e.beginPath(),e.rect(i.x-o,i.y-o,o*2,o*2),e.fill(),e.stroke(),e.globalAlpha=1}function DB(e,t,n){return Math.atan2(n-e.y,t-e.x)*180/Math.PI}function OB(e,t){let n=t-e;for(;n>180;)n-=360;for(;n<=-180;)n+=360;return n}function kB(e,t,n,r){let i=null,a=r;for(let r of e)for(let e of r.points){let o=Math.hypot(t-e.x,n-e.y);o<a&&(a=o,i=r.axis)}return i}function AB(e,t,n){for(let r of t){if(r.points.length<2)continue;let t=n===r.axis;e.strokeStyle=CB[r.axis],e.globalAlpha=t?1:.75,e.lineWidth=t?3:2,e.beginPath();let i=r.points[0];e.moveTo(i.x,i.y);for(let t of r.points.slice(1))e.lineTo(t.x,t.y);e.closePath(),e.stroke()}e.globalAlpha=1}function jB(e,t,n,r){e.font=`600 11px ui-monospace, Menlo, monospace`;let i=e.measureText(r).width+14;e.fillStyle=`rgba(16, 19, 29, 0.92)`,e.strokeStyle=`rgba(110, 231, 220, 0.5)`,e.lineWidth=1,e.beginPath(),e.roundRect(t+14,n-26,i,20,5),e.fill(),e.stroke(),e.fillStyle=`#6ee7dc`,e.textAlign=`left`,e.textBaseline=`middle`,e.fillText(r,t+21,n-16)}var MB=class{engine;editCanvas;overlay;playCanvas;cb;editUiHost=null;playUiHost=null;renderer2d=null;renderer3d=null;rendererDim=null;orbit={yaw:.6,pitch:.35,dist:10,target:[0,1,0]};pathOf=new Map;reindexNeeded=!1;nodeAtPath=new Map;selectedPath=null;paintHandler=null;extraPaths=[];hoveredNode=null;hoveredGizmo=null;lastGood=null;lastAppliedKey=null;playEngine=null;playRenderer=null;playPhysics=null;setPaintHandler(e){this.paintHandler=e}get playing(){return this.playEngine!==null}constructor(e,t,n,r){this.editCanvas=e,this.overlay=t,this.playCanvas=n,this.cb=r;let i=this;this.engine=new kt({scheduler:e=>{let t=0,n=performance.now(),r=requestAnimationFrame(function a(o){t+=.001;let s=Math.min(.1,(o-n)/1e3);n=o;try{e(t),i.tickAmbientPreviews(s)}catch(e){console.error(`incanto-editor viewport:`,e)}r=requestAnimationFrame(a)});return()=>cancelAnimationFrame(r)}}),this.editUiHost=this.makeUiHost(e.parentElement,4),this.playUiHost=this.makeUiHost(n.parentElement,5),this.engine.uiHost=this.editUiHost,this.engine.start(),this.engine.updated.connect(()=>this.drawOverlay());let a=e=>{e.key===`Shift`&&(this.shiftHeld=!0)},o=e=>{e.key===`Shift`&&(this.shiftHeld=!1)};window.addEventListener(`keydown`,a),window.addEventListener(`keyup`,o),this.cleanups.push(()=>{window.removeEventListener(`keydown`,a),window.removeEventListener(`keyup`,o)}),this.bindPointer()}cleanups=[];makeUiHost(e,t){if(!e)return null;let n=document.createElement(`div`);return n.style.cssText=`position:absolute;inset:0;pointer-events:none;z-index:${t};`,e.appendChild(n),this.cleanups.push(()=>n.remove()),n}dispose(){this.stop(),this.editPhysics?.dispose(),this.editPhysics=null,this.engine.stop(),this.engine.dispose(),this.renderer2d?.dispose(),this.renderer3d?.dispose(),this.renderer2d=null,this.renderer3d=null;for(let e of this.cleanups.splice(0))e()}setEditCamera(e,t){let n=(e[0]??0)-(t[0]??0),r=(e[1]??0)-(t[1]??0),i=(e[2]??0)-(t[2]??0),a=Math.hypot(n,r,i);a>.01&&(this.orbit.target=[t[0]??0,t[1]??0,t[2]??0],this.orbit.dist=Math.min(800,Math.max(.3,a)),this.orbit.yaw=Math.atan2(n,i),this.orbit.pitch=Math.asin(Math.max(-.99,Math.min(.99,r/a))),this.syncOrbit())}editCamera(){let{pos:e}=this.orbitVectors();return{position:[e.x,e.y,e.z],target:[...this.orbit.target]}}apply(e){e.root||(e={...e,root:{name:`__empty`,type:(e.dimension??`2d`)===`3d`?`Node3D`:`Node2D`}});let t=JSON.stringify(e);if(t===this.lastAppliedKey&&this.rendererDim===(e.dimension??`2d`))return null;let n;try{let t=structuredClone(e);YB(t),n=An(t,{stubAllBehaviors:!0})}catch(e){return e instanceof Error?e.message:String(e)}this.lastGood=e,this.lastAppliedKey=t;let r=e.dimension??`2d`;if(this.rendererDim!==r){if(this.renderer2d?.dispose(),this.renderer3d?.dispose(),this.renderer2d=null,this.renderer3d=null,r===`2d`)this.renderer2d=new qv({canvas:this.editCanvas,engine:this.engine}),this.renderer2d.ignoreStatic=!0,this.renderer2d.viewOverride=this.defaultView(e);else{this.renderer3d=new _P({canvas:this.editCanvas,engine:this.engine}),this.renderer3d.ignoreStatic=!0;let t=GB(e.root);if(t){let[e,n,r]=t;this.orbit.dist=Math.max(2,Math.hypot(e,n,r)),this.orbit.yaw=Math.atan2(e,r),this.orbit.pitch=Math.asin(Math.max(-.99,Math.min(.99,n/this.orbit.dist))),this.orbit.target=[0,Math.min(2,Math.abs(n)/2),0]}this.syncOrbit()}this.rendererDim=r}return this.engine.setScene(n),this.indexTree(n.root),this.hoveredNode=null,null}setSelection(e,t=[]){this.selectedPath=e,this.extraPaths=t}validate(e){if(!e.root)return null;try{let t=structuredClone(e);return YB(t),An(t,{stubAllBehaviors:!0}),null}catch(e){return e instanceof Error?e.message:String(e)}}defaultView(e){let t=KB(e.root);if(t)return{cx:t[0],cy:t[1],zoom:1};let n=this.editCanvas.clientWidth||960,r=this.editCanvas.clientHeight||540;return{cx:n/2,cy:r/2,zoom:1}}indexTree(e){this.pathOf=new Map,this.nodeAtPath=new Map;let t=(e,n)=>{this.pathOf.set(e,n),this.nodeAtPath.set(n.join(`.`),e),e.children.forEach((e,r)=>{t(e,[...n,r])})};t(e,[])}liveSelected(){return this.selectedPath===null?null:this.nodeAtPath.get(this.selectedPath.join(`.`))??null}patchProp(e,t,n,r){if(this.playing)return!1;let i=this.nodeAtPath.get(t.join(`.`));if(!i)return!1;try{i[n]=r===void 0?void 0:structuredClone(r)}catch{return!1}return this.reindexNeeded=!0,this.lastAppliedKey=JSON.stringify(e),!0}gizmoActive=null;gizmoMode=`move`;activeRing=null;readout=null;cancelActiveDrag=()=>{};shiftHeld=!1;get showColliders(){return this.collidersOn}set showColliders(e){this.collidersOn=e,this.editPhysics&&(this.editPhysics.debugDraw=e),e&&this.ensureOutlinePhysics()}collidersOn=!0;editPhysics=null;outlinePending=null;async ensureOutlinePhysics(){if(this.editPhysics||this.outlinePending)return this.outlinePending??void 0;let e=this.rendererDim;if(e)return this.outlinePending=(async()=>{try{if(e===`2d`){let{enablePhysics2D:e}=await bm(async()=>{let{enablePhysics2D:e}=await Promise.resolve().then(()=>ay);return{enablePhysics2D:e}},void 0,import.meta.url),t=await e(this.engine,{simulate:!1});t.debugDraw=this.collidersOn,this.editPhysics=t}else{let{enablePhysics3D:e}=await bm(async()=>{let{enablePhysics3D:e}=await Promise.resolve().then(()=>NP);return{enablePhysics3D:e}},void 0,import.meta.url),t=await e(this.engine,{simulate:!1});t.debugDraw=this.collidersOn,this.editPhysics=t}}catch(e){console.warn(`[incanto] collider outlines unavailable:`,e)}finally{this.outlinePending=null}})(),this.outlinePending}get mode(){return this.gizmoMode}setMode(e){this.gizmoMode=e,this.cb.onModeChanged(e)}gizmoLayout(){let e=this.liveSelected();if(!e)return null;if(this.rendererDim===`2d`&&this.renderer2d){let t=e.position;if(!Array.isArray(t))return null;let n=WB(e),r=this.renderer2d.screenFromWorld(n.x,n.y),i=this.renderer2d.view().zoom;return{origin:r,centerSize:7,axes:[{axis:`x`,sx:64,sy:0,worldPerUnit:64/i,color:CB.x},{axis:`y`,sx:0,sy:64,worldPerUnit:64/i,color:CB.y}]}}if(this.rendererDim===`3d`&&this.renderer3d){let t=e._object3D,n=e.position;if(!t||!Array.isArray(n))return null;t.getWorldPosition(RB);let r=this.renderer3d.screenFromWorld(RB.x,RB.y,RB.z);if(r.behind)return null;let i=[],a=this.orbit.dist,o=Math.max(.2,a*.18);for(let[e,t]of[[`x`,[1,0,0]],[`y`,[0,1,0]],[`z`,[0,0,1]]]){let n=this.renderer3d.screenFromWorld(RB.x+t[0]*o,RB.y+t[1]*o,RB.z+t[2]*o);n.behind||i.push({axis:e,sx:n.x-r.x,sy:n.y-r.y,worldPerUnit:o,color:CB[e]})}return{origin:{x:r.x,y:r.y},centerSize:7,axes:i}}return null}ringLayout(){let e=this.liveSelected();if(!e)return null;if(this.rendererDim===`2d`&&this.renderer2d){let t=WB(e),n=this.renderer2d.screenFromWorld(t.x,t.y),r=[];for(let e=0;e<48;e++){let t=e/48*Math.PI*2;r.push({x:n.x+56*Math.cos(t),y:n.y+56*Math.sin(t)})}return{origin:n,rings:[{axis:`z`,points:r}]}}if(this.rendererDim===`3d`&&this.renderer3d){let t=e._object3D;if(!t)return null;t.getWorldPosition(RB);let n={x:RB.x,y:RB.y,z:RB.z},r=this.renderer3d.screenFromWorld(n.x,n.y,n.z);if(r.behind)return null;let i=Math.max(.2,this.orbit.dist*.16),a=[];for(let e of[`x`,`y`,`z`]){let t=[];for(let r=0;r<48;r++){let a=r/48*Math.PI*2,o=Math.cos(a)*i,s=Math.sin(a)*i,c=e===`x`?this.renderer3d.screenFromWorld(n.x,n.y+o,n.z+s):e===`y`?this.renderer3d.screenFromWorld(n.x+o,n.y,n.z+s):this.renderer3d.screenFromWorld(n.x+o,n.y+s,n.z);c.behind||t.push({x:c.x,y:c.y})}a.push({axis:e,points:t})}return{origin:{x:r.x,y:r.y},rings:a}}return null}orbitVectors(){let{yaw:e,pitch:t,dist:n,target:r}=this.orbit,i=Math.cos(t),a=new U(r[0]+n*i*Math.sin(e),r[1]+n*Math.sin(t),r[2]+n*i*Math.cos(e)),o=new U(r[0],r[1],r[2]).sub(a).normalize(),s=new U().crossVectors(o,PB).normalize();return{pos:a,right:s,up:new U().crossVectors(s,o).normalize(),forward:o}}syncOrbit(){if(!this.renderer3d)return;let{pos:e}=this.orbitVectors();this.renderer3d.viewOverride={position:[e.x,e.y,e.z],target:[...this.orbit.target]}}gameView(){if(this.rendererDim===`3d`&&this.renderer3d){let e=null;for(let[t]of this.pathOf)if(t instanceof VE&&(t.current||!e)&&(e=t,t.current))break;let t=e?e._ensureObject3D():null;if(t){t.getWorldPosition(FB),IB.set(0,0,-1).applyQuaternion(t.getWorldQuaternion(LB));let e=Math.min(40,Math.max(3,this.orbit.dist));this.orbit.target=[FB.x+IB.x*e,FB.y+IB.y*e,FB.z+IB.z*e],this.orbit.dist=e,this.orbit.yaw=Math.atan2(-IB.x,-IB.z),this.orbit.pitch=Math.asin(Math.max(-.99,Math.min(.99,-IB.y)))}this.renderer3d.viewOverride=null;return}this.renderer2d&&(this.renderer2d.viewOverride=null)}snapView(e,t){e===`y`?(this.orbit.pitch=t*1.45,this.orbit.yaw=0):(this.orbit.pitch=0,this.orbit.yaw=e===`z`?t===1?0:Math.PI:Math.PI/2*t),this.syncOrbit()}gizmoCenter(){return{x:this.overlay.clientWidth-58,y:58,r:36}}gizmoHandles(){let{right:e,up:t,forward:n}=this.orbitVectors(),r=this.gizmoCenter(),i=[];for(let[a,o]of[[`x`,new U(1,0,0)],[`y`,new U(0,1,0)],[`z`,new U(0,0,1)]])for(let s of[1,-1]){let c=o.clone().multiplyScalar(s);i.push({axis:a,sign:s,x:r.x+c.dot(e)*26,y:r.y-c.dot(t)*26,z:-c.dot(n)})}return i.sort((e,t)=>e.z-t.z)}gizmoHit(e,t){let n=this.gizmoCenter();if(Math.hypot(e-n.x,t-n.y)>n.r+8)return null;let r=null,i=14;for(let n of this.gizmoHandles()){let a=Math.hypot(e-n.x,t-n.y);a<i&&(i=a,r={axis:n.axis,sign:n.sign})}return r??{axis:`z`,sign:1}}gizmoHandleAt(e,t){let n=this.gizmoCenter();if(Math.hypot(e-n.x,t-n.y)>n.r+8)return null;let r=null,i=12;for(let n of this.gizmoHandles()){let a=Math.hypot(e-n.x,t-n.y);a<i&&(i=a,r={axis:n.axis,sign:n.sign})}return r}tickAmbientPreviews(e){if(!this.playing)for(let[t]of this.pathOf)(t instanceof Yk||t instanceof Tv||t instanceof Qk||t instanceof hg||t instanceof bk)&&t.update(e)}modelAnimationsAt(e){let t=this.nodeAtPath.get(e.join(`.`));return t instanceof Yk?t.availableAnimations():[]}boneNamesAt(e,t){let n=this.nodeAtPath.get(e.join(`.`));if(!n||t===``)return[];let r=n.getNodeOrNull(t);return r instanceof Yk?r.boneNames():[]}drawOverlay(){if(this.reindexNeeded){this.reindexNeeded=!1;let e=this.engine.scene?.tree.root;e&&this.indexTree(e)}let e=this.overlay.getContext(`2d`);if(!e)return;let t=this.overlay.clientWidth,n=this.overlay.clientHeight,r=Math.min(devicePixelRatio||1,2);if((this.overlay.width!==t*r||this.overlay.height!==n*r)&&(this.overlay.width=t*r,this.overlay.height=n*r),e.setTransform(r,0,0,r,0,0),e.clearRect(0,0,t,n),this.playing)return;if(this.rendererDim===`3d`){this.drawGizmo(e),this.drawModeGizmo(e),this.readout&&jB(e,this.readout.x,this.readout.y,this.readout.text);return}if(!this.renderer2d)return;if(this.drawAxes2D(e),this.hoveredNode&&this.hoveredNode!==this.liveSelected()){let t=this.renderer2d.boundsOf(this.hoveredNode);t&&(e.strokeStyle=`rgba(110, 231, 220, 0.45)`,e.lineWidth=1.5,e.setLineDash([]),e.strokeRect(t.x,t.y,t.w,t.h))}for(let t of this.extraPaths){let n=this.nodeAtPath.get(t.join(`.`)),r=n?this.renderer2d.boundsOf(n):null;r&&(e.strokeStyle=`rgba(110, 231, 220, 0.7)`,e.lineWidth=1.5,e.setLineDash([4,3]),e.strokeRect(r.x-2,r.y-2,r.w+4,r.h+4),e.setLineDash([]))}let i=this.liveSelected();if(i){let t=this.renderer2d.boundsOf(i)??this.pointBounds(i);if(t){e.strokeStyle=`#6ee7dc`,e.lineWidth=2,e.setLineDash([6,4]),e.lineDashOffset=-(performance.now()/50%10),e.strokeRect(t.x-2,t.y-2,t.w+4,t.h+4),e.setLineDash([]),e.fillStyle=`#6ee7dc`;for(let[n,r]of[[t.x-2,t.y-2],[t.x+t.w+2,t.y-2],[t.x-2,t.y+t.h+2],[t.x+t.w+2,t.y+t.h+2]])e.fillRect(n-3,r-3,6,6)}}this.drawModeGizmo(e),this.readout&&jB(e,this.readout.x,this.readout.y,this.readout.text)}drawModeGizmo(e){if(this.gizmoMode===`rotate`){let t=this.ringLayout();t&&AB(e,t.rings,this.activeRing);return}let t=this.gizmoLayout();t&&EB(e,t,this.gizmoActive,this.gizmoMode===`scale`)}pointBounds(e){if(!this.renderer2d)return null;let t=e.position;if(!Array.isArray(t))return null;let n=WB(e),r=this.renderer2d.screenFromWorld(n.x,n.y);return{x:r.x-12,y:r.y-12,w:24,h:24}}drawGizmo(e){let t=this.gizmoCenter();e.beginPath(),e.arc(t.x,t.y,t.r,0,Math.PI*2),e.fillStyle=`rgba(16, 19, 29, 0.72)`,e.fill(),e.strokeStyle=`rgba(52, 60, 84, 0.9)`,e.lineWidth=1,e.stroke();let n={x:`#fb7185`,y:`#86efac`,z:`#7aa2ff`},r={x1:`right`,"x-1":`left`,y1:`top`,"y-1":`bottom`,z1:`front`,"z-1":`back`};for(let r of this.gizmoHandles()){let i=this.hoveredGizmo?.axis===r.axis&&this.hoveredGizmo?.sign===r.sign,a=n[r.axis],o=(r.z+1)/2;e.globalAlpha=i?1:.45+o*.55,e.strokeStyle=a,e.lineWidth=1.5,e.beginPath(),e.moveTo(t.x,t.y),e.lineTo(r.x,r.y),e.stroke(),e.beginPath(),e.arc(r.x,r.y,(r.sign===1?7:5)+(i?2:0),0,Math.PI*2),r.sign===1?(e.fillStyle=a,e.fill(),e.fillStyle=`#0b0d14`,e.font=`700 8px ui-monospace, monospace`,e.textAlign=`center`,e.textBaseline=`middle`,e.fillText(r.axis.toUpperCase(),r.x,r.y+.5)):(e.fillStyle=`rgba(16, 19, 29, 0.9)`,e.fill(),e.stroke())}if(e.globalAlpha=1,this.hoveredGizmo){let n=r[`${this.hoveredGizmo.axis}${this.hoveredGizmo.sign}`];e.fillStyle=`#9aa3bd`,e.font=`600 10px Inter, system-ui, sans-serif`,e.textAlign=`center`,e.textBaseline=`bottom`,e.fillText(`${n} view`,t.x,t.y-t.r-6)}}drawAxes2D(e){let t=this.gizmoCenter();e.save(),e.shadowColor=`rgba(0, 0, 0, 0.25)`,e.shadowBlur=10,e.shadowOffsetY=2,e.beginPath(),e.arc(t.x,t.y,31,0,Math.PI*2),e.fillStyle=`rgba(13, 16, 24, 0.42)`,e.fill(),e.shadowColor=`transparent`,e.strokeStyle=`rgba(255, 255, 255, 0.16)`,e.lineWidth=1,e.stroke();let n=t.x-9,r=t.y-9;e.lineCap=`round`;let i=(t,i,a,o)=>{let s=n+t*21,c=r+i*21,l=e.createLinearGradient(n,r,s,c);l.addColorStop(0,`${a}55`),l.addColorStop(1,a),e.strokeStyle=l,e.lineWidth=2,e.beginPath(),e.moveTo(n,r),e.lineTo(s,c),e.stroke(),e.beginPath(),e.arc(s,c,6.5,0,Math.PI*2),e.fillStyle=a,e.fill(),e.font=`800 8px Inter, system-ui, sans-serif`,e.textAlign=`center`,e.textBaseline=`middle`,e.fillStyle=`#0b0d14`,e.fillText(o,s,c+.5)};i(1,0,`#fb7185`,`X`),i(0,1,`#86efac`,`Y`),e.beginPath(),e.arc(n,r,2.5,0,Math.PI*2),e.fillStyle=`#e2e6f0`,e.fill(),e.restore()}bindPointer(){let e=this.overlay,t=null,n=null,r=!1,i=null,a=null,o=null,s=null,c=null,l=t=>{let n=this.ringLayout();if(!n)return!1;let r=kB(n.rings,t.offsetX,t.offsetY,9);if(!r)return!1;let i=this.liveSelected();if(!i)return!1;e.setPointerCapture(t.pointerId);let a=i.rotation,o=1;if(this.rendererDim===`3d`&&this.renderer3d){let{forward:e}=this.renderer3d.cameraBasis();o=(r===`x`?e.x:r===`y`?e.y:e.z)>0?1:-1}return c={axis:r,node:i,origin:n.origin,startAngle:DB(n.origin,t.offsetX,t.offsetY),startRotation:Array.isArray(a)?[...a]:a??0,sign:o},this.activeRing=r,!0},u=e=>{if(!c)return;let{axis:t,node:n,origin:r,startAngle:i,startRotation:a,sign:o}=c,s=OB(i,DB(r,e.offsetX,e.offsetY))*o,l=e.shiftKey||this.shiftHeld?15:null,u=e=>{let t=e+s;return l?Math.round(t/l)*l:Math.round(t*10)/10},d;if(Array.isArray(a)){let e={x:0,y:1,z:2}[t],r=[...a];r[e]=u(a[e]??0),d=r[e],n.rotation=r}else{let e=u(a);d=e,n.rotation=e}this.readout={x:e.offsetX,y:e.offsetY,text:`${d}°${l?` ⌁15°`:``}`}},d=e=>{if(!c)return;let{node:t,startRotation:n}=c;if(!e)t.rotation=n;else{let e=this.pathOf.get(t),n=t.rotation;e!==void 0&&n!==void 0&&(Array.isArray(n)?this.cb.onNodeRotated3D(e,[n[0]??0,n[1]??0,n[2]??0]):this.cb.onNodeRotated2D(e,n))}c=null,this.activeRing=null,this.readout=null};this.cancelActiveDrag=()=>{d(!1),s&&(s.node.position=s.startPos,s.node.scale=s.startScale,s=null,this.gizmoActive=null,this.readout=null)};let f=t=>{if(this.gizmoMode===`rotate`)return l(t);let n=this.gizmoLayout();if(!n)return!1;let r=wB(n,t.offsetX,t.offsetY);if(!r)return!1;let i=this.liveSelected();if(!i)return!1;e.setPointerCapture(t.pointerId);let a=[...i.position??[]],o=[...i.scale??[]];return s={hit:r,mode:this.gizmoMode===`scale`||t.button===2?`scale`:`move`,startX:t.offsetX,startY:t.offsetY,layout:n,node:i,startPos:a,startScale:o},this.gizmoActive=r,!0},p=e=>{if(!s)return;let{hit:t,mode:n,layout:r,node:i,startPos:a,startScale:o}=s,c=e.offsetX-s.startX,l=e.offsetY-s.startY,u=this.rendererDim===`3d`,d={x:0,y:1,z:2},f=e.shiftKey||this.shiftHeld,p=f?u?.5:10:null,m=f?.25:null,h=e=>p?Math.round(e/p)*p:e,g=e=>m?Math.max(m,Math.round(e/m)*m):e;if(n===`scale`){let n=Math.max(.05,1+(c-l)*.005),r=[...o];if(t.kind===`axis`)r[d[t.axis]]=NB(g((o[d[t.axis]]??1)*n));else for(let e=0;e<r.length;e++)r[e]=NB(g((o[e]??1)*n));i.scale=r,this.readout={x:e.offsetX,y:e.offsetY,text:`×${r.map(e=>NB(e)).join(`, `)}`};return}let _=[...a];if(t.kind===`axis`){let e=r.axes.find(e=>e.axis===t.axis);if(!e)return;let n=TB(e,c,l);if(u)_[d[t.axis]]=NB(h((a[d[t.axis]]??0)+n));else{let e=HB(i,t.axis===`x`?n:0,t.axis===`y`?n:0),r=t.axis===`x`?e.x:e.y;_[d[t.axis]]=Math.round(h((a[d[t.axis]]??0)+r))}}else if(u&&this.renderer3d){let{right:e,up:t}=this.renderer3d.cameraBasis(),n=this.orbit.dist*.0016;_[0]=NB(h((a[0]??0)+(e.x*c-t.x*l)*n)),_[1]=NB(h((a[1]??0)+(e.y*c-t.y*l)*n)),_[2]=NB(h((a[2]??0)+(e.z*c-t.z*l)*n))}else if(this.renderer2d){let e=this.renderer2d.view(),t=HB(i,c/e.zoom,l/e.zoom);_[0]=Math.round(h((a[0]??0)+t.x)),_[1]=Math.round(h((a[1]??0)+t.y))}i.position=_,this.readout={x:e.offsetX,y:e.offsetY,text:`[${_.map(e=>NB(e)).join(`, `)}]`}},m=()=>{if(!s)return;let{node:e,mode:t}=s,n=this.pathOf.get(e);if(n)if(t===`scale`){let t=e.scale??[];this.rendererDim===`3d`?this.cb.onNodeScaled3D(n,[t[0]??1,t[1]??1,t[2]??1]):this.cb.onNodeScaled(n,[t[0]??1,t[1]??1])}else{let t=e.position??[];this.rendererDim===`3d`?this.cb.onNodeMoved3D(n,[t[0]??0,t[1]??0,t[2]??0]):this.cb.onNodeMoved(n,[t[0]??0,t[1]??0])}s=null,this.gizmoActive=null};e.addEventListener(`pointerdown`,s=>{if(this.playing||f(s))return;if(this.rendererDim===`3d`){let t=this.gizmoHit(s.offsetX,s.offsetY);if(t){this.snapView(t.axis,t.sign);return}e.setPointerCapture(s.pointerId),s.button===1||s.button===2||s.shiftKey?a={x:s.offsetX,y:s.offsetY,target:[...this.orbit.target]}:(i={x:s.offsetX,y:s.offsetY,yaw:this.orbit.yaw,pitch:this.orbit.pitch},o={x:s.offsetX,y:s.offsetY,toggle:s.ctrlKey||s.metaKey});return}if(!this.renderer2d)return;if(e.setPointerCapture(s.pointerId),s.button===1||s.button===2||s.shiftKey){let e=this.renderer2d.view();n={startX:s.offsetX,startY:s.offsetY,cx:e.cx,cy:e.cy};return}if(this.paintHandler&&s.button===0){let e=this.renderer2d.worldFromScreen(s.offsetX,s.offsetY);this.paintHandler(e.x,e.y,!0),r=!0;return}let c=this.renderer2d.pick(s.offsetX,s.offsetY),l=c?this.pathOf.get(c)??null:null;if(this.cb.onPick(l,{toggle:s.ctrlKey||s.metaKey}),this.selectedPath=l,c&&l&&Array.isArray(c.position)){let e=c.position;t={node:c,startWorld:this.renderer2d.worldFromScreen(s.offsetX,s.offsetY),startPos:[e[0]??0,e[1]??0]}}}),e.addEventListener(`pointermove`,o=>{if(!this.playing){if(c){u(o);return}if(s){p(o);return}if(this.rendererDim===`3d`){if(!i&&!a?(this.hoveredGizmo=this.gizmoHandleAt(o.offsetX,o.offsetY),e.style.cursor=this.hoveredGizmo?`pointer`:`grab`):e.style.cursor=`grabbing`,i)this.orbit.yaw=i.yaw-(o.offsetX-i.x)*.006,this.orbit.pitch=Math.max(-1.5,Math.min(1.5,i.pitch+(o.offsetY-i.y)*.006)),this.syncOrbit();else if(a){let{right:e,up:t}=this.orbitVectors(),n=this.orbit.dist*.0016,r=(o.offsetX-a.x)*n,i=(o.offsetY-a.y)*n;this.orbit.target=[a.target[0]-e.x*r+t.x*i,a.target[1]-e.y*r+t.y*i,a.target[2]-e.z*r+t.z*i],this.syncOrbit()}return}if(this.renderer2d){if(e.style.cursor=`crosshair`,r&&this.paintHandler){let e=this.renderer2d.worldFromScreen(o.offsetX,o.offsetY);this.paintHandler(e.x,e.y,!1);return}if(n){let e=this.renderer2d.view();this.renderer2d.viewOverride={cx:n.cx-(o.offsetX-n.startX)/e.zoom,cy:n.cy-(o.offsetY-n.startY)/e.zoom,zoom:e.zoom};return}if(t){let e=this.renderer2d.worldFromScreen(o.offsetX,o.offsetY),n=HB(t.node,e.x-t.startWorld.x,e.y-t.startWorld.y),r=Math.round(t.startPos[0]+n.x),i=Math.round(t.startPos[1]+n.y);t.node.position=[r,i];return}this.hoveredNode=this.renderer2d.pick(o.offsetX,o.offsetY)}}});let h=e=>{if(r=!1,d(!0),m(),this.readout=null,o&&e&&this.renderer3d&&Math.hypot(e.offsetX-o.x,e.offsetY-o.y)<4){let e=this.renderer3d.pick(o.x,o.y),t=e?this.pathOf.get(e)??null:null;t&&(this.cb.onPick(t,{toggle:o.toggle}),this.selectedPath=t)}if(o=null,i=null,a=null,t){let e=this.pathOf.get(t.node),n=t.node.position;e&&(n[0]!==t.startPos[0]||n[1]!==t.startPos[1])&&this.cb.onNodeMoved(e,[n[0]??0,n[1]??0]),t=null}n=null};e.addEventListener(`pointerup`,h),e.addEventListener(`pointercancel`,h),e.addEventListener(`contextmenu`,e=>e.preventDefault()),e.addEventListener(`dblclick`,e=>{if(this.playing)return;let t=this.rendererDim===`3d`?this.renderer3d?.pick(e.offsetX,e.offsetY)??null:this.renderer2d?.pick(e.offsetX,e.offsetY)??null,n=t?this.pathOf.get(t)??null:null;n&&(this.cb.onPick(n,{toggle:e.ctrlKey||e.metaKey}),this.selectedPath=n)}),e.addEventListener(`wheel`,e=>{if(this.playing)return;e.preventDefault();let t=e.deltaY<0?1.1:1/1.1;if(this.rendererDim===`3d`){this.orbit.dist=Math.max(.3,Math.min(800,this.orbit.dist/t)),this.syncOrbit();return}if(!this.renderer2d)return;let n=this.liveSelected();if(e.altKey&&n&&Array.isArray(n.scale)){let e=n.scale,r=[Math.round((e[0]??1)*t*100)/100,Math.round((e[1]??1)*t*100)/100];n.scale=r;let i=this.pathOf.get(n);i&&this.cb.onNodeScaled(i,r);return}let r=this.renderer2d.view(),i=this.renderer2d.worldFromScreen(e.offsetX,e.offsetY),a=Math.min(8,Math.max(.1,r.zoom*t));this.renderer2d.viewOverride={cx:i.x-(e.offsetX-r.w/2)/a,cy:i.y-(e.offsetY-r.h/2)/a,zoom:a}},{passive:!1})}zoomToFit(){let e=this.liveSelected();if(this.rendererDim===`3d`){let t=new Vo;for(let[n]of this.pathOf){if(e&&n!==e&&!UB(n,e))continue;let r=n._object3D;r&&(t.expandByObject(r),t.expandByPoint(r.getWorldPosition(RB)))}if(t.isEmpty()&&e){let t=e._object3D,n=t?t.getWorldPosition(RB):null;this.orbit.target=n?[n.x,n.y,n.z]:[0,1,0],this.orbit.dist=6}else if(t.isEmpty())this.orbit.target=[0,1,0],this.orbit.dist=10;else{let e=t.getCenter(new U),n=t.getSize(new U);this.orbit.target=[e.x,e.y,e.z],this.orbit.dist=Math.max(2.5,n.length()*.85)}this.syncOrbit();return}if(!this.renderer2d)return;let t=this.editCanvas.clientWidth||960,n=this.editCanvas.clientHeight||540,r=1/0,i=1/0,a=-1/0,o=-1/0;for(let[t]of this.pathOf){if(e&&t!==e&&!UB(t,e))continue;let n=t.position;if(!Array.isArray(n))continue;let s=WB(t);r=Math.min(r,s.x),i=Math.min(i,s.y),a=Math.max(a,s.x),o=Math.max(o,s.y)}if(!Number.isFinite(r))return;let s=(r+a)/2,c=(i+o)/2,l=e?600:200,u=Math.max(a-r+l,l),d=Math.max(o-i+l,l),f=Math.min(2,Math.min(t/u,n/d));this.renderer2d.viewOverride={cx:s,cy:c,zoom:f}}async play(e){if(this.playing)return null;let t=structuredClone(e);YB(t);let n;try{n=An(t,{stubAllBehaviors:!0,declareConnectionSignals:!0})}catch(e){return e instanceof Error?e.message:String(e)}let r=new kt;r.uiHost=this.playUiHost,this.editUiHost&&(this.editUiHost.style.display=`none`),r.setScene(n),r.input.attachKeyboard(window),this.playCanvas.hidden=!1;let i=e.dimension??`2d`;try{if(i===`2d`){this.playRenderer=new qv({canvas:this.playCanvas,engine:r});let{enablePhysics2D:e}=await bm(async()=>{let{enablePhysics2D:e}=await Promise.resolve().then(()=>ay);return{enablePhysics2D:e}},void 0,import.meta.url),t=await e(r);t.debugDraw=this.showColliders,this.playPhysics=t}else{this.playRenderer=new _P({canvas:this.playCanvas,engine:r,assets:this.renderer3d?.assets});let{enablePhysics3D:e}=await bm(async()=>{let{enablePhysics3D:e}=await Promise.resolve().then(()=>NP);return{enablePhysics3D:e}},void 0,import.meta.url),t=await e(r);t.debugDraw=this.showColliders,this.playPhysics=t}}catch(e){return this.stop(),e instanceof Error?e.message:String(e)}return r.start(),this.playEngine=r,this.cb.onPlayStateChanged(!0),null}stop(){this.playEngine?.input.dispose(),this.playEngine?.stop(),this.playEngine?.dispose(),this.playEngine=null,this.playPhysics?.dispose(),this.playPhysics=null,this.editUiHost&&(this.editUiHost.style.display=``),this.playRenderer?.dispose(),this.playRenderer=null,this.playCanvas.hidden=!0,this.cb.onPlayStateChanged(!1),this.lastAppliedKey=null,this.lastGood&&this.apply(this.lastGood)}};function NB(e){return Math.round(e*100)/100}var PB=new U(0,1,0),FB=new U,IB=new U,LB=new H,RB=new U,zB=new G,BB=new U,VB=new U;function HB(e,t,n){let r=e._object2D?.parent;return r?(zB.copy(r.matrixWorld).invert(),BB.set(t,-n,0).applyMatrix4(zB),VB.set(0,0,0).applyMatrix4(zB),{x:BB.x-VB.x,y:-(BB.y-VB.y)}):{x:t,y:n}}function UB(e,t){for(let n=e.parent;n;n=n.parent)if(n===t)return!0;return!1}function WB(e){let t=e._object2D;if(t)return t.getWorldPosition(RB),{x:RB.x,y:-RB.y};let n=0,r=0,i=e;for(;i;)Array.isArray(i.position)&&(n+=i.position[0]??0,r+=i.position[1]??0),i=i.parent;return{x:n,y:r}}function GB(e){if(!e)return null;if(e.type===`Camera3D`){let t=e.props?.position??[0,2,8];return[t[0]??0,t[1]??2,t[2]??8]}for(let t of e.children??[]){let e=GB(t);if(e)return e}return null}function KB(e){if(!e)return null;if(e.type===`Camera2D`){let t=e.props?.position??[0,0];return[t[0]??0,t[1]??0]}for(let t of e.children??[]){let e=KB(t);if(e)return e}return null}var qB=null;function JB(){if(qB)return qB;let e=document.createElement(`canvas`);e.width=16,e.height=16;let t=e.getContext(`2d`);for(let e=0;e<2;e++)for(let n=0;n<2;n++)t.fillStyle=(n+e)%2==0?`#c252c2`:`#2b2b3b`,t.fillRect(n*8,e*8,8,8);return qB=e.toDataURL(),qB}function YB(e){let t=e.assets;if(t)for(let e of Object.values(t))typeof e?.url==`string`&&!e.url.includes(`/`)&&!e.url.includes(`.`)&&(e.url=JB())}var XB=e({formatSceneJson:()=>r,httpEditorApi:()=>re,mountEditor:()=>ZB});_n(),Fv(),KM(),UP(),U_();async function ZB(e={}){let t=e.api??re,n=[],r=document.createElement(`style`);r.dataset.incantoEditor=`true`,r.textContent=qz,document.head.appendChild(r),n.push(()=>r.remove());let i=document.createElement(`div`);i.className=`incanto-editor-root`,i.innerHTML=Dz,(e.host??document.body).appendChild(i),n.push(()=>i.remove());let a=e=>{let t=i.querySelector(e);if(!t)throw Error(`missing ${e}`);return t},o=await t.meta();a(`#engine-version`).textContent=`incanto@${o.version}`,PL(a(`#popover`)),UF(),a(`#docs-btn`).addEventListener(`click`,()=>VF());let s=a(`#lang-btn`),c=[{code:`en`,label:`English`},{code:`ko`,label:`한국어`}],l=()=>{a(`#lang-current`).textContent=qP()===`ko`?`한국어`:`EN`};l(),s.addEventListener(`click`,()=>{document.querySelector(`.lang-menu`)?.remove();let e=document.createElement(`div`);e.className=`context-menu floating lang-menu`;for(let{code:t,label:n}of c){let r=document.createElement(`button`);r.type=`button`,r.className=`menu-item`;let i=document.createElement(`span`);i.textContent=n;let a=document.createElement(`span`);a.textContent=qP()===t?`✓`:``,a.className=`lang-check`,r.append(i,a),r.addEventListener(`click`,()=>{e.remove(),JP(t)}),e.appendChild(r)}document.body.appendChild(e);let t=s.getBoundingClientRect();e.style.left=`${t.left}px`,e.style.top=`${t.bottom+6}px`;let n=t=>{e.contains(t.target)||t.target===s||(e.remove(),document.removeEventListener(`pointerdown`,n,!0))};setTimeout(()=>document.addEventListener(`pointerdown`,n,!0),0)}),YP(()=>{l(),WF(),u.select(u.selection)});let u=new Iz({format:1,type:`scene`,name:``,root:null}),d=a(`#tree`),f=a(`#inspector`),p=a(`#save-btn`),m=a(`#undo-btn`),h=a(`#play-btn`),g=a(`#error-banner`),_=a(`#play-notice`),v=a(`#add-type`),y=a(`#picker`),b=a(`#picker-list`),x=a(`#scenes-btn`),S=o.input,C=o.output,w,T=!1,E=a(`#error-text`),D=e=>{g.hidden=!1,E.textContent=e,PF.error(e)},O=()=>{g.hidden=!0,E.textContent=``};a(`#error-close`).addEventListener(`click`,O);let k=a(`#edit-notice`),A=null,ee=e=>{k.hidden=!1,k.textContent=e,A&&clearTimeout(A),A=setTimeout(()=>{k.hidden=!0,k.textContent=``},6e3)},te={on:!1,brush:`0`},ne=e=>{let t=0,n=0,r=u.working.root,i=e=>{let r=e?.props?.position;Array.isArray(r)&&(t+=Number(r[0]??0),n+=Number(r[1]??0))};i(r);for(let t of e)r=r?.children?.[t],i(r);return{x:t,y:n}},j=!1,ie=(e,t,n=!0)=>{n&&(j=!1);let r=u.selection,i=u.nodeAt(r);if(!r||i?.type!==`TileMap2D`)return;let{cx:a,cy:o}=tR(ne(r),Number(i.props?.tileSize??32),e,t),s=i.props?.cells??[],c=nR(s,a,o,te.brush);!c||JSON.stringify(c)===JSON.stringify(s)||(u.mutate(()=>{i.props||={},i.props.cells=c},{path:r,key:`cells`,value:c},{coalesce:j}),j=!0)},ae=()=>{let e=u.nodeAt(u.selection);te.on&&e?.type!==`TileMap2D`&&(te.on=!1),M.setPaintHandler(te.on?ie:null)},M=new MB(a(`#viewport`),a(`#overlay`),a(`#play-canvas`),{onPick:(e,t)=>u.select(e??null,t),onNodeMoved:(e,t)=>me(e,`position`,t,[0,0]),onNodeScaled:(e,t)=>me(e,`scale`,t,[1,1]),onNodeMoved3D:(e,t)=>me(e,`position`,t,[0,0,0]),onNodeScaled3D:(e,t)=>me(e,`scale`,t,[1,1,1]),onNodeRotated2D:(e,t)=>pe(e,`rotation`,t,0),onNodeRotated3D:(e,t)=>me(e,`rotation`,t,[0,0,0]),onModeChanged:e=>{for(let t of[`move`,`rotate`,`scale`])a(`#tool-${t}`).classList.toggle(`active`,t===e)},onPlayStateChanged:e=>{document.body.classList.toggle(`playing`,e),n.push(()=>document.body.classList.remove(`playing`)),h.classList.toggle(`stop`,e),h.innerHTML=e?`<svg width="11" height="11" viewBox="0 0 24 24" fill="currentColor"><rect x="6" y="6" width="12" height="12"/></svg> stop`:`<svg width="11" height="11" viewBox="0 0 24 24" fill="currentColor"><path d="M8 5v14l11-7z"/></svg> play`,_.hidden=!e,e&&(_.textContent=`▶ simulating — physics + input live; game scripts run only in your real game. Esc or stop to return.`)},onError:D}),oe=Ke().sort(),se=``,ce=e=>{if(e===se)return;se=e,v.textContent=``;let t=e===`3d`?[`3D`,`3D Physics`,`Core`,`Network`,`2D`,`2D Physics`]:[`2D`,`2D Physics`,`Core`,`Network`,`3D`,`3D Physics`];for(let[e]of IF)t.includes(e)||t.push(e);for(let e of t){let t=IF.find(([t])=>t===e)?.[1];if(!t)continue;let n=document.createElement(`optgroup`);n.label=e;for(let e of oe.filter(t)){let t=document.createElement(`option`);t.value=e,t.textContent=e,n.appendChild(t)}n.children.length>0&&v.appendChild(n)}v.value=e===`3d`?`MeshInstance3D`:`Sprite2D`};ce(`2d`);let le=()=>{let e=u.selection??[];if(M.validate(u.working)!==null){for(let e of v.querySelectorAll(`option`))e.disabled=!1;return}for(let t of v.querySelectorAll(`option`)){let n=structuredClone(u.working),r=n.root;if(!n.root)n.root={name:`__probe`,type:t.value};else{for(let t of e)r=r?.children?.[t];if(!r)continue;r.children||=[],r.children.push({name:`__probe`,type:t.value})}t.disabled=M.validate(n)!==null}};v.addEventListener(`mousedown`,le),v.addEventListener(`focus`,le);let ue=t.library?e=>uz(t,{kind:e.kind,...e.target?{target:e.target}:{},...e.shelf?{shelf:e.shelf}:{},...e.assetType?{assetType:e.assetType}:{},...e.onProps?{onProps:e.onProps}:{},...e.asAsset?{onAsset:(e,t,n)=>tV(u,n,t)}:{}}):void 0,de=!1,fe=()=>{if(!T)return;oB(d,u),cF(a(`#asset-tree`),u),f.textContent=``,lF(f,u,Se,ue)||oR(f,u,{modelRefs:()=>$B(u,`model`),animationsForSelection:()=>u.selection?M.modelAnimationsAt(u.selection):[],bonesForSelection:e=>u.selection?M.boneNamesAt(u.selection,e):[],assetRefs:e=>eV(u,e),addAsset:(e,t)=>tV(u,e,t),...ue?{openLibrary:ue}:{},confirm:Se,paint:{active:()=>te.on,brush:()=>te.brush,toggle:()=>{te.on=!te.on,ae(),fe()},setBrush:e=>{te.brush=e,fe()}}}),ce(u.working.dimension??`2d`),a(`#hints`).hidden=(u.working.dimension??`2d`)===`3d`,a(`#hints-3d`).hidden=(u.working.dimension??`2d`)!==`3d`,M.setSelection(u.selection,u.extra),ae();let e=u.pendingLivePatch;if(u.pendingLivePatch=null,!M.playing)if(e&&M.patchProp(u.working,e.path,e.key,e.value))g.hidden=!0;else{let e=M.apply(u.working);g.hidden=e===null,e!==null&&D(e)}p.disabled=!u.dirty||!u.working.root,p.title=u.working.root?``:`Add a root node before saving`,m.disabled=!u.canUndo,u.dirty!==de&&(de=u.dirty,PF.change(u.dirty))};u.onChange(fe),u.validator=e=>M.validate(e),u.onError=D;let pe=(e,t,n,r)=>{let i=u.nodeAt(e);i&&u.mutate(()=>{i.props||={},n===r?(delete i.props[t],Object.keys(i.props).length===0&&delete i.props):i.props[t]=n},{path:e,key:t,value:n})},me=(e,t,n,r)=>{let i=u.nodeAt(e);i&&u.mutate(()=>{i.props||={},JSON.stringify(n)===JSON.stringify(r)?(delete i.props[t],Object.keys(i.props).length===0&&delete i.props):i.props[t]=n},{path:e,key:t,value:n})},he=async(e,n,r)=>{M.playing&&M.stop();let i=await t.loadScene(e);w=e,S=n,C=r,T=!0;let s=e??n;a(`#file-chip`).hidden=!s,a(`#file-path`).textContent=s??``,a(`#file-chip`).title=`input: ${n}\noutput: ${r}`,y.hidden=!0,O(),lB(),u.reset(i),o.mode===`project`&&n&&PF.open(n,r)},ge=Ez({list:b,search:a(`#picker-search`),count:a(`#picker-count`),path:a(`#picker-path`)},{entries:async()=>t.scenes?await t.scenes():[],current:()=>w,open:e=>_e(e.rel,e.abs)}),_e=(e,t)=>{let n=()=>{he(e,t,t).catch(e=>D(e instanceof Error?e.message:String(e)))};if(!u.dirty||!u.canUndo){n();return}Se(`'${w??`This scene`}' has unsaved changes. Opening '${e}' discards them.`,`discard & open`,n)},ve=async()=>{y.hidden=!1,await ge.refresh()},ye=()=>{y.hidden=!0};if(a(`#picker-close`).addEventListener(`click`,ye),y.addEventListener(`pointerdown`,e=>{e.target===y&&ye()}),a(`#picker-create`).addEventListener(`click`,()=>{(async()=>{let e=a(`#picker-path`),n=(e.value.trim()||e.placeholder).trim();if(n)try{if(!t.createScene)return;let e=await t.createScene(n.endsWith(`.scene.json`)?n:`${n}.scene.json`);await he(e.rel,e.abs,e.abs)}catch(e){D(e instanceof Error?e.message:String(e))}})()}),o.mode===`project`&&t.scenes&&(x.hidden=!1,x.addEventListener(`click`,()=>void ve())),o.mode===`project`&&o.input===null)await he(void 0,``,``);else if(o.mode===`project`&&t.scenes){let e=await t.scenes(),n=e.length===1?e[0]:void 0;n?await he(n.rel,n.abs,n.abs):await ve()}else await he(void 0,o.input,o.output);a(`#add-btn`).addEventListener(`click`,()=>{let e=u.selection??[],t=v.value,n=u.insertNode({name:t,type:t},e);n&&u.select(n)});let N=a(`#generate`);OL(u),a(`#generate-btn`).addEventListener(`click`,()=>EL(u));let P=a(`#confirm`),F=e=>{if(u.selection===null&&e.length===0){D(`The scene itself cannot be deleted — it IS the file.`);return}if(e.length===0){let e=u.working.root;if(!e)return;let t=QB(e);Se(`This deletes the ROOT '${String(e.name??``)}'${t>0?` AND its ${t} descendant node${t===1?``:`s`}`:``} — the scene goes empty, and the next node you add becomes the new root.`,`delete root`,()=>u.deleteRoot());return}let t=e[0]?.slice(0,-1)??[],n=u.findRemovalReferences(e);if(n.length===0){let n=e.reduce((e,t)=>{let n=u.nodeAt(t);return e+(n?QB(n):0)},0);if(n>0){Se(`This deletes ${e.length>1?`${e.length} nodes`:`'${String(u.nodeAt(e[0]??[])?.name??``)}'`} AND ${n} descendant node${n===1?``:`s`}.`,`delete ${e.length+n} nodes`,()=>{u.removeNodes(e)&&u.select(t)});return}u.removeNodes(e)&&u.select(t);return}a(`#confirm-text`).textContent=`${n.length} reference${n.length>1?`s`:``} still point at the node(s) you are deleting. Unlink them and delete, or cancel.`;let r=a(`#confirm-list`);r.textContent=``;for(let e of n){let t=document.createElement(`div`);t.textContent=`${e.kind===`uid`?`◆ uid`:`⇄ connection`} ${e.where}`,r.appendChild(t)}a(`#confirm-title`).textContent=`still referenced`,a(`#confirm-delete`).textContent=`unlink & delete`,P.hidden=!1,be={selections:e,parentOfFirst:t}},be=null,xe=null;function Se(e,t,n){a(`#confirm-title`).textContent=`are you sure?`,a(`#confirm-text`).textContent=e,a(`#confirm-list`).textContent=``,a(`#confirm-delete`).textContent=t,xe=n,P.hidden=!1}function I(){P.hidden=!0,be=null,xe=null}a(`#confirm-close`).addEventListener(`click`,I),a(`#confirm-cancel`).addEventListener(`click`,I),P.addEventListener(`pointerdown`,e=>{e.target===P&&I()}),a(`#confirm-delete`).addEventListener(`click`,()=>{if(xe){xe(),I();return}be&&u.removeNodesUnlinking(be.selections)&&u.select(be.parentOfFirst),I()}),eB(F),tB(e=>{ee(`${XP({en:`Rename: repaired ${e.length} reference${e.length===1?``:`s`}`,ko:`이름 변경: 참조 ${e.length}건 수정`})} — ${e.map(e=>e.where).join(`, `)}`)}),a(`#asset-add-btn`).addEventListener(`click`,e=>{e.stopPropagation(),u.startAddingAsset()}),a(`#group-add-btn`).addEventListener(`click`,e=>{e.stopPropagation(),u.startAddingGroup()});for(let e of document.querySelectorAll(`.section-toggle`)){let t=e.dataset.section??``,n=document.querySelector(`[data-body="${t}"]`),r=`incanto-editor-section-${t}`,i=t=>{e.classList.toggle(`collapsed`,t),n&&(n.hidden=t),localStorage.setItem(r,t?`1`:``)};i(localStorage.getItem(r)===`1`),e.addEventListener(`click`,()=>i(!e.classList.contains(`collapsed`)))}a(`#delete-btn`).addEventListener(`click`,()=>{F(u.allSelections().filter(e=>e.length>0))});let Ce=()=>{g.hidden=!0,M.play(u.working).then(e=>{e&&D(e)})};if(h.addEventListener(`click`,()=>{if(M.playing){M.stop(),fe();return}if(!e.onPlay){Ce();return}i.querySelector(`.play-menu`)?.remove();let t=document.createElement(`div`);t.className=`context-menu floating play-menu`;let r=[[`preview`,`▶ preview here`,e.playHints?.preview??`simulate in the editor · scripts stripped`],[`debug`,`⤢ run as the game`,e.playHints?.debug??`this page becomes the game, with the debug overlay`]];for(let[n,i,a]of r){let r=document.createElement(`button`);r.type=`button`,r.className=`menu-item play-menu-item`;let o=document.createElement(`span`);o.textContent=i;let s=document.createElement(`span`);s.className=`play-menu-hint`,s.textContent=a,r.append(o,s),r.addEventListener(`click`,()=>{t.remove(),n===`preview`?Ce():e.onPlay?.(n,u.working)}),t.appendChild(r)}i.appendChild(t);let a=h.getBoundingClientRect(),o=t.getBoundingClientRect().width;t.style.left=`${Math.min(Math.max(8,a.right-o),window.innerWidth-o-8)}px`,t.style.top=`${a.bottom+6}px`;let s=e=>{e.type===`keydown`&&e.key!==`Escape`||e.type!==`keydown`&&(t.contains(e.target)||e.target===h)||(t.remove(),document.removeEventListener(`pointerdown`,s,!0),document.removeEventListener(`keydown`,s,!0))};setTimeout(()=>{document.addEventListener(`pointerdown`,s,!0),document.addEventListener(`keydown`,s,!0)},0),n.push(()=>{document.removeEventListener(`pointerdown`,s,!0),document.removeEventListener(`keydown`,s,!0)})}),e.onExit){let t=document.createElement(`button`);t.type=`button`,t.className=`ghost`,t.id=`exit-btn`,t.title=`Back to the game`,t.textContent=`✕ exit`,h.parentElement?.insertBefore(t,h),t.addEventListener(`click`,()=>void e.onExit?.())}for(let e of[`move`,`rotate`,`scale`])a(`#tool-${e}`).addEventListener(`click`,()=>M.setMode(e));M.setMode(`move`);let L=a(`#tool-colliders`),we=`incanto-editor-show-colliders`,Te=e=>{M.showColliders=e,L.classList.toggle(`active`,e),localStorage.setItem(we,e?``:`0`)};Te(localStorage.getItem(we)!==`0`),L.addEventListener(`click`,()=>Te(!M.showColliders));let Ee=a(`#hints-dock`),De=`incanto-editor-hints-open`;Ee.classList.toggle(`open`,localStorage.getItem(De)===`1`),a(`#hints-toggle`).addEventListener(`click`,()=>{let e=Ee.classList.toggle(`open`);localStorage.setItem(De,e?`1`:``)}),a(`#fit-btn`).addEventListener(`click`,()=>M.zoomToFit()),$z(()=>M.zoomToFit()),a(`#gameview-btn`).addEventListener(`click`,()=>M.gameView()),t.saveScene||(p.hidden=!0),p.addEventListener(`click`,()=>{(async()=>{try{await t.saveScene?.(u.working,w),u.markSaved(),PF.save(S,C,u.working)}catch(e){D(e instanceof Error?e.message:String(e))}})()}),m.addEventListener(`click`,()=>u.undo());let Oe=e=>{if(e.key===`Escape`&&M.cancelActiveDrag(),e.key===`Escape`&&!g.hidden&&a(`#docs`).hidden&&P.hidden&&N.hidden&&y.hidden&&!M.playing){O();return}if(e.key===`Escape`&&!a(`#docs`).hidden){HF();return}if(e.key===`Escape`&&!P.hidden){I();return}if(e.key===`Escape`&&!N.hidden){DL();return}if(e.key===`Escape`&&!y.hidden){ye();return}if(e.key===`Escape`&&M.playing){M.stop(),fe();return}if(M.playing)return;let t=e.target.matches(`input, textarea, select`);(e.metaKey||e.ctrlKey)&&e.key===`z`?(e.preventDefault(),u.undo()):(e.metaKey||e.ctrlKey)&&e.key===`s`?(e.preventDefault(),p.disabled||p.click()):!t&&e.code===`KeyF`?M.zoomToFit():!t&&(e.code===`Digit0`||e.code===`Numpad0`)?M.gameView():!t&&e.code===`KeyW`?M.setMode(`move`):!t&&e.code===`KeyE`?M.setMode(`rotate`):!t&&e.code===`KeyR`&&M.setMode(`scale`)};return window.addEventListener(`keydown`,Oe),n.push(()=>window.removeEventListener(`keydown`,Oe)),fe(),e.camera&&M.setEditCamera(e.camera.position,e.camera.target),PF.ready(S,C,o.version),{working:()=>u.working,camera:()=>M.editCamera(),showError:D,dispose(){M.dispose();for(let e of document.querySelectorAll(`.context-menu, .balloon`))e.remove();for(let e of n.splice(0).reverse())e()}}}function QB(e){let t=0;for(let n of e.children??[])t+=1+QB(n);return t}function $B(e,t){let n=e.working.assets;return n?Object.entries(n).filter(([,e])=>e?.type===t).map(([e])=>`$${e}`):[]}function eV(e,t){let n=e.working.assets;return n?Object.entries(n).filter(([,e])=>!t||e?.type!==void 0&&t.includes(e.type)).map(([e])=>`$${e}`):[]}function tV(e,t,n){let r=e.working.assets??{};for(let[e,t]of Object.entries(r))if(t?.url===n.url)return`$${e}`;let i=t;for(let e=2;i in r;e++)i=`${t}-${e}`;return e.mutate(()=>{e.working.assets||(e.working.assets={}),e.working.assets[i]=n}),`$${i}`}var nV=null,rV=null;function iV(){return rV||(rV=document.createElement(`canvas`),rV.style.cssText=`position:fixed; inset:0; width:100%; height:100%; display:block;`,document.body.appendChild(rV)),rV.style.visibility=``,rV}async function aV(e,t){return nV=await ZB({api:re,...e?{camera:e}:{},onPlay:(e,t)=>{e===`debug`&&oV(t)},playHints:{debug:`this page becomes the game — needs a scene with no project behaviors`},...t?{onExit:()=>(nV?.dispose(),nV=null,iV(),t())}:{}}),nV}async function oV(e){let t=e.dimension??`2d`;nV?.dispose(),nV=null;let n=async e=>{rV&&(rV.style.visibility=`hidden`),await aV(e.camera,e.exit)};try{if(t===`3d`){let{createGame3D:t}=await bm(async()=>{let{createGame3D:e}=await Promise.resolve().then(()=>NP);return{createGame3D:e}},void 0,import.meta.url);await t({canvas:iV(),scene:e,debug:!0,editor:{open:n}})}else{let{createGame2D:t}=await bm(async()=>{let{createGame2D:e}=await Promise.resolve().then(()=>ay);return{createGame2D:e}},void 0,import.meta.url);await t({canvas:iV(),scene:e,debug:!0,editor:{open:n}})}}catch(e){rV&&(rV.style.visibility=`hidden`),(await aV()).showError(`${e instanceof Error?e.message:String(e)}\n\nRunning as the game needs your project's behaviors, which live in your app, not in this page. Start your own dev server with debug enabled and use the ☰ debug menu's "✎ edit this scene" — the switch works both ways from there, with every behavior loaded.`)}}aV().catch(e=>{let t=document.createElement(`div`);t.id=`error-banner`,t.style.cssText=`position:fixed;inset:0 0 auto 0;z-index:99;padding:10px 14px;background:#5b1a24;color:#ffd9df;font:13px ui-monospace,monospace`,t.textContent=e instanceof Error?e.message:String(e),document.body.appendChild(t)});export{He as i,bm as n,Xe as r,$_ as t};
|
|
10858
|
+
`,Xz=new Map(BF.flatMap(e=>e.nodes.map(e=>[e.type,e.summary]))),Zz=new Set,Qz=null,$z=null,eB=null;function tB(e){$z=e}function nB(e){Qz=e}function rB(e){eB=e}var iB=null,aB=null,oB=null;function sB(e){return e?e.includes(`Body`)||e.includes(`Area`)||e.includes(`Controller`)?`cat-body`:e===`NetworkSpawner`?`cat-net`:e.endsWith(`3D`)?`cat-3d`:e.endsWith(`2D`)||e===`Label`||e===`UILayer`?`cat-2d`:`cat-core`:`cat-core`}function cB(e,t){e.textContent=``;let n=document.createElement(`div`);n.className=`tree-row scene-row${t.selection===null&&t.selectedAsset===null&&t.selectedGroup===null&&!t.addingAsset&&!t.addingGroup?` selected`:``}`,n.textContent=`⚙ ${String(t.working.name??`scene`)}`,n.addEventListener(`click`,()=>t.select(null)),e.appendChild(n);let r=t.working.root;if(!r){let t=document.createElement(`div`);t.className=`muted-note explorer-empty`,t.textContent=`no root node — pick a type below and + to start the scene`,e.appendChild(t);return}fB(r,t.selection),e.appendChild(pB(r,[],t,``)),uB(e,t.selection)}var lB=null;function uB(e,t){let n=JSON.stringify(t);n!==lB&&(lB=n,e.querySelector(`.tree-row.selected`)?.scrollIntoView?.({block:`nearest`,inline:`nearest`}))}function dB(){lB=null}function fB(e,t){if(!t)return;let n=e,r=``;for(let e of t){r=r?`${r}/${n.name}`:String(n.name),Zz.delete(r);let t=n.children?.[e];if(!t)return;n=t}}function pB(e,t,n,r){let i=r?`${r}/${e.name}`:String(e.name),a=(e.children?.length??0)>0,o=Zz.has(i),s=document.createElement(`div`);s.className=`tree-branch`;let c=document.createElement(`div`);c.className=`tree-row${n.isSelected(t)?` selected`:``}`,c.draggable=t.length>0&&oB!==i;let l=document.createElement(`span`);l.className=`chevron${a?``:` leaf`}${o?` collapsed`:``}`,a?l.appendChild(nF()):l.textContent=`·`,a&&l.addEventListener(`click`,e=>{e.stopPropagation(),o?Zz.delete(i):Zz.add(i),n.select(n.selection)});let u=document.createElement(`span`);if(u.className=`tree-icon ${sB(e.type)}`,u.appendChild(tF(e.type)),u.title=e.type??`instance`,u.addEventListener(`click`,t=>{t.stopPropagation(),mB(u,e.type??`instance`)}),c.append(l,u),oB===i){let r=document.createElement(`input`);r.className=`rename-input`,r.value=e.name??``;let i=()=>{oB=null;let i=r.value.trim();if(i&&i!==e.name){let e=n.renameNode(t,i)??[];e.length>0&&eB?.(e)}else n.select(n.selection)};r.addEventListener(`keydown`,e=>{e.stopPropagation(),e.key===`Enter`&&i(),e.key===`Escape`&&(oB=null,n.select(n.selection))});for(let e of[`click`,`pointerdown`,`dblclick`,`mousedown`])r.addEventListener(e,e=>e.stopPropagation());r.addEventListener(`blur`,i),c.appendChild(r),queueMicrotask(()=>{r.focus(),r.select()})}else{let r=document.createElement(`span`);r.className=`tree-name`,r.textContent=e.name??`(unnamed)`,r.addEventListener(`dblclick`,e=>{e.stopPropagation(),oB=i,n.select(t)}),c.appendChild(r)}if(c.addEventListener(`click`,e=>{a&&!e.metaKey&&!e.ctrlKey&&(o?Zz.delete(i):Zz.add(i)),n.select(t,{toggle:e.metaKey||e.ctrlKey})}),c.addEventListener(`contextmenu`,e=>{e.preventDefault(),n.isSelected(t)||n.select(t),hB(e.clientX,e.clientY,n,t,i)}),wB(c,t,n),s.appendChild(c),a&&!o){let r=document.createElement(`div`);r.className=`tree-children`,(e.children??[]).forEach((e,a)=>{r.appendChild(pB(e,[...t,a],n,i))}),s.appendChild(r)}return s}function mB(e,t){bB();let n=document.createElement(`div`);n.className=`balloon floating`;let r=document.createElement(`span`);r.className=`balloon-title`,r.textContent=t,n.appendChild(r);let i=Xz.get(t);if(i){let e=document.createElement(`span`);e.textContent=QP(i),n.appendChild(e)}document.body.appendChild(n);let a=e.getBoundingClientRect();n.style.left=`${Math.min(innerWidth-240,a.right+8)}px`,n.style.top=`${Math.max(8,a.top-6)}px`,xB(n)}function hB(e,t,n,r,i){bB();let a=n.allSelections(),o=a.length===1&&r.length>0,s=document.createElement(`div`);s.className=`context-menu floating`;let c=(e,t,n)=>{let r=document.createElement(`button`);r.type=`button`,r.className=`menu-item${n?.danger?` danger`:``}`,r.disabled=t===null;let i=document.createElement(`span`);if(i.textContent=e,r.appendChild(i),n?.kbd){let e=document.createElement(`kbd`);e.textContent=n.kbd,r.appendChild(e)}t&&r.addEventListener(`click`,()=>{bB(),t()}),s.appendChild(r)};c(`duplicate${a.length>1?` ×${a.length}`:``}`,()=>{for(let e of[...a].reverse())n.duplicateNode(e)}),c(`frame in view`,$z&&r.length>0?()=>{n.select(r),$z?.()}:null,{kbd:`F`}),c(`rename`,o?()=>{oB=i,n.select(r)}:null,{kbd:`dbl-click`}),s.appendChild(gB()),c(`cut`,r.length>0?()=>_B(n,!0):null),c(`copy`,r.length>0?()=>_B(n,!1):null),c(`paste as child${aB?` (${aB.nodes.length})`:``}`,aB?()=>vB(n,r):null),s.appendChild(gB()),c(`delete`,r.length>0?()=>(Qz??(e=>n.removeNodes(e)))(a):null,{danger:!0}),document.body.appendChild(s),s.style.left=`${Math.min(innerWidth-200-8,e)}px`,s.style.top=`${Math.min(innerHeight-s.offsetHeight-8,t)}px`,xB(s)}function gB(){let e=document.createElement(`div`);return e.className=`menu-divider`,e}function _B(e,t){let n=e.allSelections().filter(e=>e.length>0).map(t=>e.nodeAt(t)).filter(e=>e!==null);aB={nodes:n.map(e=>JSON.parse(JSON.stringify(e))),cut:t?n:null}}function vB(e,t){if(aB){for(let n of aB.nodes)e.insertNode(n,t);if(aB.cut){let t=e.working.root,n=aB.cut.map(e=>yB(t,e)).filter(e=>e!==null);n.length>0&&e.removeNodes(n),aB={nodes:aB.nodes,cut:null}}}}function yB(e,t){if(e===t)return[];for(let[n,r]of(e.children??[]).entries()){let e=yB(r,t);if(e)return[n,...e]}return null}function bB(){for(let e of document.querySelectorAll(`.floating`))e.remove()}function xB(e){let t=r=>{e.contains(r.target)||(e.remove(),document.removeEventListener(`pointerdown`,t,!0),document.removeEventListener(`keydown`,n,!0))},n=r=>{r.key===`Escape`&&(e.remove(),document.removeEventListener(`pointerdown`,t,!0),document.removeEventListener(`keydown`,n,!0))};setTimeout(()=>{document.addEventListener(`pointerdown`,t,!0),document.addEventListener(`keydown`,n,!0)},0)}function SB(e,t){let n=t.getBoundingClientRect(),r=(e.clientY-n.top)/n.height;return r<.25?`before`:r>.75?`after`:`into`}function CB(e){e.classList.remove(`drop-into`,`drop-before`,`drop-after`)}function wB(e,t,n){e.addEventListener(`dragstart`,r=>{iB=n.isSelected(t)?n.allSelections():[t],r.dataTransfer?.setData(`text/plain`,``),r.dataTransfer&&(r.dataTransfer.effectAllowed=`move`),e.classList.add(`dragging`)}),e.addEventListener(`dragend`,()=>{iB=null,e.classList.remove(`dragging`)}),e.addEventListener(`dragover`,n=>{if(!iB||iB.some(e=>e.length<=t.length&&e.every((e,n)=>e===t[n])))return;n.preventDefault(),n.dataTransfer&&(n.dataTransfer.dropEffect=`move`),CB(e);let r=t.length===0?`into`:SB(n,e);e.classList.add(`drop-${r}`)}),e.addEventListener(`dragleave`,()=>CB(e)),e.addEventListener(`drop`,r=>{if(CB(e),!iB)return;r.preventDefault();let i=t.length===0?`into`:SB(r,e),a=n.moveNodes(iB,t,i);iB=null,a?.[0]&&n.select(a[0])})}var TB={x:`#fb7185`,y:`#86efac`,z:`#7aa2ff`};function EB(e,t,n){let r=t-e.origin.x,i=n-e.origin.y;if(Math.abs(r)<=e.centerSize&&Math.abs(i)<=e.centerSize)return{kind:`center`};for(let t of e.axes){let e=t.sx*t.sx+t.sy*t.sy;if(e<1)continue;let n=Math.max(0,Math.min(1,(r*t.sx+i*t.sy)/e)),a=r-t.sx*n,o=i-t.sy*n;if(n>.25&&Math.hypot(a,o)<=8)return{kind:`axis`,axis:t.axis}}return null}function DB(e,t,n){let r=e.sx*e.sx+e.sy*e.sy;return r<1?0:(t*e.sx+n*e.sy)/r*e.worldPerUnit}function OB(e,t,n,r=!1){let{origin:i,axes:a,centerSize:o}=t;for(let t of a){let a=n?.kind===`axis`&&n.axis===t.axis;e.strokeStyle=t.color,e.fillStyle=t.color,e.globalAlpha=a?1:.9,e.lineWidth=a?3:2,e.beginPath(),e.moveTo(i.x,i.y),e.lineTo(i.x+t.sx,i.y+t.sy),e.stroke();let o=Math.hypot(t.sx,t.sy)||1,s=t.sx/o,c=t.sy/o,l=i.x+t.sx,u=i.y+t.sy;e.beginPath(),r?e.rect(l-5,u-5,10,10):(e.moveTo(l+s*9,u+c*9),e.lineTo(l-c*4.5,u+s*4.5),e.lineTo(l+c*4.5,u-s*4.5),e.closePath()),e.fill(),e.font=`700 9px Inter, system-ui, sans-serif`,e.textAlign=`center`,e.textBaseline=`middle`,e.fillText(t.axis.toUpperCase(),l+s*18,u+c*18)}let s=n?.kind===`center`;e.globalAlpha=s?1:.95,e.fillStyle=s?`#ffffff`:`#e2e6f0`,e.strokeStyle=`#0b0d14`,e.lineWidth=1.5,e.beginPath(),e.rect(i.x-o,i.y-o,o*2,o*2),e.fill(),e.stroke(),e.globalAlpha=1}function kB(e,t,n){return Math.atan2(n-e.y,t-e.x)*180/Math.PI}function AB(e,t){let n=t-e;for(;n>180;)n-=360;for(;n<=-180;)n+=360;return n}function jB(e,t,n,r){let i=null,a=r;for(let r of e)for(let e of r.points){let o=Math.hypot(t-e.x,n-e.y);o<a&&(a=o,i=r.axis)}return i}function MB(e,t,n){for(let r of t){if(r.points.length<2)continue;let t=n===r.axis;e.strokeStyle=TB[r.axis],e.globalAlpha=t?1:.75,e.lineWidth=t?3:2,e.beginPath();let i=r.points[0];e.moveTo(i.x,i.y);for(let t of r.points.slice(1))e.lineTo(t.x,t.y);e.closePath(),e.stroke()}e.globalAlpha=1}function NB(e,t,n,r){e.font=`600 11px ui-monospace, Menlo, monospace`;let i=e.measureText(r).width+14;e.fillStyle=`rgba(16, 19, 29, 0.92)`,e.strokeStyle=`rgba(110, 231, 220, 0.5)`,e.lineWidth=1,e.beginPath(),e.roundRect(t+14,n-26,i,20,5),e.fill(),e.stroke(),e.fillStyle=`#6ee7dc`,e.textAlign=`left`,e.textBaseline=`middle`,e.fillText(r,t+21,n-16)}var PB=class{engine;editCanvas;overlay;playCanvas;cb;editUiHost=null;playUiHost=null;renderer2d=null;renderer3d=null;rendererDim=null;orbit={yaw:.6,pitch:.35,dist:10,target:[0,1,0]};pathOf=new Map;reindexNeeded=!1;nodeAtPath=new Map;selectedPath=null;paintHandler=null;extraPaths=[];hoveredNode=null;hoveredGizmo=null;lastGood=null;lastAppliedKey=null;playEngine=null;playRenderer=null;playPhysics=null;setPaintHandler(e){this.paintHandler=e}get playing(){return this.playEngine!==null}constructor(e,t,n,r){this.editCanvas=e,this.overlay=t,this.playCanvas=n,this.cb=r;let i=this;this.engine=new kt({scheduler:e=>{let t=0,n=performance.now(),r=requestAnimationFrame(function a(o){t+=.001;let s=Math.min(.1,(o-n)/1e3);n=o;try{e(t),i.tickAmbientPreviews(s)}catch(e){console.error(`incanto-editor viewport:`,e)}r=requestAnimationFrame(a)});return()=>cancelAnimationFrame(r)}}),this.editUiHost=this.makeUiHost(e.parentElement,4),this.playUiHost=this.makeUiHost(n.parentElement,5),this.engine.uiHost=this.editUiHost,this.engine.start(),this.engine.updated.connect(()=>this.drawOverlay());let a=e=>{e.key===`Shift`&&(this.shiftHeld=!0)},o=e=>{e.key===`Shift`&&(this.shiftHeld=!1)};window.addEventListener(`keydown`,a),window.addEventListener(`keyup`,o),this.cleanups.push(()=>{window.removeEventListener(`keydown`,a),window.removeEventListener(`keyup`,o)}),this.bindPointer()}cleanups=[];makeUiHost(e,t){if(!e)return null;let n=document.createElement(`div`);return n.style.cssText=`position:absolute;inset:0;pointer-events:none;z-index:${t};`,e.appendChild(n),this.cleanups.push(()=>n.remove()),n}dispose(){this.stop(),this.editPhysics?.dispose(),this.editPhysics=null,this.engine.stop(),this.engine.dispose(),this.renderer2d?.dispose(),this.renderer3d?.dispose(),this.renderer2d=null,this.renderer3d=null;for(let e of this.cleanups.splice(0))e()}setEditCamera(e,t){let n=(e[0]??0)-(t[0]??0),r=(e[1]??0)-(t[1]??0),i=(e[2]??0)-(t[2]??0),a=Math.hypot(n,r,i);a>.01&&(this.orbit.target=[t[0]??0,t[1]??0,t[2]??0],this.orbit.dist=Math.min(800,Math.max(.3,a)),this.orbit.yaw=Math.atan2(n,i),this.orbit.pitch=Math.asin(Math.max(-.99,Math.min(.99,r/a))),this.syncOrbit())}editCamera(){let{pos:e}=this.orbitVectors();return{position:[e.x,e.y,e.z],target:[...this.orbit.target]}}apply(e){e.root||(e={...e,root:{name:`__empty`,type:(e.dimension??`2d`)===`3d`?`Node3D`:`Node2D`}});let t=JSON.stringify(e);if(t===this.lastAppliedKey&&this.rendererDim===(e.dimension??`2d`))return null;let n;try{let t=structuredClone(e);ZB(t),n=An(t,{stubAllBehaviors:!0})}catch(e){return e instanceof Error?e.message:String(e)}this.lastGood=e,this.lastAppliedKey=t;let r=e.dimension??`2d`;if(this.rendererDim!==r){if(this.renderer2d?.dispose(),this.renderer3d?.dispose(),this.renderer2d=null,this.renderer3d=null,r===`2d`)this.renderer2d=new Yv({canvas:this.editCanvas,engine:this.engine}),this.renderer2d.ignoreStatic=!0,this.renderer2d.viewOverride=this.defaultView(e);else{this.renderer3d=new yP({canvas:this.editCanvas,engine:this.engine}),this.renderer3d.ignoreStatic=!0;let t=qB(e.root);if(t){let[e,n,r]=t;this.orbit.dist=Math.max(2,Math.hypot(e,n,r)),this.orbit.yaw=Math.atan2(e,r),this.orbit.pitch=Math.asin(Math.max(-.99,Math.min(.99,n/this.orbit.dist))),this.orbit.target=[0,Math.min(2,Math.abs(n)/2),0]}this.syncOrbit()}this.rendererDim=r}return this.engine.setScene(n),this.indexTree(n.root),this.hoveredNode=null,null}setSelection(e,t=[]){this.selectedPath=e,this.extraPaths=t}validate(e){if(!e.root)return null;try{let t=structuredClone(e);return ZB(t),An(t,{stubAllBehaviors:!0}),null}catch(e){return e instanceof Error?e.message:String(e)}}defaultView(e){let t=JB(e.root);if(t)return{cx:t[0],cy:t[1],zoom:1};let n=this.editCanvas.clientWidth||960,r=this.editCanvas.clientHeight||540;return{cx:n/2,cy:r/2,zoom:1}}indexTree(e){this.pathOf=new Map,this.nodeAtPath=new Map;let t=(e,n)=>{this.pathOf.set(e,n),this.nodeAtPath.set(n.join(`.`),e),e.children.forEach((e,r)=>{t(e,[...n,r])})};t(e,[])}liveSelected(){return this.selectedPath===null?null:this.nodeAtPath.get(this.selectedPath.join(`.`))??null}patchProp(e,t,n,r){if(this.playing)return!1;let i=this.nodeAtPath.get(t.join(`.`));if(!i)return!1;try{i[n]=r===void 0?void 0:structuredClone(r)}catch{return!1}return this.reindexNeeded=!0,this.lastAppliedKey=JSON.stringify(e),!0}gizmoActive=null;gizmoMode=`move`;activeRing=null;readout=null;cancelActiveDrag=()=>{};shiftHeld=!1;get showColliders(){return this.collidersOn}set showColliders(e){this.collidersOn=e,this.editPhysics&&(this.editPhysics.debugDraw=e),e&&this.ensureOutlinePhysics()}collidersOn=!0;editPhysics=null;outlinePending=null;async ensureOutlinePhysics(){if(this.editPhysics||this.outlinePending)return this.outlinePending??void 0;let e=this.rendererDim;if(e)return this.outlinePending=(async()=>{try{if(e===`2d`){let{enablePhysics2D:e}=await bm(async()=>{let{enablePhysics2D:e}=await Promise.resolve().then(()=>sy);return{enablePhysics2D:e}},void 0,import.meta.url),t=await e(this.engine,{simulate:!1});t.debugDraw=this.collidersOn,this.editPhysics=t}else{let{enablePhysics3D:e}=await bm(async()=>{let{enablePhysics3D:e}=await Promise.resolve().then(()=>FP);return{enablePhysics3D:e}},void 0,import.meta.url),t=await e(this.engine,{simulate:!1});t.debugDraw=this.collidersOn,this.editPhysics=t}}catch(e){console.warn(`[incanto] collider outlines unavailable:`,e)}finally{this.outlinePending=null}})(),this.outlinePending}get mode(){return this.gizmoMode}setMode(e){this.gizmoMode=e,this.cb.onModeChanged(e)}gizmoLayout(){let e=this.liveSelected();if(!e)return null;if(this.rendererDim===`2d`&&this.renderer2d){let t=e.position;if(!Array.isArray(t))return null;let n=KB(e),r=this.renderer2d.screenFromWorld(n.x,n.y),i=this.renderer2d.view().zoom;return{origin:r,centerSize:7,axes:[{axis:`x`,sx:64,sy:0,worldPerUnit:64/i,color:TB.x},{axis:`y`,sx:0,sy:64,worldPerUnit:64/i,color:TB.y}]}}if(this.rendererDim===`3d`&&this.renderer3d){let t=e._object3D,n=e.position;if(!t||!Array.isArray(n))return null;t.getWorldPosition(BB);let r=this.renderer3d.screenFromWorld(BB.x,BB.y,BB.z);if(r.behind)return null;let i=[],a=this.orbit.dist,o=Math.max(.2,a*.18);for(let[e,t]of[[`x`,[1,0,0]],[`y`,[0,1,0]],[`z`,[0,0,1]]]){let n=this.renderer3d.screenFromWorld(BB.x+t[0]*o,BB.y+t[1]*o,BB.z+t[2]*o);n.behind||i.push({axis:e,sx:n.x-r.x,sy:n.y-r.y,worldPerUnit:o,color:TB[e]})}return{origin:{x:r.x,y:r.y},centerSize:7,axes:i}}return null}ringLayout(){let e=this.liveSelected();if(!e)return null;if(this.rendererDim===`2d`&&this.renderer2d){let t=KB(e),n=this.renderer2d.screenFromWorld(t.x,t.y),r=[];for(let e=0;e<48;e++){let t=e/48*Math.PI*2;r.push({x:n.x+56*Math.cos(t),y:n.y+56*Math.sin(t)})}return{origin:n,rings:[{axis:`z`,points:r}]}}if(this.rendererDim===`3d`&&this.renderer3d){let t=e._object3D;if(!t)return null;t.getWorldPosition(BB);let n={x:BB.x,y:BB.y,z:BB.z},r=this.renderer3d.screenFromWorld(n.x,n.y,n.z);if(r.behind)return null;let i=Math.max(.2,this.orbit.dist*.16),a=[];for(let e of[`x`,`y`,`z`]){let t=[];for(let r=0;r<48;r++){let a=r/48*Math.PI*2,o=Math.cos(a)*i,s=Math.sin(a)*i,c=e===`x`?this.renderer3d.screenFromWorld(n.x,n.y+o,n.z+s):e===`y`?this.renderer3d.screenFromWorld(n.x+o,n.y,n.z+s):this.renderer3d.screenFromWorld(n.x+o,n.y+s,n.z);c.behind||t.push({x:c.x,y:c.y})}a.push({axis:e,points:t})}return{origin:{x:r.x,y:r.y},rings:a}}return null}orbitVectors(){let{yaw:e,pitch:t,dist:n,target:r}=this.orbit,i=Math.cos(t),a=new U(r[0]+n*i*Math.sin(e),r[1]+n*Math.sin(t),r[2]+n*i*Math.cos(e)),o=new U(r[0],r[1],r[2]).sub(a).normalize(),s=new U().crossVectors(o,IB).normalize();return{pos:a,right:s,up:new U().crossVectors(s,o).normalize(),forward:o}}syncOrbit(){if(!this.renderer3d)return;let{pos:e}=this.orbitVectors();this.renderer3d.viewOverride={position:[e.x,e.y,e.z],target:[...this.orbit.target]}}gameView(){if(this.rendererDim===`3d`&&this.renderer3d){let e=null;for(let[t]of this.pathOf)if(t instanceof UE&&(t.current||!e)&&(e=t,t.current))break;let t=e?e._ensureObject3D():null;if(t){t.getWorldPosition(LB),RB.set(0,0,-1).applyQuaternion(t.getWorldQuaternion(zB));let e=Math.min(40,Math.max(3,this.orbit.dist));this.orbit.target=[LB.x+RB.x*e,LB.y+RB.y*e,LB.z+RB.z*e],this.orbit.dist=e,this.orbit.yaw=Math.atan2(-RB.x,-RB.z),this.orbit.pitch=Math.asin(Math.max(-.99,Math.min(.99,-RB.y)))}this.renderer3d.viewOverride=null;return}this.renderer2d&&(this.renderer2d.viewOverride=null)}snapView(e,t){e===`y`?(this.orbit.pitch=t*1.45,this.orbit.yaw=0):(this.orbit.pitch=0,this.orbit.yaw=e===`z`?t===1?0:Math.PI:Math.PI/2*t),this.syncOrbit()}gizmoCenter(){return{x:this.overlay.clientWidth-58,y:58,r:36}}gizmoHandles(){let{right:e,up:t,forward:n}=this.orbitVectors(),r=this.gizmoCenter(),i=[];for(let[a,o]of[[`x`,new U(1,0,0)],[`y`,new U(0,1,0)],[`z`,new U(0,0,1)]])for(let s of[1,-1]){let c=o.clone().multiplyScalar(s);i.push({axis:a,sign:s,x:r.x+c.dot(e)*26,y:r.y-c.dot(t)*26,z:-c.dot(n)})}return i.sort((e,t)=>e.z-t.z)}gizmoHit(e,t){let n=this.gizmoCenter();if(Math.hypot(e-n.x,t-n.y)>n.r+8)return null;let r=null,i=14;for(let n of this.gizmoHandles()){let a=Math.hypot(e-n.x,t-n.y);a<i&&(i=a,r={axis:n.axis,sign:n.sign})}return r??{axis:`z`,sign:1}}gizmoHandleAt(e,t){let n=this.gizmoCenter();if(Math.hypot(e-n.x,t-n.y)>n.r+8)return null;let r=null,i=12;for(let n of this.gizmoHandles()){let a=Math.hypot(e-n.x,t-n.y);a<i&&(i=a,r={axis:n.axis,sign:n.sign})}return r}tickAmbientPreviews(e){if(!this.playing)for(let[t]of this.pathOf)(t instanceof Zk||t instanceof Dv||t instanceof eA||t instanceof _g||t instanceof Sk)&&t.update(e)}modelAnimationsAt(e){let t=this.nodeAtPath.get(e.join(`.`));return t instanceof Zk?t.availableAnimations():[]}boneNamesAt(e,t){let n=this.nodeAtPath.get(e.join(`.`));if(!n||t===``)return[];let r=n.getNodeOrNull(t);return r instanceof Zk?r.boneNames():[]}drawOverlay(){if(this.reindexNeeded){this.reindexNeeded=!1;let e=this.engine.scene?.tree.root;e&&this.indexTree(e)}let e=this.overlay.getContext(`2d`);if(!e)return;let t=this.overlay.clientWidth,n=this.overlay.clientHeight,r=Math.min(devicePixelRatio||1,2);if((this.overlay.width!==t*r||this.overlay.height!==n*r)&&(this.overlay.width=t*r,this.overlay.height=n*r),e.setTransform(r,0,0,r,0,0),e.clearRect(0,0,t,n),this.playing)return;if(this.rendererDim===`3d`){this.drawGizmo(e),this.drawModeGizmo(e),this.readout&&NB(e,this.readout.x,this.readout.y,this.readout.text);return}if(!this.renderer2d)return;if(this.drawAxes2D(e),this.hoveredNode&&this.hoveredNode!==this.liveSelected()){let t=this.renderer2d.boundsOf(this.hoveredNode);t&&(e.strokeStyle=`rgba(110, 231, 220, 0.45)`,e.lineWidth=1.5,e.setLineDash([]),e.strokeRect(t.x,t.y,t.w,t.h))}for(let t of this.extraPaths){let n=this.nodeAtPath.get(t.join(`.`)),r=n?this.renderer2d.boundsOf(n):null;r&&(e.strokeStyle=`rgba(110, 231, 220, 0.7)`,e.lineWidth=1.5,e.setLineDash([4,3]),e.strokeRect(r.x-2,r.y-2,r.w+4,r.h+4),e.setLineDash([]))}let i=this.liveSelected();if(i){let t=this.renderer2d.boundsOf(i)??this.pointBounds(i);if(t){e.strokeStyle=`#6ee7dc`,e.lineWidth=2,e.setLineDash([6,4]),e.lineDashOffset=-(performance.now()/50%10),e.strokeRect(t.x-2,t.y-2,t.w+4,t.h+4),e.setLineDash([]),e.fillStyle=`#6ee7dc`;for(let[n,r]of[[t.x-2,t.y-2],[t.x+t.w+2,t.y-2],[t.x-2,t.y+t.h+2],[t.x+t.w+2,t.y+t.h+2]])e.fillRect(n-3,r-3,6,6)}}this.drawModeGizmo(e),this.readout&&NB(e,this.readout.x,this.readout.y,this.readout.text)}drawModeGizmo(e){if(this.gizmoMode===`rotate`){let t=this.ringLayout();t&&MB(e,t.rings,this.activeRing);return}let t=this.gizmoLayout();t&&OB(e,t,this.gizmoActive,this.gizmoMode===`scale`)}pointBounds(e){if(!this.renderer2d)return null;let t=e.position;if(!Array.isArray(t))return null;let n=KB(e),r=this.renderer2d.screenFromWorld(n.x,n.y);return{x:r.x-12,y:r.y-12,w:24,h:24}}drawGizmo(e){let t=this.gizmoCenter();e.beginPath(),e.arc(t.x,t.y,t.r,0,Math.PI*2),e.fillStyle=`rgba(16, 19, 29, 0.72)`,e.fill(),e.strokeStyle=`rgba(52, 60, 84, 0.9)`,e.lineWidth=1,e.stroke();let n={x:`#fb7185`,y:`#86efac`,z:`#7aa2ff`},r={x1:`right`,"x-1":`left`,y1:`top`,"y-1":`bottom`,z1:`front`,"z-1":`back`};for(let r of this.gizmoHandles()){let i=this.hoveredGizmo?.axis===r.axis&&this.hoveredGizmo?.sign===r.sign,a=n[r.axis],o=(r.z+1)/2;e.globalAlpha=i?1:.45+o*.55,e.strokeStyle=a,e.lineWidth=1.5,e.beginPath(),e.moveTo(t.x,t.y),e.lineTo(r.x,r.y),e.stroke(),e.beginPath(),e.arc(r.x,r.y,(r.sign===1?7:5)+(i?2:0),0,Math.PI*2),r.sign===1?(e.fillStyle=a,e.fill(),e.fillStyle=`#0b0d14`,e.font=`700 8px ui-monospace, monospace`,e.textAlign=`center`,e.textBaseline=`middle`,e.fillText(r.axis.toUpperCase(),r.x,r.y+.5)):(e.fillStyle=`rgba(16, 19, 29, 0.9)`,e.fill(),e.stroke())}if(e.globalAlpha=1,this.hoveredGizmo){let n=r[`${this.hoveredGizmo.axis}${this.hoveredGizmo.sign}`];e.fillStyle=`#9aa3bd`,e.font=`600 10px Inter, system-ui, sans-serif`,e.textAlign=`center`,e.textBaseline=`bottom`,e.fillText(`${n} view`,t.x,t.y-t.r-6)}}drawAxes2D(e){let t=this.gizmoCenter();e.save(),e.shadowColor=`rgba(0, 0, 0, 0.25)`,e.shadowBlur=10,e.shadowOffsetY=2,e.beginPath(),e.arc(t.x,t.y,31,0,Math.PI*2),e.fillStyle=`rgba(13, 16, 24, 0.42)`,e.fill(),e.shadowColor=`transparent`,e.strokeStyle=`rgba(255, 255, 255, 0.16)`,e.lineWidth=1,e.stroke();let n=t.x-9,r=t.y-9;e.lineCap=`round`;let i=(t,i,a,o)=>{let s=n+t*21,c=r+i*21,l=e.createLinearGradient(n,r,s,c);l.addColorStop(0,`${a}55`),l.addColorStop(1,a),e.strokeStyle=l,e.lineWidth=2,e.beginPath(),e.moveTo(n,r),e.lineTo(s,c),e.stroke(),e.beginPath(),e.arc(s,c,6.5,0,Math.PI*2),e.fillStyle=a,e.fill(),e.font=`800 8px Inter, system-ui, sans-serif`,e.textAlign=`center`,e.textBaseline=`middle`,e.fillStyle=`#0b0d14`,e.fillText(o,s,c+.5)};i(1,0,`#fb7185`,`X`),i(0,1,`#86efac`,`Y`),e.beginPath(),e.arc(n,r,2.5,0,Math.PI*2),e.fillStyle=`#e2e6f0`,e.fill(),e.restore()}bindPointer(){let e=this.overlay,t=null,n=null,r=!1,i=null,a=null,o=null,s=null,c=null,l=t=>{let n=this.ringLayout();if(!n)return!1;let r=jB(n.rings,t.offsetX,t.offsetY,9);if(!r)return!1;let i=this.liveSelected();if(!i)return!1;e.setPointerCapture(t.pointerId);let a=i.rotation,o=1;if(this.rendererDim===`3d`&&this.renderer3d){let{forward:e}=this.renderer3d.cameraBasis();o=(r===`x`?e.x:r===`y`?e.y:e.z)>0?1:-1}return c={axis:r,node:i,origin:n.origin,startAngle:kB(n.origin,t.offsetX,t.offsetY),startRotation:Array.isArray(a)?[...a]:a??0,sign:o},this.activeRing=r,!0},u=e=>{if(!c)return;let{axis:t,node:n,origin:r,startAngle:i,startRotation:a,sign:o}=c,s=AB(i,kB(r,e.offsetX,e.offsetY))*o,l=e.shiftKey||this.shiftHeld?15:null,u=e=>{let t=e+s;return l?Math.round(t/l)*l:Math.round(t*10)/10},d;if(Array.isArray(a)){let e={x:0,y:1,z:2}[t],r=[...a];r[e]=u(a[e]??0),d=r[e],n.rotation=r}else{let e=u(a);d=e,n.rotation=e}this.readout={x:e.offsetX,y:e.offsetY,text:`${d}°${l?` ⌁15°`:``}`}},d=e=>{if(!c)return;let{node:t,startRotation:n}=c;if(!e)t.rotation=n;else{let e=this.pathOf.get(t),n=t.rotation;e!==void 0&&n!==void 0&&(Array.isArray(n)?this.cb.onNodeRotated3D(e,[n[0]??0,n[1]??0,n[2]??0]):this.cb.onNodeRotated2D(e,n))}c=null,this.activeRing=null,this.readout=null};this.cancelActiveDrag=()=>{d(!1),s&&(s.node.position=s.startPos,s.node.scale=s.startScale,s=null,this.gizmoActive=null,this.readout=null)};let f=t=>{if(this.gizmoMode===`rotate`)return l(t);let n=this.gizmoLayout();if(!n)return!1;let r=EB(n,t.offsetX,t.offsetY);if(!r)return!1;let i=this.liveSelected();if(!i)return!1;e.setPointerCapture(t.pointerId);let a=[...i.position??[]],o=[...i.scale??[]];return s={hit:r,mode:this.gizmoMode===`scale`||t.button===2?`scale`:`move`,startX:t.offsetX,startY:t.offsetY,layout:n,node:i,startPos:a,startScale:o},this.gizmoActive=r,!0},p=e=>{if(!s)return;let{hit:t,mode:n,layout:r,node:i,startPos:a,startScale:o}=s,c=e.offsetX-s.startX,l=e.offsetY-s.startY,u=this.rendererDim===`3d`,d={x:0,y:1,z:2},f=e.shiftKey||this.shiftHeld,p=f?u?.5:10:null,m=f?.25:null,h=e=>p?Math.round(e/p)*p:e,g=e=>m?Math.max(m,Math.round(e/m)*m):e;if(n===`scale`){let n=Math.max(.05,1+(c-l)*.005),r=[...o];if(t.kind===`axis`)r[d[t.axis]]=FB(g((o[d[t.axis]]??1)*n));else for(let e=0;e<r.length;e++)r[e]=FB(g((o[e]??1)*n));i.scale=r,this.readout={x:e.offsetX,y:e.offsetY,text:`×${r.map(e=>FB(e)).join(`, `)}`};return}let _=[...a];if(t.kind===`axis`){let e=r.axes.find(e=>e.axis===t.axis);if(!e)return;let n=DB(e,c,l);if(u)_[d[t.axis]]=FB(h((a[d[t.axis]]??0)+n));else{let e=WB(i,t.axis===`x`?n:0,t.axis===`y`?n:0),r=t.axis===`x`?e.x:e.y;_[d[t.axis]]=Math.round(h((a[d[t.axis]]??0)+r))}}else if(u&&this.renderer3d){let{right:e,up:t}=this.renderer3d.cameraBasis(),n=this.orbit.dist*.0016;_[0]=FB(h((a[0]??0)+(e.x*c-t.x*l)*n)),_[1]=FB(h((a[1]??0)+(e.y*c-t.y*l)*n)),_[2]=FB(h((a[2]??0)+(e.z*c-t.z*l)*n))}else if(this.renderer2d){let e=this.renderer2d.view(),t=WB(i,c/e.zoom,l/e.zoom);_[0]=Math.round(h((a[0]??0)+t.x)),_[1]=Math.round(h((a[1]??0)+t.y))}i.position=_,this.readout={x:e.offsetX,y:e.offsetY,text:`[${_.map(e=>FB(e)).join(`, `)}]`}},m=()=>{if(!s)return;let{node:e,mode:t}=s,n=this.pathOf.get(e);if(n)if(t===`scale`){let t=e.scale??[];this.rendererDim===`3d`?this.cb.onNodeScaled3D(n,[t[0]??1,t[1]??1,t[2]??1]):this.cb.onNodeScaled(n,[t[0]??1,t[1]??1])}else{let t=e.position??[];this.rendererDim===`3d`?this.cb.onNodeMoved3D(n,[t[0]??0,t[1]??0,t[2]??0]):this.cb.onNodeMoved(n,[t[0]??0,t[1]??0])}s=null,this.gizmoActive=null};e.addEventListener(`pointerdown`,s=>{if(this.playing||f(s))return;if(this.rendererDim===`3d`){let t=this.gizmoHit(s.offsetX,s.offsetY);if(t){this.snapView(t.axis,t.sign);return}e.setPointerCapture(s.pointerId),s.button===1||s.button===2||s.shiftKey?a={x:s.offsetX,y:s.offsetY,target:[...this.orbit.target]}:(i={x:s.offsetX,y:s.offsetY,yaw:this.orbit.yaw,pitch:this.orbit.pitch},o={x:s.offsetX,y:s.offsetY,toggle:s.ctrlKey||s.metaKey});return}if(!this.renderer2d)return;if(e.setPointerCapture(s.pointerId),s.button===1||s.button===2||s.shiftKey){let e=this.renderer2d.view();n={startX:s.offsetX,startY:s.offsetY,cx:e.cx,cy:e.cy};return}if(this.paintHandler&&s.button===0){let e=this.renderer2d.worldFromScreen(s.offsetX,s.offsetY);this.paintHandler(e.x,e.y,!0),r=!0;return}let c=this.renderer2d.pick(s.offsetX,s.offsetY),l=c?this.pathOf.get(c)??null:null;if(this.cb.onPick(l,{toggle:s.ctrlKey||s.metaKey}),this.selectedPath=l,c&&l&&Array.isArray(c.position)){let e=c.position;t={node:c,startWorld:this.renderer2d.worldFromScreen(s.offsetX,s.offsetY),startPos:[e[0]??0,e[1]??0]}}}),e.addEventListener(`pointermove`,o=>{if(!this.playing){if(c){u(o);return}if(s){p(o);return}if(this.rendererDim===`3d`){if(!i&&!a?(this.hoveredGizmo=this.gizmoHandleAt(o.offsetX,o.offsetY),e.style.cursor=this.hoveredGizmo?`pointer`:`grab`):e.style.cursor=`grabbing`,i)this.orbit.yaw=i.yaw-(o.offsetX-i.x)*.006,this.orbit.pitch=Math.max(-1.5,Math.min(1.5,i.pitch+(o.offsetY-i.y)*.006)),this.syncOrbit();else if(a){let{right:e,up:t}=this.orbitVectors(),n=this.orbit.dist*.0016,r=(o.offsetX-a.x)*n,i=(o.offsetY-a.y)*n;this.orbit.target=[a.target[0]-e.x*r+t.x*i,a.target[1]-e.y*r+t.y*i,a.target[2]-e.z*r+t.z*i],this.syncOrbit()}return}if(this.renderer2d){if(e.style.cursor=`crosshair`,r&&this.paintHandler){let e=this.renderer2d.worldFromScreen(o.offsetX,o.offsetY);this.paintHandler(e.x,e.y,!1);return}if(n){let e=this.renderer2d.view();this.renderer2d.viewOverride={cx:n.cx-(o.offsetX-n.startX)/e.zoom,cy:n.cy-(o.offsetY-n.startY)/e.zoom,zoom:e.zoom};return}if(t){let e=this.renderer2d.worldFromScreen(o.offsetX,o.offsetY),n=WB(t.node,e.x-t.startWorld.x,e.y-t.startWorld.y),r=Math.round(t.startPos[0]+n.x),i=Math.round(t.startPos[1]+n.y);t.node.position=[r,i];return}this.hoveredNode=this.renderer2d.pick(o.offsetX,o.offsetY)}}});let h=e=>{if(r=!1,d(!0),m(),this.readout=null,o&&e&&this.renderer3d&&Math.hypot(e.offsetX-o.x,e.offsetY-o.y)<4){let e=this.renderer3d.pick(o.x,o.y),t=e?this.pathOf.get(e)??null:null;t&&(this.cb.onPick(t,{toggle:o.toggle}),this.selectedPath=t)}if(o=null,i=null,a=null,t){let e=this.pathOf.get(t.node),n=t.node.position;e&&(n[0]!==t.startPos[0]||n[1]!==t.startPos[1])&&this.cb.onNodeMoved(e,[n[0]??0,n[1]??0]),t=null}n=null};e.addEventListener(`pointerup`,h),e.addEventListener(`pointercancel`,h),e.addEventListener(`contextmenu`,e=>e.preventDefault()),e.addEventListener(`dblclick`,e=>{if(this.playing)return;let t=this.rendererDim===`3d`?this.renderer3d?.pick(e.offsetX,e.offsetY)??null:this.renderer2d?.pick(e.offsetX,e.offsetY)??null,n=t?this.pathOf.get(t)??null:null;n&&(this.cb.onPick(n,{toggle:e.ctrlKey||e.metaKey}),this.selectedPath=n)}),e.addEventListener(`wheel`,e=>{if(this.playing)return;e.preventDefault();let t=e.deltaY<0?1.1:1/1.1;if(this.rendererDim===`3d`){this.orbit.dist=Math.max(.3,Math.min(800,this.orbit.dist/t)),this.syncOrbit();return}if(!this.renderer2d)return;let n=this.liveSelected();if(e.altKey&&n&&Array.isArray(n.scale)){let e=n.scale,r=[Math.round((e[0]??1)*t*100)/100,Math.round((e[1]??1)*t*100)/100];n.scale=r;let i=this.pathOf.get(n);i&&this.cb.onNodeScaled(i,r);return}let r=this.renderer2d.view(),i=this.renderer2d.worldFromScreen(e.offsetX,e.offsetY),a=Math.min(8,Math.max(.1,r.zoom*t));this.renderer2d.viewOverride={cx:i.x-(e.offsetX-r.w/2)/a,cy:i.y-(e.offsetY-r.h/2)/a,zoom:a}},{passive:!1})}zoomToFit(){let e=this.liveSelected();if(this.rendererDim===`3d`){let t=new Vo;for(let[n]of this.pathOf){if(e&&n!==e&&!GB(n,e))continue;let r=n._object3D;r&&(t.expandByObject(r),t.expandByPoint(r.getWorldPosition(BB)))}if(t.isEmpty()&&e){let t=e._object3D,n=t?t.getWorldPosition(BB):null;this.orbit.target=n?[n.x,n.y,n.z]:[0,1,0],this.orbit.dist=6}else if(t.isEmpty())this.orbit.target=[0,1,0],this.orbit.dist=10;else{let e=t.getCenter(new U),n=t.getSize(new U);this.orbit.target=[e.x,e.y,e.z],this.orbit.dist=Math.max(2.5,n.length()*.85)}this.syncOrbit();return}if(!this.renderer2d)return;let t=this.editCanvas.clientWidth||960,n=this.editCanvas.clientHeight||540,r=1/0,i=1/0,a=-1/0,o=-1/0;for(let[t]of this.pathOf){if(e&&t!==e&&!GB(t,e))continue;let n=t.position;if(!Array.isArray(n))continue;let s=KB(t);r=Math.min(r,s.x),i=Math.min(i,s.y),a=Math.max(a,s.x),o=Math.max(o,s.y)}if(!Number.isFinite(r))return;let s=(r+a)/2,c=(i+o)/2,l=e?600:200,u=Math.max(a-r+l,l),d=Math.max(o-i+l,l),f=Math.min(2,Math.min(t/u,n/d));this.renderer2d.viewOverride={cx:s,cy:c,zoom:f}}async play(e){if(this.playing)return null;let t=structuredClone(e);ZB(t);let n;try{n=An(t,{stubAllBehaviors:!0,declareConnectionSignals:!0})}catch(e){return e instanceof Error?e.message:String(e)}let r=new kt;r.uiHost=this.playUiHost,this.editUiHost&&(this.editUiHost.style.display=`none`),r.setScene(n),r.input.attachKeyboard(window),this.playCanvas.hidden=!1;let i=e.dimension??`2d`;try{if(i===`2d`){this.playRenderer=new Yv({canvas:this.playCanvas,engine:r});let{enablePhysics2D:e}=await bm(async()=>{let{enablePhysics2D:e}=await Promise.resolve().then(()=>sy);return{enablePhysics2D:e}},void 0,import.meta.url),t=await e(r);t.debugDraw=this.showColliders,this.playPhysics=t}else{this.playRenderer=new yP({canvas:this.playCanvas,engine:r,assets:this.renderer3d?.assets});let{enablePhysics3D:e}=await bm(async()=>{let{enablePhysics3D:e}=await Promise.resolve().then(()=>FP);return{enablePhysics3D:e}},void 0,import.meta.url),t=await e(r);t.debugDraw=this.showColliders,this.playPhysics=t}}catch(e){return this.stop(),e instanceof Error?e.message:String(e)}return r.start(),this.playEngine=r,this.cb.onPlayStateChanged(!0),null}stop(){this.playEngine?.input.dispose(),this.playEngine?.stop(),this.playEngine?.dispose(),this.playEngine=null,this.playPhysics?.dispose(),this.playPhysics=null,this.editUiHost&&(this.editUiHost.style.display=``),this.playRenderer?.dispose(),this.playRenderer=null,this.playCanvas.hidden=!0,this.cb.onPlayStateChanged(!1),this.lastAppliedKey=null,this.lastGood&&this.apply(this.lastGood)}};function FB(e){return Math.round(e*100)/100}var IB=new U(0,1,0),LB=new U,RB=new U,zB=new H,BB=new U,VB=new G,HB=new U,UB=new U;function WB(e,t,n){let r=e._object2D?.parent;return r?(VB.copy(r.matrixWorld).invert(),HB.set(t,-n,0).applyMatrix4(VB),UB.set(0,0,0).applyMatrix4(VB),{x:HB.x-UB.x,y:-(HB.y-UB.y)}):{x:t,y:n}}function GB(e,t){for(let n=e.parent;n;n=n.parent)if(n===t)return!0;return!1}function KB(e){let t=e._object2D;if(t)return t.getWorldPosition(BB),{x:BB.x,y:-BB.y};let n=0,r=0,i=e;for(;i;)Array.isArray(i.position)&&(n+=i.position[0]??0,r+=i.position[1]??0),i=i.parent;return{x:n,y:r}}function qB(e){if(!e)return null;if(e.type===`Camera3D`){let t=e.props?.position??[0,2,8];return[t[0]??0,t[1]??2,t[2]??8]}for(let t of e.children??[]){let e=qB(t);if(e)return e}return null}function JB(e){if(!e)return null;if(e.type===`Camera2D`){let t=e.props?.position??[0,0];return[t[0]??0,t[1]??0]}for(let t of e.children??[]){let e=JB(t);if(e)return e}return null}var YB=null;function XB(){if(YB)return YB;let e=document.createElement(`canvas`);e.width=16,e.height=16;let t=e.getContext(`2d`);for(let e=0;e<2;e++)for(let n=0;n<2;n++)t.fillStyle=(n+e)%2==0?`#c252c2`:`#2b2b3b`,t.fillRect(n*8,e*8,8,8);return YB=e.toDataURL(),YB}function ZB(e){let t=e.assets;if(t)for(let e of Object.values(t))typeof e?.url==`string`&&!e.url.includes(`/`)&&!e.url.includes(`.`)&&(e.url=XB())}var QB=e({formatSceneJson:()=>r,httpEditorApi:()=>re,mountEditor:()=>$B});_n(),Lv(),JM(),GP(),G_();async function $B(e={}){let t=e.api??re,n=[],r=document.createElement(`style`);r.dataset.incantoEditor=`true`,r.textContent=Yz,document.head.appendChild(r),n.push(()=>r.remove());let i=document.createElement(`div`);i.className=`incanto-editor-root`,i.innerHTML=kz,(e.host??document.body).appendChild(i),n.push(()=>i.remove());let a=e=>{let t=i.querySelector(e);if(!t)throw Error(`missing ${e}`);return t},o=await t.meta();a(`#engine-version`).textContent=`incanto@${o.version}`,IL(a(`#popover`)),GF(),a(`#docs-btn`).addEventListener(`click`,()=>UF());let s=a(`#lang-btn`),c=[{code:`en`,label:`English`},{code:`ko`,label:`한국어`}],l=()=>{a(`#lang-current`).textContent=YP()===`ko`?`한국어`:`EN`};l(),s.addEventListener(`click`,()=>{document.querySelector(`.lang-menu`)?.remove();let e=document.createElement(`div`);e.className=`context-menu floating lang-menu`;for(let{code:t,label:n}of c){let r=document.createElement(`button`);r.type=`button`,r.className=`menu-item`;let i=document.createElement(`span`);i.textContent=n;let a=document.createElement(`span`);a.textContent=YP()===t?`✓`:``,a.className=`lang-check`,r.append(i,a),r.addEventListener(`click`,()=>{e.remove(),XP(t)}),e.appendChild(r)}document.body.appendChild(e);let t=s.getBoundingClientRect();e.style.left=`${t.left}px`,e.style.top=`${t.bottom+6}px`;let n=t=>{e.contains(t.target)||t.target===s||(e.remove(),document.removeEventListener(`pointerdown`,n,!0))};setTimeout(()=>document.addEventListener(`pointerdown`,n,!0),0)}),ZP(()=>{l(),KF(),u.select(u.selection)});let u=new Rz({format:1,type:`scene`,name:``,root:null}),d=a(`#tree`),f=a(`#inspector`),p=a(`#save-btn`),m=a(`#undo-btn`),h=a(`#play-btn`),g=a(`#error-banner`),_=a(`#play-notice`),v=a(`#add-type`),y=a(`#picker`),b=a(`#picker-list`),x=a(`#scenes-btn`),S=o.input,C=o.output,w,T=!1,E=a(`#error-text`),D=e=>{g.hidden=!1,E.textContent=e,IF.error(e)},O=()=>{g.hidden=!0,E.textContent=``};a(`#error-close`).addEventListener(`click`,O);let k=a(`#edit-notice`),A=null,ee=e=>{k.hidden=!1,k.textContent=e,A&&clearTimeout(A),A=setTimeout(()=>{k.hidden=!0,k.textContent=``},6e3)},te={on:!1,brush:`0`},ne=e=>{let t=0,n=0,r=u.working.root,i=e=>{let r=e?.props?.position;Array.isArray(r)&&(t+=Number(r[0]??0),n+=Number(r[1]??0))};i(r);for(let t of e)r=r?.children?.[t],i(r);return{x:t,y:n}},j=!1,ie=(e,t,n=!0)=>{n&&(j=!1);let r=u.selection,i=u.nodeAt(r);if(!r||i?.type!==`TileMap2D`)return;let{cx:a,cy:o}=rR(ne(r),Number(i.props?.tileSize??32),e,t),s=i.props?.cells??[],c=iR(s,a,o,te.brush);!c||JSON.stringify(c)===JSON.stringify(s)||(u.mutate(()=>{i.props||={},i.props.cells=c},{path:r,key:`cells`,value:c},{coalesce:j}),j=!0)},ae=()=>{let e=u.nodeAt(u.selection);te.on&&e?.type!==`TileMap2D`&&(te.on=!1),M.setPaintHandler(te.on?ie:null)},M=new PB(a(`#viewport`),a(`#overlay`),a(`#play-canvas`),{onPick:(e,t)=>u.select(e??null,t),onNodeMoved:(e,t)=>me(e,`position`,t,[0,0]),onNodeScaled:(e,t)=>me(e,`scale`,t,[1,1]),onNodeMoved3D:(e,t)=>me(e,`position`,t,[0,0,0]),onNodeScaled3D:(e,t)=>me(e,`scale`,t,[1,1,1]),onNodeRotated2D:(e,t)=>pe(e,`rotation`,t,0),onNodeRotated3D:(e,t)=>me(e,`rotation`,t,[0,0,0]),onModeChanged:e=>{for(let t of[`move`,`rotate`,`scale`])a(`#tool-${t}`).classList.toggle(`active`,t===e)},onPlayStateChanged:e=>{document.body.classList.toggle(`playing`,e),n.push(()=>document.body.classList.remove(`playing`)),h.classList.toggle(`stop`,e),h.innerHTML=e?`<svg width="11" height="11" viewBox="0 0 24 24" fill="currentColor"><rect x="6" y="6" width="12" height="12"/></svg> stop`:`<svg width="11" height="11" viewBox="0 0 24 24" fill="currentColor"><path d="M8 5v14l11-7z"/></svg> play`,_.hidden=!e,e&&(_.textContent=`▶ simulating — physics + input live; game scripts run only in your real game. Esc or stop to return.`)},onError:D}),oe=Ke().sort(),se=``,ce=e=>{if(e===se)return;se=e,v.textContent=``;let t=e===`3d`?[`3D`,`3D Physics`,`Core`,`Network`,`2D`,`2D Physics`]:[`2D`,`2D Physics`,`Core`,`Network`,`3D`,`3D Physics`];for(let[e]of RF)t.includes(e)||t.push(e);for(let e of t){let t=RF.find(([t])=>t===e)?.[1];if(!t)continue;let n=document.createElement(`optgroup`);n.label=e;for(let e of oe.filter(t)){let t=document.createElement(`option`);t.value=e,t.textContent=e,n.appendChild(t)}n.children.length>0&&v.appendChild(n)}v.value=e===`3d`?`MeshInstance3D`:`Sprite2D`};ce(`2d`);let le=()=>{let e=u.selection??[];if(M.validate(u.working)!==null){for(let e of v.querySelectorAll(`option`))e.disabled=!1;return}for(let t of v.querySelectorAll(`option`)){let n=structuredClone(u.working),r=n.root;if(!n.root)n.root={name:`__probe`,type:t.value};else{for(let t of e)r=r?.children?.[t];if(!r)continue;r.children||=[],r.children.push({name:`__probe`,type:t.value})}t.disabled=M.validate(n)!==null}};v.addEventListener(`mousedown`,le),v.addEventListener(`focus`,le);let ue=t.library?e=>fz(t,{kind:e.kind,...e.target?{target:e.target}:{},...e.shelf?{shelf:e.shelf}:{},...e.assetType?{assetType:e.assetType}:{},...e.onProps?{onProps:e.onProps}:{},...e.asAsset?{onAsset:(e,t,n)=>rV(u,n,t)}:{}}):void 0,de=!1,fe=()=>{if(!T)return;cB(d,u),uF(a(`#asset-tree`),u),f.textContent=``,dF(f,u,Se,ue)||cR(f,u,{modelRefs:()=>tV(u,`model`),animationsForSelection:()=>u.selection?M.modelAnimationsAt(u.selection):[],bonesForSelection:e=>u.selection?M.boneNamesAt(u.selection,e):[],assetRefs:e=>nV(u,e),addAsset:(e,t)=>rV(u,e,t),...ue?{openLibrary:ue}:{},confirm:Se,paint:{active:()=>te.on,brush:()=>te.brush,toggle:()=>{te.on=!te.on,ae(),fe()},setBrush:e=>{te.brush=e,fe()}}}),ce(u.working.dimension??`2d`),a(`#hints`).hidden=(u.working.dimension??`2d`)===`3d`,a(`#hints-3d`).hidden=(u.working.dimension??`2d`)!==`3d`,M.setSelection(u.selection,u.extra),ae();let e=u.pendingLivePatch;if(u.pendingLivePatch=null,!M.playing)if(e&&M.patchProp(u.working,e.path,e.key,e.value))g.hidden=!0;else{let e=M.apply(u.working);g.hidden=e===null,e!==null&&D(e)}p.disabled=!u.dirty||!u.working.root,p.title=u.working.root?``:`Add a root node before saving`,m.disabled=!u.canUndo,u.dirty!==de&&(de=u.dirty,IF.change(u.dirty))};u.onChange(fe),u.validator=e=>M.validate(e),u.onError=D;let pe=(e,t,n,r)=>{let i=u.nodeAt(e);i&&u.mutate(()=>{i.props||={},n===r?(delete i.props[t],Object.keys(i.props).length===0&&delete i.props):i.props[t]=n},{path:e,key:t,value:n})},me=(e,t,n,r)=>{let i=u.nodeAt(e);i&&u.mutate(()=>{i.props||={},JSON.stringify(n)===JSON.stringify(r)?(delete i.props[t],Object.keys(i.props).length===0&&delete i.props):i.props[t]=n},{path:e,key:t,value:n})},he=async(e,n,r)=>{M.playing&&M.stop();let i=await t.loadScene(e);w=e,S=n,C=r,T=!0;let s=e??n;a(`#file-chip`).hidden=!s,a(`#file-path`).textContent=s??``,a(`#file-chip`).title=`input: ${n}\noutput: ${r}`,y.hidden=!0,O(),dB(),u.reset(i),o.mode===`project`&&n&&IF.open(n,r)},ge=Oz({list:b,search:a(`#picker-search`),count:a(`#picker-count`),path:a(`#picker-path`)},{entries:async()=>t.scenes?await t.scenes():[],current:()=>w,open:e=>_e(e.rel,e.abs)}),_e=(e,t)=>{let n=()=>{he(e,t,t).catch(e=>D(e instanceof Error?e.message:String(e)))};if(!u.dirty||!u.canUndo){n();return}Se(`'${w??`This scene`}' has unsaved changes. Opening '${e}' discards them.`,`discard & open`,n)},ve=async()=>{y.hidden=!1,await ge.refresh()},ye=()=>{y.hidden=!0};if(a(`#picker-close`).addEventListener(`click`,ye),y.addEventListener(`pointerdown`,e=>{e.target===y&&ye()}),a(`#picker-create`).addEventListener(`click`,()=>{(async()=>{let e=a(`#picker-path`),n=(e.value.trim()||e.placeholder).trim();if(n)try{if(!t.createScene)return;let e=await t.createScene(n.endsWith(`.scene.json`)?n:`${n}.scene.json`);await he(e.rel,e.abs,e.abs)}catch(e){D(e instanceof Error?e.message:String(e))}})()}),o.mode===`project`&&t.scenes&&(x.hidden=!1,x.addEventListener(`click`,()=>void ve())),o.mode===`project`&&o.input===null)await he(void 0,``,``);else if(o.mode===`project`&&t.scenes){let e=await t.scenes(),n=e.length===1?e[0]:void 0;n?await he(n.rel,n.abs,n.abs):await ve()}else await he(void 0,o.input,o.output);a(`#add-btn`).addEventListener(`click`,()=>{let e=u.selection??[],t=v.value,n=u.insertNode({name:t,type:t},e);n&&u.select(n)});let N=a(`#generate`);AL(u),a(`#generate-btn`).addEventListener(`click`,()=>OL(u));let P=a(`#confirm`),F=e=>{if(u.selection===null&&e.length===0){D(`The scene itself cannot be deleted — it IS the file.`);return}if(e.length===0){let e=u.working.root;if(!e)return;let t=eV(e);Se(`This deletes the ROOT '${String(e.name??``)}'${t>0?` AND its ${t} descendant node${t===1?``:`s`}`:``} — the scene goes empty, and the next node you add becomes the new root.`,`delete root`,()=>u.deleteRoot());return}let t=e[0]?.slice(0,-1)??[],n=u.findRemovalReferences(e);if(n.length===0){let n=e.reduce((e,t)=>{let n=u.nodeAt(t);return e+(n?eV(n):0)},0);if(n>0){Se(`This deletes ${e.length>1?`${e.length} nodes`:`'${String(u.nodeAt(e[0]??[])?.name??``)}'`} AND ${n} descendant node${n===1?``:`s`}.`,`delete ${e.length+n} nodes`,()=>{u.removeNodes(e)&&u.select(t)});return}u.removeNodes(e)&&u.select(t);return}a(`#confirm-text`).textContent=`${n.length} reference${n.length>1?`s`:``} still point at the node(s) you are deleting. Unlink them and delete, or cancel.`;let r=a(`#confirm-list`);r.textContent=``;for(let e of n){let t=document.createElement(`div`);t.textContent=`${e.kind===`uid`?`◆ uid`:`⇄ connection`} ${e.where}`,r.appendChild(t)}a(`#confirm-title`).textContent=`still referenced`,a(`#confirm-delete`).textContent=`unlink & delete`,P.hidden=!1,be={selections:e,parentOfFirst:t}},be=null,xe=null;function Se(e,t,n){a(`#confirm-title`).textContent=`are you sure?`,a(`#confirm-text`).textContent=e,a(`#confirm-list`).textContent=``,a(`#confirm-delete`).textContent=t,xe=n,P.hidden=!1}function I(){P.hidden=!0,be=null,xe=null}a(`#confirm-close`).addEventListener(`click`,I),a(`#confirm-cancel`).addEventListener(`click`,I),P.addEventListener(`pointerdown`,e=>{e.target===P&&I()}),a(`#confirm-delete`).addEventListener(`click`,()=>{if(xe){xe(),I();return}be&&u.removeNodesUnlinking(be.selections)&&u.select(be.parentOfFirst),I()}),nB(F),rB(e=>{ee(`${QP({en:`Rename: repaired ${e.length} reference${e.length===1?``:`s`}`,ko:`이름 변경: 참조 ${e.length}건 수정`})} — ${e.map(e=>e.where).join(`, `)}`)}),a(`#asset-add-btn`).addEventListener(`click`,e=>{e.stopPropagation(),u.startAddingAsset()}),a(`#group-add-btn`).addEventListener(`click`,e=>{e.stopPropagation(),u.startAddingGroup()});for(let e of document.querySelectorAll(`.section-toggle`)){let t=e.dataset.section??``,n=document.querySelector(`[data-body="${t}"]`),r=`incanto-editor-section-${t}`,i=t=>{e.classList.toggle(`collapsed`,t),n&&(n.hidden=t),localStorage.setItem(r,t?`1`:``)};i(localStorage.getItem(r)===`1`),e.addEventListener(`click`,()=>i(!e.classList.contains(`collapsed`)))}a(`#delete-btn`).addEventListener(`click`,()=>{F(u.allSelections().filter(e=>e.length>0))});let Ce=()=>{g.hidden=!0,M.play(u.working).then(e=>{e&&D(e)})};if(h.addEventListener(`click`,()=>{if(M.playing){M.stop(),fe();return}if(!e.onPlay){Ce();return}i.querySelector(`.play-menu`)?.remove();let t=document.createElement(`div`);t.className=`context-menu floating play-menu`;let r=[[`preview`,`▶ preview here`,e.playHints?.preview??`simulate in the editor · scripts stripped`],[`debug`,`⤢ run as the game`,e.playHints?.debug??`this page becomes the game, with the debug overlay`]];for(let[n,i,a]of r){let r=document.createElement(`button`);r.type=`button`,r.className=`menu-item play-menu-item`;let o=document.createElement(`span`);o.textContent=i;let s=document.createElement(`span`);s.className=`play-menu-hint`,s.textContent=a,r.append(o,s),r.addEventListener(`click`,()=>{t.remove(),n===`preview`?Ce():e.onPlay?.(n,u.working)}),t.appendChild(r)}i.appendChild(t);let a=h.getBoundingClientRect(),o=t.getBoundingClientRect().width;t.style.left=`${Math.min(Math.max(8,a.right-o),window.innerWidth-o-8)}px`,t.style.top=`${a.bottom+6}px`;let s=e=>{e.type===`keydown`&&e.key!==`Escape`||e.type!==`keydown`&&(t.contains(e.target)||e.target===h)||(t.remove(),document.removeEventListener(`pointerdown`,s,!0),document.removeEventListener(`keydown`,s,!0))};setTimeout(()=>{document.addEventListener(`pointerdown`,s,!0),document.addEventListener(`keydown`,s,!0)},0),n.push(()=>{document.removeEventListener(`pointerdown`,s,!0),document.removeEventListener(`keydown`,s,!0)})}),e.onExit){let t=document.createElement(`button`);t.type=`button`,t.className=`ghost`,t.id=`exit-btn`,t.title=`Back to the game`,t.textContent=`✕ exit`,h.parentElement?.insertBefore(t,h),t.addEventListener(`click`,()=>void e.onExit?.())}for(let e of[`move`,`rotate`,`scale`])a(`#tool-${e}`).addEventListener(`click`,()=>M.setMode(e));M.setMode(`move`);let L=a(`#tool-colliders`),we=`incanto-editor-show-colliders`,Te=e=>{M.showColliders=e,L.classList.toggle(`active`,e),localStorage.setItem(we,e?``:`0`)};Te(localStorage.getItem(we)!==`0`),L.addEventListener(`click`,()=>Te(!M.showColliders));let Ee=a(`#hints-dock`),De=`incanto-editor-hints-open`;Ee.classList.toggle(`open`,localStorage.getItem(De)===`1`),a(`#hints-toggle`).addEventListener(`click`,()=>{let e=Ee.classList.toggle(`open`);localStorage.setItem(De,e?`1`:``)}),a(`#fit-btn`).addEventListener(`click`,()=>M.zoomToFit()),tB(()=>M.zoomToFit()),a(`#gameview-btn`).addEventListener(`click`,()=>M.gameView()),t.saveScene||(p.hidden=!0),p.addEventListener(`click`,()=>{(async()=>{try{await t.saveScene?.(u.working,w),u.markSaved(),IF.save(S,C,u.working)}catch(e){D(e instanceof Error?e.message:String(e))}})()}),m.addEventListener(`click`,()=>u.undo());let Oe=e=>{if(e.key===`Escape`&&M.cancelActiveDrag(),e.key===`Escape`&&!g.hidden&&a(`#docs`).hidden&&P.hidden&&N.hidden&&y.hidden&&!M.playing){O();return}if(e.key===`Escape`&&!a(`#docs`).hidden){WF();return}if(e.key===`Escape`&&!P.hidden){I();return}if(e.key===`Escape`&&!N.hidden){kL();return}if(e.key===`Escape`&&!y.hidden){ye();return}if(e.key===`Escape`&&M.playing){M.stop(),fe();return}if(M.playing)return;let t=e.target.matches(`input, textarea, select`);(e.metaKey||e.ctrlKey)&&e.key===`z`?(e.preventDefault(),u.undo()):(e.metaKey||e.ctrlKey)&&e.key===`s`?(e.preventDefault(),p.disabled||p.click()):!t&&e.code===`KeyF`?M.zoomToFit():!t&&(e.code===`Digit0`||e.code===`Numpad0`)?M.gameView():!t&&e.code===`KeyW`?M.setMode(`move`):!t&&e.code===`KeyE`?M.setMode(`rotate`):!t&&e.code===`KeyR`&&M.setMode(`scale`)};return window.addEventListener(`keydown`,Oe),n.push(()=>window.removeEventListener(`keydown`,Oe)),fe(),e.camera&&M.setEditCamera(e.camera.position,e.camera.target),IF.ready(S,C,o.version),{working:()=>u.working,camera:()=>M.editCamera(),showError:D,dispose(){M.dispose();for(let e of document.querySelectorAll(`.context-menu, .balloon`))e.remove();for(let e of n.splice(0).reverse())e()}}}function eV(e){let t=0;for(let n of e.children??[])t+=1+eV(n);return t}function tV(e,t){let n=e.working.assets;return n?Object.entries(n).filter(([,e])=>e?.type===t).map(([e])=>`$${e}`):[]}function nV(e,t){let n=e.working.assets;return n?Object.entries(n).filter(([,e])=>!t||e?.type!==void 0&&t.includes(e.type)).map(([e])=>`$${e}`):[]}function rV(e,t,n){let r=e.working.assets??{};for(let[e,t]of Object.entries(r))if(t?.url===n.url)return`$${e}`;let i=t;for(let e=2;i in r;e++)i=`${t}-${e}`;return e.mutate(()=>{e.working.assets||(e.working.assets={}),e.working.assets[i]=n}),`$${i}`}var iV=null,aV=null;function oV(){return aV||(aV=document.createElement(`canvas`),aV.style.cssText=`position:fixed; inset:0; width:100%; height:100%; display:block;`,document.body.appendChild(aV)),aV.style.visibility=``,aV}async function sV(e,t){return iV=await $B({api:re,...e?{camera:e}:{},onPlay:(e,t)=>{e===`debug`&&cV(t)},playHints:{debug:`this page becomes the game — needs a scene with no project behaviors`},...t?{onExit:()=>(iV?.dispose(),iV=null,oV(),t())}:{}}),iV}async function cV(e){let t=e.dimension??`2d`;iV?.dispose(),iV=null;let n=async e=>{aV&&(aV.style.visibility=`hidden`),await sV(e.camera,e.exit)};try{if(t===`3d`){let{createGame3D:t}=await bm(async()=>{let{createGame3D:e}=await Promise.resolve().then(()=>FP);return{createGame3D:e}},void 0,import.meta.url);await t({canvas:oV(),scene:e,debug:!0,editor:{open:n}})}else{let{createGame2D:t}=await bm(async()=>{let{createGame2D:e}=await Promise.resolve().then(()=>sy);return{createGame2D:e}},void 0,import.meta.url);await t({canvas:oV(),scene:e,debug:!0,editor:{open:n}})}}catch(e){aV&&(aV.style.visibility=`hidden`),(await sV()).showError(`${e instanceof Error?e.message:String(e)}\n\nRunning as the game needs your project's behaviors, which live in your app, not in this page. Start your own dev server with debug enabled and use the ☰ debug menu's "✎ edit this scene" — the switch works both ways from there, with every behavior loaded.`)}}sV().catch(e=>{let t=document.createElement(`div`);t.id=`error-banner`,t.style.cssText=`position:fixed;inset:0 0 auto 0;z-index:99;padding:10px 14px;background:#5b1a24;color:#ffd9df;font:13px ui-monospace,monospace`,t.textContent=e instanceof Error?e.message:String(e),document.body.appendChild(t)});export{He as i,bm as n,Xe as r,tv as t};
|