@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
@@ -33,16 +33,36 @@ function gatePorts(type, x, y, s) {
33
33
  }
34
34
  };
35
35
  }
36
+ /** Where a small TYPE label (AND/OR/…) sits INSIDE the gate body: resolved per shape so it lands
37
+ * on the visual centroid (the D-body of AND, the right-shifted bulge of OR/XOR, the triangle of
38
+ * NOT) instead of overlapping an edge. */
39
+ function gateLabelPos(type, x, y, s) {
40
+ const base = baseOf(type);
41
+ const cy = y + s / 2;
42
+ if (base === "OR" || base === "XOR") return {
43
+ x: x + .46 * s,
44
+ y: cy
45
+ };
46
+ if (base === "NOT") return {
47
+ x: x + .3 * s,
48
+ y: cy
49
+ };
50
+ return {
51
+ x: x + .38 * s,
52
+ y: cy
53
+ };
54
+ }
36
55
  /** A logic gate glyph. `live` = its OUTPUT is high. */
37
56
  function GateGlyph({ x, y, size: s, type, live, label }) {
38
57
  const base = baseOf(type);
39
- const stroke = METAL;
58
+ const stroke = live ? LIVE : METAL;
59
+ const fill = live ? "color-mix(in oklab, var(--stage-live) 14%, var(--stage-bg))" : BG;
40
60
  const ports = gatePorts(type, x, y, s);
41
61
  const cy = y + s / 2;
42
62
  let body;
43
63
  if (base === "AND") body = /* @__PURE__ */ jsx("path", {
44
64
  d: `M${x},${y} H${x + .36 * s} A${.5 * s},${.5 * s} 0 0 1 ${x + .36 * s},${y + s} H${x} Z`,
45
- fill: BG,
65
+ fill,
46
66
  stroke,
47
67
  strokeWidth: 2,
48
68
  strokeLinejoin: "round"
@@ -51,26 +71,19 @@ function GateGlyph({ x, y, size: s, type, live, label }) {
51
71
  const ox = base === "XOR" ? x + .08 * s : x;
52
72
  body = /* @__PURE__ */ jsx("path", {
53
73
  d: `M${ox},${y} C${ox + .22 * s},${y + .16 * s} ${ox + .22 * s},${y + .84 * s} ${ox},${y + s} C${ox + .45 * s},${y + s} ${ox + .72 * s},${y + .82 * s} ${x + .86 * s},${cy} C${ox + .72 * s},${y + .18 * s} ${ox + .45 * s},${y} ${ox},${y} Z`,
54
- fill: BG,
74
+ fill,
55
75
  stroke,
56
76
  strokeWidth: 2,
57
77
  strokeLinejoin: "round"
58
78
  });
59
79
  } else body = /* @__PURE__ */ jsx("path", {
60
80
  d: `M${x + .06 * s},${y} L${x + .7 * s},${cy} L${x + .06 * s},${y + s} Z`,
61
- fill: BG,
81
+ fill,
62
82
  stroke,
63
83
  strokeWidth: 2,
64
84
  strokeLinejoin: "round"
65
85
  });
66
86
  return /* @__PURE__ */ jsxs("g", { children: [
67
- live && /* @__PURE__ */ jsx("circle", {
68
- cx: x + .46 * s,
69
- cy,
70
- r: s * .62,
71
- fill: LIVE,
72
- opacity: .12
73
- }),
74
87
  base === "XOR" && /* @__PURE__ */ jsx("path", {
75
88
  d: `M${x - .02 * s},${y} C${x + .2 * s},${y + .16 * s} ${x + .2 * s},${y + .84 * s} ${x - .02 * s},${y + s}`,
76
89
  fill: "none",
@@ -103,57 +116,45 @@ function GateGlyph({ x, y, size: s, type, live, label }) {
103
116
  strokeWidth: 1.4,
104
117
  strokeLinecap: "round"
105
118
  }),
106
- label && /* @__PURE__ */ jsx("text", {
107
- x: ports.output.x - (base === "NOT" ? .42 : .5) * s,
108
- y: cy,
109
- fill: FG,
110
- fontSize: Math.max(8, s * .22),
111
- fontWeight: 700,
112
- textAnchor: "middle",
113
- dominantBaseline: "central",
114
- style: { pointerEvents: "none" },
115
- children: label
116
- })
119
+ label && (() => {
120
+ const lp = gateLabelPos(type, x, y, s);
121
+ return /* @__PURE__ */ jsx("text", {
122
+ x: lp.x,
123
+ y: lp.y,
124
+ fill: FG,
125
+ fontSize: Math.max(7, s * .17),
126
+ fontWeight: 700,
127
+ textAnchor: "middle",
128
+ dominantBaseline: "central",
129
+ style: { pointerEvents: "none" },
130
+ children: label
131
+ });
132
+ })()
117
133
  ] });
118
134
  }
119
- /** An output LED — glows `color` when on, with a soft halo + sheen; dim ring off. */
135
+ /** An output LED: a clean filled disc (lit = `color`, idle = a faint outlined disc). No glow. */
120
136
  function Lamp({ cx, cy, r, on, color = LIVE, label }) {
121
- const lit = color;
122
137
  return /* @__PURE__ */ jsxs("g", { children: [
123
- on && /* @__PURE__ */ jsx("circle", {
124
- cx,
125
- cy,
126
- r: r * 2.1,
127
- fill: lit,
128
- opacity: .18
129
- }),
130
- on && /* @__PURE__ */ jsx("circle", {
131
- cx,
132
- cy,
133
- r: r * 1.45,
134
- fill: lit,
135
- opacity: .28
136
- }),
137
138
  /* @__PURE__ */ jsx("circle", {
138
139
  cx,
139
140
  cy,
140
141
  r,
141
- fill: on ? lit : "color-mix(in oklab, var(--stage-metal) 22%, transparent)",
142
- stroke: on ? lit : METAL,
142
+ fill: on ? color : "color-mix(in oklab, var(--stage-metal) 14%, var(--stage-bg))",
143
+ stroke: on ? color : METAL,
143
144
  strokeWidth: 1.5
144
145
  }),
145
146
  /* @__PURE__ */ jsx("circle", {
146
- cx: cx - r * .3,
147
- cy: cy - r * .32,
148
- r: r * .34,
147
+ cx: cx - r * .28,
148
+ cy: cy - r * .3,
149
+ r: r * .28,
149
150
  fill: SHEEN,
150
- opacity: on ? .8 : .3
151
+ opacity: on ? .5 : .2
151
152
  }),
152
153
  label && /* @__PURE__ */ jsx("text", {
153
154
  x: cx,
154
- y: cy + r + 4,
155
+ y: cy + r + 5,
155
156
  fill: FG,
156
- fontSize: Math.max(8, r * .9),
157
+ fontSize: Math.max(8, r * .85),
157
158
  fontWeight: 700,
158
159
  textAnchor: "middle",
159
160
  dominantBaseline: "hanging",
@@ -162,6 +163,204 @@ function Lamp({ cx, cy, r, on, color = LIVE, label }) {
162
163
  })
163
164
  ] });
164
165
  }
166
+ /** Which of segments a–g are lit for each hex digit 0–F (decoder truth, for a 7-seg display). */
167
+ const SEG_MAP = [
168
+ [
169
+ 1,
170
+ 1,
171
+ 1,
172
+ 1,
173
+ 1,
174
+ 1,
175
+ 0
176
+ ],
177
+ [
178
+ 0,
179
+ 1,
180
+ 1,
181
+ 0,
182
+ 0,
183
+ 0,
184
+ 0
185
+ ],
186
+ [
187
+ 1,
188
+ 1,
189
+ 0,
190
+ 1,
191
+ 1,
192
+ 0,
193
+ 1
194
+ ],
195
+ [
196
+ 1,
197
+ 1,
198
+ 1,
199
+ 1,
200
+ 0,
201
+ 0,
202
+ 1
203
+ ],
204
+ [
205
+ 0,
206
+ 1,
207
+ 1,
208
+ 0,
209
+ 0,
210
+ 1,
211
+ 1
212
+ ],
213
+ [
214
+ 1,
215
+ 0,
216
+ 1,
217
+ 1,
218
+ 0,
219
+ 1,
220
+ 1
221
+ ],
222
+ [
223
+ 1,
224
+ 0,
225
+ 1,
226
+ 1,
227
+ 1,
228
+ 1,
229
+ 1
230
+ ],
231
+ [
232
+ 1,
233
+ 1,
234
+ 1,
235
+ 0,
236
+ 0,
237
+ 0,
238
+ 0
239
+ ],
240
+ [
241
+ 1,
242
+ 1,
243
+ 1,
244
+ 1,
245
+ 1,
246
+ 1,
247
+ 1
248
+ ],
249
+ [
250
+ 1,
251
+ 1,
252
+ 1,
253
+ 1,
254
+ 0,
255
+ 1,
256
+ 1
257
+ ],
258
+ [
259
+ 1,
260
+ 1,
261
+ 1,
262
+ 0,
263
+ 1,
264
+ 1,
265
+ 1
266
+ ],
267
+ [
268
+ 0,
269
+ 0,
270
+ 1,
271
+ 1,
272
+ 1,
273
+ 1,
274
+ 1
275
+ ],
276
+ [
277
+ 1,
278
+ 0,
279
+ 0,
280
+ 1,
281
+ 1,
282
+ 1,
283
+ 0
284
+ ],
285
+ [
286
+ 0,
287
+ 1,
288
+ 1,
289
+ 1,
290
+ 1,
291
+ 0,
292
+ 1
293
+ ],
294
+ [
295
+ 1,
296
+ 0,
297
+ 0,
298
+ 1,
299
+ 1,
300
+ 1,
301
+ 1
302
+ ],
303
+ [
304
+ 1,
305
+ 0,
306
+ 0,
307
+ 0,
308
+ 1,
309
+ 1,
310
+ 1
311
+ ]
312
+ ].map((r) => r.map(Boolean));
313
+ function digitSegments(value) {
314
+ return SEG_MAP[(value % 16 + 16) % 16];
315
+ }
316
+ /**
317
+ * A seven-segment display digit. Drive it with a `value` (0–15 → 0–F) or explicit `segs`
318
+ * (a..g booleans). Lit segments glow in the display colour; dark segments are a faint ghost,
319
+ * so you read it like a real LED display. This is the output for binary/decoder/DLD labs.
320
+ */
321
+ function SevenSegment({ x, y, w = 46, h = 80, value, segs, color = "var(--stage-warn)" }) {
322
+ const on = segs ?? (value !== void 0 ? digitSegments(value) : [
323
+ false,
324
+ false,
325
+ false,
326
+ false,
327
+ false,
328
+ false,
329
+ false
330
+ ]);
331
+ const t = Math.min(w, h) * .13;
332
+ const off = "color-mix(in oklab, var(--stage-metal) 16%, transparent)";
333
+ const seg = (key, lit, x1, y1, x2, y2) => /* @__PURE__ */ jsx("line", {
334
+ x1,
335
+ y1,
336
+ x2,
337
+ y2,
338
+ stroke: lit ? color : off,
339
+ strokeWidth: t,
340
+ strokeLinecap: "round",
341
+ opacity: lit ? 1 : .55
342
+ }, key);
343
+ const midY = y + h / 2;
344
+ return /* @__PURE__ */ jsxs("g", { children: [
345
+ /* @__PURE__ */ jsx("rect", {
346
+ x: x - t,
347
+ y: y - t,
348
+ width: w + 2 * t,
349
+ height: h + 2 * t,
350
+ rx: 6,
351
+ fill: "color-mix(in oklab, var(--stage-bg) 80%, var(--stage-metal))",
352
+ stroke: "var(--stage-grid)",
353
+ strokeWidth: 1
354
+ }),
355
+ seg("a", on[0], x + t, y, x + w - t, y),
356
+ seg("b", on[1], x + w, y + t, x + w, midY - t * .5),
357
+ seg("c", on[2], x + w, midY + t * .5, x + w, y + h - t),
358
+ seg("d", on[3], x + t, y + h, x + w - t, y + h),
359
+ seg("e", on[4], x, midY + t * .5, x, y + h - t),
360
+ seg("f", on[5], x, y + t, x, midY - t * .5),
361
+ seg("g", on[6], x + t, midY, x + w - t, midY)
362
+ ] });
363
+ }
165
364
  /** An input switch (toggle). Render inside a `<g onClick>` in the lab for taps. */
166
365
  function ToggleSwitch({ x, y, w, h, on, label }) {
167
366
  const r = h / 2;
@@ -207,4 +406,4 @@ function ToggleSwitch({ x, y, w, h, on, label }) {
207
406
  }
208
407
 
209
408
  //#endregion
210
- export { GateGlyph, Lamp, ToggleSwitch, gatePorts };
409
+ export { GateGlyph, Lamp, SevenSegment, ToggleSwitch, gatePorts };
@@ -0,0 +1,26 @@
1
+ //#region src/kit/palette.ts
2
+ /**
3
+ * Categorical colour palette, theme-aware. The eight hues live as CSS custom
4
+ * properties (`--stage-cat-1`..`--stage-cat-8`) in @classytic/stage's styles.css,
5
+ * with tuned LIGHT (:root) and DARK (.dark) values, so a series/group colour
6
+ * adapts to the theme instead of being a fixed hex that only reads on one
7
+ * background. Labs import these instead of hardcoding their own hex arrays.
8
+ *
9
+ * • SVG / CSS labs → CATEGORICAL (var(--stage-cat-N) strings)
10
+ * • canvas labs that read tokens via getComputedStyle().getPropertyValue()
11
+ * → CATEGORICAL_TOKENS (the bare custom-property names)
12
+ *
13
+ * cat-1/2/3 align with --stage-accent / --stage-accent-2 / --stage-good.
14
+ */
15
+ const N = 8;
16
+ /** `var(--stage-cat-N)` strings — drop straight into SVG fill/stroke or CSS. */
17
+ const CATEGORICAL = Array.from({ length: N }, (_, i) => `var(--stage-cat-${i + 1})`);
18
+ /** Bare custom-property names — for canvas labs that resolve via getPropertyValue. */
19
+ const CATEGORICAL_TOKENS = Array.from({ length: N }, (_, i) => `--stage-cat-${i + 1}`);
20
+ /** The i-th categorical colour (var string), wrapping. */
21
+ const catColor = (i) => CATEGORICAL[(i % N + N) % N];
22
+ /** The i-th categorical token name (for canvas getPropertyValue), wrapping. */
23
+ const catToken = (i) => CATEGORICAL_TOKENS[(i % N + N) % N];
24
+
25
+ //#endregion
26
+ export { CATEGORICAL, catColor, catToken };
@@ -36,7 +36,7 @@ interface Hints {
36
36
  reveal: () => void;
37
37
  reset: () => void;
38
38
  }
39
- /** Progressive hint state — reveal one at a time. */
39
+ /** Progressive hint state, reveal one at a time. */
40
40
  declare function useHints(hints?: string[]): Hints;
41
41
  /** Learner-visible goal banner ("You'll be able to …"). */
42
42
  declare function Objectives({
@@ -44,7 +44,7 @@ declare function Objectives({
44
44
  }: {
45
45
  items?: string[];
46
46
  }): ReactNode;
47
- /** The hint ladder — revealed hints + a "need a hint?" button while more remain. */
47
+ /** The hint ladder, revealed hints + a "need a hint?" button while more remain. */
48
48
  declare function HintLadder({
49
49
  hints
50
50
  }: {
@@ -104,14 +104,14 @@ interface RevealSolutionProps {
104
104
  solution: ReactNode;
105
105
  /** Gate the button (e.g. only after a wrong attempt). Default: always shown. */
106
106
  available?: boolean;
107
- /** Fired ONCE when the learner reveals — let the lab dock the score (peek ≠ solve). */
107
+ /** Fired ONCE when the learner reveals, let the lab dock the score (peek ≠ solve). */
108
108
  onReveal?: () => void;
109
109
  buttonLabel?: string;
110
110
  /** The warning shown with the solution. */
111
111
  note?: string;
112
112
  }
113
113
  /**
114
- * The shared "Show answer" escape hatch — so no lab is a dead-end "wrong/right".
114
+ * The shared "Show answer" escape hatch, so no lab is a dead-end "wrong/right".
115
115
  * Manages its own shown/hidden; `key` it (e.g. per step/event) to reset between
116
116
  * questions. Revealing is a deliberate peek: it warns and reports via `onReveal`.
117
117
  */
@@ -6,23 +6,23 @@ import { useLearner } from "@classytic/stage";
6
6
 
7
7
  //#region src/kit/pedagogy.tsx
8
8
  /**
9
- * Pedagogy/assessment kit — the formative-feedback layer every lab shares.
9
+ * Pedagogy/assessment kit, the formative-feedback layer every lab shares.
10
10
  *
11
11
  * `LabMeta` (objectives, hints, misconceptions, successCriteria) was authored
12
12
  * but never rendered. This turns it into the Brilliant-style loop:
13
- * • `useCheckpoint` — the ONE assessment seam: report once on first solve,
13
+ * • `useCheckpoint`, the ONE assessment seam: report once on first solve,
14
14
  * with a hint penalty folded into the score. Kills the per-lab
15
15
  * `if (x === answer) report(...)` + done-ref boilerplate.
16
- * • `useHints` + `<HintLadder>` — progressive reveal; each hint taken docks
16
+ * • `useHints` + `<HintLadder>`, progressive reveal; each hint taken docks
17
17
  * the score (pass `hints.count` to useCheckpoint).
18
- * • `<Objectives>` — the learner-visible goal banner.
19
- * • `<Feedback>` — unifies success / try-again / misconception note (the
18
+ * • `<Objectives>`, the learner-visible goal banner.
19
+ * • `<Feedback>`, unifies success / try-again / misconception note (the
20
20
  * misconception is a boolean the lab computes from resolved state).
21
- * • `<RevealSolution>` — the shared "Show answer" escape hatch every lab gets:
21
+ * • `<RevealSolution>`, the shared "Show answer" escape hatch every lab gets:
22
22
  * a button → a warned solution panel, firing `onReveal` once so the lab can
23
23
  * dock the score (peeking ≠ solving). No more dead-end "wrong/right".
24
24
  *
25
- * Domain glue over stage's learner seam — stays in labs so stage is a pure
25
+ * Domain glue over stage's learner seam, stays in labs so stage is a pure
26
26
  * engine; imports only `useLearner` from @classytic/stage.
27
27
  */
28
28
  /** Report completion once, the first time `solved` becomes true. */
@@ -69,7 +69,7 @@ function useCheckpoint({ solved, activity, score, hintsUsed = 0, hintPenalty = .
69
69
  reported
70
70
  };
71
71
  }
72
- /** Progressive hint state — reveal one at a time. */
72
+ /** Progressive hint state, reveal one at a time. */
73
73
  function useHints(hints = []) {
74
74
  const [n, setN] = useState(0);
75
75
  return {
@@ -91,7 +91,7 @@ function Objectives({ items }) {
91
91
  }), /* @__PURE__ */ jsx("ul", { children: items.map((o, i) => /* @__PURE__ */ jsx("li", { children: o }, i)) })]
92
92
  });
93
93
  }
94
- /** The hint ladder — revealed hints + a "need a hint?" button while more remain. */
94
+ /** The hint ladder, revealed hints + a "need a hint?" button while more remain. */
95
95
  function HintLadder({ hints }) {
96
96
  if (hints.revealed.length === 0 && !hints.hasMore) return null;
97
97
  return /* @__PURE__ */ jsxs("div", {
@@ -147,16 +147,20 @@ function ChallengeCard({ questions, state, title = "Predict first" }) {
147
147
  state.total
148
148
  ]
149
149
  })]
150
- }), questions.map((q) => {
150
+ }), questions.map((q, i) => {
151
151
  const picked = state.picks[q.id];
152
152
  const answered = picked != null;
153
153
  const correct = picked === q.answer;
154
154
  return /* @__PURE__ */ jsxs("div", {
155
155
  className: "lab-challenge-q",
156
156
  children: [
157
- /* @__PURE__ */ jsx("span", {
157
+ /* @__PURE__ */ jsxs("span", {
158
158
  className: "lab-challenge-prompt",
159
- children: q.prompt
159
+ children: [questions.length > 1 && /* @__PURE__ */ jsx("span", {
160
+ className: "lab-challenge-num",
161
+ "aria-hidden": true,
162
+ children: i + 1
163
+ }), /* @__PURE__ */ jsx("span", { children: q.prompt })]
160
164
  }),
161
165
  /* @__PURE__ */ jsx("div", {
162
166
  className: "lab-choices",
@@ -185,7 +189,7 @@ function ChallengeCard({ questions, state, title = "Predict first" }) {
185
189
  className: "lab-pill",
186
190
  "data-state": "no",
187
191
  role: "status",
188
- children: "Not yet — try again"
192
+ children: "Not yet, try again"
189
193
  }))
190
194
  ]
191
195
  }, q.id);
@@ -244,7 +248,7 @@ function AskBox({ prompt, placeholder = "your answer", check, activity }) {
244
248
  className: "lab-pill",
245
249
  "data-state": "no",
246
250
  role: "status",
247
- children: "Not yet — try again"
251
+ children: "Not yet, try again"
248
252
  })
249
253
  ]
250
254
  }),
@@ -263,7 +267,7 @@ function AskBox({ prompt, placeholder = "your answer", check, activity }) {
263
267
  });
264
268
  }
265
269
  /** Unified success / misconception / try-again feedback. */
266
- function Feedback({ ok, misconception, okText = "Correct", tryText = "Not yet — keep going" }) {
270
+ function Feedback({ ok, misconception, okText = "Correct", tryText = "Not yet, keep going" }) {
267
271
  if (ok) return /* @__PURE__ */ jsxs("span", {
268
272
  className: "lab-pill",
269
273
  "data-state": "ok",
@@ -288,11 +292,11 @@ function Feedback({ ok, misconception, okText = "Correct", tryText = "Not yet
288
292
  });
289
293
  }
290
294
  /**
291
- * The shared "Show answer" escape hatch — so no lab is a dead-end "wrong/right".
295
+ * The shared "Show answer" escape hatch, so no lab is a dead-end "wrong/right".
292
296
  * Manages its own shown/hidden; `key` it (e.g. per step/event) to reset between
293
297
  * questions. Revealing is a deliberate peek: it warns and reports via `onReveal`.
294
298
  */
295
- function RevealSolution({ solution, available = true, onReveal, buttonLabel = "Show answer", note = "Peeking — this one won’t count as solved on your own." }) {
299
+ function RevealSolution({ solution, available = true, onReveal, buttonLabel = "Show answer", note = "Peeking, this one won’t count as solved on your own." }) {
296
300
  const [shown, setShown] = useState(false);
297
301
  if (shown) return /* @__PURE__ */ jsxs("div", {
298
302
  className: "lab-solution",
@@ -6,7 +6,7 @@ interface PlayGate {
6
6
  inView: boolean;
7
7
  playing: boolean;
8
8
  setPlaying: (p: boolean) => void;
9
- /** playing && inView — pass to useFrameLoop's `running`. */
9
+ /** playing && inView, pass to useFrameLoop's `running`. */
10
10
  running: boolean;
11
11
  }
12
12
  declare function usePlayGate(autoPlay?: boolean): PlayGate;
package/dist/kit/play.mjs CHANGED
@@ -8,9 +8,9 @@ import { useInView } from "@classytic/stage";
8
8
  /**
9
9
  * Play-gate for hand-driven sim labs (those running their own useFrameLoop rather
10
10
  * than going through <Scene>, which already has this). It does two things:
11
- * • off-screen pause — the loop only runs while the figure is visible, so a page
11
+ * • off-screen pause, the loop only runs while the figure is visible, so a page
12
12
  * of labs doesn't pin the CPU;
13
- * • press-to-start — an ambient animation shouldn't auto-run; show a ▶ Play
13
+ * • press-to-start, an ambient animation shouldn't auto-run; show a ▶ Play
14
14
  * overlay until the learner starts it.
15
15
  *
16
16
  * Usage:
@@ -19,7 +19,7 @@ import { useInView } from "@classytic/stage";
19
19
  * … <PlayWrap gate={gate}>{figureSvg}</PlayWrap>
20
20
  *
21
21
  * For a USER-TRIGGERED lab (a Run/Drop button already decides when to animate),
22
- * skip the overlay — just gate the existing condition on visibility with `useInView`.
22
+ * skip the overlay, just gate the existing condition on visibility with `useInView`.
23
23
  */
24
24
  function usePlayGate(autoPlay = false) {
25
25
  const { ref, inView } = useInView();
@@ -0,0 +1,55 @@
1
+ import { GuessTone } from "./vessel.mjs";
2
+ import { ReactNode } from "react";
3
+ import { Vec2 } from "@classytic/stage";
4
+
5
+ //#region src/kit/predict.d.ts
6
+ interface PredictPlotProps {
7
+ /** Given data points, already plotted (the pattern to extend). */
8
+ data: Vec2[];
9
+ /** The controlled ghost point the learner drags. */
10
+ guess: Vec2;
11
+ onGuess: (p: Vec2, phase: 'move' | 'commit') => void;
12
+ /** Colour the ghost by correctness (parent decides). */
13
+ tone?: GuessTone;
14
+ /** First-quadrant window; axes sit at the corner. */
15
+ xMax: number;
16
+ yMax: number;
17
+ xStep?: number;
18
+ yStep?: number;
19
+ xLabel?: string;
20
+ yLabel?: string;
21
+ height?: number;
22
+ /** Lock the ghost to its x (vertical drag only). Default true , predict the y. */
23
+ lockX?: boolean;
24
+ /** Snap the ghost to the grid on drag. Default true. */
25
+ snap?: boolean;
26
+ /** Draw the underlying rule line y = slope·x + intercept (e.g. once solved). */
27
+ rule?: {
28
+ slope: number;
29
+ intercept: number;
30
+ } | null;
31
+ /** Faint guide column at x = guess.x so the learner sees which input they're on. */
32
+ showColumn?: boolean;
33
+ /** Readout the guess coordinate as a label by the ghost. */
34
+ readout?: boolean;
35
+ }
36
+ declare function PredictPlot({
37
+ data,
38
+ guess,
39
+ onGuess,
40
+ tone,
41
+ xMax,
42
+ yMax,
43
+ xStep,
44
+ yStep,
45
+ xLabel,
46
+ yLabel,
47
+ height,
48
+ lockX,
49
+ snap,
50
+ rule,
51
+ showColumn,
52
+ readout
53
+ }: PredictPlotProps): ReactNode;
54
+ //#endregion
55
+ export { PredictPlot, PredictPlotProps };