@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.
- package/dist/_virtual/_rolldown/runtime.mjs +18 -0
- package/dist/biology/enzyme-rate/preset.mjs +5 -5
- package/dist/biology/genetic-cross/core.d.mts +7 -7
- package/dist/biology/genetic-cross/core.mjs +4 -4
- package/dist/biology/genetic-cross/grid.mjs +132 -123
- package/dist/biology/genetic-cross/preset.mjs +4 -4
- package/dist/biology/genetic-cross/sex-linked.mjs +7 -7
- package/dist/biology/photosynthesis-factors/preset.mjs +8 -8
- package/dist/biology/respiration/preset.mjs +4 -4
- package/dist/biology/sequence/central-dogma.mjs +5 -5
- package/dist/biology/sequence/core.d.mts +6 -6
- package/dist/biology/sequence/core.mjs +1 -1
- package/dist/biology/sequence/preset.mjs +6 -6
- package/dist/blocks/authoring.mjs +5 -5
- package/dist/blocks/biology.d.mts +2 -2
- package/dist/blocks/biology.mjs +5 -5
- package/dist/blocks/chem.d.mts +2 -2
- package/dist/blocks/chem.mjs +13 -13
- package/dist/blocks/circuits.d.mts +293 -4
- package/dist/blocks/circuits.mjs +874 -9
- package/dist/blocks/discrete.d.mts +30 -2
- package/dist/blocks/discrete.mjs +74 -4
- package/dist/blocks/economics.mjs +1 -1
- package/dist/blocks/geography.mjs +1 -1
- package/dist/blocks/geometry.mjs +3 -3
- package/dist/blocks/ict.d.mts +90 -1
- package/dist/blocks/ict.mjs +217 -7
- package/dist/blocks/index.d.mts +3064 -657
- package/dist/blocks/index.mjs +9 -9
- package/dist/blocks/lab-block.mjs +5 -5
- package/dist/blocks/lab-config.d.mts +1 -1
- package/dist/blocks/lab-config.mjs +4 -4
- package/dist/blocks/lab-gallery.d.mts +1 -1
- package/dist/blocks/lab-gallery.mjs +2 -2
- package/dist/blocks/language.d.mts +6 -6
- package/dist/blocks/language.mjs +12 -12
- package/dist/blocks/lesson.mjs +4 -4
- package/dist/blocks/math.d.mts +577 -11
- package/dist/blocks/math.mjs +1648 -14
- package/dist/blocks/ml.d.mts +45 -1
- package/dist/blocks/ml.mjs +80 -6
- package/dist/blocks/physics.d.mts +9 -4
- package/dist/blocks/physics.mjs +75 -28
- package/dist/blocks/statistics.mjs +1 -1
- package/dist/build/CircuitEditor.d.mts +14 -0
- package/dist/build/CircuitEditor.mjs +787 -0
- package/dist/build/CircuitPlayer.d.mts +19 -0
- package/dist/build/CircuitPlayer.mjs +53 -0
- package/dist/build/CircuitScene.d.mts +61 -0
- package/dist/build/CircuitScene.mjs +383 -0
- package/dist/build/contract.d.mts +116 -0
- package/dist/build/editor-ops.d.mts +65 -0
- package/dist/build/editor-ops.mjs +306 -0
- package/dist/build/editor-ui.mjs +121 -0
- package/dist/build/flow.d.mts +14 -0
- package/dist/build/flow.mjs +119 -0
- package/dist/build/index.d.mts +10 -0
- package/dist/build/index.mjs +10 -0
- package/dist/build/parts/ammeter.d.mts +1 -0
- package/dist/build/parts/ammeter.mjs +32 -0
- package/dist/build/parts/bulb.d.mts +1 -0
- package/dist/build/parts/bulb.mjs +50 -0
- package/dist/build/parts/capacitor.d.mts +1 -0
- package/dist/build/parts/capacitor.mjs +26 -0
- package/dist/build/parts/cell.d.mts +1 -0
- package/dist/build/parts/cell.mjs +40 -0
- package/dist/build/parts/diode.d.mts +1 -0
- package/dist/build/parts/diode.mjs +33 -0
- package/dist/build/parts/index.d.mts +5 -0
- package/dist/build/parts/index.mjs +43 -0
- package/dist/build/parts/mosfet.d.mts +1 -0
- package/dist/build/parts/mosfet.mjs +95 -0
- package/dist/build/parts/node.d.mts +1 -0
- package/dist/build/parts/node.mjs +32 -0
- package/dist/build/parts/resistor.d.mts +1 -0
- package/dist/build/parts/resistor.mjs +49 -0
- package/dist/build/parts/shared.mjs +42 -0
- package/dist/build/parts/switch.d.mts +1 -0
- package/dist/build/parts/switch.mjs +34 -0
- package/dist/build/parts.d.mts +1 -0
- package/dist/build/registry.d.mts +9 -0
- package/dist/build/registry.mjs +15 -0
- package/dist/build/solve.d.mts +8 -0
- package/dist/build/solve.mjs +0 -0
- package/dist/catalog/registry.d.mts +2 -2
- package/dist/catalog/templates.d.mts +1 -1
- package/dist/catalog/templates.mjs +6 -6
- package/dist/chem/battery.mjs +1 -1
- package/dist/chem/bohr-atom.mjs +4 -4
- package/dist/chem/diffusion/preset.mjs +4 -4
- package/dist/chem/electrochem/preset.mjs +5 -5
- package/dist/chem/equilibrium/preset.d.mts +1 -1
- package/dist/chem/equilibrium/preset.mjs +6 -6
- package/dist/chem/gas-box/preset.mjs +6 -6
- package/dist/chem/kinetics/preset.mjs +6 -6
- package/dist/chem/periodic-trends/preset.mjs +7 -7
- package/dist/chem/reaction-lab.mjs +3 -3
- package/dist/chem/reaction-profile.mjs +4 -4
- package/dist/chem/solution/dilution.mjs +6 -6
- package/dist/chem/solution/field.d.mts +2 -2
- package/dist/chem/solution/field.mjs +2 -2
- package/dist/chem/solution/solution-box.mjs +7 -7
- package/dist/chem/stoichiometry/preset.mjs +5 -5
- package/dist/chem/titration/preset.mjs +5 -5
- package/dist/circuits/ac-dc/asset.mjs +1 -1
- package/dist/circuits/ac-dc/preset.mjs +2 -2
- package/dist/circuits/brownout/index.d.mts +1 -0
- package/dist/circuits/brownout/preset.d.mts +22 -0
- package/dist/circuits/brownout/preset.mjs +399 -0
- package/dist/circuits/capacitor-leak/preset.mjs +13 -8
- package/dist/circuits/circuit/asset.mjs +71 -14
- package/dist/circuits/circuit/preset.mjs +23 -5
- package/dist/circuits/circuit-builder.mjs +60 -132
- package/dist/circuits/circuit-lab.mjs +60 -40
- package/dist/circuits/cmos-gate/index.d.mts +1 -0
- package/dist/circuits/cmos-gate/preset.d.mts +75 -0
- package/dist/circuits/cmos-gate/preset.mjs +1491 -0
- package/dist/circuits/diode/index.d.mts +1 -0
- package/dist/circuits/diode/preset.d.mts +25 -0
- package/dist/circuits/diode/preset.mjs +266 -0
- package/dist/circuits/index.d.mts +7 -1
- package/dist/circuits/index.mjs +7 -1
- package/dist/circuits/rc-charging/index.d.mts +1 -0
- package/dist/circuits/rc-charging/preset.d.mts +27 -0
- package/dist/circuits/rc-charging/preset.mjs +329 -0
- package/dist/circuits/semiconductor/index.d.mts +1 -0
- package/dist/circuits/semiconductor/preset.d.mts +102 -0
- package/dist/circuits/semiconductor/preset.mjs +1855 -0
- package/dist/circuits/transistor/index.d.mts +1 -0
- package/dist/circuits/transistor/preset.d.mts +27 -0
- package/dist/circuits/transistor/preset.mjs +329 -0
- package/dist/commerce/accounting/core.d.mts +1 -1
- package/dist/commerce/accounting/equation-balance.mjs +5 -5
- package/dist/commerce/accounting/journal-poster.mjs +8 -8
- package/dist/commerce/accounting/statement-sorter.mjs +4 -4
- package/dist/commerce/economics/core.d.mts +2 -2
- package/dist/commerce/economics/core.mjs +1 -1
- package/dist/commerce/economics/demand-shift-vs-move.mjs +6 -6
- package/dist/commerce/economics/elasticity-revenue.mjs +6 -6
- package/dist/commerce/economics/market-equilibrium.mjs +5 -5
- package/dist/core/easing.d.mts +3 -3
- package/dist/core/easing.mjs +2 -2
- package/dist/core/numeric.d.mts +3 -3
- package/dist/core/numeric.mjs +2 -2
- package/dist/core/reactive.d.mts +1 -1
- package/dist/core/reactive.mjs +1 -1
- package/dist/core/rng.d.mts +2 -2
- package/dist/core/rng.mjs +1 -1
- package/dist/core/tex.mjs +2 -2
- package/dist/core/timeline.d.mts +1 -1
- package/dist/core/timeline.mjs +1 -1
- package/dist/core/util.mjs +11 -1
- package/dist/discrete/arrangements/preset.mjs +6 -14
- package/dist/discrete/bayes/preset.mjs +43 -35
- package/dist/discrete/binomial/preset.mjs +2 -2
- package/dist/discrete/combination-studio/figure.d.mts +6 -0
- package/dist/discrete/combination-studio/figure.mjs +159 -0
- package/dist/discrete/combination-studio/index.d.mts +2 -0
- package/dist/discrete/combination-studio/preset.d.mts +44 -0
- package/dist/discrete/combination-studio/preset.mjs +440 -0
- package/dist/discrete/core/combinatorics.d.mts +23 -3
- package/dist/discrete/core/combinatorics.mjs +38 -3
- package/dist/discrete/core/pigeonhole.d.mts +1 -1
- package/dist/discrete/core/pigeonhole.mjs +1 -1
- package/dist/discrete/core/probability.d.mts +3 -3
- package/dist/discrete/core/probability.mjs +3 -3
- package/dist/discrete/core/sets.d.mts +1 -1
- package/dist/discrete/counting-slots/preset.mjs +8 -8
- package/dist/discrete/counting-tree/preset.mjs +65 -8
- package/dist/discrete/expected-value/preset.mjs +13 -13
- package/dist/discrete/hypergeometric/preset.mjs +48 -15
- package/dist/discrete/index.d.mts +4 -2
- package/dist/discrete/index.mjs +4 -2
- package/dist/discrete/karnaugh/preset.mjs +26 -20
- package/dist/discrete/lln/preset.mjs +44 -3
- package/dist/discrete/logic-circuit/preset.mjs +2 -2
- package/dist/discrete/monte-carlo/preset.d.mts +1 -1
- package/dist/discrete/monte-carlo/preset.mjs +14 -14
- package/dist/discrete/monty-hall/preset.mjs +6 -6
- package/dist/discrete/outcome-builder/preset.mjs +3 -3
- package/dist/discrete/pascal/preset.mjs +37 -7
- package/dist/discrete/rules.d.mts +20 -0
- package/dist/discrete/rules.mjs +264 -0
- package/dist/discrete/sample-space/preset.mjs +4 -4
- package/dist/discrete/selection/preset.mjs +7 -13
- package/dist/discrete/truth-table/preset.mjs +32 -9
- package/dist/discrete/venn/preset.mjs +71 -48
- package/dist/geography/cycle-lab/preset.mjs +17 -10
- package/dist/geography/cycles.d.mts +3 -3
- package/dist/geography/cycles.mjs +3 -3
- package/dist/geometry/board/preset.d.mts +2 -0
- package/dist/geometry/board/preset.mjs +11 -15
- package/dist/geometry/builder.mjs +3 -3
- package/dist/ict/number-systems/base-odometer.mjs +4 -4
- package/dist/ict/number-systems/bit-grouper.d.mts +1 -1
- package/dist/ict/number-systems/bit-grouper.mjs +4 -4
- package/dist/ict/number-systems/place-value-dial.d.mts +1 -1
- package/dist/ict/number-systems/place-value-dial.mjs +3 -3
- package/dist/ict/number-systems/wheel.d.mts +3 -3
- package/dist/ict/number-systems/wheel.mjs +4 -4
- package/dist/kit/annotate.mjs +3 -3
- package/dist/kit/answer-check.d.mts +2 -2
- package/dist/kit/answer-check.mjs +34 -6
- package/dist/kit/ask.d.mts +19 -0
- package/dist/kit/ask.mjs +46 -0
- package/dist/kit/bar-strip.mjs +53 -0
- package/dist/kit/calc.d.mts +33 -0
- package/dist/kit/calc.mjs +27 -0
- package/dist/kit/carrier-engine.mjs +147 -0
- package/dist/kit/clue-scene.d.mts +86 -0
- package/dist/kit/clue-scene.mjs +424 -0
- package/dist/kit/cluster.d.mts +30 -0
- package/dist/kit/cluster.mjs +81 -0
- package/dist/kit/controls.mjs +11 -5
- package/dist/kit/coords.d.mts +88 -0
- package/dist/kit/coords.mjs +192 -0
- package/dist/kit/data-scene.d.mts +27 -0
- package/dist/kit/data-scene.mjs +199 -0
- package/dist/kit/diagram.mjs +111 -50
- package/dist/kit/electronics.mjs +552 -60
- package/dist/kit/expr-analysis.d.mts +18 -6
- package/dist/kit/expr-analysis.mjs +82 -28
- package/dist/kit/frame.d.mts +3 -3
- package/dist/kit/frame.mjs +25 -6
- package/dist/kit/gameshow.mjs +2 -2
- package/dist/kit/index.d.mts +14 -2
- package/dist/kit/index.mjs +13 -1
- package/dist/kit/logic-gates.mjs +246 -47
- package/dist/kit/palette.mjs +26 -0
- package/dist/kit/pedagogy.d.mts +4 -4
- package/dist/kit/pedagogy.mjs +21 -17
- package/dist/kit/play.d.mts +1 -1
- package/dist/kit/play.mjs +3 -3
- package/dist/kit/predict.d.mts +55 -0
- package/dist/kit/predict.mjs +146 -0
- package/dist/kit/receipt.d.mts +29 -0
- package/dist/kit/receipt.mjs +94 -0
- package/dist/kit/rich.mjs +2 -2
- package/dist/kit/rule.d.mts +59 -0
- package/dist/kit/rule.mjs +215 -0
- package/dist/kit/scale.mjs +1 -1
- package/dist/kit/scene-library.d.mts +22 -0
- package/dist/kit/scene-library.mjs +311 -0
- package/dist/kit/scene-studio.d.mts +14 -0
- package/dist/kit/scene-studio.mjs +338 -0
- package/dist/kit/scenes.d.mts +31 -0
- package/dist/kit/scenes.mjs +569 -0
- package/dist/kit/slot-fill.d.mts +61 -0
- package/dist/kit/slot-fill.mjs +207 -0
- package/dist/kit/solve.d.mts +21 -0
- package/dist/kit/solve.mjs +75 -0
- package/dist/kit/space.mjs +5 -5
- package/dist/kit/steps.mjs +2 -2
- package/dist/kit/vessel.d.mts +69 -0
- package/dist/kit/vessel.mjs +191 -0
- package/dist/language/agreement/preset.mjs +2 -2
- package/dist/language/article-lens/preset.d.mts +1 -1
- package/dist/language/article-lens/preset.mjs +8 -8
- package/dist/language/deck.d.mts +3 -3
- package/dist/language/deck.mjs +1 -1
- package/dist/language/preposition-scene/preset.d.mts +2 -2
- package/dist/language/preposition-scene/preset.mjs +5 -5
- package/dist/language/sentence-builder/preset.mjs +5 -5
- package/dist/language/transform/preset.d.mts +2 -2
- package/dist/language/transform/preset.mjs +5 -5
- package/dist/language/ui.d.mts +3 -3
- package/dist/language/ui.mjs +4 -4
- package/dist/language/word-match/preset.mjs +3 -3
- package/dist/logic/LogicBuildLab.d.mts +22 -0
- package/dist/logic/LogicBuildLab.mjs +170 -0
- package/dist/logic/LogicEditScene.d.mts +31 -0
- package/dist/logic/LogicEditScene.mjs +276 -0
- package/dist/logic/LogicEditor.d.mts +14 -0
- package/dist/logic/LogicEditor.mjs +413 -0
- package/dist/logic/LogicScene.d.mts +32 -0
- package/dist/logic/LogicScene.mjs +277 -0
- package/dist/logic/contract.d.mts +72 -0
- package/dist/logic/display.d.mts +24 -0
- package/dist/logic/display.mjs +127 -0
- package/dist/logic/edit-ops.d.mts +44 -0
- package/dist/logic/edit-ops.mjs +177 -0
- package/dist/logic/evaluate.d.mts +11 -0
- package/dist/logic/evaluate.mjs +93 -0
- package/dist/logic/gates.d.mts +10 -0
- package/dist/logic/gates.mjs +73 -0
- package/dist/logic/index.d.mts +14 -0
- package/dist/logic/index.mjs +13 -0
- package/dist/logic/lab.d.mts +32 -0
- package/dist/logic/lab.mjs +160 -0
- package/dist/logic/presets.d.mts +12 -0
- package/dist/logic/presets.mjs +241 -0
- package/dist/logic/registry.d.mts +9 -0
- package/dist/logic/registry.mjs +15 -0
- package/dist/math/area-model/preset.mjs +70 -44
- package/dist/math/balance-algebra/preset.mjs +14 -5
- package/dist/math/broken-tree/index.d.mts +1 -0
- package/dist/math/broken-tree/preset.d.mts +26 -0
- package/dist/math/broken-tree/preset.mjs +435 -0
- package/dist/math/circle/index.d.mts +1 -0
- package/dist/math/circle/preset.d.mts +44 -0
- package/dist/math/circle/preset.mjs +198 -0
- package/dist/math/complex/core.d.mts +93 -0
- package/dist/math/complex/core.mjs +239 -0
- package/dist/math/complex/index.d.mts +3 -0
- package/dist/math/complex/preset.d.mts +31 -0
- package/dist/math/complex/preset.mjs +377 -0
- package/dist/math/complex/rules.d.mts +6 -0
- package/dist/math/complex/rules.mjs +121 -0
- package/dist/math/conic/index.d.mts +1 -0
- package/dist/math/conic/preset.d.mts +30 -0
- package/dist/math/conic/preset.mjs +334 -0
- package/dist/math/derivation.mjs +5 -5
- package/dist/math/derivative-explorer/preset.mjs +5 -5
- package/dist/math/domain-range/index.d.mts +1 -0
- package/dist/math/domain-range/preset.d.mts +33 -0
- package/dist/math/domain-range/preset.mjs +313 -0
- package/dist/math/fraction-bar/index.d.mts +1 -0
- package/dist/math/fraction-bar/preset.d.mts +27 -0
- package/dist/math/fraction-bar/preset.mjs +197 -0
- package/dist/math/function-machine/preset.mjs +2 -2
- package/dist/math/gradient-descent.mjs +6 -6
- package/dist/math/grapher/preset.d.mts +1 -1
- package/dist/math/grapher/preset.mjs +4 -4
- package/dist/math/harmonic-form/preset.mjs +6 -6
- package/dist/math/index.d.mts +27 -2
- package/dist/math/index.mjs +27 -2
- package/dist/math/integral-explorer/preset.mjs +2 -2
- package/dist/math/interactive/preset.mjs +3 -3
- package/dist/math/limit-explorer/preset.mjs +4 -4
- package/dist/math/linear-model/index.d.mts +1 -0
- package/dist/math/linear-model/preset.d.mts +53 -0
- package/dist/math/linear-model/preset.mjs +164 -0
- package/dist/math/linear-system/preset.mjs +4 -4
- package/dist/math/mystery-bucket/preset.mjs +6 -6
- package/dist/math/number-line/preset.mjs +3 -2
- package/dist/math/parabola/preset.mjs +4 -3
- package/dist/math/pattern/preset.mjs +7 -13
- package/dist/math/percent-bar/index.d.mts +1 -0
- package/dist/math/percent-bar/preset.d.mts +37 -0
- package/dist/math/percent-bar/preset.mjs +275 -0
- package/dist/math/poly/core.d.mts +50 -0
- package/dist/math/poly/core.mjs +268 -0
- package/dist/math/poly/index.d.mts +3 -0
- package/dist/math/poly/preset.d.mts +23 -0
- package/dist/math/poly/preset.mjs +141 -0
- package/dist/math/poly/steps.d.mts +10 -0
- package/dist/math/poly/steps.mjs +99 -0
- package/dist/math/rate-machine/index.d.mts +1 -0
- package/dist/math/rate-machine/preset.d.mts +35 -0
- package/dist/math/rate-machine/preset.mjs +281 -0
- package/dist/math/ratio-share/index.d.mts +1 -0
- package/dist/math/ratio-share/preset.d.mts +24 -0
- package/dist/math/ratio-share/preset.mjs +204 -0
- package/dist/math/receipt/index.d.mts +1 -0
- package/dist/math/receipt/preset.d.mts +22 -0
- package/dist/math/receipt/preset.mjs +137 -0
- package/dist/math/sequence-predict/index.d.mts +1 -0
- package/dist/math/sequence-predict/preset.d.mts +34 -0
- package/dist/math/sequence-predict/preset.mjs +130 -0
- package/dist/math/straight-line/index.d.mts +1 -0
- package/dist/math/straight-line/preset.d.mts +37 -0
- package/dist/math/straight-line/preset.mjs +374 -0
- package/dist/math/system-solve/index.d.mts +1 -0
- package/dist/math/system-solve/preset.d.mts +21 -0
- package/dist/math/system-solve/preset.mjs +227 -0
- package/dist/math/transform/index.d.mts +1 -0
- package/dist/math/transform/preset.d.mts +41 -0
- package/dist/math/transform/preset.mjs +343 -0
- package/dist/math/triangle-trig/preset.mjs +12 -9
- package/dist/math/trig/core.d.mts +37 -0
- package/dist/math/trig/core.mjs +150 -0
- package/dist/math/trig/diagrams.d.mts +1 -0
- package/dist/math/trig/diagrams.mjs +321 -0
- package/dist/math/trig/index.d.mts +3 -0
- package/dist/math/trig/preset.d.mts +25 -0
- package/dist/math/trig/preset.mjs +260 -0
- package/dist/math/trig/rules.d.mts +6 -0
- package/dist/math/trig/rules.mjs +159 -0
- package/dist/math/trig-explorer.mjs +4 -4
- package/dist/ml/boundary/preset.mjs +8 -3
- package/dist/ml/classifier/preset.mjs +31 -6
- package/dist/ml/kmeans/preset.mjs +4 -4
- package/dist/ml/knn/preset.mjs +47 -12
- package/dist/ml/regression/preset.mjs +36 -7
- package/dist/physics/atwood/preset.mjs +4 -4
- package/dist/physics/bullet-walls/preset.d.mts +1 -1
- package/dist/physics/bullet-walls/preset.mjs +7 -7
- package/dist/physics/carnot/preset.mjs +6 -6
- package/dist/physics/circular-motion/preset.mjs +36 -5
- package/dist/physics/collision-track/preset.mjs +35 -5
- package/dist/physics/efficiency/preset.d.mts +2 -2
- package/dist/physics/efficiency/preset.mjs +5 -5
- package/dist/physics/electric-field/preset.mjs +32 -23
- package/dist/physics/electric-flux/index.d.mts +1 -0
- package/dist/physics/electric-flux/preset.d.mts +29 -0
- package/dist/physics/electric-flux/preset.mjs +264 -0
- package/dist/physics/energy-skate/preset.mjs +5 -5
- package/dist/physics/entropy/preset.mjs +7 -7
- package/dist/physics/expansion/preset.mjs +13 -13
- package/dist/physics/exponential/asset.mjs +1 -1
- package/dist/physics/exponential/preset.mjs +4 -4
- package/dist/physics/gas-process/preset.mjs +3 -3
- package/dist/physics/gauss-law/index.d.mts +1 -0
- package/dist/physics/gauss-law/preset.d.mts +20 -0
- package/dist/physics/gauss-law/preset.mjs +286 -0
- package/dist/physics/gravitation/preset.mjs +7 -7
- package/dist/physics/gravity-drop.mjs +4 -4
- package/dist/physics/heat-transfer/preset.d.mts +1 -1
- package/dist/physics/heat-transfer/preset.mjs +10 -10
- package/dist/physics/impulse/preset.mjs +5 -5
- package/dist/physics/index.d.mts +4 -1
- package/dist/physics/index.mjs +4 -1
- package/dist/physics/kepler/preset.mjs +4 -4
- package/dist/physics/lever/preset.mjs +3 -3
- package/dist/physics/lorentz/preset.mjs +11 -11
- package/dist/physics/magnetism/preset.mjs +3 -3
- package/dist/physics/optics/preset.mjs +2 -2
- package/dist/physics/orbit-lab.mjs +5 -5
- package/dist/physics/projectile-lab.mjs +4 -4
- package/dist/physics/rain-relative/preset.mjs +5 -5
- package/dist/physics/ramp-forces/preset.mjs +5 -5
- package/dist/physics/river-boat.mjs +6 -6
- package/dist/physics/shm/preset.mjs +9 -9
- package/dist/physics/stopping-distance/preset.mjs +3 -3
- package/dist/physics/temperature-scales/preset.mjs +105 -116
- package/dist/physics/terminal-velocity/preset.mjs +5 -5
- package/dist/physics/thermal/preset.mjs +5 -5
- package/dist/physics/vector-board/preset.mjs +7 -6
- package/dist/physics/vector-scene.mjs +2 -2
- package/dist/physics/vector-types/preset.mjs +37 -3
- package/dist/physics/water-density/preset.mjs +12 -12
- package/dist/physics/waves/doppler.mjs +2 -2
- package/dist/physics/waves/preset.mjs +4 -4
- package/dist/physics/waves/ripple.mjs +6 -6
- package/dist/physics/waves/string.mjs +5 -5
- package/dist/physics/work-energy/preset.mjs +4 -4
- package/dist/physics/work-potential/index.d.mts +1 -0
- package/dist/physics/work-potential/preset.d.mts +20 -0
- package/dist/physics/work-potential/preset.mjs +276 -0
- package/dist/schemas/index.d.mts +6 -6
- package/dist/schemas/index.mjs +3 -3
- package/dist/statistics/center-spread/preset.mjs +3 -3
- package/dist/statistics/core/descriptive.d.mts +2 -2
- package/dist/statistics/core/descriptive.mjs +2 -2
- package/dist/statistics/core/normal.d.mts +3 -3
- package/dist/statistics/core/normal.mjs +3 -3
- package/dist/statistics/core/sequences.d.mts +1 -1
- package/dist/statistics/galton/preset.mjs +2 -2
- package/dist/statistics/histogram/preset.mjs +6 -6
- package/dist/statistics/normal/preset.mjs +2 -2
- package/dist/statistics/sampling/preset.mjs +4 -4
- package/dist/statistics/sequence/preset.mjs +58 -15
- package/dist/statistics/z-table/preset.mjs +17 -4
- package/package.json +11 -3
- package/styles.css +4 -1
|
@@ -0,0 +1,399 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { Chip, Slider } from "../../kit/controls.mjs";
|
|
4
|
+
import { Callout, ControlBar, Field, LabFrame } from "../../kit/frame.mjs";
|
|
5
|
+
import { ChallengeCard, useChallenge, useCheckpoint } from "../../kit/pedagogy.mjs";
|
|
6
|
+
import { Tag, Wire } from "../../kit/electronics.mjs";
|
|
7
|
+
import { LabAsk } from "../../kit/ask.mjs";
|
|
8
|
+
import { useState } from "react";
|
|
9
|
+
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
10
|
+
import { solveDC } from "@classytic/stage/circuit";
|
|
11
|
+
|
|
12
|
+
//#region src/circuits/brownout/preset.tsx
|
|
13
|
+
/**
|
|
14
|
+
* BrownoutLab — what a falling supply voltage does to digital logic. A CMOS gate only switches
|
|
15
|
+
* when its transistors can turn on, and that needs the supply rail VDD to stay above the
|
|
16
|
+
* threshold Vth. Drag the battery EMF down (a draining cell, a sagging rail) and the engine solves
|
|
17
|
+
* the gate's output: with a healthy supply it swings rail to rail (valid 1 / 0); as VDD falls
|
|
18
|
+
* toward Vth the swing collapses and the output can no longer follow the input, so it is no longer
|
|
19
|
+
* a valid 1 or 0. That is a brown-out: the chip is not broken, it is simply starved of voltage, and
|
|
20
|
+
* this is the bridge from EMF and
|
|
21
|
+
* the battery to whether a logic circuit works at all.
|
|
22
|
+
*/
|
|
23
|
+
const K = .5;
|
|
24
|
+
const C_HEALTHY = "var(--stage-good)";
|
|
25
|
+
const C_MARGINAL = "var(--stage-warn, oklch(0.78 0.15 80))";
|
|
26
|
+
const C_DEAD = "var(--stage-danger)";
|
|
27
|
+
const W = 460, H = 250;
|
|
28
|
+
function BrownoutLab({ vth = 2, vmax = 6, title = "Brown-out: when the supply is too low to think", prompt = "Drag the battery EMF down. The CMOS gate only switches while the supply rail VDD stays above the transistor threshold. As VDD falls toward Vth the output, solved by the engine, loses its swing and can no longer follow the input: a brown-out, where the logic is no longer a valid 1 or 0.", ask, activity = "brownout" } = {}) {
|
|
29
|
+
const [vdd, setVdd] = useState(5);
|
|
30
|
+
const [A, setA] = useState(1);
|
|
31
|
+
const ch = useChallenge(BROWNOUT_Q);
|
|
32
|
+
useCheckpoint({
|
|
33
|
+
solved: ch.allCorrect,
|
|
34
|
+
activity: "brownout:predict"
|
|
35
|
+
});
|
|
36
|
+
const inv = (vddV, aV) => [
|
|
37
|
+
{
|
|
38
|
+
kind: "V",
|
|
39
|
+
n1: 1,
|
|
40
|
+
n2: 0,
|
|
41
|
+
value: vddV
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
kind: "V",
|
|
45
|
+
n1: 3,
|
|
46
|
+
n2: 0,
|
|
47
|
+
value: aV
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
kind: "M",
|
|
51
|
+
pmos: true,
|
|
52
|
+
n1: 2,
|
|
53
|
+
n2: 1,
|
|
54
|
+
n3: 3,
|
|
55
|
+
value: 0,
|
|
56
|
+
vth,
|
|
57
|
+
k: K
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
kind: "M",
|
|
61
|
+
n1: 2,
|
|
62
|
+
n2: 0,
|
|
63
|
+
n3: 3,
|
|
64
|
+
value: 0,
|
|
65
|
+
vth,
|
|
66
|
+
k: K
|
|
67
|
+
}
|
|
68
|
+
];
|
|
69
|
+
const yAt = (aV) => solveDC(inv(vdd, aV)).nodeV[2] ?? 0;
|
|
70
|
+
const Yhigh = yAt(0);
|
|
71
|
+
const Ylow = yAt(vdd);
|
|
72
|
+
const Y = yAt(A ? vdd : 0);
|
|
73
|
+
const swing = Yhigh - Ylow;
|
|
74
|
+
const swingFrac = vdd > .05 ? swing / vdd : 0;
|
|
75
|
+
const SAFE = 1.5 * vth;
|
|
76
|
+
const collapsed = swingFrac <= .5;
|
|
77
|
+
const zone = collapsed ? "dead" : vdd < SAFE ? "marginal" : "healthy";
|
|
78
|
+
const zoneColor = zone === "healthy" ? C_HEALTHY : zone === "marginal" ? C_MARGINAL : C_DEAD;
|
|
79
|
+
const valid = !collapsed;
|
|
80
|
+
const level = collapsed ? "invalid" : Y > vdd / 2 ? "1" : "0";
|
|
81
|
+
const GX = 70, GTOP = 40, GBOT = 210, GW = 26;
|
|
82
|
+
const y = (v) => GBOT - Math.min(v, vmax) / vmax * (GBOT - GTOP);
|
|
83
|
+
const band = (lo, hi, color) => /* @__PURE__ */ jsx("rect", {
|
|
84
|
+
x: GX,
|
|
85
|
+
y: y(hi),
|
|
86
|
+
width: GW,
|
|
87
|
+
height: Math.max(0, y(lo) - y(hi)),
|
|
88
|
+
fill: color,
|
|
89
|
+
opacity: .32
|
|
90
|
+
});
|
|
91
|
+
const gx = 250, gy = 125;
|
|
92
|
+
const scene = /* @__PURE__ */ jsx("div", {
|
|
93
|
+
style: {
|
|
94
|
+
borderRadius: 12,
|
|
95
|
+
overflow: "hidden",
|
|
96
|
+
background: "var(--stage-bg)",
|
|
97
|
+
border: "1px solid var(--stage-grid)",
|
|
98
|
+
maxWidth: W,
|
|
99
|
+
margin: "0 auto"
|
|
100
|
+
},
|
|
101
|
+
children: /* @__PURE__ */ jsxs("svg", {
|
|
102
|
+
viewBox: `0 0 ${W} ${H}`,
|
|
103
|
+
width: "100%",
|
|
104
|
+
role: "img",
|
|
105
|
+
"aria-label": `Brown-out demo, supply ${vdd.toFixed(1)} volts, logic ${zone === "healthy" ? "valid" : zone === "marginal" ? "marginal" : "invalid"}`,
|
|
106
|
+
children: [
|
|
107
|
+
band(0, vth, C_DEAD),
|
|
108
|
+
band(vth, SAFE, C_MARGINAL),
|
|
109
|
+
band(SAFE, vmax, C_HEALTHY),
|
|
110
|
+
/* @__PURE__ */ jsx("rect", {
|
|
111
|
+
x: GX,
|
|
112
|
+
y: GTOP,
|
|
113
|
+
width: GW,
|
|
114
|
+
height: GBOT - GTOP,
|
|
115
|
+
fill: "none",
|
|
116
|
+
stroke: "var(--stage-grid)",
|
|
117
|
+
strokeWidth: 1,
|
|
118
|
+
rx: 4
|
|
119
|
+
}),
|
|
120
|
+
/* @__PURE__ */ jsx("line", {
|
|
121
|
+
x1: GX - 4,
|
|
122
|
+
y1: y(vth),
|
|
123
|
+
x2: 100,
|
|
124
|
+
y2: y(vth),
|
|
125
|
+
stroke: C_DEAD,
|
|
126
|
+
strokeWidth: 1,
|
|
127
|
+
strokeDasharray: "3 3"
|
|
128
|
+
}),
|
|
129
|
+
/* @__PURE__ */ jsx("line", {
|
|
130
|
+
x1: GX - 4,
|
|
131
|
+
y1: y(SAFE),
|
|
132
|
+
x2: 100,
|
|
133
|
+
y2: y(SAFE),
|
|
134
|
+
stroke: C_HEALTHY,
|
|
135
|
+
strokeWidth: 1,
|
|
136
|
+
strokeDasharray: "3 3"
|
|
137
|
+
}),
|
|
138
|
+
/* @__PURE__ */ jsx(Tag, {
|
|
139
|
+
x: 104,
|
|
140
|
+
y: y(vth) + 4,
|
|
141
|
+
text: `Vth ${vth}V`,
|
|
142
|
+
color: "var(--stage-muted)",
|
|
143
|
+
size: 10,
|
|
144
|
+
weight: 700,
|
|
145
|
+
anchor: "start"
|
|
146
|
+
}),
|
|
147
|
+
/* @__PURE__ */ jsx(Tag, {
|
|
148
|
+
x: 104,
|
|
149
|
+
y: y(SAFE) + 4,
|
|
150
|
+
text: "safe",
|
|
151
|
+
color: "var(--stage-muted)",
|
|
152
|
+
size: 10,
|
|
153
|
+
weight: 700,
|
|
154
|
+
anchor: "start"
|
|
155
|
+
}),
|
|
156
|
+
/* @__PURE__ */ jsx("rect", {
|
|
157
|
+
x: GX,
|
|
158
|
+
y: y(vdd),
|
|
159
|
+
width: GW,
|
|
160
|
+
height: GBOT - y(vdd),
|
|
161
|
+
fill: zoneColor,
|
|
162
|
+
opacity: .85
|
|
163
|
+
}),
|
|
164
|
+
/* @__PURE__ */ jsx("polygon", {
|
|
165
|
+
points: `${GX - 12},${y(vdd) - 6} ${GX - 12},${y(vdd) + 6} ${GX - 2},${y(vdd)}`,
|
|
166
|
+
fill: zoneColor
|
|
167
|
+
}),
|
|
168
|
+
/* @__PURE__ */ jsx(Tag, {
|
|
169
|
+
x: 83,
|
|
170
|
+
y: GTOP - 8,
|
|
171
|
+
text: "VDD",
|
|
172
|
+
color: "var(--stage-fg)",
|
|
173
|
+
size: 12,
|
|
174
|
+
weight: 800,
|
|
175
|
+
anchor: "middle"
|
|
176
|
+
}),
|
|
177
|
+
/* @__PURE__ */ jsx(Tag, {
|
|
178
|
+
x: 83,
|
|
179
|
+
y: 226,
|
|
180
|
+
text: `${vdd.toFixed(1)} V`,
|
|
181
|
+
color: zoneColor,
|
|
182
|
+
size: 13,
|
|
183
|
+
weight: 800,
|
|
184
|
+
anchor: "middle"
|
|
185
|
+
}),
|
|
186
|
+
/* @__PURE__ */ jsx(Wire, {
|
|
187
|
+
points: [
|
|
188
|
+
[96, y(vdd)],
|
|
189
|
+
[gx, y(vdd)],
|
|
190
|
+
[gx, gy - 34]
|
|
191
|
+
],
|
|
192
|
+
live: vdd > .05
|
|
193
|
+
}),
|
|
194
|
+
/* @__PURE__ */ jsx("polygon", {
|
|
195
|
+
points: `${gx},${gy - 26} ${gx},151 290,${gy}`,
|
|
196
|
+
fill: "color-mix(in oklab, var(--stage-metal, gray) 18%, var(--stage-bg))",
|
|
197
|
+
stroke: "var(--stage-fg)",
|
|
198
|
+
strokeWidth: 1.5
|
|
199
|
+
}),
|
|
200
|
+
/* @__PURE__ */ jsx("circle", {
|
|
201
|
+
cx: 296,
|
|
202
|
+
cy: gy,
|
|
203
|
+
r: 5,
|
|
204
|
+
fill: "var(--stage-bg)",
|
|
205
|
+
stroke: "var(--stage-fg)",
|
|
206
|
+
strokeWidth: 1.5
|
|
207
|
+
}),
|
|
208
|
+
/* @__PURE__ */ jsx(Tag, {
|
|
209
|
+
x: 270,
|
|
210
|
+
y: 129,
|
|
211
|
+
text: "NOT",
|
|
212
|
+
color: "var(--stage-fg)",
|
|
213
|
+
size: 10,
|
|
214
|
+
weight: 700,
|
|
215
|
+
anchor: "middle"
|
|
216
|
+
}),
|
|
217
|
+
/* @__PURE__ */ jsx(Wire, {
|
|
218
|
+
points: [[gx - 36, gy], [gx, gy]],
|
|
219
|
+
live: !!A
|
|
220
|
+
}),
|
|
221
|
+
/* @__PURE__ */ jsx("circle", {
|
|
222
|
+
cx: gx - 40,
|
|
223
|
+
cy: gy,
|
|
224
|
+
r: 4.5,
|
|
225
|
+
fill: A ? C_HEALTHY : "var(--stage-muted)"
|
|
226
|
+
}),
|
|
227
|
+
/* @__PURE__ */ jsx(Tag, {
|
|
228
|
+
x: gx - 40,
|
|
229
|
+
y: gy - 10,
|
|
230
|
+
text: `A=${A}`,
|
|
231
|
+
color: "var(--stage-fg)",
|
|
232
|
+
size: 11,
|
|
233
|
+
weight: 700,
|
|
234
|
+
anchor: "middle"
|
|
235
|
+
}),
|
|
236
|
+
/* @__PURE__ */ jsx(Wire, {
|
|
237
|
+
points: [[301, gy], [346, gy]],
|
|
238
|
+
live: valid && level === "1"
|
|
239
|
+
}),
|
|
240
|
+
/* @__PURE__ */ jsx("circle", {
|
|
241
|
+
cx: 350,
|
|
242
|
+
cy: gy,
|
|
243
|
+
r: 5,
|
|
244
|
+
fill: level === "invalid" ? C_DEAD : level === "1" ? C_HEALTHY : "var(--stage-muted)"
|
|
245
|
+
}),
|
|
246
|
+
/* @__PURE__ */ jsx(Tag, {
|
|
247
|
+
x: 358,
|
|
248
|
+
y: gy - 8,
|
|
249
|
+
text: "Y",
|
|
250
|
+
color: "var(--stage-fg)",
|
|
251
|
+
size: 12,
|
|
252
|
+
weight: 700,
|
|
253
|
+
anchor: "start"
|
|
254
|
+
}),
|
|
255
|
+
/* @__PURE__ */ jsx(Tag, {
|
|
256
|
+
x: 358,
|
|
257
|
+
y: 137,
|
|
258
|
+
text: level === "invalid" ? "?" : level,
|
|
259
|
+
color: level === "invalid" ? C_DEAD : level === "1" ? C_HEALTHY : "var(--stage-fg)",
|
|
260
|
+
size: 14,
|
|
261
|
+
weight: 800,
|
|
262
|
+
anchor: "start"
|
|
263
|
+
}),
|
|
264
|
+
/* @__PURE__ */ jsx(Tag, {
|
|
265
|
+
x: 270,
|
|
266
|
+
y: H - 14,
|
|
267
|
+
text: `output = ${Y.toFixed(2)} V`,
|
|
268
|
+
color: "var(--stage-muted)",
|
|
269
|
+
size: 11,
|
|
270
|
+
weight: 700,
|
|
271
|
+
anchor: "middle"
|
|
272
|
+
})
|
|
273
|
+
]
|
|
274
|
+
})
|
|
275
|
+
});
|
|
276
|
+
return /* @__PURE__ */ jsx(LabFrame, {
|
|
277
|
+
title,
|
|
278
|
+
prompt,
|
|
279
|
+
controls: /* @__PURE__ */ jsxs(ControlBar, { children: [/* @__PURE__ */ jsx(Field, {
|
|
280
|
+
label: `battery EMF = ${vdd.toFixed(1)} V`,
|
|
281
|
+
children: /* @__PURE__ */ jsx(Slider, {
|
|
282
|
+
min: 0,
|
|
283
|
+
max: vmax,
|
|
284
|
+
step: .1,
|
|
285
|
+
value: vdd,
|
|
286
|
+
onChange: setVdd,
|
|
287
|
+
ariaLabel: "battery EMF in volts"
|
|
288
|
+
})
|
|
289
|
+
}), /* @__PURE__ */ jsx(Field, {
|
|
290
|
+
label: "input A",
|
|
291
|
+
children: /* @__PURE__ */ jsxs("span", {
|
|
292
|
+
className: "lab-field-row",
|
|
293
|
+
children: [/* @__PURE__ */ jsx(Chip, {
|
|
294
|
+
selected: A === 0,
|
|
295
|
+
onClick: () => setA(0),
|
|
296
|
+
children: "0"
|
|
297
|
+
}), /* @__PURE__ */ jsx(Chip, {
|
|
298
|
+
selected: A === 1,
|
|
299
|
+
onClick: () => setA(1),
|
|
300
|
+
children: "1"
|
|
301
|
+
})]
|
|
302
|
+
})
|
|
303
|
+
})] }),
|
|
304
|
+
aside: /* @__PURE__ */ jsxs("div", {
|
|
305
|
+
style: {
|
|
306
|
+
display: "flex",
|
|
307
|
+
flexDirection: "column",
|
|
308
|
+
gap: 10
|
|
309
|
+
},
|
|
310
|
+
children: [
|
|
311
|
+
/* @__PURE__ */ jsx("div", {
|
|
312
|
+
className: "lab-pill",
|
|
313
|
+
"data-state": valid ? "ok" : "no",
|
|
314
|
+
role: "status",
|
|
315
|
+
style: { alignSelf: "flex-start" },
|
|
316
|
+
children: zone === "healthy" ? "✓ supply healthy: logic valid, good noise margin" : zone === "marginal" ? "⚠ low rail: logic still valid but the noise margin is thin" : "✗ supply below threshold: output invalid (no swing)"
|
|
317
|
+
}),
|
|
318
|
+
/* @__PURE__ */ jsx(Callout, {
|
|
319
|
+
tone: "result",
|
|
320
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
321
|
+
style: {
|
|
322
|
+
fontSize: 13,
|
|
323
|
+
lineHeight: 1.6
|
|
324
|
+
},
|
|
325
|
+
children: [
|
|
326
|
+
"supply VDD = ",
|
|
327
|
+
/* @__PURE__ */ jsxs("strong", { children: [vdd.toFixed(1), " V"] }),
|
|
328
|
+
" (threshold Vth = ",
|
|
329
|
+
vth,
|
|
330
|
+
" V)",
|
|
331
|
+
/* @__PURE__ */ jsx("br", {}),
|
|
332
|
+
"output swing = ",
|
|
333
|
+
/* @__PURE__ */ jsxs("strong", { children: [Math.max(0, swing).toFixed(2), " V"] }),
|
|
334
|
+
" (",
|
|
335
|
+
Math.round(Math.max(0, swingFrac) * 100),
|
|
336
|
+
"% of rail)",
|
|
337
|
+
/* @__PURE__ */ jsx("br", {}),
|
|
338
|
+
"this output = ",
|
|
339
|
+
Y.toFixed(2),
|
|
340
|
+
" V → ",
|
|
341
|
+
level === "invalid" ? /* @__PURE__ */ jsx("span", {
|
|
342
|
+
style: {
|
|
343
|
+
color: C_DEAD,
|
|
344
|
+
fontWeight: 700
|
|
345
|
+
},
|
|
346
|
+
children: "invalid (neither 1 nor 0)"
|
|
347
|
+
}) : /* @__PURE__ */ jsxs("span", {
|
|
348
|
+
style: { fontWeight: 700 },
|
|
349
|
+
children: ["logic ", level]
|
|
350
|
+
})
|
|
351
|
+
]
|
|
352
|
+
})
|
|
353
|
+
}),
|
|
354
|
+
/* @__PURE__ */ jsx(Callout, {
|
|
355
|
+
tone: "info",
|
|
356
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
357
|
+
style: {
|
|
358
|
+
fontSize: 12.5,
|
|
359
|
+
lineHeight: 1.5
|
|
360
|
+
},
|
|
361
|
+
children: "A transistor needs gate-to-source above Vth to conduct. Once the whole rail drops near Vth, neither the pull-up nor the pull-down can fully turn on, so the output can no longer be driven to a valid level and the swing collapses. Real systems brown out when a battery drains or a heavy load makes the supply sag (EMF minus the internal-resistance drop). The cure is a minimum supply voltage, not a faster chip."
|
|
362
|
+
})
|
|
363
|
+
})
|
|
364
|
+
]
|
|
365
|
+
}),
|
|
366
|
+
footer: /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(ChallengeCard, {
|
|
367
|
+
questions: BROWNOUT_Q,
|
|
368
|
+
state: ch,
|
|
369
|
+
title: "Predict first"
|
|
370
|
+
}), ask ? /* @__PURE__ */ jsx(LabAsk, {
|
|
371
|
+
ask,
|
|
372
|
+
activity
|
|
373
|
+
}) : null] }),
|
|
374
|
+
children: scene
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
const BROWNOUT_Q = [{
|
|
378
|
+
id: "brownout-low",
|
|
379
|
+
prompt: "The battery drains until the supply VDD falls below the transistor threshold Vth. What happens to the gate output?",
|
|
380
|
+
choices: [
|
|
381
|
+
{
|
|
382
|
+
value: "a",
|
|
383
|
+
label: "it becomes invalid: neither a clean 1 nor 0"
|
|
384
|
+
},
|
|
385
|
+
{
|
|
386
|
+
value: "b",
|
|
387
|
+
label: "it stays a perfect 1 and 0, just slower"
|
|
388
|
+
},
|
|
389
|
+
{
|
|
390
|
+
value: "c",
|
|
391
|
+
label: "the gate burns out"
|
|
392
|
+
}
|
|
393
|
+
],
|
|
394
|
+
answer: "a",
|
|
395
|
+
explain: "Below Vth neither transistor can fully turn on, so the output cannot reach the rails and the swing collapses (it stops following the input). Nothing is damaged: the chip is simply starved of voltage. That is a brown-out, and it is why every chip has a minimum supply voltage."
|
|
396
|
+
}];
|
|
397
|
+
|
|
398
|
+
//#endregion
|
|
399
|
+
export { BrownoutLab };
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
import { Chip, Slider } from "../../kit/controls.mjs";
|
|
4
4
|
import { ControlBar, Field, LabFrame, LiveRegion } from "../../kit/frame.mjs";
|
|
5
|
-
import { HintLadder, useHints } from "../../kit/pedagogy.mjs";
|
|
6
|
-
import { useFrameTick, useReducedMotion } from "../../kit/anim.mjs";
|
|
5
|
+
import { HintLadder, useCheckpoint, useHints } from "../../kit/pedagogy.mjs";
|
|
7
6
|
import { CapacitorGlyph, CellGlyph, ResistorGlyph } from "../../kit/electronics.mjs";
|
|
7
|
+
import { useFrameTick, useReducedMotion } from "../../kit/anim.mjs";
|
|
8
8
|
import { useRef, useState } from "react";
|
|
9
9
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
10
10
|
import { useInView } from "@classytic/stage";
|
|
@@ -12,19 +12,19 @@ import { RateCore } from "@classytic/stage/sim";
|
|
|
12
12
|
|
|
13
13
|
//#region src/circuits/capacitor-leak/preset.tsx
|
|
14
14
|
/**
|
|
15
|
-
* CapacitorLeakLab
|
|
15
|
+
* CapacitorLeakLab, why a capacitor charges, holds, and (slowly) LEAKS.
|
|
16
16
|
*
|
|
17
17
|
* A textbook RC loop: a cell charges a capacitor C through a resistor R. Flip
|
|
18
|
-
* the switch to "leak" and the cell is disconnected
|
|
18
|
+
* the switch to "leak" and the cell is disconnected, the capacitor discharges
|
|
19
19
|
* through its own leakage resistance, the field between the plates thins, drips
|
|
20
|
-
* fall off the lower plate, and Vc decays exponentially. One source of truth
|
|
21
|
-
* Vc(t), integrated by the shared `useFrameLoop` clock
|
|
20
|
+
* fall off the lower plate, and Vc decays exponentially. One source of truth ,
|
|
21
|
+
* Vc(t), integrated by the shared `useFrameLoop` clock, drives the plate field,
|
|
22
22
|
* the drips, the live readout, and the Vc–t trace, so they can never disagree.
|
|
23
23
|
*
|
|
24
24
|
* Time-dependent physics lives in the COMPONENT (the pure scene resolver runs
|
|
25
25
|
* once per resolve and can't integrate an ODE); the symbols are the tokenized
|
|
26
26
|
* @classytic/stage electronics glyphs, so the schematic stays exam-standard and
|
|
27
|
-
* rethemes with `--stage-*`. SVG only
|
|
27
|
+
* rethemes with `--stage-*`. SVG only, honours prefers-reduced-motion.
|
|
28
28
|
*/
|
|
29
29
|
const W = 440, H = 250;
|
|
30
30
|
const xL = 60, xR = 380, yT = 80, yB = 172;
|
|
@@ -36,7 +36,7 @@ const GRAPH = {
|
|
|
36
36
|
h: 44
|
|
37
37
|
};
|
|
38
38
|
const clamp01 = (v) => Math.max(0, Math.min(1, v));
|
|
39
|
-
function CapacitorLeakLab({ emf = 6, rK = 10, capU = 100, leakK = 200, startCharged = false, title = "Charging & leaking a capacitor", prompt = "Charge it up, then flip to “leak
|
|
39
|
+
function CapacitorLeakLab({ emf = 6, rK = 10, capU = 100, leakK = 200, startCharged = false, title = "Charging & leaking a capacitor", prompt = "Charge it up, then flip to “leak”, watch the field thin and Vc decay.", objectives, hints = [] }) {
|
|
40
40
|
const [V, setV] = useState(emf);
|
|
41
41
|
const [R, setR] = useState(rK);
|
|
42
42
|
const [C, setC] = useState(capU);
|
|
@@ -67,6 +67,11 @@ function CapacitorLeakLab({ emf = 6, rK = 10, capU = 100, leakK = 200, startChar
|
|
|
67
67
|
const charging = mode === "charge" && q < .995;
|
|
68
68
|
const leaking = mode === "leak" && q > .01;
|
|
69
69
|
const hint = useHints(hints);
|
|
70
|
+
useCheckpoint({
|
|
71
|
+
solved: mode === "leak" && q <= .05,
|
|
72
|
+
activity: `capacitor-leak:${title}`,
|
|
73
|
+
hintsUsed: hint.count
|
|
74
|
+
});
|
|
70
75
|
const sampleArr = rate.current.samples;
|
|
71
76
|
const trace = sampleArr.length > 1 ? sampleArr.map((s, i) => {
|
|
72
77
|
const x = GRAPH.x + i / (sampleArr.length - 1) * GRAPH.w;
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import { num } from "../../core/util.mjs";
|
|
4
4
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
5
5
|
import { StageAssetDefs, registerAsset, useCoords } from "@classytic/stage";
|
|
6
|
+
import { solveDC } from "@classytic/stage/circuit";
|
|
6
7
|
|
|
7
8
|
//#region src/circuits/circuit/asset.tsx
|
|
8
9
|
const TYPE = {
|
|
@@ -16,6 +17,72 @@ const XR = 3.2;
|
|
|
16
17
|
const ROW_GAP = 1.5;
|
|
17
18
|
const RETURN_DROP = 2.2;
|
|
18
19
|
const numOr = (v, d) => typeof v === "number" && Number.isFinite(v) ? v : typeof v === "boolean" ? v ? 1 : 0 : d;
|
|
20
|
+
/**
|
|
21
|
+
* Solve the branch-list network through the ONE circuit engine (@classytic/stage/circuit
|
|
22
|
+
* MNA): parallel branches between the left bus (node 1) and the ground return (node 0),
|
|
23
|
+
* each a series chain with its own internal nodes; closed switch = near-zero R, open
|
|
24
|
+
* branch = omitted. Returns the totals + per-branch current read back from node voltages.
|
|
25
|
+
*/
|
|
26
|
+
function solveNetwork(raw, nBranch, emf, internalR) {
|
|
27
|
+
const elems = [];
|
|
28
|
+
let node = 2;
|
|
29
|
+
if (internalR > 1e-9) {
|
|
30
|
+
const bn = node++;
|
|
31
|
+
elems.push({
|
|
32
|
+
kind: "V",
|
|
33
|
+
n1: bn,
|
|
34
|
+
n2: 0,
|
|
35
|
+
value: emf,
|
|
36
|
+
id: "batt"
|
|
37
|
+
});
|
|
38
|
+
elems.push({
|
|
39
|
+
kind: "R",
|
|
40
|
+
n1: bn,
|
|
41
|
+
n2: 1,
|
|
42
|
+
value: internalR
|
|
43
|
+
});
|
|
44
|
+
} else elems.push({
|
|
45
|
+
kind: "V",
|
|
46
|
+
n1: 1,
|
|
47
|
+
n2: 0,
|
|
48
|
+
value: emf,
|
|
49
|
+
id: "batt"
|
|
50
|
+
});
|
|
51
|
+
const branchOf = (b) => raw.filter((r) => r.branch === b).sort((a, c) => a.pos - c.pos);
|
|
52
|
+
const first = [];
|
|
53
|
+
for (let b = 0; b < nBranch; b++) {
|
|
54
|
+
const chain = branchOf(b);
|
|
55
|
+
if (chain.length === 0 || chain.some((r) => r.type === "switch" && !r.closed)) {
|
|
56
|
+
first[b] = null;
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
let prev = 1;
|
|
60
|
+
let f = null;
|
|
61
|
+
chain.forEach((r, idx) => {
|
|
62
|
+
const nb = idx === chain.length - 1 ? 0 : node++;
|
|
63
|
+
const R = r.type === "switch" ? 1e-6 : Math.max(1e-9, r.ohms);
|
|
64
|
+
elems.push({
|
|
65
|
+
kind: "R",
|
|
66
|
+
n1: prev,
|
|
67
|
+
n2: nb,
|
|
68
|
+
value: R
|
|
69
|
+
});
|
|
70
|
+
if (!f) f = {
|
|
71
|
+
a: prev,
|
|
72
|
+
b: nb,
|
|
73
|
+
R
|
|
74
|
+
};
|
|
75
|
+
prev = nb;
|
|
76
|
+
});
|
|
77
|
+
first[b] = f;
|
|
78
|
+
}
|
|
79
|
+
const sol = solveDC(elems);
|
|
80
|
+
const V = sol.nodeV;
|
|
81
|
+
return {
|
|
82
|
+
Itotal: Math.abs(sol.current["batt"] ?? 0),
|
|
83
|
+
branchI: first.map((f) => f ? Math.abs(((V[f.a] ?? 0) - (V[f.b] ?? 0)) / f.R) : 0)
|
|
84
|
+
};
|
|
85
|
+
}
|
|
19
86
|
function resolver({ params, bound }) {
|
|
20
87
|
const nComp = Math.max(0, Math.round(num(params.nComp, 0)));
|
|
21
88
|
const nBranch = Math.max(1, Math.round(num(params.nBranch, 1)));
|
|
@@ -40,16 +107,7 @@ function resolver({ params, bound }) {
|
|
|
40
107
|
});
|
|
41
108
|
}
|
|
42
109
|
const branchOf = (b) => raw.filter((r) => r.branch === b).sort((a, c) => a.pos - c.pos);
|
|
43
|
-
const
|
|
44
|
-
for (let b = 0; b < nBranch; b++) {
|
|
45
|
-
const comps = branchOf(b);
|
|
46
|
-
branchR[b] = comps.some((r) => r.type === "switch" && !r.closed) ? Infinity : comps.reduce((s, r) => s + (r.type === "switch" ? 0 : r.ohms), 0);
|
|
47
|
-
}
|
|
48
|
-
const invSum = branchR.reduce((s, R) => s + (Number.isFinite(R) && R > 0 ? 1 / R : Number.isFinite(R) ? 1e9 : 0), 0);
|
|
49
|
-
const Rpar = invSum > 0 ? 1 / invSum : Infinity;
|
|
50
|
-
const Rtot = Number.isFinite(Rpar) ? Rpar + internalR : Infinity;
|
|
51
|
-
const Itotal = Number.isFinite(Rtot) && Rtot > 1e-9 ? emf / Rtot : 0;
|
|
52
|
-
const Vbranch = emf - Itotal * internalR;
|
|
110
|
+
const { Itotal, branchI } = solveNetwork(raw, nBranch, emf, internalR);
|
|
53
111
|
const loopH = (nBranch - 1) * ROW_GAP + RETURN_DROP;
|
|
54
112
|
const yTop = loopH / 2;
|
|
55
113
|
const yReturn = -loopH / 2;
|
|
@@ -58,7 +116,7 @@ function resolver({ params, bound }) {
|
|
|
58
116
|
for (let b = 0; b < nBranch; b++) {
|
|
59
117
|
const yb = yTop - b * ROW_GAP;
|
|
60
118
|
const chain = branchOf(b);
|
|
61
|
-
const Ib =
|
|
119
|
+
const Ib = branchI[b] ?? 0;
|
|
62
120
|
const m = chain.length;
|
|
63
121
|
chain.forEach((r, idx) => {
|
|
64
122
|
const x = m === 1 ? 0 : -2.1 + (XR - PADX - -2.1) * (idx / (m - 1));
|
|
@@ -115,7 +173,6 @@ function resolver({ params, bound }) {
|
|
|
115
173
|
];
|
|
116
174
|
for (let b = 0; b < nBranch; b++) {
|
|
117
175
|
const yb = yTop - b * ROW_GAP;
|
|
118
|
-
const Ib = Number.isFinite(branchR[b]) && branchR[b] > 0 ? Vbranch / branchR[b] : 0;
|
|
119
176
|
wires.push({
|
|
120
177
|
pts: [{
|
|
121
178
|
x: XL,
|
|
@@ -124,7 +181,7 @@ function resolver({ params, bound }) {
|
|
|
124
181
|
x: XR,
|
|
125
182
|
y: yb
|
|
126
183
|
}],
|
|
127
|
-
energized:
|
|
184
|
+
energized: (branchI[b] ?? 0) > 1e-6
|
|
128
185
|
});
|
|
129
186
|
}
|
|
130
187
|
const bulbs = comps.filter((c) => c.type === "bulb");
|
|
@@ -148,7 +205,7 @@ function resolver({ params, bound }) {
|
|
|
148
205
|
wires,
|
|
149
206
|
emf,
|
|
150
207
|
Itotal,
|
|
151
|
-
Rtot:
|
|
208
|
+
Rtot: Itotal > 1e-12 ? emf / Itotal : -1,
|
|
152
209
|
solved,
|
|
153
210
|
flowDur,
|
|
154
211
|
energized: railEnergized
|
|
@@ -10,7 +10,7 @@ import { Scene, controlsFromScene, isAssetGeom, registerAsset, resolve, useContr
|
|
|
10
10
|
|
|
11
11
|
//#region src/circuits/circuit/preset.tsx
|
|
12
12
|
/**
|
|
13
|
-
* Circuit network
|
|
13
|
+
* Circuit network, a SceneDoc FACTORY on @classytic/stage. A creator declares a
|
|
14
14
|
* battery + parallel BRANCHES (each a series chain of resistor/bulb/switch); the
|
|
15
15
|
* learner closes switches and tunes the battery to hit a goal (light a bulb /
|
|
16
16
|
* reach a target current / light them all). EMF + each switch are FREE scalars
|
|
@@ -134,7 +134,12 @@ function CircuitNetworkLab(props) {
|
|
|
134
134
|
12,
|
|
135
135
|
1
|
|
136
136
|
], controlId, height = 360, prompt = "Close the switch and power the circuit." } = props;
|
|
137
|
-
const { editor, doc } = useEditor(useMemo(() => circuitDoc(props), [JSON.stringify(
|
|
137
|
+
const { editor, doc } = useEditor(useMemo(() => circuitDoc(props), [JSON.stringify({
|
|
138
|
+
emf: props.emf,
|
|
139
|
+
internalR: props.internalR,
|
|
140
|
+
branches: props.branches,
|
|
141
|
+
goal: props.goal
|
|
142
|
+
})]));
|
|
138
143
|
const resolved = resolve(doc);
|
|
139
144
|
const { switches } = useMemo(() => flatten(branches), [branches]);
|
|
140
145
|
const geom = resolved.values.get("circuit");
|
|
@@ -176,6 +181,8 @@ function CircuitNetworkLab(props) {
|
|
|
176
181
|
solved: meta.solved,
|
|
177
182
|
activity: "circuit-network"
|
|
178
183
|
});
|
|
184
|
+
const switchSummary = switches.length ? switches.map((s) => `${s.label} ${Number(resolved.values.get(s.id) ?? 0) >= .5 ? "closed" : "open"}`).join(", ") : "no switches";
|
|
185
|
+
const figureLabel = `Circuit diagram. ${meta.solved ? "Powered, goal reached" : "Not yet powered"}. Battery ${emf} volts. ${switchSummary}. ${prompt}`;
|
|
179
186
|
const figure = /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
180
187
|
/* @__PURE__ */ jsx(LabStyles, {}),
|
|
181
188
|
/* @__PURE__ */ jsx(Scene, {
|
|
@@ -184,15 +191,26 @@ function CircuitNetworkLab(props) {
|
|
|
184
191
|
showGrid: false,
|
|
185
192
|
showAxes: false,
|
|
186
193
|
height,
|
|
187
|
-
ariaLabel:
|
|
194
|
+
ariaLabel: figureLabel
|
|
188
195
|
}),
|
|
189
196
|
/* @__PURE__ */ jsx(LiveRegion, { children: meta.solved ? "Circuit powered, goal reached." : `Current ${(meta.Itotal * 1e3).toFixed(0)} milliamps.` })
|
|
190
197
|
] });
|
|
191
198
|
const controlsUi = /* @__PURE__ */ jsxs(ControlBar, { children: [switches.map((s) => {
|
|
192
199
|
const closed = Number(resolved.values.get(s.id) ?? 0) >= .5;
|
|
200
|
+
const flip = () => toggle(s.id);
|
|
193
201
|
return /* @__PURE__ */ jsxs(Chip, {
|
|
194
202
|
selected: closed,
|
|
195
|
-
onClick:
|
|
203
|
+
onClick: flip,
|
|
204
|
+
role: "button",
|
|
205
|
+
tabIndex: 0,
|
|
206
|
+
"aria-pressed": closed,
|
|
207
|
+
"aria-label": `toggle ${s.label} (currently ${closed ? "closed" : "open"})`,
|
|
208
|
+
onKeyDown: (e) => {
|
|
209
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
210
|
+
e.preventDefault();
|
|
211
|
+
flip();
|
|
212
|
+
}
|
|
213
|
+
},
|
|
196
214
|
children: [
|
|
197
215
|
s.label,
|
|
198
216
|
": ",
|
|
@@ -208,7 +226,7 @@ function CircuitNetworkLab(props) {
|
|
|
208
226
|
max: emfMax,
|
|
209
227
|
step: emfStep,
|
|
210
228
|
onChange: setEmf,
|
|
211
|
-
ariaLabel:
|
|
229
|
+
ariaLabel: `battery voltage, ${emf} volts`,
|
|
212
230
|
style: { width: 120 }
|
|
213
231
|
})
|
|
214
232
|
})] });
|