@labelu/image-annotator-react
Version:
image annotator for react
1,324 lines (1,321 loc) • 46.9 kB
JavaScript
/**
* splaytree v3.1.2
* Fast Splay tree for Node and browser
*
* @author Alexander Milevski <info@w8r.name>
* @license MIT
* @preserve
*/
/*! *****************************************************************************
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
License at http://www.apache.org/licenses/LICENSE-2.0
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
MERCHANTABLITY OR NON-INFRINGEMENT.
See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
function mt(o, t) {
var e = { label: 0, sent: function() {
if (r[0] & 1)
throw r[1];
return r[1];
}, trys: [], ops: [] }, n, i, r, u;
return u = { next: s(0), throw: s(1), return: s(2) }, typeof Symbol == "function" && (u[Symbol.iterator] = function() {
return this;
}), u;
function s(h) {
return function(p) {
return f([h, p]);
};
}
function f(h) {
if (n)
throw new TypeError("Generator is already executing.");
for (; e; )
try {
if (n = 1, i && (r = h[0] & 2 ? i.return : h[0] ? i.throw || ((r = i.return) && r.call(i), 0) : i.next) && !(r = r.call(i, h[1])).done)
return r;
switch (i = 0, r && (h = [h[0] & 2, r.value]), h[0]) {
case 0:
case 1:
r = h;
break;
case 4:
return e.label++, { value: h[1], done: !1 };
case 5:
e.label++, i = h[1], h = [0];
continue;
case 7:
h = e.ops.pop(), e.trys.pop();
continue;
default:
if (r = e.trys, !(r = r.length > 0 && r[r.length - 1]) && (h[0] === 6 || h[0] === 2)) {
e = 0;
continue;
}
if (h[0] === 3 && (!r || h[1] > r[0] && h[1] < r[3])) {
e.label = h[1];
break;
}
if (h[0] === 6 && e.label < r[1]) {
e.label = r[1], r = h;
break;
}
if (r && e.label < r[2]) {
e.label = r[2], e.ops.push(h);
break;
}
r[2] && e.ops.pop(), e.trys.pop();
continue;
}
h = t.call(o, e);
} catch (p) {
h = [6, p], i = 0;
} finally {
n = r = 0;
}
if (h[0] & 5)
throw h[1];
return { value: h[0] ? h[1] : void 0, done: !0 };
}
}
var G = (
/** @class */
function() {
function o(t, e) {
this.next = null, this.key = t, this.data = e, this.left = null, this.right = null;
}
return o;
}()
);
function vt(o, t) {
return o > t ? 1 : o < t ? -1 : 0;
}
function z(o, t, e) {
for (var n = new G(null, null), i = n, r = n; ; ) {
var u = e(o, t.key);
if (u < 0) {
if (t.left === null)
break;
if (e(o, t.left.key) < 0) {
var s = t.left;
if (t.left = s.right, s.right = t, t = s, t.left === null)
break;
}
r.left = t, r = t, t = t.left;
} else if (u > 0) {
if (t.right === null)
break;
if (e(o, t.right.key) > 0) {
var s = t.right;
if (t.right = s.left, s.left = t, t = s, t.right === null)
break;
}
i.right = t, i = t, t = t.right;
} else
break;
}
return i.right = t.left, r.left = t.right, t.left = n.right, t.right = n.left, t;
}
function W(o, t, e, n) {
var i = new G(o, t);
if (e === null)
return i.left = i.right = null, i;
e = z(o, e, n);
var r = n(o, e.key);
return r < 0 ? (i.left = e.left, i.right = e, e.left = null) : r >= 0 && (i.right = e.right, i.left = e, e.right = null), i;
}
function et(o, t, e) {
var n = null, i = null;
if (t) {
t = z(o, t, e);
var r = e(t.key, o);
r === 0 ? (n = t.left, i = t.right) : r < 0 ? (i = t.right, t.right = null, n = t) : (n = t.left, t.left = null, i = t);
}
return { left: n, right: i };
}
function dt(o, t, e) {
return t === null ? o : (o === null || (t = z(o.key, t, e), t.left = o), t);
}
function Z(o, t, e, n, i) {
if (o) {
n("" + t + (e ? "└── " : "├── ") + i(o) + `
`);
var r = t + (e ? " " : "│ ");
o.left && Z(o.left, r, !1, n, i), o.right && Z(o.right, r, !0, n, i);
}
}
var tt = (
/** @class */
function() {
function o(t) {
t === void 0 && (t = vt), this._root = null, this._size = 0, this._comparator = t;
}
return o.prototype.insert = function(t, e) {
return this._size++, this._root = W(t, e, this._root, this._comparator);
}, o.prototype.add = function(t, e) {
var n = new G(t, e);
this._root === null && (n.left = n.right = null, this._size++, this._root = n);
var i = this._comparator, r = z(t, this._root, i), u = i(t, r.key);
return u === 0 ? this._root = r : (u < 0 ? (n.left = r.left, n.right = r, r.left = null) : u > 0 && (n.right = r.right, n.left = r, r.right = null), this._size++, this._root = n), this._root;
}, o.prototype.remove = function(t) {
this._root = this._remove(t, this._root, this._comparator);
}, o.prototype._remove = function(t, e, n) {
var i;
if (e === null)
return null;
e = z(t, e, n);
var r = n(t, e.key);
return r === 0 ? (e.left === null ? i = e.right : (i = z(t, e.left, n), i.right = e.right), this._size--, i) : e;
}, o.prototype.pop = function() {
var t = this._root;
if (t) {
for (; t.left; )
t = t.left;
return this._root = z(t.key, this._root, this._comparator), this._root = this._remove(t.key, this._root, this._comparator), { key: t.key, data: t.data };
}
return null;
}, o.prototype.findStatic = function(t) {
for (var e = this._root, n = this._comparator; e; ) {
var i = n(t, e.key);
if (i === 0)
return e;
i < 0 ? e = e.left : e = e.right;
}
return null;
}, o.prototype.find = function(t) {
return this._root && (this._root = z(t, this._root, this._comparator), this._comparator(t, this._root.key) !== 0) ? null : this._root;
}, o.prototype.contains = function(t) {
for (var e = this._root, n = this._comparator; e; ) {
var i = n(t, e.key);
if (i === 0)
return !0;
i < 0 ? e = e.left : e = e.right;
}
return !1;
}, o.prototype.forEach = function(t, e) {
for (var n = this._root, i = [], r = !1; !r; )
n !== null ? (i.push(n), n = n.left) : i.length !== 0 ? (n = i.pop(), t.call(e, n), n = n.right) : r = !0;
return this;
}, o.prototype.range = function(t, e, n, i) {
for (var r = [], u = this._comparator, s = this._root, f; r.length !== 0 || s; )
if (s)
r.push(s), s = s.left;
else {
if (s = r.pop(), f = u(s.key, e), f > 0)
break;
if (u(s.key, t) >= 0 && n.call(i, s))
return this;
s = s.right;
}
return this;
}, o.prototype.keys = function() {
var t = [];
return this.forEach(function(e) {
var n = e.key;
return t.push(n);
}), t;
}, o.prototype.values = function() {
var t = [];
return this.forEach(function(e) {
var n = e.data;
return t.push(n);
}), t;
}, o.prototype.min = function() {
return this._root ? this.minNode(this._root).key : null;
}, o.prototype.max = function() {
return this._root ? this.maxNode(this._root).key : null;
}, o.prototype.minNode = function(t) {
if (t === void 0 && (t = this._root), t)
for (; t.left; )
t = t.left;
return t;
}, o.prototype.maxNode = function(t) {
if (t === void 0 && (t = this._root), t)
for (; t.right; )
t = t.right;
return t;
}, o.prototype.at = function(t) {
for (var e = this._root, n = !1, i = 0, r = []; !n; )
if (e)
r.push(e), e = e.left;
else if (r.length > 0) {
if (e = r.pop(), i === t)
return e;
i++, e = e.right;
} else
n = !0;
return null;
}, o.prototype.next = function(t) {
var e = this._root, n = null;
if (t.right) {
for (n = t.right; n.left; )
n = n.left;
return n;
}
for (var i = this._comparator; e; ) {
var r = i(t.key, e.key);
if (r === 0)
break;
r < 0 ? (n = e, e = e.left) : e = e.right;
}
return n;
}, o.prototype.prev = function(t) {
var e = this._root, n = null;
if (t.left !== null) {
for (n = t.left; n.right; )
n = n.right;
return n;
}
for (var i = this._comparator; e; ) {
var r = i(t.key, e.key);
if (r === 0)
break;
r < 0 ? e = e.left : (n = e, e = e.right);
}
return n;
}, o.prototype.clear = function() {
return this._root = null, this._size = 0, this;
}, o.prototype.toList = function() {
return St(this._root);
}, o.prototype.load = function(t, e, n) {
e === void 0 && (e = []), n === void 0 && (n = !1);
var i = t.length, r = this._comparator;
if (n && J(t, e, 0, i - 1, r), this._root === null)
this._root = D(t, e, 0, i), this._size = i;
else {
var u = _t(this.toList(), Et(t, e), r);
i = this._size + i, this._root = H({ head: u }, 0, i);
}
return this;
}, o.prototype.isEmpty = function() {
return this._root === null;
}, Object.defineProperty(o.prototype, "size", {
get: function() {
return this._size;
},
enumerable: !0,
configurable: !0
}), Object.defineProperty(o.prototype, "root", {
get: function() {
return this._root;
},
enumerable: !0,
configurable: !0
}), o.prototype.toString = function(t) {
t === void 0 && (t = function(n) {
return String(n.key);
});
var e = [];
return Z(this._root, "", !0, function(n) {
return e.push(n);
}, t), e.join("");
}, o.prototype.update = function(t, e, n) {
var i = this._comparator, r = et(t, this._root, i), u = r.left, s = r.right;
i(t, e) < 0 ? s = W(e, n, s, i) : u = W(e, n, u, i), this._root = dt(u, s, i);
}, o.prototype.split = function(t) {
return et(t, this._root, this._comparator);
}, o.prototype[Symbol.iterator] = function() {
var t, e, n;
return mt(this, function(i) {
switch (i.label) {
case 0:
t = this._root, e = [], n = !1, i.label = 1;
case 1:
return n ? [3, 6] : t === null ? [3, 2] : (e.push(t), t = t.left, [3, 5]);
case 2:
return e.length === 0 ? [3, 4] : (t = e.pop(), [4, t]);
case 3:
return i.sent(), t = t.right, [3, 5];
case 4:
n = !0, i.label = 5;
case 5:
return [3, 1];
case 6:
return [
2
/*return*/
];
}
});
}, o;
}()
);
function D(o, t, e, n) {
var i = n - e;
if (i > 0) {
var r = e + Math.floor(i / 2), u = o[r], s = t[r], f = new G(u, s);
return f.left = D(o, t, e, r), f.right = D(o, t, r + 1, n), f;
}
return null;
}
function Et(o, t) {
for (var e = new G(null, null), n = e, i = 0; i < o.length; i++)
n = n.next = new G(o[i], t[i]);
return n.next = null, e.next;
}
function St(o) {
for (var t = o, e = [], n = !1, i = new G(null, null), r = i; !n; )
t ? (e.push(t), t = t.left) : e.length > 0 ? (t = r = r.next = e.pop(), t = t.right) : n = !0;
return r.next = null, i.next;
}
function H(o, t, e) {
var n = e - t;
if (n > 0) {
var i = t + Math.floor(n / 2), r = H(o, t, i), u = o.head;
return u.left = r, o.head = o.head.next, u.right = H(o, i + 1, e), u;
}
return null;
}
function _t(o, t, e) {
for (var n = new G(null, null), i = n, r = o, u = t; r !== null && u !== null; )
e(r.key, u.key) < 0 ? (i.next = r, r = r.next) : (i.next = u, u = u.next), i = i.next;
return r !== null ? i.next = r : u !== null && (i.next = u), n.next;
}
function J(o, t, e, n, i) {
if (!(e >= n)) {
for (var r = o[e + n >> 1], u = e - 1, s = n + 1; ; ) {
do
u++;
while (i(o[u], r) < 0);
do
s--;
while (i(o[s], r) > 0);
if (u >= s)
break;
var f = o[u];
o[u] = o[s], o[s] = f, f = t[u], t[u] = t[s], t[s] = f;
}
J(o, t, e, s, i), J(o, t, s + 1, n, i);
}
}
const M = 11102230246251565e-32, w = 134217729, wt = (3 + 8 * M) * M;
function X(o, t, e, n, i) {
let r, u, s, f, h = t[0], p = n[0], l = 0, c = 0;
p > h == p > -h ? (r = h, h = t[++l]) : (r = p, p = n[++c]);
let a = 0;
if (l < o && c < e)
for (p > h == p > -h ? (u = h + r, s = r - (u - h), h = t[++l]) : (u = p + r, s = r - (u - p), p = n[++c]), r = u, s !== 0 && (i[a++] = s); l < o && c < e; )
p > h == p > -h ? (u = r + h, f = u - r, s = r - (u - f) + (h - f), h = t[++l]) : (u = r + p, f = u - r, s = r - (u - f) + (p - f), p = n[++c]), r = u, s !== 0 && (i[a++] = s);
for (; l < o; )
u = r + h, f = u - r, s = r - (u - f) + (h - f), h = t[++l], r = u, s !== 0 && (i[a++] = s);
for (; c < e; )
u = r + p, f = u - r, s = r - (u - f) + (p - f), p = n[++c], r = u, s !== 0 && (i[a++] = s);
return (r !== 0 || a === 0) && (i[a++] = r), a;
}
function kt(o, t) {
let e = t[0];
for (let n = 1; n < o; n++)
e += t[n];
return e;
}
function Y(o) {
return new Float64Array(o);
}
const Rt = (3 + 16 * M) * M, It = (2 + 12 * M) * M, Pt = (9 + 64 * M) * M * M, q = Y(4), nt = Y(8), rt = Y(12), it = Y(16), k = Y(4);
function Nt(o, t, e, n, i, r, u) {
let s, f, h, p, l, c, a, g, y, b, x, m, d, v, E, S, R, _;
const P = o - i, N = e - i, A = t - r, O = n - r;
v = P * O, c = w * P, a = c - (c - P), g = P - a, c = w * O, y = c - (c - O), b = O - y, E = g * b - (v - a * y - g * y - a * b), S = A * N, c = w * A, a = c - (c - A), g = A - a, c = w * N, y = c - (c - N), b = N - y, R = g * b - (S - a * y - g * y - a * b), x = E - R, l = E - x, q[0] = E - (x + l) + (l - R), m = v + x, l = m - v, d = v - (m - l) + (x - l), x = d - S, l = d - x, q[1] = d - (x + l) + (l - S), _ = m + x, l = _ - m, q[2] = m - (_ - l) + (x - l), q[3] = _;
let T = kt(4, q), F = It * u;
if (T >= F || -T >= F || (l = o - P, s = o - (P + l) + (l - i), l = e - N, h = e - (N + l) + (l - i), l = t - A, f = t - (A + l) + (l - r), l = n - O, p = n - (O + l) + (l - r), s === 0 && f === 0 && h === 0 && p === 0) || (F = Pt * u + wt * Math.abs(T), T += P * p + O * s - (A * h + N * f), T >= F || -T >= F))
return T;
v = s * O, c = w * s, a = c - (c - s), g = s - a, c = w * O, y = c - (c - O), b = O - y, E = g * b - (v - a * y - g * y - a * b), S = f * N, c = w * f, a = c - (c - f), g = f - a, c = w * N, y = c - (c - N), b = N - y, R = g * b - (S - a * y - g * y - a * b), x = E - R, l = E - x, k[0] = E - (x + l) + (l - R), m = v + x, l = m - v, d = v - (m - l) + (x - l), x = d - S, l = d - x, k[1] = d - (x + l) + (l - S), _ = m + x, l = _ - m, k[2] = m - (_ - l) + (x - l), k[3] = _;
const yt = X(4, q, 4, k, nt);
v = P * p, c = w * P, a = c - (c - P), g = P - a, c = w * p, y = c - (c - p), b = p - y, E = g * b - (v - a * y - g * y - a * b), S = A * h, c = w * A, a = c - (c - A), g = A - a, c = w * h, y = c - (c - h), b = h - y, R = g * b - (S - a * y - g * y - a * b), x = E - R, l = E - x, k[0] = E - (x + l) + (l - R), m = v + x, l = m - v, d = v - (m - l) + (x - l), x = d - S, l = d - x, k[1] = d - (x + l) + (l - S), _ = m + x, l = _ - m, k[2] = m - (_ - l) + (x - l), k[3] = _;
const xt = X(yt, nt, 4, k, rt);
v = s * p, c = w * s, a = c - (c - s), g = s - a, c = w * p, y = c - (c - p), b = p - y, E = g * b - (v - a * y - g * y - a * b), S = f * h, c = w * f, a = c - (c - f), g = f - a, c = w * h, y = c - (c - h), b = h - y, R = g * b - (S - a * y - g * y - a * b), x = E - R, l = E - x, k[0] = E - (x + l) + (l - R), m = v + x, l = m - v, d = v - (m - l) + (x - l), x = d - S, l = d - x, k[1] = d - (x + l) + (l - S), _ = m + x, l = _ - m, k[2] = m - (_ - l) + (x - l), k[3] = _;
const bt = X(xt, rt, 4, k, it);
return it[bt - 1];
}
function At(o, t, e, n, i, r) {
const u = (t - r) * (e - i), s = (o - i) * (n - r), f = u - s, h = Math.abs(u + s);
return Math.abs(f) >= Rt * h ? f : -Nt(o, t, e, n, i, r, h);
}
const C = (o, t) => o.ll.x <= t.x && t.x <= o.ur.x && o.ll.y <= t.y && t.y <= o.ur.y, K = (o, t) => {
if (t.ur.x < o.ll.x || o.ur.x < t.ll.x || t.ur.y < o.ll.y || o.ur.y < t.ll.y)
return null;
const e = o.ll.x < t.ll.x ? t.ll.x : o.ll.x, n = o.ur.x < t.ur.x ? o.ur.x : t.ur.x, i = o.ll.y < t.ll.y ? t.ll.y : o.ll.y, r = o.ur.y < t.ur.y ? o.ur.y : t.ur.y;
return {
ll: {
x: e,
y: i
},
ur: {
x: n,
y: r
}
};
};
let $ = Number.EPSILON;
$ === void 0 && ($ = Math.pow(2, -52));
const Ot = $ * $, ot = (o, t) => {
if (-$ < o && o < $ && -$ < t && t < $)
return 0;
const e = o - t;
return e * e < Ot * o * t ? 0 : o < t ? -1 : 1;
};
class Lt {
constructor() {
this.reset();
}
reset() {
this.xRounder = new st(), this.yRounder = new st();
}
round(t, e) {
return {
x: this.xRounder.round(t),
y: this.yRounder.round(e)
};
}
}
class st {
constructor() {
this.tree = new tt(), this.round(0);
}
// Note: this can rounds input values backwards or forwards.
// You might ask, why not restrict this to just rounding
// forwards? Wouldn't that allow left endpoints to always
// remain left endpoints during splitting (never change to
// right). No - it wouldn't, because we snap intersections
// to endpoints (to establish independence from the segment
// angle for t-intersections).
round(t) {
const e = this.tree.add(t), n = this.tree.prev(e);
if (n !== null && ot(e.key, n.key) === 0)
return this.tree.remove(t), n.key;
const i = this.tree.next(e);
return i !== null && ot(e.key, i.key) === 0 ? (this.tree.remove(t), i.key) : t;
}
}
const U = new Lt(), j = (o, t) => o.x * t.y - o.y * t.x, gt = (o, t) => o.x * t.x + o.y * t.y, lt = (o, t, e) => {
const n = At(o.x, o.y, t.x, t.y, e.x, e.y);
return n > 0 ? -1 : n < 0 ? 1 : 0;
}, V = (o) => Math.sqrt(gt(o, o)), Mt = (o, t, e) => {
const n = {
x: t.x - o.x,
y: t.y - o.y
}, i = {
x: e.x - o.x,
y: e.y - o.y
};
return j(i, n) / V(i) / V(n);
}, zt = (o, t, e) => {
const n = {
x: t.x - o.x,
y: t.y - o.y
}, i = {
x: e.x - o.x,
y: e.y - o.y
};
return gt(i, n) / V(i) / V(n);
}, ut = (o, t, e) => t.y === 0 ? null : {
x: o.x + t.x / t.y * (e - o.y),
y: e
}, ht = (o, t, e) => t.x === 0 ? null : {
x: e,
y: o.y + t.y / t.x * (e - o.x)
}, $t = (o, t, e, n) => {
if (t.x === 0)
return ht(e, n, o.x);
if (n.x === 0)
return ht(o, t, e.x);
if (t.y === 0)
return ut(e, n, o.y);
if (n.y === 0)
return ut(o, t, e.y);
const i = j(t, n);
if (i == 0)
return null;
const r = {
x: e.x - o.x,
y: e.y - o.y
}, u = j(r, t) / i, s = j(r, n) / i, f = o.x + s * t.x, h = e.x + u * n.x, p = o.y + s * t.y, l = e.y + u * n.y, c = (f + h) / 2, a = (p + l) / 2;
return {
x: c,
y: a
};
};
class I {
// for ordering sweep events in the sweep event queue
static compare(t, e) {
const n = I.comparePoints(t.point, e.point);
return n !== 0 ? n : (t.point !== e.point && t.link(e), t.isLeft !== e.isLeft ? t.isLeft ? 1 : -1 : B.compare(t.segment, e.segment));
}
// for ordering points in sweep line order
static comparePoints(t, e) {
return t.x < e.x ? -1 : t.x > e.x ? 1 : t.y < e.y ? -1 : t.y > e.y ? 1 : 0;
}
// Warning: 'point' input will be modified and re-used (for performance)
constructor(t, e) {
t.events === void 0 ? t.events = [this] : t.events.push(this), this.point = t, this.isLeft = e;
}
link(t) {
if (t.point === this.point)
throw new Error("Tried to link already linked events");
const e = t.point.events;
for (let n = 0, i = e.length; n < i; n++) {
const r = e[n];
this.point.events.push(r), r.point = this.point;
}
this.checkForConsuming();
}
/* Do a pass over our linked events and check to see if any pair
* of segments match, and should be consumed. */
checkForConsuming() {
const t = this.point.events.length;
for (let e = 0; e < t; e++) {
const n = this.point.events[e];
if (n.segment.consumedBy === void 0)
for (let i = e + 1; i < t; i++) {
const r = this.point.events[i];
r.consumedBy === void 0 && n.otherSE.point.events === r.otherSE.point.events && n.segment.consume(r.segment);
}
}
}
getAvailableLinkedEvents() {
const t = [];
for (let e = 0, n = this.point.events.length; e < n; e++) {
const i = this.point.events[e];
i !== this && !i.segment.ringOut && i.segment.isInResult() && t.push(i);
}
return t;
}
/**
* Returns a comparator function for sorting linked events that will
* favor the event that will give us the smallest left-side angle.
* All ring construction starts as low as possible heading to the right,
* so by always turning left as sharp as possible we'll get polygons
* without uncessary loops & holes.
*
* The comparator function has a compute cache such that it avoids
* re-computing already-computed values.
*/
getLeftmostComparator(t) {
const e = /* @__PURE__ */ new Map(), n = (i) => {
const r = i.otherSE;
e.set(i, {
sine: Mt(this.point, t.point, r.point),
cosine: zt(this.point, t.point, r.point)
});
};
return (i, r) => {
e.has(i) || n(i), e.has(r) || n(r);
const {
sine: u,
cosine: s
} = e.get(i), {
sine: f,
cosine: h
} = e.get(r);
return u >= 0 && f >= 0 ? s < h ? 1 : s > h ? -1 : 0 : u < 0 && f < 0 ? s < h ? -1 : s > h ? 1 : 0 : f < u ? -1 : f > u ? 1 : 0;
};
}
}
let Bt = 0;
class B {
/* This compare() function is for ordering segments in the sweep
* line tree, and does so according to the following criteria:
*
* Consider the vertical line that lies an infinestimal step to the
* right of the right-more of the two left endpoints of the input
* segments. Imagine slowly moving a point up from negative infinity
* in the increasing y direction. Which of the two segments will that
* point intersect first? That segment comes 'before' the other one.
*
* If neither segment would be intersected by such a line, (if one
* or more of the segments are vertical) then the line to be considered
* is directly on the right-more of the two left inputs.
*/
static compare(t, e) {
const n = t.leftSE.point.x, i = e.leftSE.point.x, r = t.rightSE.point.x, u = e.rightSE.point.x;
if (u < n)
return 1;
if (r < i)
return -1;
const s = t.leftSE.point.y, f = e.leftSE.point.y, h = t.rightSE.point.y, p = e.rightSE.point.y;
if (n < i) {
if (f < s && f < h)
return 1;
if (f > s && f > h)
return -1;
const l = t.comparePoint(e.leftSE.point);
if (l < 0)
return 1;
if (l > 0)
return -1;
const c = e.comparePoint(t.rightSE.point);
return c !== 0 ? c : -1;
}
if (n > i) {
if (s < f && s < p)
return -1;
if (s > f && s > p)
return 1;
const l = e.comparePoint(t.leftSE.point);
if (l !== 0)
return l;
const c = t.comparePoint(e.rightSE.point);
return c < 0 ? 1 : c > 0 ? -1 : 1;
}
if (s < f)
return -1;
if (s > f)
return 1;
if (r < u) {
const l = e.comparePoint(t.rightSE.point);
if (l !== 0)
return l;
}
if (r > u) {
const l = t.comparePoint(e.rightSE.point);
if (l < 0)
return 1;
if (l > 0)
return -1;
}
if (r !== u) {
const l = h - s, c = r - n, a = p - f, g = u - i;
if (l > c && a < g)
return 1;
if (l < c && a > g)
return -1;
}
return r > u ? 1 : r < u || h < p ? -1 : h > p ? 1 : t.id < e.id ? -1 : t.id > e.id ? 1 : 0;
}
/* Warning: a reference to ringWindings input will be stored,
* and possibly will be later modified */
constructor(t, e, n, i) {
this.id = ++Bt, this.leftSE = t, t.segment = this, t.otherSE = e, this.rightSE = e, e.segment = this, e.otherSE = t, this.rings = n, this.windings = i;
}
static fromRing(t, e, n) {
let i, r, u;
const s = I.comparePoints(t, e);
if (s < 0)
i = t, r = e, u = 1;
else if (s > 0)
i = e, r = t, u = -1;
else
throw new Error(`Tried to create degenerate segment at [${t.x}, ${t.y}]`);
const f = new I(i, !0), h = new I(r, !1);
return new B(f, h, [n], [u]);
}
/* When a segment is split, the rightSE is replaced with a new sweep event */
replaceRightSE(t) {
this.rightSE = t, this.rightSE.segment = this, this.rightSE.otherSE = this.leftSE, this.leftSE.otherSE = this.rightSE;
}
bbox() {
const t = this.leftSE.point.y, e = this.rightSE.point.y;
return {
ll: {
x: this.leftSE.point.x,
y: t < e ? t : e
},
ur: {
x: this.rightSE.point.x,
y: t > e ? t : e
}
};
}
/* A vector from the left point to the right */
vector() {
return {
x: this.rightSE.point.x - this.leftSE.point.x,
y: this.rightSE.point.y - this.leftSE.point.y
};
}
isAnEndpoint(t) {
return t.x === this.leftSE.point.x && t.y === this.leftSE.point.y || t.x === this.rightSE.point.x && t.y === this.rightSE.point.y;
}
/* Compare this segment with a point.
*
* A point P is considered to be colinear to a segment if there
* exists a distance D such that if we travel along the segment
* from one * endpoint towards the other a distance D, we find
* ourselves at point P.
*
* Return value indicates:
*
* 1: point lies above the segment (to the left of vertical)
* 0: point is colinear to segment
* -1: point lies below the segment (to the right of vertical)
*/
comparePoint(t) {
if (this.isAnEndpoint(t))
return 0;
const e = this.leftSE.point, n = this.rightSE.point, i = this.vector();
if (e.x === n.x)
return t.x === e.x ? 0 : t.x < e.x ? 1 : -1;
const r = (t.y - e.y) / i.y, u = e.x + r * i.x;
if (t.x === u)
return 0;
const s = (t.x - e.x) / i.x, f = e.y + s * i.y;
return t.y === f ? 0 : t.y < f ? -1 : 1;
}
/**
* Given another segment, returns the first non-trivial intersection
* between the two segments (in terms of sweep line ordering), if it exists.
*
* A 'non-trivial' intersection is one that will cause one or both of the
* segments to be split(). As such, 'trivial' vs. 'non-trivial' intersection:
*
* * endpoint of segA with endpoint of segB --> trivial
* * endpoint of segA with point along segB --> non-trivial
* * endpoint of segB with point along segA --> non-trivial
* * point along segA with point along segB --> non-trivial
*
* If no non-trivial intersection exists, return null
* Else, return null.
*/
getIntersection(t) {
const e = this.bbox(), n = t.bbox(), i = K(e, n);
if (i === null)
return null;
const r = this.leftSE.point, u = this.rightSE.point, s = t.leftSE.point, f = t.rightSE.point, h = C(e, s) && this.comparePoint(s) === 0, p = C(n, r) && t.comparePoint(r) === 0, l = C(e, f) && this.comparePoint(f) === 0, c = C(n, u) && t.comparePoint(u) === 0;
if (p && h)
return c && !l ? u : !c && l ? f : null;
if (p)
return l && r.x === f.x && r.y === f.y ? null : r;
if (h)
return c && u.x === s.x && u.y === s.y ? null : s;
if (c && l)
return null;
if (c)
return u;
if (l)
return f;
const a = $t(r, this.vector(), s, t.vector());
return a === null || !C(i, a) ? null : U.round(a.x, a.y);
}
/**
* Split the given segment into multiple segments on the given points.
* * Each existing segment will retain its leftSE and a new rightSE will be
* generated for it.
* * A new segment will be generated which will adopt the original segment's
* rightSE, and a new leftSE will be generated for it.
* * If there are more than two points given to split on, new segments
* in the middle will be generated with new leftSE and rightSE's.
* * An array of the newly generated SweepEvents will be returned.
*
* Warning: input array of points is modified
*/
split(t) {
const e = [], n = t.events !== void 0, i = new I(t, !0), r = new I(t, !1), u = this.rightSE;
this.replaceRightSE(r), e.push(r), e.push(i);
const s = new B(i, u, this.rings.slice(), this.windings.slice());
return I.comparePoints(s.leftSE.point, s.rightSE.point) > 0 && s.swapEvents(), I.comparePoints(this.leftSE.point, this.rightSE.point) > 0 && this.swapEvents(), n && (i.checkForConsuming(), r.checkForConsuming()), e;
}
/* Swap which event is left and right */
swapEvents() {
const t = this.rightSE;
this.rightSE = this.leftSE, this.leftSE = t, this.leftSE.isLeft = !0, this.rightSE.isLeft = !1;
for (let e = 0, n = this.windings.length; e < n; e++)
this.windings[e] *= -1;
}
/* Consume another segment. We take their rings under our wing
* and mark them as consumed. Use for perfectly overlapping segments */
consume(t) {
let e = this, n = t;
for (; e.consumedBy; )
e = e.consumedBy;
for (; n.consumedBy; )
n = n.consumedBy;
const i = B.compare(e, n);
if (i !== 0) {
if (i > 0) {
const r = e;
e = n, n = r;
}
if (e.prev === n) {
const r = e;
e = n, n = r;
}
for (let r = 0, u = n.rings.length; r < u; r++) {
const s = n.rings[r], f = n.windings[r], h = e.rings.indexOf(s);
h === -1 ? (e.rings.push(s), e.windings.push(f)) : e.windings[h] += f;
}
n.rings = null, n.windings = null, n.consumedBy = e, n.leftSE.consumedBy = e.leftSE, n.rightSE.consumedBy = e.rightSE;
}
}
/* The first segment previous segment chain that is in the result */
prevInResult() {
return this._prevInResult !== void 0 ? this._prevInResult : (this.prev ? this.prev.isInResult() ? this._prevInResult = this.prev : this._prevInResult = this.prev.prevInResult() : this._prevInResult = null, this._prevInResult);
}
beforeState() {
if (this._beforeState !== void 0)
return this._beforeState;
if (!this.prev)
this._beforeState = {
rings: [],
windings: [],
multiPolys: []
};
else {
const t = this.prev.consumedBy || this.prev;
this._beforeState = t.afterState();
}
return this._beforeState;
}
afterState() {
if (this._afterState !== void 0)
return this._afterState;
const t = this.beforeState();
this._afterState = {
rings: t.rings.slice(0),
windings: t.windings.slice(0),
multiPolys: []
};
const e = this._afterState.rings, n = this._afterState.windings, i = this._afterState.multiPolys;
for (let s = 0, f = this.rings.length; s < f; s++) {
const h = this.rings[s], p = this.windings[s], l = e.indexOf(h);
l === -1 ? (e.push(h), n.push(p)) : n[l] += p;
}
const r = [], u = [];
for (let s = 0, f = e.length; s < f; s++) {
if (n[s] === 0)
continue;
const h = e[s], p = h.poly;
if (u.indexOf(p) === -1)
if (h.isExterior)
r.push(p);
else {
u.indexOf(p) === -1 && u.push(p);
const l = r.indexOf(h.poly);
l !== -1 && r.splice(l, 1);
}
}
for (let s = 0, f = r.length; s < f; s++) {
const h = r[s].multiPoly;
i.indexOf(h) === -1 && i.push(h);
}
return this._afterState;
}
/* Is this segment part of the final result? */
isInResult() {
if (this.consumedBy)
return !1;
if (this._isInResult !== void 0)
return this._isInResult;
const t = this.beforeState().multiPolys, e = this.afterState().multiPolys;
switch (L.type) {
case "union": {
const n = t.length === 0, i = e.length === 0;
this._isInResult = n !== i;
break;
}
case "intersection": {
let n, i;
t.length < e.length ? (n = t.length, i = e.length) : (n = e.length, i = t.length), this._isInResult = i === L.numMultiPolys && n < i;
break;
}
case "xor": {
const n = Math.abs(t.length - e.length);
this._isInResult = n % 2 === 1;
break;
}
case "difference": {
const n = (i) => i.length === 1 && i[0].isSubject;
this._isInResult = n(t) !== n(e);
break;
}
default:
throw new Error(`Unrecognized operation type found ${L.type}`);
}
return this._isInResult;
}
}
class ft {
constructor(t, e, n) {
if (!Array.isArray(t) || t.length === 0)
throw new Error("Input geometry is not a valid Polygon or MultiPolygon");
if (this.poly = e, this.isExterior = n, this.segments = [], typeof t[0][0] != "number" || typeof t[0][1] != "number")
throw new Error("Input geometry is not a valid Polygon or MultiPolygon");
const i = U.round(t[0][0], t[0][1]);
this.bbox = {
ll: {
x: i.x,
y: i.y
},
ur: {
x: i.x,
y: i.y
}
};
let r = i;
for (let u = 1, s = t.length; u < s; u++) {
if (typeof t[u][0] != "number" || typeof t[u][1] != "number")
throw new Error("Input geometry is not a valid Polygon or MultiPolygon");
let f = U.round(t[u][0], t[u][1]);
f.x === r.x && f.y === r.y || (this.segments.push(B.fromRing(r, f, this)), f.x < this.bbox.ll.x && (this.bbox.ll.x = f.x), f.y < this.bbox.ll.y && (this.bbox.ll.y = f.y), f.x > this.bbox.ur.x && (this.bbox.ur.x = f.x), f.y > this.bbox.ur.y && (this.bbox.ur.y = f.y), r = f);
}
(i.x !== r.x || i.y !== r.y) && this.segments.push(B.fromRing(r, i, this));
}
getSweepEvents() {
const t = [];
for (let e = 0, n = this.segments.length; e < n; e++) {
const i = this.segments[e];
t.push(i.leftSE), t.push(i.rightSE);
}
return t;
}
}
class Gt {
constructor(t, e) {
if (!Array.isArray(t))
throw new Error("Input geometry is not a valid Polygon or MultiPolygon");
this.exteriorRing = new ft(t[0], this, !0), this.bbox = {
ll: {
x: this.exteriorRing.bbox.ll.x,
y: this.exteriorRing.bbox.ll.y
},
ur: {
x: this.exteriorRing.bbox.ur.x,
y: this.exteriorRing.bbox.ur.y
}
}, this.interiorRings = [];
for (let n = 1, i = t.length; n < i; n++) {
const r = new ft(t[n], this, !1);
r.bbox.ll.x < this.bbox.ll.x && (this.bbox.ll.x = r.bbox.ll.x), r.bbox.ll.y < this.bbox.ll.y && (this.bbox.ll.y = r.bbox.ll.y), r.bbox.ur.x > this.bbox.ur.x && (this.bbox.ur.x = r.bbox.ur.x), r.bbox.ur.y > this.bbox.ur.y && (this.bbox.ur.y = r.bbox.ur.y), this.interiorRings.push(r);
}
this.multiPoly = e;
}
getSweepEvents() {
const t = this.exteriorRing.getSweepEvents();
for (let e = 0, n = this.interiorRings.length; e < n; e++) {
const i = this.interiorRings[e].getSweepEvents();
for (let r = 0, u = i.length; r < u; r++)
t.push(i[r]);
}
return t;
}
}
class ct {
constructor(t, e) {
if (!Array.isArray(t))
throw new Error("Input geometry is not a valid Polygon or MultiPolygon");
try {
typeof t[0][0][0] == "number" && (t = [t]);
} catch {
}
this.polys = [], this.bbox = {
ll: {
x: Number.POSITIVE_INFINITY,
y: Number.POSITIVE_INFINITY
},
ur: {
x: Number.NEGATIVE_INFINITY,
y: Number.NEGATIVE_INFINITY
}
};
for (let n = 0, i = t.length; n < i; n++) {
const r = new Gt(t[n], this);
r.bbox.ll.x < this.bbox.ll.x && (this.bbox.ll.x = r.bbox.ll.x), r.bbox.ll.y < this.bbox.ll.y && (this.bbox.ll.y = r.bbox.ll.y), r.bbox.ur.x > this.bbox.ur.x && (this.bbox.ur.x = r.bbox.ur.x), r.bbox.ur.y > this.bbox.ur.y && (this.bbox.ur.y = r.bbox.ur.y), this.polys.push(r);
}
this.isSubject = e;
}
getSweepEvents() {
const t = [];
for (let e = 0, n = this.polys.length; e < n; e++) {
const i = this.polys[e].getSweepEvents();
for (let r = 0, u = i.length; r < u; r++)
t.push(i[r]);
}
return t;
}
}
class Q {
/* Given the segments from the sweep line pass, compute & return a series
* of closed rings from all the segments marked to be part of the result */
static factory(t) {
const e = [];
for (let n = 0, i = t.length; n < i; n++) {
const r = t[n];
if (!r.isInResult() || r.ringOut)
continue;
let u = null, s = r.leftSE, f = r.rightSE;
const h = [s], p = s.point, l = [];
for (; u = s, s = f, h.push(s), s.point !== p; )
for (; ; ) {
const c = s.getAvailableLinkedEvents();
if (c.length === 0) {
const y = h[0].point, b = h[h.length - 1].point;
throw new Error(`Unable to complete output ring starting at [${y.x}, ${y.y}]. Last matching segment found ends at [${b.x}, ${b.y}].`);
}
if (c.length === 1) {
f = c[0].otherSE;
break;
}
let a = null;
for (let y = 0, b = l.length; y < b; y++)
if (l[y].point === s.point) {
a = y;
break;
}
if (a !== null) {
const y = l.splice(a)[0], b = h.splice(y.index);
b.unshift(b[0].otherSE), e.push(new Q(b.reverse()));
continue;
}
l.push({
index: h.length,
point: s.point
});
const g = s.getLeftmostComparator(u);
f = c.sort(g)[0].otherSE;
break;
}
e.push(new Q(h));
}
return e;
}
constructor(t) {
this.events = t;
for (let e = 0, n = t.length; e < n; e++)
t[e].segment.ringOut = this;
this.poly = null;
}
getGeom() {
let t = this.events[0].point;
const e = [t];
for (let h = 1, p = this.events.length - 1; h < p; h++) {
const l = this.events[h].point, c = this.events[h + 1].point;
lt(l, t, c) !== 0 && (e.push(l), t = l);
}
if (e.length === 1)
return null;
const n = e[0], i = e[1];
lt(n, t, i) === 0 && e.shift(), e.push(e[0]);
const r = this.isExteriorRing() ? 1 : -1, u = this.isExteriorRing() ? 0 : e.length - 1, s = this.isExteriorRing() ? e.length : -1, f = [];
for (let h = u; h != s; h += r)
f.push([e[h].x, e[h].y]);
return f;
}
isExteriorRing() {
if (this._isExteriorRing === void 0) {
const t = this.enclosingRing();
this._isExteriorRing = t ? !t.isExteriorRing() : !0;
}
return this._isExteriorRing;
}
enclosingRing() {
return this._enclosingRing === void 0 && (this._enclosingRing = this._calcEnclosingRing()), this._enclosingRing;
}
/* Returns the ring that encloses this one, if any */
_calcEnclosingRing() {
let t = this.events[0];
for (let i = 1, r = this.events.length; i < r; i++) {
const u = this.events[i];
I.compare(t, u) > 0 && (t = u);
}
let e = t.segment.prevInResult(), n = e ? e.prevInResult() : null;
for (; ; ) {
if (!e)
return null;
if (!n)
return e.ringOut;
if (n.ringOut !== e.ringOut)
return n.ringOut.enclosingRing() !== e.ringOut ? e.ringOut : e.ringOut.enclosingRing();
e = n.prevInResult(), n = e ? e.prevInResult() : null;
}
}
}
class pt {
constructor(t) {
this.exteriorRing = t, t.poly = this, this.interiorRings = [];
}
addInterior(t) {
this.interiorRings.push(t), t.poly = this;
}
getGeom() {
const t = [this.exteriorRing.getGeom()];
if (t[0] === null)
return null;
for (let e = 0, n = this.interiorRings.length; e < n; e++) {
const i = this.interiorRings[e].getGeom();
i !== null && t.push(i);
}
return t;
}
}
class Tt {
constructor(t) {
this.rings = t, this.polys = this._composePolys(t);
}
getGeom() {
const t = [];
for (let e = 0, n = this.polys.length; e < n; e++) {
const i = this.polys[e].getGeom();
i !== null && t.push(i);
}
return t;
}
_composePolys(t) {
const e = [];
for (let n = 0, i = t.length; n < i; n++) {
const r = t[n];
if (!r.poly)
if (r.isExteriorRing())
e.push(new pt(r));
else {
const u = r.enclosingRing();
u.poly || e.push(new pt(u)), u.poly.addInterior(r);
}
}
return e;
}
}
class qt {
constructor(t) {
let e = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : B.compare;
this.queue = t, this.tree = new tt(e), this.segments = [];
}
process(t) {
const e = t.segment, n = [];
if (t.consumedBy)
return t.isLeft ? this.queue.remove(t.otherSE) : this.tree.remove(e), n;
const i = t.isLeft ? this.tree.add(e) : this.tree.find(e);
if (!i)
throw new Error(`Unable to find segment #${e.id} [${e.leftSE.point.x}, ${e.leftSE.point.y}] -> [${e.rightSE.point.x}, ${e.rightSE.point.y}] in SweepLine tree.`);
let r = i, u = i, s, f;
for (; s === void 0; )
r = this.tree.prev(r), r === null ? s = null : r.key.consumedBy === void 0 && (s = r.key);
for (; f === void 0; )
u = this.tree.next(u), u === null ? f = null : u.key.consumedBy === void 0 && (f = u.key);
if (t.isLeft) {
let h = null;
if (s) {
const l = s.getIntersection(e);
if (l !== null && (e.isAnEndpoint(l) || (h = l), !s.isAnEndpoint(l))) {
const c = this._splitSafely(s, l);
for (let a = 0, g = c.length; a < g; a++)
n.push(c[a]);
}
}
let p = null;
if (f) {
const l = f.getIntersection(e);
if (l !== null && (e.isAnEndpoint(l) || (p = l), !f.isAnEndpoint(l))) {
const c = this._splitSafely(f, l);
for (let a = 0, g = c.length; a < g; a++)
n.push(c[a]);
}
}
if (h !== null || p !== null) {
let l = null;
h === null ? l = p : p === null ? l = h : l = I.comparePoints(h, p) <= 0 ? h : p, this.queue.remove(e.rightSE), n.push(e.rightSE);
const c = e.split(l);
for (let a = 0, g = c.length; a < g; a++)
n.push(c[a]);
}
n.length > 0 ? (this.tree.remove(e), n.push(t)) : (this.segments.push(e), e.prev = s);
} else {
if (s && f) {
const h = s.getIntersection(f);
if (h !== null) {
if (!s.isAnEndpoint(h)) {
const p = this._splitSafely(s, h);
for (let l = 0, c = p.length; l < c; l++)
n.push(p[l]);
}
if (!f.isAnEndpoint(h)) {
const p = this._splitSafely(f, h);
for (let l = 0, c = p.length; l < c; l++)
n.push(p[l]);
}
}
}
this.tree.remove(e);
}
return n;
}
/* Safely split a segment that is currently in the datastructures
* IE - a segment other than the one that is currently being processed. */
_splitSafely(t, e) {
this.tree.remove(t);
const n = t.rightSE;
this.queue.remove(n);
const i = t.split(e);
return i.push(n), t.consumedBy === void 0 && this.tree.add(t), i;
}
}
const at = typeof process < "u" && process.env.POLYGON_CLIPPING_MAX_QUEUE_SIZE || 1e6, Ft = typeof process < "u" && process.env.POLYGON_CLIPPING_MAX_SWEEPLINE_SEGMENTS || 1e6;
class Ct {
run(t, e, n) {
L.type = t, U.reset();
const i = [new ct(e, !0)];
for (let p = 0, l = n.length; p < l; p++)
i.push(new ct(n[p], !1));
if (L.numMultiPolys = i.length, L.type === "difference") {
const p = i[0];
let l = 1;
for (; l < i.length; )
K(i[l].bbox, p.bbox) !== null ? l++ : i.splice(l, 1);
}
if (L.type === "intersection")
for (let p = 0, l = i.length; p < l; p++) {
const c = i[p];
for (let a = p + 1, g = i.length; a < g; a++)
if (K(c.bbox, i[a].bbox) === null)
return [];
}
const r = new tt(I.compare);
for (let p = 0, l = i.length; p < l; p++) {
const c = i[p].getSweepEvents();
for (let a = 0, g = c.length; a < g; a++)
if (r.insert(c[a]), r.size > at)
throw new Error("Infinite loop when putting segment endpoints in a priority queue (queue size too big).");
}
const u = new qt(r);
let s = r.size, f = r.pop();
for (; f; ) {
const p = f.key;
if (r.size === s) {
const c = p.segment;
throw new Error(`Unable to pop() ${p.isLeft ? "left" : "right"} SweepEvent [${p.point.x}, ${p.point.y}] from segment #${c.id} [${c.leftSE.point.x}, ${c.leftSE.point.y}] -> [${c.rightSE.point.x}, ${c.rightSE.point.y}] from queue.`);
}
if (r.size > at)
throw new Error("Infinite loop when passing sweep line over endpoints (queue size too big).");
if (u.segments.length > Ft)
throw new Error("Infinite loop when passing sweep line over endpoints (too many sweep line segments).");
const l = u.process(p);
for (let c = 0, a = l.length; c < a; c++) {
const g = l[c];
g.consumedBy === void 0 && r.insert(g);
}
s = r.size, f = r.pop();
}
U.reset();
const h = Q.factory(u.segments);
return new Tt(h).getGeom();
}
}
const L = new Ct(), Ut = function(o) {
for (var t = arguments.length, e = new Array(t > 1 ? t - 1 : 0), n = 1; n < t; n++)
e[n - 1] = arguments[n];
return L.run("union", o, e);
}, Yt = function(o) {
for (var t = arguments.length, e = new Array(t > 1 ? t - 1 : 0), n = 1; n < t; n++)
e[n - 1] = arguments[n];
return L.run("intersection", o, e);
}, jt = function(o) {
for (var t = arguments.length, e = new Array(t > 1 ? t - 1 : 0), n = 1; n < t; n++)
e[n - 1] = arguments[n];
return L.run("xor", o, e);
}, Vt = function(o) {
for (var t = arguments.length, e = new Array(t > 1 ? t - 1 : 0), n = 1; n < t; n++)
e[n - 1] = arguments[n];
return L.run("difference", o, e);
};
var Qt = {
union: Ut,
intersection: Yt,
xor: jt,
difference: Vt
};
export {
Qt as default
};