memoscan
← all memos

Memo 0x36ed96f5…0395e0 on Ethereum

).fromArray(e))),n=new dn;n.expands(t);let l=[];for(let i of this.faces)if(!(i.area<=this.tolerance)&&n.intersects(i.aabb)){if(Nn(t,i.vertexlist)){l.push({face:i,intersections:[],isContained:!0});continue}let n=[];for(let l=0;l<e.length;l++){let a=[t[l],t[(l+1)%e.length]];n.push(...i.intersectWithLineSeg(a))}n.length>0&&l.push({face:i,intersections:n,isContained:!1})}return l}}class kn extends wn{tolerance;constructor(e,t,n=Kn){super(e,t,n),this.tolerance=n}isPolyLineSegmentOnEdge(e,t){for(let n=0;n<t.length-1;n++){let l=[t[n],t[n+1]];if(this.isLineSegmentOnEdgeOfFace(e,l),this.tolerance)return!0}}isLineSegmentOnEdgeOfFace(e,t,n=g){for(let l=0;l<e.vertexlist.length;l++)if(Rn([e.vertexlist[l].toArray(),e.vertexlist[(l+1)%e.vertexlist.length].toArray()],t),n)return!0;return!1}getFacesIntersectingAABB(e){let t=[];for(let n of this.faces.filter((e=>e.area>0)))e.intersects(n.aabb,this.tolerance)&&t.push(n);return t}removeEdgesInsidePolygon(e,t=100){let n=new dn;n.expands(e.map((e=>(new Ut).fromArray(e))));let l=e.map((e=>(new Ut).fromArray(e))),i=this.getFacesIntersectingAABB(n),a=[];for(let t of i){let n=t.vertexlist;for(let t=0;t<n.length;t++){let i=n[t],s=n[(t+1)%n.length];if(!In(l,i,this.tolerance)||!In(l,s,this.tolerance))continue;let o=0;[i,s].forEach((t=>{Mn(t.toArray(),e,this.tolerance)&&o++})),o>1||a.push([i,s])}}for(let e of a)J.bool(t)&&this.removeEdge(e[0].x,e[0].y,e[1].x,e[1].y);this.cleanupTrailingEdges()}insertPolygon(e,t=!0){let n=[],l=new dn;l.expands(e.map((e=>(new Ut).fromArray(e)))),l.expandByValue(this.tolerance);let i=this.getFacesIntersectingAABB(l),a=new Set;for(let e of i){let t=e.vertexlist;for(let e=0;e<t.length;e++){let n=t[e],l=t[(e+1)%t.length],i=this.findHedge(n.x,n.y,l.x,l.y);a.has(i.twin)||a.add(i)}}for(let t of e)n.push({type:"addVertex",data:{x:t[0],y:t[1]}});for(let l of a){let i=[];e:for(let a=0;a<(t?e.length:e.length-1);a++){let t=[new Ut(...e[a]),new Ut(...e[(a+1)%e.length])],s=l.intersectWithLineSegment(t);if(s.type==Wn.intersecting){for(let e of i)if(e.isEqualTo(s.point))continue e;n.push({type:"addVertex",data:{x:s.point.x,y:s.point.y}})}}}for(let l=0;l<(t?e.length:e.length-1);l++){let t=[e[l],e[(l+1)%e.length]];n.push({type:"addEdge",data:{from:{x:t[0][0],y:t[0][1]},to:{x:t[1][0],y:t[1][1]}}})}this.executeAddOperations(n)}splitFaceByPolyLine(e,t,n=!1,l=!1,i=!1){const a=(e,t,n,l)=>{const i=[.5,.25,.75];for(let a of i){let i=e.lerp(t,a);if(n.containsPoint(i)&&!n.isPointOnBoundary(i,l))return!0}return!1},s=(e,t,n,l)=>{let i=[.25,.5,.75],a=0;for(let s of i){let i=e.lerp(t,s);if(n.isPointOnBoundary(i,l)&&(a++,a>=2))return!0}return a>=2};let o=[],r=[],c=!1,d=0;if(n){let n=t.findIndex((t=>!e.containsPoint(new Ut(...t))||e.isPointOnBoundary(new Ut(...t),this.tolerance)));if(!(n>=0))return!1;t=t.slice(n).concat(t.slice(0,n))}const u=n?t.length:t.length-1;for(let n=0;n<u;n++){let l=new Ut(...t[n]),i=new Ut(...t[(n+1)%t.length]),u=[l,i],h=e.intersectWithLineSeg(u);d+=h.length;let m=[l,...h.map((e=>e.point)),i];m=Tn(l,i,m,!0,this.tolerance);for(let t=0;t<m.length-1;t++){let n=m[t],l=m[t+1];a(n,l,e,this.tolerance)&&!s(n,l,e,this.tolerance)?(c||(r=[n],c=!0),r.push(l)):c&&(o.push(r),r=[],c=!1)}}if(!n&&c&&r.length>1&&o.push(r),l||(o=o.filter((t=>{let n=t[Math.floor(t.length/2)].lerp(t[Math.ceil(t.length/2)],.5);return e.containsPoint(n)}))),o.length>1&&i){let e=null;for(let t of o){let l=0;for(let e=0;e<(n?t.length:t.length-1);e++)l+=t[e].distanceTo(t[(e+1)%t.length]);(!e||l>e.length)&&(e={length:l,line:t})}if(!e)return!1;o=[e.line]}if(0===o.length)return!1;if(l)return{lines:o,intersectionCount:d};let h=[];for(let e of o)for(let t of e)h.push({type:"addVertex",data:{x:t.x,y:t.y}});for(let e of o)for(let t=0;t<e.length-1;t++)h.push({type:"addEdge",data:{from:{x:e[t].x,y:e[t].y},to:{x:e[t+1].x,y:e[t+1].y}}});return this.executeAddOperations(h),!0}executeAddOperations(e){const t=e.filter((e=>"addVertex"===e.type)),n=e.filter((e=>"addEdge"===e.type));let l=[];for(const e of n){let t=new dn,n=new Ut(e.data.from.x,e.data.from.y),i=new Ut(e.data.to.x,e.data.to.y);t.expands([n,i]),t.expandByValue(this.tolerance);let a=new Set;for(let e of this.hedges){let l=e.getAABB();if(l.expandByValue(this.tolerance),l.intersects(t)){let t=e.intersectWithLineSegment([n,i]);t.type==Wn.intersecting&&(a.add(t.point),this.findVertex(t.point.x,t.point.y)||this.splitEdge(e.origin.x,e.origin.y,e.twin.origin.x,e.twin.origin.y,t.point.x,t.point.y))}}if(a.size>1){let e=Tn(n,i,[n,...a,i],!0,this.tolerance);for(let t=0;t<e.length-1;t++)l.push({type:"addEdge",data:{from:{x:e[t].x,y:e[t].y},to:{x:e[t+1].x,y:e[t+1].y}}})}else l.push(e)}for(const e of t){let{x:t,y:n}=e.data;if(!this.findVertex(t,n)){let e=!1;for(let l of this.hedges){let i=l.getAABB();i.expandByValue(this.tolerance),i.containsPoint(new Ut(t,n))&&!this.findVertex(t,n)&&zn([t,n],[l.origin.toArray(),l.twin.origin.toArray()])&&(e=!1!==this.splitEdge(l.origin.x,l.origin.y,l.twin.origin.x,l.twin.origin.y,t,n))}!e&&this.addVertex(t,n)}}for(const e of l.filter((e=>"addEdge"===e.type))){let{from:t,to:n}=e.data,l=this.findVertex(t.x,t.y),i=this.findVertex(n.x,n.y);if(l&&i){let e=new Set;e.add(l);let t=new dn;t.expands([l,i]),t.expandByValue(this.tolerance);for(let n of this.verticesInBB(t))zn(n.toArray(),[l.toArray(),i.toArray()])&&e.add(n);e.add(i);let n=Tn(l,i,Array.from(e),!0);for(let e=0;e<n.length-1;e++)this.findHedge(n[e].x,n[e].y,n[e+1].x,n[e+1].y)||this.addEdge(n[e].x,n[e].y,n[e+1].x,n[e+1].y)}}}cleanupDegenerateHoles(){let e=new Set;this.faces.forEach((t=>{for(let n of this.faces)t!=n&&t.aabb.containsBB(n.aabb)&&t.vertexlist.every((e=>n.containsPoint(e)))&&n.hedges.forEach((t=>{t.face==n&&e.add(t)}))})),this.faces.filter((e=>e.area>0)).forEach((t=>{t.holes.forEach((n=>{n.hedges.forEach((n=>{n.face==t&&e.add(n)}))}))}));for(const t of e)t.origin&&t.twin.origin&&this.removeEdge(t.origin.x,t.origin.y,t.twin.origin.x,t.twin.origin.y)}cleanupTrailingEdges(){this.hedges.forEach((e=>{e.face==e.twin.face&&this.removeEdge(e.origin.x,e.origin.y,e.twin.origin.x,e.twin.origin.y)}))}}function Rn(e,t,n=g){let[l,i]=e,[a,o]=t;const r=i[0]-l[0],c=i[1]-l[1],u=o[0]-a[0],h=o[1]-a[1];if(s(r*h-c*u)>n)return!1;const m=s(r*(l[1]-a[1])-(l[0]-a[0])*c),p=d(r*r+c*c);return!(p<n)&&m/p<n}function Tn(e,t,n,l=!1,i=g){const a=t.x-e.x,s=t.y-e.y;let o=a*a+s*s;if(o<i)return n;const r=1/o,c=n.map((t=>{const n=((t.x-e.x)*a+(t.y-e.y)*s)*r;return{point:t,t:Math.max(0,Math.min(1,n))}}));c.sort(((t,n)=>{const l=t.t-n.t;return Math.abs(l)>i?l:(t.point.x-e.x)**2+(t.point.y-e.y)**2-((n.point.x-e.x)**2+(n.point.y-e.y)**2)}));let d=c.map((e=>e.point));return l&&(d=function(e,t){const n=[],l=new Map;for(const i of e){const e=`${Math.round(i.x/t)},${Math.round(i.y/t)}`;l.has(e)||(l.set(e,!0),n.push(i))}return n}(d,i)),d}function Mn(e,t,n=g){for(let l=0;l<t.length;l++){const i=t[l],a=t[(l+1)%t.length],s=o(i[0],a[0])-n,c=r(i[0],a[0])+n,d=o(i[1],a[1])+-n,u=r(i[1],a[1])+n;if(e[0]>=s&&e[0]<=c&&e[1]>=d&&e[1]<=u&&Yn(e,i,a)<=n*n)return!0}return!1}function zn(e,t,n=g){const[l,i]=t,a=(e[1]-l[1])*(i[0]-l[0])-(e[0]-l[0])*(i[1]-l[1]);if(Math.abs(a)>n)return!1;const s=(e[0]-l[0])*(i[0]-l[0])+(e[1]-l[1])*(i[1]-l[1]);return!(s<-n||s-((i[0]-l[0])*(i[0]-l[0])+(i[1]-l[1])*(i[1]-l[1]))>n)}function Yn(e,t,n){const l=n[0]-t[0],i=n[1]-t[1],a=l*l+i*i;if(a<1e-14){const n=e[0]-t[0],l=e[1]-t[1];return n*n+l*l}let s=((e[0]-t[0])*l+(e[1]-t[1])*i)/a;s=Math.max(0,Math.min(1,s));const o=t[0]+s*l,r=t[1]+s*i,c=e[0]-o,d=e[1]-r;return c*c+d*d}let Pn=0;class Fn{_dcel;id=Pn++;changeIndex=0;wedge=null;_area=0;_areaDirty=!0;_vertexlist=[];_vertexlistDirty=!0;_centerDirty=!0;_hedges=[];_hedgesDirty=!0;_center=null;_hasInsertedIntoPQ=!1;_holes=[];_holesDirty=!0;_aabb=null;_aabbDirty=!0;constructor(e){this._dcel=e}get area(){return this._areaDirty&&(this._area=Un(this.vertexlist),this._areaDirty=!1),this._area}get areaExceptHoles(){const e=this.holes;let t=this.area;for(let n=0,l=e.length;n<l;n++)t+=e[n].area;return t}get internal(){return this.area>Kn}get external(){return this.area<=Kn}get hedges(){if(this._hedgesDirty){const e=[];let t=this.wedge,n=0;const l=1e6;for(e.push(t);t.nexthedge!==this.wedge&&n<l;)t=t.nexthedge,e.push(t),n++;if(n>=l)throw Error("Face vertex list is too long");this._hedges=e,this._hedgesDirty=!1}return this._hedges}get center(){if(this._centerDirty){const e=this.vertexlist;let t=0,n=0,l=0;for(let i=0;i<e.length;i++){const a=e[i].x,s=e[i].y,o=e[(i+1)%e.length].x,r=e[(i+1)%e.length].y,c=a*r-s*o;t+=c,n+=(a+o)*c,l+=(s+r)*c}t*=.5,n/=6*t,l/=6*t,this._center=new Ut(n,l),this._centerDirty=!1}return this._center}get vertexlist(){return this._vertexlistDirty&&this.cleanVertexList(),this._vertexlist}cleanVertexList(){if(!this._vertexlistDirty)return;let e=this.wedge;const t=this._vertexlist;t.length=0;let n=0;const l=1e6;for(t.push(e.origin);e.nexthedge!==this.wedge&&n<l;)e=e.nexthedge,t.push(e.origin),n++;if(n>=l)throw Error("Face vertex list is too long");this._vertexlistDirty=!1}get holes(){if(this._holesDirty&&(this._holesDirty=!1,this._holes.length=0,this.internal)){const e=this._dcel.faces;for(let t=0,n=e.length;t<n;t++)this._tryAddHole(e[t])}return this._holes}get aabb(){return this._aabb||(this._aabb=new dn),this._aabbDirty&&(this._aabb.reset(),this._aabb.expands(this.vertexlist),this._aabbDirty=!1),this._aabb}equals(e){const t=this.vertexlist,n=e.vertexlist;if(t.length!==n.length)return!1;const l=t.length;for(let e=0;e<l;e++)for(let i=0;i<l&&t[i]===n[(e+i)%l];i++)if(i===l-1)return!0;return!1}findNearestEdge(e){return function(e,t){const n=Dn(e);let l=[e[0],e[1]],i=1e10,a=-1/0,s=null;for(let o=0;o<e.length;o++){const r=[e[o],e[(o+1)%e.length]],{distance:c,projection:d}=On(t,r[0],r[1]),u={x:r[1].x-r[0].x,y:r[1].y-r[0].y};let h={x:-u.y,y:u.x},m={x:(r[0].x+r[1].x)/2-n.x,y:(r[0].y+r[1].y)/2-n.y};h.x*m.x+h.y*m.y<0&&(h={x:u.y,y:-u.x});const p={x:t.x-(r[0].x+r[1].x)/2,y:t.y-(r[0].y+r[1].y)/2},b=h.x*p.x+h.y*p.y;(c<i||c===i&&b>a)&&b>0&&(i=c,l=r,a=b,s=d)}return{edge:l,distance:i,edgePoint:s}}(this.vertexlist,e)}containsPoint(e){return!(!this.aabb.containsPoint(e)||!In(this.vertexlist,e))}isPointOnBoundary(e,t=Kn){let n=this.vertexlist.map((e=>e.toArray()));return!!Mn(e.toArray(),n,t)}intersectWithPolyLine(e,t=!1){let n=[];const l=t?e.length:e.length-1;for(let i=0;i<l;i++){const l=t?(i+1)%e.length:i+1,a=[e[i],e[l]];n.push(...this.intersectWithLineSeg(a))}return n}intersectWithLineSeg(e){const t=[],n=this.hedges.filter((e=>e.face==this)),l=(new dn).expands(e);for(let i of n){if(!i.getAABB().intersects(l))continue;const n=i.intersectWithLineSegment(e);n.type===Wn.intersecting&&t.push({point:n.point,edge:[i.origin,i.twin.origin]})}return t}dirty(){this._areaDirty=!0,this._hedgesDirty=!0,this._centerDirty=!0,this._vertexlistDirty=!0,this._holesDirty=!0,this._aabbDirty=!0,this.changeIndex++}dispose(){this.wedge=null,this._vertexlist.length=0,this._holes.length=0,this._aabb=null,this._dcel=null}_tryAddHole(e){this._holesDirty||e.external&&this.area-Math.abs(e.area)>Kn&&this.aabb.containsPoints(e.vertexlist)&&Nn(this.vertexlist,e.vertexlist,Kn)&&this._holes.push(e)}}function Hn(e,t,n){return(t.x-e.x)*(n.y-e.y)-(t.y-e.y)*(n.x-e.x)}function In(e,t,n=Kn){if(Mn([t.x,t.y],e.map((e=>e.toArray())),n))return!0;let l=0;for(let n=0;n<e.length;n++){const i=e[n],a=e[(n+1)%e.length];i.y<=t.y?a.y>t.y&&Hn(i,a,t)>0&&l++:a.y<=t.y&&Hn(i,a,t)<0&&l--}return 0!==l}function Nn(e,t,n=Kn){for(let l=0,i=t.length;l<i;l++)if(!In(e,t[l],n))return!1;return!0}function Un(e){if(e.length<3)return 0;let t=0;for(let n=0;n<e.length;n++){const l=(n+1)%e.length;t+=e[n].x*e[l].y-e[n].y*e[l].x}return.5*t}function Dn(e){let t=0,n=0;for(let l=0;l<e.length;l++)t+=e[l].x,n+=e[l].y;return new Ut(t/e.length,n/e.length)}function On(e,t,n,l=Kn){const i=(n.x-t.x)*(n.x-t.x)+(n.y-t.y)*(n.y-t.y);if(i<l)return{distance:e.distanceTo(t),projection:t};let a=((e.x-t.x)*(n.x-t.x)+(e.y-t.y)*(n.y-t.y))/i;a<-l?a=0:a>1+l&&(a=1);const s=new Ut(t.x+a*(n.x-t.x),t.y+a*(n.y-t.y));return{distance:e.distanceTo(s),projection:s}}function Bn(e,t,n=g){const[{x:l,y:i},{x:a,y:s}]=e,[{x:o,y:r},{x:c,y:d}]=t,u=(l-a)*(r-d)-(i-s)*(o-c);if(Math.abs(u)<n)return null;const h=((l-o)*(r-d)-(i-r)*(o-c))/u,m=((a-l)*(i-r)-(s-i)*(l-o))/u;return h>=-n&&h<=1+n&&m>=-n&&m<=1+n?new Ut(l+h*(a-l),i+h*(s-i)):null}function Qn(e,t){const n=[];for(let l=0;l<t.length;l++){const i=[t[l],t[(l+1)%t.length]],a=Bn(e,i);a&&n.push({point:a,edge:i})}return n}let jn=0;function Jn(){return jn++,jn}function An(e){let{boxCenter:t,perspectiveCenter:n,centerBoxMaskDimensions:l=[0,0],width:i,height:a,gThreshold:s=2.5,gMean:o=1,gStdDev:r=1.5}=e;n||(n=t);const[c,d]=t;let[u,h]=n;u=Ot(new Ut(u,h)).x,h=Ot(new Ut(u,h)).y;let m=[l[0]*Be.scale,l[1]*Be.scale];i=xe(i,Be.scale),a=xe(a,Be.scale);let p=[];const b=2*(i+a),g=b/Be.scale,f=b/g;let x=[[u-m[0],h-m[1]],[u+m[0],h-m[1]],[u+m[0],h+m[1]],[u-m[0],h+m[1]]],Z=0,y=0,G=0;for(let e=0;e<g;e++){if(G<i?(Z=c-i/2+G,y=d-a/2):G<i+a?(Z=c+i/2,y=d-a/2+(G-i)):G<2*i+a?(Z=c+i/2-(G-(i+a)),y=d+a/2):(Z=c-i/2,y=d+a/2-(G-(2*i+a))),J.gaussianBool(s,o,r)){let e=Qn([[u,h],[Z,y]].map((e=>new Ut(...e))),x.map((e=>new Ut(...e))));if(!e[0])continue;let t=[e[0].point.toArray(),[Z,y]];if(p.push(t),J.bool(0)){let e=J.int(1,3)*Be.scale;J.bool(50)&&(e*=-1);let n=[[t[0][0]+e,t[0][1]],[t[1][0]+e,t[1][1]]];p.push(n)}}G+=f}return p}function En({center:e,width:t,height:n,angle:a=0}){let[s,o]=e,r=t/2,c=n/2,d=[[s-r,o-c],[s+r,o-c],[s+r,o+c],[s-r,o+c]];return 0!==a&&(d=function(e,t,n){const a=n||function(e){const t=e.reduce(((e,t)=>[e[0]+t[0],e[1]+t[1]]),[0,0]);return[t[0]/e.length,t[1]/e.length]}(e),s=t*b/180;return e.map((e=>{const t=[e[0]-a[0],e[1]-a[1]],n=[t[0]*i(s)-t[1]*l(s),t[0]*l(s)+t[1]*i(s)];return[n[0]+a[0],n[1]+a[1]]}))}(d,a,e)),d}function _n(e){let{center:n,radius:l,startAngle:i=0,endAngle:a=180}=e,s=[],[o,r]=n;i=me(i),a=me(a);let c=t(l*Math.abs(a-i)*.125);for(let e=0;e<=c;e++){let t=i+e/c*(a-i),n=o+l*Math.cos(t),d=r+l*Math.sin(t);s.push([n,d])}let d=function(e){let t=0,n=0;for(let l=0;l<e.length;l++)t+=e[l][0],n+=e[l][1];return[t/e.length,n/e.length]}(s),u=[o-d[0],r-d[1]];return s=s.map((e=>[e[0]+u[0],e[1]+u[1]])),s}class qn{startX;startY;endX;endY;distances;constructor(e,t,n,l){this.startX=e,this.startY=t,this.endX=n,this.endY=l;const i=n-e+1,a=l-t+1;this.distances=Array(a).fill(null).map((()=>Array(i).fill(1/0)))}initializeWithEmptyCells(e,t){for(let e=0;e<this.distances.length;e++)for(let t=0;t<this.distances[0].length;t++)this.distances[e][t]=0;e.forEach((e=>{const[n,l]=t(e),i=n-this.startX,a=l-this.startY;i>=0&&a>=0&&i<this.distances[0].length&&a<this.distances.length&&(this.distances[a][i]=1/0)}));for(let e=0;e<this.distances.length;e++)this.distances[e][0]=0,this.distances[e][this.distances[0].length-1]=0;for(let e=0;e<this.distances[0].length;e++)this.distances[0][e]=0,this.distances[this.distances.length-1][e]=0;this.performJFA()}performJFA(){const e=this.distances.length,t=this.distances[0].length;let n=[];for(let l=0;l<e;l++)for(let e=0;e<t;e++)0===this.distances[l][e]&&n.push([e,l]);for(;n.length>0;){let e=n.length;for(let t=0;t<e;t++){const[e,t]=n.shift();this.checkAndUpdate(e,t,n)}}}checkAndUpdate(e,t,n){const l=[[-1,0],[1,0],[0,-1],[0,1],[-1,-1],[-1,1],[1,-1],[1,1]];for(const[i,a]of l){const l=e+i,s=t+a;l>=0&&l<this.distances[0].length&&s>=0&&s<this.distances.length&&this.distances[s][l]>this.distances[t][e]+1&&(this.distances[s][l]=this.distances[t][e]+1,n.push([l,s]))}}getDistance(e,t){const n=e-this.startX,l=t-this.startY;return n>=0&&l>=0&&n<this.distances[0].length&&l<this.distances.length?this.distances[l][n]:1/0}}var $n;!function(e){e.intersecting="INTERSECTING",e.contained="CONTAINED"}($n||($n={}));class el{cells=new Map;lines=new Map;lineMeta=new Map;distanceCalculator;nextLineId=0;cellSize;faceCellIndicesCache=new Map;aabbLineIntersectionCache=new Map;constructor(e,t){this.cellSize=e,t&&this.addLines(t)}getCellBounds(){let e=0,t=0,n=0,l=0;return this.cells.forEach(((i,a)=>{const[s,o]=this.getCellXYfromIndex(a);e=Math.min(e,s),t=Math.min(t,o),n=Math.max(n,s),l=Math.max(l,o)})),{width:n-e,height:l-t,minX:e,minY:t,maxX:n,maxY:l}}getCellIndex(e,t){return`${f(e)},${f(t)}`}getCellXYfromIndex(e){return e.split(",").map(Number)}getCellVertexFromIndex(e){let[t,n]=this.getCellXYfromIndex(e);return new Ut(t*this.cellSize,n*this.cellSize)}clear(){this.cells.clear(),this.lines.clear(),this.lineMeta.clear(),this.faceCellIndicesCache.clear(),this.aabbLineIntersectionCache.clear()}addLines(e){e.forEach((e=>this.addLine(e.line,e.meta)))}addLine(e,t){const n=this.nextLineId++;this.lines.set(n,e),this.lineMeta.set(n,t);let l=t.isClosed?e.length:e.length-1;for(let t=0;t<l;t++)this.addSegment(e[t],e[(t+1)%e.length],n);return this.aabbLineIntersectionCache.clear(),n}removeLineById(e){if(this.lines.get(e)){for(let t of this.cells.values())t.delete(e);this.lines.delete(e),this.lineMeta.delete(e),this.aabbLineIntersectionCache.clear()}}addSegment(e,t,n){let l,[i,a]=e,[o,r]=t,c=f(i/this.cellSize),d=f(a/this.cellSize),u=f(o/this.cellSize),h=f(r/this.cellSize),m=s(u-c),p=-s(h-d),b=c<u?1:-1,g=d<h?1:-1,x=m+p;for(;;){const e=this.getCellIndex(c,d);if(this.cells.has(e)||this.cells.set(e,new Set),this.cells.get(e).add(n),c===u&&d===h)break;l=2*x,l>=p&&(x+=p,c+=b),l<=m&&(x+=m,d+=g)}}getLinesIntersectingOrContainedWithinAABB(e){let t=new Set,n=f(e.minX/this.cellSize),l=f(e.maxX/this.cellSize),i=f(e.minY/this.cellSize),a=f(e.maxY/this.cellSize);for(let e=n;e<=l;e++)for(let n=i;n<=a;n++){const l=this.getCellIndex(e,n);this.cells.has(l)&&this.cells.get(l).forEach((e=>t.add(e)))}return Array.from(t).map((e=>({id:Jn(),line:this.lines.get(e),meta:this.lineMeta.get(e)})))}getAllLines(){return Array.from(this.lines).map((([e,t])=>({id:e,line:t,meta:this.lineMeta.get(e)})))}getCellsIntersectedByFace(e){const t=this.faceCellIndicesCache.get(e.id);if(t&&t.changeIndex===e.changeIndex)return t.cellIndices;const n=new Set,l=e.aabb,i=f(l.minX/this.cellSize),a=f(l.maxX/this.cellSize),s=f(l.minY/this.cellSize),o=f(l.maxY/this.cellSize);for(let t=i;t<=a;t++)for(let l=s;l<=o;l++){const i=new dn;i.expands([new Ut(t*this.cellSize,l*this.cellSize),new Ut((t+1)*this.cellSize,(l+1)*this.cellSize)]);for(let a of i.vertexList)if(e.containsPoint(a)){n.add(this.getCellIndex(t,l));break}}return this.faceCellIndicesCache.set(e.id,{changeIndex:e.changeIndex,cellIndices:n}),n}doesLineFullyIntersectFace(e,t){const n=this.lines.get(e),l=this.lineMeta.get(e);if(!n||!l)return!1;const i=t.hedges.map((e=>{let t=new dn;return t.expands([e.origin,e.nexthedge.origin]),{aabb:t,edge:e}})),a=[],s=l.isClosed?n.length:n.length-1;for(let e=0;e<s;e++){const t=new Ut(...n[e]),l=new Ut(...n[(e+1)%n.length]),s=l.x-t.x,o=l.y-t.y,r=s*s+o*o;let c=new dn;c.expands([t,l]);for(const{aabb:n,edge:d}of i){if(!n.intersects(c))continue;const i=d.intersectWithLineSegment([t,l]);if(i?.type===Wn.intersecting&&i.point){const n=((i.point.x-t.x)*s+(i.point.y-t.y)*o)/r;a.push(e+n)}}}a.sort(((e,t)=>e-t));const o=a.filter(((e,t)=>0===t||Math.abs(e-a[t-1])>g));if(o.length<2)return!1;const r=new Ut(...n[0]);let c=t.containsPoint(r)&&!t.isPointOnBoundary(r);for(let e=0;e<o.length-1;e++){c=!c;const l=o[e],i=o[e+1];if(l<g||i>s-g)continue;if(!c)continue;const a=(l+i)/2,r=Math.floor(a)%n.length,d=a-Math.floor(a),u=new Ut(...n[r]),h=new Ut(...n[(r+1)%n.length]),m=new Ut(u.x+(h.x-u.x)*d,u.y+(h.y-u.y)*d);if(t.containsPoint(m)&&!t.isPointOnBoundary(m))return!0}return!1}linesIntersectingAABB(e){const t=this.aabbLineIntersectionCache.get(e);if(t)return t;const n=new Set,l=f(e.minX/this.cellSize),i=f(e.maxX/this.cellSize),a=f(e.minY/this.cellSize),s=f(e.maxY/this.cellSize);for(let e=l;e<=i;e++)for(let t=a;t<=s;t++){const l=this.getCellIndex(e,t);this.cells.has(l)&&this.cells.get(l).forEach((e=>n.add(e)))}const o=[...n].map((e=>({constructionLine:{id:e,line:this.lines.get(e),meta:this.lineMeta.get(e)},intersectionType:$n.intersecting})));return this.aabbLineIntersectionCache.set(e,o),o}getLinesIntersectingFace(e,t=!0){const n=this.getCellsIntersectedByFace(e),l=new Set;for(const e of n){const t=this.cells.get(e);if(t)for(const e of t)l.add(e)}let i=Array.from(l);return t&&(i=i.filter((t=>this.doesLineFullyIntersectFace(t,e)))),i.map((e=>({constructionLine:{id:e,line:this.lines.get(e),meta:this.lineMeta.get(e)},intersectionType:$n.intersecting})))}getGridDistanceField(e=0,t=0){let{cellSize:n}=this;const l=new Set,i=new Set,a=[];let s=f(t/n),o=f((Y-2*t)/n),r=f(t/n),c=f((P-2*t)/n);for(let t=s;t<=o;t++)for(let n=r;n<=c;n++){const i=this.getCellIndex(t,n);(!this.cells.has(i)||this.cells.get(i)?.size<=e)&&l.add(i)}const d=(e,t)=>{const n=[e];for(;n.length>0;){const e=n.pop();if(!e||i.has(e)||!l.has(e))continue;i.add(e);const[a,s]=this.getCellXYfromIndex(e);t.indices.push(e);const o=[this.getCellIndex(a-1,s),this.getCellIndex(a+1,s),this.getCellIndex(a,s-1),this.getCellIndex(a,s+1)];for(const e of o)!i.has(e)&&l.has(e)&&n.push(e)}};l.forEach((e=>{if(!i.has(e)){const t={vertices:[],indices:[]};d(e,t),t.indices.length>1&&a.push(t)}}));let u=this.distanceCalculator||new qn(s,r,o,c);return u.initializeWithEmptyCells(l,this.getCellXYfromIndex.bind(this)),a.map((e=>{const t=new dn;let n=[];e.indices.forEach((e=>{const[t,l]=this.getCellXYfromIndex(e),i=u.getDistance(t,l);n.push([i,this.getCellVertexFromIndex(e)])}));let l=n.reduce(((e,t)=>e[0]>t[0]?e:t));return t.expands(n.map((([,e])=>e))),{aabb:t,cellCount:e.indices.length,maxDistance:l[0],cellsByDistance:n,indices:e.indices.map((e=>this.getCellVertexFromIndex(e)))}}))}}function tl(e){const[t,n,l]=e;return`oklch(${(100*(t||0)).toFixed(2)}% ${(n||0).toFixed(2)} ${(l||0).toFixed(2)})`}function nl(e){e.forEach((e=>{const[t,n,l]=e;tl(e)}))}function ll(e){const n=e.slice();for(let e=n.length-1;e>0;e--){const l=t(J.dec()*(e+1));[n[e],n[l]]=[n[l],n[e]]}return n}function il(e,t="right"){const n=e.slice();if("right"===t){const e=n.pop();void 0!==e&&n.unshift(e)}else if("left"===t){const e=n.shift();void 0!==e&&n.push(e)}return n}let al={};const sl=(e,t=5,n=0,l=Ge,i=[])=>{const a=`${e}-${n}-${t}`;if(al[a]?.min)return al[a];let s=0,o=-1/0,r=1/0,c=0,d=[],u=(t,i)=>{let a=l(yn(t,i,n,e));s+=a,c+=1,a>o&&(o=a),a<r&&(r=a),d.push(a)};if(i.length)for(let e of i)u(e.x,e.y);else for(let e=0;e<20*Be.countX;e+=Be.w/20)for(let t=0;t<20*Be.countY;t+=Be.h/20)u(e,t);let h={max:o,min:r,mean:s/c,indexValues:[],mostCommonIndex:0,leastCommonIndex:0};return d.map((e=>{let n=f(ye(e,h.min,h.max,0,t-1));h.indexValues[n]=h.indexValues[n]?h.indexValues[n]+1:1})),h.mostCommonIndex=h.indexValues.reduce(((e,t,n)=>t>h.indexValues[e]?n:e),0),h.leastCommonIndex=h.indexValues.reduce(((e,t,n)=>t<h.indexValues[e]?n:e),0),al[a]=