new M),this.satAxes=new Array(3).fill().map(()=>new M),this.satBounds=new Array(3).fill().map(()=>new fs),this.alignedSatBounds=new Array(3).fill().map(()=>new fs),this.needsUpdate=!1,t&&this.min.copy(t),e&&this.max.copy(e),s&&this.matrix.copy(s)}set(t,e,s){this.min.copy(t),this.max.copy(e),this.matrix.copy(s),this.needsUpdate=!0}copy(t){this.min.copy(t.min),this.max.copy(t.max),this.matrix.copy(t.matrix),this.needsUpdate=!0}}Ms.prototype.update=function(){const t=this.matrix,e=this.min,s=this.max,i=this.points;for(let r=0;r<=1;r++)for(let n=0;n<=1;n++)for(let a=0;a<=1;a++){const o=i[1*r|2*n|4*a];o.x=r?s.x:e.x,o.y=n?s.y:e.y,o.z=a?s.z:e.z,o.applyMatrix4(t)}const r=this.satBounds,n=this.satAxes,a=i[0];for(let t=0;t<3;t++){const e=n[t],s=r[t],o=i[1<new Fe),s=new Array(12).fill().map(()=>new Fe),i=new M,r=new M;return function(n,a=0,o=null,h=null){if(this.needsUpdate&&this.update(),this.intersectsBox(n))return(o||h)&&(n.getCenter(r),this.closestPointToPoint(r,i),n.closestPointToPoint(i,r),o&&o.copy(i),h&&h.copy(r)),0;const l=a*a,c=n.min,u=n.max,d=this.points;let p=1/0;for(let t=0;t<8;t++){const e=d[t];r.copy(e).clamp(c,u);const s=e.distanceToSquared(r);if(snew _s)}}const As=new Ss,vs=new class{constructor(){this.float32Array=null,this.uint16Array=null,this.uint32Array=null;const t=[];let e=null;this.setBuffer=s=>{e&&t.push(e),e=s,this.float32Array=new Float32Array(s),this.uint16Array=new Uint16Array(s),this.uint32Array=new Uint32Array(s)},this.clearBuffer=()=>{e=null,this.float32Array=null,this.uint16Array=null,this.uint32Array=null,0!==t.length&&this.setBuffer(t.pop())}}};let Ts,Bs;const ks=[],Ps=new zs(()=>new D);function Cs(t,e,s,i,r,n){Ts=Ps.getPrimitive(),Bs=Ps.getPrimitive(),ks.push(Ts,Bs),vs.setBuffer(t._roots[e]);const a=Vs(0,t.geometry,s,i,r,n);vs.clearBuffer(),Ps.releasePrimitive(Ts),Ps.releasePrimitive(Bs),ks.pop(),ks.pop();const o=ks.length;return o>0&&(Bs=ks[o-1],Ts=ks[o-2]),a}function Vs(t,e,s,i,r=null,n=0,a=0){const{float32Array:o,uint16Array:h,uint32Array:l}=vs;let c=2*t;if(ts(c,h)){const u=es(t,l),d=ss(c,h);return De(t,o,Ts),i(u,d,!1,a,n+t,Ts)}{const p=is(t),m=rs(t,l);let y,f,x,g,b=p,w=m;if(r&&(x=Ts,g=Bs,De(b,o,x),De(w,o,g),y=r(x),f=r(g),f=169,Us=new M,Ns=new M,Os=new M,qs=new w,Rs=new w,Ws=new w,Ds=new M,Ls=new M,js=new M,Hs=new M;function Ys(t,e,s,i,r,n,a){const o=3*i;let h=o+0,l=o+1,c=o+2;const u=t.index;t.index&&(h=u.getX(h),l=u.getX(l),c=u.getX(c));const{position:d,normal:p,uv:m,uv1:y}=t.attributes,f=function(t,e,s,i,r,n,a,o,h,l,c){Us.fromBufferAttribute(e,n),Ns.fromBufferAttribute(e,a),Os.fromBufferAttribute(e,o);const u=function(t,e,s,i,r,n,a,o){let h;if(h=1===n?t.intersectTriangle(i,s,e,!0,r):t.intersectTriangle(e,s,i,2!==n,r),null===h)return null;const l=t.origin.distanceTo(r);return lo?null:{distance:l,point:r.clone()}}(t,Us,Ns,Os,Hs,h,l,c);if(u){const e=new M;Gt.getBarycoord(Hs,Us,Ns,Os,e),i&&(qs.fromBufferAttribute(i,n),Rs.fromBufferAttribute(i,a),Ws.fromBufferAttribute(i,o),u.uv=Gt.getInterpolation(Hs,Us,Ns,Os,qs,Rs,Ws,new w)),r&&(qs.fromBufferAttribute(r,n),Rs.fromBufferAttribute(r,a),Ws.fromBufferAttribute(r,o),u.uv1=Gt.getInterpolation(Hs,Us,Ns,Os,qs,Rs,Ws,new w)),s&&(Ds.fromBufferAttribute(s,n),Ls.fromBufferAttribute(s,a),js.fromBufferAttribute(s,o),u.normal=Gt.getInterpolation(Hs,Us,Ns,Os,Ds,Ls,js,new M),u.normal.dot(t.direction)>0&&u.normal.multiplyScalar(-1));const h={a:n,b:a,c:o,normal:new M,materialIndex:0};Gt.getNormal(Us,Ns,Os,h.normal),u.face=h,u.faceIndex=n,Es&&(u.barycoord=e)}return u}(s,d,p,m,y,h,l,c,e,n,a);return f?(f.faceIndex=i,r&&r.push(f),f):null}function Xs(t,e,s,i){const r=t.a,n=t.b,a=t.c;let o=e,h=e+1,l=e+2;s&&(o=s.getX(o),h=s.getX(h),l=s.getX(l)),r.x=i.getX(o),r.y=i.getY(o),r.z=i.getZ(o),n.x=i.getX(h),n.y=i.getY(h),n.z=i.getZ(h),a.x=i.getX(l),a.y=i.getY(l),a.z=i.getZ(l)}function Gs(t,e,s,i,r,n,a){const{geometry:o}=s,{index:h}=o,l=o.attributes.position;for(let s=t,o=e+t;su&&(u=a),od&&(d=o),hp&&(p=h)}return(h[t+0]!==s||h[t+1]!==n||h[t+2]!==c||h[t+3]!==u||h[t+4]!==d||h[t+5]!==p)&&(h[t+0]=s,h[t+1]=n,h[t+2]=c,h[t+3]=u,h[t+4]=d,h[t+5]=p,!0)}{const i=t+8,r=a[t+6],o=i+s,l=r+s;let c=n,d=!1,p=!1;e?c||(d=e.has(o),p=e.has(l),c=!d&&!p):(d=!0,p=!0);const m=c||p;let y=!1;(c||d)&&(y=u(i,s,c));let f=!1;m&&(f=u(r,s,c));const x=y||f;if(x)for(let e=0;e<3;e++){const s=i+e,n=r+e,a=h[s],o=h[s+3],l=h[n],c=h[n+3];h[t+e]=ac?o:c}return x}}}function Js(t,e,s,i,r){let n,a,o,h,l,c;const u=1/s.direction.x,d=1/s.direction.y,p=1/s.direction.z,m=s.origin.x,y=s.origin.y,f=s.origin.z;let x=e[t],g=e[t+3],b=e[t+1],w=e[t+3+1],_=e[t+2],M=e[t+3+2];return u>=0?(n=(x-m)*u,a=(g-m)*u):(n=(g-m)*u,a=(x-m)*u),d>=0?(o=(b-y)*d,h=(w-y)*d):(o=(w-y)*d,h=(b-y)*d),!(n>h||o>a)&&((o>n||isNaN(n))&&(n=o),(h=0?(l=(_-f)*p,c=(M-f)*p):(l=(M-f)*p,c=(_-f)*p),!(n>c||l>a)&&((l>n||n!=n)&&(n=l),(c=i))}function $s(t,e,s,i,r,n,a){vs.setBuffer(t._roots[e]),Qs(0,t,s,i,r,n,a),vs.clearBuffer()}function Qs(t,e,s,i,r,n,a){const{float32Array:o,uint16Array:h,uint32Array:l}=vs,c=2*t;if(ts(c,h))!function(t,e,s,i,r,n,a,o){const{geometry:h,_indirectBuffer:l}=t;for(let t=i,l=i+r;t=0;let u,d;c?(u=is(t),d=rs(t,h)):(u=rs(t,h),d=is(t));const p=Js(u,a,i,r,n)?ei(u,e,s,i,r,n):null;if(p){const t=p.point[l];if(c?t<=a[d+o]:t>=a[d+o+3])return p}const m=Js(d,a,i,r,n)?ei(d,e,s,i,r,n):null;return p&&m?p.distance<=m.distance?p:m:p||m||null}}const si=new D,ii=new _s,ri=new _s,ni=new ot,ai=new Ms,oi=new Ms;function hi(t,e,s,i){vs.setBuffer(t._roots[e]);const r=li(0,t,s,i);return vs.clearBuffer(),r}function li(t,e,s,i,r=null){const{float32Array:n,uint16Array:a,uint32Array:o}=vs;let h=2*t;if(null===r&&(s.boundingBox||s.computeBoundingBox(),ai.set(s.boundingBox.min,s.boundingBox.max,i),r=ai),!ts(h,a)){const a=t+8,h=o[t+6];return De(a,n,si),r.intersectsBox(si)&&li(a,e,s,i,r)?!0:(De(h,n,si),!(!r.intersectsBox(si)||!li(h,e,s,i,r)))}{const r=e.geometry,l=r.index,c=r.attributes.position,u=s.index,d=s.attributes.position,p=es(t,o),m=ss(h,a);if(ni.copy(i).invert(),s.boundsTree)return De(t,n,oi),oi.matrix.copy(ni),oi.needsUpdate=!0,s.boundsTree.shapecast({intersectsBounds:t=>oi.intersectsBox(t),intersectsTriangle:t=>{t.a.applyMatrix4(i),t.b.applyMatrix4(i),t.c.applyMatrix4(i),t.needsUpdate=!0;for(let e=3*p,s=3*(m+p);eui.distanceToBox(t),intersectsBounds:(t,e,s)=>s{if(e.boundsTree)return e.boundsTree.shapecast({boundsTraverseOrder:t=>di.distanceToBox(t),intersectsBounds:(t,e,s)=>s{for(let a=e,o=e+r;ad&&(d=a),op&&(p=o),hm&&(m=h)}}return(h[s+0]!==n||h[s+1]!==l||h[s+2]!==u||h[s+3]!==d||h[s+4]!==p||h[s+5]!==m)&&(h[s+0]=n,h[s+1]=l,h[s+2]=u,h[s+3]=d,h[s+4]=p,h[s+5]=m,!0)}{const t=s+8,i=a[s+6],r=t+n,o=i+n;let c=l,d=!1,p=!1;e?c||(d=e.has(r),p=e.has(o),c=!d&&!p):(d=!0,p=!0);const m=c||p;let y=!1;(c||d)&&(y=u(t,n,c));let f=!1;m&&(f=u(i,n,c));const x=y||f;if(x)for(let e=0;e<3;e++){const r=t+e,n=i+e,a=h[r],o=h[r+3],l=h[n],c=h[n+3];h[s+e]=ac?o:c}return x}}}function wi(t,e,s,i,r,n,a){vs.setBuffer(t._roots[e]),_i(0,t,s,i,r,n,a),vs.clearBuffer()}function _i(t,e,s,i,r,n,a){const{float32Array:o,uint16Array:h,uint32Array:l}=vs,c=2*t;if(ts(c,h))!function(t,e,s,i,r,n,a,o){const{geometry:h,_indirectBuffer:l}=t;for(let t=i,c=i+r;t=0;let u,d;c?(u=is(t),d=rs(t,h)):(u=rs(t,h),d=is(t));const p=Js(u,a,i,r,n)?Si(u,e,s,i,r,n):null;if(p){const t=p.point[l];if(c?t<=a[d+o]:t>=a[d+o+3])return p}const m=Js(d,a,i,r,n)?Si(d,e,s,i,r,n):null;return p&&m?p.distance<=m.distance?p:m:p||m||null}}const Ai=new D,vi=new _s,Ti=new _s,Bi=new ot,ki=new Ms,Pi=new Ms;function Ci(t,e,s,i){vs.setBuffer(t._roots[e]);const r=Vi(0,t,s,i);return vs.clearBuffer(),r}function Vi(t,e,s,i,r=null){const{float32Array:n,uint16Array:a,uint32Array:o}=vs;let h=2*t;if(null===r&&(s.boundingBox||s.computeBoundingBox(),ki.set(s.boundingBox.min,s.boundingBox.max,i),r=ki),!ts(h,a)){const a=t+8,h=o[t+6];return De(a,n,Ai),r.intersectsBox(Ai)&&Vi(a,e,s,i,r)?!0:(De(h,n,Ai),!(!r.intersectsBox(Ai)||!Vi(h,e,s,i,r)))}{const r=e.geometry,l=r.index,c=r.attributes.position,u=s.index,d=s.attributes.position,p=es(t,o),m=ss(h,a);if(Bi.copy(i).invert(),s.boundsTree)return De(t,n,Pi),Pi.matrix.copy(Bi),Pi.needsUpdate=!0,s.boundsTree.shapecast({intersectsBounds:t=>Pi.intersectsBox(t),intersectsTriangle:t=>{t.a.applyMatrix4(i),t.b.applyMatrix4(i),t.c.applyMatrix4(i),t.needsUpdate=!0;for(let s=p,i=m+p;sIi.distanceToBox(t),intersectsBounds:(t,e,s)=>s{if(e.boundsTree){const o=e.boundsTree;return o.shapecast({boundsTraverseOrder:t=>Ei.distanceToBox(t),intersectsBounds:(t,e,s)=>s{for(let _=e,M=e+a;_new D),ji=new D,Hi=new D,Yi=new D,Xi=new D;let Gi=!1;function Zi(t,e,s,i,r,n=0,a=0,o=0,h=0,l=null,c=!1){let u,d;c?(u=Di,d=Wi):(u=Wi,d=Di);const p=u.float32Array,m=u.uint32Array,y=u.uint16Array,f=d.float32Array,x=d.uint32Array,g=d.uint16Array,b=2*e,w=ts(2*t,y),_=ts(b,g);let M=!1;if(_&&w)M=c?r(es(e,x),ss(2*e,g),es(t,m),ss(2*t,y),h,a+e,o,n+t):r(es(t,m),ss(2*t,y),es(e,x),ss(2*e,g),o,n+t,h,a+e);else if(_){const l=Li.getPrimitive();De(e,f,l),l.applyMatrix4(s);const u=is(t),d=rs(t,m);De(u,p,ji),De(d,p,Hi);const y=l.intersectsBox(ji),x=l.intersectsBox(Hi);M=y&&Zi(e,u,i,s,r,a,n,h,o+1,l,!c)||x&&Zi(e,d,i,s,r,a,n,h,o+1,l,!c),Li.releasePrimitive(l)}else{const u=is(e),d=rs(e,x);De(u,f,Yi),De(d,f,Xi);const y=l.intersectsBox(Yi),g=l.intersectsBox(Xi);if(y&&g)M=Zi(t,u,s,i,r,n,a,o,h+1,l,c)||Zi(t,d,s,i,r,n,a,o,h+1,l,c);else if(y)if(w)M=Zi(t,u,s,i,r,n,a,o,h+1,l,c);else{const e=Li.getPrimitive();e.copy(Yi).applyMatrix4(s);const l=is(t),d=rs(t,m);De(l,p,ji),De(d,p,Hi);const y=e.intersectsBox(ji),f=e.intersectsBox(Hi);M=y&&Zi(u,l,i,s,r,a,n,h,o+1,e,!c)||f&&Zi(u,d,i,s,r,a,n,h,o+1,e,!c),Li.releasePrimitive(e)}else if(g)if(w)M=Zi(t,d,s,i,r,n,a,o,h+1,l,c);else{const e=Li.getPrimitive();e.copy(Xi).applyMatrix4(s);const l=is(t),u=rs(t,m);De(l,p,ji),De(u,p,Hi);const y=e.intersectsBox(ji),f=e.intersectsBox(Hi);M=y&&Zi(d,l,i,s,r,a,n,h,o+1,e,!c)||f&&Zi(d,u,i,s,r,a,n,h,o+1,e,!c),Li.releasePrimitive(e)}}return M}const Ji=new Ms,$i=new D,Qi={strategy:0,maxDepth:40,maxLeafTris:10,useSharedArrayBuffer:!1,setBoundingBox:!0,onProgress:null,indirect:!1,verbose:!0,range:null};class Ki{static serialize(t,e={}){e={cloneBuffers:!0,...e};const s=t.geometry,i=t._roots,r=t._indirectBuffer,n=s.getIndex();let a;return a=e.cloneBuffers?{roots:i.map(t=>t.slice()),index:n?n.array.slice():null,indirectBuffer:r?r.slice():null}:{roots:i,index:n?n.array:null,indirectBuffer:r},a}static deserialize(t,e,s={}){s={setIndex:!0,indirect:Boolean(t.indirectBuffer),...s};const{index:i,roots:r,indirectBuffer:n}=t,a=new Ki(e,{...s,[Ne]:!0});if(a._roots=r,a._indirectBuffer=n||null,s.setIndex){const s=e.getIndex();if(null===s){const s=new re(t.index,1,!1);e.setIndex(s)}else s.array!==i&&(s.array.set(i),s.needsUpdate=!0)}return a}get indirect(){return!!this._indirectBuffer}constructor(t,e={}){if(!t.isBufferGeometry)throw new Error("MeshBVH: Only BufferGeometries are supported.");if(t.index&&t.index.isInterleavedBufferAttribute)throw new Error("MeshBVH: InterleavedBufferAttribute is not supported for the index attribute.");if((e=Object.assign({...Qi,[Ne]:!1},e)).useSharedArrayBuffer&&"undefined"==typeof SharedArrayBuffer)throw new Error("MeshBVH: SharedArrayBuffer is not available.");this.geometry=t,this._roots=null,this._indirectBuffer=null,e[Ne]||(ys(this,e),!t.boundingBox&&e.setBoundingBox&&(t.boundingBox=this.getBoundingBox(new D))),this.resolveTriangleIndex=e.indirect?t=>this._indirectBuffer[t]:t=>t}refit(t=null){return(this.indirect?bi:Zs)(this,t)}traverse(t,e=0){const s=this._roots[e],i=new Uint32Array(s),r=new Uint16Array(s);!function e(n,a=0){const o=2*n,h=r[o+15]===Ee;if(h){const e=i[n+6],l=r[o+14];t(a,h,new Float32Array(s,4*n,6),e,l)}else{const r=n+8,o=i[n+6],l=i[n+7];t(a,h,new Float32Array(s,4*n,6),l)||(e(r,a+1),e(o,a+1))}}(0)}raycast(t,e=0,s=0,i=1/0){const r=this._roots,n=this.geometry,a=[],o=e.isMaterial,h=Array.isArray(e),l=n.groups,c=o?e.side:e,u=this.indirect?wi:$s;for(let n=0,o=r.length;n!!t(i,r,n,o,h)||s(i,r,this,a,n,o,e)}else n||(n=a?(t,i,r,n)=>s(t,i,this,a,r,n,e):(t,e,s)=>s);let o=!1,h=0;const l=this._roots;for(let t=0,e=l.length;t{const e=this.resolveTriangleIndex(t);Xs(n,3*e,a,o)}:t=>{Xs(n,3*t,a,o)},l=As.getPrimitive(),c=t.geometry.index,u=t.geometry.attributes.position,d=t.indirect?e=>{const s=t.resolveTriangleIndex(e);Xs(l,3*s,c,u)}:t=>{Xs(l,3*t,c,u)};if(r){const t=(t,s,i,a,o,c,u,p)=>{for(let m=i,y=i+a;mJi.intersectsBox(t),intersectsTriangle:t=>Ji.intersectsTriangle(t)})}intersectsSphere(t){return this.shapecast({intersectsBounds:e=>t.intersectsBox(e),intersectsTriangle:e=>e.intersectsSphere(t)})}closestPointToGeometry(t,e,s={},i={},r=0,n=1/0){return(this.indirect?Ri:xi)(this,t,e,s,i,r,n)}closestPointToPoint(t,e={},s=0,i=1/0){return function(t,e,s={},i=0,r=1/0){const n=i*i,a=r*r;let o=1/0,h=null;if(t.shapecast({boundsTraverseOrder:t=>(Fs.copy(e).clamp(t.min,t.max),Fs.distanceToSquared(e)),intersectsBounds:(t,e,s)=>s{t.closestPointToPoint(e,Fs);const i=e.distanceToSquared(Fs);return i{De(0,new Float32Array(e),$i),t.union($i)}),t}}let tr;function er(t){return`#${Math.round(t.r).toString(16).padStart(2,"0")}${Math.round(t.g).toString(16).padStart(2,"0")}${Math.round(t.b).toString(16).padStart(2,"0")}`}function sr(t,e){return{r:parseInt(t.slice(1,3),16),g:parseInt(t.slice(3,5),16),b:parseInt(t.slice(5,7),16),a:e}}function ir(){if(0===Mesh.selected.length)return void Blockbench.showToastNotification({text:"No meshes selected"});if(Mesh.selected.length>1)return void Blockbench.showToastNotification({text:"Multiple meshes selected"});const t=function(){const t=localStorage.getItem("blockbench_baked_ao_settings"),e={sampleMethod:"random",highlightColor:{r:231,g:230,b:184,a:.3},shadowColor:{r:36,g:11,b:55,a:.5},samples:1e3,aoShadowSize:32,aoHighlightSize:8,retainTextureTransparency:!1,sampleTextureTransparency:!1,shadowGamma:1,highlightGamma:.5,simulateGroundPlane:!0};if(t)try{return{...e,...JSON.parse(t)}}catch(t){console.warn("Failed to parse saved AO settings, using defaults")}return e}();new Dialog("ambient_occlusion_config",{title:"Ambient Occlusion Settings",form:{highlight_color:{label:"Highlight Color",type:"color",value:er(t.highlightColor),description:"Color used for areas with high ambient lighting"},highlight_alpha:{label:"Highlight Opacity",type:"range",min:0,max:1,step:.01,value:t.highlightColor.a,description:"Opacity of the highlight color overlay"},highlight_gamma:{label:"Highlight Softness",type:"range",min:.2,max:2,step:.1,value:t.highlightGamma,description:"Gamma correction for highlight areas (lower = more contrast)"},ao_highlight_size:{label:"Highlight Size",type:"number",min:1,max:64,step:1,value:t.aoHighlightSize,description:"Ray distance for highlight detection (rays going into the surface)"},shadow_color:{label:"Shadow Color",type:"color",value:er(t.shadowColor),description:"Color used for occluded/shadowed areas"},shadow_alpha:{label:"Shadow Opacity",type:"range",min:0,max:1,step:.01,value:t.shadowColor.a,description:"Opacity of the shadow color overlay"},shadow_gamma:{label:"Shadow Softness",type:"range",min:.2,max:2,step:.1,value:t.shadowGamma,description:"Gamma correction for shadow areas (higher = softer shadows)"},ao_shadow_size:{label:"Shadow Size",type:"number",min:1,max:64,step:1,value:t.aoShadowSize,description:"Ray distance for shadow detection (rays going away from the surface)"},samples:{label:"Samples per pixel",type:"number",min:10,max:1e4,step:100,value:t.samples,description:"Number of samples per pixel (higher = better quality, slower). 100 recommended for uniform sampling, 1000 for random sampling."},sample_method:{label:"Sample Method",type:"inline_select",options:{random:"Random",uniform:"Uniform"},value:t.sampleMethod,description:"Method for sampling ambient occlusion rays. Random is slightly more accurate but noisier, uniform is smoother for less samples but is more prone to artifacts."},simulate_ground_plane:{label:"Simulate Ground Plane",type:"checkbox",value:t.simulateGroundPlane,description:"Simulate a ground plane, adding shadows at the base of the model"},retain_texture_transparency:{label:"Retain Texture Transparency",type:"checkbox",value:t.retainTextureTransparency,description:"Preserve the original transparency of textures"},sample_texture_transparency:{label:"Sample Texture Transparency",type:"checkbox",value:t.sampleTextureTransparency,description:"Consider texture transparency when calculating occlusion (slower but more accurate)"}},onConfirm:async function(t){const e={onProgress:t=>{Blockbench.setProgress(t),r.progress_bar.setProgress(t);const e=performance.now()-s,i=r.object.querySelector(".dialog_title");if(i)if(e>3e3||t>.2){const s=function(t){const e=Math.floor(t/1e3),s=Math.floor(e/60),i=e%60,r=s%60,n=Math.floor(s/60);return n>0?`${n}h ${r}m ${i}s`:r>0?`${r}m ${i}s`:`${i}s`}(e/t-e);i.textContent=`Baking Ambient Occlusion (~ ${s} remaining)`}else i.textContent="Baking Ambient Occlusion"},highlightColor:sr("#"+t.highlight_color.toHex(),t.highlight_alpha),shadowColor:sr("#"+t.shadow_color.toHex(),t.shadow_alpha),samples:t.samples,aoShadowSize:t.ao_shadow_size,aoHighlightSize:t.ao_highlight_size,retainTextureTransparency:t.retain_texture_transparency,sampleTextureTransparency:t.sample_texture_transparency,shadowGamma:t.shadow_gamma,highlightGamma:t.highlight_gamma,simulateGroundPlane:t.simulate_ground_plane,sampleMethod:t.sample_method};!function(t){localStorage.setItem("blockbench_baked_ao_settings",JSON.stringify(t))}({highlightColor:e.highlightColor,shadowColor:e.shadowColor,samples:e.samples,aoShadowSize:e.aoShadowSize,aoHighlightSize:e.aoHighlightSize,retainTextureTransparency:e.retainTextureTransparency,sampleTextureTransparency:e.sampleTextureTransparency,shadowGamma:e.shadowGamma,highlightGamma:e.highlightGamma,simulateGroundPlane:e.simulateGroundPlane,sampleMethod:e.sampleMethod});const s=performance.now(),i={cancelled:!1},r=new Dialog("bake_ambient_occlusion_loading",{title:"Baking Ambient Occlusion",progress_bar:{progress:0},cancel_on_click_outside:!1,singleButton:!0,buttons:["Cancel"],onCancel:function(){i.cancelled=!0}});r.show();try{await async function(t,e){let s=!1,i=!1,r=0,n=0;performance.mark("startAO");for(const a of Mesh.selected){let o=!1,h=0;a.forAllFaces(t=>{t.isSelected()&&(o=!0),h++});const l=await rr(a,o,t,e);s=s||l.anyMissing,i=i||l.anyWithTextures,r+=l.totalPixelsProcessed,n+=l.totalFacesProcessed}performance.mark("endAO");const a=performance.measure("AO Processing Time","startAO","endAO");console.log(`AO Processing Time: ${a.duration}ms`),i?s&&Blockbench.showToastNotification({text:"Some faces are missing textures"}):Blockbench.showToastNotification({text:"No textures found on selected meshes"})}(e,i)}finally{r.hide(),Blockbench.setProgress(0)}},buttons:["Confirm","Restore Defaults","Cancel"],onButton(t,e){1===t&&(localStorage.removeItem("blockbench_baked_ao_settings"),ir())}}).show()}async function rr(t,e,s,i){let r=!1,n=!1,a=0,o=0;const h=[];t.forAllFaces(t=>h.push(t));const l=new Map;for(const t of h){const s=t.getTexture();s?e&&!t.isSelected()||(n=!0,l.has(s)||l.set(s,[]),l.get(s).push(t)):r=!0}const[c]=function(t){if(!(t.mesh&&t.mesh instanceof THREE.Mesh))throw console.log(t),new Error("Invalid mesh object");const e=t.mesh.geometry;if(!e||!e.attributes||!e.attributes.position)throw console.log(e),new Error("Mesh does not have valid geometry attributes");const s=e.attributes.position;let i=-1/0,r=1/0;for(let t=0;ti&&(i=e),e{Object.keys(s[t]).forEach(e=>{const i=s[t][e],r=parseInt(t,10),n=parseInt(e,10);if(!0===i)for(let t=0;tsetTimeout(t,0)),o.cancelled)throw new Error("Job cancelled")}l++,a?.onProgress?.(l/e.length)}let c=0;return t.edit(t=>{const e=t.getContext("2d");for(const[t,s]of h){const[i,r]=t.split(",").map(t=>parseInt(t,10));let[n,o,h,l]=s.color;a.retainTextureTransparency&&(l*=e.getImageData(i,r,1,1).data[3]/255),e.fillStyle=`rgba(${n}, ${o}, ${h}, ${l})`,e.fillRect(i,r,1,1),c++}}),{pixelsProcessed:c,facesProcessed:e.length}}Plugin.register("baked_ambient_occlusion",{title:"Mr Salmon's Baked Ambient Occlusion",author:"Kai Salmon",description:"Baked Ambient Occlusion, creating instant shading",icon:"icon.png",version:"1.0.0",min_version:"4.8.0",variant:"both",repository:"https://github.com/kaisalmon/MrSalmonsBlockbenchBakedAmbientOcclusion",has_changelog:!1,tags:["Texture","Shading"],onload(){tr=new Action("bake_ambient_occlusion",{name:"Bake Ambient Occlusion",description:"Perform ambient occlusion baking on selected meshes",icon:"cake",click:function(){ir()}}),MenuBar.addAction(tr,"filter")},onunload(){tr.delete()}});const ar={origin:new THREE.Vector3,direction:new THREE.Vector3,normal:new THREE.Vector3};function or(t,e,s,i,r,n,a,o,h){const[l,c,u]=t,[d,p,m]=s.getNormal(!0);ar.normal.set(d,p,m);let y=0,f=0;const x=o.samples;for(let t=0;t=0?o.aoShadowSize:o.aoHighlightSize,i=new THREE.Raycaster(ar.origin,e,.001,s),d=n.raycastFirst(i.ray,THREE.DoubleSide,.001,s);if(d){const t=d.face.normal;if(ar.direction.dot(t)>0&&(f+=1),o.sampleTextureTransparency){const t=a.faceIndexToBlockbenchFace.get(d.faceIndex);if(t){const[e,s]=t.localToUV(d.point),i=t.getTexture();y+=i?i.ctx.getImageData(e,s,1,1).data[3]/255:1}else y+=1}else y+=1}else r&&i.intersectObject(r).length>0&&(y+=1)}let g=1-y/x;const b=f/x;let w,_;return g<.5?(w=2*(.5-g),w=Math.pow(w,o.shadowGamma),_=o.shadowColor):(w=2*(g-.5),w=Math.pow(w,o.highlightGamma),_=o.highlightColor),[[_.r,_.g,_.b,_.a*w],b]}function hr(t){const e={},s=Math.PI*(3-Math.sqrt(5));for(let i=0;i;
+}
+
+let button: Action;
+
+(Plugin as any).register('baked_ambient_occlusion', {
+ "title": "Mr Salmon's Baked Ambient Occlusion",
+ "author": "Kai Salmon",
+ "description": "Baked Ambient Occlusion, creating instant shading",
+ "icon": "icon.png",
+ "version": "1.0.0",
+ "min_version": "4.8.0",
+ "variant": "both",
+ "repository": "https://github.com/kaisalmon/MrSalmonsBlockbenchBakedAmbientOcclusion",
+ "has_changelog": false,
+ "tags": [
+ "Texture",
+ "Shading"
+ ],
+ onload(): void {
+ button = new Action('bake_ambient_occlusion', {
+ name: 'Bake Ambient Occlusion',
+ description: 'Perform ambient occlusion baking on selected meshes',
+ icon: 'cake',
+ click: function (): void {
+ showAmbientOcclusionDialog();
+ }
+ });
+ MenuBar.addAction(button, 'filter');
+ },
+ onunload(): void {
+ button.delete();
+ }
+});
+
+/**
+ * Convert RGB color object to hex string for color picker
+ */
+function colorToHex(color: Color): string {
+ const r = Math.round(color.r).toString(16).padStart(2, '0');
+ const g = Math.round(color.g).toString(16).padStart(2, '0');
+ const b = Math.round(color.b).toString(16).padStart(2, '0');
+ return `#${r}${g}${b}`;
+}
+
+/**
+ * Convert hex string to RGB color object
+ */
+function hexToColor(hex: string, alpha: number): Color {
+ const r = parseInt(hex.slice(1, 3), 16);
+ const g = parseInt(hex.slice(3, 5), 16);
+ const b = parseInt(hex.slice(5, 7), 16);
+ return { r, g, b, a: alpha };
+}
+
+function showAmbientOcclusionDialog(): void {
+ if (Mesh.selected.length === 0) {
+ Blockbench.showToastNotification({
+ text: 'No meshes selected',
+ });
+ return;
+ }
+ if (Mesh.selected.length > 1) {
+ Blockbench.showToastNotification({
+ text: 'Multiple meshes selected',
+ });
+ return;
+ }
+
+
+ // Load saved settings or use defaults
+ const savedSettings = getPluginSettings();
+
+ const dialog = new Dialog('ambient_occlusion_config', {
+ title: 'Ambient Occlusion Settings',
+ // width: 400,
+ form: {
+ highlight_color: {
+ label: 'Highlight Color',
+ type: 'color',
+ value: colorToHex(savedSettings.highlightColor),
+ description: 'Color used for areas with high ambient lighting'
+ },
+ highlight_alpha: {
+ label: 'Highlight Opacity',
+ type: 'range',
+ min: 0,
+ max: 1,
+ step: 0.01,
+ value: savedSettings.highlightColor.a,
+ description: 'Opacity of the highlight color overlay'
+ },
+ highlight_gamma: {
+ label: 'Highlight Softness',
+ type: 'range',
+ min: 0.2,
+ max: 2.0,
+ step: 0.1,
+ value: savedSettings.highlightGamma,
+ description: 'Gamma correction for highlight areas (lower = more contrast)'
+ },
+ ao_highlight_size: {
+ label: 'Highlight Size',
+ type: 'number',
+ min: 1,
+ max: 64,
+ step: 1,
+ value: savedSettings.aoHighlightSize,
+ description: 'Ray distance for highlight detection (rays going into the surface)'
+ },
+ shadow_color: {
+ label: 'Shadow Color',
+ type: 'color',
+ value: colorToHex(savedSettings.shadowColor),
+ description: 'Color used for occluded/shadowed areas'
+ },
+ shadow_alpha: {
+ label: 'Shadow Opacity',
+ type: 'range',
+ min: 0,
+ max: 1,
+ step: 0.01,
+ value: savedSettings.shadowColor.a,
+ description: 'Opacity of the shadow color overlay'
+ },
+ shadow_gamma: {
+ label: 'Shadow Softness',
+ type: 'range',
+ min: 0.2,
+ max: 2.0,
+ step: 0.1,
+ value: savedSettings.shadowGamma,
+ description: 'Gamma correction for shadow areas (higher = softer shadows)'
+ },
+ ao_shadow_size: {
+ label: 'Shadow Size',
+ type: 'number',
+ min: 1,
+ max: 64,
+ step: 1,
+ value: savedSettings.aoShadowSize,
+ description: 'Ray distance for shadow detection (rays going away from the surface)'
+ },
+ samples: {
+ label: 'Samples per pixel',
+ type: 'number',
+ min: 10,
+ max: 10000,
+ step: 100,
+ value: savedSettings.samples,
+ description: 'Number of samples per pixel (higher = better quality, slower). 100 recommended for uniform sampling, 1000 for random sampling.'
+ },
+ sample_method: {
+ label: 'Sample Method',
+ type: 'inline_select',
+ options: {
+ 'random': 'Random',
+ 'uniform': 'Uniform',
+ },
+ value: savedSettings.sampleMethod,
+ description: 'Method for sampling ambient occlusion rays. Random is slightly more accurate but noisier, uniform is smoother for less samples but is more prone to artifacts.'
+ },
+ simulate_ground_plane: {
+ label: 'Simulate Ground Plane',
+ type: 'checkbox',
+ value: savedSettings.simulateGroundPlane,
+ description: 'Simulate a ground plane, adding shadows at the base of the model'
+ },
+ retain_texture_transparency: {
+ label: 'Retain Texture Transparency',
+ type: 'checkbox',
+ value: savedSettings.retainTextureTransparency,
+ description: 'Preserve the original transparency of textures'
+ },
+ sample_texture_transparency: {
+ label: 'Sample Texture Transparency',
+ type: 'checkbox',
+ value: savedSettings.sampleTextureTransparency,
+ description: 'Consider texture transparency when calculating occlusion (slower but more accurate)'
+ },
+ },
+ onConfirm: async function (formResult: any) {
+ const options: BakeAmbientOcclusionOptions = {
+ onProgress: (progress: number) => {
+ Blockbench.setProgress(progress)
+ loadingDialog.progress_bar!.setProgress(progress);
+ const elapsedMs = performance.now() - startTime;
+ const dialogObject: Element = (loadingDialog as any).object;
+ const titleElem = dialogObject.querySelector('.dialog_title');
+ if (titleElem) {
+ if (elapsedMs > 3000 || progress > 0.2) {
+ const estimatedTotalMs = elapsedMs / progress;
+ const estimatedRemainingMs = estimatedTotalMs - elapsedMs;
+ const formattedTime = formatMsToReadableTime(estimatedRemainingMs);
+ titleElem.textContent = `Baking Ambient Occlusion (~ ${formattedTime} remaining)`;
+ } else {
+ titleElem.textContent = `Baking Ambient Occlusion`;
+ }
+ }
+ },
+ highlightColor: hexToColor('#' + formResult.highlight_color.toHex(), formResult.highlight_alpha),
+ shadowColor: hexToColor('#' + formResult.shadow_color.toHex(), formResult.shadow_alpha),
+ samples: formResult.samples,
+ aoShadowSize: formResult.ao_shadow_size,
+ aoHighlightSize: formResult.ao_highlight_size,
+ retainTextureTransparency: formResult.retain_texture_transparency,
+ sampleTextureTransparency: formResult.sample_texture_transparency,
+ shadowGamma: formResult.shadow_gamma,
+ highlightGamma: formResult.highlight_gamma,
+ simulateGroundPlane: formResult.simulate_ground_plane,
+ sampleMethod: formResult.sample_method
+ };
+
+ // Save settings for next session
+ savePluginSettings({
+ highlightColor: options.highlightColor,
+ shadowColor: options.shadowColor,
+ samples: options.samples,
+ aoShadowSize: options.aoShadowSize,
+ aoHighlightSize: options.aoHighlightSize,
+ retainTextureTransparency: options.retainTextureTransparency,
+ sampleTextureTransparency: options.sampleTextureTransparency,
+ shadowGamma: options.shadowGamma,
+ highlightGamma: options.highlightGamma,
+ simulateGroundPlane: options.simulateGroundPlane,
+ sampleMethod: options.sampleMethod
+ });
+
+ const startTime = performance.now();
+ const jobController = {
+ cancelled: false
+ }
+ const loadingDialog = new Dialog('bake_ambient_occlusion_loading', {
+ title: 'Baking Ambient Occlusion',
+ progress_bar: {
+ progress: 0,
+ },
+ cancel_on_click_outside: false,
+ singleButton: true,
+ buttons: ['Cancel'],
+ onCancel: function () {
+ jobController.cancelled = true;
+ }
+ });
+
+ loadingDialog.show();
+ try {
+ await bakeAmbientOcclusion(options, jobController);
+ } finally {
+ loadingDialog.hide();
+ Blockbench.setProgress(0);
+ }
+ },
+ buttons: ['Confirm', 'Restore Defaults', 'Cancel'],
+ onButton(button_index: number, e: Event): void {
+ if (button_index === 1) {
+ localStorage.removeItem('blockbench_baked_ao_settings');
+ showAmbientOcclusionDialog();
+ }
+ },
+ });
+
+ dialog.show();
+}
+
+interface BakeAmbientOcclusionOptions {
+ sampleMethod: 'random' | 'uniform';
+ onProgress?: (progress: number) => void;
+ highlightColor: Color;
+ shadowColor: Color;
+ samples: number;
+ aoShadowSize: number;
+ aoHighlightSize: number;
+ retainTextureTransparency: boolean;
+ sampleTextureTransparency: boolean;
+ shadowGamma: number;
+ highlightGamma: number;
+ simulateGroundPlane: boolean;
+}
+interface JobController {
+ cancelled: boolean;
+}
+
+async function bakeAmbientOcclusion(opts: BakeAmbientOcclusionOptions, jobController: JobController): Promise {
+ let anyMissing: boolean = false;
+ let anyWithTextures: boolean = false;
+ let pixelCount: number = 0;
+ let faceCount: number = 0;
+
+ performance.mark("startAO");
+
+ for (const mesh of Mesh.selected) {
+ let hasSelectedFaces: boolean = false;
+ let facesInMesh = 0;
+ mesh.forAllFaces((face: MeshFace) => {
+ if (face.isSelected()) {
+ hasSelectedFaces = true;
+ }
+ facesInMesh++;
+ });
+
+ // Process each face
+ const result = await processMeshFaces(mesh, hasSelectedFaces, opts, jobController);
+ anyMissing = anyMissing || result.anyMissing;
+ anyWithTextures = anyWithTextures || result.anyWithTextures;
+ pixelCount += result.totalPixelsProcessed;
+ faceCount += result.totalFacesProcessed;
+ }
+
+ performance.mark("endAO");
+ const measure: PerformanceMeasure = performance.measure("AO Processing Time", "startAO", "endAO");
+ console.log(`AO Processing Time: ${measure.duration}ms`);
+
+ if (!anyWithTextures) {
+ Blockbench.showToastNotification({
+ text: 'No textures found on selected meshes',
+ });
+ } else if (anyMissing) {
+ Blockbench.showToastNotification({
+ text: 'Some faces are missing textures',
+ });
+ }
+
+}
+
+
+function buildFaceMapping(mesh: Mesh): FaceMapping {
+ // NOTE: This code duplicates some esoteric logic in from within Blockbench
+ const faceIndexToBlockbenchFace = new Map();
+ let currentFaceIndex = 0;
+
+ for (let key in mesh.faces) {
+ const face = mesh.faces[key];
+ const vertices = face.vertices;
+
+ if (vertices.length < 3) continue;
+
+ if (vertices.length === 3) {
+ faceIndexToBlockbenchFace.set(currentFaceIndex, face);
+ currentFaceIndex += 1;
+ } else if (vertices.length === 4) {
+ faceIndexToBlockbenchFace.set(currentFaceIndex, face);
+ faceIndexToBlockbenchFace.set(currentFaceIndex + 1, face);
+ currentFaceIndex += 2;
+ }
+ }
+
+ return { faceIndexToBlockbenchFace };
+}
+
+interface ProcessMeshFacesResult {
+ anyMissing: boolean;
+ anyWithTextures: boolean;
+ totalPixelsProcessed: number;
+ totalFacesProcessed: number;
+}
+
+
+async function processMeshFaces(mesh: Mesh, hasSelectedFaces: boolean, opts: BakeAmbientOcclusionOptions, jobController: JobController): Promise {
+ let anyMissing: boolean = false;
+ let anyWithTextures: boolean = false;
+ let totalPixelsProcessed: number = 0;
+ let totalFacesProcessed = 0;
+ const faces: MeshFace[] = [];
+ mesh.forAllFaces((face: MeshFace) => faces.push(face));
+
+ // Group faces by texture
+ const facesByTexture: Map = new Map();
+
+ for (const face of faces) {
+ const tex: Texture | undefined = face.getTexture();
+ if (!tex) {
+ anyMissing = true;
+ continue;
+ }
+
+ if (hasSelectedFaces && !face.isSelected()) continue;
+
+ anyWithTextures = true;
+
+ if (!facesByTexture.has(tex)) {
+ facesByTexture.set(tex, []);
+ }
+ facesByTexture.get(tex)!.push(face);
+ }
+
+ const [lowestY]: [number, number] = getHighestAndLowestY(mesh);
+
+ const groundPlane: THREE.Mesh | null = opts.simulateGroundPlane ? createGroundPlane(lowestY) : null;
+
+ const geometry: THREE.BufferGeometry = (mesh.mesh as THREE.Mesh).geometry;
+ const geometryBackup = geometry.clone(); // Backup as BVH mutates the geometry in a way that causes bugs in Blockbench
+ const bvh: MeshBVH = new MeshBVH(geometry, {
+ indirect: true,
+ maxDepth: 1000,
+ maxLeafTris: 1,
+ });
+
+ const faceMapping = buildFaceMapping(mesh);
+
+ try {
+ for (const [texture, textureFaces] of facesByTexture) {
+ const { pixelsProcessed, facesProcessed } = await processTextureWithFaces(
+ texture, textureFaces, mesh, groundPlane, bvh, faceMapping, opts, jobController
+ );
+ totalPixelsProcessed += pixelsProcessed;
+ totalFacesProcessed += facesProcessed;
+ }
+
+ return { anyMissing, anyWithTextures, totalPixelsProcessed, totalFacesProcessed };
+ } finally {
+ (mesh.mesh as THREE.Mesh).geometry = geometryBackup;
+ }
+}
+
+function createGroundPlane(lowestY: number) {
+ const groundPlane: THREE.Mesh = new THREE.Mesh(
+ new THREE.PlaneGeometry(1000, 1000),
+ new THREE.MeshBasicMaterial({
+ color: 0x000000,
+ side: THREE.FrontSide,
+ transparent: true,
+ opacity: 0.5
+ })
+ );
+ groundPlane.rotation.set(-Math.PI / 2, 0, 0); // Rotate to be horizontal
+ groundPlane.position.setY(lowestY - 1);
+ groundPlane.updateMatrix();
+ groundPlane.updateWorldMatrix(false, false);
+ return groundPlane;
+}
+
+async function processTextureWithFaces(
+ texture: Texture,
+ faces: MeshFace[],
+ mesh: Mesh,
+ groundPlane: THREE.Mesh | null,
+ bvh: MeshBVH,
+ faceMapping: FaceMapping,
+ opts: BakeAmbientOcclusionOptions,
+ jobController: JobController
+): Promise<{
+ pixelsProcessed: number;
+ facesProcessed: number;
+}> {
+
+ const bestResults: Map = new Map();
+
+ let facesProcessed: number = 0;
+ for (const face of faces) {
+ const occupationMatrix: Record> = face.getOccupationMatrix();
+ const texture = face.getTexture();
+ if (!texture) continue;
+ const pixelDensityU = texture.width / texture.uv_width;
+ const pixelDensityV = texture.height / texture.uv_height;
+ if (pixelDensityU !== pixelDensityV) {
+ throw new Error(`Non-uniform pixel density detected for texture ${texture.name}`);
+ }
+ const pixelCoords: [number, number][] = [];
+ Object.keys(occupationMatrix).forEach((uStr: string) => {
+ Object.keys(occupationMatrix[uStr]).forEach((vStr: string) => {
+ const value: boolean = occupationMatrix[uStr][vStr];
+ const u = parseInt(uStr, 10);
+ const v = parseInt(vStr, 10);
+ if (value === true) {
+ for (let x = 0; x < pixelDensityU; x++) {
+ for (let y = 0; y < pixelDensityV; y++) {
+ pixelCoords.push([Math.floor(u * pixelDensityU + x), Math.floor(v * pixelDensityV + y)]);
+ }
+ }
+ }
+ });
+ });
+
+ let i = 0;
+ // Process pixels for this face
+ for (const [u, v] of pixelCoords) {
+ const key: string = `${u},${v}`;
+
+ // Get x,y,z in 3d space of the face at this u,v
+ let { x, y, z } = face.UVToLocal([(u + 0.5) / pixelDensityU, (v + 0.5) / pixelDensityV]);
+ const result = calculateAmbientOcclusion([x, y, z], [u, v], face, mesh, groundPlane, bvh, faceMapping, opts, generateFibonacciSpherePoints(opts.samples));
+
+ if (result) {
+ const [color, backfaceRatio] = result;
+
+ // Check if this is the best result for this pixel so far
+ const existing = bestResults.get(key);
+ if (!existing || backfaceRatio < existing.backfaceRatio) {
+ bestResults.set(key, {
+ color: color,
+ backfaceRatio: backfaceRatio
+ });
+ }
+ }
+
+ i++;
+ if (i % 32 === 0) {
+ // Yield to allow UI updates
+ await new Promise(resolve => setTimeout(resolve, 0));
+ }
+ if (jobController.cancelled) {
+ throw new Error('Job cancelled');
+ }
+ }
+ facesProcessed++;
+ opts?.onProgress?.(facesProcessed / faces.length);
+ }
+
+ let processedPixels: number = 0;
+ texture.edit((htmlCanvasElement: HTMLCanvasElement) => {
+ const ctx: CanvasRenderingContext2D = htmlCanvasElement.getContext('2d')!;
+
+ for (const [pixelKey, result] of bestResults) {
+ const [u, v] = pixelKey.split(',').map(x => parseInt(x, 10));
+ let [r, g, b, a] = result.color;
+
+ if (opts.retainTextureTransparency) {
+ const srcAlpha = ctx.getImageData(u, v, 1, 1).data[3];
+ a *= srcAlpha / 255;
+ }
+
+ ctx.fillStyle = `rgba(${r}, ${g}, ${b}, ${a})`;
+ ctx.fillRect(u, v, 1, 1);
+ processedPixels++;
+ }
+ });
+
+ return {
+ pixelsProcessed: processedPixels,
+ facesProcessed: faces.length
+ };
+}
+
+const vectorPool: VectorPool = {
+ origin: new THREE.Vector3(),
+ direction: new THREE.Vector3(),
+ normal: new THREE.Vector3()
+};
+
+
+function calculateAmbientOcclusion(
+ position: [number, number, number],
+ uv: [number, number],
+ face: MeshFace,
+ mesh: Mesh,
+ groundPlane: THREE.Mesh | null,
+ bvh: MeshBVH,
+ faceMapping: FaceMapping,
+ opts: BakeAmbientOcclusionOptions,
+ spherePoints: Record,
+): [[number, number, number, number], number] | null {
+ const [x, y, z]: [number, number, number] = position;
+ const [normalX, normalY, normalZ]: [number, number, number] = face.getNormal(true);
+
+ vectorPool.normal.set(normalX, normalY, normalZ);
+
+ let occlusion: number = 0;
+ let backfaceHits: number = 0;
+ const rayCount: number = opts.samples;
+
+ for (let i: number = 0; i < rayCount; i++) {
+ let direction: THREE.Vector3;
+ vectorPool.origin.set(x, y, z)
+ .addScaledVector(vectorPool.normal, 0.5);
+ if (opts.sampleMethod === 'random') {
+ vectorPool.origin.x += (Math.random() - 0.5) * 0.5
+ vectorPool.origin.y += (Math.random() - 0.5) * 0.5;
+ vectorPool.origin.z += (Math.random() - 0.5) * 0.5;
+ vectorPool.direction.set(
+ (Math.random() - 0.5) * 2,
+ (Math.random() - 0.5) * 2,
+ (Math.random() - 0.5) * 2
+ ).normalize();
+ direction = vectorPool.direction;
+ } else {
+ direction = spherePoints[i];
+ }
+ const rayDot = direction.dot(vectorPool.normal);
+ const radius = rayDot >= 0 ? opts.aoShadowSize : opts.aoHighlightSize;
+ const raycaster: THREE.Raycaster = new THREE.Raycaster(vectorPool.origin, direction, 0.001, radius);
+
+ const hit = bvh.raycastFirst(raycaster.ray, THREE.DoubleSide, 0.001, radius);
+ if (hit) {
+ const faceNormal = hit.face!.normal!;
+ const dot = vectorPool.direction.dot(faceNormal);
+ if (dot > 0) {
+ backfaceHits += 1;
+ }
+ if (!opts.sampleTextureTransparency) {
+ occlusion += 1;
+ } else {
+ // Use the optimized face lookup instead of the expensive linear search
+ const blockbenchFace = faceMapping.faceIndexToBlockbenchFace.get(hit.faceIndex!);
+ if (blockbenchFace) {
+ const [hitU, hitV] = blockbenchFace.localToUV(hit.point!);
+ const texture: Texture | undefined = blockbenchFace.getTexture();
+ if (texture) {
+ const pixelColor: ImageData = texture.ctx.getImageData(hitU, hitV, 1, 1);
+ occlusion += pixelColor.data[3] / 255;
+ } else {
+ occlusion += 1;
+ }
+ } else {
+ // Fallback to 1 if face not found (shouldn't happen with proper mapping)
+ occlusion += 1;
+ }
+ }
+ } else {
+ // Check if the ray intersects the ground plane
+ const groundPlaneHit = groundPlane && raycaster.intersectObject(groundPlane).length > 0;
+ if (groundPlaneHit) {
+ occlusion += 1;
+ }
+ }
+ }
+
+ let occlusionFactor: number = 1 - occlusion / rayCount;
+ const backfaceRatio = backfaceHits / rayCount;
+
+ let t: number;
+ let color: Color;
+
+ if (occlusionFactor < 0.5) {
+ t = (0.5 - occlusionFactor) * 2;
+ t = Math.pow(t, opts.shadowGamma);
+ color = opts.shadowColor;
+ } else {
+ t = (occlusionFactor - 0.5) * 2;
+ t = Math.pow(t, opts.highlightGamma);
+ color = opts.highlightColor;
+ }
+
+ return [
+ [color.r, color.g, color.b, color.a * t],
+ backfaceRatio
+ ];
+}
+
+/**
+ * Get the highest and lowest Y coordinates of all vertices in a mesh
+ * @param mesh - The mesh to analyze
+ * @returns [lowestY, highestY]
+ */
+function getHighestAndLowestY(mesh: Mesh): [number, number] {
+
+ if (!mesh.mesh || !(mesh.mesh instanceof THREE.Mesh)) {
+ console.log(mesh);
+ throw new Error('Invalid mesh object');
+ }
+
+ const geometry = mesh.mesh.geometry;
+
+ if (!geometry || !geometry.attributes || !geometry.attributes.position) {
+ console.log(geometry);
+ throw new Error('Mesh does not have valid geometry attributes');
+ }
+
+ const positionAttribute: THREE.BufferAttribute = geometry.attributes.position as THREE.BufferAttribute;
+ let highestY: number = -Infinity;
+ let lowestY: number = Infinity;
+
+ for (let i: number = 0; i < positionAttribute.count; i++) {
+ const y: number = positionAttribute.getY(i);
+ if (y > highestY) highestY = y;
+ if (y < lowestY) lowestY = y;
+ }
+
+ return [lowestY, highestY];
+}
+
+function formatMsToReadableTime(estimatedRemainingMs: number) {
+ const totalSeconds = Math.floor(estimatedRemainingMs / 1000);
+ const totalMinutes = Math.floor(totalSeconds / 60);
+ const seconds = totalSeconds % 60;
+ const minutes = totalMinutes % 60;
+ const hours = Math.floor(totalMinutes / 60);
+ if (hours > 0) {
+ return `${hours}h ${minutes}m ${seconds}s`;
+ }
+ if (minutes > 0) {
+ return `${minutes}m ${seconds}s`;
+ }
+ return `${seconds}s`;
+}
+
+function generateFibonacciSpherePoints(n: number): Record {
+ const points: Record = {};
+ const phi = Math.PI * (3 - Math.sqrt(5)); // Golden angle in radians
+ for (let i = 0; i < n; i++) {
+ const y = 1 - (i / (n - 1)) * 2; // y goes from 1 to -1
+ const radius = Math.sqrt(1 - y * y); // Radius at y
+ const theta = phi * i; // Golden angle increment
+ points[i] = new THREE.Vector3(
+ radius * Math.cos(theta),
+ y,
+ radius * Math.sin(theta)
+ );
+ }
+ return points;
+}
+
+function getPluginSettings(): BakeAmbientOcclusionOptions {
+ const savedSettings = localStorage.getItem('blockbench_baked_ao_settings');
+ const defaultSettings = {
+ sampleMethod: 'random' as 'random' | 'uniform',
+ highlightColor: { r: 231, g: 230, b: 184, a: 0.3 },
+ shadowColor: { r: 36, g: 11, b: 55, a: 0.5 },
+ samples: 1000,
+ aoShadowSize: 32,
+ aoHighlightSize: 8,
+ retainTextureTransparency: false,
+ sampleTextureTransparency: false,
+ shadowGamma: 1.0,
+ highlightGamma: 0.5,
+ simulateGroundPlane: true
+ };
+
+ if (savedSettings) {
+ try {
+ return { ...defaultSettings, ...JSON.parse(savedSettings) };
+ } catch (e) {
+ console.warn('Failed to parse saved AO settings, using defaults');
+ }
+ }
+
+ return defaultSettings;
+}
+
+function savePluginSettings(options: Partial): void {
+ localStorage.setItem('blockbench_baked_ao_settings', JSON.stringify(options));
+}
\ No newline at end of file
diff --git a/plugins/baked_ambient_occlusion/src/types.d.ts b/plugins/baked_ambient_occlusion/src/types.d.ts
new file mode 100644
index 00000000..a25182df
--- /dev/null
+++ b/plugins/baked_ambient_occlusion/src/types.d.ts
@@ -0,0 +1,5 @@
+declare namespace Blockbench {
+ type Mesh = import('blockbench-types').Mesh;
+ type Texture = import('blockbench-types').Texture;
+ type MeshFace = import('blockbench-types').MeshFace;
+}
\ No newline at end of file
diff --git a/plugins/baked_ambient_occlusion/tsconfig.json b/plugins/baked_ambient_occlusion/tsconfig.json
new file mode 100644
index 00000000..eabd32f3
--- /dev/null
+++ b/plugins/baked_ambient_occlusion/tsconfig.json
@@ -0,0 +1,25 @@
+{
+ "compilerOptions": {
+ "target": "ES2020",
+ "module": "ESNext",
+ "moduleResolution": "node",
+ "strict": true,
+ "esModuleInterop": true,
+ "skipLibCheck": true,
+ "forceConsistentCasingInFileNames": true,
+ "declaration": false,
+ "outDir": "dist",
+ "rootDir": "src",
+ "resolveJsonModule": true,
+ "allowSyntheticDefaultImports": true,
+ "lib": ["ES2020", "DOM"],
+ "types": ["blockbench-types"]
+ },
+ "include": [
+ "src/**/*"
+ ],
+ "exclude": [
+ "node_modules",
+ "dist"
+ ]
+}
\ No newline at end of file
diff --git a/plugins/baked_ambient_occlusion/webpack.config.js b/plugins/baked_ambient_occlusion/webpack.config.js
new file mode 100644
index 00000000..30ea8ab6
--- /dev/null
+++ b/plugins/baked_ambient_occlusion/webpack.config.js
@@ -0,0 +1,32 @@
+const path = require('path');
+
+module.exports = {
+ entry: './src/index.ts',
+ module: {
+ rules: [
+ {
+ test: /\.tsx?$/,
+ use: 'ts-loader',
+ exclude: /node_modules/,
+ },
+ ],
+ },
+ resolve: {
+ extensions: ['.tsx', '.ts', '.js'],
+ },
+ output: {
+ filename: 'baked_ambient_occlusion.js',
+ path: path.resolve(__dirname, 'dist'),
+ library: {
+ type: 'umd',
+ },
+ globalObject: 'this',
+ },
+ externals: {
+ // These are provided by Blockbench globally
+ 'blockbench': 'Blockbench',
+ },
+ optimization: {
+ minimize: true,
+ },
+};
\ No newline at end of file
diff --git a/plugins/baked_ambient_occlusion/yarn.lock b/plugins/baked_ambient_occlusion/yarn.lock
new file mode 100644
index 00000000..64b050de
--- /dev/null
+++ b/plugins/baked_ambient_occlusion/yarn.lock
@@ -0,0 +1,1566 @@
+# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
+# yarn lockfile v1
+
+
+"@babel/helper-string-parser@^7.27.1":
+ version "7.27.1"
+ resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz#54da796097ab19ce67ed9f88b47bb2ec49367687"
+ integrity sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==
+
+"@babel/helper-validator-identifier@^7.27.1":
+ version "7.27.1"
+ resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz#a7054dcc145a967dd4dc8fee845a57c1316c9df8"
+ integrity sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==
+
+"@babel/parser@^7.18.4":
+ version "7.28.3"
+ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.28.3.tgz#d2d25b814621bca5fe9d172bc93792547e7a2a71"
+ integrity sha512-7+Ey1mAgYqFAx2h0RuoxcQT5+MlG3GTV0TQrgr7/ZliKsm/MNDxVVutlWaziMq7wJNAz8MTqz55XLpWvva6StA==
+ dependencies:
+ "@babel/types" "^7.28.2"
+
+"@babel/types@^7.20.7", "@babel/types@^7.28.2":
+ version "7.28.2"
+ resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.28.2.tgz#da9db0856a9a88e0a13b019881d7513588cf712b"
+ integrity sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==
+ dependencies:
+ "@babel/helper-string-parser" "^7.27.1"
+ "@babel/helper-validator-identifier" "^7.27.1"
+
+"@discoveryjs/json-ext@^0.5.0":
+ version "0.5.7"
+ resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70"
+ integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==
+
+"@electron/get@^2.0.0":
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/@electron/get/-/get-2.0.3.tgz#fba552683d387aebd9f3fcadbcafc8e12ee4f960"
+ integrity sha512-Qkzpg2s9GnVV2I2BjRksUi43U5e6+zaQMcjoJy0C+C5oxaKl+fmckGDQFtRpZpZV0NQekuZZ+tGz7EA9TVnQtQ==
+ dependencies:
+ debug "^4.1.1"
+ env-paths "^2.2.0"
+ fs-extra "^8.1.0"
+ got "^11.8.5"
+ progress "^2.0.3"
+ semver "^6.2.0"
+ sumchecker "^3.0.1"
+ optionalDependencies:
+ global-agent "^3.0.0"
+
+"@jridgewell/gen-mapping@^0.3.5":
+ version "0.3.13"
+ resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz#6342a19f44347518c93e43b1ac69deb3c4656a1f"
+ integrity sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==
+ dependencies:
+ "@jridgewell/sourcemap-codec" "^1.5.0"
+ "@jridgewell/trace-mapping" "^0.3.24"
+
+"@jridgewell/resolve-uri@^3.1.0":
+ version "3.1.2"
+ resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6"
+ integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==
+
+"@jridgewell/source-map@^0.3.3":
+ version "0.3.11"
+ resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.11.tgz#b21835cbd36db656b857c2ad02ebd413cc13a9ba"
+ integrity sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==
+ dependencies:
+ "@jridgewell/gen-mapping" "^0.3.5"
+ "@jridgewell/trace-mapping" "^0.3.25"
+
+"@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.5.0":
+ version "1.5.5"
+ resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz#6912b00d2c631c0d15ce1a7ab57cd657f2a8f8ba"
+ integrity sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==
+
+"@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25":
+ version "0.3.30"
+ resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.30.tgz#4a76c4daeee5df09f5d3940e087442fb36ce2b99"
+ integrity sha512-GQ7Nw5G2lTu/BtHTKfXhKHok2WGetd4XYcVKGx00SjAk8GMwgJM3zr6zORiPGuOE+/vkc90KtTosSSvaCjKb2Q==
+ dependencies:
+ "@jridgewell/resolve-uri" "^3.1.0"
+ "@jridgewell/sourcemap-codec" "^1.4.14"
+
+"@sindresorhus/is@^4.0.0":
+ version "4.6.0"
+ resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.6.0.tgz#3c7c9c46e678feefe7a2e5bb609d3dbd665ffb3f"
+ integrity sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==
+
+"@szmarczak/http-timer@^4.0.5":
+ version "4.0.6"
+ resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-4.0.6.tgz#b4a914bb62e7c272d4e5989fe4440f812ab1d807"
+ integrity sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==
+ dependencies:
+ defer-to-connect "^2.0.0"
+
+"@types/cacheable-request@^6.0.1":
+ version "6.0.3"
+ resolved "https://registry.yarnpkg.com/@types/cacheable-request/-/cacheable-request-6.0.3.tgz#a430b3260466ca7b5ca5bfd735693b36e7a9d183"
+ integrity sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==
+ dependencies:
+ "@types/http-cache-semantics" "*"
+ "@types/keyv" "^3.1.4"
+ "@types/node" "*"
+ "@types/responselike" "^1.0.0"
+
+"@types/dompurify@^3.0.5":
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/@types/dompurify/-/dompurify-3.2.0.tgz#56610bf3e4250df57744d61fbd95422e07dfb840"
+ integrity sha512-Fgg31wv9QbLDA0SpTOXO3MaxySc4DKGLi8sna4/Utjo4r3ZRPdCt4UQee8BWr+Q5z21yifghREPJGYaEOEIACg==
+ dependencies:
+ dompurify "*"
+
+"@types/eslint-scope@^3.7.7":
+ version "3.7.7"
+ resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.7.tgz#3108bd5f18b0cdb277c867b3dd449c9ed7079ac5"
+ integrity sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==
+ dependencies:
+ "@types/eslint" "*"
+ "@types/estree" "*"
+
+"@types/eslint@*":
+ version "9.6.1"
+ resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-9.6.1.tgz#d5795ad732ce81715f27f75da913004a56751584"
+ integrity sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==
+ dependencies:
+ "@types/estree" "*"
+ "@types/json-schema" "*"
+
+"@types/estree@*", "@types/estree@^1.0.8":
+ version "1.0.8"
+ resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.8.tgz#958b91c991b1867ced318bedea0e215ee050726e"
+ integrity sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==
+
+"@types/http-cache-semantics@*":
+ version "4.0.4"
+ resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz#b979ebad3919799c979b17c72621c0bc0a31c6c4"
+ integrity sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==
+
+"@types/jquery@^3.5.32":
+ version "3.5.32"
+ resolved "https://registry.yarnpkg.com/@types/jquery/-/jquery-3.5.32.tgz#3eb0da20611b92c7c49ebed6163b52a4fdc57def"
+ integrity sha512-b9Xbf4CkMqS02YH8zACqN1xzdxc3cO735Qe5AbSUFmyOiaWAbcpqh9Wna+Uk0vgACvoQHpWDg2rGdHkYPLmCiQ==
+ dependencies:
+ "@types/sizzle" "*"
+
+"@types/json-schema@*", "@types/json-schema@^7.0.15", "@types/json-schema@^7.0.9":
+ version "7.0.15"
+ resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841"
+ integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==
+
+"@types/keyv@^3.1.4":
+ version "3.1.4"
+ resolved "https://registry.yarnpkg.com/@types/keyv/-/keyv-3.1.4.tgz#3ccdb1c6751b0c7e52300bcdacd5bcbf8faa75b6"
+ integrity sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==
+ dependencies:
+ "@types/node" "*"
+
+"@types/node@*":
+ version "24.2.1"
+ resolved "https://registry.yarnpkg.com/@types/node/-/node-24.2.1.tgz#83e41543f0a518e006594bb394e2cd961de56727"
+ integrity sha512-DRh5K+ka5eJic8CjH7td8QpYEV6Zo10gfRkjHCO3weqZHWDtAaSTFtl4+VMqOJ4N5jcuhZ9/l+yy8rVgw7BQeQ==
+ dependencies:
+ undici-types "~7.10.0"
+
+"@types/node@^20.9.0":
+ version "20.19.11"
+ resolved "https://registry.yarnpkg.com/@types/node/-/node-20.19.11.tgz#728cab53092bd5f143beed7fbba7ba99de3c16c4"
+ integrity sha512-uug3FEEGv0r+jrecvUUpbY8lLisvIjg6AAic6a2bSP5OEOLeJsDSnvhCDov7ipFFMXS3orMpzlmi0ZcuGkBbow==
+ dependencies:
+ undici-types "~6.21.0"
+
+"@types/prismjs@^1.26.0":
+ version "1.26.5"
+ resolved "https://registry.yarnpkg.com/@types/prismjs/-/prismjs-1.26.5.tgz#72499abbb4c4ec9982446509d2f14fb8483869d6"
+ integrity sha512-AUZTa7hQ2KY5L7AmtSiqxlhWxb4ina0yd8hNbl4TWuqnv/pFP0nDMb3YrfSBf4hJVGLh2YEIBfKaBW/9UEl6IQ==
+
+"@types/responselike@^1.0.0":
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/@types/responselike/-/responselike-1.0.3.tgz#cc29706f0a397cfe6df89debfe4bf5cea159db50"
+ integrity sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==
+ dependencies:
+ "@types/node" "*"
+
+"@types/sizzle@*":
+ version "2.3.9"
+ resolved "https://registry.yarnpkg.com/@types/sizzle/-/sizzle-2.3.9.tgz#d4597dbd4618264c414d7429363e3f50acb66ea2"
+ integrity sha512-xzLEyKB50yqCUPUJkIsrVvoWNfFUbIZI+RspLWt8u+tIW/BetMBZtgV2LY/2o+tYH8dRvQ+eoPf3NdhQCcLE2w==
+
+"@types/stats.js@*":
+ version "0.17.4"
+ resolved "https://registry.yarnpkg.com/@types/stats.js/-/stats.js-0.17.4.tgz#1933e5ff153a23c7664487833198d685c22e791e"
+ integrity sha512-jIBvWWShCvlBqBNIZt0KAshWpvSjhkwkEu4ZUcASoAvhmrgAUI2t1dXrjSL4xXVLB4FznPrIsX3nKXFl/Dt4vA==
+
+"@types/three@^0.129.2":
+ version "0.129.2"
+ resolved "https://registry.yarnpkg.com/@types/three/-/three-0.129.2.tgz#26d9e4ecffc8e31becfb119c494123f343f31f8f"
+ integrity sha512-fZDNRtUFnq3baNjDiAzi4QoHYcczWtEdsduH/tpiwk91fbVk8COJiT/iLoN3tIOjLKMySoYsjUfP0VTmUfZKLw==
+
+"@types/three@^0.160.0":
+ version "0.160.0"
+ resolved "https://registry.yarnpkg.com/@types/three/-/three-0.160.0.tgz#7915a97e0a14ccaa9ccbb9f190c5730b04a23075"
+ integrity sha512-jWlbUBovicUKaOYxzgkLlhkiEQJkhCVvg4W2IYD2trqD2om3VK4DGLpHH5zQHNr7RweZK/5re/4IVhbhvxbV9w==
+ dependencies:
+ "@types/stats.js" "*"
+ "@types/webxr" "*"
+ fflate "~0.6.10"
+ meshoptimizer "~0.18.1"
+
+"@types/tinycolor2@^1.4.6":
+ version "1.4.6"
+ resolved "https://registry.yarnpkg.com/@types/tinycolor2/-/tinycolor2-1.4.6.tgz#670cbc0caf4e58dd61d1e3a6f26386e473087f06"
+ integrity sha512-iEN8J0BoMnsWBqjVbWH/c0G0Hh7O21lpR2/+PrvAVgWdzL7eexIFm4JN/Wn10PTcmNdtS6U67r499mlWMXOxNw==
+
+"@types/trusted-types@^2.0.7":
+ version "2.0.7"
+ resolved "https://registry.yarnpkg.com/@types/trusted-types/-/trusted-types-2.0.7.tgz#baccb07a970b91707df3a3e8ba6896c57ead2d11"
+ integrity sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==
+
+"@types/webxr@*":
+ version "0.5.22"
+ resolved "https://registry.yarnpkg.com/@types/webxr/-/webxr-0.5.22.tgz#d8a14c12bbfaaa4a13de21ec2d4a8197b3e1b532"
+ integrity sha512-Vr6Stjv5jPRqH690f5I5GLjVk8GSsoQSYJ2FVd/3jJF7KaqfwPi3ehfBS96mlQ2kPCwZaX6U0rG2+NGHBKkA/A==
+
+"@types/yauzl@^2.9.1":
+ version "2.10.3"
+ resolved "https://registry.yarnpkg.com/@types/yauzl/-/yauzl-2.10.3.tgz#e9b2808b4f109504a03cda958259876f61017999"
+ integrity sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==
+ dependencies:
+ "@types/node" "*"
+
+"@vue/compiler-sfc@2.7.14":
+ version "2.7.14"
+ resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-2.7.14.tgz#3446fd2fbb670d709277fc3ffa88efc5e10284fd"
+ integrity sha512-aNmNHyLPsw+sVvlQFQ2/8sjNuLtK54TC6cuKnVzAY93ks4ZBrvwQSnkkIh7bsbNhum5hJBS00wSDipQ937f5DA==
+ dependencies:
+ "@babel/parser" "^7.18.4"
+ postcss "^8.4.14"
+ source-map "^0.6.1"
+
+"@webassemblyjs/ast@1.14.1", "@webassemblyjs/ast@^1.14.1":
+ version "1.14.1"
+ resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.14.1.tgz#a9f6a07f2b03c95c8d38c4536a1fdfb521ff55b6"
+ integrity sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==
+ dependencies:
+ "@webassemblyjs/helper-numbers" "1.13.2"
+ "@webassemblyjs/helper-wasm-bytecode" "1.13.2"
+
+"@webassemblyjs/floating-point-hex-parser@1.13.2":
+ version "1.13.2"
+ resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz#fcca1eeddb1cc4e7b6eed4fc7956d6813b21b9fb"
+ integrity sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==
+
+"@webassemblyjs/helper-api-error@1.13.2":
+ version "1.13.2"
+ resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz#e0a16152248bc38daee76dd7e21f15c5ef3ab1e7"
+ integrity sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==
+
+"@webassemblyjs/helper-buffer@1.14.1":
+ version "1.14.1"
+ resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz#822a9bc603166531f7d5df84e67b5bf99b72b96b"
+ integrity sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==
+
+"@webassemblyjs/helper-numbers@1.13.2":
+ version "1.13.2"
+ resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz#dbd932548e7119f4b8a7877fd5a8d20e63490b2d"
+ integrity sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==
+ dependencies:
+ "@webassemblyjs/floating-point-hex-parser" "1.13.2"
+ "@webassemblyjs/helper-api-error" "1.13.2"
+ "@xtuc/long" "4.2.2"
+
+"@webassemblyjs/helper-wasm-bytecode@1.13.2":
+ version "1.13.2"
+ resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz#e556108758f448aae84c850e593ce18a0eb31e0b"
+ integrity sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==
+
+"@webassemblyjs/helper-wasm-section@1.14.1":
+ version "1.14.1"
+ resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz#9629dda9c4430eab54b591053d6dc6f3ba050348"
+ integrity sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==
+ dependencies:
+ "@webassemblyjs/ast" "1.14.1"
+ "@webassemblyjs/helper-buffer" "1.14.1"
+ "@webassemblyjs/helper-wasm-bytecode" "1.13.2"
+ "@webassemblyjs/wasm-gen" "1.14.1"
+
+"@webassemblyjs/ieee754@1.13.2":
+ version "1.13.2"
+ resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz#1c5eaace1d606ada2c7fd7045ea9356c59ee0dba"
+ integrity sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==
+ dependencies:
+ "@xtuc/ieee754" "^1.2.0"
+
+"@webassemblyjs/leb128@1.13.2":
+ version "1.13.2"
+ resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.13.2.tgz#57c5c3deb0105d02ce25fa3fd74f4ebc9fd0bbb0"
+ integrity sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==
+ dependencies:
+ "@xtuc/long" "4.2.2"
+
+"@webassemblyjs/utf8@1.13.2":
+ version "1.13.2"
+ resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.13.2.tgz#917a20e93f71ad5602966c2d685ae0c6c21f60f1"
+ integrity sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==
+
+"@webassemblyjs/wasm-edit@^1.14.1":
+ version "1.14.1"
+ resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz#ac6689f502219b59198ddec42dcd496b1004d597"
+ integrity sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==
+ dependencies:
+ "@webassemblyjs/ast" "1.14.1"
+ "@webassemblyjs/helper-buffer" "1.14.1"
+ "@webassemblyjs/helper-wasm-bytecode" "1.13.2"
+ "@webassemblyjs/helper-wasm-section" "1.14.1"
+ "@webassemblyjs/wasm-gen" "1.14.1"
+ "@webassemblyjs/wasm-opt" "1.14.1"
+ "@webassemblyjs/wasm-parser" "1.14.1"
+ "@webassemblyjs/wast-printer" "1.14.1"
+
+"@webassemblyjs/wasm-gen@1.14.1":
+ version "1.14.1"
+ resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz#991e7f0c090cb0bb62bbac882076e3d219da9570"
+ integrity sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==
+ dependencies:
+ "@webassemblyjs/ast" "1.14.1"
+ "@webassemblyjs/helper-wasm-bytecode" "1.13.2"
+ "@webassemblyjs/ieee754" "1.13.2"
+ "@webassemblyjs/leb128" "1.13.2"
+ "@webassemblyjs/utf8" "1.13.2"
+
+"@webassemblyjs/wasm-opt@1.14.1":
+ version "1.14.1"
+ resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz#e6f71ed7ccae46781c206017d3c14c50efa8106b"
+ integrity sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==
+ dependencies:
+ "@webassemblyjs/ast" "1.14.1"
+ "@webassemblyjs/helper-buffer" "1.14.1"
+ "@webassemblyjs/wasm-gen" "1.14.1"
+ "@webassemblyjs/wasm-parser" "1.14.1"
+
+"@webassemblyjs/wasm-parser@1.14.1", "@webassemblyjs/wasm-parser@^1.14.1":
+ version "1.14.1"
+ resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz#b3e13f1893605ca78b52c68e54cf6a865f90b9fb"
+ integrity sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==
+ dependencies:
+ "@webassemblyjs/ast" "1.14.1"
+ "@webassemblyjs/helper-api-error" "1.13.2"
+ "@webassemblyjs/helper-wasm-bytecode" "1.13.2"
+ "@webassemblyjs/ieee754" "1.13.2"
+ "@webassemblyjs/leb128" "1.13.2"
+ "@webassemblyjs/utf8" "1.13.2"
+
+"@webassemblyjs/wast-printer@1.14.1":
+ version "1.14.1"
+ resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz#3bb3e9638a8ae5fdaf9610e7a06b4d9f9aa6fe07"
+ integrity sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==
+ dependencies:
+ "@webassemblyjs/ast" "1.14.1"
+ "@xtuc/long" "4.2.2"
+
+"@webpack-cli/configtest@^2.1.1":
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/@webpack-cli/configtest/-/configtest-2.1.1.tgz#3b2f852e91dac6e3b85fb2a314fb8bef46d94646"
+ integrity sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==
+
+"@webpack-cli/info@^2.0.2":
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/@webpack-cli/info/-/info-2.0.2.tgz#cc3fbf22efeb88ff62310cf885c5b09f44ae0fdd"
+ integrity sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==
+
+"@webpack-cli/serve@^2.0.5":
+ version "2.0.5"
+ resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-2.0.5.tgz#325db42395cd49fe6c14057f9a900e427df8810e"
+ integrity sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==
+
+"@xtuc/ieee754@^1.2.0":
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790"
+ integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==
+
+"@xtuc/long@4.2.2":
+ version "4.2.2"
+ resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d"
+ integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==
+
+acorn-import-phases@^1.0.3:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz#16eb850ba99a056cb7cbfe872ffb8972e18c8bd7"
+ integrity sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==
+
+acorn@^8.14.0, acorn@^8.15.0:
+ version "8.15.0"
+ resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.15.0.tgz#a360898bc415edaac46c8241f6383975b930b816"
+ integrity sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==
+
+ajv-formats@^2.1.1:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-2.1.1.tgz#6e669400659eb74973bbf2e33327180a0996b520"
+ integrity sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==
+ dependencies:
+ ajv "^8.0.0"
+
+ajv-keywords@^5.1.0:
+ version "5.1.0"
+ resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-5.1.0.tgz#69d4d385a4733cdbeab44964a1170a88f87f0e16"
+ integrity sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==
+ dependencies:
+ fast-deep-equal "^3.1.3"
+
+ajv@^8.0.0, ajv@^8.9.0:
+ version "8.17.1"
+ resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.17.1.tgz#37d9a5c776af6bc92d7f4f9510eba4c0a60d11a6"
+ integrity sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==
+ dependencies:
+ fast-deep-equal "^3.1.3"
+ fast-uri "^3.0.1"
+ json-schema-traverse "^1.0.0"
+ require-from-string "^2.0.2"
+
+ansi-styles@^4.1.0:
+ version "4.3.0"
+ resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937"
+ integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==
+ dependencies:
+ color-convert "^2.0.1"
+
+blockbench-types@^4.12.2:
+ version "4.12.2"
+ resolved "https://registry.yarnpkg.com/blockbench-types/-/blockbench-types-4.12.2.tgz#fb5bd91d4de17b6c8b91b5df603e9f65ca5e6116"
+ integrity sha512-OkqlV5RO5PAV7fkix9MfVZD1bomJpw33q7vUwA0Otekd3N2Cf+f0im0diHjsZiFACmvApMfa60jajNlD6Cqj3A==
+ dependencies:
+ "@babel/types" "^7.20.7"
+ "@types/dompurify" "^3.0.5"
+ "@types/jquery" "^3.5.32"
+ "@types/prismjs" "^1.26.0"
+ "@types/three" "^0.129.2"
+ "@types/tinycolor2" "^1.4.6"
+ dompurify "^3.0.1"
+ electron "^33.3.1"
+ prismjs "^1.29.0"
+ tinycolor2 "^1.6.0"
+ typescript "^4.9.5"
+ vue "2.7.14"
+ wintersky "^1.3.0"
+
+boolean@^3.0.1:
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/boolean/-/boolean-3.2.0.tgz#9e5294af4e98314494cbb17979fa54ca159f116b"
+ integrity sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==
+
+braces@^3.0.3:
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789"
+ integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==
+ dependencies:
+ fill-range "^7.1.1"
+
+browserslist@^4.24.0:
+ version "4.25.2"
+ resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.25.2.tgz#90c1507143742d743544ae6e92bca3348adff667"
+ integrity sha512-0si2SJK3ooGzIawRu61ZdPCO1IncZwS8IzuX73sPZsXW6EQ/w/DAfPyKI8l1ETTCr2MnvqWitmlCUxgdul45jA==
+ dependencies:
+ caniuse-lite "^1.0.30001733"
+ electron-to-chromium "^1.5.199"
+ node-releases "^2.0.19"
+ update-browserslist-db "^1.1.3"
+
+buffer-crc32@~0.2.3:
+ version "0.2.13"
+ resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242"
+ integrity sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==
+
+buffer-from@^1.0.0:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5"
+ integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==
+
+cacheable-lookup@^5.0.3:
+ version "5.0.4"
+ resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz#5a6b865b2c44357be3d5ebc2a467b032719a7005"
+ integrity sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==
+
+cacheable-request@^7.0.2:
+ version "7.0.4"
+ resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-7.0.4.tgz#7a33ebf08613178b403635be7b899d3e69bbe817"
+ integrity sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==
+ dependencies:
+ clone-response "^1.0.2"
+ get-stream "^5.1.0"
+ http-cache-semantics "^4.0.0"
+ keyv "^4.0.0"
+ lowercase-keys "^2.0.0"
+ normalize-url "^6.0.1"
+ responselike "^2.0.0"
+
+caniuse-lite@^1.0.30001733:
+ version "1.0.30001735"
+ resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001735.tgz#ba658fd3fd24a4106fd68d5ce472a2c251494dbe"
+ integrity sha512-EV/laoX7Wq2J9TQlyIXRxTJqIw4sxfXS4OYgudGxBYRuTv0q7AM6yMEpU/Vo1I94thg9U6EZ2NfZx9GJq83u7w==
+
+chalk@^4.1.0:
+ version "4.1.2"
+ resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01"
+ integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==
+ dependencies:
+ ansi-styles "^4.1.0"
+ supports-color "^7.1.0"
+
+chrome-trace-event@^1.0.2:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz#05bffd7ff928465093314708c93bdfa9bd1f0f5b"
+ integrity sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==
+
+clone-deep@^4.0.1:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-4.0.1.tgz#c19fd9bdbbf85942b4fd979c84dcf7d5f07c2387"
+ integrity sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==
+ dependencies:
+ is-plain-object "^2.0.4"
+ kind-of "^6.0.2"
+ shallow-clone "^3.0.0"
+
+clone-response@^1.0.2:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.3.tgz#af2032aa47816399cf5f0a1d0db902f517abb8c3"
+ integrity sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==
+ dependencies:
+ mimic-response "^1.0.0"
+
+color-convert@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3"
+ integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==
+ dependencies:
+ color-name "~1.1.4"
+
+color-name@~1.1.4:
+ version "1.1.4"
+ resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
+ integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
+
+colorette@^2.0.14:
+ version "2.0.20"
+ resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a"
+ integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==
+
+commander@^10.0.1:
+ version "10.0.1"
+ resolved "https://registry.yarnpkg.com/commander/-/commander-10.0.1.tgz#881ee46b4f77d1c1dccc5823433aa39b022cbe06"
+ integrity sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==
+
+commander@^2.20.0:
+ version "2.20.3"
+ resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
+ integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
+
+cross-spawn@^7.0.3:
+ version "7.0.6"
+ resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f"
+ integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==
+ dependencies:
+ path-key "^3.1.0"
+ shebang-command "^2.0.0"
+ which "^2.0.1"
+
+csstype@^3.1.0:
+ version "3.1.3"
+ resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.3.tgz#d80ff294d114fb0e6ac500fbf85b60137d7eff81"
+ integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==
+
+debug@^4.1.0, debug@^4.1.1:
+ version "4.4.1"
+ resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.1.tgz#e5a8bc6cbc4c6cd3e64308b0693a3d4fa550189b"
+ integrity sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==
+ dependencies:
+ ms "^2.1.3"
+
+decompress-response@^6.0.0:
+ version "6.0.0"
+ resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc"
+ integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==
+ dependencies:
+ mimic-response "^3.1.0"
+
+defer-to-connect@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.1.tgz#8016bdb4143e4632b77a3449c6236277de520587"
+ integrity sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==
+
+define-data-property@^1.0.1:
+ version "1.1.4"
+ resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e"
+ integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==
+ dependencies:
+ es-define-property "^1.0.0"
+ es-errors "^1.3.0"
+ gopd "^1.0.1"
+
+define-properties@^1.2.1:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.1.tgz#10781cc616eb951a80a034bafcaa7377f6af2b6c"
+ integrity sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==
+ dependencies:
+ define-data-property "^1.0.1"
+ has-property-descriptors "^1.0.0"
+ object-keys "^1.1.1"
+
+detect-node@^2.0.4:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1"
+ integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==
+
+dompurify@*, dompurify@^3.0.1:
+ version "3.2.6"
+ resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-3.2.6.tgz#ca040a6ad2b88e2a92dc45f38c79f84a714a1cad"
+ integrity sha512-/2GogDQlohXPZe6D6NOgQvXLPSYBqIWMnZ8zzOhn09REE4eyAzb+Hed3jhoM9OkuaJ8P6ZGTTVWQKAi8ieIzfQ==
+ optionalDependencies:
+ "@types/trusted-types" "^2.0.7"
+
+electron-to-chromium@^1.5.199:
+ version "1.5.203"
+ resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.203.tgz#ef7fc2f7e1b816fa4535c861d1ec1348204142b6"
+ integrity sha512-uz4i0vLhfm6dLZWbz/iH88KNDV+ivj5+2SA+utpgjKaj9Q0iDLuwk6Idhe9BTxciHudyx6IvTvijhkPvFGUQ0g==
+
+electron@^33.3.1:
+ version "33.4.11"
+ resolved "https://registry.yarnpkg.com/electron/-/electron-33.4.11.tgz#225d7f106ed3edf788ced318c63858d8b8a446dc"
+ integrity sha512-xmdAs5QWRkInC7TpXGNvzo/7exojubk+72jn1oJL7keNeIlw7xNglf8TGtJtkR4rWC5FJq0oXiIXPS9BcK2Irg==
+ dependencies:
+ "@electron/get" "^2.0.0"
+ "@types/node" "^20.9.0"
+ extract-zip "^2.0.1"
+
+end-of-stream@^1.1.0:
+ version "1.4.5"
+ resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.5.tgz#7344d711dea40e0b74abc2ed49778743ccedb08c"
+ integrity sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==
+ dependencies:
+ once "^1.4.0"
+
+enhanced-resolve@^5.0.0, enhanced-resolve@^5.17.3:
+ version "5.18.3"
+ resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz#9b5f4c5c076b8787c78fe540392ce76a88855b44"
+ integrity sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==
+ dependencies:
+ graceful-fs "^4.2.4"
+ tapable "^2.2.0"
+
+env-paths@^2.2.0:
+ version "2.2.1"
+ resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2"
+ integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==
+
+envinfo@^7.7.3:
+ version "7.14.0"
+ resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.14.0.tgz#26dac5db54418f2a4c1159153a0b2ae980838aae"
+ integrity sha512-CO40UI41xDQzhLB1hWyqUKgFhs250pNcGbyGKe1l/e4FSaI/+YE4IMG76GDt0In67WLPACIITC+sOi08x4wIvg==
+
+es-define-property@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.1.tgz#983eb2f9a6724e9303f61addf011c72e09e0b0fa"
+ integrity sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==
+
+es-errors@^1.3.0:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f"
+ integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==
+
+es-module-lexer@^1.2.1:
+ version "1.7.0"
+ resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.7.0.tgz#9159601561880a85f2734560a9099b2c31e5372a"
+ integrity sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==
+
+es6-error@^4.1.1:
+ version "4.1.1"
+ resolved "https://registry.yarnpkg.com/es6-error/-/es6-error-4.1.1.tgz#9e3af407459deed47e9a91f9b885a84eb05c561d"
+ integrity sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==
+
+escalade@^3.2.0:
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5"
+ integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==
+
+escape-string-regexp@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
+ integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
+
+eslint-scope@5.1.1:
+ version "5.1.1"
+ resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c"
+ integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==
+ dependencies:
+ esrecurse "^4.3.0"
+ estraverse "^4.1.1"
+
+esrecurse@^4.3.0:
+ version "4.3.0"
+ resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921"
+ integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==
+ dependencies:
+ estraverse "^5.2.0"
+
+estraverse@^4.1.1:
+ version "4.3.0"
+ resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d"
+ integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==
+
+estraverse@^5.2.0:
+ version "5.3.0"
+ resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123"
+ integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==
+
+events@^3.2.0:
+ version "3.3.0"
+ resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400"
+ integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==
+
+extract-zip@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-2.0.1.tgz#663dca56fe46df890d5f131ef4a06d22bb8ba13a"
+ integrity sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==
+ dependencies:
+ debug "^4.1.1"
+ get-stream "^5.1.0"
+ yauzl "^2.10.0"
+ optionalDependencies:
+ "@types/yauzl" "^2.9.1"
+
+fast-deep-equal@^3.1.3:
+ version "3.1.3"
+ resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
+ integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
+
+fast-uri@^3.0.1:
+ version "3.0.6"
+ resolved "https://registry.yarnpkg.com/fast-uri/-/fast-uri-3.0.6.tgz#88f130b77cfaea2378d56bf970dea21257a68748"
+ integrity sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==
+
+fastest-levenshtein@^1.0.12:
+ version "1.0.16"
+ resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz#210e61b6ff181de91ea9b3d1b84fdedd47e034e5"
+ integrity sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==
+
+fd-slicer@~1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e"
+ integrity sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==
+ dependencies:
+ pend "~1.2.0"
+
+fflate@~0.6.10:
+ version "0.6.10"
+ resolved "https://registry.yarnpkg.com/fflate/-/fflate-0.6.10.tgz#5f40f9659205936a2d18abf88b2e7781662b6d43"
+ integrity sha512-IQrh3lEPM93wVCEczc9SaAOvkmcoQn/G8Bo1e8ZPlY3X3bnAxWaBdvTdvM1hP62iZp0BXWDy4vTAy4fF0+Dlpg==
+
+fill-range@^7.1.1:
+ version "7.1.1"
+ resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292"
+ integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==
+ dependencies:
+ to-regex-range "^5.0.1"
+
+find-up@^4.0.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19"
+ integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==
+ dependencies:
+ locate-path "^5.0.0"
+ path-exists "^4.0.0"
+
+flat@^5.0.2:
+ version "5.0.2"
+ resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241"
+ integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==
+
+fs-extra@^8.1.0:
+ version "8.1.0"
+ resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0"
+ integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==
+ dependencies:
+ graceful-fs "^4.2.0"
+ jsonfile "^4.0.0"
+ universalify "^0.1.0"
+
+function-bind@^1.1.2:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c"
+ integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==
+
+get-stream@^5.1.0:
+ version "5.2.0"
+ resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3"
+ integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==
+ dependencies:
+ pump "^3.0.0"
+
+glob-to-regexp@^0.4.1:
+ version "0.4.1"
+ resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e"
+ integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==
+
+global-agent@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/global-agent/-/global-agent-3.0.0.tgz#ae7cd31bd3583b93c5a16437a1afe27cc33a1ab6"
+ integrity sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==
+ dependencies:
+ boolean "^3.0.1"
+ es6-error "^4.1.1"
+ matcher "^3.0.0"
+ roarr "^2.15.3"
+ semver "^7.3.2"
+ serialize-error "^7.0.1"
+
+globalthis@^1.0.1:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.4.tgz#7430ed3a975d97bfb59bcce41f5cabbafa651236"
+ integrity sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==
+ dependencies:
+ define-properties "^1.2.1"
+ gopd "^1.0.1"
+
+gopd@^1.0.1:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.2.0.tgz#89f56b8217bdbc8802bd299df6d7f1081d7e51a1"
+ integrity sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==
+
+got@^11.8.5:
+ version "11.8.6"
+ resolved "https://registry.yarnpkg.com/got/-/got-11.8.6.tgz#276e827ead8772eddbcfc97170590b841823233a"
+ integrity sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==
+ dependencies:
+ "@sindresorhus/is" "^4.0.0"
+ "@szmarczak/http-timer" "^4.0.5"
+ "@types/cacheable-request" "^6.0.1"
+ "@types/responselike" "^1.0.0"
+ cacheable-lookup "^5.0.3"
+ cacheable-request "^7.0.2"
+ decompress-response "^6.0.0"
+ http2-wrapper "^1.0.0-beta.5.2"
+ lowercase-keys "^2.0.0"
+ p-cancelable "^2.0.0"
+ responselike "^2.0.0"
+
+graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.11, graceful-fs@^4.2.4:
+ version "4.2.11"
+ resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3"
+ integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==
+
+has-flag@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b"
+ integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==
+
+has-property-descriptors@^1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz#963ed7d071dc7bf5f084c5bfbe0d1b6222586854"
+ integrity sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==
+ dependencies:
+ es-define-property "^1.0.0"
+
+hasown@^2.0.2:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003"
+ integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==
+ dependencies:
+ function-bind "^1.1.2"
+
+http-cache-semantics@^4.0.0:
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz#205f4db64f8562b76a4ff9235aa5279839a09dd5"
+ integrity sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==
+
+http2-wrapper@^1.0.0-beta.5.2:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-1.0.3.tgz#b8f55e0c1f25d4ebd08b3b0c2c079f9590800b3d"
+ integrity sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==
+ dependencies:
+ quick-lru "^5.1.1"
+ resolve-alpn "^1.0.0"
+
+import-local@^3.0.2:
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.2.0.tgz#c3d5c745798c02a6f8b897726aba5100186ee260"
+ integrity sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==
+ dependencies:
+ pkg-dir "^4.2.0"
+ resolve-cwd "^3.0.0"
+
+interpret@^3.1.1:
+ version "3.1.1"
+ resolved "https://registry.yarnpkg.com/interpret/-/interpret-3.1.1.tgz#5be0ceed67ca79c6c4bc5cf0d7ee843dcea110c4"
+ integrity sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==
+
+is-core-module@^2.16.0:
+ version "2.16.1"
+ resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.16.1.tgz#2a98801a849f43e2add644fbb6bc6229b19a4ef4"
+ integrity sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==
+ dependencies:
+ hasown "^2.0.2"
+
+is-number@^7.0.0:
+ version "7.0.0"
+ resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b"
+ integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
+
+is-plain-object@^2.0.4:
+ version "2.0.4"
+ resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677"
+ integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==
+ dependencies:
+ isobject "^3.0.1"
+
+isexe@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
+ integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==
+
+isobject@^3.0.1:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df"
+ integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==
+
+jest-worker@^27.4.5:
+ version "27.5.1"
+ resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.5.1.tgz#8d146f0900e8973b106b6f73cc1e9a8cb86f8db0"
+ integrity sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==
+ dependencies:
+ "@types/node" "*"
+ merge-stream "^2.0.0"
+ supports-color "^8.0.0"
+
+json-buffer@3.0.1:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13"
+ integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==
+
+json-parse-even-better-errors@^2.3.1:
+ version "2.3.1"
+ resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d"
+ integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==
+
+json-schema-traverse@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2"
+ integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==
+
+json-stringify-safe@^5.0.1:
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
+ integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==
+
+jsonfile@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb"
+ integrity sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==
+ optionalDependencies:
+ graceful-fs "^4.1.6"
+
+keyv@^4.0.0:
+ version "4.5.4"
+ resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93"
+ integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==
+ dependencies:
+ json-buffer "3.0.1"
+
+kind-of@^6.0.2:
+ version "6.0.3"
+ resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd"
+ integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==
+
+loader-runner@^4.2.0:
+ version "4.3.0"
+ resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.0.tgz#c1b4a163b99f614830353b16755e7149ac2314e1"
+ integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==
+
+locate-path@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0"
+ integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==
+ dependencies:
+ p-locate "^4.1.0"
+
+lowercase-keys@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479"
+ integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==
+
+matcher@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/matcher/-/matcher-3.0.0.tgz#bd9060f4c5b70aa8041ccc6f80368760994f30ca"
+ integrity sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==
+ dependencies:
+ escape-string-regexp "^4.0.0"
+
+merge-stream@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60"
+ integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==
+
+meshoptimizer@~0.18.1:
+ version "0.18.1"
+ resolved "https://registry.yarnpkg.com/meshoptimizer/-/meshoptimizer-0.18.1.tgz#cdb90907f30a7b5b1190facd3b7ee6b7087797d8"
+ integrity sha512-ZhoIoL7TNV4s5B6+rx5mC//fw8/POGyNxS/DZyCJeiZ12ScLfVwRE/GfsxwiTkMYYD5DmK2/JXnEVXqL4rF+Sw==
+
+micromatch@^4.0.0:
+ version "4.0.8"
+ resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.8.tgz#d66fa18f3a47076789320b9b1af32bd86d9fa202"
+ integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==
+ dependencies:
+ braces "^3.0.3"
+ picomatch "^2.3.1"
+
+mime-db@1.52.0:
+ version "1.52.0"
+ resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70"
+ integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==
+
+mime-types@^2.1.27:
+ version "2.1.35"
+ resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a"
+ integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==
+ dependencies:
+ mime-db "1.52.0"
+
+mimic-response@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b"
+ integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==
+
+mimic-response@^3.1.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9"
+ integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==
+
+molangjs@^1.6.6:
+ version "1.6.6"
+ resolved "https://registry.yarnpkg.com/molangjs/-/molangjs-1.6.6.tgz#a0928c2dcd090f78d1b9451e3189334631191834"
+ integrity sha512-DkOnZ5c0Xylj1qYwBisNMkIseYZwudwBZ+xQcl96mC+Uo7y4XRKuNoDzNL9p/pLE3e7Cr52rQRBu10zfY0QQ7g==
+
+ms@^2.1.3:
+ version "2.1.3"
+ resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
+ integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
+
+nanoid@^3.3.11:
+ version "3.3.11"
+ resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.11.tgz#4f4f112cefbe303202f2199838128936266d185b"
+ integrity sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==
+
+neo-async@^2.6.2:
+ version "2.6.2"
+ resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f"
+ integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==
+
+node-releases@^2.0.19:
+ version "2.0.19"
+ resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.19.tgz#9e445a52950951ec4d177d843af370b411caf314"
+ integrity sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==
+
+normalize-url@^6.0.1:
+ version "6.1.0"
+ resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a"
+ integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==
+
+object-keys@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e"
+ integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==
+
+once@^1.3.1, once@^1.4.0:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
+ integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==
+ dependencies:
+ wrappy "1"
+
+p-cancelable@^2.0.0:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-2.1.1.tgz#aab7fbd416582fa32a3db49859c122487c5ed2cf"
+ integrity sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==
+
+p-limit@^2.2.0:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1"
+ integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==
+ dependencies:
+ p-try "^2.0.0"
+
+p-locate@^4.1.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07"
+ integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==
+ dependencies:
+ p-limit "^2.2.0"
+
+p-try@^2.0.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6"
+ integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==
+
+path-exists@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3"
+ integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==
+
+path-key@^3.1.0:
+ version "3.1.1"
+ resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375"
+ integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==
+
+path-parse@^1.0.7:
+ version "1.0.7"
+ resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735"
+ integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
+
+pend@~1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50"
+ integrity sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==
+
+picocolors@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b"
+ integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==
+
+picomatch@^2.3.1:
+ version "2.3.1"
+ resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
+ integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
+
+pkg-dir@^4.2.0:
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3"
+ integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==
+ dependencies:
+ find-up "^4.0.0"
+
+postcss@^8.4.14:
+ version "8.5.6"
+ resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.5.6.tgz#2825006615a619b4f62a9e7426cc120b349a8f3c"
+ integrity sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==
+ dependencies:
+ nanoid "^3.3.11"
+ picocolors "^1.1.1"
+ source-map-js "^1.2.1"
+
+prismjs@^1.29.0:
+ version "1.30.0"
+ resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.30.0.tgz#d9709969d9d4e16403f6f348c63553b19f0975a9"
+ integrity sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==
+
+progress@^2.0.3:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8"
+ integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==
+
+pump@^3.0.0:
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.3.tgz#151d979f1a29668dc0025ec589a455b53282268d"
+ integrity sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==
+ dependencies:
+ end-of-stream "^1.1.0"
+ once "^1.3.1"
+
+quick-lru@^5.1.1:
+ version "5.1.1"
+ resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932"
+ integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==
+
+randombytes@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a"
+ integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==
+ dependencies:
+ safe-buffer "^5.1.0"
+
+rechoir@^0.8.0:
+ version "0.8.0"
+ resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.8.0.tgz#49f866e0d32146142da3ad8f0eff352b3215ff22"
+ integrity sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==
+ dependencies:
+ resolve "^1.20.0"
+
+require-from-string@^2.0.2:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909"
+ integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==
+
+resolve-alpn@^1.0.0:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/resolve-alpn/-/resolve-alpn-1.2.1.tgz#b7adbdac3546aaaec20b45e7d8265927072726f9"
+ integrity sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==
+
+resolve-cwd@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d"
+ integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==
+ dependencies:
+ resolve-from "^5.0.0"
+
+resolve-from@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69"
+ integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==
+
+resolve@^1.20.0:
+ version "1.22.10"
+ resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.10.tgz#b663e83ffb09bbf2386944736baae803029b8b39"
+ integrity sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==
+ dependencies:
+ is-core-module "^2.16.0"
+ path-parse "^1.0.7"
+ supports-preserve-symlinks-flag "^1.0.0"
+
+responselike@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/responselike/-/responselike-2.0.1.tgz#9a0bc8fdc252f3fb1cca68b016591059ba1422bc"
+ integrity sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==
+ dependencies:
+ lowercase-keys "^2.0.0"
+
+roarr@^2.15.3:
+ version "2.15.4"
+ resolved "https://registry.yarnpkg.com/roarr/-/roarr-2.15.4.tgz#f5fe795b7b838ccfe35dc608e0282b9eba2e7afd"
+ integrity sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==
+ dependencies:
+ boolean "^3.0.1"
+ detect-node "^2.0.4"
+ globalthis "^1.0.1"
+ json-stringify-safe "^5.0.1"
+ semver-compare "^1.0.0"
+ sprintf-js "^1.1.2"
+
+safe-buffer@^5.1.0:
+ version "5.2.1"
+ resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
+ integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
+
+schema-utils@^4.3.0, schema-utils@^4.3.2:
+ version "4.3.2"
+ resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.3.2.tgz#0c10878bf4a73fd2b1dfd14b9462b26788c806ae"
+ integrity sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==
+ dependencies:
+ "@types/json-schema" "^7.0.9"
+ ajv "^8.9.0"
+ ajv-formats "^2.1.1"
+ ajv-keywords "^5.1.0"
+
+semver-compare@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc"
+ integrity sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==
+
+semver@^6.2.0:
+ version "6.3.1"
+ resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4"
+ integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==
+
+semver@^7.3.2, semver@^7.3.4:
+ version "7.7.2"
+ resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.2.tgz#67d99fdcd35cec21e6f8b87a7fd515a33f982b58"
+ integrity sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==
+
+serialize-error@^7.0.1:
+ version "7.0.1"
+ resolved "https://registry.yarnpkg.com/serialize-error/-/serialize-error-7.0.1.tgz#f1360b0447f61ffb483ec4157c737fab7d778e18"
+ integrity sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==
+ dependencies:
+ type-fest "^0.13.1"
+
+serialize-javascript@^6.0.2:
+ version "6.0.2"
+ resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.2.tgz#defa1e055c83bf6d59ea805d8da862254eb6a6c2"
+ integrity sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==
+ dependencies:
+ randombytes "^2.1.0"
+
+shallow-clone@^3.0.0:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3"
+ integrity sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==
+ dependencies:
+ kind-of "^6.0.2"
+
+shebang-command@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea"
+ integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==
+ dependencies:
+ shebang-regex "^3.0.0"
+
+shebang-regex@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172"
+ integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
+
+source-map-js@^1.2.1:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46"
+ integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==
+
+source-map-support@~0.5.20:
+ version "0.5.21"
+ resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f"
+ integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==
+ dependencies:
+ buffer-from "^1.0.0"
+ source-map "^0.6.0"
+
+source-map@^0.6.0, source-map@^0.6.1:
+ version "0.6.1"
+ resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
+ integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
+
+source-map@^0.7.4:
+ version "0.7.6"
+ resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.6.tgz#a3658ab87e5b6429c8a1f3ba0083d4c61ca3ef02"
+ integrity sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==
+
+sprintf-js@^1.1.2:
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.3.tgz#4914b903a2f8b685d17fdf78a70e917e872e444a"
+ integrity sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==
+
+sumchecker@^3.0.1:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/sumchecker/-/sumchecker-3.0.1.tgz#6377e996795abb0b6d348e9b3e1dfb24345a8e42"
+ integrity sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==
+ dependencies:
+ debug "^4.1.0"
+
+supports-color@^7.1.0:
+ version "7.2.0"
+ resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da"
+ integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==
+ dependencies:
+ has-flag "^4.0.0"
+
+supports-color@^8.0.0:
+ version "8.1.1"
+ resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c"
+ integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==
+ dependencies:
+ has-flag "^4.0.0"
+
+supports-preserve-symlinks-flag@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09"
+ integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
+
+tapable@^2.1.1, tapable@^2.2.0:
+ version "2.2.2"
+ resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.2.tgz#ab4984340d30cb9989a490032f086dbb8b56d872"
+ integrity sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==
+
+terser-webpack-plugin@^5.3.11:
+ version "5.3.14"
+ resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.14.tgz#9031d48e57ab27567f02ace85c7d690db66c3e06"
+ integrity sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw==
+ dependencies:
+ "@jridgewell/trace-mapping" "^0.3.25"
+ jest-worker "^27.4.5"
+ schema-utils "^4.3.0"
+ serialize-javascript "^6.0.2"
+ terser "^5.31.1"
+
+terser@^5.31.1:
+ version "5.43.1"
+ resolved "https://registry.yarnpkg.com/terser/-/terser-5.43.1.tgz#88387f4f9794ff1a29e7ad61fb2932e25b4fdb6d"
+ integrity sha512-+6erLbBm0+LROX2sPXlUYx/ux5PyE9K/a92Wrt6oA+WDAoFTdpHE5tCYCI5PNzq2y8df4rA+QgHLJuR4jNymsg==
+ dependencies:
+ "@jridgewell/source-map" "^0.3.3"
+ acorn "^8.14.0"
+ commander "^2.20.0"
+ source-map-support "~0.5.20"
+
+three-mesh-bvh@^0.9.1:
+ version "0.9.1"
+ resolved "https://registry.yarnpkg.com/three-mesh-bvh/-/three-mesh-bvh-0.9.1.tgz#fa6db25f14bb4d2453f15c926f5eb9eba1811168"
+ integrity sha512-WNT+m9jGQgtp4YdtwEnl4oFylNVifRf7iphlwWdJ4bJu7oNkY0xHIyntep9OzHuR1hpe/pyAP840gB/EsYDJfg==
+
+three@^0.134.0:
+ version "0.134.0"
+ resolved "https://registry.yarnpkg.com/three/-/three-0.134.0.tgz#d7ad4d85d050da0861bf39749b06ddfb5f17157f"
+ integrity sha512-LbBerg7GaSPjYtTOnu41AMp7tV6efUNR3p4Wk5NzkSsNTBuA5mDGOfwwZL1jhhVMLx9V20HolIUo0+U3AXehbg==
+
+three@^0.160.0:
+ version "0.160.1"
+ resolved "https://registry.yarnpkg.com/three/-/three-0.160.1.tgz#61fe2907312e8604b1f64187f58e047503847413"
+ integrity sha512-Bgl2wPJypDOZ1stAxwfWAcJ0WQf7QzlptsxkjYiURPz+n5k4RBDLsq+6f9Y75TYxn6aHLcWz+JNmwTOXWrQTBQ==
+
+tinycolor2@^1.4.2, tinycolor2@^1.6.0:
+ version "1.6.0"
+ resolved "https://registry.yarnpkg.com/tinycolor2/-/tinycolor2-1.6.0.tgz#f98007460169b0263b97072c5ae92484ce02d09e"
+ integrity sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==
+
+to-regex-range@^5.0.1:
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4"
+ integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==
+ dependencies:
+ is-number "^7.0.0"
+
+ts-loader@^9.5.1:
+ version "9.5.2"
+ resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-9.5.2.tgz#1f3d7f4bb709b487aaa260e8f19b301635d08020"
+ integrity sha512-Qo4piXvOTWcMGIgRiuFa6nHNm+54HbYaZCKqc9eeZCLRy3XqafQgwX2F7mofrbJG3g7EEb+lkiR+z2Lic2s3Zw==
+ dependencies:
+ chalk "^4.1.0"
+ enhanced-resolve "^5.0.0"
+ micromatch "^4.0.0"
+ semver "^7.3.4"
+ source-map "^0.7.4"
+
+type-fest@^0.13.1:
+ version "0.13.1"
+ resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.13.1.tgz#0172cb5bce80b0bd542ea348db50c7e21834d934"
+ integrity sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==
+
+typescript@^4.9.5:
+ version "4.9.5"
+ resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a"
+ integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==
+
+typescript@^5.3.3:
+ version "5.9.2"
+ resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.9.2.tgz#d93450cddec5154a2d5cabe3b8102b83316fb2a6"
+ integrity sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==
+
+undici-types@~6.21.0:
+ version "6.21.0"
+ resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.21.0.tgz#691d00af3909be93a7faa13be61b3a5b50ef12cb"
+ integrity sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==
+
+undici-types@~7.10.0:
+ version "7.10.0"
+ resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-7.10.0.tgz#4ac2e058ce56b462b056e629cc6a02393d3ff350"
+ integrity sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==
+
+universalify@^0.1.0:
+ version "0.1.2"
+ resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"
+ integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==
+
+update-browserslist-db@^1.1.3:
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz#348377dd245216f9e7060ff50b15a1b740b75420"
+ integrity sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==
+ dependencies:
+ escalade "^3.2.0"
+ picocolors "^1.1.1"
+
+vue@2.7.14:
+ version "2.7.14"
+ resolved "https://registry.yarnpkg.com/vue/-/vue-2.7.14.tgz#3743dcd248fd3a34d421ae456b864a0246bafb17"
+ integrity sha512-b2qkFyOM0kwqWFuQmgd4o+uHGU7T+2z3T+WQp8UBjADfEv2n4FEMffzBmCKNP0IGzOEEfYjvtcC62xaSKeQDrQ==
+ dependencies:
+ "@vue/compiler-sfc" "2.7.14"
+ csstype "^3.1.0"
+
+watchpack@^2.4.1:
+ version "2.4.4"
+ resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.4.tgz#473bda72f0850453da6425081ea46fc0d7602947"
+ integrity sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA==
+ dependencies:
+ glob-to-regexp "^0.4.1"
+ graceful-fs "^4.1.2"
+
+webpack-cli@^5.1.4:
+ version "5.1.4"
+ resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-5.1.4.tgz#c8e046ba7eaae4911d7e71e2b25b776fcc35759b"
+ integrity sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==
+ dependencies:
+ "@discoveryjs/json-ext" "^0.5.0"
+ "@webpack-cli/configtest" "^2.1.1"
+ "@webpack-cli/info" "^2.0.2"
+ "@webpack-cli/serve" "^2.0.5"
+ colorette "^2.0.14"
+ commander "^10.0.1"
+ cross-spawn "^7.0.3"
+ envinfo "^7.7.3"
+ fastest-levenshtein "^1.0.12"
+ import-local "^3.0.2"
+ interpret "^3.1.1"
+ rechoir "^0.8.0"
+ webpack-merge "^5.7.3"
+
+webpack-merge@^5.7.3:
+ version "5.10.0"
+ resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-5.10.0.tgz#a3ad5d773241e9c682803abf628d4cd62b8a4177"
+ integrity sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==
+ dependencies:
+ clone-deep "^4.0.1"
+ flat "^5.0.2"
+ wildcard "^2.0.0"
+
+webpack-sources@^3.3.3:
+ version "3.3.3"
+ resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.3.3.tgz#d4bf7f9909675d7a070ff14d0ef2a4f3c982c723"
+ integrity sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==
+
+webpack@^5.89.0:
+ version "5.101.2"
+ resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.101.2.tgz#08c222b7acfce7da95c593e2f88ea1638a07b344"
+ integrity sha512-4JLXU0tD6OZNVqlwzm3HGEhAHufSiyv+skb7q0d2367VDMzrU1Q/ZeepvkcHH0rZie6uqEtTQQe0OEOOluH3Mg==
+ dependencies:
+ "@types/eslint-scope" "^3.7.7"
+ "@types/estree" "^1.0.8"
+ "@types/json-schema" "^7.0.15"
+ "@webassemblyjs/ast" "^1.14.1"
+ "@webassemblyjs/wasm-edit" "^1.14.1"
+ "@webassemblyjs/wasm-parser" "^1.14.1"
+ acorn "^8.15.0"
+ acorn-import-phases "^1.0.3"
+ browserslist "^4.24.0"
+ chrome-trace-event "^1.0.2"
+ enhanced-resolve "^5.17.3"
+ es-module-lexer "^1.2.1"
+ eslint-scope "5.1.1"
+ events "^3.2.0"
+ glob-to-regexp "^0.4.1"
+ graceful-fs "^4.2.11"
+ json-parse-even-better-errors "^2.3.1"
+ loader-runner "^4.2.0"
+ mime-types "^2.1.27"
+ neo-async "^2.6.2"
+ schema-utils "^4.3.2"
+ tapable "^2.1.1"
+ terser-webpack-plugin "^5.3.11"
+ watchpack "^2.4.1"
+ webpack-sources "^3.3.3"
+
+which@^2.0.1:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1"
+ integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==
+ dependencies:
+ isexe "^2.0.0"
+
+wildcard@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.1.tgz#5ab10d02487198954836b6349f74fff961e10f67"
+ integrity sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==
+
+wintersky@^1.3.0:
+ version "1.3.3"
+ resolved "https://registry.yarnpkg.com/wintersky/-/wintersky-1.3.3.tgz#18e29363f2dde939659ef943656b42fbc6b96dc7"
+ integrity sha512-1rT84FrUFu3rWLsT6WBPUFm0/zxCFrRR86D5zfzeS1XKAp3LLiQligXK9830BvAcVrAbsvBhm9vlaHsFOHkU5g==
+ dependencies:
+ molangjs "^1.6.6"
+ three "^0.134.0"
+ tinycolor2 "^1.4.2"
+
+wrappy@1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
+ integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==
+
+yauzl@^2.10.0:
+ version "2.10.0"
+ resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9"
+ integrity sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==
+ dependencies:
+ buffer-crc32 "~0.2.3"
+ fd-slicer "~1.1.0"