// Don't change, this corresponds to DateTimeKind.Kind enum values in .NET
export const DateTimeKind = {
    Unspecified: 0,
    Utc: 1,
    Local: 2,
};
// Exception is intentionally not derived from Error, for performance reasons (see #2160)
export class Exception {
    constructor(msg) {
        this.message = msg ?? "";
    }
}
export function isException(x) {
    return x instanceof Exception || x instanceof Error;
}
export function isPromise(x) {
    return x instanceof Promise;
}
export function ensureErrorOrException(e) {
    // Exceptionally admitting promises as errors for compatibility with React.suspense (see #3298)
    return (isException(e) || isPromise(e)) ? e : new Exception(String(e));
}
export function isArrayLike(x) {
    return Array.isArray(x) || ArrayBuffer.isView(x);
}
export function isMutableArray(x) {
    return Array.isArray(x) || ArrayBuffer.isView(x);
}
export function isIterable(x) {
    return x != null && typeof x === "object" && Symbol.iterator in x;
}
export function isEnumerable(x) {
    return x != null && typeof x.GetEnumerator === "function";
}
export function isComparer(x) {
    return x != null && typeof x.Compare === "function";
}
export function isComparable(x) {
    return x != null && typeof x.CompareTo === "function";
}
export function isEquatable(x) {
    return x != null && typeof x.Equals === "function";
}
export function isHashable(x) {
    return x != null && typeof x.GetHashCode === "function";
}
export function isDisposable(x) {
    return x != null && typeof x.Dispose === "function";
}
export function disposeSafe(x) {
    if (isDisposable(x)) {
        x.Dispose();
    }
}
export function defaultOf() {
    return null;
}
export function sameConstructor(x, y) {
    return Object.getPrototypeOf(x)?.constructor === Object.getPrototypeOf(y)?.constructor;
}
export class Enumerable {
    constructor(en) { this.en = en; }
    GetEnumerator() { return this.en; }
    "System.Collections.IEnumerable.GetEnumerator"() { return this.en; }
    [Symbol.iterator]() {
        return this;
    }
    next() {
        const hasNext = this.en["System.Collections.IEnumerator.MoveNext"]();
        const current = hasNext ? this.en["System.Collections.Generic.IEnumerator`1.get_Current"]() : undefined;
        return { done: !hasNext, value: current };
    }
}
export class Enumerator {
    constructor(iter) {
        this.current = defaultOf();
        this.iter = iter;
    }
    ["System.Collections.Generic.IEnumerator`1.get_Current"]() {
        return this.current;
    }
    ["System.Collections.IEnumerator.get_Current"]() {
        return this.current;
    }
    ["System.Collections.IEnumerator.MoveNext"]() {
        const cur = this.iter.next();
        this.current = cur.value;
        return !cur.done;
    }
    ["System.Collections.IEnumerator.Reset"]() {
        throw new Exception("JS iterators cannot be reset");
    }
    Dispose() {
        return;
    }
}
export function toEnumerable(e) {
    if (isEnumerable(e)) {
        return e;
    }
    else {
        return new Enumerable(new Enumerator(e[Symbol.iterator]()));
    }
}
export function getEnumerator(e) {
    if (isEnumerable(e)) {
        return e.GetEnumerator();
    }
    else {
        return new Enumerator(e[Symbol.iterator]());
    }
}
export function toIterator(en) {
    return {
        next() {
            const hasNext = en["System.Collections.IEnumerator.MoveNext"]();
            const current = hasNext ? en["System.Collections.Generic.IEnumerator`1.get_Current"]() : undefined;
            return { done: !hasNext, value: current };
        },
    };
}
export function enumerableToIterator(e) {
    return toIterator(toEnumerable(e).GetEnumerator());
}
export class Comparer {
    constructor(f) {
        this.Compare = f || compare;
    }
}
export function comparerFromEqualityComparer(comparer) {
    // Sometimes IEqualityComparer also implements IComparer
    if (isComparer(comparer)) {
        return new Comparer(comparer.Compare);
    }
    else {
        return new Comparer((x, y) => {
            const xhash = comparer.GetHashCode(x);
            const yhash = comparer.GetHashCode(y);
            if (xhash === yhash) {
                return comparer.Equals(x, y) ? 0 : -1;
            }
            else {
                return xhash < yhash ? -1 : 1;
            }
        });
    }
}
export function assertEqual(actual, expected, msg) {
    if (!equals(actual, expected)) {
        throw Object.assign(new Exception(msg || `Expected: ${expected} - Actual: ${actual}`), {
            actual,
            expected,
        });
    }
}
export function assertNotEqual(actual, expected, msg) {
    if (equals(actual, expected)) {
        throw Object.assign(new Exception(msg || `Expected: ${expected} - Actual: ${actual}`), {
            actual,
            expected,
        });
    }
}
export class Lazy {
    constructor(factory) {
        this.factory = factory;
        this.isValueCreated = false;
    }
    get Value() {
        if (!this.isValueCreated) {
            this.createdValue = this.factory();
            this.isValueCreated = true;
        }
        return this.createdValue;
    }
    get IsValueCreated() {
        return this.isValueCreated;
    }
}
export function lazyFromValue(v) {
    return new Lazy(() => v);
}
export function padWithZeros(i, length) {
    return i.toString(10).padStart(length, "0");
}
export function padLeftAndRightWithZeros(i, lengthLeft, lengthRight) {
    return i.toString(10).padStart(lengthLeft, "0").padEnd(lengthRight, "0");
}
export function dateOffset(date) {
    const date1 = date;
    return typeof date1.offset === "number"
        ? date1.offset
        : (date.kind === DateTimeKind.Utc
            ? 0 : date.getTimezoneOffset() * -60000);
}
export function int16ToString(i, radix) {
    i = i < 0 && radix != null && radix !== 10 ? 0xFFFF + i + 1 : i;
    return i.toString(radix);
}
export function int32ToString(i, radix) {
    i = i < 0 && radix != null && radix !== 10 ? 0xFFFFFFFF + i + 1 : i;
    return i.toString(radix);
}
export function int64ToString(i, radix) {
    i = i < 0 && radix != null && radix !== 10 ? 0xffffffffffffffffn + i + 1n : i;
    return i.toString(radix);
}
export class ObjectRef {
    static id(o) {
        if (!ObjectRef.idMap.has(o)) {
            ObjectRef.idMap.set(o, ++ObjectRef.count);
        }
        return ObjectRef.idMap.get(o);
    }
}
ObjectRef.idMap = new WeakMap();
ObjectRef.count = 0;
export function stringHash(s) {
    let i = 0;
    let h = 5381;
    const len = s.length;
    while (i < len) {
        h = (h * 33) ^ s.charCodeAt(i++);
    }
    return h;
}
export function numberHash(x) {
    return x * 2654435761 | 0;
}
export function bigintHash(x) {
    return stringHash(x.toString(32));
}
// From https://stackoverflow.com/a/37449594
export function combineHashCodes(hashes) {
    let h1 = 0;
    const len = hashes.length;
    for (let i = 0; i < len; i++) {
        const h2 = hashes[i];
        h1 = ((h1 << 5) + h1) ^ h2;
    }
    return h1;
}
export function physicalHash(x) {
    if (x == null) {
        return 0;
    }
    switch (typeof x) {
        case "boolean":
            return x ? 1 : 0;
        case "number":
            return numberHash(x);
        case "bigint":
            return bigintHash(x);
        case "string":
            return stringHash(x);
        default:
            return numberHash(ObjectRef.id(x));
    }
}
export function identityHash(x) {
    if (isHashable(x)) {
        return x.GetHashCode();
    }
    else {
        return physicalHash(x);
    }
}
export function dateHash(x) {
    return x.getTime();
}
export function arrayHash(x) {
    const len = x.length;
    const hashes = new Array(len);
    for (let i = 0; i < len; i++) {
        hashes[i] = structuralHash(x[i]);
    }
    return combineHashCodes(hashes);
}
export function structuralHash(x) {
    if (x == null) {
        return 0;
    }
    switch (typeof x) {
        case "boolean":
            return x ? 1 : 0;
        case "number":
            return numberHash(x);
        case "bigint":
            return bigintHash(x);
        case "string":
            return stringHash(x);
        default: {
            if (isHashable(x)) {
                return x.GetHashCode();
            }
            else if (isArrayLike(x)) {
                return arrayHash(x);
            }
            else if (x instanceof Date) {
                return dateHash(x);
            }
            else if (Object.getPrototypeOf(x)?.constructor === Object) {
                // TODO: check call-stack to prevent cyclic objects?
                const hashes = Object.values(x).map((v) => structuralHash(v));
                return combineHashCodes(hashes);
            }
            else {
                // Classes don't implement GetHashCode by default, but must use identity hashing
                return numberHash(ObjectRef.id(x));
                // return stringHash(String(x));
            }
        }
    }
}
// Intended for custom numeric types, like long or decimal
export function fastStructuralHash(x) {
    return stringHash(String(x));
}
// Intended for declared types that may or may not implement GetHashCode
export function safeHash(x) {
    // return x == null ? 0 : isHashable(x) ? x.GetHashCode() : numberHash(ObjectRef.id(x));
    return identityHash(x);
}
export function equalArraysWith(x, y, eq) {
    if (x == null) {
        return y == null;
    }
    if (y == null) {
        return false;
    }
    if (x.length !== y.length) {
        return false;
    }
    for (let i = 0; i < x.length; i++) {
        if (!eq(x[i], y[i])) {
            return false;
        }
    }
    return true;
}
export function equalArrays(x, y) {
    return equalArraysWith(x, y, equals);
}
function equalObjects(x, y) {
    const xKeys = Object.keys(x);
    const yKeys = Object.keys(y);
    if (xKeys.length !== yKeys.length) {
        return false;
    }
    xKeys.sort();
    yKeys.sort();
    for (let i = 0; i < xKeys.length; i++) {
        if (xKeys[i] !== yKeys[i] || !equals(x[xKeys[i]], y[yKeys[i]])) {
            return false;
        }
    }
    return true;
}
export function physicalEquals(x, y) {
    return x === y;
}
export function equals(x, y) {
    if (x === y) {
        return true;
    }
    else if (x == null) {
        return y == null;
    }
    else if (y == null) {
        return false;
    }
    else if (isEquatable(x)) {
        return x.Equals(y);
    }
    else if (isArrayLike(x)) {
        return isArrayLike(y) && equalArrays(x, y);
    }
    else if (typeof x !== "object") {
        return false;
    }
    else if (x instanceof Date) {
        return (y instanceof Date) && compareDates(x, y) === 0;
    }
    else {
        return Object.getPrototypeOf(x)?.constructor === Object && equalObjects(x, y);
    }
}
export function compareDates(x, y) {
    let xtime;
    let ytime;
    // DateTimeOffset and DateTime deals with equality differently.
    if ("offset" in x && "offset" in y) {
        xtime = x.getTime();
        ytime = y.getTime();
    }
    else {
        xtime = x.getTime() + dateOffset(x);
        ytime = y.getTime() + dateOffset(y);
    }
    return xtime === ytime ? 0 : (xtime < ytime ? -1 : 1);
}
export function comparePrimitives(x, y) {
    return x === y ? 0 : (x < y ? -1 : 1);
}
export function compareArraysWith(x, y, comp) {
    if (x == null) {
        return y == null ? 0 : 1;
    }
    if (y == null) {
        return -1;
    }
    if (x.length !== y.length) {
        return x.length < y.length ? -1 : 1;
    }
    for (let i = 0, j = 0; i < x.length; i++) {
        j = comp(x[i], y[i]);
        if (j !== 0) {
            return j;
        }
    }
    return 0;
}
export function compareArrays(x, y) {
    return compareArraysWith(x, y, compare);
}
function compareObjects(x, y) {
    const xKeys = Object.keys(x);
    const yKeys = Object.keys(y);
    if (xKeys.length !== yKeys.length) {
        return xKeys.length < yKeys.length ? -1 : 1;
    }
    xKeys.sort();
    yKeys.sort();
    for (let i = 0, j = 0; i < xKeys.length; i++) {
        const key = xKeys[i];
        if (key !== yKeys[i]) {
            return key < yKeys[i] ? -1 : 1;
        }
        else {
            j = compare(x[key], y[key]);
            if (j !== 0) {
                return j;
            }
        }
    }
    return 0;
}
export function compare(x, y) {
    if (x === y) {
        return 0;
    }
    else if (x == null) {
        return y == null ? 0 : -1;
    }
    else if (y == null) {
        return 1;
    }
    else if (isComparable(x)) {
        return x.CompareTo(y);
    }
    else if (isArrayLike(x)) {
        return isArrayLike(y) ? compareArrays(x, y) : -1;
    }
    else if (typeof x !== "object") {
        return x < y ? -1 : 1;
    }
    else if (x instanceof Date) {
        return y instanceof Date ? compareDates(x, y) : -1;
    }
    else {
        return Object.getPrototypeOf(x)?.constructor === Object ? compareObjects(x, y) : -1;
    }
}
export function min(comparer, x, y) {
    return comparer(x, y) < 0 ? x : y;
}
export function max(comparer, x, y) {
    return comparer(x, y) > 0 ? x : y;
}
export function clamp(comparer, value, min, max) {
    return (comparer(value, min) < 0) ? min : (comparer(value, max) > 0) ? max : value;
}
export function createAtom(value) {
    let atom = value;
    return (...args) => {
        if (args.length === 0) {
            return atom;
        }
        else {
            atom = args[0];
        }
    };
}
export function createObj(fields) {
    const obj = {};
    for (const kv of fields) {
        obj[kv[0]] = kv[1];
    }
    return obj;
}
export function jsOptions(mutator) {
    const opts = {};
    mutator(opts);
    return opts;
}
export function round(value, digits = 0) {
    const m = Math.pow(10, digits);
    const n = +(digits ? value * m : value).toFixed(8);
    const i = Math.floor(n);
    const f = n - i;
    const e = 1e-8;
    const r = (f > 0.5 - e && f < 0.5 + e) ? ((i % 2 === 0) ? i : i + 1) : Math.round(n);
    return digits ? r / m : r;
}
export function sign(x) {
    return x > 0 ? 1 : x < 0 ? -1 : 0;
}
export function unescapeDataString(s) {
    // https://stackoverflow.com/a/4458580/524236
    return decodeURIComponent((s).replace(/\+/g, "%20"));
}
export function escapeDataString(s) {
    return encodeURIComponent(s).replace(/!/g, "%21")
        .replace(/'/g, "%27")
        .replace(/\(/g, "%28")
        .replace(/\)/g, "%29")
        .replace(/\*/g, "%2A");
}
export function escapeUriString(s) {
    return encodeURI(s);
}
// ICollection.Clear and Count members can be called on Arrays
// or Dictionaries so we need a runtime check (see #1120)
export function count(col) {
    if (isArrayLike(col)) {
        return col.length;
    }
    else {
        let count = 0;
        for (const _ of col) {
            count++;
        }
        return count;
    }
}
export function clear(col) {
    if (isArrayLike(col)) {
        col.splice(0);
    }
    else {
        col.clear();
    }
}
const curried = new WeakMap();
export function uncurry2(f) {
    if (f == null) {
        return null;
    }
    const f2 = (a1, a2) => f(a1)(a2);
    curried.set(f2, f);
    return f2;
}
export function curry2(f) {
    return curried.get(f) ?? ((a1) => (a2) => f(a1, a2));
}
export function uncurry3(f) {
    if (f == null) {
        return null;
    }
    const f2 = (a1, a2, a3) => f(a1)(a2)(a3);
    curried.set(f2, f);
    return f2;
}
export function curry3(f) {
    return curried.get(f)
        ?? ((a1) => (a2) => (a3) => f(a1, a2, a3));
}
export function uncurry4(f) {
    if (f == null) {
        return null;
    }
    const f2 = (a1, a2, a3, a4) => f(a1)(a2)(a3)(a4);
    curried.set(f2, f);
    return f2;
}
export function curry4(f) {
    return curried.get(f)
        ?? ((a1) => (a2) => (a3) => (a4) => f(a1, a2, a3, a4));
}
export function uncurry5(f) {
    if (f == null) {
        return null;
    }
    const f2 = (a1, a2, a3, a4, a5) => f(a1)(a2)(a3)(a4)(a5);
    curried.set(f2, f);
    return f2;
}
export function curry5(f) {
    return curried.get(f)
        ?? ((a1) => (a2) => (a3) => (a4) => (a5) => f(a1, a2, a3, a4, a5));
}
export function uncurry6(f) {
    if (f == null) {
        return null;
    }
    const f2 = (a1, a2, a3, a4, a5, a6) => f(a1)(a2)(a3)(a4)(a5)(a6);
    curried.set(f2, f);
    return f2;
}
export function curry6(f) {
    return curried.get(f)
        ?? ((a1) => (a2) => (a3) => (a4) => (a5) => (a6) => f(a1, a2, a3, a4, a5, a6));
}
export function uncurry7(f) {
    if (f == null) {
        return null;
    }
    const f2 = (a1, a2, a3, a4, a5, a6, a7) => f(a1)(a2)(a3)(a4)(a5)(a6)(a7);
    curried.set(f2, f);
    return f2;
}
export function curry7(f) {
    return curried.get(f)
        ?? ((a1) => (a2) => (a3) => (a4) => (a5) => (a6) => (a7) => f(a1, a2, a3, a4, a5, a6, a7));
}
export function uncurry8(f) {
    if (f == null) {
        return null;
    }
    const f2 = (a1, a2, a3, a4, a5, a6, a7, a8) => f(a1)(a2)(a3)(a4)(a5)(a6)(a7)(a8);
    curried.set(f2, f);
    return f2;
}
export function curry8(f) {
    return curried.get(f)
        ?? ((a1) => (a2) => (a3) => (a4) => (a5) => (a6) => (a7) => (a8) => f(a1, a2, a3, a4, a5, a6, a7, a8));
}
export function uncurry9(f) {
    if (f == null) {
        return null;
    }
    const f2 = (a1, a2, a3, a4, a5, a6, a7, a8, a9) => f(a1)(a2)(a3)(a4)(a5)(a6)(a7)(a8)(a9);
    curried.set(f2, f);
    return f2;
}
export function curry9(f) {
    return curried.get(f)
        ?? ((a1) => (a2) => (a3) => (a4) => (a5) => (a6) => (a7) => (a8) => (a9) => f(a1, a2, a3, a4, a5, a6, a7, a8, a9));
}
export function uncurry10(f) {
    if (f == null) {
        return null;
    }
    const f2 = (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) => f(a1)(a2)(a3)(a4)(a5)(a6)(a7)(a8)(a9)(a10);
    curried.set(f2, f);
    return f2;
}
export function curry10(f) {
    return curried.get(f)
        ?? ((a1) => (a2) => (a3) => (a4) => (a5) => (a6) => (a7) => (a8) => (a9) => (a10) => f(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10));
}
export function uncurry11(f) {
    if (f == null) {
        return null;
    }
    const f2 = (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) => f(a1)(a2)(a3)(a4)(a5)(a6)(a7)(a8)(a9)(a10)(a11);
    curried.set(f2, f);
    return f2;
}
export function curry11(f) {
    return curried.get(f)
        ?? ((a1) => (a2) => (a3) => (a4) => (a5) => (a6) => (a7) => (a8) => (a9) => (a10) => (a11) => f(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11));
}
export function uncurry12(f) {
    if (f == null) {
        return null;
    }
    const f2 = (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) => f(a1)(a2)(a3)(a4)(a5)(a6)(a7)(a8)(a9)(a10)(a11)(a12);
    curried.set(f2, f);
    return f2;
}
export function curry12(f) {
    return curried.get(f)
        ?? ((a1) => (a2) => (a3) => (a4) => (a5) => (a6) => (a7) => (a8) => (a9) => (a10) => (a11) => (a12) => f(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12));
}
export function uncurry13(f) {
    if (f == null) {
        return null;
    }
    const f2 = (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) => f(a1)(a2)(a3)(a4)(a5)(a6)(a7)(a8)(a9)(a10)(a11)(a12)(a13);
    curried.set(f2, f);
    return f2;
}
export function curry13(f) {
    return curried.get(f)
        ?? ((a1) => (a2) => (a3) => (a4) => (a5) => (a6) => (a7) => (a8) => (a9) => (a10) => (a11) => (a12) => (a13) => f(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13));
}
export function uncurry14(f) {
    if (f == null) {
        return null;
    }
    const f2 = (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) => f(a1)(a2)(a3)(a4)(a5)(a6)(a7)(a8)(a9)(a10)(a11)(a12)(a13)(a14);
    curried.set(f2, f);
    return f2;
}
export function curry14(f) {
    return curried.get(f)
        ?? ((a1) => (a2) => (a3) => (a4) => (a5) => (a6) => (a7) => (a8) => (a9) => (a10) => (a11) => (a12) => (a13) => (a14) => f(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14));
}
export function uncurry15(f) {
    if (f == null) {
        return null;
    }
    const f2 = (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) => f(a1)(a2)(a3)(a4)(a5)(a6)(a7)(a8)(a9)(a10)(a11)(a12)(a13)(a14)(a15);
    curried.set(f2, f);
    return f2;
}
export function curry15(f) {
    return curried.get(f)
        ?? ((a1) => (a2) => (a3) => (a4) => (a5) => (a6) => (a7) => (a8) => (a9) => (a10) => (a11) => (a12) => (a13) => (a14) => (a15) => f(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15));
}
export function uncurry16(f) {
    if (f == null) {
        return null;
    }
    const f2 = (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16) => f(a1)(a2)(a3)(a4)(a5)(a6)(a7)(a8)(a9)(a10)(a11)(a12)(a13)(a14)(a15)(a16);
    curried.set(f2, f);
    return f2;
}
export function curry16(f) {
    return curried.get(f)
        ?? ((a1) => (a2) => (a3) => (a4) => (a5) => (a6) => (a7) => (a8) => (a9) => (a10) => (a11) => (a12) => (a13) => (a14) => (a15) => (a16) => f(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16));
}
export function uncurry17(f) {
    if (f == null) {
        return null;
    }
    const f2 = (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17) => f(a1)(a2)(a3)(a4)(a5)(a6)(a7)(a8)(a9)(a10)(a11)(a12)(a13)(a14)(a15)(a16)(a17);
    curried.set(f2, f);
    return f2;
}
export function curry17(f) {
    return curried.get(f)
        ?? ((a1) => (a2) => (a3) => (a4) => (a5) => (a6) => (a7) => (a8) => (a9) => (a10) => (a11) => (a12) => (a13) => (a14) => (a15) => (a16) => (a17) => f(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17));
}
export function uncurry18(f) {
    if (f == null) {
        return null;
    }
    const f2 = (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18) => f(a1)(a2)(a3)(a4)(a5)(a6)(a7)(a8)(a9)(a10)(a11)(a12)(a13)(a14)(a15)(a16)(a17)(a18);
    curried.set(f2, f);
    return f2;
}
export function curry18(f) {
    return curried.get(f)
        ?? ((a1) => (a2) => (a3) => (a4) => (a5) => (a6) => (a7) => (a8) => (a9) => (a10) => (a11) => (a12) => (a13) => (a14) => (a15) => (a16) => (a17) => (a18) => f(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18));
}
export function uncurry19(f) {
    if (f == null) {
        return null;
    }
    const f2 = (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19) => f(a1)(a2)(a3)(a4)(a5)(a6)(a7)(a8)(a9)(a10)(a11)(a12)(a13)(a14)(a15)(a16)(a17)(a18)(a19);
    curried.set(f2, f);
    return f2;
}
export function curry19(f) {
    return curried.get(f)
        ?? ((a1) => (a2) => (a3) => (a4) => (a5) => (a6) => (a7) => (a8) => (a9) => (a10) => (a11) => (a12) => (a13) => (a14) => (a15) => (a16) => (a17) => (a18) => (a19) => f(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19));
}
export function uncurry20(f) {
    if (f == null) {
        return null;
    }
    const f2 = (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) => f(a1)(a2)(a3)(a4)(a5)(a6)(a7)(a8)(a9)(a10)(a11)(a12)(a13)(a14)(a15)(a16)(a17)(a18)(a19)(a20);
    curried.set(f2, f);
    return f2;
}
export function curry20(f) {
    return curried.get(f)
        ?? ((a1) => (a2) => (a3) => (a4) => (a5) => (a6) => (a7) => (a8) => (a9) => (a10) => (a11) => (a12) => (a13) => (a14) => (a15) => (a16) => (a17) => (a18) => (a19) => (a20) => f(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20));
}
// More performant method to copy arrays, see #2352
export function copyToArray(source, sourceIndex, target, targetIndex, count) {
    if (ArrayBuffer.isView(source) && ArrayBuffer.isView(target)) {
        target.set(source.subarray(sourceIndex, sourceIndex + count), targetIndex);
    }
    else {
        for (let i = 0; i < count; ++i) {
            target[targetIndex + i] = source[sourceIndex + i];
        }
    }
}
