pantograph2d 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,944 @@
1
+ function $(e, t, n, r) {
2
+ return e <= r && t >= n;
3
+ }
4
+ class B {
5
+ constructor(t = 1 / 0, n = 1 / 0, r = -1 / 0, s = -1 / 0) {
6
+ this.xMin = t, this.yMin = n, this.xMax = r, this.yMax = s;
7
+ }
8
+ get width() {
9
+ return this.xMax - this.xMin;
10
+ }
11
+ get height() {
12
+ return this.yMax - this.yMin;
13
+ }
14
+ contains(t) {
15
+ const [n, r] = t;
16
+ return $(this.xMin, this.xMax, n, n) && $(this.yMin, this.yMax, r, r);
17
+ }
18
+ overlaps(t) {
19
+ return $(this.xMin, this.xMax, t.xMin, t.xMax) && $(this.yMin, this.yMax, t.yMin, t.yMax);
20
+ }
21
+ addPoint(t) {
22
+ const [n, r] = t;
23
+ return new B(
24
+ Math.min(this.xMin, n),
25
+ Math.min(this.yMin, r),
26
+ Math.max(this.xMax, n),
27
+ Math.max(this.yMax, r)
28
+ );
29
+ }
30
+ merge(t) {
31
+ return new B(
32
+ Math.min(this.xMin, t.xMin),
33
+ Math.min(this.yMin, t.yMin),
34
+ Math.max(this.xMax, t.xMax),
35
+ Math.max(this.yMax, t.yMax)
36
+ );
37
+ }
38
+ }
39
+ function ut(e) {
40
+ const t = [];
41
+ for (let n = 0; n < e; n++)
42
+ for (let r = 0; r <= n; r++)
43
+ t.push([n, r]);
44
+ return t;
45
+ }
46
+ function* X(e) {
47
+ for (const [t, n] of ut(e.length))
48
+ t !== n && (yield [e[t], e[n]]);
49
+ }
50
+ const Pt = Math.PI / 180, k = (e) => `[${e[0]}, ${e[1]}]`, c = ([e, t], [n, r], s = 1e-9) => Math.abs(e - n) <= s && Math.abs(t - r) <= s, K = ([e, t], [n, r]) => [e + n, t + r], T = ([e, t], [n, r]) => [e - n, t - r], _ = ([e, t]) => e * e + t * t, Q = ([e, t], n) => [e * n, t * n], at = ([e, t], [n, r] = [0, 0]) => (e - n) ** 2 + (t - r) ** 2, F = (e, t = [0, 0]) => Math.sqrt(at(e, t));
51
+ function q([e, t], [n, r]) {
52
+ return e * r - t * n;
53
+ }
54
+ function Z([e, t], [n, r]) {
55
+ return e * n + t * r;
56
+ }
57
+ function G([e, t]) {
58
+ const n = F([e, t]);
59
+ return [e / n, t / n];
60
+ }
61
+ function qt(e, t) {
62
+ const n = Math.cos(t) * e, r = Math.sin(t) * e;
63
+ return [n, r];
64
+ }
65
+ function lt(e, t, n = 1e-9) {
66
+ const r = q(e, t), s = _(e), i = _(t);
67
+ return r * r < s * i * n * n;
68
+ }
69
+ const C = (e, t) => {
70
+ const [n, r, s, i, o, u, a, l, h] = e, [m, f, g, P, x, d, S, v, b] = t;
71
+ return [
72
+ n * m + r * P + s * S,
73
+ n * f + r * x + s * v,
74
+ n * g + r * d + s * b,
75
+ i * m + o * P + u * S,
76
+ i * f + o * x + u * v,
77
+ i * g + o * d + u * b,
78
+ a * m + l * P + h * S,
79
+ a * f + l * x + h * v,
80
+ a * g + l * d + h * b
81
+ ];
82
+ };
83
+ class y {
84
+ constructor() {
85
+ this._matrix = [1, 0, 0, 0, 1, 0, 0, 0, 1];
86
+ }
87
+ translate(t, n) {
88
+ return this._matrix = C(this._matrix, [1, 0, t, 0, 1, n, 0, 0, 1]), this;
89
+ }
90
+ rotate(t, n) {
91
+ const r = Math.cos(t), s = Math.sin(t), i = [r, -s, 0, s, r, 0, 0, 0, 1];
92
+ return n && this.translate(n[0], n[1]), this._matrix = C(this._matrix, i), n && this.translate(-n[0], -n[1]), this;
93
+ }
94
+ mirrorX() {
95
+ return this._matrix = C(this._matrix, [1, 0, 0, 0, -1, 0, 0, 0, 1]), this;
96
+ }
97
+ mirrorY() {
98
+ return this._matrix = C(this._matrix, [-1, 0, 0, 0, 1, 0, 0, 0, 1]), this;
99
+ }
100
+ mirrorLine(t, n) {
101
+ const [r, s] = t, i = Math.atan2(s, r);
102
+ return n && this.translate(n[0], n[1]), this.rotate(i), this.mirrorX(), this.rotate(-i), n && this.translate(-n[0], -n[1]), this;
103
+ }
104
+ mirrorCenter(t) {
105
+ return t && this.translate(t[0], t[1]), this._matrix = C(this._matrix, [-1, 0, 0, 0, -1, 0, 0, 0, 1]), t && this.translate(-t[0], -t[1]), this;
106
+ }
107
+ scale(t, n) {
108
+ return n && this.translate(n[0], n[1]), this._matrix = C(this._matrix, [t, 0, 0, 0, t, 0, 0, 0, 1]), n && this.translate(-n[0], -n[1]), this;
109
+ }
110
+ transform(t) {
111
+ const [n, r] = t, [s, i, o, u, a, l] = this._matrix;
112
+ return [s * n + i * r + o, u * n + a * r + l];
113
+ }
114
+ }
115
+ class D {
116
+ translateX(t) {
117
+ const n = new y().translate(t, 0);
118
+ return this.transform(n);
119
+ }
120
+ translateY(t) {
121
+ const n = new y().translate(0, t);
122
+ return this.transform(n);
123
+ }
124
+ translate(t, n) {
125
+ const r = new y().translate(t, n);
126
+ return this.transform(r);
127
+ }
128
+ translateTo([t, n]) {
129
+ const r = new y().translate(t, n);
130
+ return this.transform(r);
131
+ }
132
+ rotate(t, n) {
133
+ const r = new y().rotate(
134
+ t * Pt,
135
+ n
136
+ );
137
+ return this.transform(r);
138
+ }
139
+ scale(t, n) {
140
+ const r = new y().scale(t, n);
141
+ return this.transform(r);
142
+ }
143
+ mirrorCenter(t) {
144
+ const n = new y().mirrorCenter(t);
145
+ return this.transform(n);
146
+ }
147
+ mirror(t = "x", n) {
148
+ const r = new y();
149
+ return t === "x" ? r.mirrorX() : t === "y" ? r.mirrorY() : r.mirrorLine(t, n), this.transform(r);
150
+ }
151
+ }
152
+ class M extends D {
153
+ constructor(t, n = [], { ignoreChecks: r = !1 } = {}) {
154
+ super(), r || xt(t, n), this.contour = t, this.holes = n;
155
+ }
156
+ get boundingBox() {
157
+ return this.contour.boundingBox;
158
+ }
159
+ get isFull() {
160
+ return this.holes.length === 0;
161
+ }
162
+ get allLoops() {
163
+ return [this.contour, ...this.holes];
164
+ }
165
+ clone() {
166
+ return new M(
167
+ this.contour.clone(),
168
+ this.holes.map((t) => t.clone())
169
+ );
170
+ }
171
+ transform(t) {
172
+ return new M(
173
+ this.contour.transform(t),
174
+ this.holes.map((n) => n.transform(t))
175
+ );
176
+ }
177
+ contains(t) {
178
+ return this.contour.contains(t) && !this.holes.some((n) => n.contains(t));
179
+ }
180
+ intersects(t) {
181
+ return this.allLoops.some(
182
+ (n) => t.allLoops.some((r) => n.intersects(r))
183
+ );
184
+ }
185
+ }
186
+ function xt(e, t = []) {
187
+ if (!e)
188
+ throw new Error("Figure must have a contour");
189
+ for (const [n, r] of X([e, ...t]))
190
+ if (n.intersects(r))
191
+ throw new Error("Loops in a figure must not intersect");
192
+ if (t.some((n) => !e.contains(n.firstPoint)))
193
+ throw new Error("Holes must be inside the contour");
194
+ for (const [n, r] of X(t))
195
+ if (n.contains(r.firstPoint))
196
+ throw new Error("Holes must not be inside other holes");
197
+ }
198
+ const dt = (e) => {
199
+ const t = e.map((s, i) => e.slice(i + 1).map((o, u) => [u + i + 1, o]).filter(([, o]) => s.boundingBox.overlaps(o.boundingBox)).map(([o]) => o)), n = [], r = Array(t.length);
200
+ return t.forEach((s, i) => {
201
+ let o = r[i];
202
+ o || (o = [], n.push(o)), o.push(e[i]), s.length && s.forEach((u) => {
203
+ r[u] = o;
204
+ });
205
+ }), n;
206
+ }, ct = (e) => e.map((t, n) => {
207
+ const s = t.segments[0].midPoint, i = e.filter((o, u) => n === u ? !1 : o.contains(s));
208
+ return {
209
+ loop: t,
210
+ isIn: i
211
+ };
212
+ }), wt = (e, t) => e.flatMap(({ loop: n }) => Y(
213
+ t.filter(
214
+ ({ loop: r, isIn: s }) => r === n || s.indexOf(n) !== -1
215
+ )
216
+ )), Mt = (e, t) => {
217
+ const n = t.filter(({ isIn: s }) => s.length <= 1), r = Y(
218
+ ct(e.map(({ loop: s }) => s))
219
+ );
220
+ return [n, ...r];
221
+ }, Y = (e) => {
222
+ if (!e.length)
223
+ return [];
224
+ const t = e.filter(({ isIn: r }) => !r.length), n = e.filter(({ isIn: r }) => r.length > 1);
225
+ return t.length === 1 && n.length === 0 ? [e] : t.length > 1 ? wt(t, e) : Mt(n, e);
226
+ };
227
+ function A(e) {
228
+ return dt(e).map(ct).flatMap(Y).map((n) => {
229
+ if (n.length === 1)
230
+ return new M(n[0].loop);
231
+ n.sort((i, o) => i.isIn.length - o.isIn.length);
232
+ const [r, ...s] = n.map(({ loop: i }) => i);
233
+ return new M(r, s);
234
+ });
235
+ }
236
+ function yt(e, t) {
237
+ const n = [];
238
+ for (const r of e)
239
+ for (const s of t)
240
+ n.push([r, s]);
241
+ return n;
242
+ }
243
+ function vt(e) {
244
+ return Array.from(Array(e).keys());
245
+ }
246
+ function E(e) {
247
+ const t = Math.min(...e.map((n) => n.length));
248
+ return vt(t).map((n) => e.map((r) => r[n]));
249
+ }
250
+ const tt = (e, t = 1e-9) => {
251
+ let n = e;
252
+ return Math.abs(e) < t && (n = 0), n.toFixed(-Math.log10(t));
253
+ };
254
+ function z(e, t = 1e-9) {
255
+ return Array.from(
256
+ new Map(
257
+ e.map(([n, r]) => [
258
+ `[${tt(n, t)},${tt(r, t)}]`,
259
+ [n, r]
260
+ ])
261
+ ).values()
262
+ );
263
+ }
264
+ class St extends D {
265
+ constructor(t, n) {
266
+ super(), this.firstPoint = t, this.lastPoint = n, this.precision = 1e-9, this.firstPoint = t, this.lastPoint = n;
267
+ }
268
+ get repr() {
269
+ return `${this.segmentType} ${k(this.firstPoint)} - ${k(
270
+ this.lastPoint
271
+ )}`;
272
+ }
273
+ [Symbol.for("nodejs.util.inspect.custom")]() {
274
+ return this.repr;
275
+ }
276
+ }
277
+ class p extends St {
278
+ constructor() {
279
+ super(...arguments), this.segmentType = "LINE", this._V = null, this._boundingBox = null;
280
+ }
281
+ isValidParameter(t) {
282
+ const n = this.length * this.precision;
283
+ return t >= -n && 1 - t >= -n;
284
+ }
285
+ paramPoint(t) {
286
+ return K(this.firstPoint, Q(this.V, t));
287
+ }
288
+ get length() {
289
+ return F(this.firstPoint, this.lastPoint);
290
+ }
291
+ get squareLength() {
292
+ return at(this.firstPoint, this.lastPoint);
293
+ }
294
+ get V() {
295
+ return this._V === null && (this._V = T(this.lastPoint, this.firstPoint)), this._V;
296
+ }
297
+ get midPoint() {
298
+ return K(this.firstPoint, Q(this.V, 0.5));
299
+ }
300
+ isSame(t) {
301
+ return t instanceof p ? c(this.firstPoint, t.firstPoint) && c(this.lastPoint, t.lastPoint) || c(this.lastPoint, t.firstPoint) && c(this.firstPoint, t.lastPoint) : !1;
302
+ }
303
+ clone() {
304
+ return new p(this.firstPoint, this.lastPoint);
305
+ }
306
+ reverse() {
307
+ return new p(this.lastPoint, this.firstPoint);
308
+ }
309
+ get boundingBox() {
310
+ return this._boundingBox === null && (this._boundingBox = new B(
311
+ Math.min(this.firstPoint[0], this.lastPoint[0]) - this.precision,
312
+ Math.min(this.firstPoint[1], this.lastPoint[1]) - this.precision,
313
+ Math.max(this.firstPoint[0], this.lastPoint[0]) + this.precision,
314
+ Math.max(this.firstPoint[1], this.lastPoint[1]) + this.precision
315
+ )), this._boundingBox;
316
+ }
317
+ distanceFrom(t) {
318
+ const n = T(t, this.firstPoint), r = Z(n, this.V) / this.squareLength;
319
+ if (r < 0)
320
+ return F(t, this.firstPoint);
321
+ if (r > 1)
322
+ return F(t, this.lastPoint);
323
+ const s = this.paramPoint(r);
324
+ return F(t, s);
325
+ }
326
+ isOnSegment(t) {
327
+ if (c(t, this.firstPoint, this.precision))
328
+ return !0;
329
+ const n = T(t, this.firstPoint);
330
+ if (!lt(this.V, n))
331
+ return !1;
332
+ const r = Z(n, this.V) / this.squareLength;
333
+ return this.isValidParameter(r);
334
+ }
335
+ tangentAt(t) {
336
+ if (!this.isOnSegment(t))
337
+ throw new Error("Point is not on segment");
338
+ return G(this.V);
339
+ }
340
+ get tangentAtFirstPoint() {
341
+ return G(this.V);
342
+ }
343
+ get tangentAtLastPoint() {
344
+ return G(this.V);
345
+ }
346
+ splitAt(t) {
347
+ let n;
348
+ if (Array.isArray(t) && t.length === 0)
349
+ return [this];
350
+ Array.isArray(t[0]) ? n = t : n = [t], n.forEach((a) => {
351
+ if (!this.isOnSegment(a))
352
+ throw new Error(
353
+ `Point ${k(a)} is not on segment ${this.repr}`
354
+ );
355
+ });
356
+ const r = [this.firstPoint, ...n, this.lastPoint], s = z(r), i = this.lastPoint[0] - this.firstPoint[0];
357
+ let o = Math.sign(i), u = 0;
358
+ return Math.abs(i) < this.precision && (o = Math.sign(this.lastPoint[1] - this.firstPoint[1]), u = 1), s.sort(
359
+ (a, l) => o * (a[u] - l[u])
360
+ ), s.flatMap((a, l) => l === s.length - 1 ? [] : new p(a, s[l + 1]));
361
+ }
362
+ transform(t) {
363
+ return new p(
364
+ t.transform(this.firstPoint),
365
+ t.transform(this.lastPoint)
366
+ );
367
+ }
368
+ }
369
+ const ht = (e, t, n) => {
370
+ const r = q(e.V, t.V), s = _(e.V), i = _(t.V), o = n ? n * n : e.precision * t.precision;
371
+ if (r * r < s * i * o)
372
+ return "parallel";
373
+ const u = T(t.firstPoint, e.firstPoint), a = q(u, t.V) / r, l = q(u, e.V) / r;
374
+ return {
375
+ intersectionParam1: a,
376
+ intersectionParam2: l
377
+ };
378
+ };
379
+ function bt(e, t, n = !1, r) {
380
+ const s = ht(e, t, r);
381
+ if (s === "parallel") {
382
+ if (!n)
383
+ return null;
384
+ if (e.isSame(t))
385
+ return e;
386
+ const u = z(
387
+ [
388
+ t.isOnSegment(e.firstPoint) ? e.firstPoint : null,
389
+ t.isOnSegment(e.lastPoint) ? e.lastPoint : null,
390
+ e.isOnSegment(t.firstPoint) ? t.firstPoint : null,
391
+ e.isOnSegment(t.lastPoint) ? t.lastPoint : null
392
+ ].filter((a) => a !== null)
393
+ ).sort((a, l) => a[0] - l[0]);
394
+ if (u.length === 0)
395
+ return null;
396
+ if (u.length === 1)
397
+ return null;
398
+ if (u.length === 2)
399
+ return new p(u[0], u[1]);
400
+ throw console.error(u), new Error(
401
+ "Unexpected number of points while intersecting parallel lines"
402
+ );
403
+ }
404
+ const { intersectionParam1: i, intersectionParam2: o } = s;
405
+ return !e.isValidParameter(i) || !t.isValidParameter(o) ? null : e.paramPoint(i);
406
+ }
407
+ function R(e, t, n) {
408
+ if (e instanceof p && t instanceof p) {
409
+ const r = bt(
410
+ e,
411
+ t,
412
+ !0,
413
+ n
414
+ );
415
+ return r === null ? { intersections: [], overlaps: [], count: 0 } : r instanceof p ? { intersections: [], overlaps: [r], count: 1 } : { intersections: [r], overlaps: [], count: 1 };
416
+ }
417
+ throw new Error("Not implemented");
418
+ }
419
+ class ft extends D {
420
+ constructor(t, { ignoreChecks: n = !1 } = {}) {
421
+ super(), this._boundingBox = null, n || mt(t), this.segments = t;
422
+ }
423
+ get repr() {
424
+ return this.segments.map((t) => t.repr).join(`
425
+ `) + `
426
+ `;
427
+ }
428
+ get firstPoint() {
429
+ return this.segments[0].firstPoint;
430
+ }
431
+ get lastPoint() {
432
+ return this.segments[this.segments.length - 1].lastPoint;
433
+ }
434
+ get segmentsCount() {
435
+ return this.segments.length;
436
+ }
437
+ onStroke(t) {
438
+ return this.segments.some((n) => n.isOnSegment(t));
439
+ }
440
+ intersects(t) {
441
+ return this.boundingBox.overlaps(t.boundingBox) ? this.segments.some(
442
+ (n) => t.segments.some(
443
+ (r) => R(n, r).count > 0
444
+ )
445
+ ) : !1;
446
+ }
447
+ get boundingBox() {
448
+ if (this._boundingBox === null) {
449
+ let t = this.segments[0].boundingBox;
450
+ this.segments.slice(1).forEach((n) => {
451
+ t = t.merge(n.boundingBox);
452
+ }), this._boundingBox = t;
453
+ }
454
+ return this._boundingBox;
455
+ }
456
+ [Symbol.for("nodejs.util.inspect.custom")]() {
457
+ return this.repr;
458
+ }
459
+ }
460
+ function Ct(e, t = "Stroke") {
461
+ ut(e.length).forEach(
462
+ ([n, r]) => {
463
+ if (n === r)
464
+ return;
465
+ const s = e[n], i = e[r], o = R(s, i);
466
+ if (o.count !== 0) {
467
+ if (o.count === 1 && !o.overlaps.length) {
468
+ const u = n - r, a = o.intersections[0];
469
+ if (u === 1 && c(s.firstPoint, a) || u === -1 && c(s.lastPoint, a) || u === e.length - 1 && c(s.lastPoint, a) && c(i.firstPoint, a) || -u === e.length - 1 && c(s.firstPoint, a) && c(i.lastPoint, a))
470
+ return;
471
+ }
472
+ throw new Error(
473
+ `${t} segments must not intersect, but segments ${s.repr} and ${i.repr} do`
474
+ );
475
+ }
476
+ }
477
+ );
478
+ }
479
+ function mt(e, t = "Stroke") {
480
+ if (e.length === 0)
481
+ throw new Error(`${t} must have at least one segment`);
482
+ E([e.slice(0, -1), e.slice(1)]).forEach(
483
+ ([n, r]) => {
484
+ if (!c(n.lastPoint, r.firstPoint))
485
+ throw new Error(
486
+ `${t} segments must be connected, but ${n.repr} and ${r.repr} are not`
487
+ );
488
+ }
489
+ ), Ct(e, t);
490
+ }
491
+ function nt(e, t) {
492
+ return !!(e instanceof p && t instanceof p && lt(e.V, t.V));
493
+ }
494
+ function et(e, t) {
495
+ if (e instanceof p && t instanceof p)
496
+ return new p(e.firstPoint, t.lastPoint);
497
+ throw new Error("Not implemented");
498
+ }
499
+ function gt(e) {
500
+ let t = !1;
501
+ const n = [];
502
+ for (const r of e.segments) {
503
+ if (n.length === 0) {
504
+ n.push(r);
505
+ continue;
506
+ }
507
+ const s = n[n.length - 1];
508
+ nt(s, r) ? (t = !0, n.pop(), n.push(et(s, r))) : n.push(r);
509
+ }
510
+ if (c(e.firstPoint, e.lastPoint) && nt(
511
+ n[0],
512
+ n[n.length - 1]
513
+ )) {
514
+ t = !0;
515
+ const r = n.pop();
516
+ n[0] = et(r, n[0]);
517
+ }
518
+ return t ? n : null;
519
+ }
520
+ class w extends ft {
521
+ reverse() {
522
+ const t = this.segments.map((n) => n.reverse());
523
+ return t.reverse(), new w(t, { ignoreChecks: !0 });
524
+ }
525
+ clone() {
526
+ return new w(
527
+ this.segments.map((t) => t.clone()),
528
+ { ignoreChecks: !0 }
529
+ );
530
+ }
531
+ extend(t) {
532
+ if (!c(this.lastPoint, t.firstPoint))
533
+ throw console.error(this.repr, t.repr), new Error("Cannot extend strand: connection point is not the same");
534
+ return new w([...this.segments, ...t.segments]);
535
+ }
536
+ simplify() {
537
+ const t = gt(this);
538
+ return t ? new w(t, { ignoreChecks: !0 }) : this;
539
+ }
540
+ transform(t) {
541
+ return new w(
542
+ this.segments.map((n) => n.transform(t)),
543
+ { ignoreChecks: !0 }
544
+ );
545
+ }
546
+ }
547
+ const It = (e, t) => {
548
+ const n = ht(t, {
549
+ V: [1, 0],
550
+ firstPoint: e,
551
+ precision: t.precision
552
+ });
553
+ if (n === "parallel")
554
+ return 0;
555
+ const { intersectionParam1: r, intersectionParam2: s } = n;
556
+ if (!t.isValidParameter(r) || s <= -t.precision)
557
+ return 0;
558
+ if (Math.abs(r) < t.precision || Math.abs(r - 1) < t.precision) {
559
+ const [, i] = t.midPoint;
560
+ return e[1] - i < 0 ? 1 : 0;
561
+ }
562
+ return 1;
563
+ };
564
+ function Vt(e, t) {
565
+ if (t instanceof p)
566
+ return It(e, t);
567
+ throw new Error("Not implemented");
568
+ }
569
+ class V extends ft {
570
+ constructor(t, { ignoreChecks: n = !1 } = {}) {
571
+ super(t, { ignoreChecks: !0 }), n || Et(t);
572
+ }
573
+ clone() {
574
+ return new V(
575
+ this.segments.map((t) => t.clone()),
576
+ { ignoreChecks: !0 }
577
+ );
578
+ }
579
+ reverse() {
580
+ const t = this.segments.map((n) => n.reverse());
581
+ return t.reverse(), new V(t, { ignoreChecks: !0 });
582
+ }
583
+ transform(t) {
584
+ return new V(
585
+ this.segments.map((n) => n.transform(t)),
586
+ { ignoreChecks: !0 }
587
+ );
588
+ }
589
+ contains(t) {
590
+ return this.onStroke(t) ? !1 : this.segments.reduce((r, s) => r + Vt(t, s), 0) % 2 === 1;
591
+ }
592
+ simplify() {
593
+ const t = gt(this);
594
+ return t ? new V(t, { ignoreChecks: !0 }) : this;
595
+ }
596
+ }
597
+ function Et(e) {
598
+ if (mt(e, "Loop"), !c(e[0].firstPoint, e[e.length - 1].lastPoint))
599
+ throw new Error("Loop segment must be closed");
600
+ }
601
+ const rt = (e, t) => {
602
+ const n = e.findIndex((i) => c(t, i.firstPoint)), r = e.slice(0, n);
603
+ return e.slice(n).concat(r);
604
+ }, st = (e, t) => {
605
+ let n = e;
606
+ const r = (u) => c(u.firstPoint, t.firstPoint) && c(u.lastPoint, t.lastPoint);
607
+ let s = e.findIndex(r);
608
+ if (s === -1) {
609
+ const u = e.map((a) => a.reverse());
610
+ if (u.reverse(), s = u.findIndex(r), s === -1)
611
+ throw console.error(
612
+ u.map((a) => a.repr),
613
+ t.repr
614
+ ), new Error("Failed to rotate to segment start");
615
+ n = u;
616
+ }
617
+ const i = n.slice(0, s);
618
+ return n.slice(s).concat(i);
619
+ };
620
+ function* it(e, t, n) {
621
+ const r = (o) => t.some((u) => c(u, o.lastPoint)), s = (o) => n.some((u) => o.isSame(u));
622
+ let i = [];
623
+ for (const o of e)
624
+ r(o) ? (i.push(o), yield new w(i, { ignoreChecks: !0 }), i = []) : s(o) ? (i.length && (yield new w(i, { ignoreChecks: !0 }), i = []), yield new w([o], { ignoreChecks: !0 })) : i.push(o);
625
+ i.length && (yield new w(i, { ignoreChecks: !0 }));
626
+ }
627
+ function Ft(e, t, n) {
628
+ return e.filter((r) => {
629
+ const s = t.filter((u) => c(u.firstPoint, r) || c(u.lastPoint, r));
630
+ if (s.length % 2)
631
+ throw new Error("Bug in the intersection algo on non crossing point");
632
+ const i = s.map((u) => n.contains(u.midPoint));
633
+ return !(i.every((u) => u) || !i.some((u) => u));
634
+ });
635
+ }
636
+ function At(e, t, n) {
637
+ let r = [];
638
+ const s = [], i = new Array(e.segments.length).fill(0).map(() => []), o = new Array(t.segments.length).fill(0).map(() => []);
639
+ if (e.segments.forEach((f, g) => {
640
+ t.segments.forEach((P, x) => {
641
+ const { intersections: d, overlaps: S } = R(
642
+ f,
643
+ P,
644
+ n
645
+ );
646
+ r.push(...d), i[g].push(...d), o[x].push(...d), s.push(...S);
647
+ const v = S.flatMap((b) => [
648
+ b.firstPoint,
649
+ b.lastPoint
650
+ ]);
651
+ r.push(...v), i[g].push(...v), o[x].push(...v);
652
+ });
653
+ }), r = z(r, n), !r.length || r.length === 1)
654
+ return null;
655
+ const u = ([f, g]) => g.length ? f.splitAt(g) : [f];
656
+ let a = E([e.segments, i]).flatMap(u), l = E([t.segments, o]).flatMap(u);
657
+ if (r = Ft(
658
+ r,
659
+ a,
660
+ t
661
+ ), !r.length && !s.length)
662
+ return null;
663
+ if (s.length) {
664
+ const f = s[0];
665
+ a = st(
666
+ a,
667
+ f
668
+ ), l = st(
669
+ l,
670
+ f
671
+ );
672
+ } else {
673
+ const f = r[0];
674
+ a = rt(a, f), l = rt(l, f);
675
+ }
676
+ const h = Array.from(
677
+ it(
678
+ a,
679
+ r,
680
+ s
681
+ )
682
+ );
683
+ let m = Array.from(
684
+ it(
685
+ l,
686
+ r,
687
+ s
688
+ )
689
+ );
690
+ return (!c(
691
+ m[0].lastPoint,
692
+ h[0].lastPoint
693
+ ) || s.length > 0 && m[0].segmentsCount !== 1) && (m = m.reverse().map((f) => f.reverse())), E([h, m]).map(([f, g]) => f.segmentsCount === 1 && s.some((P) => f.segments[0].isSame(P)) ? [f, "same"] : [f, g]);
694
+ }
695
+ function W(e) {
696
+ let t = e[0];
697
+ for (const n of e.slice(1))
698
+ t = t.extend(n);
699
+ if (!c(t.firstPoint, t.lastPoint))
700
+ throw console.error(
701
+ k(t.firstPoint),
702
+ k(t.lastPoint)
703
+ ), new Error("Bug in the intersection algo on non closing strand");
704
+ return new V(t.segments);
705
+ }
706
+ function Bt(e) {
707
+ if (!e.length)
708
+ return [];
709
+ const t = e.map((o) => o.firstPoint);
710
+ let n = e.map((o) => o.lastPoint);
711
+ n = n.slice(-1).concat(n.slice(0, -1));
712
+ const r = E([t, n]).flatMap(
713
+ ([o, u], a) => c(o, u) ? [] : a
714
+ );
715
+ if (!r.length)
716
+ return [W(e)];
717
+ const s = E([
718
+ r.slice(0, -1),
719
+ r.slice(1)
720
+ ]).map(([o, u]) => W(e.slice(o, u)));
721
+ let i = e.slice(
722
+ r[r.length - 1]
723
+ );
724
+ return r[0] !== 0 && (i = i.concat(e.slice(0, r[0]))), s.push(W(i)), s;
725
+ }
726
+ const ot = (e, t) => {
727
+ if (e.length === 0)
728
+ return [t];
729
+ const n = e.at(-1);
730
+ return c(n.lastPoint, t.firstPoint) ? e.slice(0, -1).concat([n.extend(t)]) : c(n.lastPoint, t.lastPoint) ? e.slice(0, -1).concat([n.extend(t.reverse())]) : e.concat([t]);
731
+ }, kt = (e, t) => e.length === 0 ? [t] : c(e[0].firstPoint, t.lastPoint) ? [t.extend(e[0])].concat(e.slice(1)) : [t].concat(e);
732
+ function U(e, t, {
733
+ firstInside: n,
734
+ secondInside: r
735
+ }) {
736
+ const s = At(e, t);
737
+ if (!s) {
738
+ const a = e.segments[0].midPoint, l = t.contains(a), h = t.segments[0].midPoint, m = e.contains(h);
739
+ return {
740
+ identical: !1,
741
+ firstCurveInSecond: l,
742
+ secondCurveInFirst: m
743
+ };
744
+ }
745
+ if (s.every(([, a]) => a === "same"))
746
+ return { identical: !0 };
747
+ let i = null, o = null;
748
+ const u = s.flatMap(([a, l]) => {
749
+ let h = [], m = 0;
750
+ if (l === "same")
751
+ return o === 1 ? (o = 1, a) : o === 2 || o === 0 ? (o = null, []) : o === null ? (i ? i = i.extend(a) : i = a, []) : (console.error("weird situation"), []);
752
+ const f = a.segments[0].midPoint, g = t.contains(f);
753
+ (n === "keep" && g || n === "remove" && !g) && (m += 1, h = ot(h, a));
754
+ const P = l.segments[0].midPoint, x = e.contains(P);
755
+ if (r === "keep" && x || r === "remove" && !x) {
756
+ const d = l;
757
+ m += 1, m === 2 && h.length ? (h = ot(h, d), i = null) : h = [d];
758
+ }
759
+ return o === null && m === 1 && i && (h = kt(h, i)), m === 1 && (o = m, i = null), h.length ? h : (i = null, []);
760
+ });
761
+ return Bt(u);
762
+ }
763
+ const Lt = (e, t) => {
764
+ const n = U(e, t, {
765
+ firstInside: "remove",
766
+ secondInside: "remove"
767
+ });
768
+ return Array.isArray(n) ? n : n.identical ? [e] : n.firstCurveInSecond ? [t] : n.secondCurveInFirst ? [e] : [e, t];
769
+ }, j = (e, t) => {
770
+ const n = U(e, t, {
771
+ firstInside: "remove",
772
+ secondInside: "keep"
773
+ });
774
+ return Array.isArray(n) ? n : n.identical ? [] : n.firstCurveInSecond ? [] : n.secondCurveInFirst ? [e, t] : [e];
775
+ }, J = (e, t) => {
776
+ const n = U(e, t, {
777
+ firstInside: "keep",
778
+ secondInside: "keep"
779
+ });
780
+ return Array.isArray(n) ? n : n.identical ? [e] : n.firstCurveInSecond ? [e] : n.secondCurveInFirst ? [t] : [];
781
+ };
782
+ function Ot(e) {
783
+ const t = /* @__PURE__ */ new Map(), n = [];
784
+ return e.forEach((r, s) => {
785
+ let i;
786
+ t.has(s) ? i = t.get(s) : (i = { current: [r], fusedWith: /* @__PURE__ */ new Set([s]) }, n.push(i)), e.slice(s + 1).forEach((o, u) => {
787
+ const a = i.current, l = s + u + 1;
788
+ if (i.fusedWith.has(l))
789
+ return;
790
+ let h = [o], m = !1;
791
+ if (t.has(l) && (h = t.get(l).current, m = !0), !a.some(
792
+ (P) => h.some((x) => P.intersects(x))
793
+ ))
794
+ return;
795
+ let g;
796
+ a.length > 1 || h.length > 1 ? g = L(a, h) : g = pt(a[0], h[0]), i.fusedWith.add(l), i.current = g, m || t.set(l, i);
797
+ });
798
+ }), n.flatMap(({ current: r }) => r);
799
+ }
800
+ function pt(e, t) {
801
+ const n = Lt(e.contour, t.contour), r = t.holes.flatMap((o) => j(o, e.contour)), s = e.holes.flatMap((o) => j(o, t.contour)), i = yt(e.holes, t.holes).flatMap(
802
+ ([o, u]) => J(o, u)
803
+ );
804
+ return A([
805
+ ...n,
806
+ ...r,
807
+ ...s,
808
+ ...i
809
+ ]);
810
+ }
811
+ function N(e, t) {
812
+ if (e.isFull && t.isFull)
813
+ return A(j(e.contour, t.contour));
814
+ if (e.isFull) {
815
+ const r = j(e.contour, t.contour), s = t.holes.flatMap(
816
+ (i) => J(i, e.contour)
817
+ );
818
+ return A([...r, ...s]);
819
+ } else if (t.isFull && !e.contour.intersects(t.contour))
820
+ if (e.contour.contains(t.contour.firstPoint)) {
821
+ const r = L(
822
+ e.holes.map((s) => new M(s)),
823
+ [t]
824
+ );
825
+ return A([
826
+ e.contour,
827
+ ...r.flatMap((s) => s.allLoops)
828
+ ]);
829
+ } else
830
+ return [e];
831
+ let n = N(new M(e.contour), t);
832
+ return e.holes.forEach((r) => {
833
+ n = n.flatMap((s) => N(s, new M(r)));
834
+ }), n;
835
+ }
836
+ function $t(e, t) {
837
+ const n = J(e.contour, t.contour);
838
+ if (!n.length)
839
+ return [];
840
+ let r = A(n);
841
+ return r = O(
842
+ r,
843
+ e.holes.map((s) => new M(s))
844
+ ), O(
845
+ r,
846
+ t.holes.map((s) => new M(s))
847
+ );
848
+ }
849
+ function L(e, t) {
850
+ if (!e.length)
851
+ return t;
852
+ if (!t.length)
853
+ return e;
854
+ if (e.length === 1 && t.length > 1 || t.length === 1 && e.length > 1)
855
+ return Ot([...e, ...t]);
856
+ if (e.length > 1 && t.length > 1) {
857
+ let n = L([e[0]], t);
858
+ return e.slice(1).forEach((r) => {
859
+ n = L([r], n);
860
+ }), n;
861
+ }
862
+ return e.length === 1 && t.length === 1 ? pt(e[0], t[0]) : [];
863
+ }
864
+ function O(e, t) {
865
+ if (!e.length)
866
+ return [];
867
+ if (!t.length)
868
+ return e;
869
+ if (e.length === 1 && t.length === 1)
870
+ return N(e[0], t[0]);
871
+ if (e.length > 1)
872
+ return e.flatMap((r) => O([r], t));
873
+ let n = N(e[0], t[0]);
874
+ return t.slice(1).forEach((r) => {
875
+ n = O(n, [r]);
876
+ }), n;
877
+ }
878
+ function H(e, t) {
879
+ return !e.length || !t.length ? [] : e.length === 1 && t.length === 1 ? $t(e[0], t[0]) : e.length > 1 ? e.flatMap((n) => H([n], t)) : t.flatMap((n) => H(e, [n]));
880
+ }
881
+ class I extends D {
882
+ constructor(t = [], { ignoreChecks: n = !1 } = {}) {
883
+ super(), this._boundingBox = null, n || Tt(t), this.figures = t;
884
+ }
885
+ get isEmpty() {
886
+ return this.figures.length === 0;
887
+ }
888
+ get boundingBox() {
889
+ if (this.isEmpty)
890
+ return new B();
891
+ if (this._boundingBox === null) {
892
+ let t = this.figures[0].boundingBox;
893
+ for (const n of this.figures.slice(1))
894
+ t = t.merge(n.boundingBox);
895
+ this._boundingBox = t;
896
+ }
897
+ return this._boundingBox;
898
+ }
899
+ clone() {
900
+ return new I(this.figures.map((t) => t.clone()));
901
+ }
902
+ transform(t) {
903
+ return new I(this.figures.map((n) => n.transform(t)));
904
+ }
905
+ contains(t) {
906
+ return this.figures.some((n) => n.contains(t));
907
+ }
908
+ intersects(t) {
909
+ return this.figures.some(
910
+ (n) => t.figures.some((r) => n.intersects(r))
911
+ );
912
+ }
913
+ fuse(t) {
914
+ return new I(L(this.figures, t.figures));
915
+ }
916
+ cut(t) {
917
+ return new I(O(this.figures, t.figures));
918
+ }
919
+ intersect(t) {
920
+ return new I(H(this.figures, t.figures));
921
+ }
922
+ }
923
+ function Tt(e) {
924
+ for (const [t, n] of X(e))
925
+ if (t.intersects(n))
926
+ throw new Error("Diagram figures must not intersect");
927
+ }
928
+ export {
929
+ B,
930
+ I as D,
931
+ M as F,
932
+ p as L,
933
+ w as S,
934
+ y as T,
935
+ c as a,
936
+ V as b,
937
+ Pt as c,
938
+ O as d,
939
+ L as f,
940
+ H as i,
941
+ qt as p,
942
+ T as s
943
+ };
944
+ //# sourceMappingURL=Diagram-8b41118e.js.map