@classytic/labs 0.1.0 → 0.2.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 (455) hide show
  1. package/dist/_virtual/_rolldown/runtime.mjs +18 -0
  2. package/dist/biology/enzyme-rate/preset.mjs +5 -5
  3. package/dist/biology/genetic-cross/core.d.mts +7 -7
  4. package/dist/biology/genetic-cross/core.mjs +4 -4
  5. package/dist/biology/genetic-cross/grid.mjs +132 -123
  6. package/dist/biology/genetic-cross/preset.mjs +4 -4
  7. package/dist/biology/genetic-cross/sex-linked.mjs +7 -7
  8. package/dist/biology/photosynthesis-factors/preset.mjs +8 -8
  9. package/dist/biology/respiration/preset.mjs +4 -4
  10. package/dist/biology/sequence/central-dogma.mjs +5 -5
  11. package/dist/biology/sequence/core.d.mts +6 -6
  12. package/dist/biology/sequence/core.mjs +1 -1
  13. package/dist/biology/sequence/preset.mjs +6 -6
  14. package/dist/blocks/authoring.mjs +5 -5
  15. package/dist/blocks/biology.d.mts +2 -2
  16. package/dist/blocks/biology.mjs +5 -5
  17. package/dist/blocks/chem.d.mts +2 -2
  18. package/dist/blocks/chem.mjs +13 -13
  19. package/dist/blocks/circuits.d.mts +293 -4
  20. package/dist/blocks/circuits.mjs +874 -9
  21. package/dist/blocks/discrete.d.mts +30 -2
  22. package/dist/blocks/discrete.mjs +74 -4
  23. package/dist/blocks/economics.mjs +1 -1
  24. package/dist/blocks/geography.mjs +1 -1
  25. package/dist/blocks/geometry.mjs +3 -3
  26. package/dist/blocks/ict.d.mts +90 -1
  27. package/dist/blocks/ict.mjs +217 -7
  28. package/dist/blocks/index.d.mts +3064 -657
  29. package/dist/blocks/index.mjs +9 -9
  30. package/dist/blocks/lab-block.mjs +5 -5
  31. package/dist/blocks/lab-config.d.mts +1 -1
  32. package/dist/blocks/lab-config.mjs +4 -4
  33. package/dist/blocks/lab-gallery.d.mts +1 -1
  34. package/dist/blocks/lab-gallery.mjs +2 -2
  35. package/dist/blocks/language.d.mts +6 -6
  36. package/dist/blocks/language.mjs +12 -12
  37. package/dist/blocks/lesson.mjs +4 -4
  38. package/dist/blocks/math.d.mts +577 -11
  39. package/dist/blocks/math.mjs +1648 -14
  40. package/dist/blocks/ml.d.mts +45 -1
  41. package/dist/blocks/ml.mjs +80 -6
  42. package/dist/blocks/physics.d.mts +9 -4
  43. package/dist/blocks/physics.mjs +75 -28
  44. package/dist/blocks/statistics.mjs +1 -1
  45. package/dist/build/CircuitEditor.d.mts +14 -0
  46. package/dist/build/CircuitEditor.mjs +787 -0
  47. package/dist/build/CircuitPlayer.d.mts +19 -0
  48. package/dist/build/CircuitPlayer.mjs +53 -0
  49. package/dist/build/CircuitScene.d.mts +61 -0
  50. package/dist/build/CircuitScene.mjs +383 -0
  51. package/dist/build/contract.d.mts +116 -0
  52. package/dist/build/editor-ops.d.mts +65 -0
  53. package/dist/build/editor-ops.mjs +306 -0
  54. package/dist/build/editor-ui.mjs +121 -0
  55. package/dist/build/flow.d.mts +14 -0
  56. package/dist/build/flow.mjs +119 -0
  57. package/dist/build/index.d.mts +10 -0
  58. package/dist/build/index.mjs +10 -0
  59. package/dist/build/parts/ammeter.d.mts +1 -0
  60. package/dist/build/parts/ammeter.mjs +32 -0
  61. package/dist/build/parts/bulb.d.mts +1 -0
  62. package/dist/build/parts/bulb.mjs +50 -0
  63. package/dist/build/parts/capacitor.d.mts +1 -0
  64. package/dist/build/parts/capacitor.mjs +26 -0
  65. package/dist/build/parts/cell.d.mts +1 -0
  66. package/dist/build/parts/cell.mjs +40 -0
  67. package/dist/build/parts/diode.d.mts +1 -0
  68. package/dist/build/parts/diode.mjs +33 -0
  69. package/dist/build/parts/index.d.mts +5 -0
  70. package/dist/build/parts/index.mjs +43 -0
  71. package/dist/build/parts/mosfet.d.mts +1 -0
  72. package/dist/build/parts/mosfet.mjs +95 -0
  73. package/dist/build/parts/node.d.mts +1 -0
  74. package/dist/build/parts/node.mjs +32 -0
  75. package/dist/build/parts/resistor.d.mts +1 -0
  76. package/dist/build/parts/resistor.mjs +49 -0
  77. package/dist/build/parts/shared.mjs +42 -0
  78. package/dist/build/parts/switch.d.mts +1 -0
  79. package/dist/build/parts/switch.mjs +34 -0
  80. package/dist/build/parts.d.mts +1 -0
  81. package/dist/build/registry.d.mts +9 -0
  82. package/dist/build/registry.mjs +15 -0
  83. package/dist/build/solve.d.mts +8 -0
  84. package/dist/build/solve.mjs +0 -0
  85. package/dist/catalog/registry.d.mts +2 -2
  86. package/dist/catalog/templates.d.mts +1 -1
  87. package/dist/catalog/templates.mjs +6 -6
  88. package/dist/chem/battery.mjs +1 -1
  89. package/dist/chem/bohr-atom.mjs +4 -4
  90. package/dist/chem/diffusion/preset.mjs +4 -4
  91. package/dist/chem/electrochem/preset.mjs +5 -5
  92. package/dist/chem/equilibrium/preset.d.mts +1 -1
  93. package/dist/chem/equilibrium/preset.mjs +6 -6
  94. package/dist/chem/gas-box/preset.mjs +6 -6
  95. package/dist/chem/kinetics/preset.mjs +6 -6
  96. package/dist/chem/periodic-trends/preset.mjs +7 -7
  97. package/dist/chem/reaction-lab.mjs +3 -3
  98. package/dist/chem/reaction-profile.mjs +4 -4
  99. package/dist/chem/solution/dilution.mjs +6 -6
  100. package/dist/chem/solution/field.d.mts +2 -2
  101. package/dist/chem/solution/field.mjs +2 -2
  102. package/dist/chem/solution/solution-box.mjs +7 -7
  103. package/dist/chem/stoichiometry/preset.mjs +5 -5
  104. package/dist/chem/titration/preset.mjs +5 -5
  105. package/dist/circuits/ac-dc/asset.mjs +1 -1
  106. package/dist/circuits/ac-dc/preset.mjs +2 -2
  107. package/dist/circuits/brownout/index.d.mts +1 -0
  108. package/dist/circuits/brownout/preset.d.mts +22 -0
  109. package/dist/circuits/brownout/preset.mjs +399 -0
  110. package/dist/circuits/capacitor-leak/preset.mjs +13 -8
  111. package/dist/circuits/circuit/asset.mjs +71 -14
  112. package/dist/circuits/circuit/preset.mjs +23 -5
  113. package/dist/circuits/circuit-builder.mjs +60 -132
  114. package/dist/circuits/circuit-lab.mjs +60 -40
  115. package/dist/circuits/cmos-gate/index.d.mts +1 -0
  116. package/dist/circuits/cmos-gate/preset.d.mts +75 -0
  117. package/dist/circuits/cmos-gate/preset.mjs +1491 -0
  118. package/dist/circuits/diode/index.d.mts +1 -0
  119. package/dist/circuits/diode/preset.d.mts +25 -0
  120. package/dist/circuits/diode/preset.mjs +266 -0
  121. package/dist/circuits/index.d.mts +7 -1
  122. package/dist/circuits/index.mjs +7 -1
  123. package/dist/circuits/rc-charging/index.d.mts +1 -0
  124. package/dist/circuits/rc-charging/preset.d.mts +27 -0
  125. package/dist/circuits/rc-charging/preset.mjs +329 -0
  126. package/dist/circuits/semiconductor/index.d.mts +1 -0
  127. package/dist/circuits/semiconductor/preset.d.mts +102 -0
  128. package/dist/circuits/semiconductor/preset.mjs +1855 -0
  129. package/dist/circuits/transistor/index.d.mts +1 -0
  130. package/dist/circuits/transistor/preset.d.mts +27 -0
  131. package/dist/circuits/transistor/preset.mjs +329 -0
  132. package/dist/commerce/accounting/core.d.mts +1 -1
  133. package/dist/commerce/accounting/equation-balance.mjs +5 -5
  134. package/dist/commerce/accounting/journal-poster.mjs +8 -8
  135. package/dist/commerce/accounting/statement-sorter.mjs +4 -4
  136. package/dist/commerce/economics/core.d.mts +2 -2
  137. package/dist/commerce/economics/core.mjs +1 -1
  138. package/dist/commerce/economics/demand-shift-vs-move.mjs +6 -6
  139. package/dist/commerce/economics/elasticity-revenue.mjs +6 -6
  140. package/dist/commerce/economics/market-equilibrium.mjs +5 -5
  141. package/dist/core/easing.d.mts +3 -3
  142. package/dist/core/easing.mjs +2 -2
  143. package/dist/core/numeric.d.mts +3 -3
  144. package/dist/core/numeric.mjs +2 -2
  145. package/dist/core/reactive.d.mts +1 -1
  146. package/dist/core/reactive.mjs +1 -1
  147. package/dist/core/rng.d.mts +2 -2
  148. package/dist/core/rng.mjs +1 -1
  149. package/dist/core/tex.mjs +2 -2
  150. package/dist/core/timeline.d.mts +1 -1
  151. package/dist/core/timeline.mjs +1 -1
  152. package/dist/core/util.mjs +11 -1
  153. package/dist/discrete/arrangements/preset.mjs +6 -14
  154. package/dist/discrete/bayes/preset.mjs +43 -35
  155. package/dist/discrete/binomial/preset.mjs +2 -2
  156. package/dist/discrete/combination-studio/figure.d.mts +6 -0
  157. package/dist/discrete/combination-studio/figure.mjs +159 -0
  158. package/dist/discrete/combination-studio/index.d.mts +2 -0
  159. package/dist/discrete/combination-studio/preset.d.mts +44 -0
  160. package/dist/discrete/combination-studio/preset.mjs +440 -0
  161. package/dist/discrete/core/combinatorics.d.mts +23 -3
  162. package/dist/discrete/core/combinatorics.mjs +38 -3
  163. package/dist/discrete/core/pigeonhole.d.mts +1 -1
  164. package/dist/discrete/core/pigeonhole.mjs +1 -1
  165. package/dist/discrete/core/probability.d.mts +3 -3
  166. package/dist/discrete/core/probability.mjs +3 -3
  167. package/dist/discrete/core/sets.d.mts +1 -1
  168. package/dist/discrete/counting-slots/preset.mjs +8 -8
  169. package/dist/discrete/counting-tree/preset.mjs +65 -8
  170. package/dist/discrete/expected-value/preset.mjs +13 -13
  171. package/dist/discrete/hypergeometric/preset.mjs +48 -15
  172. package/dist/discrete/index.d.mts +4 -2
  173. package/dist/discrete/index.mjs +4 -2
  174. package/dist/discrete/karnaugh/preset.mjs +26 -20
  175. package/dist/discrete/lln/preset.mjs +44 -3
  176. package/dist/discrete/logic-circuit/preset.mjs +2 -2
  177. package/dist/discrete/monte-carlo/preset.d.mts +1 -1
  178. package/dist/discrete/monte-carlo/preset.mjs +14 -14
  179. package/dist/discrete/monty-hall/preset.mjs +6 -6
  180. package/dist/discrete/outcome-builder/preset.mjs +3 -3
  181. package/dist/discrete/pascal/preset.mjs +37 -7
  182. package/dist/discrete/rules.d.mts +20 -0
  183. package/dist/discrete/rules.mjs +264 -0
  184. package/dist/discrete/sample-space/preset.mjs +4 -4
  185. package/dist/discrete/selection/preset.mjs +7 -13
  186. package/dist/discrete/truth-table/preset.mjs +32 -9
  187. package/dist/discrete/venn/preset.mjs +71 -48
  188. package/dist/geography/cycle-lab/preset.mjs +17 -10
  189. package/dist/geography/cycles.d.mts +3 -3
  190. package/dist/geography/cycles.mjs +3 -3
  191. package/dist/geometry/board/preset.d.mts +2 -0
  192. package/dist/geometry/board/preset.mjs +11 -15
  193. package/dist/geometry/builder.mjs +3 -3
  194. package/dist/ict/number-systems/base-odometer.mjs +4 -4
  195. package/dist/ict/number-systems/bit-grouper.d.mts +1 -1
  196. package/dist/ict/number-systems/bit-grouper.mjs +4 -4
  197. package/dist/ict/number-systems/place-value-dial.d.mts +1 -1
  198. package/dist/ict/number-systems/place-value-dial.mjs +3 -3
  199. package/dist/ict/number-systems/wheel.d.mts +3 -3
  200. package/dist/ict/number-systems/wheel.mjs +4 -4
  201. package/dist/kit/annotate.mjs +3 -3
  202. package/dist/kit/answer-check.d.mts +2 -2
  203. package/dist/kit/answer-check.mjs +34 -6
  204. package/dist/kit/ask.d.mts +19 -0
  205. package/dist/kit/ask.mjs +46 -0
  206. package/dist/kit/bar-strip.mjs +53 -0
  207. package/dist/kit/calc.d.mts +33 -0
  208. package/dist/kit/calc.mjs +27 -0
  209. package/dist/kit/carrier-engine.mjs +147 -0
  210. package/dist/kit/clue-scene.d.mts +86 -0
  211. package/dist/kit/clue-scene.mjs +424 -0
  212. package/dist/kit/cluster.d.mts +30 -0
  213. package/dist/kit/cluster.mjs +81 -0
  214. package/dist/kit/controls.mjs +11 -5
  215. package/dist/kit/coords.d.mts +88 -0
  216. package/dist/kit/coords.mjs +192 -0
  217. package/dist/kit/data-scene.d.mts +27 -0
  218. package/dist/kit/data-scene.mjs +199 -0
  219. package/dist/kit/diagram.mjs +111 -50
  220. package/dist/kit/electronics.mjs +552 -60
  221. package/dist/kit/expr-analysis.d.mts +18 -6
  222. package/dist/kit/expr-analysis.mjs +82 -28
  223. package/dist/kit/frame.d.mts +3 -3
  224. package/dist/kit/frame.mjs +25 -6
  225. package/dist/kit/gameshow.mjs +2 -2
  226. package/dist/kit/index.d.mts +14 -2
  227. package/dist/kit/index.mjs +13 -1
  228. package/dist/kit/logic-gates.mjs +246 -47
  229. package/dist/kit/palette.mjs +26 -0
  230. package/dist/kit/pedagogy.d.mts +4 -4
  231. package/dist/kit/pedagogy.mjs +21 -17
  232. package/dist/kit/play.d.mts +1 -1
  233. package/dist/kit/play.mjs +3 -3
  234. package/dist/kit/predict.d.mts +55 -0
  235. package/dist/kit/predict.mjs +146 -0
  236. package/dist/kit/receipt.d.mts +29 -0
  237. package/dist/kit/receipt.mjs +94 -0
  238. package/dist/kit/rich.mjs +2 -2
  239. package/dist/kit/rule.d.mts +59 -0
  240. package/dist/kit/rule.mjs +215 -0
  241. package/dist/kit/scale.mjs +1 -1
  242. package/dist/kit/scene-library.d.mts +22 -0
  243. package/dist/kit/scene-library.mjs +311 -0
  244. package/dist/kit/scene-studio.d.mts +14 -0
  245. package/dist/kit/scene-studio.mjs +338 -0
  246. package/dist/kit/scenes.d.mts +31 -0
  247. package/dist/kit/scenes.mjs +569 -0
  248. package/dist/kit/slot-fill.d.mts +61 -0
  249. package/dist/kit/slot-fill.mjs +207 -0
  250. package/dist/kit/solve.d.mts +21 -0
  251. package/dist/kit/solve.mjs +75 -0
  252. package/dist/kit/space.mjs +5 -5
  253. package/dist/kit/steps.mjs +2 -2
  254. package/dist/kit/vessel.d.mts +69 -0
  255. package/dist/kit/vessel.mjs +191 -0
  256. package/dist/language/agreement/preset.mjs +2 -2
  257. package/dist/language/article-lens/preset.d.mts +1 -1
  258. package/dist/language/article-lens/preset.mjs +8 -8
  259. package/dist/language/deck.d.mts +3 -3
  260. package/dist/language/deck.mjs +1 -1
  261. package/dist/language/preposition-scene/preset.d.mts +2 -2
  262. package/dist/language/preposition-scene/preset.mjs +5 -5
  263. package/dist/language/sentence-builder/preset.mjs +5 -5
  264. package/dist/language/transform/preset.d.mts +2 -2
  265. package/dist/language/transform/preset.mjs +5 -5
  266. package/dist/language/ui.d.mts +3 -3
  267. package/dist/language/ui.mjs +4 -4
  268. package/dist/language/word-match/preset.mjs +3 -3
  269. package/dist/logic/LogicBuildLab.d.mts +22 -0
  270. package/dist/logic/LogicBuildLab.mjs +170 -0
  271. package/dist/logic/LogicEditScene.d.mts +31 -0
  272. package/dist/logic/LogicEditScene.mjs +276 -0
  273. package/dist/logic/LogicEditor.d.mts +14 -0
  274. package/dist/logic/LogicEditor.mjs +413 -0
  275. package/dist/logic/LogicScene.d.mts +32 -0
  276. package/dist/logic/LogicScene.mjs +277 -0
  277. package/dist/logic/contract.d.mts +72 -0
  278. package/dist/logic/display.d.mts +24 -0
  279. package/dist/logic/display.mjs +127 -0
  280. package/dist/logic/edit-ops.d.mts +44 -0
  281. package/dist/logic/edit-ops.mjs +177 -0
  282. package/dist/logic/evaluate.d.mts +11 -0
  283. package/dist/logic/evaluate.mjs +93 -0
  284. package/dist/logic/gates.d.mts +10 -0
  285. package/dist/logic/gates.mjs +73 -0
  286. package/dist/logic/index.d.mts +14 -0
  287. package/dist/logic/index.mjs +13 -0
  288. package/dist/logic/lab.d.mts +32 -0
  289. package/dist/logic/lab.mjs +160 -0
  290. package/dist/logic/presets.d.mts +12 -0
  291. package/dist/logic/presets.mjs +241 -0
  292. package/dist/logic/registry.d.mts +9 -0
  293. package/dist/logic/registry.mjs +15 -0
  294. package/dist/math/area-model/preset.mjs +70 -44
  295. package/dist/math/balance-algebra/preset.mjs +14 -5
  296. package/dist/math/broken-tree/index.d.mts +1 -0
  297. package/dist/math/broken-tree/preset.d.mts +26 -0
  298. package/dist/math/broken-tree/preset.mjs +435 -0
  299. package/dist/math/circle/index.d.mts +1 -0
  300. package/dist/math/circle/preset.d.mts +44 -0
  301. package/dist/math/circle/preset.mjs +198 -0
  302. package/dist/math/complex/core.d.mts +93 -0
  303. package/dist/math/complex/core.mjs +239 -0
  304. package/dist/math/complex/index.d.mts +3 -0
  305. package/dist/math/complex/preset.d.mts +31 -0
  306. package/dist/math/complex/preset.mjs +377 -0
  307. package/dist/math/complex/rules.d.mts +6 -0
  308. package/dist/math/complex/rules.mjs +121 -0
  309. package/dist/math/conic/index.d.mts +1 -0
  310. package/dist/math/conic/preset.d.mts +30 -0
  311. package/dist/math/conic/preset.mjs +334 -0
  312. package/dist/math/derivation.mjs +5 -5
  313. package/dist/math/derivative-explorer/preset.mjs +5 -5
  314. package/dist/math/domain-range/index.d.mts +1 -0
  315. package/dist/math/domain-range/preset.d.mts +33 -0
  316. package/dist/math/domain-range/preset.mjs +313 -0
  317. package/dist/math/fraction-bar/index.d.mts +1 -0
  318. package/dist/math/fraction-bar/preset.d.mts +27 -0
  319. package/dist/math/fraction-bar/preset.mjs +197 -0
  320. package/dist/math/function-machine/preset.mjs +2 -2
  321. package/dist/math/gradient-descent.mjs +6 -6
  322. package/dist/math/grapher/preset.d.mts +1 -1
  323. package/dist/math/grapher/preset.mjs +4 -4
  324. package/dist/math/harmonic-form/preset.mjs +6 -6
  325. package/dist/math/index.d.mts +27 -2
  326. package/dist/math/index.mjs +27 -2
  327. package/dist/math/integral-explorer/preset.mjs +2 -2
  328. package/dist/math/interactive/preset.mjs +3 -3
  329. package/dist/math/limit-explorer/preset.mjs +4 -4
  330. package/dist/math/linear-model/index.d.mts +1 -0
  331. package/dist/math/linear-model/preset.d.mts +53 -0
  332. package/dist/math/linear-model/preset.mjs +164 -0
  333. package/dist/math/linear-system/preset.mjs +4 -4
  334. package/dist/math/mystery-bucket/preset.mjs +6 -6
  335. package/dist/math/number-line/preset.mjs +3 -2
  336. package/dist/math/parabola/preset.mjs +4 -3
  337. package/dist/math/pattern/preset.mjs +7 -13
  338. package/dist/math/percent-bar/index.d.mts +1 -0
  339. package/dist/math/percent-bar/preset.d.mts +37 -0
  340. package/dist/math/percent-bar/preset.mjs +275 -0
  341. package/dist/math/poly/core.d.mts +50 -0
  342. package/dist/math/poly/core.mjs +268 -0
  343. package/dist/math/poly/index.d.mts +3 -0
  344. package/dist/math/poly/preset.d.mts +23 -0
  345. package/dist/math/poly/preset.mjs +141 -0
  346. package/dist/math/poly/steps.d.mts +10 -0
  347. package/dist/math/poly/steps.mjs +99 -0
  348. package/dist/math/rate-machine/index.d.mts +1 -0
  349. package/dist/math/rate-machine/preset.d.mts +35 -0
  350. package/dist/math/rate-machine/preset.mjs +281 -0
  351. package/dist/math/ratio-share/index.d.mts +1 -0
  352. package/dist/math/ratio-share/preset.d.mts +24 -0
  353. package/dist/math/ratio-share/preset.mjs +204 -0
  354. package/dist/math/receipt/index.d.mts +1 -0
  355. package/dist/math/receipt/preset.d.mts +22 -0
  356. package/dist/math/receipt/preset.mjs +137 -0
  357. package/dist/math/sequence-predict/index.d.mts +1 -0
  358. package/dist/math/sequence-predict/preset.d.mts +34 -0
  359. package/dist/math/sequence-predict/preset.mjs +130 -0
  360. package/dist/math/straight-line/index.d.mts +1 -0
  361. package/dist/math/straight-line/preset.d.mts +37 -0
  362. package/dist/math/straight-line/preset.mjs +374 -0
  363. package/dist/math/system-solve/index.d.mts +1 -0
  364. package/dist/math/system-solve/preset.d.mts +21 -0
  365. package/dist/math/system-solve/preset.mjs +227 -0
  366. package/dist/math/transform/index.d.mts +1 -0
  367. package/dist/math/transform/preset.d.mts +41 -0
  368. package/dist/math/transform/preset.mjs +343 -0
  369. package/dist/math/triangle-trig/preset.mjs +12 -9
  370. package/dist/math/trig/core.d.mts +37 -0
  371. package/dist/math/trig/core.mjs +150 -0
  372. package/dist/math/trig/diagrams.d.mts +1 -0
  373. package/dist/math/trig/diagrams.mjs +321 -0
  374. package/dist/math/trig/index.d.mts +3 -0
  375. package/dist/math/trig/preset.d.mts +25 -0
  376. package/dist/math/trig/preset.mjs +260 -0
  377. package/dist/math/trig/rules.d.mts +6 -0
  378. package/dist/math/trig/rules.mjs +159 -0
  379. package/dist/math/trig-explorer.mjs +4 -4
  380. package/dist/ml/boundary/preset.mjs +8 -3
  381. package/dist/ml/classifier/preset.mjs +31 -6
  382. package/dist/ml/kmeans/preset.mjs +4 -4
  383. package/dist/ml/knn/preset.mjs +47 -12
  384. package/dist/ml/regression/preset.mjs +36 -7
  385. package/dist/physics/atwood/preset.mjs +4 -4
  386. package/dist/physics/bullet-walls/preset.d.mts +1 -1
  387. package/dist/physics/bullet-walls/preset.mjs +7 -7
  388. package/dist/physics/carnot/preset.mjs +6 -6
  389. package/dist/physics/circular-motion/preset.mjs +36 -5
  390. package/dist/physics/collision-track/preset.mjs +35 -5
  391. package/dist/physics/efficiency/preset.d.mts +2 -2
  392. package/dist/physics/efficiency/preset.mjs +5 -5
  393. package/dist/physics/electric-field/preset.mjs +32 -23
  394. package/dist/physics/electric-flux/index.d.mts +1 -0
  395. package/dist/physics/electric-flux/preset.d.mts +29 -0
  396. package/dist/physics/electric-flux/preset.mjs +264 -0
  397. package/dist/physics/energy-skate/preset.mjs +5 -5
  398. package/dist/physics/entropy/preset.mjs +7 -7
  399. package/dist/physics/expansion/preset.mjs +13 -13
  400. package/dist/physics/exponential/asset.mjs +1 -1
  401. package/dist/physics/exponential/preset.mjs +4 -4
  402. package/dist/physics/gas-process/preset.mjs +3 -3
  403. package/dist/physics/gauss-law/index.d.mts +1 -0
  404. package/dist/physics/gauss-law/preset.d.mts +20 -0
  405. package/dist/physics/gauss-law/preset.mjs +286 -0
  406. package/dist/physics/gravitation/preset.mjs +7 -7
  407. package/dist/physics/gravity-drop.mjs +4 -4
  408. package/dist/physics/heat-transfer/preset.d.mts +1 -1
  409. package/dist/physics/heat-transfer/preset.mjs +10 -10
  410. package/dist/physics/impulse/preset.mjs +5 -5
  411. package/dist/physics/index.d.mts +4 -1
  412. package/dist/physics/index.mjs +4 -1
  413. package/dist/physics/kepler/preset.mjs +4 -4
  414. package/dist/physics/lever/preset.mjs +3 -3
  415. package/dist/physics/lorentz/preset.mjs +11 -11
  416. package/dist/physics/magnetism/preset.mjs +3 -3
  417. package/dist/physics/optics/preset.mjs +2 -2
  418. package/dist/physics/orbit-lab.mjs +5 -5
  419. package/dist/physics/projectile-lab.mjs +4 -4
  420. package/dist/physics/rain-relative/preset.mjs +5 -5
  421. package/dist/physics/ramp-forces/preset.mjs +5 -5
  422. package/dist/physics/river-boat.mjs +6 -6
  423. package/dist/physics/shm/preset.mjs +9 -9
  424. package/dist/physics/stopping-distance/preset.mjs +3 -3
  425. package/dist/physics/temperature-scales/preset.mjs +105 -116
  426. package/dist/physics/terminal-velocity/preset.mjs +5 -5
  427. package/dist/physics/thermal/preset.mjs +5 -5
  428. package/dist/physics/vector-board/preset.mjs +7 -6
  429. package/dist/physics/vector-scene.mjs +2 -2
  430. package/dist/physics/vector-types/preset.mjs +37 -3
  431. package/dist/physics/water-density/preset.mjs +12 -12
  432. package/dist/physics/waves/doppler.mjs +2 -2
  433. package/dist/physics/waves/preset.mjs +4 -4
  434. package/dist/physics/waves/ripple.mjs +6 -6
  435. package/dist/physics/waves/string.mjs +5 -5
  436. package/dist/physics/work-energy/preset.mjs +4 -4
  437. package/dist/physics/work-potential/index.d.mts +1 -0
  438. package/dist/physics/work-potential/preset.d.mts +20 -0
  439. package/dist/physics/work-potential/preset.mjs +276 -0
  440. package/dist/schemas/index.d.mts +6 -6
  441. package/dist/schemas/index.mjs +3 -3
  442. package/dist/statistics/center-spread/preset.mjs +3 -3
  443. package/dist/statistics/core/descriptive.d.mts +2 -2
  444. package/dist/statistics/core/descriptive.mjs +2 -2
  445. package/dist/statistics/core/normal.d.mts +3 -3
  446. package/dist/statistics/core/normal.mjs +3 -3
  447. package/dist/statistics/core/sequences.d.mts +1 -1
  448. package/dist/statistics/galton/preset.mjs +2 -2
  449. package/dist/statistics/histogram/preset.mjs +6 -6
  450. package/dist/statistics/normal/preset.mjs +2 -2
  451. package/dist/statistics/sampling/preset.mjs +4 -4
  452. package/dist/statistics/sequence/preset.mjs +58 -15
  453. package/dist/statistics/z-table/preset.mjs +17 -4
  454. package/package.json +11 -3
  455. package/styles.css +4 -1
@@ -0,0 +1,343 @@
1
+ 'use client';
2
+
3
+ import { LabFrame } from "../../kit/frame.mjs";
4
+ import { useReducedMotion } from "../../kit/anim.mjs";
5
+ import { CoordPlane } from "../../kit/coords.mjs";
6
+ import { Blank, SlotTray, useSlotFill } from "../../kit/slot-fill.mjs";
7
+ import { useEffect, useState } from "react";
8
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
9
+ import { Circle, Label, Point, Polygon, Polyline, Vector, vec } from "@classytic/stage";
10
+
11
+ //#region src/math/transform/preset.tsx
12
+ /**
13
+ * TransformLab, the geometry-transformation lab that was missing entirely: translate,
14
+ * reflect, rotate, enlarge, one authorable lab switched by `kind` (the same one-lab-many-
15
+ * modes shape as StraightLineLab). The learner reads the move, fills its parameters from a
16
+ * tile tray ("translate by (▢,▢)", "rotate ▢ about O"), and on a correct fill the shape
17
+ * FLIES to the ghost targets, the reward that makes "send the points to the targets" land.
18
+ *
19
+ * Almost no new engine code: the math is stage core (`vec.rotateAbout` / `vec.lerp` + a
20
+ * 6-line applyTf), the drawing is `Polygon`/`Point`/`Circle`/`Vector`, and the answer UI is
21
+ * the shared inline slot engine (`useSlotFill` + `Blank` + `SlotTray`). A creator sets the
22
+ * shape, the transform, and the distractor tiles, no code.
23
+ */
24
+ const C_SRC = "var(--stage-accent)";
25
+ const C_IMG = "var(--stage-good)";
26
+ const C_GHOST = "var(--stage-muted)";
27
+ /** Apply a transform to a point. Pure, all from stage core math. */
28
+ function applyTf(p, t) {
29
+ const o = t.about ?? {
30
+ x: 0,
31
+ y: 0
32
+ };
33
+ switch (t.kind) {
34
+ case "translate": return {
35
+ x: p.x + (t.by?.x ?? 0),
36
+ y: p.y + (t.by?.y ?? 0)
37
+ };
38
+ case "reflect":
39
+ switch (t.axis ?? "y") {
40
+ case "x": return {
41
+ x: p.x,
42
+ y: -p.y
43
+ };
44
+ case "y": return {
45
+ x: -p.x,
46
+ y: p.y
47
+ };
48
+ case "y=x": return {
49
+ x: p.y,
50
+ y: p.x
51
+ };
52
+ case "y=-x": return {
53
+ x: -p.y,
54
+ y: -p.x
55
+ };
56
+ }
57
+ return p;
58
+ case "rotate": return vec.rotateAbout(p, o, (t.deg ?? 0) * Math.PI / 180);
59
+ case "enlarge": return {
60
+ x: o.x + (p.x - o.x) * (t.k ?? 1),
61
+ y: o.y + (p.y - o.y) * (t.k ?? 1)
62
+ };
63
+ }
64
+ }
65
+ const AXIS_LABEL = {
66
+ x: "x-axis",
67
+ y: "y-axis",
68
+ "y=x": "y = x",
69
+ "y=-x": "y = −x"
70
+ };
71
+ const easeOut = (t) => 1 - (1 - t) ** 3;
72
+ const DEFAULTS = {
73
+ translate: {
74
+ kind: "translate",
75
+ by: {
76
+ x: 5,
77
+ y: 1
78
+ }
79
+ },
80
+ reflect: {
81
+ kind: "reflect",
82
+ axis: "y"
83
+ },
84
+ rotate: {
85
+ kind: "rotate",
86
+ deg: 90,
87
+ about: {
88
+ x: 0,
89
+ y: 0
90
+ }
91
+ },
92
+ enlarge: {
93
+ kind: "enlarge",
94
+ k: 2,
95
+ about: {
96
+ x: 0,
97
+ y: 0
98
+ }
99
+ }
100
+ };
101
+ const PROMPTS = {
102
+ translate: "Complete the translation to send the shape onto the targets.",
103
+ reflect: "Pick the mirror line that lands the shape on the targets.",
104
+ rotate: "Pick the turn (about O) that lands the shape on the targets.",
105
+ enlarge: "Pick the scale factor (centre O) that lands the shape on the targets."
106
+ };
107
+ function TransformLab(props = {}) {
108
+ const kind = props.transform?.kind ?? "translate";
109
+ const tf = props.transform ?? DEFAULTS[kind];
110
+ const { shape = [
111
+ {
112
+ x: -4,
113
+ y: 0
114
+ },
115
+ {
116
+ x: -2,
117
+ y: 0
118
+ },
119
+ {
120
+ x: -2,
121
+ y: 2
122
+ }
123
+ ], view = {
124
+ xMin: -6,
125
+ xMax: 6,
126
+ yMin: -4,
127
+ yMax: 6
128
+ }, height = 380, title = "Transformations", prompt = PROMPTS[kind], activity = `transform-${kind}` } = props;
129
+ const targets = shape.map((p) => applyTf(p, tf));
130
+ let slots;
131
+ let tiles;
132
+ if (kind === "translate") {
133
+ const bx = tf.by?.x ?? 0, by = tf.by?.y ?? 0;
134
+ slots = [{
135
+ id: "dx",
136
+ answer: bx
137
+ }, {
138
+ id: "dy",
139
+ answer: by
140
+ }];
141
+ const lo = Math.min(-3, bx - 2, by - 2), hi = Math.max(3, bx + 2, by + 2);
142
+ const pool = new Set([
143
+ bx,
144
+ by,
145
+ ...props.distractors ?? []
146
+ ]);
147
+ for (let v = lo; v <= hi; v++) pool.add(v);
148
+ tiles = [...pool].sort((a, b) => a - b);
149
+ } else if (kind === "reflect") {
150
+ slots = [{
151
+ id: "axis",
152
+ answer: AXIS_LABEL[tf.axis ?? "y"]
153
+ }];
154
+ tiles = [
155
+ "x-axis",
156
+ "y-axis",
157
+ "y = x",
158
+ "y = −x"
159
+ ];
160
+ } else if (kind === "rotate") {
161
+ slots = [{
162
+ id: "deg",
163
+ answer: `${tf.deg ?? 90}°`
164
+ }];
165
+ tiles = [
166
+ "90°",
167
+ "180°",
168
+ "270°"
169
+ ];
170
+ } else {
171
+ const k = tf.k ?? 2;
172
+ slots = [{
173
+ id: "k",
174
+ answer: String(k)
175
+ }];
176
+ tiles = [
177
+ "2",
178
+ "3",
179
+ "4"
180
+ ];
181
+ }
182
+ const reduce = useReducedMotion();
183
+ const [prog, setProg] = useState(0);
184
+ const fill = useSlotFill(slots, tiles, activity);
185
+ const solved = fill.solved;
186
+ useEffect(() => {
187
+ if (!solved) {
188
+ setProg(0);
189
+ return;
190
+ }
191
+ if (reduce) {
192
+ setProg(1);
193
+ return;
194
+ }
195
+ let raf = 0;
196
+ let start = 0;
197
+ const tick = (now) => {
198
+ if (!start) start = now;
199
+ const e = Math.min(1, (now - start) / 700);
200
+ setProg(easeOut(e));
201
+ if (e < 1) raf = requestAnimationFrame(tick);
202
+ };
203
+ raf = requestAnimationFrame(tick);
204
+ return () => cancelAnimationFrame(raf);
205
+ }, [solved, reduce]);
206
+ const current = shape.map((p, i) => vec.lerp(p, targets[i], prog));
207
+ const isPoly = shape.length >= 3;
208
+ const about = tf.about ?? {
209
+ x: 0,
210
+ y: 0
211
+ };
212
+ const figure = /* @__PURE__ */ jsxs(CoordPlane, {
213
+ view,
214
+ height,
215
+ stepX: 1,
216
+ stepY: 1,
217
+ ariaLabel: `${title}: ${kind}`,
218
+ children: [
219
+ isPoly ? /* @__PURE__ */ jsx(Polyline, {
220
+ points: [...targets, targets[0]],
221
+ color: C_GHOST,
222
+ weight: 1.5,
223
+ dashed: true,
224
+ opacity: .7
225
+ }) : null,
226
+ targets.map((t, i) => /* @__PURE__ */ jsx(Circle, {
227
+ center: t,
228
+ r: .26,
229
+ color: C_GHOST,
230
+ weight: 2,
231
+ fill: "none"
232
+ }, `t${i}`)),
233
+ (kind === "rotate" || kind === "enlarge") && /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(Point, {
234
+ x: about.x,
235
+ y: about.y,
236
+ r: 4,
237
+ color: C_GHOST
238
+ }), /* @__PURE__ */ jsx(Label, {
239
+ x: about.x,
240
+ y: about.y,
241
+ text: "O",
242
+ dx: -10,
243
+ dy: -8,
244
+ size: 12,
245
+ color: C_GHOST
246
+ })] }),
247
+ isPoly && /* @__PURE__ */ jsx(Polygon, {
248
+ points: current,
249
+ color: solved ? C_IMG : C_SRC,
250
+ fill: solved ? C_IMG : C_SRC,
251
+ fillOpacity: .18,
252
+ weight: 2.5
253
+ }),
254
+ current.map((p, i) => /* @__PURE__ */ jsx(Point, {
255
+ x: p.x,
256
+ y: p.y,
257
+ r: 6,
258
+ color: solved ? C_IMG : C_SRC
259
+ }, `p${i}`)),
260
+ kind === "translate" && prog < .05 && shape.map((p, i) => /* @__PURE__ */ jsx(Vector, {
261
+ tail: p,
262
+ tip: targets[i],
263
+ color: C_GHOST,
264
+ weight: 1.5,
265
+ opacity: .5
266
+ }, `v${i}`))
267
+ ]
268
+ });
269
+ return /* @__PURE__ */ jsx(LabFrame, {
270
+ title,
271
+ prompt,
272
+ footer: /* @__PURE__ */ jsxs("div", {
273
+ style: {
274
+ display: "grid",
275
+ gap: 12,
276
+ justifyItems: "center",
277
+ marginTop: 4
278
+ },
279
+ children: [
280
+ /* @__PURE__ */ jsxs("span", {
281
+ style: {
282
+ display: "inline-flex",
283
+ alignItems: "center",
284
+ gap: 8,
285
+ flexWrap: "wrap",
286
+ fontWeight: 700,
287
+ fontSize: 16
288
+ },
289
+ children: [
290
+ kind === "translate" && /* @__PURE__ */ jsxs(Fragment$1, { children: [
291
+ "translate by ( ",
292
+ /* @__PURE__ */ jsx(Blank, {
293
+ fill,
294
+ id: "dx"
295
+ }),
296
+ " , ",
297
+ /* @__PURE__ */ jsx(Blank, {
298
+ fill,
299
+ id: "dy"
300
+ }),
301
+ " )"
302
+ ] }),
303
+ kind === "reflect" && /* @__PURE__ */ jsxs(Fragment$1, { children: ["reflect in the ", /* @__PURE__ */ jsx(Blank, {
304
+ fill,
305
+ id: "axis",
306
+ width: 72
307
+ })] }),
308
+ kind === "rotate" && /* @__PURE__ */ jsxs(Fragment$1, { children: [
309
+ "rotate ",
310
+ /* @__PURE__ */ jsx(Blank, {
311
+ fill,
312
+ id: "deg"
313
+ }),
314
+ " anticlockwise about O"
315
+ ] }),
316
+ kind === "enlarge" && /* @__PURE__ */ jsxs(Fragment$1, { children: [
317
+ "enlarge by scale factor ",
318
+ /* @__PURE__ */ jsx(Blank, {
319
+ fill,
320
+ id: "k"
321
+ }),
322
+ " , centre O"
323
+ ] })
324
+ ]
325
+ }),
326
+ /* @__PURE__ */ jsx(SlotTray, { fill }),
327
+ solved && /* @__PURE__ */ jsx("p", {
328
+ role: "status",
329
+ style: {
330
+ margin: 0,
331
+ color: "var(--stage-good)",
332
+ fontWeight: 700
333
+ },
334
+ children: "✓ Landed on the targets."
335
+ })
336
+ ]
337
+ }),
338
+ children: figure
339
+ });
340
+ }
341
+
342
+ //#endregion
343
+ export { TransformLab, applyTf };
@@ -11,22 +11,22 @@ import { Label, Segment, Stage } from "@classytic/stage";
11
11
 
12
12
  //#region src/math/triangle-trig/preset.tsx
13
13
  /**
14
- * TriangleTrig — the first REPRESENTATION plug-in: a thing the graph engine can't
14
+ * TriangleTrig, the first REPRESENTATION plug-in: a thing the graph engine can't
15
15
  * draw (a labelled right triangle), authored by config and reusing the shared
16
- * answer-check seam. Built for the angle-of-elevation/depression family — "from the
16
+ * answer-check seam. Built for the angle-of-elevation/depression family, "from the
17
17
  * top of a 15 m tower the angle of depression to a point is 31°, find the distance"
18
18
  * (the user's "see the angle and the tree/pole distances"). A 2-D split is clearer
19
19
  * (and cheaper) than pseudo-3-D.
20
20
  *
21
21
  * The creator gives an angle + ONE leg; the engine solves the rest (tan/sin/cos),
22
22
  * draws the triangle with every side + the angle labelled, exposes chosen knobs as
23
- * sliders for intuition, and — with `ask` — grades a typed answer via `checkAnswer`.
23
+ * sliders for intuition, and, with `ask`, grades a typed answer via `checkAnswer`.
24
24
  */
25
25
  const C_GIVEN = "var(--stage-accent)";
26
26
  const C_HYP = "var(--stage-accent-2)";
27
27
  const C_CALC = "var(--stage-fg)";
28
- const fmt$1 = (n) => Number.isFinite(n) ? Math.abs(n) >= 100 ? n.toFixed(0) : n.toFixed(2) : "—";
29
- function TriangleTrig({ angleDeg = 31, leg = 15, legKind = "opposite", mode = "depression", labels, drive = ["angle"], legMin = 1, legMax, ask, title = "Angle of depression — solve the right triangle", prompt = "The angle, the height and the ground distance are one right triangle: tan θ = opposite / adjacent.", height = 320, activity = "triangle-trig" } = {}) {
28
+ const fmt$1 = (n) => Number.isFinite(n) ? Math.abs(n) >= 100 ? n.toFixed(0) : n.toFixed(2) : ", ";
29
+ function TriangleTrig({ angleDeg = 31, leg = 15, legKind = "opposite", mode = "depression", labels, drive = ["angle"], legMin = 1, legMax, ask, title = "Angle of depression: solve the right triangle", prompt = "The angle, the height and the ground distance are one right triangle: tan θ = opposite / adjacent.", height = 320, activity = "triangle-trig" } = {}) {
30
30
  const [deg, setDeg] = useState(angleDeg);
31
31
  const [len, setLen] = useState(leg);
32
32
  const lab = {
@@ -71,9 +71,15 @@ function TriangleTrig({ angleDeg = 31, leg = 15, legKind = "opposite", mode = "d
71
71
  text: `${name} = ${fmt$1(value)}`,
72
72
  color,
73
73
  size: 12,
74
+ weight: given ? 700 : 600,
74
75
  dx: off.dx,
75
76
  dy: off.dy
76
77
  });
78
+ const hyLen = H || 1;
79
+ const hypOff = {
80
+ dx: -O / hyLen * 18,
81
+ dy: -A / hyLen * 18
82
+ };
77
83
  const figure = /* @__PURE__ */ jsxs(Stage, {
78
84
  view,
79
85
  height,
@@ -153,10 +159,7 @@ function TriangleTrig({ angleDeg = 31, leg = 15, legKind = "opposite", mode = "d
153
159
  sideLabel({
154
160
  x: A / 2,
155
161
  y: O / 2
156
- }, lab.hypotenuse, H, C_HYP, false, {
157
- dx: -10,
158
- dy: -8
159
- })
162
+ }, lab.hypotenuse, H, C_HYP, false, hypOff)
160
163
  ]
161
164
  });
162
165
  const aside = /* @__PURE__ */ jsx(Callout, {
@@ -0,0 +1,37 @@
1
+ import { toDeg, toRad } from "../../core/util.mjs";
2
+
3
+ //#region src/math/trig/core.d.ts
4
+ declare namespace core_d_exports {
5
+ export { TRIG_FNS, TrigFn, castLetter, castPositive, evalTrig, exactTex, isSpecial, normDeg, quadrant, radTex, referenceAngleDeg, sign, toDeg, toRad };
6
+ }
7
+ type TrigFn = 'sin' | 'cos' | 'tan';
8
+ declare const TRIG_FNS: readonly TrigFn[];
9
+ /** Coterminal angle folded into [0, 360). */
10
+ declare const normDeg: (deg: number) => number;
11
+ /** Numeric value (degrees in). tan where cos = 0 → NaN (undefined), not ±∞. */
12
+ declare function evalTrig(fn: TrigFn, deg: number): number;
13
+ /** Quadrant 1..4 of the terminal ray; 0 when it lies ON an axis (0/90/180/270). */
14
+ declare function quadrant(deg: number): 0 | 1 | 2 | 3 | 4;
15
+ /** Reference angle: the acute angle (0..90°) between the terminal ray and the
16
+ * x-axis — the angle whose exact value you actually look up. */
17
+ declare function referenceAngleDeg(deg: number): number;
18
+ /** Sign of a trig function at an angle: 1, −1, 0, or NaN (undefined). The CAST
19
+ * rule made literal (it is just the sign of x = cos, y = sin in each quadrant). */
20
+ declare function sign(fn: TrigFn, deg: number): number;
21
+ /** The CAST mnemonic: which of sin/cos/tan are POSITIVE in this quadrant.
22
+ * Q1 All · Q2 Sin · Q3 Tan · Q4 Cos. (On an axis, falls back to actual signs.) */
23
+ declare function castPositive(deg: number): TrigFn[];
24
+ /** The CAST letter shown in a quadrant: A (all), S (sin), T (tan), C (cos). */
25
+ declare const castLetter: (deg: number) => string;
26
+ /** Is `deg` one of the standard special angles (a multiple of 30° or 45°)? */
27
+ declare const isSpecial: (deg: number) => boolean;
28
+ /**
29
+ * Exact value of a trig function at a SPECIAL angle, as a LaTeX string (with the
30
+ * correct quadrant sign), or null if the angle isn't special. e.g.
31
+ * exactTex('cos', 150) → "-\tfrac{\sqrt3}{2}".
32
+ */
33
+ declare function exactTex(fn: TrigFn, deg: number): string | null;
34
+ /** A degree angle as an exact radian (LaTeX multiple of π), e.g. 30 → "\tfrac{\pi}{6}". */
35
+ declare function radTex(deg: number): string;
36
+ //#endregion
37
+ export { core_d_exports };
@@ -0,0 +1,150 @@
1
+ import { __exportAll } from "../../_virtual/_rolldown/runtime.mjs";
2
+ import { approxEq, gcd, toDeg, toRad } from "../../core/util.mjs";
3
+
4
+ //#region src/math/trig/core.ts
5
+ /**
6
+ * Trig TEACHING kernel. Stage's expr engine already EVALUATES sin/cos/tan
7
+ * numerically (and plots / differentiates / LaTeX-renders them) — so this layer
8
+ * adds only the things that engine has no notion of, the parts a learner actually
9
+ * struggles with:
10
+ * • exact special-angle values (sin30 = ½, not 0.4999…),
11
+ * • the QUADRANT + CAST sign rule (where sin/cos/tan are + / −),
12
+ * • the reference angle (the acute angle to the x-axis),
13
+ * • a degree → exact-radian multiple of π.
14
+ *
15
+ * Pure, reuses core/util's toRad/toDeg/gcd/approxEq. Numerically safe: tan at 90°
16
+ * / 270° is reported as "undefined", never ±∞.
17
+ */
18
+ var core_exports = /* @__PURE__ */ __exportAll({
19
+ TRIG_FNS: () => TRIG_FNS,
20
+ castLetter: () => castLetter,
21
+ castPositive: () => castPositive,
22
+ evalTrig: () => evalTrig,
23
+ exactTex: () => exactTex,
24
+ isSpecial: () => isSpecial,
25
+ normDeg: () => normDeg,
26
+ quadrant: () => quadrant,
27
+ radTex: () => radTex,
28
+ referenceAngleDeg: () => referenceAngleDeg,
29
+ sign: () => sign,
30
+ toDeg: () => toDeg,
31
+ toRad: () => toRad
32
+ });
33
+ const TRIG_FNS = [
34
+ "sin",
35
+ "cos",
36
+ "tan"
37
+ ];
38
+ /** Coterminal angle folded into [0, 360). */
39
+ const normDeg = (deg) => (deg % 360 + 360) % 360;
40
+ /** Numeric value (degrees in). tan where cos = 0 → NaN (undefined), not ±∞. */
41
+ function evalTrig(fn, deg) {
42
+ const r = toRad(normDeg(deg));
43
+ if (fn === "sin") return Math.sin(r);
44
+ if (fn === "cos") return Math.cos(r);
45
+ return approxEq(Math.cos(r), 0) ? NaN : Math.tan(r);
46
+ }
47
+ /** Quadrant 1..4 of the terminal ray; 0 when it lies ON an axis (0/90/180/270). */
48
+ function quadrant(deg) {
49
+ const a = normDeg(deg);
50
+ if (a === 0 || a === 90 || a === 180 || a === 270) return 0;
51
+ if (a < 90) return 1;
52
+ if (a < 180) return 2;
53
+ if (a < 270) return 3;
54
+ return 4;
55
+ }
56
+ /** Reference angle: the acute angle (0..90°) between the terminal ray and the
57
+ * x-axis — the angle whose exact value you actually look up. */
58
+ function referenceAngleDeg(deg) {
59
+ const a = normDeg(deg);
60
+ if (a <= 90) return a;
61
+ if (a <= 180) return 180 - a;
62
+ if (a <= 270) return a - 180;
63
+ return 360 - a;
64
+ }
65
+ /** Sign of a trig function at an angle: 1, −1, 0, or NaN (undefined). The CAST
66
+ * rule made literal (it is just the sign of x = cos, y = sin in each quadrant). */
67
+ function sign(fn, deg) {
68
+ const v = evalTrig(fn, deg);
69
+ if (!Number.isFinite(v)) return NaN;
70
+ return approxEq(v, 0) ? 0 : Math.sign(v);
71
+ }
72
+ /** The CAST mnemonic: which of sin/cos/tan are POSITIVE in this quadrant.
73
+ * Q1 All · Q2 Sin · Q3 Tan · Q4 Cos. (On an axis, falls back to actual signs.) */
74
+ function castPositive(deg) {
75
+ const q = quadrant(deg);
76
+ if (q === 1) return [
77
+ "sin",
78
+ "cos",
79
+ "tan"
80
+ ];
81
+ if (q === 2) return ["sin"];
82
+ if (q === 3) return ["tan"];
83
+ if (q === 4) return ["cos"];
84
+ return TRIG_FNS.filter((fn) => sign(fn, deg) > 0);
85
+ }
86
+ /** The CAST letter shown in a quadrant: A (all), S (sin), T (tan), C (cos). */
87
+ const castLetter = (deg) => ({
88
+ 1: "A",
89
+ 2: "S",
90
+ 3: "T",
91
+ 4: "C",
92
+ 0: "·"
93
+ })[quadrant(deg)];
94
+ /** Magnitudes at the base reference angles; sign is applied per quadrant. */
95
+ const BASE = {
96
+ 0: {
97
+ sin: "0",
98
+ cos: "1",
99
+ tan: "0"
100
+ },
101
+ 30: {
102
+ sin: "\\tfrac12",
103
+ cos: "\\tfrac{\\sqrt3}{2}",
104
+ tan: "\\tfrac{1}{\\sqrt3}"
105
+ },
106
+ 45: {
107
+ sin: "\\tfrac{\\sqrt2}{2}",
108
+ cos: "\\tfrac{\\sqrt2}{2}",
109
+ tan: "1"
110
+ },
111
+ 60: {
112
+ sin: "\\tfrac{\\sqrt3}{2}",
113
+ cos: "\\tfrac12",
114
+ tan: "\\sqrt3"
115
+ },
116
+ 90: {
117
+ sin: "1",
118
+ cos: "0",
119
+ tan: "\\text{undefined}"
120
+ }
121
+ };
122
+ /** Is `deg` one of the standard special angles (a multiple of 30° or 45°)? */
123
+ const isSpecial = (deg) => referenceAngleDeg(deg) in BASE;
124
+ /**
125
+ * Exact value of a trig function at a SPECIAL angle, as a LaTeX string (with the
126
+ * correct quadrant sign), or null if the angle isn't special. e.g.
127
+ * exactTex('cos', 150) → "-\tfrac{\sqrt3}{2}".
128
+ */
129
+ function exactTex(fn, deg) {
130
+ const row = BASE[referenceAngleDeg(deg)];
131
+ if (!row) return null;
132
+ const base = row[fn];
133
+ if (base === "\\text{undefined}") return base;
134
+ const s = sign(fn, deg);
135
+ if (Number.isNaN(s)) return "\\text{undefined}";
136
+ if (s === 0) return "0";
137
+ return s < 0 && base !== "0" ? `-${base}` : base;
138
+ }
139
+ /** A degree angle as an exact radian (LaTeX multiple of π), e.g. 30 → "\tfrac{\pi}{6}". */
140
+ function radTex(deg) {
141
+ const a = normDeg(deg);
142
+ if (a === 0) return "0";
143
+ const g = gcd(a, 180);
144
+ const p = a / g, q = 180 / g;
145
+ const top = p === 1 ? "\\pi" : `${p}\\pi`;
146
+ return q === 1 ? top : `\\tfrac{${top}}{${q}}`;
147
+ }
148
+
149
+ //#endregion
150
+ export { castLetter, castPositive, core_exports, evalTrig, exactTex, isSpecial, normDeg, quadrant, radTex, referenceAngleDeg, sign };
@@ -0,0 +1 @@
1
+ import { ReactNode } from "react";