export declare abstract class AbstractCollection<TElement> extends AbstractReadonlyCollection<TElement> implements ICollection<TElement> {
    protected constructor(comparator?: EqualityComparator<TElement>);
    addAll<TSource extends TElement>(collection: Iterable<TSource>): boolean;
    reset<TSource extends TElement>(collection: Iterable<TSource>): void;
    abstract add(element: TElement): boolean;
    abstract clear(): void;
}

declare abstract class AbstractDictionary<TKey, TValue> extends AbstractReadonlyDictionary<TKey, TValue> implements IDictionary<TKey, TValue> {
    protected constructor(valueComparator: EqualityComparator<TValue>, keyValueComparator: EqualityComparator<KeyValuePair<TKey, TValue>>);
    put(key: TKey, value: TValue): TValue | null;
    tryAdd(key: TKey, value: TValue): boolean;
    abstract add(key: TKey, value: TValue): TValue;
    abstract clear(): void;
    abstract remove(key: TKey): TValue | null;
    abstract set(key: TKey, value: TValue): void;
}

export declare abstract class AbstractEnumerable<TElement> implements IEnumerable<TElement> {
    protected readonly comparer: EqualityComparator<TElement>;
    protected constructor(comparator?: EqualityComparator<TElement>);
    aggregate(accumulator: Accumulator<TElement, TElement>): TElement;
    aggregate<TAccumulate>(accumulator: Accumulator<TElement, TAccumulate>, seed: TAccumulate): TAccumulate;
    aggregate<TAccumulate, TResult>(accumulator: Accumulator<TElement, TAccumulate>, seed: TAccumulate, resultSelector: Selector<TAccumulate, TResult>): TResult;
    aggregateBy<TKey, TAccumulate = TElement>(keySelector: Selector<TElement, TKey>, seedSelector: Selector<TKey, TAccumulate> | TAccumulate, accumulator: Accumulator<TElement, TAccumulate>, keyComparator?: EqualityComparator<TKey>): IEnumerable<KeyValuePair<TKey, TAccumulate>>;
    all(predicate: Predicate<TElement>): boolean;
    any(predicate?: Predicate<TElement>): boolean;
    append(element: TElement): IEnumerable<TElement>;
    atLeast(count: number, predicate?: Predicate<TElement>): boolean;
    atMost(count: number, predicate?: Predicate<TElement>): boolean;
    average(this: Iterable<number>): number;
    average(selector: Selector<TElement, number>): number;
    cartesian<TSecond>(iterable: Iterable<TSecond>): IEnumerable<[TElement, TSecond]>;
    cast<TResult>(): IEnumerable<TResult>;
    chunk(size: number): IEnumerable<IEnumerable<TElement>>;
    combinations(size?: number): IEnumerable<IEnumerable<TElement>>;
    compact(): IEnumerable<NonNullable<TElement>>;
    concat(iterable: Iterable<TElement>): IEnumerable<TElement>;
    contains(element: TElement, comparator?: EqualityComparator<TElement>): boolean;
    correlation<TSecond>(iterable: Iterable<TSecond>, selector?: Selector<TElement, number>, otherSelector?: Selector<TSecond, number>): number;
    correlationBy(leftSelector: Selector<TElement, number>, rightSelector: Selector<TElement, number>): number;
    count(predicate?: Predicate<TElement>): number;
    countBy<TKey>(keySelector: Selector<TElement, TKey>, comparator?: EqualityComparator<TKey>): IEnumerable<KeyValuePair<TKey, number>>;
    covariance<TSecond>(iterable: Iterable<TSecond>, selector?: Selector<TElement, number>, otherSelector?: Selector<TSecond, number>, sample?: boolean): number;
    covarianceBy(leftSelector: Selector<TElement, number>, rightSelector: Selector<TElement, number>, sample?: boolean): number;
    cycle(count?: number): IEnumerable<TElement>;
    defaultIfEmpty(value?: TElement | null): IEnumerable<TElement | null>;
    disjoint<TSecond>(iterable: Iterable<TSecond>, comparator?: EqualityComparator<TElement | TSecond>): boolean;
    disjointBy<TSecond, TKey, TSecondKey>(iterable: Iterable<TSecond>, keySelector: Selector<TElement, TKey>, otherKeySelector: Selector<TSecond, TSecondKey>, keyComparator?: EqualityComparator<TKey | TSecondKey>): boolean;
    distinct(keyComparator?: EqualityComparator<TElement>): IEnumerable<TElement>;
    distinctBy<TKey>(keySelector: Selector<TElement, TKey>, keyComparator?: EqualityComparator<TKey>): IEnumerable<TElement>;
    distinctUntilChanged(comparator?: EqualityComparator<TElement>): IEnumerable<TElement>;
    distinctUntilChangedBy<TKey>(keySelector: Selector<TElement, TKey>, keyComparator?: EqualityComparator<TKey>): IEnumerable<TElement>;
    elementAt(index: number): TElement;
    elementAtOrDefault(index: number): TElement | null;
    exactly(count: number, predicate?: Predicate<TElement>): boolean;
    except(iterable: Iterable<TElement>, comparator?: EqualityComparator<TElement> | OrderComparator<TElement>): IEnumerable<TElement>;
    exceptBy<TKey>(iterable: Iterable<TElement>, keySelector: Selector<TElement, TKey>, keyComparator?: EqualityComparator<TKey> | OrderComparator<TKey>): IEnumerable<TElement>;
    first<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): TFiltered;
    first(predicate?: Predicate<TElement>): TElement;
    firstOrDefault<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): TFiltered | null;
    firstOrDefault(predicate?: Predicate<TElement>): TElement | null;
    forEach(action: IndexedAction<TElement>): void;
    groupBy<TKey>(keySelector: Selector<TElement, TKey>, keyComparator?: EqualityComparator<TKey>, hashSelector?: Selector<TElement, PropertyKey>): IEnumerable<IGroup<TKey, TElement>>;
    groupJoin<TInner, TKey, TResult>(innerEnumerable: IEnumerable<TInner>, outerKeySelector: Selector<TElement, TKey>, innerKeySelector: Selector<TInner, TKey>, resultSelector: JoinSelector<TElement, IEnumerable<TInner>, TResult>, keyComparator?: EqualityComparator<TKey>): IEnumerable<TResult>;
    index(): IEnumerable<[number, TElement]>;
    interleave<TSecond>(iterable: Iterable<TSecond>): IEnumerable<TElement | TSecond>;
    intersect(iterable: Iterable<TElement>, comparator?: EqualityComparator<TElement> | OrderComparator<TElement>): IEnumerable<TElement>;
    intersectBy<TKey>(iterable: Iterable<TElement>, keySelector: Selector<TElement, TKey>, keyComparator?: EqualityComparator<TKey> | OrderComparator<TKey>): IEnumerable<TElement>;
    intersperse<TSeparator = TElement>(separator: TSeparator): IEnumerable<TElement | TSeparator>;
    join<TInner, TKey, TResult>(innerEnumerable: IEnumerable<TInner>, outerKeySelector: Selector<TElement, TKey>, innerKeySelector: Selector<TInner, TKey>, resultSelector: JoinSelector<TElement, TInner, TResult>, keyComparator?: EqualityComparator<TKey>): IEnumerable<TResult>;
    last<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): TFiltered;
    last(predicate?: Predicate<TElement>): TElement;
    lastOrDefault<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): TFiltered | null;
    lastOrDefault(predicate?: Predicate<TElement>): TElement | null;
    leftJoin<TInner, TKey, TResult>(innerEnumerable: IEnumerable<TInner>, outerKeySelector: Selector<TElement, TKey>, innerKeySelector: Selector<TInner, TKey>, resultSelector: JoinSelector<TElement, TInner, TResult>, keyComparator?: EqualityComparator<TKey>): IEnumerable<TResult>;
    max(this: Iterable<number>): number;
    max(selector: Selector<TElement, number>): number;
    maxBy<TKey>(keySelector: Selector<TElement, TKey>, comparator?: OrderComparator<TKey>): TElement;
    median(selector?: Selector<TElement, number>, tie?: MedianTieStrategy): number;
    min(this: Iterable<number>): number;
    min(selector: Selector<TElement, number>): number;
    minBy<TKey>(keySelector: Selector<TElement, TKey>, comparator?: OrderComparator<TKey>): TElement;
    mode<TKey>(keySelector?: Selector<TElement, TKey>): TElement;
    modeOrDefault<TKey>(keySelector?: Selector<TElement, TKey>): TElement | null;
    multimode<TKey>(keySelector?: Selector<TElement, TKey>): IEnumerable<TElement>;
    none(predicate?: Predicate<TElement>): boolean;
    ofType<TResult extends ObjectType>(type: TResult): IEnumerable<InferredType<TResult>>;
    order(comparator?: OrderComparator<TElement>): IOrderedEnumerable<TElement>;
    orderBy<TKey>(keySelector: Selector<TElement, TKey>, comparator?: OrderComparator<TKey>): IOrderedEnumerable<TElement>;
    orderByDescending<TKey>(keySelector: Selector<TElement, TKey>, comparator?: OrderComparator<TKey>): IOrderedEnumerable<TElement>;
    orderDescending(comparator?: OrderComparator<TElement>): IOrderedEnumerable<TElement>;
    pairwise(resultSelector: PairwiseSelector<TElement, TElement>): IEnumerable<[TElement, TElement]>;
    partition<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): [IEnumerable<TFiltered>, IEnumerable<Exclude<TElement, TFiltered>>];
    partition(predicate: Predicate<TElement>): [IEnumerable<TElement>, IEnumerable<TElement>];
    percentile(this: Iterable<number>, percent: number, strategy?: PercentileStrategy): number;
    percentile(percent: number, selector: Selector<TElement, number>, strategy?: PercentileStrategy): number;
    permutations(size?: number): IEnumerable<IEnumerable<TElement>>;
    pipe<TResult>(operator: PipeOperator<TElement, TResult>): TResult;
    prepend(element: TElement): IEnumerable<TElement>;
    product(this: Iterable<number>): number;
    product(selector: Selector<TElement, number>): number;
    reverse(): IEnumerable<TElement>;
    rightJoin<TInner, TKey, TResult>(innerEnumerable: IEnumerable<TInner>, outerKeySelector: Selector<TElement, TKey>, innerKeySelector: Selector<TInner, TKey>, resultSelector: JoinSelector<TElement | null, TInner, TResult>, keyComparator?: EqualityComparator<TKey>): IEnumerable<TResult>;
    rotate(shift: number): IEnumerable<TElement>;
    scan(accumulator: Accumulator<TElement, TElement>): IEnumerable<TElement>;
    scan<TAccumulate>(accumulator: Accumulator<TElement, TAccumulate>, seed: TAccumulate): IEnumerable<TAccumulate>;
    select<TResult>(selector: IndexedSelector<TElement, TResult>): IEnumerable<TResult>;
    selectMany<TResult>(selector: IndexedSelector<TElement, Iterable<TResult>>): IEnumerable<TResult>;
    sequenceEqual(iterable: Iterable<TElement>, comparator?: EqualityComparator<TElement>): boolean;
    shuffle(): IEnumerable<TElement>;
    single<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): TFiltered;
    single(predicate?: Predicate<TElement>): TElement;
    singleOrDefault<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): TFiltered | null;
    singleOrDefault(predicate?: Predicate<TElement>): TElement | null;
    skip(count: number): IEnumerable<TElement>;
    skipLast(count: number): IEnumerable<TElement>;
    skipUntil<TFiltered extends TElement>(predicate: IndexedTypePredicate<TElement, TFiltered>): IEnumerable<TFiltered>;
    skipUntil(predicate: IndexedPredicate<TElement>): IEnumerable<TElement>;
    skipWhile(predicate: IndexedPredicate<TElement>): IEnumerable<TElement>;
    span<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): [IEnumerable<TFiltered>, IEnumerable<TElement>];
    span(predicate: Predicate<TElement>): [IEnumerable<TElement>, IEnumerable<TElement>];
    standardDeviation(selector?: Selector<TElement, number>, sample?: boolean): number;
    step(stepNumber: number): IEnumerable<TElement>;
    sum(this: Iterable<number>): number;
    sum(selector: Selector<TElement, number>): number;
    take(count: number): IEnumerable<TElement>;
    takeLast(count: number): IEnumerable<TElement>;
    takeUntil<TFiltered extends TElement>(predicate: IndexedTypePredicate<TElement, TFiltered>): IEnumerable<TFiltered>;
    takeUntil(predicate: IndexedPredicate<TElement>): IEnumerable<TElement>;
    takeWhile<TFiltered extends TElement>(predicate: IndexedTypePredicate<TElement, TFiltered>): IEnumerable<TFiltered>;
    takeWhile(predicate: IndexedPredicate<TElement>): IEnumerable<TElement>;
    tap(action: IndexedAction<TElement>): IEnumerable<TElement>;
    toArray(): TElement[];
    toCircularLinkedList(comparator?: EqualityComparator<TElement, TElement>): CircularLinkedList<TElement>;
    toCircularQueue(comparator?: EqualityComparator<TElement>): CircularQueue<TElement>;
    toCircularQueue(capacity: number, comparator?: EqualityComparator<TElement>): CircularQueue<TElement>;
    toDictionary<TKey, TValue>(keySelector: Selector<TElement, TKey>, valueSelector: Selector<TElement, TValue>, valueComparator?: EqualityComparator<TValue>): Dictionary<TKey, TValue>;
    toEnumerableSet(): EnumerableSet<TElement>;
    toImmutableCircularQueue(comparator?: EqualityComparator<TElement>): ImmutableCircularQueue<TElement>;
    toImmutableCircularQueue(capacity: number, comparator?: EqualityComparator<TElement>): ImmutableCircularQueue<TElement>;
    toImmutableDictionary<TKey, TValue>(keySelector: Selector<TElement, TKey>, valueSelector: Selector<TElement, TValue>, valueComparator?: EqualityComparator<TValue>): ImmutableDictionary<TKey, TValue>;
    toImmutableList(comparator?: EqualityComparator<TElement>): ImmutableList<TElement>;
    toImmutablePriorityQueue(comparator?: OrderComparator<TElement>): ImmutablePriorityQueue<TElement>;
    toImmutableQueue(comparator?: EqualityComparator<TElement>): ImmutableQueue<TElement>;
    toImmutableSet(): ImmutableSet<TElement>;
    toImmutableSortedDictionary<TKey, TValue>(keySelector: Selector<TElement, TKey>, valueSelector: Selector<TElement, TValue>, keyComparator?: OrderComparator<TKey>, valueComparator?: EqualityComparator<TValue>): ImmutableSortedDictionary<TKey, TValue>;
    toImmutableSortedSet(comparator?: OrderComparator<TElement>): ImmutableSortedSet<TElement>;
    toImmutableStack(comparator?: EqualityComparator<TElement>): ImmutableStack<TElement>;
    toLinkedList(comparator?: EqualityComparator<TElement>): LinkedList<TElement>;
    toList(comparator?: EqualityComparator<TElement>): List<TElement>;
    toLookup<TKey, TValue>(keySelector: Selector<TElement, TKey>, valueSelector: Selector<TElement, TValue>, keyComparator?: OrderComparator<TKey>): ILookup<TKey, TValue>;
    toMap<TKey, TValue>(keySelector: Selector<TElement, TKey>, valueSelector: Selector<TElement, TValue>): Map<TKey, TValue>;
    toObject<TKey extends PropertyKey, TValue>(keySelector: Selector<TElement, TKey>, valueSelector: Selector<TElement, TValue>): Record<TKey, TValue>;
    toPriorityQueue(comparator?: OrderComparator<TElement>): PriorityQueue<TElement>;
    toQueue(comparator?: EqualityComparator<TElement>): Queue<TElement>;
    toSet(): Set<TElement>;
    toSortedDictionary<TKey, TValue>(keySelector: Selector<TElement, TKey>, valueSelector: Selector<TElement, TValue>, keyComparator?: OrderComparator<TKey>, valueComparator?: EqualityComparator<TValue>): SortedDictionary<TKey, TValue>;
    toSortedSet(comparator?: OrderComparator<TElement>): SortedSet<TElement>;
    toStack(comparator?: EqualityComparator<TElement>): Stack<TElement>;
    union(iterable: Iterable<TElement>, comparator?: EqualityComparator<TElement>): IEnumerable<TElement>;
    unionBy<TKey>(iterable: Iterable<TElement>, keySelector: Selector<TElement, TKey>, comparator?: EqualityComparator<TKey>): IEnumerable<TElement>;
    variance(selector?: Selector<TElement, number>, sample?: boolean): number;
    where<TFiltered extends TElement>(predicate: IndexedTypePredicate<TElement, TFiltered>): IEnumerable<TFiltered>;
    where(predicate: IndexedPredicate<TElement>): IEnumerable<TElement>;
    windows(size: number): IEnumerable<IEnumerable<TElement>>;
    zip<TSecond>(iterable: Iterable<TSecond>): IEnumerable<[TElement, TSecond]>;
    zip<TSecond, TResult = [TElement, TSecond]>(iterable: Iterable<TSecond>, zipper?: Zipper<TElement, TSecond, TResult>): IEnumerable<TResult>;
    zipMany<TIterable extends readonly Iterable<unknown>[]>(...iterables: [...TIterable]): IEnumerable<[TElement, ...UnpackIterableTuple<TIterable>]>;
    zipMany<TIterable extends readonly Iterable<unknown>[], TResult>(...iterablesAndZipper: [...TIterable, ZipManyZipper<[TElement, ...UnpackIterableTuple<TIterable>], TResult>]): IEnumerable<TResult>;
    protected getIterableSize(iterable: Iterable<TElement>): number;
    abstract [Symbol.iterator](): Iterator<TElement>;
}

export declare abstract class AbstractImmutableCollection<TElement> extends AbstractReadonlyCollection<TElement> implements IImmutableCollection<TElement> {
    protected constructor(comparator?: EqualityComparator<TElement>);
    abstract add(element: TElement): IImmutableCollection<TElement>;
    abstract addAll<TSource extends TElement>(collection: Iterable<TSource>): IImmutableCollection<TElement>;
    abstract clear(): IImmutableCollection<TElement>;
    abstract reset<TSource extends TElement>(collection: Iterable<TSource>): IImmutableCollection<TElement>;
}

declare abstract class AbstractImmutableDictionary<TKey, TValue> extends AbstractReadonlyDictionary<TKey, TValue> implements IImmutableDictionary<TKey, TValue> {
    protected constructor(valueComparator: EqualityComparator<TValue>, keyValueComparator: EqualityComparator<KeyValuePair<TKey, TValue>>);
    abstract add(key: TKey, value: TValue): IImmutableDictionary<TKey, TValue>;
    abstract clear(): IImmutableDictionary<TKey, TValue>;
    abstract put(key: TKey, value: TValue): IImmutableDictionary<TKey, TValue>;
    abstract remove(key: TKey): IImmutableDictionary<TKey, TValue>;
    abstract set(key: TKey, value: TValue): IImmutableDictionary<TKey, TValue>;
    abstract get length(): number;
}

export declare abstract class AbstractList<TElement> extends AbstractRandomAccessCollection<TElement> implements IList<TElement> {
    protected constructor(comparator?: EqualityComparator<TElement>);
    add(element: TElement): boolean;
    contains(element: TElement, comparator?: EqualityComparator<TElement>): boolean;
    elementAt(index: number): TElement;
    elementAtOrDefault(index: number): TElement | null;
    entries(): IterableIterator<[number, TElement]>;
    first<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): TFiltered;
    first(predicate?: Predicate<TElement>): TElement;
    firstOrDefault<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): TFiltered | null;
    firstOrDefault(predicate?: Predicate<TElement>): TElement | null;
    indexOf(element: TElement, comparator?: EqualityComparator<TElement>): number;
    last<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): TFiltered;
    last(predicate?: Predicate<TElement>): TElement;
    lastIndexOf(element: TElement, comparator?: EqualityComparator<TElement>): number;
    lastOrDefault<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): TFiltered | null;
    lastOrDefault(predicate?: Predicate<TElement>): TElement | null;
    removeAll<TSource extends TElement>(collection: Iterable<TSource>): boolean;
    removeIf(predicate: Predicate<TElement>): boolean;
    abstract addAt(element: TElement, index: number): boolean;
    abstract get(index: number): TElement;
    abstract getRange(index: number, count: number): IList<TElement>;
    abstract removeAt(index: number): TElement;
    abstract set(index: number, element: TElement): TElement;
    abstract sort(comparator?: OrderComparator<TElement>): void;
}

export declare abstract class AbstractRandomAccessCollection<TElement> extends AbstractCollection<TElement> implements IRandomAccessCollection<TElement> {
    retainAll<TSource extends TElement>(collection: Iterable<TSource>): boolean;
    abstract remove(element: TElement): boolean;
    abstract removeAll<TSource extends TElement>(collection: Iterable<TSource>): boolean;
    abstract removeIf(predicate: Predicate<TElement>): boolean;
}

export declare abstract class AbstractRandomAccessImmutableCollection<TElement> extends AbstractImmutableCollection<TElement> implements IRandomAccessImmutableCollection<TElement> {
    abstract remove(element: TElement): IRandomAccessImmutableCollection<TElement>;
    abstract removeAll<TSource extends TElement>(collection: Iterable<TSource>): IRandomAccessImmutableCollection<TElement>;
    abstract removeIf(predicate: (element: TElement) => boolean): IRandomAccessImmutableCollection<TElement>;
    abstract retainAll<TSource extends TElement>(collection: Iterable<TSource>): IRandomAccessImmutableCollection<TElement>;
}

export declare abstract class AbstractReadonlyCollection<TElement> extends AbstractEnumerable<TElement> implements IReadonlyCollection<TElement> {
    protected constructor(comparator?: EqualityComparator<TElement>);
    any(predicate?: Predicate<TElement>): boolean;
    containsAll<TSource extends TElement>(collection: Iterable<TSource>): boolean;
    count(predicate?: Predicate<TElement>): number;
    isEmpty(): boolean;
    toString(): string;
    toString(separator?: string): string;
    toString(separator?: string, selector?: Selector<TElement, string>): string;
    get comparator(): EqualityComparator<TElement> | OrderComparator<TElement>;
    abstract size(): number;
    abstract get length(): number;
}

declare abstract class AbstractReadonlyDictionary<TKey, TValue> implements IReadonlyDictionary<TKey, TValue> {
    protected readonly keyValueComparer: EqualityComparator<KeyValuePair<TKey, TValue>>;
    protected readonly valueComparer: EqualityComparator<TValue>;
    protected constructor(valueComparator: EqualityComparator<TValue>, keyValueComparator: EqualityComparator<KeyValuePair<TKey, TValue>>);
    aggregate(accumulator: Accumulator<KeyValuePair<TKey, TValue>, KeyValuePair<TKey, TValue>>): KeyValuePair<TKey, TValue>;
    aggregate<TAccumulate>(accumulator: Accumulator<KeyValuePair<TKey, TValue>, TAccumulate>, seed: TAccumulate): TAccumulate;
    aggregate<TAccumulate, TResult>(accumulator: Accumulator<KeyValuePair<TKey, TValue>, TAccumulate>, seed: TAccumulate, resultSelector: Selector<TAccumulate, TResult>): TResult;
    aggregateBy<TAggregateKey, TAccumulate = KeyValuePair<TKey, TValue>>(keySelector: Selector<KeyValuePair<TKey, TValue>, TAggregateKey>, seedSelector: Selector<TAggregateKey, TAccumulate> | TAccumulate, accumulator: Accumulator<KeyValuePair<TKey, TValue>, TAccumulate>, keyComparator?: EqualityComparator<TAggregateKey>): IEnumerable<KeyValuePair<TAggregateKey, TAccumulate>>;
    all(predicate: Predicate<KeyValuePair<TKey, TValue>>): boolean;
    any(predicate?: Predicate<KeyValuePair<TKey, TValue>>): boolean;
    append(element: KeyValuePair<TKey, TValue>): IEnumerable<KeyValuePair<TKey, TValue>>;
    asObject<TObjectKey extends PropertyKey>(): Record<TObjectKey, TValue>;
    atLeast(count: number, predicate?: Predicate<KeyValuePair<TKey, TValue>>): boolean;
    atMost(count: number, predicate?: Predicate<KeyValuePair<TKey, TValue>>): boolean;
    average(this: Iterable<number>): number;
    average(selector: Selector<KeyValuePair<TKey, TValue>, number>): number;
    cartesian<TSecond>(iterable: Iterable<TSecond>): IEnumerable<[KeyValuePair<TKey, TValue>, TSecond]>;
    cast<TResult>(): IEnumerable<TResult>;
    chunk(size: number): IEnumerable<IEnumerable<KeyValuePair<TKey, TValue>>>;
    combinations(size?: number): IEnumerable<IEnumerable<KeyValuePair<TKey, TValue>>>;
    compact(): IEnumerable<NonNullable<KeyValuePair<TKey, TValue>>>;
    concat(iterable: Iterable<KeyValuePair<TKey, TValue>>): IEnumerable<KeyValuePair<TKey, TValue>>;
    contains(element: KeyValuePair<TKey, TValue>, comparator?: EqualityComparator<KeyValuePair<TKey, TValue>>): boolean;
    correlation<TSecond>(iterable: Iterable<TSecond>, selector?: Selector<KeyValuePair<TKey, TValue>, number>, otherSelector?: Selector<TSecond, number>): number;
    correlationBy(leftSelector: Selector<KeyValuePair<TKey, TValue>, number>, rightSelector: Selector<KeyValuePair<TKey, TValue>, number>): number;
    count(predicate?: Predicate<KeyValuePair<TKey, TValue>>): number;
    countBy<TCountKey>(keySelector: Selector<KeyValuePair<TKey, TValue>, TCountKey>, comparator?: EqualityComparator<TCountKey>): IEnumerable<KeyValuePair<TCountKey, number>>;
    covariance<TSecond>(iterable: Iterable<TSecond>, selector?: Selector<KeyValuePair<TKey, TValue>, number>, otherSelector?: Selector<TSecond, number>, sample?: boolean): number;
    covarianceBy(leftSelector: Selector<KeyValuePair<TKey, TValue>, number>, rightSelector: Selector<KeyValuePair<TKey, TValue>, number>, sample?: boolean): number;
    cycle(count?: number): IEnumerable<KeyValuePair<TKey, TValue>>;
    defaultIfEmpty(value?: KeyValuePair<TKey, TValue> | null): IEnumerable<KeyValuePair<TKey, TValue> | null>;
    disjoint<TSecond>(iterable: Iterable<TSecond>, comparator?: EqualityComparator<KeyValuePair<TKey, TValue> | TSecond>): boolean;
    disjointBy<TSecond, TDisjointKey, TSecondDisjointKey>(iterable: Iterable<TSecond>, keySelector: Selector<KeyValuePair<TKey, TValue>, TDisjointKey>, otherKeySelector: Selector<TSecond, TSecondDisjointKey>, keyComparator?: EqualityComparator<TDisjointKey | TSecondDisjointKey>): boolean;
    distinct(keyComparator?: EqualityComparator<KeyValuePair<TKey, TValue>>): IEnumerable<KeyValuePair<TKey, TValue>>;
    distinctBy<TDistinctKey>(keySelector: Selector<KeyValuePair<TKey, TValue>, TDistinctKey>, comparator?: EqualityComparator<TDistinctKey>): IEnumerable<KeyValuePair<TKey, TValue>>;
    distinctUntilChanged(comparator?: EqualityComparator<KeyValuePair<TKey, TValue>>): IEnumerable<KeyValuePair<TKey, TValue>>;
    distinctUntilChangedBy<TDistinctKey>(keySelector: Selector<KeyValuePair<TKey, TValue>, TDistinctKey>, keyComparator?: EqualityComparator<TDistinctKey>): IEnumerable<KeyValuePair<TKey, TValue>>;
    elementAt(index: number): KeyValuePair<TKey, TValue>;
    elementAtOrDefault(index: number): KeyValuePair<TKey, TValue> | null;
    exactly(count: number, predicate?: Predicate<KeyValuePair<TKey, TValue>>): boolean;
    except(iterable: Iterable<KeyValuePair<TKey, TValue>>, comparator?: EqualityComparator<KeyValuePair<TKey, TValue>> | OrderComparator<KeyValuePair<TKey, TValue>>): IEnumerable<KeyValuePair<TKey, TValue>>;
    exceptBy<TExceptKey>(iterable: Iterable<KeyValuePair<TKey, TValue>>, keySelector: Selector<KeyValuePair<TKey, TValue>, TExceptKey>, keyComparator?: EqualityComparator<TExceptKey> | OrderComparator<TExceptKey>): IEnumerable<KeyValuePair<TKey, TValue>>;
    first<TFiltered extends KeyValuePair<TKey, TValue>>(predicate: TypePredicate<KeyValuePair<TKey, TValue>, TFiltered>): TFiltered;
    first(predicate?: Predicate<KeyValuePair<TKey, TValue>>): KeyValuePair<TKey, TValue>;
    firstOrDefault<TFiltered extends KeyValuePair<TKey, TValue>>(predicate: TypePredicate<KeyValuePair<TKey, TValue>, TFiltered>): TFiltered | null;
    firstOrDefault(predicate?: Predicate<KeyValuePair<TKey, TValue>>): KeyValuePair<TKey, TValue> | null;
    forEach(action: IndexedAction<KeyValuePair<TKey, TValue>>): void;
    groupBy<TGroupKey>(keySelector: Selector<KeyValuePair<TKey, TValue>, TGroupKey>, keyComparator?: EqualityComparator<TGroupKey>): IEnumerable<IGroup<TGroupKey, KeyValuePair<TKey, TValue>>>;
    groupJoin<TInner, TGroupKey, TResult>(innerEnumerable: IEnumerable<TInner>, outerKeySelector: Selector<KeyValuePair<TKey, TValue>, TGroupKey>, innerKeySelector: Selector<TInner, TGroupKey>, resultSelector: JoinSelector<KeyValuePair<TKey, TValue>, IEnumerable<TInner>, TResult>, keyComparator?: EqualityComparator<TGroupKey>): IEnumerable<TResult>;
    index(): IEnumerable<[number, KeyValuePair<TKey, TValue>]>;
    interleave<TSecond>(iterable: Iterable<TSecond>): IEnumerable<KeyValuePair<TKey, TValue> | TSecond>;
    intersect(iterable: Iterable<KeyValuePair<TKey, TValue>>, comparator?: EqualityComparator<KeyValuePair<TKey, TValue>> | OrderComparator<KeyValuePair<TKey, TValue>>): IEnumerable<KeyValuePair<TKey, TValue>>;
    intersectBy<TIntersectKey>(iterable: Iterable<KeyValuePair<TKey, TValue>>, keySelector: Selector<KeyValuePair<TKey, TValue>, TIntersectKey>, keyComparator?: EqualityComparator<TIntersectKey> | OrderComparator<TIntersectKey>): IEnumerable<KeyValuePair<TKey, TValue>>;
    intersperse<TSeparator = KeyValuePair<TKey, TValue>>(separator: TSeparator): IEnumerable<KeyValuePair<TKey, TValue> | TSeparator>;
    isEmpty(): boolean;
    join<TInner, TGroupKey, TResult>(innerEnumerable: IEnumerable<TInner>, outerKeySelector: Selector<KeyValuePair<TKey, TValue>, TGroupKey>, innerKeySelector: Selector<TInner, TGroupKey>, resultSelector: JoinSelector<KeyValuePair<TKey, TValue>, TInner, TResult>, keyComparator?: EqualityComparator<TGroupKey>): IEnumerable<TResult>;
    last<TFiltered extends KeyValuePair<TKey, TValue>>(predicate: TypePredicate<KeyValuePair<TKey, TValue>, TFiltered>): TFiltered;
    last(predicate?: Predicate<KeyValuePair<TKey, TValue>>): KeyValuePair<TKey, TValue>;
    lastOrDefault<TFiltered extends KeyValuePair<TKey, TValue>>(predicate: TypePredicate<KeyValuePair<TKey, TValue>, TFiltered>): TFiltered | null;
    lastOrDefault(predicate?: Predicate<KeyValuePair<TKey, TValue>>): KeyValuePair<TKey, TValue> | null;
    leftJoin<TInner, TGroupKey, TResult>(innerEnumerable: IEnumerable<TInner>, outerKeySelector: Selector<KeyValuePair<TKey, TValue>, TGroupKey>, innerKeySelector: Selector<TInner, TGroupKey>, resultSelector: JoinSelector<KeyValuePair<TKey, TValue>, TInner, TResult>, keyComparator?: EqualityComparator<TGroupKey>): IEnumerable<TResult>;
    max(this: Iterable<number>): number;
    max(selector: Selector<KeyValuePair<TKey, TValue>, number>): number;
    maxBy<TMaxKey>(keySelector: Selector<KeyValuePair<TKey, TValue>, TMaxKey>, comparator?: OrderComparator<TMaxKey>): KeyValuePair<TKey, TValue>;
    median(selector?: Selector<KeyValuePair<TKey, TValue>, number>, tie?: MedianTieStrategy): number;
    min(this: Iterable<number>): number;
    min(selector: Selector<KeyValuePair<TKey, TValue>, number>): number;
    minBy<TMinKey>(keySelector: Selector<KeyValuePair<TKey, TValue>, TMinKey>, comparator?: OrderComparator<TMinKey>): KeyValuePair<TKey, TValue>;
    mode<TModeKey>(keySelector?: Selector<KeyValuePair<TKey, TValue>, TModeKey>): KeyValuePair<TKey, TValue>;
    modeOrDefault<TModeKey>(keySelector?: Selector<KeyValuePair<TKey, TValue>, TModeKey>): KeyValuePair<TKey, TValue> | null;
    multimode<TModeKey>(keySelector?: Selector<KeyValuePair<TKey, TValue>, TModeKey>): IEnumerable<KeyValuePair<TKey, TValue>>;
    none(predicate?: Predicate<KeyValuePair<TKey, TValue>>): boolean;
    ofType<TResult extends ObjectType>(type: TResult): IEnumerable<InferredType<TResult>>;
    order(comparator?: OrderComparator<KeyValuePair<TKey, TValue>>): IOrderedEnumerable<KeyValuePair<TKey, TValue>>;
    orderBy<TOrderKey>(keySelector: Selector<KeyValuePair<TKey, TValue>, TOrderKey>, comparator?: OrderComparator<TOrderKey>): IOrderedEnumerable<KeyValuePair<TKey, TValue>>;
    orderByDescending<TOrderKey>(keySelector: Selector<KeyValuePair<TKey, TValue>, TOrderKey>, comparator?: OrderComparator<TOrderKey>): IOrderedEnumerable<KeyValuePair<TKey, TValue>>;
    orderDescending(comparator?: OrderComparator<KeyValuePair<TKey, TValue>>): IOrderedEnumerable<KeyValuePair<TKey, TValue>>;
    pairwise(resultSelector?: PairwiseSelector<KeyValuePair<TKey, TValue>, KeyValuePair<TKey, TValue>>): IEnumerable<[KeyValuePair<TKey, TValue>, KeyValuePair<TKey, TValue>]>;
    partition<TFiltered extends KeyValuePair<TKey, TValue>>(predicate: TypePredicate<KeyValuePair<TKey, TValue>, TFiltered>): [IEnumerable<TFiltered>, IEnumerable<Exclude<KeyValuePair<TKey, TValue>, TFiltered>>];
    partition(predicate: Predicate<KeyValuePair<TKey, TValue>>): [IEnumerable<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>];
    percentile(this: Iterable<number>, percent: number, strategy?: PercentileStrategy): number;
    percentile(percent: number, selector: Selector<KeyValuePair<TKey, TValue>, number>, strategy?: PercentileStrategy): number;
    permutations(size?: number): IEnumerable<IEnumerable<KeyValuePair<TKey, TValue>>>;
    pipe<TResult>(operator: PipeOperator<KeyValuePair<TKey, TValue>, TResult>): TResult;
    prepend(element: KeyValuePair<TKey, TValue>): IEnumerable<KeyValuePair<TKey, TValue>>;
    product(this: Iterable<number>): number;
    product(selector: Selector<KeyValuePair<TKey, TValue>, number>): number;
    reverse(): IEnumerable<KeyValuePair<TKey, TValue>>;
    rightJoin<TInner, TGroupKey, TResult>(innerEnumerable: IEnumerable<TInner>, outerKeySelector: Selector<KeyValuePair<TKey, TValue>, TGroupKey>, innerKeySelector: Selector<TInner, TGroupKey>, resultSelector: JoinSelector<KeyValuePair<TKey, TValue> | null, TInner, TResult>, keyComparator?: EqualityComparator<TGroupKey>): IEnumerable<TResult>;
    rotate(shift: number): IEnumerable<KeyValuePair<TKey, TValue>>;
    scan(accumulator: Accumulator<KeyValuePair<TKey, TValue>, KeyValuePair<TKey, TValue>>): IEnumerable<KeyValuePair<TKey, TValue>>;
    scan<TAccumulate>(accumulator: Accumulator<KeyValuePair<TKey, TValue>, TAccumulate>, seed: TAccumulate): IEnumerable<TAccumulate>;
    select<TResult>(selector: IndexedSelector<KeyValuePair<TKey, TValue>, TResult>): IEnumerable<TResult>;
    selectMany<TResult>(selector: IndexedSelector<KeyValuePair<TKey, TValue>, Iterable<TResult>>): IEnumerable<TResult>;
    sequenceEqual(iterable: Iterable<KeyValuePair<TKey, TValue>>, comparator?: EqualityComparator<KeyValuePair<TKey, TValue>>): boolean;
    shuffle(): IEnumerable<KeyValuePair<TKey, TValue>>;
    single<TFiltered extends KeyValuePair<TKey, TValue>>(predicate: TypePredicate<KeyValuePair<TKey, TValue>, TFiltered>): TFiltered;
    single(predicate?: Predicate<KeyValuePair<TKey, TValue>>): KeyValuePair<TKey, TValue>;
    singleOrDefault<TFiltered extends KeyValuePair<TKey, TValue>>(predicate: TypePredicate<KeyValuePair<TKey, TValue>, TFiltered>): TFiltered | null;
    singleOrDefault(predicate?: Predicate<KeyValuePair<TKey, TValue>>): KeyValuePair<TKey, TValue> | null;
    skip(count: number): IEnumerable<KeyValuePair<TKey, TValue>>;
    skipLast(count: number): IEnumerable<KeyValuePair<TKey, TValue>>;
    skipUntil<TFiltered extends KeyValuePair<TKey, TValue>>(predicate: IndexedTypePredicate<KeyValuePair<TKey, TValue>, TFiltered>): IEnumerable<TFiltered>;
    skipUntil(predicate: IndexedPredicate<KeyValuePair<TKey, TValue>>): IEnumerable<KeyValuePair<TKey, TValue>>;
    skipWhile(predicate: IndexedPredicate<KeyValuePair<TKey, TValue>>): IEnumerable<KeyValuePair<TKey, TValue>>;
    span<TFiltered extends KeyValuePair<TKey, TValue>>(predicate: TypePredicate<KeyValuePair<TKey, TValue>, TFiltered>): [IEnumerable<TFiltered>, IEnumerable<KeyValuePair<TKey, TValue>>];
    span(predicate: Predicate<KeyValuePair<TKey, TValue>>): [IEnumerable<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>];
    standardDeviation(selector?: Selector<KeyValuePair<TKey, TValue>, number>, sample?: boolean): number;
    step(stepNumber: number): IEnumerable<KeyValuePair<TKey, TValue>>;
    sum(this: Iterable<number>): number;
    sum(selector: Selector<KeyValuePair<TKey, TValue>, number>): number;
    take(count: number): IEnumerable<KeyValuePair<TKey, TValue>>;
    takeLast(count: number): IEnumerable<KeyValuePair<TKey, TValue>>;
    takeUntil<TFiltered extends KeyValuePair<TKey, TValue>>(predicate: IndexedTypePredicate<KeyValuePair<TKey, TValue>, TFiltered>): IEnumerable<TFiltered>;
    takeUntil(predicate: IndexedPredicate<KeyValuePair<TKey, TValue>>): IEnumerable<KeyValuePair<TKey, TValue>>;
    takeWhile<TFiltered extends KeyValuePair<TKey, TValue>>(predicate: IndexedTypePredicate<KeyValuePair<TKey, TValue>, TFiltered>): IEnumerable<TFiltered>;
    takeWhile(predicate: IndexedPredicate<KeyValuePair<TKey, TValue>>): IEnumerable<KeyValuePair<TKey, TValue>>;
    tap(action: IndexedAction<KeyValuePair<TKey, TValue>>): IEnumerable<KeyValuePair<TKey, TValue>>;
    toArray(): KeyValuePair<TKey, TValue>[];
    toCircularLinkedList(comparator?: EqualityComparator<KeyValuePair<TKey, TValue>>): CircularLinkedList<KeyValuePair<TKey, TValue>>;
    toCircularQueue(comparator?: EqualityComparator<KeyValuePair<TKey, TValue>>): CircularQueue<KeyValuePair<TKey, TValue>>;
    toCircularQueue(capacity: number, comparator?: EqualityComparator<KeyValuePair<TKey, TValue>>): CircularQueue<KeyValuePair<TKey, TValue>>;
    toDictionary<TDictKey, TDictValue>(keySelector: Selector<KeyValuePair<TKey, TValue>, TDictKey>, valueSelector: Selector<KeyValuePair<TKey, TValue>, TDictValue>, valueComparator?: EqualityComparator<TDictValue>): Dictionary<TDictKey, TDictValue>;
    toEnumerableSet(): EnumerableSet<KeyValuePair<TKey, TValue>>;
    toImmutableCircularQueue(comparator?: EqualityComparator<KeyValuePair<TKey, TValue>>): ImmutableCircularQueue<KeyValuePair<TKey, TValue>>;
    toImmutableCircularQueue(capacity: number, comparator?: EqualityComparator<KeyValuePair<TKey, TValue>>): ImmutableCircularQueue<KeyValuePair<TKey, TValue>>;
    toImmutableDictionary<TDictKey, TDictValue>(keySelector: Selector<KeyValuePair<TKey, TValue>, TDictKey>, valueSelector: Selector<KeyValuePair<TKey, TValue>, TDictValue>, valueComparator?: EqualityComparator<TDictValue>): ImmutableDictionary<TDictKey, TDictValue>;
    toImmutableList(comparator?: EqualityComparator<KeyValuePair<TKey, TValue>>): ImmutableList<KeyValuePair<TKey, TValue>>;
    toImmutablePriorityQueue(comparator?: OrderComparator<KeyValuePair<TKey, TValue>>): ImmutablePriorityQueue<KeyValuePair<TKey, TValue>>;
    toImmutableQueue(comparator?: EqualityComparator<KeyValuePair<TKey, TValue>>): ImmutableQueue<KeyValuePair<TKey, TValue>>;
    toImmutableSet(): ImmutableSet<KeyValuePair<TKey, TValue>>;
    toImmutableSortedDictionary<TDictKey, TDictValue>(keySelector: Selector<KeyValuePair<TKey, TValue>, TDictKey>, valueSelector: Selector<KeyValuePair<TKey, TValue>, TDictValue>, keyComparator?: OrderComparator<TDictKey>, valueComparator?: EqualityComparator<TDictValue>): ImmutableSortedDictionary<TDictKey, TDictValue>;
    toImmutableSortedSet(comparator?: OrderComparator<KeyValuePair<TKey, TValue>>): ImmutableSortedSet<KeyValuePair<TKey, TValue>>;
    toImmutableStack(comparator?: EqualityComparator<KeyValuePair<TKey, TValue>>): ImmutableStack<KeyValuePair<TKey, TValue>>;
    toLinkedList(comparator?: EqualityComparator<KeyValuePair<TKey, TValue>>): LinkedList<KeyValuePair<TKey, TValue>>;
    toList(comparator?: EqualityComparator<KeyValuePair<TKey, TValue>>): List<KeyValuePair<TKey, TValue>>;
    toLookup<TLookupKey, TLookupValue>(keySelector: Selector<KeyValuePair<TKey, TValue>, TLookupKey>, valueSelector: Selector<KeyValuePair<TKey, TValue>, TLookupValue>, keyComparator?: OrderComparator<TLookupKey>): ILookup<TLookupKey, TLookupValue>;
    toMap<TMapKey, TMapValue>(keySelector: Selector<KeyValuePair<TKey, TValue>, TMapKey>, valueSelector: Selector<KeyValuePair<TKey, TValue>, TMapValue>): Map<TMapKey, TMapValue>;
    toObject<TObjectKey extends PropertyKey, TObjectValue>(keySelector: Selector<KeyValuePair<TKey, TValue>, TObjectKey>, valueSelector: Selector<KeyValuePair<TKey, TValue>, TObjectValue>): Record<TObjectKey, TObjectValue>;
    toPriorityQueue(comparator?: OrderComparator<KeyValuePair<TKey, TValue>>): PriorityQueue<KeyValuePair<TKey, TValue>>;
    toQueue(comparator?: EqualityComparator<KeyValuePair<TKey, TValue>>): Queue<KeyValuePair<TKey, TValue>>;
    toSet(): Set<KeyValuePair<TKey, TValue>>;
    toSortedDictionary<TDictKey, TDictValue>(keySelector: Selector<KeyValuePair<TKey, TValue>, TDictKey>, valueSelector: Selector<KeyValuePair<TKey, TValue>, TDictValue>, keyComparator?: OrderComparator<TDictKey>, valueComparator?: EqualityComparator<TDictValue>): SortedDictionary<TDictKey, TDictValue>;
    toSortedSet(comparator?: OrderComparator<KeyValuePair<TKey, TValue>>): SortedSet<KeyValuePair<TKey, TValue>>;
    toStack(comparator?: EqualityComparator<KeyValuePair<TKey, TValue>>): Stack<KeyValuePair<TKey, TValue>>;
    toString(): string;
    toString(selector?: Selector<KeyValuePair<TKey, TValue>, string>): string;
    union(iterable: Iterable<KeyValuePair<TKey, TValue>>, comparator?: EqualityComparator<KeyValuePair<TKey, TValue>>): IEnumerable<KeyValuePair<TKey, TValue>>;
    unionBy<TUnionKey>(iterable: Iterable<KeyValuePair<TKey, TValue>>, keySelector: Selector<KeyValuePair<TKey, TValue>, TUnionKey>, comparator?: EqualityComparator<TUnionKey>): IEnumerable<KeyValuePair<TKey, TValue>>;
    variance(selector?: Selector<KeyValuePair<TKey, TValue>, number>, sample?: boolean): number;
    where<TFiltered extends KeyValuePair<TKey, TValue>>(predicate: IndexedTypePredicate<KeyValuePair<TKey, TValue>, TFiltered>): IEnumerable<TFiltered>;
    where(predicate: IndexedPredicate<KeyValuePair<TKey, TValue>>): IEnumerable<KeyValuePair<TKey, TValue>>;
    windows(size: number): IEnumerable<IEnumerable<KeyValuePair<TKey, TValue>>>;
    zip<TSecond, TResult = [KeyValuePair<TKey, TValue>, TSecond]>(iterable: Iterable<TSecond>, zipper?: Zipper<KeyValuePair<TKey, TValue>, TSecond, TResult>): IEnumerable<[KeyValuePair<TKey, TValue>, TSecond]> | IEnumerable<TResult>;
    zipMany<TIterable extends readonly Iterable<unknown>[]>(...iterables: [...TIterable]): IEnumerable<[KeyValuePair<TKey, TValue>, ...UnpackIterableTuple<TIterable>]>;
    zipMany<TIterable extends readonly Iterable<unknown>[], TResult>(...iterablesAndZipper: [...TIterable, ZipManyZipper<[KeyValuePair<TKey, TValue>, ...UnpackIterableTuple<TIterable>], TResult>]): IEnumerable<TResult>;
    get keyValueComparator(): EqualityComparator<KeyValuePair<TKey, TValue>>;
    get valueComparator(): EqualityComparator<TValue>;
    abstract [Symbol.iterator](): Iterator<KeyValuePair<TKey, TValue>>;
    abstract containsKey(key: TKey): boolean;
    abstract containsValue(value: TValue, comparator?: EqualityComparator<TValue>): boolean;
    abstract entries(): IterableIterator<[TKey, TValue]>;
    abstract get(key: TKey): TValue | null;
    abstract keys(): ISet<TKey>;
    abstract size(): number;
    abstract values(): IImmutableCollection<TValue>;
    abstract get length(): number;
}

export declare abstract class AbstractSet<TElement> extends AbstractRandomAccessCollection<TElement> implements ISet<TElement> {
    protected constructor(comparator?: EqualityComparator<TElement>);
    exceptWith(other: Iterable<TElement>): void;
    intersectWith(other: Iterable<TElement>): void;
    isProperSubsetOf(other: Iterable<TElement>): boolean;
    isProperSupersetOf(other: Iterable<TElement>): boolean;
    isSubsetOf(other: Iterable<TElement>): boolean;
    isSupersetOf(other: Iterable<TElement>): boolean;
    overlaps(other: Iterable<TElement>): boolean;
}

export declare abstract class AbstractTree<TElement> extends AbstractRandomAccessCollection<TElement> implements ITree<TElement> {
    protected readonly orderComparator: OrderComparator<TElement>;
    protected root: INode<TElement> | null;
    protected treeSize: number;
    protected constructor(comparator?: OrderComparator<TElement>);
    [Symbol.iterator](): Iterator<TElement>;
    clear(): void;
    contains(element: TElement, comparator?: EqualityComparator<TElement>): boolean;
    find(predicate: Predicate<TElement>): TElement | null;
    findBy<TKey>(key: TKey, selector: Selector<TElement, TKey>, comparator?: OrderComparator<TKey>): TElement | null;
    forEach(action: IndexedAction<TElement>): void;
    getRootData(): TElement | null;
    isEmpty(): boolean;
    remove(element: TElement): boolean;
    removeBy<TKey>(key: TKey, selector: Selector<TElement, TKey>, comparator?: OrderComparator<TKey>): TElement | null;
    size(): number;
    toArray(): TElement[];
    traverseToArray(direction?: TraverseType): TElement[];
    get length(): number;
    protected toInorderArray(root: INode<TElement> | null, target: TElement[]): void;
    protected toPostorderArray(root: INode<TElement> | null, target: TElement[]): void;
    protected toPreorderArray(root: INode<TElement> | null, target: TElement[]): void;
    private containsRecursive;
    private findByRecursive;
    private findRecursive;
    private removeByRecursive;
    private toArrayRecursive;
    abstract add(element: TElement): boolean;
    abstract delete(element: TElement): void;
    abstract insert(element: TElement): void;
    abstract search(element: TElement): boolean;
}

export declare interface Accumulator<TElement, TAccumulate> {
    (acc: TAccumulate, item: TElement): TAccumulate;
}

/**
 * Combines the elements of the sequence by applying an accumulator to each element and optionally projecting the final result.
 * @template TElement Type of elements within the `source` iterable.
 * @template TAccumulate Type of the intermediate accumulator. Defaults to `TElement` when no seed is provided.
 * @template TResult Type returned when a `resultSelector` is supplied.
 * @param source The source iterable.
 * @param accumulator Function that merges the running accumulator with the next element.
 * @param seed Optional initial accumulator value. When omitted, the first element is used as the starting accumulator.
 * @param resultSelector Optional projection applied to the final accumulator before it is returned.
 * @returns {TAccumulate|TResult} The final accumulator (or its projection).
 * @throws {NoElementsException} Thrown when `source` has no elements and no `seed` is provided.
 * @remarks The source sequence is enumerated exactly once. Supply a `seed` to avoid exceptions on empty sequences and to control the accumulator type.
 * @example
 * ```typescript
 * const numbers = [1, 2, 3, 4, 5];
 * const sum = aggregate(numbers, (acc, x) => acc + x);
 * console.log(sum); // 15
 *
 * const product = aggregate(numbers, (acc, x) => acc * x, 1);
 * console.log(product); // 120
 * ```
 */
export declare function aggregate<TElement>(source: Iterable<TElement>, accumulator: Accumulator<TElement, TElement>): TElement;

export declare function aggregate<TElement, TAccumulate>(source: Iterable<TElement>, accumulator: Accumulator<TElement, TAccumulate>, seed: TAccumulate): TAccumulate;

export declare function aggregate<TElement, TAccumulate, TResult>(source: Iterable<TElement>, accumulator: Accumulator<TElement, TAccumulate>, seed: TAccumulate, resultSelector: Selector<TAccumulate, TResult>): TResult;

/**
 * Groups elements by a computed key and aggregates each group by applying an accumulator within that group.
 * @template TElement Type of elements within the `source` iterable.
 * @template TKey Type returned by `keySelector` and used to organise groups.
 * @template TAccumulate Type of the accumulated value created for each group.
 * @param source The source iterable.
 * @param keySelector Selector that derives the grouping key for each element.
 * @param seedSelector Either an initial accumulator value applied to every group or a factory invoked with the group key to produce that value.
 * @param accumulator Function that merges the current accumulator with the next element in the group.
 * @param keyComparator Optional equality comparator used to match group keys.
 * @returns {IEnumerable<KeyValuePair<TKey, TAccumulate>>} A sequence containing one key-value pair per group and its aggregated result.
 * @remarks When `seedSelector` is a factory function, it is evaluated once per group to obtain the initial accumulator.
 * @example
 * ```typescript
 * const products = [
 *   { name: 'Apple', category: 'Fruit', price: 1.2 },
 *   { name: 'Banana', category: 'Fruit', price: 0.5 },
 *   { name: 'Carrot', category: 'Vegetable', price: 0.8 },
 *   { name: 'Broccoli', category: 'Vegetable', price: 1.5 },
 * ];
 *
 * const totalPriceByCategory = aggregateBy(
 *   from(products),
 *   p => p.category,
 *   0,
 *   (acc, p) => acc + p.price
 * ).toArray();
 *
 * console.log(totalPriceByCategory);
 * // [
 * //   { key: 'Fruit', value: 1.7 },
 * //   { key: 'Vegetable', value: 2.3 }
 * // ]
 * ```
 */
export declare const aggregateBy: <TElement, TKey, TAccumulate = TElement>(source: IEnumerable<TElement>, keySelector: Selector<TElement, TKey>, seedSelector: Selector<TKey, TAccumulate> | TAccumulate, accumulator: Accumulator<TElement, TAccumulate>, keyComparator?: EqualityComparator<TKey>) => IEnumerable<KeyValuePair<TKey, TAccumulate>>;

/**
 * Determines whether every element in the sequence satisfies the supplied predicate.
 * @template TElement Type of elements within the `source` iterable.
 * @param source The source iterable.
 * @param predicate Function that evaluates each element and returns `true` when it satisfies the condition.
 * @returns {boolean} `true` when all elements satisfy the predicate; otherwise, `false`.
 * @remarks Enumeration stops as soon as the predicate returns `false`.
 * @example
 * ```typescript
 * const numbers = [1, 2, 3, 4, 5];
 * const allPositive = all(numbers, x => x > 0);
 * console.log(allPositive); // true
 *
 * const mixedNumbers = [-1, 2, 3, -4, 5];
 * const allPositive2 = all(mixedNumbers, x => x > 0);
 * console.log(allPositive2); // false
 * ```
 */
export declare const all: <TElement>(source: Iterable<TElement>, predicate: Predicate<TElement>) => boolean;

/**
 * Determines whether the sequence contains at least one element that matches the optional predicate.
 * @template TElement Type of elements within the `source` iterable.
 * @param source The source iterable.
 * @param predicate Optional function used to test elements. When omitted, the function returns `true` if `source` contains any element.
 * @returns {boolean} `true` when a matching element is found; otherwise, `false`.
 * @remarks When the predicate is omitted, only the first element is inspected, making this more efficient than `count(source) > 0`.
 * @example
 * ```typescript
 * const numbers = [1, 2, 3, 4, 5];
 * const hasEvenNumber = any(numbers, x => x % 2 === 0);
 * console.log(hasEvenNumber); // true
 *
 * const oddNumbers = [1, 3, 5];
 * const hasEvenNumber2 = any(oddNumbers, x => x % 2 === 0);
 * console.log(hasEvenNumber2); // false
 * ```
 */
export declare const any: <TElement>(source: Iterable<TElement>, predicate?: Predicate<TElement>) => boolean;

/**
 * Creates a sequence that yields the current elements followed by the supplied element.
 * @template TElement Type of elements within the `source` iterable.
 * @param source The source iterable.
 * @param element Element appended to the end of the sequence.
 * @returns {IEnumerable<TElement>} A new enumerable whose final item is the provided element.
 * @remarks The source sequence is not modified; enumeration is deferred until the returned sequence is iterated.
 * @example
 * ```typescript
 * const numbers = [1, 2, 3];
 * const appended = append(numbers, 4).toArray();
 * console.log(appended); // [1, 2, 3, 4]
 * ```
 */
export declare const append: <TElement>(source: Iterable<TElement>, element: TElement) => IEnumerable<TElement>;

export declare class AsyncEnumerable<TElement> implements IAsyncEnumerable<TElement> {
    #private;
    private readonly iterable;
    constructor(iterable: AsyncIterable<TElement>);
    static empty<TSource>(): IAsyncEnumerable<TSource>;
    static from<TSource>(source: AsyncIterable<TSource>): IAsyncEnumerable<TSource>;
    static infiniteSequence(start: number, step: number): IAsyncEnumerable<number>;
    static range(start: number, count: number): IAsyncEnumerable<number>;
    static repeat<TSource>(element: TSource, count: number): IAsyncEnumerable<TSource>;
    static sequence(start: number, end: number, step: number): IAsyncEnumerable<number>;
    [Symbol.asyncIterator](): AsyncIterator<TElement>;
    aggregate(accumulator: Accumulator<TElement, TElement>): Promise<TElement>;
    aggregate<TAccumulate>(accumulator: Accumulator<TElement, TAccumulate>, seed: TAccumulate): Promise<TAccumulate>;
    aggregate<TAccumulate, TResult>(accumulator: Accumulator<TElement, TAccumulate>, seed: TAccumulate, resultSelector: Selector<TAccumulate, TResult>): Promise<TResult>;
    aggregateBy<TKey, TAccumulate = TElement>(keySelector: Selector<TElement, TKey>, seedSelector: Selector<TKey, TAccumulate> | TAccumulate, accumulator: Accumulator<TElement, TAccumulate>, keyComparator?: EqualityComparator<TKey>): IAsyncEnumerable<KeyValuePair<TKey, TAccumulate>>;
    all(predicate: Predicate<TElement>): Promise<boolean>;
    any(predicate?: Predicate<TElement>): Promise<boolean>;
    append(element: TElement): IAsyncEnumerable<TElement>;
    atLeast(count: number, predicate?: Predicate<TElement>): Promise<boolean>;
    atMost(count: number, predicate?: Predicate<TElement>): Promise<boolean>;
    average(this: AsyncIterable<number>): Promise<number>;
    average(selector: Selector<TElement, number>): Promise<number>;
    cartesian<TSecond>(iterable: AsyncIterable<TSecond>): IAsyncEnumerable<[TElement, TSecond]>;
    cast<TResult>(): IAsyncEnumerable<TResult>;
    chunk(count: number): IAsyncEnumerable<IEnumerable<TElement>>;
    combinations(size?: number): IAsyncEnumerable<IEnumerable<TElement>>;
    compact(): IAsyncEnumerable<NonNullable<TElement>>;
    concat(other: AsyncIterable<TElement>): IAsyncEnumerable<TElement>;
    contains(element: TElement, comparator?: EqualityComparator<TElement>): Promise<boolean>;
    correlation<TSecond>(iterable: AsyncIterable<TSecond>, selector?: Selector<TElement, number>, otherSelector?: Selector<TSecond, number>): Promise<number>;
    correlationBy(leftSelector: Selector<TElement, number>, rightSelector: Selector<TElement, number>): Promise<number>;
    count(predicate?: Predicate<TElement>): Promise<number>;
    countBy<TKey>(keySelector: Selector<TElement, TKey>, comparator?: EqualityComparator<TKey>): IAsyncEnumerable<KeyValuePair<TKey, number>>;
    covariance<TSecond>(iterable: AsyncIterable<TSecond>, selector?: Selector<TElement, number>, otherSelector?: Selector<TSecond, number>, sample?: boolean): Promise<number>;
    covarianceBy(leftSelector: Selector<TElement, number>, rightSelector: Selector<TElement, number>, sample?: boolean): Promise<number>;
    cycle(count?: number): IAsyncEnumerable<TElement>;
    defaultIfEmpty(defaultValue?: TElement | null): IAsyncEnumerable<TElement | null>;
    disjoint<TSecond>(iterable: AsyncIterable<TSecond>, comparator?: EqualityComparator<TElement | TSecond>): Promise<boolean>;
    disjointBy<TSecond, TKey, TSecondKey>(iterable: AsyncIterable<TSecond>, keySelector: Selector<TElement, TKey>, otherKeySelector: Selector<TSecond, TSecondKey>, keyComparator?: EqualityComparator<TKey | TSecondKey>): Promise<boolean>;
    distinct(keyComparator?: EqualityComparator<TElement>): IAsyncEnumerable<TElement>;
    distinctBy<TKey>(keySelector: Selector<TElement, TKey>, keyComparator?: EqualityComparator<TKey>): IAsyncEnumerable<TElement>;
    distinctUntilChanged(comparator?: EqualityComparator<TElement>): IAsyncEnumerable<TElement>;
    distinctUntilChangedBy<TKey>(keySelector: Selector<TElement, TKey>, keyComparator?: EqualityComparator<TKey>): IAsyncEnumerable<TElement>;
    elementAt(index: number): Promise<TElement>;
    elementAtOrDefault(index: number): Promise<TElement | null>;
    exactly(count: number, predicate?: Predicate<TElement>): Promise<boolean>;
    except(iterable: AsyncIterable<TElement>, comparator?: EqualityComparator<TElement> | OrderComparator<TElement>): IAsyncEnumerable<TElement>;
    exceptBy<TKey>(enumerable: AsyncIterable<TElement>, keySelector: Selector<TElement, TKey>, comparator?: EqualityComparator<TKey> | OrderComparator<TKey>): IAsyncEnumerable<TElement>;
    first<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): Promise<TFiltered>;
    first(predicate?: Predicate<TElement>): Promise<TElement>;
    firstOrDefault<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): Promise<TFiltered | null>;
    firstOrDefault(predicate?: Predicate<TElement>): Promise<TElement | null>;
    forEach(action: IndexedAction<TElement>): Promise<void>;
    groupBy<TKey>(keySelector: Selector<TElement, TKey>, keyComparator?: EqualityComparator<TKey>, hashSelector?: Selector<TElement, PropertyKey>): IAsyncEnumerable<IGroup<TKey, TElement>>;
    groupJoin<TInner, TKey, TResult>(inner: IAsyncEnumerable<TInner>, outerKeySelector: Selector<TElement, TKey>, innerKeySelector: Selector<TInner, TKey>, resultSelector: JoinSelector<TElement, IEnumerable<TInner>, TResult>, keyComparator?: EqualityComparator<TKey>): IAsyncEnumerable<TResult>;
    index(): IAsyncEnumerable<[number, TElement]>;
    interleave<TSecond>(iterable: AsyncIterable<TSecond>): IAsyncEnumerable<TElement | TSecond>;
    intersect(iterable: AsyncIterable<TElement>, comparator?: EqualityComparator<TElement> | OrderComparator<TElement>): IAsyncEnumerable<TElement>;
    intersectBy<TKey>(enumerable: AsyncIterable<TElement>, keySelector: Selector<TElement, TKey>, comparator?: EqualityComparator<TKey> | OrderComparator<TKey>): IAsyncEnumerable<TElement>;
    intersperse<TSeparator = TElement>(separator: TSeparator): IAsyncEnumerable<TElement | TSeparator>;
    join<TInner, TKey, TResult>(inner: IAsyncEnumerable<TInner>, outerKeySelector: Selector<TElement, TKey>, innerKeySelector: Selector<TInner, TKey>, resultSelector: JoinSelector<TElement, TInner, TResult>, keyComparator?: EqualityComparator<TKey>): IAsyncEnumerable<TResult>;
    last<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): Promise<TFiltered>;
    last(predicate?: Predicate<TElement>): Promise<TElement>;
    lastOrDefault<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): Promise<TFiltered | null>;
    lastOrDefault(predicate?: Predicate<TElement>): Promise<TElement | null>;
    leftJoin<TInner, TKey, TResult>(inner: IAsyncEnumerable<TInner>, outerKeySelector: Selector<TElement, TKey>, innerKeySelector: Selector<TInner, TKey>, resultSelector: JoinSelector<TElement, TInner, TResult>, keyComparator?: EqualityComparator<TKey>): IAsyncEnumerable<TResult>;
    max(this: AsyncIterable<number>): Promise<number>;
    max(selector: Selector<TElement, number>): Promise<number>;
    maxBy<TKey>(keySelector: Selector<TElement, TKey>, comparator?: OrderComparator<TKey>): Promise<TElement>;
    median(selector?: Selector<TElement, number>, tie?: MedianTieStrategy): Promise<number>;
    min(this: AsyncIterable<number>): Promise<number>;
    min(selector: Selector<TElement, number>): Promise<number>;
    minBy<TKey>(keySelector: Selector<TElement, TKey>, comparator?: OrderComparator<TKey>): Promise<TElement>;
    mode<TKey>(keySelector?: Selector<TElement, TKey>): Promise<TElement>;
    modeOrDefault<TKey>(keySelector?: Selector<TElement, TKey>): Promise<TElement | null>;
    multimode<TKey>(keySelector?: Selector<TElement, TKey>): IAsyncEnumerable<TElement>;
    none(predicate?: Predicate<TElement>): Promise<boolean>;
    ofType<TResult extends ObjectType>(type: TResult): IAsyncEnumerable<InferredType<TResult>>;
    order(comparator?: OrderComparator<TElement>): IOrderedAsyncEnumerable<TElement>;
    orderBy<TKey>(keySelector: Selector<TElement, TKey>, comparator?: OrderComparator<TKey>): IOrderedAsyncEnumerable<TElement>;
    orderByDescending<TKey>(keySelector: Selector<TElement, TKey>, comparator?: OrderComparator<TKey>): IOrderedAsyncEnumerable<TElement>;
    orderDescending(comparator?: OrderComparator<TElement>): IOrderedAsyncEnumerable<TElement>;
    pairwise(resultSelector: PairwiseSelector<TElement, TElement>): IAsyncEnumerable<[TElement, TElement]>;
    partition<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): Promise<[IEnumerable<TFiltered>, IEnumerable<Exclude<TElement, TFiltered>>]>;
    partition(predicate: Predicate<TElement>): Promise<[IEnumerable<TElement>, IEnumerable<TElement>]>;
    percentile(this: AsyncIterable<number>, percent: number, strategy?: PercentileStrategy): Promise<number>;
    percentile(percent: number, selector: Selector<TElement, number>, strategy?: PercentileStrategy): Promise<number>;
    permutations(size?: number): IAsyncEnumerable<IEnumerable<TElement>>;
    pipe<TResult>(operator: AsyncPipeOperator<TElement, TResult>): Promise<TResult>;
    prepend(element: TElement): IAsyncEnumerable<TElement>;
    product(this: AsyncIterable<number>): Promise<number>;
    product(selector: Selector<TElement, number>): Promise<number>;
    reverse(): IAsyncEnumerable<TElement>;
    rightJoin<TInner, TKey, TResult>(inner: IAsyncEnumerable<TInner>, outerKeySelector: Selector<TElement, TKey>, innerKeySelector: Selector<TInner, TKey>, resultSelector: JoinSelector<TElement | null, TInner, TResult>, keyComparator?: EqualityComparator<TKey>): IAsyncEnumerable<TResult>;
    rotate(shift: number): IAsyncEnumerable<TElement>;
    scan(accumulator: Accumulator<TElement, TElement>): IAsyncEnumerable<TElement>;
    scan<TAccumulate>(accumulator: Accumulator<TElement, TAccumulate>, seed: TAccumulate): IAsyncEnumerable<TAccumulate>;
    select<TResult>(selector: IndexedSelector<TElement, TResult>): IAsyncEnumerable<TResult>;
    selectMany<TResult>(selector: IndexedSelector<TElement, Iterable<TResult>>): IAsyncEnumerable<TResult>;
    sequenceEqual(iterable: AsyncIterable<TElement>, comparator?: EqualityComparator<TElement>): Promise<boolean>;
    shuffle(): IAsyncEnumerable<TElement>;
    single<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): Promise<TFiltered>;
    single(predicate?: Predicate<TElement>): Promise<TElement>;
    singleOrDefault<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): Promise<TFiltered | null>;
    singleOrDefault(predicate?: Predicate<TElement>): Promise<TElement | null>;
    skip(count: number): IAsyncEnumerable<TElement>;
    skipLast(count: number): IAsyncEnumerable<TElement>;
    skipUntil<TFiltered extends TElement>(predicate: IndexedTypePredicate<TElement, TFiltered>): IAsyncEnumerable<TFiltered>;
    skipUntil(predicate: IndexedPredicate<TElement>): IAsyncEnumerable<TElement>;
    skipWhile(predicate: IndexedPredicate<TElement>): IAsyncEnumerable<TElement>;
    span<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): Promise<[IEnumerable<TFiltered>, IEnumerable<TElement>]>;
    span(predicate: Predicate<TElement>): Promise<[IEnumerable<TElement>, IEnumerable<TElement>]>;
    standardDeviation(selector?: Selector<TElement, number>, sample?: boolean): Promise<number>;
    step(step: number): IAsyncEnumerable<TElement>;
    sum(this: AsyncIterable<number>): Promise<number>;
    sum(selector: Selector<TElement, number>): Promise<number>;
    take(count: number): IAsyncEnumerable<TElement>;
    takeLast(count: number): IAsyncEnumerable<TElement>;
    takeUntil<TFiltered extends TElement>(predicate: IndexedTypePredicate<TElement, TFiltered>): IAsyncEnumerable<TFiltered>;
    takeUntil(predicate: IndexedPredicate<TElement>): IAsyncEnumerable<TElement>;
    takeWhile<TFiltered extends TElement>(predicate: IndexedTypePredicate<TElement, TFiltered>): IAsyncEnumerable<TFiltered>;
    takeWhile(predicate: IndexedPredicate<TElement>): IAsyncEnumerable<TElement>;
    tap(action: IndexedAction<TElement>): IAsyncEnumerable<TElement>;
    toArray(): Promise<TElement[]>;
    toCircularLinkedList(comparator?: EqualityComparator<TElement>): Promise<CircularLinkedList<TElement>>;
    toCircularQueue(comparator?: EqualityComparator<TElement>): Promise<CircularQueue<TElement>>;
    toCircularQueue(capacity: number, comparator?: EqualityComparator<TElement>): Promise<CircularQueue<TElement>>;
    toDictionary<TKey, TValue>(keySelector: Selector<TElement, TKey>, valueSelector: Selector<TElement, TValue>, valueComparator?: EqualityComparator<TValue>): Promise<Dictionary<TKey, TValue>>;
    toEnumerableSet(): Promise<EnumerableSet<TElement>>;
    toImmutableCircularQueue(comparator?: EqualityComparator<TElement>): Promise<ImmutableCircularQueue<TElement>>;
    toImmutableCircularQueue(capacity: number, comparator?: EqualityComparator<TElement>): Promise<ImmutableCircularQueue<TElement>>;
    toImmutableDictionary<TKey, TValue>(keySelector: Selector<TElement, TKey>, valueSelector: Selector<TElement, TValue>, valueComparator?: EqualityComparator<TValue>): Promise<ImmutableDictionary<TKey, TValue>>;
    toImmutableList(comparator?: EqualityComparator<TElement>): Promise<ImmutableList<TElement>>;
    toImmutablePriorityQueue(comparator?: OrderComparator<TElement>): Promise<ImmutablePriorityQueue<TElement>>;
    toImmutableQueue(comparator?: EqualityComparator<TElement>): Promise<ImmutableQueue<TElement>>;
    toImmutableSet(): Promise<ImmutableSet<TElement>>;
    toImmutableSortedDictionary<TKey, TValue>(keySelector: Selector<TElement, TKey>, valueSelector: Selector<TElement, TValue>, keyComparator?: OrderComparator<TKey>, valueComparator?: EqualityComparator<TValue>): Promise<ImmutableSortedDictionary<TKey, TValue>>;
    toImmutableSortedSet(comparator?: OrderComparator<TElement>): Promise<ImmutableSortedSet<TElement>>;
    toImmutableStack(comparator?: EqualityComparator<TElement>): Promise<ImmutableStack<TElement>>;
    toLinkedList(comparator?: EqualityComparator<TElement>): Promise<LinkedList<TElement>>;
    toList(comparator?: EqualityComparator<TElement>): Promise<List<TElement>>;
    toLookup<TKey, TValue>(keySelector: Selector<TElement, TKey>, valueSelector: Selector<TElement, TValue>, keyComparator?: OrderComparator<TKey>): Promise<ILookup<TKey, TValue>>;
    toMap<TKey, TValue>(keySelector: Selector<TElement, TKey>, valueSelector: Selector<TElement, TValue>): Promise<Map<TKey, TValue>>;
    toObject<TKey extends string | number | symbol, TValue>(keySelector: Selector<TElement, TKey>, valueSelector: Selector<TElement, TValue>): Promise<Record<TKey, TValue>>;
    toPriorityQueue(comparator?: OrderComparator<TElement>): Promise<PriorityQueue<TElement>>;
    toQueue(comparator?: EqualityComparator<TElement>): Promise<Queue<TElement>>;
    toSet(): Promise<Set<TElement>>;
    toSortedDictionary<TKey, TValue>(keySelector: Selector<TElement, TKey>, valueSelector: Selector<TElement, TValue>, keyComparator?: OrderComparator<TKey>, valueComparator?: EqualityComparator<TValue>): Promise<SortedDictionary<TKey, TValue>>;
    toSortedSet(comparator?: OrderComparator<TElement>): Promise<SortedSet<TElement>>;
    toStack(comparator?: EqualityComparator<TElement>): Promise<Stack<TElement>>;
    union(iterable: AsyncIterable<TElement>, comparator?: EqualityComparator<TElement>): IAsyncEnumerable<TElement>;
    unionBy<TKey>(enumerable: AsyncIterable<TElement>, keySelector: Selector<TElement, TKey>, comparator?: EqualityComparator<TKey>): IAsyncEnumerable<TElement>;
    variance(selector?: Selector<TElement, number>, sample?: boolean): Promise<number>;
    where<TFiltered extends TElement>(predicate: IndexedTypePredicate<TElement, TFiltered>): IAsyncEnumerable<TFiltered>;
    where(predicate: IndexedPredicate<TElement>): IAsyncEnumerable<TElement>;
    windows(size: number): IAsyncEnumerable<IEnumerable<TElement>>;
    zip<TSecond>(iterable: AsyncIterable<TSecond>): IAsyncEnumerable<[TElement, TSecond]>;
    zip<TSecond, TResult = [TElement, TSecond]>(iterable: AsyncIterable<TSecond>, zipper: Zipper<TElement, TSecond, TResult>): IAsyncEnumerable<TResult>;
    zipMany<TIterable extends readonly AsyncIterable<unknown>[]>(...iterables: [...TIterable]): IAsyncEnumerable<[TElement, ...UnpackAsyncIterableTuple<TIterable>]>;
    zipMany<TIterable extends readonly AsyncIterable<unknown>[], TResult>(...iterablesAndZipper: [...TIterable, ZipManyZipper<[TElement, ...UnpackAsyncIterableTuple<TIterable>], TResult>]): IAsyncEnumerable<TResult>;
}

export declare class AsyncEnumerator<TElement> implements IAsyncEnumerable<TElement> {
    private readonly iterable;
    private static readonly DIMENSION_MISMATCH_EXCEPTION;
    private static readonly MORE_THAN_ONE_ELEMENT_EXCEPTION;
    private static readonly MORE_THAN_ONE_MATCHING_ELEMENT_EXCEPTION;
    private static readonly NO_ELEMENTS_EXCEPTION;
    private static readonly NO_MATCHING_ELEMENT_EXCEPTION;
    constructor(iterable: () => AsyncIterable<TElement>);
    [Symbol.asyncIterator](): AsyncIterator<TElement>;
    aggregate(accumulator: Accumulator<TElement, TElement>): Promise<TElement>;
    aggregate<TAccumulate>(accumulator: Accumulator<TElement, TAccumulate>, seed: TAccumulate): Promise<TAccumulate>;
    aggregate<TAccumulate, TResult>(accumulator: Accumulator<TElement, TAccumulate>, seed: TAccumulate, resultSelector: Selector<TAccumulate, TResult>): Promise<TResult>;
    aggregateBy<TKey, TAccumulate = TElement>(keySelector: Selector<TElement, TKey>, seedSelector: Selector<TKey, TAccumulate> | TAccumulate, accumulator: Accumulator<TElement, TAccumulate>, keyComparator?: EqualityComparator<TKey>): IAsyncEnumerable<KeyValuePair<TKey, TAccumulate>>;
    all(predicate: Predicate<TElement>): Promise<boolean>;
    any(predicate?: Predicate<TElement>): Promise<boolean>;
    append(element: TElement): IAsyncEnumerable<TElement>;
    atLeast(count: number, predicate?: Predicate<TElement>): Promise<boolean>;
    atMost(count: number, predicate?: Predicate<TElement>): Promise<boolean>;
    average(this: AsyncIterable<number>): Promise<number>;
    average(selector: Selector<TElement, number>): Promise<number>;
    cartesian<TSecond>(iterable: AsyncIterable<TSecond>): IAsyncEnumerable<[TElement, TSecond]>;
    cast<TResult>(): IAsyncEnumerable<TResult>;
    chunk(size: number): IAsyncEnumerable<IEnumerable<TElement>>;
    combinations(size?: number): IAsyncEnumerable<IEnumerable<TElement>>;
    compact(): IAsyncEnumerable<NonNullable<TElement>>;
    concat(other: AsyncIterable<TElement>): IAsyncEnumerable<TElement>;
    contains(element: TElement, comparator?: EqualityComparator<TElement>): Promise<boolean>;
    correlation<TSecond>(iterable: AsyncIterable<TSecond>, selector?: Selector<TElement, number>, otherSelector?: Selector<TSecond, number>): Promise<number>;
    correlationBy(leftSelector: Selector<TElement, number>, rightSelector: Selector<TElement, number>): Promise<number>;
    count(predicate?: Predicate<TElement>): Promise<number>;
    countBy<TKey>(keySelector: Selector<TElement, TKey>, comparator?: EqualityComparator<TKey>): IAsyncEnumerable<KeyValuePair<TKey, number>>;
    covariance<TSecond>(iterable: AsyncIterable<TSecond>, selector?: Selector<TElement, number>, otherSelector?: Selector<TSecond, number>, sample?: boolean): Promise<number>;
    covarianceBy(leftSelector: Selector<TElement, number>, rightSelector: Selector<TElement, number>, sample?: boolean): Promise<number>;
    cycle(count?: number): IAsyncEnumerable<TElement>;
    defaultIfEmpty(defaultValue?: TElement | null): IAsyncEnumerable<TElement | null>;
    disjoint<TSecond>(iterable: AsyncIterable<TSecond>, comparator?: EqualityComparator<TElement | TSecond>): Promise<boolean>;
    disjointBy<TSecond, TKey, TSecondKey>(iterable: AsyncIterable<TSecond>, keySelector: Selector<TElement, TKey>, otherKeySelector: Selector<TSecond, TSecondKey>, keyComparator?: EqualityComparator<TKey | TSecondKey>): Promise<boolean>;
    distinct(keyComparator?: EqualityComparator<TElement>): IAsyncEnumerable<TElement>;
    distinctBy<TKey>(keySelector: Selector<TElement, TKey>, keyComparator?: EqualityComparator<TKey>): IAsyncEnumerable<TElement>;
    distinctUntilChanged(comparator?: EqualityComparator<TElement>): IAsyncEnumerable<TElement>;
    distinctUntilChangedBy<TKey>(keySelector: Selector<TElement, TKey>, keyComparator?: EqualityComparator<TKey>): IAsyncEnumerable<TElement>;
    elementAt(index: number): Promise<TElement>;
    elementAtOrDefault(index: number): Promise<TElement | null>;
    exactly(count: number, predicate?: Predicate<TElement>): Promise<boolean>;
    except(iterable: AsyncIterable<TElement>, comparator?: EqualityComparator<TElement> | OrderComparator<TElement>): IAsyncEnumerable<TElement>;
    exceptBy<TKey>(enumerable: AsyncIterable<TElement>, keySelector: Selector<TElement, TKey>, comparator?: EqualityComparator<TKey> | OrderComparator<TKey>): IAsyncEnumerable<TElement>;
    first<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): Promise<TFiltered>;
    first(predicate?: Predicate<TElement>): Promise<TElement>;
    firstOrDefault<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): Promise<TFiltered | null>;
    firstOrDefault(predicate?: Predicate<TElement>): Promise<TElement | null>;
    forEach(action: IndexedAction<TElement>): Promise<void>;
    groupBy<TKey>(keySelector: Selector<TElement, TKey>, keyComparator?: EqualityComparator<TKey>, hashSelector?: Selector<TElement, PropertyKey>): IAsyncEnumerable<IGroup<TKey, TElement>>;
    groupJoin<TInner, TKey, TResult>(inner: IAsyncEnumerable<TInner>, outerKeySelector: Selector<TElement, TKey>, innerKeySelector: Selector<TInner, TKey>, resultSelector: JoinSelector<TElement, IEnumerable<TInner>, TResult>, keyComparator?: EqualityComparator<TKey>): IAsyncEnumerable<TResult>;
    index(): IAsyncEnumerable<[number, TElement]>;
    interleave<TSecond>(iterable: AsyncIterable<TSecond>): IAsyncEnumerable<TElement | TSecond>;
    intersect(iterable: AsyncIterable<TElement>, comparator?: EqualityComparator<TElement> | OrderComparator<TElement>): IAsyncEnumerable<TElement>;
    intersectBy<TKey>(enumerable: AsyncIterable<TElement>, keySelector: Selector<TElement, TKey>, comparator?: EqualityComparator<TKey> | OrderComparator<TKey>): IAsyncEnumerable<TElement>;
    intersperse<TSeparator = TElement>(separator: TSeparator): IAsyncEnumerable<TElement | TSeparator>;
    join<TInner, TKey, TResult>(inner: IAsyncEnumerable<TInner>, outerKeySelector: Selector<TElement, TKey>, innerKeySelector: Selector<TInner, TKey>, resultSelector: JoinSelector<TElement, TInner, TResult>, keyComparator?: EqualityComparator<TKey>): IAsyncEnumerable<TResult>;
    last<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): Promise<TFiltered>;
    last(predicate?: Predicate<TElement>): Promise<TElement>;
    lastOrDefault<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): Promise<TFiltered | null>;
    lastOrDefault(predicate?: Predicate<TElement>): Promise<TElement | null>;
    leftJoin<TInner, TKey, TResult>(inner: IAsyncEnumerable<TInner>, outerKeySelector: Selector<TElement, TKey>, innerKeySelector: Selector<TInner, TKey>, resultSelector: JoinSelector<TElement, TInner, TResult>, keyComparator?: EqualityComparator<TKey>): IAsyncEnumerable<TResult>;
    max(this: AsyncIterable<number>): Promise<number>;
    max(selector: Selector<TElement, number>): Promise<number>;
    maxBy<TKey>(keySelector: Selector<TElement, TKey>, comparator?: OrderComparator<TKey>): Promise<TElement>;
    median(selector?: Selector<TElement, number>, tie?: MedianTieStrategy): Promise<number>;
    min(this: AsyncIterable<number>): Promise<number>;
    min(selector: Selector<TElement, number>): Promise<number>;
    minBy<TKey>(keySelector: Selector<TElement, TKey>, comparator?: OrderComparator<TKey>): Promise<TElement>;
    mode<TKey>(keySelector?: Selector<TElement, TKey>): Promise<TElement>;
    modeOrDefault<TKey>(keySelector?: Selector<TElement, TKey>): Promise<TElement | null>;
    multimode<TKey>(keySelector?: Selector<TElement, TKey>): IAsyncEnumerable<TElement>;
    none(predicate?: Predicate<TElement>): Promise<boolean>;
    ofType<TResult extends ObjectType>(type: TResult): IAsyncEnumerable<InferredType<TResult>>;
    order(comparator?: OrderComparator<TElement>): IOrderedAsyncEnumerable<TElement>;
    orderBy<TKey>(keySelector: Selector<TElement, TKey>, comparator?: OrderComparator<TKey>): IOrderedAsyncEnumerable<TElement>;
    orderByDescending<TKey>(keySelector: Selector<TElement, TKey>, comparator?: OrderComparator<TKey>): IOrderedAsyncEnumerable<TElement>;
    orderDescending(comparator?: OrderComparator<TElement>): IOrderedAsyncEnumerable<TElement>;
    pairwise(resultSelector: PairwiseSelector<TElement, TElement>): IAsyncEnumerable<[TElement, TElement]>;
    partition<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): Promise<[IEnumerable<TFiltered>, IEnumerable<Exclude<TElement, TFiltered>>]>;
    partition(predicate: Predicate<TElement>): Promise<[IEnumerable<TElement>, IEnumerable<TElement>]>;
    percentile(this: AsyncIterable<number>, percent: number, strategy?: PercentileStrategy): Promise<number>;
    percentile(percent: number, selector: Selector<TElement, number>, strategy?: PercentileStrategy): Promise<number>;
    permutations(size?: number): IAsyncEnumerable<IEnumerable<TElement>>;
    pipe<TResult>(operator: AsyncPipeOperator<TElement, TResult>): Promise<TResult>;
    prepend(element: TElement): IAsyncEnumerable<TElement>;
    product(this: AsyncIterable<number>): Promise<number>;
    product(selector: Selector<TElement, number>): Promise<number>;
    reverse(): IAsyncEnumerable<TElement>;
    rightJoin<TInner, TKey, TResult>(inner: IAsyncEnumerable<TInner>, outerKeySelector: Selector<TElement, TKey>, innerKeySelector: Selector<TInner, TKey>, resultSelector: JoinSelector<TElement | null, TInner, TResult>, keyComparator?: EqualityComparator<TKey>): IAsyncEnumerable<TResult>;
    rotate(shift: number): IAsyncEnumerable<TElement>;
    scan(accumulator: Accumulator<TElement, TElement>): IAsyncEnumerable<TElement>;
    scan<TAccumulate>(accumulator: Accumulator<TElement, TAccumulate>, seed: TAccumulate): IAsyncEnumerable<TAccumulate>;
    select<TResult>(selector: IndexedSelector<TElement, TResult>): IAsyncEnumerable<TResult>;
    selectMany<TResult>(selector: IndexedSelector<TElement, Iterable<TResult>>): IAsyncEnumerable<TResult>;
    sequenceEqual(iterable: AsyncIterable<TElement>, comparator?: EqualityComparator<TElement>): Promise<boolean>;
    shuffle(): IAsyncEnumerable<TElement>;
    single<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): Promise<TFiltered>;
    single(predicate?: Predicate<TElement>): Promise<TElement>;
    singleOrDefault<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): Promise<TFiltered | null>;
    singleOrDefault(predicate?: Predicate<TElement>): Promise<TElement | null>;
    skip(count: number): IAsyncEnumerable<TElement>;
    skipLast(count: number): IAsyncEnumerable<TElement>;
    skipUntil<TFiltered extends TElement>(predicate: IndexedTypePredicate<TElement, TFiltered>): IAsyncEnumerable<TFiltered>;
    skipUntil(predicate: IndexedPredicate<TElement>): IAsyncEnumerable<TElement>;
    skipWhile(predicate: IndexedPredicate<TElement>): IAsyncEnumerable<TElement>;
    span<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): Promise<[IEnumerable<TFiltered>, IEnumerable<TElement>]>;
    span(predicate: Predicate<TElement>): Promise<[IEnumerable<TElement>, IEnumerable<TElement>]>;
    standardDeviation(selector?: Selector<TElement, number>, sample?: boolean): Promise<number>;
    step(step: number): IAsyncEnumerable<TElement>;
    sum(this: AsyncIterable<number>): Promise<number>;
    sum(selector: Selector<TElement, number>): Promise<number>;
    take(count: number): IAsyncEnumerable<TElement>;
    takeLast(count: number): IAsyncEnumerable<TElement>;
    takeUntil<TFiltered extends TElement>(predicate: IndexedTypePredicate<TElement, TFiltered>): IAsyncEnumerable<TFiltered>;
    takeUntil(predicate: IndexedPredicate<TElement>): IAsyncEnumerable<TElement>;
    takeWhile<TFiltered extends TElement>(predicate: IndexedTypePredicate<TElement, TFiltered>): IAsyncEnumerable<TFiltered>;
    takeWhile(predicate: IndexedPredicate<TElement>): IAsyncEnumerable<TElement>;
    tap(action: IndexedAction<TElement>): IAsyncEnumerable<TElement>;
    thenBy<TKey>(keySelector: Selector<TElement, TKey>, comparator?: OrderComparator<TKey>): IOrderedAsyncEnumerable<TElement>;
    thenByDescending<TKey>(keySelector: Selector<TElement, TKey>, comparator?: OrderComparator<TKey>): IOrderedAsyncEnumerable<TElement>;
    toArray(): Promise<TElement[]>;
    toCircularLinkedList(comparator?: EqualityComparator<TElement>): Promise<CircularLinkedList<TElement>>;
    toCircularQueue(comparator?: EqualityComparator<TElement>): Promise<CircularQueue<TElement>>;
    toCircularQueue(capacity: number, comparator?: EqualityComparator<TElement>): Promise<CircularQueue<TElement>>;
    toDictionary<TKey, TValue>(keySelector: Selector<TElement, TKey>, valueSelector: Selector<TElement, TValue>, valueComparator?: EqualityComparator<TValue>): Promise<Dictionary<TKey, TValue>>;
    toEnumerableSet(): Promise<EnumerableSet<TElement>>;
    toImmutableCircularQueue(comparator?: EqualityComparator<TElement>): Promise<ImmutableCircularQueue<TElement>>;
    toImmutableCircularQueue(capacity: number, comparator?: EqualityComparator<TElement>): Promise<ImmutableCircularQueue<TElement>>;
    toImmutableDictionary<TKey, TValue>(keySelector: Selector<TElement, TKey>, valueSelector: Selector<TElement, TValue>, valueComparator?: EqualityComparator<TValue>): Promise<ImmutableDictionary<TKey, TValue>>;
    toImmutableList(comparator?: EqualityComparator<TElement>): Promise<ImmutableList<TElement>>;
    toImmutablePriorityQueue(comparator?: OrderComparator<TElement>): Promise<ImmutablePriorityQueue<TElement>>;
    toImmutableQueue(comparator?: EqualityComparator<TElement>): Promise<ImmutableQueue<TElement>>;
    toImmutableSet(): Promise<ImmutableSet<TElement>>;
    toImmutableSortedDictionary<TKey, TValue>(keySelector: Selector<TElement, TKey>, valueSelector: Selector<TElement, TValue>, keyComparator?: OrderComparator<TKey>, valueComparator?: EqualityComparator<TValue>): Promise<ImmutableSortedDictionary<TKey, TValue>>;
    toImmutableSortedSet(comparator?: OrderComparator<TElement>): Promise<ImmutableSortedSet<TElement>>;
    toImmutableStack(comparator?: EqualityComparator<TElement>): Promise<ImmutableStack<TElement>>;
    toLinkedList(comparator?: EqualityComparator<TElement>): Promise<LinkedList<TElement>>;
    toList(comparator?: EqualityComparator<TElement>): Promise<List<TElement>>;
    toLookup<TKey, TValue>(keySelector: Selector<TElement, TKey>, valueSelector: Selector<TElement, TValue>, keyComparator?: OrderComparator<TKey>): Promise<ILookup<TKey, TValue>>;
    toMap<TKey, TValue>(keySelector: Selector<TElement, TKey>, valueSelector: Selector<TElement, TValue>): Promise<Map<TKey, TValue>>;
    toObject<TKey extends PropertyKey, TValue>(keySelector: Selector<TElement, TKey>, valueSelector: Selector<TElement, TValue>): Promise<Record<TKey, TValue>>;
    toPriorityQueue(comparator?: OrderComparator<TElement>): Promise<PriorityQueue<TElement>>;
    toQueue(comparator?: EqualityComparator<TElement>): Promise<Queue<TElement>>;
    toSet(): Promise<Set<TElement>>;
    toSortedDictionary<TKey, TValue>(keySelector: Selector<TElement, TKey>, valueSelector: Selector<TElement, TValue>, keyComparator?: OrderComparator<TKey>, valueComparator?: EqualityComparator<TValue>): Promise<SortedDictionary<TKey, TValue>>;
    toSortedSet(comparator?: OrderComparator<TElement>): Promise<SortedSet<TElement>>;
    toStack(comparator?: EqualityComparator<TElement>): Promise<Stack<TElement>>;
    union(iterable: AsyncIterable<TElement>, comparator?: EqualityComparator<TElement>): IAsyncEnumerable<TElement>;
    unionBy<TKey>(enumerable: AsyncIterable<TElement>, keySelector: Selector<TElement, TKey>, comparator?: EqualityComparator<TKey>): IAsyncEnumerable<TElement>;
    variance(selector?: Selector<TElement, number>, sample?: boolean): Promise<number>;
    where<TFiltered extends TElement>(predicate: IndexedTypePredicate<TElement, TFiltered>): IAsyncEnumerable<TFiltered>;
    where(predicate: IndexedPredicate<TElement>): IAsyncEnumerable<TElement>;
    windows(size: number): IAsyncEnumerable<IEnumerable<TElement>>;
    zip<TSecond, TResult = [TElement, TSecond]>(iterable: AsyncIterable<TSecond>, resultSelector?: Zipper<TElement, TSecond, TResult>): IAsyncEnumerable<TResult>;
    zipMany<TIterable extends readonly AsyncIterable<unknown>[]>(...iterables: [...TIterable]): IAsyncEnumerable<[TElement, ...UnpackAsyncIterableTuple<TIterable>]>;
    zipMany<TIterable extends readonly AsyncIterable<unknown>[], TResult>(...iterablesAndZipper: [...TIterable, ZipManyZipper<[TElement, ...UnpackAsyncIterableTuple<TIterable>], TResult>]): IAsyncEnumerable<TResult>;
    private appendGenerator;
    private cartesianGenerator;
    private castGenerator;
    private chunkGenerator;
    private combinationsGenerator;
    private compactGenerator;
    private concatGenerator;
    private cycleGenerator;
    private defaultIfEmptyGenerator;
    private distinctUntilChangedGenerator;
    private exceptByGenerator;
    private exceptGenerator;
    private groupByGenerator;
    private groupJoinGenerator;
    private indexGenerator;
    private interleaveGenerator;
    private intersectByGenerator;
    private intersectGenerator;
    private intersperseGenerator;
    private joinGenerator;
    private multimodeGenerator;
    private ofTypeGenerator;
    private pairwiseGenerator;
    private permutationsGenerator;
    private prependGenerator;
    private reverseGenerator;
    private rightJoinGenerator;
    private rotateGenerator;
    private rotateLeftGenerator;
    private rotateRightGenerator;
    private scanGenerator;
    private selectGenerator;
    private selectManyGenerator;
    private shuffleGenerator;
    private skipGenerator;
    private skipLastGenerator;
    private skipUntilGenerator;
    private skipWhileGenerator;
    private stepGenerator;
    private takeGenerator;
    private takeLastGenerator;
    private takeUntilGenerator;
    private takeWhileGenerator;
    private tapGenerator;
    private unionByGenerator;
    private unionGenerator;
    private whereGenerator;
    private windowsGenerator;
    private zipGenerator;
    private zipManyWithZipperGenerator;
    private zipManyWithoutZipperGenerator;
}

export declare interface AsyncPipeOperator<TElement, TResult> {
    (iterable: AsyncIterable<TElement>): Promise<TResult>;
}

/**
 * Determines whether {@link source} contains at least {@link count} elements that satisfy the optional predicate.
 * @template TElement Type of elements within the {@link source} iterable.
 * @param source The iterable whose elements are evaluated.
 * @param count Minimum number of matching elements required. Must be greater than or equal to 0.
 * @param predicate Optional predicate that determines which elements are counted. When omitted, every element is considered a match.
 * @returns {boolean} `true` when at least {@link count} matching elements are present; otherwise, `false`.
 * @throws {InvalidArgumentException} Thrown when {@link count} is negative.
 * @throws {unknown} Re-throws any error encountered while iterating {@link source} or executing the predicate.
 * @remarks Enumeration stops as soon as the required number of matches is found, avoiding unnecessary work on long iterables.
 * @example
 * ```typescript
 * const numbers = [1, 2, 3, 4, 5];
 * const hasAtLeastTwoEvens = atLeast(numbers, 2, n => n % 2 === 0);
 * console.log(hasAtLeastTwoEvens); // true
 * ```
 */
export declare const atLeast: <TElement>(source: Iterable<TElement>, count: number, predicate?: Predicate<TElement>) => boolean;

/**
 * Determines whether {@link source} contains no more than {@link count} elements that satisfy the optional predicate.
 * @template TElement Type of elements within the {@link source} iterable.
 * @param source The iterable whose elements are evaluated.
 * @param count Maximum number of matching elements allowed. Must be greater than or equal to 0.
 * @param predicate Optional predicate that determines which elements are counted. When omitted, every element is considered a match.
 * @returns {boolean} `true` when the number of matching elements does not exceed {@link count}; otherwise, `false`.
 * @throws {InvalidArgumentException} Thrown when {@link count} is negative.
 * @throws {unknown} Re-throws any error encountered while iterating {@link source} or executing the predicate.
 * @remarks Enumeration stops as soon as the count is exceeded, making it efficient for large or infinite iterables.
 * @example
 * ```typescript
 * const numbers = [1, 2, 3, 4, 5];
 * const hasAtMostOneEven = atMost(numbers, 1, n => n % 2 === 0);
 * console.log(hasAtMostOneEven); // false
 * ```
 */
export declare const atMost: <TElement>(source: Iterable<TElement>, count: number, predicate?: Predicate<TElement>) => boolean;

/**
 * Computes the arithmetic mean of the numeric values produced for each element in the sequence.
 * @template TElement Type of elements within the `source` iterable.
 * @param source The source iterable.
 * @param selector Optional projection that extracts the numeric value for each element. Defaults to the element itself.
 * @returns {number} The arithmetic mean of the selected values.
 * @throws {NoElementsException} Thrown when `source` is empty.
 * @remarks Provide a selector when the elements are not already numeric. All values are enumerated exactly once.
 * @example
 * ```typescript
 * const numbers = [1, 2, 3, 4, 5];
 * const avg = average(numbers);
 * console.log(avg); // 3
 *
 * const people = [
 *   { name: 'Alice', age: 25 },
 *   { name: 'Bob', age: 30 },
 *   { name: 'Charlie', age: 35 },
 * ];
 * const avgAge = average(people, p => p.age);
 * console.log(avgAge); // 30
 * ```
 */
export declare function average(source: Iterable<number>): number;

export declare function average<TElement>(source: Iterable<TElement>, selector: Selector<TElement, number>): number;

declare type BigIntType = bigint | BigInt | BigIntConstructor | "bigint";

/**
 * Performs a binary search on the given sequence and returns the index of the element. The sequence must be sorted prior to calling this method.
 * If the searched element exists multiple times in the sequence, the returned index is arbitrary.
 * @template TElement The type of the elements
 * @param {Iterable<TElement>} sequence The iterable in which the element will be binary-searched for. It must be sorted.
 * @param {TElement} element The element that will be searched for.
 * @param {OrderComparator} comparator The comparator method that will be used to compare the elements. It should always be provided if the sequence is of a complex type.
 * @return {number} The index of the element that is equal to the searched element. If the element is not found, returns -1.
 */
export declare const binarySearch: <TElement>(sequence: Iterable<TElement>, element: TElement, comparator?: OrderComparator<TElement>) => number;

declare type BooleanType = boolean | Boolean | BooleanConstructor | "boolean";

/**
 * Produces the cartesian product between {@link source} and {@link other}.
 * @template TElement Type of elements in the {@link source} iterable.
 * @template TSecond Type of elements in the {@link other} iterable.
 * @param source The primary iterable that drives the resulting sequence.
 * @param other The secondary iterable paired with every element from {@link source}.
 * @returns {IEnumerable<[TElement, TSecond]>} A deferred sequence that yields each ordered pair `[source, other]`.
 * @throws {unknown} Re-throws any error raised while iterating {@link source} or {@link other}.
 * @remarks The secondary iterable is fully buffered before iteration starts so that it can be replayed for every element from {@link source}. The resulting sequence stops when {@link source} completes.
 * @example
 * ```typescript
 * const pairs = cartesian([1, 2], ['A', 'B']).toArray();
 * console.log(pairs); // [[1, 'A'], [1, 'B'], [2, 'A'], [2, 'B']]
 * ```
 */
export declare const cartesian: <TElement, TSecond>(source: Iterable<TElement>, other: Iterable<TSecond>) => IEnumerable<[TElement, TSecond]>;

/**
 * Reinterprets each element in the sequence as the specified result type.
 * @template TResult Target type exposed by the returned sequence.
 * @template TElement Type of elements within the `source` iterable.
 * @param source The source iterable.
 * @returns {IEnumerable<TResult>} A sequence that yields the same elements typed as `TResult`.
 * @remarks No runtime conversion occurs; ensure the underlying elements are compatible with `TResult` to avoid downstream failures.
 * @example
 * ```typescript
 * const mixed = [1, 'two', 3, 'four'];
 * const numbers = cast<number>(mixed).where(x => typeof x === 'number');
 * console.log(numbers.toArray()); // [1, 3]
 * ```
 */
export declare const cast: <TResult, TElement = unknown>(source: Iterable<TElement>) => IEnumerable<TResult>;

/**
 * Splits the sequence into contiguous subsequences containing at most the specified number of elements.
 * @template TElement Type of elements within the `source` iterable.
 * @param source The source iterable.
 * @param size Maximum number of elements to include in each chunk. Must be greater than 0.
 * @returns {IEnumerable<IEnumerable<TElement>>} A sequence where each element is a chunk of the original sequence.
 * @throws {InvalidArgumentException} Thrown when `size` is less than 1.
 * @remarks The final chunk may contain fewer elements than `size`. Enumeration is deferred until the returned sequence is iterated.
 * @example
 * ```typescript
 * const numbers = [1, 2, 3, 4, 5, 6, 7, 8];
 * const chunks = chunk(numbers, 3);
 * console.log(chunks.select(c => c.toArray()).toArray()); // [[1, 2, 3], [4, 5, 6], [7, 8]]
 * ```
 */
export declare const chunk: <TElement>(source: Iterable<TElement>, size: number) => IEnumerable<IEnumerable<TElement>>;

/**
 * Represents a circular doubly linked list.
 * In a circular linked list, the last node points to the first node (head.prev -> tail),
 * and the first node points to the last node (tail.next -> head), forming a circle.
 * This implementation uses a single 'head' reference, where head.prev gives the tail.
 */
export declare class CircularLinkedList<TElement> extends AbstractList<TElement> {
    #private;
    /**
     * Initializes a new instance of the CircularLinkedList class.
     * @param iterable An optional iterable to populate the list with.
     * @param comparator An optional equality comparator for elements.
     */
    constructor(iterable?: Iterable<TElement>, comparator?: EqualityComparator<TElement>);
    /**
     * Gets an iterator for the circular linked list.
     * Iterates through the list starting from the head node.
     * @returns {Iterator<TElement>} An iterator for the list.
     */
    [Symbol.iterator](): Iterator<TElement>;
    /**
     * Adds an element to the end of the list.
     * @param element The element to add.
     * @returns {boolean} Always returns true as the add operation succeeds.
     */
    add(element: TElement): boolean;
    /**
     * Adds an element at the specified index in the list.
     * @param element The element to add.
     * @param index The zero-based index at which the element should be inserted.
     * @returns {boolean} Always returns true as the add operation succeeds.
     * @throws {IndexOutOfBoundsException} If the index is out of range (index < 0 or index > size).
     */
    addAt(element: TElement, index: number): boolean;
    /**
     * Adds an element to the beginning of the list.
     * @param element The element to add.
     */
    addFirst(element: TElement): void;
    /**
     * Adds an element to the end of the list.
     * @param element The element to add.
     */
    addLast(element: TElement): void;
    /**
     * Removes all elements from the list.
     */
    clear(): void;
    /**
     * Determines whether the list contains a specific element.
     * @param element The element to locate.
     * @param comparator An optional equality comparator.
     * @returns {boolean} True if the element is found; otherwise, false.
     */
    contains(element: TElement, comparator?: EqualityComparator<TElement>): boolean;
    /**
     * Gets the element at the specified zero-based index.
     * @param index The index of the element to retrieve.
     * @returns {TElement} The element at the specified index.
     * @throws {IndexOutOfBoundsException} If the index is out of range (index < 0 or index >= size).
     */
    get(index: number): TElement;
    /**
     * Gets a range of elements starting from the specified index.
     * The range wraps around the list if necessary.
     * @param index The zero-based starting index of the range.
     * @param count The number of elements in the range.
     * @returns {CircularLinkedList<TElement>} A new CircularLinkedList containing the specified range.
     * @throws {IndexOutOfBoundsException} If the index is out of range (index < 0 or index >= size, or index > 0 for an empty list).
     * @throws {InvalidArgumentException} If count is negative.
     */
    getRange(index: number, count: number): CircularLinkedList<TElement>;
    /**
     * Removes the first occurrence of the specified element from the list.
     * @param element The element to remove.
     * @returns {boolean} True if the element was found and removed; otherwise, false.
     */
    remove(element: TElement): boolean;
    /**
     * Removes the element at the specified index.
     * @param index The zero-based index of the element to remove.
     * @returns {TElement} The element that was removed.
     * @throws {IndexOutOfBoundsException} If the index is out of range.
     */
    removeAt(index: number): TElement;
    /**
     * Removes and returns the first element from the list.
     * @returns {TElement} The removed element.
     * @throws {NoElementsException} If the list is empty.
     */
    removeFirst(): TElement;
    /**
     * Removes and returns the last element from the list.
     * @returns {TElement} The removed element.
     * @throws {NoElementsException} If the list is empty.
     */
    removeLast(): TElement;
    /**
     * Replaces the element at the specified index with a new element.
     * @param index The zero-based index of the element to replace.
     * @param element The new element.
     * @returns {TElement} The original element that was replaced.
     * @throws {IndexOutOfBoundsException} If the index is out of range.
     */
    set(index: number, element: TElement): TElement;
    /**
     * Gets the number of elements contained in the list.
     * @returns {number} The number of elements.
     */
    size(): number;
    /**
     * Sorts the elements in the list in place.
     * Note: This converts the list to an array, sorts it, and rebuilds the list.
     * @param comparator An optional order comparator.
     */
    sort(comparator?: OrderComparator<TElement>): void;
    /**
     * Checks if the index is valid for accessing an element (0 <= index < size).
     * @param index The index to check.
     * @throws {IndexOutOfBoundsException} If the index is invalid.
     */
    private checkElementIndex;
    /**
     * Checks if the index is valid for insertion (0 <= index <= size).
     * @param index The index to check.
     * @throws {IndexOutOfBoundsException} If the index is invalid.
     */
    private checkPositionIndex;
    /**
     * Helper to check if an index is within the bounds for element access.
     * @param index The index.
     * @returns {boolean} True if valid for element access.
     */
    private isElementIndex;
    /**
     * Helper to check if an index is within the bounds for insertion.
     * @param index The index.
     * @returns {boolean} True if valid for insertion.
     */
    private isPositionIndex;
    /**
     * Retrieves the node at the specified index. Traverses from the closer end.
     * @param index The zero-based index.
     * @returns {Node<TElement>} The node at the index.
     * @throws {IndexOutOfBoundsException} If index is invalid (handled by caller).
     */
    private node;
    /**
     * Removes a specified node from the list and updates links.
     * @param node The node to remove.
     * @returns {TElement} The element of the removed node.
     */
    private unlink;
    /**
     * Gets the equality comparator used by the list.
     * @returns {EqualityComparator<TElement>} The comparator.
     */
    get comparator(): EqualityComparator<TElement>;
    get length(): number;
}

/**
 * A circular queue is a queue that uses a fixed-size queue as its underlying data structure.
 * When the queue is full, adding a new element to the queue causes the oldest element in the queue to be removed.
 * The oldest element is the one that has been in the queue the longest, which is the element at the front of the queue.
 *
 * This is a first-in-first-out (FIFO) data structure.
 * @see https://en.wikipedia.org/wiki/Circular_buffer
 */
export declare class CircularQueue<TElement> extends Queue<TElement> {
    #private;
    /**
     * Constructs a circular queue with the given capacity.
     * @param capacity The capacity of the queue. If not defined, the default capacity will be 32.
     * @param comparator The comparator used to compare the elements of the queue.
     */
    constructor(capacity?: number, comparator?: EqualityComparator<TElement>);
    /**
     * Adds an element to the queue.
     * If the queue is full, the oldest element in the queue is removed.
     * @param element The element to add to the queue.
     * @returns true if the element was added to the queue, false otherwise.
     */
    add(element: TElement): boolean;
    /**
     * Adds an element to the queue.
     * If the queue is full, the oldest element in the queue is removed.
     * @param element The element to add to the queue.
     */
    enqueue(element: TElement): void;
    /**
     * Returns if the queue is full.
     * @returns true if the queue is full, false otherwise.
     */
    isFull(): boolean;
    get comparator(): EqualityComparator<TElement>;
}

/**
 * @remarks
 * For the type of args, do not use `unknown[]` since it breaks the return type of `ofType` methods.
 * Since I did not use this anywhere in a situation where it requires a parameter,
 * I've opted for the ` never ` type, but in a situation where it requires a parameter, this should be changed to `any[]`.
 */
declare type Class<T> = new (...args: never[]) => T;

export declare enum CollectionChangedAction {
    Add = 0,
    Remove = 1,
    Replace = 2,
    Move = 3,
    Reset = 4
}

/**
 * Generates the unique combinations that can be built from the elements in the sequence.
 * @template TElement Type of elements within the `source` iterable.
 * @param source The source iterable.
 * @param size Optional number of elements that each combination must contain. When omitted, combinations of every possible length are produced.
 * @returns {IEnumerable<IEnumerable<TElement>>} A sequence of combinations built from the source elements.
 * @throws {InvalidArgumentException} Thrown when `size` is negative.
 * @remarks The source sequence is materialised before combinations are produced, so very large inputs can be expensive. Duplicate combinations produced by repeated elements are emitted only once.
 * @example
 * ```typescript
 * const numbers = [1, 2, 3];
 * const combs = combinations(numbers, 2);
 * console.log(combs.select(c => c.toArray()).toArray()); // [[1, 2], [1, 3], [2, 3]]
 * ```
 */
export declare const combinations: <TElement>(source: Iterable<TElement>, size?: number) => IEnumerable<IEnumerable<TElement>>;

/**
 * Filters out `null` and `undefined` values from the sequence.
 * @template TElement Type of elements within the `source` iterable.
 * @param source The source iterable.
 * @returns {IEnumerable<NonNullable<TElement>>} A sequence containing only the elements that are neither `null` nor `undefined`.
 * @remarks The method preserves other falsy values (such as `0` or an empty string) and defers execution until the returned sequence is iterated.
 * @example
 * ```typescript
 * const values = compact([1, null, 0, undefined]).toArray();
 * console.log(values); // [1, 0]
 * ```
 */
export declare const compact: <TElement>(source: Iterable<TElement>) => IEnumerable<NonNullable<TElement>>;

/**
 * Appends the specified iterable to the end of the sequence.
 * @template TElement Type of elements within the `source` iterable.
 * @param source The source iterable.
 * @param other Additional elements that are yielded after the current sequence.
 * @returns {IEnumerable<TElement>} A sequence containing the elements of the current sequence followed by those from `other`.
 * @remarks Enumeration of both sequences is deferred until the result is iterated.
 * @example
 * ```typescript
 * const numbers1 = [1, 2, 3];
 * const numbers2 = [4, 5, 6];
 * const concatenated = concat(numbers1, numbers2).toArray();
 * console.log(concatenated); // [1, 2, 3, 4, 5, 6]
 * ```
 */
export declare const concat: <TElement>(source: Iterable<TElement>, other: Iterable<TElement>) => IEnumerable<TElement>;

/**
 * Determines whether the sequence contains a specific element using an optional comparator.
 * @template TElement Type of elements within the `source` iterable.
 * @param source The source iterable.
 * @param element Element to locate in the sequence.
 * @param comparator Optional equality comparator used to match elements. Defaults to the library's standard equality comparison.
 * @returns {boolean} `true` when the element is found; otherwise, `false`.
 * @example
 * ```typescript
 * const numbers = [1, 2, 3, 4, 5];
 * const hasThree = contains(numbers, 3);
 * console.log(hasThree); // true
 *
 * const hasTen = contains(numbers, 10);
 * console.log(hasTen); // false
 * ```
 */
export declare const contains: <TElement>(source: Iterable<TElement>, element: TElement, comparator?: EqualityComparator<TElement>) => boolean;

/**
 * Computes the Pearson correlation coefficient between {@link source} and {@link other}.
 * @template TElement Type of elements within the `source` iterable.
 * @template TSecond Type of elements within the {@link other} iterable.
 * @param source The source iterable whose elements align with {@link other} by index.
 * @param other The iterable that provides the second series of aligned values.
 * @param selector Optional projection that extracts the numeric value for each element of {@link source}. Defaults to treating the element itself as numeric.
 * @param otherSelector Optional projection that extracts the numeric value for each element of {@link other}. Defaults to treating the element itself as numeric.
 * @returns {number} The correlation coefficient in the interval [-1, 1].
 * @throws {DimensionMismatchException} Thrown when the iterables do not contain the same number of elements.
 * @throws {InsufficientElementException} Thrown when fewer than two aligned pairs are available.
 * @throws {Error} Thrown when the standard deviation of either numeric projection is zero.
 * @throws {unknown} Re-throws any error encountered while iterating either iterable or executing the selector projections.
 * @remarks Both iterables are enumerated simultaneously via an online algorithm that avoids buffering the full dataset. Ensure the iterables are aligned because mismatch detection occurs only after enumeration begins.
 * @example
 * ```typescript
 * const temperatures = [15, 18, 21, 24];
 * const sales = [30, 36, 42, 48];
 * const result = correlation(temperatures, sales);
 * console.log(result); // 1
 * ```
 */
export declare const correlation: <TElement, TSecond>(source: Iterable<TElement>, other: Iterable<TSecond>, selector?: Selector<TElement, number>, otherSelector?: Selector<TSecond, number>) => number;

/**
 * Computes the Pearson correlation coefficient between two numeric projections of {@link source}.
 * @template TElement Type of elements within the `source` iterable.
 * @param source The source iterable that supplies the data for both projections.
 * @param leftSelector Projection that produces the first numeric series for each element.
 * @param rightSelector Projection that produces the second numeric series for each element.
 * @returns {number} The correlation coefficient in the interval [-1, 1].
 * @throws {InsufficientElementException} Thrown when fewer than two elements are available.
 * @throws {Error} Thrown when the standard deviation of either numeric projection is zero.
 * @throws {unknown} Re-throws any error encountered while iterating {@link source} or executing the selector projections.
 * @remarks The iterable is enumerated exactly once using an online algorithm, which keeps memory usage constant even for large inputs.
 * @example
 * ```typescript
 * const metrics = [
 *   { impressions: 1_000, clicks: 50 },
 *   { impressions: 1_500, clicks: 75 },
 *   { impressions: 2_000, clicks: 100 }
 * ];
 * const result = correlationBy(metrics, m => m.impressions, m => m.clicks);
 * console.log(result); // 1
 * ```
 */
export declare const correlationBy: <TElement>(source: Iterable<TElement>, leftSelector: Selector<TElement, number>, rightSelector: Selector<TElement, number>) => number;

/**
 * Counts the number of elements in the sequence, optionally restricted by a predicate.
 * @template TElement Type of elements within the `source` iterable.
 * @param source The source iterable.
 * @param predicate Optional predicate that determines which elements are counted. When omitted, all elements are counted.
 * @returns {number} The number of elements that satisfy the predicate.
 * @remarks Prefer calling `any(source)` to test for existence instead of comparing this result with zero.
 * @example
 * ```typescript
 * const numbers = [1, 2, 3, 4, 5];
 * const totalCount = count(numbers);
 * console.log(totalCount); // 5
 *
 * const evenCount = count(numbers, x => x % 2 === 0);
 * console.log(evenCount); // 2
 * ```
 */
export declare const count: <TElement>(source: Iterable<TElement>, predicate?: Predicate<TElement>) => number;

/**
 * Counts the occurrences of elements grouped by a derived key.
 * @template TElement Type of elements within the `source` iterable.
 * @template TKey Type produced by `keySelector`.
 * @param source The source iterable.
 * @param keySelector Selector used to derive the grouping key for each element.
 * @param comparator Optional equality comparator used to match keys. Defaults to the library's standard equality comparison.
 * @returns {IEnumerable<KeyValuePair<TKey, number>>} A sequence of key/count pairs describing how many elements share each key.
 * @remarks Each key appears exactly once in the result with its associated occurrence count.
 * @example
 * ```typescript
 * const products = [
 *   { name: 'Apple', category: 'Fruit' },
 *   { name: 'Banana', category: 'Fruit' },
 *   { name: 'Carrot', category: 'Vegetable' },
 * ];
 *
 * const countByCategory = countBy(products, p => p.category).toArray();
 * console.log(countByCategory);
 * // [
 * //   { key: 'Fruit', value: 2 },
 * //   { key: 'Vegetable', value: 1 }
 * // ]
 * ```
 */
export declare const countBy: <TElement, TKey>(source: Iterable<TElement>, keySelector: Selector<TElement, TKey>, comparator?: EqualityComparator<TKey>) => IEnumerable<KeyValuePair<TKey, number>>;

/**
 * Calculates the covariance between {@link source} and {@link other}.
 * @template TElement Type of elements within the {@link source} iterable.
 * @template TSecond Type of elements within {@link other}.
 * @param source The primary iterable whose elements align by index with {@link other}.
 * @param other Secondary iterable supplying the paired values.
 * @param selector Optional projection that extracts the numeric value for each element in {@link source}. Defaults to treating the element itself as numeric.
 * @param otherSelector Optional projection that extracts the numeric value for each element in {@link other}. Defaults to treating the element itself as numeric.
 * @param sample When `true`, computes the sample covariance dividing by _n - 1_; when `false`, computes the population covariance dividing by _n_. Defaults to `true`.
 * @returns {number} The calculated covariance.
 * @throws {DimensionMismatchException} Thrown when {@link source} and {@link other} do not contain the same number of elements.
 * @throws {InsufficientElementException} Thrown when fewer than two aligned pairs are available.
 * @throws {unknown} Re-throws any error thrown while iterating either iterable or executing the selector projections.
 * @remarks Both iterables are consumed simultaneously so streaming statistics can be computed without materialising all elements. Ensure the iterables are aligned because mismatch detection occurs only after iteration begins.
 * @example
 * ```typescript
 * const numbers = [1, 2, 3, 4, 5];
 * const doubles = [2, 4, 6, 8, 10];
 * const covarianceValue = covariance(numbers, doubles);
 * console.log(covarianceValue); // 5
 * ```
 */
export declare const covariance: <TElement, TSecond>(source: Iterable<TElement>, other: Iterable<TSecond>, selector?: Selector<TElement, number>, otherSelector?: Selector<TSecond, number>, sample?: boolean) => number;

/**
 * Calculates the covariance between two numeric projections of {@link source}.
 * @template TElement Type of elements within the {@link source} iterable.
 * @param source The source iterable to inspect.
 * @param leftSelector Projection that produces the first numeric series for each element.
 * @param rightSelector Projection that produces the second numeric series for each element.
 * @param sample When `true`, computes the sample covariance dividing by _n - 1_; when `false`, computes the population covariance dividing by _n_. Defaults to `true`.
 * @returns {number} The calculated covariance.
 * @throws {InsufficientElementException} Thrown when fewer than two elements are available.
 * @throws {unknown} Re-throws any error thrown while iterating {@link source} or executing the selector projections.
 * @remarks {@link source} is consumed exactly once using an online algorithm that avoids buffering, making it suitable for large datasets.
 * @example
 * ```typescript
 * const points = [
 *   { x: 1, y: 2 },
 *   { x: 2, y: 4 },
 *   { x: 3, y: 6 }
 * ];
 * const covarianceValue = covarianceBy(points, p => p.x, p => p.y);
 * console.log(covarianceValue); // 2
 * ```
 */
export declare const covarianceBy: <TElement>(source: Iterable<TElement>, leftSelector: Selector<TElement, number>, rightSelector: Selector<TElement, number>, sample?: boolean) => number;

/**
 * Repeats the sequence the specified number of times, or indefinitely when no count is provided.
 * @template TElement Type of elements within the `source` iterable.
 * @param source The source iterable.
 * @param count Optional number of times to repeat the sequence. When omitted, the sequence repeats without end.
 * @returns {IEnumerable<TElement>} A sequence that yields the original elements cyclically.
 * @throws {NoElementsException} Thrown when the sequence is empty.
 * @remarks When `count` is `undefined`, consume the result with care because it represents an infinite sequence.
 * @example
 * ```typescript
 * const numbers = [1, 2, 3];
 * const cycled = cycle(numbers, 2).toArray();
 * console.log(cycled); // [1, 2, 3, 1, 2, 3]
 * ```
 */
export declare const cycle: <TElement>(source: Iterable<TElement>, count?: number) => IEnumerable<TElement>;

/**
 * Supplies fallback content when the sequence contains no elements.
 * @template TElement Type of elements within the `source` iterable.
 * @param source The source iterable.
 * @param value Optional value returned in a singleton sequence when the source is empty. Defaults to `null`.
 * @returns {IEnumerable<TElement | null>} The original sequence when it has elements; otherwise, a singleton sequence containing the provided value.
 * @remarks Use this to ensure downstream operators always receive at least one element.
 * @example
 * ```typescript
 * const empty = [];
 * const withDefault = defaultIfEmpty(empty, 0).toArray();
 * console.log(withDefault); // [0]
 *
 * const numbers = [1, 2, 3];
 * const withDefault2 = defaultIfEmpty(numbers, 0).toArray();
 * console.log(withDefault2); // [1, 2, 3]
 * ```
 */
export declare const defaultIfEmpty: <TElement>(source: Iterable<TElement>, value?: TElement | null) => IEnumerable<TElement | null>;

export declare class Dictionary<TKey, TValue> extends AbstractDictionary<TKey, TValue> {
    #private;
    constructor();
    constructor(iterable: Iterable<KeyValuePair<TKey, TValue>>, valueComparator?: EqualityComparator<TValue>);
    constructor(iterable: Iterable<[TKey, TValue]>, valueComparator?: EqualityComparator<TValue>);
    constructor(iterable: Iterable<KeyValuePair<TKey, TValue>> | Iterable<[TKey, TValue]>, valueComparator?: EqualityComparator<TValue>);
    [Symbol.iterator](): Iterator<KeyValuePair<TKey, TValue>>;
    add(key: TKey, value: TValue): TValue;
    clear(): void;
    containsKey(key: TKey): boolean;
    containsValue(value: TValue, comparator?: EqualityComparator<TValue>): boolean;
    entries(): IterableIterator<[TKey, TValue]>;
    get(key: TKey): TValue | null;
    keys(): ISet<TKey>;
    remove(key: TKey): TValue | null;
    set(key: TKey, value: TValue): void;
    size(): number;
    values(): IImmutableCollection<TValue>;
    get length(): number;
}

/**
 * Determines whether {@link source} and {@link other} share no equivalent elements.
 * @template TElement Type of elements within the `source` iterable.
 * @template TSecond Type of elements within the {@link other} iterable.
 * @param source The primary iterable.
 * @param other Iterable compared against {@link source}.
 * @param comparator Optional equality comparator used to match elements across both iterables. Defaults to the library's standard equality comparison.
 * @returns {boolean} `true` when the iterables are disjoint; otherwise, `false`.
 * @throws {unknown} Re-throws any error encountered while iterating {@link source}, {@link other}, or executing the comparator.
 * @remarks When the default comparator is used, the implementation buffers the source elements in a {@link Set} so it can short-circuit as soon as a shared element is detected.
 * With a custom comparator, every pair of elements is compared, which may iterate each iterable multiple times; prefer the default comparator when possible for better performance.
 * @example
 * ```typescript
 * const first = [1, 2, 3];
 * const second = [4, 5, 6];
 * const areDisjoint = disjoint(first, second);
 * console.log(areDisjoint); // true
 * ```
 */
export declare const disjoint: <TElement, TSecond>(source: Iterable<TElement>, other: Iterable<TSecond>, comparator?: EqualityComparator<TElement | TSecond>) => boolean;

/**
 * Determines whether the key projections of {@link source} and {@link other} are mutually exclusive.
 * @template TElement Type of elements within the `source` iterable.
 * @template TSecond Type of elements within the {@link other} iterable.
 * @template TKey Key type produced by {@link keySelector}.
 * @template TSecondKey Key type produced by {@link otherKeySelector}.
 * @param source The primary iterable.
 * @param other Iterable compared against {@link source}.
 * @param keySelector Projection that produces the key evaluated for each source element.
 * @param otherKeySelector Projection that produces the key evaluated for each element of {@link other}.
 * @param keyComparator Optional equality comparator applied to projected keys. Defaults to the library's standard equality comparison.
 * @returns {boolean} `true` when no projected keys intersect; otherwise, `false`.
 * @throws {unknown} Re-throws any error encountered while iterating either iterable or executing the selector projections/comparator.
 * @remarks When the default comparator is used, the implementation buffers the larger key collection in a {@link Set} and short-circuits as soon as an intersecting key is found.
 * Supplying a custom comparator forces a full pairwise comparison, which may iterate both iterables repeatedly; prefer the default comparator when suitable.
 * @example
 * ```typescript
 * const left = [{ name: 'Alice' }, { name: 'Bella' }];
 * const right = [{ name: 'Mel' }];
 * const areDisjoint = disjointBy(left, right, p => p.name, p => p.name);
 * console.log(areDisjoint); // true
 * ```
 */
export declare const disjointBy: <TElement, TSecond, TKey, TSecondKey>(source: Iterable<TElement>, other: Iterable<TSecond>, keySelector: Selector<TElement, TKey>, otherKeySelector: Selector<TSecond, TSecondKey>, keyComparator?: EqualityComparator<TKey | TSecondKey>) => boolean;

/**
 * Eliminates duplicate elements from the sequence using an optional comparator.
 * @template TElement Type of elements within the `source` iterable.
 * @param source The source iterable.
 * @param keyComparator Optional equality comparator used to determine whether two elements are identical. Defaults to the library's standard equality comparison.
 * @returns {IEnumerable<TElement>} A sequence that yields each distinct element once.
 * @remarks Elements are compared by value; provide a comparator for custom reference types.
 * @example
 * ```typescript
 * const numbers = [1, 2, 2, 3, 1, 4, 5, 5];
 * const distinctNumbers = distinct(numbers).toArray();
 * console.log(distinctNumbers); // [1, 2, 3, 4, 5]
 * ```
 */
export declare const distinct: <TElement>(source: Iterable<TElement>, keyComparator?: EqualityComparator<TElement>) => IEnumerable<TElement>;

/**
 * Eliminates duplicate elements by comparing keys computed for each element.
 * @template TElement Type of elements within the `source` iterable.
 * @template TKey Key type returned by `keySelector`.
 * @param source The source iterable.
 * @param keySelector Selector used to project each element to the key used for distinctness.
 * @param keyComparator Optional equality comparator used to compare keys. Defaults to the library's standard equality comparison.
 * @returns {IEnumerable<TElement>} A sequence that contains the first occurrence of each unique key.
 * @remarks Each element's key is evaluated exactly once; cache expensive key computations when possible.
 * @example
 * ```typescript
 * const products = [
 *   { name: 'Apple', category: 'Fruit' },
 *   { name: 'Banana', category: 'Fruit' },
 *   { name: 'Carrot', category: 'Vegetable' },
 * ];
 *
 * const distinctByCategory = distinctBy(products, p => p.category).toArray();
 * console.log(distinctByCategory);
 * // [
 * //   { name: 'Apple', category: 'Fruit' },
 * //   { name: 'Carrot', category: 'Vegetable' }
 * // ]
 * ```
 */
export declare const distinctBy: <TElement, TKey>(source: Iterable<TElement>, keySelector: Selector<TElement, TKey>, keyComparator?: EqualityComparator<TKey>) => IEnumerable<TElement>;

/**
 * Removes consecutive duplicate elements by comparing each element with its predecessor.
 * @template TElement Type of elements within the `source` iterable.
 * @param source The source iterable.
 * @param comparator Optional equality comparator used to determine whether adjacent elements are equal. Defaults to the library's standard equality comparison.
 * @returns {IEnumerable<TElement>} A sequence that yields the first element of each run of equal values.
 * @remarks Unlike {@link distinct}, this only filters adjacent duplicates and preserves earlier occurrences of repeated values.
 * @example
 * ```typescript
 * const numbers = [1, 1, 2, 2, 2, 1, 3, 3];
 * const distinctUntilChangedNumbers = distinctUntilChanged(numbers).toArray();
 * console.log(distinctUntilChangedNumbers); // [1, 2, 1, 3]
 * ```
 */
export declare const distinctUntilChanged: <TElement>(source: Iterable<TElement>, comparator?: EqualityComparator<TElement>) => IEnumerable<TElement>;

/**
 * Removes consecutive duplicate elements by comparing keys projected from each element.
 * @template TElement Type of elements within the `source` iterable.
 * @template TKey Key type returned by `keySelector`.
 * @param source The source iterable.
 * @param keySelector Selector used to project each element to the key used for comparison.
 * @param keyComparator Optional equality comparator used to compare keys. Defaults to the library's standard equality comparison.
 * @returns {IEnumerable<TElement>} A sequence that yields the first element in each run of elements whose keys change.
 * @remarks Enumeration stops comparing elements once a different key is encountered, making this useful for collapsing grouped data.
 * @example
 * ```typescript
 * const products = [
 *   { name: 'Apple', category: 'Fruit' },
 *   { name: 'Banana', category: 'Fruit' },
 *   { name: 'Carrot', category: 'Vegetable' },
 *   { name: 'Broccoli', category: 'Vegetable' },
 *   { name: 'Orange', category: 'Fruit' },
 * ];
 *
 * const distinctByCategory = distinctUntilChangedBy(products, p => p.category).toArray();
 * console.log(distinctByCategory);
 * // [
 * //   { name: 'Apple', category: 'Fruit' },
 * //   { name: 'Carrot', category: 'Vegetable' },
 * //   { name: 'Orange', category: 'Fruit' }
 * // ]
 * ```
 */
export declare const distinctUntilChangedBy: <TElement, TKey>(source: Iterable<TElement>, keySelector: Selector<TElement, TKey>, keyComparator?: EqualityComparator<TKey>) => IEnumerable<TElement>;

/**
 * Retrieves the element at the specified zero-based index.
 * @template TElement Type of elements within the `source` iterable.
 * @param source The source iterable.
 * @param index Zero-based position of the element to retrieve.
 * @returns {TElement} The element located at the requested index.
 * @throws {IndexOutOfBoundsException} Thrown when `index` is negative or greater than or equal to the number of elements in {@link source}.
 * @remarks Enumeration stops once the requested element is found; remaining elements are not evaluated.
 * @example
 * ```typescript
 * const numbers = [1, 2, 3, 4, 5];
 * const element = elementAt(numbers, 2);
 * console.log(element); // 3
 * ```
 */
export declare const elementAt: <TElement>(source: Iterable<TElement>, index: number) => TElement;

/**
 * Retrieves the element at the specified zero-based index or returns `null` when the index is out of range.
 * @template TElement Type of elements within the `source` iterable.
 * @param source The source iterable.
 * @param index Zero-based position of the element to retrieve.
 * @returns {TElement | null} The element at `index`, or `null` when {@link source} is shorter than `index + 1` or when `index` is negative.
 * @remarks Use this overload when out-of-range access should produce a sentinel value instead of throwing an exception.
 * @example
 * ```typescript
 * const numbers = [1, 2, 3, 4, 5];
 * const element = elementAtOrDefault(numbers, 2);
 * console.log(element); // 3
 *
 * const element2 = elementAtOrDefault(numbers, 10);
 * console.log(element2); // null
 * ```
 */
export declare const elementAtOrDefault: <TElement>(source: Iterable<TElement>, index: number) => TElement | null;

/**
 * Creates an empty sequence.
 * @template TElement Type of elements that the returned sequence can produce.
 * @returns {IEnumerable<TElement>} A reusable, cached empty sequence.
 * @remarks The returned instance is immutable and can be shared safely across callers.
 * @example
 * ```typescript
 * const emptySequence = empty<number>();
 * console.log(emptySequence.toArray()); // []
 * ```
 */
export declare const empty: <TElement>() => IEnumerable<TElement>;

export declare class Enumerable<TElement> implements IEnumerable<TElement> {
    #private;
    private readonly iterable;
    constructor(iterable: Iterable<TElement>);
    /**
     * Creates an empty sequence.
     *
     * @template TElement The type of elements in the sequence.
     * @returns {IEnumerable<TElement>} An empty sequence.
     */
    static empty<TSource>(): IEnumerable<TSource>;
    /**
     * Creates an enumerable sequence from the given source.
     * @template TElement The type of elements in the sequence.
     * @param source The source iterable that will be converted to an enumerable sequence.
     * @returns {IEnumerable<TElement>} An enumerable sequence that contains the elements of the source.
     */
    static from<TSource>(source: Iterable<TSource>): IEnumerable<TSource>;
    static infiniteSequence(start: number, step: number): IEnumerable<number>;
    /**
     * Creates a range of numbers starting from the specified start value and containing the specified count of elements.
     * @param {number} start The start value of the range.
     * @param {number} count The number of elements in the range.
     * @returns {IEnumerable<number>} An enumerable range of numbers.
     */
    static range(start: number, count: number): IEnumerable<number>;
    /**
     * Repeats the specified element a specified number of times.
     *
     * @template TElement The type of the element to repeat.
     * @param {TElement} element The element to repeat.
     * @param {number} count The number of times to repeat the element.
     * @returns {IEnumerable<TElement>} An Iterable representing the repeated elements.
     */
    static repeat<TSource>(element: TSource, count: number): IEnumerable<TSource>;
    static sequence(start: number, end: number, step: number): IEnumerable<number>;
    [Symbol.iterator](): Iterator<TElement>;
    aggregate(accumulator: Accumulator<TElement, TElement>): TElement;
    aggregate<TAccumulate>(accumulator: Accumulator<TElement, TAccumulate>, seed: TAccumulate): TAccumulate;
    aggregate<TAccumulate, TResult>(accumulator: Accumulator<TElement, TAccumulate>, seed: TAccumulate, resultSelector: Selector<TAccumulate, TResult>): TResult;
    aggregateBy<TKey, TAccumulate = TElement>(keySelector: Selector<TElement, TKey>, seedSelector: Selector<TKey, TAccumulate> | TAccumulate, accumulator: Accumulator<TElement, TAccumulate>, keyComparator?: EqualityComparator<TKey>): IEnumerable<KeyValuePair<TKey, TAccumulate>>;
    all(predicate: Predicate<TElement>): boolean;
    any(predicate?: Predicate<TElement>): boolean;
    append(element: TElement): IEnumerable<TElement>;
    atLeast(count: number, predicate?: Predicate<TElement>): boolean;
    atMost(count: number, predicate?: Predicate<TElement>): boolean;
    average(this: Iterable<number>): number;
    average(selector: Selector<TElement, number>): number;
    cartesian<TSecond>(iterable: Iterable<TSecond>): IEnumerable<[TElement, TSecond]>;
    cast<TResult>(): IEnumerable<TResult>;
    chunk(size: number): IEnumerable<IEnumerable<TElement>>;
    combinations(size?: number): IEnumerable<IEnumerable<TElement>>;
    compact(): IEnumerable<NonNullable<TElement>>;
    concat(iterable: Iterable<TElement>): IEnumerable<TElement>;
    contains(element: TElement, comparator?: EqualityComparator<TElement>): boolean;
    correlation<TSecond>(iterable: Iterable<TSecond>, selector?: Selector<TElement, number>, otherSelector?: Selector<TSecond, number>): number;
    correlationBy(leftSelector: Selector<TElement, number>, rightSelector: Selector<TElement, number>): number;
    count(predicate?: Predicate<TElement>): number;
    countBy<TKey>(keySelector: Selector<TElement, TKey>, comparator?: EqualityComparator<TKey>): IEnumerable<KeyValuePair<TKey, number>>;
    covariance<TSecond>(iterable: Iterable<TSecond>, selector?: Selector<TElement, number>, otherSelector?: Selector<TSecond, number>, sample?: boolean): number;
    covarianceBy(leftSelector: Selector<TElement, number>, rightSelector: Selector<TElement, number>, sample?: boolean): number;
    cycle(count?: number): IEnumerable<TElement>;
    defaultIfEmpty(value?: TElement | null): IEnumerable<TElement | null>;
    disjoint<TSecond>(iterable: Iterable<TSecond>, comparator?: EqualityComparator<TElement | TSecond>): boolean;
    disjointBy<TSecond, TKey, TSecondKey>(iterable: Iterable<TSecond>, keySelector: Selector<TElement, TKey>, otherKeySelector: Selector<TSecond, TSecondKey>, keyComparator?: EqualityComparator<TKey | TSecondKey>): boolean;
    distinct(keyComparator?: EqualityComparator<TElement>): IEnumerable<TElement>;
    distinctBy<TKey>(keySelector: Selector<TElement, TKey>, keyComparator?: EqualityComparator<TKey>): IEnumerable<TElement>;
    distinctUntilChanged(comparator?: EqualityComparator<TElement>): IEnumerable<TElement>;
    distinctUntilChangedBy<TKey>(keySelector: Selector<TElement, TKey>, keyComparator?: EqualityComparator<TKey>): IEnumerable<TElement>;
    elementAt(index: number): TElement;
    elementAtOrDefault(index: number): TElement | null;
    exactly(count: number, predicate?: Predicate<TElement>): boolean;
    except(iterable: Iterable<TElement>, comparator?: EqualityComparator<TElement> | OrderComparator<TElement>): IEnumerable<TElement>;
    exceptBy<TKey>(iterable: Iterable<TElement>, keySelector: Selector<TElement, TKey>, keyComparator?: EqualityComparator<TKey> | OrderComparator<TKey>): IEnumerable<TElement>;
    first<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): TFiltered;
    first(predicate?: Predicate<TElement>): TElement;
    firstOrDefault<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): TFiltered | null;
    firstOrDefault(predicate?: Predicate<TElement>): TElement | null;
    forEach(action: IndexedAction<TElement>): void;
    groupBy<TKey>(keySelector: Selector<TElement, TKey>, keyComparator?: EqualityComparator<TKey>, hashSelector?: Selector<TElement, PropertyKey>): IEnumerable<IGroup<TKey, TElement>>;
    groupJoin<TInner, TKey, TResult>(innerEnumerable: IEnumerable<TInner>, outerKeySelector: Selector<TElement, TKey>, innerKeySelector: Selector<TInner, TKey>, resultSelector: JoinSelector<TElement, IEnumerable<TInner>, TResult>, keyComparator?: EqualityComparator<TKey>): IEnumerable<TResult>;
    index(): IEnumerable<[number, TElement]>;
    interleave<TSecond>(iterable: Iterable<TSecond>): IEnumerable<TElement | TSecond>;
    intersect(iterable: Iterable<TElement>, comparator?: EqualityComparator<TElement> | OrderComparator<TElement>): IEnumerable<TElement>;
    intersectBy<TKey>(iterable: Iterable<TElement>, keySelector: Selector<TElement, TKey>, keyComparator?: EqualityComparator<TKey> | OrderComparator<TKey>): IEnumerable<TElement>;
    intersperse<TSeparator = TElement>(separator: TSeparator): IEnumerable<TElement | TSeparator>;
    join<TInner, TKey, TResult>(innerEnumerable: IEnumerable<TInner>, outerKeySelector: Selector<TElement, TKey>, innerKeySelector: Selector<TInner, TKey>, resultSelector: JoinSelector<TElement, TInner, TResult>, keyComparator?: EqualityComparator<TKey>): IEnumerable<TResult>;
    last<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): TFiltered;
    last(predicate?: Predicate<TElement>): TElement;
    lastOrDefault<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): TFiltered | null;
    lastOrDefault(predicate?: Predicate<TElement>): TElement | null;
    leftJoin<TInner, TKey, TResult>(innerEnumerable: IEnumerable<TInner>, outerKeySelector: Selector<TElement, TKey>, innerKeySelector: Selector<TInner, TKey>, resultSelector: JoinSelector<TElement, TInner, TResult>, keyComparator?: EqualityComparator<TKey>): IEnumerable<TResult>;
    max(this: Iterable<number>): number;
    max(selector: Selector<TElement, number>): number;
    maxBy<TKey>(keySelector: Selector<TElement, TKey>, comparator?: OrderComparator<TKey>): TElement;
    median(selector?: Selector<TElement, number>, tie?: MedianTieStrategy): number;
    min(this: Iterable<number>): number;
    min(selector: Selector<TElement, number>): number;
    minBy<TKey>(keySelector: Selector<TElement, TKey>, comparator?: OrderComparator<TKey>): TElement;
    mode<TKey>(keySelector?: Selector<TElement, TKey>): TElement;
    modeOrDefault<TKey>(keySelector?: Selector<TElement, TKey>): TElement | null;
    multimode<TKey>(keySelector?: Selector<TElement, TKey>): IEnumerable<TElement>;
    none(predicate?: Predicate<TElement>): boolean;
    ofType<TResult extends ObjectType>(type: TResult): IEnumerable<InferredType<TResult>>;
    order(comparator?: OrderComparator<TElement>): IOrderedEnumerable<TElement>;
    orderBy<TKey>(keySelector: Selector<TElement, TKey>, comparator?: OrderComparator<TKey>): IOrderedEnumerable<TElement>;
    orderByDescending<TKey>(keySelector: Selector<TElement, TKey>, comparator?: OrderComparator<TKey>): IOrderedEnumerable<TElement>;
    orderDescending(comparator?: OrderComparator<TElement>): IOrderedEnumerable<TElement>;
    pairwise(resulSelector?: PairwiseSelector<TElement, TElement>): IEnumerable<[TElement, TElement]>;
    partition<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): [IEnumerable<TFiltered>, IEnumerable<Exclude<TElement, TFiltered>>];
    partition(predicate: Predicate<TElement>): [IEnumerable<TElement>, IEnumerable<TElement>];
    percentile(this: Iterable<number>, percent: number, strategy?: PercentileStrategy): number;
    percentile(percent: number, selector: Selector<TElement, number>, strategy?: PercentileStrategy): number;
    permutations(size?: number): IEnumerable<IEnumerable<TElement>>;
    pipe<TResult>(operator: PipeOperator<TElement, TResult>): TResult;
    prepend(element: TElement): IEnumerable<TElement>;
    product(this: Iterable<number>): number;
    product(selector: Selector<TElement, number>): number;
    reverse(): IEnumerable<TElement>;
    rightJoin<TInner, TKey, TResult>(innerEnumerable: IEnumerable<TInner>, outerKeySelector: Selector<TElement, TKey>, innerKeySelector: Selector<TInner, TKey>, resultSelector: JoinSelector<TElement | null, TInner, TResult>, keyComparator?: EqualityComparator<TKey>): IEnumerable<TResult>;
    rotate(shift: number): IEnumerable<TElement>;
    scan(accumulator: Accumulator<TElement, TElement>): IEnumerable<TElement>;
    scan<TAccumulate>(accumulator: Accumulator<TElement, TAccumulate>, seed: TAccumulate): IEnumerable<TAccumulate>;
    select<TResult>(selector: IndexedSelector<TElement, TResult>): IEnumerable<TResult>;
    selectMany<TResult>(selector: IndexedSelector<TElement, Iterable<TResult>>): IEnumerable<TResult>;
    sequenceEqual(iterable: Iterable<TElement>, comparator?: EqualityComparator<TElement>): boolean;
    shuffle(): IEnumerable<TElement>;
    single<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): TFiltered;
    single(predicate?: Predicate<TElement>): TElement;
    singleOrDefault<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): TFiltered | null;
    singleOrDefault(predicate?: Predicate<TElement>): TElement | null;
    skip(count: number): IEnumerable<TElement>;
    skipLast(count: number): IEnumerable<TElement>;
    skipUntil<TFiltered extends TElement>(predicate: IndexedTypePredicate<TElement, TFiltered>): IEnumerable<TFiltered>;
    skipUntil(predicate: IndexedPredicate<TElement>): IEnumerable<TElement>;
    skipWhile(predicate: IndexedPredicate<TElement>): IEnumerable<TElement>;
    span<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): [IEnumerable<TFiltered>, IEnumerable<TElement>];
    span(predicate: Predicate<TElement>): [IEnumerable<TElement>, IEnumerable<TElement>];
    standardDeviation(selector?: Selector<TElement, number>, sample?: boolean): number;
    step(step: number): IEnumerable<TElement>;
    sum(this: Iterable<number>): number;
    sum(selector: Selector<TElement, number>): number;
    take(count: number): IEnumerable<TElement>;
    takeLast(count: number): IEnumerable<TElement>;
    takeUntil<TFiltered extends TElement>(predicate: IndexedTypePredicate<TElement, TFiltered>): IEnumerable<TFiltered>;
    takeUntil(predicate: IndexedPredicate<TElement>): IEnumerable<TElement>;
    takeWhile<TFiltered extends TElement>(predicate: IndexedTypePredicate<TElement, TFiltered>): IEnumerable<TFiltered>;
    takeWhile(predicate: IndexedPredicate<TElement>): IEnumerable<TElement>;
    tap(action: IndexedAction<TElement>): IEnumerable<TElement>;
    toArray(): TElement[];
    toCircularLinkedList(comparator?: EqualityComparator<TElement, TElement>): CircularLinkedList<TElement>;
    toCircularQueue(comparator?: EqualityComparator<TElement>): CircularQueue<TElement>;
    toCircularQueue(capacity: number, comparator?: EqualityComparator<TElement>): CircularQueue<TElement>;
    toDictionary<TKey, TValue>(keySelector: Selector<TElement, TKey>, valueSelector: Selector<TElement, TValue>, valueComparator?: EqualityComparator<TValue>): Dictionary<TKey, TValue>;
    toEnumerableSet(): EnumerableSet<TElement>;
    toImmutableCircularQueue(comparator?: EqualityComparator<TElement>): ImmutableCircularQueue<TElement>;
    toImmutableCircularQueue(capacity: number, comparator?: EqualityComparator<TElement>): ImmutableCircularQueue<TElement>;
    toImmutableDictionary<TKey, TValue>(keySelector: Selector<TElement, TKey>, valueSelector: Selector<TElement, TValue>, valueComparator?: EqualityComparator<TValue>): ImmutableDictionary<TKey, TValue>;
    toImmutableList(comparator?: EqualityComparator<TElement>): ImmutableList<TElement>;
    toImmutablePriorityQueue(comparator?: OrderComparator<TElement>): ImmutablePriorityQueue<TElement>;
    toImmutableQueue(comparator?: EqualityComparator<TElement>): ImmutableQueue<TElement>;
    toImmutableSet(): ImmutableSet<TElement>;
    toImmutableSortedDictionary<TKey, TValue>(keySelector: Selector<TElement, TKey>, valueSelector: Selector<TElement, TValue>, keyComparator?: OrderComparator<TKey>, valueComparator?: EqualityComparator<TValue>): ImmutableSortedDictionary<TKey, TValue>;
    toImmutableSortedSet(comparator?: OrderComparator<TElement>): ImmutableSortedSet<TElement>;
    toImmutableStack(comparator?: EqualityComparator<TElement>): ImmutableStack<TElement>;
    toLinkedList(comparator?: EqualityComparator<TElement>): LinkedList<TElement>;
    toList(comparator?: EqualityComparator<TElement>): List<TElement>;
    toLookup<TKey, TValue>(keySelector: Selector<TElement, TKey>, valueSelector: Selector<TElement, TValue>, keyComparator?: OrderComparator<TKey>): ILookup<TKey, TValue>;
    toMap<TKey, TValue>(keySelector: Selector<TElement, TKey>, valueSelector: Selector<TElement, TValue>): Map<TKey, TValue>;
    toObject<TKey extends PropertyKey, TValue>(keySelector: Selector<TElement, TKey>, valueSelector: Selector<TElement, TValue>): Record<TKey, TValue>;
    toPriorityQueue(comparator?: OrderComparator<TElement>): PriorityQueue<TElement>;
    toQueue(comparator?: EqualityComparator<TElement>): Queue<TElement>;
    toSet(): Set<TElement>;
    toSortedDictionary<TKey, TValue>(keySelector: Selector<TElement, TKey>, valueSelector: Selector<TElement, TValue>, keyComparator?: OrderComparator<TKey>, valueComparator?: EqualityComparator<TValue>): SortedDictionary<TKey, TValue>;
    toSortedSet(comparator?: OrderComparator<TElement>): SortedSet<TElement>;
    toStack(comparator?: EqualityComparator<TElement>): Stack<TElement>;
    union(iterable: Iterable<TElement>, comparator?: EqualityComparator<TElement>): IEnumerable<TElement>;
    unionBy<TKey>(iterable: Iterable<TElement>, keySelector: Selector<TElement, TKey>, comparator?: EqualityComparator<TKey>): IEnumerable<TElement>;
    variance(selector?: Selector<TElement, number>, sample?: boolean): number;
    where<TFiltered extends TElement>(predicate: IndexedTypePredicate<TElement, TFiltered>): IEnumerable<TFiltered>;
    where(predicate: IndexedPredicate<TElement>): IEnumerable<TElement>;
    windows(size: number): IEnumerable<IEnumerable<TElement>>;
    zip<TSecond, TResult = [TElement, TSecond]>(iterable: Iterable<TSecond>, zipper?: Zipper<TElement, TSecond, TResult>): IEnumerable<[TElement, TSecond]> | IEnumerable<TResult>;
    zipMany<TIterable extends readonly Iterable<unknown>[]>(...iterables: [...TIterable]): IEnumerable<[TElement, ...UnpackIterableTuple<TIterable>]>;
    zipMany<TIterable extends readonly Iterable<unknown>[], TResult>(...iterablesAndZipper: [...TIterable, ZipManyZipper<[TElement, ...UnpackIterableTuple<TIterable>], TResult>]): IEnumerable<TResult>;
}

export declare class EnumerableSet<TElement> extends AbstractSet<TElement> {
    #private;
    constructor(iterable?: Iterable<TElement>);
    [Symbol.iterator](): Iterator<TElement>;
    add(element: TElement): boolean;
    clear(): void;
    contains(element: TElement): boolean;
    remove(element: TElement): boolean;
    removeAll<TSource extends TElement>(collection: Iterable<TSource>): boolean;
    removeIf(predicate: Predicate<TElement>): boolean;
    retainAll(collection: Iterable<TElement>): boolean;
    size(): number;
    get comparator(): EqualityComparator<TElement>;
    get length(): number;
}

export declare class Enumerator<TElement> implements IOrderedEnumerable<TElement> {
    #private;
    private readonly iterable;
    private static readonly DIMENSION_MISMATCH_EXCEPTION;
    private static readonly MORE_THAN_ONE_ELEMENT_EXCEPTION;
    private static readonly MORE_THAN_ONE_MATCHING_ELEMENT_EXCEPTION;
    private static readonly NO_ELEMENTS_EXCEPTION;
    private static readonly NO_MATCHING_ELEMENT_EXCEPTION;
    constructor(iterable: () => Iterable<TElement>);
    [Symbol.iterator](): Iterator<TElement>;
    aggregate(accumulator: Accumulator<TElement, TElement>): TElement;
    aggregate<TAccumulate>(accumulator: Accumulator<TElement, TAccumulate>, seed: TAccumulate): TAccumulate;
    aggregate<TAccumulate, TResult>(accumulator: Accumulator<TElement, TAccumulate>, seed: TAccumulate, resultSelector: Selector<TAccumulate, TResult>): TResult;
    aggregateBy<TKey, TAccumulate = TElement>(keySelector: Selector<TElement, TKey>, seedSelector: Selector<TKey, TAccumulate> | TAccumulate, accumulator: Accumulator<TElement, TAccumulate>, keyComparator?: EqualityComparator<TKey>): IEnumerable<KeyValuePair<TKey, TAccumulate>>;
    all(predicate: Predicate<TElement>): boolean;
    any(predicate?: Predicate<TElement>): boolean;
    append(element: TElement): IEnumerable<TElement>;
    atLeast(count: number, predicate?: Predicate<TElement>): boolean;
    atMost(count: number, predicate?: Predicate<TElement>): boolean;
    average(this: Iterable<number>): number;
    average(selector: Selector<TElement, number>): number;
    cartesian<TSecond>(iterable: Iterable<TSecond>): IEnumerable<[TElement, TSecond]>;
    cast<TResult>(): IEnumerable<TResult>;
    chunk(size: number): IEnumerable<IEnumerable<TElement>>;
    combinations(size?: number): IEnumerable<IEnumerable<TElement>>;
    compact(): IEnumerable<NonNullable<TElement>>;
    concat(iterable: Iterable<TElement>): IEnumerable<TElement>;
    contains(element: TElement, comparator?: EqualityComparator<TElement>): boolean;
    correlation<TSecond>(iterable: Iterable<TSecond>, selector?: Selector<TElement, number>, otherSelector?: Selector<TSecond, number>): number;
    correlationBy(leftSelector: Selector<TElement, number>, rightSelector: Selector<TElement, number>): number;
    count(predicate?: Predicate<TElement>): number;
    countBy<TKey>(keySelector: Selector<TElement, TKey>, comparator?: EqualityComparator<TKey>): IEnumerable<KeyValuePair<TKey, number>>;
    covariance<TSecond>(iterable: Iterable<TSecond>, selector?: Selector<TElement, number>, otherSelector?: Selector<TSecond, number>, sample?: boolean): number;
    covarianceBy(leftSelector: Selector<TElement, number>, rightSelector: Selector<TElement, number>, sample?: boolean): number;
    cycle(count?: number): IEnumerable<TElement>;
    defaultIfEmpty(value?: TElement | null): IEnumerable<TElement | null>;
    disjoint<TSecond>(iterable: Iterable<TSecond>, comparator?: EqualityComparator<TElement | TSecond>): boolean;
    disjointBy<TSecond, TKey, TSecondKey>(iterable: Iterable<TSecond>, keySelector: Selector<TElement, TKey>, otherKeySelector: Selector<TSecond, TSecondKey>, keyComparator?: EqualityComparator<TKey | TSecondKey>): boolean;
    distinct(keyComparator?: EqualityComparator<TElement>): IEnumerable<TElement>;
    distinctBy<TKey>(keySelector: Selector<TElement, TKey>, keyComparator?: EqualityComparator<TKey>): IEnumerable<TElement>;
    distinctUntilChanged(comparator?: EqualityComparator<TElement>): IEnumerable<TElement>;
    distinctUntilChangedBy<TKey>(keySelector: Selector<TElement, TKey>, keyComparator?: EqualityComparator<TKey>): IEnumerable<TElement>;
    elementAt(index: number): TElement;
    elementAtOrDefault(index: number): TElement | null;
    exactly(count: number, predicate?: Predicate<TElement>): boolean;
    except(iterable: Iterable<TElement>, comparator?: EqualityComparator<TElement> | OrderComparator<TElement>): IEnumerable<TElement>;
    exceptBy<TKey>(iterable: Iterable<TElement>, keySelector: Selector<TElement, TKey>, keyComparator?: EqualityComparator<TKey> | OrderComparator<TKey>): IEnumerable<TElement>;
    first<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): TFiltered;
    first(predicate?: Predicate<TElement>): TElement;
    firstOrDefault<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): TFiltered | null;
    firstOrDefault(predicate?: Predicate<TElement>): TElement | null;
    forEach(action: IndexedAction<TElement>): void;
    groupBy<TKey>(keySelector: Selector<TElement, TKey>, keyComparator?: EqualityComparator<TKey>, hashSelector?: Selector<TElement, PropertyKey>): IEnumerable<IGroup<TKey, TElement>>;
    groupJoin<TInner, TKey, TResult>(innerEnumerable: IEnumerable<TInner>, outerKeySelector: Selector<TElement, TKey>, innerKeySelector: Selector<TInner, TKey>, resultSelector: JoinSelector<TElement, IEnumerable<TInner>, TResult>, keyComparator?: EqualityComparator<TKey>): IEnumerable<TResult>;
    index(): IEnumerable<[number, TElement]>;
    interleave<TSecond>(iterable: Iterable<TSecond>): IEnumerable<TElement | TSecond>;
    intersect(iterable: Iterable<TElement>, comparator?: EqualityComparator<TElement> | OrderComparator<TElement>): IEnumerable<TElement>;
    intersectBy<TKey>(iterable: Iterable<TElement>, keySelector: Selector<TElement, TKey>, keyComparator?: EqualityComparator<TKey> | OrderComparator<TKey>): IEnumerable<TElement>;
    intersperse<TSeparator = TElement>(separator: TSeparator): IEnumerable<TElement | TSeparator>;
    join<TInner, TKey, TResult>(innerEnumerable: IEnumerable<TInner>, outerKeySelector: Selector<TElement, TKey>, innerKeySelector: Selector<TInner, TKey>, resultSelector: JoinSelector<TElement, TInner, TResult>, keyComparator?: EqualityComparator<TKey>): IEnumerable<TResult>;
    last<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): TFiltered;
    last(predicate?: Predicate<TElement>): TElement;
    lastOrDefault<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): TFiltered | null;
    lastOrDefault(predicate?: Predicate<TElement>): TElement | null;
    leftJoin<TInner, TKey, TResult>(innerEnumerable: IEnumerable<TInner>, outerKeySelector: Selector<TElement, TKey>, innerKeySelector: Selector<TInner, TKey>, resultSelector: JoinSelector<TElement, TInner, TResult>, keyComparator?: EqualityComparator<TKey>): IEnumerable<TResult>;
    max(this: Iterable<number>): number;
    max(selector: Selector<TElement, number>): number;
    maxBy<TKey>(keySelector: Selector<TElement, TKey>, comparator?: OrderComparator<TKey>): TElement;
    median(selector?: Selector<TElement, number>, tie?: MedianTieStrategy): number;
    min(this: Iterable<number>): number;
    min(selector: Selector<TElement, number>): number;
    minBy<TKey>(keySelector: Selector<TElement, TKey>, comparator?: OrderComparator<TKey>): TElement;
    mode<TKey>(keySelector?: Selector<TElement, TKey>): TElement;
    modeOrDefault<TKey>(keySelector?: Selector<TElement, TKey>): TElement | null;
    multimode<TKey>(keySelector?: Selector<TElement, TKey>): IEnumerable<TElement>;
    none(predicate?: Predicate<TElement>): boolean;
    ofType<TResult extends ObjectType>(type: TResult): IEnumerable<InferredType<TResult>>;
    order(comparator?: OrderComparator<TElement>): IOrderedEnumerable<TElement>;
    orderBy<TKey>(keySelector: Selector<TElement, TKey>, comparator?: OrderComparator<TKey>): IOrderedEnumerable<TElement>;
    orderByDescending<TKey>(keySelector: Selector<TElement, TKey>, comparator?: OrderComparator<TKey>): IOrderedEnumerable<TElement>;
    orderDescending(comparator?: OrderComparator<TElement>): IOrderedEnumerable<TElement>;
    pairwise(resultSelector?: PairwiseSelector<TElement, TElement>): IEnumerable<[TElement, TElement]>;
    partition<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): [IEnumerable<TFiltered>, IEnumerable<Exclude<TElement, TFiltered>>];
    partition(predicate: Predicate<TElement>): [IEnumerable<TElement>, IEnumerable<TElement>];
    percentile(this: Iterable<number>, percent: number, strategy?: PercentileStrategy): number;
    percentile(percent: number, selector: Selector<TElement, number>, strategy?: PercentileStrategy): number;
    permutations(size?: number): IEnumerable<IEnumerable<TElement>>;
    pipe<TResult>(operator: PipeOperator<TElement, TResult>): TResult;
    prepend(element: TElement): IEnumerable<TElement>;
    product(this: Iterable<number>): number;
    product(selector: Selector<TElement, number>): number;
    reverse(): IEnumerable<TElement>;
    rightJoin<TInner, TKey, TResult>(innerEnumerable: IEnumerable<TInner>, outerKeySelector: Selector<TElement, TKey>, innerKeySelector: Selector<TInner, TKey>, resultSelector: JoinSelector<TElement | null, TInner, TResult>, keyComparator?: EqualityComparator<TKey>): IEnumerable<TResult>;
    rotate(shift: number): IEnumerable<TElement>;
    scan(accumulator: Accumulator<TElement, TElement>): IEnumerable<TElement>;
    scan<TAccumulate>(accumulator: Accumulator<TElement, TAccumulate>, seed: TAccumulate): IEnumerable<TAccumulate>;
    select<TResult>(selector: IndexedSelector<TElement, TResult>): IEnumerable<TResult>;
    selectMany<TResult>(selector: IndexedSelector<TElement, Iterable<TResult>>): IEnumerable<TResult>;
    sequenceEqual(iterable: Iterable<TElement>, comparator?: EqualityComparator<TElement>): boolean;
    shuffle(): IEnumerable<TElement>;
    single<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): TFiltered;
    single(predicate?: Predicate<TElement>): TElement;
    singleOrDefault<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): TFiltered | null;
    singleOrDefault(predicate?: Predicate<TElement>): TElement | null;
    skip(count: number): IEnumerable<TElement>;
    skipLast(count: number): IEnumerable<TElement>;
    skipUntil<TFiltered extends TElement>(predicate: IndexedTypePredicate<TElement, TFiltered>): IEnumerable<TFiltered>;
    skipUntil(predicate: IndexedPredicate<TElement>): IEnumerable<TElement>;
    skipWhile(predicate: IndexedPredicate<TElement>): IEnumerable<TElement>;
    span<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): [IEnumerable<TFiltered>, IEnumerable<TElement>];
    span(predicate: Predicate<TElement>): [IEnumerable<TElement>, IEnumerable<TElement>];
    standardDeviation(selector?: Selector<TElement, number>, sample?: boolean): number;
    step(step: number): IEnumerable<TElement>;
    sum(this: Iterable<number>): number;
    sum(selector: Selector<TElement, number>): number;
    take(count: number): IEnumerable<TElement>;
    takeLast(count: number): IEnumerable<TElement>;
    takeUntil<TFiltered extends TElement>(predicate: IndexedTypePredicate<TElement, TFiltered>): IEnumerable<TFiltered>;
    takeUntil(predicate: IndexedPredicate<TElement>): IEnumerable<TElement>;
    takeWhile<TFiltered extends TElement>(predicate: IndexedTypePredicate<TElement, TFiltered>): IEnumerable<TFiltered>;
    takeWhile(predicate: IndexedPredicate<TElement>): IEnumerable<TElement>;
    tap(action: IndexedAction<TElement>): IEnumerable<TElement>;
    thenBy<TKey>(keySelector: Selector<TElement, TKey>, comparator?: OrderComparator<TKey>): IOrderedEnumerable<TElement>;
    thenByDescending<TKey>(keySelector: Selector<TElement, TKey>, comparator?: OrderComparator<TKey>): IOrderedEnumerable<TElement>;
    toArray(): TElement[];
    toCircularLinkedList(comparator?: EqualityComparator<TElement, TElement>): CircularLinkedList<TElement>;
    toCircularQueue(comparator?: EqualityComparator<TElement>): CircularQueue<TElement>;
    toCircularQueue(capacity: number, comparator?: EqualityComparator<TElement>): CircularQueue<TElement>;
    toDictionary<TKey, TValue>(keySelector: Selector<TElement, TKey>, valueSelector: Selector<TElement, TValue>, valueComparator?: EqualityComparator<TValue>): Dictionary<TKey, TValue>;
    toEnumerableSet(): EnumerableSet<TElement>;
    toImmutableCircularQueue(comparator?: EqualityComparator<TElement>): ImmutableCircularQueue<TElement>;
    toImmutableCircularQueue(capacity: number, comparator?: EqualityComparator<TElement>): ImmutableCircularQueue<TElement>;
    toImmutableDictionary<TKey, TValue>(keySelector: Selector<TElement, TKey>, valueSelector: Selector<TElement, TValue>, valueComparator?: EqualityComparator<TValue>): ImmutableDictionary<TKey, TValue>;
    toImmutableList(comparator?: EqualityComparator<TElement>): ImmutableList<TElement>;
    toImmutablePriorityQueue(comparator?: OrderComparator<TElement>): ImmutablePriorityQueue<TElement>;
    toImmutableQueue(comparator?: EqualityComparator<TElement>): ImmutableQueue<TElement>;
    toImmutableSet(): ImmutableSet<TElement>;
    toImmutableSortedDictionary<TKey, TValue>(keySelector: Selector<TElement, TKey>, valueSelector: Selector<TElement, TValue>, keyComparator?: OrderComparator<TKey>, valueComparator?: EqualityComparator<TValue>): ImmutableSortedDictionary<TKey, TValue>;
    toImmutableSortedSet(comparator?: OrderComparator<TElement>): ImmutableSortedSet<TElement>;
    toImmutableStack(comparator?: EqualityComparator<TElement>): ImmutableStack<TElement>;
    toLinkedList(comparator?: EqualityComparator<TElement>): LinkedList<TElement>;
    toList(comparator?: EqualityComparator<TElement>): List<TElement>;
    toLookup<TKey, TValue>(keySelector: Selector<TElement, TKey>, valueSelector: Selector<TElement, TValue>, keyComparator?: OrderComparator<TKey>): ILookup<TKey, TValue>;
    toMap<TKey, TValue>(keySelector: Selector<TElement, TKey>, valueSelector: Selector<TElement, TValue>): Map<TKey, TValue>;
    toObject<TKey extends PropertyKey, TValue>(keySelector: Selector<TElement, TKey>, valueSelector: Selector<TElement, TValue>): Record<TKey, TValue>;
    toPriorityQueue(comparator?: OrderComparator<TElement>): PriorityQueue<TElement>;
    toQueue(comparator?: EqualityComparator<TElement>): Queue<TElement>;
    toSet(): Set<TElement>;
    toSortedDictionary<TKey, TValue>(keySelector: Selector<TElement, TKey>, valueSelector: Selector<TElement, TValue>, keyComparator?: OrderComparator<TKey>, valueComparator?: EqualityComparator<TValue>): SortedDictionary<TKey, TValue>;
    toSortedSet(comparator?: OrderComparator<TElement>): SortedSet<TElement>;
    toStack(comparator?: EqualityComparator<TElement>): Stack<TElement>;
    union(iterable: Iterable<TElement>, comparator?: EqualityComparator<TElement>): IEnumerable<TElement>;
    unionBy<TKey>(iterable: Iterable<TElement>, keySelector: Selector<TElement, TKey>, comparator?: EqualityComparator<TKey>): IEnumerable<TElement>;
    variance(selector?: Selector<TElement, number>, sample?: boolean): number;
    where<TFiltered extends TElement>(predicate: IndexedTypePredicate<TElement, TFiltered>): IEnumerable<TFiltered>;
    where(predicate: IndexedPredicate<TElement>): IEnumerable<TElement>;
    windows(size: number): IEnumerable<IEnumerable<TElement>>;
    zip<TSecond, TResult = [TElement, TSecond]>(iterable: Iterable<TSecond>, zipper?: Zipper<TElement, TSecond, TResult>): IEnumerable<[TElement, TSecond]> | IEnumerable<TResult>;
    zipMany<TIterable extends readonly Iterable<unknown>[]>(...iterables: [...TIterable]): IEnumerable<[TElement, ...UnpackIterableTuple<TIterable>]>;
    zipMany<TIterable extends readonly Iterable<unknown>[], TResult>(...iterablesAndZipper: [...TIterable, ZipManyZipper<[TElement, ...UnpackIterableTuple<TIterable>], TResult>]): IEnumerable<TResult>;
    private appendGenerator;
    private cartesianGenerator;
    private castGenerator;
    private chunkGenerator;
    private combinationsGenerator;
    private compactGenerator;
    private concatGenerator;
    private cycleGenerator;
    private defaultIfEmptyGenerator;
    private distinctUntilChangedGenerator;
    private exceptByGenerator;
    private exceptGenerator;
    private groupByGenerator;
    private groupJoinGenerator;
    private indexGenerator;
    private interleaveGenerator;
    private intersectByGenerator;
    private intersectGenerator;
    private intersperseGenerator;
    private joinGenerator;
    private multimodeGenerator;
    private ofTypeGenerator;
    private pairwiseGenerator;
    private permutationsGenerator;
    private prependGenerator;
    private reverseGenerator;
    private rightJoinGenerator;
    private rotateGenerator;
    private rotateLeftGenerator;
    private rotateRightGenerator;
    private scanGenerator;
    private selectGenerator;
    private selectManyGenerator;
    private shuffleGenerator;
    private skipGenerator;
    private skipLastGenerator;
    private skipUntilGenerator;
    private skipWhileGenerator;
    private stepGenerator;
    private takeGenerator;
    private takeLastGenerator;
    private takeUntilGenerator;
    private takeWhileGenerator;
    private tapGenerator;
    private unionByGenerator;
    private unionGenerator;
    private whereGenerator;
    private windowsGenerator;
    private zipGenerator;
    private zipManyWithZipperGenerator;
    private zipManyWithoutZipperGenerator;
}

export declare interface EqualityComparator<TFirst, TSecond = TFirst> {
    (e1: TFirst, e2: TSecond): boolean;
}

/**
 * Determines whether {@link source} contains exactly {@link count} elements that satisfy the optional predicate.
 * @template TElement Type of elements within the {@link source} iterable.
 * @param source The iterable whose elements are evaluated.
 * @param count Exact number of matching elements required. Must be greater than or equal to 0.
 * @param predicate Optional predicate that determines which elements are counted. When omitted, every element is considered a match.
 * @returns {boolean} `true` when exactly {@link count} matching elements are present; otherwise, `false`.
 * @throws {InvalidArgumentException} Thrown when {@link count} is negative.
 * @throws {unknown} Re-throws any error encountered while iterating {@link source} or executing the predicate.
 * @remarks Enumeration stops once the running total exceeds {@link count}, preventing unnecessary work on long iterables.
 * @example
 * ```typescript
 * const numbers = [1, 2, 3, 4, 5];
 * const hasExactlyThreeOdds = exactly(numbers, 3, n => n % 2 !== 0);
 * console.log(hasExactlyThreeOdds); // true
 * ```
 */
export declare const exactly: <TElement>(source: Iterable<TElement>, count: number, predicate?: Predicate<TElement>) => boolean;

/**
 * Returns the elements of {@link source} that are not present in {@link other}.
 * @template TElement Type of elements within the `source` iterable.
 * @param source The source iterable.
 * @param other Sequence whose elements should be removed from {@link source}.
 * @param comparator Optional comparator used to determine element equality. Both equality and order comparators are supported; defaults to the library's standard equality comparison when omitted.
 * @returns {IEnumerable<TElement>} A sequence containing the elements from {@link source} that do not appear in {@link other}.
 * @remarks The original ordering and duplicate occurrences from {@link source} are preserved. {@link other} is fully enumerated to build the exclusion set.
 * @example
 * ```typescript
 * const numbers1 = [1, 2, 3, 4, 5];
 * const numbers2 = [3, 5, 7];
 * const result = except(numbers1, numbers2).toArray();
 * console.log(result); // [1, 2, 4]
 * ```
 */
export declare const except: <TElement>(source: Iterable<TElement>, other: Iterable<TElement>, comparator?: EqualityComparator<TElement> | OrderComparator<TElement>) => IEnumerable<TElement>;

/**
 * Returns the elements of {@link source} whose projected keys are not present in {@link other}.
 * @template TElement Type of elements within the `source` iterable.
 * @template TKey Type produced by `keySelector`.
 * @param source The source iterable.
 * @param other Sequence whose elements define the keys that should be excluded.
 * @param keySelector Selector used to project each element to the key used for comparison.
 * @param keyComparator Optional comparator used to compare keys. Both equality and order comparators are supported; defaults to the library's standard equality comparison when omitted.
 * @returns {IEnumerable<TElement>} A sequence that contains the elements from {@link source} whose keys are absent from {@link other}.
 * @remarks Source ordering is preserved and duplicate elements with distinct keys remain. {@link other} is fully enumerated to materialise the exclusion keys.
 * @example
 * ```typescript
 * const products1 = [
 *   { name: 'Apple', category: 'Fruit' },
 *   { name: 'Banana', category: 'Fruit' },
 *   { name: 'Carrot', category: 'Vegetable' },
 * ];
 * const products2 = [
 *   { name: 'Broccoli', category: 'Vegetable' },
 * ];
 *
 * const result = exceptBy(products1, products2, p => p.category).toArray();
 * console.log(result);
 * // [
 * //   { name: 'Apple', category: 'Fruit' },
 * //   { name: 'Banana', category: 'Fruit' }
 * // ]
 * ```
 */
export declare const exceptBy: <TElement, TKey>(source: Iterable<TElement>, other: Iterable<TElement>, keySelector: Selector<TElement, TKey>, keyComparator?: EqualityComparator<TKey> | OrderComparator<TKey>) => IEnumerable<TElement>;

/**
 * Returns the first element in the sequence, optionally filtered by a predicate or type guard.
 * @template TElement Type of elements within the `source` iterable.
 * @template TFiltered Subtype confirmed when a type guard predicate is supplied.
 * @param source The source iterable.
 * @param predicate Predicate evaluated against each element; when omitted, the first element is returned. When a type guard is supplied, the returned value is narrowed to `TFiltered`.
 * @returns {TElement | TFiltered} The first element that satisfies the predicate (or the very first element when none is provided).
 * @throws {NoElementsException} Thrown when the sequence is empty.
 * @throws {NoMatchingElementException} Thrown when a predicate is supplied and no element satisfies it.
 * @remarks Enumeration stops immediately once a matching element is found.
 * @example
 * ```typescript
 * const numbers = [1, 2, 3, 4, 5];
 * const firstElement = first(numbers);
 * console.log(firstElement); // 1
 *
 * const firstEven = first(numbers, x => x % 2 === 0);
 * console.log(firstEven); // 2
 * ```
 */
export declare function first<TElement, TFiltered extends TElement>(source: Iterable<TElement>, predicate: TypePredicate<TElement, TFiltered>): TFiltered;

/**
 * Returns the first element in the sequence that satisfies an optional predicate.
 * @template TElement Type of elements within the `source` iterable.
 * @param source The source iterable.
 * @param predicate Optional predicate evaluated against each element; when omitted, the first element is returned.
 * @returns {TElement} The first element that satisfies {@link predicate}, or the very first element when the predicate is missing.
 * @throws {NoElementsException} Thrown when the sequence is empty.
 * @throws {NoMatchingElementException} Thrown when a predicate is supplied and no element satisfies it.
 * @remarks Enumeration stops immediately once a matching element is found.
 */
export declare function first<TElement>(source: Iterable<TElement>, predicate?: Predicate<TElement>): TElement;

/**
 * Returns the first element in the sequence or `null` when the sequence is empty or no element satisfies the predicate.
 * @template TElement Type of elements within the `source` iterable.
 * @template TFiltered Subtype confirmed when a type guard predicate is supplied.
 * @param source The source iterable.
 * @param predicate Predicate evaluated against each element; when omitted, the first element is returned. When a type guard is supplied, the returned value is narrowed to `TFiltered`.
 * @returns {TElement | TFiltered | null} The first matching element, or `null` when no match is found.
 * @remarks This function never throws for missing elements; it communicates absence through the `null` return value.
 * @example
 * ```typescript
 * const numbers = [1, 2, 3, 4, 5];
 * const firstElement = firstOrDefault(numbers);
 * console.log(firstElement); // 1
 *
 * const firstEven = firstOrDefault(numbers, x => x % 2 === 0);
 * console.log(firstEven); // 2
 *
 * const empty: number[] = [];
 * const firstOfEmpty = firstOrDefault(empty);
 * console.log(firstOfEmpty); // null
 *
 * const noEvens = [1, 3, 5];
 * const firstEven2 = firstOrDefault(noEvens, x => x % 2 === 0);
 * console.log(firstEven2); // null
 * ```
 */
export declare function firstOrDefault<TElement, TFiltered extends TElement>(source: Iterable<TElement>, predicate: TypePredicate<TElement, TFiltered>): TFiltered | null;

/**
 * Returns the first element in the sequence that satisfies an optional predicate, or `null` when none does.
 * @template TElement Type of elements within the `source` iterable.
 * @param source The source iterable.
 * @param predicate Optional predicate evaluated against each element; when omitted, the first element is returned.
 * @returns {TElement | null} The first element that satisfies {@link predicate}, or `null` when the sequence is empty or no element matches.
 * @remarks This overload never throws for missing elements; use {@link first} when absence should raise an exception.
 */
export declare function firstOrDefault<TElement>(source: Iterable<TElement>, predicate?: Predicate<TElement>): TElement | null;

/**
 * Executes the provided callback for every element in the sequence.
 * @template TElement Type of elements within the `source` iterable.
 * @param source The source iterable.
 * @param action Callback invoked for each element; receives the element and its zero-based index.
 * @returns {void}
 * @remarks Enumeration starts immediately. Avoid mutating the underlying collection while iterating.
 * @example
 * ```typescript
 * const numbers = [1, 2, 3];
 * forEach(numbers, (x, i) => console.log(`Index ${i}: ${x}`));
 * // Index 0: 1
 * // Index 1: 2
 * // Index 2: 3
 * ```
 */
export declare const forEach: <TElement>(source: Iterable<TElement>, action: IndexedAction<TElement>) => void;

/**
 * Wraps an iterable with the library's `IEnumerable` implementation.
 * @template TElement Type of elements within the `source` iterable.
 * @param source The iterable to expose as an enumerable sequence.
 * @returns {IEnumerable<TElement>} An enumerable view over the given iterable.
 * @remarks The returned sequence defers enumeration of {@link source} until iterated.
 * @example
 * ```typescript
 * const numbers = [1, 2, 3];
 * const enumerable = from(numbers);
 * console.log(enumerable.toArray()); // [1, 2, 3]
 * ```
 */
export declare const from: <TElement>(source: Iterable<TElement>) => IEnumerable<TElement>;

declare type FunctionType = Function | FunctionConstructor;

export declare class Group<TKey, TElement> extends AbstractEnumerable<TElement> implements IGroup<TKey, TElement> {
    readonly key: TKey;
    readonly source: IEnumerable<TElement>;
    constructor(key: TKey, source: IEnumerable<TElement>);
    [Symbol.iterator](): IterableIterator<TElement>;
}

/**
 * Partitions the sequence into groups based on keys projected from each element.
 * @template TElement Type of elements within the `source` iterable.
 * @template TKey Type of key produced by {@link keySelector}.
 * @param source The source iterable.
 * @param keySelector Selector used to derive the grouping key for each element.
 * @param keyComparator Optional equality comparator used to match keys. Defaults to the library's standard equality comparison.
 * @param hashSelector Optional hash selector. When provided together with `keyComparator`, the sequence will use a bucketed approach for faster grouping based on the hash values.
 * @returns {IEnumerable<IGroup<TKey, TElement>>} A sequence of groups, each exposing the key and the elements that share it.
 * @remarks The source sequence is enumerated once when the result is iterated. Elements within each group preserve their original order, and group contents are cached for repeated enumeration.
 * @example
 * ```typescript
 * const products = [
 *   { name: 'Apple', category: 'Fruit' },
 *   { name: 'Banana', category: 'Fruit' },
 *   { name: 'Carrot', category: 'Vegetable' },
 * ];
 *
 * const grouped = groupBy(products, p => p.category);
 * for (const group of grouped) {
 *   console.log(group.key, group.toArray());
 * }
 * // Fruit [ { name: 'Apple', category: 'Fruit' }, { name: 'Banana', category: 'Fruit' } ]
 * // Vegetable [ { name: 'Carrot', category: 'Vegetable' } ]
 * ```
 */
export declare const groupBy: <TElement, TKey>(source: Iterable<TElement>, keySelector: Selector<TElement, TKey>, keyComparator?: EqualityComparator<TKey>, hashSelector?: Selector<TElement, PropertyKey>) => IEnumerable<IGroup<TKey, TElement>>;

/**
 * Correlates each element of the sequence with a collection of matching elements from another sequence.
 * @template TElement Type of elements within the outer sequence.
 * @template TInner Type of elements within the inner sequence.
 * @template TKey Type of key produced by the key selectors.
 * @template TResult Type of element returned by {@link resultSelector}.
 * @param source The outer sequence.
 * @param innerEnumerable Sequence whose elements are grouped and joined with the outer elements.
 * @param outerKeySelector Selector that extracts the join key from each outer element.
 * @param innerKeySelector Selector that extracts the join key from each inner element.
 * @param resultSelector Projection that combines an outer element with an `IEnumerable` of matching inner elements.
 * @param keyComparator Optional equality comparator used to match keys. Defaults to the library's standard equality comparison.
 * @returns {IEnumerable<TResult>} A sequence produced by applying {@link resultSelector} to each outer element and its matching inner elements.
 * @remarks The inner sequence is enumerated once to build an in-memory lookup before outer elements are processed. Each outer element is then evaluated lazily and preserves the original outer ordering.
 * @example
 * ```typescript
 * const categories = [
 *   { id: 1, name: 'Fruit' },
 *   { id: 2, name: 'Vegetable' },
 * ];
 * const products = [
 *   { name: 'Apple', categoryId: 1 },
 *   { name: 'Banana', categoryId: 1 },
 *   { name: 'Carrot', categoryId: 2 },
 * ];
 *
 * const joined = groupJoin(
 *   categories,
 *   products,
 *   c => c.id,
 *   p => p.categoryId,
 *   (c, ps) => ({ ...c, products: ps.toArray() })
 * ).toArray();
 *
 * console.log(joined);
 * // [
 * //   { id: 1, name: 'Fruit', products: [ { name: 'Apple', categoryId: 1 }, { name: 'Banana', categoryId: 1 } ] },
 * //   { id: 2, name: 'Vegetable', products: [ { name: 'Carrot', categoryId: 2 } ] }
 * // ]
 * ```
 */
export declare const groupJoin: <TElement, TInner, TKey, TResult>(source: Iterable<TElement>, innerEnumerable: Iterable<TInner>, outerKeySelector: Selector<TElement, TKey>, innerKeySelector: Selector<TInner, TKey>, resultSelector: JoinSelector<TElement, IEnumerable<TInner>, TResult>, keyComparator?: EqualityComparator<TKey>) => IEnumerable<TResult>;

export declare class Heap<TElement> extends AbstractRandomAccessCollection<TElement> {
    #private;
    constructor();
    constructor(comparator: OrderComparator<TElement>);
    constructor(comparator: OrderComparator<TElement> | null, iterable: Iterable<TElement>);
    [Symbol.iterator](): Iterator<TElement>;
    /**
     * Adds an element to the heap.
     * @template TElement The type of elements in the heap.
     * @param element The element to add.
     * @returns true
     */
    add(element: TElement): boolean;
    /**
     * Adds all elements from the specified collection to the heap.
     * @template TSource The type of elements in the collection.
     * @param {Iterable<TSource>} collection The collection of elements to add.
     * @returns true if the heap was modified; otherwise, false.
     */
    addAll<TSource extends TElement>(collection: Iterable<TSource>): boolean;
    /**
     * Clears the heap.
     */
    clear(): void;
    contains(element: TElement): boolean;
    containsAll(collection: Iterable<TElement>): boolean;
    isEmpty(): boolean;
    /**
     * Retrieves the element at the root of the heap without removing it.
     * @template TElement The type of elements in the heap.
     * @returns {TElement|null} The element at the root of the heap, or null if the heap is empty.
     */
    peek(): TElement | null;
    /**
     * Retrieves the element at the root of the heap and removes it.
     * @template TElement The type of elements in the heap.
     * @returns {TElement|null} The element at the root of the heap, or null if the heap is empty.
     */
    poll(): TElement | null;
    /**
     * Removes the specified element from the heap.
     * @template TElement The type of elements in the heap.
     * @param {TElement} element The element to remove.
     * @returns true if the element was removed; otherwise, false.
     */
    remove(element: TElement): boolean;
    /**
     * Removes all elements in the specified collection from the heap.
     * @template TSource The type of elements that will be removed from the heap.
     * @param {Iterable<TSource>} collection The collection of elements to remove.
     * @returns true if any elements were removed; otherwise, false.
     */
    removeAll<TSource extends TElement>(collection: Iterable<TSource>): boolean;
    /**
     * Removes all elements from the heap that satisfy the specified predicate.
     * @param predicate The predicate used to determine which elements to remove.
     * @returns true if any elements were removed; otherwise, false.
     */
    removeIf(predicate: Predicate<TElement>): boolean;
    /**
     * Returns the number of elements in the heap.
     * @returns The number of elements in the heap.
     */
    size(): number;
    /**
     * Builds a heap from the current elements in O(n) time.
     * This is more efficient than adding elements one by one, which takes O(n log n) time.
     * @private
     */
    private buildHeap;
    get comparator(): OrderComparator<TElement>;
    /**
     * Returns the number of elements in the heap.
     * @returns The number of elements in the heap.
     */
    get length(): number;
    private getLeftChildIndex;
    private getLeftChildValue;
    private getParentIndex;
    private getParentValue;
    private getRightChildIndex;
    private getRightChildValue;
    private hasLeftChild;
    private hasRightChild;
    private heapifyDown;
    private heapifyUp;
}

export declare interface IAsyncEnumerable<TElement> extends AsyncIterable<TElement> {
    /**
     * Asynchronously combines the elements of the sequence by applying an accumulator to each element and optionally projecting the final result.
     * @template TAccumulate Type of the intermediate accumulator. Defaults to `TElement` when no seed is provided.
     * @template TResult Type returned when a `resultSelector` is supplied.
     * @param accumulator Function that merges the running accumulator with the next element.
     * @param seed Optional initial accumulator value. When omitted, the first element is used as the starting accumulator.
     * @param resultSelector Optional projection applied to the final accumulator before it is resolved.
     * @returns {Promise<TAccumulate|TResult>} A promise that resolves to the final accumulator (or its projection).
     * @throws {NoElementsException} Thrown when the sequence is empty and no `seed` is provided.
     * @remarks The source sequence is enumerated asynchronously exactly once. Supply a `seed` to avoid exceptions on empty sequences and to control the accumulator type.
     * @example
     * ```typescript
     * const numbers = fromAsync([1, 2, 3, 4, 5]);
     * const sum = await numbers.aggregate((acc, x) => acc + x);
     * console.log(sum); // 15
     *
     * const product = await numbers.aggregate((acc, x) => acc * x, 1);
     * console.log(product); // 120
     * ```
     */
    aggregate(accumulator: Accumulator<TElement, TElement>): Promise<TElement>;
    aggregate<TAccumulate>(accumulator: Accumulator<TElement, TAccumulate>, seed: TAccumulate): Promise<TAccumulate>;
    aggregate<TAccumulate, TResult>(accumulator: Accumulator<TElement, TAccumulate>, seed: TAccumulate, resultSelector: Selector<TAccumulate, TResult>): Promise<TResult>;
    /**
     * Groups elements by a computed key and aggregates each group by applying an accumulator within that group.
     * @template TKey Type returned by `keySelector` and used to organise groups.
     * @template TAccumulate Type of the accumulated value created for each group.
     * @param keySelector Selector that derives the grouping key for each element.
     * @param seedSelector Either an initial accumulator value applied to every group or a factory invoked with the group key to produce that value.
     * @param accumulator Function that merges the current accumulator with the next element in the group.
     * @param keyComparator Optional equality comparator used to match group keys.
     * @returns {IAsyncEnumerable<KeyValuePair<TKey, TAccumulate>>} An async sequence containing one key-value pair per group and its aggregated result.
     * @remarks When `seedSelector` is a function, it is evaluated once per group to obtain the initial accumulator.
     * @example
     * ```typescript
     * const products = fromAsync([
     *   { name: 'Apple', category: 'Fruit', price: 1.2 },
     *   { name: 'Banana', category: 'Fruit', price: 0.5 },
     *   { name: 'Carrot', category: 'Vegetable', price: 0.8 },
     *   { name: 'Broccoli', category: 'Vegetable', price: 1.5 },
     * ]);
     *
     * const totalPriceByCategory = await products.aggregateBy(
     *   p => p.category,
     *   0,
     *   (acc, p) => acc + p.price
     * ).toArray();
     *
     * console.log(totalPriceByCategory);
     * // [
     * //   { key: 'Fruit', value: 1.7 },
     * //   { key: 'Vegetable', value: 2.3 }
     * // ]
     * ```
     */
    aggregateBy<TKey, TAccumulate = TElement>(keySelector: Selector<TElement, TKey>, seedSelector: Selector<TKey, TAccumulate> | TAccumulate, accumulator: Accumulator<TElement, TAccumulate>, keyComparator?: EqualityComparator<TKey>): IAsyncEnumerable<KeyValuePair<TKey, TAccumulate>>;
    /**
     * Determines whether every element in the sequence satisfies the supplied predicate.
     * @param predicate Function that evaluates each element and returns `true` when it satisfies the condition.
     * @returns {Promise<boolean>} `true` when all elements satisfy the predicate; otherwise, `false`.
     * @remarks Enumeration stops as soon as the predicate returns `false`.
     * @example
     * ```typescript
     * const numbers = fromAsync([1, 2, 3, 4, 5]);
     * const allPositive = await numbers.all(x => x > 0);
     * console.log(allPositive); // true
     *
     * const mixedNumbers = fromAsync([-1, 2, 3, -4, 5]);
     * const allPositive2 = await mixedNumbers.all(x => x > 0);
     * console.log(allPositive2); // false
     * ```
     */
    all(predicate: Predicate<TElement>): Promise<boolean>;
    /**
     * Determines whether the sequence contains at least one element that matches the optional predicate.
     * @param predicate Optional function used to test elements. When omitted, the method resolves to `true` if the sequence contains any element.
     * @returns {Promise<boolean>} `true` when a matching element is found; otherwise, `false`.
     * @remarks When the predicate is omitted, only the first element is inspected, making this more efficient than awaiting `count() > 0`.
     * @example
     * ```typescript
     * const numbers = fromAsync([1, 2, 3, 4, 5]);
     * const hasEvenNumber = await numbers.any(x => x % 2 === 0);
     * console.log(hasEvenNumber); // true
     *
     * const oddNumbers = fromAsync([1, 3, 5]);
     * const hasEvenNumber2 = await oddNumbers.any(x => x % 2 === 0);
     * console.log(hasEvenNumber2); // false
     * ```
     */
    any(predicate?: Predicate<TElement>): Promise<boolean>;
    /**
     * Creates an async sequence that yields the current elements followed by the supplied element.
     * @param element Element appended to the end of the sequence.
     * @returns {IAsyncEnumerable<TElement>} A new async enumerable whose final item is the provided element.
     * @remarks The source sequence is not modified; enumeration is deferred until the returned sequence is iterated.
     * @example
     * ```typescript
     * const numbers = fromAsync([1, 2, 3]);
     * const appended = await numbers.append(4).toArray();
     * console.log(appended); // [1, 2, 3, 4]
     * ```
     */
    append(element: TElement): IAsyncEnumerable<TElement>;
    /**
     * Determines whether the async sequence contains at least {@link count} elements that satisfy the optional predicate.
     * @param count Minimum number of matching elements required. Must be greater than or equal to 0.
     * @param predicate Optional predicate that determines which elements are counted. When omitted, every element is considered a match.
     * @returns {Promise<boolean>} `true` when at least {@link count} matching elements are present; otherwise, `false`.
     * @throws {InvalidArgumentException} Thrown when {@link count} is negative.
     * @throws {unknown} Re-throws any error encountered while asynchronously iterating the sequence or executing the predicate.
     * @remarks Enumeration stops as soon as the required number of matches is found, avoiding unnecessary work on long sequences.
     * @example
     * ```typescript
     * const numbers = fromAsync([1, 2, 3, 4, 5]);
     * const hasAtLeastTwoEvens = await numbers.atLeast(2, n => n % 2 === 0);
     * console.log(hasAtLeastTwoEvens); // true
     * ```
     */
    atLeast(count: number, predicate?: Predicate<TElement>): Promise<boolean>;
    /**
     * Determines whether the async sequence contains no more than {@link count} elements that satisfy the optional predicate.
     * @param count Maximum number of matching elements allowed. Must be greater than or equal to 0.
     * @param predicate Optional predicate that determines which elements are counted. When omitted, every element is considered a match.
     * @returns {Promise<boolean>} `true` when the number of matching elements does not exceed {@link count}; otherwise, `false`.
     * @throws {InvalidArgumentException} Thrown when {@link count} is negative.
     * @throws {unknown} Re-throws any error encountered while asynchronously iterating the sequence or executing the predicate.
     * @remarks Enumeration stops as soon as the count is exceeded, making it efficient for large or infinite sequences.
     * @example
     * ```typescript
     * const numbers = fromAsync([1, 2, 3, 4, 5]);
     * const hasAtMostOneEven = await numbers.atMost(1, n => n % 2 === 0);
     * console.log(hasAtMostOneEven); // false
     * ```
     */
    atMost(count: number, predicate?: Predicate<TElement>): Promise<boolean>;
    /**
     * Computes the arithmetic mean of the numeric values produced for each element in the sequence.
     * @param selector Optional projection that extracts the numeric value for each element. Defaults to the element itself.
     * @returns {Promise<number>} A promise that resolves to the arithmetic mean of the selected values.
     * @throws {NoElementsException} Thrown when the sequence is empty.
     * @remarks Provide a selector when the elements are not already numeric. All values are enumerated exactly once.
     * @example
     * ```typescript
     * const numbers = fromAsync([1, 2, 3, 4, 5]);
     * const avg = await numbers.average();
     * console.log(avg); // 3
     *
     * const people = fromAsync([
     *   { name: 'Alice', age: 25 },
     *   { name: 'Bob', age: 30 },
     *   { name: 'Charlie', age: 35 },
     * ]);
     * const avgAge = await people.average(p => p.age);
     * console.log(avgAge); // 30
     * ```
     */
    average(this: AsyncIterable<number>): Promise<number>;
    average(selector: Selector<TElement, number>): Promise<number>;
    /**
     * Produces the cartesian product between this async sequence and {@link iterable}.
     * @template TSecond Type of elements emitted by {@link iterable}.
     * @param iterable The secondary async sequence paired with every element from the source.
     * @returns {IAsyncEnumerable<[TElement, TSecond]>} A deferred async sequence that yields each ordered pair `[source, other]`.
     * @throws {unknown} Re-throws any error raised while asynchronously iterating the source or {@link iterable}.
     * @remarks The secondary sequence is fully buffered before iteration starts so that it can be replayed for every source element. The resulting sequence stops when the source sequence completes.
     * @example
     * ```typescript
     * const pairs = await fromAsync([1, 2]).cartesian(fromAsync(['A', 'B'])).toArray();
     * console.log(pairs); // [[1, 'A'], [1, 'B'], [2, 'A'], [2, 'B']]
     * ```
     */
    cartesian<TSecond>(iterable: AsyncIterable<TSecond>): IAsyncEnumerable<[TElement, TSecond]>;
    /**
     * Reinterprets each element in the async sequence as the specified result type.
     * @template TResult Target type exposed by the returned sequence.
     * @returns {IAsyncEnumerable<TResult>} An async sequence that yields the same elements typed as `TResult`.
     * @remarks No runtime conversion occurs; ensure the underlying elements are compatible with `TResult` to avoid downstream failures.
     * @example
     * ```typescript
     * const mixed = fromAsync([1, 'two', 3, 'four']);
     * const numbers = mixed.cast<number>().where(x => typeof x === 'number');
     * console.log(await numbers.toArray()); // [1, 3]
     * ```
     */
    cast<TResult>(): IAsyncEnumerable<TResult>;
    /**
     * Splits the sequence into contiguous subsequences containing at most the specified number of elements.
     * @param size Maximum number of elements to include in each chunk. Must be greater than 0.
     * @returns {IAsyncEnumerable<IEnumerable<TElement>>} An async sequence whose elements are chunks of the original sequence.
     * @throws {InvalidArgumentException} Thrown when `size` is less than 1.
     * @remarks Each chunk is yielded as an `IEnumerable<TElement>`. The final chunk may contain fewer elements than `size`.
     * @example
     * ```typescript
     * const numbers = fromAsync([1, 2, 3, 4, 5, 6, 7, 8]);
     * const chunks = numbers.chunk(3);
     * const result = await chunks.select(c => c.toArray()).toArray();
     * console.log(result); // [[1, 2, 3], [4, 5, 6], [7, 8]]
     * ```
     */
    chunk(size: number): IAsyncEnumerable<IEnumerable<TElement>>;
    /**
     * Generates the unique combinations that can be built from the elements in the async sequence.
     * @param size Optional number of elements that each combination must contain. When omitted, combinations of every possible length are produced.
     * @returns {IAsyncEnumerable<IEnumerable<TElement>>} An async sequence of combinations built from the source elements.
     * @throws {InvalidArgumentException} Thrown when `size` is negative.
     * @remarks The source sequence is materialised before combinations are produced, so very large inputs can be expensive. Duplicate combinations produced by repeated elements are emitted only once.
     * @example
     * ```typescript
     * const numbers = fromAsync([1, 2, 3]);
     * const combs = numbers.combinations(2);
     * const result = await combs.select(c => c.toArray()).toArray();
     * console.log(result); // [[1, 2], [1, 3], [2, 3]]
     * ```
     */
    combinations(size?: number): IAsyncEnumerable<IEnumerable<TElement>>;
    /**
     * Filters out `null` and `undefined` values from the async sequence.
     * @template TElement Type of elements produced by the source sequence.
     * @returns {IAsyncEnumerable<NonNullable<TElement>>} An async sequence containing only elements that are neither `null` nor `undefined`.
     * @remarks The method preserves other falsy values (such as `0` or an empty string) and defers execution until the result is iterated.
     * @example
     * ```typescript
     * const values = await fromAsync([1, null, 0, undefined]).compact().toArray();
     * console.log(values); // [1, 0]
     * ```
     */
    compact(): IAsyncEnumerable<NonNullable<TElement>>;
    /**
     * Appends the specified async iterable to the end of the sequence.
     * @param other Additional elements that are yielded after the current sequence.
     * @returns {IAsyncEnumerable<TElement>} An async sequence containing the elements of the current sequence followed by those from `other`.
     * @remarks Enumeration of both sequences is deferred until the result is iterated.
     * @example
     * ```typescript
     * const numbers1 = fromAsync([1, 2, 3]);
     * const numbers2 = [4, 5, 6];
     * const concatenated = await numbers1.concat(numbers2).toArray();
     * console.log(concatenated); // [1, 2, 3, 4, 5, 6]
     * ```
     */
    concat(other: AsyncIterable<TElement>): IAsyncEnumerable<TElement>;
    /**
     * Determines whether the async sequence contains a specific element using an optional comparator.
     * @param element Element to locate in the sequence.
     * @param comparator Optional equality comparator used to match elements. Defaults to the library's standard equality comparison.
     * @returns {Promise<boolean>} `true` when the element is found; otherwise, `false`.
     * @example
     * ```typescript
     * const numbers = fromAsync([1, 2, 3, 4, 5]);
     * const hasThree = await numbers.contains(3);
     * console.log(hasThree); // true
     *
     * const hasTen = await numbers.contains(10);
     * console.log(hasTen); // false
     * ```
     */
    contains(element: TElement, comparator?: EqualityComparator<TElement>): Promise<boolean>;
    /**
     * Computes the Pearson correlation coefficient between this async sequence and {@link iterable}.
     * @template TSecond Type of elements produced by {@link iterable}.
     * @param iterable Async sequence whose elements align by index with the source sequence.
     * @param selector Optional projection that extracts the numeric value for each element of the source sequence. Defaults to treating the element itself as numeric.
     * @param otherSelector Optional projection that extracts the numeric value for each element of {@link iterable}. Defaults to treating the element itself as numeric.
     * @returns {Promise<number>} A promise that resolves to the correlation coefficient in the interval [-1, 1].
     * @throws {DimensionMismatchException} Thrown when the sequences do not contain the same number of elements.
     * @throws {InsufficientElementException} Thrown when fewer than two aligned pairs are available.
     * @throws {Error} Thrown when the standard deviation of either numeric projection is zero.
     * @throws {unknown} Re-throws any error encountered while asynchronously iterating the source, {@link iterable}, or executing the selector projections.
     * @remarks Both sequences are consumed simultaneously via an online algorithm that avoids buffering the full dataset. Ensure the async iterables are aligned because mismatch detection occurs only after iteration begins.
     * @example
     * ```typescript
     * const temperatures = fromAsync([15, 18, 21, 24]);
     * const sales = fromAsync([30, 36, 42, 48]);
     * const correlation = await temperatures.correlation(sales);
     * console.log(correlation); // 1
     * ```
     */
    correlation<TSecond>(iterable: AsyncIterable<TSecond>, selector?: Selector<TElement, number>, otherSelector?: Selector<TSecond, number>): Promise<number>;
    /**
     * Computes the Pearson correlation coefficient between two numeric projections of the async sequence.
     * @param leftSelector Projection that produces the first numeric series for each element.
     * @param rightSelector Projection that produces the second numeric series for each element.
     * @returns {Promise<number>} A promise that resolves to the correlation coefficient in the interval [-1, 1].
     * @throws {InsufficientElementException} Thrown when fewer than two elements are available.
     * @throws {Error} Thrown when the standard deviation of either numeric projection is zero.
     * @throws {unknown} Re-throws any error encountered while iterating the sequence or executing the selector projections.
     * @remarks The sequence is consumed exactly once using an online algorithm, which keeps memory usage constant even for large inputs.
     * @example
     * ```typescript
     * const metrics = fromAsync([
     *   { impressions: 1_000, clicks: 50 },
     *   { impressions: 1_500, clicks: 75 },
     *   { impressions: 2_000, clicks: 100 }
     * ]);
     * const correlation = await metrics.correlationBy(m => m.impressions, m => m.clicks);
     * console.log(correlation); // 1
     * ```
     */
    correlationBy(leftSelector: Selector<TElement, number>, rightSelector: Selector<TElement, number>): Promise<number>;
    /**
     * Counts the number of elements in the async sequence, optionally restricted by a predicate.
     * @param predicate Optional predicate that determines which elements are counted. When omitted, all elements are counted.
     * @returns {Promise<number>} A promise that resolves to the number of elements that satisfy the predicate.
     * @remarks Prefer calling `any()` to test for existence instead of comparing this result with zero.
     * @example
     * ```typescript
     * const numbers = fromAsync([1, 2, 3, 4, 5]);
     * const totalCount = await numbers.count();
     * console.log(totalCount); // 5
     *
     * const evenCount = await numbers.count(x => x % 2 === 0);
     * console.log(evenCount); // 2
     * ```
     */
    count(predicate?: Predicate<TElement>): Promise<number>;
    /**
     * Counts the occurrences of elements grouped by a derived key.
     * @template TKey Type produced by `keySelector`.
     * @param keySelector Selector used to derive the grouping key for each element.
     * @param comparator Optional equality comparator used to match keys. Defaults to the library's standard equality comparison.
     * @returns {IAsyncEnumerable<KeyValuePair<TKey, number>>} An async sequence of key/count pairs describing how many elements share each key.
     * @remarks Each key appears exactly once in the result with its associated occurrence count.
     * @example
     * ```typescript
     * const products = fromAsync([
     *   { name: 'Apple', category: 'Fruit' },
     *   { name: 'Banana', category: 'Fruit' },
     *   { name: 'Carrot', category: 'Vegetable' },
     * ]);
     *
     * const countByCategory = await products.countBy(p => p.category).toArray();
     * console.log(countByCategory);
     * // [
     * //   { key: 'Fruit', value: 2 },
     * //   { key: 'Vegetable', value: 1 }
     * // ]
     * ```
     */
    countBy<TKey>(keySelector: Selector<TElement, TKey>, comparator?: EqualityComparator<TKey>): IAsyncEnumerable<KeyValuePair<TKey, number>>;
    /**
     * Calculates the covariance between this async sequence and {@link iterable}.
     * @template TSecond Type of elements produced by {@link iterable}.
     * @param iterable Async sequence whose elements align by index with the source sequence.
     * @param selector Optional projection that extracts the numeric value for each element in the source sequence. Defaults to treating the element itself as numeric.
     * @param otherSelector Optional projection that extracts the numeric value for each element in {@link iterable}. Defaults to treating the element itself as numeric.
     * @param sample When `true`, computes the sample covariance dividing by _n - 1_; when `false`, computes the population covariance dividing by _n_. Defaults to `true`.
     * @returns {Promise<number>} A promise that resolves to the calculated covariance.
     * @throws {DimensionMismatchException} Thrown when the sequences do not contain the same number of elements.
     * @throws {InsufficientElementException} Thrown when fewer than two aligned pairs are available.
     * @throws {unknown} Re-throws any error thrown while iterating either sequence or executing the selector projections.
     * @remarks Both sequences are consumed simultaneously so that streaming statistics can be computed without materialising all elements. Align the sequences carefully, as mismatch detection occurs only after enumeration begins.
     * @example
     * ```typescript
     * const numbers = fromAsync([1, 2, 3, 4, 5]);
     * const doubles = fromAsync([2, 4, 6, 8, 10]);
     * const covariance = await numbers.covariance(doubles);
     * console.log(covariance); // 5
     * ```
     */
    covariance<TSecond>(iterable: AsyncIterable<TSecond>, selector?: Selector<TElement, number>, otherSelector?: Selector<TSecond, number>, sample?: boolean): Promise<number>;
    /**
     * Calculates the covariance between two numeric projections of the async sequence.
     * @param leftSelector Projection that produces the first numeric series for each element.
     * @param rightSelector Projection that produces the second numeric series for each element.
     * @param sample When `true`, computes the sample covariance dividing by _n - 1_; when `false`, computes the population covariance dividing by _n_. Defaults to `true`.
     * @returns {Promise<number>} A promise that resolves to the calculated covariance.
     * @throws {InsufficientElementException} Thrown when fewer than two elements are available.
     * @throws {unknown} Re-throws any error thrown while iterating the sequence or executing the selector projections.
     * @remarks The sequence is consumed exactly once using an online algorithm that avoids buffering, making it suitable for large datasets.
     * @example
     * ```typescript
     * const pairs = fromAsync([
     *   { x: 1, y: 2 },
     *   { x: 2, y: 4 },
     *   { x: 3, y: 6 }
     * ]);
     * const covariance = await pairs.covarianceBy(p => p.x, p => p.y);
     * console.log(covariance); // 2
     * ```
     */
    covarianceBy(leftSelector: Selector<TElement, number>, rightSelector: Selector<TElement, number>, sample?: boolean): Promise<number>;
    /**
     * Repeats the async sequence the specified number of times, or indefinitely when no count is provided.
     * @param count Optional number of times to repeat the sequence. When omitted, the sequence repeats without end.
     * @returns {IAsyncEnumerable<TElement>} An async sequence that yields the original elements cyclically.
     * @throws {NoElementsException} Thrown when the sequence is empty.
     * @remarks When `count` is `undefined`, consume the result with care because it represents an infinite sequence.
     * @example
     * ```typescript
     * const numbers = fromAsync([1, 2, 3]);
     * const cycled = await numbers.cycle(2).toArray();
     * console.log(cycled); // [1, 2, 3, 1, 2, 3]
     * ```
     */
    cycle(count?: number): IAsyncEnumerable<TElement>;
    /**
     * Supplies fallback content when the async sequence contains no elements.
     * @param defaultValue Optional value returned in a singleton sequence when the source is empty. Defaults to `null`.
     * @returns {IAsyncEnumerable<TElement | null>} The original sequence when it has elements; otherwise, a singleton sequence containing the provided value.
     * @remarks Use this to guarantee that downstream async operators receive at least one element.
     * @example
     * ```typescript
     * const empty = fromAsync([]);
     * const withDefault = await empty.defaultIfEmpty(0).toArray();
     * console.log(withDefault); // [0]
     *
     * const numbers = fromAsync([1, 2, 3]);
     * const withDefault2 = await numbers.defaultIfEmpty(0).toArray();
     * console.log(withDefault2); // [1, 2, 3]
     * ```
     */
    defaultIfEmpty(defaultValue?: TElement | null): IAsyncEnumerable<TElement | null>;
    /**
     * Determines whether the async sequence and {@link iterable} share no equivalent elements.
     * @template TSecond Type of elements yielded by {@link iterable}.
     * @param iterable Async sequence compared against the source.
     * @param comparator Optional equality comparator used to match elements across both sequences. Defaults to the library's standard equality comparison.
     * @returns {Promise<boolean>} A promise that resolves to `true` when the sequences are disjoint; otherwise, `false`.
     * @throws {unknown} Re-throws any error encountered while asynchronously iterating the source, {@link iterable}, or executing the comparator.
     * @remarks When the default comparator is used, the method buffers the source elements in a {@link Set} so it can short-circuit as soon as a shared element is detected.
     * When a custom comparator is supplied, both sequences are materialised to avoid repeated enumeration.
     * @example
     * ```typescript
     * const first = fromAsync([1, 2, 3]);
     * const second = fromAsync([4, 5, 6]);
     * const areDisjoint = await first.disjoint(second);
     * console.log(areDisjoint); // true
     * ```
     */
    disjoint<TSecond>(iterable: AsyncIterable<TSecond>, comparator?: EqualityComparator<TElement | TSecond>): Promise<boolean>;
    /**
     * Determines whether the key projections of the async sequence and {@link iterable} are mutually exclusive.
     * @template TSecond Type of elements yielded by {@link iterable}.
     * @template TKey Key type produced by {@link keySelector}.
     * @template TSecondKey Key type produced by {@link otherKeySelector}.
     * @param iterable Async sequence compared against the source.
     * @param keySelector Projection that produces the key evaluated for each source element.
     * @param otherKeySelector Projection that produces the key evaluated for each element of {@link iterable}.
     * @param keyComparator Optional equality comparator applied to projected keys. Defaults to the library's standard equality comparison.
     * @returns {Promise<boolean>} A promise that resolves to `true` when no projected keys intersect; otherwise, `false`.
     * @throws {unknown} Re-throws any error encountered while iterating either sequence or executing the selector projections/comparator.
     * @remarks When the default comparator is used, the method buffers the larger key collection in a {@link Set} and short-circuits as soon as an intersecting key is found.
     * Supplying a custom comparator materialises both key collections and compares each pair, so prefer the default when suitable.
     * @example
     * ```typescript
     * const left = fromAsync([{ name: 'Alice' }, { name: 'Bella' }]);
     * const right = fromAsync([{ name: 'Mel' }]);
     * const areDisjoint = await left.disjointBy(right, p => p.name, p => p.name);
     * console.log(areDisjoint); // true
     * ```
     */
    disjointBy<TSecond, TKey, TSecondKey>(iterable: AsyncIterable<TSecond>, keySelector: Selector<TElement, TKey>, otherKeySelector: Selector<TSecond, TSecondKey>, keyComparator?: EqualityComparator<TKey | TSecondKey>): Promise<boolean>;
    /**
     * Eliminates duplicate elements from the async sequence using an optional comparator.
     * @param keyComparator Optional equality comparator used to determine whether two elements are identical. Defaults to the library's standard equality comparison.
     * @returns {IAsyncEnumerable<TElement>} An async sequence that yields each distinct element once.
     * @remarks Elements are compared by value; when using custom types, provide an appropriate comparator to avoid reference-based comparisons.
     * @example
     * ```typescript
     * const numbers = fromAsync([1, 2, 2, 3, 1, 4, 5, 5]);
     * const distinctNumbers = await numbers.distinct().toArray();
     * console.log(distinctNumbers); // [1, 2, 3, 4, 5]
     * ```
     */
    distinct(keyComparator?: EqualityComparator<TElement>): IAsyncEnumerable<TElement>;
    /**
     * Eliminates duplicate elements by comparing keys computed for each async element.
     * @template TKey Key type returned by `keySelector`.
     * @param keySelector Selector used to project each element to the key used for distinctness.
     * @param keyComparator Optional equality comparator used to compare keys. Defaults to the library's standard equality comparison.
     * @returns {IAsyncEnumerable<TElement>} An async sequence that contains the first occurrence of each unique key.
     * @remarks Each element's key is evaluated exactly once; cache expensive key computations when possible.
     * @example
     * ```typescript
     * const products = fromAsync([
     *   { name: 'Apple', category: 'Fruit' },
     *   { name: 'Banana', category: 'Fruit' },
     *   { name: 'Carrot', category: 'Vegetable' },
     * ]);
     *
     * const distinctByCategory = await products.distinctBy(p => p.category).toArray();
     * console.log(distinctByCategory);
     * // [
     * //   { name: 'Apple', category: 'Fruit' },
     * //   { name: 'Carrot', category: 'Vegetable' }
     * // ]
     * ```
     */
    distinctBy<TKey>(keySelector: Selector<TElement, TKey>, keyComparator?: EqualityComparator<TKey>): IAsyncEnumerable<TElement>;
    /**
     * Removes consecutive duplicate elements by comparing each yielded value with its predecessor.
     * @param comparator Optional equality comparator used to determine whether adjacent elements are equal. Defaults to the library's standard equality comparison.
     * @returns {IAsyncEnumerable<TElement>} An async sequence that yields the first element of each run of equal values.
     * @remarks Unlike {@link distinct}, this only filters adjacent duplicates and preserves earlier occurrences of repeated values.
     * @example
     * ```typescript
     * const numbers = fromAsync([1, 1, 2, 2, 2, 1, 3, 3]);
     * const distinctUntilChangedNumbers = await numbers.distinctUntilChanged().toArray();
     * console.log(distinctUntilChangedNumbers); // [1, 2, 1, 3]
     * ```
     */
    distinctUntilChanged(comparator?: EqualityComparator<TElement>): IAsyncEnumerable<TElement>;
    /**
     * Removes consecutive duplicate elements by comparing keys projected from each element.
     * @template TKey Key type returned by `keySelector`.
     * @param keySelector Selector used to project each element to the key used for comparison.
     * @param keyComparator Optional equality comparator used to compare keys. Defaults to the library's standard equality comparison.
     * @returns {IAsyncEnumerable<TElement>} An async sequence that yields the first element in each run of elements whose keys change.
     * @remarks Enumeration stops comparing elements once a different key is encountered, making this useful for collapsing grouped async data.
     * @example
     * ```typescript
     * const products = fromAsync([
     *   { name: 'Apple', category: 'Fruit' },
     *   { name: 'Banana', category: 'Fruit' },
     *   { name: 'Carrot', category: 'Vegetable' },
     *   { name: 'Broccoli', category: 'Vegetable' },
     *   { name: 'Orange', category: 'Fruit' },
     * ]);
     *
     * const distinctByCategory = await products.distinctUntilChangedBy(p => p.category).toArray();
     * console.log(distinctByCategory);
     * // [
     * //   { name: 'Apple', category: 'Fruit' },
     * //   { name: 'Carrot', category: 'Vegetable' },
     * //   { name: 'Orange', category: 'Fruit' }
     * // ]
     * ```
     */
    distinctUntilChangedBy<TKey>(keySelector: Selector<TElement, TKey>, keyComparator?: EqualityComparator<TKey>): IAsyncEnumerable<TElement>;
    /**
     * Asynchronously retrieves the element at the specified zero-based index.
     * @param index Zero-based position of the element to retrieve.
     * @returns {Promise<TElement>} A promise that resolves to the element located at the requested index.
     * @throws {IndexOutOfBoundsException} Thrown when `index` is negative or greater than or equal to the number of elements in the sequence.
     * @throws {NoSuchElementException} Thrown when the sequence terminates unexpectedly before yielding the requested element.
     * @remarks Enumeration stops once the requested element is found; remaining elements are not evaluated.
     * @example
     * ```typescript
     * const numbers = fromAsync([1, 2, 3, 4, 5]);
     * const element = await numbers.elementAt(2);
     * console.log(element); // 3
     * ```
     */
    elementAt(index: number): Promise<TElement>;
    /**
     * Asynchronously retrieves the element at the specified zero-based index or resolves to `null` when the index is out of range.
     * @param index Zero-based position of the element to retrieve.
     * @returns {Promise<TElement | null>} A promise that resolves to the element at `index`, or `null` when the sequence is shorter than `index + 1` or when `index` is negative.
     * @remarks Use this overload when out-of-range access should produce a sentinel value instead of throwing an exception.
     * @example
     * ```typescript
     * const numbers = fromAsync([1, 2, 3, 4, 5]);
     * const element = await numbers.elementAtOrDefault(2);
     * console.log(element); // 3
     *
     * const element2 = await numbers.elementAtOrDefault(10);
     * console.log(element2); // null
     * ```
     */
    elementAtOrDefault(index: number): Promise<TElement | null>;
    /**
     * Determines whether the async sequence contains exactly {@link count} elements that satisfy the optional predicate.
     * @param count Exact number of matching elements required. Must be greater than or equal to 0.
     * @param predicate Optional predicate that determines which elements are counted. When omitted, every element is considered a match.
     * @returns {Promise<boolean>} `true` when exactly {@link count} matching elements are present; otherwise, `false`.
     * @throws {InvalidArgumentException} Thrown when {@link count} is negative.
     * @throws {unknown} Re-throws any error encountered while asynchronously iterating the sequence or executing the predicate.
     * @remarks Enumeration stops once the running total exceeds {@link count}, preventing unnecessary work.
     * @example
     * ```typescript
     * const numbers = fromAsync([1, 2, 3, 4, 5]);
     * const hasExactlyThreeOdds = await numbers.exactly(3, n => n % 2 !== 0);
     * console.log(hasExactlyThreeOdds); // true
     * ```
     */
    exactly(count: number, predicate?: Predicate<TElement>): Promise<boolean>;
    /**
     * Returns the elements of this async sequence that are not present in the specified async iterable.
     * @param enumerable Async sequence whose elements should be removed from the current sequence.
     * @param comparator Optional comparator used to determine element equality. Both equality and order comparators are supported; defaults to the library's standard equality comparison when omitted.
     * @returns {IAsyncEnumerable<TElement>} An async sequence containing the elements from this sequence that do not appear in `enumerable`.
     * @remarks The original ordering and duplicate occurrences from this sequence are preserved. The `enumerable` is fully enumerated to build the exclusion set.
     * @example
     * ```typescript
     * const numbers1 = fromAsync([1, 2, 3, 4, 5]);
     * const numbers2 = [3, 5, 7];
     * const result = await numbers1.except(numbers2).toArray();
     * console.log(result); // [1, 2, 4]
     * ```
     */
    except(enumerable: AsyncIterable<TElement>, comparator?: EqualityComparator<TElement> | OrderComparator<TElement>): IAsyncEnumerable<TElement>;
    /**
     * Returns the elements of this async sequence whose projected keys are not present in the specified async iterable.
     * @template TKey Type produced by `keySelector`.
     * @param enumerable Async sequence whose elements define the keys that should be excluded.
     * @param keySelector Selector used to project each element to the key used for comparison.
     * @param comparator Optional comparator used to compare keys. Both equality and order comparators are supported; defaults to the library's standard equality comparison when omitted.
     * @returns {IAsyncEnumerable<TElement>} An async sequence that contains the elements from this sequence whose keys are absent from `enumerable`.
     * @remarks Source ordering is preserved and duplicate elements with distinct keys remain. The exclusion keys are materialised by fully enumerating `enumerable`.
     * @example
     * ```typescript
     * const products1 = fromAsync([
     *   { name: 'Apple', category: 'Fruit' },
     *   { name: 'Banana', category: 'Fruit' },
     *   { name: 'Carrot', category: 'Vegetable' },
     * ]);
     * const products2 = [
     *   { name: 'Broccoli', category: 'Vegetable' },
     * ];
     *
     * const result = await products1.exceptBy(products2, p => p.category).toArray();
     * console.log(result);
     * // [
     * //   { name: 'Apple', category: 'Fruit' },
     * //   { name: 'Banana', category: 'Fruit' }
     * // ]
     * ```
     */
    exceptBy<TKey>(enumerable: AsyncIterable<TElement>, keySelector: Selector<TElement, TKey>, comparator?: EqualityComparator<TKey> | OrderComparator<TKey>): IAsyncEnumerable<TElement>;
    /**
     * Asynchronously returns the first element that satisfies the provided type guard.
     * @template TFiltered Subtype confirmed by the type guard.
     * @param predicate Type guard evaluated against each element until it returns true.
     * @returns {Promise<TFiltered>} A promise that resolves to the first element satisfying the type guard.
     * @throws {NoElementsException} Thrown when the sequence is empty.
     * @throws {NoMatchingElementException} Thrown when no element satisfies the type guard.
     * @remarks Enumeration stops immediately once a matching element is found.
     * @example
     * ```typescript
     * const numbers = fromAsync([1, 2, 3, 4, 5]);
     * const firstElement = await numbers.first();
     * console.log(firstElement); // 1
     *
     * const firstEven = await numbers.first(x => x % 2 === 0);
     * console.log(firstEven); // 2
     * ```
     */
    first<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): Promise<TFiltered>;
    /**
     * Asynchronously returns the first element in the sequence, optionally filtered by a predicate.
     * @param predicate Predicate evaluated against each element; when omitted, the first element is returned.
     * @returns {Promise<TElement>} A promise that resolves to the first element satisfying the predicate (or the very first element when none is provided).
     * @throws {NoElementsException} Thrown when the sequence is empty.
     * @throws {NoMatchingElementException} Thrown when a predicate is supplied and no element satisfies it.
     * @remarks Enumeration stops immediately once a matching element is found.
     */
    first(predicate?: Predicate<TElement>): Promise<TElement>;
    /**
     * Asynchronously returns the first element that satisfies the provided type guard, or `null` when no such element exists.
     * @template TFiltered Subtype confirmed by the type guard.
     * @param predicate Type guard evaluated against each element until it returns true.
     * @returns {Promise<TFiltered | null>} A promise that resolves to the first element satisfying the type guard, or `null` when none match.
     * @remarks Enumeration stops immediately once a matching element is found.
     * @example
     * ```typescript
     * const numbers = fromAsync([1, 2, 3, 4, 5]);
     * const firstElement = await numbers.firstOrDefault();
     * console.log(firstElement); // 1
     *
     * const firstEven = await numbers.firstOrDefault(x => x % 2 === 0);
     * console.log(firstEven); // 2
     *
     * const empty = fromAsync<number>([]);
     * const firstOfEmpty = await empty.firstOrDefault();
     * console.log(firstOfEmpty); // null
     *
     * const noEvens = fromAsync([1, 3, 5]);
     * const firstEven2 = await noEvens.firstOrDefault(x => x % 2 === 0);
     * console.log(firstEven2); // null
     * ```
     */
    firstOrDefault<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): Promise<TFiltered | null>;
    /**
     * Asynchronously returns the first element in the sequence or `null` when the sequence is empty or no element satisfies the predicate.
     * @param predicate Predicate evaluated against each element; when omitted, the first element is returned.
     * @returns {Promise<TElement | null>} A promise that resolves to the first matching element, or `null` when no match is found.
     * @remarks This method never rejects for missing elements; it communicates absence through the `null` result.
     */
    firstOrDefault(predicate?: Predicate<TElement>): Promise<TElement | null>;
    /**
     * Executes the provided callback for every element in the async sequence.
     * @param action Callback invoked for each element; receives the element and its zero-based index.
     * @returns {Promise<void>} A promise that resolves when iteration completes.
     * @remarks Enumeration starts immediately. Avoid mutating the underlying collection while iterating.
     * @example
     * ```typescript
     * const numbers = fromAsync([1, 2, 3]);
     * await numbers.forEach((x, i) => console.log(`Index ${i}: ${x}`));
     * // Index 0: 1
     * // Index 1: 2
     * // Index 2: 3
     * ```
     */
    forEach(action: IndexedAction<TElement>): Promise<void>;
    /**
     * Partitions the async sequence into groups based on keys projected from each element.
     * @template TKey Type of key produced by {@link keySelector}.
     * @param keySelector Selector used to derive the grouping key for each element.
     * @param keyComparator Optional equality comparator used to match keys. Defaults to the library's standard equality comparison.
     * @param hashSelector Optional hash selector. When provided, the sequence will use a bucketed approach for faster grouping based on the hash values.
     * @returns {IAsyncEnumerable<IGroup<TKey, TElement>>} An async sequence of groups, each exposing the key and the elements that share it.
     * @remarks The source sequence is enumerated once when the result is iterated. Elements within each group preserve their original order, and group contents are cached for repeated enumeration.
     * @example
     * ```typescript
     * const products = fromAsync([
     *   { name: 'Apple', category: 'Fruit' },
     *   { name: 'Banana', category: 'Fruit' },
     *   { name: 'Carrot', category: 'Vegetable' },
     * ]);
     *
     * const grouped = products.groupBy(p => p.category);
     * for await (const group of grouped) {
     *   console.log(group.key, group.toArray());
     * }
     * // Fruit [ { name: 'Apple', category: 'Fruit' }, { name: 'Banana', category: 'Fruit' } ]
     * // Vegetable [ { name: 'Carrot', category: 'Vegetable' } ]
     * ```
     */
    groupBy<TKey>(keySelector: Selector<TElement, TKey>, keyComparator?: EqualityComparator<TKey>, hashSelector?: Selector<TElement, PropertyKey>): IAsyncEnumerable<IGroup<TKey, TElement>>;
    /**
     * Correlates each element of the async sequence with a collection of matching elements from another async sequence.
     * @template TInner Type of elements in the inner sequence.
     * @template TKey Type of key produced by the key selectors.
     * @template TResult Type of element returned by {@link resultSelector}.
     * @param inner Async sequence whose elements are grouped and joined with the outer elements.
     * @param outerKeySelector Selector that extracts the join key from each outer element.
     * @param innerKeySelector Selector that extracts the join key from each inner element.
     * @param resultSelector Projection that combines an outer element with an `IEnumerable` of matching inner elements.
     * @param keyComparator Optional equality comparator used to match keys. Defaults to the library's standard equality comparison.
     * @returns {IAsyncEnumerable<TResult>} An async sequence produced by applying {@link resultSelector} to each outer element and its matching inner elements.
     * @remarks The inner sequence is enumerated once to build an in-memory lookup before outer elements are processed. Each outer element is then evaluated lazily and preserves the original outer ordering.
     * @example
     * ```typescript
     * const categories = fromAsync([
     *   { id: 1, name: 'Fruit' },
     *   { id: 2, name: 'Vegetable' },
     * ]);
     * const products = fromAsync([
     *   { name: 'Apple', categoryId: 1 },
     *   { name: 'Banana', categoryId: 1 },
     *   { name: 'Carrot', categoryId: 2 },
     * ]);
     *
     * const joined = await categories.groupJoin(
     *   products,
     *   c => c.id,
     *   p => p.categoryId,
     *   (c, ps) => ({ ...c, products: ps.toArray() })
     * ).toArray();
     *
     * console.log(joined);
     * // [
     * //   { id: 1, name: 'Fruit', products: [ { name: 'Apple', categoryId: 1 }, { name: 'Banana', categoryId: 1 } ] },
     * //   { id: 2, name: 'Vegetable', products: [ { name: 'Carrot', categoryId: 2 } ] }
     * // ]
     * ```
     */
    groupJoin<TInner, TKey, TResult>(inner: IAsyncEnumerable<TInner>, outerKeySelector: Selector<TElement, TKey>, innerKeySelector: Selector<TInner, TKey>, resultSelector: JoinSelector<TElement, IEnumerable<TInner>, TResult>, keyComparator?: EqualityComparator<TKey>): IAsyncEnumerable<TResult>;
    /**
     * Enumerates the async sequence while exposing the zero-based index alongside each element.
     * @returns {IAsyncEnumerable<[number, TElement]>} An async sequence of `[index, element]` tuples.
     * @remarks The index is assigned in the order elements are produced. Enumeration is deferred until the result is iterated.
     * @example
     * ```typescript
     * const letters = fromAsync(['a', 'b', 'c']);
     * const indexed = await letters.index().toArray();
     * console.log(indexed); // [[0, 'a'], [1, 'b'], [2, 'c']]
     * ```
     */
    index(): IAsyncEnumerable<[number, TElement]>;
    /**
     * Interleaves the async sequence with another iterable, yielding elements in alternating order.
     * @template TSecond Type of elements in the second iterable.
     * @param iterable Async iterable whose elements are alternated with the current sequence.
     * @returns {IAsyncEnumerable<TElement | TSecond>} An async sequence that alternates between elements from this sequence and `iterable`.
     * @remarks If one sequence is longer, the remaining elements are appended after the shorter sequence is exhausted. Enumeration is deferred.
     * @example
     * ```typescript
     * const numbers1 = fromAsync([1, 3, 5]);
     * const numbers2 = [2, 4, 6];
     * const interleaved = await numbers1.interleave(numbers2).toArray();
     * console.log(interleaved); // [1, 2, 3, 4, 5, 6]
     * ```
     */
    interleave<TSecond>(iterable: AsyncIterable<TSecond>): IAsyncEnumerable<TElement | TSecond>;
    /**
     * Returns the elements common to this async sequence and the specified iterable.
     * @param enumerable Async sequence whose elements are compared against the current sequence.
     * @param comparator Optional comparator used to determine element equality. Both equality and order comparators are supported; defaults to the library's standard equality comparison when omitted.
     * @returns {IAsyncEnumerable<TElement>} An async sequence containing the intersection of the two sequences.
     * @remarks The original ordering of this sequence is preserved. The `enumerable` is fully enumerated to build the inclusion set prior to yielding results.
     * @example
     * ```typescript
     * const numbers1 = fromAsync([1, 2, 3, 4, 5]);
     * const numbers2 = [3, 5, 7];
     * const result = await numbers1.intersect(numbers2).toArray();
     * console.log(result); // [3, 5]
     * ```
     */
    intersect(enumerable: AsyncIterable<TElement>, comparator?: EqualityComparator<TElement> | OrderComparator<TElement>): IAsyncEnumerable<TElement>;
    /**
     * Returns the elements whose keys are common to this async sequence and the specified iterable.
     * @template TKey Type of key produced by {@link keySelector}.
     * @param enumerable Async sequence whose elements define the keys considered part of the intersection.
     * @param keySelector Selector used to project each element to the key used for comparison.
     * @param comparator Optional comparator used to compare keys. Both equality and order comparators are supported; defaults to the library's standard equality comparison when omitted.
     * @returns {IAsyncEnumerable<TElement>} An async sequence containing the intersection of the two sequences based on matching keys.
     * @remarks The `enumerable` is fully enumerated to materialise the inclusion keys before yielding results. Source ordering is preserved.
     * @example
     * ```typescript
     * const products1 = fromAsync([
     *   { name: 'Apple', category: 'Fruit' },
     *   { name: 'Carrot', category: 'Vegetable' },
     * ]);
     * const products2 = [
     *   { name: 'Banana', category: 'Fruit' },
     *   { name: 'Broccoli', category: 'Vegetable' },
     * ];
     *
     * const result = await products1.intersectBy(products2, p => p.category).toArray();
     * console.log(result);
     * // [
     * //   { name: 'Apple', category: 'Fruit' },
     * //   { name: 'Carrot', category: 'Vegetable' }
     * // ]
     * ```
     */
    intersectBy<TKey>(enumerable: AsyncIterable<TElement>, keySelector: Selector<TElement, TKey>, comparator?: EqualityComparator<TKey> | OrderComparator<TKey>): IAsyncEnumerable<TElement>;
    /**
     * Inserts the specified separator between adjoining elements.
     * @template TSeparator Type of separator to insert. Defaults to `TElement`.
     * @param separator Value inserted between consecutive elements.
     * @returns {IAsyncEnumerable<TElement | TSeparator>} An async sequence containing the original elements with separators interleaved.
     * @remarks No separator precedes the first element or follows the last element.
     * @example
     * ```typescript
     * const letters = fromAsync(['a', 'b', 'c']);
     * const interspersed = await letters.intersperse('-').toArray();
     * console.log(interspersed); // ['a', '-', 'b', '-', 'c']
     * ```
     */
    intersperse<TSeparator = TElement>(separator: TSeparator): IAsyncEnumerable<TElement | TSeparator>;
    /**
     * Produces a projection from the async sequence and a second async sequence by matching elements that share an identical join key.
     * @template TInner Type of elements in the inner sequence.
     * @template TKey Type of key produced by the key selectors.
     * @template TResult Type of element returned by {@link resultSelector}.
     * @param inner Async sequence whose elements are joined with the outer sequence.
     * @param outerKeySelector Selector that extracts the join key from each outer element.
     * @param innerKeySelector Selector that extracts the join key from each inner element.
     * @param resultSelector Projection that combines an outer element with a matching inner element.
     * @param keyComparator Optional equality comparator used to match keys. Defaults to the library's standard equality comparison when omitted.
     * @returns {IAsyncEnumerable<TResult>} An async sequence generated by applying {@link resultSelector} to each matching pair.
     * @remarks The inner sequence is fully enumerated to build an in-memory lookup before outer elements are processed. The outer sequence is then enumerated lazily and its original ordering is preserved. This is an inner join; unmatched outer or inner elements are not emitted.
     * @example
     * ```typescript
     * const categories = fromAsync([
     *   { id: 1, name: 'Fruit' },
     *   { id: 2, name: 'Vegetable' },
     * ]);
     * const products = fromAsync([
     *   { name: 'Apple', categoryId: 1 },
     *   { name: 'Banana', categoryId: 1 },
     *   { name: 'Carrot', categoryId: 2 },
     * ]);
     *
     * const joined = await categories.join(
     *   products,
     *   c => c.id,
     *   p => p.categoryId,
     *   (c, p) => ({ category: c.name, product: p.name })
     * ).toArray();
     *
     * console.log(joined);
     * // [
     * //   { category: 'Fruit', product: 'Apple' },
     * //   { category: 'Fruit', product: 'Banana' },
     * //   { category: 'Vegetable', product: 'Carrot' }
     * // ]
     * ```
     */
    join<TInner, TKey, TResult>(inner: IAsyncEnumerable<TInner>, outerKeySelector: Selector<TElement, TKey>, innerKeySelector: Selector<TInner, TKey>, resultSelector: JoinSelector<TElement, TInner, TResult>, keyComparator?: EqualityComparator<TKey>): IAsyncEnumerable<TResult>;
    /**
     * Asynchronously returns the last element that satisfies the provided type guard.
     * @template TFiltered Subtype confirmed by the type guard.
     * @param predicate Type guard evaluated against each element. Every matching element becomes a candidate, and the final match is returned.
     * @returns {Promise<TFiltered>} A promise that resolves to the last element that satisfies the type guard.
     * @throws {NoElementsException} Thrown when the sequence is empty.
     * @throws {NoMatchingElementException} Thrown when no element satisfies the type guard.
     * @remarks The entire sequence is enumerated to locate the final match.
     * @example
     * ```typescript
     * const numbers = fromAsync([1, 2, 3, 4, 5]);
     * const lastElement = await numbers.last();
     * console.log(lastElement); // 5
     *
     * const lastEven = await numbers.last(x => x % 2 === 0);
     * console.log(lastEven); // 4
     * ```
     */
    last<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): Promise<TFiltered>;
    /**
     * Asynchronously returns the last element in the sequence, optionally filtered by a predicate.
     * @param predicate Predicate evaluated against each element. When omitted, the last element of the sequence is returned.
     * @returns {Promise<TElement>} A promise that resolves to the last element that satisfies the predicate (or the final element when no predicate is supplied).
     * @throws {NoElementsException} Thrown when the sequence is empty.
     * @throws {NoMatchingElementException} Thrown when a predicate is supplied and no element satisfies it.
     * @remarks The entire sequence is enumerated to locate the final match.
     */
    last(predicate?: Predicate<TElement>): Promise<TElement>;
    /**
     * Asynchronously returns the last element that satisfies the provided type guard, or `null` when no such element exists.
     * @template TFiltered Subtype confirmed by the type guard.
     * @param predicate Type guard evaluated against each element. Every matching element becomes a candidate, and the final match is returned.
     * @returns {Promise<TFiltered | null>} A promise that resolves to the last element that satisfies the type guard, or `null` when none match.
     * @remarks The entire sequence is enumerated to locate the final match. This overload never rejects for missing elements; it communicates absence through the `null` result.
     * @example
     * ```typescript
     * const numbers = fromAsync([1, 2, 3, 4, 5]);
     * const lastElement = await numbers.lastOrDefault();
     * console.log(lastElement); // 5
     *
     * const lastEven = await numbers.lastOrDefault(x => x % 2 === 0);
     * console.log(lastEven); // 4
     *
     * const empty = fromAsync<number>([]);
     * const lastOfEmpty = await empty.lastOrDefault();
     * console.log(lastOfEmpty); // null
     *
     * const noEvens = fromAsync([1, 3, 5]);
     * const lastEven2 = await noEvens.lastOrDefault(x => x % 2 === 0);
     * console.log(lastEven2); // null
     * ```
     */
    lastOrDefault<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): Promise<TFiltered | null>;
    /**
     * Asynchronously returns the last element in the sequence or `null` when the sequence is empty or no element satisfies the predicate.
     * @param predicate Predicate evaluated against each element. When omitted, the last element of the sequence is returned.
     * @returns {Promise<TElement | null>} A promise that resolves to the last element that satisfies the predicate, or `null` when no match is found.
     * @remarks The entire sequence is enumerated to locate the final match. This overload never rejects for missing elements; it communicates absence through the `null` result.
     */
    lastOrDefault(predicate?: Predicate<TElement>): Promise<TElement | null>;
    /**
     * Produces a projection from the async sequence and a second async sequence by matching elements that share an identical join key. Outer elements with no match are included once with `null` as the inner value.
     * @template TInner Type of elements in the inner sequence.
     * @template TKey Type of key produced by the key selectors.
     * @template TResult Type of element returned by {@link resultSelector}.
     * @param inner Async sequence whose elements are joined with the outer sequence.
     * @param outerKeySelector Selector that extracts the join key from each outer element.
     * @param innerKeySelector Selector that extracts the join key from each inner element.
     * @param resultSelector Projection that combines an outer element with a matching inner element. When no match exists, `null` is supplied as the inner value.
     * @param keyComparator Optional equality comparator used to match keys. Defaults to the library's standard equality comparison when omitted.
     * @returns {IAsyncEnumerable<TResult>} An async sequence generated by applying {@link resultSelector} to each matching pair (and unmatched outer elements).
     * @remarks The inner sequence is fully enumerated to build an in-memory lookup before outer elements are processed. The outer sequence is then enumerated lazily and its original ordering is preserved. This is a left outer join.
     */
    leftJoin<TInner, TKey, TResult>(inner: IAsyncEnumerable<TInner>, outerKeySelector: Selector<TElement, TKey>, innerKeySelector: Selector<TInner, TKey>, resultSelector: JoinSelector<TElement, TInner, TResult>, keyComparator?: EqualityComparator<TKey>): IAsyncEnumerable<TResult>;
    /**
     * Asynchronously returns the largest numeric value produced for the elements in the sequence.
     * @param selector Optional projection that extracts the numeric value for each element. Defaults to the element itself.
     * @returns {Promise<number>} A promise that resolves to the maximum of the projected values.
     * @throws {NoElementsException} Thrown when the sequence is empty.
     * @remarks The entire sequence is enumerated exactly once. Provide a selector when the elements are not already numeric.
     * @example
     * ```typescript
     * const numbers = fromAsync([1, 5, 2, 4, 3]);
     * const maxNumber = await numbers.max();
     * console.log(maxNumber); // 5
     *
     * const people = fromAsync([
     *   { name: 'Alice', age: 25 },
     *   { name: 'Bob', age: 30 },
     *   { name: 'Charlie', age: 28 },
     * ]);
     * const maxAge = await people.max(p => p.age);
     * console.log(maxAge); // 30
     * ```
     */
    max(this: AsyncIterable<number>): Promise<number>;
    max(selector: Selector<TElement, number>): Promise<number>;
    /**
     * Asynchronously returns the element whose projected key is greatest according to the provided comparator.
     * @template TKey Type of key produced by {@link keySelector}.
     * @param keySelector Selector used to project each element to the key used for comparison.
     * @param comparator Optional order comparator used to compare keys. Defaults to the library's standard order comparison when omitted.
     * @returns {Promise<TElement>} A promise that resolves to the element whose key is maximal.
     * @throws {NoElementsException} Thrown when the sequence is empty.
     * @remarks When multiple elements share the maximal key, the first such element in the sequence is returned.
     * @example
     * ```typescript
     * const people = fromAsync([
     *   { name: 'Alice', age: 25 },
     *   { name: 'Bob', age: 30 },
     *   { name: 'Charlie', age: 28 },
     * ]);
     * const oldestPerson = await people.maxBy(p => p.age);
     * console.log(oldestPerson); // { name: 'Bob', age: 30 }
     * ```
     */
    maxBy<TKey>(keySelector: Selector<TElement, TKey>, comparator?: OrderComparator<TKey>): Promise<TElement>;
    /**
     * Asynchronously returns the smallest numeric value produced for the elements in the sequence.
     * @param selector Optional projection that extracts the numeric value for each element. Defaults to the element itself.
     * @returns {Promise<number>} A promise that resolves to the minimum of the projected values.
     * @throws {NoElementsException} Thrown when the sequence is empty.
     * @remarks The entire sequence is enumerated exactly once. Provide a selector when the elements are not already numeric.
     * @example
     * ```typescript
     * const numbers = fromAsync([3, 1, 5, 2, 4]);
     * const minNumber = await numbers.min();
     * console.log(minNumber); // 1
     *
     * const people = fromAsync([
     *   { name: 'Alice', age: 25 },
     *   { name: 'Bob', age: 30 },
     *   { name: 'Charlie', age: 22 },
     * ]);
     * const minAge = await people.min(p => p.age);
     * console.log(minAge); // 22
     * ```
     */
    min(this: AsyncIterable<number>): Promise<number>;
    min(selector: Selector<TElement, number>): Promise<number>;
    /**
     * Asynchronously returns the element whose projected key is smallest according to the provided comparator.
     * @template TKey Type of key produced by {@link keySelector}.
     * @param keySelector Selector used to project each element to the key used for comparison.
     * @param comparator Optional order comparator used to compare keys. Defaults to the library's standard order comparison when omitted.
     * @returns {Promise<TElement>} A promise that resolves to the element whose key is minimal.
     * @throws {NoElementsException} Thrown when the sequence is empty.
     * @remarks When multiple elements share the minimal key, the first such element in the sequence is returned.
     * @example
     * ```typescript
     * const people = fromAsync([
     *   { name: 'Alice', age: 25 },
     *   { name: 'Bob', age: 30 },
     *   { name: 'Charlie', age: 22 },
     * ]);
     * const youngestPerson = await people.minBy(p => p.age);
     * console.log(youngestPerson); // { name: 'Charlie', age: 22 }
     * ```
     */
    minBy<TKey>(keySelector: Selector<TElement, TKey>, comparator?: OrderComparator<TKey>): Promise<TElement>;
    /**
     * Calculates the median of the numeric values produced by the async sequence.
     * @param selector Optional projection that extracts the numeric value for each element. Defaults to treating the element itself as numeric.
     * @param tie Determines how the median is resolved when the sequence contains an even number of elements. Defaults to `"interpolate"`, which averages the two central values. Specify `"low"` or `"high"` to select the lower or higher neighbour respectively.
     * @returns {Promise<number>} A promise that resolves to the calculated median, or `NaN` when the sequence contains no elements.
     * @throws {unknown} Re-throws any error thrown while iterating the sequence or executing {@link selector}.
     * @remarks The sequence is fully consumed and buffered so a selection algorithm can locate the middle element(s) without fully sorting. Supply {@link selector} when the elements are not already numeric.
     * @example
     * ```typescript
     * const medianValue = await fromAsync([1, 5, 2, 4, 3]).median();
     * console.log(medianValue); // 3
     *
     * const people = fromAsync([
     *   { name: 'Alice', age: 23 },
     *   { name: 'Bella', age: 21 },
     *   { name: 'Mirei', age: 22 },
     *   { name: 'Hanna', age: 20 },
     *   { name: 'Noemi', age: 29 }
     * ]);
     * const medianAge = await people.median(p => p.age);
     * console.log(medianAge); // 22
     * ```
     */
    median(selector?: Selector<TElement, number>, tie?: MedianTieStrategy): Promise<number>;
    /**
     * Calculates a percentile of the numeric values produced by the async sequence.
     * @param percent Percentile expressed as a fraction between 0 and 1 where `0` corresponds to the minimum and `1` to the maximum.
     * @param selector Optional projection that extracts the numeric value for each element. Defaults to treating the element itself as numeric.
     * @param strategy Strategy that determines how fractional ranks are resolved. Defaults to `"linear"`, which interpolates between neighbouring values. Alternative strategies include `"nearest"`, `"low"`, `"high"`, and `"midpoint"`.
     * @returns {Promise<number>} A promise that resolves to the percentile value, or `NaN` when the sequence contains no elements.
     * @throws {unknown} Re-throws any error thrown while iterating the sequence or executing {@link selector}.
     * @remarks The sequence is fully consumed and buffered so the selection algorithm can determine the requested rank without fully sorting the data. When {@link percent} is outside `[0, 1]`, it is clamped to the bounds implied by {@link strategy}.
     * @example
     * ```typescript
     * const upperQuartile = await fromAsync([1, 2, 3, 4, 5]).percentile(0.75);
     * console.log(upperQuartile); // 4
     *
     * const responseTimes = fromAsync([
     *   { endpoint: '/users', duration: 120 },
     *   { endpoint: '/users', duration: 80 },
     *   { endpoint: '/users', duration: 200 }
     * ]);
     * const p95 = await responseTimes.percentile(0.95, r => r.duration, "nearest");
     * console.log(p95); // 200
     * ```
     */
    percentile(this: AsyncIterable<number>, percent: number, strategy?: PercentileStrategy): Promise<number>;
    percentile(percent: number, selector: Selector<TElement, number>, strategy?: PercentileStrategy): Promise<number>;
    /**
     * Asynchronously returns the element that appears most frequently in the sequence.
     * @template TKey Type of key produced by {@link keySelector}.
     * @param keySelector Optional selector that projects each element to the key used for frequency counting. Defaults to the element itself.
     * @returns {Promise<TElement>} A promise that resolves to the first element whose occurrence count matches the maximum frequency.
     * @throws {NoElementsException} Thrown when the sequence is empty.
     * @throws {unknown} Re-throws any error thrown while iterating the sequence or executing {@link keySelector}.
     * @remarks The entire sequence is consumed to build frequency counts before the mode is resolved. When multiple keys share the same frequency, the earliest corresponding element is returned.
     * @example
     * ```typescript
     * const winner = await fromAsync([1, 2, 2, 3]).mode();
     * console.log(winner); // 2
     * ```
     */
    mode<TKey>(keySelector?: Selector<TElement, TKey>): Promise<TElement>;
    /**
     * Asynchronously returns the element that appears most frequently in the sequence, or `null` when the sequence is empty.
     * @template TKey Type of key produced by {@link keySelector}.
     * @param keySelector Optional selector that projects each element to the key used for frequency counting. Defaults to the element itself.
     * @returns {Promise<TElement | null>} A promise that resolves to the first most frequent element, or `null` when the sequence contains no elements.
     * @throws {unknown} Re-throws any error thrown while iterating the sequence or executing {@link keySelector}.
     * @remarks Unlike {@link mode}, this overload communicates the absence of elements by resolving to `null`. When multiple keys share the maximum frequency, the element encountered first is returned.
     * @example
     * ```typescript
     * const winner = await fromAsync<number>([]).modeOrDefault();
     * console.log(winner); // null
     * ```
     */
    modeOrDefault<TKey>(keySelector?: Selector<TElement, TKey>): Promise<TElement | null>;
    /**
     * Produces the elements whose occurrence count is tied for the highest frequency in the async sequence.
     * @template TKey Type of key produced by {@link keySelector}.
     * @param keySelector Optional selector that projects each element to the key used for frequency counting. Defaults to the element itself.
     * @returns {IAsyncEnumerable<TElement>} An async sequence containing one representative element for each frequency mode.
     * @throws {unknown} Re-throws any error thrown while iterating the sequence or executing {@link keySelector}.
     * @remarks The result is deferred; enumerating it buffers the entire source to compute frequency counts before yielding results. When multiple elements share a key, only the first occurrence is emitted.
     * @example
     * ```typescript
     * const modes = await fromAsync([1, 2, 2, 3, 3]).multimode().toArray();
     * console.log(modes); // [2, 3]
     * ```
     */
    multimode<TKey>(keySelector?: Selector<TElement, TKey>): IAsyncEnumerable<TElement>;
    /**
     * Determines whether the async sequence contains no elements that satisfy the optional predicate.
     * @param predicate Optional predicate evaluated against each element. When omitted, the method resolves to `true` if the sequence is empty.
     * @returns {Promise<boolean>} A promise that resolves to `true` when no element satisfies the predicate (or when the sequence is empty and no predicate is provided); otherwise, `false`.
     * @remarks This is more efficient than negating `any` with a predicate because iteration stops as soon as a matching element is found.
     * @example
     * ```typescript
     * const numbers = fromAsync([1, 3, 5]);
     * const noEvens = await numbers.none(x => x % 2 === 0);
     * console.log(noEvens); // true
     *
     * const mixedNumbers = fromAsync([1, 2, 3, 5]);
     * const noEvens2 = await mixedNumbers.none(x => x % 2 === 0);
     * console.log(noEvens2); // false
     * ```
     */
    none(predicate?: Predicate<TElement>): Promise<boolean>;
    /**
     * Returns the elements that are of the specified type.
     * The type can be specified either as a constructor function or as a string.
     * @template TResult
     * @param type The type to filter the elements of the sequence with.
     * @returns {IEnumerable<TResult>} A new enumerable sequence whose elements are of the specified type.
     * @example
     * ```typescript
     * const mixed = fromAsync([1, 'two', 3, 'four', new Date()]);
     * const numbers = await mixed.ofType('number').toArray();
     * console.log(numbers); // [1, 3]
     *
     * const dates = await mixed.ofType(Date).toArray();
     * console.log(dates); // [Date object]
     * ```
     */
    ofType<TResult extends ObjectType>(type: TResult): IAsyncEnumerable<InferredType<TResult>>;
    /**
     * Sorts the elements of the async sequence in ascending order using the provided comparator.
     * @param comparator Optional order comparator used to compare elements. Defaults to the library's standard order comparison when omitted.
     * @returns {IOrderedAsyncEnumerable<TElement>} An ordered async sequence sorted ascending.
     * @remarks Sorting is deferred; the sequence is ordered only when iterated. Use `thenBy`/`thenByDescending` on the returned sequence to specify secondary keys.
     * @example
     * ```typescript
     * const numbers = fromAsync([3, 1, 5, 2, 4]);
     * const sorted = await numbers.order().toArray();
     * console.log(sorted); // [1, 2, 3, 4, 5]
     * ```
     */
    order(comparator?: OrderComparator<TElement>): IOrderedAsyncEnumerable<TElement>;
    /**
     * Sorts the elements of a sequence in ascending order by using a specified comparer.
     * @param keySelector The key selector function that will be used for selecting the key for an element.
     * @param comparator The comparator function that will be used for comparing two keys. If not specified, default order comparison will be used.
     * @example
     * ```typescript
     * const people = fromAsync([
     *   { name: 'Bob', age: 30 },
     *   { name: 'Alice', age: 25 },
     *   { name: 'Charlie', age: 22 },
     * ]);
     * const sorted = await people.orderBy(p => p.age).toArray();
     * console.log(sorted);
     * // [
     * //   { name: 'Charlie', age: 22 },
     * //   { name: 'Alice', age: 25 },
     * //   { name: 'Bob', age: 30 }
     * // ]
     * ```
     */
    orderBy<TKey>(keySelector: Selector<TElement, TKey>, comparator?: OrderComparator<TKey>): IOrderedAsyncEnumerable<TElement>;
    /**
     * Sorts the elements of a sequence in descending order by using a specified comparer.
     * @param keySelector The key selector function that will be used for selecting the key for an element.
     * @param comparator The comparator function that will be used for comparing two keys. If not specified, default order comparison will be used.
     * @example
     * ```typescript
     * const people = fromAsync([
     *   { name: 'Charlie', age: 22 },
     *   { name: 'Alice', age: 25 },
     *   { name: 'Bob', age: 30 },
     * ]);
     * const sorted = await people.orderByDescending(p => p.age).toArray();
     * console.log(sorted);
     * // [
     * //   { name: 'Bob', age: 30 },
     * //   { name: 'Alice', age: 25 },
     * //   { name: 'Charlie', age: 22 }
     * // ]
     * ```
     */
    orderByDescending<TKey>(keySelector: Selector<TElement, TKey>, comparator?: OrderComparator<TKey>): IOrderedAsyncEnumerable<TElement>;
    /**
     * Sorts the elements of the async sequence in descending order using the provided comparator.
     * @param comparator Optional order comparator used to compare elements. Defaults to the library's standard order comparison when omitted.
     * @returns {IOrderedAsyncEnumerable<TElement>} An ordered async sequence sorted descending.
     * @remarks Sorting is deferred; the sequence is ordered only when iterated. Use `thenBy`/`thenByDescending` on the returned sequence to specify secondary keys.
     * @example
     * ```typescript
     * const numbers = fromAsync([3, 1, 5, 2, 4]);
     * const sorted = await numbers.orderDescending().toArray();
     * console.log(sorted); // [5, 4, 3, 2, 1]
     * ```
     */
    orderDescending(comparator?: OrderComparator<TElement>): IOrderedAsyncEnumerable<TElement>;
    /**
     * Creates a deferred asynchronous sequence of adjacent element pairs.
     * @param resultSelector Projection applied to each current/next pair; the value it returns becomes the emitted element.
     * @returns {IAsyncEnumerable<[TElement, TElement]>} An async sequence with one element per consecutive pair from the source sequence.
     * @remarks The final element is omitted because it lacks a successor. Iteration is lazy and consumes the source sequence exactly once via its async iterator.
     * @example
     * ```typescript
     * const numbers = fromAsync([1, 2, 3, 4]);
     * const pairs = await numbers.pairwise(p => p).toArray();
     * console.log(pairs); // [[1, 2], [2, 3], [3, 4]]
     * ```
     */
    pairwise(resultSelector: PairwiseSelector<TElement, TElement>): IAsyncEnumerable<[TElement, TElement]>;
    /**
     * Splits the asynchronous sequence into two cached partitions by applying a type guard predicate.
     * @template TFiltered Type produced when {@link predicate} confirms the element.
     * @param predicate Type guard invoked for each element. Elements that satisfy the predicate populate the first partition.
     * @returns {Promise<[IEnumerable<TFiltered>, IEnumerable<Exclude<TElement, TFiltered>>]>} A promise that resolves to the matching partition and the partition with the remaining elements.
     * @remarks The entire source is consumed asynchronously and buffered before the promise resolves, allowing both partitions to be iterated multiple times without replaying the source.
     * @example
     * ```typescript
     * const numbers = fromAsync([1, 2, 3, 4, 5, 6]);
     * const [evens, odds] = await numbers.partition(x => x % 2 === 0);
     * console.log(evens.toArray()); // [2, 4, 6]
     * console.log(odds.toArray()); // [1, 3, 5]
     * ```
     */
    partition<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): Promise<[IEnumerable<TFiltered>, IEnumerable<Exclude<TElement, TFiltered>>]>;
    /**
     * Splits the asynchronous sequence into two cached partitions by applying a boolean predicate.
     * @param predicate Predicate evaluated for each element. Elements for which it returns `true` populate the first partition.
     * @returns {Promise<[IEnumerable<TElement>, IEnumerable<TElement>]>} A promise that resolves to the elements that satisfied the predicate and those that did not.
     * @remarks The entire source is consumed asynchronously and buffered before the promise resolves, allowing both partitions to be iterated multiple times without replaying the source.
     */
    partition(predicate: Predicate<TElement>): Promise<[IEnumerable<TElement>, IEnumerable<TElement>]>;
    /**
     * Generates permutations from the distinct elements of the asynchronous sequence.
     * @param size Optional target length for each permutation. When omitted, permutations use all distinct elements of the source.
     * @returns {IAsyncEnumerable<IEnumerable<TElement>>} A lazy async sequence of permutations, each materialised as an enumerable.
     * @throws {InvalidArgumentException} Thrown when {@link size} is less than 1 or greater than the number of distinct elements.
     * @remarks The source is fully enumerated to collect distinct elements before permutations are produced. Expect combinatorial growth in the number of permutations.
     * @example
     * ```typescript
     * const numbers = fromAsync([1, 2, 3]);
     * const perms = numbers.permutations(2);
     * const result = await perms.select(p => p.toArray()).toArray();
     * console.log(result); // [[1, 2], [1, 3], [2, 1], [2, 3], [3, 1], [3, 2]]
     * ```
     */
    permutations(size?: number): IAsyncEnumerable<IEnumerable<TElement>>;
    /**
     * Applies a user-defined asynchronous pipeline to this sequence and resolves with the operator's result.
     * @template TResult Result type produced by {@link operator}.
     * @param operator Function that receives the async enumerable view of this sequence and returns a promise or value.
     * @returns {Promise<TResult>} A promise that resolves to the value produced by {@link operator} after it consumes the sequence as needed.
     * @throws {unknown} Re-throws any error thrown by {@link operator} or surfaced while asynchronously enumerating the sequence.
     * @remarks The operator determines when and how the sequence is consumed, enabling custom asynchronous workflows and integrations while preserving fluent syntax.
     * @example
     * ```typescript
     * const numbers = fromAsync([1, 2, 3, 4, 5]);
     * const sum = await numbers.pipe(async e => e.sum());
     * console.log(sum); // 15
     *
     * const filteredAndDoubled = await numbers.pipe(async e =>
     *   e.where(x => x % 2 === 0).select(x => x * 2).toArray()
     * );
     * console.log(filteredAndDoubled); // [4, 8]
     * ```
     */
    pipe<TResult>(operator: AsyncPipeOperator<TElement, TResult>): Promise<TResult>;
    /**
     * Returns a deferred asynchronous sequence that yields the supplied element before the source sequence.
     * @param element Element emitted before the original sequence.
     * @returns {IAsyncEnumerable<TElement>} An async sequence that yields {@link element} followed by the source elements.
     * @remarks Enumeration is deferred; the source is not iterated until the resulting sequence is consumed.
     * @example
     * ```typescript
     * const numbers = fromAsync([1, 2, 3]);
     * const prepended = await numbers.prepend(0).toArray();
     * console.log(prepended); // [0, 1, 2, 3]
     * ```
     */
    prepend(element: TElement): IAsyncEnumerable<TElement>;
    /**
     * Computes the multiplicative aggregate of the values produced for each element in the asynchronous sequence.
     * @param selector Optional projection that extracts the numeric value for each element. Defaults to interpreting the element itself as a number.
     * @returns {Promise<number>} A promise that resolves to the product of all projected values.
     * @throws {NoElementsException} Thrown when the sequence is empty.
     * @remarks The source is consumed exactly once. Supply {@link selector} when elements are not already numeric.
     * @example
     * ```typescript
     * const numbers = fromAsync([1, 2, 3, 4, 5]);
     * const result = await numbers.product();
     * console.log(result); // 120
     *
     * const people = fromAsync([
     *   { name: 'Alice', age: 25 },
     *   { name: 'Bob', age: 30 },
     * ]);
     * const ageProduct = await people.product(p => p.age);
     * console.log(ageProduct); // 750
     * ```
     */
    product(this: AsyncIterable<number>): Promise<number>;
    product(selector: Selector<TElement, number>): Promise<number>;
    /**
     * Returns a deferred asynchronous sequence that yields the source elements in reverse order.
     * @returns {IAsyncEnumerable<TElement>} An async sequence that produces the elements of the source in reverse iteration order.
     * @remarks The implementation materialises the entire sequence into an array before emitting elements, so avoid using it on infinite sequences or when memory usage is a concern.
     * @example
     * ```typescript
     * const numbers = fromAsync([1, 2, 3, 4, 5]);
     * const reversed = await numbers.reverse().toArray();
     * console.log(reversed); // [5, 4, 3, 2, 1]
     * ```
     */
    reverse(): IAsyncEnumerable<TElement>;
    /**
     * Produces a projection from the async sequence and a second async sequence by matching elements that share an identical join key. Inner elements with no match are included once with `null` as the outer value.
     * @template TInner Type of elements in the inner sequence.
     * @template TKey Type of key produced by the key selectors.
     * @template TResult Type of element returned by {@link resultSelector}.
     * @param inner Async sequence whose elements are joined with the outer sequence.
     * @param outerKeySelector Selector that extracts the join key from each outer element.
     * @param innerKeySelector Selector that extracts the join key from each inner element.
     * @param resultSelector Projection that combines an outer element with a matching inner element. When no match exists, `null` is supplied as the outer value.
     * @param keyComparator Optional equality comparator used to match keys. Defaults to the library's standard equality comparison when omitted.
     * @returns {IAsyncEnumerable<TResult>} An async sequence generated by applying {@link resultSelector} to each matching pair (and unmatched inner elements).
     * @remarks The outer sequence is fully enumerated to build an in-memory lookup before inner elements are processed. The inner sequence is then enumerated lazily and its original ordering is preserved. This is a right outer join.
     */
    rightJoin<TInner, TKey, TResult>(inner: IAsyncEnumerable<TInner>, outerKeySelector: Selector<TElement, TKey>, innerKeySelector: Selector<TInner, TKey>, resultSelector: JoinSelector<TElement | null, TInner, TResult>, keyComparator?: EqualityComparator<TKey>): IAsyncEnumerable<TResult>;
    /**
     * Returns a deferred asynchronous sequence that rotates the elements by the specified offset while preserving length.
     * @param shift Number of positions to rotate. Positive values move elements toward the end (left rotation); negative values move them toward the beginning (right rotation).
     * @returns {IAsyncEnumerable<TElement>} An async sequence containing the same elements shifted by the requested amount.
     * @remarks The source is consumed asynchronously and buffered to honour the rotation. Rotation amounts larger than the sequence length are normalised by that length, which may require buffering the full sequence.
     * @example
     * ```typescript
     * const numbers = fromAsync([1, 2, 3, 4, 5]);
     * const rotated = await numbers.rotate(2).toArray();
     * console.log(rotated); // [3, 4, 5, 1, 2]
     *
     * const rotatedNegative = await numbers.rotate(-2).toArray();
     * console.log(rotatedNegative); // [4, 5, 1, 2, 3]
     * ```
     */
    rotate(shift: number): IAsyncEnumerable<TElement>;
    /**
     * Accumulates the asynchronous sequence and emits each intermediate result.
     * @template TAccumulate Accumulator type produced by {@link accumulator}; defaults to `TElement` when {@link seed} is omitted.
     * @param accumulator Function that merges the current accumulator value with the next element to produce the subsequent accumulator.
     * @param seed Optional initial accumulator. When omitted, the first element supplies the initial accumulator and is emitted as the first result.
     * @returns {IAsyncEnumerable<TAccumulate>} An async sequence containing every intermediate accumulator produced by {@link accumulator}.
     * @throws {NoElementsException} Thrown when the sequence is empty and {@link seed} is not provided.
     * @remarks The source is consumed asynchronously exactly once. Supplying {@link seed} prevents exceptions on empty sources but the seed itself is not emitted.
     * @example
     * ```typescript
     * const numbers = fromAsync([1, 2, 3, 4, 5]);
     * const runningTotal = await numbers.scan((acc, x) => acc + x).toArray();
     * console.log(runningTotal); // [1, 3, 6, 10, 15]
     * ```
     */
    scan(accumulator: Accumulator<TElement, TElement>): IAsyncEnumerable<TElement>;
    scan<TAccumulate>(accumulator: Accumulator<TElement, TAccumulate>, seed: TAccumulate): IAsyncEnumerable<TAccumulate>;
    /**
     * Transforms each element and its zero-based index into a new value.
     * @template TResult Result type produced by {@link selector}.
     * @param selector Projection invoked for each element together with its index.
     * @returns {IAsyncEnumerable<TResult>} An async sequence containing the values produced by {@link selector}.
     * @remarks Enumeration is deferred. The index argument increments sequentially starting at zero.
     * @example
     * ```typescript
     * const numbers = fromAsync([1, 2, 3, 4, 5]);
     * const squares = await numbers.select(x => x * x).toArray();
     * console.log(squares); // [1, 4, 9, 16, 25]
     * ```
     */
    select<TResult>(selector: IndexedSelector<TElement, TResult>): IAsyncEnumerable<TResult>;
    /**
     * Projects each element and index into an iterable and flattens the results into a single asynchronous sequence.
     * @template TResult Element type produced by the flattened iterables.
     * @param selector Projection that returns an iterable for each element and its index.
     * @returns {IAsyncEnumerable<TResult>} An async sequence containing the concatenated contents of the iterables produced by {@link selector}.
     * @remarks Each inner iterable is fully enumerated in order before the next source element is processed, preserving the relative ordering of results.
     * @example
     * ```typescript
     * const lists = fromAsync([[1, 2], [3, 4], [5]]);
     * const flattened = await lists.selectMany(x => x).toArray();
     * console.log(flattened); // [1, 2, 3, 4, 5]
     * ```
     */
    selectMany<TResult>(selector: IndexedSelector<TElement, Iterable<TResult>>): IAsyncEnumerable<TResult>;
    /**
     * Determines whether the asynchronous sequence and another async iterable contain equal elements in the same order.
     * @param enumerable Async iterable to compare against the source sequence.
     * @param comparator Optional equality comparator used to compare element pairs. Defaults to the library's standard equality comparator.
     * @returns {Promise<boolean>} A promise that resolves to `true` when both sequences have the same length and all corresponding elements are equal; otherwise, `false`.
     * @remarks Enumeration stops as soon as a mismatch or length difference is observed. Both sequences are fully enumerated only when they are equal.
     * @example
     * ```typescript
     * const numbers1 = fromAsync([1, 2, 3]);
     * const numbers2 = [1, 2, 3];
     * const numbers3 = [1, 2, 4];
     *
     * const areEqual1 = await numbers1.sequenceEqual(numbers2);
     * console.log(areEqual1); // true
     *
     * const areEqual2 = await numbers1.sequenceEqual(numbers3);
     * console.log(areEqual2); // false
     * ```
     */
    sequenceEqual(enumerable: AsyncIterable<TElement>, comparator?: EqualityComparator<TElement>): Promise<boolean>;
    /**
     * Returns a deferred asynchronous sequence whose elements appear in random order.
     * @returns {IAsyncEnumerable<TElement>} An async sequence containing the same elements as the source but shuffled.
     * @remarks The implementation materialises the entire sequence into an array before shuffling, making this unsuitable for infinite sequences.
     * @example
     * ```typescript
     * const numbers = fromAsync([1, 2, 3, 4, 5]);
     * const shuffled = await numbers.shuffle().toArray();
     * console.log(shuffled); // e.g., [3, 1, 5, 2, 4]
     * ```
     */
    shuffle(): IAsyncEnumerable<TElement>;
    /**
     * Returns the only element that satisfies the provided type guard predicate.
     * @template TFiltered extends TElement Narrowed element type produced when {@link predicate} returns `true`.
     * @param predicate Type guard evaluated for each element. The resolved element is narrowed to `TFiltered`.
     * @returns {Promise<TFiltered>} A promise that resolves to the single element satisfying {@link predicate}.
     * @throws {NoElementsException} Thrown when the sequence is empty.
     * @throws {NoMatchingElementException} Thrown when no element satisfies {@link predicate}.
     * @throws {MoreThanOneMatchingElementException} Thrown when more than one element satisfies {@link predicate}.
     * @remarks The source is fully enumerated asynchronously to ensure exactly one matching element exists.
     * @example
     * ```typescript
     * const numbers = fromAsync([5]);
     * const singleElement = await numbers.single();
     * console.log(singleElement); // 5
     *
     * const numbers2 = fromAsync([1, 2, 3, 4, 5]);
     * const singleEven = await numbers2.single(x => x > 4);
     * console.log(singleEven); // 5
     * ```
     */
    single<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): Promise<TFiltered>;
    /**
     * Returns the only element in the sequence or the only element that satisfies an optional predicate.
     * @param predicate Optional predicate evaluated for each element. When provided, the result must be the unique element for which it returns `true`.
     * @returns {Promise<TElement>} A promise that resolves to the single element in the sequence or the single element that satisfies {@link predicate}.
     * @throws {NoElementsException} Thrown when the sequence is empty.
     * @throws {MoreThanOneElementException} Thrown when more than one element exists and {@link predicate} is omitted.
     * @throws {NoMatchingElementException} Thrown when {@link predicate} is provided and no element satisfies it.
     * @throws {MoreThanOneMatchingElementException} Thrown when {@link predicate} is provided and more than one element satisfies it.
     * @remarks The source is fully enumerated asynchronously to validate uniqueness.
     */
    single(predicate?: Predicate<TElement>): Promise<TElement>;
    /**
     * Returns the only element that satisfies the provided type guard predicate, or `null` when no such element exists.
     * @template TFiltered extends TElement Narrowed element type produced when {@link predicate} returns `true`.
     * @param predicate Type guard evaluated for each element. The resolved element is narrowed to `TFiltered` when not `null`.
     * @returns {Promise<TFiltered | null>} A promise that resolves to the single matching element, or `null` when no element satisfies {@link predicate}.
     * @throws {MoreThanOneMatchingElementException} Thrown when more than one element satisfies {@link predicate}.
     * @remarks The source is fully enumerated asynchronously to confirm uniqueness of the matching element.
     * @example
     * ```typescript
     * const numbers = fromAsync([5]);
     * const singleElement = await numbers.singleOrDefault();
     * console.log(singleElement); // 5
     *
     * const numbers2 = fromAsync([1, 2, 3, 4, 5]);
     * const singleEven = await numbers2.singleOrDefault(x => x > 4);
     * console.log(singleEven); // 5
     *
     * const empty = fromAsync<number>([]);
     * const singleOfEmpty = await empty.singleOrDefault();
     * console.log(singleOfEmpty); // null
     *
     * const noMatch = fromAsync([1, 2, 3]);
     * const singleNoMatch = await noMatch.singleOrDefault(x => x > 4);
     * console.log(singleNoMatch); // null
     * ```
     */
    singleOrDefault<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): Promise<TFiltered | null>;
    /**
     * Returns the only element in the sequence or the only element that satisfies an optional predicate, or resolves to `null` when no such element exists.
     * @param predicate Optional predicate evaluated for each element. When provided, the result must be the unique element for which it returns `true`.
     * @returns {Promise<TElement | null>} A promise that resolves to the single element or matching element, or `null` when no element satisfies the conditions.
     * @throws {MoreThanOneElementException} Thrown when more than one element exists and {@link predicate} is omitted.
     * @throws {MoreThanOneMatchingElementException} Thrown when {@link predicate} is provided and more than one element satisfies it.
     * @remarks Unlike {@link single}, this method communicates the absence of a matching element by resolving to `null`.
     */
    singleOrDefault(predicate?: Predicate<TElement>): Promise<TElement | null>;
    /**
     * Skips a specified number of elements before yielding the remainder of the asynchronous sequence.
     * @param count Number of elements to bypass. Values less than or equal to zero result in no elements being skipped.
     * @returns {IAsyncEnumerable<TElement>} An async sequence containing the elements that remain after skipping {@link count} items.
     * @remarks Enumeration advances through the skipped prefix without yielding any of those elements.
     * @example
     * ```typescript
     * const numbers = fromAsync([1, 2, 3, 4, 5]);
     * const skipped = await numbers.skip(2).toArray();
     * console.log(skipped); // [3, 4, 5]
     * ```
     */
    skip(count: number): IAsyncEnumerable<TElement>;
    /**
     * Omits a specified number of elements from the end of the sequence.
     * @param count Number of trailing elements to exclude. Values less than or equal to zero leave the sequence unchanged.
     * @returns {IAsyncEnumerable<TElement>} An async sequence excluding the last {@link count} elements.
     * @remarks The implementation buffers up to {@link count} elements to determine which items to drop, which can increase memory usage for large counts.
     * @example
     * ```typescript
     * const numbers = fromAsync([1, 2, 3, 4, 5]);
     * const skipped = await numbers.skipLast(2).toArray();
     * console.log(skipped); // [1, 2, 3]
     * ```
     */
    skipLast(count: number): IAsyncEnumerable<TElement>;
    /**
     * Skips elements until a type guard predicate returns `true`, then yields that element and the remainder, narrowing the element type.
     * @template TFiltered extends TElement Result type produced when {@link predicate} returns `true`.
     * @param predicate Type guard invoked for each element and its zero-based index; once it returns `true`, that element and all following elements are yielded.
     * @returns {IAsyncEnumerable<TFiltered>} An async sequence starting with the first element that satisfies {@link predicate}.
     * @remarks The predicate's index parameter increments for each inspected element until the condition is met.
     * @example
     * ```typescript
     * const mixed: (number | string)[] = ['a', 'b', 1, 2];
     * const numbers = await fromAsync(mixed).skipUntil((x): x is number => typeof x === 'number').toArray();
     * console.log(numbers); // [1, 2]
     * ```
     */
    skipUntil<TFiltered extends TElement>(predicate: IndexedTypePredicate<TElement, TFiltered>): IAsyncEnumerable<TFiltered>;
    /**
     * Skips elements until a predicate returns `true`, then yields that element and the remainder.
     * @param predicate Predicate receiving the element and its zero-based index; once it returns `true`, enumeration stops skipping.
     * @returns {IAsyncEnumerable<TElement>} An async sequence starting with the first element that satisfies {@link predicate}.
     * @remarks The predicate runs until the first match is found; subsequent elements are yielded without further checks.
     * @example
     * ```typescript
     * const numbers = await fromAsync([0, 0, 1, 2, 3]).skipUntil(x => x >= 2).toArray();
     * console.log(numbers); // [2, 3]
     * ```
     */
    skipUntil(predicate: IndexedPredicate<TElement>): IAsyncEnumerable<TElement>;
    /**
     * Skips elements while a predicate returns `true` and then yields the remaining elements.
     * @param predicate Predicate receiving the element and its zero-based index. The first element for which it returns `false` is included in the result.
     * @returns {IAsyncEnumerable<TElement>} An async sequence starting with the first element that fails {@link predicate}.
     * @remarks The predicate's index parameter increments only while elements are being skipped.
     * @example
     * ```typescript
     * const numbers = fromAsync([1, 2, 3, 4, 5, 1, 2]);
     * const skipped = await numbers.skipWhile(x => x < 4).toArray();
     * console.log(skipped); // [4, 5, 1, 2]
     * ```
     */
    skipWhile(predicate: IndexedPredicate<TElement>): IAsyncEnumerable<TElement>;
    /**
     * Splits the sequence into the maximal leading span that satisfies a type guard and the remaining elements.
     * @template TFiltered extends TElement Narrowed element type produced when {@link predicate} returns `true`.
     * @param predicate Type guard evaluated for each element until it first returns `false`.
     * @returns {Promise<[IEnumerable<TFiltered>, IEnumerable<TElement>]>} A promise that resolves to the contiguous matching prefix and the remainder of the sequence.
     * @remarks The source is fully enumerated asynchronously and buffered so both partitions can be iterated repeatedly without re-evaluating {@link predicate}.
     * @example
     * ```typescript
     * const numbers = fromAsync([1, 2, 3, 4, 1, 2]);
     * const [first, second] = await numbers.span(x => x < 3);
     * console.log(first.toArray()); // [1, 2]
     * console.log(second.toArray()); // [3, 4, 1, 2]
     * ```
     */
    span<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): Promise<[IEnumerable<TFiltered>, IEnumerable<TElement>]>;
    /**
     * Splits the sequence into the maximal leading span that satisfies a predicate and the remaining elements.
     * @param predicate Predicate evaluated for each element until it first returns `false`.
     * @returns {Promise<[IEnumerable<TElement>, IEnumerable<TElement>]>} A promise that resolves to the contiguous matching prefix and the remainder of the sequence.
     * @remarks The source is fully enumerated asynchronously and buffered so both partitions can be iterated repeatedly without re-evaluating {@link predicate}.
     */
    span(predicate: Predicate<TElement>): Promise<[IEnumerable<TElement>, IEnumerable<TElement>]>;
    /**
     * Calculates the standard deviation of the numeric values produced by the async sequence.
     * @param selector Optional projection that extracts the numeric value for each element. Defaults to the element itself.
     * @param sample When `true`, computes the sample standard deviation; when `false`, computes the population standard deviation. Defaults to `true`.
     * @returns {Promise<number>} A promise that resolves to the calculated standard deviation, or `NaN` when there are insufficient values to compute it.
     * @throws {unknown} Re-throws any error thrown while iterating the sequence or executing {@link selector}.
     * @remarks This method delegates to {@link variance}; when the variance is `NaN`, that value is returned unchanged. The sequence is enumerated exactly once using a numerically stable single-pass algorithm.
     * @example
     * ```typescript
     * const populationStdDev = await fromAsync([1, 2, 3, 4, 5]).standardDeviation(x => x, false);
     * console.log(populationStdDev); // Math.sqrt(2)
     * ```
     */
    standardDeviation(selector?: Selector<TElement, number>, sample?: boolean): Promise<number>;
    /**
     * Returns every n-th element of the sequence, starting with the first.
     * @param step Positive interval indicating how many elements to skip between yielded items.
     * @returns {IAsyncEnumerable<TElement>} An async sequence containing elements whose zero-based index is divisible by {@link step}.
     * @throws {InvalidArgumentException} Thrown when {@link step} is less than 1.
     * @remarks The source is enumerated asynchronously exactly once; elements that are not yielded are still visited to honour the stepping interval.
     * @example
     * ```typescript
     * const numbers = fromAsync([1, 2, 3, 4, 5, 6, 7, 8, 9]);
     * const stepped = await numbers.step(3).toArray();
     * console.log(stepped); // [1, 4, 7]
     * ```
     */
    step(step: number): IAsyncEnumerable<TElement>;
    /**
     * Computes the sum of the numeric values produced for each element.
     * @param selector Optional projection that extracts the numeric value. Defaults to interpreting the element itself as a number.
     * @returns {Promise<number>} A promise that resolves to the sum of the projected values.
     * @throws {NoElementsException} Thrown when the sequence is empty.
     * @remarks The source is enumerated asynchronously exactly once. Supply {@link selector} when elements are not already numeric.
     * @example
     * ```typescript
     * const numbers = fromAsync([1, 2, 3, 4, 5]);
     * const total = await numbers.sum();
     * console.log(total); // 15
     *
     * const people = fromAsync([
     *   { name: 'Alice', age: 25 },
     *   { name: 'Bob', age: 30 },
     * ]);
     * const totalAge = await people.sum(p => p.age);
     * console.log(totalAge); // 55
     * ```
     */
    sum(this: AsyncIterable<number>): Promise<number>;
    sum(selector: Selector<TElement, number>): Promise<number>;
    /**
     * Returns up to the specified number of leading elements.
     * @param count Number of elements to emit; values less than or equal to zero produce an empty sequence.
     * @returns {IAsyncEnumerable<TElement>} A deferred async sequence containing at most {@link count} elements from the start of the source.
     * @remarks Enumeration stops once {@link count} elements have been yielded or the source sequence ends.
     * @example
     * ```typescript
     * const numbers = fromAsync([1, 2, 3, 4, 5]);
     * const firstTwo = await numbers.take(2).toArray();
     * console.log(firstTwo); // [1, 2]
     *
     * const emptyTake = await numbers.take(0).toArray();
     * console.log(emptyTake); // []
     * ```
     */
    take(count: number): IAsyncEnumerable<TElement>;
    /**
     * Returns up to the specified number of trailing elements.
     * @param count Number of elements to keep from the end; values less than or equal to zero produce an empty sequence.
     * @returns {IAsyncEnumerable<TElement>} A deferred async sequence containing at most {@link count} elements from the end of the source.
     * @remarks The implementation buffers up to {@link count} elements to determine the tail, so memory usage grows with {@link count}. The source must be finite.
     * @example
     * ```typescript
     * const numbers = fromAsync([1, 2, 3, 4, 5]);
     * const lastTwo = await numbers.takeLast(2).toArray();
     * console.log(lastTwo); // [4, 5]
     *
     * const emptyTakeLast = await numbers.takeLast(0).toArray();
     * console.log(emptyTakeLast); // []
     * ```
     */
    takeLast(count: number): IAsyncEnumerable<TElement>;
    /**
     * Returns consecutive leading elements until a type guard predicate returns `true`, then stops.
     * @template TFiltered extends TElement Result type produced when {@link predicate} returns `true`.
     * @param predicate Type guard invoked for each element and its zero-based index; iteration halts immediately when it returns `true`.
     * @returns {IAsyncEnumerable<TFiltered>} An async sequence containing the contiguous prefix produced before {@link predicate} succeeds.
     * @remarks Elements after the first element satisfying {@link predicate} are not inspected.
     * @example
     * ```typescript
     * const mixed: (number | string)[] = [1, 2, 'stop', 3];
     * const beforeStop = await fromAsync(mixed).takeUntil((x): x is string => typeof x === 'string').toArray();
     * console.log(beforeStop); // [1, 2]
     * ```
     */
    takeUntil<TFiltered extends TElement>(predicate: IndexedTypePredicate<TElement, TFiltered>): IAsyncEnumerable<TFiltered>;
    /**
     * Returns consecutive leading elements until a predicate returns `true`, then stops.
     * @param predicate Predicate invoked for each element and its zero-based index; iteration halts immediately when it returns `true`.
     * @returns {IAsyncEnumerable<TElement>} An async sequence containing the contiguous prefix produced before {@link predicate} succeeds.
     * @remarks Elements after the first element satisfying {@link predicate} are not inspected.
     * @example
     * ```typescript
     * const numbers = await fromAsync([1, 2, 3, 4, 5]).takeUntil(x => x > 3).toArray();
     * console.log(numbers); // [1, 2, 3]
     * ```
     */
    takeUntil(predicate: IndexedPredicate<TElement>): IAsyncEnumerable<TElement>;
    /**
     * Returns consecutive leading elements while a type guard predicate returns `true`, narrowing the element type.
     * @template TFiltered extends TElement Result type produced when {@link predicate} returns `true`.
     * @param predicate Type guard invoked for each element and its zero-based index; iteration stops immediately when it returns `false`.
     * @returns {IAsyncEnumerable<TFiltered>} A deferred async sequence containing the contiguous prefix that satisfies {@link predicate}.
     * @remarks Elements after the first failing element are not inspected.
     * @example
     * ```typescript
     * const mixed: (number | string)[] = [1, 2, 'three', 4, 5];
     * const numbers = await fromAsync(mixed).takeWhile((x): x is number => typeof x === 'number').toArray();
     * console.log(numbers); // [1, 2]
     * ```
     */
    takeWhile<TFiltered extends TElement>(predicate: IndexedTypePredicate<TElement, TFiltered>): IAsyncEnumerable<TFiltered>;
    /**
     * Returns consecutive leading elements while a predicate returns `true`.
     * @param predicate Predicate invoked for each element and its zero-based index; iteration stops immediately when it returns `false`.
     * @returns {IAsyncEnumerable<TElement>} A deferred async sequence containing the contiguous prefix that satisfies {@link predicate}.
     * @remarks Elements after the first failing element are not inspected.
     * @example
     * ```typescript
     * const numbers = fromAsync([1, 2, 3, 4, 5, 1, 2]);
     * const taken = await numbers.takeWhile(x => x < 4).toArray();
     * console.log(taken); // [1, 2, 3]
     *
     * const takenWithIndex = await numbers.takeWhile((x, i) => i < 3).toArray();
     * console.log(takenWithIndex); // [1, 2, 3]
     * ```
     */
    takeWhile(predicate: IndexedPredicate<TElement>): IAsyncEnumerable<TElement>;
    /**
     * Invokes the specified action for each element while yielding the original elements unchanged.
     * @param action Callback receiving the element and its zero-based index.
     * @returns {IAsyncEnumerable<TElement>} The original async sequence, enabling fluent chaining.
     * @remarks The action executes lazily as the sequence is iterated asynchronously, making it suitable for logging or instrumentation.
     * @example
     * ```typescript
     * const numbers = fromAsync([1, 2, 3]);
     * const tapped = await numbers
     *   .tap(x => console.log(`Processing: ${x}`))
     *   .select(x => x * 2)
     *   .toArray();
     * console.log(tapped); // [2, 4, 6]
     * // Expected console output:
     * // Processing: 1
     * // Processing: 2
     * // Processing: 3
     * ```
     */
    tap(action: IndexedAction<TElement>): IAsyncEnumerable<TElement>;
    /**
     * Materialises the asynchronous sequence into an array.
     * @returns {Promise<TElement[]>} A promise that resolves with all elements from the source sequence in iteration order.
     * @remarks The entire sequence is consumed asynchronously before the array is returned. Subsequent changes to the source are not reflected in the result.
     * @example
     * ```typescript
     * const numbers = fromAsync([1, 2, 3]);
     * const array = await numbers.toArray();
     * console.log(array); // [1, 2, 3]
     * ```
     */
    toArray(): Promise<TElement[]>;
    /**
     * Materialises the asynchronous sequence into a circular linked list.
     * @param comparator Optional equality comparator used by the resulting list.
     * @returns {Promise<CircularLinkedList<TElement>>} A promise that resolves to a circular linked list containing all elements from the source.
     * @remarks The entire sequence is consumed asynchronously before the list is created, and elements are stored in iteration order.
     * @example
     * ```typescript
     * const numbers = fromAsync([1, 2, 3]);
     * const circularList = await numbers.toCircularLinkedList();
     * console.log(circularList.toArray()); // [1, 2, 3]
     * ```
     */
    toCircularLinkedList(comparator?: EqualityComparator<TElement>): Promise<CircularLinkedList<TElement>>;
    /**
     * Materialises the asynchronous sequence into a circular queue that uses the implementation's default capacity.
     * @param comparator Optional equality comparator used by the resulting queue.
     * @returns {Promise<CircularQueue<TElement>>} A promise that resolves to a circular queue containing the most recent elements from the source, up to the default capacity.
     * @remarks The entire sequence is consumed asynchronously. Once the queue reaches its capacity (currently 32), older items are discarded as new elements are enqueued.
     * @example
     * ```typescript
     * const numbers = fromAsync([1, 2, 3]);
     * const circularQueue = await numbers.toCircularQueue();
     * console.log(circularQueue.toArray()); // [1, 2, 3]
     * ```
     */
    toCircularQueue(comparator?: EqualityComparator<TElement>): Promise<CircularQueue<TElement>>;
    /**
     * Materialises the asynchronous sequence into a circular queue with the specified capacity.
     * @param capacity Maximum number of elements retained by the resulting queue.
     * @param comparator Optional equality comparator used by the resulting queue.
     * @returns {Promise<CircularQueue<TElement>>} A promise that resolves to a circular queue containing the most recent elements from the source, bounded by {@link capacity}.
     * @remarks The entire sequence is consumed asynchronously. When the source contains more than {@link capacity} elements, earlier items are discarded.
     * @example
     * ```typescript
     * const numbers = fromAsync([1, 2, 3, 4, 5]);
     * const circularQueue = await numbers.toCircularQueue(3);
     * console.log(circularQueue.toArray()); // [3, 4, 5]
     * ```
     */
    toCircularQueue(capacity: number, comparator?: EqualityComparator<TElement>): Promise<CircularQueue<TElement>>;
    /**
     * Materialises the asynchronous sequence into a dictionary keyed by the provided selector.
     * @template TKey Type of key returned by {@link keySelector}.
     * @template TValue Type of value returned by {@link valueSelector}.
     * @param keySelector Selector used to derive the key for each element.
     * @param valueSelector Selector used to derive the value for each element.
     * @param valueComparator Optional equality comparator used by the resulting dictionary to compare values.
     * @returns {Promise<Dictionary<TKey, TValue>>} A promise that resolves to a dictionary populated with the projected key/value pairs.
     * @throws {InvalidArgumentException} Thrown when {@link keySelector} produces duplicate keys.
     * @remarks The entire sequence is consumed asynchronously before the dictionary is returned.
     * @example
     * ```typescript
     * const people = fromAsync([
     *   { id: 1, name: 'Alice' },
     *   { id: 2, name: 'Bob' },
     * ]);
     * const dictionary = await people.toDictionary(p => p.id, p => p.name);
     * console.log(dictionary.get(1)); // 'Alice'
     * console.log(dictionary.get(2)); // 'Bob'
     * ```
     */
    toDictionary<TKey, TValue>(keySelector: Selector<TElement, TKey>, valueSelector: Selector<TElement, TValue>, valueComparator?: EqualityComparator<TValue>): Promise<Dictionary<TKey, TValue>>;
    /**
     * Materialises the asynchronous sequence into an enumerable set containing the distinct elements.
     * @returns {Promise<EnumerableSet<TElement>>} A promise that resolves to a set populated with the distinct elements from the source.
     * @remarks The entire sequence is consumed asynchronously before the set is returned, and duplicate elements are collapsed using the set's equality semantics.
     * @example
     * ```typescript
     * const numbers = fromAsync([1, 2, 2, 3, 1]);
     * const set = await numbers.toEnumerableSet();
     * console.log(set.toArray()); // [1, 2, 3]
     * ```
     */
    toEnumerableSet(): Promise<EnumerableSet<TElement>>;
    /**
     * Materialises the asynchronous sequence into an immutable circular queue that uses the implementation's default capacity.
     * @param comparator Optional equality comparator used by the resulting queue.
     * @returns {Promise<ImmutableCircularQueue<TElement>>} A promise that resolves to an immutable circular queue containing the most recent elements from the source, up to the default capacity.
     * @remarks The entire sequence is consumed asynchronously. Earlier items are discarded when the number of elements exceeds the queue's capacity (currently 32).
     * @example
     * ```typescript
     * const numbers = fromAsync([1, 2, 3]);
     * const immutableCircularQueue = await numbers.toImmutableCircularQueue();
     * console.log(immutableCircularQueue.toArray()); // [1, 2, 3]
     * ```
     */
    toImmutableCircularQueue(comparator?: EqualityComparator<TElement>): Promise<ImmutableCircularQueue<TElement>>;
    /**
     * Materialises the asynchronous sequence into an immutable circular queue with the specified capacity.
     * @param capacity Maximum number of elements retained by the resulting queue.
     * @param comparator Optional equality comparator used by the resulting queue.
     * @returns {Promise<ImmutableCircularQueue<TElement>>} A promise that resolves to an immutable circular queue containing the most recent elements from the source, bounded by {@link capacity}.
     * @remarks The entire sequence is consumed asynchronously. When the source contains more than {@link capacity} elements, earlier items are discarded.
     * @example
     * ```typescript
     * const numbers = fromAsync([1, 2, 3, 4, 5]);
     * const immutableCircularQueue = await numbers.toImmutableCircularQueue(3);
     * console.log(immutableCircularQueue.toArray()); // [3, 4, 5]
     * ```
     */
    toImmutableCircularQueue(capacity: number, comparator?: EqualityComparator<TElement>): Promise<ImmutableCircularQueue<TElement>>;
    /**
     * Materialises the asynchronous sequence into an immutable dictionary keyed by the provided selector.
     * @template TKey Type of key returned by {@link keySelector}.
     * @template TValue Type of value returned by {@link valueSelector}.
     * @param keySelector Selector used to derive the key for each element.
     * @param valueSelector Selector used to derive the value for each element.
     * @param valueComparator Optional equality comparator used by the resulting dictionary to compare values.
     * @returns {Promise<ImmutableDictionary<TKey, TValue>>} A promise that resolves to an immutable dictionary populated with the projected key/value pairs.
     * @throws {InvalidArgumentException} Thrown when {@link keySelector} produces duplicate keys.
     * @remarks The entire sequence is consumed asynchronously before the dictionary is returned.
     * @example
     * ```typescript
     * const people = fromAsync([
     *   { id: 1, name: 'Alice' },
     *   { id: 2, name: 'Bob' },
     * ]);
     * const immutableDictionary = await people.toImmutableDictionary(p => p.id, p => p.name);
     * console.log(immutableDictionary.get(1)); // 'Alice'
     * console.log(immutableDictionary.get(2)); // 'Bob'
     * ```
     */
    toImmutableDictionary<TKey, TValue>(keySelector: Selector<TElement, TKey>, valueSelector: Selector<TElement, TValue>, valueComparator?: EqualityComparator<TValue>): Promise<ImmutableDictionary<TKey, TValue>>;
    /**
     * Materialises the asynchronous sequence into an immutable list.
     * @param comparator Optional equality comparator used by the resulting list.
     * @returns {Promise<ImmutableList<TElement>>} A promise that resolves to an immutable list containing all elements from the source in iteration order.
     * @remarks The entire sequence is consumed asynchronously before the list is returned.
     * @example
     * ```typescript
     * const numbers = fromAsync([1, 2, 3]);
     * const immutableList = await numbers.toImmutableList();
     * console.log(immutableList.toArray()); // [1, 2, 3]
     * ```
     */
    toImmutableList(comparator?: EqualityComparator<TElement>): Promise<ImmutableList<TElement>>;
    /**
     * Materialises the asynchronous sequence into an immutable priority queue.
     * @param comparator Optional order comparator used to compare elements in the resulting queue.
     * @returns {Promise<ImmutablePriorityQueue<TElement>>} A promise that resolves to an immutable priority queue containing all elements from the source.
     * @remarks The entire sequence is consumed asynchronously before the queue is returned. Elements are ordered according to {@link comparator} or the default ordering.
     * @example
     * ```typescript
     * const numbers = fromAsync([3, 1, 4, 1, 5, 9, 2, 6]);
     * const immutablePriorityQueue = await numbers.toImmutablePriorityQueue();
     * console.log(immutablePriorityQueue.toArray()); // [1, 1, 2, 3, 4, 5, 6, 9] (sorted)
     * ```
     */
    toImmutablePriorityQueue(comparator?: OrderComparator<TElement>): Promise<ImmutablePriorityQueue<TElement>>;
    /**
     * Materialises the asynchronous sequence into an immutable FIFO queue.
     * @param comparator Optional equality comparator used by the resulting queue.
     * @returns {Promise<ImmutableQueue<TElement>>} A promise that resolves to an immutable queue containing all elements from the source in enqueue order.
     * @remarks The entire sequence is consumed asynchronously before the queue is returned.
     * @example
     * ```typescript
     * const numbers = fromAsync([1, 2, 3]);
     * const immutableQueue = await numbers.toImmutableQueue();
     * console.log(immutableQueue.toArray()); // [1, 2, 3]
     * ```
     */
    toImmutableQueue(comparator?: EqualityComparator<TElement>): Promise<ImmutableQueue<TElement>>;
    /**
     * Materialises the asynchronous sequence into an immutable set containing the distinct elements.
     * @returns {Promise<ImmutableSet<TElement>>} A promise that resolves to an immutable set built from the distinct elements of the source.
     * @remarks The entire sequence is consumed asynchronously before the set is returned, and duplicate elements are collapsed using the set's equality semantics.
     * @example
     * ```typescript
     * const numbers = fromAsync([1, 2, 2, 3, 1]);
     * const immutableSet = await numbers.toImmutableSet();
     * console.log(immutableSet.toArray()); // [1, 2, 3]
     * ```
     */
    toImmutableSet(): Promise<ImmutableSet<TElement>>;
    /**
     * Materialises the asynchronous sequence into an immutable sorted dictionary keyed by the provided selector.
     * @template TKey Type of key returned by {@link keySelector}.
     * @template TValue Type of value returned by {@link valueSelector}.
     * @param keySelector Selector used to derive the key for each element.
     * @param valueSelector Selector used to derive the value for each element.
     * @param keyComparator Optional order comparator used to sort keys in the resulting dictionary.
     * @param valueComparator Optional equality comparator used to compare values in the resulting dictionary.
     * @returns {Promise<ImmutableSortedDictionary<TKey, TValue>>} A promise that resolves to an immutable sorted dictionary populated with the projected key/value pairs.
     * @throws {InvalidArgumentException} Thrown when {@link keySelector} produces duplicate keys.
     * @remarks The entire sequence is consumed asynchronously before the dictionary is returned.
     * @example
     * ```typescript
     * const people = fromAsync([
     *   { id: 2, name: 'Bob' },
     *   { id: 1, name: 'Alice' },
     * ]);
     * const immutableSortedDictionary = await people.toImmutableSortedDictionary(p => p.id, p => p.name);
     * console.log(immutableSortedDictionary.keys().toArray()); // [1, 2]
     * console.log(immutableSortedDictionary.get(1)); // 'Alice'
     * ```
     */
    toImmutableSortedDictionary<TKey, TValue>(keySelector: Selector<TElement, TKey>, valueSelector: Selector<TElement, TValue>, keyComparator?: OrderComparator<TKey>, valueComparator?: EqualityComparator<TValue>): Promise<ImmutableSortedDictionary<TKey, TValue>>;
    /**
     * Materialises the asynchronous sequence into an immutable sorted set of distinct elements.
     * @param comparator Optional order comparator used to sort the elements.
     * @returns {Promise<ImmutableSortedSet<TElement>>} A promise that resolves to an immutable sorted set containing the distinct elements from the source.
     * @remarks The entire sequence is consumed asynchronously before the set is returned, and duplicate elements are collapsed using the set's ordering semantics.
     * @example
     * ```typescript
     * const numbers = fromAsync([3, 1, 4, 1, 5, 9, 2, 6]);
     * const immutableSortedSet = await numbers.toImmutableSortedSet();
     * console.log(immutableSortedSet.toArray()); // [1, 2, 3, 4, 5, 6, 9]
     * ```
     */
    toImmutableSortedSet(comparator?: OrderComparator<TElement>): Promise<ImmutableSortedSet<TElement>>;
    /**
     * Materialises the asynchronous sequence into an immutable stack (LIFO).
     * @param comparator Optional equality comparator used by the resulting stack.
     * @returns {Promise<ImmutableStack<TElement>>} A promise that resolves to an immutable stack whose top element corresponds to the last element of the source.
     * @remarks The entire sequence is consumed asynchronously before the stack is returned.
     * @example
     * ```typescript
     * const numbers = fromAsync([1, 2, 3]);
     * const immutableStack = await numbers.toImmutableStack();
     * console.log(immutableStack.peek()); // 3
     * console.log(immutableStack.pop().peek()); // 2
     * ```
     */
    toImmutableStack(comparator?: EqualityComparator<TElement>): Promise<ImmutableStack<TElement>>;
    /**
     * Materialises the asynchronous sequence into a linked list.
     * @param comparator Optional equality comparator used by the resulting list.
     * @returns {Promise<LinkedList<TElement>>} A promise that resolves to a linked list containing all elements from the source in iteration order.
     * @remarks The entire sequence is consumed asynchronously before the list is returned.
     * @example
     * ```typescript
     * const numbers = fromAsync([1, 2, 3]);
     * const linkedList = await numbers.toLinkedList();
     * console.log(linkedList.toArray()); // [1, 2, 3]
     * ```
     */
    toLinkedList(comparator?: EqualityComparator<TElement>): Promise<LinkedList<TElement>>;
    /**
     * Materialises the asynchronous sequence into a resizable list.
     * @param comparator Optional equality comparator used by the resulting list.
     * @returns {Promise<List<TElement>>} A promise that resolves to a list containing all elements from the source in iteration order.
     * @remarks The entire sequence is consumed asynchronously before the list is returned.
     * @example
     * ```typescript
     * const numbers = fromAsync([1, 2, 3]);
     * const list = await numbers.toList();
     * console.log(list.toArray()); // [1, 2, 3]
     * ```
     */
    toList(comparator?: EqualityComparator<TElement>): Promise<List<TElement>>;
    /**
     * Materialises the asynchronous sequence into a lookup keyed by the provided selector.
     * @template TKey Type of key returned by {@link keySelector}.
     * @template TValue Type of value returned by {@link valueSelector}.
     * @param keySelector Selector used to derive the key for each element.
     * @param valueSelector Selector used to derive the value for each element.
     * @param keyComparator Optional order comparator used to compare keys in the resulting lookup.
     * @returns {Promise<ILookup<TKey, TValue>>} A promise that resolves to a lookup grouping the projected values by key.
     * @remarks The entire sequence is consumed asynchronously. Elements within each group preserve their original order and the groups are cached for repeated enumeration.
     * @example
     * ```typescript
     * const products = fromAsync([
     *   { name: 'Apple', category: 'Fruit' },
     *   { name: 'Banana', category: 'Fruit' },
     *   { name: 'Carrot', category: 'Vegetable' },
     * ]);
     * const lookup = await products.toLookup(p => p.category, p => p.name);
     * console.log(lookup.get('Fruit').toArray()); // ['Apple', 'Banana']
     * console.log(lookup.get('Vegetable').toArray()); // ['Carrot']
     * ```
     */
    toLookup<TKey, TValue>(keySelector: Selector<TElement, TKey>, valueSelector: Selector<TElement, TValue>, keyComparator?: OrderComparator<TKey>): Promise<ILookup<TKey, TValue>>;
    /**
     * Materialises the asynchronous sequence into a `Map` keyed by the provided selector.
     * @template TKey Type of key returned by {@link keySelector}.
     * @template TValue Type of value returned by {@link valueSelector}.
     * @param keySelector Selector used to derive the key for each element.
     * @param valueSelector Selector used to derive the value for each element.
     * @returns {Promise<Map<TKey, TValue>>} A promise that resolves to a map populated with the projected key/value pairs.
     * @remarks The entire sequence is consumed asynchronously. When {@link keySelector} produces duplicate keys, later elements overwrite earlier entries.
     * @example
     * ```typescript
     * const people = fromAsync([
     *   { id: 1, name: 'Alice' },
     *   { id: 2, name: 'Bob' },
     * ]);
     * const map = await people.toMap(p => p.id, p => p.name);
     * console.log(map.get(1)); // 'Alice'
     * console.log(map.get(2)); // 'Bob'
     * ```
     */
    toMap<TKey, TValue>(keySelector: Selector<TElement, TKey>, valueSelector: Selector<TElement, TValue>): Promise<Map<TKey, TValue>>;
    /**
     * Materialises the asynchronous sequence into a plain object keyed by the provided selector.
     * @template TKey extends string | number | symbol Property key type returned by {@link keySelector}.
     * @template TValue Type of value returned by {@link valueSelector}.
     * @param keySelector Selector used to derive the property key for each element.
     * @param valueSelector Selector used to derive the value for each element.
     * @returns {Promise<Record<TKey, TValue>>} A promise that resolves to an object populated with the projected key/value pairs.
     * @remarks The entire sequence is consumed asynchronously. When {@link keySelector} produces duplicate keys, later values overwrite earlier ones.
     * @example
     * ```typescript
     * const people = fromAsync([
     *   { id: 1, name: 'Alice' },
     *   { id: 2, name: 'Bob' },
     * ]);
     * const obj = await people.toObject(p => p.id, p => p.name);
     * console.log(obj[1]); // 'Alice'
     * console.log(obj[2]); // 'Bob'
     * ```
     */
    toObject<TKey extends PropertyKey, TValue>(keySelector: Selector<TElement, TKey>, valueSelector: Selector<TElement, TValue>): Promise<Record<TKey, TValue>>;
    /**
     * Materialises the asynchronous sequence into a priority queue.
     * @param comparator Optional order comparator used to compare elements in the resulting queue.
     * @returns {Promise<PriorityQueue<TElement>>} A promise that resolves to a priority queue containing all elements from the source.
     * @remarks The entire sequence is consumed asynchronously before the queue is returned. Elements are ordered according to {@link comparator} or the default ordering.
     * @example
     * ```typescript
     * const numbers = fromAsync([3, 1, 4, 1, 5, 9, 2, 6]);
     * const priorityQueue = await numbers.toPriorityQueue();
     * console.log(priorityQueue.dequeue()); // 1
     * console.log(priorityQueue.dequeue()); // 1
     * ```
     */
    toPriorityQueue(comparator?: OrderComparator<TElement>): Promise<PriorityQueue<TElement>>;
    /**
     * Materialises the asynchronous sequence into a FIFO queue.
     * @param comparator Optional equality comparator used by the resulting queue.
     * @returns {Promise<Queue<TElement>>} A promise that resolves to a queue containing all elements from the source in enqueue order.
     * @remarks The entire sequence is consumed asynchronously before the queue is returned.
     * @example
     * ```typescript
     * const numbers = fromAsync([1, 2, 3]);
     * const queue = await numbers.toQueue();
     * console.log(queue.dequeue()); // 1
     * console.log(queue.dequeue()); // 2
     * ```
     */
    toQueue(comparator?: EqualityComparator<TElement>): Promise<Queue<TElement>>;
    /**
     * Materialises the asynchronous sequence into a native `Set`.
     * @returns {Promise<Set<TElement>>} A promise that resolves to a set containing the distinct elements from the source.
     * @remarks The entire sequence is consumed asynchronously before the set is returned, and duplicate elements are collapsed using JavaScript's `SameValueZero` semantics.
     * @example
     * ```typescript
     * const numbers = fromAsync([1, 2, 2, 3, 1]);
     * const set = await numbers.toSet();
     * console.log(Array.from(set)); // [1, 2, 3]
     * ```
     */
    toSet(): Promise<Set<TElement>>;
    /**
     * Materialises the asynchronous sequence into a sorted dictionary keyed by the provided selector.
     * @template TKey Type of key returned by {@link keySelector}.
     * @template TValue Type of value returned by {@link valueSelector}.
     * @param keySelector Selector used to derive the key for each element.
     * @param valueSelector Selector used to derive the value for each element.
     * @param keyComparator Optional order comparator used to sort keys in the resulting dictionary.
     * @param valueComparator Optional equality comparator used to compare values in the resulting dictionary.
     * @returns {Promise<SortedDictionary<TKey, TValue>>} A promise that resolves to a sorted dictionary populated with the projected key/value pairs.
     * @throws {InvalidArgumentException} Thrown when {@link keySelector} produces duplicate keys.
     * @remarks The entire sequence is consumed asynchronously before the dictionary is returned.
     * @example
     * ```typescript
     * const people = fromAsync([
     *   { id: 2, name: 'Bob' },
     *   { id: 1, name: 'Alice' },
     * ]);
     * const sortedDictionary = await people.toSortedDictionary(p => p.id, p => p.name);
     * console.log(sortedDictionary.keys().toArray()); // [1, 2]
     * console.log(sortedDictionary.get(1)); // 'Alice'
     * ```
     */
    toSortedDictionary<TKey, TValue>(keySelector: Selector<TElement, TKey>, valueSelector: Selector<TElement, TValue>, keyComparator?: OrderComparator<TKey>, valueComparator?: EqualityComparator<TValue>): Promise<SortedDictionary<TKey, TValue>>;
    /**
     * Materialises the asynchronous sequence into a sorted set of distinct elements.
     * @param comparator Optional order comparator used to sort the elements.
     * @returns {Promise<SortedSet<TElement>>} A promise that resolves to a sorted set containing the distinct elements from the source.
     * @remarks The entire sequence is consumed asynchronously before the set is returned, and duplicate elements are collapsed using the set's ordering semantics.
     * @example
     * ```typescript
     * const numbers = fromAsync([3, 1, 4, 1, 5, 9, 2, 6]);
     * const sortedSet = await numbers.toSortedSet();
     * console.log(sortedSet.toArray()); // [1, 2, 3, 4, 5, 6, 9]
     * ```
     */
    toSortedSet(comparator?: OrderComparator<TElement>): Promise<SortedSet<TElement>>;
    /**
     * Materialises the asynchronous sequence into a stack (LIFO).
     * @param comparator Optional equality comparator used by the resulting stack.
     * @returns {Promise<Stack<TElement>>} A promise that resolves to a stack whose top element corresponds to the last element of the source.
     * @remarks The entire sequence is consumed asynchronously before the stack is returned.
     * @example
     * ```typescript
     * const numbers = fromAsync([1, 2, 3]);
     * const stack = await numbers.toStack();
     * console.log(stack.peek()); // 3
     * console.log(stack.pop().peek()); // 2
     * ```
     */
    toStack(comparator?: EqualityComparator<TElement>): Promise<Stack<TElement>>;
    /**
     * Creates a set-style union between this asynchronous sequence and {@link enumerable} using an equality comparator.
     * @param enumerable Additional asynchronous sequence whose elements are consumed after the source when forming the union.
     * @param comparator Optional equality comparator that determines whether two elements are considered the same. Defaults to the library's standard equality comparator.
     * @returns {IAsyncEnumerable<TElement>} A deferred asynchronous sequence containing the distinct elements from this sequence followed by elements from {@link enumerable} that are not already present according to {@link comparator}.
     * @throws {unknown} Re-throws any error thrown while iterating either async sequence or executing {@link comparator}.
     * @remarks Elements from the original sequence always appear before contributions from {@link enumerable}. The method buffers only the comparison data needed to detect duplicates and consumes each input at most once.
     * @example
     * ```typescript
     * const numbers1 = fromAsync([1, 2, 3, 4, 5]);
     * const numbers2 = [3, 5, 6, 7];
     * const unioned = await numbers1.union(numbers2).toArray();
     * console.log(unioned); // [1, 2, 3, 4, 5, 6, 7]
     * ```
     */
    union(enumerable: AsyncIterable<TElement>, comparator?: EqualityComparator<TElement>): IAsyncEnumerable<TElement>;
    /**
     * Creates a set-style union between this asynchronous sequence and {@link enumerable} by comparing keys projected from each element.
     * @template TKey Type of key generated by {@link keySelector}.
     * @param enumerable Additional asynchronous sequence whose elements are consumed after the source when forming the union.
     * @param keySelector Projection that produces a comparison key for each element.
     * @param comparator Optional equality comparator that determines whether two keys are considered the same. Defaults to the library's standard equality comparator.
     * @returns {IAsyncEnumerable<TElement>} A deferred asynchronous sequence containing the distinct elements from this sequence followed by elements from {@link enumerable} whose keys were not previously observed.
     * @throws {unknown} Re-throws any error thrown while iterating either async sequence or executing {@link keySelector} or {@link comparator}.
     * @remarks Keys are buffered to ensure uniqueness while elements remain streamable. Provide {@link comparator} when keys require structural equality semantics.
     * @example
     * ```typescript
     * const products1 = fromAsync([
     *   { name: 'Apple', category: 'Fruit' },
     *   { name: 'Banana', category: 'Fruit' },
     * ]);
     * const products2 = [
     *   { name: 'Carrot', category: 'Vegetable' },
     *   { name: 'Apple', category: 'Fruit' },
     * ];
     *
     * const unioned = await products1.unionBy(products2, p => p.category).toArray();
     * console.log(unioned);
     * // [
     * //   { name: 'Apple', category: 'Fruit' },
     * //   { name: 'Banana', category: 'Fruit' },
     * //   { name: 'Carrot', category: 'Vegetable' }
     * // ]
     * ```
     */
    unionBy<TKey>(enumerable: AsyncIterable<TElement>, keySelector: Selector<TElement, TKey>, comparator?: EqualityComparator<TKey>): IAsyncEnumerable<TElement>;
    /**
     * Calculates the variance of the numeric values produced by the async sequence.
     * @param selector Optional projection that extracts the numeric value for each element. Defaults to the element itself.
     * @param sample When `true`, computes the sample variance dividing by _n - 1_; when `false`, computes the population variance dividing by _n_. Defaults to `true`.
     * @returns {Promise<number>} A promise that resolves to the calculated variance, or `NaN` when the sequence is empty—or for sample variance when it contains a single element.
     * @throws {unknown} Re-throws any error thrown while iterating the sequence or executing {@link selector}.
     * @remarks A numerically stable single-pass algorithm (Welford's method) is used, so the sequence is enumerated exactly once regardless of size.
     * @example
     * ```typescript
     * const sampleVariance = await fromAsync([1, 2, 3, 4, 5]).variance();
     * console.log(sampleVariance); // 2.5
     * ```
     */
    variance(selector?: Selector<TElement, number>, sample?: boolean): Promise<number>;
    /**
     * Filters the asynchronous sequence using a type guard predicate and narrows the resulting element type.
     * @template TFiltered extends TElement
     * @param predicate Type guard invoked with each element and its zero-based index. Return `true` to keep the element in the results.
     * @returns {IAsyncEnumerable<TFiltered>} A deferred async sequence containing only elements that satisfy the type guard.
     * @throws {unknown} Re-throws any error thrown while iterating the source or awaiting {@link predicate}.
     * @remarks Enumeration is lazy; {@link predicate} executes on demand and may run concurrently when the consumer requests multiple elements in parallel.
     * @example
     * ```typescript
     * const numbers = fromAsync([1, 2, 3, 4, 5]);
     * const evenNumbers = await numbers.where(x => x % 2 === 0).toArray();
     * console.log(evenNumbers); // [2, 4]
     * ```
     */
    where<TFiltered extends TElement>(predicate: IndexedTypePredicate<TElement, TFiltered>): IAsyncEnumerable<TFiltered>;
    /**
     * Filters the asynchronous sequence using a predicate that can inspect both the element and its position.
     * @param predicate Predicate invoked with each element and its zero-based index. Return `true` to keep the element in the results.
     * @returns {IAsyncEnumerable<TElement>} A deferred async sequence containing only the elements that satisfy {@link predicate}.
     * @throws {unknown} Re-throws any error thrown while iterating the source or awaiting {@link predicate}.
     * @remarks Enumeration is lazy; {@link predicate} executes on demand and iteration stops as soon as the consumer stops awaiting further elements.
     */
    where(predicate: IndexedPredicate<TElement>): IAsyncEnumerable<TElement>;
    /**
     * Produces an asynchronous sequence of sliding windows of fixed size over the source sequence.
     * @param size Length of each window; must be at least 1.
     * @returns {IAsyncEnumerable<IEnumerable<TElement>>} A deferred async sequence where each element exposes one contiguous window from the source.
     * @throws {InvalidArgumentException} Thrown when {@link size} is less than 1.
     * @throws {unknown} Re-throws any error thrown while asynchronously iterating the source sequence.
     * @remarks Windows overlap and are yielded only after enough source elements are observed to fill {@link size}. Trailing partial windows are omitted.
     * @example
     * ```typescript
     * const numbers = fromAsync([1, 2, 3, 4, 5]);
     * const windows = numbers.windows(3);
     * const result = await windows.select(w => w.toArray()).toArray();
     * console.log(result); // [[1, 2, 3], [2, 3, 4], [3, 4, 5]]
     * ```
     */
    windows(size: number): IAsyncEnumerable<IEnumerable<TElement>>;
    /**
     * Combines this asynchronous sequence with {@link iterable} and yields tuples of aligned elements.
     * @template TSecond Type of elements produced by {@link iterable}.
     * @param iterable The secondary async sequence whose elements are paired with the source elements.
     * @returns {IAsyncEnumerable<[TElement, TSecond]>} A deferred async sequence of `[source, other]` tuples truncated to the length of the shorter input.
     * @throws {unknown} Re-throws any error thrown while iterating either async sequence.
     * @remarks Enumeration is lazy; pairs are produced on demand and iteration stops when either sequence completes. Use the overload that accepts a `zipper` when you need to project custom results.
     * @example
     * ```typescript
     * const numbers = fromAsync([1, 2, 3]);
     * const letters = fromAsync(['a', 'b', 'c']);
     * const zipped = await numbers.zip(letters).toArray();
     * console.log(zipped); // [[1, 'a'], [2, 'b'], [3, 'c']]
     *
     * const zippedWithSelector = await numbers.zip(letters, (num, letter) => `${num}-${letter}`).toArray();
     * console.log(zippedWithSelector); // ['1-a', '2-b', '3-c']
     * ```
     */
    zip<TSecond>(iterable: AsyncIterable<TSecond>): IAsyncEnumerable<[TElement, TSecond]>;
    /**
     * Combines this asynchronous sequence with {@link iterable} and projects each aligned pair using {@link zipper}.
     * @template TSecond Type of elements produced by {@link iterable}.
     * @template TResult Result type produced by {@link zipper}.
     * @param iterable The secondary async sequence whose elements are paired with the source elements.
     * @param zipper Projection invoked with each `[source, other]` pair to produce the resulting element. When omitted, the overload returning tuples should be used instead.
     * @returns {IAsyncEnumerable<TResult>} A deferred async sequence of projected results truncated to the length of the shorter input.
     * @throws {unknown} Re-throws any error thrown while iterating either async sequence or executing the `zipper` function.
     * @remarks Enumeration is lazy; the `zipper` function executes on demand for each pair and iteration stops when either sequence completes.
     */
    zip<TSecond, TResult = [TElement, TSecond]>(iterable: AsyncIterable<TSecond>, zipper: Zipper<TElement, TSecond, TResult>): IAsyncEnumerable<TResult>;
    /**
     * Zips this async sequence with the iterables supplied in {@link iterables}, producing aligned tuples.
     * @template TIterable Extends `readonly AsyncIterable<unknown>[]`; the element type of each iterable contributes to the resulting tuple.
     * @param iterables Additional async iterables to zip with the source.
     * @returns {IAsyncEnumerable<[TElement, ...UnpackAsyncIterableTuple<TIterable>]>} A deferred async sequence of tuples truncated to the length of the shortest input.
     * @throws {unknown} Re-throws any error raised while iterating the source or any of the supplied async iterables.
     * @remarks Iteration stops as soon as any participating async iterable completes. Tuple element types are inferred from the supplied iterables, preserving strong typing across the zipped result.
     * @example
     * ```typescript
     * const zipped = await fromAsync([1, 2, 3]).zipMany(
     *     fromAsync(['A', 'B', 'C']),
     *     fromAsync([true, false])
     * ).toArray();
     * console.log(zipped); // [[1, 'A', true], [2, 'B', false]]
     * ```
     */
    zipMany<TIterable extends readonly AsyncIterable<unknown>[]>(...iterables: [...TIterable]): IAsyncEnumerable<[TElement, ...UnpackAsyncIterableTuple<TIterable>]>;
    /**
     * Zips this async sequence with the iterables supplied in {@link iterablesAndZipper} and projects each tuple with {@link ZipManyZipper zipper}.
     * @template TIterable Extends `readonly AsyncIterable<unknown>[]`; the element type of each iterable contributes to the zipper input tuple.
     * @template TResult Result type produced by {@link ZipManyZipper zipper}.
     * @param iterablesAndZipper The trailing argument may be a zipper invoked with each tuple to produce a projected result; preceding arguments are the async iterables to zip with.
     * @returns {IAsyncEnumerable<TResult>} A deferred async sequence of projected results truncated to the length of the shortest input.
     * @throws {unknown} Re-throws any error raised while iterating the source, the supplied async iterables, or executing the zipper.
     * @remarks The zipper receives a readonly tuple `[source, ...others]` for each aligned set. Iteration stops as soon as any participating async iterable completes.
     * @example
     * ```typescript
     * const labels = await fromAsync([1, 2, 3]).zipMany(
     *     fromAsync(['A', 'B', 'C']),
     *     fromAsync([true, true, false]),
     *     ([num, letter, flag]) => `${num}${letter}-${flag ? "yes" : "no"}`
     * ).toArray();
     * console.log(labels); // ["1A-yes", "2B-yes", "3C-no"]
     * ```
     */
    zipMany<TIterable extends readonly AsyncIterable<unknown>[], TResult>(...iterablesAndZipper: [...TIterable, ZipManyZipper<[TElement, ...UnpackAsyncIterableTuple<TIterable>], TResult>]): IAsyncEnumerable<TResult>;
}

export declare interface ICollection<TElement> extends IReadonlyCollection<TElement> {
    /**
     * Adds the element to the collection.
     * @param element The element that will be added to the collection
     * @returns {boolean} true if item is added, false otherwise.
     */
    add(element: TElement): boolean;
    /**
     * Add all items from the provided collection to this collection
     * @param collection The collection whose element will be added
     *                   to this collection.
     * @returns {boolean} true if this collection is changed.
     */
    addAll<TSource extends TElement>(collection: Iterable<TSource>): boolean;
    /**
     * Remove all elements from this collection.
     */
    clear(): void;
    /**
     * Replaces the elements in this collection with the elements from the provided collection.
     * @param collection The collection whose elements will replace the current elements in this collection.
     */
    reset<TSource extends TElement>(collection: Iterable<TSource>): void;
}

export declare interface ICollectionChangedEventArgs<TElement> {
    action: CollectionChangedAction;
    newItems: ReadonlyList<TElement>;
    oldItems: ReadonlyList<TElement>;
}

export declare interface IDictionary<TKey, TValue> extends IReadonlyDictionary<TKey, TValue> {
    /**
     * Adds the specified key and value to the dictionary.
     * @param key The key of the element to add.
     * @param value The value of the element to add. It can be <code>null</code>.
     * @returns The added value.
     * @throws {InvalidArgumentException} If the key already exists in the dictionary.
     */
    add(key: TKey, value: TValue): TValue;
    /**
     * Removes all elements from this dictionary.
     */
    clear(): void;
    /**
     * Adds a value to the dictionary.
     * If the key already exists, the value associated with the key will be replaced by the new value.
     * @param key The key of the element to add or update.
     * @param value The value which will be added or updated.
     * @returns The old value of the key, or null if there was no mapping for the key.
     * @throws {Error} If the key is null
     */
    put(key: TKey, value: TValue): void;
    /**
     * Removes the specified key and its associated value from this dictionary.
     * @param key They key whose itself and its associated value will be removed from the dictionary.
     * @returns The removed value or null if the key does not exist in the dictionary.
     */
    remove(key: TKey): TValue | null;
    /**
     * Sets the value of the given key.
     * @param key The key whose value will be set.
     * @param value The new value of the key
     * @throws {KeyNotFoundException} If the key does not exist in the dictionary.
     */
    set(key: TKey, value: TValue): void;
    /**
     * Attempts to add the specified key and value to the dictionary. Unlike `add` method,
     * it will not throw an error if key already exists.
     * @param key The key of the element to add.
     * @param value The value of the element to add. It can be <code>null</code>.
     * @returns {boolean} true if key-value pair is added; false otherwise.
     */
    tryAdd(key: TKey, value: TValue): boolean;
}

export declare interface IEnumerable<TElement> extends Iterable<TElement> {
    /**
     * Combines the elements of the sequence by applying an accumulator to each element and optionally projecting the final result.
     * @template TAccumulate Type of the intermediate accumulator. Defaults to `TElement` when no seed is provided.
     * @template TResult Type returned when a `resultSelector` is supplied.
     * @param accumulator Function that merges the running accumulator with the next element.
     * @param seed Optional initial accumulator value. When omitted, the first element is used as the starting accumulator.
     * @param resultSelector Optional projection applied to the final accumulator before it is returned.
     * @returns {TAccumulate|TResult} The final accumulator (or its projection).
     * @throws {NoElementsException} Thrown when the sequence is empty and no `seed` is provided.
     * @remarks The source sequence is enumerated exactly once. Supply a `seed` to avoid exceptions on empty sequences and to control the accumulator type.
     * @example
     * ```typescript
     * const numbers = from([1, 2, 3, 4, 5]);
     * const sum = numbers.aggregate((acc, x) => acc + x);
     * console.log(sum); // 15
     *
     * const product = numbers.aggregate((acc, x) => acc * x, 1);
     * console.log(product); // 120
     * ```
     */
    aggregate(accumulator: Accumulator<TElement, TElement>): TElement;
    aggregate<TAccumulate>(accumulator: Accumulator<TElement, TAccumulate>, seed: TAccumulate): TAccumulate;
    aggregate<TAccumulate, TResult>(accumulator: Accumulator<TElement, TAccumulate>, seed: TAccumulate, resultSelector: Selector<TAccumulate, TResult>): TResult;
    /**
     * Groups elements by a computed key and aggregates each group by applying an accumulator within that group.
     * @template TKey Type returned by `keySelector` and used to organise groups.
     * @template TAccumulate Type of the accumulated value created for each group.
     * @param keySelector Selector that derives the grouping key for each element.
     * @param seedSelector Either an initial accumulator value applied to every group or a factory invoked with the group key to produce that value.
     * @param accumulator Function that merges the current accumulator with the next element in the group.
     * @param keyComparator Optional equality comparator used to match group keys.
     * @returns {IEnumerable<KeyValuePair<TKey, TAccumulate>>} A sequence containing one key-value pair per group and its aggregated result.
     * @remarks When `seedSelector` is a function, it is evaluated once per group to obtain the initial accumulator.
     * @example
     * ```typescript
     * const products = from([
     *   { name: 'Apple', category: 'Fruit', price: 1.2 },
     *   { name: 'Banana', category: 'Fruit', price: 0.5 },
     *   { name: 'Carrot', category: 'Vegetable', price: 0.8 },
     *   { name: 'Broccoli', category: 'Vegetable', price: 1.5 },
     * ]);
     *
     * const totalPriceByCategory = products.aggregateBy(
     *   p => p.category,
     *   0,
     *   (acc, p) => acc + p.price
     * ).toArray();
     *
     * console.log(totalPriceByCategory);
     * // [
     * //   { key: 'Fruit', value: 1.7 },
     * //   { key: 'Vegetable', value: 2.3 }
     * // ]
     * ```
     */
    aggregateBy<TKey, TAccumulate = TElement>(keySelector: Selector<TElement, TKey>, seedSelector: Selector<TKey, TAccumulate> | TAccumulate, accumulator: Accumulator<TElement, TAccumulate>, keyComparator?: EqualityComparator<TKey>): IEnumerable<KeyValuePair<TKey, TAccumulate>>;
    /**
     * Determines whether every element in the sequence satisfies the supplied predicate.
     * @param predicate Function that evaluates each element and returns `true` when it satisfies the condition.
     * @returns {boolean} `true` when all elements satisfy the predicate; otherwise, `false`.
     * @remarks Enumeration stops as soon as the predicate returns `false`.
     * @example
     * ```typescript
     * const numbers = from([1, 2, 3, 4, 5]);
     * const allPositive = numbers.all(x => x > 0);
     * console.log(allPositive); // true
     *
     * const mixedNumbers = from([-1, 2, 3, -4, 5]);
     * const allPositive2 = mixedNumbers.all(x => x > 0);
     * console.log(allPositive2); // false
     * ```
     */
    all(predicate: Predicate<TElement>): boolean;
    /**
     * Determines whether the sequence contains at least one element that matches the optional predicate.
     * @param predicate Optional function used to test elements. When omitted, the method returns `true` if the sequence contains any element.
     * @returns {boolean} `true` when a matching element is found; otherwise, `false`.
     * @remarks When the predicate is omitted, only the first element is inspected, making this more efficient than `count() > 0`.
     * @example
     * ```typescript
     * const numbers = from([1, 2, 3, 4, 5]);
     * const hasEvenNumber = numbers.any(x => x % 2 === 0);
     * console.log(hasEvenNumber); // true
     *
     * const oddNumbers = from([1, 3, 5]);
     * const hasEvenNumber2 = oddNumbers.any(x => x % 2 === 0);
     * console.log(hasEvenNumber2); // false
     * ```
     */
    any(predicate?: Predicate<TElement>): boolean;
    /**
     * Creates a sequence that yields the current elements followed by the supplied element.
     * @param element Element appended to the end of the sequence.
     * @returns {IEnumerable<TElement>} A new enumerable whose final item is the provided element.
     * @remarks The source sequence is not modified; enumeration is deferred until the returned sequence is iterated.
     * @example
     * ```typescript
     * const numbers = from([1, 2, 3]);
     * const appended = numbers.append(4).toArray();
     * console.log(appended); // [1, 2, 3, 4]
     * ```
     */
    append(element: TElement): IEnumerable<TElement>;
    /**
     * Determines whether the sequence contains at least {@link count} elements that satisfy the optional predicate.
     * @param count Minimum number of matching elements required. Must be greater than or equal to 0.
     * @param predicate Optional predicate that determines which elements are counted. When omitted, every element is considered a match.
     * @returns {boolean} `true` when at least {@link count} matching elements are present; otherwise, `false`.
     * @throws {InvalidArgumentException} Thrown when {@link count} is negative.
     * @throws {unknown} Re-throws any error encountered while iterating the sequence or executing the predicate.
     * @remarks Enumeration stops as soon as the required number of matches is found, avoiding unnecessary work on long sequences.
     * @example
     * ```typescript
     * const numbers = from([1, 2, 3, 4, 5]);
     * const hasAtLeastTwoEvens = numbers.atLeast(2, n => n % 2 === 0);
     * console.log(hasAtLeastTwoEvens); // true
     * ```
     */
    atLeast(count: number, predicate?: Predicate<TElement>): boolean;
    /**
     * Determines whether the sequence contains no more than {@link count} elements that satisfy the optional predicate.
     * @param count Maximum number of matching elements allowed. Must be greater than or equal to 0.
     * @param predicate Optional predicate that determines which elements are counted. When omitted, every element is considered a match.
     * @returns {boolean} `true` when the number of matching elements does not exceed {@link count}; otherwise, `false`.
     * @throws {InvalidArgumentException} Thrown when {@link count} is negative.
     * @throws {unknown} Re-throws any error encountered while iterating the sequence or executing the predicate.
     * @remarks Enumeration stops as soon as the count is exceeded, making it efficient for large or infinite sequences.
     * @example
     * ```typescript
     * const numbers = from([1, 2, 3, 4, 5]);
     * const hasAtMostOneEven = numbers.atMost(1, n => n % 2 === 0);
     * console.log(hasAtMostOneEven); // false
     * ```
     */
    atMost(count: number, predicate?: Predicate<TElement>): boolean;
    /**
     * Computes the arithmetic mean of the numeric values produced for each element in the sequence.
     * @param selector Optional projection that extracts the numeric value for each element. Defaults to the element itself.
     * @returns {number} The arithmetic mean of the selected values.
     * @throws {NoElementsException} Thrown when the sequence is empty.
     * @remarks Provide a selector when the elements are not already numeric. All values are enumerated exactly once.
     * @example
     * ```typescript
     * const numbers = from([1, 2, 3, 4, 5]);
     * const avg = numbers.average();
     * console.log(avg); // 3
     *
     * const people = from([
     *   { name: 'Alice', age: 25 },
     *   { name: 'Bob', age: 30 },
     *   { name: 'Charlie', age: 35 },
     * ]);
     * const avgAge = people.average(p => p.age);
     * console.log(avgAge); // 30
     * ```
     */
    average(this: Iterable<number>): number;
    average(selector: Selector<TElement, number>): number;
    /**
     * Produces the cartesian product between this sequence and {@link iterable}.
     * @template TSecond Type of elements emitted by {@link iterable}.
     * @param iterable The secondary sequence paired with every element from the source.
     * @returns {IEnumerable<[TElement, TSecond]>} A deferred sequence that yields each ordered pair `[source, other]`.
     * @throws {unknown} Re-throws any error raised while iterating the source or {@link iterable}.
     * @remarks The secondary sequence is fully buffered before iteration starts so that it can be replayed for every source element. The resulting sequence stops when the source sequence completes.
     * @example
     * ```typescript
     * const pairs = from([1, 2]).cartesian(['A', 'B']).toArray();
     * console.log(pairs); // [[1, 'A'], [1, 'B'], [2, 'A'], [2, 'B']]
     * ```
     */
    cartesian<TSecond>(iterable: Iterable<TSecond>): IEnumerable<[TElement, TSecond]>;
    /**
     * Reinterprets each element in the sequence as the specified result type.
     * @template TResult Target type exposed by the returned sequence.
     * @returns {IEnumerable<TResult>} A sequence that yields the same elements typed as `TResult`.
     * @remarks No runtime conversion occurs; ensure the underlying elements are compatible with `TResult` to avoid downstream failures.
     * @example
     * ```typescript
     * const mixed = from([1, 'two', 3, 'four']);
     * const numbers = mixed.cast<number>().where(x => typeof x === 'number');
     * console.log(numbers.toArray()); // [1, 3]
     * ```
     */
    cast<TResult>(): IEnumerable<TResult>;
    /**
     * Splits the sequence into contiguous subsequences containing at most the specified number of elements.
     * @param size Maximum number of elements to include in each chunk. Must be greater than 0.
     * @returns {IEnumerable<IEnumerable<TElement>>} A sequence where each element is a chunk of the original sequence.
     * @throws {InvalidArgumentException} Thrown when `size` is less than 1.
     * @remarks The final chunk may contain fewer elements than `size`. Enumeration is deferred until the returned sequence is iterated.
     * @example
     * ```typescript
     * const numbers = from([1, 2, 3, 4, 5, 6, 7, 8]);
     * const chunks = numbers.chunk(3);
     * console.log(chunks.select(c => c.toArray()).toArray()); // [[1, 2, 3], [4, 5, 6], [7, 8]]
     * ```
     */
    chunk(size: number): IEnumerable<IEnumerable<TElement>>;
    /**
     * Generates the unique combinations that can be built from the elements in the sequence.
     * @param size Optional number of elements that each combination must contain. When omitted, combinations of every possible length are produced.
     * @returns {IEnumerable<IEnumerable<TElement>>} A sequence of combinations built from the source elements.
     * @throws {InvalidArgumentException} Thrown when `size` is negative.
     * @remarks The source sequence is materialised before combinations are produced, so very large inputs can be expensive. Duplicate combinations produced by repeated elements are emitted only once.
     * @example
     * ```typescript
     * const numbers = from([1, 2, 3]);
     * const combs = numbers.combinations(2);
     * console.log(combs.select(c => c.toArray()).toArray()); // [[1, 2], [1, 3], [2, 3]]
     * ```
     */
    combinations(size?: number): IEnumerable<IEnumerable<TElement>>;
    /**
     * Filters out `null` and `undefined` values from the sequence.
     * @template TElement Type of elements in the source sequence.
     * @returns {IEnumerable<NonNullable<TElement>>} A sequence containing only the elements that are neither `null` nor `undefined`.
     * @remarks The method preserves other falsy values (such as `0` or an empty string) and defers execution until the returned sequence is iterated.
     * @example
     * ```typescript
     * const values = from([1, null, 0, undefined]).compact().toArray();
     * console.log(values); // [1, 0]
     * ```
     */
    compact(): IEnumerable<NonNullable<TElement>>;
    /**
     * Appends the specified iterable to the end of the sequence.
     * @param iterable Additional elements that are yielded after the current sequence.
     * @returns {IEnumerable<TElement>} A sequence containing the elements of the current sequence followed by those from `iterable`.
     * @remarks Enumeration of both sequences is deferred until the result is iterated.
     * @example
     * ```typescript
     * const numbers1 = from([1, 2, 3]);
     * const numbers2 = [4, 5, 6];
     * const concatenated = numbers1.concat(numbers2).toArray();
     * console.log(concatenated); // [1, 2, 3, 4, 5, 6]
     * ```
     */
    concat(iterable: Iterable<TElement>): IEnumerable<TElement>;
    /**
     * Determines whether the sequence contains a specific element using an optional comparator.
     * @param element Element to locate in the sequence.
     * @param comparator Optional equality comparator used to match elements. Defaults to the library's standard equality comparison.
     * @returns {boolean} `true` when the element is found; otherwise, `false`.
     * @example
     * ```typescript
     * const numbers = from([1, 2, 3, 4, 5]);
     * const hasThree = numbers.contains(3);
     * console.log(hasThree); // true
     *
     * const hasTen = numbers.contains(10);
     * console.log(hasTen); // false
     * ```
     */
    contains(element: TElement, comparator?: EqualityComparator<TElement>): boolean;
    /**
     * Computes the Pearson correlation coefficient between this sequence and {@link iterable}.
     * @template TSecond Type of elements produced by {@link iterable}.
     * @param iterable Sequence whose elements align by index with the source sequence.
     * @param selector Optional projection that extracts the numeric value for each element of the source sequence. Defaults to treating the element itself as numeric.
     * @param otherSelector Optional projection that extracts the numeric value for each element of {@link iterable}. Defaults to treating the element itself as numeric.
     * @returns {number} The correlation coefficient in the interval [-1, 1].
     * @throws {DimensionMismatchException} Thrown when the sequences do not contain the same number of elements.
     * @throws {InsufficientElementException} Thrown when fewer than two aligned pairs are available.
     * @throws {Error} Thrown when the standard deviation of either numeric projection is zero.
     * @throws {unknown} Re-throws any error encountered while iterating the sequences or executing the selector projections.
     * @remarks Both sequences are consumed simultaneously via an online algorithm that avoids buffering the full dataset. Ensure the iterables are aligned because mismatch detection occurs only after iteration begins.
     * @example
     * ```typescript
     * const temperatures = from([15, 18, 21, 24]);
     * const sales = [30, 36, 42, 48];
     * const correlation = temperatures.correlation(sales);
     * console.log(correlation); // 1
     * ```
     */
    correlation<TSecond>(iterable: Iterable<TSecond>, selector?: Selector<TElement, number>, otherSelector?: Selector<TSecond, number>): number;
    /**
     * Computes the Pearson correlation coefficient between two numeric projections of the sequence.
     * @param leftSelector Projection that produces the first numeric series for each element.
     * @param rightSelector Projection that produces the second numeric series for each element.
     * @returns {number} The correlation coefficient in the interval [-1, 1].
     * @throws {InsufficientElementException} Thrown when fewer than two elements are available.
     * @throws {Error} Thrown when the standard deviation of either numeric projection is zero.
     * @throws {unknown} Re-throws any error encountered while iterating the sequence or executing the selector projections.
     * @remarks The sequence is consumed exactly once using an online algorithm, which keeps memory usage constant even for large inputs.
     * @example
     * ```typescript
     * const metrics = from([
     *   { impressions: 1_000, clicks: 50 },
     *   { impressions: 1_500, clicks: 75 },
     *   { impressions: 2_000, clicks: 100 }
     * ]);
     * const correlation = metrics.correlationBy(m => m.impressions, m => m.clicks);
     * console.log(correlation); // 1
     * ```
     */
    correlationBy(leftSelector: Selector<TElement, number>, rightSelector: Selector<TElement, number>): number;
    /**
     * Counts the number of elements in the sequence, optionally restricted by a predicate.
     * @param predicate Optional predicate that determines which elements are counted. When omitted, all elements are counted.
     * @returns {number} The number of elements that satisfy the predicate.
     * @remarks Prefer calling `any()` to test for existence instead of comparing this result with zero.
     * @example
     * ```typescript
     * const numbers = from([1, 2, 3, 4, 5]);
     * const totalCount = numbers.count();
     * console.log(totalCount); // 5
     *
     * const evenCount = numbers.count(x => x % 2 === 0);
     * console.log(evenCount); // 2
     * ```
     */
    count(predicate?: Predicate<TElement>): number;
    /**
     * Counts the occurrences of elements grouped by a derived key.
     * @template TKey Type produced by `keySelector`.
     * @param keySelector Selector used to derive the grouping key for each element.
     * @param comparator Optional equality comparator used to match keys. Defaults to the library's standard equality comparison.
     * @returns {IEnumerable<KeyValuePair<TKey, number>>} A sequence of key/count pairs describing how many elements share each key.
     * @remarks Each key appears exactly once in the result with its associated occurrence count.
     * @example
     * ```typescript
     * const products = from([
     *   { name: 'Apple', category: 'Fruit' },
     *   { name: 'Banana', category: 'Fruit' },
     *   { name: 'Carrot', category: 'Vegetable' },
     * ]);
     *
     * const countByCategory = products.countBy(p => p.category).toArray();
     * console.log(countByCategory);
     * // [
     * //   { key: 'Fruit', value: 2 },
     * //   { key: 'Vegetable', value: 1 }
     * // ]
     * ```
     */
    countBy<TKey>(keySelector: Selector<TElement, TKey>, comparator?: EqualityComparator<TKey>): IEnumerable<KeyValuePair<TKey, number>>;
    /**
     * Calculates the covariance between this sequence and {@link iterable}.
     * @template TSecond Type of elements produced by {@link iterable}.
     * @param iterable Sequence whose elements align by index with the source sequence.
     * @param selector Optional projection that extracts the numeric value for each element of the source sequence. Defaults to treating the element itself as numeric.
     * @param otherSelector Optional projection that extracts the numeric value for each element of {@link iterable}. Defaults to treating the element itself as numeric.
     * @param sample When `true`, computes the sample covariance dividing by _n - 1_; when `false`, computes the population covariance dividing by _n_. Defaults to `true`.
     * @returns {number} The calculated covariance.
     * @throws {DimensionMismatchException} Thrown when the sequences do not contain the same number of elements.
     * @throws {InsufficientElementException} Thrown when fewer than two aligned pairs are available.
     * @throws {unknown} Re-throws any error thrown while iterating either sequence or executing the selector projections.
     * @remarks Both sequences are consumed simultaneously so streaming statistics can be computed without materialising all elements. Ensure the iterables are aligned because mismatch detection occurs only after iteration begins.
     * @example
     * ```typescript
     * const numbers = from([1, 2, 3, 4, 5]);
     * const doubles = [2, 4, 6, 8, 10];
     * const covariance = numbers.covariance(doubles);
     * console.log(covariance); // 5
     * ```
     */
    covariance<TSecond>(iterable: Iterable<TSecond>, selector?: Selector<TElement, number>, otherSelector?: Selector<TSecond, number>, sample?: boolean): number;
    /**
     * Calculates the covariance between two numeric projections of the sequence.
     * @param leftSelector Projection that produces the first numeric series for each element.
     * @param rightSelector Projection that produces the second numeric series for each element.
     * @param sample When `true`, computes the sample covariance dividing by _n - 1_; when `false`, computes the population covariance dividing by _n_. Defaults to `true`.
     * @returns {number} The calculated covariance.
     * @throws {InsufficientElementException} Thrown when fewer than two elements are available.
     * @throws {unknown} Re-throws any error thrown while iterating the sequence or executing the selector projections.
     * @remarks The sequence is consumed exactly once using an online algorithm that avoids buffering, making it suitable for large datasets.
     * @example
     * ```typescript
     * const metrics = from([
     *   { x: 1, y: 2 },
     *   { x: 2, y: 4 },
     *   { x: 3, y: 6 }
     * ]);
     * const covariance = metrics.covarianceBy(p => p.x, p => p.y);
     * console.log(covariance); // 2
     * ```
     */
    covarianceBy(leftSelector: Selector<TElement, number>, rightSelector: Selector<TElement, number>, sample?: boolean): number;
    /**
     * Repeats the sequence the specified number of times, or indefinitely when no count is provided.
     * @param count Optional number of times to repeat the sequence. When omitted, the sequence repeats without end.
     * @returns {IEnumerable<TElement>} A sequence that yields the original elements cyclically.
     * @throws {NoElementsException} Thrown when the sequence is empty.
     * @remarks When `count` is `undefined`, consume the result with care because it represents an infinite sequence.
     * @example
     * ```typescript
     * const numbers = from([1, 2, 3]);
     * const cycled = numbers.cycle(2).toArray();
     * console.log(cycled); // [1, 2, 3, 1, 2, 3]
     * ```
     */
    cycle(count?: number): IEnumerable<TElement>;
    /**
     * Supplies fallback content when the sequence contains no elements.
     * @param value Optional value returned in a singleton sequence when the source is empty. Defaults to `null`.
     * @returns {IEnumerable<TElement | null>} The original sequence when it has elements; otherwise, a singleton sequence containing the provided value.
     * @remarks Use this to ensure downstream operators always receive at least one element.
     * @example
     * ```typescript
     * const empty = from([]);
     * const withDefault = empty.defaultIfEmpty(0).toArray();
     * console.log(withDefault); // [0]
     *
     * const numbers = from([1, 2, 3]);
     * const withDefault2 = numbers.defaultIfEmpty(0).toArray();
     * console.log(withDefault2); // [1, 2, 3]
     * ```
     */
    defaultIfEmpty(value?: TElement | null): IEnumerable<TElement | null>;
    /**
     * Determines whether the sequence and {@link iterable} share no equivalent elements.
     * @template TSecond Type of elements yielded by {@link iterable}.
     * @param iterable Sequence compared against the source.
     * @param comparator Optional equality comparator used to match elements across both sequences. Defaults to the library's standard equality comparison.
     * @returns {boolean} `true` when the sequences are disjoint; otherwise, `false`.
     * @throws {unknown} Re-throws any error encountered while iterating the source, {@link iterable}, or executing the comparator.
     * @remarks When the default comparator is used, the method buffers the source elements in a {@link Set} so it can short-circuit as soon as a shared element is detected.
     * With a custom comparator, the method compares every pair of elements, which may iterate each sequence multiple times; prefer the default comparator when possible for better performance.
     * @example
     * ```typescript
     * const first = from([1, 2, 3]);
     * const second = [4, 5, 6];
     * const areDisjoint = first.disjoint(second);
     * console.log(areDisjoint); // true
     * ```
     */
    disjoint<TSecond>(iterable: Iterable<TSecond>, comparator?: EqualityComparator<TElement | TSecond>): boolean;
    /**
     * Determines whether the key projections of the sequence and {@link iterable} are mutually exclusive.
     * @template TSecond Type of elements yielded by {@link iterable}.
     * @template TKey Key type produced by {@link keySelector}.
     * @template TSecondKey Key type produced by {@link otherKeySelector}.
     * @param iterable Sequence compared against the source.
     * @param keySelector Projection that produces the key evaluated for each source element.
     * @param otherKeySelector Projection that produces the key evaluated for each element of {@link iterable}.
     * @param keyComparator Optional equality comparator applied to projected keys. Defaults to the library's standard equality comparison.
     * @returns {boolean} `true` when no projected keys intersect; otherwise, `false`.
     * @throws {unknown} Re-throws any error encountered while iterating either sequence or executing the selector projections/comparator.
     * @remarks When the default comparator is used, the method buffers the larger key collection in a {@link Set} and short-circuits as soon as an intersecting key is found.
     * Providing a custom comparator forces a full pairwise comparison, which may iterate both sequences repeatedly; prefer the default comparator when suitable.
     * @example
     * ```typescript
     * const left = from([{ name: 'Alice' }, { name: 'Bella' }]);
     * const right = [{ name: 'Mel' }];
     * const areDisjoint = left.disjointBy(right, p => p.name, p => p.name);
     * console.log(areDisjoint); // true
     * ```
     */
    disjointBy<TSecond, TKey, TSecondKey>(iterable: Iterable<TSecond>, keySelector: Selector<TElement, TKey>, otherKeySelector: Selector<TSecond, TSecondKey>, keyComparator?: EqualityComparator<TKey | TSecondKey>): boolean;
    /**
     * Eliminates duplicate elements from the sequence using an optional comparator.
     * @param keyComparator Optional equality comparator used to determine whether two elements are identical. Defaults to the library's standard equality comparison.
     * @returns {IEnumerable<TElement>} A sequence that yields each distinct element once.
     * @remarks Elements are compared by value; when using custom types, provide an appropriate comparator to avoid reference-based comparisons.
     * @example
     * ```typescript
     * const numbers = from([1, 2, 2, 3, 1, 4, 5, 5]);
     * const distinctNumbers = numbers.distinct().toArray();
     * console.log(distinctNumbers); // [1, 2, 3, 4, 5]
     * ```
     */
    distinct(keyComparator?: EqualityComparator<TElement>): IEnumerable<TElement>;
    /**
     * Eliminates duplicate elements by comparing keys computed for each element.
     * @template TKey Key type returned by `keySelector`.
     * @param keySelector Selector used to project each element to the key used for distinctness.
     * @param keyComparator Optional equality comparator used to compare keys. Defaults to the library's standard equality comparison.
     * @returns {IEnumerable<TElement>} A sequence that contains the first occurrence of each unique key.
     * @remarks When keys are expensive to compute, consider memoisation because each element's key is evaluated exactly once.
     * @example
     * ```typescript
     * const products = from([
     *   { name: 'Apple', category: 'Fruit' },
     *   { name: 'Banana', category: 'Fruit' },
     *   { name: 'Carrot', category: 'Vegetable' },
     * ]);
     *
     * const distinctByCategory = products.distinctBy(p => p.category).toArray();
     * console.log(distinctByCategory);
     * // [
     * //   { name: 'Apple', category: 'Fruit' },
     * //   { name: 'Carrot', category: 'Vegetable' }
     * // ]
     * ```
     */
    distinctBy<TKey>(keySelector: Selector<TElement, TKey>, keyComparator?: EqualityComparator<TKey>): IEnumerable<TElement>;
    /**
     * Removes consecutive duplicate elements by comparing each element with its predecessor.
     * @param comparator Optional equality comparator used to determine whether adjacent elements are equal. Defaults to the library's standard equality comparison.
     * @returns {IEnumerable<TElement>} A sequence that yields the first element of each run of equal values.
     * @remarks Unlike {@link distinct}, this only filters out adjacent duplicates and preserves earlier occurrences of repeated values.
     * @example
     * ```typescript
     * const numbers = from([1, 1, 2, 2, 2, 1, 3, 3]);
     * const distinctUntilChangedNumbers = numbers.distinctUntilChanged().toArray();
     * console.log(distinctUntilChangedNumbers); // [1, 2, 1, 3]
     * ```
     */
    distinctUntilChanged(comparator?: EqualityComparator<TElement>): IEnumerable<TElement>;
    /**
     * Removes consecutive duplicate elements by comparing keys projected from each element.
     * @template TKey Key type returned by `keySelector`.
     * @param keySelector Selector used to project each element to the key used for comparison.
     * @param keyComparator Optional equality comparator used to compare keys. Defaults to the library's standard equality comparison.
     * @returns {IEnumerable<TElement>} A sequence that yields the first element in each run of elements whose keys change.
     * @remarks Enumeration stops comparing elements once a different key is encountered, making this useful for collapsing grouped data.
     * @example
     * ```typescript
     * const products = from([
     *   { name: 'Apple', category: 'Fruit' },
     *   { name: 'Banana', category: 'Fruit' },
     *   { name: 'Carrot', category: 'Vegetable' },
     *   { name: 'Broccoli', category: 'Vegetable' },
     *   { name: 'Orange', category: 'Fruit' },
     * ]);
     *
     * const distinctByCategory = products.distinctUntilChangedBy(p => p.category).toArray();
     * console.log(distinctByCategory);
     * // [
     * //   { name: 'Apple', category: 'Fruit' },
     * //   { name: 'Carrot', category: 'Vegetable' },
     * //   { name: 'Orange', category: 'Fruit' }
     * // ]
     * ```
     */
    distinctUntilChangedBy<TKey>(keySelector: Selector<TElement, TKey>, keyComparator?: EqualityComparator<TKey>): IEnumerable<TElement>;
    /**
     * Retrieves the element at the specified zero-based index.
     * @param index Zero-based position of the element to retrieve.
     * @returns {TElement} The element located at the requested index.
     * @throws {IndexOutOfBoundsException} Thrown when `index` is negative or greater than or equal to the number of elements in the sequence.
     * @remarks Enumeration stops once the requested element is found; remaining elements are not evaluated.
     * @example
     * ```typescript
     * const numbers = from([1, 2, 3, 4, 5]);
     * const element = numbers.elementAt(2);
     * console.log(element); // 3
     * ```
     */
    elementAt(index: number): TElement;
    /**
     * Retrieves the element at the specified zero-based index or returns `null` when the index is out of range.
     * @param index Zero-based position of the element to retrieve.
     * @returns {TElement | null} The element at `index`, or `null` when the sequence is shorter than `index + 1` or when `index` is negative.
     * @remarks Use this overload when out-of-range access should produce a sentinel value instead of throwing an exception.
     * @example
     * ```typescript
     * const numbers = from([1, 2, 3, 4, 5]);
     * const element = numbers.elementAtOrDefault(2);
     * console.log(element); // 3
     *
     * const element2 = numbers.elementAtOrDefault(10);
     * console.log(element2); // null
     * ```
     */
    elementAtOrDefault(index: number): TElement | null;
    /**
     * Determines whether the sequence contains exactly {@link count} elements that satisfy the optional predicate.
     * @param count Exact number of matching elements required. Must be greater than or equal to 0.
     * @param predicate Optional predicate that determines which elements are counted. When omitted, every element is considered a match.
     * @returns {boolean} `true` when exactly {@link count} matching elements are present; otherwise, `false`.
     * @throws {InvalidArgumentException} Thrown when {@link count} is negative.
     * @throws {unknown} Re-throws any error encountered while iterating the sequence or executing the predicate.
     * @remarks Enumeration stops once the running total exceeds {@link count}, preventing unnecessary work on long sequences.
     * @example
     * ```typescript
     * const numbers = from([1, 2, 3, 4, 5]);
     * const hasExactlyThreeOdds = numbers.exactly(3, n => n % 2 !== 0);
     * console.log(hasExactlyThreeOdds); // true
     * ```
     */
    exactly(count: number, predicate?: Predicate<TElement>): boolean;
    /**
     * Returns the elements of this sequence that are not present in the specified iterable.
     * @param iterable Sequence whose elements should be removed from the current sequence.
     * @param comparator Optional comparator used to determine element equality. Both equality and order comparators are supported; defaults to the library's standard equality comparison when omitted.
     * @returns {IEnumerable<TElement>} A sequence containing the elements from this sequence that do not appear in `iterable`.
     * @remarks The original ordering and duplicate occurrences from this sequence are preserved. The `iterable` is fully enumerated to build the exclusion set.
     * @example
     * ```typescript
     * const numbers1 = from([1, 2, 3, 4, 5]);
     * const numbers2 = [3, 5, 7];
     * const result = numbers1.except(numbers2).toArray();
     * console.log(result); // [1, 2, 4]
     * ```
     */
    except(iterable: Iterable<TElement>, comparator?: EqualityComparator<TElement> | OrderComparator<TElement>): IEnumerable<TElement>;
    /**
     * Returns the elements of this sequence whose projected keys are not present in the specified iterable.
     * @template TKey Type produced by `keySelector`.
     * @param iterable Sequence whose elements define the keys that should be excluded.
     * @param keySelector Selector used to project each element to the key used for comparison.
     * @param keyComparator Optional comparator used to compare keys. Both equality and order comparators are supported; defaults to the library's standard equality comparison when omitted.
     * @returns {IEnumerable<TElement>} A sequence that contains the elements from this sequence whose keys are absent from `iterable`.
     * @remarks Source ordering is preserved and duplicate elements with distinct keys remain. The exclusion keys are materialised by fully enumerating `iterable`.
     * @example
     * ```typescript
     * const products1 = from([
     *   { name: 'Apple', category: 'Fruit' },
     *   { name: 'Banana', category: 'Fruit' },
     *   { name: 'Carrot', category: 'Vegetable' },
     * ]);
     * const products2 = [
     *   { name: 'Broccoli', category: 'Vegetable' },
     * ];
     *
     * const result = products1.exceptBy(products2, p => p.category).toArray();
     * console.log(result);
     * // [
     * //   { name: 'Apple', category: 'Fruit' },
     * //   { name: 'Banana', category: 'Fruit' }
     * // ]
     * ```
     */
    exceptBy<TKey>(iterable: Iterable<TElement>, keySelector: Selector<TElement, TKey>, keyComparator?: EqualityComparator<TKey> | OrderComparator<TKey>): IEnumerable<TElement>;
    /**
     * Returns the first element that satisfies the provided type guard.
     * @template TFiltered Subtype confirmed by the type guard.
     * @param predicate Type guard evaluated against each element until it returns true.
     * @returns {TFiltered} The first element that satisfies the type guard.
     * @throws {NoElementsException} Thrown when the sequence is empty.
     * @throws {NoMatchingElementException} Thrown when no element satisfies the type guard.
     * @remarks Enumeration stops immediately once a matching element is found.
     * @example
     * ```typescript
     * const numbers = from([1, 2, 3, 4, 5]);
     * const firstElement = numbers.first();
     * console.log(firstElement); // 1
     *
     * const firstEven = numbers.first(x => x % 2 === 0);
     * console.log(firstEven); // 2
     * ```
     */
    first<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): TFiltered;
    /**
     * Returns the first element in the sequence, optionally filtered by a predicate.
     * @param predicate Predicate evaluated against each element; when omitted, the first element is returned.
     * @returns {TElement} The first element of the sequence that satisfies the predicate (or the very first element when none is provided).
     * @throws {NoElementsException} Thrown when the sequence is empty.
     * @throws {NoMatchingElementException} Thrown when a predicate is supplied and no element satisfies it.
     * @remarks Enumeration stops immediately once a matching element is found.
     */
    first(predicate?: Predicate<TElement>): TElement;
    /**
     * Returns the first element that satisfies the provided type guard, or `null` when no such element exists.
     * @template TFiltered Subtype confirmed by the type guard.
     * @param predicate Type guard evaluated against each element until it returns true.
     * @returns {TFiltered | null} The first element that satisfies the type guard, or `null` when none match.
     * @remarks Enumeration stops immediately once a matching element is found.
     * @example
     * ```typescript
     * const numbers = from([1, 2, 3, 4, 5]);
     * const firstElement = numbers.firstOrDefault();
     * console.log(firstElement); // 1
     *
     * const firstEven = numbers.firstOrDefault(x => x % 2 === 0);
     * console.log(firstEven); // 2
     *
     * const empty = from<number>([]);
     * const firstOfEmpty = empty.firstOrDefault();
     * console.log(firstOfEmpty); // null
     *
     * const noEvens = from([1, 3, 5]);
     * const firstEven2 = noEvens.firstOrDefault(x => x % 2 === 0);
     * console.log(firstEven2); // null
     * ```
     */
    firstOrDefault<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): TFiltered | null;
    /**
     * Returns the first element in the sequence or `null` when the sequence is empty or no element satisfies the predicate.
     * @param predicate Predicate evaluated against each element; when omitted, the first element is returned.
     * @returns {TElement | null} The first matching element, or `null` when no match is found.
     * @remarks This method never throws; it communicates absence through the `null` return value.
     */
    firstOrDefault(predicate?: Predicate<TElement>): TElement | null;
    /**
     * Executes the provided callback for every element in the sequence.
     * @param action Callback invoked for each element; receives the element and its zero-based index.
     * @returns {void}
     * @remarks Enumeration starts immediately. Avoid mutating the underlying collection while iterating.
     * @example
     * ```typescript
     * const numbers = from([1, 2, 3]);
     * numbers.forEach((x, i) => console.log(`Index ${i}: ${x}`));
     * // Index 0: 1
     * // Index 1: 2
     * // Index 2: 3
     * ```
     */
    forEach(action: IndexedAction<TElement>): void;
    /**
     * Partitions the sequence into groups based on keys projected from each element.
     * @template TKey Type of key produced by {@link keySelector}.
     * @param keySelector Selector used to derive the grouping key for each element.
     * @param keyComparator Optional equality comparator used to match keys. Defaults to the library's standard equality comparison.
     * @param hashSelector Optional hash selector. When provided, the sequence will use a bucketed approach for faster grouping based on the hash values.
     * @returns {IEnumerable<IGroup<TKey, TElement>>} A sequence of groups, each exposing the key and the elements that share it.
     * @remarks The source sequence is enumerated once when the result is iterated. Elements within each group preserve their original order, and group contents are cached for repeated enumeration.
     * @example
     * ```typescript
     * const products = from([
     *   { name: 'Apple', category: 'Fruit' },
     *   { name: 'Banana', category: 'Fruit' },
     *   { name: 'Carrot', category: 'Vegetable' },
     * ]);
     *
     * const grouped = products.groupBy(p => p.category);
     * for (const group of grouped) {
     *   console.log(group.key, group.toArray());
     * }
     * // Fruit [ { name: 'Apple', category: 'Fruit' }, { name: 'Banana', category: 'Fruit' } ]
     * // Vegetable [ { name: 'Carrot', category: 'Vegetable' } ]
     * ```
     */
    groupBy<TKey>(keySelector: Selector<TElement, TKey>, keyComparator?: EqualityComparator<TKey>, hashSelector?: Selector<TElement, PropertyKey>): IEnumerable<IGroup<TKey, TElement>>;
    /**
     * Correlates each element of the sequence with a collection of matching elements from another sequence.
     * @template TInner Type of elements in the inner sequence.
     * @template TKey Type of key produced by the key selectors.
     * @template TResult Type of element returned by {@link resultSelector}.
     * @param innerEnumerable Sequence whose elements are grouped and joined with the outer elements.
     * @param outerKeySelector Selector that extracts the join key from each outer element.
     * @param innerKeySelector Selector that extracts the join key from each inner element.
     * @param resultSelector Projection that combines an outer element with an `IEnumerable` of matching inner elements.
     * @param keyComparator Optional equality comparator used to match keys. Defaults to the library's standard equality comparison.
     * @returns {IEnumerable<TResult>} A sequence produced by applying {@link resultSelector} to each outer element and its matching inner elements.
     * @remarks The inner sequence is enumerated once to build an in-memory lookup before outer elements are processed. Each outer element is then evaluated lazily and preserves the original outer ordering.
     * @example
     * ```typescript
     * const categories = from([
     *   { id: 1, name: 'Fruit' },
     *   { id: 2, name: 'Vegetable' },
     * ]);
     * const products = from([
     *   { name: 'Apple', categoryId: 1 },
     *   { name: 'Banana', categoryId: 1 },
     *   { name: 'Carrot', categoryId: 2 },
     * ]);
     *
     * const joined = categories.groupJoin(
     *   products,
     *   c => c.id,
     *   p => p.categoryId,
     *   (c, ps) => ({ ...c, products: ps.toArray() })
     * ).toArray();
     *
     * console.log(joined);
     * // [
     * //   { id: 1, name: 'Fruit', products: [ { name: 'Apple', categoryId: 1 }, { name: 'Banana', categoryId: 1 } ] },
     * //   { id: 2, name: 'Vegetable', products: [ { name: 'Carrot', categoryId: 2 } ] }
     * // ]
     * ```
     */
    groupJoin<TInner, TKey, TResult>(innerEnumerable: IEnumerable<TInner>, outerKeySelector: Selector<TElement, TKey>, innerKeySelector: Selector<TInner, TKey>, resultSelector: JoinSelector<TElement, IEnumerable<TInner>, TResult>, keyComparator?: EqualityComparator<TKey>): IEnumerable<TResult>;
    /**
     * Enumerates the sequence while exposing the zero-based index alongside each element.
     * @returns {IEnumerable<[number, TElement]>} A sequence of `[index, element]` tuples.
     * @remarks The index is assigned in the order elements are produced. Enumeration is deferred until the result is iterated.
     * @example
     * ```typescript
     * const letters = from(['a', 'b', 'c']);
     * const indexed = letters.index().toArray();
     * console.log(indexed); // [[0, 'a'], [1, 'b'], [2, 'c']]
     * ```
     */
    index(): IEnumerable<[number, TElement]>;
    /**
     * Interleaves the sequence with another iterable, yielding elements in alternating order.
     * @template TSecond Type of elements in the second iterable.
     * @param iterable Iterable whose elements are alternated with the current sequence.
     * @returns {IEnumerable<TElement | TSecond>} A sequence that alternates between elements from this sequence and `iterable`.
     * @remarks If one sequence is longer, the remaining elements are appended after the shorter sequence is exhausted. Enumeration is deferred.
     * @example
     * ```typescript
     * const numbers1 = from([1, 3, 5]);
     * const numbers2 = [2, 4, 6];
     * const interleaved = numbers1.interleave(numbers2).toArray();
     * console.log(interleaved); // [1, 2, 3, 4, 5, 6]
     * ```
     */
    interleave<TSecond>(iterable: Iterable<TSecond>): IEnumerable<TElement | TSecond>;
    /**
     * Returns the elements common to this sequence and the specified iterable.
     * @param iterable Sequence whose elements are compared against the current sequence.
     * @param comparator Optional comparator used to determine element equality. Both equality and order comparators are supported; defaults to the library's standard equality comparison when omitted.
     * @returns {IEnumerable<TElement>} A sequence containing the intersection of the two sequences.
     * @remarks The original ordering of this sequence is preserved. The `iterable` is fully enumerated to build the inclusion set prior to yielding results.
     * @example
     * ```typescript
     * const numbers1 = from([1, 2, 3, 4, 5]);
     * const numbers2 = [3, 5, 7];
     * const result = numbers1.intersect(numbers2).toArray();
     * console.log(result); // [3, 5]
     * ```
     */
    intersect(iterable: Iterable<TElement>, comparator?: EqualityComparator<TElement> | OrderComparator<TElement>): IEnumerable<TElement>;
    /**
     * Returns the elements whose keys are common to this sequence and the specified iterable.
     * @template TKey Type of key produced by {@link keySelector}.
     * @param iterable Sequence whose elements define the keys considered part of the intersection.
     * @param keySelector Selector used to project each element to the key used for comparison.
     * @param keyComparator Optional comparator used to compare keys. Both equality and order comparators are supported; defaults to the library's standard equality comparison when omitted.
     * @returns {IEnumerable<TElement>} A sequence containing the intersection of the two sequences based on matching keys.
     * @remarks The `iterable` is fully enumerated to materialise the inclusion keys before yielding results. Source ordering is preserved.
     * @example
     * ```typescript
     * const products1 = from([
     *   { name: 'Apple', category: 'Fruit' },
     *   { name: 'Carrot', category: 'Vegetable' },
     * ]);
     * const products2 = [
     *   { name: 'Banana', category: 'Fruit' },
     *   { name: 'Broccoli', category: 'Vegetable' },
     * ];
     *
     * const result = products1.intersectBy(products2, p => p.category).toArray();
     * console.log(result);
     * // [
     * //   { name: 'Apple', category: 'Fruit' },
     * //   { name: 'Carrot', category: 'Vegetable' }
     * // ]
     * ```
     */
    intersectBy<TKey>(iterable: Iterable<TElement>, keySelector: Selector<TElement, TKey>, keyComparator?: EqualityComparator<TKey> | OrderComparator<TKey>): IEnumerable<TElement>;
    /**
     * Inserts the specified separator between adjoining elements.
     * @template TSeparator Type of separator to insert. Defaults to `TElement`.
     * @param separator Value inserted between consecutive elements.
     * @returns {IEnumerable<TElement | TSeparator>} A sequence containing the original elements with separators interleaved.
     * @remarks No separator precedes the first element or follows the last element.
     * @example
     * ```typescript
     * const letters = from(['a', 'b', 'c']);
     * const interspersed = letters.intersperse('-').toArray();
     * console.log(interspersed); // ['a', '-', 'b', '-', 'c']
     * ```
     */
    intersperse<TSeparator = TElement>(separator: TSeparator): IEnumerable<TElement | TSeparator>;
    /**
     * Produces a projection from the sequence and a second sequence by matching elements that share an identical join key.
     * @template TInner Type of elements in the inner sequence.
     * @template TKey Type of key produced by the key selectors.
     * @template TResult Type of element returned by {@link resultSelector}.
     * @param innerEnumerable Sequence whose elements are joined with the outer sequence.
     * @param outerKeySelector Selector that extracts the join key from each outer element.
     * @param innerKeySelector Selector that extracts the join key from each inner element.
     * @param resultSelector Projection that combines an outer element with a matching inner element.
     * @param keyComparator Optional equality comparator used to match keys. Defaults to the library's standard equality comparison when omitted.
     * @returns {IEnumerable<TResult>} A sequence generated by applying {@link resultSelector} to each matching pair.
     * @remarks The inner sequence is fully enumerated to build an in-memory lookup before outer elements are processed. The outer sequence is then enumerated lazily and its original ordering is preserved. This is an inner join; unmatched outer or inner elements are not emitted.
     * @example
     * ```typescript
     * const categories = from([
     *   { id: 1, name: 'Fruit' },
     *   { id: 2, name: 'Vegetable' },
     * ]);
     * const products = from([
     *   { name: 'Apple', categoryId: 1 },
     *   { name: 'Banana', categoryId: 1 },
     *   { name: 'Carrot', categoryId: 2 },
     * ]);
     *
     * const joined = categories.join(
     *   products,
     *   c => c.id,
     *   p => p.categoryId,
     *   (c, p) => ({ category: c.name, product: p.name })
     * ).toArray();
     *
     * console.log(joined);
     * // [
     * //   { category: 'Fruit', product: 'Apple' },
     * //   { category: 'Fruit', product: 'Banana' },
     * //   { category: 'Vegetable', product: 'Carrot' }
     * // ]
     * ```
     */
    join<TInner, TKey, TResult>(innerEnumerable: IEnumerable<TInner>, outerKeySelector: Selector<TElement, TKey>, innerKeySelector: Selector<TInner, TKey>, resultSelector: JoinSelector<TElement, TInner, TResult>, keyComparator?: EqualityComparator<TKey>): IEnumerable<TResult>;
    /**
     * Returns the last element that satisfies the provided type guard.
     * @template TFiltered Subtype confirmed by the type guard.
     * @param predicate Type guard evaluated against each element. Every matching element becomes a candidate, and the final match is returned.
     * @returns {TFiltered} The last element that satisfies the type guard.
     * @throws {NoElementsException} Thrown when the sequence is empty.
     * @throws {NoMatchingElementException} Thrown when no element satisfies the type guard.
     * @remarks The entire sequence is enumerated to locate the final match.
     * @example
     * ```typescript
     * const numbers = from([1, 2, 3, 4, 5]);
     * const lastElement = numbers.last();
     * console.log(lastElement); // 5
     *
     * const lastEven = numbers.last(x => x % 2 === 0);
     * console.log(lastEven); // 4
     * ```
     */
    last<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): TFiltered;
    /**
     * Returns the last element in the sequence, optionally filtered by a predicate.
     * @param predicate Predicate evaluated against each element. When omitted, the last element of the sequence is returned.
     * @returns {TElement} The last element that satisfies the predicate (or the final element when no predicate is supplied).
     * @throws {NoElementsException} Thrown when the sequence is empty.
     * @throws {NoMatchingElementException} Thrown when a predicate is supplied and no element satisfies it.
     * @remarks The entire sequence is enumerated to locate the final match.
     */
    last(predicate?: Predicate<TElement>): TElement;
    /**
     * Returns the last element that satisfies the provided type guard, or `null` when no such element exists.
     * @template TFiltered Subtype confirmed by the type guard.
     * @param predicate Type guard evaluated against each element. Every matching element becomes a candidate, and the final match is returned.
     * @returns {TFiltered | null} The last element that satisfies the type guard, or `null` when none match.
     * @remarks The entire sequence is enumerated to locate the final match. This overload never throws; it communicates absence through the `null` return value.
     * @example
     * ```typescript
     * const numbers = from([1, 2, 3, 4, 5]);
     * const lastElement = numbers.lastOrDefault();
     * console.log(lastElement); // 5
     *
     * const lastEven = numbers.lastOrDefault(x => x % 2 === 0);
     * console.log(lastEven); // 4
     *
     * const empty = from<number>([]);
     * const lastOfEmpty = empty.lastOrDefault();
     * console.log(lastOfEmpty); // null
     *
     * const noEvens = from([1, 3, 5]);
     * const lastEven2 = noEvens.lastOrDefault(x => x % 2 === 0);
     * console.log(lastEven2); // null
     * ```
     */
    lastOrDefault<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): TFiltered | null;
    /**
     * Returns the last element in the sequence or `null` when the sequence is empty or no element satisfies the predicate.
     * @param predicate Predicate evaluated against each element. When omitted, the last element of the sequence is returned.
     * @returns {TElement | null} The last element that satisfies the predicate, or `null` when no match is found.
     * @remarks The entire sequence is enumerated to locate the final match. This overload never throws; it communicates absence through the `null` return value.
     */
    lastOrDefault(predicate?: Predicate<TElement>): TElement | null;
    /**
     * Produces a projection from the sequence and a second sequence by matching elements that share an identical join key. Outer elements with no match are included once with `null` as the inner value.
     * @template TInner Type of elements within the inner sequence.
     * @template TKey Type of key produced by the key selectors.
     * @template TResult Type of element returned by {@link resultSelector}.
     * @param innerEnumerable Sequence whose elements are joined with the outer sequence.
     * @param outerKeySelector Selector that extracts the join key from each outer element.
     * @param innerKeySelector Selector that extracts the join key from each inner element.
     * @param resultSelector Projection that combines an outer element with a matching inner element. When no match exists, `null` is supplied as the inner value.
     * @param keyComparator Optional equality comparator used to match keys. Defaults to the library's standard equality comparison when omitted.
     * @returns {IEnumerable<TResult>} A sequence generated by applying {@link resultSelector} to each matching pair (and unmatched outer elements).
     * @remarks The inner sequence is fully enumerated to build an in-memory lookup before outer elements are processed. The outer sequence is then enumerated lazily and its original ordering is preserved. This is a left outer join.
     * @example
     * ```typescript
     * const schools = from([
     *   { id: 1, name: 'Elementary School' },
     *   { id: 2, name: 'High School' }
     * ]);
     * const students = from([
     *   { name: 'Dana', schoolId: 1 },
     *   { name: 'Sam', schoolId: 3 }
     * ]);
     *
     * const joined = schools.leftJoin(
     *   students,
     *   s => s.id,
     *   st => st.schoolId,
     *   (school, student) => ({ school: school.name, student: student?.name ?? null })
     * ).toArray();
     *
     * console.log(joined);
     * // [
     * //   { school: 'Elementary School', student: 'Dana' },
     * //   { school: 'High School', student: null }
     * // ]
     * ```
     */
    leftJoin<TInner, TKey, TResult>(innerEnumerable: IEnumerable<TInner>, outerKeySelector: Selector<TElement, TKey>, innerKeySelector: Selector<TInner, TKey>, resultSelector: JoinSelector<TElement, TInner, TResult>, keyComparator?: EqualityComparator<TKey>): IEnumerable<TResult>;
    /**
     * Returns the largest numeric value produced for the elements in the sequence.
     * @param selector Optional projection that extracts the numeric value for each element. Defaults to the element itself.
     * @returns {number} The maximum of the projected values.
     * @throws {NoElementsException} Thrown when the sequence is empty.
     * @remarks The entire sequence is enumerated exactly once. Provide a selector when the elements are not already numeric.
     * @example
     * ```typescript
     * const numbers = from([1, 5, 2, 4, 3]);
     * const maxNumber = numbers.max();
     * console.log(maxNumber); // 5
     *
     * const people = from([
     *   { name: 'Alice', age: 25 },
     *   { name: 'Bob', age: 30 },
     *   { name: 'Charlie', age: 28 },
     * ]);
     * const maxAge = people.max(p => p.age);
     * console.log(maxAge); // 30
     * ```
     */
    max(this: Iterable<number>): number;
    max(selector: Selector<TElement, number>): number;
    /**
     * Returns the element whose projected key is greatest according to the provided comparator.
     * @template TKey Type of key produced by {@link keySelector}.
     * @param keySelector Selector used to project each element to the key used for comparison.
     * @param comparator Optional order comparator used to compare keys. Defaults to the library's standard order comparison when omitted.
     * @returns {TElement} The element whose key is maximal.
     * @throws {NoElementsException} Thrown when the sequence is empty.
     * @remarks When multiple elements share the maximal key, the first such element in the sequence is returned.
     * @example
     * ```typescript
     * const people = from([
     *   { name: 'Alice', age: 25 },
     *   { name: 'Bob', age: 30 },
     *   { name: 'Charlie', age: 28 },
     * ]);
     * const oldestPerson = people.maxBy(p => p.age);
     * console.log(oldestPerson); // { name: 'Bob', age: 30 }
     * ```
     */
    maxBy<TKey>(keySelector: Selector<TElement, TKey>, comparator?: OrderComparator<TKey>): TElement;
    /**
     * Calculates the median of the numeric values produced by the sequence.
     * @param selector Optional projection that extracts the numeric value for each element. Defaults to treating the element itself as numeric.
     * @param tie Determines how the median is resolved when the sequence contains an even number of elements. Defaults to `"interpolate"`, which averages the two central values. Specify `"low"` or `"high"` to select the lower or higher neighbour respectively.
     * @returns {number} The calculated median, or `NaN` when the sequence contains no elements.
     * @throws {unknown} Re-throws any error thrown while iterating the sequence or executing {@link selector}.
     * @remarks The sequence is enumerated once and buffered so a selection algorithm can locate the middle element(s) without fully sorting. Supply {@link selector} when the elements are not already numeric.
     * @example
     * ```typescript
     * const medianValue = from([1, 5, 2, 4, 3]).median();
     * console.log(medianValue); // 3
     *
     * const people = from([
     *   { name: 'Alice', age: 23 },
     *   { name: 'Bella', age: 21 },
     *   { name: 'Mirei', age: 22 },
     *   { name: 'Hanna', age: 20 },
     *   { name: 'Noemi', age: 29 }
     * ]);
     * const medianAge = people.median(p => p.age);
     * console.log(medianAge); // 22
     * ```
     */
    median(selector?: Selector<TElement, number>, tie?: MedianTieStrategy): number;
    /**
     * Returns the smallest numeric value produced for the elements in the sequence.
     * @param selector Optional projection that extracts the numeric value for each element. Defaults to the element itself.
     * @returns {number} The minimum of the projected values.
     * @throws {NoElementsException} Thrown when the sequence is empty.
     * @remarks The entire sequence is enumerated exactly once. Provide a selector when the elements are not already numeric.
     * @example
     * ```typescript
     * const numbers = from([3, 1, 5, 2, 4]);
     * const minNumber = numbers.min();
     * console.log(minNumber); // 1
     *
     * const people = from([
     *   { name: 'Alice', age: 25 },
     *   { name: 'Bob', age: 30 },
     *   { name: 'Charlie', age: 22 },
     * ]);
     * const minAge = people.min(p => p.age);
     * console.log(minAge); // 22
     * ```
     */
    min(this: Iterable<number>): number;
    min(selector: Selector<TElement, number>): number;
    /**
     * Returns the element whose projected key is smallest according to the provided comparator.
     * @template TKey Type of key produced by {@link keySelector}.
     * @param keySelector Selector used to project each element to the key used for comparison.
     * @param comparator Optional order comparator used to compare keys. Defaults to the library's standard order comparison when omitted.
     * @returns {TElement} The element whose key is minimal.
     * @throws {NoElementsException} Thrown when the sequence is empty.
     * @remarks When multiple elements share the minimal key, the first such element in the sequence is returned.
     * @example
     * ```typescript
     * const people = from([
     *   { name: 'Alice', age: 25 },
     *   { name: 'Bob', age: 30 },
     *   { name: 'Charlie', age: 22 },
     * ]);
     * const youngestPerson = people.minBy(p => p.age);
     * console.log(youngestPerson); // { name: 'Charlie', age: 22 }
     * ```
     */
    minBy<TKey>(keySelector: Selector<TElement, TKey>, comparator?: OrderComparator<TKey>): TElement;
    /**
     * Returns the element that appears most frequently in the sequence.
     * @template TKey Type of key produced by {@link keySelector}.
     * @param keySelector Optional selector that projects each element to the key used for frequency counting. Defaults to the element itself.
     * @returns {TElement} The first element whose occurrence count matches the maximum frequency.
     * @throws {NoElementsException} Thrown when the sequence is empty.
     * @throws {unknown} Re-throws any error thrown while iterating the sequence or executing {@link keySelector}.
     * @remarks The source sequence is fully enumerated to build frequency counts before the result is determined. When multiple keys share the same frequency, the earliest corresponding element is returned.
     * @example
     * ```typescript
     * const winner = from([1, 2, 2, 3]).mode();
     * console.log(winner); // 2
     * ```
     */
    mode<TKey>(keySelector?: Selector<TElement, TKey>): TElement;
    /**
     * Returns the element that appears most frequently in the sequence, or `null` when the sequence is empty.
     * @template TKey Type of key produced by {@link keySelector}.
     * @param keySelector Optional selector that projects each element to the key used for frequency counting. Defaults to the element itself.
     * @returns {TElement | null} The first most frequent element, or `null` when the sequence contains no elements.
     * @throws {unknown} Re-throws any error thrown while iterating the sequence or executing {@link keySelector}.
     * @remarks Unlike {@link mode}, this overload communicates the absence of elements by returning `null`. When multiple keys share the maximum frequency, the element that appears first is returned.
     * @example
     * ```typescript
     * const winner = from<number>([]).modeOrDefault();
     * console.log(winner); // null
     * ```
     */
    modeOrDefault<TKey>(keySelector?: Selector<TElement, TKey>): TElement | null;
    /**
     * Produces the elements whose occurrence count is tied for the highest frequency in the sequence.
     * @template TKey Type of key produced by {@link keySelector}.
     * @param keySelector Optional selector that projects each element to the key used for frequency counting. Defaults to the element itself.
     * @returns {IEnumerable<TElement>} A deferred sequence containing one representative element for each frequency mode.
     * @throws {unknown} Re-throws any error thrown while iterating the sequence or executing {@link keySelector}.
     * @remarks Enumeration of the result buffers the entire source to compute frequency counts before yielding results. When multiple elements share a key, only the first occurrence is emitted.
     * @example
     * ```typescript
     * const modes = from([1, 2, 2, 3, 3]).multimode().toArray();
     * console.log(modes); // [2, 3]
     * ```
     */
    multimode<TKey>(keySelector?: Selector<TElement, TKey>): IEnumerable<TElement>;
    /**
     * Determines whether the sequence contains no elements that satisfy the optional predicate.
     * @param predicate Optional predicate evaluated against each element. When omitted, the method returns `true` if the sequence is empty.
     * @returns {boolean} `true` when no element satisfies the predicate (or when the sequence is empty and no predicate is provided); otherwise, `false`.
     * @remarks This is more efficient than negating `any` with a predicate because iteration stops as soon as a matching element is found.
     * @example
     * ```typescript
     * const numbers = from([1, 3, 5]);
     * const noEvens = numbers.none(x => x % 2 === 0);
     * console.log(noEvens); // true
     *
     * const mixedNumbers = from([1, 2, 3, 5]);
     * const noEvens2 = mixedNumbers.none(x => x % 2 === 0);
     * console.log(noEvens2); // false
     * ```
     */
    none(predicate?: Predicate<TElement>): boolean;
    /**
     * Filters the sequence, keeping only elements assignable to the specified type.
     * @template TResult Type descriptor used to filter elements (constructor function or primitive type string).
     * @param type Type descriptor that determines which elements are retained.
     * @returns {IEnumerable<InferredType<TResult>>} A sequence containing only the elements that match the specified type.
     * @remarks This method performs a runtime type check for each element and yields matching elements lazily.
     * @example
     * ```typescript
     * const mixed = from([1, 'two', 3, 'four', new Date()]);
     * const numbers = mixed.ofType('number').toArray();
     * console.log(numbers); // [1, 3]
     *
     * const dates = mixed.ofType(Date).toArray();
     * console.log(dates); // [Date object]
     * ```
     */
    ofType<TResult extends ObjectType>(type: TResult): IEnumerable<InferredType<TResult>>;
    /**
     * Sorts the elements of the sequence in ascending order using the provided comparator.
     * @param comparator Optional order comparator used to compare elements. Defaults to the library's standard order comparison when omitted.
     * @returns {IOrderedEnumerable<TElement>} An ordered sequence sorted ascending.
     * @remarks Sorting is deferred; the sequence is ordered only when iterated. Use `thenBy`/`thenByDescending` on the returned sequence to specify secondary keys.
     * @example
     * ```typescript
     * const numbers = from([3, 1, 5, 2, 4]);
     * const sorted = numbers.order().toArray();
     * console.log(sorted); // [1, 2, 3, 4, 5]
     * ```
     */
    order(comparator?: OrderComparator<TElement>): IOrderedEnumerable<TElement>;
    /**
     * Sorts the elements of the sequence in ascending order based on keys projected from each element.
     * @template TKey Type of key produced by {@link keySelector}.
     * @param keySelector Selector used to project each element to the key used for ordering.
     * @param comparator Optional order comparator used to compare keys. Defaults to the library's standard order comparison when omitted.
     * @returns {IOrderedEnumerable<TElement>} An ordered sequence that preserves the original relative ordering of elements that share the same key.
     * @remarks Sorting is deferred; the sequence is ordered only when iterated. Use `thenBy`/`thenByDescending` on the returned sequence to specify secondary keys.
     * @example
     * ```typescript
     * const people = from([
     *   { name: 'Bob', age: 30 },
     *   { name: 'Alice', age: 25 },
     *   { name: 'Charlie', age: 22 },
     * ]);
     * const sorted = people.orderBy(p => p.age).toArray();
     * console.log(sorted);
     * // [
     * //   { name: 'Charlie', age: 22 },
     * //   { name: 'Alice', age: 25 },
     * //   { name: 'Bob', age: 30 }
     * // ]
     * ```
     */
    orderBy<TKey>(keySelector: Selector<TElement, TKey>, comparator?: OrderComparator<TKey>): IOrderedEnumerable<TElement>;
    /**
     * Sorts the elements of the sequence in descending order based on keys projected from each element.
     * @template TKey Type of key produced by {@link keySelector}.
     * @param keySelector Selector used to project each element to the key used for ordering.
     * @param comparator Optional order comparator used to compare keys. Defaults to the library's standard order comparison when omitted.
     * @returns {IOrderedEnumerable<TElement>} An ordered sequence that preserves the original relative ordering of elements that share the same key while ordering keys descending.
     * @remarks Sorting is deferred; the sequence is ordered only when iterated. Use `thenBy`/`thenByDescending` on the returned sequence to specify secondary keys.
     * @example
     * ```typescript
     * const people = from([
     *   { name: 'Charlie', age: 22 },
     *   { name: 'Alice', age: 25 },
     *   { name: 'Bob', age: 30 },
     * ]);
     * const sorted = people.orderByDescending(p => p.age).toArray();
     * console.log(sorted);
     * // [
     * //   { name: 'Bob', age: 30 },
     * //   { name: 'Alice', age: 25 },
     * //   { name: 'Charlie', age: 22 }
     * // ]
     * ```
     */
    orderByDescending<TKey>(keySelector: Selector<TElement, TKey>, comparator?: OrderComparator<TKey>): IOrderedEnumerable<TElement>;
    /**
     * Sorts the elements of the sequence in descending order using the provided comparator.
     * @param comparator Optional order comparator used to compare elements. Defaults to the library's standard order comparison when omitted.
     * @returns {IOrderedEnumerable<TElement>} An ordered sequence sorted descending.
     * @remarks Sorting is deferred; the sequence is ordered only when iterated. Use `thenBy`/`thenByDescending` on the returned sequence to specify secondary keys.
     * @example
     * ```typescript
     * const numbers = from([3, 1, 5, 2, 4]);
     * const sorted = numbers.orderDescending().toArray();
     * console.log(sorted); // [5, 4, 3, 2, 1]
     * ```
     */
    orderDescending(comparator?: OrderComparator<TElement>): IOrderedEnumerable<TElement>;
    /**
     * Creates a deferred sequence of adjacent element pairs.
     * @param resultSelector Optional projection applied to each current/next pair. Defaults to returning `[current, next]`.
     * @returns {IEnumerable<[TElement, TElement]>} A sequence with one element per consecutive pair from the source sequence.
     * @remarks The final element is omitted because it lacks a successor. The source sequence is enumerated lazily and only once.
     * @example
     * ```typescript
     * const numbers = from([1, 2, 3, 4]);
     * const pairs = numbers.pairwise().toArray();
     * console.log(pairs); // [[1, 2], [2, 3], [3, 4]]
     * ```
     */
    pairwise(resultSelector?: PairwiseSelector<TElement, TElement>): IEnumerable<[TElement, TElement]>;
    /**
     * Splits the sequence into two cached partitions by applying a type guard predicate.
     * @template TFiltered Type produced when {@link predicate} confirms the element.
     * @param predicate Type guard invoked for each element. Elements that satisfy the predicate populate the first partition.
     * @returns {[IEnumerable<TFiltered>, IEnumerable<Exclude<TElement, TFiltered>>]} A tuple containing the matching partition and the partition with the remaining elements.
     * @remarks The source is fully enumerated immediately and buffered so that both partitions can be iterated repeatedly without re-evaluating the predicate.
     * @example
     * ```typescript
     * const numbers = from([1, 2, 3, 4, 5, 6]);
     * const [evens, odds] = numbers.partition(x => x % 2 === 0);
     * console.log(evens.toArray()); // [2, 4, 6]
     * console.log(odds.toArray()); // [1, 3, 5]
     * ```
     */
    partition<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): [IEnumerable<TFiltered>, IEnumerable<Exclude<TElement, TFiltered>>];
    /**
     * Splits the sequence into two cached partitions by applying a boolean predicate.
     * @param predicate Predicate evaluated for each element. Elements for which it returns `true` populate the first partition.
     * @returns {[IEnumerable<TElement>, IEnumerable<TElement>]} A tuple containing the elements that satisfied the predicate and those that did not.
     * @remarks The source is fully enumerated immediately and buffered so that both partitions can be iterated repeatedly without re-evaluating the predicate.
     */
    partition(predicate: Predicate<TElement>): [IEnumerable<TElement>, IEnumerable<TElement>];
    /**
     * Calculates a percentile of the numeric values produced by the sequence.
     * @param percent Percentile expressed as a fraction between 0 and 1 where `0` corresponds to the minimum and `1` to the maximum.
     * @param selector Optional projection that extracts the numeric value for each element. Defaults to treating the element itself as numeric.
     * @param strategy Strategy that determines how fractional ranks are resolved. Defaults to `"linear"`, which interpolates between neighbouring values. Alternative strategies include `"nearest"`, `"low"`, `"high"`, and `"midpoint"`.
     * @returns {number} The percentile value, or `NaN` when the sequence contains no elements.
     * @throws {unknown} Re-throws any error thrown while iterating the sequence or executing {@link selector}.
     * @remarks The sequence is enumerated once and buffered so the selection algorithm can determine the requested rank without fully sorting the data. When {@link percent} falls outside `[0, 1]`, the result is clamped to the range implied by {@link strategy}.
     * @example
     * ```typescript
     * const upperQuartile = from([1, 2, 3, 4, 5]).percentile(0.75);
     * console.log(upperQuartile); // 4
     *
     * const responseTimes = from([
     *   { endpoint: '/users', duration: 120 },
     *   { endpoint: '/users', duration: 80 },
     *   { endpoint: '/users', duration: 200 }
     * ]);
     * const p95 = responseTimes.percentile(0.95, r => r.duration, "nearest");
     * console.log(p95); // 200
     * ```
     */
    percentile(this: Iterable<number>, percent: number, strategy?: PercentileStrategy): number;
    percentile(percent: number, selector: Selector<TElement, number>, strategy?: PercentileStrategy): number;
    /**
     * Generates permutations from the distinct elements of the sequence.
     * @param size Optional target length for each permutation. When omitted, permutations use all distinct elements of the source.
     * @returns {IEnumerable<IEnumerable<TElement>>} A lazy sequence of permutations, each materialised as an enumerable.
     * @throws {InvalidArgumentException} Thrown when {@link size} is less than 1 or greater than the number of distinct elements.
     * @remarks The source is enumerated to collect distinct elements before permutations are produced. Expect combinatorial growth in the number of permutations.
     * @example
     * ```typescript
     * const numbers = from([1, 2, 3]);
     * const perms = numbers.permutations(2);
     * console.log(perms.select(p => p.toArray()).toArray()); // [[1, 2], [1, 3], [2, 1], [2, 3], [3, 1], [3, 2]]
     * ```
     */
    permutations(size?: number): IEnumerable<IEnumerable<TElement>>;
    /**
     * Applies a user-defined pipeline to this sequence and returns the operator's result.
     * @template TResult Result type produced by {@link operator}.
     * @param operator Function that receives the enumerable view of this sequence and returns an arbitrary result.
     * @returns {TResult} The value produced by {@link operator} after optionally enumerating the sequence.
     * @throws {unknown} Re-throws any error thrown by {@link operator} or during enumeration initiated by the operator.
     * @remarks The operator controls when and how the sequence is iterated, enabling custom aggregations, projections, or interop with external APIs while preserving fluent syntax.
     * @example
     * ```typescript
     * const numbers = from([1, 2, 3, 4, 5]);
     * const sum = numbers.pipe(e => e.sum());
     * console.log(sum); // 15
     *
     * const filteredAndDoubled = numbers.pipe(e =>
     *   e.where(x => x % 2 === 0).select(x => x * 2).toArray()
     * );
     * console.log(filteredAndDoubled); // [4, 8]
     * ```
     */
    pipe<TResult>(operator: PipeOperator<TElement, TResult>): TResult;
    /**
     * Returns a deferred sequence that yields the supplied element before the source sequence.
     * @param element Element emitted before the original sequence.
     * @returns {IEnumerable<TElement>} A sequence that yields {@link element} followed by the source elements.
     * @remarks Enumeration is deferred; the source is not iterated until the resulting sequence is consumed.
     * @example
     * ```typescript
     * const numbers = from([1, 2, 3]);
     * const prepended = numbers.prepend(0).toArray();
     * console.log(prepended); // [0, 1, 2, 3]
     * ```
     */
    prepend(element: TElement): IEnumerable<TElement>;
    /**
     * Computes the multiplicative aggregate of the values produced for each element.
     * @param selector Optional projection that extracts the numeric value for each element. Defaults to interpreting the element itself as a number.
     * @returns {number} The product of all projected values.
     * @throws {NoElementsException} Thrown when the sequence is empty.
     * @remarks The source is enumerated exactly once. Supply {@link selector} when elements are not already numeric.
     * @example
     * ```typescript
     * const numbers = from([1, 2, 3, 4, 5]);
     * const result = numbers.product();
     * console.log(result); // 120
     *
     * const people = from([
     *   { name: 'Alice', age: 25 },
     *   { name: 'Bob', age: 30 },
     * ]);
     * const ageProduct = people.product(p => p.age);
     * console.log(ageProduct); // 750
     * ```
     */
    product(this: Iterable<number>): number;
    product(selector: Selector<TElement, number>): number;
    /**
     * Returns a deferred sequence that yields the source elements in reverse order.
     * @returns {IEnumerable<TElement>} A sequence that produces the elements of the source in reverse iteration order.
     * @remarks The implementation materialises the entire sequence into an array before emitting elements, so avoid using it on infinite sequences or when memory usage is a concern.
     * @example
     * ```typescript
     * const numbers = from([1, 2, 3, 4, 5]);
     * const reversed = numbers.reverse().toArray();
     * console.log(reversed); // [5, 4, 3, 2, 1]
     * ```
     */
    reverse(): IEnumerable<TElement>;
    /**
     * Produces a projection from the sequence and a second sequence by matching elements that share an identical join key. Inner elements with no match are included once with `null` as the outer value.
     * @template TInner Type of elements within the inner sequence.
     * @template TKey Type of key produced by the key selectors.
     * @template TResult Type of element returned by {@link resultSelector}.
     * @param innerEnumerable Sequence whose elements are joined with the outer sequence.
     * @param outerKeySelector Selector that extracts the join key from each outer element.
     * @param innerKeySelector Selector that extracts the join key from each inner element.
     * @param resultSelector Projection that combines an outer element with a matching inner element. When no match exists, `null` is supplied as the outer value.
     * @param keyComparator Optional equality comparator used to match keys. Defaults to the library's standard equality comparison when omitted.
     * @returns {IEnumerable<TResult>} A sequence generated by applying {@link resultSelector} to each matching pair (and unmatched inner elements).
     * @remarks The outer sequence is fully enumerated to build an in-memory lookup before inner elements are processed. The inner sequence is then enumerated lazily and its original ordering is preserved. This is a right outer join.
     * @example
     * ```typescript
     * const schools = from([
     *   { id: 1, name: 'Elementary School' },
     *   { id: 2, name: 'High School' }
     * ]);
     * const students = from([
     *   { name: 'Dana', schoolId: 1 },
     *   { name: 'Sam', schoolId: 3 }
     * ]);
     *
     * const joined = schools.rightJoin(
     *   students,
     *   s => s.id,
     *   st => st.schoolId,
     *   (school, student) => ({ school: school?.name ?? null, student: student.name })
     * ).toArray();
     *
     * console.log(joined);
     * // [
     * //   { school: 'Elementary School', student: 'Dana' },
     * //   { school: null, student: 'Sam' }
     * // ]
     * ```
     */
    rightJoin<TInner, TKey, TResult>(innerEnumerable: IEnumerable<TInner>, outerKeySelector: Selector<TElement, TKey>, innerKeySelector: Selector<TInner, TKey>, resultSelector: JoinSelector<TElement | null, TInner, TResult>, keyComparator?: EqualityComparator<TKey>): IEnumerable<TResult>;
    /**
     * Returns a deferred sequence that rotates the elements by the specified offset while preserving length.
     * @param shift Number of positions to rotate. Positive values move elements toward the end (left rotation); negative values move them toward the beginning (right rotation).
     * @returns {IEnumerable<TElement>} A sequence containing the same elements shifted by the requested amount.
     * @remarks The source is buffered sufficiently to honour the rotation. Rotation amounts larger than the sequence length are normalised by that length, so extremely large offsets may still require holding the entire sequence in memory.
     * @example
     * ```typescript
     * const numbers = from([1, 2, 3, 4, 5]);
     * const rotated = numbers.rotate(2).toArray();
     * console.log(rotated); // [3, 4, 5, 1, 2]
     *
     * const rotatedNegative = numbers.rotate(-2).toArray();
     * console.log(rotatedNegative); // [4, 5, 1, 2, 3]
     * ```
     */
    rotate(shift: number): IEnumerable<TElement>;
    /**
     * Produces a running aggregate of the sequence and yields each intermediate accumulator.
     * @template TAccumulate Result type produced by {@link accumulator}. Defaults to `TElement` when {@link seed} is omitted.
     * @param accumulator Function that combines the current accumulator value with the next element to produce the next accumulator.
     * @param seed Optional initial accumulator. When omitted, the first element becomes the initial accumulator and is emitted as the first result.
     * @returns {IEnumerable<TAccumulate>} A deferred sequence containing every intermediate accumulator produced by {@link accumulator}.
     * @throws {NoElementsException} Thrown when the sequence is empty and {@link seed} is not provided.
     * @remarks The source is enumerated exactly once. When {@link seed} is supplied, it is not emitted; only accumulator results appear in the output.
     * @example
     * ```typescript
     * const numbers = from([1, 2, 3, 4, 5]);
     * const runningTotal = numbers.scan((acc, x) => acc + x).toArray();
     * console.log(runningTotal); // [1, 3, 6, 10, 15]
     * ```
     */
    scan(accumulator: Accumulator<TElement, TElement>): IEnumerable<TElement>;
    scan<TAccumulate>(accumulator: Accumulator<TElement, TAccumulate>, seed: TAccumulate): IEnumerable<TAccumulate>;
    /**
     * Projects each element and its zero-based index into a new form.
     * @template TResult Result type produced by {@link selector}.
     * @param selector Projection invoked for each element together with its index.
     * @returns {IEnumerable<TResult>} A deferred sequence containing the values produced by {@link selector}.
     * @remarks Enumeration is deferred. The index argument increments sequentially starting at zero.
     * @example
     * ```typescript
     * const numbers = from([1, 2, 3, 4, 5]);
     * const squares = numbers.select(x => x * x).toArray();
     * console.log(squares); // [1, 4, 9, 16, 25]
     * ```
     */
    select<TResult>(selector: IndexedSelector<TElement, TResult>): IEnumerable<TResult>;
    /**
     * Projects each element and index into an iterable and flattens the results into a single sequence.
     * @template TResult Element type of the flattened sequence.
     * @param selector Projection that returns an iterable for each element and its index.
     * @returns {IEnumerable<TResult>} A deferred sequence containing the concatenated contents of the iterables produced by {@link selector}.
     * @remarks Each inner iterable is enumerated in order before moving to the next source element. Use this to expand one-to-many relationships.
     * @example
     * ```typescript
     * const lists = from([[1, 2], [3, 4], [5]]);
     * const flattened = lists.selectMany(x => x).toArray();
     * console.log(flattened); // [1, 2, 3, 4, 5]
     * ```
     */
    selectMany<TResult>(selector: IndexedSelector<TElement, Iterable<TResult>>): IEnumerable<TResult>;
    /**
     * Determines whether the sequence and another iterable contain equal elements in the same order.
     * @param iterable The iterable to compare against the source sequence.
     * @param comparator Optional equality comparator used to compare element pairs. Defaults to the library's standard equality comparator.
     * @returns {boolean} `true` when both sequences have the same length and all corresponding elements are equal; otherwise, `false`.
     * @remarks Enumeration stops as soon as a mismatch or length difference is observed. Both sequences are fully enumerated only when they are equal.
     * @example
     * ```typescript
     * const numbers1 = from([1, 2, 3]);
     * const numbers2 = [1, 2, 3];
     * const numbers3 = [1, 2, 4];
     *
     * const areEqual1 = numbers1.sequenceEqual(numbers2);
     * console.log(areEqual1); // true
     *
     * const areEqual2 = numbers1.sequenceEqual(numbers3);
     * console.log(areEqual2); // false
     * ```
     */
    sequenceEqual(iterable: Iterable<TElement>, comparator?: EqualityComparator<TElement>): boolean;
    /**
     * Returns a deferred sequence whose elements appear in random order.
     * @returns {IEnumerable<TElement>} A sequence containing the same elements as the source but shuffled.
     * @remarks The implementation materialises all elements into an array before shuffling, making this unsuitable for infinite sequences.
     * @example
     * ```typescript
     * const numbers = from([1, 2, 3, 4, 5]);
     * const shuffled = numbers.shuffle().toArray();
     * console.log(shuffled); // e.g., [3, 1, 5, 2, 4]
     * ```
     */
    shuffle(): IEnumerable<TElement>;
    /**
     * Returns the only element that satisfies the provided type guard predicate.
     * @template TFiltered extends TElement Narrowed element type produced when {@link predicate} returns `true`.
     * @param predicate Type guard evaluated for each element. The returned value is narrowed to `TFiltered`.
     * @returns {TFiltered} The single element that satisfies {@link predicate}.
     * @throws {NoElementsException} Thrown when the sequence is empty.
     * @throws {NoMatchingElementException} Thrown when no element satisfies {@link predicate}.
     * @throws {MoreThanOneMatchingElementException} Thrown when more than one element satisfies {@link predicate}.
     * @remarks The source is fully enumerated to ensure exactly one matching element exists.
     * @example
     * ```typescript
     * const numbers = from([5]);
     * const singleElement = numbers.single();
     * console.log(singleElement); // 5
     *
     * const numbers2 = from([1, 2, 3, 4, 5]);
     * const singleEven = numbers2.single(x => x > 4);
     * console.log(singleEven); // 5
     * ```
     */
    single<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): TFiltered;
    /**
     * Returns the only element in the sequence or the only element that satisfies an optional predicate.
     * @param predicate Optional predicate evaluated for each element. When provided, the result must be the unique element for which it returns `true`.
     * @returns {TElement} The single element in the sequence or the single element that satisfies {@link predicate}.
     * @throws {NoElementsException} Thrown when the sequence is empty.
     * @throws {MoreThanOneElementException} Thrown when more than one element exists and {@link predicate} is omitted.
     * @throws {NoMatchingElementException} Thrown when {@link predicate} is provided and no element satisfies it.
     * @throws {MoreThanOneMatchingElementException} Thrown when {@link predicate} is provided and more than one element satisfies it.
     * @remarks The source is fully enumerated to validate uniqueness.
     */
    single(predicate?: Predicate<TElement>): TElement;
    /**
     * Returns the only element that satisfies the provided type guard predicate, or `null` when no such element exists.
     * @template TFiltered extends TElement Narrowed element type produced when {@link predicate} returns `true`.
     * @param predicate Type guard evaluated for each element. The returned value is narrowed to `TFiltered` when not `null`.
     * @returns {TFiltered | null} The single matching element, or `null` when no element satisfies {@link predicate}.
     * @throws {MoreThanOneMatchingElementException} Thrown when more than one element satisfies {@link predicate}.
     * @remarks The source is fully enumerated to confirm uniqueness of the matching element.
     * @example
     * ```typescript
     * const numbers = from([5]);
     * const singleElement = numbers.singleOrDefault();
     * console.log(singleElement); // 5
     *
     * const numbers2 = from([1, 2, 3, 4, 5]);
     * const singleEven = numbers2.singleOrDefault(x => x > 4);
     * console.log(singleEven); // 5
     *
     * const empty = from<number>([]);
     * const singleOfEmpty = empty.singleOrDefault();
     * console.log(singleOfEmpty); // null
     *
     * const noMatch = from([1, 2, 3]);
     * const singleNoMatch = noMatch.singleOrDefault(x => x > 4);
     * console.log(singleNoMatch); // null
     * ```
     */
    singleOrDefault<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): TFiltered | null;
    /**
     * Returns the only element in the sequence or the only element that satisfies an optional predicate, or `null` when no such element exists.
     * @param predicate Optional predicate evaluated for each element. When provided, the result must be the unique element for which it returns `true`.
     * @returns {TElement | null} The single element or matching element, or `null` when no element satisfies the conditions.
     * @throws {MoreThanOneElementException} Thrown when more than one element exists and {@link predicate} is omitted.
     * @throws {MoreThanOneMatchingElementException} Thrown when {@link predicate} is provided and more than one element satisfies it.
     * @remarks The source is fully enumerated. Unlike {@link single}, this method returns `null` instead of throwing when no matching element is found.
     */
    singleOrDefault(predicate?: Predicate<TElement>): TElement | null;
    /**
     * Skips a specified number of elements before yielding the remainder of the sequence.
     * @param count Number of elements to bypass. Values less than or equal to zero result in no elements being skipped.
     * @returns {IEnumerable<TElement>} A deferred sequence containing the elements that remain after skipping {@link count} items.
     * @remarks Enumeration is deferred. Only the skipped prefix is traversed without yielding.
     * @example
     * ```typescript
     * const numbers = from([1, 2, 3, 4, 5]);
     * const skipped = numbers.skip(2).toArray();
     * console.log(skipped); // [3, 4, 5]
     * ```
     */
    skip(count: number): IEnumerable<TElement>;
    /**
     * Omits a specified number of elements from the end of the sequence.
     * @param count Number of trailing elements to exclude. Values less than or equal to zero leave the sequence unchanged.
     * @returns {IEnumerable<TElement>} A deferred sequence excluding the last {@link count} elements.
     * @remarks The implementation buffers up to {@link count} elements to determine which items to drop, which can increase memory usage for large values.
     * @example
     * ```typescript
     * const numbers = from([1, 2, 3, 4, 5]);
     * const skipped = numbers.skipLast(2).toArray();
     * console.log(skipped); // [1, 2, 3]
     * ```
     */
    skipLast(count: number): IEnumerable<TElement>;
    /**
     * Skips elements until a type guard predicate returns `true`, then yields that element and the remainder, narrowing the element type.
     * @template TFiltered extends TElement Result type produced when {@link predicate} returns `true`.
     * @param predicate Type guard invoked for each element and its zero-based index; once it returns `true`, that element and all following elements are yielded.
     * @returns {IEnumerable<TFiltered>} A deferred sequence starting with the first element that satisfies {@link predicate}.
     * @remarks The predicate runs until the first match is found; subsequent elements are yielded without further checks.
     * @example
     * ```typescript
     * const mixed: (number | string)[] = ['a', 'b', 1, 2];
     * const numbers = from(mixed).skipUntil((x): x is number => typeof x === 'number').toArray();
     * console.log(numbers); // [1, 2]
     * ```
     */
    skipUntil<TFiltered extends TElement>(predicate: IndexedTypePredicate<TElement, TFiltered>): IEnumerable<TFiltered>;
    /**
     * Skips elements until a predicate returns `true`, then yields that element and the remainder.
     * @param predicate Predicate receiving the element and its zero-based index; once it returns `true`, enumeration stops skipping.
     * @returns {IEnumerable<TElement>} A deferred sequence starting with the first element that satisfies {@link predicate}.
     * @remarks The predicate runs until the first match is found; subsequent elements are yielded without further checks.
     * @example
     * ```typescript
     * const numbers = from([0, 0, 1, 2, 3]);
     * const result = numbers.skipUntil((_, i) => i >= 2).toArray();
     * console.log(result); // [1, 2, 3]
     * ```
     */
    skipUntil(predicate: IndexedPredicate<TElement>): IEnumerable<TElement>;
    /**
     * Skips elements while a predicate returns `true` and then yields the remaining elements.
     * @param predicate Predicate receiving the element and its index. The first element for which it returns `false` is included in the result.
     * @returns {IEnumerable<TElement>} A deferred sequence starting with the first element that fails {@link predicate}.
     * @remarks The predicate receives a zero-based index that increments only while elements are being skipped.
     * @example
     * ```typescript
     * const numbers = from([1, 2, 3, 4, 5, 1, 2]);
     * const skipped = numbers.skipWhile(x => x < 4).toArray();
     * console.log(skipped); // [4, 5, 1, 2]
     * ```
     */
    skipWhile(predicate: IndexedPredicate<TElement>): IEnumerable<TElement>;
    /**
     * Splits the sequence into the maximal leading span that satisfies a type guard and the remaining elements.
     * @template TFiltered extends TElement Narrowed element type produced when {@link predicate} returns `true`.
     * @param predicate Type guard evaluated for each element until it first returns `false`.
     * @returns {[IEnumerable<TFiltered>, IEnumerable<TElement>]} A tuple containing the contiguous matching prefix and the remainder of the sequence.
     * @remarks The source is fully enumerated immediately and buffered so both partitions can be iterated repeatedly without re-evaluating {@link predicate}.
     * @example
     * ```typescript
     * const numbers = from([1, 2, 3, 4, 1, 2]);
     * const [first, second] = numbers.span(x => x < 3);
     * console.log(first.toArray()); // [1, 2]
     * console.log(second.toArray()); // [3, 4, 1, 2]
     * ```
     */
    span<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): [IEnumerable<TFiltered>, IEnumerable<TElement>];
    /**
     * Splits the sequence into the maximal leading span that satisfies a predicate and the remaining elements.
     * @param predicate Predicate evaluated for each element until it first returns `false`.
     * @returns {[IEnumerable<TElement>, IEnumerable<TElement>]} A tuple containing the contiguous matching prefix and the remainder of the sequence.
     * @remarks The source is fully enumerated immediately and buffered so both partitions can be iterated repeatedly without re-evaluating {@link predicate}.
     */
    span(predicate: Predicate<TElement>): [IEnumerable<TElement>, IEnumerable<TElement>];
    /**
     * Calculates the standard deviation of the numeric values produced by the sequence.
     * @param selector Optional projection that extracts the numeric value for each element. Defaults to the element itself.
     * @param sample When `true`, computes the sample standard deviation; when `false`, computes the population standard deviation. Defaults to `true`.
     * @returns {number} The calculated standard deviation, or `NaN` when there are insufficient values to compute it.
     * @throws {unknown} Re-throws any error thrown while iterating the sequence or executing {@link selector}.
     * @remarks This method delegates to {@link variance}; when the variance is `NaN`, that value is returned unchanged. The sequence is enumerated exactly once using a numerically stable single-pass algorithm.
     * @example
     * ```typescript
     * const populationStdDev = from([1, 2, 3, 4, 5]).standardDeviation(x => x, false);
     * console.log(populationStdDev); // Math.sqrt(2)
     * ```
     */
    standardDeviation(selector?: Selector<TElement, number>, sample?: boolean): number;
    /**
     * Returns every n-th element of the sequence, starting with the first.
     * @param step Positive interval indicating how many elements to skip between yielded items.
     * @returns {IEnumerable<TElement>} A deferred sequence containing elements whose zero-based index is divisible by {@link step}.
     * @throws {InvalidArgumentException} Thrown when {@link step} is less than 1.
     * @remarks The source is enumerated exactly once; elements that are not yielded are still visited.
     * @example
     * ```typescript
     * const numbers = from([1, 2, 3, 4, 5, 6, 7, 8, 9]);
     * const stepped = numbers.step(3).toArray();
     * console.log(stepped); // [1, 4, 7]
     * ```
     */
    step(step: number): IEnumerable<TElement>;
    /**
     * Computes the sum of the numeric values produced for each element.
     * @param selector Optional projection that extracts the numeric value. Defaults to interpreting the element itself as a number.
     * @returns {number} The sum of the projected values.
     * @throws {NoElementsException} Thrown when the sequence is empty.
     * @remarks The source is enumerated exactly once. Supply {@link selector} when elements are not already numeric.
     * @example
     * ```typescript
     * const numbers = from([1, 2, 3, 4, 5]);
     * const total = numbers.sum();
     * console.log(total); // 15
     *
     * const people = from([
     *   { name: 'Alice', age: 25 },
     *   { name: 'Bob', age: 30 },
     * ]);
     * const totalAge = people.sum(p => p.age);
     * console.log(totalAge); // 55
     * ```
     */
    sum(this: Iterable<number>): number;
    sum(selector: Selector<TElement, number>): number;
    /**
     * Returns up to the specified number of leading elements.
     * @param count Number of elements to emit; values less than or equal to zero produce an empty sequence.
     * @returns {IEnumerable<TElement>} A deferred sequence containing at most {@link count} elements from the start of the source.
     * @remarks Enumeration stops once {@link count} elements have been yielded or the source sequence ends.
     * @example
     * ```typescript
     * const numbers = from([1, 2, 3, 4, 5]);
     * const firstTwo = numbers.take(2).toArray();
     * console.log(firstTwo); // [1, 2]
     *
     * const emptyTake = numbers.take(0).toArray();
     * console.log(emptyTake); // []
     * ```
     */
    take(count: number): IEnumerable<TElement>;
    /**
     * Returns up to the specified number of trailing elements.
     * @param count Number of elements to keep from the end; values less than or equal to zero produce an empty sequence.
     * @returns {IEnumerable<TElement>} A deferred sequence containing at most {@link count} elements from the end of the source.
     * @remarks The implementation buffers up to {@link count} elements to determine the tail, so memory usage grows with {@link count}. The source must be finite.
     * @example
     * ```typescript
     * const numbers = from([1, 2, 3, 4, 5]);
     * const lastTwo = numbers.takeLast(2).toArray();
     * console.log(lastTwo); // [4, 5]
     *
     * const emptyTakeLast = numbers.takeLast(0).toArray();
     * console.log(emptyTakeLast); // []
     * ```
     */
    takeLast(count: number): IEnumerable<TElement>;
    /**
     * Returns consecutive leading elements until a type guard predicate returns `true`, then stops.
     * @template TFiltered extends TElement Result type produced when {@link predicate} returns `true`.
     * @param predicate Type guard invoked for each element and its zero-based index; iteration halts immediately when it returns `true`.
     * @returns {IEnumerable<TFiltered>} A deferred sequence containing the contiguous prefix produced before {@link predicate} succeeds.
     * @remarks Elements after the first element satisfying {@link predicate} are not inspected.
     * @example
     * ```typescript
     * const mixed: (number | string)[] = [1, 2, 'stop', 3];
     * const beforeStop = from(mixed).takeUntil((x): x is string => typeof x === 'string').toArray();
     * console.log(beforeStop); // [1, 2]
     * ```
     */
    takeUntil<TFiltered extends TElement>(predicate: IndexedTypePredicate<TElement, TFiltered>): IEnumerable<TFiltered>;
    /**
     * Returns consecutive leading elements until a predicate returns `true`, then stops.
     * @param predicate Predicate invoked for each element and its zero-based index; iteration halts immediately when it returns `true`.
     * @returns {IEnumerable<TElement>} A deferred sequence containing the contiguous prefix produced before {@link predicate} succeeds.
     * @remarks Elements after the first element satisfying {@link predicate} are not inspected.
     * @example
     * ```typescript
     * const numbers = from([1, 2, 3, 4, 5]);
     * const taken = numbers.takeUntil(x => x > 3).toArray();
     * console.log(taken); // [1, 2, 3]
     * ```
     */
    takeUntil(predicate: IndexedPredicate<TElement>): IEnumerable<TElement>;
    /**
     * Returns consecutive leading elements while a type guard predicate returns `true`, narrowing the element type.
     * @template TFiltered extends TElement Result type produced when {@link predicate} returns `true`.
     * @param predicate Type guard invoked for each element and its zero-based index; iteration stops immediately when it returns `false`.
     * @returns {IEnumerable<TFiltered>} A deferred sequence containing the contiguous prefix that satisfies {@link predicate}.
     * @remarks Elements after the first failing element are not inspected.
     * @example
     * ```typescript
     * const mixed: (number | string)[] = [1, 2, 'three', 4, 5];
     * const numbers = from(mixed).takeWhile((x): x is number => typeof x === 'number').toArray();
     * console.log(numbers); // [1, 2]
     * ```
     */
    takeWhile<TFiltered extends TElement>(predicate: IndexedTypePredicate<TElement, TFiltered>): IEnumerable<TFiltered>;
    /**
     * Returns consecutive leading elements while a predicate returns `true`.
     * @param predicate Predicate invoked for each element and its zero-based index; iteration stops immediately when it returns `false`.
     * @returns {IEnumerable<TElement>} A deferred sequence containing the contiguous prefix that satisfies {@link predicate}.
     * @remarks Elements after the first failing element are not inspected.
     * @example
     * ```typescript
     * const numbers = from([1, 2, 3, 4, 5, 1, 2]);
     * const taken = numbers.takeWhile(x => x < 4).toArray();
     * console.log(taken); // [1, 2, 3]
     *
     * const takenWithIndex = numbers.takeWhile((x, i) => i < 3).toArray();
     * console.log(takenWithIndex); // [1, 2, 3]
     * ```
     */
    takeWhile(predicate: IndexedPredicate<TElement>): IEnumerable<TElement>;
    /**
     * Invokes the specified action for each element while yielding the original elements unchanged.
     * @param action Callback receiving the element and its zero-based index.
     * @returns {IEnumerable<TElement>} The original sequence, enabling fluent chaining.
     * @remarks The action executes lazily as the sequence is iterated, making it suitable for logging or instrumentation.
     * @example
     * ```typescript
     * const numbers = from([1, 2, 3]);
     * const tapped = numbers
     *   .tap(x => console.log(`Processing: ${x}`))
     *   .select(x => x * 2)
     *   .toArray();
     * console.log(tapped); // [2, 4, 6]
     * // Expected console output:
     * // Processing: 1
     * // Processing: 2
     * // Processing: 3
     * ```
     */
    tap(action: IndexedAction<TElement>): IEnumerable<TElement>;
    /**
     * Materialises the sequence into an array.
     * @returns {TElement[]} An array containing all elements from the source sequence in iteration order.
     * @remarks The entire sequence is enumerated immediately. Subsequent changes to the source are not reflected in the returned array.
     * @example
     * ```typescript
     * const numbers = from([1, 2, 3]);
     * const array = numbers.toArray();
     * console.log(array); // [1, 2, 3]
     * ```
     */
    toArray(): TElement[];
    /**
     * Materialises the sequence into a circular linked list.
     * @param comparator Optional equality comparator used by the resulting list.
     * @returns {CircularLinkedList<TElement>} A circular linked list containing all elements from the source.
     * @remarks The entire sequence is enumerated immediately, and elements are stored in iteration order.
     * @example
     * ```typescript
     * const numbers = from([1, 2, 3]);
     * const circularList = numbers.toCircularLinkedList();
     * console.log(circularList.toArray()); // [1, 2, 3]
     * ```
     */
    toCircularLinkedList(comparator?: EqualityComparator<TElement>): CircularLinkedList<TElement>;
    /**
     * Materialises the sequence into a circular queue that uses the implementation's default capacity.
     * @param comparator Optional equality comparator used by the resulting queue.
     * @returns {CircularQueue<TElement>} A circular queue containing the most recent elements from the source, up to the default capacity.
     * @remarks The entire sequence is enumerated immediately. Once the queue reaches its capacity (currently 32), older items are discarded as new elements are enqueued.
     * @example
     * ```typescript
     * const numbers = from([1, 2, 3]);
     * const circularQueue = numbers.toCircularQueue();
     * console.log(circularQueue.toArray()); // [1, 2, 3]
     * ```
     */
    toCircularQueue(comparator?: EqualityComparator<TElement>): CircularQueue<TElement>;
    /**
     * Materialises the sequence into a circular queue with the specified capacity.
     * @param capacity Maximum number of elements retained by the resulting queue.
     * @param comparator Optional equality comparator used by the resulting queue.
     * @returns {CircularQueue<TElement>} A circular queue containing the most recent elements from the source, bounded by {@link capacity}.
     * @remarks The entire sequence is enumerated immediately. When the source contains more than {@link capacity} elements, earlier items are discarded.
     * @example
     * ```typescript
     * const numbers = from([1, 2, 3, 4, 5]);
     * const circularQueue = numbers.toCircularQueue(3);
     * console.log(circularQueue.toArray()); // [3, 4, 5]
     * ```
     */
    toCircularQueue(capacity: number, comparator?: EqualityComparator<TElement>): CircularQueue<TElement>;
    /**
     * Materialises the sequence into a dictionary keyed by the provided selector.
     * @template TKey Type of key returned by {@link keySelector}.
     * @template TValue Type of value returned by {@link valueSelector}.
     * @param keySelector Selector used to derive the key for each element.
     * @param valueSelector Selector used to derive the value for each element.
     * @param valueComparator Optional equality comparator used by the resulting dictionary to compare values.
     * @returns {Dictionary<TKey, TValue>} A dictionary populated with the projected key/value pairs.
     * @throws {InvalidArgumentException} Thrown when {@link keySelector} produces duplicate keys.
     * @remarks The entire sequence is enumerated immediately and entries are inserted in iteration order.
     * @example
     * ```typescript
     * const people = from([
     *   { id: 1, name: 'Alice' },
     *   { id: 2, name: 'Bob' },
     * ]);
     * const dictionary = people.toDictionary(p => p.id, p => p.name);
     * console.log(dictionary.get(1)); // 'Alice'
     * console.log(dictionary.get(2)); // 'Bob'
     * ```
     */
    toDictionary<TKey, TValue>(keySelector: Selector<TElement, TKey>, valueSelector: Selector<TElement, TValue>, valueComparator?: EqualityComparator<TValue>): Dictionary<TKey, TValue>;
    /**
     * Materialises the sequence into an enumerable set containing the distinct elements.
     * @returns {EnumerableSet<TElement>} A set populated with the distinct elements from the source.
     * @remarks The entire sequence is enumerated immediately and duplicate elements are collapsed using the set's equality semantics.
     * @example
     * ```typescript
     * const numbers = from([1, 2, 2, 3, 1]);
     * const set = numbers.toEnumerableSet();
     * console.log(set.toArray()); // [1, 2, 3]
     * ```
     */
    toEnumerableSet(): EnumerableSet<TElement>;
    /**
     * Materialises the sequence into an immutable circular queue that uses the implementation's default capacity.
     * @param comparator Optional equality comparator used by the resulting queue.
     * @returns {ImmutableCircularQueue<TElement>} An immutable circular queue containing the most recent elements from the source, up to the default capacity.
     * @remarks The entire sequence is enumerated immediately. Earlier items are discarded when the number of elements exceeds the queue's capacity (currently 32).
     * @example
     * ```typescript
     * const numbers = from([1, 2, 3]);
     * const immutableCircularQueue = numbers.toImmutableCircularQueue();
     * console.log(immutableCircularQueue.toArray()); // [1, 2, 3]
     * ```
     */
    toImmutableCircularQueue(comparator?: EqualityComparator<TElement>): ImmutableCircularQueue<TElement>;
    /**
     * Materialises the sequence into an immutable circular queue with the specified capacity.
     * @param capacity Maximum number of elements retained by the resulting queue.
     * @param comparator Optional equality comparator used by the resulting queue.
     * @returns {ImmutableCircularQueue<TElement>} An immutable circular queue containing the most recent elements from the source, bounded by {@link capacity}.
     * @remarks The entire sequence is enumerated immediately. When the source contains more than {@link capacity} elements, earlier items are discarded.
     * @example
     * ```typescript
     * const numbers = from([1, 2, 3, 4, 5]);
     * const immutableCircularQueue = numbers.toImmutableCircularQueue(3);
     * console.log(immutableCircularQueue.toArray()); // [3, 4, 5]
     * ```
     */
    toImmutableCircularQueue(capacity: number, comparator?: EqualityComparator<TElement>): ImmutableCircularQueue<TElement>;
    /**
     * Materialises the sequence into an immutable dictionary keyed by the provided selector.
     * @template TKey Type of key returned by {@link keySelector}.
     * @template TValue Type of value returned by {@link valueSelector}.
     * @param keySelector Selector used to derive the key for each element.
     * @param valueSelector Selector used to derive the value for each element.
     * @param valueComparator Optional equality comparator used by the resulting dictionary to compare values.
     * @returns {ImmutableDictionary<TKey, TValue>} An immutable dictionary populated with the projected key/value pairs.
     * @throws {InvalidArgumentException} Thrown when {@link keySelector} produces duplicate keys.
     * @remarks The entire sequence is enumerated immediately.
     * @example
     * ```typescript
     * const people = from([
     *   { id: 1, name: 'Alice' },
     *   { id: 2, name: 'Bob' },
     * ]);
     * const immutableDictionary = people.toImmutableDictionary(p => p.id, p => p.name);
     * console.log(immutableDictionary.get(1)); // 'Alice'
     * console.log(immutableDictionary.get(2)); // 'Bob'
     * ```
     */
    toImmutableDictionary<TKey, TValue>(keySelector: Selector<TElement, TKey>, valueSelector: Selector<TElement, TValue>, valueComparator?: EqualityComparator<TValue>): ImmutableDictionary<TKey, TValue>;
    /**
     * Materialises the sequence into an immutable list.
     * @param comparator Optional equality comparator used by the resulting list.
     * @returns {ImmutableList<TElement>} An immutable list containing all elements from the source in iteration order.
     * @remarks The entire sequence is enumerated immediately.
     * @example
     * ```typescript
     * const numbers = from([1, 2, 3]);
     * const immutableList = numbers.toImmutableList();
     * console.log(immutableList.toArray()); // [1, 2, 3]
     * ```
     */
    toImmutableList(comparator?: EqualityComparator<TElement>): ImmutableList<TElement>;
    /**
     * Materialises the sequence into an immutable priority queue.
     * @param comparator Optional order comparator used to compare elements in the resulting queue.
     * @returns {ImmutablePriorityQueue<TElement>} An immutable priority queue containing all elements from the source.
     * @remarks The entire sequence is enumerated immediately. Elements are ordered according to {@link comparator} or the default ordering.
     * @example
     * ```typescript
     * const numbers = from([3, 1, 4, 1, 5, 9, 2, 6]);
     * const immutablePriorityQueue = numbers.toImmutablePriorityQueue();
     * console.log(immutablePriorityQueue.toArray()); // [1, 1, 2, 3, 4, 5, 6, 9] (sorted)
     * ```
     */
    toImmutablePriorityQueue(comparator?: OrderComparator<TElement>): ImmutablePriorityQueue<TElement>;
    /**
     * Materialises the sequence into an immutable FIFO queue.
     * @param comparator Optional equality comparator used by the resulting queue.
     * @returns {ImmutableQueue<TElement>} An immutable queue containing all elements from the source in enqueue order.
     * @remarks The entire sequence is enumerated immediately.
     * @example
     * ```typescript
     * const numbers = from([1, 2, 3]);
     * const immutableQueue = numbers.toImmutableQueue();
     * console.log(immutableQueue.toArray()); // [1, 2, 3]
     * ```
     */
    toImmutableQueue(comparator?: EqualityComparator<TElement>): ImmutableQueue<TElement>;
    /**
     * Materialises the sequence into an immutable set containing the distinct elements.
     * @returns {ImmutableSet<TElement>} An immutable set built from the distinct elements of the source.
     * @remarks The entire sequence is enumerated immediately and duplicate elements are collapsed using the set's equality semantics.
     * @example
     * ```typescript
     * const numbers = from([1, 2, 2, 3, 1]);
     * const immutableSet = numbers.toImmutableSet();
     * console.log(immutableSet.toArray()); // [1, 2, 3]
     * ```
     */
    toImmutableSet(): ImmutableSet<TElement>;
    /**
     * Materialises the sequence into an immutable sorted dictionary keyed by the provided selector.
     * @template TKey Type of key returned by {@link keySelector}.
     * @template TValue Type of value returned by {@link valueSelector}.
     * @param keySelector Selector used to derive the key for each element.
     * @param valueSelector Selector used to derive the value for each element.
     * @param keyComparator Optional order comparator used to sort keys in the resulting dictionary.
     * @param valueComparator Optional equality comparator used to compare values in the resulting dictionary.
     * @returns {ImmutableSortedDictionary<TKey, TValue>} An immutable sorted dictionary populated with the projected key/value pairs.
     * @throws {InvalidArgumentException} Thrown when {@link keySelector} produces duplicate keys.
     * @remarks The entire sequence is enumerated immediately.
     * @example
     * ```typescript
     * const people = from([
     *   { id: 2, name: 'Bob' },
     *   { id: 1, name: 'Alice' },
     * ]);
     * const immutableSortedDictionary = people.toImmutableSortedDictionary(p => p.id, p => p.name);
     * console.log(immutableSortedDictionary.keys().toArray()); // [1, 2]
     * console.log(immutableSortedDictionary.get(1)); // 'Alice'
     * ```
     */
    toImmutableSortedDictionary<TKey, TValue>(keySelector: Selector<TElement, TKey>, valueSelector: Selector<TElement, TValue>, keyComparator?: OrderComparator<TKey>, valueComparator?: EqualityComparator<TValue>): ImmutableSortedDictionary<TKey, TValue>;
    /**
     * Materialises the sequence into an immutable sorted set of distinct elements.
     * @param comparator Optional order comparator used to sort the elements.
     * @returns {ImmutableSortedSet<TElement>} An immutable sorted set containing the distinct elements from the source.
     * @remarks The entire sequence is enumerated immediately and duplicate elements are collapsed using the set's ordering semantics.
     * @example
     * ```typescript
     * const numbers = from([3, 1, 4, 1, 5, 9, 2, 6]);
     * const immutableSortedSet = numbers.toImmutableSortedSet();
     * console.log(immutableSortedSet.toArray()); // [1, 2, 3, 4, 5, 6, 9]
     * ```
     */
    toImmutableSortedSet(comparator?: OrderComparator<TElement>): ImmutableSortedSet<TElement>;
    /**
     * Materialises the sequence into an immutable stack (LIFO).
     * @param comparator Optional equality comparator used by the resulting stack.
     * @returns {ImmutableStack<TElement>} An immutable stack whose top element corresponds to the last element of the source.
     * @remarks The entire sequence is enumerated immediately.
     * @example
     * ```typescript
     * const numbers = from([1, 2, 3]);
     * const immutableStack = numbers.toImmutableStack();
     * console.log(immutableStack.peek()); // 3
     * console.log(immutableStack.pop().peek()); // 2
     * ```
     */
    toImmutableStack(comparator?: EqualityComparator<TElement>): ImmutableStack<TElement>;
    /**
     * Materialises the sequence into a linked list.
     * @param comparator Optional equality comparator used by the resulting list.
     * @returns {LinkedList<TElement>} A linked list containing all elements from the source in iteration order.
     * @remarks The entire sequence is enumerated immediately.
     * @example
     * ```typescript
     * const numbers = from([1, 2, 3]);
     * const linkedList = numbers.toLinkedList();
     * console.log(linkedList.toArray()); // [1, 2, 3]
     * ```
     */
    toLinkedList(comparator?: EqualityComparator<TElement>): LinkedList<TElement>;
    /**
     * Materialises the sequence into a resizable list.
     * @param comparator Optional equality comparator used by the resulting list.
     * @returns {List<TElement>} A list containing all elements from the source in iteration order.
     * @remarks The entire sequence is enumerated immediately.
     * @example
     * ```typescript
     * const numbers = from([1, 2, 3]);
     * const list = numbers.toList();
     * console.log(list.toArray()); // [1, 2, 3]
     * ```
     */
    toList(comparator?: EqualityComparator<TElement>): List<TElement>;
    /**
     * Materialises the sequence into a lookup keyed by the provided selector.
     * @template TKey Type of key returned by {@link keySelector}.
     * @template TValue Type of value returned by {@link valueSelector}.
     * @param keySelector Selector used to derive the key for each element.
     * @param valueSelector Selector used to derive the value for each element.
     * @param keyComparator Optional order comparator used to compare keys in the resulting lookup.
     * @returns {ILookup<TKey, TValue>} A lookup grouping the projected values by key.
     * @remarks The entire sequence is enumerated immediately. Elements within each group preserve their original order and the groups are cached for repeated enumeration.
     * @example
     * ```typescript
     * const products = from([
     *   { name: 'Apple', category: 'Fruit' },
     *   { name: 'Banana', category: 'Fruit' },
     *   { name: 'Carrot', category: 'Vegetable' },
     * ]);
     * const lookup = products.toLookup(p => p.category, p => p.name);
     * console.log(lookup.get('Fruit').toArray()); // ['Apple', 'Banana']
     * console.log(lookup.get('Vegetable').toArray()); // ['Carrot']
     * ```
     */
    toLookup<TKey, TValue>(keySelector: Selector<TElement, TKey>, valueSelector: Selector<TElement, TValue>, keyComparator?: OrderComparator<TKey>): ILookup<TKey, TValue>;
    /**
     * Materialises the sequence into a `Map` keyed by the provided selector.
     * @template TKey Type of key returned by {@link keySelector}.
     * @template TValue Type of value returned by {@link valueSelector}.
     * @param keySelector Selector used to derive the key for each element.
     * @param valueSelector Selector used to derive the value for each element.
     * @returns {Map<TKey, TValue>} A map populated with the projected key/value pairs.
     * @remarks The entire sequence is enumerated immediately. When {@link keySelector} produces duplicate keys, later elements overwrite earlier entries.
     * @example
     * ```typescript
     * const people = from([
     *   { id: 1, name: 'Alice' },
     *   { id: 2, name: 'Bob' },
     * ]);
     * const map = people.toMap(p => p.id, p => p.name);
     * console.log(map.get(1)); // 'Alice'
     * console.log(map.get(2)); // 'Bob'
     * ```
     */
    toMap<TKey, TValue>(keySelector: Selector<TElement, TKey>, valueSelector: Selector<TElement, TValue>): Map<TKey, TValue>;
    /**
     * Materialises the sequence into a plain object keyed by the provided selector.
     * @template TKey extends string | number | symbol Property key type returned by {@link keySelector}.
     * @template TValue Type of value returned by {@link valueSelector}.
     * @param keySelector Selector used to derive the property key for each element.
     * @param valueSelector Selector used to derive the value for each element.
     * @returns {Record<TKey, TValue>} An object populated with the projected key/value pairs.
     * @remarks The entire sequence is enumerated immediately. When {@link keySelector} produces duplicate keys, later values overwrite earlier ones.
     * @example
     * ```typescript
     * const people = from([
     *   { id: 1, name: 'Alice' },
     *   { id: 2, name: 'Bob' },
     * ]);
     * const obj = people.toObject(p => p.id, p => p.name);
     * console.log(obj[1]); // 'Alice'
     * console.log(obj[2]); // 'Bob'
     * ```
     */
    toObject<TKey extends PropertyKey, TValue>(keySelector: Selector<TElement, TKey>, valueSelector: Selector<TElement, TValue>): Record<TKey, TValue>;
    /**
     * Materialises the sequence into a priority queue.
     * @param comparator Optional order comparator used to compare elements in the resulting queue.
     * @returns {PriorityQueue<TElement>} A priority queue containing all elements from the source.
     * @remarks The entire sequence is enumerated immediately. Elements are ordered according to {@link comparator} or the default ordering.
     * @example
     * ```typescript
     * const numbers = from([3, 1, 4, 1, 5, 9, 2, 6]);
     * const priorityQueue = numbers.toPriorityQueue();
     * console.log(priorityQueue.dequeue()); // 1
     * console.log(priorityQueue.dequeue()); // 1
     * ```
     */
    toPriorityQueue(comparator?: OrderComparator<TElement>): PriorityQueue<TElement>;
    /**
     * Materialises the sequence into a FIFO queue.
     * @param comparator Optional equality comparator used by the resulting queue.
     * @returns {Queue<TElement>} A queue containing all elements from the source in enqueue order.
     * @remarks The entire sequence is enumerated immediately.
     * @example
     * ```typescript
     * const numbers = from([1, 2, 3]);
     * const queue = numbers.toQueue();
     * console.log(queue.dequeue()); // 1
     * console.log(queue.dequeue()); // 2
     * ```
     */
    toQueue(comparator?: EqualityComparator<TElement>): Queue<TElement>;
    /**
     * Materialises the sequence into a native `Set`.
     * @returns {Set<TElement>} A set containing the distinct elements from the source.
     * @remarks The entire sequence is enumerated immediately and duplicate elements are collapsed using JavaScript's `SameValueZero` semantics.
     * @example
     * ```typescript
     * const numbers = from([1, 2, 2, 3, 1]);
     * const set = numbers.toSet();
     * console.log(Array.from(set)); // [1, 2, 3]
     * ```
     */
    toSet(): Set<TElement>;
    /**
     * Materialises the sequence into a sorted dictionary keyed by the provided selector.
     * @template TKey Type of key returned by {@link keySelector}.
     * @template TValue Type of value returned by {@link valueSelector}.
     * @param keySelector Selector used to derive the key for each element.
     * @param valueSelector Selector used to derive the value for each element.
     * @param keyComparator Optional order comparator used to sort keys in the resulting dictionary.
     * @param valueComparator Optional equality comparator used to compare values in the resulting dictionary.
     * @returns {SortedDictionary<TKey, TValue>} A sorted dictionary populated with the projected key/value pairs.
     * @throws {InvalidArgumentException} Thrown when {@link keySelector} produces duplicate keys.
     * @remarks The entire sequence is enumerated immediately.
     * @example
     * ```typescript
     * const people = from([
     *   { id: 2, name: 'Bob' },
     *   { id: 1, name: 'Alice' },
     * ]);
     * const sortedDictionary = people.toSortedDictionary(p => p.id, p => p.name);
     * console.log(sortedDictionary.keys().toArray()); // [1, 2]
     * console.log(sortedDictionary.get(1)); // 'Alice'
     * ```
     */
    toSortedDictionary<TKey, TValue>(keySelector: Selector<TElement, TKey>, valueSelector: Selector<TElement, TValue>, keyComparator?: OrderComparator<TKey>, valueComparator?: EqualityComparator<TValue>): SortedDictionary<TKey, TValue>;
    /**
     * Materialises the sequence into a sorted set of distinct elements.
     * @param comparator Optional order comparator used to sort the elements.
     * @returns {SortedSet<TElement>} A sorted set containing the distinct elements from the source.
     * @remarks The entire sequence is enumerated immediately and duplicate elements are collapsed using the set's ordering semantics.
     * @example
     * ```typescript
     * const numbers = from([3, 1, 4, 1, 5, 9, 2, 6]);
     * const sortedSet = numbers.toSortedSet();
     * console.log(sortedSet.toArray()); // [1, 2, 3, 4, 5, 6, 9]
     * ```
     */
    toSortedSet(comparator?: OrderComparator<TElement>): SortedSet<TElement>;
    /**
     * Materialises the sequence into a stack (LIFO).
     * @param comparator Optional equality comparator used by the resulting stack.
     * @returns {Stack<TElement>} A stack whose top element corresponds to the last element of the source.
     * @remarks The entire sequence is enumerated immediately.
     * @example
     * ```typescript
     * const numbers = from([1, 2, 3]);
     * const stack = numbers.toStack();
     * console.log(stack.peek()); // 3
     * console.log(stack.pop().peek()); // 2
     * ```
     */
    toStack(comparator?: EqualityComparator<TElement>): Stack<TElement>;
    /**
     * Creates a set-style union between this sequence and {@link iterable} using an equality comparator.
     * @param iterable Additional sequence whose elements are appended after the source when forming the union.
     * @param comparator Optional equality comparator that determines whether two elements are considered the same. Defaults to the library's standard equality comparator.
     * @returns {IEnumerable<TElement>} A deferred sequence containing the distinct elements from this sequence followed by elements from {@link iterable} that are not already present according to {@link comparator}.
     * @throws {unknown} Re-throws any error thrown while iterating either sequence or executing {@link comparator}.
     * @remarks Elements from the original sequence always appear before contributions from {@link iterable}. The method caches only the comparison keys needed to detect duplicates and enumerates each input at most once.
     * @example
     * ```typescript
     * const numbers1 = from([1, 2, 3, 4, 5]);
     * const numbers2 = [3, 5, 6, 7];
     * const unioned = numbers1.union(numbers2).toArray();
     * console.log(unioned); // [1, 2, 3, 4, 5, 6, 7]
     * ```
     */
    union(iterable: Iterable<TElement>, comparator?: EqualityComparator<TElement>): IEnumerable<TElement>;
    /**
     * Creates a set-style union between this sequence and {@link iterable} by comparing keys projected from each element.
     * @template TKey Type of key generated by {@link keySelector}.
     * @param iterable Additional sequence whose elements are appended after the source when forming the union.
     * @param keySelector Projection that produces a comparison key for each element.
     * @param comparator Optional equality comparator that determines whether two keys are considered the same. Defaults to the library's standard equality comparator.
     * @returns {IEnumerable<TElement>} A deferred sequence containing the distinct elements from this sequence followed by elements from {@link iterable} whose keys were not previously observed.
     * @throws {unknown} Re-throws any error thrown while iterating either sequence or executing {@link keySelector} or {@link comparator}.
     * @remarks Keys are buffered to ensure uniqueness while the elements themselves remain lazily produced. Provide {@link comparator} when keys require structural equality semantics.
     * @example
     * ```typescript
     * const products1 = from([
     *   { name: 'Apple', category: 'Fruit' },
     *   { name: 'Banana', category: 'Fruit' },
     * ]);
     * const products2 = [
     *   { name: 'Carrot', category: 'Vegetable' },
     *   { name: 'Apple', category: 'Fruit' },
     * ];
     *
     * const unioned = products1.unionBy(products2, p => p.category).toArray();
     * console.log(unioned);
     * // [
     * //   { name: 'Apple', category: 'Fruit' },
     * //   { name: 'Banana', category: 'Fruit' },
     * //   { name: 'Carrot', category: 'Vegetable' }
     * // ]
     * ```
     */
    unionBy<TKey>(iterable: Iterable<TElement>, keySelector: Selector<TElement, TKey>, comparator?: EqualityComparator<TKey>): IEnumerable<TElement>;
    /**
     * Calculates the variance of the numeric values produced by the sequence.
     * @param selector Optional projection that extracts the numeric value for each element. Defaults to the element itself.
     * @param sample When `true`, computes the sample variance dividing by _n - 1_; when `false`, computes the population variance dividing by _n_. Defaults to `true`.
     * @returns {number} The calculated variance, or `NaN` when the sequence is empty—or for sample variance when it contains a single element.
     * @throws {unknown} Re-throws any error thrown while iterating the sequence or executing {@link selector}.
     * @remarks A numerically stable single-pass algorithm (Welford's method) is used, so the source is enumerated exactly once regardless of size.
     * @example
     * ```typescript
     * const populationVariance = from([1, 2, 3, 4, 5]).variance(x => x, false);
     * console.log(populationVariance); // 2
     * ```
     */
    variance(selector?: Selector<TElement, number>, sample?: boolean): number;
    /**
     * Filters the sequence using a type guard predicate and narrows the resulting element type.
     * @template TFiltered extends TElement
     * @param predicate Type guard invoked with each element and its zero-based index. Return `true` to keep the element in the results.
     * @returns {IEnumerable<TFiltered>} A deferred sequence containing only elements that satisfy the type guard.
     * @throws {unknown} Re-throws any error thrown while iterating the source or executing {@link predicate}.
     * @remarks Enumeration is lazy; {@link predicate} executes on demand and may be invoked again if consumers restart iteration.
     * @example
     * ```typescript
     * const numbers = from([1, 2, 3, 4, 5]);
     * const evenNumbers = numbers.where(x => x % 2 === 0).toArray();
     * console.log(evenNumbers); // [2, 4]
     * ```
     */
    where<TFiltered extends TElement>(predicate: IndexedTypePredicate<TElement, TFiltered>): IEnumerable<TFiltered>;
    /**
     * Filters the sequence using a predicate that can inspect both the element and its position.
     * @param predicate Predicate invoked with each element and its zero-based index. Return `true` to keep the element in the results.
     * @returns {IEnumerable<TElement>} A deferred sequence containing only the elements that satisfy {@link predicate}.
     * @throws {unknown} Re-throws any error thrown while iterating the source or executing {@link predicate}.
     * @remarks Enumeration is lazy; {@link predicate} executes on demand and iteration stops as soon as the consumer stops reading.
     */
    where(predicate: IndexedPredicate<TElement>): IEnumerable<TElement>;
    /**
     * Produces a sequence of sliding windows of fixed size over the source sequence.
     * @param size Length of each window; must be at least 1.
     * @returns {IEnumerable<IEnumerable<TElement>>} A deferred sequence where each element exposes one contiguous window from the source.
     * @throws {InvalidArgumentException} Thrown when {@link size} is less than 1.
     * @throws {unknown} Re-throws any error thrown while iterating the source sequence.
     * @remarks Windows overlap and are yielded only after enough source elements are observed to fill {@link size}. Trailing partial windows are omitted.
     * @example
     * ```typescript
     * const numbers = from([1, 2, 3, 4, 5]);
     * const windows = numbers.windows(3);
     * console.log(windows.select(w => w.toArray()).toArray()); // [[1, 2, 3], [2, 3, 4], [3, 4, 5]]
     * ```
     */
    windows(size: number): IEnumerable<IEnumerable<TElement>>;
    /**
     * Combines this sequence with {@link iterable} and yields tuples of aligned elements.
     * @template TSecond Type of elements produced by {@link iterable}.
     * @param iterable The secondary sequence whose elements are paired with the source elements.
     * @returns {IEnumerable<[TElement, TSecond]>} A deferred sequence of `[source, other]` tuples truncated to the length of the shorter input.
     * @throws {unknown} Re-throws any error thrown while iterating either sequence.
     * @remarks Enumeration is lazy; pairs are produced on demand and iteration stops when either sequence completes. Use the overload that accepts a `zipper` when you need to project custom results.
     * @example
     * ```typescript
     * const numbers = from([1, 2, 3]);
     * const letters = ['a', 'b', 'c'];
     * const zipped = numbers.zip(letters).toArray();
     * console.log(zipped); // [[1, 'a'], [2, 'b'], [3, 'c']]
     *
     * const zippedWithSelector = numbers.zip(letters, (num, letter) => `${num}-${letter}`).toArray();
     * console.log(zippedWithSelector); // ['1-a', '2-b', '3-c']
     * ```
     */
    zip<TSecond>(iterable: Iterable<TSecond>): IEnumerable<[TElement, TSecond]>;
    /**
     * Combines this sequence with {@link iterable} and projects each aligned pair using {@link zipper}.
     * @template TSecond Type of elements produced by {@link iterable}.
     * @template TResult Result type produced by {@link zipper}.
     * @param iterable The secondary sequence whose elements are paired with the source elements.
     * @param zipper Projection invoked with each `[source, other]` pair to produce the resulting element.
     * @returns {IEnumerable<TResult>} A deferred sequence of projected results truncated to the length of the shorter input.
     * @throws {unknown} Re-throws any error thrown while iterating either sequence or executing {@link zipper}.
     * @remarks Enumeration is lazy; the `zipper` function executes on demand for each pair and iteration stops when either sequence completes.
     */
    zip<TSecond, TResult>(iterable: Iterable<TSecond>, zipper: Zipper<TElement, TSecond, TResult>): IEnumerable<TResult>;
    /**
     * Zips this sequence with the iterables supplied in {@link iterables}, producing aligned tuples.
     * @template TIterable Extends `readonly Iterable<unknown>[]`; the element type of each iterable contributes to the resulting tuple.
     * @param iterables Additional sequences to zip with the source.
     * @returns {IEnumerable<[TElement, ...UnpackIterableTuple<TIterable>]>} A deferred sequence of tuples truncated to the length of the shortest input.
     * @throws {unknown} Re-throws any error raised while iterating the source or any of the supplied iterables.
     * @remarks Iteration stops as soon as any participating iterable is exhausted. Tuple element types are inferred from the supplied iterables, preserving strong typing across the zipped result.
     * @example
     * ```typescript
     * const zipped = from([1, 2, 3]).zipMany(['A', 'B', 'C'], [true, false]).toArray();
     * console.log(zipped); // [[1, 'A', true], [2, 'B', false]]
     * ```
     */
    zipMany<TIterable extends readonly Iterable<unknown>[]>(...iterables: [...TIterable]): IEnumerable<[TElement, ...UnpackIterableTuple<TIterable>]>;
    /**
     * Zips this sequence with the iterables supplied in {@link iterablesAndZipper} and projects each tuple with {@link ZipManyZipper zipper}.
     * @template TIterable Extends `readonly Iterable<unknown>[]`; the element type of each iterable contributes to the zipper input tuple.
     * @template TResult Result type produced by {@link ZipManyZipper zipper}.
     * @param iterablesAndZipper The trailing argument may be a zipper invoked with each tuple to produce a projected result; preceding arguments are the iterables to zip with.
     * @returns {IEnumerable<TResult>} A deferred sequence of projected results truncated to the length of the shortest input.
     * @throws {unknown} Re-throws any error raised while iterating the source, the supplied iterables, or executing the zipper.
     * @remarks The zipper receives a readonly tuple `[source, ...others]` for each aligned set. Iteration stops as soon as any participating iterable is exhausted.
     * @example
     * ```typescript
     * const labels = from([1, 2, 3]).zipMany(
     *     ['A', 'B', 'C'],
     *     [true, true, false],
     *     ([num, letter, flag]) => `${num}${letter}-${flag ? "yes" : "no"}`
     * ).toArray();
     * console.log(labels); // ["1A-yes", "2B-yes", "3C-no"]
     * ```
     */
    zipMany<TIterable extends readonly Iterable<unknown>[], TResult>(...iterablesAndZipper: [...TIterable, ZipManyZipper<[TElement, ...UnpackIterableTuple<TIterable>], TResult>]): IEnumerable<TResult>;
}

export declare interface IGroup<TKey, TElement> extends IEnumerable<TElement> {
    readonly key: TKey;
    readonly source: IEnumerable<TElement>;
}

export declare interface IImmutableCollection<TElement> extends IReadonlyCollection<TElement> {
    /**
     * Adds the given element to this collection.
     * @param element The element that will be added to this collection.
     * @returns {IImmutableCollection} A new collection with the added element.
     */
    add(element: TElement): IImmutableCollection<TElement>;
    /**
     * Adds all elements from the provided collection to this collection.
     * @param collection The collection whose element will be added to this collection.
     * @returns {IImmutableCollection} A new collection with the added elements.
     */
    addAll<TSource extends TElement>(collection: Iterable<TSource>): IImmutableCollection<TElement>;
    /**
     * Removes all elements from this collection.
     * @returns {IImmutableCollection} An empty collection.
     */
    clear(): IImmutableCollection<TElement>;
    /**
     * Returns a new collection with the elements from the provided collection.
     * If the provided collection is empty, the same collection will be returned.
     * @param collection The collection whose elements will replace the current elements in this collection.
     * @returns {IImmutableCollection} A new collection with the elements from the provided collection.
     */
    reset<TSource extends TElement>(collection: Iterable<TSource>): IImmutableCollection<TElement>;
}

export declare interface IImmutableDictionary<TKey, TValue> extends IReadonlyDictionary<TKey, TValue> {
    readonly length: number;
    /**
     * Adds the specified key and value to the dictionary.
     * @param key The key of the element to add.
     * @param value The value of the element to add.
     * @returns {IImmutableDictionary} A new dictionary with the added key-value pair.
     */
    add(key: TKey, value: TValue): IImmutableDictionary<TKey, TValue>;
    /**
     * Removes all elements from this dictionary.
     * @returns {IImmutableDictionary} An empty dictionary.
     */
    clear(): IImmutableDictionary<TKey, TValue>;
    /**
     * Adds a value to the dictionary.
     * If the key already exists, the value associated with the key will be replaced by the new value.
     * @param key The key of the element to add or update.
     * @param value The value which will be added or updated.
     * @returns {IImmutableDictionary} A new dictionary with the added or updated key-value pair.
     */
    put(key: TKey, value: TValue): IImmutableDictionary<TKey, TValue>;
    /**
     * Removes the specified key and its associated value from this dictionary.
     * @param key They key whose itself and its associated value will be removed from the dictionary.
     * @returns {IImmutableDictionary} A new dictionary without the specified key-value pair.
     */
    remove(key: TKey): IImmutableDictionary<TKey, TValue>;
    /**
     * Sets the value of the given key.
     * @param key The key whose value will be set.
     * @param value The new value of the key
     * @returns {IImmutableDictionary} A new dictionary with the updated value.
     */
    set(key: TKey, value: TValue): IImmutableDictionary<TKey, TValue>;
}

export declare interface IList<TElement> extends IReadonlyList<TElement>, IRandomAccessCollection<TElement> {
    /**
     * Adds the given element to the specified index of this list.
     * @param element The element that will be added to this list.
     * @param index The index that the element will be added to.
     * @returns {boolean} true if the element is added to the list.
     * @throws {Error} If the index is out of bounds.
     */
    addAt(element: TElement, index: number): boolean;
    /**
     * Removes the element at the given index from this list.
     * @param index The index from which the element will be removed.
     * @returns The removed element.
     * @throws {Error} If the index is out of bounds.
     */
    removeAt(index: number): TElement;
    /**
     * Replaces the element at the given index with the given element.
     * @param {number} index The index at which the element will be replaced
     * @param element The element which will replace the element at the given index.
     * @returns The old replaced element
     * @throws {Error} If the index is out of bounds.
     */
    set(index: number, element: TElement): TElement;
    /**
     * Sorts the lists according to the specified comparator.
     * If not specified, the list will be sorted by using the natural ordering of the elements.
     * @param comparator The comparator used to compare the list elements.
     */
    sort(comparator?: OrderComparator<TElement>): void;
}

export declare interface ILookup<TKey, TElement> extends IEnumerable<IGroup<TKey, TElement>> {
    /**
     * Returns the collection of elements that has the specified key.
     * @param key The key of the desired group.
     * @returns The collection of elements that has the specified key.
     */
    get(key: TKey): IEnumerable<TElement>;
    /**
     * Determines whether a specified key exists in the ILookup<TKey, TElement>.
     * @param key The key to locate in the ILookup<TKey, TElement>.
     * @returns true if key is in the ILookup<TKey, TElement>; otherwise, false.
     */
    hasKey(key: TKey): boolean;
    /**
     * Gets the number of key/value collection pairs in the ILookup<TKey, TElement>.
     * @returns The number of key/value collection pairs in the ILookup<TKey, TElement>.
     */
    size(): number;
    /**
     * Gets the number of elements in the ILookup<TKey, TElement>.
     * @returns The number of elements in the ILookup<TKey, TElement>.
     */
    get length(): number;
}

/**
 * An immutable circular queue maintains a bounded history of elements. When the capacity is exceeded,
 * the oldest element is discarded and the queue keeps the most recent values.
 */
export declare class ImmutableCircularQueue<TElement> extends AbstractImmutableCollection<TElement> {
    #private;
    private constructor();
    static create<TElement>(): ImmutableCircularQueue<TElement>;
    static create<TElement>(capacity: number, comparator?: EqualityComparator<TElement>): ImmutableCircularQueue<TElement>;
    static create<TElement>(capacity: number, elements: Iterable<TElement>, comparator?: EqualityComparator<TElement>): ImmutableCircularQueue<TElement>;
    static create<TElement>(elements: Iterable<TElement>, comparator?: EqualityComparator<TElement>): ImmutableCircularQueue<TElement>;
    [Symbol.iterator](): Iterator<TElement>;
    /**
     * Adds the given element to this queue. If the queue is full, the oldest element is removed.
     * @param element The element that will be added to this queue.
     * @returns {ImmutableCircularQueue} A new queue with the added element.
     */
    add(element: TElement): ImmutableCircularQueue<TElement>;
    /**
     * Adds all elements from the provided collection to this queue.
     * Only the most recent elements up to the configured capacity are retained.
     * @param collection The collection whose elements will be added to this queue.
     * @returns {ImmutableCircularQueue} A new queue containing the retained elements.
     */
    addAll<TSource extends TElement>(collection: Iterable<TSource>): ImmutableCircularQueue<TElement>;
    /**
     * Removes all elements from this queue.
     * @returns {ImmutableCircularQueue} An empty queue that keeps the same capacity and comparator.
     */
    clear(): ImmutableCircularQueue<TElement>;
    /**
     * Removes the element at the front of this queue.
     * @returns {ImmutableCircularQueue} A new queue with the head removed.
     * @throws {NoElementsException} Thrown when the queue is empty.
     */
    dequeue(): ImmutableCircularQueue<TElement>;
    /**
     * Adds an element to the end of this queue. This method is equivalent to {@link add}.
     * @param element The element that will be added to this queue.
     * @returns {ImmutableCircularQueue} A new queue with the added element.
     */
    enqueue(element: TElement): ImmutableCircularQueue<TElement>;
    /**
     * Retrieves but does not remove the element at the beginning of the queue.
     * Unlike {@link peek}, this method throws an error if the queue is empty.
     * @returns {TElement} The head of the queue.
     * @throws {NoElementsException} If the queue is empty.
     */
    front(): TElement;
    isEmpty(): boolean;
    /**
     * Returns whether the queue has reached its capacity.
     * @returns {boolean} True if the queue is full, false otherwise.
     */
    isFull(): boolean;
    /**
     * Retrieves but does not remove the element at the beginning of the queue.
     * Unlike {@link front}, this method returns null if the queue is empty.
     * @returns {TElement | null} The head of the queue or null if the queue is empty.
     */
    peek(): TElement | null;
    /**
     * Removes the element at the beginning of the queue and returns the new queue.
     * Unlike {@link dequeue}, this method returns the existing queue if it is empty.
     * @returns {ImmutableCircularQueue} A new queue with the head removed, or this queue if it was empty.
     */
    poll(): ImmutableCircularQueue<TElement>;
    /**
     * Replaces all elements in this queue with the elements from the provided collection.
     * Only the most recent elements up to the configured capacity are retained.
     * @template TSource The type of elements in the collection.
     * @param collection The collection whose elements will replace the current elements.
     * @returns {ImmutableCircularQueue} A new queue containing only the elements from the provided collection, capped by the capacity.
     */
    reset<TSource extends TElement>(collection: Iterable<TSource>): ImmutableCircularQueue<TElement>;
    size(): number;
    /**
     * The maximum number of elements the queue can retain.
     */
    get capacity(): number;
    get comparator(): EqualityComparator<TElement>;
    get length(): number;
}

export declare class ImmutableDictionary<TKey, TValue> extends AbstractImmutableDictionary<TKey, TValue> {
    #private;
    private constructor();
    static create<TKey, TValue>(): ImmutableDictionary<TKey, TValue>;
    static create<TKey, TValue>(iterable: Iterable<KeyValuePair<TKey, TValue>>, valueComparator?: EqualityComparator<TValue>): ImmutableDictionary<TKey, TValue>;
    static create<TKey, TValue>(iterable: Iterable<[TKey, TValue]>, valueComparator?: EqualityComparator<TValue>): ImmutableDictionary<TKey, TValue>;
    static create<TKey, TValue>(iterable: Iterable<KeyValuePair<TKey, TValue>> | Iterable<[TKey, TValue]>, valueComparator?: EqualityComparator<TValue>): ImmutableDictionary<TKey, TValue>;
    [Symbol.iterator](): Iterator<KeyValuePair<TKey, TValue>>;
    add(key: TKey, value: TValue): ImmutableDictionary<TKey, TValue>;
    clear(): ImmutableDictionary<TKey, TValue>;
    containsKey(key: TKey): boolean;
    containsValue(value: TValue, comparator?: EqualityComparator<TValue>): boolean;
    entries(): IterableIterator<[TKey, TValue]>;
    get(key: TKey): TValue | null;
    keys(): ISet<TKey>;
    put(key: TKey, value: TValue): ImmutableDictionary<TKey, TValue>;
    remove(key: TKey): ImmutableDictionary<TKey, TValue>;
    set(key: TKey, value: TValue): ImmutableDictionary<TKey, TValue>;
    size(): number;
    values(): IImmutableCollection<TValue>;
    private getCopiedDictionary;
    get length(): number;
}

/**
 * An immutable binary heap that returns a new instance whenever it is modified.
 * By default, this heap behaves as a min-heap, but you can provide a custom comparator
 * to change the ordering (for example to create a max-heap).
 */
export declare class ImmutableHeap<TElement> extends AbstractImmutableCollection<TElement> {
    #private;
    private constructor();
    /**
     * Creates a new immutable heap.
     * @template TElement The type of elements stored in the heap.
     * @param iterable Optional source elements that will seed the heap.
     * @param comparator Optional comparator that controls the heap ordering.
     * @returns {ImmutableHeap<TElement>} A new heap instance containing the supplied elements.
     */
    static create<TElement>(iterable?: Iterable<TElement>, comparator?: OrderComparator<TElement>): ImmutableHeap<TElement>;
    [Symbol.iterator](): Iterator<TElement>;
    /**
     * Adds the given element to this heap.
     * @param element The element that will be added to this heap.
     * @returns {ImmutableHeap<TElement>} A new heap with the added element.
     */
    add(element: TElement): ImmutableHeap<TElement>;
    /**
     * Adds all elements from the provided collection to this heap.
     * @template TSource The type of elements in the collection.
     * @param collection The collection whose elements will be added to this heap.
     * @returns {ImmutableHeap<TElement>} A new heap with the added elements, or this heap if the collection was empty.
     */
    addAll<TSource extends TElement>(collection: Iterable<TSource>): ImmutableHeap<TElement>;
    /**
     * Removes all elements from this heap.
     * @returns {ImmutableHeap<TElement>} An empty heap with the same comparator.
     */
    clear(): ImmutableHeap<TElement>;
    /**
     * Checks if the heap contains the specified element.
     * @param element The element to locate.
     * @returns {boolean} True if the element is present; otherwise, false.
     */
    contains(element: TElement): boolean;
    /**
     * Checks if the heap contains all elements from the specified collection.
     * @template TSource The type of elements in the target collection.
     * @param collection The collection whose elements will be checked for membership.
     * @returns {boolean} True if all elements are present; otherwise, false.
     */
    containsAll<TSource extends TElement>(collection: Iterable<TSource>): boolean;
    /**
     * Determines whether the heap has no elements.
     * @returns {boolean} True if the heap is empty, false otherwise.
     */
    isEmpty(): boolean;
    /**
     * Retrieves but does not remove the element at the root of the heap.
     * @returns {TElement | null} The root element, or null if the heap is empty.
     */
    peek(): TElement | null;
    /**
     * Removes the element at the root of the heap.
     * @returns {ImmutableHeap<TElement>} A new heap without the root element, or this heap if it was empty.
     */
    poll(): ImmutableHeap<TElement>;
    /**
     * Removes the specified element from this heap.
     * @param element The element that will be removed.
     * @returns {ImmutableHeap<TElement>} A new heap without the element, or this heap if the element was not found.
     */
    remove(element: TElement): ImmutableHeap<TElement>;
    /**
     * Removes all elements from this heap that are contained in the specified collection.
     * @template TSource The type of elements that will be removed.
     * @param collection The collection of elements to remove.
     * @returns {ImmutableHeap<TElement>} A new heap without the specified elements, or this heap if no elements were removed.
     */
    removeAll<TSource extends TElement>(collection: Iterable<TSource>): ImmutableHeap<TElement>;
    /**
     * Removes all elements from this heap that satisfy the specified predicate.
     * @param predicate The predicate used to determine which elements should be removed.
     * @returns {ImmutableHeap<TElement>} A new heap without the matching elements, or this heap if no elements were removed.
     */
    removeIf(predicate: Predicate<TElement>): ImmutableHeap<TElement>;
    /**
     * Replaces all elements in this heap with the elements from the provided collection.
     * @template TSource The type of elements in the collection.
     * @param collection The collection whose elements will replace the current elements.
     * @returns {ImmutableHeap<TElement>} A new heap containing only the elements from the provided collection.
     */
    reset<TSource extends TElement>(collection: Iterable<TSource>): ImmutableHeap<TElement>;
    size(): number;
    /**
     * Gets the comparator that defines the ordering of the heap.
     * @returns {OrderComparator<TElement>} The comparator used by this heap.
     */
    get comparator(): OrderComparator<TElement>;
    get length(): number;
}

export declare class ImmutableList<TElement> extends AbstractRandomAccessImmutableCollection<TElement> implements IReadonlyList<TElement> {
    #private;
    private constructor();
    static create<TElement>(iterable?: Iterable<TElement>, comparator?: EqualityComparator<TElement>): ImmutableList<TElement>;
    [Symbol.iterator](): Iterator<TElement>;
    /**
     * Adds the given element to the end of this list.
     * @param element The element that will be added to this list.
     * @returns {ImmutableList} A new list with the added element.
     */
    add(element: TElement): ImmutableList<TElement>;
    /**
     * Adds all elements from the provided collection to this list.
     * @param collection The collection whose element will be added to this list.
     * @returns {ImmutableList} A new list with the added element.
     */
    addAll<TSource extends TElement>(collection: Iterable<TSource>): ImmutableList<TElement>;
    addAt(element: TElement, index: number): ImmutableList<TElement>;
    any(predicate?: Predicate<TElement>): boolean;
    /**
     * Removes all elements from this list.
     * @returns {ImmutableList} An empty list.
     */
    clear(): ImmutableList<TElement>;
    contains(element: TElement, comparator?: EqualityComparator<TElement>): boolean;
    containsAll<TSource extends TElement>(collection: Iterable<TSource>): boolean;
    count(predicate?: Predicate<TElement>): number;
    elementAt(index: number): TElement;
    elementAtOrDefault(index: number): TElement | null;
    entries(): IterableIterator<[number, TElement]>;
    first<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): TFiltered;
    first(predicate?: Predicate<TElement>): TElement;
    firstOrDefault<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): TFiltered | null;
    firstOrDefault(predicate?: Predicate<TElement>): TElement | null;
    get(index: number): TElement;
    /**
     * Returns a new list that contains the elements in the specified range.
     * @param index The index at which the range starts.
     * @param count The number of elements in the range.
     * @returns {ImmutableList} A new list that contains the elements in the specified range.
     */
    getRange(index: number, count: number): ImmutableList<TElement>;
    indexOf(element: TElement, comparator?: EqualityComparator<TElement>): number;
    last<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): TFiltered;
    last(predicate?: Predicate<TElement>): TElement;
    lastIndexOf(element: TElement, comparator?: EqualityComparator<TElement>): number;
    lastOrDefault<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): TFiltered | null;
    lastOrDefault(predicate?: Predicate<TElement>): TElement | null;
    /**
     * Removes the element at the given index from this list.
     * @param element The element that will be removed from the list.
     * @returns {ImmutableList} A new list without the specified element.
     */
    remove(element: TElement): ImmutableList<TElement>;
    /**
     * Removes all elements from this list that are contained in the specified collection.
     * @param collection The collection whose elements will be removed from this list.
     * @returns {ImmutableList} A new list without the elements in the specified collection.
     */
    removeAll<TSource extends TElement>(collection: Iterable<TSource>): ImmutableList<TElement>;
    /**
     * Removes the element at the given index from this list.
     * @param index The index from which the element will be removed.
     * @returns {ImmutableList} A new list without the element at the specified index.
     */
    removeAt(index: number): ImmutableList<TElement>;
    /**
     * Removes all elements from this list that satisfies the specified predicate.
     * @param predicate The predicate used to remove elements from this list.
     * @returns {ImmutableList} A new list without the elements that satisfies the specified predicate.
     */
    removeIf(predicate: Predicate<TElement>): ImmutableList<TElement>;
    /**
     * Replaces all elements in this list with the elements from the provided collection.
     * @template TSource The type of elements in the collection.
     * @param collection The collection whose elements will replace the current elements.
     * @returns {ImmutableList} A new list containing only the elements from the provided collection.
     */
    reset<TSource extends TElement>(collection: Iterable<TSource>): ImmutableList<TElement>;
    /**
     * Removes all elements from this list except the ones that are contained in the specified collection.
     * @param collection The collection whose elements will be retained in this list.
     * @returns {ImmutableList} A new list with only the elements in the specified collection.
     */
    retainAll<TSource extends TElement>(collection: Iterable<TSource>): ImmutableList<TElement>;
    /**
     * Replaces the element at the given index with the given element.
     * @param index The index at which the element will be replaced
     * @param element The element which will replace the element at the given index.
     * @returns {ImmutableList} A new list with the replaced element.
     */
    set(index: number, element: TElement): ImmutableList<TElement>;
    size(): number;
    /**
     * Sorts the list according to the specified comparator. The original list will not be modified.
     * @param comparator The comparator used to compare the list elements.
     * @returns {ImmutableList} A new list that is sorted according to the specified comparator.
     */
    sort(comparator?: OrderComparator<TElement>): ImmutableList<TElement>;
    get comparator(): EqualityComparator<TElement>;
    get length(): number;
}

export declare class ImmutablePriorityQueue<TElement> extends AbstractImmutableCollection<TElement> {
    #private;
    private constructor();
    /**
     * Creates a new immutable priority queue.
     * @template TElement The type of elements in the queue.
     * @param iterable An optional iterable to populate the queue with.
     * @param comparator An optional order comparator for the elements.
     * @returns {ImmutablePriorityQueue<TElement>} A new immutable priority queue.
     */
    static create<TElement>(iterable?: Iterable<TElement>, comparator?: OrderComparator<TElement>): ImmutablePriorityQueue<TElement>;
    [Symbol.iterator](): Iterator<TElement>;
    /**
     * Adds the given element to this priority queue.
     * @template TElement The type of elements in the queue.
     * @param element The element to add.
     * @returns {ImmutablePriorityQueue<TElement>} A new priority queue with the added element.
     */
    add(element: TElement): ImmutablePriorityQueue<TElement>;
    /**
     * Adds all elements from the provided collection to this priority queue.
     * @template TElement The type of elements in the queue.
     * @template TSource The type of elements in the collection.
     * @param collection The collection whose elements will be added.
     * @returns {ImmutablePriorityQueue<TElement>} A new priority queue with the added elements.
     */
    addAll<TSource extends TElement>(collection: Iterable<TSource>): ImmutablePriorityQueue<TElement>;
    /**
     * Removes all elements from this priority queue.
     * @returns {ImmutablePriorityQueue<TElement>} An empty priority queue with the same comparator.
     */
    clear(): ImmutablePriorityQueue<TElement>;
    /**
     * Checks if the priority queue contains the specified element.
     * Note: This operation can be inefficient on a heap (O(N)).
     * @param element The element to locate.
     * @returns {boolean} True if the element is found; otherwise, false.
     */
    contains(element: TElement): boolean;
    /**
     * Checks if this collection contains all the elements of the given collection.
     * Note: This operation can be inefficient on a heap (O(N*M)).
     * @param collection The collection whose elements will be tested for existence.
     * @returns {boolean} True if this collection contains all the elements, false otherwise.
     */
    containsAll<TSource extends TElement>(collection: Iterable<TSource>): boolean;
    /**
     * Removes the element with the highest priority from the queue.
     * @returns {ImmutablePriorityQueue<TElement>} A new priority queue with the highest priority element removed.
     * @throws {NoElementsException} If the queue is empty.
     */
    dequeue(): ImmutablePriorityQueue<TElement>;
    /**
     * Adds an element to this priority queue. This is an alias for `add`.
     * @template TElement The type of elements in the queue.
     * @param element The element to add.
     * @returns {ImmutablePriorityQueue<TElement>} A new priority queue with the added element.
     */
    enqueue(element: TElement): ImmutablePriorityQueue<TElement>;
    /**
     * Retrieves, but does not remove, the element with the highest priority.
     * @returns {TElement} The element with the highest priority.
     * @throws {NoElementsException} If the queue is empty.
     */
    front(): TElement;
    /**
     * Checks if the priority queue is empty.
     * @returns {boolean} True if the queue is empty, false otherwise.
     */
    isEmpty(): boolean;
    /**
     * Retrieves, but does not remove, the element with the highest priority, or returns null if the queue is empty.
     * @returns {TElement | null} The element with the highest priority, or null if the queue is empty.
     */
    peek(): TElement | null;
    /**
     * Removes the element with the highest priority from the queue.
     * If the queue is empty, returns an empty queue.
     * @returns {ImmutablePriorityQueue<TElement>} A new priority queue with the highest priority element removed, or an empty queue if the original was empty.
     */
    poll(): ImmutablePriorityQueue<TElement>;
    /**
     * Removes the specified element from the priority queue.
     * Note: This operation can be inefficient on a heap (O(N)).
     * @param element The element to remove.
     * @returns {ImmutablePriorityQueue<TElement>} A new priority queue without the specified element, or the original queue if the element was not found.
     */
    remove(element: TElement): ImmutablePriorityQueue<TElement>;
    /**
     * Removes all elements from this queue that are contained in the specified collection.
     * Note: This operation can be inefficient on a heap (O(N*M)).
     * @param collection The collection whose elements will be removed.
     * @returns {ImmutablePriorityQueue<TElement>} A new priority queue without the specified elements.
     */
    removeAll<TSource extends TElement>(collection: Iterable<TSource>): ImmutablePriorityQueue<TElement>;
    /**
     * Removes all elements from this queue that satisfy the specified predicate.
     * Note: This operation can be inefficient on a heap (O(N)).
     * @param predicate The predicate used to test elements.
     * @returns {ImmutablePriorityQueue<TElement>} A new priority queue without the elements satisfying the predicate.
     */
    removeIf(predicate: Predicate<TElement>): ImmutablePriorityQueue<TElement>;
    /**
     * Replaces all elements in this priority queue with the elements from the provided collection.
     * @template TSource The type of elements in the collection.
     * @param collection The collection whose elements will replace the current elements.
     * @returns {ImmutablePriorityQueue<TElement>} A new priority queue containing only the elements from the provided collection.
     */
    reset<TSource extends TElement>(collection: Iterable<TSource>): ImmutablePriorityQueue<TElement>;
    size(): number;
    /**
     * Gets the order comparator used by the priority queue.
     * @returns {OrderComparator<TElement>} The comparator.
     */
    get comparator(): OrderComparator<TElement>;
    get length(): number;
}

export declare class ImmutableQueue<TElement> extends AbstractImmutableCollection<TElement> {
    #private;
    private constructor();
    static create<TElement>(iterable?: Iterable<TElement>, comparator?: EqualityComparator<TElement>): ImmutableQueue<TElement>;
    [Symbol.iterator](): Iterator<TElement>;
    /**
     * Adds the given element to this queue.
     * @template TElement The type of elements in the queue.
     * @param element The element that will be added to this queue.
     * @returns {ImmutableQueue} A new queue with the added element.
     */
    add(element: TElement): ImmutableQueue<TElement>;
    /**
     * Adds all elements from the provided collection to this queue.
     * @template TElement The type of elements in the queue.
     * @param collection The collection whose element will be added to this queue.
     * @returns {ImmutableQueue} A new queue with the added elements.
     */
    addAll<TSource extends TElement>(collection: Iterable<TSource>): ImmutableQueue<TElement>;
    /**
     * Removes all elements from this queue.
     * @returns {ImmutableQueue} An empty queue.
     */
    clear(): ImmutableQueue<TElement>;
    /**
     * Removes the element at the front of this queue.
     * @returns {ImmutableQueue} A new queue with the element at the front removed.
     * @throws {Error} Thrown when the queue is empty.
     */
    dequeue(): ImmutableQueue<TElement>;
    /**
     * Adds an element to the end of this queue. This method is equivalent to {@link add}.
     * @template TElement The type of elements in the queue.
     * @param element The element that will be added to this queue.
     * @returns {ImmutableQueue} A new queue with the added element.
     */
    enqueue(element: TElement): ImmutableQueue<TElement>;
    /**
     * Retrieves but does not remove the element at the beginning of the queue.
     * Unlike {@link peek}, this method throws an error if the queue is empty.
     * @template TElement The type of elements in the queue.
     * @returns {TElement} The head of the queue.
     */
    front(): TElement;
    isEmpty(): boolean;
    /**
     * Retrieves but does not remove the element at the beginning of the queue.
     * Unlike {@link front}, this method returns null if the queue is empty.
     * @template TElement The type of elements in the queue.
     * @returns {TElement | null} The head of the queue or null if the queue is empty.
     */
    peek(): TElement | null;
    /**
     * Removes the element at the beginning of the queue and returns the new queue.
     * Unlike {@link dequeue}, this method does not throw an error if the queue is empty.
     * @template TElement The type of elements in the queue.
     * @returns {ImmutableQueue} A new queue with the head removed, or an empty queue if the queue is empty.
     */
    poll(): ImmutableQueue<TElement>;
    /**
     * Replaces all elements in this queue with the elements from the provided collection.
     * @template TSource The type of elements in the collection.
     * @param collection The collection whose elements will replace the current elements.
     * @returns {ImmutableQueue} A new queue containing only the elements from the provided collection.
     */
    reset<TSource extends TElement>(collection: Iterable<TSource>): ImmutableQueue<TElement>;
    size(): number;
    get comparator(): EqualityComparator<TElement>;
    get length(): number;
}

export declare class ImmutableSet<TElement> extends AbstractRandomAccessImmutableCollection<TElement> {
    #private;
    private constructor();
    static create<TElement>(iterable?: Iterable<TElement>): ImmutableSet<TElement>;
    [Symbol.iterator](): Iterator<TElement>;
    /**
     * Adds the given element to this set.
     * @param element The element that will be added to this set.
     * @returns {ImmutableSet} A new set with the added element.
     */
    add(element: TElement): ImmutableSet<TElement>;
    /**
     * Adds all elements from the provided collection to this set.
     * @param collection The collection whose element will be added to this set.
     * @returns {ImmutableSet} A new set with the added elements.
     */
    addAll<TSource extends TElement>(collection: Iterable<TSource>): ImmutableSet<TElement>;
    /**
     * Removes all elements from this set.
     * @returns {ImmutableSet} An empty set.
     */
    clear(): ImmutableSet<TElement>;
    contains(element: TElement): boolean;
    count(predicate?: Predicate<TElement>): number;
    /**
     * Returns a new set that contains elements from this set that are not in the provided collection.
     * @param collection The collection whose elements will be excluded from this set.
     * @returns {ImmutableSet} A new set that contains elements from this set that are not in the provided collection.
     */
    exceptWith<TSource extends TElement>(collection: Iterable<TSource>): ImmutableSet<TElement>;
    /**
     * Returns a new set that contains elements that are in both this set and the provided collection.
     * @param collection The collection whose elements will be intersected with this set.
     * @returns {ImmutableSet} A new set that contains elements that are in both this set and the provided collection.
     */
    intersectWith<TSource extends TElement>(collection: Iterable<TSource>): ImmutableSet<TElement>;
    isProperSubsetOf(collection: Iterable<TElement>): boolean;
    isProperSupersetOf(collection: Iterable<TElement>): boolean;
    isSubsetOf(collection: Iterable<TElement>): boolean;
    isSupersetOf(collection: Iterable<TElement>): boolean;
    overlaps(collection: Iterable<TElement>): boolean;
    /**
     * Removes the specified element from this set.
     * @param element The element that will be removed from this set.
     * @returns {ImmutableSet} A new set without the specified element.
     */
    remove(element: TElement): ImmutableSet<TElement>;
    /**
     * Removes all elements from this set that are contained in the specified collection.
     * @param collection The collection whose elements will be removed from this set.
     * @returns {ImmutableSet} A new set without the elements in the specified collection.
     */
    removeAll<TSource extends TElement>(collection: Iterable<TSource>): ImmutableSet<TElement>;
    /**
     * Removes all elements from this set that satisfy the specified predicate.
     * @param predicate The predicate used to remove elements from this set.
     * @returns {ImmutableSet} A new set without the elements that satisfy the specified predicate.
     */
    removeIf(predicate: Predicate<TElement>): ImmutableSet<TElement>;
    /**
     * Replaces all elements in this set with the elements from the provided collection.
     * @template TSource The type of elements in the collection.
     * @param collection The collection whose elements will replace the current elements.
     * @returns {ImmutableSet} A new set containing only the elements from the provided collection.
     */
    reset<TSource extends TElement>(collection: Iterable<TSource>): ImmutableSet<TElement>;
    /**
     * Removes all elements from this set except the ones that are contained in the specified collection.
     * @param collection The collection whose elements will be retained in this set.
     * @returns {ImmutableSet} A new set with only the elements in the specified collection.
     */
    retainAll<TSource extends TElement>(collection: Iterable<TSource>): ImmutableSet<TElement>;
    size(): number;
    get comparator(): EqualityComparator<TElement>;
    get length(): number;
}

export declare class ImmutableSortedDictionary<TKey, TValue> extends AbstractImmutableDictionary<TKey, TValue> {
    #private;
    private constructor();
    static create<TKey, TValue>(): ImmutableSortedDictionary<TKey, TValue>;
    static create<TKey, TValue>(iterable: Iterable<KeyValuePair<TKey, TValue>>, keyComparator?: OrderComparator<TKey>, valueComparator?: EqualityComparator<TValue>): ImmutableSortedDictionary<TKey, TValue>;
    static create<TKey, TValue>(iterable: Iterable<[TKey, TValue]>, keyComparator?: OrderComparator<TKey>, valueComparator?: EqualityComparator<TValue>): ImmutableSortedDictionary<TKey, TValue>;
    static create<TKey, TValue>(iterable: Iterable<KeyValuePair<TKey, TValue>> | Iterable<[TKey, TValue]>, keyComparator?: OrderComparator<TKey>, valueComparator?: EqualityComparator<TValue>): ImmutableSortedDictionary<TKey, TValue>;
    [Symbol.iterator](): Iterator<KeyValuePair<TKey, TValue>>;
    add(key: TKey, value: TValue): ImmutableSortedDictionary<TKey, TValue>;
    clear(): ImmutableSortedDictionary<TKey, TValue>;
    containsKey(key: TKey): boolean;
    containsValue(value: TValue, comparator?: EqualityComparator<TValue>): boolean;
    entries(): IterableIterator<[TKey, TValue]>;
    get(key: TKey): TValue | null;
    keys(): ISet<TKey>;
    put(key: TKey, value: TValue): ImmutableSortedDictionary<TKey, TValue>;
    remove(key: TKey): ImmutableSortedDictionary<TKey, TValue>;
    set(key: TKey, value: TValue): ImmutableSortedDictionary<TKey, TValue>;
    size(): number;
    values(): IImmutableCollection<TValue>;
    private getCopiedDictionary;
    get length(): number;
}

export declare class ImmutableSortedSet<TElement> extends AbstractRandomAccessImmutableCollection<TElement> {
    #private;
    private constructor();
    static create<TElement>(iterable?: Iterable<TElement>, comparator?: OrderComparator<TElement>): ImmutableSortedSet<TElement>;
    [Symbol.iterator](): Iterator<TElement>;
    /**
     * Adds the given element to this set.
     * @param element The element that will be added to this set.
     * @returns {ImmutableSortedSet} A new set with the added element.
     */
    add(element: TElement): ImmutableSortedSet<TElement>;
    /**
     * Adds all elements from the provided collection to this set.
     * @param collection The collection whose element will be added to this set.
     * @returns {ImmutableSortedSet} A new set with the added elements.
     */
    addAll<TSource extends TElement>(collection: Iterable<TSource>): ImmutableSortedSet<TElement>;
    /**
     * Removes all elements from this set.
     * @returns {ImmutableSortedSet} An empty set.
     */
    clear(): ImmutableSortedSet<TElement>;
    contains(element: TElement): boolean;
    count(predicate?: Predicate<TElement>): number;
    exceptWith(other: Iterable<TElement>): ImmutableSortedSet<TElement>;
    /**
     * Returns the first n elements of this set.
     * @param toElement The element up to which the elements will be included.
     * @param inclusive If true, the element toElement will be included; otherwise, it will be excluded.
     * @returns {ImmutableSortedSet} A new set that contains the first n elements of this set.
     */
    headSet(toElement: TElement, inclusive?: boolean): ImmutableSortedSet<TElement>;
    /**
     * Returns a new set that contains elements that are in both this set and the provided collection.
     * @param other The collection whose elements will be intersected with this set.
     * @returns {ImmutableSortedSet} A new set that contains elements that are in both this set and the provided collection.
     */
    intersectWith(other: Iterable<TElement>): ImmutableSortedSet<TElement>;
    isProperSubsetOf(other: Iterable<TElement>): boolean;
    isProperSupersetOf(other: Iterable<TElement>): boolean;
    isSubsetOf(other: Iterable<TElement>): boolean;
    isSupersetOf(other: Iterable<TElement>): boolean;
    overlaps(other: Iterable<TElement>): boolean;
    /**
     * Removes the given element from this set.
     * @param element The element that will be removed from this set.
     * @returns {ImmutableSortedSet} A new set with the removed element.
     */
    remove(element: TElement): ImmutableSortedSet<TElement>;
    /**
     * Removes all elements from this set that are contained in the specified collection.
     * @param collection The collection whose elements will be removed from this set.
     * @returns {ImmutableSortedSet} A new set without the elements in the specified collection.
     */
    removeAll<TSource extends TElement>(collection: Iterable<TSource>): ImmutableSortedSet<TElement>;
    /**
     * Removes all elements from this set that satisfy the specified predicate.
     * @param predicate The predicate that will be used to remove elements from this set.
     * @returns {ImmutableSortedSet} A new set without the elements that satisfy the predicate.
     */
    removeIf(predicate: Predicate<TElement>): ImmutableSortedSet<TElement>;
    /**
     * Replaces all elements in this set with the elements from the provided collection.
     * @template TSource The type of elements in the collection.
     * @param collection The collection whose elements will replace the current elements.
     * @returns {ImmutableSortedSet} A new set containing only the elements from the provided collection.
     */
    reset<TSource extends TElement>(collection: Iterable<TSource>): ImmutableSortedSet<TElement>;
    /**
     * Removes all elements from this set except the ones that are contained in the specified collection.
     * @param collection The collection whose elements will be retained in this set.
     * @returns {ImmutableSortedSet} A new set with only the elements in the specified collection.
     */
    retainAll<TSource extends TElement>(collection: Iterable<TSource>): ImmutableSortedSet<TElement>;
    size(): number;
    /**
     * Returns a new set that contains elements that are in the specified range.
     * @param fromElement The element from which the range will start.
     * @param toElement The element up to which the range will be included.
     * @param fromInclusive If true, the element fromElement will be included; otherwise, it will be excluded.
     * @param toInclusive If true, the element toElement will be included; otherwise, it will be excluded.
     * @returns {ImmutableSortedSet} A new set that contains elements that are in the specified range.
     */
    subSet(fromElement: TElement, toElement: TElement, fromInclusive?: boolean, toInclusive?: boolean): ImmutableSortedSet<TElement>;
    /**
     * Returns a new set that contains elements that are greater than or equal to the specified element.
     * @param fromElement The element from which the range will start.
     * @param inclusive If true, the element fromElement will be included; otherwise, it will be excluded.
     * @returns {ImmutableSortedSet} A new set that contains elements that are greater than or equal to the specified element.
     */
    tailSet(fromElement: TElement, inclusive?: boolean): ImmutableSortedSet<TElement>;
    get comparator(): OrderComparator<TElement>;
    get length(): number;
}

export declare class ImmutableStack<TElement> extends AbstractImmutableCollection<TElement> {
    #private;
    private constructor();
    static create<TElement>(iterable?: Iterable<TElement>, comparator?: EqualityComparator<TElement>): ImmutableStack<TElement>;
    [Symbol.iterator](): Iterator<TElement>;
    /**
     * Adds the given element to this stack.
     * @template TElement The type of elements in the stack.
     * @param element The element that will be added to this stack.
     * @returns {ImmutableStack} A new stack with the added element.
     */
    add(element: TElement): ImmutableStack<TElement>;
    /**
     * Adds all elements from the provided collection to this stack.
     * The elements of the collection are added in the reverse order of the collection.
     * For example, if the collection is [1, 2, 3], the stack will contain [3, 2, 1], with 3 at the top.
     * @template TElement The type of elements in the stack.
     * @param collection The collection whose element will be added to this stack.
     * @returns {ImmutableStack} A new stack with the added elements.
     */
    addAll<TSource extends TElement>(collection: Iterable<TSource>): ImmutableStack<TElement>;
    /**
     * Removes all elements from this stack.
     * @returns {ImmutableStack} An empty stack.
     */
    clear(): ImmutableStack<TElement>;
    /**
     * Retrieves but does not remove the element at the top of the stack.
     * Unlike {@link top}, this method returns null if the stack is empty.
     * @template TElement The type of elements in the stack.
     * @returns {TElement | null} The top of the stack or null if the stack is empty.
     */
    peek(): TElement | null;
    /**
     * Removes the element at the top of the stack and returns the new stack.
     * @template TElement The type of elements in the stack.
     * @returns {ImmutableStack} A new stack with the top element removed.
     */
    pop(): ImmutableStack<TElement>;
    /**
     * Adds the given element to this stack.
     * @template TElement The type of elements in the stack.
     * @param element The element that will be added to this stack.
     * @returns {ImmutableStack} A new stack with the added element.
     */
    push(element: TElement): ImmutableStack<TElement>;
    /**
     * Replaces all elements in this stack with the elements from the provided collection.
     * @template TSource The type of elements in the collection.
     * @param collection The collection whose elements will replace the current elements.
     * @returns {ImmutableStack} A new stack containing only the elements from the provided collection.
     */
    reset<TSource extends TElement>(collection: Iterable<TSource>): ImmutableStack<TElement>;
    size(): number;
    /**
     * Retrieves but does not remove the element at the top of the stack.
     * Unlike {@link peek}, this method throws an error if the stack is empty.
     * @template TElement The type of elements in the stack.
     * @returns {TElement} The top of the stack.
     * @throws {Error} If the stack is empty.
     */
    top(): TElement;
    get comparator(): EqualityComparator<TElement>;
    get length(): number;
}

export declare class ImmutableTrie<TKey, TValue, TToken = TKey> extends AbstractEnumerable<[TKey, TValue]> {
    #private;
    private constructor();
    static create<TKey, TValue, TToken = TKey>(tokenizer?: Selector<TKey, Iterable<TToken>> | null, tokenComparator?: EqualityComparator<TToken>): ImmutableTrie<TKey, TValue, TToken>;
    [Symbol.iterator](): IterableIterator<[TKey, TValue]>;
    /**
     * Removes all entries from the trie.
     * @returns A new, empty ImmutableTrie with the same tokenizer and comparator.
     */
    clear(): ImmutableTrie<TKey, TValue, TToken>;
    /**
     * Deletes a key from the trie.
     * Returns a new ImmutableTrie instance; does not modify the current one.
     * If the key was not found, returns the current instance.
     * @param key The key to delete.
     * @returns A new ImmutableTrie instance with the key deleted, or the current instance if the key was not found.
     */
    delete(key: TKey): ImmutableTrie<TKey, TValue, TToken>;
    /**
     * Gets the value associated with a key.
     * @param key The key to retrieve.
     * @returns The value associated with the key, or null if not found.
     */
    get(key: TKey): TValue | null;
    /**
     * Checks if a key exists in the trie.
     * @param key The key to check.
     * @returns True if the key exists, false otherwise.
     */
    has(key: TKey): boolean;
    /**
     * Inserts a key-value pair into the trie.
     * Returns a new ImmutableTrie instance; does not modify the current one.
     * @param key The key to insert.
     * @param value The value to associate with the key.
     * @returns A new ImmutableTrie instance with the key-value pair inserted.
     */
    insert(key: TKey, value: TValue): ImmutableTrie<TKey, TValue, TToken>;
    /**
     * Yields all values associated with a key prefix.
     * @param prefix The key prefix to search for.
     * @returns An enumerable of values associated with keys that start with the given prefix.
     */
    prefix(prefix: TKey): IEnumerable<TValue>;
    /**
     * Gets the number of stored key-value pairs.
     * @returns The number of stored key-value pairs.
     */
    size(): number;
}

/**
 * Enumerates the sequence while exposing the zero-based index alongside each element.
 * @template TElement Type of elements within the `source` iterable.
 * @param source The source iterable.
 * @returns {IEnumerable<[number, TElement]>} A sequence of `[index, element]` tuples.
 * @remarks The index is assigned in the order elements are produced. Enumeration is deferred until the result is iterated.
 * @example
 * ```typescript
 * const letters = ['a', 'b', 'c'];
 * const indexed = index(letters).toArray();
 * console.log(indexed); // [[0, 'a'], [1, 'b'], [2, 'c']]
 * ```
 */
export declare const index: <TElement>(source: Iterable<TElement>) => IEnumerable<[number, TElement]>;

export declare interface IndexedAction<TElement, TReturn = void> {
    (item: TElement, index: number): TReturn;
}

export declare interface IndexedPredicate<TElement> {
    (item: TElement, index: number): boolean;
}

export declare interface IndexedSelector<TElement, TResult> {
    (item: TElement, index: number): TResult;
}

export declare interface IndexedTupleSelector<TElement> {
    (index: number, item: TElement): [number, TElement];
}

export declare interface IndexedTypePredicate<TElement, TFiltered extends TElement> {
    (item: TElement, index: number): item is TFiltered;
}

declare type InferredType<T> = T extends SymbolType ? symbol : T extends BooleanType ? boolean : T extends NumberType ? number : T extends BigIntType ? bigint : T extends "object" ? object : T extends "function" ? Function : T extends StringType ? string : T extends Class<infer R> ? R : T extends FunctionType ? Function : T extends PlainObjectType ? object : T;

/**
 * Generates an infinite numeric sequence starting from the specified value with the given step increment.
 * @param start Initial value of the sequence.
 * @param step Step size to increment each subsequent value.
 * @returns {IEnumerable<number>} An infinite sequence of numbers starting from {@link start}, incremented by {@link step} for each subsequent element.
 * @remarks Enumeration is deferred and will continue indefinitely unless limited by operations like {@link take} or {@link takeWhile}. The sequence can be ascending (positive step) or descending (negative step).
 * @example
 * ```typescript
 * const ascending = infiniteSequence(1, 1).take(5).toArray();
 * console.log(ascending); // [1, 2, 3, 4, 5]
 * ```
 * @example
 * ```typescript
 * const descending = infiniteSequence(10, -1).take(5).toArray();
 * console.log(descending); // [10, 9, 8, 7, 6]
 * ```
 * @example
 * ```typescript
 * const stepped = infiniteSequence(0, 2).take(5).toArray();
 * console.log(stepped); // [0, 2, 4, 6, 8]
 * ```
 */
export declare const infiniteSequence: (start: number, step: number) => IEnumerable<number>;

declare interface INode<TElement> {
    getData(): TElement;
    getLeft(): INode<TElement> | null;
    getRight(): INode<TElement> | null;
    setData(data: TElement): void;
    setLeft(node: INode<TElement>): void;
    setRight(node: INode<TElement>): void;
}

/**
 * Interleaves the sequence with another iterable, yielding elements in alternating order.
 * @template TElement Type of elements within the `source` iterable.
 * @template TSecond Type of elements in the second iterable.
 * @param source The source iterable.
 * @param other Iterable whose elements are alternated with the current sequence.
 * @returns {IEnumerable<TElement | TSecond>} A sequence that alternates between elements from {@link source} and {@link other}.
 * @remarks If one sequence is longer, the remaining elements are appended after the shorter sequence is exhausted. Enumeration is deferred.
 * @example
 * ```typescript
 * const numbers1 = [1, 3, 5];
 * const numbers2 = [2, 4, 6];
 * const interleaved = interleave(numbers1, numbers2).toArray();
 * console.log(interleaved); // [1, 2, 3, 4, 5, 6]
 * ```
 */
export declare const interleave: <TElement, TSecond>(source: Iterable<TElement>, other: Iterable<TSecond>) => IEnumerable<TElement | TSecond>;

/**
 * Returns the elements common to {@link source} and {@link other}.
 * @template TElement Type of elements within the `source` iterable.
 * @param source The source iterable.
 * @param other Iterable whose elements are compared against {@link source}.
 * @param comparator Optional comparator used to determine element equality. Both equality and order comparators are supported; defaults to the library's standard equality comparison when omitted.
 * @returns {IEnumerable<TElement>} A sequence containing the intersection of the two sequences.
 * @remarks The original ordering of {@link source} is preserved. {@link other} is fully enumerated to build the inclusion set prior to yielding results.
 * @example
 * ```typescript
 * const numbers1 = [1, 2, 3, 4, 5];
 * const numbers2 = [3, 5, 7];
 * const result = intersect(numbers1, numbers2).toArray();
 * console.log(result); // [3, 5]
 * ```
 */
export declare const intersect: <TElement>(source: Iterable<TElement>, other: Iterable<TElement>, comparator?: EqualityComparator<TElement> | OrderComparator<TElement>) => IEnumerable<TElement>;

/**
 * Returns the elements whose keys are common to {@link source} and {@link other}.
 * @template TElement Type of elements within the `source` iterable.
 * @template TKey Type of key produced by {@link keySelector}.
 * @param source The source iterable.
 * @param other Iterable whose elements define the keys considered part of the intersection.
 * @param keySelector Selector used to project each element to the key used for comparison.
 * @param keyComparator Optional comparator used to compare keys. Both equality and order comparators are supported; defaults to the library's standard equality comparison when omitted.
 * @returns {IEnumerable<TElement>} A sequence containing the intersection of the two sequences based on matching keys.
 * @remarks {@link other} is fully enumerated to materialise the inclusion keys before yielding results. Source ordering is preserved.
 * @example
 * ```typescript
 * const products1 = [
 *   { name: 'Apple', category: 'Fruit' },
 *   { name: 'Carrot', category: 'Vegetable' },
 * ];
 * const products2 = [
 *   { name: 'Banana', category: 'Fruit' },
 *   { name: 'Broccoli', category: 'Vegetable' },
 * ];
 *
 * const result = intersectBy(products1, products2, p => p.category).toArray();
 * console.log(result);
 * // [
 * //   { name: 'Apple', category: 'Fruit' },
 * //   { name: 'Carrot', category: 'Vegetable' }
 * // ]
 * ```
 */
export declare const intersectBy: <TElement, TKey>(source: Iterable<TElement>, other: Iterable<TElement>, keySelector: Selector<TElement, TKey>, keyComparator?: EqualityComparator<TKey> | OrderComparator<TKey>) => IEnumerable<TElement>;

/**
 * Inserts the specified separator between adjoining elements.
 * @template TElement Type of elements within the `source` iterable.
 * @template TSeparator Type of separator to insert.
 * @param source The source iterable.
 * @param separator Value inserted between consecutive elements.
 * @returns {IEnumerable<TElement | TSeparator>} A sequence containing the original elements with separators interleaved.
 * @remarks No separator precedes the first element or follows the last element.
 * @example
 * ```typescript
 * const letters = ['a', 'b', 'c'];
 * const interspersed = intersperse(letters, '-').toArray();
 * console.log(interspersed); // ['a', '-', 'b', '-', 'c']
 * ```
 */
export declare const intersperse: <TElement, TSeparator>(source: Iterable<TElement>, separator: TSeparator) => IEnumerable<TElement | TSeparator>;

export declare interface IOrderedAsyncEnumerable<TElement> extends IAsyncEnumerable<TElement> {
    /**
     * Performs a subsequent ordering of the elements in a sequence in ascending order according to a key.
     * @param keySelector A function to extract a key from an element.
     * @param comparator A function to compare keys.
     */
    thenBy<TKey>(keySelector: Selector<TElement, TKey>, comparator?: OrderComparator<TKey>): IOrderedAsyncEnumerable<TElement>;
    /**
     * Performs a subsequent ordering of the elements in a sequence in descending order according to a key.
     * @param keySelector A function to extract a key from an element.
     * @param comparator A function to compare keys.
     */
    thenByDescending<TKey>(keySelector: Selector<TElement, TKey>, comparator?: OrderComparator<TKey>): IOrderedAsyncEnumerable<TElement>;
}

export declare interface IOrderedEnumerable<TElement> extends IEnumerable<TElement> {
    /**
     * Performs a subsequent ordering of the elements in a sequence in ascending order according to a key.
     * This method must be called on an IOrderedEnumerable (the result of orderBy, orderByDescending, thenBy, or thenByDescending).
     * Calling orderBy or orderByDescending after this method will override the entire sorting sequence.
     * @template TKey The type of the key returned by keySelector.
     * @param keySelector The function to extract the key for secondary sorting from an element.
     * @param comparator The comparator function that will be used for comparing two keys. If not specified, the default ascending order comparison will be used.
     * @returns {IOrderedEnumerable<TElement>} An IOrderedEnumerable whose elements are sorted by the primary condition and then by this secondary condition (ascending).
     * @example
     *      interface Person { name: string; city: string; age: number; }
     *      const people = new List<Person>([
     *          { name: 'Alice', city: 'London', age: 30 },
     *          { name: 'Bob', city: 'Paris', age: 25 },
     *          { name: 'Charlie', city: 'London', age: 35 },
     *          { name: 'Diana', city: 'Paris', age: 30 }
     *      ]);
     *
     *      // --- Standard Usage ---
     *      // Order by city ascending (primary), then by age ascending (secondary)
     *      const sortedPeople = people
     *          .orderBy(p => p.city) // Primary sort: city ascending
     *          .thenBy(p => p.age)      // Secondary sort: age ascending
     *          .toArray();
     *      // sortedPeople = [
     *      //   { name: 'Alice', city: 'London', age: 30 },
     *      //   { name: 'Charlie', city: 'London', age: 35 },
     *      //   { name: 'Bob', city: 'Paris', age: 25 },
     *      //   { name: 'Diana', city: 'Paris', age: 30 }
     *      // ]
     *
     *      // --- Overriding Behavior ---
     *      // Order by city, then by age, but then override with a new primary order by name
     *      const overriddenSort = people
     *          .orderBy(p => p.city)
     *          .thenBy(p => p.age)
     *          .orderBy(p => p.name) // This orderBy overrides the previous sorts
     *          .toArray();
     *      // The final sort is based only on name ascending:
     *      // overriddenSort = [
     *      //   { name: 'Alice', city: 'London', age: 30 },
     *      //   { name: 'Bob', city: 'Paris', age: 25 },
     *      //   { name: 'Charlie', city: 'London', age: 35 },
     *      //   { name: 'Diana', city: 'Paris', age: 30 }
     *      // ]
     */
    thenBy<TKey>(keySelector: Selector<TElement, TKey>, comparator?: OrderComparator<TKey>): IOrderedEnumerable<TElement>;
    /**
     * Performs a subsequent ordering of the elements in a sequence in descending order according to a key.
     * This method must be called on an IOrderedEnumerable (the result of orderBy, orderByDescending, thenBy, or thenByDescending).
     * Calling orderBy or orderByDescending after this method will override the entire sorting sequence.
     * @template TKey The type of the key returned by keySelector.
     * @param keySelector The function to extract the key for secondary sorting from an element.
     * @param comparator The comparator function that will be used for comparing two keys. If not specified, the default descending order comparison will be used.
     * @returns {IOrderedEnumerable<TElement>} An IOrderedEnumerable whose elements are sorted by the primary condition and then by this secondary condition (descending).
     * @example
     *      interface Person { name: string; city: string; age: number; }
     *      const people = new List<Person>([
     *          { name: 'Alice', city: 'London', age: 30 },
     *          { name: 'Bob', city: 'Paris', age: 25 },
     *          { name: 'Charlie', city: 'London', age: 35 },
     *          { name: 'Diana', city: 'Paris', age: 30 }
     *      ]);
     *
     *      // --- Standard Usage ---
     *      // Order by city ascending (primary), then by age descending (secondary)
     *      const sortedPeople = people
     *          .orderBy(p => p.city)          // Primary sort: city ascending
     *          .thenByDescending(p => p.age) // Secondary sort: age descending
     *          .toArray();
     *      // sortedPeople = [
     *      //   { name: 'Charlie', city: 'London', age: 35 },
     *      //   { name: 'Alice', city: 'London', age: 30 },
     *      //   { name: 'Diana', city: 'Paris', age: 30 },
     *      //   { name: 'Bob', city: 'Paris', age: 25 }
     *      // ]
     *
     *      // --- Overriding Behavior ---
     *      // Order by city, then by age descending, but then override with order by name descending
     *      const overriddenSort = people
     *          .orderBy(p => p.city)
     *          .thenByDescending(p => p.age)
     *          .orderByDescending(p => p.name) // This overrides the previous sorts
     *          .toArray();
     *      // The final sort is based only on name descending:
     *      // overriddenSort = [
     *      //   { name: 'Diana', city: 'Paris', age: 30 },
     *      //   { name: 'Charlie', city: 'London', age: 35 },
     *      //   { name: 'Bob', city: 'Paris', age: 25 },
     *      //   { name: 'Alice', city: 'London', age: 30 }
     *      // ]
     */
    thenByDescending<TKey>(keySelector: Selector<TElement, TKey>, comparator?: OrderComparator<TKey>): IOrderedEnumerable<TElement>;
}

/**
 * Represents a collection of objects whose elements can be accessed without restriction.
 */
export declare interface IRandomAccessCollection<TElement> extends ICollection<TElement> {
    /**
     * Removes the given element from this collection. Comparison is made by the collection's current comparator.
     * @param element The element that will be removed from the collection.
     * @returns true if the element is removed from the collection, false otherwise.
     */
    remove(element: TElement): boolean;
    /**
     * Removes all the elements of the given collection or array from this collection.
     * @param collection The collection or array whose elements will be removed from this collection.
     * @returns true if this collection is modified as a result.
     */
    removeAll<TSource extends TElement>(collection: Iterable<TSource>): boolean;
    /**
     * Removes all the elements that satisfy the given predicate from this collection.
     * @param predicate The predicate method against which the elements of this collection will be tested.
     * @returns {boolean} true if this collection is modified as a result.
     */
    removeIf(predicate: Predicate<TElement>): boolean;
    /**
     * Removes all the elements that do not exist in the given collection or array.
     * @param collection The collection or array whose elements will remain in this collection.
     * @returns {boolean} true if this collection is modified as a result.
     */
    retainAll<TSource extends TElement>(collection: Iterable<TSource>): boolean;
}

export declare interface IRandomAccessImmutableCollection<TElement> extends IImmutableCollection<TElement> {
    /**
     * Removes the given element from this collection.
     * @param element The element that will be removed from this collection.
     * @returns {IImmutableCollection} A new collection without the removed element.
     */
    remove(element: TElement): IRandomAccessImmutableCollection<TElement>;
    /**
     * Removes all elements from this collection that are in the provided collection.
     * @param collection The collection whose elements will be removed from this collection.
     * @returns {IImmutableCollection} A new collection without the removed elements.
     */
    removeAll<TSource extends TElement>(collection: Iterable<TSource>): IRandomAccessImmutableCollection<TElement>;
    /**
     * Removes all elements from this collection that satisfy the provided predicate.
     * @param predicate A function that will test each element for a condition.
     * @returns {IImmutableCollection} A new collection without the removed elements.
     */
    removeIf(predicate: Predicate<TElement>): IRandomAccessImmutableCollection<TElement>;
    /**
     * Retains only the elements in this collection that are contained in the specified collection.
     * @param collection The collection whose elements will be retained in this collection.
     * @returns {IImmutableCollection} A new collection with only the elements in the specified collection.
     */
    retainAll<TSource extends TElement>(collection: Iterable<TSource>): IRandomAccessImmutableCollection<TElement>;
}

export declare interface IReadonlyCollection<TElement> extends IEnumerable<TElement> {
    /**
     * Returns the number of elements in this collection.
     * @returns {number} The number of elements in this collection.
     */
    get length(): number;
    /**
     * Returns the current comparator used by this collection.
     * @template TElement The type of the elements in the collection.
     * @returns {EqualityComparator<TElement> | OrderComparator<TElement>} The current comparator used by this collection.
     */
    get comparator(): EqualityComparator<TElement> | OrderComparator<TElement>;
    /**
     * Check if this collection contains all the elements of the given collection.
     * @param collection The collection whose element will be tested for existence against this collection.
     * @returns {boolean} true if this collection contains all the elements from the given collection, false otherwise.
     */
    containsAll<TSource extends TElement>(collection: Iterable<TSource>): boolean;
    /**
     * Iterates over the collection and runs the given action against every element.
     * @param action The action that will be run against the elements of this collection
     */
    forEach(action: IndexedAction<TElement>): void;
    /**
     * Checks whether this collection is empty or not.
     * @returns {boolean} true if the collection is empty
     */
    isEmpty(): boolean;
    /**
     * Returns the number of elements in this collection.
     * @returns {number} The number of elements in this collection.
     */
    size(): number;
    /**
     * Returns a string representation of this collection.
     * @returns {string} A string representation of this collection.
     */
    toString(): string;
    /**
     * Returns a string representation of this collection.
     * @param separator The separator that will be used to separate the elements of this collection.
     * @returns {string} A string representation of this collection.
     */
    toString(separator?: string): string;
    /**
     * Returns a string representation of this collection.
     * @param separator The separator that will be used to separate the elements of this collection.
     * @param selector The selector that will be used to select the property that will be used to generate the string representation of this collection.
     * @returns {string} A string representation of this collection.
     */
    toString(separator?: string, selector?: Selector<TElement, string>): string;
}

export declare interface IReadonlyDictionary<TKey, TValue> extends IEnumerable<KeyValuePair<TKey, TValue>> {
    /**
     * Returns the number of elements in this dictionary.
     */
    get length(): number;
    /**
     * Returns an object representation of this dictionary.
     *
     * {@link toObject} is a more versatile version of this method, as it allows you to select the key and value properties
     * that will be used to generate the object representation.
     * @template TValue The type of the values of the dictionary.
     * @returns {Record<string|number|symbol, TValue>} An object representation of this dictionary.
     */
    asObject<TObjectKey extends PropertyKey>(): Record<TObjectKey, TValue>;
    /**
     * Checks whether this dictionary contains the specified key.
     * @param key The key to locate in this dictionary.
     * @returns {boolean} true if this dictionary contains an element with the specified key; false otherwise.
     */
    containsKey(key: TKey): boolean;
    /**
     * Checks whether this dictionary contains the specified value.
     * @param value The value to locate in this dictionary.
     * @param comparator The comparator function which will be used to compare the equality of the values.
     * @returns {boolean} true if this dictionary contains an element with the specified value; false otherwise.
     */
    containsValue(value: TValue, comparator?: EqualityComparator<TValue>): boolean;
    /**
     * Returns an IterableIterator that yields a tuple of [key, value].
     */
    entries(): IterableIterator<[TKey, TValue]>;
    /**
     * Returns the value associated with the given key.
     * @param key The key whose associated value will be returned
     * @returns The associated value of the key. If key does not exist, it will return null.
     */
    get(key: TKey): TValue | null;
    /**
     * Checks if the dictionary is empty or not.
     * @returns {boolean} true if the dictionary is empty; false otherwise.
     */
    isEmpty(): boolean;
    /**
     * Returns a set of keys of this dictionary.
     * @returns {ISet} A set of keys of this dictionary.
     */
    keys(): ISet<TKey>;
    /**
     * Returns the number of elements in this dictionary.
     */
    size(): number;
    /**
     * Returns a string representation of this dictionary.
     */
    toString(): string;
    /**
     * Returns a string representation of this dictionary.
     * @param selector The selector that will be used to select the property that will be used to generate the string representation of this dictionary.
     */
    toString(selector?: Selector<KeyValuePair<TKey, TValue>, string>): string;
    /**
     * Returns a list of values of the dictionary.
     * @returns {IImmutableCollection} An immutable collection of values of this dictionary.
     */
    values(): IImmutableCollection<TValue>;
    get keyValueComparator(): EqualityComparator<KeyValuePair<TKey, TValue>>;
    get valueComparator(): EqualityComparator<TValue>;
}

export declare interface IReadonlyList<TElement> extends IReadonlyCollection<TElement> {
    /**
     * Returns an IterableIterator that yields a tuple of [index, element].
     * <pre>
     *      for (const [index, element] of list.entries())
     * </pre>
     */
    entries(): IterableIterator<[number, TElement]>;
    /**
     * Returns the element at the given index.
     * @param index The index from which the element will be returned.
     * @returns The element at the given index
     */
    get(index: number): TElement;
    /**
     * Returns a shallow copy of a range of elements in the source list.
     * @param index The index at which the range will start.
     * @param count The number of elements in the range.
     * @returns A shallow copy of a range of elements in the source list.
     * @throws {Error} If the index is out of bounds.
     */
    getRange(index: number, count: number): IReadonlyList<TElement>;
    /**
     * Finds and returns the index of the first occurrence of the given element.
     * @param element The element whose index will be found.
     * @param comparator The comparator that will be used to compare for equality.
     * @returns the index of the given element. -1 if item is not found.
     */
    indexOf(element: TElement, comparator?: EqualityComparator<TElement>): number;
    /**
     * Finds and returns the index of the last occurrence of the given element.
     * @param element The element whose index will be found.
     * @param comparator The comparator that will be used to compare for equality.
     * @returns The index of the given element. -1 if item is not found.
     */
    lastIndexOf(element: TElement, comparator?: EqualityComparator<TElement>): number;
}

export declare interface ISet<TElement> extends IRandomAccessCollection<TElement> {
    /**
     * Removes all elements in the specified collection from the current set.
     * @param other The collection of items to remove from the set.
     */
    exceptWith(other: Iterable<TElement>): void;
    /**
     * Modifies the current set so that it contains only the elements that are also in the specified collection.
     * @param other
     */
    intersectWith(other: Iterable<TElement>): void;
    /**
     * Determines whether this set is a proper subset of the specified collection.
     * @param other The iterable to compare to this set.
     * @returns true if this set is a proper subset of other; otherwise, false.
     */
    isProperSubsetOf(other: Iterable<TElement>): boolean;
    /**
     * Determines whether this set is a proper superset of the specified collection.
     * @param other The iterable to compare to this set.
     * @returns true if this set is a proper superset of other; otherwise, false.
     */
    isProperSupersetOf(other: Iterable<TElement>): boolean;
    /**
     * Determines whether this set is a subset of the specified collection.
     * @param other The iterable to compare to this set.
     * @returns true if this set is a subset of other; otherwise, false.
     */
    isSubsetOf(other: Iterable<TElement>): boolean;
    /**
     * Determines whether this set is a superset of the specified collection.
     * @param other The iterable to compare to this set.
     * @returns true if this set is a superset of other; otherwise, false.
     */
    isSupersetOf(other: Iterable<TElement>): boolean;
    /**
     * Determines whether this set and the specified collection share common elements.
     * @param other The iterable to compare to this set.
     * @returns true if the set and other share at least one common element; otherwise, false.
     */
    overlaps(other: Iterable<TElement>): boolean;
}

export declare interface ITree<TElement> extends IRandomAccessCollection<TElement> {
    /**
     * Deletes the given item from the tree.
     * @param element Item to be removed from the tree.
     */
    delete(element: TElement): void;
    /**
     * Returns the first occurrence of an item that satisfy the condition by the predicate.
     * @param  predicate The function that will be used to find the items.
     * @return First occurrence of the item that satisfies the predicate. If no item satisfies, returns null.
     */
    find(predicate: Predicate<TElement>): TElement | null;
    /**
     * Returns the data at the root of this tree.
     * @return The data at the root of the tree.
     */
    getRootData(): TElement | null;
    /**
     * Inserts an item to this tree.
     * @param element Item that is to be inserted.
     */
    insert(element: TElement): void;
    /**
     * Searches for an item in this tree.
     * @param  element Item to be searched.
     * @return true if the item is found, false otherwise.
     */
    search(element: TElement): boolean;
}

/**
 * Produces a projection from the sequence and a second sequence by matching elements that share an identical join key.
 * @template TElement Type of elements within the outer sequence.
 * @template TInner Type of elements within the inner sequence.
 * @template TKey Type of key produced by the key selectors.
 * @template TResult Type of element returned by {@link resultSelector}.
 * @param source The outer sequence.
 * @param innerEnumerable Sequence whose elements are joined with the outer sequence.
 * @param outerKeySelector Selector that extracts the join key from each outer element.
 * @param innerKeySelector Selector that extracts the join key from each inner element.
 * @param resultSelector Projection that combines an outer element with a matching inner element.
 * @param keyComparator Optional equality comparator used to match keys. Defaults to the library's standard equality comparison when omitted.
 * @returns {IEnumerable<TResult>} A sequence generated by applying {@link resultSelector} to each matching pair.
 * @remarks The inner sequence is fully enumerated to build an in-memory lookup before outer elements are processed. The outer sequence is then enumerated lazily and its original ordering is preserved. This is an inner join; unmatched outer or inner elements are not emitted.
 * @example
 * ```typescript
 * const categories = [
 *   { id: 1, name: 'Fruit' },
 *   { id: 2, name: 'Vegetable' },
 * ];
 * const products = [
 *   { name: 'Apple', categoryId: 1 },
 *   { name: 'Banana', categoryId: 1 },
 *   { name: 'Carrot', categoryId: 2 },
 * ];
 *
 * const joined = join(
 *   categories,
 *   products,
 *   c => c.id,
 *   p => p.categoryId,
 *   (c, p) => ({ category: c.name, product: p.name })
 * ).toArray();
 *
 * console.log(joined);
 * // [
 * //   { category: 'Fruit', product: 'Apple' },
 * //   { category: 'Fruit', product: 'Banana' },
 * //   { category: 'Vegetable', product: 'Carrot' }
 * // ]
 * ```
 */
export declare const join: <TElement, TInner, TKey, TResult>(source: Iterable<TElement>, innerEnumerable: Iterable<TInner>, outerKeySelector: Selector<TElement, TKey>, innerKeySelector: Selector<TInner, TKey>, resultSelector: JoinSelector<TElement, TInner, TResult>, keyComparator?: EqualityComparator<TKey>) => IEnumerable<TResult>;

export declare interface JoinSelector<TFirst, TSecond, TResult> {
    (firstItem: TFirst, secondItem: TSecond | null): TResult;
}

export declare class KeyValuePair<TKey, TValue> {
    readonly key: TKey;
    value: TValue;
    constructor(key: TKey, value: TValue);
    equals(pair: KeyValuePair<TKey, TValue>, keyComparator?: EqualityComparator<TKey>, valueComparator?: EqualityComparator<TValue>): boolean;
}

/**
 * Returns the last element in the sequence, optionally filtered by a predicate or type guard.
 * @template TElement Type of elements within the `source` iterable.
 * @template TFiltered Subtype confirmed when a type guard predicate is supplied.
 * @param source The source iterable.
 * @param predicate Predicate evaluated against each element. When omitted, the last element of the sequence is returned. When a type guard is supplied, the returned value is narrowed to `TFiltered`.
 * @returns {TElement | TFiltered} The last element that satisfies the predicate (or the final element when no predicate is supplied).
 * @throws {NoElementsException} Thrown when the sequence is empty.
 * @throws {NoMatchingElementException} Thrown when a predicate is supplied and no element satisfies it.
 * @remarks The entire sequence is enumerated to locate the final match.
 * @example
 * ```typescript
 * const numbers = [1, 2, 3, 4, 5];
 * const lastElement = last(numbers);
 * console.log(lastElement); // 5
 *
 * const lastEven = last(numbers, x => x % 2 === 0);
 * console.log(lastEven); // 4
 * ```
 */
export declare function last<TElement, TFiltered extends TElement>(source: Iterable<TElement>, predicate: TypePredicate<TElement, TFiltered>): TFiltered;

/**
 * Returns the last element in the sequence that satisfies an optional predicate.
 * @template TElement Type of elements within the `source` iterable.
 * @param source The source iterable.
 * @param predicate Optional predicate evaluated against each element. When omitted, the final element of the sequence is returned.
 * @returns {TElement} The last element that satisfies {@link predicate}, or the final element when no predicate is supplied.
 * @throws {NoElementsException} Thrown when the sequence is empty.
 * @throws {NoMatchingElementException} Thrown when a predicate is supplied and no element satisfies it.
 * @remarks The entire sequence is enumerated to locate the final match.
 */
export declare function last<TElement>(source: Iterable<TElement>, predicate?: Predicate<TElement>): TElement;

/**
 * Returns the last element in the sequence or `null` when the sequence is empty or no element satisfies the predicate.
 * @template TElement Type of elements within the `source` iterable.
 * @template TFiltered Subtype confirmed when a type guard predicate is supplied.
 * @param source The source iterable.
 * @param predicate Predicate evaluated against each element. When omitted, the last element of the sequence is returned. When a type guard is supplied, the returned value is narrowed to `TFiltered`.
 * @returns {TElement | TFiltered | null} The last element that satisfies the predicate, or `null` when no match is found.
 * @remarks The entire sequence is enumerated to locate the final match. This function never throws for missing elements; it communicates absence through the `null` return value.
 * @example
 * ```typescript
 * const numbers = [1, 2, 3, 4, 5];
 * const lastElement = lastOrDefault(numbers);
 * console.log(lastElement); // 5
 *
 * const lastEven = lastOrDefault(numbers, x => x % 2 === 0);
 * console.log(lastEven); // 4
 *
 * const empty: number[] = [];
 * const lastOfEmpty = lastOrDefault(empty);
 * console.log(lastOfEmpty); // null
 *
 * const noEvens = [1, 3, 5];
 * const lastEven2 = lastOrDefault(noEvens, x => x % 2 === 0);
 * console.log(lastEven2); // null
 * ```
 */
export declare function lastOrDefault<TElement, TFiltered extends TElement>(source: Iterable<TElement>, predicate: TypePredicate<TElement, TFiltered>): TFiltered | null;

/**
 * Returns the last element in the sequence that satisfies an optional predicate, or `null` when none does.
 * @template TElement Type of elements within the `source` iterable.
 * @param source The source iterable.
 * @param predicate Optional predicate evaluated against each element. When omitted, the final element of the sequence is returned.
 * @returns {TElement | null} The last element that satisfies {@link predicate}, or `null` when the sequence is empty or no element matches.
 * @remarks Unlike {@link last}, this overload communicates absence through `null` instead of throwing.
 */
export declare function lastOrDefault<TElement>(source: Iterable<TElement>, predicate?: Predicate<TElement>): TElement | null;

/**
 * Produces a projection from the sequence and a second sequence by matching elements that share an identical join key. Outer elements with no match are included once with `null` as the inner value.
 * @template TElement Type of elements within the outer sequence.
 * @template TInner Type of elements within the inner sequence.
 * @template TKey Type of key produced by the key selectors.
 * @template TResult Type of element returned by {@link resultSelector}.
 * @param source The outer sequence.
 * @param innerEnumerable Sequence whose elements are joined with the outer sequence.
 * @param outerKeySelector Selector that extracts the join key from each outer element.
 * @param innerKeySelector Selector that extracts the join key from each inner element.
 * @param resultSelector Projection that combines an outer element with a matching inner element. When no match exists, `null` is supplied as the inner value.
 * @param keyComparator Optional equality comparator used to match keys. Defaults to the library's standard equality comparison when omitted.
 * @returns {IEnumerable<TResult>} A sequence generated by applying {@link resultSelector} to each matching pair (and unmatched outer elements).
 * @remarks The inner sequence is fully enumerated to build an in-memory lookup before outer elements are processed. The outer sequence is then enumerated lazily and its original ordering is preserved. This is a left outer join.
 * @example
 * ```typescript
 * const categories = [
 *   { id: 1, name: 'Fruit' },
 *   { id: 2, name: 'Vegetable' },
 * ];
 * const products = [
 *   { name: 'Apple', categoryId: 1 },
 *   { name: 'Banana', categoryId: 1 },
 *   { name: 'Unknown', categoryId: 3 },
 * ];
 *
 * const joined = leftJoin(
 *   categories,
 *   products,
 *   c => c.id,
 *   p => p.categoryId,
 *   (c, p) => ({ category: c.name, product: p?.name ?? null })
 * ).toArray();
 *
 * console.log(joined);
 * // [
 * //   { category: 'Fruit', product: 'Apple' },
 * //   { category: 'Fruit', product: 'Banana' },
 * //   { category: 'Vegetable', product: null }
 * // ]
 * ```
 */
export declare const leftJoin: <TElement, TInner, TKey, TResult>(source: Iterable<TElement>, innerEnumerable: Iterable<TInner>, outerKeySelector: Selector<TElement, TKey>, innerKeySelector: Selector<TInner, TKey>, resultSelector: JoinSelector<TElement, TInner, TResult>, keyComparator?: EqualityComparator<TKey>) => IEnumerable<TResult>;

export declare class LinkedList<TElement> extends AbstractList<TElement> {
    #private;
    constructor(iterable?: Iterable<TElement>, comparator?: EqualityComparator<TElement>);
    [Symbol.iterator](): Iterator<TElement>;
    add(element: TElement): boolean;
    addAt(element: TElement, index: number): boolean;
    addFirst(element: TElement): void;
    addLast(element: TElement): void;
    clear(): void;
    contains(element: TElement, comparator?: EqualityComparator<TElement>): boolean;
    get(index: number): TElement;
    getRange(index: number, count: number): LinkedList<TElement>;
    peek(): TElement | null;
    peekLast(): TElement | null;
    poll(): TElement | null;
    pollLast(): TElement | null;
    remove(element: TElement): boolean;
    removeAt(index: number): TElement;
    removeFirst(): TElement;
    removeLast(): TElement;
    set(index: number, element: TElement): TElement;
    size(): number;
    sort(comparator?: OrderComparator<TElement>): void;
    get comparator(): EqualityComparator<TElement>;
    get length(): number;
    private checkElementIndex;
    private checkPositionIndex;
    private isElementIndex;
    private isPositionIndex;
    private linkBefore;
    private linkFirst;
    private linkLast;
    private node;
    private unlink;
    private unlinkFirst;
    private unlinkLast;
    private set ListSize(value);
}

export declare class List<TElement> extends AbstractList<TElement> {
    #private;
    constructor(iterable?: Iterable<TElement>, comparator?: EqualityComparator<TElement>);
    [Symbol.iterator](): Iterator<TElement>;
    add(element: TElement): boolean;
    addAt(element: TElement, index: number): boolean;
    clear(): void;
    contains(element: TElement, comparator?: EqualityComparator<TElement>): boolean;
    get(index: number): TElement;
    getRange(index: number, count: number): List<TElement>;
    remove(element: TElement): boolean;
    removeAt(index: number): TElement;
    set(index: number, element: TElement): TElement;
    size(): number;
    sort(comparator?: OrderComparator<TElement>): void;
    toArray(): TElement[];
    toString(): string;
    toString(separator?: string): string;
    toString(separator?: string, selector?: Selector<TElement, string>): string;
    get comparator(): EqualityComparator<TElement>;
    get length(): number;
}

export declare class Lookup<TKey, TElement> extends AbstractEnumerable<IGroup<TKey, TElement>> implements ILookup<TKey, TElement> {
    #private;
    private constructor();
    static create<TSource, TKey, TValue>(source: Iterable<TSource>, keySelector: Selector<TSource, TKey>, valueSelector: Selector<TSource, TValue>, keyComparator?: OrderComparator<TKey>): Lookup<TKey, TValue>;
    [Symbol.iterator](): Iterator<IGroup<TKey, TElement>>;
    get(key: TKey): IEnumerable<TElement>;
    hasKey(key: TKey): boolean;
    size(): number;
    get length(): number;
}

/**
 * Returns the largest numeric value produced for the elements in the sequence.
 * @template TElement Type of elements within the `source` iterable.
 * @param source The source iterable.
 * @param selector Optional projection that extracts the numeric value for each element. Defaults to the element itself.
 * @returns {number} The maximum of the projected values.
 * @throws {NoElementsException} Thrown when the sequence is empty.
 * @remarks The entire sequence is enumerated exactly once. Provide a selector when the elements are not already numeric.
 * @example
 * ```typescript
 * const numbers = [1, 5, 2, 4, 3];
 * const maxNumber = max(numbers);
 * console.log(maxNumber); // 5
 *
 * const people = [
 *   { name: 'Alice', age: 25 },
 *   { name: 'Bob', age: 30 },
 *   { name: 'Charlie', age: 28 },
 * ];
 * const maxAge = max(people, p => p.age);
 * console.log(maxAge); // 30
 * ```
 */
export declare function max(source: Iterable<number>): number;

export declare function max<TElement>(source: Iterable<TElement>, selector: Selector<TElement, number>): number;

/**
 * Returns the element whose projected key is greatest according to the provided comparator.
 * @template TElement Type of elements within the `source` iterable.
 * @template TKey Type of key produced by {@link keySelector}.
 * @param source The source iterable.
 * @param keySelector Selector used to project each element to the key used for comparison.
 * @param comparator Optional order comparator used to compare keys. Defaults to the library's standard order comparison when omitted.
 * @returns {TElement} The element whose key is maximal.
 * @throws {NoElementsException} Thrown when the sequence is empty.
 * @remarks When multiple elements share the maximal key, the first such element in the sequence is returned.
 * @example
 * ```typescript
 * const people = [
 *   { name: 'Alice', age: 25 },
 *   { name: 'Bob', age: 30 },
 *   { name: 'Charlie', age: 28 },
 * ];
 * const oldestPerson = maxBy(people, p => p.age);
 * console.log(oldestPerson); // { name: 'Bob', age: 30 }
 * ```
 */
export declare const maxBy: <TElement, TKey>(source: Iterable<TElement>, keySelector: Selector<TElement, TKey>, comparator?: OrderComparator<TKey>) => TElement;

/**
 * Calculates the median of the numeric values produced by {@link source}.
 * @template TElement Type of elements within the {@link source} iterable.
 * @param source The source iterable to inspect.
 * @param selector Optional projection that extracts the numeric value for each element. Defaults to treating the element itself as numeric.
 * @param tie Determines how the median is resolved when {@link source} contains an even number of elements. Defaults to `"interpolate"`, which averages the two central values. Specify `"low"` or `"high"` to choose the lower or higher neighbour respectively.
 * @returns {number} The calculated median, or `NaN` when {@link source} contains no elements.
 * @throws {unknown} Re-throws any error thrown while iterating {@link source} or executing {@link selector}.
 * @remarks {@link source} is enumerated once and buffered so a selection algorithm can locate the middle element(s) without fully sorting. Supply {@link selector} when elements are not already numeric.
 * @example
 * ```typescript
 * const medianValue = median([1, 5, 2, 4, 3]);
 * console.log(medianValue); // 3
 *
 * const people = [
 *   { name: 'Alice', age: 23 },
 *   { name: 'Bella', age: 21 },
 *   { name: 'Mirei', age: 22 },
 *   { name: 'Hanna', age: 20 },
 *   { name: 'Noemi', age: 29 }
 * ];
 * const medianAge = median(people, p => p.age);
 * console.log(medianAge); // 22
 * ```
 */
export declare const median: <TElement>(source: Iterable<TElement>, selector?: Selector<TElement, number>, tie?: MedianTieStrategy) => number;

export declare type MedianTieStrategy = "high" | "interpolate" | "low";

/**
 * Returns the smallest numeric value produced for the elements in the sequence.
 * @template TElement Type of elements within the `source` iterable.
 * @param source The source iterable.
 * @param selector Optional projection that extracts the numeric value for each element. Defaults to the element itself.
 * @returns {number} The minimum of the projected values.
 * @throws {NoElementsException} Thrown when the sequence is empty.
 * @remarks The entire sequence is enumerated exactly once. Provide a selector when the elements are not already numeric.
 * @example
 * ```typescript
 * const numbers = [3, 1, 5, 2, 4];
 * const minNumber = min(numbers);
 * console.log(minNumber); // 1
 *
 * const people = [
 *   { name: 'Alice', age: 25 },
 *   { name: 'Bob', age: 30 },
 *   { name: 'Charlie', age: 22 },
 * ];
 * const minAge = min(people, p => p.age);
 * console.log(minAge); // 22
 * ```
 */
export declare function min(source: Iterable<number>): number;

export declare function min<TElement>(source: Iterable<TElement>, selector: Selector<TElement, number>): number;

/**
 * Returns the element whose projected key is smallest according to the provided comparator.
 * @template TElement Type of elements within the `source` iterable.
 * @template TKey Type of key produced by {@link keySelector}.
 * @param source The source iterable.
 * @param keySelector Selector used to project each element to the key used for comparison.
 * @param comparator Optional order comparator used to compare keys. Defaults to the library's standard order comparison when omitted.
 * @returns {TElement} The element whose key is minimal.
 * @throws {NoElementsException} Thrown when the sequence is empty.
 * @remarks When multiple elements share the minimal key, the first such element in the sequence is returned.
 * @example
 * ```typescript
 * const people = [
 *   { name: 'Alice', age: 25 },
 *   { name: 'Bob', age: 30 },
 *   { name: 'Charlie', age: 22 },
 * ];
 * const youngestPerson = minBy(people, p => p.age);
 * console.log(youngestPerson); // { name: 'Charlie', age: 22 }
 * ```
 */
export declare const minBy: <TElement, TKey>(source: Iterable<TElement>, keySelector: Selector<TElement, TKey>, comparator?: OrderComparator<TKey>) => TElement;

/**
 * Returns the element that appears most frequently in {@link source}.
 * @template TElement Type of elements within the {@link source} iterable.
 * @template TKey Type of key produced by {@link keySelector}.
 * @param source The source iterable to inspect.
 * @param keySelector Optional selector that projects each element to the key used for frequency counting. Defaults to the element itself.
 * @returns {TElement} The first element whose occurrence count matches the maximum frequency.
 * @throws {NoElementsException} Thrown when {@link source} is empty.
 * @throws {unknown} Re-throws any error thrown while iterating {@link source} or executing {@link keySelector}.
 * @remarks The source iterable is fully enumerated to build frequency counts before the result is determined. When multiple keys share the same frequency, the earliest corresponding element is returned.
 * @example
 * ```typescript
 * const winner = mode([1, 2, 2, 3]);
 * console.log(winner); // 2
 * ```
 */
export declare const mode: <TElement, TKey>(source: Iterable<TElement>, keySelector?: Selector<TElement, TKey>) => TElement;

/**
 * Returns the element that appears most frequently in {@link source}, or `null` when the iterable is empty.
 * @template TElement Type of elements within the {@link source} iterable.
 * @template TKey Type of key produced by {@link keySelector}.
 * @param source The source iterable to inspect.
 * @param keySelector Optional selector that projects each element to the key used for frequency counting. Defaults to the element itself.
 * @returns {TElement | null} The first most frequent element, or `null` when {@link source} contains no elements.
 * @throws {unknown} Re-throws any error thrown while iterating {@link source} or executing {@link keySelector}.
 * @remarks Unlike {@link mode}, this function communicates the absence of elements by returning `null`. When multiple keys share the maximum frequency, the element encountered first is returned.
 * @example
 * ```typescript
 * const winner = modeOrDefault<number>([]);
 * console.log(winner); // null
 * ```
 */
export declare const modeOrDefault: <TElement, TKey>(source: Iterable<TElement>, keySelector?: Selector<TElement, TKey>) => TElement | null;

/**
 * Produces the elements whose occurrence count is tied for the highest frequency in {@link source}.
 * @template TElement Type of elements within the {@link source} iterable.
 * @template TKey Type of key produced by {@link keySelector}.
 * @param source The source iterable to inspect.
 * @param keySelector Optional selector that projects each element to the key used for frequency counting. Defaults to the element itself.
 * @returns {IEnumerable<TElement>} A deferred sequence containing one representative element for each frequency mode.
 * @throws {unknown} Re-throws any error thrown while iterating {@link source} or executing {@link keySelector}.
 * @remarks Enumeration of the result buffers the entire source to compute frequency counts before yielding results. When multiple elements share a key, only the first occurrence is emitted.
 * @example
 * ```typescript
 * const modes = multimode([1, 2, 2, 3, 3]).toArray();
 * console.log(modes); // [2, 3]
 * ```
 */
export declare const multimode: <TElement, TKey>(source: Iterable<TElement>, keySelector?: Selector<TElement, TKey>) => IEnumerable<TElement>;

/**
 * Determines whether the sequence contains no elements that satisfy the optional predicate.
 * @template TElement Type of elements within the `source` iterable.
 * @param source The source iterable.
 * @param predicate Optional predicate evaluated against each element. When omitted, the function returns `true` if the sequence is empty.
 * @returns {boolean} `true` when no element satisfies the predicate (or when the sequence is empty and no predicate is provided); otherwise, `false`.
 * @remarks This is more efficient than negating `any` with a predicate because iteration stops as soon as a matching element is found.
 * @example
 * ```typescript
 * const numbers = [1, 3, 5];
 * const noEvens = none(numbers, x => x % 2 === 0);
 * console.log(noEvens); // true
 *
 * const mixedNumbers = [1, 2, 3, 5];
 * const noEvens2 = none(mixedNumbers, x => x % 2 === 0);
 * console.log(noEvens2); // false
 * ```
 */
export declare const none: <TElement>(source: Iterable<TElement>, predicate?: Predicate<TElement>) => boolean;

declare type NumberType = number | Number | NumberConstructor | "number";

declare type ObjectType<T = unknown> = PrimitiveSymbol | "symbol" | PrimitiveBoolean | "boolean" | PrimitiveNumber | "number" | PrimitiveBigInt | "bigint" | Class<T> | Function | "function" | PrimitiveObject | "object" | PrimitiveString | "string";

export declare class ObservableCollection<TElement> extends AbstractEnumerable<TElement> {
    #private;
    collectionChanged?: (sender: this, args: ICollectionChangedEventArgs<TElement>) => void;
    constructor();
    constructor(iterable?: Iterable<TElement>);
    constructor(iterable?: Iterable<TElement>, comparator?: EqualityComparator<TElement>);
    [Symbol.iterator](): Iterator<TElement>;
    add(element: TElement): boolean;
    clear(): void;
    contains(element: TElement, comparator?: EqualityComparator<TElement>): boolean;
    containsAll<TSource extends TElement>(iterable: Iterable<TSource>): boolean;
    get(index: number): TElement;
    insert(index: number, element: TElement): void;
    isEmpty(): boolean;
    move(oldIndex: number, newIndex: number): void;
    remove(element: TElement): boolean;
    removeAt(index: number): TElement;
    set(index: number, element: TElement): void;
    size(): number;
    get comparator(): EqualityComparator<TElement>;
    get length(): number;
}

/**
 * Filters the sequence, keeping only elements assignable to the specified type.
 * @template TElement Type of elements within the `source` iterable.
 * @template TResult Type descriptor used to filter elements (constructor function or primitive type string).
 * @param source The source iterable.
 * @param type Type descriptor that determines which elements are retained (e.g., 'string', `Number`, `Date`).
 * @returns {IEnumerable<InferredType<TResult>>} A sequence containing only the elements that match the specified type.
 * @remarks This function performs a runtime type check for each element and yields matching elements lazily.
 * @example
 * ```typescript
 * const mixed = [1, 'two', 3, 'four', new Date()];
 * const numbers = ofType(mixed, 'number').toArray();
 * console.log(numbers); // [1, 3]
 *
 * const dates = ofType(mixed, Date).toArray();
 * console.log(dates); // [Date object]
 * ```
 */
export declare const ofType: <TElement, TResult extends ObjectType>(source: Iterable<TElement>, type: TResult) => IEnumerable<InferredType<TResult>>;

/**
 * Sorts the elements of the sequence in ascending order using the provided comparator.
 * @template TElement Type of elements within the `source` iterable.
 * @param source The source iterable.
 * @param comparator Optional order comparator used to compare elements. Defaults to the library's standard order comparison when omitted.
 * @returns {IOrderedEnumerable<TElement>} An ordered sequence sorted ascending.
 * @remarks Sorting is deferred; the sequence is ordered only when iterated. Use `thenBy`/`thenByDescending` on the returned sequence to specify secondary keys.
 * @example
 * ```typescript
 * const numbers = [3, 1, 5, 2, 4];
 * const sorted = order(numbers).toArray();
 * console.log(sorted); // [1, 2, 3, 4, 5]
 * ```
 */
export declare const order: <TElement>(source: Iterable<TElement>, comparator?: OrderComparator<TElement>) => IOrderedEnumerable<TElement>;

/**
 * Sorts the elements of a sequence in ascending order by using a specified comparer.
 * @template TElement
 * @param source The source iterable.
 * @param keySelector The key selector function that will be used for selecting the key for an element.
 * @param comparator The comparator function that will be used for comparing two keys. If not specified, the default order comparison will be used.
 * @returns {IOrderedEnumerable<TElement>} A new enumerable sequence whose elements are sorted in ascending order.
 * @example
 * ```typescript
 * const people = [
 *   { name: 'Bob', age: 30 },
 *   { name: 'Alice', age: 25 },
 *   { name: 'Charlie', age: 22 },
 * ];
 * const sorted = orderBy(people, p => p.age).toArray();
 * console.log(sorted);
 * // [
 * //   { name: 'Charlie', age: 22 },
 * //   { name: 'Alice', age: 25 },
 * //   { name: 'Bob', age: 30 }
 * // ]
 * ```
 */
export declare const orderBy: <TElement, TKey>(source: Iterable<TElement>, keySelector: Selector<TElement, TKey>, comparator?: OrderComparator<TKey>) => IOrderedEnumerable<TElement>;

/**
 * Sorts the elements of a sequence in descending order by using a specified comparer.
 * @template TElement
 * @param source The source iterable.
 * @param keySelector The key selector function that will be used for selecting the key for an element.
 * @param comparator The comparator function that will be used for comparing two keys. If not specified, the default order comparison will be used.
 * @returns {IOrderedEnumerable<TElement>} A new enumerable sequence whose elements are sorted in descending order.
 * @example
 * ```typescript
 * const people = [
 *   { name: 'Charlie', age: 22 },
 *   { name: 'Alice', age: 25 },
 *   { name: 'Bob', age: 30 },
 * ];
 * const sorted = orderByDescending(people, p => p.age).toArray();
 * console.log(sorted);
 * // [
 * //   { name: 'Bob', age: 30 },
 * //   { name: 'Alice', age: 25 },
 * //   { name: 'Charlie', age: 22 }
 * // ]
 * ```
 */
export declare const orderByDescending: <TElement, TKey>(source: Iterable<TElement>, keySelector: Selector<TElement, TKey>, comparator?: OrderComparator<TKey>) => IOrderedEnumerable<TElement>;

export declare interface OrderComparator<TFirst, TSecond = TFirst> {
    (e1: TFirst, e2: TSecond): number;
}

/**
 * Sorts the elements of the sequence in descending order using the provided comparator.
 * @template TElement Type of elements within the `source` iterable.
 * @param source The source iterable.
 * @param comparator Optional order comparator used to compare elements. Defaults to the library's standard order comparison when omitted.
 * @returns {IOrderedEnumerable<TElement>} An ordered sequence sorted descending.
 * @remarks Sorting is deferred; the sequence is ordered only when iterated. Use `thenBy`/`thenByDescending` on the returned sequence to specify secondary keys.
 * @example
 * ```typescript
 * const numbers = [3, 1, 5, 2, 4];
 * const sorted = orderDescending(numbers).toArray();
 * console.log(sorted); // [5, 4, 3, 2, 1]
 * ```
 */
export declare const orderDescending: <TElement>(source: Iterable<TElement>, comparator?: OrderComparator<TElement>) => IOrderedEnumerable<TElement>;

export declare class OrderedAsyncEnumerator<TElement> extends AsyncEnumerator<TElement> implements IOrderedAsyncEnumerable<TElement> {
    readonly orderedValueGroups: () => AsyncIterable<AsyncIterable<TElement>>;
    constructor(orderedValueGroups: () => AsyncIterable<AsyncIterable<TElement>>);
    static createOrderedEnumerable<TElement, TKey>(source: AsyncIterable<TElement>, keySelector: Selector<TElement, TKey>, ascending: boolean, viaThenBy?: boolean, comparator?: OrderComparator<TKey>): IOrderedAsyncEnumerable<TElement>;
    private static createKeyValueMap;
}

export declare class OrderedEnumerator<TElement> extends Enumerator<TElement> implements IOrderedEnumerable<TElement> {
    readonly orderedValueGroups: () => Iterable<Iterable<TElement>>;
    constructor(orderedValueGroups: () => Iterable<Iterable<TElement>>);
    static createOrderedEnumerable<TElement, TKey>(source: Iterable<TElement>, keySelector: Selector<TElement, TKey>, ascending: boolean, viaThenBy?: boolean, comparator?: OrderComparator<TKey>): IOrderedEnumerable<TElement>;
    private static createKeyValueMap;
}

/**
 * Creates a deferred sequence of adjacent element pairs drawn from the source iterable.
 * @template TElement Type of elements within the `source` iterable.
 * @param source The source iterable.
 * @param resultSelector Optional projection applied to each current/next pair. Defaults to returning `[current, next]`.
 * @returns {IEnumerable<[TElement, TElement]>} A sequence with one element per consecutive pair from {@link source}.
 * @remarks The final element is omitted because it lacks a successor. {@link source} is enumerated lazily and exactly once.
 * @example
 * ```typescript
 * const numbers = [1, 2, 3, 4];
 * const pairs = pairwise(numbers).toArray();
 * console.log(pairs); // [[1, 2], [2, 3], [3, 4]]
 * ```
 */
export declare const pairwise: <TElement>(source: Iterable<TElement>, resultSelector?: PairwiseSelector<TElement, TElement>) => IEnumerable<[TElement, TElement]>;

export declare interface PairwiseSelector<TFirst, TSecond = TFirst, TResult = [TFirst, TSecond]> {
    (first: TFirst, second: TSecond): TResult;
}

/**
 * Splits the sequence into cached partitions using a type guard predicate.
 * @template TElement Type of elements within the `source` iterable.
 * @template TFiltered extends TElement Type produced when {@link predicate} narrows an element.
 * @param source The source iterable.
 * @param predicate Type guard invoked for each element. Elements that satisfy the predicate populate the first partition.
 * @returns {[IEnumerable<TFiltered>, IEnumerable<Exclude<TElement, TFiltered>>]} A tuple containing the matching partition and the partition with the remaining elements.
 * @remarks {@link source} is fully enumerated immediately and buffered so both partitions can be iterated repeatedly without re-evaluating the predicate.
 * @example
 * ```typescript
 * const numbers = [1, 2, 3, 4, 5, 6];
 * const [evens, odds] = partition(numbers, x => x % 2 === 0);
 * console.log(evens.toArray()); // [2, 4, 6]
 * console.log(odds.toArray()); // [1, 3, 5]
 * ```
 */
export declare function partition<TElement, TFiltered extends TElement>(source: Iterable<TElement>, predicate: TypePredicate<TElement, TFiltered>): [IEnumerable<TFiltered>, IEnumerable<Exclude<TElement, TFiltered>>];

/**
 * Splits the sequence into cached partitions using a boolean predicate.
 * @template TElement Type of elements within the `source` iterable.
 * @param source The source iterable.
 * @param predicate Predicate evaluated for each element. Elements for which it returns `true` populate the first partition.
 * @returns {[IEnumerable<TElement>, IEnumerable<TElement>]} A tuple containing the elements that satisfied {@link predicate} and those that did not.
 * @remarks {@link source} is fully enumerated immediately and buffered so both partitions can be iterated repeatedly without re-evaluating the predicate.
 */
export declare function partition<TElement>(source: Iterable<TElement>, predicate: Predicate<TElement>): [IEnumerable<TElement>, IEnumerable<TElement>];

/**
 * Calculates a percentile of the numeric values produced by {@link source}.
 * @template TElement Type of elements within the {@link source} iterable.
 * @param source The source iterable to inspect.
 * @param percent Percentile expressed as a fraction between 0 and 1 where `0` corresponds to the minimum and `1` to the maximum.
 * @param selector Optional projection that extracts the numeric value for each element. Defaults to treating the element itself as numeric.
 * @param strategy Strategy that determines how fractional ranks are resolved. Defaults to `"linear"`, which interpolates between neighbouring values. Alternative strategies include `"nearest"`, `"low"`, `"high"`, and `"midpoint"`.
 * @returns {number} The percentile value, or `NaN` when {@link source} contains no elements.
 * @throws {unknown} Re-throws any error thrown while iterating {@link source} or executing {@link selector}.
 * @remarks {@link source} is enumerated once and buffered so the selection algorithm can determine the requested rank without fully sorting the data. When {@link percent} is outside `[0, 1]`, the result is clamped to the range implied by {@link strategy}.
 * @example
 * ```typescript
 * const upperQuartile = percentile([1, 2, 3, 4, 5], 0.75);
 * console.log(upperQuartile); // 4
 *
 * const responseTimes = [
 *   { endpoint: '/users', duration: 120 },
 *   { endpoint: '/users', duration: 80 },
 *   { endpoint: '/users', duration: 200 }
 * ];
 * const p95 = percentile(responseTimes, 0.95, r => r.duration, "nearest");
 * console.log(p95); // 200
 * ```
 */
export declare function percentile(source: Iterable<number>, percent: number, strategy?: PercentileStrategy): number;

export declare function percentile<TElement>(source: Iterable<TElement>, percent: number, selector: Selector<TElement, number>, strategy?: PercentileStrategy): number;

export declare type PercentileStrategy = "linear" | "nearest" | "low" | "high" | "midpoint";

/**
 * Generates permutations from the distinct elements of the source iterable.
 * @template TElement Type of elements within the `source` iterable.
 * @param source The source iterable.
 * @param size Optional target length for each permutation. When omitted, permutations use all distinct elements of the source.
 * @returns {IEnumerable<IEnumerable<TElement>>} A lazy sequence of permutations, each materialised as an enumerable.
 * @throws {InvalidArgumentException} Thrown when {@link size} is less than 1 or greater than the number of distinct elements.
 * @remarks {@link source} is enumerated to collect distinct elements before permutations are produced. Expect combinatorial growth in the number of permutations.
 * @example
 * ```typescript
 * const numbers = [1, 2, 3];
 * const perms = permutations(numbers, 2);
 * console.log(perms.select(p => p.toArray()).toArray()); // [[1, 2], [1, 3], [2, 1], [2, 3], [3, 1], [3, 2]]
 * ```
 */
export declare const permutations: <TElement>(source: Iterable<TElement>, size?: number) => IEnumerable<IEnumerable<TElement>>;

/**
 * Applies a user-defined pipeline to {@link source} and returns the operator's result.
 * @template TElement Type of elements within {@link source}.
 * @template TResult Result type produced by {@link operator}.
 * @param source The iterable whose enumerable view is supplied to {@link operator}.
 * @param operator Function that receives the enumerable view of {@link source} and returns an arbitrary result.
 * @returns {TResult} The value produced by {@link operator} after optionally enumerating {@link source}.
 * @throws {unknown} Re-throws any error thrown by {@link operator} or during enumeration initiated by the operator.
 * @remarks The operator chooses how the sequence is consumed, making this helper convenient for custom aggregations, projections, or interop scenarios.
 * @example
 * ```typescript
 * const numbers = [1, 2, 3, 4, 5];
 * const sum = pipe(numbers, e => e.sum());
 * console.log(sum); // 15
 *
 * const filteredAndDoubled = pipe(numbers, e =>
 *   e.where(x => x % 2 === 0).select(x => x * 2).toArray()
 * );
 * console.log(filteredAndDoubled); // [4, 8]
 * ```
 */
export declare const pipe: <TElement, TResult>(source: Iterable<TElement>, operator: PipeOperator<TElement, TResult>) => TResult;

export declare interface PipeOperator<TElement, TResult> {
    (iterable: Iterable<TElement>): TResult;
}

declare type PlainObjectType = object | Object | ObjectConstructor;

export declare interface Predicate<TElement> {
    (element: TElement): boolean;
}

/**
 * Returns a deferred sequence that yields the supplied element before the source iterable.
 * @template TElement Type of elements within the `source` iterable.
 * @param source The source iterable.
 * @param element Element emitted before the original sequence.
 * @returns {IEnumerable<TElement>} A sequence that yields {@link element} followed by the elements from {@link source}.
 * @remarks Enumeration is deferred; {@link source} is not iterated until the resulting sequence is consumed.
 * @example
 * ```typescript
 * const numbers = [1, 2, 3];
 * const prepended = prepend(numbers, 0).toArray();
 * console.log(prepended); // [0, 1, 2, 3]
 * ```
 */
export declare const prepend: <TElement>(source: Iterable<TElement>, element: TElement) => IEnumerable<TElement>;

declare class PrimitiveBigInt {
    static [Symbol.hasInstance]: (x: unknown) => x is bigint;
}

declare class PrimitiveBoolean extends Boolean {
    static readonly [Symbol.hasInstance]: (x: unknown) => x is boolean;
}

declare class PrimitiveNumber extends Number {
    static readonly [Symbol.hasInstance]: (x: unknown) => x is number;
}

declare class PrimitiveObject extends Object {
    static readonly [Symbol.hasInstance]: (x: unknown) => x is object | null;
}

declare class PrimitiveString extends String {
    static readonly [Symbol.hasInstance]: (x: unknown) => x is string;
}

declare class PrimitiveSymbol {
    static [Symbol.hasInstance]: (x: unknown) => x is symbol;
}

export declare class PriorityQueue<TElement> extends AbstractCollection<TElement> {
    #private;
    constructor(iterable?: Iterable<TElement>, comparator?: OrderComparator<TElement>);
    [Symbol.iterator](): Iterator<TElement>;
    /**
     * Adds an element to the queue.
     * @template TElement The type of elements in the queue.
     * @param element The element to add.
     * @returns true
     */
    add(element: TElement): boolean;
    /**
     * Clears the queue.
     */
    clear(): void;
    contains(element: TElement): boolean;
    /**
     * Retrieves and removes the element at the beginning of the queue.
     * Unlike {@link poll}, this method throws an error if the queue is empty.
     * @template TElement The type of elements in the queue.
     * @returns {TElement} The head of the queue.
     * @throws {Error} If the queue is empty.
     */
    dequeue(): TElement;
    /**
     * Adds an element to the queue.
     * @template TElement The type of elements in the queue.
     * @param element The element to add.
     */
    enqueue(element: TElement): void;
    /**
     * Retrieves but does not remove the element at the beginning of the queue.
     * Unlike {@link peek}, this method throws an error if the queue is empty.
     * @template TElement The type of elements in the queue.
     * @returns {TElement} The head of the queue.
     * @throws {Error} If the queue is empty.
     */
    front(): TElement;
    isEmpty(): boolean;
    /**
     * Retrieves but does not remove the element at the beginning of the queue.
     * Unlike {@link front}, this method returns null if the queue is empty.
     * @template TElement The type of elements in the queue.
     * @returns {TElement | null} The head of the queue or null if the queue is empty.
     */
    peek(): TElement | null;
    /**
     * Retrieves and removes the element at the beginning of the queue.
     * Unlike {@link dequeue}, this method does not throw an error if the queue is empty.
     * @template TElement The type of elements in the queue.
     * @returns {TElement | null} The head of the queue, or null if the queue is empty.
     */
    poll(): TElement | null;
    size(): number;
    get comparator(): OrderComparator<TElement>;
    get length(): number;
}

/**
 * Computes the multiplicative aggregate of the values produced for each element in the source iterable.
 * @template TElement Type of elements within the `source` iterable.
 * @param source The source iterable.
 * @param selector Optional projection that extracts the numeric value for each element. Defaults to interpreting the element itself as a number.
 * @returns {number} The product of all projected values.
 * @throws {NoElementsException} Thrown when {@link source} is empty.
 * @remarks {@link source} is enumerated exactly once. Supply {@link selector} when elements are not already numeric.
 * @example
 * ```typescript
 * const numbers = [1, 2, 3, 4, 5];
 * const result = product(numbers);
 * console.log(result); // 120
 *
 * const people = [
 *   { name: 'Alice', age: 25 },
 *   { name: 'Bob', age: 30 },
 * ];
 * const ageProduct = product(people, p => p.age);
 * console.log(ageProduct); // 750
 * ```
 */
export declare function product(source: Iterable<number>): number;

export declare function product<TElement>(source: Iterable<TElement>, selector: Selector<TElement, number>): number;

export declare class Queue<TElement> extends AbstractCollection<TElement> {
    #private;
    constructor(iterable?: Iterable<TElement>, comparator?: EqualityComparator<TElement>);
    [Symbol.iterator](): Iterator<TElement>;
    /**
     * Adds an element to the end of the queue.
     * @param element The element that will be added to the queue.
     * @return true if the element was added to the queue, false otherwise.
     */
    add(element: TElement): boolean;
    clear(): void;
    contains(element: TElement, comparator?: EqualityComparator<TElement>): boolean;
    /**
     * Retrieves and returns the element at the beginning of the queue.
     * Unlike {@link poll}, this method does not return null if the queue is empty.
     * Instead, it throws an exception.
     * @template TElement The type of elements in the queue.
     * @returns {TElement} The head of the queue.
     * @throws {Error} If the queue is empty.
     */
    dequeue(): TElement;
    /**
     * Adds an element to the end of the queue.
     * @param element The element that will be added to the queue.
     */
    enqueue(element: TElement): void;
    /**
     * Retrieves but does not remove the element at the beginning of the queue.
     * Unlike {@link peek}, this method throws an error if the queue is empty.
     * @template TElement The type of elements in the queue.
     * @returns {TElement} The head of the queue.
     */
    front(): TElement;
    isEmpty(): boolean;
    /**
     * Retrieves but does not remove the element at the beginning of the queue.
     * Unlike {@link front}, this method returns null if the queue is empty.
     * @template TElement The type of elements in the queue.
     * @returns {TElement | null} The head of the queue or null if the queue is empty.
     */
    peek(): TElement | null;
    /**
     * Retrieves and removes the element at the beginning of the queue.
     * Unlike {@link dequeue}, this method does not throw an error if the queue is empty.
     * @template TElement The type of elements in the queue.
     * @returns {TElement | null} The head of the queue, or null if the queue is empty.
     */
    poll(): TElement | null;
    size(): number;
    get comparator(): EqualityComparator<TElement>;
    get length(): number;
}

/**
 * Generates a numeric range beginning at the specified start value.
 * @param start Start value of the range.
 * @param count Number of sequential values to produce.
 * @returns {IEnumerable<number>} A sequence of `count` integers starting from {@link start}.
 * @remarks Enumeration is deferred. When {@link count} is zero or negative, the resulting sequence is empty.
 * @example
 * ```typescript
 * const numbers = range(1, 5).toArray();
 * console.log(numbers); // [1, 2, 3, 4, 5]
 * ```
 */
export declare const range: (start: number, count: number) => IEnumerable<number>;

export declare class ReadonlyCollection<TElement> extends AbstractReadonlyCollection<TElement> {
    #private;
    constructor(collection: ICollection<TElement>, comparator?: EqualityComparator<TElement>);
    [Symbol.iterator](): Iterator<TElement>;
    contains(element: TElement, comparator?: EqualityComparator<TElement>): boolean;
    size(): number;
    get length(): number;
}

export declare class ReadonlyDictionary<TKey, TValue> extends AbstractReadonlyDictionary<TKey, TValue> {
    #private;
    constructor(dictionary: IDictionary<TKey, TValue>);
    [Symbol.iterator](): Iterator<KeyValuePair<TKey, TValue>>;
    containsKey(key: TKey): boolean;
    containsValue(value: TValue, comparator?: EqualityComparator<TValue>): boolean;
    entries(): IterableIterator<[TKey, TValue]>;
    get(key: TKey): TValue | null;
    keys(): ISet<TKey>;
    size(): number;
    values(): IImmutableCollection<TValue>;
    get length(): number;
}

export declare class ReadonlyList<TElement> extends AbstractReadonlyCollection<TElement> implements IReadonlyList<TElement> {
    #private;
    constructor(list: IList<TElement>);
    [Symbol.iterator](): Iterator<TElement>;
    contains(element: TElement, comparator?: EqualityComparator<TElement>): boolean;
    containsAll<TSource extends TElement>(collection: Iterable<TSource>): boolean;
    entries(): IterableIterator<[number, TElement]>;
    get(index: number): TElement;
    getRange(index: number, count: number): IReadonlyList<TElement>;
    indexOf(element: TElement, comparator?: EqualityComparator<TElement>): number;
    lastIndexOf(element: TElement, comparator?: EqualityComparator<TElement>): number;
    get length(): number;
    size(): number;
}

export declare class RedBlackTree<TElement> extends AbstractTree<TElement> {
    constructor(iterable?: Iterable<TElement>, comparator?: OrderComparator<TElement>);
    add(element: TElement): boolean;
    delete(element: TElement): void;
    insert(element: TElement): void;
    removeAll<TSource extends TElement>(collection: Iterable<TSource>): boolean;
    removeIf(predicate: Predicate<TElement>): boolean;
    search(element: TElement): boolean;
    private canMoveLeft;
    private canMoveRight;
    private deleteNode;
    private detachNodeFromParent;
    private findReplaceItem;
    private fixDoubleBlack;
    private fixDoubleRed;
    private getSuccessor;
    private handleBlackOrNullUncle;
    private handleBlackSibling;
    private handleBlackSiblingWithBlackChildren;
    private handleBlackSiblingWithRedChild;
    private handleLeftParent;
    private handleNullReplacement;
    private handleRedSibling;
    private handleRedUncle;
    private handleRightParent;
    private handleSiblingWithRedLeftChild;
    private handleSiblingWithRedRightChild;
    private handleSingleChildReplacement;
    private isExactMatch;
    private leftRotate;
    private moveLeft;
    private moveRight;
    private rightRotate;
    private searchNode;
    private swapColors;
    private swapValues;
}

/**
 * Creates a sequence that repeats the specified element a fixed number of times.
 * @template TElement Type of the repeated element.
 * @param element Element to repeat.
 * @param count Number of repetitions to produce.
 * @returns {IEnumerable<TElement>} A sequence containing {@link element} repeated {@link count} times.
 * @remarks Enumeration is deferred. When {@link count} is zero or negative, the resulting sequence is empty.
 * @example
 * ```typescript
 * const repeated = repeat('a', 5).toArray();
 * console.log(repeated); // ['a', 'a', 'a', 'a', 'a']
 * ```
 */
export declare const repeat: <TElement>(element: TElement, count: number) => IEnumerable<TElement>;

/**
 * Returns a deferred sequence that yields the source elements in reverse order.
 * @template TElement Type of elements within the `source` iterable.
 * @param source The source iterable.
 * @returns {IEnumerable<TElement>} A sequence that produces the elements of {@link source} in reverse iteration order.
 * @remarks The implementation materialises the entire sequence into an array before emitting elements, so avoid using it on infinite sequences or when memory usage is a concern.
 * @example
 * ```typescript
 * const numbers = [1, 2, 3, 4, 5];
 * const reversed = reverse(numbers).toArray();
 * console.log(reversed); // [5, 4, 3, 2, 1]
 * ```
 */
export declare const reverse: <TElement>(source: Iterable<TElement>) => IEnumerable<TElement>;

export declare const reverseInPlace: <TElement>(sequence: IList<TElement> | Array<TElement>) => void;

/**
 * Produces a projection from the sequence and a second sequence by matching elements that share an identical join key. Inner elements with no match are included once with `null` as the outer value.
 * @template TElement Type of elements within the outer sequence.
 * @template TInner Type of elements within the inner sequence.
 * @template TKey Type of key produced by the key selectors.
 * @template TResult Type of element returned by {@link resultSelector}.
 * @param source The outer sequence.
 * @param innerEnumerable Sequence whose elements are joined with the outer sequence.
 * @param outerKeySelector Selector that extracts the join key from each outer element.
 * @param innerKeySelector Selector that extracts the join key from each inner element.
 * @param resultSelector Projection that combines an outer element with a matching inner element. When no match exists, `null` is supplied as the outer value.
 * @param keyComparator Optional equality comparator used to match keys. Defaults to the library's standard equality comparison when omitted.
 * @returns {IEnumerable<TResult>} A sequence generated by applying {@link resultSelector} to each matching pair (and unmatched inner elements).
 * @remarks The outer sequence is fully enumerated to build an in-memory lookup before inner elements are processed. The inner sequence is then enumerated lazily and its original ordering is preserved. This is a right outer join.
 * @example
 * ```typescript
 * const categories = [
 *   { id: 1, name: 'Fruit' },
 *   { id: 2, name: 'Vegetable' },
 * ];
 * const products = [
 *   { name: 'Apple', categoryId: 1 },
 *   { name: 'Banana', categoryId: 1 },
 *   { name: 'Unknown', categoryId: 3 },
 * ];
 *
 * const joined = rightJoin(
 *   categories,
 *   products,
 *   c => c.id,
 *   p => p.categoryId,
 *   (c, p) => ({ category: c?.name ?? null, product: p.name })
 * ).toArray();
 *
 * console.log(joined);
 * // [
 * //   { category: 'Fruit', product: 'Apple' },
 * //   { category: 'Fruit', product: 'Banana' },
 * //   { category: null, product: 'Unknown' }
 * // ]
 * ```
 */
export declare const rightJoin: <TElement, TInner, TKey, TResult>(source: Iterable<TElement>, innerEnumerable: Iterable<TInner>, outerKeySelector: Selector<TElement, TKey>, innerKeySelector: Selector<TInner, TKey>, resultSelector: JoinSelector<TElement | null, TInner, TResult>, keyComparator?: EqualityComparator<TKey>) => IEnumerable<TResult>;

/**
 * Returns a deferred sequence that rotates the elements by the specified offset while preserving length.
 * @template TElement Type of elements within the `source` iterable.
 * @param source The source iterable.
 * @param shift Number of positions to rotate. Positive values move elements toward the end (left rotation); negative values move them toward the beginning (right rotation).
 * @returns {IEnumerable<TElement>} A sequence containing the same elements shifted by the requested amount.
 * @remarks The source is buffered sufficiently to honour the rotation. Rotation amounts larger than the length of {@link source} are normalised by that length, which may require buffering the full sequence.
 * @example
 * ```typescript
 * const numbers = [1, 2, 3, 4, 5];
 * const rotated = rotate(numbers, 2).toArray();
 * console.log(rotated); // [3, 4, 5, 1, 2]
 *
 * const rotatedNegative = rotate(numbers, -2).toArray();
 * console.log(rotatedNegative); // [4, 5, 1, 2, 3]
 * ```
 */
export declare const rotate: <TElement>(source: Iterable<TElement>, shift: number) => IEnumerable<TElement>;

/**
 * Accumulates the sequence and emits each intermediate result.
 * @template TElement Type of elements within the {@link source} iterable.
 * @template TAccumulate Accumulator type produced by {@link accumulator}; defaults to `TElement` when {@link seed} is omitted.
 * @param source The source iterable.
 * @param accumulator Function that merges the current accumulator value with the next element to produce the subsequent accumulator.
 * @param seed Optional initial accumulator. When omitted, the first element supplies the initial accumulator and is emitted as the first result.
 * @returns {IEnumerable<TAccumulate>} A deferred sequence containing every intermediate accumulator produced by {@link accumulator}.
 * @throws {NoElementsException} Thrown when {@link source} is empty and {@link seed} is not provided.
 * @remarks {@link source} is enumerated exactly once. Supplying {@link seed} prevents exceptions on empty sources but the seed itself is not emitted.
 * @example
 * ```typescript
 * const numbers = [1, 2, 3, 4, 5];
 * const runningTotal = scan(numbers, (acc, x) => acc + x).toArray();
 * console.log(runningTotal); // [1, 3, 6, 10, 15]
 * ```
 */
export declare function scan<TElement>(source: Iterable<TElement>, accumulator: Accumulator<TElement, TElement>): IEnumerable<TElement>;

export declare function scan<TElement, TAccumulate>(source: Iterable<TElement>, accumulator: Accumulator<TElement, TAccumulate>, seed: TAccumulate): IEnumerable<TAccumulate>;

/**
 * Transforms each element and its zero-based index into a new value.
 * @template TElement Type of elements within the {@link source} iterable.
 * @template TResult Result type produced by {@link selector}.
 * @param source The source iterable.
 * @param selector Projection invoked for each element together with its index.
 * @returns {IEnumerable<TResult>} A deferred sequence containing the values produced by {@link selector}.
 * @remarks Enumeration is deferred. The index argument increments sequentially starting at zero.
 * @example
 * ```typescript
 * const numbers = [1, 2, 3, 4, 5];
 * const squares = select(numbers, x => x * x).toArray();
 * console.log(squares); // [1, 4, 9, 16, 25]
 * ```
 */
export declare const select: <TElement, TResult>(source: Iterable<TElement>, selector: IndexedSelector<TElement, TResult>) => IEnumerable<TResult>;

/**
 * Projects each element and index into an iterable and flattens the results into a single sequence.
 * @template TElement Type of elements within the {@link source} iterable.
 * @template TResult Element type produced by the flattened iterables.
 * @param source The source iterable.
 * @param selector Projection that returns an iterable for each element and its index.
 * @returns {IEnumerable<TResult>} A deferred sequence containing the concatenated contents of the iterables produced by {@link selector}.
 * @remarks Each inner iterable is fully enumerated in order before the next source element is processed, preserving the relative ordering of results.
 * @example
 * ```typescript
 * const lists = [[1, 2], [3, 4], [5]];
 * const flattened = selectMany(lists, x => x).toArray();
 * console.log(flattened); // [1, 2, 3, 4, 5]
 * ```
 */
export declare const selectMany: <TElement, TResult>(source: Iterable<TElement>, selector: IndexedSelector<TElement, Iterable<TResult>>) => IEnumerable<TResult>;

export declare interface Selector<TElement, TResult> {
    (item: TElement): TResult;
}

/**
 * Generates a numeric sequence from the specified start value to the end value (inclusive) with the given step.
 * @param start Start value of the sequence.
 * @param end End value of the sequence (inclusive).
 * @param step Step size between consecutive values. Must be positive when ascending, negative when descending, and zero only when start equals end.
 * @returns {IEnumerable<number>} A sequence of numbers from {@link start} to {@link end} (inclusive) incremented by {@link step}.
 * @throws {InvalidArgumentException} Thrown when any parameter is NaN, when step direction doesn't match the start/end relationship, or when step is zero and start doesn't equal end.
 * @remarks Enumeration is deferred. The sequence includes {@link end} if it is reachable from {@link start} using the given {@link step}. For ascending sequences (start < end), step must be positive. For descending sequences (start > end), step must be negative.
 * @example
 * ```typescript
 * const ascending = sequence(1, 10, 1).toArray();
 * console.log(ascending); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
 * ```
 * @example
 * ```typescript
 * const descending = sequence(10, 1, -1).toArray();
 * console.log(descending); // [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
 * ```
 * @example
 * ```typescript
 * const stepped = sequence(1, 10, 2).toArray();
 * console.log(stepped); // [1, 3, 5, 7, 9]
 * ```
 */
export declare const sequence: (start: number, end: number, step: number) => IEnumerable<number>;

/**
 * Determines whether {@link source} and another iterable contain equal elements in the same order.
 * @template TElement Type of elements within the {@link source} iterable.
 * @param source The source iterable.
 * @param other Iterable to compare against the source sequence.
 * @param comparator Optional equality comparator used to compare element pairs. Defaults to the library's standard equality comparator.
 * @returns {boolean} `true` when both sequences have the same length and all corresponding elements are equal; otherwise, `false`.
 * @remarks Enumeration stops as soon as a mismatch or length difference is observed. Both sequences are fully enumerated only when they are equal.
 * @example
 * ```typescript
 * const numbers1 = [1, 2, 3];
 * const numbers2 = [1, 2, 3];
 * const numbers3 = [1, 2, 4];
 *
 * const areEqual1 = sequenceEqual(numbers1, numbers2);
 * console.log(areEqual1); // true
 *
 * const areEqual2 = sequenceEqual(numbers1, numbers3);
 * console.log(areEqual2); // false
 * ```
 */
export declare const sequenceEqual: <TElement>(source: Iterable<TElement>, other: Iterable<TElement>, comparator?: EqualityComparator<TElement>) => boolean;

/**
 * Returns a deferred sequence whose elements appear in random order.
 * @template TElement Type of elements within the {@link source} iterable.
 * @param source The source iterable.
 * @returns {IEnumerable<TElement>} A sequence containing the same elements as {@link source} but shuffled.
 * @remarks The implementation materialises the entire sequence into an array before shuffling, making this unsuitable for infinite sequences.
 * @example
 * ```typescript
 * const numbers = [1, 2, 3, 4, 5];
 * const shuffled = shuffle(numbers).toArray();
 * console.log(shuffled); // e.g., [3, 1, 5, 2, 4]
 * ```
 */
export declare const shuffle: <TElement>(source: Iterable<TElement>) => IEnumerable<TElement>;

export declare const shuffleInPlace: <TElement>(sequence: Array<TElement> | IList<TElement>) => void;

/**
 * Returns the only element that satisfies the provided type guard predicate.
 * @template TElement Type of elements within the {@link source} iterable.
 * @template TFiltered extends TElement Narrowed element type produced when {@link predicate} returns `true`.
 * @param source The source iterable.
 * @param predicate Type guard evaluated for each element. The returned value is narrowed to `TFiltered`.
 * @returns {TFiltered} The single element that satisfies {@link predicate}.
 * @throws {NoElementsException} Thrown when {@link source} is empty.
 * @throws {NoMatchingElementException} Thrown when no element satisfies {@link predicate}.
 * @throws {MoreThanOneMatchingElementException} Thrown when more than one element satisfies {@link predicate}.
 * @remarks {@link source} is fully enumerated to ensure exactly one matching element exists.
 * @example
 * ```typescript
 * const numbers = [5];
 * const singleElement = single(numbers);
 * console.log(singleElement); // 5
 *
 * const numbers2 = [1, 2, 3, 4, 5];
 * const singleEven = single(numbers2, x => x > 4);
 * console.log(singleEven); // 5
 * ```
 */
export declare function single<TElement, TFiltered extends TElement>(source: Iterable<TElement>, predicate: TypePredicate<TElement, TFiltered>): TFiltered;

/**
 * Returns the only element in the sequence or the only element that satisfies an optional predicate.
 * @template TElement Type of elements within the {@link source} iterable.
 * @param source The source iterable.
 * @param predicate Optional predicate evaluated for each element. When provided, the result must be the unique element for which it returns `true`.
 * @returns {TElement} The single element in {@link source} or the single element that satisfies {@link predicate}.
 * @throws {NoElementsException} Thrown when {@link source} is empty.
 * @throws {MoreThanOneElementException} Thrown when more than one element exists and {@link predicate} is omitted.
 * @throws {NoMatchingElementException} Thrown when {@link predicate} is provided and no element satisfies it.
 * @throws {MoreThanOneMatchingElementException} Thrown when {@link predicate} is provided and more than one element satisfies it.
 * @remarks {@link source} is fully enumerated to validate uniqueness.
 */
export declare function single<TElement>(source: Iterable<TElement>, predicate?: Predicate<TElement>): TElement;

/**
 * Returns the only element that satisfies the provided type guard predicate, or `null` when no such element exists.
 * @template TElement Type of elements within the {@link source} iterable.
 * @template TFiltered extends TElement Narrowed element type produced when {@link predicate} returns `true`.
 * @param source The source iterable.
 * @param predicate Type guard evaluated for each element. The returned value is narrowed to `TFiltered` when not `null`.
 * @returns {TFiltered | null} The single matching element, or `null` when no element satisfies {@link predicate}.
 * @throws {MoreThanOneMatchingElementException} Thrown when more than one element satisfies {@link predicate}.
 * @remarks {@link source} is fully enumerated to confirm uniqueness of the matching element.
 * @example
 * ```typescript
 * const numbers = [5];
 * const singleElement = singleOrDefault(numbers);
 * console.log(singleElement); // 5
 *
 * const numbers2 = [1, 2, 3, 4, 5];
 * const singleEven = singleOrDefault(numbers2, x => x > 4);
 * console.log(singleEven); // 5
 *
 * const empty: number[] = [];
 * const singleOfEmpty = singleOrDefault(empty);
 * console.log(singleOfEmpty); // null
 *
 * const noMatch = [1, 2, 3];
 * const singleNoMatch = singleOrDefault(noMatch, x => x > 4);
 * console.log(singleNoMatch); // null
 * ```
 */
export declare function singleOrDefault<TElement, TFiltered extends TElement>(source: Iterable<TElement>, predicate: TypePredicate<TElement, TFiltered>): TFiltered | null;

/**
 * Returns the only element in the sequence or the only element that satisfies an optional predicate, or `null` when no such element exists.
 * @template TElement Type of elements within the {@link source} iterable.
 * @param source The source iterable.
 * @param predicate Optional predicate evaluated for each element. When provided, the result must be the unique element for which it returns `true`.
 * @returns {TElement | null} The single element or matching element, or `null` when no element satisfies the conditions.
 * @throws {MoreThanOneElementException} Thrown when more than one element exists and {@link predicate} is omitted.
 * @throws {MoreThanOneMatchingElementException} Thrown when {@link predicate} is provided and more than one element satisfies it.
 * @remarks Unlike {@link single}, this method communicates the absence of a matching element by returning `null`.
 */
export declare function singleOrDefault<TElement>(source: Iterable<TElement>, predicate?: Predicate<TElement>): TElement | null;

/**
 * Skips a specified number of elements before yielding the remainder of the sequence.
 * @template TElement Type of elements within the {@link source} iterable.
 * @param source The source iterable.
 * @param count Number of elements to bypass. Values less than or equal to zero result in no elements being skipped.
 * @returns {IEnumerable<TElement>} A deferred sequence containing the elements that remain after skipping {@link count} items.
 * @remarks Enumeration advances through the skipped prefix without yielding any of those elements.
 * @example
 * ```typescript
 * const numbers = [1, 2, 3, 4, 5];
 * const skipped = skip(numbers, 2).toArray();
 * console.log(skipped); // [3, 4, 5]
 * ```
 */
export declare const skip: <TElement>(source: Iterable<TElement>, count: number) => IEnumerable<TElement>;

/**
 * Omits a specified number of elements from the end of the sequence.
 * @template TElement Type of elements within the {@link source} iterable.
 * @param source The source iterable.
 * @param count Number of trailing elements to exclude. Values less than or equal to zero leave the sequence unchanged.
 * @returns {IEnumerable<TElement>} A deferred sequence excluding the last {@link count} elements.
 * @remarks The implementation buffers up to {@link count} elements to determine which items to drop, which can increase memory usage for large counts.
 * @example
 * ```typescript
 * const numbers = [1, 2, 3, 4, 5];
 * const skipped = skipLast(numbers, 2).toArray();
 * console.log(skipped); // [1, 2, 3]
 * ```
 */
export declare const skipLast: <TElement>(source: Iterable<TElement>, count: number) => IEnumerable<TElement>;

/**
 * Skips elements until a type guard predicate returns `true`, then yields that element and the remainder, narrowing the element type.
 * @template TElement Type of elements within {@link source}.
 * @template TFiltered extends TElement Result type produced by {@link predicate}.
 * @param source The source iterable.
 * @param predicate Type guard invoked for each element and its zero-based index; once it returns `true`, that element and all following elements are yielded.
 * @returns {IEnumerable<TFiltered>} A deferred sequence starting with the first element that satisfies {@link predicate}.
 * @remarks The predicate's index parameter increments for each inspected element until the condition is met.
 * @example
 * ```typescript
 * const mixed: (number | string)[] = ['a', 'b', 1, 2];
 * const numbers = skipUntil(mixed, (x): x is number => typeof x === 'number').toArray();
 * console.log(numbers); // [1, 2]
 * ```
 */
export declare function skipUntil<TElement, TFiltered extends TElement>(source: Iterable<TElement>, predicate: IndexedTypePredicate<TElement, TFiltered>): IEnumerable<TFiltered>;

/**
 * Skips elements until a predicate returns `true`, then yields that element and the remainder.
 * @template TElement Type of elements within {@link source}.
 * @param source The source iterable.
 * @param predicate Predicate receiving the element and its zero-based index; once it returns `true`, enumeration stops skipping.
 * @returns {IEnumerable<TElement>} A deferred sequence starting with the first element that satisfies {@link predicate}.
 * @remarks The predicate runs until the first match is found; subsequent elements are yielded without further checks.
 * @example
 * ```typescript
 * const numbers = [0, 0, 1, 2, 3];
 * const result = skipUntil(numbers, (_, i) => i >= 2).toArray();
 * console.log(result); // [1, 2, 3]
 * ```
 */
export declare function skipUntil<TElement>(source: Iterable<TElement>, predicate: IndexedPredicate<TElement>): IEnumerable<TElement>;

/**
 * Skips elements while a predicate returns `true` and then yields the remaining elements.
 * @template TElement Type of elements within the {@link source} iterable.
 * @param source The source iterable.
 * @param predicate Predicate receiving the element and its zero-based index. The first element for which it returns `false` is included in the result.
 * @returns {IEnumerable<TElement>} A deferred sequence starting with the first element that fails {@link predicate}.
 * @remarks The predicate's index parameter increments only while elements are being skipped.
 * @example
 * ```typescript
 * const numbers = [1, 2, 3, 4, 5, 1, 2];
 * const skipped = skipWhile(numbers, x => x < 4).toArray();
 * console.log(skipped); // [4, 5, 1, 2]
 * ```
 */
export declare const skipWhile: <TElement>(source: Iterable<TElement>, predicate: IndexedPredicate<TElement>) => IEnumerable<TElement>;

export declare class SortedDictionary<TKey, TValue> extends AbstractDictionary<TKey, TValue> {
    #private;
    constructor();
    constructor(iterable: Iterable<KeyValuePair<TKey, TValue>>, keyComparator?: OrderComparator<TKey>, valueComparator?: EqualityComparator<TValue>);
    constructor(iterable: Iterable<[TKey, TValue]>, keyComparator?: OrderComparator<TKey>, valueComparator?: EqualityComparator<TValue>);
    constructor(iterable: Iterable<KeyValuePair<TKey, TValue>> | Iterable<[TKey, TValue]>, keyComparator?: OrderComparator<TKey>, valueComparator?: EqualityComparator<TValue>);
    [Symbol.iterator](): Iterator<KeyValuePair<TKey, TValue>>;
    add(key: TKey, value: TValue): TValue;
    clear(): void;
    containsKey(key: TKey): boolean;
    containsValue(value: TValue, comparator?: EqualityComparator<TValue>): boolean;
    entries(): IterableIterator<[TKey, TValue]>;
    get(key: TKey): TValue | null;
    keys(): ISet<TKey>;
    remove(key: TKey): TValue | null;
    set(key: TKey, value: TValue): void;
    size(): number;
    values(): IImmutableCollection<TValue>;
    get keyComparator(): OrderComparator<TKey>;
    get length(): number;
}

export declare class SortedSet<TElement> extends AbstractSet<TElement> implements ISet<TElement> {
    #private;
    constructor(iterable?: Iterable<TElement>, comparator?: OrderComparator<TElement>);
    [Symbol.iterator](): Iterator<TElement>;
    add(element: TElement): boolean;
    clear(): void;
    contains(element: TElement, comparator?: EqualityComparator<TElement>): boolean;
    headSet(toElement: TElement, inclusive?: boolean): ISet<TElement>;
    remove(element: TElement): boolean;
    removeAll<TSource extends TElement>(collection: Iterable<TSource>): boolean;
    removeIf(predicate: Predicate<TElement>): boolean;
    retainAll<TSource extends TElement>(collection: Iterable<TSource>): boolean;
    size(): number;
    subSet(fromElement: TElement, toElement: TElement, fromInclusive?: boolean, toInclusive?: boolean): ISet<TElement>;
    tailSet(fromElement: TElement, inclusive?: boolean): ISet<TElement>;
    get comparator(): OrderComparator<TElement>;
    get length(): number;
}

/**
 * Splits the sequence into the maximal leading span that satisfies a type guard and the remaining elements.
 * @template TElement Type of elements within the {@link source} iterable.
 * @template TFiltered extends TElement Narrowed element type produced when {@link predicate} returns `true`.
 * @param source The source iterable.
 * @param predicate Type guard evaluated for each element until it first returns `false`.
 * @returns {[IEnumerable<TFiltered>, IEnumerable<TElement>]} A tuple containing the contiguous matching prefix and the remainder of the sequence.
 * @remarks {@link source} is fully enumerated immediately and buffered so both partitions can be iterated repeatedly without re-evaluating {@link predicate}.
 * @example
 * ```typescript
 * const numbers = [1, 2, 3, 4, 1, 2];
 * const [first, second] = span(numbers, x => x < 3);
 * console.log(first.toArray()); // [1, 2]
 * console.log(second.toArray()); // [3, 4, 1, 2]
 * ```
 */
export declare function span<TElement, TFiltered extends TElement>(source: Iterable<TElement>, predicate: TypePredicate<TElement, TFiltered>): [IEnumerable<TFiltered>, IEnumerable<TElement>];

/**
 * Splits the sequence into the maximal leading span that satisfies a predicate and the remaining elements.
 * @template TElement Type of elements within the {@link source} iterable.
 * @param source The source iterable.
 * @param predicate Predicate evaluated for each element until it first returns `false`.
 * @returns {[IEnumerable<TElement>, IEnumerable<TElement>]} A tuple containing the contiguous matching prefix and the remainder of the sequence.
 * @remarks {@link source} is fully enumerated immediately and buffered so both partitions can be iterated repeatedly without re-evaluating {@link predicate}.
 */
export declare function span<TElement>(source: Iterable<TElement>, predicate: Predicate<TElement>): [IEnumerable<TElement>, IEnumerable<TElement>];

export declare class Stack<TElement> extends AbstractCollection<TElement> {
    #private;
    constructor(iterable?: Iterable<TElement>, comparator?: EqualityComparator<TElement>);
    [Symbol.iterator](): Iterator<TElement>;
    /**
     * Adds an element to the top of the stack.
     * @param element The element to add.
     */
    add(element: TElement): boolean;
    clear(): void;
    /**
     * Retrieves but does not remove the element at the beginning of the queue.
     * Unlike {@link top}, this method returns null if the queue is empty.
     * @template TElement The type of elements in the queue.
     * @returns {TElement | null} The head of the queue or null if the queue is empty.
     */
    peek(): TElement | null;
    /**
     * Retrieves and removes the element at the beginning of the queue.
     * @template TElement The type of elements in the queue.
     * @returns {TElement | null} The head of the queue, or null if the queue is empty.
     * @throws {Error} If the queue is empty.
     */
    pop(): TElement | null;
    /**
     * Adds an element to the top of the stack.
     * @param element The element to add.
     */
    push(element: TElement): void;
    size(): number;
    /**
     * Retrieves but does not remove the element at the beginning of the queue.
     * Unlike {@link peek}, this method throws an error if the queue is empty.
     * @template TElement The type of elements in the queue.
     * @returns {TElement} The head of the queue.
     */
    top(): TElement;
    get comparator(): EqualityComparator<TElement>;
    get length(): number;
}

/**
 * Calculates the standard deviation of the numeric values produced by {@link source}.
 * @template TElement Type of elements within the {@link source} iterable.
 * @param source The source iterable to inspect.
 * @param selector Optional projection that extracts the numeric value for each element. Defaults to the element itself.
 * @param sample When `true`, computes the sample standard deviation; when `false`, computes the population standard deviation. Defaults to `true`.
 * @returns {number} The calculated standard deviation, or `NaN` when there are insufficient values to compute it.
 * @throws {unknown} Re-throws any error thrown while iterating {@link source} or executing {@link selector}.
 * @remarks This function delegates to {@link variance}; when the variance is `NaN`, that value is returned unchanged. The iterable is enumerated exactly once using a numerically stable single-pass algorithm.
 * @example
 * ```typescript
 * const populationStdDev = standardDeviation([1, 2, 3, 4, 5], x => x, false);
 * console.log(populationStdDev); // Math.sqrt(2)
 * ```
 */
export declare const standardDeviation: <TElement>(source: Iterable<TElement>, selector?: Selector<TElement, number>, sample?: boolean) => number;

/**
 * Returns every n-th element of the sequence, starting with the first.
 * @template TElement Type of elements within the {@link source} iterable.
 * @param source The source iterable.
 * @param step Positive interval indicating how many elements to skip between yielded items.
 * @returns {IEnumerable<TElement>} A deferred sequence containing elements whose zero-based index is divisible by {@link step}.
 * @throws {InvalidArgumentException} Thrown when {@link step} is less than 1.
 * @remarks {@link source} is enumerated exactly once; elements that are not yielded are still visited to honour the stepping interval.
 * @example
 * ```typescript
 * const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9];
 * const stepped = step(numbers, 3).toArray();
 * console.log(stepped); // [1, 4, 7]
 * ```
 */
export declare const step: <TElement>(source: Iterable<TElement>, step: number) => IEnumerable<TElement>;

declare type StringType = string | String | StringConstructor | "string";

/**
 * Computes the sum of the numeric values produced for each element.
 * @template TElement Type of elements within the `source` iterable.
 * @param source The source iterable.
 * @param selector Optional projection that extracts the numeric value. Defaults to interpreting the element itself as a number.
 * @returns {number} The sum of the projected values.
 * @throws {NoElementsException} Thrown when {@link source} is empty.
 * @remarks {@link source} is enumerated exactly once. Supply {@link selector} when elements are not already numeric.
 * @example
 * ```typescript
 * const numbers = [1, 2, 3, 4, 5];
 * const total = sum(numbers);
 * console.log(total); // 15
 *
 * const people = [
 *   { name: 'Alice', age: 25 },
 *   { name: 'Bob', age: 30 },
 * ];
 * const totalAge = sum(people, p => p.age);
 * console.log(totalAge); // 55
 * ```
 */
export declare function sum(source: Iterable<number>): number;

export declare function sum<TElement>(source: Iterable<TElement>, selector: Selector<TElement, number>): number;

/**
 * Swaps the elements of the list at the given indices.
 * @param {IList|Array} sequence The list or array whose two elements will be swapped
 * @param {number} firstIndex The first index of the swap operation
 * @param {number} secondIndex The second index of the swap operation
 * @throws {IndexOutOfBoundsException} If the given indices are out of bounds.
 */
export declare const swap: <TElement>(sequence: IList<TElement> | Array<TElement>, firstIndex: number, secondIndex: number) => void;

declare type SymbolType = symbol | Symbol | SymbolConstructor | "symbol";

/**
 * Returns up to the specified number of leading elements from {@link source}.
 * @template TElement Type of elements within {@link source}.
 * @param source The source iterable.
 * @param count Number of elements to emit; values less than or equal to zero produce an empty sequence.
 * @returns {IEnumerable<TElement>} A deferred sequence containing at most {@link count} elements from the start of {@link source}.
 * @remarks Enumeration stops once {@link count} elements have been yielded or the source sequence ends.
 * @example
 * ```typescript
 * const numbers = [1, 2, 3, 4, 5];
 * const firstTwo = take(numbers, 2).toArray();
 * console.log(firstTwo); // [1, 2]
 *
 * const emptyTake = take(numbers, 0).toArray();
 * console.log(emptyTake); // []
 * ```
 */
export declare const take: <TElement>(source: Iterable<TElement>, count: number) => IEnumerable<TElement>;

/**
 * Returns up to the specified number of trailing elements from {@link source}.
 * @template TElement Type of elements within {@link source}.
 * @param source The source iterable.
 * @param count Number of elements to keep from the end; values less than or equal to zero produce an empty sequence.
 * @returns {IEnumerable<TElement>} A deferred sequence containing at most {@link count} elements from the end of {@link source}.
 * @remarks The implementation buffers up to {@link count} elements to determine the tail, so memory usage grows with {@link count}. The source must be finite.
 * @example
 * ```typescript
 * const numbers = [1, 2, 3, 4, 5];
 * const lastTwo = takeLast(numbers, 2).toArray();
 * console.log(lastTwo); // [4, 5]
 *
 * const emptyTakeLast = takeLast(numbers, 0).toArray();
 * console.log(emptyTakeLast); // []
 * ```
 */
export declare const takeLast: <TElement>(source: Iterable<TElement>, count: number) => IEnumerable<TElement>;

/**
 * Returns consecutive leading elements until a type guard predicate returns `true`, then stops.
 * @template TElement Type of elements within {@link source}.
 * @template TFiltered extends TElement Result type produced by {@link predicate}.
 * @param source The source iterable.
 * @param predicate Type guard invoked for each element and its zero-based index; iteration halts immediately when it returns `true`.
 * @returns {IEnumerable<TFiltered>} A deferred sequence containing the contiguous prefix produced before {@link predicate} succeeds.
 * @remarks Elements after the first element satisfying {@link predicate} are not inspected.
 * @example
 * ```typescript
 * const mixed: (number | string)[] = [1, 2, 'stop', 3];
 * const beforeStop = takeUntil(mixed, (x): x is string => typeof x === 'string').toArray();
 * console.log(beforeStop); // [1, 2]
 * ```
 */
export declare function takeUntil<TElement, TFiltered extends TElement>(source: Iterable<TElement>, predicate: IndexedTypePredicate<TElement, TFiltered>): IEnumerable<TFiltered>;

/**
 * Returns consecutive leading elements until a predicate returns `true`, then stops.
 * @template TElement Type of elements within {@link source}.
 * @param source The source iterable.
 * @param predicate Predicate invoked for each element and its zero-based index; iteration halts immediately when it returns `true`.
 * @returns {IEnumerable<TElement>} A deferred sequence containing the contiguous prefix produced before {@link predicate} succeeds.
 * @remarks Elements after the first element satisfying {@link predicate} are not inspected.
 * @example
 * ```typescript
 * const numbers = [1, 2, 3, 4, 5];
 * const taken = takeUntil(numbers, x => x > 3).toArray();
 * console.log(taken); // [1, 2, 3]
 * ```
 */
export declare function takeUntil<TElement>(source: Iterable<TElement>, predicate: IndexedPredicate<TElement>): IEnumerable<TElement>;

/**
 * Returns consecutive leading elements while a type guard predicate continues to succeed, narrowing the element type.
 * @template TElement Type of elements within {@link source}.
 * @template TFiltered extends TElement Narrowed element type produced by {@link predicate}.
 * @param source The source iterable.
 * @param predicate Type guard invoked for each element and its zero-based index; iteration stops immediately when it returns `false`.
 * @returns {IEnumerable<TFiltered>} A deferred sequence containing the contiguous prefix that satisfies {@link predicate}.
 * @remarks Elements after the first failing element are not inspected. Use this overload when you need the result to reflect the guarded type.
 * @example
 * ```typescript
 * const mixed: (number | string)[] = [1, 2, 'three', 4, 5];
 * const numbers = takeWhile(mixed, (x): x is number => typeof x === 'number').toArray();
 * console.log(numbers); // [1, 2]
 * ```
 */
export declare function takeWhile<TElement, TFiltered extends TElement>(source: Iterable<TElement>, predicate: IndexedTypePredicate<TElement, TFiltered>): IEnumerable<TFiltered>;

/**
 * Returns consecutive leading elements while a predicate returns `true`.
 * @template TElement Type of elements within {@link source}.
 * @param source The source iterable.
 * @param predicate Predicate invoked for each element and its zero-based index; iteration stops immediately when it returns `false`.
 * @returns {IEnumerable<TElement>} A deferred sequence containing the contiguous prefix that satisfies {@link predicate}.
 * @remarks Elements after the first failing element are not inspected.
 * @example
 * ```typescript
 * const numbers = [1, 2, 3, 4, 5, 1, 2];
 * const taken = takeWhile(numbers, x => x < 4).toArray();
 * console.log(taken); // [1, 2, 3]
 *
 * const takenWithIndex = takeWhile(numbers, (x, i) => i < 3).toArray();
 * console.log(takenWithIndex); // [1, 2, 3]
 * ```
 */
export declare function takeWhile<TElement>(source: Iterable<TElement>, predicate: IndexedPredicate<TElement>): IEnumerable<TElement>;

/**
 * Invokes the specified action for each element while yielding the original elements unchanged.
 * @template TElement Type of elements within {@link source}.
 * @param source The source iterable.
 * @param action Callback receiving the element and its zero-based index.
 * @returns {IEnumerable<TElement>} The original sequence, enabling fluent chaining.
 * @remarks The action executes lazily as the sequence is iterated, making it suitable for logging or instrumentation.
 * @example
 * ```typescript
 * const numbers = [1, 2, 3];
 * const tapped = tap(numbers, x => console.log(`Processing: ${x}`))
 *   .select(x => x * 2)
 *   .toArray();
 * console.log(tapped); // [2, 4, 6]
 * // Expected console output:
 * // Processing: 1
 * // Processing: 2
 * // Processing: 3
 * ```
 */
export declare const tap: <TElement>(source: Iterable<TElement>, action: IndexedAction<TElement>) => IEnumerable<TElement>;

/**
 * Materialises {@link source} into an array.
 * @template TElement Type of elements within {@link source}.
 * @param source The source iterable.
 * @returns {TElement[]} An array containing all elements from {@link source} in iteration order.
 * @remarks The entire sequence is enumerated immediately. Subsequent changes to {@link source} are not reflected in the returned array.
 * @example
 * ```typescript
 * const numbers = [1, 2, 3];
 * const array = toArray(numbers);
 * console.log(array); // [1, 2, 3]
 * ```
 */
export declare const toArray: <TElement>(source: Iterable<TElement>) => TElement[];

/**
 * Materialises {@link source} into a circular linked list.
 * @template TElement Type of elements within {@link source}.
 * @param source The source iterable.
 * @param comparator Optional equality comparator used by the resulting list.
 * @returns {CircularLinkedList<TElement>} A circular linked list containing all elements from {@link source}.
 * @remarks The entire sequence is enumerated immediately, and elements are stored in iteration order.
 * @example
 * ```typescript
 * const numbers = [1, 2, 3];
 * const circularList = toCircularLinkedList(numbers);
 * console.log(circularList.toArray()); // [1, 2, 3]
 * ```
 */
export declare const toCircularLinkedList: <TElement>(source: Iterable<TElement>, comparator?: EqualityComparator<TElement>) => CircularLinkedList<TElement>;

/**
 * Materialises {@link source} into a circular queue with the specified capacity.
 * @template TElement Type of elements within {@link source}.
 * @param source The source iterable.
 * @param capacity Maximum number of elements retained by the resulting queue.
 * @param comparator Optional equality comparator used by the resulting queue.
 * @returns {CircularQueue<TElement>} A circular queue containing the most recent elements from {@link source}, bounded by {@link capacity}.
 * @remarks The entire sequence is enumerated immediately. When {@link source} contains more than {@link capacity} elements, earlier items are discarded.
 * @example
 * ```typescript
 * const numbers = [1, 2, 3, 4, 5];
 * const circularQueue = toCircularQueue(numbers, 3);
 * console.log(circularQueue.toArray()); // [3, 4, 5]
 * ```
 */
export declare function toCircularQueue<TElement>(source: Iterable<TElement>, capacity: number, comparator?: EqualityComparator<TElement>): CircularQueue<TElement>;

/**
 * Materialises {@link source} into a circular queue using the implementation's default capacity.
 * @template TElement Type of elements within {@link source}.
 * @param source The source iterable.
 * @param comparator Optional equality comparator used by the resulting queue.
 * @returns {CircularQueue<TElement>} A circular queue containing the most recent elements from {@link source}, bounded by the default capacity.
 * @remarks The entire sequence is enumerated immediately. Earlier items are discarded when the number of elements exceeds the queue's capacity.
 */
export declare function toCircularQueue<TElement>(source: Iterable<TElement>, comparator?: EqualityComparator<TElement>): CircularQueue<TElement>;

/**
 * Materialises {@link source} into a dictionary keyed by the provided selector.
 * @template TElement Type of elements within {@link source}.
 * @template TKey Type of key returned by {@link keySelector}.
 * @template TValue Type of value returned by {@link valueSelector}.
 * @param source The source iterable.
 * @param keySelector Selector used to derive the key for each element.
 * @param valueSelector Selector used to derive the value for each element.
 * @param valueComparator Optional equality comparator used by the resulting dictionary to compare values.
 * @returns {Dictionary<TKey, TValue>} A dictionary populated with the projected key/value pairs.
 * @throws {InvalidArgumentException} Thrown when {@link keySelector} produces duplicate keys.
 * @remarks The entire sequence is enumerated immediately and entries are inserted in iteration order.
 * @example
 * ```typescript
 * const people = [
 *   { id: 1, name: 'Alice' },
 *   { id: 2, name: 'Bob' },
 * ];
 * const dictionary = toDictionary(people, p => p.id, p => p.name);
 * console.log(dictionary.get(1)); // 'Alice'
 * console.log(dictionary.get(2)); // 'Bob'
 * ```
 */
export declare const toDictionary: <TElement, TKey, TValue>(source: Iterable<TElement>, keySelector: Selector<TElement, TKey>, valueSelector: Selector<TElement, TValue>, valueComparator?: EqualityComparator<TValue>) => Dictionary<TKey, TValue>;

/**
 * Materialises {@link source} into an enumerable set containing the distinct elements.
 * @template TElement Type of elements within {@link source}.
 * @param source The source iterable.
 * @returns {EnumerableSet<TElement>} A set populated with the distinct elements from {@link source}.
 * @remarks The entire sequence is enumerated immediately and duplicate elements are collapsed using the set's equality semantics.
 * @example
 * ```typescript
 * const numbers = [1, 2, 2, 3, 1];
 * const set = toEnumerableSet(numbers);
 * console.log(set.toArray()); // [1, 2, 3]
 * ```
 */
export declare const toEnumerableSet: <TElement>(source: Iterable<TElement>) => EnumerableSet<TElement>;

/**
 * Materialises {@link source} into an immutable circular queue that uses the implementation's default capacity.
 * @template TElement Type of elements within {@link source}.
 * @param source The source iterable.
 * @param comparator Optional equality comparator used by the resulting queue.
 * @returns {ImmutableCircularQueue<TElement>} An immutable circular queue containing the most recent elements from {@link source}, up to the default capacity.
 * @remarks The entire sequence is enumerated immediately. Earlier items are discarded when the number of elements exceeds the queue's capacity (currently 32).
 * @example
 * ```typescript
 * const numbers = [1, 2, 3];
 * const immutableCircularQueue = toImmutableCircularQueue(numbers);
 * console.log(immutableCircularQueue.toArray()); // [1, 2, 3]
 * ```
 */
export declare function toImmutableCircularQueue<TElement>(source: Iterable<TElement>, comparator?: EqualityComparator<TElement>): ImmutableCircularQueue<TElement>;

/**
 * Materialises {@link source} into an immutable circular queue with the specified capacity.
 * @template TElement Type of elements within {@link source}.
 * @param source The source iterable.
 * @param capacity Maximum number of elements retained by the resulting queue.
 * @param comparator Optional equality comparator used by the resulting queue.
 * @returns {ImmutableCircularQueue<TElement>} An immutable circular queue containing the most recent elements from {@link source}, bounded by {@link capacity}.
 * @remarks The entire sequence is enumerated immediately. When {@link source} contains more than {@link capacity} elements, earlier items are discarded.
 * @example
 * ```typescript
 * const numbers = [1, 2, 3, 4, 5];
 * const immutableCircularQueue = toImmutableCircularQueue(numbers, 3);
 * console.log(immutableCircularQueue.toArray()); // [3, 4, 5]
 * ```
 */
export declare function toImmutableCircularQueue<TElement>(source: Iterable<TElement>, capacity: number, comparator?: EqualityComparator<TElement>): ImmutableCircularQueue<TElement>;

/**
 * Materialises {@link source} into an immutable dictionary keyed by the provided selector.
 * @template TElement Type of elements within {@link source}.
 * @template TKey Type of key returned by {@link keySelector}.
 * @template TValue Type of value returned by {@link valueSelector}.
 * @param source The source iterable.
 * @param keySelector Selector used to derive the key for each element.
 * @param valueSelector Selector used to derive the value for each element.
 * @param valueComparator Optional equality comparator used by the resulting dictionary to compare values.
 * @returns {ImmutableDictionary<TKey, TValue>} An immutable dictionary populated with the projected key/value pairs.
 * @throws {InvalidArgumentException} Thrown when {@link keySelector} produces duplicate keys.
 * @remarks The entire sequence is enumerated immediately.
 * @example
 * ```typescript
 * const people = [
 *   { id: 1, name: 'Alice' },
 *   { id: 2, name: 'Bob' },
 * ];
 * const immutableDictionary = toImmutableDictionary(people, p => p.id, p => p.name);
 * console.log(immutableDictionary.get(1)); // 'Alice'
 * console.log(immutableDictionary.get(2)); // 'Bob'
 * ```
 */
export declare const toImmutableDictionary: <TElement, TKey, TValue>(source: Iterable<TElement>, keySelector: Selector<TElement, TKey>, valueSelector: Selector<TElement, TValue>, valueComparator?: EqualityComparator<TValue>) => ImmutableDictionary<TKey, TValue>;

/**
 * Materialises {@link source} into an immutable list.
 * @template TElement Type of elements within {@link source}.
 * @param source The source iterable.
 * @param comparator Optional equality comparator used by the resulting list.
 * @returns {ImmutableList<TElement>} An immutable list containing all elements from {@link source} in iteration order.
 * @remarks The entire sequence is enumerated immediately.
 * @example
 * ```typescript
 * const numbers = [1, 2, 3];
 * const immutableList = toImmutableList(numbers);
 * console.log(immutableList.toArray()); // [1, 2, 3]
 * ```
 */
export declare const toImmutableList: <TElement>(source: Iterable<TElement>, comparator?: EqualityComparator<TElement>) => ImmutableList<TElement>;

/**
 * Materialises {@link source} into an immutable priority queue.
 * @template TElement Type of elements within {@link source}.
 * @param source The source iterable.
 * @param comparator Optional order comparator used to compare elements in the resulting queue.
 * @returns {ImmutablePriorityQueue<TElement>} An immutable priority queue containing all elements from {@link source}.
 * @remarks The entire sequence is enumerated immediately. Elements are ordered according to {@link comparator} or the default ordering.
 * @example
 * ```typescript
 * const numbers = [3, 1, 4, 1, 5, 9, 2, 6];
 * const immutablePriorityQueue = toImmutablePriorityQueue(numbers);
 * console.log(immutablePriorityQueue.toArray()); // [1, 1, 2, 3, 4, 5, 6, 9] (sorted)
 * ```
 */
export declare const toImmutablePriorityQueue: <TElement>(source: Iterable<TElement>, comparator?: OrderComparator<TElement>) => ImmutablePriorityQueue<TElement>;

/**
 * Materialises {@link source} into an immutable FIFO queue.
 * @template TElement Type of elements within {@link source}.
 * @param source The source iterable.
 * @param comparator Optional equality comparator used by the resulting queue.
 * @returns {ImmutableQueue<TElement>} An immutable queue containing all elements from {@link source} in enqueue order.
 * @remarks The entire sequence is enumerated immediately.
 * @example
 * ```typescript
 * const numbers = [1, 2, 3];
 * const immutableQueue = toImmutableQueue(numbers);
 * console.log(immutableQueue.toArray()); // [1, 2, 3]
 * ```
 */
export declare const toImmutableQueue: <TElement>(source: Iterable<TElement>, comparator?: EqualityComparator<TElement>) => ImmutableQueue<TElement>;

/**
 * Materialises {@link source} into an immutable set containing the distinct elements.
 * @template TElement Type of elements within {@link source}.
 * @param source The source iterable.
 * @returns {ImmutableSet<TElement>} An immutable set built from the distinct elements of {@link source}.
 * @remarks The entire sequence is enumerated immediately and duplicate elements are collapsed using the set's equality semantics.
 * @example
 * ```typescript
 * const numbers = [1, 2, 2, 3, 1];
 * const immutableSet = toImmutableSet(numbers);
 * console.log(immutableSet.toArray()); // [1, 2, 3]
 * ```
 */
export declare const toImmutableSet: <TElement>(source: Iterable<TElement>) => ImmutableSet<TElement>;

/**
 * Materialises {@link source} into an immutable sorted dictionary keyed by the provided selector.
 * @template TElement Type of elements within {@link source}.
 * @template TKey Type of key returned by {@link keySelector}.
 * @template TValue Type of value returned by {@link valueSelector}.
 * @param source The source iterable.
 * @param keySelector Selector used to derive the key for each element.
 * @param valueSelector Selector used to derive the value for each element.
 * @param keyComparator Optional order comparator used to sort keys in the resulting dictionary.
 * @param valueComparator Optional equality comparator used to compare values in the resulting dictionary.
 * @returns {ImmutableSortedDictionary<TKey, TValue>} An immutable sorted dictionary populated with the projected key/value pairs.
 * @throws {InvalidArgumentException} Thrown when {@link keySelector} produces duplicate keys.
 * @remarks The entire sequence is enumerated immediately.
 * @example
 * ```typescript
 * const people = [
 *   { id: 2, name: 'Bob' },
 *   { id: 1, name: 'Alice' },
 * ];
 * const immutableSortedDictionary = toImmutableSortedDictionary(people, p => p.id, p => p.name);
 * console.log(immutableSortedDictionary.keys().toArray()); // [1, 2]
 * console.log(immutableSortedDictionary.get(1)); // 'Alice'
 * ```
 */
export declare const toImmutableSortedDictionary: <TElement, TKey, TValue>(source: Iterable<TElement>, keySelector: Selector<TElement, TKey>, valueSelector: Selector<TElement, TValue>, keyComparator?: OrderComparator<TKey>, valueComparator?: EqualityComparator<TValue>) => ImmutableSortedDictionary<TKey, TValue>;

/**
 * Materialises {@link source} into an immutable sorted set of distinct elements.
 * @template TElement Type of elements within {@link source}.
 * @param source The source iterable.
 * @param comparator Optional order comparator used to sort the elements.
 * @returns {ImmutableSortedSet<TElement>} An immutable sorted set containing the distinct elements from {@link source}.
 * @remarks The entire sequence is enumerated immediately and duplicate elements are collapsed using the set's ordering semantics.
 * @example
 * ```typescript
 * const numbers = [3, 1, 4, 1, 5, 9, 2, 6];
 * const immutableSortedSet = toImmutableSortedSet(numbers);
 * console.log(immutableSortedSet.toArray()); // [1, 2, 3, 4, 5, 6, 9]
 * ```
 */
export declare const toImmutableSortedSet: <TElement>(source: Iterable<TElement>, comparator?: OrderComparator<TElement>) => ImmutableSortedSet<TElement>;

/**
 * Materialises {@link source} into an immutable stack (LIFO).
 * @template TElement Type of elements within {@link source}.
 * @param source The source iterable.
 * @param comparator Optional equality comparator used by the resulting stack.
 * @returns {ImmutableStack<TElement>} An immutable stack whose top element corresponds to the last element of {@link source}.
 * @remarks The entire sequence is enumerated immediately.
 * @example
 * ```typescript
 * const numbers = [1, 2, 3];
 * const immutableStack = toImmutableStack(numbers);
 * console.log(immutableStack.peek()); // 3
 * console.log(immutableStack.pop().peek()); // 2
 * ```
 */
export declare const toImmutableStack: <TElement>(source: Iterable<TElement>, comparator?: EqualityComparator<TElement>) => ImmutableStack<TElement>;

/**
 * Materialises {@link source} into a linked list.
 * @template TElement Type of elements within {@link source}.
 * @param source The source iterable.
 * @param comparator Optional equality comparator used by the resulting list.
 * @returns {LinkedList<TElement>} A linked list containing all elements from {@link source} in iteration order.
 * @remarks The entire sequence is enumerated immediately.
 * @example
 * ```typescript
 * const numbers = [1, 2, 3];
 * const linkedList = toLinkedList(numbers);
 * console.log(linkedList.toArray()); // [1, 2, 3]
 * ```
 */
export declare const toLinkedList: <TElement>(source: Iterable<TElement>, comparator?: EqualityComparator<TElement>) => LinkedList<TElement>;

/**
 * Materialises {@link source} into a resizable list.
 * @template TElement Type of elements within {@link source}.
 * @param source The source iterable.
 * @param comparator Optional equality comparator used by the resulting list.
 * @returns {List<TElement>} A list containing all elements from {@link source} in iteration order.
 * @remarks The entire sequence is enumerated immediately.
 * @example
 * ```typescript
 * const numbers = [1, 2, 3];
 * const list = toList(numbers);
 * console.log(list.toArray()); // [1, 2, 3]
 * ```
 */
export declare const toList: <TElement>(source: Iterable<TElement>, comparator?: EqualityComparator<TElement>) => List<TElement>;

/**
 * Materialises {@link source} into a lookup keyed by the provided selector.
 * @template TElement Type of elements within {@link source}.
 * @template TKey Type of key returned by {@link keySelector}.
 * @template TValue Type of value returned by {@link valueSelector}.
 * @param source The source iterable.
 * @param keySelector Selector used to derive the key for each element.
 * @param valueSelector Selector used to derive the value for each element.
 * @param keyComparator Optional order comparator used to compare keys in the resulting lookup.
 * @returns {ILookup<TKey, TValue>} A lookup grouping the projected values by key.
 * @remarks The entire sequence is enumerated immediately. Elements within each group preserve their original order and the groups are cached for repeated enumeration.
 * @example
 * ```typescript
 * const products = [
 *   { name: 'Apple', category: 'Fruit' },
 *   { name: 'Banana', category: 'Fruit' },
 *   { name: 'Carrot', category: 'Vegetable' },
 * ];
 * const lookup = toLookup(products, p => p.category, p => p.name);
 * console.log(lookup.get('Fruit').toArray()); // ['Apple', 'Banana']
 * console.log(lookup.get('Vegetable').toArray()); // ['Carrot']
 * ```
 */
export declare const toLookup: <TElement, TKey, TValue>(source: Iterable<TElement>, keySelector: Selector<TElement, TKey>, valueSelector: Selector<TElement, TValue>, keyComparator?: OrderComparator<TKey>) => ILookup<TKey, TValue>;

/**
 * Materialises {@link source} into a `Map` keyed by the provided selector.
 * @template TElement Type of elements within {@link source}.
 * @template TKey Type of key returned by {@link keySelector}.
 * @template TValue Type of value returned by {@link valueSelector}.
 * @param source The source iterable.
 * @param keySelector Selector used to derive the key for each element.
 * @param valueSelector Selector used to derive the value for each element.
 * @returns {Map<TKey, TValue>} A map populated with the projected key/value pairs.
 * @remarks The entire sequence is enumerated immediately. When {@link keySelector} produces duplicate keys, later elements overwrite earlier entries.
 * @example
 * ```typescript
 * const people = [
 *   { id: 1, name: 'Alice' },
 *   { id: 2, name: 'Bob' },
 * ];
 * const map = toMap(people, p => p.id, p => p.name);
 * console.log(map.get(1)); // 'Alice'
 * console.log(map.get(2)); // 'Bob'
 * ```
 */
export declare const toMap: <TElement, TKey, TValue>(source: Iterable<TElement>, keySelector: Selector<TElement, TKey>, valueSelector: Selector<TElement, TValue>) => Map<TKey, TValue>;

/**
 * Materialises {@link source} into a plain object keyed by the provided selector.
 * @template TElement Type of elements within {@link source}.
 * @template TKey extends PropertyKey Property key type returned by {@link keySelector}.
 * @template TValue Type of value returned by {@link valueSelector}.
 * @param source The source iterable.
 * @param keySelector Selector used to derive the property key for each element.
 * @param valueSelector Selector used to derive the value for each element.
 * @returns {Record<TKey, TValue>} An object populated with the projected key/value pairs.
 * @remarks The entire sequence is enumerated immediately. When {@link keySelector} produces duplicate keys, later values overwrite earlier ones.
 * @example
 * ```typescript
 * const people = [
 *   { id: 1, name: 'Alice' },
 *   { id: 2, name: 'Bob' },
 * ];
 * const obj = toObject(people, p => p.id, p => p.name);
 * console.log(obj[1]); // 'Alice'
 * console.log(obj[2]); // 'Bob'
 * ```
 */
export declare const toObject: <TElement, TKey extends PropertyKey, TValue>(source: Iterable<TElement>, keySelector: Selector<TElement, TKey>, valueSelector: Selector<TElement, TValue>) => Record<TKey, TValue>;

/**
 * Materialises {@link source} into a priority queue.
 * @template TElement Type of elements within {@link source}.
 * @param source The source iterable.
 * @param comparator Optional order comparator used to compare elements in the resulting queue.
 * @returns {PriorityQueue<TElement>} A priority queue containing all elements from {@link source}.
 * @remarks The entire sequence is enumerated immediately. Elements are ordered according to {@link comparator} or the default ordering.
 * @example
 * ```typescript
 * const numbers = [3, 1, 4, 1, 5, 9, 2, 6];
 * const priorityQueue = toPriorityQueue(numbers);
 * console.log(priorityQueue.dequeue()); // 1
 * console.log(priorityQueue.dequeue()); // 1
 * ```
 */
export declare const toPriorityQueue: <TElement>(source: Iterable<TElement>, comparator?: OrderComparator<TElement>) => PriorityQueue<TElement>;

/**
 * Materialises {@link source} into a FIFO queue.
 * @template TElement Type of elements within {@link source}.
 * @param source The source iterable.
 * @param comparator Optional equality comparator used by the resulting queue.
 * @returns {Queue<TElement>} A queue containing all elements from {@link source} in enqueue order.
 * @remarks The entire sequence is enumerated immediately.
 * @example
 * ```typescript
 * const numbers = [1, 2, 3];
 * const queue = toQueue(numbers);
 * console.log(queue.dequeue()); // 1
 * console.log(queue.dequeue()); // 2
 * ```
 */
export declare const toQueue: <TElement>(source: Iterable<TElement>, comparator?: EqualityComparator<TElement>) => Queue<TElement>;

/**
 * Materialises {@link source} into a native `Set`.
 * @template TElement Type of elements within {@link source}.
 * @param source The source iterable.
 * @returns {Set<TElement>} A set containing the distinct elements from {@link source}.
 * @remarks The entire sequence is enumerated immediately and duplicate elements are collapsed using JavaScript's `SameValueZero` semantics.
 * @example
 * ```typescript
 * const numbers = [1, 2, 2, 3, 1];
 * const set = toSet(numbers);
 * console.log(Array.from(set)); // [1, 2, 3]
 * ```
 */
export declare const toSet: <TElement>(source: Iterable<TElement>) => Set<TElement>;

/**
 * Materialises {@link source} into a sorted dictionary keyed by the provided selector.
 * @template TElement Type of elements within {@link source}.
 * @template TKey Type of key returned by {@link keySelector}.
 * @template TValue Type of value returned by {@link valueSelector}.
 * @param source The source iterable.
 * @param keySelector Selector used to derive the key for each element.
 * @param valueSelector Selector used to derive the value for each element.
 * @param keyComparator Optional order comparator used to sort keys in the resulting dictionary.
 * @param valueComparator Optional equality comparator used to compare values in the resulting dictionary.
 * @returns {SortedDictionary<TKey, TValue>} A sorted dictionary populated with the projected key/value pairs.
 * @throws {InvalidArgumentException} Thrown when {@link keySelector} produces duplicate keys.
 * @remarks The entire sequence is enumerated immediately.
 * @example
 * ```typescript
 * const people = [
 *   { id: 2, name: 'Bob' },
 *   { id: 1, name: 'Alice' },
 * ];
 * const sortedDictionary = toSortedDictionary(people, p => p.id, p => p.name);
 * console.log(sortedDictionary.keys().toArray()); // [1, 2]
 * console.log(sortedDictionary.get(1)); // 'Alice'
 * ```
 */
export declare const toSortedDictionary: <TElement, TKey, TValue>(source: Iterable<TElement>, keySelector: Selector<TElement, TKey>, valueSelector: Selector<TElement, TValue>, keyComparator?: OrderComparator<TKey>, valueComparator?: EqualityComparator<TValue>) => SortedDictionary<TKey, TValue>;

/**
 * Materialises {@link source} into a sorted set of distinct elements.
 * @template TElement Type of elements within {@link source}.
 * @param source The source iterable.
 * @param comparator Optional order comparator used to sort the elements.
 * @returns {SortedSet<TElement>} A sorted set containing the distinct elements from {@link source}.
 * @remarks The entire sequence is enumerated immediately and duplicate elements are collapsed using the set's ordering semantics.
 * @example
 * ```typescript
 * const numbers = [3, 1, 4, 1, 5, 9, 2, 6];
 * const sortedSet = toSortedSet(numbers);
 * console.log(sortedSet.toArray()); // [1, 2, 3, 4, 5, 6, 9]
 * ```
 */
export declare const toSortedSet: <TElement>(source: Iterable<TElement>, comparator?: OrderComparator<TElement>) => SortedSet<TElement>;

/**
 * Materialises {@link source} into a stack (LIFO).
 * @template TElement Type of elements within {@link source}.
 * @param source The source iterable.
 * @param comparator Optional equality comparator used by the resulting stack.
 * @returns {Stack<TElement>} A stack whose top element corresponds to the last element of {@link source}.
 * @remarks The entire sequence is enumerated immediately.
 * @example
 * ```typescript
 * const numbers = [1, 2, 3];
 * const stack = toStack(numbers);
 * console.log(stack.peek()); // 3
 * console.log(stack.pop().peek()); // 2
 * ```
 */
export declare const toStack: <TElement>(source: Iterable<TElement>, comparator?: EqualityComparator<TElement>) => Stack<TElement>;

export declare type TraverseType = "INORDER" | "PREORDER" | "POSTORDER";

export declare class Trie<TKey, TValue, TToken = TKey> extends AbstractEnumerable<[TKey, TValue]> {
    #private;
    constructor(tokenizer?: Selector<TKey, Iterable<TToken>> | null, tokenComparator?: EqualityComparator<TToken>);
    [Symbol.iterator](): IterableIterator<[TKey, TValue]>;
    /**
     * Removes all entries from the trie.
     */
    clear(): void;
    /**
     * Deletes a key from the trie.
     * @param key The key to delete.
     * @returns True if the key was found and deleted, false otherwise.
     */
    delete(key: TKey): boolean;
    /**
     * Gets the value associated with a key.
     * @param key The key to get the value for.
     * @returns The value associated with the key, or null if the key is not found.
     */
    get(key: TKey): TValue | null;
    /**
     * Checks if the trie contains a key.
     * @param key The key to check.
     * @returns True if the key exists, false otherwise.
     */
    has(key: TKey): boolean;
    /**
     * Inserts a key-value pair into the trie.
     * @param key The key to insert.
     * @param value The value associated with the key.
     */
    insert(key: TKey, value: TValue): void;
    /**
     * Yields all values with the given prefix.
     * @param prefix The prefix to search for.
     * @returns An iterable iterator of values with the given prefix.
     */
    prefix(prefix: TKey): IEnumerable<TValue>;
    /**
     * Gets the number of stored key-value pairs.
     * @returns The number of stored key-value pairs.
     */
    size(): number;
}

export declare interface TypePredicate<TElement, TFiltered extends TElement> {
    (element: TElement): element is TFiltered;
}

/**
 * Creates a set-style union between {@link source} and {@link other} using an equality comparator.
 * @template TElement Type of elements contained by the input sequences.
 * @param source The initial sequence whose distinct elements lead the union.
 * @param other Additional sequence whose elements are appended after {@link source} when forming the union.
 * @param comparator Optional equality comparator that determines whether two elements are considered the same. Defaults to the library's standard equality comparator.
 * @returns {IEnumerable<TElement>} A deferred sequence containing the distinct elements from {@link source} followed by elements from {@link other} that are not already present according to {@link comparator}.
 * @throws {unknown} Re-throws any error thrown while iterating either sequence or executing {@link comparator}.
 * @remarks Elements yielded by {@link source} always appear before contributions from {@link other}. Only comparison data required to detect duplicates is buffered, and each input is enumerated at most once.
 * @example
 * ```typescript
 * const numbers1 = [1, 2, 3, 4, 5];
 * const numbers2 = [3, 5, 6, 7];
 * const unioned = union(numbers1, numbers2).toArray();
 * console.log(unioned); // [1, 2, 3, 4, 5, 6, 7]
 * ```
 */
export declare const union: <TElement>(source: Iterable<TElement>, other: Iterable<TElement>, comparator?: EqualityComparator<TElement>) => IEnumerable<TElement>;

/**
 * Creates a set-style union between {@link source} and {@link other} by comparing keys projected from each element.
 * @template TElement Type of elements contained by the input sequences.
 * @template TKey Type of key produced by {@link keySelector}.
 * @param source The initial sequence whose distinct elements lead the union.
 * @param other Additional sequence whose elements are appended after {@link source} when forming the union.
 * @param keySelector Projection that produces a comparison key for each element.
 * @param comparator Optional equality comparator that determines whether two keys are considered the same. Defaults to the library's standard equality comparator.
 * @returns {IEnumerable<TElement>} A deferred sequence containing the distinct elements from {@link source} followed by elements from {@link other} whose keys were not previously observed.
 * @throws {unknown} Re-throws any error thrown while iterating either sequence or executing {@link keySelector} or {@link comparator}.
 * @remarks Keys are buffered to ensure uniqueness while elements remain lazily produced. Provide {@link comparator} when keys require structural equality semantics.
 * @example
 * ```typescript
 * const products1 = [
 *   { name: 'Apple', category: 'Fruit' },
 *   { name: 'Banana', category: 'Fruit' },
 * ];
 * const products2 = [
 *   { name: 'Carrot', category: 'Vegetable' },
 *   { name: 'Apple', category: 'Fruit' },
 * ];
 *
 * const unioned = unionBy(products1, products2, p => p.category).toArray();
 * console.log(unioned);
 * // [
 * //   { name: 'Apple', category: 'Fruit' },
 * //   { name: 'Banana', category: 'Fruit' },
 * //   { name: 'Carrot', category: 'Vegetable' }
 * // ]
 * ```
 */
export declare const unionBy: <TElement, TKey>(source: Iterable<TElement>, other: Iterable<TElement>, keySelector: Selector<TElement, TKey>, comparator?: EqualityComparator<TKey>) => IEnumerable<TElement>;

declare type UnpackAsyncIterableTuple<T extends readonly AsyncIterable<unknown>[]> = {
    [K in keyof T]: T[K] extends AsyncIterable<infer U> ? U : never;
};

declare type UnpackIterableTuple<T extends readonly Iterable<unknown>[]> = {
    [K in keyof T]: T[K] extends Iterable<infer U> ? U : never;
};

/**
 * Calculates the variance of the numeric values produced by {@link source}.
 * @template TElement Type of elements within the {@link source} iterable.
 * @param source The source iterable to inspect.
 * @param selector Optional projection that extracts the numeric value for each element. Defaults to the element itself.
 * @param sample When `true`, computes the sample variance dividing by _n - 1_; when `false`, computes the population variance dividing by _n_. Defaults to `true`.
 * @returns {number} The calculated variance, or `NaN` when {@link source} is empty—or for sample variance when it contains a single element.
 * @throws {unknown} Re-throws any error thrown while iterating {@link source} or executing {@link selector}.
 * @remarks A numerically stable single-pass algorithm (Welford's method) is used, so the iterable is enumerated exactly once regardless of size.
 * @example
 * ```typescript
 * const populationVariance = variance([1, 2, 3, 4, 5], x => x, false);
 * console.log(populationVariance); // 2
 * ```
 */
export declare const variance: <TElement>(source: Iterable<TElement>, selector?: Selector<TElement, number>, sample?: boolean) => number;

/**
 * Filters {@link source} using a type guard predicate and narrows the resulting element type.
 * @template TElement Type of elements within {@link source}.
 * @template TFiltered extends TElement Narrowed element type produced by {@link predicate}.
 * @param source The iterable to filter.
 * @param predicate Type guard invoked with each element and its zero-based index. Return `true` to keep the element in the results.
 * @returns {IEnumerable<TFiltered>} A deferred sequence containing only elements that satisfy the type guard.
 * @throws {unknown} Re-throws any error thrown while iterating {@link source} or executing {@link predicate}.
 * @remarks Enumeration is lazy; {@link predicate} executes on demand and may be invoked again when consumers restart iteration.
 * @example
 * ```typescript
 * const numbers = [1, 2, 3, 4, 5];
 * const evenNumbers = where(numbers, x => x % 2 === 0).toArray();
 * console.log(evenNumbers); // [2, 4]
 * ```
 */
export declare function where<TElement, TFiltered extends TElement>(source: Iterable<TElement>, predicate: IndexedTypePredicate<TElement, TFiltered>): IEnumerable<TFiltered>;

/**
 * Filters {@link source} using a predicate that can inspect both the element and its position.
 * @template TElement Type of elements within {@link source}.
 * @param source The iterable to filter.
 * @param predicate Predicate invoked with each element and its zero-based index. Return `true` to keep the element in the results.
 * @returns {IEnumerable<TElement>} A deferred sequence containing only the elements that satisfy {@link predicate}.
 * @throws {unknown} Re-throws any error thrown while iterating {@link source} or executing {@link predicate}.
 * @remarks Enumeration is lazy; {@link predicate} executes on demand and iteration stops as soon as the consumer stops reading.
 */
export declare function where<TElement>(source: Iterable<TElement>, predicate: IndexedPredicate<TElement>): IEnumerable<TElement>;

/**
 * Produces a sequence of sliding windows of fixed size over {@link source}.
 * @template TElement Type of elements within {@link source}.
 * @param source The iterable to window.
 * @param size Length of each window; must be at least 1.
 * @returns {IEnumerable<IEnumerable<TElement>>} A deferred sequence where each element exposes one contiguous window from {@link source}.
 * @throws {InvalidArgumentException} Thrown when {@link size} is less than 1.
 * @throws {unknown} Re-throws any error thrown while iterating {@link source}.
 * @remarks Windows overlap and are yielded only after enough source elements are observed to fill {@link size}. Trailing partial windows are omitted.
 * @example
 * ```typescript
 * const numbers = [1, 2, 3, 4, 5];
 * const windows = windows(numbers, 3);
 * console.log(windows.select(w => w.toArray()).toArray()); // [[1, 2, 3], [2, 3, 4], [3, 4, 5]]
 * ```
 */
export declare const windows: <TElement>(source: Iterable<TElement>, size: number) => IEnumerable<IEnumerable<TElement>>;

/**
 * Combines {@link source} with {@link other} and optionally projects each aligned pair using {@link zipper}.
 * @template TElement Type of elements within {@link source}.
 * @template TSecond Type of elements within {@link other}.
 * @template TResult Result type produced by {@link zipper}; defaults to `[TElement, TSecond]` when {@link zipper} is omitted.
 * @param source The primary sequence whose elements lead each pair.
 * @param other The secondary sequence whose elements are paired with {@link source}.
 * @param zipper Optional projection invoked with each `[source, other]` pair. When omitted, the tuples `[source, other]` are emitted.
 * @returns {IEnumerable<TResult>} A deferred sequence of projected results truncated to the length of the shorter input.
 * @throws {unknown} Re-throws any error thrown while iterating either input sequence or executing {@link zipper}.
 * @remarks Enumeration is lazy; pairs are produced on demand and iteration stops as soon as either input completes.
 * @example
 * ```typescript
 * const numbers = [1, 2, 3];
 * const letters = ['a', 'b', 'c'];
 * const zipped = zip(numbers, letters).toArray();
 * console.log(zipped); // [[1, 'a'], [2, 'b'], [3, 'c']]
 *
 * const zippedWithSelector = zip(numbers, letters, (num, letter) => `${num}-${letter}`).toArray();
 * console.log(zippedWithSelector); // ['1-a', '2-b', '3-c']
 * ```
 */
export declare const zip: <TElement, TSecond, TResult = [TElement, TSecond]>(source: Iterable<TElement>, other: Iterable<TSecond>, zipper?: Zipper<TElement, TSecond, TResult>) => IEnumerable<[TElement, TSecond]> | IEnumerable<TResult>;

/**
 * Zips {@link source} with the iterables supplied in {@link iterables}, producing aligned tuples.
 * @template TElement Type of elements in the {@link source} iterable.
 * @template TIterable Extends `readonly Iterable<unknown>[]`; each iterable's element type contributes to the resulting tuple.
 * @param source The primary iterable zipped with the additional iterables.
 * @param iterables Additional iterables to zip with {@link source}.
 * @returns {IEnumerable<[TElement, ...UnpackIterableTuple<TIterable>]>} A deferred sequence of tuples truncated to the length of the shortest input.
 * @throws {unknown} Re-throws any error raised while iterating {@link source} or any of {@link iterables}.
 * @remarks Iteration stops as soon as any participating iterable is exhausted. Tuple element types are inferred from the supplied iterables, preserving strong typing across the zipped result.
 * @example
 * ```typescript
 * const zipped = zipMany([1, 2, 3], ['A', 'B', 'C'], [true, false]).toArray();
 * console.log(zipped); // [[1, 'A', true], [2, 'B', false]]
 * ```
 */
export declare function zipMany<TElement, TIterable extends readonly Iterable<unknown>[]>(source: Iterable<TElement>, ...iterables: [...TIterable]): IEnumerable<[TElement, ...UnpackIterableTuple<TIterable>]>;

/**
 * Zips {@link source} with the iterables supplied in {@link iterablesAndZipper} and projects each tuple with {@link ZipManyZipper zipper}.
 * @template TElement Type of elements in the {@link source} iterable.
 * @template TIterable Extends `readonly Iterable<unknown>[]`; each iterable's element type contributes to the zipper input tuple.
 * @template TResult Result type produced by {@link ZipManyZipper zipper}.
 * @param source The primary iterable zipped with the additional iterables.
 * @param iterablesAndZipper The trailing argument may be a zipper invoked with each tuple to produce a projected result; preceding arguments are the iterables to zip with.
 * @returns {IEnumerable<TResult>} A deferred sequence of projected results truncated to the length of the shortest input.
 * @throws {unknown} Re-throws any error raised while iterating {@link source}, the supplied iterables, or executing the zipper.
 * @remarks The zipper receives a readonly tuple `[source, ...others]` for each aligned set. Iteration stops as soon as any participating iterable is exhausted.
 * @example
 * ```typescript
 * const labels = zipMany(
 *     [1, 2, 3],
 *     ['A', 'B', 'C'],
 *     [true, true, false],
 *     ([num, letter, flag]) => `${num}${letter}-${flag ? "yes" : "no"}`
 * ).toArray();
 * console.log(labels); // ["1A-yes", "2B-yes", "3C-no"]
 * ```
 */
export declare function zipMany<TElement, TIterable extends readonly Iterable<unknown>[], TResult>(source: Iterable<TElement>, ...iterablesAndZipper: [...TIterable, ZipManyZipper<[TElement, ...UnpackIterableTuple<TIterable>], TResult>]): IEnumerable<TResult>;

declare interface ZipManyZipper<TInputs extends readonly unknown[], TResult> {
    (values: readonly [...TInputs]): TResult;
}

export declare interface Zipper<TFirst, TSecond, TResult> {
    (sequence1: TFirst, sequence2: TSecond): TResult;
}

export { }
