@jscad/svg-deserializer 3.0.0-alpha.0 → 3.0.1-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,7 +1,7 @@
1
1
  /**
2
2
  * SVG Deserializer for JSCAD
3
3
  * @module @jscad/svg-deserializer
4
- * @version 3.0.0-alpha.0
4
+ * @version 3.0.1-alpha.0
5
5
  * @license MIT
6
6
  */
7
7
  var global,factory;global=this,factory=function(exports){var saxes={},ed5$1={};!function(exports){function isNameStartChar(c){return c>=65&&c<=90||c>=97&&c<=122||58===c||95===c||8204===c||8205===c||c>=192&&c<=214||c>=216&&c<=246||c>=248&&c<=767||c>=880&&c<=893||c>=895&&c<=8191||c>=8304&&c<=8591||c>=11264&&c<=12271||c>=12289&&c<=55295||c>=63744&&c<=64975||c>=65008&&c<=65533||c>=65536&&c<=983039}
@@ -32,7 +32,7 @@ Object.defineProperty(exports,"__esModule",{value:!0}),exports.NC_NAME_START_CHA
32
32
  /**
33
33
  * Constructive Solid Geometry (CSG) Library for JSCAD
34
34
  * @module @jscad/modeling
35
- * @version 3.0.0-alpha.0
35
+ * @version 3.0.1-alpha.0
36
36
  * @license MIT
37
37
  */
38
- const flatten=arr=>arr.reduce(((acc,val)=>Array.isArray(val)?acc.concat(flatten(val)):acc.concat(val)),[]),clone$b=geometry=>Object.assign({},geometry),clone$a=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$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=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)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},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=(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),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],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},equals$7=(a,b)=>a[0]===b[0]&&a[1]===b[1]&&a[2]===b[2],fromScalar$2=(out,scalar)=>(out[0]=scalar,out[1]=scalar,out[2]=scalar,out),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$2=(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$2=(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),multiply$2=(out,a,b)=>(out[0]=a[0]*b[0],out[1]=a[1]*b[1],out[2]=a[2]*b[2],out),negate$1=(out,vector)=>(out[0]=-vector[0],out[1]=-vector[1],out[2]=-vector[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},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$b=vec=>`[${vec[0].toFixed(7)}, ${vec[1].toFixed(7)}, ${vec[2].toFixed(7)}]`,transform$c=(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};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:()=>[0,0,0],cross:cross$1,distance:(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:(out,a,b)=>(out[0]=a[0]/b[0],out[1]=a[1]/b[1],out[2]=a[2]/b[2],out),dot:dot$2,equals:equals$7,fromScalar:fromScalar$2,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$2,min:min$2,multiply:multiply$2,negate:negate$1,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:vector=>{const x=vector[0],y=vector[1],z=vector[2];return x*x+y*y+z*z},subtract:subtract$3,toString:toString$b,transform:transform$c});const 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};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:clone$a,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:fromScaling,fromTaitBryanRotation:fromTaitBryanRotation,fromTranslation:fromTranslation,fromValues:(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},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},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:(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},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)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$a=(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),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$6=(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$1=(out,a,b)=>(out[0]=Math.max(a[0],b[0]),out[1]=Math.max(a[1],b[1]),out),min$1=(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$9=vector=>`[${vector[0].toFixed(7)}, ${vector[1].toFixed(7)}]`,transform$b=(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};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:()=>[0,0],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$6,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$1,min:min$1,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$9,transform:transform$b});const 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$5=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$b([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,transform$a=(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})},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 index$a=Object.freeze({__proto__:null,clone:clone$b,create:create$a,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$a(outlines)},fromCompactBinary:data=>{if(0!==data[0])throw new Error("invalid compact binary data");const created=create$a();created.transforms=clone$a(data.slice(1,17));for(let i=21;i<data.length;){const length=data[i++];if(length<0||i+2*length>data.length)throw new Error("invalid compact binary data");const outline=[];for(let j=0;j<length;j++){const x=data[i+2*j],y=data[i+2*j+1];outline.push(fromValues$2(x,y))}created.outlines.push(outline),i+=2*length}return data[17]>=0&&(created.color=[data[17],data[18],data[19],data[20]]),created},isA:isA$5,reverse:geometry=>{const outlines=toOutlines(geometry).map((outline=>outline.slice().reverse())),reversed=create$a(outlines);return geometry.color&&(reversed.color=geometry.color),reversed},toOutlines:toOutlines,toPoints: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},toString:geometry=>{const outlines=toOutlines(geometry);let result="geom2 ("+outlines.length+" outlines):\n[\n";return outlines.forEach((outline=>{result+=" ["+outline.map(toString$9).join()+"]\n"})),result+="]\n",result},toCompactBinary:geometry=>{const transforms=geometry.transforms;let color=[-1,-1,-1,-1];geometry.color&&(color=geometry.color);let size=21;geometry.outlines.forEach((outline=>{size+=2*outline.length+1}));const compacted=new Float32Array(size);compacted[0]=0,compacted[1]=transforms[0],compacted[2]=transforms[1],compacted[3]=transforms[2],compacted[4]=transforms[3],compacted[5]=transforms[4],compacted[6]=transforms[5],compacted[7]=transforms[6],compacted[8]=transforms[7],compacted[9]=transforms[8],compacted[10]=transforms[9],compacted[11]=transforms[10],compacted[12]=transforms[11],compacted[13]=transforms[12],compacted[14]=transforms[13],compacted[15]=transforms[14],compacted[16]=transforms[15],compacted[17]=color[0],compacted[18]=color[1],compacted[19]=color[2],compacted[20]=color[3];let index=21;return geometry.outlines.forEach((outline=>{compacted[index++]=outline.length,outline.forEach((point=>{compacted[index++]=point[0],compacted[index++]=point[1]}))})),compacted},transform:transform$a,validate:object=>{if(!isA$5(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$6(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 clone$7=geometry=>Object.assign({},geometry),create$8=polygons=>(void 0===polygons&&(polygons=[]),{polygons:polygons,transforms:[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]}),create$7=vertices=>((void 0===vertices||vertices.length<3)&&(vertices=[]),{vertices:vertices}),clone$6=(...params)=>{let out,poly3;return 1===params.length?(out=create$7(),poly3=params[0]):(out=params[0],poly3=params[1]),out.vertices=poly3.vertices.map((vec=>clone$9(vec))),out},fromVerticesAndPlane=(vertices,plane)=>{const poly=create$7(vertices);return poly.plane=plane,poly},create$6=()=>[0,0,0,0],clone$5=vector=>{const out=[0,0,0,0];return out[0]=vector[0],out[1]=vector[1],out[2]=vector[2],out[3]=vector[3],out},copy$2=(out,vector)=>(out[0]=vector[0],out[1]=vector[1],out[2]=vector[2],out[3]=vector[3],out),equals$5=(a,b)=>a[0]===b[0]&&a[1]===b[1]&&a[2]===b[2]&&a[3]===b[3],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},fromValues$1=(x,y,z,w)=>{const out=[0,0,0,0];return out[0]=x,out[1]=y,out[2]=z,out[3]=w,out},fromPoints$4=(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},signedDistanceToPoint=(plane,point)=>dot$2(plane,point)-plane[3],toString$7=vec=>`(${vec[0].toFixed(9)}, ${vec[1].toFixed(9)}, ${vec[2].toFixed(9)}, ${vec[3].toFixed(9)})`;Object.freeze({__proto__:null,clone:clone$5,copy:copy$2,create:create$6,equals:equals$5,flip:flip,fromNormalAndPoint:fromNormalAndPoint,fromValues:fromValues$1,fromPoints:fromPoints$4,fromPointsRandom:(out,a,b,c)=>{let ba=subtract$3([0,0,0],b,a),ca=subtract$3([0,0,0],c,a);length$2(ba)<EPS&&(ba=orthogonal(ba,ca)),length$2(ca)<EPS&&(ca=orthogonal(ca,ba));let normal=cross$1([0,0,0],ba,ca);length$2(normal)<EPS&&(ca=orthogonal(ca,ba),normal=cross$1(normal,ba,ca)),normal=normalize$1(normal,normal);const w=dot$2(normal,a);return out[0]=normal[0],out[1]=normal[1],out[2]=normal[2],out[3]=w,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)},signedDistanceToPoint:signedDistanceToPoint,toString:toString$7,transform:(out,plane,matrix)=>{const isMirror=isMirroring(matrix),r=orthogonal([0,0,0],plane),u=cross$1(r,plane,r),v=cross$1([0,0,0],plane,u);let point1=fromScalar$2([0,0,0],plane[3]);multiply$2(point1,point1,plane);let point2=add$1([0,0,0],point1,u),point3=add$1([0,0,0],point1,v);return point1=transform$c(point1,point1,matrix),point2=transform$c(point2,point2,matrix),point3=transform$c(point3,point3,matrix),fromPoints$4(out,point1,point2,point3),isMirror&&flip(out,out),out}});const invert$1=polygon=>{const vertices=polygon.vertices.slice().reverse(),inverted=create$7(vertices);return polygon.plane&&(inverted.plane=flip([0,0,0,0],polygon.plane)),inverted},isA$4=object=>!!(object&&"object"==typeof object&&"vertices"in object&&Array.isArray(object.vertices)),isConvex$1=polygon=>areVerticesConvex(polygon.vertices),areVerticesConvex=vertices=>{const numVertices=vertices.length;if(numVertices>2){const normal=fromPoints$4([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$4([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};Object.freeze({__proto__:null,clone:clone$5,copy:copy$2,create:create$6,dot:(a,b)=>a[0]*b[0]+a[1]*b[1]+a[2]*b[2]+a[3]*b[3],equals:equals$5,fromScalar:(out,scalar)=>(out[0]=scalar,out[1]=scalar,out[2]=scalar,out[3]=scalar,out),fromValues:fromValues$1,toString:toString$7,transform:(out,vector,matrix)=>{const[x,y,z,w]=vector;return 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[3]=matrix[3]*x+matrix[7]*y+matrix[11]*z+matrix[15]*w,out}});const cache$4=new WeakMap,toVertices$1=polygon=>polygon.vertices,toString$6=polygon=>`poly3: [${polygon.vertices.map(toString$b).join(", ")}]`,transform$7=(matrix,polygon)=>{const vertices=polygon.vertices.map((vertex=>transform$c([0,0,0],vertex,matrix)));return isMirroring(matrix)&&vertices.reverse(),create$7(vertices)},validate$4=object=>{if(!isA$4(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$7(object.vertices[i],object.vertices[(i+1)%object.vertices.length]))throw new Error(`poly3 has duplicate vertex ${object.vertices[i]}`);if(!isConvex$1(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(signedDistanceToPoint(normal,vertex));if(dist>1e-13)throw new Error(`poly3 must be coplanar: vertex ${vertex} distance ${dist}`)}))}};Object.freeze({__proto__:null,clone:clone$6,create:create$7,fromVerticesAndPlane:fromVerticesAndPlane,invert:invert$1,isA:isA$4,isConvex:isConvex$1,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$2(min,min,vertices[i]),max$2(max,max,vertices[i]);return[min,max]},measureBoundingSphere:polygon=>{const boundingSphere=cache$4.get(polygon);if(boundingSphere)return boundingSphere;const vertices=polygon.vertices,out=[0,0,0,0];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;vertices.forEach((v=>{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),cache$4.set(polygon,out),out},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,toVertices:toVertices$1,toString:toString$6,transform:transform$7,validate:validate$4});const toPolygons$1=geometry=>(geometry=>(isIdentity(geometry.transforms)||(geometry.polygons=geometry.polygons.map((polygon=>transform$7(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$3=object=>!!(object&&"object"==typeof object&&"polygons"in object&&"transforms"in object&&Array.isArray(object.polygons)&&"length"in object.transforms),transform$6=(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})};Object.freeze({__proto__:null,clone:clone$7,create:create$8,fromPoints:listOfLists=>{if(!Array.isArray(listOfLists))throw new Error("the given vertices must be an array");return create$8(listOfLists.map(create$7))},fromCompactBinary:data=>{if(1!==data[0])throw new Error("invalid compact binary data");const created=create$8();created.transforms=clone$a(data.slice(1,17));const numberOfVertices=data[21];let ci=22,vi=data.length-3*numberOfVertices;for(;vi<data.length;){const verticesPerPolygon=data[ci];ci++;const vertices=[];for(let i=0;i<verticesPerPolygon;i++)vertices.push(fromValues$3(data[vi],data[vi+1],data[vi+2])),vi+=3;created.polygons.push(create$7(vertices))}return data[17]>=0&&(created.color=[data[17],data[18],data[19],data[20]]),created},invert:geometry=>{const newPolygons=toPolygons$1(geometry).map((polygon=>invert$1(polygon)));return create$8(newPolygons)},isA:isA$3,toPoints:geometry=>toPolygons$1(geometry).map((polygon=>toVertices$1(polygon))),toPolygons:toPolygons$1,toString:geometry=>{const polygons=toPolygons$1(geometry);let result="geom3 ("+polygons.length+" polygons):\n";return polygons.forEach((polygon=>{result+=" "+toString$6(polygon)+"\n"})),result},toCompactBinary:geometry=>{const polygons=geometry.polygons,transforms=geometry.transforms,numberOfPolygons=polygons.length,numberOfVertices=polygons.reduce(((count,polygon)=>count+polygon.vertices.length),0);let color=[-1,-1,-1,-1];geometry.color&&(color=geometry.color);const compacted=new Float32Array(22+numberOfPolygons+3*numberOfVertices);compacted[0]=1,compacted[1]=transforms[0],compacted[2]=transforms[1],compacted[3]=transforms[2],compacted[4]=transforms[3],compacted[5]=transforms[4],compacted[6]=transforms[5],compacted[7]=transforms[6],compacted[8]=transforms[7],compacted[9]=transforms[8],compacted[10]=transforms[9],compacted[11]=transforms[10],compacted[12]=transforms[11],compacted[13]=transforms[12],compacted[14]=transforms[13],compacted[15]=transforms[14],compacted[16]=transforms[15],compacted[17]=color[0],compacted[18]=color[1],compacted[19]=color[2],compacted[20]=color[3],compacted[21]=numberOfVertices;let ci=22,vi=ci+numberOfPolygons;return polygons.forEach((polygon=>{const vertices=toVertices$1(polygon);compacted[ci]=vertices.length,ci++;for(let i=0;i<vertices.length;i++){const vertex=vertices[i];compacted[vi+0]=vertex[0],compacted[vi+1]=vertex[1],compacted[vi+2]=vertex[2],vi+=3}})),compacted},transform:transform$6,validate:object=>{if(!isA$3(object))throw new Error("invalid geom3 structure");if(object.polygons.forEach(validate$4),(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=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*EPS&&(points.pop(),1!==points.length);)pn=points[points.length-1]}return cloned},create$5=points=>(void 0===points&&(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$5();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*EPS&&(closed=!0)}return!0===closed&&(created=close(created)),created},toPoints$1=geometry=>(geometry=>(isIdentity(geometry.transforms)||(geometry.points=geometry.points.map((point=>transform$b([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=(...paths)=>{let isClosed=!1,newPoints=[];return paths.forEach(((path,i)=>{const tmp=toPoints$1(path).slice();if(newPoints.length>0&&tmp.length>0&&equals$6(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$1=(points,geometry)=>concat(geometry,create$5(points)),isA$2=object=>!!(object&&"object"==typeof object&&"points"in object&&"transforms"in object&&"isClosed"in object&&Array.isArray(object.points)&&"length"in object.transforms),transform$5=(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 index$5=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.ceil(Math.abs(deltatheta)/TAU*segments)+1;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$1(newPoints,geometry);return result.lastBezierControlPoint=controlPoints[controlPoints.length-2],result},appendPoints:appendPoints$1,clone:clone$4,close:close,concat:concat,create:create$5,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$6(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,fromCompactBinary:data=>{if(2!==data[0])throw new Error("invalid compact binary data");const created=create$5();created.transforms=clone$a(data.slice(1,17)),created.isClosed=!!data[17];for(let i=22;i<data.length;i+=2){const point=fromValues$2(data[i],data[i+1]);created.points.push(point)}return data[18]>=0&&(created.color=[data[18],data[19],data[20],data[21]]),created},isA:isA$2,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$9(point)+",\n"})),result+="]\n",result},toCompactBinary:geometry=>{const points=geometry.points,transforms=geometry.transforms;let color=[-1,-1,-1,-1];geometry.color&&(color=geometry.color);const compacted=new Float32Array(22+2*points.length);compacted[0]=2,compacted[1]=transforms[0],compacted[2]=transforms[1],compacted[3]=transforms[2],compacted[4]=transforms[3],compacted[5]=transforms[4],compacted[6]=transforms[5],compacted[7]=transforms[6],compacted[8]=transforms[7],compacted[9]=transforms[8],compacted[10]=transforms[9],compacted[11]=transforms[10],compacted[12]=transforms[11],compacted[13]=transforms[12],compacted[14]=transforms[13],compacted[15]=transforms[14],compacted[16]=transforms[15],compacted[17]=geometry.isClosed?1:0,compacted[18]=color[0],compacted[19]=color[1],compacted[20]=color[2],compacted[21]=color[3];for(let j=0;j<points.length;j++){const ci=2*j+22,point=points[j];compacted[ci]=point[0],compacted[ci+1]=point[1]}return compacted},transform:transform$5,validate:object=>{if(!isA$2(object))throw new Error("invalid path2 structure");if(object.points.length>1)for(let i=0;i<object.points.length;i++)if(equals$6(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 colorize=(color,...objects)=>{if(!Array.isArray(color))throw new Error("color must be an array");if(color.length<3)throw new Error("color must contain R, G and B values");if(3===color.length&&(color=[color[0],color[1],color[2],1]),0===(objects=flatten(objects)).length)throw new Error("wrong number of arguments");const results=objects.map((object=>isA$5(object)?((color,object)=>{const newGeom2=clone$b(object);return newGeom2.color=color,newGeom2})(color,object):isA$3(object)?((color,object)=>{const newGeom3=clone$7(object);return newGeom3.color=color,newGeom3})(color,object):isA$2(object)?((color,object)=>{const newPath2=clone$4(object);return newPath2.color=color,newPath2})(color,object):isA$4(object)?((color,object)=>{const newPoly=clone$6(object);return newPoly.color=color,newPoly})(color,object):(object.color=color,object)));return 1===results.length?results[0]:results},getPermutations=function(c){const permutations=[];for(let i=0;i<=c;i++)permutations.push(factorial(c)/(factorial(i)*factorial(c-i)));return permutations},factorial=function(b){let out=1;for(let i=2;i<=b;i++)out*=i;return out},valueAt=(t,bezier)=>{if(t<0||t>1)throw new Error("Bezier valueAt() input must be between 0 and 1");if("float_single"===bezier.pointType)return bezierFunction(bezier,bezier.points,t);{const result=[];for(let i=0;i<bezier.dimensions;i++){const singleDimensionPoints=[];for(let j=0;j<bezier.points.length;j++)singleDimensionPoints.push(bezier.points[j][i]);result.push(bezierFunction(bezier,singleDimensionPoints,t))}return result}},bezierFunction=function(bezier,p,t){const n=p.length-1;let result=0;for(let i=0;i<=n;i++)result+=bezier.permutations[i]*Math.pow(1-t,n-i)*Math.pow(t,i)*p[i];return result},bezierTangent=function(bezier,p,t){const n=p.length-1;let result=0;for(let i=0;i<n;i++){const q=n*(p[i+1]-p[i]);result+=bezier.tangentPermutations[i]*Math.pow(1-t,n-1-i)*Math.pow(t,i)*q}return result},lengths=(segments,bezier)=>{let sum=0;const lengths=[0];let previous=valueAt(0,bezier);for(let index=1;index<=segments;index++){const current=valueAt(index/segments,bezier);sum+=distanceBetween(current,previous),lengths.push(sum),previous=current}return lengths},distanceBetween=(a,b)=>{if(Number.isFinite(a)&&Number.isFinite(b))return Math.abs(a-b);if(Array.isArray(a)&&Array.isArray(b)){if(a.length!==b.length)throw new Error("The operands must have the same number of dimensions.");let sum=0;for(let i=0;i<a.length;i++)sum+=(b[i]-a[i])*(b[i]-a[i]);return Math.sqrt(sum)}throw new Error("The operands must be of the same type, either number or array.")};Object.freeze({__proto__:null,create:points=>{if(!Array.isArray(points))throw new Error("Bezier points must be a valid array/");if(points.length<2)throw new Error("Bezier points must contain at least 2 values.");const pointType=function(points){let firstPointType=null;return points.forEach((point=>{let pType="";if(Number.isFinite(point))pType="float_single";else{if(!Array.isArray(point))throw new Error("Bezier points must all be numbers or arrays of number.");point.forEach((val=>{if(!Number.isFinite(val))throw new Error("Bezier point values must all be numbers.")})),pType="float_"+point.length}if(null==firstPointType)firstPointType=pType;else if(firstPointType!==pType)throw new Error("Bezier points must be either all numbers or all arrays of numbers of the same size.")})),firstPointType}(points);return{points:points,pointType:pointType,dimensions:"float_single"===pointType?0:points[0].length,permutations:getPermutations(points.length-1),tangentPermutations:getPermutations(points.length-2)}},valueAt:valueAt,tangentAt:(t,bezier)=>{if(t<0||t>1)throw new Error("Bezier tangentAt() input must be between 0 and 1");if("float_single"===bezier.pointType)return bezierTangent(bezier,bezier.points,t);{const result=[];for(let i=0;i<bezier.dimensions;i++){const singleDimensionPoints=[];for(let j=0;j<bezier.points.length;j++)singleDimensionPoints.push(bezier.points[j][i]);result.push(bezierTangent(bezier,singleDimensionPoints,t))}return result}},lengths:lengths,length:(segments,bezier)=>lengths(segments,bezier)[segments],arcLengthToT:(options,bezier)=>{const{distance:distance,segments:segments}=Object.assign({},{distance:0,segments:100},options),arcLengths=lengths(segments,bezier);let startIndex=0,endIndex=segments;for(;startIndex<=endIndex;){const middleIndex=Math.floor(startIndex+(endIndex-startIndex)/2),diff=arcLengths[middleIndex]-distance;if(diff<0)startIndex=middleIndex+1;else{if(!(diff>0)){endIndex=middleIndex;break}endIndex=middleIndex-1}}const targetIndex=endIndex;if(arcLengths[targetIndex]===distance)return targetIndex/segments;const lengthBefore=arcLengths[targetIndex];return(targetIndex+(distance-lengthBefore)/(arcLengths[targetIndex+1]-lengthBefore))/segments}});const 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},measureArea$1=polygon=>area$1(polygon.points),create$3=points=>((void 0===points||points.length<3)&&(points=[]),{points:points}),reverse$3=polygon=>{const points=polygon.points.slice().reverse();return create$3(points)},arePointsInside=(points,polygon)=>0===points.length||polygon.points.length<3?0:(measureArea$1(polygon)<0&&(polygon=reverse$3(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},isA$1=object=>!!(object&&"object"==typeof object&&"points"in object&&Array.isArray(object.points)),crossBetweenSegments=(p1,p2,p3)=>{const X1=p2[0]-p1[0],Y1=p2[1]-p1[1],X2=p3[0]-p1[0];return X1*(p3[1]-p1[1])-Y1*X2};Object.freeze({__proto__:null,arePointsInside:arePointsInside,clone:polygon=>Object.assign({},polygon),create:create$3,isA:isA$1,isConvex:polygon=>{const numPoints=polygon.points.length;if(numPoints>2){const points=polygon.points;let prev=0,curr=0;for(let i=0;i<numPoints;i++)if(curr=crossBetweenSegments(points[i],points[(i+1)%numPoints],points[(i+2)%numPoints]),0!==curr){if(curr*prev<0)return!1;prev=curr}}return!0},isSimple:polygon=>{const numPoints=polygon.points.length;if(numPoints<3)return!1;if(3===numPoints)return!0;const points=polygon.points,found=new Set;if(points.forEach((v=>found.add(v.toString()))),found.size!==numPoints)return!1;for(let i=0;i<numPoints;i++)for(let j=i+2;j<numPoints;j++){const k=(j+1)%numPoints;if(i!==k){const s0=points[i],s1=points[(i+1)%numPoints],z0=points[j],z1=points[k];if(intersect$1(s0,s1,z0,z1))return!1}}return!0},measureArea:measureArea$1,measureBoundingBox:polygon=>{const points=polygon.points,numPoints=points.length,min=0===numPoints?[0,0]:clone$8(points[0]),max=clone$8(min);for(let i=1;i<numPoints;i++)min$1(min,min,points[i]),max$1(max,max,points[i]);return[min,max]},reverse:reverse$3,toPoints:polygon=>polygon.points,toString:polygon=>`poly2: [${polygon.points.map(toString$9).join(", ")}]`,transform:(matrix,polygon)=>{const points=polygon.points.map((point=>transform$b([0,0],point,matrix)));return isMirroring(matrix)&&points.reverse(),create$3(points)},validate:object=>{if(!isA$1(object))throw new Error("invalid poly2 structure");if(object.points.length<3)throw new Error(`poly2 not enough points ${object.points.length}`);if(measureArea$1(object)<=0)throw new Error("poly2 area must be greater than zero");for(let i=0;i<object.points.length;i++)if(equals$6(object.points[i],object.points[(i+1)%object.points.length]))throw new Error(`poly2 duplicate point at ${i}: [${object.points[i]}]`);object.points.forEach((point=>{if(2!==point.length)throw new Error(`poly2 invalid point ${point}`);if(!point.every(Number.isFinite))throw new Error(`poly2 invalid point ${point}`)}))}});const calculatePlane=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$7(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$7(prev,vertex)&&equals$7(prev,farthestVertex)){farthestAfter=vertex;break}prev=vertex}return fromPoints$4([0,0,0,0],farthestBefore,farthestVertex,farthestAfter)},create$2=(contours=[])=>({contours:contours}),isA=object=>!!(object&&"object"==typeof object&&"contours"in object&&Array.isArray(object.contours));class Node$2{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&&sectorContainsSector(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=calculatePlane(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$a(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)}}}Object.freeze({__proto__:null,calculatePlane:calculatePlane,clone:slice=>Object.assign({},slice),create:create$2,equals:(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$7(aVertex,bVertex))return!1}}return!0},fromGeom2:geometry=>{const contours=toOutlines(geometry).map((outline=>outline.map((point=>fromVec2([0,0,0],point)))));return create$2(contours)},fromVertices: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])},isA:isA,reverse: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},toVertices:slice=>{const vertices=[];return slice.contours.forEach((contour=>{contour.forEach((vertex=>{vertices.push(vertex)}))})),vertices},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},toString:slice=>{let result="slice ("+slice.contours.length+" contours):\n[\n";return slice.contours.forEach((contour=>{result+=" ["+contour.map(toString$b).join()+"],\n"})),result+="]\n",result},transform:(matrix,slice)=>{const contours=slice.contours.map((contour=>contour.map((vertex=>transform$c([0,0,0],vertex,matrix)))));return create$2(contours)},validate:object=>{if(!isA(object))throw new Error("invalid slice structure");const slicePlane=calculatePlane(object);object.contours.forEach(((contour,i)=>{if(contour.length<3)throw new Error(`slice contour ${i} must contain at least 3 vertices`);const contourPlane=plane(create$7(contour));if(!equals$5(slicePlane,contourPlane))throw new Error("slice contours must be coplanar");for(let i=0;i<contour.length;i++){if(!contour[i].every(Number.isFinite))throw new Error(`slice contour ${i} must contain finite vertices`);const j=(i+1)%contour.length;if(equals$7(contour[i],contour[j]))throw new Error(`slice contour ${i} has duplicate vertex ${contour[i]}`)}}))}});const direction$1=line=>{const vector=normal([0,0],line);return negate(vector,vector),vector},origin$1=line=>scale$1([0,0],line,line[2]),copy$1=(out,line)=>(out[0]=line[0],out[1]=line[1],out[2]=line[2],out),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},fromValues=(x,y,d)=>{const out=[0,1,0];return out[0]=x,out[1]=y,out[2]=d,out},solve2Linear=(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]};Object.freeze({__proto__:null,clone:line=>{const out=[0,1,0];return out[0]=line[0],out[1]=line[1],out[2]=line[2],out},closestPoint:(line,point)=>{const orig=origin$1(line),dir=direction$1(line),v=subtract$1([0,0],point,orig),dist=dot$1(v,dir);return scale$1(v,dir,dist),add(v,v,orig),v},copy:copy$1,create:()=>[0,1,0],direction:direction$1,distanceToPoint:(line,point)=>{let distance=dot$1(point,line);return distance=Math.abs(distance-line[2]),distance},equals:(line1,line2)=>line1[0]===line2[0]&&line1[1]===line2[1]&&line1[2]===line2[2],fromPoints:fromPoints$1,fromValues:fromValues,intersectPointOfLines:(line1,line2)=>{const point=solve2Linear(line1[0],line1[1],line2[0],line2[1],line1[2],line2[2]);return clone$8(point)},origin:origin$1,reverse:(out,line)=>{const normal=negate([0,0],line),distance=-line[2];return copy$1(out,fromValues(normal[0],normal[1],distance))},toString:line=>`line2: (${line[0].toFixed(7)}, ${line[1].toFixed(7)}, ${line[2].toFixed(7)})`,transform:(out,line,matrix)=>{const org=origin$1(line),dir=direction$1(line);return transform$b(org,org,matrix),transform$b(dir,dir,matrix),fromPoints$1(out,org,dir)},xAtY:(line,y)=>{let x=(line[2]-line[1]*y)/line[0];return Number.isNaN(x)&&(x=origin$1(line)[0]),x}});const create=()=>[fromValues$3(0,0,0),fromValues$3(0,0,1)],closestPoint=(line,point)=>{const lPoint=line[0],lDirection=line[1],a=dot$2(subtract$3([0,0,0],point,lPoint),lDirection),b=dot$2(lDirection,lDirection),closestPoint=scale$3([0,0,0],lDirection,a/b);return add$1(closestPoint,closestPoint,lPoint),closestPoint},fromPointAndDirection=(out,point,direction)=>{const unit=normalize$1([0,0,0],direction);return copy$4(out[0],point),copy$4(out[1],unit),out};Object.freeze({__proto__:null,clone:line=>{const out=create();return copy$4(out[0],line[0]),copy$4(out[1],line[1]),out},closestPoint:closestPoint,copy:(out,line)=>(copy$4(out[0],line[0]),copy$4(out[1],line[1]),out),create:create,direction:line=>line[1],distanceToPoint:(line,point)=>{const closest=closestPoint(line,point),distanceVector=subtract$3([0,0,0],point,closest);return length$2(distanceVector)},equals:(line1,line2)=>!!equals$7(line1[1],line2[1])&&!!equals$7(line1[0],line2[0]),fromPlanes:(out,plane1,plane2)=>{let direction=cross$1([0,0,0],plane1,plane2),length=length$2(direction);if(length<EPS)throw new Error("parallel planes do not intersect");length=1/length,direction=scale$3(direction,direction,length);const absX=Math.abs(direction[0]),absY=Math.abs(direction[1]),absZ=Math.abs(direction[2]);let origin,r;return absX>=absY&&absX>=absZ?(r=solve2Linear(plane1[1],plane1[2],plane2[1],plane2[2],plane1[3],plane2[3]),origin=fromValues$3(0,r[0],r[1])):absY>=absX&&absY>=absZ?(r=solve2Linear(plane1[0],plane1[2],plane2[0],plane2[2],plane1[3],plane2[3]),origin=fromValues$3(r[0],0,r[1])):(r=solve2Linear(plane1[0],plane1[1],plane2[0],plane2[1],plane1[3],plane2[3]),origin=fromValues$3(r[0],r[1],0)),fromPointAndDirection(out,origin,direction)},fromPointAndDirection:fromPointAndDirection,fromPoints:(out,point1,point2)=>{const direction=subtract$3([0,0,0],point2,point1);return fromPointAndDirection(out,point1,direction)},intersectPointOfLineAndPlane:(line,plane)=>{const pNormal=plane,pw=plane[3],lPoint=line[0],lDirection=line[1],labda=(pw-dot$2(pNormal,lPoint))/dot$2(pNormal,lDirection);return add$1([0,0,0],lPoint,scale$3([0,0,0],lDirection,labda))},origin:line=>line[0],reverse:(out,line)=>{const point=clone$9(line[0]),direction=negate$1([0,0,0],line[1]);return fromPointAndDirection(out,point,direction)},toString:line=>{const point=line[0],direction=line[1];return`line3: point: (${point[0].toFixed(7)}, ${point[1].toFixed(7)}, ${point[2].toFixed(7)}) direction: (${direction[0].toFixed(7)}, ${direction[1].toFixed(7)}, ${direction[2].toFixed(7)})`},transform:(out,line,matrix)=>{const point=line[0],direction=line[1],pointPlusDirection=add$1([0,0,0],point,direction),newPoint=transform$c([0,0,0],point,matrix),newPointPlusDirection=transform$c(pointPlusDirection,pointPlusDirection,matrix),newDirection=subtract$3(newPointPlusDirection,newPointPlusDirection,newPoint);return fromPointAndDirection(out,newPoint,newDirection)}});const isNumberArray=(array,dimension)=>!!(Array.isArray(array)&&array.length>=dimension)&&array.every((n=>Number.isFinite(n))),isGTE=(value,constant)=>Number.isFinite(value)&&value>=constant,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$a();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*EPS)/(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$a([points])},line=points=>{if(!Array.isArray(points))throw new Error("points must be an array");return fromPoints$2({},points)},rectangle=options=>{const{center:center,size:size}=Object.assign({},{center:[0,0],size:[2,2]},options);if(!isNumberArray(center,2))throw new Error("center must be an array of X and Y values");if(!isNumberArray(size,2))throw new Error("size must be an array of X and Y values");if(!size.every((n=>n>=0)))throw new Error("size values must be positive");if(0===size[0]||0===size[1])return create$a();const point=[size[0]/2,size[1]/2],swapped=[point[0],-point[1]],points=[subtract$1([0,0],center,point),add([0,0],center,swapped),add([0,0],center,point),subtract$1([0,0],center,swapped)];return create$a([points])},mirror=(options,...objects)=>{const{origin:origin,normal:normal}=Object.assign({},{origin:[0,0,0],normal:[0,0,1]},options);if(0===(objects=flatten(objects)).length)throw new Error("wrong number of arguments");const 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$2(object)?transform$5(matrix,object):isA$5(object)?transform$a(matrix,object):isA$3(object)?transform$6(matrix,object):object));return 1===results.length?results[0]:results},mirrorX=(...objects)=>mirror({normal:[1,0,0]},objects),mirrorY=(...objects)=>mirror({normal:[0,1,0]},objects),rotateZ=(angle,...objects)=>((angles,...objects)=>{if(!Array.isArray(angles))throw new Error("angles must be an array");if(0===(objects=flatten(objects)).length)throw new Error("wrong number of arguments");for(angles=angles.slice();angles.length<3;)angles.push(0);const yaw=angles[2],pitch=angles[1],roll=angles[0],matrix=fromTaitBryanRotation([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],yaw,pitch,roll),results=objects.map((object=>isA$2(object)?transform$5(matrix,object):isA$5(object)?transform$a(matrix,object):isA$3(object)?transform$6(matrix,object):object));return 1===results.length?results[0]:results})([0,0,angle],objects),translate=(offset,...objects)=>{if(!Array.isArray(offset))throw new Error("offset must be an array");if(0===(objects=flatten(objects)).length)throw new Error("wrong number of arguments");for(offset=offset.slice();offset.length<3;)offset.push(0);const matrix=fromTranslation([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],offset),results=objects.map((object=>isA$2(object)?transform$5(matrix,object):isA$5(object)?transform$a(matrix,object):isA$3(object)?transform$6(matrix,object):object));return 1===results.length?results[0]:results},scale=(factors,...objects)=>{if(!Array.isArray(factors))throw new Error("factors must be an array");if(0===(objects=flatten(objects)).length)throw new Error("wrong number of arguments");for(factors=factors.slice();factors.length<3;)factors.push(1);if(factors[0]<=0||factors[1]<=0||factors[2]<=0)throw new Error("factors must be positive");const matrix=fromScaling([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],factors),results=objects.map((object=>isA$2(object)?transform$5(matrix,object):isA$5(object)?transform$a(matrix,object):isA$3(object)?transform$6(matrix,object):object));return 1===results.length?results[0]:results},pxPmm=1/.2822222,svgColors={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],grey:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]},svg2cag=(vec,svgUnitsPmm)=>[vec[0]/svgUnitsPmm[0],0-vec[1]/svgUnitsPmm[1]],cagLengthX=(css,svgUnitsPmm,svgUnitsX)=>{if(css.indexOf("%")<0)return css2cag(css,svgUnitsPmm[0]);let v=parseFloat(css);return isNaN(v)?0:0===v?v:(v=v/100*svgUnitsX,v/=svgUnitsPmm[0],Math.round(1e5*v)/1e5)},cagLengthY=(css,svgUnitsPmm,svgUnitsY)=>{if(css.indexOf("%")<0)return css2cag(css,svgUnitsPmm[1]);let v=parseFloat(css);return isNaN(v)?0:0===v?v:(v=v/100*svgUnitsY,v/=svgUnitsPmm[1],Math.round(1e5*v)/1e5)},cagLengthP=(css,svgUnitsPmm,svgUnitsV)=>{if(css.indexOf("%")<0)return css2cag(css,svgUnitsPmm[1]);let v=parseFloat(css);return isNaN(v)?0:(0===v||(v=v/100*svgUnitsV,v/=svgUnitsPmm[0]),v)},css2cag=(css,unit)=>{let v=parseFloat(css);return isNaN(v)?0:(0===v||css.search(/EM/i)>0||css.search(/EX/i)>0||css.search(/MM/i)>0||(css.search(/CM/i)>0?v*=10:css.search(/IN/i)>0?v/=.03937:css.search(/PT/i)>0?v/=2.8346400000000003:css.search(/PC/i)>0?v/=.23622:v/=unit),v)},cagColor=value=>{let rgb;if((value=value.toLowerCase())in svgColors)rgb=svgColors[value],rgb=[rgb[0]/255,rgb[1]/255,rgb[2]/255];else if("#"===value[0])4===value.length&&(value="#"+value[1]+value[1]+value[2]+value[2]+value[3]+value[3]),7===value.length&&(rgb=[parseInt("0x"+value.slice(1,3))/255,parseInt("0x"+value.slice(3,5))/255,parseInt("0x"+value.slice(5,7))/255]);else{let s=/rgb\(.+,.+,.+\)/.exec(value);null!==s&&(s=s[0],s=s.slice(s.indexOf("(")+1,s.indexOf(")")),rgb=s.split(","),s.indexOf("%")>0?(rgb=[parseInt(rgb[0]),parseInt(rgb[1]),parseInt(rgb[2])],rgb=[rgb[0]/100,rgb[1]/100,rgb[2]/100]):(rgb=[parseInt(rgb[0]),parseInt(rgb[1]),parseInt(rgb[2])],rgb=[rgb[0]/255,rgb[1]/255,rgb[2]/255]))}return rgb},cssStyle=(element,name)=>{if("style"in element){const list=element.style+";";let v=new RegExp(name+"\\s*:\\s*(\\S+);","i").exec(list);if(null!==v){v=v[0];let i=v.indexOf(":")+1;for(;" "===v[i];)i++;return v=v.slice(i,v.indexOf(";")),v}}},reflect=(x,y,px,py)=>{const ox=x-px,oy=y-py;return x===px&&y===px?[x,y]:x===px?[x,py+-oy]:y===py?[px+-ox,y]:[px+-ox,py+-oy]},svgColorForTarget=(target,svgObject)=>{let color=null;return"path"===target?svgObject.stroke?color=[svgObject.stroke[0],svgObject.stroke[1],svgObject.stroke[2],1]:svgObject.fill&&(color=[svgObject.fill[0],svgObject.fill[1],svgObject.fill[2],1]):svgObject.fill?color=[svgObject.fill[0],svgObject.fill[1],svgObject.fill[2],1]:svgObject.stroke&&(color=[svgObject.stroke[0],svgObject.stroke[1],svgObject.stroke[2],1]),color},svgCore=(obj,element)=>{"id"in element&&(obj.id=element.id),"position"in element&&(obj.position=element.position)},svgPresentation=(obj,element)=>{if("display"in element&&(obj.visible=element.display),"color"in element&&(obj.fill=cagColor(element.color),obj.stroke=obj.fill),"opacity"in element&&(obj.opacity=element.opacity),"fill"in element)obj.fill=cagColor(element.fill);else{const s=cssStyle(element,"fill");s&&(obj.fill=cagColor(s))}if("fill-opacity"in element&&(obj.opacity=element["fill-opacity"]),"stroke-width"in element)obj.strokeWidth=element["stroke-width"];else{const sw=cssStyle(element,"stroke-width");sw&&(obj.strokeWidth=sw)}if("stroke"in element)obj.stroke=cagColor(element.stroke);else{const s=cssStyle(element,"stroke");s&&(obj.stroke=cagColor(s))}"stroke-opacity"in element&&(obj.strokeOpacity=element["stroke-opacity"])},svgTransformsRegExp=/\w+\(.+\)/i,svgTransforms=(cag,element)=>{let list=null;if("transform"in element)list=element.transform;else{const s=cssStyle(element,"transform");s&&(list=s)}if(null!==list){cag.transforms=[];let v=svgTransformsRegExp.exec(list);for(;null!==v;){const s=svgTransformsRegExp.lastIndex,e=list.indexOf(")")+1;let t=list.slice(s,e);t=t.trim();const n=t.slice(0,t.indexOf("("));let o,a=t.slice(t.indexOf("(")+1,t.indexOf(")")).trim();switch(a=a.indexOf(",")>0?a.split(","):a.split(" "),n){case"translate":1===a.length&&a.push(0),o={translate:[a[0],a[1]]},cag.transforms.push(o);break;case"scale":1===a.length&&a.push(a[0]),o={scale:[a[0],a[1]]},cag.transforms.push(o);break;case"rotate":o={rotate:a},cag.transforms.push(o)}list=list.slice(e,list.length),v=svgTransformsRegExp.exec(list)}}},viewBoxRegExp=/([\d.-]+)[\s,]+([\d.-]+)[\s,]+([\d.-]+)[\s,]+([\d.-]+)/i,svgSvg=(element,{customPxPmm:customPxPmm})=>{const obj={type:"svg",x:0,y:0,width:"100%",height:"100%",strokeWidth:"1"};if(obj.unitsPmm=[pxPmm,pxPmm],"pxpmm"in element&&(obj.pxPmm=element.pxpmm,obj.unitsPmm=[obj.pxPmm,obj.pxPmm]),"width"in element&&(obj.width=element.width),"height"in element&&(obj.height=element.height),"viewBox"in element){const list=element.viewBox.trim(),v=viewBoxRegExp.exec(list);if(null!==v&&(obj.viewX=parseFloat(v[1]),obj.viewY=parseFloat(v[2]),obj.viewW=parseFloat(v[3]),obj.viewH=parseFloat(v[4])),obj.width.indexOf("%")<0){let s=css2cag(obj.width,customPxPmm);s=obj.viewW/s,obj.unitsPmm[0]=s}else{const u=obj.unitsPmm[0]*(parseFloat(obj.width)/100);obj.unitsPmm[0]=u}if(obj.height.indexOf("%")<0){let s=css2cag(obj.height,pxPmm);s=obj.viewH/s,obj.unitsPmm[1]=s}else{const u=obj.unitsPmm[1]*(parseFloat(obj.height)/100);obj.unitsPmm[1]=u}}else obj.viewX=0,obj.viewY=0,obj.viewW=1920/obj.unitsPmm[0],obj.viewH=1080/obj.unitsPmm[1];return obj.viewP=Math.sqrt(obj.viewW*obj.viewW+obj.viewH*obj.viewH)/Math.SQRT2,svgCore(obj,element),svgPresentation(obj,element),obj.objects=[],obj},svgEllipse=element=>{const obj={type:"ellipse",cx:"0",cy:"0",rx:"0",ry:"0"};return"cx"in element&&(obj.cx=element.cx),"cy"in element&&(obj.cy=element.cy),"rx"in element&&(obj.rx=element.rx),"ry"in element&&(obj.ry=element.ry),svgTransforms(obj,element),svgCore(obj,element),svgPresentation(obj,element),obj},svgLine=element=>{const obj={type:"line",x1:"0",y1:"0",x2:"0",y2:"0"};return"x1"in element&&(obj.x1=element.x1),"y1"in element&&(obj.y1=element.y1),"x2"in element&&(obj.x2=element.x2),"y2"in element&&(obj.y2=element.y2),svgTransforms(obj,element),svgCore(obj,element),svgPresentation(obj,element),obj},svgListOfPoints=list=>{const points=[],exp=/([\d\-+.]+)[\s,]+([\d\-+.]+)[\s,]*/i;list=list.trim();let v=exp.exec(list);for(;null!==v;){let point=v[0];const next=exp.lastIndex+point.length;point={x:v[1],y:v[2]},points.push(point),list=list.slice(next,list.length),v=exp.exec(list)}return points},svgPolyline=element=>{const obj={type:"polyline"};return svgTransforms(obj,element),svgCore(obj,element),svgPresentation(obj,element),"points"in element&&(obj.points=svgListOfPoints(element.points)),obj},svgPolygon=element=>{const obj={type:"polygon"};return svgTransforms(obj,element),svgCore(obj,element),svgPresentation(obj,element),"points"in element&&(obj.points=svgListOfPoints(element.points)),obj},svgRect=element=>{const obj={type:"rect",x:"0",y:"0",rx:"0",ry:"0",width:"0",height:"0"};return"x"in element&&(obj.x=element.x),"y"in element&&(obj.y=element.y),"rx"in element&&(obj.rx=element.rx,"ry"in element||(obj.ry=obj.rx)),"ry"in element&&(obj.ry=element.ry,"rx"in element||(obj.rx=obj.ry)),obj.rx!==obj.ry&&console.log("Warning: Unsupported RECT with rx and ry radius"),"width"in element&&(obj.width=element.width),"height"in element&&(obj.height=element.height),svgTransforms(obj,element),svgCore(obj,element),svgPresentation(obj,element),obj},svgCircle=element=>{const obj={type:"circle",x:"0",y:"0",radius:"0"};return"cx"in element&&(obj.x=element.cx),"cy"in element&&(obj.y=element.cy),"r"in element&&(obj.radius=element.r),svgTransforms(obj,element),svgCore(obj,element),svgPresentation(obj,element),obj},svgGroup=element=>{const obj={type:"group"};if(svgTransforms(obj,element),svgCore(obj,element),svgPresentation(obj,element),"x"in element||"y"in element){let x="0",y="0";"x"in element&&(x=element.x),"y"in element&&(y=element.y),"transforms"in obj||(obj.transforms=[]);const o={translate:[x,y]};obj.transforms.push(o)}return obj.objects=[],obj},svgPath=element=>{const obj={type:"path"};if(svgTransforms(obj,element),svgCore(obj,element),svgPresentation(obj,element),obj.commands=[],"d"in element){let co=null,bf="",i=0;const l=element.d.length,offset=element.position[1]-l-2;for(;i<l;){const c=element.d[i];switch(c){case"-":bf.length>0&&(co.p.push(bf),bf=""),bf+=c;break;case".":bf.length>0&&bf.indexOf(".")>=0&&(co.p.push(bf),bf=""),bf+=c;break;case"0":case"1":case"2":case"3":case"4":case"5":case"6":case"7":case"8":case"9":bf+=c;break;case"a":case"A":case"c":case"C":case"h":case"H":case"l":case"L":case"v":case"V":case"m":case"M":case"q":case"Q":case"s":case"S":case"t":case"T":case"z":case"Z":null!==co&&(bf.length>0&&(co.p.push(bf),bf=""),obj.commands.push(co)),co={c:c,p:[],pos:i+offset};break;case",":case" ":case"\n":null!==co&&bf.length>0&&(co.p.push(bf),bf="")}i++}i===l&&null!==co&&(bf.length>0&&co.p.push(bf),obj.commands.push(co))}return obj},svgUse=(element,{svgObjects:svgObjects})=>{const obj={type:"group"};if(svgTransforms(obj,element),svgCore(obj,element),svgPresentation(obj,element),"x"in element||"y"in element){let x="0",y="0";"x"in element&&(x=element.x),"y"in element&&(y=element.y),"transforms"in obj||(obj.transforms=[]);const o={translate:[x,y]};obj.transforms.push(o)}if(obj.objects=[],"xlink:href"in element){let ref=element["xlink:href"];"#"===ref[0]&&(ref=ref.slice(1,ref.length)),void 0!==svgObjects[ref]&&(ref=svgObjects[ref],ref=JSON.parse(JSON.stringify(ref)),obj.objects.push(ref))}return obj},shapesMapGeometry=(obj,objectify,params)=>{const{svgUnitsPmm:svgUnitsPmm,svgUnitsX:svgUnitsX,svgUnitsY:svgUnitsY,svgUnitsV:svgUnitsV,svgGroups:svgGroups,target:target,segments:segments,pathSelfClosed:pathSelfClosed}=params,types={group:obj=>objectify({target:target,segments:segments},obj),rect:(obj,svgUnitsPmm,svgUnitsX,svgUnitsY,svgUnitsV,svgGroups,segments)=>{let x=cagLengthX(obj.x,svgUnitsPmm,svgUnitsX),y=0-cagLengthY(obj.y,svgUnitsPmm,svgUnitsY);const w=cagLengthX(obj.width,svgUnitsPmm,svgUnitsX),h=cagLengthY(obj.height,svgUnitsPmm,svgUnitsY),rx=cagLengthX(obj.rx,svgUnitsPmm,svgUnitsX);let shape;return w>0&&h>0&&(x+=w/2,y-=h/2,shape=0===rx?rectangle({center:[x,y],size:[w,h]}):(options=>{let{center:center,size:size,roundRadius:roundRadius,segments:segments}=Object.assign({},{center:[0,0],size:[2,2],roundRadius:.2,segments:32},options);if(!isNumberArray(center,2))throw new Error("center must be an array of X and Y values");if(!isNumberArray(size,2))throw new Error("size must be an array of X and Y values");if(!size.every((n=>n>=0)))throw new Error("size values must be positive");if(!isGTE(roundRadius,0))throw new Error("roundRadius must be positive");if(!isGTE(segments,4))throw new Error("segments must be four or more");if(0===size[0]||0===size[1])return create$a();if(0===roundRadius)return rectangle({center:center,size:size});if(size=size.map((v=>v/2)),roundRadius>size[0]-EPS||roundRadius>size[1]-EPS)throw new Error("roundRadius must be smaller then the radius of all dimensions");const cornerSegments=Math.floor(segments/4),corner0=add([0,0],center,[size[0]-roundRadius,size[1]-roundRadius]),corner1=add([0,0],center,[roundRadius-size[0],size[1]-roundRadius]),corner2=add([0,0],center,[roundRadius-size[0],roundRadius-size[1]]),corner3=add([0,0],center,[size[0]-roundRadius,roundRadius-size[1]]),corner0Points=[],corner1Points=[],corner2Points=[],corner3Points=[];for(let i=0;i<=cornerSegments;i++){const point=fromAngleRadians([0,0],TAU/4*i/cornerSegments);scale$1(point,point,roundRadius),corner0Points.push(add([0,0],corner0,point)),rotate$1(point,point,[0,0],TAU/4),corner1Points.push(add([0,0],corner1,point)),rotate$1(point,point,[0,0],TAU/4),corner2Points.push(add([0,0],corner2,point)),rotate$1(point,point,[0,0],TAU/4),corner3Points.push(add([0,0],corner3,point))}const points=corner0Points.concat(corner1Points,corner2Points,corner3Points);return create$a([points])})({center:[x,y],segments:segments,size:[w,h],roundRadius:rx}),"path"===target&&(shape=index$5.fromPoints({closed:!0},index$a.toPoints(shape)))),shape},circle:(obj,svgUnitsPmm,svgUnitsX,svgUnitsY,svgUnitsV,svgGroups,segments)=>{const x=cagLengthX(obj.x,svgUnitsPmm,svgUnitsX),y=0-cagLengthY(obj.y,svgUnitsPmm,svgUnitsY),r=cagLengthP(obj.radius,svgUnitsPmm,svgUnitsV);let shape;return r>0&&(shape=(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})})({center:[x,y],segments:segments,radius:r}),"path"===target&&(shape=index$5.fromPoints({closed:!0},index$a.toPoints(shape)))),shape},ellipse:(obj,svgUnitsPmm,svgUnitsX,svgUnitsY,svgUnitsV,svgGroups,segments)=>{const rx=cagLengthX(obj.rx,svgUnitsPmm,svgUnitsX),ry=cagLengthY(obj.ry,svgUnitsPmm,svgUnitsY),cx=cagLengthX(obj.cx,svgUnitsPmm,svgUnitsX),cy=0-cagLengthY(obj.cy,svgUnitsPmm,svgUnitsY);let shape;return rx>0&&ry>0&&(shape=ellipse({center:[cx,cy],segments:segments,radius:[rx,ry]}),"path"===target&&(shape=index$5.fromPoints({closed:!0},index$a.toPoints(shape)))),shape},line:(obj,svgUnitsPmm,svgUnitsX,svgUnitsY,svgUnitsV)=>{const x1=cagLengthX(obj.x1,svgUnitsPmm,svgUnitsX),y1=0-cagLengthY(obj.y1,svgUnitsPmm,svgUnitsY),x2=cagLengthX(obj.x2,svgUnitsPmm,svgUnitsX),y2=0-cagLengthY(obj.y2,svgUnitsPmm,svgUnitsY);return line([[x1,y1],[x2,y2]])},polygon:(obj,svgUnitsPmm,svgUnitsX,svgUnitsY)=>{const points=[];for(let j=0;j<obj.points.length;j++){const p=obj.points[j];if("x"in p&&"y"in p){const x=cagLengthX(p.x,svgUnitsPmm,svgUnitsX),y=0-cagLengthY(p.y,svgUnitsPmm,svgUnitsY);points.push([x,y])}}return"geom2"===target?index$a.create([points]):index$5.fromPoints({},points)},polyline:(obj,svgUnitsPmm,svgUnitsX,svgUnitsY,svgUnitsV)=>{const points=[];for(let j=0;j<obj.points.length;j++){const p=obj.points[j];if("x"in p&&"y"in p){const x=cagLengthX(p.x,svgUnitsPmm,svgUnitsX),y=0-cagLengthY(p.y,svgUnitsPmm,svgUnitsY);points.push([x,y])}}return line(points)},path:(obj,svgUnitsPmm,svgUnitsX,svgUnitsY,svgUnitsV,svgGroups,segments)=>{const listofpaths=expandPath(obj,svgUnitsPmm,svgUnitsX,svgUnitsY,svgUnitsV,svgGroups,segments,pathSelfClosed),shapes=Object.entries(listofpaths).sort(((a,b)=>a[0].localeCompare(b[0]))).map((entry=>{const path=entry[1];if("geom2"===target&&path.isClosed){const points=index$5.toPoints(path);return index$a.create([points])}return path}));return shapes}};return types[obj.type](obj,svgUnitsPmm,svgUnitsX,svgUnitsY,svgUnitsV,svgGroups,segments)},appendPoints=(points,geometry)=>geometry?index$5.appendPoints(points,geometry):index$5.fromPoints({},points),expandPath=(obj,svgUnitsPmm,svgUnitsX,svgUnitsY,svgUnitsV,svgGroups,segments,pathSelfClosed)=>{const paths={};let sx=0,sy=0,cx=0,cy=0,pi=0,pathName="path"+pi,pc=!1,bx=0,by=0,qx=0,qy=0;const newPath=()=>{pi++,pathName="path"+pi,pc=!1},ensurePath=()=>{paths[pathName]||(paths[pathName]=index$5.fromPoints({},[]))};for(let j=0;j<obj.commands.length;j++){const co=obj.commands[j],pts=co.p;let i=0;switch(co.c){case"m":for(0===j&&(cx=0,cy=0),pts.length>=i+2&&(cx+=parseFloat(pts[i++]),cy+=parseFloat(pts[i++]),newPath(),paths[pathName]=appendPoints([svg2cag([cx,cy],svgUnitsPmm)]),sx=cx,sy=cy);pts.length>=i+2;)cx+=parseFloat(pts[i++]),cy+=parseFloat(pts[i++]),paths[pathName]=appendPoints([svg2cag([cx,cy],svgUnitsPmm)],paths[pathName]);break;case"M":for(pts.length>=i+2&&(cx=parseFloat(pts[i++]),cy=parseFloat(pts[i++]),newPath(),paths[pathName]=appendPoints([svg2cag([cx,cy],svgUnitsPmm)]),sx=cx,sy=cy);pts.length>=i+2;)cx=parseFloat(pts[i++]),cy=parseFloat(pts[i++]),paths[pathName]=appendPoints([svg2cag([cx,cy],svgUnitsPmm)],paths[pathName]);break;case"a":for(;pts.length>=i+7;){const rx=parseFloat(pts[i++]),ry=parseFloat(pts[i++]),ro=0-.017453292519943295*parseFloat(pts[i++]),lf="1"===pts[i++],sf="1"===pts[i++];cx+=parseFloat(pts[i++]),cy+=parseFloat(pts[i++]),ensurePath(),paths[pathName]=index$5.appendArc({segments:segments,endpoint:svg2cag([cx,cy],svgUnitsPmm),radius:svg2cag([rx,ry],svgUnitsPmm),xaxisrotation:ro,clockwise:sf,large:lf},paths[pathName])}break;case"A":for(;pts.length>=i+7;){const rx=parseFloat(pts[i++]),ry=parseFloat(pts[i++]),ro=0-.017453292519943295*parseFloat(pts[i++]),lf="1"===pts[i++],sf="1"===pts[i++];cx=parseFloat(pts[i++]),cy=parseFloat(pts[i++]),ensurePath(),paths[pathName]=index$5.appendArc({segments:segments,endpoint:svg2cag([cx,cy],svgUnitsPmm),radius:svg2cag([rx,ry],svgUnitsPmm),xaxisrotation:ro,clockwise:sf,large:lf},paths[pathName])}break;case"c":for(;pts.length>=i+6;){const x1=cx+parseFloat(pts[i++]),y1=cy+parseFloat(pts[i++]);bx=cx+parseFloat(pts[i++]),by=cy+parseFloat(pts[i++]),cx+=parseFloat(pts[i++]),cy+=parseFloat(pts[i++]),ensurePath(),paths[pathName]=index$5.appendBezier({segments:segments,controlPoints:[svg2cag([x1,y1],svgUnitsPmm),svg2cag([bx,by],svgUnitsPmm),svg2cag([cx,cy],svgUnitsPmm)]},paths[pathName]);const rf=reflect(bx,by,cx,cy);bx=rf[0],by=rf[1]}break;case"C":for(;pts.length>=i+6;){const x1=parseFloat(pts[i++]),y1=parseFloat(pts[i++]);bx=parseFloat(pts[i++]),by=parseFloat(pts[i++]),cx=parseFloat(pts[i++]),cy=parseFloat(pts[i++]),ensurePath(),paths[pathName]=index$5.appendBezier({segments:segments,controlPoints:[svg2cag([x1,y1],svgUnitsPmm),svg2cag([bx,by],svgUnitsPmm),svg2cag([cx,cy],svgUnitsPmm)]},paths[pathName]);const rf=reflect(bx,by,cx,cy);bx=rf[0],by=rf[1]}break;case"q":for(;pts.length>=i+4;){const p0=[cx,cy];qx=cx+parseFloat(pts[i++]),qy=cy+parseFloat(pts[i++]),cx+=parseFloat(pts[i++]),cy+=parseFloat(pts[i++]);const q1=[p0[0]+2/3*(qx-p0[0]),p0[1]+2/3*(qy-p0[1])],q2=[q1[0]+1/3*(cx-p0[0]),q1[1]+1/3*(cy-p0[1])];ensurePath(),paths[pathName]=index$5.appendBezier({segments:segments,controlPoints:[svg2cag(q1,svgUnitsPmm),svg2cag(q2,svgUnitsPmm),svg2cag([cx,cy],svgUnitsPmm)]},paths[pathName]);const rf=reflect(qx,qy,cx,cy);qx=rf[0],qy=rf[1]}break;case"Q":for(;pts.length>=i+4;){const p0=[cx,cy];qx=parseFloat(pts[i++]),qy=parseFloat(pts[i++]),cx=parseFloat(pts[i++]),cy=parseFloat(pts[i++]);const q1=[p0[0]+2/3*(qx-p0[0]),p0[1]+2/3*(qy-p0[1])],q2=[q1[0]+1/3*(cx-p0[0]),q1[1]+1/3*(cy-p0[1])];ensurePath(),paths[pathName]=index$5.appendBezier({segments:segments,controlPoints:[svg2cag(q1,svgUnitsPmm),svg2cag(q2,svgUnitsPmm),svg2cag([cx,cy],svgUnitsPmm)]},paths[pathName]);const rf=reflect(qx,qy,cx,cy);qx=rf[0],qy=rf[1]}break;case"t":for(;pts.length>=i+2;){const p0=[cx,cy];cx+=parseFloat(pts[i++]),cy+=parseFloat(pts[i++]);const q1=[p0[0]+2/3*(qx-p0[0]),p0[1]+2/3*(qy-p0[1])],q2=[q1[0]+1/3*(cx-p0[0]),q1[1]+1/3*(cy-p0[1])];ensurePath(),paths[pathName]=index$5.appendBezier({segments:segments,controlPoints:[svg2cag(q1,svgUnitsPmm),svg2cag(q2,svgUnitsPmm),svg2cag([cx,cy],svgUnitsPmm)]},paths[pathName]);const rf=reflect(qx,qy,cx,cy);qx=rf[0],qy=rf[1]}break;case"T":for(;pts.length>=i+2;){const p0=[cx,cy];cx=parseFloat(pts[i++]),cy=parseFloat(pts[i++]);const q1=[p0[0]+2/3*(qx-p0[0]),p0[1]+2/3*(qy-p0[1])],q2=[q1[0]+1/3*(cx-p0[0]),q1[1]+1/3*(cy-p0[1])];ensurePath(),paths[pathName]=index$5.appendBezier({segments:segments,controlPoints:[svg2cag(q1,svgUnitsPmm),svg2cag(q2,svgUnitsPmm),svg2cag([cx,cy],svgUnitsPmm)]},paths[pathName]);const rf=reflect(qx,qy,cx,cy);qx=rf[0],qy=rf[1]}break;case"s":for(;pts.length>=i+4;){const x1=bx,y1=by;bx=cx+parseFloat(pts[i++]),by=cy+parseFloat(pts[i++]),cx+=parseFloat(pts[i++]),cy+=parseFloat(pts[i++]),ensurePath(),paths[pathName]=index$5.appendBezier({segments:segments,controlPoints:[svg2cag([x1,y1],svgUnitsPmm),svg2cag([bx,by],svgUnitsPmm),svg2cag([cx,cy],svgUnitsPmm)]},paths[pathName]);const rf=reflect(bx,by,cx,cy);bx=rf[0],by=rf[1]}break;case"S":for(;pts.length>=i+4;){const x1=bx,y1=by;bx=parseFloat(pts[i++]),by=parseFloat(pts[i++]),cx=parseFloat(pts[i++]),cy=parseFloat(pts[i++]),ensurePath(),paths[pathName]=index$5.appendBezier({segments:segments,controlPoints:[svg2cag([x1,y1],svgUnitsPmm),svg2cag([bx,by],svgUnitsPmm),svg2cag([cx,cy],svgUnitsPmm)]},paths[pathName]);const rf=reflect(bx,by,cx,cy);bx=rf[0],by=rf[1]}break;case"h":for(;pts.length>=i+1;)cx+=parseFloat(pts[i++]),paths[pathName]=appendPoints([svg2cag([cx,cy],svgUnitsPmm)],paths[pathName]);break;case"H":for(;pts.length>=i+1;)cx=parseFloat(pts[i++]),paths[pathName]=appendPoints([svg2cag([cx,cy],svgUnitsPmm)],paths[pathName]);break;case"l":for(;pts.length>=i+2;)cx+=parseFloat(pts[i++]),cy+=parseFloat(pts[i++]),paths[pathName]=appendPoints([svg2cag([cx,cy],svgUnitsPmm)],paths[pathName]);break;case"L":for(;pts.length>=i+2;)cx=parseFloat(pts[i++]),cy=parseFloat(pts[i++]),paths[pathName]=appendPoints([svg2cag([cx,cy],svgUnitsPmm)],paths[pathName]);break;case"v":for(;pts.length>=i+1;)cy+=parseFloat(pts[i++]),paths[pathName]=appendPoints([svg2cag([cx,cy],svgUnitsPmm)],paths[pathName]);break;case"V":for(;pts.length>=i+1;)cy=parseFloat(pts[i++]),paths[pathName]=appendPoints([svg2cag([cx,cy],svgUnitsPmm)],paths[pathName]);break;case"z":case"Z":paths[pathName]=index$5.close(paths[pathName]),cx=sx,cy=sy,pc=!0;break;default:console.log("Warning: Unknown PATH command ["+co.c+"]")}const isCloseCmd=cmd=>"z"===cmd||"Z"===cmd;if(!0!==pc&&paths[pathName]&&paths[pathName].isClosed){let coNext=obj.commands[j+1];if(coNext&&!isCloseCmd(coNext.c))if("trim"===pathSelfClosed)for(;coNext&&!isCloseCmd(coNext.c);)j++,coNext=obj.commands[j+1];else{if("split"!==pathSelfClosed)throw new Error(`Malformed svg path at ${obj.position[0]}:${co.pos}. Path closed itself with command #${j} ${co.c}${pts.join(" ")}`);newPath()}}}return paths},shapesMapJscad=(obj,codify,params)=>{const{level:level,indent:indent,on:on,svgUnitsPmm:svgUnitsPmm,svgUnitsX:svgUnitsX,svgUnitsY:svgUnitsY,svgUnitsV:svgUnitsV,svgGroups:svgGroups,target:target,segments:segments}=params,types={group:obj=>{let code=codify({target:target,segments:segments},obj);return code+=`${indent}${on} = levels.l${level+1}\n`,code},rect:(obj,svgUnitsPmm,svgUnitsX,svgUnitsY,svgUnitsV,params,svgGroups,segments)=>{let x=cagLengthX(obj.x,svgUnitsPmm,svgUnitsX),y=0-cagLengthY(obj.y,svgUnitsPmm,svgUnitsY);const w=cagLengthX(obj.width,svgUnitsPmm,svgUnitsX),h=cagLengthY(obj.height,svgUnitsPmm,svgUnitsY),rx=cagLengthX(obj.rx,svgUnitsPmm,svgUnitsX);let code;return w>0&&h>0&&(x=(x+w/2).toFixed(4),y=(y-h/2).toFixed(4),code=0===rx?`${indent}${on} = rectangle({center: [${x}, ${y}], size: [${w}, ${h}]}) // line ${obj.position}\n`:`${indent}${on} = roundedRectangle({center: [${x}, ${y}], segments: ${segments}, size: [${w}, ${h}], roundRadius: ${rx}}) // line ${obj.position}\n`,"path"===target&&(code+=`${indent}${on} = path2.fromPoints({closed: true}, geom2.toPoints(${on}))\n`)),code},circle:(obj,svgUnitsPmm,svgUnitsX,svgUnitsY,svgUnitsV,params,svgGroups,segments)=>{const x=cagLengthX(obj.x,svgUnitsPmm,svgUnitsX),y=0-cagLengthY(obj.y,svgUnitsPmm,svgUnitsY),r=cagLengthP(obj.radius,svgUnitsPmm,svgUnitsV);let code;return r>0&&(code=`${indent}${on} = circle({center: [${x}, ${y}], segments: ${segments}, radius: ${r}}) // line ${obj.position}\n`,"path"===target&&(code+=`${indent}${on} = path2.fromPoints({closed: true}, geom2.toPoints(${on}))\n`)),code},ellipse:(obj,svgUnitsPmm,svgUnitsX,svgUnitsY,svgUnitsV,params,svgGroups,segments)=>{const rx=cagLengthX(obj.rx,svgUnitsPmm,svgUnitsX),ry=cagLengthY(obj.ry,svgUnitsPmm,svgUnitsY),cx=cagLengthX(obj.cx,svgUnitsPmm,svgUnitsX),cy=0-cagLengthY(obj.cy,svgUnitsPmm,svgUnitsY);let code;return rx>0&&ry>0&&(code=`${indent}${on} = ellipse({center: [${cx}, ${cy}], segments: ${segments}, radius: [${rx}, ${ry}]}) // line ${obj.position}\n`,"path"===target&&(code+=`${indent}${on} = path2.fromPoints({closed: true}, geom2.toPoints(${on}))\n`)),code},line:(obj,svgUnitsPmm,svgUnitsX,svgUnitsY,svgUnitsV)=>{const x1=cagLengthX(obj.x1,svgUnitsPmm,svgUnitsX),y1=0-cagLengthY(obj.y1,svgUnitsPmm,svgUnitsY),x2=cagLengthX(obj.x2,svgUnitsPmm,svgUnitsX),y2=0-cagLengthY(obj.y2,svgUnitsPmm,svgUnitsY);return`${indent}${on} = line([[${x1}, ${y1}], [${x2}, ${y2}]]) // line ${obj.position}\n`},polygon:(obj,svgUnitsPmm,svgUnitsX,svgUnitsY)=>{let code=`${indent}${on} = polygon({points: [\n`;for(let j=0;j<obj.points.length;j++){const p=obj.points[j];if("x"in p&&"y"in p){const x=cagLengthX(p.x,svgUnitsPmm,svgUnitsX),y=0-cagLengthY(p.y,svgUnitsPmm,svgUnitsY);code+=`${indent} [${x}, ${y}],\n`}}return code+=`${indent}]}) // line ${obj.position}\n`,"path"===target&&(code+=`${indent}${on} = path2.fromPoints({closed: true}, geom2.toPoints(${on}))\n`),code},polyline:(obj,svgUnitsPmm,svgUnitsX,svgUnitsY,svgUnitsV)=>{let code=`${indent}${on} = path2.fromPoints({}, [\n`;for(let j=0;j<obj.points.length;j++){const p=obj.points[j];if("x"in p&&"y"in p){const x=cagLengthX(p.x,svgUnitsPmm,svgUnitsX),y=0-cagLengthY(p.y,svgUnitsPmm,svgUnitsY);code+=`${indent} [${x}, ${y}],\n`}}return code+=`${indent}]) // line ${obj.position}\n`,code},path:path};return types[obj.type](obj,svgUnitsPmm,svgUnitsX,svgUnitsY,svgUnitsV,params,svgGroups,segments)},path=(obj,svgUnitsPmm,svgUnitsX,svgUnitsY,svgUnitsV,params,svgGroups,segments)=>{const{indent:indent,on:on,target:target}=params;let tmpCode=`${indent}parts = [] // line ${obj.position}\n`,sx=0,sy=0,cx=0,cy=0,pi=0,pathName=on+pi,pc=!1,bx=0,by=0,qx=0,qy=0;for(let j=0;j<obj.commands.length;j++){const co=obj.commands[j],pts=co.p;switch(co.c){case"m":for(0===j&&(cx=0,cy=0),pi>0&&!1===pc&&(tmpCode+=`${indent}parts.push(${pathName})\n`),pts.length>=2&&(cx+=parseFloat(pts.shift()),cy+=parseFloat(pts.shift()),pi++,pc=!1,pathName=on+pi,tmpCode+=`${indent}${pathName} = path2.fromPoints({}, [[${svg2cag([cx,cy],svgUnitsPmm)}]])\n`,sx=cx,sy=cy);pts.length>=2;)cx+=parseFloat(pts.shift()),cy+=parseFloat(pts.shift()),tmpCode+=`${indent}${pathName} = path2.appendPoints([${svg2cag([cx,cy],svgUnitsPmm)}], ${pathName})\n`;break;case"M":for(pi>0&&!1===pc&&(tmpCode+=`${indent}parts.push(${pathName})\n`),pts.length>=2&&(cx=parseFloat(pts.shift()),cy=parseFloat(pts.shift()),pi++,pc=!1,pathName=on+pi,tmpCode+=`${indent}${pathName} = path2.fromPoints({}, [[${svg2cag([cx,cy],svgUnitsPmm)}]])\n`,sx=cx,sy=cy);pts.length>=2;)cx=parseFloat(pts.shift()),cy=parseFloat(pts.shift()),tmpCode+=`${indent}${pathName} = path2.appendPoints([${svg2cag([cx,cy],svgUnitsPmm)}], ${pathName})\n`;break;case"a":for(;pts.length>=7;){const rx=parseFloat(pts.shift()),ry=parseFloat(pts.shift()),ro=0-.017453292519943295*parseFloat(pts.shift()),lf="1"===pts.shift(),sf="1"===pts.shift();cx+=parseFloat(pts.shift()),cy+=parseFloat(pts.shift()),tmpCode+=`${indent}${pathName} = path2.appendArc({segments: ${segments}, endpoint: [${svg2cag([cx,cy],svgUnitsPmm)}], radius: [${svg2cag([rx,ry],svgUnitsPmm)}], xaxisrotation: ${ro}, clockwise: ${sf}, large: ${lf}}, ${pathName})\n`}break;case"A":for(;pts.length>=7;){const rx=parseFloat(pts.shift()),ry=parseFloat(pts.shift()),ro=0-.017453292519943295*parseFloat(pts.shift()),lf="1"===pts.shift(),sf="1"===pts.shift();cx=parseFloat(pts.shift()),cy=parseFloat(pts.shift()),tmpCode+=`${indent}${pathName} = path2.appendArc({segments: ${segments}, endpoint: [${svg2cag([cx,cy],svgUnitsPmm)}], radius: [${svg2cag([rx,ry],svgUnitsPmm)}], xaxisrotation: ${ro}, clockwise: ${sf}, large: ${lf}}, ${pathName})\n`}break;case"c":for(;pts.length>=6;){const x1=cx+parseFloat(pts.shift()),y1=cy+parseFloat(pts.shift());bx=cx+parseFloat(pts.shift()),by=cy+parseFloat(pts.shift()),cx+=parseFloat(pts.shift()),cy+=parseFloat(pts.shift()),tmpCode+=`${indent}${pathName} = path2.appendBezier({segments: ${segments}, controlPoints: [[${svg2cag([x1,y1],svgUnitsPmm)}], [${svg2cag([bx,by],svgUnitsPmm)}], [${svg2cag([cx,cy],svgUnitsPmm)}]]}, ${pathName})\n`;const rf=reflect(bx,by,cx,cy);bx=rf[0],by=rf[1]}break;case"C":for(;pts.length>=6;){const x1=parseFloat(pts.shift()),y1=parseFloat(pts.shift());bx=parseFloat(pts.shift()),by=parseFloat(pts.shift()),cx=parseFloat(pts.shift()),cy=parseFloat(pts.shift()),tmpCode+=`${indent}${pathName} = path2.appendBezier({segments: ${segments}, controlPoints: [[${svg2cag([x1,y1],svgUnitsPmm)}], [${svg2cag([bx,by],svgUnitsPmm)}], [${svg2cag([cx,cy],svgUnitsPmm)}]]}, ${pathName})\n`;const rf=reflect(bx,by,cx,cy);bx=rf[0],by=rf[1]}break;case"q":for(;pts.length>=4;){const p0=[cx,cy];qx=cx+parseFloat(pts.shift()),qy=cy+parseFloat(pts.shift()),cx+=parseFloat(pts.shift()),cy+=parseFloat(pts.shift());const q1=[p0[0]+2/3*(qx-p0[0]),p0[1]+2/3*(qy-p0[1])],q2=[q1[0]+1/3*(cx-p0[0]),q1[1]+1/3*(cy-p0[1])];tmpCode+=`${indent}${pathName} = path2.appendBezier({segments: ${segments}, controlPoints: [[${svg2cag(q1,svgUnitsPmm)}], [${svg2cag(q2,svgUnitsPmm)}], [${svg2cag([cx,cy],svgUnitsPmm)}]]}, ${pathName})\n`;const rf=reflect(qx,qy,cx,cy);qx=rf[0],qy=rf[1]}break;case"Q":for(;pts.length>=4;){const p0=[cx,cy];qx=parseFloat(pts.shift()),qy=parseFloat(pts.shift()),cx=parseFloat(pts.shift()),cy=parseFloat(pts.shift());const q1=[p0[0]+2/3*(qx-p0[0]),p0[1]+2/3*(qy-p0[1])],q2=[q1[0]+1/3*(cx-p0[0]),q1[1]+1/3*(cy-p0[1])];tmpCode+=`${indent}${pathName} = path2.appendBezier({segments: ${segments}, controlPoints: [[${svg2cag(q1,svgUnitsPmm)}], [${svg2cag(q2,svgUnitsPmm)}], [${svg2cag([cx,cy],svgUnitsPmm)}]]}, ${pathName})\n`;const rf=reflect(qx,qy,cx,cy);qx=rf[0],qy=rf[1]}break;case"t":for(;pts.length>=2;){const p0=[cx,cy];cx+=parseFloat(pts.shift()),cy+=parseFloat(pts.shift());const q1=[p0[0]+2/3*(qx-p0[0]),p0[1]+2/3*(qy-p0[1])],q2=[q1[0]+1/3*(cx-p0[0]),q1[1]+1/3*(cy-p0[1])];tmpCode+=`${indent}${pathName} = path2.appendBezier({segments: ${segments}, controlPoints: [[[${svg2cag(q1,svgUnitsPmm)}], [${svg2cag(q2,svgUnitsPmm)}], [${svg2cag([cx,cy],svgUnitsPmm)}]]}, ${pathName})\n`;const rf=reflect(qx,qy,cx,cy);qx=rf[0],qy=rf[1]}break;case"T":for(;pts.length>=2;){const p0=[cx,cy];cx=parseFloat(pts.shift()),cy=parseFloat(pts.shift());const q1=[p0[0]+2/3*(qx-p0[0]),p0[1]+2/3*(qy-p0[1])],q2=[q1[0]+1/3*(cx-p0[0]),q1[1]+1/3*(cy-p0[1])];tmpCode+=`${indent}${pathName} = path2.appendBezier({segments: ${segments}, controlPoints: [[[${svg2cag(q1,svgUnitsPmm)}], [${svg2cag(q2,svgUnitsPmm)}], [${svg2cag([cx,cy],svgUnitsPmm)}]]}, ${pathName})\n`;const rf=reflect(qx,qy,cx,cy);qx=rf[0],qy=rf[1]}break;case"s":for(;pts.length>=4;){const x1=bx,y1=by;bx=cx+parseFloat(pts.shift()),by=cy+parseFloat(pts.shift()),cx+=parseFloat(pts.shift()),cy+=parseFloat(pts.shift()),tmpCode+=`${indent}${pathName} = path2.appendBezier({segments: ${segments}, controlPoints: [[${svg2cag([x1,y1],svgUnitsPmm)}], [${svg2cag([bx,by],svgUnitsPmm)}], [${svg2cag([cx,cy],svgUnitsPmm)}]]}, ${pathName})\n`;const rf=reflect(bx,by,cx,cy);bx=rf[0],by=rf[1]}break;case"S":for(;pts.length>=4;){const x1=bx,y1=by;bx=parseFloat(pts.shift()),by=parseFloat(pts.shift()),cx=parseFloat(pts.shift()),cy=parseFloat(pts.shift()),tmpCode+=`${indent}${pathName} = path2.appendBezier({segments: ${segments}, controlPoints: [[${svg2cag([x1,y1],svgUnitsPmm)}], [${svg2cag([bx,by],svgUnitsPmm)}], [${svg2cag([cx,cy],svgUnitsPmm)}]]}, ${pathName})\n`;const rf=reflect(bx,by,cx,cy);bx=rf[0],by=rf[1]}break;case"h":for(;pts.length>=1;)cx+=parseFloat(pts.shift()),tmpCode+=`${indent}${pathName} = path2.appendPoints([[${svg2cag([cx,cy],svgUnitsPmm)}]], ${pathName})\n`;break;case"H":for(;pts.length>=1;)cx=parseFloat(pts.shift()),tmpCode+=`${indent}${pathName} = path2.appendPoints([[${svg2cag([cx,cy],svgUnitsPmm)}]], ${pathName})\n`;break;case"l":for(;pts.length>=2;)cx+=parseFloat(pts.shift()),cy+=parseFloat(pts.shift()),tmpCode+=`${indent}${pathName} = path2.appendPoints([[${svg2cag([cx,cy],svgUnitsPmm)}]], ${pathName})\n`;break;case"L":for(;pts.length>=2;)cx=parseFloat(pts.shift()),cy=parseFloat(pts.shift()),tmpCode+=`${indent}${pathName} = path2.appendPoints([[${svg2cag([cx,cy],svgUnitsPmm)}]], ${pathName})\n`;break;case"v":for(;pts.length>=1;)cy+=parseFloat(pts.shift()),tmpCode+=`${indent}${pathName} = path2.appendPoints([[${svg2cag([cx,cy],svgUnitsPmm)}]], ${pathName})\n`;break;case"V":for(;pts.length>=1;)cy=parseFloat(pts.shift()),tmpCode+=`${indent}${pathName} = path2.appendPoints([[${svg2cag([cx,cy],svgUnitsPmm)}]], ${pathName})\n`;break;case"z":case"Z":tmpCode+=`${indent}${pathName} = path2.close(${pathName})\n`,"geom2"===target&&(tmpCode+=`${indent}${pathName} = geom2.create([path2.toPoints(${pathName})])\n`),tmpCode+=`${indent}parts.push(${pathName})\n`,cx=sx,cy=sy,pc=!0;break;default:console.log("Warning: Unknow PATH command ["+co.c+"]")}}return pi>0&&!1===pc&&(tmpCode+=`${indent}parts.push(${pathName})\n`),tmpCode+=`${indent}${on} = parts\n`,tmpCode},instantiate=(src,options)=>{const{pxPmm:pxPmm}=options;if(options&&options.statusCallback&&options.statusCallback({progress:0}),createSvgParser(src,pxPmm),!svgObj)throw new Error("SVG parsing failed, no valid SVG data retrieved");options&&options.statusCallback&&options.statusCallback({progress:50});const result=objectify(options,svgObj);return options&&options.statusCallback&&options.statusCallback({progress:100}),result},translateScript=(src,options)=>{const{filename:filename,version:version,pxPmm:pxPmm,addMetaData:addMetaData}=options;if(options&&options.statusCallback&&options.statusCallback({progress:0}),createSvgParser(src,pxPmm),!svgObj)throw new Error("SVG parsing failed, no valid SVG data retrieved");let code=addMetaData?`//\n // producer: JSCAD SVG Deserializer ${version}\n // date: ${new Date}\n // source: ${filename}\n //\n`:"";return code+="const { colors, geometries, primitives, transforms } = require('@jscad/modeling')\n\n",options&&options.statusCallback&&options.statusCallback({progress:50}),code+=codify(options,svgObj),code+="\nmodule.exports = { main }",options&&options.statusCallback&&options.statusCallback({progress:100}),code};let svgUnitsX,svgUnitsY,svgUnitsV;const svgObjects=[],svgGroups=[],svgDefs=[];let svgObj,svgInDefs=!1,svgUnitsPmm=[1,1];const objectify=(options,group)=>{const{target:target,segments:segments,pathSelfClosed:pathSelfClosed}=options,level=svgGroups.length;svgGroups.push(group);let i=level;for(;i>0;)i--;let geometries=[];const params={svgUnitsPmm:svgUnitsPmm,svgUnitsX:svgUnitsX,svgUnitsY:svgUnitsY,svgUnitsV:svgUnitsV,level:level,target:target,svgGroups:svgGroups,segments:segments,pathSelfClosed:pathSelfClosed};for(i=0;i<group.objects.length;i++){const obj=group.objects[i];let shapes=(array=shapesMapGeometry(obj,objectify,params),Array.isArray(array)?array:null==array?[]:[array]);shapes=shapes.map((shape=>{if("transforms"in obj){let rotateAttribute=null,scaleAttribute=null,translateAttribute=null;for(let j=0;j<obj.transforms.length;j++){const t=obj.transforms[j];"rotate"in t&&(rotateAttribute=t),"scale"in t&&(scaleAttribute=t),"translate"in t&&(translateAttribute=t)}if(null!==scaleAttribute){let x=Math.abs(scaleAttribute.scale[0]),y=Math.abs(scaleAttribute.scale[1]);shape=scale([x,y,1],shape),x=scaleAttribute.scale[0],y=scaleAttribute.scale[1],x<0&&(shape=mirrorX(shape)),y<0&&(shape=mirrorY(shape))}if(null!==rotateAttribute){const z=0-.017453292519943295*rotateAttribute.rotate;shape=rotateZ(z,shape)}if(null!==translateAttribute){const x=cagLengthX(translateAttribute.translate[0],svgUnitsPmm,svgUnitsX),y=0-cagLengthY(translateAttribute.translate[1],svgUnitsPmm,svgUnitsY);shape=translate([x,y,0],shape)}}const color=svgColorForTarget(target,obj);return color&&(shape=colorize(color,shape)),shape})),geometries=geometries.concat(shapes)}var array;return svgGroups.pop(),geometries},codify=(options,group)=>{const{target:target,segments:segments}=options,level=svgGroups.length;svgGroups.push(group);let indent=" ",i=level;for(;i>0;)indent+=" ",i--;let code="";0===level&&(code+="function main(params) {\n let levels = {}\n let paths = {}\n let parts\n");const ln="levels.l"+level;for(code+=`${indent}${ln} = []\n`,i=0;i<group.objects.length;i++){const obj=group.objects[i],on="paths.p"+i;if(code+=shapesMapJscad(obj,codify,{level:level,indent:indent,ln:ln,on:on,svgUnitsPmm:svgUnitsPmm,svgUnitsX:svgUnitsX,svgUnitsY:svgUnitsY,svgUnitsV:svgUnitsV,svgGroups:svgGroups,target:target,segments:segments}),"transforms"in obj){let rotateAttribute=null,scaleAttribute=null,translateAttribute=null;for(let j=0;j<obj.transforms.length;j++){const t=obj.transforms[j];"rotate"in t&&(rotateAttribute=t),"scale"in t&&(scaleAttribute=t),"translate"in t&&(translateAttribute=t)}if(null!==scaleAttribute){let x=Math.abs(scaleAttribute.scale[0]),y=Math.abs(scaleAttribute.scale[1]);code+=`${indent}${on} = transforms.scale([${x}, ${y}, 1], ${on})\n`,x=scaleAttribute.scale[0],y=scaleAttribute.scale[1],x<0&&(code+=`${indent}${on} = transforms.mirrorX(${on})\n`),y<0&&(code+=`${indent}${on} = transforms.mirrorY(${on})\n`)}null!==rotateAttribute&&(code+=`${indent}${on} = transforms.rotateZ(${0-.017453292519943295*rotateAttribute.rotate}, ${on})\n`),null!==translateAttribute&&(code+=`${indent}${on} = transforms.translate([${cagLengthX(translateAttribute.translate[0],svgUnitsPmm,svgUnitsX)}, ${0-cagLengthY(translateAttribute.translate[1],svgUnitsPmm,svgUnitsY)}, 0], ${on})\n`)}const color=svgColorForTarget(target,obj);color&&(code+=`${indent}${on} = colors.colorize([${color}], ${on})\n`),code+=`${indent}${ln} = ${ln}.concat(${on})\n\n`}return 0===level&&(code+=indent+"return "+ln+"\n",code+="}\n"),svgGroups.pop(),code},createSvgParser=(src,pxPmm)=>{const parser=new saxes.SaxesParser;return void 0!==pxPmm&&pxPmm>parser.pxPmm&&(parser.pxPmm=pxPmm),parser.on("error",(e=>{console.log(`ERROR: SVG file, line ${parser.line}, column ${parser.column}`),console.log(e)})),parser.on("opentag",(node=>{const objMap={SVG:svgSvg,G:svgGroup,RECT:svgRect,CIRCLE:svgCircle,ELLIPSE:svgEllipse,LINE:svgLine,POLYLINE:svgPolyline,POLYGON:svgPolygon,PATH:svgPath,USE:svgUse,DEFS:()=>{svgInDefs=!0},DESC:()=>{},TITLE:()=>{},STYLE:()=>{},undefined:()=>console.log("WARNING: unsupported SVG element: "+node.name)};node.attributes.position=[parser.line+1,parser.column+1];const elementName=node.name.toUpperCase(),obj=objMap[elementName]?objMap[elementName](node.attributes,{svgObjects:svgObjects,customPxPmm:pxPmm}):void 0;if(obj)if("id"in obj&&(svgObjects[obj.id]=obj),"svg"===obj.type)svgGroups.push(obj),svgUnitsPmm=obj.unitsPmm,svgUnitsX=obj.viewW,svgUnitsY=obj.viewH,svgUnitsV=obj.viewP;else if(!0===svgInDefs){if(svgDefs.length>0){const group=svgDefs.pop();"objects"in group&&group.objects.push(obj),svgDefs.push(group)}"group"===obj.type&&svgDefs.push(obj)}else{if(svgGroups.length>0){const group=svgGroups.pop();"objects"in group&&group.objects.push(obj),svgGroups.push(group)}"group"===obj.type&&svgGroups.push(obj)}})),parser.on("closetag",(node=>{const popGroup=()=>!0===svgInDefs?svgDefs.pop():svgGroups.pop(),objMap={SVG:popGroup,DEFS:()=>{svgInDefs=!1},USE:popGroup,G:popGroup,undefined:()=>{}},elementName=node.name.toUpperCase(),obj=objMap[elementName]?objMap[elementName]():void 0;0===svgGroups.length&&(svgObj=obj)})),parser.on("end",(()=>{})),parser.write(src).close(),parser};exports.deserialize=(options,input)=>{const defaults={addMetaData:!0,filename:"svg",output:"script",pxPmm:pxPmm,segments:32,target:"path",pathSelfClosed:"error",version:"3.0.0-alpha.0"};return"script"===(options=Object.assign({},defaults,options)).output?translateScript(input,options):instantiate(input,options)},exports.mimeType="image/svg+xml",Object.defineProperty(exports,"__esModule",{value:!0})},"object"==typeof exports&&"undefined"!=typeof module?factory(exports):"function"==typeof define&&define.amd?define(["exports"],factory):factory((global="undefined"!=typeof globalThis?globalThis:global||self).jscadSvgDeserializer={});
38
+ const clone$b=geometry=>Object.assign({},geometry),clone$a=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$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=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)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},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=(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),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],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)},equals$7=(a,b)=>a[0]===b[0]&&a[1]===b[1]&&a[2]===b[2],fromScalar$2=(out,scalar)=>(out[0]=scalar,out[1]=scalar,out[2]=scalar,out),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$2=(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$2=(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),multiply$2=(out,a,b)=>(out[0]=a[0]*b[0],out[1]=a[1]*b[1],out[2]=a[2]*b[2],out),negate$1=(out,vector)=>(out[0]=-vector[0],out[1]=-vector[1],out[2]=-vector[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$b=vec=>`[${vec[0].toFixed(7)}, ${vec[1].toFixed(7)}, ${vec[2].toFixed(7)}]`,transform$c=(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};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:()=>[0,0,0],cross:cross$1,distance:distance$1,divide:(out,a,b)=>(out[0]=a[0]/b[0],out[1]=a[1]/b[1],out[2]=a[2]/b[2],out),dot:dot$2,equals:equals$7,fromScalar:fromScalar$2,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$2,min:min$2,multiply:multiply$2,negate:negate$1,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$b,transform:transform$c});const 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};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:clone$a,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:fromScaling,fromTaitBryanRotation:fromTaitBryanRotation,fromTranslation:fromTranslation,fromValues:(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},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},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:(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},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)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$a=(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),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$6=(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$1=(out,a,b)=>(out[0]=Math.max(a[0],b[0]),out[1]=Math.max(a[1],b[1]),out),min$1=(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$9=vector=>`[${vector[0].toFixed(7)}, ${vector[1].toFixed(7)}]`,transform$b=(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};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:()=>[0,0],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$6,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$1,min:min$1,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$9,transform:transform$b});const 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$5=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$b([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$5=geometry=>{const outlines=toOutlines(geometry).map((outline=>outline.slice().reverse())),reversed=create$a(outlines);return geometry.color&&(reversed.color=geometry.color),reversed},transform$a=(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$5(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 index$a=Object.freeze({__proto__:null,clone:clone$b,create:create$a,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$a(outlines)},fromCompactBinary:data=>{if(0!==data[0])throw new Error("invalid compact binary data");const created=create$a();created.transforms=clone$a(data.slice(1,17));for(let i=21;i<data.length;){const length=data[i++];if(length<0||i+2*length>data.length)throw new Error("invalid compact binary data");const outline=[];for(let j=0;j<length;j++){const x=data[i+2*j],y=data[i+2*j+1];outline.push(fromValues$2(x,y))}created.outlines.push(outline),i+=2*length}return data[17]>=0&&(created.color=[data[17],data[18],data[19],data[20]]),created},isA:isA$5,reverse:reverse$5,toOutlines:toOutlines,toPoints: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},toString:geometry=>{const outlines=toOutlines(geometry);let result="geom2 ("+outlines.length+" outlines):\n[\n";return outlines.forEach((outline=>{result+=" ["+outline.map(toString$9).join()+"]\n"})),result+="]\n",result},toCompactBinary:geometry=>{const transforms=geometry.transforms;let color=[-1,-1,-1,-1];geometry.color&&(color=geometry.color);let size=21;geometry.outlines.forEach((outline=>{size+=2*outline.length+1}));const compacted=new Float32Array(size);compacted[0]=0,compacted[1]=transforms[0],compacted[2]=transforms[1],compacted[3]=transforms[2],compacted[4]=transforms[3],compacted[5]=transforms[4],compacted[6]=transforms[5],compacted[7]=transforms[6],compacted[8]=transforms[7],compacted[9]=transforms[8],compacted[10]=transforms[9],compacted[11]=transforms[10],compacted[12]=transforms[11],compacted[13]=transforms[12],compacted[14]=transforms[13],compacted[15]=transforms[14],compacted[16]=transforms[15],compacted[17]=color[0],compacted[18]=color[1],compacted[19]=color[2],compacted[20]=color[3];let index=21;return geometry.outlines.forEach((outline=>{compacted[index++]=outline.length,outline.forEach((point=>{compacted[index++]=point[0],compacted[index++]=point[1]}))})),compacted},transform:transform$a,validate:object=>{if(!isA$5(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$6(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 clone$7=geometry=>Object.assign({},geometry),create$8=polygons=>(void 0===polygons&&(polygons=[]),{polygons:polygons,transforms:[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]}),create$7=vertices=>((void 0===vertices||vertices.length<3)&&(vertices=[]),{vertices:vertices}),clone$6=(...params)=>{let out,poly3;return 1===params.length?(out=create$7(),poly3=params[0]):(out=params[0],poly3=params[1]),out.vertices=poly3.vertices.map((vec=>clone$9(vec))),out},fromVerticesAndPlane=(vertices,plane)=>{const poly=create$7(vertices);return poly.plane=plane,poly},create$6=()=>[0,0,0,0],clone$5=vector=>{const out=[0,0,0,0];return out[0]=vector[0],out[1]=vector[1],out[2]=vector[2],out[3]=vector[3],out},copy$2=(out,vector)=>(out[0]=vector[0],out[1]=vector[1],out[2]=vector[2],out[3]=vector[3],out),equals$5=(a,b)=>a[0]===b[0]&&a[1]===b[1]&&a[2]===b[2]&&a[3]===b[3],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},fromValues$1=(x,y,z,w)=>{const out=[0,0,0,0];return out[0]=x,out[1]=y,out[2]=z,out[3]=w,out},fromPoints$4=(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},signedDistanceToPoint=(plane,point)=>dot$2(plane,point)-plane[3],toString$7=vec=>`(${vec[0].toFixed(9)}, ${vec[1].toFixed(9)}, ${vec[2].toFixed(9)}, ${vec[3].toFixed(9)})`;Object.freeze({__proto__:null,clone:clone$5,copy:copy$2,create:create$6,equals:equals$5,flip:flip,fromNormalAndPoint:fromNormalAndPoint,fromValues:fromValues$1,fromPoints:fromPoints$4,fromPointsRandom:(out,a,b,c)=>{let ba=subtract$3([0,0,0],b,a),ca=subtract$3([0,0,0],c,a);length$2(ba)<EPS&&(ba=orthogonal(ba,ca)),length$2(ca)<EPS&&(ca=orthogonal(ca,ba));let normal=cross$1([0,0,0],ba,ca);length$2(normal)<EPS&&(ca=orthogonal(ca,ba),normal=cross$1(normal,ba,ca)),normal=normalize$1(normal,normal);const w=dot$2(normal,a);return out[0]=normal[0],out[1]=normal[1],out[2]=normal[2],out[3]=w,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)},signedDistanceToPoint:signedDistanceToPoint,toString:toString$7,transform:(out,plane,matrix)=>{const isMirror=isMirroring(matrix),r=orthogonal([0,0,0],plane),u=cross$1(r,plane,r),v=cross$1([0,0,0],plane,u);let point1=fromScalar$2([0,0,0],plane[3]);multiply$2(point1,point1,plane);let point2=add$1([0,0,0],point1,u),point3=add$1([0,0,0],point1,v);return point1=transform$c(point1,point1,matrix),point2=transform$c(point2,point2,matrix),point3=transform$c(point3,point3,matrix),fromPoints$4(out,point1,point2,point3),isMirror&&flip(out,out),out}});const invert$1=polygon=>{const vertices=polygon.vertices.slice().reverse(),inverted=create$7(vertices);return polygon.plane&&(inverted.plane=flip([0,0,0,0],polygon.plane)),inverted},isA$4=object=>!!(object&&"object"==typeof object&&"vertices"in object&&Array.isArray(object.vertices)),isConvex$1=polygon=>areVerticesConvex(polygon.vertices),areVerticesConvex=vertices=>{const numVertices=vertices.length;if(numVertices>2){const normal=fromPoints$4([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$4([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};Object.freeze({__proto__:null,clone:clone$5,copy:copy$2,create:create$6,dot:(a,b)=>a[0]*b[0]+a[1]*b[1]+a[2]*b[2]+a[3]*b[3],equals:equals$5,fromScalar:(out,scalar)=>(out[0]=scalar,out[1]=scalar,out[2]=scalar,out[3]=scalar,out),fromValues:fromValues$1,toString:toString$7,transform:(out,vector,matrix)=>{const[x,y,z,w]=vector;return 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[3]=matrix[3]*x+matrix[7]*y+matrix[11]*z+matrix[15]*w,out}});const cache$4=new WeakMap,toVertices$1=polygon=>polygon.vertices,toString$6=polygon=>`poly3: [${polygon.vertices.map(toString$b).join(", ")}]`,transform$7=(matrix,polygon)=>{const vertices=polygon.vertices.map((vertex=>transform$c([0,0,0],vertex,matrix)));return isMirroring(matrix)&&vertices.reverse(),create$7(vertices)},validate$4=object=>{if(!isA$4(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$7(object.vertices[i],object.vertices[(i+1)%object.vertices.length]))throw new Error(`poly3 has duplicate vertex ${object.vertices[i]}`);if(!isConvex$1(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(signedDistanceToPoint(normal,vertex));if(dist>1e-13)throw new Error(`poly3 must be coplanar: vertex ${vertex} distance ${dist}`)}))}};Object.freeze({__proto__:null,clone:clone$6,create:create$7,fromVerticesAndPlane:fromVerticesAndPlane,invert:invert$1,isA:isA$4,isConvex:isConvex$1,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$2(min,min,vertices[i]),max$2(max,max,vertices[i]);return[min,max]},measureBoundingSphere:polygon=>{const boundingSphere=cache$4.get(polygon);if(boundingSphere)return boundingSphere;const vertices=polygon.vertices,out=[0,0,0,0];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;vertices.forEach((v=>{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),cache$4.set(polygon,out),out},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,toVertices:toVertices$1,toString:toString$6,transform:transform$7,validate:validate$4});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=(point=vertex.point,a=v0.point,b=v1.point,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)));distance>maxDistance&&(maxDistance=distance,v2=vertex)}}var point,a,b;const normal=fromPoints$4([],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$7(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$3=object=>!!(object&&"object"==typeof object&&"polygons"in object&&"transforms"in object&&Array.isArray(object.polygons)&&"length"in object.transforms),transform$6=(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})};Object.freeze({__proto__:null,clone:clone$7,create:create$8,fromPoints:listOfLists=>{if(!Array.isArray(listOfLists))throw new Error("the given vertices must be an array");return create$8(listOfLists.map(create$7))},fromPointsConvex:uniquePoints=>{if(!Array.isArray(uniquePoints))throw new Error("the given points must be an array");const polygons=((points,options={})=>{const instance=new QuickHull(points);return instance.build(),instance.collectFaces(options.skipTriangulation)})(uniquePoints,{skipTriangulation:!0}).map((face=>{const vertices=face.map((index=>uniquePoints[index]));return create$7(vertices)}));return create$8(polygons)},fromCompactBinary:data=>{if(1!==data[0])throw new Error("invalid compact binary data");const created=create$8();created.transforms=clone$a(data.slice(1,17));const numberOfVertices=data[21];let ci=22,vi=data.length-3*numberOfVertices;for(;vi<data.length;){const verticesPerPolygon=data[ci];ci++;const vertices=[];for(let i=0;i<verticesPerPolygon;i++)vertices.push(fromValues$3(data[vi],data[vi+1],data[vi+2])),vi+=3;created.polygons.push(create$7(vertices))}return data[17]>=0&&(created.color=[data[17],data[18],data[19],data[20]]),created},invert:geometry=>{const newPolygons=toPolygons$1(geometry).map((polygon=>invert$1(polygon)));return create$8(newPolygons)},isA:isA$3,toPoints:geometry=>toPolygons$1(geometry).map((polygon=>toVertices$1(polygon))),toPolygons:toPolygons$1,toString:geometry=>{const polygons=toPolygons$1(geometry);let result="geom3 ("+polygons.length+" polygons):\n";return polygons.forEach((polygon=>{result+=" "+toString$6(polygon)+"\n"})),result},toCompactBinary:geometry=>{const polygons=geometry.polygons,transforms=geometry.transforms,numberOfPolygons=polygons.length,numberOfVertices=polygons.reduce(((count,polygon)=>count+polygon.vertices.length),0);let color=[-1,-1,-1,-1];geometry.color&&(color=geometry.color);const compacted=new Float32Array(22+numberOfPolygons+3*numberOfVertices);compacted[0]=1,compacted[1]=transforms[0],compacted[2]=transforms[1],compacted[3]=transforms[2],compacted[4]=transforms[3],compacted[5]=transforms[4],compacted[6]=transforms[5],compacted[7]=transforms[6],compacted[8]=transforms[7],compacted[9]=transforms[8],compacted[10]=transforms[9],compacted[11]=transforms[10],compacted[12]=transforms[11],compacted[13]=transforms[12],compacted[14]=transforms[13],compacted[15]=transforms[14],compacted[16]=transforms[15],compacted[17]=color[0],compacted[18]=color[1],compacted[19]=color[2],compacted[20]=color[3],compacted[21]=numberOfVertices;let ci=22,vi=ci+numberOfPolygons;return polygons.forEach((polygon=>{const vertices=toVertices$1(polygon);compacted[ci]=vertices.length,ci++;for(let i=0;i<vertices.length;i++){const vertex=vertices[i];compacted[vi+0]=vertex[0],compacted[vi+1]=vertex[1],compacted[vi+2]=vertex[2],vi+=3}})),compacted},transform:transform$6,validate:object=>{if(!isA$3(object))throw new Error("invalid geom3 structure");if(object.polygons.forEach(validate$4),(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=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*EPS&&(points.pop(),1!==points.length);)pn=points[points.length-1]}return cloned},create$5=points=>(void 0===points&&(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$5();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*EPS&&(closed=!0)}return!0===closed&&(created=close(created)),created},toPoints$1=geometry=>(geometry=>(isIdentity(geometry.transforms)||(geometry.points=geometry.points.map((point=>transform$b([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=(...paths)=>{let isClosed=!1,newPoints=[];return paths.forEach(((path,i)=>{const tmp=toPoints$1(path).slice();if(newPoints.length>0&&tmp.length>0&&equals$6(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$1=(points,geometry)=>concat(geometry,create$5(points)),isA$2=object=>!!(object&&"object"==typeof object&&"points"in object&&"transforms"in object&&"isClosed"in object&&Array.isArray(object.points)&&"length"in object.transforms),transform$5=(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 index$5=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.ceil(Math.abs(deltatheta)/TAU*segments)+1;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$1(newPoints,geometry);return result.lastBezierControlPoint=controlPoints[controlPoints.length-2],result},appendPoints:appendPoints$1,clone:clone$4,close:close,concat:concat,create:create$5,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$6(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,fromCompactBinary:data=>{if(2!==data[0])throw new Error("invalid compact binary data");const created=create$5();created.transforms=clone$a(data.slice(1,17)),created.isClosed=!!data[17];for(let i=22;i<data.length;i+=2){const point=fromValues$2(data[i],data[i+1]);created.points.push(point)}return data[18]>=0&&(created.color=[data[18],data[19],data[20],data[21]]),created},isA:isA$2,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$9(point)+",\n"})),result+="]\n",result},toCompactBinary:geometry=>{const points=geometry.points,transforms=geometry.transforms;let color=[-1,-1,-1,-1];geometry.color&&(color=geometry.color);const compacted=new Float32Array(22+2*points.length);compacted[0]=2,compacted[1]=transforms[0],compacted[2]=transforms[1],compacted[3]=transforms[2],compacted[4]=transforms[3],compacted[5]=transforms[4],compacted[6]=transforms[5],compacted[7]=transforms[6],compacted[8]=transforms[7],compacted[9]=transforms[8],compacted[10]=transforms[9],compacted[11]=transforms[10],compacted[12]=transforms[11],compacted[13]=transforms[12],compacted[14]=transforms[13],compacted[15]=transforms[14],compacted[16]=transforms[15],compacted[17]=geometry.isClosed?1:0,compacted[18]=color[0],compacted[19]=color[1],compacted[20]=color[2],compacted[21]=color[3];for(let j=0;j<points.length;j++){const ci=2*j+22,point=points[j];compacted[ci]=point[0],compacted[ci+1]=point[1]}return compacted},transform:transform$5,validate:object=>{if(!isA$2(object))throw new Error("invalid path2 structure");if(object.points.length>1)for(let i=0;i<object.points.length;i++)if(equals$6(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 colorize=(color,...objects)=>{if(!Array.isArray(color))throw new Error("color must be an array");if(color.length<3)throw new Error("color must contain R, G and B values");3===color.length&&(color=[color[0],color[1],color[2],1]);const results=objects.map((object=>isA$5(object)?((color,object)=>{const newGeom2=clone$b(object);return newGeom2.color=color,newGeom2})(color,object):isA$3(object)?((color,object)=>{const newGeom3=clone$7(object);return newGeom3.color=color,newGeom3})(color,object):isA$2(object)?((color,object)=>{const newPath2=clone$4(object);return newPath2.color=color,newPath2})(color,object):isA$4(object)?((color,object)=>{const newPoly=clone$6(object);return newPoly.color=color,newPoly})(color,object):Array.isArray(object)?colorize(color,...object):(object.color=color,object)));return 1===results.length?results[0]:results},getPermutations=function(c){const permutations=[];for(let i=0;i<=c;i++)permutations.push(factorial(c)/(factorial(i)*factorial(c-i)));return permutations},factorial=function(b){let out=1;for(let i=2;i<=b;i++)out*=i;return out},valueAt=(t,bezier)=>{if(t<0||t>1)throw new Error("Bezier valueAt() input must be between 0 and 1");if("float_single"===bezier.pointType)return bezierFunction(bezier,bezier.points,t);{const result=[];for(let i=0;i<bezier.dimensions;i++){const singleDimensionPoints=[];for(let j=0;j<bezier.points.length;j++)singleDimensionPoints.push(bezier.points[j][i]);result.push(bezierFunction(bezier,singleDimensionPoints,t))}return result}},bezierFunction=function(bezier,p,t){const n=p.length-1;let result=0;for(let i=0;i<=n;i++)result+=bezier.permutations[i]*Math.pow(1-t,n-i)*Math.pow(t,i)*p[i];return result},bezierTangent=function(bezier,p,t){const n=p.length-1;let result=0;for(let i=0;i<n;i++){const q=n*(p[i+1]-p[i]);result+=bezier.tangentPermutations[i]*Math.pow(1-t,n-1-i)*Math.pow(t,i)*q}return result},lengths=(segments,bezier)=>{let sum=0;const lengths=[0];let previous=valueAt(0,bezier);for(let index=1;index<=segments;index++){const current=valueAt(index/segments,bezier);sum+=distanceBetween(current,previous),lengths.push(sum),previous=current}return lengths},distanceBetween=(a,b)=>{if(Number.isFinite(a)&&Number.isFinite(b))return Math.abs(a-b);if(Array.isArray(a)&&Array.isArray(b)){if(a.length!==b.length)throw new Error("The operands must have the same number of dimensions.");let sum=0;for(let i=0;i<a.length;i++)sum+=(b[i]-a[i])*(b[i]-a[i]);return Math.sqrt(sum)}throw new Error("The operands must be of the same type, either number or array.")};Object.freeze({__proto__:null,create:points=>{if(!Array.isArray(points))throw new Error("Bezier points must be a valid array/");if(points.length<2)throw new Error("Bezier points must contain at least 2 values.");const pointType=function(points){let firstPointType=null;return points.forEach((point=>{let pType="";if(Number.isFinite(point))pType="float_single";else{if(!Array.isArray(point))throw new Error("Bezier points must all be numbers or arrays of number.");point.forEach((val=>{if(!Number.isFinite(val))throw new Error("Bezier point values must all be numbers.")})),pType="float_"+point.length}if(null==firstPointType)firstPointType=pType;else if(firstPointType!==pType)throw new Error("Bezier points must be either all numbers or all arrays of numbers of the same size.")})),firstPointType}(points);return{points:points,pointType:pointType,dimensions:"float_single"===pointType?0:points[0].length,permutations:getPermutations(points.length-1),tangentPermutations:getPermutations(points.length-2)}},valueAt:valueAt,tangentAt:(t,bezier)=>{if(t<0||t>1)throw new Error("Bezier tangentAt() input must be between 0 and 1");if("float_single"===bezier.pointType)return bezierTangent(bezier,bezier.points,t);{const result=[];for(let i=0;i<bezier.dimensions;i++){const singleDimensionPoints=[];for(let j=0;j<bezier.points.length;j++)singleDimensionPoints.push(bezier.points[j][i]);result.push(bezierTangent(bezier,singleDimensionPoints,t))}return result}},lengths:lengths,length:(segments,bezier)=>lengths(segments,bezier)[segments],arcLengthToT:(options,bezier)=>{const{distance:distance,segments:segments}=Object.assign({},{distance:0,segments:100},options),arcLengths=lengths(segments,bezier);let startIndex=0,endIndex=segments;for(;startIndex<=endIndex;){const middleIndex=Math.floor(startIndex+(endIndex-startIndex)/2),diff=arcLengths[middleIndex]-distance;if(diff<0)startIndex=middleIndex+1;else{if(!(diff>0)){endIndex=middleIndex;break}endIndex=middleIndex-1}}const targetIndex=endIndex;if(arcLengths[targetIndex]===distance)return targetIndex/segments;const lengthBefore=arcLengths[targetIndex];return(targetIndex+(distance-lengthBefore)/(arcLengths[targetIndex+1]-lengthBefore))/segments}});const 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},measureArea$1=polygon=>area$1(polygon.points),create$3=points=>((void 0===points||points.length<3)&&(points=[]),{points:points}),reverse$3=polygon=>{const points=polygon.points.slice().reverse();return create$3(points)},arePointsInside=(points,polygon)=>0===points.length||polygon.points.length<3?0:(measureArea$1(polygon)<0&&(polygon=reverse$3(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},isA$1=object=>!!(object&&"object"==typeof object&&"points"in object&&Array.isArray(object.points)),crossBetweenSegments=(p1,p2,p3)=>{const X1=p2[0]-p1[0],Y1=p2[1]-p1[1],X2=p3[0]-p1[0];return X1*(p3[1]-p1[1])-Y1*X2};Object.freeze({__proto__:null,arePointsInside:arePointsInside,clone:polygon=>Object.assign({},polygon),create:create$3,isA:isA$1,isConvex:polygon=>{const numPoints=polygon.points.length;if(numPoints>2){const points=polygon.points;let prev=0,curr=0;for(let i=0;i<numPoints;i++)if(curr=crossBetweenSegments(points[i],points[(i+1)%numPoints],points[(i+2)%numPoints]),0!==curr){if(curr*prev<0)return!1;prev=curr}}return!0},isSimple:polygon=>{const numPoints=polygon.points.length;if(numPoints<3)return!1;if(3===numPoints)return!0;const points=polygon.points,found=new Set;if(points.forEach((v=>found.add(v.toString()))),found.size!==numPoints)return!1;for(let i=0;i<numPoints;i++)for(let j=i+2;j<numPoints;j++){const k=(j+1)%numPoints;if(i!==k){const s0=points[i],s1=points[(i+1)%numPoints],z0=points[j],z1=points[k];if(intersect$1(s0,s1,z0,z1))return!1}}return!0},measureArea:measureArea$1,measureBoundingBox:polygon=>{const points=polygon.points,numPoints=points.length,min=0===numPoints?[0,0]:clone$8(points[0]),max=clone$8(min);for(let i=1;i<numPoints;i++)min$1(min,min,points[i]),max$1(max,max,points[i]);return[min,max]},reverse:reverse$3,toPoints:polygon=>polygon.points,toString:polygon=>`poly2: [${polygon.points.map(toString$9).join(", ")}]`,transform:(matrix,polygon)=>{const points=polygon.points.map((point=>transform$b([0,0],point,matrix)));return isMirroring(matrix)&&points.reverse(),create$3(points)},validate:object=>{if(!isA$1(object))throw new Error("invalid poly2 structure");if(object.points.length<3)throw new Error(`poly2 not enough points ${object.points.length}`);if(measureArea$1(object)<=0)throw new Error("poly2 area must be greater than zero");for(let i=0;i<object.points.length;i++)if(equals$6(object.points[i],object.points[(i+1)%object.points.length]))throw new Error(`poly2 duplicate point at ${i}: [${object.points[i]}]`);object.points.forEach((point=>{if(2!==point.length)throw new Error(`poly2 invalid point ${point}`);if(!point.every(Number.isFinite))throw new Error(`poly2 invalid point ${point}`)}))}});const calculatePlane=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$7(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$7(prev,vertex)&&equals$7(prev,farthestVertex)){farthestAfter=vertex;break}prev=vertex}return fromPoints$4([0,0,0,0],farthestBefore,farthestVertex,farthestAfter)},create$2=(contours=[])=>({contours:contours}),isA=object=>!!(object&&"object"==typeof object&&"contours"in object&&Array.isArray(object.contours));class Node$2{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&&sectorContainsSector(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=calculatePlane(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$a(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)}}}Object.freeze({__proto__:null,calculatePlane:calculatePlane,clone:slice=>Object.assign({},slice),create:create$2,equals:(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$7(aVertex,bVertex))return!1}}return!0},fromGeom2:geometry=>{const contours=toOutlines(geometry).map((outline=>outline.map((point=>fromVec2([0,0,0],point)))));return create$2(contours)},fromVertices: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])},isA:isA,reverse: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},toVertices:slice=>{const vertices=[];return slice.contours.forEach((contour=>{contour.forEach((vertex=>{vertices.push(vertex)}))})),vertices},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},toString:slice=>{let result="slice ("+slice.contours.length+" contours):\n[\n";return slice.contours.forEach((contour=>{result+=" ["+contour.map(toString$b).join()+"],\n"})),result+="]\n",result},transform:(matrix,slice)=>{const contours=slice.contours.map((contour=>contour.map((vertex=>transform$c([0,0,0],vertex,matrix)))));return create$2(contours)},validate:object=>{if(!isA(object))throw new Error("invalid slice structure");const slicePlane=calculatePlane(object);object.contours.forEach(((contour,i)=>{if(contour.length<3)throw new Error(`slice contour ${i} must contain at least 3 vertices`);const contourPlane=plane(create$7(contour));if(!equals$5(slicePlane,contourPlane))throw new Error("slice contours must be coplanar");for(let i=0;i<contour.length;i++){if(!contour[i].every(Number.isFinite))throw new Error(`slice contour ${i} must contain finite vertices`);const j=(i+1)%contour.length;if(equals$7(contour[i],contour[j]))throw new Error(`slice contour ${i} has duplicate vertex ${contour[i]}`)}}))}});const direction$1=line=>{const vector=normal([0,0],line);return negate(vector,vector),vector},origin$1=line=>scale$1([0,0],line,line[2]),copy$1=(out,line)=>(out[0]=line[0],out[1]=line[1],out[2]=line[2],out),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},fromValues=(x,y,d)=>{const out=[0,1,0];return out[0]=x,out[1]=y,out[2]=d,out},solve2Linear=(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]};Object.freeze({__proto__:null,clone:line=>{const out=[0,1,0];return out[0]=line[0],out[1]=line[1],out[2]=line[2],out},closestPoint:(line,point)=>{const orig=origin$1(line),dir=direction$1(line),v=subtract$1([0,0],point,orig),dist=dot$1(v,dir);return scale$1(v,dir,dist),add(v,v,orig),v},copy:copy$1,create:()=>[0,1,0],direction:direction$1,distanceToPoint:(line,point)=>{let distance=dot$1(point,line);return distance=Math.abs(distance-line[2]),distance},equals:(line1,line2)=>line1[0]===line2[0]&&line1[1]===line2[1]&&line1[2]===line2[2],fromPoints:fromPoints$1,fromValues:fromValues,intersectPointOfLines:(line1,line2)=>{const point=solve2Linear(line1[0],line1[1],line2[0],line2[1],line1[2],line2[2]);return clone$8(point)},origin:origin$1,reverse:(out,line)=>{const normal=negate([0,0],line),distance=-line[2];return copy$1(out,fromValues(normal[0],normal[1],distance))},toString:line=>`line2: (${line[0].toFixed(7)}, ${line[1].toFixed(7)}, ${line[2].toFixed(7)})`,transform:(out,line,matrix)=>{const org=origin$1(line),dir=direction$1(line);return transform$b(org,org,matrix),transform$b(dir,dir,matrix),fromPoints$1(out,org,dir)},xAtY:(line,y)=>{let x=(line[2]-line[1]*y)/line[0];return Number.isNaN(x)&&(x=origin$1(line)[0]),x}});const create=()=>[fromValues$3(0,0,0),fromValues$3(0,0,1)],closestPoint=(line,point)=>{const lPoint=line[0],lDirection=line[1],a=dot$2(subtract$3([0,0,0],point,lPoint),lDirection),b=dot$2(lDirection,lDirection),closestPoint=scale$3([0,0,0],lDirection,a/b);return add$1(closestPoint,closestPoint,lPoint),closestPoint},fromPointAndDirection=(out,point,direction)=>{const unit=normalize$1([0,0,0],direction);return copy$4(out[0],point),copy$4(out[1],unit),out};Object.freeze({__proto__:null,clone:line=>{const out=create();return copy$4(out[0],line[0]),copy$4(out[1],line[1]),out},closestPoint:closestPoint,copy:(out,line)=>(copy$4(out[0],line[0]),copy$4(out[1],line[1]),out),create:create,direction:line=>line[1],distanceToPoint:(line,point)=>{const closest=closestPoint(line,point),distanceVector=subtract$3([0,0,0],point,closest);return length$2(distanceVector)},equals:(line1,line2)=>!!equals$7(line1[1],line2[1])&&!!equals$7(line1[0],line2[0]),fromPlanes:(out,plane1,plane2)=>{let direction=cross$1([0,0,0],plane1,plane2),length=length$2(direction);if(length<EPS)throw new Error("parallel planes do not intersect");length=1/length,direction=scale$3(direction,direction,length);const absX=Math.abs(direction[0]),absY=Math.abs(direction[1]),absZ=Math.abs(direction[2]);let origin,r;return absX>=absY&&absX>=absZ?(r=solve2Linear(plane1[1],plane1[2],plane2[1],plane2[2],plane1[3],plane2[3]),origin=fromValues$3(0,r[0],r[1])):absY>=absX&&absY>=absZ?(r=solve2Linear(plane1[0],plane1[2],plane2[0],plane2[2],plane1[3],plane2[3]),origin=fromValues$3(r[0],0,r[1])):(r=solve2Linear(plane1[0],plane1[1],plane2[0],plane2[1],plane1[3],plane2[3]),origin=fromValues$3(r[0],r[1],0)),fromPointAndDirection(out,origin,direction)},fromPointAndDirection:fromPointAndDirection,fromPoints:(out,point1,point2)=>{const direction=subtract$3([0,0,0],point2,point1);return fromPointAndDirection(out,point1,direction)},intersectPointOfLineAndPlane:(line,plane)=>{const pNormal=plane,pw=plane[3],lPoint=line[0],lDirection=line[1],labda=(pw-dot$2(pNormal,lPoint))/dot$2(pNormal,lDirection);return add$1([0,0,0],lPoint,scale$3([0,0,0],lDirection,labda))},origin:line=>line[0],reverse:(out,line)=>{const point=clone$9(line[0]),direction=negate$1([0,0,0],line[1]);return fromPointAndDirection(out,point,direction)},toString:line=>{const point=line[0],direction=line[1];return`line3: point: (${point[0].toFixed(7)}, ${point[1].toFixed(7)}, ${point[2].toFixed(7)}) direction: (${direction[0].toFixed(7)}, ${direction[1].toFixed(7)}, ${direction[2].toFixed(7)})`},transform:(out,line,matrix)=>{const point=line[0],direction=line[1],pointPlusDirection=add$1([0,0,0],point,direction),newPoint=transform$c([0,0,0],point,matrix),newPointPlusDirection=transform$c(pointPlusDirection,pointPlusDirection,matrix),newDirection=subtract$3(newPointPlusDirection,newPointPlusDirection,newPoint);return fromPointAndDirection(out,newPoint,newDirection)}});const isNumberArray=(array,dimension)=>!!(Array.isArray(array)&&array.length>=dimension)&&array.every((n=>Number.isFinite(n))),isGTE=(value,constant)=>Number.isFinite(value)&&value>=constant,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$a();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*EPS)/(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$a([points])},line=points=>{if(!Array.isArray(points))throw new Error("points must be an array");return fromPoints$2({},points)},rectangle=options=>{const{center:center,size:size}=Object.assign({},{center:[0,0],size:[2,2]},options);if(!isNumberArray(center,2))throw new Error("center must be an array of X and Y values");if(!isNumberArray(size,2))throw new Error("size must be an array of X and Y values");if(!size.every((n=>n>=0)))throw new Error("size values must be positive");if(0===size[0]||0===size[1])return create$a();const point=[size[0]/2,size[1]/2],swapped=[point[0],-point[1]],points=[subtract$1([0,0],center,point),add([0,0],center,swapped),add([0,0],center,point),subtract$1([0,0],center,swapped)];return create$a([points])},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$2(object)?transform$5(matrix,object):isA$5(object)?transform$a(matrix,object):isA$3(object)?transform$6(matrix,object):Array.isArray(object)?mirror(options,...object):object));return 1===results.length?results[0]:results},mirrorX=(...objects)=>mirror({normal:[1,0,0]},...objects),mirrorY=(...objects)=>mirror({normal:[0,1,0]},...objects),rotate=(angles,...objects)=>{if(!Array.isArray(angles))throw new Error("angles must be an array");for(angles=angles.slice();angles.length<3;)angles.push(0);const yaw=angles[2],pitch=angles[1],roll=angles[0],matrix=fromTaitBryanRotation([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],yaw,pitch,roll),results=objects.map((object=>isA$2(object)?transform$5(matrix,object):isA$5(object)?transform$a(matrix,object):isA$3(object)?transform$6(matrix,object):Array.isArray(object)?rotate(angles,...object):object));return 1===results.length?results[0]:results},rotateZ=(angle,...objects)=>rotate([0,0,angle],...objects),translate=(offset,...objects)=>{if(!Array.isArray(offset))throw new Error("offset must be an array");for(offset=offset.slice();offset.length<3;)offset.push(0);const matrix=fromTranslation([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],offset),results=objects.map((object=>isA$2(object)?transform$5(matrix,object):isA$5(object)?transform$a(matrix,object):isA$3(object)?transform$6(matrix,object):Array.isArray(object)?translate(offset,...object):object));return 1===results.length?results[0]:results},scale=(factors,...objects)=>{if(!Array.isArray(factors))throw new Error("factors must be an array");for(factors=factors.slice();factors.length<3;)factors.push(1);if(factors[0]<=0||factors[1]<=0||factors[2]<=0)throw new Error("factors must be positive");const matrix=fromScaling([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],factors),results=objects.map((object=>isA$2(object)?transform$5(matrix,object):isA$5(object)?transform$a(matrix,object):isA$3(object)?transform$6(matrix,object):Array.isArray(object)?scale(factors,...object):object));return 1===results.length?results[0]:results},pxPmm=1/.2822222,svgColors={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],grey:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]},svg2cag=(vec,svgUnitsPmm)=>[vec[0]/svgUnitsPmm[0],0-vec[1]/svgUnitsPmm[1]],cagLengthX=(css,svgUnitsPmm,svgUnitsX)=>{if(css.indexOf("%")<0)return css2cag(css,svgUnitsPmm[0]);let v=parseFloat(css);return isNaN(v)?0:0===v?v:(v=v/100*svgUnitsX,v/=svgUnitsPmm[0],Math.round(1e5*v)/1e5)},cagLengthY=(css,svgUnitsPmm,svgUnitsY)=>{if(css.indexOf("%")<0)return css2cag(css,svgUnitsPmm[1]);let v=parseFloat(css);return isNaN(v)?0:0===v?v:(v=v/100*svgUnitsY,v/=svgUnitsPmm[1],Math.round(1e5*v)/1e5)},cagLengthP=(css,svgUnitsPmm,svgUnitsV)=>{if(css.indexOf("%")<0)return css2cag(css,svgUnitsPmm[1]);let v=parseFloat(css);return isNaN(v)?0:(0===v||(v=v/100*svgUnitsV,v/=svgUnitsPmm[0]),v)},css2cag=(css,unit)=>{let v=parseFloat(css);return isNaN(v)?0:(0===v||css.search(/EM/i)>0||css.search(/EX/i)>0||css.search(/MM/i)>0||(css.search(/CM/i)>0?v*=10:css.search(/IN/i)>0?v/=.03937:css.search(/PT/i)>0?v/=2.8346400000000003:css.search(/PC/i)>0?v/=.23622:v/=unit),v)},cagColor=value=>{let rgb;if((value=value.toLowerCase())in svgColors)rgb=svgColors[value],rgb=[rgb[0]/255,rgb[1]/255,rgb[2]/255];else if("#"===value[0])4===value.length&&(value="#"+value[1]+value[1]+value[2]+value[2]+value[3]+value[3]),7===value.length&&(rgb=[parseInt("0x"+value.slice(1,3))/255,parseInt("0x"+value.slice(3,5))/255,parseInt("0x"+value.slice(5,7))/255]);else{let s=/rgb\(.+,.+,.+\)/.exec(value);null!==s&&(s=s[0],s=s.slice(s.indexOf("(")+1,s.indexOf(")")),rgb=s.split(","),s.indexOf("%")>0?(rgb=[parseInt(rgb[0]),parseInt(rgb[1]),parseInt(rgb[2])],rgb=[rgb[0]/100,rgb[1]/100,rgb[2]/100]):(rgb=[parseInt(rgb[0]),parseInt(rgb[1]),parseInt(rgb[2])],rgb=[rgb[0]/255,rgb[1]/255,rgb[2]/255]))}return rgb},cssStyle=(element,name)=>{if("style"in element){const list=element.style+";";let v=new RegExp(name+"\\s*:\\s*(\\S+);","i").exec(list);if(null!==v){v=v[0];let i=v.indexOf(":")+1;for(;" "===v[i];)i++;return v=v.slice(i,v.indexOf(";")),v}}},reflect=(x,y,px,py)=>{const ox=x-px,oy=y-py;return x===px&&y===px?[x,y]:x===px?[x,py+-oy]:y===py?[px+-ox,y]:[px+-ox,py+-oy]},svgColorForTarget=(target,svgObject)=>{let color=null;return"path"===target?svgObject.stroke?color=[svgObject.stroke[0],svgObject.stroke[1],svgObject.stroke[2],1]:svgObject.fill&&(color=[svgObject.fill[0],svgObject.fill[1],svgObject.fill[2],1]):svgObject.fill?color=[svgObject.fill[0],svgObject.fill[1],svgObject.fill[2],1]:svgObject.stroke&&(color=[svgObject.stroke[0],svgObject.stroke[1],svgObject.stroke[2],1]),color},svgCore=(obj,element)=>{"id"in element&&(obj.id=element.id),"position"in element&&(obj.position=element.position)},svgPresentation=(obj,element)=>{if("display"in element&&(obj.visible=element.display),"color"in element&&(obj.fill=cagColor(element.color),obj.stroke=obj.fill),"opacity"in element&&(obj.opacity=element.opacity),"fill"in element)obj.fill=cagColor(element.fill);else{const s=cssStyle(element,"fill");s&&(obj.fill=cagColor(s))}if("fill-opacity"in element&&(obj.opacity=element["fill-opacity"]),"stroke-width"in element)obj.strokeWidth=element["stroke-width"];else{const sw=cssStyle(element,"stroke-width");sw&&(obj.strokeWidth=sw)}if("stroke"in element)obj.stroke=cagColor(element.stroke);else{const s=cssStyle(element,"stroke");s&&(obj.stroke=cagColor(s))}"stroke-opacity"in element&&(obj.strokeOpacity=element["stroke-opacity"])},svgTransformsRegExp=/\w+\(.+\)/i,svgTransforms=(cag,element)=>{let list=null;if("transform"in element)list=element.transform;else{const s=cssStyle(element,"transform");s&&(list=s)}if(null!==list){cag.transforms=[];let v=svgTransformsRegExp.exec(list);for(;null!==v;){const s=svgTransformsRegExp.lastIndex,e=list.indexOf(")")+1;let t=list.slice(s,e);t=t.trim();const n=t.slice(0,t.indexOf("("));let o,a=t.slice(t.indexOf("(")+1,t.indexOf(")")).trim();switch(a=a.indexOf(",")>0?a.split(","):a.split(" "),n){case"translate":1===a.length&&a.push(0),o={translate:[a[0],a[1]]},cag.transforms.push(o);break;case"scale":1===a.length&&a.push(a[0]),o={scale:[a[0],a[1]]},cag.transforms.push(o);break;case"rotate":o={rotate:a},cag.transforms.push(o)}list=list.slice(e,list.length),v=svgTransformsRegExp.exec(list)}}},viewBoxRegExp=/([\d.-]+)[\s,]+([\d.-]+)[\s,]+([\d.-]+)[\s,]+([\d.-]+)/i,svgSvg=(element,{customPxPmm:customPxPmm})=>{const obj={type:"svg",x:0,y:0,width:"100%",height:"100%",strokeWidth:"1"};if(obj.unitsPmm=[pxPmm,pxPmm],"pxpmm"in element&&(obj.pxPmm=element.pxpmm,obj.unitsPmm=[obj.pxPmm,obj.pxPmm]),"width"in element&&(obj.width=element.width),"height"in element&&(obj.height=element.height),"viewBox"in element){const list=element.viewBox.trim(),v=viewBoxRegExp.exec(list);if(null!==v&&(obj.viewX=parseFloat(v[1]),obj.viewY=parseFloat(v[2]),obj.viewW=parseFloat(v[3]),obj.viewH=parseFloat(v[4])),obj.width.indexOf("%")<0){let s=css2cag(obj.width,customPxPmm);s=obj.viewW/s,obj.unitsPmm[0]=s}else{const u=obj.unitsPmm[0]*(parseFloat(obj.width)/100);obj.unitsPmm[0]=u}if(obj.height.indexOf("%")<0){let s=css2cag(obj.height,pxPmm);s=obj.viewH/s,obj.unitsPmm[1]=s}else{const u=obj.unitsPmm[1]*(parseFloat(obj.height)/100);obj.unitsPmm[1]=u}}else obj.viewX=0,obj.viewY=0,obj.viewW=1920/obj.unitsPmm[0],obj.viewH=1080/obj.unitsPmm[1];return obj.viewP=Math.sqrt(obj.viewW*obj.viewW+obj.viewH*obj.viewH)/Math.SQRT2,svgCore(obj,element),svgPresentation(obj,element),obj.objects=[],obj},svgEllipse=element=>{const obj={type:"ellipse",cx:"0",cy:"0",rx:"0",ry:"0"};return"cx"in element&&(obj.cx=element.cx),"cy"in element&&(obj.cy=element.cy),"rx"in element&&(obj.rx=element.rx),"ry"in element&&(obj.ry=element.ry),svgTransforms(obj,element),svgCore(obj,element),svgPresentation(obj,element),obj},svgLine=element=>{const obj={type:"line",x1:"0",y1:"0",x2:"0",y2:"0"};return"x1"in element&&(obj.x1=element.x1),"y1"in element&&(obj.y1=element.y1),"x2"in element&&(obj.x2=element.x2),"y2"in element&&(obj.y2=element.y2),svgTransforms(obj,element),svgCore(obj,element),svgPresentation(obj,element),obj},svgListOfPoints=list=>{const points=[],exp=/([\d\-+.]+)[\s,]+([\d\-+.]+)[\s,]*/i;list=list.trim();let v=exp.exec(list);for(;null!==v;){let point=v[0];const next=exp.lastIndex+point.length;point={x:v[1],y:v[2]},points.push(point),list=list.slice(next,list.length),v=exp.exec(list)}return points},svgPolyline=element=>{const obj={type:"polyline"};return svgTransforms(obj,element),svgCore(obj,element),svgPresentation(obj,element),"points"in element&&(obj.points=svgListOfPoints(element.points)),obj},svgPolygon=element=>{const obj={type:"polygon"};return svgTransforms(obj,element),svgCore(obj,element),svgPresentation(obj,element),"points"in element&&(obj.points=svgListOfPoints(element.points)),obj},svgRect=element=>{const obj={type:"rect",x:"0",y:"0",rx:"0",ry:"0",width:"0",height:"0"};return"x"in element&&(obj.x=element.x),"y"in element&&(obj.y=element.y),"rx"in element&&(obj.rx=element.rx,"ry"in element||(obj.ry=obj.rx)),"ry"in element&&(obj.ry=element.ry,"rx"in element||(obj.rx=obj.ry)),obj.rx!==obj.ry&&console.log("Warning: Unsupported RECT with rx and ry radius"),"width"in element&&(obj.width=element.width),"height"in element&&(obj.height=element.height),svgTransforms(obj,element),svgCore(obj,element),svgPresentation(obj,element),obj},svgCircle=element=>{const obj={type:"circle",x:"0",y:"0",radius:"0"};return"cx"in element&&(obj.x=element.cx),"cy"in element&&(obj.y=element.cy),"r"in element&&(obj.radius=element.r),svgTransforms(obj,element),svgCore(obj,element),svgPresentation(obj,element),obj},svgGroup=element=>{const obj={type:"group"};if(svgTransforms(obj,element),svgCore(obj,element),svgPresentation(obj,element),"x"in element||"y"in element){let x="0",y="0";"x"in element&&(x=element.x),"y"in element&&(y=element.y),"transforms"in obj||(obj.transforms=[]);const o={translate:[x,y]};obj.transforms.push(o)}return obj.objects=[],obj},svgPath=element=>{const obj={type:"path"};if(svgTransforms(obj,element),svgCore(obj,element),svgPresentation(obj,element),obj.commands=[],"d"in element){let co=null,bf="",i=0;const l=element.d.length,offset=element.position[1]-l-2;for(;i<l;){const c=element.d[i];switch(c){case"-":bf.length>0&&(co.p.push(bf),bf=""),bf+=c;break;case".":bf.length>0&&bf.indexOf(".")>=0&&(co.p.push(bf),bf=""),bf+=c;break;case"0":case"1":case"2":case"3":case"4":case"5":case"6":case"7":case"8":case"9":bf+=c;break;case"a":case"A":case"c":case"C":case"h":case"H":case"l":case"L":case"v":case"V":case"m":case"M":case"q":case"Q":case"s":case"S":case"t":case"T":case"z":case"Z":null!==co&&(bf.length>0&&(co.p.push(bf),bf=""),obj.commands.push(co)),co={c:c,p:[],pos:i+offset};break;case",":case" ":case"\n":null!==co&&bf.length>0&&(co.p.push(bf),bf="")}i++}i===l&&null!==co&&(bf.length>0&&co.p.push(bf),obj.commands.push(co))}return obj},svgUse=(element,{svgObjects:svgObjects})=>{const obj={type:"group"};if(svgTransforms(obj,element),svgCore(obj,element),svgPresentation(obj,element),"x"in element||"y"in element){let x="0",y="0";"x"in element&&(x=element.x),"y"in element&&(y=element.y),"transforms"in obj||(obj.transforms=[]);const o={translate:[x,y]};obj.transforms.push(o)}if(obj.objects=[],"xlink:href"in element){let ref=element["xlink:href"];"#"===ref[0]&&(ref=ref.slice(1,ref.length)),void 0!==svgObjects[ref]&&(ref=svgObjects[ref],ref=JSON.parse(JSON.stringify(ref)),obj.objects.push(ref))}return obj},shapesMapGeometry=(obj,objectify,params)=>{const{svgUnitsPmm:svgUnitsPmm,svgUnitsX:svgUnitsX,svgUnitsY:svgUnitsY,svgUnitsV:svgUnitsV,svgGroups:svgGroups,target:target,segments:segments,pathSelfClosed:pathSelfClosed}=params,types={group:obj=>objectify({target:target,segments:segments},obj),rect:(obj,svgUnitsPmm,svgUnitsX,svgUnitsY,svgUnitsV,svgGroups,segments)=>{let x=cagLengthX(obj.x,svgUnitsPmm,svgUnitsX),y=0-cagLengthY(obj.y,svgUnitsPmm,svgUnitsY);const w=cagLengthX(obj.width,svgUnitsPmm,svgUnitsX),h=cagLengthY(obj.height,svgUnitsPmm,svgUnitsY),rx=cagLengthX(obj.rx,svgUnitsPmm,svgUnitsX);let shape;return w>0&&h>0&&(x+=w/2,y-=h/2,shape=0===rx?rectangle({center:[x,y],size:[w,h]}):(options=>{let{center:center,size:size,roundRadius:roundRadius,segments:segments}=Object.assign({},{center:[0,0],size:[2,2],roundRadius:.2,segments:32},options);if(!isNumberArray(center,2))throw new Error("center must be an array of X and Y values");if(!isNumberArray(size,2))throw new Error("size must be an array of X and Y values");if(!size.every((n=>n>=0)))throw new Error("size values must be positive");if(!isGTE(roundRadius,0))throw new Error("roundRadius must be positive");if(!isGTE(segments,4))throw new Error("segments must be four or more");if(0===size[0]||0===size[1])return create$a();if(0===roundRadius)return rectangle({center:center,size:size});if(size=size.map((v=>v/2)),roundRadius>size[0]-EPS||roundRadius>size[1]-EPS)throw new Error("roundRadius must be smaller than the radius of all dimensions");const cornerSegments=Math.floor(segments/4),corner0=add([0,0],center,[size[0]-roundRadius,size[1]-roundRadius]),corner1=add([0,0],center,[roundRadius-size[0],size[1]-roundRadius]),corner2=add([0,0],center,[roundRadius-size[0],roundRadius-size[1]]),corner3=add([0,0],center,[size[0]-roundRadius,roundRadius-size[1]]),corner0Points=[],corner1Points=[],corner2Points=[],corner3Points=[];for(let i=0;i<=cornerSegments;i++){const point=fromAngleRadians([0,0],TAU/4*i/cornerSegments);scale$1(point,point,roundRadius),corner0Points.push(add([0,0],corner0,point)),rotate$1(point,point,[0,0],TAU/4),corner1Points.push(add([0,0],corner1,point)),rotate$1(point,point,[0,0],TAU/4),corner2Points.push(add([0,0],corner2,point)),rotate$1(point,point,[0,0],TAU/4),corner3Points.push(add([0,0],corner3,point))}const points=corner0Points.concat(corner1Points,corner2Points,corner3Points);return create$a([points])})({center:[x,y],segments:segments,size:[w,h],roundRadius:rx}),"path"===target&&(shape=index$5.fromPoints({closed:!0},index$a.toPoints(shape)))),shape},circle:(obj,svgUnitsPmm,svgUnitsX,svgUnitsY,svgUnitsV,svgGroups,segments)=>{const x=cagLengthX(obj.x,svgUnitsPmm,svgUnitsX),y=0-cagLengthY(obj.y,svgUnitsPmm,svgUnitsY),r=cagLengthP(obj.radius,svgUnitsPmm,svgUnitsV);let shape;return r>0&&(shape=(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})})({center:[x,y],segments:segments,radius:r}),"path"===target&&(shape=index$5.fromPoints({closed:!0},index$a.toPoints(shape)))),shape},ellipse:(obj,svgUnitsPmm,svgUnitsX,svgUnitsY,svgUnitsV,svgGroups,segments)=>{const rx=cagLengthX(obj.rx,svgUnitsPmm,svgUnitsX),ry=cagLengthY(obj.ry,svgUnitsPmm,svgUnitsY),cx=cagLengthX(obj.cx,svgUnitsPmm,svgUnitsX),cy=0-cagLengthY(obj.cy,svgUnitsPmm,svgUnitsY);let shape;return rx>0&&ry>0&&(shape=ellipse({center:[cx,cy],segments:segments,radius:[rx,ry]}),"path"===target&&(shape=index$5.fromPoints({closed:!0},index$a.toPoints(shape)))),shape},line:(obj,svgUnitsPmm,svgUnitsX,svgUnitsY,svgUnitsV)=>{const x1=cagLengthX(obj.x1,svgUnitsPmm,svgUnitsX),y1=0-cagLengthY(obj.y1,svgUnitsPmm,svgUnitsY),x2=cagLengthX(obj.x2,svgUnitsPmm,svgUnitsX),y2=0-cagLengthY(obj.y2,svgUnitsPmm,svgUnitsY);return line([[x1,y1],[x2,y2]])},polygon:(obj,svgUnitsPmm,svgUnitsX,svgUnitsY)=>{const points=[];for(let j=0;j<obj.points.length;j++){const p=obj.points[j];if("x"in p&&"y"in p){const x=cagLengthX(p.x,svgUnitsPmm,svgUnitsX),y=0-cagLengthY(p.y,svgUnitsPmm,svgUnitsY);points.push([x,y])}}return"geom2"===target?index$a.create([points]):index$5.fromPoints({},points)},polyline:(obj,svgUnitsPmm,svgUnitsX,svgUnitsY,svgUnitsV)=>{const points=[];for(let j=0;j<obj.points.length;j++){const p=obj.points[j];if("x"in p&&"y"in p){const x=cagLengthX(p.x,svgUnitsPmm,svgUnitsX),y=0-cagLengthY(p.y,svgUnitsPmm,svgUnitsY);points.push([x,y])}}return line(points)},path:(obj,svgUnitsPmm,svgUnitsX,svgUnitsY,svgUnitsV,svgGroups,segments)=>{const listofpaths=expandPath(obj,svgUnitsPmm,svgUnitsX,svgUnitsY,svgUnitsV,svgGroups,segments,pathSelfClosed),shapes=Object.entries(listofpaths).sort(((a,b)=>a[0].localeCompare(b[0]))).map((entry=>{const path=entry[1];if("geom2"===target&&path.isClosed){const points=index$5.toPoints(path);return index$a.create([points])}return path}));return shapes}};return types[obj.type](obj,svgUnitsPmm,svgUnitsX,svgUnitsY,svgUnitsV,svgGroups,segments)},appendPoints=(points,geometry)=>geometry?index$5.appendPoints(points,geometry):index$5.fromPoints({},points),expandPath=(obj,svgUnitsPmm,svgUnitsX,svgUnitsY,svgUnitsV,svgGroups,segments,pathSelfClosed)=>{const paths={};let sx=0,sy=0,cx=0,cy=0,pi=0,pathName="path"+pi,pc=!1,bx=0,by=0,qx=0,qy=0;const newPath=()=>{pi++,pathName="path"+pi,pc=!1},ensurePath=()=>{paths[pathName]||(paths[pathName]=index$5.fromPoints({},[]))};for(let j=0;j<obj.commands.length;j++){const co=obj.commands[j],pts=co.p;let i=0;switch(co.c){case"m":for(0===j&&(cx=0,cy=0),pts.length>=i+2&&(cx+=parseFloat(pts[i++]),cy+=parseFloat(pts[i++]),newPath(),paths[pathName]=appendPoints([svg2cag([cx,cy],svgUnitsPmm)]),sx=cx,sy=cy);pts.length>=i+2;)cx+=parseFloat(pts[i++]),cy+=parseFloat(pts[i++]),paths[pathName]=appendPoints([svg2cag([cx,cy],svgUnitsPmm)],paths[pathName]);break;case"M":for(pts.length>=i+2&&(cx=parseFloat(pts[i++]),cy=parseFloat(pts[i++]),newPath(),paths[pathName]=appendPoints([svg2cag([cx,cy],svgUnitsPmm)]),sx=cx,sy=cy);pts.length>=i+2;)cx=parseFloat(pts[i++]),cy=parseFloat(pts[i++]),paths[pathName]=appendPoints([svg2cag([cx,cy],svgUnitsPmm)],paths[pathName]);break;case"a":for(;pts.length>=i+7;){const rx=parseFloat(pts[i++]),ry=parseFloat(pts[i++]),ro=0-.017453292519943295*parseFloat(pts[i++]),lf="1"===pts[i++],sf="1"===pts[i++];cx+=parseFloat(pts[i++]),cy+=parseFloat(pts[i++]),ensurePath(),paths[pathName]=index$5.appendArc({segments:segments,endpoint:svg2cag([cx,cy],svgUnitsPmm),radius:svg2cag([rx,ry],svgUnitsPmm),xaxisrotation:ro,clockwise:sf,large:lf},paths[pathName])}break;case"A":for(;pts.length>=i+7;){const rx=parseFloat(pts[i++]),ry=parseFloat(pts[i++]),ro=0-.017453292519943295*parseFloat(pts[i++]),lf="1"===pts[i++],sf="1"===pts[i++];cx=parseFloat(pts[i++]),cy=parseFloat(pts[i++]),ensurePath(),paths[pathName]=index$5.appendArc({segments:segments,endpoint:svg2cag([cx,cy],svgUnitsPmm),radius:svg2cag([rx,ry],svgUnitsPmm),xaxisrotation:ro,clockwise:sf,large:lf},paths[pathName])}break;case"c":for(;pts.length>=i+6;){const x1=cx+parseFloat(pts[i++]),y1=cy+parseFloat(pts[i++]);bx=cx+parseFloat(pts[i++]),by=cy+parseFloat(pts[i++]),cx+=parseFloat(pts[i++]),cy+=parseFloat(pts[i++]),ensurePath(),paths[pathName]=index$5.appendBezier({segments:segments,controlPoints:[svg2cag([x1,y1],svgUnitsPmm),svg2cag([bx,by],svgUnitsPmm),svg2cag([cx,cy],svgUnitsPmm)]},paths[pathName]);const rf=reflect(bx,by,cx,cy);bx=rf[0],by=rf[1]}break;case"C":for(;pts.length>=i+6;){const x1=parseFloat(pts[i++]),y1=parseFloat(pts[i++]);bx=parseFloat(pts[i++]),by=parseFloat(pts[i++]),cx=parseFloat(pts[i++]),cy=parseFloat(pts[i++]),ensurePath(),paths[pathName]=index$5.appendBezier({segments:segments,controlPoints:[svg2cag([x1,y1],svgUnitsPmm),svg2cag([bx,by],svgUnitsPmm),svg2cag([cx,cy],svgUnitsPmm)]},paths[pathName]);const rf=reflect(bx,by,cx,cy);bx=rf[0],by=rf[1]}break;case"q":for(;pts.length>=i+4;){const p0=[cx,cy];qx=cx+parseFloat(pts[i++]),qy=cy+parseFloat(pts[i++]),cx+=parseFloat(pts[i++]),cy+=parseFloat(pts[i++]);const q1=[p0[0]+2/3*(qx-p0[0]),p0[1]+2/3*(qy-p0[1])],q2=[q1[0]+1/3*(cx-p0[0]),q1[1]+1/3*(cy-p0[1])];ensurePath(),paths[pathName]=index$5.appendBezier({segments:segments,controlPoints:[svg2cag(q1,svgUnitsPmm),svg2cag(q2,svgUnitsPmm),svg2cag([cx,cy],svgUnitsPmm)]},paths[pathName]);const rf=reflect(qx,qy,cx,cy);qx=rf[0],qy=rf[1]}break;case"Q":for(;pts.length>=i+4;){const p0=[cx,cy];qx=parseFloat(pts[i++]),qy=parseFloat(pts[i++]),cx=parseFloat(pts[i++]),cy=parseFloat(pts[i++]);const q1=[p0[0]+2/3*(qx-p0[0]),p0[1]+2/3*(qy-p0[1])],q2=[q1[0]+1/3*(cx-p0[0]),q1[1]+1/3*(cy-p0[1])];ensurePath(),paths[pathName]=index$5.appendBezier({segments:segments,controlPoints:[svg2cag(q1,svgUnitsPmm),svg2cag(q2,svgUnitsPmm),svg2cag([cx,cy],svgUnitsPmm)]},paths[pathName]);const rf=reflect(qx,qy,cx,cy);qx=rf[0],qy=rf[1]}break;case"t":for(;pts.length>=i+2;){const p0=[cx,cy];cx+=parseFloat(pts[i++]),cy+=parseFloat(pts[i++]);const q1=[p0[0]+2/3*(qx-p0[0]),p0[1]+2/3*(qy-p0[1])],q2=[q1[0]+1/3*(cx-p0[0]),q1[1]+1/3*(cy-p0[1])];ensurePath(),paths[pathName]=index$5.appendBezier({segments:segments,controlPoints:[svg2cag(q1,svgUnitsPmm),svg2cag(q2,svgUnitsPmm),svg2cag([cx,cy],svgUnitsPmm)]},paths[pathName]);const rf=reflect(qx,qy,cx,cy);qx=rf[0],qy=rf[1]}break;case"T":for(;pts.length>=i+2;){const p0=[cx,cy];cx=parseFloat(pts[i++]),cy=parseFloat(pts[i++]);const q1=[p0[0]+2/3*(qx-p0[0]),p0[1]+2/3*(qy-p0[1])],q2=[q1[0]+1/3*(cx-p0[0]),q1[1]+1/3*(cy-p0[1])];ensurePath(),paths[pathName]=index$5.appendBezier({segments:segments,controlPoints:[svg2cag(q1,svgUnitsPmm),svg2cag(q2,svgUnitsPmm),svg2cag([cx,cy],svgUnitsPmm)]},paths[pathName]);const rf=reflect(qx,qy,cx,cy);qx=rf[0],qy=rf[1]}break;case"s":for(;pts.length>=i+4;){const x1=bx,y1=by;bx=cx+parseFloat(pts[i++]),by=cy+parseFloat(pts[i++]),cx+=parseFloat(pts[i++]),cy+=parseFloat(pts[i++]),ensurePath(),paths[pathName]=index$5.appendBezier({segments:segments,controlPoints:[svg2cag([x1,y1],svgUnitsPmm),svg2cag([bx,by],svgUnitsPmm),svg2cag([cx,cy],svgUnitsPmm)]},paths[pathName]);const rf=reflect(bx,by,cx,cy);bx=rf[0],by=rf[1]}break;case"S":for(;pts.length>=i+4;){const x1=bx,y1=by;bx=parseFloat(pts[i++]),by=parseFloat(pts[i++]),cx=parseFloat(pts[i++]),cy=parseFloat(pts[i++]),ensurePath(),paths[pathName]=index$5.appendBezier({segments:segments,controlPoints:[svg2cag([x1,y1],svgUnitsPmm),svg2cag([bx,by],svgUnitsPmm),svg2cag([cx,cy],svgUnitsPmm)]},paths[pathName]);const rf=reflect(bx,by,cx,cy);bx=rf[0],by=rf[1]}break;case"h":for(;pts.length>=i+1;)cx+=parseFloat(pts[i++]),paths[pathName]=appendPoints([svg2cag([cx,cy],svgUnitsPmm)],paths[pathName]);break;case"H":for(;pts.length>=i+1;)cx=parseFloat(pts[i++]),paths[pathName]=appendPoints([svg2cag([cx,cy],svgUnitsPmm)],paths[pathName]);break;case"l":for(;pts.length>=i+2;)cx+=parseFloat(pts[i++]),cy+=parseFloat(pts[i++]),paths[pathName]=appendPoints([svg2cag([cx,cy],svgUnitsPmm)],paths[pathName]);break;case"L":for(;pts.length>=i+2;)cx=parseFloat(pts[i++]),cy=parseFloat(pts[i++]),paths[pathName]=appendPoints([svg2cag([cx,cy],svgUnitsPmm)],paths[pathName]);break;case"v":for(;pts.length>=i+1;)cy+=parseFloat(pts[i++]),paths[pathName]=appendPoints([svg2cag([cx,cy],svgUnitsPmm)],paths[pathName]);break;case"V":for(;pts.length>=i+1;)cy=parseFloat(pts[i++]),paths[pathName]=appendPoints([svg2cag([cx,cy],svgUnitsPmm)],paths[pathName]);break;case"z":case"Z":paths[pathName]=index$5.close(paths[pathName]),cx=sx,cy=sy,pc=!0;break;default:console.log("Warning: Unknown PATH command ["+co.c+"]")}const isCloseCmd=cmd=>"z"===cmd||"Z"===cmd;if(!0!==pc&&paths[pathName]&&paths[pathName].isClosed){let coNext=obj.commands[j+1];if(coNext&&!isCloseCmd(coNext.c))if("trim"===pathSelfClosed)for(;coNext&&!isCloseCmd(coNext.c);)j++,coNext=obj.commands[j+1];else{if("split"!==pathSelfClosed)throw new Error(`Malformed svg path at ${obj.position[0]}:${co.pos}. Path closed itself with command #${j} ${co.c}${pts.join(" ")}`);newPath()}}}return paths},shapesMapJscad=(obj,codify,params)=>{const{level:level,indent:indent,on:on,svgUnitsPmm:svgUnitsPmm,svgUnitsX:svgUnitsX,svgUnitsY:svgUnitsY,svgUnitsV:svgUnitsV,svgGroups:svgGroups,target:target,segments:segments}=params,types={group:obj=>{let code=codify({target:target,segments:segments},obj);return code+=`${indent}${on} = levels.l${level+1}\n`,code},rect:(obj,svgUnitsPmm,svgUnitsX,svgUnitsY,svgUnitsV,params,svgGroups,segments)=>{let x=cagLengthX(obj.x,svgUnitsPmm,svgUnitsX),y=0-cagLengthY(obj.y,svgUnitsPmm,svgUnitsY);const w=cagLengthX(obj.width,svgUnitsPmm,svgUnitsX),h=cagLengthY(obj.height,svgUnitsPmm,svgUnitsY),rx=cagLengthX(obj.rx,svgUnitsPmm,svgUnitsX);let code;return w>0&&h>0&&(x=(x+w/2).toFixed(4),y=(y-h/2).toFixed(4),code=0===rx?`${indent}${on} = rectangle({center: [${x}, ${y}], size: [${w}, ${h}]}) // line ${obj.position}\n`:`${indent}${on} = roundedRectangle({center: [${x}, ${y}], segments: ${segments}, size: [${w}, ${h}], roundRadius: ${rx}}) // line ${obj.position}\n`,"path"===target&&(code+=`${indent}${on} = path2.fromPoints({closed: true}, geom2.toPoints(${on}))\n`)),code},circle:(obj,svgUnitsPmm,svgUnitsX,svgUnitsY,svgUnitsV,params,svgGroups,segments)=>{const x=cagLengthX(obj.x,svgUnitsPmm,svgUnitsX),y=0-cagLengthY(obj.y,svgUnitsPmm,svgUnitsY),r=cagLengthP(obj.radius,svgUnitsPmm,svgUnitsV);let code;return r>0&&(code=`${indent}${on} = circle({center: [${x}, ${y}], segments: ${segments}, radius: ${r}}) // line ${obj.position}\n`,"path"===target&&(code+=`${indent}${on} = path2.fromPoints({closed: true}, geom2.toPoints(${on}))\n`)),code},ellipse:(obj,svgUnitsPmm,svgUnitsX,svgUnitsY,svgUnitsV,params,svgGroups,segments)=>{const rx=cagLengthX(obj.rx,svgUnitsPmm,svgUnitsX),ry=cagLengthY(obj.ry,svgUnitsPmm,svgUnitsY),cx=cagLengthX(obj.cx,svgUnitsPmm,svgUnitsX),cy=0-cagLengthY(obj.cy,svgUnitsPmm,svgUnitsY);let code;return rx>0&&ry>0&&(code=`${indent}${on} = ellipse({center: [${cx}, ${cy}], segments: ${segments}, radius: [${rx}, ${ry}]}) // line ${obj.position}\n`,"path"===target&&(code+=`${indent}${on} = path2.fromPoints({closed: true}, geom2.toPoints(${on}))\n`)),code},line:(obj,svgUnitsPmm,svgUnitsX,svgUnitsY,svgUnitsV)=>{const x1=cagLengthX(obj.x1,svgUnitsPmm,svgUnitsX),y1=0-cagLengthY(obj.y1,svgUnitsPmm,svgUnitsY),x2=cagLengthX(obj.x2,svgUnitsPmm,svgUnitsX),y2=0-cagLengthY(obj.y2,svgUnitsPmm,svgUnitsY);return`${indent}${on} = line([[${x1}, ${y1}], [${x2}, ${y2}]]) // line ${obj.position}\n`},polygon:(obj,svgUnitsPmm,svgUnitsX,svgUnitsY)=>{let code=`${indent}${on} = polygon({points: [\n`;for(let j=0;j<obj.points.length;j++){const p=obj.points[j];if("x"in p&&"y"in p){const x=cagLengthX(p.x,svgUnitsPmm,svgUnitsX),y=0-cagLengthY(p.y,svgUnitsPmm,svgUnitsY);code+=`${indent} [${x}, ${y}],\n`}}return code+=`${indent}]}) // line ${obj.position}\n`,"path"===target&&(code+=`${indent}${on} = path2.fromPoints({closed: true}, geom2.toPoints(${on}))\n`),code},polyline:(obj,svgUnitsPmm,svgUnitsX,svgUnitsY,svgUnitsV)=>{let code=`${indent}${on} = path2.fromPoints({}, [\n`;for(let j=0;j<obj.points.length;j++){const p=obj.points[j];if("x"in p&&"y"in p){const x=cagLengthX(p.x,svgUnitsPmm,svgUnitsX),y=0-cagLengthY(p.y,svgUnitsPmm,svgUnitsY);code+=`${indent} [${x}, ${y}],\n`}}return code+=`${indent}]) // line ${obj.position}\n`,code},path:path};return types[obj.type](obj,svgUnitsPmm,svgUnitsX,svgUnitsY,svgUnitsV,params,svgGroups,segments)},path=(obj,svgUnitsPmm,svgUnitsX,svgUnitsY,svgUnitsV,params,svgGroups,segments)=>{const{indent:indent,on:on,target:target}=params;let tmpCode=`${indent}parts = [] // line ${obj.position}\n`,sx=0,sy=0,cx=0,cy=0,pi=0,pathName=on+pi,pc=!1,bx=0,by=0,qx=0,qy=0;for(let j=0;j<obj.commands.length;j++){const co=obj.commands[j],pts=co.p;switch(co.c){case"m":for(0===j&&(cx=0,cy=0),pi>0&&!1===pc&&(tmpCode+=`${indent}parts.push(${pathName})\n`),pts.length>=2&&(cx+=parseFloat(pts.shift()),cy+=parseFloat(pts.shift()),pi++,pc=!1,pathName=on+pi,tmpCode+=`${indent}${pathName} = path2.fromPoints({}, [[${svg2cag([cx,cy],svgUnitsPmm)}]])\n`,sx=cx,sy=cy);pts.length>=2;)cx+=parseFloat(pts.shift()),cy+=parseFloat(pts.shift()),tmpCode+=`${indent}${pathName} = path2.appendPoints([${svg2cag([cx,cy],svgUnitsPmm)}], ${pathName})\n`;break;case"M":for(pi>0&&!1===pc&&(tmpCode+=`${indent}parts.push(${pathName})\n`),pts.length>=2&&(cx=parseFloat(pts.shift()),cy=parseFloat(pts.shift()),pi++,pc=!1,pathName=on+pi,tmpCode+=`${indent}${pathName} = path2.fromPoints({}, [[${svg2cag([cx,cy],svgUnitsPmm)}]])\n`,sx=cx,sy=cy);pts.length>=2;)cx=parseFloat(pts.shift()),cy=parseFloat(pts.shift()),tmpCode+=`${indent}${pathName} = path2.appendPoints([${svg2cag([cx,cy],svgUnitsPmm)}], ${pathName})\n`;break;case"a":for(;pts.length>=7;){const rx=parseFloat(pts.shift()),ry=parseFloat(pts.shift()),ro=0-.017453292519943295*parseFloat(pts.shift()),lf="1"===pts.shift(),sf="1"===pts.shift();cx+=parseFloat(pts.shift()),cy+=parseFloat(pts.shift()),tmpCode+=`${indent}${pathName} = path2.appendArc({segments: ${segments}, endpoint: [${svg2cag([cx,cy],svgUnitsPmm)}], radius: [${svg2cag([rx,ry],svgUnitsPmm)}], xaxisrotation: ${ro}, clockwise: ${sf}, large: ${lf}}, ${pathName})\n`}break;case"A":for(;pts.length>=7;){const rx=parseFloat(pts.shift()),ry=parseFloat(pts.shift()),ro=0-.017453292519943295*parseFloat(pts.shift()),lf="1"===pts.shift(),sf="1"===pts.shift();cx=parseFloat(pts.shift()),cy=parseFloat(pts.shift()),tmpCode+=`${indent}${pathName} = path2.appendArc({segments: ${segments}, endpoint: [${svg2cag([cx,cy],svgUnitsPmm)}], radius: [${svg2cag([rx,ry],svgUnitsPmm)}], xaxisrotation: ${ro}, clockwise: ${sf}, large: ${lf}}, ${pathName})\n`}break;case"c":for(;pts.length>=6;){const x1=cx+parseFloat(pts.shift()),y1=cy+parseFloat(pts.shift());bx=cx+parseFloat(pts.shift()),by=cy+parseFloat(pts.shift()),cx+=parseFloat(pts.shift()),cy+=parseFloat(pts.shift()),tmpCode+=`${indent}${pathName} = path2.appendBezier({segments: ${segments}, controlPoints: [[${svg2cag([x1,y1],svgUnitsPmm)}], [${svg2cag([bx,by],svgUnitsPmm)}], [${svg2cag([cx,cy],svgUnitsPmm)}]]}, ${pathName})\n`;const rf=reflect(bx,by,cx,cy);bx=rf[0],by=rf[1]}break;case"C":for(;pts.length>=6;){const x1=parseFloat(pts.shift()),y1=parseFloat(pts.shift());bx=parseFloat(pts.shift()),by=parseFloat(pts.shift()),cx=parseFloat(pts.shift()),cy=parseFloat(pts.shift()),tmpCode+=`${indent}${pathName} = path2.appendBezier({segments: ${segments}, controlPoints: [[${svg2cag([x1,y1],svgUnitsPmm)}], [${svg2cag([bx,by],svgUnitsPmm)}], [${svg2cag([cx,cy],svgUnitsPmm)}]]}, ${pathName})\n`;const rf=reflect(bx,by,cx,cy);bx=rf[0],by=rf[1]}break;case"q":for(;pts.length>=4;){const p0=[cx,cy];qx=cx+parseFloat(pts.shift()),qy=cy+parseFloat(pts.shift()),cx+=parseFloat(pts.shift()),cy+=parseFloat(pts.shift());const q1=[p0[0]+2/3*(qx-p0[0]),p0[1]+2/3*(qy-p0[1])],q2=[q1[0]+1/3*(cx-p0[0]),q1[1]+1/3*(cy-p0[1])];tmpCode+=`${indent}${pathName} = path2.appendBezier({segments: ${segments}, controlPoints: [[${svg2cag(q1,svgUnitsPmm)}], [${svg2cag(q2,svgUnitsPmm)}], [${svg2cag([cx,cy],svgUnitsPmm)}]]}, ${pathName})\n`;const rf=reflect(qx,qy,cx,cy);qx=rf[0],qy=rf[1]}break;case"Q":for(;pts.length>=4;){const p0=[cx,cy];qx=parseFloat(pts.shift()),qy=parseFloat(pts.shift()),cx=parseFloat(pts.shift()),cy=parseFloat(pts.shift());const q1=[p0[0]+2/3*(qx-p0[0]),p0[1]+2/3*(qy-p0[1])],q2=[q1[0]+1/3*(cx-p0[0]),q1[1]+1/3*(cy-p0[1])];tmpCode+=`${indent}${pathName} = path2.appendBezier({segments: ${segments}, controlPoints: [[${svg2cag(q1,svgUnitsPmm)}], [${svg2cag(q2,svgUnitsPmm)}], [${svg2cag([cx,cy],svgUnitsPmm)}]]}, ${pathName})\n`;const rf=reflect(qx,qy,cx,cy);qx=rf[0],qy=rf[1]}break;case"t":for(;pts.length>=2;){const p0=[cx,cy];cx+=parseFloat(pts.shift()),cy+=parseFloat(pts.shift());const q1=[p0[0]+2/3*(qx-p0[0]),p0[1]+2/3*(qy-p0[1])],q2=[q1[0]+1/3*(cx-p0[0]),q1[1]+1/3*(cy-p0[1])];tmpCode+=`${indent}${pathName} = path2.appendBezier({segments: ${segments}, controlPoints: [[[${svg2cag(q1,svgUnitsPmm)}], [${svg2cag(q2,svgUnitsPmm)}], [${svg2cag([cx,cy],svgUnitsPmm)}]]}, ${pathName})\n`;const rf=reflect(qx,qy,cx,cy);qx=rf[0],qy=rf[1]}break;case"T":for(;pts.length>=2;){const p0=[cx,cy];cx=parseFloat(pts.shift()),cy=parseFloat(pts.shift());const q1=[p0[0]+2/3*(qx-p0[0]),p0[1]+2/3*(qy-p0[1])],q2=[q1[0]+1/3*(cx-p0[0]),q1[1]+1/3*(cy-p0[1])];tmpCode+=`${indent}${pathName} = path2.appendBezier({segments: ${segments}, controlPoints: [[[${svg2cag(q1,svgUnitsPmm)}], [${svg2cag(q2,svgUnitsPmm)}], [${svg2cag([cx,cy],svgUnitsPmm)}]]}, ${pathName})\n`;const rf=reflect(qx,qy,cx,cy);qx=rf[0],qy=rf[1]}break;case"s":for(;pts.length>=4;){const x1=bx,y1=by;bx=cx+parseFloat(pts.shift()),by=cy+parseFloat(pts.shift()),cx+=parseFloat(pts.shift()),cy+=parseFloat(pts.shift()),tmpCode+=`${indent}${pathName} = path2.appendBezier({segments: ${segments}, controlPoints: [[${svg2cag([x1,y1],svgUnitsPmm)}], [${svg2cag([bx,by],svgUnitsPmm)}], [${svg2cag([cx,cy],svgUnitsPmm)}]]}, ${pathName})\n`;const rf=reflect(bx,by,cx,cy);bx=rf[0],by=rf[1]}break;case"S":for(;pts.length>=4;){const x1=bx,y1=by;bx=parseFloat(pts.shift()),by=parseFloat(pts.shift()),cx=parseFloat(pts.shift()),cy=parseFloat(pts.shift()),tmpCode+=`${indent}${pathName} = path2.appendBezier({segments: ${segments}, controlPoints: [[${svg2cag([x1,y1],svgUnitsPmm)}], [${svg2cag([bx,by],svgUnitsPmm)}], [${svg2cag([cx,cy],svgUnitsPmm)}]]}, ${pathName})\n`;const rf=reflect(bx,by,cx,cy);bx=rf[0],by=rf[1]}break;case"h":for(;pts.length>=1;)cx+=parseFloat(pts.shift()),tmpCode+=`${indent}${pathName} = path2.appendPoints([[${svg2cag([cx,cy],svgUnitsPmm)}]], ${pathName})\n`;break;case"H":for(;pts.length>=1;)cx=parseFloat(pts.shift()),tmpCode+=`${indent}${pathName} = path2.appendPoints([[${svg2cag([cx,cy],svgUnitsPmm)}]], ${pathName})\n`;break;case"l":for(;pts.length>=2;)cx+=parseFloat(pts.shift()),cy+=parseFloat(pts.shift()),tmpCode+=`${indent}${pathName} = path2.appendPoints([[${svg2cag([cx,cy],svgUnitsPmm)}]], ${pathName})\n`;break;case"L":for(;pts.length>=2;)cx=parseFloat(pts.shift()),cy=parseFloat(pts.shift()),tmpCode+=`${indent}${pathName} = path2.appendPoints([[${svg2cag([cx,cy],svgUnitsPmm)}]], ${pathName})\n`;break;case"v":for(;pts.length>=1;)cy+=parseFloat(pts.shift()),tmpCode+=`${indent}${pathName} = path2.appendPoints([[${svg2cag([cx,cy],svgUnitsPmm)}]], ${pathName})\n`;break;case"V":for(;pts.length>=1;)cy=parseFloat(pts.shift()),tmpCode+=`${indent}${pathName} = path2.appendPoints([[${svg2cag([cx,cy],svgUnitsPmm)}]], ${pathName})\n`;break;case"z":case"Z":tmpCode+=`${indent}${pathName} = path2.close(${pathName})\n`,"geom2"===target&&(tmpCode+=`${indent}${pathName} = geom2.create([path2.toPoints(${pathName})])\n`),tmpCode+=`${indent}parts.push(${pathName})\n`,cx=sx,cy=sy,pc=!0;break;default:console.log("Warning: Unknow PATH command ["+co.c+"]")}}return pi>0&&!1===pc&&(tmpCode+=`${indent}parts.push(${pathName})\n`),tmpCode+=`${indent}${on} = parts\n`,tmpCode},instantiate=(src,options)=>{const{pxPmm:pxPmm}=options;if(options&&options.statusCallback&&options.statusCallback({progress:0}),createSvgParser(src,pxPmm),!svgObj)throw new Error("SVG parsing failed, no valid SVG data retrieved");options&&options.statusCallback&&options.statusCallback({progress:50});const result=objectify(options,svgObj);return options&&options.statusCallback&&options.statusCallback({progress:100}),result},translateScript=(src,options)=>{const{filename:filename,version:version,pxPmm:pxPmm,addMetaData:addMetaData}=options;if(options&&options.statusCallback&&options.statusCallback({progress:0}),createSvgParser(src,pxPmm),!svgObj)throw new Error("SVG parsing failed, no valid SVG data retrieved");let code=addMetaData?`//\n // producer: JSCAD SVG Deserializer ${version}\n // date: ${new Date}\n // source: ${filename}\n //\n`:"";return code+="const { colors, geometries, primitives, transforms } = require('@jscad/modeling')\n\n",options&&options.statusCallback&&options.statusCallback({progress:50}),code+=codify(options,svgObj),code+="\nmodule.exports = { main }",options&&options.statusCallback&&options.statusCallback({progress:100}),code};let svgUnitsX,svgUnitsY,svgUnitsV;const svgObjects=[],svgGroups=[],svgDefs=[];let svgObj,svgInDefs=!1,svgUnitsPmm=[1,1];const objectify=(options,group)=>{const{target:target,segments:segments,pathSelfClosed:pathSelfClosed}=options,level=svgGroups.length;svgGroups.push(group);let i=level;for(;i>0;)i--;let geometries=[];const params={svgUnitsPmm:svgUnitsPmm,svgUnitsX:svgUnitsX,svgUnitsY:svgUnitsY,svgUnitsV:svgUnitsV,level:level,target:target,svgGroups:svgGroups,segments:segments,pathSelfClosed:pathSelfClosed};for(i=0;i<group.objects.length;i++){const obj=group.objects[i];let shapes=(array=shapesMapGeometry(obj,objectify,params),Array.isArray(array)?array:null==array?[]:[array]);shapes=shapes.map((shape=>{if("transforms"in obj){let rotateAttribute=null,scaleAttribute=null,translateAttribute=null;for(let j=0;j<obj.transforms.length;j++){const t=obj.transforms[j];"rotate"in t&&(rotateAttribute=t),"scale"in t&&(scaleAttribute=t),"translate"in t&&(translateAttribute=t)}if(null!==scaleAttribute){let x=Math.abs(scaleAttribute.scale[0]),y=Math.abs(scaleAttribute.scale[1]);shape=scale([x,y,1],shape),x=scaleAttribute.scale[0],y=scaleAttribute.scale[1],x<0&&(shape=mirrorX(shape)),y<0&&(shape=mirrorY(shape))}if(null!==rotateAttribute){const z=0-.017453292519943295*rotateAttribute.rotate;shape=rotateZ(z,shape)}if(null!==translateAttribute){const x=cagLengthX(translateAttribute.translate[0],svgUnitsPmm,svgUnitsX),y=0-cagLengthY(translateAttribute.translate[1],svgUnitsPmm,svgUnitsY);shape=translate([x,y,0],shape)}}const color=svgColorForTarget(target,obj);return color&&(shape=colorize(color,shape)),shape})),geometries=geometries.concat(shapes)}var array;return svgGroups.pop(),geometries},codify=(options,group)=>{const{target:target,segments:segments}=options,level=svgGroups.length;svgGroups.push(group);let indent=" ",i=level;for(;i>0;)indent+=" ",i--;let code="";0===level&&(code+="function main(params) {\n let levels = {}\n let paths = {}\n let parts\n");const ln="levels.l"+level;for(code+=`${indent}${ln} = []\n`,i=0;i<group.objects.length;i++){const obj=group.objects[i],on="paths.p"+i;if(code+=shapesMapJscad(obj,codify,{level:level,indent:indent,ln:ln,on:on,svgUnitsPmm:svgUnitsPmm,svgUnitsX:svgUnitsX,svgUnitsY:svgUnitsY,svgUnitsV:svgUnitsV,svgGroups:svgGroups,target:target,segments:segments}),"transforms"in obj){let rotateAttribute=null,scaleAttribute=null,translateAttribute=null;for(let j=0;j<obj.transforms.length;j++){const t=obj.transforms[j];"rotate"in t&&(rotateAttribute=t),"scale"in t&&(scaleAttribute=t),"translate"in t&&(translateAttribute=t)}if(null!==scaleAttribute){let x=Math.abs(scaleAttribute.scale[0]),y=Math.abs(scaleAttribute.scale[1]);code+=`${indent}${on} = transforms.scale([${x}, ${y}, 1], ${on})\n`,x=scaleAttribute.scale[0],y=scaleAttribute.scale[1],x<0&&(code+=`${indent}${on} = transforms.mirrorX(${on})\n`),y<0&&(code+=`${indent}${on} = transforms.mirrorY(${on})\n`)}null!==rotateAttribute&&(code+=`${indent}${on} = transforms.rotateZ(${0-.017453292519943295*rotateAttribute.rotate}, ${on})\n`),null!==translateAttribute&&(code+=`${indent}${on} = transforms.translate([${cagLengthX(translateAttribute.translate[0],svgUnitsPmm,svgUnitsX)}, ${0-cagLengthY(translateAttribute.translate[1],svgUnitsPmm,svgUnitsY)}, 0], ${on})\n`)}const color=svgColorForTarget(target,obj);color&&(code+=`${indent}${on} = colors.colorize([${color}], ${on})\n`),code+=`${indent}${ln} = ${ln}.concat(${on})\n\n`}return 0===level&&(code+=indent+"return "+ln+"\n",code+="}\n"),svgGroups.pop(),code},createSvgParser=(src,pxPmm)=>{const parser=new saxes.SaxesParser;return void 0!==pxPmm&&pxPmm>parser.pxPmm&&(parser.pxPmm=pxPmm),parser.on("error",(e=>{console.log(`ERROR: SVG file, line ${parser.line}, column ${parser.column}`),console.log(e)})),parser.on("opentag",(node=>{const objMap={SVG:svgSvg,G:svgGroup,RECT:svgRect,CIRCLE:svgCircle,ELLIPSE:svgEllipse,LINE:svgLine,POLYLINE:svgPolyline,POLYGON:svgPolygon,PATH:svgPath,USE:svgUse,DEFS:()=>{svgInDefs=!0},DESC:()=>{},TITLE:()=>{},STYLE:()=>{},undefined:()=>console.log("WARNING: unsupported SVG element: "+node.name)};node.attributes.position=[parser.line+1,parser.column+1];const elementName=node.name.toUpperCase(),obj=objMap[elementName]?objMap[elementName](node.attributes,{svgObjects:svgObjects,customPxPmm:pxPmm}):void 0;if(obj)if("id"in obj&&(svgObjects[obj.id]=obj),"svg"===obj.type)svgGroups.push(obj),svgUnitsPmm=obj.unitsPmm,svgUnitsX=obj.viewW,svgUnitsY=obj.viewH,svgUnitsV=obj.viewP;else if(!0===svgInDefs){if(svgDefs.length>0){const group=svgDefs.pop();"objects"in group&&group.objects.push(obj),svgDefs.push(group)}"group"===obj.type&&svgDefs.push(obj)}else{if(svgGroups.length>0){const group=svgGroups.pop();"objects"in group&&group.objects.push(obj),svgGroups.push(group)}"group"===obj.type&&svgGroups.push(obj)}})),parser.on("closetag",(node=>{const popGroup=()=>!0===svgInDefs?svgDefs.pop():svgGroups.pop(),objMap={SVG:popGroup,DEFS:()=>{svgInDefs=!1},USE:popGroup,G:popGroup,undefined:()=>{}},elementName=node.name.toUpperCase(),obj=objMap[elementName]?objMap[elementName]():void 0;0===svgGroups.length&&(svgObj=obj)})),parser.on("end",(()=>{})),parser.write(src).close(),parser};exports.deserialize=(options,input)=>{const defaults={addMetaData:!0,filename:"svg",output:"script",pxPmm:pxPmm,segments:32,target:"path",pathSelfClosed:"error",version:"3.0.1-alpha.0"};return options=Object.assign({},defaults,options),input=((stringOrArrayBuffer,defaultBinaryEncoding="utf-8")=>"string"==typeof stringOrArrayBuffer?stringOrArrayBuffer:new TextDecoder(defaultBinaryEncoding).decode(new Uint8Array(stringOrArrayBuffer)))(input),"script"===options.output?translateScript(input,options):instantiate(input,options)},exports.mimeType="image/svg+xml",Object.defineProperty(exports,"__esModule",{value:!0})},"object"==typeof exports&&"undefined"!=typeof module?factory(exports):"function"==typeof define&&define.amd?define(["exports"],factory):factory((global="undefined"!=typeof globalThis?globalThis:global||self).jscadSvgDeserializer={});