import type { IMAGE_MIME_TYPES, UserIdleState, throttleRAF, MIME_TYPES, ColorPaletteCustom, EditorInterface } from "@excalidraw/common";
import type { LinearElementEditor } from "@excalidraw/element";
import type { MaybeTransformHandleType } from "@excalidraw/element";
import type { PointerType, ExcalidrawLinearElement, NonDeletedExcalidrawElement, NonDeleted, TextAlign, ExcalidrawElement, GroupId, ExcalidrawBindableElement, Arrowhead, FontFamilyValues, FileId, Theme, StrokeRoundness, ExcalidrawEmbeddableElement, ExcalidrawMagicFrameElement, ExcalidrawFrameLikeElement, ExcalidrawElementType, ExcalidrawIframeLikeElement, OrderedExcalidrawElement, ExcalidrawNonSelectionElement, BindMode, ExcalidrawTextElement } from "@excalidraw/element/types";
import type { Merge, MaybePromise, ValueOf, MakeBrand } from "@excalidraw/common/utility-types";
import type { CaptureUpdateActionType, DurableIncrement, EphemeralIncrement } from "@excalidraw/element";
import type { GlobalPoint } from "@excalidraw/math";
import type { Action } from "./actions/types";
import type { Spreadsheet } from "./charts";
import type { ClipboardData, ParsedDataTransferFile } from "./clipboard";
import type App from "./components/App";
import type Library from "./data/library";
import type { ContextMenuItems } from "./components/ContextMenu";
import type { SnapLine } from "./snapping";
import type { ImportedDataState } from "./data/types";
import type { Language } from "./i18n";
import type { isOverScrollBars } from "./scene/scrollbars";
import type React from "react";
import type { JSX } from "react";
export type { App };
export type SocketId = string & {
    _brand: "SocketId";
};
export type Collaborator = Readonly<{
    pointer?: CollaboratorPointer;
    button?: "up" | "down";
    selectedElementIds?: AppState["selectedElementIds"];
    username?: string | null;
    userState?: UserIdleState;
    color?: {
        background: string;
        stroke: string;
    };
    avatarUrl?: string;
    id?: string;
    socketId?: SocketId;
    isCurrentUser?: boolean;
    isInCall?: boolean;
    isSpeaking?: boolean;
    isMuted?: boolean;
}>;
export type CollaboratorPointer = {
    x: number;
    y: number;
    tool: "pointer" | "laser";
    /**
     * Whether to render cursor + username. Useful when you only want to render
     * laser trail.
     *
     * @default true
     */
    renderCursor?: boolean;
    /**
     * Explicit laser color.
     *
     * @default string collaborator's cursor color
     */
    laserColor?: string;
};
export type DataURL = string & {
    _brand: "DataURL";
};
export type BinaryFileData = {
    mimeType: ValueOf<typeof IMAGE_MIME_TYPES> | typeof MIME_TYPES.binary;
    id: FileId;
    dataURL: DataURL;
    /**
     * Epoch timestamp in milliseconds
     */
    created: number;
    /**
     * Indicates when the file was last retrieved from storage to be loaded
     * onto the scene. We use this flag to determine whether to delete unused
     * files from storage.
     *
     * Epoch timestamp in milliseconds.
     */
    lastRetrieved?: number;
    /**
     * indicates the version of the file. This can be used to determine whether
     * the file dataURL has changed e.g. as part of restore due to schema update.
     */
    version?: number;
};
export type BinaryFileMetadata = Omit<BinaryFileData, "dataURL">;
export type BinaryFiles = Record<ExcalidrawElement["id"], BinaryFileData>;
export type ToolType = "selection" | "lasso" | "rectangle" | "diamond" | "ellipse" | "arrow" | "line" | "freedraw" | "text" | "image" | "eraser" | "hand" | "frame" | "magicframe" | "embeddable" | "laser" | "mermaid";
export type ElementOrToolType = ExcalidrawElementType | ToolType | "custom";
export type ActiveTool = {
    type: ToolType;
    customType: null;
} | {
    type: "custom";
    customType: string;
};
export type SidebarName = string;
export type SidebarTabName = string;
export type UserToFollow = {
    socketId: SocketId;
    username: string;
};
type _CommonCanvasAppState = {
    zoom: AppState["zoom"];
    scrollX: AppState["scrollX"];
    scrollY: AppState["scrollY"];
    width: AppState["width"];
    height: AppState["height"];
    viewModeEnabled: AppState["viewModeEnabled"];
    openDialog: AppState["openDialog"];
    editingGroupId: AppState["editingGroupId"];
    selectedElementIds: AppState["selectedElementIds"];
    frameToHighlight: AppState["frameToHighlight"];
    offsetLeft: AppState["offsetLeft"];
    offsetTop: AppState["offsetTop"];
    theme: AppState["theme"];
};
export type StaticCanvasAppState = Readonly<_CommonCanvasAppState & {
    shouldCacheIgnoreZoom: AppState["shouldCacheIgnoreZoom"];
    /** null indicates transparent bg */
    viewBackgroundColor: AppState["viewBackgroundColor"] | null;
    exportScale: AppState["exportScale"];
    selectedElementsAreBeingDragged: AppState["selectedElementsAreBeingDragged"];
    gridSize: AppState["gridSize"];
    gridStep: AppState["gridStep"];
    frameRendering: AppState["frameRendering"];
    linkOpacity: AppState["linkOpacity"];
    gridColor: AppState["gridColor"];
    gridDirection: AppState["gridDirection"];
    frameColor: AppState["frameColor"];
    currentHoveredFontFamily: AppState["currentHoveredFontFamily"];
    hoveredElementIds: AppState["hoveredElementIds"];
    suggestedBinding: AppState["suggestedBinding"];
    croppingElementId: AppState["croppingElementId"];
}>;
export type InteractiveCanvasAppState = Readonly<_CommonCanvasAppState & {
    activeTool: AppState["activeTool"];
    activeEmbeddable: AppState["activeEmbeddable"];
    selectionElement: AppState["selectionElement"];
    selectedGroupIds: AppState["selectedGroupIds"];
    selectedLinearElement: AppState["selectedLinearElement"];
    multiElement: AppState["multiElement"];
    newElement: AppState["newElement"];
    isBindingEnabled: AppState["isBindingEnabled"];
    isMidpointSnappingEnabled: AppState["isMidpointSnappingEnabled"];
    suggestedBinding: AppState["suggestedBinding"];
    isRotating: AppState["isRotating"];
    elementsToHighlight: AppState["elementsToHighlight"];
    collaborators: AppState["collaborators"];
    snapLines: AppState["snapLines"];
    zenModeEnabled: AppState["zenModeEnabled"];
    editingTextElement: AppState["editingTextElement"];
    viewBackgroundColor: AppState["viewBackgroundColor"];
    gridColor: AppState["gridColor"];
    gridDirection: AppState["gridDirection"];
    highlightSearchResult: AppState["highlightSearchResult"];
    isCropping: AppState["isCropping"];
    croppingElementId: AppState["croppingElementId"];
    searchMatches: AppState["searchMatches"];
    activeLockedId: AppState["activeLockedId"];
    hoveredElementIds: AppState["hoveredElementIds"];
    frameRendering: AppState["frameRendering"];
    frameColor: AppState["frameColor"];
    shouldCacheIgnoreZoom: AppState["shouldCacheIgnoreZoom"];
    exportScale: AppState["exportScale"];
    currentItemArrowType: AppState["currentItemArrowType"];
}>;
export type ObservedAppState = ObservedStandaloneAppState & ObservedElementsAppState;
export type ObservedStandaloneAppState = {
    name: AppState["name"];
    viewBackgroundColor: AppState["viewBackgroundColor"];
};
export type ObservedElementsAppState = {
    editingGroupId: AppState["editingGroupId"];
    selectedElementIds: AppState["selectedElementIds"];
    selectedGroupIds: AppState["selectedGroupIds"];
    selectedLinearElement: {
        elementId: LinearElementEditor["elementId"];
        isEditing: boolean;
    } | null;
    croppingElementId: AppState["croppingElementId"];
    lockedMultiSelections: AppState["lockedMultiSelections"];
    activeLockedId: AppState["activeLockedId"];
};
export type BoxSelectionMode = "contain" | "overlap";
export interface AppState {
    contextMenu: {
        items: ContextMenuItems;
        top: number;
        left: number;
    } | null;
    showWelcomeScreen: boolean;
    isLoading: boolean;
    errorMessage: React.ReactNode;
    activeEmbeddable: {
        element: NonDeletedExcalidrawElement;
        state: "hover" | "active";
    } | null;
    /**
     * for a newly created element
     * - set on pointer down, updated during pointer move, used on pointer up
     */
    newElement: NonDeleted<ExcalidrawNonSelectionElement> | null;
    /**
     * for a single element that's being resized
     * - set on pointer down when it's selected and the active tool is selection
     */
    resizingElement: NonDeletedExcalidrawElement | null;
    /**
     * multiElement is for multi-point linear element that's created by clicking as opposed to dragging
     * - when set and present, the editor will handle linear element creation logic accordingly
     */
    multiElement: NonDeleted<ExcalidrawLinearElement> | null;
    /**
     * decoupled from newElement, dragging selection only creates selectionElement
     * - set on pointer down, updated during pointer move
     */
    selectionElement: NonDeletedExcalidrawElement | null;
    /**
     * tracking current arrow binding editor state (takes into account
     * `bindingPreference` and keyboard modifiers (ctrl/alt)
     */
    isBindingEnabled: boolean;
    /** user box selection preference; defaults to "contain" when unset */
    boxSelectionMode: BoxSelectionMode;
    /** user arrow binding preference */
    bindingPreference: "enabled" | "disabled";
    /** user preference whether arrow snap to midpoints while binding */
    isMidpointSnappingEnabled: boolean;
    /**
     * The bindable element the UI highlights for the user when an arrow is
     * dragged or otherwise its endpoint being close to said element.
     */
    suggestedBinding: {
        element: NonDeleted<ExcalidrawBindableElement>;
        midPoint?: GlobalPoint;
    } | null;
    frameToHighlight: NonDeleted<ExcalidrawFrameLikeElement> | null;
    frameRendering: {
        enabled: boolean;
        name: boolean;
        outline: boolean;
        clip: boolean;
        markerName: boolean;
        markerEnabled: boolean;
    };
    editingFrame: string | null;
    elementsToHighlight: NonDeleted<ExcalidrawElement>[] | null;
    /**
     * set when a new text is created or when an existing text is being edited
     */
    editingTextElement: ExcalidrawTextElement | null;
    activeTool: {
        /**
         * indicates a previous tool we should revert back to if we deselect the
         * currently active tool. At the moment applies to `eraser` and `hand` tool.
         */
        lastActiveTool: ActiveTool | null;
        locked: boolean;
        fromSelection: boolean;
    } & ActiveTool;
    preferredSelectionTool: {
        type: "selection" | "lasso";
        initialized: boolean;
    };
    penMode: boolean;
    penDetected: boolean;
    exportBackground: boolean;
    exportEmbedScene: boolean;
    exportWithDarkMode: boolean;
    exportScale: number;
    currentItemStrokeColor: string;
    currentItemBackgroundColor: string;
    currentItemFillStyle: ExcalidrawElement["fillStyle"];
    currentItemStrokeWidth: number;
    currentItemStrokeStyle: ExcalidrawElement["strokeStyle"];
    currentItemRoughness: number;
    currentItemOpacity: number;
    currentItemFontFamily: FontFamilyValues;
    currentItemFontSize: number;
    currentItemTextAlign: TextAlign;
    currentItemStartArrowhead: Arrowhead | null;
    currentItemEndArrowhead: Arrowhead | null;
    currentHoveredFontFamily: FontFamilyValues | null;
    currentItemRoundness: StrokeRoundness;
    currentItemArrowType: "sharp" | "round" | "elbow";
    currentItemFrameRole: ExcalidrawFrameLikeElement["frameRole"] | null;
    viewBackgroundColor: string;
    scrollX: number;
    scrollY: number;
    cursorButton: "up" | "down";
    scrolledOutside: boolean;
    name: string | null;
    isResizing: boolean;
    isRotating: boolean;
    zoom: Zoom;
    openMenu: "canvas" | "shape" | null;
    openPopup: "canvasBackground" | "elementBackground" | "elementStroke" | "fontFamily" | "compactTextProperties" | "compactStrokeStyles" | "compactOtherProperties" | "compactArrowProperties" | null;
    openSidebar: {
        name: SidebarName;
        tab?: SidebarTabName;
    } | null;
    openDialog: null | {
        name: "imageExport" | "help" | "jsonExport";
    } | {
        name: "ttd";
        tab: "text-to-diagram" | "mermaid";
    } | {
        name: "commandPalette";
    } | {
        name: "settings";
    } | {
        name: "elementLinkSelector";
        sourceElementId: ExcalidrawElement["id"];
    } | {
        name: "charts";
        data: Spreadsheet;
        rawText: string;
    };
    /**
     * Reflects user preference for whether the default sidebar should be docked.
     *
     * NOTE this is only a user preference and does not reflect the actual docked
     * state of the sidebar, because the host apps can override this through
     * a DefaultSidebar prop, which is not reflected back to the appState.
     */
    defaultSidebarDockedPreference: boolean;
    lastPointerDownWith: PointerType;
    selectedElementIds: Readonly<{
        [id: string]: true;
    }>;
    hoveredElementIds: Readonly<{
        [id: string]: true;
    }>;
    previousSelectedElementIds: {
        [id: string]: true;
    };
    selectedElementsAreBeingDragged: boolean;
    shouldCacheIgnoreZoom: boolean;
    toast: {
        message: React.ReactNode;
        closable?: boolean;
        duration?: number;
    } | null;
    zenModeEnabled: boolean;
    theme: Theme;
    /** grid cell px size */
    gridSize: number;
    gridStep: number;
    gridModeEnabled: boolean;
    viewModeEnabled: boolean;
    /** top-most selected groups (i.e. does not include nested groups) */
    selectedGroupIds: {
        [groupId: string]: boolean;
    };
    /** group being edited when you drill down to its constituent element
      (e.g. when you double-click on a group's element) */
    editingGroupId: GroupId | null;
    width: number;
    height: number;
    offsetTop: number;
    offsetLeft: number;
    fileHandle: FileSystemFileHandle | null;
    collaborators: Map<SocketId, Collaborator>;
    stats: {
        open: boolean;
        /** bitmap. Use `STATS_PANELS` bit values */
        panels: number;
    };
    showHyperlinkPopup: false | "info" | "editor";
    linkOpacity: number;
    colorPalette?: {
        canvasBackground: ColorPaletteCustom;
        elementBackground: ColorPaletteCustom;
        elementStroke: ColorPaletteCustom;
        topPicks: {
            canvasBackground: [string, string, string, string, string];
            elementStroke: [string, string, string, string, string];
            elementBackground: [string, string, string, string, string];
        };
    };
    allowWheelZoom?: boolean;
    allowPinchZoom?: boolean;
    disableContextMenu: boolean;
    pinnedScripts?: string[];
    customPens?: any[];
    currentStrokeOptions?: any;
    resetCustomPen?: any;
    gridColor: {
        Bold: string;
        Regular: string;
    };
    gridDirection: {
        horizontal: boolean;
        vertical: boolean;
    };
    highlightSearchResult: boolean;
    dynamicStyle: {
        [x: string]: string;
    };
    frameColor: {
        stroke: string;
        fill: string;
        nameColor: string;
    };
    selectedLinearElement: LinearElementEditor | null;
    snapLines: readonly SnapLine[];
    originSnapOffset: {
        x: number;
        y: number;
    } | null;
    objectsSnapModeEnabled: boolean;
    /** the user's socket id & username who is being followed on the canvas */
    userToFollow: UserToFollow | null;
    /** the socket ids of the users following the current user */
    followedBy: Set<SocketId>;
    /** image cropping */
    isCropping: boolean;
    croppingElementId: ExcalidrawElement["id"] | null;
    /** null if no search matches found / search closed */
    searchMatches: Readonly<{
        focusedId: ExcalidrawElement["id"] | null;
        matches: readonly SearchMatch[];
    }> | null;
    /** the locked element/group that's active and shows unlock popup */
    activeLockedId: string | null;
    lockedMultiSelections: {
        [groupId: string]: true;
    };
    bindMode: BindMode;
}
export type SearchMatch = {
    id: string;
    focus: boolean;
    matchedLines: {
        offsetX: number;
        offsetY: number;
        width: number;
        height: number;
        showOnCanvas: boolean;
    }[];
};
export type UIAppState = Omit<AppState, "cursorButton" | "scrollX" | "scrollY">;
export type NormalizedZoomValue = number & {
    _brand: "normalizedZoom";
};
export type Zoom = Readonly<{
    value: NormalizedZoomValue;
}>;
export type PointerCoords = Readonly<{
    x: number;
    y: number;
}>;
export type Gesture = {
    pointers: Map<number, PointerCoords>;
    lastCenter: {
        x: number;
        y: number;
    } | null;
    initialDistance: number | null;
    initialScale: number | null;
};
export declare class GestureEvent extends UIEvent {
    readonly rotation: number;
    readonly scale: number;
}
/** @deprecated legacy: do not use outside of migration paths */
export type LibraryItem_v1 = readonly NonDeleted<ExcalidrawElement>[];
/** @deprecated legacy: do not use outside of migration paths */
type LibraryItems_v1 = readonly LibraryItem_v1[];
/** v2 library item */
export type LibraryItem = {
    id: string;
    status: "published" | "unpublished";
    elements: readonly NonDeleted<ExcalidrawElement>[];
    /** timestamp in epoch (ms) */
    created: number;
    name?: string;
    error?: string;
};
export type LibraryItems = readonly LibraryItem[];
export type LibraryItems_anyVersion = LibraryItems | LibraryItems_v1;
export type LibraryItemsSource = ((currentLibraryItems: LibraryItems) => MaybePromise<LibraryItems_anyVersion | Blob>) | MaybePromise<LibraryItems_anyVersion | Blob>;
export type ExcalidrawInitialDataState = Merge<ImportedDataState, {
    libraryItems?: MaybePromise<Required<ImportedDataState>["libraryItems"]>;
}>;
export type OnUserFollowedPayload = {
    userToFollow: UserToFollow;
    action: "FOLLOW" | "UNFOLLOW";
};
export type OnExportProgress = {
    type: "progress";
    message?: React.ReactNode;
    /** 0-1 range */
    progress?: number;
};
export interface ExcalidrawProps {
    onChange?: (elements: readonly OrderedExcalidrawElement[], appState: AppState, files: BinaryFiles) => void;
    /**
     * note: only subscribes if the props.onIncrement is defined on initial render
     */
    onIncrement?: (event: DurableIncrement | EphemeralIncrement) => void;
    initialData?: (() => MaybePromise<ExcalidrawInitialDataState | null>) | MaybePromise<ExcalidrawInitialDataState | null>;
    /**
     * Invoked as soon as the Excalidraw API is available
     * NOTE editor is not yet mounted, and state is not yet initialized
     */
    onExcalidrawAPI?: (api: ExcalidrawImperativeAPI | null) => void;
    /**
     * Invoked once the editor root is mounted.
     */
    onMount?: (payload: ExcalidrawMountPayload) => void;
    /**
     * Invoked when the editor root is unmounted.
     */
    onUnmount?: () => void;
    /**
     * Invoked once the initial scene is loaded.
     */
    onInitialize?: (api: ExcalidrawImperativeAPI) => void;
    isCollaborating?: boolean;
    onPointerUpdate?: (payload: {
        pointer: {
            x: number;
            y: number;
            tool: "pointer" | "laser";
        };
        button: "down" | "up";
        pointersMap: Gesture["pointers"];
    }) => void;
    onPaste?: (data: ClipboardData, event: ClipboardEvent | null, files: ParsedDataTransferFile[]) => Promise<boolean> | boolean;
    onDrop?: (event: React.DragEvent<HTMLDivElement>) => Promise<boolean> | boolean;
    /**
     * Called when element(s) are duplicated so you can listen or modify as
     * needed.
     *
     * Called when duplicating via mouse-drag, keyboard, paste, library insert
     * etc.
     *
     * Returned elements will be used in place of the next elements
     * (you should return all elements, including deleted, and not mutate
     * the element if changes are made)
     */
    onDuplicate?: (nextElements: readonly ExcalidrawElement[], 
    /** excludes the duplicated elements */
    prevElements: readonly ExcalidrawElement[]) => ExcalidrawElement[] | void;
    renderTopLeftUI?: (isMobile: boolean, appState: UIAppState) => JSX.Element | null;
    renderTopRightUI?: (isMobile: boolean, appState: UIAppState) => JSX.Element | null;
    langCode?: Language["code"];
    viewModeEnabled?: boolean;
    zenModeEnabled?: boolean;
    gridModeEnabled?: boolean;
    objectsSnapModeEnabled?: boolean;
    libraryReturnUrl?: string;
    initState?: AppState;
    theme?: Theme;
    name?: string;
    renderCustomStats?: (elements: readonly NonDeletedExcalidrawElement[], appState: UIAppState) => JSX.Element;
    UIOptions?: Partial<UIOptions>;
    /**
     * dimensions and size constraints for inserted images
     */
    imageOptions?: ImageOptions;
    detectScroll?: boolean;
    handleKeyboardGlobally?: boolean;
    onLibraryChange?: (libraryItems: LibraryItems) => void | Promise<any>;
    autoFocus?: boolean;
    onBeforeTextEdit?: (textElement: ExcalidrawTextElement, isExistingElement: boolean) => string;
    onBeforeTextSubmit?: (textElement: ExcalidrawTextElement, nextText: string, //wrapped
    nextOriginalText: string, isDeleted: boolean) => {
        updatedNextOriginalText: string;
        nextLink: string;
    };
    generateIdForFile?: (file: File) => string | Promise<string>;
    onThemeChange?: (newTheme: string) => void;
    onViewModeChange?: (isViewModeEnabled: boolean) => void;
    generateLinkForSelection?: (id: string, type: "element" | "group") => string;
    onLinkOpen?: (element: NonDeletedExcalidrawElement, event: CustomEvent<{
        nativeEvent: MouseEvent | React.PointerEvent<HTMLCanvasElement>;
    }>) => void;
    onLinkHover?: (element: NonDeletedExcalidrawElement, event: React.PointerEvent<HTMLCanvasElement>) => void;
    onPointerDown?: (activeTool: AppState["activeTool"], pointerDownState: PointerDownState) => void;
    onPointerUp?: (activeTool: AppState["activeTool"], pointerDownState: PointerDownState) => void;
    onScrollChange?: (scrollX: number, scrollY: number, zoom: Zoom) => void;
    onUserFollow?: (payload: OnUserFollowedPayload) => void;
    children?: React.ReactNode;
    validateEmbeddable?: boolean | string[] | RegExp | RegExp[] | ((link: string) => boolean | undefined);
    renderEmbeddable?: (element: NonDeleted<ExcalidrawEmbeddableElement>, appState: AppState) => JSX.Element | null;
    renderWebview?: boolean;
    renderEmbeddableMenu?: (appState: AppState) => JSX.Element | null;
    renderMermaid?: boolean;
    onContextMenu?: (element: readonly NonDeletedExcalidrawElement[], appState: AppState, onClose: (callback?: () => void) => void) => JSX.Element | null;
    aiEnabled?: boolean;
    showDeprecatedFonts?: boolean;
    insertLinkAction?: (linkVal: string) => void;
    renderScrollbars?: boolean;
    /**
     * Called before exporting to a file.
     *
     * Allows the host app to intercept and delay saving until async operations
     * (e.g., images are loaded) complete.
     *
     * If Promise/AsyncGenerator is returned, a progress toast will be shown
     * until the operation completes. Generator can yield progress updates.
     */
    onExport?: (
    /** type of export. Currently we only call for JSON exports or
     * JSON-embedded PNG (which is also identified as `json` type here)*/
    type: "json", data: {
        elements: readonly ExcalidrawElement[];
        appState: AppState;
        files: BinaryFiles;
    }, options: {
        /** signal that gets aborted if user cancels the export (e.g. closes
         * the native file picker dialog). In that case, you can either
         * return immediately, or throw AbortError.
         */
        signal: AbortSignal;
    }) => MaybePromise<void> | AsyncGenerator<OnExportProgress, void>;
}
export type SceneData = {
    elements?: ImportedDataState["elements"];
    appState?: ImportedDataState["appState"];
    collaborators?: Map<SocketId, Collaborator>;
    captureUpdate?: CaptureUpdateActionType;
};
export type ExportOpts = {
    saveFileToDisk?: boolean;
    onExportToBackend?: (exportedElements: readonly NonDeletedExcalidrawElement[], appState: UIAppState, files: BinaryFiles) => void;
    renderCustomUI?: (exportedElements: readonly NonDeletedExcalidrawElement[], appState: UIAppState, files: BinaryFiles, canvas: HTMLCanvasElement) => JSX.Element;
};
export type ImageOptions = Partial<{
    maxWidthOrHeight: number;
    maxFileSizeBytes: number;
}>;
export type CanvasActions = Partial<{
    changeViewBackgroundColor: boolean;
    clearCanvas: boolean;
    export: false | ExportOpts;
    loadScene: boolean;
    saveToActiveFile: boolean;
    toggleTheme: boolean | null;
    saveAsImage: boolean;
}>;
export type UIOptions = Partial<{
    dockedSidebarBreakpoint: number;
    canvasActions: CanvasActions;
    tools: {
        image: boolean;
    };
    /**
     * Optionally control the editor form factor and desktop UI mode from the host app.
     * If not provided, we will take care of it internally.
     */
    getFormFactor?: (editorWidth: number, editorHeight: number) => EditorInterface["formFactor"];
    /** @deprecated does nothing. Will be removed in 0.15 */
    welcomeScreen?: boolean;
}>;
export type AppProps = Merge<ExcalidrawProps, {
    UIOptions: Merge<UIOptions, {
        canvasActions: Required<CanvasActions> & {
            export: ExportOpts;
        };
    }>;
    imageOptions: Required<ImageOptions>;
    detectScroll: boolean;
    handleKeyboardGlobally: boolean;
    isCollaborating: boolean;
    children?: React.ReactNode;
    aiEnabled: boolean;
}>;
/** A subset of App class properties that we need to use elsewhere
 * in the app, eg Manager. Factored out into a separate type to keep DRY. */
export type AppClassProperties = {
    props: AppProps;
    state: AppState;
    api: App["api"];
    sessionExportThemeOverride: App["sessionExportThemeOverride"];
    interactiveCanvas: HTMLCanvasElement | null;
    /** static canvas */
    canvas: HTMLCanvasElement;
    focusContainer(): void;
    library: Library;
    imageCache: Map<FileId, {
        image: HTMLImageElement | Promise<HTMLImageElement>;
        mimeType: ValueOf<typeof IMAGE_MIME_TYPES>;
    }>;
    files: BinaryFiles;
    editorInterface: App["editorInterface"];
    scene: App["scene"];
    syncActionResult: App["syncActionResult"];
    fonts: App["fonts"];
    pasteFromClipboard: App["pasteFromClipboard"];
    id: App["id"];
    onInsertElements: App["onInsertElements"];
    onExportImage: App["onExportImage"];
    lastViewportPosition: App["lastViewportPosition"];
    scrollToContent: App["scrollToContent"];
    addFiles: App["addFiles"];
    addElementsFromPasteOrLibrary: App["addElementsFromPasteOrLibrary"];
    setSelection: App["setSelection"];
    togglePenMode: App["togglePenMode"];
    toggleLock: App["toggleLock"];
    setActiveTool: App["setActiveTool"];
    setOpenDialog: App["setOpenDialog"];
    insertEmbeddableElement: App["insertEmbeddableElement"];
    onMagicframeToolSelect: App["onMagicframeToolSelect"];
    getName: App["getName"];
    dismissLinearEditor: App["dismissLinearEditor"];
    flowChartCreator: App["flowChartCreator"];
    getEffectiveGridSize: App["getEffectiveGridSize"];
    setPlugins: App["setPlugins"];
    plugins: App["plugins"];
    getEditorUIOffsets: App["getEditorUIOffsets"];
    visibleElements: App["visibleElements"];
    excalidrawContainerValue: App["excalidrawContainerValue"];
    onPointerUpEmitter: App["onPointerUpEmitter"];
    updateEditorAtom: App["updateEditorAtom"];
    onPointerDownEmitter: App["onPointerDownEmitter"];
    onEvent: App["onEvent"];
    onStateChange: App["onStateChange"];
    lastPointerMoveCoords: App["lastPointerMoveCoords"];
    bindModeHandler: App["bindModeHandler"];
    setAppState: App["setAppState"];
};
export type PointerDownState = Readonly<{
    origin: Readonly<{
        x: number;
        y: number;
    }>;
    originInGrid: Readonly<{
        x: number;
        y: number;
    }>;
    scrollbars: ReturnType<typeof isOverScrollBars>;
    lastCoords: {
        x: number;
        y: number;
    };
    originalElements: Map<string, NonDeleted<ExcalidrawElement>>;
    resize: {
        handleType: MaybeTransformHandleType;
        isResizing: boolean;
        offset: {
            x: number;
            y: number;
        };
        arrowDirection: "origin" | "end";
        center: {
            x: number;
            y: number;
        };
    };
    hit: {
        element: NonDeleted<ExcalidrawElement> | null;
        allHitElements: NonDeleted<ExcalidrawElement>[];
        wasAddedToSelection: boolean;
        hasBeenDuplicated: boolean;
        hasHitCommonBoundingBoxOfSelectedElements: boolean;
    };
    withCmdOrCtrl: boolean;
    drag: {
        hasOccurred: boolean;
        offset: {
            x: number;
            y: number;
        } | null;
        origin: {
            x: number;
            y: number;
        };
        blockDragging: boolean;
    };
    eventListeners: {
        onMove: null | ReturnType<typeof throttleRAF>;
        onUp: null | ((event: PointerEvent) => void);
        onKeyDown: null | ((event: KeyboardEvent) => void);
        onKeyUp: null | ((event: KeyboardEvent) => void);
    };
    boxSelection: {
        hasOccurred: boolean;
    };
}>;
export type UnsubscribeCallback = () => void;
export type ExcalidrawMountPayload = {
    excalidrawAPI: ExcalidrawImperativeAPI;
    container: HTMLDivElement | null;
};
export type ExcalidrawImperativeAPIEventMap = {
    "editor:mount": [payload: ExcalidrawMountPayload];
    "editor:initialize": [api: ExcalidrawImperativeAPI];
    "editor:unmount": [];
};
export interface ExcalidrawImperativeAPI {
    /** Whether the editor has been unmounted and the API is no longer usable. */
    isDestroyed: boolean;
    updateScene: InstanceType<typeof App>["updateScene"];
    applyDeltas: InstanceType<typeof App>["applyDeltas"];
    mutateElement: InstanceType<typeof App>["mutateElement"];
    updateLibrary: InstanceType<typeof Library>["updateLibrary"];
    resetScene: InstanceType<typeof App>["resetScene"];
    getSceneElementsIncludingDeleted: InstanceType<typeof App>["getSceneElementsIncludingDeleted"];
    getSceneElementsMapIncludingDeleted: InstanceType<typeof App>["getSceneElementsMapIncludingDeleted"];
    history: {
        clear: InstanceType<typeof App>["resetHistory"];
        undo: InstanceType<typeof App>["undo"];
        redo: InstanceType<typeof App>["redo"];
    };
    setForceRenderAllEmbeddables: InstanceType<typeof App>["setForceRenderAllEmbeddables"];
    zoomToFit: InstanceType<typeof App>["zoomToFit"];
    refreshEditorInterface: InstanceType<typeof App>["refreshEditorInterface"];
    isTouchScreen: InstanceType<typeof App>["isTouchScreen"];
    setDesktopUIMode: InstanceType<typeof App>["setDesktopUIMode"];
    setMobileModeAllowed: InstanceType<typeof App>["setMobileModeAllowed"];
    isTrayModeEnabled: InstanceType<typeof App>["isTrayModeEnabled"];
    getColorAtScenePoint: InstanceType<typeof App>["getColorAtScenePoint"];
    startLineEditor: InstanceType<typeof App>["startLineEditor"];
    refreshAllArrows: InstanceType<typeof App>["refreshAllArrows"];
    getSceneElements: InstanceType<typeof App>["getSceneElements"];
    getAppState: () => InstanceType<typeof App>["state"];
    getFiles: () => InstanceType<typeof App>["files"];
    getName: InstanceType<typeof App>["getName"];
    scrollToContent: InstanceType<typeof App>["scrollToContent"];
    registerAction: (action: Action) => void;
    refresh: InstanceType<typeof App>["refresh"];
    setToast: InstanceType<typeof App>["setToast"];
    addFiles: (data: BinaryFileData[]) => void;
    updateContainerSize: InstanceType<typeof App>["updateContainerSize"];
    id: string;
    selectElements: (elements: readonly ExcalidrawElement[], highlightSearchResult?: boolean) => void;
    sendBackward: (elements: readonly ExcalidrawElement[]) => void;
    bringForward: (elements: readonly ExcalidrawElement[]) => void;
    sendToBack: (elements: readonly ExcalidrawElement[]) => void;
    bringToFront: (elements: readonly ExcalidrawElement[]) => void;
    setActiveTool: InstanceType<typeof App>["setActiveTool"];
    setCursor: InstanceType<typeof App>["setCursor"];
    resetCursor: InstanceType<typeof App>["resetCursor"];
    toggleSidebar: InstanceType<typeof App>["toggleSidebar"];
    getHTMLIFrameElement: InstanceType<typeof App>["getHTMLIFrameElement"];
    getEditorInterface: () => EditorInterface;
    /**
     * Disables rendering of frames (including element clipping), but currently
     * the frames are still interactive in edit mode. As such, this API should be
     * used in conjunction with view mode (props.viewModeEnabled).
     */
    updateFrameRendering: InstanceType<typeof App>["updateFrameRendering"];
    onChange: (callback: (elements: readonly ExcalidrawElement[], appState: AppState, files: BinaryFiles) => void) => UnsubscribeCallback;
    onIncrement: (callback: (event: DurableIncrement | EphemeralIncrement) => void) => UnsubscribeCallback;
    onPointerDown: (callback: (activeTool: AppState["activeTool"], pointerDownState: PointerDownState, event: React.PointerEvent<HTMLElement>) => void) => UnsubscribeCallback;
    onPointerUp: (callback: (activeTool: AppState["activeTool"], pointerDownState: PointerDownState, event: PointerEvent) => void) => UnsubscribeCallback;
    onScrollChange: (callback: (scrollX: number, scrollY: number, zoom: Zoom) => void) => UnsubscribeCallback;
    onUserFollow: (callback: (payload: OnUserFollowedPayload) => void) => UnsubscribeCallback;
    onStateChange: InstanceType<typeof App>["onStateChange"];
    onEvent: InstanceType<typeof App>["onEvent"];
}
export type FrameNameBounds = {
    x: number;
    y: number;
    width: number;
    height: number;
    angle: number;
};
export type FrameNameBoundsCache = {
    get: (frameElement: ExcalidrawFrameLikeElement | ExcalidrawMagicFrameElement) => FrameNameBounds | null;
    _cache: Map<string, FrameNameBounds & {
        zoom: AppState["zoom"]["value"];
        versionNonce: ExcalidrawFrameLikeElement["versionNonce"];
    }>;
};
export type KeyboardModifiersObject = {
    ctrlKey: boolean;
    shiftKey: boolean;
    altKey: boolean;
    metaKey: boolean;
};
export type Primitive = number | string | boolean | bigint | symbol | null | undefined;
export type JSONValue = string | number | boolean | null | object;
export type EmbedsValidationStatus = Map<ExcalidrawIframeLikeElement["id"], boolean>;
export type ElementsPendingErasure = Set<ExcalidrawElement["id"]>;
export type PendingExcalidrawElements = ExcalidrawElement[];
/** Runtime gridSize value. Null indicates disabled grid. */
export type NullableGridSize = (AppState["gridSize"] & MakeBrand<"NullableGridSize">) | null;
export type GenerateDiagramToCode = (props: {
    frame: ExcalidrawMagicFrameElement;
    children: readonly ExcalidrawElement[];
}) => MaybePromise<{
    html: string;
}>;
export type Offsets = Partial<{
    top: number;
    right: number;
    bottom: number;
    left: number;
}>;
