import { FlowMode, Fragment, PageMargins, PageNumberChapterSeparator, PageNumberFormat, SourceAnchor, ResolvedLayout, ResolvedPage, ResolvedPaintItem, LayoutSourceIdentity, LayoutStoryLocator } from '../../../contracts/src/index.js';
import { PageStyles } from './styles.js';
import { PaintSnapshotStructuredContentBlockEntity, PaintSnapshotStructuredContentInlineEntity } from './sdt/snapshot.js';
export type { PaintSnapshotStructuredContentBlockEntity, PaintSnapshotStructuredContentInlineEntity, } from './sdt/snapshot.js';
/**
 * Layout mode for document rendering.
 * @typedef {('vertical'|'horizontal'|'book')} LayoutMode
 * - 'vertical': Standard page-by-page vertical layout (default)
 * - 'horizontal': Pages arranged horizontally side-by-side
 * - 'book': Book-style layout with facing pages
 */
export type LayoutMode = 'vertical' | 'horizontal' | 'book';
export type { FlowMode } from '../../../contracts/src/index.js';
/**
 * Interface for position mapping from ProseMirror transactions.
 * Used to efficiently update DOM position attributes without full re-render.
 */
export interface PositionMapping {
    /** Transform a position from old to new document coordinates */
    map(pos: number, bias?: number): number;
    /** Array of step maps - length indicates transaction complexity */
    readonly maps: readonly unknown[];
}
export type RenderedLineInfo = {
    el: HTMLElement;
    top: number;
    height: number;
};
/**
 * Input to `DomPainter.paint()`.
 *
 * The painter consumes only `resolvedLayout`. All fragment, geometry, and
 * page-level metadata it needs is reachable from `ResolvedPaintItem.fragment`
 * back-pointers and `ResolvedPage` fields.
 */
export type DomPainterInput = {
    resolvedLayout: ResolvedLayout;
};
export type PageDecorationPayload = {
    fragments: Fragment[];
    /** Resolved items aligned 1:1 with `fragments`. Same length, same order. */
    items: ResolvedPaintItem[];
    /** Minimum Y coordinate from layout; negative when content extends above y=0. */
    minY?: number;
    height: number;
    /** Optional measured content height to aid bottom alignment in footers. */
    contentHeight?: number;
    /** Decoration band origin in page-local Y. Producer is the sole source of truth (SD-2957). */
    offset: number;
    marginLeft?: number;
    contentWidth?: number;
    headerFooterRefId?: string;
    sectionType?: string;
    /** True while this rendered header/footer story is the active editing surface. */
    isActiveHeaderFooter?: boolean;
    box?: {
        x: number;
        y: number;
        width: number;
        height: number;
    };
    hitRegion?: {
        x: number;
        y: number;
        width: number;
        height: number;
    };
};
/**
 * Provider function for page decorations (headers and footers).
 * Called for each page to generate header or footer content.
 *
 * @param {number} pageNumber - The page number (1-indexed)
 * @param {PageMargins} [pageMargins] - Page margin configuration
 * @param {ResolvedPage} [page] - Resolved page from the layout
 * @returns {PageDecorationPayload | null} Decoration payload containing fragments and layout info, or null if no decoration
 */
export type PageDecorationProvider = (pageNumber: number, pageMargins?: PageMargins, page?: ResolvedPage) => PageDecorationPayload | null;
/**
 * Ruler configuration options for per-page rulers.
 */
export type RulerOptions = {
    /** Whether to show rulers on pages (default: false) */
    enabled?: boolean;
    /** Whether rulers are interactive with drag handles (default: false for per-page) */
    interactive?: boolean;
    /** Callback when margin handle drag ends (only used if interactive) */
    onMarginChange?: (side: 'left' | 'right', marginInches: number) => void;
};
type PainterOptions = {
    pageStyles?: PageStyles;
    layoutMode?: LayoutMode;
    flowMode?: FlowMode;
    /** Gap between pages in pixels (default: 24px for vertical, 20px for horizontal) */
    pageGap?: number;
    headerProvider?: PageDecorationProvider;
    footerProvider?: PageDecorationProvider;
    virtualization?: {
        enabled?: boolean;
        window?: number;
        overscan?: number;
        /** Virtualization gap override (defaults to 72px; independent of pageGap). */
        gap?: number;
        paddingTop?: number;
    };
    /** Per-page ruler options */
    ruler?: RulerOptions;
    /** Called with the paint snapshot after each paint cycle completes. */
    onPaintSnapshot?: (snapshot: PaintSnapshot) => void;
    /** Render nonprinting formatting marks such as spaces, tabs, and paragraph marks. */
    showFormattingMarks?: boolean;
    /** Built-in SDT chrome rendering mode. */
    contentControlsChrome?: 'default' | 'none';
};
/**
 * Rendering context passed to fragment renderers containing page metadata.
 * Provides information about the current page position and section for dynamic content like page numbers.
 *
 * @typedef {Object} FragmentRenderContext
 * @property {number} pageNumber - Current page number (1-indexed)
 * @property {number} totalPages - Total number of pages in the document
 * @property {'body'|'header'|'footer'} section - Document section being rendered
 * @property {string} [pageNumberText] - Optional formatted page number text (e.g., "Page 1 of 10")
 * @property {number} [displayPageNumber] - Section-aware numeric page value before formatting
 * @property {number} [sectionPageCount] - Physical page count in the current section
 */
export type FragmentRenderContext = {
    pageNumber: number;
    totalPages: number;
    section: 'body' | 'header' | 'footer';
    story?: LayoutStoryLocator;
    pageNumberText?: string;
    displayPageNumber?: number;
    pageNumberFormat?: PageNumberFormat;
    pageNumberChapterText?: string;
    pageNumberChapterSeparator?: PageNumberChapterSeparator;
    sectionPageCount?: number;
    pageIndex?: number;
};
export type PaintSnapshotLineStyle = {
    paddingLeftPx?: number;
    paddingRightPx?: number;
    textIndentPx?: number;
    marginLeftPx?: number;
    marginRightPx?: number;
    leftPx?: number;
    topPx?: number;
    widthPx?: number;
    heightPx?: number;
    display?: string;
    position?: string;
    textAlign?: string;
    justifyContent?: string;
};
export type PaintSnapshotMarkerStyle = {
    text?: string;
    leftPx?: number;
    widthPx?: number;
    paddingRightPx?: number;
    display?: string;
    position?: string;
    textAlign?: string;
    fontWeight?: string;
    fontStyle?: string;
    color?: string;
    sourceAnchor?: SourceAnchor;
};
export type PaintSnapshotTabStyle = {
    widthPx?: number;
    leftPx?: number;
    position?: string;
    borderBottom?: string;
};
export type PaintSnapshotAnnotationEntity = {
    element: HTMLElement;
    pageIndex: number;
    pmStart?: number;
    pmEnd?: number;
    fieldId?: string;
    fieldType?: string;
    type?: string;
    layoutSourceIdentity?: LayoutSourceIdentity;
};
export type PaintSnapshotImageEntity = {
    element: HTMLElement;
    pageIndex: number;
    kind: 'inline' | 'fragment';
    pmStart?: number;
    pmEnd?: number;
    blockId?: string;
    sourceAnchor?: SourceAnchor;
    layoutSourceIdentity?: LayoutSourceIdentity;
};
export type PaintSnapshotEntities = {
    annotations: PaintSnapshotAnnotationEntity[];
    structuredContentBlocks: PaintSnapshotStructuredContentBlockEntity[];
    structuredContentInlines: PaintSnapshotStructuredContentInlineEntity[];
    images: PaintSnapshotImageEntity[];
};
export type PaintSnapshotLine = {
    index: number;
    inTableFragment: boolean;
    inTableParagraph: boolean;
    style: PaintSnapshotLineStyle;
    markers?: PaintSnapshotMarkerStyle[];
    tabs?: PaintSnapshotTabStyle[];
    sourceAnchor?: SourceAnchor;
    layoutSourceIdentity?: LayoutSourceIdentity;
};
export type PaintSnapshotPage = {
    index: number;
    pageNumber?: number;
    lineCount: number;
    lines: PaintSnapshotLine[];
};
export type PaintSnapshot = {
    formatVersion: 1;
    pageCount: number;
    lineCount: number;
    markerCount: number;
    tabCount: number;
    pages: PaintSnapshotPage[];
    entities: PaintSnapshotEntities;
};
/**
 * Stamp the editor-neutral layout-identity dataset (prep-001).
 *
 * Additive only — runs alongside the legacy `data-pm-*` / `data-block-id`
 * writes in `applyFragmentFrame` and `applyResolvedFragmentFrame`. v1
 * consumers still read PM-shaped datasets; future editor-neutral consumers
 * read `data-layout-fragment-id` / `data-layout-story` / `data-layout-block-ref`
 * here.
 */
export declare function applyLayoutIdentityDataset(element: HTMLElement, identity: LayoutSourceIdentity | undefined): void;
/**
 * DOM-based document painter that renders layout fragments to HTML elements.
 * Manages page rendering, virtualization, headers/footers, and incremental updates.
 *
 * @class DomPainter
 *
 * @remarks
 * The DomPainter is responsible for:
 * - Rendering layout fragments (paragraphs, lists, images, tables, drawings) to DOM elements
 * - Managing page-level DOM structure and styling
 * - Providing virtualization for large documents (vertical mode only)
 * - Handling headers and footers via PageDecorationProvider
 * - Incremental re-rendering when only specific blocks change
 * - Hyperlink rendering with security sanitization and accessibility
 *
 * @example
 * ```typescript
 * const painter = new DomPainter(blocks, measures, {
 *   layoutMode: 'vertical',
 *   pageStyles: { width: '8.5in', height: '11in' }
 * });
 * painter.mount(document.getElementById('editor-container'));
 * painter.render(layout);
 * ```
 */
export declare class DomPainter {
    private readonly options;
    private mount;
    private doc;
    private pageStates;
    private currentLayout;
    private changedBlocks;
    private readonly layoutMode;
    private readonly isSemanticFlow;
    private headerProvider?;
    private footerProvider?;
    private totalPages;
    private sectionPageCounts;
    private linkIdCounter;
    private sdtLabelsRendered;
    /**
     * WeakMap storing tooltip data for hyperlink elements before DOM insertion.
     * Uses WeakMap to prevent memory leaks - entries are automatically garbage collected
     * when the corresponding element is removed from memory.
     * @private
     */
    private pendingTooltips;
    private pageGap;
    private virtualEnabled;
    private virtualWindow;
    private virtualOverscan;
    private virtualGap;
    private virtualPaddingTop;
    private topSpacerEl;
    private bottomSpacerEl;
    private virtualPagesEl;
    private virtualGapSpacers;
    private virtualPinnedPages;
    private virtualMountedKey;
    private pageIndexToState;
    private virtualHeights;
    private virtualOffsets;
    private virtualStart;
    private virtualEnd;
    private layoutVersion;
    private layoutEpoch;
    private processedLayoutVersion;
    /** Current transaction mapping for position updates (null if no mapping or complex transaction) */
    private currentMapping;
    private onScrollHandler;
    private onWindowScrollHandler;
    private onResizeHandler;
    /** CSS zoom/scale factor applied to the mount element via transform: scale(). Defaults to 1 (no zoom). */
    private zoomFactor;
    /**
     * External scroll container (an ancestor element with overflow-y: auto/scroll).
     * When set, updateVirtualWindow() uses this element's position to compute scrollY
     * relative to the scroll container instead of relative to the browser viewport.
     * This fixes the scroll offset calculation when SuperDoc is mounted inside a
     * wrapper div that owns scrolling rather than the window.
     */
    private scrollContainer;
    /**
     * Cached offset (in px) from the scroll container's content top to the mount's top.
     * Used for stable scrollY calculation that avoids feedback loops from spacer DOM mutations.
     * Invalidated when the mount, scroll container, or zoom changes.
     */
    private scrollContainerMountOffset;
    private paintSnapshotBuilder;
    private lastPaintSnapshot;
    private onPaintSnapshotCallback;
    private mountedPageIndices;
    /** Resolved layout for the next-gen paint pipeline. */
    private resolvedLayout;
    private showFormattingMarks;
    private contentControlsChrome;
    constructor(options?: PainterOptions);
    setShowFormattingMarks(showFormattingMarks: boolean): void;
    setProviders(header?: PageDecorationProvider, footer?: PageDecorationProvider): void;
    private applyFormattingMarksClass;
    private invalidateRenderedContent;
    /**
     * Pins specific page indices so they remain mounted when virtualization is enabled.
     *
     * Used by selection/drag logic to ensure endpoints can be resolved via DOM
     * even when they fall outside the current scroll window.
     */
    setVirtualizationPins(pageIndices: number[] | null | undefined): void;
    /**
     * Sets the CSS zoom/scale factor applied to the mount element.
     *
     * When the mount element has `transform: scale(zoom)`, getBoundingClientRect()
     * returns screen-space coordinates (scaled), but internal layout offsets are in
     * unscaled layout space. This factor is used to convert between the two spaces
     * during virtualization window calculations.
     *
     * @param zoom - The zoom/scale factor (e.g., 0.75 for 75% zoom). Defaults to 1.
     */
    setZoom(zoom: number): void;
    /**
     * Sets the external scroll container element.
     *
     * When the scroll container is an ancestor element (e.g., a wrapper div with
     * overflow-y: auto), the default scrollY calculation using mount.getBoundingClientRect()
     * relative to the viewport produces an offset equal to the scroll container's distance
     * from the viewport top. This causes the virtualization window to be misaligned with the
     * actual visible area.
     *
     * Setting the scroll container allows updateVirtualWindow() to compute scrollY relative
     * to the scroll container instead, eliminating this offset.
     *
     * @param el - The scroll container element, or null to clear.
     */
    setScrollContainer(el: HTMLElement | null): void;
    /** Returns the resolved page for a given index, or null if resolved data is unavailable. */
    private getResolvedPage;
    /**
     * Returns the latest painter snapshot captured during the last paint cycle.
     */
    getPaintSnapshot(): PaintSnapshot | null;
    /**
     * Returns the page indices that are currently mounted in the DOM.
     *
     * Unlike paint snapshots, this reflects virtualization remounts that happen
     * during scroll without waiting for a full paint cycle.
     */
    getMountedPageIndices(): number[];
    private createAllPageIndices;
    private setMountedPageIndices;
    private emitPaintSnapshot;
    private beginPaintSnapshot;
    private finalizePaintSnapshotFromBuilder;
    private capturePaintSnapshotLine;
    private collectPaintSnapshotFromDomRoot;
    paint(input: DomPainterInput, mount: HTMLElement, mapping?: PositionMapping): void;
    private renderVirtualized;
    private ensureVirtualizationSetup;
    private configureSpacerElement;
    private bindVirtualizationHandlers;
    private computeVirtualMetrics;
    private topOfIndex;
    private contentTotalHeight;
    private getMountPaddingTopPx;
    /**
     * Public method to trigger virtualization window update on scroll.
     * Call this from external scroll handlers when the scroll container
     * is different from the painter's mount element.
     */
    onScroll(): void;
    private updateVirtualWindow;
    private updateSpacers;
    private updateSpacersForMountedPages;
    private clearGapSpacers;
    private renderHorizontal;
    private renderBookMode;
    private renderPage;
    /**
     * Render a ruler element for a page.
     *
     * Creates a horizontal ruler with tick marks and optional interactive margin handles.
     * The ruler is positioned at the top of the page and displays inch measurements.
     *
     * @param pageWidthPx - Page width in pixels
     * @param page - Page data containing margins and optional size information
     * @returns Ruler element, or null if this.doc is unavailable or page margins are missing
     *
     * Side effects:
     * - Creates DOM elements and applies inline styles
     * - May invoke the onMarginChange callback if interactive mode is enabled
     *
     * Fallback behavior:
     * - Uses DEFAULT_PAGE_HEIGHT_PX (1056px = 11 inches) if page.size.h is not available
     * - Defaults margins to 0 if not explicitly provided
     */
    private renderPageRuler;
    private renderColumnSeparators;
    private getColumnSeparatorPositions;
    private renderDecorationsForPage;
    /**
     * Check if an anchored fragment has vRelativeFrom === 'page'.
     * Used to determine special Y positioning for page-relative anchored media
     * in header/footer decoration sections.
     */
    private isPageRelativeAnchoredFragment;
    /**
     * Header/footer layout emits normalized anchor Y coordinates:
     * - headers: local to the header container origin
     * - footers: local to the top of the footer band (pageHeight - bottomMargin)
     *
     * Footer containers can grow upward when content overflows the reserved footer
     * band, so their top edge is not always the same as the footer band origin.
     * This helper returns the page-space origin that normalized anchor Y values
     * are measured from.
     */
    private getDecorationAnchorPageOriginY;
    private renderDecorationSection;
    private resetState;
    private getSectionPageCount;
    private fullRender;
    private patchLayout;
    private patchPage;
    /**
     * Updates data-pm-start/data-pm-end attributes on all elements within a fragment
     * using the transaction's mapping. Skips header/footer content (separate PM coordinate space).
     * Also skips fragments that end before the edit point (their positions don't change).
     */
    private updatePositionAttributes;
    private createPageState;
    private applySemanticPageOverrides;
    private getEffectivePageStyles;
    private renderFragment;
    /**
     * Renders a paragraph fragment with defensive error handling.
     * Falls back to error placeholder on rendering errors to prevent full paint failure.
     *
     * @param fragment - The paragraph fragment to render
     * @param context - Rendering context with page and column information
     * @param sdtBoundary - Optional SDT boundary overrides for multi-fragment containers
     * @returns HTMLElement containing the rendered fragment or error placeholder
     */
    private renderParagraphFragment;
    /**
     * Creates an error placeholder element for failed fragment renders.
     * Prevents entire paint operation from failing due to single fragment error.
     *
     * @param blockId - The block ID that failed to render
     * @param error - The error that occurred
     * @returns HTMLElement showing the error
     */
    private createErrorPlaceholder;
    private renderImageFragment;
    /**
     * Optionally wrap an image element in an anchor for DrawingML hyperlinks (a:hlinkClick).
     *
     * When `hyperlink` is present and its URL passes sanitization, returns an
     * `<a class="superdoc-link">` wrapping `imageEl`. The existing EditorInputManager
     * click-delegation on `a.superdoc-link` handles both viewing-mode navigation and
     * editing-mode event dispatch automatically, with no extra wiring needed here.
     *
     * When `hyperlink` is absent or the URL fails sanitization the original element
     * is returned unchanged.
     *
     * @param imageEl   - The image element (img or span wrapper) to potentially wrap.
     * @param hyperlink - Hyperlink metadata from the ImageBlock/ImageRun, or undefined.
     * @param display   - CSS display value for the anchor: 'block' for fragment images,
     *                    'inline-block' for inline runs.
     */
    private buildImageHyperlinkAnchor;
    private renderDrawingFragment;
    private renderDrawingContent;
    private createVectorShapeElement;
    /**
     * Apply fill and stroke styles to a fallback shape container
     */
    private applyFallbackShapeStyle;
    private hasShapeTextContent;
    private createShapeTextElement;
    private shouldUseWordArtTextRenderer;
    private createWordArtTextElement;
    private buildWordArtLines;
    private resolveShapeTextPartText;
    private getWordArtTextAnchor;
    private getWordArtTextX;
    private applyWordArtTextFormatting;
    /**
     * Create a fallback text element for shapes without SVG
     * @param textContent - Text content with formatting
     * @param textAlign - Horizontal text alignment
     * @param textVerticalAlign - Vertical text alignment (top, center, bottom)
     * @param textInsets - Text insets in pixels (top, right, bottom, left)
     * @param groupScaleX - Scale factor applied by parent group (for counter-scaling)
     * @param groupScaleY - Scale factor applied by parent group (for counter-scaling)
     */
    private createFallbackTextElement;
    private tryCreatePresetSvg;
    /**
     * Creates an SVG string from custom geometry path data (a:custGeom).
     * Each path in the custom geometry has its own coordinate space (w × h) which is
     * mapped to the shape's actual dimensions via the SVG viewBox.
     */
    private tryCreateCustomGeometrySvg;
    private parseSafeSvg;
    private stripUnsafeSvgContent;
    private getEffectExtentMetrics;
    private applyLineEnds;
    private findLineEndTarget;
    private ensureSvgDefs;
    private appendLineEndMarker;
    private createLineEndShape;
    private sanitizeSvgId;
    private applyVectorShapeTransforms;
    private createShapeGroupElement;
    private createGroupChildContent;
    private createDrawingPlaceholder;
    /**
     * Create an SVG chart element from a ChartDrawing block.
     * Delegates to the chart-renderer module for clean separation.
     */
    private createChartElement;
    private resolveTableRenderData;
    private renderTableFragment;
    private renderLine;
    private createRunRenderContext;
    /**
     * Updates an existing fragment element's position and dimensions in place.
     * Used during incremental updates to efficiently reposition fragments without full re-render.
     *
     * @param el - The HTMLElement representing the fragment to update
     * @param fragment - The fragment data containing updated position and dimensions
     * @param section - The document section ('body', 'header', 'footer') containing this fragment.
     *                  Affects PM position validation - only body sections validate PM positions.
     *                  If undefined, defaults to 'body' section behavior.
     */
    private updateFragmentElement;
    /**
     * Applies fragment positioning, dimensions, and metadata to an HTML element.
     *
     * @param el - The HTMLElement to apply fragment properties to
     * @param fragment - The fragment data containing position, dimensions, and PM position information
     * @param section - The document section ('body', 'header', 'footer') containing this fragment.
     *                  Controls PM position validation behavior:
     *                  - 'body' or undefined: PM positions are validated and required for paragraph fragments
     *                  - 'header' or 'footer': PM position validation is skipped (these sections have separate PM coordinate spaces)
     *                  When undefined, defaults to 'body' section behavior (validation enabled).
     */
    private applyFragmentFrame;
    /**
     * Applies PM position data attributes from a legacy Fragment.
     * Extracted from applyFragmentFrame for use in the resolved wrapper path.
     * When a resolvedItem is provided, its fields take precedence over fragment fields.
     */
    private applyFragmentPmAttributes;
    /**
     * Applies fragment wrapper positioning from a ResolvedFragmentItem.
     * Uses resolved data for spatial properties and delegates PM attributes to the legacy path.
     */
    private isAnchoredMediaFragment;
    private shouldRenderBehindPageContent;
    private isHeaderWordArtWatermark;
    private isVmlTextWatermarkImage;
    private applyHeaderFooterTextWatermarkPreviewOpacity;
    /**
     * Only anchored images and drawings participate in explicit wrapper stacking.
     * Inline media intentionally rely on DOM order to preserve legacy paint order.
     */
    private resolveFragmentWrapperZIndex;
    private applyFragmentWrapperZIndex;
    private applyResolvedFragmentFrame;
    /**
     * Estimates the height of a fragment when explicit height is not available.
     *
     * This method provides fallback height calculations for footer bottom-alignment
     * from resolved layout data, or using the fragment's height property for
     * tables, images, and drawings.
     *
     * @param fragment - The fragment to estimate height for
     * @returns Estimated height in pixels, or 0 if height cannot be determined
     */
    private estimateFragmentHeight;
}
//# sourceMappingURL=renderer.d.ts.map