@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,275 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { round } from "../../core/util.mjs";
|
|
4
|
+
import { StatusPill } from "../../kit/controls.mjs";
|
|
5
|
+
import { ControlBar, LabFrame } from "../../kit/frame.mjs";
|
|
6
|
+
import { useCheckpoint } from "../../kit/pedagogy.mjs";
|
|
7
|
+
import { getScene } from "../../kit/scenes.mjs";
|
|
8
|
+
import { useEffect, useState } from "react";
|
|
9
|
+
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
10
|
+
import { Dot, Label, MovableDot, Segment, Stage } from "@classytic/stage";
|
|
11
|
+
|
|
12
|
+
//#region src/math/percent-bar/preset.tsx
|
|
13
|
+
/**
|
|
14
|
+
* PercentBarLab, the authorable PERCENTAGE manipulative: a bar is the whole
|
|
15
|
+
* (100%), the learner drags a fill to a target percent, and the same drag reads
|
|
16
|
+
* out both the percent AND the concrete amount (percent × whole). One engine,
|
|
17
|
+
* many analogies, the story is data: set `whole` + `unit` (students, mL, $, %
|
|
18
|
+
* battery) and an optional `segments` breakdown for the reference bar, and the
|
|
19
|
+
* SAME component teaches "make 25%", "25% of 80", a budget split, a charged
|
|
20
|
+
* battery, a poll. Built on the juiced <MovableDot> (snap + live readout +
|
|
21
|
+
* ghost stops) so a percentage feels tactile, not typed.
|
|
22
|
+
*
|
|
23
|
+
* Fully authorable: whole, unit, target, snap granularity, the reference-bar
|
|
24
|
+
* segments + their labels/colours, and the prompt, no code per analogy.
|
|
25
|
+
*/
|
|
26
|
+
const PALETTE = [
|
|
27
|
+
"var(--stage-accent)",
|
|
28
|
+
"var(--stage-good)",
|
|
29
|
+
"#f3a23b",
|
|
30
|
+
"#e85aa6",
|
|
31
|
+
"#7c83ff",
|
|
32
|
+
"#34c6c6"
|
|
33
|
+
];
|
|
34
|
+
const fmtVal = (n) => String(round(n));
|
|
35
|
+
function PercentBarLab(props = {}) {
|
|
36
|
+
const { whole = 100, unit = "", start = 0, target, snapPct = 5, showValue = true, segments, referenceLabel, scene, height = 230, title = "Percentages", prompt = target != null ? `Drag the bar to ${target}%.` : "Drag the bar and watch the percentage.", activity = "percent-bar" } = props;
|
|
37
|
+
const snap = (p) => Math.round(p / snapPct) * snapPct;
|
|
38
|
+
const clampPct = (p) => Math.max(0, Math.min(100, snap(p)));
|
|
39
|
+
const [pct, setPct] = useState(clampPct(start));
|
|
40
|
+
useEffect(() => {
|
|
41
|
+
setPct(clampPct(start));
|
|
42
|
+
}, [start, snapPct]);
|
|
43
|
+
const solved = target != null && pct === target;
|
|
44
|
+
const value = round(whole * pct / 100);
|
|
45
|
+
useCheckpoint({
|
|
46
|
+
solved,
|
|
47
|
+
activity,
|
|
48
|
+
response: `${pct}%${showValue ? ` = ${fmtVal(value)} ${unit}` : ""}`
|
|
49
|
+
});
|
|
50
|
+
const fillColor = solved ? "var(--stage-good)" : "var(--stage-accent)";
|
|
51
|
+
const Y_REF = 1.35;
|
|
52
|
+
const Y_BAR = -.25;
|
|
53
|
+
const BARW = 30;
|
|
54
|
+
const segTotal = (segments ?? []).reduce((s, x) => s + Math.max(0, x.frac), 0) || 1;
|
|
55
|
+
let acc = 0;
|
|
56
|
+
const segSpans = (segments ?? []).map((s, i) => {
|
|
57
|
+
const x0 = acc / segTotal * 100;
|
|
58
|
+
acc += Math.max(0, s.frac);
|
|
59
|
+
const x1 = acc / segTotal * 100;
|
|
60
|
+
return {
|
|
61
|
+
...s,
|
|
62
|
+
x0,
|
|
63
|
+
x1,
|
|
64
|
+
mid: (x0 + x1) / 2,
|
|
65
|
+
color: s.color ?? PALETTE[i % PALETTE.length]
|
|
66
|
+
};
|
|
67
|
+
});
|
|
68
|
+
const ticks = [];
|
|
69
|
+
for (let p = 0; p <= 100; p += snapPct) ticks.push(p);
|
|
70
|
+
const figure = /* @__PURE__ */ jsxs(Stage, {
|
|
71
|
+
view: {
|
|
72
|
+
xMin: -7,
|
|
73
|
+
xMax: 114,
|
|
74
|
+
yMin: -2.4,
|
|
75
|
+
yMax: segments?.length || referenceLabel ? 2.6 : 1.2
|
|
76
|
+
},
|
|
77
|
+
height,
|
|
78
|
+
preserveAspect: false,
|
|
79
|
+
pad: 14,
|
|
80
|
+
ariaLabel: `Percentage bar at ${pct} percent of ${whole}${unit ? " " + unit : ""}`,
|
|
81
|
+
children: [
|
|
82
|
+
(segSpans.length > 0 || referenceLabel) && /* @__PURE__ */ jsxs(Fragment$1, { children: [referenceLabel && /* @__PURE__ */ jsx(Label, {
|
|
83
|
+
x: 0,
|
|
84
|
+
y: Y_REF,
|
|
85
|
+
text: referenceLabel,
|
|
86
|
+
color: "var(--stage-muted)",
|
|
87
|
+
size: 12,
|
|
88
|
+
anchor: "start",
|
|
89
|
+
dy: -22
|
|
90
|
+
}), segSpans.length > 0 ? segSpans.map((s, i) => /* @__PURE__ */ jsxs("g", { children: [/* @__PURE__ */ jsx(Segment, {
|
|
91
|
+
from: {
|
|
92
|
+
x: s.x0,
|
|
93
|
+
y: Y_REF
|
|
94
|
+
},
|
|
95
|
+
to: {
|
|
96
|
+
x: s.x1,
|
|
97
|
+
y: Y_REF
|
|
98
|
+
},
|
|
99
|
+
color: s.color,
|
|
100
|
+
weight: BARW - 4,
|
|
101
|
+
opacity: .85
|
|
102
|
+
}), s.label && s.x1 - s.x0 > 9 && /* @__PURE__ */ jsx(Label, {
|
|
103
|
+
x: s.mid,
|
|
104
|
+
y: Y_REF,
|
|
105
|
+
text: s.label,
|
|
106
|
+
color: "var(--stage-fg)",
|
|
107
|
+
size: 11,
|
|
108
|
+
weight: 700
|
|
109
|
+
})] }, i)) : /* @__PURE__ */ jsx(Segment, {
|
|
110
|
+
from: {
|
|
111
|
+
x: 0,
|
|
112
|
+
y: Y_REF
|
|
113
|
+
},
|
|
114
|
+
to: {
|
|
115
|
+
x: 100,
|
|
116
|
+
y: Y_REF
|
|
117
|
+
},
|
|
118
|
+
color: "var(--stage-grid)",
|
|
119
|
+
weight: BARW - 4,
|
|
120
|
+
opacity: .7
|
|
121
|
+
})] }),
|
|
122
|
+
/* @__PURE__ */ jsx(Segment, {
|
|
123
|
+
from: {
|
|
124
|
+
x: 0,
|
|
125
|
+
y: Y_BAR
|
|
126
|
+
},
|
|
127
|
+
to: {
|
|
128
|
+
x: 100,
|
|
129
|
+
y: Y_BAR
|
|
130
|
+
},
|
|
131
|
+
color: "var(--stage-grid)",
|
|
132
|
+
weight: BARW,
|
|
133
|
+
opacity: .6
|
|
134
|
+
}),
|
|
135
|
+
/* @__PURE__ */ jsx(Segment, {
|
|
136
|
+
from: {
|
|
137
|
+
x: 0,
|
|
138
|
+
y: Y_BAR
|
|
139
|
+
},
|
|
140
|
+
to: {
|
|
141
|
+
x: Math.max(1e-4, pct),
|
|
142
|
+
y: Y_BAR
|
|
143
|
+
},
|
|
144
|
+
color: fillColor,
|
|
145
|
+
weight: BARW
|
|
146
|
+
}),
|
|
147
|
+
ticks.map((p) => /* @__PURE__ */ jsx(Segment, {
|
|
148
|
+
from: {
|
|
149
|
+
x: p,
|
|
150
|
+
y: Y_BAR - .62
|
|
151
|
+
},
|
|
152
|
+
to: {
|
|
153
|
+
x: p,
|
|
154
|
+
y: Y_BAR - (p % 25 === 0 ? .92 : .78)
|
|
155
|
+
},
|
|
156
|
+
color: "var(--stage-fg)",
|
|
157
|
+
opacity: p % 25 === 0 ? .5 : .2,
|
|
158
|
+
weight: p % 25 === 0 ? 1.5 : 1
|
|
159
|
+
}, p)),
|
|
160
|
+
/* @__PURE__ */ jsx(Label, {
|
|
161
|
+
x: 0,
|
|
162
|
+
y: Y_BAR,
|
|
163
|
+
text: "0%",
|
|
164
|
+
color: "var(--stage-muted)",
|
|
165
|
+
size: 12,
|
|
166
|
+
dy: 34
|
|
167
|
+
}),
|
|
168
|
+
/* @__PURE__ */ jsx(Label, {
|
|
169
|
+
x: 100,
|
|
170
|
+
y: Y_BAR,
|
|
171
|
+
text: "100%",
|
|
172
|
+
color: "var(--stage-muted)",
|
|
173
|
+
size: 12,
|
|
174
|
+
dy: 34
|
|
175
|
+
}),
|
|
176
|
+
/* @__PURE__ */ jsx(Label, {
|
|
177
|
+
x: 100,
|
|
178
|
+
y: Y_BAR,
|
|
179
|
+
text: `${fmtVal(whole)}${unit ? " " + unit : ""}`,
|
|
180
|
+
color: "var(--stage-muted)",
|
|
181
|
+
size: 12,
|
|
182
|
+
anchor: "start",
|
|
183
|
+
dx: 10
|
|
184
|
+
}),
|
|
185
|
+
target != null && /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(Segment, {
|
|
186
|
+
from: {
|
|
187
|
+
x: target,
|
|
188
|
+
y: Y_BAR - .95
|
|
189
|
+
},
|
|
190
|
+
to: {
|
|
191
|
+
x: target,
|
|
192
|
+
y: .7
|
|
193
|
+
},
|
|
194
|
+
color: "var(--stage-good)",
|
|
195
|
+
weight: 1.75,
|
|
196
|
+
opacity: solved ? .9 : .55,
|
|
197
|
+
dashed: true
|
|
198
|
+
}), !solved && /* @__PURE__ */ jsx(Dot, {
|
|
199
|
+
x: target,
|
|
200
|
+
y: Y_BAR,
|
|
201
|
+
r: 5,
|
|
202
|
+
color: "var(--stage-good)",
|
|
203
|
+
opacity: .4
|
|
204
|
+
})] }),
|
|
205
|
+
/* @__PURE__ */ jsx(MovableDot, {
|
|
206
|
+
value: {
|
|
207
|
+
x: pct,
|
|
208
|
+
y: Y_BAR
|
|
209
|
+
},
|
|
210
|
+
onMove: (p) => setPct(clampPct(p.x)),
|
|
211
|
+
constrain: "horizontal",
|
|
212
|
+
range: {
|
|
213
|
+
min: 0,
|
|
214
|
+
max: 100
|
|
215
|
+
},
|
|
216
|
+
snap: snapPct,
|
|
217
|
+
step: snapPct,
|
|
218
|
+
readout: () => `${pct}%`,
|
|
219
|
+
color: fillColor,
|
|
220
|
+
r: 9,
|
|
221
|
+
ariaLabel: "percentage fill handle"
|
|
222
|
+
})
|
|
223
|
+
]
|
|
224
|
+
});
|
|
225
|
+
const controls = /* @__PURE__ */ jsxs(ControlBar, { children: [
|
|
226
|
+
/* @__PURE__ */ jsxs("span", {
|
|
227
|
+
style: {
|
|
228
|
+
fontWeight: 700,
|
|
229
|
+
fontSize: 16,
|
|
230
|
+
fontVariantNumeric: "tabular-nums"
|
|
231
|
+
},
|
|
232
|
+
children: [pct, "%"]
|
|
233
|
+
}),
|
|
234
|
+
showValue && /* @__PURE__ */ jsxs("span", {
|
|
235
|
+
style: {
|
|
236
|
+
fontVariantNumeric: "tabular-nums",
|
|
237
|
+
opacity: .85
|
|
238
|
+
},
|
|
239
|
+
children: [
|
|
240
|
+
"= ",
|
|
241
|
+
fmtVal(value),
|
|
242
|
+
unit ? ` ${unit}` : "",
|
|
243
|
+
whole !== 100 ? ` of ${fmtVal(whole)}` : ""
|
|
244
|
+
]
|
|
245
|
+
}),
|
|
246
|
+
target != null && /* @__PURE__ */ jsx(StatusPill, {
|
|
247
|
+
ok: solved,
|
|
248
|
+
children: solved ? `✓ ${target}%` : `target ${target}%`
|
|
249
|
+
})
|
|
250
|
+
] });
|
|
251
|
+
const twin = scene && scene !== "none" ? getScene(scene)?.render({
|
|
252
|
+
frac: pct / 100,
|
|
253
|
+
guessTone: solved ? "ok" : "idle",
|
|
254
|
+
color: fillColor,
|
|
255
|
+
label: `${pct}%`,
|
|
256
|
+
width: 132,
|
|
257
|
+
height: 170
|
|
258
|
+
}) : null;
|
|
259
|
+
return /* @__PURE__ */ jsx(LabFrame, {
|
|
260
|
+
title,
|
|
261
|
+
prompt,
|
|
262
|
+
controls,
|
|
263
|
+
aside: twin ? /* @__PURE__ */ jsx("div", {
|
|
264
|
+
style: {
|
|
265
|
+
display: "grid",
|
|
266
|
+
placeItems: "center"
|
|
267
|
+
},
|
|
268
|
+
children: twin
|
|
269
|
+
}) : void 0,
|
|
270
|
+
children: figure
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
//#endregion
|
|
275
|
+
export { PercentBarLab };
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { Complex } from "../complex/core.mjs";
|
|
2
|
+
import { Node } from "@classytic/stage";
|
|
3
|
+
|
|
4
|
+
//#region src/math/poly/core.d.ts
|
|
5
|
+
declare namespace core_d_exports {
|
|
6
|
+
export { Poly, PolyRoots, add, allRoots, deflate, degree, deriv, evalC, evalPoly, factorTex, fromAst, mul, polyTex, solve, solveEquation, trim };
|
|
7
|
+
}
|
|
8
|
+
type Poly = number[];
|
|
9
|
+
declare const trim: (p: Poly) => Poly;
|
|
10
|
+
declare const degree: (p: Poly) => number;
|
|
11
|
+
/** Horner evaluation (real). */
|
|
12
|
+
declare function evalPoly(p: Poly, x: number): number;
|
|
13
|
+
/** Horner evaluation (complex). */
|
|
14
|
+
declare function evalC(p: Poly, z: Complex): Complex;
|
|
15
|
+
/** Derivative polynomial. */
|
|
16
|
+
declare const deriv: (p: Poly) => Poly;
|
|
17
|
+
declare function add(a: Poly, b: Poly): Poly;
|
|
18
|
+
declare function mul(a: Poly, b: Poly): Poly;
|
|
19
|
+
/** Synthetic division of p by (x − r); returns the quotient (assumes r is a root,
|
|
20
|
+
* i.e. drops the remainder). The "divide out a found factor" step. */
|
|
21
|
+
declare function deflate(p: Poly, r: number): Poly;
|
|
22
|
+
/** LaTeX of a polynomial in descending order, e.g. [−6,11,−6,1] → "x^{3} - 6x^{2} + 11x - 6". */
|
|
23
|
+
declare function polyTex(p0: Poly, x?: string): string;
|
|
24
|
+
/** Coefficients of `node` as a polynomial in `x` (other vars from `params`), or
|
|
25
|
+
* null if it isn't a polynomial in x (sin(x), 1/x, fractional power, …). */
|
|
26
|
+
declare function fromAst(node: Node, x?: string, params?: Record<string, number>): Poly | null;
|
|
27
|
+
/**
|
|
28
|
+
* All complex roots of `p` via Durand–Kerner simultaneous iteration (then snapped).
|
|
29
|
+
* For a degree-n polynomial returns n roots; real roots come back with im = 0.
|
|
30
|
+
*/
|
|
31
|
+
declare function allRoots(p0: Poly): Complex[];
|
|
32
|
+
interface PolyRoots {
|
|
33
|
+
poly: Poly;
|
|
34
|
+
degree: number;
|
|
35
|
+
roots: Complex[];
|
|
36
|
+
realRoots: number[];
|
|
37
|
+
}
|
|
38
|
+
/** Solve p = 0 for ALL roots (any degree up to MAX_DEG). null if degenerate. */
|
|
39
|
+
declare function solve(p0: Poly): PolyRoots | null;
|
|
40
|
+
/** Solve an expression-AST equation `expr = 0` for x, any degree. null if not a
|
|
41
|
+
* polynomial in x. (Linear/quadratic also flow through here, exactly.) */
|
|
42
|
+
declare function solveEquation(node: Node, x?: string, params?: Record<string, number>): PolyRoots | null;
|
|
43
|
+
/**
|
|
44
|
+
* Factored form of the polynomial over the reals: leading coefficient × linear
|
|
45
|
+
* factors (real roots, with multiplicity) × irreducible quadratics (complex
|
|
46
|
+
* conjugate pairs). e.g. x³−6x²+11x−6 → "(x − 1)(x − 2)(x − 3)".
|
|
47
|
+
*/
|
|
48
|
+
declare function factorTex(p0: Poly, x?: string): string;
|
|
49
|
+
//#endregion
|
|
50
|
+
export { Poly, PolyRoots, add, allRoots, core_d_exports, deflate, degree, deriv, evalC, evalPoly, factorTex, fromAst, mul, polyTex, solve, solveEquation, trim };
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
import { __exportAll } from "../../_virtual/_rolldown/runtime.mjs";
|
|
2
|
+
import { ONE, ZERO, abs, add as add$1, cx, div, fromPolar, isFiniteC, mul as mul$1, sub } from "../complex/core.mjs";
|
|
3
|
+
import { evaluate } from "@classytic/stage";
|
|
4
|
+
|
|
5
|
+
//#region src/math/poly/core.ts
|
|
6
|
+
/**
|
|
7
|
+
* Polynomial core, the canonical single-variable polynomial engine. The clean,
|
|
8
|
+
* focused alternative to bolting on a heavy general CAS (Algebrite / nerdamer):
|
|
9
|
+
* for the polynomial algebra school actually needs — expand, evaluate,
|
|
10
|
+
* differentiate, FACTOR, and SOLVE any degree — a normalised coefficient form
|
|
11
|
+
* makes everything fall out.
|
|
12
|
+
*
|
|
13
|
+
* • a Poly is just `number[]` ascending: [a0, a1, …, an] = a0 + a1 x + … + an xⁿ.
|
|
14
|
+
* • roots of ANY degree via DURAND–KERNER (Weierstrass) simultaneous iteration,
|
|
15
|
+
* reusing the complex kernel — all n complex roots at once, then snapped to
|
|
16
|
+
* exact rationals where they're clearly nice (so 2, ½, −3 print exact, not
|
|
17
|
+
* 1.9999999).
|
|
18
|
+
* • factored form is read straight off the cleaned roots (real → (x−r);
|
|
19
|
+
* complex pair → an irreducible real quadratic).
|
|
20
|
+
*
|
|
21
|
+
* Numerically safe: Durand–Kerner is capped at MAX_ITER and falls back gracefully;
|
|
22
|
+
* coefficient arrays are trimmed; no overflow paths (the complex kernel guards div).
|
|
23
|
+
*/
|
|
24
|
+
var core_exports = /* @__PURE__ */ __exportAll({
|
|
25
|
+
add: () => add,
|
|
26
|
+
allRoots: () => allRoots,
|
|
27
|
+
deflate: () => deflate,
|
|
28
|
+
degree: () => degree,
|
|
29
|
+
deriv: () => deriv,
|
|
30
|
+
evalC: () => evalC,
|
|
31
|
+
evalPoly: () => evalPoly,
|
|
32
|
+
factorTex: () => factorTex,
|
|
33
|
+
fromAst: () => fromAst,
|
|
34
|
+
mul: () => mul,
|
|
35
|
+
polyTex: () => polyTex,
|
|
36
|
+
solve: () => solve,
|
|
37
|
+
solveEquation: () => solveEquation,
|
|
38
|
+
trim: () => trim
|
|
39
|
+
});
|
|
40
|
+
const EPS = 1e-9;
|
|
41
|
+
const MAX_ITER = 300;
|
|
42
|
+
const MAX_DEG = 8;
|
|
43
|
+
const trim = (p) => {
|
|
44
|
+
let n = p.length;
|
|
45
|
+
while (n > 1 && Math.abs(p[n - 1]) < 1e-12) n--;
|
|
46
|
+
return p.slice(0, n);
|
|
47
|
+
};
|
|
48
|
+
const degree = (p) => trim(p).length - 1;
|
|
49
|
+
/** Horner evaluation (real). */
|
|
50
|
+
function evalPoly(p, x) {
|
|
51
|
+
let s = 0;
|
|
52
|
+
for (let i = p.length - 1; i >= 0; i--) s = s * x + (p[i] ?? 0);
|
|
53
|
+
return s;
|
|
54
|
+
}
|
|
55
|
+
/** Horner evaluation (complex). */
|
|
56
|
+
function evalC(p, z) {
|
|
57
|
+
let s = ZERO;
|
|
58
|
+
for (let i = p.length - 1; i >= 0; i--) s = add$1(mul$1(s, z), cx(p[i] ?? 0));
|
|
59
|
+
return s;
|
|
60
|
+
}
|
|
61
|
+
/** Derivative polynomial. */
|
|
62
|
+
const deriv = (p) => trim(p.slice(1).map((c, i) => c * (i + 1)));
|
|
63
|
+
function add(a, b) {
|
|
64
|
+
const n = Math.max(a.length, b.length), o = [];
|
|
65
|
+
for (let i = 0; i < n; i++) o.push((a[i] ?? 0) + (b[i] ?? 0));
|
|
66
|
+
return trim(o);
|
|
67
|
+
}
|
|
68
|
+
function mul(a, b) {
|
|
69
|
+
const o = new Array(a.length + b.length - 1).fill(0);
|
|
70
|
+
for (let i = 0; i < a.length; i++) for (let j = 0; j < b.length; j++) o[i + j] += a[i] * b[j];
|
|
71
|
+
return trim(o);
|
|
72
|
+
}
|
|
73
|
+
/** Synthetic division of p by (x − r); returns the quotient (assumes r is a root,
|
|
74
|
+
* i.e. drops the remainder). The "divide out a found factor" step. */
|
|
75
|
+
function deflate(p, r) {
|
|
76
|
+
const n = p.length - 1;
|
|
77
|
+
if (n < 1) return [0];
|
|
78
|
+
const q = new Array(n).fill(0);
|
|
79
|
+
q[n - 1] = p[n];
|
|
80
|
+
for (let k = n - 2; k >= 0; k--) q[k] = p[k + 1] + r * q[k + 1];
|
|
81
|
+
return trim(q);
|
|
82
|
+
}
|
|
83
|
+
const tnum = (n) => {
|
|
84
|
+
const r = Math.round(n * 1e6) / 1e6;
|
|
85
|
+
return (Object.is(r, -0) ? 0 : r).toString();
|
|
86
|
+
};
|
|
87
|
+
/** LaTeX of a polynomial in descending order, e.g. [−6,11,−6,1] → "x^{3} - 6x^{2} + 11x - 6". */
|
|
88
|
+
function polyTex(p0, x = "x") {
|
|
89
|
+
const p = trim(p0);
|
|
90
|
+
let out = "";
|
|
91
|
+
for (let d = p.length - 1; d >= 0; d--) {
|
|
92
|
+
const c = p[d];
|
|
93
|
+
if (c === 0) continue;
|
|
94
|
+
const mag = Math.abs(c);
|
|
95
|
+
const t = `${d === 0 ? tnum(mag) : mag === 1 ? "" : tnum(mag)}${d === 0 ? "" : d === 1 ? x : `${x}^{${d}}`}`;
|
|
96
|
+
out += out === "" ? c < 0 ? `-${t}` : t : c < 0 ? ` - ${t}` : ` + ${t}`;
|
|
97
|
+
}
|
|
98
|
+
return out || "0";
|
|
99
|
+
}
|
|
100
|
+
function hasVar(node, x) {
|
|
101
|
+
switch (node.type) {
|
|
102
|
+
case "var": return node.name === x;
|
|
103
|
+
case "neg": return hasVar(node.arg, x);
|
|
104
|
+
case "binary": return hasVar(node.left, x) || hasVar(node.right, x);
|
|
105
|
+
case "call": return node.args.some((a) => hasVar(a, x));
|
|
106
|
+
default: return false;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
/** Coefficients of `node` as a polynomial in `x` (other vars from `params`), or
|
|
110
|
+
* null if it isn't a polynomial in x (sin(x), 1/x, fractional power, …). */
|
|
111
|
+
function fromAst(node, x = "x", params = {}) {
|
|
112
|
+
if (!hasVar(node, x)) {
|
|
113
|
+
const v = evaluate(node, params);
|
|
114
|
+
return Number.isFinite(v) ? [v] : null;
|
|
115
|
+
}
|
|
116
|
+
switch (node.type) {
|
|
117
|
+
case "var": return [0, 1];
|
|
118
|
+
case "neg": {
|
|
119
|
+
const c = fromAst(node.arg, x, params);
|
|
120
|
+
return c && c.map((k) => -k);
|
|
121
|
+
}
|
|
122
|
+
case "binary": {
|
|
123
|
+
const { op, left, right } = node;
|
|
124
|
+
const L = fromAst(left, x, params);
|
|
125
|
+
if (!L) return null;
|
|
126
|
+
if (op === "+") {
|
|
127
|
+
const R = fromAst(right, x, params);
|
|
128
|
+
return R && add(L, R);
|
|
129
|
+
}
|
|
130
|
+
if (op === "-") {
|
|
131
|
+
const R = fromAst(right, x, params);
|
|
132
|
+
return R && add(L, R.map((k) => -k));
|
|
133
|
+
}
|
|
134
|
+
if (op === "*") {
|
|
135
|
+
const R = fromAst(right, x, params);
|
|
136
|
+
return R && mul(L, R);
|
|
137
|
+
}
|
|
138
|
+
if (op === "/") {
|
|
139
|
+
if (hasVar(right, x)) return null;
|
|
140
|
+
const d = evaluate(right, params);
|
|
141
|
+
return Number.isFinite(d) && d !== 0 ? L.map((k) => k / d) : null;
|
|
142
|
+
}
|
|
143
|
+
if (op === "^") {
|
|
144
|
+
if (hasVar(right, x)) return null;
|
|
145
|
+
const n = evaluate(right, params);
|
|
146
|
+
if (!Number.isInteger(n) || n < 0 || n > MAX_DEG) return null;
|
|
147
|
+
let acc = [1];
|
|
148
|
+
for (let i = 0; i < n; i++) acc = mul(acc, L);
|
|
149
|
+
return acc;
|
|
150
|
+
}
|
|
151
|
+
return null;
|
|
152
|
+
}
|
|
153
|
+
default: return null;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
/** Snap a near-rational real to its exact value (denominators 1..12), else itself. */
|
|
157
|
+
function snapReal(r) {
|
|
158
|
+
for (const d of [
|
|
159
|
+
1,
|
|
160
|
+
2,
|
|
161
|
+
3,
|
|
162
|
+
4,
|
|
163
|
+
5,
|
|
164
|
+
6,
|
|
165
|
+
8,
|
|
166
|
+
10,
|
|
167
|
+
12
|
|
168
|
+
]) {
|
|
169
|
+
const n = Math.round(r * d);
|
|
170
|
+
if (Math.abs(r * d - n) < 1e-7) {
|
|
171
|
+
const v = n / d;
|
|
172
|
+
return Object.is(v, -0) ? 0 : v;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
return Math.round(r * 1e9) / 1e9;
|
|
176
|
+
}
|
|
177
|
+
const snap = (z) => Math.abs(z.im) < 1e-7 ? {
|
|
178
|
+
re: snapReal(z.re),
|
|
179
|
+
im: 0
|
|
180
|
+
} : {
|
|
181
|
+
re: snapReal(z.re),
|
|
182
|
+
im: snapReal(z.im)
|
|
183
|
+
};
|
|
184
|
+
/**
|
|
185
|
+
* All complex roots of `p` via Durand–Kerner simultaneous iteration (then snapped).
|
|
186
|
+
* For a degree-n polynomial returns n roots; real roots come back with im = 0.
|
|
187
|
+
*/
|
|
188
|
+
function allRoots(p0) {
|
|
189
|
+
const p = trim(p0);
|
|
190
|
+
const n = p.length - 1;
|
|
191
|
+
if (n <= 0) return [];
|
|
192
|
+
const lead = p[n];
|
|
193
|
+
const m = p.map((c) => c / lead);
|
|
194
|
+
let z = Array.from({ length: n }, (_, k) => fromPolar(1 + .1 * k / n, 2 * Math.PI * k / n + .6));
|
|
195
|
+
for (let it = 0; it < MAX_ITER; it++) {
|
|
196
|
+
let maxDelta = 0;
|
|
197
|
+
z = z.map((zi, i) => {
|
|
198
|
+
let denom = ONE;
|
|
199
|
+
for (let j = 0; j < n; j++) if (j !== i) denom = mul$1(denom, sub(zi, z[j]));
|
|
200
|
+
const corr = div(evalC(m, zi), denom);
|
|
201
|
+
if (!isFiniteC(corr)) return zi;
|
|
202
|
+
maxDelta = Math.max(maxDelta, abs(corr));
|
|
203
|
+
return sub(zi, corr);
|
|
204
|
+
});
|
|
205
|
+
if (maxDelta < EPS) break;
|
|
206
|
+
}
|
|
207
|
+
const roots = z.map(snap);
|
|
208
|
+
roots.sort((a, b) => a.im === 0 && b.im === 0 ? a.re - b.re : a.im === 0 ? -1 : b.im === 0 ? 1 : a.re - b.re || a.im - b.im);
|
|
209
|
+
return roots;
|
|
210
|
+
}
|
|
211
|
+
/** Solve p = 0 for ALL roots (any degree up to MAX_DEG). null if degenerate. */
|
|
212
|
+
function solve(p0) {
|
|
213
|
+
const p = trim(p0);
|
|
214
|
+
const d = p.length - 1;
|
|
215
|
+
if (d < 1) return null;
|
|
216
|
+
const roots = allRoots(p);
|
|
217
|
+
return {
|
|
218
|
+
poly: p,
|
|
219
|
+
degree: d,
|
|
220
|
+
roots,
|
|
221
|
+
realRoots: roots.filter((r) => r.im === 0).map((r) => r.re)
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
/** Solve an expression-AST equation `expr = 0` for x, any degree. null if not a
|
|
225
|
+
* polynomial in x. (Linear/quadratic also flow through here, exactly.) */
|
|
226
|
+
function solveEquation(node, x = "x", params = {}) {
|
|
227
|
+
const p = fromAst(node, x, params);
|
|
228
|
+
return p ? solve(p) : null;
|
|
229
|
+
}
|
|
230
|
+
const fnum = (n) => {
|
|
231
|
+
const r = Math.round(n * 1e6) / 1e6;
|
|
232
|
+
return (Object.is(r, -0) ? 0 : r).toString().replace(/^-/, "−");
|
|
233
|
+
};
|
|
234
|
+
/** "(x − r)" with the sign tucked in, and "(x − 0)" → "x". */
|
|
235
|
+
const linTex = (r, x) => r === 0 ? x : `(${x} ${r < 0 ? "+" : "−"} ${fnum(Math.abs(r))})`;
|
|
236
|
+
/**
|
|
237
|
+
* Factored form of the polynomial over the reals: leading coefficient × linear
|
|
238
|
+
* factors (real roots, with multiplicity) × irreducible quadratics (complex
|
|
239
|
+
* conjugate pairs). e.g. x³−6x²+11x−6 → "(x − 1)(x − 2)(x − 3)".
|
|
240
|
+
*/
|
|
241
|
+
function factorTex(p0, x = "x") {
|
|
242
|
+
const p = trim(p0);
|
|
243
|
+
const lead = p[p.length - 1] ?? 1;
|
|
244
|
+
const sol = solve(p);
|
|
245
|
+
if (!sol) return fnum(p[0] ?? 0);
|
|
246
|
+
const used = new Array(sol.roots.length).fill(false);
|
|
247
|
+
const parts = [];
|
|
248
|
+
for (let i = 0; i < sol.roots.length; i++) {
|
|
249
|
+
if (used[i]) continue;
|
|
250
|
+
const z = sol.roots[i];
|
|
251
|
+
if (z.im === 0) {
|
|
252
|
+
used[i] = true;
|
|
253
|
+
parts.push(linTex(z.re, x));
|
|
254
|
+
continue;
|
|
255
|
+
}
|
|
256
|
+
used[i] = true;
|
|
257
|
+
const j = sol.roots.findIndex((w, k) => !used[k] && Math.abs(w.re - z.re) < 1e-6 && Math.abs(w.im + z.im) < 1e-6);
|
|
258
|
+
if (j >= 0) used[j] = true;
|
|
259
|
+
const b2 = z.re * z.re + z.im * z.im, two = 2 * z.re;
|
|
260
|
+
const mid = Math.abs(two) < 1e-9 ? "" : ` ${two < 0 ? "+" : "−"} ${fnum(Math.abs(two))}${x}`;
|
|
261
|
+
parts.push(`(${x}^2${mid} ${b2 < 0 ? "−" : "+"} ${fnum(Math.abs(b2))})`);
|
|
262
|
+
}
|
|
263
|
+
const lc = Math.abs(lead - 1) < 1e-9 ? "" : `${fnum(lead)}\\,`;
|
|
264
|
+
return parts.length ? `${lc}${parts.join("")}` : fnum(lead);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
//#endregion
|
|
268
|
+
export { core_exports, deflate, degree, evalPoly, factorTex, fromAst, polyTex, solve, solveEquation, trim };
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { Poly, PolyRoots, add, allRoots, core_d_exports, deflate, degree, deriv, evalC, evalPoly, factorTex, fromAst, mul, polyTex, solve, solveEquation, trim } from "./core.mjs";
|
|
2
|
+
import { factorSteps, solveSteps } from "./steps.mjs";
|
|
3
|
+
import { PolynomialSolverLab, PolynomialSolverProps, SolverMode } from "./preset.mjs";
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { ReactNode } from "react";
|
|
2
|
+
|
|
3
|
+
//#region src/math/poly/preset.d.ts
|
|
4
|
+
type SolverMode = 'factor' | 'solve';
|
|
5
|
+
interface PolynomialSolverProps {
|
|
6
|
+
/** The polynomial in x, e.g. "x^2 + 5x + 6" or "x^3 - 6x^2 + 11x - 6". */
|
|
7
|
+
expr?: string;
|
|
8
|
+
mode?: SolverMode;
|
|
9
|
+
/** Let the learner edit the polynomial (the live solver). Default true. */
|
|
10
|
+
editable?: boolean;
|
|
11
|
+
height?: number;
|
|
12
|
+
title?: string;
|
|
13
|
+
prompt?: string;
|
|
14
|
+
}
|
|
15
|
+
declare function PolynomialSolverLab({
|
|
16
|
+
expr,
|
|
17
|
+
mode,
|
|
18
|
+
editable,
|
|
19
|
+
title,
|
|
20
|
+
prompt
|
|
21
|
+
}?: PolynomialSolverProps): ReactNode;
|
|
22
|
+
//#endregion
|
|
23
|
+
export { PolynomialSolverLab, PolynomialSolverProps, SolverMode };
|