@sarmal/core 0.27.0 → 0.28.1

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