const base = {}; base.Int64 = class Int64 { constructor(low, high) { this.low = low | 0; this.high = high | 0; } static create(value) { if (isNaN(value)) { return base.Int64.zero; } if (value <= -9223372036854776000) { return base.Int64.min; } if (value + 1 >= 9223372036854776000) { return base.Int64.max; } if (value < 0) { return base.Int64.create(-value).negate(); } return new base.Int64((value % 4294967296) | 0, (value / 4294967296)); } get isZero() { return this.low === 0 && this.high === 0; } get isNegative() { return this.high < 0; } negate() { if (this.equals(base.Int64.min)) { return base.Int64.min; } return this.not().add(base.Int64.one); } not() { return new base.Int64(~this.low, ~this.high); } equals(other) { if (!(other instanceof base.Int64) && (this.high >>> 31) === 1 && (other.high >>> 31) === 1) { return false; } return this.high === other.high && this.low === other.low; } compare(other) { if (this.equals(other)) { return 0; } const thisNeg = this.isNegative; const otherNeg = other.isNegative; if (thisNeg && !otherNeg) { return -1; } if (!thisNeg && otherNeg) { return 1; } return this.subtract(other).isNegative ? -1 : 1; } add(other) { return base.Utility.add(this, other, false); } subtract(other) { return base.Utility.subtract(this, other, false); } multiply(other) { return base.Utility.multiply(this, other, false); } divide(other) { return base.Utility.divide(this, other, false); } toInteger() { return this.low; } toNumber() { if (this.high === 0) { return this.low >>> 0; } if (this.high === -1) { return this.low; } return (this.high * 4294967296) + (this.low >>> 0); } toString(radix) { const r = radix || 10; if (r < 2 || r > 16) { throw new RangeError('radix'); } if (this.isZero) { return '0'; } if (this.high < 0) { if (this.equals(base.Int64.min)) { const radix = new base.Int64(r, 0); const div = this.divide(radix); const remainder = div.multiply(radix).subtract(this); return div.toString(radix) + (remainder.low >>> 0).toString(radix); } return '-' + this.negate().toString(r); } if (this.high === 0) { return this.low.toString(radix); } return base.Utility.text(this, false, r); } }; base.Int64.min = new base.Int64(0, -2147483648); base.Int64.zero = new base.Int64(0, 0); base.Int64.one = new base.Int64(1, 0); base.Int64.negativeOne = new base.Int64(-1, 0); base.Int64.power24 = new base.Int64(1 << 24, 0); base.Int64.max = new base.Int64(0, 2147483647); base.Uint64 = class Uint64 { constructor(low, high) { this.low = low | 0; this.high = high | 0; } static create(value) { if (isNaN(value)) { return base.Uint64.zero; } if (value < 0) { return base.Uint64.zero; } if (value >= 18446744073709552000) { return base.Uint64.max; } if (value < 0) { return base.Uint64.create(-value).negate(); } return new base.Uint64((value % 4294967296) | 0, (value / 4294967296)); } get isZero() { return this.low === 0 && this.high === 0; } get isNegative() { return false; } negate() { return this.not().add(base.Int64.one); } not() { return new base.Uint64(~this.low, ~this.high); } equals(other) { if (!(other instanceof base.Uint64) && (this.high >>> 31) === 1 && (other.high >>> 31) === 1) { return false; } return this.high === other.high && this.low === other.low; } compare(other) { if (this.equals(other)) { return 0; } const thisNeg = this.isNegative; const otherNeg = other.isNegative; if (thisNeg && !otherNeg) { return -1; } if (!thisNeg && otherNeg) { return 1; } return (other.high >>> 0) > (this.high >>> 0) || (other.high === this.high && (other.low >>> 0) > (this.low >>> 0)) ? -1 : 1; } add(other) { return base.Utility.add(this, other, true); } subtract(other) { return base.Utility.subtract(this, other, true); } multiply(other) { return base.Utility.multiply(this, other, true); } divide(other) { return base.Utility.divide(this, other, true); } toInteger() { return this.low >>> 0; } toNumber() { if (this.high === 0) { return this.low >>> 0; } return ((this.high >>> 0) * 4294967296) + (this.low >>> 0); } toString(radix) { const r = radix || 10; if (r < 2 || 36 < r) { throw new RangeError('radix'); } if (this.isZero) { return '0'; } if (this.high === 0) { return this.low.toString(radix); } return base.Utility.text(this, true, r); } }; base.Utility = class { static add(a, b, unsigned) { const a48 = a.high >>> 16; const a32 = a.high & 0xFFFF; const a16 = a.low >>> 16; const a00 = a.low & 0xFFFF; const b48 = b.high >>> 16; const b32 = b.high & 0xFFFF; const b16 = b.low >>> 16; const b00 = b.low & 0xFFFF; let c48 = 0; let c32 = 0; let c16 = 0; let c00 = 0; c00 += a00 + b00; c16 += c00 >>> 16; c00 &= 0xFFFF; c16 += a16 + b16; c32 += c16 >>> 16; c16 &= 0xFFFF; c32 += a32 + b32; c48 += c32 >>> 16; c32 &= 0xFFFF; c48 += a48 + b48; c48 &= 0xFFFF; return base.Utility._create((c16 << 16) | c00, (c48 << 16) | c32, unsigned); } static subtract(a, b, unsigned) { return base.Utility.add(a, b.negate(), unsigned); } static multiply(a, b, unsigned) { if (a.isZero) { return base.Int64.zero; } if (b.isZero) { return base.Int64.zero; } if (a.equals(base.Int64.min)) { return b.isOdd() ? base.Int64.min : base.Int64.zero; } if (b.equals(base.Int64.min)) { return a.isOdd() ? base.Int64.min : base.Int64.zero; } if (a.isNegative) { if (b.isNegative) { return a.negate().multiply(b.negate()); } return a.negate().multiply(b).negate(); } else if (b.isNegative) { return a.multiply(b.negate()).negate(); } if (a.compare(base.Int64.power24) < 0 && b.compare(base.Int64.power24) < 0) { return unsigned ? base.Uint64.create(a.toNumber() * b.toNumber()) : base.Int64.create(a.toNumber() * b.toNumber()); } const a48 = a.high >>> 16; const a32 = a.high & 0xFFFF; const a16 = a.low >>> 16; const a00 = a.low & 0xFFFF; const b48 = b.high >>> 16; const b32 = b.high & 0xFFFF; const b16 = b.low >>> 16; const b00 = b.low & 0xFFFF; let c48 = 0; let c32 = 0; let c16 = 0; let c00 = 0; c00 += a00 * b00; c16 += c00 >>> 16; c00 &= 0xFFFF; c16 += a16 * b00; c32 += c16 >>> 16; c16 &= 0xFFFF; c16 += a00 * b16; c32 += c16 >>> 16; c16 &= 0xFFFF; c32 += a32 * b00; c48 += c32 >>> 16; c32 &= 0xFFFF; c32 += a16 * b16; c48 += c32 >>> 16; c32 &= 0xFFFF; c32 += a00 * b32; c48 += c32 >>> 16; c32 &= 0xFFFF; c48 += a48 * b00 + a32 * b16 + a16 * b32 + a00 * b48; c48 &= 0xFFFF; return base.Utility._create((c16 << 16) | c00, (c48 << 16) | c32, unsigned); } static divide(a, b, unsigned) { if (b.isZero) { throw new Error('Division by zero.'); } if (a.isZero) { return unsigned ? base.Uint64.zero : base.Int64.zero; } let approx; let remainder; let result; if (!unsigned) { if (a.equals(base.Int64.min)) { if (b.equals(base.Int64.one) || b.equals(base.Int64.negativeOne)) { return base.Int64.min; } else if (b.equals(base.Int64.min)) { return base.Int64.one; } const half = base.Utility._shiftRight(a, unsigned, 1); const halfDivide = half.divide(b); approx = base.Utility._shiftLeft(halfDivide, halfDivide instanceof base.Uint64, 1); if (approx.equals(base.Int64.zero)) { return b.isNegative ? base.Int64.one : base.Int64.negativeOne; } remainder = a.subtract(b.multiply(approx)); result = approx.add(remainder.divide(b)); return result; } else if (b.equals(base.Int64.min)) { return base.Int64.zero; } if (a.isNegative) { if (b.isNegative) { return this.negate().divide(b.negate()); } return a.negate().divide(b).negate(); } else if (b.isNegative) { return a.divide(b.negate()).negate(); } result = base.Int64.zero; } else { if (!(b instanceof base.Uint64)) { b = new base.Uint64(b.low, b.high); } if (b.compare(a) > 0) { return base.Int64.zero; } if (b.compare(base.Utility._shiftRight(a, unsigned, 1)) > 0) { return base.Uint64.one; } result = base.Uint64.zero; } remainder = a; while (remainder.compare(b) >= 0) { let approx = Math.max(1, Math.floor(remainder.toNumber() / b.toNumber())); const log2 = Math.ceil(Math.log(approx) / Math.LN2); const delta = (log2 <= 48) ? 1 : Math.pow(2, log2 - 48); let approxResult = base.Int64.create(approx); let approxRemainder = approxResult.multiply(b); while (approxRemainder.isNegative || approxRemainder.compare(remainder) > 0) { approx -= delta; approxResult = unsigned ? base.Uint64.create(approx) : base.Int64.create(approx); approxRemainder = approxResult.multiply(b); } if (approxResult.isZero) { approxResult = base.Int64.one; } result = result.add(approxResult); remainder = remainder.subtract(approxRemainder); } return result; } static text(value, unsigned, radix) { const power = unsigned ? base.Uint64.create(Math.pow(radix, 6)) : base.Int64.create(Math.pow(radix, 6)); let remainder = value; let result = ''; for (; ;) { const remainderDiv = remainder.divide(power); const intval = remainder.subtract(remainderDiv.multiply(power)).toInteger() >>> 0; let digits = intval.toString(radix); remainder = remainderDiv; if (remainder.low === 0 && remainder.high === 0) { return digits + result; } while (digits.length < 6) { digits = '0' + digits; } result = '' + digits + result; } } static _shiftLeft(value, unsigned, shift) { return base.Utility._create(value.low << shift, (value.high << shift) | (value.low >>> (32 - shift)), unsigned); } static _shiftRight(value, unsigned, shift) { return base.Utility._create((value.low >>> shift) | (value.high << (32 - shift)), value.high >> shift, unsigned); } static _create(low, high, unsigned) { return unsigned ? new base.Uint64(low, high) : new base.Int64(low, high); } }; base.Uint64.zero = new base.Uint64(0, 0); base.Uint64.one = new base.Uint64(1, 0); base.Uint64.max = new base.Uint64(-1, -1); base.Complex64 = class Complex { constructor(real, imaginary) { this.real = real; this.imaginary = imaginary; } static create(real, imaginary) { return new base.Complex64(real, imaginary); } toString(/* radix */) { return this.real + ' + ' + this.imaginary + 'i'; } }; base.Complex128 = class Complex { constructor(real, imaginary) { this.real = real; this.imaginary = imaginary; } static create(real, imaginary) { return new base.Complex128(real, imaginary); } toString(/* radix */) { return this.real + ' + ' + this.imaginary + 'i'; } }; if (!DataView.prototype.getFloat16) { DataView.prototype.getFloat16 = function (byteOffset, littleEndian) { const value = this.getUint16(byteOffset, littleEndian); const e = (value & 0x7C00) >> 10; let f = value & 0x03FF; if (e == 0) { f = 0.00006103515625 * (f / 1024); } else if (e == 0x1F) { f = f ? NaN : Infinity; } else { f = DataView.__float16_pow[e] * (1 + (f / 1024)); } return value & 0x8000 ? -f : f; }; DataView.__float16_pow = { 1: 1 / 16384, 2: 1 / 8192, 3: 1 / 4096, 4: 1 / 2048, 5: 1 / 1024, 6: 1 / 512, 7: 1 / 256, 8: 1 / 128, 9: 1 / 64, 10: 1 / 32, 11: 1 / 16, 12: 1 / 8, 13: 1 / 4, 14: 1 / 2, 15: 1, 16: 2, 17: 4, 18: 8, 19: 16, 20: 32, 21: 64, 22: 128, 23: 256, 24: 512, 25: 1024, 26: 2048, 27: 4096, 28: 8192, 29: 16384, 30: 32768, 31: 65536 }; } if (!DataView.prototype.setFloat16) { DataView.prototype.setFloat16 = function (byteOffset, value, littleEndian) { DataView.__float16_float[0] = value; [value] = DataView.__float16_int; const s = (value >>> 16) & 0x8000; const e = (value >>> 23) & 0xff; const f = value & 0x7fffff; const v = s | DataView.__float16_base[e] | (f >> DataView.__float16_shift[e]); this.setUint16(byteOffset, v, littleEndian); }; DataView.__float16_float = new Float32Array(1); DataView.__float16_int = new Uint32Array(DataView.__float16_float.buffer, 0, DataView.__float16_float.length); DataView.__float16_base = new Uint32Array(256); DataView.__float16_shift = new Uint32Array(256); for (let i = 0; i < 256; ++i) { const e = i - 127; if (e < -27) { DataView.__float16_base[i] = 0x0000; DataView.__float16_shift[i] = 24; } else if (e < -14) { DataView.__float16_base[i] = 0x0400 >> -e - 14; DataView.__float16_shift[i] = -e - 1; } else if (e <= 15) { DataView.__float16_base[i] = e + 15 << 10; DataView.__float16_shift[i] = 13; } else if (e < 128) { DataView.__float16_base[i] = 0x7c00; DataView.__float16_shift[i] = 24; } else { DataView.__float16_base[i] = 0x7c00; DataView.__float16_shift[i] = 13; } } } if (!DataView.prototype.getBfloat16) { DataView.prototype.getBfloat16 = function (byteOffset, littleEndian) { if (littleEndian) { DataView.__bfloat16_get_uint16_le[1] = this.getUint16(byteOffset, littleEndian); return DataView.__bfloat16_get_float32_le[0]; } DataView.__bfloat16_uint16_be[0] = this.getUint16(byteOffset, littleEndian); return DataView.__bfloat16_get_float32_be[0]; }; DataView.__bfloat16_get_float32_le = new Float32Array(1); DataView.__bfloat16_get_float32_be = new Float32Array(1); DataView.__bfloat16_get_uint16_le = new Uint16Array(DataView.__bfloat16_get_float32_le.buffer, DataView.__bfloat16_get_float32_le.byteOffset, 2); DataView.__bfloat16_get_uint16_be = new Uint16Array(DataView.__bfloat16_get_float32_be.buffer, DataView.__bfloat16_get_float32_be.byteOffset, 2); } DataView.__float8e4m3_float32 = new Float32Array(1); DataView.__float8e4m3_uint32 = new Uint32Array(DataView.__float8e4m3_float32.buffer, DataView.__float8e4m3_float32.byteOffset, 1); DataView.prototype.getFloat8e4m3 = function (byteOffset, fn, uz) { const value = this.getUint8(byteOffset); let exponent_bias = 7; if (uz) { exponent_bias = 8; if (value == 0x80) { return NaN; } } else if (value === 255) { return -NaN; } else if (value === 0x7f) { return NaN; } let expo = (value & 0x78) >> 3; let mant = value & 0x07; const sign = value & 0x80; let res = sign << 24; if (expo == 0) { if (mant > 0) { expo = 0x7F - exponent_bias; if (mant & 0x4 == 0) { mant &= 0x3; mant <<= 1; expo -= 1; } if (mant & 0x4 == 0) { mant &= 0x3; mant <<= 1; expo -= 1; } res |= (mant & 0x3) << 21; res |= expo << 23; } } else { res |= mant << 20; expo += 0x7F - exponent_bias; res |= expo << 23; } DataView.__float8e4m3_uint32[0] = res; return DataView.__float8e4m3_float32[0]; }; DataView.__float8e5m2_float32 = new Float32Array(1); DataView.__float8e5m2_uint32 = new Uint32Array(DataView.__float8e5m2_float32.buffer, DataView.__float8e5m2_float32.byteOffset, 1); DataView.prototype.getFloat8e5m2 = function (byteOffset, fn, uz) { const value = this.getUint8(byteOffset); let exponent_bias = NaN; if (fn && uz) { if (value == 0x80) { return NaN; } exponent_bias = 16; } else if (!fn && !uz) { if (value >= 253 && value <= 255) { return -NaN; } if (value >= 126 && value <= 127) { return NaN; } if (value === 252) { return -Infinity; } if (value === 124) { return Infinity; } exponent_bias = 15; } let expo = (value & 0x7C) >> 2; let mant = value & 0x03; let res = (value & 0x80) << 24; if (expo == 0) { if (mant > 0) { expo = 0x7F - exponent_bias; if (mant & 0x2 == 0) { mant &= 0x1; mant <<= 1; expo -= 1; } res |= (mant & 0x1) << 22; res |= expo << 23; } } else { res |= mant << 21; expo += 0x7F - exponent_bias; res |= expo << 23; } DataView.__float8e5m2_uint32[0] = res; return DataView.__float8e5m2_float32[0]; }; DataView.prototype.getInt64 = DataView.prototype.getInt64 || function (byteOffset, littleEndian) { return littleEndian ? new base.Int64(this.getUint32(byteOffset, true), this.getUint32(byteOffset + 4, true)) : new base.Int64(this.getUint32(byteOffset + 4, true), this.getUint32(byteOffset, true)); }; DataView.prototype.setInt64 = DataView.prototype.setInt64 || function (byteOffset, value, littleEndian) { if (littleEndian) { this.setUint32(byteOffset, value.low, true); this.setUint32(byteOffset + 4, value.high, true); } else { this.setUint32(byteOffset + 4, value.low, false); this.setUint32(byteOffset, value.high, false); } }; DataView.prototype.getIntBits = DataView.prototype.getUintBits || function (offset, bits) { offset = offset * bits; const available = (this.byteLength << 3) - offset; if (bits > available) { throw new RangeError("Invalid bit size '" + bits + "'."); } let value = 0; let index = 0; while (index < bits) { const remainder = offset & 7; const size = Math.min(bits - index, 8 - remainder); value <<= size; value |= (this.getUint8(offset >> 3) >> (8 - size - remainder)) & ~(0xff << size); offset += size; index += size; } return (value < (2 << (bits - 1)) ? value : (2 << bits)); }; DataView.prototype.getUint64 = DataView.prototype.getUint64 || function (byteOffset, littleEndian) { return littleEndian ? new base.Uint64(this.getUint32(byteOffset, true), this.getUint32(byteOffset + 4, true)) : new base.Uint64(this.getUint32(byteOffset + 4, true), this.getUint32(byteOffset, true)); }; DataView.prototype.setUint64 = DataView.prototype.setUint64 || function (byteOffset, value, littleEndian) { if (littleEndian) { this.setUint32(byteOffset, value.low, true); this.setUint32(byteOffset + 4, value.high, true); } else { this.setUint32(byteOffset + 4, value.low, false); this.setUint32(byteOffset, value.high, false); } }; DataView.prototype.getUintBits = DataView.prototype.getUintBits || function (offset, bits) { offset = offset * bits; const available = (this.byteLength << 3) - offset; if (bits > available) { throw new RangeError("Invalid bit size '" + bits + "'."); } let value = 0; let index = 0; while (index < bits) { const remainder = offset & 7; const size = Math.min(bits - index, 8 - remainder); value <<= size; value |= (this.getUint8(offset >> 3) >> (8 - size - remainder)) & ~(0xff << size); offset += size; index += size; } return value; }; DataView.prototype.getComplex64 = DataView.prototype.getComplex64 || function (byteOffset, littleEndian) { const real = littleEndian ? this.getFloat32(byteOffset, littleEndian) : this.getFloat32(byteOffset + 4, littleEndian); const imaginary = littleEndian ? this.getFloat32(byteOffset + 4, littleEndian) : this.getFloat32(byteOffset, littleEndian); return base.Complex64.create(real, imaginary); }; DataView.prototype.setComplex64 = DataView.prototype.setComplex64 || function (byteOffset, value, littleEndian) { if (littleEndian) { this.setFloat32(byteOffset, value.real, littleEndian); this.setFloat32(byteOffset + 4, value.imaginary, littleEndian); } else { this.setFloat32(byteOffset + 4, value.real, littleEndian); this.setFloat32(byteOffset, value.imaginary, littleEndian); } }; DataView.prototype.getComplex128 = DataView.prototype.getComplex128 || function (byteOffset, littleEndian) { const real = littleEndian ? this.getFloat64(byteOffset, littleEndian) : this.getFloat64(byteOffset + 8, littleEndian); const imaginary = littleEndian ? this.getFloat64(byteOffset + 8, littleEndian) : this.getFloat64(byteOffset, littleEndian); return base.Complex128.create(real, imaginary); }; DataView.prototype.setComplex128 = DataView.prototype.setComplex128 || function (byteOffset, value, littleEndian) { if (littleEndian) { this.setFloat64(byteOffset, value.real, littleEndian); this.setFloat64(byteOffset + 8, value.imaginary, littleEndian); } else { this.setFloat64(byteOffset + 8, value.real, littleEndian); this.setFloat64(byteOffset, value.imaginary, littleEndian); } };