@callcium/sdk 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +701 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3216 -0
- package/dist/index.js.map +1 -0
- package/package.json +63 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":["DF","inspect","DF","DF","PF","DF","Issues.bitmaskContradiction","Issues.redundantBitmask","Issues.bitmaskAnyImpossible","Issues.setFullyExcluded","Issues.setPartiallyExcluded","Issues.setExcludesEquality","Issues.setReduction","Issues.emptySetIntersection","Issues.setRedundancy","Issues.duplicateConstraint","Issues.fromOpRule","Issues.unsortedInSet","Issues.emptyGroup","PF"],"sources":["../src/errors.ts","../src/bytes.ts","../src/constants.ts","../src/descriptor.ts","../src/type-desc.ts","../src/descriptor-coder.ts","../src/policy-coder.ts","../src/operators.ts","../src/validation-issue.ts","../src/policy-validator.ts","../src/signature.ts","../src/policy-builder.ts","../src/constraint.ts","../src/reader.ts","../src/policy-enforcer.ts"],"sourcesContent":["/** Machine-readable error code for structural decoding and validation failures. */\nexport type CallciumErrorCode =\n | \"UNSUPPORTED_VERSION\"\n | \"MALFORMED_HEADER\"\n | \"UNEXPECTED_END\"\n | \"NODE_OVERFLOW\"\n | \"UNKNOWN_TYPE_CODE\"\n | \"INVALID_OPERATOR\"\n | \"INVALID_ARRAY_LENGTH\"\n | \"INVALID_TUPLE_FIELD_COUNT\"\n | \"PARAM_COUNT_MISMATCH\"\n | \"EMPTY_POLICY\"\n | \"EMPTY_GROUP\"\n | \"EMPTY_PATH\"\n | \"INVALID_CONTEXT_PATH\"\n | \"INVALID_CONTEXT_PROPERTY\"\n | \"INVALID_QUANTIFIER\"\n | \"INVALID_SCOPE\"\n | \"RULE_SIZE_MISMATCH\"\n | \"GROUP_SIZE_MISMATCH\"\n | \"GROUP_OVERFLOW\"\n | \"RULE_OVERFLOW\"\n | \"TRAILING_BYTES\"\n | \"INTERNAL_ERROR\"\n | \"INVALID_SIGNATURE\"\n | \"INVALID_TYPE_STRING\"\n | \"UNKNOWN_TYPE\"\n | \"DESCRIPTOR_TOO_LARGE\"\n | \"INVALID_PATH\"\n | \"DUPLICATE_PATH\"\n | \"INVALID_CONSTRAINT\"\n | \"INVALID_OPERATOR_DATA\"\n | \"EMPTY_SET\"\n | \"SET_TOO_LARGE\"\n | \"INVALID_RANGE\"\n | \"GROUP_COUNT_OVERFLOW\"\n | \"RULE_COUNT_OVERFLOW\"\n | \"RULE_SIZE_OVERFLOW\"\n | \"DESC_LENGTH_OVERFLOW\"\n | \"INVALID_HEX\"\n | \"VALIDATION_ERROR\";\n\n/**\n * Thrown when a policy or descriptor blob is structurally malformed.\n * The optional `offset` indicates the byte position in the source blob where the error was detected.\n */\nexport class CallciumError extends Error {\n public readonly code: CallciumErrorCode;\n /** Byte position in the source blob where the error was detected, if applicable. */\n public readonly offset?: number;\n\n constructor(code: CallciumErrorCode, message: string, offset?: number) {\n const prefix = offset !== undefined ? `[offset ${offset}] ` : \"\";\n super(`${prefix}${message}`);\n this.name = \"CallciumError\";\n this.code = code;\n Object.setPrototypeOf(this, CallciumError.prototype);\n }\n}\n\n/**\n * Thrown by `PolicyEnforcer.enforce` when calldata fails policy enforcement.\n * Distinct from `CallciumError(\"VALIDATION_ERROR\")`, which signals static\n * issues in the policy itself.\n * Carries the full list of violations (one per failed group).\n */\nexport class PolicyViolationError extends Error {\n public readonly violations: import(\"./types\").Violation[];\n\n constructor(violations: import(\"./types\").Violation[]) {\n const first = violations[0];\n const msg = first ? `Policy violation: ${first.message}` : \"Policy violation\";\n super(msg);\n this.name = \"PolicyViolationError\";\n this.violations = violations;\n Object.setPrototypeOf(this, PolicyViolationError.prototype);\n }\n}\n","import { CallciumError } from \"./errors\";\n\nimport type { Address, Hex } from \"./types\";\n\n/** Regex that matches a valid hex body (even number of hex chars). */\nconst HEX_BODY_RE = /^[0-9a-fA-F]*$/;\n\n/** Convert a hex string to a byte array, stripping the 0x prefix if present. */\nexport function hexToBytes(hex: string): Uint8Array {\n const clean = hex.startsWith(\"0x\") ? hex.slice(2) : hex;\n if (clean.length % 2 !== 0) {\n throw new CallciumError(\"INVALID_HEX\", \"Odd-length hex string\");\n }\n if (!HEX_BODY_RE.test(clean)) {\n throw new CallciumError(\"INVALID_HEX\", \"Invalid hex characters\");\n }\n const bytes = new Uint8Array(clean.length / 2);\n for (let i = 0; i < clean.length; i += 2) {\n bytes[i / 2] = parseInt(clean.substring(i, i + 2), 16);\n }\n return bytes;\n}\n\n// Pre-computed hex lookup avoids per-byte toString + padStart in the hot path.\nconst HEX_LUT = Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, \"0\"));\n\n/** Convert a byte array to a 0x-prefixed lowercase hex string. */\nexport function bytesToHex(bytes: Uint8Array): Hex {\n let body = \"\";\n for (let i = 0; i < bytes.length; i++) body += HEX_LUT[bytes[i]!];\n return `0x${body}`;\n}\n\n/** Extract a subarray and return it as a 0x-prefixed hex string. */\nexport function toHex(data: Uint8Array, start: number, end: number): Hex {\n return bytesToHex(data.subarray(start, end));\n}\n\n/** Read a big-endian uint16 from a byte array at the given offset. */\nexport function readU16(data: Uint8Array, offset: number): number {\n return (data[offset]! << 8) | data[offset + 1]!;\n}\n\n/** Read a big-endian uint24 from a byte array at the given offset. */\nexport function readU24(data: Uint8Array, offset: number): number {\n return (data[offset]! << 16) | (data[offset + 1]! << 8) | data[offset + 2]!;\n}\n\n/** Read a big-endian uint32 from a byte array at the given offset. */\nexport function readU32(data: Uint8Array, offset: number): number {\n return ((data[offset]! << 24) | (data[offset + 1]! << 16) | (data[offset + 2]! << 8) | data[offset + 3]!) >>> 0;\n}\n\n/** Write a 16-bit big-endian value into a Uint8Array at offset. */\nexport function writeBE16(buffer: Uint8Array, offset: number, value: number): void {\n buffer[offset] = (value >>> 8) & 0xff;\n buffer[offset + 1] = value & 0xff;\n}\n\n/** Write a 24-bit big-endian value into a Uint8Array at offset. */\nexport function writeBE24(buffer: Uint8Array, offset: number, value: number): void {\n buffer[offset] = (value >>> 16) & 0xff;\n buffer[offset + 1] = (value >>> 8) & 0xff;\n buffer[offset + 2] = value & 0xff;\n}\n\n/** Format a bigint as a zero-padded 32-byte hex string. */\nexport function bigintToHex(value: bigint): Hex {\n return `0x${value.toString(16).padStart(64, \"0\")}`;\n}\n\n/** Validate and brand a hex string as an address. Throws if the runtime length is not exactly 20 bytes. */\nexport function toAddress(hex: string): Address {\n const body = hex.startsWith(\"0x\") ? hex.slice(2) : hex;\n if (body.length !== 40) {\n throw new CallciumError(\"INVALID_HEX\", `Invalid address length: expected 40 hex chars, got ${body.length}`);\n }\n if (!HEX_BODY_RE.test(body)) {\n throw new CallciumError(\"INVALID_HEX\", \"Invalid hex characters in address\");\n }\n return `0x${body}`;\n}\n","import { CallciumError } from \"./errors\";\n\n///////////////////////////////////////////////////////////////////////////\n// Descriptor format\n///////////////////////////////////////////////////////////////////////////\n\n/** Binary layout constants for the Callcium descriptor format. */\nexport const DescriptorFormat = {\n VERSION: 0x01,\n HEADER_SIZE: 2,\n TYPECODE_SIZE: 1,\n COMPOSITE_META_SIZE: 3,\n TUPLE_HEADER_SIZE: 6,\n ARRAY_HEADER_SIZE: 4,\n ARRAY_LENGTH_SIZE: 2,\n TUPLE_FIELDCOUNT_SIZE: 2,\n META_STATIC_WORDS_SHIFT: 12,\n META_NODE_LENGTH_MASK: 0x0fff,\n MAX_NODE_LENGTH: 0x0fff,\n MAX_STATIC_ARRAY_LENGTH: 4095,\n MAX_TUPLE_FIELDS: 4089,\n MAX_PARAMS: 255,\n} as const satisfies Record<string, number>;\n\n///////////////////////////////////////////////////////////////////////////\n// Policy format\n///////////////////////////////////////////////////////////////////////////\n\n/** Binary layout constants for the Callcium policy format. */\nexport const PolicyFormat = {\n VERSION: 0x01,\n VERSION_MASK: 0x0f,\n FLAG_NO_SELECTOR: 0x10,\n RESERVED_MASK: 0xe0,\n HEADER_SIZE: 1,\n SELECTOR_OFFSET: 1,\n SELECTOR_SIZE: 4,\n DESC_LENGTH_OFFSET: 5,\n DESC_LENGTH_SIZE: 2,\n DESC_OFFSET: 7,\n GROUP_COUNT_SIZE: 1,\n GROUP_RULECOUNT_SIZE: 2,\n GROUP_SIZE_SIZE: 4,\n GROUP_HEADER_SIZE: 6,\n RULE_SIZE_SIZE: 2,\n RULE_SCOPE_OFFSET: 2,\n RULE_DEPTH_OFFSET: 3,\n RULE_PATH_OFFSET: 4,\n PATH_STEP_SIZE: 2,\n RULE_OPCODE_SIZE: 1,\n RULE_DATALENGTH_SIZE: 2,\n RULE_FIXED_OVERHEAD: 7,\n RULE_MIN_SIZE: 9,\n} as const satisfies Record<string, number>;\n\n///////////////////////////////////////////////////////////////////////////\n// Table-derived helpers\n///////////////////////////////////////////////////////////////////////////\n\n/**\n * Extract a `{ KEY: code }` map from a table with `key` and `code` fields.\n * @internal\n */\ntype CodeMap<T extends readonly { readonly key: string; readonly code: number }[]> = {\n readonly [E in T[number] as E[\"key\"]]: E[\"code\"];\n};\n\n/** Build a plain `{ KEY: code }` object from a table at runtime. */\nfunction buildCodeMap<T extends readonly { readonly key: string; readonly code: number }[]>(table: T): CodeMap<T> {\n // oxlint-disable-next-line typescript/no-unsafe-type-assertion -- derived from the same const table that defines the type.\n return Object.fromEntries(table.map((e) => [e.key, e.code])) as CodeMap<T>;\n}\n\n///////////////////////////////////////////////////////////////////////////\n// Scope codes\n///////////////////////////////////////////////////////////////////////////\n\nconst SCOPE_TABLE = [\n { key: \"CONTEXT\", code: 0x00, label: \"context\" },\n { key: \"CALLDATA\", code: 0x01, label: \"calldata\" },\n] as const;\n\n/** Rule scope discriminant: context (EVM environment) vs. calldata (ABI payload). */\nexport const Scope = buildCodeMap(SCOPE_TABLE);\n\n/** Display metadata for a scope code. */\nexport type ScopeInfo = { label: string };\n\nconst scopeByCode = new Map<number, ScopeInfo>(SCOPE_TABLE.map((e) => [e.code, { label: e.label }]));\n\n/**\n * Map a scope code to its display label.\n * @param code - Scope byte value.\n * @returns Display metadata for the scope.\n * @throws {CallciumError} If the code is not a recognised scope.\n */\nexport function lookupScope(code: number): ScopeInfo {\n const info = scopeByCode.get(code);\n if (!info) throw new CallciumError(\"INVALID_SCOPE\", `Unknown scope value ${code}`);\n return info;\n}\n\n///////////////////////////////////////////////////////////////////////////\n// Context property IDs\n///////////////////////////////////////////////////////////////////////////\n\nconst CTX_PROP_TABLE = [\n { key: \"MSG_SENDER\", code: 0x0000, label: \"msg.sender\", typeCode: 0x40 },\n { key: \"MSG_VALUE\", code: 0x0001, label: \"msg.value\", typeCode: 0x1f },\n { key: \"BLOCK_TIMESTAMP\", code: 0x0002, label: \"block.timestamp\", typeCode: 0x1f },\n { key: \"BLOCK_NUMBER\", code: 0x0003, label: \"block.number\", typeCode: 0x1f },\n { key: \"CHAIN_ID\", code: 0x0004, label: \"block.chainid\", typeCode: 0x1f },\n { key: \"TX_ORIGIN\", code: 0x0005, label: \"tx.origin\", typeCode: 0x40 },\n] as const;\n\n/** Well-known context property IDs for context-scope rules. */\nexport const ContextProperty = buildCodeMap(CTX_PROP_TABLE);\n\n/** Maximum valid context property ID. */\nexport const MAX_CONTEXT_PROPERTY_ID = Math.max(...CTX_PROP_TABLE.map((e) => e.code));\n\n/** Display metadata for a context property code. */\nexport type ContextPropertyInfo = { label: string; contextKey: keyof import(\"./types\").Context; typeCode: number };\n\n/** Maps each context property table key to its camelCase Context key. */\nconst CTX_KEY_MAP: Record<(typeof CTX_PROP_TABLE)[number][\"key\"], keyof import(\"./types\").Context> = {\n MSG_SENDER: \"msgSender\",\n MSG_VALUE: \"msgValue\",\n BLOCK_TIMESTAMP: \"blockTimestamp\",\n BLOCK_NUMBER: \"blockNumber\",\n CHAIN_ID: \"chainId\",\n TX_ORIGIN: \"txOrigin\",\n};\n\nconst ctxPropByCode = new Map<number, ContextPropertyInfo>(\n CTX_PROP_TABLE.map((e) => [e.code, { label: e.label, contextKey: CTX_KEY_MAP[e.key], typeCode: e.typeCode }]),\n);\n\n/**\n * Map a context property code to its display label and ABI type code.\n * @param code - Context property ID.\n * @returns Display metadata including the Solidity type code for the property value.\n * @throws {CallciumError} If the code is not a recognised context property.\n */\nexport function lookupContextProperty(code: number): ContextPropertyInfo {\n const info = ctxPropByCode.get(code);\n if (!info) throw new CallciumError(\"INVALID_CONTEXT_PROPERTY\", `Unknown context property ${code}`);\n return info;\n}\n\n///////////////////////////////////////////////////////////////////////////\n// Protocol limits\n///////////////////////////////////////////////////////////////////////////\n\n/** Protocol-imposed safety limits for path depth and quantifier array size. */\nexport const Limits = {\n MAX_PATH_DEPTH: 32,\n MAX_QUANTIFIED_ARRAY_LENGTH: 256,\n} as const satisfies Record<string, number>;\n\n///////////////////////////////////////////////////////////////////////////\n// Operator codes\n///////////////////////////////////////////////////////////////////////////\n\n/** Operand count category for operator data validation. */\nexport type Operands = \"single\" | \"range\" | \"variadic\";\n\n/** @internal */\nconst OP_TABLE = [\n { key: \"EQ\", code: 0x01, label: \"==\", operands: \"single\" },\n { key: \"GT\", code: 0x02, label: \">\", operands: \"single\" },\n { key: \"LT\", code: 0x03, label: \"<\", operands: \"single\" },\n { key: \"GTE\", code: 0x04, label: \">=\", operands: \"single\" },\n { key: \"LTE\", code: 0x05, label: \"<=\", operands: \"single\" },\n { key: \"BETWEEN\", code: 0x06, label: \"between\", operands: \"range\" },\n { key: \"IN\", code: 0x07, label: \"in\", operands: \"variadic\" },\n { key: \"BITMASK_ALL\", code: 0x10, label: \"bitmask all\", operands: \"single\" },\n { key: \"BITMASK_ANY\", code: 0x11, label: \"bitmask any\", operands: \"single\" },\n { key: \"BITMASK_NONE\", code: 0x12, label: \"bitmask none\", operands: \"single\" },\n { key: \"LENGTH_EQ\", code: 0x20, label: \"length ==\", operands: \"single\" },\n { key: \"LENGTH_GT\", code: 0x21, label: \"length >\", operands: \"single\" },\n { key: \"LENGTH_LT\", code: 0x22, label: \"length <\", operands: \"single\" },\n { key: \"LENGTH_GTE\", code: 0x23, label: \"length >=\", operands: \"single\" },\n { key: \"LENGTH_LTE\", code: 0x24, label: \"length <=\", operands: \"single\" },\n { key: \"LENGTH_BETWEEN\", code: 0x25, label: \"length between\", operands: \"range\" },\n] as const;\n\n/** Callcium policy operator codes. */\nexport const Op: CodeMap<typeof OP_TABLE> & { readonly NOT: 0x80 } = { ...buildCodeMap(OP_TABLE), NOT: 0x80 };\n\n/** Display metadata for an operator code. */\nexport type OpInfo = { label: string; operands: Operands };\n\nconst opByCode = new Map<number, OpInfo>(OP_TABLE.map((e) => [e.code, { label: e.label, operands: e.operands }]));\n\n/**\n * Map an operator code to its display label. Strips the NOT flag automatically.\n * @param code - Operator byte value (may include the NOT flag).\n * @returns Display metadata for the base operator.\n * @throws {CallciumError} If the base code is not a recognised operator.\n */\nexport function lookupOp(code: number): OpInfo {\n const base = code & ~Op.NOT;\n const info = opByCode.get(base);\n if (!info)\n throw new CallciumError(\"INVALID_OPERATOR\", `Unknown operator code 0x${base.toString(16).padStart(2, \"0\")}`);\n return info;\n}\n\n/**\n * Check whether an operator's data payload has the correct length.\n * @param opBase - Base operator code with the NOT flag stripped.\n * @param dataLength - Byte length of the operator's data payload.\n * @returns True if the data length is valid for the given operator.\n */\nexport function isValidOperatorData(opBase: number, dataLength: number): boolean {\n const operands = opByCode.get(opBase)?.operands;\n if (operands === \"single\") return dataLength === 32;\n if (operands === \"range\") return dataLength === 64;\n if (operands === \"variadic\") return dataLength > 0 && dataLength % 32 === 0;\n return false;\n}\n\n///////////////////////////////////////////////////////////////////////////\n// Quantifier steps\n///////////////////////////////////////////////////////////////////////////\n\nconst QUANTIFIER_TABLE = [\n { key: \"ALL_OR_EMPTY\", code: 0xffff, label: \"all or empty\" },\n { key: \"ALL\", code: 0xfffe, label: \"all\" },\n { key: \"ANY\", code: 0xfffd, label: \"any\" },\n] as const;\n\n/** Reserved path step values that trigger quantified evaluation over array elements. */\nexport const Quantifier = buildCodeMap(QUANTIFIER_TABLE);\n\n/** Display metadata for a quantifier step. */\nexport type QuantifierInfo = { label: string };\n\nconst quantifierByCode = new Map<number, QuantifierInfo>(QUANTIFIER_TABLE.map((e) => [e.code, { label: e.label }]));\n\n/** Check whether a path step is a quantifier (ALL_OR_EMPTY, ALL, or ANY). */\nexport function isQuantifier(step: number): boolean {\n return step >= Quantifier.ANY;\n}\n\n/**\n * Map a quantifier path step to its display label.\n * @param code - Quantifier step value.\n * @returns Display metadata for the quantifier.\n * @throws {CallciumError} If the code is not a recognised quantifier.\n */\nexport function lookupQuantifier(code: number): QuantifierInfo {\n const info = quantifierByCode.get(code);\n if (!info) throw new CallciumError(\"INVALID_QUANTIFIER\", `Unknown quantifier step 0x${code.toString(16)}`);\n return info;\n}\n\n///////////////////////////////////////////////////////////////////////////\n// Type code ranges\n///////////////////////////////////////////////////////////////////////////\n\n/** ABI type code ranges and sentinel values for the descriptor format. */\nexport const TypeCode = {\n UINT_MIN: 0x00,\n UINT_MAX: 0x1f,\n INT_MIN: 0x20,\n INT_MAX: 0x3f,\n ADDRESS: 0x40,\n BOOL: 0x41,\n FUNCTION: 0x42,\n FIXED_BYTES_MIN: 0x50,\n FIXED_BYTES_MAX: 0x6f,\n BYTES: 0x70,\n STRING: 0x71,\n STATIC_ARRAY: 0x80,\n DYNAMIC_ARRAY: 0x81,\n TUPLE: 0x90,\n} as const satisfies Record<string, number>;\n\n/** Structural category for a descriptor type code. */\nexport type TypeClass = \"elementary\" | \"tuple\" | \"staticArray\" | \"dynamicArray\";\n\n/** Structural classification without label — used by the decoder hot path. */\nexport type TypeClassInfo = { typeClass: TypeClass; isDynamic: boolean };\n\n/** Display metadata for a descriptor type code. */\nexport type TypeCodeInfo = TypeClassInfo & { label: string };\n\n/** Throw an UNKNOWN_TYPE_CODE error. */\nfunction unknownTypeCode(code: number): never {\n throw new CallciumError(\"UNKNOWN_TYPE_CODE\", `Unknown type code 0x${code.toString(16).padStart(2, \"0\")}`);\n}\n\n// Pre-allocated constant objects for fixed type codes (avoids per-call allocation).\nconst ELEMENTARY = { typeClass: \"elementary\", isDynamic: false } as const;\nconst ELEMENTARY_DYN = { typeClass: \"elementary\", isDynamic: true } as const;\nconst STATIC_ARR = { typeClass: \"staticArray\", isDynamic: false } as const;\nconst DYNAMIC_ARR = { typeClass: \"dynamicArray\", isDynamic: true } as const;\nconst TUPLE = { typeClass: \"tuple\", isDynamic: false } as const;\n\n/**\n * Classify a type code into its structural category and dynamism.\n * Lightweight variant of `lookupTypeCode` that skips label computation.\n * @param code - A single-byte descriptor type code.\n * @returns Type class and whether the type is ABI-dynamic.\n * @throws {CallciumError} If the code is not a recognised type code.\n */\nexport function classifyTypeCode(code: number): TypeClassInfo {\n if (code >= TypeCode.UINT_MIN && code <= TypeCode.UINT_MAX) return ELEMENTARY;\n if (code >= TypeCode.INT_MIN && code <= TypeCode.INT_MAX) return ELEMENTARY;\n if (code === TypeCode.ADDRESS || code === TypeCode.BOOL || code === TypeCode.FUNCTION) return ELEMENTARY;\n if (code >= 0x43 && code <= 0x4f) unknownTypeCode(code);\n if (code >= TypeCode.FIXED_BYTES_MIN && code <= TypeCode.FIXED_BYTES_MAX) return ELEMENTARY;\n if (code === TypeCode.BYTES || code === TypeCode.STRING) return ELEMENTARY_DYN;\n if (code >= 0x72 && code <= 0x7f) unknownTypeCode(code);\n if (code === TypeCode.STATIC_ARRAY) return STATIC_ARR;\n if (code === TypeCode.DYNAMIC_ARRAY) return DYNAMIC_ARR;\n if (code >= 0x82 && code <= 0x8f) unknownTypeCode(code);\n if (code === TypeCode.TUPLE) return TUPLE;\n unknownTypeCode(code);\n}\n\n/** Compute the Solidity type label for a type code. */\nfunction typeCodeLabel(code: number): string {\n if (code >= TypeCode.UINT_MIN && code <= TypeCode.UINT_MAX) return `uint${(code - TypeCode.UINT_MIN + 1) * 8}`;\n if (code >= TypeCode.INT_MIN && code <= TypeCode.INT_MAX) return `int${(code - TypeCode.INT_MIN + 1) * 8}`;\n if (code === TypeCode.ADDRESS) return \"address\";\n if (code === TypeCode.BOOL) return \"bool\";\n if (code === TypeCode.FUNCTION) return \"function\";\n if (code >= TypeCode.FIXED_BYTES_MIN && code <= TypeCode.FIXED_BYTES_MAX)\n return `bytes${code - TypeCode.FIXED_BYTES_MIN + 1}`;\n if (code === TypeCode.BYTES) return \"bytes\";\n if (code === TypeCode.STRING) return \"string\";\n if (code === TypeCode.STATIC_ARRAY) return \"T[k]\";\n if (code === TypeCode.DYNAMIC_ARRAY) return \"T[]\";\n if (code === TypeCode.TUPLE) return \"tuple\";\n return `0x${code.toString(16).padStart(2, \"0\")}`;\n}\n\n/**\n * Map a raw type code byte to its Solidity label, structural category, and dynamism.\n * @param code - A single-byte descriptor type code.\n * @returns Label, type class, and whether the type is ABI-dynamic.\n * @throws {CallciumError} If the code is not a recognised type code.\n */\nexport function lookupTypeCode(code: number): TypeCodeInfo {\n return { label: typeCodeLabel(code), ...classifyTypeCode(code) };\n}\n","import { readU16, readU24 } from \"./bytes\";\nimport { DescriptorFormat as DF, TypeCode } from \"./constants\";\nimport { CallciumError } from \"./errors\";\n\n///////////////////////////////////////////////////////////////////////////\n// Public types\n///////////////////////////////////////////////////////////////////////////\n\n/** Structural type information extracted from a descriptor node. */\nexport type TypeInfo = {\n typeCode: number;\n isDynamic: boolean;\n staticSize: number;\n};\n\n///////////////////////////////////////////////////////////////////////////\n// Internal helpers\n///////////////////////////////////////////////////////////////////////////\n\n/**\n * Return the byte length of the node at `offset`.\n * Elementary nodes occupy exactly one byte; composite nodes encode their\n * length in the lower 12 bits of the 24-bit meta field.\n */\nfunction nodeLength(desc: Uint8Array, offset: number): number {\n const typeCode = desc[offset]!;\n if (typeCode < TypeCode.STATIC_ARRAY) return DF.TYPECODE_SIZE;\n return readU24(desc, offset + 1) & DF.META_NODE_LENGTH_MASK;\n}\n\n/**\n * Return the byte offset of the `fieldIndex`-th field inside a tuple node.\n * Starts at the first field and skips `fieldIndex` nodes using `nodeLength`.\n */\nfunction tupleFieldOffset(desc: Uint8Array, tupleOffset: number, fieldIndex: number): number {\n let cursor = tupleOffset + DF.TUPLE_HEADER_SIZE;\n for (let i = 0; i < fieldIndex; i++) {\n cursor += nodeLength(desc, cursor);\n }\n return cursor;\n}\n\n///////////////////////////////////////////////////////////////////////////\n// Public interface\n///////////////////////////////////////////////////////////////////////////\n\n/** Return paramCount from header byte 1. */\nfunction paramCount(desc: Uint8Array): number {\n return desc[1]!;\n}\n\n/** Return byte offset of the N-th top-level param (0-indexed). */\nfunction paramOffset(desc: Uint8Array, index: number): number {\n const count = desc[1]!;\n if (index >= count) {\n throw new CallciumError(\"INVALID_PATH\", `Param index ${index} out of range (paramCount=${count}).`);\n }\n let cursor = DF.HEADER_SIZE;\n for (let i = 0; i < index; i++) {\n cursor += nodeLength(desc, cursor);\n }\n return cursor;\n}\n\n/**\n * Inspect the type node at a given byte offset.\n * @param desc - Raw descriptor bytes.\n * @param offset - Byte position of the node.\n * @returns typeCode, isDynamic, and staticSize in bytes.\n */\nfunction inspect(desc: Uint8Array, offset: number): TypeInfo {\n const typeCode = desc[offset]!;\n let staticWords: number;\n if (typeCode < TypeCode.STATIC_ARRAY) {\n staticWords = typeCode === TypeCode.BYTES || typeCode === TypeCode.STRING ? 0 : 1;\n } else {\n staticWords = readU24(desc, offset + 1) >> DF.META_STATIC_WORDS_SHIFT;\n }\n const isDynamic = staticWords === 0;\n return { typeCode, isDynamic, staticSize: staticWords * 32 };\n}\n\n/**\n * Resolve the type at a calldata path (array of step indices).\n *\n * The first step selects a top-level param. Each subsequent step descends\n * into the current node: for tuples it selects a field, for arrays it\n * advances to the element descriptor.\n *\n * @param desc - Raw descriptor bytes.\n * @param steps - Path steps, length >= 1.\n * @returns TypeInfo for the node at the resolved path.\n * @throws {CallciumError} On empty steps, out-of-bounds param, or descent into elementary type.\n */\nfunction typeAt(desc: Uint8Array, steps: number[]): TypeInfo {\n if (steps.length === 0) {\n throw new CallciumError(\"INVALID_PATH\", \"Path must have at least one step.\");\n }\n\n const paramIndex = steps[0]!;\n const count = desc[1]!;\n if (paramIndex >= count) {\n throw new CallciumError(\"INVALID_PATH\", `Param index ${paramIndex} out of range (paramCount=${count}).`);\n }\n\n let cursor = paramOffset(desc, paramIndex);\n\n for (let stepIndex = 1; stepIndex < steps.length; stepIndex++) {\n const typeCode = desc[cursor]!;\n const step = steps[stepIndex]!;\n\n if (typeCode === TypeCode.TUPLE) {\n const fields = tupleFieldCount(desc, cursor);\n if (step >= fields) {\n throw new CallciumError(\"INVALID_PATH\", `Tuple field index ${step} out of range (tuple has ${fields} fields).`);\n }\n cursor = tupleFieldOffset(desc, cursor, step);\n } else if (typeCode === TypeCode.STATIC_ARRAY || typeCode === TypeCode.DYNAMIC_ARRAY) {\n cursor = arrayElementOffset(cursor);\n } else {\n throw new CallciumError(\"INVALID_PATH\", `Cannot descend into elementary type at offset ${cursor}.`);\n }\n }\n\n return inspect(desc, cursor);\n}\n\n/**\n * Return tuple field count at a tuple node offset.\n * @param desc - Raw descriptor bytes.\n * @param offset - Byte position of the tuple node.\n */\nfunction tupleFieldCount(desc: Uint8Array, offset: number): number {\n return readU16(desc, offset + 4);\n}\n\n/**\n * Return static array length at a static array node offset.\n * @param desc - Raw descriptor bytes.\n * @param offset - Byte position of the static array node.\n */\nfunction staticArrayLength(desc: Uint8Array, offset: number): number {\n const elemOffset = arrayElementOffset(offset);\n const elemLen = nodeLength(desc, elemOffset);\n const lengthOffset = elemOffset + elemLen;\n return readU16(desc, lengthOffset);\n}\n\n/**\n * Return the byte offset of the array element descriptor.\n * @param offset - Byte position of the array node (static or dynamic).\n */\nfunction arrayElementOffset(offset: number): number {\n return offset + DF.ARRAY_HEADER_SIZE;\n}\n\n/** Inspect and navigate raw descriptor bytes. */\nexport const Descriptor = {\n paramCount,\n paramOffset,\n inspect,\n typeAt,\n tupleFieldOffset,\n tupleFieldCount,\n staticArrayLength,\n nodeLength,\n arrayElementOffset,\n};\n","import { readU24, writeBE16, writeBE24 } from \"./bytes\";\nimport { DescriptorFormat as DF, TypeCode } from \"./constants\";\nimport { CallciumError } from \"./errors\";\n\n///////////////////////////////////////////////////////////////////////////\n// Internal helpers\n///////////////////////////////////////////////////////////////////////////\n\n/**\n * Extract the staticWords count from a descriptor node.\n *\n * For elementary types (typeCode < STATIC_ARRAY), returns 1 unless the type is\n * BYTES or STRING, which are ABI-dynamic and return 0. For composite types,\n * reads the 24-bit meta field at offset 1 and shifts right by\n * META_STATIC_WORDS_SHIFT.\n */\nfunction extractStaticWords(desc: Uint8Array): number {\n const typeCode = desc[0]!;\n if (typeCode < TypeCode.STATIC_ARRAY) {\n return typeCode === TypeCode.BYTES || typeCode === TypeCode.STRING ? 0 : 1;\n }\n return readU24(desc, 1) >> DF.META_STATIC_WORDS_SHIFT;\n}\n\n///////////////////////////////////////////////////////////////////////////\n// Elementary types\n///////////////////////////////////////////////////////////////////////////\n\n/** Build a descriptor node for `address`. */\nexport function address(): Uint8Array {\n return new Uint8Array([TypeCode.ADDRESS]);\n}\n\n/** Build a descriptor node for `bool`. */\nexport function bool(): Uint8Array {\n return new Uint8Array([TypeCode.BOOL]);\n}\n\n/** Build a descriptor node for `function`. */\nexport function function_(): Uint8Array {\n return new Uint8Array([TypeCode.FUNCTION]);\n}\n\n/** Build a descriptor node for `uint256`. */\nexport function uint256(): Uint8Array {\n return new Uint8Array([TypeCode.UINT_MAX]);\n}\n\n/** Build a descriptor node for `int256`. */\nexport function int256(): Uint8Array {\n return new Uint8Array([TypeCode.INT_MAX]);\n}\n\n/**\n * Build a descriptor node for `uintN`.\n * @param bits - Bit width, 8–256 in steps of 8.\n * @throws {CallciumError} If bits is out of range or not a multiple of 8.\n */\nexport function uintN(bits: number): Uint8Array {\n if (bits < 8 || bits > 256 || bits % 8 !== 0) {\n throw new CallciumError(\"INVALID_TYPE_STRING\", `Invalid uintN bits: ${bits}. Must be 8–256 in steps of 8.`);\n }\n return new Uint8Array([TypeCode.UINT_MIN + (bits / 8 - 1)]);\n}\n\n/**\n * Build a descriptor node for `intN`.\n * @param bits - Bit width, 8–256 in steps of 8.\n * @throws {CallciumError} If bits is out of range or not a multiple of 8.\n */\nexport function intN(bits: number): Uint8Array {\n if (bits < 8 || bits > 256 || bits % 8 !== 0) {\n throw new CallciumError(\"INVALID_TYPE_STRING\", `Invalid intN bits: ${bits}. Must be 8–256 in steps of 8.`);\n }\n return new Uint8Array([TypeCode.INT_MIN + (bits / 8 - 1)]);\n}\n\n/** Build a descriptor node for `bytes` (dynamic). */\nexport function bytes(): Uint8Array {\n return new Uint8Array([TypeCode.BYTES]);\n}\n\n/** Build a descriptor node for `string`. */\nexport function string_(): Uint8Array {\n return new Uint8Array([TypeCode.STRING]);\n}\n\n/**\n * Build a descriptor node for `bytesN`.\n * @param n - Byte width, 1–32.\n * @throws {CallciumError} If n is out of range.\n */\nexport function bytesN(n: number): Uint8Array {\n if (n < 1 || n > 32) {\n throw new CallciumError(\"INVALID_TYPE_STRING\", `Invalid bytesN size: ${n}. Must be 1–32.`);\n }\n return new Uint8Array([TypeCode.FIXED_BYTES_MIN + (n - 1)]);\n}\n\n/** Build a descriptor node for `bytes32`. */\nexport function bytes32(): Uint8Array {\n return bytesN(32);\n}\n\n/**\n * Build a descriptor node for an enum type (alias for `uintN`).\n * @param bits - Bit width, default 8.\n */\nexport function enum_(bits: number = 8): Uint8Array {\n return uintN(bits);\n}\n\n///////////////////////////////////////////////////////////////////////////\n// Composite types\n///////////////////////////////////////////////////////////////////////////\n\n/**\n * Build a descriptor node for a dynamic array `T[]` or static array `T[length]`.\n *\n * Dynamic form: `[0x81][meta:3][elemDesc]`\n * Static form: `[0x80][meta:3][elemDesc][length:be16]`\n *\n * @param elemDesc - Descriptor bytes for the element type.\n * @param length - Fixed array length. When omitted, produces a dynamic array.\n * @throws {CallciumError} If length is 0 or exceeds MAX_STATIC_ARRAY_LENGTH.\n */\nexport function array(elemDesc: Uint8Array, length?: number): Uint8Array {\n if (length === undefined) {\n // Dynamic array T[].\n const nodeLength = DF.ARRAY_HEADER_SIZE + elemDesc.length;\n if (nodeLength > DF.MAX_NODE_LENGTH) {\n throw new CallciumError(\n \"DESCRIPTOR_TOO_LARGE\",\n `Dynamic array node length ${nodeLength} exceeds maximum ${DF.MAX_NODE_LENGTH}.`,\n );\n }\n const meta24 = (0 << DF.META_STATIC_WORDS_SHIFT) | nodeLength;\n const buf = new Uint8Array(1 + DF.COMPOSITE_META_SIZE + elemDesc.length);\n buf[0] = TypeCode.DYNAMIC_ARRAY;\n writeBE24(buf, 1, meta24);\n buf.set(elemDesc, 4);\n return buf;\n }\n\n // Static array T[length].\n if (length <= 0 || length > DF.MAX_STATIC_ARRAY_LENGTH) {\n throw new CallciumError(\n \"INVALID_ARRAY_LENGTH\",\n `Static array length ${length} out of range. Must be 1–${DF.MAX_STATIC_ARRAY_LENGTH}.`,\n );\n }\n const nodeLength = DF.ARRAY_HEADER_SIZE + elemDesc.length + DF.ARRAY_LENGTH_SIZE;\n if (nodeLength > DF.MAX_NODE_LENGTH) {\n throw new CallciumError(\n \"DESCRIPTOR_TOO_LARGE\",\n `Static array node length ${nodeLength} exceeds maximum ${DF.MAX_NODE_LENGTH}.`,\n );\n }\n const elemStaticWords = extractStaticWords(elemDesc);\n const staticWords = elemStaticWords === 0 ? 0 : length * elemStaticWords;\n if (staticWords > DF.META_NODE_LENGTH_MASK) {\n throw new CallciumError(\n \"DESCRIPTOR_TOO_LARGE\",\n `Static array static words ${staticWords} exceeds 12-bit maximum ${DF.META_NODE_LENGTH_MASK}.`,\n );\n }\n const meta24 = (staticWords << DF.META_STATIC_WORDS_SHIFT) | nodeLength;\n const buf = new Uint8Array(1 + DF.COMPOSITE_META_SIZE + elemDesc.length + DF.ARRAY_LENGTH_SIZE);\n buf[0] = TypeCode.STATIC_ARRAY;\n writeBE24(buf, 1, meta24);\n buf.set(elemDesc, 4);\n writeBE16(buf, 4 + elemDesc.length, length);\n return buf;\n}\n\n/**\n * Build a descriptor node for a tuple.\n *\n * Format: `[0x90][meta:3][fieldCount:be16][field0][field1]...`\n *\n * @param fieldDescs - Descriptor bytes for each field, in order.\n * @throws {CallciumError} If fieldDescs is empty, exceeds MAX_TUPLE_FIELDS, or nodeLength overflows MAX_NODE_LENGTH.\n */\nexport function tuple(fieldDescs: Uint8Array[]): Uint8Array {\n if (fieldDescs.length === 0 || fieldDescs.length > DF.MAX_TUPLE_FIELDS) {\n throw new CallciumError(\n \"INVALID_TUPLE_FIELD_COUNT\",\n `Tuple field count ${fieldDescs.length} out of range. Must be 1–${DF.MAX_TUPLE_FIELDS}.`,\n );\n }\n const totalFieldBytes = fieldDescs.reduce((sum, f) => sum + f.length, 0);\n const nodeLength = DF.TUPLE_HEADER_SIZE + totalFieldBytes;\n if (nodeLength > DF.MAX_NODE_LENGTH) {\n throw new CallciumError(\n \"INVALID_TUPLE_FIELD_COUNT\",\n `Tuple node length ${nodeLength} exceeds maximum ${DF.MAX_NODE_LENGTH}.`,\n );\n }\n\n let anyDynamic = false;\n let staticWordsSum = 0;\n for (const field of fieldDescs) {\n const staticWords = extractStaticWords(field);\n if (staticWords === 0) {\n anyDynamic = true;\n }\n staticWordsSum += staticWords;\n }\n const staticWords = anyDynamic ? 0 : staticWordsSum;\n if (staticWords > DF.META_NODE_LENGTH_MASK) {\n throw new CallciumError(\n \"DESCRIPTOR_TOO_LARGE\",\n `Tuple static words ${staticWords} exceeds 12-bit maximum ${DF.META_NODE_LENGTH_MASK}.`,\n );\n }\n const meta24 = (staticWords << DF.META_STATIC_WORDS_SHIFT) | nodeLength;\n\n const buf = new Uint8Array(1 + DF.COMPOSITE_META_SIZE + DF.TUPLE_FIELDCOUNT_SIZE + totalFieldBytes);\n buf[0] = TypeCode.TUPLE;\n writeBE24(buf, 1, meta24);\n writeBE16(buf, 4, fieldDescs.length);\n let offset = 6;\n for (const field of fieldDescs) {\n buf.set(field, offset);\n offset += field.length;\n }\n return buf;\n}\n\n/**\n * Build a descriptor node for a struct (alias for `tuple`).\n * @param fieldDescs - Descriptor bytes for each field, in order.\n */\nexport function struct(fieldDescs: Uint8Array[]): Uint8Array {\n return tuple(fieldDescs);\n}\n","import { readU16, readU24 } from \"./bytes\";\nimport { DescriptorFormat as DF, TypeCode, lookupTypeCode, classifyTypeCode } from \"./constants\";\nimport { Descriptor } from \"./descriptor\";\nimport { CallciumError } from \"./errors\";\nimport { address, array, bool, bytes, bytesN, function_, intN, string_, tuple, uint256, uintN } from \"./type-desc\";\n\nimport type { DecodedParam, DescNode, Hex } from \"./types\";\n\n///////////////////////////////////////////////////////////////////////////\n// Splitting helpers\n///////////////////////////////////////////////////////////////////////////\n\n/**\n * Collect the positions of depth-0 commas in input[start..end).\n * Commas inside `()` or `[]` are skipped.\n */\nfunction commaPositions(input: string, start: number, end: number): number[] {\n const positions: number[] = [];\n let depth = 0;\n for (let i = start; i < end; i++) {\n const char = input[i];\n if (char === \"(\" || char === \"[\") {\n depth++;\n } else if (char === \")\" || char === \"]\") {\n depth--;\n } else if (char === \",\" && depth === 0) {\n positions.push(i);\n }\n }\n return positions;\n}\n\n///////////////////////////////////////////////////////////////////////////\n// Integer parser\n///////////////////////////////////////////////////////////////////////////\n\n/**\n * Parse a decimal integer from input[start..end).\n * Returns -1 if the substring is empty or contains non-digit characters.\n */\nfunction parseUint(input: string, start: number, end: number): number {\n if (start >= end) return -1;\n let value = 0;\n for (let i = start; i < end; i++) {\n const code = input.charCodeAt(i);\n if (code < 48 || code > 57) return -1;\n value = value * 10 + (code - 48);\n }\n return value;\n}\n\n///////////////////////////////////////////////////////////////////////////\n// Tuple parser\n///////////////////////////////////////////////////////////////////////////\n\n/**\n * Parse a tuple literal `(field0,field1,...)` where the opening `(` is at\n * `start` and the substring to parse ends before `end`.\n */\nfunction parseTuple(input: string, start: number, end: number): Uint8Array {\n // Expect opening paren at start.\n if (input[start] !== \"(\") {\n throw new CallciumError(\"INVALID_TYPE_STRING\", `Expected '(' at position ${start}`);\n }\n // Find matching closing paren.\n let depth = 0;\n let closePos = -1;\n for (let i = start; i < end; i++) {\n if (input[i] === \"(\") depth++;\n else if (input[i] === \")\") {\n depth--;\n if (depth === 0) {\n closePos = i;\n break;\n }\n }\n }\n if (closePos === -1) {\n throw new CallciumError(\"INVALID_TYPE_STRING\", `Unmatched '(' at position ${start}`);\n }\n\n const innerStart = start + 1;\n const innerEnd = closePos;\n const commas = commaPositions(input, innerStart, innerEnd);\n\n const segments: Array<[number, number]> = [];\n let segStart = innerStart;\n for (const comma of commas) {\n segments.push([segStart, comma]);\n segStart = comma + 1;\n }\n segments.push([segStart, innerEnd]);\n\n // An empty tuple `()` is not valid.\n if (segments.length === 1 && segments[0]![0] === segments[0]![1]) {\n throw new CallciumError(\"INVALID_TYPE_STRING\", \"Empty tuple is not allowed\");\n }\n\n const fieldDescs = segments.map(([fieldStart, fieldEnd]) => parseType(input, fieldStart, fieldEnd));\n return tuple(fieldDescs);\n}\n\n///////////////////////////////////////////////////////////////////////////\n// Base type parser\n///////////////////////////////////////////////////////////////////////////\n\n/** Parse the base type (no array suffixes) from input[start..end). */\nfunction parseBaseType(input: string, start: number, end: number): Uint8Array {\n const segment = input.slice(start, end);\n\n if (segment === \"address\") return address();\n if (segment === \"bool\") return bool();\n if (segment === \"function\") return function_();\n if (segment === \"bytes\") return bytes();\n if (segment === \"string\") return string_();\n if (segment === \"uint256\") return uint256();\n if (segment === \"int256\") return intN(256);\n\n if (segment.startsWith(\"(\")) return parseTuple(input, start, end);\n\n // uintN\n if (segment.startsWith(\"uint\")) {\n const bits = parseUint(input, start + 4, end);\n if (bits === -1) {\n throw new CallciumError(\"UNKNOWN_TYPE\", `Unrecognised type '${segment}'`);\n }\n return uintN(bits);\n }\n\n // intN\n if (segment.startsWith(\"int\")) {\n const bits = parseUint(input, start + 3, end);\n if (bits === -1) {\n throw new CallciumError(\"UNKNOWN_TYPE\", `Unrecognised type '${segment}'`);\n }\n return intN(bits);\n }\n\n // bytesN\n if (segment.startsWith(\"bytes\")) {\n const n = parseUint(input, start + 5, end);\n if (n === -1) {\n throw new CallciumError(\"UNKNOWN_TYPE\", `Unrecognised type '${segment}'`);\n }\n return bytesN(n);\n }\n\n throw new CallciumError(\"UNKNOWN_TYPE\", `Unrecognised type '${segment}'`);\n}\n\n///////////////////////////////////////////////////////////////////////////\n// Array suffix collector\n///////////////////////////////////////////////////////////////////////////\n\n/**\n * Parse a type segment from input[start..end).\n *\n * Scans backward from end to collect all `[...]` suffixes, identifies the\n * base type extent, parses the base, then applies suffixes left-to-right.\n */\nfunction parseType(input: string, start: number, end: number): Uint8Array {\n if (start >= end) {\n throw new CallciumError(\"INVALID_TYPE_STRING\", \"Empty type segment\");\n }\n\n // Collect array suffixes by scanning backward.\n // Each suffix is either `[]` (dynamic) or `[N]` (static with length N).\n const suffixes: Array<number | undefined> = [];\n let baseEnd = end;\n\n while (baseEnd > start && input[baseEnd - 1] === \"]\") {\n // Find the matching `[`.\n const closePos = baseEnd - 1;\n let openPos = closePos - 1;\n // Walk back past digits (for static arrays).\n while (openPos > start && input[openPos] !== \"[\") {\n openPos--;\n }\n if (input[openPos] !== \"[\") {\n throw new CallciumError(\"INVALID_TYPE_STRING\", `Unmatched ']' at position ${closePos}`);\n }\n const innerStart = openPos + 1;\n const innerEnd = closePos;\n if (innerStart === innerEnd) {\n // Dynamic array `[]`.\n suffixes.unshift(undefined);\n } else {\n const length = parseUint(input, innerStart, innerEnd);\n if (length === -1) {\n throw new CallciumError(\"INVALID_TYPE_STRING\", `Invalid array length at position ${innerStart}`);\n }\n suffixes.unshift(length);\n }\n baseEnd = openPos;\n }\n\n let desc = parseBaseType(input, start, baseEnd);\n\n // Apply suffixes left-to-right: the leftmost suffix is the outermost array.\n for (const length of suffixes) {\n desc = array(desc, length);\n }\n\n return desc;\n}\n\n///////////////////////////////////////////////////////////////////////////\n// Public interface\n///////////////////////////////////////////////////////////////////////////\n\n/**\n * Encode a comma-separated list of ABI type strings into a binary descriptor.\n *\n * @param typesCsv - Comma-separated ABI type strings, e.g. `\"address,uint256,(bool,bytes32)[],string\"`.\n * @returns Binary descriptor bytes starting with the version+paramCount header.\n * @throws {CallciumError} With code `INVALID_TYPE_STRING` for malformed input.\n * @throws {CallciumError} With code `UNKNOWN_TYPE` for unrecognised type names.\n */\nfunction fromTypes(typesCsv: string): Uint8Array {\n if (typesCsv === \"\") {\n return new Uint8Array([DF.VERSION, 0x00]);\n }\n\n const commas = commaPositions(typesCsv, 0, typesCsv.length);\n\n const segments: Array<[number, number]> = [];\n let segStart = 0;\n for (const comma of commas) {\n segments.push([segStart, comma]);\n segStart = comma + 1;\n }\n segments.push([segStart, typesCsv.length]);\n\n const paramDescs = segments.map(([start, end]) => parseType(typesCsv, start, end));\n if (paramDescs.length > DF.MAX_PARAMS) {\n throw new CallciumError(\n \"DESCRIPTOR_TOO_LARGE\",\n `Parameter count ${paramDescs.length} exceeds maximum ${DF.MAX_PARAMS}.`,\n );\n }\n const totalBytes = paramDescs.reduce((sum, d) => sum + d.length, 0);\n const result = new Uint8Array(DF.HEADER_SIZE + totalBytes);\n result[0] = DF.VERSION;\n result[1] = paramDescs.length;\n let offset = DF.HEADER_SIZE;\n for (const desc of paramDescs) {\n result.set(desc, offset);\n offset += desc.length;\n }\n return result;\n}\n\n///////////////////////////////////////////////////////////////////////////\n// Inverse: descriptor bytes → type string\n///////////////////////////////////////////////////////////////////////////\n\n/** Reconstruct a Solidity type string from a descriptor node at the given offset. */\nfunction nodeToTypeString(desc: Uint8Array, offset: number): string {\n const typeCode = desc[offset]!;\n\n if (typeCode === TypeCode.TUPLE) {\n const fieldCount = Descriptor.tupleFieldCount(desc, offset);\n const fieldTypes: string[] = [];\n let fieldOffset = offset + DF.TUPLE_HEADER_SIZE;\n for (let i = 0; i < fieldCount; i++) {\n fieldTypes.push(nodeToTypeString(desc, fieldOffset));\n fieldOffset += Descriptor.nodeLength(desc, fieldOffset);\n }\n return `(${fieldTypes.join(\",\")})`;\n }\n\n if (typeCode === TypeCode.STATIC_ARRAY) {\n const length = Descriptor.staticArrayLength(desc, offset);\n const elemType = nodeToTypeString(desc, Descriptor.arrayElementOffset(offset));\n return `${elemType}[${length}]`;\n }\n\n if (typeCode === TypeCode.DYNAMIC_ARRAY) {\n const elemType = nodeToTypeString(desc, Descriptor.arrayElementOffset(offset));\n return `${elemType}[]`;\n }\n\n return lookupTypeCode(typeCode).label;\n}\n\n/**\n * Reconstruct a comma-separated list of ABI type strings from a binary descriptor.\n *\n * Inverse of `fromTypes`: `toTypes(fromTypes(s))` returns `s` for any valid input.\n *\n * @param desc - Binary descriptor bytes (with version+paramCount header).\n * @returns Comma-separated ABI type strings, e.g. `\"address,uint256,(bool,bytes32)[]\"`.\n * @throws {CallciumError} If the descriptor is malformed.\n */\nfunction toTypes(desc: Uint8Array): string {\n const count = Descriptor.paramCount(desc);\n const types: string[] = [];\n let offset = DF.HEADER_SIZE;\n for (let i = 0; i < count; i++) {\n types.push(nodeToTypeString(desc, offset));\n offset += Descriptor.nodeLength(desc, offset);\n }\n return types.join(\",\");\n}\n\n///////////////////////////////////////////////////////////////////////////\n// Descriptor binary decoder\n///////////////////////////////////////////////////////////////////////////\n\ntype ParseResult = { node: DescNode; next: number };\n\n/** Recursively parse a single descriptor node starting at offset. */\nfunction parseNode(data: Uint8Array, offset: number): ParseResult {\n if (offset >= data.length) {\n throw new CallciumError(\"UNEXPECTED_END\", \"Unexpected end of descriptor\", offset);\n }\n\n const code = data[offset]!;\n const info = classifyTypeCode(code);\n const metaOffset = offset + DF.TYPECODE_SIZE;\n\n if (info.typeClass === \"elementary\") {\n const node: DescNode = {\n type: \"elementary\",\n typeCode: code,\n isDynamic: info.isDynamic,\n staticSize: info.isDynamic ? 0 : 32,\n span: { start: offset, end: metaOffset },\n };\n return { node, next: metaOffset };\n }\n\n const metaEnd = metaOffset + DF.COMPOSITE_META_SIZE;\n if (metaEnd > data.length) {\n throw new CallciumError(\"UNEXPECTED_END\", \"Incomplete composite metadata\", offset);\n }\n\n const meta = readU24(data, metaOffset);\n const staticWords = meta >> DF.META_STATIC_WORDS_SHIFT;\n const nodeLength = meta & DF.META_NODE_LENGTH_MASK;\n\n const minHeader = info.typeClass === \"tuple\" ? DF.TUPLE_HEADER_SIZE : DF.ARRAY_HEADER_SIZE;\n if (nodeLength < minHeader) {\n throw new CallciumError(\n \"MALFORMED_HEADER\",\n `Composite node length ${nodeLength} is smaller than minimum header ${minHeader}`,\n offset,\n );\n }\n if (offset + nodeLength > data.length) {\n throw new CallciumError(\"NODE_OVERFLOW\", \"Composite node extends beyond descriptor\", offset);\n }\n\n const isDynamic = staticWords === 0;\n const staticSize = isDynamic ? 0 : staticWords * 32;\n const nodeEnd = offset + nodeLength;\n\n if (info.typeClass === \"tuple\") {\n const fieldCountOffset = metaEnd;\n if (fieldCountOffset + 2 > data.length) {\n throw new CallciumError(\"UNEXPECTED_END\", \"Incomplete tuple header\", offset);\n }\n const fieldCount = readU16(data, fieldCountOffset);\n if (fieldCount === 0) {\n throw new CallciumError(\"INVALID_TUPLE_FIELD_COUNT\", \"Tuple must have at least one field\", offset);\n }\n if (fieldCount > DF.MAX_TUPLE_FIELDS) {\n throw new CallciumError(\n \"INVALID_TUPLE_FIELD_COUNT\",\n `Tuple field count ${fieldCount} exceeds maximum ${DF.MAX_TUPLE_FIELDS}`,\n offset,\n );\n }\n\n const fields: DescNode[] = [];\n let cursor = offset + DF.TUPLE_HEADER_SIZE;\n for (let i = 0; i < fieldCount; i++) {\n const result = parseNode(data, cursor);\n fields.push(result.node);\n cursor = result.next;\n }\n\n const node: DescNode = {\n type: \"tuple\",\n typeCode: code,\n isDynamic,\n staticSize,\n fields,\n span: { start: offset, end: nodeEnd },\n };\n return { node, next: nodeEnd };\n }\n\n if (info.typeClass === \"staticArray\") {\n const elemResult = parseNode(data, Descriptor.arrayElementOffset(offset));\n const lengthOffset = elemResult.next;\n if (lengthOffset + DF.ARRAY_LENGTH_SIZE > data.length) {\n throw new CallciumError(\"UNEXPECTED_END\", \"Missing static array length suffix\", offset);\n }\n const length = readU16(data, lengthOffset);\n if (length === 0) {\n throw new CallciumError(\"INVALID_ARRAY_LENGTH\", \"Static array length must be greater than zero\", offset);\n }\n if (length > DF.MAX_STATIC_ARRAY_LENGTH) {\n throw new CallciumError(\n \"INVALID_ARRAY_LENGTH\",\n `Static array length ${length} exceeds maximum ${DF.MAX_STATIC_ARRAY_LENGTH}`,\n offset,\n );\n }\n\n const node: DescNode = {\n type: \"staticArray\",\n typeCode: code,\n isDynamic,\n staticSize,\n element: elemResult.node,\n length,\n span: { start: offset, end: nodeEnd },\n };\n return { node, next: nodeEnd };\n }\n\n const elemResult = parseNode(data, Descriptor.arrayElementOffset(offset));\n const node: DescNode = {\n type: \"dynamicArray\",\n typeCode: code,\n isDynamic: true,\n staticSize: 0,\n element: elemResult.node,\n span: { start: offset, end: nodeEnd },\n };\n return { node, next: nodeEnd };\n}\n\n/** Convert a zero-based param index to a BE16 hex path step. */\nfunction indexToPath(index: number): Hex {\n return `0x${index.toString(16).padStart(4, \"0\")}`;\n}\n\ntype DecodedDescriptor = {\n version: number;\n params: DecodedParam[];\n};\n\n/** Decode a binary descriptor blob, returning the structural representation and AST. */\nexport function decodeDescriptor(data: Uint8Array): {\n descriptor: DecodedDescriptor;\n tree: DescNode[];\n} {\n if (data.length < 1) {\n throw new CallciumError(\"MALFORMED_HEADER\", \"Descriptor is empty\");\n }\n\n const version = data[0]!;\n if (version !== DF.VERSION) {\n throw new CallciumError(\"UNSUPPORTED_VERSION\", `Version ${version} is not supported (expected ${DF.VERSION})`);\n }\n\n if (data.length < DF.HEADER_SIZE) {\n throw new CallciumError(\"MALFORMED_HEADER\", \"Descriptor too short for header\");\n }\n\n const declaredCount = data[1]!;\n const params: DecodedParam[] = [];\n const tree: DescNode[] = [];\n let cursor: number = DF.HEADER_SIZE;\n\n while (cursor < data.length) {\n if (params.length >= DF.MAX_PARAMS) {\n throw new CallciumError(\n \"PARAM_COUNT_MISMATCH\",\n `Descriptor exceeds the maximum of ${DF.MAX_PARAMS} top-level params`,\n );\n }\n\n const { node, next } = parseNode(data, cursor);\n tree.push(node);\n\n params.push({\n index: params.length,\n typeCode: node.typeCode,\n isDynamic: node.isDynamic,\n staticSize: node.staticSize,\n path: indexToPath(params.length),\n span: { start: cursor, end: next },\n });\n\n cursor = next;\n }\n\n if (params.length !== declaredCount) {\n throw new CallciumError(\n \"PARAM_COUNT_MISMATCH\",\n `Header declares ${declaredCount} params but ${params.length} were parsed`,\n );\n }\n\n return {\n descriptor: { version, params },\n tree,\n };\n}\n\n/** Encode and decode descriptors. */\nexport const DescriptorCoder = { fromTypes, toTypes };\n","import { keccak_256 } from \"@noble/hashes/sha3\";\n\nimport { bytesToHex, hexToBytes, toHex, readU16, readU32, writeBE16 } from \"./bytes\";\nimport { DescriptorFormat as DF, PolicyFormat as PF, Scope, Limits, Op, isValidOperatorData } from \"./constants\";\nimport { decodeDescriptor } from \"./descriptor-coder\";\nimport { CallciumError } from \"./errors\";\n\nimport type {\n Constraint,\n DescNode,\n Field,\n Hex,\n DecodedGroup,\n DecodedParam,\n DecodedPolicy,\n DecodedRule,\n PolicyData,\n} from \"./types\";\n\n///////////////////////////////////////////////////////////////////////////\n// Path helper\n///////////////////////////////////////////////////////////////////////////\n\n/**\n * Parse a BE16-encoded hex path into an array of step values.\n * @param path - 0x-prefixed hex string containing BE16-encoded path steps.\n * @returns Array of numeric step values.\n */\nexport function parsePathSteps(path: Hex): number[] {\n const body = path.slice(2);\n const steps: number[] = [];\n for (let i = 0; i < body.length; i += 4) {\n steps.push(parseInt(body.slice(i, i + 4), 16));\n }\n return steps;\n}\n\n///////////////////////////////////////////////////////////////////////////\n// Policy field helper\n///////////////////////////////////////////////////////////////////////////\n\n/** Wrap a value with its byte span for positional tracking. */\nfunction field<T>(value: T, start: number, end: number): Field<T> {\n return { value, span: { start, end } };\n}\n\n///////////////////////////////////////////////////////////////////////////\n// Policy decoder\n///////////////////////////////////////////////////////////////////////////\n\n/** Decode a policy blob, returning the structural representation and descriptor AST. */\nexport function decodePolicy(blob: Hex): {\n policy: DecodedPolicy;\n tree: DescNode[];\n} {\n const data = hexToBytes(blob);\n if (data.length < PF.DESC_OFFSET + 1) {\n throw new CallciumError(\"MALFORMED_HEADER\", \"Policy blob is too short\");\n }\n\n const headerByte = data[0]!;\n const version = headerByte & PF.VERSION_MASK;\n if (version !== PF.VERSION) {\n throw new CallciumError(\"UNSUPPORTED_VERSION\", `Version ${version} is not supported (expected ${PF.VERSION})`);\n }\n if ((headerByte & PF.RESERVED_MASK) !== 0) {\n throw new CallciumError(\"MALFORMED_HEADER\", \"Reserved header bits must be zero\");\n }\n\n const isSelectorless = (headerByte & PF.FLAG_NO_SELECTOR) !== 0;\n\n const selectorStart = PF.SELECTOR_OFFSET;\n const selectorEnd = selectorStart + PF.SELECTOR_SIZE;\n const selectorHex = toHex(data, selectorStart, selectorEnd);\n\n if (isSelectorless && selectorHex !== \"0x00000000\") {\n throw new CallciumError(\"MALFORMED_HEADER\", \"Selectorless policy must have a zeroed selector slot\");\n }\n\n const descLengthStart = PF.DESC_LENGTH_OFFSET;\n const descLengthValue = readU16(data, descLengthStart);\n if (descLengthValue < 2) {\n throw new CallciumError(\"MALFORMED_HEADER\", \"Descriptor length must be at least 2\");\n }\n\n const descStart = PF.DESC_OFFSET;\n const descEnd = descStart + descLengthValue;\n const groupCountOffset = descEnd;\n\n if (data.length < groupCountOffset + PF.GROUP_COUNT_SIZE) {\n throw new CallciumError(\"MALFORMED_HEADER\", \"Policy blob is too short for descriptor and group count\");\n }\n\n // Decode the embedded descriptor, offsetting spans to be relative to the policy blob.\n const descSlice = data.subarray(descStart, descEnd);\n const { descriptor: desc, tree } = decodeDescriptor(descSlice);\n const params: DecodedParam[] = desc.params.map((param) => ({\n ...param,\n span: {\n start: descStart + param.span.start,\n end: descStart + param.span.end,\n },\n }));\n const descriptorRaw = toHex(data, descStart, descEnd);\n\n const groupCountStart = groupCountOffset;\n const groupCountEnd = groupCountStart + PF.GROUP_COUNT_SIZE;\n const groupCountValue = data[groupCountOffset]!;\n if (groupCountValue === 0) {\n throw new CallciumError(\"EMPTY_POLICY\", \"Policy must contain at least one group\");\n }\n\n let offset = groupCountEnd;\n const groups: DecodedGroup[] = [];\n\n for (let groupIndex = 0; groupIndex < groupCountValue; groupIndex++) {\n if (offset + PF.GROUP_HEADER_SIZE > data.length) {\n throw new CallciumError(\"UNEXPECTED_END\", \"Unexpected end while reading group header\", offset);\n }\n\n const ruleCountStart = offset;\n const ruleCountValue = readU16(data, ruleCountStart);\n const groupSizeStart = offset + PF.GROUP_RULECOUNT_SIZE;\n const groupSizeValue = readU32(data, groupSizeStart);\n const groupBodyStart = offset + PF.GROUP_HEADER_SIZE;\n const groupEnd = groupBodyStart + groupSizeValue;\n\n if (ruleCountValue === 0) {\n throw new CallciumError(\"EMPTY_GROUP\", \"Group must contain at least one rule\", offset);\n }\n if (groupSizeValue < ruleCountValue * PF.RULE_MIN_SIZE) {\n throw new CallciumError(\"GROUP_SIZE_MISMATCH\", \"Declared group size is too small for its rule count\", offset);\n }\n if (groupEnd > data.length) {\n throw new CallciumError(\"GROUP_OVERFLOW\", \"Group extends beyond policy blob\", offset);\n }\n\n const rules: DecodedRule[] = [];\n let ruleOffset = groupBodyStart;\n\n for (let ruleIndex = 0; ruleIndex < ruleCountValue; ruleIndex++) {\n if (ruleOffset + PF.RULE_SIZE_SIZE > data.length) {\n throw new CallciumError(\"UNEXPECTED_END\", \"Unexpected end while reading rule size\", ruleOffset);\n }\n\n const ruleSizeValue = readU16(data, ruleOffset);\n if (ruleSizeValue < PF.RULE_MIN_SIZE) {\n throw new CallciumError(\n \"RULE_SIZE_MISMATCH\",\n `Rule size ${ruleSizeValue} is below minimum ${PF.RULE_MIN_SIZE}`,\n ruleOffset,\n );\n }\n if (ruleOffset + ruleSizeValue > groupEnd) {\n throw new CallciumError(\"RULE_OVERFLOW\", \"Rule extends beyond group boundary\", ruleOffset);\n }\n\n const scopeOffset = ruleOffset + PF.RULE_SCOPE_OFFSET;\n const scopeValue = data[scopeOffset]!;\n if (scopeValue !== Scope.CONTEXT && scopeValue !== Scope.CALLDATA) {\n throw new CallciumError(\"INVALID_SCOPE\", `Unknown scope value ${scopeValue}`, ruleOffset);\n }\n\n const depthOffset = ruleOffset + PF.RULE_DEPTH_OFFSET;\n const depthValue = data[depthOffset]!;\n if (depthValue === 0) {\n throw new CallciumError(\"EMPTY_PATH\", \"Rule path must have at least one step\", ruleOffset);\n }\n if (scopeValue === Scope.CONTEXT && depthValue !== 1) {\n throw new CallciumError(\n \"INVALID_CONTEXT_PATH\",\n \"Context-scope rules must have exactly one path step\",\n ruleOffset,\n );\n }\n\n const pathStart = ruleOffset + PF.RULE_PATH_OFFSET;\n const pathLength = depthValue * PF.PATH_STEP_SIZE;\n const pathHex = toHex(data, pathStart, pathStart + pathLength);\n\n const opCodeOffset = pathStart + pathLength;\n const opCodeValue = data[opCodeOffset]!;\n\n const dataLengthOffset = opCodeOffset + PF.RULE_OPCODE_SIZE;\n const dataLengthValue = readU16(data, dataLengthOffset);\n\n const dataStart = dataLengthOffset + PF.RULE_DATALENGTH_SIZE;\n\n // Validate ruleSize matches the computed layout.\n const expectedRuleSize = PF.RULE_FIXED_OVERHEAD + pathLength + dataLengthValue;\n if (ruleSizeValue !== expectedRuleSize) {\n throw new CallciumError(\n \"RULE_SIZE_MISMATCH\",\n `Declared rule size ${ruleSizeValue} does not match computed size ${expectedRuleSize}`,\n ruleOffset,\n );\n }\n\n // Validate operator and data length.\n const opBase = opCodeValue & ~Op.NOT;\n if (opBase === 0 || !isValidOperatorData(opBase, dataLengthValue)) {\n throw new CallciumError(\"INVALID_OPERATOR\", \"Unrecognized or malformed operator\", ruleOffset);\n }\n\n rules.push({\n ruleSize: field(ruleSizeValue, ruleOffset, ruleOffset + PF.RULE_SIZE_SIZE),\n scope: field(scopeValue, scopeOffset, scopeOffset + 1),\n pathDepth: field(depthValue, depthOffset, depthOffset + 1),\n path: field(pathHex, pathStart, pathStart + pathLength),\n opCode: field(opCodeValue, opCodeOffset, opCodeOffset + PF.RULE_OPCODE_SIZE),\n dataLength: field(dataLengthValue, dataLengthOffset, dataLengthOffset + PF.RULE_DATALENGTH_SIZE),\n data: field(toHex(data, dataStart, dataStart + dataLengthValue), dataStart, dataStart + dataLengthValue),\n span: { start: ruleOffset, end: ruleOffset + ruleSizeValue },\n });\n\n ruleOffset += ruleSizeValue;\n }\n\n if (ruleOffset !== groupEnd) {\n throw new CallciumError(\"GROUP_SIZE_MISMATCH\", \"Rules do not exactly fill the declared group size\", offset);\n }\n\n groups.push({\n ruleCount: field(ruleCountValue, ruleCountStart, ruleCountStart + PF.GROUP_RULECOUNT_SIZE),\n groupSize: field(groupSizeValue, groupSizeStart, groupSizeStart + PF.GROUP_SIZE_SIZE),\n rules,\n span: { start: offset, end: groupEnd },\n });\n offset = groupEnd;\n }\n\n // Reject trailing bytes after the last group.\n if (offset !== data.length) {\n throw new CallciumError(\"TRAILING_BYTES\", \"Trailing bytes after last group\", offset);\n }\n\n const policy: DecodedPolicy = {\n header: field(headerByte, 0, PF.HEADER_SIZE),\n selector: field(selectorHex, selectorStart, selectorEnd),\n descLength: field(descLengthValue, descLengthStart, descLengthStart + PF.DESC_LENGTH_SIZE),\n descriptor: {\n raw: descriptorRaw,\n header: field({ version: desc.version, paramCount: desc.params.length }, descStart, descStart + DF.HEADER_SIZE),\n params,\n span: { start: descStart, end: descEnd },\n },\n groupCount: field(groupCountValue, groupCountStart, groupCountEnd),\n groups,\n span: { start: 0, end: data.length },\n version,\n isSelectorless,\n };\n\n return { policy, tree };\n}\n\n///////////////////////////////////////////////////////////////////////////\n// Encoder internals\n///////////////////////////////////////////////////////////////////////////\n\ntype Rule = { scope: number; path: Uint8Array; operator: Uint8Array };\n\n/** Flatten a Constraint into one Rule per operator. */\nfunction flattenConstraint(constraint: Constraint): Rule[] {\n const path = hexToBytes(constraint.path);\n return constraint.operators.map((op) => ({\n scope: constraint.scope,\n path,\n operator: hexToBytes(op),\n }));\n}\n\n/** Compare two byte arrays lexicographically. */\nfunction compareBytes(a: Uint8Array, b: Uint8Array): number {\n const length = Math.min(a.length, b.length);\n for (let i = 0; i < length; i++) {\n if (a[i]! !== b[i]!) return a[i]! - b[i]!;\n }\n return a.length - b.length;\n}\n\n/** Sort rules by (scope, pathDepth, pathBytes, operatorBytes). */\nfunction sortRules(rules: Rule[]): void {\n rules.sort((a, b) => {\n if (a.scope !== b.scope) return a.scope - b.scope;\n const depthA = a.path.length / 2;\n const depthB = b.path.length / 2;\n if (depthA !== depthB) return depthA - depthB;\n const pathCmp = compareBytes(a.path, b.path);\n if (pathCmp !== 0) return pathCmp;\n return compareBytes(a.operator, b.operator);\n });\n}\n\n/** Serialize a single rule to its wire format bytes. */\nfunction encodeRule(rule: Rule): Uint8Array {\n if (rule.path.length === 0) {\n throw new CallciumError(\"EMPTY_PATH\", \"Rule path must have at least one step.\");\n }\n if ((rule.path.length & 1) !== 0) {\n throw new CallciumError(\"INVALID_PATH\", \"Path byte length must be even.\");\n }\n if (rule.operator.length < 1) {\n throw new CallciumError(\"INVALID_OPERATOR\", \"Operator must have at least one byte (opcode).\");\n }\n const depth = rule.path.length / 2;\n if (depth > Limits.MAX_PATH_DEPTH) {\n throw new CallciumError(\"INVALID_PATH\", `Path depth ${depth} exceeds maximum ${Limits.MAX_PATH_DEPTH}.`);\n }\n if (rule.scope === Scope.CONTEXT && depth !== 1) {\n throw new CallciumError(\"INVALID_CONTEXT_PATH\", \"Context-scope rules must have exactly one path step.\");\n }\n const opCode = rule.operator[0]!;\n const data = rule.operator.subarray(1);\n const ruleSize = PF.RULE_FIXED_OVERHEAD + rule.path.length + data.length;\n if (ruleSize > 0xffff) {\n throw new CallciumError(\"RULE_SIZE_OVERFLOW\", `Rule size ${ruleSize} exceeds maximum 65535`);\n }\n\n const buf = new Uint8Array(ruleSize);\n writeBE16(buf, 0, ruleSize);\n buf[2] = rule.scope;\n buf[3] = depth;\n buf.set(rule.path, 4);\n const opOffset = 4 + rule.path.length;\n buf[opOffset] = opCode;\n writeBE16(buf, opOffset + 1, data.length);\n buf.set(data, opOffset + 3);\n\n return buf;\n}\n\n/** Serialize all rules in a group to a single byte array. */\nfunction encodeGroupRules(rules: Rule[]): Uint8Array {\n const parts = rules.map(encodeRule);\n const totalSize = parts.reduce((sum, p) => sum + p.length, 0);\n const buf = new Uint8Array(totalSize);\n let offset = 0;\n for (const part of parts) {\n buf.set(part, offset);\n offset += part.length;\n }\n return buf;\n}\n\n///////////////////////////////////////////////////////////////////////////\n// PolicyCoder\n///////////////////////////////////////////////////////////////////////////\n\n/** Build a single operator hex string from a decoded rule's opCode and data. */\nfunction buildOperatorHex(rule: DecodedRule): Hex {\n const opCodeHex = rule.opCode.value.toString(16).padStart(2, \"0\");\n const dataBody = rule.data.value.slice(2);\n return `0x${opCodeHex}${dataBody}`;\n}\n\n/**\n * Encode a PolicyData structure into the canonical binary format.\n * @param data - The policy data to encode.\n * @returns The encoded policy as a 0x-prefixed hex string.\n */\nfunction encode(data: PolicyData): Hex {\n // Flatten constraints into rules and sort within each group.\n const sortedGroups: Rule[][] = data.groups.map((group) => {\n const rules = group.flatMap(flattenConstraint);\n sortRules(rules);\n return rules;\n });\n\n if (sortedGroups.length === 0) {\n throw new CallciumError(\"EMPTY_POLICY\", \"Policy must contain at least one group\");\n }\n if (sortedGroups.length > 0xff) {\n throw new CallciumError(\"GROUP_COUNT_OVERFLOW\", `Group count ${sortedGroups.length} exceeds maximum 255`);\n }\n\n // Sort groups by keccak256 hash of their serialized rule bytes.\n const groupsWithHash: { wireBytes: Uint8Array; hash: Uint8Array; ruleCount: number }[] = sortedGroups.map(\n (rules, groupIndex) => {\n if (rules.length === 0) {\n throw new CallciumError(\"EMPTY_GROUP\", `Group ${groupIndex} is empty`);\n }\n if (rules.length > 0xffff) {\n throw new CallciumError(\n \"RULE_COUNT_OVERFLOW\",\n `Group ${groupIndex} rule count ${rules.length} exceeds maximum 65535`,\n );\n }\n const wireBytes = encodeGroupRules(rules);\n return { wireBytes, hash: keccak_256(wireBytes), ruleCount: rules.length };\n },\n );\n groupsWithHash.sort((a, b) => compareBytes(a.hash, b.hash));\n\n // Build the binary output.\n const descBytes = hexToBytes(data.descriptor);\n if (descBytes.length > 0xffff) {\n throw new CallciumError(\"DESC_LENGTH_OVERFLOW\", `Descriptor length ${descBytes.length} exceeds maximum 65535`);\n }\n const selectorBytes = data.isSelectorless ? new Uint8Array(4) : hexToBytes(data.selector);\n\n const headerByte = PF.VERSION | (data.isSelectorless ? PF.FLAG_NO_SELECTOR : 0);\n\n // Pre-compute total size.\n let totalSize = PF.HEADER_SIZE + PF.SELECTOR_SIZE + PF.DESC_LENGTH_SIZE + descBytes.length + PF.GROUP_COUNT_SIZE;\n for (const g of groupsWithHash) {\n totalSize += PF.GROUP_HEADER_SIZE + g.wireBytes.length;\n }\n\n const out = new Uint8Array(totalSize);\n let offset = 0;\n\n // Header.\n out[offset++] = headerByte;\n\n // Selector.\n out.set(selectorBytes, offset);\n offset += PF.SELECTOR_SIZE;\n\n // Descriptor length (BE16).\n writeBE16(out, offset, descBytes.length);\n offset += PF.DESC_LENGTH_SIZE;\n\n // Descriptor.\n out.set(descBytes, offset);\n offset += descBytes.length;\n\n // Group count.\n out[offset++] = groupsWithHash.length;\n\n // Groups.\n for (const g of groupsWithHash) {\n // Rule count (BE16).\n writeBE16(out, offset, g.ruleCount);\n offset += PF.GROUP_RULECOUNT_SIZE;\n\n // Group size (BE32).\n out[offset++] = (g.wireBytes.length >>> 24) & 0xff;\n out[offset++] = (g.wireBytes.length >>> 16) & 0xff;\n out[offset++] = (g.wireBytes.length >>> 8) & 0xff;\n out[offset++] = g.wireBytes.length & 0xff;\n\n // Rule bytes.\n out.set(g.wireBytes, offset);\n offset += g.wireBytes.length;\n }\n\n return bytesToHex(out);\n}\n\n/**\n * Decode a binary policy blob into a PolicyData structure.\n * @param blob - Binary policy as 0x-prefixed hex string.\n * @returns The decoded policy data with constraints grouped by scope and path.\n * @throws {CallciumError} If the blob is structurally malformed.\n */\nfunction decode(blob: Hex): PolicyData {\n const { policy } = decodePolicy(blob);\n\n const groups: Constraint[][] = policy.groups.map((group) => {\n const constraintMap = new Map<string, Constraint>();\n const constraintOrder: string[] = [];\n\n for (const rule of group.rules) {\n const key = `${rule.scope.value}:${rule.path.value}`;\n const opHex = buildOperatorHex(rule);\n\n const existing = constraintMap.get(key);\n if (existing !== undefined) {\n existing.operators.push(opHex);\n } else {\n const constraint: Constraint = {\n scope: rule.scope.value,\n path: rule.path.value,\n operators: [opHex],\n span: rule.span,\n };\n constraintMap.set(key, constraint);\n constraintOrder.push(key);\n }\n }\n\n return constraintOrder.map((k) => constraintMap.get(k)!);\n });\n\n return {\n isSelectorless: policy.isSelectorless,\n selector: policy.selector.value,\n descriptor: policy.descriptor.raw,\n groups,\n span: policy.span,\n };\n}\n\n/**\n * Inspect a binary policy blob, returning the structural representation with full byte-level spans.\n * @param blob - Binary policy as 0x-prefixed hex string.\n * @returns The inspected policy with per-field spans for every structural element.\n * @throws {CallciumError} If the blob is structurally malformed.\n */\nfunction inspect(blob: Hex): DecodedPolicy {\n return decodePolicy(blob).policy;\n}\n\n/** Encode, decode, and inspect policies in the canonical binary format. */\nexport const PolicyCoder = { encode, decode, inspect };\n","import { Op, TypeCode } from \"./constants\";\nimport { CallciumError } from \"./errors\";\n\n/** Read a big-endian 256-bit unsigned integer from a 32-byte window. */\nexport function toBigInt(bytes: Uint8Array, offset = 0): bigint {\n const view = new DataView(bytes.buffer, bytes.byteOffset + offset, 32);\n return (\n (view.getBigUint64(0, false) << 192n) |\n (view.getBigUint64(8, false) << 128n) |\n (view.getBigUint64(16, false) << 64n) |\n view.getBigUint64(24, false)\n );\n}\n\n/** Return true when the type code represents a signed integer (int8 through int256). */\nexport function isSigned(typeCode: number): boolean {\n return typeCode >= TypeCode.INT_MIN && typeCode <= TypeCode.INT_MAX;\n}\n\n/** Return true when the operator code (with or without NOT flag) is a LENGTH_* variant. */\nexport function isLengthOp(opCode: number): boolean {\n const base = opCode & ~Op.NOT;\n return base >= Op.LENGTH_EQ && base <= Op.LENGTH_BETWEEN;\n}\n\n/** Return true when LENGTH_* operators are valid for the given type code (bytes, string, or dynamic array). */\nexport function isLengthValidType(typeCode: number): boolean {\n return typeCode === TypeCode.BYTES || typeCode === TypeCode.STRING || typeCode === TypeCode.DYNAMIC_ARRAY;\n}\n\n/** Compare two 256-bit values, using two's complement interpretation for signed type codes. */\nfunction compareTyped(a: bigint, b: bigint, typeCode: number): number {\n if (isSigned(typeCode)) {\n const sa = BigInt.asIntN(256, a);\n const sb = BigInt.asIntN(256, b);\n return sa < sb ? -1 : sa > sb ? 1 : 0;\n }\n return a < b ? -1 : a > b ? 1 : 0;\n}\n\n/** Binary search over a sorted array of 32-byte words. Comparison is always unsigned. */\nfunction isIn(value: bigint, data: Uint8Array): boolean {\n const count = data.length / 32;\n let lo = 0;\n let hi = count - 1;\n while (lo <= hi) {\n const mid = (lo + hi) >>> 1;\n const elem = toBigInt(data, mid * 32);\n if (value === elem) return true;\n if (value < elem) hi = mid - 1;\n else lo = mid + 1;\n }\n return false;\n}\n\n/**\n * Apply a single operator against a value and operand data.\n * Handles the NOT flag internally by inverting the base operator result.\n * @param opCode - Operator code, potentially OR'd with the NOT flag.\n * @param value - The 256-bit value to test (ignored for LENGTH_* operators).\n * @param valueLength - Runtime byte or element count, only meaningful for LENGTH_* operators.\n * @param operandData - Raw operand bytes (32 per operand, 64 for range operators).\n * @param typeCode - ABI type code, used to select signed vs. unsigned comparison.\n * @returns Whether the value satisfies the operator.\n */\nexport function applyOperator(\n opCode: number,\n value: bigint,\n valueLength: number,\n operandData: Uint8Array,\n typeCode: number,\n): boolean {\n const negate = (opCode & Op.NOT) !== 0;\n const base = opCode & ~Op.NOT;\n\n let result: boolean;\n\n switch (base) {\n case Op.EQ:\n result = value === toBigInt(operandData, 0);\n break;\n\n case Op.GT:\n result = compareTyped(value, toBigInt(operandData, 0), typeCode) > 0;\n break;\n\n case Op.LT:\n result = compareTyped(value, toBigInt(operandData, 0), typeCode) < 0;\n break;\n\n case Op.GTE:\n result = compareTyped(value, toBigInt(operandData, 0), typeCode) >= 0;\n break;\n\n case Op.LTE:\n result = compareTyped(value, toBigInt(operandData, 0), typeCode) <= 0;\n break;\n\n case Op.BETWEEN: {\n const min = toBigInt(operandData, 0);\n const max = toBigInt(operandData, 32);\n result = compareTyped(value, min, typeCode) >= 0 && compareTyped(value, max, typeCode) <= 0;\n break;\n }\n\n case Op.IN:\n result = isIn(value, operandData);\n break;\n\n case Op.BITMASK_ALL: {\n const mask = toBigInt(operandData, 0);\n result = (value & mask) === mask;\n break;\n }\n\n case Op.BITMASK_ANY: {\n const mask = toBigInt(operandData, 0);\n result = (value & mask) !== 0n;\n break;\n }\n\n case Op.BITMASK_NONE: {\n const mask = toBigInt(operandData, 0);\n result = (value & mask) === 0n;\n break;\n }\n\n case Op.LENGTH_EQ:\n result = BigInt(valueLength) === toBigInt(operandData, 0);\n break;\n\n case Op.LENGTH_GT:\n result = BigInt(valueLength) > toBigInt(operandData, 0);\n break;\n\n case Op.LENGTH_LT:\n result = BigInt(valueLength) < toBigInt(operandData, 0);\n break;\n\n case Op.LENGTH_GTE:\n result = BigInt(valueLength) >= toBigInt(operandData, 0);\n break;\n\n case Op.LENGTH_LTE:\n result = BigInt(valueLength) <= toBigInt(operandData, 0);\n break;\n\n case Op.LENGTH_BETWEEN: {\n const length = BigInt(valueLength);\n const min = toBigInt(operandData, 0);\n const max = toBigInt(operandData, 32);\n result = length >= min && length <= max;\n break;\n }\n\n default:\n throw new CallciumError(\"INVALID_OPERATOR\", `Unknown operator code 0x${base.toString(16).padStart(2, \"0\")}.`);\n }\n\n return negate ? !result : result;\n}\n","import type { Hex, Issue, IssueCategory, IssueSeverity } from \"./types\";\n\n///////////////////////////////////////////////////////////////////////////\n// Constants\n///////////////////////////////////////////////////////////////////////////\n\nexport const ZERO: Hex = `0x${\"0\".repeat(64)}`;\n\n///////////////////////////////////////////////////////////////////////////\n// Internal helper\n///////////////////////////////////////////////////////////////////////////\n\n/** Construct a fully populated Issue. */\nfunction makeIssue(\n severity: IssueSeverity,\n category: IssueCategory,\n groupIndex: number,\n constraintIndex: number,\n code: string,\n value1: Hex,\n value2: Hex,\n message: string,\n): Issue {\n return { severity, category, groupIndex, constraintIndex, code, value1, value2, message };\n}\n\n///////////////////////////////////////////////////////////////////////////\n// Type mismatch\n///////////////////////////////////////////////////////////////////////////\n\n/** Create an issue from operator compatibility results. */\nexport function fromOpRule(\n code: string,\n message: string,\n groupIndex: number,\n constraintIndex: number,\n opCode: Hex,\n): Issue {\n return makeIssue(\"error\", \"typeMismatch\", groupIndex, constraintIndex, code, opCode, ZERO, message);\n}\n\n///////////////////////////////////////////////////////////////////////////\n// Contradiction\n///////////////////////////////////////////////////////////////////////////\n\n/** eq(v) and neq(v) on same path. */\nexport function eqNeqContradiction(groupIndex: number, constraintIndex: number, value: Hex): Issue {\n return makeIssue(\n \"error\",\n \"contradiction\",\n groupIndex,\n constraintIndex,\n \"EQ_NEQ_CONTRADICTION\",\n value,\n ZERO,\n \"eq(v) and neq(v) on same path\",\n );\n}\n\n/** Multiple eq() operators with different values. */\nexport function conflictingEquality(groupIndex: number, constraintIndex: number, existing: Hex, newValue: Hex): Issue {\n return makeIssue(\n \"error\",\n \"contradiction\",\n groupIndex,\n constraintIndex,\n \"CONFLICTING_EQUALITY\",\n existing,\n newValue,\n \"Multiple eq() operators with different values\",\n );\n}\n\n/** Value is outside the physical range of the type. */\nexport function outOfPhysicalBounds(groupIndex: number, constraintIndex: number, value: Hex): Issue {\n return makeIssue(\n \"error\",\n \"contradiction\",\n groupIndex,\n constraintIndex,\n \"OUT_OF_PHYSICAL_BOUNDS\",\n value,\n ZERO,\n \"Value is outside the physical range of the type\",\n );\n}\n\n/** gt() on type maximum is impossible. */\nexport function impossibleGt(groupIndex: number, constraintIndex: number, value: Hex): Issue {\n return makeIssue(\n \"error\",\n \"contradiction\",\n groupIndex,\n constraintIndex,\n \"IMPOSSIBLE_GT\",\n value,\n ZERO,\n \"gt() on type maximum is impossible\",\n );\n}\n\n/** lt() on type minimum is impossible. */\nexport function impossibleLt(groupIndex: number, constraintIndex: number, value: Hex): Issue {\n return makeIssue(\n \"error\",\n \"contradiction\",\n groupIndex,\n constraintIndex,\n \"IMPOSSIBLE_LT\",\n value,\n ZERO,\n \"lt() on type minimum is impossible\",\n );\n}\n\n/** eq() value is excluded by bound. */\nexport function boundsExcludeEquality(groupIndex: number, constraintIndex: number, eq: Hex, bound: Hex): Issue {\n return makeIssue(\n \"error\",\n \"contradiction\",\n groupIndex,\n constraintIndex,\n \"BOUNDS_EXCLUDE_EQUALITY\",\n eq,\n bound,\n \"eq() value is excluded by bound\",\n );\n}\n\n/** Lower bound exceeds upper bound. */\nexport function impossibleRange(groupIndex: number, constraintIndex: number, lower: Hex, upper: Hex): Issue {\n return makeIssue(\n \"error\",\n \"contradiction\",\n groupIndex,\n constraintIndex,\n \"IMPOSSIBLE_RANGE\",\n lower,\n upper,\n \"Lower bound exceeds upper bound\",\n );\n}\n\n/** Set operation excludes existing eq() value. */\nexport function setExcludesEquality(groupIndex: number, constraintIndex: number, value: Hex): Issue {\n return makeIssue(\n \"error\",\n \"contradiction\",\n groupIndex,\n constraintIndex,\n \"SET_EXCLUDES_EQUALITY\",\n value,\n ZERO,\n \"Set operation excludes existing eq() value\",\n );\n}\n\n/** Multiple isIn() sets have no intersection. */\nexport function emptySetIntersection(groupIndex: number, constraintIndex: number): Issue {\n return makeIssue(\n \"error\",\n \"contradiction\",\n groupIndex,\n constraintIndex,\n \"EMPTY_SET_INTERSECTION\",\n ZERO,\n ZERO,\n \"Multiple isIn() sets have no intersection\",\n );\n}\n\n/** All values in isIn() set are excluded by neq/notIn. */\nexport function setFullyExcluded(groupIndex: number, constraintIndex: number): Issue {\n return makeIssue(\n \"error\",\n \"contradiction\",\n groupIndex,\n constraintIndex,\n \"SET_FULLY_EXCLUDED\",\n ZERO,\n ZERO,\n \"All values in isIn() set are excluded by neq/notIn\",\n );\n}\n\n/** lengthEq(v) and lengthNeq(v) on same path. */\nexport function lengthEqNeqContradiction(groupIndex: number, constraintIndex: number, value: Hex): Issue {\n return makeIssue(\n \"error\",\n \"contradiction\",\n groupIndex,\n constraintIndex,\n \"LENGTH_EQ_NEQ_CONTRADICTION\",\n value,\n ZERO,\n \"lengthEq(v) and lengthNeq(v) on same path\",\n );\n}\n\n/** Multiple lengthEq() operators with different values. */\nexport function conflictingLength(groupIndex: number, constraintIndex: number, existing: Hex, newValue: Hex): Issue {\n return makeIssue(\n \"error\",\n \"contradiction\",\n groupIndex,\n constraintIndex,\n \"CONFLICTING_LENGTH\",\n existing,\n newValue,\n \"Multiple lengthEq() operators with different values\",\n );\n}\n\n/** lengthEq() value is excluded by bound. */\nexport function boundsExcludeLength(groupIndex: number, constraintIndex: number, eq: Hex, bound: Hex): Issue {\n return makeIssue(\n \"error\",\n \"contradiction\",\n groupIndex,\n constraintIndex,\n \"BOUNDS_EXCLUDE_LENGTH\",\n eq,\n bound,\n \"lengthEq() value is excluded by bound\",\n );\n}\n\n/** Lower length bound exceeds upper bound. */\nexport function impossibleLengthRange(groupIndex: number, constraintIndex: number, lower: Hex, upper: Hex): Issue {\n return makeIssue(\n \"error\",\n \"contradiction\",\n groupIndex,\n constraintIndex,\n \"IMPOSSIBLE_LENGTH_RANGE\",\n lower,\n upper,\n \"Lower length bound exceeds upper bound\",\n );\n}\n\n/** Length value is outside the physical range. */\nexport function outOfPhysicalLengthBounds(groupIndex: number, constraintIndex: number, value: Hex): Issue {\n return makeIssue(\n \"error\",\n \"contradiction\",\n groupIndex,\n constraintIndex,\n \"OUT_OF_PHYSICAL_LENGTH_BOUNDS\",\n value,\n ZERO,\n \"Length value is outside the physical range\",\n );\n}\n\n/** lengthGt() on maximum length is impossible. */\nexport function impossibleLengthGt(groupIndex: number, constraintIndex: number, value: Hex): Issue {\n return makeIssue(\n \"error\",\n \"contradiction\",\n groupIndex,\n constraintIndex,\n \"IMPOSSIBLE_LENGTH_GT\",\n value,\n ZERO,\n \"lengthGt() on maximum length is impossible\",\n );\n}\n\n/** lengthLt() on minimum length is impossible. */\nexport function impossibleLengthLt(groupIndex: number, constraintIndex: number, value: Hex): Issue {\n return makeIssue(\n \"error\",\n \"contradiction\",\n groupIndex,\n constraintIndex,\n \"IMPOSSIBLE_LENGTH_LT\",\n value,\n ZERO,\n \"lengthLt() on minimum length is impossible\",\n );\n}\n\n/** Bitmask operators conflict. */\nexport function bitmaskContradiction(groupIndex: number, constraintIndex: number, mask: Hex, conflicting: Hex): Issue {\n return makeIssue(\n \"error\",\n \"contradiction\",\n groupIndex,\n constraintIndex,\n \"BITMASK_CONTRADICTION\",\n mask,\n conflicting,\n \"Bitmask operators conflict\",\n );\n}\n\n/** bitmaskAny is impossible because all bits are forbidden. */\nexport function bitmaskAnyImpossible(groupIndex: number, constraintIndex: number, mask: Hex, mustBeZero: Hex): Issue {\n return makeIssue(\n \"error\",\n \"contradiction\",\n groupIndex,\n constraintIndex,\n \"BITMASK_ANY_IMPOSSIBLE\",\n mask,\n mustBeZero,\n \"bitmaskAny is impossible because all bits are forbidden\",\n );\n}\n\n/** isIn/notIn set is not strictly sorted and deduplicated. */\nexport function unsortedInSet(groupIndex: number, constraintIndex: number): Issue {\n return makeIssue(\n \"error\",\n \"contradiction\",\n groupIndex,\n constraintIndex,\n \"UNSORTED_IN_SET\",\n ZERO,\n ZERO,\n \"isIn/notIn set is not strictly sorted and deduplicated.\",\n );\n}\n\n/** Group contains zero constraints. */\nexport function emptyGroup(groupIndex: number): Issue {\n return makeIssue(\"error\", \"vacuity\", groupIndex, 0, \"EMPTY_GROUP\", ZERO, ZERO, \"Group contains zero constraints.\");\n}\n\n///////////////////////////////////////////////////////////////////////////\n// Redundancy\n///////////////////////////////////////////////////////////////////////////\n\n/** Numeric bound is dominated by a stricter bound. */\nexport function dominatedBound(groupIndex: number, constraintIndex: number, value: Hex): Issue {\n return makeIssue(\n \"warning\",\n \"redundancy\",\n groupIndex,\n constraintIndex,\n \"DOMINATED_BOUND\",\n value,\n ZERO,\n \"Numeric bound is dominated by a stricter bound\",\n );\n}\n\n/** Bound is redundant because eq() is set. */\nexport function redundantBound(groupIndex: number, constraintIndex: number, bound: Hex, eq: Hex): Issue {\n return makeIssue(\n \"warning\",\n \"redundancy\",\n groupIndex,\n constraintIndex,\n \"REDUNDANT_BOUND\",\n bound,\n eq,\n \"Bound is redundant because eq() is set\",\n );\n}\n\n/** notIn() value was present in isIn() set. */\nexport function setReduction(groupIndex: number, constraintIndex: number, value: Hex): Issue {\n return makeIssue(\n \"warning\",\n \"redundancy\",\n groupIndex,\n constraintIndex,\n \"SET_REDUCTION\",\n value,\n ZERO,\n \"notIn() value was present in isIn() set\",\n );\n}\n\n/** isIn() sets partially overlap. */\nexport function setRedundancy(groupIndex: number, constraintIndex: number, intersectionCount: Hex): Issue {\n return makeIssue(\n \"warning\",\n \"redundancy\",\n groupIndex,\n constraintIndex,\n \"SET_REDUNDANCY\",\n intersectionCount,\n ZERO,\n \"isIn() sets partially overlap\",\n );\n}\n\n/** Some values in isIn() set are excluded by neq/notIn. */\nexport function setPartiallyExcluded(groupIndex: number, constraintIndex: number, excludedCount: Hex): Issue {\n return makeIssue(\n \"warning\",\n \"redundancy\",\n groupIndex,\n constraintIndex,\n \"SET_PARTIALLY_EXCLUDED\",\n excludedCount,\n ZERO,\n \"Some values in isIn() set are excluded by neq/notIn\",\n );\n}\n\n/** Length bound is dominated by a stricter bound. */\nexport function dominatedLengthBound(groupIndex: number, constraintIndex: number, value: Hex): Issue {\n return makeIssue(\n \"warning\",\n \"redundancy\",\n groupIndex,\n constraintIndex,\n \"DOMINATED_LENGTH_BOUND\",\n value,\n ZERO,\n \"Length bound is dominated by a stricter bound\",\n );\n}\n\n/** Length bound is redundant because lengthEq() is set. */\nexport function redundantLengthBound(groupIndex: number, constraintIndex: number, bound: Hex, eq: Hex): Issue {\n return makeIssue(\n \"warning\",\n \"redundancy\",\n groupIndex,\n constraintIndex,\n \"REDUNDANT_LENGTH_BOUND\",\n bound,\n eq,\n \"Length bound is redundant because lengthEq() is set\",\n );\n}\n\n/** Bitmask operation is redundant. */\nexport function redundantBitmask(groupIndex: number, constraintIndex: number, mask: Hex, existing: Hex): Issue {\n return makeIssue(\n \"warning\",\n \"redundancy\",\n groupIndex,\n constraintIndex,\n \"REDUNDANT_BITMASK\",\n mask,\n existing,\n \"Bitmask operation is redundant\",\n );\n}\n\n/** Duplicate operator in constraint. */\nexport function duplicateConstraint(groupIndex: number, constraintIndex: number): Issue {\n return makeIssue(\n \"warning\",\n \"redundancy\",\n groupIndex,\n constraintIndex,\n \"DUPLICATE_CONSTRAINT\",\n ZERO,\n ZERO,\n \"Duplicate operator in constraint\",\n );\n}\n\n///////////////////////////////////////////////////////////////////////////\n// Vacuity\n///////////////////////////////////////////////////////////////////////////\n\n/** gte() bound equals type minimum (always true). */\nexport function vacuousGte(groupIndex: number, constraintIndex: number, value: Hex): Issue {\n return makeIssue(\n \"info\",\n \"vacuity\",\n groupIndex,\n constraintIndex,\n \"VACUOUS_GTE\",\n value,\n ZERO,\n \"gte() bound equals type minimum (always true)\",\n );\n}\n\n/** lte() bound equals type maximum (always true). */\nexport function vacuousLte(groupIndex: number, constraintIndex: number, value: Hex): Issue {\n return makeIssue(\n \"info\",\n \"vacuity\",\n groupIndex,\n constraintIndex,\n \"VACUOUS_LTE\",\n value,\n ZERO,\n \"lte() bound equals type maximum (always true)\",\n );\n}\n\n/** lengthGte(0) is always true. */\nexport function vacuousLengthGte(groupIndex: number, constraintIndex: number, value: Hex): Issue {\n return makeIssue(\n \"info\",\n \"vacuity\",\n groupIndex,\n constraintIndex,\n \"VACUOUS_LENGTH_GTE\",\n value,\n ZERO,\n \"lengthGte(0) is always true\",\n );\n}\n\n/** lengthLte() bound equals maximum (always true). */\nexport function vacuousLengthLte(groupIndex: number, constraintIndex: number, value: Hex): Issue {\n return makeIssue(\n \"info\",\n \"vacuity\",\n groupIndex,\n constraintIndex,\n \"VACUOUS_LENGTH_LTE\",\n value,\n ZERO,\n \"lengthLte() bound equals maximum (always true)\",\n );\n}\n\n///////////////////////////////////////////////////////////////////////////\n// Bound issue factory set\n///////////////////////////////////////////////////////////////////////////\n\n/** Pre-select value or length issue factories for a bound domain. */\nexport function boundIssues(isLength: boolean) {\n return {\n eqNeqContradiction: isLength ? lengthEqNeqContradiction : eqNeqContradiction,\n conflicting: isLength ? conflictingLength : conflictingEquality,\n outOfPhysicalBounds: isLength ? outOfPhysicalLengthBounds : outOfPhysicalBounds,\n impossibleGt: isLength ? impossibleLengthGt : impossibleGt,\n impossibleLt: isLength ? impossibleLengthLt : impossibleLt,\n boundsExcludeEquality: isLength ? boundsExcludeLength : boundsExcludeEquality,\n impossibleRange: isLength ? impossibleLengthRange : impossibleRange,\n dominated: isLength ? dominatedLengthBound : dominatedBound,\n redundant: isLength ? redundantLengthBound : redundantBound,\n vacuousGte: isLength ? vacuousLengthGte : vacuousGte,\n vacuousLte: isLength ? vacuousLengthLte : vacuousLte,\n };\n}\n\n/** Issue factory set returned by {@link boundIssues}. */\nexport type BoundIssueSet = ReturnType<typeof boundIssues>;\n","import { bigintToHex, hexToBytes } from \"./bytes\";\nimport { lookupContextProperty, Op, Scope, TypeCode } from \"./constants\";\nimport { Descriptor, type TypeInfo } from \"./descriptor\";\nimport { isSigned, isLengthOp, isLengthValidType } from \"./operators\";\nimport { parsePathSteps } from \"./policy-coder\";\nimport * as Issues from \"./validation-issue\";\nimport { boundIssues, type BoundIssueSet } from \"./validation-issue\";\n\nimport type { Constraint, Hex, Issue, PolicyData } from \"./types\";\n\n///////////////////////////////////////////////////////////////////////////\n// Internal types\n///////////////////////////////////////////////////////////////////////////\n\ntype BoundDomain = {\n isSigned: boolean;\n min: bigint;\n max: bigint;\n hasEq: boolean;\n eq: bigint;\n hasLower: boolean;\n lower: bigint;\n lowerInclusive: boolean;\n hasUpper: boolean;\n upper: bigint;\n upperInclusive: boolean;\n holes: bigint[];\n};\n\ntype BitmaskDomain = {\n mustBeOne: bigint;\n mustBeZero: bigint;\n};\n\ntype SetDomain = {\n hasIn: boolean;\n inValues: bigint[];\n notInValues: bigint[];\n};\n\ntype ConstraintContext = {\n scope: number;\n path: Hex;\n typeInfo: TypeInfo;\n numeric: BoundDomain;\n bitmask: BitmaskDomain;\n length: BoundDomain;\n set: SetDomain;\n};\n\n///////////////////////////////////////////////////////////////////////////\n// Constants\n///////////////////////////////////////////////////////////////////////////\n\n/**\n * Maximum number of tracked \"holes\" (neq exclusions) and notIn values per\n * domain. A hole is a single value excluded via a negated equality (neq).\n * During cross-operator analysis, holes punch values out of isIn sets — if\n * every member of an isIn set is excluded by holes or notIn, the constraint\n * is unsatisfiable (SET_FULLY_EXCLUDED). When only some are excluded, the\n * validator emits SET_PARTIALLY_EXCLUDED.\n *\n * Both caps are protocol-defined limits. Beyond these limits,\n * additional exclusions are silently ignored — the validator becomes\n * best-effort for set-reduction diagnostics but never produces false\n * positives, only potential false negatives (missed redundancy warnings).\n */\nconst MAX_HOLES = 8;\nconst MAX_NOT_IN = 8;\nconst LENGTH_MAX = 0xffffffffn;\n\n// Mask for reinterpreting uint256 as int256 (two's complement).\nconst UINT256_MAX = (1n << 256n) - 1n;\nconst INT256_SIGN_BIT = 1n << 255n;\n\n///////////////////////////////////////////////////////////////////////////\n// Signed-aware comparisons\n///////////////////////////////////////////////////////////////////////////\n\n/** Reinterpret a uint256 bigint as a signed int256. */\nfunction toSigned(v: bigint): bigint {\n return v >= INT256_SIGN_BIT ? v - (1n << 256n) : v;\n}\n\n/** a > b. */\nfunction isGt(a: bigint, b: bigint, signed: boolean): boolean {\n return signed ? toSigned(a) > toSigned(b) : a > b;\n}\n\n/** a >= b. */\nfunction isGte(a: bigint, b: bigint, signed: boolean): boolean {\n return signed ? toSigned(a) >= toSigned(b) : a >= b;\n}\n\n/** a < b. */\nfunction isLt(a: bigint, b: bigint, signed: boolean): boolean {\n return signed ? toSigned(a) < toSigned(b) : a < b;\n}\n\n/** a <= b. */\nfunction isLte(a: bigint, b: bigint, signed: boolean): boolean {\n return signed ? toSigned(a) <= toSigned(b) : a <= b;\n}\n\n///////////////////////////////////////////////////////////////////////////\n// Type classification\n///////////////////////////////////////////////////////////////////////////\n\n/** True for uint and int type codes. */\nfunction isNumericType(typeCode: number): boolean {\n return typeCode <= TypeCode.UINT_MAX || (typeCode >= TypeCode.INT_MIN && typeCode <= TypeCode.INT_MAX);\n}\n\n/** True for uint and bytes32 type codes. */\nfunction isBitmaskCompatible(typeCode: number): boolean {\n return typeCode <= TypeCode.UINT_MAX || typeCode === TypeCode.FIXED_BYTES_MIN + 31;\n}\n\n/** Physical domain limits for a type code (returned as raw uint256 bigints). */\nfunction getDomainLimits(typeCode: number): { min: bigint; max: bigint } {\n if (typeCode <= TypeCode.UINT_MAX) {\n const bits = BigInt(typeCode - TypeCode.UINT_MIN + 1) * 8n;\n return { min: 0n, max: bits === 256n ? UINT256_MAX : (1n << bits) - 1n };\n }\n if (typeCode >= TypeCode.INT_MIN && typeCode <= TypeCode.INT_MAX) {\n const bits = BigInt(typeCode - TypeCode.INT_MIN + 1) * 8n;\n if (bits === 256n) {\n // int256: min = uint256(type(int256).min), max = uint256(type(int256).max).\n return { min: INT256_SIGN_BIT, max: INT256_SIGN_BIT - 1n };\n }\n const half = 1n << (bits - 1n);\n // Stored as raw uint256: min is two's complement of -(2^(bits-1)).\n const max = half - 1n;\n const min = (UINT256_MAX - half + 1n) & UINT256_MAX;\n return { min, max };\n }\n if (typeCode === TypeCode.BOOL) return { min: 0n, max: 1n };\n if (typeCode === TypeCode.ADDRESS) return { min: 0n, max: (1n << 160n) - 1n };\n return { min: 0n, max: UINT256_MAX };\n}\n\n///////////////////////////////////////////////////////////////////////////\n// Operator classification\n///////////////////////////////////////////////////////////////////////////\n\n/** True for EQ, GT, LT, GTE, LTE, BETWEEN, IN, BITMASK_*. */\nfunction isValueOp(opBase: number): boolean {\n return opBase <= Op.BITMASK_NONE;\n}\n\n/** True for GT, LT, GTE, LTE, BETWEEN. */\nfunction isComparisonOp(opBase: number): boolean {\n return opBase >= Op.GT && opBase <= Op.BETWEEN;\n}\n\n/** True for BITMASK_ALL, BITMASK_ANY, BITMASK_NONE. */\nfunction isBitmaskOp(opBase: number): boolean {\n return opBase >= Op.BITMASK_ALL && opBase <= Op.BITMASK_NONE;\n}\n\n///////////////////////////////////////////////////////////////////////////\n// Type compatibility check\n///////////////////////////////////////////////////////////////////////////\n\n/** Return the incompatibility reason, or null if the operator is allowed. */\nfunction getIncompat(opBase: number, typeInfo: TypeInfo): { code: string; message: string } | null {\n const { typeCode, isDynamic, staticSize } = typeInfo;\n if (isValueOp(opBase)) {\n if (isDynamic || staticSize !== 32) {\n return { code: \"VALUE_OP_ON_DYNAMIC\", message: \"Value operator used on dynamic type\" };\n }\n if (isComparisonOp(opBase) && !isNumericType(typeCode)) {\n return { code: \"NUMERIC_OP_ON_NON_NUMERIC\", message: \"Comparison operator used on non-numeric type\" };\n }\n if (isBitmaskOp(opBase) && !isBitmaskCompatible(typeCode)) {\n return { code: \"BITMASK_ON_INVALID\", message: \"Bitmask operator used on incompatible type\" };\n }\n return null;\n }\n if (isLengthOp(opBase)) {\n if (!isLengthValidType(typeCode)) {\n return { code: \"LENGTH_ON_STATIC\", message: \"Length operator used on non-dynamic type\" };\n }\n return null;\n }\n return { code: \"UNKNOWN_OPERATOR\", message: \"Unknown operator code\" };\n}\n\n/** Check operator–type compatibility and return an issue descriptor on mismatch. */\nfunction checkCompatibility(\n opBase: number,\n typeCode: number,\n isDynamic: boolean,\n staticSize: number,\n): { compatible: boolean; code: string; message: string } {\n const incompat = getIncompat(opBase, { typeCode, isDynamic, staticSize });\n return incompat ? { compatible: false, ...incompat } : { compatible: true, code: \"\", message: \"\" };\n}\n\n/**\n * True if operator `opCode` is allowed on a target with the given type info.\n * Tolerates the NOT flag on `opCode`.\n */\nexport function isOpAllowed(opCode: number, typeInfo: TypeInfo): boolean {\n return getIncompat(opCode & ~Op.NOT, typeInfo) === null;\n}\n\n///////////////////////////////////////////////////////////////////////////\n// Payload reading\n///////////////////////////////////////////////////////////////////////////\n\n/** Read a single uint256 from operator hex (bytes after the opcode byte). */\nfunction readValue(opHex: Hex): bigint {\n return BigInt(`0x${opHex.slice(4)}`);\n}\n\n/** Read a pair of uint256 values from a BETWEEN operator. */\nfunction readPair(opHex: Hex): { low: bigint; high: bigint } {\n const body = opHex.slice(4);\n return {\n low: BigInt(`0x${body.slice(0, 64)}`),\n high: BigInt(`0x${body.slice(64, 128)}`),\n };\n}\n\n/** Unpack an IN operator's payload into an array of bigint values. */\nfunction unpackSet(opHex: Hex): bigint[] {\n const body = opHex.slice(4);\n const count = body.length / 64;\n const values: bigint[] = [];\n for (let i = 0; i < count; i++) {\n values.push(BigInt(`0x${body.slice(i * 64, (i + 1) * 64)}`));\n }\n return values;\n}\n\n/** True if every element is strictly greater than the previous. */\nfunction isStrictlyAscending(values: bigint[]): boolean {\n for (let i = 1; i < values.length; i++) {\n if (values[i]! <= values[i - 1]!) return false;\n }\n return true;\n}\n\n///////////////////////////////////////////////////////////////////////////\n// Opcode normalization\n///////////////////////////////////////////////////////////////////////////\n\n/** Convert LENGTH_* opcode to its core comparison equivalent. */\nfunction normalizeLengthOp(base: number): number {\n if (base === Op.LENGTH_EQ) return Op.EQ;\n if (base === Op.LENGTH_GT) return Op.GT;\n if (base === Op.LENGTH_LT) return Op.LT;\n if (base === Op.LENGTH_GTE) return Op.GTE;\n if (base === Op.LENGTH_LTE) return Op.LTE;\n return base;\n}\n\n/** Convert a negated bound opcode to its positive equivalent. */\nfunction negateBoundOp(base: number): number {\n if (base === Op.GT) return Op.LTE;\n if (base === Op.GTE) return Op.LT;\n if (base === Op.LT) return Op.GTE;\n if (base === Op.LTE) return Op.GT;\n return base;\n}\n\n///////////////////////////////////////////////////////////////////////////\n// Context initialization\n///////////////////////////////////////////////////////////////////////////\n\n/** Create a fresh constraint context with domain limits from the type. */\nfunction initContext(scope: number, path: Hex, typeInfo: TypeInfo): ConstraintContext {\n const { min, max } = getDomainLimits(typeInfo.typeCode);\n return {\n scope,\n path,\n typeInfo,\n numeric: {\n isSigned: isSigned(typeInfo.typeCode),\n min,\n max,\n hasEq: false,\n eq: 0n,\n hasLower: false,\n lower: 0n,\n lowerInclusive: false,\n hasUpper: false,\n upper: 0n,\n upperInclusive: false,\n holes: [],\n },\n bitmask: { mustBeOne: 0n, mustBeZero: 0n },\n length: {\n isSigned: false,\n min: 0n,\n max: LENGTH_MAX,\n hasEq: false,\n eq: 0n,\n hasLower: false,\n lower: 0n,\n lowerInclusive: false,\n hasUpper: false,\n upper: 0n,\n upperInclusive: false,\n holes: [],\n },\n set: {\n hasIn: false,\n inValues: [],\n notInValues: [],\n },\n };\n}\n\n///////////////////////////////////////////////////////////////////////////\n// Bound domain update\n///////////////////////////////////////////////////////////////////////////\n\n/** Narrow the numeric bound domain with an operator and emit issues on contradiction or redundancy. */\nfunction updateBound(\n domain: BoundDomain,\n base: number,\n isNegated: boolean,\n value: bigint,\n emit: BoundIssueSet,\n groupIndex: number,\n constraintIndex: number,\n issues: Issue[],\n): void {\n let changedEq = false;\n let changedLower = false;\n let changedUpper = false;\n\n // Negation handling.\n if (isNegated) {\n if (base === Op.EQ) {\n if (domain.hasEq && domain.eq === value) {\n issues.push(emit.eqNeqContradiction(groupIndex, constraintIndex, bigintToHex(value)));\n }\n let alreadyHole = false;\n for (let j = 0; j < domain.holes.length; j++) {\n if (domain.holes[j] === value) {\n alreadyHole = true;\n break;\n }\n }\n if (!alreadyHole && domain.holes.length < MAX_HOLES) {\n domain.holes.push(value);\n }\n } else {\n updateBound(domain, negateBoundOp(base), false, value, emit, groupIndex, constraintIndex, issues);\n }\n return;\n }\n\n // Vacuity checks.\n if (base === Op.GTE && value === domain.min) {\n issues.push(emit.vacuousGte(groupIndex, constraintIndex, bigintToHex(value)));\n } else if (base === Op.LTE && value === domain.max) {\n issues.push(emit.vacuousLte(groupIndex, constraintIndex, bigintToHex(value)));\n }\n\n // Physical bounds and impossibility.\n if (isLt(value, domain.min, domain.isSigned) || isGt(value, domain.max, domain.isSigned)) {\n issues.push(emit.outOfPhysicalBounds(groupIndex, constraintIndex, bigintToHex(value)));\n } else if (base === Op.GT && value === domain.max) {\n issues.push(emit.impossibleGt(groupIndex, constraintIndex, bigintToHex(value)));\n } else if (base === Op.LT && value === domain.min) {\n issues.push(emit.impossibleLt(groupIndex, constraintIndex, bigintToHex(value)));\n }\n\n // Equality handling.\n if (base === Op.EQ) {\n if (!domain.hasEq || domain.eq !== value) changedEq = true;\n if (domain.hasEq) {\n if (domain.eq !== value) {\n issues.push(emit.conflicting(groupIndex, constraintIndex, bigintToHex(domain.eq), bigintToHex(value)));\n }\n }\n for (let j = 0; j < domain.holes.length; j++) {\n if (domain.holes[j] === value) {\n issues.push(emit.eqNeqContradiction(groupIndex, constraintIndex, bigintToHex(value)));\n }\n }\n domain.hasEq = true;\n domain.eq = value;\n } else if (base === Op.GT || base === Op.GTE) {\n const inclusive = base === Op.GTE;\n if (domain.hasLower) {\n let redundant = false;\n let strictlyBetter = false;\n\n if (isLt(value, domain.lower, domain.isSigned)) {\n redundant = true;\n } else if (value === domain.lower) {\n if (domain.lowerInclusive) {\n if (!inclusive) strictlyBetter = true;\n else redundant = true;\n } else {\n if (!inclusive) redundant = true;\n }\n } else {\n strictlyBetter = true;\n }\n\n if (redundant) {\n issues.push(emit.dominated(groupIndex, constraintIndex, bigintToHex(value)));\n }\n\n if (strictlyBetter) {\n issues.push(emit.dominated(groupIndex, constraintIndex, bigintToHex(domain.lower)));\n domain.lower = value;\n domain.lowerInclusive = inclusive;\n changedLower = true;\n }\n } else {\n domain.hasLower = true;\n domain.lower = value;\n domain.lowerInclusive = inclusive;\n changedLower = true;\n }\n } else if (base === Op.LT || base === Op.LTE) {\n const inclusive = base === Op.LTE;\n if (domain.hasUpper) {\n let redundant = false;\n let strictlyBetter = false;\n\n if (isGt(value, domain.upper, domain.isSigned)) {\n redundant = true;\n } else if (value === domain.upper) {\n if (domain.upperInclusive) {\n if (!inclusive) strictlyBetter = true;\n else redundant = true;\n } else {\n if (!inclusive) redundant = true;\n }\n } else {\n strictlyBetter = true;\n }\n\n if (redundant) {\n issues.push(emit.dominated(groupIndex, constraintIndex, bigintToHex(value)));\n }\n\n if (strictlyBetter) {\n issues.push(emit.dominated(groupIndex, constraintIndex, bigintToHex(domain.upper)));\n domain.upper = value;\n domain.upperInclusive = inclusive;\n changedUpper = true;\n }\n } else {\n domain.hasUpper = true;\n domain.upper = value;\n domain.upperInclusive = inclusive;\n changedUpper = true;\n }\n }\n\n // Cross-checks: equality vs lower bound.\n if (changedEq || changedLower) {\n if (domain.hasEq && domain.hasLower) {\n const contradiction = domain.lowerInclusive\n ? isLt(domain.eq, domain.lower, domain.isSigned)\n : isLte(domain.eq, domain.lower, domain.isSigned);\n if (contradiction) {\n issues.push(\n emit.boundsExcludeEquality(groupIndex, constraintIndex, bigintToHex(domain.eq), bigintToHex(domain.lower)),\n );\n } else {\n issues.push(emit.redundant(groupIndex, constraintIndex, bigintToHex(domain.lower), bigintToHex(domain.eq)));\n }\n }\n }\n\n // Cross-checks: equality vs upper bound.\n if (changedEq || changedUpper) {\n if (domain.hasEq && domain.hasUpper) {\n const contradiction = domain.upperInclusive\n ? isGt(domain.eq, domain.upper, domain.isSigned)\n : isGte(domain.eq, domain.upper, domain.isSigned);\n if (contradiction) {\n issues.push(\n emit.boundsExcludeEquality(groupIndex, constraintIndex, bigintToHex(domain.eq), bigintToHex(domain.upper)),\n );\n } else {\n issues.push(emit.redundant(groupIndex, constraintIndex, bigintToHex(domain.upper), bigintToHex(domain.eq)));\n }\n }\n }\n\n // Cross-check: lower vs upper bound.\n if (changedLower || changedUpper) {\n if (domain.hasLower && domain.hasUpper) {\n const impossible =\n isGt(domain.lower, domain.upper, domain.isSigned) ||\n (domain.lower === domain.upper && (!domain.lowerInclusive || !domain.upperInclusive));\n if (impossible) {\n issues.push(\n emit.impossibleRange(groupIndex, constraintIndex, bigintToHex(domain.lower), bigintToHex(domain.upper)),\n );\n }\n }\n }\n}\n\n///////////////////////////////////////////////////////////////////////////\n// Bitmask domain update\n///////////////////////////////////////////////////////////////////////////\n\n/** Update the bitmask domain and emit issues on contradiction or redundancy. */\nfunction updateBitmask(\n ctx: ConstraintContext,\n base: number,\n isNegated: boolean,\n mask: bigint,\n groupIndex: number,\n constraintIndex: number,\n issues: Issue[],\n): void {\n if (isNegated) return;\n\n if (base === Op.BITMASK_ALL) {\n if ((ctx.bitmask.mustBeZero & mask) !== 0n) {\n issues.push(\n Issues.bitmaskContradiction(\n groupIndex,\n constraintIndex,\n bigintToHex(mask),\n bigintToHex(ctx.bitmask.mustBeZero),\n ),\n );\n }\n if ((ctx.bitmask.mustBeOne & mask) === mask) {\n issues.push(\n Issues.redundantBitmask(groupIndex, constraintIndex, bigintToHex(mask), bigintToHex(ctx.bitmask.mustBeOne)),\n );\n }\n ctx.bitmask.mustBeOne |= mask;\n } else if (base === Op.BITMASK_NONE) {\n if ((ctx.bitmask.mustBeOne & mask) !== 0n) {\n issues.push(\n Issues.bitmaskContradiction(groupIndex, constraintIndex, bigintToHex(mask), bigintToHex(ctx.bitmask.mustBeOne)),\n );\n }\n if ((ctx.bitmask.mustBeZero & mask) === mask) {\n issues.push(\n Issues.redundantBitmask(groupIndex, constraintIndex, bigintToHex(mask), bigintToHex(ctx.bitmask.mustBeZero)),\n );\n }\n ctx.bitmask.mustBeZero |= mask;\n } else if (base === Op.BITMASK_ANY) {\n if (mask !== 0n && (ctx.bitmask.mustBeZero & mask) === mask) {\n issues.push(\n Issues.bitmaskAnyImpossible(\n groupIndex,\n constraintIndex,\n bigintToHex(mask),\n bigintToHex(ctx.bitmask.mustBeZero),\n ),\n );\n }\n if ((ctx.bitmask.mustBeOne & mask) !== 0n) {\n issues.push(\n Issues.redundantBitmask(groupIndex, constraintIndex, bigintToHex(mask), bigintToHex(ctx.bitmask.mustBeOne)),\n );\n }\n }\n}\n\n///////////////////////////////////////////////////////////////////////////\n// Set domain update\n///////////////////////////////////////////////////////////////////////////\n\n/** Emit an issue if the IN set has been fully excluded by NOT_IN or NEQ holes. */\nfunction checkSetEmpty(ctx: ConstraintContext, groupIndex: number, constraintIndex: number, issues: Issue[]): void {\n if (!ctx.set.hasIn) return;\n\n let possibleCount = 0;\n const inCount = ctx.set.inValues.length;\n for (let i = 0; i < inCount; i++) {\n const value = ctx.set.inValues[i]!;\n let forbidden = false;\n for (let k = 0; k < ctx.numeric.holes.length; k++) {\n if (ctx.numeric.holes[k] === value) {\n forbidden = true;\n break;\n }\n }\n if (!forbidden) {\n for (let k = 0; k < ctx.set.notInValues.length; k++) {\n if (ctx.set.notInValues[k] === value) {\n forbidden = true;\n break;\n }\n }\n }\n if (!forbidden) possibleCount++;\n }\n\n if (possibleCount === 0) {\n issues.push(Issues.setFullyExcluded(groupIndex, constraintIndex));\n } else if (possibleCount < inCount) {\n issues.push(Issues.setPartiallyExcluded(groupIndex, constraintIndex, bigintToHex(BigInt(inCount - possibleCount))));\n }\n}\n\n/** Update the set domain with IN or NOT_IN values and emit issues on contradiction or redundancy. */\nfunction updateSet(\n ctx: ConstraintContext,\n isNegated: boolean,\n values: bigint[],\n groupIndex: number,\n constraintIndex: number,\n issues: Issue[],\n): void {\n if (isNegated) {\n for (const value of values) {\n if (ctx.numeric.hasEq && ctx.numeric.eq === value) {\n issues.push(Issues.setExcludesEquality(groupIndex, constraintIndex, bigintToHex(value)));\n }\n if (ctx.set.hasIn) {\n let inSet = false;\n for (const existing of ctx.set.inValues) {\n if (existing === value) {\n inSet = true;\n break;\n }\n }\n if (inSet) {\n issues.push(Issues.setReduction(groupIndex, constraintIndex, bigintToHex(value)));\n }\n }\n if (ctx.set.notInValues.length < MAX_NOT_IN) {\n ctx.set.notInValues.push(value);\n }\n }\n checkSetEmpty(ctx, groupIndex, constraintIndex, issues);\n } else {\n if (ctx.numeric.hasEq) {\n let found = false;\n for (const candidate of values) {\n if (candidate === ctx.numeric.eq) {\n found = true;\n break;\n }\n }\n if (!found) {\n issues.push(Issues.setExcludesEquality(groupIndex, constraintIndex, bigintToHex(ctx.numeric.eq)));\n }\n }\n\n if (ctx.set.hasIn) {\n const intersection: bigint[] = [];\n for (const existing of ctx.set.inValues) {\n for (const candidate of values) {\n if (existing === candidate) {\n intersection.push(existing);\n break;\n }\n }\n }\n\n if (intersection.length === 0) {\n issues.push(Issues.emptySetIntersection(groupIndex, constraintIndex));\n } else if (intersection.length < values.length || intersection.length < ctx.set.inValues.length) {\n issues.push(Issues.setRedundancy(groupIndex, constraintIndex, bigintToHex(BigInt(intersection.length))));\n }\n ctx.set.inValues = intersection;\n } else {\n ctx.set.hasIn = true;\n ctx.set.inValues = values;\n }\n\n checkSetEmpty(ctx, groupIndex, constraintIndex, issues);\n }\n}\n\n///////////////////////////////////////////////////////////////////////////\n// Duplicate detection\n///////////////////////////////////////////////////////////////////////////\n\n/** Emit a warning if the constraint contains any identical operators. */\nfunction checkDuplicates(issues: Issue[], operators: Hex[], groupIndex: number, constraintIndex: number): void {\n const seen = new Set<string>();\n for (const op of operators) {\n const key = op.toLowerCase();\n if (seen.has(key)) {\n issues.push(Issues.duplicateConstraint(groupIndex, constraintIndex));\n return;\n }\n seen.add(key);\n }\n}\n\n///////////////////////////////////////////////////////////////////////////\n// Constraint validation\n///////////////////////////////////////////////////////////////////////////\n\n/** Validate all operators on a single constraint against its domain context. */\nfunction validateConstraint(\n ctx: ConstraintContext,\n constraint: Constraint,\n groupIndex: number,\n constraintIndex: number,\n issues: Issue[],\n): void {\n const operators = constraint.operators;\n\n for (const opHex of operators) {\n const opCode = parseInt(opHex.slice(2, 4), 16);\n const base = opCode & ~Op.NOT;\n const isNegated = (opCode & Op.NOT) !== 0;\n\n const compat = checkCompatibility(base, ctx.typeInfo.typeCode, ctx.typeInfo.isDynamic, ctx.typeInfo.staticSize);\n if (!compat.compatible) {\n issues.push(\n Issues.fromOpRule(compat.code, compat.message, groupIndex, constraintIndex, bigintToHex(BigInt(opCode))),\n );\n continue;\n }\n\n if (isValueOp(base)) {\n if (base >= Op.EQ && base <= Op.BETWEEN) {\n if (base === Op.BETWEEN) {\n const { low, high } = readPair(opHex);\n updateBound(ctx.numeric, Op.GTE, isNegated, low, boundIssues(false), groupIndex, constraintIndex, issues);\n updateBound(ctx.numeric, Op.LTE, isNegated, high, boundIssues(false), groupIndex, constraintIndex, issues);\n } else {\n const value = readValue(opHex);\n const holesBefore = ctx.numeric.holes.length;\n updateBound(ctx.numeric, base, isNegated, value, boundIssues(false), groupIndex, constraintIndex, issues);\n if (ctx.numeric.holes.length > holesBefore) {\n checkSetEmpty(ctx, groupIndex, constraintIndex, issues);\n }\n }\n } else if (isBitmaskOp(base)) {\n const mask = readValue(opHex);\n updateBitmask(ctx, base, isNegated, mask, groupIndex, constraintIndex, issues);\n } else if (base === Op.IN) {\n const values = unpackSet(opHex);\n if (!isStrictlyAscending(values)) {\n issues.push(Issues.unsortedInSet(groupIndex, constraintIndex));\n } else {\n updateSet(ctx, isNegated, values, groupIndex, constraintIndex, issues);\n }\n }\n } else if (isLengthOp(base)) {\n if (base === Op.LENGTH_BETWEEN) {\n const { low, high } = readPair(opHex);\n updateBound(ctx.length, Op.GTE, isNegated, low, boundIssues(true), groupIndex, constraintIndex, issues);\n updateBound(ctx.length, Op.LTE, isNegated, high, boundIssues(true), groupIndex, constraintIndex, issues);\n } else {\n const value = readValue(opHex);\n updateBound(\n ctx.length,\n normalizeLengthOp(base),\n isNegated,\n value,\n boundIssues(true),\n groupIndex,\n constraintIndex,\n issues,\n );\n }\n }\n }\n\n checkDuplicates(issues, operators, groupIndex, constraintIndex);\n}\n\n///////////////////////////////////////////////////////////////////////////\n// Group validation\n///////////////////////////////////////////////////////////////////////////\n\n/** Validate all constraints in a group, building per-path contexts for cross-constraint analysis. */\nfunction validateGroup(data: PolicyData, descBytes: Uint8Array, groupIndex: number, issues: Issue[]): void {\n const constraints = data.groups[groupIndex]!;\n const contexts: ConstraintContext[] = [];\n\n for (let constraintIndex = 0; constraintIndex < constraints.length; constraintIndex++) {\n const constraint = constraints[constraintIndex]!;\n const normalizedPath: Hex = `0x${constraint.path.slice(2).toLowerCase()}`;\n\n // Find existing context for this (scope, path) pair.\n let ctx: ConstraintContext | undefined;\n for (const existing of contexts) {\n if (existing.scope === constraint.scope && existing.path === normalizedPath) {\n ctx = existing;\n break;\n }\n }\n\n if (!ctx) {\n let typeInfo: TypeInfo;\n if (constraint.scope === Scope.CALLDATA) {\n const steps = parsePathSteps(constraint.path);\n typeInfo = Descriptor.typeAt(descBytes, steps);\n } else {\n const steps = parsePathSteps(constraint.path);\n const ctxId = steps[0]!;\n const typeCode = lookupContextProperty(ctxId).typeCode;\n typeInfo = { typeCode, isDynamic: false, staticSize: 32 };\n }\n ctx = initContext(constraint.scope, normalizedPath, typeInfo);\n contexts.push(ctx);\n }\n\n validateConstraint(ctx, constraint, groupIndex, constraintIndex, issues);\n }\n}\n\n///////////////////////////////////////////////////////////////////////////\n// Public API\n///////////////////////////////////////////////////////////////////////////\n\n/**\n * Validate a policy for type mismatches, contradictions, redundancies, and vacuities.\n * @param data - The canonical policy data to validate.\n * @returns All validation issues found, ordered by group and constraint index.\n */\nfunction validate(data: PolicyData): Issue[] {\n const issues: Issue[] = [];\n const descBytes = hexToBytes(data.descriptor);\n\n for (let groupIndex = 0; groupIndex < data.groups.length; groupIndex++) {\n if (data.groups[groupIndex]!.length === 0) {\n issues.push(Issues.emptyGroup(groupIndex));\n continue;\n }\n validateGroup(data, descBytes, groupIndex, issues);\n }\n\n return issues;\n}\n\n/** Semantic validation for policies. */\nexport const PolicyValidator = { validate };\n","import { keccak_256 } from \"@noble/hashes/sha3\";\n\nimport { bytesToHex } from \"./bytes\";\nimport { CallciumError } from \"./errors\";\n\nimport type { Hex } from \"./types\";\n\n///////////////////////////////////////////////////////////////////////////\n// SignatureParser\n///////////////////////////////////////////////////////////////////////////\n\n/** Parsed components of an ABI function signature. */\nexport type ParsedSignature = {\n /** The 4-byte function selector as a 0x-prefixed hex string. */\n selector: Hex;\n /** Comma-separated parameter types, empty string for no-argument functions. */\n types: string;\n};\n\n/** Return true if the char code is an ASCII letter. */\nfunction isAlpha(c: number): boolean {\n return (c >= 0x41 && c <= 0x5a) || (c >= 0x61 && c <= 0x7a);\n}\n\n/** Return true if the char code is an ASCII alphanumeric character. */\nfunction isAlphanum(c: number): boolean {\n return isAlpha(c) || (c >= 0x30 && c <= 0x39);\n}\n\n/**\n * Parse an ABI function signature into its selector and types.\n *\n * Strict mode: no whitespace, name must match `[A-Za-z_][A-Za-z0-9_]*`,\n * structure must be `name(types)` with the final `)` as the last character.\n *\n * @param signature - A function signature string, e.g. `\"transfer(address,uint256)\"`.\n * @returns The 4-byte selector and the comma-separated types string.\n * @throws {CallciumError} with code `\"INVALID_SIGNATURE\"` if the signature is malformed.\n */\nfunction parse(signature: string): ParsedSignature {\n if (signature.length < 3) {\n throw new CallciumError(\"INVALID_SIGNATURE\", `Invalid signature: too short, got \"${signature}\"`);\n }\n\n // Scan for whitespace, non-ASCII, and the opening parenthesis in one pass.\n let openParen = -1;\n for (let i = 0; i < signature.length; i++) {\n const c = signature.charCodeAt(i);\n if (c === 0x20 || c === 0x09 || c === 0x0a || c === 0x0d) {\n throw new CallciumError(\"INVALID_SIGNATURE\", \"Signature must not contain whitespace\");\n }\n if (c > 0x7e) {\n throw new CallciumError(\"INVALID_SIGNATURE\", \"Signature must contain only ASCII characters\");\n }\n if (openParen === -1 && c === 0x28) {\n openParen = i;\n }\n }\n\n if (openParen < 1) {\n throw new CallciumError(\n \"INVALID_SIGNATURE\",\n `Invalid signature: must have a function name followed by parentheses, got \"${signature}\"`,\n );\n }\n\n if (!signature.endsWith(\")\")) {\n throw new CallciumError(\"INVALID_SIGNATURE\", `Invalid signature: must end with \")\", got \"${signature}\"`);\n }\n\n // Validate function name: [A-Za-z_][A-Za-z0-9_]*.\n const firstChar = signature.charCodeAt(0);\n if (!isAlpha(firstChar) && firstChar !== 0x5f) {\n throw new CallciumError(\"INVALID_SIGNATURE\", \"Function name must start with a letter or underscore\");\n }\n for (let i = 1; i < openParen; i++) {\n const c = signature.charCodeAt(i);\n if (!isAlphanum(c) && c !== 0x5f) {\n throw new CallciumError(\n \"INVALID_SIGNATURE\",\n \"Function name must contain only alphanumeric characters or underscores\",\n );\n }\n }\n\n const types = signature.slice(openParen + 1, signature.length - 1);\n const encoded = new Uint8Array(signature.length);\n for (let i = 0; i < signature.length; i++) encoded[i] = signature.charCodeAt(i);\n const hash = keccak_256(encoded);\n const selector = bytesToHex(hash.subarray(0, 4));\n\n return { selector, types };\n}\n\n/** ABI function signature parser. */\nexport const SignatureParser = { parse };\n","import { bytesToHex, hexToBytes, readU16 } from \"./bytes\";\nimport { Scope, TypeCode, isQuantifier, MAX_CONTEXT_PROPERTY_ID } from \"./constants\";\nimport { ConstraintBuilder } from \"./constraint\";\nimport { Descriptor } from \"./descriptor\";\nimport { DescriptorCoder } from \"./descriptor-coder\";\nimport { CallciumError } from \"./errors\";\nimport { PolicyCoder, parsePathSteps } from \"./policy-coder\";\nimport { PolicyValidator } from \"./policy-validator\";\nimport { SignatureParser } from \"./signature\";\n\nimport type { Constraint, Hex, Issue, PolicyData } from \"./types\";\n\n///////////////////////////////////////////////////////////////////////////\n// Internal types\n///////////////////////////////////////////////////////////////////////////\n\ntype PolicyDraft = {\n isSelectorless: boolean;\n selector: Hex;\n descriptor: Uint8Array;\n groups: Constraint[][];\n pathHashes: Set<string>[];\n};\n\n///////////////////////////////////////////////////////////////////////////\n// Path validation\n///////////////////////////////////////////////////////////////////////////\n\n/** Validate a context-scope path. */\nfunction validateContextPath(pathBytes: Uint8Array): void {\n if (pathBytes.length !== 2) {\n throw new CallciumError(\"INVALID_CONTEXT_PATH\", \"Context-scope path must be exactly one step (2 bytes).\");\n }\n const step = readU16(pathBytes, 0);\n if (step > MAX_CONTEXT_PROPERTY_ID) {\n throw new CallciumError(\n \"INVALID_CONTEXT_PROPERTY\",\n `Unknown context property ID 0x${step.toString(16).padStart(4, \"0\")}.`,\n );\n }\n}\n\n/** Validate a calldata-scope path against the descriptor. */\nfunction validateCalldataPath(path: Hex, desc: Uint8Array): void {\n const steps = parsePathSteps(path);\n if (steps.length === 0) {\n throw new CallciumError(\"INVALID_PATH\", \"Calldata path must have at least one step.\");\n }\n\n const argIndex = steps[0]!;\n const paramCount = Descriptor.paramCount(desc);\n if (argIndex >= paramCount) {\n throw new CallciumError(\n \"INVALID_PATH\",\n `Argument index ${argIndex} out of range (descriptor has ${paramCount} params).`,\n );\n }\n\n let offset = Descriptor.paramOffset(desc, argIndex);\n let hasQuantifier = false;\n\n for (let i = 1; i < steps.length; i++) {\n const step = steps[i]!;\n const info = Descriptor.inspect(desc, offset);\n\n if (info.typeCode === TypeCode.TUPLE) {\n if (isQuantifier(step)) {\n throw new CallciumError(\"INVALID_PATH\", \"Quantifier step is not valid on a tuple node.\");\n }\n const fieldCount = Descriptor.tupleFieldCount(desc, offset);\n if (step >= fieldCount) {\n throw new CallciumError(\n \"INVALID_PATH\",\n `Tuple field index ${step} out of range (tuple has ${fieldCount} fields).`,\n );\n }\n offset = Descriptor.tupleFieldOffset(desc, offset, step);\n } else if (info.typeCode === TypeCode.STATIC_ARRAY || info.typeCode === TypeCode.DYNAMIC_ARRAY) {\n if (isQuantifier(step)) {\n if (hasQuantifier) {\n throw new CallciumError(\"INVALID_PATH\", \"Nested quantifiers are not allowed.\");\n }\n hasQuantifier = true;\n } else if (info.typeCode === TypeCode.STATIC_ARRAY) {\n const arrayLength = Descriptor.staticArrayLength(desc, offset);\n if (step >= arrayLength) {\n throw new CallciumError(\n \"INVALID_PATH\",\n `Array index ${step} out of range (static array has ${arrayLength} elements).`,\n );\n }\n }\n offset = Descriptor.arrayElementOffset(offset);\n } else {\n throw new CallciumError(\"INVALID_PATH\", \"Cannot descend into an elementary type.\");\n }\n }\n}\n\n///////////////////////////////////////////////////////////////////////////\n// PolicyBuilder\n///////////////////////////////////////////////////////////////////////////\n\n/** Fluent builder for constructing Callcium policies. */\nexport class PolicyBuilder {\n private draft: PolicyDraft;\n\n private constructor(draft: PolicyDraft) {\n this.draft = draft;\n }\n\n /**\n * Create a builder from a function signature.\n * @param signature - ABI function signature, e.g. `\"transfer(address,uint256)\"`.\n */\n static create(signature: string): PolicyBuilder {\n const parsed = SignatureParser.parse(signature);\n const descriptor = DescriptorCoder.fromTypes(parsed.types);\n return new PolicyBuilder({\n isSelectorless: false,\n selector: parsed.selector,\n descriptor,\n groups: [[]],\n pathHashes: [new Set()],\n });\n }\n\n /**\n * Create a selectorless builder from a raw type string.\n * @param typesCsv - Comma-separated ABI type strings, e.g. `\"address,uint256\"`.\n */\n static createRaw(typesCsv: string): PolicyBuilder {\n const descriptor = DescriptorCoder.fromTypes(typesCsv);\n return new PolicyBuilder({\n isSelectorless: true,\n selector: \"0x00000000\",\n descriptor,\n groups: [[]],\n pathHashes: [new Set()],\n });\n }\n\n /**\n * Add a constraint to the current group.\n * @param constraint - A `Constraint` object or a `ConstraintBuilder` instance.\n */\n add(constraint: Constraint | ConstraintBuilder): this {\n const c: Constraint = {\n scope: constraint.scope,\n path: constraint.path,\n operators: [...constraint.operators],\n };\n\n if (c.operators.length === 0) {\n throw new CallciumError(\"INVALID_CONSTRAINT\", \"Constraint must have at least one operator.\");\n }\n\n if (c.scope === Scope.CONTEXT) {\n validateContextPath(hexToBytes(c.path));\n } else if (c.scope === Scope.CALLDATA) {\n validateCalldataPath(c.path, this.draft.descriptor);\n } else {\n throw new CallciumError(\"INVALID_SCOPE\", `Unknown scope value ${c.scope}.`);\n }\n\n const key = `${c.scope}:${c.path.toLowerCase()}`;\n const currentHashes = this.draft.pathHashes[this.draft.pathHashes.length - 1]!;\n if (currentHashes.has(key)) {\n throw new CallciumError(\"DUPLICATE_PATH\", `Duplicate path ${c.path} in the same group.`);\n }\n\n currentHashes.add(key);\n this.draft.groups[this.draft.groups.length - 1]!.push(c);\n return this;\n }\n\n /** Start a new constraint group (OR branch). */\n or(): this {\n const lastGroup = this.draft.groups[this.draft.groups.length - 1]!;\n if (lastGroup.length === 0) {\n throw new CallciumError(\"EMPTY_GROUP\", \"Cannot start a new group when the current group is empty.\");\n }\n this.draft.groups.push([]);\n this.draft.pathHashes.push(new Set());\n return this;\n }\n\n /**\n * Build the policy into an encoded binary blob.\n * @returns The policy as a 0x-prefixed hex string.\n * @throws {CallciumError} If any group is empty or validation finds errors.\n */\n build(): Hex {\n this.checkGroups();\n const policyData = this.toPolicyData();\n const issues = PolicyValidator.validate(policyData);\n const firstError = issues.find((issue) => issue.severity === \"error\");\n if (firstError) {\n throw new CallciumError(\"VALIDATION_ERROR\", firstError.message);\n }\n return PolicyCoder.encode(policyData);\n }\n\n /**\n * Validate the policy without encoding.\n * @returns All validation issues found.\n */\n validate(): Issue[] {\n this.checkGroups();\n const policyData = this.toPolicyData();\n return PolicyValidator.validate(policyData);\n }\n\n /** Throw if any group is empty. */\n private checkGroups(): void {\n for (let i = 0; i < this.draft.groups.length; i++) {\n if (this.draft.groups[i]!.length === 0) {\n throw new CallciumError(\"EMPTY_GROUP\", `Group ${i} is empty.`);\n }\n }\n }\n\n /** Convert the draft to a PolicyData structure. */\n private toPolicyData(): PolicyData {\n return {\n isSelectorless: this.draft.isSelectorless,\n selector: this.draft.selector,\n descriptor: bytesToHex(this.draft.descriptor),\n groups: this.draft.groups,\n };\n }\n}\n","import { bytesToHex, writeBE16 } from \"./bytes\";\nimport { Op, Scope, ContextProperty } from \"./constants\";\nimport { CallciumError } from \"./errors\";\n\nimport type { Hex, Constraint } from \"./types\";\n\n///////////////////////////////////////////////////////////////////////////\n// Value encoding helpers\n///////////////////////////////////////////////////////////////////////////\n\n/** Accepted scalar value types for operator arguments. */\nexport type ScalarValue = bigint | number | boolean | string;\n\n/** Convert a scalar value to a 32-byte big-endian word. */\nfunction encodeWord(value: ScalarValue): Uint8Array {\n const word = new Uint8Array(32);\n\n if (typeof value === \"boolean\") {\n word[31] = value ? 1 : 0;\n return word;\n }\n\n if (typeof value === \"string\") {\n // Address encoding: validate 20-byte hex and right-align into 32 bytes.\n const body = value.startsWith(\"0x\") ? value.slice(2) : value;\n if (body.length !== 40) {\n throw new CallciumError(\n \"INVALID_CONSTRAINT\",\n `Invalid address length: expected 40 hex chars, got ${body.length}`,\n );\n }\n for (let i = 0; i < 20; i++) {\n const byte = parseInt(body.substring(i * 2, i * 2 + 2), 16);\n if (Number.isNaN(byte)) {\n throw new CallciumError(\"INVALID_CONSTRAINT\", `Invalid hex character in address at position ${i * 2}`);\n }\n word[12 + i] = byte;\n }\n return word;\n }\n\n // bigint | number — unsigned 256-bit big-endian.\n let bigValue = typeof value === \"number\" ? BigInt(value) : value;\n for (let i = 31; i >= 0; i--) {\n word[i] = Number(bigValue & 0xffn);\n bigValue >>= 8n;\n }\n return word;\n}\n\n/** Pack a scalar value as a hex operator payload (opCode byte + 32-byte word). */\nfunction singleOp(opCode: number, value: ScalarValue): Hex {\n const buffer = new Uint8Array(33);\n buffer[0] = opCode;\n buffer.set(encodeWord(value), 1);\n return bytesToHex(buffer);\n}\n\n/** Pack a range operator (opCode byte + min word + max word). */\nfunction rangeOp(opCode: number, min: bigint, max: bigint): Hex {\n if (min > max) {\n throw new CallciumError(\"INVALID_RANGE\", `Range min (${min}) must not exceed max (${max})`);\n }\n const buffer = new Uint8Array(65);\n buffer[0] = opCode;\n buffer.set(encodeWord(min), 1);\n buffer.set(encodeWord(max), 33);\n return bytesToHex(buffer);\n}\n\n/** Convert values to bigint, sort ascending (unsigned), deduplicate, and pack as set payload. */\nfunction setOp(opCode: number, values: readonly ScalarValue[]): Hex {\n const bigs = values.map((v) => {\n if (typeof v === \"bigint\") return v;\n if (typeof v === \"number\") return BigInt(v);\n if (typeof v === \"boolean\") return v ? 1n : 0n;\n // String address.\n const body = v.startsWith(\"0x\") ? v.slice(2) : v;\n return BigInt(\"0x\" + (body || \"0\"));\n });\n\n bigs.sort((a, b) => (a < b ? -1 : a > b ? 1 : 0));\n\n const deduped: bigint[] = [];\n for (const value of bigs) {\n if (deduped.length === 0 || deduped[deduped.length - 1] !== value) {\n deduped.push(value);\n }\n }\n\n if (deduped.length === 0) {\n throw new CallciumError(\"EMPTY_SET\", \"Set must contain at least one value\");\n }\n\n const buffer = new Uint8Array(1 + deduped.length * 32);\n buffer[0] = opCode;\n for (let i = 0; i < deduped.length; i++) {\n buffer.set(encodeWord(deduped[i]!), 1 + i * 32);\n }\n return bytesToHex(buffer);\n}\n\n///////////////////////////////////////////////////////////////////////////\n// Path encoding\n///////////////////////////////////////////////////////////////////////////\n\n/** Encode a sequence of uint16 path steps as a big-endian hex string. */\nfunction encodePath(steps: readonly number[]): Hex {\n const buffer = new Uint8Array(steps.length * 2);\n for (let i = 0; i < steps.length; i++) {\n writeBE16(buffer, i * 2, steps[i]!);\n }\n return bytesToHex(buffer);\n}\n\n///////////////////////////////////////////////////////////////////////////\n// ConstraintBuilder\n///////////////////////////////////////////////////////////////////////////\n\n/**\n * Mutable builder that accumulates operators targeting a single path.\n * Implements the `Constraint` interface so it can be passed directly to policy builders.\n */\nexport class ConstraintBuilder implements Constraint {\n readonly scope: number;\n readonly path: Hex;\n readonly operators: Hex[];\n\n /** @internal */\n constructor(scope: number, path: Hex) {\n this.scope = scope;\n this.path = path;\n this.operators = [];\n }\n\n /** Push a pre-encoded operator hex string and return this for chaining. */\n private push(opHex: Hex): this {\n this.operators.push(opHex);\n return this;\n }\n\n ///////////////////////////////////////////////////////////////////////////\n // Value operators\n ///////////////////////////////////////////////////////////////////////////\n\n /** Assert the value equals `value`. */\n eq(value: ScalarValue): this {\n return this.push(singleOp(Op.EQ, value));\n }\n\n /** Assert the value does not equal `value`. */\n neq(value: ScalarValue): this {\n return this.push(singleOp(Op.EQ | Op.NOT, value));\n }\n\n /** Assert the value is greater than `bound`. */\n gt(bound: bigint | number): this {\n return this.push(singleOp(Op.GT, bound));\n }\n\n /** Assert the value is less than `bound`. */\n lt(bound: bigint | number): this {\n return this.push(singleOp(Op.LT, bound));\n }\n\n /** Assert the value is greater than or equal to `bound`. */\n gte(bound: bigint | number): this {\n return this.push(singleOp(Op.GTE, bound));\n }\n\n /** Assert the value is less than or equal to `bound`. */\n lte(bound: bigint | number): this {\n return this.push(singleOp(Op.LTE, bound));\n }\n\n /**\n * Assert the value is within [min, max] inclusive.\n * @throws {CallciumError} If min > max.\n */\n between(min: bigint | number, max: bigint | number): this {\n return this.push(rangeOp(Op.BETWEEN, BigInt(min), BigInt(max)));\n }\n\n ///////////////////////////////////////////////////////////////////////////\n // Set membership\n ///////////////////////////////////////////////////////////////////////////\n\n /**\n * Assert the value is a member of the set.\n * Values are sorted and deduplicated before encoding.\n * @throws {CallciumError} If the set is empty after deduplication.\n */\n isIn(values: readonly ScalarValue[]): this {\n return this.push(setOp(Op.IN, values));\n }\n\n /**\n * Assert the value is not a member of the set.\n * @throws {CallciumError} If the set is empty after deduplication.\n */\n notIn(values: readonly ScalarValue[]): this {\n return this.push(setOp(Op.IN | Op.NOT, values));\n }\n\n ///////////////////////////////////////////////////////////////////////////\n // Bitmask operators\n ///////////////////////////////////////////////////////////////////////////\n\n /** Assert all bits in `mask` are set. */\n bitmaskAll(mask: bigint): this {\n return this.push(singleOp(Op.BITMASK_ALL, mask));\n }\n\n /** Assert at least one bit in `mask` is set. */\n bitmaskAny(mask: bigint): this {\n return this.push(singleOp(Op.BITMASK_ANY, mask));\n }\n\n /** Assert no bit in `mask` is set. */\n bitmaskNone(mask: bigint): this {\n return this.push(singleOp(Op.BITMASK_NONE, mask));\n }\n\n ///////////////////////////////////////////////////////////////////////////\n // Length operators\n ///////////////////////////////////////////////////////////////////////////\n\n /** Assert the runtime length equals `n`. */\n lengthEq(n: bigint | number): this {\n return this.push(singleOp(Op.LENGTH_EQ, n));\n }\n\n /** Assert the runtime length is greater than `n`. */\n lengthGt(n: bigint | number): this {\n return this.push(singleOp(Op.LENGTH_GT, n));\n }\n\n /** Assert the runtime length is less than `n`. */\n lengthLt(n: bigint | number): this {\n return this.push(singleOp(Op.LENGTH_LT, n));\n }\n\n /** Assert the runtime length is greater than or equal to `n`. */\n lengthGte(n: bigint | number): this {\n return this.push(singleOp(Op.LENGTH_GTE, n));\n }\n\n /** Assert the runtime length is less than or equal to `n`. */\n lengthLte(n: bigint | number): this {\n return this.push(singleOp(Op.LENGTH_LTE, n));\n }\n\n /**\n * Assert the runtime length is within [min, max] inclusive.\n * @throws {CallciumError} If min > max.\n */\n lengthBetween(min: bigint | number, max: bigint | number): this {\n return this.push(rangeOp(Op.LENGTH_BETWEEN, BigInt(min), BigInt(max)));\n }\n}\n\n///////////////////////////////////////////////////////////////////////////\n// Target factories\n///////////////////////////////////////////////////////////////////////////\n\n/**\n * Target a calldata argument by path.\n * Each argument is a big-endian uint16 step; multiple steps navigate into nested types.\n */\nexport function arg(p0: number): ConstraintBuilder;\nexport function arg(p0: number, p1: number): ConstraintBuilder;\nexport function arg(p0: number, p1: number, p2: number): ConstraintBuilder;\nexport function arg(p0: number, p1: number, p2: number, p3: number): ConstraintBuilder;\nexport function arg(...steps: number[]): ConstraintBuilder {\n return new ConstraintBuilder(Scope.CALLDATA, encodePath(steps));\n}\n\n/** Target the `msg.sender` context property. */\nexport function msgSender(): ConstraintBuilder {\n return new ConstraintBuilder(Scope.CONTEXT, encodePath([ContextProperty.MSG_SENDER]));\n}\n\n/** Target the `msg.value` context property. */\nexport function msgValue(): ConstraintBuilder {\n return new ConstraintBuilder(Scope.CONTEXT, encodePath([ContextProperty.MSG_VALUE]));\n}\n\n/** Target the `block.timestamp` context property. */\nexport function blockTimestamp(): ConstraintBuilder {\n return new ConstraintBuilder(Scope.CONTEXT, encodePath([ContextProperty.BLOCK_TIMESTAMP]));\n}\n\n/** Target the `block.number` context property. */\nexport function blockNumber(): ConstraintBuilder {\n return new ConstraintBuilder(Scope.CONTEXT, encodePath([ContextProperty.BLOCK_NUMBER]));\n}\n\n/** Target the `block.chainid` context property. */\nexport function chainId(): ConstraintBuilder {\n return new ConstraintBuilder(Scope.CONTEXT, encodePath([ContextProperty.CHAIN_ID]));\n}\n\n/** Target the `tx.origin` context property. */\nexport function txOrigin(): ConstraintBuilder {\n return new ConstraintBuilder(Scope.CONTEXT, encodePath([ContextProperty.TX_ORIGIN]));\n}\n","import { readU16 } from \"./bytes\";\nimport { isQuantifier } from \"./constants\";\nimport { CallciumError } from \"./errors\";\n\nimport type { DescNode, DynamicArrayNode, StaticArrayNode, TupleNode, ViolationCode } from \"./types\";\n\n///////////////////////////////////////////////////////////////////////////\n// Result types\n///////////////////////////////////////////////////////////////////////////\n\n/** Generic result type for operations that can fail with a violation code. */\nexport type Result<T> = ({ ok: true } & T) | { ok: false; code: ViolationCode };\n\n/** Result of a calldata read: success with data, or failure with a violation code. */\nexport type ReadResult<T> = T | { code: ViolationCode };\n\n/** A resolved position within calldata, pairing a descriptor node with its ABI head and base offsets. */\nexport type Location = {\n /** Byte offset of the node's head (value slot for static, pointer slot for dynamic). */\n head: number;\n /** Composite start for resolving composite-relative offsets. */\n base: number;\n node: DescNode;\n};\n\n/** Structural info for an array at a resolved location, pre-computed for element iteration. */\nexport type ArrayShape = {\n length: number;\n elementNode: DescNode;\n elementIsDynamic: boolean;\n elementStaticSize: number;\n headsBase: number;\n dataOffset: number;\n compositeBase: number;\n};\n\n/** Result when locate encounters a quantifier step in the path. */\nexport type QuantifierResult = {\n quantifier: number;\n location: Location;\n remainingPath: Uint8Array;\n};\n\n/** Result of locating a path target. */\nexport type LocateResult =\n | { ok: true; type: \"leaf\"; location: Location }\n | { ok: true; type: \"quantifier\"; quantifier: QuantifierResult }\n | { ok: false; code: ViolationCode };\n\n/** Result of computing array shape. */\nexport type ArrayShapeResult = Result<{ shape: ArrayShape }>;\n\n/** Result of resolving an array element location. */\nexport type LocationResult = Result<{ location: Location }>;\n\n/** Result of loading a scalar value. */\nexport type LoadResult = Result<{ value: Uint8Array }>;\n\n/** Dynamic sequence payload: data offset and logical length (bytes for bytes/string, elements for arrays). */\nexport type SliceResult = Result<{ dataOffset: number; length: number }>;\n\n///////////////////////////////////////////////////////////////////////////\n// Calldata reading primitives\n///////////////////////////////////////////////////////////////////////////\n\n/** Read 32 bytes at offset, bounds-checked. */\nexport function load32(callData: Uint8Array, offset: number): ReadResult<Uint8Array> {\n if (offset < 0 || offset + 32 > callData.length) {\n return { code: \"CALLDATA_OUT_OF_BOUNDS\" };\n }\n return callData.subarray(offset, offset + 32);\n}\n\n/**\n * Read ABI pointer (offset or length) from a 32-byte slot.\n * Validates high 28 bytes are zero (rejects values > 32-bit).\n */\nexport function readPointer(callData: Uint8Array, head: number): ReadResult<number> {\n const word = load32(callData, head);\n if (word instanceof Uint8Array) {\n for (let i = 0; i < 28; i++) {\n if (word[i] !== 0) return { code: \"CALLDATA_OUT_OF_BOUNDS\" };\n }\n return ((word[28]! << 24) | (word[29]! << 16) | (word[30]! << 8) | word[31]!) >>> 0;\n }\n return word; // propagate CALLDATA_OUT_OF_BOUNDS\n}\n\n///////////////////////////////////////////////////////////////////////////\n// Internal helpers\n///////////////////////////////////////////////////////////////////////////\n\n/** Return the number of bytes this node occupies in the head region. */\nfunction headContribution(node: DescNode): number {\n return node.isDynamic ? 32 : node.staticSize;\n}\n\n/** Read a single BE16 path step at the given step index. */\nfunction readStep(pathBytes: Uint8Array, stepIndex: number): number {\n return readU16(pathBytes, stepIndex * 2);\n}\n\n///////////////////////////////////////////////////////////////////////////\n// Single-step descent\n///////////////////////////////////////////////////////////////////////////\n\ntype DescendResult =\n | { type: \"ok\"; head: number; base: number; node: DescNode }\n | { type: \"violation\"; code: ViolationCode };\n\n/** Navigate one path step through a node (tuple field, array element, or quantifier). */\nfunction descend(node: DescNode, callData: Uint8Array, head: number, base: number, childIndex: number): DescendResult {\n if (node.type === \"tuple\") {\n return descendTuple(node, callData, head, base, childIndex);\n }\n if (node.type === \"dynamicArray\") {\n return descendDynamicArray(node, callData, head, base, childIndex);\n }\n if (node.type === \"staticArray\") {\n return descendStaticArray(node, callData, head, base, childIndex);\n }\n throw new CallciumError(\"INVALID_PATH\", `Cannot descend into elementary type (${node.type}).`);\n}\n\n/** Descend into a tuple field by index. */\nfunction descendTuple(\n node: TupleNode,\n callData: Uint8Array,\n head: number,\n base: number,\n childIndex: number,\n): DescendResult {\n if (childIndex >= node.fields.length) {\n throw new CallciumError(\n \"INVALID_PATH\",\n `Tuple field index ${childIndex} out of range (${node.fields.length} fields).`,\n );\n }\n\n let tupleBase: number;\n let cursor: number;\n\n if (node.isDynamic) {\n const ptrResult = readPointer(callData, head);\n if (typeof ptrResult !== \"number\") return { type: \"violation\", code: ptrResult.code };\n tupleBase = base + ptrResult;\n cursor = tupleBase;\n } else {\n tupleBase = base;\n cursor = head;\n }\n\n for (let i = 0; i < childIndex; i++) {\n cursor += headContribution(node.fields[i]!);\n }\n\n return {\n type: \"ok\",\n head: cursor,\n base: tupleBase,\n node: node.fields[childIndex]!,\n };\n}\n\n/** Descend into a dynamic array element by index. */\nfunction descendDynamicArray(\n node: DynamicArrayNode,\n callData: Uint8Array,\n head: number,\n base: number,\n childIndex: number,\n): DescendResult {\n const arrayBaseResult = readPointer(callData, head);\n if (typeof arrayBaseResult !== \"number\") return { type: \"violation\", code: arrayBaseResult.code };\n const arrayBase = base + arrayBaseResult;\n\n const lengthResult = readPointer(callData, arrayBase);\n if (typeof lengthResult !== \"number\") return { type: \"violation\", code: lengthResult.code };\n\n if (childIndex >= lengthResult) {\n return { type: \"violation\", code: \"ARRAY_INDEX_OUT_OF_BOUNDS\" };\n }\n\n const headsBase = arrayBase + 32;\n const elem = node.element;\n\n if (elem.isDynamic) {\n return {\n type: \"ok\",\n head: headsBase + childIndex * 32,\n base: headsBase,\n node: elem,\n };\n }\n return {\n type: \"ok\",\n head: headsBase + childIndex * elem.staticSize,\n base: arrayBase,\n node: elem,\n };\n}\n\n/** Descend into a static array element by index. */\nfunction descendStaticArray(\n node: StaticArrayNode,\n callData: Uint8Array,\n head: number,\n base: number,\n childIndex: number,\n): DescendResult {\n if (childIndex >= node.length) {\n throw new CallciumError(\"INVALID_PATH\", `Static array index ${childIndex} out of range (length ${node.length}).`);\n }\n\n const elem = node.element;\n\n if (elem.isDynamic) {\n const ptrResult = readPointer(callData, head);\n if (typeof ptrResult !== \"number\") return { type: \"violation\", code: ptrResult.code };\n const arrayBase = base + ptrResult;\n return {\n type: \"ok\",\n head: arrayBase + childIndex * 32,\n base: arrayBase,\n node: elem,\n };\n }\n return {\n type: \"ok\",\n head: head + childIndex * elem.staticSize,\n base,\n node: elem,\n };\n}\n\n///////////////////////////////////////////////////////////////////////////\n// Composable API\n///////////////////////////////////////////////////////////////////////////\n\n/**\n * Resolve a path to a calldata location, stopping at a leaf or quantifier.\n *\n * The path is a sequence of BE16 steps. The first step selects the top-level\n * parameter; subsequent steps descend into tuples and arrays. If a quantifier\n * step is encountered, returns a QuantifierResult with the array location and\n * remaining path suffix.\n */\nexport function locate(\n tree: DescNode[],\n callData: Uint8Array,\n pathBytes: Uint8Array,\n baseOffset: number,\n): LocateResult {\n const stepCount = pathBytes.length / 2;\n if (stepCount === 0) {\n throw new CallciumError(\"INVALID_PATH\", \"Path is empty.\");\n }\n\n // Step 0: resolve the target parameter.\n const paramIndex = readStep(pathBytes, 0);\n if (paramIndex >= tree.length) {\n throw new CallciumError(\"INVALID_PATH\", `Param index ${paramIndex} out of range (${tree.length} params).`);\n }\n\n let head = baseOffset;\n for (let i = 0; i < paramIndex; i++) {\n head += headContribution(tree[i]!);\n }\n let base = baseOffset;\n let node = tree[paramIndex]!;\n\n // Steps 1..N: descend through the tree.\n for (let s = 1; s < stepCount; s++) {\n const step = readStep(pathBytes, s);\n\n // Quantifier step: return the array location and remaining path.\n if (isQuantifier(step)) {\n const remaining = pathBytes.subarray((s + 1) * 2);\n // Defence-in-depth: reject nested quantifiers in hand-crafted blobs.\n for (let r = 0; r < remaining.length / 2; r++) {\n if (isQuantifier(readStep(remaining, r))) {\n throw new CallciumError(\"INVALID_QUANTIFIER\", \"Nested quantifiers are not supported.\");\n }\n }\n return {\n ok: true,\n type: \"quantifier\",\n quantifier: {\n quantifier: step,\n location: { head, base, node },\n remainingPath: remaining,\n },\n };\n }\n\n const result = descend(node, callData, head, base, step);\n if (result.type === \"violation\") return { ok: false, code: result.code };\n head = result.head;\n base = result.base;\n node = result.node;\n }\n\n return { ok: true, type: \"leaf\", location: { head, base, node } };\n}\n\n/** Extract array shape from a location pointing to an array node. */\nexport function arrayShape(callData: Uint8Array, location: Location): ArrayShapeResult {\n const { head, base, node } = location;\n\n if (node.type === \"dynamicArray\") {\n const arrayBaseResult = readPointer(callData, head);\n if (typeof arrayBaseResult !== \"number\") return { ok: false, code: arrayBaseResult.code };\n const arrayBase = base + arrayBaseResult;\n\n const lengthResult = readPointer(callData, arrayBase);\n if (typeof lengthResult !== \"number\") return { ok: false, code: lengthResult.code };\n\n const elem = node.element;\n const headsBase = arrayBase + 32;\n\n if (elem.isDynamic) {\n return {\n ok: true,\n shape: {\n length: lengthResult,\n elementNode: elem,\n elementIsDynamic: true,\n elementStaticSize: 0,\n headsBase,\n dataOffset: 0,\n compositeBase: headsBase,\n },\n };\n }\n return {\n ok: true,\n shape: {\n length: lengthResult,\n elementNode: elem,\n elementIsDynamic: false,\n elementStaticSize: elem.staticSize,\n headsBase: 0,\n dataOffset: headsBase,\n compositeBase: arrayBase,\n },\n };\n }\n\n if (node.type === \"staticArray\") {\n const elem = node.element;\n\n if (elem.isDynamic) {\n const arrayBaseResult = readPointer(callData, head);\n if (typeof arrayBaseResult !== \"number\") return { ok: false, code: arrayBaseResult.code };\n const arrayBase = base + arrayBaseResult;\n return {\n ok: true,\n shape: {\n length: node.length,\n elementNode: elem,\n elementIsDynamic: true,\n elementStaticSize: 0,\n headsBase: arrayBase,\n dataOffset: 0,\n compositeBase: arrayBase,\n },\n };\n }\n return {\n ok: true,\n shape: {\n length: node.length,\n elementNode: elem,\n elementIsDynamic: false,\n elementStaticSize: elem.staticSize,\n headsBase: 0,\n dataOffset: head,\n compositeBase: base,\n },\n };\n }\n\n throw new CallciumError(\"INVALID_PATH\", `Cannot compute array shape for non-array node (${node.type}).`);\n}\n\n/** Compute the location for element N within a precomputed array shape. */\nexport function arrayElementAt(shape: ArrayShape, index: number, callData: Uint8Array): LocationResult {\n if (index >= shape.length) {\n return { ok: false, code: \"ARRAY_INDEX_OUT_OF_BOUNDS\" };\n }\n\n let head: number;\n let base: number;\n\n if (!shape.elementIsDynamic) {\n head = shape.dataOffset + index * shape.elementStaticSize;\n base = shape.compositeBase;\n } else {\n head = shape.headsBase + index * 32;\n base = shape.headsBase;\n }\n\n if (head + 32 > callData.length) {\n return { ok: false, code: \"CALLDATA_OUT_OF_BOUNDS\" };\n }\n\n return {\n ok: true,\n location: { head, base, node: shape.elementNode },\n };\n}\n\n/** Load a 32-byte scalar value from a resolved location. */\nexport function loadScalar(callData: Uint8Array, location: Location): LoadResult {\n const result = load32(callData, location.head);\n if (result instanceof Uint8Array) {\n return { ok: true, value: result };\n }\n return { ok: false, code: result.code };\n}\n\n/** Load the data offset and logical length for a dynamic type (bytes, string, or dynamic array). */\nexport function loadSlice(callData: Uint8Array, location: Location): SliceResult {\n const ptrResult = readPointer(callData, location.head);\n if (typeof ptrResult !== \"number\") return { ok: false, code: ptrResult.code };\n\n const dataStart = location.base + ptrResult;\n const lengthResult = readPointer(callData, dataStart);\n if (typeof lengthResult !== \"number\") return { ok: false, code: lengthResult.code };\n\n return { ok: true, dataOffset: dataStart + 32, length: lengthResult };\n}\n\n/** Continue navigating through additional path steps from a resolved location. */\nexport function descendPath(callData: Uint8Array, location: Location, pathBytes: Uint8Array): LocationResult {\n const stepCount = pathBytes.length / 2;\n let { head, base, node } = location;\n\n for (let s = 0; s < stepCount; s++) {\n const step = readStep(pathBytes, s);\n const result = descend(node, callData, head, base, step);\n if (result.type === \"violation\") return { ok: false, code: result.code };\n head = result.head;\n base = result.base;\n node = result.node;\n }\n\n return { ok: true, location: { head, base, node } };\n}\n","import { hexToBytes, bytesToHex, readU16, bigintToHex } from \"./bytes\";\nimport {\n PolicyFormat as PF,\n Scope,\n MAX_CONTEXT_PROPERTY_ID,\n Limits,\n Quantifier,\n TypeCode,\n Op,\n lookupOp,\n lookupContextProperty,\n} from \"./constants\";\nimport { CallciumError, PolicyViolationError } from \"./errors\";\nimport { applyOperator, toBigInt, isLengthOp } from \"./operators\";\nimport { decodePolicy } from \"./policy-coder\";\nimport { locate, arrayShape, arrayElementAt, loadScalar, loadSlice, descendPath } from \"./reader\";\n\nimport type { Location } from \"./reader\";\nimport type { Context, DescNode, EnforceResult, Hex, Violation, ViolationCode } from \"./types\";\n\n///////////////////////////////////////////////////////////////////////////\n// Helpers\n///////////////////////////////////////////////////////////////////////////\n\n/** Convert a hex address to a 256-bit bigint (zero-padded to 32 bytes). */\nfunction addressToBigInt(hex: string): bigint {\n const bytes = hexToBytes(hex);\n const padded = new Uint8Array(32);\n padded.set(bytes, 32 - bytes.length);\n return toBigInt(padded, 0);\n}\n\n/** Format a bigint as a compact hex string without leading-zero padding. */\nfunction compactHex(value: bigint): string {\n if (value === 0n) return \"0x0\";\n return `0x${value.toString(16)}`;\n}\n\n/** Truncate a hex string to at most maxChars characters, adding ellipsis if needed. */\nfunction truncateHexForMessage(hex: string, maxChars = 66): string {\n if (hex.length <= maxChars) return hex;\n return `${hex.slice(0, maxChars - 1)}…`;\n}\n\n/** Format a decoded operand as decimal for length ops, otherwise compact hex. */\nfunction formatOperandValue(value: bigint, opCode: number): string {\n return isLengthOp(opCode) ? value.toString(10) : compactHex(value);\n}\n\n/** Format the constraint (operator + operands) from a single lookupOp call. */\nfunction formatConstraint(opCode: number, operandData: Uint8Array): string {\n const negated = (opCode & Op.NOT) !== 0;\n const { label, operands } = lookupOp(opCode);\n const op = negated ? `not ${label}` : label;\n\n let formattedOperands: string;\n if (operands === \"variadic\") {\n formattedOperands = `(${operandData.length / 32} values)`;\n } else if (operands === \"range\") {\n const min = toBigInt(operandData, 0);\n const max = toBigInt(operandData, 32);\n formattedOperands = `[${formatOperandValue(min, opCode)}, ${formatOperandValue(max, opCode)}]`;\n } else {\n formattedOperands = formatOperandValue(toBigInt(operandData, 0), opCode);\n }\n\n return `${op} ${formattedOperands}`;\n}\n\n/** Build a self-contained VALUE_MISMATCH message for a scalar or length comparison. */\nfunction mismatchMessage(opCode: number, actual: bigint | number, operandData: Uint8Array): string {\n const display = typeof actual === \"number\" ? String(actual) : truncateHexForMessage(compactHex(actual));\n return `constraint ${formatConstraint(opCode, operandData)} violated by ${display}`;\n}\n\n///////////////////////////////////////////////////////////////////////////\n// Public API\n///////////////////////////////////////////////////////////////////////////\n\n/**\n * Check a policy against ABI-encoded call data without throwing on violations.\n * @param policy - Binary policy blob as 0x-prefixed hex string.\n * @param callData - ABI-encoded call data as 0x-prefixed hex string.\n * @param context - Optional execution context for context-scoped rules.\n * @returns Pass with matched group index, or fail with one violation per failed group.\n * @throws {CallciumError} If the policy blob is structurally malformed.\n */\nfunction check(policy: Hex, callData: Hex, context?: Context): EnforceResult {\n const { policy: decoded, tree } = decodePolicy(policy);\n const callDataBytes = hexToBytes(callData);\n\n // Selector check.\n if (!decoded.isSelectorless) {\n if (callDataBytes.length < 4) {\n return {\n ok: false,\n violations: [\n {\n code: \"MISSING_SELECTOR\",\n message: \"Calldata too short to contain a selector\",\n },\n ],\n };\n }\n const expectedSelector = decoded.selector.value;\n const actualSelector = bytesToHex(callDataBytes.subarray(0, 4));\n if (actualSelector !== expectedSelector) {\n return {\n ok: false,\n violations: [\n {\n code: \"SELECTOR_MISMATCH\",\n message: `Expected selector ${expectedSelector}, got ${actualSelector}`,\n resolvedValue: actualSelector,\n },\n ],\n };\n }\n }\n\n const baseOffset = decoded.isSelectorless ? 0 : PF.SELECTOR_SIZE;\n\n // Evaluate groups with OR semantics.\n const allViolations: Violation[] = [];\n\n for (let groupIndex = 0; groupIndex < decoded.groups.length; groupIndex++) {\n const group = decoded.groups[groupIndex]!;\n let groupFailed = false;\n\n for (let ruleIndex = 0; ruleIndex < group.rules.length; ruleIndex++) {\n const rule = group.rules[ruleIndex]!;\n const violation = evaluateRule(rule, tree, callDataBytes, baseOffset, groupIndex, ruleIndex, context);\n if (violation !== null) {\n allViolations.push(violation);\n groupFailed = true;\n break;\n }\n }\n\n if (!groupFailed) {\n return { ok: true, matchedGroup: groupIndex };\n }\n }\n\n return { ok: false, violations: allViolations };\n}\n\n/**\n * Enforce a policy against ABI-encoded call data, throwing on violation.\n * @param policy - Binary policy blob as 0x-prefixed hex string.\n * @param callData - ABI-encoded call data as 0x-prefixed hex string.\n * @param context - Optional execution context for context-scoped rules.\n * @throws {PolicyViolationError} If the policy rejects the call data.\n * @throws {CallciumError} If the policy blob is structurally malformed.\n */\nfunction enforce(policy: Hex, callData: Hex, context?: Context): void {\n const result = check(policy, callData, context);\n if (!result.ok) {\n throw new PolicyViolationError(result.violations);\n }\n}\n\n///////////////////////////////////////////////////////////////////////////\n// Rule evaluation\n///////////////////////////////////////////////////////////////////////////\n\n/** Evaluate a single rule against calldata or context, returning a violation or null on pass. */\nfunction evaluateRule(\n rule: {\n scope: { value: number };\n path: { value: Hex };\n opCode: { value: number };\n data: { value: Hex };\n },\n tree: DescNode[],\n callDataBytes: Uint8Array,\n baseOffset: number,\n groupIndex: number,\n ruleIndex: number,\n context?: Context,\n): Violation | null {\n const scope = rule.scope.value;\n const pathBytes = hexToBytes(rule.path.value);\n const opCode = rule.opCode.value;\n const operandData = hexToBytes(rule.data.value);\n\n if (pathBytes.length / 2 > Limits.MAX_PATH_DEPTH) {\n throw new CallciumError(\n \"INVALID_PATH\",\n `Path depth ${pathBytes.length / 2} exceeds maximum ${Limits.MAX_PATH_DEPTH}.`,\n );\n }\n\n if (scope === Scope.CONTEXT) {\n return evaluateContextRule(pathBytes, opCode, operandData, groupIndex, ruleIndex, rule.path.value, context);\n }\n\n // Calldata rule: locate the path target.\n const locResult = locate(tree, callDataBytes, pathBytes, baseOffset);\n\n if (!locResult.ok) {\n return {\n group: groupIndex,\n rule: ruleIndex,\n code: locResult.code,\n message: `Navigation failed: ${locResult.code}`,\n path: rule.path.value,\n };\n }\n\n // Quantifier: delegate to composable quantifier evaluator.\n if (locResult.type === \"quantifier\") {\n return evaluateQuantifier(\n locResult.quantifier,\n callDataBytes,\n opCode,\n operandData,\n groupIndex,\n ruleIndex,\n rule.path.value,\n );\n }\n\n // Leaf: evaluate directly.\n return evaluateLeaf(locResult.location, callDataBytes, opCode, operandData, groupIndex, ruleIndex, rule.path.value);\n}\n\n///////////////////////////////////////////////////////////////////////////\n// Context rule evaluation\n///////////////////////////////////////////////////////////////////////////\n\n/** Evaluate a context-scoped rule by resolving the property from the execution context. */\nfunction evaluateContextRule(\n pathBytes: Uint8Array,\n opCode: number,\n operandData: Uint8Array,\n groupIndex: number,\n ruleIndex: number,\n pathHex: Hex,\n context?: Context,\n): Violation | null {\n const propertyId = readU16(pathBytes, 0);\n\n if (propertyId > MAX_CONTEXT_PROPERTY_ID) {\n throw new CallciumError(\n \"INVALID_CONTEXT_PATH\",\n `Unknown context property ID 0x${propertyId.toString(16).padStart(4, \"0\")}`,\n );\n }\n\n const propInfo = lookupContextProperty(propertyId);\n const contextValue = context?.[propInfo.contextKey];\n\n if (contextValue === undefined) {\n return {\n group: groupIndex,\n rule: ruleIndex,\n code: \"MISSING_CONTEXT\",\n message: `Context property ${propInfo.label} not provided`,\n path: pathHex,\n };\n }\n\n let value: bigint;\n if (typeof contextValue === \"string\") {\n value = addressToBigInt(contextValue);\n } else {\n value = contextValue;\n }\n\n const result = applyOperator(opCode, value, 32, operandData, TypeCode.UINT_MAX);\n\n if (!result) {\n return {\n group: groupIndex,\n rule: ruleIndex,\n code: \"VALUE_MISMATCH\",\n message: mismatchMessage(opCode, value, operandData),\n path: pathHex,\n resolvedValue: bigintToHex(value),\n };\n }\n\n return null;\n}\n\n///////////////////////////////////////////////////////////////////////////\n// Core leaf operator\n///////////////////////////////////////////////////////////////////////////\n\ntype LeafResult =\n | { passed: true; value?: bigint; length?: number }\n | { passed: false; value?: bigint; length?: number }\n | { error: ViolationCode };\n\n/** Load a value from calldata at the given location and apply the operator. */\nfunction applyLeafOperator(\n callDataBytes: Uint8Array,\n location: Location,\n opCode: number,\n operandData: Uint8Array,\n): LeafResult {\n const { node } = location;\n\n if (isLengthOp(opCode)) {\n let valueLength: number;\n\n if (node.isDynamic) {\n const lengthResult = loadSlice(callDataBytes, location);\n if (!lengthResult.ok) return { error: lengthResult.code };\n valueLength = lengthResult.length;\n } else {\n valueLength = node.staticSize;\n }\n\n const passed = applyOperator(opCode, 0n, valueLength, operandData, node.typeCode);\n return { passed, length: valueLength };\n }\n\n const result = loadScalar(callDataBytes, location);\n if (!result.ok) return { error: result.code };\n\n const value = toBigInt(result.value, 0);\n const passed = applyOperator(opCode, value, 32, operandData, node.typeCode);\n return { passed, value };\n}\n\n///////////////////////////////////////////////////////////////////////////\n// Leaf evaluation\n///////////////////////////////////////////////////////////////////////////\n\n/** Evaluate a leaf rule, producing a violation on failure or null on pass. */\nfunction evaluateLeaf(\n location: Location,\n callDataBytes: Uint8Array,\n opCode: number,\n operandData: Uint8Array,\n groupIndex: number,\n ruleIndex: number,\n pathHex: Hex,\n): Violation | null {\n const result = applyLeafOperator(callDataBytes, location, opCode, operandData);\n\n if (\"error\" in result) {\n const message = isLengthOp(opCode)\n ? `Failed to read length: ${result.error}`\n : `Failed to load value: ${result.error}`;\n return {\n group: groupIndex,\n rule: ruleIndex,\n code: result.error,\n message,\n path: pathHex,\n };\n }\n\n if (!result.passed) {\n const actual: bigint | number = result.value !== undefined ? result.value : (result.length ?? 0);\n return {\n group: groupIndex,\n rule: ruleIndex,\n code: \"VALUE_MISMATCH\",\n message: mismatchMessage(opCode, actual, operandData),\n path: pathHex,\n resolvedValue: bigintToHex(typeof actual === \"number\" ? BigInt(actual) : actual),\n };\n }\n\n return null;\n}\n\n///////////////////////////////////////////////////////////////////////////\n// Quantifier evaluation\n///////////////////////////////////////////////////////////////////////////\n\n/** Evaluate a quantified rule by iterating over array elements with ALL/ANY semantics. */\nfunction evaluateQuantifier(\n qResult: {\n quantifier: number;\n location: Location;\n remainingPath: Uint8Array;\n },\n callDataBytes: Uint8Array,\n opCode: number,\n operandData: Uint8Array,\n groupIndex: number,\n ruleIndex: number,\n pathHex: Hex,\n): Violation | null {\n const { quantifier, location: arrayLocation, remainingPath } = qResult;\n\n // Compute array shape from the array location.\n const shapeResult = arrayShape(callDataBytes, arrayLocation);\n if (!shapeResult.ok) {\n return {\n group: groupIndex,\n rule: ruleIndex,\n code: shapeResult.code,\n message: `Failed to read array shape: ${shapeResult.code}`,\n path: pathHex,\n };\n }\n const shape = shapeResult.shape;\n\n // Check quantifier limit.\n if (shape.length > Limits.MAX_QUANTIFIED_ARRAY_LENGTH) {\n return {\n group: groupIndex,\n rule: ruleIndex,\n code: \"QUANTIFIER_LIMIT_EXCEEDED\",\n message: `Array length ${shape.length} exceeds maximum ${Limits.MAX_QUANTIFIED_ARRAY_LENGTH}`,\n path: pathHex,\n };\n }\n\n // Empty array semantics.\n if (shape.length === 0) {\n if (quantifier === Quantifier.ALL_OR_EMPTY) {\n return null;\n }\n return {\n group: groupIndex,\n rule: ruleIndex,\n code: \"QUANTIFIER_EMPTY_ARRAY\",\n message: \"Quantifier applied to empty array\",\n path: pathHex,\n };\n }\n\n const isUniversal = quantifier === Quantifier.ALL_OR_EMPTY || quantifier === Quantifier.ALL;\n const hasSuffix = remainingPath.length > 0;\n\n for (let elemIndex = 0; elemIndex < shape.length; elemIndex++) {\n // Resolve element location via arrayElementAt.\n const elemResult = arrayElementAt(shape, elemIndex, callDataBytes);\n if (!elemResult.ok) {\n if (isUniversal) {\n return {\n group: groupIndex,\n rule: ruleIndex,\n code: elemResult.code,\n message: `Quantifier element ${elemIndex}: ${elemResult.code}`,\n path: pathHex,\n };\n }\n continue;\n }\n const elemLocation = elemResult.location;\n\n let elemPassed: boolean;\n\n if (hasSuffix) {\n // Descend through suffix path from element location.\n const leafResult = descendPath(callDataBytes, elemLocation, remainingPath);\n\n if (!leafResult.ok) {\n if (isUniversal) {\n return {\n group: groupIndex,\n rule: ruleIndex,\n code: leafResult.code,\n message: `Quantifier element ${elemIndex} navigation failed: ${leafResult.code}`,\n path: pathHex,\n };\n }\n continue;\n }\n\n elemPassed = evaluateLeafValue(leafResult.location, callDataBytes, opCode, operandData);\n } else {\n // Element itself is the target.\n const leafResult = applyLeafOperator(callDataBytes, elemLocation, opCode, operandData);\n if (\"error\" in leafResult) {\n if (isUniversal) {\n return {\n group: groupIndex,\n rule: ruleIndex,\n code: leafResult.error,\n message: `Quantifier element ${elemIndex}: ${leafResult.error}`,\n path: pathHex,\n };\n }\n continue;\n }\n elemPassed = leafResult.passed;\n }\n\n // Short-circuit.\n if (isUniversal && !elemPassed) {\n return {\n group: groupIndex,\n rule: ruleIndex,\n code: \"VALUE_MISMATCH\",\n message: `constraint ${formatConstraint(opCode, operandData)} violated at element ${elemIndex}`,\n path: pathHex,\n };\n }\n if (!isUniversal && elemPassed) {\n return null;\n }\n }\n\n if (isUniversal) {\n return null;\n }\n return {\n group: groupIndex,\n rule: ruleIndex,\n code: \"VALUE_MISMATCH\",\n message: `constraint ${formatConstraint(opCode, operandData)} violated by all elements`,\n path: pathHex,\n };\n}\n\n///////////////////////////////////////////////////////////////////////////\n// Leaf value evaluation\n///////////////////////////////////////////////////////////////////////////\n\n/** Apply a leaf operator and return a boolean. Returns false on calldata read failure. */\nfunction evaluateLeafValue(\n location: Location,\n callDataBytes: Uint8Array,\n opCode: number,\n operandData: Uint8Array,\n): boolean {\n const result = applyLeafOperator(callDataBytes, location, opCode, operandData);\n if (\"error\" in result) return false;\n return result.passed;\n}\n\n/** Check and enforce policies against ABI-encoded call data. */\nexport const PolicyEnforcer = { check, enforce };\n"],"mappings":"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,iBACA,yBACA,OACA,MACA,6CACD;;;AAIH,SAAgB,qBAAqB,YAAoB,iBAAgC;AACvF,QAAO,UACL,SACA,iBACA,YACA,iBACA,0BACA,MACA,MACA,4CACD;;;AAIH,SAAgB,iBAAiB,YAAoB,iBAAgC;AACnF,QAAO,UACL,SACA,iBACA,YACA,iBACA,sBACA,MACA,MACA,qDACD;;;AAIH,SAAgB,yBAAyB,YAAoB,iBAAyB,OAAmB;AACvG,QAAO,UACL,SACA,iBACA,YACA,iBACA,+BACA,OACA,MACA,4CACD;;;AAIH,SAAgB,kBAAkB,YAAoB,iBAAyB,UAAe,UAAsB;AAClH,QAAO,UACL,SACA,iBACA,YACA,iBACA,sBACA,UACA,UACA,sDACD;;;AAIH,SAAgB,oBAAoB,YAAoB,iBAAyB,IAAS,OAAmB;AAC3G,QAAO,UACL,SACA,iBACA,YACA,iBACA,yBACA,IACA,OACA,wCACD;;;AAIH,SAAgB,sBAAsB,YAAoB,iBAAyB,OAAY,OAAmB;AAChH,QAAO,UACL,SACA,iBACA,YACA,iBACA,2BACA,OACA,OACA,yCACD;;;AAIH,SAAgB,0BAA0B,YAAoB,iBAAyB,OAAmB;AACxG,QAAO,UACL,SACA,iBACA,YACA,iBACA,iCACA,OACA,MACA,6CACD;;;AAIH,SAAgB,mBAAmB,YAAoB,iBAAyB,OAAmB;AACjG,QAAO,UACL,SACA,iBACA,YACA,iBACA,wBACA,OACA,MACA,6CACD;;;AAIH,SAAgB,mBAAmB,YAAoB,iBAAyB,OAAmB;AACjG,QAAO,UACL,SACA,iBACA,YACA,iBACA,wBACA,OACA,MACA,6CACD;;;AAIH,SAAgB,qBAAqB,YAAoB,iBAAyB,MAAW,aAAyB;AACpH,QAAO,UACL,SACA,iBACA,YACA,iBACA,yBACA,MACA,aACA,6BACD;;;AAIH,SAAgB,qBAAqB,YAAoB,iBAAyB,MAAW,YAAwB;AACnH,QAAO,UACL,SACA,iBACA,YACA,iBACA,0BACA,MACA,YACA,0DACD;;;AAIH,SAAgB,cAAc,YAAoB,iBAAgC;AAChF,QAAO,UACL,SACA,iBACA,YACA,iBACA,mBACA,MACA,MACA,0DACD;;;AAIH,SAAgB,WAAW,YAA2B;AACpD,QAAO,UAAU,SAAS,WAAW,YAAY,GAAG,eAAe,MAAM,MAAM,mCAAmC;;;AAQpH,SAAgB,eAAe,YAAoB,iBAAyB,OAAmB;AAC7F,QAAO,UACL,WACA,cACA,YACA,iBACA,mBACA,OACA,MACA,iDACD;;;AAIH,SAAgB,eAAe,YAAoB,iBAAyB,OAAY,IAAgB;AACtG,QAAO,UACL,WACA,cACA,YACA,iBACA,mBACA,OACA,IACA,yCACD;;;AAIH,SAAgB,aAAa,YAAoB,iBAAyB,OAAmB;AAC3F,QAAO,UACL,WACA,cACA,YACA,iBACA,iBACA,OACA,MACA,0CACD;;;AAIH,SAAgB,cAAc,YAAoB,iBAAyB,mBAA+B;AACxG,QAAO,UACL,WACA,cACA,YACA,iBACA,kBACA,mBACA,MACA,gCACD;;;AAIH,SAAgB,qBAAqB,YAAoB,iBAAyB,eAA2B;AAC3G,QAAO,UACL,WACA,cACA,YACA,iBACA,0BACA,eACA,MACA,sDACD;;;AAIH,SAAgB,qBAAqB,YAAoB,iBAAyB,OAAmB;AACnG,QAAO,UACL,WACA,cACA,YACA,iBACA,0BACA,OACA,MACA,gDACD;;;AAIH,SAAgB,qBAAqB,YAAoB,iBAAyB,OAAY,IAAgB;AAC5G,QAAO,UACL,WACA,cACA,YACA,iBACA,0BACA,OACA,IACA,sDACD;;;AAIH,SAAgB,iBAAiB,YAAoB,iBAAyB,MAAW,UAAsB;AAC7G,QAAO,UACL,WACA,cACA,YACA,iBACA,qBACA,MACA,UACA,iCACD;;;AAIH,SAAgB,oBAAoB,YAAoB,iBAAgC;AACtF,QAAO,UACL,WACA,cACA,YACA,iBACA,wBACA,MACA,MACA,mCACD;;;AAQH,SAAgB,WAAW,YAAoB,iBAAyB,OAAmB;AACzF,QAAO,UACL,QACA,WACA,YACA,iBACA,eACA,OACA,MACA,gDACD;;;AAIH,SAAgB,WAAW,YAAoB,iBAAyB,OAAmB;AACzF,QAAO,UACL,QACA,WACA,YACA,iBACA,eACA,OACA,MACA,gDACD;;;AAIH,SAAgB,iBAAiB,YAAoB,iBAAyB,OAAmB;AAC/F,QAAO,UACL,QACA,WACA,YACA,iBACA,sBACA,OACA,MACA,8BACD;;;AAIH,SAAgB,iBAAiB,YAAoB,iBAAyB,OAAmB;AAC/F,QAAO,UACL,QACA,WACA,YACA,iBACA,sBACA,OACA,MACA,iDACD;;;AAQH,SAAgB,YAAY,UAAmB;AAC7C,QAAO;EACL,oBAAoB,WAAW,2BAA2B;EAC1D,aAAa,WAAW,oBAAoB;EAC5C,qBAAqB,WAAW,4BAA4B;EAC5D,cAAc,WAAW,qBAAqB;EAC9C,cAAc,WAAW,qBAAqB;EAC9C,uBAAuB,WAAW,sBAAsB;EACxD,iBAAiB,WAAW,wBAAwB;EACpD,WAAW,WAAW,uBAAuB;EAC7C,WAAW,WAAW,uBAAuB;EAC7C,YAAY,WAAW,mBAAmB;EAC1C,YAAY,WAAW,mBAAmB;EAC3C;;;;;;;;;;;;;;;;;ACvdH,MAAM,YAAY;AAClB,MAAM,aAAa;AACnB,MAAM,aAAa;AAGnB,MAAM,eAAe,MAAM,QAAQ;AACnC,MAAM,kBAAkB,MAAM;;AAO9B,SAAS,SAAS,GAAmB;AACnC,QAAO,KAAK,kBAAkB,KAAK,MAAM,QAAQ;;;AAInD,SAAS,KAAK,GAAW,GAAW,QAA0B;AAC5D,QAAO,SAAS,SAAS,EAAE,GAAG,SAAS,EAAE,GAAG,IAAI;;;AAIlD,SAAS,MAAM,GAAW,GAAW,QAA0B;AAC7D,QAAO,SAAS,SAAS,EAAE,IAAI,SAAS,EAAE,GAAG,KAAK;;;AAIpD,SAAS,KAAK,GAAW,GAAW,QAA0B;AAC5D,QAAO,SAAS,SAAS,EAAE,GAAG,SAAS,EAAE,GAAG,IAAI;;;AAIlD,SAAS,MAAM,GAAW,GAAW,QAA0B;AAC7D,QAAO,SAAS,SAAS,EAAE,IAAI,SAAS,EAAE,GAAG,KAAK;;;AAQpD,SAAS,cAAc,UAA2B;AAChD,QAAO,YAAY,SAAS,YAAa,YAAY,SAAS,WAAW,YAAY,SAAS;;;AAIhG,SAAS,oBAAoB,UAA2B;AACtD,QAAO,YAAY,SAAS,YAAY,aAAa,SAAS,kBAAkB;;;AAIlF,SAAS,gBAAgB,UAAgD;AACvE,KAAI,YAAY,SAAS,UAAU;EACjC,MAAM,OAAO,OAAO,WAAW,SAAS,WAAW,EAAE,GAAG;AACxD,SAAO;GAAE,KAAK;GAAI,KAAK,SAAS,OAAO,eAAe,MAAM,QAAQ;GAAI;;AAE1E,KAAI,YAAY,SAAS,WAAW,YAAY,SAAS,SAAS;EAChE,MAAM,OAAO,OAAO,WAAW,SAAS,UAAU,EAAE,GAAG;AACvD,MAAI,SAAS,KAEX,QAAO;GAAE,KAAK;GAAiB,KAAK,kBAAkB;GAAI;EAE5D,MAAM,OAAO,MAAO,OAAO;EAE3B,MAAM,MAAM,OAAO;AAEnB,SAAO;GAAE,KADI,cAAc,OAAO,KAAM;GAC1B;GAAK;;AAErB,KAAI,aAAa,SAAS,KAAM,QAAO;EAAE,KAAK;EAAI,KAAK;EAAI;AAC3D,KAAI,aAAa,SAAS,QAAS,QAAO;EAAE,KAAK;EAAI,MAAM,MAAM,QAAQ;EAAI;AAC7E,QAAO;EAAE,KAAK;EAAI,KAAK;EAAa;;;AAQtC,SAAS,UAAU,QAAyB;AAC1C,QAAO,UAAU,GAAG;;;AAItB,SAAS,eAAe,QAAyB;AAC/C,QAAO,UAAU,GAAG,MAAM,UAAU,GAAG;;;AAIzC,SAAS,YAAY,QAAyB;AAC5C,QAAO,UAAU,GAAG,eAAe,UAAU,GAAG;;;AAQlD,SAAS,YAAY,QAAgB,UAA8D;CACjG,MAAM,EAAE,UAAU,WAAW,eAAe;AAC5C,KAAI,UAAU,OAAO,EAAE;AACrB,MAAI,aAAa,eAAe,GAC9B,QAAO;GAAE,MAAM;GAAuB,SAAS;GAAuC;AAExF,MAAI,eAAe,OAAO,IAAI,CAAC,cAAc,SAAS,CACpD,QAAO;GAAE,MAAM;GAA6B,SAAS;GAAgD;AAEvG,MAAI,YAAY,OAAO,IAAI,CAAC,oBAAoB,SAAS,CACvD,QAAO;GAAE,MAAM;GAAsB,SAAS;GAA8C;AAE9F,SAAO;;AAET,KAAI,WAAW,OAAO,EAAE;AACtB,MAAI,CAAC,kBAAkB,SAAS,CAC9B,QAAO;GAAE,MAAM;GAAoB,SAAS;GAA4C;AAE1F,SAAO;;AAET,QAAO;EAAE,MAAM;EAAoB,SAAS;EAAyB;;;AAIvE,SAAS,mBACP,QACA,UACA,WACA,YACwD;CACxD,MAAM,WAAW,YAAY,QAAQ;EAAE;EAAU;EAAW;EAAY,CAAC;AACzE,QAAO,WAAW;EAAE,YAAY;EAAO,GAAG;EAAU,GAAG;EAAE,YAAY;EAAM,MAAM;EAAI,SAAS;EAAI;;;;;;AAOpG,SAAgB,YAAY,QAAgB,UAA6B;AACvE,QAAO,YAAY,SAAS,CAAC,GAAG,KAAK,SAAS,KAAK;;;AAQrD,SAAS,UAAU,OAAoB;AACrC,QAAO,OAAO,KAAK,MAAM,MAAM,EAAE,GAAG;;;AAItC,SAAS,SAAS,OAA2C;CAC3D,MAAM,OAAO,MAAM,MAAM,EAAE;AAC3B,QAAO;EACL,KAAK,OAAO,KAAK,KAAK,MAAM,GAAG,GAAG,GAAG;EACrC,MAAM,OAAO,KAAK,KAAK,MAAM,IAAI,IAAI,GAAG;EACzC;;;AAIH,SAAS,UAAU,OAAsB;CACvC,MAAM,OAAO,MAAM,MAAM,EAAE;CAC3B,MAAM,QAAQ,KAAK,SAAS;CAC5B,MAAM,SAAmB,EAAE;AAC3B,MAAK,IAAI,IAAI,GAAG,IAAI,OAAO,IACzB,QAAO,KAAK,OAAO,KAAK,KAAK,MAAM,IAAI,KAAK,IAAI,KAAK,GAAG,GAAG,CAAC;AAE9D,QAAO;;;AAIT,SAAS,oBAAoB,QAA2B;AACtD,MAAK,IAAI,IAAI,GAAG,IAAI,OAAO,QAAQ,IACjC,KAAI,OAAO,MAAO,OAAO,IAAI,GAAK,QAAO;AAE3C,QAAO;;;AAQT,SAAS,kBAAkB,MAAsB;AAC/C,KAAI,SAAS,GAAG,UAAW,QAAO,GAAG;AACrC,KAAI,SAAS,GAAG,UAAW,QAAO,GAAG;AACrC,KAAI,SAAS,GAAG,UAAW,QAAO,GAAG;AACrC,KAAI,SAAS,GAAG,WAAY,QAAO,GAAG;AACtC,KAAI,SAAS,GAAG,WAAY,QAAO,GAAG;AACtC,QAAO;;;AAIT,SAAS,cAAc,MAAsB;AAC3C,KAAI,SAAS,GAAG,GAAI,QAAO,GAAG;AAC9B,KAAI,SAAS,GAAG,IAAK,QAAO,GAAG;AAC/B,KAAI,SAAS,GAAG,GAAI,QAAO,GAAG;AAC9B,KAAI,SAAS,GAAG,IAAK,QAAO,GAAG;AAC/B,QAAO;;;AAQT,SAAS,YAAY,OAAe,MAAW,UAAuC;CACpF,MAAM,EAAE,KAAK,QAAQ,gBAAgB,SAAS,SAAS;AACvD,QAAO;EACL;EACA;EACA;EACA,SAAS;GACP,UAAU,SAAS,SAAS,SAAS;GACrC;GACA;GACA,OAAO;GACP,IAAI;GACJ,UAAU;GACV,OAAO;GACP,gBAAgB;GAChB,UAAU;GACV,OAAO;GACP,gBAAgB;GAChB,OAAO,EAAE;GACV;EACD,SAAS;GAAE,WAAW;GAAI,YAAY;GAAI;EAC1C,QAAQ;GACN,UAAU;GACV,KAAK;GACL,KAAK;GACL,OAAO;GACP,IAAI;GACJ,UAAU;GACV,OAAO;GACP,gBAAgB;GAChB,UAAU;GACV,OAAO;GACP,gBAAgB;GAChB,OAAO,EAAE;GACV;EACD,KAAK;GACH,OAAO;GACP,UAAU,EAAE;GACZ,aAAa,EAAE;GAChB;EACF;;;AAQH,SAAS,YACP,QACA,MACA,WACA,OACA,MACA,YACA,iBACA,QACM;CACN,IAAI,YAAY;CAChB,IAAI,eAAe;CACnB,IAAI,eAAe;AAGnB,KAAI,WAAW;AACb,MAAI,SAAS,GAAG,IAAI;AAClB,OAAI,OAAO,SAAS,OAAO,OAAO,MAChC,QAAO,KAAK,KAAK,mBAAmB,YAAY,iBAAiB,YAAY,MAAM,CAAC,CAAC;GAEvF,IAAI,cAAc;AAClB,QAAK,IAAI,IAAI,GAAG,IAAI,OAAO,MAAM,QAAQ,IACvC,KAAI,OAAO,MAAM,OAAO,OAAO;AAC7B,kBAAc;AACd;;AAGJ,OAAI,CAAC,eAAe,OAAO,MAAM,SAAS,UACxC,QAAO,MAAM,KAAK,MAAM;QAG1B,aAAY,QAAQ,cAAc,KAAK,EAAE,OAAO,OAAO,MAAM,YAAY,iBAAiB,OAAO;AAEnG;;AAIF,KAAI,SAAS,GAAG,OAAO,UAAU,OAAO,IACtC,QAAO,KAAK,KAAK,WAAW,YAAY,iBAAiB,YAAY,MAAM,CAAC,CAAC;UACpE,SAAS,GAAG,OAAO,UAAU,OAAO,IAC7C,QAAO,KAAK,KAAK,WAAW,YAAY,iBAAiB,YAAY,MAAM,CAAC,CAAC;AAI/E,KAAI,KAAK,OAAO,OAAO,KAAK,OAAO,SAAS,IAAI,KAAK,OAAO,OAAO,KAAK,OAAO,SAAS,CACtF,QAAO,KAAK,KAAK,oBAAoB,YAAY,iBAAiB,YAAY,MAAM,CAAC,CAAC;UAC7E,SAAS,GAAG,MAAM,UAAU,OAAO,IAC5C,QAAO,KAAK,KAAK,aAAa,YAAY,iBAAiB,YAAY,MAAM,CAAC,CAAC;UACtE,SAAS,GAAG,MAAM,UAAU,OAAO,IAC5C,QAAO,KAAK,KAAK,aAAa,YAAY,iBAAiB,YAAY,MAAM,CAAC,CAAC;AAIjF,KAAI,SAAS,GAAG,IAAI;AAClB,MAAI,CAAC,OAAO,SAAS,OAAO,OAAO,MAAO,aAAY;AACtD,MAAI,OAAO;OACL,OAAO,OAAO,MAChB,QAAO,KAAK,KAAK,YAAY,YAAY,iBAAiB,YAAY,OAAO,GAAG,EAAE,YAAY,MAAM,CAAC,CAAC;;AAG1G,OAAK,IAAI,IAAI,GAAG,IAAI,OAAO,MAAM,QAAQ,IACvC,KAAI,OAAO,MAAM,OAAO,MACtB,QAAO,KAAK,KAAK,mBAAmB,YAAY,iBAAiB,YAAY,MAAM,CAAC,CAAC;AAGzF,SAAO,QAAQ;AACf,SAAO,KAAK;YACH,SAAS,GAAG,MAAM,SAAS,GAAG,KAAK;EAC5C,MAAM,YAAY,SAAS,GAAG;AAC9B,MAAI,OAAO,UAAU;GACnB,IAAI,YAAY;GAChB,IAAI,iBAAiB;AAErB,OAAI,KAAK,OAAO,OAAO,OAAO,OAAO,SAAS,CAC5C,aAAY;YACH,UAAU,OAAO;QACtB,OAAO,eACT,KAAI,CAAC,UAAW,kBAAiB;QAC5B,aAAY;aAEb,CAAC,UAAW,aAAY;SAG9B,kBAAiB;AAGnB,OAAI,UACF,QAAO,KAAK,KAAK,UAAU,YAAY,iBAAiB,YAAY,MAAM,CAAC,CAAC;AAG9E,OAAI,gBAAgB;AAClB,WAAO,KAAK,KAAK,UAAU,YAAY,iBAAiB,YAAY,OAAO,MAAM,CAAC,CAAC;AACnF,WAAO,QAAQ;AACf,WAAO,iBAAiB;AACxB,mBAAe;;SAEZ;AACL,UAAO,WAAW;AAClB,UAAO,QAAQ;AACf,UAAO,iBAAiB;AACxB,kBAAe;;YAER,SAAS,GAAG,MAAM,SAAS,GAAG,KAAK;EAC5C,MAAM,YAAY,SAAS,GAAG;AAC9B,MAAI,OAAO,UAAU;GACnB,IAAI,YAAY;GAChB,IAAI,iBAAiB;AAErB,OAAI,KAAK,OAAO,OAAO,OAAO,OAAO,SAAS,CAC5C,aAAY;YACH,UAAU,OAAO;QACtB,OAAO,eACT,KAAI,CAAC,UAAW,kBAAiB;QAC5B,aAAY;aAEb,CAAC,UAAW,aAAY;SAG9B,kBAAiB;AAGnB,OAAI,UACF,QAAO,KAAK,KAAK,UAAU,YAAY,iBAAiB,YAAY,MAAM,CAAC,CAAC;AAG9E,OAAI,gBAAgB;AAClB,WAAO,KAAK,KAAK,UAAU,YAAY,iBAAiB,YAAY,OAAO,MAAM,CAAC,CAAC;AACnF,WAAO,QAAQ;AACf,WAAO,iBAAiB;AACxB,mBAAe;;SAEZ;AACL,UAAO,WAAW;AAClB,UAAO,QAAQ;AACf,UAAO,iBAAiB;AACxB,kBAAe;;;AAKnB,KAAI,aAAa;MACX,OAAO,SAAS,OAAO,SAIzB,KAHsB,OAAO,iBACzB,KAAK,OAAO,IAAI,OAAO,OAAO,OAAO,SAAS,GAC9C,MAAM,OAAO,IAAI,OAAO,OAAO,OAAO,SAAS,CAEjD,QAAO,KACL,KAAK,sBAAsB,YAAY,iBAAiB,YAAY,OAAO,GAAG,EAAE,YAAY,OAAO,MAAM,CAAC,CAC3G;MAED,QAAO,KAAK,KAAK,UAAU,YAAY,iBAAiB,YAAY,OAAO,MAAM,EAAE,YAAY,OAAO,GAAG,CAAC,CAAC;;AAMjH,KAAI,aAAa;MACX,OAAO,SAAS,OAAO,SAIzB,KAHsB,OAAO,iBACzB,KAAK,OAAO,IAAI,OAAO,OAAO,OAAO,SAAS,GAC9C,MAAM,OAAO,IAAI,OAAO,OAAO,OAAO,SAAS,CAEjD,QAAO,KACL,KAAK,sBAAsB,YAAY,iBAAiB,YAAY,OAAO,GAAG,EAAE,YAAY,OAAO,MAAM,CAAC,CAC3G;MAED,QAAO,KAAK,KAAK,UAAU,YAAY,iBAAiB,YAAY,OAAO,MAAM,EAAE,YAAY,OAAO,GAAG,CAAC,CAAC;;AAMjH,KAAI,gBAAgB;MACd,OAAO,YAAY,OAAO;OAE1B,KAAK,OAAO,OAAO,OAAO,OAAO,OAAO,SAAS,IAChD,OAAO,UAAU,OAAO,UAAU,CAAC,OAAO,kBAAkB,CAAC,OAAO,gBAErE,QAAO,KACL,KAAK,gBAAgB,YAAY,iBAAiB,YAAY,OAAO,MAAM,EAAE,YAAY,OAAO,MAAM,CAAC,CACxG;;;;;AAWT,SAAS,cACP,KACA,MACA,WACA,MACA,YACA,iBACA,QACM;AACN,KAAI,UAAW;AAEf,KAAI,SAAS,GAAG,aAAa;AAC3B,OAAK,IAAI,QAAQ,aAAa,UAAU,GACtC,QAAO,KACLE,qBACE,YACA,iBACA,YAAY,KAAK,EACjB,YAAY,IAAI,QAAQ,WAAW,CACpC,CACF;AAEH,OAAK,IAAI,QAAQ,YAAY,UAAU,KACrC,QAAO,KACLC,iBAAwB,YAAY,iBAAiB,YAAY,KAAK,EAAE,YAAY,IAAI,QAAQ,UAAU,CAAC,CAC5G;AAEH,MAAI,QAAQ,aAAa;YAChB,SAAS,GAAG,cAAc;AACnC,OAAK,IAAI,QAAQ,YAAY,UAAU,GACrC,QAAO,KACLD,qBAA4B,YAAY,iBAAiB,YAAY,KAAK,EAAE,YAAY,IAAI,QAAQ,UAAU,CAAC,CAChH;AAEH,OAAK,IAAI,QAAQ,aAAa,UAAU,KACtC,QAAO,KACLC,iBAAwB,YAAY,iBAAiB,YAAY,KAAK,EAAE,YAAY,IAAI,QAAQ,WAAW,CAAC,CAC7G;AAEH,MAAI,QAAQ,cAAc;YACjB,SAAS,GAAG,aAAa;AAClC,MAAI,SAAS,OAAO,IAAI,QAAQ,aAAa,UAAU,KACrD,QAAO,KACLC,qBACE,YACA,iBACA,YAAY,KAAK,EACjB,YAAY,IAAI,QAAQ,WAAW,CACpC,CACF;AAEH,OAAK,IAAI,QAAQ,YAAY,UAAU,GACrC,QAAO,KACLD,iBAAwB,YAAY,iBAAiB,YAAY,KAAK,EAAE,YAAY,IAAI,QAAQ,UAAU,CAAC,CAC5G;;;;AAUP,SAAS,cAAc,KAAwB,YAAoB,iBAAyB,QAAuB;AACjH,KAAI,CAAC,IAAI,IAAI,MAAO;CAEpB,IAAI,gBAAgB;CACpB,MAAM,UAAU,IAAI,IAAI,SAAS;AACjC,MAAK,IAAI,IAAI,GAAG,IAAI,SAAS,KAAK;EAChC,MAAM,QAAQ,IAAI,IAAI,SAAS;EAC/B,IAAI,YAAY;AAChB,OAAK,IAAI,IAAI,GAAG,IAAI,IAAI,QAAQ,MAAM,QAAQ,IAC5C,KAAI,IAAI,QAAQ,MAAM,OAAO,OAAO;AAClC,eAAY;AACZ;;AAGJ,MAAI,CAAC;QACE,IAAI,IAAI,GAAG,IAAI,IAAI,IAAI,YAAY,QAAQ,IAC9C,KAAI,IAAI,IAAI,YAAY,OAAO,OAAO;AACpC,gBAAY;AACZ;;;AAIN,MAAI,CAAC,UAAW;;AAGlB,KAAI,kBAAkB,EACpB,QAAO,KAAKE,iBAAwB,YAAY,gBAAgB,CAAC;UACxD,gBAAgB,QACzB,QAAO,KAAKC,qBAA4B,YAAY,iBAAiB,YAAY,OAAO,UAAU,cAAc,CAAC,CAAC,CAAC;;;AAKvH,SAAS,UACP,KACA,WACA,QACA,YACA,iBACA,QACM;AACN,KAAI,WAAW;AACb,OAAK,MAAM,SAAS,QAAQ;AAC1B,OAAI,IAAI,QAAQ,SAAS,IAAI,QAAQ,OAAO,MAC1C,QAAO,KAAKC,oBAA2B,YAAY,iBAAiB,YAAY,MAAM,CAAC,CAAC;AAE1F,OAAI,IAAI,IAAI,OAAO;IACjB,IAAI,QAAQ;AACZ,SAAK,MAAM,YAAY,IAAI,IAAI,SAC7B,KAAI,aAAa,OAAO;AACtB,aAAQ;AACR;;AAGJ,QAAI,MACF,QAAO,KAAKC,aAAoB,YAAY,iBAAiB,YAAY,MAAM,CAAC,CAAC;;AAGrF,OAAI,IAAI,IAAI,YAAY,SAAS,WAC/B,KAAI,IAAI,YAAY,KAAK,MAAM;;AAGnC,gBAAc,KAAK,YAAY,iBAAiB,OAAO;QAClD;AACL,MAAI,IAAI,QAAQ,OAAO;GACrB,IAAI,QAAQ;AACZ,QAAK,MAAM,aAAa,OACtB,KAAI,cAAc,IAAI,QAAQ,IAAI;AAChC,YAAQ;AACR;;AAGJ,OAAI,CAAC,MACH,QAAO,KAAKD,oBAA2B,YAAY,iBAAiB,YAAY,IAAI,QAAQ,GAAG,CAAC,CAAC;;AAIrG,MAAI,IAAI,IAAI,OAAO;GACjB,MAAM,eAAyB,EAAE;AACjC,QAAK,MAAM,YAAY,IAAI,IAAI,SAC7B,MAAK,MAAM,aAAa,OACtB,KAAI,aAAa,WAAW;AAC1B,iBAAa,KAAK,SAAS;AAC3B;;AAKN,OAAI,aAAa,WAAW,EAC1B,QAAO,KAAKE,qBAA4B,YAAY,gBAAgB,CAAC;YAC5D,aAAa,SAAS,OAAO,UAAU,aAAa,SAAS,IAAI,IAAI,SAAS,OACvF,QAAO,KAAKC,cAAqB,YAAY,iBAAiB,YAAY,OAAO,aAAa,OAAO,CAAC,CAAC,CAAC;AAE1G,OAAI,IAAI,WAAW;SACd;AACL,OAAI,IAAI,QAAQ;AAChB,OAAI,IAAI,WAAW;;AAGrB,gBAAc,KAAK,YAAY,iBAAiB,OAAO;;;;AAS3D,SAAS,gBAAgB,QAAiB,WAAkB,YAAoB,iBAA+B;CAC7G,MAAM,uBAAO,IAAI,KAAa;AAC9B,MAAK,MAAM,MAAM,WAAW;EAC1B,MAAM,MAAM,GAAG,aAAa;AAC5B,MAAI,KAAK,IAAI,IAAI,EAAE;AACjB,UAAO,KAAKC,oBAA2B,YAAY,gBAAgB,CAAC;AACpE;;AAEF,OAAK,IAAI,IAAI;;;;AASjB,SAAS,mBACP,KACA,YACA,YACA,iBACA,QACM;CACN,MAAM,YAAY,WAAW;AAE7B,MAAK,MAAM,SAAS,WAAW;EAC7B,MAAM,SAAS,SAAS,MAAM,MAAM,GAAG,EAAE,EAAE,GAAG;EAC9C,MAAM,OAAO,SAAS,CAAC,GAAG;EAC1B,MAAM,aAAa,SAAS,GAAG,SAAS;EAExC,MAAM,SAAS,mBAAmB,MAAM,IAAI,SAAS,UAAU,IAAI,SAAS,WAAW,IAAI,SAAS,WAAW;AAC/G,MAAI,CAAC,OAAO,YAAY;AACtB,UAAO,KACLC,WAAkB,OAAO,MAAM,OAAO,SAAS,YAAY,iBAAiB,YAAY,OAAO,OAAO,CAAC,CAAC,CACzG;AACD;;AAGF,MAAI,UAAU,KAAK;OACb,QAAQ,GAAG,MAAM,QAAQ,GAAG,QAC9B,KAAI,SAAS,GAAG,SAAS;IACvB,MAAM,EAAE,KAAK,SAAS,SAAS,MAAM;AACrC,gBAAY,IAAI,SAAS,GAAG,KAAK,WAAW,KAAK,YAAY,MAAM,EAAE,YAAY,iBAAiB,OAAO;AACzG,gBAAY,IAAI,SAAS,GAAG,KAAK,WAAW,MAAM,YAAY,MAAM,EAAE,YAAY,iBAAiB,OAAO;UACrG;IACL,MAAM,QAAQ,UAAU,MAAM;IAC9B,MAAM,cAAc,IAAI,QAAQ,MAAM;AACtC,gBAAY,IAAI,SAAS,MAAM,WAAW,OAAO,YAAY,MAAM,EAAE,YAAY,iBAAiB,OAAO;AACzG,QAAI,IAAI,QAAQ,MAAM,SAAS,YAC7B,eAAc,KAAK,YAAY,iBAAiB,OAAO;;YAGlD,YAAY,KAAK,CAE1B,eAAc,KAAK,MAAM,WADZ,UAAU,MACiB,EAAE,YAAY,iBAAiB,OAAO;YACrE,SAAS,GAAG,IAAI;IACzB,MAAM,SAAS,UAAU,MAAM;AAC/B,QAAI,CAAC,oBAAoB,OAAO,CAC9B,QAAO,KAAKC,cAAqB,YAAY,gBAAgB,CAAC;QAE9D,WAAU,KAAK,WAAW,QAAQ,YAAY,iBAAiB,OAAO;;aAGjE,WAAW,KAAK,CACzB,KAAI,SAAS,GAAG,gBAAgB;GAC9B,MAAM,EAAE,KAAK,SAAS,SAAS,MAAM;AACrC,eAAY,IAAI,QAAQ,GAAG,KAAK,WAAW,KAAK,YAAY,KAAK,EAAE,YAAY,iBAAiB,OAAO;AACvG,eAAY,IAAI,QAAQ,GAAG,KAAK,WAAW,MAAM,YAAY,KAAK,EAAE,YAAY,iBAAiB,OAAO;SACnG;GACL,MAAM,QAAQ,UAAU,MAAM;AAC9B,eACE,IAAI,QACJ,kBAAkB,KAAK,EACvB,WACA,OACA,YAAY,KAAK,EACjB,YACA,iBACA,OACD;;;AAKP,iBAAgB,QAAQ,WAAW,YAAY,gBAAgB;;;AAQjE,SAAS,cAAc,MAAkB,WAAuB,YAAoB,QAAuB;CACzG,MAAM,cAAc,KAAK,OAAO;CAChC,MAAM,WAAgC,EAAE;AAExC,MAAK,IAAI,kBAAkB,GAAG,kBAAkB,YAAY,QAAQ,mBAAmB;EACrF,MAAM,aAAa,YAAY;EAC/B,MAAM,iBAAsB,KAAK,WAAW,KAAK,MAAM,EAAE,CAAC,aAAa;EAGvE,IAAI;AACJ,OAAK,MAAM,YAAY,SACrB,KAAI,SAAS,UAAU,WAAW,SAAS,SAAS,SAAS,gBAAgB;AAC3E,SAAM;AACN;;AAIJ,MAAI,CAAC,KAAK;GACR,IAAI;AACJ,OAAI,WAAW,UAAU,MAAM,UAAU;IACvC,MAAM,QAAQ,eAAe,WAAW,KAAK;AAC7C,eAAW,WAAW,OAAO,WAAW,MAAM;UACzC;IAEL,MAAM,QADQ,eAAe,WAAW,KACrB,CAAC;AAEpB,eAAW;KAAE,UADI,sBAAsB,MAAM,CAAC;KACvB,WAAW;KAAO,YAAY;KAAI;;AAE3D,SAAM,YAAY,WAAW,OAAO,gBAAgB,SAAS;AAC7D,YAAS,KAAK,IAAI;;AAGpB,qBAAmB,KAAK,YAAY,YAAY,iBAAiB,OAAO;;;;;;;;AAa5E,SAAS,SAAS,MAA2B;CAC3C,MAAM,SAAkB,EAAE;CAC1B,MAAM,YAAY,WAAW,KAAK,WAAW;AAE7C,MAAK,IAAI,aAAa,GAAG,aAAa,KAAK,OAAO,QAAQ,cAAc;AACtE,MAAI,KAAK,OAAO,YAAa,WAAW,GAAG;AACzC,UAAO,KAAKC,WAAkB,WAAW,CAAC;AAC1C;;AAEF,gBAAc,MAAM,WAAW,YAAY,OAAO;;AAGpD,QAAO;;;AAIT,MAAa,kBAAkB,EAAE,UAAU;;;;ACjzB3C,SAAS,QAAQ,GAAoB;AACnC,QAAQ,KAAK,MAAQ,KAAK,MAAU,KAAK,MAAQ,KAAK;;;AAIxD,SAAS,WAAW,GAAoB;AACtC,QAAO,QAAQ,EAAE,IAAK,KAAK,MAAQ,KAAK;;;;;;;;;;;;AAa1C,SAAS,MAAM,WAAoC;AACjD,KAAI,UAAU,SAAS,EACrB,OAAM,IAAI,cAAc,qBAAqB,sCAAsC,UAAU,GAAG;CAIlG,IAAI,YAAY;AAChB,MAAK,IAAI,IAAI,GAAG,IAAI,UAAU,QAAQ,KAAK;EACzC,MAAM,IAAI,UAAU,WAAW,EAAE;AACjC,MAAI,MAAM,MAAQ,MAAM,KAAQ,MAAM,MAAQ,MAAM,GAClD,OAAM,IAAI,cAAc,qBAAqB,wCAAwC;AAEvF,MAAI,IAAI,IACN,OAAM,IAAI,cAAc,qBAAqB,+CAA+C;AAE9F,MAAI,cAAc,MAAM,MAAM,GAC5B,aAAY;;AAIhB,KAAI,YAAY,EACd,OAAM,IAAI,cACR,qBACA,8EAA8E,UAAU,GACzF;AAGH,KAAI,CAAC,UAAU,SAAS,IAAI,CAC1B,OAAM,IAAI,cAAc,qBAAqB,8CAA8C,UAAU,GAAG;CAI1G,MAAM,YAAY,UAAU,WAAW,EAAE;AACzC,KAAI,CAAC,QAAQ,UAAU,IAAI,cAAc,GACvC,OAAM,IAAI,cAAc,qBAAqB,uDAAuD;AAEtG,MAAK,IAAI,IAAI,GAAG,IAAI,WAAW,KAAK;EAClC,MAAM,IAAI,UAAU,WAAW,EAAE;AACjC,MAAI,CAAC,WAAW,EAAE,IAAI,MAAM,GAC1B,OAAM,IAAI,cACR,qBACA,yEACD;;CAIL,MAAM,QAAQ,UAAU,MAAM,YAAY,GAAG,UAAU,SAAS,EAAE;CAClE,MAAM,UAAU,IAAI,WAAW,UAAU,OAAO;AAChD,MAAK,IAAI,IAAI,GAAG,IAAI,UAAU,QAAQ,IAAK,SAAQ,KAAK,UAAU,WAAW,EAAE;AAI/E,QAAO;EAAE,UAFQ,WADJ,WAAW,QACQ,CAAC,SAAS,GAAG,EAAE,CAE9B;EAAE;EAAO;;;AAI5B,MAAa,kBAAkB,EAAE,OAAO;;;;AClExC,SAAS,oBAAoB,WAA6B;AACxD,KAAI,UAAU,WAAW,EACvB,OAAM,IAAI,cAAc,wBAAwB,yDAAyD;CAE3G,MAAM,OAAO,QAAQ,WAAW,EAAE;AAClC,KAAI,OAAO,wBACT,OAAM,IAAI,cACR,4BACA,iCAAiC,KAAK,SAAS,GAAG,CAAC,SAAS,GAAG,IAAI,CAAC,GACrE;;;AAKL,SAAS,qBAAqB,MAAW,MAAwB;CAC/D,MAAM,QAAQ,eAAe,KAAK;AAClC,KAAI,MAAM,WAAW,EACnB,OAAM,IAAI,cAAc,gBAAgB,6CAA6C;CAGvF,MAAM,WAAW,MAAM;CACvB,MAAM,aAAa,WAAW,WAAW,KAAK;AAC9C,KAAI,YAAY,WACd,OAAM,IAAI,cACR,gBACA,kBAAkB,SAAS,gCAAgC,WAAW,WACvE;CAGH,IAAI,SAAS,WAAW,YAAY,MAAM,SAAS;CACnD,IAAI,gBAAgB;AAEpB,MAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;EACrC,MAAM,OAAO,MAAM;EACnB,MAAM,OAAO,WAAW,QAAQ,MAAM,OAAO;AAE7C,MAAI,KAAK,aAAa,SAAS,OAAO;AACpC,OAAI,aAAa,KAAK,CACpB,OAAM,IAAI,cAAc,gBAAgB,gDAAgD;GAE1F,MAAM,aAAa,WAAW,gBAAgB,MAAM,OAAO;AAC3D,OAAI,QAAQ,WACV,OAAM,IAAI,cACR,gBACA,qBAAqB,KAAK,2BAA2B,WAAW,WACjE;AAEH,YAAS,WAAW,iBAAiB,MAAM,QAAQ,KAAK;aAC/C,KAAK,aAAa,SAAS,gBAAgB,KAAK,aAAa,SAAS,eAAe;AAC9F,OAAI,aAAa,KAAK,EAAE;AACtB,QAAI,cACF,OAAM,IAAI,cAAc,gBAAgB,sCAAsC;AAEhF,oBAAgB;cACP,KAAK,aAAa,SAAS,cAAc;IAClD,MAAM,cAAc,WAAW,kBAAkB,MAAM,OAAO;AAC9D,QAAI,QAAQ,YACV,OAAM,IAAI,cACR,gBACA,eAAe,KAAK,kCAAkC,YAAY,aACnE;;AAGL,YAAS,WAAW,mBAAmB,OAAO;QAE9C,OAAM,IAAI,cAAc,gBAAgB,0CAA0C;;;;AAUxF,IAAa,gBAAb,MAAa,cAAc;CACzB;CAEA,YAAoB,OAAoB;AACtC,OAAK,QAAQ;;;;;;CAOf,OAAO,OAAO,WAAkC;EAC9C,MAAM,SAAS,gBAAgB,MAAM,UAAU;EAC/C,MAAM,aAAa,gBAAgB,UAAU,OAAO,MAAM;AAC1D,SAAO,IAAI,cAAc;GACvB,gBAAgB;GAChB,UAAU,OAAO;GACjB;GACA,QAAQ,CAAC,EAAE,CAAC;GACZ,YAAY,iBAAC,IAAI,KAAK,CAAC;GACxB,CAAC;;;;;;CAOJ,OAAO,UAAU,UAAiC;AAEhD,SAAO,IAAI,cAAc;GACvB,gBAAgB;GAChB,UAAU;GACV,YAJiB,gBAAgB,UAAU,SAIjC;GACV,QAAQ,CAAC,EAAE,CAAC;GACZ,YAAY,iBAAC,IAAI,KAAK,CAAC;GACxB,CAAC;;;;;;CAOJ,IAAI,YAAkD;EACpD,MAAM,IAAgB;GACpB,OAAO,WAAW;GAClB,MAAM,WAAW;GACjB,WAAW,CAAC,GAAG,WAAW,UAAU;GACrC;AAED,MAAI,EAAE,UAAU,WAAW,EACzB,OAAM,IAAI,cAAc,sBAAsB,8CAA8C;AAG9F,MAAI,EAAE,UAAU,MAAM,QACpB,qBAAoB,WAAW,EAAE,KAAK,CAAC;WAC9B,EAAE,UAAU,MAAM,SAC3B,sBAAqB,EAAE,MAAM,KAAK,MAAM,WAAW;MAEnD,OAAM,IAAI,cAAc,iBAAiB,uBAAuB,EAAE,MAAM,GAAG;EAG7E,MAAM,MAAM,GAAG,EAAE,MAAM,GAAG,EAAE,KAAK,aAAa;EAC9C,MAAM,gBAAgB,KAAK,MAAM,WAAW,KAAK,MAAM,WAAW,SAAS;AAC3E,MAAI,cAAc,IAAI,IAAI,CACxB,OAAM,IAAI,cAAc,kBAAkB,kBAAkB,EAAE,KAAK,qBAAqB;AAG1F,gBAAc,IAAI,IAAI;AACtB,OAAK,MAAM,OAAO,KAAK,MAAM,OAAO,SAAS,GAAI,KAAK,EAAE;AACxD,SAAO;;;CAIT,KAAW;AAET,MADkB,KAAK,MAAM,OAAO,KAAK,MAAM,OAAO,SAAS,GACjD,WAAW,EACvB,OAAM,IAAI,cAAc,eAAe,4DAA4D;AAErG,OAAK,MAAM,OAAO,KAAK,EAAE,CAAC;AAC1B,OAAK,MAAM,WAAW,qBAAK,IAAI,KAAK,CAAC;AACrC,SAAO;;;;;;;CAQT,QAAa;AACX,OAAK,aAAa;EAClB,MAAM,aAAa,KAAK,cAAc;EAEtC,MAAM,aADS,gBAAgB,SAAS,WACf,CAAC,MAAM,UAAU,MAAM,aAAa,QAAQ;AACrE,MAAI,WACF,OAAM,IAAI,cAAc,oBAAoB,WAAW,QAAQ;AAEjE,SAAO,YAAY,OAAO,WAAW;;;;;;CAOvC,WAAoB;AAClB,OAAK,aAAa;EAClB,MAAM,aAAa,KAAK,cAAc;AACtC,SAAO,gBAAgB,SAAS,WAAW;;;CAI7C,cAA4B;AAC1B,OAAK,IAAI,IAAI,GAAG,IAAI,KAAK,MAAM,OAAO,QAAQ,IAC5C,KAAI,KAAK,MAAM,OAAO,GAAI,WAAW,EACnC,OAAM,IAAI,cAAc,eAAe,SAAS,EAAE,YAAY;;;CAMpE,eAAmC;AACjC,SAAO;GACL,gBAAgB,KAAK,MAAM;GAC3B,UAAU,KAAK,MAAM;GACrB,YAAY,WAAW,KAAK,MAAM,WAAW;GAC7C,QAAQ,KAAK,MAAM;GACpB;;;;;;ACvNL,SAAS,WAAW,OAAgC;CAClD,MAAM,OAAO,IAAI,WAAW,GAAG;AAE/B,KAAI,OAAO,UAAU,WAAW;AAC9B,OAAK,MAAM,QAAQ,IAAI;AACvB,SAAO;;AAGT,KAAI,OAAO,UAAU,UAAU;EAE7B,MAAM,OAAO,MAAM,WAAW,KAAK,GAAG,MAAM,MAAM,EAAE,GAAG;AACvD,MAAI,KAAK,WAAW,GAClB,OAAM,IAAI,cACR,sBACA,sDAAsD,KAAK,SAC5D;AAEH,OAAK,IAAI,IAAI,GAAG,IAAI,IAAI,KAAK;GAC3B,MAAM,OAAO,SAAS,KAAK,UAAU,IAAI,GAAG,IAAI,IAAI,EAAE,EAAE,GAAG;AAC3D,OAAI,OAAO,MAAM,KAAK,CACpB,OAAM,IAAI,cAAc,sBAAsB,gDAAgD,IAAI,IAAI;AAExG,QAAK,KAAK,KAAK;;AAEjB,SAAO;;CAIT,IAAI,WAAW,OAAO,UAAU,WAAW,OAAO,MAAM,GAAG;AAC3D,MAAK,IAAI,IAAI,IAAI,KAAK,GAAG,KAAK;AAC5B,OAAK,KAAK,OAAO,WAAW,KAAM;AAClC,eAAa;;AAEf,QAAO;;;AAIT,SAAS,SAAS,QAAgB,OAAyB;CACzD,MAAM,SAAS,IAAI,WAAW,GAAG;AACjC,QAAO,KAAK;AACZ,QAAO,IAAI,WAAW,MAAM,EAAE,EAAE;AAChC,QAAO,WAAW,OAAO;;;AAI3B,SAAS,QAAQ,QAAgB,KAAa,KAAkB;AAC9D,KAAI,MAAM,IACR,OAAM,IAAI,cAAc,iBAAiB,cAAc,IAAI,yBAAyB,IAAI,GAAG;CAE7F,MAAM,SAAS,IAAI,WAAW,GAAG;AACjC,QAAO,KAAK;AACZ,QAAO,IAAI,WAAW,IAAI,EAAE,EAAE;AAC9B,QAAO,IAAI,WAAW,IAAI,EAAE,GAAG;AAC/B,QAAO,WAAW,OAAO;;;AAI3B,SAAS,MAAM,QAAgB,QAAqC;CAClE,MAAM,OAAO,OAAO,KAAK,MAAM;AAC7B,MAAI,OAAO,MAAM,SAAU,QAAO;AAClC,MAAI,OAAO,MAAM,SAAU,QAAO,OAAO,EAAE;AAC3C,MAAI,OAAO,MAAM,UAAW,QAAO,IAAI,KAAK;EAE5C,MAAM,OAAO,EAAE,WAAW,KAAK,GAAG,EAAE,MAAM,EAAE,GAAG;AAC/C,SAAO,OAAO,QAAQ,QAAQ,KAAK;GACnC;AAEF,MAAK,MAAM,GAAG,MAAO,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,EAAG;CAEjD,MAAM,UAAoB,EAAE;AAC5B,MAAK,MAAM,SAAS,KAClB,KAAI,QAAQ,WAAW,KAAK,QAAQ,QAAQ,SAAS,OAAO,MAC1D,SAAQ,KAAK,MAAM;AAIvB,KAAI,QAAQ,WAAW,EACrB,OAAM,IAAI,cAAc,aAAa,sCAAsC;CAG7E,MAAM,SAAS,IAAI,WAAW,IAAI,QAAQ,SAAS,GAAG;AACtD,QAAO,KAAK;AACZ,MAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,QAAQ,IAClC,QAAO,IAAI,WAAW,QAAQ,GAAI,EAAE,IAAI,IAAI,GAAG;AAEjD,QAAO,WAAW,OAAO;;;AAQ3B,SAAS,WAAW,OAA+B;CACjD,MAAM,SAAS,IAAI,WAAW,MAAM,SAAS,EAAE;AAC/C,MAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,IAChC,WAAU,QAAQ,IAAI,GAAG,MAAM,GAAI;AAErC,QAAO,WAAW,OAAO;;;;;;AAW3B,IAAa,oBAAb,MAAqD;CACnD;CACA;CACA;;CAGA,YAAY,OAAe,MAAW;AACpC,OAAK,QAAQ;AACb,OAAK,OAAO;AACZ,OAAK,YAAY,EAAE;;;CAIrB,KAAa,OAAkB;AAC7B,OAAK,UAAU,KAAK,MAAM;AAC1B,SAAO;;;CAQT,GAAG,OAA0B;AAC3B,SAAO,KAAK,KAAK,SAAS,GAAG,IAAI,MAAM,CAAC;;;CAI1C,IAAI,OAA0B;AAC5B,SAAO,KAAK,KAAK,SAAS,GAAG,KAAK,GAAG,KAAK,MAAM,CAAC;;;CAInD,GAAG,OAA8B;AAC/B,SAAO,KAAK,KAAK,SAAS,GAAG,IAAI,MAAM,CAAC;;;CAI1C,GAAG,OAA8B;AAC/B,SAAO,KAAK,KAAK,SAAS,GAAG,IAAI,MAAM,CAAC;;;CAI1C,IAAI,OAA8B;AAChC,SAAO,KAAK,KAAK,SAAS,GAAG,KAAK,MAAM,CAAC;;;CAI3C,IAAI,OAA8B;AAChC,SAAO,KAAK,KAAK,SAAS,GAAG,KAAK,MAAM,CAAC;;;;;;CAO3C,QAAQ,KAAsB,KAA4B;AACxD,SAAO,KAAK,KAAK,QAAQ,GAAG,SAAS,OAAO,IAAI,EAAE,OAAO,IAAI,CAAC,CAAC;;;;;;;CAYjE,KAAK,QAAsC;AACzC,SAAO,KAAK,KAAK,MAAM,GAAG,IAAI,OAAO,CAAC;;;;;;CAOxC,MAAM,QAAsC;AAC1C,SAAO,KAAK,KAAK,MAAM,GAAG,KAAK,GAAG,KAAK,OAAO,CAAC;;;CAQjD,WAAW,MAAoB;AAC7B,SAAO,KAAK,KAAK,SAAS,GAAG,aAAa,KAAK,CAAC;;;CAIlD,WAAW,MAAoB;AAC7B,SAAO,KAAK,KAAK,SAAS,GAAG,aAAa,KAAK,CAAC;;;CAIlD,YAAY,MAAoB;AAC9B,SAAO,KAAK,KAAK,SAAS,GAAG,cAAc,KAAK,CAAC;;;CAQnD,SAAS,GAA0B;AACjC,SAAO,KAAK,KAAK,SAAS,GAAG,WAAW,EAAE,CAAC;;;CAI7C,SAAS,GAA0B;AACjC,SAAO,KAAK,KAAK,SAAS,GAAG,WAAW,EAAE,CAAC;;;CAI7C,SAAS,GAA0B;AACjC,SAAO,KAAK,KAAK,SAAS,GAAG,WAAW,EAAE,CAAC;;;CAI7C,UAAU,GAA0B;AAClC,SAAO,KAAK,KAAK,SAAS,GAAG,YAAY,EAAE,CAAC;;;CAI9C,UAAU,GAA0B;AAClC,SAAO,KAAK,KAAK,SAAS,GAAG,YAAY,EAAE,CAAC;;;;;;CAO9C,cAAc,KAAsB,KAA4B;AAC9D,SAAO,KAAK,KAAK,QAAQ,GAAG,gBAAgB,OAAO,IAAI,EAAE,OAAO,IAAI,CAAC,CAAC;;;AAgB1E,SAAgB,IAAI,GAAG,OAAoC;AACzD,QAAO,IAAI,kBAAkB,MAAM,UAAU,WAAW,MAAM,CAAC;;;AAIjE,SAAgB,YAA+B;AAC7C,QAAO,IAAI,kBAAkB,MAAM,SAAS,WAAW,CAAC,gBAAgB,WAAW,CAAC,CAAC;;;AAIvF,SAAgB,WAA8B;AAC5C,QAAO,IAAI,kBAAkB,MAAM,SAAS,WAAW,CAAC,gBAAgB,UAAU,CAAC,CAAC;;;AAItF,SAAgB,iBAAoC;AAClD,QAAO,IAAI,kBAAkB,MAAM,SAAS,WAAW,CAAC,gBAAgB,gBAAgB,CAAC,CAAC;;;AAI5F,SAAgB,cAAiC;AAC/C,QAAO,IAAI,kBAAkB,MAAM,SAAS,WAAW,CAAC,gBAAgB,aAAa,CAAC,CAAC;;;AAIzF,SAAgB,UAA6B;AAC3C,QAAO,IAAI,kBAAkB,MAAM,SAAS,WAAW,CAAC,gBAAgB,SAAS,CAAC,CAAC;;;AAIrF,SAAgB,WAA8B;AAC5C,QAAO,IAAI,kBAAkB,MAAM,SAAS,WAAW,CAAC,gBAAgB,UAAU,CAAC,CAAC;;;;;AC9OtF,SAAgB,OAAO,UAAsB,QAAwC;AACnF,KAAI,SAAS,KAAK,SAAS,KAAK,SAAS,OACvC,QAAO,EAAE,MAAM,0BAA0B;AAE3C,QAAO,SAAS,SAAS,QAAQ,SAAS,GAAG;;;;;;AAO/C,SAAgB,YAAY,UAAsB,MAAkC;CAClF,MAAM,OAAO,OAAO,UAAU,KAAK;AACnC,KAAI,gBAAgB,YAAY;AAC9B,OAAK,IAAI,IAAI,GAAG,IAAI,IAAI,IACtB,KAAI,KAAK,OAAO,EAAG,QAAO,EAAE,MAAM,0BAA0B;AAE9D,UAAS,KAAK,OAAQ,KAAO,KAAK,OAAQ,KAAO,KAAK,OAAQ,IAAK,KAAK,SAAU;;AAEpF,QAAO;;;AAQT,SAAS,iBAAiB,MAAwB;AAChD,QAAO,KAAK,YAAY,KAAK,KAAK;;;AAIpC,SAAS,SAAS,WAAuB,WAA2B;AAClE,QAAO,QAAQ,WAAW,YAAY,EAAE;;;AAY1C,SAAS,QAAQ,MAAgB,UAAsB,MAAc,MAAc,YAAmC;AACpH,KAAI,KAAK,SAAS,QAChB,QAAO,aAAa,MAAM,UAAU,MAAM,MAAM,WAAW;AAE7D,KAAI,KAAK,SAAS,eAChB,QAAO,oBAAoB,MAAM,UAAU,MAAM,MAAM,WAAW;AAEpE,KAAI,KAAK,SAAS,cAChB,QAAO,mBAAmB,MAAM,UAAU,MAAM,MAAM,WAAW;AAEnE,OAAM,IAAI,cAAc,gBAAgB,wCAAwC,KAAK,KAAK,IAAI;;;AAIhG,SAAS,aACP,MACA,UACA,MACA,MACA,YACe;AACf,KAAI,cAAc,KAAK,OAAO,OAC5B,OAAM,IAAI,cACR,gBACA,qBAAqB,WAAW,iBAAiB,KAAK,OAAO,OAAO,WACrE;CAGH,IAAI;CACJ,IAAI;AAEJ,KAAI,KAAK,WAAW;EAClB,MAAM,YAAY,YAAY,UAAU,KAAK;AAC7C,MAAI,OAAO,cAAc,SAAU,QAAO;GAAE,MAAM;GAAa,MAAM,UAAU;GAAM;AACrF,cAAY,OAAO;AACnB,WAAS;QACJ;AACL,cAAY;AACZ,WAAS;;AAGX,MAAK,IAAI,IAAI,GAAG,IAAI,YAAY,IAC9B,WAAU,iBAAiB,KAAK,OAAO,GAAI;AAG7C,QAAO;EACL,MAAM;EACN,MAAM;EACN,MAAM;EACN,MAAM,KAAK,OAAO;EACnB;;;AAIH,SAAS,oBACP,MACA,UACA,MACA,MACA,YACe;CACf,MAAM,kBAAkB,YAAY,UAAU,KAAK;AACnD,KAAI,OAAO,oBAAoB,SAAU,QAAO;EAAE,MAAM;EAAa,MAAM,gBAAgB;EAAM;CACjG,MAAM,YAAY,OAAO;CAEzB,MAAM,eAAe,YAAY,UAAU,UAAU;AACrD,KAAI,OAAO,iBAAiB,SAAU,QAAO;EAAE,MAAM;EAAa,MAAM,aAAa;EAAM;AAE3F,KAAI,cAAc,aAChB,QAAO;EAAE,MAAM;EAAa,MAAM;EAA6B;CAGjE,MAAM,YAAY,YAAY;CAC9B,MAAM,OAAO,KAAK;AAElB,KAAI,KAAK,UACP,QAAO;EACL,MAAM;EACN,MAAM,YAAY,aAAa;EAC/B,MAAM;EACN,MAAM;EACP;AAEH,QAAO;EACL,MAAM;EACN,MAAM,YAAY,aAAa,KAAK;EACpC,MAAM;EACN,MAAM;EACP;;;AAIH,SAAS,mBACP,MACA,UACA,MACA,MACA,YACe;AACf,KAAI,cAAc,KAAK,OACrB,OAAM,IAAI,cAAc,gBAAgB,sBAAsB,WAAW,wBAAwB,KAAK,OAAO,IAAI;CAGnH,MAAM,OAAO,KAAK;AAElB,KAAI,KAAK,WAAW;EAClB,MAAM,YAAY,YAAY,UAAU,KAAK;AAC7C,MAAI,OAAO,cAAc,SAAU,QAAO;GAAE,MAAM;GAAa,MAAM,UAAU;GAAM;EACrF,MAAM,YAAY,OAAO;AACzB,SAAO;GACL,MAAM;GACN,MAAM,YAAY,aAAa;GAC/B,MAAM;GACN,MAAM;GACP;;AAEH,QAAO;EACL,MAAM;EACN,MAAM,OAAO,aAAa,KAAK;EAC/B;EACA,MAAM;EACP;;;;;;;;;;AAeH,SAAgB,OACd,MACA,UACA,WACA,YACc;CACd,MAAM,YAAY,UAAU,SAAS;AACrC,KAAI,cAAc,EAChB,OAAM,IAAI,cAAc,gBAAgB,iBAAiB;CAI3D,MAAM,aAAa,SAAS,WAAW,EAAE;AACzC,KAAI,cAAc,KAAK,OACrB,OAAM,IAAI,cAAc,gBAAgB,eAAe,WAAW,iBAAiB,KAAK,OAAO,WAAW;CAG5G,IAAI,OAAO;AACX,MAAK,IAAI,IAAI,GAAG,IAAI,YAAY,IAC9B,SAAQ,iBAAiB,KAAK,GAAI;CAEpC,IAAI,OAAO;CACX,IAAI,OAAO,KAAK;AAGhB,MAAK,IAAI,IAAI,GAAG,IAAI,WAAW,KAAK;EAClC,MAAM,OAAO,SAAS,WAAW,EAAE;AAGnC,MAAI,aAAa,KAAK,EAAE;GACtB,MAAM,YAAY,UAAU,UAAU,IAAI,KAAK,EAAE;AAEjD,QAAK,IAAI,IAAI,GAAG,IAAI,UAAU,SAAS,GAAG,IACxC,KAAI,aAAa,SAAS,WAAW,EAAE,CAAC,CACtC,OAAM,IAAI,cAAc,sBAAsB,wCAAwC;AAG1F,UAAO;IACL,IAAI;IACJ,MAAM;IACN,YAAY;KACV,YAAY;KACZ,UAAU;MAAE;MAAM;MAAM;MAAM;KAC9B,eAAe;KAChB;IACF;;EAGH,MAAM,SAAS,QAAQ,MAAM,UAAU,MAAM,MAAM,KAAK;AACxD,MAAI,OAAO,SAAS,YAAa,QAAO;GAAE,IAAI;GAAO,MAAM,OAAO;GAAM;AACxE,SAAO,OAAO;AACd,SAAO,OAAO;AACd,SAAO,OAAO;;AAGhB,QAAO;EAAE,IAAI;EAAM,MAAM;EAAQ,UAAU;GAAE;GAAM;GAAM;GAAM;EAAE;;;AAInE,SAAgB,WAAW,UAAsB,UAAsC;CACrF,MAAM,EAAE,MAAM,MAAM,SAAS;AAE7B,KAAI,KAAK,SAAS,gBAAgB;EAChC,MAAM,kBAAkB,YAAY,UAAU,KAAK;AACnD,MAAI,OAAO,oBAAoB,SAAU,QAAO;GAAE,IAAI;GAAO,MAAM,gBAAgB;GAAM;EACzF,MAAM,YAAY,OAAO;EAEzB,MAAM,eAAe,YAAY,UAAU,UAAU;AACrD,MAAI,OAAO,iBAAiB,SAAU,QAAO;GAAE,IAAI;GAAO,MAAM,aAAa;GAAM;EAEnF,MAAM,OAAO,KAAK;EAClB,MAAM,YAAY,YAAY;AAE9B,MAAI,KAAK,UACP,QAAO;GACL,IAAI;GACJ,OAAO;IACL,QAAQ;IACR,aAAa;IACb,kBAAkB;IAClB,mBAAmB;IACnB;IACA,YAAY;IACZ,eAAe;IAChB;GACF;AAEH,SAAO;GACL,IAAI;GACJ,OAAO;IACL,QAAQ;IACR,aAAa;IACb,kBAAkB;IAClB,mBAAmB,KAAK;IACxB,WAAW;IACX,YAAY;IACZ,eAAe;IAChB;GACF;;AAGH,KAAI,KAAK,SAAS,eAAe;EAC/B,MAAM,OAAO,KAAK;AAElB,MAAI,KAAK,WAAW;GAClB,MAAM,kBAAkB,YAAY,UAAU,KAAK;AACnD,OAAI,OAAO,oBAAoB,SAAU,QAAO;IAAE,IAAI;IAAO,MAAM,gBAAgB;IAAM;GACzF,MAAM,YAAY,OAAO;AACzB,UAAO;IACL,IAAI;IACJ,OAAO;KACL,QAAQ,KAAK;KACb,aAAa;KACb,kBAAkB;KAClB,mBAAmB;KACnB,WAAW;KACX,YAAY;KACZ,eAAe;KAChB;IACF;;AAEH,SAAO;GACL,IAAI;GACJ,OAAO;IACL,QAAQ,KAAK;IACb,aAAa;IACb,kBAAkB;IAClB,mBAAmB,KAAK;IACxB,WAAW;IACX,YAAY;IACZ,eAAe;IAChB;GACF;;AAGH,OAAM,IAAI,cAAc,gBAAgB,kDAAkD,KAAK,KAAK,IAAI;;;AAI1G,SAAgB,eAAe,OAAmB,OAAe,UAAsC;AACrG,KAAI,SAAS,MAAM,OACjB,QAAO;EAAE,IAAI;EAAO,MAAM;EAA6B;CAGzD,IAAI;CACJ,IAAI;AAEJ,KAAI,CAAC,MAAM,kBAAkB;AAC3B,SAAO,MAAM,aAAa,QAAQ,MAAM;AACxC,SAAO,MAAM;QACR;AACL,SAAO,MAAM,YAAY,QAAQ;AACjC,SAAO,MAAM;;AAGf,KAAI,OAAO,KAAK,SAAS,OACvB,QAAO;EAAE,IAAI;EAAO,MAAM;EAA0B;AAGtD,QAAO;EACL,IAAI;EACJ,UAAU;GAAE;GAAM;GAAM,MAAM,MAAM;GAAa;EAClD;;;AAIH,SAAgB,WAAW,UAAsB,UAAgC;CAC/E,MAAM,SAAS,OAAO,UAAU,SAAS,KAAK;AAC9C,KAAI,kBAAkB,WACpB,QAAO;EAAE,IAAI;EAAM,OAAO;EAAQ;AAEpC,QAAO;EAAE,IAAI;EAAO,MAAM,OAAO;EAAM;;;AAIzC,SAAgB,UAAU,UAAsB,UAAiC;CAC/E,MAAM,YAAY,YAAY,UAAU,SAAS,KAAK;AACtD,KAAI,OAAO,cAAc,SAAU,QAAO;EAAE,IAAI;EAAO,MAAM,UAAU;EAAM;CAE7E,MAAM,YAAY,SAAS,OAAO;CAClC,MAAM,eAAe,YAAY,UAAU,UAAU;AACrD,KAAI,OAAO,iBAAiB,SAAU,QAAO;EAAE,IAAI;EAAO,MAAM,aAAa;EAAM;AAEnF,QAAO;EAAE,IAAI;EAAM,YAAY,YAAY;EAAI,QAAQ;EAAc;;;AAIvE,SAAgB,YAAY,UAAsB,UAAoB,WAAuC;CAC3G,MAAM,YAAY,UAAU,SAAS;CACrC,IAAI,EAAE,MAAM,MAAM,SAAS;AAE3B,MAAK,IAAI,IAAI,GAAG,IAAI,WAAW,KAAK;EAClC,MAAM,OAAO,SAAS,WAAW,EAAE;EACnC,MAAM,SAAS,QAAQ,MAAM,UAAU,MAAM,MAAM,KAAK;AACxD,MAAI,OAAO,SAAS,YAAa,QAAO;GAAE,IAAI;GAAO,MAAM,OAAO;GAAM;AACxE,SAAO,OAAO;AACd,SAAO,OAAO;AACd,SAAO,OAAO;;AAGhB,QAAO;EAAE,IAAI;EAAM,UAAU;GAAE;GAAM;GAAM;GAAM;EAAE;;;;;ACtarD,SAAS,gBAAgB,KAAqB;CAC5C,MAAM,QAAQ,WAAW,IAAI;CAC7B,MAAM,SAAS,IAAI,WAAW,GAAG;AACjC,QAAO,IAAI,OAAO,KAAK,MAAM,OAAO;AACpC,QAAO,SAAS,QAAQ,EAAE;;;AAI5B,SAAS,WAAW,OAAuB;AACzC,KAAI,UAAU,GAAI,QAAO;AACzB,QAAO,KAAK,MAAM,SAAS,GAAG;;;AAIhC,SAAS,sBAAsB,KAAa,WAAW,IAAY;AACjE,KAAI,IAAI,UAAU,SAAU,QAAO;AACnC,QAAO,GAAG,IAAI,MAAM,GAAG,WAAW,EAAE,CAAC;;;AAIvC,SAAS,mBAAmB,OAAe,QAAwB;AACjE,QAAO,WAAW,OAAO,GAAG,MAAM,SAAS,GAAG,GAAG,WAAW,MAAM;;;AAIpE,SAAS,iBAAiB,QAAgB,aAAiC;CACzE,MAAM,WAAW,SAAS,GAAG,SAAS;CACtC,MAAM,EAAE,OAAO,aAAa,SAAS,OAAO;CAC5C,MAAM,KAAK,UAAU,OAAO,UAAU;CAEtC,IAAI;AACJ,KAAI,aAAa,WACf,qBAAoB,IAAI,YAAY,SAAS,GAAG;UACvC,aAAa,SAAS;EAC/B,MAAM,MAAM,SAAS,aAAa,EAAE;EACpC,MAAM,MAAM,SAAS,aAAa,GAAG;AACrC,sBAAoB,IAAI,mBAAmB,KAAK,OAAO,CAAC,IAAI,mBAAmB,KAAK,OAAO,CAAC;OAE5F,qBAAoB,mBAAmB,SAAS,aAAa,EAAE,EAAE,OAAO;AAG1E,QAAO,GAAG,GAAG,GAAG;;;AAIlB,SAAS,gBAAgB,QAAgB,QAAyB,aAAiC;CACjG,MAAM,UAAU,OAAO,WAAW,WAAW,OAAO,OAAO,GAAG,sBAAsB,WAAW,OAAO,CAAC;AACvG,QAAO,cAAc,iBAAiB,QAAQ,YAAY,CAAC,eAAe;;;;;;;;;;AAe5E,SAAS,MAAM,QAAa,UAAe,SAAkC;CAC3E,MAAM,EAAE,QAAQ,SAAS,SAAS,aAAa,OAAO;CACtD,MAAM,gBAAgB,WAAW,SAAS;AAG1C,KAAI,CAAC,QAAQ,gBAAgB;AAC3B,MAAI,cAAc,SAAS,EACzB,QAAO;GACL,IAAI;GACJ,YAAY,CACV;IACE,MAAM;IACN,SAAS;IACV,CACF;GACF;EAEH,MAAM,mBAAmB,QAAQ,SAAS;EAC1C,MAAM,iBAAiB,WAAW,cAAc,SAAS,GAAG,EAAE,CAAC;AAC/D,MAAI,mBAAmB,iBACrB,QAAO;GACL,IAAI;GACJ,YAAY,CACV;IACE,MAAM;IACN,SAAS,qBAAqB,iBAAiB,QAAQ;IACvD,eAAe;IAChB,CACF;GACF;;CAIL,MAAM,aAAa,QAAQ,iBAAiB,IAAIC,aAAG;CAGnD,MAAM,gBAA6B,EAAE;AAErC,MAAK,IAAI,aAAa,GAAG,aAAa,QAAQ,OAAO,QAAQ,cAAc;EACzE,MAAM,QAAQ,QAAQ,OAAO;EAC7B,IAAI,cAAc;AAElB,OAAK,IAAI,YAAY,GAAG,YAAY,MAAM,MAAM,QAAQ,aAAa;GACnE,MAAM,OAAO,MAAM,MAAM;GACzB,MAAM,YAAY,aAAa,MAAM,MAAM,eAAe,YAAY,YAAY,WAAW,QAAQ;AACrG,OAAI,cAAc,MAAM;AACtB,kBAAc,KAAK,UAAU;AAC7B,kBAAc;AACd;;;AAIJ,MAAI,CAAC,YACH,QAAO;GAAE,IAAI;GAAM,cAAc;GAAY;;AAIjD,QAAO;EAAE,IAAI;EAAO,YAAY;EAAe;;;;;;;;;;AAWjD,SAAS,QAAQ,QAAa,UAAe,SAAyB;CACpE,MAAM,SAAS,MAAM,QAAQ,UAAU,QAAQ;AAC/C,KAAI,CAAC,OAAO,GACV,OAAM,IAAI,qBAAqB,OAAO,WAAW;;;AASrD,SAAS,aACP,MAMA,MACA,eACA,YACA,YACA,WACA,SACkB;CAClB,MAAM,QAAQ,KAAK,MAAM;CACzB,MAAM,YAAY,WAAW,KAAK,KAAK,MAAM;CAC7C,MAAM,SAAS,KAAK,OAAO;CAC3B,MAAM,cAAc,WAAW,KAAK,KAAK,MAAM;AAE/C,KAAI,UAAU,SAAS,IAAI,OAAO,eAChC,OAAM,IAAI,cACR,gBACA,cAAc,UAAU,SAAS,EAAE,mBAAmB,OAAO,eAAe,GAC7E;AAGH,KAAI,UAAU,MAAM,QAClB,QAAO,oBAAoB,WAAW,QAAQ,aAAa,YAAY,WAAW,KAAK,KAAK,OAAO,QAAQ;CAI7G,MAAM,YAAY,OAAO,MAAM,eAAe,WAAW,WAAW;AAEpE,KAAI,CAAC,UAAU,GACb,QAAO;EACL,OAAO;EACP,MAAM;EACN,MAAM,UAAU;EAChB,SAAS,sBAAsB,UAAU;EACzC,MAAM,KAAK,KAAK;EACjB;AAIH,KAAI,UAAU,SAAS,aACrB,QAAO,mBACL,UAAU,YACV,eACA,QACA,aACA,YACA,WACA,KAAK,KAAK,MACX;AAIH,QAAO,aAAa,UAAU,UAAU,eAAe,QAAQ,aAAa,YAAY,WAAW,KAAK,KAAK,MAAM;;;AAQrH,SAAS,oBACP,WACA,QACA,aACA,YACA,WACA,SACA,SACkB;CAClB,MAAM,aAAa,QAAQ,WAAW,EAAE;AAExC,KAAI,aAAa,wBACf,OAAM,IAAI,cACR,wBACA,iCAAiC,WAAW,SAAS,GAAG,CAAC,SAAS,GAAG,IAAI,GAC1E;CAGH,MAAM,WAAW,sBAAsB,WAAW;CAClD,MAAM,eAAe,UAAU,SAAS;AAExC,KAAI,iBAAiB,KAAA,EACnB,QAAO;EACL,OAAO;EACP,MAAM;EACN,MAAM;EACN,SAAS,oBAAoB,SAAS,MAAM;EAC5C,MAAM;EACP;CAGH,IAAI;AACJ,KAAI,OAAO,iBAAiB,SAC1B,SAAQ,gBAAgB,aAAa;KAErC,SAAQ;AAKV,KAAI,CAFW,cAAc,QAAQ,OAAO,IAAI,aAAa,SAAS,SAE3D,CACT,QAAO;EACL,OAAO;EACP,MAAM;EACN,MAAM;EACN,SAAS,gBAAgB,QAAQ,OAAO,YAAY;EACpD,MAAM;EACN,eAAe,YAAY,MAAM;EAClC;AAGH,QAAO;;;AAaT,SAAS,kBACP,eACA,UACA,QACA,aACY;CACZ,MAAM,EAAE,SAAS;AAEjB,KAAI,WAAW,OAAO,EAAE;EACtB,IAAI;AAEJ,MAAI,KAAK,WAAW;GAClB,MAAM,eAAe,UAAU,eAAe,SAAS;AACvD,OAAI,CAAC,aAAa,GAAI,QAAO,EAAE,OAAO,aAAa,MAAM;AACzD,iBAAc,aAAa;QAE3B,eAAc,KAAK;AAIrB,SAAO;GAAE,QADM,cAAc,QAAQ,IAAI,aAAa,aAAa,KAAK,SACzD;GAAE,QAAQ;GAAa;;CAGxC,MAAM,SAAS,WAAW,eAAe,SAAS;AAClD,KAAI,CAAC,OAAO,GAAI,QAAO,EAAE,OAAO,OAAO,MAAM;CAE7C,MAAM,QAAQ,SAAS,OAAO,OAAO,EAAE;AAEvC,QAAO;EAAE,QADM,cAAc,QAAQ,OAAO,IAAI,aAAa,KAAK,SACnD;EAAE;EAAO;;;AAQ1B,SAAS,aACP,UACA,eACA,QACA,aACA,YACA,WACA,SACkB;CAClB,MAAM,SAAS,kBAAkB,eAAe,UAAU,QAAQ,YAAY;AAE9E,KAAI,WAAW,QAAQ;EACrB,MAAM,UAAU,WAAW,OAAO,GAC9B,0BAA0B,OAAO,UACjC,yBAAyB,OAAO;AACpC,SAAO;GACL,OAAO;GACP,MAAM;GACN,MAAM,OAAO;GACb;GACA,MAAM;GACP;;AAGH,KAAI,CAAC,OAAO,QAAQ;EAClB,MAAM,SAA0B,OAAO,UAAU,KAAA,IAAY,OAAO,QAAS,OAAO,UAAU;AAC9F,SAAO;GACL,OAAO;GACP,MAAM;GACN,MAAM;GACN,SAAS,gBAAgB,QAAQ,QAAQ,YAAY;GACrD,MAAM;GACN,eAAe,YAAY,OAAO,WAAW,WAAW,OAAO,OAAO,GAAG,OAAO;GACjF;;AAGH,QAAO;;;AAQT,SAAS,mBACP,SAKA,eACA,QACA,aACA,YACA,WACA,SACkB;CAClB,MAAM,EAAE,YAAY,UAAU,eAAe,kBAAkB;CAG/D,MAAM,cAAc,WAAW,eAAe,cAAc;AAC5D,KAAI,CAAC,YAAY,GACf,QAAO;EACL,OAAO;EACP,MAAM;EACN,MAAM,YAAY;EAClB,SAAS,+BAA+B,YAAY;EACpD,MAAM;EACP;CAEH,MAAM,QAAQ,YAAY;AAG1B,KAAI,MAAM,SAAS,OAAO,4BACxB,QAAO;EACL,OAAO;EACP,MAAM;EACN,MAAM;EACN,SAAS,gBAAgB,MAAM,OAAO,mBAAmB,OAAO;EAChE,MAAM;EACP;AAIH,KAAI,MAAM,WAAW,GAAG;AACtB,MAAI,eAAe,WAAW,aAC5B,QAAO;AAET,SAAO;GACL,OAAO;GACP,MAAM;GACN,MAAM;GACN,SAAS;GACT,MAAM;GACP;;CAGH,MAAM,cAAc,eAAe,WAAW,gBAAgB,eAAe,WAAW;CACxF,MAAM,YAAY,cAAc,SAAS;AAEzC,MAAK,IAAI,YAAY,GAAG,YAAY,MAAM,QAAQ,aAAa;EAE7D,MAAM,aAAa,eAAe,OAAO,WAAW,cAAc;AAClE,MAAI,CAAC,WAAW,IAAI;AAClB,OAAI,YACF,QAAO;IACL,OAAO;IACP,MAAM;IACN,MAAM,WAAW;IACjB,SAAS,sBAAsB,UAAU,IAAI,WAAW;IACxD,MAAM;IACP;AAEH;;EAEF,MAAM,eAAe,WAAW;EAEhC,IAAI;AAEJ,MAAI,WAAW;GAEb,MAAM,aAAa,YAAY,eAAe,cAAc,cAAc;AAE1E,OAAI,CAAC,WAAW,IAAI;AAClB,QAAI,YACF,QAAO;KACL,OAAO;KACP,MAAM;KACN,MAAM,WAAW;KACjB,SAAS,sBAAsB,UAAU,sBAAsB,WAAW;KAC1E,MAAM;KACP;AAEH;;AAGF,gBAAa,kBAAkB,WAAW,UAAU,eAAe,QAAQ,YAAY;SAClF;GAEL,MAAM,aAAa,kBAAkB,eAAe,cAAc,QAAQ,YAAY;AACtF,OAAI,WAAW,YAAY;AACzB,QAAI,YACF,QAAO;KACL,OAAO;KACP,MAAM;KACN,MAAM,WAAW;KACjB,SAAS,sBAAsB,UAAU,IAAI,WAAW;KACxD,MAAM;KACP;AAEH;;AAEF,gBAAa,WAAW;;AAI1B,MAAI,eAAe,CAAC,WAClB,QAAO;GACL,OAAO;GACP,MAAM;GACN,MAAM;GACN,SAAS,cAAc,iBAAiB,QAAQ,YAAY,CAAC,uBAAuB;GACpF,MAAM;GACP;AAEH,MAAI,CAAC,eAAe,WAClB,QAAO;;AAIX,KAAI,YACF,QAAO;AAET,QAAO;EACL,OAAO;EACP,MAAM;EACN,MAAM;EACN,SAAS,cAAc,iBAAiB,QAAQ,YAAY,CAAC;EAC7D,MAAM;EACP;;;AAQH,SAAS,kBACP,UACA,eACA,QACA,aACS;CACT,MAAM,SAAS,kBAAkB,eAAe,UAAU,QAAQ,YAAY;AAC9E,KAAI,WAAW,OAAQ,QAAO;AAC9B,QAAO,OAAO;;;AAIhB,MAAa,iBAAiB;CAAE;CAAO;CAAS"}
|