declare global {

    type Style = {
        font: ?string;
        size: ?number;
        bold: boolean;
        italic: boolean;
        underline: boolean;
        smallCaps: boolean;
        sup: boolean;
        dropcap: boolean;
        color: string;
        opacity: number;
    };

    // Strings representing supported sources of text.
    // `stext` indicates the text was extracted directly from a PDF using mupdf.
    type TextSource = null | 'tesseract' | 'textract' | 'google_vision' | 'google_doc_ai' | 'abbyy' | 'alto' | 'stext' | 'hocr' | 'text' | 'azure_doc_intel' | 'docx';

    type FontState = {
        enableOpt: boolean;
        forceOpt: boolean;
        enableCleanToNimbusMono: boolean;
        defaultFontName: string;
        serifDefaultName: string;
        sansDefaultName: string;
        glyphSet: null | 'latin' | 'all';
        charMetrics: { [key: string]: CharMetricsFamily };
    }

    type ScribeSaveData = {
        ocr: OcrPage[];
        fontState: FontState;
        layoutRegions: LayoutPage[];
        layoutDataTables: LayoutDataTablePage[];
        annotations: AnnotationHighlight[][];
    }

    type StyleLookup = ('normal' | 'bold' | 'italic' | 'boldItalic');

    // OCR objects
    type OcrPage = import("./objects/ocrObjects.js").OcrPage;
    type OcrLine = import("./objects/ocrObjects.js").OcrLine;
    type OcrWord = import("./objects/ocrObjects.js").OcrWord;
    type OcrChar = import("./objects/ocrObjects.js").OcrChar;

    // Font objects
    type CharMetricsFont = import("./objects/charMetricsObjects.js").CharMetricsFont;
    type CharMetricsRawFamily = import("./objects/charMetricsObjects.js").CharMetricsRawFamily;
    type CharMetricsFamily = import("./objects/charMetricsObjects.js").CharMetricsFamily;
    type CharMetricsRawFont = import("./objects/charMetricsObjects.js").CharMetricsRawFont;
    type FontContainerFont = import("./containers/fontContainer.js").FontContainerFont;

    type FontContainerFamilyBuiltIn = {
        normal: FontContainerFont;
        italic: FontContainerFont;
        bold: FontContainerFont;
        boldItalic: FontContainerFont;
    };

    type FontContainerFamilyUpload = {
        normal: FontContainerFont | null;
        italic: FontContainerFont | null;
        bold: FontContainerFont | null;
        boldItalic: FontContainerFont | null;
    };

    type FontContainerFamily = FontContainerFamilyBuiltIn | FontContainerFamilyUpload;

    type FontContainer = {
        Carlito: FontContainerFamilyBuiltIn;
        Century: FontContainerFamilyBuiltIn;
        Garamond: FontContainerFamilyBuiltIn;
        Palatino: FontContainerFamilyBuiltIn;
        NimbusRoman: FontContainerFamilyBuiltIn;
        NimbusSans: FontContainerFamilyBuiltIn;
        NimbusMono: FontContainerFamilyBuiltIn;
        [key: string]: FontContainerFamily;
    };

    type fontSrcBuiltIn = {
        normal: ArrayBuffer;
        italic: ArrayBuffer;
        bold: ArrayBuffer;
        boldItalic: ArrayBuffer;
    };

    type fontSrcUpload = {
        normal: ArrayBuffer | null;
        italic: ArrayBuffer | null;
        bold: ArrayBuffer | null;
        boldItalic: ArrayBuffer | null;
    };

    type opentypeFont = import("./font-parser/src/index.js").Font;
    type opentypeGlyph = import("./font-parser/src/index.js").Glyph;
    type GeneralScheduler = import("./generalWorkerMain.js").GeneralScheduler;

    // Image objects
    type ImageWrapper = import("./objects/imageObjects.js").ImageWrapper;

    /**
     * Information from the IHDR chunk of a PNG file.
     */
    type PngIHDRInfo = {
        /** Image width in pixels. */
        width: number;
        /** Image height in pixels. */
        height: number;
        /** Bits per sample or per palette index. */
        bitDepth: number;
        /** Color type (e.g., grayscale, RGB, palette). */
        colorType: number;
        /** Compression method (always 0 for PNG). */
        compressionMethod: number;
        /** Filter method (always 0 for PNG). */
        filterMethod: number;
        /** Interlace method (0 for none, 1 for Adam7). */
        interlaceMethod: number;
    };

    type dims = {
        height: number;
        width: number;
    };

    type bbox = {
        left: number;
        right: number;
        top: number;
        bottom: number;
    };

    type PageMetrics = import("./objects/pageMetricsObjects.js").PageMetrics;

    type EvalMetrics = {
        total: number;
        correct: number;
        incorrect: number;
        missed: number;
        extra: number;
        correctLowConf: number;
        incorrectHighConf: number;
    };
    /**
     * Represents a comparison debug object with image data and error metrics.
     * Raw errors are calculated purely based on visual overlap. Words where most pixels overlap with the underlying image will have low raw error.
     * Adjusted errors are calculated by applying ad-hoc adjustments to raw errors. The intent of these adjustments is to penalize patterns of letters
     * that are visually similar to other letters but unlikely to occur in correct recognition results.
     */
    type CompDebugBrowser = {
        context: 'browser';
        imageRaw: Blob; // The raw image blob.
        imageA: Blob; // The first image blob for comparison.
        imageB: Blob; // The second image blob for comparison.
        dims: dims; // Dimensions object specifying size or other dimensional data.
        errorRawA: number; // Raw error of "A" words, calculated purely based on visual overlap.
        errorRawB: number; // Raw error of "B" words, similar to errorRawA.
        errorAdjA: number | null; // Adjusted error of "A" words. Null until calculated.
        errorAdjB: number | null; // Adjusted error of "B" words. Null until calculated.
    };

    /**
     * Represents a comparison debug object with image data and error metrics.
     * Raw errors are calculated purely based on visual overlap. Words where most pixels overlap with the underlying image will have low raw error.
     * Adjusted errors are calculated by applying ad-hoc adjustments to raw errors. The intent of these adjustments is to penalize patterns of letters
     * that are visually similar to other letters but unlikely to occur in correct recognition results.
     */
    type CompDebugNode = {
        context: 'node';
        imageRaw: import('canvas').Image; // The raw image.
        imageA: import('canvas').Image; // The first image for comparison.
        imageB: import('canvas').Image; // The second image for comparison.
        dims: dims; // Dimensions object specifying size or other dimensional data.
        errorRawA: number; // Raw error of "A" words, calculated purely based on visual overlap.
        errorRawB: number; // Raw error of "B" words, similar to errorRawA.
        errorAdjA: number | null; // Adjusted error of "A" words. Null until calculated.
        errorAdjB: number | null; // Adjusted error of "B" words. Null until calculated.
    };

    type ProgressMessage = ProgressMessageConvert | ProgressMessageGeneral | ProgressMessageRecognize;

    type ProgressMessageGeneral = {
        type: 'export' | 'importImage' | 'importPDF' | 'render';
        n: number;
        info: {};
    }

    type ProgressMessageConvert = {
        type: 'convert';
        n: number;
        info: {
            engineName: string;
        };
    }

    type ProgressMessageRecognize = {
        type: 'recognize';
        n?: number;
        info?: {
            status?: string;
            engineName?: string;
            elapsedMs?: number;
            responsesReceived?: number;
            timestamp?: number;
        };
    }

    type FileNode = import("./import/nodeAdapter.js").FileNode;

    type AnnotationHighlight = {
        bbox: bbox;
        color: string;
        opacity: number;
        groupId: string;
        comment?: string;
        quads?: bbox[];
    };

    // Layout objects
    type LayoutPage = import("./objects/layoutObjects.js").LayoutPage;
    type LayoutDataTablePage = import("./objects/layoutObjects.js").LayoutDataTablePage;
    type LayoutDataTable = import("./objects/layoutObjects.js").LayoutDataTable;
    type LayoutDataColumn = import("./objects/layoutObjects.js").LayoutDataColumn;
    type LayoutRegion = import("./objects/layoutObjects.js").LayoutRegion;

    interface Point {
        x: number;
        y: number;
    }

    interface Polygon {
        br: Point;
        bl: Point;
        tr: Point;
        tl: Point;
    }

    interface TextractBoundingBox {
        Width: number;
        Height: number;
        Left: number;
        Top: number;
    }

    interface TextractPoint {
        X: number;
        Y: number;
    }

    type PdfFontInfo = {
        type: number;
        index: number;
        name: string;
        objN: number;
        opentype: opentypeFont;
    };

    type PdfFontFamily = {
        normal?: PdfFontInfo;
        italic?: PdfFontInfo;
        bold?: PdfFontInfo;
        boldItalic?: PdfFontInfo;
        [style: string]: PdfFontInfo | undefined;
    };

    interface TextractGeometry {
        BoundingBox: TextractBoundingBox;
        Polygon: TextractPoint[];
        RotationAngle: number;
    }

    interface Relationship {
        Type: string;
        Ids: string[];
    }

    interface TextractBlock {
        BlockType: "WORD" | "LINE" | "PAGE" | "KEY_VALUE_SET" | "CELL" | "MERGED_CELL" | "SELECTION_ELEMENT" | "TABLE";
        Confidence: number;
        Text: string;
        TextType: "PRINTED" | "HANDWRITING";
        Geometry: TextractGeometry;
        Id: string;
        Page?: number;
        Relationships?: Relationship[];
    }

    // Google Vision types
    interface GoogleVisionVertex {
        x: number;
        y: number;
    }

    interface GoogleVisionBoundingPoly {
        vertices: GoogleVisionVertex[];
        normalizedVertices: GoogleVisionVertex[];
    }

    interface GoogleVisionDetectedLanguage {
        languageCode: string;
        confidence: number;
    }

    interface GoogleVisionDetectedBreak {
        type: 'UNKNOWN' | 'SPACE' | 'SURE_SPACE' | 'EOL_SURE_SPACE' | 'HYPHEN' | 'LINE_BREAK';
        isPrefix: boolean;
    }

    interface GoogleVisionTextProperty {
        detectedLanguages: GoogleVisionDetectedLanguage[];
        detectedBreak?: GoogleVisionDetectedBreak;
    }

    interface GoogleVisionSymbol {
        property?: GoogleVisionTextProperty;
        boundingBox: GoogleVisionBoundingPoly;
        text: string;
        confidence: number;
    }

    interface GoogleVisionWord {
        property?: GoogleVisionTextProperty;
        boundingBox: GoogleVisionBoundingPoly;
        symbols: GoogleVisionSymbol[];
        confidence: number;
    }

    interface GoogleVisionParagraph {
        property?: GoogleVisionTextProperty;
        boundingBox: GoogleVisionBoundingPoly;
        words: GoogleVisionWord[];
        confidence: number;
    }

    interface GoogleVisionBlock {
        property?: GoogleVisionTextProperty;
        boundingBox: GoogleVisionBoundingPoly;
        paragraphs: GoogleVisionParagraph[];
        blockType: 'UNKNOWN' | 'TEXT' | 'TABLE' | 'PICTURE' | 'RULER' | 'BARCODE';
        confidence: number;
    }

    interface GoogleVisionPage {
        property?: GoogleVisionTextProperty;
        width: number;
        height: number;
        blocks: GoogleVisionBlock[];
        confidence: number;
    }

    interface GoogleVisionFullTextAnnotation {
        pages: GoogleVisionPage[];
        text: string;
    }

    // Recognition model types (for custom/external recognition models)
    type RecognitionOutputFormat = 'textract' | 'google_vision' | 'google_doc_ai' | 'azure_doc_intel' | 'hocr' | 'abbyy' | 'alto' | 'stext' | 'text';

    type RecognitionResult = {
        success: boolean;
        rawData?: string;
        format: RecognitionOutputFormat | string;
        error?: Error;
    };

    interface RecognitionModelConfig {
        name: string;
        outputFormat: RecognitionOutputFormat | null;
        rateLimit?: { tps: number } | { rpm: number };
    }

    interface RecognitionModel {
        config: RecognitionModelConfig;
        recognizeImage(imageData: Uint8Array | ArrayBuffer, options?: any): Promise<RecognitionResult>;
        recognizeDocument?(documentData: Uint8Array | ArrayBuffer, options?: any): Promise<RecognitionResult>;
        convertPage?(rawData: string, n: number): Promise<{
            pageObj: OcrPage;
            dataTables: LayoutDataTablePage;
            warn: object;
            langSet: Set<string>;
            fontSet: Set<string>;
        }>;
        isThrottlingError?(error: Error): boolean;
    }

    // Azure Document Intelligence types
    interface AzureDocIntelSpan {
        offset: number;
        length: number;
    }

    interface AzureDocIntelWord {
        content: string;
        polygon: number[];
        span: AzureDocIntelSpan;
        confidence: number;
    }

    interface AzureDocIntelLine {
        content: string;
        polygon: number[];
        spans: AzureDocIntelSpan[];
    }

    interface AzureDocIntelStyle {
        isHandwritten?: boolean;
        spans: AzureDocIntelSpan[];
        confidence: number;
    }

    interface AzureDocIntelPage {
        pageNumber: number;
        angle: number;
        width: number;
        height: number;
        unit: 'pixel' | 'inch';
        words: AzureDocIntelWord[];
        lines: AzureDocIntelLine[];
        spans: AzureDocIntelSpan[];
    }

    interface AzureDocIntelAnalyzeResult {
        apiVersion: string;
        modelId: string;
        content: string;
        pages: AzureDocIntelPage[];
        styles: AzureDocIntelStyle[];
    }

    interface AzureDocIntelResponse {
        status: 'succeeded' | 'failed' | 'running';
        createdDateTime: string;
        lastUpdatedDateTime: string;
        analyzeResult: AzureDocIntelAnalyzeResult;
    }

    // Tesseract types
    type TessOutputFormats = {
        text: boolean;
        blocks: boolean;
        layoutBlocks: boolean;
        hocr: boolean;
        tsv: boolean;
        box: boolean;
        unlv: boolean;
        osd: boolean;
        imageColor: boolean;
        imageGrey: boolean;
        imageBinary: boolean;
        debug: boolean;
    };

    type TessRecognizeOptions = {
        rectangle: TessRectangle;
        rotateAuto: boolean;
        rotateRadians: number;
    };

    type TessRecognizeResult = {
        jobId: string;
        data: TessPage;
    };

    type TessRectangle = {
        left: number;
        top: number;
        width: number;
        height: number;
    };

    type TessImageLike = string | Blob;

    type TessBaseline = {
        x0: number;
        y0: number;
        x1: number;
        y1: number;
        has_baseline: boolean;
    };

    type TessRowAttributes = {
        ascenders: number;
        descenders: number;
        rowHeight: number;
    };

    type TessBbox = {
        x0: number;
        y0: number;
        x1: number;
        y1: number;
    };

    type TessChoice = {
        text: string;
        confidence: number;
    };

    type TessSymbol = {
        choices: TessChoice[];
        image: any;
        text: string;
        confidence: number;
        baseline: TessBaseline;
        bbox: TessBbox;
        is_superscript: boolean;
        is_subscript: boolean;
        is_dropcap: boolean;
        word: TessWord;
        line: TessLine;
        paragraph: TessParagraph;
        block: TessBlock;
        page: TessPage;
    };

    type TessWord = {
        symbols: TessSymbol[];
        choices: TessChoice[];
        text: string;
        confidence: number;
        baseline: TessBaseline;
        bbox: TessBbox;
        is_numeric: boolean;
        in_dictionary: boolean;
        direction: string;
        language: string;
        is_bold: boolean;
        is_italic: boolean;
        is_underlined: boolean;
        is_monospace: boolean;
        is_serif: boolean;
        is_smallcaps: boolean;
        font_size: number;
        font_id: number;
        font_name: string;
        line: TessLine;
        paragraph: TessParagraph;
        block: TessBlock;
        page: TessPage;
    };

    type TessLine = {
        words: TessWord[];
        text: string;
        confidence: number;
        baseline: TessBaseline;
        rowAttributes: TessRowAttributes;
        bbox: TessBbox;
        paragraph: TessParagraph;
        block: TessBlock;
        page: TessPage;
        symbols: TessSymbol[];
    };

    type TessParagraph = {
        lines: TessLine[];
        text: string;
        confidence: number;
        baseline: TessBaseline;
        bbox: TessBbox;
        is_ltr: boolean;
        block: TessBlock;
        page: TessPage;
        words: TessWord[];
        symbols: TessSymbol[];
    };

    type TessBlock = {
        paragraphs: TessParagraph[];
        text: string;
        confidence: number;
        baseline: TessBaseline;
        bbox: TessBbox;
        blocktype: string;
        polygon: any;
        page: TessPage;
        lines: TessLine[];
        words: TessWord[];
        symbols: TessSymbol[];
    };

    type TessPage = {
        blocks: TessBlock[] | null;
        confidence: number;
        lines: TessLine[];
        oem: string;
        osd: string;
        paragraphs: TessParagraph[];
        psm: string;
        symbols: TessSymbol[];
        text: string;
        version: string;
        words: TessWord[];
        hocr: string | null;
        tsv: string | null;
        box: string | null;
        unlv: string | null;
        sd: string | null;
        imageColor: string | null;
        imageGrey: string | null;
        imageBinary: string | null;
        rotateRadians: number | null;
        debug: string | null;
        debugVis: string | null;
    };

}

export { };

