svg-path-commander 0.1.10-alpha3 → 0.1.10

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 (112) hide show
  1. package/dist/svg-path-commander.esm.js +217 -205
  2. package/dist/svg-path-commander.esm.min.js +2 -2
  3. package/dist/svg-path-commander.js +226 -212
  4. package/dist/svg-path-commander.min.js +2 -2
  5. package/index.js +3 -0
  6. package/package.json +7 -6
  7. package/rollup.config.js +58 -0
  8. package/src/convert/pathToAbsolute.js +7 -5
  9. package/src/convert/pathToCurve.js +5 -5
  10. package/src/convert/pathToRelative.js +7 -6
  11. package/src/convert/pathToString.js +3 -3
  12. package/src/math/epsilon.js +1 -1
  13. package/src/parser/finalizeSegment.js +13 -18
  14. package/src/parser/isPathCommand.js +1 -1
  15. package/src/parser/parsePathString.js +6 -7
  16. package/src/parser/{svgPathArray.js → pathParser.js} +3 -3
  17. package/src/parser/scanFlag.js +1 -1
  18. package/src/parser/scanParam.js +1 -1
  19. package/src/parser/scanSegment.js +1 -1
  20. package/src/parser/skipSpaces.js +1 -1
  21. package/src/process/clonePath.js +4 -5
  22. package/src/process/fixArc.js +2 -2
  23. package/src/process/getSVGMatrix.js +8 -11
  24. package/src/process/lineToCubic.js +1 -1
  25. package/src/process/normalizePath.js +4 -3
  26. package/src/process/normalizeSegment.js +3 -3
  27. package/src/process/optimizePath.js +6 -3
  28. package/src/process/projection2d.js +1 -1
  29. package/src/process/quadToCubic.js +7 -7
  30. package/src/process/reverseCurve.js +2 -2
  31. package/src/process/reversePath.js +2 -2
  32. package/src/process/roundPath.js +27 -12
  33. package/src/process/segmentToCubic.js +4 -4
  34. package/src/process/splitCubic.js +1 -1
  35. package/src/process/splitPath.js +1 -1
  36. package/src/process/transformPath.js +2 -2
  37. package/src/svg-path-commander.js +17 -17
  38. package/src/util/getCubicSize.js +1 -1
  39. package/src/util/getDrawDirection.js +1 -1
  40. package/src/util/getPathArea.js +3 -3
  41. package/src/util/getPathBBox.js +2 -2
  42. package/src/util/getPathLength.js +1 -1
  43. package/src/util/getPointAtLength.js +1 -1
  44. package/src/util/isAbsoluteArray.js +1 -1
  45. package/src/util/isCurveArray.js +1 -1
  46. package/src/util/isNormalizedArray.js +1 -1
  47. package/src/util/isPathArray.js +1 -1
  48. package/src/util/isRelativeArray.js +1 -1
  49. package/src/util/isValidPath.js +2 -2
  50. package/src/util/shapeToPath.js +26 -26
  51. package/types/convert/pathToAbsolute.d.ts +1 -0
  52. package/types/convert/pathToCurve.d.ts +1 -0
  53. package/types/convert/pathToRelative.d.ts +1 -0
  54. package/types/convert/pathToString.d.ts +1 -0
  55. package/types/index.d.ts +74 -840
  56. package/types/math/epsilon.d.ts +2 -0
  57. package/types/math/midPoint.d.ts +1 -0
  58. package/types/math/rotateVector.d.ts +4 -0
  59. package/types/options/options.d.ts +6 -0
  60. package/types/parser/finalizeSegment.d.ts +1 -0
  61. package/types/parser/invalidPathValue.d.ts +2 -0
  62. package/types/parser/isArcCommand.d.ts +1 -0
  63. package/types/parser/isDigit.d.ts +1 -0
  64. package/types/parser/isDigitStart.d.ts +1 -0
  65. package/types/parser/isPathCommand.d.ts +1 -0
  66. package/types/parser/isSpace.d.ts +1 -0
  67. package/types/parser/paramsCount.d.ts +4 -0
  68. package/types/parser/parsePathString.d.ts +1 -0
  69. package/types/parser/pathParser.d.ts +12 -0
  70. package/types/parser/scanFlag.d.ts +1 -0
  71. package/types/parser/scanParam.d.ts +1 -0
  72. package/types/parser/scanSegment.d.ts +1 -0
  73. package/types/parser/skipSpaces.d.ts +1 -0
  74. package/types/process/arcToCubic.d.ts +1 -0
  75. package/types/process/clonePath.d.ts +1 -0
  76. package/types/process/fixArc.d.ts +1 -0
  77. package/types/process/getSVGMatrix.d.ts +2 -0
  78. package/types/process/lineToCubic.d.ts +1 -0
  79. package/types/process/normalizePath.d.ts +1 -0
  80. package/types/process/normalizeSegment.d.ts +1 -0
  81. package/types/process/optimizePath.d.ts +1 -0
  82. package/types/process/projection2d.d.ts +1 -0
  83. package/types/process/quadToCubic.d.ts +1 -0
  84. package/types/process/reverseCurve.d.ts +1 -0
  85. package/types/process/reversePath.d.ts +1 -0
  86. package/types/process/roundPath.d.ts +1 -0
  87. package/types/process/segmentToCubic.d.ts +1 -0
  88. package/types/process/shorthandToCubic.d.ts +4 -0
  89. package/types/process/shorthandToQuad.d.ts +4 -0
  90. package/types/process/splitPath.d.ts +1 -0
  91. package/types/process/transformEllipse.d.ts +5 -0
  92. package/types/process/transformPath.d.ts +1 -0
  93. package/types/svg-path-commander.d.ts +18 -0
  94. package/types/util/getCubicSize.d.ts +1 -0
  95. package/types/util/getDrawDirection.d.ts +1 -0
  96. package/types/util/getPathArea.d.ts +1 -0
  97. package/types/util/getPathBBox.d.ts +1 -0
  98. package/types/util/getPathLength.d.ts +1 -0
  99. package/types/util/getPointAtLength.d.ts +1 -0
  100. package/types/util/getPointAtSegLength.d.ts +4 -0
  101. package/types/util/getSegCubicLength.d.ts +1 -0
  102. package/types/util/isAbsoluteArray.d.ts +1 -0
  103. package/types/util/isCurveArray.d.ts +1 -0
  104. package/types/util/isNormalizedArray.d.ts +1 -0
  105. package/types/util/isPathArray.d.ts +1 -0
  106. package/types/util/isRelativeArray.d.ts +1 -0
  107. package/types/util/isValidPath.d.ts +1 -0
  108. package/types/util/shapeToPath.d.ts +6 -0
  109. package/types/util/util.d.ts +61 -0
  110. package/types/util/version.d.ts +2 -0
  111. package/src/index.js +0 -3
  112. package/types/types.d.ts +0 -83
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * SVGPathCommander v0.1.10alpha3 (http://thednp.github.io/svg-path-commander)
2
+ * SVGPathCommander v0.1.10 (http://thednp.github.io/svg-path-commander)
3
3
  * Copyright 2021 © thednp
4
4
  * Licensed under MIT (https://github.com/thednp/svg-path-commander/blob/master/LICENSE)
5
5
  */
@@ -23,31 +23,26 @@ const paramsCount = {
23
23
  /**
24
24
  * Breaks the parsing of a pathString once a segment is finalized.
25
25
  *
26
- * @param {SVGPC.parserPathArray} path the `parserPathArray` instance
26
+ * @param {svgpcNS.pathParser} path the `PathParser` instance
27
27
  */
28
28
  function finalizeSegment(path) {
29
29
  let pathCommand = path.pathValue[path.segmentStart];
30
- let pathComLK = pathCommand.toLowerCase();
31
- let params = path.data;
30
+ let LK = pathCommand.toLowerCase();
31
+ let { data } = path;
32
32
 
33
33
  // Process duplicated commands (without comand name)
34
- if (pathComLK === 'm' && params.length > 2) {
35
- path.segments.push([pathCommand, params[0], params[1]]);
36
- params = params.slice(2);
37
- pathComLK = 'l';
38
- pathCommand = (pathCommand === 'm') ? 'l' : 'L';
34
+ if (LK === 'm' && data.length > 2) {
35
+ path.segments.push([pathCommand, data[0], data[1]]);
36
+ data = data.slice(2);
37
+ LK = 'l';
38
+ pathCommand = pathCommand === 'm' ? 'l' : 'L';
39
39
  }
40
40
 
41
- if (pathComLK === 'r') {
41
+ while (data.length >= paramsCount[LK]) {
42
42
  // @ts-ignore
43
- path.segments.push([pathCommand].concat(params));
44
- } else {
45
- while (params.length >= paramsCount[pathComLK]) {
46
- // @ts-ignore
47
- path.segments.push([pathCommand].concat(params.splice(0, paramsCount[pathComLK])));
48
- if (!paramsCount[pathComLK]) {
49
- break;
50
- }
43
+ path.segments.push([pathCommand].concat(data.splice(0, paramsCount[LK])));
44
+ if (!paramsCount[LK]) {
45
+ break;
51
46
  }
52
47
  }
53
48
  }
@@ -58,7 +53,7 @@ const invalidPathValue = 'Invalid path value';
58
53
  * Validates an A (arc-to) specific path command value.
59
54
  * Usually a `large-arc-flag` or `sweep-flag`.
60
55
  *
61
- * @param {SVGPC.parserPathArray} path the `parserPathArray` instance
56
+ * @param {svgpcNS.pathParser} path the `PathParser` instance
62
57
  */
63
58
  function scanFlag(path) {
64
59
  const { index } = path;
@@ -93,7 +88,7 @@ function isDigit(code) {
93
88
  * Validates every character of the path string,
94
89
  * every path command, negative numbers or floating point numbers.
95
90
  *
96
- * @param {SVGPC.parserPathArray} path the `parserPathArray` instance
91
+ * @param {svgpcNS.pathParser} path the `PathParser` instance
97
92
  */
98
93
  function scanParam(path) {
99
94
  const { max, pathValue, index: start } = path;
@@ -205,7 +200,7 @@ function isSpace(ch) {
205
200
  * path string every time it encounters any kind of
206
201
  * space character.
207
202
  *
208
- * @param {SVGPC.parserPathArray} path the `parserPathArray` instance
203
+ * @param {svgpcNS.pathParser} path the `PathParser` instance
209
204
  */
210
205
  function skipSpaces(path) {
211
206
  const { pathValue, max } = path;
@@ -233,7 +228,7 @@ function isPathCommand(code) {
233
228
  case 0x71/* q */:
234
229
  case 0x74/* t */:
235
230
  case 0x61/* a */:
236
- case 0x72/* r */:
231
+ // case 0x72/* r */: // R is not supported
237
232
  return true;
238
233
  default:
239
234
  return false;
@@ -269,7 +264,7 @@ function isArcCommand(code) {
269
264
  * Scans every character in the path string to determine
270
265
  * where a segment starts and where it ends.
271
266
  *
272
- * @param {SVGPC.parserPathArray} path the `parserPathArray` instance
267
+ * @param {svgpcNS.pathParser} path the `PathParser` instance
273
268
  */
274
269
  function scanSegment(path) {
275
270
  const { max, pathValue, index } = path;
@@ -326,29 +321,28 @@ function scanSegment(path) {
326
321
  finalizeSegment(path);
327
322
  }
328
323
 
329
- // @ts-nocheck
330
324
  /**
331
325
  * Returns a clone of an existing `pathArray`.
332
326
  *
333
- * @param {SVGPC.pathArray | string[]} path the source `pathArray`
334
- * @returns {SVGPC.pathArray} the cloned `pathArray`
327
+ * @param {svgpcNS.pathArray | any[] | string} path the source `pathArray`
328
+ * @returns {any} the cloned `pathArray`
335
329
  */
336
330
  function clonePath(path) {
337
- return path.map((x) => {
331
+ return Array.isArray(path) ? path.map((x) => {
338
332
  if (Array.isArray(x)) {
339
333
  return clonePath(x);
340
334
  }
341
335
  return !Number.isNaN(+x) ? +x : x;
342
- });
336
+ }) : path;
343
337
  }
344
338
 
345
339
  /**
346
- * The `parserPathArray` used by the parser.
340
+ * The `PathParser` used by the parser.
347
341
  *
348
342
  * @param {string} pathString
349
343
  */
350
- function SVGPathArray(pathString) {
351
- /** @type {[string, ...number[]][]} */
344
+ function PathParser(pathString) {
345
+ /** @type {svgpcNS.pathArray} */
352
346
  this.segments = [];
353
347
  /** @type {string} */
354
348
  this.pathValue = pathString;
@@ -369,7 +363,7 @@ function SVGPathArray(pathString) {
369
363
  /**
370
364
  * Iterates an array to check if it's an actual `pathArray`.
371
365
  *
372
- * @param {string | SVGPC.pathArray} path the `pathArray` to be checked
366
+ * @param {string | svgpcNS.pathArray} path the `pathArray` to be checked
373
367
  * @returns {boolean} iteration result
374
368
  */
375
369
  function isPathArray(path) {
@@ -383,16 +377,15 @@ function isPathArray(path) {
383
377
  * Parses a path string value and returns an array
384
378
  * of segments we like to call `pathArray`.
385
379
  *
386
- * @param {string | SVGPC.pathArray} pathInput the string to be parsed
387
- * @returns {SVGPC.pathArray} the resulted `pathArray`
380
+ * @param {svgpcNS.pathArray | string} pathInput the string to be parsed
381
+ * @returns {svgpcNS.pathArray} the resulted `pathArray`
388
382
  */
389
383
  function parsePathString(pathInput) {
390
384
  if (isPathArray(pathInput)) {
391
- // @ts-ignore
392
385
  return clonePath(pathInput);
393
386
  }
394
- // @ts-ignore
395
- const path = new SVGPathArray(pathInput);
387
+
388
+ const path = new PathParser(`${pathInput}`); // TS expects string
396
389
 
397
390
  skipSpaces(path);
398
391
 
@@ -403,7 +396,7 @@ function parsePathString(pathInput) {
403
396
  if (path.err.length) {
404
397
  path.segments = [];
405
398
  } else if (path.segments.length) {
406
- if ('mM'.indexOf(path.segments[0][0]) < 0) {
399
+ if (!'mM'.includes(path.segments[0][0])) {
407
400
  path.err = `${invalidPathValue}: missing M/m`;
408
401
  path.segments = [];
409
402
  } else {
@@ -418,7 +411,7 @@ function parsePathString(pathInput) {
418
411
  * Iterates an array to check if it's a `pathArray`
419
412
  * with all absolute values.
420
413
  *
421
- * @param {string | SVGPC.pathArray} path the `pathArray` to be checked
414
+ * @param {string | svgpcNS.pathArray} path the `pathArray` to be checked
422
415
  * @returns {boolean} iteration result
423
416
  */
424
417
  function isAbsoluteArray(path) {
@@ -430,17 +423,17 @@ function isAbsoluteArray(path) {
430
423
  * Parses a path string value or object and returns an array
431
424
  * of segments, all converted to absolute values.
432
425
  *
433
- * @param {string | SVGPC.pathArray} pathInput the path string | object
434
- * @returns {SVGPC.pathArray} the resulted `pathArray` with absolute values
426
+ * @param {svgpcNS.pathArray | string} pathInput the path string | object
427
+ * @returns {svgpcNS.pathArray} the resulted `pathArray` with absolute values
435
428
  */
436
429
  function pathToAbsolute(pathInput) {
437
- if (Array.isArray(pathInput) && isAbsoluteArray(pathInput)) {
430
+ if (isAbsoluteArray(pathInput)) {
438
431
  return clonePath(pathInput);
439
432
  }
440
433
 
441
434
  const path = parsePathString(pathInput);
442
435
  const ii = path.length;
443
- /** @type {SVGPC.pathArray} */
436
+ /** @type {svgpcNS.pathArray} */
444
437
  const resultArray = [];
445
438
  let x = 0;
446
439
  let y = 0;
@@ -461,6 +454,8 @@ function pathToAbsolute(pathInput) {
461
454
  const segment = path[i];
462
455
  const [pathCommand] = segment;
463
456
  const absCommand = pathCommand.toUpperCase();
457
+ /** @type {svgpcNS.pathSegment} */
458
+ // @ts-ignore -- trust me
464
459
  const absoluteSegment = [];
465
460
  let newSeg = [];
466
461
 
@@ -495,7 +490,7 @@ function pathToAbsolute(pathInput) {
495
490
  absoluteSegment.push(segment[j]);
496
491
  }
497
492
  }
498
- // @ts-ignore
493
+
499
494
  resultArray.push(absoluteSegment);
500
495
 
501
496
  const segLength = absoluteSegment.length;
@@ -528,7 +523,7 @@ function pathToAbsolute(pathInput) {
528
523
  * Iterates an array to check if it's a `pathArray`
529
524
  * with relative values.
530
525
  *
531
- * @param {string | SVGPC.pathArray} path the `pathArray` to be checked
526
+ * @param {string | svgpcNS.pathArray} path the `pathArray` to be checked
532
527
  * @returns {boolean} iteration result
533
528
  */
534
529
  function isRelativeArray(path) {
@@ -540,17 +535,17 @@ function isRelativeArray(path) {
540
535
  * Parses a path string value or object and returns an array
541
536
  * of segments, all converted to relative values.
542
537
  *
543
- * @param {string | SVGPC.pathArray} pathInput the path string | object
544
- * @returns {SVGPC.pathArray} the resulted `pathArray` with relative values
538
+ * @param {string | svgpcNS.pathArray} pathInput the path string | object
539
+ * @returns {svgpcNS.pathArray} the resulted `pathArray` with relative values
545
540
  */
546
541
  function pathToRelative(pathInput) {
547
- if (Array.isArray(pathInput) && isRelativeArray(pathInput)) {
542
+ if (isRelativeArray(pathInput)) {
548
543
  return clonePath(pathInput);
549
544
  }
550
545
 
551
546
  const path = parsePathString(pathInput);
552
547
  const ii = path.length;
553
- /** @type {SVGPC.pathArray} */
548
+ /** @type {svgpcNS.pathArray} */
554
549
  const resultArray = [];
555
550
  let x = 0;
556
551
  let y = 0;
@@ -571,7 +566,9 @@ function pathToRelative(pathInput) {
571
566
  const segment = path[i];
572
567
  const [pathCommand] = segment;
573
568
  const relativeCommand = pathCommand.toLowerCase();
574
- const relativeSegment = []; // this a test to please TS
569
+ /** @type {svgpcNS.pathSegment} */
570
+ // @ts-ignore -- trust me DON'T CHANGE
571
+ const relativeSegment = [];
575
572
  let newSeg = [];
576
573
 
577
574
  if (pathCommand !== relativeCommand) {
@@ -607,7 +604,6 @@ function pathToRelative(pathInput) {
607
604
  relativeSegment.push(segment[j]);
608
605
  }
609
606
  }
610
- // @ts-ignore
611
607
  resultArray.push(relativeSegment);
612
608
 
613
609
  const segLength = relativeSegment.length;
@@ -635,39 +631,54 @@ function pathToRelative(pathInput) {
635
631
  * Rounds the values of a `pathArray` instance to
636
632
  * a specified amount of decimals and returns it.
637
633
  *
638
- * @param {SVGPC.pathArray} path the source `pathArray`
639
- * @param {null | number} round the amount of decimals to round numbers to
640
- * @returns {SVGPC.pathArray} the resulted `pathArray` with rounded values
634
+ * @param {svgpcNS.pathArray} path the source `pathArray`
635
+ * @param {number | boolean | null} round the amount of decimals to round numbers to
636
+ * @returns {svgpcNS.pathArray} the resulted `pathArray` with rounded values
641
637
  */
642
638
  function roundPath(path, round) {
643
639
  const { round: defaultRound, decimals: defaultDecimals } = SVGPCO;
644
640
  const decimalsOption = round && !Number.isNaN(+round) ? +round
645
641
  : defaultRound && defaultDecimals;
646
642
 
647
- if (!decimalsOption) return clonePath(path);
643
+ if (round === false || (!defaultRound && !decimalsOption)) return clonePath(path);
648
644
 
649
- // @ts-ignore
650
- return path.map((seg) => seg.map((c) => {
651
- const nr = +c;
652
- const dc = 10 ** decimalsOption;
653
- if (!Number.isNaN(nr)) {
654
- return nr % 1 === 0 ? nr : Math.round(nr * dc) / dc;
645
+ const dc = 10 ** decimalsOption;
646
+ /** @type {svgpcNS.pathArray} */
647
+ const result = [];
648
+ const pl = path.length;
649
+ /** @type {svgpcNS.pathSegment} */
650
+ let segment;
651
+ /** @type {number} */
652
+ let n = 0;
653
+ let pi = [];
654
+
655
+ // FOR works best with TS
656
+ for (let i = 0; i < pl; i += 1) {
657
+ pi = path[i];
658
+ segment = [''];
659
+ for (let j = 0; j < pi.length; j += 1) {
660
+ if (!j) segment[j] = pi[j];
661
+ else {
662
+ n = +pi[j];
663
+ segment.push(!j || n % 1 === 0 ? n : Math.round(n * dc) / dc);
664
+ }
655
665
  }
656
- return c;
657
- }));
666
+ result.push(segment);
667
+ }
668
+ return result;
658
669
  }
659
670
 
660
671
  /**
661
672
  * Returns a valid `d` attribute string value created
662
673
  * by rounding values and concatenating the `pathArray` segments.
663
674
  *
664
- * @param {SVGPC.pathArray} path the `pathArray` object
665
- * @param {number | null} round amount of decimals to round values to
675
+ * @param {svgpcNS.pathArray} path the `pathArray` object
676
+ * @param {any} round amount of decimals to round values to
666
677
  * @returns {string} the concatenated path string
667
678
  */
668
679
  function pathToString(path, round) {
669
680
  return roundPath(path, round)
670
- .map((x) => x[0].concat(x.slice(1).join(' '))).join('');
681
+ .map((x) => x[0] + (x.slice(1).join(' '))).join('');
671
682
  }
672
683
 
673
684
  /**
@@ -707,9 +718,9 @@ function shorthandToCubic(x1, y1, x2, y2, prevCommand) {
707
718
  /**
708
719
  * Normalizes a single segment of a `pathArray` object.
709
720
  *
710
- * @param {SVGPC.pathSegment} segment the segment object
721
+ * @param {svgpcNS.pathSegment} segment the segment object
711
722
  * @param {any} params the coordinates of the previous segment
712
- * @param {String} prevCommand the path command of the previous segment
723
+ * @param {string} prevCommand the path command of the previous segment
713
724
  * @returns {any} the normalized segment
714
725
  */
715
726
  function normalizeSegment(segment, params, prevCommand) {
@@ -717,7 +728,7 @@ function normalizeSegment(segment, params, prevCommand) {
717
728
  const xy = segment.slice(1);
718
729
  let result = segment.slice();
719
730
 
720
- if ('TQ'.indexOf(segment[0]) < 0) {
731
+ if (!'TQ'.includes(segment[0])) {
721
732
  // optional but good to be cautious
722
733
  params.qx = null;
723
734
  params.qy = null;
@@ -750,7 +761,7 @@ function normalizeSegment(segment, params, prevCommand) {
750
761
  * with all segments are in non-shorthand notation
751
762
  * with absolute values.
752
763
  *
753
- * @param {string | SVGPC.pathArray} path the `pathArray` to be checked
764
+ * @param {string | svgpcNS.pathArray} path the `pathArray` to be checked
754
765
  * @returns {boolean} iteration result
755
766
  */
756
767
  function isNormalizedArray(path) {
@@ -765,8 +776,8 @@ function isNormalizedArray(path) {
765
776
  * * convert segments to absolute values
766
777
  * * convert shorthand path commands to their non-shorthand notation
767
778
  *
768
- * @param {string | SVGPC.pathArray} pathInput the string to be parsed or 'pathArray'
769
- * @returns {SVGPC.pathArray} the normalized `pathArray`
779
+ * @param {string | svgpcNS.pathArray} pathInput the string to be parsed or 'pathArray'
780
+ * @returns {svgpcNS.pathArray} the normalized `pathArray`
770
781
  */
771
782
  function normalizePath(pathInput) { // path|pathString
772
783
  if (Array.isArray(pathInput) && isNormalizedArray(pathInput)) {
@@ -779,13 +790,14 @@ function normalizePath(pathInput) { // path|pathString
779
790
  };
780
791
  const allPathCommands = [];
781
792
  const ii = path.length;
793
+ let pathCommand = '';
782
794
  let prevCommand = '';
783
795
  let segment;
784
796
  let seglen;
785
797
 
786
798
  for (let i = 0; i < ii; i += 1) {
787
799
  // save current path command
788
- const [pathCommand] = path[i];
800
+ [pathCommand] = path[i];
789
801
 
790
802
  // Save current path command
791
803
  allPathCommands[i] = pathCommand;
@@ -809,8 +821,8 @@ function normalizePath(pathInput) { // path|pathString
809
821
  * Reverses all segments and their values of a `pathArray`
810
822
  * and returns a new instance.
811
823
  *
812
- * @param {SVGPC.pathArray} pathInput the source `pathArray`
813
- * @returns {SVGPC.pathArray} the reversed `pathArray`
824
+ * @param {svgpcNS.pathArray} pathInput the source `pathArray`
825
+ * @returns {svgpcNS.pathArray} the reversed `pathArray`
814
826
  */
815
827
  function reversePath(pathInput) {
816
828
  const absolutePath = pathToAbsolute(pathInput);
@@ -899,7 +911,7 @@ function reversePath(pathInput) {
899
911
  * In the process, values are converted to absolute
900
912
  * for visual consistency.
901
913
  *
902
- * @param {SVGPC.pathArray | string} pathInput the cubic-bezier parameters
914
+ * @param {svgpcNS.pathArray | string} pathInput the cubic-bezier parameters
903
915
  * @return {string[]} an array with all sub-path strings
904
916
  */
905
917
  function splitPath(pathInput) {
@@ -916,16 +928,19 @@ function splitPath(pathInput) {
916
928
  * * create a new `pathArray` with elements with shortest segments
917
929
  * from absolute and relative `pathArray`s
918
930
  *
919
- * @param {string | SVGPC.pathArray} pathInput a string or `pathArray`
931
+ * @param {string | svgpcNS.pathArray} pathInput a string or `pathArray`
920
932
  * @param {number | null} round the amount of decimals to round values to
921
- * @returns {SVGPC.pathArray} the optimized `pathArray`
933
+ * @returns {svgpcNS.pathArray} the optimized `pathArray`
922
934
  */
923
935
  function optimizePath(pathInput, round) {
924
936
  const absolutePath = roundPath(pathToAbsolute(pathInput), round);
925
937
  const relativePath = roundPath(pathToRelative(pathInput), round);
938
+
926
939
  return absolutePath.map((x, i) => {
927
940
  if (i) {
928
- return x.join('').length < relativePath[i].join('').length ? x : relativePath[i];
941
+ return x.join('').length < relativePath[i].join('').length
942
+ ? x
943
+ : relativePath[i];
929
944
  }
930
945
  return x;
931
946
  });
@@ -934,7 +949,7 @@ function optimizePath(pathInput, round) {
934
949
  /**
935
950
  * A global namespace for epsilon.
936
951
  *
937
- * @type {Number}
952
+ * @type {number}
938
953
  */
939
954
  const epsilon = 1e-9;
940
955
 
@@ -1069,13 +1084,13 @@ function arcToCubic(X1, Y1, RX, RY, angle, LAF, SF, X2, Y2, recursive) {
1069
1084
  /**
1070
1085
  * Converts a Q (quadratic-bezier) segment to C (cubic-bezier).
1071
1086
  *
1072
- * @param {Number} x1 curve start x
1073
- * @param {Number} y1 curve start y
1074
- * @param {Number} qx control point x
1075
- * @param {Number} qy control point y
1076
- * @param {Number} x2 curve end x
1077
- * @param {Number} y2 curve end y
1078
- * @returns {Number[]} the cubic-bezier segment
1087
+ * @param {number} x1 curve start x
1088
+ * @param {number} y1 curve start y
1089
+ * @param {number} qx control point x
1090
+ * @param {number} qy control point y
1091
+ * @param {number} x2 curve end x
1092
+ * @param {number} y2 curve end y
1093
+ * @returns {number[]} the cubic-bezier segment
1079
1094
  */
1080
1095
  function quadToCubic(x1, y1, qx, qy, x2, y2) {
1081
1096
  const r13 = 1 / 3;
@@ -1150,7 +1165,7 @@ function lineToCubic(x1, y1, x2, y2) {
1150
1165
  const p4 = midPoint(p2, p3, t);
1151
1166
  const p5 = midPoint(p3, p4, t);
1152
1167
  const p6 = midPoint(p4, p5, t);
1153
- // @ts-ignore
1168
+ // @ts-ignore -- rest operator won't fix
1154
1169
  const cp1 = getPointAtSegLength.apply(0, p0.concat(p2, p4, p6, t));
1155
1170
  // @ts-ignore
1156
1171
  const cp2 = getPointAtSegLength.apply(0, p6.concat(p5, p3, p1, 0));
@@ -1161,12 +1176,12 @@ function lineToCubic(x1, y1, x2, y2) {
1161
1176
  /**
1162
1177
  * Converts any segment to C (cubic-bezier).
1163
1178
  *
1164
- * @param {SVGPC.pathSegment} segment the source segment
1165
- * @param {SVGPC.parserParams} params the source segment parameters
1166
- * @returns {SVGPC.pathSegment} the cubic-bezier segment
1179
+ * @param {svgpcNS.pathSegment} segment the source segment
1180
+ * @param {svgpcNS.parserParams} params the source segment parameters
1181
+ * @returns {svgpcNS.pathSegment} the cubic-bezier segment
1167
1182
  */
1168
1183
  function segmentToCubic(segment, params) {
1169
- if ('TQ'.indexOf(segment[0]) < 0) {
1184
+ if (!'TQ'.includes(segment[0])) {
1170
1185
  params.qx = null;
1171
1186
  params.qy = null;
1172
1187
  }
@@ -1199,7 +1214,7 @@ function segmentToCubic(segment, params) {
1199
1214
  /**
1200
1215
  * Splits an extended A (arc-to) segment into two cubic-bezier segments.
1201
1216
  *
1202
- * @param {SVGPC.pathArray} path the `pathArray` this segment belongs to
1217
+ * @param {svgpcNS.pathArray} path the `pathArray` this segment belongs to
1203
1218
  * @param {string[]} allPathCommands all previous path commands
1204
1219
  * @param {Number} i the index of the segment
1205
1220
  */
@@ -1213,23 +1228,13 @@ function fixArc(path, allPathCommands, i) {
1213
1228
  // if created multiple C:s, their original seg is saved
1214
1229
  allPathCommands[i] = 'A';
1215
1230
  // path.splice(i++, 0, ['C'].concat(segment.splice(0, 6)));
1216
- // @ts-ignore
1231
+ // @ts-ignore -- cannot fix
1217
1232
  path.splice(ni += 1, 0, ['C'].concat(segment.splice(0, 6)));
1218
1233
  }
1219
1234
  path.splice(i, 1);
1220
1235
  }
1221
1236
  }
1222
1237
 
1223
- var version$1 = "0.0.16alpha4";
1224
-
1225
- // @ts-ignore
1226
-
1227
- /**
1228
- * A global namespace for library version.
1229
- * @type {string}
1230
- */
1231
- const DMVersion = version$1;
1232
-
1233
1238
  // DOMMatrix Static methods
1234
1239
  // * `fromFloat64Array` and `fromFloat32Array` methods are not supported;
1235
1240
  // * `fromArray` a more simple implementation, should also accept float[32/64]Array;
@@ -1291,25 +1296,25 @@ function fromArray(array) {
1291
1296
  m.m34 = m34;
1292
1297
  m.m44 = m44;
1293
1298
  } else if (a.length === 6) {
1294
- const [m11, m12, m21, m22, m41, m42] = a;
1299
+ const [M11, M12, M21, M22, M41, M42] = a;
1295
1300
 
1296
- m.m11 = m11;
1297
- m.a = m11;
1301
+ m.m11 = M11;
1302
+ m.a = M11;
1298
1303
 
1299
- m.m12 = m12;
1300
- m.b = m12;
1304
+ m.m12 = M12;
1305
+ m.b = M12;
1301
1306
 
1302
- m.m21 = m21;
1303
- m.c = m21;
1307
+ m.m21 = M21;
1308
+ m.c = M21;
1304
1309
 
1305
- m.m22 = m22;
1306
- m.d = m22;
1310
+ m.m22 = M22;
1311
+ m.d = M22;
1307
1312
 
1308
- m.m41 = m41;
1309
- m.e = m41;
1313
+ m.m41 = M41;
1314
+ m.e = M41;
1310
1315
 
1311
- m.m42 = m42;
1312
- m.f = m42;
1316
+ m.m42 = M42;
1317
+ m.f = M42;
1313
1318
  } else {
1314
1319
  throw new TypeError('CSSMatrix: expecting an Array of 6/16 values.');
1315
1320
  }
@@ -1320,7 +1325,7 @@ function fromArray(array) {
1320
1325
  * Creates a new mutable `CSSMatrix` instance given an existing matrix or a
1321
1326
  * `DOMMatrix` instance which provides the values for its properties.
1322
1327
  *
1323
- * @param {CSSMatrix | DOMMatrix | DMNS.jsonMatrix} m the source matrix to feed values from.
1328
+ * @param {CSSMatrix | DOMMatrix | CSSMatrixNS.JSONMatrix} m the source matrix to feed values from.
1324
1329
  * @return {CSSMatrix} the resulted matrix.
1325
1330
  */
1326
1331
  function fromMatrix(m) {
@@ -1359,9 +1364,20 @@ function fromString(source) {
1359
1364
  }
1360
1365
  const str = String(source).replace(/\s/g, '');
1361
1366
  let m = new CSSMatrix();
1367
+ const invalidStringError = `CSSMatrix: invalid transform string "${source}"`;
1362
1368
  let is2D = true;
1369
+ // const transformFunctions = [
1370
+ // 'matrix', 'matrix3d', 'perspective', 'translate3d',
1371
+ // 'translate', 'translateX', 'translateY', 'translateZ',
1372
+ // 'rotate', 'rotate3d', 'rotateX', 'rotateY', 'rotateZ',
1373
+ // 'scale', 'scale3d', 'skewX', 'skewY'];
1363
1374
  const tramsformObject = str.split(')').filter((f) => f).map((fn) => {
1364
1375
  const [prop, value] = fn.split('(');
1376
+ if (!value) {
1377
+ // invalidate
1378
+ throw TypeError(invalidStringError);
1379
+ }
1380
+
1365
1381
  const components = value.split(',')
1366
1382
  .map((n) => (n.includes('rad') ? parseFloat(n) * (180 / Math.PI) : parseFloat(n)));
1367
1383
  const [x, y, z, a] = components;
@@ -1421,6 +1437,8 @@ function fromString(source) {
1421
1437
  // @ts-ignore unfortunately
1422
1438
  m = m[fn](...axeValues);
1423
1439
  }
1440
+ } else {
1441
+ throw TypeError(invalidStringError);
1424
1442
  }
1425
1443
  });
1426
1444
 
@@ -1711,7 +1729,7 @@ class CSSMatrix {
1711
1729
  /**
1712
1730
  * Sets a new `Boolean` flag value for `this.isIdentity` matrix property.
1713
1731
  *
1714
- * @param {Boolean} value sets a new flag for this property
1732
+ * @param {boolean} value sets a new flag for this property
1715
1733
  */
1716
1734
  set isIdentity(value) {
1717
1735
  this.isIdentity = value;
@@ -1722,7 +1740,7 @@ class CSSMatrix {
1722
1740
  * matrix is one in which every value is 0 except those on the main diagonal from top-left
1723
1741
  * to bottom-right corner (in other words, where the offsets in each direction are equal).
1724
1742
  *
1725
- * @return {Boolean} the current property value
1743
+ * @return {boolean} the current property value
1726
1744
  */
1727
1745
  get isIdentity() {
1728
1746
  const m = this;
@@ -1736,7 +1754,7 @@ class CSSMatrix {
1736
1754
  * A `Boolean` flag whose value is `true` if the matrix was initialized as a 2D matrix
1737
1755
  * and `false` if the matrix is 3D.
1738
1756
  *
1739
- * @return {Boolean} the current property value
1757
+ * @return {boolean} the current property value
1740
1758
  */
1741
1759
  get is2D() {
1742
1760
  const m = this;
@@ -1746,7 +1764,7 @@ class CSSMatrix {
1746
1764
  /**
1747
1765
  * Sets a new `Boolean` flag value for `this.is2D` matrix property.
1748
1766
  *
1749
- * @param {Boolean} value sets a new flag for this property
1767
+ * @param {boolean} value sets a new flag for this property
1750
1768
  */
1751
1769
  set is2D(value) {
1752
1770
  this.is2D = value;
@@ -1833,7 +1851,7 @@ class CSSMatrix {
1833
1851
  * The result can also be used as a second parameter for the `fromMatrix` static method
1834
1852
  * to load values into a matrix instance.
1835
1853
  *
1836
- * @return {DMNS.jsonMatrix} an *Object* with all matrix values.
1854
+ * @return {CSSMatrixNS.JSONMatrix} an *Object* with all matrix values.
1837
1855
  */
1838
1856
  toJSON() {
1839
1857
  return JSON.parse(JSON.stringify(this));
@@ -1844,7 +1862,7 @@ class CSSMatrix {
1844
1862
  * matrix multiplied by the passed matrix, with the passed matrix to the right.
1845
1863
  * This matrix is not modified.
1846
1864
  *
1847
- * @param {CSSMatrix | DOMMatrix | DMNS.jsonMatrix} m2 CSSMatrix
1865
+ * @param {CSSMatrix | DOMMatrix | CSSMatrixNS.JSONMatrix} m2 CSSMatrix
1848
1866
  * @return {CSSMatrix} The resulted matrix.
1849
1867
  */
1850
1868
  multiply(m2) {
@@ -1965,8 +1983,8 @@ class CSSMatrix {
1965
1983
  *
1966
1984
  * @copyright thednp © 2021
1967
1985
  *
1968
- * @param {DMNS.PointTuple | DOMPoint} v Tuple or DOMPoint
1969
- * @return {DMNS.PointTuple} the resulting Tuple
1986
+ * @param {CSSMatrixNS.PointTuple | DOMPoint} v Tuple or DOMPoint
1987
+ * @return {CSSMatrixNS.PointTuple} the resulting Tuple
1970
1988
  */
1971
1989
  transformPoint(v) {
1972
1990
  const M = this;
@@ -1988,8 +2006,8 @@ class CSSMatrix {
1988
2006
  * {x,y,z,w} Tuple *Object* comprising the transformed vector.
1989
2007
  * Neither the matrix nor the original vector are altered.
1990
2008
  *
1991
- * @param {DMNS.PointTuple} t Tuple with `{x,y,z,w}` components
1992
- * @return {DMNS.PointTuple} the resulting Tuple
2009
+ * @param {CSSMatrixNS.PointTuple} t Tuple with `{x,y,z,w}` components
2010
+ * @return {CSSMatrixNS.PointTuple} the resulting Tuple
1993
2011
  */
1994
2012
  transform(t) {
1995
2013
  const m = this;
@@ -2018,19 +2036,18 @@ CSSMatrix.Multiply = Multiply;
2018
2036
  CSSMatrix.fromArray = fromArray;
2019
2037
  CSSMatrix.fromMatrix = fromMatrix;
2020
2038
  CSSMatrix.fromString = fromString;
2021
- CSSMatrix.Version = DMVersion;
2022
2039
 
2023
2040
  /**
2024
2041
  * Returns a transformation matrix to apply to `<path>` elements.
2025
2042
  *
2026
- * @param {SVGPC.transformObject} transform the `transformObject`
2043
+ * @param {svgpcNS.transformObject} transform the `transformObject`
2027
2044
  * @returns {CSSMatrix} a new transformation matrix
2028
2045
  */
2029
2046
  function getSVGMatrix(transform) {
2030
2047
  let matrix = new CSSMatrix();
2031
2048
  const { origin } = transform;
2032
- const originX = +origin[0];
2033
- const originY = +origin[1];
2049
+ const originX = origin[0];
2050
+ const originY = origin[1];
2034
2051
  const { translate } = transform;
2035
2052
  const { rotate } = transform;
2036
2053
  const { skew } = transform;
@@ -2040,22 +2057,20 @@ function getSVGMatrix(transform) {
2040
2057
  if ((Array.isArray(translate) && translate.some((x) => +x !== 0)) || !Number.isNaN(translate)) {
2041
2058
  matrix = Array.isArray(translate)
2042
2059
  ? matrix.translate(+translate[0] || 0, +translate[1] || 0, +translate[2] || 0)
2043
- // @ts-ignore
2044
- : matrix.translate(+translate || 0);
2060
+ : matrix.translate(+translate || 0, 0, 0);
2045
2061
  }
2046
2062
 
2047
2063
  if (rotate || skew || scale) {
2048
2064
  // set SVG transform-origin, always defined
2049
2065
  // matrix = matrix.translate(+originX,+originY,+originZ)
2050
- // @ts-ignore
2066
+ // @ts-ignore -- SVG transform origin is always 2D
2051
2067
  matrix = matrix.translate(+originX, +originY);
2052
2068
 
2053
2069
  // set rotation
2054
2070
  if (rotate) {
2055
2071
  matrix = Array.isArray(rotate) && rotate.some((x) => +x !== 0)
2056
2072
  ? matrix.rotate(+rotate[0] || 0, +rotate[1] || 0, +rotate[2] || 0)
2057
- // @ts-ignore
2058
- : matrix.rotate(+rotate || 0);
2073
+ : matrix.rotate(0, 0, +rotate || 0);
2059
2074
  }
2060
2075
  // set skew(s)
2061
2076
  if (Array.isArray(skew) && skew.some((x) => +x !== 0)) {
@@ -2070,12 +2085,11 @@ function getSVGMatrix(transform) {
2070
2085
  if (!Number.isNaN(scale) || (Array.isArray(scale) && scale.some((x) => +x !== 1))) {
2071
2086
  matrix = Array.isArray(scale)
2072
2087
  ? (matrix.scale(+scale[0] || 1, +scale[1] || 1, +scale[2] || 1))
2073
- // @ts-ignore
2074
- : matrix.scale(+scale || 1);
2088
+ : matrix.scale(+scale || 1, +scale || 1, +scale || 1);
2075
2089
  }
2076
2090
  // set SVG transform-origin
2077
2091
  // matrix = matrix.translate(-originX,-originY,-originZ)
2078
- // @ts-ignore
2092
+ // @ts-ignore -- SVG transform origin is always 2D
2079
2093
  matrix = matrix.translate(-originX, -originY);
2080
2094
  }
2081
2095
  return matrix;
@@ -2162,7 +2176,7 @@ function transformEllipse(m, rx, ry, ax) {
2162
2176
  * Details =>
2163
2177
  * https://stackoverflow.com/questions/23792505/predicted-rendering-of-css-3d-transformed-pixel
2164
2178
  *
2165
- * @param {SVGPC.CSSMatrix} m the transformation matrix
2179
+ * @param {svgpcNS.CSSMatrix} m the transformation matrix
2166
2180
  * @param {Number[]} point2D the initial [x,y] coordinates
2167
2181
  * @param {number[]} origin the initial [x,y] coordinates
2168
2182
  * @returns {Number[]} the projected [x,y] coordinates
@@ -2190,9 +2204,9 @@ function projection2d(m, point2D, origin) {
2190
2204
  * Since *SVGElement* doesn't support 3D transformation, this function
2191
2205
  * creates a 2D projection of the <path> element.
2192
2206
  *
2193
- * @param {SVGPC.pathArray} path the `pathArray` to apply transformation
2207
+ * @param {svgpcNS.pathArray} path the `pathArray` to apply transformation
2194
2208
  * @param {any} transform the transform functions `Object`
2195
- * @returns {SVGPC.pathArray} the resulted `pathArray`
2209
+ * @returns {svgpcNS.pathArray} the resulted `pathArray`
2196
2210
  */
2197
2211
  function transformPath(path, transform) {
2198
2212
  let x = 0; let y = 0; let i; let j; let ii; let jj; let lx; let ly; let te;
@@ -2324,7 +2338,7 @@ function transformPath(path, transform) {
2324
2338
  * @param {number} c2y the second control point Y
2325
2339
  * @param {number} p2x the ending point X
2326
2340
  * @param {number} p2y the ending point Y
2327
- * @returns {SVGPC.segmentLimits} the length of the cubic-bezier segment
2341
+ * @returns {svgpcNS.segmentLimits} the length of the cubic-bezier segment
2328
2342
  */
2329
2343
  function getCubicSize(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y) {
2330
2344
  let a = (c2x - 2 * c1x + p1x) - (p2x - 2 * c2x + c1x);
@@ -2380,7 +2394,7 @@ function getCubicSize(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y) {
2380
2394
  * Iterates an array to check if it's a `pathArray`
2381
2395
  * with all C (cubic bezier) segments.
2382
2396
  *
2383
- * @param {string | SVGPC.pathArray} path the `Array` to be checked
2397
+ * @param {string | svgpcNS.pathArray} path the `Array` to be checked
2384
2398
  * @returns {boolean} iteration result
2385
2399
  */
2386
2400
  function isCurveArray(path) {
@@ -2392,11 +2406,11 @@ function isCurveArray(path) {
2392
2406
  * Parses a path string value or 'pathArray' and returns a new one
2393
2407
  * in which all segments are converted to cubic-bezier.
2394
2408
  *
2395
- * @param {string | SVGPC.pathArray} pathInput the string to be parsed or object
2396
- * @returns {SVGPC.pathArray} the resulted `pathArray` converted to cubic-bezier
2409
+ * @param {string | svgpcNS.pathArray} pathInput the string to be parsed or object
2410
+ * @returns {svgpcNS.pathArray} the resulted `pathArray` converted to cubic-bezier
2397
2411
  */
2398
2412
  function pathToCurve(pathInput) {
2399
- if (Array.isArray(pathInput) && isCurveArray(pathInput)) {
2413
+ if (isCurveArray(pathInput)) {
2400
2414
  return clonePath(pathInput);
2401
2415
  }
2402
2416
 
@@ -2404,15 +2418,15 @@ function pathToCurve(pathInput) {
2404
2418
  const params = {
2405
2419
  x1: 0, y1: 0, x2: 0, y2: 0, x: 0, y: 0, qx: null, qy: null,
2406
2420
  };
2421
+ /** @type {string[]} */
2407
2422
  const allPathCommands = [];
2408
- let pathCommand = '';
2423
+ let pathCommand = ''; // ts-lint
2409
2424
  let ii = path.length;
2410
2425
 
2411
2426
  for (let i = 0; i < ii; i += 1) {
2412
2427
  const segment = path[i];
2413
2428
  const seglen = segment.length;
2414
2429
  if (segment) [pathCommand] = segment;
2415
-
2416
2430
  allPathCommands[i] = pathCommand;
2417
2431
  path[i] = segmentToCubic(segment, params);
2418
2432
 
@@ -2431,8 +2445,8 @@ function pathToCurve(pathInput) {
2431
2445
  /**
2432
2446
  * Returns the bounding box of a shape.
2433
2447
  *
2434
- * @param {SVGPC.pathArray} path the shape `pathArray`
2435
- * @returns {SVGPC.pathBBox} the length of the cubic-bezier segment
2448
+ * @param {svgpcNS.pathArray} path the shape `pathArray`
2449
+ * @returns {svgpcNS.pathBBox} the length of the cubic-bezier segment
2436
2450
  */
2437
2451
  function getPathBBox(path) {
2438
2452
  if (!path) {
@@ -2513,7 +2527,7 @@ function getCubicSegArea(x0, y0, x1, y1, x2, y2, x3, y3) {
2513
2527
  *
2514
2528
  * => https://github.com/paperjs/paper.js/blob/develop/src/path/Path.js
2515
2529
  *
2516
- * @param {SVGPC.pathArray} path the shape `pathArray`
2530
+ * @param {svgpcNS.pathArray} path the shape `pathArray`
2517
2531
  * @returns {number} the length of the cubic-bezier segment
2518
2532
  */
2519
2533
  function getPathArea(path) {
@@ -2524,8 +2538,8 @@ function getPathArea(path) {
2524
2538
  switch (seg[0]) {
2525
2539
  case 'M':
2526
2540
  case 'Z':
2527
- mx = seg[0] === 'M' ? seg[1] : mx;
2528
- my = seg[0] === 'M' ? seg[2] : my;
2541
+ // @ts-ignore
2542
+ mx = seg[0] === 'M' ? seg[1] : mx; my = seg[0] === 'M' ? seg[2] : my;
2529
2543
  x = mx;
2530
2544
  y = my;
2531
2545
  return 0;
@@ -2597,7 +2611,7 @@ function getSegCubicLength(x1, y1, x2, y2, x3, y3, x4, y4, z) {
2597
2611
  * or the equivalent to `shape.getTotalLength()`
2598
2612
  * pathToCurve version
2599
2613
  *
2600
- * @param {SVGPC.pathArray} path the ending point Y
2614
+ * @param {svgpcNS.pathArray} path the ending point Y
2601
2615
  * @returns {number} the shape total length
2602
2616
  */
2603
2617
  function getPathLength(path) {
@@ -2614,7 +2628,7 @@ function getPathLength(path) {
2614
2628
  * Check if a path is drawn clockwise and returns true if so,
2615
2629
  * false otherwise.
2616
2630
  *
2617
- * @param {string | SVGPC.pathArray} path the path string or `pathArray`
2631
+ * @param {string | svgpcNS.pathArray} path the path string or `pathArray`
2618
2632
  * @returns {boolean} true when clockwise or false if not
2619
2633
  */
2620
2634
  function getDrawDirection(path) {
@@ -2624,7 +2638,7 @@ function getDrawDirection(path) {
2624
2638
  /**
2625
2639
  * Returns [x,y] coordinates of a point at a given length of a shape.
2626
2640
  *
2627
- * @param {string | SVGPC.pathArray} path the `pathArray` to look into
2641
+ * @param {string | svgpcNS.pathArray} path the `pathArray` to look into
2628
2642
  * @param {number} length the length of the shape to look at
2629
2643
  * @returns {number[]} the requested [x,y] coordinates
2630
2644
  */
@@ -2665,7 +2679,7 @@ function isValidPath(pathString) {
2665
2679
  return false;
2666
2680
  }
2667
2681
 
2668
- const path = new SVGPathArray(pathString);
2682
+ const path = new PathParser(pathString);
2669
2683
 
2670
2684
  skipSpaces(path);
2671
2685
 
@@ -2678,6 +2692,7 @@ function isValidPath(pathString) {
2678
2692
 
2679
2693
  /**
2680
2694
  * Supported shapes and their specific parameters.
2695
+ * @type {Object.<string, string[]>}
2681
2696
  */
2682
2697
  const shapeParams = {
2683
2698
  circle: ['cx', 'cy', 'r'],
@@ -2691,8 +2706,8 @@ const shapeParams = {
2691
2706
  /**
2692
2707
  * Returns a new `pathArray` from line attributes.
2693
2708
  *
2694
- * @param {SVGPC.lineAttr} attr shape configuration
2695
- * @return {SVGPC.pathArray} a new line `pathArray`
2709
+ * @param {svgpcNS.lineAttr} attr shape configuration
2710
+ * @return {svgpcNS.pathArray} a new line `pathArray`
2696
2711
  */
2697
2712
  function getLinePath(attr) {
2698
2713
  const {
@@ -2704,11 +2719,11 @@ function getLinePath(attr) {
2704
2719
  /**
2705
2720
  * Returns a new `pathArray` like from polyline/polygon attributes.
2706
2721
  *
2707
- * @param {SVGPC.polyAttr} attr shape configuration
2708
- * @return {SVGPC.pathArray} a new polygon/polyline `pathArray`
2722
+ * @param {svgpcNS.polyAttr} attr shape configuration
2723
+ * @return {svgpcNS.pathArray} a new polygon/polyline `pathArray`
2709
2724
  */
2710
2725
  function getPolyPath(attr) {
2711
- /** @type {SVGPC.pathArray} */
2726
+ /** @type {svgpcNS.pathArray} */
2712
2727
  const pathArray = [];
2713
2728
  const points = attr.points.split(/[\s|,]/).map(Number);
2714
2729
 
@@ -2724,8 +2739,8 @@ function getPolyPath(attr) {
2724
2739
  /**
2725
2740
  * Returns a new `pathArray` from circle attributes.
2726
2741
  *
2727
- * @param {SVGPC.circleAttr} attr shape configuration
2728
- * @return {SVGPC.pathArray} a circle `pathArray`
2742
+ * @param {svgpcNS.circleAttr} attr shape configuration
2743
+ * @return {svgpcNS.pathArray} a circle `pathArray`
2729
2744
  */
2730
2745
  function getCirclePath(attr) {
2731
2746
  const {
@@ -2742,8 +2757,8 @@ function getCirclePath(attr) {
2742
2757
  /**
2743
2758
  * Returns a new `pathArray` from ellipse attributes.
2744
2759
  *
2745
- * @param {SVGPC.ellipseAttr} attr shape configuration
2746
- * @return {SVGPC.pathArray} an ellipse `pathArray`
2760
+ * @param {svgpcNS.ellipseAttr} attr shape configuration
2761
+ * @return {svgpcNS.pathArray} an ellipse `pathArray`
2747
2762
  */
2748
2763
  function getEllipsePath(attr) {
2749
2764
  const {
@@ -2760,8 +2775,8 @@ function getEllipsePath(attr) {
2760
2775
  /**
2761
2776
  * Returns a new `pathArray` like from rect attributes.
2762
2777
  *
2763
- * @param {SVGPC.rectAttr} attr object with properties above
2764
- * @return {SVGPC.pathArray} a new `pathArray` from `<rect>` attributes
2778
+ * @param {svgpcNS.rectAttr} attr object with properties above
2779
+ * @return {svgpcNS.pathArray} a new `pathArray` from `<rect>` attributes
2765
2780
  */
2766
2781
  function getRectanglePath(attr) {
2767
2782
  const x = +attr.x || 0;
@@ -2809,7 +2824,7 @@ function getRectanglePath(attr) {
2809
2824
  * The newly created `<path>` element keeps all non-specific
2810
2825
  * attributes like `class`, `fill`, etc.
2811
2826
  *
2812
- * @param {SVGPC.shapeTypes} element target shape
2827
+ * @param {svgpcNS.shapeTypes} element target shape
2813
2828
  * @param {boolean} replace option to replace target
2814
2829
  * @return {?SVGPathElement} the newly created `<path>` element
2815
2830
  */
@@ -2822,13 +2837,13 @@ function shapeToPath(element, replace) {
2822
2837
 
2823
2838
  const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
2824
2839
  const type = element.tagName;
2825
- /** @ts-ignore */
2826
2840
  const shapeAttrs = shapeParams[type];
2827
-
2828
- // set config
2841
+ /** set config
2842
+ * @type {any}
2843
+ */
2829
2844
  const config = {};
2830
2845
  config.type = type;
2831
- /** @ts-ignore */
2846
+
2832
2847
  shapeAttrs.forEach((p) => { config[p] = element.getAttribute(p); });
2833
2848
 
2834
2849
  // set no-specific shape attributes: fill, stroke, etc
@@ -2838,16 +2853,14 @@ function shapeToPath(element, replace) {
2838
2853
 
2839
2854
  // set d
2840
2855
  let description;
2841
- /** @ts-ignore */
2842
- if (type === 'circle') description = pathToString(getCirclePath(config));
2843
- /** @ts-ignore */
2844
- else if (type === 'ellipse') description = pathToString(getEllipsePath(config));
2845
- /** @ts-ignore */
2846
- else if (['polyline', 'polygon'].includes(type)) description = pathToString(getPolyPath(config));
2847
- /** @ts-ignore */
2848
- else if (type === 'rect') description = pathToString(getRectanglePath(config));
2849
- /** @ts-ignore */
2850
- else if (type === 'line') description = pathToString(getLinePath(config));
2856
+ const { round, decimals } = SVGPCO;
2857
+ const rounding = round && decimals ? decimals : null;
2858
+
2859
+ if (type === 'circle') description = pathToString(getCirclePath(config), rounding);
2860
+ else if (type === 'ellipse') description = pathToString(getEllipsePath(config), rounding);
2861
+ else if (['polyline', 'polygon'].includes(type)) description = pathToString(getPolyPath(config), rounding);
2862
+ else if (type === 'rect') description = pathToString(getRectanglePath(config), rounding);
2863
+ else if (type === 'line') description = pathToString(getLinePath(config), rounding);
2851
2864
  else if (type === 'glyph') description = element.getAttribute('d');
2852
2865
 
2853
2866
  // replace target element
@@ -2866,8 +2879,8 @@ function shapeToPath(element, replace) {
2866
2879
  * Reverses all segments and their values from a `pathArray`
2867
2880
  * which consists of only C (cubic-bezier) path commands.
2868
2881
  *
2869
- * @param {SVGPC.pathArray} path the source `pathArray`
2870
- * @returns {SVGPC.pathArray} the reversed `pathArray`
2882
+ * @param {svgpcNS.pathArray} path the source `pathArray`
2883
+ * @returns {svgpcNS.pathArray} the reversed `pathArray`
2871
2884
  */
2872
2885
  function reverseCurve(path) {
2873
2886
  const rotatedCurve = path.slice(1)
@@ -2883,7 +2896,7 @@ function reverseCurve(path) {
2883
2896
  .concat(rotatedCurve.map((x) => ['C'].concat(x.slice(2))));
2884
2897
  }
2885
2898
 
2886
- var version = "0.1.10alpha3";
2899
+ var version = "0.1.10";
2887
2900
 
2888
2901
  // @ts-ignore
2889
2902
 
@@ -2925,8 +2938,6 @@ const Util = {
2925
2938
  Version,
2926
2939
  };
2927
2940
 
2928
- // import isPathArray from './util/isPathArray';
2929
-
2930
2941
  /**
2931
2942
  * Creates a new SVGPathCommander instance.
2932
2943
  *
@@ -2948,13 +2959,13 @@ class SVGPathCommander {
2948
2959
  round = 0;
2949
2960
  }
2950
2961
 
2951
- const { decimals } = round && (options || SVGPCO);
2962
+ const { decimals } = round ? (options || SVGPCO) : { decimals: false };
2952
2963
 
2953
2964
  // set instance options
2954
- this.round = round === 0 ? 0 : decimals;
2965
+ this.round = decimals;
2955
2966
  // ZERO | FALSE will disable rounding numbers
2956
2967
 
2957
- /** @type {SVGPC.pathArray} */
2968
+ /** @type {svgpcNS.pathArray} */
2958
2969
  this.segments = parsePathString(pathValue);
2959
2970
 
2960
2971
  /** * @type {string} */
@@ -2994,20 +3005,21 @@ class SVGPathCommander {
2994
3005
  const { segments } = this;
2995
3006
  const split = splitPath(this.toString());
2996
3007
  const subPath = split.length > 1 ? split : 0;
3008
+ /**
3009
+ * @param {svgpcNS.pathArray} x
3010
+ * @param {number} i
3011
+ */
3012
+ const reverser = (x, i) => {
3013
+ if (onlySubpath) {
3014
+ return i ? reversePath(x) : parsePathString(x);
3015
+ }
3016
+ return reversePath(x);
3017
+ };
2997
3018
 
2998
- const absoluteMultiPath = subPath && clonePath(subPath)
2999
- .map((x, i) => {
3000
- if (onlySubpath) {
3001
- // @ts-ignore
3002
- return i ? reversePath(x) : parsePathString(x);
3003
- }
3004
- // @ts-ignore
3005
- return reversePath(x);
3006
- });
3019
+ const absoluteMultiPath = subPath && clonePath(subPath).map(reverser);
3007
3020
 
3008
3021
  let path = [];
3009
3022
  if (subPath) {
3010
- // @ts-ignore
3011
3023
  path = absoluteMultiPath.flat(1);
3012
3024
  } else {
3013
3025
  path = onlySubpath ? segments : reversePath(segments);
@@ -3045,7 +3057,7 @@ class SVGPathCommander {
3045
3057
 
3046
3058
  /**
3047
3059
  * Transform path using values from an `Object` defined as `transformObject`.
3048
- * @see SVGPC.transformObject for a quick refference
3060
+ * @see svgpcNS.transformObject for a quick refference
3049
3061
  *
3050
3062
  * @param {Object.<string, (number | number[])>} source a `transformObject`as described above
3051
3063
  * @public
@@ -3061,7 +3073,7 @@ class SVGPathCommander {
3061
3073
  // it's important that we have one
3062
3074
  if (!transform.origin) {
3063
3075
  const BBox = getPathBBox(segments);
3064
- transform.origin = [BBox.cx, BBox.cy, BBox.cx];
3076
+ transform.origin = [+BBox.cx, +BBox.cy];
3065
3077
  }
3066
3078
 
3067
3079
  this.segments = transformPath(segments, transform);