@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
@@ -1,4 +1,4 @@
1
- 'use strict';
1
+ "use strict";
2
2
 
3
3
  // src/engine.ts
4
4
  var TWO_PI = Math.PI * 2;
@@ -63,13 +63,13 @@ function resolveCurve(curveDef) {
63
63
  period,
64
64
  speed,
65
65
  skeleton: curveDef.skeleton,
66
- skeletonFn: curveDef.skeletonFn
66
+ skeletonFn: curveDef.skeletonFn,
67
67
  };
68
68
  }
69
69
  function createEngine(curveDef, trailLength = 120) {
70
70
  if (!Number.isFinite(trailLength) || trailLength <= 0) {
71
71
  throw new RangeError(
72
- `[sarmal] trailLength must be a positive finite number, got ${trailLength}`
72
+ `[sarmal] trailLength must be a positive finite number, got ${trailLength}`,
73
73
  );
74
74
  }
75
75
  let curve = resolveCurve(curveDef);
@@ -110,7 +110,8 @@ function createEngine(curveDef, trailLength = 120) {
110
110
  actualTime += deltaTime;
111
111
  if (morphCurveB !== null && _morphAlpha !== null) {
112
112
  const a = curve.fn(phase, actualTime, EMPTY_PARAMS);
113
- const phaseB = _morphStrategy === "normalized" ? phase / curve.period * morphCurveB.period : phase;
113
+ const phaseB =
114
+ _morphStrategy === "normalized" ? (phase / curve.period) * morphCurveB.period : phase;
114
115
  const b = morphCurveB.fn(phaseB, actualTime, EMPTY_PARAMS);
115
116
  trail.push(a.x + (b.x - a.x) * _morphAlpha, a.y + (b.y - a.y) * _morphAlpha);
116
117
  } else {
@@ -137,14 +138,14 @@ function createEngine(curveDef, trailLength = 120) {
137
138
  trail.clear();
138
139
  },
139
140
  jump(newPhase, { clearTrail = false } = {}) {
140
- phase = (newPhase % curve.period + curve.period) % curve.period;
141
+ phase = ((newPhase % curve.period) + curve.period) % curve.period;
141
142
  if (clearTrail) {
142
143
  trail.clear();
143
144
  }
144
145
  },
145
146
  seek(targetPhase, { wrap = false, step = curve.period / trailLength } = {}) {
146
147
  const advance = curve.speed * step;
147
- const target = (targetPhase % curve.period + curve.period) % curve.period;
148
+ const target = ((targetPhase % curve.period) + curve.period) % curve.period;
148
149
  const targetTime = target / curve.speed;
149
150
  phase = target;
150
151
  actualTime = targetTime;
@@ -153,7 +154,7 @@ function createEngine(curveDef, trailLength = 120) {
153
154
  const count = wrap ? trailLength : Math.min(trailLength, pointsFromStart);
154
155
  for (let i = count - 1; i >= 0; i--) {
155
156
  const samplePhase = target - i * advance;
156
- const wrappedPhase = (samplePhase % curve.period + curve.period) % curve.period;
157
+ const wrappedPhase = ((samplePhase % curve.period) + curve.period) % curve.period;
157
158
  const elapsed = targetTime - i * step;
158
159
  const point = curve.fn(wrappedPhase, elapsed, EMPTY_PARAMS);
159
160
  trail.push(point.x, point.y);
@@ -170,13 +171,16 @@ function createEngine(curveDef, trailLength = 120) {
170
171
  ...frozenB,
171
172
  fn: (samplePhase, elapsed, params) => {
172
173
  const a = frozenA.fn(samplePhase, elapsed, params);
173
- const phaseB = frozenStrategy === "normalized" ? samplePhase / frozenA.period * frozenB.period : samplePhase;
174
+ const phaseB =
175
+ frozenStrategy === "normalized"
176
+ ? (samplePhase / frozenA.period) * frozenB.period
177
+ : samplePhase;
174
178
  const b = frozenB.fn(phaseB, elapsed, params);
175
179
  return {
176
180
  x: a.x + (b.x - a.x) * frozenAlpha,
177
- y: a.y + (b.y - a.y) * frozenAlpha
181
+ y: a.y + (b.y - a.y) * frozenAlpha,
178
182
  };
179
- }
183
+ },
180
184
  };
181
185
  }
182
186
  _morphStrategy = strategy;
@@ -189,7 +193,7 @@ function createEngine(curveDef, trailLength = 120) {
189
193
  completeMorph() {
190
194
  if (morphCurveB !== null) {
191
195
  if (_morphStrategy === "normalized" && curve.period !== morphCurveB.period) {
192
- phase = phase / curve.period * morphCurveB.period;
196
+ phase = (phase / curve.period) * morphCurveB.period;
193
197
  }
194
198
  curve = morphCurveB;
195
199
  }
@@ -201,19 +205,22 @@ function createEngine(curveDef, trailLength = 120) {
201
205
  const points2 = new Array(steps);
202
206
  if (morphCurveB !== null && _morphAlpha !== null) {
203
207
  for (let i = 0; i < steps; i++) {
204
- const samplePhase = i / (steps - 1) * curve.period;
208
+ const samplePhase = (i / (steps - 1)) * curve.period;
205
209
  const a = sampleSkeleton(curve, samplePhase);
206
- const phaseB = _morphStrategy === "normalized" ? samplePhase / curve.period * morphCurveB.period : samplePhase;
210
+ const phaseB =
211
+ _morphStrategy === "normalized"
212
+ ? (samplePhase / curve.period) * morphCurveB.period
213
+ : samplePhase;
207
214
  const b = sampleSkeleton(morphCurveB, phaseB);
208
215
  points2[i] = {
209
216
  x: a.x + (b.x - a.x) * _morphAlpha,
210
- y: a.y + (b.y - a.y) * _morphAlpha
217
+ y: a.y + (b.y - a.y) * _morphAlpha,
211
218
  };
212
219
  }
213
220
  return points2;
214
221
  }
215
222
  for (let i = 0; i < steps; i++) {
216
- const samplePhase = i / (steps - 1) * curve.period;
223
+ const samplePhase = (i / (steps - 1)) * curve.period;
217
224
  points2[i] = sampleSkeleton(curve, samplePhase);
218
225
  }
219
226
  return points2;
@@ -255,7 +262,7 @@ function createEngine(curveDef, trailLength = 120) {
255
262
  _speedTransition.reject(new Error("Speed transition cancelled"));
256
263
  _speedTransition = null;
257
264
  }
258
- }
265
+ },
259
266
  };
260
267
  }
261
268
 
@@ -294,7 +301,15 @@ function computeNormal(trail, i) {
294
301
  const tangent = computeTangent(trail, i);
295
302
  return { x: -tangent.y, y: tangent.x };
296
303
  }
297
- function computeTrailQuad(trail, i, trailCount, toX, toY, minWidth = TRAIL_MIN_WIDTH, maxWidth = TRAIL_MAX_WIDTH) {
304
+ function computeTrailQuad(
305
+ trail,
306
+ i,
307
+ trailCount,
308
+ toX,
309
+ toY,
310
+ minWidth = TRAIL_MIN_WIDTH,
311
+ maxWidth = TRAIL_MAX_WIDTH,
312
+ ) {
298
313
  const progress = i / (trailCount - 1);
299
314
  const nextProgress = (i + 1) / (trailCount - 1);
300
315
  const opacity = Math.pow(progress, TRAIL_FADE_CURVE) * TRAIL_MAX_OPACITY;
@@ -318,13 +333,16 @@ function computeTrailQuad(trail, i, trailCount, toX, toY, minWidth = TRAIL_MIN_W
318
333
  r1x: nx - n1.x * w1,
319
334
  r1y: ny - n1.y * w1,
320
335
  opacity,
321
- progress
336
+ progress,
322
337
  };
323
338
  }
324
339
  function computeBoundaries(pts, logicalWidth, logicalHeight, minPaddingPx = FIT_PADDING_MIN) {
325
340
  if (pts.length === 0) return null;
326
341
  const first = pts[0];
327
- let minX = first.x, maxX = first.x, minY = first.y, maxY = first.y;
342
+ let minX = first.x,
343
+ maxX = first.x,
344
+ minY = first.y,
345
+ maxY = first.y;
328
346
  for (const p of pts) {
329
347
  if (p.x < minX) {
330
348
  minX = p.x;
@@ -343,7 +361,7 @@ function computeBoundaries(pts, logicalWidth, logicalHeight, minPaddingPx = FIT_
343
361
  const h = maxY - minY;
344
362
  if (w === 0 && h === 0) {
345
363
  throw new Error(
346
- "[sarmal] Degenerate curve: all skeleton points are identical. Check that your curve fn returns distinct points for different values of t."
364
+ "[sarmal] Degenerate curve: all skeleton points are identical. Check that your curve fn returns distinct points for different values of t.",
347
365
  );
348
366
  }
349
367
  const scaleXProportional = logicalWidth / (w * (1 + FIT_PADDING * 2));
@@ -354,12 +372,12 @@ function computeBoundaries(pts, logicalWidth, logicalHeight, minPaddingPx = FIT_
354
372
  scaleXProportional,
355
373
  scaleYProportional,
356
374
  scaleXMinPadding,
357
- scaleYMinPadding
375
+ scaleYMinPadding,
358
376
  );
359
377
  return {
360
378
  scale,
361
379
  offsetX: (logicalWidth - w * scale) / 2 - minX * scale,
362
- offsetY: (logicalHeight - h * scale) / 2 - minY * scale
380
+ offsetY: (logicalHeight - h * scale) / 2 - minY * scale,
363
381
  };
364
382
  }
365
383
  function enginePassthroughs(engine) {
@@ -370,17 +388,17 @@ function enginePassthroughs(engine) {
370
388
  getSpeed: engine.getSpeed,
371
389
  resetSpeed: engine.resetSpeed,
372
390
  setSpeedOver: engine.setSpeedOver,
373
- getSarmalSkeleton: engine.getSarmalSkeleton
391
+ getSarmalSkeleton: engine.getSarmalSkeleton,
374
392
  };
375
393
  }
376
394
  function hexToRgb(hex) {
377
395
  const n = parseInt(hex.slice(1), 16);
378
- return { r: n >> 16, g: n >> 8 & 255, b: n & 255 };
396
+ return { r: n >> 16, g: (n >> 8) & 255, b: n & 255 };
379
397
  }
380
398
  var lerpRgb = (a, b, t) => ({
381
399
  r: Math.round(a.r + (b.r - a.r) * t),
382
400
  g: Math.round(a.g + (b.g - a.g) * t),
383
- b: Math.round(a.b + (b.b - a.b) * t)
401
+ b: Math.round(a.b + (b.b - a.b) * t),
384
402
  });
385
403
  function getPaletteColor(palette, position, timeOffset = 0) {
386
404
  if (palette.length === 0) {
@@ -389,7 +407,7 @@ function getPaletteColor(palette, position, timeOffset = 0) {
389
407
  if (palette.length === 1) {
390
408
  return hexToRgb(palette[0]);
391
409
  }
392
- const cyclePos = ((position + timeOffset) % 1 + 1) % 1;
410
+ const cyclePos = (((position + timeOffset) % 1) + 1) % 1;
393
411
  const scaled = cyclePos * palette.length;
394
412
  const idx = Math.floor(scaled);
395
413
  const t = scaled - idx;
@@ -404,7 +422,7 @@ var RENDER_OPTION_KEYS = /* @__PURE__ */ new Set([
404
422
  "headColor",
405
423
  "skeletonColor",
406
424
  "trailStyle",
407
- "headRadius"
425
+ "headRadius",
408
426
  ]);
409
427
  function validateRenderOptions(partial) {
410
428
  for (const key of Object.keys(partial)) {
@@ -432,7 +450,7 @@ function assertTrailColor(value) {
432
450
  if (typeof value === "string") {
433
451
  if (!HEX_COLOR_RE.test(value)) {
434
452
  throw new TypeError(
435
- `[sarmal] setRenderOptions: trailColor must be a 6-digit hex string, got "${value}"`
453
+ `[sarmal] setRenderOptions: trailColor must be a 6-digit hex string, got "${value}"`,
436
454
  );
437
455
  }
438
456
  return;
@@ -440,21 +458,21 @@ function assertTrailColor(value) {
440
458
  if (Array.isArray(value)) {
441
459
  if (value.length < 2) {
442
460
  throw new RangeError(
443
- `[sarmal] setRenderOptions: trailColor array must have at least 2 entries, got ${value.length}`
461
+ `[sarmal] setRenderOptions: trailColor array must have at least 2 entries, got ${value.length}`,
444
462
  );
445
463
  }
446
464
  for (let i = 0; i < value.length; i++) {
447
465
  const entry = value[i];
448
466
  if (typeof entry !== "string" || !HEX_COLOR_RE.test(entry)) {
449
467
  throw new TypeError(
450
- `[sarmal] setRenderOptions: trailColor[${i}] must be a 6-digit hex string, got ${JSON.stringify(entry)}`
468
+ `[sarmal] setRenderOptions: trailColor[${i}] must be a 6-digit hex string, got ${JSON.stringify(entry)}`,
451
469
  );
452
470
  }
453
471
  }
454
472
  return;
455
473
  }
456
474
  throw new TypeError(
457
- `[sarmal] setRenderOptions: trailColor must be a 6-digit hex string or an array of hex strings, got ${JSON.stringify(value)}`
475
+ `[sarmal] setRenderOptions: trailColor must be a 6-digit hex string or an array of hex strings, got ${JSON.stringify(value)}`,
458
476
  );
459
477
  }
460
478
  function assertHeadColor(value) {
@@ -463,7 +481,7 @@ function assertHeadColor(value) {
463
481
  }
464
482
  if (typeof value !== "string" || !HEX_COLOR_RE.test(value)) {
465
483
  throw new TypeError(
466
- `[sarmal] setRenderOptions: headColor must be a 6-digit hex string or null, got ${JSON.stringify(value)}`
484
+ `[sarmal] setRenderOptions: headColor must be a 6-digit hex string or null, got ${JSON.stringify(value)}`,
467
485
  );
468
486
  }
469
487
  }
@@ -473,26 +491,26 @@ function assertSkeletonColor(value) {
473
491
  }
474
492
  if (typeof value !== "string" || !HEX_COLOR_RE.test(value)) {
475
493
  throw new TypeError(
476
- `[sarmal] setRenderOptions: skeletonColor must be a 6-digit hex string or "transparent", got ${JSON.stringify(value)}`
494
+ `[sarmal] setRenderOptions: skeletonColor must be a 6-digit hex string or "transparent", got ${JSON.stringify(value)}`,
477
495
  );
478
496
  }
479
497
  }
480
498
  function assertTrailStyle(value) {
481
499
  if (!TRAIL_STYLES.includes(value)) {
482
500
  throw new RangeError(
483
- `[sarmal] setRenderOptions: trailStyle must be one of "default", "gradient-static", "gradient-animated", got ${JSON.stringify(value)}`
501
+ `[sarmal] setRenderOptions: trailStyle must be one of "default", "gradient-static", "gradient-animated", got ${JSON.stringify(value)}`,
484
502
  );
485
503
  }
486
504
  }
487
505
  function assertHeadRadius(value) {
488
506
  if (typeof value !== "number") {
489
507
  throw new TypeError(
490
- `[sarmal] setRenderOptions: headRadius must be a number, got ${JSON.stringify(value)}`
508
+ `[sarmal] setRenderOptions: headRadius must be a number, got ${JSON.stringify(value)}`,
491
509
  );
492
510
  }
493
511
  if (!Number.isFinite(value) || value <= 0) {
494
512
  throw new TypeError(
495
- `[sarmal] setRenderOptions: headRadius must be a finite positive number, got ${value}`
513
+ `[sarmal] setRenderOptions: headRadius must be a finite positive number, got ${value}`,
496
514
  );
497
515
  }
498
516
  }
@@ -514,13 +532,13 @@ function resolveHeadColor(trailColor, trailStyle) {
514
532
  function warnIfTrailColorMismatch(trailColor, trailStyle) {
515
533
  if (trailStyle === "default" && Array.isArray(trailColor)) {
516
534
  console.warn(
517
- '[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.'
535
+ '[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.',
518
536
  );
519
537
  return;
520
538
  }
521
539
  if (trailStyle !== "default" && typeof trailColor === "string") {
522
540
  console.warn(
523
- `[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.`
541
+ `[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.`,
524
542
  );
525
543
  }
526
544
  }
@@ -530,7 +548,7 @@ var getHeadDotRadius = (w, h) => Math.max(1, 3 * Math.sqrt(Math.min(w, h) / 160)
530
548
  var WHITE_HEX = "#ffffff";
531
549
  function hexToRgbComponents(hex) {
532
550
  const n = parseInt(hex.slice(1), 16);
533
- return `${n >> 16},${n >> 8 & 255},${n & 255}`;
551
+ return `${n >> 16},${(n >> 8) & 255},${n & 255}`;
534
552
  }
535
553
  function applyDprSizing(target, logicalWidth, logicalHeight, dpr) {
536
554
  target.style.width = `${logicalWidth}px`;
@@ -657,7 +675,7 @@ function createRenderer(options) {
657
675
  i,
658
676
  trailCount,
659
677
  toX,
660
- toY
678
+ toY,
661
679
  );
662
680
  if (trailStyle === "default") {
663
681
  ctx.fillStyle = `rgba(${trailSolidRgb},${opacity})`;
@@ -822,7 +840,7 @@ function createRenderer(options) {
822
840
  if (partial.trailColor !== void 0 || partial.trailStyle !== void 0) {
823
841
  warnIfTrailColorMismatch(trailColor, trailStyle);
824
842
  }
825
- }
843
+ },
826
844
  };
827
845
  const pauseOnHidden = options.pauseOnHidden !== false;
828
846
  function handleVisibilityChange() {
@@ -872,8 +890,10 @@ function sampleCurveSkeleton(curveDef) {
872
890
  const samples = Math.ceil(period * 50);
873
891
  const pts = Array.from({ length: samples });
874
892
  for (let i = 0; i < samples; i++) {
875
- const phase = i / (samples - 1) * period;
876
- pts[i] = curveDef.skeletonFn ? curveDef.skeletonFn(phase) : curveDef.fn(phase, 0, EMPTY_PARAMS2);
893
+ const phase = (i / (samples - 1)) * period;
894
+ pts[i] = curveDef.skeletonFn
895
+ ? curveDef.skeletonFn(phase)
896
+ : curveDef.fn(phase, 0, EMPTY_PARAMS2);
877
897
  }
878
898
  return pts;
879
899
  }
@@ -885,7 +905,7 @@ function createSVGRenderer(options) {
885
905
  const poolSize = engine.trailLength;
886
906
  if (poolSize > HIGH_TRAIL_LENGTH_THRESHOLD) {
887
907
  console.warn(
888
- `[sarmal] High trailLength in SVG renderer (${poolSize}). Consider using the canvas renderer for long trails.`
908
+ `[sarmal] High trailLength in SVG renderer (${poolSize}). Consider using the canvas renderer for long trails.`,
889
909
  );
890
910
  }
891
911
  let trailStyle = options.trailStyle ?? "default";
@@ -904,9 +924,9 @@ function createSVGRenderer(options) {
904
924
  return rect.width && rect.height ? Math.min(rect.width, rect.height) : 200;
905
925
  }
906
926
  const containerPx = getContainerPixelSize();
907
- const svgTrailMinWidth = TRAIL_MIN_WIDTH * viewSize / containerPx;
908
- const svgTrailMaxWidth = TRAIL_MAX_WIDTH * viewSize / containerPx;
909
- const svgSkeletonStrokeWidth = String(SKELETON_STROKE_WIDTH_PX * viewSize / containerPx);
927
+ const svgTrailMinWidth = (TRAIL_MIN_WIDTH * viewSize) / containerPx;
928
+ const svgTrailMaxWidth = (TRAIL_MAX_WIDTH * viewSize) / containerPx;
929
+ const svgSkeletonStrokeWidth = String((SKELETON_STROKE_WIDTH_PX * viewSize) / containerPx);
910
930
  headRadius = options.headRadius ?? SVG_DEFAULT_HEAD_RADIUS;
911
931
  container.setAttribute("viewBox", `0 0 ${viewSize} ${viewSize}`);
912
932
  container.setAttribute("role", "img");
@@ -994,7 +1014,7 @@ function createSVGRenderer(options) {
994
1014
  px,
995
1015
  py,
996
1016
  svgTrailMinWidth,
997
- svgTrailMaxWidth
1017
+ svgTrailMaxWidth,
998
1018
  );
999
1019
  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`;
1000
1020
  trailPaths[i].setAttribute("d", d);
@@ -1022,7 +1042,8 @@ function createSVGRenderer(options) {
1022
1042
  let animationId = null;
1023
1043
  let lastTime = 0;
1024
1044
  let pausedByVisibility = false;
1025
- const prefersReducedMotion = typeof window !== "undefined" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
1045
+ const prefersReducedMotion =
1046
+ typeof window !== "undefined" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
1026
1047
  let morphResolve = null;
1027
1048
  let morphReject = null;
1028
1049
  let morphDurationMs = DEFAULT_MORPH_DURATION_MS;
@@ -1040,7 +1061,7 @@ function createSVGRenderer(options) {
1040
1061
  skeletonPathA.setAttribute("visibility", "visible");
1041
1062
  skeletonPathA.setAttribute(
1042
1063
  "stroke-opacity",
1043
- String((1 - morphAlpha) * DEFAULT_SKELETON_OPACITY)
1064
+ String((1 - morphAlpha) * DEFAULT_SKELETON_OPACITY),
1044
1065
  );
1045
1066
  }
1046
1067
  if (morphPathBBuilt) {
@@ -1194,7 +1215,7 @@ function createSVGRenderer(options) {
1194
1215
  if (partial.trailColor !== void 0 || partial.trailStyle !== void 0) {
1195
1216
  warnIfTrailColorMismatch(trailColor, trailStyle);
1196
1217
  }
1197
- }
1218
+ },
1198
1219
  };
1199
1220
  const pauseOnHidden = options.pauseOnHidden !== false;
1200
1221
  function handleVisibilityChange() {
@@ -1232,7 +1253,13 @@ var PERIOD = 2 * Math.PI;
1232
1253
  function catmullRom1D(p0, p1, p2, p3, u) {
1233
1254
  const u2 = u * u;
1234
1255
  const u3 = u2 * u;
1235
- return 0.5 * (2 * p1 + (-p0 + p2) * u + (2 * p0 - 5 * p1 + 4 * p2 - p3) * u2 + (-p0 + 3 * p1 - 3 * p2 + p3) * u3);
1256
+ return (
1257
+ 0.5 *
1258
+ (2 * p1 +
1259
+ (-p0 + p2) * u +
1260
+ (2 * p0 - 5 * p1 + 4 * p2 - p3) * u2 +
1261
+ (-p0 + 3 * p1 - 3 * p2 + p3) * u3)
1262
+ );
1236
1263
  }
1237
1264
  function evaluateCatmullRom(points2, phase) {
1238
1265
  const N = points2.length;
@@ -1242,7 +1269,7 @@ function evaluateCatmullRom(points2, phase) {
1242
1269
  if (N === 1) {
1243
1270
  return { x: points2[0][0], y: points2[0][1] };
1244
1271
  }
1245
- phase = (phase % PERIOD + PERIOD) % PERIOD;
1272
+ phase = ((phase % PERIOD) + PERIOD) % PERIOD;
1246
1273
  const segmentSize = PERIOD / N;
1247
1274
  let i = Math.floor(phase / segmentSize);
1248
1275
  if (i >= N) {
@@ -1256,7 +1283,7 @@ function evaluateCatmullRom(points2, phase) {
1256
1283
  const p3 = points2[(i + 2) % N];
1257
1284
  return {
1258
1285
  x: catmullRom1D(p0[0], p1[0], p2[0], p3[0], u),
1259
- y: catmullRom1D(p0[1], p1[1], p2[1], p3[1], u)
1286
+ y: catmullRom1D(p0[1], p1[1], p2[1], p3[1], u),
1260
1287
  };
1261
1288
  }
1262
1289
  function drawCurve(points2, opts) {
@@ -1266,20 +1293,20 @@ function drawCurve(points2, opts) {
1266
1293
  const first = points2[0];
1267
1294
  if (points2.every((p) => p[0] === first[0] && p[1] === first[1])) {
1268
1295
  console.warn(
1269
- "[sarmal].drawCurve: all control points are identical. The curve will be a single point."
1296
+ "[sarmal].drawCurve: all control points are identical. The curve will be a single point.",
1270
1297
  );
1271
1298
  }
1272
1299
  const maxAbs = points2.reduce((m, p) => Math.max(m, Math.abs(p[0]), Math.abs(p[1])), 0);
1273
1300
  if (maxAbs > 2) {
1274
1301
  console.warn(
1275
- `[sarmal].drawCurve: control points extend to \xB1${maxAbs.toFixed(1)}, which may render off-screen. Coordinates should be in [-1, 1].`
1302
+ `[sarmal].drawCurve: control points extend to \xB1${maxAbs.toFixed(1)}, which may render off-screen. Coordinates should be in [-1, 1].`,
1276
1303
  );
1277
1304
  }
1278
1305
  const pts = points2.map(([x, y]) => [x, y]);
1279
1306
  return {
1280
1307
  name: opts?.name ?? "drawn",
1281
1308
  fn: (phase) => evaluateCatmullRom(pts, phase),
1282
- period: PERIOD
1309
+ period: PERIOD,
1283
1310
  };
1284
1311
  }
1285
1312
 
@@ -1305,11 +1332,11 @@ var points = [
1305
1332
  [-0.69, -0.84],
1306
1333
  [-0.87, -0.66],
1307
1334
  [-0.9, -0.47],
1308
- [-0.76, -0.35]
1335
+ [-0.76, -0.35],
1309
1336
  ];
1310
1337
  var artemis2 = {
1311
1338
  ...drawCurve(points, { name: "Artemis II" }),
1312
- speed: 0.7
1339
+ speed: 0.7,
1313
1340
  };
1314
1341
 
1315
1342
  // src/curves/astroid.ts
@@ -1319,14 +1346,14 @@ function astroidFn(phase, _elapsed, _params) {
1319
1346
  const s = Math.sin(phase);
1320
1347
  return {
1321
1348
  x: c * c * c,
1322
- y: s * s * s
1349
+ y: s * s * s,
1323
1350
  };
1324
1351
  }
1325
1352
  var astroid = {
1326
1353
  name: "Astroid",
1327
1354
  fn: astroidFn,
1328
1355
  period: TWO_PI2,
1329
- speed: 1.1
1356
+ speed: 1.1,
1330
1357
  };
1331
1358
 
1332
1359
  // src/curves/deltoid.ts
@@ -1334,14 +1361,14 @@ var TWO_PI3 = Math.PI * 2;
1334
1361
  function deltoidFn(phase, _elapsed, _params) {
1335
1362
  return {
1336
1363
  x: 2 * Math.cos(phase) + Math.cos(2 * phase),
1337
- y: 2 * Math.sin(phase) - Math.sin(2 * phase)
1364
+ y: 2 * Math.sin(phase) - Math.sin(2 * phase),
1338
1365
  };
1339
1366
  }
1340
1367
  var deltoid = {
1341
1368
  name: "Deltoid",
1342
1369
  fn: deltoidFn,
1343
1370
  period: TWO_PI3,
1344
- speed: 0.9
1371
+ speed: 0.9,
1345
1372
  };
1346
1373
 
1347
1374
  // src/curves/epicycloid3.ts
@@ -1349,14 +1376,14 @@ var TWO_PI4 = Math.PI * 2;
1349
1376
  function epicycloid3Fn(phase, _elapsed, _params) {
1350
1377
  return {
1351
1378
  x: 4 * Math.cos(phase) - Math.cos(4 * phase),
1352
- y: 4 * Math.sin(phase) - Math.sin(4 * phase)
1379
+ y: 4 * Math.sin(phase) - Math.sin(4 * phase),
1353
1380
  };
1354
1381
  }
1355
1382
  var epicycloid3 = {
1356
1383
  name: "Epicycloid (n=3)",
1357
1384
  fn: epicycloid3Fn,
1358
1385
  period: TWO_PI4,
1359
- speed: 0.75
1386
+ speed: 0.75,
1360
1387
  };
1361
1388
 
1362
1389
  // src/curves/epitrochoid7.ts
@@ -1365,14 +1392,14 @@ function epitrochoid7Fn(phase, _elapsed, _params) {
1365
1392
  const d = 1 + 0.55 * Math.sin(phase * 0.5);
1366
1393
  return {
1367
1394
  x: 7 * Math.cos(phase) - d * Math.cos(7 * phase),
1368
- y: 7 * Math.sin(phase) - d * Math.sin(7 * phase)
1395
+ y: 7 * Math.sin(phase) - d * Math.sin(7 * phase),
1369
1396
  };
1370
1397
  }
1371
1398
  function epitrochoid7SkeletonFn(phase) {
1372
1399
  const d = 1.275;
1373
1400
  return {
1374
1401
  x: 7 * Math.cos(phase) - d * Math.cos(7 * phase),
1375
- y: 7 * Math.sin(phase) - d * Math.sin(7 * phase)
1402
+ y: 7 * Math.sin(phase) - d * Math.sin(7 * phase),
1376
1403
  };
1377
1404
  }
1378
1405
  var epitrochoid7 = {
@@ -1380,7 +1407,7 @@ var epitrochoid7 = {
1380
1407
  fn: epitrochoid7Fn,
1381
1408
  period: TWO_PI5,
1382
1409
  speed: 1.4,
1383
- skeletonFn: epitrochoid7SkeletonFn
1410
+ skeletonFn: epitrochoid7SkeletonFn,
1384
1411
  };
1385
1412
 
1386
1413
  // src/curves/lissajous32.ts
@@ -1389,7 +1416,7 @@ function lissajous32Fn(phase, elapsed, _params) {
1389
1416
  const phi = elapsed * 0.45;
1390
1417
  return {
1391
1418
  x: Math.sin(3 * phase + phi),
1392
- y: Math.sin(2 * phase)
1419
+ y: Math.sin(2 * phase),
1393
1420
  };
1394
1421
  }
1395
1422
  var lissajous32 = {
@@ -1397,7 +1424,7 @@ var lissajous32 = {
1397
1424
  fn: lissajous32Fn,
1398
1425
  period: TWO_PI6,
1399
1426
  speed: 2,
1400
- skeleton: "live"
1427
+ skeleton: "live",
1401
1428
  };
1402
1429
 
1403
1430
  // src/curves/lissajous43.ts
@@ -1406,7 +1433,7 @@ function lissajous43Fn(phase, elapsed, _params) {
1406
1433
  const phi = elapsed * 0.38;
1407
1434
  return {
1408
1435
  x: Math.sin(4 * phase + phi),
1409
- y: Math.sin(3 * phase)
1436
+ y: Math.sin(3 * phase),
1410
1437
  };
1411
1438
  }
1412
1439
  var lissajous43 = {
@@ -1414,17 +1441,18 @@ var lissajous43 = {
1414
1441
  fn: lissajous43Fn,
1415
1442
  period: TWO_PI7,
1416
1443
  speed: 1.8,
1417
- skeleton: "live"
1444
+ skeleton: "live",
1418
1445
  };
1419
1446
 
1420
1447
  // src/curves/lame.ts
1421
1448
  var TWO_PI8 = Math.PI * 2;
1422
1449
  function lameFn(phase, elapsed, _params) {
1423
1450
  const p = 1.75 + 1.25 * Math.sin(elapsed * 0.48);
1424
- const c = Math.cos(phase), s = Math.sin(phase);
1451
+ const c = Math.cos(phase),
1452
+ s = Math.sin(phase);
1425
1453
  return {
1426
1454
  x: Math.sign(c) * Math.pow(Math.abs(c), p),
1427
- y: Math.sign(s) * Math.pow(Math.abs(s), p)
1455
+ y: Math.sign(s) * Math.pow(Math.abs(s), p),
1428
1456
  };
1429
1457
  }
1430
1458
  var lame = {
@@ -1432,7 +1460,7 @@ var lame = {
1432
1460
  fn: lameFn,
1433
1461
  period: TWO_PI8,
1434
1462
  speed: 1,
1435
- skeleton: "live"
1463
+ skeleton: "live",
1436
1464
  };
1437
1465
 
1438
1466
  // src/curves/rose3.ts
@@ -1441,14 +1469,14 @@ function rose3Fn(phase, _elapsed, _params) {
1441
1469
  const r = Math.cos(3 * phase);
1442
1470
  return {
1443
1471
  x: r * Math.cos(phase),
1444
- y: r * Math.sin(phase)
1472
+ y: r * Math.sin(phase),
1445
1473
  };
1446
1474
  }
1447
1475
  var rose3 = {
1448
1476
  name: "Rose (n=3)",
1449
1477
  fn: rose3Fn,
1450
1478
  period: TWO_PI9,
1451
- speed: 1.15
1479
+ speed: 1.15,
1452
1480
  };
1453
1481
 
1454
1482
  // src/curves/rose5.ts
@@ -1457,78 +1485,87 @@ function rose5Fn(phase, _elapsed, _params) {
1457
1485
  const r = Math.cos(5 * phase);
1458
1486
  return {
1459
1487
  x: r * Math.cos(phase),
1460
- y: r * Math.sin(phase)
1488
+ y: r * Math.sin(phase),
1461
1489
  };
1462
1490
  }
1463
1491
  var rose5 = {
1464
1492
  name: "Rose (n=5)",
1465
1493
  fn: rose5Fn,
1466
1494
  period: TWO_PI10,
1467
- speed: 1
1495
+ speed: 1,
1468
1496
  };
1469
1497
 
1470
1498
  // src/curves/rose52.ts
1471
1499
  var FOUR_PI = Math.PI * 4;
1472
1500
  function rose52Fn(phase, _elapsed, _params) {
1473
- const r = Math.cos(5 / 2 * phase);
1501
+ const r = Math.cos((5 / 2) * phase);
1474
1502
  return {
1475
1503
  x: r * Math.cos(phase),
1476
- y: r * Math.sin(phase)
1504
+ y: r * Math.sin(phase),
1477
1505
  };
1478
1506
  }
1479
1507
  var rose52 = {
1480
1508
  name: "Rose (n=5/2)",
1481
1509
  fn: rose52Fn,
1482
1510
  period: FOUR_PI,
1483
- speed: 0.8
1511
+ speed: 0.8,
1484
1512
  };
1485
1513
 
1486
1514
  // src/curves/star.ts
1487
1515
  var TWO_PI11 = Math.PI * 2;
1488
1516
  function starFn(phase, _elapsed, _params) {
1489
- 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));
1517
+ const r =
1518
+ Math.abs(Math.cos((5 / 2) * phase)) +
1519
+ 0.35 * Math.abs(Math.cos((15 / 2) * phase)) +
1520
+ 0.15 * Math.abs(Math.cos((25 / 2) * phase));
1490
1521
  return {
1491
1522
  x: r * Math.cos(phase),
1492
- y: r * Math.sin(phase)
1523
+ y: r * Math.sin(phase),
1493
1524
  };
1494
1525
  }
1495
1526
  var star = {
1496
1527
  name: "Star",
1497
1528
  fn: starFn,
1498
1529
  period: TWO_PI11,
1499
- speed: 1
1530
+ speed: 1,
1500
1531
  };
1501
1532
 
1502
1533
  // src/curves/star4.ts
1503
1534
  var TWO_PI12 = Math.PI * 2;
1504
1535
  function star4Fn(phase, _elapsed, _params) {
1505
- const r = Math.abs(Math.cos(2 * phase)) + 0.35 * Math.abs(Math.cos(6 * phase)) + 0.15 * Math.abs(Math.cos(10 * phase));
1536
+ const r =
1537
+ Math.abs(Math.cos(2 * phase)) +
1538
+ 0.35 * Math.abs(Math.cos(6 * phase)) +
1539
+ 0.15 * Math.abs(Math.cos(10 * phase));
1506
1540
  return {
1507
1541
  x: r * Math.cos(phase),
1508
- y: r * Math.sin(phase)
1542
+ y: r * Math.sin(phase),
1509
1543
  };
1510
1544
  }
1511
1545
  var star4 = {
1512
1546
  name: "Star (4-arm)",
1513
1547
  fn: star4Fn,
1514
1548
  period: TWO_PI12,
1515
- speed: 1
1549
+ speed: 1,
1516
1550
  };
1517
1551
 
1518
1552
  // src/curves/star7.ts
1519
1553
  var TWO_PI13 = Math.PI * 2;
1520
1554
  function star7Fn(phase, _elapsed, _params) {
1521
- 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));
1555
+ const r =
1556
+ Math.abs(Math.cos((7 / 2) * phase)) +
1557
+ 0.35 * Math.abs(Math.cos((21 / 2) * phase)) +
1558
+ 0.15 * Math.abs(Math.cos((35 / 2) * phase));
1522
1559
  return {
1523
1560
  x: r * Math.cos(phase),
1524
- y: r * Math.sin(phase)
1561
+ y: r * Math.sin(phase),
1525
1562
  };
1526
1563
  }
1527
1564
  var star7 = {
1528
1565
  name: "Star (7-arm)",
1529
1566
  fn: star7Fn,
1530
1567
  period: TWO_PI13,
1531
- speed: 1
1568
+ speed: 1,
1532
1569
  };
1533
1570
 
1534
1571
  // src/curves/index.ts
@@ -1546,7 +1583,7 @@ var curves = {
1546
1583
  lissajous32,
1547
1584
  lissajous43,
1548
1585
  epicycloid3,
1549
- lame
1586
+ lame,
1550
1587
  };
1551
1588
 
1552
1589
  // src/index.ts
@@ -1563,22 +1600,21 @@ function parseTrailColor(value) {
1563
1600
  if (Array.isArray(parsed)) {
1564
1601
  return parsed;
1565
1602
  }
1566
- } catch {
1567
- }
1603
+ } catch {}
1568
1604
  return value;
1569
1605
  }
1570
1606
  function buildOptions(el2) {
1571
1607
  return {
1572
- ...el2.dataset.trailColor && {
1573
- trailColor: parseTrailColor(el2.dataset.trailColor)
1574
- },
1575
- ...el2.dataset.skeletonColor && { skeletonColor: el2.dataset.skeletonColor },
1576
- ...el2.dataset.headColor && { headColor: el2.dataset.headColor },
1577
- ...el2.dataset.headRadius && { headRadius: parseFloat(el2.dataset.headRadius) },
1578
- ...el2.dataset.trailLength && { trailLength: parseInt(el2.dataset.trailLength, 10) },
1579
- ...el2.dataset.trailStyle && {
1580
- trailStyle: el2.dataset.trailStyle
1581
- }
1608
+ ...(el2.dataset.trailColor && {
1609
+ trailColor: parseTrailColor(el2.dataset.trailColor),
1610
+ }),
1611
+ ...(el2.dataset.skeletonColor && { skeletonColor: el2.dataset.skeletonColor }),
1612
+ ...(el2.dataset.headColor && { headColor: el2.dataset.headColor }),
1613
+ ...(el2.dataset.headRadius && { headRadius: parseFloat(el2.dataset.headRadius) }),
1614
+ ...(el2.dataset.trailLength && { trailLength: parseInt(el2.dataset.trailLength, 10) }),
1615
+ ...(el2.dataset.trailStyle && {
1616
+ trailStyle: el2.dataset.trailStyle,
1617
+ }),
1582
1618
  };
1583
1619
  }
1584
1620
  function init() {
@@ -1593,7 +1629,10 @@ function init() {
1593
1629
  return console.error(`[sarmal] "${curveName}" is not a valid curve name`);
1594
1630
  }
1595
1631
  const options = buildOptions(el2);
1596
- const instance = el2 instanceof HTMLCanvasElement ? createSarmal(el2, curveDef, options) : createSarmalSVG(el2, curveDef, options);
1632
+ const instance =
1633
+ el2 instanceof HTMLCanvasElement
1634
+ ? createSarmal(el2, curveDef, options)
1635
+ : createSarmalSVG(el2, curveDef, options);
1597
1636
  if (el2.dataset.speed) {
1598
1637
  instance.setSpeed(parseFloat(el2.dataset.speed));
1599
1638
  }
@@ -1609,4 +1648,4 @@ if (document.readyState === "loading") {
1609
1648
 
1610
1649
  exports.init = init;
1611
1650
  //# sourceMappingURL=auto-init.cjs.map
1612
- //# sourceMappingURL=auto-init.cjs.map
1651
+ //# sourceMappingURL=auto-init.cjs.map