/**
 * @file hash 边界解析（对齐 IncrementalParser）
 * @module renderer/incremental/HashBoundaryResolver
 *
 * 将 CM 行变更转换为 {@link IncrementalParseRange} + markdown 切片，
 * 调用 {@link TransformerEngine.parseIncremental}。
 *
 * 锚点基于 **全 AST children**（{@link astBlockSpans}），不用 {@link BlockIndex}。
 *
 * ## 数据流
 *
 * ```
 * PennaChangeLineSet[]
 *       ↓ dirtyLinesFromChanges + expandDirtyToBlockBounds
 * astBlockSpans → prevHash / nextHash
 *       ↓ mapOldLineToNew + slice
 * { range, markdown } → parseIncremental
 * ```
 *
 * hash 分区语义与 {@link IncrementalParser.partitionAstByHash} 一致，
 * 见 {@link IncrementalParseRange}。
 */
import type { MarkdownNode } from "../../transformer/core/MarkdownNode.js";
import type { TransformerEngine } from "../../transformer/TransformerEngine.js";
import type { IncrementalParseRange, IncrementalParseResult } from "../../transformer/core/Incremental/IncrementalParseRange.js";
import type { PennaChangeLineSet } from "../../renderer/incremental/PennaChangeSet";
/**
 * 单个 AST 顶层块的行区间与 hash（hash 边界专用，含 invisible 块）。
 *
 * 行号为 0-based 半开区间 `[startLine, endLine)`。
 * DOM / scroll-sync 用 {@link BlockIndex}，不用本类型。
 */
export interface AstBlockSpan {
    readonly node: MarkdownNode;
    readonly hash: string;
    readonly startLine: number;
    readonly endLine: number;
    readonly childIndex: number;
}
/** 从 AST 根提取全量顶层块 span（含 invisible）。 */
export declare function astBlockSpans(ast: MarkdownNode): AstBlockSpan[];
/** 判断块行区间是否与脏区相交。 */
export declare function spanOverlapsDirty(span: AstBlockSpan, startLine: number, endLine: number): boolean;
/** 找与脏区相交的连续 span 索引闭区间；无相交时 `null`。 */
export declare function findAffectedSpanRange(spans: AstBlockSpan[], startLine: number, endLine: number): {
    startIdx: number;
    endIdx: number;
} | null;
/** 传给 {@link TransformerEngine.parseIncremental} 的输入。 */
export interface HashBoundaryInput {
    /** hash 边界，锚定未变块 */
    range: IncrementalParseRange;
    /** 变更区 markdown；空串/空数组表示 delete */
    markdown: string | string[];
}
/** {@link resolveHashBoundaryInternal} 的返回值。 */
export interface HashBoundaryResolveResult {
    /** parseIncremental 输入 */
    input: HashBoundaryInput;
    /** 旧文档侧脏区（0-based 半开 `[startLine, endLine)`） */
    dirtyOld: {
        startLine: number;
        endLine: number;
    };
    /** 新文档侧脏区（0-based 半开） */
    dirtyNew: {
        startLine: number;
        endLine: number;
    };
}
/**
 * 旧文档 1-based 行号 → 新文档 1-based 行号。
 *
 * 按 CM changes 顺序累加插入/删除行差；落点在变更区内的行按相对偏移映射。
 *
 * @param changes   CM 行变更集
 * @param oldLine1  旧文档目标行（1-based）
 * @returns 新文档对应行（1-based）
 */
export declare function mapOldLineToNew(changes: PennaChangeLineSet[], oldLine1: number): number;
/**
 * 从 CM changes 合并旧文档侧原始脏行区间。
 *
 * @param changes CM 行变更集
 * @returns 0-based 半开 `[startLine, endLine)`；无有效变更时 `undefined`
 */
export declare function dirtyLinesFromChanges(changes: PennaChangeLineSet[]): {
    startLine: number;
    endLine: number;
} | undefined;
/**
 * 向上/向下寻找安全的块边界。
 *
 * @param spans       全 AST span 列表（旧 AST）
 * @param startLine   初步脏区起始行（0-based）
 * @param endLine     初步脏区结束行（0-based）
 * @returns 扩展后的行区间
 */
export declare function expandDirtyToBlockBounds(spans: AstBlockSpan[], startLine: number, endLine: number): {
    startLine: number;
    endLine: number;
};
/**
 * 脏区是否与 `globalEffect` 顶层块相交。
 *
 * 定义块（frontmatter、footnote_def、linkReferenceDef 等）写入文档级 store，
 * 编辑后引用块 hash 不变但渲染会变，应降级全量渲染。
 */
export declare function dirtyTouchesGlobalEffect(ast: MarkdownNode, changes: PennaChangeLineSet[]): boolean;
/**
 * 解析 hash 边界并调用 `parseIncremental`，原地更新 `prevAst`。
 *
 * @param prevAst     上次 AST 根（会被 mutate）
 * @param prevLines   上次归一化源码行
 * @param newLines    新归一化源码行
 * @param changes     CM 行变更集
 * @param transformer 解析引擎
 * @returns parse 结果与边界信息；无法 resolve 时 `undefined`
 * @throws `parseIncremental` 锚点 hash 在 AST 中不存在等错误
 */
export declare function parseWithHashBoundary(prevAst: MarkdownNode, prevLines: string[], newLines: string[], changes: PennaChangeLineSet[], transformer: TransformerEngine): {
    result: IncrementalParseResult;
    resolve: HashBoundaryResolveResult;
} | undefined;
//# sourceMappingURL=HashBoundaryResolver.d.ts.map