@sarmal/core 0.26.0 → 0.27.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/dist/auto-init.cjs +145 -106
  2. package/dist/auto-init.js +144 -105
  3. package/dist/cli.js +1048 -0
  4. package/dist/cli.js.map +1 -0
  5. package/dist/curves/artemis2.cjs +16 -10
  6. package/dist/curves/artemis2.d.cts +1 -1
  7. package/dist/curves/artemis2.d.ts +1 -1
  8. package/dist/curves/artemis2.js +15 -9
  9. package/dist/curves/astroid.cjs +4 -4
  10. package/dist/curves/astroid.d.cts +1 -1
  11. package/dist/curves/astroid.d.ts +1 -1
  12. package/dist/curves/astroid.js +3 -3
  13. package/dist/curves/deltoid.cjs +4 -4
  14. package/dist/curves/deltoid.d.cts +1 -1
  15. package/dist/curves/deltoid.d.ts +1 -1
  16. package/dist/curves/deltoid.js +3 -3
  17. package/dist/curves/epicycloid3.cjs +4 -4
  18. package/dist/curves/epicycloid3.d.cts +1 -1
  19. package/dist/curves/epicycloid3.d.ts +1 -1
  20. package/dist/curves/epicycloid3.js +3 -3
  21. package/dist/curves/epitrochoid7.cjs +5 -5
  22. package/dist/curves/epitrochoid7.d.cts +1 -1
  23. package/dist/curves/epitrochoid7.d.ts +1 -1
  24. package/dist/curves/epitrochoid7.js +4 -4
  25. package/dist/curves/index.cjs +59 -43
  26. package/dist/curves/index.d.cts +29 -29
  27. package/dist/curves/index.d.ts +29 -29
  28. package/dist/curves/index.js +75 -43
  29. package/dist/curves/lame.cjs +6 -5
  30. package/dist/curves/lame.d.cts +1 -1
  31. package/dist/curves/lame.d.ts +1 -1
  32. package/dist/curves/lame.js +5 -4
  33. package/dist/curves/lissajous32.cjs +4 -4
  34. package/dist/curves/lissajous32.d.cts +1 -1
  35. package/dist/curves/lissajous32.d.ts +1 -1
  36. package/dist/curves/lissajous32.js +3 -3
  37. package/dist/curves/lissajous43.cjs +4 -4
  38. package/dist/curves/lissajous43.d.cts +1 -1
  39. package/dist/curves/lissajous43.d.ts +1 -1
  40. package/dist/curves/lissajous43.js +3 -3
  41. package/dist/curves/rose3.cjs +4 -4
  42. package/dist/curves/rose3.d.cts +1 -1
  43. package/dist/curves/rose3.d.ts +1 -1
  44. package/dist/curves/rose3.js +3 -3
  45. package/dist/curves/rose5.cjs +4 -4
  46. package/dist/curves/rose5.d.cts +1 -1
  47. package/dist/curves/rose5.d.ts +1 -1
  48. package/dist/curves/rose5.js +3 -3
  49. package/dist/curves/rose52.cjs +5 -5
  50. package/dist/curves/rose52.d.cts +1 -1
  51. package/dist/curves/rose52.d.ts +1 -1
  52. package/dist/curves/rose52.js +4 -4
  53. package/dist/curves/star.cjs +8 -5
  54. package/dist/curves/star.d.cts +1 -1
  55. package/dist/curves/star.d.ts +1 -1
  56. package/dist/curves/star.js +7 -4
  57. package/dist/curves/star4.cjs +8 -5
  58. package/dist/curves/star4.d.cts +1 -1
  59. package/dist/curves/star4.d.ts +1 -1
  60. package/dist/curves/star4.js +7 -4
  61. package/dist/curves/star7.cjs +8 -5
  62. package/dist/curves/star7.d.cts +1 -1
  63. package/dist/curves/star7.d.ts +1 -1
  64. package/dist/curves/star7.js +7 -4
  65. package/dist/index.cjs +131 -94
  66. package/dist/index.d.cts +78 -58
  67. package/dist/index.d.ts +78 -58
  68. package/dist/index.js +152 -94
  69. package/dist/renderer-shared-OR--cv-t.d.ts +49 -0
  70. package/dist/renderer-shared-jqw_Q1WO.d.cts +49 -0
  71. package/dist/terminal.cjs +593 -0
  72. package/dist/terminal.cjs.map +1 -0
  73. package/dist/terminal.d.cts +44 -0
  74. package/dist/terminal.d.ts +44 -0
  75. package/dist/terminal.js +585 -0
  76. package/dist/terminal.js.map +1 -0
  77. package/dist/types-zbxUgcmZ.d.cts +280 -266
  78. package/dist/types-zbxUgcmZ.d.ts +280 -266
  79. package/package.json +11 -1
package/dist/index.js CHANGED
@@ -61,13 +61,13 @@ function resolveCurve(curveDef) {
61
61
  period,
62
62
  speed,
63
63
  skeleton: curveDef.skeleton,
64
- skeletonFn: curveDef.skeletonFn
64
+ skeletonFn: curveDef.skeletonFn,
65
65
  };
66
66
  }
67
67
  function createEngine(curveDef, trailLength = 120) {
68
68
  if (!Number.isFinite(trailLength) || trailLength <= 0) {
69
69
  throw new RangeError(
70
- `[sarmal] trailLength must be a positive finite number, got ${trailLength}`
70
+ `[sarmal] trailLength must be a positive finite number, got ${trailLength}`,
71
71
  );
72
72
  }
73
73
  let curve = resolveCurve(curveDef);
@@ -108,7 +108,8 @@ function createEngine(curveDef, trailLength = 120) {
108
108
  actualTime += deltaTime;
109
109
  if (morphCurveB !== null && _morphAlpha !== null) {
110
110
  const a = curve.fn(phase, actualTime, EMPTY_PARAMS);
111
- const phaseB = _morphStrategy === "normalized" ? phase / curve.period * morphCurveB.period : phase;
111
+ const phaseB =
112
+ _morphStrategy === "normalized" ? (phase / curve.period) * morphCurveB.period : phase;
112
113
  const b = morphCurveB.fn(phaseB, actualTime, EMPTY_PARAMS);
113
114
  trail.push(a.x + (b.x - a.x) * _morphAlpha, a.y + (b.y - a.y) * _morphAlpha);
114
115
  } else {
@@ -135,14 +136,14 @@ function createEngine(curveDef, trailLength = 120) {
135
136
  trail.clear();
136
137
  },
137
138
  jump(newPhase, { clearTrail = false } = {}) {
138
- phase = (newPhase % curve.period + curve.period) % curve.period;
139
+ phase = ((newPhase % curve.period) + curve.period) % curve.period;
139
140
  if (clearTrail) {
140
141
  trail.clear();
141
142
  }
142
143
  },
143
144
  seek(targetPhase, { wrap = false, step = curve.period / trailLength } = {}) {
144
145
  const advance = curve.speed * step;
145
- const target = (targetPhase % curve.period + curve.period) % curve.period;
146
+ const target = ((targetPhase % curve.period) + curve.period) % curve.period;
146
147
  const targetTime = target / curve.speed;
147
148
  phase = target;
148
149
  actualTime = targetTime;
@@ -151,7 +152,7 @@ function createEngine(curveDef, trailLength = 120) {
151
152
  const count = wrap ? trailLength : Math.min(trailLength, pointsFromStart);
152
153
  for (let i = count - 1; i >= 0; i--) {
153
154
  const samplePhase = target - i * advance;
154
- const wrappedPhase = (samplePhase % curve.period + curve.period) % curve.period;
155
+ const wrappedPhase = ((samplePhase % curve.period) + curve.period) % curve.period;
155
156
  const elapsed = targetTime - i * step;
156
157
  const point = curve.fn(wrappedPhase, elapsed, EMPTY_PARAMS);
157
158
  trail.push(point.x, point.y);
@@ -168,13 +169,16 @@ function createEngine(curveDef, trailLength = 120) {
168
169
  ...frozenB,
169
170
  fn: (samplePhase, elapsed, params) => {
170
171
  const a = frozenA.fn(samplePhase, elapsed, params);
171
- const phaseB = frozenStrategy === "normalized" ? samplePhase / frozenA.period * frozenB.period : samplePhase;
172
+ const phaseB =
173
+ frozenStrategy === "normalized"
174
+ ? (samplePhase / frozenA.period) * frozenB.period
175
+ : samplePhase;
172
176
  const b = frozenB.fn(phaseB, elapsed, params);
173
177
  return {
174
178
  x: a.x + (b.x - a.x) * frozenAlpha,
175
- y: a.y + (b.y - a.y) * frozenAlpha
179
+ y: a.y + (b.y - a.y) * frozenAlpha,
176
180
  };
177
- }
181
+ },
178
182
  };
179
183
  }
180
184
  _morphStrategy = strategy;
@@ -187,7 +191,7 @@ function createEngine(curveDef, trailLength = 120) {
187
191
  completeMorph() {
188
192
  if (morphCurveB !== null) {
189
193
  if (_morphStrategy === "normalized" && curve.period !== morphCurveB.period) {
190
- phase = phase / curve.period * morphCurveB.period;
194
+ phase = (phase / curve.period) * morphCurveB.period;
191
195
  }
192
196
  curve = morphCurveB;
193
197
  }
@@ -199,19 +203,22 @@ function createEngine(curveDef, trailLength = 120) {
199
203
  const points2 = new Array(steps);
200
204
  if (morphCurveB !== null && _morphAlpha !== null) {
201
205
  for (let i = 0; i < steps; i++) {
202
- const samplePhase = i / (steps - 1) * curve.period;
206
+ const samplePhase = (i / (steps - 1)) * curve.period;
203
207
  const a = sampleSkeleton(curve, samplePhase);
204
- const phaseB = _morphStrategy === "normalized" ? samplePhase / curve.period * morphCurveB.period : samplePhase;
208
+ const phaseB =
209
+ _morphStrategy === "normalized"
210
+ ? (samplePhase / curve.period) * morphCurveB.period
211
+ : samplePhase;
205
212
  const b = sampleSkeleton(morphCurveB, phaseB);
206
213
  points2[i] = {
207
214
  x: a.x + (b.x - a.x) * _morphAlpha,
208
- y: a.y + (b.y - a.y) * _morphAlpha
215
+ y: a.y + (b.y - a.y) * _morphAlpha,
209
216
  };
210
217
  }
211
218
  return points2;
212
219
  }
213
220
  for (let i = 0; i < steps; i++) {
214
- const samplePhase = i / (steps - 1) * curve.period;
221
+ const samplePhase = (i / (steps - 1)) * curve.period;
215
222
  points2[i] = sampleSkeleton(curve, samplePhase);
216
223
  }
217
224
  return points2;
@@ -253,7 +260,7 @@ function createEngine(curveDef, trailLength = 120) {
253
260
  _speedTransition.reject(new Error("Speed transition cancelled"));
254
261
  _speedTransition = null;
255
262
  }
256
- }
263
+ },
257
264
  };
258
265
  }
259
266
 
@@ -292,7 +299,15 @@ function computeNormal(trail, i) {
292
299
  const tangent = computeTangent(trail, i);
293
300
  return { x: -tangent.y, y: tangent.x };
294
301
  }
295
- function computeTrailQuad(trail, i, trailCount, toX, toY, minWidth = TRAIL_MIN_WIDTH, maxWidth = TRAIL_MAX_WIDTH) {
302
+ function computeTrailQuad(
303
+ trail,
304
+ i,
305
+ trailCount,
306
+ toX,
307
+ toY,
308
+ minWidth = TRAIL_MIN_WIDTH,
309
+ maxWidth = TRAIL_MAX_WIDTH,
310
+ ) {
296
311
  const progress = i / (trailCount - 1);
297
312
  const nextProgress = (i + 1) / (trailCount - 1);
298
313
  const opacity = Math.pow(progress, TRAIL_FADE_CURVE) * TRAIL_MAX_OPACITY;
@@ -316,13 +331,16 @@ function computeTrailQuad(trail, i, trailCount, toX, toY, minWidth = TRAIL_MIN_W
316
331
  r1x: nx - n1.x * w1,
317
332
  r1y: ny - n1.y * w1,
318
333
  opacity,
319
- progress
334
+ progress,
320
335
  };
321
336
  }
322
337
  function computeBoundaries(pts, logicalWidth, logicalHeight, minPaddingPx = FIT_PADDING_MIN) {
323
338
  if (pts.length === 0) return null;
324
339
  const first = pts[0];
325
- let minX = first.x, maxX = first.x, minY = first.y, maxY = first.y;
340
+ let minX = first.x,
341
+ maxX = first.x,
342
+ minY = first.y,
343
+ maxY = first.y;
326
344
  for (const p of pts) {
327
345
  if (p.x < minX) {
328
346
  minX = p.x;
@@ -341,7 +359,7 @@ function computeBoundaries(pts, logicalWidth, logicalHeight, minPaddingPx = FIT_
341
359
  const h = maxY - minY;
342
360
  if (w === 0 && h === 0) {
343
361
  throw new Error(
344
- "[sarmal] Degenerate curve: all skeleton points are identical. Check that your curve fn returns distinct points for different values of t."
362
+ "[sarmal] Degenerate curve: all skeleton points are identical. Check that your curve fn returns distinct points for different values of t.",
345
363
  );
346
364
  }
347
365
  const scaleXProportional = logicalWidth / (w * (1 + FIT_PADDING * 2));
@@ -352,12 +370,12 @@ function computeBoundaries(pts, logicalWidth, logicalHeight, minPaddingPx = FIT_
352
370
  scaleXProportional,
353
371
  scaleYProportional,
354
372
  scaleXMinPadding,
355
- scaleYMinPadding
373
+ scaleYMinPadding,
356
374
  );
357
375
  return {
358
376
  scale,
359
377
  offsetX: (logicalWidth - w * scale) / 2 - minX * scale,
360
- offsetY: (logicalHeight - h * scale) / 2 - minY * scale
378
+ offsetY: (logicalHeight - h * scale) / 2 - minY * scale,
361
379
  };
362
380
  }
363
381
  function enginePassthroughs(engine) {
@@ -368,7 +386,7 @@ function enginePassthroughs(engine) {
368
386
  getSpeed: engine.getSpeed,
369
387
  resetSpeed: engine.resetSpeed,
370
388
  setSpeedOver: engine.setSpeedOver,
371
- getSarmalSkeleton: engine.getSarmalSkeleton
389
+ getSarmalSkeleton: engine.getSarmalSkeleton,
372
390
  };
373
391
  }
374
392
  var palettes = {
@@ -377,16 +395,16 @@ var palettes = {
377
395
  ocean: ["#1e3a8a", "#06b6d4", "#22d3ee", "#e0f2fe"],
378
396
  ice: ["#1e3a8a", "#67e8f9"],
379
397
  fire: ["#7f1d1d", "#fbbf24"],
380
- forest: ["#14532d", "#86efac"]
398
+ forest: ["#14532d", "#86efac"],
381
399
  };
382
400
  function hexToRgb(hex) {
383
401
  const n = parseInt(hex.slice(1), 16);
384
- return { r: n >> 16, g: n >> 8 & 255, b: n & 255 };
402
+ return { r: n >> 16, g: (n >> 8) & 255, b: n & 255 };
385
403
  }
386
404
  var lerpRgb = (a, b, t) => ({
387
405
  r: Math.round(a.r + (b.r - a.r) * t),
388
406
  g: Math.round(a.g + (b.g - a.g) * t),
389
- b: Math.round(a.b + (b.b - a.b) * t)
407
+ b: Math.round(a.b + (b.b - a.b) * t),
390
408
  });
391
409
  function getPaletteColor(palette, position, timeOffset = 0) {
392
410
  if (palette.length === 0) {
@@ -395,7 +413,7 @@ function getPaletteColor(palette, position, timeOffset = 0) {
395
413
  if (palette.length === 1) {
396
414
  return hexToRgb(palette[0]);
397
415
  }
398
- const cyclePos = ((position + timeOffset) % 1 + 1) % 1;
416
+ const cyclePos = (((position + timeOffset) % 1) + 1) % 1;
399
417
  const scaled = cyclePos * palette.length;
400
418
  const idx = Math.floor(scaled);
401
419
  const t = scaled - idx;
@@ -410,7 +428,7 @@ var RENDER_OPTION_KEYS = /* @__PURE__ */ new Set([
410
428
  "headColor",
411
429
  "skeletonColor",
412
430
  "trailStyle",
413
- "headRadius"
431
+ "headRadius",
414
432
  ]);
415
433
  function validateRenderOptions(partial) {
416
434
  for (const key of Object.keys(partial)) {
@@ -438,7 +456,7 @@ function assertTrailColor(value) {
438
456
  if (typeof value === "string") {
439
457
  if (!HEX_COLOR_RE.test(value)) {
440
458
  throw new TypeError(
441
- `[sarmal] setRenderOptions: trailColor must be a 6-digit hex string, got "${value}"`
459
+ `[sarmal] setRenderOptions: trailColor must be a 6-digit hex string, got "${value}"`,
442
460
  );
443
461
  }
444
462
  return;
@@ -446,21 +464,21 @@ function assertTrailColor(value) {
446
464
  if (Array.isArray(value)) {
447
465
  if (value.length < 2) {
448
466
  throw new RangeError(
449
- `[sarmal] setRenderOptions: trailColor array must have at least 2 entries, got ${value.length}`
467
+ `[sarmal] setRenderOptions: trailColor array must have at least 2 entries, got ${value.length}`,
450
468
  );
451
469
  }
452
470
  for (let i = 0; i < value.length; i++) {
453
471
  const entry = value[i];
454
472
  if (typeof entry !== "string" || !HEX_COLOR_RE.test(entry)) {
455
473
  throw new TypeError(
456
- `[sarmal] setRenderOptions: trailColor[${i}] must be a 6-digit hex string, got ${JSON.stringify(entry)}`
474
+ `[sarmal] setRenderOptions: trailColor[${i}] must be a 6-digit hex string, got ${JSON.stringify(entry)}`,
457
475
  );
458
476
  }
459
477
  }
460
478
  return;
461
479
  }
462
480
  throw new TypeError(
463
- `[sarmal] setRenderOptions: trailColor must be a 6-digit hex string or an array of hex strings, got ${JSON.stringify(value)}`
481
+ `[sarmal] setRenderOptions: trailColor must be a 6-digit hex string or an array of hex strings, got ${JSON.stringify(value)}`,
464
482
  );
465
483
  }
466
484
  function assertHeadColor(value) {
@@ -469,7 +487,7 @@ function assertHeadColor(value) {
469
487
  }
470
488
  if (typeof value !== "string" || !HEX_COLOR_RE.test(value)) {
471
489
  throw new TypeError(
472
- `[sarmal] setRenderOptions: headColor must be a 6-digit hex string or null, got ${JSON.stringify(value)}`
490
+ `[sarmal] setRenderOptions: headColor must be a 6-digit hex string or null, got ${JSON.stringify(value)}`,
473
491
  );
474
492
  }
475
493
  }
@@ -479,26 +497,26 @@ function assertSkeletonColor(value) {
479
497
  }
480
498
  if (typeof value !== "string" || !HEX_COLOR_RE.test(value)) {
481
499
  throw new TypeError(
482
- `[sarmal] setRenderOptions: skeletonColor must be a 6-digit hex string or "transparent", got ${JSON.stringify(value)}`
500
+ `[sarmal] setRenderOptions: skeletonColor must be a 6-digit hex string or "transparent", got ${JSON.stringify(value)}`,
483
501
  );
484
502
  }
485
503
  }
486
504
  function assertTrailStyle(value) {
487
505
  if (!TRAIL_STYLES.includes(value)) {
488
506
  throw new RangeError(
489
- `[sarmal] setRenderOptions: trailStyle must be one of "default", "gradient-static", "gradient-animated", got ${JSON.stringify(value)}`
507
+ `[sarmal] setRenderOptions: trailStyle must be one of "default", "gradient-static", "gradient-animated", got ${JSON.stringify(value)}`,
490
508
  );
491
509
  }
492
510
  }
493
511
  function assertHeadRadius(value) {
494
512
  if (typeof value !== "number") {
495
513
  throw new TypeError(
496
- `[sarmal] setRenderOptions: headRadius must be a number, got ${JSON.stringify(value)}`
514
+ `[sarmal] setRenderOptions: headRadius must be a number, got ${JSON.stringify(value)}`,
497
515
  );
498
516
  }
499
517
  if (!Number.isFinite(value) || value <= 0) {
500
518
  throw new TypeError(
501
- `[sarmal] setRenderOptions: headRadius must be a finite positive number, got ${value}`
519
+ `[sarmal] setRenderOptions: headRadius must be a finite positive number, got ${value}`,
502
520
  );
503
521
  }
504
522
  }
@@ -520,13 +538,13 @@ function resolveHeadColor(trailColor, trailStyle) {
520
538
  function warnIfTrailColorMismatch(trailColor, trailStyle) {
521
539
  if (trailStyle === "default" && Array.isArray(trailColor)) {
522
540
  console.warn(
523
- '[sarmal] trailColor is an array but trailStyle is "default"; only the first color will be used. Pass a gradient trailStyle to use the whole palette.'
541
+ '[sarmal] trailColor is an array but trailStyle is "default"; only the first color will be used. Pass a gradient trailStyle to use the whole palette.',
524
542
  );
525
543
  return;
526
544
  }
527
545
  if (trailStyle !== "default" && typeof trailColor === "string") {
528
546
  console.warn(
529
- `[sarmal] trailColor is a single color but trailStyle is "${trailStyle}"; the trail will render as a solid color. Pass an array of hex colors to use a real gradient.`
547
+ `[sarmal] trailColor is a single color but trailStyle is "${trailStyle}"; the trail will render as a solid color. Pass an array of hex colors to use a real gradient.`,
530
548
  );
531
549
  }
532
550
  }
@@ -536,7 +554,7 @@ var getHeadDotRadius = (w, h) => Math.max(1, 3 * Math.sqrt(Math.min(w, h) / 160)
536
554
  var WHITE_HEX = "#ffffff";
537
555
  function hexToRgbComponents(hex) {
538
556
  const n = parseInt(hex.slice(1), 16);
539
- return `${n >> 16},${n >> 8 & 255},${n & 255}`;
557
+ return `${n >> 16},${(n >> 8) & 255},${n & 255}`;
540
558
  }
541
559
  function applyDprSizing(target, logicalWidth, logicalHeight, dpr) {
542
560
  target.style.width = `${logicalWidth}px`;
@@ -663,7 +681,7 @@ function createRenderer(options) {
663
681
  i,
664
682
  trailCount,
665
683
  toX,
666
- toY
684
+ toY,
667
685
  );
668
686
  if (trailStyle === "default") {
669
687
  ctx.fillStyle = `rgba(${trailSolidRgb},${opacity})`;
@@ -828,7 +846,7 @@ function createRenderer(options) {
828
846
  if (partial.trailColor !== void 0 || partial.trailStyle !== void 0) {
829
847
  warnIfTrailColorMismatch(trailColor, trailStyle);
830
848
  }
831
- }
849
+ },
832
850
  };
833
851
  const pauseOnHidden = options.pauseOnHidden !== false;
834
852
  function handleVisibilityChange() {
@@ -878,8 +896,10 @@ function sampleCurveSkeleton(curveDef) {
878
896
  const samples = Math.ceil(period * 50);
879
897
  const pts = Array.from({ length: samples });
880
898
  for (let i = 0; i < samples; i++) {
881
- const phase = i / (samples - 1) * period;
882
- pts[i] = curveDef.skeletonFn ? curveDef.skeletonFn(phase) : curveDef.fn(phase, 0, EMPTY_PARAMS2);
899
+ const phase = (i / (samples - 1)) * period;
900
+ pts[i] = curveDef.skeletonFn
901
+ ? curveDef.skeletonFn(phase)
902
+ : curveDef.fn(phase, 0, EMPTY_PARAMS2);
883
903
  }
884
904
  return pts;
885
905
  }
@@ -891,7 +911,7 @@ function createSVGRenderer(options) {
891
911
  const poolSize = engine.trailLength;
892
912
  if (poolSize > HIGH_TRAIL_LENGTH_THRESHOLD) {
893
913
  console.warn(
894
- `[sarmal] High trailLength in SVG renderer (${poolSize}). Consider using the canvas renderer for long trails.`
914
+ `[sarmal] High trailLength in SVG renderer (${poolSize}). Consider using the canvas renderer for long trails.`,
895
915
  );
896
916
  }
897
917
  let trailStyle = options.trailStyle ?? "default";
@@ -910,9 +930,9 @@ function createSVGRenderer(options) {
910
930
  return rect.width && rect.height ? Math.min(rect.width, rect.height) : 200;
911
931
  }
912
932
  const containerPx = getContainerPixelSize();
913
- const svgTrailMinWidth = TRAIL_MIN_WIDTH * viewSize / containerPx;
914
- const svgTrailMaxWidth = TRAIL_MAX_WIDTH * viewSize / containerPx;
915
- const svgSkeletonStrokeWidth = String(SKELETON_STROKE_WIDTH_PX * viewSize / containerPx);
933
+ const svgTrailMinWidth = (TRAIL_MIN_WIDTH * viewSize) / containerPx;
934
+ const svgTrailMaxWidth = (TRAIL_MAX_WIDTH * viewSize) / containerPx;
935
+ const svgSkeletonStrokeWidth = String((SKELETON_STROKE_WIDTH_PX * viewSize) / containerPx);
916
936
  headRadius = options.headRadius ?? SVG_DEFAULT_HEAD_RADIUS;
917
937
  container.setAttribute("viewBox", `0 0 ${viewSize} ${viewSize}`);
918
938
  container.setAttribute("role", "img");
@@ -1000,7 +1020,7 @@ function createSVGRenderer(options) {
1000
1020
  px,
1001
1021
  py,
1002
1022
  svgTrailMinWidth,
1003
- svgTrailMaxWidth
1023
+ svgTrailMaxWidth,
1004
1024
  );
1005
1025
  const d = `M${l0x.toFixed(2)} ${l0y.toFixed(2)} L${l1x.toFixed(2)} ${l1y.toFixed(2)} L${r1x.toFixed(2)} ${r1y.toFixed(2)} L${r0x.toFixed(2)} ${r0y.toFixed(2)} Z`;
1006
1026
  trailPaths[i].setAttribute("d", d);
@@ -1028,7 +1048,8 @@ function createSVGRenderer(options) {
1028
1048
  let animationId = null;
1029
1049
  let lastTime = 0;
1030
1050
  let pausedByVisibility = false;
1031
- const prefersReducedMotion = typeof window !== "undefined" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
1051
+ const prefersReducedMotion =
1052
+ typeof window !== "undefined" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
1032
1053
  let morphResolve = null;
1033
1054
  let morphReject = null;
1034
1055
  let morphDurationMs = DEFAULT_MORPH_DURATION_MS;
@@ -1046,7 +1067,7 @@ function createSVGRenderer(options) {
1046
1067
  skeletonPathA.setAttribute("visibility", "visible");
1047
1068
  skeletonPathA.setAttribute(
1048
1069
  "stroke-opacity",
1049
- String((1 - morphAlpha) * DEFAULT_SKELETON_OPACITY)
1070
+ String((1 - morphAlpha) * DEFAULT_SKELETON_OPACITY),
1050
1071
  );
1051
1072
  }
1052
1073
  if (morphPathBBuilt) {
@@ -1200,7 +1221,7 @@ function createSVGRenderer(options) {
1200
1221
  if (partial.trailColor !== void 0 || partial.trailStyle !== void 0) {
1201
1222
  warnIfTrailColorMismatch(trailColor, trailStyle);
1202
1223
  }
1203
- }
1224
+ },
1204
1225
  };
1205
1226
  const pauseOnHidden = options.pauseOnHidden !== false;
1206
1227
  function handleVisibilityChange() {
@@ -1238,7 +1259,13 @@ var PERIOD = 2 * Math.PI;
1238
1259
  function catmullRom1D(p0, p1, p2, p3, u) {
1239
1260
  const u2 = u * u;
1240
1261
  const u3 = u2 * u;
1241
- return 0.5 * (2 * p1 + (-p0 + p2) * u + (2 * p0 - 5 * p1 + 4 * p2 - p3) * u2 + (-p0 + 3 * p1 - 3 * p2 + p3) * u3);
1262
+ return (
1263
+ 0.5 *
1264
+ (2 * p1 +
1265
+ (-p0 + p2) * u +
1266
+ (2 * p0 - 5 * p1 + 4 * p2 - p3) * u2 +
1267
+ (-p0 + 3 * p1 - 3 * p2 + p3) * u3)
1268
+ );
1242
1269
  }
1243
1270
  function evaluateCatmullRom(points2, phase) {
1244
1271
  const N = points2.length;
@@ -1248,7 +1275,7 @@ function evaluateCatmullRom(points2, phase) {
1248
1275
  if (N === 1) {
1249
1276
  return { x: points2[0][0], y: points2[0][1] };
1250
1277
  }
1251
- phase = (phase % PERIOD + PERIOD) % PERIOD;
1278
+ phase = ((phase % PERIOD) + PERIOD) % PERIOD;
1252
1279
  const segmentSize = PERIOD / N;
1253
1280
  let i = Math.floor(phase / segmentSize);
1254
1281
  if (i >= N) {
@@ -1262,7 +1289,7 @@ function evaluateCatmullRom(points2, phase) {
1262
1289
  const p3 = points2[(i + 2) % N];
1263
1290
  return {
1264
1291
  x: catmullRom1D(p0[0], p1[0], p2[0], p3[0], u),
1265
- y: catmullRom1D(p0[1], p1[1], p2[1], p3[1], u)
1292
+ y: catmullRom1D(p0[1], p1[1], p2[1], p3[1], u),
1266
1293
  };
1267
1294
  }
1268
1295
  function drawCurve(points2, opts) {
@@ -1272,20 +1299,20 @@ function drawCurve(points2, opts) {
1272
1299
  const first = points2[0];
1273
1300
  if (points2.every((p) => p[0] === first[0] && p[1] === first[1])) {
1274
1301
  console.warn(
1275
- "[sarmal].drawCurve: all control points are identical. The curve will be a single point."
1302
+ "[sarmal].drawCurve: all control points are identical. The curve will be a single point.",
1276
1303
  );
1277
1304
  }
1278
1305
  const maxAbs = points2.reduce((m, p) => Math.max(m, Math.abs(p[0]), Math.abs(p[1])), 0);
1279
1306
  if (maxAbs > 2) {
1280
1307
  console.warn(
1281
- `[sarmal].drawCurve: control points extend to \xB1${maxAbs.toFixed(1)}, which may render off-screen. Coordinates should be in [-1, 1].`
1308
+ `[sarmal].drawCurve: control points extend to \xB1${maxAbs.toFixed(1)}, which may render off-screen. Coordinates should be in [-1, 1].`,
1282
1309
  );
1283
1310
  }
1284
1311
  const pts = points2.map(([x, y]) => [x, y]);
1285
1312
  return {
1286
1313
  name: opts?.name ?? "drawn",
1287
1314
  fn: (phase) => evaluateCatmullRom(pts, phase),
1288
- period: PERIOD
1315
+ period: PERIOD,
1289
1316
  };
1290
1317
  }
1291
1318
 
@@ -1311,11 +1338,11 @@ var points = [
1311
1338
  [-0.69, -0.84],
1312
1339
  [-0.87, -0.66],
1313
1340
  [-0.9, -0.47],
1314
- [-0.76, -0.35]
1341
+ [-0.76, -0.35],
1315
1342
  ];
1316
1343
  var artemis2 = {
1317
1344
  ...drawCurve(points, { name: "Artemis II" }),
1318
- speed: 0.7
1345
+ speed: 0.7,
1319
1346
  };
1320
1347
 
1321
1348
  // src/curves/astroid.ts
@@ -1325,14 +1352,14 @@ function astroidFn(phase, _elapsed, _params) {
1325
1352
  const s = Math.sin(phase);
1326
1353
  return {
1327
1354
  x: c * c * c,
1328
- y: s * s * s
1355
+ y: s * s * s,
1329
1356
  };
1330
1357
  }
1331
1358
  var astroid = {
1332
1359
  name: "Astroid",
1333
1360
  fn: astroidFn,
1334
1361
  period: TWO_PI2,
1335
- speed: 1.1
1362
+ speed: 1.1,
1336
1363
  };
1337
1364
 
1338
1365
  // src/curves/deltoid.ts
@@ -1340,14 +1367,14 @@ var TWO_PI3 = Math.PI * 2;
1340
1367
  function deltoidFn(phase, _elapsed, _params) {
1341
1368
  return {
1342
1369
  x: 2 * Math.cos(phase) + Math.cos(2 * phase),
1343
- y: 2 * Math.sin(phase) - Math.sin(2 * phase)
1370
+ y: 2 * Math.sin(phase) - Math.sin(2 * phase),
1344
1371
  };
1345
1372
  }
1346
1373
  var deltoid = {
1347
1374
  name: "Deltoid",
1348
1375
  fn: deltoidFn,
1349
1376
  period: TWO_PI3,
1350
- speed: 0.9
1377
+ speed: 0.9,
1351
1378
  };
1352
1379
 
1353
1380
  // src/curves/epicycloid3.ts
@@ -1355,14 +1382,14 @@ var TWO_PI4 = Math.PI * 2;
1355
1382
  function epicycloid3Fn(phase, _elapsed, _params) {
1356
1383
  return {
1357
1384
  x: 4 * Math.cos(phase) - Math.cos(4 * phase),
1358
- y: 4 * Math.sin(phase) - Math.sin(4 * phase)
1385
+ y: 4 * Math.sin(phase) - Math.sin(4 * phase),
1359
1386
  };
1360
1387
  }
1361
1388
  var epicycloid3 = {
1362
1389
  name: "Epicycloid (n=3)",
1363
1390
  fn: epicycloid3Fn,
1364
1391
  period: TWO_PI4,
1365
- speed: 0.75
1392
+ speed: 0.75,
1366
1393
  };
1367
1394
 
1368
1395
  // src/curves/epitrochoid7.ts
@@ -1371,14 +1398,14 @@ function epitrochoid7Fn(phase, _elapsed, _params) {
1371
1398
  const d = 1 + 0.55 * Math.sin(phase * 0.5);
1372
1399
  return {
1373
1400
  x: 7 * Math.cos(phase) - d * Math.cos(7 * phase),
1374
- y: 7 * Math.sin(phase) - d * Math.sin(7 * phase)
1401
+ y: 7 * Math.sin(phase) - d * Math.sin(7 * phase),
1375
1402
  };
1376
1403
  }
1377
1404
  function epitrochoid7SkeletonFn(phase) {
1378
1405
  const d = 1.275;
1379
1406
  return {
1380
1407
  x: 7 * Math.cos(phase) - d * Math.cos(7 * phase),
1381
- y: 7 * Math.sin(phase) - d * Math.sin(7 * phase)
1408
+ y: 7 * Math.sin(phase) - d * Math.sin(7 * phase),
1382
1409
  };
1383
1410
  }
1384
1411
  var epitrochoid7 = {
@@ -1386,7 +1413,7 @@ var epitrochoid7 = {
1386
1413
  fn: epitrochoid7Fn,
1387
1414
  period: TWO_PI5,
1388
1415
  speed: 1.4,
1389
- skeletonFn: epitrochoid7SkeletonFn
1416
+ skeletonFn: epitrochoid7SkeletonFn,
1390
1417
  };
1391
1418
 
1392
1419
  // src/curves/lissajous32.ts
@@ -1395,7 +1422,7 @@ function lissajous32Fn(phase, elapsed, _params) {
1395
1422
  const phi = elapsed * 0.45;
1396
1423
  return {
1397
1424
  x: Math.sin(3 * phase + phi),
1398
- y: Math.sin(2 * phase)
1425
+ y: Math.sin(2 * phase),
1399
1426
  };
1400
1427
  }
1401
1428
  var lissajous32 = {
@@ -1403,7 +1430,7 @@ var lissajous32 = {
1403
1430
  fn: lissajous32Fn,
1404
1431
  period: TWO_PI6,
1405
1432
  speed: 2,
1406
- skeleton: "live"
1433
+ skeleton: "live",
1407
1434
  };
1408
1435
 
1409
1436
  // src/curves/lissajous43.ts
@@ -1412,7 +1439,7 @@ function lissajous43Fn(phase, elapsed, _params) {
1412
1439
  const phi = elapsed * 0.38;
1413
1440
  return {
1414
1441
  x: Math.sin(4 * phase + phi),
1415
- y: Math.sin(3 * phase)
1442
+ y: Math.sin(3 * phase),
1416
1443
  };
1417
1444
  }
1418
1445
  var lissajous43 = {
@@ -1420,17 +1447,18 @@ var lissajous43 = {
1420
1447
  fn: lissajous43Fn,
1421
1448
  period: TWO_PI7,
1422
1449
  speed: 1.8,
1423
- skeleton: "live"
1450
+ skeleton: "live",
1424
1451
  };
1425
1452
 
1426
1453
  // src/curves/lame.ts
1427
1454
  var TWO_PI8 = Math.PI * 2;
1428
1455
  function lameFn(phase, elapsed, _params) {
1429
1456
  const p = 1.75 + 1.25 * Math.sin(elapsed * 0.48);
1430
- const c = Math.cos(phase), s = Math.sin(phase);
1457
+ const c = Math.cos(phase),
1458
+ s = Math.sin(phase);
1431
1459
  return {
1432
1460
  x: Math.sign(c) * Math.pow(Math.abs(c), p),
1433
- y: Math.sign(s) * Math.pow(Math.abs(s), p)
1461
+ y: Math.sign(s) * Math.pow(Math.abs(s), p),
1434
1462
  };
1435
1463
  }
1436
1464
  var lame = {
@@ -1438,7 +1466,7 @@ var lame = {
1438
1466
  fn: lameFn,
1439
1467
  period: TWO_PI8,
1440
1468
  speed: 1,
1441
- skeleton: "live"
1469
+ skeleton: "live",
1442
1470
  };
1443
1471
 
1444
1472
  // src/curves/rose3.ts
@@ -1447,14 +1475,14 @@ function rose3Fn(phase, _elapsed, _params) {
1447
1475
  const r = Math.cos(3 * phase);
1448
1476
  return {
1449
1477
  x: r * Math.cos(phase),
1450
- y: r * Math.sin(phase)
1478
+ y: r * Math.sin(phase),
1451
1479
  };
1452
1480
  }
1453
1481
  var rose3 = {
1454
1482
  name: "Rose (n=3)",
1455
1483
  fn: rose3Fn,
1456
1484
  period: TWO_PI9,
1457
- speed: 1.15
1485
+ speed: 1.15,
1458
1486
  };
1459
1487
 
1460
1488
  // src/curves/rose5.ts
@@ -1463,78 +1491,87 @@ function rose5Fn(phase, _elapsed, _params) {
1463
1491
  const r = Math.cos(5 * phase);
1464
1492
  return {
1465
1493
  x: r * Math.cos(phase),
1466
- y: r * Math.sin(phase)
1494
+ y: r * Math.sin(phase),
1467
1495
  };
1468
1496
  }
1469
1497
  var rose5 = {
1470
1498
  name: "Rose (n=5)",
1471
1499
  fn: rose5Fn,
1472
1500
  period: TWO_PI10,
1473
- speed: 1
1501
+ speed: 1,
1474
1502
  };
1475
1503
 
1476
1504
  // src/curves/rose52.ts
1477
1505
  var FOUR_PI = Math.PI * 4;
1478
1506
  function rose52Fn(phase, _elapsed, _params) {
1479
- const r = Math.cos(5 / 2 * phase);
1507
+ const r = Math.cos((5 / 2) * phase);
1480
1508
  return {
1481
1509
  x: r * Math.cos(phase),
1482
- y: r * Math.sin(phase)
1510
+ y: r * Math.sin(phase),
1483
1511
  };
1484
1512
  }
1485
1513
  var rose52 = {
1486
1514
  name: "Rose (n=5/2)",
1487
1515
  fn: rose52Fn,
1488
1516
  period: FOUR_PI,
1489
- speed: 0.8
1517
+ speed: 0.8,
1490
1518
  };
1491
1519
 
1492
1520
  // src/curves/star.ts
1493
1521
  var TWO_PI11 = Math.PI * 2;
1494
1522
  function starFn(phase, _elapsed, _params) {
1495
- const r = Math.abs(Math.cos(5 / 2 * phase)) + 0.35 * Math.abs(Math.cos(15 / 2 * phase)) + 0.15 * Math.abs(Math.cos(25 / 2 * phase));
1523
+ const r =
1524
+ Math.abs(Math.cos((5 / 2) * phase)) +
1525
+ 0.35 * Math.abs(Math.cos((15 / 2) * phase)) +
1526
+ 0.15 * Math.abs(Math.cos((25 / 2) * phase));
1496
1527
  return {
1497
1528
  x: r * Math.cos(phase),
1498
- y: r * Math.sin(phase)
1529
+ y: r * Math.sin(phase),
1499
1530
  };
1500
1531
  }
1501
1532
  var star = {
1502
1533
  name: "Star",
1503
1534
  fn: starFn,
1504
1535
  period: TWO_PI11,
1505
- speed: 1
1536
+ speed: 1,
1506
1537
  };
1507
1538
 
1508
1539
  // src/curves/star4.ts
1509
1540
  var TWO_PI12 = Math.PI * 2;
1510
1541
  function star4Fn(phase, _elapsed, _params) {
1511
- const r = Math.abs(Math.cos(2 * phase)) + 0.35 * Math.abs(Math.cos(6 * phase)) + 0.15 * Math.abs(Math.cos(10 * phase));
1542
+ const r =
1543
+ Math.abs(Math.cos(2 * phase)) +
1544
+ 0.35 * Math.abs(Math.cos(6 * phase)) +
1545
+ 0.15 * Math.abs(Math.cos(10 * phase));
1512
1546
  return {
1513
1547
  x: r * Math.cos(phase),
1514
- y: r * Math.sin(phase)
1548
+ y: r * Math.sin(phase),
1515
1549
  };
1516
1550
  }
1517
1551
  var star4 = {
1518
1552
  name: "Star (4-arm)",
1519
1553
  fn: star4Fn,
1520
1554
  period: TWO_PI12,
1521
- speed: 1
1555
+ speed: 1,
1522
1556
  };
1523
1557
 
1524
1558
  // src/curves/star7.ts
1525
1559
  var TWO_PI13 = Math.PI * 2;
1526
1560
  function star7Fn(phase, _elapsed, _params) {
1527
- const r = Math.abs(Math.cos(7 / 2 * phase)) + 0.35 * Math.abs(Math.cos(21 / 2 * phase)) + 0.15 * Math.abs(Math.cos(35 / 2 * phase));
1561
+ const r =
1562
+ Math.abs(Math.cos((7 / 2) * phase)) +
1563
+ 0.35 * Math.abs(Math.cos((21 / 2) * phase)) +
1564
+ 0.15 * Math.abs(Math.cos((35 / 2) * phase));
1528
1565
  return {
1529
1566
  x: r * Math.cos(phase),
1530
- y: r * Math.sin(phase)
1567
+ y: r * Math.sin(phase),
1531
1568
  };
1532
1569
  }
1533
1570
  var star7 = {
1534
1571
  name: "Star (7-arm)",
1535
1572
  fn: star7Fn,
1536
1573
  period: TWO_PI13,
1537
- speed: 1
1574
+ speed: 1,
1538
1575
  };
1539
1576
 
1540
1577
  // src/curves/index.ts
@@ -1552,7 +1589,7 @@ var curves = {
1552
1589
  lissajous32,
1553
1590
  lissajous43,
1554
1591
  epicycloid3,
1555
- lame
1592
+ lame,
1556
1593
  };
1557
1594
 
1558
1595
  // src/index.ts
@@ -1562,6 +1599,27 @@ function createSarmal(canvas, curveDef, options) {
1562
1599
  return createRenderer({ canvas, engine, ...rendererOpts });
1563
1600
  }
1564
1601
 
1565
- export { artemis2, astroid, computeBoundaries, createEngine, createRenderer, createSVGRenderer, createSarmal, createSarmalSVG, curves, deltoid, drawCurve, epicycloid3, epitrochoid7, evaluateCatmullRom, lame, lissajous32, lissajous43, palettes, rose3, rose5 };
1602
+ export {
1603
+ artemis2,
1604
+ astroid,
1605
+ computeBoundaries,
1606
+ createEngine,
1607
+ createRenderer,
1608
+ createSVGRenderer,
1609
+ createSarmal,
1610
+ createSarmalSVG,
1611
+ curves,
1612
+ deltoid,
1613
+ drawCurve,
1614
+ epicycloid3,
1615
+ epitrochoid7,
1616
+ evaluateCatmullRom,
1617
+ lame,
1618
+ lissajous32,
1619
+ lissajous43,
1620
+ palettes,
1621
+ rose3,
1622
+ rose5,
1623
+ };
1624
+ //# sourceMappingURL=index.js.map
1566
1625
  //# sourceMappingURL=index.js.map
1567
- //# sourceMappingURL=index.js.map