@classytic/stage 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +7 -3
  3. package/dist/assets/index.mjs +0 -1
  4. package/dist/assets/kit/glyphs.d.mts +5 -5
  5. package/dist/assets/kit/glyphs.mjs +4 -4
  6. package/dist/builder/Palette.mjs +50 -89
  7. package/dist/builder/SceneBuilder.mjs +18 -76
  8. package/dist/builder/editor.d.mts +2 -1
  9. package/dist/builder/editor.mjs +14 -4
  10. package/dist/builder/tools.d.mts +1 -1
  11. package/dist/builder/tools.mjs +1 -1
  12. package/dist/chem/index.d.mts +5 -5
  13. package/dist/chem/index.mjs +4 -4
  14. package/dist/circuit/index.d.mts +92 -0
  15. package/dist/circuit/index.mjs +333 -0
  16. package/dist/core/clock.d.mts +1 -1
  17. package/dist/core/clock.mjs +3 -3
  18. package/dist/core/control.d.mts +1 -1
  19. package/dist/core/control.mjs +2 -2
  20. package/dist/core/coords.d.mts +4 -4
  21. package/dist/core/coords.mjs +1 -1
  22. package/dist/core/index.d.mts +2 -1
  23. package/dist/core/index.mjs +2 -1
  24. package/dist/core/learner.d.mts +1 -1
  25. package/dist/core/learner.mjs +1 -1
  26. package/dist/core/math.d.mts +26 -0
  27. package/dist/core/math.mjs +37 -0
  28. package/dist/core/motion.d.mts +6 -6
  29. package/dist/core/motion.mjs +6 -6
  30. package/dist/core/richText.d.mts +2 -2
  31. package/dist/core/vec.d.mts +1 -1
  32. package/dist/field/index.d.mts +11 -3
  33. package/dist/field/index.mjs +20 -3
  34. package/dist/finance/bizsim.d.mts +93 -0
  35. package/dist/finance/bizsim.mjs +117 -0
  36. package/dist/finance/index.d.mts +118 -0
  37. package/dist/finance/index.mjs +203 -0
  38. package/dist/index.d.mts +6 -3
  39. package/dist/index.mjs +6 -4
  40. package/dist/interaction/MovableDot.d.mts +17 -1
  41. package/dist/interaction/MovableDot.mjs +160 -43
  42. package/dist/interaction/index.d.mts +2 -1
  43. package/dist/interaction/index.mjs +2 -1
  44. package/dist/interaction/useDraggable.d.mts +1 -1
  45. package/dist/interaction/useDraggable.mjs +55 -5
  46. package/dist/interaction/usePressSpring.d.mts +24 -0
  47. package/dist/interaction/usePressSpring.mjs +67 -0
  48. package/dist/logic/ast.d.mts +1 -1
  49. package/dist/logic/index.mjs +8 -3
  50. package/dist/logic/minimize.d.mts +2 -2
  51. package/dist/logic/minimize.mjs +56 -18
  52. package/dist/logic/table.mjs +1 -1
  53. package/dist/math/ast.d.mts +1 -1
  54. package/dist/math/ast.mjs +1 -1
  55. package/dist/math/calculus.d.mts +22 -1
  56. package/dist/math/calculus.mjs +224 -11
  57. package/dist/math/compile.d.mts +8 -0
  58. package/dist/math/compile.mjs +40 -0
  59. package/dist/math/defs.mjs +1 -1
  60. package/dist/math/index.d.mts +5 -4
  61. package/dist/math/index.mjs +5 -4
  62. package/dist/math/latex.mjs +8 -0
  63. package/dist/math/parse.mjs +2 -2
  64. package/dist/math/tokenize.mjs +1 -1
  65. package/dist/primitives/CanvasLayer.mjs +3 -3
  66. package/dist/primitives/Dot.d.mts +2 -15
  67. package/dist/primitives/Dot.mjs +6 -4
  68. package/dist/primitives/Grid.d.mts +41 -14
  69. package/dist/primitives/Grid.mjs +100 -22
  70. package/dist/primitives/Label.d.mts +2 -15
  71. package/dist/primitives/Label.mjs +4 -3
  72. package/dist/primitives/Lines.d.mts +4 -32
  73. package/dist/primitives/Lines.mjs +10 -8
  74. package/dist/primitives/Shapes.d.mts +5 -43
  75. package/dist/primitives/Shapes.mjs +12 -10
  76. package/dist/primitives/Tex.mjs +2 -2
  77. package/dist/primitives/index.d.mts +2 -2
  78. package/dist/primitives/index.mjs +2 -2
  79. package/dist/primitives/props.mjs +31 -0
  80. package/dist/scene/Scene.d.mts +6 -1
  81. package/dist/scene/Scene.mjs +16 -41
  82. package/dist/scene/assets.d.mts +2 -2
  83. package/dist/scene/assets.mjs +2 -2
  84. package/dist/scene/commands.d.mts +10 -1
  85. package/dist/scene/commands.mjs +42 -2
  86. package/dist/scene/evaluators.mjs +2 -2
  87. package/dist/scene/index.d.mts +2 -2
  88. package/dist/scene/index.mjs +2 -2
  89. package/dist/scene/migrate.mjs +1 -1
  90. package/dist/scene/sims.mjs +1 -1
  91. package/dist/scene/types.d.mts +4 -4
  92. package/dist/sim/particles.d.mts +2 -2
  93. package/dist/sim/rate.d.mts +4 -4
  94. package/dist/sim/rate.mjs +1 -1
  95. package/dist/sim/registry.d.mts +1 -1
  96. package/dist/sim/sampler.d.mts +5 -5
  97. package/dist/sim/thermal.d.mts +3 -3
  98. package/dist/sim/thermal.mjs +2 -2
  99. package/dist/sim/types.d.mts +2 -2
  100. package/dist/sim/wave.d.mts +2 -2
  101. package/dist/sim/wave.mjs +2 -2
  102. package/dist/steps/index.d.mts +1 -1
  103. package/dist/steps/index.mjs +3 -3
  104. package/dist/thermo/index.d.mts +1 -1
  105. package/dist/thermo/index.mjs +1 -1
  106. package/dist/view/Stage.mjs +6 -13
  107. package/dist/view/useInView.mjs +1 -1
  108. package/package.json +37 -25
  109. package/styles.css +141 -1
  110. package/dist/assets/kit/index.mjs +0 -4
package/dist/index.d.mts CHANGED
@@ -15,6 +15,7 @@ import { Palette, PaletteProps } from "./builder/Palette.mjs";
15
15
  import { CoordsContext, DragOverlayContext, StageRefContext, useCoords, useDragOverlay, useStageRef } from "./core/context.mjs";
16
16
  import { ClockProvider, ClockProviderProps, FrameDriver, FrameInfo, useFrameLoop } from "./core/clock.mjs";
17
17
  import { Learner, LearnerProvider, LearnerResult, PriorAttempts, useLearner } from "./core/learner.mjs";
18
+ import { approxEq, clamp, clamp01, gcd, remap, round, snapTo, toDeg, toRad } from "./core/math.mjs";
18
19
  import { RichSpan, Script, parseRichText } from "./core/richText.mjs";
19
20
  import { StepProgress, StepProgressProvider, StepScope, StepSpec, StepState, useStepProgress } from "./steps/index.mjs";
20
21
  import { Stage, StageProps } from "./view/Stage.mjs";
@@ -26,12 +27,13 @@ import { Line, LineProps, Ray, Segment, SegmentProps, Vector, VectorProps } from
26
27
  import { Circle, CircleProps, Ellipse, EllipseProps, Path, PathProps, Polygon, PolygonProps, Polyline, PolylineProps } from "./primitives/Shapes.mjs";
27
28
  import { Label, LabelProps } from "./primitives/Label.mjs";
28
29
  import { Tex, TexProps } from "./primitives/Tex.mjs";
29
- import { Axes, AxesProps, Grid, GridProps, niceStep } from "./primitives/Grid.mjs";
30
+ import { Axes, AxesProps, ClearZone, Grid, GridProps, clearOfLabel, niceStep } from "./primitives/Grid.mjs";
30
31
  import { OfXProps, OfYProps, ParametricProps, Plot } from "./primitives/Plot.mjs";
31
32
  import { CanvasLayer, CanvasLayerProps } from "./primitives/CanvasLayer.mjs";
32
33
  import { useScreenToMath } from "./interaction/useScreenToMath.mjs";
33
34
  import { AriaSliderProps, Constrain, DraggableHandlers, UseDraggable, UseDraggableArgs, useDraggable } from "./interaction/useDraggable.mjs";
34
35
  import { MovableDot, MovableDotProps } from "./interaction/MovableDot.mjs";
36
+ import { PressSpringOpts, useImpulse, usePressSpring } from "./interaction/usePressSpring.mjs";
35
37
  import { HitCandidate, hitTest } from "./interaction/hitTest.mjs";
36
38
  import { OP_REFS, isRef, parentIds } from "./scene/schema.mjs";
37
39
  import { EVALUATORS, EvalCtx } from "./scene/evaluators.mjs";
@@ -41,7 +43,8 @@ import { Scene, SceneProps } from "./scene/Scene.mjs";
41
43
  import { RenderOpts, renderElements } from "./scene/render.mjs";
42
44
  import { BinOp, Node, compileNode, evaluate, freeVars } from "./math/ast.mjs";
43
45
  import { parse as parse$1 } from "./math/parse.mjs";
44
- import { differentiate, simplify } from "./math/calculus.mjs";
46
+ import { definiteIntegral, differentiate, integrate, simplify } from "./math/calculus.mjs";
47
+ import { CompiledFn, compile } from "./math/compile.mjs";
45
48
  import { toLatex as toLatex$1 } from "./math/latex.mjs";
46
49
  import { CompiledExpr, ExprError, ExprResult, compileExpr } from "./math/index.mjs";
47
50
  import { BinOp as BinOp$1, LNode, evalBool, freeVars as freeVars$1 } from "./logic/ast.mjs";
@@ -51,4 +54,4 @@ import { toLatex } from "./logic/latex.mjs";
51
54
  import { Cube, Minimization, cubeCovers, cubeOfSelection, cubeTerm, minimalCover, minimize, primeImplicants } from "./logic/minimize.mjs";
52
55
  import { CompiledLogic, LogicResult, compileLogic } from "./logic/index.mjs";
53
56
  import { AssetResolveArgs, AssetSpec, assetMeta, getAsset, listAssets, registerAsset } from "./scene/assets.mjs";
54
- export { type A11yProps, AUTHORING_TOOLS, type AriaSliderProps, type AssetGeometry, type AssetResolveArgs, type AssetSpec, Axes, type AxesProps, type BinOp, type Binding, BucketGlyph, CIRCLE, CURRENT_SCHEMA_VERSION, CanvasLayer, type CanvasLayerProps, Circle, type CircleProps, type CircleVal, type Classification, ClockProvider, type ClockProviderProps, type Command, type CommandResult, type CompiledExpr, type CompiledLogic, type Constrain, type ControlMap, type ControlPick, type ControlSpec, type ControlSurface, type CoordinateSystem, CoordsContext, type CoordsOptions, type Cube, DELETE, type DerivedDef, type DerivedElement, type DerivedKind, type DispatchOpts, Dot, type DotProps, DragOverlayContext, type DraggableHandlers, EVALUATORS, Editor, type ElementBase, type ElementStyle, Ellipse, type EllipseProps, type EvalCtx, type ExprError, type ExprResult, type FrameDriver, type FrameInfo, type FreeElement, type FreeNote, type FreePoint, type FreeScalar, GEOMETRY_TOOLS, type GlyphBox, Grid, type GridProps, HangerHook, type HangerHookProps, type HitCandidate, INTERSECT, type IconName, type Id, type InstanceState, LINE, type LNode, type LabMeta, Label, type LabelProps, type Learner, LearnerProvider, type LearnerResult, Line, type LineProps, type BinOp$1 as LogicBinOp, type LogicResult, MEASURE, MIDPOINT, type Matrix, type Minimization, MovableDot, type MovableDotProps, type MutatePatch, NOTE, type Node, type NumOrRef, OP_REFS, type OfXProps, type OfYProps, type Op, POINT, Palette, type PaletteProps, type ParametricProps, Path, type PathProps, Plot, Point, Polygon, type PolygonProps, Polyline, type PolylineProps, type PriorAttempts, Ray, type Ref, type RenderOpts, type Resolved, type RichSpan, SCALAR, SEGMENT, SELECT, Scene, SceneBuilder, type SceneBuilderProps, type SceneDoc, type SceneElement, type SceneMeta, type SceneProps, SceneStore, type Vec2 as SceneVec2, type Script, Segment, type SegmentProps, type ShapeLineVal, type Size, Stage, StageAssetDefs, type StageProps, StageRefContext, type StepProgress, StepProgressProvider, StepScope, type StepSpec, type StepState, type StyleProps, Tex, type TexProps, type Tool, type ToolCtx, ToolIcon, type TruthRow, type TruthTable, type UseDraggable, type UseDraggableArgs, type Val, type Vec2, Vector, type VectorProps, type ViewBox, WeightGlyph, XBlockGlyph, applyCommand, assetMeta, classify, collectRemoved, compileExpr, compileLogic, compileNode, controlsFromScene, createCoords, cubeCovers, cubeOfSelection, cubeTerm, differentiate, emptyDoc, equivalent, evalBool, evaluate, fmt, freeVars, getAsset, getControlSurface, hitTest, inverse, isAssetGeom, isCircleVal, isDerived, isFree, isLineVal, isRef, isVec2, listAssets, listControlSurfaces, freeVars$1 as logicFreeVars, toLatex as logicToLatex, mat, migrate, minimalCover, minimize, niceStep, numOf, onControlChange, parentIds, parse, parse$1 as parseExpr, parseLogic, parseRichText, primeImplicants, registerAsset, renderElements, resolve, serialize, simplify, toCNF, toDNF, toLatex$1 as toLatex, truthTable, useControlSurface, useCoords, useDragOverlay, useDraggable, useEditor, useElementSize, useFrameLoop, useInView, useLearner, useScreenToMath, useStageRef, useStepProgress, vec };
57
+ export { type A11yProps, AUTHORING_TOOLS, type AriaSliderProps, type AssetGeometry, type AssetResolveArgs, type AssetSpec, Axes, type AxesProps, type BinOp, type Binding, BucketGlyph, CIRCLE, CURRENT_SCHEMA_VERSION, CanvasLayer, type CanvasLayerProps, Circle, type CircleProps, type CircleVal, type Classification, type ClearZone, ClockProvider, type ClockProviderProps, type Command, type CommandResult, type CompiledExpr, type CompiledFn, type CompiledLogic, type Constrain, type ControlMap, type ControlPick, type ControlSpec, type ControlSurface, type CoordinateSystem, CoordsContext, type CoordsOptions, type Cube, DELETE, type DerivedDef, type DerivedElement, type DerivedKind, type DispatchOpts, Dot, type DotProps, DragOverlayContext, type DraggableHandlers, EVALUATORS, Editor, type ElementBase, type ElementStyle, Ellipse, type EllipseProps, type EvalCtx, type ExprError, type ExprResult, type FrameDriver, type FrameInfo, type FreeElement, type FreeNote, type FreePoint, type FreeScalar, GEOMETRY_TOOLS, type GlyphBox, Grid, type GridProps, HangerHook, type HangerHookProps, type HitCandidate, INTERSECT, type IconName, type Id, type InstanceState, LINE, type LNode, type LabMeta, Label, type LabelProps, type Learner, LearnerProvider, type LearnerResult, Line, type LineProps, type BinOp$1 as LogicBinOp, type LogicResult, MEASURE, MIDPOINT, type Matrix, type Minimization, MovableDot, type MovableDotProps, type MutatePatch, NOTE, type Node, type NumOrRef, OP_REFS, type OfXProps, type OfYProps, type Op, POINT, Palette, type PaletteProps, type ParametricProps, Path, type PathProps, Plot, Point, Polygon, type PolygonProps, Polyline, type PolylineProps, type PressSpringOpts, type PriorAttempts, Ray, type Ref, type RenderOpts, type Resolved, type RichSpan, SCALAR, SEGMENT, SELECT, Scene, SceneBuilder, type SceneBuilderProps, type SceneDoc, type SceneElement, type SceneMeta, type SceneProps, SceneStore, type Vec2 as SceneVec2, type Script, Segment, type SegmentProps, type ShapeLineVal, type Size, Stage, StageAssetDefs, type StageProps, StageRefContext, type StepProgress, StepProgressProvider, StepScope, type StepSpec, type StepState, type StyleProps, Tex, type TexProps, type Tool, type ToolCtx, ToolIcon, type TruthRow, type TruthTable, type UseDraggable, type UseDraggableArgs, type Val, type Vec2, Vector, type VectorProps, type ViewBox, WeightGlyph, XBlockGlyph, applyCommand, approxEq, assetMeta, clamp, clamp01, classify, clearOfLabel, collectRemoved, compile, compileExpr, compileLogic, compileNode, controlsFromScene, createCoords, cubeCovers, cubeOfSelection, cubeTerm, definiteIntegral, differentiate, emptyDoc, equivalent, evalBool, evaluate, fmt, freeVars, gcd, getAsset, getControlSurface, hitTest, integrate, inverse, isAssetGeom, isCircleVal, isDerived, isFree, isLineVal, isRef, isVec2, listAssets, listControlSurfaces, freeVars$1 as logicFreeVars, toLatex as logicToLatex, mat, migrate, minimalCover, minimize, niceStep, numOf, onControlChange, parentIds, parse, parse$1 as parseExpr, parseLogic, parseRichText, primeImplicants, registerAsset, remap, renderElements, resolve, round, serialize, simplify, snapTo, toCNF, toDNF, toDeg, toLatex$1 as toLatex, toRad, truthTable, useControlSurface, useCoords, useDragOverlay, useDraggable, useEditor, useElementSize, useFrameLoop, useImpulse, useInView, useLearner, usePressSpring, useScreenToMath, useStageRef, useStepProgress, vec };
package/dist/index.mjs CHANGED
@@ -5,6 +5,7 @@ import { CoordsContext, DragOverlayContext, StageRefContext, useCoords, useDragO
5
5
  import { ClockProvider, useFrameLoop } from "./core/clock.mjs";
6
6
  import { getControlSurface, listControlSurfaces, onControlChange, useControlSurface } from "./core/control.mjs";
7
7
  import { LearnerProvider, useLearner } from "./core/learner.mjs";
8
+ import { approxEq, clamp, clamp01, gcd, remap, round, snapTo, toDeg, toRad } from "./core/math.mjs";
8
9
  import { StepProgressProvider, StepScope, useStepProgress } from "./steps/index.mjs";
9
10
  import { useElementSize } from "./view/useElementSize.mjs";
10
11
  import { Stage } from "./view/Stage.mjs";
@@ -14,11 +15,12 @@ import { Line, Ray, Segment, Vector } from "./primitives/Lines.mjs";
14
15
  import { Circle, Ellipse, Path, Polygon, Polyline } from "./primitives/Shapes.mjs";
15
16
  import { Label } from "./primitives/Label.mjs";
16
17
  import { Tex } from "./primitives/Tex.mjs";
17
- import { Axes, Grid, niceStep } from "./primitives/Grid.mjs";
18
+ import { Axes, Grid, clearOfLabel, niceStep } from "./primitives/Grid.mjs";
18
19
  import { Plot } from "./primitives/Plot.mjs";
19
20
  import { CanvasLayer } from "./primitives/CanvasLayer.mjs";
20
21
  import { useScreenToMath } from "./interaction/useScreenToMath.mjs";
21
22
  import { useDraggable } from "./interaction/useDraggable.mjs";
23
+ import { useImpulse, usePressSpring } from "./interaction/usePressSpring.mjs";
22
24
  import { MovableDot } from "./interaction/MovableDot.mjs";
23
25
  import { hitTest } from "./interaction/hitTest.mjs";
24
26
  import { isAssetGeom, isCircleVal, isDerived, isFree, isLineVal, isVec2, numOf } from "./scene/types.mjs";
@@ -26,7 +28,8 @@ import { OP_REFS, isRef, parentIds } from "./scene/schema.mjs";
26
28
  import { assetMeta, getAsset, listAssets, registerAsset } from "./scene/assets.mjs";
27
29
  import { compileNode, evaluate, freeVars } from "./math/ast.mjs";
28
30
  import { parse as parse$1 } from "./math/parse.mjs";
29
- import { differentiate, simplify } from "./math/calculus.mjs";
31
+ import { definiteIntegral, differentiate, integrate, simplify } from "./math/calculus.mjs";
32
+ import { compile } from "./math/compile.mjs";
30
33
  import { toLatex as toLatex$1 } from "./math/latex.mjs";
31
34
  import { compileExpr } from "./math/index.mjs";
32
35
  import { EVALUATORS } from "./scene/evaluators.mjs";
@@ -44,7 +47,6 @@ import { AUTHORING_TOOLS, CIRCLE, DELETE, GEOMETRY_TOOLS, INTERSECT, LINE, MEASU
44
47
  import { SceneBuilder } from "./builder/SceneBuilder.mjs";
45
48
  import { StageAssetDefs } from "./assets/kit/svg-defs.mjs";
46
49
  import { BucketGlyph, HangerHook, WeightGlyph, XBlockGlyph } from "./assets/kit/glyphs.mjs";
47
- import "./assets/kit/index.mjs";
48
50
  import { evalBool, freeVars as freeVars$1 } from "./logic/ast.mjs";
49
51
  import { parseLogic } from "./logic/parse.mjs";
50
52
  import { classify, equivalent, toCNF, toDNF, truthTable } from "./logic/table.mjs";
@@ -52,4 +54,4 @@ import { toLatex } from "./logic/latex.mjs";
52
54
  import { cubeCovers, cubeOfSelection, cubeTerm, minimalCover, minimize, primeImplicants } from "./logic/minimize.mjs";
53
55
  import { compileLogic } from "./logic/index.mjs";
54
56
 
55
- export { AUTHORING_TOOLS, Axes, BucketGlyph, CIRCLE, CURRENT_SCHEMA_VERSION, CanvasLayer, Circle, ClockProvider, CoordsContext, DELETE, Dot, DragOverlayContext, EVALUATORS, Editor, Ellipse, GEOMETRY_TOOLS, Grid, HangerHook, INTERSECT, LINE, Label, LearnerProvider, Line, MEASURE, MIDPOINT, MovableDot, NOTE, OP_REFS, POINT, Palette, Path, Plot, Point, Polygon, Polyline, Ray, SCALAR, SEGMENT, SELECT, Scene, SceneBuilder, SceneStore, Segment, Stage, StageAssetDefs, StageRefContext, StepProgressProvider, StepScope, Tex, ToolIcon, Vector, WeightGlyph, XBlockGlyph, applyCommand, assetMeta, classify, collectRemoved, compileExpr, compileLogic, compileNode, controlsFromScene, createCoords, cubeCovers, cubeOfSelection, cubeTerm, differentiate, emptyDoc, equivalent, evalBool, evaluate, fmt, freeVars, getAsset, getControlSurface, hitTest, inverse, isAssetGeom, isCircleVal, isDerived, isFree, isLineVal, isRef, isVec2, listAssets, listControlSurfaces, freeVars$1 as logicFreeVars, toLatex as logicToLatex, mat, migrate, minimalCover, minimize, niceStep, numOf, onControlChange, parentIds, parse, parse$1 as parseExpr, parseLogic, parseRichText, primeImplicants, registerAsset, renderElements, resolve, serialize, simplify, toCNF, toDNF, toLatex$1 as toLatex, truthTable, useControlSurface, useCoords, useDragOverlay, useDraggable, useEditor, useElementSize, useFrameLoop, useInView, useLearner, useScreenToMath, useStageRef, useStepProgress, vec };
57
+ export { AUTHORING_TOOLS, Axes, BucketGlyph, CIRCLE, CURRENT_SCHEMA_VERSION, CanvasLayer, Circle, ClockProvider, CoordsContext, DELETE, Dot, DragOverlayContext, EVALUATORS, Editor, Ellipse, GEOMETRY_TOOLS, Grid, HangerHook, INTERSECT, LINE, Label, LearnerProvider, Line, MEASURE, MIDPOINT, MovableDot, NOTE, OP_REFS, POINT, Palette, Path, Plot, Point, Polygon, Polyline, Ray, SCALAR, SEGMENT, SELECT, Scene, SceneBuilder, SceneStore, Segment, Stage, StageAssetDefs, StageRefContext, StepProgressProvider, StepScope, Tex, ToolIcon, Vector, WeightGlyph, XBlockGlyph, applyCommand, approxEq, assetMeta, clamp, clamp01, classify, clearOfLabel, collectRemoved, compile, compileExpr, compileLogic, compileNode, controlsFromScene, createCoords, cubeCovers, cubeOfSelection, cubeTerm, definiteIntegral, differentiate, emptyDoc, equivalent, evalBool, evaluate, fmt, freeVars, gcd, getAsset, getControlSurface, hitTest, integrate, inverse, isAssetGeom, isCircleVal, isDerived, isFree, isLineVal, isRef, isVec2, listAssets, listControlSurfaces, freeVars$1 as logicFreeVars, toLatex as logicToLatex, mat, migrate, minimalCover, minimize, niceStep, numOf, onControlChange, parentIds, parse, parse$1 as parseExpr, parseLogic, parseRichText, primeImplicants, registerAsset, remap, renderElements, resolve, round, serialize, simplify, snapTo, toCNF, toDNF, toDeg, toLatex$1 as toLatex, toRad, truthTable, useControlSurface, useCoords, useDragOverlay, useDraggable, useEditor, useElementSize, useFrameLoop, useImpulse, useInView, useLearner, usePressSpring, useScreenToMath, useStageRef, useStepProgress, vec };
@@ -18,6 +18,18 @@ interface MovableDotProps {
18
18
  /** Keyboard arrow-key nudge in math units. Match the lab's snap grid so a
19
19
  * single arrow press actually moves (e.g. 1 for an integer number line). */
20
20
  step?: number;
21
+ /** Math-unit snap grid. Tells the handle the lattice so it can preview the
22
+ * candidate landing spots (ghosts) and a snap-tick — purely visual; the lab
23
+ * still owns the actual snapping in its onMove. 0/undefined = no preview. */
24
+ snap?: number;
25
+ /** Faint candidate snap-stops shown while dragging (default: on when `snap`
26
+ * is set). Pass explicit points to drive non-grid lattices (e.g. stops along
27
+ * a ray); otherwise they're derived from `snap` + the view + `constrain`. */
28
+ ghosts?: boolean;
29
+ ghostPoints?: Vec2[];
30
+ /** Live value pill near the handle while dragging. true = default formatter,
31
+ * a fn for custom text, false to hide. Default true. */
32
+ readout?: boolean | ((v: Vec2) => string);
21
33
  }
22
34
  declare function MovableDot({
23
35
  value,
@@ -27,7 +39,11 @@ declare function MovableDot({
27
39
  r,
28
40
  ariaLabel,
29
41
  range,
30
- step
42
+ step,
43
+ snap,
44
+ ghosts,
45
+ ghostPoints,
46
+ readout
31
47
  }: MovableDotProps): ReactNode;
32
48
  //#endregion
33
49
  export { MovableDot, MovableDotProps };
@@ -2,12 +2,52 @@
2
2
 
3
3
  import { useCoords } from "../core/context.mjs";
4
4
  import { useDraggable } from "./useDraggable.mjs";
5
+ import { useImpulse, usePressSpring } from "./usePressSpring.mjs";
5
6
  import { useState } from "react";
6
- import { jsx, jsxs } from "react/jsx-runtime";
7
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
7
8
 
8
9
  //#region src/interaction/MovableDot.tsx
9
- function MovableDot({ value, onMove, constrain, color = "var(--stage-accent)", r = 7, ariaLabel = "draggable point", range, step }) {
10
- const [px, py] = useCoords().toPx(value.x, value.y);
10
+ const ACCENT = "var(--stage-accent)";
11
+ function fnum(n) {
12
+ const r = Math.round(n * 100) / 100;
13
+ return Object.is(r, -0) ? "0" : String(r);
14
+ }
15
+ /** Candidate snap-stops within a small window around `value`, derived from the
16
+ * grid + which axes are free. Kept LOCAL (±3 steps) so the guide reads as
17
+ * "here are your nearby choices", not a wall of dots. */
18
+ function autoGhosts(value, snap, constrain, view, range) {
19
+ if (!(snap > 0)) return [];
20
+ const W = 3;
21
+ const stops = [];
22
+ const along = (axis) => {
23
+ const base = axis === "x" ? value.x : value.y;
24
+ const lo = axis === "x" ? range?.min ?? view.xMin : range?.min ?? view.yMin;
25
+ const hi = axis === "x" ? range?.max ?? view.xMax : range?.max ?? view.yMax;
26
+ for (let k = -3; k <= W; k++) {
27
+ if (k === 0) continue;
28
+ const v = Math.round(base / snap) * snap + k * snap;
29
+ if (v < lo - 1e-9 || v > hi + 1e-9) continue;
30
+ stops.push(axis === "x" ? {
31
+ x: v,
32
+ y: value.y
33
+ } : {
34
+ x: value.x,
35
+ y: v
36
+ });
37
+ }
38
+ };
39
+ const oneD = constrain === "horizontal" || constrain === "vertical";
40
+ if (constrain === "horizontal") along("x");
41
+ else if (constrain === "vertical") along("y");
42
+ else if (!oneD && typeof constrain !== "function") {
43
+ along("x");
44
+ along("y");
45
+ }
46
+ return stops;
47
+ }
48
+ function MovableDot({ value, onMove, constrain, color = ACCENT, r = 7, ariaLabel = "draggable point", range, step, snap, ghosts, ghostPoints, readout = true }) {
49
+ const c = useCoords();
50
+ const [px, py] = c.toPx(value.x, value.y);
11
51
  const { dragging, handlers, ariaProps } = useDraggable({
12
52
  value,
13
53
  onMove,
@@ -16,50 +56,127 @@ function MovableDot({ value, onMove, constrain, color = "var(--stage-accent)", r
16
56
  ...step !== void 0 ? { step } : {}
17
57
  });
18
58
  const [hovered, setHovered] = useState(false);
19
- const lift = hovered && !dragging;
20
- const dotR = lift ? r + 1.5 : r;
21
- return /* @__PURE__ */ jsxs("g", {
22
- ...handlers,
23
- ...ariaProps,
24
- "aria-label": ariaLabel,
25
- onPointerEnter: () => setHovered(true),
26
- onPointerLeave: () => setHovered(false),
27
- style: {
28
- cursor: dragging ? "grabbing" : "grab",
29
- outline: "none"
30
- },
31
- children: [
32
- /* @__PURE__ */ jsx("circle", {
33
- cx: px,
34
- cy: py,
35
- r: Math.max(r + 14, 12),
36
- fill: "transparent"
37
- }),
38
- dragging ? /* @__PURE__ */ jsx("circle", {
39
- cx: px,
40
- cy: py,
41
- r: r + 6,
42
- fill: color,
43
- opacity: .2
44
- }) : /* @__PURE__ */ jsx("circle", {
59
+ const [interacted, setInteracted] = useState(false);
60
+ const press = usePressSpring(dragging, {
61
+ to: 1,
62
+ stiffness: 360,
63
+ damping: 24
64
+ });
65
+ const dotR = r + (hovered && !dragging ? 1.5 : 0) + press * 3;
66
+ const tickRaw = useImpulse(`${Math.round(value.x * 1e4)}:${Math.round(value.y * 1e4)}`, 280);
67
+ const tick = dragging ? tickRaw : 0;
68
+ const stops = !(dragging && (ghosts ?? (snap != null && snap > 0))) ? [] : ghostPoints ?? autoGhosts(value, snap ?? 0, constrain, c.view, range);
69
+ const label = readout === false ? null : typeof readout === "function" ? readout(value) : constrain === "horizontal" || constrain === "vertical" ? fnum(constrain === "vertical" ? value.y : value.x) : `(${fnum(value.x)}, ${fnum(value.y)})`;
70
+ const pillW = label ? Math.max(30, label.length * 7.5 + 14) : 0;
71
+ const pillY = py - dotR - 30;
72
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
73
+ stops.length > 0 && /* @__PURE__ */ jsx("g", {
74
+ style: { pointerEvents: "none" },
75
+ children: stops.map((s, i) => {
76
+ const [gx, gy] = c.toPx(s.x, s.y);
77
+ const d = Math.hypot(gx - px, gy - py);
78
+ return /* @__PURE__ */ jsx("circle", {
79
+ cx: gx,
80
+ cy: gy,
81
+ r: 3,
82
+ fill: color,
83
+ opacity: Math.max(.12, .5 - d / 360)
84
+ }, i);
85
+ })
86
+ }),
87
+ /* @__PURE__ */ jsxs("g", {
88
+ ...handlers,
89
+ ...ariaProps,
90
+ "aria-label": ariaLabel,
91
+ onPointerDown: (e) => {
92
+ setInteracted(true);
93
+ handlers.onPointerDown(e);
94
+ },
95
+ onKeyDown: (e) => {
96
+ setInteracted(true);
97
+ handlers.onKeyDown(e);
98
+ },
99
+ onPointerEnter: () => setHovered(true),
100
+ onPointerLeave: () => setHovered(false),
101
+ style: {
102
+ cursor: dragging ? "grabbing" : "grab",
103
+ outline: "none"
104
+ },
105
+ children: [
106
+ /* @__PURE__ */ jsx("circle", {
107
+ cx: px,
108
+ cy: py,
109
+ r: Math.max(r + 14, 12),
110
+ fill: "transparent"
111
+ }),
112
+ !interacted && !dragging && /* @__PURE__ */ jsx("circle", {
113
+ className: "stage-nudge",
114
+ cx: px,
115
+ cy: py,
116
+ r: r + 5,
117
+ fill: "none",
118
+ stroke: color,
119
+ strokeWidth: 1.5,
120
+ style: { pointerEvents: "none" }
121
+ }),
122
+ dragging ? /* @__PURE__ */ jsx("circle", {
123
+ cx: px,
124
+ cy: py,
125
+ r: r + 6 + press * 4,
126
+ fill: color,
127
+ opacity: .18
128
+ }) : /* @__PURE__ */ jsx("circle", {
129
+ cx: px,
130
+ cy: py,
131
+ r: r + 5,
132
+ fill: "none",
133
+ stroke: color,
134
+ strokeWidth: 1.5,
135
+ opacity: hovered ? .55 : .28
136
+ }),
137
+ /* @__PURE__ */ jsx("circle", {
138
+ cx: px,
139
+ cy: py,
140
+ r: dotR,
141
+ fill: color,
142
+ stroke: "var(--stage-bg)",
143
+ strokeWidth: 2
144
+ })
145
+ ]
146
+ }),
147
+ /* @__PURE__ */ jsxs("g", {
148
+ style: { pointerEvents: "none" },
149
+ children: [tick > 0 && /* @__PURE__ */ jsx("circle", {
45
150
  cx: px,
46
151
  cy: py,
47
- r: r + 5,
152
+ r: dotR + (1 - tick) * 12,
48
153
  fill: "none",
49
154
  stroke: color,
50
- strokeWidth: 1.5,
51
- opacity: lift ? .55 : .28
52
- }),
53
- /* @__PURE__ */ jsx("circle", {
54
- cx: px,
55
- cy: py,
56
- r: dotR,
57
- fill: color,
58
- stroke: "var(--stage-bg)",
59
- strokeWidth: 2
60
- })
61
- ]
62
- });
155
+ strokeWidth: 2,
156
+ opacity: tick * .6
157
+ }), dragging && label && /* @__PURE__ */ jsxs("g", { children: [/* @__PURE__ */ jsx("rect", {
158
+ x: px - pillW / 2,
159
+ y: pillY,
160
+ width: pillW,
161
+ height: 22,
162
+ rx: 7,
163
+ fill: "var(--stage-bg)",
164
+ stroke: "var(--stage-grid)",
165
+ strokeWidth: 1,
166
+ opacity: .96
167
+ }), /* @__PURE__ */ jsx("text", {
168
+ x: px,
169
+ y: pillY + 11,
170
+ textAnchor: "middle",
171
+ dominantBaseline: "central",
172
+ fontSize: 12,
173
+ fontWeight: 700,
174
+ fill: "var(--stage-fg)",
175
+ style: { fontVariantNumeric: "tabular-nums" },
176
+ children: label
177
+ })] })]
178
+ })
179
+ ] });
63
180
  }
64
181
 
65
182
  //#endregion
@@ -1,5 +1,6 @@
1
1
  import { useScreenToMath } from "./useScreenToMath.mjs";
2
2
  import { AriaSliderProps, Constrain, DraggableHandlers, UseDraggable, UseDraggableArgs, useDraggable } from "./useDraggable.mjs";
3
3
  import { MovableDot, MovableDotProps } from "./MovableDot.mjs";
4
+ import { PressSpringOpts, useImpulse, usePressSpring } from "./usePressSpring.mjs";
4
5
  import { HitCandidate, hitTest } from "./hitTest.mjs";
5
- export { type AriaSliderProps, type Constrain, type DraggableHandlers, type HitCandidate, MovableDot, type MovableDotProps, type UseDraggable, type UseDraggableArgs, hitTest, useDraggable, useScreenToMath };
6
+ export { type AriaSliderProps, type Constrain, type DraggableHandlers, type HitCandidate, MovableDot, type MovableDotProps, type PressSpringOpts, type UseDraggable, type UseDraggableArgs, hitTest, useDraggable, useImpulse, usePressSpring, useScreenToMath };
@@ -1,6 +1,7 @@
1
1
  import { useScreenToMath } from "./useScreenToMath.mjs";
2
2
  import { useDraggable } from "./useDraggable.mjs";
3
+ import { useImpulse, usePressSpring } from "./usePressSpring.mjs";
3
4
  import { MovableDot } from "./MovableDot.mjs";
4
5
  import { hitTest } from "./hitTest.mjs";
5
6
 
6
- export { MovableDot, hitTest, useDraggable, useScreenToMath };
7
+ export { MovableDot, hitTest, useDraggable, useImpulse, usePressSpring, useScreenToMath };
@@ -10,7 +10,7 @@ interface UseDraggableArgs {
10
10
  constrain?: Constrain;
11
11
  /** Keyboard nudge step in math units. */
12
12
  step?: number;
13
- /** Bounds on the active axis drives aria-valuemin/max for a proper slider
13
+ /** Bounds on the active axis, drives aria-valuemin/max for a proper slider
14
14
  * (WAI-ARIA APG). Omit for an unbounded 2D point (valuetext still describes it). */
15
15
  range?: {
16
16
  min: number;
@@ -1,7 +1,7 @@
1
1
  'use client';
2
2
 
3
3
  import { useScreenToMath } from "./useScreenToMath.mjs";
4
- import { useCallback, useRef, useState } from "react";
4
+ import { useCallback, useEffect, useRef, useState } from "react";
5
5
 
6
6
  //#region src/interaction/useDraggable.ts
7
7
  function constrained(p, start, constrain) {
@@ -20,6 +20,20 @@ function useDraggable({ value, onMove, constrain, step = .5, range }) {
20
20
  const toMath = useScreenToMath();
21
21
  const [dragging, setDragging] = useState(false);
22
22
  const startRef = useRef(value);
23
+ const onMoveRef = useRef(onMove);
24
+ onMoveRef.current = onMove;
25
+ const pendingRef = useRef(null);
26
+ const rafRef = useRef(0);
27
+ const flushMove = useCallback(() => {
28
+ rafRef.current = 0;
29
+ const p = pendingRef.current;
30
+ if (!p) return;
31
+ pendingRef.current = null;
32
+ onMoveRef.current(p, "move");
33
+ }, []);
34
+ useEffect(() => () => {
35
+ if (rafRef.current) cancelAnimationFrame(rafRef.current);
36
+ }, []);
23
37
  const onPointerDown = useCallback((e) => {
24
38
  e.currentTarget.setPointerCapture(e.pointerId);
25
39
  startRef.current = value;
@@ -30,19 +44,25 @@ function useDraggable({ value, onMove, constrain, step = .5, range }) {
30
44
  if (!dragging) return;
31
45
  const m = toMath(e);
32
46
  if (!m) return;
33
- onMove(constrained({
47
+ pendingRef.current = constrained({
34
48
  x: m[0],
35
49
  y: m[1]
36
- }, startRef.current, constrain), "move");
50
+ }, startRef.current, constrain);
51
+ if (!rafRef.current) rafRef.current = requestAnimationFrame(flushMove);
37
52
  }, [
38
53
  dragging,
39
54
  toMath,
40
55
  constrain,
41
- onMove
56
+ flushMove
42
57
  ]);
43
58
  const onPointerUp = useCallback((e) => {
44
59
  if (!dragging) return;
45
60
  setDragging(false);
61
+ if (rafRef.current) {
62
+ cancelAnimationFrame(rafRef.current);
63
+ rafRef.current = 0;
64
+ }
65
+ pendingRef.current = null;
46
66
  const m = toMath(e);
47
67
  onMove(m ? constrained({
48
68
  x: m[0],
@@ -57,6 +77,7 @@ function useDraggable({ value, onMove, constrain, step = .5, range }) {
57
77
  ]);
58
78
  const onKeyDown = useCallback((e) => {
59
79
  const d = step * (e.shiftKey ? 5 : 1) * (e.altKey ? .25 : 1);
80
+ const vertical = constrain === "vertical";
60
81
  let np = null;
61
82
  if (e.key === "ArrowLeft") np = {
62
83
  x: value.x - d,
@@ -74,6 +95,34 @@ function useDraggable({ value, onMove, constrain, step = .5, range }) {
74
95
  x: value.x,
75
96
  y: value.y - d
76
97
  };
98
+ else if (e.key === "PageUp") np = vertical ? {
99
+ x: value.x,
100
+ y: value.y + 5 * step
101
+ } : {
102
+ x: value.x + 5 * step,
103
+ y: value.y
104
+ };
105
+ else if (e.key === "PageDown") np = vertical ? {
106
+ x: value.x,
107
+ y: value.y - 5 * step
108
+ } : {
109
+ x: value.x - 5 * step,
110
+ y: value.y
111
+ };
112
+ else if (e.key === "Home" && range) np = vertical ? {
113
+ x: value.x,
114
+ y: range.min
115
+ } : {
116
+ x: range.min,
117
+ y: value.y
118
+ };
119
+ else if (e.key === "End" && range) np = vertical ? {
120
+ x: value.x,
121
+ y: range.max
122
+ } : {
123
+ x: range.max,
124
+ y: value.y
125
+ };
77
126
  if (np) {
78
127
  e.preventDefault();
79
128
  const p = constrained(np, value, constrain);
@@ -84,7 +133,8 @@ function useDraggable({ value, onMove, constrain, step = .5, range }) {
84
133
  value,
85
134
  step,
86
135
  constrain,
87
- onMove
136
+ onMove,
137
+ range
88
138
  ]);
89
139
  const oneD = constrain === "horizontal" || constrain === "vertical";
90
140
  const vertical = constrain === "vertical";
@@ -0,0 +1,24 @@
1
+ //#region src/interaction/usePressSpring.d.ts
2
+ interface PressSpringOpts {
3
+ /** Resting value when inactive. Default 0. */
4
+ from?: number;
5
+ /** Target value when active. Default 1. */
6
+ to?: number;
7
+ stiffness?: number;
8
+ damping?: number;
9
+ }
10
+ /**
11
+ * A scalar that springs toward `to` while `active`, back to `from` on release,
12
+ * e.g. a 0→1 "press" amount you map to a radius bump or halo grow. The RAF loop
13
+ * is gated on "still moving" so a page full of idle handles costs nothing.
14
+ * Under reduced-motion it returns the target immediately (no animation).
15
+ */
16
+ declare function usePressSpring(active: boolean, opts?: PressSpringOpts): number;
17
+ /**
18
+ * A one-shot impulse: jumps to 1 whenever `key` changes, then decays to 0 over
19
+ * `ms`. Map it to an expanding ring / flash to make a discrete event (a snap, a
20
+ * correct landing) FEEL like it clicked. Returns 0 under reduced-motion.
21
+ */
22
+ declare function useImpulse(key: number | string, ms?: number): number;
23
+ //#endregion
24
+ export { PressSpringOpts, useImpulse, usePressSpring };
@@ -0,0 +1,67 @@
1
+ 'use client';
2
+
3
+ import { useFrameLoop } from "../core/clock.mjs";
4
+ import { prefersReducedMotion, spring } from "../core/motion.mjs";
5
+ import { useRef, useState } from "react";
6
+
7
+ //#region src/interaction/usePressSpring.ts
8
+ /**
9
+ * Interaction "feel" hooks, the juice layer for draggable handles. Both are thin
10
+ * wrappers over the pure `spring` / decay maths in core/motion.ts; they own a
11
+ * frame loop that runs ONLY while the value is unsettled (no idle RAF), and they
12
+ * honor prefers-reduced-motion by snapping to the end state. SSR-safe.
13
+ */
14
+ const EPS = 8e-4;
15
+ /**
16
+ * A scalar that springs toward `to` while `active`, back to `from` on release,
17
+ * e.g. a 0→1 "press" amount you map to a radius bump or halo grow. The RAF loop
18
+ * is gated on "still moving" so a page full of idle handles costs nothing.
19
+ * Under reduced-motion it returns the target immediately (no animation).
20
+ */
21
+ function usePressSpring(active, opts = {}) {
22
+ const { from = 0, to = 1, stiffness = 320, damping = 26 } = opts;
23
+ const target = active ? to : from;
24
+ const reduce = prefersReducedMotion();
25
+ const [val, setVal] = useState(from);
26
+ const valRef = useRef(from);
27
+ const vel = useRef(0);
28
+ const settled = Math.abs(valRef.current - target) < EPS && Math.abs(vel.current) < EPS;
29
+ useFrameLoop((f) => {
30
+ const next = spring(valRef.current, target, vel, f.dtMs / 1e3, {
31
+ stiffness,
32
+ damping
33
+ });
34
+ if (Math.abs(next - target) < EPS && Math.abs(vel.current) < EPS) {
35
+ valRef.current = target;
36
+ vel.current = 0;
37
+ setVal(target);
38
+ } else {
39
+ valRef.current = next;
40
+ setVal(next);
41
+ }
42
+ }, { running: !reduce && !settled });
43
+ return reduce ? target : val;
44
+ }
45
+ /**
46
+ * A one-shot impulse: jumps to 1 whenever `key` changes, then decays to 0 over
47
+ * `ms`. Map it to an expanding ring / flash to make a discrete event (a snap, a
48
+ * correct landing) FEEL like it clicked. Returns 0 under reduced-motion.
49
+ */
50
+ function useImpulse(key, ms = 260) {
51
+ const [v, setV] = useState(0);
52
+ const amp = useRef(0);
53
+ const prevKey = useRef(key);
54
+ const reduce = prefersReducedMotion();
55
+ if (prevKey.current !== key) {
56
+ prevKey.current = key;
57
+ if (!reduce) amp.current = 1;
58
+ }
59
+ useFrameLoop((f) => {
60
+ amp.current = Math.max(0, amp.current - f.dtMs / ms);
61
+ setV(amp.current);
62
+ }, { running: !reduce && amp.current > 0 });
63
+ return reduce ? 0 : v;
64
+ }
65
+
66
+ //#endregion
67
+ export { useImpulse, usePressSpring };
@@ -1,6 +1,6 @@
1
1
  //#region src/logic/ast.d.ts
2
2
  /**
3
- * Propositional-logic AST the boolean-domain sibling of the `expr` engine's
3
+ * Propositional-logic AST, the boolean-domain sibling of the `expr` engine's
4
4
  * numeric AST. A formula is variables joined by ¬ ∧ ∨ ⊕ → ↔. Pure + zero-dep;
5
5
  * `evalBool` is the single evaluator every consumer (truth tables, equivalence,
6
6
  * boolean circuits) runs.
@@ -6,7 +6,7 @@ import { cubeCovers, cubeOfSelection, cubeTerm, minimalCover, minimize, primeImp
6
6
 
7
7
  //#region src/logic/index.ts
8
8
  /**
9
- * @classytic/stage logic kernel a pure, dependency-free propositional-logic
9
+ * @classytic/stage logic kernel, a pure, dependency-free propositional-logic
10
10
  * engine, the boolean-domain sibling of the `expr` (numeric) engine. Parses
11
11
  * ¬ ∧ ∨ ⊕ → ↔ (unicode or ASCII), evaluates, builds truth tables, classifies
12
12
  * tautology/contradiction/contingency, checks equivalence, and emits DNF/CNF +
@@ -18,11 +18,16 @@ import { cubeCovers, cubeOfSelection, cubeTerm, minimalCover, minimize, primeImp
18
18
  function compileLogic(src) {
19
19
  try {
20
20
  const ast = parseLogic(src);
21
+ const vars = freeVars(ast);
21
22
  return {
22
23
  ok: true,
23
24
  ast,
24
- vars: freeVars(ast),
25
- eval: (env) => evalBool(ast, env)
25
+ vars,
26
+ eval: (env) => {
27
+ const missing = vars.filter((v) => !(v in env));
28
+ if (missing.length) throw new Error(`logic: assignment is missing variable${missing.length > 1 ? "s" : ""} ${missing.join(", ")}`);
29
+ return evalBool(ast, env);
30
+ }
26
31
  };
27
32
  } catch (e) {
28
33
  return {
@@ -17,11 +17,11 @@ interface Minimization {
17
17
  }
18
18
  /** All minterms a cube covers, within an n-variable space. */
19
19
  declare function cubeCovers(c: Cube, n: number): number[];
20
- /** The product term for a cube a literal per FIXED bit (MSB = first var). */
20
+ /** The product term for a cube, a literal per FIXED bit (MSB = first var). */
21
21
  declare function cubeTerm(c: Cube, vars: string[], neg?: string, join?: string): string;
22
22
  /** Quine–McCluskey prime implicants of a set of minterms (+ optional don't-cares). */
23
23
  declare function primeImplicants(minterms: number[], n: number, dontCares?: number[]): Cube[];
24
- /** A minimal SOP cover: essential prime implicants + a greedy fill of the rest. */
24
+ /** A minimum SOP cover: essential prime implicants + Petrick's exact cover of the rest. */
25
25
  declare function minimalCover(minterms: number[], n: number, dontCares?: number[]): Cube[];
26
26
  /** Full minimisation of a formula (or explicit minterms) → cover + SOP string. */
27
27
  declare function minimize(input: LNode | {