@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
@@ -1,6 +1,8 @@
1
1
  import { RegressionLab } from "../ml/regression/preset.mjs";
2
2
  import { KMeansLab } from "../ml/kmeans/preset.mjs";
3
3
  import { ClassifierThresholdLab } from "../ml/classifier/preset.mjs";
4
+ import { DecisionBoundaryLab } from "../ml/boundary/preset.mjs";
5
+ import { KNNBoundaryLab } from "../ml/knn/preset.mjs";
4
6
  import { z } from "zod";
5
7
 
6
8
  //#region src/blocks/ml.d.ts
@@ -40,6 +42,27 @@ declare const ClassifierThresholdBlock: import("@classytic/cms-ui/contract").Cms
40
42
  title: z.ZodOptional<z.ZodString>;
41
43
  prompt: z.ZodOptional<z.ZodString>;
42
44
  }, z.core.$strip>>;
45
+ declare const DecisionBoundaryBlock: import("@classytic/cms-ui/contract").CmsBlock<z.ZodObject<{
46
+ dataset: z.ZodDefault<z.ZodEnum<{
47
+ xor: "xor";
48
+ separable: "separable";
49
+ overlap: "overlap";
50
+ }>>;
51
+ seed: z.ZodDefault<z.ZodNumber>;
52
+ title: z.ZodOptional<z.ZodString>;
53
+ prompt: z.ZodOptional<z.ZodString>;
54
+ }, z.core.$strip>>;
55
+ declare const KnnBoundaryBlock: import("@classytic/cms-ui/contract").CmsBlock<z.ZodObject<{
56
+ dataset: z.ZodDefault<z.ZodEnum<{
57
+ xor: "xor";
58
+ blobs: "blobs";
59
+ circles: "circles";
60
+ }>>;
61
+ k: z.ZodDefault<z.ZodNumber>;
62
+ seed: z.ZodDefault<z.ZodNumber>;
63
+ title: z.ZodOptional<z.ZodString>;
64
+ prompt: z.ZodOptional<z.ZodString>;
65
+ }, z.core.$strip>>;
43
66
  /** This domain's block specs + tag→component render map. */
44
67
  declare const mlBlocks: readonly [import("@classytic/cms-ui/contract").CmsBlock<z.ZodObject<{
45
68
  data: z.ZodOptional<z.ZodArray<z.ZodObject<{
@@ -74,11 +97,32 @@ declare const mlBlocks: readonly [import("@classytic/cms-ui/contract").CmsBlock<
74
97
  span: z.ZodDefault<z.ZodNumber>;
75
98
  title: z.ZodOptional<z.ZodString>;
76
99
  prompt: z.ZodOptional<z.ZodString>;
100
+ }, z.core.$strip>>, import("@classytic/cms-ui/contract").CmsBlock<z.ZodObject<{
101
+ dataset: z.ZodDefault<z.ZodEnum<{
102
+ xor: "xor";
103
+ separable: "separable";
104
+ overlap: "overlap";
105
+ }>>;
106
+ seed: z.ZodDefault<z.ZodNumber>;
107
+ title: z.ZodOptional<z.ZodString>;
108
+ prompt: z.ZodOptional<z.ZodString>;
109
+ }, z.core.$strip>>, import("@classytic/cms-ui/contract").CmsBlock<z.ZodObject<{
110
+ dataset: z.ZodDefault<z.ZodEnum<{
111
+ xor: "xor";
112
+ blobs: "blobs";
113
+ circles: "circles";
114
+ }>>;
115
+ k: z.ZodDefault<z.ZodNumber>;
116
+ seed: z.ZodDefault<z.ZodNumber>;
117
+ title: z.ZodOptional<z.ZodString>;
118
+ prompt: z.ZodOptional<z.ZodString>;
77
119
  }, z.core.$strip>>];
78
120
  declare const mlComponents: {
79
121
  readonly Regression: typeof RegressionLab;
80
122
  readonly KMeans: typeof KMeansLab;
81
123
  readonly ClassifierThreshold: typeof ClassifierThresholdLab;
124
+ readonly DecisionBoundary: typeof DecisionBoundaryLab;
125
+ readonly KnnBoundary: typeof KNNBoundaryLab;
82
126
  };
83
127
  //#endregion
84
- export { ClassifierThresholdBlock, KMeansBlock, RegressionBlock, mlBlocks, mlComponents };
128
+ export { ClassifierThresholdBlock, DecisionBoundaryBlock, KMeansBlock, KnnBoundaryBlock, RegressionBlock, mlBlocks, mlComponents };
@@ -1,6 +1,8 @@
1
1
  import { RegressionLab } from "../ml/regression/preset.mjs";
2
2
  import { KMeansLab } from "../ml/kmeans/preset.mjs";
3
3
  import { ClassifierThresholdLab } from "../ml/classifier/preset.mjs";
4
+ import { DecisionBoundaryLab } from "../ml/boundary/preset.mjs";
5
+ import { KNNBoundaryLab } from "../ml/knn/preset.mjs";
4
6
  import { LabConfig } from "./lab-config.mjs";
5
7
  import { jsx, jsxs } from "react/jsx-runtime";
6
8
  import { z } from "zod";
@@ -8,10 +10,10 @@ import { defineBlock } from "@classytic/cms-ui/contract";
8
10
 
9
11
  //#region src/blocks/ml.tsx
10
12
  /**
11
- * @classytic/labs/blocks — machine-learning / data-analytics lab block specs.
13
+ * @classytic/labs/blocks, machine-learning / data-analytics lab block specs.
12
14
  *
13
15
  * `defineBlock` editor adapters for the ML labs. REFERENCE for the schema-driven
14
- * authoring panel: the editor config is just `<LabConfig schema={…}>` — one
16
+ * authoring panel: the editor config is just `<LabConfig schema={…}>`, one
15
17
  * Zod-driven panel renders every prop, so there's no hand-built ConfigRow list to
16
18
  * maintain. Hoist each block's schema to a const so it backs BOTH `defineBlock`
17
19
  * and the panel. One domain per file; exported at `@classytic/labs/blocks/ml`.
@@ -110,7 +112,7 @@ const ClassifierThresholdBlock = defineBlock({
110
112
  tag: "ClassifierThreshold",
111
113
  void: true,
112
114
  label: "Classification threshold (precision/recall)",
113
- description: "The precision–recall trade-off, draggable: positive and negative examples overlap on a score axis; slide the threshold and the 2×2 confusion matrix + precision/recall/accuracy/F1 update live — pushing precision up costs recall. Author the two score sets.",
115
+ description: "The precision–recall trade-off, draggable: positive and negative examples overlap on a score axis; slide the threshold and the 2×2 confusion matrix + precision/recall/accuracy/F1 update live, pushing precision up costs recall. Author the two score sets.",
114
116
  category: "interactive",
115
117
  schema: classifierSchema,
116
118
  Component: ({ attributes, mode, updateAttributes }) => {
@@ -130,17 +132,89 @@ const ClassifierThresholdBlock = defineBlock({
130
132
  }), widget] });
131
133
  }
132
134
  });
135
+ const boundarySchema = z.object({
136
+ dataset: z.enum([
137
+ "separable",
138
+ "overlap",
139
+ "xor"
140
+ ]).default("separable"),
141
+ seed: z.number().int().default(11),
142
+ title: z.string().optional(),
143
+ prompt: z.string().optional()
144
+ });
145
+ const DecisionBoundaryBlock = defineBlock({
146
+ key: "decision-boundary",
147
+ tag: "DecisionBoundary",
148
+ void: true,
149
+ label: "Linear decision boundary (perceptron)",
150
+ description: "A linear classifier you can see think: drag the boundary’s two handles to split two classes by hand (misclassified points get a red ring, accuracy updates live), then hit train and watch a perceptron nudge the line into place itself. The honest twist: the XOR dataset can’t be split by any straight line. Author the dataset + seed.",
151
+ category: "interactive",
152
+ schema: boundarySchema,
153
+ Component: ({ attributes, mode, updateAttributes }) => {
154
+ const widget = /* @__PURE__ */ jsx(DecisionBoundaryLab, {
155
+ dataset: attributes.dataset,
156
+ seed: attributes.seed,
157
+ title: attributes.title,
158
+ prompt: attributes.prompt
159
+ });
160
+ if (mode !== "editing" || !updateAttributes) return widget;
161
+ return /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx(LabConfig, {
162
+ schema: boundarySchema,
163
+ value: attributes,
164
+ onChange: updateAttributes
165
+ }), widget] });
166
+ }
167
+ });
168
+ const knnSchema = z.object({
169
+ dataset: z.enum([
170
+ "blobs",
171
+ "xor",
172
+ "circles"
173
+ ]).default("circles"),
174
+ k: z.number().int().min(1).max(15).default(5),
175
+ seed: z.number().int().default(7),
176
+ title: z.string().optional(),
177
+ prompt: z.string().optional()
178
+ });
179
+ const KnnBoundaryBlock = defineBlock({
180
+ key: "knn",
181
+ tag: "KnnBoundary",
182
+ void: true,
183
+ label: "k-nearest neighbours boundary",
184
+ description: "The answer to “a line can’t split XOR”: k-NN paints the whole plane by majority vote of each point’s k closest labelled neighbours, carving a curvy boundary that shrugs off XOR and concentric rings. Drag the test point to see its neighbours vote; slide k to feel overfit (k=1, jagged) vs oversmooth (big k). Author the dataset + k.",
185
+ category: "interactive",
186
+ schema: knnSchema,
187
+ Component: ({ attributes, mode, updateAttributes }) => {
188
+ const widget = /* @__PURE__ */ jsx(KNNBoundaryLab, {
189
+ dataset: attributes.dataset,
190
+ k: attributes.k,
191
+ seed: attributes.seed,
192
+ title: attributes.title,
193
+ prompt: attributes.prompt
194
+ });
195
+ if (mode !== "editing" || !updateAttributes) return widget;
196
+ return /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx(LabConfig, {
197
+ schema: knnSchema,
198
+ value: attributes,
199
+ onChange: updateAttributes
200
+ }), widget] });
201
+ }
202
+ });
133
203
  /** This domain's block specs + tag→component render map. */
134
204
  const mlBlocks = [
135
205
  RegressionBlock,
136
206
  KMeansBlock,
137
- ClassifierThresholdBlock
207
+ ClassifierThresholdBlock,
208
+ DecisionBoundaryBlock,
209
+ KnnBoundaryBlock
138
210
  ];
139
211
  const mlComponents = {
140
212
  Regression: RegressionLab,
141
213
  KMeans: KMeansLab,
142
- ClassifierThreshold: ClassifierThresholdLab
214
+ ClassifierThreshold: ClassifierThresholdLab,
215
+ DecisionBoundary: DecisionBoundaryLab,
216
+ KnnBoundary: KNNBoundaryLab
143
217
  };
144
218
 
145
219
  //#endregion
146
- export { ClassifierThresholdBlock, KMeansBlock, RegressionBlock, mlBlocks, mlComponents };
220
+ export { ClassifierThresholdBlock, DecisionBoundaryBlock, KMeansBlock, KnnBoundaryBlock, RegressionBlock, mlBlocks, mlComponents };
@@ -58,9 +58,9 @@ declare const VectorBoardBlock: import("@classytic/cms-ui/contract").CmsBlock<z.
58
58
  drag: z.ZodOptional<z.ZodBoolean>;
59
59
  }, z.core.$strip>>>;
60
60
  combine: z.ZodDefault<z.ZodEnum<{
61
- none: "none";
62
61
  sum: "sum";
63
62
  diff: "diff";
63
+ none: "none";
64
64
  }>>;
65
65
  goalX: z.ZodOptional<z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>>;
66
66
  goalY: z.ZodOptional<z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>>;
@@ -152,6 +152,11 @@ declare const EntropyBlock: LabBlock;
152
152
  declare const TemperatureScalesBlock: LabBlock;
153
153
  declare const WaterDensityBlock: LabBlock;
154
154
  declare const EfficiencyBlock: LabBlock;
155
+ declare const ElectricFieldBlock: LabBlock;
156
+ declare const ElectricFluxBlock: LabBlock;
157
+ declare const GaussLawBlock: LabBlock;
158
+ declare const WorkEnergyBlock: LabBlock;
159
+ declare const WorkPotentialBlock: LabBlock;
155
160
  declare const physicsBlocks: readonly [import("@classytic/cms-ui/contract").CmsBlock<z.ZodObject<{
156
161
  targetMeters: z.ZodOptional<z.ZodNumber>;
157
162
  g: z.ZodOptional<z.ZodNumber>;
@@ -176,9 +181,9 @@ declare const physicsBlocks: readonly [import("@classytic/cms-ui/contract").CmsB
176
181
  drag: z.ZodOptional<z.ZodBoolean>;
177
182
  }, z.core.$strip>>>;
178
183
  combine: z.ZodDefault<z.ZodEnum<{
179
- none: "none";
180
184
  sum: "sum";
181
185
  diff: "diff";
186
+ none: "none";
182
187
  }>>;
183
188
  goalX: z.ZodOptional<z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>>;
184
189
  goalY: z.ZodOptional<z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>>;
@@ -240,7 +245,7 @@ declare const physicsBlocks: readonly [import("@classytic/cms-ui/contract").CmsB
240
245
  showCenterOfMass: z.ZodDefault<z.ZodBoolean>;
241
246
  title: z.ZodOptional<z.ZodString>;
242
247
  prompt: z.ZodOptional<z.ZodString>;
243
- }, z.core.$strip>>, LabBlock, LabBlock, LabBlock, LabBlock, LabBlock, LabBlock, LabBlock, LabBlock, LabBlock, LabBlock, LabBlock, LabBlock, LabBlock, LabBlock, LabBlock, LabBlock, LabBlock, LabBlock, LabBlock, LabBlock, LabBlock, LabBlock, LabBlock, LabBlock];
248
+ }, z.core.$strip>>, LabBlock, LabBlock, LabBlock, LabBlock, LabBlock, LabBlock, LabBlock, LabBlock, LabBlock, LabBlock, LabBlock, LabBlock, LabBlock, LabBlock, LabBlock, LabBlock, LabBlock, LabBlock, LabBlock, LabBlock, LabBlock, LabBlock, LabBlock, LabBlock, LabBlock, LabBlock, LabBlock, LabBlock, LabBlock];
244
249
  declare const physicsComponents: {
245
250
  VectorBoard: typeof VectorBoardView;
246
251
  VectorTypes: typeof VectorTypesLab;
@@ -256,4 +261,4 @@ declare const physicsComponents: {
256
261
  GravityDrop: typeof GravityDrop;
257
262
  };
258
263
  //#endregion
259
- export { AtwoodBlock, BulletWallsBlock, CarnotBlock, CircularMotionBlock, CollisionTrackBlock, DopplerBlock, EfficiencyBlock, EnergySkateBlock, EntropyBlock, GasProcessBlock, GravitationBlock, GravityDropBlock, HeatTransferBlock, HeatingCurveBlock, ImpulseBlock, KeplerBlock, LeverBlock, LeverPuzzle, LorentzBlock, MagnetismBlock, OpticsBlock, OrbitLabBlock, ProjectileLabBlock, RainRelativeBlock, RampForcesBlock, RippleTankBlock, RiverBoatBlock, SimpleHarmonicBlock, StoppingDistanceBlock, StringReflectionBlock, TemperatureScalesBlock, TerminalVelocityBlock, ThermalExpansionBlock, VectorBoardBlock, VectorTypesBlock, WaterDensityBlock, WaveBlock, physicsBlocks, physicsComponents };
264
+ export { AtwoodBlock, BulletWallsBlock, CarnotBlock, CircularMotionBlock, CollisionTrackBlock, DopplerBlock, EfficiencyBlock, ElectricFieldBlock, ElectricFluxBlock, EnergySkateBlock, EntropyBlock, GasProcessBlock, GaussLawBlock, GravitationBlock, GravityDropBlock, HeatTransferBlock, HeatingCurveBlock, ImpulseBlock, KeplerBlock, LeverBlock, LeverPuzzle, LorentzBlock, MagnetismBlock, OpticsBlock, OrbitLabBlock, ProjectileLabBlock, RainRelativeBlock, RampForcesBlock, RippleTankBlock, RiverBoatBlock, SimpleHarmonicBlock, StoppingDistanceBlock, StringReflectionBlock, TemperatureScalesBlock, TerminalVelocityBlock, ThermalExpansionBlock, VectorBoardBlock, VectorTypesBlock, WaterDensityBlock, WaveBlock, WorkEnergyBlock, WorkPotentialBlock, physicsBlocks, physicsComponents };
@@ -23,7 +23,12 @@ import { RippleTankLab } from "../physics/waves/ripple.mjs";
23
23
  import { DopplerLab } from "../physics/waves/doppler.mjs";
24
24
  import { StringReflectionLab } from "../physics/waves/string.mjs";
25
25
  import { MagnetismLab } from "../physics/magnetism/preset.mjs";
26
+ import { ElectricFieldLab } from "../physics/electric-field/preset.mjs";
27
+ import { ElectricFluxLab } from "../physics/electric-flux/preset.mjs";
28
+ import { GaussLab } from "../physics/gauss-law/preset.mjs";
29
+ import { WorkPotentialLab } from "../physics/work-potential/preset.mjs";
26
30
  import { LorentzForceLab } from "../physics/lorentz/preset.mjs";
31
+ import { WorkEnergyLab } from "../physics/work-energy/preset.mjs";
27
32
  import { HeatingCurveLab } from "../physics/thermal/preset.mjs";
28
33
  import { HeatTransferLab } from "../physics/heat-transfer/preset.mjs";
29
34
  import { ThermalExpansionLab } from "../physics/expansion/preset.mjs";
@@ -46,7 +51,7 @@ const ProjectileLabBlock = defineBlock({
46
51
  key: "projectile-lab",
47
52
  void: true,
48
53
  label: "Projectile lab",
49
- description: "Interactive projectile motion — tune angle & speed, hit a target.",
54
+ description: "Interactive projectile motion, tune angle & speed, hit a target.",
50
55
  category: "interactive",
51
56
  schema: z.object({
52
57
  targetMeters: z.number().optional(),
@@ -61,7 +66,7 @@ const OrbitLabBlock = defineBlock({
61
66
  key: "orbit-lab",
62
67
  void: true,
63
68
  label: "Orbit lab",
64
- description: "Interactive orbit — launch a satellite: crash, orbit, or escape.",
69
+ description: "Interactive orbit, launch a satellite: crash, orbit, or escape.",
65
70
  category: "interactive",
66
71
  schema: z.object({}),
67
72
  Component: () => /* @__PURE__ */ jsx(OrbitLab, {})
@@ -70,7 +75,7 @@ const GravityDropBlock = defineBlock({
70
75
  key: "gravity-drop",
71
76
  void: true,
72
77
  label: "Gravity drop",
73
- description: "Drop balls on three worlds — compare how gravity changes the fall.",
78
+ description: "Drop balls on three worlds, compare how gravity changes the fall.",
74
79
  category: "interactive",
75
80
  schema: z.object({ height: z.number().optional() }),
76
81
  Component: ({ attributes }) => /* @__PURE__ */ jsx(GravityDrop, { height: attributes.height })
@@ -79,7 +84,7 @@ const RiverBoatBlock = defineBlock({
79
84
  key: "river-boat",
80
85
  void: true,
81
86
  label: "River crossing (vectors)",
82
- description: "Boat-and-river vector problem — step through tip-to-tail addition + component resolution.",
87
+ description: "Boat-and-river vector problem, step through tip-to-tail addition + component resolution.",
83
88
  category: "interactive",
84
89
  schema: z.object({
85
90
  boatSpeed: z.number().optional(),
@@ -158,7 +163,7 @@ const OpticsBlock = defineBlock({
158
163
  schema: z.object({}),
159
164
  Component: ({ mode }) => mode === "editing" ? /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx(ConfigPanel, { children: /* @__PURE__ */ jsx("span", {
160
165
  style: { opacity: .7 },
161
- children: "No settings — drag the source, aim, or mirrors in the lesson."
166
+ children: "No settings, drag the source, aim, or mirrors in the lesson."
162
167
  }) }), /* @__PURE__ */ jsx(OpticsLab, {})] }) : /* @__PURE__ */ jsx(OpticsLab, {})
163
168
  });
164
169
  const LeverBlock = defineBlock({
@@ -166,7 +171,7 @@ const LeverBlock = defineBlock({
166
171
  tag: "Lever",
167
172
  void: true,
168
173
  label: "Lever (balance the torque)",
169
- description: "A known weight at a distance vs an unknown — set the unknown so turning effects match.",
174
+ description: "A known weight at a distance vs an unknown, set the unknown so turning effects match.",
170
175
  category: "interactive",
171
176
  schema: z.object({
172
177
  knownWeight: z.number().default(4),
@@ -382,7 +387,7 @@ const RainRelativeBlock = defineBlock({
382
387
  tag: "RainRelative",
383
388
  void: true,
384
389
  label: "Rain on a moving car (relative velocity)",
385
- description: "Animated rain that slants as the car speeds up — apparent velocity V_rain − V_car, with a live triangle + angle.",
390
+ description: "Animated rain that slants as the car speeds up, apparent velocity V_rain − V_car, with a live triangle + angle.",
386
391
  category: "interactive",
387
392
  schema: z.object({
388
393
  maxSpeed: z.number().default(10),
@@ -525,7 +530,7 @@ const RampForcesBlock = defineBlock({
525
530
  })
526
531
  }),
527
532
  /* @__PURE__ */ jsx(ConfigRow, {
528
- label: "controls — e.g. { \"hide\": [\"mass\"], \"lock\": [\"angle\"] }",
533
+ label: "controls: e.g. { \"hide\": [\"mass\"], \"lock\": [\"angle\"] }",
529
534
  children: /* @__PURE__ */ jsx(JsonArea, {
530
535
  value: attributes.controls ?? {},
531
536
  onChange: (v) => updateAttributes({ controls: v }),
@@ -637,7 +642,7 @@ const stringSchema = z.object({
637
642
  });
638
643
  const StringReflectionBlock = wlab("string-reflection", "Reflection & standing waves on a string", "A pulse reflects (fixed end inverts, free end upright); a continuous wave + its reflection lock into a standing wave at the resonant harmonics fₙ=n·c/2L.", stringSchema, (a) => /* @__PURE__ */ jsx(StringReflectionLab, { ...a }));
639
644
  const magnetismSchema = z.object({ ...common });
640
- const MagnetismBlock = wlab("magnetism", "Magnetism — field lines & compass", "Drag a bar magnet (or switch to a current-carrying wire); the field lines retrace live and a draggable compass needle aligns to the field.", magnetismSchema, (a) => /* @__PURE__ */ jsx(MagnetismLab, { ...a }));
645
+ const MagnetismBlock = wlab("magnetism", "Magnetism, field lines & compass", "Drag a bar magnet (or switch to a current-carrying wire); the field lines retrace live and a draggable compass needle aligns to the field.", magnetismSchema, (a) => /* @__PURE__ */ jsx(MagnetismLab, { ...a }));
641
646
  const lorentzSchema = z.object({
642
647
  charge: z.union([z.literal(1), z.literal(-1)]).optional(),
643
648
  fieldOut: z.boolean().optional(),
@@ -653,7 +658,7 @@ const impulseSchema = z.object({
653
658
  crackForce: z.number().optional(),
654
659
  ...common
655
660
  });
656
- const ImpulseBlock = wlab("impulse", "Impulse — catch the egg (J = F·Δt = Δp)", "Same ball, same speed → fixed impulse. Stretch the contact time and the force–time pulse morphs from a tall spike to a low bump with EQUAL shaded area, so the peak force plummets. A fragile egg cracks above its force limit — the number behind airbags, crumple zones and bending your knees.", impulseSchema, (a) => /* @__PURE__ */ jsx(ImpulseLab, { ...a }));
661
+ const ImpulseBlock = wlab("impulse", "Impulse, catch the egg (J = F·Δt = Δp)", "Same ball, same speed → fixed impulse. Stretch the contact time and the force–time pulse morphs from a tall spike to a low bump with EQUAL shaded area, so the peak force plummets. A fragile egg cracks above its force limit, the number behind airbags, crumple zones and bending your knees.", impulseSchema, (a) => /* @__PURE__ */ jsx(ImpulseLab, { ...a }));
657
662
  const bulletWallsSchema = z.object({
658
663
  speed: z.number().optional(),
659
664
  toughness: z.number().optional(),
@@ -673,7 +678,7 @@ const circularSchema = z.object({
673
678
  controlConfig: ccSchema,
674
679
  ...common
675
680
  });
676
- const CircularMotionBlock = wlab("circular-motion", "Circular motion — centripetal force & cut the string", "A ball whirls on a string: velocity stays tangent while the tension (centripetal force F = mv²/r) points to the centre, bending the path without changing speed. Cut the string and it flies off along the TANGENT — not radially outward — killing the classic misconception. Live F, ω and period.", circularSchema, (a) => /* @__PURE__ */ jsx(CircularMotionLab, { ...a }));
681
+ const CircularMotionBlock = wlab("circular-motion", "Circular motion, centripetal force & cut the string", "A ball whirls on a string: velocity stays tangent while the tension (centripetal force F = mv²/r) points to the centre, bending the path without changing speed. Cut the string and it flies off along the TANGENT, not radially outward, killing the classic misconception. Live F, ω and period.", circularSchema, (a) => /* @__PURE__ */ jsx(CircularMotionLab, { ...a }));
677
682
  const energySkateSchema = z.object({
678
683
  startHeight: z.number().optional(),
679
684
  friction: z.boolean().optional(),
@@ -681,7 +686,7 @@ const energySkateSchema = z.object({
681
686
  controlConfig: ccSchema,
682
687
  ...common
683
688
  });
684
- const EnergySkateBlock = wlab("energy-skate", "Energy skate park — KE ⇄ PE (+ heat)", "A skater released on a ramp: potential, kinetic and thermal bars always sum to the same total. Friction off → it returns to the same height forever; friction on → the heat bar grows and every peak is lower. Energy conservation and conversion, animated (the LOL bar chart).", energySkateSchema, (a) => /* @__PURE__ */ jsx(EnergySkateLab, { ...a }));
689
+ const EnergySkateBlock = wlab("energy-skate", "Energy skate park, KE ⇄ PE (+ heat)", "A skater released on a ramp: potential, kinetic and thermal bars always sum to the same total. Friction off → it returns to the same height forever; friction on → the heat bar grows and every peak is lower. Energy conservation and conversion, animated (the LOL bar chart).", energySkateSchema, (a) => /* @__PURE__ */ jsx(EnergySkateLab, { ...a }));
685
690
  const shmSchema = z.object({
686
691
  mode: z.enum(["spring", "pendulum"]).optional(),
687
692
  k: z.number().optional(),
@@ -691,13 +696,13 @@ const shmSchema = z.object({
691
696
  controlConfig: ccSchema,
692
697
  ...common
693
698
  });
694
- const SimpleHarmonicBlock = wlab("shm", "Simple harmonic motion — spring & pendulum", "One a = −ω²x kernel, two skins. A restoring force ∝ displacement gives x(t) = A·cos(ωt), and a pen traces it out as a SINE — the bridge to the waves lessons. Spring: ω=√(k/m). Pendulum: ω=√(g/L), with the period independent of mass and amplitude. Live ω/T/f and a PE⇄KE energy split.", shmSchema, (a) => /* @__PURE__ */ jsx(SimpleHarmonicLab, { ...a }), "SimpleHarmonic");
699
+ const SimpleHarmonicBlock = wlab("shm", "Simple harmonic motion, spring & pendulum", "One a = −ω²x kernel, two skins. A restoring force ∝ displacement gives x(t) = A·cos(ωt), and a pen traces it out as a SINE, the bridge to the waves lessons. Spring: ω=√(k/m). Pendulum: ω=√(g/L), with the period independent of mass and amplitude. Live ω/T/f and a PE⇄KE energy split.", shmSchema, (a) => /* @__PURE__ */ jsx(SimpleHarmonicLab, { ...a }), "SimpleHarmonic");
695
700
  const atwoodSchema = z.object({
696
701
  m1: z.number().optional(),
697
702
  m2: z.number().optional(),
698
703
  ...common
699
704
  });
700
- const AtwoodBlock = wlab("atwood", "Atwood machine — two masses over a pulley", "Two masses share one rope over a pulley. Only the difference in weight drives the system while the total mass resists it: a = (m₁−m₂)g/(m₁+m₂), tension T = 2m₁m₂g/(m₁+m₂). Equal masses balance; a tiny difference on big masses gives a slow, measurable a — how Atwood weighed gravity. Predict which side falls, then release.", atwoodSchema, (a) => /* @__PURE__ */ jsx(AtwoodLab, { ...a }));
705
+ const AtwoodBlock = wlab("atwood", "Atwood machine, two masses over a pulley", "Two masses share one rope over a pulley. Only the difference in weight drives the system while the total mass resists it: a = (m₁−m₂)g/(m₁+m₂), tension T = 2m₁m₂g/(m₁+m₂). Equal masses balance; a tiny difference on big masses gives a slow, measurable a, how Atwood weighed gravity. Predict which side falls, then release.", atwoodSchema, (a) => /* @__PURE__ */ jsx(AtwoodLab, { ...a }));
701
706
  const terminalSchema = z.object({
702
707
  mass: z.number().optional(),
703
708
  drag: z.number().optional(),
@@ -705,7 +710,7 @@ const terminalSchema = z.object({
705
710
  controlConfig: ccSchema,
706
711
  ...common
707
712
  });
708
- const TerminalVelocityBlock = wlab("terminal-velocity", "Terminal velocity — the skydiver (air drag)", "A fall with air resistance: drag grows with speed (∝v²) until it balances gravity, so the speed levels off at v_t = √(mg/b). The weight arrow stays fixed while the drag arrow rises to meet it and the v–t curve flattens onto its asymptote (exact tanh solution). Pop the parachute and v_t collapses to a survivable speed.", terminalSchema, (a) => /* @__PURE__ */ jsx(TerminalVelocityLab, { ...a }));
713
+ const TerminalVelocityBlock = wlab("terminal-velocity", "Terminal velocity, the skydiver (air drag)", "A fall with air resistance: drag grows with speed (∝v²) until it balances gravity, so the speed levels off at v_t = √(mg/b). The weight arrow stays fixed while the drag arrow rises to meet it and the v–t curve flattens onto its asymptote (exact tanh solution). Pop the parachute and v_t collapses to a survivable speed.", terminalSchema, (a) => /* @__PURE__ */ jsx(TerminalVelocityLab, { ...a }));
709
714
  const keplerSchema = z.object({
710
715
  semiMajor: z.number().optional(),
711
716
  eccentricity: z.number().optional(),
@@ -713,13 +718,13 @@ const keplerSchema = z.object({
713
718
  controlConfig: ccSchema,
714
719
  ...common
715
720
  });
716
- const KeplerBlock = wlab("kepler", "Kepler’s laws — orbits & equal areas", "A planet on a true ellipse with the star at a focus (Kepler 1). Solving Kepler’s equation makes it genuinely speed up at perihelion, and the equal-time wedges it sweeps come out equal in area (Kepler 2) — fat-and-short near the star, thin-and-long far out. Stretch the orbit and the period grows as T² ∝ a³ (Kepler 3).", keplerSchema, (a) => /* @__PURE__ */ jsx(KeplerLab, { ...a }));
721
+ const KeplerBlock = wlab("kepler", "Kepler’s laws, orbits & equal areas", "A planet on a true ellipse with the star at a focus (Kepler 1). Solving Kepler’s equation makes it genuinely speed up at perihelion, and the equal-time wedges it sweeps come out equal in area (Kepler 2), fat-and-short near the star, thin-and-long far out. Stretch the orbit and the period grows as T² ∝ a³ (Kepler 3).", keplerSchema, (a) => /* @__PURE__ */ jsx(KeplerLab, { ...a }));
717
722
  const gravitationSchema = z.object({
718
723
  planetMass: z.number().optional(),
719
724
  satMass: z.number().optional(),
720
725
  ...common
721
726
  });
722
- const GravitationBlock = wlab("gravitation", "Universal gravitation — the inverse-square law", "Newton’s F = G·M·m / r². Drag the satellite and the pull tracks 1/r²: double the distance and the force drops to a quarter (not a half). A live F–r curve marks your spot on the steep fall-off; the same law thins weight with altitude (g = GM/r²) and sets orbital speed v = √(GM/r).", gravitationSchema, (a) => /* @__PURE__ */ jsx(GravitationLab, { ...a }));
727
+ const GravitationBlock = wlab("gravitation", "Universal gravitation, the inverse-square law", "Newton’s F = G·M·m / r². Drag the satellite and the pull tracks 1/r²: double the distance and the force drops to a quarter (not a half). A live F–r curve marks your spot on the steep fall-off; the same law thins weight with altitude (g = GM/r²) and sets orbital speed v = √(GM/r).", gravitationSchema, (a) => /* @__PURE__ */ jsx(GravitationLab, { ...a }));
723
728
  const heatTransferSchema = z.object({
724
729
  mode: z.enum([
725
730
  "conduction",
@@ -729,7 +734,7 @@ const heatTransferSchema = z.object({
729
734
  controlConfig: ccSchema,
730
735
  ...common
731
736
  });
732
- const HeatTransferBlock = wlab("heat-transfer", "Heat transfer — conduction / convection / radiation", "The three ways heat moves, each with its rate law and animation. Author a survey (all three) OR a focused lesson: set mode + controlConfig.hide=['mechanism'] to show conduction (or convection / radiation) on its own.", heatTransferSchema, (a) => /* @__PURE__ */ jsx(HeatTransferLab, { ...a }));
737
+ const HeatTransferBlock = wlab("heat-transfer", "Heat transfer, conduction / convection / radiation", "The three ways heat moves, each with its rate law and animation. Author a survey (all three) OR a focused lesson: set mode + controlConfig.hide=['mechanism'] to show conduction (or convection / radiation) on its own.", heatTransferSchema, (a) => /* @__PURE__ */ jsx(HeatTransferLab, { ...a }));
733
738
  const thermalExpansionSchema = z.object({
734
739
  mode: z.enum([
735
740
  "length",
@@ -740,7 +745,7 @@ const thermalExpansionSchema = z.object({
740
745
  controlConfig: ccSchema,
741
746
  ...common
742
747
  });
743
- const ThermalExpansionBlock = wlab("thermal-expansion", "Thermal expansion — length / area / volume / bimetallic", "Heat a solid and it grows: ΔL=αLΔT, ΔA=2αAΔT, ΔV=3αVΔT, plus a bimetallic-strip thermostat. Author one case (e.g. mode:'area', controlConfig.hide=['what expands']) or the full set.", thermalExpansionSchema, (a) => /* @__PURE__ */ jsx(ThermalExpansionLab, { ...a }));
748
+ const ThermalExpansionBlock = wlab("thermal-expansion", "Thermal expansion, length / area / volume / bimetallic", "Heat a solid and it grows: ΔL=αLΔT, ΔA=2αAΔT, ΔV=3αVΔT, plus a bimetallic-strip thermostat. Author one case (e.g. mode:'area', controlConfig.hide=['what expands']) or the full set.", thermalExpansionSchema, (a) => /* @__PURE__ */ jsx(ThermalExpansionLab, { ...a }));
744
749
  const heatingCurveSchema = z.object({
745
750
  substance: z.enum(["water", "ethanol"]).optional().describe("preset to start from"),
746
751
  substanceName: z.string().optional().describe("custom substance name (overrides the preset)"),
@@ -755,7 +760,7 @@ const heatingCurveSchema = z.object({
755
760
  power: z.number().optional().describe("initial heating power, W (negative cools)"),
756
761
  ...common
757
762
  });
758
- const HeatingCurveBlock = wlab("heating-curve", "Heating curve — q=mcΔθ runs + latent plateaus", "Pour heat into ice and watch temperature climb in steps: sloped runs where a phase warms (q=mcΔθ) and flat plateaus where it melts/boils (q=mL). Burner + beaker + thermometer beside the live curve. AUTHOR the model: pick a preset OR declare a custom substance (specific + latent heats, melt/boil points) and the starting mass/power.", heatingCurveSchema, (a) => /* @__PURE__ */ jsx(HeatingCurveLab, { ...a }));
763
+ const HeatingCurveBlock = wlab("heating-curve", "Heating curve, q=mcΔθ runs + latent plateaus", "Pour heat into ice and watch temperature climb in steps: sloped runs where a phase warms (q=mcΔθ) and flat plateaus where it melts/boils (q=mL). Burner + beaker + thermometer beside the live curve. AUTHOR the model: pick a preset OR declare a custom substance (specific + latent heats, melt/boil points) and the starting mass/power.", heatingCurveSchema, (a) => /* @__PURE__ */ jsx(HeatingCurveLab, { ...a }));
759
764
  const gasProcessSchema = z.object({
760
765
  kind: z.enum([
761
766
  "isothermal",
@@ -769,7 +774,7 @@ const gasProcessSchema = z.object({
769
774
  volumeL: z.number().optional().describe("initial volume, L"),
770
775
  ...common
771
776
  });
772
- const GasProcessBlock = wlab("gas-process", "Gas processes — work = area under P–V", "Expand/compress an ideal gas isothermally, adiabatically, isobarically or isochorically. The shaded area under the P–V curve is the work; the first law ΔU = Q − W balances every term. A faint reference isotherm shows the adiabatic falling steeper.", gasProcessSchema, (a) => /* @__PURE__ */ jsx(GasProcessLab, { ...a }));
777
+ const GasProcessBlock = wlab("gas-process", "Gas processes, work = area under P–V", "Expand/compress an ideal gas isothermally, adiabatically, isobarically or isochorically. The shaded area under the P–V curve is the work; the first law ΔU = Q − W balances every term. A faint reference isotherm shows the adiabatic falling steeper.", gasProcessSchema, (a) => /* @__PURE__ */ jsx(GasProcessLab, { ...a }));
773
778
  const carnotSchema = z.object({
774
779
  hotK: z.number().optional().describe("hot reservoir temperature, K"),
775
780
  coldK: z.number().optional().describe("cold reservoir temperature, K"),
@@ -777,19 +782,19 @@ const carnotSchema = z.object({
777
782
  expansionRatio: z.number().optional().describe("isothermal expansion V₂/V₁"),
778
783
  ...common
779
784
  });
780
- const CarnotBlock = wlab("carnot", "Carnot cycle — P–V loop + T–S rectangle", "The most efficient heat engine, shown as a P–V loop (enclosed area = net work) and the same cycle as a T–S rectangle (heat in at Th, out at Tc). Efficiency η = 1 − Tc/Th, with the entropy bookkeeping ΔS = Qh/Th = Qc/Tc → net 0.", carnotSchema, (a) => /* @__PURE__ */ jsx(CarnotCycleLab, { ...a }));
785
+ const CarnotBlock = wlab("carnot", "Carnot cycle, P–V loop + T–S rectangle", "The most efficient heat engine, shown as a P–V loop (enclosed area = net work) and the same cycle as a T–S rectangle (heat in at Th, out at Tc). Efficiency η = 1 − Tc/Th, with the entropy bookkeeping ΔS = Qh/Th = Qc/Tc → net 0.", carnotSchema, (a) => /* @__PURE__ */ jsx(CarnotCycleLab, { ...a }));
781
786
  const entropySchema = z.object({
782
787
  mode: z.enum(["heat", "expansion"]).optional(),
783
788
  ...common
784
789
  });
785
- const EntropyBlock = wlab("entropy", "Entropy & the 2nd law — the one-way arrow", "Why heat flows hot→cold (ΔS_total = Q/Tc − Q/Th > 0) and a gas spreads into a vacuum (ΔS = nR·ln Vf/Vi). The total entropy of the universe always increases. Two modes: heat flow and free expansion.", entropySchema, (a) => /* @__PURE__ */ jsx(EntropyLab, { ...a }));
790
+ const EntropyBlock = wlab("entropy", "Entropy & the 2nd law, the one-way arrow", "Why heat flows hot→cold (ΔS_total = Q/Tc − Q/Th > 0) and a gas spreads into a vacuum (ΔS = nR·ln Vf/Vi). The total entropy of the universe always increases. Two modes: heat flow and free expansion.", entropySchema, (a) => /* @__PURE__ */ jsx(EntropyLab, { ...a }));
786
791
  const tempScalesSchema = z.object({ ...common });
787
- const TemperatureScalesBlock = wlab("temperature-scales", "Temperature scales — °C / °F / K", "One mercury column read against Celsius, Fahrenheit and Kelvin at once (F = 9⁄5·C + 32, K = C + 273.15). Fixed points marked; jump to absolute zero, ice, body, boiling. Shows why Kelvin starts at absolute zero.", tempScalesSchema, (a) => /* @__PURE__ */ jsx(TemperatureScalesLab, { ...a }));
792
+ const TemperatureScalesBlock = wlab("temperature-scales", "Temperature scales, °C / °F / K", "One mercury column read against Celsius, Fahrenheit and Kelvin at once (F = 9⁄5·C + 32, K = C + 273.15). Fixed points marked; jump to absolute zero, ice, body, boiling. Shows why Kelvin starts at absolute zero.", tempScalesSchema, (a) => /* @__PURE__ */ jsx(TemperatureScalesLab, { ...a }));
788
793
  const waterDensitySchema = z.object({
789
794
  mode: z.enum(["anomaly", "lake"]).optional(),
790
795
  ...common
791
796
  });
792
- const WaterDensityBlock = wlab("water-density", "Water’s 4 °C anomaly — why ice floats", "Water is densest at 4 °C and expands again toward freezing, so ice floats. Drag the temperature on the density curve, or switch to the lake view to see why a pond freezes top-down (4 °C water and fish survive below the ice).", waterDensitySchema, (a) => /* @__PURE__ */ jsx(WaterDensityLab, { ...a }));
797
+ const WaterDensityBlock = wlab("water-density", "Water’s 4 °C anomaly, why ice floats", "Water is densest at 4 °C and expands again toward freezing, so ice floats. Drag the temperature on the density curve, or switch to the lake view to see why a pond freezes top-down (4 °C water and fish survive below the ice).", waterDensitySchema, (a) => /* @__PURE__ */ jsx(WaterDensityLab, { ...a }));
793
798
  const efficiencySchema = z.object({
794
799
  device: z.enum([
795
800
  "incandescent",
@@ -809,7 +814,44 @@ const efficiencySchema = z.object({
809
814
  })).optional().describe("author your own energy breakdown"),
810
815
  ...common
811
816
  });
812
- const EfficiencyBlock = wlab("efficiency", "Efficiency — input→output ratio (Sankey)", "Efficiency as the fraction of energy that comes out useful: η = useful ÷ input, drawn as a Sankey energy flow that splits into a useful stream and wasted heat. Compare real devices (incandescent vs LED, engine vs motor) or AUTHOR your own breakdown via the streams field.", efficiencySchema, (a) => /* @__PURE__ */ jsx(EfficiencyLab, { ...a }));
817
+ const EfficiencyBlock = wlab("efficiency", "Efficiency, input→output ratio (Sankey)", "Efficiency as the fraction of energy that comes out useful: η = useful ÷ input, drawn as a Sankey energy flow that splits into a useful stream and wasted heat. Compare real devices (incandescent vs LED, engine vs motor) or AUTHOR your own breakdown via the streams field.", efficiencySchema, (a) => /* @__PURE__ */ jsx(EfficiencyLab, { ...a }));
818
+ const electricFieldSchema = z.object({
819
+ title: z.string().optional(),
820
+ prompt: z.string().optional(),
821
+ objectives: z.array(z.string()).optional()
822
+ });
823
+ const ElectricFieldBlock = wlab("electric-field", "Electric field, charges & the force F = qE", "Drag two charges and flip their signs; field lines retrace live, flowing out of + into −. Drop a test charge anywhere and a force arrow F = qE appears, toward + or away depending on its sign. Like charges repel, opposites attract.", electricFieldSchema, (a) => /* @__PURE__ */ jsx(ElectricFieldLab, { ...a }));
824
+ const electricFluxSchema = z.object({
825
+ field: z.number().optional().describe("field strength in vacuum (arbitrary units)"),
826
+ area: z.number().optional().describe("area: length of the flat window, scene units"),
827
+ angleDeg: z.number().optional().describe("initial angle between the area normal and the field, degrees"),
828
+ height: z.number().optional(),
829
+ activity: z.string().optional(),
830
+ title: z.string().optional(),
831
+ prompt: z.string().optional()
832
+ });
833
+ const ElectricFluxBlock = wlab("electric-flux", "Electric flux Φ = E·A·cosθ (line-counting)", "Flux made literal: how many field lines thread your area. Rotate the area (edge-on Φ = 0, face-on Φ = E·A), resize it, or change the medium (permittivity εr weakens E). The lines that pass through light up: that count is the flux.", electricFluxSchema, (a) => /* @__PURE__ */ jsx(ElectricFluxLab, { ...a }));
834
+ const gaussSchema = z.object({
835
+ height: z.number().optional(),
836
+ activity: z.string().optional(),
837
+ title: z.string().optional(),
838
+ prompt: z.string().optional()
839
+ });
840
+ const GaussLawBlock = wlab("gauss-law", "Gauss’s law, flux depends only on charge inside", "A Gaussian loop (drag its centre, drag the rim to resize) sits in the field of two charges. Green markers show field leaving, red show field entering. The net flux Φ = Q/ε₀ depends only on the charge ENCLOSED, not the loop’s size or shape, and a charge outside adds zero.", gaussSchema, (a) => /* @__PURE__ */ jsx(GaussLab, { ...a }), "GaussLaw");
841
+ const workEnergySchema = z.object({
842
+ mode: z.enum(["spring", "constant"]).optional(),
843
+ title: z.string().optional(),
844
+ prompt: z.string().optional(),
845
+ objectives: z.array(z.string()).optional()
846
+ });
847
+ const WorkEnergyBlock = wlab("work-energy", "Work done = area under the force–distance graph", "Work made visible as the AREA under the force–distance graph. A spring (F = kx) gives a triangle so W = ½kx², a constant force gives a rectangle so W = Fx. Drag the distance and the shaded area (the work) grows with it; the equation updates live.", workEnergySchema, (a) => /* @__PURE__ */ jsx(WorkEnergyLab, { ...a }));
848
+ const workPotentialSchema = z.object({
849
+ height: z.number().optional(),
850
+ activity: z.string().optional(),
851
+ title: z.string().optional(),
852
+ prompt: z.string().optional()
853
+ });
854
+ const WorkPotentialBlock = wlab("work-potential", "Potential & work, equipotentials and W = qΔV", "Electric potential made visible through equipotential rings (V = kQ/r) with field lines at right angles. Drag points A and B: the work to move a charge A → B is W = qΔV and depends only on the endpoints, never the path. Slide a point around a ring (same V) and the work is zero.", workPotentialSchema, (a) => /* @__PURE__ */ jsx(WorkPotentialLab, { ...a }));
813
855
  const physicsBlocks = [
814
856
  ProjectileLabBlock,
815
857
  OrbitLabBlock,
@@ -846,7 +888,12 @@ const physicsBlocks = [
846
888
  EntropyBlock,
847
889
  TemperatureScalesBlock,
848
890
  WaterDensityBlock,
849
- EfficiencyBlock
891
+ EfficiencyBlock,
892
+ ElectricFieldBlock,
893
+ ElectricFluxBlock,
894
+ GaussLawBlock,
895
+ WorkEnergyBlock,
896
+ WorkPotentialBlock
850
897
  ];
851
898
  const physicsComponents = {
852
899
  ...buildComponents(physicsBlocks),
@@ -865,4 +912,4 @@ const physicsComponents = {
865
912
  };
866
913
 
867
914
  //#endregion
868
- export { AtwoodBlock, BulletWallsBlock, CarnotBlock, CircularMotionBlock, CollisionTrackBlock, DopplerBlock, EfficiencyBlock, EnergySkateBlock, EntropyBlock, GasProcessBlock, GravitationBlock, GravityDropBlock, HeatTransferBlock, HeatingCurveBlock, ImpulseBlock, KeplerBlock, LeverBlock, LeverPuzzle, LorentzBlock, MagnetismBlock, OpticsBlock, OrbitLabBlock, ProjectileLabBlock, RainRelativeBlock, RampForcesBlock, RippleTankBlock, RiverBoatBlock, SimpleHarmonicBlock, StoppingDistanceBlock, StringReflectionBlock, TemperatureScalesBlock, TerminalVelocityBlock, ThermalExpansionBlock, VectorBoardBlock, VectorTypesBlock, WaterDensityBlock, WaveBlock, physicsBlocks, physicsComponents };
915
+ export { AtwoodBlock, BulletWallsBlock, CarnotBlock, CircularMotionBlock, CollisionTrackBlock, DopplerBlock, EfficiencyBlock, ElectricFieldBlock, ElectricFluxBlock, EnergySkateBlock, EntropyBlock, GasProcessBlock, GaussLawBlock, GravitationBlock, GravityDropBlock, HeatTransferBlock, HeatingCurveBlock, ImpulseBlock, KeplerBlock, LeverBlock, LeverPuzzle, LorentzBlock, MagnetismBlock, OpticsBlock, OrbitLabBlock, ProjectileLabBlock, RainRelativeBlock, RampForcesBlock, RippleTankBlock, RiverBoatBlock, SimpleHarmonicBlock, StoppingDistanceBlock, StringReflectionBlock, TemperatureScalesBlock, TerminalVelocityBlock, ThermalExpansionBlock, VectorBoardBlock, VectorTypesBlock, WaterDensityBlock, WaveBlock, WorkEnergyBlock, WorkPotentialBlock, physicsBlocks, physicsComponents };
@@ -65,7 +65,7 @@ const galtonSchema = z.object({
65
65
  showCurve: z.boolean().optional(),
66
66
  ...common
67
67
  });
68
- const GaltonBlock = lab("galton", "GaltonBoard", "Galton board (central limit theorem)", "Balls bounce through pegs (each a coin-flip) and pile into a bell curve hugging the theoretical normal — the CLT made visible.", galtonSchema, (a) => /* @__PURE__ */ jsx(GaltonBoardLab, { ...a }));
68
+ const GaltonBlock = lab("galton", "GaltonBoard", "Galton board (central limit theorem)", "Balls bounce through pegs (each a coin-flip) and pile into a bell curve hugging the theoretical normal, the CLT made visible.", galtonSchema, (a) => /* @__PURE__ */ jsx(GaltonBoardLab, { ...a }));
69
69
  const histoSchema = z.object({
70
70
  data: z.array(z.number()).optional(),
71
71
  bins: z.number().optional(),
@@ -0,0 +1,14 @@
1
+ import { CircuitDoc } from "./contract.mjs";
2
+ import { ReactNode } from "react";
3
+
4
+ //#region src/build/CircuitEditor.d.ts
5
+ interface CircuitEditorProps {
6
+ value: CircuitDoc;
7
+ onChange: (doc: CircuitDoc) => void;
8
+ }
9
+ declare function CircuitEditor({
10
+ value,
11
+ onChange
12
+ }: CircuitEditorProps): ReactNode;
13
+ //#endregion
14
+ export { CircuitEditor, CircuitEditorProps };