pts 0.11.5 → 0.12.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.
package/dist/pts.js CHANGED
@@ -1,4 +1,4 @@
1
- /* Copyright © 2017-2023 William Ngan and contributors.
1
+ /* Copyright © 2017-2024 William Ngan and contributors.
2
2
  Licensed under Apache 2.0 License.
3
3
  See https://github.com/williamngan/pts for details. */
4
4
  (() => {
@@ -98,7 +98,7 @@ See https://github.com/williamngan/pts for details. */
98
98
  Mat: () => Mat,
99
99
  Vec: () => Vec
100
100
  });
101
- var Vec = class {
101
+ var Vec = class _Vec {
102
102
  /**
103
103
  * Add `b` to vector `a`.
104
104
  * @returns vector `a`
@@ -191,44 +191,44 @@ See https://github.com/williamngan/pts for details. */
191
191
  * Magnitude of `a`.
192
192
  */
193
193
  static magnitude(a) {
194
- return Math.sqrt(Vec.dot(a, a));
194
+ return Math.sqrt(_Vec.dot(a, a));
195
195
  }
196
196
  /**
197
197
  * Unit vector of `a`. If magnitude of `a` is already known, pass it in the second paramter to optimize calculation.
198
198
  */
199
199
  static unit(a, magnitude = void 0) {
200
- let m = magnitude === void 0 ? Vec.magnitude(a) : magnitude;
200
+ const m = magnitude === void 0 ? _Vec.magnitude(a) : magnitude;
201
201
  if (m === 0)
202
202
  return Pt.make(a.length);
203
- return Vec.divide(a, m);
203
+ return _Vec.divide(a, m);
204
204
  }
205
205
  /**
206
206
  * Set `a` to its absolute value in each dimension.
207
207
  * @returns vector `a`
208
208
  */
209
209
  static abs(a) {
210
- return Vec.map(a, Math.abs);
210
+ return _Vec.map(a, Math.abs);
211
211
  }
212
212
  /**
213
213
  * Set `a` to its floor value in each dimension.
214
214
  * @returns vector `a`
215
215
  */
216
216
  static floor(a) {
217
- return Vec.map(a, Math.floor);
217
+ return _Vec.map(a, Math.floor);
218
218
  }
219
219
  /**
220
220
  * Set `a` to its ceiling value in each dimension.
221
221
  * @returns vector `a`
222
222
  */
223
223
  static ceil(a) {
224
- return Vec.map(a, Math.ceil);
224
+ return _Vec.map(a, Math.ceil);
225
225
  }
226
226
  /**
227
227
  * Set `a` to its rounded value in each dimension.
228
228
  * @returns vector `a`
229
229
  */
230
230
  static round(a) {
231
- return Vec.map(a, Math.round);
231
+ return _Vec.map(a, Math.round);
232
232
  }
233
233
  /**
234
234
  * Find the max value within a vector's dimensions.
@@ -278,7 +278,7 @@ See https://github.com/williamngan/pts for details. */
278
278
  return a;
279
279
  }
280
280
  };
281
- var Mat = class {
281
+ var Mat = class _Mat {
282
282
  constructor() {
283
283
  this.reset();
284
284
  }
@@ -292,13 +292,13 @@ See https://github.com/williamngan/pts for details. */
292
292
  * Convert the value of its stored 3x3 matrix to a 2D [`DOMMatrix`](https://developer.mozilla.org/en-US/docs/Web/API/DOMMatrix) instance
293
293
  */
294
294
  get domMatrix() {
295
- return new DOMMatrix(Mat.toDOMMatrix(this._33));
295
+ return new DOMMatrix(_Mat.toDOMMatrix(this._33));
296
296
  }
297
297
  /**
298
298
  * Reset the internal 3x3 matrix to its identity
299
299
  */
300
300
  reset() {
301
- this._33 = Mat.scale2DMatrix(1, 1);
301
+ this._33 = _Mat.scale2DMatrix(1, 1);
302
302
  }
303
303
  /**
304
304
  * Scale the internal 3x3 matrix. You can chain this function with other related functions.
@@ -306,8 +306,8 @@ See https://github.com/williamngan/pts for details. */
306
306
  * @param at Optional origin location to scale from.
307
307
  */
308
308
  scale2D(val, at = [0, 0]) {
309
- const m = Mat.scaleAt2DMatrix(val[0] || 1, val[1] || 1, at);
310
- this._33 = Mat.multiply(this._33, m);
309
+ const m = _Mat.scaleAt2DMatrix(val[0] || 1, val[1] || 1, at);
310
+ this._33 = _Mat.multiply(this._33, m);
311
311
  return this;
312
312
  }
313
313
  /**
@@ -316,8 +316,8 @@ See https://github.com/williamngan/pts for details. */
316
316
  * @param at Optional origin location to rotate from.
317
317
  */
318
318
  rotate2D(ang, at = [0, 0]) {
319
- const m = Mat.rotateAt2DMatrix(Math.cos(ang), Math.sin(ang), at);
320
- this._33 = Mat.multiply(this._33, m);
319
+ const m = _Mat.rotateAt2DMatrix(Math.cos(ang), Math.sin(ang), at);
320
+ this._33 = _Mat.multiply(this._33, m);
321
321
  return this;
322
322
  }
323
323
  /**
@@ -325,8 +325,8 @@ See https://github.com/williamngan/pts for details. */
325
325
  * @param val [x, y] offset values
326
326
  */
327
327
  translate2D(val) {
328
- const m = Mat.translate2DMatrix(val[0] || 0, val[1] || 0);
329
- this._33 = Mat.multiply(this._33, m);
328
+ const m = _Mat.translate2DMatrix(val[0] || 0, val[1] || 0);
329
+ this._33 = _Mat.multiply(this._33, m);
330
330
  return this;
331
331
  }
332
332
  /**
@@ -335,8 +335,8 @@ See https://github.com/williamngan/pts for details. */
335
335
  * @param at Optional origin location to scale from.
336
336
  */
337
337
  shear2D(val, at = [0, 0]) {
338
- const m = Mat.shearAt2DMatrix(Math.tan(val[0] || 0), Math.tan(val[1] || 1), at);
339
- this._33 = Mat.multiply(this._33, m);
338
+ const m = _Mat.shearAt2DMatrix(Math.tan(val[0] || 0), Math.tan(val[1] || 1), at);
339
+ this._33 = _Mat.multiply(this._33, m);
340
340
  return this;
341
341
  }
342
342
  /**
@@ -352,8 +352,8 @@ See https://github.com/williamngan/pts for details. */
352
352
  if (a.length != b.length)
353
353
  throw new Error("Cannot add matrix if rows' and columns' size don't match.");
354
354
  }
355
- let g = new Group();
356
- let isNum = typeof b == "number";
355
+ const g = new Group();
356
+ const isNum = typeof b == "number";
357
357
  for (let i = 0, len = a.length; i < len; i++) {
358
358
  g.push(a[i].$add(isNum ? b : b[i]));
359
359
  }
@@ -368,7 +368,7 @@ See https://github.com/williamngan/pts for details. */
368
368
  * @returns If not elementwise, this will return a new group with M Pt, each with N dimensions (M-rows, N-columns).
369
369
  */
370
370
  static multiply(a, b, transposed = false, elementwise = false) {
371
- let g = new Group();
371
+ const g = new Group();
372
372
  if (typeof b != "number") {
373
373
  if (elementwise) {
374
374
  if (a.length != b.length)
@@ -382,9 +382,9 @@ See https://github.com/williamngan/pts for details. */
382
382
  if (transposed && a[0].length != b[0].length)
383
383
  throw new Error("Cannot multiply matrix if transposed and the columns in both matrices don't match.");
384
384
  if (!transposed)
385
- b = Mat.transpose(b);
385
+ b = _Mat.transpose(b);
386
386
  for (let ai = 0, alen = a.length; ai < alen; ai++) {
387
- let p = Pt.make(b.length, 0);
387
+ const p = Pt.make(b.length, 0);
388
388
  for (let bi = 0, blen = b.length; bi < blen; bi++) {
389
389
  p[bi] = Vec.dot(a[ai], b[bi]);
390
390
  }
@@ -405,7 +405,7 @@ See https://github.com/williamngan/pts for details. */
405
405
  * @param defaultValue a default value to fill if index out of bound. If not provided, it will throw an error instead.
406
406
  */
407
407
  static zipSlice(g, index, defaultValue = false) {
408
- let z = [];
408
+ const z = [];
409
409
  for (let i = 0, len = g.length; i < len; i++) {
410
410
  if (g[i].length - 1 < index && defaultValue === false)
411
411
  throw `Index ${index} is out of bounds`;
@@ -420,10 +420,10 @@ See https://github.com/williamngan/pts for details. */
420
420
  * @param useLongest If true, find the longest list of values in a Pt and use its length for zipping. Default is false, which uses the first item's length for zipping.
421
421
  */
422
422
  static zip(g, defaultValue = false, useLongest = false) {
423
- let ps = new Group();
424
- let len = useLongest ? g.reduce((a, b) => Math.max(a, b.length), 0) : g[0].length;
423
+ const ps = new Group();
424
+ const len = useLongest ? g.reduce((a, b) => Math.max(a, b.length), 0) : g[0].length;
425
425
  for (let i = 0; i < len; i++) {
426
- ps.push(Mat.zipSlice(g, i, defaultValue));
426
+ ps.push(_Mat.zipSlice(g, i, defaultValue));
427
427
  }
428
428
  return ps;
429
429
  }
@@ -431,7 +431,7 @@ See https://github.com/williamngan/pts for details. */
431
431
  * Same as `zip` function.
432
432
  */
433
433
  static transpose(g, defaultValue = false, useLongest = false) {
434
- return Mat.zip(g, defaultValue, useLongest);
434
+ return _Mat.zip(g, defaultValue, useLongest);
435
435
  }
436
436
  static toDOMMatrix(m) {
437
437
  return [m[0][0], m[0][1], m[1][0], m[1][1], m[2][0], m[2][1]];
@@ -443,8 +443,8 @@ See https://github.com/williamngan/pts for details. */
443
443
  * @returns a new transformed Pt
444
444
  */
445
445
  static transform2D(pt, m) {
446
- let x = pt[0] * m[0][0] + pt[1] * m[1][0] + m[2][0];
447
- let y = pt[0] * m[0][1] + pt[1] * m[1][1] + m[2][1];
446
+ const x = pt[0] * m[0][0] + pt[1] * m[1][0] + m[2][0];
447
+ const y = pt[0] * m[0][1] + pt[1] * m[1][1] + m[2][1];
448
448
  return new Pt(x, y);
449
449
  }
450
450
  /**
@@ -491,7 +491,7 @@ See https://github.com/williamngan/pts for details. */
491
491
  * Get a matrix to scale a point from an origin point. For use in `transform2D`.
492
492
  */
493
493
  static scaleAt2DMatrix(sx, sy, at) {
494
- let m = Mat.scale2DMatrix(sx, sy);
494
+ const m = _Mat.scale2DMatrix(sx, sy);
495
495
  m[2][0] = -at[0] * sx + at[0];
496
496
  m[2][1] = -at[1] * sy + at[1];
497
497
  return m;
@@ -500,7 +500,7 @@ See https://github.com/williamngan/pts for details. */
500
500
  * Get a matrix to rotate a point from an origin point. For use in `transform2D`.
501
501
  */
502
502
  static rotateAt2DMatrix(cosA, sinA, at) {
503
- let m = Mat.rotate2DMatrix(cosA, sinA);
503
+ const m = _Mat.rotate2DMatrix(cosA, sinA);
504
504
  m[2][0] = at[0] * (1 - cosA) + at[1] * sinA;
505
505
  m[2][1] = at[1] * (1 - cosA) - at[0] * sinA;
506
506
  return m;
@@ -509,7 +509,7 @@ See https://github.com/williamngan/pts for details. */
509
509
  * Get a matrix to shear a point from an origin point. For use in `transform2D`.
510
510
  */
511
511
  static shearAt2DMatrix(tanX, tanY, at) {
512
- let m = Mat.shear2DMatrix(tanX, tanY);
512
+ const m = _Mat.shear2DMatrix(tanX, tanY);
513
513
  m[2][0] = -at[1] * tanY;
514
514
  m[2][1] = -at[0] * tanX;
515
515
  return m;
@@ -520,7 +520,7 @@ See https://github.com/williamngan/pts for details. */
520
520
  * @param p1 second end point to define the reflection line
521
521
  */
522
522
  static reflectAt2DMatrix(p1, p2) {
523
- let intercept = Line.intercept(p1, p2);
523
+ const intercept = Line.intercept(p1, p2);
524
524
  if (intercept == void 0) {
525
525
  return [
526
526
  new Pt([-1, 0, 0]),
@@ -528,10 +528,10 @@ See https://github.com/williamngan/pts for details. */
528
528
  new Pt([p1[0] + p2[0], 0, 1])
529
529
  ];
530
530
  } else {
531
- let yi = intercept.yi;
532
- let ang2 = Math.atan(intercept.slope) * 2;
533
- let cosA = Math.cos(ang2);
534
- let sinA = Math.sin(ang2);
531
+ const yi = intercept.yi;
532
+ const ang2 = Math.atan(intercept.slope) * 2;
533
+ const cosA = Math.cos(ang2);
534
+ const sinA = Math.sin(ang2);
535
535
  return [
536
536
  new Pt([cosA, sinA, 0]),
537
537
  new Pt([sinA, -cosA, 0]),
@@ -544,7 +544,7 @@ See https://github.com/williamngan/pts for details. */
544
544
  // src/Op.ts
545
545
  var _errorLength = (obj, param = "expected") => Util.warn("Group's length is less than " + param, obj);
546
546
  var _errorOutofBound = (obj, param = "") => Util.warn(`Index ${param} is out of bound in Group`, obj);
547
- var Line = class {
547
+ var Line = class _Line {
548
548
  /**
549
549
  * Create a line that originates from an anchor point, given an angle and a magnitude.
550
550
  * @param anchor an anchor Pt
@@ -642,7 +642,7 @@ See https://github.com/williamngan/pts for details. */
642
642
  */
643
643
  static distanceFromPt(line, pt) {
644
644
  let _line = Util.iterToArray(line);
645
- let projectionVector = Line.perpendicularFromPt(_line, pt, true);
645
+ let projectionVector = _Line.perpendicularFromPt(_line, pt, true);
646
646
  if (projectionVector) {
647
647
  return projectionVector.magnitude();
648
648
  } else {
@@ -658,8 +658,8 @@ See https://github.com/williamngan/pts for details. */
658
658
  static intersectRay2D(la, lb) {
659
659
  let _la = Util.iterToArray(la);
660
660
  let _lb = Util.iterToArray(lb);
661
- let a = Line.intercept(_la[0], _la[1]);
662
- let b = Line.intercept(_lb[0], _lb[1]);
661
+ let a = _Line.intercept(_la[0], _la[1]);
662
+ let b = _Line.intercept(_lb[0], _lb[1]);
663
663
  let pa = _la[0];
664
664
  let pb = _lb[0];
665
665
  if (a == void 0) {
@@ -693,7 +693,7 @@ See https://github.com/williamngan/pts for details. */
693
693
  static intersectLine2D(la, lb) {
694
694
  let _la = Util.iterToArray(la);
695
695
  let _lb = Util.iterToArray(lb);
696
- let pt = Line.intersectRay2D(_la, _lb);
696
+ let pt = _Line.intersectRay2D(_la, _lb);
697
697
  return pt && Geom.withinBound(pt, _la[0], _la[1]) && Geom.withinBound(pt, _lb[0], _lb[1]) ? pt : void 0;
698
698
  }
699
699
  /**
@@ -705,7 +705,7 @@ See https://github.com/williamngan/pts for details. */
705
705
  static intersectLineWithRay2D(line, ray) {
706
706
  let _line = Util.iterToArray(line);
707
707
  let _ray = Util.iterToArray(ray);
708
- let pt = Line.intersectRay2D(_line, _ray);
708
+ let pt = _Line.intersectRay2D(_line, _ray);
709
709
  return pt && Geom.withinBound(pt, _line[0], _line[1]) ? pt : void 0;
710
710
  }
711
711
  /**
@@ -717,7 +717,7 @@ See https://github.com/williamngan/pts for details. */
717
717
  static intersectPolygon2D(lineOrRay, poly, sourceIsRay = false) {
718
718
  let _lineOrRay = Util.iterToArray(lineOrRay);
719
719
  let _poly = Util.iterToArray(poly);
720
- let fn = sourceIsRay ? Line.intersectLineWithRay2D : Line.intersectLine2D;
720
+ let fn = sourceIsRay ? _Line.intersectLineWithRay2D : _Line.intersectLine2D;
721
721
  let pts = new Group();
722
722
  for (let i = 0, len = _poly.length; i < len; i++) {
723
723
  let next = i === len - 1 ? 0 : i + 1;
@@ -735,7 +735,7 @@ See https://github.com/williamngan/pts for details. */
735
735
  */
736
736
  static intersectLines2D(lines1, lines2, isRay = false) {
737
737
  let group = new Group();
738
- let fn = isRay ? Line.intersectLineWithRay2D : Line.intersectLine2D;
738
+ let fn = isRay ? _Line.intersectLineWithRay2D : _Line.intersectLine2D;
739
739
  for (let l1 of lines1) {
740
740
  for (let l2 of lines2) {
741
741
  let _ip = fn(l1, l2);
@@ -753,7 +753,7 @@ See https://github.com/williamngan/pts for details. */
753
753
  */
754
754
  static intersectGridWithRay2D(ray, gridPt) {
755
755
  let _ray = Util.iterToArray(ray);
756
- let t = Line.intercept(new Pt(_ray[0]).subtract(gridPt), new Pt(_ray[1]).subtract(gridPt));
756
+ let t = _Line.intercept(new Pt(_ray[0]).subtract(gridPt), new Pt(_ray[1]).subtract(gridPt));
757
757
  let g = new Group();
758
758
  if (t && t.xi)
759
759
  g.push(new Pt(gridPt[0] + t.xi, gridPt[1]));
@@ -769,7 +769,7 @@ See https://github.com/williamngan/pts for details. */
769
769
  */
770
770
  static intersectGridWithLine2D(line, gridPt) {
771
771
  let _line = Util.iterToArray(line);
772
- let g = Line.intersectGridWithRay2D(_line, gridPt);
772
+ let g = _Line.intersectGridWithRay2D(_line, gridPt);
773
773
  let gg = new Group();
774
774
  for (let i = 0, len = g.length; i < len; i++) {
775
775
  if (Geom.withinBound(g[i], _line[0], _line[1]))
@@ -789,7 +789,7 @@ See https://github.com/williamngan/pts for details. */
789
789
  let box = Geom.boundingBox(Group.fromPtArray(_line));
790
790
  if (!Rectangle.hasIntersectRect2D(box, _rect))
791
791
  return new Group();
792
- return Line.intersectLines2D([_line], Rectangle.sides(_rect));
792
+ return _Line.intersectLines2D([_line], Rectangle.sides(_rect));
793
793
  }
794
794
  /**
795
795
  * Get evenly distributed points on a line. Similar to [`Create.distributeLinear`](#link) but excluding end points.
@@ -830,7 +830,7 @@ See https://github.com/williamngan/pts for details. */
830
830
  } else {
831
831
  sideIdx = ls[0] < 0 ? 3 : 1;
832
832
  }
833
- return Line.intersectRay2D(sides[sideIdx], _line);
833
+ return _Line.intersectRay2D(sides[sideIdx], _line);
834
834
  }
835
835
  }
836
836
  /**
@@ -866,7 +866,7 @@ See https://github.com/williamngan/pts for details. */
866
866
  return new Group(_line[0].$min(_line[1]), _line[0].$max(_line[1]));
867
867
  }
868
868
  };
869
- var Rectangle = class {
869
+ var Rectangle = class _Rectangle {
870
870
  /**
871
871
  * Create a rectangle from top-left anchor point. Same as [`Rectangle.fromTopLeft`](#link).
872
872
  * @param topLeft top-left point
@@ -875,7 +875,7 @@ See https://github.com/williamngan/pts for details. */
875
875
  * @returns a Group of 2 Pts representing a rectangle
876
876
  */
877
877
  static from(topLeft, widthOrSize, height) {
878
- return Rectangle.fromTopLeft(topLeft, widthOrSize, height);
878
+ return _Rectangle.fromTopLeft(topLeft, widthOrSize, height);
879
879
  }
880
880
  /**
881
881
  * Create a rectangle given a top-left position and a size.
@@ -916,9 +916,9 @@ See https://github.com/williamngan/pts for details. */
916
916
  */
917
917
  static toSquare(pts, enclose = false) {
918
918
  let _pts = Util.iterToArray(pts);
919
- let s = Rectangle.size(_pts);
919
+ let s = _Rectangle.size(_pts);
920
920
  let m = enclose ? s.maxValue().value : s.minValue().value;
921
- return Rectangle.fromCenter(Rectangle.center(_pts), m, m);
921
+ return _Rectangle.fromCenter(_Rectangle.center(_pts), m, m);
922
922
  }
923
923
  /**
924
924
  * Get the size of this rectangle as a Pt.
@@ -954,7 +954,7 @@ See https://github.com/williamngan/pts for details. */
954
954
  * @returns an array of 4 Groups, each of which represents a line segment
955
955
  */
956
956
  static sides(rect) {
957
- let [p0, p1, p2, p3] = Rectangle.corners(rect);
957
+ let [p0, p1, p2, p3] = _Rectangle.corners(rect);
958
958
  return [
959
959
  new Group(p0, p1),
960
960
  new Group(p1, p2),
@@ -988,7 +988,7 @@ See https://github.com/williamngan/pts for details. */
988
988
  * @param rect a Group or an Iterable<Pt> with 2 Pt representing a Rectangle
989
989
  */
990
990
  static polygon(rect) {
991
- return Rectangle.corners(rect);
991
+ return _Rectangle.corners(rect);
992
992
  }
993
993
  /**
994
994
  * Subdivide a rectangle into 4 rectangles, one for each quadrant.
@@ -997,8 +997,8 @@ See https://github.com/williamngan/pts for details. */
997
997
  */
998
998
  static quadrants(rect, center) {
999
999
  let _rect = Util.iterToArray(rect);
1000
- let corners = Rectangle.corners(_rect);
1001
- let _center = center != void 0 ? new Pt(center) : Rectangle.center(_rect);
1000
+ let corners = _Rectangle.corners(_rect);
1001
+ let _center = center != void 0 ? new Pt(center) : _Rectangle.center(_rect);
1002
1002
  return corners.map((c) => new Group(c, _center).boundingBox());
1003
1003
  }
1004
1004
  /**
@@ -1051,12 +1051,12 @@ See https://github.com/williamngan/pts for details. */
1051
1051
  static intersectRect2D(rect1, rect2) {
1052
1052
  let _rect1 = Util.iterToArray(rect1);
1053
1053
  let _rect2 = Util.iterToArray(rect2);
1054
- if (!Rectangle.hasIntersectRect2D(_rect1, _rect2))
1054
+ if (!_Rectangle.hasIntersectRect2D(_rect1, _rect2))
1055
1055
  return new Group();
1056
- return Line.intersectLines2D(Rectangle.sides(_rect1), Rectangle.sides(_rect2));
1056
+ return Line.intersectLines2D(_Rectangle.sides(_rect1), _Rectangle.sides(_rect2));
1057
1057
  }
1058
1058
  };
1059
- var Circle = class {
1059
+ var Circle = class _Circle {
1060
1060
  /**
1061
1061
  * Create a circle that either fits within, or encloses, a rectangle.
1062
1062
  * @param pts a Group or an Iterable<PtLike> with 2 Pt representing a rectangle
@@ -1147,7 +1147,7 @@ See https://github.com/williamngan/pts for details. */
1147
1147
  static intersectLine2D(circle, line) {
1148
1148
  let _pts = Util.iterToArray(circle);
1149
1149
  let _line = Util.iterToArray(line);
1150
- let ps = Circle.intersectRay2D(_pts, _line);
1150
+ let ps = _Circle.intersectRay2D(_pts, _line);
1151
1151
  let g = new Group();
1152
1152
  if (ps.length > 0) {
1153
1153
  for (let i = 0, len = ps.length; i < len; i++) {
@@ -1200,7 +1200,7 @@ See https://github.com/williamngan/pts for details. */
1200
1200
  let sides = Rectangle.sides(_rect);
1201
1201
  let g = [];
1202
1202
  for (let i = 0, len = sides.length; i < len; i++) {
1203
- let ps = Circle.intersectLine2D(_pts, sides[i]);
1203
+ let ps = _Circle.intersectLine2D(_pts, sides[i]);
1204
1204
  if (ps.length > 0)
1205
1205
  g.push(ps);
1206
1206
  }
@@ -1243,7 +1243,7 @@ See https://github.com/williamngan/pts for details. */
1243
1243
  }
1244
1244
  }
1245
1245
  };
1246
- var Triangle = class {
1246
+ var Triangle = class _Triangle {
1247
1247
  /**
1248
1248
  * Create a triangle from a rectangle. The triangle will be isosceles, with the bottom of the rectangle as its base.
1249
1249
  * @param rect a Group or an Iterable<Pt> with 2 Pt representing a rectangle
@@ -1269,7 +1269,7 @@ See https://github.com/williamngan/pts for details. */
1269
1269
  * @param size size is the magnitude of lines from center to the triangle's vertices, like a "radius".
1270
1270
  */
1271
1271
  static fromCenter(pt, size) {
1272
- return Triangle.fromCircle(Circle.fromCenter(pt, size));
1272
+ return _Triangle.fromCircle(Circle.fromCenter(pt, size));
1273
1273
  }
1274
1274
  /**
1275
1275
  * Get the medial, which is an inner triangle formed by connecting the midpoints of this triangle's sides.
@@ -1308,7 +1308,7 @@ See https://github.com/williamngan/pts for details. */
1308
1308
  */
1309
1309
  static altitude(tri, index) {
1310
1310
  let _pts = Util.iterToArray(tri);
1311
- let opp = Triangle.oppositeSide(_pts, index);
1311
+ let opp = _Triangle.oppositeSide(_pts, index);
1312
1312
  if (opp.length > 1) {
1313
1313
  return new Group(_pts[index], Line.perpendicularFromPt(opp, _pts[index]));
1314
1314
  } else {
@@ -1324,8 +1324,8 @@ See https://github.com/williamngan/pts for details. */
1324
1324
  let _pts = Util.iterToArray(tri);
1325
1325
  if (_pts.length < 3)
1326
1326
  return _errorLength(void 0, 3);
1327
- let a = Triangle.altitude(_pts, 0);
1328
- let b = Triangle.altitude(_pts, 1);
1327
+ let a = _Triangle.altitude(_pts, 0);
1328
+ let b = _Triangle.altitude(_pts, 1);
1329
1329
  return Line.intersectRay2D(a, b);
1330
1330
  }
1331
1331
  /**
@@ -1348,7 +1348,7 @@ See https://github.com/williamngan/pts for details. */
1348
1348
  */
1349
1349
  static incircle(tri, center) {
1350
1350
  let _pts = Util.iterToArray(tri);
1351
- let c = center ? center : Triangle.incenter(_pts);
1351
+ let c = center ? center : _Triangle.incenter(_pts);
1352
1352
  let area = Polygon.area(_pts);
1353
1353
  let perim = Polygon.perimeter(_pts, true);
1354
1354
  let r = 2 * area / perim.total;
@@ -1361,7 +1361,7 @@ See https://github.com/williamngan/pts for details. */
1361
1361
  */
1362
1362
  static circumcenter(tri) {
1363
1363
  let _pts = Util.iterToArray(tri);
1364
- let md = Triangle.medial(_pts);
1364
+ let md = _Triangle.medial(_pts);
1365
1365
  let a = [md[0], Geom.perpendicular(_pts[0].$subtract(md[0])).p1.$add(md[0])];
1366
1366
  let b = [md[1], Geom.perpendicular(_pts[1].$subtract(md[1])).p1.$add(md[1])];
1367
1367
  return Line.intersectRay2D(a, b);
@@ -1373,12 +1373,12 @@ See https://github.com/williamngan/pts for details. */
1373
1373
  */
1374
1374
  static circumcircle(tri, center) {
1375
1375
  let _pts = Util.iterToArray(tri);
1376
- let c = center ? center : Triangle.circumcenter(_pts);
1376
+ let c = center ? center : _Triangle.circumcenter(_pts);
1377
1377
  let r = _pts[0].$subtract(c).magnitude();
1378
1378
  return Circle.fromCenter(c, r);
1379
1379
  }
1380
1380
  };
1381
- var Polygon = class {
1381
+ var Polygon = class _Polygon {
1382
1382
  /**
1383
1383
  * Get the centroid of a polygon, which is the average of all its points.
1384
1384
  * @param pts a Group or an Iterable<PtLike> representing a polygon
@@ -1442,7 +1442,7 @@ See https://github.com/williamngan/pts for details. */
1442
1442
  * @param t a value between 0 to 1 for interpolation. Default to 0.5 which will get the middle point.
1443
1443
  */
1444
1444
  static midpoints(poly, closePath = false, t = 0.5) {
1445
- let sides = Polygon.lines(poly, closePath);
1445
+ let sides = _Polygon.lines(poly, closePath);
1446
1446
  let mids = sides.map((s) => Geom.interpolate(s[0], s[1], t));
1447
1447
  return mids;
1448
1448
  }
@@ -1479,7 +1479,7 @@ See https://github.com/williamngan/pts for details. */
1479
1479
  * @returns a bisector Pt that's a normalized unit vector
1480
1480
  */
1481
1481
  static bisector(poly, index) {
1482
- let sides = Polygon.adjacentSides(poly, index, true);
1482
+ let sides = _Polygon.adjacentSides(poly, index, true);
1483
1483
  if (sides.length >= 2) {
1484
1484
  let a = sides[0][1].$subtract(sides[0][0]).unit();
1485
1485
  let b = sides[1][1].$subtract(sides[1][0]).unit();
@@ -1495,7 +1495,7 @@ See https://github.com/williamngan/pts for details. */
1495
1495
  * @returns an object with `total` length, and `segments` which is a Pt that stores each segment's length
1496
1496
  */
1497
1497
  static perimeter(poly, closePath = false) {
1498
- let lines = Polygon.lines(poly, closePath);
1498
+ let lines = _Polygon.lines(poly, closePath);
1499
1499
  let mag = 0;
1500
1500
  let p = Pt.make(lines.length, 0);
1501
1501
  for (let i = 0, len = lines.length; i < len; i++) {
@@ -1635,8 +1635,8 @@ See https://github.com/williamngan/pts for details. */
1635
1635
  * @param unitAxis unit axis
1636
1636
  */
1637
1637
  static _axisOverlap(poly1, poly2, unitAxis) {
1638
- let pa = Polygon.projectAxis(poly1, unitAxis);
1639
- let pb = Polygon.projectAxis(poly2, unitAxis);
1638
+ let pa = _Polygon.projectAxis(poly1, unitAxis);
1639
+ let pb = _Polygon.projectAxis(poly2, unitAxis);
1640
1640
  return pa[0] < pb[0] ? pb[0] - pa[1] : pa[0] - pb[1];
1641
1641
  }
1642
1642
  /**
@@ -1648,7 +1648,7 @@ See https://github.com/williamngan/pts for details. */
1648
1648
  let _poly = Util.iterToArray(poly);
1649
1649
  let c = false;
1650
1650
  for (let i = 0, len = _poly.length; i < len; i++) {
1651
- let ln = Polygon.lineAt(_poly, i);
1651
+ let ln = _Polygon.lineAt(_poly, i);
1652
1652
  if (ln[0][1] > pt[1] != ln[1][1] > pt[1] && pt[0] < (ln[1][0] - ln[0][0]) * (pt[1] - ln[0][1]) / (ln[1][1] - ln[0][1]) + ln[0][0]) {
1653
1653
  c = !c;
1654
1654
  }
@@ -1679,10 +1679,10 @@ See https://github.com/williamngan/pts for details. */
1679
1679
  let r = _circle[1][0];
1680
1680
  let minDist = Number.MAX_SAFE_INTEGER;
1681
1681
  for (let i = 0, len = _poly.length; i < len; i++) {
1682
- let edge = Polygon.lineAt(_poly, i);
1682
+ let edge = _Polygon.lineAt(_poly, i);
1683
1683
  let axis = new Pt(edge[0].y - edge[1].y, edge[1].x - edge[0].x).unit();
1684
1684
  let poly2 = new Group(c.$add(axis.$multiply(r)), c.$subtract(axis.$multiply(r)));
1685
- let dist = Polygon._axisOverlap(_poly, poly2, axis);
1685
+ let dist = _Polygon._axisOverlap(_poly, poly2, axis);
1686
1686
  if (dist > 0) {
1687
1687
  return null;
1688
1688
  } else if (Math.abs(dist) < minDist) {
@@ -1697,7 +1697,7 @@ See https://github.com/williamngan/pts for details. */
1697
1697
  }
1698
1698
  if (!info.edge)
1699
1699
  return null;
1700
- let dir = c.$subtract(Polygon.centroid(_poly)).dot(info.normal);
1700
+ let dir = c.$subtract(_Polygon.centroid(_poly)).dot(info.normal);
1701
1701
  if (dir < 0)
1702
1702
  info.normal.multiply(-1);
1703
1703
  info.dist = minDist;
@@ -1726,9 +1726,9 @@ See https://github.com/williamngan/pts for details. */
1726
1726
  };
1727
1727
  let minDist = Number.MAX_SAFE_INTEGER;
1728
1728
  for (let i = 0, plen = _poly1.length + _poly2.length; i < plen; i++) {
1729
- let edge = i < _poly1.length ? Polygon.lineAt(_poly1, i) : Polygon.lineAt(_poly2, i - _poly1.length);
1729
+ let edge = i < _poly1.length ? _Polygon.lineAt(_poly1, i) : _Polygon.lineAt(_poly2, i - _poly1.length);
1730
1730
  let axis = new Pt(edge[0].y - edge[1].y, edge[1].x - edge[0].x).unit();
1731
- let dist = Polygon._axisOverlap(_poly1, _poly2, axis);
1731
+ let dist = _Polygon._axisOverlap(_poly1, _poly2, axis);
1732
1732
  if (dist > 0) {
1733
1733
  return null;
1734
1734
  } else if (Math.abs(dist) < minDist) {
@@ -1741,8 +1741,8 @@ See https://github.com/williamngan/pts for details. */
1741
1741
  info.dist = minDist;
1742
1742
  let b1 = info.which === 0 ? _poly2 : _poly1;
1743
1743
  let b2 = info.which === 0 ? _poly1 : _poly2;
1744
- let c1 = Polygon.centroid(b1);
1745
- let c2 = Polygon.centroid(b2);
1744
+ let c1 = _Polygon.centroid(b1);
1745
+ let c2 = _Polygon.centroid(b2);
1746
1746
  let dir = c1.$subtract(c2).dot(info.normal);
1747
1747
  if (dir < 0)
1748
1748
  info.normal.multiply(-1);
@@ -1764,7 +1764,7 @@ See https://github.com/williamngan/pts for details. */
1764
1764
  static intersectPolygon2D(poly1, poly2) {
1765
1765
  let _poly1 = Util.iterToArray(poly1);
1766
1766
  let _poly2 = Util.iterToArray(poly2);
1767
- let lp = Polygon.lines(_poly1);
1767
+ let lp = _Polygon.lines(_poly1);
1768
1768
  let g = [];
1769
1769
  for (let i = 0, len = lp.length; i < len; i++) {
1770
1770
  let ins = Line.intersectPolygon2D(lp[i], _poly2, false);
@@ -1787,7 +1787,7 @@ See https://github.com/williamngan/pts for details. */
1787
1787
  return boxes;
1788
1788
  }
1789
1789
  };
1790
- var Curve = class {
1790
+ var Curve = class _Curve {
1791
1791
  /**
1792
1792
  * Get a precalculated coefficients per step.
1793
1793
  * @param steps number of steps
@@ -1846,17 +1846,17 @@ See https://github.com/williamngan/pts for details. */
1846
1846
  if (_pts.length < 2)
1847
1847
  return new Group();
1848
1848
  let ps = new Group();
1849
- let ts = Curve.getSteps(steps);
1850
- let c = Curve.controlPoints(_pts, 0, true);
1849
+ let ts = _Curve.getSteps(steps);
1850
+ let c = _Curve.controlPoints(_pts, 0, true);
1851
1851
  for (let i = 0; i <= steps; i++) {
1852
- ps.push(Curve.catmullRomStep(ts[i], c));
1852
+ ps.push(_Curve.catmullRomStep(ts[i], c));
1853
1853
  }
1854
1854
  let k = 0;
1855
1855
  while (k < _pts.length - 2) {
1856
- let cp = Curve.controlPoints(_pts, k);
1856
+ let cp = _Curve.controlPoints(_pts, k);
1857
1857
  if (cp.length > 0) {
1858
1858
  for (let i = 0; i <= steps; i++) {
1859
- ps.push(Curve.catmullRomStep(ts[i], cp));
1859
+ ps.push(_Curve.catmullRomStep(ts[i], cp));
1860
1860
  }
1861
1861
  k++;
1862
1862
  }
@@ -1876,7 +1876,7 @@ See https://github.com/williamngan/pts for details. */
1876
1876
  new Pt(-1.5, 2, 0.5, 0),
1877
1877
  new Pt(0.5, -0.5, 0, 0)
1878
1878
  );
1879
- return Curve._calcPt(ctrls, Mat.multiply([step], m, true)[0]);
1879
+ return _Curve._calcPt(ctrls, Mat.multiply([step], m, true)[0]);
1880
1880
  }
1881
1881
  /**
1882
1882
  * Create a Cardinal curve.
@@ -1890,17 +1890,17 @@ See https://github.com/williamngan/pts for details. */
1890
1890
  if (_pts.length < 2)
1891
1891
  return new Group();
1892
1892
  let ps = new Group();
1893
- let ts = Curve.getSteps(steps);
1894
- let c = Curve.controlPoints(_pts, 0, true);
1893
+ let ts = _Curve.getSteps(steps);
1894
+ let c = _Curve.controlPoints(_pts, 0, true);
1895
1895
  for (let i = 0; i <= steps; i++) {
1896
- ps.push(Curve.cardinalStep(ts[i], c, tension));
1896
+ ps.push(_Curve.cardinalStep(ts[i], c, tension));
1897
1897
  }
1898
1898
  let k = 0;
1899
1899
  while (k < _pts.length - 2) {
1900
- let cp = Curve.controlPoints(_pts, k);
1900
+ let cp = _Curve.controlPoints(_pts, k);
1901
1901
  if (cp.length > 0) {
1902
1902
  for (let i = 0; i <= steps; i++) {
1903
- ps.push(Curve.cardinalStep(ts[i], cp, tension));
1903
+ ps.push(_Curve.cardinalStep(ts[i], cp, tension));
1904
1904
  }
1905
1905
  k++;
1906
1906
  }
@@ -1924,7 +1924,7 @@ See https://github.com/williamngan/pts for details. */
1924
1924
  let h = Mat.multiply([step], m, true)[0].multiply(tension);
1925
1925
  let h2 = 2 * step[0] - 3 * step[1] + 1;
1926
1926
  let h3 = -2 * step[0] + 3 * step[1];
1927
- let pt = Curve._calcPt(ctrls, h);
1927
+ let pt = _Curve._calcPt(ctrls, h);
1928
1928
  pt.x += h2 * ctrls[1].x + h3 * ctrls[2].x;
1929
1929
  pt.y += h2 * ctrls[1].y + h3 * ctrls[2].y;
1930
1930
  if (pt.length > 2)
@@ -1942,13 +1942,13 @@ See https://github.com/williamngan/pts for details. */
1942
1942
  if (_pts.length < 4)
1943
1943
  return new Group();
1944
1944
  let ps = new Group();
1945
- let ts = Curve.getSteps(steps);
1945
+ let ts = _Curve.getSteps(steps);
1946
1946
  let k = 0;
1947
1947
  while (k < _pts.length - 3) {
1948
- let c = Curve.controlPoints(_pts, k);
1948
+ let c = _Curve.controlPoints(_pts, k);
1949
1949
  if (c.length > 0) {
1950
1950
  for (let i = 0; i <= steps; i++) {
1951
- ps.push(Curve.bezierStep(ts[i], c));
1951
+ ps.push(_Curve.bezierStep(ts[i], c));
1952
1952
  }
1953
1953
  k += 3;
1954
1954
  }
@@ -1968,7 +1968,7 @@ See https://github.com/williamngan/pts for details. */
1968
1968
  new Pt(-3, 3, 0, 0),
1969
1969
  new Pt(1, 0, 0, 0)
1970
1970
  );
1971
- return Curve._calcPt(ctrls, Mat.multiply([step], m, true)[0]);
1971
+ return _Curve._calcPt(ctrls, Mat.multiply([step], m, true)[0]);
1972
1972
  }
1973
1973
  /**
1974
1974
  * Create a basis spline (NURBS) curve.
@@ -1982,18 +1982,18 @@ See https://github.com/williamngan/pts for details. */
1982
1982
  if (_pts.length < 2)
1983
1983
  return new Group();
1984
1984
  let ps = new Group();
1985
- let ts = Curve.getSteps(steps);
1985
+ let ts = _Curve.getSteps(steps);
1986
1986
  let k = 0;
1987
1987
  while (k < _pts.length - 3) {
1988
- let c = Curve.controlPoints(_pts, k);
1988
+ let c = _Curve.controlPoints(_pts, k);
1989
1989
  if (c.length > 0) {
1990
1990
  if (tension !== 1) {
1991
1991
  for (let i = 0; i <= steps; i++) {
1992
- ps.push(Curve.bsplineTensionStep(ts[i], c, tension));
1992
+ ps.push(_Curve.bsplineTensionStep(ts[i], c, tension));
1993
1993
  }
1994
1994
  } else {
1995
1995
  for (let i = 0; i <= steps; i++) {
1996
- ps.push(Curve.bsplineStep(ts[i], c));
1996
+ ps.push(_Curve.bsplineStep(ts[i], c));
1997
1997
  }
1998
1998
  }
1999
1999
  k++;
@@ -2014,7 +2014,7 @@ See https://github.com/williamngan/pts for details. */
2014
2014
  new Pt(-0.5, 0.5, 0.5, 0.16666666666666666),
2015
2015
  new Pt(0.16666666666666666, 0, 0, 0)
2016
2016
  );
2017
- return Curve._calcPt(ctrls, Mat.multiply([step], m, true)[0]);
2017
+ return _Curve._calcPt(ctrls, Mat.multiply([step], m, true)[0]);
2018
2018
  }
2019
2019
  /**
2020
2020
  * Interpolate to get a point on a basis spline curve with tension.
@@ -2033,7 +2033,7 @@ See https://github.com/williamngan/pts for details. */
2033
2033
  let h = Mat.multiply([step], m, true)[0].multiply(tension);
2034
2034
  let h2 = 2 * step[0] - 3 * step[1] + 1;
2035
2035
  let h3 = -2 * step[0] + 3 * step[1];
2036
- let pt = Curve._calcPt(ctrls, h);
2036
+ let pt = _Curve._calcPt(ctrls, h);
2037
2037
  pt.x += h2 * ctrls[1].x + h3 * ctrls[2].x;
2038
2038
  pt.y += h2 * ctrls[1].y + h3 * ctrls[2].y;
2039
2039
  if (pt.length > 2)
@@ -2044,13 +2044,13 @@ See https://github.com/williamngan/pts for details. */
2044
2044
 
2045
2045
  // src/uheprng.ts
2046
2046
  function Mash() {
2047
- var n = 4022871197;
2048
- var mash = function(data) {
2047
+ let n = 4022871197;
2048
+ let mash = function(data) {
2049
2049
  if (data) {
2050
2050
  data = data.toString();
2051
- for (var i = 0; i < data.length; i++) {
2051
+ for (let i = 0; i < data.length; i++) {
2052
2052
  n += data.charCodeAt(i);
2053
- var h = 0.02519603282416938 * n;
2053
+ let h = 0.02519603282416938 * n;
2054
2054
  n = h >>> 0;
2055
2055
  h -= n;
2056
2056
  h *= n;
@@ -2065,12 +2065,12 @@ See https://github.com/williamngan/pts for details. */
2065
2065
  return mash;
2066
2066
  }
2067
2067
  function uheprng_default(seed) {
2068
- var o = 48;
2069
- var c = 1;
2070
- var p = o;
2071
- var s = new Array(o);
2072
- var i, j, k = 0;
2073
- var mash = Mash();
2068
+ let o = 48;
2069
+ let c = 1;
2070
+ let p = o;
2071
+ let s = new Array(o);
2072
+ let i, j, k = 0;
2073
+ let mash = Mash();
2074
2074
  for (i = 0; i < o; i++)
2075
2075
  s[i] = mash(Math.random().toString());
2076
2076
  function initState() {
@@ -2102,24 +2102,24 @@ See https://github.com/williamngan/pts for details. */
2102
2102
  hashString(seed);
2103
2103
  return {
2104
2104
  /**
2105
- * this (not anymore) PRIVATE (internal access only) function is the heart of the multiply-with-carry
2106
- * (MWC) PRNG algorithm. When called it returns a pseudo-random number in the form of a
2107
- * 32-bit JavaScript fraction (0.0 to <1.0) it is a PRIVATE function used by the default
2108
- * [0-1] return function, and by the random 'string(n)' function which returns 'n'
2109
- * characters from 33 to 126.
2110
- * @returns a number between 0.0 and 1.0
2111
- */
2105
+ * this (not anymore) PRIVATE (internal access only) function is the heart of the multiply-with-carry
2106
+ * (MWC) PRNG algorithm. When called it returns a pseudo-random number in the form of a
2107
+ * 32-bit JavaScript fraction (0.0 to <1.0) it is a PRIVATE function used by the default
2108
+ * [0-1] return function, and by the random 'string(n)' function which returns 'n'
2109
+ * characters from 33 to 126.
2110
+ * @returns a number between 0.0 and 1.0
2111
+ */
2112
2112
  random() {
2113
2113
  if (++p >= o)
2114
2114
  p = 0;
2115
- var t = 1768863 * s[p] + c * 23283064365386963e-26;
2115
+ let t = 1768863 * s[p] + c * 23283064365386963e-26;
2116
2116
  return s[p] = t - (c = t | 0);
2117
2117
  }
2118
2118
  };
2119
2119
  }
2120
2120
 
2121
2121
  // src/Num.ts
2122
- var Num = class {
2122
+ var Num = class _Num {
2123
2123
  /**
2124
2124
  * Check if two numbers are equal or almost equal within a threshold.
2125
2125
  * @param a number a
@@ -2155,7 +2155,7 @@ See https://github.com/williamngan/pts for details. */
2155
2155
  * @example `boundValue(361, 0, 360)` will return 1
2156
2156
  */
2157
2157
  static boundValue(val, min, max) {
2158
- let len = Math.abs(max - min);
2158
+ const len = Math.abs(max - min);
2159
2159
  let a = val % len;
2160
2160
  if (a > max)
2161
2161
  a -= len;
@@ -2178,8 +2178,8 @@ See https://github.com/williamngan/pts for details. */
2178
2178
  * @param b range value 2
2179
2179
  */
2180
2180
  static randomRange(a, b = 0) {
2181
- let r = a > b ? a - b : b - a;
2182
- return a + Num.random() * r;
2181
+ const r = a > b ? a - b : b - a;
2182
+ return a + _Num.random() * r;
2183
2183
  }
2184
2184
  /**
2185
2185
  * Get a random Pt within the range defined by either 1 or 2 Pt
@@ -2187,11 +2187,11 @@ See https://github.com/williamngan/pts for details. */
2187
2187
  * @param b optional Pt to define the end of the range
2188
2188
  */
2189
2189
  static randomPt(a, b) {
2190
- let p = new Pt(a.length);
2191
- let range = b ? Vec.subtract(b.slice(), a) : a;
2192
- let start = b ? a : new Pt(a.length).fill(0);
2190
+ const p = new Pt(a.length);
2191
+ const range = b ? Vec.subtract(b.slice(), a) : a;
2192
+ const start = b ? a : new Pt(a.length).fill(0);
2193
2193
  for (let i = 0, len = p.length; i < len; i++) {
2194
- p[i] = Num.random() * range[i] + start[i];
2194
+ p[i] = _Num.random() * range[i] + start[i];
2195
2195
  }
2196
2196
  return p;
2197
2197
  }
@@ -2202,8 +2202,8 @@ See https://github.com/williamngan/pts for details. */
2202
2202
  * @param b range value 1
2203
2203
  */
2204
2204
  static normalizeValue(n, a, b) {
2205
- let min = Math.min(a, b);
2206
- let max = Math.max(a, b);
2205
+ const min = Math.min(a, b);
2206
+ const max = Math.max(a, b);
2207
2207
  return (n - min) / (max - min);
2208
2208
  }
2209
2209
  /**
@@ -2212,8 +2212,8 @@ See https://github.com/williamngan/pts for details. */
2212
2212
  * @returns a Pt of the dimensional sums
2213
2213
  */
2214
2214
  static sum(pts) {
2215
- let _pts = Util.iterToArray(pts);
2216
- let c = new Pt(_pts[0]);
2215
+ const _pts = Util.iterToArray(pts);
2216
+ const c = new Pt(_pts[0]);
2217
2217
  for (let i = 1, len = _pts.length; i < len; i++) {
2218
2218
  Vec.add(c, _pts[i]);
2219
2219
  }
@@ -2225,8 +2225,8 @@ See https://github.com/williamngan/pts for details. */
2225
2225
  * @returns a Pt of averages
2226
2226
  */
2227
2227
  static average(pts) {
2228
- let _pts = Util.iterToArray(pts);
2229
- return Num.sum(_pts).divide(_pts.length);
2228
+ const _pts = Util.iterToArray(pts);
2229
+ return _Num.sum(_pts).divide(_pts.length);
2230
2230
  }
2231
2231
  /**
2232
2232
  * Given a value between 0 to 1, returns a value that cycles between 0 -> 1 -> 0 using the provided shaping method.
@@ -2249,9 +2249,9 @@ See https://github.com/williamngan/pts for details. */
2249
2249
  static mapToRange(n, currA, currB, targetA, targetB) {
2250
2250
  if (currA == currB)
2251
2251
  throw new Error("[currMin, currMax] must define a range that is not zero");
2252
- let min = Math.min(targetA, targetB);
2253
- let max = Math.max(targetA, targetB);
2254
- return Num.normalizeValue(n, currA, currB) * (max - min) + min;
2252
+ const min = Math.min(targetA, targetB);
2253
+ const max = Math.max(targetA, targetB);
2254
+ return _Num.normalizeValue(n, currA, currB) * (max - min) + min;
2255
2255
  }
2256
2256
  /**
2257
2257
  * Seed the pseudorandom generator.
@@ -2269,7 +2269,7 @@ See https://github.com/williamngan/pts for details. */
2269
2269
  return this.generator ? this.generator.random() : Math.random();
2270
2270
  }
2271
2271
  };
2272
- var Geom = class {
2272
+ var Geom = class _Geom {
2273
2273
  /**
2274
2274
  * Bound an angle between 0 to 360 degrees.
2275
2275
  * @param angle angle value
@@ -2305,7 +2305,7 @@ See https://github.com/williamngan/pts for details. */
2305
2305
  */
2306
2306
  static boundingBox(pts) {
2307
2307
  let minPt, maxPt;
2308
- for (let p of pts) {
2308
+ for (const p of pts) {
2309
2309
  if (minPt == void 0) {
2310
2310
  minPt = p.clone();
2311
2311
  maxPt = p.clone();
@@ -2331,9 +2331,9 @@ See https://github.com/williamngan/pts for details. */
2331
2331
  * @param direction a string either "to" (subtract all Pt with this anchor base), or "from" (add all Pt from this anchor base)
2332
2332
  */
2333
2333
  static anchor(pts, ptOrIndex = 0, direction = "to") {
2334
- let method = direction == "to" ? "subtract" : "add";
2334
+ const method = direction == "to" ? "subtract" : "add";
2335
2335
  let i = 0;
2336
- for (let p of pts) {
2336
+ for (const p of pts) {
2337
2337
  if (typeof ptOrIndex == "number") {
2338
2338
  if (ptOrIndex !== i)
2339
2339
  p[method](pts[ptOrIndex]);
@@ -2351,8 +2351,8 @@ See https://github.com/williamngan/pts for details. */
2351
2351
  * @returns interpolated point as a new Pt
2352
2352
  */
2353
2353
  static interpolate(a, b, t = 0.5) {
2354
- let len = Math.min(a.length, b.length);
2355
- let d = Pt.make(len);
2354
+ const len = Math.min(a.length, b.length);
2355
+ const d = Pt.make(len);
2356
2356
  for (let i = 0; i < len; i++) {
2357
2357
  d[i] = a[i] * (1 - t) + b[i] * t;
2358
2358
  }
@@ -2364,13 +2364,13 @@ See https://github.com/williamngan/pts for details. */
2364
2364
  * @returns an array of two Pt that are perpendicular to this Pt
2365
2365
  */
2366
2366
  static perpendicular(pt, axis = Const.xy) {
2367
- let y = axis[1];
2368
- let x = axis[0];
2369
- let p = new Pt(pt);
2370
- let pa = new Pt(p);
2367
+ const y = axis[1];
2368
+ const x = axis[0];
2369
+ const p = new Pt(pt);
2370
+ const pa = new Pt(p);
2371
2371
  pa[x] = -p[y];
2372
2372
  pa[y] = p[x];
2373
- let pb = new Pt(p);
2373
+ const pb = new Pt(p);
2374
2374
  pb[x] = p[y];
2375
2375
  pb[y] = -p[x];
2376
2376
  return new Group(pa, pb);
@@ -2399,14 +2399,14 @@ See https://github.com/williamngan/pts for details. */
2399
2399
  * @param pts a Group or an Iterable<Pt>
2400
2400
  */
2401
2401
  static sortEdges(pts) {
2402
- let _pts = Util.iterToArray(pts);
2403
- let bounds = Geom.boundingBox(_pts);
2404
- let center = bounds[1].add(bounds[0]).divide(2);
2405
- let fn = (a, b) => {
2402
+ const _pts = Util.iterToArray(pts);
2403
+ const bounds = _Geom.boundingBox(_pts);
2404
+ const center = bounds[1].add(bounds[0]).divide(2);
2405
+ const fn = (a, b) => {
2406
2406
  if (a.length < 2 || b.length < 2)
2407
2407
  throw new Error("Pt dimension cannot be less than 2");
2408
- let da = a.$subtract(center);
2409
- let db = b.$subtract(center);
2408
+ const da = a.$subtract(center);
2409
+ const db = b.$subtract(center);
2410
2410
  if (da[0] >= 0 && db[0] < 0)
2411
2411
  return 1;
2412
2412
  if (da[0] < 0 && db[0] >= 0)
@@ -2416,7 +2416,7 @@ See https://github.com/williamngan/pts for details. */
2416
2416
  return da[1] > db[1] ? 1 : -1;
2417
2417
  return db[1] > da[1] ? 1 : -1;
2418
2418
  }
2419
- let det = da.$cross2D(db);
2419
+ const det = da.$cross2D(db);
2420
2420
  if (det < 0)
2421
2421
  return 1;
2422
2422
  if (det > 0)
@@ -2432,17 +2432,17 @@ See https://github.com/williamngan/pts for details. */
2432
2432
  * @param anchor optional anchor point to scale from
2433
2433
  */
2434
2434
  static scale(ps, scale, anchor) {
2435
- let pts = Util.iterToArray(ps[0] !== void 0 && typeof ps[0] == "number" ? [ps] : ps);
2436
- let scs = typeof scale == "number" ? Pt.make(pts[0].length, scale) : scale;
2435
+ const pts = Util.iterToArray(ps[0] !== void 0 && typeof ps[0] == "number" ? [ps] : ps);
2436
+ const scs = typeof scale == "number" ? Pt.make(pts[0].length, scale) : scale;
2437
2437
  if (!anchor)
2438
2438
  anchor = Pt.make(pts[0].length, 0);
2439
2439
  for (let i = 0, len = pts.length; i < len; i++) {
2440
- let p = pts[i];
2440
+ const p = pts[i];
2441
2441
  for (let k = 0, lenP = p.length; k < lenP; k++) {
2442
2442
  p[k] = anchor && anchor[k] ? anchor[k] + (p[k] - anchor[k]) * scs[k] : p[k] * scs[k];
2443
2443
  }
2444
2444
  }
2445
- return Geom;
2445
+ return _Geom;
2446
2446
  }
2447
2447
  /**
2448
2448
  * Rotate a Pt or a Group of Pts in 2D space. You may also use [`Pt.rotate2D`](#link) instance method.
@@ -2452,14 +2452,14 @@ See https://github.com/williamngan/pts for details. */
2452
2452
  * @param axis optional axis such as "xy" (use Const.xy) to define a 2D plane, or a number array to specify indices
2453
2453
  */
2454
2454
  static rotate2D(ps, angle, anchor, axis) {
2455
- let pts = Util.iterToArray(ps[0] !== void 0 && typeof ps[0] == "number" ? [ps] : ps);
2456
- let fn = anchor ? Mat.rotateAt2DMatrix : Mat.rotate2DMatrix;
2455
+ const pts = Util.iterToArray(ps[0] !== void 0 && typeof ps[0] == "number" ? [ps] : ps);
2456
+ const fn = anchor ? Mat.rotateAt2DMatrix : Mat.rotate2DMatrix;
2457
2457
  if (!anchor)
2458
2458
  anchor = Pt.make(pts[0].length, 0);
2459
- let cos = Math.cos(angle);
2460
- let sin = Math.sin(angle);
2459
+ const cos = Math.cos(angle);
2460
+ const sin = Math.sin(angle);
2461
2461
  for (let i = 0, len = pts.length; i < len; i++) {
2462
- let p = axis ? pts[i].$take(axis) : pts[i];
2462
+ const p = axis ? pts[i].$take(axis) : pts[i];
2463
2463
  p.to(Mat.transform2D(p, fn(cos, sin, anchor)));
2464
2464
  if (axis) {
2465
2465
  for (let k = 0; k < axis.length; k++) {
@@ -2467,7 +2467,7 @@ See https://github.com/williamngan/pts for details. */
2467
2467
  }
2468
2468
  }
2469
2469
  }
2470
- return Geom;
2470
+ return _Geom;
2471
2471
  }
2472
2472
  /**
2473
2473
  * Shear a Pt or a Group of Pts in 2D space. You may also use [`Pt.shear2D`](#link) instance method.
@@ -2477,15 +2477,15 @@ See https://github.com/williamngan/pts for details. */
2477
2477
  * @param axis optional axis such as "xy" (use Const.xy) to define a 2D plane, or a number array to specify indices
2478
2478
  */
2479
2479
  static shear2D(ps, scale, anchor, axis) {
2480
- let pts = Util.iterToArray(ps[0] !== void 0 && typeof ps[0] == "number" ? [ps] : ps);
2481
- let s = typeof scale == "number" ? [scale, scale] : scale;
2480
+ const pts = Util.iterToArray(ps[0] !== void 0 && typeof ps[0] == "number" ? [ps] : ps);
2481
+ const s = typeof scale == "number" ? [scale, scale] : scale;
2482
2482
  if (!anchor)
2483
2483
  anchor = Pt.make(pts[0].length, 0);
2484
- let fn = anchor ? Mat.shearAt2DMatrix : Mat.shear2DMatrix;
2485
- let tanx = Math.tan(s[0]);
2486
- let tany = Math.tan(s[1]);
2484
+ const fn = anchor ? Mat.shearAt2DMatrix : Mat.shear2DMatrix;
2485
+ const tanx = Math.tan(s[0]);
2486
+ const tany = Math.tan(s[1]);
2487
2487
  for (let i = 0, len = pts.length; i < len; i++) {
2488
- let p = axis ? pts[i].$take(axis) : pts[i];
2488
+ const p = axis ? pts[i].$take(axis) : pts[i];
2489
2489
  p.to(Mat.transform2D(p, fn(tanx, tany, anchor)));
2490
2490
  if (axis) {
2491
2491
  for (let k = 0; k < axis.length; k++) {
@@ -2493,7 +2493,7 @@ See https://github.com/williamngan/pts for details. */
2493
2493
  }
2494
2494
  }
2495
2495
  }
2496
- return Geom;
2496
+ return _Geom;
2497
2497
  }
2498
2498
  /**
2499
2499
  * Reflect a Pt or a Group of Pts along a 2D line. You may also use [`Pt.reflect2D`](#link) instance method.
@@ -2502,11 +2502,11 @@ See https://github.com/williamngan/pts for details. */
2502
2502
  * @param axis optional axis such as "xy" (use Const.xy) to define a 2D plane, or a number array to specify indices
2503
2503
  */
2504
2504
  static reflect2D(ps, line, axis) {
2505
- let pts = Util.iterToArray(ps[0] !== void 0 && typeof ps[0] == "number" ? [ps] : ps);
2506
- let _line = Util.iterToArray(line);
2507
- let mat = Mat.reflectAt2DMatrix(_line[0], _line[1]);
2505
+ const pts = Util.iterToArray(ps[0] !== void 0 && typeof ps[0] == "number" ? [ps] : ps);
2506
+ const _line = Util.iterToArray(line);
2507
+ const mat = Mat.reflectAt2DMatrix(_line[0], _line[1]);
2508
2508
  for (let i = 0, len = pts.length; i < len; i++) {
2509
- let p = axis ? pts[i].$take(axis) : pts[i];
2509
+ const p = axis ? pts[i].$take(axis) : pts[i];
2510
2510
  p.to(Mat.transform2D(p, mat));
2511
2511
  if (axis) {
2512
2512
  for (let k = 0; k < axis.length; k++) {
@@ -2514,17 +2514,17 @@ See https://github.com/williamngan/pts for details. */
2514
2514
  }
2515
2515
  }
2516
2516
  }
2517
- return Geom;
2517
+ return _Geom;
2518
2518
  }
2519
2519
  /**
2520
2520
  * Generate a cosine lookup table.
2521
2521
  * @returns an object with a cosine tables (array of 360 values) and a function to get cosine given a radian input.
2522
2522
  */
2523
2523
  static cosTable() {
2524
- let cos = new Float64Array(360);
2524
+ const cos = new Float64Array(360);
2525
2525
  for (let i = 0; i < 360; i++)
2526
2526
  cos[i] = Math.cos(i * Math.PI / 180);
2527
- let find = (rad) => cos[Math.floor(Geom.boundAngle(Geom.toDegree(rad)))];
2527
+ const find = (rad) => cos[Math.floor(_Geom.boundAngle(_Geom.toDegree(rad)))];
2528
2528
  return { table: cos, cos: find };
2529
2529
  }
2530
2530
  /**
@@ -2532,14 +2532,14 @@ See https://github.com/williamngan/pts for details. */
2532
2532
  * @returns an object with a sine tables (array of 360 values) and a function to get sine value given a radian input.
2533
2533
  */
2534
2534
  static sinTable() {
2535
- let sin = new Float64Array(360);
2535
+ const sin = new Float64Array(360);
2536
2536
  for (let i = 0; i < 360; i++)
2537
2537
  sin[i] = Math.sin(i * Math.PI / 180);
2538
- let find = (rad) => sin[Math.floor(Geom.boundAngle(Geom.toDegree(rad)))];
2538
+ const find = (rad) => sin[Math.floor(_Geom.boundAngle(_Geom.toDegree(rad)))];
2539
2539
  return { table: sin, sin: find };
2540
2540
  }
2541
2541
  };
2542
- var Shaping = class {
2542
+ var Shaping = class _Shaping {
2543
2543
  /**
2544
2544
  * Linear mapping.
2545
2545
  * @param t a value between 0 to 1
@@ -2570,7 +2570,7 @@ See https://github.com/williamngan/pts for details. */
2570
2570
  * @param c the value to shape, default is 1
2571
2571
  */
2572
2572
  static quadraticInOut(t, c = 1) {
2573
- let dt = t * 2;
2573
+ const dt = t * 2;
2574
2574
  return t < 0.5 ? c / 2 * t * t * 4 : -c / 2 * ((dt - 1) * (dt - 3) - 1);
2575
2575
  }
2576
2576
  /**
@@ -2587,7 +2587,7 @@ See https://github.com/williamngan/pts for details. */
2587
2587
  * @param c the value to shape, default is 1
2588
2588
  */
2589
2589
  static cubicOut(t, c = 1) {
2590
- let dt = t - 1;
2590
+ const dt = t - 1;
2591
2591
  return c * (dt * dt * dt + 1);
2592
2592
  }
2593
2593
  /**
@@ -2596,7 +2596,7 @@ See https://github.com/williamngan/pts for details. */
2596
2596
  * @param c the value to shape, default is 1
2597
2597
  */
2598
2598
  static cubicInOut(t, c = 1) {
2599
- let dt = t * 2;
2599
+ const dt = t * 2;
2600
2600
  return t < 0.5 ? c / 2 * dt * dt * dt : c / 2 * ((dt - 2) * (dt - 2) * (dt - 2) + 2);
2601
2601
  }
2602
2602
  /**
@@ -2647,9 +2647,9 @@ See https://github.com/williamngan/pts for details. */
2647
2647
  * @param c the value to shape, default is 1
2648
2648
  */
2649
2649
  static cosineApprox(t, c = 1) {
2650
- let t2 = t * t;
2651
- let t4 = t2 * t2;
2652
- let t6 = t4 * t2;
2650
+ const t2 = t * t;
2651
+ const t4 = t2 * t2;
2652
+ const t6 = t4 * t2;
2653
2653
  return c * (4 * t6 / 9 - 17 * t4 / 9 + 22 * t2 / 9);
2654
2654
  }
2655
2655
  /**
@@ -2666,7 +2666,7 @@ See https://github.com/williamngan/pts for details. */
2666
2666
  * @param c the value to shape, default is 1
2667
2667
  */
2668
2668
  static circularOut(t, c = 1) {
2669
- let dt = t - 1;
2669
+ const dt = t - 1;
2670
2670
  return c * Math.sqrt(1 - dt * dt);
2671
2671
  }
2672
2672
  /**
@@ -2675,7 +2675,7 @@ See https://github.com/williamngan/pts for details. */
2675
2675
  * @param c the value to shape, default is 1
2676
2676
  */
2677
2677
  static circularInOut(t, c = 1) {
2678
- let dt = t * 2;
2678
+ const dt = t * 2;
2679
2679
  return t < 0.5 ? -c / 2 * (Math.sqrt(1 - dt * dt) - 1) : c / 2 * (Math.sqrt(1 - (dt - 2) * (dt - 2)) + 1);
2680
2680
  }
2681
2681
  /**
@@ -2685,8 +2685,8 @@ See https://github.com/williamngan/pts for details. */
2685
2685
  * @param p elastic parmeter between 0 to 1. The lower the number, the more elastic it will be. Default is 0.7.
2686
2686
  */
2687
2687
  static elasticIn(t, c = 1, p = 0.7) {
2688
- let dt = t - 1;
2689
- let s = p / Const.two_pi * 1.5707963267948966;
2688
+ const dt = t - 1;
2689
+ const s = p / Const.two_pi * 1.5707963267948966;
2690
2690
  return c * (-Math.pow(2, 10 * dt) * Math.sin((dt - s) * Const.two_pi / p));
2691
2691
  }
2692
2692
  /**
@@ -2696,7 +2696,7 @@ See https://github.com/williamngan/pts for details. */
2696
2696
  * @param p elastic parmeter between 0 to 1. The lower the number, the more elastic it will be. Default is 0.7.
2697
2697
  */
2698
2698
  static elasticOut(t, c = 1, p = 0.7) {
2699
- let s = p / Const.two_pi * 1.5707963267948966;
2699
+ const s = p / Const.two_pi * 1.5707963267948966;
2700
2700
  return c * (Math.pow(2, -10 * t) * Math.sin((t - s) * Const.two_pi / p)) + c;
2701
2701
  }
2702
2702
  /**
@@ -2707,7 +2707,7 @@ See https://github.com/williamngan/pts for details. */
2707
2707
  */
2708
2708
  static elasticInOut(t, c = 1, p = 0.6) {
2709
2709
  let dt = t * 2;
2710
- let s = p / Const.two_pi * 1.5707963267948966;
2710
+ const s = p / Const.two_pi * 1.5707963267948966;
2711
2711
  if (t < 0.5) {
2712
2712
  dt -= 1;
2713
2713
  return c * (-0.5 * (Math.pow(2, 10 * dt) * Math.sin((dt - s) * Const.two_pi / p)));
@@ -2722,7 +2722,7 @@ See https://github.com/williamngan/pts for details. */
2722
2722
  * @param c the value to shape, default is 1
2723
2723
  */
2724
2724
  static bounceIn(t, c = 1) {
2725
- return c - Shaping.bounceOut(1 - t, c);
2725
+ return c - _Shaping.bounceOut(1 - t, c);
2726
2726
  }
2727
2727
  /**
2728
2728
  * Bounce out, adapted from Robert Penner's [easing functions](http://robertpenner.com/easing/).
@@ -2749,7 +2749,7 @@ See https://github.com/williamngan/pts for details. */
2749
2749
  * @param c the value to shape, default is 1
2750
2750
  */
2751
2751
  static bounceInOut(t, c = 1) {
2752
- return t < 0.5 ? Shaping.bounceIn(t * 2, c) / 2 : Shaping.bounceOut(t * 2 - 1, c) / 2 + c / 2;
2752
+ return t < 0.5 ? _Shaping.bounceIn(t * 2, c) / 2 : _Shaping.bounceOut(t * 2 - 1, c) / 2 + c / 2;
2753
2753
  }
2754
2754
  /**
2755
2755
  * Sigmoid curve changes its shape adapted from the input value, but always returns a value between 0 to 1.
@@ -2758,7 +2758,7 @@ See https://github.com/williamngan/pts for details. */
2758
2758
  * @param p the larger the value, the "steeper" the curve will be. Default is 10.
2759
2759
  */
2760
2760
  static sigmoid(t, c = 1, p = 10) {
2761
- let d = p * (t - 0.5);
2761
+ const d = p * (t - 0.5);
2762
2762
  return c / (1 + Math.exp(-d));
2763
2763
  }
2764
2764
  /**
@@ -2770,9 +2770,9 @@ See https://github.com/williamngan/pts for details. */
2770
2770
  static logSigmoid(t, c = 1, p = 0.7) {
2771
2771
  p = Math.max(Const.epsilon, Math.min(1 - Const.epsilon, p));
2772
2772
  p = 1 / (1 - p);
2773
- let A = 1 / (1 + Math.exp((t - 0.5) * p * -2));
2774
- let B = 1 / (1 + Math.exp(p));
2775
- let C = 1 / (1 + Math.exp(-p));
2773
+ const A = 1 / (1 + Math.exp((t - 0.5) * p * -2));
2774
+ const B = 1 / (1 + Math.exp(p));
2775
+ const C = 1 / (1 + Math.exp(-p));
2776
2776
  return c * (A - B) / (C - B);
2777
2777
  }
2778
2778
  /**
@@ -2795,13 +2795,13 @@ See https://github.com/williamngan/pts for details. */
2795
2795
  * @param p1 a Pt object specifying the first control Pt, or a value specifying the control Pt's x position (its y position will default to 0.5). Default is `Pt(0.95, 0.95)
2796
2796
  */
2797
2797
  static quadraticBezier(t, c = 1, p = [0.05, 0.95]) {
2798
- let a = typeof p != "number" ? p[0] : p;
2799
- let b = typeof p != "number" ? p[1] : 0.5;
2798
+ const a = typeof p != "number" ? p[0] : p;
2799
+ const b = typeof p != "number" ? p[1] : 0.5;
2800
2800
  let om2a = 1 - 2 * a;
2801
2801
  if (om2a === 0) {
2802
2802
  om2a = Const.epsilon;
2803
2803
  }
2804
- let d = (Math.sqrt(a * a + om2a * t) - a) / om2a;
2804
+ const d = (Math.sqrt(a * a + om2a * t) - a) / om2a;
2805
2805
  return c * ((1 - 2 * b) * (d * d) + 2 * b * d);
2806
2806
  }
2807
2807
  /**
@@ -2812,7 +2812,7 @@ See https://github.com/williamngan/pts for details. */
2812
2812
  * @param p2` a Pt object specifying the second control Pt. Default is `Pt(0.9, 0.2).
2813
2813
  */
2814
2814
  static cubicBezier(t, c = 1, p1 = [0.1, 0.7], p2 = [0.9, 0.2]) {
2815
- let curve = new Group(new Pt(0, 0), new Pt(p1), new Pt(p2), new Pt(1, 1));
2815
+ const curve = new Group(new Pt(0, 0), new Pt(p1), new Pt(p2), new Pt(1, 1));
2816
2816
  return c * Curve.bezierStep(new Pt(t * t * t, t * t, t, 1), Curve.controlPoints(curve)).y;
2817
2817
  }
2818
2818
  /**
@@ -2822,11 +2822,11 @@ See https://github.com/williamngan/pts for details. */
2822
2822
  * @param p1` a Pt object specifying the Pt to pass through. Default is `Pt(0.2, 0.35)
2823
2823
  */
2824
2824
  static quadraticTarget(t, c = 1, p1 = [0.2, 0.35]) {
2825
- let a = Math.min(1 - Const.epsilon, Math.max(Const.epsilon, p1[0]));
2826
- let b = Math.min(1, Math.max(0, p1[1]));
2827
- let A = (1 - b) / (1 - a) - b / a;
2828
- let B = (A * (a * a) - b) / a;
2829
- let y = A * (t * t) - B * t;
2825
+ const a = Math.min(1 - Const.epsilon, Math.max(Const.epsilon, p1[0]));
2826
+ const b = Math.min(1, Math.max(0, p1[1]));
2827
+ const A = (1 - b) / (1 - a) - b / a;
2828
+ const B = (A * (a * a) - b) / a;
2829
+ const y = A * (t * t) - B * t;
2830
2830
  return c * Math.min(1, Math.max(0, y));
2831
2831
  }
2832
2832
  /**
@@ -2847,8 +2847,8 @@ See https://github.com/williamngan/pts for details. */
2847
2847
  * @param args optional paramters to pass to original function
2848
2848
  */
2849
2849
  static step(fn, steps, t, c, ...args) {
2850
- let s = 1 / steps;
2851
- let tt = Math.floor(t / s) * s;
2850
+ const s = 1 / steps;
2851
+ const tt = Math.floor(t / s) * s;
2852
2852
  return fn(tt, c, ...args);
2853
2853
  }
2854
2854
  };
@@ -2886,16 +2886,16 @@ See https://github.com/williamngan/pts for details. */
2886
2886
  calc() {
2887
2887
  if (!this._source)
2888
2888
  return;
2889
- let dims = this._source[0].length;
2889
+ const dims = this._source[0].length;
2890
2890
  this._dims = dims;
2891
- let max = new Pt(dims);
2892
- let min = new Pt(dims);
2893
- let mag = new Pt(dims);
2891
+ const max = new Pt(dims);
2892
+ const min = new Pt(dims);
2893
+ const mag = new Pt(dims);
2894
2894
  for (let i = 0; i < dims; i++) {
2895
2895
  max[i] = Const.min;
2896
2896
  min[i] = Const.max;
2897
2897
  mag[i] = 0;
2898
- let s = this._source.zipSlice(i);
2898
+ const s = this._source.zipSlice(i);
2899
2899
  for (let k = 0, len = s.length; k < len; k++) {
2900
2900
  max[i] = Math.max(max[i], s[k]);
2901
2901
  min[i] = Math.min(min[i], s[k]);
@@ -2914,10 +2914,10 @@ See https://github.com/williamngan/pts for details. */
2914
2914
  * @param exclude Optional boolean array where `true` means excluding the conversion in that specific dimension.
2915
2915
  */
2916
2916
  mapTo(min, max, exclude) {
2917
- let target = new Group();
2917
+ const target = new Group();
2918
2918
  for (let i = 0, len = this._source.length; i < len; i++) {
2919
- let g = this._source[i];
2920
- let n = new Pt(this._dims);
2919
+ const g = this._source[i];
2920
+ const n = new Pt(this._dims);
2921
2921
  for (let k = 0; k < this._dims; k++) {
2922
2922
  n[k] = exclude && exclude[k] ? g[k] : Num.mapToRange(g[k], this._min[k], this._max[k], min, max);
2923
2923
  }
@@ -2931,7 +2931,7 @@ See https://github.com/williamngan/pts for details. */
2931
2931
  * @param update Optional. Set the parameter to `false` if you want to append without immediately updating this Range's min and max values. Default is `true`.
2932
2932
  */
2933
2933
  append(pts, update = true) {
2934
- let _pts = Util.iterToArray(pts);
2934
+ const _pts = Util.iterToArray(pts);
2935
2935
  if (_pts[0].length !== this._dims)
2936
2936
  throw new Error(`Dimensions don't match. ${this._dims} dimensions in Range and ${_pts[0].length} provided in parameter. `);
2937
2937
  this._source = this._source.concat(_pts);
@@ -2944,9 +2944,9 @@ See https://github.com/williamngan/pts for details. */
2944
2944
  * @param count number of subdivision. For example, 10 subdivision will return 11 tick values, which include first(min) and last(max) values.
2945
2945
  */
2946
2946
  ticks(count) {
2947
- let g = new Group();
2947
+ const g = new Group();
2948
2948
  for (let i = 0; i <= count; i++) {
2949
- let p = new Pt(this._dims);
2949
+ const p = new Pt(this._dims);
2950
2950
  for (let k = 0, len = this._max.length; k < len; k++) {
2951
2951
  p[k] = Num.lerp(this._min[k], this._max[k], i / count);
2952
2952
  }
@@ -3015,7 +3015,7 @@ See https://github.com/williamngan/pts for details. */
3015
3015
  /** Gaussian constant (1 / Math.sqrt(2 * Math.PI)) */
3016
3016
  gaussian: 0.3989422804014327
3017
3017
  };
3018
- var _Util = class {
3018
+ var _Util = class _Util {
3019
3019
  /**
3020
3020
  * Set a global warning level setting. If no parameter is passed, this will return the current warn-level. See [`Util.warn`](#link).
3021
3021
  * @param lv a [`WarningType`](#link) option, where "error" will throw an error, "warn" will log in console, and "mute" will ignore the error.
@@ -3110,7 +3110,7 @@ See https://github.com/williamngan/pts for details. */
3110
3110
  * @param flattenAsGroup a boolean to specify whether the return type should be a Group or Array. Default is `true` which returns a Group.
3111
3111
  */
3112
3112
  static flatten(pts, flattenAsGroup = true) {
3113
- let arr = flattenAsGroup ? new Group() : new Array();
3113
+ let arr = flattenAsGroup ? new Group() : [];
3114
3114
  return arr.concat.apply(arr, pts);
3115
3115
  }
3116
3116
  /**
@@ -3183,7 +3183,7 @@ See https://github.com/williamngan/pts for details. */
3183
3183
  * @param callback a function to capture the data. It receives two parameters: a `response` as string, and a `success` status as boolean.
3184
3184
  */
3185
3185
  static load(url, callback) {
3186
- var request = new XMLHttpRequest();
3186
+ let request = new XMLHttpRequest();
3187
3187
  request.open("GET", url, true);
3188
3188
  request.onload = function() {
3189
3189
  if (request.status >= 200 && request.status < 400) {
@@ -3261,11 +3261,11 @@ See https://github.com/williamngan/pts for details. */
3261
3261
  return /iPhone|iPad|Android/i.test(navigator.userAgent);
3262
3262
  }
3263
3263
  };
3264
+ _Util._warnLevel = "mute";
3264
3265
  var Util = _Util;
3265
- Util._warnLevel = "mute";
3266
3266
 
3267
3267
  // src/Pt.ts
3268
- var Pt = class extends Float32Array {
3268
+ var Pt = class _Pt extends Float32Array {
3269
3269
  /**
3270
3270
  * Create a Pt. If no parameter is provided, this will instantiate a Pt with 2 dimensions [0, 0].
3271
3271
  * Note that `new Pt(3)` will only instantiate Pt with length of 3 (ie, same as `new Float32Array(3)` ). If you need a Pt with 1 dimension of value 3, use `new Pt([3])`.
@@ -3288,7 +3288,7 @@ See https://github.com/williamngan/pts for details. */
3288
3288
  * @param randomize if `true`, randomize the value between 0 to default value
3289
3289
  */
3290
3290
  static make(dimensions, defaultValue = 0, randomize = false) {
3291
- let p = new Float32Array(dimensions);
3291
+ const p = new Float32Array(dimensions);
3292
3292
  if (defaultValue)
3293
3293
  p.fill(defaultValue);
3294
3294
  if (randomize) {
@@ -3296,7 +3296,7 @@ See https://github.com/williamngan/pts for details. */
3296
3296
  p[i] = p[i] * Num.random();
3297
3297
  }
3298
3298
  }
3299
- return new Pt(p);
3299
+ return new _Pt(p);
3300
3300
  }
3301
3301
  /**
3302
3302
  * ID string of this Pt
@@ -3347,7 +3347,7 @@ See https://github.com/williamngan/pts for details. */
3347
3347
  * Clone this Pt and return it as a new Pt.
3348
3348
  */
3349
3349
  clone() {
3350
- return new Pt(this);
3350
+ return new _Pt(this);
3351
3351
  }
3352
3352
  /**
3353
3353
  * Check if another Pt is equal to this Pt, within a threshold.
@@ -3366,7 +3366,7 @@ See https://github.com/williamngan/pts for details. */
3366
3366
  * @param args can be either a list of numbers, an array, a Pt, or an object with {x,y,z,w} properties
3367
3367
  */
3368
3368
  to(...args) {
3369
- let p = Util.getArgs(args);
3369
+ const p = Util.getArgs(args);
3370
3370
  for (let i = 0, len = Math.min(this.length, p.length); i < len; i++) {
3371
3371
  this[i] = p[i];
3372
3372
  }
@@ -3386,8 +3386,8 @@ See https://github.com/williamngan/pts for details. */
3386
3386
  * @param anchorFromPt If `true`, add it from this Pt's current position. Default is `false` which update the position from origin (0,0). See also [`Geom.rotate2D`](#link) for rotating a point from another anchor point.
3387
3387
  */
3388
3388
  toAngle(radian, magnitude, anchorFromPt = false) {
3389
- let m = magnitude != void 0 ? magnitude : this.magnitude();
3390
- let change = [Math.cos(radian) * m, Math.sin(radian) * m];
3389
+ const m = magnitude != void 0 ? magnitude : this.magnitude();
3390
+ const change = [Math.cos(radian) * m, Math.sin(radian) * m];
3391
3391
  return anchorFromPt ? this.add(change) : this.to(change);
3392
3392
  }
3393
3393
  /**
@@ -3397,7 +3397,7 @@ See https://github.com/williamngan/pts for details. */
3397
3397
  * @returns a resulting function that takes other parameters required in `fn`
3398
3398
  */
3399
3399
  op(fn) {
3400
- let self = this;
3400
+ const self = this;
3401
3401
  return (...params) => {
3402
3402
  return fn(self, ...params);
3403
3403
  };
@@ -3409,7 +3409,7 @@ See https://github.com/williamngan/pts for details. */
3409
3409
  * @returns an array of resulting functions
3410
3410
  */
3411
3411
  ops(fns) {
3412
- let _ops = [];
3412
+ const _ops = [];
3413
3413
  for (let i = 0, len = fns.length; i < len; i++) {
3414
3414
  _ops.push(this.op(fns[i]));
3415
3415
  }
@@ -3420,18 +3420,18 @@ See https://github.com/williamngan/pts for details. */
3420
3420
  * @param axis a string such as "xy" (use Const.xy) or an array to specify indices
3421
3421
  */
3422
3422
  $take(axis) {
3423
- let p = [];
3423
+ const p = [];
3424
3424
  for (let i = 0, len = axis.length; i < len; i++) {
3425
3425
  p.push(this[axis[i]] || 0);
3426
3426
  }
3427
- return new Pt(p);
3427
+ return new _Pt(p);
3428
3428
  }
3429
3429
  /**
3430
3430
  * Concatenate this Pt with addition dimensional values and return as a new Pt.
3431
3431
  * @param args can be either a list of numbers, an array, a Pt, or an object with {x,y,z,w} properties
3432
3432
  */
3433
3433
  $concat(...args) {
3434
- return new Pt(this.toArray().concat(Util.getArgs(args)));
3434
+ return new _Pt(this.toArray().concat(Util.getArgs(args)));
3435
3435
  }
3436
3436
  /**
3437
3437
  * Add scalar or vector values to this Pt.
@@ -3626,8 +3626,8 @@ See https://github.com/williamngan/pts for details. */
3626
3626
  * @param args can be either a list of numbers, an array, a Pt, or an object with {x,y,z,w} properties
3627
3627
  */
3628
3628
  $min(...args) {
3629
- let p = Util.getArgs(args);
3630
- let m = this.clone();
3629
+ const p = Util.getArgs(args);
3630
+ const m = this.clone();
3631
3631
  for (let i = 0, len = Math.min(this.length, p.length); i < len; i++) {
3632
3632
  m[i] = Math.min(this[i], p[i]);
3633
3633
  }
@@ -3638,8 +3638,8 @@ See https://github.com/williamngan/pts for details. */
3638
3638
  * @param args can be either a list of numbers, an array, a Pt, or an object with {x,y,z,w} properties
3639
3639
  */
3640
3640
  $max(...args) {
3641
- let p = Util.getArgs(args);
3642
- let m = this.clone();
3641
+ const p = Util.getArgs(args);
3642
+ const m = this.clone();
3643
3643
  for (let i = 0, len = Math.min(this.length, p.length); i < len; i++) {
3644
3644
  m[i] = Math.max(this[i], p[i]);
3645
3645
  }
@@ -3666,7 +3666,7 @@ See https://github.com/williamngan/pts for details. */
3666
3666
  * @param anchor optional anchor point to scale from
3667
3667
  */
3668
3668
  scale(scale, anchor) {
3669
- Geom.scale(this, scale, anchor || Pt.make(this.length, 0));
3669
+ Geom.scale(this, scale, anchor || _Pt.make(this.length, 0));
3670
3670
  return this;
3671
3671
  }
3672
3672
  /**
@@ -3676,7 +3676,7 @@ See https://github.com/williamngan/pts for details. */
3676
3676
  * @param axis optional string such as "yz" to specify a 2D plane
3677
3677
  */
3678
3678
  rotate2D(angle, anchor, axis) {
3679
- Geom.rotate2D(this, angle, anchor || Pt.make(this.length, 0), axis);
3679
+ Geom.rotate2D(this, angle, anchor || _Pt.make(this.length, 0), axis);
3680
3680
  return this;
3681
3681
  }
3682
3682
  /**
@@ -3686,7 +3686,7 @@ See https://github.com/williamngan/pts for details. */
3686
3686
  * @param axis optional string such as "yz" to specify a 2D plane
3687
3687
  */
3688
3688
  shear2D(scale, anchor, axis) {
3689
- Geom.shear2D(this, scale, anchor || Pt.make(this.length, 0), axis);
3689
+ Geom.shear2D(this, scale, anchor || _Pt.make(this.length, 0), axis);
3690
3690
  return this;
3691
3691
  }
3692
3692
  /**
@@ -3714,16 +3714,16 @@ See https://github.com/williamngan/pts for details. */
3714
3714
  * Convert this Pt to a Group as new Group([0,...], pt)
3715
3715
  */
3716
3716
  toGroup() {
3717
- return new Group(Pt.make(this.length), this.clone());
3717
+ return new Group(_Pt.make(this.length), this.clone());
3718
3718
  }
3719
3719
  /**
3720
3720
  * Convert this Pt to a Bound as new Group([0,...], pt)
3721
3721
  */
3722
3722
  toBound() {
3723
- return new Bound(Pt.make(this.length), this.clone());
3723
+ return new Bound(_Pt.make(this.length), this.clone());
3724
3724
  }
3725
3725
  };
3726
- var Group = class extends Array {
3726
+ var Group = class _Group extends Array {
3727
3727
  /**
3728
3728
  * Create a Group by passing an array of [`Pt`](#link). You may also create a Group using [`Group.fromArray`](#link) or [`Group.fromPtArray`](#link).
3729
3729
  * @param args an array of Pts
@@ -3792,7 +3792,7 @@ See https://github.com/williamngan/pts for details. */
3792
3792
  * Depp clone this group and its Pts.
3793
3793
  */
3794
3794
  clone() {
3795
- let group = new Group();
3795
+ const group = new _Group();
3796
3796
  for (let i = 0, len = this.length; i < len; i++) {
3797
3797
  group.push(this[i].clone());
3798
3798
  }
@@ -3804,9 +3804,9 @@ See https://github.com/williamngan/pts for details. */
3804
3804
  * @example `Group.fromArray( [[1,2], [3,4], [5,6]] )`
3805
3805
  */
3806
3806
  static fromArray(list) {
3807
- let g = new Group();
3808
- for (let li of list) {
3809
- let p = li instanceof Pt ? li : new Pt(li);
3807
+ const g = new _Group();
3808
+ for (const li of list) {
3809
+ const p = li instanceof Pt ? li : new Pt(li);
3810
3810
  g.push(p);
3811
3811
  }
3812
3812
  return g;
@@ -3816,7 +3816,7 @@ See https://github.com/williamngan/pts for details. */
3816
3816
  * @param list an Iterable<Pt>
3817
3817
  */
3818
3818
  static fromPtArray(list) {
3819
- return Group.from(list);
3819
+ return _Group.from(list);
3820
3820
  }
3821
3821
  /**
3822
3822
  * Split this Group into an array of sub-groups.
@@ -3825,7 +3825,7 @@ See https://github.com/williamngan/pts for details. */
3825
3825
  * @param loopBack if `true`, always go through the array till the end and loop back to the beginning to complete the segments if needed
3826
3826
  */
3827
3827
  split(chunkSize, stride, loopBack = false) {
3828
- let sp = Util.split(this, chunkSize, stride, loopBack);
3828
+ const sp = Util.split(this, chunkSize, stride, loopBack);
3829
3829
  return sp;
3830
3830
  }
3831
3831
  /**
@@ -3834,7 +3834,7 @@ See https://github.com/williamngan/pts for details. */
3834
3834
  * @param index the index position to insert into
3835
3835
  */
3836
3836
  insert(pts, index = 0) {
3837
- Group.prototype.splice.apply(this, [index, 0, ...pts]);
3837
+ _Group.prototype.splice.apply(this, [index, 0, ...pts]);
3838
3838
  return this;
3839
3839
  }
3840
3840
  /**
@@ -3844,8 +3844,8 @@ See https://github.com/williamngan/pts for details. */
3844
3844
  * @returns The items that are removed.
3845
3845
  */
3846
3846
  remove(index = 0, count = 1) {
3847
- let param = index < 0 ? [index * -1 - 1, count] : [index, count];
3848
- return Group.prototype.splice.apply(this, param);
3847
+ const param = index < 0 ? [index * -1 - 1, count] : [index, count];
3848
+ return _Group.prototype.splice.apply(this, param);
3849
3849
  }
3850
3850
  /**
3851
3851
  * Split this group into an array of sub-group segments.
@@ -3896,7 +3896,7 @@ See https://github.com/williamngan/pts for details. */
3896
3896
  * @returns a resulting function that takes other parameters required in `fn`
3897
3897
  */
3898
3898
  op(fn) {
3899
- let self = this;
3899
+ const self = this;
3900
3900
  return (...params) => {
3901
3901
  return fn(self, ...params);
3902
3902
  };
@@ -3908,7 +3908,7 @@ See https://github.com/williamngan/pts for details. */
3908
3908
  * @returns an array of resulting functions
3909
3909
  */
3910
3910
  ops(fns) {
3911
- let _ops = [];
3911
+ const _ops = [];
3912
3912
  for (let i = 0, len = fns.length; i < len; i++) {
3913
3913
  _ops.push(this.op(fns[i]));
3914
3914
  }
@@ -3920,9 +3920,9 @@ See https://github.com/williamngan/pts for details. */
3920
3920
  */
3921
3921
  interpolate(t) {
3922
3922
  t = Num.clamp(t, 0, 1);
3923
- let chunk = this.length - 1;
3924
- let tc = 1 / (this.length - 1);
3925
- let idx = Math.floor(t / tc);
3923
+ const chunk = this.length - 1;
3924
+ const tc = 1 / (this.length - 1);
3925
+ const idx = Math.floor(t / tc);
3926
3926
  return Geom.interpolate(this[idx], this[Math.min(this.length - 1, idx + 1)], (t - idx * tc) * chunk);
3927
3927
  }
3928
3928
  /**
@@ -3937,7 +3937,7 @@ See https://github.com/williamngan/pts for details. */
3937
3937
  * @param args can be either a list of numbers, an array, a Pt, or an object with {x,y,z,w} properties
3938
3938
  */
3939
3939
  moveTo(...args) {
3940
- let d = new Pt(Util.getArgs(args)).subtract(this[0]);
3940
+ const d = new Pt(Util.getArgs(args)).subtract(this[0]);
3941
3941
  this.moveBy(d);
3942
3942
  return this;
3943
3943
  }
@@ -4085,7 +4085,7 @@ See https://github.com/williamngan/pts for details. */
4085
4085
  return "Group[ " + this.reduce((p, c) => p + c.toString() + " ", "") + " ]";
4086
4086
  }
4087
4087
  };
4088
- var Bound = class extends Group {
4088
+ var Bound = class _Bound extends Group {
4089
4089
  /**
4090
4090
  * Create a Bound. This is similar to the Group constructor. You can also create a Bound via the static function [`Bound.fromGroup`](#link), or alternatively via the [Group.toBound](#link) function.
4091
4091
  * @param args a list of Pt as parameters
@@ -4106,7 +4106,7 @@ See https://github.com/williamngan/pts for details. */
4106
4106
  * @returns a Bound object
4107
4107
  */
4108
4108
  static fromBoundingRect(rect) {
4109
- let b = new Bound(new Pt(rect.left || 0, rect.top || 0), new Pt(rect.right || 0, rect.bottom || 0));
4109
+ const b = new _Bound(new Pt(rect.left || 0, rect.top || 0), new Pt(rect.right || 0, rect.bottom || 0));
4110
4110
  if (rect.width && rect.height)
4111
4111
  b.size = new Pt(rect.width, rect.height);
4112
4112
  return b;
@@ -4116,10 +4116,10 @@ See https://github.com/williamngan/pts for details. */
4116
4116
  * @param g a Group or an Iterable<PtLike>
4117
4117
  */
4118
4118
  static fromGroup(g) {
4119
- let _g = Util.iterToArray(g);
4119
+ const _g = Util.iterToArray(g);
4120
4120
  if (_g.length < 2)
4121
4121
  throw new Error("Cannot create a Bound from a group that has less than 2 Pt");
4122
- return new Bound(_g[0], _g[_g.length - 1]);
4122
+ return new _Bound(_g[0], _g[_g.length - 1]);
4123
4123
  }
4124
4124
  /**
4125
4125
  * Initiate the bound's properties.
@@ -4130,8 +4130,8 @@ See https://github.com/williamngan/pts for details. */
4130
4130
  this._inited = true;
4131
4131
  }
4132
4132
  if (this.p1 && this.p2) {
4133
- let a = this.p1;
4134
- let b = this.p2;
4133
+ const a = this.p1;
4134
+ const b = this.p2;
4135
4135
  this.topLeft = a.$min(b);
4136
4136
  this._bottomRight = a.$max(b);
4137
4137
  this._updateSize();
@@ -4142,7 +4142,7 @@ See https://github.com/williamngan/pts for details. */
4142
4142
  * Clone this bound and return a new one.
4143
4143
  */
4144
4144
  clone() {
4145
- return new Bound(this._topLeft.clone(), this._bottomRight.clone());
4145
+ return new _Bound(this._topLeft.clone(), this._bottomRight.clone());
4146
4146
  }
4147
4147
  /**
4148
4148
  * Recalculte size and center.
@@ -4175,7 +4175,7 @@ See https://github.com/williamngan/pts for details. */
4175
4175
  * Recalculate based on center position and size.
4176
4176
  */
4177
4177
  _updatePosFromCenter() {
4178
- let half = this._size.$multiply(0.5);
4178
+ const half = this._size.$multiply(0.5);
4179
4179
  this._topLeft = this._center.$subtract(half);
4180
4180
  this._bottomRight = this._center.$add(half);
4181
4181
  }
@@ -4318,10 +4318,12 @@ See https://github.com/williamngan/pts for details. */
4318
4318
  click: "click",
4319
4319
  keydown: "keydown",
4320
4320
  keyup: "keyup",
4321
+ pointerdown: "pointerdown",
4322
+ pointerup: "pointerup",
4321
4323
  contextmenu: "contextmenu",
4322
4324
  all: "all"
4323
4325
  };
4324
- var _UI = class {
4326
+ var _UI = class _UI {
4325
4327
  /**
4326
4328
  * Create an UI element. You may also create a new UI using one of the static helper like [`UI.fromRectangle`](#link) or [`UI.fromCircle`](#link).
4327
4329
  * @param group a Group or an Iterable<PtLike> that defines the UI's appearance
@@ -4557,8 +4559,8 @@ See https://github.com/williamngan/pts for details. */
4557
4559
  }
4558
4560
  }
4559
4561
  };
4562
+ _UI._counter = 0;
4560
4563
  var UI = _UI;
4561
- UI._counter = 0;
4562
4564
  var UIButton = class extends UI {
4563
4565
  /**
4564
4566
  * Create an UIButton. A button has 2 states, "clicks" (number) and "hover" (boolean), which you can access through [`UI.state`](#link) function. You may also create a new UIButton using one of the static helper like [`UI.fromRectangle`](#link) or [`UI.fromCircle`](#link).
@@ -4583,7 +4585,7 @@ See https://github.com/williamngan/pts for details. */
4583
4585
  if (hover && !this._states.hover) {
4584
4586
  this.state("hover", true);
4585
4587
  UI._trigger(this._actions[UA.enter], this, pt, UA.enter, evt);
4586
- var _capID = this.hold(UA.move);
4588
+ let _capID = this.hold(UA.move);
4587
4589
  this._hoverID = this.on(UA.move, (t, p) => {
4588
4590
  if (!this._within(p) && !this.state("dragging")) {
4589
4591
  this.state("hover", false);
@@ -4634,7 +4636,7 @@ See https://github.com/williamngan/pts for details. */
4634
4636
  * @returns id numbers that refer to enter/leave handlers, for use in [`UIButton.offHover`](#link) or [`UI.off`](#link).
4635
4637
  */
4636
4638
  onHover(enter, leave) {
4637
- var ids = [void 0, void 0];
4639
+ let ids = [void 0, void 0];
4638
4640
  if (enter)
4639
4641
  ids[0] = this.on(UIPointerActions.enter, enter);
4640
4642
  if (leave)
@@ -4648,7 +4650,7 @@ See https://github.com/williamngan/pts for details. */
4648
4650
  * @returns an array of booleans indicating whether the handlers were removed successfully
4649
4651
  */
4650
4652
  offHover(enterID, leaveID) {
4651
- var s = [false, false];
4653
+ let s = [false, false];
4652
4654
  if (enterID === void 0 || enterID >= 0)
4653
4655
  s[0] = this.off(UIPointerActions.enter, enterID);
4654
4656
  if (leaveID === void 0 || leaveID >= 0)
@@ -4791,9 +4793,9 @@ See https://github.com/williamngan/pts for details. */
4791
4793
  * @param player an [`IPlayer`](#link) object with animate function, or a callback function `fn(time, ftime)`.
4792
4794
  */
4793
4795
  add(p) {
4794
- let player = typeof p == "function" ? { animate: p } : p;
4795
- let k = this.playerCount++;
4796
- let pid = this.id + k;
4796
+ const player = typeof p == "function" ? { animate: p } : p;
4797
+ const k = this.playerCount++;
4798
+ const pid = player.animateID || this.id + k;
4797
4799
  this.players[pid] = player;
4798
4800
  player.animateID = pid;
4799
4801
  if (player.resize && this.bound.inited)
@@ -4860,7 +4862,7 @@ See https://github.com/williamngan/pts for details. */
4860
4862
  if (this._refresh)
4861
4863
  this.clear();
4862
4864
  if (this._isReady) {
4863
- for (let k in this.players) {
4865
+ for (const k in this.players) {
4864
4866
  if (this.players[k].animate)
4865
4867
  this.players[k].animate(time, this._time.diff, this);
4866
4868
  }
@@ -4978,7 +4980,7 @@ See https://github.com/williamngan/pts for details. */
4978
4980
  * Get the mouse or touch pointer that stores the last action.
4979
4981
  */
4980
4982
  get pointer() {
4981
- let p = this._pointer.clone();
4983
+ const p = this._pointer.clone();
4982
4984
  p.id = this._pointer.id;
4983
4985
  return p;
4984
4986
  }
@@ -5030,9 +5032,13 @@ See https://github.com/williamngan/pts for details. */
5030
5032
  this._mouseOut = this._mouseOut.bind(this);
5031
5033
  this._mouseMove = this._mouseMove.bind(this);
5032
5034
  this._mouseClick = this._mouseClick.bind(this);
5035
+ this._pointerDown = this._pointerDown.bind(this);
5036
+ this._pointerUp = this._pointerUp.bind(this);
5033
5037
  this._contextMenu = this._contextMenu.bind(this);
5034
5038
  this.bindCanvas("mousedown", this._mouseDown, {}, customTarget);
5039
+ this.bindCanvas("pointerdown", this._pointerDown, {}, customTarget);
5035
5040
  this.bindCanvas("mouseup", this._mouseUp, {}, customTarget);
5041
+ this.bindCanvas("pointerup", this._pointerUp, {}, customTarget);
5036
5042
  this.bindCanvas("mouseover", this._mouseOver, {}, customTarget);
5037
5043
  this.bindCanvas("mouseout", this._mouseOut, {}, customTarget);
5038
5044
  this.bindCanvas("mousemove", this._mouseMove, {}, customTarget);
@@ -5041,7 +5047,9 @@ See https://github.com/williamngan/pts for details. */
5041
5047
  this._hasMouse = true;
5042
5048
  } else {
5043
5049
  this.unbindCanvas("mousedown", this._mouseDown, {}, customTarget);
5050
+ this.unbindCanvas("pointerdown", this._pointerDown, {}, customTarget);
5044
5051
  this.unbindCanvas("mouseup", this._mouseUp, {}, customTarget);
5052
+ this.unbindCanvas("pointerup", this._pointerUp, {}, customTarget);
5045
5053
  this.unbindCanvas("mouseover", this._mouseOver, {}, customTarget);
5046
5054
  this.unbindCanvas("mouseout", this._mouseOut, {}, customTarget);
5047
5055
  this.unbindCanvas("mousemove", this._mouseMove, {}, customTarget);
@@ -5099,9 +5107,9 @@ See https://github.com/williamngan/pts for details. */
5099
5107
  touchesToPoints(evt, which = "touches") {
5100
5108
  if (!evt || !evt[which])
5101
5109
  return [];
5102
- let ts = [];
5103
- for (var i = 0; i < evt[which].length; i++) {
5104
- let t = evt[which].item(i);
5110
+ const ts = [];
5111
+ for (let i = 0; i < evt[which].length; i++) {
5112
+ const t = evt[which].item(i);
5105
5113
  ts.push(new Pt(t.pageX - this.bound.topLeft.x, t.pageY - this.bound.topLeft.y));
5106
5114
  }
5107
5115
  return ts;
@@ -5117,9 +5125,9 @@ See https://github.com/williamngan/pts for details. */
5117
5125
  return;
5118
5126
  let px = 0, py = 0;
5119
5127
  if (evt instanceof MouseEvent) {
5120
- for (let k in this.players) {
5128
+ for (const k in this.players) {
5121
5129
  if (this.players.hasOwnProperty(k)) {
5122
- let v = this.players[k];
5130
+ const v = this.players[k];
5123
5131
  px = evt.pageX - this.outerBound.x;
5124
5132
  py = evt.pageY - this.outerBound.y;
5125
5133
  if (v.action)
@@ -5127,11 +5135,11 @@ See https://github.com/williamngan/pts for details. */
5127
5135
  }
5128
5136
  }
5129
5137
  } else {
5130
- for (let k in this.players) {
5138
+ for (const k in this.players) {
5131
5139
  if (this.players.hasOwnProperty(k)) {
5132
- let v = this.players[k];
5133
- let c = evt.changedTouches && evt.changedTouches.length > 0;
5134
- let touch = evt.changedTouches.item(0);
5140
+ const v = this.players[k];
5141
+ const c = evt.changedTouches && evt.changedTouches.length > 0;
5142
+ const touch = evt.changedTouches.item(0);
5135
5143
  px = c ? touch.pageX - this.outerBound.x : 0;
5136
5144
  py = c ? touch.pageY - this.outerBound.y : 0;
5137
5145
  if (v.action)
@@ -5153,6 +5161,13 @@ See https://github.com/williamngan/pts for details. */
5153
5161
  this._pressed = true;
5154
5162
  return false;
5155
5163
  }
5164
+ _pointerDown(evt) {
5165
+ this._mouseAction(UIPointerActions.pointerdown, evt);
5166
+ if (evt.target instanceof Element) {
5167
+ evt.target.setPointerCapture(evt.pointerId);
5168
+ }
5169
+ return false;
5170
+ }
5156
5171
  /**
5157
5172
  * MouseUp handler.
5158
5173
  * @param evt
@@ -5167,6 +5182,16 @@ See https://github.com/williamngan/pts for details. */
5167
5182
  this._dragged = false;
5168
5183
  return false;
5169
5184
  }
5185
+ _pointerUp(evt) {
5186
+ this._mouseAction(UIPointerActions.pointerup, evt);
5187
+ if (evt.target instanceof Element) {
5188
+ evt.target.releasePointerCapture(evt.pointerId);
5189
+ if (this._dragged)
5190
+ this._mouseAction(UIPointerActions.drop, evt);
5191
+ this._dragged = false;
5192
+ }
5193
+ return false;
5194
+ }
5170
5195
  /**
5171
5196
  * MouseMove handler.
5172
5197
  * @param evt
@@ -5245,9 +5270,9 @@ See https://github.com/williamngan/pts for details. */
5245
5270
  _keyboardAction(type, evt) {
5246
5271
  if (!this.isPlaying)
5247
5272
  return;
5248
- for (let k in this.players) {
5273
+ for (const k in this.players) {
5249
5274
  if (this.players.hasOwnProperty(k)) {
5250
- let v = this.players[k];
5275
+ const v = this.players[k];
5251
5276
  if (v.action)
5252
5277
  v.action(type, evt.shiftKey ? 1 : 0, evt.altKey ? 1 : 0, evt);
5253
5278
  }
@@ -5510,7 +5535,7 @@ See https://github.com/williamngan/pts for details. */
5510
5535
  __export(Image_exports, {
5511
5536
  Img: () => Img
5512
5537
  });
5513
- var Img = class {
5538
+ var Img = class _Img {
5514
5539
  /**
5515
5540
  * Create an Img
5516
5541
  * @param editable Specify if you want to manipulate pixels of this image. Default is `false`.
@@ -5535,7 +5560,7 @@ See https://github.com/williamngan/pts for details. */
5535
5560
  * @param ready An optional ready callback function
5536
5561
  */
5537
5562
  static load(src, editable = false, space, ready) {
5538
- const img = new Img(editable, space);
5563
+ const img = new _Img(editable, space);
5539
5564
  img.load(src).then((res) => {
5540
5565
  if (ready)
5541
5566
  ready(res);
@@ -5551,7 +5576,7 @@ See https://github.com/williamngan/pts for details. */
5551
5576
  */
5552
5577
  static loadAsync(src, editable = false, space) {
5553
5578
  return __async(this, null, function* () {
5554
- const img = yield new Img(editable, space).load(src);
5579
+ const img = yield new _Img(editable, space).load(src);
5555
5580
  return img;
5556
5581
  });
5557
5582
  }
@@ -5565,7 +5590,7 @@ See https://github.com/williamngan/pts for details. */
5565
5590
  */
5566
5591
  static loadPattern(src, space, repeat = "repeat", editable = false) {
5567
5592
  return __async(this, null, function* () {
5568
- const img = yield Img.loadAsync(src, editable, space);
5593
+ const img = yield _Img.loadAsync(src, editable, space);
5569
5594
  return img.pattern(repeat);
5570
5595
  });
5571
5596
  }
@@ -5576,7 +5601,7 @@ See https://github.com/williamngan/pts for details. */
5576
5601
  * @param scale Optionally set a specific pixel scale (density) of the image canvas.
5577
5602
  */
5578
5603
  static blank(size, space, scale) {
5579
- let img = new Img(true, space);
5604
+ let img = new _Img(true, space);
5580
5605
  const s = scale ? scale : space.pixelScale;
5581
5606
  img.initCanvas(size[0], size[1], s);
5582
5607
  return img;
@@ -5682,7 +5707,7 @@ See https://github.com/williamngan/pts for details. */
5682
5707
  */
5683
5708
  pixel(p, rescale = true) {
5684
5709
  const s = typeof rescale == "number" ? rescale : rescale ? this._scale : 1;
5685
- return Img.getPixel(this._data, [p[0] * s, p[1] * s]);
5710
+ return _Img.getPixel(this._data, [p[0] * s, p[1] * s]);
5686
5711
  }
5687
5712
  /**
5688
5713
  * Given an ImaegData object and a position, return the RGBA pixel value at that position.
@@ -5747,7 +5772,7 @@ See https://github.com/williamngan/pts for details. */
5747
5772
  */
5748
5773
  static fromBlob(blob, editable = false, space) {
5749
5774
  let url = URL.createObjectURL(blob);
5750
- return new Img(editable, space).load(url);
5775
+ return new _Img(editable, space).load(url);
5751
5776
  }
5752
5777
  /**
5753
5778
  * Convert ImageData object to a Blob, which you can then create an Img instance via [`Img.fromBlob`](#link). Note that the resulting image's dimensions will not account for pixel density.
@@ -5875,8 +5900,8 @@ See https://github.com/williamngan/pts for details. */
5875
5900
  this._bgcolor = "#e1e9f0";
5876
5901
  this._offscreen = false;
5877
5902
  this._initialResize = false;
5878
- var _selector = null;
5879
- var _existed = false;
5903
+ let _selector = null;
5904
+ let _existed = false;
5880
5905
  this.id = "pt";
5881
5906
  if (elem instanceof Element) {
5882
5907
  _selector = elem;
@@ -5913,7 +5938,7 @@ See https://github.com/williamngan/pts for details. */
5913
5938
  * @param id element id attribute
5914
5939
  */
5915
5940
  _createElement(elem = "div", id) {
5916
- let d = document.createElement(elem);
5941
+ const d = document.createElement(elem);
5917
5942
  d.setAttribute("id", id);
5918
5943
  return d;
5919
5944
  }
@@ -5928,7 +5953,7 @@ See https://github.com/williamngan/pts for details. */
5928
5953
  this._resizeHandler(null);
5929
5954
  this.clear(this._bgcolor);
5930
5955
  this._canvas.dispatchEvent(new Event("ready"));
5931
- for (let k in this.players) {
5956
+ for (const k in this.players) {
5932
5957
  if (this.players.hasOwnProperty(k)) {
5933
5958
  if (this.players[k].start)
5934
5959
  this.players[k].start(this.bound.clone(), this);
@@ -5948,8 +5973,8 @@ See https://github.com/williamngan/pts for details. */
5948
5973
  this._bgcolor = opt.bgcolor ? opt.bgcolor : "transparent";
5949
5974
  this.autoResize = opt.resize != void 0 ? opt.resize : false;
5950
5975
  if (opt.retina !== false) {
5951
- let r1 = window ? window.devicePixelRatio || 1 : 1;
5952
- let r2 = this._ctx.webkitBackingStorePixelRatio || this._ctx.mozBackingStorePixelRatio || this._ctx.msBackingStorePixelRatio || this._ctx.oBackingStorePixelRatio || this._ctx.backingStorePixelRatio || 1;
5976
+ const r1 = window ? window.devicePixelRatio || 1 : 1;
5977
+ const r2 = this._ctx.webkitBackingStorePixelRatio || this._ctx.mozBackingStorePixelRatio || this._ctx.msBackingStorePixelRatio || this._ctx.oBackingStorePixelRatio || this._ctx.backingStorePixelRatio || 1;
5953
5978
  this._pixelScale = Math.max(1, r1 / r2);
5954
5979
  }
5955
5980
  if (opt.offscreen) {
@@ -6003,9 +6028,9 @@ See https://github.com/williamngan/pts for details. */
6003
6028
  this._offCtx.scale(this._pixelScale, this._pixelScale);
6004
6029
  }
6005
6030
  }
6006
- for (let k in this.players) {
6031
+ for (const k in this.players) {
6007
6032
  if (this.players.hasOwnProperty(k)) {
6008
- let p = this.players[k];
6033
+ const p = this.players[k];
6009
6034
  if (p.resize)
6010
6035
  p.resize(this.bound, evt);
6011
6036
  }
@@ -6022,9 +6047,9 @@ See https://github.com/williamngan/pts for details. */
6022
6047
  _resizeHandler(evt) {
6023
6048
  if (!window)
6024
6049
  return;
6025
- let b = this._autoResize || this._initialResize ? this._container.getBoundingClientRect() : this._canvas.getBoundingClientRect();
6050
+ const b = this._autoResize || this._initialResize ? this._container.getBoundingClientRect() : this._canvas.getBoundingClientRect();
6026
6051
  if (b) {
6027
- let box = Bound.fromBoundingRect(b);
6052
+ const box = Bound.fromBoundingRect(b);
6028
6053
  box.center = box.center.add(window.pageXOffset, window.pageYOffset);
6029
6054
  this.resize(box, evt);
6030
6055
  }
@@ -6167,14 +6192,14 @@ See https://github.com/williamngan/pts for details. */
6167
6192
  * @example `let rec = space.recorder(true); rec.start(); setTimeout( () => rec.stop(), 5000); // record 5s of video and download the file`
6168
6193
  */
6169
6194
  recorder(downloadOrCallback, filetype = "webm", bitrate = 15e6) {
6170
- let stream = this._canvas.captureStream();
6195
+ const stream = this._canvas.captureStream();
6171
6196
  const recorder = new MediaRecorder(stream, { mimeType: `video/${filetype}`, bitsPerSecond: bitrate });
6172
6197
  recorder.ondataavailable = function(d) {
6173
- let url = URL.createObjectURL(new Blob([d.data], { type: `video/${filetype}` }));
6198
+ const url = URL.createObjectURL(new Blob([d.data], { type: `video/${filetype}` }));
6174
6199
  if (typeof downloadOrCallback === "function") {
6175
6200
  downloadOrCallback(url);
6176
6201
  } else if (downloadOrCallback) {
6177
- let a = document.createElement("a");
6202
+ const a = document.createElement("a");
6178
6203
  a.href = url;
6179
6204
  a.download = `canvas_video.${filetype}`;
6180
6205
  a.click();
@@ -6184,7 +6209,7 @@ See https://github.com/williamngan/pts for details. */
6184
6209
  return recorder;
6185
6210
  }
6186
6211
  };
6187
- var CanvasForm = class extends VisualForm {
6212
+ var CanvasForm = class _CanvasForm extends VisualForm {
6188
6213
  /**
6189
6214
  * Create a new CanvasForm. You may also use [`CanvasSpace.getForm()`](#link) to get the default form.
6190
6215
  * @param space an instance of CanvasSpace
@@ -6261,20 +6286,20 @@ See https://github.com/williamngan/pts for details. */
6261
6286
  }
6262
6287
  }
6263
6288
  /**
6264
- * Set current alpha value.
6265
- * @example `form.alpha(0.6)`
6266
- * @param a alpha value between 0 and 1
6267
- */
6289
+ * Set current alpha value.
6290
+ * @example `form.alpha(0.6)`
6291
+ * @param a alpha value between 0 and 1
6292
+ */
6268
6293
  alpha(a) {
6269
6294
  this._ctx.globalAlpha = a;
6270
6295
  this._style.globalAlpha = a;
6271
6296
  return this;
6272
6297
  }
6273
6298
  /**
6274
- * Set current fill style. Provide a valid color string such as `"#FFF"` or `"rgba(255,0,100,0.5)"` or `false` to specify no fill color.
6275
- * @example `form.fill("#F90")`, `form.fill("rgba(0,0,0,.5")`, `form.fill(false)`
6276
- * @param c fill color which can be as color, gradient, or pattern. (See [canvas documentation](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/fillStyle))
6277
- */
6299
+ * Set current fill style. Provide a valid color string such as `"#FFF"` or `"rgba(255,0,100,0.5)"` or `false` to specify no fill color.
6300
+ * @example `form.fill("#F90")`, `form.fill("rgba(0,0,0,.5")`, `form.fill(false)`
6301
+ * @param c fill color which can be as color, gradient, or pattern. (See [canvas documentation](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/fillStyle))
6302
+ */
6278
6303
  fill(c) {
6279
6304
  if (typeof c == "boolean") {
6280
6305
  this.filled = c;
@@ -6286,21 +6311,21 @@ See https://github.com/williamngan/pts for details. */
6286
6311
  return this;
6287
6312
  }
6288
6313
  /**
6289
- * Set current fill style and remove stroke style.
6290
- * @param c fill color which can be as color, gradient, or pattern. (See [canvas documentation](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/fillStyle))
6291
- */
6314
+ * Set current fill style and remove stroke style.
6315
+ * @param c fill color which can be as color, gradient, or pattern. (See [canvas documentation](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/fillStyle))
6316
+ */
6292
6317
  fillOnly(c) {
6293
6318
  this.stroke(false);
6294
6319
  return this.fill(c);
6295
6320
  }
6296
6321
  /**
6297
- * Set current stroke style. Provide a valid color string or `false` to specify no stroke color.
6298
- * @example `form.stroke("#F90")`, `form.stroke("rgba(0,0,0,.5")`, `form.stroke(false)`, `form.stroke("#000", 0.5, 'round', 'square')`
6299
- * @param c stroke color which can be as color, gradient, or pattern. (See [canvas documentation](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/strokeStyle))
6300
- * @param width Optional value (can be floating point) to set line width
6301
- * @param linejoin Optional string to set line joint style. Can be "miter", "bevel", or "round".
6302
- * @param linecap Optional string to set line cap style. Can be "butt", "round", or "square".
6303
- */
6322
+ * Set current stroke style. Provide a valid color string or `false` to specify no stroke color.
6323
+ * @example `form.stroke("#F90")`, `form.stroke("rgba(0,0,0,.5")`, `form.stroke(false)`, `form.stroke("#000", 0.5, 'round', 'square')`
6324
+ * @param c stroke color which can be as color, gradient, or pattern. (See [canvas documentation](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/strokeStyle))
6325
+ * @param width Optional value (can be floating point) to set line width
6326
+ * @param linejoin Optional string to set line joint style. Can be "miter", "bevel", or "round".
6327
+ * @param linecap Optional string to set line cap style. Can be "butt", "round", or "square".
6328
+ */
6304
6329
  stroke(c, width, linejoin, linecap) {
6305
6330
  if (typeof c == "boolean") {
6306
6331
  this.stroked = c;
@@ -6324,24 +6349,24 @@ See https://github.com/williamngan/pts for details. */
6324
6349
  return this;
6325
6350
  }
6326
6351
  /**
6327
- * Set stroke style and remove fill style.
6328
- * @param c stroke color which can be as color, gradient, or pattern. (See [canvas documentation](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/strokeStyle))
6329
- * @param width Optional value (can be floating point) to set line width
6330
- * @param linejoin Optional string to set line joint style. Can be "miter", "bevel", or "round".
6331
- * @param linecap Optional string to set line cap style. Can be "butt", "round", or "square".
6332
- */
6352
+ * Set stroke style and remove fill style.
6353
+ * @param c stroke color which can be as color, gradient, or pattern. (See [canvas documentation](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/strokeStyle))
6354
+ * @param width Optional value (can be floating point) to set line width
6355
+ * @param linejoin Optional string to set line joint style. Can be "miter", "bevel", or "round".
6356
+ * @param linecap Optional string to set line cap style. Can be "butt", "round", or "square".
6357
+ */
6333
6358
  strokeOnly(c, width, linejoin, linecap) {
6334
6359
  this.fill(false);
6335
6360
  return this.stroke(c, width, linejoin, linecap);
6336
6361
  }
6337
6362
  /**
6338
- * A convenient function to apply fill and/or stroke after custom drawings using canvas context (eg, `form.ctx.ellipse(...)`).
6339
- * You don't need to call this function if you're using Pts' drawing functions like `form.point` or `form.rect`
6340
- * @param filled apply fill when set to `true`
6341
- * @param stroked apply stroke when set to `true`
6342
- * @param strokeWidth optionally set a stroke width
6343
- * @example `form.ctx.beginPath(); form.ctx.ellipse(...); form.applyFillStroke();`
6344
- */
6363
+ * A convenient function to apply fill and/or stroke after custom drawings using canvas context (eg, `form.ctx.ellipse(...)`).
6364
+ * You don't need to call this function if you're using Pts' drawing functions like `form.point` or `form.rect`
6365
+ * @param filled apply fill when set to `true`
6366
+ * @param stroked apply stroke when set to `true`
6367
+ * @param strokeWidth optionally set a stroke width
6368
+ * @example `form.ctx.beginPath(); form.ctx.ellipse(...); form.applyFillStroke();`
6369
+ */
6345
6370
  applyFillStroke(filled = true, stroked = true, strokeWidth = 1) {
6346
6371
  if (filled) {
6347
6372
  if (typeof filled === "string")
@@ -6356,22 +6381,22 @@ See https://github.com/williamngan/pts for details. */
6356
6381
  return this;
6357
6382
  }
6358
6383
  /**
6359
- * This function takes an array of gradient colors, and returns a function to define the areas of the gradient fill. See demo code in [CanvasForm.gradient](https://ptsjs.org/demo/?name=canvasform.textBox).
6360
- * @param stops an array of gradient stops. This can be an array of colors `["#f00", "#0f0", ...]` for evenly distributed gradient, or an array of [stop, color] like `[[0.1, "#f00"], [0.7, "#0f0"]]`
6361
- * @returns a function that takes 1 or 2 `Group` as parameters. Use a single `Group` to specify a rectangular area for linear gradient, or use 2 `Groups` to specify 2 `Circles` for radial gradient.
6362
- * @example `c1 = Circle.fromCenter(...); grad = form.gradient(["#f00", "#00f"]); form.fill( grad( c1, c2 ) ).circle( c1 )`
6363
- */
6384
+ * This function takes an array of gradient colors, and returns a function to define the areas of the gradient fill. See demo code in [CanvasForm.gradient](https://ptsjs.org/demo/?name=canvasform.textBox).
6385
+ * @param stops an array of gradient stops. This can be an array of colors `["#f00", "#0f0", ...]` for evenly distributed gradient, or an array of [stop, color] like `[[0.1, "#f00"], [0.7, "#0f0"]]`
6386
+ * @returns a function that takes 1 or 2 `Group` as parameters. Use a single `Group` to specify a rectangular area for linear gradient, or use 2 `Groups` to specify 2 `Circles` for radial gradient.
6387
+ * @example `c1 = Circle.fromCenter(...); grad = form.gradient(["#f00", "#00f"]); form.fill( grad( c1, c2 ) ).circle( c1 )`
6388
+ */
6364
6389
  gradient(stops) {
6365
- let vals = [];
6390
+ const vals = [];
6366
6391
  if (stops.length < 2)
6367
6392
  stops.push([0.99, "#000"], [1, "#000"]);
6368
6393
  for (let i = 0, len = stops.length; i < len; i++) {
6369
- let t = typeof stops[i] === "string" ? i * (1 / (stops.length - 1)) : stops[i][0];
6370
- let v = typeof stops[i] === "string" ? stops[i] : stops[i][1];
6394
+ const t = typeof stops[i] === "string" ? i * (1 / (stops.length - 1)) : stops[i][0];
6395
+ const v = typeof stops[i] === "string" ? stops[i] : stops[i][1];
6371
6396
  vals.push([t, v]);
6372
6397
  }
6373
6398
  return (area1, area2) => {
6374
- let grad = area2 ? this._ctx.createRadialGradient(area1[0][0], area1[0][1], Math.abs(area1[1][0]), area2[0][0], area2[0][1], Math.abs(area2[1][0])) : this._ctx.createLinearGradient(area1[0][0], area1[0][1], area1[1][0], area1[1][1]);
6399
+ const grad = area2 ? this._ctx.createRadialGradient(area1[0][0], area1[0][1], Math.abs(area1[1][0]), area2[0][0], area2[0][1], Math.abs(area2[1][0])) : this._ctx.createLinearGradient(area1[0][0], area1[0][1], area1[1][0], area1[1][1]);
6375
6400
  for (let i = 0, len = vals.length; i < len; i++) {
6376
6401
  grad.addColorStop(vals[i][0], vals[i][1]);
6377
6402
  }
@@ -6379,26 +6404,26 @@ See https://github.com/williamngan/pts for details. */
6379
6404
  };
6380
6405
  }
6381
6406
  /**
6382
- * Set composite operation (also known as blend mode). You can also call this function without parameters to get back to default 'source-over' mode. See [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalCompositeOperation) for the full list of operations you can use.
6383
- * @param mode a composite operation such as 'lighten', 'multiply', 'overlay', and 'color-burn'.
6384
- */
6407
+ * Set composite operation (also known as blend mode). You can also call this function without parameters to get back to default 'source-over' mode. See [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalCompositeOperation) for the full list of operations you can use.
6408
+ * @param mode a composite operation such as 'lighten', 'multiply', 'overlay', and 'color-burn'.
6409
+ */
6385
6410
  composite(mode = "source-over") {
6386
6411
  this._ctx.globalCompositeOperation = mode;
6387
6412
  return this;
6388
6413
  }
6389
6414
  /**
6390
- * Create a clipping mask from the current path. See [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/clip) for details.
6391
- */
6415
+ * Create a clipping mask from the current path. See [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/clip) for details.
6416
+ */
6392
6417
  clip() {
6393
6418
  this._ctx.clip();
6394
6419
  return this;
6395
6420
  }
6396
6421
  /**
6397
- * Activate dashed stroke and set dash style. You can customize the segments and offset.
6398
- * @example `form.dash()`, `form.dash([5, 10])`, `form.dash([5, 5], 5)`, `form.dash(false)`
6399
- * @param segments Dash segments. Defaults to `true` which corresponds to `[5, 5]`. Pass `false` to deactivate dashes. (See [canvas documentation](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/setLineDash))
6400
- * @param offset Dash offset. Defaults to 0. (See [canvas documentation](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineDashOffset)
6401
- */
6422
+ * Activate dashed stroke and set dash style. You can customize the segments and offset.
6423
+ * @example `form.dash()`, `form.dash([5, 10])`, `form.dash([5, 5], 5)`, `form.dash(false)`
6424
+ * @param segments Dash segments. Defaults to `true` which corresponds to `[5, 5]`. Pass `false` to deactivate dashes. (See [canvas documentation](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/setLineDash))
6425
+ * @param offset Dash offset. Defaults to 0. (See [canvas documentation](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineDashOffset)
6426
+ */
6402
6427
  dash(segments = true, offset = 0) {
6403
6428
  if (!segments) {
6404
6429
  this._ctx.setLineDash([]);
@@ -6413,14 +6438,14 @@ See https://github.com/williamngan/pts for details. */
6413
6438
  return this;
6414
6439
  }
6415
6440
  /**
6416
- * Set the current font.
6417
- * @param sizeOrFont either a number to specify font-size, or a `Font` object to specify all font properties
6418
- * @param weight Optional font-weight string such as "bold"
6419
- * @param style Optional font-style string such as "italic"
6420
- * @param lineHeight Optional line-height number suchas 1.5
6421
- * @param family Optional font-family such as "Helvetica, sans-serif"
6422
- * @example `form.font( myFont )`, `form.font(14, "bold")`
6423
- */
6441
+ * Set the current font.
6442
+ * @param sizeOrFont either a number to specify font-size, or a `Font` object to specify all font properties
6443
+ * @param weight Optional font-weight string such as "bold"
6444
+ * @param style Optional font-style string such as "italic"
6445
+ * @param lineHeight Optional line-height number suchas 1.5
6446
+ * @param family Optional font-family such as "Helvetica, sans-serif"
6447
+ * @example `form.font( myFont )`, `form.font(14, "bold")`
6448
+ */
6424
6449
  font(sizeOrFont, weight, style, lineHeight, family) {
6425
6450
  if (typeof sizeOrFont == "number") {
6426
6451
  this._font.size = sizeOrFont;
@@ -6441,49 +6466,49 @@ See https://github.com/williamngan/pts for details. */
6441
6466
  return this;
6442
6467
  }
6443
6468
  /**
6444
- * Set whether to use html canvas' [`measureText`](#link) function, or a faster but less accurate heuristic function.
6445
- * @param estimate `true` to use heuristic function, or `false` to use ctx.measureText
6446
- */
6469
+ * Set whether to use html canvas' [`measureText`](#link) function, or a faster but less accurate heuristic function.
6470
+ * @param estimate `true` to use heuristic function, or `false` to use ctx.measureText
6471
+ */
6447
6472
  fontWidthEstimate(estimate = true) {
6448
6473
  this._estimateTextWidth = estimate ? Typography.textWidthEstimator((c) => this._ctx.measureText(c).width) : void 0;
6449
6474
  return this;
6450
6475
  }
6451
6476
  /**
6452
- * Get the width of this text. It will return an actual measurement or an estimate based on [`fontWidthEstimate`](#link) setting. Default is an actual measurement using canvas context's measureText.
6453
- * @param c a string of text contents
6454
- */
6477
+ * Get the width of this text. It will return an actual measurement or an estimate based on [`fontWidthEstimate`](#link) setting. Default is an actual measurement using canvas context's measureText.
6478
+ * @param c a string of text contents
6479
+ */
6455
6480
  getTextWidth(c) {
6456
6481
  return !this._estimateTextWidth ? this._ctx.measureText(c + " .").width : this._estimateTextWidth(c);
6457
6482
  }
6458
6483
  /**
6459
- * Truncate text to fit width.
6460
- * @param str text to truncate
6461
- * @param width width to fit
6462
- * @param tail text to indicate overflow such as "...". Default is empty "".
6463
- */
6484
+ * Truncate text to fit width.
6485
+ * @param str text to truncate
6486
+ * @param width width to fit
6487
+ * @param tail text to indicate overflow such as "...". Default is empty "".
6488
+ */
6464
6489
  _textTruncate(str, width, tail = "") {
6465
6490
  return Typography.truncate(this.getTextWidth.bind(this), str, width, tail);
6466
6491
  }
6467
6492
  /**
6468
- * Align text within a rectangle box.
6469
- * @param box a Group or an Iterable<PtLike> that defines a rectangular box
6470
- * @param vertical a string that specifies the vertical alignment in the box: "top", "bottom", "middle", "start", "end"
6471
- * @param offset Optional offset from the edge (like padding)
6472
- * @param center Optional center position
6473
- */
6493
+ * Align text within a rectangle box.
6494
+ * @param box a Group or an Iterable<PtLike> that defines a rectangular box
6495
+ * @param vertical a string that specifies the vertical alignment in the box: "top", "bottom", "middle", "start", "end"
6496
+ * @param offset Optional offset from the edge (like padding)
6497
+ * @param center Optional center position
6498
+ */
6474
6499
  _textAlign(box, vertical, offset, center) {
6475
- let _box = Util.iterToArray(box);
6500
+ const _box = Util.iterToArray(box);
6476
6501
  if (!Util.arrayCheck(_box))
6477
6502
  return;
6478
6503
  if (!center)
6479
6504
  center = Rectangle.center(_box);
6480
- var px = _box[0][0];
6505
+ let px = _box[0][0];
6481
6506
  if (this._ctx.textAlign == "end" || this._ctx.textAlign == "right") {
6482
6507
  px = _box[1][0];
6483
6508
  } else if (this._ctx.textAlign == "center" || this._ctx.textAlign == "middle") {
6484
6509
  px = center[0];
6485
6510
  }
6486
- var py = center[1];
6511
+ let py = center[1];
6487
6512
  if (vertical == "top" || vertical == "start") {
6488
6513
  py = _box[0][1];
6489
6514
  } else if (vertical == "end" || vertical == "bottom") {
@@ -6492,10 +6517,10 @@ See https://github.com/williamngan/pts for details. */
6492
6517
  return offset ? new Pt(px + offset[0], py + offset[1]) : new Pt(px, py);
6493
6518
  }
6494
6519
  /**
6495
- * Reset the rendering context's common styles to this form's styles. This supports using multiple forms on the same canvas context.
6496
- */
6520
+ * Reset the rendering context's common styles to this form's styles. This supports using multiple forms on the same canvas context.
6521
+ */
6497
6522
  reset() {
6498
- for (let k in this._style) {
6523
+ for (const k in this._style) {
6499
6524
  if (this._style.hasOwnProperty(k)) {
6500
6525
  this._ctx[k] = this._style[k];
6501
6526
  }
@@ -6511,38 +6536,38 @@ See https://github.com/williamngan/pts for details. */
6511
6536
  this._ctx.stroke();
6512
6537
  }
6513
6538
  /**
6514
- * A static function to draw a point.
6515
- * @param ctx canvas rendering context
6516
- * @param p a Pt object
6517
- * @param radius radius of the point. Default is 5.
6518
- * @param shape The shape of the point. Defaults to "square", but it can be "circle" or a custom shape function in your own implementation.
6519
- * @example `form.point( p )`, `form.point( p, 10, "circle" )`
6520
- */
6539
+ * A static function to draw a point.
6540
+ * @param ctx canvas rendering context
6541
+ * @param p a Pt object
6542
+ * @param radius radius of the point. Default is 5.
6543
+ * @param shape The shape of the point. Defaults to "square", but it can be "circle" or a custom shape function in your own implementation.
6544
+ * @example `form.point( p )`, `form.point( p, 10, "circle" )`
6545
+ */
6521
6546
  static point(ctx, p, radius = 5, shape = "square") {
6522
6547
  if (!p)
6523
6548
  return;
6524
- if (!CanvasForm[shape])
6549
+ if (!_CanvasForm[shape])
6525
6550
  throw new Error(`${shape} is not a static function of CanvasForm`);
6526
- CanvasForm[shape](ctx, p, radius);
6551
+ _CanvasForm[shape](ctx, p, radius);
6527
6552
  }
6528
6553
  /**
6529
- * Draws a point.
6530
- * @param p a Pt object
6531
- * @param radius radius of the point. Default is 5.
6532
- * @param shape The shape of the point. Defaults to "square", but it can be "circle" or a custom shape function in your own implementation.
6533
- * @example `form.point( p )`, `form.point( p, 10, "circle" )`
6534
- */
6554
+ * Draws a point.
6555
+ * @param p a Pt object
6556
+ * @param radius radius of the point. Default is 5.
6557
+ * @param shape The shape of the point. Defaults to "square", but it can be "circle" or a custom shape function in your own implementation.
6558
+ * @example `form.point( p )`, `form.point( p, 10, "circle" )`
6559
+ */
6535
6560
  point(p, radius = 5, shape = "square") {
6536
- CanvasForm.point(this._ctx, p, radius, shape);
6561
+ _CanvasForm.point(this._ctx, p, radius, shape);
6537
6562
  this._paint();
6538
6563
  return this;
6539
6564
  }
6540
6565
  /**
6541
- * A static function to draw a circle.
6542
- * @param ctx canvas rendering context
6543
- * @param pt center position of the circle
6544
- * @param radius radius of the circle
6545
- */
6566
+ * A static function to draw a circle.
6567
+ * @param ctx canvas rendering context
6568
+ * @param pt center position of the circle
6569
+ * @param radius radius of the circle
6570
+ */
6546
6571
  static circle(ctx, pt, radius = 10) {
6547
6572
  if (!pt)
6548
6573
  return;
@@ -6551,25 +6576,25 @@ See https://github.com/williamngan/pts for details. */
6551
6576
  ctx.closePath();
6552
6577
  }
6553
6578
  /**
6554
- * Draw a circle. See also [`Circle.fromCenter`](#link)
6555
- * @param pts usually a Group or an Iterable<PtLike> with 2 Pt, but it can also take an array of two numeric arrays [ [position], [size] ]
6556
- */
6579
+ * Draw a circle. See also [`Circle.fromCenter`](#link)
6580
+ * @param pts usually a Group or an Iterable<PtLike> with 2 Pt, but it can also take an array of two numeric arrays [ [position], [size] ]
6581
+ */
6557
6582
  circle(pts) {
6558
- let p = Util.iterToArray(pts);
6559
- CanvasForm.circle(this._ctx, p[0], p[1][0]);
6583
+ const p = Util.iterToArray(pts);
6584
+ _CanvasForm.circle(this._ctx, p[0], p[1][0]);
6560
6585
  this._paint();
6561
6586
  return this;
6562
6587
  }
6563
6588
  /**
6564
- * A static function to draw an ellipse.
6565
- * @param ctx canvas rendering context
6566
- * @param pt center position
6567
- * @param radius radius [x, y] of the ellipse
6568
- * @param rotation rotation of the ellipse in radian. Default is 0.
6569
- * @param startAngle start angle of the ellipse. Default is 0.
6570
- * @param endAngle end angle of the ellipse. Default is 2 PI.
6571
- * @param cc an optional boolean value to specify if it should be drawn clockwise (`false`) or counter-clockwise (`true`). Default is clockwise.
6572
- */
6589
+ * A static function to draw an ellipse.
6590
+ * @param ctx canvas rendering context
6591
+ * @param pt center position
6592
+ * @param radius radius [x, y] of the ellipse
6593
+ * @param rotation rotation of the ellipse in radian. Default is 0.
6594
+ * @param startAngle start angle of the ellipse. Default is 0.
6595
+ * @param endAngle end angle of the ellipse. Default is 2 PI.
6596
+ * @param cc an optional boolean value to specify if it should be drawn clockwise (`false`) or counter-clockwise (`true`). Default is clockwise.
6597
+ */
6573
6598
  static ellipse(ctx, pt, radius, rotation = 0, startAngle = 0, endAngle = Const.two_pi, cc = false) {
6574
6599
  if (!pt || !radius)
6575
6600
  return;
@@ -6577,28 +6602,28 @@ See https://github.com/williamngan/pts for details. */
6577
6602
  ctx.ellipse(pt[0], pt[1], radius[0], radius[1], rotation, startAngle, endAngle, cc);
6578
6603
  }
6579
6604
  /**
6580
- * Draw an ellipse.
6581
- * @param pt center position
6582
- * @param radius radius [x, y] of the ellipse
6583
- * @param rotation rotation of the ellipse in radian. Default is 0.
6584
- * @param startAngle start angle of the ellipse. Default is 0.
6585
- * @param endAngle end angle of the ellipse. Default is 2 PI.
6586
- * @param cc an optional boolean value to specify if it should be drawn clockwise (`false`) or counter-clockwise (`true`). Default is clockwise.
6587
- */
6605
+ * Draw an ellipse.
6606
+ * @param pt center position
6607
+ * @param radius radius [x, y] of the ellipse
6608
+ * @param rotation rotation of the ellipse in radian. Default is 0.
6609
+ * @param startAngle start angle of the ellipse. Default is 0.
6610
+ * @param endAngle end angle of the ellipse. Default is 2 PI.
6611
+ * @param cc an optional boolean value to specify if it should be drawn clockwise (`false`) or counter-clockwise (`true`). Default is clockwise.
6612
+ */
6588
6613
  ellipse(pt, radius, rotation = 0, startAngle = 0, endAngle = Const.two_pi, cc = false) {
6589
- CanvasForm.ellipse(this._ctx, pt, radius, rotation, startAngle, endAngle, cc);
6614
+ _CanvasForm.ellipse(this._ctx, pt, radius, rotation, startAngle, endAngle, cc);
6590
6615
  this._paint();
6591
6616
  return this;
6592
6617
  }
6593
6618
  /**
6594
- * A static function to draw an arc.
6595
- * @param ctx canvas rendering context
6596
- * @param pt center position
6597
- * @param radius radius of the arc circle
6598
- * @param startAngle start angle of the arc
6599
- * @param endAngle end angle of the arc
6600
- * @param cc an optional boolean value to specify if it should be drawn clockwise (`false`) or counter-clockwise (`true`). Default is clockwise.
6601
- */
6619
+ * A static function to draw an arc.
6620
+ * @param ctx canvas rendering context
6621
+ * @param pt center position
6622
+ * @param radius radius of the arc circle
6623
+ * @param startAngle start angle of the arc
6624
+ * @param endAngle end angle of the arc
6625
+ * @param cc an optional boolean value to specify if it should be drawn clockwise (`false`) or counter-clockwise (`true`). Default is clockwise.
6626
+ */
6602
6627
  static arc(ctx, pt, radius, startAngle, endAngle, cc) {
6603
6628
  if (!pt)
6604
6629
  return;
@@ -6606,31 +6631,31 @@ See https://github.com/williamngan/pts for details. */
6606
6631
  ctx.arc(pt[0], pt[1], radius, startAngle, endAngle, cc);
6607
6632
  }
6608
6633
  /**
6609
- * Draw an arc.
6610
- * @param pt center position
6611
- * @param radius radius of the arc circle
6612
- * @param startAngle start angle of the arc
6613
- * @param endAngle end angle of the arc
6614
- * @param cc an optional boolean value to specify if it should be drawn clockwise (`false`) or counter-clockwise (`true`). Default is clockwise.
6615
- */
6634
+ * Draw an arc.
6635
+ * @param pt center position
6636
+ * @param radius radius of the arc circle
6637
+ * @param startAngle start angle of the arc
6638
+ * @param endAngle end angle of the arc
6639
+ * @param cc an optional boolean value to specify if it should be drawn clockwise (`false`) or counter-clockwise (`true`). Default is clockwise.
6640
+ */
6616
6641
  arc(pt, radius, startAngle, endAngle, cc) {
6617
- CanvasForm.arc(this._ctx, pt, radius, startAngle, endAngle, cc);
6642
+ _CanvasForm.arc(this._ctx, pt, radius, startAngle, endAngle, cc);
6618
6643
  this._paint();
6619
6644
  return this;
6620
6645
  }
6621
6646
  /**
6622
- * A static function to draw a square.
6623
- * @param ctx canvas rendering context
6624
- * @param pt center position of the square
6625
- * @param halfsize half size of the square
6626
- */
6647
+ * A static function to draw a square.
6648
+ * @param ctx canvas rendering context
6649
+ * @param pt center position of the square
6650
+ * @param halfsize half size of the square
6651
+ */
6627
6652
  static square(ctx, pt, halfsize) {
6628
6653
  if (!pt)
6629
6654
  return;
6630
- let x1 = pt[0] - halfsize;
6631
- let y1 = pt[1] - halfsize;
6632
- let x2 = pt[0] + halfsize;
6633
- let y2 = pt[1] + halfsize;
6655
+ const x1 = pt[0] - halfsize;
6656
+ const y1 = pt[1] - halfsize;
6657
+ const x2 = pt[0] + halfsize;
6658
+ const y2 = pt[1] + halfsize;
6634
6659
  ctx.beginPath();
6635
6660
  ctx.moveTo(x1, y1);
6636
6661
  ctx.lineTo(x1, y2);
@@ -6639,26 +6664,26 @@ See https://github.com/williamngan/pts for details. */
6639
6664
  ctx.closePath();
6640
6665
  }
6641
6666
  /**
6642
- * Draw a square, given a center and its half-size.
6643
- * @param pt center Pt
6644
- * @param halfsize half-size
6645
- */
6667
+ * Draw a square, given a center and its half-size.
6668
+ * @param pt center Pt
6669
+ * @param halfsize half-size
6670
+ */
6646
6671
  square(pt, halfsize) {
6647
- CanvasForm.square(this._ctx, pt, halfsize);
6672
+ _CanvasForm.square(this._ctx, pt, halfsize);
6648
6673
  this._paint();
6649
6674
  return this;
6650
6675
  }
6651
6676
  /**
6652
- * A static function to draw a line or polyline.
6653
- * @param ctx canvas rendering context
6654
- * @param pts a Group or an Iterable<PtLike> representing a line
6655
- */
6677
+ * A static function to draw a line or polyline.
6678
+ * @param ctx canvas rendering context
6679
+ * @param pts a Group or an Iterable<PtLike> representing a line
6680
+ */
6656
6681
  static line(ctx, pts) {
6657
6682
  if (!Util.arrayCheck(pts))
6658
6683
  return;
6659
6684
  let i = 0;
6660
6685
  ctx.beginPath();
6661
- for (let it of pts) {
6686
+ for (const it of pts) {
6662
6687
  if (it) {
6663
6688
  if (i++ > 0) {
6664
6689
  ctx.lineTo(it[0], it[1]);
@@ -6669,41 +6694,41 @@ See https://github.com/williamngan/pts for details. */
6669
6694
  }
6670
6695
  }
6671
6696
  /**
6672
- * Draw a line or polyline.
6673
- * @param pts a Group or an Iterable<PtLike> representing a line
6674
- */
6697
+ * Draw a line or polyline.
6698
+ * @param pts a Group or an Iterable<PtLike> representing a line
6699
+ */
6675
6700
  line(pts) {
6676
- CanvasForm.line(this._ctx, pts);
6701
+ _CanvasForm.line(this._ctx, pts);
6677
6702
  this._paint();
6678
6703
  return this;
6679
6704
  }
6680
6705
  /**
6681
- * A static function to draw a polygon.
6682
- * @param ctx canvas rendering context
6683
- * @param pts a Group or an Iterable<PtLike> representing a polygon
6684
- */
6706
+ * A static function to draw a polygon.
6707
+ * @param ctx canvas rendering context
6708
+ * @param pts a Group or an Iterable<PtLike> representing a polygon
6709
+ */
6685
6710
  static polygon(ctx, pts) {
6686
6711
  if (!Util.arrayCheck(pts))
6687
6712
  return;
6688
- CanvasForm.line(ctx, pts);
6713
+ _CanvasForm.line(ctx, pts);
6689
6714
  ctx.closePath();
6690
6715
  }
6691
6716
  /**
6692
- * Draw a polygon.
6693
- * @param pts a Group or an Iterable<PtLike> representingg a polygon
6694
- */
6717
+ * Draw a polygon.
6718
+ * @param pts a Group or an Iterable<PtLike> representingg a polygon
6719
+ */
6695
6720
  polygon(pts) {
6696
- CanvasForm.polygon(this._ctx, pts);
6721
+ _CanvasForm.polygon(this._ctx, pts);
6697
6722
  this._paint();
6698
6723
  return this;
6699
6724
  }
6700
6725
  /**
6701
- * A static function to draw a rectangle.
6702
- * @param ctx canvas rendering context
6703
- * @param pts a Group or an Iterable<PtLike> with 2 Pt specifying the top-left and bottom-right positions.
6704
- */
6726
+ * A static function to draw a rectangle.
6727
+ * @param ctx canvas rendering context
6728
+ * @param pts a Group or an Iterable<PtLike> with 2 Pt specifying the top-left and bottom-right positions.
6729
+ */
6705
6730
  static rect(ctx, pts) {
6706
- let p = Util.iterToArray(pts);
6731
+ const p = Util.iterToArray(pts);
6707
6732
  if (!Util.arrayCheck(p))
6708
6733
  return;
6709
6734
  ctx.beginPath();
@@ -6714,29 +6739,29 @@ See https://github.com/williamngan/pts for details. */
6714
6739
  ctx.closePath();
6715
6740
  }
6716
6741
  /**
6717
- * Draw a rectangle.
6718
- * @param pts a Group or an Iterable<PtLike> with 2 Pt specifying the top-left and bottom-right positions.
6719
- */
6742
+ * Draw a rectangle.
6743
+ * @param pts a Group or an Iterable<PtLike> with 2 Pt specifying the top-left and bottom-right positions.
6744
+ */
6720
6745
  rect(pts) {
6721
- CanvasForm.rect(this._ctx, pts);
6746
+ _CanvasForm.rect(this._ctx, pts);
6722
6747
  this._paint();
6723
6748
  return this;
6724
6749
  }
6725
6750
  /**
6726
- * A static function to draw an image.
6727
- * @param ctx canvas rendering context
6728
- * @param img either an [Img](#link) instance or an [`CanvasImageSource`](https://developer.mozilla.org/en-US/docs/Web/API/CanvasImageSource) instance (eg the image from `<img>`, `<video>` or `<canvas>`)
6729
- * @param ptOrRect a target area to place the image. Either a Pt or numeric array specifying a position, or a Group or an Iterable<PtLike> with 2 Pt (top-left, bottom-right) that specifies a bounding box for resizing. Default is (0,0) at top-left.
6730
- * @param orig optionally a Group or an Iterable<PtLike> with 2 Pt (top-left, bottom-right) that specifies a cropping box in the original target.
6731
- */
6751
+ * A static function to draw an image.
6752
+ * @param ctx canvas rendering context
6753
+ * @param img either an [Img](#link) instance or an [`CanvasImageSource`](https://developer.mozilla.org/en-US/docs/Web/API/CanvasImageSource) instance (eg the image from `<img>`, `<video>` or `<canvas>`)
6754
+ * @param ptOrRect a target area to place the image. Either a Pt or numeric array specifying a position, or a Group or an Iterable<PtLike> with 2 Pt (top-left, bottom-right) that specifies a bounding box for resizing. Default is (0,0) at top-left.
6755
+ * @param orig optionally a Group or an Iterable<PtLike> with 2 Pt (top-left, bottom-right) that specifies a cropping box in the original target.
6756
+ */
6732
6757
  static image(ctx, ptOrRect, img, orig) {
6733
- let t = Util.iterToArray(ptOrRect);
6758
+ const t = Util.iterToArray(ptOrRect);
6734
6759
  let pos;
6735
6760
  if (typeof t[0] === "number") {
6736
6761
  pos = t;
6737
6762
  } else {
6738
6763
  if (orig) {
6739
- let o = Util.iterToArray(orig);
6764
+ const o = Util.iterToArray(orig);
6740
6765
  pos = [
6741
6766
  o[0][0],
6742
6767
  o[0][1],
@@ -6760,29 +6785,29 @@ See https://github.com/williamngan/pts for details. */
6760
6785
  }
6761
6786
  }
6762
6787
  /**
6763
- * Draw an image.
6764
- * @param img either an [Img](#link) instance or an [`CanvasImageSource`](https://developer.mozilla.org/en-US/docs/Web/API/CanvasImageSource) instance (eg the image from `<img>`, `<video>` or `<canvas>`)
6765
- * @param ptOrRect a target area to place the image. Either a PtLike specifying a position, or a Group or an Iterable<PtLike> with 2 Pt (top-left position, bottom-right position) that specifies a bounding box. Default is (0,0) at top-left.
6766
- * @param orig optionally a Group or an Iterable<PtLike> with 2 Pt (top-left position, bottom-right position) that specifies a cropping box in the original target.
6767
- */
6788
+ * Draw an image.
6789
+ * @param img either an [Img](#link) instance or an [`CanvasImageSource`](https://developer.mozilla.org/en-US/docs/Web/API/CanvasImageSource) instance (eg the image from `<img>`, `<video>` or `<canvas>`)
6790
+ * @param ptOrRect a target area to place the image. Either a PtLike specifying a position, or a Group or an Iterable<PtLike> with 2 Pt (top-left position, bottom-right position) that specifies a bounding box. Default is (0,0) at top-left.
6791
+ * @param orig optionally a Group or an Iterable<PtLike> with 2 Pt (top-left position, bottom-right position) that specifies a cropping box in the original target.
6792
+ */
6768
6793
  image(ptOrRect, img, orig) {
6769
6794
  if (img instanceof Img) {
6770
6795
  if (img.loaded) {
6771
- CanvasForm.image(this._ctx, ptOrRect, img.image, orig);
6796
+ _CanvasForm.image(this._ctx, ptOrRect, img.image, orig);
6772
6797
  }
6773
6798
  } else {
6774
- CanvasForm.image(this._ctx, ptOrRect, img, orig);
6799
+ _CanvasForm.image(this._ctx, ptOrRect, img, orig);
6775
6800
  }
6776
6801
  return this;
6777
6802
  }
6778
6803
  /**
6779
- * A static function to draw ImageData on canvas
6780
- * @param ctx canvas rendering context
6781
- * @param ptOrRect a target area to place the image. Either a Pt or numeric array specifying a position, or a Group or an Iterable<PtLike> with 2 Pt (top-left, bottom-right) that specifies a bounding box for resizing. Default is (0,0) at top-left.
6782
- * @param img an ImageData object
6783
- */
6804
+ * A static function to draw ImageData on canvas
6805
+ * @param ctx canvas rendering context
6806
+ * @param ptOrRect a target area to place the image. Either a Pt or numeric array specifying a position, or a Group or an Iterable<PtLike> with 2 Pt (top-left, bottom-right) that specifies a bounding box for resizing. Default is (0,0) at top-left.
6807
+ * @param img an ImageData object
6808
+ */
6784
6809
  static imageData(ctx, ptOrRect, img) {
6785
- let t = Util.iterToArray(ptOrRect);
6810
+ const t = Util.iterToArray(ptOrRect);
6786
6811
  if (typeof t[0] === "number") {
6787
6812
  ctx.putImageData(img, t[0], t[1]);
6788
6813
  } else {
@@ -6790,74 +6815,74 @@ See https://github.com/williamngan/pts for details. */
6790
6815
  }
6791
6816
  }
6792
6817
  /**
6793
- * Draw ImageData on canvas using ImageData
6794
- * @param ptOrRect a target area to place the image. Either a Pt or numeric array specifying a position, or a Group or an Iterable<PtLike> with 2 Pt (top-left, bottom-right) that specifies a bounding box for resizing. Default is (0,0) at top-left.
6795
- * @param img an ImageData object
6796
- */
6818
+ * Draw ImageData on canvas using ImageData
6819
+ * @param ptOrRect a target area to place the image. Either a Pt or numeric array specifying a position, or a Group or an Iterable<PtLike> with 2 Pt (top-left, bottom-right) that specifies a bounding box for resizing. Default is (0,0) at top-left.
6820
+ * @param img an ImageData object
6821
+ */
6797
6822
  imageData(ptOrRect, img) {
6798
- CanvasForm.imageData(this._ctx, ptOrRect, img);
6823
+ _CanvasForm.imageData(this._ctx, ptOrRect, img);
6799
6824
  return this;
6800
6825
  }
6801
6826
  /**
6802
- * A static function to draw text.
6803
- * @param ctx canvas rendering context
6804
- * @param `pt` a Point object to specify the anchor point
6805
- * @param `txt` a string of text to draw
6806
- * @param `maxWidth` specify a maximum width per line
6807
- */
6827
+ * A static function to draw text.
6828
+ * @param ctx canvas rendering context
6829
+ * @param `pt` a Point object to specify the anchor point
6830
+ * @param `txt` a string of text to draw
6831
+ * @param `maxWidth` specify a maximum width per line
6832
+ */
6808
6833
  static text(ctx, pt, txt, maxWidth) {
6809
6834
  if (!pt)
6810
6835
  return;
6811
6836
  ctx.fillText(txt, pt[0], pt[1], maxWidth);
6812
6837
  }
6813
6838
  /**
6814
- * Draw text on canvas.
6815
- * @param `pt` a Pt or numeric array to specify the anchor point
6816
- * @param `txt` text
6817
- * @param `maxWidth` specify a maximum width per line
6818
- */
6839
+ * Draw text on canvas.
6840
+ * @param `pt` a Pt or numeric array to specify the anchor point
6841
+ * @param `txt` text
6842
+ * @param `maxWidth` specify a maximum width per line
6843
+ */
6819
6844
  text(pt, txt, maxWidth) {
6820
- CanvasForm.text(this._ctx, pt, txt, maxWidth);
6845
+ _CanvasForm.text(this._ctx, pt, txt, maxWidth);
6821
6846
  return this;
6822
6847
  }
6823
6848
  /**
6824
- * Fit a single-line text in a rectangular box.
6825
- * @param box a rectangle box defined by a Group or an Iterable<Pt>
6826
- * @param txt string of text
6827
- * @param tail text to indicate overflow such as "...". Default is empty "".
6828
- * @param verticalAlign "top", "middle", or "bottom" to specify vertical alignment inside the box
6829
- * @param overrideBaseline If `true`, use the corresponding baseline as verticalAlign. If `false`, use the current canvas context's textBaseline setting. Default is `true`.
6830
- */
6849
+ * Fit a single-line text in a rectangular box.
6850
+ * @param box a rectangle box defined by a Group or an Iterable<Pt>
6851
+ * @param txt string of text
6852
+ * @param tail text to indicate overflow such as "...". Default is empty "".
6853
+ * @param verticalAlign "top", "middle", or "bottom" to specify vertical alignment inside the box
6854
+ * @param overrideBaseline If `true`, use the corresponding baseline as verticalAlign. If `false`, use the current canvas context's textBaseline setting. Default is `true`.
6855
+ */
6831
6856
  textBox(box, txt, verticalAlign = "middle", tail = "", overrideBaseline = true) {
6832
6857
  if (overrideBaseline)
6833
6858
  this._ctx.textBaseline = verticalAlign;
6834
- let size = Rectangle.size(box);
6835
- let t = this._textTruncate(txt, size[0], tail);
6859
+ const size = Rectangle.size(box);
6860
+ const t = this._textTruncate(txt, size[0], tail);
6836
6861
  this.text(this._textAlign(box, verticalAlign), t[0]);
6837
6862
  return this;
6838
6863
  }
6839
6864
  /**
6840
- * Fit multi-line text in a rectangular box. Note that this will also set canvas context's textBaseline to "top".
6841
- * @param box a Group or an Iterable<PtLike> with 2 Pt that represents a bounding box
6842
- * @param txt string of text
6843
- * @param lineHeight line height as a ratio of font size. Default is 1.2.
6844
- * @param verticalAlign "top", "middle", or "bottom" to specify vertical alignment inside the box
6845
- * @param crop a boolean to specify whether to crop text when overflowing
6846
- */
6865
+ * Fit multi-line text in a rectangular box. Note that this will also set canvas context's textBaseline to "top".
6866
+ * @param box a Group or an Iterable<PtLike> with 2 Pt that represents a bounding box
6867
+ * @param txt string of text
6868
+ * @param lineHeight line height as a ratio of font size. Default is 1.2.
6869
+ * @param verticalAlign "top", "middle", or "bottom" to specify vertical alignment inside the box
6870
+ * @param crop a boolean to specify whether to crop text when overflowing
6871
+ */
6847
6872
  paragraphBox(box, txt, lineHeight = 1.2, verticalAlign = "top", crop = true) {
6848
- let b = Util.iterToArray(box);
6849
- let size = Rectangle.size(b);
6873
+ const b = Util.iterToArray(box);
6874
+ const size = Rectangle.size(b);
6850
6875
  this._ctx.textBaseline = "top";
6851
- let lstep = this._font.size * lineHeight;
6852
- let nextLine = (sub, buffer = [], cc = 0) => {
6876
+ const lstep = this._font.size * lineHeight;
6877
+ const nextLine = (sub, buffer = [], cc = 0) => {
6853
6878
  if (!sub)
6854
6879
  return buffer;
6855
6880
  if (crop && cc * lstep > size[1] - lstep * 2)
6856
6881
  return buffer;
6857
6882
  if (cc > 1e4)
6858
6883
  throw new Error("max recursion reached (10000)");
6859
- let t = this._textTruncate(sub, size[0], "");
6860
- let newln = t[0].indexOf("\n");
6884
+ const t = this._textTruncate(sub, size[0], "");
6885
+ const newln = t[0].indexOf("\n");
6861
6886
  if (newln >= 0) {
6862
6887
  buffer.push(t[0].substr(0, newln));
6863
6888
  return nextLine(sub.substr(newln + 1), buffer, cc + 1);
@@ -6865,12 +6890,12 @@ See https://github.com/williamngan/pts for details. */
6865
6890
  let dt = t[0].lastIndexOf(" ") + 1;
6866
6891
  if (dt <= 0 || t[1] === sub.length)
6867
6892
  dt = void 0;
6868
- let line = t[0].substr(0, dt);
6893
+ const line = t[0].substr(0, dt);
6869
6894
  buffer.push(line);
6870
6895
  return t[1] <= 0 || t[1] === sub.length ? buffer : nextLine(sub.substr(dt || t[1]), buffer, cc + 1);
6871
6896
  };
6872
- let lines = nextLine(txt);
6873
- let lsize = lines.length * lstep;
6897
+ const lines = nextLine(txt);
6898
+ const lsize = lines.length * lstep;
6874
6899
  let lbox = b;
6875
6900
  if (verticalAlign == "middle" || verticalAlign == "center") {
6876
6901
  let lpad = (size[1] - lsize) / 2;
@@ -6882,17 +6907,17 @@ See https://github.com/williamngan/pts for details. */
6882
6907
  } else {
6883
6908
  lbox = new Group(b[0], b[0].$add(size[0], lsize));
6884
6909
  }
6885
- let center = Rectangle.center(lbox);
6910
+ const center = Rectangle.center(lbox);
6886
6911
  for (let i = 0, len = lines.length; i < len; i++) {
6887
6912
  this.text(this._textAlign(lbox, "top", [0, i * lstep], center), lines[i]);
6888
6913
  }
6889
6914
  return this;
6890
6915
  }
6891
6916
  /**
6892
- * Set text alignment and baseline (eg, vertical-align).
6893
- * @param alignment HTML canvas' textAlign option: "left", "right", "center", "start", or "end"
6894
- * @param baseline HTML canvas' textBaseline option: "top", "hanging", "middle", "alphabetic", "ideographic", "bottom". For convenience, you can also use "center" (same as "middle"), and "baseline" (same as "alphabetic")
6895
- */
6917
+ * Set text alignment and baseline (eg, vertical-align).
6918
+ * @param alignment HTML canvas' textAlign option: "left", "right", "center", "start", or "end"
6919
+ * @param baseline HTML canvas' textBaseline option: "top", "hanging", "middle", "alphabetic", "ideographic", "bottom". For convenience, you can also use "center" (same as "middle"), and "baseline" (same as "alphabetic")
6920
+ */
6896
6921
  alignText(alignment = "left", baseline = "alphabetic") {
6897
6922
  if (baseline == "center")
6898
6923
  baseline = "middle";
@@ -6903,11 +6928,11 @@ See https://github.com/williamngan/pts for details. */
6903
6928
  return this;
6904
6929
  }
6905
6930
  /**
6906
- * A convenient way to draw some text on canvas for logging or debugging. It'll be draw on the top-left of the canvas as an overlay.
6907
- * @param txt text
6908
- */
6931
+ * A convenient way to draw some text on canvas for logging or debugging. It'll be draw on the top-left of the canvas as an overlay.
6932
+ * @param txt text
6933
+ */
6909
6934
  log(txt) {
6910
- let w = this._ctx.measureText(txt).width + 20;
6935
+ const w = this._ctx.measureText(txt).width + 20;
6911
6936
  this.stroke(false).fill("rgba(0,0,0,.4)").rect([[0, 0], [w, 20]]);
6912
6937
  this.fill("#fff").text([10, 14], txt);
6913
6938
  return this;
@@ -7376,7 +7401,7 @@ See https://github.com/williamngan/pts for details. */
7376
7401
  return Num.lerp(Num.lerp(n00, n10, tx), Num.lerp(n01, n11, tx), _fade(y));
7377
7402
  }
7378
7403
  };
7379
- var Delaunay = class extends Group {
7404
+ var Delaunay = class _Delaunay extends Group {
7380
7405
  constructor() {
7381
7406
  super(...arguments);
7382
7407
  this._mesh = [];
@@ -7423,7 +7448,7 @@ See https://github.com/williamngan/pts for details. */
7423
7448
  edges.push(circum.i, circum.j, circum.j, circum.k, circum.k, circum.i);
7424
7449
  opened.splice(j, 1);
7425
7450
  }
7426
- Delaunay._dedupe(edges);
7451
+ _Delaunay._dedupe(edges);
7427
7452
  j = edges.length;
7428
7453
  while (j > 1) {
7429
7454
  opened.push(this._circum(edges[--j], edges[--j], c, false, pts));
@@ -7569,7 +7594,7 @@ See https://github.com/williamngan/pts for details. */
7569
7594
  __export(Color_exports, {
7570
7595
  Color: () => Color
7571
7596
  });
7572
- var _Color = class extends Pt {
7597
+ var _Color = class _Color extends Pt {
7573
7598
  /**
7574
7599
  * Create a Color. Same as creating a Pt. Optionally you may use [`Color.from`](#link) to create a color.
7575
7600
  * @param args Pt-like parameters which can be a list of numeric parameters, an array of numbers, or an object with {x,y,z,w} properties
@@ -7584,8 +7609,8 @@ See https://github.com/williamngan/pts for details. */
7584
7609
  * @param args Pt-like parameters which can be a list of numeric parameters, an array of numbers, or an object with {x,y,z,w} properties
7585
7610
  */
7586
7611
  static from(...args) {
7587
- let p = [1, 1, 1, 1];
7588
- let c = Util.getArgs(args);
7612
+ const p = [1, 1, 1, 1];
7613
+ const c = Util.getArgs(args);
7589
7614
  for (let i = 0, len = p.length; i < len; i++) {
7590
7615
  if (i < c.length)
7591
7616
  p[i] = c[i];
@@ -7600,7 +7625,7 @@ See https://github.com/williamngan/pts for details. */
7600
7625
  if (hex[0] == "#")
7601
7626
  hex = hex.substr(1);
7602
7627
  if (hex.length <= 3) {
7603
- let fn = (i) => hex[i] || "F";
7628
+ const fn = (i) => hex[i] || "F";
7604
7629
  hex = `${fn(0)}${fn(0)}${fn(1)}${fn(1)}${fn(2)}${fn(2)}`;
7605
7630
  }
7606
7631
  let alpha = 1;
@@ -7608,7 +7633,7 @@ See https://github.com/williamngan/pts for details. */
7608
7633
  alpha = hex.substr(6) && 255 / 255;
7609
7634
  hex = hex.substring(0, 6);
7610
7635
  }
7611
- let hexVal = parseInt(hex, 16);
7636
+ const hexVal = parseInt(hex, 16);
7612
7637
  return new _Color(hexVal >> 16, hexVal >> 8 & 255, hexVal & 255, alpha);
7613
7638
  }
7614
7639
  /**
@@ -7690,7 +7715,7 @@ See https://github.com/williamngan/pts for details. */
7690
7715
  * Clone this Color.
7691
7716
  */
7692
7717
  clone() {
7693
- let c = new _Color(this);
7718
+ const c = new _Color(this);
7694
7719
  c.toMode(this._mode);
7695
7720
  return c;
7696
7721
  }
@@ -7701,7 +7726,7 @@ See https://github.com/williamngan/pts for details. */
7701
7726
  */
7702
7727
  toMode(mode, convert = false) {
7703
7728
  if (convert) {
7704
- let fname = this._mode.toUpperCase() + "to" + mode.toUpperCase();
7729
+ const fname = this._mode.toUpperCase() + "to" + mode.toUpperCase();
7705
7730
  if (_Color[fname]) {
7706
7731
  this.to(_Color[fname](this, this._isNorm, this._isNorm));
7707
7732
  } else {
@@ -7753,7 +7778,7 @@ See https://github.com/williamngan/pts for details. */
7753
7778
  return this._mode == "lch" ? this[2] : this[0];
7754
7779
  }
7755
7780
  set h(n) {
7756
- let i = this._mode == "lch" ? 2 : 0;
7781
+ const i = this._mode == "lch" ? 2 : 0;
7757
7782
  this[i] = n;
7758
7783
  }
7759
7784
  /**
@@ -7772,7 +7797,7 @@ See https://github.com/williamngan/pts for details. */
7772
7797
  return this._mode == "hsl" ? this[2] : this[0];
7773
7798
  }
7774
7799
  set l(n) {
7775
- let i = this._mode == "hsl" ? 2 : 0;
7800
+ const i = this._mode == "hsl" ? 2 : 0;
7776
7801
  this[i] = n;
7777
7802
  }
7778
7803
  // lab, lch, luv
@@ -7838,7 +7863,7 @@ See https://github.com/williamngan/pts for details. */
7838
7863
  normalize(toNorm = true) {
7839
7864
  if (this._isNorm == toNorm)
7840
7865
  return this;
7841
- let ranges = _Color.ranges[this._mode];
7866
+ const ranges = _Color.ranges[this._mode];
7842
7867
  for (let i = 0; i < 3; i++) {
7843
7868
  this[i] = !toNorm ? Num.mapToRange(this[i], 0, 1, ranges[i][0], ranges[i][1]) : Num.mapToRange(this[i], ranges[i][0], ranges[i][1], 0, 1);
7844
7869
  }
@@ -7859,8 +7884,8 @@ See https://github.com/williamngan/pts for details. */
7859
7884
  */
7860
7885
  toString(format = "mode") {
7861
7886
  if (format == "hex") {
7862
- let _hex = (n) => {
7863
- let s = Math.floor(n).toString(16);
7887
+ const _hex = (n) => {
7888
+ const s = Math.floor(n).toString(16);
7864
7889
  return s.length < 2 ? "0" + s : s;
7865
7890
  };
7866
7891
  return `#${_hex(this[0])}${_hex(this[1])}${_hex(this[2])}`;
@@ -7880,17 +7905,17 @@ See https://github.com/williamngan/pts for details. */
7880
7905
  * @returns a new HSL Color
7881
7906
  */
7882
7907
  static RGBtoHSL(rgb, normalizedInput = false, normalizedOutput = false) {
7883
- let [r, g, b] = !normalizedInput ? rgb.$normalize() : rgb;
7884
- let max = Math.max(r, g, b);
7885
- let min = Math.min(r, g, b);
7908
+ const [r, g, b] = !normalizedInput ? rgb.$normalize() : rgb;
7909
+ const max = Math.max(r, g, b);
7910
+ const min = Math.min(r, g, b);
7886
7911
  let h = (max + min) / 2;
7887
7912
  let s = h;
7888
- let l = h;
7913
+ const l = h;
7889
7914
  if (max == min) {
7890
7915
  h = 0;
7891
7916
  s = 0;
7892
7917
  } else {
7893
- let d = max - min;
7918
+ const d = max - min;
7894
7919
  s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
7895
7920
  h = 0;
7896
7921
  if (max === r) {
@@ -7916,9 +7941,9 @@ See https://github.com/williamngan/pts for details. */
7916
7941
  h = h / 360;
7917
7942
  if (s == 0)
7918
7943
  return _Color.rgb(l * 255, l * 255, l * 255, hsl.alpha);
7919
- let q = l <= 0.5 ? l * (1 + s) : l + s - l * s;
7920
- let p = 2 * l - q;
7921
- let convert = (t) => {
7944
+ const q = l <= 0.5 ? l * (1 + s) : l + s - l * s;
7945
+ const p = 2 * l - q;
7946
+ const convert = (t) => {
7922
7947
  t = t < 0 ? t + 1 : t > 1 ? t - 1 : t;
7923
7948
  if (t * 6 < 1) {
7924
7949
  return p + (q - p) * t * 6;
@@ -7930,7 +7955,7 @@ See https://github.com/williamngan/pts for details. */
7930
7955
  return p;
7931
7956
  }
7932
7957
  };
7933
- let sc = normalizedOutput ? 1 : 255;
7958
+ const sc = normalizedOutput ? 1 : 255;
7934
7959
  return _Color.rgb(
7935
7960
  sc * convert(h + 1 / 3),
7936
7961
  sc * convert(h),
@@ -7946,13 +7971,13 @@ See https://github.com/williamngan/pts for details. */
7946
7971
  * @returns a new HSB Color
7947
7972
  */
7948
7973
  static RGBtoHSB(rgb, normalizedInput = false, normalizedOutput = false) {
7949
- let [r, g, b] = !normalizedInput ? rgb.$normalize() : rgb;
7950
- let max = Math.max(r, g, b);
7951
- let min = Math.min(r, g, b);
7952
- let d = max - min;
7974
+ const [r, g, b] = !normalizedInput ? rgb.$normalize() : rgb;
7975
+ const max = Math.max(r, g, b);
7976
+ const min = Math.min(r, g, b);
7977
+ const d = max - min;
7953
7978
  let h = 0;
7954
- let s = max === 0 ? 0 : d / max;
7955
- let v = max;
7979
+ const s = max === 0 ? 0 : d / max;
7980
+ const v = max;
7956
7981
  if (max != min) {
7957
7982
  if (max === r) {
7958
7983
  h = (g - b) / d + (g < b ? 6 : 0);
@@ -7975,12 +8000,12 @@ See https://github.com/williamngan/pts for details. */
7975
8000
  let [h, s, v] = hsb;
7976
8001
  if (!normalizedInput)
7977
8002
  h = h / 360;
7978
- let i = Math.floor(h * 6);
7979
- let f = h * 6 - i;
7980
- let p = v * (1 - s);
7981
- let q = v * (1 - f * s);
7982
- let t = v * (1 - (1 - f) * s);
7983
- let pick = [
8003
+ const i = Math.floor(h * 6);
8004
+ const f = h * 6 - i;
8005
+ const p = v * (1 - s);
8006
+ const q = v * (1 - f * s);
8007
+ const t = v * (1 - (1 - f) * s);
8008
+ const pick = [
7984
8009
  [v, t, p],
7985
8010
  [q, v, p],
7986
8011
  [p, v, t],
@@ -7988,8 +8013,8 @@ See https://github.com/williamngan/pts for details. */
7988
8013
  [t, p, v],
7989
8014
  [v, p, q]
7990
8015
  ];
7991
- let c = pick[i % 6];
7992
- let sc = normalizedOutput ? 1 : 255;
8016
+ const c = pick[i % 6];
8017
+ const sc = normalizedOutput ? 1 : 255;
7993
8018
  return _Color.rgb(
7994
8019
  sc * c[0],
7995
8020
  sc * c[1],
@@ -8005,7 +8030,7 @@ See https://github.com/williamngan/pts for details. */
8005
8030
  * @returns a new LAB Color
8006
8031
  */
8007
8032
  static RGBtoLAB(rgb, normalizedInput = false, normalizedOutput = false) {
8008
- let c = normalizedInput ? rgb.$normalize(false) : rgb;
8033
+ const c = normalizedInput ? rgb.$normalize(false) : rgb;
8009
8034
  return _Color.XYZtoLAB(_Color.RGBtoXYZ(c), false, normalizedOutput);
8010
8035
  }
8011
8036
  /**
@@ -8016,7 +8041,7 @@ See https://github.com/williamngan/pts for details. */
8016
8041
  * @returns a new RGB Color
8017
8042
  */
8018
8043
  static LABtoRGB(lab, normalizedInput = false, normalizedOutput = false) {
8019
- let c = normalizedInput ? lab.$normalize(false) : lab;
8044
+ const c = normalizedInput ? lab.$normalize(false) : lab;
8020
8045
  return _Color.XYZtoRGB(_Color.LABtoXYZ(c), false, normalizedOutput);
8021
8046
  }
8022
8047
  /**
@@ -8027,7 +8052,7 @@ See https://github.com/williamngan/pts for details. */
8027
8052
  * @returns a new LCH Color
8028
8053
  */
8029
8054
  static RGBtoLCH(rgb, normalizedInput = false, normalizedOutput = false) {
8030
- let c = normalizedInput ? rgb.$normalize(false) : rgb;
8055
+ const c = normalizedInput ? rgb.$normalize(false) : rgb;
8031
8056
  return _Color.LABtoLCH(_Color.RGBtoLAB(c), false, normalizedOutput);
8032
8057
  }
8033
8058
  /**
@@ -8038,7 +8063,7 @@ See https://github.com/williamngan/pts for details. */
8038
8063
  * @returns a new RGB Color
8039
8064
  */
8040
8065
  static LCHtoRGB(lch, normalizedInput = false, normalizedOutput = false) {
8041
- let c = normalizedInput ? lch.$normalize(false) : lch;
8066
+ const c = normalizedInput ? lch.$normalize(false) : lch;
8042
8067
  return _Color.LABtoRGB(_Color.LCHtoLAB(c), false, normalizedOutput);
8043
8068
  }
8044
8069
  /**
@@ -8049,7 +8074,7 @@ See https://github.com/williamngan/pts for details. */
8049
8074
  * @returns a new LUV Color
8050
8075
  */
8051
8076
  static RGBtoLUV(rgb, normalizedInput = false, normalizedOutput = false) {
8052
- let c = normalizedInput ? rgb.$normalize(false) : rgb;
8077
+ const c = normalizedInput ? rgb.$normalize(false) : rgb;
8053
8078
  return _Color.XYZtoLUV(_Color.RGBtoXYZ(c), false, normalizedOutput);
8054
8079
  }
8055
8080
  /**
@@ -8060,7 +8085,7 @@ See https://github.com/williamngan/pts for details. */
8060
8085
  * @returns a new RGB Color
8061
8086
  */
8062
8087
  static LUVtoRGB(luv, normalizedInput = false, normalizedOutput = false) {
8063
- let c = normalizedInput ? luv.$normalize(false) : luv;
8088
+ const c = normalizedInput ? luv.$normalize(false) : luv;
8064
8089
  return _Color.XYZtoRGB(_Color.LUVtoXYZ(c), false, normalizedOutput);
8065
8090
  }
8066
8091
  /**
@@ -8071,13 +8096,13 @@ See https://github.com/williamngan/pts for details. */
8071
8096
  * @returns a new XYZ Color
8072
8097
  */
8073
8098
  static RGBtoXYZ(rgb, normalizedInput = false, normalizedOutput = false) {
8074
- let c = !normalizedInput ? rgb.$normalize() : rgb.clone();
8099
+ const c = !normalizedInput ? rgb.$normalize() : rgb.clone();
8075
8100
  for (let i = 0; i < 3; i++) {
8076
8101
  c[i] = c[i] > 0.04045 ? Math.pow((c[i] + 0.055) / 1.055, 2.4) : c[i] / 12.92;
8077
8102
  if (!normalizedOutput)
8078
8103
  c[i] = c[i] * 100;
8079
8104
  }
8080
- let cc = _Color.xyz(
8105
+ const cc = _Color.xyz(
8081
8106
  c[0] * 0.4124564 + c[1] * 0.3575761 + c[2] * 0.1804375,
8082
8107
  c[0] * 0.2126729 + c[1] * 0.7151522 + c[2] * 0.072175,
8083
8108
  c[0] * 0.0193339 + c[1] * 0.119192 + c[2] * 0.9503041,
@@ -8093,8 +8118,8 @@ See https://github.com/williamngan/pts for details. */
8093
8118
  * @returns a new RGB Color
8094
8119
  */
8095
8120
  static XYZtoRGB(xyz, normalizedInput = false, normalizedOutput = false) {
8096
- let [x, y, z] = !normalizedInput ? xyz.$normalize() : xyz;
8097
- let rgb = [
8121
+ const [x, y, z] = !normalizedInput ? xyz.$normalize() : xyz;
8122
+ const rgb = [
8098
8123
  x * 3.2406254773200533 + y * -1.5372079722103187 + z * -0.4986285986982479,
8099
8124
  x * -0.9689307147293197 + y * 1.8757560608852415 + z * 0.041517523842953964,
8100
8125
  x * 0.055710120445510616 + y * -0.2040210505984867 + z * 1.0569959422543882
@@ -8105,7 +8130,7 @@ See https://github.com/williamngan/pts for details. */
8105
8130
  if (!normalizedOutput)
8106
8131
  rgb[i] = Math.round(rgb[i] * 255);
8107
8132
  }
8108
- let cc = _Color.rgb(rgb[0], rgb[1], rgb[2], xyz.alpha);
8133
+ const cc = _Color.rgb(rgb[0], rgb[1], rgb[2], xyz.alpha);
8109
8134
  return normalizedOutput ? cc.normalize() : cc;
8110
8135
  }
8111
8136
  /**
@@ -8116,13 +8141,13 @@ See https://github.com/williamngan/pts for details. */
8116
8141
  * @returns a new LAB Color
8117
8142
  */
8118
8143
  static XYZtoLAB(xyz, normalizedInput = false, normalizedOutput = false) {
8119
- let c = normalizedInput ? xyz.$normalize(false) : xyz.clone();
8144
+ const c = normalizedInput ? xyz.$normalize(false) : xyz.clone();
8120
8145
  const eps = 0.00885645167;
8121
8146
  const kap = 903.296296296;
8122
8147
  c.divide(_Color.D65);
8123
- let fn = (n) => n > eps ? Math.pow(n, 1 / 3) : (kap * n + 16) / 116;
8124
- let cy = fn(c[1]);
8125
- let cc = _Color.lab(
8148
+ const fn = (n) => n > eps ? Math.pow(n, 1 / 3) : (kap * n + 16) / 116;
8149
+ const cy = fn(c[1]);
8150
+ const cc = _Color.lab(
8126
8151
  116 * cy - 16,
8127
8152
  500 * (fn(c[0]) - cy),
8128
8153
  200 * (cy - fn(c[2])),
@@ -8138,16 +8163,16 @@ See https://github.com/williamngan/pts for details. */
8138
8163
  * @returns a new XYZ Color
8139
8164
  */
8140
8165
  static LABtoXYZ(lab, normalizedInput = false, normalizedOutput = false) {
8141
- let c = normalizedInput ? lab.$normalize(false) : lab;
8142
- let y = (c[0] + 16) / 116;
8143
- let x = c[1] / 500 + y;
8144
- let z = y - c[2] / 200;
8166
+ const c = normalizedInput ? lab.$normalize(false) : lab;
8167
+ const y = (c[0] + 16) / 116;
8168
+ const x = c[1] / 500 + y;
8169
+ const z = y - c[2] / 200;
8145
8170
  const eps = 0.00885645167;
8146
8171
  const kap = 903.296296296;
8147
- let d = _Color.D65;
8172
+ const d = _Color.D65;
8148
8173
  const xxx = Math.pow(x, 3);
8149
8174
  const zzz = Math.pow(z, 3);
8150
- let cc = _Color.xyz(
8175
+ const cc = _Color.xyz(
8151
8176
  d[0] * (xxx > eps ? xxx : (116 * x - 16) / kap),
8152
8177
  d[1] * (c[0] > kap * eps ? Math.pow((c[0] + 16) / 116, 3) : c[0] / kap),
8153
8178
  d[2] * (zzz > eps ? zzz : (116 * z - 16) / kap),
@@ -8164,13 +8189,13 @@ See https://github.com/williamngan/pts for details. */
8164
8189
  */
8165
8190
  static XYZtoLUV(xyz, normalizedInput = false, normalizedOutput = false) {
8166
8191
  let [x, y, z] = normalizedInput ? xyz.$normalize(false) : xyz;
8167
- let u = 4 * x / (x + 15 * y + 3 * z);
8168
- let v = 9 * y / (x + 15 * y + 3 * z);
8192
+ const u = 4 * x / (x + 15 * y + 3 * z);
8193
+ const v = 9 * y / (x + 15 * y + 3 * z);
8169
8194
  y = y / 100;
8170
8195
  y = y > 8856e-6 ? Math.pow(y, 1 / 3) : 7.787 * y + 16 / 116;
8171
- let refU = 4 * _Color.D65[0] / (_Color.D65[0] + 15 * _Color.D65[1] + 3 * _Color.D65[2]);
8172
- let refV = 9 * _Color.D65[1] / (_Color.D65[0] + 15 * _Color.D65[1] + 3 * _Color.D65[2]);
8173
- let L = 116 * y - 16;
8196
+ const refU = 4 * _Color.D65[0] / (_Color.D65[0] + 15 * _Color.D65[1] + 3 * _Color.D65[2]);
8197
+ const refV = 9 * _Color.D65[1] / (_Color.D65[0] + 15 * _Color.D65[1] + 3 * _Color.D65[2]);
8198
+ const L = 116 * y - 16;
8174
8199
  return _Color.luv(
8175
8200
  L,
8176
8201
  13 * L * (u - refU),
@@ -8188,15 +8213,15 @@ See https://github.com/williamngan/pts for details. */
8188
8213
  static LUVtoXYZ(luv, normalizedInput = false, normalizedOutput = false) {
8189
8214
  let [l, u, v] = normalizedInput ? luv.$normalize(false) : luv;
8190
8215
  let y = (l + 16) / 116;
8191
- let cubeY = y * y * y;
8216
+ const cubeY = y * y * y;
8192
8217
  y = cubeY > 8856e-6 ? cubeY : (y - 16 / 116) / 7.787;
8193
- let refU = 4 * _Color.D65[0] / (_Color.D65[0] + 15 * _Color.D65[1] + 3 * _Color.D65[2]);
8194
- let refV = 9 * _Color.D65[1] / (_Color.D65[0] + 15 * _Color.D65[1] + 3 * _Color.D65[2]);
8218
+ const refU = 4 * _Color.D65[0] / (_Color.D65[0] + 15 * _Color.D65[1] + 3 * _Color.D65[2]);
8219
+ const refV = 9 * _Color.D65[1] / (_Color.D65[0] + 15 * _Color.D65[1] + 3 * _Color.D65[2]);
8195
8220
  u = u / (13 * l) + refU;
8196
8221
  v = v / (13 * l) + refV;
8197
8222
  y = y * 100;
8198
- let x = -1 * (9 * y * u) / ((u - 4) * v - u * v);
8199
- let z = (9 * y - 15 * v * y - v * x) / (3 * v);
8223
+ const x = -1 * (9 * y * u) / ((u - 4) * v - u * v);
8224
+ const z = (9 * y - 15 * v * y - v * x) / (3 * v);
8200
8225
  return _Color.xyz(x, y, z, luv.alpha);
8201
8226
  }
8202
8227
  /**
@@ -8207,8 +8232,8 @@ See https://github.com/williamngan/pts for details. */
8207
8232
  * @returns a new LCH Color
8208
8233
  */
8209
8234
  static LABtoLCH(lab, normalizedInput = false, normalizedOutput = false) {
8210
- let c = normalizedInput ? lab.$normalize(false) : lab;
8211
- let h = Geom.toDegree(Geom.boundRadian(Math.atan2(c[2], c[1])));
8235
+ const c = normalizedInput ? lab.$normalize(false) : lab;
8236
+ const h = Geom.toDegree(Geom.boundRadian(Math.atan2(c[2], c[1])));
8212
8237
  return _Color.lch(
8213
8238
  c[0],
8214
8239
  Math.sqrt(c[1] * c[1] + c[2] * c[2]),
@@ -8224,8 +8249,8 @@ See https://github.com/williamngan/pts for details. */
8224
8249
  * @returns a new LAB Color
8225
8250
  */
8226
8251
  static LCHtoLAB(lch, normalizedInput = false, normalizedOutput = false) {
8227
- let c = normalizedInput ? lch.$normalize(false) : lch;
8228
- let rad = Geom.toRadian(c[2]);
8252
+ const c = normalizedInput ? lch.$normalize(false) : lch;
8253
+ const rad = Geom.toRadian(c[2]);
8229
8254
  return _Color.lab(
8230
8255
  c[0],
8231
8256
  Math.cos(rad) * c[1],
@@ -8234,13 +8259,12 @@ See https://github.com/williamngan/pts for details. */
8234
8259
  );
8235
8260
  }
8236
8261
  };
8237
- var Color = _Color;
8238
8262
  // XYZ property for Standard Observer 2deg, Daylight/sRGB illuminant D65
8239
- Color.D65 = new Pt(95.047, 100, 108.883, 1);
8263
+ _Color.D65 = new Pt(95.047, 100, 108.883, 1);
8240
8264
  /**
8241
8265
  * Value range for each color space
8242
8266
  */
8243
- Color.ranges = {
8267
+ _Color.ranges = {
8244
8268
  rgb: new Group(new Pt(0, 255), new Pt(0, 255), new Pt(0, 255)),
8245
8269
  hsl: new Group(new Pt(0, 360), new Pt(0, 1), new Pt(0, 1)),
8246
8270
  hsb: new Group(new Pt(0, 360), new Pt(0, 1), new Pt(0, 1)),
@@ -8249,6 +8273,7 @@ See https://github.com/williamngan/pts for details. */
8249
8273
  luv: new Group(new Pt(0, 100), new Pt(-134, 220), new Pt(-140, 122)),
8250
8274
  xyz: new Group(new Pt(0, 100), new Pt(0, 100), new Pt(0, 100))
8251
8275
  };
8276
+ var Color = _Color;
8252
8277
 
8253
8278
  // src/Dom.ts
8254
8279
  var Dom_exports = {};
@@ -8257,7 +8282,7 @@ See https://github.com/williamngan/pts for details. */
8257
8282
  HTMLForm: () => HTMLForm,
8258
8283
  HTMLSpace: () => HTMLSpace
8259
8284
  });
8260
- var DOMSpace = class extends MultiTouchSpace {
8285
+ var DOMSpace = class _DOMSpace extends MultiTouchSpace {
8261
8286
  /**
8262
8287
  * Create a DOMSpace for HTML DOM elements
8263
8288
  * @param elem Specify an element by its "id" attribute as string, or by the element object itself. Use css to customize its appearance if needed.
@@ -8270,8 +8295,8 @@ See https://github.com/williamngan/pts for details. */
8270
8295
  this._autoResize = true;
8271
8296
  this._bgcolor = "#e1e9f0";
8272
8297
  this._css = {};
8273
- var _selector = null;
8274
- var _existed = false;
8298
+ let _selector = null;
8299
+ let _existed = false;
8275
8300
  this.id = "pts";
8276
8301
  if (elem instanceof Element) {
8277
8302
  _selector = elem;
@@ -8282,8 +8307,8 @@ See https://github.com/williamngan/pts for details. */
8282
8307
  this.id = elem.substr(1);
8283
8308
  }
8284
8309
  if (!_selector) {
8285
- this._container = DOMSpace.createElement("div", "pts_container");
8286
- this._canvas = DOMSpace.createElement("div", "pts_element");
8310
+ this._container = _DOMSpace.createElement("div", "pts_container");
8311
+ this._canvas = _DOMSpace.createElement("div", "pts_element");
8287
8312
  this._container.appendChild(this._canvas);
8288
8313
  document.body.appendChild(this._container);
8289
8314
  _existed = false;
@@ -8545,7 +8570,7 @@ See https://github.com/williamngan/pts for details. */
8545
8570
  return super.removeAll();
8546
8571
  }
8547
8572
  };
8548
- var _HTMLForm = class extends VisualForm {
8573
+ var _HTMLForm = class _HTMLForm extends VisualForm {
8549
8574
  /**
8550
8575
  * Create a new `HTMLForm`. Alternatively, you can use [`HTMLSpace.getForm`](#link) function to get an instance of HTMLForm.
8551
8576
  * @param space the space to use
@@ -8964,9 +8989,9 @@ See https://github.com/williamngan/pts for details. */
8964
8989
  return this;
8965
8990
  }
8966
8991
  };
8992
+ _HTMLForm.groupID = 0;
8993
+ _HTMLForm.domID = 0;
8967
8994
  var HTMLForm = _HTMLForm;
8968
- HTMLForm.groupID = 0;
8969
- HTMLForm.domID = 0;
8970
8995
 
8971
8996
  // src/Svg.ts
8972
8997
  var Svg_exports = {};
@@ -8974,7 +8999,7 @@ See https://github.com/williamngan/pts for details. */
8974
8999
  SVGForm: () => SVGForm,
8975
9000
  SVGSpace: () => SVGSpace
8976
9001
  });
8977
- var SVGSpace = class extends DOMSpace {
9002
+ var SVGSpace = class _SVGSpace extends DOMSpace {
8978
9003
  /**
8979
9004
  * Create a SVGSpace which represents a Space for SVG elements.
8980
9005
  * @param elem Specify an element by its "id" attribute as string, or by the element object itself. An element can be an existing `<svg>`, or a `<div>` container in which a new `<svg>` will be created. If left empty, a `<div id="pt_container"><svg id="pt" /></div>` will be added to DOM. Use css to customize its appearance if needed.
@@ -8985,7 +9010,7 @@ See https://github.com/williamngan/pts for details. */
8985
9010
  super(elem, callback);
8986
9011
  this._bgcolor = "#999";
8987
9012
  if (this._canvas.nodeName.toLowerCase() != "svg") {
8988
- let s = SVGSpace.svgElement(this._canvas, "svg", `${this.id}_svg`);
9013
+ let s = _SVGSpace.svgElement(this._canvas, "svg", `${this.id}_svg`);
8989
9014
  this._container = this._canvas;
8990
9015
  this._canvas = s;
8991
9016
  }
@@ -9011,7 +9036,7 @@ See https://github.com/williamngan/pts for details. */
9011
9036
  */
9012
9037
  resize(b, evt) {
9013
9038
  super.resize(b, evt);
9014
- SVGSpace.setAttr(this.element, {
9039
+ _SVGSpace.setAttr(this.element, {
9015
9040
  "viewBox": `0 0 ${this.bound.width} ${this.bound.height}`,
9016
9041
  "width": `${this.bound.width}`,
9017
9042
  "height": `${this.bound.height}`,
@@ -9056,7 +9081,7 @@ See https://github.com/williamngan/pts for details. */
9056
9081
  return super.removeAll();
9057
9082
  }
9058
9083
  };
9059
- var _SVGForm = class extends VisualForm {
9084
+ var _SVGForm = class _SVGForm extends VisualForm {
9060
9085
  /**
9061
9086
  * Create a new SVGForm. You may also use [`SVGSpace.getForm`](#link) to get a default form directly.
9062
9087
  * @param space an instance of SVGSpace
@@ -9550,9 +9575,9 @@ See https://github.com/williamngan/pts for details. */
9550
9575
  return this;
9551
9576
  }
9552
9577
  };
9578
+ _SVGForm.groupID = 0;
9579
+ _SVGForm.domID = 0;
9553
9580
  var SVGForm = _SVGForm;
9554
- SVGForm.groupID = 0;
9555
- SVGForm.domID = 0;
9556
9581
 
9557
9582
  // src/Physics.ts
9558
9583
  var Physics_exports = {};
@@ -9561,7 +9586,7 @@ See https://github.com/williamngan/pts for details. */
9561
9586
  Particle: () => Particle,
9562
9587
  World: () => World
9563
9588
  });
9564
- var World = class {
9589
+ var World = class _World {
9565
9590
  /**
9566
9591
  * Create a `World` for 2D physics simulation.
9567
9592
  * @param bound a Group or an Iterable<Pt> representing a rectangular bounding box
@@ -9649,13 +9674,10 @@ See https://github.com/williamngan/pts for details. */
9649
9674
  * @returns a Body, or undefined if not found
9650
9675
  */
9651
9676
  body(id) {
9652
- let idx = id;
9653
9677
  if (typeof id === "string" && id.length > 0) {
9654
- idx = this._bnames.indexOf(id);
9678
+ return this._bodies[this._bnames.indexOf(id)];
9655
9679
  }
9656
- if (!(idx >= 0))
9657
- return void 0;
9658
- return this._bodies[idx];
9680
+ return typeof id === "number" && id >= 0 ? this._bodies[id] : void 0;
9659
9681
  }
9660
9682
  /**
9661
9683
  * Get a particle in this world by index or string id.
@@ -9663,13 +9685,10 @@ See https://github.com/williamngan/pts for details. */
9663
9685
  * @returns a Particle, or undefined if not found
9664
9686
  */
9665
9687
  particle(id) {
9666
- let idx = id;
9667
9688
  if (typeof id === "string" && id.length > 0) {
9668
- idx = this._pnames.indexOf(id);
9689
+ return this._particles[this._pnames.indexOf(id)];
9669
9690
  }
9670
- if (!(idx >= 0))
9671
- return void 0;
9672
- return this._particles[idx];
9691
+ return typeof id === "number" && id >= 0 ? this._particles[id] : void 0;
9673
9692
  }
9674
9693
  /**
9675
9694
  * Given a body's name, return its index in the bodies array, or -1 if not found.
@@ -9816,7 +9835,7 @@ See https://github.com/williamngan/pts for details. */
9816
9835
  for (let i = 0, len = this._particles.length; i < len; i++) {
9817
9836
  let p = this._particles[i];
9818
9837
  this.integrate(p, dt, this._lastTime);
9819
- World.boundConstraint(p, this._bound, this._damping);
9838
+ _World.boundConstraint(p, this._bound, this._damping);
9820
9839
  for (let k = i + 1; k < len; k++) {
9821
9840
  if (i !== k) {
9822
9841
  let p2 = this._particles[k];
@@ -9837,7 +9856,7 @@ See https://github.com/williamngan/pts for details. */
9837
9856
  if (bds) {
9838
9857
  for (let k = 0, klen = bds.length; k < klen; k++) {
9839
9858
  let bk = bds[k];
9840
- World.boundConstraint(bk, this._bound, this._damping);
9859
+ _World.boundConstraint(bk, this._bound, this._damping);
9841
9860
  this.integrate(bk, dt, this._lastTime);
9842
9861
  }
9843
9862
  for (let k = i + 1; k < len; k++) {
@@ -10020,7 +10039,7 @@ See https://github.com/williamngan/pts for details. */
10020
10039
  return `Particle: ${this[0]} ${this[1]} | previous ${this._prev[0]} ${this._prev[1]} | mass ${this._mass}`;
10021
10040
  }
10022
10041
  };
10023
- var Body = class extends Group {
10042
+ var Body = class _Body extends Group {
10024
10043
  /**
10025
10044
  * Create an empty Body, this is usually followed by [`Body.init`](#link) to populate the Body. Alternatively, use static function [`Body.fromGroup`](#link) to create and initate a body directly.
10026
10045
  */
@@ -10039,7 +10058,7 @@ See https://github.com/williamngan/pts for details. */
10039
10058
  * @param autoMass Automatically calculate the mass based on the area of the polygon. Default is true.
10040
10059
  */
10041
10060
  static fromGroup(body, stiff = 1, autoLink = true, autoMass = true) {
10042
- let b = new Body().init(body);
10061
+ let b = new _Body().init(body);
10043
10062
  if (autoLink)
10044
10063
  b.linkAll(stiff);
10045
10064
  if (autoMass)
@@ -10199,7 +10218,7 @@ See https://github.com/williamngan/pts for details. */
10199
10218
  Sound: () => Sound,
10200
10219
  Tempo: () => Tempo
10201
10220
  });
10202
- var Tempo = class {
10221
+ var Tempo = class _Tempo {
10203
10222
  /**
10204
10223
  * Construct a new Tempo instance by beats-per-minute. Alternatively, you can use [`Tempo.fromBeat`](#link) to create from milliseconds.
10205
10224
  * @param bpm beats per minute
@@ -10215,7 +10234,7 @@ See https://github.com/williamngan/pts for details. */
10215
10234
  * @param ms milliseconds per beat
10216
10235
  */
10217
10236
  static fromBeat(ms) {
10218
- return new Tempo(6e4 / ms);
10237
+ return new _Tempo(6e4 / ms);
10219
10238
  }
10220
10239
  /**
10221
10240
  * Beats-per-minute value
@@ -10257,16 +10276,16 @@ See https://github.com/williamngan/pts for details. */
10257
10276
  * @returns an object with chainable functions
10258
10277
  */
10259
10278
  every(beats) {
10260
- let self = this;
10261
- let p = Array.isArray(beats) ? beats[0] : beats;
10279
+ const self = this;
10280
+ const p = Array.isArray(beats) ? beats[0] : beats;
10262
10281
  return {
10263
10282
  start: function(fn, offset = 0, name) {
10264
- let id = name || self._createID(fn);
10283
+ const id = name || self._createID(fn);
10265
10284
  self._listeners[id] = { name: id, beats, period: p, index: 0, offset, duration: -1, continuous: false, fn };
10266
10285
  return this;
10267
10286
  },
10268
10287
  progress: function(fn, offset = 0, name) {
10269
- let id = name || self._createID(fn);
10288
+ const id = name || self._createID(fn);
10270
10289
  self._listeners[id] = { name: id, beats, period: p, index: 0, offset, duration: -1, continuous: true, fn };
10271
10290
  return this;
10272
10291
  }
@@ -10278,11 +10297,11 @@ See https://github.com/williamngan/pts for details. */
10278
10297
  * @param time current time in milliseconds
10279
10298
  */
10280
10299
  track(time) {
10281
- for (let k in this._listeners) {
10300
+ for (const k in this._listeners) {
10282
10301
  if (this._listeners.hasOwnProperty(k)) {
10283
- let li = this._listeners[k];
10284
- let _t = li.offset ? time + li.offset : time;
10285
- let ms = li.period * this._ms;
10302
+ const li = this._listeners[k];
10303
+ const _t = li.offset ? time + li.offset : time;
10304
+ const ms = li.period * this._ms;
10286
10305
  let isStart = false;
10287
10306
  if (_t > li.duration + ms) {
10288
10307
  li.duration = _t - _t % this._ms;
@@ -10292,10 +10311,10 @@ See https://github.com/williamngan/pts for details. */
10292
10311
  }
10293
10312
  isStart = true;
10294
10313
  }
10295
- let count = Math.max(0, Math.ceil(Math.floor(li.duration / this._ms) / li.period));
10296
- let params = li.continuous ? [count, Num.clamp((_t - li.duration) / ms, 0, 1), _t, isStart] : [count];
10314
+ const count = Math.max(0, Math.ceil(Math.floor(li.duration / this._ms) / li.period));
10315
+ const params = li.continuous ? [count, Num.clamp((_t - li.duration) / ms, 0, 1), _t, isStart] : [count];
10297
10316
  if (li.continuous || isStart) {
10298
- let done = li.fn.apply(li, params);
10317
+ const done = li.fn.apply(li, params);
10299
10318
  if (done)
10300
10319
  delete this._listeners[li.name];
10301
10320
  }
@@ -10329,7 +10348,7 @@ See https://github.com/williamngan/pts for details. */
10329
10348
  return;
10330
10349
  }
10331
10350
  };
10332
- var Sound = class {
10351
+ var Sound = class _Sound {
10333
10352
  // Tracking play time against ctx.currentTime
10334
10353
  /**
10335
10354
  * Construct a `Sound` instance. Usually, it's more convenient to use one of the static methods like [`Sound.load`](#function_load) or [`Sound.from`](#function_from).
@@ -10344,7 +10363,7 @@ See https://github.com/williamngan/pts for details. */
10344
10363
  * Create an AudioContext instance. This is called internally only.
10345
10364
  */
10346
10365
  _createAudioContext() {
10347
- let _ctx = window.AudioContext;
10366
+ const _ctx = window.AudioContext;
10348
10367
  if (!_ctx)
10349
10368
  throw new Error("Your browser doesn't support Web Audio. (No AudioContext)");
10350
10369
  this._ctx = _ctx ? new _ctx() : void 0;
@@ -10358,7 +10377,7 @@ See https://github.com/williamngan/pts for details. */
10358
10377
  * @returns a `Sound` instance
10359
10378
  */
10360
10379
  static from(node, ctx, type = "gen", stream) {
10361
- let s = new Sound(type);
10380
+ const s = new _Sound(type);
10362
10381
  s._node = node;
10363
10382
  s._ctx = ctx;
10364
10383
  if (stream)
@@ -10374,7 +10393,7 @@ See https://github.com/williamngan/pts for details. */
10374
10393
  */
10375
10394
  static load(source, crossOrigin = "anonymous") {
10376
10395
  return new Promise((resolve, reject) => {
10377
- let s = new Sound("file");
10396
+ const s = new _Sound("file");
10378
10397
  s._source = typeof source === "string" ? new Audio(source) : source;
10379
10398
  s._source.autoplay = false;
10380
10399
  s._source.crossOrigin = crossOrigin;
@@ -10399,10 +10418,10 @@ See https://github.com/williamngan/pts for details. */
10399
10418
  */
10400
10419
  static loadAsBuffer(url) {
10401
10420
  return new Promise((resolve, reject) => {
10402
- let request = new XMLHttpRequest();
10421
+ const request = new XMLHttpRequest();
10403
10422
  request.open("GET", url, true);
10404
10423
  request.responseType = "arraybuffer";
10405
- let s = new Sound("file");
10424
+ const s = new _Sound("file");
10406
10425
  request.onload = function() {
10407
10426
  s._ctx.decodeAudioData(request.response, function(buffer) {
10408
10427
  s.createBuffer(buffer);
@@ -10434,13 +10453,13 @@ See https://github.com/williamngan/pts for details. */
10434
10453
  * @example `Sound.generate( 'sine', 120 )`
10435
10454
  */
10436
10455
  static generate(type, val) {
10437
- let s = new Sound("gen");
10456
+ const s = new _Sound("gen");
10438
10457
  return s._gen(type, val);
10439
10458
  }
10440
10459
  // Create the oscillator
10441
10460
  _gen(type, val) {
10442
10461
  this._node = this._ctx.createOscillator();
10443
- let osc = this._node;
10462
+ const osc = this._node;
10444
10463
  osc.type = type;
10445
10464
  if (type === "custom") {
10446
10465
  osc.setPeriodicWave(val);
@@ -10458,7 +10477,7 @@ See https://github.com/williamngan/pts for details. */
10458
10477
  static input(constraint) {
10459
10478
  return __async(this, null, function* () {
10460
10479
  try {
10461
- let s = new Sound("input");
10480
+ const s = new _Sound("input");
10462
10481
  if (!s)
10463
10482
  return void 0;
10464
10483
  const c = constraint ? constraint : { audio: true, video: false };
@@ -10528,7 +10547,7 @@ See https://github.com/williamngan/pts for details. */
10528
10547
  get progress() {
10529
10548
  let dur = 0;
10530
10549
  let curr = 0;
10531
- if (!!this._buffer) {
10550
+ if (this._buffer) {
10532
10551
  dur = this._buffer.duration;
10533
10552
  curr = this._timestamp ? this._ctx.currentTime - this._timestamp : 0;
10534
10553
  } else {
@@ -10600,7 +10619,7 @@ See https://github.com/williamngan/pts for details. */
10600
10619
  * @param smooth Optional smoothing value (corresponds to `AnalyserNode.smoothingTimeConstant`)
10601
10620
  */
10602
10621
  analyze(size = 256, minDb = -100, maxDb = -30, smooth = 0.8) {
10603
- let a = this._ctx.createAnalyser();
10622
+ const a = this._ctx.createAnalyser();
10604
10623
  a.fftSize = size * 2;
10605
10624
  a.minDecibels = minDb;
10606
10625
  a.maxDecibels = maxDb;
@@ -10627,8 +10646,8 @@ See https://github.com/williamngan/pts for details. */
10627
10646
  }
10628
10647
  // Map domain data to another range
10629
10648
  _domainTo(time, size, position = [0, 0], trim = [0, 0]) {
10630
- let data = time ? this.timeDomain() : this.freqDomain();
10631
- let g = new Group();
10649
+ const data = time ? this.timeDomain() : this.freqDomain();
10650
+ const g = new Group();
10632
10651
  for (let i = trim[0], len = data.length - trim[1]; i < len; i++) {
10633
10652
  g.push(new Pt(position[0] + size[0] * i / len, position[1] + size[1] * data[i] / 255));
10634
10653
  }
@@ -10687,7 +10706,7 @@ See https://github.com/williamngan/pts for details. */
10687
10706
  this._ctx.resume();
10688
10707
  }
10689
10708
  if (this._type === "file") {
10690
- if (!!this._buffer) {
10709
+ if (this._buffer) {
10691
10710
  this._node.start(timeAt);
10692
10711
  this._timestamp = this._ctx.currentTime + timeAt;
10693
10712
  } else {
@@ -10712,7 +10731,7 @@ See https://github.com/williamngan/pts for details. */
10712
10731
  if (this._playing)
10713
10732
  (this._outputNode || this._node).disconnect(this._ctx.destination);
10714
10733
  if (this._type === "file") {
10715
- if (!!this._buffer) {
10734
+ if (this._buffer) {
10716
10735
  if (this.progress < 1)
10717
10736
  this._node.stop();
10718
10737
  } else {