export type MerkleTreeJson = {
    tree: Record<string, string>;
    reverseTree?: Record<string, string>;
    count: string;
    index: string;
};
/**
 * Merkle tree implementation that allows the user to insert in specific places in the tree
 *
 */
export declare class MerkleTree<T> {
    private hashFunction;
    private levels;
    private defaultNodeValue;
    /**
     * the map where the items are stored
     */
    private readonly tree;
    /**
     * amount of elements inserted inside the bottom row of the tree
     */
    private count;
    /**
     * the maximum index inserted into the tree
     * used together with count to make sure that the merkle tree is complete.
     * meaning that there aren't any missing elements between getStartIndex() and index
     */
    private index;
    private reverseTree;
    static createWithData<T>(tree: Map<bigint, T>, reverseTree: Map<T, bigint> | undefined, index: bigint, count: bigint, hashFunction: (a: T, b: T) => T, levels: bigint, defaultNodeValue: T): MerkleTree<T>;
    /**
     * @param hashFunction the hashFunction used to fill the upper layers of the merkle tree
     * @param levels the amount of layers in the merkle tree
     * @param defaultNodeValue the default value of an empty node in the merkle tree
     */
    static create<T>(hashFunction: (a: T, b: T) => T, defaultNodeValue: T, levels?: bigint): MerkleTree<T>;
    private createReverseTree;
    private constructor();
    /**
     * get starting nodeIndex from which inserts are allowed
     */
    getStartIndex(): bigint;
    /**
     * implementation of logarithm2 function from merkle contract
     */
    logarithm2(a: bigint): bigint;
    bigIntMax(a: bigint, b: bigint): bigint;
    private forceInsert;
    /**
     * insert value into the merkle tree
     * @param value the value to insert
     * @param nodeIndex the index to insert the value, you can get starting index from getStartIndex()
     * @throws will throw RangeError if nodeIndex is less than getStartIndex()
     */
    insert(value: T, nodeIndex: bigint): void;
    remove(nodeIndex: bigint): void;
    private completenessCheck;
    /**
     * get root hash of the merkle tree
     * @returns the hash, if the merkle tree is empty, will return
     * @throws will throw MerkleTreeIncompleteError if there are missing elements in the tree
     */
    getRootHash(): T | undefined;
    getMerkleData(): Map<bigint, T>;
    getValue(index: bigint): T | undefined;
    getSiblingIndex(index: bigint): bigint;
    /**
     * get sibling hashes needed by main.circom
     * @throws will throw MerkleTreeIncompleteError if there are missing elements in the tree
     */
    getSiblingHashesForVerification(item: T): bigint[] | T[];
    /**
     * get item's sibling hashes side
     * @returns sibling's indexes
     * @throws will throw MerkleTreeIncompleteError if there are missing elements in the tree
     */
    getSiblingSides(item: T): bigint[];
    toJSON(): MerkleTreeJson;
    toJSONLite(): MerkleTreeJson;
    clone(): MerkleTree<T>;
    getIndex(): bigint;
}
