@jscad/dxf-deserializer 3.0.4-alpha.0 → 3.0.5-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
/*! @jscad/dxf-deserializer V3.0.
|
|
2
|
-
var global,factory;global=this,factory=function(exports){const dxfMap=new Map([[0,"etyp"],[1,"text"],[2,"name"],[3,"nam1"],[5,"hdle"],[6,"ltyp"],[7,"lsty"],[8,"lnam"],[9,"vari"],[10,"pptx"],[11,"sptx"],[12,"tptx"],[13,"fptx"],[20,"ppty"],[21,"spty"],[22,"tpty"],[23,"fpty"],[30,"pptz"],[31,"sptz"],[32,"tptz"],[33,"fptz"],[38,"elev"],[39,"lthk"],[40,"swid"],[41,"ewid"],[42,"bulg"],[43,"cwid"],[48,"lscl"],[50,"ang0"],[51,"ang1"],[60,"visb"],[62,"cnmb"],[67,"spac"],[70,"lflg"],[71,"fvia"],[72,"fvib"],[73,"fvic"],[74,"fvid"],[75,"cflg"],[90,"vlen"],[91,"slen"],[92,"plen"],[93,"flen"],[94,"elen"],[95,"clen"],[100,"sbnm"],[210,"etrx"],[220,"etry"],[230,"etrz"]]),getTLA=group=>dxfMap.get(group),colorIndex=[[0,0,0,255],[255,0,0,255],[255,255,0,255],[0,255,0,255],[0,255,255,255],[0,0,255,255],[255,0,255,255],[255,255,255,255],[128,128,128,255],[192,192,192,255],[255,0,0,255],[255,127,127,255],[165,0,0,255],[165,82,82,255],[127,0,0,255],[127,63,63,255],[76,0,0,255],[76,38,38,255],[38,0,0,255],[38,19,19,255],[255,63,0,255],[255,159,127,255],[165,41,0,255],[165,103,82,255],[127,31,0,255],[127,79,63,255],[76,19,0,255],[76,47,38,255],[38,9,0,255],[38,28,19,255],[255,127,0,255],[255,191,127,255],[165,82,0,255],[165,124,82,255],[127,63,0,255],[127,95,63,255],[76,38,0,255],[76,57,38,255],[38,19,0,255],[38,28,19,255],[255,191,0,255],[255,223,127,255],[165,124,0,255],[165,145,82,255],[127,95,0,255],[127,111,63,255],[76,57,0,255],[76,66,38,255],[38,28,0,255],[38,33,19,255],[255,255,0,255],[255,255,127,255],[165,165,0,255],[165,165,82,255],[127,127,0,255],[127,127,63,255],[76,76,0,255],[76,76,38,255],[38,38,0,255],[38,38,19,255],[191,255,0,255],[223,255,127,255],[124,165,0,255],[145,165,82,255],[95,127,0,255],[111,127,63,255],[57,76,0,255],[66,76,38,255],[28,38,0,255],[33,38,19,255],[127,255,0,255],[191,255,127,255],[82,165,0,255],[124,165,82,255],[63,127,0,255],[95,127,63,255],[38,76,0,255],[57,76,38,255],[19,38,0,255],[28,38,19,255],[63,255,0,255],[159,255,127,255],[41,165,0,255],[103,165,82,255],[31,127,0,255],[79,127,63,255],[19,76,0,255],[47,76,38,255],[9,38,0,255],[23,38,19,255],[0,255,0,255],[125,255,127,255],[0,165,0,255],[82,165,82,255],[0,127,0,255],[63,127,63,255],[0,76,0,255],[38,76,38,255],[0,38,0,255],[19,38,19,255],[0,255,63,255],[127,255,159,255],[0,165,41,255],[82,165,103,255],[0,127,31,255],[63,127,79,255],[0,76,19,255],[38,76,47,255],[0,38,9,255],[19,88,23,255],[0,255,127,255],[127,255,191,255],[0,165,82,255],[82,165,124,255],[0,127,63,255],[63,127,95,255],[0,76,38,255],[38,76,57,255],[0,38,19,255],[19,88,28,255],[0,255,191,255],[127,255,223,255],[0,165,124,255],[82,165,145,255],[0,127,95,255],[63,127,111,255],[0,76,57,255],[38,76,66,255],[0,38,28,255],[19,88,88,255],[0,255,255,255],[127,255,255,255],[0,165,165,255],[82,165,165,255],[0,127,127,255],[63,127,127,255],[0,76,76,255],[38,76,76,255],[0,38,38,255],[19,88,88,255],[0,191,255,255],[127,223,255,255],[0,124,165,255],[82,145,165,255],[0,95,127,255],[63,111,217,255],[0,57,76,255],[38,66,126,255],[0,28,38,255],[19,88,88,255],[0,127,255,255],[127,191,255,255],[0,82,165,255],[82,124,165,255],[0,63,127,255],[63,95,127,255],[0,38,76,255],[38,57,126,255],[0,19,38,255],[19,28,88,255],[0,63,255,255],[127,159,255,255],[0,41,165,255],[82,103,165,255],[0,31,127,255],[63,79,127,255],[0,19,76,255],[38,47,126,255],[0,9,38,255],[19,23,88,255],[0,0,255,255],[127,127,255,255],[0,0,165,255],[82,82,165,255],[0,0,127,255],[63,63,127,255],[0,0,76,255],[38,38,126,255],[0,0,38,255],[19,19,88,255],[63,0,255,255],[159,127,255,255],[41,0,165,255],[103,82,165,255],[31,0,127,255],[79,63,127,255],[19,0,76,255],[47,38,126,255],[9,0,38,255],[23,19,88,255],[127,0,255,255],[191,127,255,255],[165,0,82,255],[124,82,165,255],[63,0,127,255],[95,63,127,255],[38,0,76,255],[57,38,126,255],[19,0,38,255],[28,19,88,255],[191,0,255,255],[223,127,255,255],[124,0,165,255],[142,82,165,255],[95,0,127,255],[111,63,127,255],[57,0,76,255],[66,38,76,255],[28,0,38,255],[88,19,88,255],[255,0,255,255],[255,127,255,255],[165,0,165,255],[165,82,165,255],[127,0,127,255],[127,63,127,255],[76,0,76,255],[76,38,76,255],[38,0,38,255],[88,19,88,255],[255,0,191,255],[255,127,223,255],[165,0,124,255],[165,82,145,255],[127,0,95,255],[127,63,111,255],[76,0,57,255],[76,38,66,255],[38,0,28,255],[88,19,88,255],[255,0,127,255],[255,127,191,255],[165,0,82,255],[165,82,124,255],[127,0,63,255],[127,63,95,255],[76,0,38,255],[76,38,57,255],[38,0,19,255],[88,19,28,255],[255,0,63,255],[255,127,159,255],[165,0,41,255],[165,82,103,255],[127,0,31,255],[127,63,79,255],[76,0,19,255],[76,38,47,255],[38,0,9,255],[88,19,23,255],[0,0,0,255],[101,101,101,255],[102,102,102,255],[153,153,153,255],[204,204,204,255],[255,255,255,255]];class DxfReader{constructor(options){this.options=Object.assign({},{strict:!1,track:!0},options),this.trackPosition=this.options.track,this.trackPosition&&(this.line=0,this.column=0,this.c=0)}on(state,callback){return this["on"+state]=callback,this}absorb(group,callback){return void 0===this.absorbers&&(this.absorbers=new Map),this.absorbers.set(group,callback),this}write(data){return parse(this,data),this}close(){return this.isclosed=!0,this}}const emiterror=(reader,er)=>(reader.trackPosition&&(er+=`\nLine: ${reader.line}\nColumn: ${reader.column}\nChar: ${reader.c}`),er=new Error(er),reader.error=er,emitstate(reader,"onerror",er)),emitend=reader=>emitstate(reader,"onend",reader.data),emitstate=(reader,state,data)=>{const onhandler=state.toString();return reader[onhandler]&&reader[onhandler](reader,data),reader},parse=(reader,data)=>{if(reader.error)throw reader.error;if(reader.isclosed)return emiterror(reader,"Cannot write after close");if((reader=>{emitstate(reader,"onstart",reader.data)})(reader),null===data)return emitend(reader);reader.group=null,reader.value=null,reader.error=null,reader.position=0,reader.line=0,reader.column=0;let i=0,c="",l="";for(;null===reader.error&&(c=charAt(data,i++),c);)reader.trackPosition&&(reader.position++,"\n"===c?(reader.line++,reader.column=0):reader.column++),"\n"===c?(parseLine(reader,l),l=""):l+=c;return emitend(reader),reader},parseLine=(reader,line)=>{line=line.trim(),null===reader.group?(setDxfGroup(reader,line),reader.value=null):setDxfValue(reader,line),null!==reader.group&&null!==reader.value&&(((reader,group,value)=>{if(void 0!==reader.absorbers){const absorber=reader.absorbers.get(group);void 0!==absorber&&absorber(reader,group,value)}})(reader,reader.group,reader.value),reader.group=null,reader.value=null)},setDxfGroup=(reader,line)=>{const code=parseInt(line);isNaN(code)?(emiterror(reader,"Invalid group (int)"),reader.group=null):reader.group=code},setDxfValue=(reader,line)=>{reader.options.strict,reader.value=line},charAt=(data,i)=>data&&data.length>i?data.charAt(i):"",copy$5=(out,matrix)=>(out[0]=matrix[0],out[1]=matrix[1],out[2]=matrix[2],out[3]=matrix[3],out[4]=matrix[4],out[5]=matrix[5],out[6]=matrix[6],out[7]=matrix[7],out[8]=matrix[8],out[9]=matrix[9],out[10]=matrix[10],out[11]=matrix[11],out[12]=matrix[12],out[13]=matrix[13],out[14]=matrix[14],out[15]=matrix[15],out),EPS$1=1e-5,TAU=2*Math.PI,rezero=n=>Math.abs(n)<1e-13?0:n,sin=radians=>rezero(Math.sin(radians)),cos=radians=>rezero(Math.cos(radians)),identity=out=>(out[0]=1,out[1]=0,out[2]=0,out[3]=0,out[4]=0,out[5]=1,out[6]=0,out[7]=0,out[8]=0,out[9]=0,out[10]=1,out[11]=0,out[12]=0,out[13]=0,out[14]=0,out[15]=1,out),fromRotation=(out,rad,axis)=>{let[x,y,z]=axis;const lengthSquared=x*x+y*y+z*z;if(Math.abs(lengthSquared)<EPS$1)return identity(out);const len=1/Math.sqrt(lengthSquared);x*=len,y*=len,z*=len;const s=sin(rad),c=cos(rad),t=1-c;return out[0]=x*x*t+c,out[1]=y*x*t+z*s,out[2]=z*x*t-y*s,out[3]=0,out[4]=x*y*t-z*s,out[5]=y*y*t+c,out[6]=z*y*t+x*s,out[7]=0,out[8]=x*z*t+y*s,out[9]=y*z*t-x*s,out[10]=z*z*t+c,out[11]=0,out[12]=0,out[13]=0,out[14]=0,out[15]=1,out},fromTranslation=(out,vector)=>(out[0]=1,out[1]=0,out[2]=0,out[3]=0,out[4]=0,out[5]=1,out[6]=0,out[7]=0,out[8]=0,out[9]=0,out[10]=1,out[11]=0,out[12]=vector[0],out[13]=vector[1],out[14]=vector[2],out[15]=1,out),fromValues$4=(m00,m01,m02,m03,m10,m11,m12,m13,m20,m21,m22,m23,m30,m31,m32,m33)=>{const out=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1];return out[0]=m00,out[1]=m01,out[2]=m02,out[3]=m03,out[4]=m10,out[5]=m11,out[6]=m12,out[7]=m13,out[8]=m20,out[9]=m21,out[10]=m22,out[11]=m23,out[12]=m30,out[13]=m31,out[14]=m32,out[15]=m33,out},abs$1=(out,vector)=>(out[0]=Math.abs(vector[0]),out[1]=Math.abs(vector[1]),out[2]=Math.abs(vector[2]),out),add$1=(out,a,b)=>(out[0]=a[0]+b[0],out[1]=a[1]+b[1],out[2]=a[2]+b[2],out),dot$2=(a,b)=>a[0]*b[0]+a[1]*b[1]+a[2]*b[2],create$c=()=>[0,0,0],clone$9=vector=>{const out=[0,0,0];return out[0]=vector[0],out[1]=vector[1],out[2]=vector[2],out},copy$4=(out,vector)=>(out[0]=vector[0],out[1]=vector[1],out[2]=vector[2],out),cross$1=(out,a,b)=>{const ax=a[0],ay=a[1],az=a[2],bx=b[0],by=b[1],bz=b[2];return out[0]=ay*bz-az*by,out[1]=az*bx-ax*bz,out[2]=ax*by-ay*bx,out},distance$1=(a,b)=>{const x=b[0]-a[0],y=b[1]-a[1],z=b[2]-a[2];return Math.sqrt(x*x+y*y+z*z)},divide$1=(out,a,b)=>(out[0]=a[0]/b[0],out[1]=a[1]/b[1],out[2]=a[2]/b[2],out),equals$8=(a,b)=>a[0]===b[0]&&a[1]===b[1]&&a[2]===b[2],fromValues$3=(x,y,z)=>{const out=[0,0,0];return out[0]=x,out[1]=y,out[2]=z,out},fromVec2=(out,vector,z=0)=>(out[0]=vector[0],out[1]=vector[1],out[2]=z,out),length$2=vector=>{const x=vector[0],y=vector[1],z=vector[2];return Math.sqrt(x*x+y*y+z*z)},max$1=(out,a,b)=>(out[0]=Math.max(a[0],b[0]),out[1]=Math.max(a[1],b[1]),out[2]=Math.max(a[2],b[2]),out),min$1=(out,a,b)=>(out[0]=Math.min(a[0],b[0]),out[1]=Math.min(a[1],b[1]),out[2]=Math.min(a[2],b[2]),out),normalize$1=(out,vector)=>{const x=vector[0],y=vector[1],z=vector[2];let len=x*x+y*y+z*z;return len>0&&(len=1/Math.sqrt(len)),out[0]=x*len,out[1]=y*len,out[2]=z*len,out},orthogonal=(out,vector)=>{const bV=abs$1([0,0,0],vector),b0=0+(bV[0]<bV[1]&&bV[0]<bV[2]),b1=0+(bV[1]<=bV[0]&&bV[1]<bV[2]),b2=0+(bV[2]<=bV[0]&&bV[2]<=bV[1]);return cross$1(out,vector,[b0,b1,b2])},scale$3=(out,vector,amount)=>(out[0]=vector[0]*amount,out[1]=vector[1]*amount,out[2]=vector[2]*amount,out),squaredDistance$1=(a,b)=>{const x=b[0]-a[0],y=b[1]-a[1],z=b[2]-a[2];return x*x+y*y+z*z},squaredLength$1=vector=>{const x=vector[0],y=vector[1],z=vector[2];return x*x+y*y+z*z},subtract$3=(out,a,b)=>(out[0]=a[0]-b[0],out[1]=a[1]-b[1],out[2]=a[2]-b[2],out),toString$c=vec=>`[${vec[0].toFixed(7)}, ${vec[1].toFixed(7)}, ${vec[2].toFixed(7)}]`,transform$d=(out,vector,matrix)=>{const x=vector[0],y=vector[1],z=vector[2];let w=matrix[3]*x+matrix[7]*y+matrix[11]*z+matrix[15];return w=w||1,out[0]=(matrix[0]*x+matrix[4]*y+matrix[8]*z+matrix[12])/w,out[1]=(matrix[1]*x+matrix[5]*y+matrix[9]*z+matrix[13])/w,out[2]=(matrix[2]*x+matrix[6]*y+matrix[10]*z+matrix[14])/w,out};var index$k=Object.freeze({__proto__:null,abs:abs$1,add:add$1,angle:(a,b)=>{const ax=a[0],ay=a[1],az=a[2],bx=b[0],by=b[1],bz=b[2],mag=Math.sqrt(ax*ax+ay*ay+az*az)*Math.sqrt(bx*bx+by*by+bz*bz),cosine=mag&&dot$2(a,b)/mag;return Math.acos(Math.min(Math.max(cosine,-1),1))},clone:clone$9,copy:copy$4,create:create$c,cross:cross$1,distance:distance$1,divide:divide$1,dot:dot$2,equals:equals$8,fromScalar:(out,scalar)=>(out[0]=scalar,out[1]=scalar,out[2]=scalar,out),fromValues:fromValues$3,fromVec2:fromVec2,length:length$2,lerp:(out,a,b,t)=>(out[0]=a[0]+t*(b[0]-a[0]),out[1]=a[1]+t*(b[1]-a[1]),out[2]=a[2]+t*(b[2]-a[2]),out),max:max$1,min:min$1,multiply:(out,a,b)=>(out[0]=a[0]*b[0],out[1]=a[1]*b[1],out[2]=a[2]*b[2],out),negate:(out,vector)=>(out[0]=-vector[0],out[1]=-vector[1],out[2]=-vector[2],out),normalize:normalize$1,orthogonal:orthogonal,rotateX:(out,vector,origin,radians)=>{const p=[],r=[];return p[0]=vector[0]-origin[0],p[1]=vector[1]-origin[1],p[2]=vector[2]-origin[2],r[0]=p[0],r[1]=p[1]*Math.cos(radians)-p[2]*Math.sin(radians),r[2]=p[1]*Math.sin(radians)+p[2]*Math.cos(radians),out[0]=r[0]+origin[0],out[1]=r[1]+origin[1],out[2]=r[2]+origin[2],out},rotateY:(out,vector,origin,radians)=>{const p=[],r=[];return p[0]=vector[0]-origin[0],p[1]=vector[1]-origin[1],p[2]=vector[2]-origin[2],r[0]=p[2]*Math.sin(radians)+p[0]*Math.cos(radians),r[1]=p[1],r[2]=p[2]*Math.cos(radians)-p[0]*Math.sin(radians),out[0]=r[0]+origin[0],out[1]=r[1]+origin[1],out[2]=r[2]+origin[2],out},rotateZ:(out,vector,origin,radians)=>{const p=[],r=[];return p[0]=vector[0]-origin[0],p[1]=vector[1]-origin[1],r[0]=p[0]*Math.cos(radians)-p[1]*Math.sin(radians),r[1]=p[0]*Math.sin(radians)+p[1]*Math.cos(radians),out[0]=r[0]+origin[0],out[1]=r[1]+origin[1],out[2]=vector[2],out},scale:scale$3,snap:(out,vector,epsilon)=>(out[0]=Math.round(vector[0]/epsilon)*epsilon+0,out[1]=Math.round(vector[1]/epsilon)*epsilon+0,out[2]=Math.round(vector[2]/epsilon)*epsilon+0,out),squaredDistance:squaredDistance$1,squaredLength:squaredLength$1,subtract:subtract$3,toString:toString$c,transform:transform$d});const fromVectorRotation=(out,source,target)=>{const sourceNormal=normalize$1([0,0,0],source),targetNormal=normalize$1([0,0,0],target),axis=cross$1([0,0,0],targetNormal,sourceNormal),cosA=dot$2(targetNormal,sourceNormal);if(-1===cosA)return fromRotation(out,Math.PI,orthogonal(axis,sourceNormal));const k=1/(1+cosA);return out[0]=axis[0]*axis[0]*k+cosA,out[1]=axis[1]*axis[0]*k-axis[2],out[2]=axis[2]*axis[0]*k+axis[1],out[3]=0,out[4]=axis[0]*axis[1]*k+axis[2],out[5]=axis[1]*axis[1]*k+cosA,out[6]=axis[2]*axis[1]*k-axis[0],out[7]=0,out[8]=axis[0]*axis[2]*k-axis[1],out[9]=axis[1]*axis[2]*k+axis[0],out[10]=axis[2]*axis[2]*k+cosA,out[11]=0,out[12]=0,out[13]=0,out[14]=0,out[15]=1,out},fromXRotation=(out,radians)=>{const s=sin(radians),c=cos(radians);return out[0]=1,out[1]=0,out[2]=0,out[3]=0,out[4]=0,out[5]=c,out[6]=s,out[7]=0,out[8]=0,out[9]=-s,out[10]=c,out[11]=0,out[12]=0,out[13]=0,out[14]=0,out[15]=1,out},fromZRotation=(out,radians)=>{const s=sin(radians),c=cos(radians);return out[0]=c,out[1]=s,out[2]=0,out[3]=0,out[4]=-s,out[5]=c,out[6]=0,out[7]=0,out[8]=0,out[9]=0,out[10]=1,out[11]=0,out[12]=0,out[13]=0,out[14]=0,out[15]=1,out},isIdentity=matrix=>1===matrix[0]&&0===matrix[1]&&0===matrix[2]&&0===matrix[3]&&0===matrix[4]&&1===matrix[5]&&0===matrix[6]&&0===matrix[7]&&0===matrix[8]&&0===matrix[9]&&1===matrix[10]&&0===matrix[11]&&0===matrix[12]&&0===matrix[13]&&0===matrix[14]&&1===matrix[15],isMirroring=matrix=>{const x=matrix[4]*matrix[9]-matrix[8]*matrix[5],y=matrix[8]*matrix[1]-matrix[0]*matrix[9],z=matrix[0]*matrix[5]-matrix[4]*matrix[1];return x*matrix[2]+y*matrix[6]+z*matrix[10]<0},isZero=num=>Math.abs(num)<Number.EPSILON,mirrorByPlane=(out,plane)=>{const[nx,ny,nz,w]=plane;return out[0]=1-2*nx*nx,out[1]=-2*ny*nx,out[2]=-2*nz*nx,out[3]=0,out[4]=-2*nx*ny,out[5]=1-2*ny*ny,out[6]=-2*nz*ny,out[7]=0,out[8]=-2*nx*nz,out[9]=-2*ny*nz,out[10]=1-2*nz*nz,out[11]=0,out[12]=2*nx*w,out[13]=2*ny*w,out[14]=2*nz*w,out[15]=1,out},multiply$1=(out,a,b)=>{const a00=a[0],a01=a[1],a02=a[2],a03=a[3],a10=a[4],a11=a[5],a12=a[6],a13=a[7],a20=a[8],a21=a[9],a22=a[10],a23=a[11],a30=a[12],a31=a[13],a32=a[14],a33=a[15];let b0=b[0],b1=b[1],b2=b[2],b3=b[3];return out[0]=b0*a00+b1*a10+b2*a20+b3*a30,out[1]=b0*a01+b1*a11+b2*a21+b3*a31,out[2]=b0*a02+b1*a12+b2*a22+b3*a32,out[3]=b0*a03+b1*a13+b2*a23+b3*a33,b0=b[4],b1=b[5],b2=b[6],b3=b[7],out[4]=b0*a00+b1*a10+b2*a20+b3*a30,out[5]=b0*a01+b1*a11+b2*a21+b3*a31,out[6]=b0*a02+b1*a12+b2*a22+b3*a32,out[7]=b0*a03+b1*a13+b2*a23+b3*a33,b0=b[8],b1=b[9],b2=b[10],b3=b[11],out[8]=b0*a00+b1*a10+b2*a20+b3*a30,out[9]=b0*a01+b1*a11+b2*a21+b3*a31,out[10]=b0*a02+b1*a12+b2*a22+b3*a32,out[11]=b0*a03+b1*a13+b2*a23+b3*a33,b0=b[12],b1=b[13],b2=b[14],b3=b[15],out[12]=b0*a00+b1*a10+b2*a20+b3*a30,out[13]=b0*a01+b1*a11+b2*a21+b3*a31,out[14]=b0*a02+b1*a12+b2*a22+b3*a32,out[15]=b0*a03+b1*a13+b2*a23+b3*a33,out};var index$j=Object.freeze({__proto__:null,add:(out,a,b)=>(out[0]=a[0]+b[0],out[1]=a[1]+b[1],out[2]=a[2]+b[2],out[3]=a[3]+b[3],out[4]=a[4]+b[4],out[5]=a[5]+b[5],out[6]=a[6]+b[6],out[7]=a[7]+b[7],out[8]=a[8]+b[8],out[9]=a[9]+b[9],out[10]=a[10]+b[10],out[11]=a[11]+b[11],out[12]=a[12]+b[12],out[13]=a[13]+b[13],out[14]=a[14]+b[14],out[15]=a[15]+b[15],out),clone:matrix=>{const out=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1];return out[0]=matrix[0],out[1]=matrix[1],out[2]=matrix[2],out[3]=matrix[3],out[4]=matrix[4],out[5]=matrix[5],out[6]=matrix[6],out[7]=matrix[7],out[8]=matrix[8],out[9]=matrix[9],out[10]=matrix[10],out[11]=matrix[11],out[12]=matrix[12],out[13]=matrix[13],out[14]=matrix[14],out[15]=matrix[15],out},copy:copy$5,create:()=>[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],equals:(a,b)=>a[0]===b[0]&&a[1]===b[1]&&a[2]===b[2]&&a[3]===b[3]&&a[4]===b[4]&&a[5]===b[5]&&a[6]===b[6]&&a[7]===b[7]&&a[8]===b[8]&&a[9]===b[9]&&a[10]===b[10]&&a[11]===b[11]&&a[12]===b[12]&&a[13]===b[13]&&a[14]===b[14]&&a[15]===b[15],fromRotation:fromRotation,fromScaling:(out,vector)=>(out[0]=vector[0],out[1]=0,out[2]=0,out[3]=0,out[4]=0,out[5]=vector[1],out[6]=0,out[7]=0,out[8]=0,out[9]=0,out[10]=vector[2],out[11]=0,out[12]=0,out[13]=0,out[14]=0,out[15]=1,out),fromTaitBryanRotation:(out,yaw,pitch,roll)=>{const sy=sin(yaw),cy=cos(yaw),sp=sin(pitch),cp=cos(pitch),sr=sin(roll),cr=cos(roll);return out[0]=cp*cy,out[1]=cp*sy,out[2]=-sp,out[3]=0,out[4]=sr*sp*cy-cr*sy,out[5]=cr*cy+sr*sp*sy,out[6]=sr*cp,out[7]=0,out[8]=sr*sy+cr*sp*cy,out[9]=cr*sp*sy-sr*cy,out[10]=cr*cp,out[11]=0,out[12]=0,out[13]=0,out[14]=0,out[15]=1,out},fromTranslation:fromTranslation,fromValues:fromValues$4,fromVectorRotation:fromVectorRotation,fromXRotation:fromXRotation,fromYRotation:(out,radians)=>{const s=sin(radians),c=cos(radians);return out[0]=c,out[1]=0,out[2]=-s,out[3]=0,out[4]=0,out[5]=1,out[6]=0,out[7]=0,out[8]=s,out[9]=0,out[10]=c,out[11]=0,out[12]=0,out[13]=0,out[14]=0,out[15]=1,out},fromZRotation:fromZRotation,identity:identity,invert:(out,matrix)=>{const a00=matrix[0],a01=matrix[1],a02=matrix[2],a03=matrix[3],a10=matrix[4],a11=matrix[5],a12=matrix[6],a13=matrix[7],a20=matrix[8],a21=matrix[9],a22=matrix[10],a23=matrix[11],a30=matrix[12],a31=matrix[13],a32=matrix[14],a33=matrix[15],b00=a00*a11-a01*a10,b01=a00*a12-a02*a10,b02=a00*a13-a03*a10,b03=a01*a12-a02*a11,b04=a01*a13-a03*a11,b05=a02*a13-a03*a12,b06=a20*a31-a21*a30,b07=a20*a32-a22*a30,b08=a20*a33-a23*a30,b09=a21*a32-a22*a31,b10=a21*a33-a23*a31,b11=a22*a33-a23*a32;let det=b00*b11-b01*b10+b02*b09+b03*b08-b04*b07+b05*b06;return det?(det=1/det,out[0]=(a11*b11-a12*b10+a13*b09)*det,out[1]=(a02*b10-a01*b11-a03*b09)*det,out[2]=(a31*b05-a32*b04+a33*b03)*det,out[3]=(a22*b04-a21*b05-a23*b03)*det,out[4]=(a12*b08-a10*b11-a13*b07)*det,out[5]=(a00*b11-a02*b08+a03*b07)*det,out[6]=(a32*b02-a30*b05-a33*b01)*det,out[7]=(a20*b05-a22*b02+a23*b01)*det,out[8]=(a10*b10-a11*b08+a13*b06)*det,out[9]=(a01*b08-a00*b10-a03*b06)*det,out[10]=(a30*b04-a31*b02+a33*b00)*det,out[11]=(a21*b02-a20*b04-a23*b00)*det,out[12]=(a11*b07-a10*b09-a12*b06)*det,out[13]=(a00*b09-a01*b07+a02*b06)*det,out[14]=(a31*b01-a30*b03-a32*b00)*det,out[15]=(a20*b03-a21*b01+a22*b00)*det,out):null},isIdentity:isIdentity,isMirroring:isMirroring,isOnlyTransformScale:matrix=>isZero(matrix[1])&&isZero(matrix[2])&&isZero(matrix[3])&&isZero(matrix[4])&&isZero(matrix[6])&&isZero(matrix[7])&&isZero(matrix[8])&&isZero(matrix[9])&&isZero(matrix[11])&&1===matrix[15],mirrorByPlane:mirrorByPlane,multiply:multiply$1,rotate:(out,matrix,radians,axis)=>{let[x,y,z]=axis;const lengthSquared=x*x+y*y+z*z;if(Math.abs(lengthSquared)<EPS$1)return copy$5(out,matrix);const len=1/Math.sqrt(lengthSquared);x*=len,y*=len,z*=len;const s=sin(radians),c=cos(radians),t=1-c,a00=matrix[0],a01=matrix[1],a02=matrix[2],a03=matrix[3],a10=matrix[4],a11=matrix[5],a12=matrix[6],a13=matrix[7],a20=matrix[8],a21=matrix[9],a22=matrix[10],a23=matrix[11],b00=x*x*t+c,b01=y*x*t+z*s,b02=z*x*t-y*s,b10=x*y*t-z*s,b11=y*y*t+c,b12=z*y*t+x*s,b20=x*z*t+y*s,b21=y*z*t-x*s,b22=z*z*t+c;return out[0]=a00*b00+a10*b01+a20*b02,out[1]=a01*b00+a11*b01+a21*b02,out[2]=a02*b00+a12*b01+a22*b02,out[3]=a03*b00+a13*b01+a23*b02,out[4]=a00*b10+a10*b11+a20*b12,out[5]=a01*b10+a11*b11+a21*b12,out[6]=a02*b10+a12*b11+a22*b12,out[7]=a03*b10+a13*b11+a23*b12,out[8]=a00*b20+a10*b21+a20*b22,out[9]=a01*b20+a11*b21+a21*b22,out[10]=a02*b20+a12*b21+a22*b22,out[11]=a03*b20+a13*b21+a23*b22,matrix!==out&&(out[12]=matrix[12],out[13]=matrix[13],out[14]=matrix[14],out[15]=matrix[15]),out},rotateX:(out,matrix,radians)=>{const s=sin(radians),c=cos(radians),a10=matrix[4],a11=matrix[5],a12=matrix[6],a13=matrix[7],a20=matrix[8],a21=matrix[9],a22=matrix[10],a23=matrix[11];return matrix!==out&&(out[0]=matrix[0],out[1]=matrix[1],out[2]=matrix[2],out[3]=matrix[3],out[12]=matrix[12],out[13]=matrix[13],out[14]=matrix[14],out[15]=matrix[15]),out[4]=a10*c+a20*s,out[5]=a11*c+a21*s,out[6]=a12*c+a22*s,out[7]=a13*c+a23*s,out[8]=a20*c-a10*s,out[9]=a21*c-a11*s,out[10]=a22*c-a12*s,out[11]=a23*c-a13*s,out},rotateY:(out,matrix,radians)=>{const s=sin(radians),c=cos(radians),a00=matrix[0],a01=matrix[1],a02=matrix[2],a03=matrix[3],a20=matrix[8],a21=matrix[9],a22=matrix[10],a23=matrix[11];return matrix!==out&&(out[4]=matrix[4],out[5]=matrix[5],out[6]=matrix[6],out[7]=matrix[7],out[12]=matrix[12],out[13]=matrix[13],out[14]=matrix[14],out[15]=matrix[15]),out[0]=a00*c-a20*s,out[1]=a01*c-a21*s,out[2]=a02*c-a22*s,out[3]=a03*c-a23*s,out[8]=a00*s+a20*c,out[9]=a01*s+a21*c,out[10]=a02*s+a22*c,out[11]=a03*s+a23*c,out},rotateZ:(out,matrix,radians)=>{const s=sin(radians),c=cos(radians),a00=matrix[0],a01=matrix[1],a02=matrix[2],a03=matrix[3],a10=matrix[4],a11=matrix[5],a12=matrix[6],a13=matrix[7];return matrix!==out&&(out[8]=matrix[8],out[9]=matrix[9],out[10]=matrix[10],out[11]=matrix[11],out[12]=matrix[12],out[13]=matrix[13],out[14]=matrix[14],out[15]=matrix[15]),out[0]=a00*c+a10*s,out[1]=a01*c+a11*s,out[2]=a02*c+a12*s,out[3]=a03*c+a13*s,out[4]=a10*c-a00*s,out[5]=a11*c-a01*s,out[6]=a12*c-a02*s,out[7]=a13*c-a03*s,out},scale:(out,matrix,dimensions)=>{const x=dimensions[0],y=dimensions[1],z=dimensions[2];return out[0]=matrix[0]*x,out[1]=matrix[1]*x,out[2]=matrix[2]*x,out[3]=matrix[3]*x,out[4]=matrix[4]*y,out[5]=matrix[5]*y,out[6]=matrix[6]*y,out[7]=matrix[7]*y,out[8]=matrix[8]*z,out[9]=matrix[9]*z,out[10]=matrix[10]*z,out[11]=matrix[11]*z,out[12]=matrix[12],out[13]=matrix[13],out[14]=matrix[14],out[15]=matrix[15],out},subtract:(out,a,b)=>(out[0]=a[0]-b[0],out[1]=a[1]-b[1],out[2]=a[2]-b[2],out[3]=a[3]-b[3],out[4]=a[4]-b[4],out[5]=a[5]-b[5],out[6]=a[6]-b[6],out[7]=a[7]-b[7],out[8]=a[8]-b[8],out[9]=a[9]-b[9],out[10]=a[10]-b[10],out[11]=a[11]-b[11],out[12]=a[12]-b[12],out[13]=a[13]-b[13],out[14]=a[14]-b[14],out[15]=a[15]-b[15],out),toString:mat=>mat.map(n=>n.toFixed(7)).toString(),translate:(out,matrix,offsets)=>{const x=offsets[0],y=offsets[1],z=offsets[2];let a00,a01,a02,a03,a10,a11,a12,a13,a20,a21,a22,a23;return matrix===out?(out[12]=matrix[0]*x+matrix[4]*y+matrix[8]*z+matrix[12],out[13]=matrix[1]*x+matrix[5]*y+matrix[9]*z+matrix[13],out[14]=matrix[2]*x+matrix[6]*y+matrix[10]*z+matrix[14],out[15]=matrix[3]*x+matrix[7]*y+matrix[11]*z+matrix[15]):(a00=matrix[0],a01=matrix[1],a02=matrix[2],a03=matrix[3],a10=matrix[4],a11=matrix[5],a12=matrix[6],a13=matrix[7],a20=matrix[8],a21=matrix[9],a22=matrix[10],a23=matrix[11],out[0]=a00,out[1]=a01,out[2]=a02,out[3]=a03,out[4]=a10,out[5]=a11,out[6]=a12,out[7]=a13,out[8]=a20,out[9]=a21,out[10]=a22,out[11]=a23,out[12]=a00*x+a10*y+a20*z+matrix[12],out[13]=a01*x+a11*y+a21*z+matrix[13],out[14]=a02*x+a12*y+a22*z+matrix[14],out[15]=a03*x+a13*y+a23*z+matrix[15]),out}});const create$b=(outlines=[])=>({outlines:outlines,transforms:[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]}),add=(out,a,b)=>(out[0]=a[0]+b[0],out[1]=a[1]+b[1],out),angleRadians=vector=>Math.atan2(vector[1],vector[0]),angleDegrees=vector=>57.29577951308232*angleRadians(vector),create$a=()=>[0,0],clone$8=vector=>{const out=[0,0];return out[0]=vector[0],out[1]=vector[1],out},cross=(out,a,b)=>(out[0]=0,out[1]=0,out[2]=a[0]*b[1]-a[1]*b[0],out),distance=(a,b)=>{const x=b[0]-a[0],y=b[1]-a[1];return Math.sqrt(x*x+y*y)},dot$1=(a,b)=>a[0]*b[0]+a[1]*b[1],equals$7=(a,b)=>a[0]===b[0]&&a[1]===b[1],fromAngleRadians=(out,radians)=>(out[0]=cos(radians),out[1]=sin(radians),out),fromValues$2=(x,y)=>{const out=[0,0];return out[0]=x,out[1]=y,out},max=(out,a,b)=>(out[0]=Math.max(a[0],b[0]),out[1]=Math.max(a[1],b[1]),out),min=(out,a,b)=>(out[0]=Math.min(a[0],b[0]),out[1]=Math.min(a[1],b[1]),out),negate=(out,vector)=>(out[0]=-vector[0],out[1]=-vector[1],out),rotate$1=(out,vector,origin,radians)=>{const x=vector[0]-origin[0],y=vector[1]-origin[1],c=Math.cos(radians),s=Math.sin(radians);return out[0]=x*c-y*s+origin[0],out[1]=x*s+y*c+origin[1],out},normal=(out,vector)=>rotate$1(out,vector,[0,0],TAU/4),normalize=(out,vector)=>{const x=vector[0],y=vector[1];let len=x*x+y*y;return len>0&&(len=1/Math.sqrt(len)),out[0]=x*len,out[1]=y*len,out},scale$1=(out,vector,amount)=>(out[0]=vector[0]*amount,out[1]=vector[1]*amount,out),subtract$1=(out,a,b)=>(out[0]=a[0]-b[0],out[1]=a[1]-b[1],out),toString$a=vector=>`[${vector[0].toFixed(7)}, ${vector[1].toFixed(7)}]`,transform$c=(out,vector,matrix)=>{const x=vector[0],y=vector[1];return out[0]=matrix[0]*x+matrix[4]*y+matrix[12],out[1]=matrix[1]*x+matrix[5]*y+matrix[13],out};var index$i=Object.freeze({__proto__:null,abs:(out,vector)=>(out[0]=Math.abs(vector[0]),out[1]=Math.abs(vector[1]),out),add:add,angle:angleRadians,angleDegrees:angleDegrees,angleRadians:angleRadians,clone:clone$8,copy:(out,vector)=>(out[0]=vector[0],out[1]=vector[1],out),create:create$a,cross:cross,distance:distance,divide:(out,a,b)=>(out[0]=a[0]/b[0],out[1]=a[1]/b[1],out),dot:dot$1,equals:equals$7,fromAngleDegrees:(out,degrees)=>fromAngleRadians(out,.017453292519943295*degrees),fromAngleRadians:fromAngleRadians,fromScalar:(out,scalar)=>(out[0]=scalar,out[1]=scalar,out),fromValues:fromValues$2,length:vector=>Math.sqrt(vector[0]*vector[0]+vector[1]*vector[1]),lerp:(out,a,b,t)=>{const ax=a[0],ay=a[1];return out[0]=ax+t*(b[0]-ax),out[1]=ay+t*(b[1]-ay),out},max:max,min:min,multiply:(out,a,b)=>(out[0]=a[0]*b[0],out[1]=a[1]*b[1],out),negate:negate,normal:normal,normalize:normalize,rotate:rotate$1,scale:scale$1,snap:(out,vector,epsilon)=>(out[0]=Math.round(vector[0]/epsilon)*epsilon+0,out[1]=Math.round(vector[1]/epsilon)*epsilon+0,out),squaredDistance:(a,b)=>{const x=b[0]-a[0],y=b[1]-a[1];return x*x+y*y},squaredLength:vector=>{const x=vector[0],y=vector[1];return x*x+y*y},subtract:subtract$1,toString:toString$a,transform:transform$c});const fromSides=sides=>{const pointMap=(sides=>{const pointMap=new Map,edges=(sides=>{const unique=new Map,getUniquePoint=point=>{const key=point.toString();return unique.has(key)?unique.get(key):(unique.set(key,point),point)};return sides.map(side=>side.map(getUniquePoint))})(sides);return edges.forEach(edge=>{pointMap.has(edge[0])?pointMap.get(edge[0]).push(edge):pointMap.set(edge[0],[edge])}),pointMap})(sides),outlines=[];for(;;){let startSide;for(const[point,edges]of pointMap){if(startSide=edges.shift(),startSide)break;pointMap.delete(point)}if(void 0===startSide)break;const connectedPoints=[],startPoint=startSide[0];for(;;){connectedPoints.push(startSide[0]);const nextPoint=startSide[1];if(nextPoint===startPoint)break;const nextPossibleSides=pointMap.get(nextPoint);if(!nextPossibleSides)throw new Error(`geometry is not closed at point ${nextPoint}`);const nextSide=popNextSide(startSide,nextPossibleSides);0===nextPossibleSides.length&&pointMap.delete(nextPoint),startSide=nextSide}connectedPoints.length>0&&connectedPoints.push(connectedPoints.shift()),outlines.push(connectedPoints)}return pointMap.clear(),create$b(outlines)},popNextSide=(startSide,nextSides)=>{if(1===nextSides.length)return nextSides.pop();const v0=[0,0],startAngle=angleDegrees(subtract$1(v0,startSide[1],startSide[0]));let bestAngle,bestIndex;nextSides.forEach((nextSide,index)=>{let angle=angleDegrees(subtract$1(v0,nextSide[1],nextSide[0]))-startAngle;angle<-180&&(angle+=360),angle>=180&&(angle-=360),(void 0===bestIndex||angle>bestAngle)&&(bestIndex=index,bestAngle=angle)});const nextSide=nextSides[bestIndex];return nextSides.splice(bestIndex,1),nextSide},isA$6=object=>!!(object&&"object"==typeof object&&"outlines"in object&&"transforms"in object&&Array.isArray(object.outlines)&&"length"in object.transforms),toOutlines=geometry=>(geometry=>(isIdentity(geometry.transforms)||(geometry.outlines=geometry.outlines.map(outline=>outline.map(point=>transform$c([0,0],point,geometry.transforms))),geometry.transforms=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]),geometry))(geometry).outlines,reverse$6=geometry=>{const outlines=toOutlines(geometry).map(outline=>outline.slice().reverse()),reversed=create$b(outlines);return geometry.color&&(reversed.color=geometry.color),reversed},toPoints$2=geometry=>{const points=[];return toOutlines(geometry).forEach(outline=>{outline.forEach(point=>{points.push(point)})}),points},toSides=geometry=>{const sides=[];return toOutlines(geometry).forEach(outline=>{outline.forEach((point,i)=>{const j=(i+1)%outline.length;sides.push([point,outline[j]])})}),sides},transform$b=(matrix,geometry)=>{const transforms=multiply$1([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],matrix,geometry.transforms),transformed=Object.assign({},geometry,{transforms:transforms});return matrix[0]*matrix[5]-matrix[4]*matrix[1]<0?reverse$6(transformed):transformed},intersect$1=(p1,p2,p3,p4,endpointTouch=!0)=>{if(p1[0]===p2[0]&&p1[1]===p2[1]||p3[0]===p4[0]&&p3[1]===p4[1])return;const denominator=(p4[1]-p3[1])*(p2[0]-p1[0])-(p4[0]-p3[0])*(p2[1]-p1[1]);if(Math.abs(denominator)<Number.MIN_VALUE)return;const ua=((p4[0]-p3[0])*(p1[1]-p3[1])-(p4[1]-p3[1])*(p1[0]-p3[0]))/denominator,ub=((p2[0]-p1[0])*(p1[1]-p3[1])-(p2[1]-p1[1])*(p1[0]-p3[0]))/denominator;return ua<0||ua>1||ub<0||ub>1||!(endpointTouch||0!==ua&&1!==ua&&0!==ub&&1!==ub)?void 0:[p1[0]+ua*(p2[0]-p1[0]),p1[1]+ua*(p2[1]-p1[1])]};var geom2=Object.freeze({__proto__:null,clone:geometry=>Object.assign({},geometry),create:create$b,fromSides:fromSides,isA:isA$6,reverse:reverse$6,toOutlines:toOutlines,toPoints:toPoints$2,toSides:toSides,toString:geometry=>{const outlines=toOutlines(geometry);let result="geom2 ("+outlines.length+" outlines):\n[\n";return outlines.forEach(outline=>{result+=" ["+outline.map(toString$a).join()+"]\n"}),result+="]\n",result},transform:transform$b,validate:object=>{if(!isA$6(object))throw new Error("invalid geom2 structure");if(object.outlines.forEach((outline,i)=>{if(outline.length<3)throw new Error(`geom2 outline ${i} must contain at least 3 points`);for(let i=0;i<outline.length;i++){const j=(i+1)%outline.length;if(equals$7(outline[i],outline[j]))throw new Error(`geom2 outline ${i} has duplicate point ${outline[i]}`)}}),toOutlines(object).forEach((outline,i)=>{for(let a1=0;a1<outline.length;a1++){const a2=(a1+1)%outline.length;for(let b1=0;b1<outline.length;b1++){const b2=(b1+1)%outline.length;if(a1!==b1){const int=intersect$1(outline[a1],outline[a2],outline[b1],outline[b2],!1);if(int)throw new Error(`geom2 outline ${i} self intersection at ${int}`)}}}}),!object.transforms.every(Number.isFinite))throw new Error(`geom2 invalid transforms ${object.transforms}`)}});const create$9=(polygons=[])=>({polygons:polygons,transforms:[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]}),create$8=(vertices=[])=>({vertices:vertices}),fromVerticesAndPlane=(vertices,plane)=>{const poly=create$8(vertices);return poly.plane=plane,poly},create$7=()=>[0,0,0,0],flip=(out,plane)=>(out[0]=-plane[0],out[1]=-plane[1],out[2]=-plane[2],out[3]=-plane[3],out),fromNormalAndPoint=(out,normal,point)=>{const u=normalize$1([0,0,0],normal),w=dot$2(point,u);return out[0]=u[0],out[1]=u[1],out[2]=u[2],out[3]=w,out},fromPoints$3=(out,...vertices)=>{const len=vertices.length,ba=[0,0,0],ca=[0,0,0],vertexNormal=index=>{const a=vertices[index],b=vertices[(index+1)%len],c=vertices[(index+2)%len];return subtract$3(ba,b,a),subtract$3(ca,c,a),cross$1(ba,ba,ca),normalize$1(ba,ba),ba};return out[0]=0,out[1]=0,out[2]=0,3===len?copy$4(out,vertexNormal(0)):(vertices.forEach((v,i)=>{add$1(out,out,vertexNormal(i))}),normalize$1(out,out)),out[3]=dot$2(out,vertices[0]),out},projectionOfPoint=(plane,point)=>{const a=point[0]*plane[0]+point[1]*plane[1]+point[2]*plane[2]-plane[3],x=point[0]-a*plane[0],y=point[1]-a*plane[1],z=point[2]-a*plane[2];return fromValues$3(x,y,z)},invert$1=polygon=>{const vertices=polygon.vertices.slice().reverse(),inverted=create$8(vertices);return polygon.plane&&(inverted.plane=flip([0,0,0,0],polygon.plane)),inverted},isA$5=object=>!!(object&&"object"==typeof object&&"vertices"in object&&Array.isArray(object.vertices)),isConvex$2=polygon=>areVerticesConvex(polygon.vertices),areVerticesConvex=vertices=>{const numVertices=vertices.length;if(numVertices>2){const normal=fromPoints$3([0,0,0,0],...vertices);let prevPrevPos=vertices[numVertices-2],prevPos=vertices[numVertices-1];for(let i=0;i<numVertices;i++){const pos=vertices[i];if(!isConvexVertex(prevPrevPos,prevPos,pos,normal))return!1;prevPrevPos=prevPos,prevPos=pos}}return!0},isConvexVertex=(prevVertex,vertex,nextVertex,normal)=>{const crossProduct=cross$1([0,0,0],subtract$3([0,0,0],vertex,prevVertex),subtract$3([0,0,0],nextVertex,vertex));return dot$2(crossProduct,normal)>=0},plane=polygon=>(polygon.plane||(polygon.plane=fromPoints$3([0,0,0,0],...polygon.vertices)),polygon.plane),measureArea$2=polygon=>{const n=polygon.vertices.length;if(n<3)return 0;const vertices=polygon.vertices,normal=plane(polygon),ax=Math.abs(normal[0]),ay=Math.abs(normal[1]),az=Math.abs(normal[2]);if(ax+ay+az===0)return 0;let coord=3;ax>ay&&ax>az?coord=1:ay>az&&(coord=2);let area=0,h=0,i=1,j=2;switch(coord){case 1:for(i=1;i<n;i++)h=i-1,j=(i+1)%n,area+=vertices[i][1]*(vertices[j][2]-vertices[h][2]);area+=vertices[0][1]*(vertices[1][2]-vertices[n-1][2]),area/=2*normal[0];break;case 2:for(i=1;i<n;i++)h=i-1,j=(i+1)%n,area+=vertices[i][2]*(vertices[j][0]-vertices[h][0]);area+=vertices[0][2]*(vertices[1][0]-vertices[n-1][0]),area/=2*normal[1];break;default:for(i=1;i<n;i++)h=i-1,j=(i+1)%n,area+=vertices[i][0]*(vertices[j][1]-vertices[h][1]);area+=vertices[0][0]*(vertices[1][1]-vertices[n-1][1]),area/=2*normal[2]}return area},cache$4=new WeakMap,measureBoundingSphere$1=(out,polygon)=>{const vertices=polygon.vertices;if(0===vertices.length)return out[0]=0,out[1]=0,out[2]=0,out[3]=0,out;let minx=vertices[0],miny=minx,minz=minx,maxx=minx,maxy=minx,maxz=minx;for(let i=0;i<vertices.length;i++){const v=vertices[i];minx[0]>v[0]&&(minx=v),miny[1]>v[1]&&(miny=v),minz[2]>v[2]&&(minz=v),maxx[0]<v[0]&&(maxx=v),maxy[1]<v[1]&&(maxy=v),maxz[2]<v[2]&&(maxz=v)}out[0]=.5*(minx[0]+maxx[0]),out[1]=.5*(miny[1]+maxy[1]),out[2]=.5*(minz[2]+maxz[2]);const x=out[0]-maxx[0],y=out[1]-maxy[1],z=out[2]-maxz[2];return out[3]=Math.sqrt(x*x+y*y+z*z),out},measureBoundingSphereAndCache=polygon=>{const boundingSphere=cache$4.get(polygon);if(boundingSphere)return boundingSphere;const out=[0,0,0,0];return measureBoundingSphere$1(out,polygon),cache$4.set(polygon,out),out},toVertices$3=polygon=>polygon.vertices,toString$7=polygon=>`poly3: [${polygon.vertices.map(toString$c).join(", ")}]`,transform$9=(matrix,polygon)=>{const vertices=polygon.vertices.map(vertex=>transform$d([0,0,0],vertex,matrix));return isMirroring(matrix)&&vertices.reverse(),create$8(vertices)},validate$5=object=>{if(!isA$5(object))throw new Error("invalid poly3 structure");if(object.vertices.length<3)throw new Error(`poly3 not enough vertices ${object.vertices.length}`);if(measureArea$2(object)<=0)throw new Error("poly3 area must be greater than zero");for(let i=0;i<object.vertices.length;i++)if(equals$8(object.vertices[i],object.vertices[(i+1)%object.vertices.length]))throw new Error(`poly3 has duplicate vertex ${object.vertices[i]}`);if(!isConvex$2(object))throw new Error("poly3 must be convex");if(object.vertices.forEach(vertex=>{if(!vertex.every(Number.isFinite))throw new Error(`poly3 invalid vertex ${vertex}`)}),object.vertices.length>3){const normal=plane(object);object.vertices.forEach(vertex=>{const dist=Math.abs(((plane,point)=>dot$2(plane,point)-plane[3])(normal,vertex));if(dist>1e-13)throw new Error(`poly3 must be coplanar: vertex ${vertex} distance ${dist}`)})}};var poly3=Object.freeze({__proto__:null,clone:(...params)=>{let out,poly3;return 1===params.length?(out=create$8(),poly3=params[0]):(out=params[0],poly3=params[1]),out.vertices=poly3.vertices.map(vec=>clone$9(vec)),out},create:create$8,fromVerticesAndPlane:fromVerticesAndPlane,invert:invert$1,isA:isA$5,isConvex:isConvex$2,measureArea:measureArea$2,measureBoundingBox:polygon=>{const vertices=polygon.vertices,numVertices=vertices.length,min=0===numVertices?[0,0,0]:clone$9(vertices[0]),max=clone$9(min);for(let i=1;i<numVertices;i++)min$1(min,min,vertices[i]),max$1(max,max,vertices[i]);return[min,max]},measureBoundingSphere:measureBoundingSphere$1,measureBoundingSphereAndCache:measureBoundingSphereAndCache,measureSignedVolume:polygon=>{let signedVolume=0;const vertices=polygon.vertices,cross=[0,0,0];for(let i=0;i<vertices.length-2;i++)cross$1(cross,vertices[i+1],vertices[i+2]),signedVolume+=dot$2(vertices[0],cross);return signedVolume/=6,signedVolume},plane:plane,toString:toString$7,toVertices:toVertices$3,transform:transform$9,validate:validate$5});const pointLineDistance=(point,a,b)=>Math.sqrt(((p,a,b)=>{const ab=[],ap=[];subtract$3(ab,b,a),subtract$3(ap,p,a);const area=squaredLength$1(cross$1([],ap,ab)),s=squaredLength$1(ab);if(0===s)throw Error("a and b are the same point");return area/s})(point,a,b));class VertexList{constructor(){this.head=null,this.tail=null}clear(){this.head=this.tail=null}insertBefore(target,node){node.prev=target.prev,node.next=target,node.prev?node.prev.next=node:this.head=node,target.prev=node}insertAfter(target,node){node.prev=target,node.next=target.next,node.next?node.next.prev=node:this.tail=node,target.next=node}add(node){this.head?this.tail.next=node:this.head=node,node.prev=this.tail,node.next=null,this.tail=node}addAll(node){for(this.head?this.tail.next=node:this.head=node,node.prev=this.tail;node.next;)node=node.next;this.tail=node}remove(node){node.prev?node.prev.next=node.next:this.head=node.next,node.next?node.next.prev=node.prev:this.tail=node.prev}removeChain(a,b){a.prev?a.prev.next=b.next:this.head=b.next,b.next?b.next.prev=a.prev:this.tail=a.prev}first(){return this.head}isEmpty(){return!this.head}}class Vertex{constructor(point,index){this.point=point,this.index=index,this.next=null,this.prev=null,this.face=null}}class HalfEdge{constructor(vertex,face){this.vertex=vertex,this.face=face,this.next=null,this.prev=null,this.opposite=null}head(){return this.vertex}tail(){return this.prev?this.prev.vertex:null}length(){return this.tail()?distance$1(this.tail().point,this.head().point):-1}lengthSquared(){return this.tail()?squaredDistance$1(this.tail().point,this.head().point):-1}setOpposite(edge){this.opposite=edge,edge.opposite=this}}class Face{constructor(){this.normal=[],this.centroid=[],this.offset=0,this.outside=null,this.mark=0,this.edge=null,this.nVertices=0}getEdge(i){if("number"!=typeof i)throw Error("requires a number");let it=this.edge;for(;i>0;)it=it.next,i-=1;for(;i<0;)it=it.prev,i+=1;return it}computeNormal(){const e0=this.edge,e1=e0.next;let e2=e1.next;const v2=subtract$3([],e1.head().point,e0.head().point),t=[],v1=[];for(this.nVertices=2,this.normal=[0,0,0];e2!==e0;)copy$4(v1,v2),subtract$3(v2,e2.head().point,e0.head().point),add$1(this.normal,this.normal,cross$1(t,v1,v2)),e2=e2.next,this.nVertices+=1;this.area=length$2(this.normal),this.normal=scale$3(this.normal,this.normal,1/this.area)}computeNormalMinArea(minArea){if(this.computeNormal(),this.area<minArea){let maxEdge,maxSquaredLength=0,edge=this.edge;do{const lengthSquared=edge.lengthSquared();lengthSquared>maxSquaredLength&&(maxEdge=edge,maxSquaredLength=lengthSquared),edge=edge.next}while(edge!==this.edge);const p1=maxEdge.tail().point,p2=maxEdge.head().point,maxVector=subtract$3([],p2,p1),maxLength=Math.sqrt(maxSquaredLength);scale$3(maxVector,maxVector,1/maxLength);const maxProjection=dot$2(this.normal,maxVector);scale$3(maxVector,maxVector,-maxProjection),add$1(this.normal,this.normal,maxVector),normalize$1(this.normal,this.normal)}}computeCentroid(){this.centroid=[0,0,0];let edge=this.edge;do{add$1(this.centroid,this.centroid,edge.head().point),edge=edge.next}while(edge!==this.edge);scale$3(this.centroid,this.centroid,1/this.nVertices)}computeNormalAndCentroid(minArea){void 0!==minArea?this.computeNormalMinArea(minArea):this.computeNormal(),this.computeCentroid(),this.offset=dot$2(this.normal,this.centroid)}distanceToPlane(point){return dot$2(this.normal,point)-this.offset}connectHalfEdges(prev,next){let discardedFace;if(prev.opposite.face===next.opposite.face){const oppositeFace=next.opposite.face;let oppositeEdge;prev===this.edge&&(this.edge=next),3===oppositeFace.nVertices?(oppositeEdge=next.opposite.prev.opposite,oppositeFace.mark=2,discardedFace=oppositeFace):(oppositeEdge=next.opposite.next,oppositeFace.edge===oppositeEdge.prev&&(oppositeFace.edge=oppositeEdge),oppositeEdge.prev=oppositeEdge.prev.prev,oppositeEdge.prev.next=oppositeEdge),next.prev=prev.prev,next.prev.next=next,next.setOpposite(oppositeEdge),oppositeFace.computeNormalAndCentroid()}else prev.next=next,next.prev=prev;return discardedFace}mergeAdjacentFaces(adjacentEdge,discardedFaces){const oppositeEdge=adjacentEdge.opposite,oppositeFace=oppositeEdge.face;discardedFaces.push(oppositeFace),oppositeFace.mark=2;let edge,discardedFace,adjacentEdgePrev=adjacentEdge.prev,adjacentEdgeNext=adjacentEdge.next,oppositeEdgePrev=oppositeEdge.prev,oppositeEdgeNext=oppositeEdge.next;for(;adjacentEdgePrev.opposite.face===oppositeFace;)adjacentEdgePrev=adjacentEdgePrev.prev,oppositeEdgeNext=oppositeEdgeNext.next;for(;adjacentEdgeNext.opposite.face===oppositeFace;)adjacentEdgeNext=adjacentEdgeNext.next,oppositeEdgePrev=oppositeEdgePrev.prev;for(edge=oppositeEdgeNext;edge!==oppositeEdgePrev.next;edge=edge.next)edge.face=this;return this.edge=adjacentEdgeNext,discardedFace=this.connectHalfEdges(oppositeEdgePrev,adjacentEdgeNext),discardedFace&&discardedFaces.push(discardedFace),discardedFace=this.connectHalfEdges(adjacentEdgePrev,oppositeEdgeNext),discardedFace&&discardedFaces.push(discardedFace),this.computeNormalAndCentroid(),discardedFaces}collectIndices(){const indices=[];let edge=this.edge;do{indices.push(edge.head().index),edge=edge.next}while(edge!==this.edge);return indices}static createTriangle(v0,v1,v2,minArea=0){const face=new Face,e0=new HalfEdge(v0,face),e1=new HalfEdge(v1,face),e2=new HalfEdge(v2,face);return e0.next=e2.prev=e1,e1.next=e0.prev=e2,e2.next=e1.prev=e0,face.edge=e0,face.computeNormalAndCentroid(minArea),face}}class QuickHull{constructor(points){if(!Array.isArray(points))throw TypeError("input is not a valid array");if(points.length<4)throw Error("cannot build a simplex out of <4 points");this.tolerance=-1,this.nFaces=0,this.nPoints=points.length,this.faces=[],this.newFaces=[],this.claimed=new VertexList,this.unclaimed=new VertexList,this.vertices=[];for(let i=0;i<points.length;i+=1)this.vertices.push(new Vertex(points[i],i));this.discardedFaces=[],this.vertexPointIndices=[]}addVertexToFace(vertex,face){vertex.face=face,face.outside?this.claimed.insertBefore(face.outside,vertex):this.claimed.add(vertex),face.outside=vertex}removeVertexFromFace(vertex,face){vertex===face.outside&&(vertex.next&&vertex.next.face===face?face.outside=vertex.next:face.outside=null),this.claimed.remove(vertex)}removeAllVerticesFromFace(face){if(face.outside){let end=face.outside;for(;end.next&&end.next.face===face;)end=end.next;return this.claimed.removeChain(face.outside,end),end.next=null,face.outside}}deleteFaceVertices(face,absorbingFace){const faceVertices=this.removeAllVerticesFromFace(face);if(faceVertices)if(absorbingFace){let nextVertex;for(let vertex=faceVertices;vertex;vertex=nextVertex)nextVertex=vertex.next,absorbingFace.distanceToPlane(vertex.point)>this.tolerance?this.addVertexToFace(vertex,absorbingFace):this.unclaimed.add(vertex)}else this.unclaimed.addAll(faceVertices)}resolveUnclaimedPoints(newFaces){let vertexNext=this.unclaimed.first();for(let vertex=vertexNext;vertex;vertex=vertexNext){vertexNext=vertex.next;let maxFace,maxDistance=this.tolerance;for(let i=0;i<newFaces.length;i+=1){const face=newFaces[i];if(0===face.mark){const dist=face.distanceToPlane(vertex.point);if(dist>maxDistance&&(maxDistance=dist,maxFace=face),maxDistance>1e3*this.tolerance)break}}maxFace&&this.addVertexToFace(vertex,maxFace)}}computeExtremes(){const min=[],max=[],minVertices=[],maxVertices=[];let i,j;for(i=0;i<3;i+=1)minVertices[i]=maxVertices[i]=this.vertices[0];for(i=0;i<3;i+=1)min[i]=max[i]=this.vertices[0].point[i];for(i=1;i<this.vertices.length;i+=1){const vertex=this.vertices[i],point=vertex.point;for(j=0;j<3;j+=1)point[j]<min[j]&&(min[j]=point[j],minVertices[j]=vertex);for(j=0;j<3;j+=1)point[j]>max[j]&&(max[j]=point[j],maxVertices[j]=vertex)}return this.tolerance=3*Number.EPSILON*(Math.max(Math.abs(min[0]),Math.abs(max[0]))+Math.max(Math.abs(min[1]),Math.abs(max[1]))+Math.max(Math.abs(min[2]),Math.abs(max[2]))),[minVertices,maxVertices]}createInitialSimplex(){const vertices=this.vertices,[min,max]=this.computeExtremes();let v2,v3,i,j,maxDistance=0,indexMax=0;for(i=0;i<3;i+=1){const distance=max[i].point[i]-min[i].point[i];distance>maxDistance&&(maxDistance=distance,indexMax=i)}const v0=min[indexMax],v1=max[indexMax];for(maxDistance=0,i=0;i<this.vertices.length;i+=1){const vertex=this.vertices[i];if(vertex!==v0&&vertex!==v1){const distance=pointLineDistance(vertex.point,v0.point,v1.point);distance>maxDistance&&(maxDistance=distance,v2=vertex)}}const normal=fromPoints$3([],v0.point,v1.point,v2.point),distPO=dot$2(v0.point,normal);for(maxDistance=-1,i=0;i<this.vertices.length;i+=1){const vertex=this.vertices[i];if(vertex!==v0&&vertex!==v1&&vertex!==v2){const distance=Math.abs(dot$2(normal,vertex.point)-distPO);distance>maxDistance&&(maxDistance=distance,v3=vertex)}}const faces=[];if(dot$2(v3.point,normal)-distPO<0)for(faces.push(Face.createTriangle(v0,v1,v2),Face.createTriangle(v3,v1,v0),Face.createTriangle(v3,v2,v1),Face.createTriangle(v3,v0,v2)),i=0;i<3;i+=1){const j=(i+1)%3;faces[i+1].getEdge(2).setOpposite(faces[0].getEdge(j)),faces[i+1].getEdge(1).setOpposite(faces[j+1].getEdge(0))}else for(faces.push(Face.createTriangle(v0,v2,v1),Face.createTriangle(v3,v0,v1),Face.createTriangle(v3,v1,v2),Face.createTriangle(v3,v2,v0)),i=0;i<3;i+=1){const j=(i+1)%3;faces[i+1].getEdge(2).setOpposite(faces[0].getEdge((3-i)%3)),faces[i+1].getEdge(0).setOpposite(faces[j+1].getEdge(1))}for(i=0;i<4;i+=1)this.faces.push(faces[i]);for(i=0;i<vertices.length;i+=1){const vertex=vertices[i];if(vertex!==v0&&vertex!==v1&&vertex!==v2&&vertex!==v3){let maxFace;for(maxDistance=this.tolerance,j=0;j<4;j+=1){const distance=faces[j].distanceToPlane(vertex.point);distance>maxDistance&&(maxDistance=distance,maxFace=faces[j])}maxFace&&this.addVertexToFace(vertex,maxFace)}}}reindexFaceAndVertices(){const activeFaces=[];for(let i=0;i<this.faces.length;i+=1){const face=this.faces[i];0===face.mark&&activeFaces.push(face)}this.faces=activeFaces}collectFaces(skipTriangulation){const faceIndices=[];for(let i=0;i<this.faces.length;i+=1){if(0!==this.faces[i].mark)throw Error("attempt to include a destroyed face in the hull");const indices=this.faces[i].collectIndices();if(skipTriangulation)faceIndices.push(indices);else for(let j=0;j<indices.length-2;j+=1)faceIndices.push([indices[0],indices[j+1],indices[j+2]])}return faceIndices}nextVertexToAdd(){if(!this.claimed.isEmpty()){let eyeVertex,vertex,maxDistance=0;const eyeFace=this.claimed.first().face;for(vertex=eyeFace.outside;vertex&&vertex.face===eyeFace;vertex=vertex.next){const distance=eyeFace.distanceToPlane(vertex.point);distance>maxDistance&&(maxDistance=distance,eyeVertex=vertex)}return eyeVertex}}computeHorizon(eyePoint,crossEdge,face,horizon){let edge;this.deleteFaceVertices(face),face.mark=2,edge=crossEdge?crossEdge.next:crossEdge=face.getEdge(0);do{const oppositeEdge=edge.opposite,oppositeFace=oppositeEdge.face;0===oppositeFace.mark&&(oppositeFace.distanceToPlane(eyePoint)>this.tolerance?this.computeHorizon(eyePoint,oppositeEdge,oppositeFace,horizon):horizon.push(edge)),edge=edge.next}while(edge!==crossEdge)}addAdjoiningFace(eyeVertex,horizonEdge){const face=Face.createTriangle(eyeVertex,horizonEdge.tail(),horizonEdge.head());return this.faces.push(face),face.getEdge(-1).setOpposite(horizonEdge.opposite),face.getEdge(0)}addNewFaces(eyeVertex,horizon){let firstSideEdge,previousSideEdge;this.newFaces=[];for(let i=0;i<horizon.length;i+=1){const horizonEdge=horizon[i],sideEdge=this.addAdjoiningFace(eyeVertex,horizonEdge);firstSideEdge?sideEdge.next.setOpposite(previousSideEdge):firstSideEdge=sideEdge,this.newFaces.push(sideEdge.face),previousSideEdge=sideEdge}firstSideEdge.next.setOpposite(previousSideEdge)}oppositeFaceDistance(edge){return edge.face.distanceToPlane(edge.opposite.face.centroid)}doAdjacentMerge(face,mergeType){let edge=face.edge,convex=!0,it=0;do{if(it>=face.nVertices)throw Error("merge recursion limit exceeded");const oppositeFace=edge.opposite.face;let merge=!1;if(2===mergeType?(this.oppositeFaceDistance(edge)>-this.tolerance||this.oppositeFaceDistance(edge.opposite)>-this.tolerance)&&(merge=!0):face.area>oppositeFace.area?this.oppositeFaceDistance(edge)>-this.tolerance?merge=!0:this.oppositeFaceDistance(edge.opposite)>-this.tolerance&&(convex=!1):this.oppositeFaceDistance(edge.opposite)>-this.tolerance?merge=!0:this.oppositeFaceDistance(edge)>-this.tolerance&&(convex=!1),merge){const discardedFaces=face.mergeAdjacentFaces(edge,[]);for(let i=0;i<discardedFaces.length;i+=1)this.deleteFaceVertices(discardedFaces[i],face);return!0}edge=edge.next,it+=1}while(edge!==face.edge);return convex||(face.mark=1),!1}addVertexToHull(eyeVertex){const horizon=[];this.unclaimed.clear(),this.removeVertexFromFace(eyeVertex,eyeVertex.face),this.computeHorizon(eyeVertex.point,null,eyeVertex.face,horizon),this.addNewFaces(eyeVertex,horizon);for(let i=0;i<this.newFaces.length;i+=1){const face=this.newFaces[i];if(0===face.mark)for(;this.doAdjacentMerge(face,1););}for(let i=0;i<this.newFaces.length;i+=1){const face=this.newFaces[i];if(1===face.mark)for(face.mark=0;this.doAdjacentMerge(face,2););}this.resolveUnclaimedPoints(this.newFaces)}build(){let eyeVertex;for(this.createInitialSimplex();eyeVertex=this.nextVertexToAdd();)this.addVertexToHull(eyeVertex);this.reindexFaceAndVertices()}}const toPolygons$1=geometry=>(geometry=>(isIdentity(geometry.transforms)||(geometry.polygons=geometry.polygons.map(polygon=>transform$9(geometry.transforms,polygon)),geometry.transforms=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]),geometry))(geometry).polygons,isA$4=object=>!!(object&&"object"==typeof object&&"polygons"in object&&"transforms"in object&&Array.isArray(object.polygons)&&"length"in object.transforms),transform$8=(matrix,geometry)=>{const transforms=multiply$1([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],matrix,geometry.transforms);return Object.assign({},geometry,{transforms:transforms})};var geom3=Object.freeze({__proto__:null,clone:geometry=>Object.assign({},geometry),create:create$9,fromVertices:listOfLists=>{if(!Array.isArray(listOfLists))throw new Error("the given vertices must be an array");return create$9(listOfLists.map(create$8))},fromVerticesConvex:uniqueVertices=>{if(!Array.isArray(uniqueVertices))throw new Error("the given vertices must be an array");const polygons=((points,options={})=>{const instance=new QuickHull(points);return instance.build(),instance.collectFaces(options.skipTriangulation)})(uniqueVertices,{skipTriangulation:!0}).map(face=>{const vertices=face.map(index=>uniqueVertices[index]);return create$8(vertices)});return create$9(polygons)},invert:geometry=>{const newPolygons=toPolygons$1(geometry).map(polygon=>invert$1(polygon));return create$9(newPolygons)},isA:isA$4,isConvex:geometry=>{if(!isA$4(geometry))throw new Error("isConvex requires a geom3 geometry");const polygons=toPolygons$1(geometry);if(0===polygons.length)return!0;const vertices=[],found=new Set;for(let i=0;i<polygons.length;i++){const verts=polygons[i].vertices;for(let j=0;j<verts.length;j++){const v=verts[j],key=`${v[0]},${v[1]},${v[2]}`;found.has(key)||(found.add(key),vertices.push(v))}}for(let i=0;i<polygons.length;i++){const p=plane(polygons[i]);for(let j=0;j<vertices.length;j++){const v=vertices[j];if(dot$2(p,v)-p[3]>EPS$1)return!1}}return!0},toPolygons:toPolygons$1,toString:geometry=>{const polygons=toPolygons$1(geometry);let result="geom3 ("+polygons.length+" polygons):\n";return polygons.forEach(polygon=>{result+=" "+toString$7(polygon)+"\n"}),result},toVertices:geometry=>toPolygons$1(geometry).map(polygon=>toVertices$3(polygon)),transform:transform$8,validate:object=>{if(!isA$4(object))throw new Error("invalid geom3 structure");if(object.polygons.forEach(validate$5),(object=>{const edgeCount=new Map;object.polygons.forEach(({vertices:vertices})=>{vertices.forEach((v,i)=>{const edge=`${v}/${vertices[(i+1)%vertices.length]}`,count=edgeCount.has(edge)?edgeCount.get(edge):0;edgeCount.set(edge,count+1)})});const nonManifold=[];if(edgeCount.forEach((count,edge)=>{const complementEdge=edge.split("/").reverse().join("/");count!==edgeCount.get(complementEdge)&&nonManifold.push(edge.replace("/"," -> "))}),nonManifold.length>0)throw new Error(`non-manifold edges ${nonManifold.length}\n${nonManifold.join("\n")}`)})(object),!object.transforms.every(Number.isFinite))throw new Error(`geom3 invalid transforms ${object.transforms}`)}});const clone$4=geometry=>Object.assign({},geometry),close$1=geometry=>{if(geometry.isClosed)return geometry;const cloned=clone$4(geometry);if(cloned.isClosed=!0,cloned.points.length>1){const points=cloned.points,p0=points[0];let pn=points[points.length-1];for(;distance(p0,pn)<EPS$1*EPS$1&&(points.pop(),1!==points.length);)pn=points[points.length-1]}return cloned},create$6=(points=[])=>({points:points,isClosed:!1,transforms:[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]}),fromPoints$2=(options,points)=>{let{closed:closed}=Object.assign({},{closed:!1},options),created=create$6();if(created.points=points.map(point=>clone$8(point)),created.points.length>1){const p0=created.points[0],pn=created.points[created.points.length-1];distance(p0,pn)<EPS$1*EPS$1&&(closed=!0)}return!0===closed&&(created=close$1(created)),created},toPoints$1=geometry=>(geometry=>(isIdentity(geometry.transforms)||(geometry.points=geometry.points.map(point=>transform$c([0,0],point,geometry.transforms)),geometry.transforms=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]),geometry))(geometry).points,concat$1=(...paths)=>{let isClosed=!1,newPoints=[];return paths.forEach((path,i)=>{const tmp=toPoints$1(path).slice();if(newPoints.length>0&&tmp.length>0&&equals$7(tmp[0],newPoints[newPoints.length-1])&&tmp.shift(),tmp.length>0&&isClosed)throw new Error(`Cannot concatenate to a closed path; check the ${i}th path`);isClosed=path.isClosed,newPoints=newPoints.concat(tmp)}),fromPoints$2({closed:isClosed},newPoints)},appendPoints=(points,geometry)=>concat$1(geometry,create$6(points)),isA$3=object=>!!(object&&"object"==typeof object&&"points"in object&&"transforms"in object&&"isClosed"in object&&Array.isArray(object.points)&&"length"in object.transforms),transform$7=(matrix,geometry)=>{const transforms=multiply$1([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],matrix,geometry.transforms);return Object.assign({},geometry,{transforms:transforms})};var path2=Object.freeze({__proto__:null,appendArc:(options,geometry)=>{let{endpoint:endpoint,radius:radius,xaxisRotation:xaxisRotation,clockwise:clockwise,large:large,segments:segments}=Object.assign({},{radius:[0,0],xaxisRotation:0,clockwise:!1,large:!1,segments:16},options);if(!Array.isArray(endpoint))throw new Error("endpoint must be an array of X and Y values");if(endpoint.length<2)throw new Error("endpoint must contain X and Y values");if(endpoint=clone$8(endpoint),!Array.isArray(radius))throw new Error("radius must be an array of X and Y values");if(radius.length<2)throw new Error("radius must contain X and Y values");if(segments<4)throw new Error("segments must be four or more");if(geometry.isClosed)throw new Error("the given path cannot be closed");const points=toPoints$1(geometry);if(points.length<1)throw new Error("the given path must contain one or more points (as the starting point for the arc)");let xRadius=radius[0],yRadius=radius[1];const startpoint=points[points.length-1];xRadius=Math.round(1e5*xRadius)/1e5,yRadius=Math.round(1e5*yRadius)/1e5,endpoint=fromValues$2(Math.round(1e5*endpoint[0])/1e5,Math.round(1e5*endpoint[1])/1e5);const sweepFlag=!clockwise;let newPoints=[];if(0===xRadius||0===yRadius)newPoints.push(endpoint);else{xRadius=Math.abs(xRadius),yRadius=Math.abs(yRadius);const phi=xaxisRotation,cosPhi=Math.cos(phi),sinPhi=Math.sin(phi),minusHalfDistance=subtract$1([0,0],startpoint,endpoint);scale$1(minusHalfDistance,minusHalfDistance,.5);const x=Math.round(1e5*(cosPhi*minusHalfDistance[0]+sinPhi*minusHalfDistance[1]))/1e5,y=Math.round(1e5*(-sinPhi*minusHalfDistance[0]+cosPhi*minusHalfDistance[1]))/1e5,startTranslated=fromValues$2(x,y),bigLambda=startTranslated[0]*startTranslated[0]/(xRadius*xRadius)+startTranslated[1]*startTranslated[1]/(yRadius*yRadius);if(bigLambda>1){const sqrtBigLambda=Math.sqrt(bigLambda);xRadius*=sqrtBigLambda,yRadius*=sqrtBigLambda,xRadius=Math.round(1e5*xRadius)/1e5,yRadius=Math.round(1e5*yRadius)/1e5}let multiplier1=Math.sqrt((xRadius*xRadius*yRadius*yRadius-xRadius*xRadius*startTranslated[1]*startTranslated[1]-yRadius*yRadius*startTranslated[0]*startTranslated[0])/(xRadius*xRadius*startTranslated[1]*startTranslated[1]+yRadius*yRadius*startTranslated[0]*startTranslated[0]));sweepFlag===large&&(multiplier1=-multiplier1);const centerTranslated=fromValues$2(xRadius*startTranslated[1]/yRadius,-yRadius*startTranslated[0]/xRadius);scale$1(centerTranslated,centerTranslated,multiplier1);let center=fromValues$2(cosPhi*centerTranslated[0]-sinPhi*centerTranslated[1],sinPhi*centerTranslated[0]+cosPhi*centerTranslated[1]);center=add(center,center,scale$1([0,0],add([0,0],startpoint,endpoint),.5));const vector1=fromValues$2((startTranslated[0]-centerTranslated[0])/xRadius,(startTranslated[1]-centerTranslated[1])/yRadius),vector2=fromValues$2((-startTranslated[0]-centerTranslated[0])/xRadius,(-startTranslated[1]-centerTranslated[1])/yRadius),theta1=angleRadians(vector1);let deltatheta=angleRadians(vector2)-theta1;deltatheta%=TAU,!sweepFlag&&deltatheta>0?deltatheta-=TAU:sweepFlag&&deltatheta<0&&(deltatheta+=TAU);let numSteps=Math.floor(segments*(Math.abs(deltatheta)/TAU));numSteps<1&&(numSteps=1);for(let step=1;step<numSteps;step++){const theta=theta1+step/numSteps*deltatheta,cosTheta=Math.cos(theta),sinTheta=Math.sin(theta),point=fromValues$2(cosPhi*xRadius*cosTheta-sinPhi*yRadius*sinTheta,sinPhi*xRadius*cosTheta+cosPhi*yRadius*sinTheta);add(point,point,center),newPoints.push(point)}numSteps&&newPoints.push(options.endpoint)}return newPoints=points.concat(newPoints),fromPoints$2({},newPoints)},appendBezier:(options,geometry)=>{let{controlPoints:controlPoints,segments:segments}=Object.assign({},{segments:16},options);if(!Array.isArray(controlPoints))throw new Error("controlPoints must be an array of one or more points");if(controlPoints.length<1)throw new Error("controlPoints must be an array of one or more points");if(segments<4)throw new Error("segments must be four or more");if(geometry.isClosed)throw new Error("the given geometry cannot be closed");const points=toPoints$1(geometry);if(points.length<1)throw new Error("the given path must contain one or more points (as the starting point for the bezier curve)");if(controlPoints=controlPoints.slice(),null===controlPoints[0]){if(controlPoints.length<2)throw new Error("a null control point must be passed with one more control points");let lastBezierControlPoint=points[points.length-2];if("lastBezierControlPoint"in geometry&&(lastBezierControlPoint=geometry.lastBezierControlPoint),!Array.isArray(lastBezierControlPoint))throw new Error("the given path must contain TWO or more points if given a null control point");const controlPoint=scale$1([0,0],points[points.length-1],2);subtract$1(controlPoint,controlPoint,lastBezierControlPoint),controlPoints[0]=controlPoint}controlPoints.unshift(points[points.length-1]);const bezierOrder=controlPoints.length-1,factorials=[];let fact=1;for(let i=0;i<=bezierOrder;++i)i>0&&(fact*=i),factorials.push(fact);const binomials=[];for(let i=0;i<=bezierOrder;++i){const binomial=factorials[bezierOrder]/(factorials[i]*factorials[bezierOrder-i]);binomials.push(binomial)}const v0=[0,0],v1=[0,0],v3=[0,0,0],getPointForT=t=>{let tk=1,oneMinusTNMinusK=Math.pow(1-t,bezierOrder);const invOneMinusT=1!==t?1/(1-t):1,point=[0,0];for(let k=0;k<=bezierOrder;++k){k===bezierOrder&&(oneMinusTNMinusK=1);const bernsteinCoefficient=binomials[k]*tk*oneMinusTNMinusK,derivativePoint=scale$1(v0,controlPoints[k],bernsteinCoefficient);add(point,point,derivativePoint),tk*=t,oneMinusTNMinusK*=invOneMinusT}return point},newPoints=[],newPointsT=[],numSteps=bezierOrder+1;for(let i=0;i<numSteps;++i){const t=i/(numSteps-1),point=getPointForT(t);newPoints.push(point),newPointsT.push(t)}let subdivideBase=1;const maxAngle=TAU/segments,maxSinAngle=Math.sin(maxAngle);for(;subdivideBase<newPoints.length-1;){const dir1=subtract$1(v0,newPoints[subdivideBase],newPoints[subdivideBase-1]);normalize(dir1,dir1);const dir2=subtract$1(v1,newPoints[subdivideBase+1],newPoints[subdivideBase]);normalize(dir2,dir2);const sinAngle=cross(v3,dir1,dir2);if(Math.abs(sinAngle[2])>maxSinAngle){const t0=newPointsT[subdivideBase-1],t1=newPointsT[subdivideBase+1],newt0=t0+1*(t1-t0)/3,newt1=t0+2*(t1-t0)/3,point0=getPointForT(newt0),point1=getPointForT(newt1);newPoints.splice(subdivideBase,1,point0,point1),newPointsT.splice(subdivideBase,1,newt0,newt1),subdivideBase--,subdivideBase<1&&(subdivideBase=1)}else++subdivideBase}newPoints.shift();const result=appendPoints(newPoints,geometry);return result.lastBezierControlPoint=controlPoints[controlPoints.length-2],result},appendPoints:appendPoints,clone:clone$4,close:close$1,concat:concat$1,create:create$6,equals:(a,b)=>{if(a.isClosed!==b.isClosed)return!1;if(a.points.length!==b.points.length)return!1;const aPoints=toPoints$1(a),bPoints=toPoints$1(b),length=aPoints.length;let offset=0;do{let unequal=!1;for(let i=0;i<length;i++)if(!equals$7(aPoints[i],bPoints[(i+offset)%length])){unequal=!0;break}if(!1===unequal)return!0;if(!a.isClosed)return!1}while(++offset<length);return!1},fromPoints:fromPoints$2,isA:isA$3,reverse:geometry=>{const cloned=clone$4(geometry);return cloned.points=geometry.points.slice().reverse(),cloned},toPoints:toPoints$1,toString:geometry=>{const points=toPoints$1(geometry);let result="path ("+points.length+" points, "+geometry.isClosed+"):\n[\n";return points.forEach(point=>{result+=" "+toString$a(point)+",\n"}),result+="]\n",result},transform:transform$7,validate:object=>{if(!isA$3(object))throw new Error("invalid path2 structure");if(object.points.length>1)for(let i=0;i<object.points.length;i++)if(equals$7(object.points[i],object.points[(i+1)%object.points.length]))throw new Error(`path2 has duplicate point ${object.points[i]}`);if(object.points.forEach(point=>{if(!point.every(Number.isFinite))throw new Error(`path2 invalid point ${point}`)}),!object.transforms.every(Number.isFinite))throw new Error(`path2 invalid transforms ${object.transforms}`)}});const flatten=arr=>arr.flat(1/0),area$1=points=>{let area=0;for(let i=0;i<points.length;i++){const j=(i+1)%points.length;area+=points[i][0]*points[j][1],area-=points[j][0]*points[i][1]}return area/2},create$3=(points=[])=>({points:points}),arePointsInside=(points,polygon)=>0===points.length||polygon.points.length<3?0:((polygon=>area$1(polygon.points))(polygon)<0&&(polygon=(polygon=>{const points=polygon.points.slice().reverse();return create$3(points)})(polygon)),points.reduce((acc,point)=>acc+isPointInside(point,polygon.points),0)===points.length?1:0),isPointInside=(point,polygon)=>{const numPoints=polygon.length,tx=point[0],ty=point[1];let vtx0=polygon[numPoints-1],vtx1=polygon[0],yFlag0=vtx0[1]>ty,insideFlag=0,i=0;for(let j=numPoints+1;--j;){const yFlag1=vtx1[1]>ty;if(yFlag0!==yFlag1){const xFlag0=vtx0[0]>tx,xFlag1=vtx1[0]>tx;(xFlag0&&xFlag1||vtx1[0]-(vtx1[1]-ty)*(vtx0[0]-vtx1[0])/(vtx0[1]-vtx1[1])>=tx)&&(insideFlag=!insideFlag)}yFlag0=yFlag1,vtx0=vtx1,vtx1=polygon[++i]}return insideFlag},create$2=(contours=[])=>({contours:contours}),fromGeom2=geometry=>{const contours=toOutlines(geometry).map(outline=>outline.map(point=>fromVec2([0,0,0],point)));return create$2(contours)},isA=object=>!!(object&&"object"==typeof object&&"contours"in object&&Array.isArray(object.contours)),reverse$2=slice=>{const contours=slice.contours.map(contour=>contour.slice().reverse());return create$2(contours)},toEdges=slice=>{const edges=[];return slice.contours.forEach(contour=>{contour.forEach((vertex,i)=>{const next=contour[(i+1)%contour.length];edges.push([vertex,next])})}),edges};let Node$2=class{constructor(i,x,y){this.i=i,this.x=x,this.y=y,this.prev=null,this.next=null,this.z=null,this.prevZ=null,this.nextZ=null,this.steiner=!1}};const insertNode=(i,x,y,last)=>{const p=new Node$2(i,x,y);return last?(p.next=last.next,p.prev=last,last.next.prev=p,last.next=p):(p.prev=p,p.next=p),p},removeNode=p=>{p.next.prev=p.prev,p.prev.next=p.next,p.prevZ&&(p.prevZ.nextZ=p.nextZ),p.nextZ&&(p.nextZ.prevZ=p.prevZ)},pointInTriangle=(ax,ay,bx,by,cx,cy,px,py)=>(cx-px)*(ay-py)-(ax-px)*(cy-py)>=0&&(ax-px)*(by-py)-(bx-px)*(ay-py)>=0&&(bx-px)*(cy-py)-(cx-px)*(by-py)>=0,area=(p,q,r)=>(q.y-p.y)*(r.x-q.x)-(q.x-p.x)*(r.y-q.y),linkedPolygon=(data,start,end,dim,clockwise)=>{let last;if(clockwise===signedArea$1(data,start,end,dim)>0)for(let i=start;i<end;i+=dim)last=insertNode(i,data[i],data[i+1],last);else for(let i=end-dim;i>=start;i-=dim)last=insertNode(i,data[i],data[i+1],last);return last&&equals$2(last,last.next)&&(removeNode(last),last=last.next),last},filterPoints=(start,end)=>{if(!start)return start;end||(end=start);let again,p=start;do{if(again=!1,p.steiner||!equals$2(p,p.next)&&0!==area(p.prev,p,p.next))p=p.next;else{if(removeNode(p),p=end=p.prev,p===p.next)break;again=!0}}while(again||p!==end);return end},cureLocalIntersections=(start,triangles,dim)=>{let p=start;do{const a=p.prev,b=p.next.next;!equals$2(a,b)&&intersects(a,p,p.next,b)&&locallyInside(a,b)&&locallyInside(b,a)&&(triangles.push(a.i/dim),triangles.push(p.i/dim),triangles.push(b.i/dim),removeNode(p),removeNode(p.next),p=start=b),p=p.next}while(p!==start);return filterPoints(p)},locallyInside=(a,b)=>area(a.prev,a,a.next)<0?area(a,b,a.next)>=0&&area(a,a.prev,b)>=0:area(a,b,a.prev)<0||area(a,a.next,b)<0,splitPolygon=(a,b)=>{const a2=new Node$2(a.i,a.x,a.y),b2=new Node$2(b.i,b.x,b.y),an=a.next,bp=b.prev;return a.next=b,b.prev=a,a2.next=an,an.prev=a2,b2.next=a2,a2.prev=b2,bp.next=b2,b2.prev=bp,b2},isValidDiagonal=(a,b)=>a.next.i!==b.i&&a.prev.i!==b.i&&!((a,b)=>{let p=a;do{if(p.i!==a.i&&p.next.i!==a.i&&p.i!==b.i&&p.next.i!==b.i&&intersects(p,p.next,a,b))return!0;p=p.next}while(p!==a);return!1})(a,b)&&(locallyInside(a,b)&&locallyInside(b,a)&&((a,b)=>{let p=a,inside=!1;const px=(a.x+b.x)/2,py=(a.y+b.y)/2;do{p.y>py!=p.next.y>py&&p.next.y!==p.y&&px<(p.next.x-p.x)*(py-p.y)/(p.next.y-p.y)+p.x&&(inside=!inside),p=p.next}while(p!==a);return inside})(a,b)&&(area(a.prev,a,b.prev)||area(a,b.prev,b))||equals$2(a,b)&&area(a.prev,a,a.next)>0&&area(b.prev,b,b.next)>0),intersects=(p1,q1,p2,q2)=>{const o1=Math.sign(area(p1,q1,p2)),o2=Math.sign(area(p1,q1,q2)),o3=Math.sign(area(p2,q2,p1)),o4=Math.sign(area(p2,q2,q1));return o1!==o2&&o3!==o4||!(0!==o1||!onSegment(p1,p2,q1))||!(0!==o2||!onSegment(p1,q2,q1))||!(0!==o3||!onSegment(p2,p1,q2))||!(0!==o4||!onSegment(p2,q1,q2))},onSegment=(p,q,r)=>q.x<=Math.max(p.x,r.x)&&q.x>=Math.min(p.x,r.x)&&q.y<=Math.max(p.y,r.y)&&q.y>=Math.min(p.y,r.y),signedArea$1=(data,start,end,dim)=>{let sum=0;for(let i=start,j=end-dim;i<end;i+=dim)sum+=(data[j]-data[i])*(data[i+1]+data[j+1]),j=i;return sum},equals$2=(p1,p2)=>p1.x===p2.x&&p1.y===p2.y,eliminateHole=(hole,outerNode)=>{const bridge=findHoleBridge(hole,outerNode);if(!bridge)return outerNode;const bridgeReverse=splitPolygon(bridge,hole),filteredBridge=filterPoints(bridge,bridge.next);return filterPoints(bridgeReverse,bridgeReverse.next),outerNode===bridge?filteredBridge:outerNode},findHoleBridge=(hole,outerNode)=>{let p=outerNode;const hx=hole.x,hy=hole.y;let m,qx=-1/0;do{if(hy<=p.y&&hy>=p.next.y&&p.next.y!==p.y){const x=p.x+(hy-p.y)*(p.next.x-p.x)/(p.next.y-p.y);if(x<=hx&&x>qx){if(qx=x,x===hx){if(hy===p.y)return p;if(hy===p.next.y)return p.next}m=p.x<p.next.x?p:p.next}}p=p.next}while(p!==outerNode);if(!m)return null;if(hx===qx)return m;const stop=m,mx=m.x,my=m.y;let tanMin=1/0;p=m;do{if(hx>=p.x&&p.x>=mx&&hx!==p.x&&pointInTriangle(hy<my?hx:qx,hy,mx,my,hy<my?qx:hx,hy,p.x,p.y)){const tan=Math.abs(hy-p.y)/(hx-p.x);locallyInside(p,hole)&&(tan<tanMin||tan===tanMin&&(p.x>m.x||p.x===m.x&§orContainsSector(m,p)))&&(m=p,tanMin=tan)}p=p.next}while(p!==stop);return m},sectorContainsSector=(m,p)=>area(m.prev,m,p.prev)<0&&area(p.next,m,m.next)<0,getLeftmost=start=>{let p=start,leftmost=start;do{(p.x<leftmost.x||p.x===leftmost.x&&p.y<leftmost.y)&&(leftmost=p),p=p.next}while(p!==start);return leftmost},earcutLinked=(ear,triangles,dim,minX,minY,invSize,pass)=>{if(!ear)return;!pass&&invSize&&indexCurve(ear,minX,minY,invSize);let prev,next,stop=ear;for(;ear.prev!==ear.next;)if(prev=ear.prev,next=ear.next,invSize?isEarHashed(ear,minX,minY,invSize):isEar(ear))triangles.push(prev.i/dim),triangles.push(ear.i/dim),triangles.push(next.i/dim),removeNode(ear),ear=next.next,stop=next.next;else if((ear=next)===stop){pass?1===pass?(ear=cureLocalIntersections(filterPoints(ear),triangles,dim),earcutLinked(ear,triangles,dim,minX,minY,invSize,2)):2===pass&&splitEarcut(ear,triangles,dim,minX,minY,invSize):earcutLinked(filterPoints(ear),triangles,dim,minX,minY,invSize,1);break}},isEar=ear=>{const a=ear.prev,b=ear,c=ear.next;if(area(a,b,c)>=0)return!1;let p=ear.next.next;for(;p!==ear.prev;){if(pointInTriangle(a.x,a.y,b.x,b.y,c.x,c.y,p.x,p.y)&&area(p.prev,p,p.next)>=0)return!1;p=p.next}return!0},isEarHashed=(ear,minX,minY,invSize)=>{const a=ear.prev,b=ear,c=ear.next;if(area(a,b,c)>=0)return!1;const minTX=a.x<b.x?a.x<c.x?a.x:c.x:b.x<c.x?b.x:c.x,minTY=a.y<b.y?a.y<c.y?a.y:c.y:b.y<c.y?b.y:c.y,maxTX=a.x>b.x?a.x>c.x?a.x:c.x:b.x>c.x?b.x:c.x,maxTY=a.y>b.y?a.y>c.y?a.y:c.y:b.y>c.y?b.y:c.y,minZ=zOrder(minTX,minTY,minX,minY,invSize),maxZ=zOrder(maxTX,maxTY,minX,minY,invSize);let p=ear.prevZ,n=ear.nextZ;for(;p&&p.z>=minZ&&n&&n.z<=maxZ;){if(p!==ear.prev&&p!==ear.next&&pointInTriangle(a.x,a.y,b.x,b.y,c.x,c.y,p.x,p.y)&&area(p.prev,p,p.next)>=0)return!1;if(p=p.prevZ,n!==ear.prev&&n!==ear.next&&pointInTriangle(a.x,a.y,b.x,b.y,c.x,c.y,n.x,n.y)&&area(n.prev,n,n.next)>=0)return!1;n=n.nextZ}for(;p&&p.z>=minZ;){if(p!==ear.prev&&p!==ear.next&&pointInTriangle(a.x,a.y,b.x,b.y,c.x,c.y,p.x,p.y)&&area(p.prev,p,p.next)>=0)return!1;p=p.prevZ}for(;n&&n.z<=maxZ;){if(n!==ear.prev&&n!==ear.next&&pointInTriangle(a.x,a.y,b.x,b.y,c.x,c.y,n.x,n.y)&&area(n.prev,n,n.next)>=0)return!1;n=n.nextZ}return!0},splitEarcut=(start,triangles,dim,minX,minY,invSize)=>{let a=start;do{let b=a.next.next;for(;b!==a.prev;){if(a.i!==b.i&&isValidDiagonal(a,b)){let c=splitPolygon(a,b);return a=filterPoints(a,a.next),c=filterPoints(c,c.next),earcutLinked(a,triangles,dim,minX,minY,invSize),void earcutLinked(c,triangles,dim,minX,minY,invSize)}b=b.next}a=a.next}while(a!==start)},indexCurve=(start,minX,minY,invSize)=>{let p=start;do{null===p.z&&(p.z=zOrder(p.x,p.y,minX,minY,invSize)),p.prevZ=p.prev,p.nextZ=p.next,p=p.next}while(p!==start);p.prevZ.nextZ=null,p.prevZ=null,((list,fn)=>{let i,p,q,e,numMerges,inSize=1;do{p=list,list=null;let tail=null;for(numMerges=0;p;){numMerges++,q=p;let pSize=0;for(i=0;i<inSize&&(pSize++,q=q.nextZ,q);i++);let qSize=inSize;for(;pSize>0||qSize>0&&q;)0!==pSize&&(0===qSize||!q||fn(p)<=fn(q))?(e=p,p=p.nextZ,pSize--):(e=q,q=q.nextZ,qSize--),tail?tail.nextZ=e:list=e,e.prevZ=tail,tail=e;p=q}tail.nextZ=null,inSize*=2}while(numMerges>1)})(p,p=>p.z)},zOrder=(x,y,minX,minY,invSize)=>(x=1431655765&((x=858993459&((x=252645135&((x=16711935&((x=32767*(x-minX)*invSize)|x<<8))|x<<4))|x<<2))|x<<1))|(y=1431655765&((y=858993459&((y=252645135&((y=16711935&((y=32767*(y-minY)*invSize)|y<<8))|y<<4))|y<<2))|y<<1))<<1;class PolygonHierarchy{constructor(slice){this.plane=(slice=>{if(slice.contours.length<1)throw new Error("slices must have at least one contour to calculate a plane");const middle=[0,0,0];let n=0;slice.contours.forEach(contour=>{contour.forEach(vertex=>{add$1(middle,middle,vertex),n++})}),scale$3(middle,middle,1/n);let farthestBefore,farthestVertex,farthestAfter,farthestContour=[],distance=0;slice.contours.forEach(contour=>{let prev=contour[contour.length-1];contour.forEach(vertex=>{if(!equals$8(prev,vertex)){const d=squaredDistance$1(middle,vertex);d>distance&&(farthestContour=contour,farthestBefore=prev,farthestVertex=vertex,distance=d)}prev=vertex})});let prev=farthestContour[farthestContour.length-1];for(let i=0;i<farthestContour.length;i++){const vertex=farthestContour[i];if(!equals$8(prev,vertex)&&equals$8(prev,farthestVertex)){farthestAfter=vertex;break}prev=vertex}return fromPoints$3([0,0,0,0],farthestBefore,farthestVertex,farthestAfter)})(slice);const rightVector=orthogonal([0,0,0],this.plane),perp=cross$1([0,0,0],this.plane,rightVector);this.v=normalize$1(perp,perp),this.u=cross$1([0,0,0],this.v,this.plane),this.basisMap=new Map;const projected=slice.contours.map(part=>part.map(v=>this.to2D(v))),geometry=create$b(projected);this.roots=(geometry=>{const outlines=toOutlines(geometry),solids=[],holes=[];outlines.forEach((outline,i)=>{const a=area$1(outline);a<0?holes.push(i):a>0&&solids.push(i)});const children=[],parents=[];return solids.forEach((s,i)=>{const solid=outlines[s];children[i]=[],holes.forEach((h,j)=>{const hole=outlines[h];arePointsInside([hole[0]],create$3(solid))&&(children[i].push(h),parents[j]||(parents[j]=[]),parents[j].push(i))})}),holes.forEach((h,j)=>{if(parents[j]&&parents[j].length>1){const directParent=((list,score)=>{let bestIndex,best;return list.forEach((item,index)=>{const value=score(item);(void 0===best||value<best)&&(bestIndex=index,best=value)}),bestIndex})(parents[j],p=>children[p].length);parents[j].forEach((p,i)=>{i!==directParent&&(children[p]=children[p].filter(c=>c!==h))})}}),children.map((holes,i)=>({solid:outlines[solids[i]],holes:holes.map(h=>outlines[h])}))})(geometry)}to2D(vector3){const vector2=fromValues$2(dot$2(vector3,this.u),dot$2(vector3,this.v));return this.basisMap.set(vector2,vector3),vector2}to3D(vector2){const original=this.basisMap.get(vector2);if(original)return original;{console.log("Warning: point not in original slice");const v1=scale$3([0,0,0],this.u,vector2[0]),v2=scale$3([0,0,0],this.v,vector2[1]),planeOrigin=scale$3([0,0,0],this.plane,this.plane[3]),v3=add$1(v1,v1,planeOrigin);return add$1(v2,v2,v3)}}}const toPolygons=slice=>{const hierarchy=new PolygonHierarchy(slice),polygons=[];return hierarchy.roots.forEach(({solid:solid,holes:holes})=>{let index=solid.length;const holesIndex=[];holes.forEach((hole,i)=>{holesIndex.push(index),index+=hole.length});const vertices=[solid,...holes].flat(),getVertex=i=>hierarchy.to3D(vertices[i]),indices=((data,holeIndices,dim=2)=>{const hasHoles=holeIndices&&holeIndices.length,outerLen=hasHoles?holeIndices[0]*dim:data.length;let outerNode=linkedPolygon(data,0,outerLen,dim,!0);const triangles=[];if(!outerNode||outerNode.next===outerNode.prev)return triangles;let minX,minY,maxX,maxY,invSize;if(hasHoles&&(outerNode=((data,holeIndices,outerNode,dim)=>{const queue=[];for(let i=0,len=holeIndices.length;i<len;i++){const start=holeIndices[i]*dim,end=i<len-1?holeIndices[i+1]*dim:data.length,list=linkedPolygon(data,start,end,dim,!1);list===list.next&&(list.steiner=!0),queue.push(getLeftmost(list))}queue.sort((a,b)=>a.x-b.x);for(let i=0;i<queue.length;i++)outerNode=eliminateHole(queue[i],outerNode),outerNode=filterPoints(outerNode,outerNode.next);return outerNode})(data,holeIndices,outerNode,dim)),data.length>80*dim){minX=maxX=data[0],minY=maxY=data[1];for(let i=dim;i<outerLen;i+=dim){const x=data[i],y=data[i+1];x<minX&&(minX=x),y<minY&&(minY=y),x>maxX&&(maxX=x),y>maxY&&(maxY=y)}invSize=Math.max(maxX-minX,maxY-minY),invSize=0!==invSize?1/invSize:0}return earcutLinked(outerNode,triangles,dim,minX,minY,invSize),triangles})(vertices.flat(),holesIndex);for(let i=0;i<indices.length;i+=3){const tri=indices.slice(i,i+3).map(getVertex);polygons.push(fromVerticesAndPlane(tri,hierarchy.plane))}}),polygons},transform$4=(matrix,slice)=>{const contours=slice.contours.map(contour=>contour.map(vertex=>transform$d([0,0,0],vertex,matrix)));return create$2(contours)},create$1=()=>[0,1,0],direction$1=line=>{const vector=normal([0,0],line);return negate(vector,vector),vector},fromPoints$1=(out,point1,point2)=>{const vector=subtract$1([0,0],point2,point1);normal(vector,vector),normalize(vector,vector);const distance=dot$1(point1,vector);return out[0]=vector[0],out[1]=vector[1],out[2]=distance,out},cache$2=new WeakMap,expand2=(bbox,point)=>{0===bbox.length?(bbox[0]=fromVec2([0,0,0],point),bbox[1]=fromVec2([0,0,0],point)):(min(bbox[0],bbox[0],point),max(bbox[1],bbox[1],point))},expand3=(bbox,vertex)=>{0===bbox.length?(bbox[0]=clone$9(vertex),bbox[1]=clone$9(vertex)):(min$1(bbox[0],bbox[0],vertex),max$1(bbox[1],bbox[1],vertex))},measureCached$1=(geometry,measureFn)=>{let boundingBox=cache$2.get(geometry);return boundingBox||(boundingBox=measureFn(geometry),0===boundingBox.length&&(boundingBox[0]=[0,0,0],boundingBox[1]=[0,0,0]),cache$2.set(geometry,boundingBox),boundingBox)},measureBoundingBoxOfPath2=geometry=>{const boundingBox=[];return toPoints$1(geometry).forEach(point=>{expand2(boundingBox,point)}),boundingBox},measureBoundingBoxOfGeom2=geometry=>{const boundingBox=[];return toPoints$2(geometry).forEach(point=>{expand2(boundingBox,point)}),boundingBox},measureBoundingBoxOfGeom3=geometry=>{const boundingBox=[];return toPolygons$1(geometry).forEach(polygon=>{toVertices$3(polygon).forEach(vertex=>{expand3(boundingBox,vertex)})}),boundingBox},measureBoundingBoxOfSlice=geometry=>{const boundingBox=[];return geometry.contours.forEach(contour=>{contour.forEach(vertex=>{expand3(boundingBox,vertex)})}),boundingBox},measureBoundingBox=(...geometries)=>{const results=(geometries=flatten(geometries)).map(geometry=>isA$3(geometry)?measureCached$1(geometry,measureBoundingBoxOfPath2):isA$6(geometry)?measureCached$1(geometry,measureBoundingBoxOfGeom2):isA$4(geometry)?measureCached$1(geometry,measureBoundingBoxOfGeom3):isA(geometry)?measureCached$1(geometry,measureBoundingBoxOfSlice):[[0,0,0],[0,0,0]]);return 1===results.length?results[0]:results},calculateEpsilonFromBounds=(bounds,dimensions)=>{let total=0;for(let i=0;i<dimensions;i++)total+=bounds[1][i]-bounds[0][i];return EPS$1*total/dimensions},isNumberArray=(array,dimension)=>!!(Array.isArray(array)&&array.length>=dimension)&&array.every(n=>Number.isFinite(n)),isGTE=(value,constant)=>Number.isFinite(value)&&value>=constant,arc=options=>{const defaults={center:[0,0],radius:1,startAngle:0,endAngle:TAU,makeTangent:!1,segments:32};let{center:center,radius:radius,startAngle:startAngle,endAngle:endAngle,makeTangent:makeTangent,segments:segments}=Object.assign({},defaults,options);if(!isNumberArray(center,2))throw new Error("center must be an array of X and Y values");if(value=radius,constant=0,!(Number.isFinite(value)&&value>constant))throw new Error("radius must be greater than zero");var value,constant;if(!isGTE(startAngle,0))throw new Error("startAngle must be positive");if(!isGTE(endAngle,0))throw new Error("endAngle must be positive");if(!isGTE(segments,4))throw new Error("segments must be four or more");startAngle%=TAU,endAngle%=TAU;let rotation=TAU;startAngle<endAngle&&(rotation=endAngle-startAngle),startAngle>endAngle&&(rotation=endAngle+(TAU-startAngle));const minAngle=Math.acos((radius*radius+radius*radius-EPS$1*EPS$1)/(2*radius*radius)),centerV=clone$8(center);let point;const pointArray=[];if(rotation<minAngle)point=fromAngleRadians([0,0],startAngle),scale$1(point,point,radius),add(point,point,centerV),pointArray.push(point);else{const numSteps=Math.floor(segments*(Math.abs(rotation)/TAU));let edgeStepSize=.5*numSteps/rotation;edgeStepSize>.25&&(edgeStepSize=.25);const totalSteps=makeTangent?numSteps+2:numSteps;for(let i=0;i<=totalSteps;i++){let step=i;makeTangent&&(step=(i-1)*(numSteps-2*edgeStepSize)/numSteps+edgeStepSize,step<0&&(step=0),step>numSteps&&(step=numSteps));const angle=startAngle+step*(rotation/numSteps);point=fromAngleRadians(create$a(),angle),scale$1(point,point,radius),add(point,point,centerV),pointArray.push(point)}}return fromPoints$2({closed:!1},pointArray)},ellipse=options=>{const defaults={center:[0,0],radius:[1,1],startAngle:0,endAngle:TAU,segments:32};let{center:center,radius:radius,startAngle:startAngle,endAngle:endAngle,segments:segments}=Object.assign({},defaults,options);if(!isNumberArray(center,2))throw new Error("center must be an array of X and Y values");if(!isNumberArray(radius,2))throw new Error("radius must be an array of X and Y values");if(!radius.every(n=>n>=0))throw new Error("radius values must be positive");if(!isGTE(startAngle,0))throw new Error("startAngle must be positive");if(!isGTE(endAngle,0))throw new Error("endAngle must be positive");if(!isGTE(segments,3))throw new Error("segments must be three or more");if(0===radius[0]||0===radius[1])return create$b();startAngle%=TAU,endAngle%=TAU;let rotation=TAU;startAngle<endAngle&&(rotation=endAngle-startAngle),startAngle>endAngle&&(rotation=endAngle+(TAU-startAngle));const minRadius=Math.min(radius[0],radius[1]);if(rotation<Math.acos((minRadius*minRadius+minRadius*minRadius-EPS$1*EPS$1)/(2*minRadius*minRadius)))throw new Error("startAngle and endAngle do not define a significant rotation");segments=Math.floor(segments*(rotation/TAU));const centerV=clone$8(center),step=rotation/segments,points=[];segments=rotation<TAU?segments+1:segments;for(let i=0;i<segments;i++){const angle=step*i+startAngle,point=fromValues$2(radius[0]*cos(angle),radius[1]*sin(angle));add(point,centerV,point),points.push(point)}return rotation<TAU&&points.push(centerV),create$b([points])},circle=options=>{const defaults={center:[0,0],radius:1,startAngle:0,endAngle:TAU,segments:32};let{center:center,radius:radius,startAngle:startAngle,endAngle:endAngle,segments:segments}=Object.assign({},defaults,options);if(!isGTE(radius,0))throw new Error("radius must be positive");return radius=[radius,radius],ellipse({center:center,radius:radius,startAngle:startAngle,endAngle:endAngle,segments:segments})},line=points=>{if(!Array.isArray(points))throw new Error("points must be an array");return fromPoints$2({},points)},sphere=options=>{let{center:center,radius:radius,segments:segments,axes:axes}=Object.assign({},{center:[0,0,0],radius:1,segments:32,axes:[[1,0,0],[0,-1,0],[0,0,1]]},options);if(!isGTE(radius,0))throw new Error("radius must be positive");return radius=[radius,radius,radius],(options=>{const{center:center,radius:radius,segments:segments,axes:axes}=Object.assign({},{center:[0,0,0],radius:[1,1,1],segments:32,axes:[[1,0,0],[0,-1,0],[0,0,1]]},options);if(!isNumberArray(center,3))throw new Error("center must be an array of X, Y and Z values");if(!isNumberArray(radius,3))throw new Error("radius must be an array of X, Y and Z values");if(!radius.every(n=>n>=0))throw new Error("radius values must be positive");if(!isGTE(segments,4))throw new Error("segments must be four or more");if(0===radius[0]||0===radius[1]||0===radius[2])return create$9();const xVector=scale$3([0,0,0],normalize$1([0,0,0],axes[0]),radius[0]),yVector=scale$3([0,0,0],normalize$1([0,0,0],axes[1]),radius[1]),zVector=scale$3([0,0,0],normalize$1([0,0,0],axes[2]),radius[2]),qSegments=Math.round(segments/4);let prevCylinderVertex;const polygons=[],p1=[0,0,0],p2=[0,0,0];for(let slice1=0;slice1<=segments;slice1++){const angle=TAU*slice1/segments,cylinderVertex=add$1(create$c(),scale$3(p1,xVector,cos(angle)),scale$3(p2,yVector,sin(angle)));if(slice1>0){let prevCosPitch,prevSinPitch;for(let slice2=0;slice2<=qSegments;slice2++){const pitch=TAU/4*slice2/qSegments,cosPitch=cos(pitch),sinPitch=sin(pitch);if(slice2>0){let vertex,vertices=[];vertex=subtract$3(create$c(),scale$3(p1,prevCylinderVertex,prevCosPitch),scale$3(p2,zVector,prevSinPitch)),vertices.push(add$1(vertex,vertex,center)),vertex=subtract$3(create$c(),scale$3(p1,cylinderVertex,prevCosPitch),scale$3(p2,zVector,prevSinPitch)),vertices.push(add$1(vertex,vertex,center)),slice2<qSegments&&(vertex=subtract$3(create$c(),scale$3(p1,cylinderVertex,cosPitch),scale$3(p2,zVector,sinPitch)),vertices.push(add$1(vertex,vertex,center))),vertex=subtract$3(create$c(),scale$3(p1,prevCylinderVertex,cosPitch),scale$3(p2,zVector,sinPitch)),vertices.push(add$1(vertex,vertex,center)),polygons.push(create$8(vertices)),vertices=[],vertex=add$1(create$c(),scale$3(p1,prevCylinderVertex,prevCosPitch),scale$3(p2,zVector,prevSinPitch)),vertices.push(add$1(create$c(),center,vertex)),vertex=add$1(vertex,scale$3(p1,cylinderVertex,prevCosPitch),scale$3(p2,zVector,prevSinPitch)),vertices.push(add$1(create$c(),center,vertex)),slice2<qSegments&&(vertex=add$1(vertex,scale$3(p1,cylinderVertex,cosPitch),scale$3(p2,zVector,sinPitch)),vertices.push(add$1(create$c(),center,vertex))),vertex=add$1(vertex,scale$3(p1,prevCylinderVertex,cosPitch),scale$3(p2,zVector,sinPitch)),vertices.push(add$1(create$c(),center,vertex)),vertices.reverse(),polygons.push(create$8(vertices))}prevCosPitch=cosPitch,prevSinPitch=sinPitch}}prevCylinderVertex=cylinderVertex}return create$9(polygons)})({center:center,radius:radius,segments:segments,axes:axes})},mirror=(options,...objects)=>{const{origin:origin,normal:normal}=Object.assign({},{origin:[0,0,0],normal:[0,0,1]},options),planeOfMirror=fromNormalAndPoint([0,0,0,0],normal,origin);if(Number.isNaN(planeOfMirror[0]))throw new Error("the given origin and normal do not define a proper plane");const matrix=mirrorByPlane([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],planeOfMirror),results=objects.map(object=>isA$3(object)?transform$7(matrix,object):isA$6(object)?transform$b(matrix,object):isA$4(object)?transform$8(matrix,object):Array.isArray(object)?mirror(options,...object):object);return 1===results.length?results[0]:results},gcd=(a,b)=>a===b?a:a<b?gcd(b,a):1===b?1:0===b?a:gcd(b,a%b),repartitionEdges=(newLength,edges)=>{const multiple=newLength/edges.length;if(1===multiple)return edges;const divisor=fromValues$3(multiple,multiple,multiple),increment=[0,0,0],newEdges=[];return edges.forEach(edge=>{subtract$3(increment,edge[1],edge[0]),divide$1(increment,increment,divisor);let prev=edge[0];for(let i=1;i<=multiple;++i){const next=add$1(create$c(),prev,increment);newEdges.push([prev,next]),prev=next}}),newEdges},EPSAREA=EPS$1*EPS$1/2*Math.sin(Math.PI/3),extrudeWalls=(slice0,slice1)=>{let edges0=toEdges(slice0),edges1=toEdges(slice1);if(edges0.length!==edges1.length){const newLength=(a=edges0.length)*(b=edges1.length)/gcd(a,b);newLength!==edges0.length&&(edges0=repartitionEdges(newLength,edges0)),newLength!==edges1.length&&(edges1=repartitionEdges(newLength,edges1))}var a,b;const walls=[];return edges0.forEach((edge0,i)=>{const edge1=edges1[i],poly0=create$8([edge0[0],edge0[1],edge1[1]]),poly0area=measureArea$2(poly0);Number.isFinite(poly0area)&&poly0area>EPSAREA&&walls.push(poly0);const poly1=create$8([edge0[0],edge1[1],edge1[0]]),poly1area=measureArea$2(poly1);Number.isFinite(poly1area)&&poly1area>EPSAREA&&walls.push(poly1)}),walls},defaultCallback=(progress,index,base)=>{let baseSlice=null;return isA$6(base)&&(baseSlice=fromGeom2(base)),isA$5(base)&&(baseSlice=(vertices=>{if(!Array.isArray(vertices))throw new Error("the given vertices must be an array");if(vertices.length<3)throw new Error("the given vertices must contain THREE or more vertices");const cloned=vertices.map(vertex=>3===vertex.length?vertex:fromVec2([0,0,0],vertex));return create$2([cloned])})(toVertices$3(base))),0===progress||1===progress?transform$4(fromTranslation([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],[0,0,progress]),baseSlice):null},extrudeFromSlices=(options,base)=>{const defaults={numberOfSlices:2,capStart:!0,capEnd:!0,close:!1,callback:defaultCallback},{numberOfSlices:numberOfSlices,capStart:capStart,capEnd:capEnd,close:close,callback:generate}=Object.assign({},defaults,options);if(numberOfSlices<2)throw new Error("numberOfSlices must be 2 or more");const sMax=numberOfSlices-1;let startSlice=null,endSlice=null,prevSlice=null;const polygons=[];for(let s=0;s<numberOfSlices;s++){const currentSlice=generate(s/sMax,s,base);if(currentSlice){if(!isA(currentSlice))throw new Error("the callback function must return slice objects");if(0===currentSlice.contours.length)throw new Error("the callback function must return slices with one or more contours");if(prevSlice){const walls=extrudeWalls(prevSlice,currentSlice);for(let i=0;i<walls.length;i++)polygons.push(walls[i])}0===s&&(startSlice=currentSlice),s===numberOfSlices-1&&(endSlice=currentSlice),prevSlice=currentSlice}}if(capEnd){const endPolygons=toPolygons(endSlice);for(let i=0;i<endPolygons.length;i++)polygons.push(endPolygons[i])}if(capStart){const startPolygons=toPolygons(startSlice).map(invert$1);for(let i=0;i<startPolygons.length;i++)polygons.push(startPolygons[i])}if(!capStart&&!capEnd&&close&&!((a,b)=>{if(a.contours.length!==b.contours.length)return!1;const len=a.contours.length;for(let i=0;i<len;i++){const aVertex=a.contours[i];for(let j=0;j<len;j++){const bVertex=b.contours[j];if(!equals$8(aVertex,bVertex))return!1}}return!0})(endSlice,startSlice)){const walls=extrudeWalls(endSlice,startSlice);for(let i=0;i<walls.length;i++)polygons.push(walls[i])}return create$9(polygons)},flattenHelper=(arr,out)=>(Array.isArray(arr)?arr.forEach(child=>flattenHelper(child,out)):null!=arr&&void 0!==arr&&out.push(arr),out),DEFAULT_COMPARE=(a,b)=>a>b?1:a<b?-1:0;let Node$1=class{constructor(key,data){this.key=key,this.data=data,this.left=null,this.right=null,this.next=null}};const splay=(key,t,comparator)=>{const N=new Node$1(null,null);let left=N,right=N;for(;;){const cmp=comparator(key,t.key);if(cmp<0){if(null===t.left)break;if(comparator(key,t.left.key)<0){const y=t.left;if(t.left=y.right,y.right=t,null===(t=y).left)break}right.left=t,right=t,t=t.left}else{if(!(cmp>0))break;if(null===t.right)break;if(comparator(key,t.right.key)>0){const y=t.right;if(t.right=y.left,y.left=t,null===(t=y).right)break}left.right=t,left=t,t=t.right}}return left.right=t.left,right.left=t.right,t.left=N.right,t.right=N.left,t};let Tree$1=class{constructor(comparator=DEFAULT_COMPARE){this.comparator=comparator,this._root=null}insert(key,data){return this._root=((key,data,root,comparator)=>{const node=new Node$1(key,data);if(null===root)return node;const cmp=comparator(key,(root=splay(key,root,comparator)).key);return cmp<0?(node.left=root.left,node.right=root,root.left=null):cmp>=0&&(node.right=root.right,node.left=root,root.right=null),node})(key,data,this._root,this.comparator),this._root}remove(key){this._root=this._remove(key)}_remove(key){if(null===this._root)return null;let x;const t=splay(key,this._root,this.comparator);return 0===this.comparator(key,t.key)?(null===t.left?x=t.right:(x=splay(key,t.left,this.comparator),x.right=t.right),x):t}find(key){return this._root&&(this._root=splay(key,this._root,this.comparator),0!==this.comparator(key,this._root.key))?null:this._root}minNode(t=this._root){if(t)for(;t.left;)t=t.left;return t}maxNode(t=this._root){if(t)for(;t.right;)t=t.right;return t}next(node){let successor=null;if(node.right){for(successor=node.right;successor.left;)successor=successor.left;return successor}let root=this._root;for(;root;){const cmp=this.comparator(node.key,root.key);if(0===cmp)break;cmp<0?(successor=root,root=root.left):root=root.right}return successor}prev(node){let predecessor=null;if(node.left){for(predecessor=node.left;predecessor.right;)predecessor=predecessor.right;return predecessor}let root=this._root;for(;root;){const cmp=this.comparator(node.key,root.key);if(0===cmp)break;cmp<0?root=root.left:(predecessor=root,root=root.right)}return predecessor}};const computeFields=(event,prev,operation)=>{null===prev?(event.inOut=!1,event.otherInOut=!0):(event.isSubject===prev.isSubject?(event.inOut=!prev.inOut,event.otherInOut=prev.otherInOut):(event.inOut=!prev.otherInOut,event.otherInOut=prev.isVertical()?!prev.inOut:prev.inOut),prev&&(event.prevInResult=!inResult(prev,operation)||prev.isVertical()?prev.prevInResult:prev));const isInResult=inResult(event,operation);event.resultTransition=isInResult?determineResultTransition(event,operation):0},inResult=(event,operation)=>{switch(event.type){case 0:switch(operation){case 0:return!event.otherInOut;case 1:return event.otherInOut;case 2:return event.isSubject&&event.otherInOut||!event.isSubject&&!event.otherInOut;case 3:return!0}break;case 2:return 0===operation||1===operation;case 3:return 2===operation;case 1:return!1}return!1},determineResultTransition=(event,operation)=>{const thisIn=!event.inOut,thatIn=!event.otherInOut;let isIn;switch(operation){case 0:isIn=thisIn&&thatIn;break;case 1:isIn=thisIn||thatIn;break;case 3:isIn=thisIn^thatIn;break;case 2:isIn=event.isSubject?thisIn&&!thatIn:thatIn&&!thisIn}return isIn?1:-1};class SweepEvent{constructor(point,left,otherEvent,isSubject,type=0){this.left=left,this.point=point,this.otherEvent=otherEvent,this.isSubject=isSubject,this.type=type,this.inOut=!1,this.otherInOut=!1,this.prevInResult=null,this.resultTransition=0,this.otherPos=-1,this.outputContourId=-1,this.isExteriorRing=!0}isBelow(p){const p0=this.point,p1=this.otherEvent.point;return this.left?(p0[0]-p[0])*(p1[1]-p[1])-(p1[0]-p[0])*(p0[1]-p[1])>0:(p1[0]-p[0])*(p0[1]-p[1])-(p0[0]-p[0])*(p1[1]-p[1])>0}isAbove(p){return!this.isBelow(p)}isVertical(){return this.point[0]===this.otherEvent.point[0]}get inResult(){return 0!==this.resultTransition}}const signedArea=(p0,p1,p2)=>{const res=(ax=p0[0],ay=p0[1],bx=p1[0],by=p1[1],cx=p2[0],(ay-(cy=p2[1]))*(bx-cx)-(ax-cx)*(by-cy));var ax,ay,bx,by,cx,cy;return res>0?-1:res<0?1:0},compareEvents=(e1,e2)=>{const p1=e1.point,p2=e2.point;return p1[0]>p2[0]?1:p1[0]<p2[0]?-1:p1[1]!==p2[1]?p1[1]>p2[1]?1:-1:e1.left!==e2.left?e1.left?1:-1:0!==signedArea(p1,e1.otherEvent.point,e2.otherEvent.point)?e1.isBelow(e2.otherEvent.point)?-1:1:!e1.isSubject&&e2.isSubject?1:-1},divideSegment=(segment,point,queue)=>{const r=new SweepEvent(point,!1,segment,segment.isSubject),l=new SweepEvent(point,!0,segment.otherEvent,segment.isSubject);return r.contourId=l.contourId=segment.contourId,compareEvents(l,segment.otherEvent)>0&&(segment.otherEvent.left=!0,l.left=!1),segment.otherEvent.otherEvent=l,segment.otherEvent=r,queue.push(l),queue.push(r),queue},crossProduct=(a,b)=>a[0]*b[1]-a[1]*b[0],possibleIntersection=(se1,se2,queue)=>{const inter=((a1,a2,b1,b2,noEndpointTouch=!1)=>{const va=[a2[0]-a1[0],a2[1]-a1[1]],vb=[b2[0]-b1[0],b2[1]-b1[1]],toPoint=(p,s,d)=>[p[0]+s*d[0],p[1]+s*d[1]],v1=[b1[0]-a1[0],b1[1]-a1[1]];let kross=crossProduct(va,vb),sqrKross=kross*kross;if(sqrKross>0){const s=crossProduct(v1,vb)/kross;if(s<0||s>1)return null;const t=crossProduct(v1,va)/kross;return t<0||t>1?null:0===s||1===s?noEndpointTouch?null:[toPoint(a1,s,va)]:0===t||1===t?noEndpointTouch?null:[toPoint(b1,t,vb)]:[toPoint(a1,s,va)]}if(kross=crossProduct(v1,va),sqrKross=kross*kross,sqrKross>0)return null;const sqrLenA=dot$1(va,va),sa=dot$1(va,v1)/sqrLenA,sb=sa+dot$1(va,vb)/sqrLenA,smin=Math.min(sa,sb),smax=Math.max(sa,sb);return smin<=1&&smax>=0?1===smin?noEndpointTouch?null:[toPoint(a1,smin>0?smin:0,va)]:0===smax?noEndpointTouch?null:[toPoint(a1,smax<1?smax:1,va)]:noEndpointTouch&&0===smin&&1===smax?null:[toPoint(a1,smin>0?smin:0,va),toPoint(a1,smax<1?smax:1,va)]:null})(se1.point,se1.otherEvent.point,se2.point,se2.otherEvent.point),nIntersections=inter?inter.length:0;if(0===nIntersections)return 0;if(1===nIntersections&&(equals$7(se1.point,se2.point)||equals$7(se1.otherEvent.point,se2.otherEvent.point)))return 0;if(1===nIntersections)return equals$7(se1.point,inter[0])||equals$7(se1.otherEvent.point,inter[0])||divideSegment(se1,inter[0],queue),equals$7(se2.point,inter[0])||equals$7(se2.otherEvent.point,inter[0])||divideSegment(se2,inter[0],queue),1;if(2===nIntersections&&se1.isSubject===se2.isSubject)return 0;const segmentEvents=[];let leftCoincide=!1,rightCoincide=!1;return equals$7(se1.point,se2.point)?leftCoincide=!0:1===compareEvents(se1,se2)?segmentEvents.push(se2,se1):segmentEvents.push(se1,se2),equals$7(se1.otherEvent.point,se2.otherEvent.point)?rightCoincide=!0:1===compareEvents(se1.otherEvent,se2.otherEvent)?segmentEvents.push(se2.otherEvent,se1.otherEvent):segmentEvents.push(se1.otherEvent,se2.otherEvent),leftCoincide?(se2.type=1,se1.type=se2.inOut===se1.inOut?2:3,rightCoincide||divideSegment(segmentEvents[1].otherEvent,segmentEvents[0].point,queue),2):rightCoincide?(divideSegment(segmentEvents[0],segmentEvents[1].point,queue),3):segmentEvents[0]!==segmentEvents[3].otherEvent?(divideSegment(segmentEvents[0],segmentEvents[1].point,queue),divideSegment(segmentEvents[1],segmentEvents[2].point,queue),4):(divideSegment(segmentEvents[0],segmentEvents[1].point,queue),divideSegment(segmentEvents[3].otherEvent,segmentEvents[2].point,queue),5)},compareSegments=(le1,le2)=>{if(le1===le2)return 0;if(0!==signedArea(le1.point,le1.otherEvent.point,le2.point)||0!==signedArea(le1.point,le1.otherEvent.point,le2.otherEvent.point))return equals$7(le1.point,le2.point)?le1.isBelow(le2.otherEvent.point)?-1:1:le1.point[0]===le2.point[0]?le1.point[1]<le2.point[1]?-1:1:1===compareEvents(le1,le2)?le2.isAbove(le1.point)?-1:1:le1.isBelow(le2.point)?-1:1;if(le1.isSubject!==le2.isSubject)return le1.isSubject?-1:1;{let p1=le1.point,p2=le2.point;if(p1[0]===p2[0]&&p1[1]===p2[1])return p1=le1.otherEvent.point,p2=le2.otherEvent.point,p1[0]===p2[0]&&p1[1]===p2[1]?0:le1.contourId>le2.contourId?1:-1}return 1===compareEvents(le1,le2)?1:-1};class Contour{constructor(){this.points=[],this.holeIds=[],this.holeOf=null,this.depth=0}isExterior(){return null==this.holeOf}}const nextPos=(pos,resultEvents,processed,origPos)=>{const length=resultEvents.length,p0=resultEvents[pos].point;let p1,newPos=pos+1;for(newPos<length&&(p1=resultEvents[newPos].point);newPos<length&&p1[0]===p0[0]&&p1[1]===p0[1];){if(!processed[newPos])return newPos;newPos++,newPos<length&&(p1=resultEvents[newPos].point)}for(newPos=pos-1;processed[newPos]&&newPos>origPos;)newPos--;return newPos},initializeContourFromContext=(event,contours,contourId)=>{const contour=new Contour;if(null!=event.prevInResult){const prevInResult=event.prevInResult,lowerContourId=prevInResult.outputContourId,lowerResultTransition=prevInResult.resultTransition;if(lowerContourId<0)contour.holeOf=null,contour.depth=0;else if(lowerResultTransition>0){const lowerContour=contours[lowerContourId];if(null!=lowerContour.holeOf){const parentContourId=lowerContour.holeOf;contours[parentContourId].holeIds.push(contourId),contour.holeOf=parentContourId,contour.depth=contours[lowerContourId].depth}else contours[lowerContourId].holeIds.push(contourId),contour.holeOf=lowerContourId,contour.depth=contours[lowerContourId].depth+1}else contour.depth=contours[lowerContourId].depth}return contour};class Queue{constructor(data,compare){if(this.data=data,this.length=this.data.length,this.compare=compare,this.length>0)for(let i=(this.length>>1)-1;i>=0;i--)this._down(i)}push(item){this.data.push(item),this._up(this.length++)}pop(){if(0===this.length)return;const top=this.data[0],bottom=this.data.pop();return--this.length>0&&(this.data[0]=bottom,this._down(0)),top}peek(){return this.data[0]}_up(pos){const{data:data,compare:compare}=this,item=data[pos];for(;pos>0;){const parent=pos-1>>1,current=data[parent];if(compare(item,current)>=0)break;data[pos]=current,pos=parent}data[pos]=item}_down(pos){const{data:data,compare:compare}=this,halfLength=this.length>>1,item=data[pos];for(;pos<halfLength;){let bestChild=1+(pos<<1);const right=bestChild+1;if(right<this.length&&compare(data[right],data[bestChild])<0&&(bestChild=right),compare(data[bestChild],item)>=0)break;data[pos]=data[bestChild],pos=bestChild}data[pos]=item}}let externalRingId=0;const processPolygon=(contourOrHole,isSubject,ringId,queue,bbox,isExteriorRing)=>{const len=contourOrHole.length-1;for(let i=0;i<len;i++){const s1=contourOrHole[i],s2=contourOrHole[i+1],e1=new SweepEvent(s1,!1,void 0,isSubject),e2=new SweepEvent(s2,!1,e1,isSubject);if(e1.otherEvent=e2,s1[0]===s2[0]&&s1[1]===s2[1])continue;e1.contourId=e2.contourId=ringId,isExteriorRing||(e1.isExteriorRing=!1,e2.isExteriorRing=!1),compareEvents(e1,e2)>0?e2.left=!0:e1.left=!0;const x=s1[0],y=s1[1];bbox[0]=Math.min(bbox[0],x),bbox[1]=Math.min(bbox[1],y),bbox[2]=Math.max(bbox[2],x),bbox[3]=Math.max(bbox[3],y),queue.push(e1),queue.push(e2)}},EMPTY=[],toMartinez=geometry=>{const outlines=[];return toOutlines(geometry).forEach(outline=>{equals$7(outline[0],outline[outline.length-1])?outlines.push(outline):outlines.push([...outline,outline[0]])}),[outlines]},fromOutlines=outlines=>(outlines.forEach(outline=>{equals$7(outline[0],outline[outline.length-1])&&outline.pop()}),outlines=outlines.filter(o=>o.length>=3),create$b(outlines)),boolean=(subjectGeom,clippingGeom,operation)=>{const subject=toMartinez(subjectGeom),clipping=toMartinez(clippingGeom);let trivial=((subject,clipping)=>{let result=null;return subject.length*clipping.length===0&&(result=0===subject.length?clipping:subject),result===EMPTY?create$b():result?fromOutlines(result.flat()):null})(subject,clipping);if(trivial)return trivial;const sbbox=[1/0,1/0,-1/0,-1/0],cbbox=[1/0,1/0,-1/0,-1/0],eventQueue=((subject,clipping,sbbox,cbbox)=>{const eventQueue=new Queue([],compareEvents);for(let i=0;i<subject.length;i++){const polygonSet=subject[i];for(let j=0;j<polygonSet.length;j++){const isExteriorRing=0===j;isExteriorRing&&externalRingId++,processPolygon(polygonSet[j],!0,externalRingId,eventQueue,sbbox,isExteriorRing)}}for(let i=0;i<clipping.length;i++){const polygonSet=clipping[i];for(let j=0;j<polygonSet.length;j++){let isExteriorRing=0===j;isExteriorRing&&externalRingId++,processPolygon(polygonSet[j],!1,externalRingId,eventQueue,cbbox,isExteriorRing)}}return eventQueue})(subject,clipping,sbbox,cbbox);if(trivial=((subject,clipping,sbbox,cbbox)=>{let result=null;return(sbbox[0]>cbbox[2]||cbbox[0]>sbbox[2]||sbbox[1]>cbbox[3]||cbbox[1]>sbbox[3])&&(result=subject.concat(clipping)),result===EMPTY?create$b():result?fromOutlines(result.flat()):null})(subject,clipping,sbbox,cbbox),trivial)return trivial;const sortedEvents=((eventQueue,subject,clipping,sbbox,cbbox,operation)=>{const sweepLine=new Tree$1(compareSegments),sortedEvents=[];let prev,next,begin;for(;0!==eventQueue.length;){const event=eventQueue.pop();if(sortedEvents.push(event),event.left){next=prev=sweepLine.insert(event),begin=sweepLine.minNode(),prev=prev!==begin?sweepLine.prev(prev):null,next=sweepLine.next(next);const prevEvent=prev?prev.key:null;let prevprevEvent;if(computeFields(event,prevEvent,operation),next&&2===possibleIntersection(event,next.key,eventQueue)&&(computeFields(event,prevEvent,operation),computeFields(next.key,event,operation)),prev&&2===possibleIntersection(prev.key,event,eventQueue)){let prevprev=prev;prevprev=prevprev!==begin?sweepLine.prev(prevprev):null,prevprevEvent=prevprev?prevprev.key:null,computeFields(prevEvent,prevprevEvent,operation),computeFields(event,prevEvent,operation)}}else next=prev=sweepLine.find(event.otherEvent),prev&&next&&(prev=prev!==begin?sweepLine.prev(prev):null,next=sweepLine.next(next),sweepLine.remove(event.otherEvent),next&&prev&&possibleIntersection(prev.key,next.key,eventQueue))}return sortedEvents})(eventQueue,0,0,0,0,operation),contours=(sortedEvents=>{const resultEvents=(sortedEvents=>{const resultEvents=[];sortedEvents.forEach(e=>{(e.left&&e.inResult||!e.left&&e.otherEvent.inResult)&&resultEvents.push(e)});let sorted=!1;for(;!sorted;){sorted=!0;const len=resultEvents.length;for(let i=0;i<len;i++)if(i+1<len&&1===compareEvents(resultEvents[i],resultEvents[i+1])){const tmp=resultEvents[i];resultEvents[i]=resultEvents[i+1],resultEvents[i+1]=tmp,sorted=!1}}return resultEvents.forEach((e,i)=>{e.otherPos=i}),resultEvents.forEach(e=>{if(!e.left){const otherPos=e.otherPos;e.otherPos=e.otherEvent.otherPos,e.otherEvent.otherPos=otherPos}}),resultEvents})(sortedEvents),evlen=resultEvents.length,processed=[],contours=[];for(let i=0;i<evlen;i++){if(processed[i])continue;const contourId=contours.length,contour=initializeContourFromContext(resultEvents[i],contours,contourId),markAsProcessed=pos=>{processed[pos]=!0,pos<evlen&&(resultEvents[pos].outputContourId=contourId)};let pos=i;const origPos=i;for(contour.points.push(resultEvents[pos].point);markAsProcessed(pos),pos=resultEvents[pos].otherPos,markAsProcessed(pos),contour.points.push(resultEvents[pos].point),pos=nextPos(pos,resultEvents,processed,origPos),!(pos===origPos||pos>=evlen););contours.push(contour)}return contours})(sortedEvents),polygons=[];for(let i=0;i<contours.length;i++){const contour=contours[i];if(contour.isExterior()){const rings=[contour.points];for(let j=0;j<contour.holeIds.length;j++){const holePoints=contours[contour.holeIds[j]].points,hole=[];for(let k=holePoints.length-2;k>=0;k--)hole.push(holePoints[k]);rings.push(hole)}polygons.push(rings)}}return polygons.length?fromOutlines(polygons.flat()):create$b()},interpolateBetween2DPointsForY=(point1,point2,y)=>{let t,f1=y-point1[1],f2=point2[1]-point1[1];return f2<0&&(f1=-f1,f2=-f2),t=f1<=0?0:f1>=f2?1:f2<1e-10?.5:f1/f2,point1[0]+t*(point2[0]-point1[0])};class OrthonormalFormula{constructor(plane){this.plane=plane;const rightVector=orthogonal([0,0,0],plane);this.v=normalize$1(rightVector,cross$1(rightVector,plane,rightVector)),this.u=cross$1([0,0,0],this.v,plane),this.planeOrigin=scale$3([0,0,0],plane,plane[3]),this.basisMap=new Map}getProjectionMatrix(){return fromValues$4(this.u[0],this.v[0],this.plane[0],0,this.u[1],this.v[1],this.plane[1],0,this.u[2],this.v[2],this.plane[2],0,0,0,-this.plane[3],1)}getInverseProjectionMatrix(){return fromValues$4(this.u[0],this.u[1],this.u[2],0,this.v[0],this.v[1],this.v[2],0,this.plane[0],this.plane[1],this.plane[2],0,this.planeOrigin[0],this.planeOrigin[1],this.planeOrigin[2],1)}to2D(vertex){const point=fromValues$2(dot$2(vertex,this.u),dot$2(vertex,this.v));return this.basisMap.set(point,vertex),point}to3D(point){const original=this.basisMap.get(point);if(original)return original;const v1=scale$3([0,0,0],this.u,point[0]),v2=scale$3([0,0,0],this.v,point[1]),v3=add$1(v1,v1,this.planeOrigin);return add$1(v2,v2,v3)}}const insertSorted=(array,element,compareFunc)=>{let leftBound=0,rightBound=array.length;for(;rightBound>leftBound;){const testIndex=Math.floor((leftBound+rightBound)/2);compareFunc(element,array[testIndex])>0?leftBound=testIndex+1:rightBound=testIndex}array.splice(leftBound,0,element)},fnNumberSort=(a,b)=>a-b,retessellate=geometry=>{if(geometry.isRetesselated)return geometry;const polygons=toPolygons$1(geometry).map((polygon,index)=>({vertices:polygon.vertices,plane:plane(polygon),index:index})),classified=classifyPolygons(polygons),destPolygons=[];classified.forEach(group=>{if(Array.isArray(group)){const coplanarPolygons=(sourcePolygons=>{if(sourcePolygons.length<2)return sourcePolygons;const destPolygons=[],numPolygons=sourcePolygons.length,plane$1=plane(sourcePolygons[0]),orthonormalFormula=new OrthonormalFormula(plane$1),polygonVertices2d=[],polygonTopVertexIndexes=[],topy2polygonIndexes=new Map,yCoordinateToPolygonIndexes=new Map,yCoordinateBins=new Map;for(let polygonIndex=0;polygonIndex<numPolygons;polygonIndex++){const poly3d=sourcePolygons[polygonIndex];let vertices2d=[],numVertices=poly3d.vertices.length,minIndex=-1;if(numVertices>0){let miny,maxy;for(let i=0;i<numVertices;i++){let pos2d=orthonormalFormula.to2D(poly3d.vertices[i]);const yCoordinateBin=Math.floor(999999.9999999999*pos2d[1]);let newY;yCoordinateBins.has(yCoordinateBin)?newY=yCoordinateBins.get(yCoordinateBin):yCoordinateBins.has(yCoordinateBin+1)?newY=yCoordinateBins.get(yCoordinateBin+1):yCoordinateBins.has(yCoordinateBin-1)?newY=yCoordinateBins.get(yCoordinateBin-1):(newY=pos2d[1],yCoordinateBins.set(yCoordinateBin,pos2d[1])),pos2d=fromValues$2(pos2d[0],newY),vertices2d.push(pos2d);const y=pos2d[1];(0===i||y<miny)&&(miny=y,minIndex=i),(0===i||y>maxy)&&(maxy=y);let polygonIndexes=yCoordinateToPolygonIndexes.get(y);polygonIndexes||(polygonIndexes=[],yCoordinateToPolygonIndexes.set(y,polygonIndexes)),polygonIndexes[polygonIndex]=!0}if(miny>=maxy)vertices2d=[],numVertices=0,minIndex=-1;else{let polygonIndexes=topy2polygonIndexes.get(miny);polygonIndexes||(polygonIndexes=[],topy2polygonIndexes.set(miny,polygonIndexes)),polygonIndexes.push(polygonIndex)}}vertices2d.reverse(),minIndex=numVertices-minIndex-1,polygonVertices2d.push(vertices2d),polygonTopVertexIndexes.push(minIndex)}const yCoordinates=[];yCoordinateToPolygonIndexes.forEach((polylist,y)=>yCoordinates.push(y)),yCoordinates.sort(fnNumberSort);let activePolygons=[],prevOutPolygonRow=[];for(let yIndex=0;yIndex<yCoordinates.length;yIndex++){const newOutPolygonRow=[],yCoordinate=yCoordinates[yIndex],polygonIndexesWithCorner=yCoordinateToPolygonIndexes.get(yCoordinate);let nextYcoordinate,removeCount=0;for(let activePolygonIndex=0;activePolygonIndex<activePolygons.length;++activePolygonIndex){const activePolygon=activePolygons[activePolygonIndex],polygonIndex=activePolygon.polygonIndex;if(polygonIndexesWithCorner[polygonIndex]){const vertices2d=polygonVertices2d[polygonIndex],numVertices=vertices2d.length;let newLeftVertexIndex=activePolygon.leftVertexIndex,newRightVertexIndex=activePolygon.rightVertexIndex;for(;;){let nextLeftVertexIndex=newLeftVertexIndex+1;if(nextLeftVertexIndex>=numVertices&&(nextLeftVertexIndex=0),vertices2d[nextLeftVertexIndex][1]!==yCoordinate)break;newLeftVertexIndex=nextLeftVertexIndex}let nextRightVertexIndex=newRightVertexIndex-1;if(nextRightVertexIndex<0&&(nextRightVertexIndex=numVertices-1),vertices2d[nextRightVertexIndex][1]===yCoordinate&&(newRightVertexIndex=nextRightVertexIndex),newLeftVertexIndex!==activePolygon.leftVertexIndex&&newLeftVertexIndex===newRightVertexIndex)activePolygon.remove=!0,removeCount++;else{activePolygon.leftVertexIndex=newLeftVertexIndex,activePolygon.rightVertexIndex=newRightVertexIndex,activePolygon.topLeft=vertices2d[newLeftVertexIndex],activePolygon.topRight=vertices2d[newRightVertexIndex];let nextLeftVertexIndex=newLeftVertexIndex+1;nextLeftVertexIndex>=numVertices&&(nextLeftVertexIndex=0),activePolygon.bottomLeft=vertices2d[nextLeftVertexIndex];let nextRightVertexIndex=newRightVertexIndex-1;nextRightVertexIndex<0&&(nextRightVertexIndex=numVertices-1),activePolygon.bottomRight=vertices2d[nextRightVertexIndex]}}}if(removeCount>0&&(activePolygons=activePolygons.filter(p=>!p.remove)),yIndex>=yCoordinates.length-1)activePolygons=[],nextYcoordinate=null;else{nextYcoordinate=Number(yCoordinates[yIndex+1]);const middleYcoordinate=.5*(yCoordinate+nextYcoordinate),startingPolygonIndexes=topy2polygonIndexes.get(yCoordinate);for(const polygonIndexKey in startingPolygonIndexes){const polygonIndex=startingPolygonIndexes[polygonIndexKey],vertices2d=polygonVertices2d[polygonIndex],numVertices=vertices2d.length,topVertexIndex=polygonTopVertexIndexes[polygonIndex];let topLeftVertexIndex=topVertexIndex;for(;;){let i=topLeftVertexIndex+1;if(i>=numVertices&&(i=0),vertices2d[i][1]!==yCoordinate)break;if(i===topVertexIndex)break;topLeftVertexIndex=i}let topRightVertexIndex=topVertexIndex;for(;;){let i=topRightVertexIndex-1;if(i<0&&(i=numVertices-1),vertices2d[i][1]!==yCoordinate)break;if(i===topLeftVertexIndex)break;topRightVertexIndex=i}let nextLeftVertexIndex=topLeftVertexIndex+1;nextLeftVertexIndex>=numVertices&&(nextLeftVertexIndex=0);let nextRightVertexIndex=topRightVertexIndex-1;nextRightVertexIndex<0&&(nextRightVertexIndex=numVertices-1);const newActivePolygon={polygonIndex:polygonIndex,leftVertexIndex:topLeftVertexIndex,rightVertexIndex:topRightVertexIndex,topLeft:vertices2d[topLeftVertexIndex],topRight:vertices2d[topRightVertexIndex],bottomLeft:vertices2d[nextLeftVertexIndex],bottomRight:vertices2d[nextRightVertexIndex]};insertSorted(activePolygons,newActivePolygon,(el1,el2)=>{const x1=interpolateBetween2DPointsForY(el1.topLeft,el1.bottomLeft,middleYcoordinate),x2=interpolateBetween2DPointsForY(el2.topLeft,el2.bottomLeft,middleYcoordinate);return x1>x2?1:x1<x2?-1:0})}}for(const activePolygonKey in activePolygons){const activePolygon=activePolygons[activePolygonKey];let x=interpolateBetween2DPointsForY(activePolygon.topLeft,activePolygon.bottomLeft,yCoordinate);const topLeft=fromValues$2(x,yCoordinate);x=interpolateBetween2DPointsForY(activePolygon.topRight,activePolygon.bottomRight,yCoordinate);const topRight=fromValues$2(x,yCoordinate);x=interpolateBetween2DPointsForY(activePolygon.topLeft,activePolygon.bottomLeft,nextYcoordinate);const bottomLeft=fromValues$2(x,nextYcoordinate);x=interpolateBetween2DPointsForY(activePolygon.topRight,activePolygon.bottomRight,nextYcoordinate);const bottomRight=fromValues$2(x,nextYcoordinate),outPolygon={topLeft:topLeft,topRight:topRight,bottomLeft:bottomLeft,bottomRight:bottomRight,leftLine:fromPoints$1(create$1(),topLeft,bottomLeft),rightLine:fromPoints$1(create$1(),bottomRight,topRight)};if(newOutPolygonRow.length>0){const prevOutPolygon=newOutPolygonRow[newOutPolygonRow.length-1],d1=distance(outPolygon.topLeft,prevOutPolygon.topRight),d2=distance(outPolygon.bottomLeft,prevOutPolygon.bottomRight);d1<EPS$1&&d2<EPS$1&&(outPolygon.topLeft=prevOutPolygon.topLeft,outPolygon.leftLine=prevOutPolygon.leftLine,outPolygon.bottomLeft=prevOutPolygon.bottomLeft,newOutPolygonRow.splice(newOutPolygonRow.length-1,1))}newOutPolygonRow.push(outPolygon)}if(yIndex>0){const prevContinuedIndexes=new Set,matchedIndexes=new Set;for(let i=0;i<newOutPolygonRow.length;i++){const thisPolygon=newOutPolygonRow[i];for(let ii=0;ii<prevOutPolygonRow.length;ii++)if(!matchedIndexes.has(ii)){const prevPolygon=prevOutPolygonRow[ii];if(distance(prevPolygon.bottomLeft,thisPolygon.topLeft)<EPS$1&&distance(prevPolygon.bottomRight,thisPolygon.topRight)<EPS$1){matchedIndexes.add(ii);const v1=direction$1(thisPolygon.leftLine),v2=direction$1(prevPolygon.leftLine),d1=v1[0]-v2[0],v3=direction$1(thisPolygon.rightLine),v4=direction$1(prevPolygon.rightLine),d2=v3[0]-v4[0],leftLineContinues=Math.abs(d1)<EPS$1,rightLineContinues=Math.abs(d2)<EPS$1;(leftLineContinues||d1>=0)&&(rightLineContinues||d2>=0)&&(thisPolygon.outPolygon=prevPolygon.outPolygon,thisPolygon.leftLineContinues=leftLineContinues,thisPolygon.rightLineContinues=rightLineContinues,prevContinuedIndexes.add(ii));break}}}for(let ii=0;ii<prevOutPolygonRow.length;ii++)if(!prevContinuedIndexes.has(ii)){const prevPolygon=prevOutPolygonRow[ii];prevPolygon.outPolygon.rightPoints.push(prevPolygon.bottomRight),distance(prevPolygon.bottomRight,prevPolygon.bottomLeft)>EPS$1&&prevPolygon.outPolygon.leftPoints.push(prevPolygon.bottomLeft),prevPolygon.outPolygon.leftPoints.reverse();const vertices3d=prevPolygon.outPolygon.rightPoints.concat(prevPolygon.outPolygon.leftPoints).map(point2d=>orthonormalFormula.to3D(point2d)),polygon=fromVerticesAndPlane(vertices3d,plane$1);polygon.vertices.length&&destPolygons.push(polygon)}}for(let i=0;i<newOutPolygonRow.length;i++){const thisPolygon=newOutPolygonRow[i];thisPolygon.outPolygon?(thisPolygon.leftLineContinues||thisPolygon.outPolygon.leftPoints.push(thisPolygon.topLeft),thisPolygon.rightLineContinues||thisPolygon.outPolygon.rightPoints.push(thisPolygon.topRight)):(thisPolygon.outPolygon={leftPoints:[],rightPoints:[]},thisPolygon.outPolygon.leftPoints.push(thisPolygon.topLeft),distance(thisPolygon.topLeft,thisPolygon.topRight)>EPS$1&&thisPolygon.outPolygon.rightPoints.push(thisPolygon.topRight))}prevOutPolygonRow=newOutPolygonRow}return destPolygons})(group);for(let i=0;i<coplanarPolygons.length;i++)destPolygons.push(coplanarPolygons[i])}else destPolygons.push(group)});const result=create$9(destPolygons);return result.isRetesselated=!0,result},classifyPolygons=polygons=>{let clusters=[polygons];const nonCoplanar=[];for(let component=3;component>=0;component--){const maybeCoplanar=[],tolerance=3===component?15e-9:1e-13;clusters.forEach(cluster=>{cluster.sort(byPlaneComponent(component,tolerance));let startIndex=0;for(let i=1;i<cluster.length;i++)cluster[i].plane[component]-cluster[startIndex].plane[component]>tolerance&&(i-startIndex===1?nonCoplanar.push(cluster[startIndex]):maybeCoplanar.push(cluster.slice(startIndex,i)),startIndex=i);cluster.length-startIndex===1?nonCoplanar.push(cluster[startIndex]):maybeCoplanar.push(cluster.slice(startIndex))}),clusters=maybeCoplanar}const result=[];return clusters.forEach(cluster=>{cluster[0]&&(result[cluster[0].index]=cluster)}),nonCoplanar.forEach(polygon=>{result[polygon.index]=polygon}),result},byPlaneComponent=(component,tolerance)=>(a,b)=>a.plane[component]-b.plane[component]>tolerance?1:b.plane[component]-a.plane[component]>tolerance?-1:0;class Node{constructor(parent){this.plane=null,this.front=null,this.back=null,this.polygontreenodes=[],this.parent=parent}invert(){const queue=[this];let node;for(let i=0;i<queue.length;i++){node=queue[i],null!==node.plane&&(node.plane=flip(create$7(),node.plane)),null!==node.front&&queue.push(node.front),null!==node.back&&queue.push(node.back);const temp=node.front;node.front=node.back,node.back=temp}}clipPolygons(polygonTreeNodes,alsoRemoveCoplanarFront){let node,current={node:this,polygonTreeNodes:polygonTreeNodes};const stack=[];do{if(node=current.node,polygonTreeNodes=current.polygonTreeNodes,null!==node.plane){const plane=node.plane,backNodes=[],frontNodes=[],coplanarFrontNodes=alsoRemoveCoplanarFront?backNodes:frontNodes;for(let i=0;i<polygonTreeNodes.length;i++){const treeNode=polygonTreeNodes[i];treeNode.canSplit()&&treeNode.splitByPlane(plane,coplanarFrontNodes,backNodes,frontNodes,backNodes)}null!==node.front&&frontNodes.length>0&&stack.push({node:node.front,polygonTreeNodes:frontNodes});const numBackNodes=backNodes.length;if(null!==node.back&&numBackNodes>0)stack.push({node:node.back,polygonTreeNodes:backNodes});else for(let i=0;i<numBackNodes;i++)backNodes[i].remove()}current=stack.pop()}while(void 0!==current)}clipTo(bsptree,alsoRemoveCoplanarFront){let node=this;const stack=[];do{node.polygontreenodes.length>0&&bsptree.clipPolygons(node.polygontreenodes,alsoRemoveCoplanarFront),null!==node.front&&stack.push(node.front),null!==node.back&&stack.push(node.back),node=stack.pop()}while(void 0!==node)}addPolygonTreeNodes(newPolygonTreeNodes){let current={node:this,polygonTreeNodes:newPolygonTreeNodes};const stack=[];do{const node=current.node,polygonTreeNodes=current.polygonTreeNodes,len=polygonTreeNodes.length;if(0===len){current=stack.pop();continue}if(null===node.plane){let index=0;index=Math.floor(len/2);const bestPoly=polygonTreeNodes[index].getPolygon();node.plane=plane(bestPoly)}const frontNodes=[],backNodes=[];for(let i=0;i<len;++i)polygonTreeNodes[i].splitByPlane(node.plane,node.polygontreenodes,backNodes,frontNodes,backNodes);frontNodes.length>0&&(null===node.front&&(node.front=new Node(node)),len===frontNodes.length&&0===backNodes.length?node.front.polygontreenodes=frontNodes:stack.push({node:node.front,polygonTreeNodes:frontNodes})),backNodes.length>0&&(null===node.back&&(node.back=new Node(node)),len===backNodes.length&&0===frontNodes.length?node.back.polygontreenodes=backNodes:stack.push({node:node.back,polygonTreeNodes:backNodes})),current=stack.pop()}while(void 0!==current)}}const splitLineSegmentByPlane=(plane,p1,p2)=>{const direction=subtract$3([0,0,0],p2,p1);let lambda=(plane[3]-dot$2(plane,p1))/dot$2(plane,direction);return Number.isNaN(lambda)?lambda=0:lambda>1?lambda=1:lambda<0&&(lambda=0),scale$3(direction,direction,lambda),add$1(direction,p1,direction),direction},splitResult={type:0,front:null,back:null};class PolygonTreeNode{constructor(parent,polygon){this.parent=parent,this.polygon=polygon,this.children=[]}addPolygons(polygons){if(!this.isRootNode())throw new Error("PolygonTreeNode01");for(let i=0;i<polygons.length;i++)this.addChild(polygons[i])}remove(){this.polygon=null;const parentschildren=this.parent.children,i=parentschildren.indexOf(this);if(i<0)throw new Error("PolyTreeNode02");parentschildren.splice(i,1),this.parent._recursivelyInvalidatePolygon()}canSplit(){return null!=this.polygon||this.children.length>0}isRootNode(){return!this.parent}invert(){if(!this.isRootNode())throw new Error("PolyTreeNode03");this._invertSub()}getPolygon(){if(null===this.polygon)throw new Error("PolyTreeNode04");return this.polygon}getPolygons(result){let children=[this];const queue=[children];let i,j,l,node;for(i=0;i<queue.length;++i)for(children=queue[i],j=0,l=children.length;j<l;j++)node=children[j],null!==node.polygon?result.push(node.polygon):node.children.length>0&&queue.push(node.children)}getPolygonsNew(result){if(null!==this.polygon)result.push(this.polygon);else for(let i=0;i<this.children.length;i++)this.children[i].getPolygons(result)}splitByPlaneOld(plane,coplanarfrontnodes,coplanarbacknodes,frontnodes,backnodes){if(this.children.length>0){const queue=[this.children];let i,j,l,node,nodes;for(i=0;i<queue.length;i++)for(nodes=queue[i],j=0,l=nodes.length;j<l;j++)node=nodes[j],node.children.length>0?queue.push(node.children):null!==this.polygon&&node._splitByPlane(plane,coplanarfrontnodes,coplanarbacknodes,frontnodes,backnodes)}else null!==this.polygon&&this._splitByPlane(plane,coplanarfrontnodes,coplanarbacknodes,frontnodes,backnodes)}splitByPlane(plane,coplanarFrontNodes,coplanarBackNodes,frontNodes,backNodes){if(this.children.length>0)for(let i=0;i<this.children.length;i++)this.children[i].splitByPlane(plane,coplanarFrontNodes,coplanarBackNodes,frontNodes,backNodes);else null!==this.polygon&&this._splitByPlane(plane,coplanarFrontNodes,coplanarBackNodes,frontNodes,backNodes)}_splitByPlane(splane,coplanarFrontNodes,coplanarBackNodes,frontNodes,backNodes){const bounds=measureBoundingSphereAndCache(this.polygon),sphereRadius=bounds[3]+EPS$1,d=dot$2(splane,bounds)-splane[3];if(d>sphereRadius)frontNodes.push(this);else if(d<-sphereRadius)backNodes.push(this);else switch(((result,splane,polygon)=>{const vertices=polygon.vertices,numVertices=vertices.length,pplane=plane(polygon);if(b=splane,(a=pplane)[0]===b[0]&&a[1]===b[1]&&a[2]===b[2]&&a[3]===b[3])result.type=0;else{let hasFront=!1,hasBack=!1;const vertexIsBack=[],MINEPS=-EPS$1;for(let i=0;i<numVertices;i++){const t=dot$2(splane,vertices[i])-splane[3],isback=t<MINEPS;vertexIsBack.push(isback),t>EPS$1&&(hasFront=!0),t<MINEPS&&(hasBack=!0)}if(hasFront||hasBack)if(hasBack)if(hasFront){const frontVertices=[],backVertices=[];let isback=vertexIsBack[0];for(let vertexIndex=0;vertexIndex<numVertices;vertexIndex++){const vertex=vertices[vertexIndex];let nextVertexIndex=vertexIndex+1;nextVertexIndex>=numVertices&&(nextVertexIndex=0);const nextIsBack=vertexIsBack[nextVertexIndex];if(isback===nextIsBack)isback?backVertices.push(vertex):frontVertices.push(vertex);else{const nextPoint=vertices[nextVertexIndex],intersectionPoint=splitLineSegmentByPlane(splane,vertex,nextPoint);isback?(backVertices.push(vertex),backVertices.push(intersectionPoint),frontVertices.push(intersectionPoint)):(frontVertices.push(vertex),frontVertices.push(intersectionPoint),backVertices.push(intersectionPoint))}isback=nextIsBack}const EPS_SQUARED=EPS$1*EPS$1;if(backVertices.length>=3){let prevVertex=backVertices[backVertices.length-1];for(let vertexIndex=0;vertexIndex<backVertices.length;vertexIndex++){const vertex=backVertices[vertexIndex];squaredDistance$1(vertex,prevVertex)<EPS_SQUARED&&(backVertices.splice(vertexIndex,1),vertexIndex--),prevVertex=vertex}}if(frontVertices.length>=3){let prevVertex=frontVertices[frontVertices.length-1];for(let vertexIndex=0;vertexIndex<frontVertices.length;vertexIndex++){const vertex=frontVertices[vertexIndex];squaredDistance$1(vertex,prevVertex)<EPS_SQUARED&&(frontVertices.splice(vertexIndex,1),vertexIndex--),prevVertex=vertex}}result.type=4,result.front=frontVertices.length>=3?fromVerticesAndPlane(frontVertices,pplane):null,result.back=backVertices.length>=3?fromVerticesAndPlane(backVertices,pplane):null}else result.type=3;else result.type=2;else{const t=dot$2(splane,pplane);result.type=t>=0?0:1}}var a,b})(splitResult,splane,this.polygon),splitResult.type){case 0:coplanarFrontNodes.push(this);break;case 1:coplanarBackNodes.push(this);break;case 2:frontNodes.push(this);break;case 3:backNodes.push(this);break;case 4:if(null!==splitResult.front){const frontNode=this.addChild(splitResult.front);frontNodes.push(frontNode)}if(null!==splitResult.back){const backNode=this.addChild(splitResult.back);backNodes.push(backNode)}}}addChild(polygon){const newChild=new PolygonTreeNode(this,polygon);return this.children.push(newChild),newChild}_invertSub(){let children=[this];const queue=[children];let i,j,l,node;for(i=0;i<queue.length;i++)for(children=queue[i],j=0,l=children.length;j<l;j++)node=children[j],null!==node.polygon&&(node.polygon=invert$1(node.polygon)),node.children.length>0&&queue.push(node.children)}_invertSubNew(){null!==this.polygon&&(this.polygon=invert$1(this.polygon));for(let i=0;i<this.children.length;i++)this.children[i]._invertSub()}_recursivelyInvalidatePolygon(){this.polygon=null,null!==this.parent&&this.parent._recursivelyInvalidatePolygon()}clear(){for(let i=0;i<this.children.length;i++)this.children[i].clear();this.children.length=0,null!==this.polygon&&(this.polygon=null),this.parent=null}toString(){let result="",children=[this];const queue=[children];let i,j,l,node;for(i=0;i<queue.length;++i){children=queue[i];const prefix=" ".repeat(i);for(j=0,l=children.length;j<l;j++)node=children[j],result+=`${prefix}PolygonTreeNode (${node.isRootNode()}): ${node.children.length}`,null!==node.polygon?result+=`\n ${prefix}polygon: ${node.polygon.vertices}\n`:result+="\n",node.children.length>0&&queue.push(node.children)}return result}}class Tree{constructor(polygons){this.polygonTree=new PolygonTreeNode(null,null),this.rootnode=new Node(null),polygons&&this.addPolygons(polygons)}invert(){this.polygonTree.invert(),this.rootnode.invert()}clipTo(tree,alsoRemoveCoplanarFront=!1){this.rootnode.clipTo(tree.rootnode,alsoRemoveCoplanarFront)}allPolygons(){const result=[];return this.polygonTree.getPolygons(result),result}addPolygons(polygons){const polygonTreeNodes=new Array(polygons.length);for(let i=0;i<polygons.length;i++)polygonTreeNodes[i]=this.polygonTree.addChild(polygons[i]);this.rootnode.addPolygonTreeNodes(polygonTreeNodes)}addPolygonsNew(polygons){this.polygonTree.addPolygons(polygons),this.rootnode.addPolygonTreeNodes(this.polygonTree.children)}clear(){this.polygonTree.clear()}toString(){return"Tree: "+this.polygonTree.toString("")}}const unionGeom2=geometries=>{let newGeometry=geometries.shift();return geometries.forEach(geometry=>{newGeometry=boolean(newGeometry,geometry,1)}),newGeometry},unionGeom3Sub=(geometry1,geometry2)=>{if(!((geometry1,geometry2)=>{if(0===geometry1.polygons.length||0===geometry2.polygons.length)return!1;const bounds1=measureBoundingBox(geometry1),min1=bounds1[0],max1=bounds1[1],bounds2=measureBoundingBox(geometry2),min2=bounds2[0],max2=bounds2[1];return!(min2[0]-max1[0]>EPS$1||min1[0]-max2[0]>EPS$1||min2[1]-max1[1]>EPS$1||min1[1]-max2[1]>EPS$1||min2[2]-max1[2]>EPS$1||min1[2]-max2[2]>EPS$1)})(geometry1,geometry2))return unionForNonIntersecting(geometry1,geometry2);const a=new Tree(toPolygons$1(geometry1)),b=new Tree(toPolygons$1(geometry2));a.clipTo(b,!1),b.clipTo(a),b.invert(),b.clipTo(a),b.invert();const newPolygons=a.allPolygons().concat(b.allPolygons());return create$9(newPolygons)},unionForNonIntersecting=(geometry1,geometry2)=>{let newpolygons=toPolygons$1(geometry1);return newpolygons=newpolygons.concat(toPolygons$1(geometry2)),create$9(newpolygons)},union=(...geometries)=>{if(0===(arr=geometries,geometries=flattenHelper(arr,[])).length)return;var arr;if(!(shapes=>{let previousType;for(const shape of shapes){let currentType=0;if(isA$6(shape)&&(currentType=1),isA$4(shape)&&(currentType=2),isA$3(shape)&&(currentType=3),previousType&¤tType!==previousType)return!1;previousType=currentType}return!0})(geometries))throw new Error("union arguments must be the same geometry type");const geometry=geometries[0];if(isA$6(geometry))return unionGeom2(geometries);if(isA$4(geometry))return(geometries=>{let i;for(i=1;i<geometries.length;i+=2)geometries.push(unionGeom3Sub(geometries[i-1],geometries[i]));let newGeometry=geometries[i-1];return newGeometry=retessellate(newGeometry),newGeometry})(geometries);throw new Error("union unsupported geometry type")},extrudeLinearGeom2=(options,geometry)=>{let{offset:offset,twistAngle:twistAngle,twistSteps:twistSteps,repair:repair}=Object.assign({},{offset:[0,0,1],twistAngle:0,twistSteps:12,repair:!0},options);if(twistSteps<1)throw new Error("twistSteps must be 1 or more");0===twistAngle&&(twistSteps=1);const offsetV=clone$9(offset);let baseSlice=fromGeom2(geometry);offsetV[2]<0&&(baseSlice=reverse$2(baseSlice));const matrix=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],output=extrudeFromSlices(options={numberOfSlices:twistSteps+1,capStart:!0,capEnd:!0,repair:repair,callback:(progress,index,base)=>{const Zrotation=index/twistSteps*twistAngle,Zoffset=scale$3([0,0,0],offsetV,index/twistSteps);return multiply$1(matrix,fromZRotation(matrix,Zrotation),fromTranslation([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],Zoffset)),transform$4(matrix,base)}},baseSlice);return geometry.color&&(output.color=geometry.color),output},extrudeLinear=(options,...objects)=>{const{height:height,twistAngle:twistAngle,twistSteps:twistSteps,repair:repair}=Object.assign({},{height:1,twistAngle:0,twistSteps:1,repair:!0},options);options={offset:[0,0,height],twistAngle:twistAngle,twistSteps:twistSteps,repair:repair};const results=objects.map(object=>isA$3(object)?((options,geometry)=>{if(!geometry.isClosed)throw new Error("extruded path must be closed");const points=toPoints$1(geometry),geometry2=create$b([points]);return geometry.color&&(geometry2.color=geometry.color),extrudeLinearGeom2(options,geometry2)})(options,object):isA$6(object)?extrudeLinearGeom2(options,object):Array.isArray(object)?extrudeLinear(options,...object):object);return 1===results.length?results[0]:results},aboutEqualNormals=(a,b)=>Math.abs(a[0]-b[0])<=1e-13&&Math.abs(a[1]-b[1])<=1e-13&&Math.abs(a[2]-b[2])<=1e-13,project=(options,...objects)=>{const{axis:axis,origin:origin}=Object.assign({},{axis:[0,0,1],origin:[0,0,0]},options);options={axis:axis,origin:origin};const results=objects.map(object=>isA$4(object)?((options,geometry)=>{const projPlane=fromNormalAndPoint([0,0,0,0],options.axis,options.origin);if(Number.isNaN(projPlane[0])||Number.isNaN(projPlane[1])||Number.isNaN(projPlane[2])||Number.isNaN(projPlane[3]))throw new Error("project: invalid axis or origin");const epsilon=((...geometries)=>{const results=(geometries=flatten(geometries)).map(geometry=>isA$3(geometry)||isA$6(geometry)?calculateEpsilonFromBounds(measureBoundingBox(geometry),2):isA$4(geometry)||isA(geometry)?calculateEpsilonFromBounds(measureBoundingBox(geometry),3):0);return 1===results.length?results[0]:results})(geometry),epsilonArea=epsilon*epsilon*Math.sqrt(3)/4;if(0===epsilon)return create$b();const polygons=toPolygons$1(geometry);let projPolys=[];for(let i=0;i<polygons.length;i++){const newVertices=polygons[i].vertices.map(v=>projectionOfPoint(projPlane,v)),newPoly=create$8(newVertices),newPlane=plane(newPoly);aboutEqualNormals(projPlane,newPlane)&&(measureArea$2(newPoly)<epsilonArea||projPolys.push(newPoly))}if(!aboutEqualNormals(projPlane,[0,0,1])){const rotation=fromVectorRotation([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],projPlane,[0,0,1]);projPolys=projPolys.map(p=>transform$9(rotation,p))}projPolys=projPolys.sort((a,b)=>measureArea$2(b)-measureArea$2(a));const projGeoms=projPolys.map(p=>{const cloned=p.vertices.map(clone$8);return create$b([cloned])}),output=unionGeom2(projGeoms);return geometry.color&&(output.color=geometry.color),output})(options,object):Array.isArray(object)?project(options,...object):object);return 1===results.length?results[0]:results};Object.freeze({__proto__:null,extrudeFromSlices:extrudeFromSlices,extrudeHelical:(options,geometry)=>{const defaults={angle:TAU,startAngle:0,pitch:10,endOffset:0,segmentsPerRotation:32},{angle:angle,endOffset:endOffset,segmentsPerRotation:segmentsPerRotation,startAngle:startAngle}=Object.assign({},defaults,options);let pitch;if(pitch=!options.pitch&&options.height?options.height/(angle/TAU):options.pitch?options.pitch:defaults.pitch,segmentsPerRotation<3)throw new Error("The number of segments per rotation needs to be at least 3.");let baseSlice=fromGeom2(geometry);measureBoundingBox(geometry)[1][0]<=0&&(baseSlice=reverse$2(baseSlice));const calculatedSegments=Math.round(segmentsPerRotation/TAU*Math.abs(angle)),segments=calculatedSegments>=2?calculatedSegments:2,step1=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1];let matrix;return extrudeFromSlices({numberOfSlices:segments+1,callback:(progress,index,base)=>{const zRotation=startAngle+angle/segments*index;return multiply$1(step1,fromTranslation([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],[endOffset/segments*index,0,(zRotation-startAngle)/TAU*pitch*Math.sign(angle)]),fromXRotation([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],-TAU/4*Math.sign(angle))),matrix=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],multiply$1(matrix,fromZRotation([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],zRotation),step1),transform$4(matrix,baseSlice)}},baseSlice)},extrudeLinear:extrudeLinear,extrudeRotate:(options,geometry)=>{const defaults={segments:12,startAngle:0,angle:TAU,overflow:"cap"};let{segments:segments,startAngle:startAngle,angle:angle,overflow:overflow}=Object.assign({},defaults,options);if(segments<3)throw new Error("segments must be greater then 3");startAngle=Math.abs(startAngle)>TAU?startAngle%TAU:startAngle,angle=Math.abs(angle)>TAU?angle%TAU:angle;let endAngle=startAngle+angle;if(endAngle=Math.abs(endAngle)>TAU?endAngle%TAU:endAngle,endAngle<startAngle){const x=startAngle;startAngle=endAngle,endAngle=x}let totalRotation=endAngle-startAngle;if(totalRotation<=0&&(totalRotation=TAU),Math.abs(totalRotation)<TAU){const anglePerSegment=TAU/segments;segments=Math.floor(Math.abs(totalRotation)/anglePerSegment),Math.abs(totalRotation)>segments*anglePerSegment&&segments++}let shapeSides=toSides(geometry);if(0===shapeSides.length)return create$9();let sliceGeometry=geometry;const pointsWithNegativeX=shapeSides.filter(s=>s[0][0]<0),pointsWithPositiveX=shapeSides.filter(s=>s[0][0]>=0);pointsWithNegativeX.length>0&&pointsWithPositiveX.length>0&&"cap"===overflow&&(pointsWithNegativeX.length>pointsWithPositiveX.length?(shapeSides=shapeSides.map(side=>{let point0=side[0],point1=side[1];return point0=[Math.min(point0[0],0),point0[1]],point1=[Math.min(point1[0],0),point1[1]],[point0,point1]}),sliceGeometry=fromSides(shapeSides),sliceGeometry=((...objects)=>mirror({normal:[1,0,0]},...objects))(sliceGeometry)):pointsWithPositiveX.length>=pointsWithNegativeX.length&&(shapeSides=shapeSides.map(side=>{let point0=side[0],point1=side[1];return point0=[Math.max(point0[0],0),point0[1]],point1=[Math.max(point1[0],0),point1[1]],[point0,point1]}),sliceGeometry=fromSides(shapeSides)));const rotationPerSlice=totalRotation/segments,isCapped=Math.abs(totalRotation)<TAU;let baseSlice=fromGeom2(sliceGeometry);baseSlice=reverse$2(baseSlice);const matrix=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],xRotationMatrix=fromXRotation([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],TAU/4),output=extrudeFromSlices(options={numberOfSlices:segments+1,capStart:isCapped,capEnd:isCapped,close:!isCapped,callback:(progress,index,base)=>{let Zrotation=rotationPerSlice*index+startAngle;return totalRotation===TAU&&index===segments&&(Zrotation=startAngle),multiply$1(matrix,fromZRotation(matrix,Zrotation),xRotationMatrix),transform$4(matrix,base)}},baseSlice);return geometry.color&&(output.color=geometry.color),output},project:project});const offsetFromPoints=(options,points)=>{let{delta:delta,corners:corners,closed:closed,segments:segments}=Object.assign({},{delta:1,corners:"edge",closed:!1,segments:16},options);if(Math.abs(delta)<EPS$1)return points;if(points.length<2)return points;let rotation=options.closed?area$1(points):1;0===rotation&&(rotation=1);const orientation=rotation>0&&delta>=0||rotation<0&&delta<0;delta=Math.abs(delta);let previousSegment=null,newPoints=[];const newCorners=[],of=[0,0],n=points.length;for(let i=0;i<n;i++){const j=(i+1)%n,p0=points[i],p1=points[j];orientation?subtract$1(of,p0,p1):subtract$1(of,p1,p0),normal(of,of),normalize(of,of),scale$1(of,of,delta);const n0=add(create$a(),p0,of),n1=add(create$a(),p1,of),currentSegment=[n0,n1];if(null!=previousSegment&&(closed||!closed&&0!==j)){const ip=intersect$1(previousSegment[0],previousSegment[1],currentSegment[0],currentSegment[1],!0);ip?(newPoints.pop(),currentSegment[0]=ip):newCorners.push({c:p0,s0:previousSegment,s1:currentSegment})}previousSegment=[n0,n1],(0!==j||closed)&&(newPoints.push(currentSegment[0]),newPoints.push(currentSegment[1]))}if(closed&&null!=previousSegment){const n0=newPoints[0],n1=newPoints[1],ip=intersect$1(previousSegment[0],previousSegment[1],n0,n1,!0);if(ip)newPoints[0]=ip,newPoints.pop();else{const p0=points[0],currentSegment=[n0,n1];newCorners.push({c:p0,s0:previousSegment,s1:currentSegment})}}if("edge"===corners){const pointIndex=new Map;newPoints.forEach((point,index)=>pointIndex.set(point,index));const line0=[0,1,0],line1=[0,1,0];newCorners.forEach(corner=>{fromPoints$1(line0,corner.s0[0],corner.s0[1]),fromPoints$1(line1,corner.s1[0],corner.s1[1]);const ip=((line1,line2)=>{const point=((a,b,c,d,u,v)=>{const invdet=1/(a*d-b*c);let x=u*d-b*v,y=-u*c+a*v;return x*=invdet,y*=invdet,[x,y]})(line1[0],line1[1],line2[0],line2[1],line1[2],line2[2]);return clone$8(point)})(line0,line1);if(Number.isFinite(ip[0])&&Number.isFinite(ip[1])){const p0=corner.s0[1],i=pointIndex.get(p0);newPoints[i]=ip,newPoints[(i+1)%newPoints.length]=void 0}else{const p0=corner.s1[0],i=pointIndex.get(p0);newPoints[i]=void 0}}),newPoints=newPoints.filter(p=>void 0!==p)}if("round"===corners){let cornerSegments=Math.floor(segments/4);const v0=[0,0];newCorners.forEach(corner=>{let rotation=angleRadians(subtract$1(v0,corner.s1[0],corner.c));if(rotation-=angleRadians(subtract$1(v0,corner.s0[1],corner.c)),orientation&&rotation<0&&(rotation+=Math.PI,rotation<0&&(rotation+=Math.PI)),!orientation&&rotation>0&&(rotation-=Math.PI,rotation>0&&(rotation-=Math.PI)),0!==rotation){cornerSegments=Math.floor(segments*(Math.abs(rotation)/TAU));const step=rotation/cornerSegments,start=angleRadians(subtract$1(v0,corner.s0[1],corner.c)),cornerPoints=[];for(let i=1;i<cornerSegments;i++){const radians=start+step*i,point=fromAngleRadians(create$a(),radians);scale$1(point,point,delta),add(point,point,corner.c),cornerPoints.push(point)}if(cornerPoints.length>0){const p0=corner.s0[1];let i=newPoints.findIndex(point=>equals$7(p0,point));i=(i+1)%newPoints.length,newPoints.splice(i,0,...cornerPoints)}}else{const p0=corner.s1[0],i=newPoints.findIndex(point=>equals$7(p0,point));newPoints.splice(i,1)}})}return newPoints},mapPlaneToVertex=(map,vertex,plane)=>{const key=vertex.toString();if(map.has(key))map.get(key)[1].push(plane);else{const entry=[vertex,[plane]];map.set(key,entry)}},mapPlaneToEdge=(map,edge,plane)=>{const key0=edge[0].toString(),key1=edge[1].toString(),key=key0<key1?`${key0},${key1}`:`${key1},${key0}`;if(map.has(key))map.get(key)[1].push(plane);else{const entry=[edge,[plane]];map.set(key,entry)}},addUniqueAngle=(map,angle)=>{map.findIndex(item=>item===angle)<0&&map.push(angle)},offset=(options,...objects)=>{const results=objects.map(object=>isA$3(object)?((options,geometry)=>{const{delta:delta,corners:corners,segments:segments}=Object.assign({},{delta:1,corners:"edge",segments:16},options);if(delta<=0)throw new Error("the given delta must be positive for paths");if("edge"!==corners&&"chamfer"!==corners&&"round"!==corners)throw new Error('corners must be "edge", "chamfer", or "round"');const closed=geometry.isClosed,points=toPoints$1(geometry),paths={points:points,external:offsetFromPoints({delta:delta,corners:corners,segments:segments,closed:closed},points),internal:offsetFromPoints({delta:-delta,corners:corners,segments:segments,closed:closed},points)},output=geometry.isClosed?(paths=>{let{external:external,internal:internal}=paths;return external.length<2?create$b():(area$1(external)<0?external=external.reverse():internal=internal.reverse(),create$b([external,internal]))})(paths):((paths,segments,corners,delta)=>{const{points:points,external:external,internal:internal}=paths;if(0===points.length)return create$b();if(1===points.length)return circle({center:points[0],radius:delta});const capSegments=Math.floor(segments/2),e2iCap=[],i2eCap=[];if("round"===corners&&capSegments>0){const step=Math.PI/capSegments,eCorner=points[points.length-1],e2iStart=angleRadians(subtract$1([0,0],external[external.length-1],eCorner)),iCorner=points[0],i2eStart=angleRadians(subtract$1([0,0],internal[0],iCorner));for(let i=1;i<capSegments;i++){let radians=e2iStart+step*i,point=fromAngleRadians(create$a(),radians);scale$1(point,point,delta),add(point,point,eCorner),e2iCap.push(point),radians=i2eStart+step*i,point=fromAngleRadians(create$a(),radians),scale$1(point,point,delta),add(point,point,iCorner),i2eCap.push(point)}}const allPoints=[];return allPoints.push(...external,...e2iCap,...internal.reverse(),...i2eCap),create$b([allPoints])})(paths,segments,corners,delta);return geometry.color&&(output.color=geometry.color),output})(options,object):isA$6(object)?((options,geometry)=>{const{delta:delta,corners:corners,segments:segments,expandHoles:expandHoles}=Object.assign({},{delta:1,corners:"edge",segments:16,expandHoles:!1},options);if("edge"!==corners&&"chamfer"!==corners&&"round"!==corners)throw new Error('corners must be "edge", "chamfer", or "round"');if(!Number.isFinite(delta))throw new Error("delta must be a finite number");if("round"===corners&&!Number.isFinite(segments))throw new Error("segments must be a finite number");if("round"===corners&&!(segments>0))throw new Error("segments must be greater than zero");const outlines=toOutlines(geometry),newOutlines=outlines.map(outline=>{let outside=!0;return expandHoles&&(outside=outlines.reduce((acc,polygon)=>acc+arePointsInside(outline,create$3(polygon)),0)%2==0),offsetFromPoints(options={delta:outside?delta:-delta,corners:corners,closed:!0,segments:segments},outline)}),output=create$b(newOutlines);return geometry.color&&(output.color=geometry.color),output})(options,object):isA$4(object)?((options,geometry)=>{const{delta:delta,corners:corners,segments:segments}=Object.assign({},{delta:1,corners:"round",segments:12},options);if("round"!==corners)throw new Error('corners must be "round" for 3D geometries');const expanded=((options,geometry)=>{const{delta:delta,segments:segments}=Object.assign({},{delta:1,segments:12},options);let result=create$9();const vertices2planes=new Map,edges2planes=new Map,v1=[0,0,0],v2=[0,0,0];return toPolygons$1(geometry).forEach(polygon=>{const extrudeVector=scale$3([0,0,0],plane(polygon),2*delta),extrudedFace=((offsetVector,polygon1)=>{dot$2(plane(polygon1),offsetVector)>0&&(polygon1=invert$1(polygon1));const newPolygons=[polygon1],polygon2=transform$9(fromTranslation([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],offsetVector),polygon1),numVertices=polygon1.vertices.length;for(let i=0;i<numVertices;i++){const nexti=i<numVertices-1?i+1:0,sideFacePolygon=create$8([polygon1.vertices[i],polygon2.vertices[i],polygon2.vertices[nexti],polygon1.vertices[nexti]]);newPolygons.push(sideFacePolygon)}return newPolygons.push(invert$1(polygon2)),create$9(newPolygons)})(extrudeVector,transform$9(fromTranslation([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],scale$3([0,0,0],extrudeVector,-.5)),polygon));result=unionGeom3Sub(result,extrudedFace);const vertices=polygon.vertices;for(let i=0;i<vertices.length;i++){mapPlaneToVertex(vertices2planes,vertices[i],plane(polygon));const j=(i+1)%vertices.length,edge=[vertices[i],vertices[j]];mapPlaneToEdge(edges2planes,edge,plane(polygon))}}),edges2planes.forEach(item=>{const edge=item[0],planes=item[1],startVertex=edge[0],endVertex=edge[1],zBase=subtract$3([0,0,0],endVertex,startVertex);normalize$1(zBase,zBase);const xBase=planes[0],yBase=cross$1([0,0,0],xBase,zBase);let angles=[];for(let i=0;i<segments;i++)addUniqueAngle(angles,i*TAU/segments);for(let i=0,iMax=planes.length;i<iMax;i++){const planeNormal=planes[i],si=dot$2(yBase,planeNormal),co=dot$2(xBase,planeNormal);let angle=Math.atan2(si,co);angle<0&&(angle+=TAU),addUniqueAngle(angles,angle),angle=Math.atan2(-si,-co),angle<0&&(angle+=TAU),addUniqueAngle(angles,angle)}angles=angles.sort(fnNumberSort);const numAngles=angles.length;let prevP1,prevP2;const startFaceVertices=[],endFaceVertices=[],polygons=[];for(let i=-1;i<numAngles;i++){const angle=angles[i<0?i+numAngles:i],si=Math.sin(angle),co=Math.cos(angle);scale$3(v1,xBase,co*delta),scale$3(v2,yBase,si*delta),add$1(v1,v1,v2);const p1=add$1(create$c(),startVertex,v1),p2=add$1(create$c(),endVertex,v1);let skip=!1;if(i>=0&&distance$1(p1,prevP1)<EPS$1&&(skip=!0),!skip){if(i>=0){startFaceVertices.push(p1),endFaceVertices.push(p2);const polygon=create$8([prevP2,p2,p1,prevP1]);polygons.push(polygon)}prevP1=p1,prevP2=p2}}endFaceVertices.reverse(),polygons.push(create$8(startFaceVertices)),polygons.push(create$8(endFaceVertices));const cylinder=create$9(polygons);result=unionGeom3Sub(result,cylinder)}),vertices2planes.forEach(item=>{const vertex=item[0],planes=item[1],xaxis=planes[0];let bestzaxis=null,bestzaxisOrthogonality=0;for(let i=1;i<planes.length;i++){const normal=planes[i],cross=cross$1(v1,xaxis,normal),crossLength=length$2(cross);crossLength>.05&&crossLength>bestzaxisOrthogonality&&(bestzaxisOrthogonality=crossLength,bestzaxis=normal)}bestzaxis||(bestzaxis=orthogonal(v1,xaxis));const yaxis=cross$1(v1,xaxis,bestzaxis);normalize$1(yaxis,yaxis);const zaxis=cross$1(v2,yaxis,xaxis),corner=sphere({center:[vertex[0],vertex[1],vertex[2]],radius:delta,segments:segments,axes:[xaxis,yaxis,zaxis]});result=unionGeom3Sub(result,corner)}),retessellate(result)})(options={delta:delta,corners:corners,segments:segments},geometry),output=union(geometry,expanded);return geometry.color&&(output.color=geometry.color),output})(options,object):Array.isArray(object)?offset(options,...object):object);return 1===results.length?results[0]:results};Object.freeze({__proto__:null,offset:offset,offsetFromPoints:offsetFromPoints});const findLayer=(obj,layers)=>{const lname=obj.lnam||"0";for(const layer of layers)if(layer.name===lname)return layer;return null},getColorNumber=(obj,layers)=>{let cn=obj.cnmb||-1;if(256===cn){cn=-1;const layer=findLayer(obj,layers);null!==layer&&(cn=layer.cnmb||-1)}return cn},getColor=(index,colorindex)=>{if(index<1)return null;index=((num,mod)=>{const remain=num%mod;return Math.floor(remain>=0?remain:remain+mod)})(index,colorindex.length);const color=colorindex[index];return[color[0]/255,color[1]/255,color[2]/255,color[3]/255]},instantiatePolygon=(obj,layers,options)=>{const vertices=[];if(vertices.push(index$k.fromValues(obj.pptx,obj.ppty,obj.pptz)),vertices.push(index$k.fromValues(obj.sptx,obj.spty,obj.sptz)),vertices.push(index$k.fromValues(obj.tptx,obj.tpty,obj.tptz)),obj.fptx){let pushit=!1;obj.tptx!==obj.fptx&&(pushit=!0),obj.tpty!==obj.fpty&&(pushit=!0),obj.tptz!==obj.fptz&&(pushit=!0),pushit&&vertices.push(index$k.fromValues(obj.fptx,obj.fpty,obj.fptz))}const cn=getColorNumber(obj,layers),color=getColor(cn,options.colorindex),polygon=poly3.create(vertices);return color&&(polygon.color=color),polygon},instantiateLine=(obj,layers,options)=>{if(obj.pptz===obj.sptz&&0===obj.pptz){const p1=index$i.fromValues(obj.pptx,obj.ppty),p2=index$i.fromValues(obj.sptx,obj.spty);return line([p1,p2])}const p1=index$k.fromValues(obj.pptx,obj.ppty,obj.pptz),p2=index$k.fromValues(obj.sptx,obj.spty,obj.sptz);return line([p1,p2])},instantiateVector=obj=>{const d3line=parseInt("00000000000100000",2),d3mesh=parseInt("00000000001000000",2),d3face=parseInt("00000000010000000",2),flags=obj.lflg,vtype={};return(flags&d3line)===d3line||(flags&d3mesh)===d3mesh?vtype.vec=index$k.fromValues(obj.pptx,obj.ppty,obj.pptz):(flags&d3face)===d3face?(vtype.vec=index$k.fromValues(obj.pptx,obj.ppty,obj.pptz),vtype.fvia=obj.fvia,vtype.fvib=obj.fvib,vtype.fvic=obj.fvic,vtype.fvid=obj.fvid):(vtype.vec=index$i.fromValues(obj.pptx,obj.ppty),vtype.bulg=obj.bulg),vtype},addSection=(path,x1,y1,bulg)=>{if(0===bulg)path=path2.appendPoints([[x1,y1]],path);else{const points=path2.toPoints(path),prev=points[points.length-1],curr=index$i.fromValues(x1,y1),r=index$i.distance(prev,curr)*((1+Math.pow(bulg,2))/(4*bulg)),clockwise=bulg<0,large=!1,d=4*Math.atan(bulg),res=16;path=path2.appendArc({endpoint:[x1,y1],radius:[r,r],xaxisrotation:d,clockwise:clockwise,large:large,segments:res},path)}return path},instantiatePath2D=(obj,layers,options)=>{const closed=parseInt("00000000000000001",2),vlen=obj.vlen,pptxs=obj.pptxs,pptys=obj.pptys,bulgs=obj.bulgs,flags=obj.lflg;let path=path2.create();const isclosed=(flags&closed)===closed;return vlen!==pptxs.length||vlen!==pptys.length||vlen!==bulgs.length||(pptxs.forEach((item,index,array)=>{let bulg=0;index>0&&(bulg=bulgs[index-1]),path=addSection(path,pptxs[index],pptys[index],bulg)}),isclosed&&!path.isClosed&&(path=addSection(path,pptxs[0],pptys[0],bulgs[vlen-1]),path=path2.close(path))),path},instantiateArc=(obj,layers,options)=>{obj.lthk;const pptx=obj.pptx,ppty=obj.ppty,swid=obj.swid;let ang0=obj.ang0;ang0*=.017453292519943295;let ang1=obj.ang1;return ang1*=.017453292519943295,arc({center:[pptx,ppty],radius:swid,startAngle:ang0,endAngle:ang1,segments:16})},instantiateCircle=(obj,layers,options)=>{const lthk=obj.lthk,pptx=obj.pptx,ppty=obj.ppty,swid=obj.swid,cn=getColorNumber(obj,layers),color=getColor(cn,options.colorindex);if(0===lthk){const cag=circle({center:[pptx,ppty],radius:swid,segments:16});return color&&(cag.color=color),cag}const csg=circle({center:[pptx,ppty],radius:swid,segments:16}).extrude({offset:[0,0,lthk]});return color&&(csg.color=color),csg},instantiateEllipse=(obj,layers,options)=>{const pptx=obj.pptx,ppty=obj.ppty,pptz=obj.pptz,sptx=obj.sptx,spty=obj.spty,sptz=obj.sptz,swid=obj.swid;if(0===pptz&&0===sptz){const center=index$i.fromValues(0,0),mjaxis=index$i.fromValues(sptx,spty),rx=index$i.distance(center,mjaxis),ry=rx*swid;let angle=180*Math.atan2(spty,sptx)/Math.PI;angle<1e-5&&(angle=0),angle*=.017453292519943295;const cag=ellipse({center:[0,0],radius:[rx,ry],segments:16}),matrix=index$j.fromZRotation(index$j.create(),angle);return index$j.multiply(matrix,matrix,index$j.fromTranslation(index$j.create(),[pptx,ppty,0])),geom2.transform(matrix,cag)}},instantiateMesh=(obj,layers,options)=>{const vlen=obj.vlen,pptxs=obj.pptxs,pptys=obj.pptys,pptzs=obj.pptzs,flen=obj.flen,fvals=obj.fvals,cn=getColorNumber(obj,layers),color=getColor(cn,options.colorindex),polygons=[];if(vlen===pptxs.length&&vlen===pptys.length&&vlen===pptzs.length&&flen===fvals.length){const faces=(fvals=>{const faces=[];let vi=0;for(;vi<fvals.length;){let fi=fvals[vi++];const face=[];for(;fi>0;)face.push(fvals[vi++]),fi--;faces.push(face)}return faces})(fvals),points=((pptxs,pptys,pptzs)=>{const points=[];let vi=0;for(;vi<pptxs.length;){const x=pptxs[vi],y=pptys[vi],z=pptzs[vi];points.push([x,y,z]),vi++}return points})(pptxs,pptys,pptzs);let fi=0;for(;fi<faces.length;){const face=faces[fi];let vertices=[],vi=0;for(;vi<face.length;){const pi=face[vi],vertex=index$k.clone(points[pi]);vertices.push(vertex),vi++}1===options.dxf.angdir&&(vertices=vertices.reverse());const poly=poly3.create(vertices);color&&(poly.color=color),polygons.push(poly),fi++}}return geom3.create(polygons)},getPolyType$1=obj=>{const closedM=parseInt("00000000000000001",2),d3line=parseInt("00000000000001000",2),d3mesh=parseInt("00000000000010000",2),closedN=parseInt("00000000000100000",2),d3face=parseInt("00000000001000000",2),flags=obj.lflg;let ptype=null;return(flags&d3line)===d3line?ptype=null:(flags&d3mesh)===d3mesh||(flags&d3face)===d3face?(ptype=geom3.create(),ptype.closedM=(flags&closedM)===closedM,ptype.closedN=(flags&closedN)===closedN):(ptype=path2.create(),ptype.closedM=(flags&closedM)===closedM),"cnmb"in obj&&(ptype.cnmb=obj.cnmb),ptype},completeCurrent=(objects,baseobj,polygons,vectors,options)=>{if(path2.isA(baseobj)){const points=vectors.map(vector=>vector.vec);objects.push(path2.fromPoints({closed:baseobj.closed},points))}return geom3.isA(baseobj)&&objects.push(geom3.create(polygons)),null},translateVector2D=vector=>`${vector[0]},${vector[1]}`,translateVector3D=vector=>`${vector[0]},${vector[1]},${vector[2]}`,translatePolygon=polygon=>{const vertices=poly3.toVertices(polygon);let script="createPolygon([";return vertices.forEach(vertice=>{script+=`[${translateVector3D(vertice)}],`}),script+=`],${translateColor(polygon)})`,script},translateColor=polygon=>{let script="null";if("color"in polygon){const rgb=polygon.color;script=`[${rgb[0]},${rgb[1]},${rgb[2]},${rgb[3]}]`}return script},translateLine=(obj,layers,options)=>{const name=obj.name,cn=getColorNumber(obj,layers),color=getColor(cn,options.colorindex);let script="";if(!obj.pptz||obj.pptz===obj.sptz&&0===obj.pptz){const p1=index$i.fromValues(obj.pptx,obj.ppty),p2=index$i.fromValues(obj.sptx,obj.spty);script=` let ${name} = line([[${translateVector2D(p1)}],[${translateVector2D(p2)}]])\n`}else{const p1=index$k.fromValues(obj.pptx,obj.ppty,obj.pptz),p2=index$k.fromValues(obj.sptx,obj.spty,obj.sptz);script=` let ${name} = line([[${translateVector3D(p1)}],[${translateVector3D(p2)}]])\n`}color&&(script+=` ${name} = colorize([${color[0]}, ${color[1]}, ${color[2]}, 1], ${name})\n`),obj.script=script,addToLayer(obj,layers)},translateSection=(name,x1,y1,bulg,px,py)=>{if(0===bulg)return`path2.appendPoints([[${x1},${y1}]], ${name})\n`;const prev=index$i.fromValues(px,py),curr=index$i.fromValues(x1,y1),r=index$i.distance(prev,curr)*((1+Math.pow(bulg,2))/(4*bulg)),clockwise=bulg<0;return`path2.appendArc({endpoint: [${x1},${y1}],radius: [${r},${r}],xaxisrotation: ${4*Math.atan(bulg)},clockwise: ${clockwise},large: false,segments: 16}, ${name})\n`},translatePath2D=(obj,layers,options)=>{const closed=parseInt("00000000000000001",2),vlen=obj.vlen,pptxs=obj.pptxs,pptys=obj.pptys,bulgs=obj.bulgs,flags=obj.lflg,name=obj.name,cn=getColorNumber(obj,layers),color=getColor(cn,options.colorindex);let script=` let ${name} = path2.create()\n`;const isclosed=(flags&closed)===closed;if(vlen===pptxs.length&&vlen===pptys.length&&vlen===bulgs.length){script+=` ${name} = path2.appendPoints([[${pptxs[0]}, ${pptys[0]}]], ${name})\n`;for(let i=0;i<pptxs.length;i++){const j=(i+1)%pptxs.length,cx=pptxs[j],cy=pptys[j],px=pptxs[i],py=pptys[i],bulg=bulgs[i];(0!==j||0!==bulg)&&(script+=` ${name} = ${translateSection(name,cx,cy,bulg,px,py)}`)}script+=isclosed?` ${name} = path2.close(${name})\n`:"\n",color&&(script+=` ${name} = colorize([${color[0]}, ${color[1]}, ${color[2]}, 1], ${name})\n`),obj.script=script,addToLayer(obj,layers)}},translateArc=(obj,layers,options)=>{const lthk=obj.lthk,pptx=obj.pptx,ppty=obj.ppty,swid=obj.swid;let ang0=obj.ang0,ang1=obj.ang1;const name=obj.name,cn=getColorNumber(obj,layers),color=getColor(cn,options.colorindex);if(ang0*=.017453292519943295,ang1*=.017453292519943295,0===lthk){let script=` let ${name} = arc({center: [${pptx}, ${ppty}], radius: ${swid}, startAngle: ${ang0}, endAngle: ${ang1}, segements: 16})\n`;return color&&(script+=` ${name} = colorize([${color[0]}, ${color[1]}, ${color[2]}, 1], ${name})\n`),obj.script=script,void addToLayer(obj,layers)}let script=` let ${name} = arc({center: [${pptx}, ${ppty}], radius: ${swid}, startAngle: ${ang0}, endAngle: ${ang1}, segements: 16})\n`;color&&(script+=` ${name} = colorize([${color[0]}, ${color[1]}, ${color[2]}, 1], ${name})\n`),obj.script=script,addToLayer(obj,layers)},translateCircle=(obj,layers,options)=>{const lthk=obj.lthk,pptx=obj.pptx,ppty=obj.ppty,swid=obj.swid,name=obj.name,cn=getColorNumber(obj,layers),color=getColor(cn,options.colorindex);if(0===lthk){let script=` let ${name} = circle({center: [${pptx}, ${ppty}], radius: ${swid}, segments: 16})\n`;return color&&(script+=` ${name} = colorize([${color[0]}, ${color[1]}, ${color[2]}, 1], ${name})\n`),obj.script=script,void addToLayer(obj,layers)}let script=` let ${name} = circle({center: [${pptx}, ${ppty}], radius: ${swid}, segments: 16}).extrude({offset: [0,0,${lthk}]}))\n`;color&&(script+=` ${name} = colorize([${color[0]}, ${color[1]}, ${color[2]}, 1], ${name})\n`),obj.script=script,addToLayer(obj,layers)},translateEllipse=(obj,layers,options)=>{const pptx=obj.pptx,ppty=obj.ppty,pptz=obj.pptz,sptx=obj.sptx,spty=obj.spty,sptz=obj.sptz,swid=obj.swid,name=obj.name,cn=getColorNumber(obj,layers),color=getColor(cn,options.colorindex);if(0===pptz&&0===sptz){const center=index$i.fromValues(0,0),mjaxis=index$i.fromValues(sptx,spty),rx=index$i.distance(center,mjaxis);let script=` let ${name} = ellipse({center: [0, 0, 0], radius: [${rx}, ${rx*swid}], segments: 16})\n let ${name}matrix = mat4.multiply(mat4.create(), mat4.fromTranslation(mat4.create(), [${pptx}, ${ppty}, 0]), mat4.fromZRotation(mat4.create(), ${Math.atan2(spty,sptx)}))\n ${name} = geom2.transform(${name}matrix, ${name})\n`;color&&(script+=` ${name} = colorize([${color[0]}, ${color[1]}, ${color[2]}, 1], ${name})\n`),obj.script=script,addToLayer(obj,layers)}},translateMesh=(obj,layers,options)=>{const vlen=obj.vlen,pptxs=obj.pptxs,pptys=obj.pptys,pptzs=obj.pptzs,flen=obj.flen,fvals=obj.fvals,cn=getColorNumber(obj,layers),color=getColor(cn,options.colorindex),polygons=[];if(vlen===pptxs.length&&vlen===pptys.length&&vlen===pptzs.length)if(flen===fvals.length){const faces=(fvals=>{const faces=[];let vi=0;for(;vi<fvals.length;){let fi=fvals[vi++];const face=[];for(;fi>0;)face.push(fvals[vi++]),fi--;faces.push(face)}return faces})(fvals),points=((pptxs,pptys,pptzs)=>{const points=[];let vi=0;for(;vi<pptxs.length;){const x=pptxs[vi],y=pptys[vi],z=pptzs[vi];points.push([x,y,z]),vi++}return points})(pptxs,pptys,pptzs);let fi=0;for(;fi<faces.length;){const face=faces[fi];let vertices=[],vi=0;for(;vi<face.length;){const pi=face[vi],vector=index$k.clone(points[pi]);vertices.push(vector),vi++}1===options.dxf.angdir&&(vertices=vertices.reverse());const poly=poly3.create(vertices);color&&(poly.color=color),polygons.push(poly),fi++}}else console.warn("invalid mesh: faces");else console.warn("invalid mesh: vertices");const name=obj.name;let script=` const ${name}_polygons = [\n`;for(const polygon of polygons)script+=" "+translatePolygon(polygon)+",\n";return script+=` ]\n let ${name} = geom3.create(${name}_polygons)\n`,obj.script=script,addToLayer(obj,layers),null},addToLayer=(obj,layers)=>{let layer=findLayer(obj,layers);null===layer&&(layer=(layers=>{for(const layer of layers)if("0"===layer.name)return layer;const layer={type:"layer",lnam:"layer0",name:"0",lscl:1,visb:0,spac:0,objects:[]};return layers.push(layer),layer})(layers)),"objects"in layer||(layer.objects=[]),layer.objects.push(obj)},getPolyType=obj=>{const closedM=parseInt("00000000000000001",2),d3line=parseInt("00000000000001000",2),d3mesh=parseInt("00000000000010000",2),closedN=parseInt("00000000000100000",2),d3face=parseInt("00000000001000000",2),flags=obj.lflg;let ptype=null;return(flags&d3line)===d3line?ptype={type:"3dline",isclosed:(flags&closedM)===closedM}:(flags&d3mesh)===d3mesh?(ptype={type:"3dpolymesh"},ptype.fvia=obj.fvia,ptype.fvib=obj.fvib,ptype.closedM=(flags&closedM)===closedM,ptype.closedN=(flags&closedN)===closedN):(flags&d3face)===d3face?(ptype={type:"3dpolyfaces"},ptype.fvia=obj.fvia,ptype.fvib=obj.fvib):ptype={type:"2dline",isclosed:(flags&closedM)===closedM},"cnmb"in obj&&(ptype.cnmb=obj.cnmb),"lnam"in obj&&(ptype.lnam=obj.lnam),ptype},translateCurrent=(obj,layers,parts,options)=>{if(null===obj)return null;const type=obj.type,cn=getColorNumber(obj,layers),color=getColor(cn,options.colorindex);if("2dline"===type)return((obj,layers,parts,options)=>{obj.vlen=parts.length,obj.pptxs=[],obj.pptys=[],obj.bulgs=[];for(const part of parts)obj.pptxs.push(part.vec[0]),obj.pptys.push(part.vec[1]),obj.bulgs.push(part.bulg);return obj.isclosed?obj.lflg=parseInt("00000000000000001",2):obj.lflg=0,translatePath2D(obj,layers,options),null})(obj,layers,parts,options);if("3dline"===type)return null;if("3dpolymesh"===type){const facets=((meshM,meshN,parts,color,options)=>{const getVector=(x,y)=>parts[(x-1)*meshN+(y-1)].vec,facets=[];if(meshM*meshN!==parts.length)return facets;if(meshM<2|meshN<2)return facets;let i=1;for(;i<meshM;){let j=1;for(;j<meshN;){let facet=[getVector(i,j),getVector(i+1,j),getVector(i+1,j+1),getVector(i,j+1)];1===options.dxf.angdir&&(facet=facet.reverse());const polygon=poly3.create(facet),plane=poly3.plane(polygon);Number.isFinite(plane[3])&&(color&&(polygon.color=color),facets.push(polygon)),j++}i++}return facets})(obj.fvia,obj.fvib,parts,color,options);parts=facets}if("3dpolyfaces"===type&&"fvia"in obj){const faces=((meshM,meshN,parts,color,options)=>{const faces=[];if(meshM+meshN!==parts.length)return faces;let i=meshM;for(;i<parts.length;){let part=parts[i];const indexes=[Math.abs(part.fvia),Math.abs(part.fvib),Math.abs(part.fvic),Math.abs(part.fvid)];let vertices=[];if(indexes[0]>0&&(part=parts[indexes[0]-1],vertices.push(part.vec),indexes[1]>0&&(part=parts[indexes[1]-1],vertices.push(part.vec),indexes[2]>0&&(part=parts[indexes[2]-1],vertices.push(part.vec),indexes[3]>0&&(part=parts[indexes[3]-1],vertices.push(part.vec))))),vertices.length>2){1===options.dxf.angdir&&(vertices=vertices.reverse());const polygon=poly3.create(vertices);faces.push(polygon)}i++}return faces})(obj.fvia,obj.fvib,parts,0,options);parts=faces}const name=obj.name;let script=` const ${name}_polygons = [\n`;for(const polygon of parts)script+=" "+translatePolygon(polygon)+",\n";return script+=` ]\n let ${name} = geom3.create(${name}_polygons)\n`,color&&(script+=` ${name}.color = [${color}]\n`),obj.script=script,addToLayer(obj,layers),null},saveVariable=(obj,options)=>{"$ANGDIR"===(obj.name||"Unknown")&&"lflg"in obj&&(options.dxf.angdir=obj.lflg)},handleError=(reader,error)=>{if(!0===reader.options.strict)throw error;console.log(`error: line ${error.line}, column ${error.column}, bad character [${error.c}]`)},handleStart=(reader,data)=>{},handleEnd=(reader,data)=>{},handleEntity=(reader,group,value)=>{let obj=null;switch(value){case"LAYER":obj={type:"layer"},obj[getTLA(48)]=1,obj[getTLA(60)]=0,obj[getTLA(67)]=0,reader.objstack.push(obj);break;case"LINE":obj={type:"line"},obj[getTLA(48)]=1,obj[getTLA(60)]=0,obj[getTLA(62)]=256,obj[getTLA(67)]=0,obj[getTLA(210)]=0,obj[getTLA(220)]=0,obj[getTLA(230)]=0,reader.objstack.push(obj);break;case"LWPOLYLINE":obj={type:"lwpolyline"},obj[getTLA(48)]=1,obj[getTLA(60)]=0,obj[getTLA(62)]=256,obj[getTLA(67)]=0,obj[getTLA(38)]=0,obj[getTLA(39)]=0,obj[getTLA(43)]=0,obj[getTLA(70)]=0,obj[getTLA(90)]=0,obj[getTLA(210)]=0,obj[getTLA(220)]=0,obj[getTLA(230)]=1,reader.objstack.push(obj);break;case"MESH":obj={type:"mesh"},obj[getTLA(48)]=1,obj[getTLA(60)]=0,obj[getTLA(62)]=256,obj[getTLA(67)]=0,obj[getTLA(91)]=0,obj[getTLA(92)]=0,obj[getTLA(93)]=0,obj[getTLA(94)]=0,obj[getTLA(95)]=0,obj.state=0,reader.objstack.push(obj);break;case"POLYLINE":obj={type:"polyline"},obj[getTLA(48)]=1,obj[getTLA(60)]=0,obj[getTLA(62)]=256,obj[getTLA(67)]=0,obj[getTLA(10)]=0,obj[getTLA(20)]=0,obj[getTLA(30)]=0,obj[getTLA(39)]=0,obj[getTLA(40)]=0,obj[getTLA(41)]=0,obj[getTLA(70)]=0,obj[getTLA(71)]=0,obj[getTLA(72)]=0,obj[getTLA(73)]=0,obj[getTLA(74)]=0,obj[getTLA(75)]=0,obj[getTLA(210)]=0,obj[getTLA(220)]=0,obj[getTLA(230)]=1,reader.objstack.push(obj);break;case"ARC":obj={type:"arc"},obj[getTLA(48)]=1,obj[getTLA(60)]=0,obj[getTLA(62)]=256,obj[getTLA(67)]=0,obj[getTLA(39)]=0,obj[getTLA(210)]=0,obj[getTLA(220)]=0,obj[getTLA(230)]=1,reader.objstack.push(obj);break;case"CIRCLE":obj={type:"circle"},obj[getTLA(48)]=1,obj[getTLA(60)]=0,obj[getTLA(62)]=256,obj[getTLA(67)]=0,obj[getTLA(39)]=0,obj[getTLA(210)]=0,obj[getTLA(220)]=0,obj[getTLA(230)]=1,reader.objstack.push(obj);break;case"ELLIPSE":obj={type:"ellipse"},obj[getTLA(48)]=1,obj[getTLA(60)]=0,obj[getTLA(62)]=256,obj[getTLA(67)]=0,obj[getTLA(210)]=0,obj[getTLA(220)]=0,obj[getTLA(230)]=1,reader.objstack.push(obj);break;case"VERTEX":obj={type:"vertex"},obj[getTLA(48)]=1,obj[getTLA(60)]=0,obj[getTLA(62)]=256,obj[getTLA(67)]=0,obj[getTLA(10)]=0,obj[getTLA(20)]=0,obj[getTLA(30)]=0,obj[getTLA(40)]=0,obj[getTLA(41)]=0,obj[getTLA(42)]=0,obj[getTLA(70)]=0,obj[getTLA(71)]=0,obj[getTLA(72)]=0,obj[getTLA(73)]=0,obj[getTLA(74)]=0,reader.objstack.push(obj);break;case"3DFACE":obj={type:"3dface"},obj[getTLA(48)]=1,obj[getTLA(60)]=0,obj[getTLA(62)]=256,obj[getTLA(67)]=0,obj[getTLA(70)]=0,reader.objstack.push(obj);break;case"SEQEND":obj={type:"seqend"},reader.objstack.push(obj);break;default:obj={},reader.objstack.push(obj)}},handleVariable=(reader,group,value)=>{const obj={type:"variable",name:value};reader.objstack.push(obj)},handleInt=(reader,group,value)=>{const obj=reader.objstack.pop();"type"in obj&&(obj[getTLA(group)]=parseFloat(value)),reader.objstack.push(obj)},handleDouble=(reader,group,value)=>{const obj=reader.objstack.pop();"type"in obj&&(obj[getTLA(group)]=parseFloat(value)),reader.objstack.push(obj)},handleXcoord=(reader,group,value)=>{const obj=reader.objstack.pop();"type"in obj&&("lwpolyline"===obj.type?(void 0===obj.pptxs&&(obj.pptxs=[],obj.bulgs=[]),obj.pptxs.push(parseFloat(value)),obj.bulgs.push(0)):"mesh"===obj.type?(void 0===obj.pptxs&&(obj.pptxs=[]),obj.pptxs.push(parseFloat(value))):obj[getTLA(group)]=parseFloat(value)),reader.objstack.push(obj)},handleYcoord=(reader,group,value)=>{const obj=reader.objstack.pop();"type"in obj&&("lwpolyline"===obj.type||"mesh"===obj.type?(void 0===obj.pptys&&(obj.pptys=[]),obj.pptys.push(parseFloat(value))):obj[getTLA(group)]=parseFloat(value)),reader.objstack.push(obj)},handleZcoord=(reader,group,value)=>{const obj=reader.objstack.pop();"type"in obj&&("mesh"===obj.type?(void 0===obj.pptzs&&(obj.pptzs=[]),obj.pptzs.push(parseFloat(value))):obj[getTLA(group)]=parseFloat(value)),reader.objstack.push(obj)},handleBulge=(reader,group,value)=>{const obj=reader.objstack.pop();if("type"in obj)if("lwpolyline"===obj.type){const bulgs=obj.bulgs;void 0!==bulgs&&obj.pptxs.length===bulgs.length&&(bulgs[bulgs.length-1]=parseFloat(value))}else obj[getTLA(group)]=parseFloat(value);reader.objstack.push(obj)},handleLen=(reader,group,value)=>{const obj=reader.objstack.pop();if("type"in obj)if("mesh"===obj.type){const state=obj.state;switch(group){case 91:obj[getTLA(group)]=parseFloat(value),obj.state=1;break;case 92:1===state?(obj.vlen=parseFloat(value),obj.state=2):(obj.plen=parseFloat(value),obj.state=6);break;case 93:obj[getTLA(group)]=parseFloat(value),obj.state=3;break;case 94:obj[getTLA(group)]=parseFloat(value),obj.state=4;break;case 95:obj[getTLA(group)]=parseFloat(value),obj.state=5;break;default:obj.state=7}}else obj[getTLA(group)]=parseFloat(value);reader.objstack.push(obj)},handleValue=(reader,group,value)=>{const obj=reader.objstack.pop();if("type"in obj)if("mesh"===obj.type)switch(obj.state){case 3:void 0===obj.fvals&&(obj.fvals=[]),obj.fvals.push(parseFloat(value));break;case 4:void 0===obj.evals&&(obj.evals=[]),obj.evals.push(parseFloat(value))}else obj[getTLA(group)]=parseFloat(value);reader.objstack.push(obj)},handleString=(reader,group,value)=>{const obj=reader.objstack.pop();"type"in obj&&(obj[getTLA(group)]=value),reader.objstack.push(obj)},handleName=(reader,group,value)=>{const obj=reader.objstack.pop();"type"in obj&&void 0===obj[getTLA(group)]&&(obj[getTLA(group)]=value),reader.objstack.push(obj)},createReader=(src,options)=>{const dxfreader=new DxfReader(options);return dxfreader.on("error",handleError),dxfreader.on("start",handleStart),dxfreader.on("end",handleEnd),dxfreader.absorb(0,handleEntity),dxfreader.absorb(1,handleString),dxfreader.absorb(2,handleName),dxfreader.absorb(3,handleName),dxfreader.absorb(6,handleString),dxfreader.absorb(7,handleString),dxfreader.absorb(8,handleString),dxfreader.absorb(9,handleVariable),dxfreader.absorb(10,handleXcoord),dxfreader.absorb(11,handleDouble),dxfreader.absorb(12,handleDouble),dxfreader.absorb(13,handleDouble),dxfreader.absorb(20,handleYcoord),dxfreader.absorb(21,handleDouble),dxfreader.absorb(22,handleDouble),dxfreader.absorb(23,handleDouble),dxfreader.absorb(30,handleZcoord),dxfreader.absorb(31,handleDouble),dxfreader.absorb(32,handleDouble),dxfreader.absorb(33,handleDouble),dxfreader.absorb(39,handleDouble),dxfreader.absorb(40,handleDouble),dxfreader.absorb(41,handleDouble),dxfreader.absorb(42,handleBulge),dxfreader.absorb(50,handleDouble),dxfreader.absorb(51,handleDouble),dxfreader.absorb(62,handleInt),dxfreader.absorb(70,handleInt),dxfreader.absorb(71,handleInt),dxfreader.absorb(72,handleInt),dxfreader.absorb(73,handleInt),dxfreader.absorb(74,handleInt),dxfreader.absorb(75,handleInt),dxfreader.absorb(90,handleValue),dxfreader.absorb(91,handleLen),dxfreader.absorb(92,handleLen),dxfreader.absorb(93,handleLen),dxfreader.absorb(94,handleLen),dxfreader.absorb(95,handleLen),dxfreader.absorb(210,handleInt),dxfreader.absorb(220,handleInt),dxfreader.absorb(230,handleInt),dxfreader.objstack=[],dxfreader.objstack.push({type:"dxf"}),dxfreader.write(src),dxfreader.close(),dxfreader},instantiate=(src,options)=>{const objs=((reader,options)=>{const layers=[];let current=null;const polygons=[],objects=[],vectors=[];let p=null;for(const obj of reader.objstack)if(p=null,"type"in obj){switch(obj.type){case"dxf":break;case"layer":current=completeCurrent(objects,current,polygons,vectors),layers.push(obj);break;case"variable":case"seqend":current=completeCurrent(objects,current,polygons,vectors);break;case"3dface":p=instantiatePolygon(obj,layers,options),null===current&&(current=geom3.create());break;case"mesh":current=completeCurrent(objects,current,polygons,vectors),objects.push(instantiateMesh(obj,layers,options));break;case"arc":current=completeCurrent(objects,current,polygons,vectors),objects.push(instantiateArc(obj));break;case"circle":current=completeCurrent(objects,current,polygons,vectors),objects.push(instantiateCircle(obj,layers,options));break;case"ellipse":current=completeCurrent(objects,current,polygons,vectors),objects.push(instantiateEllipse(obj));break;case"line":current=completeCurrent(objects,current,polygons,vectors),objects.push(instantiateLine(obj));break;case"polyline":current=completeCurrent(objects,current,polygons,vectors),null===current&&(current=getPolyType$1(obj));break;case"vertex":p=instantiateVector(obj);break;case"lwpolyline":current=completeCurrent(objects,current,polygons,vectors),objects.push(instantiatePath2D(obj))}poly3.isA(p)&&polygons.push(p),p&&"vec"in p&&3===p.vec.length&&vectors.push(p),p&&"vec"in p&&2===p.vec.length&&vectors.push(p)}return current=completeCurrent(objects,current,polygons,vectors),objects})(createReader(src,options),options);return objs},translate=(src,options)=>{const reader=createReader(src,options);let code=`// Produced by JSCAD IO Library : DXF Deserializer (${options.version})\n\n`;return code+=((reader,options)=>{const layers=[];let current=null,parts=[],numobjs=0,p=null;for(const obj of reader.objstack)if(p=null,"type"in obj){if("name"in obj){let name=obj.name;name=name.replace(/ /g,"_"),name=name.replace(/-/g,"_"),name=name.replace(/\./g,"_"),obj.name=name}else obj.name="jscad"+numobjs,numobjs+=1;switch(obj.type){case"dxf":break;case"layer":current=translateCurrent(current,layers,parts,options),parts=[],obj.objects=[],obj.lnam="layer"+layers.length,layers.push(obj);break;case"variable":current=translateCurrent(current,layers,parts,options),parts=[],saveVariable(obj,options);break;case"3dface":p=instantiatePolygon(obj,layers,options),null===current&&(current={type:"3dfaces"},current.name="jscad"+numobjs,numobjs+=1);break;case"mesh":current=translateCurrent(current,layers,parts,options),parts=[],translateMesh(obj,layers,options);break;case"arc":current=translateCurrent(current,layers,parts,options),parts=[],translateArc(obj,layers,options);break;case"circle":current=translateCurrent(current,layers,parts,options),parts=[],translateCircle(obj,layers,options);break;case"ellipse":current=translateCurrent(current,layers,parts,options),parts=[],translateEllipse(obj,layers,options);break;case"line":current=translateCurrent(current,layers,parts,options),parts=[],translateLine(obj,layers,options);break;case"polyline":current=translateCurrent(current,layers,parts,options),parts=[],null===current&&(current=getPolyType(obj),current.name="jscad"+numobjs,numobjs+=1);break;case"vertex":p=instantiateVector(obj);break;case"seqend":current=translateCurrent(current,layers,parts,options),parts=[];break;case"lwpolyline":current=translateCurrent(current,layers,parts,options),parts=[],translatePath2D(obj,layers,options)}poly3.isA(p)&&parts.push(p),p&&"vec"in p&&3===p.vec.length&&parts.push(p),p&&"vec"in p&&2===p.vec.length&&parts.push(p)}current=translateCurrent(current,layers,parts,options);let script="import * from '@jscad/modeling'\n\nexport const main = () => {\n let layers = []\n return layers.concat(";return layers.forEach(layer=>{const name=layer.lnam||"Unknown";script+=`${name}(),`}),script+="[])\n}\n",script+="\nconst createPolygon = (listofpoints, color) => {\n let polygon = poly3.create(listofpoints)\n return colorize(color, polygon)\n}\n",layers.forEach(layer=>{script+=(layer=>{let script=`const ${layer.lnam||"Unknown"} = () => {\n`;for(const object of layer.objects)script+=object.script;script+=" return [";for(const object of layer.objects)script+=object.name+",";return script+="]\n}\n",script})(layer)}),script})(reader,options),code};exports.deserialize=(options,src)=>{const defaults={filename:"dxf",version:"3.0.4-alpha.0",output:"script",strict:!0,colorindex:colorIndex,dxf:{angdir:0,insunits:4,pfacevmax:4}};return options=Object.assign({},defaults,options),src=((stringOrArrayBuffer,defaultBinaryEncoding="utf-8")=>"string"==typeof stringOrArrayBuffer?stringOrArrayBuffer:new TextDecoder(defaultBinaryEncoding).decode(new Uint8Array(stringOrArrayBuffer)))(src),"script"===options.output?translate(src,options):instantiate(src,options)},exports.mimeType="image/vnd.dxf"},"object"==typeof exports&&"undefined"!=typeof module?factory(exports):"function"==typeof define&&define.amd?define(["exports"],factory):factory((global="undefined"!=typeof globalThis?globalThis:global||self).jscadDxfDeserializer={});
|
|
1
|
+
/*! @jscad/dxf-deserializer V3.0.5-alpha.0 (MIT) */
|
|
2
|
+
var global,factory;global=this,factory=function(exports){const dxfMap=new Map([[0,"etyp"],[1,"text"],[2,"name"],[3,"nam1"],[5,"hdle"],[6,"ltyp"],[7,"lsty"],[8,"lnam"],[9,"vari"],[10,"pptx"],[11,"sptx"],[12,"tptx"],[13,"fptx"],[20,"ppty"],[21,"spty"],[22,"tpty"],[23,"fpty"],[30,"pptz"],[31,"sptz"],[32,"tptz"],[33,"fptz"],[38,"elev"],[39,"lthk"],[40,"swid"],[41,"ewid"],[42,"bulg"],[43,"cwid"],[48,"lscl"],[50,"ang0"],[51,"ang1"],[60,"visb"],[62,"cnmb"],[67,"spac"],[70,"lflg"],[71,"fvia"],[72,"fvib"],[73,"fvic"],[74,"fvid"],[75,"cflg"],[90,"vlen"],[91,"slen"],[92,"plen"],[93,"flen"],[94,"elen"],[95,"clen"],[100,"sbnm"],[210,"etrx"],[220,"etry"],[230,"etrz"]]),getTLA=group=>dxfMap.get(group),colorIndex=[[0,0,0,255],[255,0,0,255],[255,255,0,255],[0,255,0,255],[0,255,255,255],[0,0,255,255],[255,0,255,255],[255,255,255,255],[128,128,128,255],[192,192,192,255],[255,0,0,255],[255,127,127,255],[165,0,0,255],[165,82,82,255],[127,0,0,255],[127,63,63,255],[76,0,0,255],[76,38,38,255],[38,0,0,255],[38,19,19,255],[255,63,0,255],[255,159,127,255],[165,41,0,255],[165,103,82,255],[127,31,0,255],[127,79,63,255],[76,19,0,255],[76,47,38,255],[38,9,0,255],[38,28,19,255],[255,127,0,255],[255,191,127,255],[165,82,0,255],[165,124,82,255],[127,63,0,255],[127,95,63,255],[76,38,0,255],[76,57,38,255],[38,19,0,255],[38,28,19,255],[255,191,0,255],[255,223,127,255],[165,124,0,255],[165,145,82,255],[127,95,0,255],[127,111,63,255],[76,57,0,255],[76,66,38,255],[38,28,0,255],[38,33,19,255],[255,255,0,255],[255,255,127,255],[165,165,0,255],[165,165,82,255],[127,127,0,255],[127,127,63,255],[76,76,0,255],[76,76,38,255],[38,38,0,255],[38,38,19,255],[191,255,0,255],[223,255,127,255],[124,165,0,255],[145,165,82,255],[95,127,0,255],[111,127,63,255],[57,76,0,255],[66,76,38,255],[28,38,0,255],[33,38,19,255],[127,255,0,255],[191,255,127,255],[82,165,0,255],[124,165,82,255],[63,127,0,255],[95,127,63,255],[38,76,0,255],[57,76,38,255],[19,38,0,255],[28,38,19,255],[63,255,0,255],[159,255,127,255],[41,165,0,255],[103,165,82,255],[31,127,0,255],[79,127,63,255],[19,76,0,255],[47,76,38,255],[9,38,0,255],[23,38,19,255],[0,255,0,255],[125,255,127,255],[0,165,0,255],[82,165,82,255],[0,127,0,255],[63,127,63,255],[0,76,0,255],[38,76,38,255],[0,38,0,255],[19,38,19,255],[0,255,63,255],[127,255,159,255],[0,165,41,255],[82,165,103,255],[0,127,31,255],[63,127,79,255],[0,76,19,255],[38,76,47,255],[0,38,9,255],[19,88,23,255],[0,255,127,255],[127,255,191,255],[0,165,82,255],[82,165,124,255],[0,127,63,255],[63,127,95,255],[0,76,38,255],[38,76,57,255],[0,38,19,255],[19,88,28,255],[0,255,191,255],[127,255,223,255],[0,165,124,255],[82,165,145,255],[0,127,95,255],[63,127,111,255],[0,76,57,255],[38,76,66,255],[0,38,28,255],[19,88,88,255],[0,255,255,255],[127,255,255,255],[0,165,165,255],[82,165,165,255],[0,127,127,255],[63,127,127,255],[0,76,76,255],[38,76,76,255],[0,38,38,255],[19,88,88,255],[0,191,255,255],[127,223,255,255],[0,124,165,255],[82,145,165,255],[0,95,127,255],[63,111,217,255],[0,57,76,255],[38,66,126,255],[0,28,38,255],[19,88,88,255],[0,127,255,255],[127,191,255,255],[0,82,165,255],[82,124,165,255],[0,63,127,255],[63,95,127,255],[0,38,76,255],[38,57,126,255],[0,19,38,255],[19,28,88,255],[0,63,255,255],[127,159,255,255],[0,41,165,255],[82,103,165,255],[0,31,127,255],[63,79,127,255],[0,19,76,255],[38,47,126,255],[0,9,38,255],[19,23,88,255],[0,0,255,255],[127,127,255,255],[0,0,165,255],[82,82,165,255],[0,0,127,255],[63,63,127,255],[0,0,76,255],[38,38,126,255],[0,0,38,255],[19,19,88,255],[63,0,255,255],[159,127,255,255],[41,0,165,255],[103,82,165,255],[31,0,127,255],[79,63,127,255],[19,0,76,255],[47,38,126,255],[9,0,38,255],[23,19,88,255],[127,0,255,255],[191,127,255,255],[165,0,82,255],[124,82,165,255],[63,0,127,255],[95,63,127,255],[38,0,76,255],[57,38,126,255],[19,0,38,255],[28,19,88,255],[191,0,255,255],[223,127,255,255],[124,0,165,255],[142,82,165,255],[95,0,127,255],[111,63,127,255],[57,0,76,255],[66,38,76,255],[28,0,38,255],[88,19,88,255],[255,0,255,255],[255,127,255,255],[165,0,165,255],[165,82,165,255],[127,0,127,255],[127,63,127,255],[76,0,76,255],[76,38,76,255],[38,0,38,255],[88,19,88,255],[255,0,191,255],[255,127,223,255],[165,0,124,255],[165,82,145,255],[127,0,95,255],[127,63,111,255],[76,0,57,255],[76,38,66,255],[38,0,28,255],[88,19,88,255],[255,0,127,255],[255,127,191,255],[165,0,82,255],[165,82,124,255],[127,0,63,255],[127,63,95,255],[76,0,38,255],[76,38,57,255],[38,0,19,255],[88,19,28,255],[255,0,63,255],[255,127,159,255],[165,0,41,255],[165,82,103,255],[127,0,31,255],[127,63,79,255],[76,0,19,255],[76,38,47,255],[38,0,9,255],[88,19,23,255],[0,0,0,255],[101,101,101,255],[102,102,102,255],[153,153,153,255],[204,204,204,255],[255,255,255,255]];class DxfReader{constructor(options){this.options=Object.assign({},{strict:!1,track:!0},options),this.trackPosition=this.options.track,this.trackPosition&&(this.line=0,this.column=0,this.c=0)}on(state,callback){return this["on"+state]=callback,this}absorb(group,callback){return void 0===this.absorbers&&(this.absorbers=new Map),this.absorbers.set(group,callback),this}write(data){return parse(this,data),this}close(){return this.isclosed=!0,this}}const emiterror=(reader,er)=>(reader.trackPosition&&(er+=`\nLine: ${reader.line}\nColumn: ${reader.column}\nChar: ${reader.c}`),er=new Error(er),reader.error=er,emitstate(reader,"onerror",er)),emitend=reader=>emitstate(reader,"onend",reader.data),emitstate=(reader,state,data)=>{const onhandler=state.toString();return reader[onhandler]&&reader[onhandler](reader,data),reader},parse=(reader,data)=>{if(reader.error)throw reader.error;if(reader.isclosed)return emiterror(reader,"Cannot write after close");if((reader=>{emitstate(reader,"onstart",reader.data)})(reader),null===data)return emitend(reader);reader.group=null,reader.value=null,reader.error=null,reader.position=0,reader.line=0,reader.column=0;let i=0,c="",l="";for(;null===reader.error&&(c=charAt(data,i++),c);)reader.trackPosition&&(reader.position++,"\n"===c?(reader.line++,reader.column=0):reader.column++),"\n"===c?(parseLine(reader,l),l=""):l+=c;return emitend(reader),reader},parseLine=(reader,line)=>{line=line.trim(),null===reader.group?(setDxfGroup(reader,line),reader.value=null):setDxfValue(reader,line),null!==reader.group&&null!==reader.value&&(((reader,group,value)=>{if(void 0!==reader.absorbers){const absorber=reader.absorbers.get(group);void 0!==absorber&&absorber(reader,group,value)}})(reader,reader.group,reader.value),reader.group=null,reader.value=null)},setDxfGroup=(reader,line)=>{const code=parseInt(line);isNaN(code)?(emiterror(reader,"Invalid group (int)"),reader.group=null):reader.group=code},setDxfValue=(reader,line)=>{reader.options.strict,reader.value=line},charAt=(data,i)=>data&&data.length>i?data.charAt(i):"",copy$5=(out,matrix)=>(out[0]=matrix[0],out[1]=matrix[1],out[2]=matrix[2],out[3]=matrix[3],out[4]=matrix[4],out[5]=matrix[5],out[6]=matrix[6],out[7]=matrix[7],out[8]=matrix[8],out[9]=matrix[9],out[10]=matrix[10],out[11]=matrix[11],out[12]=matrix[12],out[13]=matrix[13],out[14]=matrix[14],out[15]=matrix[15],out),EPS$1=1e-5,TAU=2*Math.PI,rezero=n=>Math.abs(n)<1e-13?0:n,sin=radians=>rezero(Math.sin(radians)),cos=radians=>rezero(Math.cos(radians)),identity=out=>(out[0]=1,out[1]=0,out[2]=0,out[3]=0,out[4]=0,out[5]=1,out[6]=0,out[7]=0,out[8]=0,out[9]=0,out[10]=1,out[11]=0,out[12]=0,out[13]=0,out[14]=0,out[15]=1,out),fromRotation=(out,rad,axis)=>{let[x,y,z]=axis;const lengthSquared=x*x+y*y+z*z;if(Math.abs(lengthSquared)<EPS$1)return identity(out);const len=1/Math.sqrt(lengthSquared);x*=len,y*=len,z*=len;const s=sin(rad),c=cos(rad),t=1-c;return out[0]=x*x*t+c,out[1]=y*x*t+z*s,out[2]=z*x*t-y*s,out[3]=0,out[4]=x*y*t-z*s,out[5]=y*y*t+c,out[6]=z*y*t+x*s,out[7]=0,out[8]=x*z*t+y*s,out[9]=y*z*t-x*s,out[10]=z*z*t+c,out[11]=0,out[12]=0,out[13]=0,out[14]=0,out[15]=1,out},fromTranslation=(out,vector)=>(out[0]=1,out[1]=0,out[2]=0,out[3]=0,out[4]=0,out[5]=1,out[6]=0,out[7]=0,out[8]=0,out[9]=0,out[10]=1,out[11]=0,out[12]=vector[0],out[13]=vector[1],out[14]=vector[2],out[15]=1,out),fromValues$4=(m00,m01,m02,m03,m10,m11,m12,m13,m20,m21,m22,m23,m30,m31,m32,m33)=>{const out=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1];return out[0]=m00,out[1]=m01,out[2]=m02,out[3]=m03,out[4]=m10,out[5]=m11,out[6]=m12,out[7]=m13,out[8]=m20,out[9]=m21,out[10]=m22,out[11]=m23,out[12]=m30,out[13]=m31,out[14]=m32,out[15]=m33,out},abs$1=(out,vector)=>(out[0]=Math.abs(vector[0]),out[1]=Math.abs(vector[1]),out[2]=Math.abs(vector[2]),out),add$1=(out,a,b)=>(out[0]=a[0]+b[0],out[1]=a[1]+b[1],out[2]=a[2]+b[2],out),dot$2=(a,b)=>a[0]*b[0]+a[1]*b[1]+a[2]*b[2],create$c=()=>[0,0,0],clone$a=vector=>{const out=[0,0,0];return out[0]=vector[0],out[1]=vector[1],out[2]=vector[2],out},copy$4=(out,vector)=>(out[0]=vector[0],out[1]=vector[1],out[2]=vector[2],out),cross$1=(out,a,b)=>{const ax=a[0],ay=a[1],az=a[2],bx=b[0],by=b[1],bz=b[2];return out[0]=ay*bz-az*by,out[1]=az*bx-ax*bz,out[2]=ax*by-ay*bx,out},distance$1=(a,b)=>{const x=b[0]-a[0],y=b[1]-a[1],z=b[2]-a[2];return Math.sqrt(x*x+y*y+z*z)},divide$1=(out,a,b)=>(out[0]=a[0]/b[0],out[1]=a[1]/b[1],out[2]=a[2]/b[2],out),equals$8=(a,b)=>a[0]===b[0]&&a[1]===b[1]&&a[2]===b[2],fromValues$3=(x,y,z)=>{const out=[0,0,0];return out[0]=x,out[1]=y,out[2]=z,out},fromVec2=(out,vector,z=0)=>(out[0]=vector[0],out[1]=vector[1],out[2]=z,out),length$2=vector=>{const x=vector[0],y=vector[1],z=vector[2];return Math.sqrt(x*x+y*y+z*z)},max$1=(out,a,b)=>(out[0]=Math.max(a[0],b[0]),out[1]=Math.max(a[1],b[1]),out[2]=Math.max(a[2],b[2]),out),min$1=(out,a,b)=>(out[0]=Math.min(a[0],b[0]),out[1]=Math.min(a[1],b[1]),out[2]=Math.min(a[2],b[2]),out),normalize$1=(out,vector)=>{const x=vector[0],y=vector[1],z=vector[2];let len=x*x+y*y+z*z;return len>0&&(len=1/Math.sqrt(len)),out[0]=x*len,out[1]=y*len,out[2]=z*len,out},orthogonal=(out,vector)=>{const bV=abs$1([0,0,0],vector),b0=0+(bV[0]<bV[1]&&bV[0]<bV[2]),b1=0+(bV[1]<=bV[0]&&bV[1]<bV[2]),b2=0+(bV[2]<=bV[0]&&bV[2]<=bV[1]);return cross$1(out,vector,[b0,b1,b2])},scale$3=(out,vector,amount)=>(out[0]=vector[0]*amount,out[1]=vector[1]*amount,out[2]=vector[2]*amount,out),squaredDistance$1=(a,b)=>{const x=b[0]-a[0],y=b[1]-a[1],z=b[2]-a[2];return x*x+y*y+z*z},squaredLength$1=vector=>{const x=vector[0],y=vector[1],z=vector[2];return x*x+y*y+z*z},subtract$3=(out,a,b)=>(out[0]=a[0]-b[0],out[1]=a[1]-b[1],out[2]=a[2]-b[2],out),toString$c=vec=>`[${vec[0].toFixed(7)}, ${vec[1].toFixed(7)}, ${vec[2].toFixed(7)}]`,transform$d=(out,vector,matrix)=>{const x=vector[0],y=vector[1],z=vector[2];let w=matrix[3]*x+matrix[7]*y+matrix[11]*z+matrix[15];return w=w||1,out[0]=(matrix[0]*x+matrix[4]*y+matrix[8]*z+matrix[12])/w,out[1]=(matrix[1]*x+matrix[5]*y+matrix[9]*z+matrix[13])/w,out[2]=(matrix[2]*x+matrix[6]*y+matrix[10]*z+matrix[14])/w,out};var index$k=Object.freeze({__proto__:null,abs:abs$1,add:add$1,angle:(a,b)=>{const ax=a[0],ay=a[1],az=a[2],bx=b[0],by=b[1],bz=b[2],mag=Math.sqrt(ax*ax+ay*ay+az*az)*Math.sqrt(bx*bx+by*by+bz*bz),cosine=mag&&dot$2(a,b)/mag;return Math.acos(Math.min(Math.max(cosine,-1),1))},clone:clone$a,copy:copy$4,create:create$c,cross:cross$1,distance:distance$1,divide:divide$1,dot:dot$2,equals:equals$8,fromScalar:(out,scalar)=>(out[0]=scalar,out[1]=scalar,out[2]=scalar,out),fromValues:fromValues$3,fromVec2:fromVec2,length:length$2,lerp:(out,a,b,t)=>(out[0]=a[0]+t*(b[0]-a[0]),out[1]=a[1]+t*(b[1]-a[1]),out[2]=a[2]+t*(b[2]-a[2]),out),max:max$1,min:min$1,multiply:(out,a,b)=>(out[0]=a[0]*b[0],out[1]=a[1]*b[1],out[2]=a[2]*b[2],out),negate:(out,vector)=>(out[0]=-vector[0],out[1]=-vector[1],out[2]=-vector[2],out),normalize:normalize$1,orthogonal:orthogonal,rotateX:(out,vector,origin,radians)=>{const p=[],r=[];return p[0]=vector[0]-origin[0],p[1]=vector[1]-origin[1],p[2]=vector[2]-origin[2],r[0]=p[0],r[1]=p[1]*Math.cos(radians)-p[2]*Math.sin(radians),r[2]=p[1]*Math.sin(radians)+p[2]*Math.cos(radians),out[0]=r[0]+origin[0],out[1]=r[1]+origin[1],out[2]=r[2]+origin[2],out},rotateY:(out,vector,origin,radians)=>{const p=[],r=[];return p[0]=vector[0]-origin[0],p[1]=vector[1]-origin[1],p[2]=vector[2]-origin[2],r[0]=p[2]*Math.sin(radians)+p[0]*Math.cos(radians),r[1]=p[1],r[2]=p[2]*Math.cos(radians)-p[0]*Math.sin(radians),out[0]=r[0]+origin[0],out[1]=r[1]+origin[1],out[2]=r[2]+origin[2],out},rotateZ:(out,vector,origin,radians)=>{const p=[],r=[];return p[0]=vector[0]-origin[0],p[1]=vector[1]-origin[1],r[0]=p[0]*Math.cos(radians)-p[1]*Math.sin(radians),r[1]=p[0]*Math.sin(radians)+p[1]*Math.cos(radians),out[0]=r[0]+origin[0],out[1]=r[1]+origin[1],out[2]=vector[2],out},scale:scale$3,snap:(out,vector,epsilon)=>(out[0]=Math.round(vector[0]/epsilon)*epsilon+0,out[1]=Math.round(vector[1]/epsilon)*epsilon+0,out[2]=Math.round(vector[2]/epsilon)*epsilon+0,out),squaredDistance:squaredDistance$1,squaredLength:squaredLength$1,subtract:subtract$3,toString:toString$c,transform:transform$d});const fromVectorRotation=(out,source,target)=>{const sourceNormal=normalize$1([0,0,0],source),targetNormal=normalize$1([0,0,0],target),axis=cross$1([0,0,0],targetNormal,sourceNormal),cosA=dot$2(targetNormal,sourceNormal);if(-1===cosA)return fromRotation(out,Math.PI,orthogonal(axis,sourceNormal));const k=1/(1+cosA);return out[0]=axis[0]*axis[0]*k+cosA,out[1]=axis[1]*axis[0]*k-axis[2],out[2]=axis[2]*axis[0]*k+axis[1],out[3]=0,out[4]=axis[0]*axis[1]*k+axis[2],out[5]=axis[1]*axis[1]*k+cosA,out[6]=axis[2]*axis[1]*k-axis[0],out[7]=0,out[8]=axis[0]*axis[2]*k-axis[1],out[9]=axis[1]*axis[2]*k+axis[0],out[10]=axis[2]*axis[2]*k+cosA,out[11]=0,out[12]=0,out[13]=0,out[14]=0,out[15]=1,out},fromXRotation=(out,radians)=>{const s=sin(radians),c=cos(radians);return out[0]=1,out[1]=0,out[2]=0,out[3]=0,out[4]=0,out[5]=c,out[6]=s,out[7]=0,out[8]=0,out[9]=-s,out[10]=c,out[11]=0,out[12]=0,out[13]=0,out[14]=0,out[15]=1,out},fromZRotation=(out,radians)=>{const s=sin(radians),c=cos(radians);return out[0]=c,out[1]=s,out[2]=0,out[3]=0,out[4]=-s,out[5]=c,out[6]=0,out[7]=0,out[8]=0,out[9]=0,out[10]=1,out[11]=0,out[12]=0,out[13]=0,out[14]=0,out[15]=1,out},isIdentity=matrix=>1===matrix[0]&&0===matrix[1]&&0===matrix[2]&&0===matrix[3]&&0===matrix[4]&&1===matrix[5]&&0===matrix[6]&&0===matrix[7]&&0===matrix[8]&&0===matrix[9]&&1===matrix[10]&&0===matrix[11]&&0===matrix[12]&&0===matrix[13]&&0===matrix[14]&&1===matrix[15],isMirroring=matrix=>{const x=matrix[4]*matrix[9]-matrix[8]*matrix[5],y=matrix[8]*matrix[1]-matrix[0]*matrix[9],z=matrix[0]*matrix[5]-matrix[4]*matrix[1];return x*matrix[2]+y*matrix[6]+z*matrix[10]<0},isZero=num=>Math.abs(num)<Number.EPSILON,mirrorByPlane=(out,plane)=>{const[nx,ny,nz,w]=plane;return out[0]=1-2*nx*nx,out[1]=-2*ny*nx,out[2]=-2*nz*nx,out[3]=0,out[4]=-2*nx*ny,out[5]=1-2*ny*ny,out[6]=-2*nz*ny,out[7]=0,out[8]=-2*nx*nz,out[9]=-2*ny*nz,out[10]=1-2*nz*nz,out[11]=0,out[12]=2*nx*w,out[13]=2*ny*w,out[14]=2*nz*w,out[15]=1,out},multiply$1=(out,a,b)=>{const a00=a[0],a01=a[1],a02=a[2],a03=a[3],a10=a[4],a11=a[5],a12=a[6],a13=a[7],a20=a[8],a21=a[9],a22=a[10],a23=a[11],a30=a[12],a31=a[13],a32=a[14],a33=a[15];let b0=b[0],b1=b[1],b2=b[2],b3=b[3];return out[0]=b0*a00+b1*a10+b2*a20+b3*a30,out[1]=b0*a01+b1*a11+b2*a21+b3*a31,out[2]=b0*a02+b1*a12+b2*a22+b3*a32,out[3]=b0*a03+b1*a13+b2*a23+b3*a33,b0=b[4],b1=b[5],b2=b[6],b3=b[7],out[4]=b0*a00+b1*a10+b2*a20+b3*a30,out[5]=b0*a01+b1*a11+b2*a21+b3*a31,out[6]=b0*a02+b1*a12+b2*a22+b3*a32,out[7]=b0*a03+b1*a13+b2*a23+b3*a33,b0=b[8],b1=b[9],b2=b[10],b3=b[11],out[8]=b0*a00+b1*a10+b2*a20+b3*a30,out[9]=b0*a01+b1*a11+b2*a21+b3*a31,out[10]=b0*a02+b1*a12+b2*a22+b3*a32,out[11]=b0*a03+b1*a13+b2*a23+b3*a33,b0=b[12],b1=b[13],b2=b[14],b3=b[15],out[12]=b0*a00+b1*a10+b2*a20+b3*a30,out[13]=b0*a01+b1*a11+b2*a21+b3*a31,out[14]=b0*a02+b1*a12+b2*a22+b3*a32,out[15]=b0*a03+b1*a13+b2*a23+b3*a33,out};var index$j=Object.freeze({__proto__:null,add:(out,a,b)=>(out[0]=a[0]+b[0],out[1]=a[1]+b[1],out[2]=a[2]+b[2],out[3]=a[3]+b[3],out[4]=a[4]+b[4],out[5]=a[5]+b[5],out[6]=a[6]+b[6],out[7]=a[7]+b[7],out[8]=a[8]+b[8],out[9]=a[9]+b[9],out[10]=a[10]+b[10],out[11]=a[11]+b[11],out[12]=a[12]+b[12],out[13]=a[13]+b[13],out[14]=a[14]+b[14],out[15]=a[15]+b[15],out),clone:matrix=>{const out=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1];return out[0]=matrix[0],out[1]=matrix[1],out[2]=matrix[2],out[3]=matrix[3],out[4]=matrix[4],out[5]=matrix[5],out[6]=matrix[6],out[7]=matrix[7],out[8]=matrix[8],out[9]=matrix[9],out[10]=matrix[10],out[11]=matrix[11],out[12]=matrix[12],out[13]=matrix[13],out[14]=matrix[14],out[15]=matrix[15],out},copy:copy$5,create:()=>[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],equals:(a,b)=>a[0]===b[0]&&a[1]===b[1]&&a[2]===b[2]&&a[3]===b[3]&&a[4]===b[4]&&a[5]===b[5]&&a[6]===b[6]&&a[7]===b[7]&&a[8]===b[8]&&a[9]===b[9]&&a[10]===b[10]&&a[11]===b[11]&&a[12]===b[12]&&a[13]===b[13]&&a[14]===b[14]&&a[15]===b[15],fromRotation:fromRotation,fromScaling:(out,vector)=>(out[0]=vector[0],out[1]=0,out[2]=0,out[3]=0,out[4]=0,out[5]=vector[1],out[6]=0,out[7]=0,out[8]=0,out[9]=0,out[10]=vector[2],out[11]=0,out[12]=0,out[13]=0,out[14]=0,out[15]=1,out),fromTaitBryanRotation:(out,yaw,pitch,roll)=>{const sy=sin(yaw),cy=cos(yaw),sp=sin(pitch),cp=cos(pitch),sr=sin(roll),cr=cos(roll);return out[0]=cp*cy,out[1]=cp*sy,out[2]=-sp,out[3]=0,out[4]=sr*sp*cy-cr*sy,out[5]=cr*cy+sr*sp*sy,out[6]=sr*cp,out[7]=0,out[8]=sr*sy+cr*sp*cy,out[9]=cr*sp*sy-sr*cy,out[10]=cr*cp,out[11]=0,out[12]=0,out[13]=0,out[14]=0,out[15]=1,out},fromTranslation:fromTranslation,fromValues:fromValues$4,fromVectorRotation:fromVectorRotation,fromXRotation:fromXRotation,fromYRotation:(out,radians)=>{const s=sin(radians),c=cos(radians);return out[0]=c,out[1]=0,out[2]=-s,out[3]=0,out[4]=0,out[5]=1,out[6]=0,out[7]=0,out[8]=s,out[9]=0,out[10]=c,out[11]=0,out[12]=0,out[13]=0,out[14]=0,out[15]=1,out},fromZRotation:fromZRotation,identity:identity,invert:(out,matrix)=>{const a00=matrix[0],a01=matrix[1],a02=matrix[2],a03=matrix[3],a10=matrix[4],a11=matrix[5],a12=matrix[6],a13=matrix[7],a20=matrix[8],a21=matrix[9],a22=matrix[10],a23=matrix[11],a30=matrix[12],a31=matrix[13],a32=matrix[14],a33=matrix[15],b00=a00*a11-a01*a10,b01=a00*a12-a02*a10,b02=a00*a13-a03*a10,b03=a01*a12-a02*a11,b04=a01*a13-a03*a11,b05=a02*a13-a03*a12,b06=a20*a31-a21*a30,b07=a20*a32-a22*a30,b08=a20*a33-a23*a30,b09=a21*a32-a22*a31,b10=a21*a33-a23*a31,b11=a22*a33-a23*a32;let det=b00*b11-b01*b10+b02*b09+b03*b08-b04*b07+b05*b06;return det?(det=1/det,out[0]=(a11*b11-a12*b10+a13*b09)*det,out[1]=(a02*b10-a01*b11-a03*b09)*det,out[2]=(a31*b05-a32*b04+a33*b03)*det,out[3]=(a22*b04-a21*b05-a23*b03)*det,out[4]=(a12*b08-a10*b11-a13*b07)*det,out[5]=(a00*b11-a02*b08+a03*b07)*det,out[6]=(a32*b02-a30*b05-a33*b01)*det,out[7]=(a20*b05-a22*b02+a23*b01)*det,out[8]=(a10*b10-a11*b08+a13*b06)*det,out[9]=(a01*b08-a00*b10-a03*b06)*det,out[10]=(a30*b04-a31*b02+a33*b00)*det,out[11]=(a21*b02-a20*b04-a23*b00)*det,out[12]=(a11*b07-a10*b09-a12*b06)*det,out[13]=(a00*b09-a01*b07+a02*b06)*det,out[14]=(a31*b01-a30*b03-a32*b00)*det,out[15]=(a20*b03-a21*b01+a22*b00)*det,out):null},isIdentity:isIdentity,isMirroring:isMirroring,isOnlyTransformScale:matrix=>isZero(matrix[1])&&isZero(matrix[2])&&isZero(matrix[3])&&isZero(matrix[4])&&isZero(matrix[6])&&isZero(matrix[7])&&isZero(matrix[8])&&isZero(matrix[9])&&isZero(matrix[11])&&1===matrix[15],mirrorByPlane:mirrorByPlane,multiply:multiply$1,rotate:(out,matrix,radians,axis)=>{let[x,y,z]=axis;const lengthSquared=x*x+y*y+z*z;if(Math.abs(lengthSquared)<EPS$1)return copy$5(out,matrix);const len=1/Math.sqrt(lengthSquared);x*=len,y*=len,z*=len;const s=sin(radians),c=cos(radians),t=1-c,a00=matrix[0],a01=matrix[1],a02=matrix[2],a03=matrix[3],a10=matrix[4],a11=matrix[5],a12=matrix[6],a13=matrix[7],a20=matrix[8],a21=matrix[9],a22=matrix[10],a23=matrix[11],b00=x*x*t+c,b01=y*x*t+z*s,b02=z*x*t-y*s,b10=x*y*t-z*s,b11=y*y*t+c,b12=z*y*t+x*s,b20=x*z*t+y*s,b21=y*z*t-x*s,b22=z*z*t+c;return out[0]=a00*b00+a10*b01+a20*b02,out[1]=a01*b00+a11*b01+a21*b02,out[2]=a02*b00+a12*b01+a22*b02,out[3]=a03*b00+a13*b01+a23*b02,out[4]=a00*b10+a10*b11+a20*b12,out[5]=a01*b10+a11*b11+a21*b12,out[6]=a02*b10+a12*b11+a22*b12,out[7]=a03*b10+a13*b11+a23*b12,out[8]=a00*b20+a10*b21+a20*b22,out[9]=a01*b20+a11*b21+a21*b22,out[10]=a02*b20+a12*b21+a22*b22,out[11]=a03*b20+a13*b21+a23*b22,matrix!==out&&(out[12]=matrix[12],out[13]=matrix[13],out[14]=matrix[14],out[15]=matrix[15]),out},rotateX:(out,matrix,radians)=>{const s=sin(radians),c=cos(radians),a10=matrix[4],a11=matrix[5],a12=matrix[6],a13=matrix[7],a20=matrix[8],a21=matrix[9],a22=matrix[10],a23=matrix[11];return matrix!==out&&(out[0]=matrix[0],out[1]=matrix[1],out[2]=matrix[2],out[3]=matrix[3],out[12]=matrix[12],out[13]=matrix[13],out[14]=matrix[14],out[15]=matrix[15]),out[4]=a10*c+a20*s,out[5]=a11*c+a21*s,out[6]=a12*c+a22*s,out[7]=a13*c+a23*s,out[8]=a20*c-a10*s,out[9]=a21*c-a11*s,out[10]=a22*c-a12*s,out[11]=a23*c-a13*s,out},rotateY:(out,matrix,radians)=>{const s=sin(radians),c=cos(radians),a00=matrix[0],a01=matrix[1],a02=matrix[2],a03=matrix[3],a20=matrix[8],a21=matrix[9],a22=matrix[10],a23=matrix[11];return matrix!==out&&(out[4]=matrix[4],out[5]=matrix[5],out[6]=matrix[6],out[7]=matrix[7],out[12]=matrix[12],out[13]=matrix[13],out[14]=matrix[14],out[15]=matrix[15]),out[0]=a00*c-a20*s,out[1]=a01*c-a21*s,out[2]=a02*c-a22*s,out[3]=a03*c-a23*s,out[8]=a00*s+a20*c,out[9]=a01*s+a21*c,out[10]=a02*s+a22*c,out[11]=a03*s+a23*c,out},rotateZ:(out,matrix,radians)=>{const s=sin(radians),c=cos(radians),a00=matrix[0],a01=matrix[1],a02=matrix[2],a03=matrix[3],a10=matrix[4],a11=matrix[5],a12=matrix[6],a13=matrix[7];return matrix!==out&&(out[8]=matrix[8],out[9]=matrix[9],out[10]=matrix[10],out[11]=matrix[11],out[12]=matrix[12],out[13]=matrix[13],out[14]=matrix[14],out[15]=matrix[15]),out[0]=a00*c+a10*s,out[1]=a01*c+a11*s,out[2]=a02*c+a12*s,out[3]=a03*c+a13*s,out[4]=a10*c-a00*s,out[5]=a11*c-a01*s,out[6]=a12*c-a02*s,out[7]=a13*c-a03*s,out},scale:(out,matrix,dimensions)=>{const x=dimensions[0],y=dimensions[1],z=dimensions[2];return out[0]=matrix[0]*x,out[1]=matrix[1]*x,out[2]=matrix[2]*x,out[3]=matrix[3]*x,out[4]=matrix[4]*y,out[5]=matrix[5]*y,out[6]=matrix[6]*y,out[7]=matrix[7]*y,out[8]=matrix[8]*z,out[9]=matrix[9]*z,out[10]=matrix[10]*z,out[11]=matrix[11]*z,out[12]=matrix[12],out[13]=matrix[13],out[14]=matrix[14],out[15]=matrix[15],out},subtract:(out,a,b)=>(out[0]=a[0]-b[0],out[1]=a[1]-b[1],out[2]=a[2]-b[2],out[3]=a[3]-b[3],out[4]=a[4]-b[4],out[5]=a[5]-b[5],out[6]=a[6]-b[6],out[7]=a[7]-b[7],out[8]=a[8]-b[8],out[9]=a[9]-b[9],out[10]=a[10]-b[10],out[11]=a[11]-b[11],out[12]=a[12]-b[12],out[13]=a[13]-b[13],out[14]=a[14]-b[14],out[15]=a[15]-b[15],out),toString:mat=>mat.map(n=>n.toFixed(7)).toString(),translate:(out,matrix,offsets)=>{const x=offsets[0],y=offsets[1],z=offsets[2];let a00,a01,a02,a03,a10,a11,a12,a13,a20,a21,a22,a23;return matrix===out?(out[12]=matrix[0]*x+matrix[4]*y+matrix[8]*z+matrix[12],out[13]=matrix[1]*x+matrix[5]*y+matrix[9]*z+matrix[13],out[14]=matrix[2]*x+matrix[6]*y+matrix[10]*z+matrix[14],out[15]=matrix[3]*x+matrix[7]*y+matrix[11]*z+matrix[15]):(a00=matrix[0],a01=matrix[1],a02=matrix[2],a03=matrix[3],a10=matrix[4],a11=matrix[5],a12=matrix[6],a13=matrix[7],a20=matrix[8],a21=matrix[9],a22=matrix[10],a23=matrix[11],out[0]=a00,out[1]=a01,out[2]=a02,out[3]=a03,out[4]=a10,out[5]=a11,out[6]=a12,out[7]=a13,out[8]=a20,out[9]=a21,out[10]=a22,out[11]=a23,out[12]=a00*x+a10*y+a20*z+matrix[12],out[13]=a01*x+a11*y+a21*z+matrix[13],out[14]=a02*x+a12*y+a22*z+matrix[14],out[15]=a03*x+a13*y+a23*z+matrix[15]),out}});const create$b=(outlines=[])=>({outlines:outlines,transforms:[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]}),add=(out,a,b)=>(out[0]=a[0]+b[0],out[1]=a[1]+b[1],out),angleRadians=vector=>Math.atan2(vector[1],vector[0]),angleDegrees=vector=>57.29577951308232*angleRadians(vector),create$a=()=>[0,0],clone$9=vector=>{const out=[0,0];return out[0]=vector[0],out[1]=vector[1],out},cross=(out,a,b)=>(out[0]=0,out[1]=0,out[2]=a[0]*b[1]-a[1]*b[0],out),distance=(a,b)=>{const x=b[0]-a[0],y=b[1]-a[1];return Math.sqrt(x*x+y*y)},dot$1=(a,b)=>a[0]*b[0]+a[1]*b[1],equals$7=(a,b)=>a[0]===b[0]&&a[1]===b[1],fromAngleRadians=(out,radians)=>(out[0]=cos(radians),out[1]=sin(radians),out),fromValues$2=(x,y)=>{const out=[0,0];return out[0]=x,out[1]=y,out},max=(out,a,b)=>(out[0]=Math.max(a[0],b[0]),out[1]=Math.max(a[1],b[1]),out),min=(out,a,b)=>(out[0]=Math.min(a[0],b[0]),out[1]=Math.min(a[1],b[1]),out),negate=(out,vector)=>(out[0]=-vector[0],out[1]=-vector[1],out),rotate$1=(out,vector,origin,radians)=>{const x=vector[0]-origin[0],y=vector[1]-origin[1],c=Math.cos(radians),s=Math.sin(radians);return out[0]=x*c-y*s+origin[0],out[1]=x*s+y*c+origin[1],out},normal=(out,vector)=>rotate$1(out,vector,[0,0],TAU/4),normalize=(out,vector)=>{const x=vector[0],y=vector[1];let len=x*x+y*y;return len>0&&(len=1/Math.sqrt(len)),out[0]=x*len,out[1]=y*len,out},scale$1=(out,vector,amount)=>(out[0]=vector[0]*amount,out[1]=vector[1]*amount,out),subtract$1=(out,a,b)=>(out[0]=a[0]-b[0],out[1]=a[1]-b[1],out),toString$a=vector=>`[${vector[0].toFixed(7)}, ${vector[1].toFixed(7)}]`,transform$c=(out,vector,matrix)=>{const x=vector[0],y=vector[1];return out[0]=matrix[0]*x+matrix[4]*y+matrix[12],out[1]=matrix[1]*x+matrix[5]*y+matrix[13],out};var index$i=Object.freeze({__proto__:null,abs:(out,vector)=>(out[0]=Math.abs(vector[0]),out[1]=Math.abs(vector[1]),out),add:add,angle:angleRadians,angleDegrees:angleDegrees,angleRadians:angleRadians,clone:clone$9,copy:(out,vector)=>(out[0]=vector[0],out[1]=vector[1],out),create:create$a,cross:cross,distance:distance,divide:(out,a,b)=>(out[0]=a[0]/b[0],out[1]=a[1]/b[1],out),dot:dot$1,equals:equals$7,fromAngleDegrees:(out,degrees)=>fromAngleRadians(out,.017453292519943295*degrees),fromAngleRadians:fromAngleRadians,fromScalar:(out,scalar)=>(out[0]=scalar,out[1]=scalar,out),fromValues:fromValues$2,length:vector=>Math.sqrt(vector[0]*vector[0]+vector[1]*vector[1]),lerp:(out,a,b,t)=>{const ax=a[0],ay=a[1];return out[0]=ax+t*(b[0]-ax),out[1]=ay+t*(b[1]-ay),out},max:max,min:min,multiply:(out,a,b)=>(out[0]=a[0]*b[0],out[1]=a[1]*b[1],out),negate:negate,normal:normal,normalize:normalize,rotate:rotate$1,scale:scale$1,snap:(out,vector,epsilon)=>(out[0]=Math.round(vector[0]/epsilon)*epsilon+0,out[1]=Math.round(vector[1]/epsilon)*epsilon+0,out),squaredDistance:(a,b)=>{const x=b[0]-a[0],y=b[1]-a[1];return x*x+y*y},squaredLength:vector=>{const x=vector[0],y=vector[1];return x*x+y*y},subtract:subtract$1,toString:toString$a,transform:transform$c});const fromSides=sides=>{const pointMap=(sides=>{const pointMap=new Map,edges=(sides=>{const unique=new Map,getUniquePoint=point=>{const key=point.toString();return unique.has(key)?unique.get(key):(unique.set(key,point),point)};return sides.map(side=>side.map(getUniquePoint))})(sides);return edges.forEach(edge=>{pointMap.has(edge[0])?pointMap.get(edge[0]).push(edge):pointMap.set(edge[0],[edge])}),pointMap})(sides),outlines=[];for(;;){let startSide;for(const[point,edges]of pointMap){if(startSide=edges.shift(),startSide)break;pointMap.delete(point)}if(void 0===startSide)break;const connectedPoints=[],startPoint=startSide[0];for(;;){connectedPoints.push(startSide[0]);const nextPoint=startSide[1];if(nextPoint===startPoint)break;const nextPossibleSides=pointMap.get(nextPoint);if(!nextPossibleSides)throw new Error(`geometry is not closed at point ${nextPoint}`);const nextSide=popNextSide(startSide,nextPossibleSides);0===nextPossibleSides.length&&pointMap.delete(nextPoint),startSide=nextSide}connectedPoints.length>0&&connectedPoints.push(connectedPoints.shift()),outlines.push(connectedPoints)}return pointMap.clear(),create$b(outlines)},popNextSide=(startSide,nextSides)=>{if(1===nextSides.length)return nextSides.pop();const v0=[0,0],startAngle=angleDegrees(subtract$1(v0,startSide[1],startSide[0]));let bestAngle,bestIndex;nextSides.forEach((nextSide,index)=>{let angle=angleDegrees(subtract$1(v0,nextSide[1],nextSide[0]))-startAngle;angle<-180&&(angle+=360),angle>=180&&(angle-=360),(void 0===bestIndex||angle>bestAngle)&&(bestIndex=index,bestAngle=angle)});const nextSide=nextSides[bestIndex];return nextSides.splice(bestIndex,1),nextSide},isA$6=object=>!!(object&&"object"==typeof object&&"outlines"in object&&"transforms"in object&&Array.isArray(object.outlines)&&"length"in object.transforms),toOutlines=geometry=>(geometry=>(isIdentity(geometry.transforms)||(geometry.outlines=geometry.outlines.map(outline=>outline.map(point=>transform$c([0,0],point,geometry.transforms))),geometry.transforms=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]),geometry))(geometry).outlines,reverse$6=geometry=>{const outlines=toOutlines(geometry).map(outline=>outline.slice().reverse()),reversed=create$b(outlines);return geometry.color&&(reversed.color=geometry.color),reversed},toPoints$2=geometry=>{const points=[];return toOutlines(geometry).forEach(outline=>{outline.forEach(point=>{points.push(point)})}),points},toSides=geometry=>{const sides=[];return toOutlines(geometry).forEach(outline=>{outline.forEach((point,i)=>{const j=(i+1)%outline.length;sides.push([point,outline[j]])})}),sides},transform$b=(matrix,geometry)=>{const transforms=multiply$1([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],matrix,geometry.transforms),transformed=Object.assign({},geometry,{transforms:transforms});return matrix[0]*matrix[5]-matrix[4]*matrix[1]<0?reverse$6(transformed):transformed},intersect$1=(p1,p2,p3,p4,endpointTouch=!0)=>{if(p1[0]===p2[0]&&p1[1]===p2[1]||p3[0]===p4[0]&&p3[1]===p4[1])return;const denominator=(p4[1]-p3[1])*(p2[0]-p1[0])-(p4[0]-p3[0])*(p2[1]-p1[1]);if(Math.abs(denominator)<Number.MIN_VALUE)return;const ua=((p4[0]-p3[0])*(p1[1]-p3[1])-(p4[1]-p3[1])*(p1[0]-p3[0]))/denominator,ub=((p2[0]-p1[0])*(p1[1]-p3[1])-(p2[1]-p1[1])*(p1[0]-p3[0]))/denominator;return ua<0||ua>1||ub<0||ub>1||!(endpointTouch||0!==ua&&1!==ua&&0!==ub&&1!==ub)?void 0:[p1[0]+ua*(p2[0]-p1[0]),p1[1]+ua*(p2[1]-p1[1])]};var geom2=Object.freeze({__proto__:null,clone:geometry=>Object.assign({},geometry),create:create$b,fromPoints:points=>{if(!Array.isArray(points))throw new Error("the given points must be an array");const length=points.length;if(length<3)throw new Error("the given points must define a closed geometry with three or more points");return equals$7(points[0],points[length-1])&&(points=points.slice(0,-1)),create$b([points])},fromSides:fromSides,isA:isA$6,reverse:reverse$6,toOutlines:toOutlines,toPoints:toPoints$2,toSides:toSides,toString:geometry=>{const outlines=toOutlines(geometry);let result="geom2 ("+outlines.length+" outlines):\n[\n";return outlines.forEach(outline=>{result+=" ["+outline.map(toString$a).join()+"]\n"}),result+="]\n",result},transform:transform$b,validate:object=>{if(!isA$6(object))throw new Error("invalid geom2 structure");if(object.outlines.forEach((outline,i)=>{if(outline.length<3)throw new Error(`geom2 outline ${i} must contain at least 3 points`);for(let i=0;i<outline.length;i++){const j=(i+1)%outline.length;if(equals$7(outline[i],outline[j]))throw new Error(`geom2 outline ${i} has duplicate point ${outline[i]}`)}}),toOutlines(object).forEach((outline,i)=>{for(let a1=0;a1<outline.length;a1++){const a2=(a1+1)%outline.length;for(let b1=0;b1<outline.length;b1++){const b2=(b1+1)%outline.length;if(a1!==b1){const int=intersect$1(outline[a1],outline[a2],outline[b1],outline[b2],!1);if(int)throw new Error(`geom2 outline ${i} self intersection at ${int}`)}}}}),!object.transforms.every(Number.isFinite))throw new Error(`geom2 invalid transforms ${object.transforms}`)}});const create$9=(polygons=[])=>({polygons:polygons,transforms:[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]}),create$8=(vertices=[])=>({vertices:vertices}),fromVerticesAndPlane=(vertices,plane)=>{const poly=create$8(vertices);return poly.plane=plane,poly},create$7=()=>[0,0,0,0],flip=(out,plane)=>(out[0]=-plane[0],out[1]=-plane[1],out[2]=-plane[2],out[3]=-plane[3],out),fromNormalAndPoint=(out,normal,point)=>(normalize$1(out,normal),out[3]=dot$2(point,out),out),ba=[0,0,0],ca=[0,0,0],fromPoints$3=(out,...vertices)=>{const len=vertices.length,vertexNormal=index=>{const a=vertices[index],b=vertices[(index+1)%len],c=vertices[(index+2)%len];return subtract$3(ba,b,a),subtract$3(ca,c,a),cross$1(ba,ba,ca),normalize$1(ba,ba),ba};return 3===len?copy$4(out,vertexNormal(0)):(out[0]=0,out[1]=0,out[2]=0,vertices.forEach((v,i)=>{add$1(out,out,vertexNormal(i))}),normalize$1(out,out)),out[3]=dot$2(out,vertices[0]),out},projectionOfPoint=(plane,point)=>{const a=point[0]*plane[0]+point[1]*plane[1]+point[2]*plane[2]-plane[3],x=point[0]-a*plane[0],y=point[1]-a*plane[1],z=point[2]-a*plane[2];return fromValues$3(x,y,z)},invert$1=polygon=>{const vertices=polygon.vertices.slice().reverse(),inverted=create$8(vertices);return polygon.plane&&(inverted.plane=flip([0,0,0,0],polygon.plane)),inverted},isA$5=object=>!!(object&&"object"==typeof object&&"vertices"in object&&Array.isArray(object.vertices)),isConvex$2=polygon=>areVerticesConvex(polygon.vertices),areVerticesConvex=vertices=>{const numVertices=vertices.length;if(numVertices>2){const normal=fromPoints$3([0,0,0,0],...vertices);let prevPrevPos=vertices[numVertices-2],prevPos=vertices[numVertices-1];for(let i=0;i<numVertices;i++){const pos=vertices[i];if(!isConvexVertex(prevPrevPos,prevPos,pos,normal))return!1;prevPrevPos=prevPos,prevPos=pos}}return!0},isConvexVertex=(prevVertex,vertex,nextVertex,normal)=>{const crossProduct=cross$1([0,0,0],subtract$3([0,0,0],vertex,prevVertex),subtract$3([0,0,0],nextVertex,vertex));return dot$2(crossProduct,normal)>=0},plane=polygon=>(polygon.plane||(polygon.plane=fromPoints$3([0,0,0,0],...polygon.vertices)),polygon.plane),measureArea$2=polygon=>{const n=polygon.vertices.length;if(n<3)return 0;const vertices=polygon.vertices,normal=plane(polygon),ax=Math.abs(normal[0]),ay=Math.abs(normal[1]),az=Math.abs(normal[2]);if(ax+ay+az===0)return 0;let coord=3;ax>ay&&ax>az?coord=1:ay>az&&(coord=2);let area=0,h=0,i=1,j=2;switch(coord){case 1:for(i=1;i<n;i++)h=i-1,j=(i+1)%n,area+=vertices[i][1]*(vertices[j][2]-vertices[h][2]);area+=vertices[0][1]*(vertices[1][2]-vertices[n-1][2]),area/=2*normal[0];break;case 2:for(i=1;i<n;i++)h=i-1,j=(i+1)%n,area+=vertices[i][2]*(vertices[j][0]-vertices[h][0]);area+=vertices[0][2]*(vertices[1][0]-vertices[n-1][0]),area/=2*normal[1];break;default:for(i=1;i<n;i++)h=i-1,j=(i+1)%n,area+=vertices[i][0]*(vertices[j][1]-vertices[h][1]);area+=vertices[0][0]*(vertices[1][1]-vertices[n-1][1]),area/=2*normal[2]}return area},cache$4=new WeakMap,measureBoundingSphere$1=(out,polygon)=>{const vertices=polygon.vertices;if(0===vertices.length)return out[0]=0,out[1]=0,out[2]=0,out[3]=0,out;let minx=vertices[0],miny=minx,minz=minx,maxx=minx,maxy=minx,maxz=minx;for(let i=0;i<vertices.length;i++){const v=vertices[i];minx[0]>v[0]&&(minx=v),miny[1]>v[1]&&(miny=v),minz[2]>v[2]&&(minz=v),maxx[0]<v[0]&&(maxx=v),maxy[1]<v[1]&&(maxy=v),maxz[2]<v[2]&&(maxz=v)}out[0]=.5*(minx[0]+maxx[0]),out[1]=.5*(miny[1]+maxy[1]),out[2]=.5*(minz[2]+maxz[2]);const x=out[0]-maxx[0],y=out[1]-maxy[1],z=out[2]-maxz[2];return out[3]=Math.sqrt(x*x+y*y+z*z),out},measureBoundingSphereAndCache=polygon=>{const boundingSphere=cache$4.get(polygon);if(boundingSphere)return boundingSphere;const out=[0,0,0,0];return measureBoundingSphere$1(out,polygon),cache$4.set(polygon,out),out},toVertices$3=polygon=>polygon.vertices,toString$7=polygon=>`poly3: [${polygon.vertices.map(toString$c).join(", ")}]`,transform$9=(matrix,polygon)=>{const vertices=polygon.vertices.map(vertex=>transform$d([0,0,0],vertex,matrix));return isMirroring(matrix)&&vertices.reverse(),create$8(vertices)},validate$5=object=>{if(!isA$5(object))throw new Error("invalid poly3 structure");if(object.vertices.length<3)throw new Error(`poly3 not enough vertices ${object.vertices.length}`);if(measureArea$2(object)<=0)throw new Error("poly3 area must be greater than zero");for(let i=0;i<object.vertices.length;i++)if(equals$8(object.vertices[i],object.vertices[(i+1)%object.vertices.length]))throw new Error(`poly3 has duplicate vertex ${object.vertices[i]}`);if(!isConvex$2(object))throw new Error("poly3 must be convex");if(object.vertices.forEach(vertex=>{if(!vertex.every(Number.isFinite))throw new Error(`poly3 invalid vertex ${vertex}`)}),object.vertices.length>3){const normal=plane(object);object.vertices.forEach(vertex=>{const dist=Math.abs(((plane,point)=>dot$2(plane,point)-plane[3])(normal,vertex));if(dist>1e-13)throw new Error(`poly3 must be coplanar: vertex ${vertex} distance ${dist}`)})}};var poly3=Object.freeze({__proto__:null,clone:(...params)=>{let out,poly3;return 1===params.length?(out=create$8(),poly3=params[0]):(out=params[0],poly3=params[1]),out.vertices=poly3.vertices.map(vec=>clone$a(vec)),out},create:create$8,fromVerticesAndPlane:fromVerticesAndPlane,invert:invert$1,isA:isA$5,isConvex:isConvex$2,measureArea:measureArea$2,measureBoundingBox:polygon=>{const vertices=polygon.vertices,numVertices=vertices.length,min=0===numVertices?[0,0,0]:clone$a(vertices[0]),max=clone$a(min);for(let i=1;i<numVertices;i++)min$1(min,min,vertices[i]),max$1(max,max,vertices[i]);return[min,max]},measureBoundingSphere:measureBoundingSphere$1,measureBoundingSphereAndCache:measureBoundingSphereAndCache,measureSignedVolume:polygon=>{let signedVolume=0;const vertices=polygon.vertices,cross=[0,0,0];for(let i=0;i<vertices.length-2;i++)cross$1(cross,vertices[i+1],vertices[i+2]),signedVolume+=dot$2(vertices[0],cross);return signedVolume/=6,signedVolume},plane:plane,toString:toString$7,toVertices:toVertices$3,transform:transform$9,validate:validate$5});const pointLineDistance=(point,a,b)=>Math.sqrt(((p,a,b)=>{const ab=[],ap=[];subtract$3(ab,b,a),subtract$3(ap,p,a);const area=squaredLength$1(cross$1([],ap,ab)),s=squaredLength$1(ab);if(0===s)throw Error("a and b are the same point");return area/s})(point,a,b));class VertexList{constructor(){this.head=null,this.tail=null}clear(){this.head=this.tail=null}insertBefore(target,node){node.prev=target.prev,node.next=target,node.prev?node.prev.next=node:this.head=node,target.prev=node}insertAfter(target,node){node.prev=target,node.next=target.next,node.next?node.next.prev=node:this.tail=node,target.next=node}add(node){this.head?this.tail.next=node:this.head=node,node.prev=this.tail,node.next=null,this.tail=node}addAll(node){for(this.head?this.tail.next=node:this.head=node,node.prev=this.tail;node.next;)node=node.next;this.tail=node}remove(node){node.prev?node.prev.next=node.next:this.head=node.next,node.next?node.next.prev=node.prev:this.tail=node.prev}removeChain(a,b){a.prev?a.prev.next=b.next:this.head=b.next,b.next?b.next.prev=a.prev:this.tail=a.prev}first(){return this.head}isEmpty(){return!this.head}}class Vertex{constructor(point,index){this.point=point,this.index=index,this.next=null,this.prev=null,this.face=null}}class HalfEdge{constructor(vertex,face){this.vertex=vertex,this.face=face,this.next=null,this.prev=null,this.opposite=null}head(){return this.vertex}tail(){return this.prev?this.prev.vertex:null}length(){return this.tail()?distance$1(this.tail().point,this.head().point):-1}lengthSquared(){return this.tail()?squaredDistance$1(this.tail().point,this.head().point):-1}setOpposite(edge){this.opposite=edge,edge.opposite=this}}class Face{constructor(){this.normal=[],this.centroid=[],this.offset=0,this.outside=null,this.mark=0,this.edge=null,this.nVertices=0}getEdge(i){if("number"!=typeof i)throw Error("requires a number");let it=this.edge;for(;i>0;)it=it.next,i-=1;for(;i<0;)it=it.prev,i+=1;return it}computeNormal(){const e0=this.edge,e1=e0.next;let e2=e1.next;const v2=subtract$3([],e1.head().point,e0.head().point),t=[],v1=[];for(this.nVertices=2,this.normal=[0,0,0];e2!==e0;)copy$4(v1,v2),subtract$3(v2,e2.head().point,e0.head().point),add$1(this.normal,this.normal,cross$1(t,v1,v2)),e2=e2.next,this.nVertices+=1;this.area=length$2(this.normal),this.normal=scale$3(this.normal,this.normal,1/this.area)}computeNormalMinArea(minArea){if(this.computeNormal(),this.area<minArea){let maxEdge,maxSquaredLength=0,edge=this.edge;do{const lengthSquared=edge.lengthSquared();lengthSquared>maxSquaredLength&&(maxEdge=edge,maxSquaredLength=lengthSquared),edge=edge.next}while(edge!==this.edge);const p1=maxEdge.tail().point,p2=maxEdge.head().point,maxVector=subtract$3([],p2,p1),maxLength=Math.sqrt(maxSquaredLength);scale$3(maxVector,maxVector,1/maxLength);const maxProjection=dot$2(this.normal,maxVector);scale$3(maxVector,maxVector,-maxProjection),add$1(this.normal,this.normal,maxVector),normalize$1(this.normal,this.normal)}}computeCentroid(){this.centroid=[0,0,0];let edge=this.edge;do{add$1(this.centroid,this.centroid,edge.head().point),edge=edge.next}while(edge!==this.edge);scale$3(this.centroid,this.centroid,1/this.nVertices)}computeNormalAndCentroid(minArea){void 0!==minArea?this.computeNormalMinArea(minArea):this.computeNormal(),this.computeCentroid(),this.offset=dot$2(this.normal,this.centroid)}distanceToPlane(point){return dot$2(this.normal,point)-this.offset}connectHalfEdges(prev,next){let discardedFace;if(prev.opposite.face===next.opposite.face){const oppositeFace=next.opposite.face;let oppositeEdge;prev===this.edge&&(this.edge=next),3===oppositeFace.nVertices?(oppositeEdge=next.opposite.prev.opposite,oppositeFace.mark=2,discardedFace=oppositeFace):(oppositeEdge=next.opposite.next,oppositeFace.edge===oppositeEdge.prev&&(oppositeFace.edge=oppositeEdge),oppositeEdge.prev=oppositeEdge.prev.prev,oppositeEdge.prev.next=oppositeEdge),next.prev=prev.prev,next.prev.next=next,next.setOpposite(oppositeEdge),oppositeFace.computeNormalAndCentroid()}else prev.next=next,next.prev=prev;return discardedFace}mergeAdjacentFaces(adjacentEdge,discardedFaces){const oppositeEdge=adjacentEdge.opposite,oppositeFace=oppositeEdge.face;discardedFaces.push(oppositeFace),oppositeFace.mark=2;let edge,discardedFace,adjacentEdgePrev=adjacentEdge.prev,adjacentEdgeNext=adjacentEdge.next,oppositeEdgePrev=oppositeEdge.prev,oppositeEdgeNext=oppositeEdge.next;for(;adjacentEdgePrev.opposite.face===oppositeFace;)adjacentEdgePrev=adjacentEdgePrev.prev,oppositeEdgeNext=oppositeEdgeNext.next;for(;adjacentEdgeNext.opposite.face===oppositeFace;)adjacentEdgeNext=adjacentEdgeNext.next,oppositeEdgePrev=oppositeEdgePrev.prev;for(edge=oppositeEdgeNext;edge!==oppositeEdgePrev.next;edge=edge.next)edge.face=this;return this.edge=adjacentEdgeNext,discardedFace=this.connectHalfEdges(oppositeEdgePrev,adjacentEdgeNext),discardedFace&&discardedFaces.push(discardedFace),discardedFace=this.connectHalfEdges(adjacentEdgePrev,oppositeEdgeNext),discardedFace&&discardedFaces.push(discardedFace),this.computeNormalAndCentroid(),discardedFaces}collectIndices(){const indices=[];let edge=this.edge;do{indices.push(edge.head().index),edge=edge.next}while(edge!==this.edge);return indices}static createTriangle(v0,v1,v2,minArea=0){const face=new Face,e0=new HalfEdge(v0,face),e1=new HalfEdge(v1,face),e2=new HalfEdge(v2,face);return e0.next=e2.prev=e1,e1.next=e0.prev=e2,e2.next=e1.prev=e0,face.edge=e0,face.computeNormalAndCentroid(minArea),face}}class QuickHull{constructor(points){if(!Array.isArray(points))throw TypeError("input is not a valid array");if(points.length<4)throw Error("cannot build a simplex out of <4 points");this.tolerance=-1,this.nFaces=0,this.nPoints=points.length,this.faces=[],this.newFaces=[],this.claimed=new VertexList,this.unclaimed=new VertexList,this.vertices=[];for(let i=0;i<points.length;i+=1)this.vertices.push(new Vertex(points[i],i));this.discardedFaces=[],this.vertexPointIndices=[]}addVertexToFace(vertex,face){vertex.face=face,face.outside?this.claimed.insertBefore(face.outside,vertex):this.claimed.add(vertex),face.outside=vertex}removeVertexFromFace(vertex,face){vertex===face.outside&&(vertex.next&&vertex.next.face===face?face.outside=vertex.next:face.outside=null),this.claimed.remove(vertex)}removeAllVerticesFromFace(face){if(face.outside){let end=face.outside;for(;end.next&&end.next.face===face;)end=end.next;return this.claimed.removeChain(face.outside,end),end.next=null,face.outside}}deleteFaceVertices(face,absorbingFace){const faceVertices=this.removeAllVerticesFromFace(face);if(faceVertices)if(absorbingFace){let nextVertex;for(let vertex=faceVertices;vertex;vertex=nextVertex)nextVertex=vertex.next,absorbingFace.distanceToPlane(vertex.point)>this.tolerance?this.addVertexToFace(vertex,absorbingFace):this.unclaimed.add(vertex)}else this.unclaimed.addAll(faceVertices)}resolveUnclaimedPoints(newFaces){let vertexNext=this.unclaimed.first();for(let vertex=vertexNext;vertex;vertex=vertexNext){vertexNext=vertex.next;let maxFace,maxDistance=this.tolerance;for(let i=0;i<newFaces.length;i+=1){const face=newFaces[i];if(0===face.mark){const dist=face.distanceToPlane(vertex.point);if(dist>maxDistance&&(maxDistance=dist,maxFace=face),maxDistance>1e3*this.tolerance)break}}maxFace&&this.addVertexToFace(vertex,maxFace)}}computeExtremes(){const min=[],max=[],minVertices=[],maxVertices=[];let i,j;for(i=0;i<3;i+=1)minVertices[i]=maxVertices[i]=this.vertices[0];for(i=0;i<3;i+=1)min[i]=max[i]=this.vertices[0].point[i];for(i=1;i<this.vertices.length;i+=1){const vertex=this.vertices[i],point=vertex.point;for(j=0;j<3;j+=1)point[j]<min[j]&&(min[j]=point[j],minVertices[j]=vertex);for(j=0;j<3;j+=1)point[j]>max[j]&&(max[j]=point[j],maxVertices[j]=vertex)}return this.tolerance=3*Number.EPSILON*(Math.max(Math.abs(min[0]),Math.abs(max[0]))+Math.max(Math.abs(min[1]),Math.abs(max[1]))+Math.max(Math.abs(min[2]),Math.abs(max[2]))),[minVertices,maxVertices]}createInitialSimplex(){const vertices=this.vertices,[min,max]=this.computeExtremes();let v2,v3,i,j,maxDistance=0,indexMax=0;for(i=0;i<3;i+=1){const distance=max[i].point[i]-min[i].point[i];distance>maxDistance&&(maxDistance=distance,indexMax=i)}const v0=min[indexMax],v1=max[indexMax];for(maxDistance=0,i=0;i<this.vertices.length;i+=1){const vertex=this.vertices[i];if(vertex!==v0&&vertex!==v1){const distance=pointLineDistance(vertex.point,v0.point,v1.point);distance>maxDistance&&(maxDistance=distance,v2=vertex)}}const normal=fromPoints$3([],v0.point,v1.point,v2.point),distPO=dot$2(v0.point,normal);for(maxDistance=-1,i=0;i<this.vertices.length;i+=1){const vertex=this.vertices[i];if(vertex!==v0&&vertex!==v1&&vertex!==v2){const distance=Math.abs(dot$2(normal,vertex.point)-distPO);distance>maxDistance&&(maxDistance=distance,v3=vertex)}}const faces=[];if(dot$2(v3.point,normal)-distPO<0)for(faces.push(Face.createTriangle(v0,v1,v2),Face.createTriangle(v3,v1,v0),Face.createTriangle(v3,v2,v1),Face.createTriangle(v3,v0,v2)),i=0;i<3;i+=1){const j=(i+1)%3;faces[i+1].getEdge(2).setOpposite(faces[0].getEdge(j)),faces[i+1].getEdge(1).setOpposite(faces[j+1].getEdge(0))}else for(faces.push(Face.createTriangle(v0,v2,v1),Face.createTriangle(v3,v0,v1),Face.createTriangle(v3,v1,v2),Face.createTriangle(v3,v2,v0)),i=0;i<3;i+=1){const j=(i+1)%3;faces[i+1].getEdge(2).setOpposite(faces[0].getEdge((3-i)%3)),faces[i+1].getEdge(0).setOpposite(faces[j+1].getEdge(1))}for(i=0;i<4;i+=1)this.faces.push(faces[i]);for(i=0;i<vertices.length;i+=1){const vertex=vertices[i];if(vertex!==v0&&vertex!==v1&&vertex!==v2&&vertex!==v3){let maxFace;for(maxDistance=this.tolerance,j=0;j<4;j+=1){const distance=faces[j].distanceToPlane(vertex.point);distance>maxDistance&&(maxDistance=distance,maxFace=faces[j])}maxFace&&this.addVertexToFace(vertex,maxFace)}}}reindexFaceAndVertices(){const activeFaces=[];for(let i=0;i<this.faces.length;i+=1){const face=this.faces[i];0===face.mark&&activeFaces.push(face)}this.faces=activeFaces}collectFaces(skipTriangulation){const faceIndices=[];for(let i=0;i<this.faces.length;i+=1){if(0!==this.faces[i].mark)throw Error("attempt to include a destroyed face in the hull");const indices=this.faces[i].collectIndices();if(skipTriangulation)faceIndices.push(indices);else for(let j=0;j<indices.length-2;j+=1)faceIndices.push([indices[0],indices[j+1],indices[j+2]])}return faceIndices}nextVertexToAdd(){if(!this.claimed.isEmpty()){let eyeVertex,vertex,maxDistance=0;const eyeFace=this.claimed.first().face;for(vertex=eyeFace.outside;vertex&&vertex.face===eyeFace;vertex=vertex.next){const distance=eyeFace.distanceToPlane(vertex.point);distance>maxDistance&&(maxDistance=distance,eyeVertex=vertex)}return eyeVertex}}computeHorizon(eyePoint,crossEdge,face,horizon){let edge;this.deleteFaceVertices(face),face.mark=2,edge=crossEdge?crossEdge.next:crossEdge=face.getEdge(0);do{const oppositeEdge=edge.opposite,oppositeFace=oppositeEdge.face;0===oppositeFace.mark&&(oppositeFace.distanceToPlane(eyePoint)>this.tolerance?this.computeHorizon(eyePoint,oppositeEdge,oppositeFace,horizon):horizon.push(edge)),edge=edge.next}while(edge!==crossEdge)}addAdjoiningFace(eyeVertex,horizonEdge){const face=Face.createTriangle(eyeVertex,horizonEdge.tail(),horizonEdge.head());return this.faces.push(face),face.getEdge(-1).setOpposite(horizonEdge.opposite),face.getEdge(0)}addNewFaces(eyeVertex,horizon){let firstSideEdge,previousSideEdge;this.newFaces=[];for(let i=0;i<horizon.length;i+=1){const horizonEdge=horizon[i],sideEdge=this.addAdjoiningFace(eyeVertex,horizonEdge);firstSideEdge?sideEdge.next.setOpposite(previousSideEdge):firstSideEdge=sideEdge,this.newFaces.push(sideEdge.face),previousSideEdge=sideEdge}firstSideEdge.next.setOpposite(previousSideEdge)}oppositeFaceDistance(edge){return edge.face.distanceToPlane(edge.opposite.face.centroid)}doAdjacentMerge(face,mergeType){let edge=face.edge,convex=!0,it=0;do{if(it>=face.nVertices)throw Error("merge recursion limit exceeded");const oppositeFace=edge.opposite.face;let merge=!1;if(2===mergeType?(this.oppositeFaceDistance(edge)>-this.tolerance||this.oppositeFaceDistance(edge.opposite)>-this.tolerance)&&(merge=!0):face.area>oppositeFace.area?this.oppositeFaceDistance(edge)>-this.tolerance?merge=!0:this.oppositeFaceDistance(edge.opposite)>-this.tolerance&&(convex=!1):this.oppositeFaceDistance(edge.opposite)>-this.tolerance?merge=!0:this.oppositeFaceDistance(edge)>-this.tolerance&&(convex=!1),merge){const discardedFaces=face.mergeAdjacentFaces(edge,[]);for(let i=0;i<discardedFaces.length;i+=1)this.deleteFaceVertices(discardedFaces[i],face);return!0}edge=edge.next,it+=1}while(edge!==face.edge);return convex||(face.mark=1),!1}addVertexToHull(eyeVertex){const horizon=[];this.unclaimed.clear(),this.removeVertexFromFace(eyeVertex,eyeVertex.face),this.computeHorizon(eyeVertex.point,null,eyeVertex.face,horizon),this.addNewFaces(eyeVertex,horizon);for(let i=0;i<this.newFaces.length;i+=1){const face=this.newFaces[i];if(0===face.mark)for(;this.doAdjacentMerge(face,1););}for(let i=0;i<this.newFaces.length;i+=1){const face=this.newFaces[i];if(1===face.mark)for(face.mark=0;this.doAdjacentMerge(face,2););}this.resolveUnclaimedPoints(this.newFaces)}build(){let eyeVertex;for(this.createInitialSimplex();eyeVertex=this.nextVertexToAdd();)this.addVertexToHull(eyeVertex);this.reindexFaceAndVertices()}}const toPolygons$1=geometry=>(geometry=>(isIdentity(geometry.transforms)||(geometry.polygons=geometry.polygons.map(polygon=>transform$9(geometry.transforms,polygon)),geometry.transforms=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]),geometry))(geometry).polygons,isA$4=object=>!!(object&&"object"==typeof object&&"polygons"in object&&"transforms"in object&&Array.isArray(object.polygons)&&"length"in object.transforms),transform$8=(matrix,geometry)=>{const transforms=multiply$1([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],matrix,geometry.transforms);return Object.assign({},geometry,{transforms:transforms})};var geom3=Object.freeze({__proto__:null,clone:geometry=>Object.assign({},geometry),create:create$9,fromVertices:listOfLists=>{if(!Array.isArray(listOfLists))throw new Error("the given vertices must be an array");return create$9(listOfLists.map(create$8))},fromVerticesConvex:uniqueVertices=>{if(!Array.isArray(uniqueVertices))throw new Error("the given vertices must be an array");const polygons=((points,options={})=>{const instance=new QuickHull(points);return instance.build(),instance.collectFaces(options.skipTriangulation)})(uniqueVertices,{skipTriangulation:!0}).map(face=>{const vertices=face.map(index=>uniqueVertices[index]);return create$8(vertices)});return create$9(polygons)},invert:geometry=>{const newPolygons=toPolygons$1(geometry).map(polygon=>invert$1(polygon));return create$9(newPolygons)},isA:isA$4,isConvex:geometry=>{if(!isA$4(geometry))throw new Error("isConvex requires a geom3 geometry");const polygons=toPolygons$1(geometry);if(0===polygons.length)return!0;const vertices=[],found=new Set;for(let i=0;i<polygons.length;i++){const verts=polygons[i].vertices;for(let j=0;j<verts.length;j++){const v=verts[j],key=`${v[0]},${v[1]},${v[2]}`;found.has(key)||(found.add(key),vertices.push(v))}}for(let i=0;i<polygons.length;i++){const p=plane(polygons[i]);for(let j=0;j<vertices.length;j++){const v=vertices[j];if(dot$2(p,v)-p[3]>EPS$1)return!1}}return!0},toPolygons:toPolygons$1,toString:geometry=>{const polygons=toPolygons$1(geometry);let result="geom3 ("+polygons.length+" polygons):\n";return polygons.forEach(polygon=>{result+=" "+toString$7(polygon)+"\n"}),result},toVertices:geometry=>toPolygons$1(geometry).map(polygon=>toVertices$3(polygon)),transform:transform$8,validate:object=>{if(!isA$4(object))throw new Error("invalid geom3 structure");if(object.polygons.forEach(validate$5),(object=>{const edgeCount=new Map;object.polygons.forEach(({vertices:vertices})=>{vertices.forEach((v,i)=>{const edge=`${v}/${vertices[(i+1)%vertices.length]}`,count=edgeCount.has(edge)?edgeCount.get(edge):0;edgeCount.set(edge,count+1)})});const nonManifold=[];if(edgeCount.forEach((count,edge)=>{const complementEdge=edge.split("/").reverse().join("/");count!==edgeCount.get(complementEdge)&&nonManifold.push(edge.replace("/"," -> "))}),nonManifold.length>0)throw new Error(`non-manifold edges ${nonManifold.length}\n${nonManifold.join("\n")}`)})(object),!object.transforms.every(Number.isFinite))throw new Error(`geom3 invalid transforms ${object.transforms}`)}});const clone$5=geometry=>Object.assign({},geometry),close$1=geometry=>{if(geometry.isClosed)return geometry;const cloned=clone$5(geometry);if(cloned.isClosed=!0,cloned.points.length>1){const points=cloned.points,p0=points[0];let pn=points[points.length-1];for(;distance(p0,pn)<EPS$1*EPS$1&&(points.pop(),1!==points.length);)pn=points[points.length-1]}return cloned},create$6=(points=[])=>({points:points,isClosed:!1,transforms:[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]}),fromPoints$2=(options,points)=>{let{closed:closed}=Object.assign({},{closed:!1},options),created=create$6();if(created.points=points.map(point=>clone$9(point)),created.points.length>1){const p0=created.points[0],pn=created.points[created.points.length-1];distance(p0,pn)<EPS$1*EPS$1&&(closed=!0)}return!0===closed&&(created=close$1(created)),created},toPoints$1=geometry=>(geometry=>(isIdentity(geometry.transforms)||(geometry.points=geometry.points.map(point=>transform$c([0,0],point,geometry.transforms)),geometry.transforms=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]),geometry))(geometry).points,concat$1=(...paths)=>{let isClosed=!1,newPoints=[];return paths.forEach((path,i)=>{const tmp=toPoints$1(path).slice();if(newPoints.length>0&&tmp.length>0&&equals$7(tmp[0],newPoints[newPoints.length-1])&&tmp.shift(),tmp.length>0&&isClosed)throw new Error(`Cannot concatenate to a closed path; check the ${i}th path`);isClosed=path.isClosed,newPoints=newPoints.concat(tmp)}),fromPoints$2({closed:isClosed},newPoints)},appendPoints=(points,geometry)=>concat$1(geometry,create$6(points)),isA$3=object=>!!(object&&"object"==typeof object&&"points"in object&&"transforms"in object&&"isClosed"in object&&Array.isArray(object.points)&&"length"in object.transforms),transform$7=(matrix,geometry)=>{const transforms=multiply$1([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],matrix,geometry.transforms);return Object.assign({},geometry,{transforms:transforms})};var path2=Object.freeze({__proto__:null,appendArc:(options,geometry)=>{let{endpoint:endpoint,radius:radius,xaxisRotation:xaxisRotation,clockwise:clockwise,large:large,segments:segments}=Object.assign({},{radius:[0,0],xaxisRotation:0,clockwise:!1,large:!1,segments:16},options);if(!Array.isArray(endpoint))throw new Error("endpoint must be an array of X and Y values");if(endpoint.length<2)throw new Error("endpoint must contain X and Y values");if(endpoint=clone$9(endpoint),!Array.isArray(radius))throw new Error("radius must be an array of X and Y values");if(radius.length<2)throw new Error("radius must contain X and Y values");if(segments<4)throw new Error("segments must be four or more");if(geometry.isClosed)throw new Error("the given path cannot be closed");const points=toPoints$1(geometry);if(points.length<1)throw new Error("the given path must contain one or more points (as the starting point for the arc)");let xRadius=radius[0],yRadius=radius[1];const startpoint=points[points.length-1];xRadius=Math.round(1e5*xRadius)/1e5,yRadius=Math.round(1e5*yRadius)/1e5,endpoint=fromValues$2(Math.round(1e5*endpoint[0])/1e5,Math.round(1e5*endpoint[1])/1e5);const sweepFlag=!clockwise;let newPoints=[];if(0===xRadius||0===yRadius)newPoints.push(endpoint);else{xRadius=Math.abs(xRadius),yRadius=Math.abs(yRadius);const phi=xaxisRotation,cosPhi=Math.cos(phi),sinPhi=Math.sin(phi),minusHalfDistance=subtract$1([0,0],startpoint,endpoint);scale$1(minusHalfDistance,minusHalfDistance,.5);const x=Math.round(1e5*(cosPhi*minusHalfDistance[0]+sinPhi*minusHalfDistance[1]))/1e5,y=Math.round(1e5*(-sinPhi*minusHalfDistance[0]+cosPhi*minusHalfDistance[1]))/1e5,startTranslated=fromValues$2(x,y),bigLambda=startTranslated[0]*startTranslated[0]/(xRadius*xRadius)+startTranslated[1]*startTranslated[1]/(yRadius*yRadius);if(bigLambda>1){const sqrtBigLambda=Math.sqrt(bigLambda);xRadius*=sqrtBigLambda,yRadius*=sqrtBigLambda,xRadius=Math.round(1e5*xRadius)/1e5,yRadius=Math.round(1e5*yRadius)/1e5}let multiplier1=Math.sqrt((xRadius*xRadius*yRadius*yRadius-xRadius*xRadius*startTranslated[1]*startTranslated[1]-yRadius*yRadius*startTranslated[0]*startTranslated[0])/(xRadius*xRadius*startTranslated[1]*startTranslated[1]+yRadius*yRadius*startTranslated[0]*startTranslated[0]));sweepFlag===large&&(multiplier1=-multiplier1);const centerTranslated=fromValues$2(xRadius*startTranslated[1]/yRadius,-yRadius*startTranslated[0]/xRadius);scale$1(centerTranslated,centerTranslated,multiplier1);let center=fromValues$2(cosPhi*centerTranslated[0]-sinPhi*centerTranslated[1],sinPhi*centerTranslated[0]+cosPhi*centerTranslated[1]);center=add(center,center,scale$1([0,0],add([0,0],startpoint,endpoint),.5));const vector1=fromValues$2((startTranslated[0]-centerTranslated[0])/xRadius,(startTranslated[1]-centerTranslated[1])/yRadius),vector2=fromValues$2((-startTranslated[0]-centerTranslated[0])/xRadius,(-startTranslated[1]-centerTranslated[1])/yRadius),theta1=angleRadians(vector1);let deltatheta=angleRadians(vector2)-theta1;deltatheta%=TAU,!sweepFlag&&deltatheta>0?deltatheta-=TAU:sweepFlag&&deltatheta<0&&(deltatheta+=TAU);let numSteps=Math.floor(segments*(Math.abs(deltatheta)/TAU));numSteps<1&&(numSteps=1);for(let step=1;step<numSteps;step++){const theta=theta1+step/numSteps*deltatheta,cosTheta=Math.cos(theta),sinTheta=Math.sin(theta),point=fromValues$2(cosPhi*xRadius*cosTheta-sinPhi*yRadius*sinTheta,sinPhi*xRadius*cosTheta+cosPhi*yRadius*sinTheta);add(point,point,center),newPoints.push(point)}numSteps&&newPoints.push(options.endpoint)}return newPoints=points.concat(newPoints),fromPoints$2({},newPoints)},appendBezier:(options,geometry)=>{let{controlPoints:controlPoints,segments:segments}=Object.assign({},{segments:16},options);if(!Array.isArray(controlPoints))throw new Error("controlPoints must be an array of one or more points");if(controlPoints.length<1)throw new Error("controlPoints must be an array of one or more points");if(segments<4)throw new Error("segments must be four or more");if(geometry.isClosed)throw new Error("the given geometry cannot be closed");const points=toPoints$1(geometry);if(points.length<1)throw new Error("the given path must contain one or more points (as the starting point for the bezier curve)");if(controlPoints=controlPoints.slice(),null===controlPoints[0]){if(controlPoints.length<2)throw new Error("a null control point must be passed with one more control points");let lastBezierControlPoint=points[points.length-2];if("lastBezierControlPoint"in geometry&&(lastBezierControlPoint=geometry.lastBezierControlPoint),!Array.isArray(lastBezierControlPoint))throw new Error("the given path must contain TWO or more points if given a null control point");const controlPoint=scale$1([0,0],points[points.length-1],2);subtract$1(controlPoint,controlPoint,lastBezierControlPoint),controlPoints[0]=controlPoint}controlPoints.unshift(points[points.length-1]);const bezierOrder=controlPoints.length-1,factorials=[];let fact=1;for(let i=0;i<=bezierOrder;++i)i>0&&(fact*=i),factorials.push(fact);const binomials=[];for(let i=0;i<=bezierOrder;++i){const binomial=factorials[bezierOrder]/(factorials[i]*factorials[bezierOrder-i]);binomials.push(binomial)}const v0=[0,0],v1=[0,0],v3=[0,0,0],getPointForT=t=>{let tk=1,oneMinusTNMinusK=Math.pow(1-t,bezierOrder);const invOneMinusT=1!==t?1/(1-t):1,point=[0,0];for(let k=0;k<=bezierOrder;++k){k===bezierOrder&&(oneMinusTNMinusK=1);const bernsteinCoefficient=binomials[k]*tk*oneMinusTNMinusK,derivativePoint=scale$1(v0,controlPoints[k],bernsteinCoefficient);add(point,point,derivativePoint),tk*=t,oneMinusTNMinusK*=invOneMinusT}return point},newPoints=[],newPointsT=[],numSteps=bezierOrder+1;for(let i=0;i<numSteps;++i){const t=i/(numSteps-1),point=getPointForT(t);newPoints.push(point),newPointsT.push(t)}let subdivideBase=1;const maxAngle=TAU/segments,maxSinAngle=Math.sin(maxAngle);for(;subdivideBase<newPoints.length-1;){const dir1=subtract$1(v0,newPoints[subdivideBase],newPoints[subdivideBase-1]);normalize(dir1,dir1);const dir2=subtract$1(v1,newPoints[subdivideBase+1],newPoints[subdivideBase]);normalize(dir2,dir2);const sinAngle=cross(v3,dir1,dir2);if(Math.abs(sinAngle[2])>maxSinAngle){const t0=newPointsT[subdivideBase-1],t1=newPointsT[subdivideBase+1],newt0=t0+1*(t1-t0)/3,newt1=t0+2*(t1-t0)/3,point0=getPointForT(newt0),point1=getPointForT(newt1);newPoints.splice(subdivideBase,1,point0,point1),newPointsT.splice(subdivideBase,1,newt0,newt1),subdivideBase--,subdivideBase<1&&(subdivideBase=1)}else++subdivideBase}newPoints.shift();const result=appendPoints(newPoints,geometry);return result.lastBezierControlPoint=controlPoints[controlPoints.length-2],result},appendPoints:appendPoints,clone:clone$5,close:close$1,concat:concat$1,create:create$6,equals:(a,b)=>{if(a.isClosed!==b.isClosed)return!1;if(a.points.length!==b.points.length)return!1;const aPoints=toPoints$1(a),bPoints=toPoints$1(b),length=aPoints.length;let offset=0;do{let unequal=!1;for(let i=0;i<length;i++)if(!equals$7(aPoints[i],bPoints[(i+offset)%length])){unequal=!0;break}if(!1===unequal)return!0;if(!a.isClosed)return!1}while(++offset<length);return!1},fromPoints:fromPoints$2,isA:isA$3,reverse:geometry=>{const cloned=clone$5(geometry);return cloned.points=geometry.points.slice().reverse(),cloned},toPoints:toPoints$1,toString:geometry=>{const points=toPoints$1(geometry);let result="path ("+points.length+" points, "+geometry.isClosed+"):\n[\n";return points.forEach(point=>{result+=" "+toString$a(point)+",\n"}),result+="]\n",result},transform:transform$7,validate:object=>{if(!isA$3(object))throw new Error("invalid path2 structure");if(object.points.length>1)for(let i=0;i<object.points.length;i++)if(equals$7(object.points[i],object.points[(i+1)%object.points.length]))throw new Error(`path2 has duplicate point ${object.points[i]}`);if(object.points.forEach(point=>{if(!point.every(Number.isFinite))throw new Error(`path2 invalid point ${point}`)}),!object.transforms.every(Number.isFinite))throw new Error(`path2 invalid transforms ${object.transforms}`)}});const isA$2=object=>!!(object&&"object"==typeof object&&"vertices"in object&&"transforms"in object&&"isClosed"in object&&Array.isArray(object.vertices)&&"length"in object.transforms),create$4=(contours=[])=>({contours:contours}),fromOutlines$1=outlines=>{const contours=outlines.map(outline=>outline.map(point=>fromVec2([0,0,0],point)));return create$4(contours)},isA$1=object=>!!(object&&"object"==typeof object&&"contours"in object&&Array.isArray(object.contours)),reverse$3=slice=>{const contours=slice.contours.map(contour=>contour.slice().reverse());return create$4(contours)},toEdges=slice=>{const edges=[];return slice.contours.forEach(contour=>{contour.forEach((vertex,i)=>{const next=contour[(i+1)%contour.length];edges.push([vertex,next])})}),edges};let Node$2=class{constructor(i,x,y){this.i=i,this.x=x,this.y=y,this.prev=null,this.next=null,this.z=null,this.prevZ=null,this.nextZ=null,this.steiner=!1}};const insertNode=(i,x,y,last)=>{const p=new Node$2(i,x,y);return last?(p.next=last.next,p.prev=last,last.next.prev=p,last.next=p):(p.prev=p,p.next=p),p},removeNode=p=>{p.next.prev=p.prev,p.prev.next=p.next,p.prevZ&&(p.prevZ.nextZ=p.nextZ),p.nextZ&&(p.nextZ.prevZ=p.prevZ)},pointInTriangle=(ax,ay,bx,by,cx,cy,px,py)=>(cx-px)*(ay-py)-(ax-px)*(cy-py)>=0&&(ax-px)*(by-py)-(bx-px)*(ay-py)>=0&&(bx-px)*(cy-py)-(cx-px)*(by-py)>=0,area$1=(p,q,r)=>(q.y-p.y)*(r.x-q.x)-(q.x-p.x)*(r.y-q.y),linkedPolygon=(data,start,end,dim,clockwise)=>{let last;if(clockwise===signedArea$1(data,start,end,dim)>0)for(let i=start;i<end;i+=dim)last=insertNode(i,data[i],data[i+1],last);else for(let i=end-dim;i>=start;i-=dim)last=insertNode(i,data[i],data[i+1],last);return last&&equals$2(last,last.next)&&(removeNode(last),last=last.next),last},filterPoints=(start,end)=>{if(!start)return start;end||(end=start);let again,p=start;do{if(again=!1,p.steiner||!equals$2(p,p.next)&&0!==area$1(p.prev,p,p.next))p=p.next;else{if(removeNode(p),p=end=p.prev,p===p.next)break;again=!0}}while(again||p!==end);return end},cureLocalIntersections=(start,triangles,dim)=>{let p=start;do{const a=p.prev,b=p.next.next;!equals$2(a,b)&&intersects(a,p,p.next,b)&&locallyInside(a,b)&&locallyInside(b,a)&&(triangles.push(a.i/dim),triangles.push(p.i/dim),triangles.push(b.i/dim),removeNode(p),removeNode(p.next),p=start=b),p=p.next}while(p!==start);return filterPoints(p)},locallyInside=(a,b)=>area$1(a.prev,a,a.next)<0?area$1(a,b,a.next)>=0&&area$1(a,a.prev,b)>=0:area$1(a,b,a.prev)<0||area$1(a,a.next,b)<0,splitPolygon=(a,b)=>{const a2=new Node$2(a.i,a.x,a.y),b2=new Node$2(b.i,b.x,b.y),an=a.next,bp=b.prev;return a.next=b,b.prev=a,a2.next=an,an.prev=a2,b2.next=a2,a2.prev=b2,bp.next=b2,b2.prev=bp,b2},isValidDiagonal=(a,b)=>a.next.i!==b.i&&a.prev.i!==b.i&&!((a,b)=>{let p=a;do{if(p.i!==a.i&&p.next.i!==a.i&&p.i!==b.i&&p.next.i!==b.i&&intersects(p,p.next,a,b))return!0;p=p.next}while(p!==a);return!1})(a,b)&&(locallyInside(a,b)&&locallyInside(b,a)&&((a,b)=>{let p=a,inside=!1;const px=(a.x+b.x)/2,py=(a.y+b.y)/2;do{p.y>py!=p.next.y>py&&p.next.y!==p.y&&px<(p.next.x-p.x)*(py-p.y)/(p.next.y-p.y)+p.x&&(inside=!inside),p=p.next}while(p!==a);return inside})(a,b)&&(area$1(a.prev,a,b.prev)||area$1(a,b.prev,b))||equals$2(a,b)&&area$1(a.prev,a,a.next)>0&&area$1(b.prev,b,b.next)>0),intersects=(p1,q1,p2,q2)=>{const o1=Math.sign(area$1(p1,q1,p2)),o2=Math.sign(area$1(p1,q1,q2)),o3=Math.sign(area$1(p2,q2,p1)),o4=Math.sign(area$1(p2,q2,q1));return o1!==o2&&o3!==o4||!(0!==o1||!onSegment(p1,p2,q1))||!(0!==o2||!onSegment(p1,q2,q1))||!(0!==o3||!onSegment(p2,p1,q2))||!(0!==o4||!onSegment(p2,q1,q2))},onSegment=(p,q,r)=>q.x<=Math.max(p.x,r.x)&&q.x>=Math.min(p.x,r.x)&&q.y<=Math.max(p.y,r.y)&&q.y>=Math.min(p.y,r.y),signedArea$1=(data,start,end,dim)=>{let sum=0;for(let i=start,j=end-dim;i<end;i+=dim)sum+=(data[j]-data[i])*(data[i+1]+data[j+1]),j=i;return sum},equals$2=(p1,p2)=>p1.x===p2.x&&p1.y===p2.y,eliminateHole=(hole,outerNode)=>{const bridge=findHoleBridge(hole,outerNode);if(!bridge)return outerNode;const bridgeReverse=splitPolygon(bridge,hole),filteredBridge=filterPoints(bridge,bridge.next);return filterPoints(bridgeReverse,bridgeReverse.next),outerNode===bridge?filteredBridge:outerNode},findHoleBridge=(hole,outerNode)=>{let p=outerNode;const hx=hole.x,hy=hole.y;let m,qx=-1/0;do{if(hy<=p.y&&hy>=p.next.y&&p.next.y!==p.y){const x=p.x+(hy-p.y)*(p.next.x-p.x)/(p.next.y-p.y);if(x<=hx&&x>qx){if(qx=x,x===hx){if(hy===p.y)return p;if(hy===p.next.y)return p.next}m=p.x<p.next.x?p:p.next}}p=p.next}while(p!==outerNode);if(!m)return null;if(hx===qx)return m;const stop=m,mx=m.x,my=m.y;let tanMin=1/0;p=m;do{if(hx>=p.x&&p.x>=mx&&hx!==p.x&&pointInTriangle(hy<my?hx:qx,hy,mx,my,hy<my?qx:hx,hy,p.x,p.y)){const tan=Math.abs(hy-p.y)/(hx-p.x);locallyInside(p,hole)&&(tan<tanMin||tan===tanMin&&(p.x>m.x||p.x===m.x&§orContainsSector(m,p)))&&(m=p,tanMin=tan)}p=p.next}while(p!==stop);return m},sectorContainsSector=(m,p)=>area$1(m.prev,m,p.prev)<0&&area$1(p.next,m,m.next)<0,getLeftmost=start=>{let p=start,leftmost=start;do{(p.x<leftmost.x||p.x===leftmost.x&&p.y<leftmost.y)&&(leftmost=p),p=p.next}while(p!==start);return leftmost},earcutLinked=(ear,triangles,dim,minX,minY,invSize,pass)=>{if(!ear)return;!pass&&invSize&&indexCurve(ear,minX,minY,invSize);let prev,next,stop=ear;for(;ear.prev!==ear.next;)if(prev=ear.prev,next=ear.next,invSize?isEarHashed(ear,minX,minY,invSize):isEar(ear))triangles.push(prev.i/dim),triangles.push(ear.i/dim),triangles.push(next.i/dim),removeNode(ear),ear=next.next,stop=next.next;else if((ear=next)===stop){pass?1===pass?(ear=cureLocalIntersections(filterPoints(ear),triangles,dim),earcutLinked(ear,triangles,dim,minX,minY,invSize,2)):2===pass&&splitEarcut(ear,triangles,dim,minX,minY,invSize):earcutLinked(filterPoints(ear),triangles,dim,minX,minY,invSize,1);break}},isEar=ear=>{const a=ear.prev,b=ear,c=ear.next;if(area$1(a,b,c)>=0)return!1;let p=ear.next.next;for(;p!==ear.prev;){if(pointInTriangle(a.x,a.y,b.x,b.y,c.x,c.y,p.x,p.y)&&area$1(p.prev,p,p.next)>=0)return!1;p=p.next}return!0},isEarHashed=(ear,minX,minY,invSize)=>{const a=ear.prev,b=ear,c=ear.next;if(area$1(a,b,c)>=0)return!1;const minTX=a.x<b.x?a.x<c.x?a.x:c.x:b.x<c.x?b.x:c.x,minTY=a.y<b.y?a.y<c.y?a.y:c.y:b.y<c.y?b.y:c.y,maxTX=a.x>b.x?a.x>c.x?a.x:c.x:b.x>c.x?b.x:c.x,maxTY=a.y>b.y?a.y>c.y?a.y:c.y:b.y>c.y?b.y:c.y,minZ=zOrder(minTX,minTY,minX,minY,invSize),maxZ=zOrder(maxTX,maxTY,minX,minY,invSize);let p=ear.prevZ,n=ear.nextZ;for(;p&&p.z>=minZ&&n&&n.z<=maxZ;){if(p!==ear.prev&&p!==ear.next&&pointInTriangle(a.x,a.y,b.x,b.y,c.x,c.y,p.x,p.y)&&area$1(p.prev,p,p.next)>=0)return!1;if(p=p.prevZ,n!==ear.prev&&n!==ear.next&&pointInTriangle(a.x,a.y,b.x,b.y,c.x,c.y,n.x,n.y)&&area$1(n.prev,n,n.next)>=0)return!1;n=n.nextZ}for(;p&&p.z>=minZ;){if(p!==ear.prev&&p!==ear.next&&pointInTriangle(a.x,a.y,b.x,b.y,c.x,c.y,p.x,p.y)&&area$1(p.prev,p,p.next)>=0)return!1;p=p.prevZ}for(;n&&n.z<=maxZ;){if(n!==ear.prev&&n!==ear.next&&pointInTriangle(a.x,a.y,b.x,b.y,c.x,c.y,n.x,n.y)&&area$1(n.prev,n,n.next)>=0)return!1;n=n.nextZ}return!0},splitEarcut=(start,triangles,dim,minX,minY,invSize)=>{let a=start;do{let b=a.next.next;for(;b!==a.prev;){if(a.i!==b.i&&isValidDiagonal(a,b)){let c=splitPolygon(a,b);return a=filterPoints(a,a.next),c=filterPoints(c,c.next),earcutLinked(a,triangles,dim,minX,minY,invSize),void earcutLinked(c,triangles,dim,minX,minY,invSize)}b=b.next}a=a.next}while(a!==start)},indexCurve=(start,minX,minY,invSize)=>{let p=start;do{null===p.z&&(p.z=zOrder(p.x,p.y,minX,minY,invSize)),p.prevZ=p.prev,p.nextZ=p.next,p=p.next}while(p!==start);p.prevZ.nextZ=null,p.prevZ=null,((list,fn)=>{let i,p,q,e,numMerges,inSize=1;do{p=list,list=null;let tail=null;for(numMerges=0;p;){numMerges++,q=p;let pSize=0;for(i=0;i<inSize&&(pSize++,q=q.nextZ,q);i++);let qSize=inSize;for(;pSize>0||qSize>0&&q;)0!==pSize&&(0===qSize||!q||fn(p)<=fn(q))?(e=p,p=p.nextZ,pSize--):(e=q,q=q.nextZ,qSize--),tail?tail.nextZ=e:list=e,e.prevZ=tail,tail=e;p=q}tail.nextZ=null,inSize*=2}while(numMerges>1)})(p,p=>p.z)},zOrder=(x,y,minX,minY,invSize)=>(x=1431655765&((x=858993459&((x=252645135&((x=16711935&((x=32767*(x-minX)*invSize)|x<<8))|x<<4))|x<<2))|x<<1))|(y=1431655765&((y=858993459&((y=252645135&((y=16711935&((y=32767*(y-minY)*invSize)|y<<8))|y<<4))|y<<2))|y<<1))<<1,area=points=>{let area=0;for(let i=0;i<points.length;i++){const j=(i+1)%points.length;area+=points[i][0]*points[j][1],area-=points[j][0]*points[i][1]}return area/2},create$3=(points=[])=>({points:points}),arePointsInside=(points,polygon)=>0===points.length||polygon.points.length<3?0:((polygon=>area(polygon.points))(polygon)<0&&(polygon=(polygon=>{const points=polygon.points.slice().reverse();return create$3(points)})(polygon)),points.reduce((acc,point)=>acc+isPointInside(point,polygon.points),0)===points.length?1:0),isPointInside=(point,polygon)=>{const numPoints=polygon.length,tx=point[0],ty=point[1];let vtx0=polygon[numPoints-1],vtx1=polygon[0],yFlag0=vtx0[1]>ty,insideFlag=0,i=0;for(let j=numPoints+1;--j;){const yFlag1=vtx1[1]>ty;if(yFlag0!==yFlag1){const xFlag0=vtx0[0]>tx,xFlag1=vtx1[0]>tx;(xFlag0&&xFlag1||vtx1[0]-(vtx1[1]-ty)*(vtx0[0]-vtx1[0])/(vtx0[1]-vtx1[1])>=tx)&&(insideFlag=!insideFlag)}yFlag0=yFlag1,vtx0=vtx1,vtx1=polygon[++i]}return insideFlag};class PolygonHierarchy{constructor(slice){this.plane=(slice=>{if(slice.contours.length<1)throw new Error("slices must have at least one contour to calculate a plane");const middle=[0,0,0];let n=0;slice.contours.forEach(contour=>{contour.forEach(vertex=>{add$1(middle,middle,vertex),n++})}),scale$3(middle,middle,1/n);let farthestBefore,farthestVertex,farthestAfter,farthestContour=[],distance=0;slice.contours.forEach(contour=>{let prev=contour[contour.length-1];contour.forEach(vertex=>{if(!equals$8(prev,vertex)){const d=squaredDistance$1(middle,vertex);d>distance&&(farthestContour=contour,farthestBefore=prev,farthestVertex=vertex,distance=d)}prev=vertex})});let prev=farthestContour[farthestContour.length-1];for(let i=0;i<farthestContour.length;i++){const vertex=farthestContour[i];if(!equals$8(prev,vertex)&&equals$8(prev,farthestVertex)){farthestAfter=vertex;break}prev=vertex}return fromPoints$3([0,0,0,0],farthestBefore,farthestVertex,farthestAfter)})(slice);const rightVector=orthogonal([0,0,0],this.plane),perp=cross$1([0,0,0],this.plane,rightVector);this.v=normalize$1(perp,perp),this.u=cross$1([0,0,0],this.v,this.plane),this.basisMap=new Map;const projected=slice.contours.map(part=>part.map(v=>this.to2D(v))),geometry=create$b(projected);this.roots=(geometry=>{const outlines=toOutlines(geometry),solids=[],holes=[];outlines.forEach((outline,i)=>{const a=area(outline);a<0?holes.push(i):a>0&&solids.push(i)});const children=[],parents=[];return solids.forEach((s,i)=>{const solid=outlines[s];children[i]=[],holes.forEach((h,j)=>{const hole=outlines[h];arePointsInside([hole[0]],create$3(solid))&&(children[i].push(h),parents[j]||(parents[j]=[]),parents[j].push(i))})}),holes.forEach((h,j)=>{if(parents[j]&&parents[j].length>1){const directParent=((list,score)=>{let bestIndex,best;return list.forEach((item,index)=>{const value=score(item);(void 0===best||value<best)&&(bestIndex=index,best=value)}),bestIndex})(parents[j],p=>children[p].length);parents[j].forEach((p,i)=>{i!==directParent&&(children[p]=children[p].filter(c=>c!==h))})}}),children.map((holes,i)=>({solid:outlines[solids[i]],holes:holes.map(h=>outlines[h])}))})(geometry)}to2D(vector3){const vector2=fromValues$2(dot$2(vector3,this.u),dot$2(vector3,this.v));return this.basisMap.set(vector2,vector3),vector2}to3D(vector2){const original=this.basisMap.get(vector2);if(original)return original;{console.log("Warning: point not in original slice");const v1=scale$3([0,0,0],this.u,vector2[0]),v2=scale$3([0,0,0],this.v,vector2[1]),planeOrigin=scale$3([0,0,0],this.plane,this.plane[3]),v3=add$1(v1,v1,planeOrigin);return add$1(v2,v2,v3)}}}const toPolygons=slice=>{const hierarchy=new PolygonHierarchy(slice),polygons=[];return hierarchy.roots.forEach(({solid:solid,holes:holes})=>{let index=solid.length;const holesIndex=[];holes.forEach((hole,i)=>{holesIndex.push(index),index+=hole.length});const vertices=[solid,...holes].flat(),getVertex=i=>hierarchy.to3D(vertices[i]),indices=((data,holeIndices,dim=2)=>{const hasHoles=holeIndices&&holeIndices.length,outerLen=hasHoles?holeIndices[0]*dim:data.length;let outerNode=linkedPolygon(data,0,outerLen,dim,!0);const triangles=[];if(!outerNode||outerNode.next===outerNode.prev)return triangles;let minX,minY,maxX,maxY,invSize;if(hasHoles&&(outerNode=((data,holeIndices,outerNode,dim)=>{const queue=[];for(let i=0,len=holeIndices.length;i<len;i++){const start=holeIndices[i]*dim,end=i<len-1?holeIndices[i+1]*dim:data.length,list=linkedPolygon(data,start,end,dim,!1);list===list.next&&(list.steiner=!0),queue.push(getLeftmost(list))}queue.sort((a,b)=>a.x-b.x);for(let i=0;i<queue.length;i++)outerNode=eliminateHole(queue[i],outerNode),outerNode=filterPoints(outerNode,outerNode.next);return outerNode})(data,holeIndices,outerNode,dim)),data.length>80*dim){minX=maxX=data[0],minY=maxY=data[1];for(let i=dim;i<outerLen;i+=dim){const x=data[i],y=data[i+1];x<minX&&(minX=x),y<minY&&(minY=y),x>maxX&&(maxX=x),y>maxY&&(maxY=y)}invSize=Math.max(maxX-minX,maxY-minY),invSize=0!==invSize?1/invSize:0}return earcutLinked(outerNode,triangles,dim,minX,minY,invSize),triangles})(vertices.flat(),holesIndex);for(let i=0;i<indices.length;i+=3){const tri=indices.slice(i,i+3).map(getVertex);polygons.push(fromVerticesAndPlane(tri,hierarchy.plane))}}),polygons},transform$4=(matrix,slice)=>{const contours=slice.contours.map(contour=>contour.map(vertex=>transform$d([0,0,0],vertex,matrix)));return create$4(contours)},flatten=arr=>arr.flat(1/0),create$1=()=>[0,1,0],direction$1=line=>{const vector=normal([0,0],line);return negate(vector,vector),vector},fromPoints$1=(out,point1,point2)=>{const vector=subtract$1([0,0],point2,point1);normal(vector,vector),normalize(vector,vector);const distance=dot$1(point1,vector);return out[0]=vector[0],out[1]=vector[1],out[2]=distance,out},cache$2=new WeakMap,expand2=(bbox,point)=>{0===bbox.length?(bbox[0]=fromVec2([0,0,0],point),bbox[1]=fromVec2([0,0,0],point)):(min(bbox[0],bbox[0],point),max(bbox[1],bbox[1],point))},expand3=(bbox,vertex)=>{0===bbox.length?(bbox[0]=clone$a(vertex),bbox[1]=clone$a(vertex)):(min$1(bbox[0],bbox[0],vertex),max$1(bbox[1],bbox[1],vertex))},measureCached$1=(geometry,measureFn)=>{let boundingBox=cache$2.get(geometry);return boundingBox||(boundingBox=measureFn(geometry),0===boundingBox.length&&(boundingBox[0]=[0,0,0],boundingBox[1]=[0,0,0]),cache$2.set(geometry,boundingBox),boundingBox)},measureBoundingBoxOfPath2=geometry=>{const boundingBox=[];return toPoints$1(geometry).forEach(point=>{expand2(boundingBox,point)}),boundingBox},measureBoundingBoxOfPath3=geometry=>{const boundingBox=[];return(geometry=>(geometry=>(isIdentity(geometry.transforms)||(geometry.vertices=geometry.vertices.map(vertex=>transform$d([0,0,0],vertex,geometry.transforms)),geometry.transforms=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]),geometry))(geometry).vertices)(geometry).forEach(vertice=>{expand3(boundingBox,vertice)}),boundingBox},measureBoundingBoxOfGeom2=geometry=>{const boundingBox=[];return toPoints$2(geometry).forEach(point=>{expand2(boundingBox,point)}),boundingBox},measureBoundingBoxOfGeom3=geometry=>{const boundingBox=[];return toPolygons$1(geometry).forEach(polygon=>{toVertices$3(polygon).forEach(vertex=>{expand3(boundingBox,vertex)})}),boundingBox},measureBoundingBoxOfSlice=geometry=>{const boundingBox=[];return geometry.contours.forEach(contour=>{contour.forEach(vertex=>{expand3(boundingBox,vertex)})}),boundingBox},measureBoundingBox=(...geometries)=>{const results=(geometries=flatten(geometries)).map(geometry=>isA$4(geometry)?measureCached$1(geometry,measureBoundingBoxOfGeom3):isA$6(geometry)?measureCached$1(geometry,measureBoundingBoxOfGeom2):isA$3(geometry)?measureCached$1(geometry,measureBoundingBoxOfPath2):isA$2(geometry)?measureCached$1(geometry,measureBoundingBoxOfPath3):isA$1(geometry)?measureCached$1(geometry,measureBoundingBoxOfSlice):[[0,0,0],[0,0,0]]);return 1===results.length?results[0]:results},calculateEpsilonFromBounds=(bounds,dimensions)=>{let total=0;for(let i=0;i<dimensions;i++)total+=bounds[1][i]-bounds[0][i];return EPS$1*total/dimensions},isNumberArray=(array,dimension)=>!!(Array.isArray(array)&&array.length>=dimension)&&array.every(n=>Number.isFinite(n)),isGTE=(value,constant)=>Number.isFinite(value)&&value>=constant,arc=(options={})=>{let{center:center=[0,0],radius:radius=1,startAngle:startAngle=0,endAngle:endAngle=TAU,makeTangent:makeTangent=!1,segments:segments=32}=options;if(!isNumberArray(center,2))throw new Error("center must be an array of X and Y values");if(value=radius,constant=0,!(Number.isFinite(value)&&value>constant))throw new Error("radius must be greater than zero");var value,constant;if(!isGTE(startAngle,0))throw new Error("startAngle must be positive");if(!isGTE(endAngle,0))throw new Error("endAngle must be positive");if(!isGTE(segments,4))throw new Error("segments must be four or more");startAngle%=TAU,endAngle%=TAU;let rotation=TAU;startAngle<endAngle&&(rotation=endAngle-startAngle),startAngle>endAngle&&(rotation=endAngle+(TAU-startAngle));const minAngle=Math.acos((radius*radius+radius*radius-EPS$1*EPS$1)/(2*radius*radius)),centerV=clone$9(center);let point;const pointArray=[];if(rotation<minAngle)point=fromAngleRadians([0,0],startAngle),scale$1(point,point,radius),add(point,point,centerV),pointArray.push(point);else{const numSteps=Math.floor(segments*(Math.abs(rotation)/TAU));let edgeStepSize=.5*numSteps/rotation;edgeStepSize>.25&&(edgeStepSize=.25);const totalSteps=makeTangent?numSteps+2:numSteps;for(let i=0;i<=totalSteps;i++){let step=i;makeTangent&&(step=(i-1)*(numSteps-2*edgeStepSize)/numSteps+edgeStepSize,step<0&&(step=0),step>numSteps&&(step=numSteps));const angle=startAngle+step*(rotation/numSteps);point=fromAngleRadians(create$a(),angle),scale$1(point,point,radius),add(point,point,centerV),pointArray.push(point)}}return fromPoints$2({closed:!1},pointArray)},ellipse=(options={})=>{let{center:center=[0,0],radius:radius=[1,1],startAngle:startAngle=0,endAngle:endAngle=TAU,segments:segments=32}=options;if(!isNumberArray(center,2))throw new Error("center must be an array of X and Y values");if(!isNumberArray(radius,2))throw new Error("radius must be an array of X and Y values");if(!radius.every(n=>n>=0))throw new Error("radius values must be positive");if(!isGTE(startAngle,0))throw new Error("startAngle must be positive");if(!isGTE(endAngle,0))throw new Error("endAngle must be positive");if(!isGTE(segments,3))throw new Error("segments must be three or more");if(0===radius[0]||0===radius[1])return create$b();startAngle%=TAU,endAngle%=TAU;let rotation=TAU;startAngle<endAngle&&(rotation=endAngle-startAngle),startAngle>endAngle&&(rotation=endAngle+(TAU-startAngle));const minRadius=Math.min(radius[0],radius[1]);if(rotation<Math.acos((minRadius*minRadius+minRadius*minRadius-EPS$1*EPS$1)/(2*minRadius*minRadius)))throw new Error("startAngle and endAngle do not define a significant rotation");segments=Math.floor(segments*(rotation/TAU));const centerV=clone$9(center),step=rotation/segments,points=[];segments=rotation<TAU?segments+1:segments;for(let i=0;i<segments;i++){const angle=step*i+startAngle,point=fromValues$2(radius[0]*cos(angle),radius[1]*sin(angle));add(point,centerV,point),points.push(point)}return rotation<TAU&&points.push(centerV),create$b([points])},circle=(options={})=>{let{center:center=[0,0],radius:radius=1,startAngle:startAngle=0,endAngle:endAngle=TAU,segments:segments=32}=options;if(!isGTE(radius,0))throw new Error("radius must be positive");return radius=[radius,radius],ellipse({center:center,radius:radius,startAngle:startAngle,endAngle:endAngle,segments:segments})},line=points=>{if(!Array.isArray(points))throw new Error("points must be an array");return fromPoints$2({},points)},sphere=(options={})=>{let{center:center=[0,0,0],radius:radius=1,segments:segments=32,axes:axes=[[1,0,0],[0,-1,0],[0,0,1]]}=options;if(!isGTE(radius,0))throw new Error("radius must be positive");return radius=[radius,radius,radius],((options={})=>{const{center:center=[0,0,0],radius:radius=[1,1,1],segments:segments=32,axes:axes=[[1,0,0],[0,-1,0],[0,0,1]]}=options;if(!isNumberArray(center,3))throw new Error("center must be an array of X, Y and Z values");if(!isNumberArray(radius,3))throw new Error("radius must be an array of X, Y and Z values");if(!radius.every(n=>n>=0))throw new Error("radius values must be positive");if(!isGTE(segments,4))throw new Error("segments must be four or more");if(0===radius[0]||0===radius[1]||0===radius[2])return create$9();const xVector=scale$3([0,0,0],normalize$1([0,0,0],axes[0]),radius[0]),yVector=scale$3([0,0,0],normalize$1([0,0,0],axes[1]),radius[1]),zVector=scale$3([0,0,0],normalize$1([0,0,0],axes[2]),radius[2]),qSegments=Math.round(segments/4);let prevCylinderVertex;const polygons=[],p1=[0,0,0],p2=[0,0,0];for(let slice1=0;slice1<=segments;slice1++){const angle=TAU*slice1/segments,cylinderVertex=add$1(create$c(),scale$3(p1,xVector,cos(angle)),scale$3(p2,yVector,sin(angle)));if(slice1>0){let prevCosPitch,prevSinPitch;for(let slice2=0;slice2<=qSegments;slice2++){const pitch=TAU/4*slice2/qSegments,cosPitch=cos(pitch),sinPitch=sin(pitch);if(slice2>0){let vertex,vertices=[];vertex=subtract$3(create$c(),scale$3(p1,prevCylinderVertex,prevCosPitch),scale$3(p2,zVector,prevSinPitch)),vertices.push(add$1(vertex,vertex,center)),vertex=subtract$3(create$c(),scale$3(p1,cylinderVertex,prevCosPitch),scale$3(p2,zVector,prevSinPitch)),vertices.push(add$1(vertex,vertex,center)),slice2<qSegments&&(vertex=subtract$3(create$c(),scale$3(p1,cylinderVertex,cosPitch),scale$3(p2,zVector,sinPitch)),vertices.push(add$1(vertex,vertex,center))),vertex=subtract$3(create$c(),scale$3(p1,prevCylinderVertex,cosPitch),scale$3(p2,zVector,sinPitch)),vertices.push(add$1(vertex,vertex,center)),polygons.push(create$8(vertices)),vertices=[],vertex=add$1(create$c(),scale$3(p1,prevCylinderVertex,prevCosPitch),scale$3(p2,zVector,prevSinPitch)),vertices.push(add$1(create$c(),center,vertex)),vertex=add$1(vertex,scale$3(p1,cylinderVertex,prevCosPitch),scale$3(p2,zVector,prevSinPitch)),vertices.push(add$1(create$c(),center,vertex)),slice2<qSegments&&(vertex=add$1(vertex,scale$3(p1,cylinderVertex,cosPitch),scale$3(p2,zVector,sinPitch)),vertices.push(add$1(create$c(),center,vertex))),vertex=add$1(vertex,scale$3(p1,prevCylinderVertex,cosPitch),scale$3(p2,zVector,sinPitch)),vertices.push(add$1(create$c(),center,vertex)),vertices.reverse(),polygons.push(create$8(vertices))}prevCosPitch=cosPitch,prevSinPitch=sinPitch}}prevCylinderVertex=cylinderVertex}return create$9(polygons)})({center:center,radius:radius,segments:segments,axes:axes})},mirror=(options,...objects)=>{const{origin:origin,normal:normal}=Object.assign({},{origin:[0,0,0],normal:[0,0,1]},options),planeOfMirror=fromNormalAndPoint([0,0,0,0],normal,origin);if(Number.isNaN(planeOfMirror[0]))throw new Error("the given origin and normal do not define a proper plane");const matrix=mirrorByPlane([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],planeOfMirror),results=objects.map(object=>isA$4(object)?transform$8(matrix,object):isA$6(object)?transform$b(matrix,object):isA$3(object)?transform$7(matrix,object):isA$2(object)?((matrix,geometry)=>{const transforms=multiply$1([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],matrix,geometry.transforms);return Object.assign({},geometry,{transforms:transforms})})(matrix,object):isA$1(object)?transform$4(matrix,object):Array.isArray(object)?mirror(options,...object):object);return 1===results.length?results[0]:results},gcd=(a,b)=>a===b?a:a<b?gcd(b,a):1===b?1:0===b?a:gcd(b,a%b),repartitionEdges=(newLength,edges)=>{const multiple=newLength/edges.length;if(1===multiple)return edges;const divisor=fromValues$3(multiple,multiple,multiple),increment=[0,0,0],newEdges=[];return edges.forEach(edge=>{subtract$3(increment,edge[1],edge[0]),divide$1(increment,increment,divisor);let prev=edge[0];for(let i=1;i<=multiple;++i){const next=add$1(create$c(),prev,increment);newEdges.push([prev,next]),prev=next}}),newEdges},EPSAREA=EPS$1*EPS$1/2*Math.sin(Math.PI/3),extrudeWalls=(slice0,slice1)=>{let edges0=toEdges(slice0),edges1=toEdges(slice1);if(edges0.length!==edges1.length){const newLength=(a=edges0.length)*(b=edges1.length)/gcd(a,b);newLength!==edges0.length&&(edges0=repartitionEdges(newLength,edges0)),newLength!==edges1.length&&(edges1=repartitionEdges(newLength,edges1))}var a,b;const walls=[];return edges0.forEach((edge0,i)=>{const edge1=edges1[i],poly0=create$8([edge0[0],edge0[1],edge1[1]]),poly0area=measureArea$2(poly0);Number.isFinite(poly0area)&&poly0area>EPSAREA&&walls.push(poly0);const poly1=create$8([edge0[0],edge1[1],edge1[0]]),poly1area=measureArea$2(poly1);Number.isFinite(poly1area)&&poly1area>EPSAREA&&walls.push(poly1)}),walls},defaultCallback=(progress,index,base)=>{let baseSlice=null;return isA$6(base)&&(baseSlice=fromOutlines$1(toOutlines(base))),isA$5(base)&&(baseSlice=(vertices=>{if(!Array.isArray(vertices))throw new Error("the given vertices must be an array");if(vertices.length<3)throw new Error("the given vertices must contain THREE or more vertices");const cloned=vertices.map(vertex=>3===vertex.length?vertex:fromVec2([0,0,0],vertex));return create$4([cloned])})(toVertices$3(base))),0===progress||1===progress?transform$4(fromTranslation([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],[0,0,progress]),baseSlice):null},extrudeFromSlices=(options,base)=>{const defaults={numberOfSlices:2,capStart:!0,capEnd:!0,close:!1,callback:defaultCallback},{numberOfSlices:numberOfSlices,capStart:capStart,capEnd:capEnd,close:close,callback:generate}=Object.assign({},defaults,options);if(numberOfSlices<2)throw new Error("numberOfSlices must be 2 or more");const sMax=numberOfSlices-1;let startSlice=null,endSlice=null,prevSlice=null;const polygons=[];for(let s=0;s<numberOfSlices;s++){const currentSlice=generate(s/sMax,s,base);if(currentSlice){if(!isA$1(currentSlice))throw new Error("the callback function must return slice objects");if(0===currentSlice.contours.length)throw new Error("the callback function must return slices with one or more contours");if(prevSlice){const walls=extrudeWalls(prevSlice,currentSlice);for(let i=0;i<walls.length;i++)polygons.push(walls[i])}0===s&&(startSlice=currentSlice),s===numberOfSlices-1&&(endSlice=currentSlice),prevSlice=currentSlice}}if(capEnd){const endPolygons=toPolygons(endSlice);for(let i=0;i<endPolygons.length;i++)polygons.push(endPolygons[i])}if(capStart){const startPolygons=toPolygons(startSlice).map(invert$1);for(let i=0;i<startPolygons.length;i++)polygons.push(startPolygons[i])}if(!capStart&&!capEnd&&close&&!((a,b)=>{if(a.contours.length!==b.contours.length)return!1;const len=a.contours.length;for(let i=0;i<len;i++){const aVertex=a.contours[i];for(let j=0;j<len;j++){const bVertex=b.contours[j];if(!equals$8(aVertex,bVertex))return!1}}return!0})(endSlice,startSlice)){const walls=extrudeWalls(endSlice,startSlice);for(let i=0;i<walls.length;i++)polygons.push(walls[i])}return create$9(polygons)},flattenHelper=(arr,out)=>(Array.isArray(arr)?arr.forEach(child=>flattenHelper(child,out)):null!=arr&&void 0!==arr&&out.push(arr),out),DEFAULT_COMPARE=(a,b)=>a>b?1:a<b?-1:0;let Node$1=class{constructor(key,data){this.key=key,this.data=data,this.left=null,this.right=null,this.next=null}};const splay=(key,t,comparator)=>{const N=new Node$1(null,null);let left=N,right=N;for(;;){const cmp=comparator(key,t.key);if(cmp<0){if(null===t.left)break;if(comparator(key,t.left.key)<0){const y=t.left;if(t.left=y.right,y.right=t,null===(t=y).left)break}right.left=t,right=t,t=t.left}else{if(!(cmp>0))break;if(null===t.right)break;if(comparator(key,t.right.key)>0){const y=t.right;if(t.right=y.left,y.left=t,null===(t=y).right)break}left.right=t,left=t,t=t.right}}return left.right=t.left,right.left=t.right,t.left=N.right,t.right=N.left,t};let Tree$1=class{constructor(comparator=DEFAULT_COMPARE){this.comparator=comparator,this._root=null}insert(key,data){return this._root=((key,data,root,comparator)=>{const node=new Node$1(key,data);if(null===root)return node;const cmp=comparator(key,(root=splay(key,root,comparator)).key);return cmp<0?(node.left=root.left,node.right=root,root.left=null):cmp>=0&&(node.right=root.right,node.left=root,root.right=null),node})(key,data,this._root,this.comparator),this._root}remove(key){this._root=this._remove(key)}_remove(key){if(null===this._root)return null;let x;const t=splay(key,this._root,this.comparator);return 0===this.comparator(key,t.key)?(null===t.left?x=t.right:(x=splay(key,t.left,this.comparator),x.right=t.right),x):t}find(key){return this._root&&(this._root=splay(key,this._root,this.comparator),0!==this.comparator(key,this._root.key))?null:this._root}minNode(t=this._root){if(t)for(;t.left;)t=t.left;return t}maxNode(t=this._root){if(t)for(;t.right;)t=t.right;return t}next(node){let successor=null;if(node.right){for(successor=node.right;successor.left;)successor=successor.left;return successor}let root=this._root;for(;root;){const cmp=this.comparator(node.key,root.key);if(0===cmp)break;cmp<0?(successor=root,root=root.left):root=root.right}return successor}prev(node){let predecessor=null;if(node.left){for(predecessor=node.left;predecessor.right;)predecessor=predecessor.right;return predecessor}let root=this._root;for(;root;){const cmp=this.comparator(node.key,root.key);if(0===cmp)break;cmp<0?root=root.left:(predecessor=root,root=root.right)}return predecessor}};const computeFields=(event,prev,operation)=>{null===prev?(event.inOut=!1,event.otherInOut=!0):(event.isSubject===prev.isSubject?(event.inOut=!prev.inOut,event.otherInOut=prev.otherInOut):(event.inOut=!prev.otherInOut,event.otherInOut=prev.isVertical()?!prev.inOut:prev.inOut),prev&&(event.prevInResult=!inResult(prev,operation)||prev.isVertical()?prev.prevInResult:prev));const isInResult=inResult(event,operation);event.resultTransition=isInResult?determineResultTransition(event,operation):0},inResult=(event,operation)=>{switch(event.type){case 0:switch(operation){case 0:return!event.otherInOut;case 1:return event.otherInOut;case 2:return event.isSubject&&event.otherInOut||!event.isSubject&&!event.otherInOut;case 3:return!0}break;case 2:return 0===operation||1===operation;case 3:return 2===operation;case 1:return!1}return!1},determineResultTransition=(event,operation)=>{const thisIn=!event.inOut,thatIn=!event.otherInOut;let isIn;switch(operation){case 0:isIn=thisIn&&thatIn;break;case 1:isIn=thisIn||thatIn;break;case 3:isIn=thisIn^thatIn;break;case 2:isIn=event.isSubject?thisIn&&!thatIn:thatIn&&!thisIn}return isIn?1:-1};class SweepEvent{constructor(point,left,otherEvent,isSubject,type=0){this.left=left,this.point=point,this.otherEvent=otherEvent,this.isSubject=isSubject,this.type=type,this.inOut=!1,this.otherInOut=!1,this.prevInResult=null,this.resultTransition=0,this.otherPos=-1,this.outputContourId=-1,this.isExteriorRing=!0}isBelow(p){const p0=this.point,p1=this.otherEvent.point;return this.left?(p0[0]-p[0])*(p1[1]-p[1])-(p1[0]-p[0])*(p0[1]-p[1])>0:(p1[0]-p[0])*(p0[1]-p[1])-(p0[0]-p[0])*(p1[1]-p[1])>0}isAbove(p){return!this.isBelow(p)}isVertical(){return this.point[0]===this.otherEvent.point[0]}get inResult(){return 0!==this.resultTransition}}const signedArea=(p0,p1,p2)=>{const res=(ax=p0[0],ay=p0[1],bx=p1[0],by=p1[1],cx=p2[0],(ay-(cy=p2[1]))*(bx-cx)-(ax-cx)*(by-cy));var ax,ay,bx,by,cx,cy;return res>0?-1:res<0?1:0},compareEvents=(e1,e2)=>{const p1=e1.point,p2=e2.point;return p1[0]>p2[0]?1:p1[0]<p2[0]?-1:p1[1]!==p2[1]?p1[1]>p2[1]?1:-1:e1.left!==e2.left?e1.left?1:-1:0!==signedArea(p1,e1.otherEvent.point,e2.otherEvent.point)?e1.isBelow(e2.otherEvent.point)?-1:1:!e1.isSubject&&e2.isSubject?1:-1},divideSegment=(segment,point,queue)=>{const r=new SweepEvent(point,!1,segment,segment.isSubject),l=new SweepEvent(point,!0,segment.otherEvent,segment.isSubject);return r.contourId=l.contourId=segment.contourId,compareEvents(l,segment.otherEvent)>0&&(segment.otherEvent.left=!0,l.left=!1),segment.otherEvent.otherEvent=l,segment.otherEvent=r,queue.push(l),queue.push(r),queue},crossProduct=(a,b)=>a[0]*b[1]-a[1]*b[0],possibleIntersection=(se1,se2,queue)=>{const inter=((a1,a2,b1,b2,noEndpointTouch=!1)=>{const va=[a2[0]-a1[0],a2[1]-a1[1]],vb=[b2[0]-b1[0],b2[1]-b1[1]],toPoint=(p,s,d)=>[p[0]+s*d[0],p[1]+s*d[1]],v1=[b1[0]-a1[0],b1[1]-a1[1]];let kross=crossProduct(va,vb),sqrKross=kross*kross;if(sqrKross>0){const s=crossProduct(v1,vb)/kross;if(s<0||s>1)return null;const t=crossProduct(v1,va)/kross;return t<0||t>1?null:0===s||1===s?noEndpointTouch?null:[toPoint(a1,s,va)]:0===t||1===t?noEndpointTouch?null:[toPoint(b1,t,vb)]:[toPoint(a1,s,va)]}if(kross=crossProduct(v1,va),sqrKross=kross*kross,sqrKross>0)return null;const sqrLenA=dot$1(va,va),sa=dot$1(va,v1)/sqrLenA,sb=sa+dot$1(va,vb)/sqrLenA,smin=Math.min(sa,sb),smax=Math.max(sa,sb);return smin<=1&&smax>=0?1===smin?noEndpointTouch?null:[toPoint(a1,smin>0?smin:0,va)]:0===smax?noEndpointTouch?null:[toPoint(a1,smax<1?smax:1,va)]:noEndpointTouch&&0===smin&&1===smax?null:[toPoint(a1,smin>0?smin:0,va),toPoint(a1,smax<1?smax:1,va)]:null})(se1.point,se1.otherEvent.point,se2.point,se2.otherEvent.point),nIntersections=inter?inter.length:0;if(0===nIntersections)return 0;if(1===nIntersections&&(equals$7(se1.point,se2.point)||equals$7(se1.otherEvent.point,se2.otherEvent.point)))return 0;if(1===nIntersections)return equals$7(se1.point,inter[0])||equals$7(se1.otherEvent.point,inter[0])||divideSegment(se1,inter[0],queue),equals$7(se2.point,inter[0])||equals$7(se2.otherEvent.point,inter[0])||divideSegment(se2,inter[0],queue),1;if(2===nIntersections&&se1.isSubject===se2.isSubject)return 0;const segmentEvents=[];let leftCoincide=!1,rightCoincide=!1;return equals$7(se1.point,se2.point)?leftCoincide=!0:1===compareEvents(se1,se2)?segmentEvents.push(se2,se1):segmentEvents.push(se1,se2),equals$7(se1.otherEvent.point,se2.otherEvent.point)?rightCoincide=!0:1===compareEvents(se1.otherEvent,se2.otherEvent)?segmentEvents.push(se2.otherEvent,se1.otherEvent):segmentEvents.push(se1.otherEvent,se2.otherEvent),leftCoincide?(se2.type=1,se1.type=se2.inOut===se1.inOut?2:3,rightCoincide||divideSegment(segmentEvents[1].otherEvent,segmentEvents[0].point,queue),2):rightCoincide?(divideSegment(segmentEvents[0],segmentEvents[1].point,queue),3):segmentEvents[0]!==segmentEvents[3].otherEvent?(divideSegment(segmentEvents[0],segmentEvents[1].point,queue),divideSegment(segmentEvents[1],segmentEvents[2].point,queue),4):(divideSegment(segmentEvents[0],segmentEvents[1].point,queue),divideSegment(segmentEvents[3].otherEvent,segmentEvents[2].point,queue),5)},compareSegments=(le1,le2)=>{if(le1===le2)return 0;if(0!==signedArea(le1.point,le1.otherEvent.point,le2.point)||0!==signedArea(le1.point,le1.otherEvent.point,le2.otherEvent.point))return equals$7(le1.point,le2.point)?le1.isBelow(le2.otherEvent.point)?-1:1:le1.point[0]===le2.point[0]?le1.point[1]<le2.point[1]?-1:1:1===compareEvents(le1,le2)?le2.isAbove(le1.point)?-1:1:le1.isBelow(le2.point)?-1:1;if(le1.isSubject!==le2.isSubject)return le1.isSubject?-1:1;{let p1=le1.point,p2=le2.point;if(p1[0]===p2[0]&&p1[1]===p2[1])return p1=le1.otherEvent.point,p2=le2.otherEvent.point,p1[0]===p2[0]&&p1[1]===p2[1]?0:le1.contourId>le2.contourId?1:-1}return 1===compareEvents(le1,le2)?1:-1};class Contour{constructor(){this.points=[],this.holeIds=[],this.holeOf=null,this.depth=0}isExterior(){return null==this.holeOf}}const nextPos=(pos,resultEvents,processed,origPos)=>{const length=resultEvents.length,p0=resultEvents[pos].point;let p1,newPos=pos+1;for(newPos<length&&(p1=resultEvents[newPos].point);newPos<length&&p1[0]===p0[0]&&p1[1]===p0[1];){if(!processed[newPos])return newPos;newPos++,newPos<length&&(p1=resultEvents[newPos].point)}for(newPos=pos-1;processed[newPos]&&newPos>origPos;)newPos--;return newPos},initializeContourFromContext=(event,contours,contourId)=>{const contour=new Contour;if(null!=event.prevInResult){const prevInResult=event.prevInResult,lowerContourId=prevInResult.outputContourId,lowerResultTransition=prevInResult.resultTransition;if(lowerContourId<0)contour.holeOf=null,contour.depth=0;else if(lowerResultTransition>0){const lowerContour=contours[lowerContourId];if(null!=lowerContour.holeOf){const parentContourId=lowerContour.holeOf;contours[parentContourId].holeIds.push(contourId),contour.holeOf=parentContourId,contour.depth=contours[lowerContourId].depth}else contours[lowerContourId].holeIds.push(contourId),contour.holeOf=lowerContourId,contour.depth=contours[lowerContourId].depth+1}else contour.depth=contours[lowerContourId].depth}return contour};class Queue{constructor(data,compare){if(this.data=data,this.length=this.data.length,this.compare=compare,this.length>0)for(let i=(this.length>>1)-1;i>=0;i--)this._down(i)}push(item){this.data.push(item),this._up(this.length++)}pop(){if(0===this.length)return;const top=this.data[0],bottom=this.data.pop();return--this.length>0&&(this.data[0]=bottom,this._down(0)),top}peek(){return this.data[0]}_up(pos){const{data:data,compare:compare}=this,item=data[pos];for(;pos>0;){const parent=pos-1>>1,current=data[parent];if(compare(item,current)>=0)break;data[pos]=current,pos=parent}data[pos]=item}_down(pos){const{data:data,compare:compare}=this,halfLength=this.length>>1,item=data[pos];for(;pos<halfLength;){let bestChild=1+(pos<<1);const right=bestChild+1;if(right<this.length&&compare(data[right],data[bestChild])<0&&(bestChild=right),compare(data[bestChild],item)>=0)break;data[pos]=data[bestChild],pos=bestChild}data[pos]=item}}let externalRingId=0;const processPolygon=(contourOrHole,isSubject,ringId,queue,bbox,isExteriorRing)=>{const len=contourOrHole.length-1;for(let i=0;i<len;i++){const s1=contourOrHole[i],s2=contourOrHole[i+1],e1=new SweepEvent(s1,!1,void 0,isSubject),e2=new SweepEvent(s2,!1,e1,isSubject);if(e1.otherEvent=e2,s1[0]===s2[0]&&s1[1]===s2[1])continue;e1.contourId=e2.contourId=ringId,isExteriorRing||(e1.isExteriorRing=!1,e2.isExteriorRing=!1),compareEvents(e1,e2)>0?e2.left=!0:e1.left=!0;const x=s1[0],y=s1[1];bbox[0]=Math.min(bbox[0],x),bbox[1]=Math.min(bbox[1],y),bbox[2]=Math.max(bbox[2],x),bbox[3]=Math.max(bbox[3],y),queue.push(e1),queue.push(e2)}},EMPTY=[],toMartinez=geometry=>{const outlines=[];return toOutlines(geometry).forEach(outline=>{equals$7(outline[0],outline[outline.length-1])?outlines.push(outline):outlines.push([...outline,outline[0]])}),[outlines]},fromOutlines=outlines=>(outlines.forEach(outline=>{equals$7(outline[0],outline[outline.length-1])&&outline.pop()}),outlines=outlines.filter(o=>o.length>=3),create$b(outlines)),boolean=(subjectGeom,clippingGeom,operation)=>{const subject=toMartinez(subjectGeom),clipping=toMartinez(clippingGeom);let trivial=((subject,clipping)=>{let result=null;return subject.length*clipping.length===0&&(result=0===subject.length?clipping:subject),result===EMPTY?create$b():result?fromOutlines(result.flat()):null})(subject,clipping);if(trivial)return trivial;const sbbox=[1/0,1/0,-1/0,-1/0],cbbox=[1/0,1/0,-1/0,-1/0],eventQueue=((subject,clipping,sbbox,cbbox)=>{const eventQueue=new Queue([],compareEvents);for(let i=0;i<subject.length;i++){const polygonSet=subject[i];for(let j=0;j<polygonSet.length;j++){const isExteriorRing=0===j;isExteriorRing&&externalRingId++,processPolygon(polygonSet[j],!0,externalRingId,eventQueue,sbbox,isExteriorRing)}}for(let i=0;i<clipping.length;i++){const polygonSet=clipping[i];for(let j=0;j<polygonSet.length;j++){let isExteriorRing=0===j;isExteriorRing&&externalRingId++,processPolygon(polygonSet[j],!1,externalRingId,eventQueue,cbbox,isExteriorRing)}}return eventQueue})(subject,clipping,sbbox,cbbox);if(trivial=((subject,clipping,sbbox,cbbox)=>{let result=null;return(sbbox[0]>cbbox[2]||cbbox[0]>sbbox[2]||sbbox[1]>cbbox[3]||cbbox[1]>sbbox[3])&&(result=subject.concat(clipping)),result===EMPTY?create$b():result?fromOutlines(result.flat()):null})(subject,clipping,sbbox,cbbox),trivial)return trivial;const sortedEvents=((eventQueue,subject,clipping,sbbox,cbbox,operation)=>{const sweepLine=new Tree$1(compareSegments),sortedEvents=[];let prev,next,begin;for(;0!==eventQueue.length;){const event=eventQueue.pop();if(sortedEvents.push(event),event.left){next=prev=sweepLine.insert(event),begin=sweepLine.minNode(),prev=prev!==begin?sweepLine.prev(prev):null,next=sweepLine.next(next);const prevEvent=prev?prev.key:null;let prevprevEvent;if(computeFields(event,prevEvent,operation),next&&2===possibleIntersection(event,next.key,eventQueue)&&(computeFields(event,prevEvent,operation),computeFields(next.key,event,operation)),prev&&2===possibleIntersection(prev.key,event,eventQueue)){let prevprev=prev;prevprev=prevprev!==begin?sweepLine.prev(prevprev):null,prevprevEvent=prevprev?prevprev.key:null,computeFields(prevEvent,prevprevEvent,operation),computeFields(event,prevEvent,operation)}}else next=prev=sweepLine.find(event.otherEvent),prev&&next&&(prev=prev!==begin?sweepLine.prev(prev):null,next=sweepLine.next(next),sweepLine.remove(event.otherEvent),next&&prev&&possibleIntersection(prev.key,next.key,eventQueue))}return sortedEvents})(eventQueue,0,0,0,0,operation),contours=(sortedEvents=>{const resultEvents=(sortedEvents=>{const resultEvents=[];sortedEvents.forEach(e=>{(e.left&&e.inResult||!e.left&&e.otherEvent.inResult)&&resultEvents.push(e)});let sorted=!1;for(;!sorted;){sorted=!0;const len=resultEvents.length;for(let i=0;i<len;i++)if(i+1<len&&1===compareEvents(resultEvents[i],resultEvents[i+1])){const tmp=resultEvents[i];resultEvents[i]=resultEvents[i+1],resultEvents[i+1]=tmp,sorted=!1}}return resultEvents.forEach((e,i)=>{e.otherPos=i}),resultEvents.forEach(e=>{if(!e.left){const otherPos=e.otherPos;e.otherPos=e.otherEvent.otherPos,e.otherEvent.otherPos=otherPos}}),resultEvents})(sortedEvents),evlen=resultEvents.length,processed=[],contours=[];for(let i=0;i<evlen;i++){if(processed[i])continue;const contourId=contours.length,contour=initializeContourFromContext(resultEvents[i],contours,contourId),markAsProcessed=pos=>{processed[pos]=!0,pos<evlen&&(resultEvents[pos].outputContourId=contourId)};let pos=i;const origPos=i;for(contour.points.push(resultEvents[pos].point);markAsProcessed(pos),pos=resultEvents[pos].otherPos,markAsProcessed(pos),contour.points.push(resultEvents[pos].point),pos=nextPos(pos,resultEvents,processed,origPos),!(pos===origPos||pos>=evlen););contours.push(contour)}return contours})(sortedEvents),polygons=[];for(let i=0;i<contours.length;i++){const contour=contours[i];if(contour.isExterior()){const rings=[contour.points];for(let j=0;j<contour.holeIds.length;j++){const holePoints=contours[contour.holeIds[j]].points,hole=[];for(let k=holePoints.length-2;k>=0;k--)hole.push(holePoints[k]);rings.push(hole)}polygons.push(rings)}}return polygons.length?fromOutlines(polygons.flat()):create$b()},interpolateBetween2DPointsForY=(point1,point2,y)=>{let t,f1=y-point1[1],f2=point2[1]-point1[1];return f2<0&&(f1=-f1,f2=-f2),t=f1<=0?0:f1>=f2?1:f2<1e-10?.5:f1/f2,point1[0]+t*(point2[0]-point1[0])};class OrthonormalFormula{constructor(plane){this.plane=plane;const rightVector=orthogonal([0,0,0],plane);this.v=normalize$1(rightVector,cross$1(rightVector,plane,rightVector)),this.u=cross$1([0,0,0],this.v,plane),this.planeOrigin=scale$3([0,0,0],plane,plane[3]),this.basisMap=new Map}getProjectionMatrix(){return fromValues$4(this.u[0],this.v[0],this.plane[0],0,this.u[1],this.v[1],this.plane[1],0,this.u[2],this.v[2],this.plane[2],0,0,0,-this.plane[3],1)}getInverseProjectionMatrix(){return fromValues$4(this.u[0],this.u[1],this.u[2],0,this.v[0],this.v[1],this.v[2],0,this.plane[0],this.plane[1],this.plane[2],0,this.planeOrigin[0],this.planeOrigin[1],this.planeOrigin[2],1)}to2D(vertex){const point=fromValues$2(dot$2(vertex,this.u),dot$2(vertex,this.v));return this.basisMap.set(point,vertex),point}to3D(point){const original=this.basisMap.get(point);if(original)return original;const v1=scale$3([0,0,0],this.u,point[0]),v2=scale$3([0,0,0],this.v,point[1]),v3=add$1(v1,v1,this.planeOrigin);return add$1(v2,v2,v3)}}const insertSorted=(array,element,compareFunc)=>{let leftBound=0,rightBound=array.length;for(;rightBound>leftBound;){const testIndex=Math.floor((leftBound+rightBound)/2);compareFunc(element,array[testIndex])>0?leftBound=testIndex+1:rightBound=testIndex}array.splice(leftBound,0,element)},fnNumberSort=(a,b)=>a-b,retessellate=geometry=>{if(geometry.isRetesselated)return geometry;const polygons=toPolygons$1(geometry).map((polygon,index)=>({vertices:polygon.vertices,plane:plane(polygon),index:index})),classified=classifyPolygons(polygons),destPolygons=[];classified.forEach(group=>{if(Array.isArray(group)){const coplanarPolygons=(sourcePolygons=>{if(sourcePolygons.length<2)return sourcePolygons;const destPolygons=[],numPolygons=sourcePolygons.length,plane$1=plane(sourcePolygons[0]),orthonormalFormula=new OrthonormalFormula(plane$1),polygonVertices2d=[],polygonTopVertexIndexes=[],topy2polygonIndexes=new Map,yCoordinateToPolygonIndexes=new Map,yCoordinateBins=new Map;for(let polygonIndex=0;polygonIndex<numPolygons;polygonIndex++){const poly3d=sourcePolygons[polygonIndex];let vertices2d=[],numVertices=poly3d.vertices.length,minIndex=-1;if(numVertices>0){let miny,maxy;for(let i=0;i<numVertices;i++){let pos2d=orthonormalFormula.to2D(poly3d.vertices[i]);const yCoordinateBin=Math.floor(999999.9999999999*pos2d[1]);let newY;yCoordinateBins.has(yCoordinateBin)?newY=yCoordinateBins.get(yCoordinateBin):yCoordinateBins.has(yCoordinateBin+1)?newY=yCoordinateBins.get(yCoordinateBin+1):yCoordinateBins.has(yCoordinateBin-1)?newY=yCoordinateBins.get(yCoordinateBin-1):(newY=pos2d[1],yCoordinateBins.set(yCoordinateBin,pos2d[1])),pos2d=fromValues$2(pos2d[0],newY),vertices2d.push(pos2d);const y=pos2d[1];(0===i||y<miny)&&(miny=y,minIndex=i),(0===i||y>maxy)&&(maxy=y);let polygonIndexes=yCoordinateToPolygonIndexes.get(y);polygonIndexes||(polygonIndexes=[],yCoordinateToPolygonIndexes.set(y,polygonIndexes)),polygonIndexes[polygonIndex]=!0}if(miny>=maxy)vertices2d=[],numVertices=0,minIndex=-1;else{let polygonIndexes=topy2polygonIndexes.get(miny);polygonIndexes||(polygonIndexes=[],topy2polygonIndexes.set(miny,polygonIndexes)),polygonIndexes.push(polygonIndex)}}vertices2d.reverse(),minIndex=numVertices-minIndex-1,polygonVertices2d.push(vertices2d),polygonTopVertexIndexes.push(minIndex)}const yCoordinates=[];yCoordinateToPolygonIndexes.forEach((polylist,y)=>yCoordinates.push(y)),yCoordinates.sort(fnNumberSort);let activePolygons=[],prevOutPolygonRow=[];for(let yIndex=0;yIndex<yCoordinates.length;yIndex++){const newOutPolygonRow=[],yCoordinate=yCoordinates[yIndex],polygonIndexesWithCorner=yCoordinateToPolygonIndexes.get(yCoordinate);let nextYcoordinate,removeCount=0;for(let activePolygonIndex=0;activePolygonIndex<activePolygons.length;++activePolygonIndex){const activePolygon=activePolygons[activePolygonIndex],polygonIndex=activePolygon.polygonIndex;if(polygonIndexesWithCorner[polygonIndex]){const vertices2d=polygonVertices2d[polygonIndex],numVertices=vertices2d.length;let newLeftVertexIndex=activePolygon.leftVertexIndex,newRightVertexIndex=activePolygon.rightVertexIndex;for(;;){let nextLeftVertexIndex=newLeftVertexIndex+1;if(nextLeftVertexIndex>=numVertices&&(nextLeftVertexIndex=0),vertices2d[nextLeftVertexIndex][1]!==yCoordinate)break;newLeftVertexIndex=nextLeftVertexIndex}let nextRightVertexIndex=newRightVertexIndex-1;if(nextRightVertexIndex<0&&(nextRightVertexIndex=numVertices-1),vertices2d[nextRightVertexIndex][1]===yCoordinate&&(newRightVertexIndex=nextRightVertexIndex),newLeftVertexIndex!==activePolygon.leftVertexIndex&&newLeftVertexIndex===newRightVertexIndex)activePolygon.remove=!0,removeCount++;else{activePolygon.leftVertexIndex=newLeftVertexIndex,activePolygon.rightVertexIndex=newRightVertexIndex,activePolygon.topLeft=vertices2d[newLeftVertexIndex],activePolygon.topRight=vertices2d[newRightVertexIndex];let nextLeftVertexIndex=newLeftVertexIndex+1;nextLeftVertexIndex>=numVertices&&(nextLeftVertexIndex=0),activePolygon.bottomLeft=vertices2d[nextLeftVertexIndex];let nextRightVertexIndex=newRightVertexIndex-1;nextRightVertexIndex<0&&(nextRightVertexIndex=numVertices-1),activePolygon.bottomRight=vertices2d[nextRightVertexIndex]}}}if(removeCount>0&&(activePolygons=activePolygons.filter(p=>!p.remove)),yIndex>=yCoordinates.length-1)activePolygons=[],nextYcoordinate=null;else{nextYcoordinate=Number(yCoordinates[yIndex+1]);const middleYcoordinate=.5*(yCoordinate+nextYcoordinate),startingPolygonIndexes=topy2polygonIndexes.get(yCoordinate);for(const polygonIndexKey in startingPolygonIndexes){const polygonIndex=startingPolygonIndexes[polygonIndexKey],vertices2d=polygonVertices2d[polygonIndex],numVertices=vertices2d.length,topVertexIndex=polygonTopVertexIndexes[polygonIndex];let topLeftVertexIndex=topVertexIndex;for(;;){let i=topLeftVertexIndex+1;if(i>=numVertices&&(i=0),vertices2d[i][1]!==yCoordinate)break;if(i===topVertexIndex)break;topLeftVertexIndex=i}let topRightVertexIndex=topVertexIndex;for(;;){let i=topRightVertexIndex-1;if(i<0&&(i=numVertices-1),vertices2d[i][1]!==yCoordinate)break;if(i===topLeftVertexIndex)break;topRightVertexIndex=i}let nextLeftVertexIndex=topLeftVertexIndex+1;nextLeftVertexIndex>=numVertices&&(nextLeftVertexIndex=0);let nextRightVertexIndex=topRightVertexIndex-1;nextRightVertexIndex<0&&(nextRightVertexIndex=numVertices-1);const newActivePolygon={polygonIndex:polygonIndex,leftVertexIndex:topLeftVertexIndex,rightVertexIndex:topRightVertexIndex,topLeft:vertices2d[topLeftVertexIndex],topRight:vertices2d[topRightVertexIndex],bottomLeft:vertices2d[nextLeftVertexIndex],bottomRight:vertices2d[nextRightVertexIndex]};insertSorted(activePolygons,newActivePolygon,(el1,el2)=>{const x1=interpolateBetween2DPointsForY(el1.topLeft,el1.bottomLeft,middleYcoordinate),x2=interpolateBetween2DPointsForY(el2.topLeft,el2.bottomLeft,middleYcoordinate);return x1>x2?1:x1<x2?-1:0})}}for(const activePolygonKey in activePolygons){const activePolygon=activePolygons[activePolygonKey];let x=interpolateBetween2DPointsForY(activePolygon.topLeft,activePolygon.bottomLeft,yCoordinate);const topLeft=fromValues$2(x,yCoordinate);x=interpolateBetween2DPointsForY(activePolygon.topRight,activePolygon.bottomRight,yCoordinate);const topRight=fromValues$2(x,yCoordinate);x=interpolateBetween2DPointsForY(activePolygon.topLeft,activePolygon.bottomLeft,nextYcoordinate);const bottomLeft=fromValues$2(x,nextYcoordinate);x=interpolateBetween2DPointsForY(activePolygon.topRight,activePolygon.bottomRight,nextYcoordinate);const bottomRight=fromValues$2(x,nextYcoordinate),outPolygon={topLeft:topLeft,topRight:topRight,bottomLeft:bottomLeft,bottomRight:bottomRight,leftLine:fromPoints$1(create$1(),topLeft,bottomLeft),rightLine:fromPoints$1(create$1(),bottomRight,topRight)};if(newOutPolygonRow.length>0){const prevOutPolygon=newOutPolygonRow[newOutPolygonRow.length-1],d1=distance(outPolygon.topLeft,prevOutPolygon.topRight),d2=distance(outPolygon.bottomLeft,prevOutPolygon.bottomRight);d1<EPS$1&&d2<EPS$1&&(outPolygon.topLeft=prevOutPolygon.topLeft,outPolygon.leftLine=prevOutPolygon.leftLine,outPolygon.bottomLeft=prevOutPolygon.bottomLeft,newOutPolygonRow.splice(newOutPolygonRow.length-1,1))}newOutPolygonRow.push(outPolygon)}if(yIndex>0){const prevContinuedIndexes=new Set,matchedIndexes=new Set;for(let i=0;i<newOutPolygonRow.length;i++){const thisPolygon=newOutPolygonRow[i];for(let ii=0;ii<prevOutPolygonRow.length;ii++)if(!matchedIndexes.has(ii)){const prevPolygon=prevOutPolygonRow[ii];if(distance(prevPolygon.bottomLeft,thisPolygon.topLeft)<EPS$1&&distance(prevPolygon.bottomRight,thisPolygon.topRight)<EPS$1){matchedIndexes.add(ii);const v1=direction$1(thisPolygon.leftLine),v2=direction$1(prevPolygon.leftLine),d1=v1[0]-v2[0],v3=direction$1(thisPolygon.rightLine),v4=direction$1(prevPolygon.rightLine),d2=v3[0]-v4[0],leftLineContinues=Math.abs(d1)<EPS$1,rightLineContinues=Math.abs(d2)<EPS$1;(leftLineContinues||d1>=0)&&(rightLineContinues||d2>=0)&&(thisPolygon.outPolygon=prevPolygon.outPolygon,thisPolygon.leftLineContinues=leftLineContinues,thisPolygon.rightLineContinues=rightLineContinues,prevContinuedIndexes.add(ii));break}}}for(let ii=0;ii<prevOutPolygonRow.length;ii++)if(!prevContinuedIndexes.has(ii)){const prevPolygon=prevOutPolygonRow[ii];prevPolygon.outPolygon.rightPoints.push(prevPolygon.bottomRight),distance(prevPolygon.bottomRight,prevPolygon.bottomLeft)>EPS$1&&prevPolygon.outPolygon.leftPoints.push(prevPolygon.bottomLeft),prevPolygon.outPolygon.leftPoints.reverse();const vertices3d=prevPolygon.outPolygon.rightPoints.concat(prevPolygon.outPolygon.leftPoints).map(point2d=>orthonormalFormula.to3D(point2d)),polygon=fromVerticesAndPlane(vertices3d,plane$1);polygon.vertices.length&&destPolygons.push(polygon)}}for(let i=0;i<newOutPolygonRow.length;i++){const thisPolygon=newOutPolygonRow[i];thisPolygon.outPolygon?(thisPolygon.leftLineContinues||thisPolygon.outPolygon.leftPoints.push(thisPolygon.topLeft),thisPolygon.rightLineContinues||thisPolygon.outPolygon.rightPoints.push(thisPolygon.topRight)):(thisPolygon.outPolygon={leftPoints:[],rightPoints:[]},thisPolygon.outPolygon.leftPoints.push(thisPolygon.topLeft),distance(thisPolygon.topLeft,thisPolygon.topRight)>EPS$1&&thisPolygon.outPolygon.rightPoints.push(thisPolygon.topRight))}prevOutPolygonRow=newOutPolygonRow}return destPolygons})(group);for(let i=0;i<coplanarPolygons.length;i++)destPolygons.push(coplanarPolygons[i])}else destPolygons.push(group)});const result=create$9(destPolygons);return result.isRetesselated=!0,result},classifyPolygons=polygons=>{let clusters=[polygons];const nonCoplanar=[];for(let component=3;component>=0;component--){const maybeCoplanar=[],tolerance=3===component?15e-9:1e-13;clusters.forEach(cluster=>{cluster.sort(byPlaneComponent(component,tolerance));let startIndex=0;for(let i=1;i<cluster.length;i++)cluster[i].plane[component]-cluster[startIndex].plane[component]>tolerance&&(i-startIndex===1?nonCoplanar.push(cluster[startIndex]):maybeCoplanar.push(cluster.slice(startIndex,i)),startIndex=i);cluster.length-startIndex===1?nonCoplanar.push(cluster[startIndex]):maybeCoplanar.push(cluster.slice(startIndex))}),clusters=maybeCoplanar}const result=[];return clusters.forEach(cluster=>{cluster[0]&&(result[cluster[0].index]=cluster)}),nonCoplanar.forEach(polygon=>{result[polygon.index]=polygon}),result},byPlaneComponent=(component,tolerance)=>(a,b)=>a.plane[component]-b.plane[component]>tolerance?1:b.plane[component]-a.plane[component]>tolerance?-1:0;class Node{constructor(parent){this.plane=null,this.front=null,this.back=null,this.polygontreenodes=[],this.parent=parent}invert(){const queue=[this];let node;for(let i=0;i<queue.length;i++){node=queue[i],null!==node.plane&&(node.plane=flip(create$7(),node.plane)),null!==node.front&&queue.push(node.front),null!==node.back&&queue.push(node.back);const temp=node.front;node.front=node.back,node.back=temp}}clipPolygons(polygonTreeNodes,alsoRemoveCoplanarFront){let node,current={node:this,polygonTreeNodes:polygonTreeNodes};const stack=[];do{if(node=current.node,polygonTreeNodes=current.polygonTreeNodes,null!==node.plane){const plane=node.plane,backNodes=[],frontNodes=[],coplanarFrontNodes=alsoRemoveCoplanarFront?backNodes:frontNodes;for(let i=0;i<polygonTreeNodes.length;i++){const treeNode=polygonTreeNodes[i];treeNode.canSplit()&&treeNode.splitByPlane(plane,coplanarFrontNodes,backNodes,frontNodes,backNodes)}null!==node.front&&frontNodes.length>0&&stack.push({node:node.front,polygonTreeNodes:frontNodes});const numBackNodes=backNodes.length;if(null!==node.back&&numBackNodes>0)stack.push({node:node.back,polygonTreeNodes:backNodes});else for(let i=0;i<numBackNodes;i++)backNodes[i].remove()}current=stack.pop()}while(void 0!==current)}clipTo(bsptree,alsoRemoveCoplanarFront){let node=this;const stack=[];do{node.polygontreenodes.length>0&&bsptree.clipPolygons(node.polygontreenodes,alsoRemoveCoplanarFront),null!==node.front&&stack.push(node.front),null!==node.back&&stack.push(node.back),node=stack.pop()}while(void 0!==node)}addPolygonTreeNodes(newPolygonTreeNodes){let current={node:this,polygonTreeNodes:newPolygonTreeNodes};const stack=[];do{const node=current.node,polygonTreeNodes=current.polygonTreeNodes,len=polygonTreeNodes.length;if(0===len){current=stack.pop();continue}if(null===node.plane){let index=0;index=Math.floor(len/2);const bestPoly=polygonTreeNodes[index].getPolygon();node.plane=plane(bestPoly)}const frontNodes=[],backNodes=[];for(let i=0;i<len;++i)polygonTreeNodes[i].splitByPlane(node.plane,node.polygontreenodes,backNodes,frontNodes,backNodes);frontNodes.length>0&&(null===node.front&&(node.front=new Node(node)),len===frontNodes.length&&0===backNodes.length?node.front.polygontreenodes=frontNodes:stack.push({node:node.front,polygonTreeNodes:frontNodes})),backNodes.length>0&&(null===node.back&&(node.back=new Node(node)),len===backNodes.length&&0===frontNodes.length?node.back.polygontreenodes=backNodes:stack.push({node:node.back,polygonTreeNodes:backNodes})),current=stack.pop()}while(void 0!==current)}}const splitLineSegmentByPlane=(plane,p1,p2)=>{const direction=subtract$3([0,0,0],p2,p1);let lambda=(plane[3]-dot$2(plane,p1))/dot$2(plane,direction);return Number.isNaN(lambda)?lambda=0:lambda>1?lambda=1:lambda<0&&(lambda=0),scale$3(direction,direction,lambda),add$1(direction,p1,direction),direction},splitResult={type:0,front:null,back:null};class PolygonTreeNode{constructor(parent,polygon){this.parent=parent,this.polygon=polygon,this.children=[]}addPolygons(polygons){if(!this.isRootNode())throw new Error("PolygonTreeNode01");for(let i=0;i<polygons.length;i++)this.addChild(polygons[i])}remove(){this.polygon=null;const parentschildren=this.parent.children,i=parentschildren.indexOf(this);if(i<0)throw new Error("PolyTreeNode02");parentschildren.splice(i,1),this.parent._recursivelyInvalidatePolygon()}canSplit(){return null!=this.polygon||this.children.length>0}isRootNode(){return!this.parent}invert(){if(!this.isRootNode())throw new Error("PolyTreeNode03");this._invertSub()}getPolygon(){if(null===this.polygon)throw new Error("PolyTreeNode04");return this.polygon}getPolygons(result){let children=[this];const queue=[children];let i,j,l,node;for(i=0;i<queue.length;++i)for(children=queue[i],j=0,l=children.length;j<l;j++)node=children[j],null!==node.polygon?result.push(node.polygon):node.children.length>0&&queue.push(node.children)}getPolygonsNew(result){if(null!==this.polygon)result.push(this.polygon);else for(let i=0;i<this.children.length;i++)this.children[i].getPolygons(result)}splitByPlaneOld(plane,coplanarfrontnodes,coplanarbacknodes,frontnodes,backnodes){if(this.children.length>0){const queue=[this.children];let i,j,l,node,nodes;for(i=0;i<queue.length;i++)for(nodes=queue[i],j=0,l=nodes.length;j<l;j++)node=nodes[j],node.children.length>0?queue.push(node.children):null!==this.polygon&&node._splitByPlane(plane,coplanarfrontnodes,coplanarbacknodes,frontnodes,backnodes)}else null!==this.polygon&&this._splitByPlane(plane,coplanarfrontnodes,coplanarbacknodes,frontnodes,backnodes)}splitByPlane(plane,coplanarFrontNodes,coplanarBackNodes,frontNodes,backNodes){if(this.children.length>0)for(let i=0;i<this.children.length;i++)this.children[i].splitByPlane(plane,coplanarFrontNodes,coplanarBackNodes,frontNodes,backNodes);else null!==this.polygon&&this._splitByPlane(plane,coplanarFrontNodes,coplanarBackNodes,frontNodes,backNodes)}_splitByPlane(splane,coplanarFrontNodes,coplanarBackNodes,frontNodes,backNodes){const bounds=measureBoundingSphereAndCache(this.polygon),sphereRadius=bounds[3]+EPS$1,d=dot$2(splane,bounds)-splane[3];if(d>sphereRadius)frontNodes.push(this);else if(d<-sphereRadius)backNodes.push(this);else switch(((result,splane,polygon)=>{const vertices=polygon.vertices,numVertices=vertices.length,pplane=plane(polygon);if(b=splane,(a=pplane)[0]===b[0]&&a[1]===b[1]&&a[2]===b[2]&&a[3]===b[3])result.type=0;else{let hasFront=!1,hasBack=!1;const vertexIsBack=[],MINEPS=-EPS$1;for(let i=0;i<numVertices;i++){const t=dot$2(splane,vertices[i])-splane[3],isback=t<MINEPS;vertexIsBack.push(isback),t>EPS$1&&(hasFront=!0),t<MINEPS&&(hasBack=!0)}if(hasFront||hasBack)if(hasBack)if(hasFront){const frontVertices=[],backVertices=[];let isback=vertexIsBack[0];for(let vertexIndex=0;vertexIndex<numVertices;vertexIndex++){const vertex=vertices[vertexIndex];let nextVertexIndex=vertexIndex+1;nextVertexIndex>=numVertices&&(nextVertexIndex=0);const nextIsBack=vertexIsBack[nextVertexIndex];if(isback===nextIsBack)isback?backVertices.push(vertex):frontVertices.push(vertex);else{const nextPoint=vertices[nextVertexIndex],intersectionPoint=splitLineSegmentByPlane(splane,vertex,nextPoint);isback?(backVertices.push(vertex),backVertices.push(intersectionPoint),frontVertices.push(intersectionPoint)):(frontVertices.push(vertex),frontVertices.push(intersectionPoint),backVertices.push(intersectionPoint))}isback=nextIsBack}const EPS_SQUARED=EPS$1*EPS$1;if(backVertices.length>=3){let prevVertex=backVertices[backVertices.length-1];for(let vertexIndex=0;vertexIndex<backVertices.length;vertexIndex++){const vertex=backVertices[vertexIndex];squaredDistance$1(vertex,prevVertex)<EPS_SQUARED&&(backVertices.splice(vertexIndex,1),vertexIndex--),prevVertex=vertex}}if(frontVertices.length>=3){let prevVertex=frontVertices[frontVertices.length-1];for(let vertexIndex=0;vertexIndex<frontVertices.length;vertexIndex++){const vertex=frontVertices[vertexIndex];squaredDistance$1(vertex,prevVertex)<EPS_SQUARED&&(frontVertices.splice(vertexIndex,1),vertexIndex--),prevVertex=vertex}}result.type=4,result.front=frontVertices.length>=3?fromVerticesAndPlane(frontVertices,pplane):null,result.back=backVertices.length>=3?fromVerticesAndPlane(backVertices,pplane):null}else result.type=3;else result.type=2;else{const t=dot$2(splane,pplane);result.type=t>=0?0:1}}var a,b})(splitResult,splane,this.polygon),splitResult.type){case 0:coplanarFrontNodes.push(this);break;case 1:coplanarBackNodes.push(this);break;case 2:frontNodes.push(this);break;case 3:backNodes.push(this);break;case 4:if(null!==splitResult.front){const frontNode=this.addChild(splitResult.front);frontNodes.push(frontNode)}if(null!==splitResult.back){const backNode=this.addChild(splitResult.back);backNodes.push(backNode)}}}addChild(polygon){const newChild=new PolygonTreeNode(this,polygon);return this.children.push(newChild),newChild}_invertSub(){let children=[this];const queue=[children];let i,j,l,node;for(i=0;i<queue.length;i++)for(children=queue[i],j=0,l=children.length;j<l;j++)node=children[j],null!==node.polygon&&(node.polygon=invert$1(node.polygon)),node.children.length>0&&queue.push(node.children)}_invertSubNew(){null!==this.polygon&&(this.polygon=invert$1(this.polygon));for(let i=0;i<this.children.length;i++)this.children[i]._invertSub()}_recursivelyInvalidatePolygon(){this.polygon=null,null!==this.parent&&this.parent._recursivelyInvalidatePolygon()}clear(){for(let i=0;i<this.children.length;i++)this.children[i].clear();this.children.length=0,null!==this.polygon&&(this.polygon=null),this.parent=null}toString(){let result="",children=[this];const queue=[children];let i,j,l,node;for(i=0;i<queue.length;++i){children=queue[i];const prefix=" ".repeat(i);for(j=0,l=children.length;j<l;j++)node=children[j],result+=`${prefix}PolygonTreeNode (${node.isRootNode()}): ${node.children.length}`,null!==node.polygon?result+=`\n ${prefix}polygon: ${node.polygon.vertices}\n`:result+="\n",node.children.length>0&&queue.push(node.children)}return result}}class Tree{constructor(polygons){this.polygonTree=new PolygonTreeNode(null,null),this.rootnode=new Node(null),polygons&&this.addPolygons(polygons)}invert(){this.polygonTree.invert(),this.rootnode.invert()}clipTo(tree,alsoRemoveCoplanarFront=!1){this.rootnode.clipTo(tree.rootnode,alsoRemoveCoplanarFront)}allPolygons(){const result=[];return this.polygonTree.getPolygons(result),result}addPolygons(polygons){const polygonTreeNodes=new Array(polygons.length);for(let i=0;i<polygons.length;i++)polygonTreeNodes[i]=this.polygonTree.addChild(polygons[i]);this.rootnode.addPolygonTreeNodes(polygonTreeNodes)}addPolygonsNew(polygons){this.polygonTree.addPolygons(polygons),this.rootnode.addPolygonTreeNodes(this.polygonTree.children)}clear(){this.polygonTree.clear()}toString(){return"Tree: "+this.polygonTree.toString("")}}const unionGeom2=geometries=>{let newGeometry=geometries.shift();return geometries.forEach(geometry=>{newGeometry=boolean(newGeometry,geometry,1)}),newGeometry},unionGeom3Sub=(geometry1,geometry2)=>{if(!((geometry1,geometry2)=>{if(0===geometry1.polygons.length||0===geometry2.polygons.length)return!1;const bounds1=measureBoundingBox(geometry1),min1=bounds1[0],max1=bounds1[1],bounds2=measureBoundingBox(geometry2),min2=bounds2[0],max2=bounds2[1];return!(min2[0]-max1[0]>EPS$1||min1[0]-max2[0]>EPS$1||min2[1]-max1[1]>EPS$1||min1[1]-max2[1]>EPS$1||min2[2]-max1[2]>EPS$1||min1[2]-max2[2]>EPS$1)})(geometry1,geometry2))return unionForNonIntersecting(geometry1,geometry2);const a=new Tree(toPolygons$1(geometry1)),b=new Tree(toPolygons$1(geometry2));a.clipTo(b,!1),b.clipTo(a),b.invert(),b.clipTo(a),b.invert();const newPolygons=a.allPolygons().concat(b.allPolygons());return create$9(newPolygons)},unionForNonIntersecting=(geometry1,geometry2)=>{let newpolygons=toPolygons$1(geometry1);return newpolygons=newpolygons.concat(toPolygons$1(geometry2)),create$9(newpolygons)},union=(...geometries)=>{if(0===(arr=geometries,geometries=flattenHelper(arr,[])).length)return;var arr;if(!(shapes=>{let previousType;for(const shape of shapes){let currentType=0;if(isA$6(shape)&&(currentType=1),isA$4(shape)&&(currentType=2),isA$3(shape)&&(currentType=3),isA$2(shape)&&(currentType=4),isA$1(shape)&&(currentType=5),previousType&¤tType!==previousType)return!1;previousType=currentType}return!0})(geometries))throw new Error("union arguments must be the same geometry type");const geometry=geometries[0];if(isA$6(geometry))return unionGeom2(geometries);if(isA$4(geometry))return(geometries=>{let i;for(i=1;i<geometries.length;i+=2)geometries.push(unionGeom3Sub(geometries[i-1],geometries[i]));let newGeometry=geometries[i-1];return newGeometry=retessellate(newGeometry),newGeometry})(geometries);throw new Error("union unsupported geometry type")},extrudeLinearGeom2=(options,geometry)=>{let{offset:offset,twistAngle:twistAngle,twistSteps:twistSteps,repair:repair}=Object.assign({},{offset:[0,0,1],twistAngle:0,twistSteps:12,repair:!0},options);if(twistSteps<1)throw new Error("twistSteps must be 1 or more");0===twistAngle&&(twistSteps=1);const offsetV=clone$a(offset);let baseSlice=fromOutlines$1(toOutlines(geometry));offsetV[2]<0&&(baseSlice=reverse$3(baseSlice));const matrix=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],output=extrudeFromSlices(options={numberOfSlices:twistSteps+1,capStart:!0,capEnd:!0,repair:repair,callback:(progress,index,base)=>{const Zrotation=index/twistSteps*twistAngle,Zoffset=scale$3([0,0,0],offsetV,index/twistSteps);return multiply$1(matrix,fromZRotation(matrix,Zrotation),fromTranslation([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],Zoffset)),transform$4(matrix,base)}},baseSlice);return geometry.color&&(output.color=geometry.color),output},extrudeLinear=(options,...objects)=>{const{height:height,twistAngle:twistAngle,twistSteps:twistSteps,repair:repair}=Object.assign({},{height:1,twistAngle:0,twistSteps:1,repair:!0},options);options={height:height,twistAngle:twistAngle,twistSteps:twistSteps,repair:repair,offset:[0,0,height]};const results=objects.map(object=>isA$3(object)?((options,geometry)=>{if(!geometry.isClosed)throw new Error("extruded path must be closed");const points=toPoints$1(geometry),geometry2=create$b([points]);return geometry.color&&(geometry2.color=geometry.color),extrudeLinearGeom2(options,geometry2)})(options,object):isA$6(object)?extrudeLinearGeom2(options,object):Array.isArray(object)?extrudeLinear(options,...object):object);return 1===results.length?results[0]:results},aboutEqualNormals=(a,b)=>Math.abs(a[0]-b[0])<=1e-13&&Math.abs(a[1]-b[1])<=1e-13&&Math.abs(a[2]-b[2])<=1e-13,project=(options,...objects)=>{const{axis:axis,origin:origin}=Object.assign({},{axis:[0,0,1],origin:[0,0,0]},options);options={axis:axis,origin:origin};const results=objects.map(object=>isA$4(object)?((options,geometry)=>{const projPlane=fromNormalAndPoint([0,0,0,0],options.axis,options.origin);if(Number.isNaN(projPlane[0])||Number.isNaN(projPlane[1])||Number.isNaN(projPlane[2])||Number.isNaN(projPlane[3]))throw new Error("project: invalid axis or origin");const epsilon=((...geometries)=>{const results=(geometries=flatten(geometries)).map(geometry=>isA$4(geometry)?calculateEpsilonFromBounds(measureBoundingBox(geometry),3):isA$6(geometry)||isA$3(geometry)?calculateEpsilonFromBounds(measureBoundingBox(geometry),2):isA$2(geometry)||isA$1(geometry)?calculateEpsilonFromBounds(measureBoundingBox(geometry),3):0);return 1===results.length?results[0]:results})(geometry),epsilonArea=epsilon*epsilon*Math.sqrt(3)/4;if(0===epsilon)return create$b();const polygons=toPolygons$1(geometry);let projPolys=[];for(let i=0;i<polygons.length;i++){const newVertices=polygons[i].vertices.map(v=>projectionOfPoint(projPlane,v)),newPoly=create$8(newVertices),newPlane=plane(newPoly);aboutEqualNormals(projPlane,newPlane)&&(measureArea$2(newPoly)<epsilonArea||projPolys.push(newPoly))}if(!aboutEqualNormals(projPlane,[0,0,1])){const rotation=fromVectorRotation([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],projPlane,[0,0,1]);projPolys=projPolys.map(p=>transform$9(rotation,p))}projPolys=projPolys.sort((a,b)=>measureArea$2(b)-measureArea$2(a));const projGeoms=projPolys.map(p=>{const cloned=p.vertices.map(clone$9);return create$b([cloned])}),output=unionGeom2(projGeoms);return geometry.color&&(output.color=geometry.color),output})(options,object):Array.isArray(object)?project(options,...object):object);return 1===results.length?results[0]:results};Object.freeze({__proto__:null,extrudeFromSlices:extrudeFromSlices,extrudeHelical:(options,geometry)=>{const defaults={angle:TAU,startAngle:0,pitch:10,endOffset:0,segmentsPerRotation:32},{angle:angle,endOffset:endOffset,segmentsPerRotation:segmentsPerRotation,startAngle:startAngle}=Object.assign({},defaults,options);let pitch;if(pitch=!options.pitch&&options.height?options.height/(angle/TAU):options.pitch?options.pitch:defaults.pitch,segmentsPerRotation<3)throw new Error("The number of segments per rotation needs to be at least 3.");let baseSlice=fromOutlines$1(toOutlines(geometry));measureBoundingBox(geometry)[1][0]<=0&&(baseSlice=reverse$3(baseSlice));const calculatedSegments=Math.round(segmentsPerRotation/TAU*Math.abs(angle)),segments=calculatedSegments>=2?calculatedSegments:2,step1=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1];let matrix;return extrudeFromSlices({numberOfSlices:segments+1,callback:(progress,index,base)=>{const zRotation=startAngle+angle/segments*index;return multiply$1(step1,fromTranslation([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],[endOffset/segments*index,0,(zRotation-startAngle)/TAU*pitch*Math.sign(angle)]),fromXRotation([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],-TAU/4*Math.sign(angle))),matrix=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],multiply$1(matrix,fromZRotation([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],zRotation),step1),transform$4(matrix,baseSlice)}},baseSlice)},extrudeLinear:extrudeLinear,extrudeRotate:(options,geometry)=>{const defaults={segments:12,startAngle:0,angle:TAU,overflow:"cap"};let{segments:segments,startAngle:startAngle,angle:angle,overflow:overflow}=Object.assign({},defaults,options);if(segments<3)throw new Error("segments must be greater then 3");startAngle=Math.abs(startAngle)>TAU?startAngle%TAU:startAngle,angle=Math.abs(angle)>TAU?angle%TAU:angle;let endAngle=startAngle+angle;if(endAngle=Math.abs(endAngle)>TAU?endAngle%TAU:endAngle,endAngle<startAngle){const x=startAngle;startAngle=endAngle,endAngle=x}let totalRotation=endAngle-startAngle;if(totalRotation<=0&&(totalRotation=TAU),Math.abs(totalRotation)<TAU){const anglePerSegment=TAU/segments;segments=Math.floor(Math.abs(totalRotation)/anglePerSegment),Math.abs(totalRotation)>segments*anglePerSegment&&segments++}let shapeSides=toSides(geometry);if(0===shapeSides.length)return create$9();let sliceGeometry=geometry;const pointsWithNegativeX=shapeSides.filter(s=>s[0][0]<0),pointsWithPositiveX=shapeSides.filter(s=>s[0][0]>=0);pointsWithNegativeX.length>0&&pointsWithPositiveX.length>0&&"cap"===overflow&&(pointsWithNegativeX.length>pointsWithPositiveX.length?(shapeSides=shapeSides.map(side=>{let point0=side[0],point1=side[1];return point0=[Math.min(point0[0],0),point0[1]],point1=[Math.min(point1[0],0),point1[1]],[point0,point1]}),sliceGeometry=fromSides(shapeSides),sliceGeometry=((...objects)=>mirror({normal:[1,0,0]},...objects))(sliceGeometry)):pointsWithPositiveX.length>=pointsWithNegativeX.length&&(shapeSides=shapeSides.map(side=>{let point0=side[0],point1=side[1];return point0=[Math.max(point0[0],0),point0[1]],point1=[Math.max(point1[0],0),point1[1]],[point0,point1]}),sliceGeometry=fromSides(shapeSides)));const rotationPerSlice=totalRotation/segments,isCapped=Math.abs(totalRotation)<TAU;let baseSlice=fromOutlines$1(toOutlines(sliceGeometry));baseSlice=reverse$3(baseSlice);const matrix=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],xRotationMatrix=fromXRotation([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],TAU/4),output=extrudeFromSlices(options={numberOfSlices:segments+1,capStart:isCapped,capEnd:isCapped,close:!isCapped,callback:(progress,index,base)=>{let Zrotation=rotationPerSlice*index+startAngle;return totalRotation===TAU&&index===segments&&(Zrotation=startAngle),multiply$1(matrix,fromZRotation(matrix,Zrotation),xRotationMatrix),transform$4(matrix,base)}},baseSlice);return geometry.color&&(output.color=geometry.color),output},project:project});const offsetFromPoints=(options,points)=>{let{delta:delta,corners:corners,closed:closed,segments:segments}=Object.assign({},{delta:1,corners:"edge",closed:!1,segments:16},options);if(Math.abs(delta)<EPS$1)return points;if(points.length<2)return points;let rotation=options.closed?area(points):1;0===rotation&&(rotation=1);const orientation=rotation>0&&delta>=0||rotation<0&&delta<0;delta=Math.abs(delta);let previousSegment=null,newPoints=[];const newCorners=[],of=[0,0],n=points.length;for(let i=0;i<n;i++){const j=(i+1)%n,p0=points[i],p1=points[j];orientation?subtract$1(of,p0,p1):subtract$1(of,p1,p0),normal(of,of),normalize(of,of),scale$1(of,of,delta);const n0=add(create$a(),p0,of),n1=add(create$a(),p1,of),currentSegment=[n0,n1];if(null!=previousSegment&&(closed||!closed&&0!==j)){const ip=intersect$1(previousSegment[0],previousSegment[1],currentSegment[0],currentSegment[1],!0);ip?(newPoints.pop(),currentSegment[0]=ip):newCorners.push({c:p0,s0:previousSegment,s1:currentSegment})}previousSegment=[n0,n1],(0!==j||closed)&&(newPoints.push(currentSegment[0]),newPoints.push(currentSegment[1]))}if(closed&&null!=previousSegment){const n0=newPoints[0],n1=newPoints[1],ip=intersect$1(previousSegment[0],previousSegment[1],n0,n1,!0);if(ip)newPoints[0]=ip,newPoints.pop();else{const p0=points[0],currentSegment=[n0,n1];newCorners.push({c:p0,s0:previousSegment,s1:currentSegment})}}if("edge"===corners){const pointIndex=new Map;newPoints.forEach((point,index)=>pointIndex.set(point,index));const line0=[0,1,0],line1=[0,1,0];newCorners.forEach(corner=>{fromPoints$1(line0,corner.s0[0],corner.s0[1]),fromPoints$1(line1,corner.s1[0],corner.s1[1]);const ip=((line1,line2)=>{const point=((a,b,c,d,u,v)=>{const invdet=1/(a*d-b*c);let x=u*d-b*v,y=-u*c+a*v;return x*=invdet,y*=invdet,[x,y]})(line1[0],line1[1],line2[0],line2[1],line1[2],line2[2]);return clone$9(point)})(line0,line1);if(Number.isFinite(ip[0])&&Number.isFinite(ip[1])){const p0=corner.s0[1],i=pointIndex.get(p0);newPoints[i]=ip,newPoints[(i+1)%newPoints.length]=void 0}else{const p0=corner.s1[0],i=pointIndex.get(p0);newPoints[i]=void 0}}),newPoints=newPoints.filter(p=>void 0!==p)}if("round"===corners){let cornerSegments=Math.floor(segments/4);const v0=[0,0];newCorners.forEach(corner=>{let rotation=angleRadians(subtract$1(v0,corner.s1[0],corner.c));if(rotation-=angleRadians(subtract$1(v0,corner.s0[1],corner.c)),orientation&&rotation<0&&(rotation+=Math.PI,rotation<0&&(rotation+=Math.PI)),!orientation&&rotation>0&&(rotation-=Math.PI,rotation>0&&(rotation-=Math.PI)),0!==rotation){cornerSegments=Math.floor(segments*(Math.abs(rotation)/TAU));const step=rotation/cornerSegments,start=angleRadians(subtract$1(v0,corner.s0[1],corner.c)),cornerPoints=[];for(let i=1;i<cornerSegments;i++){const radians=start+step*i,point=fromAngleRadians(create$a(),radians);scale$1(point,point,delta),add(point,point,corner.c),cornerPoints.push(point)}if(cornerPoints.length>0){const p0=corner.s0[1];let i=newPoints.findIndex(point=>equals$7(p0,point));i=(i+1)%newPoints.length,newPoints.splice(i,0,...cornerPoints)}}else{const p0=corner.s1[0],i=newPoints.findIndex(point=>equals$7(p0,point));newPoints.splice(i,1)}})}return newPoints},mapPlaneToVertex=(map,vertex,plane)=>{const key=vertex.toString();if(map.has(key))map.get(key)[1].push(plane);else{const entry=[vertex,[plane]];map.set(key,entry)}},mapPlaneToEdge=(map,edge,plane)=>{const key0=edge[0].toString(),key1=edge[1].toString(),key=key0<key1?`${key0},${key1}`:`${key1},${key0}`;if(map.has(key))map.get(key)[1].push(plane);else{const entry=[edge,[plane]];map.set(key,entry)}},addUniqueAngle=(map,angle)=>{map.findIndex(item=>item===angle)<0&&map.push(angle)},offset=(options,...objects)=>{const results=objects.map(object=>isA$3(object)?((options,geometry)=>{const{delta:delta,corners:corners,segments:segments}=Object.assign({},{delta:1,corners:"edge",segments:16},options);if(delta<=0)throw new Error("the given delta must be positive for paths");if("edge"!==corners&&"chamfer"!==corners&&"round"!==corners)throw new Error('corners must be "edge", "chamfer", or "round"');const closed=geometry.isClosed,points=toPoints$1(geometry),paths={points:points,external:offsetFromPoints({delta:delta,corners:corners,segments:segments,closed:closed},points),internal:offsetFromPoints({delta:-delta,corners:corners,segments:segments,closed:closed},points)},output=geometry.isClosed?(paths=>{let{external:external,internal:internal}=paths;return external.length<2?create$b():(area(external)<0?external=external.reverse():internal=internal.reverse(),create$b([external,internal]))})(paths):((paths,segments,corners,delta)=>{const{points:points,external:external,internal:internal}=paths;if(0===points.length)return create$b();if(1===points.length)return circle({center:points[0],radius:delta});const capSegments=Math.floor(segments/2),e2iCap=[],i2eCap=[];if("round"===corners&&capSegments>0){const step=Math.PI/capSegments,eCorner=points[points.length-1],e2iStart=angleRadians(subtract$1([0,0],external[external.length-1],eCorner)),iCorner=points[0],i2eStart=angleRadians(subtract$1([0,0],internal[0],iCorner));for(let i=1;i<capSegments;i++){let radians=e2iStart+step*i,point=fromAngleRadians(create$a(),radians);scale$1(point,point,delta),add(point,point,eCorner),e2iCap.push(point),radians=i2eStart+step*i,point=fromAngleRadians(create$a(),radians),scale$1(point,point,delta),add(point,point,iCorner),i2eCap.push(point)}}const allPoints=[];return allPoints.push(...external,...e2iCap,...internal.reverse(),...i2eCap),create$b([allPoints])})(paths,segments,corners,delta);return geometry.color&&(output.color=geometry.color),output})(options,object):isA$6(object)?((options,geometry)=>{const{delta:delta,corners:corners,segments:segments,expandHoles:expandHoles}=Object.assign({},{delta:1,corners:"edge",segments:16,expandHoles:!1},options);if("edge"!==corners&&"chamfer"!==corners&&"round"!==corners)throw new Error('corners must be "edge", "chamfer", or "round"');if(!Number.isFinite(delta))throw new Error("delta must be a finite number");if("round"===corners&&!Number.isFinite(segments))throw new Error("segments must be a finite number");if("round"===corners&&!(segments>0))throw new Error("segments must be greater than zero");const outlines=toOutlines(geometry),newOutlines=outlines.map(outline=>{let outside=!0;return expandHoles&&(outside=outlines.reduce((acc,polygon)=>acc+arePointsInside(outline,create$3(polygon)),0)%2==0),offsetFromPoints(options={delta:outside?delta:-delta,corners:corners,closed:!0,segments:segments},outline)}),output=create$b(newOutlines);return geometry.color&&(output.color=geometry.color),output})(options,object):isA$4(object)?((options,geometry)=>{const{delta:delta,corners:corners,segments:segments}=Object.assign({},{delta:1,corners:"round",segments:12},options);if("round"!==corners)throw new Error('corners must be "round" for 3D geometries');const expanded=((options,geometry)=>{const{delta:delta,segments:segments}=Object.assign({},{delta:1,segments:12},options);let result=create$9();const vertices2planes=new Map,edges2planes=new Map,v1=[0,0,0],v2=[0,0,0];return toPolygons$1(geometry).forEach(polygon=>{const extrudeVector=scale$3([0,0,0],plane(polygon),2*delta),extrudedFace=((offsetVector,polygon1)=>{dot$2(plane(polygon1),offsetVector)>0&&(polygon1=invert$1(polygon1));const newPolygons=[polygon1],polygon2=transform$9(fromTranslation([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],offsetVector),polygon1),numVertices=polygon1.vertices.length;for(let i=0;i<numVertices;i++){const nexti=i<numVertices-1?i+1:0,sideFacePolygon=create$8([polygon1.vertices[i],polygon2.vertices[i],polygon2.vertices[nexti],polygon1.vertices[nexti]]);newPolygons.push(sideFacePolygon)}return newPolygons.push(invert$1(polygon2)),create$9(newPolygons)})(extrudeVector,transform$9(fromTranslation([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],scale$3([0,0,0],extrudeVector,-.5)),polygon));result=unionGeom3Sub(result,extrudedFace);const vertices=polygon.vertices;for(let i=0;i<vertices.length;i++){mapPlaneToVertex(vertices2planes,vertices[i],plane(polygon));const j=(i+1)%vertices.length,edge=[vertices[i],vertices[j]];mapPlaneToEdge(edges2planes,edge,plane(polygon))}}),edges2planes.forEach(item=>{const edge=item[0],planes=item[1],startVertex=edge[0],endVertex=edge[1],zBase=subtract$3([0,0,0],endVertex,startVertex);normalize$1(zBase,zBase);const xBase=planes[0],yBase=cross$1([0,0,0],xBase,zBase);let angles=[];for(let i=0;i<segments;i++)addUniqueAngle(angles,i*TAU/segments);for(let i=0,iMax=planes.length;i<iMax;i++){const planeNormal=planes[i],si=dot$2(yBase,planeNormal),co=dot$2(xBase,planeNormal);let angle=Math.atan2(si,co);angle<0&&(angle+=TAU),addUniqueAngle(angles,angle),angle=Math.atan2(-si,-co),angle<0&&(angle+=TAU),addUniqueAngle(angles,angle)}angles=angles.sort(fnNumberSort);const numAngles=angles.length;let prevP1,prevP2;const startFaceVertices=[],endFaceVertices=[],polygons=[];for(let i=-1;i<numAngles;i++){const angle=angles[i<0?i+numAngles:i],si=Math.sin(angle),co=Math.cos(angle);scale$3(v1,xBase,co*delta),scale$3(v2,yBase,si*delta),add$1(v1,v1,v2);const p1=add$1(create$c(),startVertex,v1),p2=add$1(create$c(),endVertex,v1);let skip=!1;if(i>=0&&distance$1(p1,prevP1)<EPS$1&&(skip=!0),!skip){if(i>=0){startFaceVertices.push(p1),endFaceVertices.push(p2);const polygon=create$8([prevP2,p2,p1,prevP1]);polygons.push(polygon)}prevP1=p1,prevP2=p2}}endFaceVertices.reverse(),polygons.push(create$8(startFaceVertices)),polygons.push(create$8(endFaceVertices));const cylinder=create$9(polygons);result=unionGeom3Sub(result,cylinder)}),vertices2planes.forEach(item=>{const vertex=item[0],planes=item[1],xaxis=planes[0];let bestzaxis=null,bestzaxisOrthogonality=0;for(let i=1;i<planes.length;i++){const normal=planes[i],cross=cross$1(v1,xaxis,normal),crossLength=length$2(cross);crossLength>.05&&crossLength>bestzaxisOrthogonality&&(bestzaxisOrthogonality=crossLength,bestzaxis=normal)}bestzaxis||(bestzaxis=orthogonal(v1,xaxis));const yaxis=cross$1(v1,xaxis,bestzaxis);normalize$1(yaxis,yaxis);const zaxis=cross$1(v2,yaxis,xaxis),corner=sphere({center:[vertex[0],vertex[1],vertex[2]],radius:delta,segments:segments,axes:[xaxis,yaxis,zaxis]});result=unionGeom3Sub(result,corner)}),retessellate(result)})(options={delta:delta,corners:corners,segments:segments},geometry),output=union(geometry,expanded);return geometry.color&&(output.color=geometry.color),output})(options,object):Array.isArray(object)?offset(options,...object):object);return 1===results.length?results[0]:results};Object.freeze({__proto__:null,offset:offset,offsetFromPoints:offsetFromPoints});const findLayer=(obj,layers)=>{const lname=obj.lnam||"0";for(const layer of layers)if(layer.name===lname)return layer;return null},getColorNumber=(obj,layers)=>{let cn=obj.cnmb||-1;if(256===cn){cn=-1;const layer=findLayer(obj,layers);null!==layer&&(cn=layer.cnmb||-1)}return cn},getColor=(index,colorindex)=>{if(index<1)return null;index=((num,mod)=>{const remain=num%mod;return Math.floor(remain>=0?remain:remain+mod)})(index,colorindex.length);const color=colorindex[index];return[color[0]/255,color[1]/255,color[2]/255,color[3]/255]},instantiatePolygon=(obj,layers,options)=>{const vertices=[];if(vertices.push(index$k.fromValues(obj.pptx,obj.ppty,obj.pptz)),vertices.push(index$k.fromValues(obj.sptx,obj.spty,obj.sptz)),vertices.push(index$k.fromValues(obj.tptx,obj.tpty,obj.tptz)),obj.fptx){let pushit=!1;obj.tptx!==obj.fptx&&(pushit=!0),obj.tpty!==obj.fpty&&(pushit=!0),obj.tptz!==obj.fptz&&(pushit=!0),pushit&&vertices.push(index$k.fromValues(obj.fptx,obj.fpty,obj.fptz))}const cn=getColorNumber(obj,layers),color=getColor(cn,options.colorindex),polygon=poly3.create(vertices);return color&&(polygon.color=color),polygon},instantiateLine=(obj,layers,options)=>{if(obj.pptz===obj.sptz&&0===obj.pptz){const p1=index$i.fromValues(obj.pptx,obj.ppty),p2=index$i.fromValues(obj.sptx,obj.spty);return line([p1,p2])}const p1=index$k.fromValues(obj.pptx,obj.ppty,obj.pptz),p2=index$k.fromValues(obj.sptx,obj.spty,obj.sptz);return line([p1,p2])},instantiateVector=obj=>{const d3line=parseInt("00000000000100000",2),d3mesh=parseInt("00000000001000000",2),d3face=parseInt("00000000010000000",2),flags=obj.lflg,vtype={};return(flags&d3line)===d3line||(flags&d3mesh)===d3mesh?vtype.vec=index$k.fromValues(obj.pptx,obj.ppty,obj.pptz):(flags&d3face)===d3face?(vtype.vec=index$k.fromValues(obj.pptx,obj.ppty,obj.pptz),vtype.fvia=obj.fvia,vtype.fvib=obj.fvib,vtype.fvic=obj.fvic,vtype.fvid=obj.fvid):(vtype.vec=index$i.fromValues(obj.pptx,obj.ppty),vtype.bulg=obj.bulg),vtype},addSection=(path,x1,y1,bulg)=>{if(0===bulg)path=path2.appendPoints([[x1,y1]],path);else{const points=path2.toPoints(path),prev=points[points.length-1],curr=index$i.fromValues(x1,y1),r=index$i.distance(prev,curr)*((1+Math.pow(bulg,2))/(4*bulg)),clockwise=bulg<0,large=!1,d=4*Math.atan(bulg),res=16;path=path2.appendArc({endpoint:[x1,y1],radius:[r,r],xaxisrotation:d,clockwise:clockwise,large:large,segments:res},path)}return path},instantiatePath2D=(obj,layers,options)=>{const closed=parseInt("00000000000000001",2),vlen=obj.vlen,pptxs=obj.pptxs,pptys=obj.pptys,bulgs=obj.bulgs,flags=obj.lflg;let path=path2.create();const isclosed=(flags&closed)===closed;return vlen!==pptxs.length||vlen!==pptys.length||vlen!==bulgs.length||(pptxs.forEach((item,index,array)=>{let bulg=0;index>0&&(bulg=bulgs[index-1]),path=addSection(path,pptxs[index],pptys[index],bulg)}),isclosed&&!path.isClosed&&(path=addSection(path,pptxs[0],pptys[0],bulgs[vlen-1]),path=path2.close(path))),path},instantiateArc=(obj,layers,options)=>{obj.lthk;const pptx=obj.pptx,ppty=obj.ppty,swid=obj.swid;let ang0=obj.ang0;ang0*=.017453292519943295;let ang1=obj.ang1;return ang1*=.017453292519943295,arc({center:[pptx,ppty],radius:swid,startAngle:ang0,endAngle:ang1,segments:16})},instantiateCircle=(obj,layers,options)=>{const lthk=obj.lthk,pptx=obj.pptx,ppty=obj.ppty,swid=obj.swid,cn=getColorNumber(obj,layers),color=getColor(cn,options.colorindex);if(0===lthk){const cag=circle({center:[pptx,ppty],radius:swid,segments:16});return color&&(cag.color=color),cag}const csg=circle({center:[pptx,ppty],radius:swid,segments:16}).extrude({offset:[0,0,lthk]});return color&&(csg.color=color),csg},instantiateEllipse=(obj,layers,options)=>{const pptx=obj.pptx,ppty=obj.ppty,pptz=obj.pptz,sptx=obj.sptx,spty=obj.spty,sptz=obj.sptz,swid=obj.swid;if(0===pptz&&0===sptz){const center=index$i.fromValues(0,0),mjaxis=index$i.fromValues(sptx,spty),rx=index$i.distance(center,mjaxis),ry=rx*swid;let angle=180*Math.atan2(spty,sptx)/Math.PI;angle<1e-5&&(angle=0),angle*=.017453292519943295;const cag=ellipse({center:[0,0],radius:[rx,ry],segments:16}),matrix=index$j.fromZRotation(index$j.create(),angle);return index$j.multiply(matrix,matrix,index$j.fromTranslation(index$j.create(),[pptx,ppty,0])),geom2.transform(matrix,cag)}},instantiateMesh=(obj,layers,options)=>{const vlen=obj.vlen,pptxs=obj.pptxs,pptys=obj.pptys,pptzs=obj.pptzs,flen=obj.flen,fvals=obj.fvals,cn=getColorNumber(obj,layers),color=getColor(cn,options.colorindex),polygons=[];if(vlen===pptxs.length&&vlen===pptys.length&&vlen===pptzs.length&&flen===fvals.length){const faces=(fvals=>{const faces=[];let vi=0;for(;vi<fvals.length;){let fi=fvals[vi++];const face=[];for(;fi>0;)face.push(fvals[vi++]),fi--;faces.push(face)}return faces})(fvals),points=((pptxs,pptys,pptzs)=>{const points=[];let vi=0;for(;vi<pptxs.length;){const x=pptxs[vi],y=pptys[vi],z=pptzs[vi];points.push([x,y,z]),vi++}return points})(pptxs,pptys,pptzs);let fi=0;for(;fi<faces.length;){const face=faces[fi];let vertices=[],vi=0;for(;vi<face.length;){const pi=face[vi],vertex=index$k.clone(points[pi]);vertices.push(vertex),vi++}1===options.dxf.angdir&&(vertices=vertices.reverse());const poly=poly3.create(vertices);color&&(poly.color=color),polygons.push(poly),fi++}}return geom3.create(polygons)},getPolyType$1=obj=>{const closedM=parseInt("00000000000000001",2),d3line=parseInt("00000000000001000",2),d3mesh=parseInt("00000000000010000",2),closedN=parseInt("00000000000100000",2),d3face=parseInt("00000000001000000",2),flags=obj.lflg;let ptype=null;return(flags&d3line)===d3line?ptype=null:(flags&d3mesh)===d3mesh||(flags&d3face)===d3face?(ptype=geom3.create(),ptype.closedM=(flags&closedM)===closedM,ptype.closedN=(flags&closedN)===closedN):(ptype=path2.create(),ptype.closedM=(flags&closedM)===closedM),"cnmb"in obj&&(ptype.cnmb=obj.cnmb),ptype},completeCurrent=(objects,baseobj,polygons,vectors,options)=>{if(path2.isA(baseobj)){const points=vectors.map(vector=>vector.vec);objects.push(path2.fromPoints({closed:baseobj.closed},points))}return geom3.isA(baseobj)&&objects.push(geom3.create(polygons)),null},translateVector2D=vector=>`${vector[0]},${vector[1]}`,translateVector3D=vector=>`${vector[0]},${vector[1]},${vector[2]}`,translatePolygon=polygon=>{const vertices=poly3.toVertices(polygon);let script="createPolygon([";return vertices.forEach(vertice=>{script+=`[${translateVector3D(vertice)}],`}),script+=`],${translateColor(polygon)})`,script},translateColor=polygon=>{let script="null";if("color"in polygon){const rgb=polygon.color;script=`[${rgb[0]},${rgb[1]},${rgb[2]},${rgb[3]}]`}return script},translateLine=(obj,layers,options)=>{const name=obj.name,cn=getColorNumber(obj,layers),color=getColor(cn,options.colorindex);let script="";if(!obj.pptz||obj.pptz===obj.sptz&&0===obj.pptz){const p1=index$i.fromValues(obj.pptx,obj.ppty),p2=index$i.fromValues(obj.sptx,obj.spty);script=` let ${name} = line([[${translateVector2D(p1)}],[${translateVector2D(p2)}]])\n`}else{const p1=index$k.fromValues(obj.pptx,obj.ppty,obj.pptz),p2=index$k.fromValues(obj.sptx,obj.spty,obj.sptz);script=` let ${name} = line([[${translateVector3D(p1)}],[${translateVector3D(p2)}]])\n`}color&&(script+=` ${name} = colorize([${color[0]}, ${color[1]}, ${color[2]}, 1], ${name})\n`),obj.script=script,addToLayer(obj,layers)},translateSection=(name,x1,y1,bulg,px,py)=>{if(0===bulg)return`path2.appendPoints([[${x1},${y1}]], ${name})\n`;const prev=index$i.fromValues(px,py),curr=index$i.fromValues(x1,y1),r=index$i.distance(prev,curr)*((1+Math.pow(bulg,2))/(4*bulg)),clockwise=bulg<0;return`path2.appendArc({endpoint: [${x1},${y1}],radius: [${r},${r}],xaxisrotation: ${4*Math.atan(bulg)},clockwise: ${clockwise},large: false,segments: 16}, ${name})\n`},translatePath2D=(obj,layers,options)=>{const closed=parseInt("00000000000000001",2),vlen=obj.vlen,pptxs=obj.pptxs,pptys=obj.pptys,bulgs=obj.bulgs,flags=obj.lflg,name=obj.name,cn=getColorNumber(obj,layers),color=getColor(cn,options.colorindex);let script=` let ${name} = path2.create()\n`;const isclosed=(flags&closed)===closed;if(vlen===pptxs.length&&vlen===pptys.length&&vlen===bulgs.length){script+=` ${name} = path2.appendPoints([[${pptxs[0]}, ${pptys[0]}]], ${name})\n`;for(let i=0;i<pptxs.length;i++){const j=(i+1)%pptxs.length,cx=pptxs[j],cy=pptys[j],px=pptxs[i],py=pptys[i],bulg=bulgs[i];(0!==j||0!==bulg)&&(script+=` ${name} = ${translateSection(name,cx,cy,bulg,px,py)}`)}script+=isclosed?` ${name} = path2.close(${name})\n`:"\n",color&&(script+=` ${name} = colorize([${color[0]}, ${color[1]}, ${color[2]}, 1], ${name})\n`),obj.script=script,addToLayer(obj,layers)}},translateArc=(obj,layers,options)=>{const lthk=obj.lthk,pptx=obj.pptx,ppty=obj.ppty,swid=obj.swid;let ang0=obj.ang0,ang1=obj.ang1;const name=obj.name,cn=getColorNumber(obj,layers),color=getColor(cn,options.colorindex);if(ang0*=.017453292519943295,ang1*=.017453292519943295,0===lthk){let script=` let ${name} = arc({center: [${pptx}, ${ppty}], radius: ${swid}, startAngle: ${ang0}, endAngle: ${ang1}, segements: 16})\n`;return color&&(script+=` ${name} = colorize([${color[0]}, ${color[1]}, ${color[2]}, 1], ${name})\n`),obj.script=script,void addToLayer(obj,layers)}let script=` let ${name} = arc({center: [${pptx}, ${ppty}], radius: ${swid}, startAngle: ${ang0}, endAngle: ${ang1}, segements: 16})\n`;color&&(script+=` ${name} = colorize([${color[0]}, ${color[1]}, ${color[2]}, 1], ${name})\n`),obj.script=script,addToLayer(obj,layers)},translateCircle=(obj,layers,options)=>{const lthk=obj.lthk,pptx=obj.pptx,ppty=obj.ppty,swid=obj.swid,name=obj.name,cn=getColorNumber(obj,layers),color=getColor(cn,options.colorindex);if(0===lthk){let script=` let ${name} = circle({center: [${pptx}, ${ppty}], radius: ${swid}, segments: 16})\n`;return color&&(script+=` ${name} = colorize([${color[0]}, ${color[1]}, ${color[2]}, 1], ${name})\n`),obj.script=script,void addToLayer(obj,layers)}let script=` let ${name} = circle({center: [${pptx}, ${ppty}], radius: ${swid}, segments: 16}).extrude({offset: [0,0,${lthk}]}))\n`;color&&(script+=` ${name} = colorize([${color[0]}, ${color[1]}, ${color[2]}, 1], ${name})\n`),obj.script=script,addToLayer(obj,layers)},translateEllipse=(obj,layers,options)=>{const pptx=obj.pptx,ppty=obj.ppty,pptz=obj.pptz,sptx=obj.sptx,spty=obj.spty,sptz=obj.sptz,swid=obj.swid,name=obj.name,cn=getColorNumber(obj,layers),color=getColor(cn,options.colorindex);if(0===pptz&&0===sptz){const center=index$i.fromValues(0,0),mjaxis=index$i.fromValues(sptx,spty),rx=index$i.distance(center,mjaxis);let script=` let ${name} = ellipse({center: [0, 0, 0], radius: [${rx}, ${rx*swid}], segments: 16})\n let ${name}matrix = mat4.multiply(mat4.create(), mat4.fromTranslation(mat4.create(), [${pptx}, ${ppty}, 0]), mat4.fromZRotation(mat4.create(), ${Math.atan2(spty,sptx)}))\n ${name} = geom2.transform(${name}matrix, ${name})\n`;color&&(script+=` ${name} = colorize([${color[0]}, ${color[1]}, ${color[2]}, 1], ${name})\n`),obj.script=script,addToLayer(obj,layers)}},translateMesh=(obj,layers,options)=>{const vlen=obj.vlen,pptxs=obj.pptxs,pptys=obj.pptys,pptzs=obj.pptzs,flen=obj.flen,fvals=obj.fvals,cn=getColorNumber(obj,layers),color=getColor(cn,options.colorindex),polygons=[];if(vlen===pptxs.length&&vlen===pptys.length&&vlen===pptzs.length)if(flen===fvals.length){const faces=(fvals=>{const faces=[];let vi=0;for(;vi<fvals.length;){let fi=fvals[vi++];const face=[];for(;fi>0;)face.push(fvals[vi++]),fi--;faces.push(face)}return faces})(fvals),points=((pptxs,pptys,pptzs)=>{const points=[];let vi=0;for(;vi<pptxs.length;){const x=pptxs[vi],y=pptys[vi],z=pptzs[vi];points.push([x,y,z]),vi++}return points})(pptxs,pptys,pptzs);let fi=0;for(;fi<faces.length;){const face=faces[fi];let vertices=[],vi=0;for(;vi<face.length;){const pi=face[vi],vector=index$k.clone(points[pi]);vertices.push(vector),vi++}1===options.dxf.angdir&&(vertices=vertices.reverse());const poly=poly3.create(vertices);color&&(poly.color=color),polygons.push(poly),fi++}}else console.warn("invalid mesh: faces");else console.warn("invalid mesh: vertices");const name=obj.name;let script=` const ${name}_polygons = [\n`;for(const polygon of polygons)script+=" "+translatePolygon(polygon)+",\n";return script+=` ]\n let ${name} = geom3.create(${name}_polygons)\n`,obj.script=script,addToLayer(obj,layers),null},addToLayer=(obj,layers)=>{let layer=findLayer(obj,layers);null===layer&&(layer=(layers=>{for(const layer of layers)if("0"===layer.name)return layer;const layer={type:"layer",lnam:"layer0",name:"0",lscl:1,visb:0,spac:0,objects:[]};return layers.push(layer),layer})(layers)),"objects"in layer||(layer.objects=[]),layer.objects.push(obj)},getPolyType=obj=>{const closedM=parseInt("00000000000000001",2),d3line=parseInt("00000000000001000",2),d3mesh=parseInt("00000000000010000",2),closedN=parseInt("00000000000100000",2),d3face=parseInt("00000000001000000",2),flags=obj.lflg;let ptype=null;return(flags&d3line)===d3line?ptype={type:"3dline",isclosed:(flags&closedM)===closedM}:(flags&d3mesh)===d3mesh?(ptype={type:"3dpolymesh"},ptype.fvia=obj.fvia,ptype.fvib=obj.fvib,ptype.closedM=(flags&closedM)===closedM,ptype.closedN=(flags&closedN)===closedN):(flags&d3face)===d3face?(ptype={type:"3dpolyfaces"},ptype.fvia=obj.fvia,ptype.fvib=obj.fvib):ptype={type:"2dline",isclosed:(flags&closedM)===closedM},"cnmb"in obj&&(ptype.cnmb=obj.cnmb),"lnam"in obj&&(ptype.lnam=obj.lnam),ptype},translateCurrent=(obj,layers,parts,options)=>{if(null===obj)return null;const type=obj.type,cn=getColorNumber(obj,layers),color=getColor(cn,options.colorindex);if("2dline"===type)return((obj,layers,parts,options)=>{obj.vlen=parts.length,obj.pptxs=[],obj.pptys=[],obj.bulgs=[];for(const part of parts)obj.pptxs.push(part.vec[0]),obj.pptys.push(part.vec[1]),obj.bulgs.push(part.bulg);return obj.isclosed?obj.lflg=parseInt("00000000000000001",2):obj.lflg=0,translatePath2D(obj,layers,options),null})(obj,layers,parts,options);if("3dline"===type)return null;if("3dpolymesh"===type){const facets=((meshM,meshN,parts,color,options)=>{const getVector=(x,y)=>parts[(x-1)*meshN+(y-1)].vec,facets=[];if(meshM*meshN!==parts.length)return facets;if(meshM<2|meshN<2)return facets;let i=1;for(;i<meshM;){let j=1;for(;j<meshN;){let facet=[getVector(i,j),getVector(i+1,j),getVector(i+1,j+1),getVector(i,j+1)];1===options.dxf.angdir&&(facet=facet.reverse());const polygon=poly3.create(facet),plane=poly3.plane(polygon);Number.isFinite(plane[3])&&(color&&(polygon.color=color),facets.push(polygon)),j++}i++}return facets})(obj.fvia,obj.fvib,parts,color,options);parts=facets}if("3dpolyfaces"===type&&"fvia"in obj){const faces=((meshM,meshN,parts,color,options)=>{const faces=[];if(meshM+meshN!==parts.length)return faces;let i=meshM;for(;i<parts.length;){let part=parts[i];const indexes=[Math.abs(part.fvia),Math.abs(part.fvib),Math.abs(part.fvic),Math.abs(part.fvid)];let vertices=[];if(indexes[0]>0&&(part=parts[indexes[0]-1],vertices.push(part.vec),indexes[1]>0&&(part=parts[indexes[1]-1],vertices.push(part.vec),indexes[2]>0&&(part=parts[indexes[2]-1],vertices.push(part.vec),indexes[3]>0&&(part=parts[indexes[3]-1],vertices.push(part.vec))))),vertices.length>2){1===options.dxf.angdir&&(vertices=vertices.reverse());const polygon=poly3.create(vertices);faces.push(polygon)}i++}return faces})(obj.fvia,obj.fvib,parts,0,options);parts=faces}const name=obj.name;let script=` const ${name}_polygons = [\n`;for(const polygon of parts)script+=" "+translatePolygon(polygon)+",\n";return script+=` ]\n let ${name} = geom3.create(${name}_polygons)\n`,color&&(script+=` ${name}.color = [${color}]\n`),obj.script=script,addToLayer(obj,layers),null},saveVariable=(obj,options)=>{"$ANGDIR"===(obj.name||"Unknown")&&"lflg"in obj&&(options.dxf.angdir=obj.lflg)},handleError=(reader,error)=>{if(!0===reader.options.strict)throw error;console.log(`error: line ${error.line}, column ${error.column}, bad character [${error.c}]`)},handleStart=(reader,data)=>{},handleEnd=(reader,data)=>{},handleEntity=(reader,group,value)=>{let obj=null;switch(value){case"LAYER":obj={type:"layer"},obj[getTLA(48)]=1,obj[getTLA(60)]=0,obj[getTLA(67)]=0,reader.objstack.push(obj);break;case"LINE":obj={type:"line"},obj[getTLA(48)]=1,obj[getTLA(60)]=0,obj[getTLA(62)]=256,obj[getTLA(67)]=0,obj[getTLA(210)]=0,obj[getTLA(220)]=0,obj[getTLA(230)]=0,reader.objstack.push(obj);break;case"LWPOLYLINE":obj={type:"lwpolyline"},obj[getTLA(48)]=1,obj[getTLA(60)]=0,obj[getTLA(62)]=256,obj[getTLA(67)]=0,obj[getTLA(38)]=0,obj[getTLA(39)]=0,obj[getTLA(43)]=0,obj[getTLA(70)]=0,obj[getTLA(90)]=0,obj[getTLA(210)]=0,obj[getTLA(220)]=0,obj[getTLA(230)]=1,reader.objstack.push(obj);break;case"MESH":obj={type:"mesh"},obj[getTLA(48)]=1,obj[getTLA(60)]=0,obj[getTLA(62)]=256,obj[getTLA(67)]=0,obj[getTLA(91)]=0,obj[getTLA(92)]=0,obj[getTLA(93)]=0,obj[getTLA(94)]=0,obj[getTLA(95)]=0,obj.state=0,reader.objstack.push(obj);break;case"POLYLINE":obj={type:"polyline"},obj[getTLA(48)]=1,obj[getTLA(60)]=0,obj[getTLA(62)]=256,obj[getTLA(67)]=0,obj[getTLA(10)]=0,obj[getTLA(20)]=0,obj[getTLA(30)]=0,obj[getTLA(39)]=0,obj[getTLA(40)]=0,obj[getTLA(41)]=0,obj[getTLA(70)]=0,obj[getTLA(71)]=0,obj[getTLA(72)]=0,obj[getTLA(73)]=0,obj[getTLA(74)]=0,obj[getTLA(75)]=0,obj[getTLA(210)]=0,obj[getTLA(220)]=0,obj[getTLA(230)]=1,reader.objstack.push(obj);break;case"ARC":obj={type:"arc"},obj[getTLA(48)]=1,obj[getTLA(60)]=0,obj[getTLA(62)]=256,obj[getTLA(67)]=0,obj[getTLA(39)]=0,obj[getTLA(210)]=0,obj[getTLA(220)]=0,obj[getTLA(230)]=1,reader.objstack.push(obj);break;case"CIRCLE":obj={type:"circle"},obj[getTLA(48)]=1,obj[getTLA(60)]=0,obj[getTLA(62)]=256,obj[getTLA(67)]=0,obj[getTLA(39)]=0,obj[getTLA(210)]=0,obj[getTLA(220)]=0,obj[getTLA(230)]=1,reader.objstack.push(obj);break;case"ELLIPSE":obj={type:"ellipse"},obj[getTLA(48)]=1,obj[getTLA(60)]=0,obj[getTLA(62)]=256,obj[getTLA(67)]=0,obj[getTLA(210)]=0,obj[getTLA(220)]=0,obj[getTLA(230)]=1,reader.objstack.push(obj);break;case"VERTEX":obj={type:"vertex"},obj[getTLA(48)]=1,obj[getTLA(60)]=0,obj[getTLA(62)]=256,obj[getTLA(67)]=0,obj[getTLA(10)]=0,obj[getTLA(20)]=0,obj[getTLA(30)]=0,obj[getTLA(40)]=0,obj[getTLA(41)]=0,obj[getTLA(42)]=0,obj[getTLA(70)]=0,obj[getTLA(71)]=0,obj[getTLA(72)]=0,obj[getTLA(73)]=0,obj[getTLA(74)]=0,reader.objstack.push(obj);break;case"3DFACE":obj={type:"3dface"},obj[getTLA(48)]=1,obj[getTLA(60)]=0,obj[getTLA(62)]=256,obj[getTLA(67)]=0,obj[getTLA(70)]=0,reader.objstack.push(obj);break;case"SEQEND":obj={type:"seqend"},reader.objstack.push(obj);break;default:obj={},reader.objstack.push(obj)}},handleVariable=(reader,group,value)=>{const obj={type:"variable",name:value};reader.objstack.push(obj)},handleInt=(reader,group,value)=>{const obj=reader.objstack.pop();"type"in obj&&(obj[getTLA(group)]=parseFloat(value)),reader.objstack.push(obj)},handleDouble=(reader,group,value)=>{const obj=reader.objstack.pop();"type"in obj&&(obj[getTLA(group)]=parseFloat(value)),reader.objstack.push(obj)},handleXcoord=(reader,group,value)=>{const obj=reader.objstack.pop();"type"in obj&&("lwpolyline"===obj.type?(void 0===obj.pptxs&&(obj.pptxs=[],obj.bulgs=[]),obj.pptxs.push(parseFloat(value)),obj.bulgs.push(0)):"mesh"===obj.type?(void 0===obj.pptxs&&(obj.pptxs=[]),obj.pptxs.push(parseFloat(value))):obj[getTLA(group)]=parseFloat(value)),reader.objstack.push(obj)},handleYcoord=(reader,group,value)=>{const obj=reader.objstack.pop();"type"in obj&&("lwpolyline"===obj.type||"mesh"===obj.type?(void 0===obj.pptys&&(obj.pptys=[]),obj.pptys.push(parseFloat(value))):obj[getTLA(group)]=parseFloat(value)),reader.objstack.push(obj)},handleZcoord=(reader,group,value)=>{const obj=reader.objstack.pop();"type"in obj&&("mesh"===obj.type?(void 0===obj.pptzs&&(obj.pptzs=[]),obj.pptzs.push(parseFloat(value))):obj[getTLA(group)]=parseFloat(value)),reader.objstack.push(obj)},handleBulge=(reader,group,value)=>{const obj=reader.objstack.pop();if("type"in obj)if("lwpolyline"===obj.type){const bulgs=obj.bulgs;void 0!==bulgs&&obj.pptxs.length===bulgs.length&&(bulgs[bulgs.length-1]=parseFloat(value))}else obj[getTLA(group)]=parseFloat(value);reader.objstack.push(obj)},handleLen=(reader,group,value)=>{const obj=reader.objstack.pop();if("type"in obj)if("mesh"===obj.type){const state=obj.state;switch(group){case 91:obj[getTLA(group)]=parseFloat(value),obj.state=1;break;case 92:1===state?(obj.vlen=parseFloat(value),obj.state=2):(obj.plen=parseFloat(value),obj.state=6);break;case 93:obj[getTLA(group)]=parseFloat(value),obj.state=3;break;case 94:obj[getTLA(group)]=parseFloat(value),obj.state=4;break;case 95:obj[getTLA(group)]=parseFloat(value),obj.state=5;break;default:obj.state=7}}else obj[getTLA(group)]=parseFloat(value);reader.objstack.push(obj)},handleValue=(reader,group,value)=>{const obj=reader.objstack.pop();if("type"in obj)if("mesh"===obj.type)switch(obj.state){case 3:void 0===obj.fvals&&(obj.fvals=[]),obj.fvals.push(parseFloat(value));break;case 4:void 0===obj.evals&&(obj.evals=[]),obj.evals.push(parseFloat(value))}else obj[getTLA(group)]=parseFloat(value);reader.objstack.push(obj)},handleString=(reader,group,value)=>{const obj=reader.objstack.pop();"type"in obj&&(obj[getTLA(group)]=value),reader.objstack.push(obj)},handleName=(reader,group,value)=>{const obj=reader.objstack.pop();"type"in obj&&void 0===obj[getTLA(group)]&&(obj[getTLA(group)]=value),reader.objstack.push(obj)},createReader=(src,options)=>{const dxfreader=new DxfReader(options);return dxfreader.on("error",handleError),dxfreader.on("start",handleStart),dxfreader.on("end",handleEnd),dxfreader.absorb(0,handleEntity),dxfreader.absorb(1,handleString),dxfreader.absorb(2,handleName),dxfreader.absorb(3,handleName),dxfreader.absorb(6,handleString),dxfreader.absorb(7,handleString),dxfreader.absorb(8,handleString),dxfreader.absorb(9,handleVariable),dxfreader.absorb(10,handleXcoord),dxfreader.absorb(11,handleDouble),dxfreader.absorb(12,handleDouble),dxfreader.absorb(13,handleDouble),dxfreader.absorb(20,handleYcoord),dxfreader.absorb(21,handleDouble),dxfreader.absorb(22,handleDouble),dxfreader.absorb(23,handleDouble),dxfreader.absorb(30,handleZcoord),dxfreader.absorb(31,handleDouble),dxfreader.absorb(32,handleDouble),dxfreader.absorb(33,handleDouble),dxfreader.absorb(39,handleDouble),dxfreader.absorb(40,handleDouble),dxfreader.absorb(41,handleDouble),dxfreader.absorb(42,handleBulge),dxfreader.absorb(50,handleDouble),dxfreader.absorb(51,handleDouble),dxfreader.absorb(62,handleInt),dxfreader.absorb(70,handleInt),dxfreader.absorb(71,handleInt),dxfreader.absorb(72,handleInt),dxfreader.absorb(73,handleInt),dxfreader.absorb(74,handleInt),dxfreader.absorb(75,handleInt),dxfreader.absorb(90,handleValue),dxfreader.absorb(91,handleLen),dxfreader.absorb(92,handleLen),dxfreader.absorb(93,handleLen),dxfreader.absorb(94,handleLen),dxfreader.absorb(95,handleLen),dxfreader.absorb(210,handleInt),dxfreader.absorb(220,handleInt),dxfreader.absorb(230,handleInt),dxfreader.objstack=[],dxfreader.objstack.push({type:"dxf"}),dxfreader.write(src),dxfreader.close(),dxfreader},instantiate=(src,options)=>{const objs=((reader,options)=>{const layers=[];let current=null;const polygons=[],objects=[],vectors=[];let p=null;for(const obj of reader.objstack)if(p=null,"type"in obj){switch(obj.type){case"dxf":break;case"layer":current=completeCurrent(objects,current,polygons,vectors),layers.push(obj);break;case"variable":case"seqend":current=completeCurrent(objects,current,polygons,vectors);break;case"3dface":p=instantiatePolygon(obj,layers,options),null===current&&(current=geom3.create());break;case"mesh":current=completeCurrent(objects,current,polygons,vectors),objects.push(instantiateMesh(obj,layers,options));break;case"arc":current=completeCurrent(objects,current,polygons,vectors),objects.push(instantiateArc(obj));break;case"circle":current=completeCurrent(objects,current,polygons,vectors),objects.push(instantiateCircle(obj,layers,options));break;case"ellipse":current=completeCurrent(objects,current,polygons,vectors),objects.push(instantiateEllipse(obj));break;case"line":current=completeCurrent(objects,current,polygons,vectors),objects.push(instantiateLine(obj));break;case"polyline":current=completeCurrent(objects,current,polygons,vectors),null===current&&(current=getPolyType$1(obj));break;case"vertex":p=instantiateVector(obj);break;case"lwpolyline":current=completeCurrent(objects,current,polygons,vectors),objects.push(instantiatePath2D(obj))}poly3.isA(p)&&polygons.push(p),p&&"vec"in p&&3===p.vec.length&&vectors.push(p),p&&"vec"in p&&2===p.vec.length&&vectors.push(p)}return current=completeCurrent(objects,current,polygons,vectors),objects})(createReader(src,options),options);return objs},translate=(src,options)=>{const reader=createReader(src,options);let code=`// Produced by JSCAD IO Library : DXF Deserializer (${options.version})\n\n`;return code+=((reader,options)=>{const layers=[];let current=null,parts=[],numobjs=0,p=null;for(const obj of reader.objstack)if(p=null,"type"in obj){if("name"in obj){let name=obj.name;name=name.replace(/ /g,"_"),name=name.replace(/-/g,"_"),name=name.replace(/\./g,"_"),obj.name=name}else obj.name="jscad"+numobjs,numobjs+=1;switch(obj.type){case"dxf":break;case"layer":current=translateCurrent(current,layers,parts,options),parts=[],obj.objects=[],obj.lnam="layer"+layers.length,layers.push(obj);break;case"variable":current=translateCurrent(current,layers,parts,options),parts=[],saveVariable(obj,options);break;case"3dface":p=instantiatePolygon(obj,layers,options),null===current&&(current={type:"3dfaces"},current.name="jscad"+numobjs,numobjs+=1);break;case"mesh":current=translateCurrent(current,layers,parts,options),parts=[],translateMesh(obj,layers,options);break;case"arc":current=translateCurrent(current,layers,parts,options),parts=[],translateArc(obj,layers,options);break;case"circle":current=translateCurrent(current,layers,parts,options),parts=[],translateCircle(obj,layers,options);break;case"ellipse":current=translateCurrent(current,layers,parts,options),parts=[],translateEllipse(obj,layers,options);break;case"line":current=translateCurrent(current,layers,parts,options),parts=[],translateLine(obj,layers,options);break;case"polyline":current=translateCurrent(current,layers,parts,options),parts=[],null===current&&(current=getPolyType(obj),current.name="jscad"+numobjs,numobjs+=1);break;case"vertex":p=instantiateVector(obj);break;case"seqend":current=translateCurrent(current,layers,parts,options),parts=[];break;case"lwpolyline":current=translateCurrent(current,layers,parts,options),parts=[],translatePath2D(obj,layers,options)}poly3.isA(p)&&parts.push(p),p&&"vec"in p&&3===p.vec.length&&parts.push(p),p&&"vec"in p&&2===p.vec.length&&parts.push(p)}current=translateCurrent(current,layers,parts,options);let script="import * from '@jscad/modeling'\n\nexport const main = () => {\n let layers = []\n return layers.concat(";return layers.forEach(layer=>{const name=layer.lnam||"Unknown";script+=`${name}(),`}),script+="[])\n}\n",script+="\nconst createPolygon = (listofpoints, color) => {\n let polygon = poly3.create(listofpoints)\n return colorize(color, polygon)\n}\n",layers.forEach(layer=>{script+=(layer=>{let script=`const ${layer.lnam||"Unknown"} = () => {\n`;for(const object of layer.objects)script+=object.script;script+=" return [";for(const object of layer.objects)script+=object.name+",";return script+="]\n}\n",script})(layer)}),script})(reader,options),code};exports.deserialize=(options,src)=>{const defaults={filename:"dxf",version:"3.0.5-alpha.0",output:"script",strict:!0,colorindex:colorIndex,dxf:{angdir:0,insunits:4,pfacevmax:4}};return options=Object.assign({},defaults,options),src=((stringOrArrayBuffer,defaultBinaryEncoding="utf-8")=>"string"==typeof stringOrArrayBuffer?stringOrArrayBuffer:new TextDecoder(defaultBinaryEncoding).decode(new Uint8Array(stringOrArrayBuffer)))(src),"script"===options.output?translate(src,options):instantiate(src,options)},exports.mimeType="image/vnd.dxf"},"object"==typeof exports&&"undefined"!=typeof module?factory(exports):"function"==typeof define&&define.amd?define(["exports"],factory):factory((global="undefined"!=typeof globalThis?globalThis:global||self).jscadDxfDeserializer={});
|