UNPKG

@zkpersona/noir-helpers

Version:

Helpers utilities for Noir proofs and input generation.

1,726 lines (1,717 loc) 148 kB
import { UltraPlonkBackend, UltraHonkBackend } from '@aztec/bb.js'; import { Noir } from '@noir-lang/noir_js'; import fs from 'node:fs'; import path from 'node:path'; import json2toml from 'json2toml'; import { inspect } from 'node:util'; import { z } from 'zod'; // src/prover.ts var Prover = class { plonk; honk; noir; provingBackend; /** * Creates a new instance of the Prover. * * @param circuit - The compiled Noir circuit to use for proving * @param provingBackend - Configuration for the proving backend * * @throws {Error} If the circuit bytecode is invalid or malformed * @throws {Error} If the proving backend configuration is invalid * @throws {Error} If backend initialization fails */ constructor(circuit, provingBackend) { const acirBytecode = circuit.bytecode; if (provingBackend.type === "plonk" || provingBackend.type === "all") { this.plonk = new UltraPlonkBackend( acirBytecode, provingBackend.options, provingBackend.circuitOptions ); } if (provingBackend.type === "honk" || provingBackend.type === "all") { this.honk = new UltraHonkBackend( acirBytecode, provingBackend.options, provingBackend.circuitOptions ); } this.provingBackend = provingBackend; this.noir = new Noir(circuit); } /** * Simulates the circuit execution to generate a witness. * This method executes the circuit with the given inputs to produce * a witness that can be used for proof generation. * * @param input - The input values for the circuit * @returns A promise that resolves to an object containing: * - witness: The generated witness as a Uint8Array * - returnValue: The circuit's return value * * @throws {Error} If the circuit execution fails * @throws {Error} If the input values are invalid or malformed * @throws {Error} If witness generation fails */ async simulateWitness(input) { return await this.noir.execute(input); } /** * Generates a zero-knowledge proof from a witness. * * @param witness - The witness generated from circuit execution * @param provingBackend - Optional override for the proving backend configuration * @returns A promise that resolves to the generated proof * * @throws {Error} If the witness is invalid or malformed * @throws {Error} If the proving backend is not initialized * @throws {Error} If proof generation fails */ async prove(witness, provingBackend) { const backend = this.getProvingBackend(provingBackend?.type); return await backend.generateProof(witness); } /** * Generates a complete zero-knowledge proof from circuit inputs. * This is a convenience method that combines witness generation and proof generation. * * @param input - The input values for the circuit * @param provingBackend - Optional override for the proving backend configuration * @returns A promise that resolves to the generated proof * * @throws {Error} If witness generation fails * @throws {Error} If proof generation fails * @throws {Error} If the input values are invalid */ async fullProve(input, provingBackend) { const { witness } = await this.simulateWitness(input); return this.prove(witness, provingBackend); } /** * Verifies a zero-knowledge proof. * * @param proof - The proof to verify * @param provingBackend - Optional override for the proving backend configuration * @returns A promise that resolves to true if the proof is valid, false otherwise * * @throws {Error} If the proof is invalid or malformed * @throws {Error} If the proving backend is not initialized * @throws {Error} If verification fails */ async verify(proof, provingBackend) { const backend = this.getProvingBackend(provingBackend?.type); return await backend.verifyProof(proof); } /** * Cleans up resources used by the proving backends. * This method should be called when the prover is no longer needed * to free up system resources. It is recommended to call this method * in a finally block or when the prover instance is being disposed. * * @returns A promise that resolves when cleanup is complete * * @throws {Error} If resource cleanup fails */ async destroy() { if (this.plonk) { await this.plonk.destroy(); } if (this.honk) { await this.honk.destroy(); } } /** * Gets the appropriate proving backend based on the specified type. * This method handles backend selection and initialization state checking. * * @param backendType - Optional override for the backend type * @returns The initialized proving backend * * @throws {Error} If the backend type is invalid * @throws {Error} If the requested backend is not initialized * * @private */ getProvingBackend(backendType) { let type; if (backendType === "plonk" || this.provingBackend.type === "plonk") { type = "plonk"; } else if (backendType === "honk" || this.provingBackend.type === "honk") { type = "honk"; } else { throw new Error( 'Specify a proving backend from either "plonk" or "honk"' ); } let backend; if (type === "plonk" && this.plonk) { backend = this.plonk; } else if (type === "honk" && this.honk) { backend = this.honk; } else { throw new Error(`Proving backend ${type} not initialized`); } return backend; } }; var generateToml = (data, filePath, formatterOpts) => { if (!path.isAbsolute(filePath)) { throw new Error( `The provided file path must be absolute. Received: ${filePath}` ); } const tomlContent = json2toml(data, formatterOpts); const dir = path.dirname(filePath); fs.mkdirSync(dir, { recursive: true }); fs.writeFileSync(filePath, tomlContent, "utf-8"); }; // src/data-types/array.ts var FixedSizeArray = class { length; items; constructor(length, items) { if (length !== items.length) { throw new Error( `Length mismatch: expected ${length}, got ${items.length}` ); } this.length = length; this.items = [...items]; } len() { return this.length; } toArray() { return [...this.items]; } get(index) { if (index < 0 || index >= this.length) { throw new Error(`Index ${index} out of bounds`); } return this.items[index]; } at(index) { const adjustedIndex = index < 0 ? this.length + index : index; return this.get(adjustedIndex); } set(index, item) { if (index < 0 || index >= this.length) { throw new Error(`Index ${index} out of bounds`); } this.items[index] = item; } forEach(callback) { this.items.forEach(callback); } map(callback) { return this.items.map(callback); } toCircuitInputs() { return this.items.map(getInputRepresentation); } }; // src/data-types/bool.ts var Bool = class _Bool { /** The underlying boolean value */ val; /** * Creates a new boolean instance with the specified value. * * @param value - The boolean value to initialize the instance with */ constructor(value) { this.val = value; } /** * Returns the underlying boolean value. * * @returns The boolean value */ value() { return this.val; } /** * Compares this boolean with another for equality. * * @param other - The boolean to compare with * @returns true if both booleans have the same value, false otherwise */ eq(other) { return this.val === other.val; } /** * Performs a logical NOT operation on this boolean. * Returns a new boolean instance with the negated value. * * @returns A new boolean instance with the opposite value */ not() { return new _Bool(!this.val); } /** * Converts the boolean to its Circuit Input representation. * Returns the underlying primitive boolean value. * * @returns The boolean value as a primitive */ toCircuitInputs() { return this.val; } }; // src/data-types/bounded-vec.ts var BoundedVec = class { /** Maximum number of elements the vector can hold */ maxSize; /** Current number of elements in the vector */ length; /** Internal storage for vector elements */ items; /** * Creates a new bounded vector with the specified maximum size. * The vector is initialized with default values up to the maximum size. * * @param maxSize - The maximum number of elements the vector can hold * @param defaultValue - Default value for initialization * @param initialItems - Initial items to add to the vector * @throws {Error} If maxSize is negative */ constructor(maxSize, defaultValue, initialItems = []) { if (maxSize < 0) { throw new Error("Max size must be non-negative"); } this.maxSize = maxSize; this.items = Array.from({ length: maxSize }, () => defaultValue); this.length = 0; this.extendFromArray(initialItems); } /** * Returns the current number of elements in the vector. * * @returns The number of elements currently stored in the vector */ len() { return this.length; } /** * Returns the maximum number of elements the vector can hold. * * @returns The maximum capacity of the vector */ maxLen() { return this.maxSize; } /** * Checks if the vector is empty. * * @returns true if the vector contains no elements, false otherwise */ isEmpty() { return this.length === 0; } /** * Checks if the vector has reached its maximum capacity. * * @returns true if the vector is at maximum capacity, false otherwise */ isFull() { return this.length === this.maxSize; } /** * Returns the internal storage for the vector. */ storage() { return this.items; } /** * Retrieves the element at the specified index. * * @param index - The zero-based index of the element to retrieve * @returns The element at the specified index * @throws {Error} If the index is out of bounds (index < 0 or index >= length) */ get(index) { if (index < 0 || index >= this.length) { throw new Error("Index out of bounds"); } return this.items[index]; } /** * Retrieves the element at the specified index, supporting negative indices. * Negative indices count from the end of the vector (-1 is the last element). * * @param index - The index of the element to retrieve (can be negative) * @returns The element at the specified index * @throws {Error} If the index is out of bounds after adjustment */ at(index) { const adjustedIndex = index < 0 ? this.length + index : index; return this.get(adjustedIndex); } /** * Adds an element to the end of the vector. * * @param item - The element to add to the vector * @throws {Error} If the vector is at maximum capacity */ push(item) { if (this.isFull()) { throw new Error("Vector is full"); } this.items[this.length] = item; this.length++; } /** * Sets the element at the specified index to the given value. * * @param index - The zero-based index where the element should be set * @param item - The new value to set at the specified index * @throws {Error} If the index is out of bounds (index < 0 or index >= length) */ set(index, item) { if (index < 0 || index >= this.length) { throw new Error("Index out of bounds"); } this.items[index] = item; } /** * Removes and returns the last element of the vector. * * @returns The last element of the vector * @throws {Error} If the vector is empty */ pop() { if (this.isEmpty()) { throw new Error("Vector is empty"); } const item = this.items[this.length - 1]; this.length--; return item; } /** * Extends the vector by adding all elements from the given array. * * @param arr - The array of elements to add to the vector * @throws {Error} If adding the elements would exceed the vector's maximum capacity */ extendFromArray(arr) { if (this.length + arr.length > this.maxSize) { throw new Error("Vector overflow"); } for (const item of arr) { this.push(item); } } /** * Extends the vector by adding all elements from another bounded vector. * * @param vec - The bounded vector whose elements should be added * @throws {Error} If adding the elements would exceed the vector's maximum capacity */ extendFromVec(vec) { this.extendFromArray(vec.toArray()); } /** * Returns a copy of the vector's elements as an array. * Only includes elements up to the current length. * * @returns An array containing the vector's elements */ toArray() { return this.items.slice(0, this.length); } /** * Converts the BoundedVec to a Circuit Input representation. * The JSON object contains both the elements and the current length. * * @returns Noir Circuit Input representation of the BoundedVec */ toCircuitInputs() { return { storage: this.storage().map((item) => getInputRepresentation(item)), len: this.length }; } }; var MAX_FIELD_SIZE = 21888242871839275222246405745257275088548364400416034343698204186575808495616n; var fieldInputSchema = z.union([ z.number().int("Field input must be an integer"), z.bigint(), z.string().refine( (str) => /^0x[0-9a-fA-F]+$/.test(str) || /^\d+$/.test(str), "String must be a decimal or hexadecimal number" ) ]); var FieldValidator = fieldInputSchema.transform((val) => { if (typeof val === "string") { return BigInt(val); } return BigInt(val); }).refine( (n) => n <= MAX_FIELD_SIZE && n >= -MAX_FIELD_SIZE, "Field value must be between -MAX_FIELD_SIZE and MAX_FIELD_SIZE" ); var IntegerValidator = (min, max) => fieldInputSchema.transform((n) => BigInt(n)).refine((n) => n >= min && n <= max, { message: `Value must be in range [${min}, ${max}]` }); // src/data-types/field.ts var Field = class _Field { /** The internal bigint representation of the field value */ value; /** The maximum bit size of a Field */ static MAX_BIT_SIZE = 254n; /** The modulus of the field */ static MODULUS = 21888242871839275222246405745257275088548364400416034343698204186575808495617n; /** * Creates a new Field instance from various input types. * * @param input - The input value to convert to a field element * @throws Error if the input cannot be parsed as a valid field value */ constructor(input) { const parsed = FieldValidator.parse(input); this.value = parsed % _Field.MODULUS; } [inspect.custom]() { return `Field<${this.value.toString()}>`; } /** * Internal helper function to compute the log2 of a large value (0-2^254). * * @param value - The value to compute the log2 of * @returns The log2 of the value */ log2(value) { if (value <= 0n) { throw new Error("log2 is undefined for non-positive values"); } let result = 0n; let v = value; while (v > 1n) { v >>= 1n; result += 1n; } return result; } /** * Converts the field value to an array of bits in little-endian order. * * @param length - The number of bits to extract * @returns An array of bits (0 or 1) in little-endian order * @throws Error if length is negative or exceeds Field.MAX_BIT_SIZE or if length is less than the minimum required bits to represent the value */ toLeBits(length) { const minLengthRequired = this.value === 0n ? 0 : Math.ceil(Number(this.log2(this.value)) + 1); if (length < minLengthRequired || length > _Field.MAX_BIT_SIZE) { throw new Error( `Length must be between ${minLengthRequired} and ${_Field.MAX_BIT_SIZE}` ); } const bits = []; for (let i = 0; i < length; i++) { const bit = this.value >> BigInt(i) & 1n; bits.push(Number(bit)); } return bits; } /** * Converts the field value to an array of bits in big-endian order. * * @param length - The number of bits to extract * @returns An array of bits (0 or 1) in big-endian order * @throws Error if length is negative or exceeds Field.MAX_BIT_SIZE or if length is less than the minimum required bits to represent the value */ toBeBits(length) { const minLengthRequired = this.value === 0n ? 0 : Math.ceil(Number(this.log2(this.value)) + 1); if (length < minLengthRequired || length > _Field.MAX_BIT_SIZE) { throw new Error( `Length must be between ${minLengthRequired} and ${_Field.MAX_BIT_SIZE}` ); } const bits = []; for (let i = length - 1; i >= 0; i--) { const bit = this.value >> BigInt(i) & 1n; bits.push(Number(bit)); } return bits; } /** * Converts the field value to an array of bytes in little-endian order. * * @param length - The number of bytes to extract * @returns An array of bytes in little-endian order * @throws Error if length is negative or exceeds Field.MAX_BIT_SIZE or if length is less than the minimum required bytes to represent the value */ toLeBytes(length) { const minLengthRequired = Math.ceil(this.value.toString(2).length / 8); if (length < minLengthRequired || length > _Field.modLeBytes().length) { throw new Error( `Length must be between ${minLengthRequired} and ${_Field.modLeBytes().length}` ); } const bytes = []; for (let i = 0; i < length; i++) { const byte = Number(this.value >> BigInt(8 * i) & 0xffn); bytes.push(byte); } return bytes; } /** * Converts the field value to an array of bytes in big-endian order. * * @param length - The number of bytes to extract * @returns An array of bytes in big-endian order, sized by the length parameter * @throws Error if length is negative, or exceeds maximum bit size or if length is less than the minimum required bytes to represent the value */ toBeBytes(length) { const minLengthRequired = Math.ceil(this.value.toString(2).length / 8); if (length < minLengthRequired || length > _Field.modBeBytes().length) { throw new Error( `Length must be between ${minLengthRequired} and ${_Field.modBeBytes().length}` ); } const bytes = []; for (let i = length - 1; i >= 0; i--) { const byte = Number(this.value >> BigInt(8 * i) & 0xffn); bytes.push(byte); } return bytes; } /** * Calculates the minimum length needed to represent a value in a given radix, rounded up to the nearest power of 2. * * This function is used internally to determine the minimum number of digits required to represent * a field value in a given base (radix). The result is always rounded up to the nearest power of 2 * to ensure consistent sizing for cryptographic operations. * * @param value - The bigint value to calculate the representation length for * @param radix - The base to represent the value in (must be a power of 2) * @returns The minimum number of digits needed to represent the value in the given radix, rounded up to the nearest power of 2 * @throws {Error} If the value is negative * @throws {Error} If the radix is not a power of 2 * @throws {Error} If the radix is less than 2 */ minRadixLength(value, radix) { if (value < 0n) throw new Error("value must be non-negative"); if ((radix & radix - 1) !== 0) throw new Error("radix must be a power of 2"); if (radix < 2) throw new Error("radix must be >= 2"); if (value === 0n) return 1; let radixBits = 0; let r = radix; while ((r >>= 1) > 0) { radixBits++; } let bits = 0; let v = value; while (v > 0n) { v >>= 1n; bits++; } const rawLen = Math.ceil(bits / radixBits); let rounded = 1; while (rounded < rawLen) { rounded <<= 1; } return rounded; } /** * Converts the field value to an array of digits in little-endian order using the specified radix. * * @param radix - The base to use for conversion * @param length - The number of digits to extract * @returns An array of digits in little-endian order * @throws Error if radix is invalid or length is negative or if length is less than the minimum required digits to represent the value, or if length is greater than 256 */ toLeRadix(radix, length) { const minimumRequired = this.minRadixLength(this.value, radix); if (length < minimumRequired || length > 256) { throw new Error(`Length must be between ${minimumRequired} and 256`); } const r = BigInt(radix); const digits = []; let v = this.value; for (let i = 0; i < length; i++) { digits.push(Number(v % r)); v /= r; } while (digits.length < length) digits.push(0); return digits; } /** * Converts the field value to an array of digits in big-endian order using the specified radix. * * @param radix - The base to use for conversion (must be a power of 2 between 2 and 256) * @param length - The number of digits to extract * @returns An array of digits in big-endian order * @throws Error if radix is invalid or length is negative or if length is less than the minimum required digits to represent the value, or if length is greater than 256 */ toBeRadix(radix, length) { const minimumRequired = this.minRadixLength(this.value, radix); if (length < minimumRequired || length > 256) { throw new Error(`Length must be between ${minimumRequired} and 256`); } const r = BigInt(radix); const digits = []; let v = this.value; for (let i = 0; i < length; i++) { digits.push(Number(v % r)); v /= r; } while (digits.length < length) digits.push(0); return digits.reverse(); } /** * Raises the field value to the specified power. * * @param exponent - The power to raise to * @returns A new Field instance with the result * @throws Error if exponent is negative or greater than equal to 2^32 */ pow32(exponent) { const exp = exponent.value; const MAX_EXP = BigInt(2 ** 32); if (exp < 0n) throw new Error("Negative exponents are not allowed"); if (exp >= MAX_EXP) throw new Error("Exponent too large: exceeds 2^32 limit"); let result = 1n; let b = this.value % _Field.MODULUS; let e = exp; while (e > 0n) { if (e & 1n) { result = result * b % _Field.MODULUS; } b = b * b % _Field.MODULUS; e >>= 1n; } return new _Field(result); } /** * Asserts that the field value does not exceed the specified bit size. * * @param bitSize - The maximum allowed bit size * @throws Error if the field value exceeds the specified bit size */ assertMaxBitSize(bitSize) { if (this.value < 0n) { throw new Error("Negative field values are not allowed"); } let bitLength = 0; let v = this.value; while (v > 0n) { v >>= 1n; bitLength++; } if (bitLength > bitSize) { throw new Error(`Field value exceeds ${bitSize} bits`); } } /** * Returns the sign of the field value (0 or 1). * This is used in cryptographic operations to determine the sign of a field element. * * @returns 0 if the value is even, 1 if odd */ sgn0() { return Number(this.value & 1n); } /** * Returns a string representation of the field value. * * @returns The field value as a decimal string */ toString() { return this.value.toString(10); } /** * Converts the field value to a hexadecimal string. * * @param length - Optional length in bytes to pad the hex string to * @returns The field value as a hexadecimal string with '0x' prefix */ toHex() { const hex = this.value.toString(16); return `0x${hex}`; } /** * Converts the field value to its Circuit Input representation. * Returns the field value as a hexadecimal string. * */ toCircuitInputs() { return this.toHex(); } /** * Checks if this field value equals another value. * * @param other - The value to compare against (can be Field, number, string, or bigint) * @returns true if the values are equal */ equals(other) { if (other instanceof _Field) { return this.value === other.value; } return this.value === BigInt(other); } /** * Adds another value to this field value. * * @param input - The value to add (can be Field, number, string, or bigint) * @returns A new Field instance with the sum */ add(input) { const rhs = input instanceof _Field ? input.value : BigInt(input); const sum = this.value + rhs; const reduced = sum >= _Field.MODULUS ? sum - _Field.MODULUS : sum; return new _Field(reduced); } /** * Subtracts another value from this field value. * * @param input - The value to subtract (can be Field, number, string, or bigint) * @returns A new Field instance with the difference */ sub(input) { const otherField = input instanceof _Field ? input : new _Field(input); const res = (this.value - otherField.value + _Field.MODULUS) % _Field.MODULUS; return new _Field(res); } /** * Multiplies this field value by another value. * * @param input - The value to multiply by (can be Field, number, string, or bigint) * @returns A new Field instance with the product */ mul(input) { const otherField = input instanceof _Field ? input : new _Field(input); return new _Field(this.value * otherField.value % _Field.MODULUS); } /** * Computes the modular inverse of a field element. * * @param a - The field element to compute the inverse of * @param mod - The modulus to use for the computation * * @returns The modular inverse of the field element */ modInv(a, mod) { let t = 0n; let newT = 1n; let r = mod; let newR = a; while (newR !== 0n) { const quotient = r / newR; [t, newT] = [newT, t - quotient * newT]; [r, newR] = [newR, r - quotient * newR]; } if (r > 1n) throw new Error("Input is not invertible"); if (t < 0n) t += mod; return t; } /** * Divides this field value by another value. * * @param input - The value to divide by (can be Field, number, string, or bigint) * @returns A new Field instance with the quotient * @throws Error if dividing by zero */ div(input) { const otherField = input instanceof _Field ? input : new _Field(input); if (otherField.value === 0n) { throw new Error("Division by zero"); } const inv = this.modInv(otherField.value, _Field.MODULUS); const result = this.value * inv % _Field.MODULUS; return new _Field(result); } /** * Computes the remainder of division of this field value by another value. * * @param input - The value to divide by (can be Field, number, string, or bigint) * @returns A new Field instance with the remainder * @throws Error if dividing by zero */ mod(input) { const rhs = input instanceof _Field ? input.value : new _Field(input).value; if (rhs === 0n) { throw new Error("Cannot modulo by zero"); } const result = (this.value % rhs + rhs) % rhs; return new _Field(result); } /** * Creates a copy of this field value. * * @returns A new Field instance with the same value */ clone() { return new _Field(this.value); } static modBeBits() { return [ 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 ]; } static modBeBytes() { return [ 48, 100, 78, 114, 225, 49, 160, 41, 184, 80, 69, 182, 129, 129, 88, 93, 40, 51, 232, 72, 121, 185, 112, 145, 67, 225, 245, 147, 240, 0, 0, 1 ]; } static modLeBits() { return [ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1 ]; } static modLeBytes() { return [ 1, 0, 0, 240, 147, 245, 225, 67, 145, 112, 185, 121, 72, 232, 51, 40, 93, 88, 129, 129, 182, 69, 80, 184, 41, 160, 49, 225, 114, 78, 100, 48 ]; } static modNumBits() { return _Field.MAX_BIT_SIZE; } }; // src/data-types/integer.ts var AbstractInteger = class extends Field { /** Maximum value that can be represented by this integer type */ static MAX_VALUE; /** Minimum value that can be represented by this integer type */ static MIN_VALUE; /** * Gets the minimum value that can be represented by this integer type. * @returns The minimum value as a bigint */ min() { return this.constructor.MIN_VALUE; } /** * Gets the maximum value that can be represented by this integer type. * @returns The maximum value as a bigint */ max() { return this.constructor.MAX_VALUE; } /** * Creates a new instance of the concrete integer type. * @param value - The value to initialize the new instance with * @returns A new instance of the concrete integer type */ newInstance(value) { const ConcreteClass = Object.getPrototypeOf(this).constructor; if (value instanceof Field) { return new ConcreteClass(value.value); } return new ConcreteClass(value); } /** * Constructs a new integer instance with the given value. * Validates that the input value is within the allowed range. * @param input - The value to initialize this integer with * @throws {ZodError} If the input value is outside the allowed range */ constructor(input) { super(input); const min = this.constructor.MIN_VALUE; const max = this.constructor.MAX_VALUE; IntegerValidator(min, max).parse(input); } /** * Adds another integer to this one with overflow checking. * @param other - The integer to add * @returns A new integer representing the sum * @throws {Error} If the result would overflow */ add(other) { return this.newInstance(super.add(other)); } /** * Subtracts another integer from this one with overflow checking. * @param other - The integer to subtract * @returns A new integer representing the difference * @throws {Error} If the result would overflow */ sub(other) { return this.newInstance(super.sub(other)); } /** * Multiplies this integer by another with overflow checking. * @param other - The integer to multiply by * @returns A new integer representing the product * @throws {Error} If the result would overflow */ mul(other) { return this.newInstance(super.mul(other)); } /** * Divides this integer by another with overflow checking. * @param other - The integer to divide by * @returns A new integer representing the quotient * @throws {Error} If the result would overflow or if dividing by zero */ div(other) { return this.newInstance(super.div(other)); } /** * Computes the remainder of dividing this integer by another. * @param other - The integer to divide by * @returns A new integer representing the remainder * @throws {Error} If dividing by zero */ mod(other) { return super.mod(other); } /** * Performs wrapping addition of two integers. * If the result would overflow, it wraps around to the minimum value. * @param other - The integer to add * @returns A new integer representing the wrapped sum */ wrappingAdd(other) { const min = this.min(); const max = this.max(); const range = max - min + 1n; const a = this.value - min; const b = other.value - min; const mask = range - 1n; const sum = a + b & mask; return this.newInstance(sum + min); } /** * Performs wrapping subtraction of two integers. * If the result would underflow, it wraps around to the maximum value. * @param other - The integer to subtract * @returns A new integer representing the wrapped difference */ wrappingSub(other) { const min = this.min(); const max = this.max(); const range = max - min + 1n; const a = this.value - min; const b = other.value - min; const mask = range - 1n; const diff = a - b & mask; return this.newInstance(diff + min); } /** * Performs wrapping multiplication of two integers. * If the result would overflow, it wraps around to the minimum value. * @param other - The integer to multiply by * @returns A new integer representing the wrapped product */ wrappingMul(other) { const min = this.min(); const max = this.max(); const range = max - min + 1n; const a = this.value - min; const b = other.value - min; const mask = range - 1n; const prod = a * b & mask; return this.newInstance(prod + min); } }; var U1 = class extends AbstractInteger { static MAX_VALUE = 1n; static MIN_VALUE = 0n; }; var U8 = class extends AbstractInteger { static MAX_VALUE = 255n; static MIN_VALUE = 0n; }; var U16 = class extends AbstractInteger { static MAX_VALUE = 65535n; static MIN_VALUE = 0n; }; var U32 = class extends AbstractInteger { static MAX_VALUE = 4294967295n; static MIN_VALUE = 0n; }; var U64 = class extends AbstractInteger { static MAX_VALUE = 18446744073709551615n; static MIN_VALUE = 0n; }; var I1 = class extends AbstractInteger { static MAX_VALUE = 0n; static MIN_VALUE = -0n; }; var I8 = class extends AbstractInteger { static MAX_VALUE = 127n; static MIN_VALUE = -128n; }; var I16 = class extends AbstractInteger { static MAX_VALUE = 32767n; static MIN_VALUE = -32768n; }; var I32 = class extends AbstractInteger { static MAX_VALUE = 2147483647n; static MIN_VALUE = -2147483648n; }; var I64 = class extends AbstractInteger { static MAX_VALUE = 9223372036854775807n; static MIN_VALUE = -9223372036854775808n; }; // src/data-types/string.ts var Str = class { /** The underlying string value */ val; /** * Creates a new string instance with the specified value. * * @param value - The string value to initialize the instance with */ constructor(value) { this.val = value; } /** * Returns the underlying string value. * * @returns The string value */ value() { return this.val; } /** * Returns the length of the string. * * @returns The number of characters in the string */ len() { return this.val.length; } /** * Converts the string to an array of UTF-8 encoded bytes. * Each byte is represented as a U8 integer value. * * @returns An array of U8 integers representing the UTF-8 encoded bytes */ asBytes() { const encoder = new TextEncoder(); const encoded = encoder.encode(this.val); const res = []; for (const ele of encoded) { res.push(new U8(ele)); } return res; } /** * Compares this string with another for equality. * * @param other - The string to compare with * @returns true if both strings have the same value, false otherwise */ eq(other) { return this.val === other.val; } /** * Converts the string to its Circuit Input representation. * Returns the underlying primitive string value. */ toCircuitInputs() { return this.val; } }; // src/data-types/index.ts var getInputRepresentation = (value) => { if (value instanceof AbstractInteger) { return value.toString(); } if (value instanceof Bool) { return value.toCircuitInputs(); } if (value instanceof Str) { return value.toCircuitInputs(); } if (value instanceof Field) { return value.toCircuitInputs(); } if (value instanceof BoundedVec) { return value.toCircuitInputs(); } if (value instanceof FixedSizeArray) { return value.toCircuitInputs(); } if (typeof value === "object" && value !== null) { const result = {}; for (const [key, val] of Object.entries(value)) { result[key] = getInputRepresentation(val); } return result; } throw new Error( `Invalid value type: ${value === null ? "null" : typeof value}` ); }; function toCircuitInputs(value) { return getInputRepresentation(value); } export { AbstractInteger, Bool, BoundedVec, Field, FieldValidator, FixedSizeArray, I1, I16, I32, I64, I8, IntegerValidator, Prover, Str, U1, U16, U32, U64, U8, generateToml, getInputRepresentation, toCircuitInputs }; //# sourceMappingURL=index.mjs.map //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9wcm92ZXIudHMiLCIuLi9zcmMvZ2VuZXJhdGUtdG9tbC50cyIsIi4uL3NyYy9kYXRhLXR5cGVzL2FycmF5LnRzIiwiLi4vc3JjL2RhdGEtdHlwZXMvYm9vbC50cyIsIi4uL3NyYy9kYXRhLXR5cGVzL2JvdW5kZWQtdmVjLnRzIiwiLi4vc3JjL2RhdGEtdHlwZXMvem9kL2luZGV4LnRzIiwiLi4vc3JjL2RhdGEtdHlwZXMvZmllbGQudHMiLCIuLi9zcmMvZGF0YS10eXBlcy9pbnRlZ2VyLnRzIiwiLi4vc3JjL2RhdGEtdHlwZXMvc3RyaW5nLnRzIiwiLi4vc3JjL2RhdGEtdHlwZXMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7O0FBb0NPLElBQU0sU0FBTixNQUFhO0FBQUEsRUFDbEIsS0FBQTtBQUFBLEVBQ0EsSUFBQTtBQUFBLEVBQ0EsSUFBQTtBQUFBLEVBQ0EsY0FBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFZQSxXQUFBLENBQVksU0FBMEIsY0FBZ0MsRUFBQTtBQUNwRSxJQUFBLE1BQU0sZUFBZSxPQUFRLENBQUEsUUFBQTtBQUM3QixJQUFBLElBQUksY0FBZSxDQUFBLElBQUEsS0FBUyxPQUFXLElBQUEsY0FBQSxDQUFlLFNBQVMsS0FBTyxFQUFBO0FBQ3BFLE1BQUEsSUFBQSxDQUFLLFFBQVEsSUFBSSxpQkFBQTtBQUFBLFFBQ2YsWUFBQTtBQUFBLFFBQ0EsY0FBZSxDQUFBLE9BQUE7QUFBQSxRQUNmLGNBQWUsQ0FBQTtBQUFBLE9BQ2pCO0FBQUE7QUFFRixJQUFBLElBQUksY0FBZSxDQUFBLElBQUEsS0FBUyxNQUFVLElBQUEsY0FBQSxDQUFlLFNBQVMsS0FBTyxFQUFBO0FBQ25FLE1BQUEsSUFBQSxDQUFLLE9BQU8sSUFBSSxnQkFBQTtBQUFBLFFBQ2QsWUFBQTtBQUFBLFFBQ0EsY0FBZSxDQUFBLE9BQUE7QUFBQSxRQUNmLGNBQWUsQ0FBQTtBQUFBLE9BQ2pCO0FBQUE7QUFFRixJQUFBLElBQUEsQ0FBSyxjQUFpQixHQUFBLGNBQUE7QUFDdEIsSUFBSyxJQUFBLENBQUEsSUFBQSxHQUFPLElBQUksSUFBQSxDQUFLLE9BQU8sQ0FBQTtBQUFBO0FBQzlCO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQWdCQSxNQUFNLGdCQUNKLEtBQzJELEVBQUE7QUFDM0QsSUFBQSxPQUFPLE1BQU0sSUFBQSxDQUFLLElBQUssQ0FBQSxPQUFBLENBQVEsS0FBSyxDQUFBO0FBQUE7QUFDdEM7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBYUEsTUFBTSxLQUNKLENBQUEsT0FBQSxFQUNBLGNBQ29CLEVBQUE7QUFDcEIsSUFBQSxNQUFNLE9BQVUsR0FBQSxJQUFBLENBQUssaUJBQWtCLENBQUEsY0FBQSxFQUFnQixJQUFJLENBQUE7QUFDM0QsSUFBTyxPQUFBLE1BQU0sT0FBUSxDQUFBLGFBQUEsQ0FBYyxPQUFPLENBQUE7QUFBQTtBQUM1QztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQWNBLE1BQU0sU0FDSixDQUFBLEtBQUEsRUFDQSxjQUNvQixFQUFBO0FBQ3BCLElBQUEsTUFBTSxFQUFFLE9BQVEsRUFBQSxHQUFJLE1BQU0sSUFBQSxDQUFLLGdCQUFnQixLQUFLLENBQUE7QUFDcEQsSUFBTyxPQUFBLElBQUEsQ0FBSyxLQUFNLENBQUEsT0FBQSxFQUFTLGNBQWMsQ0FBQTtBQUFBO0FBQzNDO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQWFBLE1BQU0sTUFDSixDQUFBLEtBQUEsRUFDQSxjQUNrQixFQUFBO0FBQ2xCLElBQUEsTUFBTSxPQUFVLEdBQUEsSUFBQSxDQUFLLGlCQUFrQixDQUFBLGNBQUEsRUFBZ0IsSUFBSSxDQUFBO0FBQzNELElBQU8sT0FBQSxNQUFNLE9BQVEsQ0FBQSxXQUFBLENBQVksS0FBSyxDQUFBO0FBQUE7QUFDeEM7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQVlBLE1BQU0sT0FBVSxHQUFBO0FBQ2QsSUFBQSxJQUFJLEtBQUssS0FBTyxFQUFBO0FBQ2QsTUFBTSxNQUFBLElBQUEsQ0FBSyxNQUFNLE9BQVEsRUFBQTtBQUFBO0FBRTNCLElBQUEsSUFBSSxLQUFLLElBQU0sRUFBQTtBQUNiLE1BQU0sTUFBQSxJQUFBLENBQUssS0FBSyxPQUFRLEVBQUE7QUFBQTtBQUMxQjtBQUNGO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBY1Esa0JBQWtCLFdBQXNDLEVBQUE7QUFDOUQsSUFBSSxJQUFBLElBQUE7QUFDSixJQUFBLElBQUksV0FBZ0IsS0FBQSxPQUFBLElBQVcsSUFBSyxDQUFBLGNBQUEsQ0FBZSxTQUFTLE9BQVMsRUFBQTtBQUNuRSxNQUFPLElBQUEsR0FBQSxPQUFBO0FBQUEsZUFDRSxXQUFnQixLQUFBLE1BQUEsSUFBVSxJQUFLLENBQUEsY0FBQSxDQUFlLFNBQVMsTUFBUSxFQUFBO0FBQ3hFLE1BQU8sSUFBQSxHQUFBLE1BQUE7QUFBQSxLQUNGLE1BQUE7QUFDTCxNQUFBLE1BQU0sSUFBSSxLQUFBO0FBQUEsUUFDUjtBQUFBLE9BQ0Y7QUFBQTtBQUdGLElBQUksSUFBQSxPQUFBO0FBQ0osSUFBSSxJQUFBLElBQUEsS0FBUyxPQUFXLElBQUEsSUFBQSxDQUFLLEtBQU8sRUFBQTtBQUNsQyxNQUFBLE9BQUEsR0FBVSxJQUFLLENBQUEsS0FBQTtBQUFBLEtBQ04sTUFBQSxJQUFBLElBQUEsS0FBUyxNQUFVLElBQUEsSUFBQSxDQUFLLElBQU0sRUFBQTtBQUN2QyxNQUFBLE9BQUEsR0FBVSxJQUFLLENBQUEsSUFBQTtBQUFBLEtBQ1YsTUFBQTtBQUNMLE1BQUEsTUFBTSxJQUFJLEtBQUEsQ0FBTSxDQUFtQixnQkFBQSxFQUFBLElBQUksQ0FBa0IsZ0JBQUEsQ0FBQSxDQUFBO0FBQUE7QUFHM0QsSUFBTyxPQUFBLE9BQUE7QUFBQTtBQUVYO0FDOUxPLElBQU0sWUFBZSxHQUFBLENBQzFCLElBQ0EsRUFBQSxRQUFBLEVBQ0EsYUFDUyxLQUFBO0FBRVQsRUFBQSxJQUFJLENBQUMsSUFBQSxDQUFLLFVBQVcsQ0FBQSxRQUFRLENBQUcsRUFBQTtBQUM5QixJQUFBLE1BQU0sSUFBSSxLQUFBO0FBQUEsTUFDUixzREFBc0QsUUFBUSxDQUFBO0FBQUEsS0FDaEU7QUFBQTtBQUdGLEVBQU0sTUFBQSxXQUFBLEdBQWMsU0FBVSxDQUFBLElBQUEsRUFBTSxhQUFhLENBQUE7QUFDakQsRUFBTSxNQUFBLEdBQUEsR0FBTSxJQUFLLENBQUEsT0FBQSxDQUFRLFFBQVEsQ0FBQTtBQUNqQyxFQUFBLEVBQUEsQ0FBRyxTQUFVLENBQUEsR0FBQSxFQUFLLEVBQUUsU0FBQSxFQUFXLE1BQU0sQ0FBQTtBQUNyQyxFQUFHLEVBQUEsQ0FBQSxhQUFBLENBQWMsUUFBVSxFQUFBLFdBQUEsRUFBYSxPQUFPLENBQUE7QUFDakQ7OztBQzNCTyxJQUFNLGlCQUFOLE1BQTJEO0FBQUEsRUFDL0MsTUFBQTtBQUFBLEVBQ1QsS0FBQTtBQUFBLEVBRVIsV0FBQSxDQUFZLFFBQVcsS0FBWSxFQUFBO0FBQ2pDLElBQUksSUFBQSxNQUFBLEtBQVcsTUFBTSxNQUFRLEVBQUE7QUFDM0IsTUFBQSxNQUFNLElBQUksS0FBQTtBQUFBLFFBQ1IsQ0FBNkIsMEJBQUEsRUFBQSxNQUFNLENBQVMsTUFBQSxFQUFBLEtBQUEsQ0FBTSxNQUFNLENBQUE7QUFBQSxPQUMxRDtBQUFBO0FBRUYsSUFBQSxJQUFBLENBQUssTUFBUyxHQUFBLE1BQUE7QUFDZCxJQUFLLElBQUEsQ0FBQSxLQUFBLEdBQVEsQ0FBQyxHQUFHLEtBQUssQ0FBQTtBQUFBO0FBQ3hCLEVBRUEsR0FBYyxHQUFBO0FBQ1osSUFBQSxPQUFPLElBQUssQ0FBQSxNQUFBO0FBQUE7QUFDZCxFQUVBLE9BQWUsR0FBQTtBQUNiLElBQU8sT0FBQSxDQUFDLEdBQUcsSUFBQSxDQUFLLEtBQUssQ0FBQTtBQUFBO0FBQ3ZCLEVBRUEsSUFBSSxLQUFrQixFQUFBO0FBQ3BCLElBQUEsSUFBSSxLQUFRLEdBQUEsQ0FBQSxJQUFLLEtBQVMsSUFBQSxJQUFBLENBQUssTUFBUSxFQUFBO0FBQ3JDLE1BQUEsTUFBTSxJQUFJLEtBQUEsQ0FBTSxDQUFTLE1BQUEsRUFBQSxLQUFLLENBQWdCLGNBQUEsQ0FBQSxDQUFBO0FBQUE7QUFFaEQsSUFBTyxPQUFBLElBQUEsQ0FBSyxNQUFNLEtBQUssQ0FBQTtBQUFBO0FBQ3pCLEVBRUEsR0FBRyxLQUFrQixFQUFBO0FBQ25CLElBQUEsTUFBTSxhQUFnQixHQUFBLEtBQUEsR0FBUSxDQUFJLEdBQUEsSUFBQSxDQUFLLFNBQVMsS0FBUSxHQUFBLEtBQUE7QUFDeEQsSUFBTyxPQUFBLElBQUEsQ0FBSyxJQUFJLGFBQWEsQ0FBQTtBQUFBO0FBQy9CLEVBRUEsR0FBQSxDQUFJLE9BQWUsSUFBZSxFQUFBO0FBQ2hDLElBQUEsSUFBSSxLQUFRLEdBQUEsQ0FBQSxJQUFLLEtBQVMsSUFBQSxJQUFBLENBQUssTUFBUSxFQUFBO0FBQ3JDLE1BQUEsTUFBTSxJQUFJLEtBQUEsQ0FBTSxDQUFTLE1BQUEsRUFBQSxLQUFLLENBQWdCLGNBQUEsQ0FBQSxDQUFBO0FBQUE7QUFFaEQsSUFBSyxJQUFBLENBQUEsS0FBQSxDQUFNLEtBQUssQ0FBSSxHQUFBLElBQUE7QUFBQTtBQUN0QixFQUVBLFFBQVEsUUFBa0QsRUFBQTtBQUN4RCxJQUFLLElBQUEsQ0FBQSxLQUFBLENBQU0sUUFBUSxRQUFRLENBQUE7QUFBQTtBQUM3QixFQUVBLElBQU8sUUFBOEMsRUFBQTtBQUNuRCxJQUFPLE9BQUEsSUFBQSxDQUFLLEtBQU0sQ0FBQSxHQUFBLENBQUksUUFBUSxDQUFBO0FBQUE7QUFDaEMsRUFFQSxlQUFnQyxHQUFBO0FBQzlCLElBQU8sT0FBQSxJQUFBLENBQUssS0FBTSxDQUFBLEdBQUEsQ0FBSSxzQkFBc0IsQ0FBQTtBQUFBO0FBRWhEOzs7QUNsRGEsSUFBQSxJQUFBLEdBQU4sTUFBTSxLQUFLLENBQUE7QUFBQTtBQUFBLEVBRUMsR0FBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQU9qQixZQUFZLEtBQWdCLEVBQUE7QUFDMUIsSUFBQSxJQUFBLENBQUssR0FBTSxHQUFBLEtBQUE7QUFBQTtBQUNiO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQU9BLEtBQWlCLEdBQUE7QUFDZixJQUFBLE9BQU8sSUFBSyxDQUFBLEdBQUE7QUFBQTtBQUNkO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBUUEsR0FBRyxLQUFzQixFQUFBO0FBQ3ZCLElBQU8sT0FBQSxJQUFBLENBQUssUUFBUSxLQUFNLENBQUEsR0FBQTtBQUFBO0FBQzVCO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBUUEsR0FBWSxHQUFBO0FBQ1YsSUFBQSxPQUFPLElBQUksS0FBQSxDQUFLLENBQUMsSUFBQSxDQUFLLEdBQUcsQ0FBQTtBQUFBO0FBQzNCO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBUUEsZUFBMkIsR0FBQTtBQUN6QixJQUFBLE9BQU8sSUFBSyxDQUFBLEdBQUE7QUFBQTtBQUVoQjs7O0FDNUNPLElBQU0sYUFBTixNQUF1RDtBQUFBO0FBQUEsRUFFM0MsT0FBQTtBQUFBO0FBQUEsRUFFVCxNQUFBO0FBQUE7QUFBQSxFQUVBLEtBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQVdSLFdBQVksQ0FBQSxPQUFBLEVBQVksWUFBaUIsRUFBQSxZQUFBLEdBQW9CLEVBQUksRUFBQTtBQUMvRCxJQUFBLElBQUksVUFBVSxDQUFHLEVBQUE7QUFDZixNQUFNLE1BQUEsSUFBSSxNQUFNLCtCQUErQixDQUFBO0FBQUE7QUFFakQsSUFBQSxJQUFBLENBQUssT0FBVSxHQUFBLE9BQUE7QUFDZixJQUFLLElBQUEsQ0FBQSxLQUFBLEdBQVEsTUFBTSxJQUFLLENBQUEsRUFBRSxRQUFRLE9BQVEsRUFBQSxFQUFHLE1BQU0sWUFBWSxDQUFBO0FBQy9ELElBQUEsSUFBQSxDQUFLLE1BQVMsR0FBQSxDQUFBO0FBQ2QsSUFBQSxJQUFBLENBQUssZ0JBQWdCLFlBQVksQ0FBQTtBQUFBO0FBQ25DO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQU9BLEdBQWMsR0FBQTtBQUNaLElBQUEsT0FBTyxJQUFLLENBQUEsTUFBQTtBQUFBO0FBQ2Q7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBT0EsTUFBaUIsR0FBQTtBQUNmLElBQUEsT0FBTyxJQUFLLENBQUEsT0FBQTtBQUFBO0FBQ2Q7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBT1EsT0FBbUIsR0FBQTtBQUN6QixJQUFBLE9BQU8sS0FBSyxNQUFXLEtBQUEsQ0FBQTtBQUFBO0FBQ3pCO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQU9RLE1BQWtCLEdBQUE7QUFDeEIsSUFBTyxPQUFBLElBQUEsQ0FBSyxXQUFXLElBQUssQ0FBQSxPQUFBO0FBQUE7QUFDOUI7QUFBQTtBQUFBO0FBQUEsRUFLQSxPQUFlLEdBQUE7QUFDYixJQUFBLE9BQU8sSUFBSyxDQUFBLEtBQUE7QUFBQTtBQUNkO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFTQSxJQUFJLEtBQWtCLEVBQUE7QUFDcEIsSUFBQSxJQUFJLEtBQVEsR0FBQSxDQUFBLElBQUssS0FBUyxJQUFBLElBQUEsQ0FBSyxNQUFRLEVBQUE7QUFDckMsTUFBTSxNQUFBLElBQUksTUFBTSxxQkFBcUIsQ0FBQTtBQUFBO0FBRXZDLElBQU8sT0FBQSxJQUFBLENBQUssTUFBTSxLQUFLLENBQUE7QUFBQTtBQUN6QjtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFVQSxHQUFHLEtBQWtCLEVBQUE7QUFDbkIsSUFBQSxNQUFNLGFBQWdCLEdBQUEsS0FBQSxHQUFRLENBQUksR0FBQSxJQUFBLENBQUssU0FBUyxLQUFRLEdBQUEsS0FBQTtBQUN4RCxJQUFPLE9BQUEsSUFBQSxDQUFLLElBQUksYUFBYSxDQUFBO0FBQUE7QUFDL0I7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFRQSxLQUFLLElBQWUsRUFBQTtBQUNsQixJQUFJLElBQUEsSUFBQSxDQUFLLFFBQVUsRUFBQTtBQUNqQixNQUFNLE1BQUEsSUFBSSxNQUFNLGdCQUFnQixDQUFBO0FBQUE7QUFFbEMsSUFBSyxJQUFBLENBQUEsS0FBQSxDQUFNLElBQUssQ0FBQSxNQUFNLENBQUksR0FBQSxJQUFBO0FBQzFCLElBQUssSUFBQSxDQUFBLE1BQUEsRUFBQTtBQUFBO0FBQ1A7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxF