UNPKG

@labelu/image-annotator-react

Version:
1,324 lines (1,321 loc) 46.9 kB
/** * 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 };