@classytic/labs 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (455) hide show
  1. package/dist/_virtual/_rolldown/runtime.mjs +18 -0
  2. package/dist/biology/enzyme-rate/preset.mjs +5 -5
  3. package/dist/biology/genetic-cross/core.d.mts +7 -7
  4. package/dist/biology/genetic-cross/core.mjs +4 -4
  5. package/dist/biology/genetic-cross/grid.mjs +132 -123
  6. package/dist/biology/genetic-cross/preset.mjs +4 -4
  7. package/dist/biology/genetic-cross/sex-linked.mjs +7 -7
  8. package/dist/biology/photosynthesis-factors/preset.mjs +8 -8
  9. package/dist/biology/respiration/preset.mjs +4 -4
  10. package/dist/biology/sequence/central-dogma.mjs +5 -5
  11. package/dist/biology/sequence/core.d.mts +6 -6
  12. package/dist/biology/sequence/core.mjs +1 -1
  13. package/dist/biology/sequence/preset.mjs +6 -6
  14. package/dist/blocks/authoring.mjs +5 -5
  15. package/dist/blocks/biology.d.mts +2 -2
  16. package/dist/blocks/biology.mjs +5 -5
  17. package/dist/blocks/chem.d.mts +2 -2
  18. package/dist/blocks/chem.mjs +13 -13
  19. package/dist/blocks/circuits.d.mts +293 -4
  20. package/dist/blocks/circuits.mjs +874 -9
  21. package/dist/blocks/discrete.d.mts +30 -2
  22. package/dist/blocks/discrete.mjs +74 -4
  23. package/dist/blocks/economics.mjs +1 -1
  24. package/dist/blocks/geography.mjs +1 -1
  25. package/dist/blocks/geometry.mjs +3 -3
  26. package/dist/blocks/ict.d.mts +90 -1
  27. package/dist/blocks/ict.mjs +217 -7
  28. package/dist/blocks/index.d.mts +3064 -657
  29. package/dist/blocks/index.mjs +9 -9
  30. package/dist/blocks/lab-block.mjs +5 -5
  31. package/dist/blocks/lab-config.d.mts +1 -1
  32. package/dist/blocks/lab-config.mjs +4 -4
  33. package/dist/blocks/lab-gallery.d.mts +1 -1
  34. package/dist/blocks/lab-gallery.mjs +2 -2
  35. package/dist/blocks/language.d.mts +6 -6
  36. package/dist/blocks/language.mjs +12 -12
  37. package/dist/blocks/lesson.mjs +4 -4
  38. package/dist/blocks/math.d.mts +577 -11
  39. package/dist/blocks/math.mjs +1648 -14
  40. package/dist/blocks/ml.d.mts +45 -1
  41. package/dist/blocks/ml.mjs +80 -6
  42. package/dist/blocks/physics.d.mts +9 -4
  43. package/dist/blocks/physics.mjs +75 -28
  44. package/dist/blocks/statistics.mjs +1 -1
  45. package/dist/build/CircuitEditor.d.mts +14 -0
  46. package/dist/build/CircuitEditor.mjs +787 -0
  47. package/dist/build/CircuitPlayer.d.mts +19 -0
  48. package/dist/build/CircuitPlayer.mjs +53 -0
  49. package/dist/build/CircuitScene.d.mts +61 -0
  50. package/dist/build/CircuitScene.mjs +383 -0
  51. package/dist/build/contract.d.mts +116 -0
  52. package/dist/build/editor-ops.d.mts +65 -0
  53. package/dist/build/editor-ops.mjs +306 -0
  54. package/dist/build/editor-ui.mjs +121 -0
  55. package/dist/build/flow.d.mts +14 -0
  56. package/dist/build/flow.mjs +119 -0
  57. package/dist/build/index.d.mts +10 -0
  58. package/dist/build/index.mjs +10 -0
  59. package/dist/build/parts/ammeter.d.mts +1 -0
  60. package/dist/build/parts/ammeter.mjs +32 -0
  61. package/dist/build/parts/bulb.d.mts +1 -0
  62. package/dist/build/parts/bulb.mjs +50 -0
  63. package/dist/build/parts/capacitor.d.mts +1 -0
  64. package/dist/build/parts/capacitor.mjs +26 -0
  65. package/dist/build/parts/cell.d.mts +1 -0
  66. package/dist/build/parts/cell.mjs +40 -0
  67. package/dist/build/parts/diode.d.mts +1 -0
  68. package/dist/build/parts/diode.mjs +33 -0
  69. package/dist/build/parts/index.d.mts +5 -0
  70. package/dist/build/parts/index.mjs +43 -0
  71. package/dist/build/parts/mosfet.d.mts +1 -0
  72. package/dist/build/parts/mosfet.mjs +95 -0
  73. package/dist/build/parts/node.d.mts +1 -0
  74. package/dist/build/parts/node.mjs +32 -0
  75. package/dist/build/parts/resistor.d.mts +1 -0
  76. package/dist/build/parts/resistor.mjs +49 -0
  77. package/dist/build/parts/shared.mjs +42 -0
  78. package/dist/build/parts/switch.d.mts +1 -0
  79. package/dist/build/parts/switch.mjs +34 -0
  80. package/dist/build/parts.d.mts +1 -0
  81. package/dist/build/registry.d.mts +9 -0
  82. package/dist/build/registry.mjs +15 -0
  83. package/dist/build/solve.d.mts +8 -0
  84. package/dist/build/solve.mjs +0 -0
  85. package/dist/catalog/registry.d.mts +2 -2
  86. package/dist/catalog/templates.d.mts +1 -1
  87. package/dist/catalog/templates.mjs +6 -6
  88. package/dist/chem/battery.mjs +1 -1
  89. package/dist/chem/bohr-atom.mjs +4 -4
  90. package/dist/chem/diffusion/preset.mjs +4 -4
  91. package/dist/chem/electrochem/preset.mjs +5 -5
  92. package/dist/chem/equilibrium/preset.d.mts +1 -1
  93. package/dist/chem/equilibrium/preset.mjs +6 -6
  94. package/dist/chem/gas-box/preset.mjs +6 -6
  95. package/dist/chem/kinetics/preset.mjs +6 -6
  96. package/dist/chem/periodic-trends/preset.mjs +7 -7
  97. package/dist/chem/reaction-lab.mjs +3 -3
  98. package/dist/chem/reaction-profile.mjs +4 -4
  99. package/dist/chem/solution/dilution.mjs +6 -6
  100. package/dist/chem/solution/field.d.mts +2 -2
  101. package/dist/chem/solution/field.mjs +2 -2
  102. package/dist/chem/solution/solution-box.mjs +7 -7
  103. package/dist/chem/stoichiometry/preset.mjs +5 -5
  104. package/dist/chem/titration/preset.mjs +5 -5
  105. package/dist/circuits/ac-dc/asset.mjs +1 -1
  106. package/dist/circuits/ac-dc/preset.mjs +2 -2
  107. package/dist/circuits/brownout/index.d.mts +1 -0
  108. package/dist/circuits/brownout/preset.d.mts +22 -0
  109. package/dist/circuits/brownout/preset.mjs +399 -0
  110. package/dist/circuits/capacitor-leak/preset.mjs +13 -8
  111. package/dist/circuits/circuit/asset.mjs +71 -14
  112. package/dist/circuits/circuit/preset.mjs +23 -5
  113. package/dist/circuits/circuit-builder.mjs +60 -132
  114. package/dist/circuits/circuit-lab.mjs +60 -40
  115. package/dist/circuits/cmos-gate/index.d.mts +1 -0
  116. package/dist/circuits/cmos-gate/preset.d.mts +75 -0
  117. package/dist/circuits/cmos-gate/preset.mjs +1491 -0
  118. package/dist/circuits/diode/index.d.mts +1 -0
  119. package/dist/circuits/diode/preset.d.mts +25 -0
  120. package/dist/circuits/diode/preset.mjs +266 -0
  121. package/dist/circuits/index.d.mts +7 -1
  122. package/dist/circuits/index.mjs +7 -1
  123. package/dist/circuits/rc-charging/index.d.mts +1 -0
  124. package/dist/circuits/rc-charging/preset.d.mts +27 -0
  125. package/dist/circuits/rc-charging/preset.mjs +329 -0
  126. package/dist/circuits/semiconductor/index.d.mts +1 -0
  127. package/dist/circuits/semiconductor/preset.d.mts +102 -0
  128. package/dist/circuits/semiconductor/preset.mjs +1855 -0
  129. package/dist/circuits/transistor/index.d.mts +1 -0
  130. package/dist/circuits/transistor/preset.d.mts +27 -0
  131. package/dist/circuits/transistor/preset.mjs +329 -0
  132. package/dist/commerce/accounting/core.d.mts +1 -1
  133. package/dist/commerce/accounting/equation-balance.mjs +5 -5
  134. package/dist/commerce/accounting/journal-poster.mjs +8 -8
  135. package/dist/commerce/accounting/statement-sorter.mjs +4 -4
  136. package/dist/commerce/economics/core.d.mts +2 -2
  137. package/dist/commerce/economics/core.mjs +1 -1
  138. package/dist/commerce/economics/demand-shift-vs-move.mjs +6 -6
  139. package/dist/commerce/economics/elasticity-revenue.mjs +6 -6
  140. package/dist/commerce/economics/market-equilibrium.mjs +5 -5
  141. package/dist/core/easing.d.mts +3 -3
  142. package/dist/core/easing.mjs +2 -2
  143. package/dist/core/numeric.d.mts +3 -3
  144. package/dist/core/numeric.mjs +2 -2
  145. package/dist/core/reactive.d.mts +1 -1
  146. package/dist/core/reactive.mjs +1 -1
  147. package/dist/core/rng.d.mts +2 -2
  148. package/dist/core/rng.mjs +1 -1
  149. package/dist/core/tex.mjs +2 -2
  150. package/dist/core/timeline.d.mts +1 -1
  151. package/dist/core/timeline.mjs +1 -1
  152. package/dist/core/util.mjs +11 -1
  153. package/dist/discrete/arrangements/preset.mjs +6 -14
  154. package/dist/discrete/bayes/preset.mjs +43 -35
  155. package/dist/discrete/binomial/preset.mjs +2 -2
  156. package/dist/discrete/combination-studio/figure.d.mts +6 -0
  157. package/dist/discrete/combination-studio/figure.mjs +159 -0
  158. package/dist/discrete/combination-studio/index.d.mts +2 -0
  159. package/dist/discrete/combination-studio/preset.d.mts +44 -0
  160. package/dist/discrete/combination-studio/preset.mjs +440 -0
  161. package/dist/discrete/core/combinatorics.d.mts +23 -3
  162. package/dist/discrete/core/combinatorics.mjs +38 -3
  163. package/dist/discrete/core/pigeonhole.d.mts +1 -1
  164. package/dist/discrete/core/pigeonhole.mjs +1 -1
  165. package/dist/discrete/core/probability.d.mts +3 -3
  166. package/dist/discrete/core/probability.mjs +3 -3
  167. package/dist/discrete/core/sets.d.mts +1 -1
  168. package/dist/discrete/counting-slots/preset.mjs +8 -8
  169. package/dist/discrete/counting-tree/preset.mjs +65 -8
  170. package/dist/discrete/expected-value/preset.mjs +13 -13
  171. package/dist/discrete/hypergeometric/preset.mjs +48 -15
  172. package/dist/discrete/index.d.mts +4 -2
  173. package/dist/discrete/index.mjs +4 -2
  174. package/dist/discrete/karnaugh/preset.mjs +26 -20
  175. package/dist/discrete/lln/preset.mjs +44 -3
  176. package/dist/discrete/logic-circuit/preset.mjs +2 -2
  177. package/dist/discrete/monte-carlo/preset.d.mts +1 -1
  178. package/dist/discrete/monte-carlo/preset.mjs +14 -14
  179. package/dist/discrete/monty-hall/preset.mjs +6 -6
  180. package/dist/discrete/outcome-builder/preset.mjs +3 -3
  181. package/dist/discrete/pascal/preset.mjs +37 -7
  182. package/dist/discrete/rules.d.mts +20 -0
  183. package/dist/discrete/rules.mjs +264 -0
  184. package/dist/discrete/sample-space/preset.mjs +4 -4
  185. package/dist/discrete/selection/preset.mjs +7 -13
  186. package/dist/discrete/truth-table/preset.mjs +32 -9
  187. package/dist/discrete/venn/preset.mjs +71 -48
  188. package/dist/geography/cycle-lab/preset.mjs +17 -10
  189. package/dist/geography/cycles.d.mts +3 -3
  190. package/dist/geography/cycles.mjs +3 -3
  191. package/dist/geometry/board/preset.d.mts +2 -0
  192. package/dist/geometry/board/preset.mjs +11 -15
  193. package/dist/geometry/builder.mjs +3 -3
  194. package/dist/ict/number-systems/base-odometer.mjs +4 -4
  195. package/dist/ict/number-systems/bit-grouper.d.mts +1 -1
  196. package/dist/ict/number-systems/bit-grouper.mjs +4 -4
  197. package/dist/ict/number-systems/place-value-dial.d.mts +1 -1
  198. package/dist/ict/number-systems/place-value-dial.mjs +3 -3
  199. package/dist/ict/number-systems/wheel.d.mts +3 -3
  200. package/dist/ict/number-systems/wheel.mjs +4 -4
  201. package/dist/kit/annotate.mjs +3 -3
  202. package/dist/kit/answer-check.d.mts +2 -2
  203. package/dist/kit/answer-check.mjs +34 -6
  204. package/dist/kit/ask.d.mts +19 -0
  205. package/dist/kit/ask.mjs +46 -0
  206. package/dist/kit/bar-strip.mjs +53 -0
  207. package/dist/kit/calc.d.mts +33 -0
  208. package/dist/kit/calc.mjs +27 -0
  209. package/dist/kit/carrier-engine.mjs +147 -0
  210. package/dist/kit/clue-scene.d.mts +86 -0
  211. package/dist/kit/clue-scene.mjs +424 -0
  212. package/dist/kit/cluster.d.mts +30 -0
  213. package/dist/kit/cluster.mjs +81 -0
  214. package/dist/kit/controls.mjs +11 -5
  215. package/dist/kit/coords.d.mts +88 -0
  216. package/dist/kit/coords.mjs +192 -0
  217. package/dist/kit/data-scene.d.mts +27 -0
  218. package/dist/kit/data-scene.mjs +199 -0
  219. package/dist/kit/diagram.mjs +111 -50
  220. package/dist/kit/electronics.mjs +552 -60
  221. package/dist/kit/expr-analysis.d.mts +18 -6
  222. package/dist/kit/expr-analysis.mjs +82 -28
  223. package/dist/kit/frame.d.mts +3 -3
  224. package/dist/kit/frame.mjs +25 -6
  225. package/dist/kit/gameshow.mjs +2 -2
  226. package/dist/kit/index.d.mts +14 -2
  227. package/dist/kit/index.mjs +13 -1
  228. package/dist/kit/logic-gates.mjs +246 -47
  229. package/dist/kit/palette.mjs +26 -0
  230. package/dist/kit/pedagogy.d.mts +4 -4
  231. package/dist/kit/pedagogy.mjs +21 -17
  232. package/dist/kit/play.d.mts +1 -1
  233. package/dist/kit/play.mjs +3 -3
  234. package/dist/kit/predict.d.mts +55 -0
  235. package/dist/kit/predict.mjs +146 -0
  236. package/dist/kit/receipt.d.mts +29 -0
  237. package/dist/kit/receipt.mjs +94 -0
  238. package/dist/kit/rich.mjs +2 -2
  239. package/dist/kit/rule.d.mts +59 -0
  240. package/dist/kit/rule.mjs +215 -0
  241. package/dist/kit/scale.mjs +1 -1
  242. package/dist/kit/scene-library.d.mts +22 -0
  243. package/dist/kit/scene-library.mjs +311 -0
  244. package/dist/kit/scene-studio.d.mts +14 -0
  245. package/dist/kit/scene-studio.mjs +338 -0
  246. package/dist/kit/scenes.d.mts +31 -0
  247. package/dist/kit/scenes.mjs +569 -0
  248. package/dist/kit/slot-fill.d.mts +61 -0
  249. package/dist/kit/slot-fill.mjs +207 -0
  250. package/dist/kit/solve.d.mts +21 -0
  251. package/dist/kit/solve.mjs +75 -0
  252. package/dist/kit/space.mjs +5 -5
  253. package/dist/kit/steps.mjs +2 -2
  254. package/dist/kit/vessel.d.mts +69 -0
  255. package/dist/kit/vessel.mjs +191 -0
  256. package/dist/language/agreement/preset.mjs +2 -2
  257. package/dist/language/article-lens/preset.d.mts +1 -1
  258. package/dist/language/article-lens/preset.mjs +8 -8
  259. package/dist/language/deck.d.mts +3 -3
  260. package/dist/language/deck.mjs +1 -1
  261. package/dist/language/preposition-scene/preset.d.mts +2 -2
  262. package/dist/language/preposition-scene/preset.mjs +5 -5
  263. package/dist/language/sentence-builder/preset.mjs +5 -5
  264. package/dist/language/transform/preset.d.mts +2 -2
  265. package/dist/language/transform/preset.mjs +5 -5
  266. package/dist/language/ui.d.mts +3 -3
  267. package/dist/language/ui.mjs +4 -4
  268. package/dist/language/word-match/preset.mjs +3 -3
  269. package/dist/logic/LogicBuildLab.d.mts +22 -0
  270. package/dist/logic/LogicBuildLab.mjs +170 -0
  271. package/dist/logic/LogicEditScene.d.mts +31 -0
  272. package/dist/logic/LogicEditScene.mjs +276 -0
  273. package/dist/logic/LogicEditor.d.mts +14 -0
  274. package/dist/logic/LogicEditor.mjs +413 -0
  275. package/dist/logic/LogicScene.d.mts +32 -0
  276. package/dist/logic/LogicScene.mjs +277 -0
  277. package/dist/logic/contract.d.mts +72 -0
  278. package/dist/logic/display.d.mts +24 -0
  279. package/dist/logic/display.mjs +127 -0
  280. package/dist/logic/edit-ops.d.mts +44 -0
  281. package/dist/logic/edit-ops.mjs +177 -0
  282. package/dist/logic/evaluate.d.mts +11 -0
  283. package/dist/logic/evaluate.mjs +93 -0
  284. package/dist/logic/gates.d.mts +10 -0
  285. package/dist/logic/gates.mjs +73 -0
  286. package/dist/logic/index.d.mts +14 -0
  287. package/dist/logic/index.mjs +13 -0
  288. package/dist/logic/lab.d.mts +32 -0
  289. package/dist/logic/lab.mjs +160 -0
  290. package/dist/logic/presets.d.mts +12 -0
  291. package/dist/logic/presets.mjs +241 -0
  292. package/dist/logic/registry.d.mts +9 -0
  293. package/dist/logic/registry.mjs +15 -0
  294. package/dist/math/area-model/preset.mjs +70 -44
  295. package/dist/math/balance-algebra/preset.mjs +14 -5
  296. package/dist/math/broken-tree/index.d.mts +1 -0
  297. package/dist/math/broken-tree/preset.d.mts +26 -0
  298. package/dist/math/broken-tree/preset.mjs +435 -0
  299. package/dist/math/circle/index.d.mts +1 -0
  300. package/dist/math/circle/preset.d.mts +44 -0
  301. package/dist/math/circle/preset.mjs +198 -0
  302. package/dist/math/complex/core.d.mts +93 -0
  303. package/dist/math/complex/core.mjs +239 -0
  304. package/dist/math/complex/index.d.mts +3 -0
  305. package/dist/math/complex/preset.d.mts +31 -0
  306. package/dist/math/complex/preset.mjs +377 -0
  307. package/dist/math/complex/rules.d.mts +6 -0
  308. package/dist/math/complex/rules.mjs +121 -0
  309. package/dist/math/conic/index.d.mts +1 -0
  310. package/dist/math/conic/preset.d.mts +30 -0
  311. package/dist/math/conic/preset.mjs +334 -0
  312. package/dist/math/derivation.mjs +5 -5
  313. package/dist/math/derivative-explorer/preset.mjs +5 -5
  314. package/dist/math/domain-range/index.d.mts +1 -0
  315. package/dist/math/domain-range/preset.d.mts +33 -0
  316. package/dist/math/domain-range/preset.mjs +313 -0
  317. package/dist/math/fraction-bar/index.d.mts +1 -0
  318. package/dist/math/fraction-bar/preset.d.mts +27 -0
  319. package/dist/math/fraction-bar/preset.mjs +197 -0
  320. package/dist/math/function-machine/preset.mjs +2 -2
  321. package/dist/math/gradient-descent.mjs +6 -6
  322. package/dist/math/grapher/preset.d.mts +1 -1
  323. package/dist/math/grapher/preset.mjs +4 -4
  324. package/dist/math/harmonic-form/preset.mjs +6 -6
  325. package/dist/math/index.d.mts +27 -2
  326. package/dist/math/index.mjs +27 -2
  327. package/dist/math/integral-explorer/preset.mjs +2 -2
  328. package/dist/math/interactive/preset.mjs +3 -3
  329. package/dist/math/limit-explorer/preset.mjs +4 -4
  330. package/dist/math/linear-model/index.d.mts +1 -0
  331. package/dist/math/linear-model/preset.d.mts +53 -0
  332. package/dist/math/linear-model/preset.mjs +164 -0
  333. package/dist/math/linear-system/preset.mjs +4 -4
  334. package/dist/math/mystery-bucket/preset.mjs +6 -6
  335. package/dist/math/number-line/preset.mjs +3 -2
  336. package/dist/math/parabola/preset.mjs +4 -3
  337. package/dist/math/pattern/preset.mjs +7 -13
  338. package/dist/math/percent-bar/index.d.mts +1 -0
  339. package/dist/math/percent-bar/preset.d.mts +37 -0
  340. package/dist/math/percent-bar/preset.mjs +275 -0
  341. package/dist/math/poly/core.d.mts +50 -0
  342. package/dist/math/poly/core.mjs +268 -0
  343. package/dist/math/poly/index.d.mts +3 -0
  344. package/dist/math/poly/preset.d.mts +23 -0
  345. package/dist/math/poly/preset.mjs +141 -0
  346. package/dist/math/poly/steps.d.mts +10 -0
  347. package/dist/math/poly/steps.mjs +99 -0
  348. package/dist/math/rate-machine/index.d.mts +1 -0
  349. package/dist/math/rate-machine/preset.d.mts +35 -0
  350. package/dist/math/rate-machine/preset.mjs +281 -0
  351. package/dist/math/ratio-share/index.d.mts +1 -0
  352. package/dist/math/ratio-share/preset.d.mts +24 -0
  353. package/dist/math/ratio-share/preset.mjs +204 -0
  354. package/dist/math/receipt/index.d.mts +1 -0
  355. package/dist/math/receipt/preset.d.mts +22 -0
  356. package/dist/math/receipt/preset.mjs +137 -0
  357. package/dist/math/sequence-predict/index.d.mts +1 -0
  358. package/dist/math/sequence-predict/preset.d.mts +34 -0
  359. package/dist/math/sequence-predict/preset.mjs +130 -0
  360. package/dist/math/straight-line/index.d.mts +1 -0
  361. package/dist/math/straight-line/preset.d.mts +37 -0
  362. package/dist/math/straight-line/preset.mjs +374 -0
  363. package/dist/math/system-solve/index.d.mts +1 -0
  364. package/dist/math/system-solve/preset.d.mts +21 -0
  365. package/dist/math/system-solve/preset.mjs +227 -0
  366. package/dist/math/transform/index.d.mts +1 -0
  367. package/dist/math/transform/preset.d.mts +41 -0
  368. package/dist/math/transform/preset.mjs +343 -0
  369. package/dist/math/triangle-trig/preset.mjs +12 -9
  370. package/dist/math/trig/core.d.mts +37 -0
  371. package/dist/math/trig/core.mjs +150 -0
  372. package/dist/math/trig/diagrams.d.mts +1 -0
  373. package/dist/math/trig/diagrams.mjs +321 -0
  374. package/dist/math/trig/index.d.mts +3 -0
  375. package/dist/math/trig/preset.d.mts +25 -0
  376. package/dist/math/trig/preset.mjs +260 -0
  377. package/dist/math/trig/rules.d.mts +6 -0
  378. package/dist/math/trig/rules.mjs +159 -0
  379. package/dist/math/trig-explorer.mjs +4 -4
  380. package/dist/ml/boundary/preset.mjs +8 -3
  381. package/dist/ml/classifier/preset.mjs +31 -6
  382. package/dist/ml/kmeans/preset.mjs +4 -4
  383. package/dist/ml/knn/preset.mjs +47 -12
  384. package/dist/ml/regression/preset.mjs +36 -7
  385. package/dist/physics/atwood/preset.mjs +4 -4
  386. package/dist/physics/bullet-walls/preset.d.mts +1 -1
  387. package/dist/physics/bullet-walls/preset.mjs +7 -7
  388. package/dist/physics/carnot/preset.mjs +6 -6
  389. package/dist/physics/circular-motion/preset.mjs +36 -5
  390. package/dist/physics/collision-track/preset.mjs +35 -5
  391. package/dist/physics/efficiency/preset.d.mts +2 -2
  392. package/dist/physics/efficiency/preset.mjs +5 -5
  393. package/dist/physics/electric-field/preset.mjs +32 -23
  394. package/dist/physics/electric-flux/index.d.mts +1 -0
  395. package/dist/physics/electric-flux/preset.d.mts +29 -0
  396. package/dist/physics/electric-flux/preset.mjs +264 -0
  397. package/dist/physics/energy-skate/preset.mjs +5 -5
  398. package/dist/physics/entropy/preset.mjs +7 -7
  399. package/dist/physics/expansion/preset.mjs +13 -13
  400. package/dist/physics/exponential/asset.mjs +1 -1
  401. package/dist/physics/exponential/preset.mjs +4 -4
  402. package/dist/physics/gas-process/preset.mjs +3 -3
  403. package/dist/physics/gauss-law/index.d.mts +1 -0
  404. package/dist/physics/gauss-law/preset.d.mts +20 -0
  405. package/dist/physics/gauss-law/preset.mjs +286 -0
  406. package/dist/physics/gravitation/preset.mjs +7 -7
  407. package/dist/physics/gravity-drop.mjs +4 -4
  408. package/dist/physics/heat-transfer/preset.d.mts +1 -1
  409. package/dist/physics/heat-transfer/preset.mjs +10 -10
  410. package/dist/physics/impulse/preset.mjs +5 -5
  411. package/dist/physics/index.d.mts +4 -1
  412. package/dist/physics/index.mjs +4 -1
  413. package/dist/physics/kepler/preset.mjs +4 -4
  414. package/dist/physics/lever/preset.mjs +3 -3
  415. package/dist/physics/lorentz/preset.mjs +11 -11
  416. package/dist/physics/magnetism/preset.mjs +3 -3
  417. package/dist/physics/optics/preset.mjs +2 -2
  418. package/dist/physics/orbit-lab.mjs +5 -5
  419. package/dist/physics/projectile-lab.mjs +4 -4
  420. package/dist/physics/rain-relative/preset.mjs +5 -5
  421. package/dist/physics/ramp-forces/preset.mjs +5 -5
  422. package/dist/physics/river-boat.mjs +6 -6
  423. package/dist/physics/shm/preset.mjs +9 -9
  424. package/dist/physics/stopping-distance/preset.mjs +3 -3
  425. package/dist/physics/temperature-scales/preset.mjs +105 -116
  426. package/dist/physics/terminal-velocity/preset.mjs +5 -5
  427. package/dist/physics/thermal/preset.mjs +5 -5
  428. package/dist/physics/vector-board/preset.mjs +7 -6
  429. package/dist/physics/vector-scene.mjs +2 -2
  430. package/dist/physics/vector-types/preset.mjs +37 -3
  431. package/dist/physics/water-density/preset.mjs +12 -12
  432. package/dist/physics/waves/doppler.mjs +2 -2
  433. package/dist/physics/waves/preset.mjs +4 -4
  434. package/dist/physics/waves/ripple.mjs +6 -6
  435. package/dist/physics/waves/string.mjs +5 -5
  436. package/dist/physics/work-energy/preset.mjs +4 -4
  437. package/dist/physics/work-potential/index.d.mts +1 -0
  438. package/dist/physics/work-potential/preset.d.mts +20 -0
  439. package/dist/physics/work-potential/preset.mjs +276 -0
  440. package/dist/schemas/index.d.mts +6 -6
  441. package/dist/schemas/index.mjs +3 -3
  442. package/dist/statistics/center-spread/preset.mjs +3 -3
  443. package/dist/statistics/core/descriptive.d.mts +2 -2
  444. package/dist/statistics/core/descriptive.mjs +2 -2
  445. package/dist/statistics/core/normal.d.mts +3 -3
  446. package/dist/statistics/core/normal.mjs +3 -3
  447. package/dist/statistics/core/sequences.d.mts +1 -1
  448. package/dist/statistics/galton/preset.mjs +2 -2
  449. package/dist/statistics/histogram/preset.mjs +6 -6
  450. package/dist/statistics/normal/preset.mjs +2 -2
  451. package/dist/statistics/sampling/preset.mjs +4 -4
  452. package/dist/statistics/sequence/preset.mjs +58 -15
  453. package/dist/statistics/z-table/preset.mjs +17 -4
  454. package/package.json +11 -3
  455. package/styles.css +4 -1
@@ -0,0 +1,65 @@
1
+ import { CircuitDoc, PinRef } from "./contract.mjs";
2
+ import { Vec2 } from "@classytic/stage";
3
+
4
+ //#region src/build/editor-ops.d.ts
5
+ /** Add a part; each pin starts on its own fresh node (unconnected). The first cell's −
6
+ * terminal is tied to ground so the network always has a reference. */
7
+ declare function addPart(doc: CircuitDoc, kind: string, at: Vec2): CircuitDoc;
8
+ declare function movePart(doc: CircuitDoc, id: string, at: Vec2): CircuitDoc;
9
+ declare function updateProps(doc: CircuitDoc, id: string, patch: Record<string, number | string | boolean>): CircuitDoc;
10
+ declare function rotatePart(doc: CircuitDoc, id: string): CircuitDoc;
11
+ /**
12
+ * Drop junction nodes that have fewer than 2 wire connections AND their dangling wires, to a
13
+ * fixpoint. This is an EXPLICIT "tidy" the UI can offer; it is NOT run automatically, because a
14
+ * node a user just placed (or is half-way wiring) legitimately has 0 or 1 connection and must
15
+ * not vanish under them.
16
+ */
17
+ declare function pruneJunctions(doc: CircuitDoc): CircuitDoc;
18
+ declare function deletePart(doc: CircuitDoc, id: string): CircuitDoc;
19
+ /** Connect two pins with a NEW wire edge (parts keep their positions). No-op for a
20
+ * self-link, a duplicate of an existing wire, or an endpoint whose part/pin
21
+ * doesn't exist (an invalid edge that would persist as an invisible no-op). */
22
+ declare function connect(doc: CircuitDoc, a: PinRef, b: PinRef): CircuitDoc;
23
+ /** Add a wire the way a user DRAWS one: it is always created (even between pins already on the
24
+ * same net, e.g. a deliberately-routed redundant path) so a drawn wire never silently vanishes.
25
+ * Only a self-link or an endpoint that doesn't exist is rejected. Carries optional bend points. */
26
+ declare function addWire(doc: CircuitDoc, a: PinRef, b: PinRef, mids?: Vec2[]): CircuitDoc;
27
+ /** Remove a wire edge. Low-level: callers that may orphan a junction wrap with pruneJunctions. */
28
+ declare function removeWire(doc: CircuitDoc, wireId: string): CircuitDoc;
29
+ /** Re-target ONE end of a wire to a different pin (drag-to-detach / reconnect). Rejects a move
30
+ * that would make the wire a self-loop, or that points at a pin which doesn't exist. */
31
+ declare function retargetWire(doc: CircuitDoc, wireId: string, end: 'a' | 'b', to: PinRef): CircuitDoc;
32
+ /** Remove a wire (the editor's delete-wire action). Junctions are left in place, never
33
+ * auto-removed, so nothing the user placed disappears unexpectedly. */
34
+ declare function disconnectWire(doc: CircuitDoc, wireId: string): CircuitDoc;
35
+ /** World position of a pin's terminal (via its PartDef), for geometry on the doc. */
36
+ declare function terminalOf(doc: CircuitDoc, ref: PinRef): Vec2 | undefined;
37
+ /** The full polyline a wire draws: through its bend points if it has any, else the default
38
+ * Manhattan elbow. The renderer, hit-test, and tap all route through this one function. */
39
+ declare function wirePolyline(ta: Vec2, mids: Vec2[], tb: Vec2): Vec2[];
40
+ /** Set (or clear, when empty) a wire's bend points. */
41
+ declare function setWireWaypoints(doc: CircuitDoc, wireId: string, mids: Vec2[]): CircuitDoc;
42
+ /** Place a free junction (a 'node' part) at a point; returns its pin for wiring. */
43
+ declare function addJunction(doc: CircuitDoc, at: Vec2): {
44
+ doc: CircuitDoc;
45
+ pin: PinRef;
46
+ };
47
+ /**
48
+ * Tap an existing wire at a point: drop a junction ON the wire (projected onto its route)
49
+ * and SPLIT the wire into two that meet there, so a new lead can branch off mid-span. The
50
+ * junction is a `node` part (no element), so the three wires share one net and the solver
51
+ * needs no special mid-wire case. Returns the junction pin to wire the new lead to.
52
+ */
53
+ declare function tapWire(doc: CircuitDoc, wireId: string, at: Vec2): {
54
+ doc: CircuitDoc;
55
+ pin: PinRef;
56
+ };
57
+ /** Drop a part ONTO a wire: insert it in series. The wire is removed and the part's two
58
+ * ends are wired to the wire's two original endpoints (a → pin0, pin1 → b). */
59
+ declare function spliceIntoWire(doc: CircuitDoc, wireId: string, kind: string, at: Vec2): CircuitDoc;
60
+ /** Toggle a pin's connection to ground. Grounding ties the pin's net to the reference;
61
+ * toggling again gives the pin a fresh independent node (un-grounds it), so a short made
62
+ * by grounding both terminals of a source can always be undone. */
63
+ declare function setGround(doc: CircuitDoc, ref: PinRef): CircuitDoc;
64
+ //#endregion
65
+ export { addJunction, addPart, addWire, connect, deletePart, disconnectWire, movePart, pruneJunctions, removeWire, retargetWire, rotatePart, setGround, setWireWaypoints, spliceIntoWire, tapWire, terminalOf, updateProps, wirePolyline };
@@ -0,0 +1,306 @@
1
+ import { getPart } from "./registry.mjs";
2
+
3
+ //#region src/build/editor-ops.ts
4
+ const freshId = (prefix, taken) => {
5
+ let i = 1;
6
+ while (taken.has(`${prefix}${i}`)) i++;
7
+ return `${prefix}${i}`;
8
+ };
9
+ const nodeIdsOf = (doc) => new Set([...doc.nodes.map((n) => n.id), ...doc.parts.flatMap((p) => Object.values(p.pins))]);
10
+ /** Add a part; each pin starts on its own fresh node (unconnected). The first cell's −
11
+ * terminal is tied to ground so the network always has a reference. */
12
+ function addPart(doc, kind, at) {
13
+ const def = getPart(kind);
14
+ if (!def) return doc;
15
+ const id = freshId(kind, new Set(doc.parts.map((p) => p.id)));
16
+ const taken = nodeIdsOf(doc);
17
+ const grounded = [...taken].includes("gnd");
18
+ const pins = {};
19
+ for (const pin of def.pins) {
20
+ if (kind === "cell" && !grounded && pin === "b") {
21
+ pins[pin] = "gnd";
22
+ continue;
23
+ }
24
+ const nid = freshId("nd", taken);
25
+ taken.add(nid);
26
+ pins[pin] = nid;
27
+ }
28
+ const part = {
29
+ id,
30
+ kind,
31
+ at,
32
+ orient: "h",
33
+ props: { ...def.defaultProps },
34
+ pins
35
+ };
36
+ return {
37
+ ...doc,
38
+ parts: [...doc.parts, part]
39
+ };
40
+ }
41
+ function movePart(doc, id, at) {
42
+ return {
43
+ ...doc,
44
+ parts: doc.parts.map((p) => p.id === id ? {
45
+ ...p,
46
+ at
47
+ } : p)
48
+ };
49
+ }
50
+ function updateProps(doc, id, patch) {
51
+ return {
52
+ ...doc,
53
+ parts: doc.parts.map((p) => p.id === id ? {
54
+ ...p,
55
+ props: {
56
+ ...p.props,
57
+ ...patch
58
+ }
59
+ } : p)
60
+ };
61
+ }
62
+ function rotatePart(doc, id) {
63
+ return {
64
+ ...doc,
65
+ parts: doc.parts.map((p) => p.id === id ? {
66
+ ...p,
67
+ orient: p.orient === "v" ? "h" : "v"
68
+ } : p)
69
+ };
70
+ }
71
+ /**
72
+ * Drop junction nodes that have fewer than 2 wire connections AND their dangling wires, to a
73
+ * fixpoint. This is an EXPLICIT "tidy" the UI can offer; it is NOT run automatically, because a
74
+ * node a user just placed (or is half-way wiring) legitimately has 0 or 1 connection and must
75
+ * not vanish under them.
76
+ */
77
+ function pruneJunctions(doc) {
78
+ let parts = doc.parts;
79
+ let wires = doc.wires ?? [];
80
+ for (;;) {
81
+ const count = /* @__PURE__ */ new Map();
82
+ for (const w of wires) for (const e of [w.a, w.b]) count.set(e.partId, (count.get(e.partId) ?? 0) + 1);
83
+ const orphans = new Set(parts.filter((p) => p.kind === "node" && (count.get(p.id) ?? 0) < 2).map((p) => p.id));
84
+ if (orphans.size === 0) break;
85
+ parts = parts.filter((p) => !orphans.has(p.id));
86
+ wires = wires.filter((w) => !orphans.has(w.a.partId) && !orphans.has(w.b.partId));
87
+ }
88
+ return {
89
+ ...doc,
90
+ parts,
91
+ wires
92
+ };
93
+ }
94
+ function deletePart(doc, id) {
95
+ return {
96
+ ...doc,
97
+ parts: doc.parts.filter((p) => p.id !== id),
98
+ wires: (doc.wires ?? []).filter((w) => w.a.partId !== id && w.b.partId !== id)
99
+ };
100
+ }
101
+ const samePin = (x, y) => x.partId === y.partId && x.pin === y.pin;
102
+ const sameWire = (a, b, x, y) => samePin(a, x) && samePin(b, y) || samePin(a, y) && samePin(b, x);
103
+ /** True when the ref names a real part AND a pin that part's definition declares.
104
+ * Keeps invalid (invisible no-op) wires out of persisted, authored docs. */
105
+ const pinExists = (doc, ref) => {
106
+ const part = doc.parts.find((p) => p.id === ref.partId);
107
+ if (!part) return false;
108
+ return getPart(part.kind)?.pins.includes(ref.pin) ?? false;
109
+ };
110
+ /** Connect two pins with a NEW wire edge (parts keep their positions). No-op for a
111
+ * self-link, a duplicate of an existing wire, or an endpoint whose part/pin
112
+ * doesn't exist (an invalid edge that would persist as an invisible no-op). */
113
+ function connect(doc, a, b) {
114
+ if (samePin(a, b)) return doc;
115
+ if (!pinExists(doc, a) || !pinExists(doc, b)) return doc;
116
+ const wires = doc.wires ?? [];
117
+ if (wires.some((w) => sameWire(w.a, w.b, a, b))) return doc;
118
+ const id = freshId("w", new Set(wires.map((w) => w.id)));
119
+ return {
120
+ ...doc,
121
+ wires: [...wires, {
122
+ id,
123
+ a,
124
+ b
125
+ }]
126
+ };
127
+ }
128
+ /** Add a wire the way a user DRAWS one: it is always created (even between pins already on the
129
+ * same net, e.g. a deliberately-routed redundant path) so a drawn wire never silently vanishes.
130
+ * Only a self-link or an endpoint that doesn't exist is rejected. Carries optional bend points. */
131
+ function addWire(doc, a, b, mids) {
132
+ if (samePin(a, b) || !pinExists(doc, a) || !pinExists(doc, b)) return doc;
133
+ const wires = doc.wires ?? [];
134
+ const id = freshId("w", new Set(wires.map((w) => w.id)));
135
+ return {
136
+ ...doc,
137
+ wires: [...wires, mids?.length ? {
138
+ id,
139
+ a,
140
+ b,
141
+ mid: mids
142
+ } : {
143
+ id,
144
+ a,
145
+ b
146
+ }]
147
+ };
148
+ }
149
+ /** Remove a wire edge. Low-level: callers that may orphan a junction wrap with pruneJunctions. */
150
+ function removeWire(doc, wireId) {
151
+ return {
152
+ ...doc,
153
+ wires: (doc.wires ?? []).filter((w) => w.id !== wireId)
154
+ };
155
+ }
156
+ /** Re-target ONE end of a wire to a different pin (drag-to-detach / reconnect). Rejects a move
157
+ * that would make the wire a self-loop, or that points at a pin which doesn't exist. */
158
+ function retargetWire(doc, wireId, end, to) {
159
+ return {
160
+ ...doc,
161
+ wires: (doc.wires ?? []).map((w) => {
162
+ if (w.id !== wireId) return w;
163
+ if (samePin(to, end === "a" ? w.b : w.a) || !pinExists(doc, to)) return w;
164
+ return end === "a" ? {
165
+ ...w,
166
+ a: to
167
+ } : {
168
+ ...w,
169
+ b: to
170
+ };
171
+ })
172
+ };
173
+ }
174
+ /** Remove a wire (the editor's delete-wire action). Junctions are left in place, never
175
+ * auto-removed, so nothing the user placed disappears unexpectedly. */
176
+ function disconnectWire(doc, wireId) {
177
+ return removeWire(doc, wireId);
178
+ }
179
+ /** World position of a pin's terminal (via its PartDef), for geometry on the doc. */
180
+ function terminalOf(doc, ref) {
181
+ const p = doc.parts.find((x) => x.id === ref.partId);
182
+ const def = p && getPart(p.kind);
183
+ return def ? def.terminalAt(p, ref.pin) : void 0;
184
+ }
185
+ /** Manhattan route a pin→pin wire takes (straight if aligned, else a single elbow). */
186
+ function route(a, b) {
187
+ return a.x === b.x || a.y === b.y ? [a, b] : [
188
+ a,
189
+ {
190
+ x: a.x,
191
+ y: b.y
192
+ },
193
+ b
194
+ ];
195
+ }
196
+ /** The full polyline a wire draws: through its bend points if it has any, else the default
197
+ * Manhattan elbow. The renderer, hit-test, and tap all route through this one function. */
198
+ function wirePolyline(ta, mids, tb) {
199
+ return mids.length ? [
200
+ ta,
201
+ ...mids,
202
+ tb
203
+ ] : route(ta, tb);
204
+ }
205
+ /** Set (or clear, when empty) a wire's bend points. */
206
+ function setWireWaypoints(doc, wireId, mids) {
207
+ return {
208
+ ...doc,
209
+ wires: (doc.wires ?? []).map((w) => w.id === wireId ? {
210
+ ...w,
211
+ mid: mids.length ? mids : void 0
212
+ } : w)
213
+ };
214
+ }
215
+ /** Closest point on a polyline to p (so a tapped junction sits exactly on the wire). */
216
+ function projectOnPolyline(p, pts) {
217
+ let best = pts[0] ?? p, bd = Infinity;
218
+ for (let i = 0; i < pts.length - 1; i++) {
219
+ const a = pts[i], b = pts[i + 1];
220
+ const dx = b.x - a.x, dy = b.y - a.y, len2 = dx * dx + dy * dy;
221
+ const t = len2 ? Math.max(0, Math.min(1, ((p.x - a.x) * dx + (p.y - a.y) * dy) / len2)) : 0;
222
+ const pt = {
223
+ x: a.x + t * dx,
224
+ y: a.y + t * dy
225
+ };
226
+ const d = Math.hypot(p.x - pt.x, p.y - pt.y);
227
+ if (d < bd) {
228
+ bd = d;
229
+ best = pt;
230
+ }
231
+ }
232
+ return best;
233
+ }
234
+ /** Place a free junction (a 'node' part) at a point; returns its pin for wiring. */
235
+ function addJunction(doc, at) {
236
+ const d = addPart(doc, "node", at);
237
+ return {
238
+ doc: d,
239
+ pin: {
240
+ partId: d.parts[d.parts.length - 1].id,
241
+ pin: "j"
242
+ }
243
+ };
244
+ }
245
+ /**
246
+ * Tap an existing wire at a point: drop a junction ON the wire (projected onto its route)
247
+ * and SPLIT the wire into two that meet there, so a new lead can branch off mid-span. The
248
+ * junction is a `node` part (no element), so the three wires share one net and the solver
249
+ * needs no special mid-wire case. Returns the junction pin to wire the new lead to.
250
+ */
251
+ function tapWire(doc, wireId, at) {
252
+ const wire = (doc.wires ?? []).find((w) => w.id === wireId);
253
+ const ta = wire && terminalOf(doc, wire.a);
254
+ const tb = wire && terminalOf(doc, wire.b);
255
+ if (!wire || !ta || !tb) return addJunction(doc, at);
256
+ const { doc: withNode, pin } = addJunction(doc, projectOnPolyline(at, wirePolyline(ta, wire.mid ?? [], tb)));
257
+ let d = connect(withNode, wire.a, pin);
258
+ d = connect(d, pin, wire.b);
259
+ d = removeWire(d, wireId);
260
+ return {
261
+ doc: d,
262
+ pin
263
+ };
264
+ }
265
+ /** Drop a part ONTO a wire: insert it in series. The wire is removed and the part's two
266
+ * ends are wired to the wire's two original endpoints (a → pin0, pin1 → b). */
267
+ function spliceIntoWire(doc, wireId, kind, at) {
268
+ const wire = (doc.wires ?? []).find((w) => w.id === wireId);
269
+ const def = getPart(kind);
270
+ if (!wire || !def || def.pins.length < 2) return addPart(doc, kind, at);
271
+ let d = addPart(doc, kind, at);
272
+ const part = d.parts[d.parts.length - 1];
273
+ if (!part) return d;
274
+ const [p0, p1] = def.pins;
275
+ d = removeWire(d, wireId);
276
+ d = connect(d, wire.a, {
277
+ partId: part.id,
278
+ pin: p0
279
+ });
280
+ d = connect(d, {
281
+ partId: part.id,
282
+ pin: p1
283
+ }, wire.b);
284
+ return d;
285
+ }
286
+ /** Toggle a pin's connection to ground. Grounding ties the pin's net to the reference;
287
+ * toggling again gives the pin a fresh independent node (un-grounds it), so a short made
288
+ * by grounding both terminals of a source can always be undone. */
289
+ function setGround(doc, ref) {
290
+ const part = doc.parts.find((p) => p.id === ref.partId);
291
+ if (!part) return doc;
292
+ const next = part.pins[ref.pin] === "gnd" ? freshId("nd", nodeIdsOf(doc)) : "gnd";
293
+ return {
294
+ ...doc,
295
+ parts: doc.parts.map((p) => p.id === ref.partId ? {
296
+ ...p,
297
+ pins: {
298
+ ...p.pins,
299
+ [ref.pin]: next
300
+ }
301
+ } : p)
302
+ };
303
+ }
304
+
305
+ //#endregion
306
+ export { addJunction, addPart, addWire, connect, deletePart, disconnectWire, movePart, pruneJunctions, removeWire, retargetWire, rotatePart, setGround, setWireWaypoints, spliceIntoWire, tapWire, terminalOf, updateProps, wirePolyline };
@@ -0,0 +1,121 @@
1
+ 'use client';
2
+
3
+ import { jsx, jsxs } from "react/jsx-runtime";
4
+
5
+ //#region src/build/editor-ui.tsx
6
+ const R = "var(--radius, 0.625rem)";
7
+ const BORDER = "var(--border, oklch(0.92 0.004 286))";
8
+ const MUTED = "var(--muted-foreground, oklch(0.55 0.01 286))";
9
+ const FG = "var(--foreground, oklch(0.21 0.006 286))";
10
+ function Panel({ title, children, style }) {
11
+ return /* @__PURE__ */ jsxs("div", {
12
+ style: {
13
+ background: "var(--card, #fff)",
14
+ color: FG,
15
+ border: `1px solid ${BORDER}`,
16
+ borderRadius: R,
17
+ padding: 12,
18
+ display: "flex",
19
+ flexDirection: "column",
20
+ gap: 10,
21
+ ...style
22
+ },
23
+ children: [title && /* @__PURE__ */ jsx("div", {
24
+ style: {
25
+ fontSize: 11,
26
+ fontWeight: 700,
27
+ letterSpacing: "0.04em",
28
+ textTransform: "uppercase",
29
+ color: MUTED
30
+ },
31
+ children: title
32
+ }), children]
33
+ });
34
+ }
35
+ function EBtn({ children, onClick, active, variant = "default", title, disabled }) {
36
+ return /* @__PURE__ */ jsx("button", {
37
+ type: "button",
38
+ onClick,
39
+ title,
40
+ disabled,
41
+ style: {
42
+ display: "inline-flex",
43
+ alignItems: "center",
44
+ justifyContent: "center",
45
+ gap: 6,
46
+ padding: "7px 11px",
47
+ fontSize: 13,
48
+ fontWeight: 600,
49
+ lineHeight: 1,
50
+ background: variant === "primary" || active ? "var(--primary, oklch(0.21 0.006 286))" : variant === "danger" ? "var(--destructive, oklch(0.58 0.22 27))" : variant === "ghost" ? "transparent" : "var(--secondary, oklch(0.97 0.001 286))",
51
+ color: variant === "primary" || active ? "var(--primary-foreground, oklch(0.98 0 0))" : variant === "danger" ? "var(--destructive-foreground, #fff)" : FG,
52
+ border: `1px solid ${variant === "ghost" ? BORDER : "transparent"}`,
53
+ borderRadius: `calc(${R} - 2px)`,
54
+ cursor: disabled ? "not-allowed" : "pointer",
55
+ opacity: disabled ? .5 : 1,
56
+ transition: "background 120ms, opacity 120ms",
57
+ whiteSpace: "nowrap"
58
+ },
59
+ children
60
+ });
61
+ }
62
+ function Field({ label, children }) {
63
+ return /* @__PURE__ */ jsxs("label", {
64
+ style: {
65
+ display: "grid",
66
+ gridTemplateColumns: "1fr auto",
67
+ alignItems: "center",
68
+ gap: 8,
69
+ fontSize: 13,
70
+ color: FG
71
+ },
72
+ children: [/* @__PURE__ */ jsx("span", {
73
+ style: { color: MUTED },
74
+ children: label
75
+ }), children]
76
+ });
77
+ }
78
+ function NumInput({ value, onChange, step = 1, min, ariaLabel }) {
79
+ return /* @__PURE__ */ jsx("input", {
80
+ type: "number",
81
+ value,
82
+ step,
83
+ min,
84
+ "aria-label": ariaLabel,
85
+ onChange: (e) => {
86
+ const v = Number(e.target.value);
87
+ if (Number.isFinite(v)) onChange(v);
88
+ },
89
+ style: {
90
+ width: 92,
91
+ padding: "5px 8px",
92
+ fontSize: 13,
93
+ textAlign: "right",
94
+ fontVariantNumeric: "tabular-nums",
95
+ color: FG,
96
+ background: "var(--background, #fff)",
97
+ border: `1px solid ${BORDER}`,
98
+ borderRadius: `calc(${R} - 3px)`
99
+ }
100
+ });
101
+ }
102
+ function TextInput({ value, onChange, ariaLabel }) {
103
+ return /* @__PURE__ */ jsx("input", {
104
+ type: "text",
105
+ value,
106
+ "aria-label": ariaLabel,
107
+ onChange: (e) => onChange(e.target.value),
108
+ style: {
109
+ width: 120,
110
+ padding: "5px 8px",
111
+ fontSize: 13,
112
+ color: FG,
113
+ background: "var(--background, #fff)",
114
+ border: `1px solid ${BORDER}`,
115
+ borderRadius: `calc(${R} - 3px)`
116
+ }
117
+ });
118
+ }
119
+
120
+ //#endregion
121
+ export { EBtn, Field, NumInput, Panel, TextInput };
@@ -0,0 +1,14 @@
1
+ import { CircuitDoc, CircuitSolution } from "./contract.mjs";
2
+
3
+ //#region src/build/flow.d.ts
4
+ declare const pinKey: (id: string, pin: string) => string;
5
+ declare const nodeKey: (nid: string) => string;
6
+ interface WireFlow {
7
+ /** signed current from pin/node `u` to pin/node `v` (amps); positive = u→v. */
8
+ current: (u: string, v: string) => number;
9
+ }
10
+ /** Threshold below which a wire is treated as carrying no current (float-noise / open branch). */
11
+ declare const FLOW_EPS = 0.000001;
12
+ declare function wireCurrents(doc: CircuitDoc, sol: CircuitSolution): WireFlow;
13
+ //#endregion
14
+ export { FLOW_EPS, WireFlow, nodeKey, pinKey, wireCurrents };
@@ -0,0 +1,119 @@
1
+ import { getPart } from "./registry.mjs";
2
+
3
+ //#region src/build/flow.ts
4
+ /**
5
+ * Per-wire current for the flow animation. The MNA solve (`solveCircuit`) yields node
6
+ * voltages and COMPONENT branch currents, but a net is one equipotential region, so it
7
+ * cannot say how much current each individual WIRE carries. Without that, the renderer
8
+ * animated every wire in an energised net, even dead-end stubs and bypassed branches, so
9
+ * a learner saw "current flowing through every path" regardless of the real circuit.
10
+ *
11
+ * We recover honest per-wire current with a small resistor-network solve: build the graph
12
+ * of pins/nodes joined by wires, give each wire a unit conductance, inject each component's
13
+ * KNOWN terminal current at its pins, and solve the graph Laplacian L·v = b for node
14
+ * potentials. A wire's current is then v_u − v_v. This is exact on a series path (it carries
15
+ * the full loop current), splits evenly across parallel wires, and is ZERO on a dead branch,
16
+ * so the animation flows only where current actually flows. When a wire shorts past a
17
+ * component, that wire carries the current while the component (v ≈ 0 across it) goes dark.
18
+ */
19
+ const fnum = (v, d) => typeof v === "number" && Number.isFinite(v) ? v : d;
20
+ const pinKey = (id, pin) => `${id} ${pin}`;
21
+ const nodeKey = (nid) => `node:${nid}`;
22
+ /** current the part drives a→b internally (n1→n2), reused from the part state convention. */
23
+ const branchAB = (p, sol) => p.kind === "resistor" || p.kind === "bulb" ? (sol.pinV(p.id, "a") - sol.pinV(p.id, "b")) / fnum(p.props?.ohms, p.kind === "bulb" ? 100 : 1e3) : sol.current[p.id] ?? 0;
24
+ /** Dense linear solve A·x = b via Gaussian elimination with partial pivoting; null if singular. */
25
+ function solveDense(A, b) {
26
+ const n = b.length;
27
+ const M = A.map((r, i) => [...r, b[i]]);
28
+ for (let c = 0; c < n; c++) {
29
+ let piv = c;
30
+ for (let r = c + 1; r < n; r++) if (Math.abs(M[r][c]) > Math.abs(M[piv][c])) piv = r;
31
+ if (Math.abs(M[piv][c]) < 1e-12) return null;
32
+ [M[c], M[piv]] = [M[piv], M[c]];
33
+ const pv = M[c][c];
34
+ for (let r = 0; r < n; r++) {
35
+ if (r === c) continue;
36
+ const f = M[r][c] / pv;
37
+ if (f === 0) continue;
38
+ for (let k = c; k <= n; k++) M[r][k] -= f * M[c][k];
39
+ }
40
+ }
41
+ return M.map((r, i) => r[n] / r[i]);
42
+ }
43
+ /** Threshold below which a wire is treated as carrying no current (float-noise / open branch). */
44
+ const FLOW_EPS = 1e-6;
45
+ function wireCurrents(doc, sol) {
46
+ if (!sol.ok) return { current: () => 0 };
47
+ const edges = [];
48
+ const nodePins = /* @__PURE__ */ new Map();
49
+ for (const p of doc.parts) {
50
+ const def = getPart(p.kind);
51
+ if (!def) continue;
52
+ for (const pin of def.pins) {
53
+ const nid = p.pins?.[pin];
54
+ if (nid) (nodePins.get(nid) ?? nodePins.set(nid, []).get(nid)).push(pinKey(p.id, pin));
55
+ }
56
+ }
57
+ for (const [nid, pins] of nodePins) if (pins.length >= 2) for (const pk of pins) edges.push([pk, nodeKey(nid)]);
58
+ for (const w of doc.wires ?? []) edges.push([pinKey(w.a.partId, w.a.pin), pinKey(w.b.partId, w.b.pin)]);
59
+ const idx = /* @__PURE__ */ new Map();
60
+ const vid = (k) => {
61
+ let n = idx.get(k);
62
+ if (n === void 0) {
63
+ n = idx.size;
64
+ idx.set(k, n);
65
+ }
66
+ return n;
67
+ };
68
+ for (const [u, v] of edges) {
69
+ vid(u);
70
+ vid(v);
71
+ }
72
+ const N = idx.size;
73
+ if (N === 0) return { current: () => 0 };
74
+ const b = new Array(N).fill(0);
75
+ for (const p of doc.parts) {
76
+ const def = getPart(p.kind);
77
+ if (!def) continue;
78
+ const Ib = branchAB(p, sol);
79
+ const p0 = def.pins[0] ? idx.get(pinKey(p.id, def.pins[0])) : void 0;
80
+ const p1 = def.pins[1] ? idx.get(pinKey(p.id, def.pins[1])) : void 0;
81
+ if (p0 !== void 0) b[p0] -= Ib;
82
+ if (p1 !== void 0) b[p1] += Ib;
83
+ }
84
+ const parent = Array.from({ length: N }, (_, i) => i);
85
+ const find = (x) => {
86
+ while (parent[x] !== x) {
87
+ parent[x] = parent[parent[x]];
88
+ x = parent[x];
89
+ }
90
+ return x;
91
+ };
92
+ const L = Array.from({ length: N }, () => new Array(N).fill(0));
93
+ for (const [u, v] of edges) {
94
+ const a = idx.get(u), c = idx.get(v);
95
+ L[a][a] += 1;
96
+ L[c][c] += 1;
97
+ L[a][c] -= 1;
98
+ L[c][a] -= 1;
99
+ parent[find(a)] = find(c);
100
+ }
101
+ const pots = new Array(N).fill(0);
102
+ const comps = /* @__PURE__ */ new Map();
103
+ for (let i = 0; i < N; i++) (comps.get(find(i)) ?? comps.set(find(i), []).get(find(i))).push(i);
104
+ for (const verts of comps.values()) {
105
+ if (verts.length < 2) continue;
106
+ const unknown = verts.slice(1);
107
+ const x = solveDense(unknown.map((ri) => unknown.map((cj) => L[ri][cj])), unknown.map((ri) => b[ri]));
108
+ if (x) unknown.forEach((vi, i) => {
109
+ pots[vi] = x[i];
110
+ });
111
+ }
112
+ return { current: (u, v) => {
113
+ const iu = idx.get(u), iv = idx.get(v);
114
+ return iu === void 0 || iv === void 0 ? 0 : pots[iu] - pots[iv];
115
+ } };
116
+ }
117
+
118
+ //#endregion
119
+ export { FLOW_EPS, nodeKey, pinKey, wireCurrents };
@@ -0,0 +1,10 @@
1
+ import { CNode, CircuitDoc, CircuitSolution, PartDef, PartInstance, PartKind, PartState, PinRef, Wire } from "./contract.mjs";
2
+ import { getPart, listParts, registerPart } from "./registry.mjs";
3
+ import { partState, solveCircuit } from "./solve.mjs";
4
+ import { FLOW_EPS, WireFlow, nodeKey, pinKey, wireCurrents } from "./flow.mjs";
5
+ import { registerBuiltinParts } from "./parts/index.mjs";
6
+ import { CircuitEditorBag, CircuitScene, CircuitSceneProps } from "./CircuitScene.mjs";
7
+ import { CircuitPlayer, CircuitPlayerProps } from "./CircuitPlayer.mjs";
8
+ import { CircuitEditor, CircuitEditorProps } from "./CircuitEditor.mjs";
9
+ import { addJunction, addPart, addWire, connect, deletePart, disconnectWire, movePart, pruneJunctions, removeWire, retargetWire, rotatePart, setGround, setWireWaypoints, spliceIntoWire, tapWire, terminalOf, updateProps, wirePolyline } from "./editor-ops.mjs";
10
+ export { type CNode, type CircuitDoc, CircuitEditor, type CircuitEditorBag, type CircuitEditorProps, CircuitPlayer, type CircuitPlayerProps, CircuitScene, type CircuitSceneProps, type CircuitSolution, FLOW_EPS, type PartDef, type PartInstance, type PartKind, type PartState, type PinRef, type Wire, type WireFlow, addJunction, addPart, addWire, connect, deletePart, disconnectWire, getPart, listParts, movePart, nodeKey, partState, pinKey, pruneJunctions, registerBuiltinParts, registerPart, removeWire, retargetWire, rotatePart, setGround, setWireWaypoints, solveCircuit, spliceIntoWire, tapWire, terminalOf, updateProps, wireCurrents, wirePolyline };
@@ -0,0 +1,10 @@
1
+ import { getPart, listParts, registerPart } from "./registry.mjs";
2
+ import { registerBuiltinParts } from "./parts/index.mjs";
3
+ import { partState, solveCircuit } from "./solve.mjs";
4
+ import { FLOW_EPS, nodeKey, pinKey, wireCurrents } from "./flow.mjs";
5
+ import { addJunction, addPart, addWire, connect, deletePart, disconnectWire, movePart, pruneJunctions, removeWire, retargetWire, rotatePart, setGround, setWireWaypoints, spliceIntoWire, tapWire, terminalOf, updateProps, wirePolyline } from "./editor-ops.mjs";
6
+ import { CircuitScene } from "./CircuitScene.mjs";
7
+ import { CircuitPlayer } from "./CircuitPlayer.mjs";
8
+ import { CircuitEditor } from "./CircuitEditor.mjs";
9
+
10
+ export { CircuitEditor, CircuitPlayer, CircuitScene, FLOW_EPS, addJunction, addPart, addWire, connect, deletePart, disconnectWire, getPart, listParts, movePart, nodeKey, partState, pinKey, pruneJunctions, registerBuiltinParts, registerPart, removeWire, retargetWire, rotatePart, setGround, setWireWaypoints, solveCircuit, spliceIntoWire, tapWire, terminalOf, updateProps, wireCurrents, wirePolyline };
@@ -0,0 +1 @@
1
+ export { };
@@ -0,0 +1,32 @@
1
+ 'use client';
2
+
3
+ import { AmmeterGlyph } from "../../kit/electronics.mjs";
4
+ import { render2, term2 } from "./shared.mjs";
5
+ import { jsx } from "react/jsx-runtime";
6
+
7
+ //#region src/build/parts/ammeter.tsx
8
+ /** Ammeter: an ideal 0 V branch that reads the current through it (mA). Drop it in series. */
9
+ const AMMETER = {
10
+ kind: "ammeter",
11
+ label: "Ammeter",
12
+ pins: ["a", "b"],
13
+ defaultProps: {},
14
+ terminalAt: term2,
15
+ toElems: (i, n) => [{
16
+ kind: "V",
17
+ n1: n("a"),
18
+ n2: n("b"),
19
+ value: 0,
20
+ id: i.id
21
+ }],
22
+ render: (i, s) => render2(i, void 0, (cx, cy, h) => /* @__PURE__ */ jsx(AmmeterGlyph, {
23
+ cx,
24
+ cy,
25
+ half: h,
26
+ live: s.live,
27
+ reading: `${(Math.abs(s.i) * 1e3).toFixed(Math.abs(s.i) >= .0995 ? 0 : 1)} mA`
28
+ }))
29
+ };
30
+
31
+ //#endregion
32
+ export { AMMETER };
@@ -0,0 +1 @@
1
+ export { };