/**
 * Direct image labeling widget.
 *
 * Label on image widget enables creating more natural, conceptual questions
 * that involve the use of images, and enable learners to demonstrate their
 * knowledge by directly interacting with the image.
 */
import * as React from "react";
import { PerseusI18nContext } from "../../components/i18n-context";
import Marker from "./marker";
import type { DependencyProps } from "../../dependencies";
import type { Widget, WidgetProps } from "../../types";
import type { LabelImagePromptJSON } from "../../widget-ai-utils/label-image/label-image-ai-utils";
import type { InteractiveMarkerType, PerseusLabelImageWidgetOptions, PerseusLabelImageUserInput, LabelImagePublicWidgetOptions, ShowSolutions, PerseusLabelImageUserInputMarker } from "@khanacademy/perseus-core";
type PreferredPopoverDirection = "NONE" | "UP" | "DOWN" | "LEFT" | "RIGHT";
/**
 * Represents a direction vector.
 * No diagonals allowed.
 */
type Direction = {
    x: 0;
    y: 1 | -1;
} | {
    x: 1 | -1;
    y: 0;
} | {
    x: 0;
    y: 0;
};
type Point = {
    x: number;
    y: number;
};
export type OptionalAnswersMarkerType = Omit<InteractiveMarkerType, "answers"> & {
    answers?: string[];
};
type Options = Omit<PerseusLabelImageWidgetOptions, "markers"> & {
    markers: ReadonlyArray<OptionalAnswersMarkerType>;
};
type Props = WidgetProps<Options, PerseusLabelImageUserInput> & {
    analytics: DependencyProps["analytics"];
    preferredPopoverDirection?: PreferredPopoverDirection;
};
type LabelImageState = {
    activeMarkerIndex: number;
    markersInteracted: boolean;
    hideAnswers: boolean;
};
/**
 * Get user input marker with the appropriate selection state for current display mode.
 * When showing solutions, it auto-selects correct answers, or clears
 * selections for markers without answers.
 *
 * @param marker - The widget options marker (possibly with answer).
 * @param userInputMarker - The user input marker (with user selection).
 * @returns A modified version of user input, possibly with correct answer.
 */
export declare function getComputedSelectedState(marker: OptionalAnswersMarkerType, userInputMarker: PerseusLabelImageUserInputMarker, reviewMode: boolean, showSolutions?: ShowSolutions): PerseusLabelImageUserInputMarker;
export declare class LabelImage extends React.Component<Props, LabelImageState> implements Widget {
    static contextType: React.Context<import("../../components/i18n-context").I18nContextType>;
    context: React.ContextType<typeof PerseusI18nContext>;
    _markers: Array<Marker | null | undefined>;
    _mounted: boolean;
    /**
     * Test whether point is contained within triangle.
     *
     * Implementation taken from: https://stackoverflow.com/a/2049593
     */
    static pointInTriangle(p: Point, a: Point, b: Point, c: Point): boolean;
    /**
     * Determine the image side given a marker position (as percent of size).
     */
    static imageSideForMarkerPosition(x: number, y: number, preferredDirection: PreferredPopoverDirection | undefined): "bottom" | "left" | "right" | "top" | "center";
    /**
     * Calculate the next marker to navigate to, from the "this marker".
     *
     * Given a cardinal navigation direction (in the x or y axis), return the
     * next marker index to visit.
     */
    static navigateToMarkerIndex(navigateDirection: Direction, markers: ReadonlyArray<{
        x: number;
        y: number;
        showCorrectness?: "correct" | "incorrect";
    }>, thisIndex: number): number;
    constructor(props: Props);
    componentDidMount(): void;
    componentWillUnmount(): void;
    getPromptJSON(): LabelImagePromptJSON;
    handleMarkerChange(index: number, marker: PerseusLabelImageUserInput["markers"][number]): void;
    activateMarker(index: number, opened: boolean): void;
    handleMarkerKeyDown(index: number, e: React.KeyboardEvent): void;
    handleAnswerChoicesChangeForMarker(index: number, selection: ReadonlyArray<boolean>): void;
    renderMarkers(): ReadonlyArray<React.ReactNode>;
    renderInstructions(): React.ReactNode;
    /**
     * @deprecated and likely very broken API
     * [LEMS-3185] do not trust serializedState
     */
    getSerializedState(): any;
    render(): React.ReactNode;
}
declare function getStartUserInput(options: LabelImagePublicWidgetOptions): PerseusLabelImageUserInput;
/**
 * @deprecated and likely a very broken API
 * [LEMS-3185] do not trust serializedState
 */
declare function getUserInputFromSerializedState(serializedState: any): PerseusLabelImageUserInput;
declare function getCorrectUserInput(options: PerseusLabelImageWidgetOptions): PerseusLabelImageUserInput;
declare const _default: {
    name: string;
    displayName: string;
    widget: React.ForwardRefExoticComponent<Omit<Omit<PerseusLabelImageWidgetOptions, "markers"> & {
        markers: ReadonlyArray<OptionalAnswersMarkerType>;
    } & {
        trackInteraction: (extraData?: Empty | undefined) => void;
        widgetId: string;
        widgetIndex: number;
        alignment: string | null | undefined;
        static: boolean | null | undefined;
        problemNum: number | null | undefined;
        apiOptions: Readonly<Readonly<{
            isArticle?: boolean;
            onFocusChange?: (newFocusPath: import("../..").FocusPath, oldFocusPath: import("../..").FocusPath, keypadHeight?: number, focusedElement?: HTMLElement) => unknown;
            showAlignmentOptions?: boolean;
            readOnly?: boolean;
            editingDisabled?: boolean;
            answerableCallback?: (arg1: boolean) => unknown;
            getAnotherHint?: () => unknown;
            interactionCallback?: (widgetData: {
                [widgetId: string]: any;
            }) => void;
            imagePlaceholder?: React.ReactNode;
            widgetPlaceholder?: React.ReactNode;
            baseElements?: {
                Link: React.ComponentType<any>;
            };
            imagePreloader?: (dimensions: import("../../types").Dimensions) => React.ReactNode;
            trackInteraction?: (args: {
                type: string;
                id: string;
                correct?: boolean;
            } & Partial<import("../../types").TrackingGradedGroupExtraArguments> & Partial<{
                visible: number;
            }>) => void;
            customKeypad?: boolean;
            nativeKeypadProxy?: (blur: () => void) => import("@khanacademy/math-input").KeypadAPI;
            isMobile?: boolean;
            isMobileApp?: boolean;
            setDrawingAreaAvailable?: (arg1: boolean) => unknown;
            hintProgressColor?: string;
            canScrollPage?: boolean;
            editorChangeDelay?: number;
            flags?: Record<"new-radio-widget" | "image-widget-upgrade", boolean>;
        }> & {
            baseElements: NonNullable<import("../..").APIOptions["baseElements"]>;
            canScrollPage: NonNullable<import("../..").APIOptions["canScrollPage"]>;
            editorChangeDelay: NonNullable<import("../..").APIOptions["editorChangeDelay"]>;
            isArticle: NonNullable<import("../..").APIOptions["isArticle"]>;
            isMobile: NonNullable<import("../..").APIOptions["isMobile"]>;
            isMobileApp: NonNullable<import("../..").APIOptions["isMobileApp"]>;
            editingDisabled: NonNullable<import("../..").APIOptions["editingDisabled"]>;
            onFocusChange: NonNullable<import("../..").APIOptions["onFocusChange"]>;
            readOnly: NonNullable<import("../..").APIOptions["readOnly"]>;
            setDrawingAreaAvailable: NonNullable<import("../..").APIOptions["setDrawingAreaAvailable"]>;
            showAlignmentOptions: NonNullable<import("../..").APIOptions["showAlignmentOptions"]>;
        }>;
        keypadElement?: any;
        questionCompleted?: boolean;
        onFocus: (blurPath: import("../..").FocusPath) => void;
        onBlur: (blurPath: import("../..").FocusPath) => void;
        findWidgets: (criterion: import("../../types").FilterCriterion) => ReadonlyArray<Widget>;
        reviewMode: boolean;
        showSolutions?: ShowSolutions;
        handleUserInput: (newUserInput: PerseusLabelImageUserInput, cb?: () => void, silent?: boolean) => void;
        userInput: PerseusLabelImageUserInput;
        linterContext: import("@khanacademy/perseus-linter").LinterContextProps;
        containerSizeClass: import("../../util/sizing-utils").SizeClass;
    } & {
        analytics: DependencyProps["analytics"];
        preferredPopoverDirection?: PreferredPopoverDirection;
    }, keyof import("../..").PerseusDependenciesV2> & React.RefAttributes<LabelImage>>;
    isLintable: true;
    getStartUserInput: typeof getStartUserInput;
    getCorrectUserInput: typeof getCorrectUserInput;
    getUserInputFromSerializedState: typeof getUserInputFromSerializedState;
};
export default _default;
