@joint/core 4.1.2 → 4.2.0-alpha.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 (45) hide show
  1. package/README.md +1 -1
  2. package/dist/geometry.js +128 -123
  3. package/dist/geometry.min.js +2 -2
  4. package/dist/joint.d.ts +79 -16
  5. package/dist/joint.js +2249 -1730
  6. package/dist/joint.min.js +2 -2
  7. package/dist/joint.nowrap.js +2248 -1727
  8. package/dist/joint.nowrap.min.js +2 -2
  9. package/dist/vectorizer.js +469 -272
  10. package/dist/vectorizer.min.js +2 -2
  11. package/dist/version.mjs +1 -1
  12. package/package.json +28 -22
  13. package/src/V/create.mjs +51 -0
  14. package/src/V/index.mjs +69 -154
  15. package/src/V/namespace.mjs +9 -0
  16. package/src/V/transform.mjs +183 -0
  17. package/src/V/traverse.mjs +16 -0
  18. package/src/anchors/index.mjs +140 -33
  19. package/src/cellTools/Boundary.mjs +1 -1
  20. package/src/cellTools/Control.mjs +1 -1
  21. package/src/connectionPoints/index.mjs +24 -9
  22. package/src/connectionStrategies/index.mjs +1 -1
  23. package/src/connectors/jumpover.mjs +1 -1
  24. package/src/dia/Cell.mjs +6 -2
  25. package/src/dia/CellView.mjs +47 -39
  26. package/src/dia/Element.mjs +79 -35
  27. package/src/dia/ElementView.mjs +9 -3
  28. package/src/dia/HighlighterView.mjs +32 -11
  29. package/src/dia/Paper.mjs +134 -22
  30. package/src/dia/PaperLayer.mjs +9 -2
  31. package/src/dia/attributes/text.mjs +12 -3
  32. package/src/dia/layers/GridLayer.mjs +5 -0
  33. package/src/dia/ports.mjs +152 -39
  34. package/src/env/index.mjs +1 -1
  35. package/src/g/rect.mjs +7 -0
  36. package/src/highlighters/stroke.mjs +1 -1
  37. package/src/linkAnchors/index.mjs +2 -2
  38. package/src/linkTools/Anchor.mjs +2 -2
  39. package/src/linkTools/Vertices.mjs +4 -6
  40. package/src/mvc/Dom/methods.mjs +2 -2
  41. package/src/util/util.mjs +1 -1
  42. package/src/util/utilHelpers.mjs +2 -0
  43. package/types/geometry.d.ts +2 -0
  44. package/types/joint.d.ts +81 -20
  45. package/src/V/annotation.mjs +0 -0
@@ -1,4 +1,4 @@
1
- /*! JointJS v4.1.2 (2025-01-16) - JavaScript diagramming library
1
+ /*! JointJS v4.2.0-alpha.0 (2025-06-16) - JavaScript diagramming library
2
2
 
3
3
 
4
4
  This Source Code Form is subject to the terms of the Mozilla Public
@@ -8,14 +8,14 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
8
  (function (global, factory) {
9
9
  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
10
10
  typeof define === 'function' && define.amd ? define(factory) :
11
- (global = global || self, global.V = factory());
12
- }(this, function () { 'use strict';
11
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.V = factory());
12
+ })(this, (function () { 'use strict';
13
13
 
14
14
  // Declare shorthands to the most used math functions.
15
15
  const {
16
- round,
16
+ round: round$3,
17
17
  floor,
18
- PI
18
+ PI: PI$1
19
19
  } = Math;
20
20
  const scale = {
21
21
  // Return the `value` from the `domain` interval scaled to the `range` interval.
@@ -29,15 +29,15 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
29
29
  return angle % 360 + (angle < 0 ? 360 : 0);
30
30
  };
31
31
  const snapToGrid = function (value, gridSize) {
32
- return gridSize * round(value / gridSize);
32
+ return gridSize * round$3(value / gridSize);
33
33
  };
34
34
  const toDeg = function (rad) {
35
- return 180 * rad / PI % 360;
35
+ return 180 * rad / PI$1 % 360;
36
36
  };
37
37
  const toRad = function (deg, over360) {
38
38
  over360 = over360 || false;
39
39
  deg = over360 ? deg : deg % 360;
40
- return deg * PI / 180;
40
+ return deg * PI$1 / 180;
41
41
  };
42
42
 
43
43
  // Return a random integer from the interval [min,max], inclusive.
@@ -56,10 +56,11 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
56
56
  };
57
57
 
58
58
  // @return the bearing (cardinal direction) of the line. For example N, W, or SE.
59
+ // @returns {String} One of the following bearings : NE, E, SE, S, SW, W, NW, N.
59
60
  const {
60
- cos,
61
- sin,
62
- atan2
61
+ cos: cos$2,
62
+ sin: sin$2,
63
+ atan2: atan2$1
63
64
  } = Math;
64
65
  const bearing = function (p, q) {
65
66
  var lat1 = toRad(p.y);
@@ -67,9 +68,9 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
67
68
  var lon1 = p.x;
68
69
  var lon2 = q.x;
69
70
  var dLon = toRad(lon2 - lon1);
70
- var y = sin(dLon) * cos(lat2);
71
- var x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(dLon);
72
- var brng = toDeg(atan2(y, x));
71
+ var y = sin$2(dLon) * cos$2(lat2);
72
+ var x = cos$2(lat1) * sin$2(lat2) - sin$2(lat1) * cos$2(lat2) * cos$2(dLon);
73
+ var brng = toDeg(atan2$1(y, x));
73
74
  var bearings = ['NE', 'E', 'SE', 'S', 'SW', 'W', 'NW', 'N'];
74
75
  var index = brng - 22.5;
75
76
  if (index < 0) index += 360;
@@ -112,16 +113,16 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
112
113
  * `Point(Point(10, 20))`
113
114
  */
114
115
  const {
115
- abs,
116
+ abs: abs$2,
116
117
  cos: cos$1,
117
118
  sin: sin$1,
118
- sqrt,
119
- min,
120
- max,
121
- atan2: atan2$1,
122
- round: round$1,
123
- pow,
124
- PI: PI$1
119
+ sqrt: sqrt$2,
120
+ min: min$3,
121
+ max: max$3,
122
+ atan2,
123
+ round: round$2,
124
+ pow: pow$3,
125
+ PI
125
126
  } = Math;
126
127
  const Point = function (x, y) {
127
128
  if (!(this instanceof Point)) {
@@ -145,8 +146,8 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
145
146
  // @param {point} [optional] Origin.
146
147
  Point.fromPolar = function (distance, angle, origin) {
147
148
  origin = new Point(origin);
148
- var x = abs(distance * cos$1(angle));
149
- var y = abs(distance * sin$1(angle));
149
+ var x = abs$2(distance * cos$1(angle));
150
+ var y = abs$2(distance * sin$1(angle));
150
151
  var deg = normalizeAngle(toDeg(angle));
151
152
  if (deg < 90) {
152
153
  y = -y;
@@ -187,8 +188,8 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
187
188
  if (r.containsPoint(this)) {
188
189
  return this;
189
190
  }
190
- this.x = min(max(this.x, r.x), r.x + r.width);
191
- this.y = min(max(this.y, r.y), r.y + r.height);
191
+ this.x = min$3(max$3(this.x, r.x), r.x + r.width);
192
+ this.y = min$3(max$3(this.y, r.y), r.y + r.height);
192
193
  return this;
193
194
  },
194
195
  // Compute the angle between vector from me to p1 and the vector from me to p2.
@@ -254,11 +255,11 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
254
255
  return new Point((1 - t) * x + t * p.x, (1 - t) * y + t * p.y);
255
256
  },
256
257
  magnitude: function () {
257
- return sqrt(this.x * this.x + this.y * this.y) || 0.01;
258
+ return sqrt$2(this.x * this.x + this.y * this.y) || 0.01;
258
259
  },
259
260
  // Returns a manhattan (taxi-cab) distance between me and point `p`.
260
261
  manhattanDistance: function (p) {
261
- return abs(p.x - this.x) + abs(p.y - this.y);
262
+ return abs$2(p.x - this.x) + abs$2(p.y - this.y);
262
263
  },
263
264
  // Move point on line starting from ref ending at me by
264
265
  // distance distance.
@@ -315,12 +316,12 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
315
316
  f = 1000;
316
317
  break;
317
318
  default:
318
- f = pow(10, precision);
319
+ f = pow$3(10, precision);
319
320
  break;
320
321
  }
321
322
  }
322
- this.x = round$1(this.x * f) / f;
323
- this.y = round$1(this.y * f) / f;
323
+ this.x = round$2(this.x * f) / f;
324
+ this.y = round$2(this.y * f) / f;
324
325
  return this;
325
326
  },
326
327
  // Scale point with origin.
@@ -347,13 +348,13 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
347
348
  // Invert the y-axis.
348
349
  var y = -(p.y - this.y);
349
350
  var x = p.x - this.x;
350
- var rad = atan2$1(y, x); // defined for all 0 corner cases
351
+ var rad = atan2(y, x); // defined for all 0 corner cases
351
352
 
352
353
  // Correction for III. and IV. quadrant.
353
354
  if (rad < 0) {
354
- rad = 2 * PI$1 + rad;
355
+ rad = 2 * PI + rad;
355
356
  }
356
- return 180 * rad / PI$1;
357
+ return 180 * rad / PI;
357
358
  },
358
359
  toJSON: function () {
359
360
  return {
@@ -367,7 +368,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
367
368
  o = o && new Point(o) || new Point(0, 0);
368
369
  var x = this.x;
369
370
  var y = this.y;
370
- this.x = sqrt((x - o.x) * (x - o.x) + (y - o.y) * (y - o.y)); // r
371
+ this.x = sqrt$2((x - o.x) * (x - o.x) + (y - o.y) * (y - o.y)); // r
371
372
  this.y = toRad(o.theta(new Point(x, y)));
372
373
  return this;
373
374
  },
@@ -399,8 +400,8 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
399
400
  const point = Point;
400
401
 
401
402
  const {
402
- max: max$1,
403
- min: min$1
403
+ max: max$2,
404
+ min: min$2
404
405
  } = Math;
405
406
  const Line = function (p1, p2) {
406
407
  if (!(this instanceof Line)) {
@@ -420,10 +421,10 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
420
421
  return this.start.angleBetween(this.end, horizontalPoint);
421
422
  },
422
423
  bbox: function () {
423
- var left = min$1(this.start.x, this.end.x);
424
- var top = min$1(this.start.y, this.end.y);
425
- var right = max$1(this.start.x, this.end.x);
426
- var bottom = max$1(this.start.y, this.end.y);
424
+ var left = min$2(this.start.x, this.end.x);
425
+ var top = min$2(this.start.y, this.end.y);
426
+ var right = max$2(this.start.x, this.end.x);
427
+ var bottom = max$2(this.start.y, this.end.y);
427
428
  return new Rect(left, top, right - left, bottom - top);
428
429
  },
429
430
  // @return the bearing (cardinal direction) of the line. For example N, W, or SE.
@@ -444,7 +445,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
444
445
  // @return {number} the normalized length of the closest point on the line to point `p`
445
446
  closestPointNormalizedLength: function (p) {
446
447
  var product = this.vector().dot(new Line(this.start, p).vector());
447
- var cpNormalizedLength = min$1(1, max$1(0, product / this.squaredLength()));
448
+ var cpNormalizedLength = min$2(1, max$2(0, product / this.squaredLength()));
448
449
 
449
450
  // cpNormalizedLength returns `NaN` if this line has zero length
450
451
  // we can work with that - if `NaN`, return 0
@@ -650,8 +651,8 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
650
651
 
651
652
  const {
652
653
  sqrt: sqrt$1,
653
- round: round$2,
654
- pow: pow$1
654
+ round: round$1,
655
+ pow: pow$2
655
656
  } = Math;
656
657
  const Ellipse = function (c, a, b) {
657
658
  if (!(this instanceof Ellipse)) {
@@ -799,14 +800,14 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
799
800
  f = 1000;
800
801
  break;
801
802
  default:
802
- f = pow$1(10, precision);
803
+ f = pow$2(10, precision);
803
804
  break;
804
805
  }
805
806
  }
806
- this.x = round$2(this.x * f) / f;
807
- this.y = round$2(this.y * f) / f;
808
- this.a = round$2(this.a * f) / f;
809
- this.b = round$2(this.b * f) / f;
807
+ this.x = round$1(this.x * f) / f;
808
+ this.y = round$1(this.y * f) / f;
809
+ this.a = round$1(this.a * f) / f;
810
+ this.b = round$1(this.b * f) / f;
810
811
  return this;
811
812
  },
812
813
  /** Compute angle between tangent and x axis
@@ -844,12 +845,12 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
844
845
 
845
846
  const {
846
847
  abs: abs$1,
847
- cos: cos$2,
848
- sin: sin$2,
849
- min: min$2,
850
- max: max$2,
851
- round: round$3,
852
- pow: pow$2
848
+ cos,
849
+ sin,
850
+ min: min$1,
851
+ max: max$1,
852
+ round,
853
+ pow: pow$1
853
854
  } = Math;
854
855
  const Rect = function (x, y, w, h) {
855
856
  if (!(this instanceof Rect)) {
@@ -870,14 +871,14 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
870
871
  e = new Ellipse(e);
871
872
  return new Rect(e.x - e.a, e.y - e.b, 2 * e.a, 2 * e.b);
872
873
  };
873
- Rect.fromPointUnion = function () {
874
- if (arguments.length === 0) return null;
874
+ Rect.fromPointUnion = function (...points) {
875
+ if (points.length === 0) return null;
875
876
  const p = new Point();
876
877
  let minX, minY, maxX, maxY;
877
878
  minX = minY = Infinity;
878
879
  maxX = maxY = -Infinity;
879
- for (let i = 0; i < arguments.length; i++) {
880
- p.update(i < 0 || arguments.length <= i ? undefined : arguments[i]);
880
+ for (let i = 0; i < points.length; i++) {
881
+ p.update(points[i]);
881
882
  const x = p.x;
882
883
  const y = p.y;
883
884
  if (x < minX) minX = x;
@@ -887,14 +888,14 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
887
888
  }
888
889
  return new Rect(minX, minY, maxX - minX, maxY - minY);
889
890
  };
890
- Rect.fromRectUnion = function () {
891
- if (arguments.length === 0) return null;
891
+ Rect.fromRectUnion = function (...rects) {
892
+ if (rects.length === 0) return null;
892
893
  const r = new Rect();
893
894
  let minX, minY, maxX, maxY;
894
895
  minX = minY = Infinity;
895
896
  maxX = maxY = -Infinity;
896
- for (let i = 0; i < arguments.length; i++) {
897
- r.update(i < 0 || arguments.length <= i ? undefined : arguments[i]);
897
+ for (let i = 0; i < rects.length; i++) {
898
+ r.update(rects[i]);
898
899
  const x = r.x;
899
900
  const y = r.y;
900
901
  const mX = x + r.width;
@@ -920,8 +921,8 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
920
921
  height
921
922
  } = this;
922
923
  const theta = toRad(angle);
923
- const st = abs$1(sin$2(theta));
924
- const ct = abs$1(cos$2(theta));
924
+ const st = abs$1(sin(theta));
925
+ const ct = abs$1(cos(theta));
925
926
  const w = width * ct + height * st;
926
927
  const h = width * st + height * ct;
927
928
  this.x += (width - w) / 2;
@@ -1022,9 +1023,9 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
1022
1023
 
1023
1024
  // No intersection found
1024
1025
  if (rCorner.x <= myOrigin.x || rCorner.y <= myOrigin.y || rOrigin.x >= myCorner.x || rOrigin.y >= myCorner.y) return null;
1025
- var x = max$2(myOrigin.x, rOrigin.x);
1026
- var y = max$2(myOrigin.y, rOrigin.y);
1027
- return new Rect(x, y, min$2(myCorner.x, rCorner.x) - x, min$2(myCorner.y, rCorner.y) - y);
1026
+ var x = max$1(myOrigin.x, rOrigin.x);
1027
+ var y = max$1(myOrigin.y, rOrigin.y);
1028
+ return new Rect(x, y, min$1(myCorner.x, rCorner.x) - x, min$1(myCorner.y, rCorner.y) - y);
1028
1029
  },
1029
1030
  intersectionWithLine: function (line) {
1030
1031
  var r = this;
@@ -1115,13 +1116,13 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
1115
1116
  sy4 = (this.y + this.height - oy) / (p4.y - oy);
1116
1117
  }
1117
1118
  return {
1118
- sx: min$2(sx1, sx2, sx3, sx4),
1119
- sy: min$2(sy1, sy2, sy3, sy4)
1119
+ sx: min$1(sx1, sx2, sx3, sx4),
1120
+ sy: min$1(sy1, sy2, sy3, sy4)
1120
1121
  };
1121
1122
  },
1122
1123
  maxRectUniformScaleToFit: function (rect, origin) {
1123
1124
  var scale = this.maxRectScaleToFit(rect, origin);
1124
- return min$2(scale.sx, scale.sy);
1125
+ return min$1(scale.sx, scale.sy);
1125
1126
  },
1126
1127
  // Move and expand me.
1127
1128
  // @param r {rectangle} representing deltas
@@ -1132,6 +1133,12 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
1132
1133
  this.height += r.height || 0;
1133
1134
  return this;
1134
1135
  },
1136
+ moveAroundPoint: function (origin, angle) {
1137
+ const newCenter = this.center().rotate(origin, angle);
1138
+ this.x = newCenter.x - this.width / 2;
1139
+ this.y = newCenter.y - this.height / 2;
1140
+ return this;
1141
+ },
1135
1142
  // Normalize the rectangle; i.e., make it so that it has a non-negative width and height.
1136
1143
  // If width < 0 the function swaps the left and right corners,
1137
1144
  // and it swaps the top and bottom corners if height < 0
@@ -1203,14 +1210,14 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
1203
1210
  f = 1000;
1204
1211
  break;
1205
1212
  default:
1206
- f = pow$2(10, precision);
1213
+ f = pow$1(10, precision);
1207
1214
  break;
1208
1215
  }
1209
1216
  }
1210
- this.x = round$3(this.x * f) / f;
1211
- this.y = round$3(this.y * f) / f;
1212
- this.width = round$3(this.width * f) / f;
1213
- this.height = round$3(this.height * f) / f;
1217
+ this.x = round(this.x * f) / f;
1218
+ this.y = round(this.y * f) / f;
1219
+ this.width = round(this.width * f) / f;
1220
+ this.height = round(this.height * f) / f;
1214
1221
  return this;
1215
1222
  },
1216
1223
  // Scale rectangle with origin.
@@ -1800,8 +1807,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
1800
1807
  }
1801
1808
  return this;
1802
1809
  },
1803
- simplify: function () {
1804
- let opt = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
1810
+ simplify: function (opt = {}) {
1805
1811
  const points = this.points;
1806
1812
  if (points.length < 3) return this; // we need at least 3 points
1807
1813
 
@@ -1948,11 +1954,11 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
1948
1954
  });
1949
1955
 
1950
1956
  const {
1951
- abs: abs$2,
1952
- sqrt: sqrt$2,
1953
- min: min$3,
1954
- max: max$3,
1955
- pow: pow$3
1957
+ abs,
1958
+ sqrt,
1959
+ min,
1960
+ max,
1961
+ pow
1956
1962
  } = Math;
1957
1963
  const Curve = function (p1, p2, p3, p4) {
1958
1964
  if (!(this instanceof Curve)) {
@@ -2101,9 +2107,9 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
2101
2107
  a = -3 * y0 + 9 * y1 - 9 * y2 + 3 * y3;
2102
2108
  c = 3 * y1 - 3 * y0;
2103
2109
  }
2104
- if (abs$2(a) < 1e-12) {
2110
+ if (abs(a) < 1e-12) {
2105
2111
  // Numerical robustness
2106
- if (abs$2(b) < 1e-12) {
2112
+ if (abs(b) < 1e-12) {
2107
2113
  // Numerical robustness
2108
2114
  continue;
2109
2115
  }
@@ -2112,7 +2118,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
2112
2118
  continue;
2113
2119
  }
2114
2120
  b2ac = b * b - 4 * c * a;
2115
- sqrtb2ac = sqrt$2(b2ac);
2121
+ sqrtb2ac = sqrt(b2ac);
2116
2122
  if (b2ac < 0) continue;
2117
2123
  t1 = (-b + sqrtb2ac) / (2 * a);
2118
2124
  if (0 < t1 && t1 < 1) tvalues.push(t1);
@@ -2153,10 +2159,10 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
2153
2159
  bounds[0].length = jlen + 2;
2154
2160
  bounds[1].length = jlen + 2;
2155
2161
  points.length = jlen + 2;
2156
- var left = min$3.apply(null, bounds[0]);
2157
- var top = min$3.apply(null, bounds[1]);
2158
- var right = max$3.apply(null, bounds[0]);
2159
- var bottom = max$3.apply(null, bounds[1]);
2162
+ var left = min.apply(null, bounds[0]);
2163
+ var top = min.apply(null, bounds[1]);
2164
+ var right = max.apply(null, bounds[0]);
2165
+ var bottom = max.apply(null, bounds[1]);
2160
2166
  return new Rect(left, top, right - left, bottom - top);
2161
2167
  },
2162
2168
  clone: function () {
@@ -2230,7 +2236,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
2230
2236
  minSumDist = sumDist;
2231
2237
  }
2232
2238
  }
2233
- var precisionRatio = pow$3(10, -precision);
2239
+ var precisionRatio = pow(10, -precision);
2234
2240
 
2235
2241
  // recursively divide investigated subdivision:
2236
2242
  // until distance between baselinePoint and closest path endpoint is within 10^(-precision)
@@ -2241,8 +2247,8 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
2241
2247
  // - note that this function is not monotonic = it doesn't converge stably but has "teeth"
2242
2248
  // - the function decreases while one of the endpoints is fixed but "jumps" whenever we switch
2243
2249
  // - this criterion works well for points lying far away from the curve
2244
- var startPrecisionRatio = distFromStart ? abs$2(distFromStart - distFromEnd) / distFromStart : 0;
2245
- var endPrecisionRatio = distFromEnd ? abs$2(distFromStart - distFromEnd) / distFromEnd : 0;
2250
+ var startPrecisionRatio = distFromStart ? abs(distFromStart - distFromEnd) / distFromStart : 0;
2251
+ var endPrecisionRatio = distFromEnd ? abs(distFromStart - distFromEnd) / distFromEnd : 0;
2246
2252
  var hasRequiredPrecision = startPrecisionRatio < precisionRatio || endPrecisionRatio < precisionRatio;
2247
2253
 
2248
2254
  // check if we have reached at least one required minimal distance
@@ -2409,7 +2415,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
2409
2415
  var isPoint = !this.isDifferentiable();
2410
2416
  if (isPoint) return subdivisions;
2411
2417
  var previousLength = this.endpointDistance();
2412
- var precisionRatio = pow$3(10, -precision);
2418
+ var precisionRatio = pow(10, -precision);
2413
2419
 
2414
2420
  // special case #2: sine-like curves may have the same observed length in iteration 0 and 1 - skip iteration 1
2415
2421
  // - not a problem for further iterations because cubic curves cannot have more than two local extrema
@@ -2641,7 +2647,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
2641
2647
  // e.g. at precision 1, the length may be underestimated by up to 10% and cause this function to return 1
2642
2648
 
2643
2649
  var curveLength = this.length(localOpt);
2644
- var precisionRatio = pow$3(10, -precision);
2650
+ var precisionRatio = pow(10, -precision);
2645
2651
 
2646
2652
  // recursively divide investigated subdivision:
2647
2653
  // until distance between baselinePoint and closest path endpoint is within 10^(-precision)
@@ -2776,6 +2782,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
2776
2782
  }
2777
2783
 
2778
2784
  // Accepts path data string, array of segments, array of Curves and/or Lines, or a Polyline.
2785
+ // Path created is not guaranteed to be a valid (serializable) path (might not start with an M).
2779
2786
  const Path = function (arg) {
2780
2787
  if (!(this instanceof Path)) {
2781
2788
  return new Path(arg);
@@ -5080,8 +5087,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
5080
5087
  }
5081
5088
  });
5082
5089
  }
5083
- function _polylineWithLine(polyline, line) {
5084
- let opt = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
5090
+ function _polylineWithLine(polyline, line, opt = {}) {
5085
5091
  const {
5086
5092
  interior = false
5087
5093
  } = opt;
@@ -5114,8 +5120,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
5114
5120
  }
5115
5121
  return false;
5116
5122
  }
5117
- function _polylineWithEllipse(polyline, ellipse) {
5118
- let opt = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
5123
+ function _polylineWithEllipse(polyline, ellipse, opt = {}) {
5119
5124
  const {
5120
5125
  start,
5121
5126
  end,
@@ -5168,8 +5173,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
5168
5173
  }
5169
5174
  });
5170
5175
  }
5171
- function _polylineWithPolyline(polyline1, polyline2) {
5172
- let opt = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
5176
+ function _polylineWithPolyline(polyline1, polyline2, opt = {}) {
5173
5177
  const {
5174
5178
  interior = false
5175
5179
  } = opt;
@@ -5261,80 +5265,336 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
5261
5265
  return m[0][0] * m[1][1] * m[2][2] - m[0][0] * m[1][2] * m[2][1] - m[0][1] * m[1][0] * m[2][2] + m[0][1] * m[1][2] * m[2][0] + m[0][2] * m[1][0] * m[2][1] - m[0][2] * m[1][1] * m[2][0];
5262
5266
  }
5263
5267
 
5264
- var _intersection = ({
5268
+ var _intersection = {
5269
+ __proto__: null,
5270
+ ellipseWithEllipse: ellipseWithEllipse,
5271
+ ellipseWithLine: ellipseWithLine,
5265
5272
  exists: exists,
5266
5273
  lineWithLine: lineWithLine,
5267
- ellipseWithLine: ellipseWithLine,
5268
- ellipseWithEllipse: ellipseWithEllipse,
5269
- rectWithLine: rectWithLine,
5270
- rectWithEllipse: rectWithEllipse,
5271
- rectWithRect: rectWithRect,
5272
- polylineWithLine: polylineWithLine,
5273
- polylineWithEllipse: polylineWithEllipse,
5274
- polylineWithRect: polylineWithRect,
5275
- polylineWithPolyline: polylineWithPolyline,
5276
- polygonWithLine: polygonWithLine,
5277
- polygonWithEllipse: polygonWithEllipse,
5278
- polygonWithRect: polygonWithRect,
5279
- polygonWithPolyline: polygonWithPolyline,
5280
- polygonWithPolygon: polygonWithPolygon,
5281
- pathWithLine: pathWithLine,
5282
5274
  pathWithEllipse: pathWithEllipse,
5283
- pathWithRect: pathWithRect,
5284
- pathWithPolyline: pathWithPolyline,
5275
+ pathWithLine: pathWithLine,
5276
+ pathWithPath: pathWithPath,
5285
5277
  pathWithPolygon: pathWithPolygon,
5286
- pathWithPath: pathWithPath
5287
- });
5278
+ pathWithPolyline: pathWithPolyline,
5279
+ pathWithRect: pathWithRect,
5280
+ polygonWithEllipse: polygonWithEllipse,
5281
+ polygonWithLine: polygonWithLine,
5282
+ polygonWithPolygon: polygonWithPolygon,
5283
+ polygonWithPolyline: polygonWithPolyline,
5284
+ polygonWithRect: polygonWithRect,
5285
+ polylineWithEllipse: polylineWithEllipse,
5286
+ polylineWithLine: polylineWithLine,
5287
+ polylineWithPolyline: polylineWithPolyline,
5288
+ polylineWithRect: polylineWithRect,
5289
+ rectWithEllipse: rectWithEllipse,
5290
+ rectWithLine: rectWithLine,
5291
+ rectWithRect: rectWithRect
5292
+ };
5288
5293
 
5289
5294
  // Geometry library.
5295
+ // -----------------
5296
+
5290
5297
  const intersection = _intersection;
5291
5298
 
5292
- var g = ({
5293
- intersection: intersection,
5294
- scale: scale,
5295
- normalizeAngle: normalizeAngle,
5296
- snapToGrid: snapToGrid,
5297
- toDeg: toDeg,
5298
- toRad: toRad,
5299
- random: random,
5300
- bezier: bezier,
5299
+ var g = {
5300
+ __proto__: null,
5301
5301
  Curve: Curve,
5302
5302
  Ellipse: Ellipse,
5303
- ellipse: ellipse,
5304
5303
  Line: Line,
5305
- line: line,
5306
5304
  Path: Path,
5307
5305
  Point: Point,
5308
- point: point,
5309
- Polyline: Polyline,
5310
5306
  Polygon: Polygon,
5307
+ Polyline: Polyline,
5311
5308
  Rect: Rect,
5309
+ bezier: bezier,
5310
+ ellipse: ellipse,
5311
+ intersection: intersection,
5312
+ line: line,
5313
+ normalizeAngle: normalizeAngle,
5314
+ point: point,
5315
+ random: random,
5312
5316
  rect: rect,
5317
+ scale: scale,
5318
+ snapToGrid: snapToGrid,
5319
+ toDeg: toDeg,
5320
+ toRad: toRad,
5313
5321
  types: types
5314
- });
5322
+ };
5323
+
5324
+ const svg = 'http://www.w3.org/2000/svg';
5325
+ const xmlns = 'http://www.w3.org/2000/xmlns/';
5326
+ const xml = 'http://www.w3.org/XML/1998/namespace';
5327
+ const xlink = 'http://www.w3.org/1999/xlink';
5328
+ const xhtml = 'http://www.w3.org/1999/xhtml';
5329
+
5330
+ var ns = {
5331
+ __proto__: null,
5332
+ svg: svg,
5333
+ xhtml: xhtml,
5334
+ xlink: xlink,
5335
+ xml: xml,
5336
+ xmlns: xmlns
5337
+ };
5338
+
5339
+ /**
5340
+ * @constant {boolean}
5341
+ * @description Indicates the environment supports SVG.
5342
+ */
5343
+ const isSVGSupported = typeof window === 'object' && !!window.SVGAngle;
5344
+
5345
+ /**
5346
+ * @constant {string}
5347
+ * @description The version of the SVG document.
5348
+ */
5349
+ const SVG_VERSION = '1.1';
5350
+
5351
+ /**
5352
+ * @constant {SVGSVGElement}
5353
+ * @description The detached SVG document for various internal purposes.
5354
+ * e.g. SVGMatrix has no constructor, so the only way to create it is
5355
+ * to create an SVG document and then call `createSVGMatrix()`.
5356
+ */
5357
+ const internalSVGDocument = isSVGSupported ? createSVGDocument() : null;
5358
+
5359
+ /**
5360
+ * @constant {SVGGElement}
5361
+ * @description The detached SVG group element for various internal purposes.
5362
+ */
5363
+ const internalSVGGroup = isSVGSupported ? createSVGElement('g') : null;
5364
+
5365
+ /**
5366
+ * @returns {SVGSVGElement}
5367
+ * @description Creates an SVG document.
5368
+ */
5369
+ function createSVGDocument() {
5370
+ const svg = createSVGElement('svg');
5371
+ svg.setAttributeNS(xmlns, 'xmlns:xlink', xlink);
5372
+ svg.setAttribute('version', SVG_VERSION);
5373
+ return svg;
5374
+ }
5375
+
5376
+ /**
5377
+ * @param {string} name
5378
+ * @returns {SVGElement}
5379
+ * @description Creates an SVG element with the given name.
5380
+ */
5381
+ function createSVGElement(name) {
5382
+ return document.createElementNS(svg, name);
5383
+ }
5384
+
5385
+ /**
5386
+ * @param {SVGElement} node1
5387
+ * @param {SVGElement} node2
5388
+ * @returns {SVGElement|null}
5389
+ * @description Finds the common ancestor node of two nodes.
5390
+ */
5391
+ function getCommonAncestor(node1, node2) {
5392
+ // Find the common ancestor node of two nodes.
5393
+ let parent = node1;
5394
+ do {
5395
+ if (parent.contains(node2)) return parent;
5396
+ parent = parent.parentNode;
5397
+ } while (parent);
5398
+ return null;
5399
+ }
5400
+
5401
+ /**
5402
+ * @returns {SVGMatrix}
5403
+ * @description Creates an identity matrix.
5404
+ */
5405
+ function createIdentityMatrix() {
5406
+ return internalSVGDocument.createSVGMatrix();
5407
+ }
5408
+
5409
+ /**
5410
+ * @param {Partial<SVGMatrix>} matrixInit
5411
+ * @returns {SVGMatrix}
5412
+ * @description Creates a new SVGMatrix object.
5413
+ * If no matrix is provided, it returns the identity matrix.
5414
+ * If a matrix like object is provided, it sets the matrix values.
5415
+ */
5416
+ function createMatrix(matrixInit = {}) {
5417
+ const matrix = internalSVGDocument.createSVGMatrix();
5418
+ if (!matrixInit) return matrix;
5419
+ if ('a' in matrixInit) matrix.a = matrixInit.a;
5420
+ if ('b' in matrixInit) matrix.b = matrixInit.b;
5421
+ if ('c' in matrixInit) matrix.c = matrixInit.c;
5422
+ if ('d' in matrixInit) matrix.d = matrixInit.d;
5423
+ if ('e' in matrixInit) matrix.e = matrixInit.e;
5424
+ if ('f' in matrixInit) matrix.f = matrixInit.f;
5425
+ return matrix;
5426
+ }
5427
+
5428
+ /**
5429
+ * @returns {SVGTransform}
5430
+ * @description Creates a new SVGTransform object.
5431
+ */
5432
+ function createSVGTransform() {
5433
+ return internalSVGDocument.createSVGTransform();
5434
+ }
5435
+
5436
+ /**
5437
+ * @param {SVGElement} node
5438
+ * @returns {SVGMatrix|null}
5439
+ * @description Returns the transformation matrix of the given node.
5440
+ * If the node has no transformation, it returns null.
5441
+ */
5442
+ function getNodeMatrix(node) {
5443
+ const consolidatedTransformation = node.transform.baseVal.consolidate();
5444
+ return consolidatedTransformation ? consolidatedTransformation.matrix : null;
5445
+ }
5446
+
5447
+ /**
5448
+ * @param {string} transformString
5449
+ * @returns {SVGMatrix}
5450
+ * @description Creates a matrix from the given transform string.
5451
+ */
5452
+ function createMatrixFromTransformString(transformString) {
5453
+ internalSVGGroup.setAttribute('transform', transformString);
5454
+ return getNodeMatrix(internalSVGGroup);
5455
+ }
5456
+
5457
+ /**
5458
+ * @param {SVGElement} node
5459
+ * @param {Partial<SVGMatrix>} matrixInit
5460
+ * @param {boolean} override
5461
+ * @description Sets the transformation matrix of the given node.
5462
+ * We don't use `node.transform.baseVal` here (@see `transformNode`)
5463
+ * for the following reasons:
5464
+ * - Performance: while Chrome performs slightly better, Firefox
5465
+ * and Safari are significantly slower
5466
+ * https://www.measurethat.net/Benchmarks/Show/34447/1/overriding-svg-transform-attribute
5467
+ * - Limited support: JSDOM does not support `node.transform.baseVal`
5468
+ */
5469
+ function replaceTransformNode(node, matrixInit) {
5470
+ node.setAttribute('transform', matrixToTransformString(matrixInit));
5471
+ }
5472
+
5473
+ /**
5474
+ * @param {SVGElement} node
5475
+ * @param {Partial<SVGMatrix>} matrixInit
5476
+ * @description Applies a transformation matrix to the given node.
5477
+ * If the node already has a transformation, it appends the new transformation.
5478
+ * If the node has no transformation, it creates a new one.
5479
+ */
5480
+ function transformNode(node, matrixInit) {
5481
+ const transform = createSVGTransform();
5482
+ const matrix = isSVGMatrix(matrixInit) ? matrixInit : createMatrix(matrixInit);
5483
+ transform.setMatrix(matrix);
5484
+ node.transform.baseVal.appendItem(transform);
5485
+ }
5486
+ const MATRIX_TYPE = '[object SVGMatrix]';
5487
+
5488
+ /**
5489
+ * @param {any} obj
5490
+ * @returns {boolean}
5491
+ * @description Checks if the given object is an SVGMatrix.
5492
+ */
5493
+ function isSVGMatrix(obj) {
5494
+ return Object.prototype.toString.call(obj) === MATRIX_TYPE;
5495
+ }
5496
+
5497
+ /**
5498
+ * @param {Partial<SVGMatrix>} matrixInit
5499
+ * @returns {string}
5500
+ * @description Converts a matrix to a transform string.
5501
+ * If no matrix is provided, it returns the identity matrix string.
5502
+ */
5503
+ function matrixToTransformString(matrixInit = {}) {
5504
+ const {
5505
+ a = 1,
5506
+ b = 0,
5507
+ c = 0,
5508
+ d = 1,
5509
+ e = 0,
5510
+ f = 0
5511
+ } = matrixInit;
5512
+ return `matrix(${a},${b},${c},${d},${e},${f})`;
5513
+ }
5514
+
5515
+ /**
5516
+ *
5517
+ * @param {SVGElement} a
5518
+ * @param {SVGElement} b
5519
+ * @returns {SVGMatrix|null}
5520
+ * @description Finds the transformation matrix from `a` to `b`.
5521
+ * It requires that both elements to be visible (in the render tree)
5522
+ * in order to calculate the correct transformation matrix.
5523
+ */
5524
+ function getRelativeTransformation(a, b) {
5525
+ // Different SVG elements, no transformation possible
5526
+ // Note: SVGSVGElement has no `ownerSVGElement`
5527
+ if ((a.ownerSVGElement || a) !== (b.ownerSVGElement || b)) return null;
5528
+ // Get the transformation matrix from `a` to `b`.
5529
+ const am = b.getScreenCTM();
5530
+ if (!am) return null;
5531
+ const bm = a.getScreenCTM();
5532
+ if (!bm) return null;
5533
+ return am.inverse().multiply(bm);
5534
+ }
5535
+
5536
+ /**
5537
+ * @param {SVGElement} a
5538
+ * @param {SVGElement} b
5539
+ * @returns {SVGMatrix|null}
5540
+ * @description Finds the transformation matrix from `a` to `b`.
5541
+ * A safe way to calculate the transformation matrix between two elements.
5542
+ * It does not require the elements to be visible (in the render tree).
5543
+ */
5544
+ function getRelativeTransformationSafe(a, b) {
5545
+ if (a === b) {
5546
+ // No transformation needed
5547
+ return createIdentityMatrix();
5548
+ }
5549
+ const position = a.compareDocumentPosition(b);
5550
+ if (position & Node.DOCUMENT_POSITION_CONTAINED_BY) {
5551
+ // `b` is a descendant of `a`
5552
+ return getLinealTransformation(a, b).inverse();
5553
+ } else if (position & Node.DOCUMENT_POSITION_CONTAINS) {
5554
+ // `a` is a descendant of `b`
5555
+ return getLinealTransformation(b, a);
5556
+ }
5557
+ const c = getCommonAncestor(a, b);
5558
+ if (!c) {
5559
+ // No common ancestor
5560
+ return null;
5561
+ }
5562
+ const mca = getLinealTransformation(c, a);
5563
+ const mcb = getLinealTransformation(c, b);
5564
+ return mcb.inverse().multiply(mca);
5565
+ }
5566
+
5567
+ /**
5568
+ * @param {SVGElement} descendant
5569
+ * @param {SVGElement} ancestor
5570
+ * @returns {SVGMatrix}
5571
+ * @description Finds the transformation matrix between the `ancestor` and `descendant`.
5572
+ */
5573
+ function getLinealTransformation(ancestor, descendant) {
5574
+ const transformations = [];
5575
+ let n = descendant;
5576
+ while (n && n.nodeType === Node.ELEMENT_NODE && n !== ancestor) {
5577
+ const nm = getNodeMatrix(n);
5578
+ if (nm) {
5579
+ transformations.unshift(nm);
5580
+ }
5581
+ n = n.parentNode;
5582
+ }
5583
+ return transformations.reduce((m, t) => m.multiply(t), createIdentityMatrix());
5584
+ }
5315
5585
 
5316
5586
  // Vectorizer.
5317
- const V = function () {
5318
- var hasSvg = typeof window === 'object' && !!window.SVGAngle;
5587
+ // -----------
5319
5588
 
5589
+ const V = function () {
5320
5590
  // SVG support is required.
5321
- if (!hasSvg) {
5591
+ if (!isSVGSupported) {
5322
5592
  // Return a function that throws an error when it is used.
5323
5593
  return function () {
5324
5594
  throw new Error('SVG is required to use Vectorizer.');
5325
5595
  };
5326
5596
  }
5327
5597
 
5328
- // XML namespaces.
5329
- var ns = {
5330
- svg: 'http://www.w3.org/2000/svg',
5331
- xmlns: 'http://www.w3.org/2000/xmlns/',
5332
- xml: 'http://www.w3.org/XML/1998/namespace',
5333
- xlink: 'http://www.w3.org/1999/xlink',
5334
- xhtml: 'http://www.w3.org/1999/xhtml'
5335
- };
5336
- var SVGVersion = '1.1';
5337
-
5338
5598
  // Declare shorthands to the most used math functions.
5339
5599
  var math = Math;
5340
5600
  var PI = math.PI;
@@ -5379,7 +5639,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
5379
5639
  }
5380
5640
  el = document.importNode(svgDoc.firstChild, true);
5381
5641
  } else {
5382
- el = document.createElementNS(ns.svg, el);
5642
+ el = createSVGElement(el);
5383
5643
  }
5384
5644
  V.ensureId(el);
5385
5645
  }
@@ -5405,17 +5665,19 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
5405
5665
  * @param {SVGGElement} toElem
5406
5666
  * @returns {SVGMatrix}
5407
5667
  */
5408
- VPrototype.getTransformToElement = function (target) {
5409
- var node = this.node;
5410
- if (V.isSVGGraphicsElement(target) && V.isSVGGraphicsElement(node)) {
5411
- var targetCTM = V.toNode(target).getScreenCTM();
5412
- var nodeCTM = node.getScreenCTM();
5413
- if (targetCTM && nodeCTM) {
5414
- return targetCTM.inverse().multiply(nodeCTM);
5668
+ VPrototype.getTransformToElement = function (target, opt) {
5669
+ const node = this.node;
5670
+ const targetNode = V.toNode(target);
5671
+ let m;
5672
+ if (V.isSVGGraphicsElement(targetNode) && V.isSVGGraphicsElement(node)) {
5673
+ if (opt && opt.safe) {
5674
+ // Use the traversal method to get the transformation matrix.
5675
+ m = getRelativeTransformationSafe(node, targetNode);
5676
+ } else {
5677
+ m = getRelativeTransformation(node, targetNode);
5415
5678
  }
5416
5679
  }
5417
- // Could not get actual transformation matrix
5418
- return V.createSVGMatrix();
5680
+ return m || createIdentityMatrix();
5419
5681
  };
5420
5682
 
5421
5683
  /**
@@ -5424,15 +5686,19 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
5424
5686
  * @returns {Vectorizer|SVGMatrix} Setter / Getter
5425
5687
  */
5426
5688
  VPrototype.transform = function (matrix, opt) {
5427
- var node = this.node;
5689
+ const node = this.node;
5690
+
5691
+ // Getter
5428
5692
  if (V.isUndefined(matrix)) {
5429
- return V.transformStringToMatrix(this.attr('transform'));
5693
+ return getNodeMatrix(node) || createIdentityMatrix();
5430
5694
  }
5695
+
5696
+ // Setter
5431
5697
  if (opt && opt.absolute) {
5432
- return this.attr('transform', V.matrixToTransformString(matrix));
5698
+ replaceTransformNode(node, matrix);
5699
+ } else {
5700
+ transformNode(node, matrix);
5433
5701
  }
5434
- var svgTransform = V.createSVGTransform(matrix);
5435
- node.transform.baseVal.appendItem(svgTransform);
5436
5702
  return this;
5437
5703
  };
5438
5704
  VPrototype.translate = function (tx, ty, opt) {
@@ -5506,7 +5772,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
5506
5772
  }
5507
5773
  try {
5508
5774
  box = node.getBBox();
5509
- } catch (e) {
5775
+ } catch {
5510
5776
  // Fallback for IE.
5511
5777
  box = {
5512
5778
  x: node.clientLeft,
@@ -5552,7 +5818,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
5552
5818
  if (!options.recursive) {
5553
5819
  try {
5554
5820
  outputBBox = node.getBBox();
5555
- } catch (e) {
5821
+ } catch {
5556
5822
  // Fallback for IE.
5557
5823
  outputBBox = {
5558
5824
  x: node.clientLeft,
@@ -5790,7 +6056,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
5790
6056
  for (var i = 0, lastI = lines.length - 1; i <= lastI; i++) {
5791
6057
  var dy = lineHeight;
5792
6058
  var lineClassName = 'v-line';
5793
- var lineNode = doc.createElementNS(ns.svg, 'tspan');
6059
+ var lineNode = doc.createElementNS(svg, 'tspan');
5794
6060
  var line = lines[i];
5795
6061
  var lineMetrics;
5796
6062
  if (line) {
@@ -6104,9 +6370,9 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
6104
6370
  try {
6105
6371
  var globalPoint = p.matrixTransform(svg.getScreenCTM().inverse());
6106
6372
  var globalToLocalMatrix = this.getTransformToElement(svg).inverse();
6107
- } catch (e) {
6373
+ } catch {
6108
6374
  // IE9 throws an exception in odd cases. (`Unexpected call to method or property access`)
6109
- // We have to make do with the original coordianates.
6375
+ // We have to make do with the original coordinates.
6110
6376
  return p;
6111
6377
  }
6112
6378
  return globalPoint.matrixTransform(globalToLocalMatrix);
@@ -6160,7 +6426,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
6160
6426
  // 5. Apply transformations and the scale
6161
6427
  var transform = V.createSVGTransform();
6162
6428
  transform.setMatrix(translateFromOrigin.matrix.multiply(rotateAroundOrigin.matrix.multiply(translateToOrigin.matrix.multiply(ctm.scale(scale.sx, scale.sy)))));
6163
- this.attr('transform', V.matrixToTransformString(transform.matrix));
6429
+ this.attr('transform', matrixToTransformString(transform.matrix));
6164
6430
  return this;
6165
6431
  };
6166
6432
  VPrototype.animateAlongPath = function (attrs, path) {
@@ -6174,7 +6440,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
6174
6440
  this.append(animateMotion);
6175
6441
  try {
6176
6442
  animateMotion.node.beginElement();
6177
- } catch (e) {
6443
+ } catch {
6178
6444
  // Fallback for IE 9.
6179
6445
  // Run the animation programmatically if FakeSmile (`http://leunen.me/fakesmile/`) present
6180
6446
  if (document.documentElement.getAttribute('smiling') === 'fake') {
@@ -6437,7 +6703,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
6437
6703
  // If `content` is passed, it will be used as the SVG content of the `<svg>` root element.
6438
6704
  V.createSvgDocument = function (content) {
6439
6705
  if (content) {
6440
- const XMLString = `<svg xmlns="${ns.svg}" xmlns:xlink="${ns.xlink}" version="${SVGVersion}">${content}</svg>`;
6706
+ const XMLString = `<svg xmlns="${svg}" xmlns:xlink="${xlink}" version="${SVG_VERSION}">${content}</svg>`;
6441
6707
  const {
6442
6708
  documentElement
6443
6709
  } = V.parseXML(XMLString, {
@@ -6445,10 +6711,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
6445
6711
  });
6446
6712
  return documentElement;
6447
6713
  }
6448
- const svg = document.createElementNS(ns.svg, 'svg');
6449
- svg.setAttributeNS(ns.xmlns, 'xmlns:xlink', ns.xlink);
6450
- svg.setAttribute('version', SVGVersion);
6451
- return svg;
6714
+ return createSVGDocument();
6452
6715
  };
6453
6716
  V.createSVGStyle = function (stylesheet) {
6454
6717
  const {
@@ -6457,8 +6720,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
6457
6720
  type: 'text/css'
6458
6721
  }, [V.createCDATASection(stylesheet)]);
6459
6722
  return node;
6460
- }, V.createCDATASection = function () {
6461
- let data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
6723
+ }, V.createCDATASection = function (data = '') {
6462
6724
  const xml = document.implementation.createDocument(null, 'xml', null);
6463
6725
  return xml.createCDATASection(data);
6464
6726
  };
@@ -6503,7 +6765,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
6503
6765
  parser.async = opt.async;
6504
6766
  }
6505
6767
  xml = parser.parseFromString(data, 'text/xml');
6506
- } catch (error) {
6768
+ } catch {
6507
6769
  xml = undefined;
6508
6770
  }
6509
6771
  if (!xml || xml.getElementsByTagName('parsererror').length) {
@@ -6519,9 +6781,9 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
6519
6781
 
6520
6782
  // List of attributes for which not to split camel case words.
6521
6783
  // It contains known SVG attribute names and may be extended with user-defined attribute names.
6522
- ['baseFrequency', 'baseProfile', 'clipPathUnits', 'contentScriptType', 'contentStyleType', 'diffuseConstant', 'edgeMode', 'externalResourcesRequired', 'filterRes',
6784
+ ['attributeName', 'baseFrequency', 'baseProfile', 'clipPathUnits', 'contentScriptType', 'contentStyleType', 'diffuseConstant', 'edgeMode', 'externalResourcesRequired', 'filterRes',
6523
6785
  // deprecated
6524
- 'filterUnits', 'gradientTransform', 'gradientUnits', 'kernelMatrix', 'kernelUnitLength', 'keyPoints', 'lengthAdjust', 'limitingConeAngle', 'markerHeight', 'markerUnits', 'markerWidth', 'maskContentUnits', 'maskUnits', 'numOctaves', 'pathLength', 'patternContentUnits', 'patternTransform', 'patternUnits', 'pointsAtX', 'pointsAtY', 'pointsAtZ', 'preserveAlpha', 'preserveAspectRatio', 'primitiveUnits', 'refX', 'refY', 'requiredExtensions', 'requiredFeatures', 'specularConstant', 'specularExponent', 'spreadMethod', 'startOffset', 'stdDeviation', 'stitchTiles', 'surfaceScale', 'systemLanguage', 'tableValues', 'targetX', 'targetY', 'textLength', 'viewBox', 'viewTarget',
6786
+ 'filterUnits', 'gradientTransform', 'gradientUnits', 'kernelMatrix', 'kernelUnitLength', 'keyPoints', 'lengthAdjust', 'limitingConeAngle', 'markerHeight', 'markerUnits', 'markerWidth', 'maskContentUnits', 'maskUnits', 'numOctaves', 'pathLength', 'patternContentUnits', 'patternTransform', 'patternUnits', 'pointsAtX', 'pointsAtY', 'pointsAtZ', 'preserveAlpha', 'preserveAspectRatio', 'primitiveUnits', 'refX', 'refY', 'requiredExtensions', 'requiredFeatures', 'repeatCount', 'specularConstant', 'specularExponent', 'spreadMethod', 'startOffset', 'stdDeviation', 'stitchTiles', 'surfaceScale', 'systemLanguage', 'tableValues', 'targetX', 'targetY', 'textLength', 'viewBox', 'viewTarget',
6525
6787
  // deprecated
6526
6788
  'xChannelSelector', 'yChannelSelector', 'zoomAndPan' // deprecated
6527
6789
  ].forEach(name => _attributeNames[name] = name);
@@ -6588,86 +6850,19 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
6588
6850
  // ReDoS mitigation: Use an anchor at the beginning of the match
6589
6851
  // ReDoS mitigation: Avoid backtracking (uses `[^()]+` instead of `.*?`)
6590
6852
  // ReDoS mitigation: Don't match initial `(` inside repeated part
6591
- // The following regex needs to use /g (= cannot use capturing groups)
6592
- V.transformRegex = /\b\w+\([^()]+\)/g;
6593
6853
  // The following regexes need to use capturing groups (= cannot use /g)
6594
6854
  V.transformFunctionRegex = /\b(\w+)\(([^()]+)\)/;
6595
6855
  V.transformTranslateRegex = /\btranslate\(([^()]+)\)/;
6596
6856
  V.transformRotateRegex = /\brotate\(([^()]+)\)/;
6597
6857
  V.transformScaleRegex = /\bscale\(([^()]+)\)/;
6598
6858
  V.transformStringToMatrix = function (transform) {
6599
- // Initialize result matrix as identity matrix
6600
- let transformationMatrix = V.createSVGMatrix();
6601
-
6602
- // Note: Multiple transform functions are allowed in `transform` string
6603
- // `match()` returns `null` if none found
6604
- const transformMatches = transform && transform.match(V.transformRegex);
6605
- if (!transformMatches) {
6606
- // Return identity matrix
6607
- return transformationMatrix;
6608
- }
6609
- const numMatches = transformMatches.length;
6610
- for (let i = 0; i < numMatches; i++) {
6611
- const transformMatch = transformMatches[i];
6612
- // Use same regex as above, but with capturing groups
6613
- // `match()` returns values of capturing groups as `[1]`, `[2]`
6614
- const transformFunctionMatch = transformMatch.match(V.transformFunctionRegex);
6615
- if (transformFunctionMatch) {
6616
- let sx, sy, tx, ty, angle;
6617
- let ctm = V.createSVGMatrix();
6618
- const transformFunction = transformFunctionMatch[1].toLowerCase();
6619
- const args = transformFunctionMatch[2].split(V.transformSeparatorRegex);
6620
- switch (transformFunction) {
6621
- case 'scale':
6622
- sx = parseFloat(args[0]);
6623
- sy = args[1] === undefined ? sx : parseFloat(args[1]);
6624
- ctm = ctm.scaleNonUniform(sx, sy);
6625
- break;
6626
- case 'translate':
6627
- tx = parseFloat(args[0]);
6628
- ty = parseFloat(args[1]);
6629
- ctm = ctm.translate(tx, ty);
6630
- break;
6631
- case 'rotate':
6632
- angle = parseFloat(args[0]);
6633
- tx = parseFloat(args[1]) || 0;
6634
- ty = parseFloat(args[2]) || 0;
6635
- if (tx !== 0 || ty !== 0) {
6636
- ctm = ctm.translate(tx, ty).rotate(angle).translate(-tx, -ty);
6637
- } else {
6638
- ctm = ctm.rotate(angle);
6639
- }
6640
- break;
6641
- case 'skewx':
6642
- angle = parseFloat(args[0]);
6643
- ctm = ctm.skewX(angle);
6644
- break;
6645
- case 'skewy':
6646
- angle = parseFloat(args[0]);
6647
- ctm = ctm.skewY(angle);
6648
- break;
6649
- case 'matrix':
6650
- ctm.a = parseFloat(args[0]);
6651
- ctm.b = parseFloat(args[1]);
6652
- ctm.c = parseFloat(args[2]);
6653
- ctm.d = parseFloat(args[3]);
6654
- ctm.e = parseFloat(args[4]);
6655
- ctm.f = parseFloat(args[5]);
6656
- break;
6657
- default:
6658
- continue;
6659
- }
6660
-
6661
- // Multiply current transformation into result matrix
6662
- transformationMatrix = transformationMatrix.multiply(ctm);
6663
- }
6859
+ let matrix;
6860
+ if (V.isString(transform)) {
6861
+ matrix = createMatrixFromTransformString(transform);
6664
6862
  }
6665
- return transformationMatrix;
6666
- };
6667
- V.matrixToTransformString = function (matrix) {
6668
- matrix || (matrix = true);
6669
- return 'matrix(' + (matrix.a !== undefined ? matrix.a : 1) + ',' + (matrix.b !== undefined ? matrix.b : 0) + ',' + (matrix.c !== undefined ? matrix.c : 0) + ',' + (matrix.d !== undefined ? matrix.d : 1) + ',' + (matrix.e !== undefined ? matrix.e : 0) + ',' + (matrix.f !== undefined ? matrix.f : 0) + ')';
6863
+ return matrix || createIdentityMatrix();
6670
6864
  };
6865
+ V.matrixToTransformString = matrixToTransformString;
6671
6866
  V.parseTransformString = function (transform) {
6672
6867
  var translate, rotate, scale;
6673
6868
  if (transform) {
@@ -6825,31 +7020,24 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
6825
7020
  // IE/Edge does not implement SVGGraphicsElement interface, thus check for `getScreenCTM` below
6826
7021
  return node instanceof SVGElement && typeof node.getScreenCTM === 'function';
6827
7022
  };
6828
- var svgDocument = V('svg').node;
6829
- V.createSVGMatrix = function (matrix) {
6830
- var svgMatrix = svgDocument.createSVGMatrix();
6831
- for (var component in matrix) {
6832
- svgMatrix[component] = matrix[component];
6833
- }
6834
- return svgMatrix;
6835
- };
7023
+ V.createSVGMatrix = createMatrix;
6836
7024
  V.createSVGTransform = function (matrix) {
6837
7025
  if (!V.isUndefined(matrix)) {
6838
- if (!(matrix instanceof SVGMatrix)) {
6839
- matrix = V.createSVGMatrix(matrix);
7026
+ if (!isSVGMatrix(matrix)) {
7027
+ matrix = createMatrix(matrix);
6840
7028
  }
6841
- return svgDocument.createSVGTransformFromMatrix(matrix);
7029
+ return internalSVGDocument.createSVGTransformFromMatrix(matrix);
6842
7030
  }
6843
- return svgDocument.createSVGTransform();
7031
+ return internalSVGDocument.createSVGTransform();
6844
7032
  };
6845
7033
  V.createSVGPoint = function (x, y) {
6846
- var p = svgDocument.createSVGPoint();
7034
+ var p = internalSVGDocument.createSVGPoint();
6847
7035
  p.x = x;
6848
7036
  p.y = y;
6849
7037
  return p;
6850
7038
  };
6851
7039
  V.transformRect = function (r, matrix) {
6852
- var p = svgDocument.createSVGPoint();
7040
+ var p = internalSVGDocument.createSVGPoint();
6853
7041
  p.x = r.x;
6854
7042
  p.y = r.y;
6855
7043
  var corner1 = p.matrixTransform(matrix);
@@ -7041,7 +7229,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
7041
7229
  };
7042
7230
  V.convertLineToPathData = function (line) {
7043
7231
  line = V(line);
7044
- var d = ['M', line.attr('x1'), line.attr('y1'), 'L', line.attr('x2'), line.attr('y2')].join(' ');
7232
+ var d = ['M', line.attr('x1') || '0', line.attr('y1') || '0', 'L', line.attr('x2') || '0', line.attr('y2') || '0'].join(' ');
7045
7233
  return d;
7046
7234
  };
7047
7235
  V.convertPolygonToPathData = function (polygon) {
@@ -7451,10 +7639,6 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
7451
7639
  case 'V':
7452
7640
  path = ['L'].concat(d.x, path[1]);
7453
7641
  break;
7454
- case 'L':
7455
- break;
7456
- case 'Z':
7457
- break;
7458
7642
  }
7459
7643
  return path;
7460
7644
  }
@@ -7509,7 +7693,20 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
7509
7693
  return normalize(pathData).join(',').split(',').join(' ');
7510
7694
  };
7511
7695
  }();
7512
- V.namespace = ns;
7696
+
7697
+ /**
7698
+ *
7699
+ * @param {SVGElement|V} node1
7700
+ * @param {SVGElement|V} node2
7701
+ * @returns {SVGElement|null}
7702
+ */
7703
+ V.getCommonAncestor = function (node1, node2) {
7704
+ if (!node1 || !node2) return null;
7705
+ return getCommonAncestor(V.toNode(node1), V.toNode(node2));
7706
+ };
7707
+ V.namespace = {
7708
+ ...ns
7709
+ };
7513
7710
  V.g = g;
7514
7711
  return V;
7515
7712
  }();