UNPKG

@arl/leaflet-tracksymbol2

Version:
1,644 lines 186 kB
import Qt, { LatLng as Lt, Path as On, Util as He, Bounds as Nn, LatLngBounds as Cn, Point as Rn, DomUtil as Mn } from "leaflet"; const Ge = !0, Un = !1, Dt = { CCW: -1, CW: 1, NOT_ORIENTABLE: 0 }, Fn = 2 * Math.PI, Wt = 1, qe = 0, D = 2, kn = 3, Bn = 4, Vn = 1, $n = 2, de = 0, bt = 1, mt = 2; var zt = /* @__PURE__ */ Object.freeze({ __proto__: null, BOUNDARY: D, CCW: Ge, CONTAINS: kn, CW: Un, END_VERTEX: mt, INSIDE: Wt, INTERLACE: Bn, NOT_VERTEX: de, ORIENTATION: Dt, OUTSIDE: qe, OVERLAP_OPPOSITE: $n, OVERLAP_SAME: Vn, PIx2: Fn, START_VERTEX: bt }); let Y = 1e-6; function De(r) { Y = r; } function We() { return Y; } const Hn = 3; function ie(r) { return r < Y && r > -Y; } function rt(r, t) { return r - t < Y && r - t > -Y; } function ze(r, t) { return r - t > Y; } function Gn(r, t) { return r - t > -Y; } function Ye(r, t) { return r - t < -Y; } function qn(r, t) { return r - t < Y; } var Dn = /* @__PURE__ */ Object.freeze({ __proto__: null, DECIMALS: Hn, EQ: rt, EQ_0: ie, GE: Gn, GT: ze, LE: qn, LT: Ye, getTolerance: We, setTolerance: De }); let i = { Utils: Dn, Errors: void 0, Matrix: void 0, Planar_set: void 0, Point: void 0, Vector: void 0, Line: void 0, Circle: void 0, Segment: void 0, Arc: void 0, Box: void 0, Edge: void 0, Face: void 0, Ray: void 0, Ray_shooting: void 0, Multiline: void 0, Polygon: void 0, Distance: void 0, Inversion: void 0 }; for (let r in zt) i[r] = zt[r]; Object.defineProperty(i, "DP_TOL", { get: function() { return We(); }, set: function(r) { De(r); } }); class T { /** * Throw error ILLEGAL_PARAMETERS when cannot instantiate from given parameter * @returns {ReferenceError} */ static get ILLEGAL_PARAMETERS() { return new ReferenceError("Illegal Parameters"); } /** * Throw error ZERO_DIVISION to catch situation of zero division * @returns {Error} */ static get ZERO_DIVISION() { return new Error("Zero division"); } /** * Error to throw from BooleanOperations module in case when fixBoundaryConflicts not capable to fix it * @returns {Error} */ static get UNRESOLVED_BOUNDARY_CONFLICT() { return new Error("Unresolved boundary conflict in boolean operation"); } /** * Error to throw from LinkedList:testInfiniteLoop static method * in case when circular loop detected in linked list * @returns {Error} */ static get INFINITE_LOOP() { return new Error("Infinite loop"); } static get CANNOT_COMPLETE_BOOLEAN_OPERATION() { return new Error("Cannot complete boolean operation"); } static get CANNOT_INVOKE_ABSTRACT_METHOD() { return new Error("Abstract method cannot be invoked"); } static get OPERATION_IS_NOT_SUPPORTED() { return new Error("Operation is not supported"); } static get UNSUPPORTED_SHAPE_TYPE() { return new Error("Unsupported shape type"); } } i.Errors = T; class ge { constructor(t, e) { this.first = t, this.last = e || this.first; } [Symbol.iterator]() { let t; return { next: () => (t = t ? t.next : this.first, { value: t, done: t === void 0 }) }; } /** * Return number of elements in the list * @returns {number} */ get size() { let t = 0; for (let e of this) t++; return t; } /** * Return array of elements from start to end, * If start or end not defined, take first as start, last as end * @returns {Array} */ toArray(t = void 0, e = void 0) { let n = [], s = t || this.first, l = e || this.last, o = s; if (o === void 0) return n; do n.push(o), o = o.next; while (o !== l.next); return n; } /** * Append new element to the end of the list * @param {LinkedListElement} element * @returns {LinkedList} */ append(t) { return this.isEmpty() ? this.first = t : (t.prev = this.last, this.last.next = t), this.last = t, this.last.next = void 0, this.first.prev = void 0, this; } /** * Insert new element to the list after elementBefore * @param {LinkedListElement} newElement * @param {LinkedListElement} elementBefore * @returns {LinkedList} */ insert(t, e) { if (this.isEmpty()) this.first = t, this.last = t; else if (e == null) t.next = this.first, this.first.prev = t, this.first = t; else { let n = e.next; e.next = t, n && (n.prev = t), t.prev = e, t.next = n, this.last === e && (this.last = t); } return this.last.next = void 0, this.first.prev = void 0, this; } /** * Remove element from the list * @param {LinkedListElement} element * @returns {LinkedList} */ remove(t) { return t === this.first && t === this.last ? (this.first = void 0, this.last = void 0) : (t.prev && (t.prev.next = t.next), t.next && (t.next.prev = t.prev), t === this.first && (this.first = t.next), t === this.last && (this.last = t.prev)), this; } /** * Return true if list is empty * @returns {boolean} */ isEmpty() { return this.first === void 0; } /** * Throw an error if circular loop detected in the linked list * @param {LinkedListElement} first element to start iteration * @throws {Errors.INFINITE_LOOP} */ static testInfiniteLoop(t) { let e = t, n = t; do { if (e != t && e === n) throw T.INFINITE_LOOP; e = e.next, n = n.next.next; } while (e != t); } } const Se = { stroke: "black" }; class Wn { constructor(t = Se) { for (const e in t) this[e] = t[e]; this.stroke = t.stroke ?? Se.stroke; } toAttributesString() { return Object.keys(this).reduce( (t, e) => t + (this[e] !== void 0 ? this.toAttrString(e, this[e]) : ""), "" ); } toAttrString(t, e) { const n = t === "className" ? "class" : this.convertCamelToKebabCase(t); return e === null ? `${n} ` : `${n}="${e.toString()}" `; } convertCamelToKebabCase(t) { return t.match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g).join("-").toLowerCase(); } } function ot(r) { return new Wn(r).toAttributesString(); } function It(r, t) { let e = [], [n, s, l] = r.standard, [o, a, u] = t.standard, h = n * a - s * o, f = l * a - s * u, g = n * u - l * o; if (!i.Utils.EQ_0(h)) { let _, v; s === 0 ? (_ = l / n, v = g / h) : a === 0 ? (_ = u / o, v = g / h) : n === 0 ? (_ = f / h, v = l / s) : o === 0 ? (_ = f / h, v = u / a) : (_ = f / h, v = g / h), e.push(new i.Point(_, v)); } return e; } function lt(r, t) { let e = [], n = t.pc.projectionOn(r), s = t.pc.distanceTo(n)[0]; if (i.Utils.EQ(s, t.r)) e.push(n); else if (i.Utils.LT(s, t.r)) { let l = Math.sqrt(t.r * t.r - s * s), o, a; o = r.norm.rotate90CCW().multiply(l), a = n.translate(o), e.push(a), o = r.norm.rotate90CW().multiply(l), a = n.translate(o), e.push(a); } return e; } function Et(r, t) { let e = []; for (let n of t.toSegments()) { let s = Ft(n, r); for (let l of s) nn(l, e) || e.push(l); } return e; } function jt(r, t) { let e = []; if (Et(r, t.box).length === 0) return e; let n = new i.Circle(t.pc, t.r), s = lt(r, n); for (let l of s) l.on(t) && e.push(l); return e; } function Ft(r, t) { let e = []; if (r.ps.on(t) && e.push(r.ps), r.pe.on(t) && !r.isZeroLength() && e.push(r.pe), e.length > 0 || r.isZeroLength() || r.ps.leftTo(t) && r.pe.leftTo(t) || !r.ps.leftTo(t) && !r.pe.leftTo(t)) return e; let n = new i.Line(r.ps, r.pe); return It(n, t); } function Zt(r, t) { let e = []; if (r.box.not_intersect(t.box)) return e; if (r.isZeroLength()) return r.ps.on(t) && e.push(r.ps), e; if (t.isZeroLength()) return t.ps.on(r) && e.push(t.ps), e; let n = new i.Line(r.ps, r.pe), s = new i.Line(t.ps, t.pe); if (n.incidentTo(s)) r.ps.on(t) && e.push(r.ps), r.pe.on(t) && e.push(r.pe), t.ps.on(r) && !t.ps.equalTo(r.ps) && !t.ps.equalTo(r.pe) && e.push(t.ps), t.pe.on(r) && !t.pe.equalTo(r.ps) && !t.pe.equalTo(r.pe) && e.push(t.pe); else { let l = It(n, s); l.length > 0 && ye(l[0], r) && ye(l[0], t) && e.push(l[0]); } return e; } function ye(r, t) { const e = t.box; return i.Utils.LE(r.x, e.xmax) && i.Utils.GE(r.x, e.xmin) && i.Utils.LE(r.y, e.ymax) && i.Utils.GE(r.y, e.ymin); } function Xt(r, t) { let e = []; if (r.box.not_intersect(t.box)) return e; if (r.isZeroLength()) { let [l, o] = r.ps.distanceTo(t.pc); return i.Utils.EQ(l, t.r) && e.push(r.ps), e; } let n = new i.Line(r.ps, r.pe), s = lt(n, t); for (let l of s) l.on(r) && e.push(l); return e; } function vt(r, t) { let e = []; if (r.box.not_intersect(t.box)) return e; if (r.isZeroLength()) return r.ps.on(t) && e.push(r.ps), e; let n = new i.Line(r.ps, r.pe), s = new i.Circle(t.pc, t.r), l = lt(n, s); for (let o of l) o.on(r) && o.on(t) && e.push(o); return e; } function zn(r, t) { let e = []; for (let n of t.toSegments()) { let s = Zt(n, r); for (let l of s) e.push(l); } return e; } function Qe(r, t) { let e = []; if (r.box.not_intersect(t.box)) return e; let n = new i.Vector(r.pc, t.pc), s = r.r, l = t.r; if (i.Utils.EQ_0(s) || i.Utils.EQ_0(l)) return e; if (i.Utils.EQ_0(n.x) && i.Utils.EQ_0(n.y) && i.Utils.EQ(s, l)) return e.push(r.pc.translate(-s, 0)), e; let o = r.pc.distanceTo(t.pc)[0]; if (i.Utils.GT(o, s + l) || i.Utils.LT(o, Math.abs(s - l))) return e; n.x /= o, n.y /= o; let a; if (i.Utils.EQ(o, s + l) || i.Utils.EQ(o, Math.abs(s - l))) return a = r.pc.translate(s * n.x, s * n.y), e.push(a), e; let u = s * s / (2 * o) - l * l / (2 * o) + o / 2, h = r.pc.translate(u * n.x, u * n.y), f = Math.sqrt(s * s - u * u); return a = h.translate(n.rotate90CCW().multiply(f)), e.push(a), a = h.translate(n.rotate90CW().multiply(f)), e.push(a), e; } function Yn(r, t) { let e = []; for (let n of t.toSegments()) { let s = Xt(n, r); for (let l of s) e.push(l); } return e; } function je(r, t) { let e = []; if (r.box.not_intersect(t.box)) return e; if (r.pc.equalTo(t.pc) && i.Utils.EQ(r.r, t.r)) { let o; return o = r.start, o.on(t) && e.push(o), o = r.end, o.on(t) && e.push(o), o = t.start, o.on(r) && e.push(o), o = t.end, o.on(r) && e.push(o), e; } let n = new i.Circle(r.pc, r.r), s = new i.Circle(t.pc, t.r), l = n.intersect(s); for (let o of l) o.on(r) && o.on(t) && e.push(o); return e; } function pe(r, t) { let e = []; if (r.box.not_intersect(t.box)) return e; if (t.pc.equalTo(r.pc) && i.Utils.EQ(t.r, r.r)) return e.push(r.start), e.push(r.end), e; let n = t, s = new i.Circle(r.pc, r.r), l = Qe(n, s); for (let o of l) o.on(r) && e.push(o); return e; } function Qn(r, t) { let e = []; for (let n of t.toSegments()) { let s = vt(n, r); for (let l of s) e.push(l); } return e; } function Ze(r, t) { return r.isSegment ? Zt(r.shape, t) : vt(t, r.shape); } function Xe(r, t) { return r.isSegment ? vt(r.shape, t) : je(r.shape, t); } function Ke(r, t) { return r.isSegment ? Ft(r.shape, t) : jt(t, r.shape); } function jn(r, t) { return r.isSegment ? Ee(t, r.shape) : xe(t, r.shape); } function Zn(r, t) { return r.isSegment ? Xt(r.shape, t) : pe(r.shape, t); } function _e(r, t) { let e = []; for (let n of t.edges) for (let s of Ze(n, r)) e.push(s); return e; } function me(r, t) { let e = []; for (let n of t.edges) for (let s of Xe(n, r)) e.push(s); return e; } function kt(r, t) { let e = []; if (t.isEmpty()) return e; for (let n of t.edges) for (let s of Ke(n, r)) nn(s, e) || e.push(s); return r.sortPoints(e); } function Je(r, t) { let e = []; if (t.isEmpty()) return e; for (let n of t.edges) for (let s of Zn(n, r)) e.push(s); return e; } function tn(r, t) { return r.isSegment ? Ze(t, r.shape) : r.isArc ? Xe(t, r.shape) : r.isLine ? Ke(t, r.shape) : r.isRay ? jn(t, r.shape) : []; } function en(r, t) { let e = []; if (t.isEmpty() || r.shape.box.not_intersect(t.box)) return e; let n = t.edges.search(r.shape.box); for (let s of n) e = [...e, ...tn(r, s)]; return e; } function Xn(r, t) { let e = []; if (t.isEmpty() || r.size === 0) return e; for (let n of r) e = [...e, ...en(n, t)]; return e; } function Kn(r, t) { let e = []; if (r.isEmpty() || t.isEmpty() || r.box.not_intersect(t.box)) return e; for (let n of r.edges) e = [...e, ...en(n, t)]; return e; } function Jn(r, t) { return r instanceof i.Line ? kt(r, t) : r instanceof i.Segment ? _e(r, t) : r instanceof i.Arc ? me(r, t) : []; } function nn(r, t) { return t.some((e) => e.equalTo(r)); } function nt(r) { return new i.Line(r.start, r.norm); } function Ee(r, t) { return Ft(t, nt(r)).filter((e) => r.contains(e)); } function xe(r, t) { return jt(nt(r), t).filter((e) => r.contains(e)); } function rn(r, t) { return lt(nt(r), t).filter((e) => r.contains(e)); } function ti(r, t) { return Et(nt(r), t).filter((e) => r.contains(e)); } function sn(r, t) { return It(nt(r), t).filter((e) => r.contains(e)); } function ei(r, t) { return It(nt(r), nt(t)).filter((e) => r.contains(e)).filter((e) => t.contains(e)); } function on(r, t) { return kt(nt(r), t).filter((e) => r.contains(e)); } function ln(r, t) { if (r.intersect && r.intersect instanceof Function) return r.intersect(t); throw T.UNSUPPORTED_SHAPE_TYPE; } function Bt(r, t) { let e = []; for (let n of t) e = [...e, ...ln(r, n.shape)]; return e; } function ni(r, t) { let e = []; for (let n of r) for (let s of t) e = [...e, ...ln(n, s)]; return e; } let at = class At extends ge { constructor(...t) { if (super(), this.isInfinite = !1, t.length === 1 && t[0] instanceof Array && t[0].length > 0) { let e = !1; const n = t[0], s = n.length, l = (u) => u instanceof i.Segment || u instanceof i.Arc || u instanceof i.Ray || u instanceof i.Line, o = (u) => u instanceof i.Segment || u instanceof i.Arc || u instanceof i.Ray, a = (u) => u instanceof i.Segment || u instanceof i.Arc; if (e = s === 1 && l(n[0]) || s > 1 && o(n[0]) && o(n[s - 1]) && n.slice(1, s - 1).every(a), e) { this.isInfinite = n.some( (u) => u instanceof i.Ray || u instanceof i.Line ); for (let u of n) { let h = new i.Edge(u); this.append(h); } this.setArcLength(); } else throw i.Errors.ILLEGAL_PARAMETERS; } } /** * (Getter) Return array of edges * @returns {Edge[]} */ get edges() { return [...this]; } /** * (Getter) Return bounding box of the multiline * @returns {Box} */ get box() { return this.edges.reduce((t, e) => t.merge(e.box), new i.Box()); } /** * (Getter) Returns array of vertices * @returns {Point[]} */ get vertices() { let t = this.edges.map((e) => e.start); return t.push(this.last.end), t; } /** * (Getter) Returns length of the multiline, return POSITIVE_INFINITY if multiline is infinite * @returns {number} */ get length() { if (this.isEmpty()) return 0; if (this.isInfinite) return Number.POSITIVE_INFINITY; let t = 0; for (let e of this) t += e.length; return t; } /** * Return new cloned instance of Multiline * @returns {Multiline} */ clone() { return new At(this.toShapes()); } /** * Set arc_length property for each of the edges in the multiline. * Arc_length of the edge is the arc length from the multiline start vertex to the edge start vertex */ setArcLength() { for (let t of this) this.setOneEdgeArcLength(t); } setOneEdgeArcLength(t) { t === this.first ? t.arc_length = 0 : t.arc_length = t.prev.arc_length + t.prev.length; } /** * Return point on multiline at given length from the start of the multiline * @param length * @returns {Point | null} */ pointAtLength(t) { if (t > this.length || t < 0 || this.isInfinite) return null; let e = null; for (let n of this) if (t >= n.arc_length && (n === this.last || t < n.next.arc_length)) { e = n.pointAtLength(t - n.arc_length); break; } return e; } /** * Split edge and add new vertex, return new edge inserted * @param {Point} pt - point on edge that will be added as new vertex * @param {Edge} edge - edge to split * @returns {Edge} */ addVertex(t, e) { let n = e.shape.split(t); if (n[0] === null) return e.prev; if (n[1] === null) return e; let s = new i.Edge(n[0]), l = e.prev; return this.insert(s, l), e.shape = n[1], s; } getChain(t, e) { let n = []; for (let s = t; s !== e.next; s = s.next) n.push(s); return n; } /** * Split edges of multiline with intersection points and return mutated multiline * @param {Point[]} ip - array of points to be added as new vertices * @returns {Multiline} */ split(t) { for (let e of t) { let n = this.findEdgeByPoint(e); this.addVertex(e, n); } return this; } /** * Returns edge which contains given point * @param {Point} pt * @returns {Edge} */ findEdgeByPoint(t) { let e; for (let n of this) if (n.shape.contains(t)) { e = n; break; } return e; } /** * Calculate distance and shortest segment from any shape to multiline * @param shape * @returns {[number,Flatten.Segment]} */ distanceTo(t) { if (t instanceof Point) { const [e, n] = i.Distance.shape2multiline(t, this); return [e, n.reverse()]; } if (t instanceof i.Line) { const [e, n] = i.Distance.shape2multiline(t, this); return [e, n.reverse()]; } if (t instanceof i.Circle) { const [e, n] = i.Distance.shape2multiline(t, this); return [e, n.reverse()]; } if (t instanceof i.Segment) { const [e, n] = i.Distance.shape2multiline(t, this); return [e, n.reverse()]; } if (t instanceof i.Arc) { const [e, n] = i.Distance.shape2multiline(t, this); return [e, n.reverse()]; } if (t instanceof i.Multiline) return i.Distance.multiline2multiline(this, t); throw i.Errors.UNSUPPORTED_SHAPE_TYPE; } /** * Calculate intersection of multiline with other shape * @param {Shape} shape * @returns {Point[]} */ intersect(t) { return t instanceof i.Multiline ? ni(this, t) : Bt(t, this); } /** * Return true if multiline contains the shape: no point of shape lies outside * @param shape * @returns {boolean} */ contains(t) { if (t instanceof i.Point) return this.edges.some((e) => e.shape.contains(t)); throw i.Errors.UNSUPPORTED_SHAPE_TYPE; } /** * Returns new multiline translated by vector vec * @param {Vector} vec * @returns {Multiline} */ translate(t) { return new At(this.edges.map((e) => e.shape.translate(t))); } /** * Return new multiline rotated by given angle around given point * If point omitted, rotate around origin (0,0) * Positive value of angle defines rotation counterclockwise, negative - clockwise * @param {number} angle - rotation angle in radians * @param {Point} center - rotation center, default is (0,0) * @returns {Multiline} - new rotated polygon */ rotate(t = 0, e = new i.Point()) { return new At(this.edges.map((n) => n.shape.rotate(t, e))); } /** * Return new multiline transformed using affine transformation matrix * Method does not support unbounded shapes * @param {Matrix} matrix - affine transformation matrix * @returns {Multiline} - new multiline */ transform(t = new i.Matrix()) { return new At(this.edges.map((e) => e.shape.transform(t))); } /** * Transform multiline into array of shapes * @returns {Shape[]} */ toShapes() { return this.edges.map((t) => t.shape.clone()); } /** * This method returns an object that defines how data will be * serialized when called JSON.stringify() method * @returns {Object} */ toJSON() { return this.edges.map((t) => t.toJSON()); } /** * Return string to be inserted into 'points' attribute of <polyline> element * @returns {string} */ svgPoints() { return this.vertices.map((t) => `${t.x},${t.y}`).join(" "); } /** * Return string to be assigned to 'd' attribute of <path> element * @returns {*} */ dpath() { let t = `M${this.first.start.x},${this.first.start.y}`; for (let e of this) t += e.svg(); return t; } /** * Return string to draw multiline in svg * @param attrs - an object with attributes for svg path element * TODO: support semi-infinite Ray and infinite Line * @returns {string} */ svg(t = {}) { let e = ` <path ${ot({ fill: "none", ...t })} d="`; e += ` M${this.first.start.x},${this.first.start.y}`; for (let n of this) e += n.svg(); return e += `" > </path>`, e; } }; i.Multiline = at; const ii = (...r) => new i.Multiline(...r); i.multiline = ii; function xt(r, t, e) { let n = e.length, s = r.shape.split(t); if (s.length === 0) return; let l = 0; s[0] === null ? l = 0 : s[1] === null ? l = r.shape.length : l = s[0].length; let o = de; rt(l, 0) && (o |= bt), rt(l, r.shape.length) && (o |= mt); let a; l === 1 / 0 ? a = s[0].coord(t) : a = o & mt && r.next && r.next.arc_length === 0 ? 0 : r.arc_length + l, e.push({ id: n, pt: t, arc_length: a, edge_before: r, edge_after: void 0, face: r.face, is_vertex: o }); } function Mt(r) { r.int_points1_sorted = tt(r.int_points1), r.int_points2_sorted = tt(r.int_points2); } function tt(r) { let t = /* @__PURE__ */ new Map(), e = 0; for (let s of r) t.has(s.face) || (t.set(s.face, e), e++); for (let s of r) s.faceId = t.get(s.face); return r.slice().sort(ri); } function ri(r, t) { return r.faceId < t.faceId ? -1 : r.faceId > t.faceId ? 1 : r.arc_length < t.arc_length ? -1 : r.arc_length > t.arc_length ? 1 : 0; } function Te(r) { if (r.int_points1.length < 2) return; let t = !1, e, n, s, l; for (let o = 0; o < r.int_points1_sorted.length; o++) if (r.int_points1_sorted[o].id !== -1) { e = r.int_points1_sorted[o], n = r.int_points2[e.id]; for (let a = o + 1; a < r.int_points1_sorted.length && (s = r.int_points1_sorted[a], !!rt(s.arc_length, e.arc_length)); a++) s.id !== -1 && (l = r.int_points2[s.id], l.id !== -1 && s.edge_before === e.edge_before && s.edge_after === e.edge_after && l.edge_before === n.edge_before && l.edge_after === n.edge_after && (s.id = -1, l.id = -1, t = !0)); } n = r.int_points2_sorted[0], e = r.int_points1[n.id]; for (let o = 1; o < r.int_points2_sorted.length; o++) { let a = r.int_points2_sorted[o]; if (a.id === -1) continue; if (n.id === -1 || /* can't be reference if already deleted */ !rt(a.arc_length, n.arc_length)) { n = a, e = r.int_points1[n.id]; continue; } let u = r.int_points1[a.id]; u.edge_before === e.edge_before && u.edge_after === e.edge_after && a.edge_before === n.edge_before && a.edge_after === n.edge_after && (u.id = -1, a.id = -1, t = !0); } t && (r.int_points1 = r.int_points1.filter((o) => o.id >= 0), r.int_points2 = r.int_points2.filter((o) => o.id >= 0), r.int_points1.forEach((o, a) => o.id = a), r.int_points2.forEach((o, a) => o.id = a)); } function re(r) { for (let t of r) t.edge_before && (t.edge_before.bvStart = void 0, t.edge_before.bvEnd = void 0, t.edge_before.bv = void 0, t.edge_before.overlap = void 0), t.edge_after && (t.edge_after.bvStart = void 0, t.edge_after.bvEnd = void 0, t.edge_after.bv = void 0, t.edge_after.overlap = void 0); for (let t of r) t.edge_before && (t.edge_before.bvEnd = D), t.edge_after && (t.edge_after.bvStart = D); } function se(r, t) { for (let e of r) e.edge_before && e.edge_before.setInclusion(t), e.edge_after && e.edge_after.setInclusion(t); } function si(r) { let t, e, n, s = r.int_points1.length; for (let l = 0; l < s; l++) { let o = r.int_points1_sorted[l]; o.face !== t && (e = l, t = o.face); let a = l, u = Tt(r.int_points1_sorted, l, t), h; a + u < s && r.int_points1_sorted[a + u].face === t ? h = a + u : h = e; let f = Tt(r.int_points1_sorted, h, t); n = null; for (let E = h; E < h + f; E++) { let x = r.int_points1_sorted[E]; if (x.face === t && r.int_points2[x.id].face === r.int_points2[o.id].face) { n = x; break; } } if (n === null) continue; let g = o.edge_after, _ = n.edge_before; if (!(g.bv === D && _.bv === D) || g !== _) continue; let v = r.int_points2[o.id], I = r.int_points2[n.id], w = v.edge_after, S = I.edge_before; w.bv === D && S.bv === D && w === S || (v = r.int_points2[n.id], I = r.int_points2[o.id], w = v.edge_after, S = I.edge_before), w.bv === D && S.bv === D && w === S && g.setOverlap(w); } } function Tt(r, t, e) { let n, s, l = 1; if (r.length === 1) return 1; n = r[t]; for (let o = t + 1; o < r.length && !(n.face !== e || (s = r[o], !(s.pt.equalTo(n.pt) && s.edge_before === n.edge_before && s.edge_after === n.edge_after))); o++) l++; return l; } function wt(r, t) { if (t) { for (let e of t) { let n = e.edge_before; if (e.is_vertex = de, n.shape.start && n.shape.start.equalTo(e.pt) && (e.is_vertex |= bt), n.shape.end && n.shape.end.equalTo(e.pt) && (e.is_vertex |= mt), e.is_vertex & bt) { e.edge_before = n.prev, n.prev && (e.is_vertex = mt); continue; } if (e.is_vertex & mt) continue; let s = r.addVertex(e.pt, n); e.edge_before = s; } for (let e of t) e.edge_before ? e.edge_after = e.edge_before.next : r instanceof at && e.is_vertex & bt && (e.edge_after = r.first); } } function Pe(r, t, e) { const n = r.edge_before, s = t.edge_after, l = e.length; n.next = e[0], e[0].prev = n, e[l - 1].next = s, s.prev = e[l - 1]; } const { INSIDE: W, OUTSIDE: z, BOUNDARY: P, OVERLAP_SAME: oi, OVERLAP_OPPOSITE: li } = zt, { NOT_VERTEX: mr, START_VERTEX: Ae, END_VERTEX: Le } = zt, Kt = 1, Vt = 2, st = 3; function ai(r, t) { let [e, n] = $t(r, t, Kt, !0); return e; } function oe(r, t) { let n = t.clone().reverse(), [s, l] = $t(r, n, st, !0); return s; } function an(r, t) { let [e, n] = $t(r, t, Vt, !0); return e; } function fn(r, t) { let [e, n] = $t(r, t, Vt, !1), s = []; for (let o of e.faces) s = [...s, ...[...o.edges].map((a) => a.shape)]; let l = []; for (let o of n.faces) l = [...l, ...[...o.edges].map((a) => a.shape)]; return [s, l]; } function le(r, t) { let [e, n] = $t(r, t, st, !1), s = []; for (let l of e.faces) s = [...s, ...[...l.edges].map((o) => o.shape)]; return s; } function un(r, t) { let e = r.clone(), n = t.clone(), s = hn(e, n); Mt(s), wt(e, s.int_points1_sorted), wt(n, s.int_points2_sorted), Te(s), Mt(s); let l = s.int_points1_sorted.map((a) => a.pt), o = s.int_points2_sorted.map((a) => a.pt); return [l, o]; } function fi(r, t, e, n) { let s = be(r, e.int_points1), l = be(t, e.int_points2); for (Oe(s, t), Oe(l, r), re(e.int_points1), re(e.int_points2), se(e.int_points1, t), se(e.int_points2, r); hi(r, t, e.int_points1, e.int_points1_sorted, e.int_points2, e); ) ; si(e), ae(r, n, e.int_points1_sorted, !0), ae(t, n, e.int_points2_sorted, !1), Ne(r, s, n, !0), Ne(t, l, n, !1); } function ui(r, t, e, n) { ci(r, t, n, e.int_points2), di(r, t, e), fe(r, e.int_points1), fe(t, e.int_points2), ue(r, e.int_points1, e.int_points2), ue(r, e.int_points2, e.int_points1); } function $t(r, t, e, n) { let s = r.clone(), l = t.clone(), o = hn(s, l); return Mt(o), wt(s, o.int_points1_sorted), wt(l, o.int_points2_sorted), Te(o), Mt(o), fi(s, l, o, e), n && ui(s, l, o, e), [s, l]; } function hn(r, t) { let e = { int_points1: [], int_points2: [] }; for (let n of r.edges) { let s = t.edges.search(n.box); for (let l of s) { let o = n.shape.intersect(l.shape); for (let a of o) xt(n, a, e.int_points1), xt(l, a, e.int_points2); } } return e; } function be(r, t) { let e = []; for (let n of r.faces) t.find((s) => s.face === n) || e.push(n); return e; } function Oe(r, t) { for (let e of r) e.first.bv = e.first.bvStart = e.first.bvEnd = void 0, e.first.setInclusion(t); } function hi(r, t, e, n, s, l) { let o, a, u, h = n.length, f = !1; for (let g = 0; g < h; g++) { let _ = n[g]; _.face !== o && (a = g, o = _.face); let v = g, I = Tt(n, g, o), w; v + I < h && n[v + I].face === o ? w = v + I : w = a; let S = Tt(n, w, o); u = null; for (let p = w; p < w + S; p++) { let b = n[p]; if (b.face === o && s[b.id].face === s[_.id].face) { u = b; break; } } if (u === null) continue; let E = _.edge_after, x = u.edge_before; if (E.bv === P && x.bv != P) { E.bv = x.bv; continue; } if (E.bv != P && x.bv === P) { x.bv = E.bv; continue; } if (E.bv === P && x.bv === P && E != x || E.bv === W && x.bv === z || E.bv === z && x.bv === W) { let p = E.next; for (; p != x; ) p.bvStart = void 0, p.bvEnd = void 0, p.bv = void 0, p.setInclusion(t), p = p.next; } if (E.bv === P && x.bv === P && E != x) { let p = E.next, b; for (; p != x; ) { if (p.bv != P) { if (b === void 0) b = p.bv; else if (p.bv != b) throw T.UNRESOLVED_BOUNDARY_CONFLICT; } p = p.next; } b != null && (E.bv = b, x.bv = b); continue; } if (E.bv === W && x.bv === z || E.bv === z && x.bv === W) { let p = E; for (; p != x; ) { if (p.bvStart === E.bv && p.bvEnd === x.bv) { let [b, Jt] = p.shape.distanceTo(t); if (b < 10 * i.DP_TOL) { xt(p, Jt.ps, e); let Z = e[e.length - 1]; if (Z.is_vertex & Ae) Z.edge_after = p, Z.edge_before = p.prev, p.bvStart = P, p.bv = void 0, p.setInclusion(t); else if (Z.is_vertex & Le) Z.edge_after = p.next, p.bvEnd = P, p.bv = void 0, p.setInclusion(t); else { let R = t.addVertex(Z.pt, p); Z.edge_before = R, Z.edge_after = R.next, R.setInclusion(t), R.next.bvStart = P, R.next.bvEnd = void 0, R.next.bv = void 0, R.next.setInclusion(t); } let ft = t.findEdgeByPoint(Jt.pe); xt(ft, Jt.pe, s); let X = s[s.length - 1]; if (X.is_vertex & Ae) X.edge_after = ft, X.edge_before = ft.prev; else if (X.is_vertex & Le) X.edge_after = ft.next; else { let R = s.find((bn) => bn.edge_after === ft), O = t.addVertex(X.pt, ft); X.edge_before = O, X.edge_after = O.next, R && (R.edge_after = O), O.bvStart = void 0, O.bvEnd = P, O.bv = void 0, O.setInclusion(r), O.next.bvStart = P, O.next.bvEnd = void 0, O.next.bv = void 0, O.next.setInclusion(r); } Mt(l), f = !0; break; } } p = p.next; } if (f) break; throw T.UNRESOLVED_BOUNDARY_CONFLICT; } } return f; } function ae(r, t, e, n) { if (!e) return; let s, l, o, a; for (let u = 0; u < e.length; u++) { if (o = e[u], o.face !== s && (l = u, s = o.face), s.isEmpty()) continue; let h = u, f = Tt(e, u, s), g; h + f < e.length && e[h + f].face === o.face ? g = h + f : g = l, a = e[g]; let _ = g, v = Tt(e, _, s), I = o.edge_after, w = a.edge_before; if (I.bv === W && w.bv === W && t === Kt || I.bv === z && w.bv === z && t === Vt || (I.bv === z || w.bv === z) && t === st && !n || (I.bv === W || w.bv === W) && t === st && n || I.bv === P && w.bv === P && I.overlap & oi && n || I.bv === P && w.bv === P && I.overlap & li) { r.removeChain(s, I, w); for (let S = h; S < h + f; S++) e[S].edge_after = void 0; for (let S = _; S < _ + v; S++) e[S].edge_before = void 0; } u += f - 1; } } function ci(r, t, e, n) { for (let s of t.faces) { for (let l of s) r.edges.add(l); /*(op === BOOLEAN_UNION || op == BOOLEAN_SUBTRACT) &&*/ n.find((l) => l.face === s) === void 0 && r.addFace(s.first, s.last); } } function di(r, t, e) { if (e.int_points1.length !== 0) for (let n = 0; n < e.int_points1.length; n++) { let s = e.int_points1[n], l = e.int_points2[n]; if (s.edge_before !== void 0 && s.edge_after === void 0 && l.edge_before === void 0 && l.edge_after !== void 0 && (s.edge_before.next = l.edge_after, l.edge_after.prev = s.edge_before, s.edge_after = l.edge_after, l.edge_before = s.edge_before), l.edge_before !== void 0 && l.edge_after === void 0 && s.edge_before === void 0 && s.edge_after !== void 0 && (l.edge_before.next = s.edge_after, s.edge_after.prev = l.edge_before, l.edge_after = s.edge_after, s.edge_before = l.edge_before), s.edge_before !== void 0 && s.edge_after === void 0) for (let o of e.int_points1_sorted) o !== s && o.edge_before === void 0 && o.edge_after !== void 0 && o.pt.equalTo(s.pt) && (s.edge_before.next = o.edge_after, o.edge_after.prev = s.edge_before, s.edge_after = o.edge_after, o.edge_before = s.edge_before); if (l.edge_before !== void 0 && l.edge_after === void 0) for (let o of e.int_points2_sorted) o !== l && o.edge_before === void 0 && o.edge_after !== void 0 && o.pt.equalTo(l.pt) && (l.edge_before.next = o.edge_after, o.edge_after.prev = l.edge_before, l.edge_after = o.edge_after, o.edge_before = l.edge_before); } } function fe(r, t) { for (let e of t) r.faces.delete(e.face), e.face = void 0, e.edge_before && (e.edge_before.face = void 0), e.edge_after && (e.edge_after.face = void 0); } function ue(r, t, e) { for (let n of t) { if (n.edge_before === void 0 || n.edge_after === void 0 || n.face || n.edge_after.face || n.edge_before.face) continue; let s = n.edge_after, l = n.edge_before; try { ge.testInfiniteLoop(s); } catch { throw T.CANNOT_COMPLETE_BOOLEAN_OPERATION; } let o = r.addFace(s, l); for (let a of t) a.edge_before && a.edge_after && a.edge_before.face === o && a.edge_after.face === o && (a.face = o); for (let a of e) a.edge_before && a.edge_after && a.edge_before.face === o && a.edge_after.face === o && (a.face = o); } } function Ne(r, t, e, n) { for (let s of t) { let l = s.first.bv; (e === Kt && l === W || e === st && l === W && n || e === st && l === z && !n || e === Vt && l === z) && r.deleteFace(s); } } var gi = /* @__PURE__ */ Object.freeze({ __proto__: null, BOOLEAN_INTERSECT: Vt, BOOLEAN_SUBTRACT: st, BOOLEAN_UNION: Kt, calculateIntersections: un, innerClip: fn, intersect: an, outerClip: le, removeNotRelevantChains: ae, removeOldFaces: fe, restoreFaces: ue, subtract: oe, unify: ai }); const pi = RegExp("T.F..FFF.|T.F...F.."), _i = RegExp("T........|.T.......|...T.....|....T...."), mi = RegExp("FT.......|F..T.....|F...T...."), Ei = RegExp("T.F..F..."), xi = RegExp("T.F..F...|.TF..F...|..FT.F...|..F.TF..."); class St { /** * Create new instance of DE9IM matrix */ constructor() { this.m = new Array(9).fill(void 0); } /** * Get Interior To Interior intersection * @returns {Shape[] | undefined} */ get I2I() { return this.m[0]; } /** * Set Interior To Interior intersection * @param geom */ set I2I(t) { this.m[0] = t; } /** * Get Interior To Boundary intersection * @returns {Shape[] | undefined} */ get I2B() { return this.m[1]; } /** * Set Interior to Boundary intersection * @param geomc */ set I2B(t) { this.m[1] = t; } /** * Get Interior To Exterior intersection * @returns {Shape[] | undefined} */ get I2E() { return this.m[2]; } /** * Set Interior to Exterior intersection * @param geom */ set I2E(t) { this.m[2] = t; } /** * Get Boundary To Interior intersection * @returns {Shape[] | undefined} */ get B2I() { return this.m[3]; } /** * Set Boundary to Interior intersection * @param geom */ set B2I(t) { this.m[3] = t; } /** * Get Boundary To Boundary intersection * @returns {Shape[] | undefined} */ get B2B() { return this.m[4]; } /** * Set Boundary to Boundary intersection * @param geom */ set B2B(t) { this.m[4] = t; } /** * Get Boundary To Exterior intersection * @returns {Shape[] | undefined} */ get B2E() { return this.m[5]; } /** * Set Boundary to Exterior intersection * @param geom */ set B2E(t) { this.m[5] = t; } /** * Get Exterior To Interior intersection * @returns {Shape[] | undefined} */ get E2I() { return this.m[6]; } /** * Set Exterior to Interior intersection * @param geom */ set E2I(t) { this.m[6] = t; } /** * Get Exterior To Boundary intersection * @returns {Shape[] | undefined} */ get E2B() { return this.m[7]; } /** * Set Exterior to Boundary intersection * @param geom */ set E2B(t) { this.m[7] = t; } /** * Get Exterior to Exterior intersection * @returns {Shape[] | undefined} */ get E2E() { return this.m[8]; } /** * Set Exterior to Exterior intersection * @param geom */ set E2E(t) { this.m[8] = t; } /** * Return de9im matrix as string where<br/> * - intersection is 'T'<br/> * - not intersected is 'F'<br/> * - not relevant is '*'<br/> * For example, string 'FF**FF****' means 'DISJOINT' * @returns {string} */ toString() { return this.m.map((t) => t instanceof Array && t.length > 0 ? "T" : t instanceof Array && t.length === 0 ? "F" : "*").join(""); } equal() { return pi.test(this.toString()); } intersect() { return _i.test(this.toString()); } touch() { return mi.test(this.toString()); } inside() { return Ei.test(this.toString()); } covered() { return xi.test(this.toString()); } } function Ot(r, t) { let e, n = new i.Ray(t), s = new i.Line(n.pt, n.norm); const l = new i.Box( n.box.xmin - i.DP_TOL, n.box.ymin - i.DP_TOL, n.box.xmax, n.box.ymax + i.DP_TOL ); if (r.box.not_intersect(l)) return i.OUTSIDE; let o = r.edges.search(l); if (o.length === 0) return i.OUTSIDE; for (let f of o) if (f.shape.contains(t)) return i.BOUNDARY; let a = [...r.faces], u = []; for (let f of o) for (let g of n.intersect(f.shape)) { if (g.equalTo(t)) return i.BOUNDARY; u.push({ pt: g, edge: f, face_index: a.indexOf(f.face) }); } u.sort((f, g) => Ye(f.pt.x, g.pt.x) ? -1 : ze(f.pt.x, g.pt.x) ? 1 : f.face_index < g.face_index ? -1 : f.face_index > g.face_index ? 1 : f.edge.arc_length < g.edge.arc_length ? -1 : f.edge.arc_length > g.edge.arc_length ? 1 : 0); let h = 0; for (let f = 0; f < u.length; f++) { let g = u[f]; if (g.pt.equalTo(g.edge.shape.start)) { if (f > 0 && g.pt.equalTo(u[f - 1].pt) && g.face_index === u[f - 1].face_index && g.edge.prev === u[f - 1].edge) continue; let _ = g.edge.prev; for (; ie(_.length); ) _ = _.prev; let v = _.shape.tangentInEnd(), I = g.pt.translate(v), w = g.edge.shape.tangentInStart(), S = g.pt.translate(w), E = I.leftTo(s), x = S.leftTo(s); (E && !x || !E && x) && h++; } else if (g.pt.equalTo(g.edge.shape.end)) { if (f > 0 && g.pt.equalTo(u[f - 1].pt) && g.face_index === u[f - 1].face_index && g.edge.next === u[f - 1].edge) continue; let _ = g.edge.next; for (; ie(_.length); ) _ = _.next; let v = _.shape.tangentInStart(), I = g.pt.translate(v), w = g.edge.shape.tangentInEnd(), S = g.pt.translate(w), E = I.leftTo(s), x = S.leftTo(s); (E && !x || !E && x) && h++; } else if (g.edge.shape instanceof i.Segment) h++; else { let _ = g.edge.shape.box; rt(g.pt.y, _.ymin) || rt(g.pt.y, _.ymax) || h++; } } return e = h % 2 === 1 ? Wt : qe, e; } function Ti(r, t) { return yt(r, t).equal(); } function cn(r, t) { return yt(r, t).intersect(); } function wi(r, t) { return yt(r, t).touch(); } function Ii(r, t) { return !cn(r, t); } function dn(r, t) { return yt(r, t).inside(); } function gn(r, t) { return yt(r, t).covered(); } function vi(r, t) { return dn(t, r); } function pn(r, t) { return gn(t, r); } function yt(r, t) { if (r instanceof i.Line && t instanceof i.Line) return Si(r, t); if (r instanceof i.Line && t instanceof i.Circle) return yi(r, t); if (r instanceof i.Line && t instanceof i.Box) return Pi(r, t); if (r instanceof i.Line && t instanceof i.Polygon) return Ai(r, t); if ((r instanceof i.Segment || r instanceof i.Arc) && t instanceof i.Polygon) return Ce(r, t); if ((r instanceof i.Segment || r instanceof i.Arc) && (t instanceof i.Circle || t instanceof i.Box)) return Ce(r, new i.Polygon(t)); if (r instanceof i.Polygon && t instanceof i.Polygon) return Ht(r, t); if ((r instanceof i.Circle || r instanceof i.Box) && (t instanceof i.Circle || t instanceof i.Box)) return Ht(new i.Polygon(r), new i.Polygon(t)); if ((r instanceof i.Circle || r instanceof i.Box) && t instanceof i.Polygon) return Ht(new i.Polygon(r), t); if (r instanceof i.Polygon && (t instanceof i.Circle || t instanceof i.Box)) return Ht(r, new i.Polygon(t)); } function Si(r, t) { let e = new St(), n = It(r, t); return n.length === 0 ? r.contains(t.pt) && t.contains(r.pt) ? (e.I2I = [r], e.I2E = [], e.E2I = []) : (e.I2I = [], e.I2E = [r], e.E2I = [t]) : (e.I2I = n, e.I2E = r.split(n), e.E2I = t.split(n)), e; } function yi(r, t) { let e = new St(), n = lt(r, t); if (n.length === 0) e.I2I = [], e.I2B = [], e.I2E = [r], e.E2I = [t]; else if (n.length === 1) e.I2I = [], e.I2B = n, e.I2E = r.split(n), e.E2I = [t]; else { let s = new at([r]), l = r.sortPoints(n); s.split(l); let o = s.toShapes(); e.I2I = [o[1]], e.I2B = l, e.I2E = [o[0], o[2]], e.E2I = new i.Polygon([t.toArc()]).cutWithLine(r); } return e; } function Pi(r, t) { let e = new St(), n = Et(r, t); if (n.length === 0) e.I2I = [], e.I2B = [], e.I2E = [r], e.E2I = [t]; else if (n.length === 1) e.I2I = [], e.I2B = n, e.I2E = r.split(n), e.E2I = [t]; else { let s = new at([r]), l = r.sortPoints(n); s.split(l); let o = s.toShapes(); t.toSegments().some((a) => a.contains(n[0]) && a.contains(n[1])) ? (e.I2I = [], e.I2B = [o[1]], e.I2E = [o[0], o[2]], e.E2I = [t]) : (e.I2I = [o[1]], e.I2B = l, e.I2E = [o[0], o[2]], e.E2I = new i.Polygon(t.toSegments()).cutWithLine(r)); } return e; } function Ai(r, t) { let e = new St(), n = kt(r, t), s = new at([r]), l = n.length > 0 ? n.slice() : r.sortPoints(n); return s.split(l), [...s].forEach((o) => o.setInclusion(t)), e.I2I = [...s].filter((o) => o.bv === i.INSIDE).map((o) => o.shape), e.I2B = [...s].slice(1).map((o) => o.bv === i.BOUNDARY ? o.shape : o.shape.start), e.I2E = [...s].filter((o) => o.bv === i.OUTSIDE).map((o) => o.shape), e.E2I = t.cutWithLine(r), e; } function Ce(r, t) { let e = new St(), n = Jn(r, t), s = n.length > 0 ? n.slice() : r.sortPoints(n), l = new at([r]); l.split(s), [...l].forEach((o) => o.setInclusion(t)), e.I2I = [...l].filter((o) => o.bv === i.INSIDE).map((o) => o.shape), e.I2B = [...l].slice(1).map((o) => o.bv === i.BOUNDARY ? o.shape : o.shape.start), e.I2E = [...l].filter((o) => o.bv === i.OUTSIDE).map((o) => o.shape), e.B2I = [], e.B2B = [], e.B2E = []; for (let o of [r.start, r.end]) switch (Ot(t, o)) { case i.INSIDE: e.B2I.push(o); break; case i.BOUNDARY: e.B2B.push(o); break; case i.OUTSIDE: e.B2E.push(o); break; } return e; } function Ht(r, t) { let e = new St(), [n, s] = un(r, t), l = an(r, t), o = oe(r, t), a = oe(t, r), [u, h] = fn(r, t), f = le(r, t), g = le(t, r); return e.I2I = l.isEmpty() ? [] : [l], e.I2B = h, e.I2E = o.isEmpty() ? [] : [o], e.B2I = u, e.B2B = n, e.B2E = f, e.E2I = a.isEmpty() ? [] : [a], e.E2B = g, e; } var Li = /* @__PURE__ */ Object.freeze({ __proto__: null, contain: vi, cover: pn, covered: gn, disjoint: Ii, equal: Ti, inside: dn, intersect: cn, relate: yt, touch: wi }); let Nt = class ct { /** * Construct new instance of affine transformation matrix <br/> * If parameters omitted, construct identity matrix a = 1, d = 1 * @param {number} a - position(0,0) sx*cos(alpha) * @param {number} b - position (0,1) sx*sin(alpha) * @param {number} c - position (1,0) -sy*sin(alpha) * @param {number} d - position (1,1) sy*cos(alpha) * @param {number} tx - position (2,0) translation by x * @param {number} ty - position (2,1) translation by y */ constructor(t = 1, e = 0, n = 0, s = 1, l = 0, o = 0) { this.a = t, this.b = e, this.c = n, this.d = s, this.tx = l, this.ty = o; } /** * Return new cloned instance of matrix * @return {Matrix} **/ clone() { return new ct(this.a, this.b, this.c, this.d, this.tx, this.ty); } /** * Transform vector [x,y] using transformation matrix. <br/> * Vector [x,y] is an abstract array[2] of numbers and not a FlattenJS object <br/> * The result is also an abstract vector [x',y'] = A * [x,y]: * <code> * [x' [ ax + by + tx * y' = cx + dy + ty * 1] 1 ] * </code> * @param {number[]} vector - array[2] of numbers * @returns {number[]} transformation result - array[2] of numbers */ transform(t) { return [ t[0] * this.a + t[1] * this.c + this.tx, t[0] * this.b + t[1] * this.d + this.ty ]; } /** * Returns result of multiplication of this matrix by other matrix * @param {Matrix} other_matrix - matrix to multiply by * @returns {Matrix} */ multiply(t) { return new ct( this.a * t.a + this.c * t.b, this.b * t.a + this.d * t.b, this.a * t.c + this.c * t.d, this.b * t.c + this.d * t.d, this.a * t.tx + this.c * t.ty + this.tx, this.b * t.tx + this.d * t.ty + this.ty ); } /** * Return new matrix as a result of multiplication of the current matrix * by the matrix(1,0,0,1,tx,ty) * @param {Vector} vector - Translation by vector or * @param {number} tx - translation by x-axis * @param {number} ty - translation by y-axis * @returns {Matrix} */ translate(...t) { let e, n; if (t.length == 1 && !isNaN(t[0].x) && !isNaN(t[0].y)) e = t[0].x, n = t[0].y; else if (t.length === 2 && typeof t[0] == "number" && typeof t[1] == "number") e = t[0], n = t[1]; else throw T.ILLEGAL_PARAMETERS; return this.multiply(new ct(1, 0, 0, 1, e, n)); } /** * Return new matrix as a result of multiplication of the current matrix * by the matrix that defines rotation by given angle (in radians) around * center of rotation (centerX,centerY) in counterclockwise direction * @param {number} angle - angle in radians * @param {number} centerX - center of rotation * @param {number} centerY - center of rotation * @returns {Matrix} */ rotate(t, e = 0, n = 0) { let s = Math.cos(t), l = Math.sin(t); return this.translate(e, n).multiply(new ct(s, l, -l, s, 0, 0)).translate(-e, -n); } /** * Return new matrix as a result of multiplication of the current matrix * by the matrix (sx,0,0,sy,0,0) that defines scaling * @param {number} sx * @param {number} sy * @returns {Matrix} */ scale(t, e) { return this.multiply(new ct(t, 0, 0, e, 0, 0)); } /** * Returns true if two matrix are equal parameter by parameter * @param {Matrix} matrix - other matrix * @returns {boolean} true if equal, false otherwise */ equalTo(t) { return !(!i.Utils.EQ(this.tx, t.tx) || !i.Utils.EQ(this.ty, t.ty) || !i.Utils.EQ(this.a, t.a) || !i.Utils.EQ(this.b, t.b) || !i.Utils.EQ(this.c, t.c) || !i.Utils.EQ(this.d, t.d)); } }; i.Matrix = Nt; const bi = (...r) => new i.Matrix(...r); i.matrix = bi; const Oi = class he { /** * Accept two comparable values and creates new instance of interval * Predicate Interval.comparable_less(low, high) supposed to return true on these values * @param low * @param high */ constructor(t, e) { this.low = t, this.high = e; } /** * Clone interval * @returns {Interval} */ clone() { return new he(this.low, this.high); } /** * Propery max returns clone of this interval * @returns {Interval} */ get max() { return this.clone(); } /** * Predicate returns true is this interval less than other interval * @param other_interval * @returns {boolean} */ less_than(t) { return this.low < t.low || this.low == t.low && this.high < t.high; } /** * Predicate returns true is this interval equals to other interval * @param other_interval * @returns {boolean} */ equal_to(t) { return this.low == t.low && this.high == t.high; } /** * Predicate returns true if this interval intersects other interval * @param other_interval * @returns {boolean} */ intersect(t) { return !this.not_intersect(t); } /** * Predicate returns true if this interval does not intersect other interval * @param other_interval * @returns {boolean} */ not_intersect(t) { return this.high < t.low || t.high < this.low; } /** * Returns new interval merged with other interval * @param {Interval} interval - Other interval to merge with * @returns {Interval} */ m