@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
@@ -45,19 +45,19 @@
45
45
  * @module path-optimization
46
46
  */
47
47
 
48
- import Decimal from 'decimal.js';
48
+ import Decimal from "decimal.js";
49
49
 
50
50
  // Set high precision for all calculations
51
51
  Decimal.set({ precision: 80 });
52
52
 
53
53
  // Helper to convert to Decimal
54
- const D = x => (x instanceof Decimal ? x : new Decimal(x));
54
+ const D = (x) => (x instanceof Decimal ? x : new Decimal(x));
55
55
 
56
56
  // Near-zero threshold for comparisons
57
- const EPSILON = new Decimal('1e-40');
57
+ const EPSILON = new Decimal("1e-40");
58
58
 
59
59
  // Default tolerance for optimization (user-configurable)
60
- const DEFAULT_TOLERANCE = new Decimal('1e-10');
60
+ const DEFAULT_TOLERANCE = new Decimal("1e-10");
61
61
 
62
62
  // ============================================================================
63
63
  // Point and Distance Utilities
@@ -70,8 +70,10 @@ const DEFAULT_TOLERANCE = new Decimal('1e-10');
70
70
  * @returns {{x: Decimal, y: Decimal}} Point object
71
71
  */
72
72
  export function point(x, y) {
73
- if (x === null || x === undefined) throw new Error('point: x coordinate is required');
74
- if (y === null || y === undefined) throw new Error('point: y coordinate is required');
73
+ if (x === null || x === undefined)
74
+ throw new Error("point: x coordinate is required");
75
+ if (y === null || y === undefined)
76
+ throw new Error("point: y coordinate is required");
75
77
  return { x: D(x), y: D(y) };
76
78
  }
77
79
 
@@ -82,9 +84,11 @@ export function point(x, y) {
82
84
  * @returns {Decimal} Distance
83
85
  */
84
86
  export function distance(p1, p2) {
85
- if (!p1 || !p2) throw new Error('distance: both points are required');
86
- if (p1.x === undefined || p1.y === undefined) throw new Error('distance: p1 must have x and y properties');
87
- if (p2.x === undefined || p2.y === undefined) throw new Error('distance: p2 must have x and y properties');
87
+ if (!p1 || !p2) throw new Error("distance: both points are required");
88
+ if (p1.x === undefined || p1.y === undefined)
89
+ throw new Error("distance: p1 must have x and y properties");
90
+ if (p2.x === undefined || p2.y === undefined)
91
+ throw new Error("distance: p2 must have x and y properties");
88
92
  // Ensure coordinates are Decimal objects
89
93
  const x1 = p1.x instanceof Decimal ? p1.x : D(p1.x);
90
94
  const y1 = p1.y instanceof Decimal ? p1.y : D(p1.y);
@@ -103,9 +107,11 @@ export function distance(p1, p2) {
103
107
  * @returns {boolean} True if points are equal
104
108
  */
105
109
  export function pointsEqual(p1, p2, tolerance = EPSILON) {
106
- if (!p1 || !p2) throw new Error('pointsEqual: both points are required');
107
- if (p1.x === undefined || p1.y === undefined) throw new Error('pointsEqual: p1 must have x and y properties');
108
- if (p2.x === undefined || p2.y === undefined) throw new Error('pointsEqual: p2 must have x and y properties');
110
+ if (!p1 || !p2) throw new Error("pointsEqual: both points are required");
111
+ if (p1.x === undefined || p1.y === undefined)
112
+ throw new Error("pointsEqual: p1 must have x and y properties");
113
+ if (p2.x === undefined || p2.y === undefined)
114
+ throw new Error("pointsEqual: p2 must have x and y properties");
109
115
  const tol = D(tolerance);
110
116
  // Ensure coordinates are Decimal objects
111
117
  const x1 = p1.x instanceof Decimal ? p1.x : D(p1.x);
@@ -131,27 +137,34 @@ export function pointsEqual(p1, p2, tolerance = EPSILON) {
131
137
  * @returns {{x: Decimal, y: Decimal}} Point on curve
132
138
  */
133
139
  export function evaluateCubicBezier(p0, p1, p2, p3, t) {
134
- if (!p0 || !p1 || !p2 || !p3) throw new Error('evaluateCubicBezier: all points are required');
135
- if (p0.x === undefined || p0.y === undefined) throw new Error('evaluateCubicBezier: p0 must have x and y properties');
136
- if (p1.x === undefined || p1.y === undefined) throw new Error('evaluateCubicBezier: p1 must have x and y properties');
137
- if (p2.x === undefined || p2.y === undefined) throw new Error('evaluateCubicBezier: p2 must have x and y properties');
138
- if (p3.x === undefined || p3.y === undefined) throw new Error('evaluateCubicBezier: p3 must have x and y properties');
139
- if (t === null || t === undefined) throw new Error('evaluateCubicBezier: parameter t is required');
140
+ if (!p0 || !p1 || !p2 || !p3)
141
+ throw new Error("evaluateCubicBezier: all points are required");
142
+ if (p0.x === undefined || p0.y === undefined)
143
+ throw new Error("evaluateCubicBezier: p0 must have x and y properties");
144
+ if (p1.x === undefined || p1.y === undefined)
145
+ throw new Error("evaluateCubicBezier: p1 must have x and y properties");
146
+ if (p2.x === undefined || p2.y === undefined)
147
+ throw new Error("evaluateCubicBezier: p2 must have x and y properties");
148
+ if (p3.x === undefined || p3.y === undefined)
149
+ throw new Error("evaluateCubicBezier: p3 must have x and y properties");
150
+ if (t === null || t === undefined)
151
+ throw new Error("evaluateCubicBezier: parameter t is required");
140
152
 
141
153
  const tD = D(t);
142
154
  // Validate t is within valid range [0, 1] for Bezier curves
143
- if (tD.lessThan(0) || tD.greaterThan(1)) throw new Error('evaluateCubicBezier: parameter t must be in range [0, 1]');
155
+ if (tD.lessThan(0) || tD.greaterThan(1))
156
+ throw new Error("evaluateCubicBezier: parameter t must be in range [0, 1]");
144
157
  const oneMinusT = D(1).minus(tD);
145
158
 
146
159
  // Bernstein basis polynomials
147
- const b0 = oneMinusT.pow(3); // (1-t)³
148
- const b1 = D(3).mul(oneMinusT.pow(2)).mul(tD); // 3(1-t)²t
149
- const b2 = D(3).mul(oneMinusT).mul(tD.pow(2)); // 3(1-t)t²
150
- const b3 = tD.pow(3); // t³
160
+ const b0 = oneMinusT.pow(3); // (1-t)³
161
+ const b1 = D(3).mul(oneMinusT.pow(2)).mul(tD); // 3(1-t)²t
162
+ const b2 = D(3).mul(oneMinusT).mul(tD.pow(2)); // 3(1-t)t²
163
+ const b3 = tD.pow(3); // t³
151
164
 
152
165
  return {
153
166
  x: b0.mul(p0.x).plus(b1.mul(p1.x)).plus(b2.mul(p2.x)).plus(b3.mul(p3.x)),
154
- y: b0.mul(p0.y).plus(b1.mul(p1.y)).plus(b2.mul(p2.y)).plus(b3.mul(p3.y))
167
+ y: b0.mul(p0.y).plus(b1.mul(p1.y)).plus(b2.mul(p2.y)).plus(b3.mul(p3.y)),
155
168
  };
156
169
  }
157
170
 
@@ -166,25 +179,33 @@ export function evaluateCubicBezier(p0, p1, p2, p3, t) {
166
179
  * @returns {{x: Decimal, y: Decimal}} Point on curve
167
180
  */
168
181
  export function evaluateQuadraticBezier(p0, p1, p2, t) {
169
- if (!p0 || !p1 || !p2) throw new Error('evaluateQuadraticBezier: all points are required');
170
- if (p0.x === undefined || p0.y === undefined) throw new Error('evaluateQuadraticBezier: p0 must have x and y properties');
171
- if (p1.x === undefined || p1.y === undefined) throw new Error('evaluateQuadraticBezier: p1 must have x and y properties');
172
- if (p2.x === undefined || p2.y === undefined) throw new Error('evaluateQuadraticBezier: p2 must have x and y properties');
173
- if (t === null || t === undefined) throw new Error('evaluateQuadraticBezier: parameter t is required');
182
+ if (!p0 || !p1 || !p2)
183
+ throw new Error("evaluateQuadraticBezier: all points are required");
184
+ if (p0.x === undefined || p0.y === undefined)
185
+ throw new Error("evaluateQuadraticBezier: p0 must have x and y properties");
186
+ if (p1.x === undefined || p1.y === undefined)
187
+ throw new Error("evaluateQuadraticBezier: p1 must have x and y properties");
188
+ if (p2.x === undefined || p2.y === undefined)
189
+ throw new Error("evaluateQuadraticBezier: p2 must have x and y properties");
190
+ if (t === null || t === undefined)
191
+ throw new Error("evaluateQuadraticBezier: parameter t is required");
174
192
 
175
193
  const tD = D(t);
176
194
  // Validate t is within valid range [0, 1] for Bezier curves
177
- if (tD.lessThan(0) || tD.greaterThan(1)) throw new Error('evaluateQuadraticBezier: parameter t must be in range [0, 1]');
195
+ if (tD.lessThan(0) || tD.greaterThan(1))
196
+ throw new Error(
197
+ "evaluateQuadraticBezier: parameter t must be in range [0, 1]",
198
+ );
178
199
  const oneMinusT = D(1).minus(tD);
179
200
 
180
201
  // Bernstein basis polynomials
181
- const b0 = oneMinusT.pow(2); // (1-t)²
182
- const b1 = D(2).mul(oneMinusT).mul(tD); // 2(1-t)t
183
- const b2 = tD.pow(2); // t²
202
+ const b0 = oneMinusT.pow(2); // (1-t)²
203
+ const b1 = D(2).mul(oneMinusT).mul(tD); // 2(1-t)t
204
+ const b2 = tD.pow(2); // t²
184
205
 
185
206
  return {
186
207
  x: b0.mul(p0.x).plus(b1.mul(p1.x)).plus(b2.mul(p2.x)),
187
- y: b0.mul(p0.y).plus(b1.mul(p1.y)).plus(b2.mul(p2.y))
208
+ y: b0.mul(p0.y).plus(b1.mul(p1.y)).plus(b2.mul(p2.y)),
188
209
  };
189
210
  }
190
211
 
@@ -205,10 +226,14 @@ export function evaluateQuadraticBezier(p0, p1, p2, t) {
205
226
  * @returns {{canConvert: boolean, endX: Decimal, verified: boolean}} Conversion result
206
227
  */
207
228
  export function lineToHorizontal(x1, y1, x2, y2, tolerance = EPSILON) {
208
- if (x1 === null || x1 === undefined) throw new Error('lineToHorizontal: x1 is required');
209
- if (y1 === null || y1 === undefined) throw new Error('lineToHorizontal: y1 is required');
210
- if (x2 === null || x2 === undefined) throw new Error('lineToHorizontal: x2 is required');
211
- if (y2 === null || y2 === undefined) throw new Error('lineToHorizontal: y2 is required');
229
+ if (x1 === null || x1 === undefined)
230
+ throw new Error("lineToHorizontal: x1 is required");
231
+ if (y1 === null || y1 === undefined)
232
+ throw new Error("lineToHorizontal: y1 is required");
233
+ if (x2 === null || x2 === undefined)
234
+ throw new Error("lineToHorizontal: x2 is required");
235
+ if (y2 === null || y2 === undefined)
236
+ throw new Error("lineToHorizontal: y2 is required");
212
237
 
213
238
  const tol = D(tolerance);
214
239
  const startY = D(y1);
@@ -227,7 +252,7 @@ export function lineToHorizontal(x1, y1, x2, y2, tolerance = EPSILON) {
227
252
  return {
228
253
  canConvert,
229
254
  endX,
230
- verified
255
+ verified,
231
256
  };
232
257
  }
233
258
 
@@ -244,10 +269,14 @@ export function lineToHorizontal(x1, y1, x2, y2, tolerance = EPSILON) {
244
269
  * @returns {{canConvert: boolean, endY: Decimal, verified: boolean}} Conversion result
245
270
  */
246
271
  export function lineToVertical(x1, y1, x2, y2, tolerance = EPSILON) {
247
- if (x1 === null || x1 === undefined) throw new Error('lineToVertical: x1 is required');
248
- if (y1 === null || y1 === undefined) throw new Error('lineToVertical: y1 is required');
249
- if (x2 === null || x2 === undefined) throw new Error('lineToVertical: x2 is required');
250
- if (y2 === null || y2 === undefined) throw new Error('lineToVertical: y2 is required');
272
+ if (x1 === null || x1 === undefined)
273
+ throw new Error("lineToVertical: x1 is required");
274
+ if (y1 === null || y1 === undefined)
275
+ throw new Error("lineToVertical: y1 is required");
276
+ if (x2 === null || x2 === undefined)
277
+ throw new Error("lineToVertical: x2 is required");
278
+ if (y2 === null || y2 === undefined)
279
+ throw new Error("lineToVertical: y2 is required");
251
280
 
252
281
  const tol = D(tolerance);
253
282
  const startX = D(x1);
@@ -266,7 +295,7 @@ export function lineToVertical(x1, y1, x2, y2, tolerance = EPSILON) {
266
295
  return {
267
296
  canConvert,
268
297
  endY,
269
- verified
298
+ verified,
270
299
  };
271
300
  }
272
301
 
@@ -283,14 +312,19 @@ export function lineToVertical(x1, y1, x2, y2, tolerance = EPSILON) {
283
312
  * @returns {{x: Decimal, y: Decimal}} Reflected point
284
313
  */
285
314
  export function reflectPoint(control, center) {
286
- if (!control || !center) throw new Error('reflectPoint: both control and center points are required');
287
- if (control.x === undefined || control.y === undefined) throw new Error('reflectPoint: control must have x and y properties');
288
- if (center.x === undefined || center.y === undefined) throw new Error('reflectPoint: center must have x and y properties');
315
+ if (!control || !center)
316
+ throw new Error(
317
+ "reflectPoint: both control and center points are required",
318
+ );
319
+ if (control.x === undefined || control.y === undefined)
320
+ throw new Error("reflectPoint: control must have x and y properties");
321
+ if (center.x === undefined || center.y === undefined)
322
+ throw new Error("reflectPoint: center must have x and y properties");
289
323
 
290
324
  // Reflection formula: reflected = center + (center - control) = 2*center - control
291
325
  return {
292
326
  x: D(2).mul(center.x).minus(control.x),
293
- y: D(2).mul(center.y).minus(control.y)
327
+ y: D(2).mul(center.y).minus(control.y),
294
328
  };
295
329
  }
296
330
 
@@ -316,15 +350,34 @@ export function reflectPoint(control, center) {
316
350
  * @param {Decimal} [tolerance=DEFAULT_TOLERANCE] - Maximum allowed deviation
317
351
  * @returns {{canConvert: boolean, cp2X: Decimal, cp2Y: Decimal, endX: Decimal, endY: Decimal, maxDeviation: Decimal, verified: boolean}}
318
352
  */
319
- export function curveToSmooth(prevControl, x0, y0, x1, y1, x2, y2, x3, y3, tolerance = DEFAULT_TOLERANCE) {
320
- if (x0 === null || x0 === undefined) throw new Error('curveToSmooth: x0 is required');
321
- if (y0 === null || y0 === undefined) throw new Error('curveToSmooth: y0 is required');
322
- if (x1 === null || x1 === undefined) throw new Error('curveToSmooth: x1 is required');
323
- if (y1 === null || y1 === undefined) throw new Error('curveToSmooth: y1 is required');
324
- if (x2 === null || x2 === undefined) throw new Error('curveToSmooth: x2 is required');
325
- if (y2 === null || y2 === undefined) throw new Error('curveToSmooth: y2 is required');
326
- if (x3 === null || x3 === undefined) throw new Error('curveToSmooth: x3 is required');
327
- if (y3 === null || y3 === undefined) throw new Error('curveToSmooth: y3 is required');
353
+ export function curveToSmooth(
354
+ prevControl,
355
+ x0,
356
+ y0,
357
+ x1,
358
+ y1,
359
+ x2,
360
+ y2,
361
+ x3,
362
+ y3,
363
+ tolerance = DEFAULT_TOLERANCE,
364
+ ) {
365
+ if (x0 === null || x0 === undefined)
366
+ throw new Error("curveToSmooth: x0 is required");
367
+ if (y0 === null || y0 === undefined)
368
+ throw new Error("curveToSmooth: y0 is required");
369
+ if (x1 === null || x1 === undefined)
370
+ throw new Error("curveToSmooth: x1 is required");
371
+ if (y1 === null || y1 === undefined)
372
+ throw new Error("curveToSmooth: y1 is required");
373
+ if (x2 === null || x2 === undefined)
374
+ throw new Error("curveToSmooth: x2 is required");
375
+ if (y2 === null || y2 === undefined)
376
+ throw new Error("curveToSmooth: y2 is required");
377
+ if (x3 === null || x3 === undefined)
378
+ throw new Error("curveToSmooth: x3 is required");
379
+ if (y3 === null || y3 === undefined)
380
+ throw new Error("curveToSmooth: y3 is required");
328
381
 
329
382
  const tol = D(tolerance);
330
383
  const p0 = point(x0, y0);
@@ -341,7 +394,7 @@ export function curveToSmooth(prevControl, x0, y0, x1, y1, x2, y2, x3, y3, toler
341
394
  endX: p3.x,
342
395
  endY: p3.y,
343
396
  maxDeviation: D(Infinity),
344
- verified: true
397
+ verified: true,
345
398
  };
346
399
  }
347
400
 
@@ -359,7 +412,7 @@ export function curveToSmooth(prevControl, x0, y0, x1, y1, x2, y2, x3, y3, toler
359
412
  endX: p3.x,
360
413
  endY: p3.y,
361
414
  maxDeviation: controlDeviation,
362
- verified: true
415
+ verified: true,
363
416
  };
364
417
  }
365
418
 
@@ -388,7 +441,7 @@ export function curveToSmooth(prevControl, x0, y0, x1, y1, x2, y2, x3, y3, toler
388
441
  endX: p3.x,
389
442
  endY: p3.y,
390
443
  maxDeviation: Decimal.max(controlDeviation, maxSampleDeviation),
391
- verified: true
444
+ verified: true,
392
445
  };
393
446
  }
394
447
 
@@ -412,13 +465,28 @@ export function curveToSmooth(prevControl, x0, y0, x1, y1, x2, y2, x3, y3, toler
412
465
  * @param {Decimal} [tolerance=DEFAULT_TOLERANCE] - Maximum allowed deviation
413
466
  * @returns {{canConvert: boolean, endX: Decimal, endY: Decimal, maxDeviation: Decimal, verified: boolean}}
414
467
  */
415
- export function quadraticToSmooth(prevControl, x0, y0, x1, y1, x2, y2, tolerance = DEFAULT_TOLERANCE) {
416
- if (x0 === null || x0 === undefined) throw new Error('quadraticToSmooth: x0 is required');
417
- if (y0 === null || y0 === undefined) throw new Error('quadraticToSmooth: y0 is required');
418
- if (x1 === null || x1 === undefined) throw new Error('quadraticToSmooth: x1 is required');
419
- if (y1 === null || y1 === undefined) throw new Error('quadraticToSmooth: y1 is required');
420
- if (x2 === null || x2 === undefined) throw new Error('quadraticToSmooth: x2 is required');
421
- if (y2 === null || y2 === undefined) throw new Error('quadraticToSmooth: y2 is required');
468
+ export function quadraticToSmooth(
469
+ prevControl,
470
+ x0,
471
+ y0,
472
+ x1,
473
+ y1,
474
+ x2,
475
+ y2,
476
+ tolerance = DEFAULT_TOLERANCE,
477
+ ) {
478
+ if (x0 === null || x0 === undefined)
479
+ throw new Error("quadraticToSmooth: x0 is required");
480
+ if (y0 === null || y0 === undefined)
481
+ throw new Error("quadraticToSmooth: y0 is required");
482
+ if (x1 === null || x1 === undefined)
483
+ throw new Error("quadraticToSmooth: x1 is required");
484
+ if (y1 === null || y1 === undefined)
485
+ throw new Error("quadraticToSmooth: y1 is required");
486
+ if (x2 === null || x2 === undefined)
487
+ throw new Error("quadraticToSmooth: x2 is required");
488
+ if (y2 === null || y2 === undefined)
489
+ throw new Error("quadraticToSmooth: y2 is required");
422
490
 
423
491
  const tol = D(tolerance);
424
492
  const p0 = point(x0, y0);
@@ -432,7 +500,7 @@ export function quadraticToSmooth(prevControl, x0, y0, x1, y1, x2, y2, tolerance
432
500
  endX: p2.x,
433
501
  endY: p2.y,
434
502
  maxDeviation: D(Infinity),
435
- verified: true
503
+ verified: true,
436
504
  };
437
505
  }
438
506
 
@@ -448,7 +516,7 @@ export function quadraticToSmooth(prevControl, x0, y0, x1, y1, x2, y2, tolerance
448
516
  endX: p2.x,
449
517
  endY: p2.y,
450
518
  maxDeviation: controlDeviation,
451
- verified: true
519
+ verified: true,
452
520
  };
453
521
  }
454
522
 
@@ -475,7 +543,7 @@ export function quadraticToSmooth(prevControl, x0, y0, x1, y1, x2, y2, tolerance
475
543
  endX: p2.x,
476
544
  endY: p2.y,
477
545
  maxDeviation: Decimal.max(controlDeviation, maxSampleDeviation),
478
- verified: true
546
+ verified: true,
479
547
  };
480
548
  }
481
549
 
@@ -488,18 +556,30 @@ export function quadraticToSmooth(prevControl, x0, y0, x1, y1, x2, y2, tolerance
488
556
  * Used to avoid infinite recursion in verification.
489
557
  */
490
558
  function _toRelativeArgs(cmd, args, cx, cy) {
491
- if (!cmd || typeof cmd !== 'string') throw new Error('_toRelativeArgs: cmd must be a non-empty string');
492
- if (!Array.isArray(args)) throw new Error('_toRelativeArgs: args must be an array');
493
- if (cx === null || cx === undefined) throw new Error('_toRelativeArgs: cx is required');
494
- if (cy === null || cy === undefined) throw new Error('_toRelativeArgs: cy is required');
559
+ if (!cmd || typeof cmd !== "string")
560
+ throw new Error("_toRelativeArgs: cmd must be a non-empty string");
561
+ if (!Array.isArray(args))
562
+ throw new Error("_toRelativeArgs: args must be an array");
563
+ if (cx === null || cx === undefined)
564
+ throw new Error("_toRelativeArgs: cx is required");
565
+ if (cy === null || cy === undefined)
566
+ throw new Error("_toRelativeArgs: cy is required");
495
567
 
496
568
  // Validate that commands requiring arguments have at least one
497
- if (['M', 'L', 'H', 'V', 'C', 'S', 'Q', 'T', 'A'].includes(cmd) && args.length === 0) {
498
- throw new Error(`_toRelativeArgs: ${cmd} command requires arguments but received empty array`);
569
+ if (
570
+ ["M", "L", "H", "V", "C", "S", "Q", "T", "A"].includes(cmd) &&
571
+ args.length === 0
572
+ ) {
573
+ throw new Error(
574
+ `_toRelativeArgs: ${cmd} command requires arguments but received empty array`,
575
+ );
499
576
  }
500
577
 
501
- if (cmd === 'M' || cmd === 'L' || cmd === 'T') {
502
- if (args.length % 2 !== 0) throw new Error(`_toRelativeArgs: ${cmd} requires pairs of coordinates, got ${args.length} args`);
578
+ if (cmd === "M" || cmd === "L" || cmd === "T") {
579
+ if (args.length % 2 !== 0)
580
+ throw new Error(
581
+ `_toRelativeArgs: ${cmd} requires pairs of coordinates, got ${args.length} args`,
582
+ );
503
583
  const relativeArgs = [];
504
584
  for (let i = 0; i < args.length; i += 2) {
505
585
  relativeArgs.push(args[i].minus(cx));
@@ -507,14 +587,17 @@ function _toRelativeArgs(cmd, args, cx, cy) {
507
587
  }
508
588
  return relativeArgs;
509
589
  }
510
- if (cmd === 'H') {
511
- return args.map(x => x.minus(cx));
590
+ if (cmd === "H") {
591
+ return args.map((x) => x.minus(cx));
512
592
  }
513
- if (cmd === 'V') {
514
- return args.map(y => y.minus(cy));
593
+ if (cmd === "V") {
594
+ return args.map((y) => y.minus(cy));
515
595
  }
516
- if (cmd === 'C' || cmd === 'S' || cmd === 'Q') {
517
- if (args.length % 2 !== 0) throw new Error(`_toRelativeArgs: ${cmd} requires pairs of coordinates, got ${args.length} args`);
596
+ if (cmd === "C" || cmd === "S" || cmd === "Q") {
597
+ if (args.length % 2 !== 0)
598
+ throw new Error(
599
+ `_toRelativeArgs: ${cmd} requires pairs of coordinates, got ${args.length} args`,
600
+ );
518
601
  const relativeArgs = [];
519
602
  for (let i = 0; i < args.length; i += 2) {
520
603
  relativeArgs.push(args[i].minus(cx));
@@ -522,8 +605,11 @@ function _toRelativeArgs(cmd, args, cx, cy) {
522
605
  }
523
606
  return relativeArgs;
524
607
  }
525
- if (cmd === 'A') {
526
- if (args.length % 7 !== 0) throw new Error(`_toRelativeArgs: A requires groups of 7 args, got ${args.length} args`);
608
+ if (cmd === "A") {
609
+ if (args.length % 7 !== 0)
610
+ throw new Error(
611
+ `_toRelativeArgs: A requires groups of 7 args, got ${args.length} args`,
612
+ );
527
613
  const relativeArgs = [];
528
614
  for (let i = 0; i < args.length; i += 7) {
529
615
  relativeArgs.push(args[i]);
@@ -544,18 +630,30 @@ function _toRelativeArgs(cmd, args, cx, cy) {
544
630
  * Used to avoid infinite recursion in verification.
545
631
  */
546
632
  function _toAbsoluteArgs(cmd, args, cx, cy) {
547
- if (!cmd || typeof cmd !== 'string') throw new Error('_toAbsoluteArgs: cmd must be a non-empty string');
548
- if (!Array.isArray(args)) throw new Error('_toAbsoluteArgs: args must be an array');
549
- if (cx === null || cx === undefined) throw new Error('_toAbsoluteArgs: cx is required');
550
- if (cy === null || cy === undefined) throw new Error('_toAbsoluteArgs: cy is required');
633
+ if (!cmd || typeof cmd !== "string")
634
+ throw new Error("_toAbsoluteArgs: cmd must be a non-empty string");
635
+ if (!Array.isArray(args))
636
+ throw new Error("_toAbsoluteArgs: args must be an array");
637
+ if (cx === null || cx === undefined)
638
+ throw new Error("_toAbsoluteArgs: cx is required");
639
+ if (cy === null || cy === undefined)
640
+ throw new Error("_toAbsoluteArgs: cy is required");
551
641
 
552
642
  // Validate that commands requiring arguments have at least one
553
- if (['m', 'l', 'h', 'v', 'c', 's', 'q', 't', 'a'].includes(cmd) && args.length === 0) {
554
- throw new Error(`_toAbsoluteArgs: ${cmd} command requires arguments but received empty array`);
643
+ if (
644
+ ["m", "l", "h", "v", "c", "s", "q", "t", "a"].includes(cmd) &&
645
+ args.length === 0
646
+ ) {
647
+ throw new Error(
648
+ `_toAbsoluteArgs: ${cmd} command requires arguments but received empty array`,
649
+ );
555
650
  }
556
651
 
557
- if (cmd === 'm' || cmd === 'l' || cmd === 't') {
558
- if (args.length % 2 !== 0) throw new Error(`_toAbsoluteArgs: ${cmd} requires pairs of coordinates, got ${args.length} args`);
652
+ if (cmd === "m" || cmd === "l" || cmd === "t") {
653
+ if (args.length % 2 !== 0)
654
+ throw new Error(
655
+ `_toAbsoluteArgs: ${cmd} requires pairs of coordinates, got ${args.length} args`,
656
+ );
559
657
  const absoluteArgs = [];
560
658
  for (let i = 0; i < args.length; i += 2) {
561
659
  absoluteArgs.push(args[i].plus(cx));
@@ -563,14 +661,17 @@ function _toAbsoluteArgs(cmd, args, cx, cy) {
563
661
  }
564
662
  return absoluteArgs;
565
663
  }
566
- if (cmd === 'h') {
567
- return args.map(dx => dx.plus(cx));
664
+ if (cmd === "h") {
665
+ return args.map((dx) => dx.plus(cx));
568
666
  }
569
- if (cmd === 'v') {
570
- return args.map(dy => dy.plus(cy));
667
+ if (cmd === "v") {
668
+ return args.map((dy) => dy.plus(cy));
571
669
  }
572
- if (cmd === 'c' || cmd === 's' || cmd === 'q') {
573
- if (args.length % 2 !== 0) throw new Error(`_toAbsoluteArgs: ${cmd} requires pairs of coordinates, got ${args.length} args`);
670
+ if (cmd === "c" || cmd === "s" || cmd === "q") {
671
+ if (args.length % 2 !== 0)
672
+ throw new Error(
673
+ `_toAbsoluteArgs: ${cmd} requires pairs of coordinates, got ${args.length} args`,
674
+ );
574
675
  const absoluteArgs = [];
575
676
  for (let i = 0; i < args.length; i += 2) {
576
677
  absoluteArgs.push(args[i].plus(cx));
@@ -578,8 +679,11 @@ function _toAbsoluteArgs(cmd, args, cx, cy) {
578
679
  }
579
680
  return absoluteArgs;
580
681
  }
581
- if (cmd === 'a') {
582
- if (args.length % 7 !== 0) throw new Error(`_toAbsoluteArgs: a requires groups of 7 args, got ${args.length} args`);
682
+ if (cmd === "a") {
683
+ if (args.length % 7 !== 0)
684
+ throw new Error(
685
+ `_toAbsoluteArgs: a requires groups of 7 args, got ${args.length} args`,
686
+ );
583
687
  const absoluteArgs = [];
584
688
  for (let i = 0; i < args.length; i += 7) {
585
689
  absoluteArgs.push(args[i]);
@@ -607,11 +711,15 @@ function _toAbsoluteArgs(cmd, args, cx, cy) {
607
711
  * @returns {{command: string, args: Array<Decimal>, verified: boolean}}
608
712
  */
609
713
  export function toRelative(command, currentX, currentY) {
610
- if (!command) throw new Error('toRelative: command object is required');
611
- if (!command.command) throw new Error('toRelative: command.command is required');
612
- if (!Array.isArray(command.args)) throw new Error('toRelative: command.args must be an array');
613
- if (currentX === null || currentX === undefined) throw new Error('toRelative: currentX is required');
614
- if (currentY === null || currentY === undefined) throw new Error('toRelative: currentY is required');
714
+ if (!command) throw new Error("toRelative: command object is required");
715
+ if (!command.command)
716
+ throw new Error("toRelative: command.command is required");
717
+ if (!Array.isArray(command.args))
718
+ throw new Error("toRelative: command.args must be an array");
719
+ if (currentX === null || currentX === undefined)
720
+ throw new Error("toRelative: currentX is required");
721
+ if (currentY === null || currentY === undefined)
722
+ throw new Error("toRelative: currentY is required");
615
723
 
616
724
  const cmd = command.command;
617
725
  const args = command.args.map(D);
@@ -619,11 +727,11 @@ export function toRelative(command, currentX, currentY) {
619
727
  const cy = D(currentY);
620
728
 
621
729
  // Z command is already relative (closes to start of subpath)
622
- if (cmd === 'Z' || cmd === 'z') {
730
+ if (cmd === "Z" || cmd === "z") {
623
731
  return {
624
- command: 'z',
732
+ command: "z",
625
733
  args: [],
626
- verified: true
734
+ verified: true,
627
735
  };
628
736
  }
629
737
 
@@ -632,7 +740,7 @@ export function toRelative(command, currentX, currentY) {
632
740
  return {
633
741
  command: cmd,
634
742
  args,
635
- verified: true
743
+ verified: true,
636
744
  };
637
745
  }
638
746
 
@@ -653,7 +761,7 @@ export function toRelative(command, currentX, currentY) {
653
761
  return {
654
762
  command: relCmd,
655
763
  args: relativeArgs,
656
- verified
764
+ verified,
657
765
  };
658
766
  }
659
767
 
@@ -669,11 +777,15 @@ export function toRelative(command, currentX, currentY) {
669
777
  * @returns {{command: string, args: Array<Decimal>, verified: boolean}}
670
778
  */
671
779
  export function toAbsolute(command, currentX, currentY) {
672
- if (!command) throw new Error('toAbsolute: command object is required');
673
- if (!command.command) throw new Error('toAbsolute: command.command is required');
674
- if (!Array.isArray(command.args)) throw new Error('toAbsolute: command.args must be an array');
675
- if (currentX === null || currentX === undefined) throw new Error('toAbsolute: currentX is required');
676
- if (currentY === null || currentY === undefined) throw new Error('toAbsolute: currentY is required');
780
+ if (!command) throw new Error("toAbsolute: command object is required");
781
+ if (!command.command)
782
+ throw new Error("toAbsolute: command.command is required");
783
+ if (!Array.isArray(command.args))
784
+ throw new Error("toAbsolute: command.args must be an array");
785
+ if (currentX === null || currentX === undefined)
786
+ throw new Error("toAbsolute: currentX is required");
787
+ if (currentY === null || currentY === undefined)
788
+ throw new Error("toAbsolute: currentY is required");
677
789
 
678
790
  const cmd = command.command;
679
791
  const args = command.args.map(D);
@@ -681,11 +793,11 @@ export function toAbsolute(command, currentX, currentY) {
681
793
  const cy = D(currentY);
682
794
 
683
795
  // Z command is always absolute (closes to start of subpath)
684
- if (cmd === 'Z' || cmd === 'z') {
796
+ if (cmd === "Z" || cmd === "z") {
685
797
  return {
686
- command: 'Z',
798
+ command: "Z",
687
799
  args: [],
688
- verified: true
800
+ verified: true,
689
801
  };
690
802
  }
691
803
 
@@ -694,7 +806,7 @@ export function toAbsolute(command, currentX, currentY) {
694
806
  return {
695
807
  command: cmd,
696
808
  args,
697
- verified: true
809
+ verified: true,
698
810
  };
699
811
  }
700
812
 
@@ -715,7 +827,7 @@ export function toAbsolute(command, currentX, currentY) {
715
827
  return {
716
828
  command: absCmd,
717
829
  args: absoluteArgs,
718
- verified
830
+ verified,
719
831
  };
720
832
  }
721
833
 
@@ -731,23 +843,31 @@ export function toAbsolute(command, currentX, currentY) {
731
843
  * @returns {string} Formatted command string
732
844
  */
733
845
  function formatCommand(command, precision = 6) {
734
- if (!command) throw new Error('formatCommand: command object is required');
735
- if (!command.command) throw new Error('formatCommand: command.command is required');
736
- if (!Array.isArray(command.args)) throw new Error('formatCommand: command.args must be an array');
737
- if (typeof precision !== 'number' || precision < 0) throw new Error('formatCommand: precision must be a non-negative number');
846
+ if (!command) throw new Error("formatCommand: command object is required");
847
+ if (!command.command)
848
+ throw new Error("formatCommand: command.command is required");
849
+ if (!Array.isArray(command.args))
850
+ throw new Error("formatCommand: command.args must be an array");
851
+ if (typeof precision !== "number" || precision < 0)
852
+ throw new Error("formatCommand: precision must be a non-negative number");
738
853
 
739
854
  const cmd = command.command;
740
- const args = command.args.map((arg, index) => {
741
- // Convert to Decimal if not already, then to number
742
- const argDecimal = arg instanceof Decimal ? arg : D(arg);
743
- const num = argDecimal.toNumber();
744
- // Validate the number is finite
745
- if (!Number.isFinite(num)) throw new Error(`formatCommand: argument at index ${index} converted to non-finite number: ${num}`);
746
- // Format with specified precision and remove trailing zeros
747
- // Use toFixed for precision, then parseFloat to remove trailing zeros
748
- const formatted = num.toFixed(precision);
749
- return parseFloat(formatted).toString();
750
- }).join(',');
855
+ const args = command.args
856
+ .map((arg, index) => {
857
+ // Convert to Decimal if not already, then to number
858
+ const argDecimal = arg instanceof Decimal ? arg : D(arg);
859
+ const num = argDecimal.toNumber();
860
+ // Validate the number is finite
861
+ if (!Number.isFinite(num))
862
+ throw new Error(
863
+ `formatCommand: argument at index ${index} converted to non-finite number: ${num}`,
864
+ );
865
+ // Format with specified precision and remove trailing zeros
866
+ // Use toFixed for precision, then parseFloat to remove trailing zeros
867
+ const formatted = num.toFixed(precision);
868
+ return parseFloat(formatted).toString();
869
+ })
870
+ .join(",");
751
871
 
752
872
  return args.length > 0 ? `${cmd}${args}` : cmd;
753
873
  }
@@ -763,16 +883,29 @@ function formatCommand(command, precision = 6) {
763
883
  * @returns {{command: string, args: Array<Decimal>, isShorter: boolean, savedBytes: number, verified: boolean}}
764
884
  */
765
885
  export function chooseShorterForm(absCommand, relCommand, precision = 6) {
766
- if (!absCommand) throw new Error('chooseShorterForm: absCommand is required');
767
- if (!absCommand.command) throw new Error('chooseShorterForm: absCommand.command is required');
768
- if (!Array.isArray(absCommand.args)) throw new Error('chooseShorterForm: absCommand.args must be an array');
769
- if (!relCommand) throw new Error('chooseShorterForm: relCommand is required');
770
- if (!relCommand.command) throw new Error('chooseShorterForm: relCommand.command is required');
771
- if (!Array.isArray(relCommand.args)) throw new Error('chooseShorterForm: relCommand.args must be an array');
772
- if (typeof precision !== 'number' || precision < 0) throw new Error('chooseShorterForm: precision must be a non-negative number');
773
-
774
- const absStr = formatCommand({ command: absCommand.command, args: absCommand.args.map(D) }, precision);
775
- const relStr = formatCommand({ command: relCommand.command, args: relCommand.args.map(D) }, precision);
886
+ if (!absCommand) throw new Error("chooseShorterForm: absCommand is required");
887
+ if (!absCommand.command)
888
+ throw new Error("chooseShorterForm: absCommand.command is required");
889
+ if (!Array.isArray(absCommand.args))
890
+ throw new Error("chooseShorterForm: absCommand.args must be an array");
891
+ if (!relCommand) throw new Error("chooseShorterForm: relCommand is required");
892
+ if (!relCommand.command)
893
+ throw new Error("chooseShorterForm: relCommand.command is required");
894
+ if (!Array.isArray(relCommand.args))
895
+ throw new Error("chooseShorterForm: relCommand.args must be an array");
896
+ if (typeof precision !== "number" || precision < 0)
897
+ throw new Error(
898
+ "chooseShorterForm: precision must be a non-negative number",
899
+ );
900
+
901
+ const absStr = formatCommand(
902
+ { command: absCommand.command, args: absCommand.args.map(D) },
903
+ precision,
904
+ );
905
+ const relStr = formatCommand(
906
+ { command: relCommand.command, args: relCommand.args.map(D) },
907
+ precision,
908
+ );
776
909
 
777
910
  const absLen = absStr.length;
778
911
  const relLen = relStr.length;
@@ -792,7 +925,7 @@ export function chooseShorterForm(absCommand, relCommand, precision = 6) {
792
925
  args: relCommand.args.map(D),
793
926
  isShorter,
794
927
  savedBytes,
795
- verified
928
+ verified,
796
929
  };
797
930
  } else {
798
931
  return {
@@ -800,7 +933,7 @@ export function chooseShorterForm(absCommand, relCommand, precision = 6) {
800
933
  args: absCommand.args.map(D),
801
934
  isShorter: false,
802
935
  savedBytes: 0,
803
- verified
936
+ verified,
804
937
  };
805
938
  }
806
939
  }
@@ -821,26 +954,60 @@ export function chooseShorterForm(absCommand, relCommand, precision = 6) {
821
954
  * @returns {{commands: Array<{command: string, args: Array<Decimal>}>, collapseCount: number, verified: boolean}}
822
955
  */
823
956
  export function collapseRepeated(commands) {
824
- if (!Array.isArray(commands)) throw new Error('collapseRepeated: commands must be an array');
957
+ if (!Array.isArray(commands))
958
+ throw new Error("collapseRepeated: commands must be an array");
825
959
 
826
960
  // Validate each command object
827
961
  for (let i = 0; i < commands.length; i++) {
828
- if (!commands[i]) throw new Error(`collapseRepeated: command at index ${i} is null or undefined`);
829
- if (!commands[i].command) throw new Error(`collapseRepeated: command at index ${i} is missing 'command' property`);
830
- if (!Array.isArray(commands[i].args)) throw new Error(`collapseRepeated: command at index ${i} is missing 'args' array property`);
962
+ if (!commands[i])
963
+ throw new Error(
964
+ `collapseRepeated: command at index ${i} is null or undefined`,
965
+ );
966
+ if (!commands[i].command)
967
+ throw new Error(
968
+ `collapseRepeated: command at index ${i} is missing 'command' property`,
969
+ );
970
+ if (!Array.isArray(commands[i].args))
971
+ throw new Error(
972
+ `collapseRepeated: command at index ${i} is missing 'args' array property`,
973
+ );
831
974
  // Validate that commands requiring arguments have them
832
975
  const cmd = commands[i].command;
833
- const requiresArgs = ['M', 'm', 'L', 'l', 'H', 'h', 'V', 'v', 'C', 'c', 'S', 's', 'Q', 'q', 'T', 't', 'A', 'a'].includes(cmd);
976
+ const requiresArgs = [
977
+ "M",
978
+ "m",
979
+ "L",
980
+ "l",
981
+ "H",
982
+ "h",
983
+ "V",
984
+ "v",
985
+ "C",
986
+ "c",
987
+ "S",
988
+ "s",
989
+ "Q",
990
+ "q",
991
+ "T",
992
+ "t",
993
+ "A",
994
+ "a",
995
+ ].includes(cmd);
834
996
  if (requiresArgs && commands[i].args.length === 0) {
835
- throw new Error(`collapseRepeated: command '${cmd}' at index ${i} requires arguments but has empty args array`);
997
+ throw new Error(
998
+ `collapseRepeated: command '${cmd}' at index ${i} requires arguments but has empty args array`,
999
+ );
836
1000
  }
837
1001
  }
838
1002
 
839
1003
  if (commands.length < 2) {
840
1004
  return {
841
- commands: commands.map(cmd => ({ command: cmd.command, args: cmd.args.map(D) })),
1005
+ commands: commands.map((cmd) => ({
1006
+ command: cmd.command,
1007
+ args: cmd.args.map(D),
1008
+ })),
842
1009
  collapseCount: 0,
843
- verified: true
1010
+ verified: true,
844
1011
  };
845
1012
  }
846
1013
 
@@ -857,7 +1024,22 @@ export function collapseRepeated(commands) {
857
1024
  // Note: M/m are excluded because M has special semantics (first pair is moveto, subsequent pairs become lineto)
858
1025
  // Note: A/a are excluded because arc commands have complex 7-parameter structure and flags
859
1026
  // Note: Z/z are excluded because they have no arguments
860
- const canCollapse = ['L', 'l', 'H', 'h', 'V', 'v', 'T', 't', 'C', 'c', 'S', 's', 'Q', 'q'].includes(command);
1027
+ const canCollapse = [
1028
+ "L",
1029
+ "l",
1030
+ "H",
1031
+ "h",
1032
+ "V",
1033
+ "v",
1034
+ "T",
1035
+ "t",
1036
+ "C",
1037
+ "c",
1038
+ "S",
1039
+ "s",
1040
+ "Q",
1041
+ "q",
1042
+ ].includes(command);
861
1043
 
862
1044
  if (canCollapse && command === currentCommand) {
863
1045
  // Same command - append args
@@ -879,14 +1061,17 @@ export function collapseRepeated(commands) {
879
1061
  }
880
1062
 
881
1063
  // VERIFICATION: Count total arguments should remain the same
882
- const originalArgCount = commands.reduce((sum, cmd) => sum + cmd.args.length, 0);
1064
+ const originalArgCount = commands.reduce(
1065
+ (sum, cmd) => sum + cmd.args.length,
1066
+ 0,
1067
+ );
883
1068
  const resultArgCount = result.reduce((sum, cmd) => sum + cmd.args.length, 0);
884
1069
  const verified = originalArgCount === resultArgCount;
885
1070
 
886
1071
  return {
887
1072
  commands: result,
888
1073
  collapseCount,
889
- verified
1074
+ verified,
890
1075
  };
891
1076
  }
892
1077
 
@@ -907,10 +1092,14 @@ export function collapseRepeated(commands) {
907
1092
  * @returns {{canConvert: boolean, deviation: Decimal, verified: boolean}}
908
1093
  */
909
1094
  export function lineToZ(lastX, lastY, startX, startY, tolerance = EPSILON) {
910
- if (lastX === null || lastX === undefined) throw new Error('lineToZ: lastX is required');
911
- if (lastY === null || lastY === undefined) throw new Error('lineToZ: lastY is required');
912
- if (startX === null || startX === undefined) throw new Error('lineToZ: startX is required');
913
- if (startY === null || startY === undefined) throw new Error('lineToZ: startY is required');
1095
+ if (lastX === null || lastX === undefined)
1096
+ throw new Error("lineToZ: lastX is required");
1097
+ if (lastY === null || lastY === undefined)
1098
+ throw new Error("lineToZ: lastY is required");
1099
+ if (startX === null || startX === undefined)
1100
+ throw new Error("lineToZ: startX is required");
1101
+ if (startY === null || startY === undefined)
1102
+ throw new Error("lineToZ: startY is required");
914
1103
 
915
1104
  const tol = D(tolerance);
916
1105
  const last = point(lastX, lastY);
@@ -927,7 +1116,7 @@ export function lineToZ(lastX, lastY, startX, startY, tolerance = EPSILON) {
927
1116
  return {
928
1117
  canConvert,
929
1118
  deviation,
930
- verified
1119
+ verified,
931
1120
  };
932
1121
  }
933
1122
 
@@ -935,11 +1124,7 @@ export function lineToZ(lastX, lastY, startX, startY, tolerance = EPSILON) {
935
1124
  // Exports
936
1125
  // ============================================================================
937
1126
 
938
- export {
939
- EPSILON,
940
- DEFAULT_TOLERANCE,
941
- D
942
- };
1127
+ export { EPSILON, DEFAULT_TOLERANCE, D };
943
1128
 
944
1129
  export default {
945
1130
  // Point utilities
@@ -975,5 +1160,5 @@ export default {
975
1160
 
976
1161
  // Constants
977
1162
  EPSILON,
978
- DEFAULT_TOLERANCE
1163
+ DEFAULT_TOLERANCE,
979
1164
  };