egaki 0.5.0 → 0.7.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 (280) hide show
  1. package/CHANGELOG.md +188 -0
  2. package/dist/cli/cache-utils.d.ts +33 -0
  3. package/dist/cli/cache-utils.d.ts.map +1 -0
  4. package/dist/cli/cache-utils.js +157 -0
  5. package/dist/cli/cached-generate.d.ts +105 -0
  6. package/dist/cli/cached-generate.d.ts.map +1 -0
  7. package/dist/cli/cached-generate.js +208 -0
  8. package/dist/cli/cached-generate.test.d.ts +11 -0
  9. package/dist/cli/cached-generate.test.d.ts.map +1 -0
  10. package/dist/cli/cached-generate.test.js +431 -0
  11. package/dist/cli/cartesia-provider.d.ts +16 -0
  12. package/dist/cli/cartesia-provider.d.ts.map +1 -0
  13. package/dist/cli/cartesia-provider.js +184 -0
  14. package/dist/cli/chatgpt-auth.d.ts.map +1 -0
  15. package/dist/cli/cli.d.ts +4 -0
  16. package/dist/cli/cli.d.ts.map +1 -0
  17. package/dist/cli/cli.js +1329 -0
  18. package/dist/cli/clone-generate.d.ts +26 -0
  19. package/dist/cli/clone-generate.d.ts.map +1 -0
  20. package/dist/cli/clone-generate.js +148 -0
  21. package/dist/{credentials.d.ts → cli/credentials.d.ts} +11 -2
  22. package/dist/cli/credentials.d.ts.map +1 -0
  23. package/dist/{credentials.js → cli/credentials.js} +88 -5
  24. package/dist/cli/elevenlabs-speech-provider.d.ts +26 -0
  25. package/dist/cli/elevenlabs-speech-provider.d.ts.map +1 -0
  26. package/dist/cli/elevenlabs-speech-provider.js +199 -0
  27. package/dist/cli/generate.d.ts +140 -0
  28. package/dist/cli/generate.d.ts.map +1 -0
  29. package/dist/cli/generate.js +604 -0
  30. package/dist/cli/generate.test.d.ts +2 -0
  31. package/dist/cli/generate.test.d.ts.map +1 -0
  32. package/dist/cli/generate.test.js +131 -0
  33. package/dist/cli/login.d.ts.map +1 -0
  34. package/dist/{login.js → cli/login.js} +45 -4
  35. package/dist/cli/main.d.ts +3 -0
  36. package/dist/cli/main.d.ts.map +1 -0
  37. package/dist/cli/main.js +7 -0
  38. package/dist/cli/model-catalog.d.ts +141 -0
  39. package/dist/cli/model-catalog.d.ts.map +1 -0
  40. package/dist/cli/model-catalog.js +2135 -0
  41. package/dist/{models.d.ts → cli/models.d.ts} +16 -9
  42. package/dist/cli/models.d.ts.map +1 -0
  43. package/dist/cli/models.js +313 -0
  44. package/dist/cli/open-browser.d.ts.map +1 -0
  45. package/dist/cli/openai-speech-provider.d.ts +3 -0
  46. package/dist/cli/openai-speech-provider.d.ts.map +1 -0
  47. package/dist/cli/openai-speech-provider.js +28 -0
  48. package/dist/cli/separation-generate.d.ts +34 -0
  49. package/dist/cli/separation-generate.d.ts.map +1 -0
  50. package/dist/cli/separation-generate.js +117 -0
  51. package/dist/cli/speech-catalog.d.ts +35 -0
  52. package/dist/cli/speech-catalog.d.ts.map +1 -0
  53. package/dist/cli/speech-catalog.js +195 -0
  54. package/dist/cli/speech-generate.d.ts +86 -0
  55. package/dist/cli/speech-generate.d.ts.map +1 -0
  56. package/dist/cli/speech-generate.js +156 -0
  57. package/dist/cli/speech-models.d.ts +8 -0
  58. package/dist/cli/speech-models.d.ts.map +1 -0
  59. package/dist/cli/speech-models.js +109 -0
  60. package/dist/cli/speech-provider.test.d.ts +2 -0
  61. package/dist/cli/speech-provider.test.d.ts.map +1 -0
  62. package/dist/cli/speech-provider.test.js +197 -0
  63. package/dist/cli/subscription.d.ts.map +1 -0
  64. package/dist/cli/transcription-catalog.d.ts +35 -0
  65. package/dist/cli/transcription-catalog.d.ts.map +1 -0
  66. package/dist/cli/transcription-catalog.js +192 -0
  67. package/dist/cli/transcription-generate.d.ts +62 -0
  68. package/dist/cli/transcription-generate.d.ts.map +1 -0
  69. package/dist/cli/transcription-generate.js +144 -0
  70. package/dist/cli/transcription-models.d.ts +9 -0
  71. package/dist/cli/transcription-models.d.ts.map +1 -0
  72. package/dist/cli/transcription-models.js +100 -0
  73. package/dist/cli/transcription-providers.d.ts +22 -0
  74. package/dist/cli/transcription-providers.d.ts.map +1 -0
  75. package/dist/cli/transcription-providers.js +290 -0
  76. package/dist/cli/video-model-catalog.d.ts +2 -0
  77. package/dist/cli/video-model-catalog.d.ts.map +1 -0
  78. package/dist/cli/video-model-catalog.js +5 -0
  79. package/dist/cli/xai-auth.d.ts +29 -0
  80. package/dist/cli/xai-auth.d.ts.map +1 -0
  81. package/dist/cli/xai-auth.js +325 -0
  82. package/dist/vite/angled-screen.d.ts +57 -0
  83. package/dist/vite/angled-screen.d.ts.map +1 -0
  84. package/dist/vite/angled-screen.js +115 -0
  85. package/dist/vite/app.d.ts +51 -0
  86. package/dist/vite/app.d.ts.map +1 -0
  87. package/dist/vite/app.js +150 -0
  88. package/dist/vite/bands-shader.d.ts +47 -0
  89. package/dist/vite/bands-shader.d.ts.map +1 -0
  90. package/dist/vite/bands-shader.js +267 -0
  91. package/dist/vite/code-block.d.ts +107 -0
  92. package/dist/vite/code-block.d.ts.map +1 -0
  93. package/dist/vite/code-block.js +641 -0
  94. package/dist/vite/components.d.ts +36 -0
  95. package/dist/vite/components.d.ts.map +1 -0
  96. package/dist/vite/components.js +113 -0
  97. package/dist/vite/dispersion-rings-shader.d.ts +44 -0
  98. package/dist/vite/dispersion-rings-shader.d.ts.map +1 -0
  99. package/dist/vite/dispersion-rings-shader.js +282 -0
  100. package/dist/vite/easing-curves.d.ts +129 -0
  101. package/dist/vite/easing-curves.d.ts.map +1 -0
  102. package/dist/vite/easing-curves.js +584 -0
  103. package/dist/vite/easing-curves.test.d.ts +2 -0
  104. package/dist/vite/easing-curves.test.d.ts.map +1 -0
  105. package/dist/vite/easing-curves.test.js +200 -0
  106. package/dist/vite/generated-media-client.d.ts +35 -0
  107. package/dist/vite/generated-media-client.d.ts.map +1 -0
  108. package/dist/vite/generated-media-client.js +76 -0
  109. package/dist/vite/keyframes.d.ts +129 -0
  110. package/dist/vite/keyframes.d.ts.map +1 -0
  111. package/dist/vite/keyframes.js +194 -0
  112. package/dist/vite/layout-editor.d.ts +45 -0
  113. package/dist/vite/layout-editor.d.ts.map +1 -0
  114. package/dist/vite/layout-editor.js +587 -0
  115. package/dist/vite/layout-transition.d.ts +136 -0
  116. package/dist/vite/layout-transition.d.ts.map +1 -0
  117. package/dist/vite/layout-transition.js +581 -0
  118. package/dist/vite/liquid-gradient-shader.d.ts +62 -0
  119. package/dist/vite/liquid-gradient-shader.d.ts.map +1 -0
  120. package/dist/vite/liquid-gradient-shader.js +413 -0
  121. package/dist/vite/mdx-client.d.ts +15 -0
  122. package/dist/vite/mdx-client.d.ts.map +1 -0
  123. package/dist/vite/mdx-client.js +265 -0
  124. package/dist/vite/mdx-parse.d.ts +102 -0
  125. package/dist/vite/mdx-parse.d.ts.map +1 -0
  126. package/dist/vite/mdx-parse.js +251 -0
  127. package/dist/vite/mdx-provided-components.d.ts +18 -0
  128. package/dist/vite/mdx-provided-components.d.ts.map +1 -0
  129. package/dist/vite/mdx-provided-components.js +14 -0
  130. package/dist/vite/mdx-video.d.ts +327 -0
  131. package/dist/vite/mdx-video.d.ts.map +1 -0
  132. package/dist/vite/mdx-video.js +596 -0
  133. package/dist/vite/mdx-video.test.d.ts +9 -0
  134. package/dist/vite/mdx-video.test.d.ts.map +1 -0
  135. package/dist/vite/mdx-video.test.js +1945 -0
  136. package/dist/vite/media-components.d.ts +45 -0
  137. package/dist/vite/media-components.d.ts.map +1 -0
  138. package/dist/vite/media-components.js +355 -0
  139. package/dist/vite/media-duration-store.d.ts +66 -0
  140. package/dist/vite/media-duration-store.d.ts.map +1 -0
  141. package/dist/vite/media-duration-store.js +204 -0
  142. package/dist/vite/player-page.d.ts +35 -0
  143. package/dist/vite/player-page.d.ts.map +1 -0
  144. package/dist/vite/player-page.js +720 -0
  145. package/dist/vite/render-client.d.ts +18 -0
  146. package/dist/vite/render-client.d.ts.map +1 -0
  147. package/dist/vite/render-client.js +67 -0
  148. package/dist/vite/sdk.d.ts +221 -0
  149. package/dist/vite/sdk.d.ts.map +1 -0
  150. package/dist/vite/sdk.js +355 -0
  151. package/dist/vite/server-components.d.ts +55 -0
  152. package/dist/vite/server-components.d.ts.map +1 -0
  153. package/dist/vite/server-components.js +156 -0
  154. package/dist/vite/server-mdx.d.ts +74 -0
  155. package/dist/vite/server-mdx.d.ts.map +1 -0
  156. package/dist/vite/server-mdx.js +259 -0
  157. package/dist/vite/shader-renderer.d.ts +48 -0
  158. package/dist/vite/shader-renderer.d.ts.map +1 -0
  159. package/dist/vite/shader-renderer.js +411 -0
  160. package/dist/vite/store-hooks.d.ts +12 -0
  161. package/dist/vite/store-hooks.d.ts.map +1 -0
  162. package/dist/vite/store-hooks.js +93 -0
  163. package/dist/vite/store.d.ts +75 -0
  164. package/dist/vite/store.d.ts.map +1 -0
  165. package/dist/vite/store.js +52 -0
  166. package/dist/vite/store.test.d.ts +6 -0
  167. package/dist/vite/store.test.d.ts.map +1 -0
  168. package/dist/vite/store.test.js +172 -0
  169. package/dist/vite/tweakpane-hook.d.ts +94 -0
  170. package/dist/vite/tweakpane-hook.d.ts.map +1 -0
  171. package/dist/vite/tweakpane-hook.js +450 -0
  172. package/dist/vite/vite-plugin.d.ts +28 -0
  173. package/dist/vite/vite-plugin.d.ts.map +1 -0
  174. package/dist/vite/vite-plugin.js +538 -0
  175. package/dist/vite/wave-gradient-shader.d.ts +41 -0
  176. package/dist/vite/wave-gradient-shader.d.ts.map +1 -0
  177. package/dist/vite/wave-gradient-shader.js +207 -0
  178. package/package.json +103 -25
  179. package/skills/egaki/SKILL.md +162 -1
  180. package/src/cli/cache-utils.ts +169 -0
  181. package/src/cli/cached-generate.test.ts +531 -0
  182. package/src/cli/cached-generate.ts +348 -0
  183. package/src/cli/cartesia-provider.ts +249 -0
  184. package/src/cli/cli.ts +1818 -0
  185. package/src/cli/clone-generate.ts +202 -0
  186. package/src/{credentials.ts → cli/credentials.ts} +90 -7
  187. package/src/cli/elevenlabs-speech-provider.ts +243 -0
  188. package/src/cli/generate.test.ts +166 -0
  189. package/src/cli/generate.ts +912 -0
  190. package/src/{login.ts → cli/login.ts} +48 -3
  191. package/src/cli/main.ts +8 -0
  192. package/src/cli/model-catalog.ts +2336 -0
  193. package/src/cli/models.ts +408 -0
  194. package/src/cli/openai-speech-provider.ts +34 -0
  195. package/src/cli/separation-generate.ts +187 -0
  196. package/src/cli/speech-catalog.ts +253 -0
  197. package/src/cli/speech-generate.ts +275 -0
  198. package/src/cli/speech-models.ts +146 -0
  199. package/src/cli/speech-provider.test.ts +226 -0
  200. package/src/cli/transcription-catalog.ts +250 -0
  201. package/src/cli/transcription-generate.ts +214 -0
  202. package/src/cli/transcription-models.ts +136 -0
  203. package/src/cli/transcription-providers.ts +427 -0
  204. package/src/cli/video-model-catalog.ts +14 -0
  205. package/src/cli/xai-auth.ts +396 -0
  206. package/src/vite/angled-screen.tsx +214 -0
  207. package/src/vite/app.tsx +197 -0
  208. package/src/vite/bands-shader.tsx +319 -0
  209. package/src/vite/code-block.tsx +939 -0
  210. package/src/vite/components.tsx +278 -0
  211. package/src/vite/dispersion-rings-shader.tsx +331 -0
  212. package/src/vite/easing-curves.test.ts +232 -0
  213. package/src/vite/easing-curves.ts +743 -0
  214. package/src/vite/generated-media-client.tsx +121 -0
  215. package/src/vite/keyframes.tsx +347 -0
  216. package/src/vite/layout-editor.tsx +709 -0
  217. package/src/vite/layout-transition.tsx +706 -0
  218. package/src/vite/liquid-gradient-shader.tsx +474 -0
  219. package/src/vite/mdx-client.tsx +420 -0
  220. package/src/vite/mdx-parse.ts +343 -0
  221. package/src/vite/mdx-provided-components.ts +19 -0
  222. package/src/vite/mdx-video.test.tsx +2219 -0
  223. package/src/vite/mdx-video.tsx +976 -0
  224. package/src/vite/media-components.tsx +473 -0
  225. package/src/vite/media-duration-store.ts +225 -0
  226. package/src/vite/motion-timing.ts +194 -0
  227. package/src/vite/player-page.tsx +1107 -0
  228. package/src/vite/render-client.ts +84 -0
  229. package/src/vite/sdk.ts +598 -0
  230. package/src/vite/server-components.tsx +241 -0
  231. package/src/vite/server-mdx.ts +285 -0
  232. package/src/vite/shader-renderer.tsx +535 -0
  233. package/src/vite/store-hooks.ts +117 -0
  234. package/src/vite/store.test.ts +202 -0
  235. package/src/vite/store.ts +115 -0
  236. package/src/vite/styles.css +21 -0
  237. package/src/vite/tweakpane-hook.tsx +593 -0
  238. package/src/vite/virtual-modules.d.ts +30 -0
  239. package/src/vite/vite-plugin.ts +584 -0
  240. package/src/vite/wave-gradient-shader.tsx +253 -0
  241. package/README.md +0 -266
  242. package/dist/antigravity-auth.d.ts +0 -15
  243. package/dist/antigravity-auth.d.ts.map +0 -1
  244. package/dist/antigravity-auth.js +0 -544
  245. package/dist/antigravity-image.d.ts +0 -11
  246. package/dist/antigravity-image.d.ts.map +0 -1
  247. package/dist/antigravity-image.js +0 -285
  248. package/dist/chatgpt-auth.d.ts.map +0 -1
  249. package/dist/cli.d.ts +0 -3
  250. package/dist/cli.d.ts.map +0 -1
  251. package/dist/cli.js +0 -968
  252. package/dist/credentials.d.ts.map +0 -1
  253. package/dist/gateway-model-candidates.generated.d.ts +0 -11
  254. package/dist/gateway-model-candidates.generated.d.ts.map +0 -1
  255. package/dist/gateway-model-candidates.generated.js +0 -64
  256. package/dist/login.d.ts.map +0 -1
  257. package/dist/model-catalog.d.ts +0 -42
  258. package/dist/model-catalog.d.ts.map +0 -1
  259. package/dist/model-catalog.js +0 -1001
  260. package/dist/models.d.ts.map +0 -1
  261. package/dist/models.js +0 -246
  262. package/dist/open-browser.d.ts.map +0 -1
  263. package/dist/subscription.d.ts.map +0 -1
  264. package/dist/video-model-catalog.d.ts +0 -52
  265. package/dist/video-model-catalog.d.ts.map +0 -1
  266. package/dist/video-model-catalog.js +0 -306
  267. package/src/cli.ts +0 -1378
  268. package/src/model-catalog.ts +0 -1077
  269. package/src/models.ts +0 -309
  270. package/src/video-model-catalog.ts +0 -363
  271. /package/dist/{chatgpt-auth.d.ts → cli/chatgpt-auth.d.ts} +0 -0
  272. /package/dist/{chatgpt-auth.js → cli/chatgpt-auth.js} +0 -0
  273. /package/dist/{login.d.ts → cli/login.d.ts} +0 -0
  274. /package/dist/{open-browser.d.ts → cli/open-browser.d.ts} +0 -0
  275. /package/dist/{open-browser.js → cli/open-browser.js} +0 -0
  276. /package/dist/{subscription.d.ts → cli/subscription.d.ts} +0 -0
  277. /package/dist/{subscription.js → cli/subscription.js} +0 -0
  278. /package/src/{chatgpt-auth.ts → cli/chatgpt-auth.ts} +0 -0
  279. /package/src/{open-browser.ts → cli/open-browser.ts} +0 -0
  280. /package/src/{subscription.ts → cli/subscription.ts} +0 -0
@@ -0,0 +1,232 @@
1
+ /**
2
+ * Tests for the easing curve engine.
3
+ *
4
+ * The golden values below are the ORIGINAL hardcoded sample arrays that were
5
+ * extracted from Jitter's webpack bundle (before this file generated them
6
+ * from functions). They pin the generator output: every preset is checked at
7
+ * 10 spot indices per intensity level, plus structural invariants.
8
+ *
9
+ * During the port, ALL 3570 values (14 presets x 5 intensities x 51 samples)
10
+ * were verified Object.is-identical to the extracted arrays. These spot
11
+ * checks guard against regressions in the engine math.
12
+ */
13
+ import { describe, expect, test } from 'vitest'
14
+
15
+ import {
16
+ type Intensity,
17
+ accelerateElasticSamples,
18
+ accelerateImpulseSamples,
19
+ bounceAnticipateSamples,
20
+ bounceSamples,
21
+ bounceThrowSamples,
22
+ cubicBezier,
23
+ decelerateElasticSamples,
24
+ decelerateOvershootSamples,
25
+ elasticSnapSamples,
26
+ impulseOvershootSamples,
27
+ impulseSlowSamples,
28
+ lerpSamples,
29
+ naturalThrowSamples,
30
+ overshootBouncySamples,
31
+ overshootElasticSamples,
32
+ overshootSamples,
33
+ polybezier,
34
+ } from './easing-curves.ts'
35
+
36
+ const SPOT_INDICES = [0, 1, 7, 13, 19, 25, 31, 37, 43, 50] as const
37
+
38
+ const GOLDEN: Record<string, Record<Intensity, number[]>> = {
39
+ naturalThrow: {
40
+ 0: [0, -0.0004, -0.0275, -0.0921, -0.0621, 0.3395, 1.0399, 1.1399, 1.0314, 1],
41
+ 25: [0, -0.0005, -0.0453, -0.1428, -0.1247, 0.19, 0.9808, 1.1559, 1.0338, 1],
42
+ 50: [0, -0.0005, -0.0706, -0.1938, -0.1819, 0.0583, 0.8338, 1.1644, 1.0353, 1],
43
+ 75: [0, -0.0007, -0.0975, -0.2918, -0.2818, -0.0397, 0.7714, 1.198, 1.0418, 1],
44
+ 100: [0, -0.0008, -0.1164, -0.3903, -0.3819, -0.1404, 0.6832, 1.2223, 1.0467, 1],
45
+ },
46
+ decelerateOvershoot: {
47
+ 0: [0, 0.2145, 0.8308, 1.0582, 1.0982, 1.0661, 1.0335, 1.0137, 1.0035, 1],
48
+ 25: [0, 0.2486, 0.9403, 1.1731, 1.189, 1.1204, 1.0611, 1.0252, 1.0065, 1],
49
+ 50: [0, 0.2873, 1.058, 1.2874, 1.2684, 1.165, 1.0839, 1.0348, 1.0091, 1],
50
+ 75: [0, 0.4347, 1.2454, 1.4, 1.3216, 1.1915, 1.098, 1.041, 1.0108, 1],
51
+ 100: [0, 0.6371, 1.4202, 1.4889, 1.3572, 1.21, 1.1081, 1.0456, 1.0121, 1],
52
+ },
53
+ decelerateElastic: {
54
+ 0: [0, 0.2149, 0.7414, 0.9671, 1.0709, 1.1, 1.0805, 1.0411, 1.0115, 1],
55
+ 25: [0, 0.2642, 0.8047, 1.0237, 1.1226, 1.15, 1.1218, 1.0552, 1.0133, 1],
56
+ 50: [0, 0.3251, 0.8688, 1.0799, 1.1741, 1.2, 1.1642, 1.0638, 1.0137, 1],
57
+ 75: [0, 0.4212, 1.0067, 1.2265, 1.3235, 1.35, 1.3148, 1.1251, 1.0226, 1],
58
+ 100: [0, 0.5174, 1.1446, 1.3731, 1.4728, 1.5, 1.4704, 1.2162, 1.0302, 1],
59
+ },
60
+ accelerateImpulse: {
61
+ 0: [0, -0.0005, -0.0262, -0.0738, -0.0995, -0.0784, 0.0105, 0.1811, 0.4571, 1],
62
+ 25: [0, -0.0006, -0.0313, -0.0942, -0.1422, -0.1442, -0.0779, 0.079, 0.362, 1],
63
+ 50: [0, -0.0007, -0.0339, -0.1067, -0.1751, -0.2, -0.1606, -0.0241, 0.257, 1],
64
+ 75: [0, -0.0009, -0.0465, -0.1519, -0.2694, -0.3401, -0.3406, -0.2407, 0.0263, 1],
65
+ 100: [0, -0.0011, -0.0534, -0.1785, -0.334, -0.4539, -0.4997, -0.4487, -0.219, 1],
66
+ },
67
+ accelerateElastic: {
68
+ 0: [0, -0.0002, -0.0099, -0.0461, -0.0894, -0.1, -0.0763, 0.0101, 0.2036, 1],
69
+ 25: [0, -0.0002, -0.0131, -0.0685, -0.1363, -0.15, -0.1252, -0.0349, 0.1674, 1],
70
+ 50: [0, -0.0002, -0.0154, -0.0901, -0.1842, -0.2, -0.1741, -0.0799, 0.1312, 1],
71
+ 75: [0, -0.0003, -0.0253, -0.2024, -0.3329, -0.35, -0.3235, -0.2265, -0.0067, 1],
72
+ 100: [0, -0.0004, -0.0338, -0.3722, -0.4837, -0.5, -0.4728, -0.3731, -0.1446, 1],
73
+ },
74
+ elasticSnap: {
75
+ 0: [0, 0.0374, 0.6938, 1.0155, 1.0341, 1.0073, 0.9985, 0.9989, 0.9999, 1.0001],
76
+ 25: [0, 0.0507, 0.868, 1.088, 1.0153, 0.9919, 0.9983, 1.0007, 1.0002, 0.9999],
77
+ 50: [0, 0.0739, 1.0803, 1.0643, 0.9752, 1.0007, 1.0021, 0.9994, 1, 1],
78
+ 75: [0, 0.12, 1.2732, 0.9246, 1.0178, 0.9969, 1.0001, 1.0003, 0.9998, 1],
79
+ 100: [0, 0.2503, 0.9638, 1.0864, 0.9841, 0.9946, 1.0029, 0.9999, 0.9997, 1],
80
+ },
81
+ bounce: {
82
+ 0: [0, 0.0009, 0.0439, 0.1516, 0.3239, 0.5608, 0.8623, 0.9684, 0.9676, 1],
83
+ 25: [0, 0.0017, 0.0844, 0.2911, 0.622, 0.9751, 0.8814, 0.9117, 0.9864, 1],
84
+ 50: [0, 0.0036, 0.1771, 0.611, 0.8779, 0.7497, 0.8819, 0.938, 0.986, 1],
85
+ 75: [0, 0.0064, 0.3154, 0.9503, 0.6454, 0.8041, 0.8754, 0.9817, 0.9842, 1],
86
+ 100: [0, 0.0129, 0.6314, 0.56, 0.7178, 0.7621, 0.9245, 0.9541, 0.9972, 1],
87
+ },
88
+ bounceAnticipate: {
89
+ 0: [0, -0.312, -1.091, -0.25, 0.5362, 0.4344, 0.7219, 0.8843, 0.9941, 1],
90
+ 25: [0, -0.2805, -1.0932, -0.5893, 0.9879, 0.3642, 0.9834, 0.9, 0.9737, 1],
91
+ 50: [0, -0.2551, -1.0782, -0.8111, 0.3954, 0.505, 0.656, 0.8284, 0.9509, 1],
92
+ 75: [0, -0.2365, -1.0652, -0.9626, -0.0309, 0.7255, 0.5385, 0.9146, 0.9754, 1],
93
+ 100: [0, -0.2429, -1.1621, -1.1587, -0.2326, 0.7471, 0.4442, 0.9706, 0.9749, 1],
94
+ },
95
+ bounceThrow: {
96
+ 0: [0, 0.1176, 0.7764, 0.4171, 0.9877, 0.7378, 0.861, 0.9301, 0.9892, 1],
97
+ 25: [0, 0.1708, 0.7334, 0.3524, 0.5552, 0.8521, 0.8234, 0.9149, 0.9755, 1],
98
+ 50: [0, 0.2061, 0.7171, 0.3341, 0.3456, 0.7518, 0.842, 0.9146, 0.9687, 1],
99
+ 75: [0, 0.2215, 0.7562, 0.4077, 0.3207, 0.4954, 0.9317, 0.8906, 0.9953, 1],
100
+ 100: [0, 0.2124, 0.8436, 0.5714, 0.4552, 0.4949, 0.6907, 0.9883, 0.9576, 1],
101
+ },
102
+ impulseSlow: {
103
+ 0: [0, -0.0021, -0.0445, 0.0225, 0.3076, 0.5975, 0.7948, 0.9142, 0.9775, 1],
104
+ 25: [0, -0.0026, -0.0744, -0.1182, 0.1306, 0.5103, 0.7603, 0.9025, 0.9749, 1],
105
+ 50: [0, -0.0023, -0.0801, -0.1858, -0.0939, 0.3794, 0.7124, 0.8868, 0.9714, 1],
106
+ 75: [0, -0.003, -0.1348, -0.4006, -0.5995, -0.1034, 0.5564, 0.8363, 0.9601, 1],
107
+ 100: [0, -0.0024, -0.1252, -0.4364, -0.8436, -0.9544, 0.2787, 0.7605, 0.944, 1],
108
+ },
109
+ impulseOvershoot: {
110
+ 0: [0, -0.0036, -0.0922, -0.0004, 0.5079, 0.9071, 1.0402, 1.0393, 1.0103, 1],
111
+ 25: [0, -0.0046, -0.1285, -0.0668, 0.5603, 0.9749, 1.074, 1.0485, 1.0124, 1],
112
+ 50: [0, -0.0052, -0.1579, -0.136, 0.6332, 1.0386, 1.0987, 1.0533, 1.0135, 1],
113
+ 75: [0, -0.0113, -0.3777, -0.5814, 0.7836, 1.2858, 1.2451, 1.1111, 1.0287, 1],
114
+ 100: [0, -0.0142, -0.4997, -0.9951, 1.1135, 1.4876, 1.3082, 1.135, 1.0358, 1],
115
+ },
116
+ overshoot: {
117
+ 0: [0, 0.1632, 0.6829, 0.9265, 1.0324, 1.0477, 1.0265, 1.0105, 1.0026, 1],
118
+ 25: [0, 0.2168, 0.8435, 1.0785, 1.1234, 1.0823, 1.0407, 1.0165, 1.0042, 1],
119
+ 50: [0, 0.3067, 1.0551, 1.1997, 1.1519, 1.0857, 1.0427, 1.0176, 1.0046, 1],
120
+ 75: [0, 0.4862, 1.5158, 1.5525, 1.348, 1.1958, 1.1, 1.0422, 1.0112, 1],
121
+ 100: [0, 0.7533, 1.9953, 1.7321, 1.4428, 1.2546, 1.1327, 1.0569, 1.0153, 1],
122
+ },
123
+ overshootElastic: {
124
+ 0: [0, 0.0025, 0.1678, 0.685, 1.0242, 1.1, 1.0862, 1.0468, 1.0125, 1],
125
+ 25: [0, 0.0018, 0.1352, 0.7495, 1.0889, 1.15, 1.1342, 1.0692, 1.0148, 1],
126
+ 50: [0, 0.0014, 0.1068, 0.831, 1.1504, 1.2, 1.1842, 1.0901, 1.0154, 1],
127
+ 75: [0, 0.0014, 0.1046, 0.9685, 1.3005, 1.35, 1.3261, 1.155, 1.0239, 1],
128
+ 100: [0, 0.0013, 0.1014, 1.1166, 1.4511, 1.5, 1.4704, 1.2162, 1.0302, 1],
129
+ },
130
+ overshootBouncy: {
131
+ 0: [0, 0.001, 0.0631, 0.3011, 0.9441, 1.2, 1.1389, 1.0614, 1.0162, 1],
132
+ 25: [0, 0.001, 0.0606, 0.2711, 0.8628, 1.35, 1.22, 1.0928, 1.0242, 1],
133
+ 50: [0, 0.001, 0.0582, 0.249, 0.7417, 1.5, 1.2803, 1.115, 1.0298, 1],
134
+ 75: [0, 0.001, 0.0585, 0.2461, 0.7133, 1.7, 1.3355, 1.1298, 1.0326, 1],
135
+ 100: [0, 0.001, 0.0584, 0.2421, 0.6823, 1.9, 1.3601, 1.135, 1.0335, 1],
136
+ },
137
+ }
138
+
139
+ const ALL_SAMPLES: Record<string, Record<Intensity, number[]>> = {
140
+ naturalThrow: naturalThrowSamples,
141
+ decelerateOvershoot: decelerateOvershootSamples,
142
+ decelerateElastic: decelerateElasticSamples,
143
+ accelerateImpulse: accelerateImpulseSamples,
144
+ accelerateElastic: accelerateElasticSamples,
145
+ elasticSnap: elasticSnapSamples,
146
+ bounce: bounceSamples,
147
+ bounceAnticipate: bounceAnticipateSamples,
148
+ bounceThrow: bounceThrowSamples,
149
+ impulseSlow: impulseSlowSamples,
150
+ impulseOvershoot: impulseOvershootSamples,
151
+ overshoot: overshootSamples,
152
+ overshootElastic: overshootElasticSamples,
153
+ overshootBouncy: overshootBouncySamples,
154
+ }
155
+
156
+ const INTENSITIES = [0, 25, 50, 75, 100] as const
157
+
158
+ describe('generated samples match the original Jitter-extracted values', () => {
159
+ for (const [name, golden] of Object.entries(GOLDEN)) {
160
+ test(name, () => {
161
+ const samples = ALL_SAMPLES[name]!
162
+ for (const intensity of INTENSITIES) {
163
+ const actual = SPOT_INDICES.map((i) => samples[intensity][i])
164
+ expect(actual, `${name}[${intensity}]`).toEqual(golden[intensity])
165
+ }
166
+ })
167
+ }
168
+ })
169
+
170
+ describe('structural invariants', () => {
171
+ test('every curve has 51 samples and starts at 0', () => {
172
+ for (const samples of Object.values(ALL_SAMPLES)) {
173
+ for (const intensity of INTENSITIES) {
174
+ expect(samples[intensity]).toHaveLength(51)
175
+ expect(samples[intensity][0]).toBe(0)
176
+ }
177
+ }
178
+ })
179
+
180
+ test('path-based curves end exactly at 1', () => {
181
+ // elasticSnap is physics-based and may settle at e.g. 1.0001 or 0.9999.
182
+ const { elasticSnap: _elasticSnap, ...pathAndBounce } = ALL_SAMPLES
183
+ for (const samples of Object.values(pathAndBounce)) {
184
+ for (const intensity of INTENSITIES) {
185
+ expect(samples[intensity][50]).toBe(1)
186
+ }
187
+ }
188
+ })
189
+ })
190
+
191
+ describe('cubicBezier', () => {
192
+ test('is identity for linear control points', () => {
193
+ const linear = cubicBezier(0.25, 0.25, 0.75, 0.75)
194
+ expect(linear(0.3)).toBe(0.3)
195
+ })
196
+
197
+ test('matches known css ease-like curve endpoints', () => {
198
+ const ease = cubicBezier(0.5, 0, 0, 1)
199
+ expect(ease(0)).toBe(0)
200
+ expect(ease(1)).toBe(1)
201
+ expect(ease(0.5)).toBeGreaterThan(0.5)
202
+ })
203
+
204
+ test('throws on x control points outside [0, 1]', () => {
205
+ expect(() => cubicBezier(-0.1, 0, 0.5, 1)).toThrow()
206
+ expect(() => cubicBezier(0, 0, 1.5, 1)).toThrow()
207
+ })
208
+ })
209
+
210
+ describe('polybezier', () => {
211
+ test('returns anchor y exactly when x hits an anchor', () => {
212
+ const curve = polybezier([
213
+ { x: 0, y: 0, upper: 0 },
214
+ { x: 0.5, y: 1.2, lower: 0.8, upper: 0.2 },
215
+ { x: 1, y: 1, lower: 0.7 },
216
+ ])
217
+ expect(curve(0)).toBe(0)
218
+ expect(curve(0.5)).toBe(1.2)
219
+ expect(curve(1)).toBe(1)
220
+ })
221
+ })
222
+
223
+ describe('lerpSamples', () => {
224
+ test('interpolates linearly between samples and clamps', () => {
225
+ const samples = [0, 1, 0.5]
226
+ expect(lerpSamples(samples, 0)).toBe(0)
227
+ expect(lerpSamples(samples, 0.25)).toBe(0.5)
228
+ expect(lerpSamples(samples, 1)).toBe(0.5)
229
+ expect(lerpSamples(samples, -1)).toBe(0)
230
+ expect(lerpSamples(samples, 2)).toBe(0.5)
231
+ })
232
+ })