import { Canvas, Num, Var } from "@penrose/core"; import { Diagram } from "./diagram.js"; import { Circle, CircleProps, Ellipse, EllipseProps, Equation, EquationProps, Group, GroupProps, Image, ImageProps, Line, LineProps, Path, PathProps, Polygon, PolygonProps, Polyline, PolylineProps, Predicate, Rectangle, RectangleProps, Shape, Substance, Text, TextProps, Type } from "./types.js"; /** * A description of which substances should be selected over in a `forall` selector. * The keys are the names of the variables to assign, and the values are the types of the substances to assign to them. * * For example, selecting over all pairs of `Bird`s and single `Tree`s, assigning the birds to `b1` and `b2` and the tree to `t`, * could look like: * ```ts * { b1: Bird, b2: Bird, t: Tree } * ``` */ export type SelectorVars = Record; /** * The assigment to a selection, used as the input to closures provided to `forall`. * The keys are the same keys as declared in the provided `SelectorVars`, * and are a particular satsifying assignment of substances. */ export type SelectorAssignment = Record; /** * Options for a new input. * - `name`: The name of the input. If provided, the value can be retrieved * from each diagram using the input with `DiagramBuilder.prototype.getInput`. * - `init`: What to initialize the input to. Defaults to random sampling. * - `optimized`: Whether the input should be optimized. */ export type InputOpts = { name?: string; init?: number; optimized?: boolean; }; /** * An input that can be shared between diagrams and get/set from outside the diagram. * You should call `useSharedInput` to create a shared input, rather than * calling `new SharedInput` directly. */ export declare class SharedInput { readonly name: string; readonly init?: number; private diagrams; private effectMap; private valEffects; private currVal; private syncing; private optimized; private static nextId; constructor(init?: number, optimized?: boolean, name?: string); /** * Set the value of the input. This will update the value in all diagrams, * and trigger a re-render for the component that created the input. * @param val Value to set the input to */ set: (val: number) => void; /** * Add an effect to run when the value of the input changes. * @param fn Effect to run */ addEffect: (fn: (val: number) => void) => void; /** * Remove an effect added with `addEffect` from the input. * @param fn Effect to remove */ removeEffect: (fn: (val: number) => void) => void; /** * Get the current value of the input. */ get: () => number | null; /** * Get whether the input is optimized. */ getOptimized: () => boolean; private setValNoSyncing; private preventSyncing; private replaceEffects; register: (diagram: Diagram) => void; unregister: (diagram: Diagram) => void; } /** * Construct a diagram with a Penrose-like API. You may find it useful to * destructure an object of this type: * * ```TS * const { * type, * predicate, * circle, * line, * ensure, * // ... * } = new DiagramBuilder(canvas(400, 400), "seed"); * ``` */ export declare class DiagramBuilder { private substanceTypeMap; /** Subtype → supertype edges; same orientation as Domain's type graph. */ private typeGraph; private nextSubstanceId; private substanceIdMap; private canvas; private inputs; private varInputMap; private namedInputs; private samplingContext; private shapes; private constraints; private objectives; private variation; private nextId; private partialLayering; private pinnedInputs; private externalInputs; private lassoStrength; private interactiveOnlyShapes; /** Shape name -> event name -> listener */ private eventListeners; /** * Create a new diagram builder. * @param canvas Local dimensions of the SVG. This has no effect on the rendered size of your diagram--only the size * of the local coordinate system. * @param variation Randomness seed * @param lassoStrength Strength of the optimizers lasso term. Higher values encourage diagram continuity, * while lower values encourage reactivity. Default is 0. */ constructor(canvas: Canvas, variation?: string, lassoStrength?: number); /** * Fill all shape methods */ private defineShapeMethods; /** * Instantiate a new substance. If no type is given, this is identical to creating * and empty object. If a type `T` is given, this method is equivalent to calling `T()`. * @param type Type to instantiate */ substance: (type?: Type) => Substance; /** * Create a new substance type. The type object serves as a constructor for new * substances. Pass previously declared types as arguments to make them direct * supertypes of the new type. * * ```TS * const Vector = type(); * const Drawable = type(); * const UnitVector = type(Vector, Drawable); * * const v1 = Vector(); * const v2 = UnitVector(); * ``` * * A selector for `Vector` matches both `v1` and `v2`. Supertypes must be * created by the same `DiagramBuilder` before their subtypes. * * @param supertypes Types that the new type extends */ type: (...supertypes: Type[]) => Type; /** * Create a new predicate over substances. * * The returned predicate function can be used to declare relationships * between substances (by calling the predicate) and to query existing relation * (by calling the predicate's `.test` method): * * ```TS * const Vector = type(); * const Orthogonal = predicate(); * * const v1 = Vector(); * const v2 = Vector(); * * Orthogonal.test(v1, v2); // returns false * Orthogonal(v1, v2); * Orthogonal.test(v1, v2); // returns true * ``` */ predicate: () => Predicate; private isSubtype; private internalForallWhere; /** * Iterate over all possible assignments of substances to variables, subject to condition `where`. * This selection does NOT deduplicate assignments. * @param vars * @param where * @param func */ forallWhere: (vars: SelectorVars, where: (assigned: SelectorAssignment) => boolean, func: (assigned: SelectorAssignment, matchId: number) => void) => void; /** * Iterate over all possible assignments of substances to variables. * This selection deduplicates assignments. * @param vars * @param func */ forall: (vars: SelectorVars, func: (assigned: SelectorAssignment, matchId: number) => void) => void; /** * Create a new input. * @param info `InputOpts` for the input */ input: (info?: InputOpts) => Var; /** * Create an input from a `SharedInput`. * @param input `SharedInput` to create an input from * @param initOverride Override the initial value of the shared input */ sharedInput: (input: SharedInput, initOverride?: number) => Var; /** Create a new circle. Options: see https://penrose.cs.cmu.edu/docs/ref/style/shapes/circle */ circle: (_props?: Partial) => Readonly; /** Create a new ellipse. Options: see https://penrose.cs.cmu.edu/docs/ref/style/shapes/ellipse */ ellipse: (_props?: Partial) => Readonly; /** Create a new equation. Options: see https://penrose.cs.cmu.edu/docs/ref/style/shapes/equation */ equation: (_props?: Partial) => Readonly; /** Create a new image. Options: see https://penrose.cs.cmu.edu/docs/ref/style/shapes/image */ image: (_props?: Partial) => Readonly; /** Create a new line. Options: see https://penrose.cs.cmu.edu/docs/ref/style/shapes/line */ line: (_props?: Partial) => Readonly; /** Create a new path. Options: see https://penrose.cs.cmu.edu/docs/ref/style */ path: (_props?: Partial) => Readonly; /** Create a new polygon. Options: see https://penrose.cs.cmu.edu/docs/ref/style/shapes/polygon */ polygon: (_props?: Partial) => Readonly; /** Create a new polyline. Options: see https://penrose.cs.cmu.edu/docs/ref/style/shapes/polyline */ polyline: (_props?: Partial) => Readonly; /** Create a new rectangle. Options: see https://penrose.cs.cmu.edu/docs/ref/style/shapes/rectangle */ rectangle: (_props?: Partial) => Readonly; /** Create a new text. Options: see https://penrose.cs.cmu.edu/docs/ref/style/shapes/text */ text: (_props?: Partial) => Readonly; /** Create a new group. Options: see https://penrose.cs.cmu.edu/docs/ref/style/shapes/group * Note that, unlike in Penrose, the `clipPath` field takes either a `Shape` or `null`. */ group: (_props?: Partial) => Readonly; /** * Register a constraint with the diagram. * @param constraint A `Num` created with the `constraints` module (or, if you know what you're doing, by yourself. * You can read about creating custom constaints at https://penrose.cs.cmu.edu/docs/ref/constraints) * @param weight An optional weight to multiply the constraint by. If you find that your constraints are not * being satisfied, you may want to try increasing the weight. */ ensure: (constraint: Num, weight?: number) => void; /** * Register an objective with the diagram. * * @param objective A `Num` created with the `objectives` module (or, if you know what you're doing, by yourself. * You can read about creating custom constaints at https://penrose.cs.cmu.edu/docs/ref/constraints) * @param weight An optional weight to multiply the objective by. If you find that your objectives are not * being satisfied, you may want to try increasing the weight. */ encourage: (objective: Num, weight?: number) => void; /** * Require that one shape be above another. * @param below The bottom shape * @param above The top shape */ layer: (below: Shape, above: Shape) => void; /** * An input giving the current time since the diagram was mounted. You can use this * to create animations. However, you _must_ use the `AnimatedRenderer` component to * render the diagram, otherwise this input will not be updated. */ time: () => Var; /** * Get an input by name. * @param name Name of the input */ getInput: (name: string) => Var; /** * Build the diagram. */ build: () => Promise; /** * Create a new input, and constrain that input to a calculated value. * This is useful for reading calculated values from the diagram using `getInput`, * and for creating draggable values. * @param num Value to bind the input to * @param info `InputOpts` for the input */ bindToInput: (num: Num, info?: InputOpts) => Var; addEventListener: (shape: Shape, event: string, listener: (e: any, diagram: Diagram) => void) => void; removeEventListener: (shape: Shape, event: string, listener: (e: any, diagram: Diagram) => void) => void; setOptimized: (name: string, optimized: boolean) => void; private getOnCanvasConstraints; private getDragConstraints; private getTranslatedInputIdxsByPath; private getNameShapeMap; private makeLassoInputs; } //# sourceMappingURL=builder.d.ts.map