earcut 2.2.4 → 3.0.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 +1 @@
1
- !function(e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).earcut=e()}(function(){return function r(x,i,u){function f(n,e){if(!i[n]){if(!x[n]){var t="function"==typeof require&&require;if(!e&&t)return t(n,!0);if(o)return o(n,!0);throw(e=new Error("Cannot find module '"+n+"'")).code="MODULE_NOT_FOUND",e}t=i[n]={exports:{}},x[n][0].call(t.exports,function(e){return f(x[n][1][e]||e)},t,t.exports,r,x,i,u)}return i[n].exports}for(var o="function"==typeof require&&require,e=0;e<u.length;e++)f(u[e]);return f}({1:[function(e,n,t){"use strict";function r(e,n,t){t=t||2;var r,x,i,u,f,o=n&&n.length,v=o?n[0]*t:e.length,p=s(e,0,v,t,!0),y=[];if(p&&p.next!==p.prev){if(o&&(p=function(e,n,t,r){var x,i,u,f,o=[];for(x=0,i=n.length;x<i;x++)f=n[x]*r,u=x<i-1?n[x+1]*r:e.length,(f=s(e,f,u,r,!1))===f.next&&(f.steiner=!0),o.push(function(e){var n=e,t=e;for(;(n.x<t.x||n.x===t.x&&n.y<t.y)&&(t=n),n=n.next,n!==e;);return t}(f));for(o.sort(c),x=0;x<o.length;x++)t=function(e,n){var t=function(e,n){var t,r=n,x=e.x,i=e.y,u=-1/0;do{if(i<=r.y&&i>=r.next.y&&r.next.y!==r.y){var f=r.x+(i-r.y)*(r.next.x-r.x)/(r.next.y-r.y);if(f<=x&&u<f&&(u=f,t=r.x<r.next.x?r:r.next,f===x))return t}}while(r=r.next,r!==n);if(!t)return null;var o,v=t,p=t.x,y=t.y,a=1/0;r=t;for(;x>=r.x&&r.x>=p&&x!==r.x&&D(i<y?x:u,i,p,y,i<y?u:x,i,r.x,r.y)&&(o=Math.abs(i-r.y)/(x-r.x),_(r,e)&&(o<a||o===a&&(r.x>t.x||r.x===t.x&&function(e,n){return E(e.prev,e,n.prev)<0&&E(n.next,e,e.next)<0}(t,r)))&&(t=r,a=o)),r=r.next,r!==v;);return t}(e,n);if(!t)return n;n=j(t,e);return q(n,n.next),q(t,t.next)}(o[x],t);return t}(e,n,p,t)),e.length>80*t){for(var a=r=e[0],l=x=e[1],h=t;h<v;h+=t)(i=e[h])<a&&(a=i),(u=e[h+1])<l&&(l=u),r<i&&(r=i),x<u&&(x=u);f=0!==(f=Math.max(r-a,x-l))?32767/f:0}O(p,y,t,a,l,f,0)}return y}function s(e,n,t,r,x){var i,u;if(x===0<d(e,n,t,r))for(i=n;i<t;i+=r)u=f(i,e[i],e[i+1],u);else for(i=t-r;n<=i;i-=r)u=f(i,e[i],e[i+1],u);return u&&N(u,u.next)&&(C(u),u=u.next),u}function q(e,n){if(!e)return e;n=n||e;var t,r=e;do{if(t=!1,r.steiner||!N(r,r.next)&&0!==E(r.prev,r,r.next))r=r.next;else{if(C(r),(r=n=r.prev)===r.next)break;t=!0}}while(t||r!==n);return n}function O(e,n,t,r,x,i,u){if(e){if(!u&&i){for(var f=e,o=r,v=x,p=i,y=f;0===y.z&&(y.z=k(y.x,y.y,o,v,p)),y.prevZ=y.prev,y.nextZ=y.next,(y=y.next)!==f;);y.prevZ.nextZ=null,y.prevZ=null;var a,l,h,s,c,d,Z,g,w=y,M=1;do{for(l=w,c=w=null,d=0;l;){for(d++,h=l,a=Z=0;a<M&&(Z++,h=h.nextZ);a++);for(g=M;0<Z||0<g&&h;)0!==Z&&(0===g||!h||l.z<=h.z)?(l=(s=l).nextZ,Z--):(h=(s=h).nextZ,g--),c?c.nextZ=s:w=s,s.prevZ=c,c=s;l=h}}while(c.nextZ=null,M*=2,1<d)}for(var b,m,z=e;e.prev!==e.next;)if(b=e.prev,m=e.next,i?function(e,n,t,r){var x=e.prev,i=e,u=e.next;if(0<=E(x,i,u))return;var f=x.x,o=i.x,v=u.x,p=x.y,y=i.y,a=u.y,l=f<o?f<v?f:v:o<v?o:v,h=p<y?p<a?p:a:y<a?y:a,s=o<f?v<f?f:v:v<o?o:v,c=y<p?a<p?p:a:a<y?y:a,d=k(l,h,n,t,r),Z=k(s,c,n,t,r),g=e.prevZ,w=e.nextZ;for(;g&&g.z>=d&&w&&w.z<=Z;){if(g.x>=l&&g.x<=s&&g.y>=h&&g.y<=c&&g!==x&&g!==u&&D(f,p,o,y,v,a,g.x,g.y)&&0<=E(g.prev,g,g.next))return;if(g=g.prevZ,w.x>=l&&w.x<=s&&w.y>=h&&w.y<=c&&w!==x&&w!==u&&D(f,p,o,y,v,a,w.x,w.y)&&0<=E(w.prev,w,w.next))return;w=w.nextZ}for(;g&&g.z>=d;){if(g.x>=l&&g.x<=s&&g.y>=h&&g.y<=c&&g!==x&&g!==u&&D(f,p,o,y,v,a,g.x,g.y)&&0<=E(g.prev,g,g.next))return;g=g.prevZ}for(;w&&w.z<=Z;){if(w.x>=l&&w.x<=s&&w.y>=h&&w.y<=c&&w!==x&&w!==u&&D(f,p,o,y,v,a,w.x,w.y)&&0<=E(w.prev,w,w.next))return;w=w.nextZ}return 1}(e,r,x,i):function(e){var n=e.prev,t=e,e=e.next;if(0<=E(n,t,e))return;var r=n.x,x=t.x,i=e.x,u=n.y,f=t.y,o=e.y,v=r<x?r<i?r:i:x<i?x:i,p=u<f?u<o?u:o:f<o?f:o,y=x<r?i<r?r:i:i<x?x:i,a=f<u?o<u?u:o:o<f?f:o,l=e.next;for(;l!==n;){if(l.x>=v&&l.x<=y&&l.y>=p&&l.y<=a&&D(r,u,x,f,i,o,l.x,l.y)&&0<=E(l.prev,l,l.next))return;l=l.next}return 1}(e))n.push(b.i/t|0),n.push(e.i/t|0),n.push(m.i/t|0),C(e),e=m.next,z=m.next;else if((e=m)===z){u?1===u?O(e=function(e,n,t){var r=e;do{var x=r.prev,i=r.next.next}while(!N(x,i)&&U(x,r,r.next,i)&&_(x,i)&&_(i,x)&&(n.push(x.i/t|0),n.push(r.i/t|0),n.push(i.i/t|0),C(r),C(r.next),r=e=i),r=r.next,r!==e);return q(r)}(q(e),n,t),n,t,r,x,i,2):2===u&&function(e,n,t,r,x,i){var u=e;do{for(var f,o=u.next.next;o!==u.prev;){if(u.i!==o.i&&function(e,n){return e.next.i!==n.i&&e.prev.i!==n.i&&!function(e,n){var t=e;do{if(t.i!==e.i&&t.next.i!==e.i&&t.i!==n.i&&t.next.i!==n.i&&U(t,t.next,e,n))return 1}while(t=t.next,t!==e);return}(e,n)&&(_(e,n)&&_(n,e)&&function(e,n){var t=e,r=!1,x=(e.x+n.x)/2,i=(e.y+n.y)/2;for(;t.y>i!=t.next.y>i&&t.next.y!==t.y&&x<(t.next.x-t.x)*(i-t.y)/(t.next.y-t.y)+t.x&&(r=!r),t=t.next,t!==e;);return r}(e,n)&&(E(e.prev,e,n.prev)||E(e,n.prev,n))||N(e,n)&&0<E(e.prev,e,e.next)&&0<E(n.prev,n,n.next))}(u,o))return f=j(u,o),u=q(u,u.next),f=q(f,f.next),O(u,n,t,r,x,i,0),O(f,n,t,r,x,i,0);o=o.next}}while(u=u.next,u!==e)}(e,n,t,r,x,i):O(q(e),n,t,r,x,i,1);break}}}function c(e,n){return e.x-n.x}function k(e,n,t,r,x){return(e=1431655765&((e=858993459&((e=252645135&((e=16711935&((e=(e-t)*x|0)|e<<8))|e<<4))|e<<2))|e<<1))|(n=1431655765&((n=858993459&((n=252645135&((n=16711935&((n=(n-r)*x|0)|n<<8))|n<<4))|n<<2))|n<<1))<<1}function D(e,n,t,r,x,i,u,f){return(e-u)*(i-f)<=(x-u)*(n-f)&&(t-u)*(n-f)<=(e-u)*(r-f)&&(x-u)*(r-f)<=(t-u)*(i-f)}function E(e,n,t){return(n.y-e.y)*(t.x-n.x)-(n.x-e.x)*(t.y-n.y)}function N(e,n){return e.x===n.x&&e.y===n.y}function U(e,n,t,r){var x=v(E(e,n,t)),i=v(E(e,n,r)),u=v(E(t,r,e)),f=v(E(t,r,n));return x!==i&&u!==f||(0===x&&o(e,t,n)||(0===i&&o(e,r,n)||(0===u&&o(t,e,r)||!(0!==f||!o(t,n,r)))))}function o(e,n,t){return n.x<=Math.max(e.x,t.x)&&n.x>=Math.min(e.x,t.x)&&n.y<=Math.max(e.y,t.y)&&n.y>=Math.min(e.y,t.y)}function v(e){return 0<e?1:e<0?-1:0}function _(e,n){return E(e.prev,e,e.next)<0?0<=E(e,n,e.next)&&0<=E(e,e.prev,n):E(e,n,e.prev)<0||E(e,e.next,n)<0}function j(e,n){var t=new u(e.i,e.x,e.y),r=new u(n.i,n.x,n.y),x=e.next,i=n.prev;return(e.next=n).prev=e,(t.next=x).prev=t,(r.next=t).prev=r,(i.next=r).prev=i,r}function f(e,n,t,r){e=new u(e,n,t);return r?(e.next=r.next,(e.prev=r).next.prev=e,r.next=e):(e.prev=e).next=e,e}function C(e){e.next.prev=e.prev,e.prev.next=e.next,e.prevZ&&(e.prevZ.nextZ=e.nextZ),e.nextZ&&(e.nextZ.prevZ=e.prevZ)}function u(e,n,t){this.i=e,this.x=n,this.y=t,this.prev=null,this.next=null,this.z=0,this.prevZ=null,this.nextZ=null,this.steiner=!1}function d(e,n,t,r){for(var x=0,i=n,u=t-r;i<t;i+=r)x+=(e[u]-e[i])*(e[i+1]+e[u+1]),u=i;return x}n.exports=r,(n.exports.default=r).deviation=function(e,n,t,r){var x=n&&n.length,i=x?n[0]*t:e.length,u=Math.abs(d(e,0,i,t));if(x)for(var f=0,o=n.length;f<o;f++){var v=n[f]*t,p=f<o-1?n[f+1]*t:e.length;u-=Math.abs(d(e,v,p,t))}for(var y=0,f=0;f<r.length;f+=3){var a=r[f]*t,l=r[f+1]*t,h=r[f+2]*t;y+=Math.abs((e[a]-e[h])*(e[1+l]-e[1+a])-(e[a]-e[l])*(e[1+h]-e[1+a]))}return 0===u&&0===y?0:Math.abs((y-u)/u)},r.flatten=function(e){for(var n=e[0][0].length,t={vertices:[],holes:[],dimensions:n},r=0,x=0;x<e.length;x++){for(var i=0;i<e[x].length;i++)for(var u=0;u<n;u++)t.vertices.push(e[x][i][u]);0<x&&(r+=e[x-1].length,t.holes.push(r))}return t}},{}]},{},[1])(1)});
1
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).earcut={})}(this,(function(e){"use strict";function t(e,t,n,r,x){let i;if(x===j(e,t,n,r)>0)for(let x=t;x<n;x+=r)i=w(x/r|0,e[x],e[x+1],i);else for(let x=n-r;x>=t;x-=r)i=w(x/r|0,e[x],e[x+1],i);return i&&a(i,i.next)&&(z(i),i=i.next),i}function n(e,t){if(!e)return e;t||(t=e);let n,r=e;do{if(n=!1,r.steiner||!a(r,r.next)&&0!==h(r.prev,r,r.next))r=r.next;else{if(z(r),r=t=r.prev,r===r.next)break;n=!0}}while(n||r!==t);return t}function r(e,t,f,l,c,p,s){if(!e)return;!s&&p&&function(e,t,n,r){let x=e;do{0===x.z&&(x.z=y(x.x,x.y,t,n,r)),x.prevZ=x.prev,x.nextZ=x.next,x=x.next}while(x!==e);x.prevZ.nextZ=null,x.prevZ=null,function(e){let t,n=1;do{let r,x=e;e=null;let i=null;for(t=0;x;){t++;let o=x,u=0;for(let e=0;e<n&&(u++,o=o.nextZ,o);e++);let f=n;for(;u>0||f>0&&o;)0!==u&&(0===f||!o||x.z<=o.z)?(r=x,x=x.nextZ,u--):(r=o,o=o.nextZ,f--),i?i.nextZ=r:e=r,r.prevZ=i,i=r;x=o}i.nextZ=null,n*=2}while(t>1)}(x)}(e,l,c,p);let v=e;for(;e.prev!==e.next;){const y=e.prev,h=e.next;if(p?i(e,l,c,p):x(e))t.push(y.i,e.i,h.i),z(e),e=h.next,v=h.next;else if((e=h)===v){s?1===s?r(e=o(n(e),t),t,f,l,c,p,2):2===s&&u(e,t,f,l,c,p):r(n(e),t,f,l,c,p,1);break}}}function x(e){const t=e.prev,n=e,r=e.next;if(h(t,n,r)>=0)return!1;const x=t.x,i=n.x,o=r.x,u=t.y,f=n.y,l=r.y,c=x<i?x<o?x:o:i<o?i:o,y=u<f?u<l?u:l:f<l?f:l,p=x>i?x>o?x:o:i>o?i:o,v=u>f?u>l?u:l:f>l?f:l;let a=r.next;for(;a!==t;){if(a.x>=c&&a.x<=p&&a.y>=y&&a.y<=v&&s(x,u,i,f,o,l,a.x,a.y)&&h(a.prev,a,a.next)>=0)return!1;a=a.next}return!0}function i(e,t,n,r){const x=e.prev,i=e,o=e.next;if(h(x,i,o)>=0)return!1;const u=x.x,f=i.x,l=o.x,c=x.y,p=i.y,v=o.y,a=u<f?u<l?u:l:f<l?f:l,Z=c<p?c<v?c:v:p<v?p:v,d=u>f?u>l?u:l:f>l?f:l,g=c>p?c>v?c:v:p>v?p:v,b=y(a,Z,t,n,r),M=y(d,g,t,n,r);let w=e.prevZ,z=e.nextZ;for(;w&&w.z>=b&&z&&z.z<=M;){if(w.x>=a&&w.x<=d&&w.y>=Z&&w.y<=g&&w!==x&&w!==o&&s(u,c,f,p,l,v,w.x,w.y)&&h(w.prev,w,w.next)>=0)return!1;if(w=w.prevZ,z.x>=a&&z.x<=d&&z.y>=Z&&z.y<=g&&z!==x&&z!==o&&s(u,c,f,p,l,v,z.x,z.y)&&h(z.prev,z,z.next)>=0)return!1;z=z.nextZ}for(;w&&w.z>=b;){if(w.x>=a&&w.x<=d&&w.y>=Z&&w.y<=g&&w!==x&&w!==o&&s(u,c,f,p,l,v,w.x,w.y)&&h(w.prev,w,w.next)>=0)return!1;w=w.prevZ}for(;z&&z.z<=M;){if(z.x>=a&&z.x<=d&&z.y>=Z&&z.y<=g&&z!==x&&z!==o&&s(u,c,f,p,l,v,z.x,z.y)&&h(z.prev,z,z.next)>=0)return!1;z=z.nextZ}return!0}function o(e,t){let r=e;do{const n=r.prev,x=r.next.next;!a(n,x)&&Z(n,r,r.next,x)&&b(n,x)&&b(x,n)&&(t.push(n.i,r.i,x.i),z(r),z(r.next),r=e=x),r=r.next}while(r!==e);return n(r)}function u(e,t,x,i,o,u){let f=e;do{let e=f.next.next;for(;e!==f.prev;){if(f.i!==e.i&&v(f,e)){let l=M(f,e);return f=n(f,f.next),l=n(l,l.next),r(f,t,x,i,o,u,0),void r(l,t,x,i,o,u,0)}e=e.next}f=f.next}while(f!==e)}function f(e,t){return e.x-t.x}function l(e,t){const r=function(e,t){let n=t;const r=e.x,x=e.y;let i,o=-1/0;do{if(x<=n.y&&x>=n.next.y&&n.next.y!==n.y){const e=n.x+(x-n.y)*(n.next.x-n.x)/(n.next.y-n.y);if(e<=r&&e>o&&(o=e,i=n.x<n.next.x?n:n.next,e===r))return i}n=n.next}while(n!==t);if(!i)return null;const u=i,f=i.x,l=i.y;let y=1/0;n=i;do{if(r>=n.x&&n.x>=f&&r!==n.x&&s(x<l?r:o,x,f,l,x<l?o:r,x,n.x,n.y)){const t=Math.abs(x-n.y)/(r-n.x);b(n,e)&&(t<y||t===y&&(n.x>i.x||n.x===i.x&&c(i,n)))&&(i=n,y=t)}n=n.next}while(n!==u);return i}(e,t);if(!r)return t;const x=M(r,e);return n(x,x.next),n(r,r.next)}function c(e,t){return h(e.prev,e,t.prev)<0&&h(t.next,e,e.next)<0}function y(e,t,n,r,x){return(e=1431655765&((e=858993459&((e=252645135&((e=16711935&((e=(e-n)*x|0)|e<<8))|e<<4))|e<<2))|e<<1))|(t=1431655765&((t=858993459&((t=252645135&((t=16711935&((t=(t-r)*x|0)|t<<8))|t<<4))|t<<2))|t<<1))<<1}function p(e){let t=e,n=e;do{(t.x<n.x||t.x===n.x&&t.y<n.y)&&(n=t),t=t.next}while(t!==e);return n}function s(e,t,n,r,x,i,o,u){return(x-o)*(t-u)>=(e-o)*(i-u)&&(e-o)*(r-u)>=(n-o)*(t-u)&&(n-o)*(i-u)>=(x-o)*(r-u)}function v(e,t){return e.next.i!==t.i&&e.prev.i!==t.i&&!function(e,t){let n=e;do{if(n.i!==e.i&&n.next.i!==e.i&&n.i!==t.i&&n.next.i!==t.i&&Z(n,n.next,e,t))return!0;n=n.next}while(n!==e);return!1}(e,t)&&(b(e,t)&&b(t,e)&&function(e,t){let n=e,r=!1;const x=(e.x+t.x)/2,i=(e.y+t.y)/2;do{n.y>i!=n.next.y>i&&n.next.y!==n.y&&x<(n.next.x-n.x)*(i-n.y)/(n.next.y-n.y)+n.x&&(r=!r),n=n.next}while(n!==e);return r}(e,t)&&(h(e.prev,e,t.prev)||h(e,t.prev,t))||a(e,t)&&h(e.prev,e,e.next)>0&&h(t.prev,t,t.next)>0)}function h(e,t,n){return(t.y-e.y)*(n.x-t.x)-(t.x-e.x)*(n.y-t.y)}function a(e,t){return e.x===t.x&&e.y===t.y}function Z(e,t,n,r){const x=g(h(e,t,n)),i=g(h(e,t,r)),o=g(h(n,r,e)),u=g(h(n,r,t));return x!==i&&o!==u||(!(0!==x||!d(e,n,t))||(!(0!==i||!d(e,r,t))||(!(0!==o||!d(n,e,r))||!(0!==u||!d(n,t,r)))))}function d(e,t,n){return t.x<=Math.max(e.x,n.x)&&t.x>=Math.min(e.x,n.x)&&t.y<=Math.max(e.y,n.y)&&t.y>=Math.min(e.y,n.y)}function g(e){return e>0?1:e<0?-1:0}function b(e,t){return h(e.prev,e,e.next)<0?h(e,t,e.next)>=0&&h(e,e.prev,t)>=0:h(e,t,e.prev)<0||h(e,e.next,t)<0}function M(e,t){const n=m(e.i,e.x,e.y),r=m(t.i,t.x,t.y),x=e.next,i=t.prev;return e.next=t,t.prev=e,n.next=x,x.prev=n,r.next=n,n.prev=r,i.next=r,r.prev=i,r}function w(e,t,n,r){const x=m(e,t,n);return r?(x.next=r.next,x.prev=r,r.next.prev=x,r.next=x):(x.prev=x,x.next=x),x}function z(e){e.next.prev=e.prev,e.prev.next=e.next,e.prevZ&&(e.prevZ.nextZ=e.nextZ),e.nextZ&&(e.nextZ.prevZ=e.prevZ)}function m(e,t,n){return{i:e,x:t,y:n,prev:null,next:null,z:0,prevZ:null,nextZ:null,steiner:!1}}function j(e,t,n,r){let x=0;for(let i=t,o=n-r;i<n;i+=r)x+=(e[o]-e[i])*(e[i+1]+e[o+1]),o=i;return x}e.default=function(e,n,x=2){const i=n&&n.length,o=i?n[0]*x:e.length;let u=t(e,0,o,x,!0);const c=[];if(!u||u.next===u.prev)return c;let y,s,v;if(i&&(u=function(e,n,r,x){const i=[];for(let r=0,o=n.length;r<o;r++){const u=t(e,n[r]*x,r<o-1?n[r+1]*x:e.length,x,!1);u===u.next&&(u.steiner=!0),i.push(p(u))}i.sort(f);for(let e=0;e<i.length;e++)r=l(i[e],r);return r}(e,n,u,x)),e.length>80*x){y=1/0,s=1/0;let t=-1/0,n=-1/0;for(let r=x;r<o;r+=x){const x=e[r],i=e[r+1];x<y&&(y=x),i<s&&(s=i),x>t&&(t=x),i>n&&(n=i)}v=Math.max(t-y,n-s),v=0!==v?32767/v:0}return r(u,c,x,y,s,v,0),c},e.deviation=function(e,t,n,r){const x=t&&t.length,i=x?t[0]*n:e.length;let o=Math.abs(j(e,0,i,n));if(x)for(let r=0,x=t.length;r<x;r++){const i=t[r]*n,u=r<x-1?t[r+1]*n:e.length;o-=Math.abs(j(e,i,u,n))}let u=0;for(let t=0;t<r.length;t+=3){const x=r[t]*n,i=r[t+1]*n,o=r[t+2]*n;u+=Math.abs((e[x]-e[o])*(e[i+1]-e[x+1])-(e[x]-e[i])*(e[o+1]-e[x+1]))}return 0===o&&0===u?0:Math.abs((u-o)/o)},e.flatten=function(e){const t=[],n=[],r=e[0][0].length;let x=0,i=0;for(const o of e){for(const e of o)for(let n=0;n<r;n++)t.push(e[n]);i&&(x+=i,n.push(x)),i=o.length}return{vertices:t,holes:n,dimensions:r}},Object.defineProperty(e,"__esModule",{value:!0})}));
package/package.json CHANGED
@@ -1,40 +1,40 @@
1
1
  {
2
2
  "name": "earcut",
3
- "version": "2.2.4",
3
+ "version": "3.0.0",
4
4
  "description": "The fastest and smallest JavaScript polygon triangulation library for your WebGL apps",
5
5
  "main": "src/earcut.js",
6
- "unpkg": "dist/earcut.min.js",
7
- "jsdelivr": "dist/earcut.min.js",
6
+ "type": "module",
7
+ "exports": "./src/earcut.js",
8
8
  "files": [
9
+ "src/earcut.js",
9
10
  "dist/earcut.min.js",
10
11
  "dist/earcut.dev.js"
11
12
  ],
12
13
  "scripts": {
13
- "pretest": "eslint src test/test.js",
14
- "test": "tape test/test.js",
15
- "watch": "mkdirp dist && watchify -v -d src/earcut.js -s earcut -o dist/earcut.dev.js",
16
- "build-dev": "mkdirp dist && browserify -d src/earcut.js -s earcut > dist/earcut.dev.js",
17
- "build-min": "mkdirp dist && browserify src/earcut.js -s earcut | uglifyjs -c -m > dist/earcut.min.js",
18
- "prepublishOnly": "npm run build-dev && npm run build-min",
19
- "cov": "c8 tape test/*.js",
20
- "coveralls": "npm run cov && c8 report -r lcov && coveralls < ./coverage/lcov.info"
14
+ "pretest": "eslint src test/test.js bench/*.js viz/viz.js",
15
+ "test": "node --test",
16
+ "build": "rollup -c",
17
+ "prepublishOnly": "npm run build",
18
+ "cov": "node --test --experimental-test-coverage"
21
19
  },
22
20
  "author": "Vladimir Agafonkin",
23
21
  "license": "ISC",
24
22
  "devDependencies": {
23
+ "@rollup/plugin-terser": "^0.4.4",
25
24
  "benchmark": "^2.1.4",
26
- "browserify": "^17.0.0",
27
- "c8": "^7.11.3",
28
25
  "coveralls": "^3.1.1",
29
- "eslint": "^8.19.0",
30
- "eslint-config-mourner": "^2.0.3",
31
- "mkdirp": "^1.0.4",
32
- "tape": "^5.5.3",
33
- "uglify-js": "^3.16.2",
26
+ "eslint": "^9.5.0",
27
+ "eslint-config-mourner": "^4.0.1",
28
+ "rollup": "^4.18.0",
29
+ "uglify-js": "^3.18.0",
34
30
  "watchify": "^4.0.0"
35
31
  },
36
32
  "eslintConfig": {
37
- "extends": "mourner"
33
+ "extends": "mourner",
34
+ "parserOptions": {
35
+ "sourceType": "module",
36
+ "ecmaVersion": 2020
37
+ }
38
38
  },
39
39
  "repository": {
40
40
  "type": "git",
package/src/earcut.js CHANGED
@@ -1,31 +1,27 @@
1
- 'use strict';
2
1
 
3
- module.exports = earcut;
4
- module.exports.default = earcut;
2
+ export default function earcut(data, holeIndices, dim = 2) {
5
3
 
6
- function earcut(data, holeIndices, dim) {
7
-
8
- dim = dim || 2;
9
-
10
- var hasHoles = holeIndices && holeIndices.length,
11
- outerLen = hasHoles ? holeIndices[0] * dim : data.length,
12
- outerNode = linkedList(data, 0, outerLen, dim, true),
13
- triangles = [];
4
+ const hasHoles = holeIndices && holeIndices.length;
5
+ const outerLen = hasHoles ? holeIndices[0] * dim : data.length;
6
+ let outerNode = linkedList(data, 0, outerLen, dim, true);
7
+ const triangles = [];
14
8
 
15
9
  if (!outerNode || outerNode.next === outerNode.prev) return triangles;
16
10
 
17
- var minX, minY, maxX, maxY, x, y, invSize;
11
+ let minX, minY, invSize;
18
12
 
19
13
  if (hasHoles) outerNode = eliminateHoles(data, holeIndices, outerNode, dim);
20
14
 
21
15
  // if the shape is not too simple, we'll use z-order curve hash later; calculate polygon bbox
22
16
  if (data.length > 80 * dim) {
23
- minX = maxX = data[0];
24
- minY = maxY = data[1];
25
-
26
- for (var i = dim; i < outerLen; i += dim) {
27
- x = data[i];
28
- y = data[i + 1];
17
+ minX = Infinity;
18
+ minY = Infinity;
19
+ let maxX = -Infinity;
20
+ let maxY = -Infinity;
21
+
22
+ for (let i = dim; i < outerLen; i += dim) {
23
+ const x = data[i];
24
+ const y = data[i + 1];
29
25
  if (x < minX) minX = x;
30
26
  if (y < minY) minY = y;
31
27
  if (x > maxX) maxX = x;
@@ -44,12 +40,12 @@ function earcut(data, holeIndices, dim) {
44
40
 
45
41
  // create a circular doubly linked list from polygon points in the specified winding order
46
42
  function linkedList(data, start, end, dim, clockwise) {
47
- var i, last;
43
+ let last;
48
44
 
49
45
  if (clockwise === (signedArea(data, start, end, dim) > 0)) {
50
- for (i = start; i < end; i += dim) last = insertNode(i, data[i], data[i + 1], last);
46
+ for (let i = start; i < end; i += dim) last = insertNode(i / dim | 0, data[i], data[i + 1], last);
51
47
  } else {
52
- for (i = end - dim; i >= start; i -= dim) last = insertNode(i, data[i], data[i + 1], last);
48
+ for (let i = end - dim; i >= start; i -= dim) last = insertNode(i / dim | 0, data[i], data[i + 1], last);
53
49
  }
54
50
 
55
51
  if (last && equals(last, last.next)) {
@@ -65,7 +61,7 @@ function filterPoints(start, end) {
65
61
  if (!start) return start;
66
62
  if (!end) end = start;
67
63
 
68
- var p = start,
64
+ let p = start,
69
65
  again;
70
66
  do {
71
67
  again = false;
@@ -91,19 +87,15 @@ function earcutLinked(ear, triangles, dim, minX, minY, invSize, pass) {
91
87
  // interlink polygon nodes in z-order
92
88
  if (!pass && invSize) indexCurve(ear, minX, minY, invSize);
93
89
 
94
- var stop = ear,
95
- prev, next;
90
+ let stop = ear;
96
91
 
97
92
  // iterate through ears, slicing them one by one
98
93
  while (ear.prev !== ear.next) {
99
- prev = ear.prev;
100
- next = ear.next;
94
+ const prev = ear.prev;
95
+ const next = ear.next;
101
96
 
102
97
  if (invSize ? isEarHashed(ear, minX, minY, invSize) : isEar(ear)) {
103
- // cut off the triangle
104
- triangles.push(prev.i / dim | 0);
105
- triangles.push(ear.i / dim | 0);
106
- triangles.push(next.i / dim | 0);
98
+ triangles.push(prev.i, ear.i, next.i); // cut off the triangle
107
99
 
108
100
  removeNode(ear);
109
101
 
@@ -124,7 +116,7 @@ function earcutLinked(ear, triangles, dim, minX, minY, invSize, pass) {
124
116
 
125
117
  // if this didn't work, try curing all small self-intersections locally
126
118
  } else if (pass === 1) {
127
- ear = cureLocalIntersections(filterPoints(ear), triangles, dim);
119
+ ear = cureLocalIntersections(filterPoints(ear), triangles);
128
120
  earcutLinked(ear, triangles, dim, minX, minY, invSize, 2);
129
121
 
130
122
  // as a last resort, try splitting the remaining polygon into two
@@ -139,22 +131,22 @@ function earcutLinked(ear, triangles, dim, minX, minY, invSize, pass) {
139
131
 
140
132
  // check whether a polygon node forms a valid ear with adjacent nodes
141
133
  function isEar(ear) {
142
- var a = ear.prev,
134
+ const a = ear.prev,
143
135
  b = ear,
144
136
  c = ear.next;
145
137
 
146
138
  if (area(a, b, c) >= 0) return false; // reflex, can't be an ear
147
139
 
148
140
  // now make sure we don't have other points inside the potential ear
149
- var ax = a.x, bx = b.x, cx = c.x, ay = a.y, by = b.y, cy = c.y;
141
+ const ax = a.x, bx = b.x, cx = c.x, ay = a.y, by = b.y, cy = c.y;
150
142
 
151
143
  // triangle bbox; min & max are calculated like this for speed
152
- var x0 = ax < bx ? (ax < cx ? ax : cx) : (bx < cx ? bx : cx),
144
+ const x0 = ax < bx ? (ax < cx ? ax : cx) : (bx < cx ? bx : cx),
153
145
  y0 = ay < by ? (ay < cy ? ay : cy) : (by < cy ? by : cy),
154
146
  x1 = ax > bx ? (ax > cx ? ax : cx) : (bx > cx ? bx : cx),
155
147
  y1 = ay > by ? (ay > cy ? ay : cy) : (by > cy ? by : cy);
156
148
 
157
- var p = c.next;
149
+ let p = c.next;
158
150
  while (p !== a) {
159
151
  if (p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 &&
160
152
  pointInTriangle(ax, ay, bx, by, cx, cy, p.x, p.y) &&
@@ -166,25 +158,25 @@ function isEar(ear) {
166
158
  }
167
159
 
168
160
  function isEarHashed(ear, minX, minY, invSize) {
169
- var a = ear.prev,
161
+ const a = ear.prev,
170
162
  b = ear,
171
163
  c = ear.next;
172
164
 
173
165
  if (area(a, b, c) >= 0) return false; // reflex, can't be an ear
174
166
 
175
- var ax = a.x, bx = b.x, cx = c.x, ay = a.y, by = b.y, cy = c.y;
167
+ const ax = a.x, bx = b.x, cx = c.x, ay = a.y, by = b.y, cy = c.y;
176
168
 
177
169
  // triangle bbox; min & max are calculated like this for speed
178
- var x0 = ax < bx ? (ax < cx ? ax : cx) : (bx < cx ? bx : cx),
170
+ const x0 = ax < bx ? (ax < cx ? ax : cx) : (bx < cx ? bx : cx),
179
171
  y0 = ay < by ? (ay < cy ? ay : cy) : (by < cy ? by : cy),
180
172
  x1 = ax > bx ? (ax > cx ? ax : cx) : (bx > cx ? bx : cx),
181
173
  y1 = ay > by ? (ay > cy ? ay : cy) : (by > cy ? by : cy);
182
174
 
183
175
  // z-order range for the current triangle bbox;
184
- var minZ = zOrder(x0, y0, minX, minY, invSize),
176
+ const minZ = zOrder(x0, y0, minX, minY, invSize),
185
177
  maxZ = zOrder(x1, y1, minX, minY, invSize);
186
178
 
187
- var p = ear.prevZ,
179
+ let p = ear.prevZ,
188
180
  n = ear.nextZ;
189
181
 
190
182
  // look for points inside the triangle in both directions
@@ -216,17 +208,15 @@ function isEarHashed(ear, minX, minY, invSize) {
216
208
  }
217
209
 
218
210
  // go through all polygon nodes and cure small local self-intersections
219
- function cureLocalIntersections(start, triangles, dim) {
220
- var p = start;
211
+ function cureLocalIntersections(start, triangles) {
212
+ let p = start;
221
213
  do {
222
- var a = p.prev,
214
+ const a = p.prev,
223
215
  b = p.next.next;
224
216
 
225
217
  if (!equals(a, b) && intersects(a, p, p.next, b) && locallyInside(a, b) && locallyInside(b, a)) {
226
218
 
227
- triangles.push(a.i / dim | 0);
228
- triangles.push(p.i / dim | 0);
229
- triangles.push(b.i / dim | 0);
219
+ triangles.push(a.i, p.i, b.i);
230
220
 
231
221
  // remove two nodes involved
232
222
  removeNode(p);
@@ -243,13 +233,13 @@ function cureLocalIntersections(start, triangles, dim) {
243
233
  // try splitting polygon into two and triangulate them independently
244
234
  function splitEarcut(start, triangles, dim, minX, minY, invSize) {
245
235
  // look for a valid diagonal that divides the polygon into two
246
- var a = start;
236
+ let a = start;
247
237
  do {
248
- var b = a.next.next;
238
+ let b = a.next.next;
249
239
  while (b !== a.prev) {
250
240
  if (a.i !== b.i && isValidDiagonal(a, b)) {
251
241
  // split the polygon in two by the diagonal
252
- var c = splitPolygon(a, b);
242
+ let c = splitPolygon(a, b);
253
243
 
254
244
  // filter colinear points around the cuts
255
245
  a = filterPoints(a, a.next);
@@ -268,13 +258,12 @@ function splitEarcut(start, triangles, dim, minX, minY, invSize) {
268
258
 
269
259
  // link every hole into the outer loop, producing a single-ring polygon without holes
270
260
  function eliminateHoles(data, holeIndices, outerNode, dim) {
271
- var queue = [],
272
- i, len, start, end, list;
261
+ const queue = [];
273
262
 
274
- for (i = 0, len = holeIndices.length; i < len; i++) {
275
- start = holeIndices[i] * dim;
276
- end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;
277
- list = linkedList(data, start, end, dim, false);
263
+ for (let i = 0, len = holeIndices.length; i < len; i++) {
264
+ const start = holeIndices[i] * dim;
265
+ const end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;
266
+ const list = linkedList(data, start, end, dim, false);
278
267
  if (list === list.next) list.steiner = true;
279
268
  queue.push(getLeftmost(list));
280
269
  }
@@ -282,7 +271,7 @@ function eliminateHoles(data, holeIndices, outerNode, dim) {
282
271
  queue.sort(compareX);
283
272
 
284
273
  // process holes from left to right
285
- for (i = 0; i < queue.length; i++) {
274
+ for (let i = 0; i < queue.length; i++) {
286
275
  outerNode = eliminateHole(queue[i], outerNode);
287
276
  }
288
277
 
@@ -295,12 +284,12 @@ function compareX(a, b) {
295
284
 
296
285
  // find a bridge between vertices that connects hole with an outer ring and and link it
297
286
  function eliminateHole(hole, outerNode) {
298
- var bridge = findHoleBridge(hole, outerNode);
287
+ const bridge = findHoleBridge(hole, outerNode);
299
288
  if (!bridge) {
300
289
  return outerNode;
301
290
  }
302
291
 
303
- var bridgeReverse = splitPolygon(bridge, hole);
292
+ const bridgeReverse = splitPolygon(bridge, hole);
304
293
 
305
294
  // filter collinear points around the cuts
306
295
  filterPoints(bridgeReverse, bridgeReverse.next);
@@ -309,17 +298,17 @@ function eliminateHole(hole, outerNode) {
309
298
 
310
299
  // David Eberly's algorithm for finding a bridge between hole and outer polygon
311
300
  function findHoleBridge(hole, outerNode) {
312
- var p = outerNode,
313
- hx = hole.x,
314
- hy = hole.y,
315
- qx = -Infinity,
316
- m;
301
+ let p = outerNode;
302
+ const hx = hole.x;
303
+ const hy = hole.y;
304
+ let qx = -Infinity;
305
+ let m;
317
306
 
318
307
  // find a segment intersected by a ray from the hole's leftmost point to the left;
319
308
  // segment's endpoint with lesser x will be potential connection point
320
309
  do {
321
310
  if (hy <= p.y && hy >= p.next.y && p.next.y !== p.y) {
322
- var x = p.x + (hy - p.y) * (p.next.x - p.x) / (p.next.y - p.y);
311
+ const x = p.x + (hy - p.y) * (p.next.x - p.x) / (p.next.y - p.y);
323
312
  if (x <= hx && x > qx) {
324
313
  qx = x;
325
314
  m = p.x < p.next.x ? p : p.next;
@@ -335,11 +324,10 @@ function findHoleBridge(hole, outerNode) {
335
324
  // if there are no points found, we have a valid connection;
336
325
  // otherwise choose the point of the minimum angle with the ray as connection point
337
326
 
338
- var stop = m,
339
- mx = m.x,
340
- my = m.y,
341
- tanMin = Infinity,
342
- tan;
327
+ const stop = m;
328
+ const mx = m.x;
329
+ const my = m.y;
330
+ let tanMin = Infinity;
343
331
 
344
332
  p = m;
345
333
 
@@ -347,7 +335,7 @@ function findHoleBridge(hole, outerNode) {
347
335
  if (hx >= p.x && p.x >= mx && hx !== p.x &&
348
336
  pointInTriangle(hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p.x, p.y)) {
349
337
 
350
- tan = Math.abs(hy - p.y) / (hx - p.x); // tangential
338
+ const tan = Math.abs(hy - p.y) / (hx - p.x); // tangential
351
339
 
352
340
  if (locallyInside(p, hole) &&
353
341
  (tan < tanMin || (tan === tanMin && (p.x > m.x || (p.x === m.x && sectorContainsSector(m, p)))))) {
@@ -369,7 +357,7 @@ function sectorContainsSector(m, p) {
369
357
 
370
358
  // interlink polygon nodes in z-order
371
359
  function indexCurve(start, minX, minY, invSize) {
372
- var p = start;
360
+ let p = start;
373
361
  do {
374
362
  if (p.z === 0) p.z = zOrder(p.x, p.y, minX, minY, invSize);
375
363
  p.prevZ = p.prev;
@@ -386,25 +374,26 @@ function indexCurve(start, minX, minY, invSize) {
386
374
  // Simon Tatham's linked list merge sort algorithm
387
375
  // http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html
388
376
  function sortLinked(list) {
389
- var i, p, q, e, tail, numMerges, pSize, qSize,
390
- inSize = 1;
377
+ let numMerges;
378
+ let inSize = 1;
391
379
 
392
380
  do {
393
- p = list;
381
+ let p = list;
382
+ let e;
394
383
  list = null;
395
- tail = null;
384
+ let tail = null;
396
385
  numMerges = 0;
397
386
 
398
387
  while (p) {
399
388
  numMerges++;
400
- q = p;
401
- pSize = 0;
402
- for (i = 0; i < inSize; i++) {
389
+ let q = p;
390
+ let pSize = 0;
391
+ for (let i = 0; i < inSize; i++) {
403
392
  pSize++;
404
393
  q = q.nextZ;
405
394
  if (!q) break;
406
395
  }
407
- qSize = inSize;
396
+ let qSize = inSize;
408
397
 
409
398
  while (pSize > 0 || (qSize > 0 && q)) {
410
399
 
@@ -457,7 +446,7 @@ function zOrder(x, y, minX, minY, invSize) {
457
446
 
458
447
  // find the leftmost node of a polygon ring
459
448
  function getLeftmost(start) {
460
- var p = start,
449
+ let p = start,
461
450
  leftmost = start;
462
451
  do {
463
452
  if (p.x < leftmost.x || (p.x === leftmost.x && p.y < leftmost.y)) leftmost = p;
@@ -494,10 +483,10 @@ function equals(p1, p2) {
494
483
 
495
484
  // check if two segments intersect
496
485
  function intersects(p1, q1, p2, q2) {
497
- var o1 = sign(area(p1, q1, p2));
498
- var o2 = sign(area(p1, q1, q2));
499
- var o3 = sign(area(p2, q2, p1));
500
- var o4 = sign(area(p2, q2, q1));
486
+ const o1 = sign(area(p1, q1, p2));
487
+ const o2 = sign(area(p1, q1, q2));
488
+ const o3 = sign(area(p2, q2, p1));
489
+ const o4 = sign(area(p2, q2, q1));
501
490
 
502
491
  if (o1 !== o2 && o3 !== o4) return true; // general case
503
492
 
@@ -520,7 +509,7 @@ function sign(num) {
520
509
 
521
510
  // check if a polygon diagonal intersects any polygon segments
522
511
  function intersectsPolygon(a, b) {
523
- var p = a;
512
+ let p = a;
524
513
  do {
525
514
  if (p.i !== a.i && p.next.i !== a.i && p.i !== b.i && p.next.i !== b.i &&
526
515
  intersects(p, p.next, a, b)) return true;
@@ -539,10 +528,10 @@ function locallyInside(a, b) {
539
528
 
540
529
  // check if the middle point of a polygon diagonal is inside the polygon
541
530
  function middleInside(a, b) {
542
- var p = a,
543
- inside = false,
544
- px = (a.x + b.x) / 2,
545
- py = (a.y + b.y) / 2;
531
+ let p = a;
532
+ let inside = false;
533
+ const px = (a.x + b.x) / 2;
534
+ const py = (a.y + b.y) / 2;
546
535
  do {
547
536
  if (((p.y > py) !== (p.next.y > py)) && p.next.y !== p.y &&
548
537
  (px < (p.next.x - p.x) * (py - p.y) / (p.next.y - p.y) + p.x))
@@ -556,8 +545,8 @@ function middleInside(a, b) {
556
545
  // link two polygon vertices with a bridge; if the vertices belong to the same ring, it splits polygon into two;
557
546
  // if one belongs to the outer ring and another to a hole, it merges it into a single ring
558
547
  function splitPolygon(a, b) {
559
- var a2 = new Node(a.i, a.x, a.y),
560
- b2 = new Node(b.i, b.x, b.y),
548
+ const a2 = createNode(a.i, a.x, a.y),
549
+ b2 = createNode(b.i, b.x, b.y),
561
550
  an = a.next,
562
551
  bp = b.prev;
563
552
 
@@ -578,7 +567,7 @@ function splitPolygon(a, b) {
578
567
 
579
568
  // create a node and optionally link it with previous one (in a circular doubly linked list)
580
569
  function insertNode(i, x, y, last) {
581
- var p = new Node(i, x, y);
570
+ const p = createNode(i, x, y);
582
571
 
583
572
  if (!last) {
584
573
  p.prev = p;
@@ -601,49 +590,39 @@ function removeNode(p) {
601
590
  if (p.nextZ) p.nextZ.prevZ = p.prevZ;
602
591
  }
603
592
 
604
- function Node(i, x, y) {
605
- // vertex index in coordinates array
606
- this.i = i;
607
-
608
- // vertex coordinates
609
- this.x = x;
610
- this.y = y;
611
-
612
- // previous and next vertex nodes in a polygon ring
613
- this.prev = null;
614
- this.next = null;
615
-
616
- // z-order curve value
617
- this.z = 0;
618
-
619
- // previous and next nodes in z-order
620
- this.prevZ = null;
621
- this.nextZ = null;
622
-
623
- // indicates whether this is a steiner point
624
- this.steiner = false;
593
+ function createNode(i, x, y) {
594
+ return {
595
+ i, // vertex index in coordinates array
596
+ x, y, // vertex coordinates
597
+ prev: null, // previous and next vertex nodes in a polygon ring
598
+ next: null,
599
+ z: 0, // z-order curve value
600
+ prevZ: null, // previous and next nodes in z-order
601
+ nextZ: null,
602
+ steiner: false // indicates whether this is a steiner point
603
+ };
625
604
  }
626
605
 
627
606
  // return a percentage difference between the polygon area and its triangulation area;
628
607
  // used to verify correctness of triangulation
629
- earcut.deviation = function (data, holeIndices, dim, triangles) {
630
- var hasHoles = holeIndices && holeIndices.length;
631
- var outerLen = hasHoles ? holeIndices[0] * dim : data.length;
608
+ export function deviation(data, holeIndices, dim, triangles) {
609
+ const hasHoles = holeIndices && holeIndices.length;
610
+ const outerLen = hasHoles ? holeIndices[0] * dim : data.length;
632
611
 
633
- var polygonArea = Math.abs(signedArea(data, 0, outerLen, dim));
612
+ let polygonArea = Math.abs(signedArea(data, 0, outerLen, dim));
634
613
  if (hasHoles) {
635
- for (var i = 0, len = holeIndices.length; i < len; i++) {
636
- var start = holeIndices[i] * dim;
637
- var end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;
614
+ for (let i = 0, len = holeIndices.length; i < len; i++) {
615
+ const start = holeIndices[i] * dim;
616
+ const end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;
638
617
  polygonArea -= Math.abs(signedArea(data, start, end, dim));
639
618
  }
640
619
  }
641
620
 
642
- var trianglesArea = 0;
643
- for (i = 0; i < triangles.length; i += 3) {
644
- var a = triangles[i] * dim;
645
- var b = triangles[i + 1] * dim;
646
- var c = triangles[i + 2] * dim;
621
+ let trianglesArea = 0;
622
+ for (let i = 0; i < triangles.length; i += 3) {
623
+ const a = triangles[i] * dim;
624
+ const b = triangles[i + 1] * dim;
625
+ const c = triangles[i + 2] * dim;
647
626
  trianglesArea += Math.abs(
648
627
  (data[a] - data[c]) * (data[b + 1] - data[a + 1]) -
649
628
  (data[a] - data[b]) * (data[c + 1] - data[a + 1]));
@@ -651,11 +630,11 @@ earcut.deviation = function (data, holeIndices, dim, triangles) {
651
630
 
652
631
  return polygonArea === 0 && trianglesArea === 0 ? 0 :
653
632
  Math.abs((trianglesArea - polygonArea) / polygonArea);
654
- };
633
+ }
655
634
 
656
635
  function signedArea(data, start, end, dim) {
657
- var sum = 0;
658
- for (var i = start, j = end - dim; i < end; i += dim) {
636
+ let sum = 0;
637
+ for (let i = start, j = end - dim; i < end; i += dim) {
659
638
  sum += (data[j] - data[i]) * (data[i + 1] + data[j + 1]);
660
639
  j = i;
661
640
  }
@@ -663,19 +642,22 @@ function signedArea(data, start, end, dim) {
663
642
  }
664
643
 
665
644
  // turn a polygon in a multi-dimensional array form (e.g. as in GeoJSON) into a form Earcut accepts
666
- earcut.flatten = function (data) {
667
- var dim = data[0][0].length,
668
- result = {vertices: [], holes: [], dimensions: dim},
669
- holeIndex = 0;
670
-
671
- for (var i = 0; i < data.length; i++) {
672
- for (var j = 0; j < data[i].length; j++) {
673
- for (var d = 0; d < dim; d++) result.vertices.push(data[i][j][d]);
645
+ export function flatten(data) {
646
+ const vertices = [];
647
+ const holes = [];
648
+ const dimensions = data[0][0].length;
649
+ let holeIndex = 0;
650
+ let prevLen = 0;
651
+
652
+ for (const ring of data) {
653
+ for (const p of ring) {
654
+ for (let d = 0; d < dimensions; d++) vertices.push(p[d]);
674
655
  }
675
- if (i > 0) {
676
- holeIndex += data[i - 1].length;
677
- result.holes.push(holeIndex);
656
+ if (prevLen) {
657
+ holeIndex += prevLen;
658
+ holes.push(holeIndex);
678
659
  }
660
+ prevLen = ring.length;
679
661
  }
680
- return result;
681
- };
662
+ return {vertices, holes, dimensions};
663
+ }