/* prettier-ignore-start */

/* eslint-disable */

// @ts-nocheck

// noinspection JSUnusedGlobalSymbols
declare global {
  // Generated by dts-bundle-generator v9.5.1

  import { PuzzleData as PuzzleData$1 } from 'logic-pad-solver-core';
  import { z } from 'zod';

  interface Position$1 {
    readonly x: number;
    readonly y: number;
  }
  export interface Edge {
    readonly x1: number;
    readonly y1: number;
    readonly x2: number;
    readonly y2: number;
  }
  /**
   * Major rules are frequently referenced in grids to provide additional UI.
   */
  export declare enum MajorRule {
    MusicGrid = 'music',
    CompletePattern = 'complete_pattern',
    Underclued = 'underclued',
    WrapAround = 'wrap_around',
  }
  /**
   * General puzzle types for categorization. One puzzle can have multiple types.
   */
  export declare enum PuzzleType {
    Logic = 'logic',
    Underclued = 'underclued',
    Pattern = 'pattern',
    Music = 'music',
  }
  export declare enum State {
    /**
     * Describes the violation of a rule.
     */
    Error = 'error',
    /**
     * Describes that a rule is satisfied and complete in the current grid.
     */
    Satisfied = 'satisfied',
    /**
     * Describes that a rule is not violated, but is not yet complete in the current grid.
     */
    Incomplete = 'incomplete',
    /**
     * Describes that a rule is violated but ignored due to the effect of another rule.
     */
    Ignored = 'ignored',
  }
  export declare namespace State {
    function isSatisfied(state: State): boolean;
  }
  export type RuleState =
    | {
        readonly state: State.Error;
        readonly positions: readonly Position$1[];
      }
    | {
        readonly state: State.Satisfied;
      }
    | {
        readonly state: State.Incomplete;
      }
    | {
        readonly state: State.Ignored;
      };
  export interface GridState {
    final: State;
    rules: readonly RuleState[];
    symbols: ReadonlyMap<string, State[]>;
  }
  export declare enum Color {
    Dark = 'dark',
    Light = 'light',
    Gray = 'gray',
  }
  export declare enum Comparison {
    Equal = 'eq',
    AtLeast = 'ge',
    AtMost = 'le',
  }
  export declare const COMPARISONS: readonly Comparison[];
  export declare enum Wrapping {
    None = 'none',
    Wrap = 'wrap',
    WrapReverse = 'wrap-reverse',
    ReflectReverse = 'reflect-reverse',
  }
  export declare const WRAPPINGS: readonly Wrapping[];
  export declare enum Direction {
    Up = 'up',
    Down = 'down',
    Left = 'left',
    Right = 'right',
  }
  export declare const DIRECTIONS: readonly Direction[];
  export type DirectionMap<T> = Record<Direction, T>;
  export type DirectionToggle = Readonly<DirectionMap<boolean>>;
  export declare function directionToggle(
    ...directions: readonly Direction[]
  ): {
    up: boolean;
    down: boolean;
    left: boolean;
    right: boolean;
  };
  export declare enum Orientation {
    Up = 'up',
    UpRight = 'up-right',
    Right = 'right',
    DownRight = 'down-right',
    Down = 'down',
    DownLeft = 'down-left',
    Left = 'left',
    UpLeft = 'up-left',
  }
  export declare const ORIENTATIONS: readonly Orientation[];
  export type OrientationMap<T> = Record<Orientation, T>;
  export type OrientationToggle = Readonly<OrientationMap<boolean>>;
  export declare function orientationToggle(
    ...orientations: readonly Orientation[]
  ): {
    up: boolean;
    'up-right': boolean;
    right: boolean;
    'down-right': boolean;
    down: boolean;
    'down-left': boolean;
    left: boolean;
    'up-left': boolean;
  };
  export declare enum Mode {
    Create = 'create',
    Solve = 'solve',
    Perfection = 'perfection',
  }
  export declare enum Instrument {
    Piano = 'piano',
    Drum = 'drum',
    Violin = 'violin',
    Xylophone = 'xylophone',
    GuitarAcoustic = 'guitar-acoustic',
    GuitarElectric = 'guitar-electric',
    Flute = 'flute',
    Trumpet = 'trumpet',
  }
  export declare const INSTRUMENTS: readonly Instrument[];
  export declare const DRUM_SAMPLES: readonly [
    'snare',
    'kick',
    'hihat',
    'hihat-open',
    'crash',
    'tom',
    'rim',
  ];
  export declare function isDrumSample(note: string): boolean;
  export declare class GridZones {
    readonly edges: readonly Edge[];
    constructor(edges?: readonly Edge[]);
    addEdge(edge: Edge): GridZones;
    removeEdge(edge: Edge): GridZones;
    hasEdge(edge: Edge): boolean;
    getEdgesAt({ x, y }: Position$1): readonly Edge[];
    /**
     * Check if two GridZones objects are equal.
     * @param other The other GridZones object to compare to.
     * @returns Whether the two objects are equal.
     */
    equals(other: GridZones): boolean;
    /**
     * Deduplicate an array of edges.
     * @param edges The array of edges to deduplicate.
     * @returns The deduplicated array of edges.
     */
    static deduplicateEdges(edges: readonly Edge[]): readonly Edge[];
    static validateEdges(
      connections: GridZones,
      width: number,
      height: number
    ): GridZones;
    insertColumn(index: number): GridZones;
    insertRow(index: number): GridZones;
    removeColumn(index: number): GridZones;
    removeRow(index: number): GridZones;
  }
  export declare class TileConnections {
    [y: number]: {
      [x: number]: boolean;
    };
    constructor();
    get topLeft(): boolean;
    set topLeft(value: boolean);
    get top(): boolean;
    set top(value: boolean);
    get topRight(): boolean;
    set topRight(value: boolean);
    get left(): boolean;
    set left(value: boolean);
    get center(): boolean;
    set center(value: boolean);
    get right(): boolean;
    set right(value: boolean);
    get bottomLeft(): boolean;
    set bottomLeft(value: boolean);
    get bottom(): boolean;
    set bottom(value: boolean);
    get bottomRight(): boolean;
    set bottomRight(value: boolean);
    equals(other: TileConnections): boolean;
  }
  export declare class GridConnections extends GridZones {
    constructor(edges?: readonly Edge[]);
    addEdge(edge: Edge): GridConnections;
    removeEdge(edge: Edge): GridConnections;
    getForTile({ x, y }: Position$1): TileConnections;
    getConnectedTiles({ x, y }: Position$1): readonly Position$1[];
    /**
     * Create new GridConnections from a string array.
     *
     * - Use `.` for cells that don't connect to anything.
     * - Use any other character for cells that connect to the same character.
     *
     * @param array - The string array to create the connections from.
     * @returns The created connections. You can apply this to a GridData object using GridData.withConnections.
     */
    static create(array: string[]): GridConnections;
    static validateEdges(
      connections: GridConnections,
      width: number,
      height: number
    ): GridConnections;
    insertColumn(index: number): GridConnections;
    insertRow(index: number): GridConnections;
    removeColumn(index: number): GridConnections;
    removeRow(index: number): GridConnections;
  }
  /**
   * Offset the given position by a given step in the given direction.
   * @param position The position to offset.
   * @param direction The direction to offset in.
   * @param step The distance to offset by.
   * @returns The offset position.
   */
  export declare function move(
    position: Position$1,
    direction: Direction | Orientation,
    step?: number
  ): {
    x: number;
    y: number;
  };
  /**
   * Check if two edges are the same, regardless of direction.
   * @param a The first edge.
   * @param b The second edge.
   * @returns Whether the edges are the same.
   */
  export declare function isSameEdge(a: Edge, b: Edge): boolean;
  /**
   * Convert the given direction to a rotation in degrees.
   * @param direction The direction to convert.
   * @returns The rotation in degrees.
   */
  export declare function directionToRotation(
    direction: Direction
  ): 0 | 270 | 90 | 180;
  /**
   * Convert the given orientation to a rotation in degrees.
   * @param orientation The orientation to convert.
   * @returns The rotation in degrees.
   */
  export declare function orientationToRotation(
    orientation: Orientation
  ): 0 | 270 | 90 | 180 | 225 | 125 | 315 | 45;
  /**
   * Create a new 2D array with the given dimensions and values.
   * @param width The width of the array.
   * @param height The height of the array.
   * @param value A function that returns the value for each x,y coordinate.
   * @returns The 2D array.
   */
  export declare function array<T>(
    width: number,
    height: number,
    value: (x: number, y: number) => T
  ): T[][];
  /**
   * Resize the given array to the new size, cutting off or padding with the default value.
   * @param array The array to resize.
   * @param newSize The new size of the array.
   * @param defaultValue A function that returns the default value for each new element.
   * @returns The resized array.
   */
  export declare function resize<T>(
    array: T[],
    newSize: number,
    defaultValue: () => T
  ): T[];
  export declare function resize<T>(
    array: readonly T[],
    newSize: number,
    defaultValue: () => T
  ): readonly T[];
  /**
   * Check if all the given values are equal.
   * @param values The values to compare.
   * @returns Whether all the values are equal.
   */
  export declare function allEqual<T>(...values: T[]): boolean;
  /**
   * Return the first element of the array which has the minimum mapped value.
   *
   * @param values The array of values.
   * @param mapper The function to map each value to a number.
   * @returns The first element with the minimum mapped value.
   */
  export declare function minBy<T>(
    values: readonly T[],
    mapper: (element: T) => number
  ): T | undefined;
  /**
   * Return the first element of the array which has the maximum mapped value.
   *
   * @param values The array of values.
   * @param mapper The function to map each value to a number.
   * @returns The first element with the maximum mapped value.
   */
  export declare function maxBy<T>(
    values: readonly T[],
    mapper: (element: T) => number
  ): T | undefined;
  /**
   * Escape the given text by replacing the specified characters with HTML escape sequences.
   * @param text The text to escape.
   * @param escapeCharacters The characters to escape.
   * @returns The escaped text.
   */
  declare function escape$1(text: string, escapeCharacters?: string): string;
  /**
   * Unescape the given text by replacing HTML escape sequences with the corresponding characters.
   * @param text The text to unescape.
   * @param escapeCharacters The characters to unescape. This should match the characters escaped by the `escape` function.
   * @returns The unescaped text.
   */
  declare function unescape$1(text: string, escapeCharacters?: string): string;
  export declare class CachedAccess<T> {
    private readonly getter;
    private static readonly UNCACHED;
    private cache;
    private constructor();
    static of<T>(getter: () => T): CachedAccess<T>;
    get value(): T;
  }
  export declare abstract class Configurable {
    abstract get title(): string;
    abstract get configExplanation(): string;
    get configs(): readonly AnyConfig[] | null;
    abstract copyWith(props: Record<string, unknown>): this;
    /**
     * Check if this instruction is equal to another instruction by comparing their IDs and configs.
     *
     * @param other The other instruction to compare to.
     * @returns Whether the two instructions are equal.
     */
    equals(other: Configurable): boolean;
  }
  export declare abstract class Instruction extends Configurable {
    abstract get id(): string;
    abstract get explanation(): string;
    get configExplanation(): string;
    abstract createExampleGrid(): GridData;
    /**
     * Indicates that validation by logic is not available and the solution must be used for validation
     */
    get validateWithSolution(): boolean;
    get necessaryForCompletion(): boolean;
    get visibleWhenSolving(): boolean;
    /**
     * Return a variant of this instruction that is suitable for the given mode.
     */
    abstract modeVariant(mode: Mode): Instruction | null;
    /**
     * Check if this instruction is equal to another instruction by comparing their IDs and configs.
     *
     * @param other The other instruction to compare to.
     * @returns Whether the two instructions are equal.
     */
    equals(other: Instruction): boolean;
  }
  export interface SearchVariant {
    description: string;
    rule: Rule;
  }
  export declare abstract class Rule extends Instruction {
    abstract validateGrid(grid: GridData): RuleState;
    abstract get searchVariants(): SearchVariant[];
    searchVariant(): SearchVariant;
    modeVariant(_mode: Mode): Rule | null;
    /**
     * Whether only one instance of this rule is allowed in a grid.
     */
    get isSingleton(): boolean;
  }
  export interface GridResizeHandler {
    /**
     * Update itself when the grid is resized.
     */
    onGridResize(
      grid: GridData,
      mode: 'insert' | 'remove',
      direction: 'row' | 'column',
      index: number
    ): this | null;
  }
  export declare function handlesGridResize<T extends Instruction>(
    val: T
  ): val is T & GridResizeHandler;
  declare abstract class Symbol$1
    extends Instruction
    implements GridResizeHandler
  {
    readonly x: number;
    readonly y: number;
    constructor(x: number, y: number);
    abstract validateSymbol(grid: GridData, solution: GridData | null): State;
    modeVariant(_mode: Mode): Symbol$1 | null;
    onGridResize(
      _grid: GridData,
      mode: 'insert' | 'remove',
      direction: 'row' | 'column',
      index: number
    ): this | null;
    /**
     * The step size for the x and y coordinates of the symbol.
     */
    get placementStep(): number;
    /**
     * The order in which symbols are displayed on the instruction list. Lower values are displayed first.
     */
    get sortOrder(): number;
    withX(x: number): this;
    withY(y: number): this;
    withPosition(x: number, y: number): this;
    /**
     * For symbols that can be placed between tiles, this method implements the default validation logic,
     * which requires all tiles touching the symbol to be either gray or of the same color.
     */
    protected validateSubtilePlacement(grid: GridData): boolean;
  }
  export declare class TileData {
    readonly exists: boolean;
    readonly fixed: boolean;
    readonly color: Color;
    constructor(exists: boolean, fixed: boolean, color: Color);
    /**
     * Create a gray tile.
     */
    static empty(): TileData;
    /**
     * Create a non-existent tile.
     */
    static doesNotExist(): TileData;
    copyWith({
      exists,
      fixed,
      color,
    }: {
      exists?: boolean;
      fixed?: boolean;
      color?: Color;
    }): this;
    withExists(exists: boolean): this;
    withFixed(fixed: boolean): this;
    withColor(color: Color): this;
    get isFixed(): boolean;
    equals(other: TileData): boolean;
    static create(char: string): TileData;
  }
  export interface GridChangeHandler {
    onGridChange(newGrid: GridData): this;
  }
  export declare function handlesGridChange<T extends Instruction>(
    val: T
  ): val is T & GridChangeHandler;
  export interface SetGridHandler {
    onSetGrid(
      oldGrid: GridData,
      newGrid: GridData,
      solution: GridData | null
    ): GridData;
  }
  export declare function handlesSetGrid<T extends Instruction>(
    val: T
  ): val is T & SetGridHandler;
  export declare function invokeSetGrid(
    oldGrid: GridData,
    newGrid: GridData,
    solution: GridData | null
  ): GridData;
  export declare class Row extends Configurable {
    /**
     * The note to play at this row, or null to keep the current note from the previous control line.
     * If this is null from the first control line, the note will be silent.
     */
    readonly note: string | null;
    /**
     * The instrument to play the note with, or null to keep the current instrument from the previous control line.
     * If this is null from the first control line, the instrument will be "piano".
     * This has no effect if the current note is a drum sample.
     */
    readonly instrument: Instrument | null;
    /**
     * The velocity to play the note at, or null to keep the current velocity from the previous control line.
     * Ranges from 0 to 1
     */
    readonly velocity: number | null;
    readonly title = 'Music Grid - Row';
    readonly configExplanation =
      'Configure the playback settings from this tile onwards.';
    private static readonly CONFIGS;
    constructor(
      /**
       * The note to play at this row, or null to keep the current note from the previous control line.
       * If this is null from the first control line, the note will be silent.
       */
      note: string | null,
      /**
       * The instrument to play the note with, or null to keep the current instrument from the previous control line.
       * If this is null from the first control line, the instrument will be "piano".
       * This has no effect if the current note is a drum sample.
       */
      instrument: Instrument | null,
      /**
       * The velocity to play the note at, or null to keep the current velocity from the previous control line.
       * Ranges from 0 to 1
       */
      velocity: number | null
    );
    get configs(): readonly AnyConfig[] | null;
    copyWith({
      note,
      instrument,
      velocity,
    }: {
      note?: string | null;
      instrument?: Instrument | null;
      velocity?: number | null;
    }): this;
  }
  export declare class ControlLine extends Configurable {
    readonly column: number;
    readonly bpm: number | null;
    readonly pedal: boolean | null;
    readonly checkpoint: boolean;
    readonly rows: readonly Row[];
    readonly title = 'Music Grid - Control Line';
    readonly configExplanation =
      'Configure the playback settings from this point onwards.';
    private static readonly CONFIGS;
    /**
     * Configure playback settings, taking effect at the given column (inclusive)
     * @param column The column at which the settings take effect
     * @param bpm The new beats per minute, or null to keep the current value from the previous control line
     * @param pedal Whether the pedal is pressed, or null to keep the current value from the previous control line
     * @param checkpoint Whether this control line is a checkpoint
     * @param rows The notes to play at each row. This list is automatically resized to match the height of the grid. You may pass in an empty list if none of the rows need to be changed.
     */
    constructor(
      column: number,
      bpm: number | null,
      pedal: boolean | null,
      checkpoint: boolean,
      rows: readonly Row[]
    );
    get configs(): readonly AnyConfig[] | null;
    copyWith({
      column,
      bpm,
      pedal,
      checkpoint,
      rows,
    }: {
      column?: number;
      bpm?: number | null;
      pedal?: boolean | null;
      checkpoint?: boolean;
      rows?: readonly Row[];
    }): this;
    withColumn(column: number): this;
    withBpm(bpm: number | null): this;
    withPedal(pedal: boolean | null): this;
    withCheckpoint(checkpoint: boolean): this;
    withRows(rows: readonly Row[]): this;
    equals(other: ControlLine): boolean;
    get isEmpty(): boolean;
  }
  export declare class MusicGridRule
    extends Rule
    implements GridChangeHandler, SetGridHandler, GridResizeHandler
  {
    readonly controlLines: readonly ControlLine[];
    readonly track: GridData | null;
    readonly normalizeVelocity: boolean;
    readonly title = 'Music Grid';
    get configExplanation(): string;
    private static readonly EXAMPLE_GRID;
    private static readonly CONFIGS;
    private static readonly SEARCH_VARIANTS;
    /**
     * **Music Grid: Listen to the solution**
     * @param controlLines Denote changes in the playback settings. At least one control line at column 0 should be present to enable playback.
     * @param track The grid to be played when "listen" is clicked. Set as null to play the solution.
     * @param normalizeVelocity Whether to normalize the velocity of the notes by their pitch such that lower notes are played softer.
     */
    constructor(
      controlLines: readonly ControlLine[],
      track: GridData | null,
      normalizeVelocity?: boolean
    );
    get id(): string;
    get explanation(): string;
    get configs(): readonly AnyConfig[] | null;
    createExampleGrid(): GridData;
    get searchVariants(): SearchVariant[];
    validateGrid(_grid: GridData): RuleState;
    onSetGrid(
      _oldGrid: GridData,
      newGrid: GridData,
      _solution: GridData | null
    ): GridData;
    onGridChange(newGrid: GridData): this;
    onGridResize(
      _grid: GridData,
      mode: 'insert' | 'remove',
      direction: 'row' | 'column',
      index: number
    ): this | null;
    /**
     * Add or replace a control line.
     * @param controlLine The control line to set.
     * @returns A new rule with the control line set.
     */
    setControlLine(controlLine: ControlLine): this;
    withTrack(track: GridData | null): this;
    copyWith({
      controlLines,
      track,
      normalizeVelocity,
    }: {
      controlLines?: readonly ControlLine[];
      track?: GridData | null;
      normalizeVelocity?: boolean;
    }): this;
    get validateWithSolution(): boolean;
    get isSingleton(): boolean;
    static mergeControlLines(...lines: ControlLine[]): ControlLine;
    static deduplicateControlLines(
      lines: readonly ControlLine[]
    ): ControlLine[];
  }
  export declare class CompletePatternRule extends Rule {
    readonly title = 'Complete The Pattern';
    get configExplanation(): string;
    private static readonly EXAMPLE_GRID;
    private static readonly SEARCH_VARIANTS;
    /**
     * **Complete the pattern**
     *
     * This rule validates answers based on the provided solution.
     */
    constructor();
    get id(): string;
    get explanation(): string;
    createExampleGrid(): GridData;
    get searchVariants(): SearchVariant[];
    validateGrid(_grid: GridData): RuleState;
    copyWith(_: object): this;
    get validateWithSolution(): boolean;
    get isSingleton(): boolean;
  }
  export declare class UndercluedRule extends Rule {
    readonly title = 'Underclued';
    get configExplanation(): string;
    private static readonly EXAMPLE_GRID;
    private static readonly SEARCH_VARIANTS;
    /**
     * **Underclued Grid: Mark only what is definitely true**
     *
     * This rule validates answers based on the provided solution.
     */
    constructor();
    get id(): string;
    get explanation(): string;
    createExampleGrid(): GridData;
    get searchVariants(): SearchVariant[];
    validateGrid(_grid: GridData): RuleState;
    copyWith(_: object): this;
    get validateWithSolution(): boolean;
    get isSingleton(): boolean;
  }
  export interface GetTileHandler {
    onGetTile(x: number, y: number, grid: GridData): Position$1;
  }
  export declare function handlesGetTile<T extends Instruction>(
    val: T
  ): val is T & GetTileHandler;
  export declare class WrapAroundRule extends Rule implements GetTileHandler {
    readonly horizontal: Wrapping;
    readonly vertical: Wrapping;
    readonly title = 'Wrap Around';
    get configExplanation(): string;
    private static readonly EXAMPLE_GRID_NONE;
    private static readonly EXAMPLE_GRID_HORIZONTAL;
    private static readonly EXAMPLE_GRID_VERTICAL;
    private static readonly SEARCH_VARIANTS;
    private static readonly CONFIGS;
    /**
     * **The left and right edges are connected (in reverse)**
     *
     * @param horizontal - The horizontal wrapping.
     * @param vertical - The vertical wrapping.
     */
    constructor(horizontal: Wrapping, vertical: Wrapping);
    onGetTile(x: number, y: number, grid: GridData): Position$1;
    get id(): string;
    get explanation(): string;
    createExampleGrid(): GridData;
    get configs(): readonly AnyConfig[] | null;
    get searchVariants(): SearchVariant[];
    validateGrid(grid: GridData): RuleState;
    copyWith({
      horizontal,
      vertical,
    }: {
      horizontal?: Wrapping;
      vertical?: Wrapping;
    }): this;
    get isSingleton(): boolean;
  }
  export declare const NEIGHBOR_OFFSETS: Position$1[];
  export declare const NEIGHBOR_OFFSETS_8: Position$1[];
  export declare class GridData {
    readonly width: number;
    readonly height: number;
    readonly tiles: readonly (readonly TileData[])[];
    readonly connections: GridConnections;
    readonly zones: GridZones;
    readonly symbols: ReadonlyMap<string, readonly Symbol$1[]>;
    readonly rules: readonly Rule[];
    readonly musicGrid: CachedAccess<MusicGridRule | undefined>;
    readonly completePattern: CachedAccess<CompletePatternRule | undefined>;
    readonly underclued: CachedAccess<UndercluedRule | undefined>;
    readonly wrapAround: CachedAccess<WrapAroundRule | undefined>;
    /**
     * Create a new grid with tiles, connections, symbols and rules.
     *
     * @param width The width of the grid.
     * @param height The height of the grid.
     * @param tiles The tiles of the grid.
     * @param connections The connections of the grid, which determines which tiles are merged.
     * @param zones The zones of the grid.
     * @param symbols The symbols in the grid.
     * @param rules The rules of the grid.
     */
    constructor(
      width: number,
      height: number,
      tiles?: readonly (readonly TileData[])[],
      connections?: GridConnections,
      zones?: GridZones,
      symbols?: ReadonlyMap<string, readonly Symbol$1[]>,
      rules?: readonly Rule[]
    );
    /**
     * Create a new GridData object from a string array.
     *
     * - Use `b` for dark cells, `w` for light cells, and `n` for gray cells.
     * - Capitalize the letter to make the tile fixed.
     * - Use `.` to represent empty space.
     *
     * @param array - The string array to create the grid from.
     * @returns The created grid.
     */
    static create(array: string[]): GridData;
    /**
     * Create a new grid with tiles, connections, symbols and rules. Sanitize the provided list of symbols and rules,
     * and trigger grid change events.
     *
     * @param width The width of the grid.
     * @param height The height of the grid.
     * @param tiles The tiles of the grid.
     * @param connections The connections of the grid, which determines which tiles are merged.
     * @param zones The zones of the grid.
     * @param symbols The symbols in the grid.
     * @param rules The rules of the grid.
     */
    static create(
      width: number,
      height: number,
      tiles?: readonly (readonly TileData[])[],
      connections?: GridConnections,
      zones?: GridZones,
      symbols?: ReadonlyMap<string, readonly Symbol$1[]>,
      rules?: readonly Rule[],
      sanitize?: boolean,
      triggerEvents?: boolean
    ): GridData;
    /**
     * Copy the current grid while modifying the provided properties.
     * @param param0 The properties to modify.
     * @returns The new grid with the modified properties.
     */
    copyWith(
      {
        width,
        height,
        tiles,
        connections,
        zones,
        symbols,
        rules,
      }: {
        width?: number;
        height?: number;
        tiles?: readonly (readonly TileData[])[];
        connections?: GridConnections;
        zones?: GridZones;
        symbols?: ReadonlyMap<string, readonly Symbol$1[]>;
        rules?: readonly Rule[];
      },
      sanitize?: boolean,
      triggerEvents?: boolean
    ): GridData;
    toArrayCoordinates(x: number, y: number): Position$1;
    isPositionValid(x: number, y: number): boolean;
    /**
     * Safely get the tile at the given position.
     * @param x The x-coordinate of the tile.
     * @param y The y-coordinate of the tile.
     * @returns The tile at the given position, or a non-existent tile if the position is invalid.
     */
    getTile(x: number, y: number): TileData;
    /**
     * Safely set the tile at the given position.
     * If the position is invalid, the tile array is returned unchanged.
     * If the tile is merged with other tiles, the colors of all connected tiles are changed.
     *
     * @param x The x-coordinate of the tile.
     * @param y The y-coordinate of the tile.
     * @param tile The new tile to set.
     * @returns The new tile array with updated tiles.
     */
    setTile(
      x: number,
      y: number,
      tile: TileData | ((tile: TileData) => TileData)
    ): readonly (readonly TileData[])[];
    /**
     * Replace or modify all tiles in the grid.
     *
     * @param tiles The new tile array or a function to mutate the existing tile array.
     * @returns The new grid with the new tiles.
     */
    withTiles(
      tiles:
        | readonly (readonly TileData[])[]
        | ((value: TileData[][]) => readonly (readonly TileData[])[])
    ): GridData;
    /**
     * Add or modify the connections in the grid.
     * @param connections The new connections to add or modify.
     * @returns The new grid with the new connections.
     */
    withConnections(
      connections:
        | GridConnections
        | ((value: GridConnections) => GridConnections)
    ): GridData;
    /**
     * Add or modify the zones in the grid.
     * @param zones The new zones to add or modify.
     * @returns The new grid with the new zones.
     */
    withZones(zones: GridZones | ((value: GridZones) => GridZones)): GridData;
    /**
     * Add or modify the symbols in the grid.
     * @param symbols The new symbols to add or modify.
     * @returns The new grid with the new symbols.
     */
    withSymbols(
      symbols:
        | readonly Symbol$1[]
        | ReadonlyMap<string, readonly Symbol$1[]>
        | ((
            value: Map<string, readonly Symbol$1[]>
          ) => ReadonlyMap<string, readonly Symbol$1[]>)
    ): GridData;
    /**
     * Add a new symbol to the grid.
     * @param symbol The symbol to add.
     * @returns The new grid with the new symbol.
     */
    addSymbol(symbol: Symbol$1): GridData;
    /**
     * Remove an instance of the symbol from the grid.
     * @param symbol The symbol to remove.
     * @returns The new grid with the symbol removed.
     */
    removeSymbol(symbol: Symbol$1): GridData;
    /**
     * Remove all symbols that satisfy the predicate.
     * @param predicate The predicate to test each symbol with.
     * @returns The new grid with the symbols removed.
     */
    removeSymbolIf(predicate: (symbol: Symbol$1) => boolean): GridData;
    /**
     * Find the first symbol that satisfies the predicate.
     * @param predicate The predicate to test each symbol with.
     * @returns The first symbol that satisfies the predicate, or undefined if no symbol is found.
     */
    findSymbol(predicate: (symbol: Symbol$1) => boolean): Symbol$1 | undefined;
    /**
     * Replace an existing symbol with a new symbol.
     * @param oldSymbol The symbol to replace.
     * @param newSymbol The new symbol to replace with.
     * @returns The new grid with the symbol replaced.
     */
    replaceSymbol(oldSymbol: Symbol$1, newSymbol: Symbol$1): GridData;
    /**
     * Add or modify the rules in the grid.
     * @param rules The new rules to add or modify.
     * @returns The new grid with the new rules.
     */
    withRules(
      rules: readonly Rule[] | ((value: readonly Rule[]) => readonly Rule[])
    ): GridData;
    /**
     * Add a new rule to the grid.
     * @param rule The rule to add.
     * @returns The new grid with the new rule.
     */
    addRule(rule: Rule): GridData;
    /**
     * Remove an instance of the rule from the grid.
     * @param rule The rule to remove.
     * @returns The new grid with the rule removed.
     */
    removeRule(rule: Rule): GridData;
    /**
     * Remove all rules that satisfy the predicate.
     * @param predicate The predicate to test each rule with.
     * @returns The new grid with the rules removed.
     */
    removeRuleIf(predicate: (rule: Rule) => boolean): GridData;
    /**
     * Find the first rule that satisfies the predicate.
     * @param predicate The predicate to test each rule with.
     * @returns The first rule that satisfies the predicate, or undefined if no rule is found.
     */
    findRule(predicate: (rule: Rule) => boolean): Rule | undefined;
    /**
     * Replace an existing rule with a new rule.
     * @param oldRule The rule to replace.
     * @param newRule The new rule to replace with.
     * @returns The new grid with the rule replaced.
     */
    replaceRule(oldRule: Rule, newRule: Rule): GridData;
    /**
     * Insert a new column at the given index, shifting all components of the grid accordingly. Newly inserted tiles are gray.
     * @param index The index to insert the column at.
     * @returns The new grid with the new column inserted.
     */
    insertColumn(index: number): GridData;
    /**
     * Insert a new row at the given index, shifting all components of the grid accordingly. Newly inserted tiles are gray.
     * @param index The index to insert the row at.
     * @returns The new grid with the new row inserted.
     */
    insertRow(index: number): GridData;
    /**
     * Remove a column at the given index, shifting all components of the grid accordingly.
     * @param index The index to remove the column at.
     * @returns The new grid with the column removed.
     */
    removeColumn(index: number): GridData;
    /**
     * Remove a row at the given index, shifting all components of the grid accordingly.
     * @param index The index to remove the row at.
     * @returns The new grid with the row removed.
     */
    removeRow(index: number): GridData;
    /**
     * Resize the grid to the new width and height, shifting all components of the grid accordingly. Newly inserted tiles are gray.
     * @param width The new width of the grid.
     * @param height The new height of the grid.
     * @returns The new grid with the new dimensions.
     */
    resize(width: number, height: number): this;
    /**
     * Create a new mutable TileData array from a string array.
     *
     * - Use `b` for dark cells, `w` for light cells, and `n` for gray cells.
     * - Capitalize the letter to make the tile fixed.
     * - Use `.` to represent empty space.
     *
     * @param array - The string array to create the tiles from.
     * @returns The created tile array.
     */
    static createTiles(array: string[]): TileData[][];
    /**
     * Find a tile in the grid that satisfies the predicate.
     *
     * @param predicate The predicate to test each tile with.
     * @returns The position of the first tile that satisfies the predicate, or undefined if no tile is found.
     */
    find(
      predicate: (tile: TileData, x: number, y: number) => boolean
    ): Position$1 | undefined;
    /**
     * Iterate over all tiles in the same region as the given position that satisfy the predicate.
     * The iteration stops when the callback returns a value that is not undefined.
     * Non-existent tiles are not included in the iteration.
     *
     * @param position The position to start the iteration from. This position is included in the iteration.
     * @param predicate The predicate to test each tile with. The callback is only called for tiles that satisfy this predicate.
     * @param callback The callback to call for each tile that satisfies the predicate. The iteration stops when this callback returns a value that is not undefined.
     * @param visited A 2D array to keep track of visited tiles. This array is modified by the function.
     * @returns The value returned by the callback that stopped the iteration, or undefined if the iteration completed.
     */
    iterateArea<T>(
      position: Position$1,
      predicate: (
        tile: TileData,
        logicalX: number,
        logicalY: number
      ) => boolean,
      callback: (
        tile: TileData,
        x: number,
        y: number,
        logicalX: number,
        logicalY: number
      ) => undefined | T,
      visited?: boolean[][]
    ): T | undefined;
    /**
     * Iterate over all tiles in a straight line from the given position in the given direction that satisfy the predicate.
     * The iteration stops when the callback returns a value that is not undefined.
     * Non-existent tiles break the iteration.
     *
     * @param position The position to start the iteration from. This position is included in the iteration.
     * @param direction The direction to iterate in.
     * @param predicate The predicate to test each tile with. The callback is only called for tiles that satisfy this predicate.
     * @param callback The callback to call for each tile that satisfies the predicate. The iteration stops when this callback returns a value that is not undefined.
     * @param visited A 2D array to keep track of visited tiles. This array is modified by the function.
     * @returns The value returned by the callback that stopped the iteration, or undefined if the iteration completed.
     */
    iterateDirection<T>(
      position: Position$1,
      direction: Direction | Orientation,
      predicate: (
        tile: TileData,
        logicalX: number,
        logicalY: number
      ) => boolean,
      callback: (
        tile: TileData,
        x: number,
        y: number,
        logicalX: number,
        logicalY: number
      ) => T | undefined,
      visited?: boolean[][]
    ): T | undefined;
    /**
     * Iterate over all tiles in a straight line from the given position in the given direction that satisfy the predicate.
     * The iteration stops when the callback returns a value that is not undefined.
     * Non-existent tiles are included in the iteration.
     *
     * @param position The position to start the iteration from. This position is included in the iteration.
     * @param direction The direction to iterate in.
     * @param predicate The predicate to test each tile with. The callback is only called for tiles that satisfy this predicate.
     * @param callback The callback to call for each tile that satisfies the predicate. The iteration stops when this callback returns a value that is not undefined.
     * @param visited A 2D array to keep track of visited tiles. This array is modified by the function.
     * @returns The value returned by the callback that stopped the iteration, or undefined if the iteration completed.
     */
    iterateDirectionAll<T>(
      position: Position$1,
      direction: Direction | Orientation,
      predicate: (
        tile: TileData,
        logicalX: number,
        logicalY: number
      ) => boolean,
      callback: (
        tile: TileData,
        x: number,
        y: number,
        logicalX: number,
        logicalY: number
      ) => T | undefined,
      visited?: boolean[][]
    ): T | undefined;
    /**
     * Reduce the grid by zones defined in the GridZones.
     *
     * @param reducer The reducer function to apply to each zone.
     * @param initializer The initializer function to create the initial value for each zone.
     * @param visited A 2D array to keep track of visited tiles. This array is modified by the function.
     * @returns An array of reduced values, one for each zone.
     */
    reduceByZone<T>(
      reducer: (
        acc: T,
        tile: TileData,
        x: number,
        y: number,
        logicalX: number,
        logicalY: number
      ) => T,
      initializer: () => T,
      visited?: boolean[][]
    ): T[];
    /**
     * Check if every tile in the grid is filled with a color other than gray.
     *
     * @returns True if every tile is filled with a color other than gray, false otherwise.
     */
    isComplete(): boolean;
    /**
     * Iterate over all tiles in the grid.
     * The iteration stops when the callback returns a value that is not undefined.
     *
     * @param callback The callback to call for each tile.
     * @returns The value returned by the callback that stopped the iteration, or undefined if the iteration completed.
     */
    forEach<T>(
      callback: (tile: TileData, x: number, y: number) => T | undefined
    ): T | undefined;
    /**
     * Flood fill a continuous region starting from the given position with the given color.
     *
     * @param position The position to start the flood fill from.
     * @param from The color of the tiles to fill.
     * @param to The color to fill the tiles with.
     * @param allowFixed Whether to fill fixed tiles.
     * @returns The new grid with the region filled with the new color.
     */
    floodFill(
      position: Position$1,
      from: Color,
      to: Color,
      allowFixed: boolean
    ): GridData;
    /**
     * Flood fill all tiles with the given color to a new color, even if they are not connected.
     *
     * @param from The color of the tiles to fill.
     * @param to The color to fill the tiles with.
     * @param allowFixed Whether to fill fixed tiles.
     * @returns The new grid with all tiles filled with the new color.
     */
    floodFillAll(from: Color, to: Color, allowFixed: boolean): GridData;
    /**
     * Check if the grid has any instructions that require a custom solution.
     * @returns True if the grid has any instructions that require a custom solution, false otherwise.
     */
    requireSolution(): boolean;
    /**
     * Reset all non-fixed tiles to gray.
     *
     * @returns The new grid with all non-fixed tiles reset to gray.
     */
    resetTiles(): this;
    /**
     * Copy the tiles in the given region to a new grid.
     * All connections and symbols within the selected region are copied.
     * All rules are included as well.
     *
     * @param origin The top-left corner of the region to copy.
     * @param width The width of the region to copy.
     * @param height The height of the region to copy.
     * @returns The new grid with the copied tiles.
     */
    copyTiles(origin: Position$1, width: number, height: number): GridData;
    /**
     * Paste the tiles from the given grid to the current grid at the given position.
     * All connections, symbols, and rules are merged.
     *
     * @param origin The top-left corner of the region to paste the tiles to.
     * @param grid The grid to paste the tiles from.
     * @returns The new grid with the pasted tiles.
     */
    pasteTiles(origin: Position$1, grid: GridData): GridData;
    /**
     * Paste the tiles from the given array to the current grid at the given position.
     *
     * @param origin The top-left corner of the region to paste the tiles to.
     * @param tile The array of tiles to paste.
     * @returns The new grid with the pasted tiles.
     */
    pasteTiles(
      origin: Position$1,
      tile: readonly (readonly TileData[])[]
    ): GridData;
    /**
     * Check if this grid is equal to another grid in terms of size and tile colors.
     * Rules, symbols, and connections are not compared.
     *
     * @param grid The grid to compare with.
     * @returns True if the grids are equal in size and tile colors, false otherwise.
     */
    colorEquals(grid: GridData): boolean;
    /**
     * Check if this grid is equal to another grid in terms of size, tile colors, connections, symbols, and rules.
     *
     * @param other The grid to compare with.
     * @returns True if the grids are equal, false otherwise.
     */
    equals(other: GridData): boolean;
    /**
     * Get the count of tiles that satisfy the given conditions.
     * @param exists Whether the tile exists or not.
     * @param fixed Whether the tile is fixed or not. If undefined, the fixed state is ignored.
     * @param color The color of the tile. If undefined, all colors are included.
     * @returns The count of tiles that satisfy the given conditions.
     */
    getTileCount(exists: boolean, fixed?: boolean, color?: Color): number;
    /**
     * Get the count of tiles that satisfy the given conditions for each color.
     * @param color The color of the tiles.
     * @returns The count of tiles that satisfy the given conditions for each color.
     */
    getColorCount(color: Color): {
      min: number;
      max: number;
    };
    /**
     * Deduplicate the rules in the given list.
     *
     * @param rules The list of rules to deduplicate.
     * @returns The deduplicated list of rules.
     */
    static deduplicateRules(rules: readonly Rule[]): Rule[];
    /**
     * Deduplicate the singleton rules in the given list.
     *
     * @param rules The list of rules to deduplicate.
     * @returns The deduplicated list of rules.
     */
    static deduplicateSingletonRules(rules: readonly Rule[]): Rule[];
    /**
     * Deduplicate the symbols in the given map.
     *
     * @param symbols The map of symbols to deduplicate.
     * @returns The deduplicated map of symbols.
     */
    static deduplicateSymbols(
      symbols: ReadonlyMap<string, readonly Symbol$1[]>
    ): Map<string, Symbol$1[]>;
  }
  export declare enum ConfigType {
    Boolean = 'boolean',
    NullableBoolean = 'nullableBoolean',
    Number = 'number',
    NullableNumber = 'nullableNumber',
    String = 'string',
    Color = 'color',
    Comparison = 'comparison',
    Wrapping = 'wrapping',
    Direction = 'direction',
    DirectionToggle = 'directionToggle',
    Orientation = 'orientation',
    OrientationToggle = 'orientationToggle',
    Tile = 'tile',
    Shape = 'shape',
    Grid = 'grid',
    NullableGrid = 'nullableGrid',
    Icon = 'icon',
    ControlLines = 'controlLines',
    NullableNote = 'nullableNote',
    NullableInstrument = 'nullableInstrument',
    SolvePath = 'solvePath',
  }
  export interface Config<T> {
    readonly type: ConfigType;
    readonly field: string;
    readonly description: string;
    readonly explanation?: string;
    readonly default: T;
    readonly configurable: boolean;
  }
  export interface BooleanConfig extends Config<boolean> {
    readonly type: ConfigType.Boolean;
  }
  export interface NullableBooleanConfig extends Config<boolean | null> {
    readonly type: ConfigType.NullableBoolean;
  }
  export interface NumberConfig extends Config<number> {
    readonly type: ConfigType.Number;
    readonly min?: number;
    readonly max?: number;
    readonly step?: number;
  }
  export interface NullableNumberConfig extends Config<number | null> {
    readonly type: ConfigType.NullableNumber;
    readonly min?: number;
    readonly max?: number;
    readonly step?: number;
  }
  export interface StringConfig extends Config<string> {
    readonly type: ConfigType.String;
    readonly maxLength?: number;
    readonly placeholder?: string;
  }
  export interface ColorConfig extends Config<Color> {
    readonly type: ConfigType.Color;
    readonly allowGray: boolean;
  }
  export interface ComparisonConfig extends Config<Comparison> {
    readonly type: ConfigType.Comparison;
  }
  export interface WrappingConfig extends Config<Wrapping> {
    readonly type: ConfigType.Wrapping;
  }
  export interface DirectionConfig extends Config<Direction> {
    readonly type: ConfigType.Direction;
  }
  export interface DirectionToggleConfig extends Config<DirectionToggle> {
    readonly type: ConfigType.DirectionToggle;
  }
  export interface OrientationConfig extends Config<Orientation> {
    readonly type: ConfigType.Orientation;
  }
  export interface OrientationToggleConfig extends Config<OrientationToggle> {
    readonly type: ConfigType.OrientationToggle;
  }
  export interface TileConfig extends Config<GridData> {
    readonly type: ConfigType.Tile;
    readonly resizable: boolean;
  }
  export interface ShapeConfig extends Config<GridData> {
    readonly type: ConfigType.Shape;
    readonly resizable: boolean;
  }
  export interface GridConfig extends Config<GridData> {
    readonly type: ConfigType.Grid;
  }
  export interface NullableGridConfig extends Config<GridData | null> {
    readonly type: ConfigType.NullableGrid;
    readonly nonNullDefault: GridData;
  }
  export interface IconConfig extends Config<string> {
    readonly type: ConfigType.Icon;
  }
  export interface ControlLinesConfig extends Config<ControlLine[]> {
    readonly type: ConfigType.ControlLines;
  }
  export interface NullableNoteConfig extends Config<string | null> {
    readonly type: ConfigType.NullableNote;
  }
  export interface NullableInstrumentConfig extends Config<Instrument | null> {
    readonly type: ConfigType.NullableInstrument;
  }
  export interface SolvePathConfig extends Config<Position$1[]> {
    readonly type: ConfigType.SolvePath;
  }
  export type AnyConfig =
    | BooleanConfig
    | NullableBooleanConfig
    | NumberConfig
    | NullableNumberConfig
    | StringConfig
    | ColorConfig
    | ComparisonConfig
    | WrappingConfig
    | DirectionConfig
    | DirectionToggleConfig
    | OrientationConfig
    | OrientationToggleConfig
    | TileConfig
    | ShapeConfig
    | GridConfig
    | NullableGridConfig
    | IconConfig
    | ControlLinesConfig
    | NullableNoteConfig
    | NullableInstrumentConfig
    | SolvePathConfig;
  /**
   * Compare two config values for equality, using an appropriate method for the config type.
   *
   * @param type The type of the config.
   * @param a The first value to compare.
   * @param b The second value to compare.
   * @returns Whether the two values are equal.
   */
  export declare function configEquals<C extends AnyConfig>(
    type: C['type'],
    a: C['default'],
    b: C['default']
  ): boolean;
  export declare function isEventHandler<T>(
    val: unknown,
    event: string
  ): val is T;
  export interface FinalValidationHandler {
    /**
     * Edits the final grid state after all rules and symbols have been validated.
     *
     * @param grid The grid that is being validated.
     * @param solution The solution grid, or null if the solution is not available.
     * @param state The current state of the grid.
     */
    onFinalValidation(
      grid: GridData,
      solution: GridData | null,
      state: GridState
    ): GridState;
  }
  export declare function handlesFinalValidation<T extends Instruction>(
    val: T
  ): val is T & FinalValidationHandler;
  export interface SymbolDisplayHandler {
    /**
     * Controls whether a symbol should be visible in the grid.
     *
     * @param grid The grid that is being displayed.
     * @param solution The solution grid, if it is available.
     * @param symbol The symbol that is being displayed.
     * @param editing Whether the grid is being edited.
     * @returns True if the symbol should be displayed, false otherwise. The symbol will not be displayed if any handler returns false.
     */
    onSymbolDisplay(
      grid: GridData,
      solution: GridData | null,
      symbol: Symbol$1,
      editing: boolean
    ): boolean;
  }
  export declare function handlesSymbolDisplay<T extends Instruction>(
    val: T
  ): val is T & SymbolDisplayHandler;
  export interface SymbolMergeHandler {
    /**
     * Determines if the description of two symbols can be merged when displayed in the UI.
     * @param other The other symbol to compare against.
     */
    descriptionEquals(other: Symbol$1): boolean;
  }
  export declare function handlesSymbolMerge<T extends Instruction>(
    val: T
  ): val is T & SymbolMergeHandler;
  export interface SymbolValidationHandler {
    /**
     * Overrides the validation of symbols.
     *
     * You can return a different validation result, or call the original validation logic with a modified grid.
     *
     * @param grid - The grid to validate.
     * @param _symbol - The symbol to validate.
     * @param validator - The original validation logic for the symbol.
     * @returns The state of the symbol after validation.
     */
    onSymbolValidation(
      grid: GridData,
      symbol: Symbol$1,
      validator: (grid: GridData) => State
    ): State | undefined;
  }
  export declare function handlesSymbolValidation<T extends Rule>(
    val: T
  ): val is T & SymbolValidationHandler;
  export type PuzzleMetadata = {
    /**
     * The title of the puzzle. (required)
     */
    title: string;
    /**
     * The author of the puzzle. (required)
     */
    author: string;
    /**
     * A description of the puzzle. (can be empty)
     */
    description: string;
    /**
     * The difficulty of the puzzle, from 0 to 10. (required)
     *
     * 0 represents an unrated puzzle, 6-10 represent star difficulties.
     */
    difficulty: number;
  };
  export declare const MetadataSchema: z.ZodObject<
    {
      title: z.ZodString;
      author: z.ZodString;
      description: z.ZodString;
      difficulty: z.ZodNumber;
    },
    z.core.$strict
  >;
  export declare const PuzzleSchema: z.ZodObject<
    {
      title: z.ZodString;
      author: z.ZodString;
      description: z.ZodString;
      difficulty: z.ZodNumber;
      grid: z.ZodCustom<GridData, GridData>;
      solution: z.ZodNullable<z.ZodCustom<GridData, GridData>>;
    },
    z.core.$strict
  >;
  export type PuzzleData = {
    /**
     * The grid of the puzzle. (required)
     *
     * You must fix all given cells in the grid. The rest of the cells will be cleared.
     */
    grid: GridData;
    /**
     * The solution to the puzzle. (optional)
     *
     * You should provide a solution if a rule requires it. Otherwise, the rule can never be satisfied.
     *
     * If there are no rules that require a solution, this field will be ignored.
     */
    solution: GridData | null;
  };
  export type Puzzle = PuzzleMetadata & PuzzleData;
  /**
   * Checks if two puzzles are equal.
   */
  export declare function puzzleEquals(a: Puzzle, b: Puzzle): boolean;
  /**
   * Get the types of a puzzle based on its grid properties. The returned types are ordered by their priority.
   * The first type is the most important one.
   */
  export declare function getPuzzleTypes(grid: GridData): PuzzleType[];
  export interface PuzzleChecklistItem {
    id: string;
    success: boolean;
    mandatory: boolean;
  }
  export interface PuzzleChecklist {
    items: PuzzleChecklistItem[];
    isValid: boolean;
  }
  export declare function validatePuzzleChecklist(
    metadata: PuzzleMetadata,
    gridWithSolution: GridData,
    state: GridState
  ): PuzzleChecklist;
  export interface ShapeElement {
    x: number;
    y: number;
    color: Color;
  }
  export interface Shape {
    width: number;
    height: number;
    elements: ShapeElement[];
  }
  export declare function shapeEquals(a: Shape, b: Shape): boolean;
  export declare function tilesToShape(
    tiles: readonly (readonly TileData[])[]
  ): Shape;
  export declare function positionsToShape(
    positions: Position$1[],
    color: Color
  ): Shape;
  export declare function getShapeVariants(shape: Shape): Shape[];
  export declare function normalizeShape(shape: Shape): Shape;
  export declare function sanitizePatternGrid(
    pattern: GridData,
    tileMapper?: (tile: TileData) => TileData
  ): GridData;
  export declare class BanPatternRule extends Rule {
    readonly title = 'Ban Pattern';
    private static readonly EXAMPLE_GRID;
    private static readonly CONFIGS;
    private static readonly SEARCH_VARIANTS;
    readonly pattern: GridData;
    readonly cache: Shape[];
    /**
     * **Don't make this pattern**
     *
     * @param pattern - GridData representing the banned pattern. Only non-gray tiles are considered.
     */
    constructor(pattern: GridData);
    get id(): string;
    get explanation(): string;
    get configs(): readonly AnyConfig[] | null;
    createExampleGrid(): GridData;
    get searchVariants(): SearchVariant[];
    validateGrid(grid: GridData): RuleState;
    copyWith({ pattern }: { pattern?: GridData }): this;
    withPattern(pattern: GridData): this;
  }
  export interface Zone {
    positions: Position$1[];
    completed: number;
    possible: number;
  }
  export type ZoneCounts = {
    zones: Zone[];
    complete: boolean;
  };
  export declare abstract class CellCountPerZoneRule extends Rule {
    readonly color: Color;
    get configExplanation(): string;
    /**
     * @param color - The color of the cells to count.
     */
    constructor(color: Color);
    protected getZoneCounts(grid: GridData): ZoneCounts;
    withColor(color: Color): this;
  }
  export declare class CellCountRule extends Rule {
    readonly color: Color;
    readonly count: number;
    readonly title = 'Total Count';
    private static readonly CONFIGS;
    private static readonly EXAMPLE_GRID_LIGHT;
    private static readonly EXAMPLE_GRID_DARK;
    private static readonly SEARCH_VARIANTS;
    /**
     * **There are &lt;count&gt; &lt;color&gt; cells in total**
     *
     * @param color - The color of the cells to count.
     * @param count - The total number of cells of the given color.
     */
    constructor(color: Color, count: number);
    get id(): string;
    get explanation(): string;
    get configs(): readonly AnyConfig[] | null;
    createExampleGrid(): GridData;
    get searchVariants(): SearchVariant[];
    validateGrid(grid: GridData): RuleState;
    copyWith({ color, count }: { color?: Color; count?: number }): this;
    withColor(color: Color): this;
    withCount(count: number): this;
  }
  export declare class ConnectAllRule extends Rule {
    readonly color: Color;
    readonly title = 'Connect All';
    private static readonly CONFIGS;
    private static readonly EXAMPLE_GRID_LIGHT;
    private static readonly EXAMPLE_GRID_DARK;
    private static readonly SEARCH_VARIANTS;
    /**
     * **Connect all &lt;color&gt; cells**
     *
     * @param color - The color of the cells to connect.
     */
    constructor(color: Color);
    get id(): string;
    get explanation(): string;
    get configs(): readonly AnyConfig[] | null;
    createExampleGrid(): GridData;
    get searchVariants(): SearchVariant[];
    validateGrid(grid: GridData): RuleState;
    copyWith({ color }: { color?: Color }): this;
    withColor(color: Color): this;
  }
  export declare class ConnectZonesRule extends Rule {
    readonly color: Color;
    readonly title = 'Connect Zones';
    private static readonly CONFIGS;
    private static readonly EXAMPLE_GRID_LIGHT;
    private static readonly EXAMPLE_GRID_DARK;
    private static readonly SEARCH_VARIANTS;
    /**
     * **Connect all &lt;color&gt; cells in each zone**
     *
     * @param color - The color of the cells to connect.
     */
    constructor(color: Color);
    get id(): string;
    get explanation(): string;
    get configs(): readonly AnyConfig[] | null;
    createExampleGrid(): GridData;
    get searchVariants(): SearchVariant[];
    validateGrid(grid: GridData): RuleState;
    copyWith({ color }: { color?: Color }): this;
    withColor(color: Color): this;
  }
  export type ShapeRegions = {
    regions: {
      positions: Position$1[];
      shape: Shape;
      count: number;
    }[];
    complete: boolean;
  };
  export declare abstract class RegionShapeRule extends Rule {
    readonly color: Color;
    /**
     * @param color - The color of the regions to compare.
     */
    constructor(color: Color);
    protected getShapeRegions(grid: GridData): ShapeRegions;
    withColor(color: Color): this;
  }
  export declare class ContainsShapeRule extends RegionShapeRule {
    readonly title = 'Areas Contain Pattern';
    private static readonly EXAMPLE_GRID_LIGHT;
    private static readonly EXAMPLE_GRID_DARK;
    private static readonly CONFIGS;
    private static readonly SEARCH_VARIANTS;
    readonly pattern: GridData;
    readonly cache: Shape[];
    /**
     * **All &lt;color&gt; areas must contain this pattern**
     *
     * @param color - The color of the regions to compare.
     * @param pattern - GridData representing the required pattern. Only non-gray tiles are considered.
     */
    constructor(color: Color, pattern: GridData);
    get id(): string;
    get explanation(): string;
    get configs(): readonly AnyConfig[] | null;
    createExampleGrid(): GridData;
    get searchVariants(): SearchVariant[];
    validateGrid(grid: GridData): RuleState;
    copyWith({ color, pattern }: { color?: Color; pattern?: GridData }): this;
    withPattern(pattern: GridData): this;
  }
  export declare class CustomRule extends Rule {
    readonly description: string;
    readonly grid: GridData;
    readonly title = 'Custom Rule';
    get configExplanation(): string;
    private static readonly EXAMPLE_GRID;
    static readonly configs: readonly AnyConfig[];
    private static readonly SEARCH_VARIANTS;
    /**
     * A custom rule with a description and thumbnail grid.
     *
     * This rule validates answers based on the provided solution.
     *
     * @param description - The description of the rule.
     * @param grid - The thumbnail grid of the rule, preferably 5x4 in size.
     */
    constructor(description: string, grid: GridData);
    get id(): string;
    get explanation(): string;
    get configs(): readonly AnyConfig[] | null;
    createExampleGrid(): GridData;
    get searchVariants(): SearchVariant[];
    validateGrid(_grid: GridData): RuleState;
    copyWith({
      description,
      grid,
    }: {
      description?: string;
      grid?: GridData;
    }): this;
    get validateWithSolution(): boolean;
  }
  export declare class DifferentCountPerZoneRule extends CellCountPerZoneRule {
    readonly color: Color;
    readonly title = 'Different Count Per Zone';
    private static readonly CONFIGS;
    private static readonly EXAMPLE_GRID_LIGHT;
    private static readonly EXAMPLE_GRID_DARK;
    private static readonly EXAMPLE_GRID_GRAY;
    private static readonly SEARCH_VARIANTS;
    /**
     * **Zones of the same size have different numbers of &lt;color&gt; cells.**
     *
     * @param color - The color of the cells to count.
     */
    constructor(color: Color);
    get id(): string;
    get explanation(): string;
    get configs(): readonly AnyConfig[] | null;
    createExampleGrid(): GridData;
    get searchVariants(): SearchVariant[];
    validateGrid(grid: GridData): RuleState;
    copyWith({ color }: { color?: Color }): this;
  }
  export declare class ExactCountPerZoneRule extends CellCountPerZoneRule {
    readonly color: Color;
    readonly count: number;
    readonly title = 'Exact Count Per Zone';
    private static readonly CONFIGS;
    private static readonly EXAMPLE_GRID_LIGHT;
    private static readonly EXAMPLE_GRID_DARK;
    private static readonly EXAMPLE_GRID_GRAY;
    private static readonly SEARCH_VARIANTS;
    /**
     * **Each zone has &lt;count&gt; &lt;color&gt; cells.**
     *
     * @param color - The color of the cells to count.
     * @param count - The exact count of the cells in each zone.
     */
    constructor(color: Color, count: number);
    get id(): string;
    get explanation(): string;
    get configs(): readonly AnyConfig[] | null;
    createExampleGrid(): GridData;
    get searchVariants(): SearchVariant[];
    validateGrid(grid: GridData): RuleState;
    copyWith({ color, count }: { color?: Color; count?: number }): this;
  }
  export declare class ForesightRule extends Rule {
    readonly count: number;
    readonly regenInterval: number;
    readonly startFull: boolean;
    readonly solvePath: Position$1[];
    readonly title = 'Foresight';
    get configExplanation(): string;
    private static readonly EXAMPLE_GRID;
    private static readonly CONFIGS;
    private static readonly SEARCH_VARIANTS;
    /**
     * **Foresight: Show hints**
     */
    constructor(
      count: number,
      regenInterval: number,
      startFull: boolean,
      solvePath?: Position$1[]
    );
    get id(): string;
    get explanation(): string;
    get visibleWhenSolving(): boolean;
    get configs(): readonly AnyConfig[] | null;
    createExampleGrid(): GridData;
    get searchVariants(): SearchVariant[];
    validateGrid(_grid: GridData): RuleState;
    get necessaryForCompletion(): boolean;
    get isSingleton(): boolean;
    modeVariant(mode: Mode): Rule | null;
    copyWith({
      count,
      regenInterval,
      startFull,
      solvePath,
    }: {
      count?: number;
      regenInterval?: number;
      startFull?: boolean;
      solvePath?: Position$1[];
    }): this;
  }
  export declare const allRules: Map<string, Rule>;
  export declare class LyingSymbolRule
    extends Rule
    implements FinalValidationHandler
  {
    readonly count: number;
    readonly title = 'Lying Symbols';
    private static readonly EXAMPLE_GRID;
    private static readonly CONFIGS;
    private static readonly SEARCH_VARIANTS;
    /**
     * **&lt;count&gt; symbols are lying and are incorrect**
     *
     * @param count Number of lying symbols
     */
    constructor(count: number);
    get id(): string;
    get explanation(): string;
    get configs(): readonly AnyConfig[] | null;
    createExampleGrid(): GridData;
    get searchVariants(): SearchVariant[];
    validateGrid(_: GridData): RuleState;
    get isSingleton(): boolean;
    onFinalValidation(
      grid: GridData,
      solution: GridData | null,
      state: GridState
    ): GridState;
    copyWith({ count }: { count?: number }): this;
    withCount(count: number): this;
  }
  export declare class MysteryRule
    extends Rule
    implements FinalValidationHandler, GridChangeHandler, GridResizeHandler
  {
    readonly solution: GridData;
    readonly visible: boolean;
    readonly title = 'Alternate Solution';
    get configExplanation(): string;
    private static readonly EXAMPLE_GRID;
    private static readonly CONFIGS;
    private static readonly SEARCH_VARIANTS;
    /**
     * **Mystery: alternate solution**
     */
    constructor(solution: GridData, visible: boolean);
    get id(): string;
    get explanation(): string;
    get visibleWhenSolving(): boolean;
    get configs(): readonly AnyConfig[] | null;
    createExampleGrid(): GridData;
    get searchVariants(): SearchVariant[];
    validateGrid(grid: GridData): RuleState;
    get necessaryForCompletion(): boolean;
    onFinalValidation(
      grid: GridData,
      _solution: GridData | null,
      state: GridState
    ): GridState;
    onGridChange(newGrid: GridData): this;
    onGridResize(
      _grid: GridData,
      mode: 'insert' | 'remove',
      direction: 'row' | 'column',
      index: number
    ): this | null;
    copyWith({
      solution,
      visible,
    }: {
      solution?: GridData;
      visible?: boolean;
    }): this;
    withSolution(solution: GridData): this;
    withVisible(visible: boolean): this;
    static cleanSolution(solution: GridData, baseGrid?: GridData): GridData;
  }
  export declare class NoLoopsRule extends Rule {
    readonly color: Color;
    readonly title = 'No Loops';
    private static readonly CONFIGS;
    private static readonly EXAMPLE_GRID_LIGHT;
    private static readonly EXAMPLE_GRID_DARK;
    private static readonly SEARCH_VARIANTS;
    /**
     * **No loops in &lt;color&gt; cells**
     *
     * @param color - The color of the cells to check.
     */
    constructor(color: Color);
    get id(): string;
    get explanation(): string;
    get configs(): readonly AnyConfig[] | null;
    createExampleGrid(): GridData;
    get searchVariants(): SearchVariant[];
    validateGrid(grid: GridData): RuleState;
    copyWith({ color }: { color?: Color }): this;
    withColor(color: Color): this;
  }
  export declare class OffByXRule
    extends Rule
    implements SymbolValidationHandler
  {
    readonly number: number;
    readonly title = 'Off By X';
    private static readonly CONFIGS;
    private static readonly EXAMPLE_GRID;
    private static readonly SEARCH_VARIANTS;
    /**
     * **All numbers are off by &lt;number&gt;**
     *
     * @param number - The number that all cells are off by.
     */
    constructor(number: number);
    get id(): string;
    get explanation(): string;
    get configs(): readonly AnyConfig[] | null;
    createExampleGrid(): GridData;
    get searchVariants(): SearchVariant[];
    validateGrid(grid: GridData): RuleState;
    onSymbolValidation(
      grid: GridData,
      symbol: Symbol$1,
      _validator: (grid: GridData) => State
    ): State | undefined;
    get isSingleton(): boolean;
    copyWith({ number }: { number?: number }): this;
    withNumber(number: number): this;
  }
  export declare class PerfectionRule
    extends Rule
    implements SetGridHandler, FinalValidationHandler
  {
    readonly editor: boolean;
    readonly title = 'Perfection';
    get configExplanation(): string;
    private static readonly EXAMPLE_GRID;
    private static readonly SEARCH_VARIANTS;
    /**
     * **Quest for Perfection: cell colors are final**
     *
     * @param editor - whether to enable editor mode. This field is automatically set by the editor.
     */
    constructor(editor?: boolean);
    get id(): string;
    get explanation(): string;
    get configs(): readonly AnyConfig[] | null;
    createExampleGrid(): GridData;
    get searchVariants(): SearchVariant[];
    get necessaryForCompletion(): boolean;
    get isSingleton(): boolean;
    modeVariant(mode: Mode): Rule | null;
    validateGrid(grid: GridData): RuleState;
    /**
     * If the grid passes validation but is different from the solution, indicate the error in the final state.
     */
    onFinalValidation(
      grid: GridData,
      solution: GridData | null,
      state: GridState
    ): GridState;
    private fixTiles;
    private isValid;
    private findSingleError;
    /**
     * Force all tiles to be fixed.
     *
     * If the grid is already wrong, prevent the player from changing it further.
     */
    onSetGrid(
      oldGrid: GridData,
      newGrid: GridData,
      solution: GridData | null
    ): GridData;
    copyWith({ editor }: { editor?: boolean }): this;
  }
  export declare class RegionAreaRule extends Rule {
    readonly color: Color;
    readonly size: number;
    readonly title = 'Region Area Size';
    private static readonly CONFIGS;
    private static readonly EXAMPLE_GRID_DARK;
    private static readonly EXAMPLE_GRID_LIGHT;
    private static readonly EXAMPLE_GRID_GRAY;
    private static readonly SEARCH_VARIANTS;
    /**
     * **All &lt;color&gt; regions have area &lt;size&gt;**
     *
     * @param color - The color of the regions.
     * @param size - The area of the regions.
     */
    constructor(color: Color, size: number);
    get id(): string;
    get explanation(): string;
    get configs(): readonly AnyConfig[] | null;
    createExampleGrid(): GridData;
    get searchVariants(): SearchVariant[];
    validateGrid(grid: GridData): RuleState;
    copyWith({ color, size }: { color?: Color; size?: number }): this;
    withColor(color: Color): this;
    withSize(size: number): this;
  }
  export declare class SameCountPerZoneRule extends CellCountPerZoneRule {
    readonly color: Color;
    readonly title = 'Equal Count Per Zone';
    private static readonly CONFIGS;
    private static readonly EXAMPLE_GRID_LIGHT;
    private static readonly EXAMPLE_GRID_DARK;
    private static readonly EXAMPLE_GRID_GRAY;
    private static readonly SEARCH_VARIANTS;
    /**
     * **Zones of the same size have the same number of &lt;color&gt; cells.**
     *
     * @param color - The color of the cells to count.
     */
    constructor(color: Color);
    get id(): string;
    get explanation(): string;
    get configs(): readonly AnyConfig[] | null;
    createExampleGrid(): GridData;
    get searchVariants(): SearchVariant[];
    validateGrid(grid: GridData): RuleState;
    copyWith({ color }: { color?: Color }): this;
  }
  export declare class SameShapeRule extends RegionShapeRule {
    readonly title = 'Same Shape Areas';
    private static readonly CONFIGS;
    private static readonly EXAMPLE_GRID_LIGHT;
    private static readonly EXAMPLE_GRID_DARK;
    private static readonly SEARCH_VARIANTS;
    /**
     * **All &lt;color&gt; areas have the same shape and size**
     *
     * @param color - The color of the regions to compare.
     */
    constructor(color: Color);
    get id(): string;
    get explanation(): string;
    get configs(): readonly AnyConfig[] | null;
    createExampleGrid(): GridData;
    get searchVariants(): SearchVariant[];
    validateGrid(grid: GridData): RuleState;
    copyWith({ color }: { color?: Color }): this;
  }
  export declare class SymbolsPerRegionRule extends Rule {
    readonly color: Color;
    readonly count: number;
    readonly comparison: Comparison;
    readonly title = 'Symbols Per Area';
    private static readonly SYMBOL_POSITIONS;
    private static readonly CONFIGS;
    private static readonly EXAMPLE_GRIDS;
    private static readonly SEARCH_VARIANTS;
    /**
     * **Exactly &lt;count&gt; symbols per &lt;color&gt; area**
     *
     * @param color - Color of the region affected by the rule
     * @param count - Number of symbols to have in each region
     * @param comparison - Comparison to use when checking the number of symbols
     */
    constructor(color: Color, count: number, comparison?: Comparison);
    get id(): string;
    get explanation(): string;
    get configs(): readonly AnyConfig[] | null;
    createExampleGrid(): GridData;
    get searchVariants(): SearchVariant[];
    validateGrid(grid: GridData): RuleState;
    copyWith({
      count,
      color,
      comparison,
    }: {
      count?: number;
      color?: Color;
      comparison?: Comparison;
    }): this;
    withColor(color: Color): this;
    withCount(count: number): this;
    withComparison(comparison: Comparison): this;
  }
  export declare class UniqueShapeRule extends RegionShapeRule {
    readonly title = 'Unique Shape Areas';
    private static readonly CONFIGS;
    private static readonly EXAMPLE_GRID_LIGHT;
    private static readonly EXAMPLE_GRID_DARK;
    private static readonly SEARCH_VARIANTS;
    /**
     * **No two &lt;color&gt; areas have the same shape and size**
     *
     * @param color - The color of the regions to compare.
     */
    constructor(color: Color);
    get id(): string;
    get explanation(): string;
    get configs(): readonly AnyConfig[] | null;
    createExampleGrid(): GridData;
    get searchVariants(): SearchVariant[];
    validateGrid(grid: GridData): RuleState;
    copyWith({ color }: { color?: Color }): this;
  }
  /**
   * The master serializer for puzzles.
   *
   * It uses the default serializer when stringifying puzzles, and select the correct deserializer when parsing puzzles.
   */
  export declare const Serializer: {
    stringifyTiles(tiles: readonly (readonly TileData[])[]): string;
    parseTiles(input: string): TileData[][];
    stringifyRule(rule: Rule): string;
    parseRule(input: string): Rule;
    stringifySymbol(symbol: Symbol$1): string;
    parseSymbol(input: string): Symbol$1;
    stringifyGrid(grid: GridData): string;
    parseGrid(input: string): GridData;
    stringifyGridWithSolution(puzzle: PuzzleData): string;
    parseGridWithSolution(input: string): PuzzleData;
    /**
     * Convert a puzzle to a string.
     * @param puzzle The puzzle to convert.
     * @returns The string representation of the puzzle.
     */
    stringifyPuzzle(puzzle: Puzzle): string;
    /**
     * Parse a puzzle from a string.
     * @param input The string to parse.
     * @returns The parsed puzzle.
     */
    parsePuzzle(input: string): Puzzle;
  };
  export declare abstract class CompressorBase {
    /**
     * The unique identifier for this compressor.
     */
    abstract get id(): string;
    /**
     * Compress the given input string into URL-safe compressed string.
     * @param input The input string to compress.
     */
    abstract compress(input: string): Promise<string>;
    /**
     * Decompress the given compressed string back into the original string.
     * @param input The compressed string to decompress.
     */
    abstract decompress(input: string): Promise<string>;
  }
  declare class MasterCompressor extends CompressorBase {
    get id(): string;
    compress(input: string): Promise<string>;
    decompress(input: string): Promise<string>;
  }
  export declare const Compressor: MasterCompressor;
  export declare class ChecksumCompressor extends CompressorBase {
    get id(): string;
    compress(input: string): Promise<string>;
    decompress(_input: string): Promise<string>;
  }
  export declare abstract class StreamCompressor extends CompressorBase {
    protected abstract get algorithm(): CompressionFormat;
    compress(input: string): Promise<string>;
    decompress(input: string): Promise<string>;
  }
  export declare class DeflateCompressor extends StreamCompressor {
    get id(): string;
    protected get algorithm(): CompressionFormat;
    compress(input: string): Promise<string>;
    decompress(input: string): Promise<string>;
  }
  export declare class GzipCompressor extends StreamCompressor {
    get id(): string;
    protected get algorithm(): CompressionFormat;
  }
  export declare abstract class SerializerBase {
    abstract get version(): number;
    abstract stringifyTile(tile: TileData): string;
    abstract parseTile(str: string): TileData;
    abstract stringifyRule(rule: Rule): string;
    abstract stringifySymbol(symbol: Symbol$1): string;
    abstract parseRule(str: string): Rule;
    abstract parseSymbol(str: string): Symbol$1;
    abstract stringifyConnections(connections: GridConnections): string;
    abstract parseConnections(input: string): GridConnections;
    abstract stringifyZones(zones: GridZones): string;
    abstract parseZones(input: string): GridZones;
    abstract stringifyTiles(tiles: readonly (readonly TileData[])[]): string;
    abstract parseTiles(input: string): TileData[][];
    abstract stringifyRules(rules: readonly Rule[]): string;
    abstract parseRules(input: string): Rule[];
    abstract stringifySymbols(
      symbols: ReadonlyMap<string, readonly Symbol$1[]>
    ): string;
    abstract parseSymbols(input: string): Map<string, Symbol$1[]>;
    abstract stringifyGrid(grid: GridData): string;
    abstract parseGrid(input: string): GridData;
    abstract stringifyGridWithSolution(puzzle: PuzzleData): string;
    abstract parseGridWithSolution(input: string): PuzzleData;
    abstract stringifyPuzzle(puzzle: Puzzle): string;
    abstract parsePuzzle(input: string): Puzzle;
  }
  export declare const OFFSETS: {
    x: number;
    y: number;
  }[];
  export declare const orientationChars: {
    up: string;
    'up-right': string;
    right: string;
    'down-right': string;
    down: string;
    'down-left': string;
    left: string;
    'up-left': string;
  };
  export declare class SerializerV0 extends SerializerBase {
    readonly version: number;
    stringifyTile(tile: TileData): string;
    parseTile(str: string): TileData;
    stringifyControlLine(line: ControlLine): string;
    parseControlLine(str: string): ControlLine;
    stringifyConfig(instruction: Instruction, config: AnyConfig): string;
    parseConfig(
      configs: readonly AnyConfig[],
      entry: string
    ): [string, unknown];
    stringifyInstruction(instruction: Instruction): string;
    stringifyRule(rule: Rule): string;
    stringifySymbol(symbol: Symbol$1): string;
    parseRule(str: string): Rule;
    parseSymbol(str: string): Symbol$1;
    stringifyConnections(connections: GridConnections): string;
    parseConnections(input: string): GridConnections;
    stringifyZones(zones: GridZones): string;
    parseZones(input: string): GridZones;
    stringifyTiles(tiles: readonly (readonly TileData[])[]): string;
    parseTiles(input: string): TileData[][];
    stringifyRules(rules: readonly Rule[]): string;
    parseRules(input: string): Rule[];
    stringifySymbols(symbols: ReadonlyMap<string, readonly Symbol$1[]>): string;
    parseSymbols(input: string): Map<string, Symbol$1[]>;
    stringifyGrid(grid: GridData): string;
    parseGrid(input: string): GridData;
    stringifyGridWithSolution(puzzle: PuzzleData): string;
    parseGridWithSolution(input: string): PuzzleData;
    stringifyPuzzle(puzzle: Puzzle): string;
    parsePuzzle(input: string): Puzzle;
  }
  export declare class SerializerChecksum extends SerializerV0 {
    readonly version: number;
    parseTile(_str: string): TileData;
    stringifyControlLine(line: ControlLine): string;
    parseControlLine(_str: string): ControlLine;
    stringifyConfig(instruction: Instruction, config: AnyConfig): string;
    parseConfig(
      _configs: readonly AnyConfig[],
      _entry: string
    ): [string, unknown];
    parseRule(_str: string): Rule;
    parseSymbol(_str: string): Symbol$1;
    parseConnections(_input: string): GridConnections;
    stringifyZones(zones: GridZones): string;
    parseZones(_input: string): GridZones;
    parseTiles(_input: string): TileData[][];
    stringifyRules(rules: readonly Rule[]): string;
    parseRules(_input: string): Rule[];
    stringifySymbols(symbols: ReadonlyMap<string, readonly Symbol$1[]>): string;
    parseSymbols(_input: string): Map<string, Symbol$1[]>;
    stringifyGrid(grid: GridData): string;
    parseGrid(_input: string): GridData;
    stringifyGridWithSolution(puzzle: PuzzleData): string;
    parseGridWithSolution(_input: string): PuzzleData;
    stringifyPuzzle(puzzle: Puzzle): string;
    parsePuzzle(_input: string): Puzzle;
  }
  /**
   * Base class that all solvers must extend.
   */
  export declare abstract class Solver {
    /**
     * The unique identifier of the solver.
     *
     * This is also displayed to the user when selecting a solver.
     */
    abstract get id(): string;
    /**
     * The author(s) of the solver.
     */
    abstract get author(): string;
    /**
     * A short paragraph describing when the user should use this solver.
     */
    abstract get description(): string;
    /**
     * Whether the solver supports cancellation. If `true`, the solver must respond to the abort signal if it is provided.
     */
    abstract get supportsCancellation(): boolean;
    /**
     * Solve the given grid. The implementation should delegate long-running tasks to a worker thread and yield solutions
     * asynchronously.
     *
     * The solver must yield at least once, otherwise the UI will not update.
     *
     * If the solver finds no solution other than those already yielded, it should yield `null`. Yielding `null` on the
     * first iteration indicates that the grid is unsolvable. Yielding `null` on the second iteration indicates that the
     * solution is unique.
     *
     * If the solve finds the trivial solution of not filling any tiles, such as in the case of an underclued grid with
     * too many alternate solutions, it must yield the solution instead of yielding `null`.
     *
     * In the current UI implementation, the solver will be terminated after yielding `null`, or after 2 iterations if
     * `null` is never yielded. The solver should perform any necessary cleanup in the `finally` block of the generator.
     *
     * @param grid The grid to solve. The provided grid is guaranteed to be supported by the solver. Some tiles in the
     * grid may already be filled by the user. It is up to the solver to decide whether to respect these tiles or not.
     * @param abortSignal An optional signal that the solver should subscribe to in order to cancel the operation. If the
     * solver does not support cancellation, it should ignore this parameter.
     */
    abstract solve(
      grid: GridData,
      abortSignal?: AbortSignal
    ): AsyncGenerator<GridData | null>;
    /**
     * Check if the solver supports the current browser environment. This method is called once when the user first clicks
     * the "Solve" button, and the result is cached for the duration of the editor session.
     *
     * The `solve` method will not be called if this method returns `false`, and a message will be displayed to the user
     * indicating that the solver is not supported.
     *
     * @returns A promise that resolves to `true` if the environment is supported, or `false` otherwise.
     */
    protected isEnvironmentSupported(): Promise<boolean>;
    readonly environmentCheck: CachedAccess<Promise<boolean>>;
    /**
     * Check if the solver supports the given instruction. This is used to render a small indication in the UI for each
     * instruction in the editor.
     *
     * @param instructionId The unique identifier of the instruction.
     */
    isInstructionSupported(_grid: GridData, instruction: Instruction): boolean;
    /**
     * Check if the solver supports the given grid. This methid is frequently called when the user changes the grid, and
     * the result is used to enable or disable the "Solve" button.
     *
     * The `solve` method will not be called if this method returns `false`, and a message will be displayed to the user
     * indicating that the grid is not supported by this solver.
     *
     * @param grid The grid to check.
     * @returns `true` if the grid is supported, or `false` otherwise.
     */
    isGridSupported(grid: GridData): boolean;
  }
  export declare const allSolvers: Map<string, Solver>;
  export declare class AutoSolver extends Solver {
    readonly id = 'auto';
    readonly author = 'various contributors';
    readonly description =
      'Automatically select the fastest solver based on supported instructions and environment.';
    readonly supportsCancellation = true;
    private static readonly nonAdditiveInstructions;
    isGridSupported(grid: GridData): boolean;
    isInstructionSupported(grid: GridData, instruction: Instruction): boolean;
    protected isEnvironmentSupported(): Promise<boolean>;
    private fillSolution;
    private fixGrid;
    private solveWithProgress;
    private solveOne;
    solve(
      grid: GridData,
      abortSignal?: AbortSignal
    ): AsyncGenerator<GridData | null>;
  }
  export declare abstract class EventIteratingSolver extends Solver {
    readonly supportsCancellation = true;
    protected abstract createWorker(): Worker;
    protected isEnvironmentSupported(): Promise<boolean>;
    solve(
      grid: GridData,
      abortSignal?: AbortSignal
    ): AsyncGenerator<GridData | null>;
  }
  export declare class BacktrackSolver extends EventIteratingSolver {
    private static readonly supportedInstrs;
    readonly id = 'backtrack';
    readonly author = 'ALaggyDev';
    readonly description =
      'Solves puzzles pretty fast using backtracking with optimizations. Support most rules and symbols (including underclued).';
    protected createWorker(): Worker;
    isInstructionSupported(_grid: GridData, instruction: Instruction): boolean;
  }
  export declare enum BTTile {
    Empty = 0,
    Dark = 1,
    Light = 2,
    NonExist = 3,
  }
  export type BTColor = BTTile.Dark | BTTile.Light;
  export declare class BTGridData {
    readonly tiles: BTTile[][];
    readonly connections: Position$1[][][];
    readonly modules: BTModule[];
    readonly width: number;
    readonly height: number;
    constructor(
      tiles: BTTile[][],
      connections: Position$1[][][],
      modules: BTModule[],
      width: number,
      height: number
    );
    getTile(x: number, y: number): BTTile;
    setTileWithConnection(x: number, y: number, tile: BTTile): void;
    isInBound(x: number, y: number): boolean;
    getEdges(pos: Position$1): Position$1[];
    clone(): BTGridData;
  }
  export declare class IntArray2D {
    private readonly array;
    readonly width: number;
    readonly height: number;
    private constructor();
    static create(width: number, height: number): IntArray2D;
    set(x: number, y: number, value: number): void;
    get(x: number, y: number): number;
    clone(): IntArray2D;
  }
  export interface CheckResult {
    tilesNeedCheck: IntArray2D | null;
    ratings: Rating[] | null;
  }
  export interface Rating {
    pos: Position$1;
    score: number;
  }
  export declare abstract class BTModule {
    abstract checkGlobal(grid: BTGridData): CheckResult | false;
    checkLocal(grid: BTGridData, _: Position$1[]): CheckResult | boolean;
  }
  export declare function getOppositeColor(color: BTColor): BTColor;
  export declare function colorToBTTile(color: Color): BTTile;
  export declare function createOneTileResult(
    grid: BTGridData,
    pos: Position$1,
    score?: number | undefined
  ): CheckResult;
  export declare function checkSubtilePlacement(
    grid: BTGridData,
    pos: Position$1
  ): CheckResult | false | undefined;
  export declare class BanPatternBTModule extends BTModule {
    instr: BanPatternRule;
    constructor(instr: BanPatternRule);
    checkGlobal(grid: BTGridData): CheckResult | false;
    checkLocal(grid: BTGridData, positions: Position$1[]): CheckResult | false;
  }
  export declare class CellCountBTModule extends BTModule {
    instr: CellCountRule;
    constructor(instr: CellCountRule);
    checkGlobal(grid: BTGridData): CheckResult | false;
  }
  export declare class ConnectAllBTModule extends BTModule {
    instr: ConnectAllRule;
    constructor(instr: ConnectAllRule);
    checkGlobal(grid: BTGridData): CheckResult | false;
  }
  export declare class RegionAreaBTModule extends BTModule {
    instr: RegionAreaRule;
    constructor(instr: RegionAreaRule);
    checkGlobal(grid: BTGridData): CheckResult | false;
    private visitArea;
  }
  export declare abstract class RegionShapeBTModule extends BTModule {
    instr: RegionShapeRule;
    constructor(instr: RegionShapeRule);
    protected getShapeRegions(grid: BTGridData): ShapeRegions['regions'];
    private visitArea;
  }
  export declare class SameShapeBTModule extends RegionShapeBTModule {
    instr: SameShapeRule;
    constructor(instr: SameShapeRule);
    checkGlobal(grid: BTGridData): CheckResult | false;
  }
  export declare class SymbolsPerRegionBTModule extends BTModule {
    instr: SymbolsPerRegionRule;
    private symbolMap;
    constructor(
      instr: SymbolsPerRegionRule,
      width: number,
      height: number,
      allSymbols: Symbol$1[]
    );
    checkGlobal(grid: BTGridData): CheckResult | false;
    private visitArea;
  }
  export declare class UniqueShapeBTModule extends RegionShapeBTModule {
    instr: UniqueShapeRule;
    constructor(instr: UniqueShapeRule);
    checkGlobal(grid: BTGridData): CheckResult | false;
  }
  /**
   * All symbols which contain a number should extend this class to be compatible with off by X rules.
   */
  export declare abstract class NumberSymbol extends Symbol$1 {
    readonly x: number;
    readonly y: number;
    readonly number: number;
    constructor(x: number, y: number, number: number);
    abstract countTiles(grid: GridData): {
      completed: number;
      possible: number;
    } | null;
    validateSymbol(grid: GridData): State;
    withNumber(number: number): this;
  }
  export declare class AreaNumberSymbol extends NumberSymbol {
    readonly title = 'Area Number';
    private static readonly CONFIGS;
    private static readonly EXAMPLE_GRID;
    /**
     * **Area Numbers must equal region sizes**
     *
     * @param x - The x-coordinate of the symbol.
     * @param y - The y-coordinate of the symbol.
     * @param number - The area number.
     */
    constructor(x: number, y: number, number: number);
    get id(): string;
    get explanation(): string;
    get configs(): readonly AnyConfig[] | null;
    createExampleGrid(): GridData;
    countTiles(grid: GridData): {
      completed: number;
      possible: number;
    } | null;
    copyWith({
      x,
      y,
      number,
    }: {
      x?: number;
      y?: number;
      number?: number;
    }): this;
    withNumber(number: number): this;
  }
  export declare class AreaNumberBTModule extends BTModule {
    instr: AreaNumberSymbol;
    constructor(instr: AreaNumberSymbol);
    checkGlobal(grid: BTGridData): CheckResult | false;
    checkLocal(
      grid: BTGridData,
      positions: Position$1[]
    ): CheckResult | boolean;
  }
  export declare class DartSymbol extends NumberSymbol {
    readonly orientation: Orientation;
    readonly title = 'Dart';
    private static readonly CONFIGS;
    private static readonly EXAMPLE_GRID;
    /**
     * **Darts count opposite color cells in that direction**
     *
     * @param x - The x-coordinate of the symbol.
     * @param y - The y-coordinate of the symbol.
     * @param number - The number of cells seen by the symbol.
     * @param orientation - The orientation of the symbol.
     */
    constructor(x: number, y: number, number: number, orientation: Orientation);
    get id(): string;
    get placementStep(): number;
    get explanation(): string;
    get configs(): readonly AnyConfig[] | null;
    createExampleGrid(): GridData;
    countTiles(grid: GridData): {
      completed: number;
      possible: number;
    };
    copyWith({
      x,
      y,
      number,
      orientation,
    }: {
      x?: number;
      y?: number;
      number?: number;
      orientation?: Orientation;
    }): this;
    withNumber(number: number): this;
  }
  export declare class DartBTModule extends BTModule {
    instr: DartSymbol;
    constructor(instr: DartSymbol);
    checkGlobal(grid: BTGridData): CheckResult | false;
    private buildCheckAndRating;
  }
  export type DirectionLinkerMap = Record<Direction, Direction>;
  export declare abstract class DirectionLinkerSymbol extends Symbol$1 {
    readonly x: number;
    readonly y: number;
    private static readonly CONFIGS;
    private static readonly EXAMPLE_GRID;
    private static readonly directionDeltas;
    private linkedDirections;
    /**
     * **Darts count opposite color cells in that direction**
     *
     * @param x - The x-coordinate of the symbol.
     * @param y - The y-coordinate of the symbol.
     */
    constructor(x: number, y: number);
    changeDirections(linkedDirections: DirectionLinkerMap): this;
    get id(): string;
    get explanation(): string;
    get configs(): readonly AnyConfig[] | null;
    createExampleGrid(): GridData;
    private deltaCoordinate;
    validateSymbol(grid: GridData): State;
    private getInitialCheckedCouples;
  }
  export declare abstract class DirectionLinkerBTModule extends BTModule {
    instr: DirectionLinkerSymbol;
    constructor(instr: DirectionLinkerSymbol);
    private initialPositions;
    private getInitialPositions;
    checkGlobal(grid: BTGridData): CheckResult | false;
    protected abstract movePos(
      grid: BTGridData,
      x: number,
      y: number
    ): Position$1 | null;
  }
  export declare class FocusSymbol
    extends NumberSymbol
    implements SymbolMergeHandler
  {
    readonly deadEnd: boolean;
    get title(): string;
    private static readonly CONFIGS;
    private static readonly EXAMPLE_GRID;
    private static readonly EXAMPLE_GRID_DEAD_END;
    /**
     * **Focus Numbers count directly adjacent cells of the same color**
     * @param x - The x-coordinate of the symbol.
     * @param y - The y-coordinate of the symbol.
     * @param deadEnd - Whether this Focus Number is a Dead End.
     * @param number - The focus number.
     */
    constructor(x: number, y: number, deadEnd: boolean, number: number);
    get id(): string;
    get placementStep(): number;
    get explanation(): string;
    get configs(): readonly AnyConfig[] | null;
    createExampleGrid(): GridData;
    private countForColor;
    countTiles(grid: GridData): {
      completed: number;
      possible: number;
    };
    descriptionEquals(other: Symbol$1): boolean;
    copyWith({
      x,
      y,
      deadEnd,
      number,
    }: {
      x?: number;
      y?: number;
      deadEnd?: boolean;
      number?: number;
    }): this;
    withNumber(number: number): this;
    withDeadEnd(deadEnd: boolean): this;
  }
  export declare class FocusBTModule extends BTModule {
    instr: FocusSymbol;
    private cachedCheckResult?;
    constructor(instr: FocusSymbol);
    checkGlobal(grid: BTGridData): CheckResult | false;
    private buildCheckAndRating;
  }
  export declare class GalaxySymbol extends DirectionLinkerSymbol {
    readonly x: number;
    readonly y: number;
    readonly title = 'Galaxy';
    private static readonly linkedDirections;
    /**
     * **Galaxies are centers of rotational symmetry**
     *
     * @param x - The x-coordinate of the symbol.
     * @param y - The y-coordinate of the symbol.
     */
    constructor(x: number, y: number);
    get id(): string;
    get explanation(): string;
    get configs(): readonly AnyConfig[] | null;
    createExampleGrid(): GridData;
    validateSymbol(grid: GridData): State;
    copyWith({ x, y }: { x?: number; y?: number }): this;
  }
  export declare class GalaxyBTModule extends DirectionLinkerBTModule {
    instr: GalaxySymbol;
    constructor(instr: GalaxySymbol);
    protected movePos(
      grid: BTGridData,
      x: number,
      y: number
    ): Position$1 | null;
  }
  export declare class LetterSymbol extends Symbol$1 {
    readonly x: number;
    readonly y: number;
    readonly letter: string;
    readonly title = 'Letter';
    private static readonly CONFIGS;
    private static readonly EXAMPLE_GRID;
    /**
     * **Letters must be sorted into one type per area**
     *
     * @param x - The x-coordinate of the symbol.
     * @param y - The y-coordinate of the symbol.
     * @param letter - The letter of the symbol.
     */
    constructor(x: number, y: number, letter: string);
    get id(): string;
    get explanation(): string;
    get configs(): readonly AnyConfig[] | null;
    createExampleGrid(): GridData;
    validateSymbol(grid: GridData): State;
    copyWith({
      x,
      y,
      letter,
    }: {
      x?: number;
      y?: number;
      letter?: string;
    }): this;
    withLetter(letter: string): this;
  }
  export declare class LetterBTModule extends BTModule {
    private letters;
    private letterGrid;
    constructor(instrs: LetterSymbol[], width: number, height: number);
    checkGlobal(grid: BTGridData): CheckResult | false;
    private visitArea;
  }
  export declare class LotusSymbol extends DirectionLinkerSymbol {
    readonly x: number;
    readonly y: number;
    readonly orientation: Orientation;
    readonly title = 'Lotus';
    private static readonly linkedDirectionsFromOrientation;
    /**
     * **Areas containing this symbol must be symmetrical**
     *
     * @param x - The x-coordinate of the symbol.
     * @param y - The y-coordinate of the symbol.
     * @param orientation - The orientation of the symbol.
     */
    constructor(x: number, y: number, orientation: Orientation);
    get id(): string;
    get explanation(): string;
    get configs(): readonly AnyConfig[] | null;
    createExampleGrid(): GridData;
    validateSymbol(grid: GridData): State;
    copyWith({
      x,
      y,
      orientation,
    }: {
      x?: number;
      y?: number;
      orientation?: Orientation;
    }): this;
  }
  export declare class LotusBTModule extends DirectionLinkerBTModule {
    instr: LotusSymbol;
    constructor(instr: LotusSymbol);
    protected movePos(
      grid: BTGridData,
      x: number,
      y: number
    ): Position$1 | null;
    private getTileSafe;
    checkGlobal(grid: BTGridData): false | CheckResult;
  }
  export declare class MinesweeperSymbol extends NumberSymbol {
    readonly title = 'Minesweeper Number';
    private static readonly CONFIGS;
    private static readonly EXAMPLE_GRID;
    /**
     * **Minesweeper Numbers count opposite cells in 8 adjacent spaces**
     *
     * @param x - The x-coordinate of the symbol.
     * @param y - The y-coordinate of the symbol.
     * @param number - The number of cells seen by the symbol.
     */
    constructor(x: number, y: number, number: number);
    get id(): string;
    get placementStep(): number;
    get explanation(): string;
    get configs(): readonly AnyConfig[] | null;
    createExampleGrid(): GridData;
    private countForColor;
    countTiles(grid: GridData): {
      completed: number;
      possible: number;
    };
    copyWith({
      x,
      y,
      number,
    }: {
      x?: number;
      y?: number;
      number?: number;
    }): this;
    withNumber(number: number): this;
  }
  export declare class MinesweeperBTModule extends BTModule {
    instr: MinesweeperSymbol;
    private cachedCheckResult?;
    constructor(instr: MinesweeperSymbol);
    checkGlobal(grid: BTGridData): CheckResult | false;
    private buildCheckAndRating;
  }
  export declare class MyopiaSymbol
    extends Symbol$1
    implements SymbolMergeHandler
  {
    readonly diagonals: boolean;
    readonly directions: OrientationToggle;
    get title(): 'Framed Myopia Arrow' | 'Myopia Arrow';
    private static readonly CONFIGS;
    private static readonly EXAMPLE_GRID;
    private static readonly EXAMPLE_DIAGONAL_GRID;
    /**
     * **Viewpoint Numbers count visible cells in the four directions**
     * @param x - The x-coordinate of the symbol.
     * @param y - The y-coordinate of the symbol.
     * @param diagonals - Whether the symbol should consider diagonal directions.
     * @param directions - The directions in which an arrow is pointing.
     */
    constructor(
      x: number,
      y: number,
      diagonals: boolean,
      directions: OrientationToggle
    );
    get id(): string;
    get placementStep(): number;
    get explanation(): string;
    get configs(): readonly AnyConfig[] | null;
    createExampleGrid(): GridData;
    validateSymbol(grid: GridData): State;
    descriptionEquals(other: Symbol$1): boolean;
    copyWith({
      x,
      y,
      diagonals,
      directions,
    }: {
      x?: number;
      y?: number;
      diagonals?: boolean;
      directions?: OrientationToggle;
    }): this;
    withDirections(directions: OrientationToggle): this;
    withDiagonals(diagonals: boolean): this;
  }
  export declare class MyopiaBTModule extends BTModule {
    instr: MyopiaSymbol;
    constructor(instr: MyopiaSymbol);
    checkGlobal(grid: BTGridData): CheckResult | false;
  }
  export declare class ViewpointSymbol extends NumberSymbol {
    readonly title = 'Viewpoint Number';
    private static readonly CONFIGS;
    private static readonly EXAMPLE_GRID;
    /**
     * **Viewpoint Numbers count visible cells in the four directions**
     * @param x - The x-coordinate of the symbol.
     * @param y - The y-coordinate of the symbol.
     * @param number - The viewpoint number.
     */
    constructor(x: number, y: number, number: number);
    get id(): string;
    get placementStep(): number;
    get explanation(): string;
    get configs(): readonly AnyConfig[] | null;
    createExampleGrid(): GridData;
    private countForColor;
    countTiles(grid: GridData): {
      completed: number;
      possible: number;
    };
    copyWith({
      x,
      y,
      number,
    }: {
      x?: number;
      y?: number;
      number?: number;
    }): this;
    withNumber(number: number): this;
  }
  export declare class ViewpointBTModule extends BTModule {
    instr: ViewpointSymbol;
    constructor(instr: ViewpointSymbol);
    checkGlobal(grid: BTGridData): CheckResult | false;
  }
  export declare class CspuzSolver extends EventIteratingSolver {
    private static readonly supportedInstrs;
    readonly id = 'cspuz';
    readonly author = 'semiexp';
    readonly description =
      'A blazingly fast WebAssembly solver that supports most rules and symbols (including underclued).';
    protected createWorker(): Worker;
    isGridSupported(grid: GridData): boolean;
    isInstructionSupported(grid: GridData, instruction: Instruction): boolean;
    isEnvironmentSupported(): Promise<boolean>;
  }
  export declare function gridToJson(grid: GridData): PuzzleData$1;
  export declare class UniversalSolver extends EventIteratingSolver {
    readonly id = 'universal';
    readonly author = 'romain22222, Lysine';
    readonly description =
      'A backtracking solver that supports all rules and symbols (including underclued) but is less optimized.';
    protected createWorker(): Worker;
  }
  export declare abstract class CustomSymbol
    extends Symbol$1
    implements SymbolMergeHandler
  {
    readonly description: string;
    readonly grid: GridData;
    /**
     * **A custom symbol**
     *
     * @param description - The description of the symbol. Leave this empty to hide the description.
     * @param grid - The thumbnail grid of the rule, preferably 5x4 in size.
     * @param x - The x-coordinate of the symbol.
     * @param y - The y-coordinate of the symbol.
     */
    constructor(description: string, grid: GridData, x: number, y: number);
    get explanation(): string;
    createExampleGrid(): GridData;
    validateSymbol(_grid: GridData): State;
    get validateWithSolution(): boolean;
    descriptionEquals(other: Symbol$1): boolean;
    withDescription(description: string): this;
    withGrid(grid: GridData): this;
  }
  export declare class CustomIconSymbol extends CustomSymbol {
    readonly icon: string;
    readonly rotation: number;
    readonly title = 'Custom Icon Symbol';
    get configExplanation(): string;
    private static readonly EXAMPLE_GRID;
    private static readonly CONFIGS;
    /**
     * **A custom icon symbol**
     *
     * @param description - The description of the symbol. Leave this empty to hide the description.
     * @param grid - The thumbnail grid of the rule, preferably 5x4 in size.
     * @param x - The x-coordinate of the symbol.
     * @param y - The y-coordinate of the symbol.
     * @param icon - The icon to display. All available icons can be found at https://react-icons.github.io/react-icons/icons/md/
     * @param rotation - The rotation of the icon in degrees.
     */
    constructor(
      description: string,
      grid: GridData,
      x: number,
      y: number,
      icon: string,
      rotation?: number
    );
    get id(): string;
    get configs(): readonly AnyConfig[] | null;
    copyWith({
      description,
      grid,
      x,
      y,
      icon,
      rotation,
    }: {
      description?: string;
      grid?: GridData;
      x?: number;
      y?: number;
      icon?: string;
      rotation?: number;
    }): this;
    withIcon(icon: string): this;
    withRotation(rotation: number): this;
  }
  export declare class CustomTextSymbol extends CustomSymbol {
    readonly text: string;
    readonly rotation: number;
    readonly title = 'Custom Text Symbol';
    get configExplanation(): string;
    private static readonly EXAMPLE_GRID;
    private static readonly CONFIGS;
    /**
     * **A custom text symbol**
     *
     * @param description - The description of the symbol. Leave this empty to hide the description.
     * @param grid - The thumbnail grid of the rule, preferably 5x4 in size.
     * @param x - The x-coordinate of the symbol.
     * @param y - The y-coordinate of the symbol.
     * @param text - The text to display.
     * @param rotation - The rotation of the text in degrees.
     */
    constructor(
      description: string,
      grid: GridData,
      x: number,
      y: number,
      text: string,
      rotation?: number
    );
    get id(): string;
    get configs(): readonly AnyConfig[] | null;
    copyWith({
      description,
      grid,
      x,
      y,
      text,
      rotation,
    }: {
      description?: string;
      grid?: GridData;
      x?: number;
      y?: number;
      text?: string;
      rotation?: number;
    }): this;
    withText(text: string): this;
    withRotation(rotation: number): this;
  }
  export declare class EveryLetterSymbol extends Symbol$1 {
    readonly x: number;
    readonly y: number;
    readonly letter: string;
    readonly title = 'Hollow Letter';
    private static readonly CONFIGS;
    private static readonly EXAMPLE_GRID;
    /**
     * **Include each Hollow Letter once per region**
     *
     * @param x - The x-coordinate of the symbol.
     * @param y - The y-coordinate of the symbol.
     * @param letter - The letter of the symbol.
     */
    constructor(x: number, y: number, letter: string);
    get id(): string;
    get explanation(): string;
    get configs(): readonly AnyConfig[] | null;
    createExampleGrid(): GridData;
    validateSymbol(grid: GridData): State;
    copyWith({
      x,
      y,
      letter,
    }: {
      x?: number;
      y?: number;
      letter?: string;
    }): this;
    withLetter(letter: string): this;
  }
  export declare class HiddenSymbol
    extends Symbol$1
    implements SymbolDisplayHandler
  {
    readonly x: number;
    readonly y: number;
    readonly revealLocation: boolean;
    readonly title = 'Hidden Symbol Marker';
    get configExplanation(): string;
    private static readonly CONFIGS;
    private static readonly EXAMPLE_GRID;
    /**
     * **Hidden Symbols: color cells correctly to reveal more clues**
     *
     * @param x - The x-coordinate of the symbol.
     * @param y - The y-coordinate of the symbol.
     * @param revealLocation - Whether to reveal the location of the symbol.
     */
    constructor(x: number, y: number, revealLocation?: boolean);
    get id(): string;
    get explanation(): string;
    get configs(): readonly AnyConfig[] | null;
    createExampleGrid(): GridData;
    get necessaryForCompletion(): boolean;
    get visibleWhenSolving(): boolean;
    get sortOrder(): number;
    validateSymbol(grid: GridData, solution: GridData | null): State;
    onSymbolDisplay(
      grid: GridData,
      solution: GridData | null,
      symbol: Symbol$1,
      editing: boolean
    ): boolean;
    copyWith({
      x,
      y,
      revealLocation,
    }: {
      x?: number;
      y?: number;
      revealLocation?: boolean;
    }): this;
    withRevealLocation(revealLocation: boolean): this;
  }
  export declare class HouseSymbol extends NumberSymbol {
    readonly x: number;
    readonly y: number;
    readonly number: number;
    readonly title = 'House';
    private static readonly CONFIGS;
    private static readonly EXAMPLE_GRID;
    /**
     * **Houses must connect to exactly one other house**
     *
     * @param x - The x-coordinate of the symbol.
     * @param y - The y-coordinate of the symbol.
     * @param number - The number of houses in this region.
     */
    constructor(x: number, y: number, number: number);
    get id(): string;
    get explanation(): string;
    get configs(): readonly AnyConfig[] | null;
    createExampleGrid(): GridData;
    countTiles(grid: GridData): {
      completed: number;
      possible: number;
    } | null;
    copyWith({
      x,
      y,
      number,
    }: {
      x?: number;
      y?: number;
      number?: number;
    }): this;
  }
  export declare const allSymbols: Map<string, Symbol$1>;
  /**
   * A marker for symbols not supported by the current solver.
   * Solvers should count these symbols in the symbols per region rule but otherwise ignore them.
   */
  export declare class UnsupportedSymbol extends Symbol$1 {
    readonly title = 'Unsupported Symbol';
    private static readonly CONFIGS;
    private static readonly EXAMPLE_GRID;
    get id(): string;
    get explanation(): string;
    get configs(): readonly AnyConfig[] | null;
    createExampleGrid(): GridData;
    validateSymbol(_grid: GridData, _solution: GridData | null): State;
    copyWith({ x, y }: { x?: number; y?: number }): this;
  }
  export declare function aggregateState(
    rules: readonly RuleState[],
    grid: GridData,
    symbols: ReadonlyMap<string, State[]>
  ): State.Error | State.Satisfied | State.Incomplete;
  export declare function applyFinalOverrides(
    grid: GridData,
    solution: GridData | null,
    state: GridState
  ): GridState;
  export function validateGrid(
    grid: GridData,
    solution: GridData | null
  ): GridState;
  export declare class GridValidator {
    private worker;
    private stateListeners;
    private loadListeners;
    private readonly validateGridDebounced;
    readonly validateGrid: (grid: GridData, solution: GridData | null) => void;
    private readonly notifyState;
    readonly subscribeToState: (
      listener: (state: GridState) => void
    ) => () => void;
    private readonly notifyLoad;
    readonly subscribeToLoad: (listener: () => void) => () => void;
    readonly isLoading: () => boolean;
    readonly delete: () => void;
  }

  export { Symbol$1 as Symbol, escape$1 as escape, unescape$1 as unescape };

  export {};

  export { Symbol$1 as _Symbol };
}
export {};

/* prettier-ignore-end */
