@emasoft/svg-matrix 1.0.30 → 1.0.31

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 (45) hide show
  1. package/bin/svg-matrix.js +310 -61
  2. package/bin/svglinter.cjs +102 -3
  3. package/bin/svgm.js +236 -27
  4. package/package.json +1 -1
  5. package/src/animation-optimization.js +137 -17
  6. package/src/animation-references.js +123 -6
  7. package/src/arc-length.js +213 -4
  8. package/src/bezier-analysis.js +217 -21
  9. package/src/bezier-intersections.js +275 -12
  10. package/src/browser-verify.js +237 -4
  11. package/src/clip-path-resolver.js +168 -0
  12. package/src/convert-path-data.js +479 -28
  13. package/src/css-specificity.js +73 -10
  14. package/src/douglas-peucker.js +219 -2
  15. package/src/flatten-pipeline.js +284 -26
  16. package/src/geometry-to-path.js +250 -25
  17. package/src/gjk-collision.js +236 -33
  18. package/src/index.js +261 -3
  19. package/src/inkscape-support.js +86 -28
  20. package/src/logger.js +48 -3
  21. package/src/marker-resolver.js +278 -74
  22. package/src/mask-resolver.js +265 -66
  23. package/src/matrix.js +44 -5
  24. package/src/mesh-gradient.js +352 -102
  25. package/src/off-canvas-detection.js +382 -13
  26. package/src/path-analysis.js +192 -18
  27. package/src/path-data-plugins.js +309 -5
  28. package/src/path-optimization.js +129 -5
  29. package/src/path-simplification.js +188 -32
  30. package/src/pattern-resolver.js +454 -106
  31. package/src/polygon-clip.js +324 -1
  32. package/src/svg-boolean-ops.js +226 -9
  33. package/src/svg-collections.js +7 -5
  34. package/src/svg-flatten.js +386 -62
  35. package/src/svg-parser.js +179 -8
  36. package/src/svg-rendering-context.js +235 -6
  37. package/src/svg-toolbox.js +45 -8
  38. package/src/svg2-polyfills.js +40 -10
  39. package/src/transform-decomposition.js +258 -32
  40. package/src/transform-optimization.js +259 -13
  41. package/src/transforms2d.js +82 -9
  42. package/src/transforms3d.js +62 -10
  43. package/src/use-symbol-resolver.js +286 -42
  44. package/src/vector.js +64 -8
  45. package/src/verification.js +392 -1
package/src/vector.js CHANGED
@@ -5,8 +5,19 @@ import Decimal from 'decimal.js';
5
5
  * Accepts numbers, strings, or Decimal instances.
6
6
  * @param {number|string|Decimal} x - The value to convert
7
7
  * @returns {Decimal} The Decimal representation
8
+ * @throws {Error} If x is null, undefined, or cannot be converted to Decimal
8
9
  */
9
- const D = x => (x instanceof Decimal ? x : new Decimal(x));
10
+ const D = x => {
11
+ if (x === null || x === undefined) {
12
+ throw new Error(`Cannot convert ${x === null ? 'null' : 'undefined'} to Decimal`);
13
+ }
14
+ if (x instanceof Decimal) return x;
15
+ try {
16
+ return new Decimal(x);
17
+ } catch (err) {
18
+ throw new Error(`Invalid numeric value: ${err.message}`);
19
+ }
20
+ };
10
21
 
11
22
  /**
12
23
  * Vector - Decimal-backed vector class for arbitrary-precision vector operations.
@@ -28,11 +39,21 @@ export class Vector {
28
39
  /**
29
40
  * Create a new Vector from an array of components.
30
41
  * @param {Array<number|string|Decimal>} components - Array of vector components
31
- * @throws {Error} If components is not an array
42
+ * @throws {Error} If components is not an array, is empty, or contains invalid values
32
43
  */
33
44
  constructor(components) {
34
45
  if (!Array.isArray(components)) throw new Error('Vector requires array');
35
- this.data = components.map(c => D(c));
46
+ if (components.length === 0) throw new Error('Vector requires at least one component');
47
+ try {
48
+ this.data = components.map((c, i) => {
49
+ if (c === null || c === undefined) {
50
+ throw new Error(`Vector component at index ${i} is ${c === null ? 'null' : 'undefined'}`);
51
+ }
52
+ return D(c);
53
+ });
54
+ } catch (err) {
55
+ throw new Error(`Vector constructor failed: ${err.message}`);
56
+ }
36
57
  this.length = this.data.length;
37
58
  }
38
59
 
@@ -40,8 +61,12 @@ export class Vector {
40
61
  * Factory method to create a Vector from an array.
41
62
  * @param {Array<number|string|Decimal>} arr - Array of vector components
42
63
  * @returns {Vector} New Vector instance
64
+ * @throws {Error} If arr is null or undefined
43
65
  */
44
66
  static from(arr) {
67
+ if (arr === null || arr === undefined) {
68
+ throw new Error(`Vector.from: argument is ${arr === null ? 'null' : 'undefined'}`);
69
+ }
45
70
  return new Vector(arr);
46
71
  }
47
72
 
@@ -116,9 +141,18 @@ export class Vector {
116
141
  * Scalar multiplication.
117
142
  * @param {number|string|Decimal} scalar - Scalar to multiply by
118
143
  * @returns {Vector} New scaled Vector
144
+ * @throws {Error} If scalar is null, undefined, or invalid
119
145
  */
120
146
  scale(scalar) {
121
- const s = D(scalar);
147
+ if (scalar === null || scalar === undefined) {
148
+ throw new Error(`scale: scalar is ${scalar === null ? 'null' : 'undefined'}`);
149
+ }
150
+ let s;
151
+ try {
152
+ s = D(scalar);
153
+ } catch (err) {
154
+ throw new Error(`scale: invalid scalar - ${err.message}`);
155
+ }
122
156
  return new Vector(this.data.map(v => v.mul(s)));
123
157
  }
124
158
 
@@ -156,12 +190,15 @@ export class Vector {
156
190
  *
157
191
  * @param {Vector} other - Vector to compute outer product with
158
192
  * @returns {Decimal[][]} 2D array of Decimals (can be passed to Matrix.from())
159
- * @throws {Error} If other is not a Vector
193
+ * @throws {Error} If other is not a Vector or either vector is empty
160
194
  */
161
195
  outer(other) {
162
196
  if (!other || !(other instanceof Vector)) {
163
197
  throw new Error('outer: argument must be a Vector');
164
198
  }
199
+ if (this.length === 0 || other.length === 0) {
200
+ throw new Error('outer: cannot compute outer product with empty vector');
201
+ }
165
202
  const rows = this.length, cols = other.length;
166
203
  const out = Array.from({ length: rows }, (_, i) =>
167
204
  Array.from({ length: cols }, (_, j) => this.data[i].mul(other.data[j]))
@@ -267,8 +304,12 @@ export class Vector {
267
304
  * @throws {Error} If unable to find orthogonal vector (e.g., zero vector)
268
305
  */
269
306
  orthogonal() {
307
+ const n = this.norm();
308
+ if (n.isZero()) {
309
+ throw new Error('orthogonal: cannot find orthogonal vector to zero vector');
310
+ }
270
311
  if (this.length === 2) {
271
- // 2D perpendicular: rotate 90 degrees counterclockwise
312
+ // 2D perpendicular: rotate 90 degrees counterclockwise [-y, x]
272
313
  return new Vector([this.data[1].negated(), this.data[0]]);
273
314
  }
274
315
  // For n > 2: find a standard basis vector not parallel to this,
@@ -282,7 +323,7 @@ export class Vector {
282
323
  const orthNorm = orth.norm();
283
324
  if (!orthNorm.isZero()) return orth.normalize();
284
325
  }
285
- throw new Error('Unable to find orthogonal vector');
326
+ throw new Error('orthogonal: unable to find orthogonal vector (degenerate case)');
286
327
  }
287
328
 
288
329
  /**
@@ -322,11 +363,26 @@ export class Vector {
322
363
  * @param {Vector} other - Vector to compare with
323
364
  * @param {number|string|Decimal} [tolerance=0] - Maximum allowed difference per component
324
365
  * @returns {boolean} True if vectors are equal within tolerance
366
+ * @throws {Error} If tolerance is invalid (null, NaN, or negative)
325
367
  */
326
368
  equals(other, tolerance = 0) {
327
369
  if (!(other instanceof Vector)) return false;
328
370
  if (other.length !== this.length) return false;
329
- const tol = D(tolerance);
371
+ if (tolerance === null) {
372
+ throw new Error('equals: tolerance cannot be null');
373
+ }
374
+ let tol;
375
+ try {
376
+ tol = D(tolerance);
377
+ if (tol.isNaN()) {
378
+ throw new Error('equals: tolerance cannot be NaN');
379
+ }
380
+ if (tol.isNegative()) {
381
+ throw new Error('equals: tolerance must be non-negative');
382
+ }
383
+ } catch (err) {
384
+ throw new Error(`equals: invalid tolerance - ${err.message}`);
385
+ }
330
386
  for (let i = 0; i < this.length; i++) {
331
387
  const diff = this.data[i].minus(other.data[i]).abs();
332
388
  if (diff.greaterThan(tol)) return false;