@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
@@ -1,6 +1,6 @@
1
1
  interface Point {
2
- x: number;
3
- y: number;
2
+ x: number;
3
+ y: number;
4
4
  }
5
5
  /**
6
6
  * A control point for drawn curves, represented as a
@@ -9,64 +9,64 @@ interface Point {
9
9
  */
10
10
  type ControlPoint = [number, number];
11
11
  interface CurveDef {
12
- name: string;
13
- /**
14
- * The parametric function that defines the curve shape.
15
- * @param phase Current position along the curve, in [0, period)
16
- * @param elapsed Elapsed actual time in seconds. It is always increasing, and never resets on period wrap
17
- * @param params Named parameter overrides. intentional forward-compatible parameter
18
- */
19
- fn: (phase: number, elapsed: number, params: Record<string, number>) => Point;
20
- /**
21
- * @default (Math.PI * 2)
22
- */
23
- period?: number;
24
- /**
25
- * @default 1
26
- */
27
- speed?: number;
28
- /**
29
- * To indicate a compatible library version when providing the curve definitions
30
- * Intended for potential backwards compatibility scenarios and futureproofing
31
- */
32
- version?: number;
33
- /**
34
- * Skeleton rendering mode:
35
- * - 'static': Skeleton is computed once at init from `fn(phase, 0)` and cached
36
- * - 'live': Skeleton is recomputed each frame using `fn(phase, actualTime)` specifically for curves whose shape drifts *over time*
37
- * @default "static"
38
- */
39
- skeleton?: "static" | "live";
40
- /**
41
- * An **override** function for computing a skeleton independent of `fn`
42
- * If provided, this function is used instead of `fn` to sample the skeleton,
43
- * and the result is cached just like like 'static' mode
44
- * @param phase The parametric position along the curve (0 to period)
45
- * @returns The point on the skeleton at position `phase`
46
- */
47
- skeletonFn?: (phase: number) => Point;
12
+ name: string;
13
+ /**
14
+ * The parametric function that defines the curve shape.
15
+ * @param phase Current position along the curve, in [0, period)
16
+ * @param elapsed Elapsed actual time in seconds. It is always increasing, and never resets on period wrap
17
+ * @param params Named parameter overrides. intentional forward-compatible parameter
18
+ */
19
+ fn: (phase: number, elapsed: number, params: Record<string, number>) => Point;
20
+ /**
21
+ * @default (Math.PI * 2)
22
+ */
23
+ period?: number;
24
+ /**
25
+ * @default 1
26
+ */
27
+ speed?: number;
28
+ /**
29
+ * To indicate a compatible library version when providing the curve definitions
30
+ * Intended for potential backwards compatibility scenarios and futureproofing
31
+ */
32
+ version?: number;
33
+ /**
34
+ * Skeleton rendering mode:
35
+ * - 'static': Skeleton is computed once at init from `fn(phase, 0)` and cached
36
+ * - 'live': Skeleton is recomputed each frame using `fn(phase, actualTime)` specifically for curves whose shape drifts *over time*
37
+ * @default "static"
38
+ */
39
+ skeleton?: "static" | "live";
40
+ /**
41
+ * An **override** function for computing a skeleton independent of `fn`
42
+ * If provided, this function is used instead of `fn` to sample the skeleton,
43
+ * and the result is cached just like like 'static' mode
44
+ * @param phase The parametric position along the curve (0 to period)
45
+ * @returns The point on the skeleton at position `phase`
46
+ */
47
+ skeletonFn?: (phase: number) => Point;
48
48
  }
49
49
  type JumpOptions = {
50
- /**
51
- * When true, clears the trail on jump. When false (default), the trail is left as-is.
52
- * @default false
53
- */
54
- clearTrail?: boolean;
50
+ /**
51
+ * When true, clears the trail on jump. When false (default), the trail is left as-is.
52
+ * @default false
53
+ */
54
+ clearTrail?: boolean;
55
55
  };
56
56
  type SeekOptions = {
57
- /**
58
- * When true, the trail wraps around the period boundary,
59
- * which results in a full trail even near `phase=0`
60
- * By default, the trail stops at `phase=0`, which results in a partial trail near the start
61
- * @default false
62
- */
63
- wrap?: boolean;
64
- /**
65
- * Time gap between each trail point (in same units as `phase`)
66
- * Smaller value means a trail that is more dense
67
- * @default period / trailLength
68
- */
69
- step?: number;
57
+ /**
58
+ * When true, the trail wraps around the period boundary,
59
+ * which results in a full trail even near `phase=0`
60
+ * By default, the trail stops at `phase=0`, which results in a partial trail near the start
61
+ * @default false
62
+ */
63
+ wrap?: boolean;
64
+ /**
65
+ * Time gap between each trail point (in same units as `phase`)
66
+ * Smaller value means a trail that is more dense
67
+ * @default period / trailLength
68
+ */
69
+ step?: number;
70
70
  };
71
71
  type MorpStrategy = "raw" | "normalized";
72
72
  /**
@@ -75,169 +75,169 @@ type MorpStrategy = "raw" | "normalized";
75
75
  * In the renderer, these are passthroughs
76
76
  */
77
77
  interface AnimationControls {
78
- /**
79
- * Resets the simulation state, clearing the trail and reverting internal `phase` to 0
80
- * The next call to `tick` will start fresh from the beginning of the curve
81
- */
82
- reset(): void;
83
- /**
84
- * Instantly moves the head to position `phase`.
85
- *
86
- * ! Does NOT update `actualTime`.
87
- *
88
- * Trail is left untouched by default. You can pass `clearTrail: true` to wipe it.
89
- * Use for morphing mid-flight or any time you don't need trail context.
90
- * @param phase The position to jump to (will be wrapped into [0, period))
91
- */
92
- jump(phase: number, options?: JumpOptions): void;
93
- /**
94
- * Moves to `phase` AND reconstructs the trail as if the animation naturally arrived there from `phase=0`
95
- * Also updates `actualTime` to match. Trail is always rebuilt from scratch
96
- * Use for initialisation or any jump where you want the trail to look meaningful
97
- * @param phase The position to seek to (will be wrapped into [0, period))
98
- */
99
- seek(phase: number, options?: SeekOptions): void;
100
- /**
101
- * Overrides the animation speed at runtime
102
- * `0` freezes `phase` but the loop keeps running
103
- * Negative values reverse traversal.
104
- *
105
- * ! Does NOT affect a curve's inherent speed given in CurveDef
106
- * @param speed 0 = freeze, negative = reverse, no upper bound
107
- */
108
- setSpeed(speed: number): void;
109
- /**
110
- * Returns the *effective speed* the engine is currently using:
111
- * `userSpeedOverride` if set, otherwise the curve's default speed.
112
- * This is what `tick()` actually uses
113
- */
114
- getSpeed(): number;
115
- /**
116
- * Drops the speed override and defers back to the curve's inherent default speed.
117
- * ! Sets `userSpeedOverride` to `null`
118
- */
119
- resetSpeed(): void;
120
- /**
121
- * Transitions to the target speed over `duration` milliseconds using linear interpolation.
122
- * Resolves when the transition completes.
123
- *
124
- * Calling this while a transition is already in progress cancels the old transition
125
- * (rejecting its Promise) and starts a new one from the current interpolated speed.
126
- *
127
- * @param speed Target speed
128
- * @param duration Transition duration in milliseconds (must be > 0)
129
- */
130
- setSpeedOver(speed: number, duration: number): Promise<void>;
78
+ /**
79
+ * Resets the simulation state, clearing the trail and reverting internal `phase` to 0
80
+ * The next call to `tick` will start fresh from the beginning of the curve
81
+ */
82
+ reset(): void;
83
+ /**
84
+ * Instantly moves the head to position `phase`.
85
+ *
86
+ * ! Does NOT update `actualTime`.
87
+ *
88
+ * Trail is left untouched by default. You can pass `clearTrail: true` to wipe it.
89
+ * Use for morphing mid-flight or any time you don't need trail context.
90
+ * @param phase The position to jump to (will be wrapped into [0, period))
91
+ */
92
+ jump(phase: number, options?: JumpOptions): void;
93
+ /**
94
+ * Moves to `phase` AND reconstructs the trail as if the animation naturally arrived there from `phase=0`
95
+ * Also updates `actualTime` to match. Trail is always rebuilt from scratch
96
+ * Use for initialisation or any jump where you want the trail to look meaningful
97
+ * @param phase The position to seek to (will be wrapped into [0, period))
98
+ */
99
+ seek(phase: number, options?: SeekOptions): void;
100
+ /**
101
+ * Overrides the animation speed at runtime
102
+ * `0` freezes `phase` but the loop keeps running
103
+ * Negative values reverse traversal.
104
+ *
105
+ * ! Does NOT affect a curve's inherent speed given in CurveDef
106
+ * @param speed 0 = freeze, negative = reverse, no upper bound
107
+ */
108
+ setSpeed(speed: number): void;
109
+ /**
110
+ * Returns the *effective speed* the engine is currently using:
111
+ * `userSpeedOverride` if set, otherwise the curve's default speed.
112
+ * This is what `tick()` actually uses
113
+ */
114
+ getSpeed(): number;
115
+ /**
116
+ * Drops the speed override and defers back to the curve's inherent default speed.
117
+ * ! Sets `userSpeedOverride` to `null`
118
+ */
119
+ resetSpeed(): void;
120
+ /**
121
+ * Transitions to the target speed over `duration` milliseconds using linear interpolation.
122
+ * Resolves when the transition completes.
123
+ *
124
+ * Calling this while a transition is already in progress cancels the old transition
125
+ * (rejecting its Promise) and starts a new one from the current interpolated speed.
126
+ *
127
+ * @param speed Target speed
128
+ * @param duration Transition duration in milliseconds (must be > 0)
129
+ */
130
+ setSpeedOver(speed: number, duration: number): Promise<void>;
131
131
  }
132
132
  type MorphOptions = {
133
- /**
134
- * Duration of the morph transition in milliseconds
135
- * @default 300
136
- */
137
- duration?: number;
138
- /**
139
- * Strategy for lerping between curves with different periods:
140
- * - 'normalized': maps `phase` proportionally into each curve's period (smooth for all period ratios)
141
- * - 'raw': uses the same `phase` for both curves (can produce incoherent results for mismatched periods)
142
- * @default 'normalized'
143
- */
144
- morphStrategy?: MorpStrategy;
133
+ /**
134
+ * Duration of the morph transition in milliseconds
135
+ * @default 300
136
+ */
137
+ duration?: number;
138
+ /**
139
+ * Strategy for lerping between curves with different periods:
140
+ * - 'normalized': maps `phase` proportionally into each curve's period (smooth for all period ratios)
141
+ * - 'raw': uses the same `phase` for both curves (can produce incoherent results for mismatched periods)
142
+ * @default 'normalized'
143
+ */
144
+ morphStrategy?: MorpStrategy;
145
145
  };
146
146
  interface Engine extends AnimationControls {
147
- /**
148
- * Advances the Sarmal simulation by the given delta time (dt) in seconds.
149
- * Internally, this increases the simulation `phase` by `speed * dt`,
150
- * wraps `phase` at `period`, evaluates the curve's parametric function `fn(phase)`,
151
- * and appends the new point to the trail.
152
- * Returns the pre-allocated trail buffer, which has the *same* reference every call
153
- * ! Do not use `Array.length` to determine size
154
- * @param deltaTime Delta time in seconds (typically frame time from **requestAnimationFrame** or similar)
155
- */
156
- tick(deltaTime: number): Array<Point>;
157
- /**
158
- * Number of valid points in the trail buffer returned by the last `tick()` call
159
- * ! Use this instead of `trail.length`
160
- */
161
- readonly trailCount: number;
162
- /**
163
- * The maximum capacity of the trail buffer, which is set at engine creation
164
- * This is the upper bound for `trailCount`
165
- */
166
- readonly trailLength: number;
167
- /**
168
- * Returns the *skeleton* of the curve.
169
- * In technicality, it just represents the complete traversal of the curve over one full period,
170
- * which is sampled at points from `phase=0` to `phase=period`
171
- *
172
- * For "static" skeletons, this returns the same array on every call
173
- * For "live" skeletons, this returns a different array each frame
174
- * For `skeletonFn` overrides, this returns the skeleton from that function, which is *always* static
175
- *
176
- * The number of sample points is automatically derived from the curve's period.
177
- */
178
- getSarmalSkeleton(): Array<Point>;
179
- readonly isLiveSkeleton: boolean;
180
- /**
181
- * Begins a smooth transition from the current curve to `target`
182
- * Saves the current curve as `curveA`, registers `target` as `curveB`, and resets `morphAlpha` to `0`
183
- *
184
- * If called while a morph is already in progress,
185
- * the interpolated state is frozen and becomes the new `curveA`
186
- * @param target The curve to transition to
187
- * @param strategy 'normalized' maps phase proportionally into each curve's period (default), 'raw' uses the same phase
188
- */
189
- startMorph(target: CurveDef, strategy?: MorpStrategy): void;
190
- /**
191
- * Sets the interpolation amount between `curveA` and `curveB`.
192
- * 0 = full curveA
193
- * 1 = full curveB
194
- * Called by the renderer each frame as `actualTime` advances
195
- * @param alpha A value in [0, 1]
196
- */
197
- setMorphAlpha(alpha: number): void;
198
- /**
199
- * Finalises the morph: `curveB` becomes the new active curve and `morphAlpha` is reset to `null`
200
- * ! Called by the renderer when alpha reaches `1`
201
- */
202
- completeMorph(): void;
203
- /**
204
- * Current interpolation progress between `curveA` and `curveB`
205
- * `null` when no morph is in progress
206
- */
207
- readonly morphAlpha: number | null;
208
- /**
209
- * Cancels any in-progress speed transition initiated by `setSpeedOver()`.
210
- * Called internally by the renderer's `stop()` method.
211
- */
212
- cancelSpeedTransition(): void;
147
+ /**
148
+ * Advances the Sarmal simulation by the given delta time (dt) in seconds.
149
+ * Internally, this increases the simulation `phase` by `speed * dt`,
150
+ * wraps `phase` at `period`, evaluates the curve's parametric function `fn(phase)`,
151
+ * and appends the new point to the trail.
152
+ * Returns the pre-allocated trail buffer, which has the *same* reference every call
153
+ * ! Do not use `Array.length` to determine size
154
+ * @param deltaTime Delta time in seconds (typically frame time from **requestAnimationFrame** or similar)
155
+ */
156
+ tick(deltaTime: number): Array<Point>;
157
+ /**
158
+ * Number of valid points in the trail buffer returned by the last `tick()` call
159
+ * ! Use this instead of `trail.length`
160
+ */
161
+ readonly trailCount: number;
162
+ /**
163
+ * The maximum capacity of the trail buffer, which is set at engine creation
164
+ * This is the upper bound for `trailCount`
165
+ */
166
+ readonly trailLength: number;
167
+ /**
168
+ * Returns the *skeleton* of the curve.
169
+ * In technicality, it just represents the complete traversal of the curve over one full period,
170
+ * which is sampled at points from `phase=0` to `phase=period`
171
+ *
172
+ * For "static" skeletons, this returns the same array on every call
173
+ * For "live" skeletons, this returns a different array each frame
174
+ * For `skeletonFn` overrides, this returns the skeleton from that function, which is *always* static
175
+ *
176
+ * The number of sample points is automatically derived from the curve's period.
177
+ */
178
+ getSarmalSkeleton(): Array<Point>;
179
+ readonly isLiveSkeleton: boolean;
180
+ /**
181
+ * Begins a smooth transition from the current curve to `target`
182
+ * Saves the current curve as `curveA`, registers `target` as `curveB`, and resets `morphAlpha` to `0`
183
+ *
184
+ * If called while a morph is already in progress,
185
+ * the interpolated state is frozen and becomes the new `curveA`
186
+ * @param target The curve to transition to
187
+ * @param strategy 'normalized' maps phase proportionally into each curve's period (default), 'raw' uses the same phase
188
+ */
189
+ startMorph(target: CurveDef, strategy?: MorpStrategy): void;
190
+ /**
191
+ * Sets the interpolation amount between `curveA` and `curveB`.
192
+ * 0 = full curveA
193
+ * 1 = full curveB
194
+ * Called by the renderer each frame as `actualTime` advances
195
+ * @param alpha A value in [0, 1]
196
+ */
197
+ setMorphAlpha(alpha: number): void;
198
+ /**
199
+ * Finalises the morph: `curveB` becomes the new active curve and `morphAlpha` is reset to `null`
200
+ * ! Called by the renderer when alpha reaches `1`
201
+ */
202
+ completeMorph(): void;
203
+ /**
204
+ * Current interpolation progress between `curveA` and `curveB`
205
+ * `null` when no morph is in progress
206
+ */
207
+ readonly morphAlpha: number | null;
208
+ /**
209
+ * Cancels any in-progress speed transition initiated by `setSpeedOver()`.
210
+ * Called internally by the renderer's `stop()` method.
211
+ */
212
+ cancelSpeedTransition(): void;
213
213
  }
214
214
  interface SarmalInstance extends AnimationControls {
215
- /** Starts the animation loop (requestAnimationFrame). If already running, does nothing. */
216
- play(): void;
217
- /** Pauses the animation loop (cancelAnimationFrame) and cancels any speed transition. Preserves state. */
218
- pause(): void;
219
- /** Stops the animation and cleans up resources */
220
- destroy(): void;
221
- /**
222
- * Returns the skeleton of the curve:
223
- * The complete traversal over one full period, sampled at points from phase=0 to phase=period.
224
- */
225
- getSarmalSkeleton(): Array<Point>;
226
- /**
227
- * Smoothly transitions from the current curve to `target`.
228
- * The trail naturally reflects the new curve as new points are added.
229
- * @param target The curve to transition to
230
- * @param options.duration How long the morph takes in milliseconds (default: 300)
231
- * @param options.morphStrategy 'normalized' uses proportional phase mapping (default), 'raw' uses same phase
232
- * @returns Promise that resolves when the morph is complete
233
- */
234
- morphTo(target: CurveDef, options?: MorphOptions): Promise<void>;
235
- /**
236
- * Changes render options on a live SarmalInstance without destroying and recreating it.
237
- *
238
- * ! Validation fails the operation completely if any of the fields fail the chceck.
239
- */
240
- setRenderOptions(partial: RuntimeRenderOptions): void;
215
+ /** Starts the animation loop (requestAnimationFrame). If already running, does nothing. */
216
+ play(): void;
217
+ /** Pauses the animation loop (cancelAnimationFrame) and cancels any speed transition. Preserves state. */
218
+ pause(): void;
219
+ /** Stops the animation and cleans up resources */
220
+ destroy(): void;
221
+ /**
222
+ * Returns the skeleton of the curve:
223
+ * The complete traversal over one full period, sampled at points from phase=0 to phase=period.
224
+ */
225
+ getSarmalSkeleton(): Array<Point>;
226
+ /**
227
+ * Smoothly transitions from the current curve to `target`.
228
+ * The trail naturally reflects the new curve as new points are added.
229
+ * @param target The curve to transition to
230
+ * @param options.duration How long the morph takes in milliseconds (default: 300)
231
+ * @param options.morphStrategy 'normalized' uses proportional phase mapping (default), 'raw' uses same phase
232
+ * @returns Promise that resolves when the morph is complete
233
+ */
234
+ morphTo(target: CurveDef, options?: MorphOptions): Promise<void>;
235
+ /**
236
+ * Changes render options on a live SarmalInstance without destroying and recreating it.
237
+ *
238
+ * ! Validation fails the operation completely if any of the fields fail the chceck.
239
+ */
240
+ setRenderOptions(partial: RuntimeRenderOptions): void;
241
241
  }
242
242
  /**
243
243
  * With 'gradient-animated' the colors cycle along the trail over time
@@ -258,82 +258,68 @@ type TrailColor = string | string[];
258
258
  * Passing `"transparent"` for `skeletonColor` hides the skeleton. Any other value must be a valid {@link TrailColor}.
259
259
  */
260
260
  interface RuntimeRenderOptions {
261
- trailColor?: TrailColor;
262
- /** 6-digit hex string to override, or `null` to make it automatic */
263
- headColor?: string | null;
264
- /** 6-digit hex string, or `"transparent"` to hide the skeleton. */
265
- skeletonColor?: string;
266
- trailStyle?: TrailStyle;
267
- /** Radius of the head dot.
268
- * - Canvas: CSS pixels. Auto-derived from container size if omitted.
269
- * - SVG: viewBox units (0–100 space). Default: `0.5`. */
270
- headRadius?: number;
261
+ trailColor?: TrailColor;
262
+ /** 6-digit hex string to override, or `null` to make it automatic */
263
+ headColor?: string | null;
264
+ /** 6-digit hex string, or `"transparent"` to hide the skeleton. */
265
+ skeletonColor?: string;
266
+ trailStyle?: TrailStyle;
267
+ /** Radius of the head dot.
268
+ * - Canvas: CSS pixels. Auto-derived from container size if omitted.
269
+ * - SVG: viewBox units (0–100 space). Default: `0.5`. */
270
+ headRadius?: number;
271
271
  }
272
272
  /**
273
273
  * Common renderer options shared between canvas and SVG renderers.
274
274
  * Extracted to avoid duplication and ensure consistency.
275
275
  */
276
276
  interface BaseRendererOptions {
277
- /**
278
- * Whether to start the animation loop automatically on creation.
279
- * @default true
280
- */
281
- autoStart?: boolean;
282
- /**
283
- * Whether to automatically pause the animation when the browser tab is hidden
284
- * and resume it when the tab becomes visible again.
285
- * @default true
286
- */
287
- pauseOnHidden?: boolean;
288
- /**
289
- * Initial position along the curve (phase value). If provided, seek(initialPhase) is called before the first frame.
290
- * @default undefined (no seek performed, starts at phase=0)
291
- */
292
- initialPhase?: number;
293
- /**
294
- * @default '#ffffff'
295
- */
296
- skeletonColor?: string;
297
- /**
298
- * Single hex color for default trails, or an array of hex colors for gradient trails.
299
- * @default '#ffffff'
300
- */
301
- trailColor?: TrailColor;
302
- /**
303
- * Hex color for the head dot.
304
- * If omitted, the color is derived from the trail
305
- */
306
- headColor?: string;
307
- /** @default 4 */
308
- headRadius?: number;
309
- /**
310
- * Trail rendering style
311
- * @default 'default'
312
- */
313
- trailStyle?: TrailStyle;
277
+ /**
278
+ * Whether to start the animation loop automatically on creation.
279
+ * @default true
280
+ */
281
+ autoStart?: boolean;
282
+ /**
283
+ * Whether to automatically pause the animation when the browser tab is hidden
284
+ * and resume it when the tab becomes visible again.
285
+ * @default true
286
+ */
287
+ pauseOnHidden?: boolean;
288
+ /**
289
+ * Initial position along the curve (phase value). If provided, seek(initialPhase) is called before the first frame.
290
+ * @default undefined (no seek performed, starts at phase=0)
291
+ */
292
+ initialPhase?: number;
293
+ /**
294
+ * @default '#ffffff'
295
+ */
296
+ skeletonColor?: string;
297
+ /**
298
+ * Single hex color for default trails, or an array of hex colors for gradient trails.
299
+ * @default '#ffffff'
300
+ */
301
+ trailColor?: TrailColor;
302
+ /**
303
+ * Hex color for the head dot.
304
+ * If omitted, the color is derived from the trail
305
+ */
306
+ headColor?: string;
307
+ /** @default 4 */
308
+ headRadius?: number;
309
+ /**
310
+ * Trail rendering style
311
+ * @default 'default'
312
+ */
313
+ trailStyle?: TrailStyle;
314
314
  }
315
315
  interface RendererOptions extends BaseRendererOptions {
316
- /** Target canvas element that will contain the Sarmal */
317
- canvas: HTMLCanvasElement;
318
- engine: Engine;
316
+ /** Target canvas element that will contain the Sarmal */
317
+ canvas: HTMLCanvasElement;
318
+ engine: Engine;
319
319
  }
320
320
  interface SarmalOptions extends Omit<RendererOptions, "canvas" | "engine"> {
321
- /** @default 120 */
322
- trailLength?: number;
321
+ /** @default 120 */
322
+ trailLength?: number;
323
323
  }
324
324
 
325
- export type {
326
- BaseRendererOptions as B,
327
- CurveDef as C,
328
- Engine as E,
329
- JumpOptions as J,
330
- Point as P,
331
- RendererOptions as R,
332
- SarmalInstance as S,
333
- TrailColor as T,
334
- ControlPoint as a,
335
- SarmalOptions as b,
336
- RuntimeRenderOptions as c,
337
- SeekOptions as d,
338
- TrailStyle as e,
339
- };
325
+ export type { BaseRendererOptions as B, CurveDef as C, Engine as E, JumpOptions as J, Point as P, RendererOptions as R, SarmalInstance as S, TrailColor as T, ControlPoint as a, SarmalOptions as b, RuntimeRenderOptions as c, SeekOptions as d, TrailStyle as e };