@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
@@ -3,18 +3,19 @@
3
3
  import { mulberry32, randInt } from "../../core/rng.mjs";
4
4
  import { Chip, Slider } from "../../kit/controls.mjs";
5
5
  import { Callout, ControlBar, Field, LabFrame, LiveRegion } from "../../kit/frame.mjs";
6
- import { HintLadder, useHints } from "../../kit/pedagogy.mjs";
6
+ import { HintLadder, useCheckpoint, useHints } from "../../kit/pedagogy.mjs";
7
7
  import { useReducedMotionDeferred } from "../../kit/anim.mjs";
8
+ import { catColor, catToken } from "../../kit/palette.mjs";
8
9
  import { useCallback, useEffect, useMemo, useRef, useState } from "react";
9
10
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
10
11
  import { CanvasLayer, useControlSurface, useFrameLoop, useInView } from "@classytic/stage";
11
12
 
12
13
  //#region src/discrete/monte-carlo/preset.tsx
13
14
  /**
14
- * MonteCarloLab — the GENERAL "estimate a probability by running it many times"
15
+ * MonteCarloLab, the GENERAL "estimate a probability by running it many times"
15
16
  * engine. The whole of statistical ML rests on one idea this lab makes visible:
16
17
  * the empirical frequency of an event converges to its true probability as trials
17
- * pile up (the law of large numbers). You don't compute the answer — you SAMPLE
18
+ * pile up (the law of large numbers). You don't compute the answer, you SAMPLE
18
19
  * it, and watch the estimate settle onto the truth.
19
20
  *
20
21
  * It is general by construction: a creator supplies one or more SERIES, each just
@@ -22,19 +23,13 @@ import { CanvasLayer, useControlSurface, useFrameLoop, useInView } from "@classy
22
23
  * estimates like π). The lab runs seeded batches per frame, tracks hits/total,
23
24
  * and draws either a convergence run-chart (empirical line homing onto the dashed
24
25
  * theoretical) or a dart scatter. Randomness is a SEEDED PRNG (mulberry32), so a
25
- * run is replayable — an agent can pin a seed and reproduce a lesson exactly.
26
+ * run is replayable, an agent can pin a seed and reproduce a lesson exactly.
26
27
  *
27
28
  * Ships a small library of named experiments (`montyHall`, `piDarts`, `diceSum`,
28
- * `bernoulli`) that expand to series — the Monty Hall paradox (switch ⇒ ⅔, stay
29
+ * `bernoulli`) that expand to series, the Monty Hall paradox (switch ⇒ ⅔, stay
29
30
  * ⇒ ⅓, two lines splitting apart) is the headline. Add an experiment by writing a
30
31
  * factory that returns series; the engine never changes.
31
32
  */
32
- const COLORS = [
33
- "#1c7ed6",
34
- "#e8590c",
35
- "#2f9e44",
36
- "#9c36b5"
37
- ];
38
33
  function montyTrial(rng, doSwitch, doors) {
39
34
  const car = randInt(rng, 0, doors - 1);
40
35
  const pick = randInt(rng, 0, doors - 1);
@@ -206,7 +201,7 @@ function MonteCarloLab({ series: seriesIn, experiment, viz: vizIn, seed = 12345,
206
201
  const tok = (n, fb) => css.getPropertyValue(n).trim() || fb;
207
202
  tok("--stage-fg", "#222");
208
203
  const grid = tok("--stage-grid", "rgba(125,125,125,.25)"), muted = tok("--stage-muted", "#888"), good = tok("--stage-good", "#2f9e44");
209
- const seriesColor = (i) => series[i].color ?? COLORS[i % COLORS.length];
204
+ const seriesColor = (i) => series[i].color ?? tok(catToken(i), `hsl(${i * 47 % 360} 70% 50%)`);
210
205
  const W = ctx.canvas.clientWidth || 640, Hh = height;
211
206
  ctx.clearRect(0, 0, W, Hh);
212
207
  if (viz === "scatter") {
@@ -315,13 +310,18 @@ function MonteCarloLab({ series: seriesIn, experiment, viz: vizIn, seed = 12345,
315
310
  const frac = total ? st.hits / total : 0;
316
311
  return {
317
312
  label: s.label,
318
- color: s.color ?? COLORS[i % COLORS.length],
313
+ color: s.color ?? catColor(i),
319
314
  est: s.estimate ? s.estimate(frac) : frac,
320
315
  theoretical: s.theoretical,
321
316
  total
322
317
  };
323
318
  });
324
319
  const totalTrials = stats.reduce((a, b) => Math.max(a, b.total), 0);
320
+ useCheckpoint({
321
+ solved: stats.length > 0 && totalTrials >= 300 && stats.every((s) => s.theoretical == null || Math.abs(s.est - s.theoretical) <= (viz === "scatter" ? .05 : .02)),
322
+ activity: `monte-carlo:${title}`,
323
+ hintsUsed: hints.count
324
+ });
325
325
  useControlSurface(controlId, {
326
326
  run: {
327
327
  type: "action",
@@ -389,7 +389,7 @@ function MonteCarloLab({ series: seriesIn, experiment, viz: vizIn, seed = 12345,
389
389
  children: [
390
390
  s.label,
391
391
  ": ",
392
- s.total ? s.est.toFixed(viz === "scatter" ? 4 : 3) : "—",
392
+ s.total ? s.est.toFixed(viz === "scatter" ? 4 : 3) : ", ",
393
393
  s.theoretical != null && /* @__PURE__ */ jsxs("span", {
394
394
  style: {
395
395
  color: "var(--stage-muted)",
@@ -10,11 +10,11 @@ import { useControlSurface, useFrameLoop, useInView } from "@classytic/stage";
10
10
 
11
11
  //#region src/discrete/monty-hall/preset.tsx
12
12
  /**
13
- * MontyHallLab — the paradox as a GAME you play, not a chart you stare at. Three
13
+ * MontyHallLab, the paradox as a GAME you play, not a chart you stare at. Three
14
14
  * doors (one hides a car, the rest goats); you pick, Monty throws open a goat, and
15
15
  * you choose to STAY or SWITCH and watch the door swing open on your fate. Every
16
16
  * game you (and the auto-player) finish feeds two growing win-rate bars, so the
17
- * shocking truth — switch ≈ 2/3, stay ≈ 1/3 — is something you EARN by watching it
17
+ * shocking truth, switch ≈ 2/3, stay ≈ 1/3, is something you EARN by watching it
18
18
  * happen, the law of large numbers built from felt experience.
19
19
  *
20
20
  * Doors/car/goat are stage glyphs (DoorGlyph swings open via CSS); the round logic
@@ -200,7 +200,7 @@ function MontyHallLab({ doors = 3, seed = 7, title = "The Monty Hall game", prom
200
200
  const swTarget = (n - 1) / n, stTarget = 1 / n;
201
201
  const narration = () => {
202
202
  if (phase === "pick") return pick == null ? /* @__PURE__ */ jsxs(Fragment$1, { children: [
203
- "🎬 Pick a door — one hides the ",
203
+ "🎬 Pick a door, one hides the ",
204
204
  /* @__PURE__ */ jsx("b", { children: "car" }),
205
205
  ", the others ",
206
206
  /* @__PURE__ */ jsx("b", { children: "goats" }),
@@ -213,7 +213,7 @@ function MontyHallLab({ doors = 3, seed = 7, title = "The Monty Hall game", prom
213
213
  if (phase === "revealed") return /* @__PURE__ */ jsxs(Fragment$1, { children: [
214
214
  "Monty opened ",
215
215
  opened.map((d) => `Door ${d + 1}`).join(", "),
216
- " — a goat! 🐐 Now: ",
216
+ ", a goat! 🐐 Now: ",
217
217
  /* @__PURE__ */ jsx("b", { children: "stay" }),
218
218
  " with Door ",
219
219
  pick + 1,
@@ -238,7 +238,7 @@ function MontyHallLab({ doors = 3, seed = 7, title = "The Monty Hall game", prom
238
238
  }),
239
239
  " You ",
240
240
  strategy === "switch" ? "switched" : "stayed",
241
- " — the car was behind Door ",
241
+ ", the car was behind Door ",
242
242
  car + 1,
243
243
  "."
244
244
  ] });
@@ -436,7 +436,7 @@ function MontyHallLab({ doors = 3, seed = 7, title = "The Monty Hall game", prom
436
436
  color: "var(--stage-muted)"
437
437
  },
438
438
  children: [
439
- games ? `${(rate * 100).toFixed(1)}%` : "—",
439
+ games ? `${(rate * 100).toFixed(1)}%` : ", ",
440
440
  " · ",
441
441
  wins,
442
442
  "/",
@@ -12,12 +12,12 @@ import { useControlSurface } from "@classytic/stage";
12
12
 
13
13
  //#region src/discrete/outcome-builder/preset.tsx
14
14
  /**
15
- * OutcomeBuilderLab — "where do the possibilities come from?" Build a sample space
15
+ * OutcomeBuilderLab, "where do the possibilities come from?" Build a sample space
16
16
  * one stage at a time: add a coin or a die and watch the list of ALL outcomes
17
17
  * fan out, with the counting principle spelled out (2 × 2 × 6 = 24). Each outcome
18
18
  * is drawn with the real coin/dice glyphs, so the abstract "sample space" is a
19
19
  * concrete board you can point at. Click outcomes to mark an EVENT and read its
20
- * probability as favourable ÷ total — the definition, built by hand.
20
+ * probability as favourable ÷ total, the definition, built by hand.
21
21
  *
22
22
  * Pure enumeration (cartesian product of the per-stage option lists); P uses the
23
23
  * gcd from the discrete kernel for a reduced fraction.
@@ -181,7 +181,7 @@ function OutcomeBuilderLab({ stages: stages0 = ["coin", "coin"], maxOutcomes = 7
181
181
  children: [
182
182
  "That's ",
183
183
  /* @__PURE__ */ jsx("b", { children: total }),
184
- " equally-likely outcomes — too many to draw. The counting principle still gives the count without listing them all."
184
+ " equally-likely outcomes, too many to draw. The counting principle still gives the count without listing them all."
185
185
  ]
186
186
  }) : /* @__PURE__ */ jsx("div", {
187
187
  style: {
@@ -3,7 +3,7 @@
3
3
  import { Tex as Tex$1 } from "../../core/tex.mjs";
4
4
  import { Chip, Slider } from "../../kit/controls.mjs";
5
5
  import { Callout, ControlBar, Field, LabFrame } from "../../kit/frame.mjs";
6
- import { HintLadder, useHints } from "../../kit/pedagogy.mjs";
6
+ import { ChallengeCard, HintLadder, useChallenge, useCheckpoint, useHints } from "../../kit/pedagogy.mjs";
7
7
  import { nCr } from "../core/combinatorics.mjs";
8
8
  import { useMemo, useState } from "react";
9
9
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
@@ -11,16 +11,16 @@ import { useControlSurface } from "@classytic/stage";
11
11
 
12
12
  //#region src/discrete/pascal/preset.tsx
13
13
  /**
14
- * PascalTriangleLab — where counting, the binomial theorem, and a fractal meet. The
15
- * triangle is built live by the one rule that defines it — each cell is the SUM of
16
- * the two above — and every cell is also C(n,k): the number of ways to choose k of
14
+ * PascalTriangleLab, where counting, the binomial theorem, and a fractal meet. The
15
+ * triangle is built live by the one rule that defines it, each cell is the SUM of
16
+ * the two above, and every cell is also C(n,k): the number of ways to choose k of
17
17
  * n (so the counting labs and this are the same numbers). Click a cell to see the
18
18
  * two parents add into it AND its three identities (combination · path count ·
19
19
  * binomial coefficient). Pick the binomial view and a whole ROW becomes the
20
20
  * expansion (a+b)ⁿ. Flip "odd/even" and the triangle blooms into the Sierpiński
21
- * triangle — the wow that shows structure hides in plain arithmetic.
21
+ * triangle, the wow that shows structure hides in plain arithmetic.
22
22
  *
23
- * Values come from nCr (kernel), but the recurrence is what's shown — the formula
23
+ * Values come from nCr (kernel), but the recurrence is what's shown, the formula
24
24
  * is derived by the picture, not stated.
25
25
  */
26
26
  const CW = 46, RH = 42, R = 18, PAD = 22;
@@ -44,6 +44,31 @@ function PascalTriangleLab({ rows = 7, view: view0 = "build", title = "Pascal's
44
44
  k: 2
45
45
  });
46
46
  const hints = useHints(hintList);
47
+ const Q = useMemo(() => [{
48
+ id: "pascal-C52",
49
+ prompt: "Row 5 of Pascal’s triangle is 1, 5, 10, 10, 5, 1. What is C(5,2) — the number of ways to choose 2 from 5?",
50
+ choices: [
51
+ {
52
+ value: "20",
53
+ label: "20"
54
+ },
55
+ {
56
+ value: "10",
57
+ label: "10"
58
+ },
59
+ {
60
+ value: "7",
61
+ label: "7"
62
+ }
63
+ ],
64
+ answer: "10",
65
+ explain: "Each cell is the sum of the two above it, and equals C(n,k); C(5,2)=10, while 5×4=20 counts ORDERED pairs."
66
+ }], []);
67
+ const ch = useChallenge(Q);
68
+ useCheckpoint({
69
+ solved: ch.allCorrect,
70
+ activity: "pascal:predict"
71
+ });
47
72
  const vbW = N * CW + 2 * R + 40, vbH = PAD + (N + 1) * RH + 10;
48
73
  const cx = (n, k) => vbW / 2 + (k - n / 2) * CW;
49
74
  const cy = (n) => 40 + n * RH;
@@ -238,7 +263,7 @@ function PascalTriangleLab({ rows = 7, view: view0 = "build", title = "Pascal's
238
263
  }) : /* @__PURE__ */ jsxs("p", {
239
264
  style: { margin: 0 },
240
265
  children: [
241
- "📐 an edge — always ",
266
+ "📐 an edge, always ",
242
267
  /* @__PURE__ */ jsx("b", { children: "1" }),
243
268
  " (one way)."
244
269
  ]
@@ -286,6 +311,11 @@ function PascalTriangleLab({ rows = 7, view: view0 = "build", title = "Pascal's
286
311
  ]
287
312
  })] }) : /* @__PURE__ */ jsx(Callout, { children: "Click any cell." });
288
313
  const footer = /* @__PURE__ */ jsxs(Fragment$1, { children: [
314
+ /* @__PURE__ */ jsx(ChallengeCard, {
315
+ questions: Q,
316
+ state: ch,
317
+ title: "Predict first"
318
+ }),
289
319
  view === "binomial" && selRow >= 0 && /* @__PURE__ */ jsxs("div", {
290
320
  style: {
291
321
  padding: "8px 12px",
@@ -0,0 +1,20 @@
1
+ import { Worked } from "../kit/calc.mjs";
2
+ import { RuleDef } from "../kit/rule.mjs";
3
+
4
+ //#region src/discrete/rules.d.ts
5
+ declare function explainFactorial(n: number): Worked;
6
+ declare function explainNPr(n: number, r: number): Worked;
7
+ declare function explainNCr(n: number, r: number): Worked;
8
+ declare function explainProduct(stages: number[]): Worked;
9
+ declare function explainSum(cases: number[]): Worked;
10
+ declare function explainPermWithRep(n: number, r: number): Worked;
11
+ declare const PRODUCT_RULE: RuleDef;
12
+ declare const SUM_RULE: RuleDef;
13
+ declare const FACTORIAL_RULE: RuleDef;
14
+ declare const PERMUTATION_RULE: RuleDef;
15
+ declare const COMBINATION_RULE: RuleDef;
16
+ declare const PERM_REP_RULE: RuleDef;
17
+ /** The full counting rulebook, in teaching order, for a gallery / rulebook lab. */
18
+ declare const COUNTING_RULES: RuleDef[];
19
+ //#endregion
20
+ export { COMBINATION_RULE, COUNTING_RULES, FACTORIAL_RULE, PERMUTATION_RULE, PERM_REP_RULE, PRODUCT_RULE, SUM_RULE, explainFactorial, explainNCr, explainNPr, explainPermWithRep, explainProduct, explainSum };
@@ -0,0 +1,264 @@
1
+ import { calc, texNum } from "../kit/calc.mjs";
2
+ import { factorial, nCr, nPr, permutationsWithRepetition, ruleOfProduct, ruleOfSum } from "./core/combinatorics.mjs";
3
+
4
+ //#region src/discrete/rules.ts
5
+ /**
6
+ * The counting RULEBOOK, as data. Each rule is a {@link RuleDef} an author drops
7
+ * into a lab/lesson (formula + analogy + a live calculator that shows its working
8
+ * + a derivation/proof + tricks). The calculators COMPUTE through the
9
+ * combinatorics kernel (single source of truth) and NARRATE the working in LaTeX,
10
+ * so a lab teaches HOW the rule computes, not just the answer.
11
+ */
12
+ function explainFactorial(n) {
13
+ const v = factorial(n);
14
+ const chain = n <= 1 ? "1" : Array.from({ length: n }, (_, i) => n - i).join(" \\times ");
15
+ return calc().step(`${n}! = ${chain}`, "multiply every whole number down to 1").step(`= ${texNum(v)}`).done(v);
16
+ }
17
+ function explainNPr(n, r) {
18
+ const v = nPr(n, r);
19
+ const chain = r <= 0 ? "1" : Array.from({ length: r }, (_, i) => n - i).join(" \\times ");
20
+ return calc().step(`P(${n},${r}) = \\frac{${n}!}{(${n}-${r})!} = \\frac{${n}!}{${n - r}!}`, "cancel the unused tail").step(`= ${chain}`, `${r} falling factor${r === 1 ? "" : "s"}`).step(`= ${texNum(v)}`).done(v);
21
+ }
22
+ function explainNCr(n, r) {
23
+ const v = nCr(n, r);
24
+ const p = nPr(n, r), kf = factorial(r);
25
+ return calc().step(`C(${n},${r}) = \\frac{P(${n},${r})}{${r}!} = \\frac{${n}!}{${r}!\\,(${n}-${r})!}`, "order ignored: divide out the r! re-orderings").step(`= \\frac{${texNum(p)}}{${texNum(kf)}}`, `P(${n},${r})=${texNum(p)},\\; ${r}!=${texNum(kf)}`).step(`= ${texNum(v)}`).done(v);
26
+ }
27
+ function explainProduct(stages) {
28
+ const v = ruleOfProduct(...stages);
29
+ return calc().step(stages.map(texNum).join(" \\times "), "multiply the choices at each independent stage (AND)").step(`= ${texNum(v)}`).done(v);
30
+ }
31
+ function explainSum(cases) {
32
+ const v = ruleOfSum(...cases);
33
+ return calc().step(cases.map(texNum).join(" + "), "add the mutually-exclusive cases (OR)").step(`= ${texNum(v)}`).done(v);
34
+ }
35
+ function explainPermWithRep(n, r) {
36
+ const v = permutationsWithRepetition(n, r);
37
+ const chain = Array.from({ length: Math.max(1, r) }, () => texNum(n)).join(" \\times ");
38
+ return calc().step(`${n}^{${r}} = ${chain}`, `each of ${r} positions has all ${n} options`).step(`= ${texNum(v)}`).done(v);
39
+ }
40
+ const PRODUCT_RULE = {
41
+ id: "rule-of-product",
42
+ name: "Rule of product (AND → multiply)",
43
+ formula: "\\#(A \\text{ then } B) = \\#A \\times \\#B",
44
+ analogy: "An outfit = pick a shirt AND pick trousers: 4 shirts × 3 trousers = 12 outfits.",
45
+ inputs: [
46
+ {
47
+ key: "a",
48
+ label: "stage 1",
49
+ default: 4,
50
+ min: 1,
51
+ max: 20
52
+ },
53
+ {
54
+ key: "b",
55
+ label: "stage 2",
56
+ default: 3,
57
+ min: 1,
58
+ max: 20
59
+ },
60
+ {
61
+ key: "c",
62
+ label: "stage 3",
63
+ default: 2,
64
+ min: 1,
65
+ max: 20
66
+ }
67
+ ],
68
+ compute: (v) => explainProduct([
69
+ v.a ?? 1,
70
+ v.b ?? 1,
71
+ v.c ?? 1
72
+ ]),
73
+ derivation: [
74
+ { tex: "\\text{Each of the } \\#A \\text{ first choices}" },
75
+ {
76
+ tex: "\\text{pairs with all } \\#B \\text{ second choices}",
77
+ note: "independent"
78
+ },
79
+ {
80
+ tex: "\\Rightarrow \\#A \\times \\#B \\text{ outcomes}",
81
+ note: "an A × B grid"
82
+ }
83
+ ],
84
+ tricks: [
85
+ "Use it when steps happen in SEQUENCE (\"and then\"), independently.",
86
+ "Repetition allowed ⇒ same count each stage ⇒ nʳ.",
87
+ "No repetition ⇒ the pool shrinks (n, n−1, …) ⇒ P(n,r)."
88
+ ]
89
+ };
90
+ const SUM_RULE = {
91
+ id: "rule-of-sum",
92
+ name: "Rule of sum (OR → add)",
93
+ formula: "\\#(A \\text{ or } B) = \\#A + \\#B \\quad (A \\cap B = \\varnothing)",
94
+ analogy: "A drink = a tea OR a coffee: 3 teas + 5 coffees = 8 choices.",
95
+ inputs: [{
96
+ key: "a",
97
+ label: "case A",
98
+ default: 3,
99
+ min: 0,
100
+ max: 50
101
+ }, {
102
+ key: "b",
103
+ label: "case B",
104
+ default: 5,
105
+ min: 0,
106
+ max: 50
107
+ }],
108
+ compute: (v) => explainSum([v.a ?? 0, v.b ?? 0]),
109
+ tricks: [
110
+ "Use it for a choice BETWEEN exclusive cases (\"either … or\").",
111
+ "If the cases OVERLAP, subtract the double-count: |A∪B| = |A|+|B|−|A∩B|.",
112
+ "The exam trap in one line: \"and\" → ×, \"or\" → +."
113
+ ]
114
+ };
115
+ const FACTORIAL_RULE = {
116
+ id: "factorial",
117
+ name: "Factorial: n!",
118
+ formula: "n! = n \\times (n-1) \\times \\cdots \\times 2 \\times 1",
119
+ analogy: "The ways to line up n distinct books on a shelf.",
120
+ inputs: [{
121
+ key: "n",
122
+ label: "n",
123
+ default: 5,
124
+ min: 0,
125
+ max: 12
126
+ }],
127
+ compute: (v) => explainFactorial(v.n ?? 0),
128
+ derivation: [
129
+ {
130
+ tex: "\\text{Slot 1: } n \\text{ choices}",
131
+ note: "any book first"
132
+ },
133
+ {
134
+ tex: "\\text{Slot 2: } (n-1) \\text{ choices}",
135
+ note: "one is used"
136
+ },
137
+ {
138
+ tex: "\\cdots \\text{ last slot: } 1",
139
+ note: "no choice left"
140
+ },
141
+ {
142
+ tex: "n \\times (n-1) \\times \\cdots \\times 1 = n!",
143
+ note: "rule of product"
144
+ }
145
+ ],
146
+ tricks: [
147
+ "0! = 1 (one way to arrange nothing).",
148
+ "Grows explosively: 13! > 6 billion.",
149
+ "The engine under both P(n,r) and C(n,r)."
150
+ ]
151
+ };
152
+ const PERMUTATION_RULE = {
153
+ id: "permutation",
154
+ name: "Permutations: P(n, r)",
155
+ formula: "P(n,r) = \\frac{n!}{(n-r)!}",
156
+ analogy: "Gold / silver / bronze to r of n runners: ORDER matters.",
157
+ inputs: [{
158
+ key: "n",
159
+ label: "n",
160
+ default: 5,
161
+ min: 0,
162
+ max: 12
163
+ }, {
164
+ key: "r",
165
+ label: "r",
166
+ default: 3,
167
+ min: 0,
168
+ max: 12
169
+ }],
170
+ compute: (v) => explainNPr(v.n ?? 0, v.r ?? 0),
171
+ derivation: [
172
+ { tex: "\\text{Fill } r \\text{ ordered slots from } n" },
173
+ {
174
+ tex: "n \\times (n-1) \\times \\cdots \\times (n-r+1)",
175
+ note: "pool shrinks each slot"
176
+ },
177
+ {
178
+ tex: "= \\frac{n!}{(n-r)!}",
179
+ note: "the tail (n−r)! cancels"
180
+ }
181
+ ],
182
+ tricks: [
183
+ "Order MATTERS → permutation; AB ≠ BA.",
184
+ "P(n,n) = n! (arrange everyone).",
185
+ "P(n,r) = C(n,r) × r! (choose, then order)."
186
+ ]
187
+ };
188
+ const COMBINATION_RULE = {
189
+ id: "combination",
190
+ name: "Combinations: C(n, r)",
191
+ formula: "C(n,r) = \\binom{n}{r} = \\frac{n!}{r!\\,(n-r)!}",
192
+ analogy: "Picking a team of r from n: ORDER does NOT matter.",
193
+ inputs: [{
194
+ key: "n",
195
+ label: "n",
196
+ default: 5,
197
+ min: 0,
198
+ max: 20
199
+ }, {
200
+ key: "r",
201
+ label: "r",
202
+ default: 3,
203
+ min: 0,
204
+ max: 20
205
+ }],
206
+ compute: (v) => explainNCr(v.n ?? 0, v.r ?? 0),
207
+ derivation: [
208
+ {
209
+ tex: "\\text{Order them first: } P(n,r) = \\frac{n!}{(n-r)!}",
210
+ note: "the ordered count"
211
+ },
212
+ {
213
+ tex: "\\text{Each team was counted } r! \\text{ times}",
214
+ note: "its r! orderings"
215
+ },
216
+ {
217
+ tex: "C(n,r) = \\frac{P(n,r)}{r!} = \\frac{n!}{r!\\,(n-r)!}",
218
+ note: "divide out the over-count"
219
+ }
220
+ ],
221
+ tricks: [
222
+ "Order does NOT matter → combination; {A,B} = {B,A}.",
223
+ "Symmetry: C(n,r) = C(n, n−r) (choose who is OUT).",
224
+ "Row n of Pascal’s triangle IS C(n,0) … C(n,n).",
225
+ "\"Overcount by order, then divide it out\": C = P ÷ r!."
226
+ ]
227
+ };
228
+ const PERM_REP_RULE = {
229
+ id: "perm-with-rep",
230
+ name: "Permutations with repetition: nʳ",
231
+ formula: "\\#\\text{strings} = n^{r}",
232
+ analogy: "A 4-digit PIN from 10 digits: each slot independently has all 10 → 10⁴.",
233
+ inputs: [{
234
+ key: "n",
235
+ label: "options n",
236
+ default: 10,
237
+ min: 1,
238
+ max: 26
239
+ }, {
240
+ key: "r",
241
+ label: "positions r",
242
+ default: 4,
243
+ min: 0,
244
+ max: 10
245
+ }],
246
+ compute: (v) => explainPermWithRep(v.n ?? 1, v.r ?? 0),
247
+ tricks: [
248
+ "Repetition ALLOWED and order matters → nʳ.",
249
+ "It is the rule of product with the SAME n each stage.",
250
+ "Counts functions A→B, binary strings (2ⁿ), dice-roll sequences."
251
+ ]
252
+ };
253
+ /** The full counting rulebook, in teaching order, for a gallery / rulebook lab. */
254
+ const COUNTING_RULES = [
255
+ PRODUCT_RULE,
256
+ SUM_RULE,
257
+ FACTORIAL_RULE,
258
+ PERMUTATION_RULE,
259
+ COMBINATION_RULE,
260
+ PERM_REP_RULE
261
+ ];
262
+
263
+ //#endregion
264
+ export { COMBINATION_RULE, COUNTING_RULES, FACTORIAL_RULE, PERMUTATION_RULE, PERM_REP_RULE, PRODUCT_RULE, SUM_RULE, explainFactorial, explainNCr, explainNPr, explainPermWithRep, explainProduct, explainSum };
@@ -11,17 +11,17 @@ import { useControlSurface, useLearner } from "@classytic/stage";
11
11
 
12
12
  //#region src/discrete/sample-space/preset.tsx
13
13
  /**
14
- * SampleSpaceBoard — the GENERAL equally-likely-outcomes tool. Probability =
14
+ * SampleSpaceBoard, the GENERAL equally-likely-outcomes tool. Probability =
15
15
  * count the favourable slice of all equally-likely outcomes; this makes that
16
16
  * literal: every outcome is a cell, the learner SELECTS an event, and reads
17
17
  * favourable / total → P. The two-dice 6×6 grid is the star (you SEE P(sum=7)
18
18
  * as a diagonal of 6 cells = 1/6).
19
19
  *
20
20
  * Two authoring forms:
21
- * • `dims` — a 1- or 2-D product space (one die [6], two dice [6,6], cards
21
+ * • `dims`, a 1- or 2-D product space (one die [6], two dice [6,6], cards
22
22
  * [4,13]); cells are coordinate pairs, events are reduce-based (sum/diff/
23
23
  * max/min/product/doubles) so they stay DATA, not code.
24
- * • `outcomes` — an explicit 1-D list (coins HHT…, custom); event = a named
24
+ * • `outcomes`, an explicit 1-D list (coins HHT…, custom); event = a named
25
25
  * favourable set.
26
26
  * Counts/P come from `@classytic/labs/discrete/core`; an agent narrates them.
27
27
  */
@@ -361,7 +361,7 @@ function SampleSpaceBoardLab({ dims, faces, dice, outcomes, event, mode: mode0,
361
361
  children: "Check"
362
362
  }), checked && /* @__PURE__ */ jsx(StatusPill, {
363
363
  ok: correct,
364
- children: correct ? "✓ Exactly the event" : "Not quite — green outlines are the ones you missed"
364
+ children: correct ? "✓ Exactly the event" : "Not quite, green outlines are the ones you missed"
365
365
  })] }),
366
366
  !isTarget && sel.size > 0 && /* @__PURE__ */ jsx(Chip, {
367
367
  selected: true,
@@ -5,13 +5,14 @@ import { CheckButton, Chip, StatusPill, Stepper } from "../../kit/controls.mjs";
5
5
  import { Callout, ControlBar, Field, LabFrame } from "../../kit/frame.mjs";
6
6
  import { HintLadder, RevealSolution, useCheckpoint, useHints } from "../../kit/pedagogy.mjs";
7
7
  import { nCr } from "../core/combinatorics.mjs";
8
+ import { CATEGORICAL } from "../../kit/palette.mjs";
8
9
  import { useMemo, useState } from "react";
9
10
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
10
11
  import { useControlSurface } from "@classytic/stage";
11
12
 
12
13
  //#region src/discrete/selection/preset.tsx
13
14
  /**
14
- * SelectionLab — "draw from the bag": counting (and probability) when you SELECT a
15
+ * SelectionLab, "draw from the bag": counting (and probability) when you SELECT a
15
16
  * handful from groups, the pattern behind colored-ball urns and card hands. Pick how
16
17
  * many of each colour you want in the draw; the lab counts the favourable selections
17
18
  * as a product of per-group choices and divides by the total selections:
@@ -22,14 +23,7 @@ import { useControlSurface } from "@classytic/stage";
22
23
  * hands (13 hearts of 52, draw 5 → P(2 hearts)). Concrete: the bag is drawn as real
23
24
  * balls. Predict the count, then check. Kernel = nCr (the combination is the engine).
24
25
  */
25
- const PALETTE = [
26
- "#e03131",
27
- "#1c7ed6",
28
- "#2f9e44",
29
- "#f59f00",
30
- "#9c36b5",
31
- "#0ca678"
32
- ];
26
+ const PALETTE = CATEGORICAL;
33
27
  const NAMED = {
34
28
  red: "#e03131",
35
29
  blue: "#1c7ed6",
@@ -145,7 +139,7 @@ function SelectionLab({ groups = [
145
139
  /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsxs("p", {
146
140
  className: "lab-field-label",
147
141
  children: [
148
- "the bag — ",
142
+ "the bag, ",
149
143
  N,
150
144
  " total"
151
145
  ]
@@ -200,7 +194,7 @@ function SelectionLab({ groups = [
200
194
  children: [
201
195
  "draw ",
202
196
  k,
203
- " — you want: ",
197
+ ", you want: ",
204
198
  groups.map((g, i) => `${pick[i] ?? 0} ${g.label}`).join(" + ")
205
199
  ]
206
200
  }), /* @__PURE__ */ jsxs("div", {
@@ -263,7 +257,7 @@ function SelectionLab({ groups = [
263
257
  fontSize: 14
264
258
  },
265
259
  children: [
266
- "Set how many of each colour to draw — they must add up to ",
260
+ "Set how many of each colour to draw, they must add up to ",
267
261
  k,
268
262
  "."
269
263
  ]
@@ -288,7 +282,7 @@ function SelectionLab({ groups = [
288
282
  }),
289
283
  /* @__PURE__ */ jsx("span", {
290
284
  className: "lab-callout-big",
291
- children: mode === "probability" ? valid ? frac(prob) : "—" : ways.toLocaleString()
285
+ children: mode === "probability" ? valid ? frac(prob) : ", " : ways.toLocaleString()
292
286
  }),
293
287
  /* @__PURE__ */ jsxs("span", {
294
288
  style: {