/**
 * Cost function for a candidate label placement. Lower is better.
 *
 * The hierarchy `lineBox >> boxDot > boxBox > lineLine >> stick > spread > len`
 * is near-lexicographic: a single leader passing under another label always
 * outranks fixing every overlap a node could have against its <=24 neighbors,
 * so the optimizer eliminates crossings first (the user's top priority), then
 * dot coverage, then box overlaps, then tidies the radial fan.
 */
import type { LabelNode, SolverConfig } from './types';
export declare const W: {
    /** DOMINANT — a leader passing under ANOTHER label's box. Requirement #1. */
    lineBox: number;
    /** Our box covering another node's dot. Worse than a box overlap. Requirement #4. */
    boxDot: number;
    /** Two label boxes overlapping. Requirement #2. */
    boxBox: number;
    /** Two leaders crossing — thin lines, mild. Supports the radial fan. */
    lineLine: number;
    /** Sticky bonus for staying on the previous slot (anti flip-flop). Requirement #6. */
    stick: number;
    /** Penalty when a slot's angle nearly coincides with a neighbor's leader angle. */
    spread: number;
    /** Outward-fan preference: cheaper to point away from the local cluster. Requirement #3. */
    radial: number;
    /** Leader length — keep labels close to their dot. Small. */
    len: number;
};
/**
 * The geometric "bad" terms only (leader-under-box, box-over-dot, box-box,
 * leader-leader, angular spread) for placing `node` at slot `si` against its
 * committed neighbors. This is the local-search objective AND its termination
 * guard — exactly 0 when the node has no crossings/overlaps. The solver both
 * selects and accepts moves on this value so it can never lock a node at a
 * placement whose conflict another available slot would reduce.
 */
export declare function evalConflict(node: LabelNode, si: number, neighbors: LabelNode[], config: SolverConfig): number;
/**
 * Conflict-independent "tidiness" of a slot: short leaders, pointing away from
 * the local cluster centroid (radial fan-out), with a bonus for staying put.
 * Used only as a tie-break among slots of equal conflict, never to override a
 * conflict reduction.
 */
export declare function placementBias(node: LabelNode, si: number): number;
