!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).BubbleSets={})}(this,(function(t){"use strict";function e(t,e,i,s,n,r){const h=i-t,o=s-e;let a=n-t,c=r-e,u=a*h+c*o,l=0;u<=0?l=0:(a=h-a,c=o-c,u=a*h+c*o,l=u<=0?0:u*u/(h*h+o*o));const x=a*a+c*c-l;return x<0?0:x}function i(t,e,i,s){return(t-i)*(t-i)+(e-s)*(e-s)}function s(t,e,s,n,r){return i(t,e,s,n)this.y1&&e>=this.y2)return!1;if(t>this.x1&&t>=this.x2)return!1;if(tthis.x2+i)return!1}else if(tthis.x1+i)return!1;if(this.y1this.y2+i)return!1}else if(ethis.y1+i)return!1;return!0}}var h,o;!function(t){t[t.POINT=1]="POINT",t[t.PARALLEL=2]="PARALLEL",t[t.COINCIDENT=3]="COINCIDENT",t[t.NONE=4]="NONE"}(h||(h={}));class a{constructor(t,e=0,i=0){this.state=t,this.x=e,this.y=i}}function c(t,e){const i=(e.x2-e.x1)*(t.y1-e.y1)-(e.y2-e.y1)*(t.x1-e.x1),s=(t.x2-t.x1)*(t.y1-e.y1)-(t.y2-t.y1)*(t.x1-e.x1),n=(e.y2-e.y1)*(t.x2-t.x1)-(e.x2-e.x1)*(t.y2-t.y1);if(n){const e=i/n,r=s/n;return 0<=e&&e<=1&&0<=r&&r<=1?new a(h.POINT,t.x1+e*(t.x2-t.x1),t.y1+e*(t.y2-t.y1)):new a(h.NONE)}return new a(0===i||0===s?h.COINCIDENT:h.PARALLEL)}function u(t,e){const i=(e.x2-e.x1)*(t.y1-e.y1)-(e.y2-e.y1)*(t.x1-e.x1),s=(t.x2-t.x1)*(t.y1-e.y1)-(t.y2-t.y1)*(t.x1-e.x1),n=(e.y2-e.y1)*(t.x2-t.x1)-(e.x2-e.x1)*(t.y2-t.y1);if(n){const t=i/n,e=s/n;if(0<=t&&t<=1&&0<=e&&e<=1)return t}return Number.POSITIVE_INFINITY}function l(t,e,i){const s=new Set;return t.width<=0?(s.add(o.LEFT),s.add(o.RIGHT)):et.x+t.width&&s.add(o.RIGHT),t.height<=0?(s.add(o.TOP),s.add(o.BOTTOM)):it.y+t.height&&s.add(o.BOTTOM),s}function x(t,e){let i=e.x1,s=e.y1;const n=e.x2,r=e.y2,h=Array.from(l(t,n,r));if(0===h.length)return!0;let a=l(t,i,s);for(;0!==a.size;){for(const t of h)if(a.has(t))return!1;if(a.has(o.RIGHT)||a.has(o.LEFT)){let e=t.x;a.has(o.RIGHT)&&(e+=t.width),s+=(e-i)*(r-s)/(n-i),i=e}else{let e=t.y;a.has(o.BOTTOM)&&(e+=t.height),i+=(e-s)*(n-i)/(r-s),s=e}a=l(t,i,s)}return!0}function f(t,e){let i=Number.POSITIVE_INFINITY,s=0;function n(t,n,h,o){let a=u(e,new r(t,n,h,o));a=Math.abs(a-.5),a>=0&&a<=1&&(s++,a1?i:(n(t.x,t.y2,t.x2,t.y2),s>1?i:(n(t.x2,t.y,t.x2,t.y2),0===s?-1:i))}function y(t,e){let i=0;const s=c(t,new r(e.x,e.y,e.x2,e.y));i+=s.state===h.POINT?1:0;const n=c(t,new r(e.x,e.y,e.x,e.y2));i+=n.state===h.POINT?1:0;const o=c(t,new r(e.x,e.y2,e.x2,e.y2));i+=o.state===h.POINT?1:0;const a=c(t,new r(e.x2,e.y,e.x2,e.y2));return i+=a.state===h.POINT?1:0,{top:s,left:n,bottom:o,right:a,count:i}}!function(t){t[t.LEFT=0]="LEFT",t[t.TOP=1]="TOP",t[t.RIGHT=2]="RIGHT",t[t.BOTTOM=3]="BOTTOM"}(o||(o={}));class d{constructor(t,e,i,s){this.x=t,this.y=e,this.width=i,this.height=s}get x2(){return this.x+this.width}get y2(){return this.y+this.height}get cx(){return this.x+this.width/2}get cy(){return this.y+this.height/2}get radius(){return Math.max(this.width,this.height)/2}static from(t){return new d(t.x,t.y,t.width,t.height)}equals(t){return this.x===t.x&&this.y===t.y&&this.width===t.width&&this.height===t.height}clone(){return new d(this.x,this.y,this.width,this.height)}add(t){const e=Math.min(this.x,t.x),i=Math.min(this.y,t.y),s=Math.max(this.x2,t.x+t.width),n=Math.max(this.y2,t.y+t.height);this.x=e,this.y=i,this.width=s-e,this.height=n-i}addPoint(t){const e=Math.min(this.x,t.x),i=Math.min(this.y,t.y),s=Math.max(this.x2,t.x),n=Math.max(this.y2,t.y);this.x=e,this.y=i,this.width=s-e,this.height=n-i}toString(){return`Rectangle[x=${this.x}, y=${this.y}, w=${this.width}, h=${this.height}]`}draw(t){t.rect(this.x,this.y,this.width,this.height)}containsPt(t,e){return t>=this.x&&t<=this.x2&&e>=this.y&&e<=this.y2}get area(){return this.width*this.height}intersects(t){return!(this.area<=0||t.width<=0||t.height<=0)&&(t.x+t.width>this.x&&t.y+t.height>this.y&&t.x=this.width?this.width-1:t}boundY(t){return t=this.height?this.height-1:t}scaleX(t){return this.boundX(Math.floor((t-this.pixelX)/this.pixelGroup))}scaleY(t){return this.boundY(Math.floor((t-this.pixelY)/this.pixelGroup))}scale(t){const e=this.scaleX(t.x),i=this.scaleY(t.y),s=this.boundX(Math.ceil((t.x+t.width-this.pixelX)/this.pixelGroup)),n=this.boundY(Math.ceil((t.y+t.height-this.pixelY)/this.pixelGroup));return new d(e,i,s-e,n-i)}invertScaleX(t){return Math.round(t*this.pixelGroup+this.pixelX)}invertScaleY(t){return Math.round(t*this.pixelGroup+this.pixelY)}addPadding(t,e){const i=Math.ceil(e/this.pixelGroup),s=this.boundX(t.x-i),n=this.boundY(t.y-i),r=this.boundX(t.x2+i),h=this.boundY(t.y2+i);return new d(s,n,r-s,h-n)}get(t,e){return t<0||e<0||t>=this.width||e>=this.height?Number.NaN:this.area[t+e*this.width]}inc(t,e,i){t<0||e<0||t>=this.width||e>=this.height||(this.area[t+e*this.width]+=i)}set(t,e,i){t<0||e<0||t>=this.width||e>=this.height||(this.area[t+e*this.width]=i)}incArea(t,e){if(t.width<=0||t.height<=0||0===e)return;const i=this.width,s=t.width,n=Math.max(0,t.i),r=Math.max(0,t.j),h=Math.min(t.i+t.width,i),o=Math.min(t.j+t.height,this.height);if(!(o<=0||h<=0||n>=i||o>=this.height))for(let a=r;aMath.min(t,e)),Number.POSITIVE_INFINITY),s=this.area.reduce(((t,e)=>Math.max(t,e)),Number.NEGATIVE_INFINITY),n=t=>(t-i)/(s-i);t.scale(this.pixelGroup,this.pixelGroup);for(let e=0;ee?"black":"white",t.fillRect(i,s,1,1)}t.restore()}}}function m(t,e){const i=t=>({x:t.x-e,y:t.y-e,width:t.width+2*e,height:t.height+2*e});return Array.isArray(t)?t.map(i):i(t)}function b(t,i,s){return M(Object.assign(n(t),{distSquare:(i,s)=>e(t.x1,t.y1,t.x2,t.y2,i,s)}),i,s)}function M(t,e,i){const s=m(t,i),n=e.scale(s),r=e.createSub(n,s);return function(t,e,i,s){const n=i*i;for(let r=0;rt.distSquare(e,i))),r}function E(t,e,i){const s=e.scale(t),n=e.addPadding(s,i),r=e.createSub(n,{x:t.x-i,y:t.y-i}),h=s.x-n.x,o=s.y-n.y,a=n.x2-s.x2,c=n.y2-s.y2,u=n.width-h-a,l=n.height-o-c,x=i*i;r.fillArea({x:h,y:o,width:u+1,height:l+1},x);const f=[0],y=Math.max(o,h,a,c);{const n=e.invertScaleX(s.x+s.width/2);for(let r=1;r{e+=t.cx,i+=t.cy})),e/=t.length,i/=t.length,t.map((t=>{const s=e-t.cx,n=i-t.cy;return[t,s*s+n*n]})).sort(((t,e)=>t[1]-e[1])).map((t=>t[0]))}(t);return h.map(((t,o)=>{const a=h.slice(0,o);return function(t,e,s,n,h){const o=I(e.cx,e.cy),a=function(t,e,s){let n=Number.POSITIVE_INFINITY;return e.reduce(((e,h)=>{const o=i(t.x,t.y,h.cx,h.cy);if(o>n)return e;const a=new r(t.x,t.y,h.cx,h.cy),c=function(t,e){return t.reduce(((t,i)=>x(i,e)&&function(t,e){function i(t,i,s,n){let h=u(e,new r(t,i,s,n));return h=Math.abs(h-.5),h>=0&&h<=1?1:0}let s=i(t.x,t.y,t.x2,t.y);return s+=i(t.x,t.y,t.x,t.y2),s>1||(s+=i(t.x,t.y2,t.x2,t.y2),s>1||(s+=i(t.x2,t.y,t.x2,t.y2),s>0))}(i,e)?t+1:t),0)}(s,a);return o*(c+1)*(c+1)0;){const t=h.pop(),i=O(e,t),a=i?y(t,i):null;if(!i||!a||2!==a.count){o||n.push(t);continue}let c=s,u=S(i,c,a,!0),l=R(u,h)||R(u,n),x=T(u,e);for(;!l&&x&&c>=1;)c/=1.5,u=S(i,c,a,!0),l=R(u,h)||R(u,n),x=T(u,e);if(!u||l||x||(h.push(new r(t.x1,t.y1,u.x,u.y)),h.push(new r(u.x,u.y,t.x2,t.y2)),o=!0),o)continue;c=s,u=S(i,c,a,!1);let f=R(u,h)||R(u,n);for(x=T(u,e);!f&&x&&c>=1;)c/=1.5,u=S(i,c,a,!1),f=R(u,h)||R(u,n),x=T(u,e);u&&!f&&(h.push(new r(t.x1,t.y1,u.x,u.y)),h.push(new r(u.x,u.y,t.x2,t.y2)),o=!0),o||n.push(t)}for(;h.length>0;)n.push(h.pop());return n}(new r(o.x,o.y,a.cx,a.cy),t,n,h);return function(t,e){const i=[];for(;t.length>0;){const s=t.pop();if(0===t.length){i.push(s);break}const n=t.pop(),h=new r(s.x1,s.y1,n.x2,n.y2);O(e,h)?(i.push(s),t.push(n)):t.push(h)}return i}(c,t)}(e,t,a,s,n)})).flat()}function T(t,e){return e.some((e=>e.containsPt(t.x,t.y)))}function R(t,e){return e.some((e=>!!s(e.x1,e.y1,t.x,t.y,.001)||!!s(e.x2,e.y2,t.x,t.y,.001)))}function O(t,e){let i=Number.POSITIVE_INFINITY,s=null;for(const n of t){if(!x(n,e))continue;const t=f(n,e);t>=0&&ta.y?I(t.x-e,t.y-e):I(t.x2+e,t.y-e):r.yo.x?I(t.x-e,t.y-e):I(t.x-e,t.y2+e):n.xa.y?I(t.x2+e,t.y2+e):I(t.x-e,t.y2+e):r.yo.x?I(t.x2+e,t.y2+e):I(t.x2+e,t.y-e):n.xn)return!1}return!0}function v(t,e){switch(t){case-2:return(((3-e)*e-3)*e+1)/6;case-1:return((3*e-6)*e*e+4)/6;case 0:return(((-3*e+3)*e+3)*e+1)/6;case 1:return e*e*e/6;default:throw new Error("unknown error")}}class j{constructor(t=[],e=!0){this.points=t,this.closed=e}get(t){const e=t,i=this.points.length;return t<0?this.closed?this.get(t+i):this.points[0]:t>=i?this.closed?this.get(t-i):this.points[i-1]:this.points[e]}get length(){return this.points.length}toString(t=1/0){const e=this.points;if(0===e.length)return"";const i="function"==typeof t?t:function(t){if(!Number.isFinite(t))return t=>t;if(0===t)return Math.round;const e=Math.pow(10,t);return t=>Math.round(t*e)/e}(t);let s="M";for(const t of e)s+=`${i(t.x)},${i(t.y)} L`;return s=s.slice(0,-1),this.closed&&(s+=" Z"),s}draw(t){const e=this.points;if(0!==e.length){t.beginPath(),t.moveTo(e[0].x,e[0].y);for(const i of e)t.lineTo(i.x,i.y);this.closed&&t.closePath()}}sample(t){return function(t=8){return e=>{let i=t,s=e.length;if(i>1)for(s=Math.floor(e.length/i);s<3&&i>1;)i-=1,s=Math.floor(e.length/i);const n=[];for(let t=0,r=0;r{if(t<0||e.length<3)return e;const i=[];let s=0;const n=t*t;for(;s{if(i.length<3)return i;const s=[],n=i.closed,r=i.length+3-1+(n?0:2);s.push(e(i,2-(n?0:2),0));for(let h=2-(n?0:2);he.containsPt(t.cx,t.cy)&&this.withinArea(t.cx,t.cy)))}withinArea(t,e){if(0===this.length)return!1;let i=0;const s=this.points[0],n=new r(s.x,s.y,s.x,s.y);for(let s=1;se?n+r:n}function r(t,e){let i=0;return i=n(t,e,i,1),i=n(t+1,e,i,2),i=n(t,e+1,i,4),i=n(t+1,e+1,i,8),Number.isNaN(i)?-1:i}let h=1;function o(e,i){let n=e,o=i,a=t.invertScaleX(n),c=t.invertScaleY(o);for(let e=0;eY(e.raw,t)));return!(e<0)&&(this.members.splice(e,1),this.dirty.add(F.MEMBERS),!0)}removeNonMember(t){const e=this.nonMembers.findIndex((e=>Y(e.raw,t)));return!(e<0)&&(this.nonMembers.splice(e,1),this.dirty.add(F.NON_MEMBERS),!0)}removeEdge(t){const e=this.edges.findIndex((e=>e.obj.equals(t)));return!(e<0)&&(this.edges.splice(e,1),this.dirty.add(F.NON_MEMBERS),!0)}pushNonMember(...t){if(0!==t.length){this.dirty.add(F.NON_MEMBERS);for(const e of t)this.nonMembers.push({raw:e,obj:L(e)?p.from(e):d.from(e),area:null})}}pushEdge(...t){if(0!==t.length){this.dirty.add(F.EDGES);for(const e of t)this.edges.push({raw:e,obj:r.from(e),area:null})}}update(){const t=this.dirty.has(F.MEMBERS),e=this.dirty.has(F.NON_MEMBERS);let i=this.dirty.has(F.EDGES);this.dirty.clear();const s=this.members.map((t=>t.obj));if(this.o.virtualEdges&&(t||e)){const t=N(s,this.nonMembers.map((t=>t.obj)),this.o.maxRoutingIterations,this.o.morphBuffer),e=new Map(this.virtualEdges.map((t=>[t.obj.toString(),t.area])));this.virtualEdges=t.map((t=>{var i;return{raw:t,obj:t,area:null!==(i=e.get(t.toString()))&&void 0!==i?i:null}})),i=!0}let n=!1;if(t||i){const t=q(s,this.virtualEdges.concat(this.edges).map((t=>t.obj))),e=Math.max(this.o.edgeR1,this.o.nodeR1)+this.o.morphBuffer,i=d.from(m(t,e));i.equals(this.activeRegion)||(n=!0,this.activeRegion=i)}if(n){const t=Math.ceil(this.activeRegion.width/this.o.pixelGroup),e=Math.ceil(this.activeRegion.height/this.o.pixelGroup);this.activeRegion.x!==this.potentialArea.pixelX||this.activeRegion.y!==this.potentialArea.pixelY?(this.potentialArea=w.fromPixelRegion(this.activeRegion,this.o.pixelGroup),this.members.forEach((t=>t.area=null)),this.nonMembers.forEach((t=>t.area=null)),this.edges.forEach((t=>t.area=null)),this.virtualEdges.forEach((t=>t.area=null))):t===this.potentialArea.width&&e===this.potentialArea.height||(this.potentialArea=w.fromPixelRegion(this.activeRegion,this.o.pixelGroup))}const r=new Map,h=t=>{if(t.area){const e=`${t.obj.width}x${t.obj.height}x${t.obj instanceof d?"R":"C"}`;r.set(e,t.area)}},o=t=>{if(t.area)return;const e=`${t.obj.width}x${t.obj.height}x${t.obj instanceof d?"R":"C"}`;if(r.has(e)){const i=r.get(e);return void(t.area=this.potentialArea.copy(i,{x:t.obj.x-this.o.nodeR1,y:t.obj.y-this.o.nodeR1}))}const i=t.obj instanceof d?E(t.obj,this.potentialArea,this.o.nodeR1):M(t.obj,this.potentialArea,this.o.nodeR1);t.area=i,r.set(e,i)};this.members.forEach(h),this.nonMembers.forEach(h),this.members.forEach(o),this.nonMembers.forEach((t=>{this.activeRegion.intersects(t.obj)?o(t):t.area=null})),this.edges.forEach((t=>{t.area||(t.area=b(t.obj,this.potentialArea,this.o.edgeR1))})),this.virtualEdges.forEach((t=>{t.area||(t.area=b(t.obj,this.potentialArea,this.o.edgeR1))}))}drawMembers(t){for(const e of this.members)e.obj.draw(t)}drawNonMembers(t){for(const e of this.nonMembers)e.obj.draw(t)}drawEdges(t){for(const e of this.edges)e.obj.draw(t)}drawPotentialArea(t,e=!0){this.potentialArea.draw(t,e)}compute(){if(0===this.members.length)return new j([]);this.dirty.size>0&&this.update();const{o:t,potentialArea:e}=this,i=this.members.map((t=>t.area)),s=this.virtualEdges.concat(this.edges).map((t=>t.area)),n=this.nonMembers.filter((t=>null!=t.area)).map((t=>t.area)),r=this.members.map((t=>t.obj));return X(e,i,s,n,(t=>t.containsElements(r)),t)}}function X(t,e,i,s,n,r={}){const h=Object.assign({},B,r);let o=h.threshold,a=h.memberInfluenceFactor,c=h.edgeInfluenceFactor,u=h.nonMemberInfluenceFactor;const l=(h.nodeR0-h.nodeR1)*(h.nodeR0-h.nodeR1),x=(h.edgeR0-h.edgeR1)*(h.edgeR0-h.edgeR1);for(let r=0;r0))break;u*=.8}}return new j([])}function q(t,e){if(0===t.length)return new d(0,0,0,0);const i=d.from(t[0]);for(const e of t)i.add(e);for(const t of e)i.add(n(t));return i}t.Area=w,t.BubbleSets=$,t.Circle=p,t.Line=r,t.PointPath=j,t.Rectangle=d,t.addPadding=m,t.boundingBox=g,t.calculatePotentialOutline=X,t.calculateVirtualEdges=N,t.circle=function(t,e,i){return{cx:t,cy:e,radius:i}},t.createGenericInfluenceArea=M,t.createLineInfluenceArea=b,t.createOutline=function(t,e=[],i=[],s={}){if(0===t.length)return new j([]);const n=new $(s);return n.pushMember(...t),n.pushNonMember(...e),n.pushEdge(...i),n.compute()},t.createRectangleInfluenceArea=E,t.default=$,t.defaultOptions=B,t.line=function(t,e,i,s){return{x1:t,y1:e,x2:i,y2:s}},t.lineBoundingBox=n,t.point=I,t.rect=function(t,e,i,s){return{x:t,y:e,width:i,height:s}},t.unionBoundingBox=q,Object.defineProperty(t,"__esModule",{value:!0})})); //# sourceMappingURL=index.umd.min.js.map