import { BBox } from './bbox';
import { SceneChangeDetection } from './changeDetectable';
import type { LayersManager } from './layersManager';
import type { ZIndex } from './zIndex';
export { SceneChangeDetection };
export declare enum PointerEvents {
    All = 0,
    None = 1
}
export type RenderContext = {
    ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D;
    width: number;
    height: number;
    devicePixelRatio: number;
    clipBBox?: BBox;
    stats?: {
        opsPerformed: number;
        opsSkipped: number;
        nodesRendered: number;
        nodesSkipped: number;
        layersRendered: number;
        layersSkipped: number;
    };
    debugNodeSearch?: (string | RegExp)[];
    debugNodes: Record<string, Node>;
};
export interface NodeOptions {
    name?: string;
    tag?: number;
    zIndex?: ZIndex;
    debugDirty?: boolean;
}
export type NodeWithOpacity = Node & {
    opacity: number;
};
export type ChildNodeCounts = {
    groups: number;
    nonGroups: number;
    thisComplexity: number;
    complexity: number;
};
/**
 * Abstract scene graph node.
 * Each node can have zero or one parent and belong to zero or one scene.
 */
export declare abstract class Node<D = any> {
    private static _nextSerialNumber;
    static _debugEnabled: boolean;
    static toSVG(node: Node, width: number, height: number): string | undefined;
    static extractBBoxes(nodes: Iterable<Node>, skipInvisible?: boolean): Generator<BBox, void, unknown>;
    /** Unique number to allow creation order to be easily determined. */
    readonly serialNumber: number;
    readonly childNodeCounts: ChildNodeCounts;
    /** Unique node ID in the form `ClassName-NaturalNumber`. */
    readonly id: string;
    readonly name?: string;
    /**
     * Some number to identify this node, typically within a `Group` node.
     * Usually this will be some enum value used as a selector.
     */
    tag: number;
    transitionOut?: boolean;
    pointerEvents: PointerEvents;
    protected _datum?: D;
    protected _previousDatum?: D;
    protected _debug?: (...args: any[]) => void;
    protected _layerManager?: LayersManager;
    private readonly _debugDirtyProperties?;
    protected _dirty: boolean;
    protected dirtyZIndex: boolean;
    private parentNode?;
    private childNodes?;
    private cachedBBox?;
    /**
     * To simplify the type system (especially in Selections) we don't have the `Parent` node
     * (one that has children). Instead, we mimic HTML DOM, where any node can have children.
     * But we still need to distinguish regular leaf nodes from container leafs somehow.
     */
    protected isContainerNode: boolean;
    visible: boolean;
    zIndex: ZIndex;
    constructor(options?: NodeOptions);
    /**
     * Some arbitrary data bound to the node.
     */
    get datum(): any;
    set datum(datum: any);
    get previousDatum(): any;
    get layerManager(): LayersManager | undefined;
    get dirty(): boolean;
    closestDatum(): any;
    /** Perform any pre-rendering initialization. */
    preRender(renderCtx: RenderContext, thisComplexity?: number): ChildNodeCounts;
    render(renderCtx: RenderContext): void;
    _setLayerManager(value?: LayersManager): void;
    protected sortChildren(compareFn?: (a: Node, b: Node) => number): void;
    traverseUp(includeSelf?: boolean): Generator<Node, void, unknown>;
    children(): Generator<Node, void, undefined>;
    descendants(): Generator<Node, void, undefined>;
    /**
     * Checks if the node is a leaf (has no children).
     */
    isLeaf(): boolean;
    /**
     * Checks if the node is the root (has no parent).
     */
    isRoot(): boolean;
    /**
     * Appends one or more new node instances to this parent.
     * If one needs to:
     * - move a child to the end of the list of children
     * - move a child from one parent to another (including parents in other scenes)
     * one should use the {@link insertBefore} method instead.
     * @param nodes A node or nodes to append.
     */
    append(nodes: Iterable<Node> | Node): void;
    appendChild<T extends Node>(node: T): T;
    removeChild(node: Node): void;
    remove(): void;
    clear(): void;
    destroy(): void;
    setProperties<T>(this: T, styles: {
        [K in keyof T]?: T[K];
    }, pickKeys?: (keyof T)[]): T;
    containsPoint(_x: number, _y: number): boolean;
    /**
     * Hit testing method.
     * Recursively checks if the given point is inside this node or any of its children.
     * Returns the first matching node or `undefined`.
     * Nodes that render later (show on top) are hit tested first.
     */
    pickNode(x: number, y: number): Node | undefined;
    pickNodes(x: number, y: number, into?: Node<any>[]): Node<any>[];
    private invalidateCachedBBox;
    getBBox(): BBox;
    protected computeBBox(): BBox | undefined;
    markDirty(property?: string): void;
    markClean(): void;
    private markDebugProperties;
    private debugDirtyProperties;
    protected onZIndexChange(): void;
    toSVG(): {
        elements: SVGElement[];
        defs?: SVGElement[];
    } | undefined;
}
