UNPKG

rabbit-ear

Version:
2 lines 289 kB
/* Rabbit Ear 0.9.4 alpha 2024-04-20 (c) Kraft, GNU GPLv3 License */ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).ear=t()}(this,(function(){"use strict";const e="object"==typeof window&&"object"==typeof window.document,t="object"==typeof process&&"object"==typeof process.versions&&(null!=process.versions.node||null!=process.versions.bun),r="object"==typeof window&&"Deno"in window&&"object"==typeof window.Deno,s=t||r;var a="valid manifold required",o="cycle not allowed",c="replace() generated undefined",n="foldAngles cannot be determined from flat-folded faces without an assignment",i="WebGl not Supported",l="only convex faces are supported",d="window not set; if using node/deno include package @xmldom/xmldom and set ear.window = xmldom",_="non-convex triangulation requires vertices_coords",m="svgToFold found <style> in <svg>. rendering will be incomplete unless run in a major browser.",g="LayerSolver bad input. no solution possible";const v={window:void 0};e&&(v.window=window);const RabbitEarWindow$1=()=>{if(void 0===v.window)throw new Error(d);return v.window},p=1e-6,u=180/Math.PI,h=Math.PI/180,b=2*Math.PI;var y=Object.freeze({__proto__:null,D2R:h,EPSILON:p,R2D:u,TWO_PI:b});const safeAdd=(e,t)=>e+(t||0),magnitude=e=>Math.sqrt(e.map((e=>e*e)).reduce(safeAdd,0)),magnitude2=e=>Math.sqrt(e[0]*e[0]+e[1]*e[1]),magnitude3=e=>Math.sqrt(e[0]*e[0]+e[1]*e[1]+e[2]*e[2]),magSquared2=e=>e[0]*e[0]+e[1]*e[1],magSquared=e=>e.map((e=>e*e)).reduce(safeAdd,0),normalize$2=e=>{const t=magnitude(e);return 0===t?e:e.map((e=>e/t))},normalize2=e=>{const t=magnitude2(e);return 0===t?[e[0],e[1]]:[e[0]/t,e[1]/t]},normalize3=e=>{const t=magnitude3(e);return 0===t?e:[e[0]/t,e[1]/t,e[2]/t]},scale$1=(e,t)=>e.map((e=>e*t)),scale2$1=(e,t)=>[e[0]*t,e[1]*t],scale3$1=(e,t)=>[e[0]*t,e[1]*t,e[2]*t],scaleNonUniform=(e,t)=>e.map(((e,r)=>e*t[r])),scaleNonUniform2=(e,t)=>[e[0]*t[0],e[1]*t[1]],scaleNonUniform3=(e,t)=>[e[0]*t[0],e[1]*t[1],e[2]*t[2]],add=(e,t)=>e.map(((e,r)=>e+(t[r]||0))),add2=(e,t)=>[e[0]+t[0],e[1]+t[1]],add3=(e,t)=>[e[0]+t[0],e[1]+t[1],e[2]+t[2]],subtract=(e,t)=>e.map(((e,r)=>e-(t[r]||0))),subtract2=(e,t)=>[e[0]-t[0],e[1]-t[1]],subtract3=(e,t)=>[e[0]-t[0],e[1]-t[1],e[2]-t[2]],dot=(e,t)=>e.map(((r,s)=>e[s]*t[s])).reduce(safeAdd,0),dot2=(e,t)=>e[0]*t[0]+e[1]*t[1],dot3=(e,t)=>e[0]*t[0]+e[1]*t[1]+e[2]*t[2],midpoint=(e,t)=>e.map(((e,r)=>(e+t[r])/2)),midpoint2=(e,t)=>scale2$1(add2(e,t),.5),average=(...e)=>{if(0===e.length)return;const t=e[0].length>0?e[0].length:0,r=Array(t).fill(0);return Array.from(e).forEach((e=>r.forEach(((t,s)=>{r[s]+=e[s]||0})))),r.map((t=>t/e.length))},average2=(...e)=>{if(!e||!e.length)return;const t=e.reduce(((e,t)=>add2(e,t)),[0,0]);return[t[0]/e.length,t[1]/e.length]},average3=(...e)=>{if(!e||!e.length)return;const t=e.reduce(((e,t)=>add3(e,t)),[0,0,0]);return[t[0]/e.length,t[1]/e.length,t[2]/e.length]},lerp=(e,t,r=0)=>{const s=1-r;return e.map(((e,a)=>e*s+(t[a]||0)*r))},cross2=(e,t)=>e[0]*t[1]-e[1]*t[0],cross3=(e,t)=>[e[1]*t[2]-e[2]*t[1],e[2]*t[0]-e[0]*t[2],e[0]*t[1]-e[1]*t[0]],distance=(e,t)=>Math.sqrt(e.map(((r,s)=>(e[s]-t[s])**2)).reduce(safeAdd,0)),distance2=(e,t)=>{const r=e[0]-t[0],s=e[1]-t[1];return Math.sqrt(r*r+s*s)},distance3=(e,t)=>{const r=e[0]-t[0],s=e[1]-t[1],a=e[2]-t[2];return Math.sqrt(r*r+s*s+a*a)},flip=e=>e.map((e=>-e)),flip2=e=>[-e[0],-e[1]],flip3=e=>[-e[0],-e[1],-e[2]],rotate90=e=>[-e[1],e[0]],rotate270=e=>[e[1],-e[0]],parallelNormalized=(e,t,r=p)=>1-Math.abs(dot(e,t))<r,parallel=(e,t,r=p)=>parallelNormalized(normalize$2(e),normalize$2(t),r),parallel2=(e,t,r=p)=>Math.abs(cross2(e,t))<r,parallel3=(e,t,r=p)=>magnitude3(cross3(e,t))<r,resize=(e,t)=>t.length===e?t:Array(e).fill(0).map(((e,r)=>t[r]?t[r]:e)),resize2=e=>[e[0]||0,e[1]||0],resize3=e=>[e[0]||0,e[1]||0,e[2]||0],basisVectors2=(e=[1,0])=>{const t=normalize2(e);return[t,rotate90(t)]},basisVectors3=(e=[1,0,0])=>{const t=normalize3(e),r=[[1,0,0],[0,1,0],[0,0,1]].map((e=>cross3(e,t))),s=r.map(magnitude3).map(((e,t)=>({n:e,i:t}))).sort(((e,t)=>t.n-e.n)).map((e=>e.i)).shift(),a=normalize3(r[s]);return[t,a,cross3(t,a)]};var E=Object.freeze({__proto__:null,add:add,add2:add2,add3:add3,average:average,average2:average2,average3:average3,basisVectors:e=>2===e.length?basisVectors2([e[0],e[1]]):basisVectors3([e[0],e[1],e[2]]),basisVectors2:basisVectors2,basisVectors3:basisVectors3,cross2:cross2,cross3:cross3,degenerate:(e,t=p)=>e.map((e=>Math.abs(e))).reduce(safeAdd,0)<t,distance:distance,distance2:distance2,distance3:distance3,dot:dot,dot2:dot2,dot3:dot3,flip:flip,flip2:flip2,flip3:flip3,lerp:lerp,magSquared:magSquared,magSquared2:magSquared2,magnitude:magnitude,magnitude2:magnitude2,magnitude3:magnitude3,midpoint:midpoint,midpoint2:midpoint2,midpoint3:(e,t)=>scale3$1(add3(e,t),.5),normalize:normalize$2,normalize2:normalize2,normalize3:normalize3,parallel:parallel,parallel2:parallel2,parallel3:parallel3,parallelNormalized:parallelNormalized,resize:resize,resize2:resize2,resize3:resize3,resizeUp:(e,t)=>[e,t].map((r=>resize(Math.max(e.length,t.length),r))),rotate270:rotate270,rotate90:rotate90,scale:scale$1,scale2:scale2$1,scale3:scale3$1,scaleNonUniform:scaleNonUniform,scaleNonUniform2:scaleNonUniform2,scaleNonUniform3:scaleNonUniform3,subtract:subtract,subtract2:subtract2,subtract3:subtract3});const vectorToAngle=e=>Math.atan2(e[1],e[0]),angleToVector=e=>[Math.cos(e),Math.sin(e)],pointsToLine2=(e,t)=>({vector:subtract2(t,e),origin:resize2(e)}),pointsToLine3=(e,t)=>({vector:subtract3(t,e),origin:resize3(e)}),pointsToLine=(e,t)=>3===e.length&&3===t.length?pointsToLine3(e,t):pointsToLine2(e,t),vecLineToUniqueLine=({vector:e,origin:t})=>{const r=magnitude(e),s=rotate90([e[0],e[1]]),a=dot(t,s)/r;return{normal:scale2$1(s,1/r),distance:a}},uniqueLineToVecLine=({normal:e,distance:t})=>({vector:rotate270(e),origin:scale2$1(e,t)});var M=Object.freeze({__proto__:null,angleToVector:angleToVector,pointsToLine:pointsToLine,pointsToLine2:pointsToLine2,pointsToLine3:pointsToLine3,uniqueLineToVecLine:uniqueLineToVecLine,vecLineToUniqueLine:vecLineToUniqueLine,vectorToAngle:vectorToAngle});const epsilonEqual=(e,t,r=p)=>Math.abs(e-t)<r,epsilonCompare=(e,t,r=p)=>epsilonEqual(e,t,r)?0:Math.sign(e-t),epsilonEqualVectors=(e,t,r=p)=>{for(let s=0;s<Math.max(e.length,t.length);s+=1)if(!epsilonEqual(e[s]||0,t[s]||0,r))return!1;return!0},include=(e,t=p)=>e>-t,exclude=(e,t=p)=>e>t,includeL=(e,t)=>!0,A=include,x=exclude,includeS=(e,t=p)=>e>-t&&e<1+t,excludeS=(e,t=p)=>e>t&&e<1-t;var O=Object.freeze({__proto__:null,epsilonCompare:epsilonCompare,epsilonEqual:epsilonEqual,epsilonEqualVectors:epsilonEqualVectors,exclude:exclude,excludeL:(e,t)=>!0,excludeR:x,excludeS:excludeS,include:include,includeL:includeL,includeR:A,includeS:includeS});const isCounterClockwiseBetween=(e,t,r)=>{for(;r<t;)r+=b;for(;e>t;)e-=b;for(;e<t;)e+=b;return e<r},clockwiseAngleRadians=(e,t)=>{for(;e<0;)e+=b;for(;t<0;)t+=b;for(;e>b;)e-=b;for(;t>b;)t-=b;const r=e-t;return r>=0?r:b-(t-e)},counterClockwiseAngleRadians=(e,t)=>{for(;e<0;)e+=b;for(;t<0;)t+=b;for(;e>b;)e-=b;for(;t>b;)t-=b;const r=t-e;return r>=0?r:b-(e-t)},clockwiseAngle2=(e,t)=>{const r=t[0]*e[0]+t[1]*e[1],s=t[0]*e[1]-t[1]*e[0];let a=Math.atan2(s,r);return a<0&&(a+=b),a},counterClockwiseAngle2=(e,t)=>{const r=e[0]*t[0]+e[1]*t[1],s=e[0]*t[1]-e[1]*t[0];let a=Math.atan2(s,r);return a<0&&(a+=b),a},clockwiseBisect2=(e,t)=>angleToVector(vectorToAngle(e)-clockwiseAngle2(e,t)/2),clockwiseSubsectRadians=(e,t,r)=>{const s=clockwiseAngleRadians(e,t)/r;return Array.from(Array(r-1)).map(((t,r)=>e+s*(r+1)))},counterClockwiseSubsectRadians=(e,t,r)=>{const s=counterClockwiseAngleRadians(e,t)/r;return Array.from(Array(r-1)).map(((t,r)=>e+s*(r+1)))},counterClockwiseSubsect2=(e,t,r)=>{const s=Math.atan2(e[1],e[0]),a=Math.atan2(t[1],t[0]);return counterClockwiseSubsectRadians(s,a,r).map(angleToVector)},counterClockwiseOrderRadians=e=>{const t=e.map(((e,t)=>t)).sort(((t,r)=>e[t]-e[r]));return t.slice(t.indexOf(0),t.length).concat(t.slice(0,t.indexOf(0)))},counterClockwiseOrder2=e=>counterClockwiseOrderRadians(e.map(vectorToAngle)),counterClockwiseSectorsRadians=e=>counterClockwiseOrderRadians(e).map((t=>e[t])).map(((e,t,r)=>[e,r[(t+1)%r.length]])).map((e=>counterClockwiseAngleRadians(e[0],e[1]))),counterClockwiseSectors2=e=>counterClockwiseSectorsRadians(e.map(vectorToAngle)),threePointTurnDirection=(e,t,r,s=p)=>{const a=normalize2(subtract2(t,e)),o=normalize2(subtract2(r,e)),c=cross2(a,o);return epsilonEqual(c,0,s)?epsilonEqual(distance2(e,t)+distance2(t,r),distance2(e,r))?0:void 0:Math.sign(c)};var j=Object.freeze({__proto__:null,clockwiseAngle2:clockwiseAngle2,clockwiseAngleRadians:clockwiseAngleRadians,clockwiseBisect2:clockwiseBisect2,clockwiseSubsect2:(e,t,r)=>{const s=Math.atan2(e[1],e[0]),a=Math.atan2(t[1],t[0]);return clockwiseSubsectRadians(s,a,r).map(angleToVector)},clockwiseSubsectRadians:clockwiseSubsectRadians,counterClockwiseAngle2:counterClockwiseAngle2,counterClockwiseAngleRadians:counterClockwiseAngleRadians,counterClockwiseBisect2:(e,t)=>angleToVector(vectorToAngle(e)+counterClockwiseAngle2(e,t)/2),counterClockwiseOrder2:counterClockwiseOrder2,counterClockwiseOrderRadians:counterClockwiseOrderRadians,counterClockwiseSectors2:counterClockwiseSectors2,counterClockwiseSectorsRadians:counterClockwiseSectorsRadians,counterClockwiseSubsect2:counterClockwiseSubsect2,counterClockwiseSubsectRadians:counterClockwiseSubsectRadians,isCounterClockwiseBetween:isCounterClockwiseBetween,threePointTurnDirection:threePointTurnDirection});const clampLine=e=>e,clampSegment=e=>e<-p?0:e>1.000001?1:e,collinearPoints=(e,t,r,s=p)=>{const a=[[e,t],[t,r]].map((e=>subtract(e[1],e[0]))).map((e=>normalize$2(e)));return epsilonEqual(1,Math.abs(dot(a[0],a[1])),s)},collinearBetween=(e,t,r,s=!1,a=p)=>{if([e,r].map((e=>epsilonEqualVectors(t,e,a))).reduce(((e,t)=>e||t),!1))return s;const o=[[e,t],[t,r]].map((e=>subtract(e[1],e[0]))).map((e=>normalize$2(e)));return epsilonEqual(1,dot(o[0],o[1]),p)},collinearLines3=(e,t,r=p)=>parallel3(e.vector,t.vector,r)&&parallel3(e.vector,subtract3(t.origin,e.origin),r),pleat$2=(e,t,r,s=p)=>{const a=cross2(e.vector,t.vector),o=cross2(subtract2(t.origin,e.origin),t.vector)/a,[c,n]=[e.vector,t.vector].map(normalize2);if(Math.abs(cross2(c,n))<s)return((e,t,r)=>{const s=dot(e.vector,t.vector)<0,a=e.vector,o=s?flip(t.vector):t.vector,c=Array.from(Array(r-1)).map(((s,a)=>lerp(e.origin,t.origin,(a+1)/r))),n=Array.from(Array(r-1)).map(((e,t)=>lerp(a,o,(t+1)/r))).map(((e,t)=>({vector:[e[0],e[1]],origin:[c[t][0],c[t][1]]}))),i=[n,n];return i[s?0:1]=[],i})(e,t,r);const i=a>-s?[[e.vector,t.vector],[flip2(t.vector),e.vector]]:[[t.vector,e.vector],[flip2(e.vector),t.vector]],l=[counterClockwiseSubsect2(i[0][0],i[0][1],r),counterClockwiseSubsect2(i[1][0],i[1][1],r)],d=add2(e.origin,scale2$1(e.vector,o)),_=Array.from(Array(r-1)).map((()=>d)),[m,g]=l.map((e=>e.map(((e,t)=>({vector:e,origin:_[t]})))));return[m,g]},bisectLines2=(e,t,r=p)=>{const[s,a]=pleat$2(e,t,2,r).map((e=>e[0])),o=[s,a];return o.forEach(((e,t)=>{void 0===e&&delete o[t]})),o};var w=Object.freeze({__proto__:null,bisectLines2:bisectLines2,clampLine:clampLine,clampRay:e=>e<-p?0:e,clampSegment:clampSegment,collinearBetween:collinearBetween,collinearLines2:(e,t,r=p)=>parallel2(e.vector,t.vector,r)&&parallel2(e.vector,subtract2(t.origin,e.origin),r),collinearLines3:collinearLines3,collinearPoints:collinearPoints,pleat:pleat$2});const rangeUnion=(e,t)=>{const r=t[0]<=t[1];return e[0]<=e[1]?[Math.min(e[0],r?t[0]:t[1]),Math.max(e[1],r?t[1]:t[0])]:[Math.min(e[1],r?t[0]:t[1]),Math.max(e[0],r?t[1]:t[0])]},doRangesOverlap=(e,t,r=p)=>{const s=e[0]<e[1]?e:[e[1],e[0]],a=t[0]<t[1]?t:[t[1],t[0]];return Math.min(s[1],a[1])-Math.max(s[0],a[0])>r};var F=Object.freeze({__proto__:null,doRangesOverlap:doRangesOverlap,rangeUnion:rangeUnion});const clusterSortedGeneric=(e,t)=>{if(!e.length)return[];const r=e.map(((e,t)=>t)),s=[[r.shift()]];return r.forEach((r=>{const a=s[s.length-1],o=a[a.length-1];t(e[o],e[r])?a.push(r):s.push([r])})),s},clusterUnsortedIndices=(e,t)=>{if(!e.length)return[];const r=e.slice(),s=[[r.shift()]];return r.forEach((e=>{const r=s.map(((r,s)=>t(r[0],e)?s:void 0)).filter((e=>void 0!==e)).shift();void 0!==r?s[r].push(e):s.push([e])})),s},clusterScalars=(e,t=p)=>{const r=e.map(((e,t)=>({v:e,i:t}))).sort(((e,t)=>e.v-t.v)).map((e=>e.i)).filter((()=>!0)),s=r.map((t=>e[t]));return clusterSortedGeneric(s,((e,r)=>Math.abs(e-r)<t)).map((e=>e.map((e=>r[e]))))},clusterParallelVectors=(e,t=p)=>{const r=e.map(normalize$2),s=[[0]];e:for(let e=1;e<r.length;e+=1){for(let a=0;a<s.length;a+=1)if(parallelNormalized(r[e],r[s[a][0]],t)){s[a].push(e);continue e}s.push([e])}return s};var S=Object.freeze({__proto__:null,clusterParallelVectors:clusterParallelVectors,clusterRanges:(e,t=p)=>{const r=e.map((([e,t],r)=>({v:Math.min(e,t),i:r}))).sort(((e,t)=>e.v-t.v)).map((e=>e.i)).filter((()=>!0)),s=r.map((t=>e[t]));let a=[...s[0]];return clusterSortedGeneric(s,((e,r)=>{const s=doRangesOverlap(a,r,t);return a=s?rangeUnion(a,r):[...r],s})).map((e=>e.map((e=>r[e]))))},clusterScalars:clusterScalars,clusterSortedGeneric:clusterSortedGeneric,clusterUnsortedIndices:clusterUnsortedIndices});const intersectLineLine=(e,t,r=includeL,s=includeL,a=p)=>{const o=cross2(normalize2(e.vector),normalize2(t.vector));if(Math.abs(o)<a)return{a:void 0,b:void 0,point:void 0};const c=cross2(e.vector,t.vector),n=-c,i=[t.origin[0]-e.origin[0],t.origin[1]-e.origin[1]],l=[-i[0],-i[1]],d=cross2(i,t.vector)/c,_=cross2(l,e.vector)/n;return r(d,a/magnitude2(e.vector))&&s(_,a/magnitude2(t.vector))?{a:d,b:_,point:add2(e.origin,scale2$1(e.vector,d))}:{a:void 0,b:void 0,point:void 0}},intersectCircleLine=(e,t,r=include,s=includeL,a=p)=>{const o=t.vector[0]**2+t.vector[1]**2,c=Math.sqrt(o),n=0===c?t.vector:scale2$1(t.vector,1/c),i=rotate90(n),l=subtract2(t.origin,e.origin),d=cross2(l,n);if(Math.abs(d)>e.radius+a)return;const _=Math.sqrt(e.radius**2-d**2),f=(t,r)=>e.origin[r]-i[r]*d+n[r]*t,m=Math.abs(e.radius-Math.abs(d))<a?[_].map((e=>[f(e,0),f(e,1)])):[-_,_].map((e=>[f(e,0),f(e,1)])),g=m.map((e=>e.map(((e,r)=>e-t.origin[r])))).map((e=>e[0]*t.vector[0]+t.vector[1]*e[1])).map((e=>e/o));return m.filter(((e,t)=>s(g[t],a)))},intersectPolygonLine=(e,t,r=includeL,s=p)=>{const a=e.map(((e,t,r)=>({vector:subtract2(r[(t+1)%r.length],e),origin:resize2(e)}))).map((e=>intersectLineLine(t,e,r,includeS,s))).filter((({point:e})=>void 0!==e)).sort(((e,t)=>e.a-t.a)).map((({a:e,point:t})=>({a:e,point:t})));return clusterSortedGeneric(a,((e,t)=>epsilonEqual(e.a,t.a,s))).map((([e])=>a[e]))};var C=Object.freeze({__proto__:null,intersectCircleLine:intersectCircleLine,intersectLineLine:intersectLineLine,intersectPolygonLine:intersectPolygonLine});const cubeRootSigned=e=>e<0?-((-e)**(1/3)):e**(1/3),normalAxiom1=(e,t)=>{const r=normalize2(rotate90(subtract2(t,e)));return[{normal:r,distance:dot2(add2(e,t),r)/2}]},axiom1=(e,t)=>[{vector:normalize2(subtract2(t,e)),origin:e}],normalAxiom2=(e,t)=>{const r=normalize2(subtract2(t,e));return[{normal:r,distance:dot2(add2(e,t),r)/2}]},axiom2=(e,t)=>[{vector:normalize2(rotate90(subtract2(t,e))),origin:midpoint2(e,t)}],normalAxiom3=(e,t)=>{const r=cross2(e.normal,t.normal);if(Math.abs(r)<p)return[{normal:e.normal,distance:(e.distance+t.distance*dot2(e.normal,t.normal))/2}];const s=[(e.distance*t.normal[1]-t.distance*e.normal[1])/r,(t.distance*e.normal[0]-e.distance*t.normal[0])/r],[a,o]=[add2,subtract2].map((r=>normalize2(r(e.normal,t.normal)))).map((e=>({normal:e,distance:dot2(s,e)})));return[a,o]},axiom3=(e,t)=>bisectLines2(e,t),normalAxiom4=(e,t)=>{const r=rotate90(e.normal);return[{normal:r,distance:dot2(t,r)}]},axiom4=({vector:e},t)=>[{vector:rotate90(normalize2(e)),origin:t}],normalAxiom5=(e,t,r)=>{const s=dot2(t,e.normal),a=e.distance-s,o=distance2(t,r);if(a>o)return[];const c=Math.sqrt(o*o-a*a),n=scale2$1(e.normal,a),i=add2(t,n),l=scale2$1(rotate90(e.normal),c),d=c<p?[i]:[add2(i,l),subtract2(i,l)],[_,m]=d.map((e=>normalize2(subtract2(r,e)))).map((e=>({normal:e,distance:dot2(t,e)})));return[_,m]},axiom5=(e,t,r)=>(intersectCircleLine({radius:distance2(t,r),origin:t},e)||[]).map((e=>({vector:normalize2(rotate90(subtract2(e,r))),origin:midpoint2(r,e)}))),normalAxiom6=(e,t,r,s)=>{if(Math.abs(1-dot2(e.normal,r)/e.distance)<.02)return[];const a=rotate90(e.normal),o=subtract2(add2(r,scale2$1(e.normal,e.distance)),scale2$1(s,2)),c=subtract2(scale2$1(e.normal,e.distance),r),n=dot2(s,t.normal)-t.distance,i=2*dot2(c,a),l=dot2(c,c),d=dot2(add2(o,c),a),_=dot2(o,c),m=dot2(a,t.normal),g=dot2(c,t.normal),v=m,u=n+d*m+g,h=n*i+_*m+d*g,b=n*l+_*g;let y=[];return Math.abs(v)>p?y=[b,h,u,v]:Math.abs(u)>p?y=[b,h,u]:Math.abs(h)>p&&(y=[b,h]),(e=>{const[t,r,s,a]=e;switch(e.length){case 2:return[-t/r];case 3:{const e=r**2-4*t*s;if(e<-p)return[];const a=-r/(2*s);if(e<p)return[a];const o=Math.sqrt(e)/(2*s);return[a+o,a-o]}case 4:{const e=s/a,o=r/a,c=(9*e*o-t/a*27-2*e**3)/54,n=((3*o-e**2)/9)**3+c**2,i=-e/3;if(n>0){const e=Math.sqrt(n);return[i+cubeRootSigned(c+e)+cubeRootSigned(c-e)]}if(Math.abs(n)<p){if(c<0)return[];const e=c**(1/3);return[i+2*e,i-e]}const l=Math.sqrt(-n),d=Math.atan2(l,c)/3,_=(c**2-n)**(1/6),m=_*Math.cos(d),g=_*Math.sin(d);return[i+2*m,i-m-Math.sqrt(3)*g,i-m+Math.sqrt(3)*g]}default:return[]}})(y).map((t=>add2(scale2$1(e.normal,e.distance),scale2$1(a,t)))).map((e=>({p:e,normal:normalize2(subtract2(e,r))}))).map((e=>({normal:e.normal,distance:dot2(e.normal,midpoint2(e.p,r))})))},axiom6=(e,t,r,s)=>normalAxiom6(vecLineToUniqueLine(e),vecLineToUniqueLine(t),r,s).map(uniqueLineToVecLine),normalAxiom7=(e,t,r)=>{const s=rotate90(e.normal),a=dot2(s,t.normal);if(Math.abs(a)<p)return;const o=dot2(r,s),c=dot2(r,t.normal);return[{normal:s,distance:(t.distance+2*o*a-c)/(2*a)}]},axiom7=(e,t,r)=>{const s=intersectLineLine(e,{vector:t.vector,origin:r},includeL,includeL).point;return void 0===s?[]:[{vector:normalize2(rotate90(subtract2(s,r))),origin:midpoint2(r,s)}]};var V=Object.freeze({__proto__:null,axiom1:axiom1,axiom2:axiom2,axiom3:axiom3,axiom4:axiom4,axiom5:axiom5,axiom6:axiom6,axiom7:axiom7,normalAxiom1:normalAxiom1,normalAxiom2:normalAxiom2,normalAxiom3:normalAxiom3,normalAxiom4:normalAxiom4,normalAxiom5:normalAxiom5,normalAxiom6:normalAxiom6,normalAxiom7:normalAxiom7});const z=[1,0,0,1],T=z.concat(0,0),multiplyMatrix2Vector2=(e,t)=>[e[0]*t[0]+e[2]*t[1]+e[4],e[1]*t[0]+e[3]*t[1]+e[5]],multiplyMatrix2Line2=(e,{vector:t,origin:r})=>({vector:[e[0]*t[0]+e[2]*t[1],e[1]*t[0]+e[3]*t[1]],origin:[e[0]*r[0]+e[2]*r[1]+e[4],e[1]*r[0]+e[3]*r[1]+e[5]]}),multiplyMatrices2=(e,t)=>[e[0]*t[0]+e[2]*t[1],e[1]*t[0]+e[3]*t[1],e[0]*t[2]+e[2]*t[3],e[1]*t[2]+e[3]*t[3],e[0]*t[4]+e[2]*t[5]+e[4],e[1]*t[4]+e[3]*t[5]+e[5]],determinant2=e=>e[0]*e[3]-e[1]*e[2],invertMatrix2=e=>{const t=determinant2(e);if(!(Math.abs(t)<1e-12||Number.isNaN(t))&&Number.isFinite(e[4])&&Number.isFinite(e[5]))return[e[3]/t,-e[1]/t,-e[2]/t,e[0]/t,(e[2]*e[5]-e[3]*e[4])/t,(e[1]*e[4]-e[0]*e[5])/t]},makeMatrix2Scale=(e=[1,1],t=[0,0])=>[e[0],0,0,e[1],e[0]*-t[0]+t[0],e[1]*-t[1]+t[1]],makeMatrix2Reflect=(e,t=[0,0])=>{const r=Math.atan2(e[1],e[0]),s=Math.cos(r),a=Math.sin(r),o=Math.cos(-r),c=Math.sin(-r),n=s*o+a*c,i=s*-c+a*o,l=a*o+-s*c,d=a*-c+-s*o;return[n,i,l,d,t[0]+n*-t[0]+-t[1]*l,t[1]+i*-t[0]+-t[1]*d]};var P=Object.freeze({__proto__:null,determinant2:determinant2,identity2x2:z,identity2x3:T,invertMatrix2:invertMatrix2,makeMatrix2Reflect:makeMatrix2Reflect,makeMatrix2Rotate:(e,t=[0,0])=>{const r=Math.cos(e),s=Math.sin(e);return[r,s,-s,r,t[0],t[1]]},makeMatrix2Scale:makeMatrix2Scale,makeMatrix2Translate:(e=0,t=0)=>z.concat(e,t),makeMatrix2UniformScale:(e=1,t=[0,0])=>makeMatrix2Scale([e,e],t),multiplyMatrices2:multiplyMatrices2,multiplyMatrix2Line2:multiplyMatrix2Line2,multiplyMatrix2Vector2:multiplyMatrix2Vector2});const overlapLinePoint=({vector:e,origin:t},r,s=includeL,a=p)=>{const o=subtract2(r,t),c=magSquared(e),n=Math.sqrt(c);if(n<a)return!1;const i=[e[0]/n,e[1]/n],l=cross2(o,i),d=dot2(o,e)/c;return Math.abs(l)<a&&s(d,a/n)},overlapConvexPolygonPoint=(e,t,r=exclude,s=p)=>{const a=e.map(((e,t,r)=>[e,r[(t+1)%r.length]])).map((([e,r])=>[subtract2(r,e),subtract2(t,e)])).map((([e,t])=>cross2(e,t))),o=Math.sign(a.reduce(((e,t)=>e+t),0));return{overlap:a.map((e=>e*o)).map((e=>r(e,s))).map(((e,t,r)=>e===r[0])).reduce(((e,t)=>e&&t),!0),t:a}},overlapConvexPolygons=(e,t,r=p)=>{for(let s=0;s<2;s+=1){const a=0===s?e:t,o=0===s?t:e;for(let e=0;e<a.length;e+=1){const t=a[e],s=rotate90(subtract2(a[(e+1)%a.length],a[e])),c=o.map((e=>subtract2(e,t))).map((e=>dot2(s,e))),n=a[(e+2)%a.length],i=dot2(s,subtract2(n,t))>0;if(c.map((e=>i?e<r:e>-r)).reduce(((e,t)=>e&&t),!0))return!1}}return!0},overlapBoundingBoxes=(e,t,r=p)=>{const s=Math.min(e.min.length,t.min.length);for(let a=0;a<s;a+=1)if(e.min[a]>t.max[a]+r||e.max[a]<t.min[a]-r)return!1;return!0};var $=Object.freeze({__proto__:null,overlapBoundingBoxes:overlapBoundingBoxes,overlapConvexPolygonPoint:overlapConvexPolygonPoint,overlapConvexPolygons:overlapConvexPolygons,overlapLinePoint:overlapLinePoint});const clipLineConvexPolygon=(e,{vector:t,origin:r},s=include,a=includeL,o=p)=>{const c=intersectPolygonLine(e,{vector:t,origin:r},includeL,o).map((({a:e})=>e));if(c.length<2)return;const n=((e,t,r)=>{if(e.length<2)return;let s=0,a=e.length-1;for(;s<a&&!t(e[s+1]-e[s],r);)s+=1;for(;a>s&&!t(e[a]-e[a-1],r);)a-=1;return s>=a?void 0:[e[s],e[a]]})(c,s,2*o/magnitude2(t));if(void 0===n)return;const i=n.map((e=>a(e)?e:e<.5?0:1));if(Math.abs(i[0]-i[1])<2*o/magnitude2(t))return;const l=add2(r,scale2$1(t,(i[0]+i[1])/2));return overlapConvexPolygonPoint(e,l,s,o).overlap?i.map((e=>add2(r,scale2$1(t,e)))):void 0},clipPolygonPolygon=(e,t,r=p)=>{const inside=(e,t,s)=>(s[0]-t[0])*(e[1]-t[1])>(s[1]-t[1])*(e[0]-t[0])+r,intersection=(e,t,r,s)=>{const a=subtract2(e,t),o=subtract2(s,r),c=cross2(e,t),n=cross2(s,r),i=1/cross2(a,o);return scale2$1(subtract2(scale2$1(o,c),scale2$1(a,n)),i)};let s=e,a=t[t.length-1];for(let e=0;e<t.length;e+=1){const r=t[e],o=s;s=[];let c=o[o.length-1];for(let e=0;e<o.length;e+=1){const t=o[e];inside(t,a,r)?(inside(c,a,r)||s.push(intersection(a,r,t,c)),s.push(t)):inside(c,a,r)&&s.push(intersection(a,r,t,c)),c=t}a=r}return 0===s.length?void 0:s};var B=Object.freeze({__proto__:null,clipLineConvexPolygon:clipLineConvexPolygon,clipPolygonPolygon:clipPolygonPolygon});const reflectPoint=(e,t)=>{const r=makeMatrix2Reflect(e.vector,e.origin);return multiplyMatrix2Vector2(r,t)},validateAxiom1And2=(e,t,r)=>[[t,r].map((t=>overlapConvexPolygonPoint(e,t,include).overlap)).reduce(((e,t)=>e&&t),!0)],validateAxiom3=(e,t,r,s)=>{const a=[r,s].map((t=>clipLineConvexPolygon(e,t,include,includeL)));if(void 0===a[0]||void 0===a[1])return[!1,!1];const o=t.map((t=>void 0===t?void 0:clipLineConvexPolygon(e,t,include,includeL))),c=[0,1].map((e=>void 0!==o[e])),n=t.map((e=>void 0===e?void 0:[reflectPoint(e,a[0][0]),reflectPoint(e,a[0][1])])),i=n.map((e=>void 0!==e&&(overlapLinePoint({vector:subtract2(a[1][1],a[1][0]),origin:a[1][0]},e[0],includeS)||overlapLinePoint({vector:subtract2(a[1][1],a[1][0]),origin:a[1][0]},e[1],includeS)||overlapLinePoint({vector:subtract2(e[1],e[0]),origin:e[0]},a[1][0],includeS)||overlapLinePoint({vector:subtract2(e[1],e[0]),origin:e[0]},a[1][1],includeS))));return[0,1].map((e=>!0===i[e]&&!0===c[e]))},validateAxiom4=(e,t,r,s)=>{const a={vector:rotate90(r.vector),origin:s},o=intersectLineLine(r,a).point;return o?[[s,o].map((t=>overlapConvexPolygonPoint(e,t,include).overlap)).reduce(((e,t)=>e&&t),!0)]:[!1]},validateAxiom5=(e,t,r,s,a)=>{if(0===t.length)return[];const o=[s,a].map((t=>overlapConvexPolygonPoint(e,t,include).overlap)).reduce(((e,t)=>e&&t),!0),c=t.map((e=>reflectPoint(e,a))).map((t=>overlapConvexPolygonPoint(e,t,include).overlap));return c.map((e=>e&&o))},validateAxiom6=function(e,t,r,s,a,o){if(0===t.length)return[];if(![a,o].map((t=>overlapConvexPolygonPoint(e,t,include).overlap)).reduce(((e,t)=>e&&t),!0))return t.map((()=>!1));const c=t.map((e=>reflectPoint(e,a))).map((t=>overlapConvexPolygonPoint(e,t,include).overlap)),n=t.map((e=>reflectPoint(e,o))).map((t=>overlapConvexPolygonPoint(e,t,include).overlap));return t.map(((e,t)=>c[t]&&n[t]))},validateAxiom7=(e,t,r,s,a)=>{const o=overlapConvexPolygonPoint(e,a,include).overlap;if(!t.length)return[!1];const c=reflectPoint(t[0],a),n=overlapConvexPolygonPoint(e,c,include).overlap,i=intersectPolygonLine(e,s,includeL).length>=2,l=intersectLineLine(s,t[0],includeL,includeL).point,d=!!l&&overlapConvexPolygonPoint(e,l,include).overlap;return[o&&n&&i&&d]};var N=Object.freeze({__proto__:null,validateAxiom1And2:validateAxiom1And2,validateAxiom3:validateAxiom3,validateAxiom4:validateAxiom4,validateAxiom5:validateAxiom5,validateAxiom6:validateAxiom6,validateAxiom7:validateAxiom7});var R=Object.freeze({__proto__:null,axiom1InPolygon:(e,t,r)=>{const s=validateAxiom1And2(e,t,r);return axiom1(t,r).filter(((e,t)=>s[t]))},axiom2InPolygon:(e,t,r)=>{const s=validateAxiom1And2(e,t,r);return axiom2(t,r).filter(((e,t)=>s[t]))},axiom3InPolygon:(e,t,r)=>{const s=axiom3(t,r),a=validateAxiom3(e,s,t,r);return s.filter(((e,t)=>a[t]))},axiom4InPolygon:(e,t,r)=>{const s=axiom4(t,r),a=validateAxiom4(e,0,t,r);return s.filter(((e,t)=>a[t]))},axiom5InPolygon:(e,t,r,s)=>{const a=axiom5(t,r,s),o=validateAxiom5(e,a,0,r,s);return a.filter(((e,t)=>o[t]))},axiom6InPolygon:(e,t,r,s,a)=>{const o=axiom6(t,r,s,a),c=validateAxiom6(e,o,0,0,s,a);return o.filter(((e,t)=>c[t]))},axiom7InPolygon:(e,t,r,s)=>{const a=axiom7(t,r,s),o=validateAxiom7(e,a,0,r,s);return a.filter(((e,t)=>o[t]))},normalAxiom1InPolygon:(e,t,r)=>{const s=validateAxiom1And2(e,t,r);return normalAxiom1(t,r).filter(((e,t)=>s[t]))},normalAxiom2InPolygon:(e,t,r)=>{const s=validateAxiom1And2(e,t,r);return normalAxiom2(t,r).filter(((e,t)=>s[t]))},normalAxiom3InPolygon:(e,t,r)=>{const s=normalAxiom3(t,r),a=validateAxiom3(e,s.map(uniqueLineToVecLine),uniqueLineToVecLine(t),uniqueLineToVecLine(r));return s.filter(((e,t)=>a[t]))},normalAxiom4InPolygon:(e,t,r)=>{const s=normalAxiom4(t,r),a=validateAxiom4(e,s.map(uniqueLineToVecLine),uniqueLineToVecLine(t),r);return s.filter(((e,t)=>a[t]))},normalAxiom5InPolygon:(e,t,r,s)=>{const a=normalAxiom5(t,r,s),o=validateAxiom5(e,a.map(uniqueLineToVecLine),uniqueLineToVecLine(t),r,s);return a.filter(((e,t)=>o[t]))},normalAxiom6InPolygon:(e,t,r,s,a)=>{const o=normalAxiom6(t,r,s,a),c=validateAxiom6(e,o.map(uniqueLineToVecLine),uniqueLineToVecLine(t),uniqueLineToVecLine(r),s,a);return o.filter(((e,t)=>c[t]))},normalAxiom7InPolygon:(e,t,r,s)=>{const a=normalAxiom7(t,r,s),o=validateAxiom7(e,a.map(uniqueLineToVecLine),uniqueLineToVecLine(t),uniqueLineToVecLine(r),s);return a.filter(((e,t)=>o[t]))}}),L={...V,...R,...N};const I="Rabbit Ear",makePairsMap=(e,t)=>{const r={};return(t||e.map(((e,t)=>t))).forEach((t=>e[t].map(((e,t,r)=>[0,1].map((e=>(t+e)%r.length)).map((e=>r[e])).join(" "))).forEach((e=>{r[e]=t})))),r},makeVerticesToEdge=({edges_vertices:e},t)=>makePairsMap(e,t),makeVerticesToFace=({faces_vertices:e},t)=>makePairsMap(e,t),makeEdgesToFace=({faces_edges:e},t)=>makePairsMap(e,t);var U=Object.freeze({__proto__:null,makeEdgesToFace:makeEdgesToFace,makeVerticesToEdge:makeVerticesToEdge,makeVerticesToFace:makeVerticesToFace});const makeVerticesEdgesUnsorted=({edges_vertices:e})=>{const t=[];return e.forEach(((e,r)=>e.forEach((e=>{void 0===t[e]&&(t[e]=[]),t[e].push(r)})))),t},makeVerticesEdges=({edges_vertices:e,vertices_vertices:t})=>{const r=makeVerticesToEdge({edges_vertices:e});return t.map(((e,t)=>e.map((e=>r[`${t} ${e}`]))))};var D=Object.freeze({__proto__:null,makeVerticesEdges:makeVerticesEdges,makeVerticesEdgesUnsorted:makeVerticesEdgesUnsorted});const uniqueElements=e=>Array.from(new Set(e)),uniqueSortedNumbers=e=>{const t={};return e.forEach((e=>{t[e]=!0})),Object.keys(t).map(parseFloat)},epsilonUniqueSortedNumbers=(e,t=p)=>{const r=e.slice().sort(((e,t)=>e-t));if(r.length<2)return r;const s=[!0];for(let e=1;e<r.length;e+=1)s[e]=!epsilonEqual(r[e],r[e-1],t);return r.filter(((e,t)=>s[t]))},rotateCircularArray=(e,t)=>t<=0?e:e.slice(t).concat(e.slice(0,t)),splitCircularArray$1=(e,t)=>(t.sort(((e,t)=>e-t)),[e.slice(t[1]).concat(e.slice(0,t[0]+1)),e.slice(t[0],t[1]+1)]),chooseTwoPairs=e=>{const t=Array(e.length*(e.length-1)/2);let r=0;for(let s=0;s<e.length-1;s+=1)for(let a=s+1;a<e.length;a+=1,r+=1)t[r]=[e[s],e[a]];return t},setDifferenceSortedEpsilonNumbers=(e,t,r=p)=>{const s=[];let a=0,o=0;for(;a<e.length&&o<t.length;)epsilonEqual(e[a],t[o],r)?a+=1:e[a]>t[o]?o+=1:t[o]>e[a]&&(s.push(e[a]),a+=1);return s},arrayMinimumIndex=(e,t)=>{if(!e.length)return;const r="function"==typeof t?e.map((e=>t(e))):e;let s=0;return r.forEach(((e,t,r)=>{e<r[s]&&(s=t)})),s},arrayMaximumIndex=(e,t)=>{if(!e.length)return;const r="function"==typeof t?e.map((e=>t(e))):e;let s=0;return r.forEach(((e,t,r)=>{e>r[s]&&(s=t)})),s},mergeArraysWithHoles=(...e)=>{const t=[];return e.forEach((e=>e.forEach(((e,r)=>{t[r]=e})))),t},clustersToReflexiveArrays=e=>{const t=[];return e.flat().forEach((e=>{t[e]=[]})),e.flatMap(chooseTwoPairs).forEach((([e,r])=>{t[e].push(r),t[r].push(e)})),t},arrayArrayToLookupArray=e=>e.map((e=>{const t=[];return e.forEach((e=>{t[e]=!0})),t}));var Q=Object.freeze({__proto__:null,arrayArrayToLookupArray:arrayArrayToLookupArray,arrayIntersection:(e,t)=>{const r={};return t.forEach((e=>{r[e]=0})),t.forEach((e=>{r[e]+=1})),e.filter((e=>r[e]>0&&(r[e]-=1,!0)))},arrayMaximumIndex:arrayMaximumIndex,arrayMinimumIndex:arrayMinimumIndex,chooseTwoPairs:chooseTwoPairs,clustersToReflexiveArrays:clustersToReflexiveArrays,epsilonUniqueSortedNumbers:epsilonUniqueSortedNumbers,lookupArrayToArrayArray:e=>e.map((e=>e.map(((e,t)=>e?t:void 0)).filter((e=>void 0!==e)))),mergeArraysWithHoles:mergeArraysWithHoles,nonUniqueElements:e=>{const t={};return e.forEach((e=>{void 0===t[e]&&(t[e]=0),t[e]+=1})),e.filter((e=>t[e]>1))},rotateCircularArray:rotateCircularArray,setDifferenceSortedEpsilonNumbers:setDifferenceSortedEpsilonNumbers,setDifferenceSortedNumbers:(e,t)=>{const r=[];let s=0,a=0;for(;s<e.length&&a<t.length;)e[s]===t[a]?s+=1:e[s]>t[a]?a+=1:t[a]>e[s]&&(r.push(e[s]),s+=1);return r},splitCircularArray:splitCircularArray$1,uniqueElements:uniqueElements,uniqueSortedNumbers:uniqueSortedNumbers});const edgeifyFaces=({vertices_coords:e,faces_vertices:t},r=0)=>t.map((t=>[t.reduce(((t,s)=>e[t][r]<e[s][r]?t:s)),t.reduce(((t,s)=>e[t][r]>e[s][r]?t:s))])),sweepValues=({edges_vertices:e,vertices_edges:t},r,s=p)=>{t||(t=makeVerticesEdgesUnsorted({edges_vertices:e}));const a=e.map((e=>e.map((e=>r[e])))),o=a.map((([e,t])=>epsilonEqual(e,t,s))),c=a.map((([e,t])=>Math.sign(e-t))),n=e.map((([e,t],r)=>o[r]?{[e]:0,[t]:0}:{[e]:c[r],[t]:-c[r]}));return clusterScalars(r,s).map((e=>e.filter((e=>t[e])))).filter((e=>e.length)).map((e=>({vertices:e,t:e.reduce(((e,t)=>e+r[t]),0)/e.length,start:uniqueElements(e.flatMap((e=>t[e].filter((t=>n[t][e]<=0))))),end:uniqueElements(e.flatMap((e=>t[e].filter((t=>n[t][e]>=0)))))})))},sweepEdges=({vertices_coords:e,edges_vertices:t,vertices_edges:r},s=0,a=p)=>sweepValues({edges_vertices:t,vertices_edges:r},e.map((e=>e[s])),a),sweepFaces=({vertices_coords:e,faces_vertices:t},r=0,s=p)=>sweepValues({edges_vertices:edgeifyFaces({vertices_coords:e,faces_vertices:t},r)},e.map((e=>e[r])),s);var W=Object.freeze({__proto__:null,sweep:({vertices_coords:e,edges_vertices:t,faces_vertices:r},s=0,a=p)=>{const o=e.map((e=>e[s])),c=edgeifyFaces({vertices_coords:e,faces_vertices:r},s),n=makeVerticesEdgesUnsorted({edges_vertices:t}),i=makeVerticesEdgesUnsorted({edges_vertices:c}),l=t.map((e=>e.map((e=>o[e])))),d=c.map((e=>e.map((e=>o[e])))),_=l.map((([e,t])=>epsilonEqual(e,t,a))),m=d.map((([e,t])=>epsilonEqual(e,t,a))),g=l.map((([e,t])=>Math.sign(e-t))),v=d.map((([e,t])=>Math.sign(e-t))),u=t.map((([e,t],r)=>_[r]?{[e]:0,[t]:0}:{[e]:g[r],[t]:-g[r]})),h=r.map((([e,t],r)=>m[r]?{[e]:0,[t]:0}:{[e]:v[r],[t]:-v[r]}));return clusterScalars(o,a).map((e=>({vertices:e,t:e.reduce(((e,t)=>e+o[t]),0)/e.length,edges:{start:uniqueElements(e.filter((e=>void 0!==n[e])).flatMap((e=>n[e].filter((t=>u[t][e]<=0))))),end:uniqueElements(e.filter((e=>void 0!==n[e])).flatMap((e=>n[e].filter((t=>u[t][e]>=0)))))},faces:{start:uniqueElements(e.filter((e=>void 0!==i[e])).flatMap((e=>i[e].filter((t=>h[t][e]<=0))))),end:uniqueElements(e.filter((e=>void 0!==i[e])).flatMap((e=>i[e].filter((t=>h[t][e]>=0)))))}})))},sweepEdges:sweepEdges,sweepFaces:sweepFaces,sweepValues:sweepValues,sweepVertices:({vertices_coords:e},t=0,r=p)=>clusterScalars(e.map((e=>e[t])),r).map((r=>({vertices:r,t:r.reduce(((r,s)=>r+e[s][t]),0)/r.length})))});const doEdgesOverlap=({vertices_coords:e,edges_vertices:t},r=p)=>{const s=(({vertices_coords:e,edges_vertices:t},r=0)=>t.map((t=>t.map((t=>e[t])))).map((([e,t])=>[Math.min(e[1],t[1])-r,Math.max(e[1],t[1])+r])).map((e=>epsilonEqual(e[0],e[1],Math.abs(2.5*r))?void 0:e)))({vertices_coords:e,edges_vertices:t},-r),a=e.map(resize2),o=t.map((e=>[a[e[0]],a[e[1]]])).map((([e,t])=>pointsToLine2(e,t))),c=[],n=sweepEdges({vertices_coords:e,edges_vertices:t});try{n.forEach((({start:e,end:t})=>{e.forEach((e=>{c[e]=!0})),Object.keys(c).map((e=>parseInt(e,10))).forEach((t=>e.forEach((e=>{if(t!==e&&(!s[t]||!s[e]||doRangesOverlap(s[t],s[e]))&&intersectLineLine(o[t],o[e],excludeS,excludeS,r).point)throw new Error})))),t.forEach((e=>{delete c[e]}))}))}catch(e){return!0}return!1};var q=Object.freeze({__proto__:null,doEdgesOverlap:doEdgesOverlap});const G={file:["file_spec","file_creator","file_author","file_title","file_description","file_classes","file_frames"],frame:["frame_author","frame_title","frame_description","frame_attributes","frame_classes","frame_unit","frame_parent","frame_inherit"],graph:["vertices_coords","vertices_vertices","vertices_edges","vertices_faces","edges_vertices","edges_faces","edges_assignment","edges_foldAngle","edges_length","faces_vertices","faces_edges","faces_faces"],orders:["edgeOrders","faceOrders"]},H=["vertices","edges","faces"],J=Array.from("BbMmVvFfJjCcUu"),Z={B:"boundary",M:"mountain",V:"valley",F:"flat",J:"join",C:"cut",U:"unassigned"};Object.keys(Z).forEach((e=>{Z[e.toLowerCase()]=Z[e]}));const Y={B:0,b:0,M:-180,m:-180,V:180,v:180,F:0,f:0,J:0,j:0,C:0,c:0,U:0,u:0},X={B:!1,b:!1,M:!0,m:!0,V:!0,v:!0,F:!1,f:!1,J:!1,j:!1,C:!1,c:!1,U:!0,u:!0},K={B:!0,b:!0,M:!1,m:!1,V:!1,v:!1,F:!1,f:!1,J:!1,j:!1,C:!0,c:!0,U:!1,u:!1},edgeAssignmentToFoldAngle=e=>Y[e]||0,edgeFoldAngleToAssignment=e=>e>p?"V":e<-p?"M":"U",edgeFoldAngleIsFlatFolded=e=>epsilonEqual(-180,e)||epsilonEqual(180,e),edgeFoldAngleIsFlat=e=>epsilonEqual(0,e)||edgeFoldAngleIsFlatFolded(e),edgesFoldAngleAreAllFlat=({edges_foldAngle:e})=>{if(!e)return!0;for(let t=0;t<e.length;t+=1)if(!edgeFoldAngleIsFlat(e[t]))return!1;return!0},filterKeys=(e,t)=>Object.keys(e).filter((e=>t(e))),filterKeysWithPrefix=(e,t)=>filterKeys(e,(e=>e.substring(0,t.length+1)===`${t}_`)),filterKeysWithSuffix=(e,t)=>filterKeys(e,(e=>e.substring(e.length-t.length-1,e.length)===`_${t}`)),getAllPrefixes=e=>{const t={};return Object.keys(e).filter((e=>e.includes("_"))).map((e=>e.substring(0,e.indexOf("_")))).forEach((e=>{t[e]=!0})),Object.keys(t)},getAllSuffixes=e=>{const t={};return Object.keys(e).filter((e=>e.includes("_"))).map((e=>e.substring(e.lastIndexOf("_")+1,e.length))).forEach((e=>{t[e]=!0})),Object.keys(t)},ee=Object.freeze([].concat(G.file).concat(G.frame).concat(G.graph).concat(G.orders)),getDimensionQuick=({vertices_coords:e})=>{if(!e||!e.length)return;if(void 0!==e[0])return e[0].length;const t=e.filter((()=>!0)).shift();return t?t.length:void 0},isFoldedForm=({vertices_coords:e,edges_vertices:t,faces_vertices:r,faces_edges:s,frame_classes:a,file_classes:o},c=p)=>{if(a&&a.includes("foldedForm")||o&&o.includes("foldedForm"))return!0;if(a&&a.includes("creasePattern")||o&&o.includes("creasePattern"))return!1;if(!e)return!1;const n=getDimensionQuick({vertices_coords:e});if(!r&&!s)return 3===n;if(t&&2===n)return doEdgesOverlap({vertices_coords:e,edges_vertices:t});for(let t=0;t<e.length;t+=1)if(e[t]&&"number"==typeof e[t][2]&&!epsilonEqual(e[t][2],0,c))return!0;return 3===n},makeEdgesIsFolded=({edges_vertices:e,edges_foldAngle:t,edges_assignment:r})=>void 0===r?void 0===t?e.map((()=>!0)):t.map((e=>e<-p||e>p)):r.map((e=>X[e])),te={M:"V",m:"v",V:"M",v:"m"},invertAssignment=e=>te[e]||e,invertAssignments=e=>(e.edges_assignment&&(e.edges_assignment=e.edges_assignment.map((e=>te[e]?te[e]:e))),e.edges_foldAngle&&(e.edges_foldAngle=e.edges_foldAngle.map((e=>-e))),e),sortEdgesByAssignment=({edges_vertices:e,edges_assignment:t=[]})=>{const r=Array.from(new Set(J.map((e=>e.toUpperCase())))),s=e.map(((e,r)=>t[r]||"U")).map((e=>e.toUpperCase())),a={};return r.forEach((e=>{a[e]=[]})),s.forEach(((e,t)=>a[e].push(t))),a};var re=Object.freeze({__proto__:null,VEF:H,assignmentCanBeFolded:X,assignmentFlatFoldAngle:Y,assignmentIsBoundary:K,edgeAssignmentToFoldAngle:edgeAssignmentToFoldAngle,edgeFoldAngleIsFlat:edgeFoldAngleIsFlat,edgeFoldAngleIsFlatFolded:edgeFoldAngleIsFlatFolded,edgeFoldAngleToAssignment:edgeFoldAngleToAssignment,edgesAssignmentNames:Z,edgesAssignmentValues:J,edgesFoldAngleAreAllFlat:edgesFoldAngleAreAllFlat,filterKeysWithPrefix:filterKeysWithPrefix,filterKeysWithSuffix:filterKeysWithSuffix,foldFileClasses:["singleModel","multiModel","animation","diagrams"],foldFrameAttributes:["2D","3D","abstract","manifold","nonManifold","orientable","nonOrientable","selfTouching","nonSelfTouching","selfIntersecting","nonSelfIntersecting"],foldFrameClasses:["creasePattern","foldedForm","graph","linkage"],foldKeys:G,getAllPrefixes:getAllPrefixes,getAllSuffixes:getAllSuffixes,getDimension:({vertices_coords:e},t=p)=>{for(let r=0;r<e.length;r+=1)if(e[r]&&3===e[r].length&&!epsilonEqual(0,e[r][2],t))return 3;return 2},getDimensionQuick:getDimensionQuick,getFileMetadata:(e={})=>{const t={};return G.file.filter((e=>"file_frames"!==e)).filter((t=>void 0!==e[t])).forEach((r=>{t[r]=e[r]})),t},invertAssignment:invertAssignment,invertAssignments:invertAssignments,isFoldObject:(e={})=>0===Object.keys(e).length?0:ee.filter((t=>e[t])).length/Object.keys(e).length,isFoldedForm:isFoldedForm,makeEdgesIsFolded:makeEdgesIsFolded,sortEdgesByAssignment:sortEdgesByAssignment,transposeGraphArrayAtIndex:(e,t,r)=>{const s=filterKeysWithPrefix(e,t);if(0===s.length)return;const a={};return s.forEach((t=>{a[t]=e[t][r]})),a},transposeGraphArrays:(e,t)=>{const r=filterKeysWithPrefix(e,t);if(0===r.length)return[];const s=Math.max(...r.map((t=>e[t].length))),a=Array.from(Array(s)).map((()=>({})));return r.forEach((t=>a.forEach(((r,s)=>{a[s][t]=e[t][s]})))),a}});const se={edges:"edgeOrders",faces:"faceOrders"},maxArraysLength=e=>Math.max(0,...e.filter((e=>void 0!==e)).map((e=>e.length))),count=(e,t)=>maxArraysLength(filterKeysWithPrefix(e,t).map((t=>e[t]))),countEdges=({edges_vertices:e,edges_faces:t})=>maxArraysLength([e,t]),countImplied=(e,t)=>Math.max((e=>{let t=-1;return e.filter((e=>void 0!==e)).forEach((e=>e.forEach((e=>e.forEach((e=>{e>t&&(t=e)})))))),t})(filterKeysWithSuffix(e,t).map((t=>e[t]))),e[se[t]]?(e=>{let t=-1;return e.forEach((e=>{e[0]>t&&(t=e[0]),e[1]>t&&(t=e[1])})),t})(e[se[t]]):-1)+1,countImpliedVertices=e=>countImplied(e,"vertices"),countImpliedEdges=e=>countImplied(e,"edges");var ae=Object.freeze({__proto__:null,count:count,countEdges:countEdges,countFaces:({faces_vertices:e,faces_edges:t,faces_faces:r})=>maxArraysLength([e,t,r]),countImplied:countImplied,countImpliedEdges:countImpliedEdges,countImpliedFaces:e=>countImplied(e,"faces"),countImpliedVertices:countImpliedVertices,countVertices:({vertices_coords:e,vertices_vertices:t,vertices_edges:r,vertices_faces:s})=>maxArraysLength([e,t,r,s])});const makeVerticesFacesUnsorted=({vertices_coords:e,vertices_edges:t,faces_vertices:r})=>{const s=e||t;if(!r)return(s||[]).map((()=>[]));const a=void 0!==s?s.map((()=>[])):Array.from(Array(countImpliedVertices({faces_vertices:r}))).map((()=>[]));return r.forEach(((e,t)=>{const r=[];e.forEach((e=>{r[e]=t})),r.forEach(((e,t)=>a[t].push(e)))})),a},makeVerticesFaces=({vertices_coords:e,vertices_vertices:t,faces_vertices:r})=>{if(!r)return e.map((()=>[]));if(!t)return makeVerticesFacesUnsorted({vertices_coords:e,faces_vertices:r});const s=makeVerticesToFace({faces_vertices:r});return t.map(((e,t)=>e.map((e=>[t,e].join(" "))))).map((e=>e.map((e=>s[e]))))};var oe=Object.freeze({__proto__:null,makeVerticesFaces:makeVerticesFaces,makeVerticesFacesUnsorted:makeVerticesFacesUnsorted});const projectPointOnPlane=(e,t=[1,0,0],r=[0,0,0])=>{const s=resize3(e),a=subtract3(s,resize3(r)),o=normalize3(resize3(t)),c=dot3(o,a),n=scale3$1(o,c);return subtract3(s,n)};var ce=Object.freeze({__proto__:null,projectPointOnPlane:projectPointOnPlane});const sortPointsAlongVector=(e,t)=>{return r=t,s=dot,e.map(((e,t)=>({i:t,n:s(e,r)}))).sort(((e,t)=>e.n-t.n)).map((e=>e.i));var r,s},radialSortUnitVectors2=e=>{const t=[[],[]];e.map((e=>e[1]>=0?0:1)).forEach(((e,r)=>t[e].push(r)));const r=[(t,r)=>e[r][0]-e[t][0],(t,r)=>e[t][0]-e[r][0]];return t.flatMap(((e,t)=>e.sort(r[t])))},radialSortVectors3=(e,t=[1,0,0],r=[0,0,0])=>{const s=basisVectors3(t),a=[s[1],s[2],s[0]],o=e.map((e=>projectPointOnPlane(e,t,r))).map((e=>subtract(e,r))).map((e=>[dot(e,a[0]),dot(e,a[1])])).map(normalize2);return radialSortUnitVectors2(o)};var ne=Object.freeze({__proto__:null,radialSortUnitVectors2:radialSortUnitVectors2,radialSortVectors3:radialSortVectors3,sortPointsAlongVector:sortPointsAlongVector});const sortVerticesCounterClockwise=({vertices_coords:e},t,r)=>t.map((t=>e[t])).map((t=>subtract(t,e[r]))).map((e=>Math.atan2(e[1],e[0]))).map((e=>e>-p?e:e+2*Math.PI)).map(((e,t)=>({a:e,i:t}))).sort(((e,t)=>e.a-t.a)).map((e=>e.i)).map((e=>t[e]));var ie=Object.freeze({__proto__:null,sortVerticesAlongVector:({vertices_coords:e},t,r)=>sortPointsAlongVector(t.map((t=>e[t])),r).map((e=>t[e])),sortVerticesCounterClockwise:sortVerticesCounterClockwise});const makeVerticesVertices2D=({vertices_coords:e,vertices_edges:t,edges_vertices:r})=>{t||(t=makeVerticesEdgesUnsorted({edges_vertices:r}));const s=t.map(((e,t)=>e.map((e=>r[e].filter((e=>e!==t)))).reduce(((e,t)=>e.concat(t)),[])));return void 0===e?s:s.map(((t,r)=>sortVerticesCounterClockwise({vertices_coords:e},t,r)))},makeVerticesVerticesFromFaces=({vertices_coords:e,vertices_faces:t,faces_vertices:r})=>{t||(t=makeVerticesFacesUnsorted({vertices_coords:e,faces_vertices:r}));const s=t.map((e=>e.map((e=>r[e])))),a=s.map(((e,t)=>e.map((e=>e.indexOf(t))))),o=s.map(((e,t)=>e.map(((e,r)=>[(a[t][r]+e.length-1)%e.length,a[t][r],(a[t][r]+1)%e.length])))),c=o.map(((e,t)=>e.map(((e,r)=>e.map((e=>s[t][r][e])))))),n=c.map((e=>{const t=e.map((e=>[[0,1],[1,2]].map((t=>t.map((t=>e[t])).join(" "))))),r={},s={};return t.forEach(((e,t)=>{r[e[0]]=t,s[e[1]]=t})),{facesVerts:t,to:s,from:r}}));return n.map((e=>{const t=Object.keys(e.to),r=t.map((e=>e.split(" ").reverse().join(" "))),s=t.filter(((t,s)=>!(r[s]in e.from)));if(s.length>2)return console.warn("vertices_vertices found an unsolvable vertex"),[];const a=s.length?s:[t[0]],o=[],c={};for(let t=0;t<a.length;t+=1){const r=a[t],s=[r];c[r]=!0;let n=!1;do{const t=s[s.length-1],r=e.to[t];if(!(r in e.facesVerts))break;let a;if(e.facesVerts[r][0]===t&&(a=e.facesVerts[r][1]),e.facesVerts[r][1]===t&&(a=e.facesVerts[r][0]),void 0===a)return[];const o=a.split(" ").reverse().join(" ");s.push(a),n=o in c,n||s.push(o),c[a]=!0,c[o]=!0}while(!n);const i=s.filter(((e,t)=>t%2==0)).map((e=>e.split(" ")[1])).map((e=>parseInt(e,10)));o.push(...i)}return o}))},makeVerticesVertices=e=>{if(!e.vertices_coords||!e.vertices_coords.length)return[];return 3===e.vertices_coords.filter((()=>!0)).shift().length?makeVerticesVerticesFromFaces(e):makeVerticesVertices2D(e)},makeVerticesVerticesUnsorted=({vertices_edges:e,edges_vertices:t})=>(e||(e=makeVerticesEdgesUnsorted({edges_vertices:t})),e.map(((e,r)=>e.flatMap((e=>t[e].filter((e=>e!==r)))))));var le=Object.freeze({__proto__:null,makeVerticesVertices:makeVerticesVertices,makeVerticesVertices2D:makeVerticesVertices2D,makeVerticesVerticesFromFaces:makeVerticesVerticesFromFaces,makeVerticesVerticesUnsorted:makeVerticesVerticesUnsorted});const makeFacesVerticesFromEdges=({edges_vertices:e,faces_edges:t})=>t.map((t=>t.map((t=>e[t])).map(((e,t,r)=>{const s=r[(t+1)%r.length];return e[0]===s[0]||e[0]===s[1]?e[1]:e[0]}))));var fe=Object.freeze({__proto__:null,makeFacesVerticesFromEdges:makeFacesVerticesFromEdges});const makeFacesEdgesFromVertices=({edges_vertices:e,faces_vertices:t})=>{const r=makeVerticesToEdge({edges_vertices:e});return t.map((e=>e.map(((e,t,r)=>[e,r[(t+1)%r.length]].join(" "))))).map((e=>e.map((e=>r[e]))))};var de=Object.freeze({__proto__:null,makeFacesEdgesFromVertices:makeFacesEdgesFromVertices});const angleArray=e=>Array.from(Array(Math.floor(e))).map(((t,r)=>b*(r/e))),anglesToVecs=(e,t)=>e.map((e=>[t*Math.cos(e),t*Math.sin(e)])),makePolygonCircumradius=(e=3,t=1)=>anglesToVecs(angleArray(e),t),makePolygonCircumradiusSide=(e=3,t=1)=>{const r=Math.PI/e,s=angleArray(e).map((e=>e+r));return anglesToVecs(s,t)},makePolygonNonCollinear=(e,t=p)=>{const r=e.map(((e,t,r)=>[e,r[(t+1)%r.length]])).map((e=>subtract(e[1],e[0]))).map(((e,t,r)=>[e,r[(t+r.length-1)%r.length]])).map((e=>!parallel(e[1],e[0],t)));return e.filter(((e,t)=>r[t]))},makePolygonNonCollinear3=(e,t=p)=>{const r=e.map(((e,t,r)=>[e,r[(t+1)%r.length]])).map((e=>subtract3(e[1],e[0]))).map(((e,t,r)=>[e,r[(t+r.length-1)%r.length]])).map((e=>!parallel(e[1],e[0],t)));return e.filter(((e,t)=>r[t]))},signedArea=e=>.5*e.map(((e,t,r)=>[e,r[(t+1)%r.length]])).map((([e,t])=>cross2(e,t))).reduce(((e,t)=>e+t),0),centroid=e=>{const t=1/(6*signedArea(e)),r=e.map(((e,t,r)=>[e,r[(t+1)%r.length]])).map((([e,t])=>scale2$1(add2(e,t),cross2(e,t)))).reduce(((e,t)=>add2(e,t)),[0,0]);return[r[0]*t,r[1]*t]},boundingBox$1=(e,t=0)=>{if(!e||!e.length)return;const r=(e=>{for(let t=0;t<e.length;t+=1)if(e[t]&&e[t].length)return e[t].length;return 0})(e),s=Array(r).fill(1/0),a=Array(r).fill(-1/0);e.filter((e=>void 0!==e)).forEach((e=>e.forEach(((e,r)=>{e<s[r]&&(s[r]=e-t),e>a[r]&&(a[r]=e+t)}))));const o=a.map(((e,t)=>e-s[t]));return{min:s,max:a,span:o}};var _e=Object.freeze({__proto__:null,boundingBox:boundingBox$1,centroid:centroid,makePolygonCircumradius:makePolygonCircumradius,makePolygonCircumradiusSide:makePolygonCircumradiusSide,makePolygonInradius:(e=3,t=1)=>makePolygonCircumradius(e,t/Math.cos(Math.PI/e)),makePolygonInradiusSide:(e=3,t=1)=>makePolygonCircumradiusSide(e,t/Math.cos(Math.PI/e)),makePolygonNonCollinear:makePolygonNonCollinear,makePolygonNonCollinear3:makePolygonNonCollinear3,makePolygonSideLength:(e=3,t=1)=>makePolygonCircumradius(e,t/2/Math.sin(Math.PI/e)),makePolygonSideLengthSide:(e=3,t=1)=>makePolygonCircumradiusSide(e,t/2/Math.sin(Math.PI/e)),signedArea:signedArea});const makeEdgesCoords=({vertices_coords:e,edges_vertices:t})=>t.map((t=>[e[t[0]],e[t[1]]])),makeEdgesVector=({vertices_coords:e,edges_vertices:t})=>{const r=2===getDimensionQuick({vertices_coords:e})?resize2:resize3;return makeEdgesCoords({vertices_coords:e,edges_vertices:t}).map((([e,t])=>r(subtract(t,e))))},makeEdgesLength=({vertices_coords:e,edges_vertices:t})=>makeEdgesVector({vertices_coords:e,edges_vertices:t}).map(magnitude);var me=Object.freeze({__proto__:null,makeEdgesBoundingBox:({vertices_coords:e,edges_vertices:t},r)=>makeEdgesCoords({vertices_coords:e,edges_vertices:t}).map((e=>boundingBox$1(e,r))),makeEdgesCoords:makeEdgesCoords,makeEdgesLength:makeEdgesLength,makeEdgesVector:makeEdgesVector});const walkSingleFace=({vertices_vertices:e,vertices_sectors:t},r,s,a={})=>{const o={};let c=r,n=s;const i={vertices:[r],edges:[`${r} ${s}`],angles:[]};for(;;){const r=e[n],s=(r.indexOf(c)+r.length-1)%r.length,l=r[s],d=`${n} ${l}`;if(a[d])return;if(o[d])return Object.assign(a,o),i.vertices.pop(),i.edges.pop(),i.angles.length||delete i.angles,i;o[d]=!0,i.vertices.push(n),i.edges.push(d),t&&i.angles.push(t[n][s]),c=n,n=l}},walkPlanarFaces=({vertices_vertices:e,vertices_sectors:t})=>{const r={},s={vertices_vertices:e,vertices_sectors:t};return e.flatMap(((e,t)=>e.map((e=>walkSingleFace(s,t,e,r))).filter((e=>void 0!==e))))},filterWalkedBoundaryFace=e=>e.filter((e=>e.angles.map((e=>Math.PI-e)).reduce(((e,t)=>e+t),0)>0));var ge=Object.freeze({__proto__:null,filterWalkedBoundaryFace:filterWalkedBoundaryFace,walkPlanarFaces:walkPlanarFaces,walkSingleFace:walkSingleFace});const makeVerticesVerticesVector=({vertices_coords:e,vertices_vertices:t,vertices_edges:r,vertices_faces:s,edges_vertices:a,edges_vector:o,faces_vertices:c})=>{o||(o=makeEdgesVector({vertices_coords:e,edges_vertices:a})),t||(t=makeVerticesVertices({vertices_coords:e,vertices_edges:r,vertices_faces:s,edges_vertices:a,faces_vertices:c}));const n={};return a.map((e=>e.join(" "))).forEach(((e,t)=>{n[e]=t})),t.map(((e,r)=>t[r].map((e=>{const t=n[`${r} ${e}`],s=n[`${e} ${r}`];return void 0!==t?resize2(o[t]):void 0!==s?flip2(o[s]):void 0}))))},makeVerticesSectors=({vertices_coords:e,vertices_vertices:t,edges_vertices:r,edges_vector:s})=>makeVerticesVerticesVector({vertices_coords:e,vertices_vertices:t,edges_vertices:r,edges_vector:s}).map((e=>1===e.length?[b]:counterClockwiseSectors2(e)));var ve=Object.freeze({__proto__:null,makeVerticesSectors:makeVerticesSectors,makeVerticesVerticesVector:makeVerticesVerticesVector});const makePlanarFaces=({vertices_coords:e,vertices_vertices:t,vertices_edges:r,vertices_sectors:s,edges_vertices:a,edges_vector:o})=>{t||(t=makeVerticesVertices({vertices_coords:e,edges_vertices:a,vertices_edges:r})),s||(s=makeVerticesSectors({vertices_coords:e,vertices_vertices:t,edges_vertices:a,edges_vector:o}));const c=makeVerticesToEdge({edges_vertices:a}),n=filterWalkedBoundaryFace(walkPlanarFaces({vertices_vertices:t,vertices_sectors:s})).map((e=>({...e,edges:e.edges.map((e=>c[e]))})));return{faces_vertices:n.map((e=>e.vertices)),faces_edges:n.map((e=>e.edges)),faces_sectors:n.map((e=>e.angles))}},makeFacesPolygon=({vertices_coords:e,faces_vertices:t},r)=>t.map((t=>t.map((t=>e[t])))).map((e=>makePolygonNonCollinear(e,r))),makeFacesPolygonQuick=({vertices_coords:e,faces_vertices:t})=>t.