@emasoft/svg-matrix 1.1.0 → 1.2.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.
Files changed (55) hide show
  1. package/bin/svg-matrix.js +7 -6
  2. package/bin/svgm.js +109 -40
  3. package/dist/svg-matrix.min.js +7 -7
  4. package/dist/svg-toolbox.min.js +148 -228
  5. package/dist/svgm.min.js +152 -232
  6. package/dist/version.json +5 -5
  7. package/package.json +1 -1
  8. package/scripts/postinstall.js +72 -41
  9. package/scripts/test-postinstall.js +18 -16
  10. package/scripts/version-sync.js +78 -60
  11. package/src/animation-optimization.js +190 -98
  12. package/src/animation-references.js +11 -3
  13. package/src/arc-length.js +23 -20
  14. package/src/bezier-analysis.js +9 -13
  15. package/src/bezier-intersections.js +18 -4
  16. package/src/browser-verify.js +35 -8
  17. package/src/clip-path-resolver.js +285 -114
  18. package/src/convert-path-data.js +20 -8
  19. package/src/css-specificity.js +33 -9
  20. package/src/douglas-peucker.js +272 -141
  21. package/src/geometry-to-path.js +79 -22
  22. package/src/gjk-collision.js +287 -126
  23. package/src/index.js +56 -21
  24. package/src/inkscape-support.js +122 -101
  25. package/src/logger.js +43 -27
  26. package/src/marker-resolver.js +201 -121
  27. package/src/mask-resolver.js +231 -98
  28. package/src/matrix.js +9 -5
  29. package/src/mesh-gradient.js +22 -14
  30. package/src/off-canvas-detection.js +53 -17
  31. package/src/path-optimization.js +356 -171
  32. package/src/path-simplification.js +671 -256
  33. package/src/pattern-resolver.js +1 -3
  34. package/src/polygon-clip.js +396 -78
  35. package/src/svg-boolean-ops.js +90 -23
  36. package/src/svg-collections.js +1546 -667
  37. package/src/svg-flatten.js +152 -38
  38. package/src/svg-matrix-lib.js +2 -2
  39. package/src/svg-parser.js +5 -1
  40. package/src/svg-rendering-context.js +3 -1
  41. package/src/svg-toolbox-lib.js +2 -2
  42. package/src/svg-toolbox.js +99 -457
  43. package/src/svg-validation-data.js +513 -345
  44. package/src/svg2-polyfills.js +156 -93
  45. package/src/svgm-lib.js +8 -4
  46. package/src/transform-optimization.js +168 -51
  47. package/src/transforms2d.js +73 -40
  48. package/src/transforms3d.js +34 -27
  49. package/src/use-symbol-resolver.js +175 -76
  50. package/src/vector.js +80 -44
  51. package/src/vendor/inkscape-hatch-polyfill.js +143 -108
  52. package/src/vendor/inkscape-hatch-polyfill.min.js +291 -1
  53. package/src/vendor/inkscape-mesh-polyfill.js +953 -766
  54. package/src/vendor/inkscape-mesh-polyfill.min.js +896 -1
  55. package/src/verification.js +3 -4
@@ -732,9 +732,7 @@ export function resolvePattern(patternData, targetBBox, options = {}) {
732
732
  );
733
733
 
734
734
  // Parse patternTransform if present
735
- const patternTransform = parsePatternTransform(
736
- patternData.patternTransform,
737
- );
735
+ const patternTransform = parsePatternTransform(patternData.patternTransform);
738
736
 
739
737
  // Get tile positions
740
738
  const positions = getTilePositions(tile, targetBBox);
@@ -166,10 +166,24 @@ export function point(x, y) {
166
166
  */
167
167
  export function pointsEqual(p1, p2, tolerance = EPSILON) {
168
168
  // Validate parameters - check for null/undefined explicitly since Decimal objects are always truthy
169
- if (!p1 || typeof p1 !== "object" || p1.x === null || p1.x === undefined || p1.y === null || p1.y === undefined) {
169
+ if (
170
+ !p1 ||
171
+ typeof p1 !== "object" ||
172
+ p1.x === null ||
173
+ p1.x === undefined ||
174
+ p1.y === null ||
175
+ p1.y === undefined
176
+ ) {
170
177
  throw new Error("pointsEqual: p1 must be a point with x and y properties");
171
178
  }
172
- if (!p2 || typeof p2 !== "object" || p2.x === null || p2.x === undefined || p2.y === null || p2.y === undefined) {
179
+ if (
180
+ !p2 ||
181
+ typeof p2 !== "object" ||
182
+ p2.x === null ||
183
+ p2.x === undefined ||
184
+ p2.y === null ||
185
+ p2.y === undefined
186
+ ) {
173
187
  throw new Error("pointsEqual: p2 must be a point with x and y properties");
174
188
  }
175
189
  if (!tolerance || typeof tolerance.abs !== "function") {
@@ -221,13 +235,31 @@ export function pointsEqual(p1, p2, tolerance = EPSILON) {
221
235
  */
222
236
  export function cross(o, a, b) {
223
237
  // Validate parameters - check for null/undefined explicitly since Decimal objects are always truthy
224
- if (!o || o.x === null || o.x === undefined || o.y === null || o.y === undefined) {
238
+ if (
239
+ !o ||
240
+ o.x === null ||
241
+ o.x === undefined ||
242
+ o.y === null ||
243
+ o.y === undefined
244
+ ) {
225
245
  throw new Error("cross: origin point o must have x and y properties");
226
246
  }
227
- if (!a || a.x === null || a.x === undefined || a.y === null || a.y === undefined) {
247
+ if (
248
+ !a ||
249
+ a.x === null ||
250
+ a.x === undefined ||
251
+ a.y === null ||
252
+ a.y === undefined
253
+ ) {
228
254
  throw new Error("cross: point a must have x and y properties");
229
255
  }
230
- if (!b || b.x === null || b.x === undefined || b.y === null || b.y === undefined) {
256
+ if (
257
+ !b ||
258
+ b.x === null ||
259
+ b.x === undefined ||
260
+ b.y === null ||
261
+ b.y === undefined
262
+ ) {
231
263
  throw new Error("cross: point b must have x and y properties");
232
264
  }
233
265
  const ax = a.x.minus(o.x);
@@ -279,13 +311,31 @@ export function cross(o, a, b) {
279
311
  */
280
312
  export function dot(o, a, b) {
281
313
  // Validate parameters - check for null/undefined explicitly since Decimal objects are always truthy
282
- if (!o || o.x === null || o.x === undefined || o.y === null || o.y === undefined) {
314
+ if (
315
+ !o ||
316
+ o.x === null ||
317
+ o.x === undefined ||
318
+ o.y === null ||
319
+ o.y === undefined
320
+ ) {
283
321
  throw new Error("dot: origin point o must have x and y properties");
284
322
  }
285
- if (!a || a.x === null || a.x === undefined || a.y === null || a.y === undefined) {
323
+ if (
324
+ !a ||
325
+ a.x === null ||
326
+ a.x === undefined ||
327
+ a.y === null ||
328
+ a.y === undefined
329
+ ) {
286
330
  throw new Error("dot: point a must have x and y properties");
287
331
  }
288
- if (!b || b.x === null || b.x === undefined || b.y === null || b.y === undefined) {
332
+ if (
333
+ !b ||
334
+ b.x === null ||
335
+ b.x === undefined ||
336
+ b.y === null ||
337
+ b.y === undefined
338
+ ) {
289
339
  throw new Error("dot: point b must have x and y properties");
290
340
  }
291
341
  const ax = a.x.minus(o.x);
@@ -372,17 +422,49 @@ export function sign(val) {
372
422
  */
373
423
  export function segmentIntersection(a, b, c, d) {
374
424
  // Validate all segment endpoints - check for null/undefined explicitly
375
- if (!a || a.x === null || a.x === undefined || a.y === null || a.y === undefined) {
376
- throw new Error("segmentIntersection: point a must have x and y properties");
377
- }
378
- if (!b || b.x === null || b.x === undefined || b.y === null || b.y === undefined) {
379
- throw new Error("segmentIntersection: point b must have x and y properties");
380
- }
381
- if (!c || c.x === null || c.x === undefined || c.y === null || c.y === undefined) {
382
- throw new Error("segmentIntersection: point c must have x and y properties");
383
- }
384
- if (!d || d.x === null || d.x === undefined || d.y === null || d.y === undefined) {
385
- throw new Error("segmentIntersection: point d must have x and y properties");
425
+ if (
426
+ !a ||
427
+ a.x === null ||
428
+ a.x === undefined ||
429
+ a.y === null ||
430
+ a.y === undefined
431
+ ) {
432
+ throw new Error(
433
+ "segmentIntersection: point a must have x and y properties",
434
+ );
435
+ }
436
+ if (
437
+ !b ||
438
+ b.x === null ||
439
+ b.x === undefined ||
440
+ b.y === null ||
441
+ b.y === undefined
442
+ ) {
443
+ throw new Error(
444
+ "segmentIntersection: point b must have x and y properties",
445
+ );
446
+ }
447
+ if (
448
+ !c ||
449
+ c.x === null ||
450
+ c.x === undefined ||
451
+ c.y === null ||
452
+ c.y === undefined
453
+ ) {
454
+ throw new Error(
455
+ "segmentIntersection: point c must have x and y properties",
456
+ );
457
+ }
458
+ if (
459
+ !d ||
460
+ d.x === null ||
461
+ d.x === undefined ||
462
+ d.y === null ||
463
+ d.y === undefined
464
+ ) {
465
+ throw new Error(
466
+ "segmentIntersection: point d must have x and y properties",
467
+ );
386
468
  }
387
469
 
388
470
  // Direction vectors
@@ -465,17 +547,49 @@ export function segmentIntersection(a, b, c, d) {
465
547
  */
466
548
  export function lineSegmentIntersection(lineA, lineB, segA, segB) {
467
549
  // Validate all points - check for null/undefined explicitly
468
- if (!lineA || lineA.x === null || lineA.x === undefined || lineA.y === null || lineA.y === undefined) {
469
- throw new Error("lineSegmentIntersection: lineA must have x and y properties");
470
- }
471
- if (!lineB || lineB.x === null || lineB.x === undefined || lineB.y === null || lineB.y === undefined) {
472
- throw new Error("lineSegmentIntersection: lineB must have x and y properties");
473
- }
474
- if (!segA || segA.x === null || segA.x === undefined || segA.y === null || segA.y === undefined) {
475
- throw new Error("lineSegmentIntersection: segA must have x and y properties");
476
- }
477
- if (!segB || segB.x === null || segB.x === undefined || segB.y === null || segB.y === undefined) {
478
- throw new Error("lineSegmentIntersection: segB must have x and y properties");
550
+ if (
551
+ !lineA ||
552
+ lineA.x === null ||
553
+ lineA.x === undefined ||
554
+ lineA.y === null ||
555
+ lineA.y === undefined
556
+ ) {
557
+ throw new Error(
558
+ "lineSegmentIntersection: lineA must have x and y properties",
559
+ );
560
+ }
561
+ if (
562
+ !lineB ||
563
+ lineB.x === null ||
564
+ lineB.x === undefined ||
565
+ lineB.y === null ||
566
+ lineB.y === undefined
567
+ ) {
568
+ throw new Error(
569
+ "lineSegmentIntersection: lineB must have x and y properties",
570
+ );
571
+ }
572
+ if (
573
+ !segA ||
574
+ segA.x === null ||
575
+ segA.x === undefined ||
576
+ segA.y === null ||
577
+ segA.y === undefined
578
+ ) {
579
+ throw new Error(
580
+ "lineSegmentIntersection: segA must have x and y properties",
581
+ );
582
+ }
583
+ if (
584
+ !segB ||
585
+ segB.x === null ||
586
+ segB.x === undefined ||
587
+ segB.y === null ||
588
+ segB.y === undefined
589
+ ) {
590
+ throw new Error(
591
+ "lineSegmentIntersection: segB must have x and y properties",
592
+ );
479
593
  }
480
594
 
481
595
  const dx1 = lineB.x.minus(lineA.x);
@@ -553,7 +667,13 @@ export function lineSegmentIntersection(lineA, lineB, segA, segB) {
553
667
  */
554
668
  export function pointInPolygon(pt, polygon) {
555
669
  // Validate point parameter - check for null/undefined explicitly
556
- if (!pt || pt.x === null || pt.x === undefined || pt.y === null || pt.y === undefined) {
670
+ if (
671
+ !pt ||
672
+ pt.x === null ||
673
+ pt.x === undefined ||
674
+ pt.y === null ||
675
+ pt.y === undefined
676
+ ) {
557
677
  throw new Error("pointInPolygon: pt must have x and y properties");
558
678
  }
559
679
  // Validate polygon is an array
@@ -567,8 +687,16 @@ export function pointInPolygon(pt, polygon) {
567
687
 
568
688
  // Validate polygon elements have x and y properties
569
689
  for (let i = 0; i < n; i++) {
570
- if (!polygon[i] || polygon[i].x === null || polygon[i].x === undefined || polygon[i].y === null || polygon[i].y === undefined) {
571
- throw new Error(`pointInPolygon: polygon[${i}] must have x and y properties`);
690
+ if (
691
+ !polygon[i] ||
692
+ polygon[i].x === null ||
693
+ polygon[i].x === undefined ||
694
+ polygon[i].y === null ||
695
+ polygon[i].y === undefined
696
+ ) {
697
+ throw new Error(
698
+ `pointInPolygon: polygon[${i}] must have x and y properties`,
699
+ );
572
700
  }
573
701
  }
574
702
 
@@ -640,14 +768,36 @@ export function pointInPolygon(pt, polygon) {
640
768
  */
641
769
  export function pointOnSegment(pt, a, b) {
642
770
  // Validate all points - check for null/undefined explicitly
643
- if (!pt || pt.x === null || pt.x === undefined || pt.y === null || pt.y === undefined) {
771
+ if (
772
+ !pt ||
773
+ pt.x === null ||
774
+ pt.x === undefined ||
775
+ pt.y === null ||
776
+ pt.y === undefined
777
+ ) {
644
778
  throw new Error("pointOnSegment: pt must have x and y properties");
645
779
  }
646
- if (!a || a.x === null || a.x === undefined || a.y === null || a.y === undefined) {
647
- throw new Error("pointOnSegment: segment point a must have x and y properties");
648
- }
649
- if (!b || b.x === null || b.x === undefined || b.y === null || b.y === undefined) {
650
- throw new Error("pointOnSegment: segment point b must have x and y properties");
780
+ if (
781
+ !a ||
782
+ a.x === null ||
783
+ a.x === undefined ||
784
+ a.y === null ||
785
+ a.y === undefined
786
+ ) {
787
+ throw new Error(
788
+ "pointOnSegment: segment point a must have x and y properties",
789
+ );
790
+ }
791
+ if (
792
+ !b ||
793
+ b.x === null ||
794
+ b.x === undefined ||
795
+ b.y === null ||
796
+ b.y === undefined
797
+ ) {
798
+ throw new Error(
799
+ "pointOnSegment: segment point b must have x and y properties",
800
+ );
651
801
  }
652
802
 
653
803
  // Check collinearity using cross product
@@ -734,14 +884,28 @@ export function clipPolygonSH(subject, clip) {
734
884
 
735
885
  // Validate all subject points have x and y properties
736
886
  for (let i = 0; i < subject.length; i++) {
737
- if (!subject[i] || subject[i].x === null || subject[i].x === undefined || subject[i].y === null || subject[i].y === undefined) {
738
- throw new Error(`clipPolygonSH: subject[${i}] must have x and y properties`);
887
+ if (
888
+ !subject[i] ||
889
+ subject[i].x === null ||
890
+ subject[i].x === undefined ||
891
+ subject[i].y === null ||
892
+ subject[i].y === undefined
893
+ ) {
894
+ throw new Error(
895
+ `clipPolygonSH: subject[${i}] must have x and y properties`,
896
+ );
739
897
  }
740
898
  }
741
899
 
742
900
  // Validate all clip points have x and y properties
743
901
  for (let i = 0; i < clip.length; i++) {
744
- if (!clip[i] || clip[i].x === null || clip[i].x === undefined || clip[i].y === null || clip[i].y === undefined) {
902
+ if (
903
+ !clip[i] ||
904
+ clip[i].x === null ||
905
+ clip[i].x === undefined ||
906
+ clip[i].y === null ||
907
+ clip[i].y === undefined
908
+ ) {
745
909
  throw new Error(`clipPolygonSH: clip[${i}] must have x and y properties`);
746
910
  }
747
911
  }
@@ -822,13 +986,31 @@ export function clipPolygonSH(subject, clip) {
822
986
  */
823
987
  function isInsideEdge(pt, edgeStart, edgeEnd) {
824
988
  // Validate inputs (defensive check for internal function) - check for null/undefined explicitly
825
- if (!pt || pt.x === null || pt.x === undefined || pt.y === null || pt.y === undefined) {
989
+ if (
990
+ !pt ||
991
+ pt.x === null ||
992
+ pt.x === undefined ||
993
+ pt.y === null ||
994
+ pt.y === undefined
995
+ ) {
826
996
  throw new Error("isInsideEdge: pt must have x and y properties");
827
997
  }
828
- if (!edgeStart || edgeStart.x === null || edgeStart.x === undefined || edgeStart.y === null || edgeStart.y === undefined) {
998
+ if (
999
+ !edgeStart ||
1000
+ edgeStart.x === null ||
1001
+ edgeStart.x === undefined ||
1002
+ edgeStart.y === null ||
1003
+ edgeStart.y === undefined
1004
+ ) {
829
1005
  throw new Error("isInsideEdge: edgeStart must have x and y properties");
830
1006
  }
831
- if (!edgeEnd || edgeEnd.x === null || edgeEnd.x === undefined || edgeEnd.y === null || edgeEnd.y === undefined) {
1007
+ if (
1008
+ !edgeEnd ||
1009
+ edgeEnd.x === null ||
1010
+ edgeEnd.x === undefined ||
1011
+ edgeEnd.y === null ||
1012
+ edgeEnd.y === undefined
1013
+ ) {
832
1014
  throw new Error("isInsideEdge: edgeEnd must have x and y properties");
833
1015
  }
834
1016
 
@@ -852,16 +1034,40 @@ function isInsideEdge(pt, edgeStart, edgeEnd) {
852
1034
  */
853
1035
  function lineIntersection(a, b, c, d) {
854
1036
  // Validate inputs (defensive check for internal function) - check for null/undefined explicitly
855
- if (!a || a.x === null || a.x === undefined || a.y === null || a.y === undefined) {
1037
+ if (
1038
+ !a ||
1039
+ a.x === null ||
1040
+ a.x === undefined ||
1041
+ a.y === null ||
1042
+ a.y === undefined
1043
+ ) {
856
1044
  throw new Error("lineIntersection: point a must have x and y properties");
857
1045
  }
858
- if (!b || b.x === null || b.x === undefined || b.y === null || b.y === undefined) {
1046
+ if (
1047
+ !b ||
1048
+ b.x === null ||
1049
+ b.x === undefined ||
1050
+ b.y === null ||
1051
+ b.y === undefined
1052
+ ) {
859
1053
  throw new Error("lineIntersection: point b must have x and y properties");
860
1054
  }
861
- if (!c || c.x === null || c.x === undefined || c.y === null || c.y === undefined) {
1055
+ if (
1056
+ !c ||
1057
+ c.x === null ||
1058
+ c.x === undefined ||
1059
+ c.y === null ||
1060
+ c.y === undefined
1061
+ ) {
862
1062
  throw new Error("lineIntersection: point c must have x and y properties");
863
1063
  }
864
- if (!d || d.x === null || d.x === undefined || d.y === null || d.y === undefined) {
1064
+ if (
1065
+ !d ||
1066
+ d.x === null ||
1067
+ d.x === undefined ||
1068
+ d.y === null ||
1069
+ d.y === undefined
1070
+ ) {
865
1071
  throw new Error("lineIntersection: point d must have x and y properties");
866
1072
  }
867
1073
 
@@ -937,8 +1143,16 @@ export function polygonArea(polygon) {
937
1143
 
938
1144
  // Validate all polygon points have x and y properties
939
1145
  for (let i = 0; i < n; i++) {
940
- if (!polygon[i] || polygon[i].x === null || polygon[i].x === undefined || polygon[i].y === null || polygon[i].y === undefined) {
941
- throw new Error(`polygonArea: polygon[${i}] must have x and y properties`);
1146
+ if (
1147
+ !polygon[i] ||
1148
+ polygon[i].x === null ||
1149
+ polygon[i].x === undefined ||
1150
+ polygon[i].y === null ||
1151
+ polygon[i].y === undefined
1152
+ ) {
1153
+ throw new Error(
1154
+ `polygonArea: polygon[${i}] must have x and y properties`,
1155
+ );
942
1156
  }
943
1157
  }
944
1158
 
@@ -1083,8 +1297,16 @@ export function convexHull(points) {
1083
1297
  if (points.length < 3) {
1084
1298
  // Validate and convert points
1085
1299
  for (let i = 0; i < points.length; i++) {
1086
- if (!points[i] || points[i].x === null || points[i].x === undefined || points[i].y === null || points[i].y === undefined) {
1087
- throw new Error(`convexHull: points[${i}] must have x and y properties`);
1300
+ if (
1301
+ !points[i] ||
1302
+ points[i].x === null ||
1303
+ points[i].x === undefined ||
1304
+ points[i].y === null ||
1305
+ points[i].y === undefined
1306
+ ) {
1307
+ throw new Error(
1308
+ `convexHull: points[${i}] must have x and y properties`,
1309
+ );
1088
1310
  }
1089
1311
  }
1090
1312
  return points.map((p) => point(p.x, p.y));
@@ -1092,7 +1314,13 @@ export function convexHull(points) {
1092
1314
 
1093
1315
  // Validate all points have x and y properties before converting
1094
1316
  for (let i = 0; i < points.length; i++) {
1095
- if (!points[i] || points[i].x === null || points[i].x === undefined || points[i].y === null || points[i].y === undefined) {
1317
+ if (
1318
+ !points[i] ||
1319
+ points[i].x === null ||
1320
+ points[i].x === undefined ||
1321
+ points[i].y === null ||
1322
+ points[i].y === undefined
1323
+ ) {
1096
1324
  throw new Error(`convexHull: points[${i}] must have x and y properties`);
1097
1325
  }
1098
1326
  }
@@ -1183,7 +1411,13 @@ export function boundingBox(polygon) {
1183
1411
  }
1184
1412
 
1185
1413
  // Validate first point has x and y properties
1186
- if (!polygon[0] || polygon[0].x === null || polygon[0].x === undefined || polygon[0].y === null || polygon[0].y === undefined) {
1414
+ if (
1415
+ !polygon[0] ||
1416
+ polygon[0].x === null ||
1417
+ polygon[0].x === undefined ||
1418
+ polygon[0].y === null ||
1419
+ polygon[0].y === undefined
1420
+ ) {
1187
1421
  throw new Error("boundingBox: polygon[0] must have x and y properties");
1188
1422
  }
1189
1423
 
@@ -1195,8 +1429,16 @@ export function boundingBox(polygon) {
1195
1429
  for (let i = 0; i < polygon.length; i++) {
1196
1430
  const p = polygon[i];
1197
1431
  // Validate each point has x and y properties
1198
- if (!p || p.x === null || p.x === undefined || p.y === null || p.y === undefined) {
1199
- throw new Error(`boundingBox: polygon[${i}] must have x and y properties`);
1432
+ if (
1433
+ !p ||
1434
+ p.x === null ||
1435
+ p.x === undefined ||
1436
+ p.y === null ||
1437
+ p.y === undefined
1438
+ ) {
1439
+ throw new Error(
1440
+ `boundingBox: polygon[${i}] must have x and y properties`,
1441
+ );
1200
1442
  }
1201
1443
  const x = D(p.x);
1202
1444
  const y = D(p.y);
@@ -1242,13 +1484,33 @@ export function bboxIntersects(bb1, bb2) {
1242
1484
  if (!bb1 || !bb2) return false;
1243
1485
 
1244
1486
  // Validate bounding boxes have required properties - check for null/undefined explicitly
1245
- if (bb1.minX === null || bb1.minX === undefined || bb1.minY === null || bb1.minY === undefined ||
1246
- bb1.maxX === null || bb1.maxX === undefined || bb1.maxY === null || bb1.maxY === undefined) {
1247
- throw new Error("bboxIntersects: bb1 must have minX, minY, maxX, maxY properties");
1248
- }
1249
- if (bb2.minX === null || bb2.minX === undefined || bb2.minY === null || bb2.minY === undefined ||
1250
- bb2.maxX === null || bb2.maxX === undefined || bb2.maxY === null || bb2.maxY === undefined) {
1251
- throw new Error("bboxIntersects: bb2 must have minX, minY, maxX, maxY properties");
1487
+ if (
1488
+ bb1.minX === null ||
1489
+ bb1.minX === undefined ||
1490
+ bb1.minY === null ||
1491
+ bb1.minY === undefined ||
1492
+ bb1.maxX === null ||
1493
+ bb1.maxX === undefined ||
1494
+ bb1.maxY === null ||
1495
+ bb1.maxY === undefined
1496
+ ) {
1497
+ throw new Error(
1498
+ "bboxIntersects: bb1 must have minX, minY, maxX, maxY properties",
1499
+ );
1500
+ }
1501
+ if (
1502
+ bb2.minX === null ||
1503
+ bb2.minX === undefined ||
1504
+ bb2.minY === null ||
1505
+ bb2.minY === undefined ||
1506
+ bb2.maxX === null ||
1507
+ bb2.maxX === undefined ||
1508
+ bb2.maxY === null ||
1509
+ bb2.maxY === undefined
1510
+ ) {
1511
+ throw new Error(
1512
+ "bboxIntersects: bb2 must have minX, minY, maxX, maxY properties",
1513
+ );
1252
1514
  }
1253
1515
 
1254
1516
  return !(
@@ -1312,15 +1574,31 @@ export function polygonIntersection(subject, clip) {
1312
1574
 
1313
1575
  // Validate all subject points have x and y properties
1314
1576
  for (let i = 0; i < subject.length; i++) {
1315
- if (!subject[i] || subject[i].x === null || subject[i].x === undefined || subject[i].y === null || subject[i].y === undefined) {
1316
- throw new Error(`polygonIntersection: subject[${i}] must have x and y properties`);
1577
+ if (
1578
+ !subject[i] ||
1579
+ subject[i].x === null ||
1580
+ subject[i].x === undefined ||
1581
+ subject[i].y === null ||
1582
+ subject[i].y === undefined
1583
+ ) {
1584
+ throw new Error(
1585
+ `polygonIntersection: subject[${i}] must have x and y properties`,
1586
+ );
1317
1587
  }
1318
1588
  }
1319
1589
 
1320
1590
  // Validate all clip points have x and y properties
1321
1591
  for (let i = 0; i < clip.length; i++) {
1322
- if (!clip[i] || clip[i].x === null || clip[i].x === undefined || clip[i].y === null || clip[i].y === undefined) {
1323
- throw new Error(`polygonIntersection: clip[${i}] must have x and y properties`);
1592
+ if (
1593
+ !clip[i] ||
1594
+ clip[i].x === null ||
1595
+ clip[i].x === undefined ||
1596
+ clip[i].y === null ||
1597
+ clip[i].y === undefined
1598
+ ) {
1599
+ throw new Error(
1600
+ `polygonIntersection: clip[${i}] must have x and y properties`,
1601
+ );
1324
1602
  }
1325
1603
  }
1326
1604
 
@@ -1388,7 +1666,13 @@ export function isConvex(polygon) {
1388
1666
 
1389
1667
  // Validate all polygon points have x and y properties
1390
1668
  for (let i = 0; i < n; i++) {
1391
- if (!polygon[i] || polygon[i].x === null || polygon[i].x === undefined || polygon[i].y === null || polygon[i].y === undefined) {
1669
+ if (
1670
+ !polygon[i] ||
1671
+ polygon[i].x === null ||
1672
+ polygon[i].x === undefined ||
1673
+ polygon[i].y === null ||
1674
+ polygon[i].y === undefined
1675
+ ) {
1392
1676
  throw new Error(`isConvex: polygon[${i}] must have x and y properties`);
1393
1677
  }
1394
1678
  }
@@ -1438,7 +1722,9 @@ export function isConvex(polygon) {
1438
1722
  function generalPolygonIntersection(subject, clip) {
1439
1723
  // Validate inputs are arrays (defensive check for internal function)
1440
1724
  if (!Array.isArray(subject) || !Array.isArray(clip)) {
1441
- throw new Error("generalPolygonIntersection: both arguments must be arrays");
1725
+ throw new Error(
1726
+ "generalPolygonIntersection: both arguments must be arrays",
1727
+ );
1442
1728
  }
1443
1729
 
1444
1730
  const intersectionPoints = [];
@@ -1566,15 +1852,31 @@ export function polygonUnion(polygon1, polygon2) {
1566
1852
 
1567
1853
  // Validate all polygon1 points have x and y properties
1568
1854
  for (let i = 0; i < polygon1.length; i++) {
1569
- if (!polygon1[i] || polygon1[i].x === null || polygon1[i].x === undefined || polygon1[i].y === null || polygon1[i].y === undefined) {
1570
- throw new Error(`polygonUnion: polygon1[${i}] must have x and y properties`);
1855
+ if (
1856
+ !polygon1[i] ||
1857
+ polygon1[i].x === null ||
1858
+ polygon1[i].x === undefined ||
1859
+ polygon1[i].y === null ||
1860
+ polygon1[i].y === undefined
1861
+ ) {
1862
+ throw new Error(
1863
+ `polygonUnion: polygon1[${i}] must have x and y properties`,
1864
+ );
1571
1865
  }
1572
1866
  }
1573
1867
 
1574
1868
  // Validate all polygon2 points have x and y properties
1575
1869
  for (let i = 0; i < polygon2.length; i++) {
1576
- if (!polygon2[i] || polygon2[i].x === null || polygon2[i].x === undefined || polygon2[i].y === null || polygon2[i].y === undefined) {
1577
- throw new Error(`polygonUnion: polygon2[${i}] must have x and y properties`);
1870
+ if (
1871
+ !polygon2[i] ||
1872
+ polygon2[i].x === null ||
1873
+ polygon2[i].x === undefined ||
1874
+ polygon2[i].y === null ||
1875
+ polygon2[i].y === undefined
1876
+ ) {
1877
+ throw new Error(
1878
+ `polygonUnion: polygon2[${i}] must have x and y properties`,
1879
+ );
1578
1880
  }
1579
1881
  }
1580
1882
 
@@ -1913,15 +2215,31 @@ export function polygonDifference(polygon1, polygon2) {
1913
2215
 
1914
2216
  // Validate all polygon1 points have x and y properties
1915
2217
  for (let i = 0; i < polygon1.length; i++) {
1916
- if (!polygon1[i] || polygon1[i].x === null || polygon1[i].x === undefined || polygon1[i].y === null || polygon1[i].y === undefined) {
1917
- throw new Error(`polygonDifference: polygon1[${i}] must have x and y properties`);
2218
+ if (
2219
+ !polygon1[i] ||
2220
+ polygon1[i].x === null ||
2221
+ polygon1[i].x === undefined ||
2222
+ polygon1[i].y === null ||
2223
+ polygon1[i].y === undefined
2224
+ ) {
2225
+ throw new Error(
2226
+ `polygonDifference: polygon1[${i}] must have x and y properties`,
2227
+ );
1918
2228
  }
1919
2229
  }
1920
2230
 
1921
2231
  // Validate all polygon2 points have x and y properties
1922
2232
  for (let i = 0; i < polygon2.length; i++) {
1923
- if (!polygon2[i] || polygon2[i].x === null || polygon2[i].x === undefined || polygon2[i].y === null || polygon2[i].y === undefined) {
1924
- throw new Error(`polygonDifference: polygon2[${i}] must have x and y properties`);
2233
+ if (
2234
+ !polygon2[i] ||
2235
+ polygon2[i].x === null ||
2236
+ polygon2[i].x === undefined ||
2237
+ polygon2[i].y === null ||
2238
+ polygon2[i].y === undefined
2239
+ ) {
2240
+ throw new Error(
2241
+ `polygonDifference: polygon2[${i}] must have x and y properties`,
2242
+ );
1925
2243
  }
1926
2244
  }
1927
2245