@bcts/envelope 1.0.0-alpha.7 → 1.0.0-alpha.9
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.cjs.map +1 -1
- package/dist/index.d.cts +353 -549
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +353 -549
- package/dist/index.d.mts.map +1 -1
- package/dist/index.iife.js.map +1 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +9 -9
- package/src/base/assertions.ts +0 -151
- package/src/base/elide.ts +0 -136
- package/src/base/envelope-decodable.ts +0 -43
- package/src/base/envelope.ts +199 -1
- package/src/base/leaf.ts +1 -80
- package/src/base/queries.ts +0 -130
- package/src/base/walk.ts +0 -26
- package/src/base/wrap.ts +0 -46
- package/src/extension/attachment.ts +0 -89
- package/src/extension/compress.ts +0 -117
- package/src/extension/encrypt.ts +0 -82
- package/src/extension/proof.ts +0 -49
- package/src/extension/recipient.ts +0 -117
- package/src/extension/salt.ts +0 -109
- package/src/extension/signature.ts +0 -65
- package/src/extension/types.ts +0 -130
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["#data","#predicate","#object","#digest","CborMap","cbor","#compressedData","#digest","cbor","createSecureRng","SecureRandomNumberGenerator","#key","SYMMETRIC_KEY_SIZE","SYMMETRIC_NONCE_SIZE","#ciphertext","#nonce","#authTag","#aadDigest","encodedCbor","encryptedMessage","cbor","TAG_ENVELOPE","ENVELOPE","LEAF","ENCRYPTED","COMPRESSED","#case","KnownValue","cbor","TAG_ENCODED_CBOR","assertions: Envelope[]","MajorType","ENVELOPE","envelope: Envelope","cbor","cbor","SecureRandomNumberGenerator","#data","#privateKey","ECDSA_PRIVATE_KEY_SIZE","SecureRandomNumberGenerator","#publicKey","ECDSA_PUBLIC_KEY_SIZE","ECDSA_UNCOMPRESSED_PUBLIC_KEY_SIZE","#assertions","#envelopes","#publicKey","X25519_PUBLIC_KEY_SIZE","#privateKey","SecureRandomNumberGenerator","X25519_PRIVATE_KEY_SIZE","#data","SYMMETRIC_NONCE_SIZE","SYMMETRIC_AUTH_SIZE","contentKey: SymmetricKey | null","#id","#value","#function","#parameters","#envelope","funcId: FunctionID","paramId: ParameterID","cbor","entries: string[]","elements: TreeElement[]","parts: string[]"],"sources":["../src/base/digest.ts","../src/base/error.ts","../src/base/assertion.ts","../src/extension/compress.ts","../src/extension/encrypt.ts","../src/base/envelope.ts","../src/base/envelope-encodable.ts","../src/base/cbor.ts","../src/base/envelope-decodable.ts","../src/base/elide.ts","../src/base/walk.ts","../src/base/assertions.ts","../src/base/leaf.ts","../src/base/queries.ts","../src/base/wrap.ts","../src/extension/types.ts","../src/extension/salt.ts","../src/extension/signature.ts","../src/extension/attachment.ts","../src/extension/recipient.ts","../src/extension/expression.ts","../src/extension/proof.ts","../src/format/hex.ts","../src/format/diagnostic.ts","../src/format/tree.ts","../src/utils/string.ts","../src/index.ts"],"sourcesContent":["import { sha256 } from \"@bcts/crypto\";\n\n/// A cryptographic digest used to uniquely identify digital objects.\n///\n/// Digests in Gordian Envelope are always SHA-256 hashes (32 bytes).\n/// This is a fundamental building block for the Merkle-like digest tree\n/// that enables privacy features while maintaining integrity.\n///\n/// Based on BCR-2021-002: Digests for Digital Objects\n/// @see https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2021-002-digest.md\nexport class Digest {\n readonly #data: Uint8Array;\n\n /// Creates a new Digest from raw bytes.\n ///\n /// @param data - The 32-byte digest data\n /// @throws {Error} If data is not exactly 32 bytes\n constructor(data: Uint8Array) {\n if (data.length !== 32) {\n throw new Error(`Digest must be exactly 32 bytes, got ${data.length} bytes`);\n }\n this.#data = data;\n }\n\n /// Returns the raw digest bytes.\n ///\n /// @returns A Uint8Array containing the 32-byte digest\n data(): Uint8Array {\n return this.#data;\n }\n\n /// Creates a digest from an image (arbitrary byte array).\n ///\n /// This is the primary way to create a digest from data. The data is\n /// hashed using SHA-256 to produce a 32-byte digest.\n ///\n /// @param image - The data to hash\n /// @returns A new Digest instance\n ///\n /// @example\n /// ```typescript\n /// const digest = Digest.fromImage(new TextEncoder().encode(\"Hello, world!\"));\n /// ```\n static fromImage(image: Uint8Array): Digest {\n const hash = sha256(image);\n return new Digest(hash);\n }\n\n /// Creates a digest from multiple digests.\n ///\n /// This is used to combine digests in the Merkle-like tree structure.\n /// The digests are concatenated and then hashed.\n ///\n /// @param digests - An array of digests to combine\n /// @returns A new Digest instance representing the combined digests\n ///\n /// @example\n /// ```typescript\n /// const digest1 = Digest.fromImage(data1);\n /// const digest2 = Digest.fromImage(data2);\n /// const combined = Digest.fromDigests([digest1, digest2]);\n /// ```\n static fromDigests(digests: Digest[]): Digest {\n const totalLength = digests.length * 32;\n const combined = new Uint8Array(totalLength);\n let offset = 0;\n for (const digest of digests) {\n combined.set(digest.data(), offset);\n offset += 32;\n }\n return Digest.fromImage(combined);\n }\n\n /// Returns the hexadecimal string representation of the digest.\n ///\n /// @returns A 64-character hexadecimal string\n ///\n /// @example\n /// ```typescript\n /// const digest = Digest.fromImage(data);\n /// console.log(digest.hex()); // \"5feceb66ffc86f38d952786c6d696c79c2dbc239dd4e91b46729d73a27fb57e9\"\n /// ```\n hex(): string {\n return Array.from(this.#data)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n }\n\n /// Returns an abbreviated hexadecimal representation for visual comparison.\n ///\n /// Following Blockchain Commons conventions, this returns the first 7\n /// hexadecimal digits of the digest, which provides sufficient entropy\n /// for human visual comparison while being easy to read.\n ///\n /// @returns A 7-character hexadecimal string\n ///\n /// @example\n /// ```typescript\n /// const digest = Digest.fromImage(data);\n /// console.log(digest.short()); // \"5feceb6\"\n /// ```\n short(): string {\n return this.hex().substring(0, 7);\n }\n\n /// Creates a digest from a hexadecimal string.\n ///\n /// @param hex - A 64-character hexadecimal string\n /// @returns A new Digest instance\n /// @throws {Error} If the hex string is not exactly 64 characters\n ///\n /// @example\n /// ```typescript\n /// const digest = Digest.fromHex(\"5feceb66ffc86f38d952786c6d696c79c2dbc239dd4e91b46729d73a27fb57e9\");\n /// ```\n static fromHex(hex: string): Digest {\n if (hex.length !== 64) {\n throw new Error(`Hex string must be exactly 64 characters, got ${hex.length}`);\n }\n const data = new Uint8Array(32);\n for (let i = 0; i < 32; i++) {\n data[i] = parseInt(hex.substring(i * 2, i * 2 + 2), 16);\n }\n return new Digest(data);\n }\n\n /// Checks if two digests are equal.\n ///\n /// @param other - The other digest to compare with\n /// @returns `true` if the digests are equal, `false` otherwise\n equals(other: Digest): boolean {\n if (this.#data.length !== other.#data.length) {\n return false;\n }\n for (let i = 0; i < this.#data.length; i++) {\n if (this.#data[i] !== other.#data[i]) {\n return false;\n }\n }\n return true;\n }\n\n /// Returns a string representation of the digest (short form).\n ///\n /// @returns The short hexadecimal representation\n toString(): string {\n return this.short();\n }\n\n /// Creates a deep copy of the digest.\n ///\n /// @returns A new Digest instance with the same data\n clone(): Digest {\n return new Digest(new Uint8Array(this.#data));\n }\n}\n\n/// Trait for types that can provide a digest.\n///\n/// This is equivalent to Rust's `DigestProvider` trait. Types that\n/// implement this interface can be used in contexts where a digest\n/// is needed for identity or integrity verification.\nexport interface DigestProvider {\n /// Returns the digest of this object.\n ///\n /// The digest uniquely identifies the semantic content of the object,\n /// regardless of whether parts of it are elided, encrypted, or compressed.\n digest(): Digest;\n}\n\n/// Helper function to create a digest from a string.\n///\n/// This is a convenience function for creating digests from text strings,\n/// which are encoded as UTF-8 before hashing.\n///\n/// @param text - The text to hash\n/// @returns A new Digest instance\n///\n/// @example\n/// ```typescript\n/// const digest = digestFromString(\"Hello, world!\");\n/// ```\nexport function digestFromString(text: string): Digest {\n const encoder = new TextEncoder();\n return Digest.fromImage(encoder.encode(text));\n}\n\n/// Helper function to create a digest from a number.\n///\n/// The number is converted to a big-endian byte representation before hashing.\n///\n/// @param num - The number to hash\n/// @returns A new Digest instance\n///\n/// @example\n/// ```typescript\n/// const digest = digestFromNumber(42);\n/// ```\nexport function digestFromNumber(num: number): Digest {\n const buffer = new ArrayBuffer(8);\n const view = new DataView(buffer);\n view.setFloat64(0, num, false); // big-endian\n return Digest.fromImage(new Uint8Array(buffer));\n}\n","/// Error types returned when operating on Gordian Envelopes.\n///\n/// These errors capture various conditions that can occur when working with\n/// envelopes, including structure validation, operation constraints, and\n/// extension-specific errors.\n///\n/// The errors are organized by category, reflecting the base envelope\n/// specification and various extensions defined in the Gordian Envelope\n/// Internet Draft and Blockchain Commons Research (BCR) documents.\n\nexport enum ErrorCode {\n // Base Specification\n ALREADY_ELIDED = \"ALREADY_ELIDED\",\n AMBIGUOUS_PREDICATE = \"AMBIGUOUS_PREDICATE\",\n INVALID_DIGEST = \"INVALID_DIGEST\",\n INVALID_FORMAT = \"INVALID_FORMAT\",\n MISSING_DIGEST = \"MISSING_DIGEST\",\n NONEXISTENT_PREDICATE = \"NONEXISTENT_PREDICATE\",\n NOT_WRAPPED = \"NOT_WRAPPED\",\n NOT_LEAF = \"NOT_LEAF\",\n NOT_ASSERTION = \"NOT_ASSERTION\",\n INVALID_ASSERTION = \"INVALID_ASSERTION\",\n\n // Attachments Extension\n INVALID_ATTACHMENT = \"INVALID_ATTACHMENT\",\n NONEXISTENT_ATTACHMENT = \"NONEXISTENT_ATTACHMENT\",\n AMBIGUOUS_ATTACHMENT = \"AMBIGUOUS_ATTACHMENT\",\n\n // Compression Extension\n ALREADY_COMPRESSED = \"ALREADY_COMPRESSED\",\n NOT_COMPRESSED = \"NOT_COMPRESSED\",\n\n // Symmetric Encryption Extension\n ALREADY_ENCRYPTED = \"ALREADY_ENCRYPTED\",\n NOT_ENCRYPTED = \"NOT_ENCRYPTED\",\n\n // Known Values Extension\n NOT_KNOWN_VALUE = \"NOT_KNOWN_VALUE\",\n\n // Public Key Encryption Extension\n UNKNOWN_RECIPIENT = \"UNKNOWN_RECIPIENT\",\n\n // Encrypted Key Extension\n UNKNOWN_SECRET = \"UNKNOWN_SECRET\",\n\n // Public Key Signing Extension\n UNVERIFIED_SIGNATURE = \"UNVERIFIED_SIGNATURE\",\n INVALID_OUTER_SIGNATURE_TYPE = \"INVALID_OUTER_SIGNATURE_TYPE\",\n INVALID_INNER_SIGNATURE_TYPE = \"INVALID_INNER_SIGNATURE_TYPE\",\n UNVERIFIED_INNER_SIGNATURE = \"UNVERIFIED_INNER_SIGNATURE\",\n INVALID_SIGNATURE_TYPE = \"INVALID_SIGNATURE_TYPE\",\n\n // SSKR Extension\n INVALID_SHARES = \"INVALID_SHARES\",\n SSKR = \"SSKR\",\n\n // Types Extension\n INVALID_TYPE = \"INVALID_TYPE\",\n AMBIGUOUS_TYPE = \"AMBIGUOUS_TYPE\",\n\n // Expressions Extension\n UNEXPECTED_RESPONSE_ID = \"UNEXPECTED_RESPONSE_ID\",\n INVALID_RESPONSE = \"INVALID_RESPONSE\",\n\n // External errors\n CBOR = \"CBOR\",\n COMPONENTS = \"COMPONENTS\",\n GENERAL = \"GENERAL\",\n}\n\nexport class EnvelopeError extends Error {\n readonly code: ErrorCode;\n declare readonly cause?: Error;\n\n constructor(code: ErrorCode, message: string, cause?: Error) {\n super(message);\n this.name = \"EnvelopeError\";\n this.code = code;\n if (cause !== undefined) {\n this.cause = cause;\n }\n\n // Maintains proper stack trace for where our error was thrown (only available on V8)\n if (\"captureStackTrace\" in Error) {\n (\n Error as {\n captureStackTrace(target: object, constructor: typeof EnvelopeError): void;\n }\n ).captureStackTrace(this, EnvelopeError);\n }\n }\n\n //\n // Base Specification\n /// Returned when attempting to compress or encrypt an envelope that has\n /// already been elided.\n ///\n /// This error occurs because an elided envelope only contains a digest\n /// reference and no longer has a subject that can be compressed or\n /// encrypted.\n static alreadyElided(): EnvelopeError {\n return new EnvelopeError(\n ErrorCode.ALREADY_ELIDED,\n \"envelope was elided, so it cannot be compressed or encrypted\",\n );\n }\n\n /// Returned when attempting to retrieve an assertion by predicate, but\n /// multiple matching assertions exist.\n ///\n /// For queries that expect a single result (like `objectForPredicate`),\n /// having multiple matching assertions is ambiguous and requires more\n /// specific targeting.\n static ambiguousPredicate(): EnvelopeError {\n return new EnvelopeError(\n ErrorCode.AMBIGUOUS_PREDICATE,\n \"more than one assertion matches the predicate\",\n );\n }\n\n /// Returned when a digest validation fails.\n ///\n /// This can occur when unwrapping an envelope, verifying signatures, or\n /// other operations that rely on the integrity of envelope digests.\n static invalidDigest(): EnvelopeError {\n return new EnvelopeError(ErrorCode.INVALID_DIGEST, \"digest did not match\");\n }\n\n /// Returned when an envelope's format is invalid.\n ///\n /// This typically occurs during parsing or decoding of an envelope from\n /// CBOR.\n static invalidFormat(): EnvelopeError {\n return new EnvelopeError(ErrorCode.INVALID_FORMAT, \"invalid format\");\n }\n\n /// Returned when a digest is expected but not found.\n ///\n /// This can occur when working with envelope structures that require digest\n /// information, such as when working with elided envelopes.\n static missingDigest(): EnvelopeError {\n return new EnvelopeError(ErrorCode.MISSING_DIGEST, \"a digest was expected but not found\");\n }\n\n /// Returned when attempting to retrieve an assertion by predicate, but no\n /// matching assertion exists.\n ///\n /// This error occurs with functions like `objectForPredicate` when the\n /// specified predicate doesn't match any assertion in the envelope.\n static nonexistentPredicate(): EnvelopeError {\n return new EnvelopeError(ErrorCode.NONEXISTENT_PREDICATE, \"no assertion matches the predicate\");\n }\n\n /// Returned when attempting to unwrap an envelope that wasn't wrapped.\n ///\n /// This error occurs when calling `Envelope.tryUnwrap` on an\n /// envelope that doesn't have the wrapped format.\n static notWrapped(): EnvelopeError {\n return new EnvelopeError(\n ErrorCode.NOT_WRAPPED,\n \"cannot unwrap an envelope that was not wrapped\",\n );\n }\n\n /// Returned when expecting an envelope's subject to be a leaf, but it\n /// isn't.\n ///\n /// This error occurs when calling methods that require access to a leaf\n /// value but the envelope's subject is an assertion, node, or elided.\n static notLeaf(): EnvelopeError {\n return new EnvelopeError(ErrorCode.NOT_LEAF, \"the envelope's subject is not a leaf\");\n }\n\n /// Returned when expecting an envelope's subject to be an assertion, but it\n /// isn't.\n ///\n /// This error occurs when calling methods that require an assertion\n /// structure but the envelope's subject has a different format.\n static notAssertion(): EnvelopeError {\n return new EnvelopeError(ErrorCode.NOT_ASSERTION, \"the envelope's subject is not an assertion\");\n }\n\n /// Returned when assertion is invalid\n static invalidAssertion(): EnvelopeError {\n return new EnvelopeError(\n ErrorCode.INVALID_ASSERTION,\n \"assertion must be a map with exactly one element\",\n );\n }\n\n //\n // Attachments Extension\n /// Returned when an attachment's format is invalid.\n ///\n /// This error occurs when an envelope contains an attachment with an\n /// invalid structure according to the Envelope Attachment specification\n /// (BCR-2023-006).\n static invalidAttachment(): EnvelopeError {\n return new EnvelopeError(ErrorCode.INVALID_ATTACHMENT, \"invalid attachment\");\n }\n\n /// Returned when an attachment is requested but does not exist.\n ///\n /// This error occurs when attempting to retrieve an attachment by ID that\n /// doesn't exist in the envelope.\n static nonexistentAttachment(): EnvelopeError {\n return new EnvelopeError(ErrorCode.NONEXISTENT_ATTACHMENT, \"nonexistent attachment\");\n }\n\n /// Returned when multiple attachments match a single query.\n ///\n /// This error occurs when multiple attachments have the same ID, making\n /// it ambiguous which attachment should be returned.\n static ambiguousAttachment(): EnvelopeError {\n return new EnvelopeError(ErrorCode.AMBIGUOUS_ATTACHMENT, \"ambiguous attachment\");\n }\n\n //\n // Compression Extension\n /// Returned when attempting to compress an envelope that is already\n /// compressed.\n ///\n /// This error occurs when calling compression functions on an envelope that\n /// already has compressed content, as defined in BCR-2023-005.\n static alreadyCompressed(): EnvelopeError {\n return new EnvelopeError(ErrorCode.ALREADY_COMPRESSED, \"envelope was already compressed\");\n }\n\n /// Returned when attempting to decompress an envelope that is not\n /// compressed.\n ///\n /// This error occurs when calling decompression functions on an envelope\n /// that doesn't contain compressed content.\n static notCompressed(): EnvelopeError {\n return new EnvelopeError(\n ErrorCode.NOT_COMPRESSED,\n \"cannot decompress an envelope that was not compressed\",\n );\n }\n\n //\n // Symmetric Encryption Extension\n /// Returned when attempting to encrypt an envelope that is already\n /// encrypted or compressed.\n ///\n /// This error occurs to prevent multiple layers of encryption or encryption\n /// of compressed data, which could reduce security, as defined in\n /// BCR-2023-004.\n static alreadyEncrypted(): EnvelopeError {\n return new EnvelopeError(\n ErrorCode.ALREADY_ENCRYPTED,\n \"envelope was already encrypted or compressed, so it cannot be encrypted\",\n );\n }\n\n /// Returned when attempting to decrypt an envelope that is not encrypted.\n ///\n /// This error occurs when calling decryption functions on an envelope that\n /// doesn't contain encrypted content.\n static notEncrypted(): EnvelopeError {\n return new EnvelopeError(\n ErrorCode.NOT_ENCRYPTED,\n \"cannot decrypt an envelope that was not encrypted\",\n );\n }\n\n //\n // Known Values Extension\n /// Returned when expecting an envelope's subject to be a known value, but\n /// it isn't.\n ///\n /// This error occurs when calling methods that require a known value (as\n /// defined in BCR-2023-003) but the envelope's subject is a different\n /// type.\n static notKnownValue(): EnvelopeError {\n return new EnvelopeError(\n ErrorCode.NOT_KNOWN_VALUE,\n \"the envelope's subject is not a known value\",\n );\n }\n\n //\n // Public Key Encryption Extension\n /// Returned when attempting to decrypt an envelope with a recipient that\n /// doesn't match.\n ///\n /// This error occurs when trying to use a private key to decrypt an\n /// envelope that wasn't encrypted for the corresponding public key.\n static unknownRecipient(): EnvelopeError {\n return new EnvelopeError(ErrorCode.UNKNOWN_RECIPIENT, \"unknown recipient\");\n }\n\n //\n // Encrypted Key Extension\n /// Returned when attempting to decrypt an envelope with a secret that\n /// doesn't match.\n ///\n /// This error occurs when trying to use a secret that does not correspond\n /// to the expected recipient, preventing successful decryption.\n static unknownSecret(): EnvelopeError {\n return new EnvelopeError(ErrorCode.UNKNOWN_SECRET, \"secret not found\");\n }\n\n //\n // Public Key Signing Extension\n /// Returned when a signature verification fails.\n ///\n /// This error occurs when a signature does not validate against its\n /// purported public key.\n static unverifiedSignature(): EnvelopeError {\n return new EnvelopeError(ErrorCode.UNVERIFIED_SIGNATURE, \"could not verify a signature\");\n }\n\n /// Returned when the outer signature object type is not `Signature`.\n static invalidOuterSignatureType(): EnvelopeError {\n return new EnvelopeError(\n ErrorCode.INVALID_OUTER_SIGNATURE_TYPE,\n \"unexpected outer signature object type\",\n );\n }\n\n /// Returned when the inner signature object type is not `Signature`.\n static invalidInnerSignatureType(): EnvelopeError {\n return new EnvelopeError(\n ErrorCode.INVALID_INNER_SIGNATURE_TYPE,\n \"unexpected inner signature object type\",\n );\n }\n\n /// Returned when the inner signature is not made with the same key as the\n /// outer signature.\n static unverifiedInnerSignature(): EnvelopeError {\n return new EnvelopeError(\n ErrorCode.UNVERIFIED_INNER_SIGNATURE,\n \"inner signature not made with same key as outer signature\",\n );\n }\n\n /// Returned when the signature object is not a `Signature`.\n static invalidSignatureType(): EnvelopeError {\n return new EnvelopeError(ErrorCode.INVALID_SIGNATURE_TYPE, \"unexpected signature object type\");\n }\n\n //\n // SSKR Extension\n /// Returned when SSKR shares are invalid or insufficient for\n /// reconstruction.\n ///\n /// This error occurs when attempting to join SSKR shares that are\n /// malformed, from different splits, or insufficient to meet the\n /// recovery threshold.\n static invalidShares(): EnvelopeError {\n return new EnvelopeError(ErrorCode.INVALID_SHARES, \"invalid SSKR shares\");\n }\n\n /// SSKR error wrapper\n static sskr(message: string, cause?: Error): EnvelopeError {\n return new EnvelopeError(ErrorCode.SSKR, `sskr error: ${message}`, cause);\n }\n\n //\n // Types Extension\n /// Returned when an envelope contains an invalid type.\n ///\n /// This error occurs when an envelope's type information doesn't match\n /// the expected format or value.\n static invalidType(): EnvelopeError {\n return new EnvelopeError(ErrorCode.INVALID_TYPE, \"invalid type\");\n }\n\n /// Returned when an envelope contains ambiguous type information.\n ///\n /// This error occurs when multiple type assertions exist that conflict\n /// with each other or create ambiguity about the envelope's type.\n static ambiguousType(): EnvelopeError {\n return new EnvelopeError(ErrorCode.AMBIGUOUS_TYPE, \"ambiguous type\");\n }\n\n //\n // Expressions Extension\n /// Returned when a response envelope has an unexpected ID.\n ///\n /// This error occurs when processing a response envelope and the ID doesn't\n /// match the expected request ID, as defined in BCR-2023-012.\n static unexpectedResponseId(): EnvelopeError {\n return new EnvelopeError(ErrorCode.UNEXPECTED_RESPONSE_ID, \"unexpected response ID\");\n }\n\n /// Returned when a response envelope is invalid.\n static invalidResponse(): EnvelopeError {\n return new EnvelopeError(ErrorCode.INVALID_RESPONSE, \"invalid response\");\n }\n\n //\n // External errors\n /// dcbor error wrapper\n static cbor(message: string, cause?: Error): EnvelopeError {\n return new EnvelopeError(ErrorCode.CBOR, `dcbor error: ${message}`, cause);\n }\n\n /// Components error wrapper\n static components(message: string, cause?: Error): EnvelopeError {\n return new EnvelopeError(ErrorCode.COMPONENTS, `components error: ${message}`, cause);\n }\n\n /// General error wrapper\n static general(message: string, cause?: Error): EnvelopeError {\n return new EnvelopeError(ErrorCode.GENERAL, `general error: ${message}`, cause);\n }\n\n /// Create error with custom message (equivalent to Rust's Error::msg)\n static msg(message: string): EnvelopeError {\n return EnvelopeError.general(message);\n }\n}\n\n/// Type alias for Result type (for Rust compatibility)\nexport type Result<T> = T;\n\n/// Export for backward compatibility\nexport type { EnvelopeError as Error };\n","import { Digest, type DigestProvider } from \"./digest\";\nimport { Envelope } from \"./envelope\";\nimport { type EnvelopeEncodable } from \"./envelope-encodable\";\nimport { EnvelopeError } from \"./error\";\nimport type { Cbor } from \"@bcts/dcbor\";\nimport { CborMap } from \"@bcts/dcbor\";\n\n/// A predicate-object relationship representing an assertion about a subject.\n///\n/// In Gordian Envelope, assertions are the basic building blocks for attaching\n/// information to a subject. An assertion consists of a predicate (which states\n/// what is being asserted) and an object (which provides the assertion's\n/// value).\n///\n/// Assertions can be attached to envelope subjects to form semantic statements\n/// like: \"subject hasAttribute value\" or \"document signedBy signature\".\n///\n/// Assertions are equivalent to RDF (Resource Description Framework) triples,\n/// where:\n/// - The envelope's subject is the subject of the triple\n/// - The assertion's predicate is the predicate of the triple\n/// - The assertion's object is the object of the triple\n///\n/// Generally you do not create an instance of this type directly, but\n/// instead use `Envelope.newAssertion()`, or the various functions\n/// on `Envelope` that create assertions.\nexport class Assertion implements DigestProvider {\n readonly #predicate: Envelope;\n readonly #object: Envelope;\n readonly #digest: Digest;\n\n /// Creates a new assertion and calculates its digest.\n ///\n /// This constructor takes a predicate and object, both of which are\n /// converted to envelopes using the `EnvelopeEncodable` trait. It then\n /// calculates the assertion's digest by combining the digests of the\n /// predicate and object.\n ///\n /// The digest is calculated according to the Gordian Envelope\n /// specification, which ensures that semantically equivalent assertions\n /// always produce the same digest.\n ///\n /// @param predicate - The predicate of the assertion, which states what is\n /// being asserted\n /// @param object - The object of the assertion, which provides the assertion's\n /// value\n ///\n /// @returns A new assertion with the specified predicate, object, and calculated\n /// digest.\n ///\n /// @example\n /// ```typescript\n /// // Direct method - create an assertion envelope\n /// const assertionEnvelope = Envelope.newAssertion(\"name\", \"Alice\");\n ///\n /// // Or create and add an assertion to a subject\n /// const person = Envelope.new(\"person\").addAssertion(\"name\", \"Alice\");\n /// ```\n constructor(predicate: EnvelopeEncodable | Envelope, object: EnvelopeEncodable | Envelope) {\n this.#predicate = predicate instanceof Envelope ? predicate : Envelope.new(predicate);\n this.#object = object instanceof Envelope ? object : Envelope.new(object);\n this.#digest = Digest.fromDigests([this.#predicate.digest(), this.#object.digest()]);\n }\n\n /// Returns the predicate of the assertion.\n ///\n /// The predicate states what is being asserted about the subject. It is\n /// typically a string or known value, but can be any envelope.\n ///\n /// @returns A clone of the assertion's predicate envelope.\n predicate(): Envelope {\n return this.#predicate;\n }\n\n /// Returns the object of the assertion.\n ///\n /// The object provides the value or content of the assertion. It can be any\n /// type that can be represented as an envelope.\n ///\n /// @returns A clone of the assertion's object envelope.\n object(): Envelope {\n return this.#object;\n }\n\n /// Returns the digest of this assertion.\n ///\n /// Implementation of the DigestProvider interface.\n ///\n /// @returns The assertion's digest\n digest(): Digest {\n return this.#digest;\n }\n\n /// Checks if two assertions are equal based on digest equality.\n ///\n /// Two assertions are considered equal if they have the same digest,\n /// regardless of how they were constructed.\n ///\n /// @param other - The other assertion to compare with\n /// @returns `true` if the assertions are equal, `false` otherwise\n equals(other: Assertion): boolean {\n return this.#digest.equals(other.#digest);\n }\n\n /// Converts this assertion to CBOR.\n ///\n /// The CBOR representation of an assertion is a map with a single key-value\n /// pair, where the key is the predicate's CBOR and the value is the object's\n /// CBOR.\n ///\n /// @returns A CBOR representation of this assertion\n toCbor(): Cbor {\n const map = new CborMap();\n map.set(this.#predicate.untaggedCbor(), this.#object.untaggedCbor());\n return map as unknown as Cbor;\n }\n\n /// Attempts to create an assertion from a CBOR value.\n ///\n /// The CBOR must be a map with exactly one entry, where the key represents\n /// the predicate and the value represents the object.\n ///\n /// @param cbor - The CBOR value to convert\n /// @returns A new Assertion instance\n /// @throws {EnvelopeError} If the CBOR is not a valid assertion\n static fromCbor(cbor: Cbor): Assertion {\n // Check if cbor is a Map\n if (!(cbor instanceof CborMap)) {\n throw EnvelopeError.invalidAssertion();\n }\n\n return Assertion.fromCborMap(cbor);\n }\n\n /// Attempts to create an assertion from a CBOR map.\n ///\n /// The map must have exactly one entry, where the key represents the\n /// predicate and the value represents the object. This is used in\n /// the deserialization process.\n ///\n /// @param map - The CBOR map to convert\n /// @returns A new Assertion instance\n /// @throws {EnvelopeError} If the map doesn't have exactly one entry\n static fromCborMap(map: CborMap): Assertion {\n if (map.size !== 1) {\n throw EnvelopeError.invalidAssertion();\n }\n\n const entries = Array.from(map.entries());\n const firstEntry = entries[0];\n if (firstEntry === undefined) {\n throw EnvelopeError.invalidAssertion();\n }\n const [predicateCbor, objectCbor] = firstEntry;\n\n const predicate = Envelope.fromUntaggedCbor(predicateCbor);\n\n const object = Envelope.fromUntaggedCbor(objectCbor);\n\n return new Assertion(predicate, object);\n }\n\n /// Creates a string representation of this assertion for debugging.\n ///\n /// @returns A string representation\n toString(): string {\n return `Assertion(${String(this.#predicate)}: ${String(this.#object)})`;\n }\n\n /// Creates a copy of this assertion.\n ///\n /// Since assertions are immutable and envelopes are cheap to clone,\n /// this returns the same instance.\n ///\n /// @returns This assertion instance\n clone(): Assertion {\n return this;\n }\n}\n","import { Envelope } from \"../base/envelope\";\nimport { EnvelopeError } from \"../base/error\";\nimport { type Digest } from \"../base/digest\";\nimport * as pako from \"pako\";\nimport { cborData, decodeCbor } from \"@bcts/dcbor\";\n\n/// Extension for compressing and decompressing envelopes.\n///\n/// This module provides functionality for compressing envelopes to reduce their\n/// size while maintaining their digests. Unlike elision, which removes content,\n/// compression preserves all the information in the envelope but represents it\n/// more efficiently.\n///\n/// Compression is implemented using the DEFLATE algorithm (via pako) and preserves\n/// the envelope's digest, making it compatible with the envelope's hierarchical\n/// digest tree structure.\n///\n/// @example\n/// ```typescript\n/// // Create an envelope with some larger, compressible content\n/// const lorem = \"Lorem ipsum dolor sit amet...\".repeat(10);\n/// const envelope = Envelope.new(lorem);\n///\n/// // Compress the envelope\n/// const compressed = envelope.compress();\n///\n/// // The compressed envelope has the same digest as the original\n/// console.log(envelope.digest().equals(compressed.digest())); // true\n///\n/// // But it takes up less space when serialized\n/// console.log(compressed.cborBytes().length < envelope.cborBytes().length); // true\n///\n/// // The envelope can be decompressed to recover the original content\n/// const decompressed = compressed.decompress();\n/// console.log(decompressed.asText() === lorem); // true\n/// ```\n\n/// Represents compressed data with optional digest\nexport class Compressed {\n readonly #compressedData: Uint8Array;\n readonly #digest?: Digest;\n\n constructor(compressedData: Uint8Array, digest?: Digest) {\n this.#compressedData = compressedData;\n if (digest !== undefined) {\n this.#digest = digest;\n }\n }\n\n /// Creates a Compressed instance from decompressed data\n static fromDecompressedData(decompressedData: Uint8Array, digest?: Digest): Compressed {\n const compressed = pako.deflate(decompressedData);\n return new Compressed(compressed, digest);\n }\n\n /// Returns the compressed data\n compressedData(): Uint8Array {\n return this.#compressedData;\n }\n\n /// Returns the optional digest\n digestOpt(): Digest | undefined {\n return this.#digest;\n }\n\n /// Decompresses the data\n decompress(): Uint8Array {\n return pako.inflate(this.#compressedData);\n }\n}\n\ndeclare module \"../base/envelope\" {\n interface Envelope {\n /// Returns a compressed version of this envelope.\n ///\n /// This method compresses the envelope using the DEFLATE algorithm,\n /// creating a more space-efficient representation while preserving the\n /// envelope's digest and semantic content. The compressed envelope\n /// maintains the same digest as the original, ensuring compatibility\n /// with the envelope's digest tree structure.\n ///\n /// When an envelope is compressed, the entire envelope structure (including\n /// its subject and assertions) is compressed as a single unit. The\n /// compression preserves all the information but reduces the size of\n /// the serialized envelope.\n ///\n /// @returns The compressed envelope\n /// @throws {EnvelopeError} If the envelope is already encrypted or elided\n ///\n /// @example\n /// ```typescript\n /// // Create an envelope with some content\n /// const text = \"This is a fairly long text that will benefit from compression.\";\n /// const envelope = Envelope.new(text);\n ///\n /// // Compress the envelope\n /// const compressed = envelope.compress();\n ///\n /// // Check that the compressed version has the same digest\n /// console.log(envelope.digest().equals(compressed.digest())); // true\n ///\n /// // Verify that the compressed version takes less space\n /// console.log(compressed.cborBytes().length < envelope.cborBytes().length);\n /// ```\n compress(): Envelope;\n\n /// Returns the decompressed variant of this envelope.\n ///\n /// This method reverses the compression process, restoring the envelope to\n /// its original decompressed form. The decompressed envelope will have\n /// the same digest as the compressed version.\n ///\n /// @returns The decompressed envelope\n /// @throws {EnvelopeError} If the envelope is not compressed, missing digest, or has invalid digest\n ///\n /// @example\n /// ```typescript\n /// // Create and compress an envelope\n /// const original = Envelope.new(\"Hello, world!\");\n /// const compressed = original.compress();\n ///\n /// // Decompress it\n /// const decompressed = compressed.decompress();\n ///\n /// // The decompressed envelope should match the original\n /// console.log(decompressed.asText() === \"Hello, world!\"); // true\n /// console.log(decompressed.digest().equals(original.digest())); // true\n /// ```\n decompress(): Envelope;\n\n /// Returns this envelope with its subject compressed.\n ///\n /// Unlike `compress()` which compresses the entire envelope, this method\n /// only compresses the subject of the envelope, leaving the assertions\n /// decompressed. This is useful when you want to compress a large\n /// subject while keeping the assertions readable and accessible.\n ///\n /// @returns A new envelope with a compressed subject\n ///\n /// @example\n /// ```typescript\n /// // Create an envelope with a large subject and some assertions\n /// const lorem = \"Lorem ipsum dolor sit amet...\";\n /// const envelope = Envelope.new(lorem)\n /// .addAssertion(\"note\", \"This is a metadata note\");\n ///\n /// // Compress just the subject\n /// const subjectCompressed = envelope.compressSubject();\n ///\n /// // The envelope's digest is preserved\n /// console.log(envelope.digest().equals(subjectCompressed.digest())); // true\n ///\n /// // The subject is now compressed\n /// console.log(subjectCompressed.subject().isCompressed()); // true\n /// ```\n compressSubject(): Envelope;\n\n /// Returns this envelope with its subject decompressed.\n ///\n /// This method reverses the effect of `compressSubject()`, decompressing\n /// the subject of the envelope while leaving the rest of the envelope\n /// unchanged.\n ///\n /// @returns A new envelope with a decompressed subject\n ///\n /// @example\n /// ```typescript\n /// // Create an envelope and compress its subject\n /// const original = Envelope.new(\"Hello, world!\")\n /// .addAssertion(\"note\", \"Test note\");\n /// const compressed = original.compressSubject();\n ///\n /// // Verify the subject is compressed\n /// console.log(compressed.subject().isCompressed()); // true\n ///\n /// // Decompress the subject\n /// const decompressed = compressed.decompressSubject();\n ///\n /// // Verify the subject is now decompressed\n /// console.log(!decompressed.subject().isCompressed()); // true\n /// ```\n decompressSubject(): Envelope;\n\n /// Checks if this envelope is compressed\n isCompressed(): boolean;\n }\n}\n\n/// Register compression extension methods on Envelope prototype\n/// This function is exported and called during module initialization\n/// to ensure Envelope is fully defined before attaching methods.\nexport function registerCompressExtension(): void {\n if (Envelope?.prototype === undefined) {\n return;\n }\n\n // Skip if already registered\n if (typeof Envelope.prototype.compress === \"function\") {\n return;\n }\n\n Envelope.prototype.compress = function (this: Envelope): Envelope {\n const c = this.case();\n\n // If already compressed, return as-is\n if (c.type === \"compressed\") {\n return this;\n }\n\n // Can't compress encrypted or elided envelopes\n if (c.type === \"encrypted\") {\n throw EnvelopeError.general(\"Cannot compress encrypted envelope\");\n }\n if (c.type === \"elided\") {\n throw EnvelopeError.general(\"Cannot compress elided envelope\");\n }\n\n // Compress the entire envelope\n const cbor = this.taggedCbor();\n\n const decompressedData = cborData(cbor);\n\n const compressed = Compressed.fromDecompressedData(decompressedData, this.digest());\n\n // Create a compressed envelope case\n return Envelope.fromCase({ type: \"compressed\", value: compressed });\n };\n\n /// Implementation of decompress()\n Envelope.prototype.decompress = function (this: Envelope): Envelope {\n const c = this.case();\n\n if (c.type !== \"compressed\") {\n throw EnvelopeError.general(\"Envelope is not compressed\");\n }\n\n const compressed = c.value;\n const digest = compressed.digestOpt();\n\n if (digest === undefined) {\n throw EnvelopeError.general(\"Missing digest in compressed envelope\");\n }\n\n // Verify the digest matches\n if (!digest.equals(this.digest())) {\n throw EnvelopeError.general(\"Invalid digest in compressed envelope\");\n }\n\n // Decompress the data\n const decompressedData = compressed.decompress();\n\n // Parse back to envelope\n\n const cbor = decodeCbor(decompressedData);\n const envelope = Envelope.fromTaggedCbor(cbor);\n\n // Verify the decompressed envelope has the correct digest\n if (!envelope.digest().equals(digest)) {\n throw EnvelopeError.general(\"Invalid digest after decompression\");\n }\n\n return envelope;\n };\n\n /// Implementation of compressSubject()\n Envelope.prototype.compressSubject = function (this: Envelope): Envelope {\n if (this.subject().isCompressed()) {\n return this;\n }\n\n const subject = this.subject().compress();\n return this.replaceSubject(subject);\n };\n\n /// Implementation of decompressSubject()\n Envelope.prototype.decompressSubject = function (this: Envelope): Envelope {\n if (this.subject().isCompressed()) {\n const subject = this.subject().decompress();\n return this.replaceSubject(subject);\n }\n\n return this;\n };\n\n /// Implementation of isCompressed()\n Envelope.prototype.isCompressed = function (this: Envelope): boolean {\n return this.case().type === \"compressed\";\n };\n}\n\n// Auto-register on module load - will be called again from index.ts\n// to ensure proper ordering after all modules are loaded\nregisterCompressExtension();\n","import { Envelope } from \"../base/envelope\";\nimport { EnvelopeError } from \"../base/error\";\nimport { type Digest } from \"../base/digest\";\nimport { cborData, decodeCbor } from \"@bcts/dcbor\";\nimport {\n aeadChaCha20Poly1305EncryptWithAad,\n aeadChaCha20Poly1305DecryptWithAad,\n SYMMETRIC_KEY_SIZE,\n SYMMETRIC_NONCE_SIZE,\n} from \"@bcts/crypto\";\nimport { SecureRandomNumberGenerator, rngRandomData, type RandomNumberGenerator } from \"@bcts/rand\";\n\n/// Extension for encrypting and decrypting envelopes using symmetric encryption.\n///\n/// This module extends Gordian Envelope with functions for symmetric encryption\n/// and decryption using the IETF-ChaCha20-Poly1305 construct. It enables\n/// privacy-enhancing operations by allowing envelope elements to be encrypted\n/// without changing the envelope's digest, similar to elision.\n///\n/// The encryption process preserves the envelope's digest tree structure, which\n/// means signatures, proofs, and other cryptographic artifacts remain valid\n/// even when parts of the envelope are encrypted.\n///\n/// @example\n/// ```typescript\n/// // Create an envelope\n/// const envelope = Envelope.new(\"Hello world\");\n///\n/// // Generate a symmetric key for encryption\n/// const key = SymmetricKey.generate();\n///\n/// // Encrypt the envelope's subject\n/// const encrypted = envelope.encryptSubject(key);\n///\n/// // The encrypted envelope has the same digest as the original\n/// console.log(envelope.digest().equals(encrypted.digest())); // true\n///\n/// // The subject is now encrypted\n/// console.log(encrypted.subject().isEncrypted()); // true\n///\n/// // Decrypt the envelope\n/// const decrypted = encrypted.decryptSubject(key);\n///\n/// // The decrypted envelope is equivalent to the original\n/// console.log(envelope.digest().equals(decrypted.digest())); // true\n/// ```\n\n/// Helper function to create a secure RNG\nfunction createSecureRng(): RandomNumberGenerator {\n return new SecureRandomNumberGenerator();\n}\n\n/// Represents a symmetric encryption key (256-bit)\n/// Matches bc-components-rust/src/symmetric/symmetric_key.rs\nexport class SymmetricKey {\n readonly #key: Uint8Array;\n\n constructor(key: Uint8Array) {\n if (key.length !== SYMMETRIC_KEY_SIZE) {\n throw new Error(`Symmetric key must be ${SYMMETRIC_KEY_SIZE} bytes`);\n }\n this.#key = key;\n }\n\n /// Generates a new random symmetric key\n static generate(): SymmetricKey {\n const rng = createSecureRng();\n const key = rngRandomData(rng, SYMMETRIC_KEY_SIZE);\n return new SymmetricKey(key);\n }\n\n /// Creates a symmetric key from existing bytes\n static from(key: Uint8Array): SymmetricKey {\n return new SymmetricKey(key);\n }\n\n /// Returns the raw key bytes\n data(): Uint8Array {\n return this.#key;\n }\n\n /// Encrypts data with associated digest (AAD)\n /// Uses IETF ChaCha20-Poly1305 with 12-byte nonce\n encrypt(plaintext: Uint8Array, digest: Digest): EncryptedMessage {\n const rng = createSecureRng();\n\n // Generate a random nonce (12 bytes for IETF ChaCha20-Poly1305)\n const nonce = rngRandomData(rng, SYMMETRIC_NONCE_SIZE);\n\n // Use digest as additional authenticated data (AAD)\n const aad = digest.data();\n\n // Encrypt using IETF ChaCha20-Poly1305\n const [ciphertext, authTag] = aeadChaCha20Poly1305EncryptWithAad(\n plaintext,\n this.#key,\n nonce,\n aad,\n );\n\n return new EncryptedMessage(ciphertext, nonce, authTag, digest);\n }\n\n /// Decrypts an encrypted message\n decrypt(message: EncryptedMessage): Uint8Array {\n const digest = message.aadDigest();\n if (digest === undefined) {\n throw EnvelopeError.general(\"Missing digest in encrypted message\");\n }\n\n const aad = digest.data();\n\n try {\n const plaintext = aeadChaCha20Poly1305DecryptWithAad(\n message.ciphertext(),\n this.#key,\n message.nonce(),\n aad,\n message.authTag(),\n );\n\n return plaintext;\n } catch (_error) {\n throw EnvelopeError.general(\"Decryption failed: invalid key or corrupted data\");\n }\n }\n}\n\n/// Represents an encrypted message with nonce, auth tag, and optional AAD digest\n/// Matches bc-components-rust/src/symmetric/encrypted_message.rs\nexport class EncryptedMessage {\n readonly #ciphertext: Uint8Array;\n readonly #nonce: Uint8Array;\n readonly #authTag: Uint8Array;\n readonly #aadDigest?: Digest;\n\n constructor(ciphertext: Uint8Array, nonce: Uint8Array, authTag: Uint8Array, aadDigest?: Digest) {\n this.#ciphertext = ciphertext;\n this.#nonce = nonce;\n this.#authTag = authTag;\n if (aadDigest !== undefined) {\n this.#aadDigest = aadDigest;\n }\n }\n\n /// Returns the ciphertext\n ciphertext(): Uint8Array {\n return this.#ciphertext;\n }\n\n /// Returns the nonce\n nonce(): Uint8Array {\n return this.#nonce;\n }\n\n /// Returns the authentication tag\n authTag(): Uint8Array {\n return this.#authTag;\n }\n\n /// Returns the optional AAD digest\n aadDigest(): Digest | undefined {\n return this.#aadDigest;\n }\n\n /// Returns the digest of this encrypted message (the AAD digest)\n digest(): Digest {\n if (this.#aadDigest === undefined) {\n throw new Error(\"Encrypted message missing AAD digest\");\n }\n return this.#aadDigest;\n }\n}\n\ndeclare module \"../base/envelope\" {\n interface Envelope {\n /// Returns a new envelope with its subject encrypted.\n ///\n /// Encrypts only the subject of the envelope, leaving assertions\n /// unencrypted. To encrypt an entire envelope including its assertions,\n /// it must first be wrapped using the `wrap()` method, or you\n /// can use the `encrypt()` convenience method.\n ///\n /// The encryption uses IETF ChaCha20-Poly1305 and preserves the envelope's\n /// digest, allowing for features like selective disclosure and\n /// signature verification to work even on encrypted envelopes.\n ///\n /// @param key - The SymmetricKey to use for encryption\n /// @returns A new envelope with its subject encrypted\n /// @throws {EnvelopeError} If the envelope is already encrypted or elided\n ///\n /// @example\n /// ```typescript\n /// const envelope = Envelope.new(\"Secret data\");\n /// const key = SymmetricKey.generate();\n /// const encrypted = envelope.encryptSubject(key);\n /// console.log(encrypted.subject().isEncrypted()); // true\n /// ```\n encryptSubject(key: SymmetricKey): Envelope;\n\n /// Returns a new envelope with its subject decrypted.\n ///\n /// Decrypts the subject of an envelope that was previously encrypted using\n /// `encryptSubject()`. The symmetric key used must be the same one\n /// used for encryption.\n ///\n /// @param key - The SymmetricKey to use for decryption\n /// @returns A new envelope with its subject decrypted\n /// @throws {EnvelopeError} If the envelope's subject is not encrypted, key is incorrect, or digest mismatch\n ///\n /// @example\n /// ```typescript\n /// const decrypted = encrypted.decryptSubject(key);\n /// console.log(decrypted.asText()); // \"Secret data\"\n /// ```\n decryptSubject(key: SymmetricKey): Envelope;\n\n /// Convenience method to encrypt an entire envelope including its assertions.\n ///\n /// This method wraps the envelope and then encrypts its subject, which has\n /// the effect of encrypting the entire original envelope including all\n /// its assertions.\n ///\n /// @param key - The SymmetricKey to use for encryption\n /// @returns A new envelope with the entire original envelope encrypted\n ///\n /// @example\n /// ```typescript\n /// const envelope = Envelope.new(\"Alice\").addAssertion(\"knows\", \"Bob\");\n /// const key = SymmetricKey.generate();\n /// const encrypted = envelope.encrypt(key);\n /// ```\n encrypt(key: SymmetricKey): Envelope;\n\n /// Convenience method to decrypt an entire envelope that was encrypted\n /// using the `encrypt()` method.\n ///\n /// This method decrypts the subject and then unwraps the resulting\n /// envelope, returning the original envelope with all its assertions.\n ///\n /// @param key - The SymmetricKey to use for decryption\n /// @returns The original decrypted envelope\n /// @throws {EnvelopeError} If envelope is not encrypted, key is incorrect, digest mismatch, or cannot unwrap\n ///\n /// @example\n /// ```typescript\n /// const decrypted = encrypted.decrypt(key);\n /// console.log(envelope.digest().equals(decrypted.digest())); // true\n /// ```\n decrypt(key: SymmetricKey): Envelope;\n\n /// Checks if this envelope is encrypted\n isEncrypted(): boolean;\n }\n}\n\n/// Register encryption extension methods on Envelope prototype\n/// This function is exported and called during module initialization\n/// to ensure Envelope is fully defined before attaching methods.\nexport function registerEncryptExtension(): void {\n if (Envelope?.prototype === undefined) {\n return;\n }\n\n // Skip if already registered\n if (typeof Envelope.prototype.encryptSubject === \"function\") {\n return;\n }\n\n Envelope.prototype.encryptSubject = function (this: Envelope, key: SymmetricKey): Envelope {\n const c = this.case();\n\n // Can't encrypt if already encrypted or elided\n if (c.type === \"encrypted\") {\n throw EnvelopeError.general(\"Envelope is already encrypted\");\n }\n if (c.type === \"elided\") {\n throw EnvelopeError.general(\"Cannot encrypt elided envelope\");\n }\n\n // For node case, encrypt just the subject\n if (c.type === \"node\") {\n if (c.subject.isEncrypted()) {\n throw EnvelopeError.general(\"Subject is already encrypted\");\n }\n\n // Get the subject's CBOR data\n const subjectCbor = c.subject.taggedCbor();\n const encodedCbor = cborData(subjectCbor);\n const subjectDigest = c.subject.digest();\n\n // Encrypt the subject\n const encryptedMessage = key.encrypt(encodedCbor, subjectDigest);\n\n // Create encrypted envelope\n const encryptedSubject = Envelope.fromCase({\n type: \"encrypted\",\n message: encryptedMessage,\n });\n\n // Rebuild the node with encrypted subject and same assertions\n return Envelope.newWithAssertions(encryptedSubject, c.assertions);\n }\n\n // For other cases, encrypt the entire envelope\n const cbor = this.taggedCbor();\n const encodedCbor = cborData(cbor);\n const digest = this.digest();\n\n const encryptedMessage = key.encrypt(encodedCbor, digest);\n\n return Envelope.fromCase({\n type: \"encrypted\",\n message: encryptedMessage,\n });\n };\n\n /// Implementation of decryptSubject()\n Envelope.prototype.decryptSubject = function (this: Envelope, key: SymmetricKey): Envelope {\n const subjectCase = this.subject().case();\n\n if (subjectCase.type !== \"encrypted\") {\n throw EnvelopeError.general(\"Subject is not encrypted\");\n }\n\n const message = subjectCase.message;\n const subjectDigest = message.aadDigest();\n\n if (subjectDigest === undefined) {\n throw EnvelopeError.general(\"Missing digest in encrypted message\");\n }\n\n // Decrypt the subject\n const decryptedData = key.decrypt(message);\n\n // Parse back to envelope\n const cbor = decodeCbor(decryptedData);\n const resultSubject = Envelope.fromTaggedCbor(cbor);\n\n // Verify digest\n if (!resultSubject.digest().equals(subjectDigest)) {\n throw EnvelopeError.general(\"Invalid digest after decryption\");\n }\n\n const c = this.case();\n\n // If this is a node, rebuild with decrypted subject\n if (c.type === \"node\") {\n const result = Envelope.newWithAssertions(resultSubject, c.assertions);\n if (!result.digest().equals(c.digest)) {\n throw EnvelopeError.general(\"Invalid envelope digest after decryption\");\n }\n return result;\n }\n\n // Otherwise just return the decrypted subject\n return resultSubject;\n };\n\n /// Implementation of encrypt() - convenience method\n Envelope.prototype.encrypt = function (this: Envelope, key: SymmetricKey): Envelope {\n return this.wrap().encryptSubject(key);\n };\n\n /// Implementation of decrypt() - convenience method\n Envelope.prototype.decrypt = function (this: Envelope, key: SymmetricKey): Envelope {\n const decrypted = this.decryptSubject(key);\n return decrypted.unwrap();\n };\n\n /// Implementation of isEncrypted()\n Envelope.prototype.isEncrypted = function (this: Envelope): boolean {\n return this.case().type === \"encrypted\";\n };\n}\n\n// Auto-register on module load - will be called again from index.ts\n// to ensure proper ordering after all modules are loaded\nregisterEncryptExtension();\n","import { Digest, type DigestProvider } from \"./digest\";\nimport { Assertion } from \"./assertion\";\nimport { EnvelopeError } from \"./error\";\nimport type { EnvelopeEncodableValue } from \"./envelope-encodable\";\nimport { KnownValue } from \"@bcts/known-values\";\nimport type { Cbor } from \"@bcts/dcbor\";\nimport {\n cbor,\n cborData,\n toTaggedValue,\n TAG_ENCODED_CBOR,\n MajorType,\n asByteString,\n asCborArray,\n asCborMap,\n asTaggedValue,\n tryExpectedTaggedValue,\n} from \"@bcts/dcbor\";\nimport { ENVELOPE, LEAF, ENCRYPTED, COMPRESSED } from \"@bcts/components\";\n\n/// Import tag values from the tags registry\n/// These match the Rust reference implementation in bc-tags-rust\nconst TAG_ENVELOPE = ENVELOPE.value;\nconst TAG_LEAF = LEAF.value;\nconst TAG_ENCRYPTED = ENCRYPTED.value;\nconst TAG_COMPRESSED = COMPRESSED.value;\n\n/// The core structural variants of a Gordian Envelope.\n///\n/// Each variant represents a different structural form that an\n/// envelope can take, as defined in the Gordian Envelope IETF Internet Draft.\n/// The different cases provide different capabilities and serve different\n/// purposes in the envelope ecosystem.\n///\n/// The `EnvelopeCase` is the internal representation of an envelope's\n/// structure. While each case has unique properties, they all maintain a digest\n/// that ensures the integrity of the envelope.\n///\n/// It is advised to use the other Envelope APIs for most uses. Please see the\n/// queries module for more information on how to interact with envelopes.\nexport type EnvelopeCase =\n | {\n type: \"node\";\n /// The subject of the node\n subject: Envelope;\n /// The assertions attached to the subject\n assertions: Envelope[];\n /// The digest of the node\n digest: Digest;\n }\n | {\n type: \"leaf\";\n /// The CBOR value contained in the leaf\n cbor: Cbor;\n /// The digest of the leaf\n digest: Digest;\n }\n | {\n type: \"wrapped\";\n /// The envelope being wrapped\n envelope: Envelope;\n /// The digest of the wrapped envelope\n digest: Digest;\n }\n | {\n type: \"assertion\";\n /// The assertion\n assertion: Assertion;\n }\n | {\n type: \"elided\";\n /// The digest of the elided content\n digest: Digest;\n }\n | {\n type: \"knownValue\";\n /// The known value instance\n value: KnownValue;\n /// The digest of the known value\n digest: Digest;\n }\n | {\n type: \"encrypted\";\n /// The encrypted message\n message: EncryptedMessage;\n }\n | {\n type: \"compressed\";\n /// The compressed data\n value: Compressed;\n };\n\n// Import types from extension modules (will be available at runtime)\nimport { Compressed } from \"../extension/compress\";\nimport { EncryptedMessage } from \"../extension/encrypt\";\n\n/// A flexible container for structured data with built-in integrity\n/// verification.\n///\n/// Gordian Envelope is the primary data structure of this library. It provides a\n/// way to encapsulate and organize data with cryptographic integrity, privacy\n/// features, and selective disclosure capabilities.\n///\n/// Key characteristics of envelopes:\n///\n/// - **Immutability**: Envelopes are immutable. Operations that appear to\n/// \"modify\" an envelope actually create a new envelope. This immutability is\n/// fundamental to maintaining the integrity of the envelope's digest tree.\n///\n/// - **Efficient Cloning**: Envelopes use shallow copying for efficient O(1)\n/// cloning. Since they're immutable, clones share the same underlying data.\n///\n/// - **Semantic Structure**: Envelopes can represent various semantic\n/// relationships through subjects, predicates, and objects (similar to RDF\n/// triples).\n///\n/// - **Digest Tree**: Each envelope maintains a Merkle-like digest tree that\n/// ensures the integrity of its contents and enables verification of\n/// individual parts.\n///\n/// - **Privacy Features**: Envelopes support selective disclosure through\n/// elision, encryption, and compression of specific parts, while maintaining\n/// the overall integrity of the structure.\n///\n/// - **Deterministic Representation**: Envelopes use deterministic CBOR\n/// encoding to ensure consistent serialization across platforms.\n///\n/// The Gordian Envelope specification is defined in an IETF Internet Draft, and\n/// this implementation closely follows that specification.\n///\n/// @example\n/// ```typescript\n/// // Create an envelope representing a person\n/// const person = Envelope.new(\"person\")\n/// .addAssertion(\"name\", \"Alice\")\n/// .addAssertion(\"age\", 30)\n/// .addAssertion(\"email\", \"alice@example.com\");\n///\n/// // Create a partially redacted version by eliding the email\n/// const redacted = person.elideRemovingTarget(\n/// person.assertionWithPredicate(\"email\")\n/// );\n///\n/// // The digest of both envelopes remains the same\n/// assert(person.digest().equals(redacted.digest()));\n/// ```\nexport class Envelope implements DigestProvider {\n readonly #case: EnvelopeCase;\n\n /// Private constructor. Use static factory methods to create envelopes.\n ///\n /// @param envelopeCase - The envelope case variant\n private constructor(envelopeCase: EnvelopeCase) {\n this.#case = envelopeCase;\n }\n\n /// Returns a reference to the underlying envelope case.\n ///\n /// The `EnvelopeCase` enum represents the specific structural variant of\n /// this envelope. This method provides access to that underlying\n /// variant for operations that need to differentiate between the\n /// different envelope types.\n ///\n /// @returns The `EnvelopeCase` that defines this envelope's structure.\n case(): EnvelopeCase {\n return this.#case;\n }\n\n /// Creates an envelope with a subject, which can be any value that\n /// can be encoded as an envelope.\n ///\n /// @param subject - The subject value\n /// @returns A new envelope containing the subject\n ///\n /// @example\n /// ```typescript\n /// const envelope = Envelope.new(\"Hello, world!\");\n /// const numberEnvelope = Envelope.new(42);\n /// const binaryEnvelope = Envelope.new(new Uint8Array([1, 2, 3]));\n /// ```\n static new(subject: EnvelopeEncodableValue): Envelope {\n // Convert the subject to an envelope\n if (subject instanceof Envelope) {\n return subject;\n }\n\n // Handle primitives and create leaf envelopes\n return Envelope.newLeaf(subject);\n }\n\n /// Creates an envelope with a subject, or null if subject is undefined.\n ///\n /// @param subject - The optional subject value\n /// @returns A new envelope or null envelope\n static newOrNull(subject: EnvelopeEncodableValue | undefined): Envelope {\n if (subject === undefined || subject === null) {\n return Envelope.null();\n }\n return Envelope.new(subject);\n }\n\n /// Creates an envelope with a subject, or undefined if subject is undefined.\n ///\n /// @param subject - The optional subject value\n /// @returns A new envelope or undefined\n static newOrNone(subject: EnvelopeEncodableValue | undefined): Envelope | undefined {\n if (subject === undefined || subject === null) {\n return undefined;\n }\n return Envelope.new(subject);\n }\n\n /// Creates an envelope from an EnvelopeCase.\n ///\n /// This is an internal method used by extensions to create envelopes\n /// from custom case types like compressed or encrypted.\n ///\n /// @param envelopeCase - The envelope case to wrap\n /// @returns A new envelope with the given case\n static fromCase(envelopeCase: EnvelopeCase): Envelope {\n return new Envelope(envelopeCase);\n }\n\n /// Creates an assertion envelope with a predicate and object.\n ///\n /// @param predicate - The predicate of the assertion\n /// @param object - The object of the assertion\n /// @returns A new assertion envelope\n ///\n /// @example\n /// ```typescript\n /// const assertion = Envelope.newAssertion(\"name\", \"Alice\");\n /// ```\n static newAssertion(predicate: EnvelopeEncodableValue, object: EnvelopeEncodableValue): Envelope {\n const predicateEnv = predicate instanceof Envelope ? predicate : Envelope.new(predicate);\n const objectEnv = object instanceof Envelope ? object : Envelope.new(object);\n return Envelope.newWithAssertion(new Assertion(predicateEnv, objectEnv));\n }\n\n /// Creates a null envelope (containing CBOR null).\n ///\n /// @returns A null envelope\n static null(): Envelope {\n return Envelope.newLeaf(null);\n }\n\n //\n // Internal constructors\n //\n\n /// Creates an envelope with a subject and unchecked assertions.\n ///\n /// The assertions are sorted by digest and the envelope's digest is calculated.\n ///\n /// @param subject - The subject envelope\n /// @param uncheckedAssertions - The assertions to attach\n /// @returns A new node envelope\n static newWithUncheckedAssertions(subject: Envelope, uncheckedAssertions: Envelope[]): Envelope {\n if (uncheckedAssertions.length === 0) {\n throw new Error(\"Assertions array cannot be empty\");\n }\n\n // Sort assertions by digest\n const sortedAssertions = [...uncheckedAssertions].sort((a, b) => {\n const aHex = a.digest().hex();\n const bHex = b.digest().hex();\n return aHex.localeCompare(bHex);\n });\n\n // Calculate digest from subject and all assertions\n const digests = [subject.digest(), ...sortedAssertions.map((a) => a.digest())];\n const digest = Digest.fromDigests(digests);\n\n return new Envelope({\n type: \"node\",\n subject,\n assertions: sortedAssertions,\n digest,\n });\n }\n\n /// Creates an envelope with a subject and validated assertions.\n ///\n /// All assertions must be assertion or obscured envelopes.\n ///\n /// @param subject - The subject envelope\n /// @param assertions - The assertions to attach\n /// @returns A new node envelope\n /// @throws {EnvelopeError} If any assertion is not valid\n static newWithAssertions(subject: Envelope, assertions: Envelope[]): Envelope {\n // Validate that all assertions are assertion or obscured envelopes\n for (const assertion of assertions) {\n if (!assertion.isSubjectAssertion() && !assertion.isSubjectObscured()) {\n throw EnvelopeError.invalidFormat();\n }\n }\n\n return Envelope.newWithUncheckedAssertions(subject, assertions);\n }\n\n /// Creates an envelope with an assertion as its subject.\n ///\n /// @param assertion - The assertion\n /// @returns A new assertion envelope\n static newWithAssertion(assertion: Assertion): Envelope {\n return new Envelope({\n type: \"assertion\",\n assertion,\n });\n }\n\n /// Creates an envelope with a known value.\n ///\n /// @param value - The known value (can be a KnownValue instance or a number/bigint)\n /// @returns A new known value envelope\n static newWithKnownValue(value: KnownValue | number | bigint): Envelope {\n const knownValue = value instanceof KnownValue ? value : new KnownValue(value);\n // Calculate digest from CBOR encoding of the known value\n const digest = Digest.fromImage(knownValue.toCborData());\n return new Envelope({\n type: \"knownValue\",\n value: knownValue,\n digest,\n });\n }\n\n /// Creates an envelope with encrypted content.\n ///\n /// @param encryptedMessage - The encrypted message\n /// @returns A new encrypted envelope\n /// @throws {EnvelopeError} If the encrypted message doesn't have a digest\n static newWithEncrypted(encryptedMessage: EncryptedMessage): Envelope {\n // TODO: Validate that encrypted message has digest\n // if (!encryptedMessage.hasDigest()) {\n // throw EnvelopeError.missingDigest();\n // }\n return new Envelope({\n type: \"encrypted\",\n message: encryptedMessage,\n });\n }\n\n /// Creates an envelope with compressed content.\n ///\n /// @param compressed - The compressed data\n /// @returns A new compressed envelope\n /// @throws {EnvelopeError} If the compressed data doesn't have a digest\n static newWithCompressed(compressed: Compressed): Envelope {\n // TODO: Validate that compressed has digest\n // if (!compressed.hasDigest()) {\n // throw EnvelopeError.missingDigest();\n // }\n return new Envelope({\n type: \"compressed\",\n value: compressed,\n });\n }\n\n /// Creates an elided envelope containing only a digest.\n ///\n /// @param digest - The digest of the elided content\n /// @returns A new elided envelope\n static newElided(digest: Digest): Envelope {\n return new Envelope({\n type: \"elided\",\n digest,\n });\n }\n\n /// Creates a leaf envelope containing a CBOR value.\n ///\n /// @param value - The value to encode as CBOR\n /// @returns A new leaf envelope\n static newLeaf(value: unknown): Envelope {\n // Convert value to CBOR\n const cbor = Envelope.valueToCbor(value);\n\n // Calculate digest from CBOR bytes\n const cborBytes = Envelope.cborToBytes(cbor);\n const digest = Digest.fromImage(cborBytes);\n\n return new Envelope({\n type: \"leaf\",\n cbor,\n digest,\n });\n }\n\n /// Creates a wrapped envelope.\n ///\n /// @param envelope - The envelope to wrap\n /// @returns A new wrapped envelope\n static newWrapped(envelope: Envelope): Envelope {\n const digest = Digest.fromDigests([envelope.digest()]);\n return new Envelope({\n type: \"wrapped\",\n envelope,\n digest,\n });\n }\n\n /// Returns the digest of this envelope.\n ///\n /// Implementation of DigestProvider interface.\n ///\n /// @returns The envelope's digest\n digest(): Digest {\n const c = this.#case;\n switch (c.type) {\n case \"node\":\n case \"leaf\":\n case \"wrapped\":\n case \"elided\":\n case \"knownValue\":\n return c.digest;\n case \"assertion\":\n return c.assertion.digest();\n case \"encrypted\": {\n // Get digest from encrypted message (AAD)\n const digest = c.message.aadDigest();\n if (digest === undefined) {\n throw new Error(\"Encrypted envelope missing digest\");\n }\n return digest;\n }\n case \"compressed\": {\n // Get digest from compressed value\n const digest = c.value.digestOpt();\n if (digest === undefined) {\n throw new Error(\"Compressed envelope missing digest\");\n }\n return digest;\n }\n }\n }\n\n /// Returns the subject of this envelope.\n ///\n /// For different envelope cases:\n /// - Node: Returns the subject envelope\n /// - Other cases: Returns the envelope itself\n ///\n /// @returns The subject envelope\n subject(): Envelope {\n const c = this.#case;\n switch (c.type) {\n case \"node\":\n return c.subject;\n case \"leaf\":\n case \"wrapped\":\n case \"assertion\":\n case \"elided\":\n case \"knownValue\":\n case \"encrypted\":\n case \"compressed\":\n return this;\n }\n }\n\n /// Checks if the envelope's subject is an assertion.\n ///\n /// @returns `true` if the subject is an assertion, `false` otherwise\n isSubjectAssertion(): boolean {\n return this.#case.type === \"assertion\";\n }\n\n /// Checks if the envelope's subject is obscured (elided, encrypted, or compressed).\n ///\n /// @returns `true` if the subject is obscured, `false` otherwise\n isSubjectObscured(): boolean {\n const t = this.#case.type;\n return t === \"elided\" || t === \"encrypted\" || t === \"compressed\";\n }\n\n //\n // CBOR conversion helpers\n //\n\n /// Converts a value to CBOR.\n ///\n /// @param value - The value to convert\n /// @returns A CBOR representation\n private static valueToCbor(value: unknown): Cbor {\n // Import cbor function at runtime to avoid circular dependencies\n\n return cbor(value as Parameters<typeof cbor>[0]);\n }\n\n /// Converts CBOR to bytes.\n ///\n /// @param cbor - The CBOR value\n /// @returns Byte representation\n private static cborToBytes(cbor: Cbor): Uint8Array {\n // Import cborData function at runtime to avoid circular dependencies\n\n return cborData(cbor);\n }\n\n /// Returns the untagged CBOR representation of this envelope.\n ///\n /// @returns The untagged CBOR\n untaggedCbor(): Cbor {\n const c = this.#case;\n switch (c.type) {\n case \"node\": {\n // Array with subject followed by assertions\n const result = [c.subject.untaggedCbor()];\n for (const assertion of c.assertions) {\n result.push(assertion.untaggedCbor());\n }\n return Envelope.valueToCbor(result);\n }\n case \"leaf\":\n // Tagged with TAG_LEAF (204)\n return toTaggedValue(TAG_LEAF, c.cbor);\n case \"wrapped\":\n // Wrapped envelopes are tagged with TAG_ENVELOPE\n return c.envelope.taggedCbor();\n case \"assertion\":\n // Assertions convert to CBOR maps\n return c.assertion.toCbor();\n case \"elided\":\n // Elided is just the digest bytes\n return Envelope.valueToCbor(c.digest.data());\n case \"knownValue\":\n // TODO: Implement known value encoding\n throw new Error(\"Known value encoding not yet implemented\");\n case \"encrypted\": {\n // Encrypted is tagged with TAG_ENCRYPTED (40002)\n // Contains: [ciphertext, nonce, auth, optional_aad_digest]\n // Per BCR-2023-004 and BCR-2022-001\n const message = c.message;\n const digest = message.aadDigest();\n const arr =\n digest !== undefined\n ? [message.ciphertext(), message.nonce(), message.authTag(), digest.data()]\n : [message.ciphertext(), message.nonce(), message.authTag()];\n return toTaggedValue(TAG_ENCRYPTED, Envelope.valueToCbor(arr));\n }\n case \"compressed\": {\n // Compressed is tagged with TAG_COMPRESSED (40003)\n // and contains an array: [compressed_data, optional_digest]\n const digest = c.value.digestOpt();\n const data = c.value.compressedData();\n const arr = digest !== undefined ? [data, digest.data()] : [data];\n return toTaggedValue(TAG_COMPRESSED, Envelope.valueToCbor(arr));\n }\n }\n }\n\n /// Returns the tagged CBOR representation of this envelope.\n ///\n /// All envelopes are tagged with TAG_ENVELOPE (200).\n ///\n /// @returns The tagged CBOR\n taggedCbor(): Cbor {\n return toTaggedValue(TAG_ENVELOPE, this.untaggedCbor());\n }\n\n /// Creates an envelope from untagged CBOR.\n ///\n /// @param cbor - The untagged CBOR value\n /// @returns A new envelope\n static fromUntaggedCbor(cbor: Cbor): Envelope {\n // Check if it's a tagged value\n const tagged = asTaggedValue(cbor);\n if (tagged !== undefined) {\n const [tag, item] = tagged;\n switch (tag.value) {\n case TAG_LEAF:\n case TAG_ENCODED_CBOR:\n // Leaf envelope\n return Envelope.newLeaf(item);\n case TAG_ENVELOPE: {\n // Wrapped envelope\n const envelope = Envelope.fromUntaggedCbor(item);\n return Envelope.newWrapped(envelope);\n }\n case TAG_COMPRESSED: {\n // Compressed envelope: array with [compressed_data, optional_digest]\n const arr = asCborArray(item);\n if (arr === undefined || arr.length < 1 || arr.length > 2) {\n throw EnvelopeError.cbor(\"compressed envelope must have 1 or 2 elements\");\n }\n // We've already checked arr.length >= 1 above\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const compressedData = asByteString(arr.get(0)!);\n if (compressedData === undefined) {\n throw EnvelopeError.cbor(\"compressed data must be byte string\");\n }\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const digestBytes = arr.length === 2 ? asByteString(arr.get(1)!) : undefined;\n if (arr.length === 2 && digestBytes === undefined) {\n throw EnvelopeError.cbor(\"digest must be byte string\");\n }\n const digest = digestBytes !== undefined ? new Digest(digestBytes) : undefined;\n\n // Import Compressed class at runtime to avoid circular dependency\n\n const compressed = new Compressed(compressedData, digest);\n return Envelope.fromCase({ type: \"compressed\", value: compressed });\n }\n case TAG_ENCRYPTED: {\n // Encrypted envelope: array with [ciphertext, nonce, auth, optional_aad_digest]\n // Per BCR-2023-004 and BCR-2022-001\n const arr = asCborArray(item);\n if (arr === undefined || arr.length < 3 || arr.length > 4) {\n throw EnvelopeError.cbor(\"encrypted envelope must have 3 or 4 elements\");\n }\n // We've already checked arr.length >= 3 above\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const ciphertext = asByteString(arr.get(0)!);\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const nonce = asByteString(arr.get(1)!);\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const authTag = asByteString(arr.get(2)!);\n if (ciphertext === undefined || nonce === undefined || authTag === undefined) {\n throw EnvelopeError.cbor(\"ciphertext, nonce, and auth must be byte strings\");\n }\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const digestBytes = arr.length === 4 ? asByteString(arr.get(3)!) : undefined;\n if (arr.length === 4 && digestBytes === undefined) {\n throw EnvelopeError.cbor(\"aad digest must be byte string\");\n }\n const digest = digestBytes !== undefined ? new Digest(digestBytes) : undefined;\n\n const message = new EncryptedMessage(ciphertext, nonce, authTag, digest);\n return Envelope.fromCase({ type: \"encrypted\", message });\n }\n default:\n throw EnvelopeError.cbor(`unknown envelope tag: ${tag.value}`);\n }\n }\n\n // Check if it's a byte string (elided)\n const bytes = asByteString(cbor);\n if (bytes !== undefined) {\n if (bytes.length !== 32) {\n throw EnvelopeError.cbor(\"elided digest must be 32 bytes\");\n }\n return Envelope.newElided(new Digest(bytes));\n }\n\n // Check if it's an array (node)\n const array = asCborArray(cbor);\n if (array !== undefined) {\n if (array.length < 2) {\n throw EnvelopeError.cbor(\"node must have at least two elements\");\n }\n const subjectCbor = array.get(0);\n if (subjectCbor === undefined) {\n throw EnvelopeError.cbor(\"node subject is missing\");\n }\n const subject = Envelope.fromUntaggedCbor(subjectCbor);\n const assertions: Envelope[] = [];\n for (let i = 1; i < array.length; i++) {\n const assertionCbor = array.get(i);\n if (assertionCbor === undefined) {\n throw EnvelopeError.cbor(`node assertion at index ${i} is missing`);\n }\n assertions.push(Envelope.fromUntaggedCbor(assertionCbor));\n }\n return Envelope.newWithAssertions(subject, assertions);\n }\n\n // Check if it's a map (assertion)\n const map = asCborMap(cbor);\n if (map !== undefined) {\n const assertion = Assertion.fromCborMap(map);\n return Envelope.newWithAssertion(assertion);\n }\n\n // Handle known values (unsigned integers)\n if (cbor.type === MajorType.Unsigned) {\n const knownValue = new KnownValue(cbor.value as number | bigint);\n return Envelope.newWithKnownValue(knownValue);\n }\n\n throw EnvelopeError.cbor(\"invalid envelope format\");\n }\n\n /// Creates an envelope from tagged CBOR.\n ///\n /// @param cbor - The tagged CBOR value (should have TAG_ENVELOPE)\n /// @returns A new envelope\n static fromTaggedCbor(cbor: Cbor): Envelope {\n try {\n const untagged = tryExpectedTaggedValue(cbor, TAG_ENVELOPE);\n return Envelope.fromUntaggedCbor(untagged);\n } catch (error) {\n throw EnvelopeError.cbor(\n `expected TAG_ENVELOPE (${TAG_ENVELOPE})`,\n error instanceof Error ? error : undefined,\n );\n }\n }\n\n /// Adds an assertion to this envelope.\n ///\n /// @param predicate - The assertion predicate\n /// @param object - The assertion object\n /// @returns A new envelope with the assertion added\n ///\n /// @example\n /// ```typescript\n /// const person = Envelope.new(\"Alice\")\n /// .addAssertion(\"age\", 30)\n /// .addAssertion(\"city\", \"Boston\");\n /// ```\n addAssertion(predicate: EnvelopeEncodableValue, object: EnvelopeEncodableValue): Envelope {\n const assertion = Envelope.newAssertion(predicate, object);\n return this.addAssertionEnvelope(assertion);\n }\n\n /// Adds an assertion envelope to this envelope.\n ///\n /// @param assertion - The assertion envelope\n /// @returns A new envelope with the assertion added\n addAssertionEnvelope(assertion: Envelope): Envelope {\n const c = this.#case;\n\n // If this is already a node, add to existing assertions\n if (c.type === \"node\") {\n return Envelope.newWithAssertions(c.subject, [...c.assertions, assertion]);\n }\n\n // Otherwise, create a new node with this envelope as subject\n return Envelope.newWithAssertions(this, [assertion]);\n }\n\n /// Creates a string representation of this envelope.\n ///\n /// @returns A string representation\n toString(): string {\n return `Envelope(${this.#case.type})`;\n }\n\n /// Creates a shallow copy of this envelope.\n ///\n /// Since envelopes are immutable, this returns the same instance.\n ///\n /// @returns This envelope\n clone(): Envelope {\n return this;\n }\n\n //\n // Format methods (implemented via prototype extension in format module)\n //\n\n /// Returns a tree-formatted string representation of the envelope.\n ///\n /// The tree format displays the hierarchical structure of the envelope,\n /// showing subjects, assertions, and their relationships.\n ///\n /// @param options - Optional formatting options\n /// @returns A tree-formatted string\n declare treeFormat: (options?: {\n hideNodes?: boolean;\n highlightDigests?: Set<string>;\n digestDisplay?: \"short\" | \"full\";\n }) => string;\n\n /// Returns a short identifier for this envelope based on its digest.\n ///\n /// @param format - Format for the digest ('short' or 'full')\n /// @returns A digest identifier string\n declare shortId: (format?: \"short\" | \"full\") => string;\n\n /// Returns a summary string for this envelope.\n ///\n /// @param maxLength - Maximum length of the summary\n /// @returns A summary string\n declare summary: (maxLength?: number) => string;\n\n /// Returns a hex representation of the envelope's CBOR encoding.\n ///\n /// @returns A hex string\n declare hex: () => string;\n\n /// Returns the CBOR-encoded bytes of the envelope.\n ///\n /// @returns The CBOR bytes\n declare cborBytes: () => Uint8Array;\n\n /// Returns a CBOR diagnostic notation string for the envelope.\n ///\n /// @returns A diagnostic string\n declare diagnostic: () => string;\n}\n","import type { Envelope } from \"./envelope\";\n\n/// A trait for types that can be encoded as a Gordian Envelope.\n///\n/// This interface defines the contract for converting a value into an envelope.\n/// Types implementing this interface can be used directly with envelope\n/// construction functions without explicit conversion.\n///\n/// There are numerous built-in implementations for common types including:\n/// - Primitive types (numbers, strings, booleans)\n/// - CBOR values\n/// - Cryptographic types (digests, keys, etc.)\n/// - Assertions\n/// - Other envelopes\n///\n/// @example\n/// ```typescript\n/// // String implements EnvelopeEncodable\n/// const e1 = Envelope.new(\"Hello\");\n///\n/// // Numbers implement EnvelopeEncodable\n/// const e2 = Envelope.new(42);\n///\n/// // Using in envelope construction\n/// const envelope = Envelope.new(\"subject\")\n/// .addAssertion(\"name\", \"Alice\") // Uses EnvelopeEncodable for both predicate and object\n/// .addAssertion(\"age\", 30); // Uses EnvelopeEncodable for the numeric object\n/// ```\nexport interface EnvelopeEncodable {\n /// Converts this value into a Gordian Envelope.\n ///\n /// This is the core method of the interface, converting the implementing type\n /// into an envelope representation. Most implementations will convert the\n /// value to a leaf envelope containing the value.\n ///\n /// @returns A new envelope containing the value.\n intoEnvelope(): Envelope;\n}\n\n/// Type guard to check if a value implements EnvelopeEncodable.\n///\n/// @param value - The value to check\n/// @returns `true` if the value implements EnvelopeEncodable, `false` otherwise\nexport function isEnvelopeEncodable(value: unknown): value is EnvelopeEncodable {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"intoEnvelope\" in value &&\n typeof (value as EnvelopeEncodable).intoEnvelope === \"function\"\n );\n}\n\n/// Helper type for values that can be encoded as envelopes.\n///\n/// This includes:\n/// - Types that directly implement EnvelopeEncodable\n/// - Primitive types (string, number, boolean)\n/// - Uint8Array (for binary data)\n/// - null and undefined\n///\n/// The Envelope class will handle conversion of these types automatically.\nexport type EnvelopeEncodableValue =\n | EnvelopeEncodable\n | string\n | number\n | boolean\n | bigint\n | Uint8Array\n | null\n | undefined\n | Envelope;\n","import type { Cbor } from \"@bcts/dcbor\";\nimport {\n type CborTagged,\n type CborTaggedEncodable,\n type CborTaggedDecodable,\n tagsForValues,\n cborData,\n decodeCbor,\n} from \"@bcts/dcbor\";\nimport { ENVELOPE } from \"@bcts/components\";\nimport { Envelope } from \"./envelope\";\n\nconst TAG_ENVELOPE = ENVELOPE.value;\n\n/// Support for CBOR encoding and decoding of `Envelope`.\n///\n/// All envelopes are tagged with the `envelope` tag (200). Within that tag,\n/// each of the envelope cases has a unique CBOR signature:\n///\n/// * `.node` contains a CBOR array, the first element of which is the subject,\n/// followed by one or more assertions.\n/// * `.leaf` is tagged #6.24 (TAG_ENCODED_CBOR) or #6.204 (TAG_LEAF), which\n/// are the IANA tag for embedded CBOR.\n/// * `.wrapped` is tagged with the `envelope` tag.\n/// * `.assertion` is a single-element map `{predicate: object}`.\n/// * `.knownValue` is an unsigned 64-bit integer.\n/// * `.encrypted` is tagged with the `crypto-msg` tag.\n/// * `.elided` is a byte string of length 32 (the digest).\n/// * `.compressed` is tagged with the `compressed` tag.\n///\n/// This module provides implementations of the CBOR encoding/decoding traits\n/// for the Envelope type, matching the Rust bc-envelope implementation.\n\n/// Implements CborTagged interface for Envelope.\n///\n/// Returns the tags that should be used for CBOR encoding.\nexport class EnvelopeCBORTagged implements CborTagged {\n cborTags(): ReturnType<typeof tagsForValues> {\n return tagsForValues([TAG_ENVELOPE]);\n }\n\n static cborTags(): number[] {\n return tagsForValues([TAG_ENVELOPE]).map((tag) => Number(tag.value));\n }\n}\n\n/// Implements CborTaggedEncodable for Envelope.\n///\n/// Provides the untagged CBOR representation of an envelope.\nexport class EnvelopeCBORTaggedEncodable implements CborTaggedEncodable {\n constructor(private readonly envelope: Envelope) {}\n\n cborTags(): ReturnType<typeof tagsForValues> {\n return tagsForValues([TAG_ENVELOPE]);\n }\n\n untaggedCbor(): Cbor {\n return this.envelope.untaggedCbor();\n }\n\n taggedCbor(): Cbor {\n return this.envelope.taggedCbor();\n }\n}\n\n/// Implements CborTaggedDecodable for Envelope.\n///\n/// Provides the ability to decode an envelope from untagged CBOR.\nexport class EnvelopeCBORTaggedDecodable<T = Envelope> implements CborTaggedDecodable<T> {\n cborTags(): ReturnType<typeof tagsForValues> {\n return tagsForValues([TAG_ENVELOPE]);\n }\n\n static fromUntaggedCbor(cbor: Cbor): Envelope {\n return Envelope.fromUntaggedCbor(cbor);\n }\n\n static fromTaggedCbor(cbor: Cbor): Envelope {\n return Envelope.fromTaggedCbor(cbor);\n }\n\n fromUntaggedCbor(cbor: Cbor): T {\n return Envelope.fromUntaggedCbor(cbor) as T;\n }\n\n fromTaggedCbor(cbor: Cbor): T {\n return Envelope.fromTaggedCbor(cbor) as T;\n }\n}\n\n/// Convenience function to convert an Envelope to CBOR.\n///\n/// @param envelope - The envelope to convert\n/// @returns The CBOR representation (tagged)\nexport function envelopeToCbor(envelope: Envelope): Cbor {\n return envelope.taggedCbor();\n}\n\n/// Convenience function to create an Envelope from CBOR.\n///\n/// @param cbor - The CBOR value (expected to be tagged with TAG_ENVELOPE)\n/// @returns A new Envelope\nexport function envelopeFromCbor(cbor: Cbor): Envelope {\n return Envelope.fromTaggedCbor(cbor);\n}\n\n/// Convenience function to encode an Envelope to CBOR bytes.\n///\n/// @param envelope - The envelope to encode\n/// @returns The CBOR bytes\nexport function envelopeToBytes(envelope: Envelope): Uint8Array {\n return cborData(envelope.taggedCbor());\n}\n\n/// Convenience function to decode an Envelope from CBOR bytes.\n///\n/// @param bytes - The CBOR bytes\n/// @returns A new Envelope\nexport function envelopeFromBytes(bytes: Uint8Array): Envelope {\n const cbor = decodeCbor(bytes);\n return Envelope.fromTaggedCbor(cbor);\n}\n","import type { Cbor } from \"@bcts/dcbor\";\nimport { tryIntoText, tryIntoBool, tryIntoByteString, isNull, decodeCbor } from \"@bcts/dcbor\";\nimport { Envelope } from \"./envelope\";\nimport { EnvelopeError } from \"./error\";\n\n/// Provides functions for extracting typed values from envelopes.\n///\n/// This module defines conversion functions that parallel Rust's `TryFrom<Envelope>`\n/// implementations. These allow extracting specific types from envelope leaf values.\n///\n/// In the Rust version, a macro (`impl_envelope_decodable!`) is used to generate\n/// these implementations for many types. In TypeScript, we provide explicit\n/// conversion functions instead.\n\n/// Extracts a string value from an envelope.\n///\n/// @param envelope - The envelope to extract from\n/// @returns The string value\n/// @throws {EnvelopeError} If the envelope is not a leaf or cannot be converted\nexport function extractString(envelope: Envelope): string {\n const cbor = envelope.tryLeaf();\n try {\n return tryIntoText(cbor);\n } catch (error) {\n throw EnvelopeError.cbor(\n \"envelope does not contain a string\",\n error instanceof Error ? error : undefined,\n );\n }\n}\n\n/// Extracts a number value from an envelope.\n///\n/// @param envelope - The envelope to extract from\n/// @returns The number value\n/// @throws {EnvelopeError} If the envelope is not a leaf or cannot be converted\nexport function extractNumber(envelope: Envelope): number {\n const cbor = envelope.tryLeaf();\n\n // Handle unsigned, negative, and simple (float) types\n if (\"type\" in cbor) {\n switch (cbor.type) {\n case 0: // MajorType.Unsigned\n return typeof cbor.value === \"bigint\" ? Number(cbor.value) : cbor.value;\n case 1: {\n // MajorType.Negative\n // Negative values are stored as magnitude, convert back\n const magnitude = typeof cbor.value === \"bigint\" ? Number(cbor.value) : cbor.value;\n return -magnitude - 1;\n }\n case 7: // MajorType.Simple\n if (\n typeof cbor.value === \"object\" &&\n cbor.value !== null &&\n \"type\" in cbor.value &&\n cbor.value.type === \"Float\"\n ) {\n return cbor.value.value;\n }\n break;\n case 2: // MajorType.ByteString\n case 3: // MajorType.TextString\n case 4: // MajorType.Array\n case 5: // MajorType.Map\n case 6: // MajorType.Tag\n // These CBOR types don't represent numbers\n break;\n }\n }\n\n throw EnvelopeError.cbor(\"envelope does not contain a number\");\n}\n\n/// Extracts a boolean value from an envelope.\n///\n/// @param envelope - The envelope to extract from\n/// @returns The boolean value\n/// @throws {EnvelopeError} If the envelope is not a leaf or cannot be converted\nexport function extractBoolean(envelope: Envelope): boolean {\n const cbor = envelope.tryLeaf();\n try {\n return tryIntoBool(cbor);\n } catch (error) {\n throw EnvelopeError.cbor(\n \"envelope does not contain a boolean\",\n error instanceof Error ? error : undefined,\n );\n }\n}\n\n/// Extracts a byte array value from an envelope.\n///\n/// @param envelope - The envelope to extract from\n/// @returns The byte array value\n/// @throws {EnvelopeError} If the envelope is not a leaf or cannot be converted\nexport function extractBytes(envelope: Envelope): Uint8Array {\n const cbor = envelope.tryLeaf();\n try {\n return tryIntoByteString(cbor);\n } catch (error) {\n throw EnvelopeError.cbor(\n \"envelope does not contain bytes\",\n error instanceof Error ? error : undefined,\n );\n }\n}\n\n/// Extracts null from an envelope.\n///\n/// @param envelope - The envelope to extract from\n/// @throws {EnvelopeError} If the envelope is not a leaf containing null\nexport function extractNull(envelope: Envelope): null {\n const cbor = envelope.tryLeaf();\n if (isNull(cbor)) {\n return null;\n }\n throw EnvelopeError.cbor(\"envelope does not contain null\");\n}\n\n/// Extension methods for Envelope to support CBOR decoding.\n///\n/// These methods are added to the Envelope class prototype to match\n/// the Rust API.\ndeclare module \"./envelope\" {\n interface Envelope {\n /// Attempts to extract the leaf CBOR value from this envelope.\n ///\n /// @returns The CBOR value contained in the leaf\n /// @throws {EnvelopeError} If the envelope is not a leaf\n tryLeaf(): Cbor;\n\n /// Converts this envelope to a string.\n ///\n /// @returns The string value\n /// @throws {EnvelopeError} If the envelope cannot be converted\n extractString(): string;\n\n /// Converts this envelope to a number.\n ///\n /// @returns The number value\n /// @throws {EnvelopeError} If the envelope cannot be converted\n extractNumber(): number;\n\n /// Converts this envelope to a boolean.\n ///\n /// @returns The boolean value\n /// @throws {EnvelopeError} If the envelope cannot be converted\n extractBoolean(): boolean;\n\n /// Converts this envelope to a byte array.\n ///\n /// @returns The byte array value\n /// @throws {EnvelopeError} If the envelope cannot be converted\n extractBytes(): Uint8Array;\n\n /// Extracts null from this envelope.\n ///\n /// @throws {EnvelopeError} If the envelope does not contain null\n extractNull(): null;\n }\n}\n\n/// Static methods for creating envelopes from CBOR data.\n///\n/// These are convenience methods that mirror the Rust implementation.\nexport class EnvelopeDecoder {\n /// Creates an envelope from a CBOR value.\n ///\n /// @param cbor - The CBOR value to convert into an envelope\n /// @returns A new envelope created from the CBOR data\n /// @throws {EnvelopeError} If the CBOR does not represent a valid envelope\n static tryFromCbor(cbor: Cbor): Envelope {\n try {\n return Envelope.fromTaggedCbor(cbor);\n } catch (error) {\n throw EnvelopeError.cbor(\"invalid envelope CBOR\", error instanceof Error ? error : undefined);\n }\n }\n\n /// Creates an envelope from raw CBOR binary data.\n ///\n /// @param data - The raw CBOR binary data to convert into an envelope\n /// @returns A new envelope created from the CBOR data\n /// @throws {EnvelopeError} If the data is not valid CBOR or does not\n /// represent a valid envelope structure\n static tryFromCborData(data: Uint8Array): Envelope {\n try {\n const cbor = decodeCbor(data);\n return EnvelopeDecoder.tryFromCbor(cbor);\n } catch (error) {\n throw EnvelopeError.cbor(\n \"invalid envelope CBOR data\",\n error instanceof Error ? error : undefined,\n );\n }\n }\n}\n\n/// Add the tryLeaf method to Envelope prototype.\n///\n/// This extracts the leaf CBOR value from an envelope.\nEnvelope.prototype.tryLeaf = function (this: Envelope): Cbor {\n const c = this.case();\n if (c.type !== \"leaf\") {\n throw EnvelopeError.notLeaf();\n }\n return c.cbor;\n};\n\n/// Add extraction convenience methods to Envelope prototype\nEnvelope.prototype.extractString = function (this: Envelope): string {\n return extractString(this);\n};\n\nEnvelope.prototype.extractNumber = function (this: Envelope): number {\n return extractNumber(this);\n};\n\nEnvelope.prototype.extractBoolean = function (this: Envelope): boolean {\n return extractBoolean(this);\n};\n\nEnvelope.prototype.extractBytes = function (this: Envelope): Uint8Array {\n return extractBytes(this);\n};\n\nEnvelope.prototype.extractNull = function (this: Envelope): null {\n return extractNull(this);\n};\n","import { type Digest, type DigestProvider } from \"./digest\";\nimport { Envelope } from \"./envelope\";\nimport { Assertion } from \"./assertion\";\nimport { EnvelopeError } from \"./error\";\n\n/// Types of obscuration that can be applied to envelope elements.\n///\n/// This enum identifies the different ways an envelope element can be obscured.\nexport enum ObscureType {\n /// The element has been elided, showing only its digest.\n Elided = \"elided\",\n\n /// The element has been encrypted using symmetric encryption.\n /// TODO: Implement when encrypt feature is added\n Encrypted = \"encrypted\",\n\n /// The element has been compressed to reduce its size.\n /// TODO: Implement when compress feature is added\n Compressed = \"compressed\",\n}\n\n/// Actions that can be performed on parts of an envelope to obscure them.\n///\n/// Gordian Envelope supports several ways to obscure parts of an envelope while\n/// maintaining its semantic integrity and digest tree.\nexport type ObscureAction =\n | { type: \"elide\" }\n | { type: \"encrypt\"; key: unknown } // TODO: SymmetricKey type\n | { type: \"compress\" };\n\n/// Helper to create elide action\nexport function elideAction(): ObscureAction {\n return { type: \"elide\" };\n}\n\n/// Support for eliding elements from envelopes.\ndeclare module \"./envelope\" {\n interface Envelope {\n /// Returns the elided variant of this envelope.\n ///\n /// Elision replaces an envelope with just its digest, hiding its content\n /// while maintaining the integrity of the envelope's digest tree.\n ///\n /// @returns The elided envelope\n elide(): Envelope;\n\n /// Returns a version of this envelope with elements in the target set\n /// obscured using the specified action.\n ///\n /// @param target - The set of digests that identify elements to be obscured\n /// @param action - The action to perform on the targeted elements\n /// @returns The modified envelope\n elideRemovingSetWithAction(target: Set<Digest>, action: ObscureAction): Envelope;\n\n /// Returns a version of this envelope with elements in the target set\n /// elided.\n ///\n /// @param target - The set of digests that identify elements to be elided\n /// @returns The modified envelope\n elideRemovingSet(target: Set<Digest>): Envelope;\n\n /// Returns a version of this envelope with elements in the target array\n /// obscured using the specified action.\n ///\n /// @param target - An array of DigestProviders\n /// @param action - The action to perform\n /// @returns The modified envelope\n elideRemovingArrayWithAction(target: DigestProvider[], action: ObscureAction): Envelope;\n\n /// Returns a version of this envelope with elements in the target array\n /// elided.\n ///\n /// @param target - An array of DigestProviders\n /// @returns The modified envelope\n elideRemovingArray(target: DigestProvider[]): Envelope;\n\n /// Returns a version of this envelope with the target element obscured.\n ///\n /// @param target - A DigestProvider\n /// @param action - The action to perform\n /// @returns The modified envelope\n elideRemovingTargetWithAction(target: DigestProvider, action: ObscureAction): Envelope;\n\n /// Returns a version of this envelope with the target element elided.\n ///\n /// @param target - A DigestProvider\n /// @returns The modified envelope\n elideRemovingTarget(target: DigestProvider): Envelope;\n\n /// Returns a version of this envelope with only elements in the target set\n /// revealed, and all other elements obscured.\n ///\n /// @param target - The set of digests that identify elements to be revealed\n /// @param action - The action to perform on other elements\n /// @returns The modified envelope\n elideRevealingSetWithAction(target: Set<Digest>, action: ObscureAction): Envelope;\n\n /// Returns a version of this envelope with only elements in the target set\n /// revealed.\n ///\n /// @param target - The set of digests that identify elements to be revealed\n /// @returns The modified envelope\n elideRevealingSet(target: Set<Digest>): Envelope;\n\n /// Returns a version of this envelope with elements not in the target array\n /// obscured.\n ///\n /// @param target - An array of DigestProviders\n /// @param action - The action to perform\n /// @returns The modified envelope\n elideRevealingArrayWithAction(target: DigestProvider[], action: ObscureAction): Envelope;\n\n /// Returns a version of this envelope with elements not in the target array\n /// elided.\n ///\n /// @param target - An array of DigestProviders\n /// @returns The modified envelope\n elideRevealingArray(target: DigestProvider[]): Envelope;\n\n /// Returns a version of this envelope with all elements except the target\n /// element obscured.\n ///\n /// @param target - A DigestProvider\n /// @param action - The action to perform\n /// @returns The modified envelope\n elideRevealingTargetWithAction(target: DigestProvider, action: ObscureAction): Envelope;\n\n /// Returns a version of this envelope with all elements except the target\n /// element elided.\n ///\n /// @param target - A DigestProvider\n /// @returns The modified envelope\n elideRevealingTarget(target: DigestProvider): Envelope;\n\n /// Returns the unelided variant of this envelope by revealing the original\n /// content.\n ///\n /// @param envelope - The original unelided envelope\n /// @returns The revealed envelope\n /// @throws {EnvelopeError} If digests don't match\n unelide(envelope: Envelope): Envelope;\n\n /// Returns the set of digests of nodes matching the specified criteria.\n ///\n /// @param targetDigests - Optional set of digests to filter by\n /// @param obscureTypes - Array of ObscureType values to match against\n /// @returns A Set of matching digests\n nodesMatching(targetDigests: Set<Digest> | undefined, obscureTypes: ObscureType[]): Set<Digest>;\n\n /// Returns a new envelope with elided nodes restored from the provided set.\n ///\n /// @param envelopes - An array of envelopes that may match elided nodes\n /// @returns The envelope with restored nodes\n walkUnelide(envelopes: Envelope[]): Envelope;\n\n /// Returns a new envelope with nodes matching target digests replaced.\n ///\n /// @param target - Set of digests identifying nodes to replace\n /// @param replacement - The envelope to use for replacement\n /// @returns The modified envelope\n /// @throws {EnvelopeError} If replacement is invalid\n walkReplace(target: Set<Digest>, replacement: Envelope): Envelope;\n\n /// Checks if two envelopes are identical (same structure and content).\n ///\n /// @param other - The other envelope to compare with\n /// @returns `true` if identical\n isIdenticalTo(other: Envelope): boolean;\n }\n}\n\n/// Implementation of elide()\nEnvelope.prototype.elide = function (this: Envelope): Envelope {\n const c = this.case();\n if (c.type === \"elided\") {\n return this;\n }\n return Envelope.newElided(this.digest());\n};\n\n/// Core elision logic\nfunction elideSetWithAction(\n envelope: Envelope,\n target: Set<Digest>,\n isRevealing: boolean,\n action: ObscureAction,\n): Envelope {\n const selfDigest = envelope.digest();\n const targetContainsSelf = Array.from(target).some((d) => d.equals(selfDigest));\n\n // Target Matches isRevealing elide\n // false false false\n // false true true\n // true false true\n // true true false\n\n if (targetContainsSelf !== isRevealing) {\n // Should obscure this envelope\n if (action.type === \"elide\") {\n return envelope.elide();\n } else if (action.type === \"encrypt\") {\n // TODO: Implement encryption\n throw new Error(\"Encryption not yet implemented\");\n } else if (action.type === \"compress\") {\n // TODO: Implement compression\n throw new Error(\"Compression not yet implemented\");\n }\n }\n\n const c = envelope.case();\n\n // Recursively process structure\n if (c.type === \"assertion\") {\n const predicate = elideSetWithAction(c.assertion.predicate(), target, isRevealing, action);\n const object = elideSetWithAction(c.assertion.object(), target, isRevealing, action);\n const elidedAssertion = new Assertion(predicate, object);\n return Envelope.newWithAssertion(elidedAssertion);\n } else if (c.type === \"node\") {\n const elidedSubject = elideSetWithAction(c.subject, target, isRevealing, action);\n const elidedAssertions = c.assertions.map((a) =>\n elideSetWithAction(a, target, isRevealing, action),\n );\n return Envelope.newWithUncheckedAssertions(elidedSubject, elidedAssertions);\n } else if (c.type === \"wrapped\") {\n const elidedEnvelope = elideSetWithAction(c.envelope, target, isRevealing, action);\n return Envelope.newWrapped(elidedEnvelope);\n }\n\n return envelope;\n}\n\n/// Implementation of elideRemovingSetWithAction\nEnvelope.prototype.elideRemovingSetWithAction = function (\n this: Envelope,\n target: Set<Digest>,\n action: ObscureAction,\n): Envelope {\n return elideSetWithAction(this, target, false, action);\n};\n\n/// Implementation of elideRemovingSet\nEnvelope.prototype.elideRemovingSet = function (this: Envelope, target: Set<Digest>): Envelope {\n return elideSetWithAction(this, target, false, elideAction());\n};\n\n/// Implementation of elideRemovingArrayWithAction\nEnvelope.prototype.elideRemovingArrayWithAction = function (\n this: Envelope,\n target: DigestProvider[],\n action: ObscureAction,\n): Envelope {\n const targetSet = new Set(target.map((p) => p.digest()));\n return elideSetWithAction(this, targetSet, false, action);\n};\n\n/// Implementation of elideRemovingArray\nEnvelope.prototype.elideRemovingArray = function (\n this: Envelope,\n target: DigestProvider[],\n): Envelope {\n const targetSet = new Set(target.map((p) => p.digest()));\n return elideSetWithAction(this, targetSet, false, elideAction());\n};\n\n/// Implementation of elideRemovingTargetWithAction\nEnvelope.prototype.elideRemovingTargetWithAction = function (\n this: Envelope,\n target: DigestProvider,\n action: ObscureAction,\n): Envelope {\n return this.elideRemovingArrayWithAction([target], action);\n};\n\n/// Implementation of elideRemovingTarget\nEnvelope.prototype.elideRemovingTarget = function (\n this: Envelope,\n target: DigestProvider,\n): Envelope {\n return this.elideRemovingArray([target]);\n};\n\n/// Implementation of elideRevealingSetWithAction\nEnvelope.prototype.elideRevealingSetWithAction = function (\n this: Envelope,\n target: Set<Digest>,\n action: ObscureAction,\n): Envelope {\n return elideSetWithAction(this, target, true, action);\n};\n\n/// Implementation of elideRevealingSet\nEnvelope.prototype.elideRevealingSet = function (this: Envelope, target: Set<Digest>): Envelope {\n return elideSetWithAction(this, target, true, elideAction());\n};\n\n/// Implementation of elideRevealingArrayWithAction\nEnvelope.prototype.elideRevealingArrayWithAction = function (\n this: Envelope,\n target: DigestProvider[],\n action: ObscureAction,\n): Envelope {\n const targetSet = new Set(target.map((p) => p.digest()));\n return elideSetWithAction(this, targetSet, true, action);\n};\n\n/// Implementation of elideRevealingArray\nEnvelope.prototype.elideRevealingArray = function (\n this: Envelope,\n target: DigestProvider[],\n): Envelope {\n const targetSet = new Set(target.map((p) => p.digest()));\n return elideSetWithAction(this, targetSet, true, elideAction());\n};\n\n/// Implementation of elideRevealingTargetWithAction\nEnvelope.prototype.elideRevealingTargetWithAction = function (\n this: Envelope,\n target: DigestProvider,\n action: ObscureAction,\n): Envelope {\n return this.elideRevealingArrayWithAction([target], action);\n};\n\n/// Implementation of elideRevealingTarget\nEnvelope.prototype.elideRevealingTarget = function (\n this: Envelope,\n target: DigestProvider,\n): Envelope {\n return this.elideRevealingArray([target]);\n};\n\n/// Implementation of unelide\nEnvelope.prototype.unelide = function (this: Envelope, envelope: Envelope): Envelope {\n if (this.digest().equals(envelope.digest())) {\n return envelope;\n }\n throw EnvelopeError.invalidDigest();\n};\n\n/// Implementation of nodesMatching\nEnvelope.prototype.nodesMatching = function (\n this: Envelope,\n targetDigests: Set<Digest> | undefined,\n obscureTypes: ObscureType[],\n): Set<Digest> {\n const result = new Set<Digest>();\n\n const visitor = (envelope: Envelope): void => {\n // Check if this node matches the target digests\n const digestMatches =\n targetDigests === undefined ||\n Array.from(targetDigests).some((d) => d.equals(envelope.digest()));\n\n if (!digestMatches) {\n return;\n }\n\n // If no obscure types specified, include all nodes\n if (obscureTypes.length === 0) {\n result.add(envelope.digest());\n return;\n }\n\n // Check if this node matches any of the specified obscure types\n const c = envelope.case();\n const typeMatches = obscureTypes.some((obscureType) => {\n if (obscureType === ObscureType.Elided && c.type === \"elided\") {\n return true;\n }\n if (obscureType === ObscureType.Encrypted && c.type === \"encrypted\") {\n return true;\n }\n if (obscureType === ObscureType.Compressed && c.type === \"compressed\") {\n return true;\n }\n return false;\n });\n\n if (typeMatches) {\n result.add(envelope.digest());\n }\n };\n\n // Walk the envelope tree\n walkEnvelope(this, visitor);\n\n return result;\n};\n\n/// Helper to walk envelope tree\nfunction walkEnvelope(envelope: Envelope, visitor: (e: Envelope) => void): void {\n visitor(envelope);\n\n const c = envelope.case();\n if (c.type === \"node\") {\n walkEnvelope(c.subject, visitor);\n for (const assertion of c.assertions) {\n walkEnvelope(assertion, visitor);\n }\n } else if (c.type === \"assertion\") {\n walkEnvelope(c.assertion.predicate(), visitor);\n walkEnvelope(c.assertion.object(), visitor);\n } else if (c.type === \"wrapped\") {\n walkEnvelope(c.envelope, visitor);\n }\n}\n\n/// Implementation of walkUnelide\nEnvelope.prototype.walkUnelide = function (this: Envelope, envelopes: Envelope[]): Envelope {\n // Build a lookup map of digest -> envelope\n const envelopeMap = new Map<string, Envelope>();\n for (const env of envelopes) {\n envelopeMap.set(env.digest().hex(), env);\n }\n\n return walkUnelideWithMap(this, envelopeMap);\n};\n\n/// Helper for walkUnelide with map\nfunction walkUnelideWithMap(envelope: Envelope, envelopeMap: Map<string, Envelope>): Envelope {\n const c = envelope.case();\n\n if (c.type === \"elided\") {\n // Try to find a matching envelope to restore\n const replacement = envelopeMap.get(envelope.digest().hex());\n return replacement ?? envelope;\n }\n\n if (c.type === \"node\") {\n const newSubject = walkUnelideWithMap(c.subject, envelopeMap);\n const newAssertions = c.assertions.map((a) => walkUnelideWithMap(a, envelopeMap));\n\n if (\n newSubject.isIdenticalTo(c.subject) &&\n newAssertions.every((a, i) => a.isIdenticalTo(c.assertions[i]))\n ) {\n return envelope;\n }\n\n return Envelope.newWithUncheckedAssertions(newSubject, newAssertions);\n }\n\n if (c.type === \"wrapped\") {\n const newEnvelope = walkUnelideWithMap(c.envelope, envelopeMap);\n if (newEnvelope.isIdenticalTo(c.envelope)) {\n return envelope;\n }\n return Envelope.newWrapped(newEnvelope);\n }\n\n if (c.type === \"assertion\") {\n const newPredicate = walkUnelideWithMap(c.assertion.predicate(), envelopeMap);\n const newObject = walkUnelideWithMap(c.assertion.object(), envelopeMap);\n\n if (\n newPredicate.isIdenticalTo(c.assertion.predicate()) &&\n newObject.isIdenticalTo(c.assertion.object())\n ) {\n return envelope;\n }\n\n return Envelope.newAssertion(newPredicate, newObject);\n }\n\n return envelope;\n}\n\n/// Implementation of walkReplace\nEnvelope.prototype.walkReplace = function (\n this: Envelope,\n target: Set<Digest>,\n replacement: Envelope,\n): Envelope {\n // Check if this node matches the target\n if (Array.from(target).some((d) => d.equals(this.digest()))) {\n return replacement;\n }\n\n const c = this.case();\n\n if (c.type === \"node\") {\n const newSubject = c.subject.walkReplace(target, replacement);\n const newAssertions = c.assertions.map((a) => a.walkReplace(target, replacement));\n\n if (\n newSubject.isIdenticalTo(c.subject) &&\n newAssertions.every((a, i) => a.isIdenticalTo(c.assertions[i]))\n ) {\n return this;\n }\n\n // Validate that all assertions are either assertions or obscured\n return Envelope.newWithAssertions(newSubject, newAssertions);\n }\n\n if (c.type === \"wrapped\") {\n const newEnvelope = c.envelope.walkReplace(target, replacement);\n if (newEnvelope.isIdenticalTo(c.envelope)) {\n return this;\n }\n return Envelope.newWrapped(newEnvelope);\n }\n\n if (c.type === \"assertion\") {\n const newPredicate = c.assertion.predicate().walkReplace(target, replacement);\n const newObject = c.assertion.object().walkReplace(target, replacement);\n\n if (\n newPredicate.isIdenticalTo(c.assertion.predicate()) &&\n newObject.isIdenticalTo(c.assertion.object())\n ) {\n return this;\n }\n\n return Envelope.newAssertion(newPredicate, newObject);\n }\n\n return this;\n};\n\n/// Implementation of isIdenticalTo\nEnvelope.prototype.isIdenticalTo = function (this: Envelope, other: Envelope): boolean {\n // Two envelopes are identical if they have the same digest\n // and the same case type (to handle wrapped vs unwrapped with same content)\n return this.digest().equals(other.digest()) && this.case().type === other.case().type;\n};\n","import { Envelope } from \"./envelope\";\n\n/// Functions for traversing and manipulating the envelope hierarchy.\n///\n/// This module provides functionality for traversing the hierarchical structure\n/// of envelopes, allowing for operations such as inspection, transformation,\n/// and extraction of specific elements. It implements a visitor pattern that\n/// enables executing arbitrary code on each element of an envelope in a\n/// structured way.\n///\n/// The traversal can be performed in two modes:\n/// - Structure-based traversal: Visits every element in the envelope hierarchy\n/// - Tree-based traversal: Skips node elements and focuses on the semantic\n/// content\n\n/// The type of incoming edge provided to the visitor.\n///\n/// This enum identifies how an envelope element is connected to its parent in\n/// the hierarchy during traversal. It helps the visitor function understand the\n/// semantic relationship between elements.\nexport enum EdgeType {\n /// No incoming edge (root)\n None = \"none\",\n /// Element is the subject of a node\n Subject = \"subject\",\n /// Element is an assertion on a node\n Assertion = \"assertion\",\n /// Element is the predicate of an assertion\n Predicate = \"predicate\",\n /// Element is the object of an assertion\n Object = \"object\",\n /// Element is the content wrapped by another envelope\n Content = \"content\",\n}\n\n/// Returns a short text label for the edge type, or undefined if no label is\n/// needed.\n///\n/// This is primarily used for tree formatting to identify relationships\n/// between elements.\n///\n/// @param edgeType - The edge type\n/// @returns A short label or undefined\nexport function edgeLabel(edgeType: EdgeType): string | undefined {\n switch (edgeType) {\n case EdgeType.Subject:\n return \"subj\";\n case EdgeType.Content:\n return \"cont\";\n case EdgeType.Predicate:\n return \"pred\";\n case EdgeType.Object:\n return \"obj\";\n case EdgeType.None:\n case EdgeType.Assertion:\n return undefined;\n default:\n return undefined;\n }\n}\n\n/// A visitor function that is called for each element in the envelope.\n///\n/// The visitor function takes the following parameters:\n/// - `envelope`: The current envelope element being visited\n/// - `level`: The depth level in the hierarchy (0 for root)\n/// - `incomingEdge`: The type of edge connecting this element to its parent\n/// - `state`: Optional context passed down from the parent's visitor call\n///\n/// The visitor returns a tuple of:\n/// - The state that will be passed to child elements\n/// - A boolean indicating whether to stop traversal (true = stop)\n///\n/// This enables accumulating state or passing context during traversal.\nexport type Visitor<State> = (\n envelope: Envelope,\n level: number,\n incomingEdge: EdgeType,\n state: State,\n) => [State, boolean];\n\ndeclare module \"./envelope\" {\n interface Envelope {\n /// Walks the envelope structure, calling the visitor function for each\n /// element.\n ///\n /// This function traverses the entire envelope hierarchy and calls the\n /// visitor function on each element. The traversal can be performed in\n /// two modes:\n ///\n /// - Structure-based traversal (`hideNodes = false`): Visits every element\n /// including node containers\n /// - Tree-based traversal (`hideNodes = true`): Skips node elements and\n /// focuses on semantic content\n ///\n /// The visitor function can optionally return a context value that is\n /// passed to child elements, enabling state to be accumulated or passed\n /// down during traversal.\n ///\n /// @param hideNodes - If true, the visitor will not be called for node\n /// containers\n /// @param state - Initial state passed to the visitor\n /// @param visit - The visitor function called for each element\n walk<State>(hideNodes: boolean, state: State, visit: Visitor<State>): void;\n }\n}\n\n/// Implementation of walk()\nEnvelope.prototype.walk = function <State>(\n this: Envelope,\n hideNodes: boolean,\n state: State,\n visit: Visitor<State>,\n): void {\n if (hideNodes) {\n walkTree(this, 0, EdgeType.None, state, visit);\n } else {\n walkStructure(this, 0, EdgeType.None, state, visit);\n }\n};\n\n/// Recursive implementation of structure-based traversal.\n///\n/// This internal function performs the actual recursive traversal of the\n/// envelope structure, visiting every element and maintaining the\n/// correct level and edge relationships.\nfunction walkStructure<State>(\n envelope: Envelope,\n level: number,\n incomingEdge: EdgeType,\n state: State,\n visit: Visitor<State>,\n): void {\n // Visit this envelope\n const [newState, stop] = visit(envelope, level, incomingEdge, state);\n if (stop) {\n return;\n }\n\n const nextLevel = level + 1;\n const c = envelope.case();\n\n switch (c.type) {\n case \"node\":\n // Visit subject\n walkStructure(c.subject, nextLevel, EdgeType.Subject, newState, visit);\n // Visit all assertions\n for (const assertion of c.assertions) {\n walkStructure(assertion, nextLevel, EdgeType.Assertion, newState, visit);\n }\n break;\n\n case \"wrapped\":\n // Visit wrapped envelope\n walkStructure(c.envelope, nextLevel, EdgeType.Content, newState, visit);\n break;\n\n case \"assertion\":\n // Visit predicate and object\n walkStructure(c.assertion.predicate(), nextLevel, EdgeType.Predicate, newState, visit);\n walkStructure(c.assertion.object(), nextLevel, EdgeType.Object, newState, visit);\n break;\n\n case \"leaf\":\n case \"elided\":\n case \"knownValue\":\n case \"encrypted\":\n case \"compressed\":\n // Leaf nodes and other types have no children\n break;\n }\n}\n\n/// Recursive implementation of tree-based traversal.\n///\n/// This internal function performs the actual recursive traversal of the\n/// envelope's semantic tree, skipping node containers and focusing on\n/// the semantic content elements. It maintains the correct level and\n/// edge relationships while skipping structural elements.\nfunction walkTree<State>(\n envelope: Envelope,\n level: number,\n incomingEdge: EdgeType,\n state: State,\n visit: Visitor<State>,\n): State {\n let currentState = state;\n let subjectLevel = level;\n\n // Skip visiting if this is a node\n if (!envelope.isNode()) {\n const [newState, stop] = visit(envelope, level, incomingEdge, currentState);\n if (stop) {\n return newState;\n }\n currentState = newState;\n subjectLevel = level + 1;\n }\n\n const c = envelope.case();\n\n switch (c.type) {\n case \"node\": {\n // Visit subject\n const assertionState = walkTree(\n c.subject,\n subjectLevel,\n EdgeType.Subject,\n currentState,\n visit,\n );\n // Visit all assertions\n const assertionLevel = subjectLevel + 1;\n for (const assertion of c.assertions) {\n walkTree(assertion, assertionLevel, EdgeType.Assertion, assertionState, visit);\n }\n break;\n }\n\n case \"wrapped\":\n // Visit wrapped envelope\n walkTree(c.envelope, subjectLevel, EdgeType.Content, currentState, visit);\n break;\n\n case \"assertion\":\n // Visit predicate and object\n walkTree(c.assertion.predicate(), subjectLevel, EdgeType.Predicate, currentState, visit);\n walkTree(c.assertion.object(), subjectLevel, EdgeType.Object, currentState, visit);\n break;\n\n case \"leaf\":\n case \"elided\":\n case \"knownValue\":\n case \"encrypted\":\n case \"compressed\":\n // Leaf nodes and other types have no children\n break;\n }\n\n return currentState;\n}\n","import { Envelope } from \"./envelope\";\nimport type { EnvelopeEncodableValue } from \"./envelope-encodable\";\nimport { EnvelopeError } from \"./error\";\n\n/// Support for adding assertions.\n///\n/// Assertions are predicate-object pairs that make statements about an\n/// envelope's subject. This implementation provides methods for adding various\n/// types of assertions to envelopes.\n///\n/// These methods extend the Envelope class to provide a rich API for\n/// working with assertions, matching the Rust bc-envelope implementation.\n\ndeclare module \"./envelope\" {\n interface Envelope {\n /// Returns a new envelope with multiple assertion envelopes added.\n ///\n /// This is a convenience method for adding multiple assertions at once.\n /// Each assertion in the array must be a valid assertion envelope or an\n /// obscured variant of one.\n ///\n /// @param assertions - An array of valid assertion envelopes to add\n /// @returns A new envelope with all the assertions added\n /// @throws {EnvelopeError} If any of the provided envelopes are not valid\n /// assertion envelopes\n addAssertionEnvelopes(assertions: Envelope[]): Envelope;\n\n /// Adds an optional assertion envelope to this envelope.\n ///\n /// If the optional assertion is present, adds it to the envelope.\n /// Otherwise, returns the envelope unchanged. This method is particularly\n /// useful when working with functions that may or may not return an\n /// assertion.\n ///\n /// The method also ensures that duplicate assertions (with the same digest)\n /// are not added, making it idempotent.\n ///\n /// @param assertion - An optional assertion envelope to add\n /// @returns A new envelope with the assertion added if provided, or the\n /// original envelope if no assertion was provided or it was a duplicate\n /// @throws {EnvelopeError} If the provided envelope is not a valid assertion\n /// envelope or an obscured variant\n addOptionalAssertionEnvelope(assertion: Envelope | undefined): Envelope;\n\n /// Adds an assertion with the given predicate and optional object.\n ///\n /// This method is useful when you have a predicate but may or may not have\n /// an object value to associate with it. If the object is present, an\n /// assertion is created and added to the envelope. Otherwise, the\n /// envelope is returned unchanged.\n ///\n /// @param predicate - The predicate for the assertion\n /// @param object - An optional object value for the assertion\n /// @returns A new envelope with the assertion added if the object was\n /// provided, or the original envelope if no object was provided\n addOptionalAssertion(\n predicate: EnvelopeEncodableValue,\n object: EnvelopeEncodableValue | undefined,\n ): Envelope;\n\n /// Adds an assertion with the given predicate and string value, but only if\n /// the string is non-empty.\n ///\n /// This is a convenience method that only adds an assertion if the string\n /// value is non-empty. It's particularly useful when working with user\n /// input or optional text fields that should only be included if they\n /// contain actual content.\n ///\n /// @param predicate - The predicate for the assertion\n /// @param str - The string value for the assertion\n /// @returns A new envelope with the assertion added if the string is\n /// non-empty, or the original envelope if the string is empty\n addNonemptyStringAssertion(predicate: EnvelopeEncodableValue, str: string): Envelope;\n\n /// Returns a new envelope with the given array of assertions added.\n ///\n /// Similar to `addAssertionEnvelopes` but doesn't throw errors. This is\n /// useful when you're certain all envelopes in the array are valid\n /// assertion envelopes and don't need to handle errors.\n ///\n /// @param envelopes - An array of assertion envelopes to add\n /// @returns A new envelope with all the valid assertions added\n addAssertions(envelopes: Envelope[]): Envelope;\n\n /// Adds an assertion only if the provided condition is true.\n ///\n /// This method allows for conditional inclusion of assertions based on a\n /// boolean condition. It's a convenient way to add assertions only in\n /// certain circumstances without requiring separate conditional logic.\n ///\n /// @param condition - Boolean that determines whether to add the assertion\n /// @param predicate - The predicate for the assertion\n /// @param object - The object value for the assertion\n /// @returns A new envelope with the assertion added if the condition is\n /// true, or the original envelope if the condition is false\n addAssertionIf(\n condition: boolean,\n predicate: EnvelopeEncodableValue,\n object: EnvelopeEncodableValue,\n ): Envelope;\n\n /// Adds an assertion envelope only if the provided condition is true.\n ///\n /// Similar to `addAssertionIf` but works with pre-constructed assertion\n /// envelopes. This is useful when you have already created an assertion\n /// envelope separately and want to conditionally add it.\n ///\n /// @param condition - Boolean that determines whether to add the assertion\n /// envelope\n /// @param assertionEnvelope - The assertion envelope to add\n /// @returns A new envelope with the assertion added if the condition is\n /// true, or the original envelope if the condition is false\n /// @throws {EnvelopeError} If the provided envelope is not a valid assertion\n /// envelope or an obscured variant and the condition is true\n addAssertionEnvelopeIf(condition: boolean, assertionEnvelope: Envelope): Envelope;\n\n /// Returns a new envelope with the given assertion removed.\n ///\n /// Finds and removes an assertion matching the target assertion's digest.\n /// If the assertion doesn't exist, returns the same envelope unchanged.\n /// If removing the assertion would leave the envelope with no assertions,\n /// returns just the subject as a new envelope.\n ///\n /// @param target - The assertion envelope to remove\n /// @returns A new envelope with the specified assertion removed if found,\n /// or the original envelope if not found\n removeAssertion(target: Envelope): Envelope;\n\n /// Returns a new envelope with the given assertion replaced by a new one.\n ///\n /// This method removes the specified assertion and adds a new one in its\n /// place. If the targeted assertion does not exist, returns the same\n /// envelope with the new assertion added.\n ///\n /// @param assertion - The assertion envelope to replace\n /// @param newAssertion - The new assertion envelope to add\n /// @returns A new envelope with the assertion replaced if found, or the\n /// original envelope with the new assertion added if not found\n /// @throws {EnvelopeError} If the new assertion is not a valid assertion\n /// envelope or an obscured variant\n replaceAssertion(assertion: Envelope, newAssertion: Envelope): Envelope;\n\n /// Returns a new envelope with its subject replaced by the provided one.\n ///\n /// This method preserves all assertions from the original envelope but\n /// applies them to a new subject. It effectively creates a new envelope\n /// with the provided subject and copies over all assertions from the\n /// current envelope.\n ///\n /// @param subject - The new subject for the envelope\n /// @returns A new envelope with the new subject and all assertions from the\n /// original envelope\n replaceSubject(subject: Envelope): Envelope;\n\n /// Returns the assertions of this envelope.\n ///\n /// For a node envelope, returns the array of assertion envelopes.\n /// For all other envelope types, returns an empty array.\n ///\n /// @returns An array of assertion envelopes\n assertions(): Envelope[];\n }\n}\n\n/// Implementation of addAssertionEnvelopes\nEnvelope.prototype.addAssertionEnvelopes = function (\n this: Envelope,\n assertions: Envelope[],\n): Envelope {\n return assertions.reduce((result, assertion) => result.addAssertionEnvelope(assertion), this);\n};\n\n/// Implementation of addOptionalAssertionEnvelope\nEnvelope.prototype.addOptionalAssertionEnvelope = function (\n this: Envelope,\n assertion: Envelope | undefined,\n): Envelope {\n if (assertion === undefined) {\n return this;\n }\n\n // Validate that the assertion is a valid assertion or obscured envelope\n if (!assertion.isSubjectAssertion() && !assertion.isSubjectObscured()) {\n throw EnvelopeError.invalidFormat();\n }\n\n const c = this.case();\n\n // Check if this is already a node\n if (c.type === \"node\") {\n // Check for duplicate assertions\n const isDuplicate = c.assertions.some((a) => a.digest().equals(assertion.digest()));\n if (isDuplicate) {\n return this;\n }\n\n // Add the new assertion\n return Envelope.newWithUncheckedAssertions(c.subject, [...c.assertions, assertion]);\n }\n\n // Otherwise, create a new node with this envelope as subject\n return Envelope.newWithUncheckedAssertions(this.subject(), [assertion]);\n};\n\n/// Implementation of addOptionalAssertion\nEnvelope.prototype.addOptionalAssertion = function (\n this: Envelope,\n predicate: EnvelopeEncodableValue,\n object: EnvelopeEncodableValue | undefined,\n): Envelope {\n if (object === undefined || object === null) {\n return this;\n }\n return this.addAssertion(predicate, object);\n};\n\n/// Implementation of addNonemptyStringAssertion\nEnvelope.prototype.addNonemptyStringAssertion = function (\n this: Envelope,\n predicate: EnvelopeEncodableValue,\n str: string,\n): Envelope {\n if (str.length === 0) {\n return this;\n }\n return this.addAssertion(predicate, str);\n};\n\n/// Implementation of addAssertions\nEnvelope.prototype.addAssertions = function (this: Envelope, envelopes: Envelope[]): Envelope {\n return envelopes.reduce((result, envelope) => result.addAssertionEnvelope(envelope), this);\n};\n\n/// Implementation of addAssertionIf\nEnvelope.prototype.addAssertionIf = function (\n this: Envelope,\n condition: boolean,\n predicate: EnvelopeEncodableValue,\n object: EnvelopeEncodableValue,\n): Envelope {\n if (condition) {\n return this.addAssertion(predicate, object);\n }\n return this;\n};\n\n/// Implementation of addAssertionEnvelopeIf\nEnvelope.prototype.addAssertionEnvelopeIf = function (\n this: Envelope,\n condition: boolean,\n assertionEnvelope: Envelope,\n): Envelope {\n if (condition) {\n return this.addAssertionEnvelope(assertionEnvelope);\n }\n return this;\n};\n\n/// Implementation of removeAssertion\nEnvelope.prototype.removeAssertion = function (this: Envelope, target: Envelope): Envelope {\n const assertions = this.assertions();\n const targetDigest = target.digest();\n\n const index = assertions.findIndex((a) => a.digest().equals(targetDigest));\n\n if (index === -1) {\n // Assertion not found, return unchanged\n return this;\n }\n\n // Remove the assertion\n const newAssertions = [...assertions.slice(0, index), ...assertions.slice(index + 1)];\n\n if (newAssertions.length === 0) {\n // No assertions left, return just the subject\n return this.subject();\n }\n\n // Return envelope with remaining assertions\n return Envelope.newWithUncheckedAssertions(this.subject(), newAssertions);\n};\n\n/// Implementation of replaceAssertion\nEnvelope.prototype.replaceAssertion = function (\n this: Envelope,\n assertion: Envelope,\n newAssertion: Envelope,\n): Envelope {\n return this.removeAssertion(assertion).addAssertionEnvelope(newAssertion);\n};\n\n/// Implementation of replaceSubject\nEnvelope.prototype.replaceSubject = function (this: Envelope, subject: Envelope): Envelope {\n return this.assertions().reduce((e, a) => e.addAssertionEnvelope(a), subject);\n};\n\n/// Implementation of assertions\nEnvelope.prototype.assertions = function (this: Envelope): Envelope[] {\n const c = this.case();\n if (c.type === \"node\") {\n return c.assertions;\n }\n return [];\n};\n","import type { Cbor, CborMap } from \"@bcts/dcbor\";\nimport { isNumber, isNaN, asArray, asMap, asText } from \"@bcts/dcbor\";\nimport { Envelope } from \"./envelope\";\n\n/// Provides methods for working with envelope leaf nodes,\n/// which are dCBOR values of any kind.\n///\n/// This module extends the Envelope class with convenience methods for\n/// working with leaf values, including type checking and extraction.\n\ndeclare module \"./envelope\" {\n interface Envelope {\n /// Checks if this envelope contains false.\n ///\n /// @returns `true` if the envelope's subject is false, `false` otherwise\n isFalse(): boolean;\n\n /// Checks if this envelope contains true.\n ///\n /// @returns `true` if the envelope's subject is true, `false` otherwise\n isTrue(): boolean;\n\n /// Checks if this envelope contains a boolean value.\n ///\n /// @returns `true` if the envelope's subject is a boolean, `false`\n /// otherwise\n isBool(): boolean;\n\n /// Checks if this envelope is a leaf node that contains a number.\n ///\n /// @returns `true` if the envelope is a leaf containing a number, `false`\n /// otherwise\n isNumber(): boolean;\n\n /// Checks if the subject of this envelope is a number.\n ///\n /// @returns `true` if the subject is a number, `false` otherwise\n isSubjectNumber(): boolean;\n\n /// Checks if this envelope is a leaf node that contains NaN.\n ///\n /// @returns `true` if the envelope is a leaf containing NaN, `false`\n /// otherwise\n isNaN(): boolean;\n\n /// Checks if the subject of this envelope is NaN.\n ///\n /// @returns `true` if the subject is NaN, `false` otherwise\n isSubjectNaN(): boolean;\n\n /// Checks if this envelope contains null.\n ///\n /// @returns `true` if the envelope's subject is null, `false` otherwise\n isNull(): boolean;\n\n /// Attempts to extract the leaf CBOR as a byte string.\n ///\n /// @returns The byte string value\n /// @throws {EnvelopeError} If the envelope is not a leaf or not a byte\n /// string\n tryByteString(): Uint8Array;\n\n /// Returns the leaf CBOR as a byte string if possible.\n ///\n /// @returns The byte string value or undefined\n asByteString(): Uint8Array | undefined;\n\n /// Returns the leaf CBOR as an array if possible.\n ///\n /// @returns The array value or undefined\n asArray(): readonly Cbor[] | undefined;\n\n /// Returns the leaf CBOR as a map if possible.\n ///\n /// @returns The map value or undefined\n asMap(): CborMap | undefined;\n\n /// Returns the leaf CBOR as text if possible.\n ///\n /// @returns The text value or undefined\n asText(): string | undefined;\n\n /// Returns the leaf CBOR value if this envelope is a leaf.\n ///\n /// @returns The CBOR value or undefined\n asLeaf(): Cbor | undefined;\n }\n}\n\n// Note: Static methods Envelope.false() and Envelope.true() are implemented below\n// but cannot be declared in TypeScript module augmentation due to reserved keywords.\n\n/// Implementation of static false()\n(Envelope as unknown as { false: () => Envelope }).false = function (): Envelope {\n return Envelope.newLeaf(false);\n};\n\n/// Implementation of static true()\n(Envelope as unknown as { true: () => Envelope }).true = function (): Envelope {\n return Envelope.newLeaf(true);\n};\n\n/// Implementation of isFalse()\nEnvelope.prototype.isFalse = function (this: Envelope): boolean {\n try {\n return this.extractBoolean() === false;\n } catch {\n return false;\n }\n};\n\n/// Implementation of isTrue()\nEnvelope.prototype.isTrue = function (this: Envelope): boolean {\n try {\n return this.extractBoolean() === true;\n } catch {\n return false;\n }\n};\n\n/// Implementation of isBool()\nEnvelope.prototype.isBool = function (this: Envelope): boolean {\n try {\n const value = this.extractBoolean();\n return typeof value === \"boolean\";\n } catch {\n return false;\n }\n};\n\n/// Implementation of isNumber()\nEnvelope.prototype.isNumber = function (this: Envelope): boolean {\n const leaf = this.asLeaf();\n if (leaf === undefined) {\n return false;\n }\n\n return isNumber(leaf);\n};\n\n/// Implementation of isSubjectNumber()\nEnvelope.prototype.isSubjectNumber = function (this: Envelope): boolean {\n return this.subject().isNumber();\n};\n\n/// Implementation of isNaN()\nEnvelope.prototype.isNaN = function (this: Envelope): boolean {\n const leaf = this.asLeaf();\n if (leaf === undefined) {\n return false;\n }\n\n // Check for NaN in CBOR simple types\n if (\"type\" in leaf && leaf.type === 7) {\n return isNaN(leaf as unknown as Parameters<typeof isNaN>[0]);\n }\n return false;\n};\n\n/// Implementation of isSubjectNaN()\nEnvelope.prototype.isSubjectNaN = function (this: Envelope): boolean {\n return this.subject().isNaN();\n};\n\n/// Implementation of isNull()\nEnvelope.prototype.isNull = function (this: Envelope): boolean {\n try {\n this.extractNull();\n return true;\n } catch (_error) {\n return false;\n }\n};\n\n/// Implementation of tryByteString()\nEnvelope.prototype.tryByteString = function (this: Envelope): Uint8Array {\n return this.extractBytes();\n};\n\n/// Implementation of asByteString()\nEnvelope.prototype.asByteString = function (this: Envelope): Uint8Array | undefined {\n try {\n return this.extractBytes();\n } catch {\n return undefined;\n }\n};\n\n/// Implementation of asArray()\nEnvelope.prototype.asArray = function (this: Envelope): readonly Cbor[] | undefined {\n const leaf = this.asLeaf();\n if (leaf === undefined) {\n return undefined;\n }\n\n return asArray(leaf);\n};\n\n/// Implementation of asMap()\nEnvelope.prototype.asMap = function (this: Envelope) {\n const leaf = this.asLeaf();\n if (leaf === undefined) {\n return undefined;\n }\n\n return asMap(leaf);\n};\n\n/// Implementation of asText()\nEnvelope.prototype.asText = function (this: Envelope): string | undefined {\n const leaf = this.asLeaf();\n if (leaf === undefined) {\n return undefined;\n }\n\n return asText(leaf);\n};\n\n/// Implementation of asLeaf()\nEnvelope.prototype.asLeaf = function (this: Envelope): Cbor | undefined {\n const c = this.case();\n if (c.type === \"leaf\") {\n return c.cbor;\n }\n return undefined;\n};\n","// Cbor type available if needed later\nimport { Envelope } from \"./envelope\";\nimport type { EnvelopeEncodableValue } from \"./envelope-encodable\";\nimport { EnvelopeError } from \"./error\";\n\n/// Provides methods for querying envelope structure and extracting data.\n///\n/// The `queries` module contains methods for:\n///\n/// 1. **Structural queries**: Methods for examining the envelope's structure\n/// (`subject()`, `assertions()`)\n/// 2. **Type queries**: Methods for determining the envelope's type\n/// (`isLeaf()`, `isNode()`, etc.)\n/// 3. **Content extraction**: Methods for extracting typed content from\n/// envelopes (`extractSubject()`, `extractObjectForPredicate()`)\n/// 4. **Assertion queries**: Methods for finding assertions with specific\n/// predicates (`assertionWithPredicate()`)\n///\n/// These methods enable traversal and inspection of envelope hierarchies,\n/// allowing for flexible manipulation and access to envelope data structures.\n\ndeclare module \"./envelope\" {\n interface Envelope {\n /// Returns true if the envelope has at least one assertion.\n ///\n /// @returns `true` if there are assertions, `false` otherwise\n hasAssertions(): boolean;\n\n /// Returns the envelope as an assertion if it is one.\n ///\n /// @returns The assertion envelope or undefined\n asAssertion(): Envelope | undefined;\n\n /// Returns the envelope as an assertion or throws an error.\n ///\n /// @returns The assertion envelope\n /// @throws {EnvelopeError} If the envelope is not an assertion\n tryAssertion(): Envelope;\n\n /// Returns the predicate of this assertion envelope.\n ///\n /// @returns The predicate envelope or undefined\n asPredicate(): Envelope | undefined;\n\n /// Returns the predicate of this assertion envelope or throws an error.\n ///\n /// @returns The predicate envelope\n /// @throws {EnvelopeError} If the envelope is not an assertion\n tryPredicate(): Envelope;\n\n /// Returns the object of this assertion envelope.\n ///\n /// @returns The object envelope or undefined\n asObject(): Envelope | undefined;\n\n /// Returns the object of this assertion envelope or throws an error.\n ///\n /// @returns The object envelope\n /// @throws {EnvelopeError} If the envelope is not an assertion\n tryObject(): Envelope;\n\n /// Checks if this envelope is case Assertion.\n ///\n /// @returns `true` if this is an assertion envelope\n isAssertion(): boolean;\n\n /// Checks if this envelope is case Elided.\n ///\n /// @returns `true` if this is an elided envelope\n isElided(): boolean;\n\n /// Checks if this envelope is case Leaf.\n ///\n /// @returns `true` if this is a leaf envelope\n isLeaf(): boolean;\n\n /// Checks if this envelope is case Node.\n ///\n /// @returns `true` if this is a node envelope\n isNode(): boolean;\n\n /// Checks if this envelope is case Wrapped.\n ///\n /// @returns `true` if this is a wrapped envelope\n isWrapped(): boolean;\n\n /// Checks if this envelope is internal (has child elements).\n ///\n /// Internal elements include node, wrapped, and assertion.\n ///\n /// @returns `true` if this envelope has children\n isInternal(): boolean;\n\n /// Checks if this envelope is obscured (elided, encrypted, or compressed).\n ///\n /// @returns `true` if this envelope is obscured\n isObscured(): boolean;\n\n /// Returns all assertions with the given predicate.\n ///\n /// Match is performed by comparing digests.\n ///\n /// @param predicate - The predicate to search for\n /// @returns An array of matching assertion envelopes\n assertionsWithPredicate(predicate: EnvelopeEncodableValue): Envelope[];\n\n /// Returns the assertion with the given predicate.\n ///\n /// @param predicate - The predicate to search for\n /// @returns The matching assertion envelope\n /// @throws {EnvelopeError} If no assertion or multiple assertions match\n assertionWithPredicate(predicate: EnvelopeEncodableValue): Envelope;\n\n /// Returns the assertion with the given predicate, or undefined if not\n /// found.\n ///\n /// @param predicate - The predicate to search for\n /// @returns The matching assertion envelope or undefined\n /// @throws {EnvelopeError} If multiple assertions match\n optionalAssertionWithPredicate(predicate: EnvelopeEncodableValue): Envelope | undefined;\n\n /// Returns the object of the assertion with the given predicate.\n ///\n /// @param predicate - The predicate to search for\n /// @returns The object envelope\n /// @throws {EnvelopeError} If no assertion or multiple assertions match\n objectForPredicate(predicate: EnvelopeEncodableValue): Envelope;\n\n /// Returns the object of the assertion with the given predicate, or\n /// undefined if not found.\n ///\n /// @param predicate - The predicate to search for\n /// @returns The object envelope or undefined\n /// @throws {EnvelopeError} If multiple assertions match\n optionalObjectForPredicate(predicate: EnvelopeEncodableValue): Envelope | undefined;\n\n /// Returns the objects of all assertions with the matching predicate.\n ///\n /// @param predicate - The predicate to search for\n /// @returns An array of object envelopes\n objectsForPredicate(predicate: EnvelopeEncodableValue): Envelope[];\n\n /// Returns the number of structural elements in the envelope.\n ///\n /// This includes the envelope itself and all nested elements.\n ///\n /// @returns The total element count\n elementsCount(): number;\n }\n}\n\n/// Implementation of hasAssertions()\nEnvelope.prototype.hasAssertions = function (this: Envelope): boolean {\n const c = this.case();\n return c.type === \"node\" && c.assertions.length > 0;\n};\n\n/// Implementation of asAssertion()\nEnvelope.prototype.asAssertion = function (this: Envelope): Envelope | undefined {\n const c = this.case();\n return c.type === \"assertion\" ? this : undefined;\n};\n\n/// Implementation of tryAssertion()\nEnvelope.prototype.tryAssertion = function (this: Envelope): Envelope {\n const result = this.asAssertion();\n if (result === undefined) {\n throw EnvelopeError.notAssertion();\n }\n return result;\n};\n\n/// Implementation of asPredicate()\nEnvelope.prototype.asPredicate = function (this: Envelope): Envelope | undefined {\n // Refer to subject in case the assertion is a node and therefore has\n // its own assertions\n const subj = this.subject();\n const c = subj.case();\n if (c.type === \"assertion\") {\n return c.assertion.predicate();\n }\n return undefined;\n};\n\n/// Implementation of tryPredicate()\nEnvelope.prototype.tryPredicate = function (this: Envelope): Envelope {\n const result = this.asPredicate();\n if (result === undefined) {\n throw EnvelopeError.notAssertion();\n }\n return result;\n};\n\n/// Implementation of asObject()\nEnvelope.prototype.asObject = function (this: Envelope): Envelope | undefined {\n // Refer to subject in case the assertion is a node and therefore has\n // its own assertions\n const subj = this.subject();\n const c = subj.case();\n if (c.type === \"assertion\") {\n return c.assertion.object();\n }\n return undefined;\n};\n\n/// Implementation of tryObject()\nEnvelope.prototype.tryObject = function (this: Envelope): Envelope {\n const result = this.asObject();\n if (result === undefined) {\n throw EnvelopeError.notAssertion();\n }\n return result;\n};\n\n/// Implementation of isAssertion()\nEnvelope.prototype.isAssertion = function (this: Envelope): boolean {\n return this.case().type === \"assertion\";\n};\n\n/// Implementation of isElided()\nEnvelope.prototype.isElided = function (this: Envelope): boolean {\n return this.case().type === \"elided\";\n};\n\n/// Implementation of isLeaf()\nEnvelope.prototype.isLeaf = function (this: Envelope): boolean {\n return this.case().type === \"leaf\";\n};\n\n/// Implementation of isNode()\nEnvelope.prototype.isNode = function (this: Envelope): boolean {\n return this.case().type === \"node\";\n};\n\n/// Implementation of isWrapped()\nEnvelope.prototype.isWrapped = function (this: Envelope): boolean {\n return this.case().type === \"wrapped\";\n};\n\n/// Implementation of isInternal()\nEnvelope.prototype.isInternal = function (this: Envelope): boolean {\n const type = this.case().type;\n return type === \"node\" || type === \"wrapped\" || type === \"assertion\";\n};\n\n/// Implementation of isObscured()\nEnvelope.prototype.isObscured = function (this: Envelope): boolean {\n const type = this.case().type;\n return type === \"elided\" || type === \"encrypted\" || type === \"compressed\";\n};\n\n/// Implementation of assertionsWithPredicate()\nEnvelope.prototype.assertionsWithPredicate = function (\n this: Envelope,\n predicate: EnvelopeEncodableValue,\n): Envelope[] {\n const predicateEnv = Envelope.new(predicate);\n const predicateDigest = predicateEnv.digest();\n\n return this.assertions().filter((assertion) => {\n const pred = assertion.subject().asPredicate();\n return pred?.digest().equals(predicateDigest) === true;\n });\n};\n\n/// Implementation of assertionWithPredicate()\nEnvelope.prototype.assertionWithPredicate = function (\n this: Envelope,\n predicate: EnvelopeEncodableValue,\n): Envelope {\n const matches = this.assertionsWithPredicate(predicate);\n\n if (matches.length === 0) {\n throw EnvelopeError.nonexistentPredicate();\n }\n if (matches.length > 1) {\n throw EnvelopeError.ambiguousPredicate();\n }\n\n return matches[0];\n};\n\n/// Implementation of optionalAssertionWithPredicate()\nEnvelope.prototype.optionalAssertionWithPredicate = function (\n this: Envelope,\n predicate: EnvelopeEncodableValue,\n): Envelope | undefined {\n const matches = this.assertionsWithPredicate(predicate);\n\n if (matches.length === 0) {\n return undefined;\n }\n if (matches.length > 1) {\n throw EnvelopeError.ambiguousPredicate();\n }\n\n return matches[0];\n};\n\n/// Implementation of objectForPredicate()\nEnvelope.prototype.objectForPredicate = function (\n this: Envelope,\n predicate: EnvelopeEncodableValue,\n): Envelope {\n const assertion = this.assertionWithPredicate(predicate);\n const obj = assertion.asObject();\n if (obj === undefined) {\n throw EnvelopeError.notAssertion();\n }\n return obj;\n};\n\n/// Implementation of optionalObjectForPredicate()\nEnvelope.prototype.optionalObjectForPredicate = function (\n this: Envelope,\n predicate: EnvelopeEncodableValue,\n): Envelope | undefined {\n const matches = this.assertionsWithPredicate(predicate);\n\n if (matches.length === 0) {\n return undefined;\n }\n if (matches.length > 1) {\n throw EnvelopeError.ambiguousPredicate();\n }\n\n const obj = matches[0].subject().asObject();\n return obj;\n};\n\n/// Implementation of objectsForPredicate()\nEnvelope.prototype.objectsForPredicate = function (\n this: Envelope,\n predicate: EnvelopeEncodableValue,\n): Envelope[] {\n return this.assertionsWithPredicate(predicate).map((assertion) => {\n const obj = assertion.asObject();\n if (obj === undefined) {\n throw EnvelopeError.notAssertion();\n }\n return obj;\n });\n};\n\n/// Implementation of elementsCount()\nEnvelope.prototype.elementsCount = function (this: Envelope): number {\n let count = 1; // Count this envelope\n\n const c = this.case();\n switch (c.type) {\n case \"node\":\n count += c.subject.elementsCount();\n for (const assertion of c.assertions) {\n count += assertion.elementsCount();\n }\n break;\n case \"assertion\":\n count += c.assertion.predicate().elementsCount();\n count += c.assertion.object().elementsCount();\n break;\n case \"wrapped\":\n count += c.envelope.elementsCount();\n break;\n case \"leaf\":\n case \"elided\":\n case \"knownValue\":\n case \"encrypted\":\n case \"compressed\":\n // These cases don't contribute additional elements\n break;\n }\n\n return count;\n};\n","import { Envelope } from \"./envelope\";\nimport { EnvelopeError } from \"./error\";\n\n/// Support for wrapping and unwrapping envelopes.\n///\n/// Wrapping allows treating an envelope (including its assertions) as a single\n/// unit, making it possible to add assertions about the envelope as a whole.\n\ndeclare module \"./envelope\" {\n interface Envelope {\n /// Returns a new envelope which wraps the current envelope.\n ///\n /// Wrapping an envelope allows you to treat an envelope (including its\n /// assertions) as a single unit, making it possible to add assertions\n /// about the envelope as a whole.\n ///\n /// @returns A new wrapped envelope\n ///\n /// @example\n /// ```typescript\n /// // Create an envelope with an assertion\n /// const envelope = Envelope.new(\"Hello.\").addAssertion(\"language\", \"English\");\n ///\n /// // Wrap it to add an assertion about the envelope as a whole\n /// const wrapped = envelope.wrap().addAssertion(\"authenticated\", true);\n /// ```\n wrap(): Envelope;\n\n /// Unwraps and returns the inner envelope.\n ///\n /// This extracts the envelope contained within a wrapped envelope.\n ///\n /// @returns The unwrapped envelope\n /// @throws {EnvelopeError} If this is not a wrapped envelope\n ///\n /// @example\n /// ```typescript\n /// // Create an envelope and wrap it\n /// const envelope = Envelope.new(\"Hello.\");\n /// const wrapped = envelope.wrap();\n ///\n /// // Unwrap to get the original envelope\n /// const unwrapped = wrapped.tryUnwrap();\n /// ```\n tryUnwrap(): Envelope;\n\n /// Alias for tryUnwrap() - unwraps and returns the inner envelope.\n ///\n /// @returns The unwrapped envelope\n /// @throws {EnvelopeError} If this is not a wrapped envelope\n unwrap(): Envelope;\n }\n}\n\n/// Implementation of wrap()\nEnvelope.prototype.wrap = function (this: Envelope): Envelope {\n return Envelope.newWrapped(this);\n};\n\n/// Implementation of tryUnwrap()\nEnvelope.prototype.tryUnwrap = function (this: Envelope): Envelope {\n const c = this.subject().case();\n if (c.type === \"wrapped\") {\n return c.envelope;\n }\n throw EnvelopeError.notWrapped();\n};\n\n/// Implementation of unwrap() - alias for tryUnwrap()\nEnvelope.prototype.unwrap = function (this: Envelope): Envelope {\n return this.tryUnwrap();\n};\n","import { Envelope } from \"../base/envelope\";\nimport { type EnvelopeEncodableValue } from \"../base/envelope-encodable\";\nimport { EnvelopeError } from \"../base/error\";\n\n/// Type system for Gordian Envelopes.\n///\n/// This module provides functionality for adding, querying, and verifying types\n/// within envelopes. In Gordian Envelope, types are implemented using the\n/// special `'isA'` predicate (the string \"isA\"), which is semantically\n/// equivalent to the RDF `rdf:type` concept.\n///\n/// Type information enables:\n/// - Semantic classification of envelopes\n/// - Type verification before processing content\n/// - Conversion between domain objects and envelopes\n/// - Schema validation\n///\n/// ## Type Representation\n///\n/// Types are represented as assertions with the `'isA'` predicate and an object\n/// that specifies the type. The type object is typically a string or an envelope.\n///\n/// ## Usage Patterns\n///\n/// The type system is commonly used in two ways:\n///\n/// 1. **Type Tagging**: Adding type information to envelopes to indicate their\n/// semantic meaning\n///\n/// ```typescript\n/// // Create an envelope representing a person\n/// const person = Envelope.new(\"Alice\")\n/// .addType(\"Person\")\n/// .addAssertion(\"age\", 30);\n/// ```\n///\n/// 2. **Type Checking**: Verifying that an envelope has the expected type\n/// before processing\n///\n/// ```typescript\n/// function processPerson(envelope: Envelope): void {\n/// // Verify this is a person before processing\n/// envelope.checkType(\"Person\");\n///\n/// // Now we can safely extract person-specific information\n/// const name = envelope.subject().extractString();\n/// const age = envelope.objectForPredicate(\"age\").extractNumber();\n///\n/// console.log(`${name} is ${age} years old`);\n/// }\n/// ```\n\n/// The standard predicate for type assertions\nexport const IS_A = \"isA\";\n\ndeclare module \"../base/envelope\" {\n interface Envelope {\n /// Adds a type assertion to the envelope using the `'isA'` predicate.\n ///\n /// This method provides a convenient way to declare the type of an envelope\n /// using the standard `'isA'` predicate. The type can be any value that can\n /// be converted to an envelope, typically a string.\n ///\n /// @param object - The type to assign to this envelope\n /// @returns A new envelope with the type assertion added\n ///\n /// @example\n /// ```typescript\n /// // Create a document and declare its type\n /// const document = Envelope.new(\"Important Content\").addType(\"Document\");\n ///\n /// // Verify the type was added\n /// assert(document.hasType(\"Document\"));\n /// ```\n addType(object: EnvelopeEncodableValue): Envelope;\n\n /// Returns all type objects from the envelope's `'isA'` assertions.\n ///\n /// This method retrieves all objects of assertions that use the `'isA'`\n /// predicate. Each returned envelope represents a type that has been\n /// assigned to this envelope.\n ///\n /// @returns An array of envelopes, each representing a type assigned to\n /// this envelope\n ///\n /// @example\n /// ```typescript\n /// // Create an envelope with multiple types\n /// const multiTyped = Envelope.new(\"Versatile Entity\")\n /// .addType(\"Person\")\n /// .addType(\"Employee\")\n /// .addType(\"Manager\");\n ///\n /// // Get all the type objects\n /// const types = multiTyped.types();\n ///\n /// // There should be 3 types\n /// console.log(types.length); // 3\n /// ```\n types(): Envelope[];\n\n /// Gets a single type object from the envelope's `'isA'` assertions.\n ///\n /// This method is useful when an envelope is expected to have exactly one\n /// type. It throws an error if the envelope has zero or multiple types.\n ///\n /// @returns The single type object if exactly one exists\n /// @throws {EnvelopeError} If multiple types exist or no types exist\n ///\n /// @example\n /// ```typescript\n /// // Create an envelope with a single type\n /// const person = Envelope.new(\"Alice\").addType(\"Person\");\n ///\n /// // Get the type\n /// const typeObj = person.getType();\n /// const typeString = typeObj.extractString();\n /// console.log(typeString); // \"Person\"\n /// ```\n getType(): Envelope;\n\n /// Checks if the envelope has a specific type, using an envelope as the\n /// type identifier.\n ///\n /// This method compares the digest of each type object with the digest of\n /// the provided value to determine if the envelope has the specified type.\n ///\n /// @param t - The type to check for, which will be converted to an envelope\n /// @returns `true` if the envelope has the specified type, `false`\n /// otherwise\n ///\n /// @example\n /// ```typescript\n /// // Create a typed envelope\n /// const document = Envelope.new(\"Contract\")\n /// .addType(\"LegalDocument\")\n /// .addAssertion(\"status\", \"Draft\");\n ///\n /// // Check for various types\n /// console.log(document.hasType(\"LegalDocument\")); // true\n /// console.log(document.hasType(\"Spreadsheet\")); // false\n /// ```\n hasType(t: EnvelopeEncodableValue): boolean;\n\n /// Verifies that the envelope has a specific type.\n ///\n /// This method is similar to `hasType` but throws an error instead of\n /// returning false, making it suitable for use in validation chains.\n ///\n /// @param t - The type to check for, which will be converted to an envelope\n /// @throws {EnvelopeError} If the envelope does not have the specified type\n ///\n /// @example\n /// ```typescript\n /// // Function that processes a person\n /// function processPerson(envelope: Envelope): string {\n /// // Verify this is a person\n /// envelope.checkType(\"Person\");\n ///\n /// // Extract the name\n /// const name = envelope.subject().extractString();\n /// return name;\n /// }\n ///\n /// // Create a person envelope\n /// const person = Envelope.new(\"Alice\").addType(\"Person\");\n ///\n /// // Process the person\n /// const result = processPerson(person);\n /// console.log(result); // \"Alice\"\n ///\n /// // Create a non-person envelope\n /// const document = Envelope.new(\"Contract\").addType(\"Document\");\n ///\n /// // Processing will throw an error\n /// try {\n /// processPerson(document);\n /// } catch (e) {\n /// console.log(\"Not a person!\");\n /// }\n /// ```\n checkType(t: EnvelopeEncodableValue): void;\n }\n}\n\n/// Implementation of addType()\n// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions\nif (Envelope?.prototype) {\n Envelope.prototype.addType = function (this: Envelope, object: EnvelopeEncodableValue): Envelope {\n return this.addAssertion(IS_A, object);\n };\n\n /// Implementation of types()\n Envelope.prototype.types = function (this: Envelope): Envelope[] {\n return this.objectsForPredicate(IS_A);\n };\n\n /// Implementation of getType()\n Envelope.prototype.getType = function (this: Envelope): Envelope {\n const t = this.types();\n if (t.length === 0) {\n throw EnvelopeError.invalidType();\n }\n if (t.length === 1) {\n return t[0];\n }\n throw EnvelopeError.ambiguousType();\n };\n\n /// Implementation of hasType()\n Envelope.prototype.hasType = function (this: Envelope, t: EnvelopeEncodableValue): boolean {\n const e = Envelope.new(t);\n return this.types().some((x) => x.digest().equals(e.digest()));\n };\n\n /// Implementation of checkType()\n Envelope.prototype.checkType = function (this: Envelope, t: EnvelopeEncodableValue): void {\n if (!this.hasType(t)) {\n throw EnvelopeError.invalidType();\n }\n };\n}\n","import { Envelope } from \"../base/envelope\";\nimport { EnvelopeError } from \"../base/error\";\nimport {\n SecureRandomNumberGenerator,\n rngRandomData,\n rngNextInClosedRangeI32,\n type RandomNumberGenerator,\n} from \"@bcts/rand\";\n\n/// Extension for adding salt to envelopes to prevent correlation.\n///\n/// This module provides functionality for decorrelating envelopes by adding\n/// random salt. Salt is added as an assertion with the predicate 'salt' and\n/// a random value. When an envelope is elided, this salt ensures that the\n/// digest of the elided envelope cannot be correlated with other elided\n/// envelopes containing the same information.\n///\n/// Decorrelation is an important privacy feature that prevents third parties\n/// from determining whether two elided envelopes originally contained the same\n/// information by comparing their digests.\n///\n/// Based on bc-envelope-rust/src/extension/salt.rs and bc-components-rust/src/salt.rs\n///\n/// @example\n/// ```typescript\n/// // Create a simple envelope\n/// const envelope = Envelope.new(\"Hello\");\n///\n/// // Create a decorrelated version by adding salt\n/// const salted = envelope.addSalt();\n///\n/// // The salted envelope has a different digest than the original\n/// console.log(envelope.digest().equals(salted.digest())); // false\n/// ```\n\n/// The standard predicate for salt assertions\nexport const SALT = \"salt\";\n\n/// Minimum salt size in bytes (64 bits)\nconst MIN_SALT_SIZE = 8;\n\n/// Creates a new SecureRandomNumberGenerator instance\nfunction createSecureRng(): RandomNumberGenerator {\n return new SecureRandomNumberGenerator();\n}\n\n/// Generates random bytes using the rand package\nfunction generateRandomBytes(length: number, rng?: RandomNumberGenerator): Uint8Array {\n const actualRng = rng ?? createSecureRng();\n return rngRandomData(actualRng, length);\n}\n\n/// Calculates salt size proportional to envelope size\n/// This matches the Rust implementation in bc-components-rust/src/salt.rs\nfunction calculateProportionalSaltSize(envelopeSize: number, rng?: RandomNumberGenerator): number {\n const actualRng = rng ?? createSecureRng();\n const count = envelopeSize;\n const minSize = Math.max(8, Math.ceil(count * 0.05));\n const maxSize = Math.max(minSize + 8, Math.ceil(count * 0.25));\n return rngNextInClosedRangeI32(actualRng, minSize, maxSize);\n}\n\ndeclare module \"../base/envelope\" {\n interface Envelope {\n /// Adds a proportionally-sized salt assertion to decorrelate the envelope.\n ///\n /// This method adds random salt bytes as an assertion to the envelope. The\n /// size of the salt is proportional to the size of the envelope being\n /// salted:\n /// - For small envelopes: 8-16 bytes\n /// - For larger envelopes: 5-25% of the envelope's size\n ///\n /// Salt is added as an assertion with the predicate 'salt' and an object\n /// containing random bytes. This changes the digest of the envelope while\n /// preserving its semantic content, making it impossible to correlate with\n /// other envelopes containing the same information.\n ///\n /// @returns A new envelope with the salt assertion added\n ///\n /// @example\n /// ```typescript\n /// // Create an envelope with personally identifiable information\n /// const alice = Envelope.new(\"Alice\")\n /// .addAssertion(\"email\", \"alice@example.com\")\n /// .addAssertion(\"ssn\", \"123-45-6789\");\n ///\n /// // Create a second envelope with the same information\n /// const alice2 = Envelope.new(\"Alice\")\n /// .addAssertion(\"email\", \"alice@example.com\")\n /// .addAssertion(\"ssn\", \"123-45-6789\");\n ///\n /// // The envelopes have the same digest\n /// console.log(alice.digest().equals(alice2.digest())); // true\n ///\n /// // Add salt to both envelopes\n /// const aliceSalted = alice.addSalt();\n /// const alice2Salted = alice2.addSalt();\n ///\n /// // Now the envelopes have different digests, preventing correlation\n /// console.log(aliceSalted.digest().equals(alice2Salted.digest())); // false\n /// ```\n addSalt(): Envelope;\n\n /// Adds salt of a specific byte length to the envelope.\n ///\n /// This method adds salt of a specified number of bytes to decorrelate the\n /// envelope. It requires that the byte count be at least 8 bytes (64 bits)\n /// to ensure sufficient entropy for effective decorrelation.\n ///\n /// @param count - The exact number of salt bytes to add\n /// @returns A new envelope with salt added\n /// @throws {EnvelopeError} If the byte count is less than 8\n ///\n /// @example\n /// ```typescript\n /// const envelope = Envelope.new(\"Hello\");\n ///\n /// // Add exactly 16 bytes of salt\n /// const salted = envelope.addSaltWithLength(16);\n ///\n /// // Trying to add less than 8 bytes will throw an error\n /// try {\n /// envelope.addSaltWithLength(7);\n /// } catch (e) {\n /// console.log(\"Error: salt must be at least 8 bytes\");\n /// }\n /// ```\n addSaltWithLength(count: number): Envelope;\n\n /// Adds the given salt bytes as an assertion to the envelope.\n ///\n /// This method attaches specific salt bytes as an assertion to the\n /// envelope, using 'salt' as the predicate. This is useful when you need\n /// to control the specific salt content being added.\n ///\n /// @param saltBytes - A Uint8Array containing salt bytes\n /// @returns A new envelope with the salt assertion added\n ///\n /// @example\n /// ```typescript\n /// // Create salt with specific bytes\n /// const salt = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8]);\n ///\n /// // Add this specific salt to an envelope\n /// const envelope = Envelope.new(\"Hello\");\n /// const salted = envelope.addSaltBytes(salt);\n /// ```\n addSaltBytes(saltBytes: Uint8Array): Envelope;\n\n /// Adds salt with a byte length randomly chosen from the given range.\n ///\n /// This method adds salt with a length randomly selected from the specified\n /// range to decorrelate the envelope. This provides additional\n /// decorrelation by varying the size of the salt itself.\n ///\n /// @param min - Minimum number of salt bytes (must be at least 8)\n /// @param max - Maximum number of salt bytes\n /// @returns A new envelope with salt added\n /// @throws {EnvelopeError} If min is less than 8 or max is less than min\n ///\n /// @example\n /// ```typescript\n /// const envelope = Envelope.new(\"Hello\");\n ///\n /// // Add salt with a length randomly chosen between 16 and 32 bytes\n /// const salted = envelope.addSaltInRange(16, 32);\n /// ```\n addSaltInRange(min: number, max: number): Envelope;\n }\n}\n\n/// Implementation of addSalt()\n// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions\nif (Envelope?.prototype) {\n Envelope.prototype.addSalt = function (this: Envelope): Envelope {\n const rng = createSecureRng();\n const envelopeSize = this.cborBytes().length;\n const saltSize = calculateProportionalSaltSize(envelopeSize, rng);\n const saltBytes = generateRandomBytes(saltSize, rng);\n return this.addAssertion(SALT, saltBytes);\n };\n\n /// Implementation of addSaltWithLength()\n Envelope.prototype.addSaltWithLength = function (this: Envelope, count: number): Envelope {\n if (count < MIN_SALT_SIZE) {\n throw EnvelopeError.general(`Salt must be at least ${MIN_SALT_SIZE} bytes, got ${count}`);\n }\n const saltBytes = generateRandomBytes(count);\n return this.addAssertion(SALT, saltBytes);\n };\n\n /// Implementation of addSaltBytes()\n Envelope.prototype.addSaltBytes = function (this: Envelope, saltBytes: Uint8Array): Envelope {\n if (saltBytes.length < MIN_SALT_SIZE) {\n throw EnvelopeError.general(\n `Salt must be at least ${MIN_SALT_SIZE} bytes, got ${saltBytes.length}`,\n );\n }\n return this.addAssertion(SALT, saltBytes);\n };\n\n /// Implementation of addSaltInRange()\n Envelope.prototype.addSaltInRange = function (\n this: Envelope,\n min: number,\n max: number,\n ): Envelope {\n if (min < MIN_SALT_SIZE) {\n throw EnvelopeError.general(\n `Minimum salt size must be at least ${MIN_SALT_SIZE} bytes, got ${min}`,\n );\n }\n if (max < min) {\n throw EnvelopeError.general(\n `Maximum salt size must be at least minimum, got min=${min} max=${max}`,\n );\n }\n const rng = createSecureRng();\n const saltSize = rngNextInClosedRangeI32(rng, min, max);\n const saltBytes = generateRandomBytes(saltSize, rng);\n return this.addAssertion(SALT, saltBytes);\n };\n}\n","/**\n * Signature Extension for Gordian Envelope\n *\n * Provides functionality for digitally signing Envelopes and verifying signatures,\n * with optional metadata support.\n *\n * The signature extension allows:\n * - Signing envelope subjects to validate their authenticity\n * - Adding metadata to signatures (e.g., signer identity, date, purpose)\n * - Verification of signatures, both with and without metadata\n * - Support for multiple signatures on a single envelope\n */\n\nimport { Envelope } from \"../base/envelope\";\nimport { EnvelopeError } from \"../base/error\";\nimport {\n ecdsaSign,\n ecdsaVerify,\n ecdsaPublicKeyFromPrivateKey,\n ECDSA_PRIVATE_KEY_SIZE,\n ECDSA_PUBLIC_KEY_SIZE,\n ECDSA_UNCOMPRESSED_PUBLIC_KEY_SIZE,\n} from \"@bcts/crypto\";\nimport { SecureRandomNumberGenerator, rngRandomData } from \"@bcts/rand\";\n\n/**\n * Known value for the 'signed' predicate.\n * This is the standard predicate used for signature assertions.\n */\nexport const SIGNED = \"signed\";\n\n/**\n * Known value for the 'verifiedBy' predicate.\n * Used to indicate verification status.\n */\nexport const VERIFIED_BY = \"verifiedBy\";\n\n/**\n * Known value for the 'note' predicate.\n * Used for adding notes/comments to signatures.\n */\nexport const NOTE = \"note\";\n\n/**\n * Represents a cryptographic signature.\n */\nexport class Signature {\n readonly #data: Uint8Array;\n\n constructor(data: Uint8Array) {\n this.#data = data;\n }\n\n /**\n * Returns the raw signature bytes.\n */\n data(): Uint8Array {\n return this.#data;\n }\n\n /**\n * Returns the hex-encoded signature.\n */\n hex(): string {\n return Array.from(this.#data)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n }\n\n /**\n * Creates a Signature from hex string.\n */\n static fromHex(hex: string): Signature {\n const bytes = new Uint8Array(hex.length / 2);\n for (let i = 0; i < hex.length; i += 2) {\n bytes[i / 2] = parseInt(hex.substr(i, 2), 16);\n }\n return new Signature(bytes);\n }\n}\n\n/**\n * Interface for types that can sign data.\n */\nexport interface Signer {\n /**\n * Signs the provided data and returns a Signature.\n */\n sign(data: Uint8Array): Signature;\n}\n\n/**\n * Interface for types that can verify signatures.\n */\nexport interface Verifier {\n /**\n * Verifies a signature against the provided data.\n * Returns true if the signature is valid.\n */\n verify(data: Uint8Array, signature: Signature): boolean;\n}\n\n/**\n * ECDSA signing key using secp256k1 curve.\n * Uses @bcts/crypto functions.\n */\nexport class SigningPrivateKey implements Signer {\n readonly #privateKey: Uint8Array;\n\n constructor(privateKey: Uint8Array) {\n if (privateKey.length !== ECDSA_PRIVATE_KEY_SIZE) {\n throw new Error(`Private key must be ${ECDSA_PRIVATE_KEY_SIZE} bytes`);\n }\n this.#privateKey = privateKey;\n }\n\n /**\n * Generates a new random private key.\n */\n static generate(): SigningPrivateKey {\n const rng = new SecureRandomNumberGenerator();\n const privateKey = rngRandomData(rng, ECDSA_PRIVATE_KEY_SIZE);\n return new SigningPrivateKey(privateKey);\n }\n\n /**\n * Creates a private key from hex string.\n */\n static fromHex(hex: string): SigningPrivateKey {\n const bytes = new Uint8Array(hex.length / 2);\n for (let i = 0; i < hex.length; i += 2) {\n bytes[i / 2] = parseInt(hex.substr(i, 2), 16);\n }\n return new SigningPrivateKey(bytes);\n }\n\n /**\n * Returns the corresponding public key.\n */\n publicKey(): SigningPublicKey {\n const publicKey = ecdsaPublicKeyFromPrivateKey(this.#privateKey);\n return new SigningPublicKey(publicKey);\n }\n\n /**\n * Signs data and returns a Signature.\n */\n sign(data: Uint8Array): Signature {\n const signatureBytes = ecdsaSign(this.#privateKey, data);\n return new Signature(signatureBytes);\n }\n\n /**\n * Returns the raw private key bytes.\n */\n data(): Uint8Array {\n return this.#privateKey;\n }\n}\n\n/**\n * ECDSA public key for signature verification using secp256k1 curve.\n * Uses @bcts/crypto functions.\n */\nexport class SigningPublicKey implements Verifier {\n readonly #publicKey: Uint8Array;\n\n constructor(publicKey: Uint8Array) {\n if (\n publicKey.length !== ECDSA_PUBLIC_KEY_SIZE &&\n publicKey.length !== ECDSA_UNCOMPRESSED_PUBLIC_KEY_SIZE\n ) {\n throw new Error(\n `Public key must be ${ECDSA_PUBLIC_KEY_SIZE} bytes (compressed) or ${ECDSA_UNCOMPRESSED_PUBLIC_KEY_SIZE} bytes (uncompressed)`,\n );\n }\n this.#publicKey = publicKey;\n }\n\n /**\n * Creates a public key from hex string.\n */\n static fromHex(hex: string): SigningPublicKey {\n const bytes = new Uint8Array(hex.length / 2);\n for (let i = 0; i < hex.length; i += 2) {\n bytes[i / 2] = parseInt(hex.substr(i, 2), 16);\n }\n return new SigningPublicKey(bytes);\n }\n\n /**\n * Verifies a signature against the provided data.\n */\n verify(data: Uint8Array, signature: Signature): boolean {\n try {\n return ecdsaVerify(this.#publicKey, signature.data(), data);\n } catch {\n return false;\n }\n }\n\n /**\n * Returns the raw public key bytes.\n */\n data(): Uint8Array {\n return this.#publicKey;\n }\n\n /**\n * Returns the hex-encoded public key.\n */\n hex(): string {\n return Array.from(this.#publicKey)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n }\n}\n\n/**\n * Metadata that can be attached to a signature.\n */\nexport class SignatureMetadata {\n readonly #assertions: [string, unknown][] = [];\n\n /**\n * Adds an assertion to the metadata.\n */\n withAssertion(predicate: string, object: unknown): SignatureMetadata {\n const metadata = new SignatureMetadata();\n metadata.#assertions.push(...this.#assertions);\n metadata.#assertions.push([predicate, object]);\n return metadata;\n }\n\n /**\n * Returns all assertions in the metadata.\n */\n assertions(): [string, unknown][] {\n return this.#assertions;\n }\n\n /**\n * Returns true if this metadata has any assertions.\n */\n hasAssertions(): boolean {\n return this.#assertions.length > 0;\n }\n}\n\n/**\n * Support for signing envelopes and verifying signatures.\n */\ndeclare module \"../base/envelope\" {\n interface Envelope {\n /**\n * Creates a signature for the envelope's subject and returns a new\n * envelope with a 'signed': Signature assertion.\n *\n * @param signer - The signing key\n * @returns The signed envelope\n *\n * @example\n * ```typescript\n * const privateKey = SigningPrivateKey.generate();\n * const envelope = Envelope.new(\"Hello, world!\");\n * const signed = envelope.addSignature(privateKey);\n * ```\n */\n addSignature(signer: Signer): Envelope;\n\n /**\n * Creates a signature for the envelope's subject with optional metadata.\n *\n * @param signer - The signing key\n * @param metadata - Optional metadata to attach to the signature\n * @returns The signed envelope\n */\n addSignatureWithMetadata(signer: Signer, metadata?: SignatureMetadata): Envelope;\n\n /**\n * Creates multiple signatures for the envelope's subject.\n *\n * @param signers - Array of signing keys\n * @returns The envelope with multiple signatures\n */\n addSignatures(signers: Signer[]): Envelope;\n\n /**\n * Returns whether this envelope has a valid signature from the given verifier.\n *\n * @param verifier - The public key to verify against\n * @returns True if a valid signature from this verifier exists\n */\n hasSignatureFrom(verifier: Verifier): boolean;\n\n /**\n * Verifies that this envelope has a valid signature from the given verifier\n * and returns the envelope.\n *\n * @param verifier - The public key to verify against\n * @returns The verified envelope\n * @throws {EnvelopeError} If no valid signature is found\n */\n verifySignatureFrom(verifier: Verifier): Envelope;\n\n /**\n * Returns all signature assertions in this envelope.\n *\n * @returns Array of signature envelopes\n */\n signatures(): Envelope[];\n }\n}\n\n// Implementation\n// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions\nif (Envelope?.prototype) {\n Envelope.prototype.addSignature = function (this: Envelope, signer: Signer): Envelope {\n return this.addSignatureWithMetadata(signer, undefined);\n };\n\n Envelope.prototype.addSignatureWithMetadata = function (\n this: Envelope,\n signer: Signer,\n metadata?: SignatureMetadata,\n ): Envelope {\n const digest = this.subject().digest();\n const signature = signer.sign(digest.data());\n let signatureEnvelope = Envelope.new(signature.data());\n\n if (metadata?.hasAssertions() === true) {\n // Add metadata assertions to the signature\n for (const [predicate, object] of metadata.assertions()) {\n signatureEnvelope = signatureEnvelope.addAssertion(\n predicate,\n object as string | number | boolean,\n );\n }\n\n // Wrap the signature with metadata\n signatureEnvelope = signatureEnvelope.wrap();\n\n // Sign the wrapped envelope\n const outerSignature = signer.sign(signatureEnvelope.digest().data());\n signatureEnvelope = signatureEnvelope.addAssertion(SIGNED, outerSignature.data());\n }\n\n return this.addAssertion(SIGNED, signatureEnvelope);\n };\n\n Envelope.prototype.addSignatures = function (this: Envelope, signers: Signer[]): Envelope {\n return signers.reduce((envelope, signer) => envelope.addSignature(signer), this);\n };\n\n Envelope.prototype.hasSignatureFrom = function (this: Envelope, verifier: Verifier): boolean {\n const subjectDigest = this.subject().digest();\n const signatures = this.signatures();\n\n for (const sigEnvelope of signatures) {\n const c = sigEnvelope.case();\n\n if (c.type === \"leaf\") {\n // Simple signature - verify directly\n try {\n const sigData = sigEnvelope.asByteString();\n if (sigData !== undefined) {\n const signature = new Signature(sigData);\n if (verifier.verify(subjectDigest.data(), signature)) {\n return true;\n }\n }\n } catch {\n continue;\n }\n } else if (c.type === \"node\") {\n // Signature with metadata - it's a node with 'signed' assertion\n // The structure is: { wrapped_signature [signed: outer_signature] }\n // Check if this node has a 'signed' assertion\n const outerSigs = sigEnvelope.assertions().filter((a) => {\n const aC = a.case();\n if (aC.type === \"assertion\") {\n const pred = aC.assertion.predicate();\n try {\n return pred.asText() === SIGNED;\n } catch {\n return false;\n }\n }\n return false;\n });\n\n for (const outerSig of outerSigs) {\n const outerSigCase = outerSig.case();\n if (outerSigCase.type === \"assertion\") {\n const outerSigObj = outerSigCase.assertion.object();\n try {\n const outerSigData = outerSigObj.asByteString();\n if (outerSigData !== undefined) {\n const outerSignature = new Signature(outerSigData);\n\n // The subject of this node should be a wrapped envelope\n const nodeSubject = c.subject;\n const nodeSubjectCase = nodeSubject.case();\n\n // Verify outer signature against the wrapped envelope\n if (\n nodeSubjectCase.type === \"wrapped\" &&\n verifier.verify(nodeSubject.digest().data(), outerSignature)\n ) {\n // Now verify inner signature\n const wrapped = nodeSubjectCase.envelope;\n const innerSig = wrapped.subject();\n const innerSigData = innerSig.asByteString();\n if (innerSigData !== undefined) {\n const innerSignature = new Signature(innerSigData);\n if (verifier.verify(subjectDigest.data(), innerSignature)) {\n return true;\n }\n }\n }\n }\n } catch {\n continue;\n }\n }\n }\n }\n }\n\n return false;\n };\n\n Envelope.prototype.verifySignatureFrom = function (this: Envelope, verifier: Verifier): Envelope {\n if (this.hasSignatureFrom(verifier)) {\n return this;\n }\n throw EnvelopeError.general(\"No valid signature found from the given verifier\");\n };\n\n Envelope.prototype.signatures = function (this: Envelope): Envelope[] {\n const assertions = this.assertions();\n return assertions\n .filter((a) => {\n const c = a.case();\n if (c.type === \"assertion\") {\n const pred = c.assertion.predicate();\n try {\n return pred.asText() === SIGNED;\n } catch {\n return false;\n }\n }\n return false;\n })\n .map((a) => {\n const c = a.case();\n if (c.type === \"assertion\") {\n return c.assertion.object();\n }\n throw EnvelopeError.general(\"Invalid signature assertion\");\n });\n };\n}\n","/**\n * Attachment Extension for Gordian Envelope\n *\n * Provides functionality for attaching vendor-specific metadata to envelopes.\n * Attachments enable flexible, extensible data storage without modifying\n * the core data model, facilitating interoperability and future compatibility.\n *\n * Each attachment has:\n * - A payload (arbitrary data)\n * - A required vendor identifier (typically a reverse domain name)\n * - An optional conformsTo URI that indicates the format of the attachment\n *\n * See BCR-2023-006: https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2023-006-envelope-attachment.md\n */\n\nimport { Envelope } from \"../base/envelope\";\nimport { type Digest } from \"../base/digest\";\nimport { EnvelopeError } from \"../base/error\";\nimport type { EnvelopeEncodableValue } from \"../base/envelope-encodable\";\n\n/**\n * Known value for the 'attachment' predicate.\n */\nexport const ATTACHMENT = \"attachment\";\n\n/**\n * Known value for the 'vendor' predicate.\n */\nexport const VENDOR = \"vendor\";\n\n/**\n * Known value for the 'conformsTo' predicate.\n */\nexport const CONFORMS_TO = \"conformsTo\";\n\n/**\n * A container for vendor-specific metadata attachments.\n *\n * Attachments provides a flexible mechanism for attaching arbitrary metadata\n * to envelopes without modifying their core structure.\n */\nexport class Attachments {\n readonly #envelopes = new Map<string, Envelope>();\n\n /**\n * Creates a new empty attachments container.\n */\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n constructor() {}\n\n /**\n * Adds a new attachment with the specified payload and metadata.\n *\n * @param payload - The data to attach\n * @param vendor - A string identifying the entity that defined the attachment format\n * @param conformsTo - Optional URI identifying the structure the payload conforms to\n */\n add(payload: EnvelopeEncodableValue, vendor: string, conformsTo?: string): void {\n const attachment = Envelope.newAttachment(payload, vendor, conformsTo);\n this.#envelopes.set(attachment.digest().hex(), attachment);\n }\n\n /**\n * Retrieves an attachment by its digest.\n *\n * @param digest - The unique digest of the attachment to retrieve\n * @returns The envelope if found, or undefined\n */\n get(digest: Digest): Envelope | undefined {\n return this.#envelopes.get(digest.hex());\n }\n\n /**\n * Removes an attachment by its digest.\n *\n * @param digest - The unique digest of the attachment to remove\n * @returns The removed envelope if found, or undefined\n */\n remove(digest: Digest): Envelope | undefined {\n const envelope = this.#envelopes.get(digest.hex());\n this.#envelopes.delete(digest.hex());\n return envelope;\n }\n\n /**\n * Removes all attachments from the container.\n */\n clear(): void {\n this.#envelopes.clear();\n }\n\n /**\n * Returns whether the container has any attachments.\n */\n isEmpty(): boolean {\n return this.#envelopes.size === 0;\n }\n\n /**\n * Adds all attachments from this container to an envelope.\n *\n * @param envelope - The envelope to add attachments to\n * @returns A new envelope with all attachments added as assertions\n */\n addToEnvelope(envelope: Envelope): Envelope {\n let result = envelope;\n for (const attachment of this.#envelopes.values()) {\n result = result.addAssertion(ATTACHMENT, attachment);\n }\n return result;\n }\n\n /**\n * Creates an Attachments container from an envelope's attachment assertions.\n *\n * @param envelope - The envelope to extract attachments from\n * @returns A new Attachments container with the envelope's attachments\n */\n static fromEnvelope(envelope: Envelope): Attachments {\n const attachments = new Attachments();\n const attachmentEnvelopes = envelope.attachments();\n\n for (const attachment of attachmentEnvelopes) {\n attachments.#envelopes.set(attachment.digest().hex(), attachment);\n }\n\n return attachments;\n }\n}\n\n/**\n * Support for attachments in envelopes.\n */\ndeclare module \"../base/envelope\" {\n interface Envelope {\n /**\n * Creates a new envelope with an attachment as its subject.\n *\n * The attachment consists of:\n * - The predicate 'attachment'\n * - An object that is a wrapped envelope containing:\n * - The payload (as the subject)\n * - A required 'vendor': String assertion\n * - An optional 'conformsTo': String assertion\n *\n * @param payload - The content of the attachment\n * @param vendor - A string identifying the entity (typically reverse domain name)\n * @param conformsTo - Optional URI identifying the format of the attachment\n * @returns A new attachment envelope\n *\n * @example\n * ```typescript\n * const attachment = Envelope.newAttachment(\n * \"Custom data\",\n * \"com.example\",\n * \"https://example.com/format/v1\"\n * );\n * ```\n */\n addAttachment(payload: EnvelopeEncodableValue, vendor: string, conformsTo?: string): Envelope;\n\n /**\n * Returns the payload of an attachment envelope.\n *\n * @returns The payload envelope\n * @throws {EnvelopeError} If the envelope is not a valid attachment\n */\n attachmentPayload(): Envelope;\n\n /**\n * Returns the vendor identifier of an attachment envelope.\n *\n * @returns The vendor string\n * @throws {EnvelopeError} If the envelope is not a valid attachment\n */\n attachmentVendor(): string;\n\n /**\n * Returns the optional conformsTo URI of an attachment envelope.\n *\n * @returns The conformsTo string if present, or undefined\n * @throws {EnvelopeError} If the envelope is not a valid attachment\n */\n attachmentConformsTo(): string | undefined;\n\n /**\n * Returns all attachment assertions in this envelope.\n *\n * @returns Array of attachment envelopes\n */\n attachments(): Envelope[];\n\n /**\n * Searches for attachments matching the given vendor and conformsTo.\n *\n * @param vendor - Optional vendor identifier to match\n * @param conformsTo - Optional conformsTo URI to match\n * @returns Array of matching attachment envelopes\n */\n attachmentsWithVendorAndConformsTo(vendor?: string, conformsTo?: string): Envelope[];\n }\n\n namespace Envelope {\n /**\n * Creates a new attachment envelope.\n *\n * @param payload - The content of the attachment\n * @param vendor - A string identifying the entity\n * @param conformsTo - Optional URI identifying the format\n * @returns A new attachment envelope\n */\n function newAttachment(\n payload: EnvelopeEncodableValue,\n vendor: string,\n conformsTo?: string,\n ): Envelope;\n }\n}\n\n// Implementation\n\n/**\n * Creates a new attachment envelope.\n */\nEnvelope.newAttachment = function (\n payload: EnvelopeEncodableValue,\n vendor: string,\n conformsTo?: string,\n): Envelope {\n // Create the payload envelope wrapped with vendor assertion\n let attachmentObj = Envelope.new(payload).wrap().addAssertion(VENDOR, vendor);\n\n // Add optional conformsTo\n if (conformsTo !== undefined) {\n attachmentObj = attachmentObj.addAssertion(CONFORMS_TO, conformsTo);\n }\n\n // Create an assertion with 'attachment' as predicate and the wrapped payload as object\n // This returns an assertion envelope\n const attachmentPredicate = Envelope.new(ATTACHMENT);\n return attachmentPredicate.addAssertion(ATTACHMENT, attachmentObj).assertions()[0];\n};\n\n/**\n * Adds an attachment to an envelope.\n */\n// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions\nif (Envelope?.prototype) {\n Envelope.prototype.addAttachment = function (\n this: Envelope,\n payload: EnvelopeEncodableValue,\n vendor: string,\n conformsTo?: string,\n ): Envelope {\n let attachmentObj = Envelope.new(payload).wrap().addAssertion(VENDOR, vendor);\n\n if (conformsTo !== undefined) {\n attachmentObj = attachmentObj.addAssertion(CONFORMS_TO, conformsTo);\n }\n\n return this.addAssertion(ATTACHMENT, attachmentObj);\n };\n\n /**\n * Returns the payload of an attachment envelope.\n */\n Envelope.prototype.attachmentPayload = function (this: Envelope): Envelope {\n const c = this.case();\n if (c.type !== \"assertion\") {\n throw EnvelopeError.general(\"Envelope is not an attachment assertion\");\n }\n\n const obj = c.assertion.object();\n return obj.unwrap();\n };\n\n /**\n * Returns the vendor of an attachment envelope.\n */\n Envelope.prototype.attachmentVendor = function (this: Envelope): string {\n const c = this.case();\n if (c.type !== \"assertion\") {\n throw EnvelopeError.general(\"Envelope is not an attachment assertion\");\n }\n\n const obj = c.assertion.object();\n const vendorEnv = obj.objectForPredicate(VENDOR);\n const vendor = vendorEnv.asText();\n\n if (vendor === undefined || vendor === \"\") {\n throw EnvelopeError.general(\"Attachment has no vendor\");\n }\n\n return vendor;\n };\n\n /**\n * Returns the conformsTo of an attachment envelope.\n */\n Envelope.prototype.attachmentConformsTo = function (this: Envelope): string | undefined {\n const c = this.case();\n if (c.type !== \"assertion\") {\n throw EnvelopeError.general(\"Envelope is not an attachment assertion\");\n }\n\n const obj = c.assertion.object();\n const conformsToEnv = obj.optionalObjectForPredicate(CONFORMS_TO);\n\n if (conformsToEnv === undefined) {\n return undefined;\n }\n\n return conformsToEnv.asText();\n };\n\n /**\n * Returns all attachment assertions.\n */\n Envelope.prototype.attachments = function (this: Envelope): Envelope[] {\n return this.assertionsWithPredicate(ATTACHMENT).map((a) => {\n const c = a.case();\n if (c.type === \"assertion\") {\n return c.assertion.object();\n }\n throw EnvelopeError.general(\"Invalid attachment assertion\");\n });\n };\n\n /**\n * Returns attachments matching vendor and/or conformsTo.\n */\n Envelope.prototype.attachmentsWithVendorAndConformsTo = function (\n this: Envelope,\n vendor?: string,\n conformsTo?: string,\n ): Envelope[] {\n const allAttachments = this.attachments();\n\n return allAttachments.filter((attachment) => {\n try {\n // The attachment is already a wrapped envelope with vendor/conformsTo assertions\n // Check vendor if specified\n if (vendor !== undefined) {\n const vendorEnv = attachment.objectForPredicate(VENDOR);\n const attachmentVendor = vendorEnv.asText();\n if (attachmentVendor !== vendor) {\n return false;\n }\n }\n\n // Check conformsTo if specified\n if (conformsTo !== undefined) {\n const conformsToEnv = attachment.optionalObjectForPredicate(CONFORMS_TO);\n if (conformsToEnv === undefined) {\n return false;\n }\n const conformsToText = conformsToEnv.asText();\n if (conformsToText !== conformsTo) {\n return false;\n }\n }\n\n return true;\n } catch {\n return false;\n }\n });\n };\n}\n","import { Envelope } from \"../base/envelope\";\nimport { EnvelopeError } from \"../base/error\";\nimport { SymmetricKey } from \"./encrypt\";\nimport {\n x25519NewPrivateKeyUsing,\n x25519PublicKeyFromPrivateKey,\n x25519SharedKey,\n aeadChaCha20Poly1305EncryptWithAad,\n aeadChaCha20Poly1305DecryptWithAad,\n hkdfHmacSha256,\n X25519_PUBLIC_KEY_SIZE,\n X25519_PRIVATE_KEY_SIZE,\n SYMMETRIC_NONCE_SIZE,\n SYMMETRIC_AUTH_SIZE,\n} from \"@bcts/crypto\";\nimport { SecureRandomNumberGenerator, rngRandomData } from \"@bcts/rand\";\n\n/// Extension for public-key encryption to specific recipients.\n///\n/// This module implements multi-recipient public key encryption using the\n/// Gordian Envelope sealed message pattern. Each recipient gets a sealed\n/// message containing an encrypted content key, allowing multiple recipients\n/// to decrypt the same envelope using their private keys.\n///\n/// ## How it works:\n///\n/// 1. A random symmetric content key is generated\n/// 2. The envelope's subject is encrypted with the content key\n/// 3. The content key is encrypted to each recipient's public key using X25519 key agreement\n/// 4. Each encrypted content key is added as a `hasRecipient` assertion\n///\n/// ## Sealed Box Security:\n///\n/// Sealed boxes use ephemeral X25519 key pairs. The ephemeral private key\n/// is discarded after encryption, ensuring that even the sender cannot\n/// decrypt the message later. Recipients must try each sealed message\n/// until one decrypts successfully.\n///\n/// Uses @bcts/crypto functions for X25519 and ChaCha20-Poly1305.\n///\n/// @example\n/// ```typescript\n/// // Generate recipient keys\n/// const alice = PrivateKeyBase.generate();\n/// const bob = PrivateKeyBase.generate();\n///\n/// // Encrypt to multiple recipients\n/// const envelope = Envelope.new(\"Secret message\")\n/// .encryptSubjectToRecipients([alice.publicKeys(), bob.publicKeys()]);\n///\n/// // Alice decrypts\n/// const aliceDecrypted = envelope.decryptSubjectToRecipient(alice);\n///\n/// // Bob decrypts\n/// const bobDecrypted = envelope.decryptSubjectToRecipient(bob);\n/// ```\n\n/// Predicate constant for recipient assertions\nexport const HAS_RECIPIENT = \"hasRecipient\";\n\n/// Represents an X25519 public key for encryption\nexport class PublicKeyBase {\n readonly #publicKey: Uint8Array;\n\n constructor(publicKey: Uint8Array) {\n if (publicKey.length !== X25519_PUBLIC_KEY_SIZE) {\n throw new Error(`Public key must be ${X25519_PUBLIC_KEY_SIZE} bytes`);\n }\n this.#publicKey = publicKey;\n }\n\n /// Returns the raw public key bytes\n data(): Uint8Array {\n return this.#publicKey;\n }\n\n /// Returns the public key as a hex string\n hex(): string {\n return Array.from(this.#publicKey)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n }\n\n /// Creates a public key from hex string\n static fromHex(hex: string): PublicKeyBase {\n if (hex.length !== 64) {\n throw new Error(\"Hex string must be 64 characters (32 bytes)\");\n }\n const bytes = new Uint8Array(32);\n for (let i = 0; i < 32; i++) {\n bytes[i] = parseInt(hex.substr(i * 2, 2), 16);\n }\n return new PublicKeyBase(bytes);\n }\n}\n\n/// Represents an X25519 private key for decryption\nexport class PrivateKeyBase {\n readonly #privateKey: Uint8Array;\n readonly #publicKey: PublicKeyBase;\n\n private constructor(privateKey: Uint8Array, publicKey: Uint8Array) {\n this.#privateKey = privateKey;\n this.#publicKey = new PublicKeyBase(publicKey);\n }\n\n /// Generates a new random X25519 key pair\n static generate(): PrivateKeyBase {\n const rng = new SecureRandomNumberGenerator();\n const privateKey = x25519NewPrivateKeyUsing(rng);\n const publicKey = x25519PublicKeyFromPrivateKey(privateKey);\n return new PrivateKeyBase(privateKey, publicKey);\n }\n\n /// Creates a private key from existing bytes\n static fromBytes(privateKey: Uint8Array, publicKey: Uint8Array): PrivateKeyBase {\n if (privateKey.length !== X25519_PRIVATE_KEY_SIZE) {\n throw new Error(`Private key must be ${X25519_PRIVATE_KEY_SIZE} bytes`);\n }\n if (publicKey.length !== X25519_PUBLIC_KEY_SIZE) {\n throw new Error(`Public key must be ${X25519_PUBLIC_KEY_SIZE} bytes`);\n }\n return new PrivateKeyBase(privateKey, publicKey);\n }\n\n /// Creates a private key from hex strings\n static fromHex(privateHex: string, publicHex: string): PrivateKeyBase {\n const privateBytes = new Uint8Array(32);\n const publicBytes = new Uint8Array(32);\n\n for (let i = 0; i < 32; i++) {\n privateBytes[i] = parseInt(privateHex.substr(i * 2, 2), 16);\n publicBytes[i] = parseInt(publicHex.substr(i * 2, 2), 16);\n }\n\n return new PrivateKeyBase(privateBytes, publicBytes);\n }\n\n /// Returns the public key\n publicKeys(): PublicKeyBase {\n return this.#publicKey;\n }\n\n /// Returns the raw private key bytes\n data(): Uint8Array {\n return this.#privateKey;\n }\n\n /// Returns the private key as hex string\n hex(): string {\n return Array.from(this.#privateKey)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n }\n\n /// Decrypts a sealed message to get the content key\n unseal(sealedMessage: SealedMessage): SymmetricKey {\n try {\n const decrypted = sealedMessage.decrypt(this.#privateKey, this.#publicKey.data());\n return SymmetricKey.from(decrypted);\n } catch (_error) {\n throw EnvelopeError.general(\"Failed to unseal message: not a recipient\");\n }\n }\n}\n\n/// Represents a sealed message - encrypted content key for a recipient\n/// Uses X25519 key agreement + ChaCha20-Poly1305 AEAD\n///\n/// Format: ephemeral_public_key (32 bytes) || nonce (12 bytes) || ciphertext || auth_tag (16 bytes)\nexport class SealedMessage {\n readonly #data: Uint8Array;\n\n constructor(data: Uint8Array) {\n this.#data = data;\n }\n\n /// Creates a sealed message by encrypting a symmetric key to a recipient's public key\n /// Uses X25519 ECDH for key agreement and ChaCha20-Poly1305 for encryption\n static seal(contentKey: SymmetricKey, recipientPublicKey: PublicKeyBase): SealedMessage {\n const rng = new SecureRandomNumberGenerator();\n\n // Generate ephemeral key pair\n const ephemeralPrivate = x25519NewPrivateKeyUsing(rng);\n const ephemeralPublic = x25519PublicKeyFromPrivateKey(ephemeralPrivate);\n\n // Compute shared secret using X25519 ECDH\n const sharedSecret = x25519SharedKey(ephemeralPrivate, recipientPublicKey.data());\n\n // Derive encryption key from shared secret using HKDF\n const salt = new TextEncoder().encode(\"sealed_message\");\n const encryptionKey = hkdfHmacSha256(sharedSecret, salt, 32);\n\n // Generate random nonce\n const nonce = rngRandomData(rng, SYMMETRIC_NONCE_SIZE);\n\n // Encrypt content key using ChaCha20-Poly1305\n const plaintext = contentKey.data();\n const [ciphertext, authTag] = aeadChaCha20Poly1305EncryptWithAad(\n plaintext,\n encryptionKey,\n nonce,\n new Uint8Array(0), // No AAD for sealed box\n );\n\n // Format: ephemeral_public_key || nonce || ciphertext || auth_tag\n const totalLength = ephemeralPublic.length + nonce.length + ciphertext.length + authTag.length;\n const sealed = new Uint8Array(totalLength);\n let offset = 0;\n\n sealed.set(ephemeralPublic, offset);\n offset += ephemeralPublic.length;\n\n sealed.set(nonce, offset);\n offset += nonce.length;\n\n sealed.set(ciphertext, offset);\n offset += ciphertext.length;\n\n sealed.set(authTag, offset);\n\n return new SealedMessage(sealed);\n }\n\n /// Decrypts this sealed message using recipient's private key\n decrypt(recipientPrivate: Uint8Array, _recipientPublic: Uint8Array): Uint8Array {\n // Parse sealed message format: ephemeral_public_key || nonce || ciphertext || auth_tag\n const minLength = X25519_PUBLIC_KEY_SIZE + SYMMETRIC_NONCE_SIZE + SYMMETRIC_AUTH_SIZE;\n if (this.#data.length < minLength) {\n throw new Error(\"Sealed message too short\");\n }\n\n let offset = 0;\n\n // Extract ephemeral public key\n const ephemeralPublic = this.#data.slice(offset, offset + X25519_PUBLIC_KEY_SIZE);\n offset += X25519_PUBLIC_KEY_SIZE;\n\n // Extract nonce\n const nonce = this.#data.slice(offset, offset + SYMMETRIC_NONCE_SIZE);\n offset += SYMMETRIC_NONCE_SIZE;\n\n // Extract ciphertext and auth tag\n const ciphertextAndTag = this.#data.slice(offset);\n const ciphertext = ciphertextAndTag.slice(0, -SYMMETRIC_AUTH_SIZE);\n const authTag = ciphertextAndTag.slice(-SYMMETRIC_AUTH_SIZE);\n\n // Compute shared secret using X25519 ECDH\n const sharedSecret = x25519SharedKey(recipientPrivate, ephemeralPublic);\n\n // Derive decryption key from shared secret using HKDF\n const salt = new TextEncoder().encode(\"sealed_message\");\n const decryptionKey = hkdfHmacSha256(sharedSecret, salt, 32);\n\n // Decrypt using ChaCha20-Poly1305\n const plaintext = aeadChaCha20Poly1305DecryptWithAad(\n ciphertext,\n decryptionKey,\n nonce,\n new Uint8Array(0), // No AAD for sealed box\n authTag,\n );\n\n return plaintext;\n }\n\n /// Returns the raw sealed message bytes\n data(): Uint8Array {\n return this.#data;\n }\n\n /// Returns the sealed message as hex string\n hex(): string {\n return Array.from(this.#data)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n }\n\n /// Creates a sealed message from hex string\n static fromHex(hex: string): SealedMessage {\n const bytes = new Uint8Array(hex.length / 2);\n for (let i = 0; i < bytes.length; i++) {\n bytes[i] = parseInt(hex.substr(i * 2, 2), 16);\n }\n return new SealedMessage(bytes);\n }\n}\n\ndeclare module \"../base/envelope\" {\n interface Envelope {\n /// Encrypts the envelope's subject to a single recipient.\n ///\n /// Generates a random content key, encrypts the subject with it,\n /// and adds a sealed message containing the content key encrypted\n /// to the recipient's public key.\n ///\n /// @param recipientPublicKey - The recipient's public key\n /// @returns A new envelope with encrypted subject and recipient assertion\n ///\n /// @example\n /// ```typescript\n /// const bob = PrivateKeyBase.generate();\n /// const encrypted = envelope.encryptSubjectToRecipient(bob.publicKeys());\n /// ```\n encryptSubjectToRecipient(recipientPublicKey: PublicKeyBase): Envelope;\n\n /// Encrypts the envelope's subject to multiple recipients.\n ///\n /// Each recipient gets their own sealed message containing the same\n /// content key encrypted to their public key. Recipients must try\n /// each sealed message until one decrypts successfully.\n ///\n /// @param recipients - Array of recipient public keys\n /// @returns A new envelope with encrypted subject and multiple recipient assertions\n ///\n /// @example\n /// ```typescript\n /// const encrypted = envelope.encryptSubjectToRecipients([\n /// alice.publicKeys(),\n /// bob.publicKeys(),\n /// charlie.publicKeys()\n /// ]);\n /// ```\n encryptSubjectToRecipients(recipients: PublicKeyBase[]): Envelope;\n\n /// Adds a recipient to an already encrypted envelope.\n ///\n /// The envelope must already be encrypted with a content key.\n /// This method adds another recipient who can decrypt using the\n /// same content key.\n ///\n /// @param recipientPublicKey - The new recipient's public key\n /// @param contentKey - The symmetric key used to encrypt the subject\n /// @returns A new envelope with an additional recipient assertion\n ///\n /// @example\n /// ```typescript\n /// const dave = PrivateKeyBase.generate();\n /// const withDave = encrypted.addRecipient(dave.publicKeys(), contentKey);\n /// ```\n addRecipient(recipientPublicKey: PublicKeyBase, contentKey: SymmetricKey): Envelope;\n\n /// Decrypts an envelope's subject using a recipient's private key.\n ///\n /// Tries each `hasRecipient` assertion until one unseals successfully,\n /// then uses the recovered content key to decrypt the subject.\n ///\n /// @param recipientPrivateKey - The recipient's private key\n /// @returns A new envelope with decrypted subject\n /// @throws {EnvelopeError} If not a valid recipient or subject not encrypted\n ///\n /// @example\n /// ```typescript\n /// const decrypted = encrypted.decryptSubjectToRecipient(bob);\n /// ```\n decryptSubjectToRecipient(recipientPrivateKey: PrivateKeyBase): Envelope;\n\n /// Convenience method to decrypt and unwrap an envelope.\n ///\n /// Useful when the entire envelope was wrapped and encrypted.\n /// Decrypts the subject and then unwraps it.\n ///\n /// @param recipientPrivateKey - The recipient's private key\n /// @returns The original decrypted and unwrapped envelope\n /// @throws {EnvelopeError} If not a valid recipient, subject not encrypted, or cannot unwrap\n ///\n /// @example\n /// ```typescript\n /// const original = wrappedEncrypted.decryptToRecipient(alice);\n /// ```\n decryptToRecipient(recipientPrivateKey: PrivateKeyBase): Envelope;\n\n /// Convenience method to encrypt an entire envelope to recipients.\n ///\n /// Wraps the envelope first, then encrypts it to the recipients.\n /// This encrypts both the subject and all assertions.\n ///\n /// @param recipients - Array of recipient public keys\n /// @returns A new encrypted envelope\n ///\n /// @example\n /// ```typescript\n /// const encrypted = envelope.encryptToRecipients([\n /// alice.publicKeys(),\n /// bob.publicKeys()\n /// ]);\n /// ```\n encryptToRecipients(recipients: PublicKeyBase[]): Envelope;\n\n /// Returns all sealed messages (recipient assertions) in the envelope.\n ///\n /// Each sealed message represents one recipient who can decrypt\n /// the envelope's subject.\n ///\n /// @returns Array of sealed messages\n ///\n /// @example\n /// ```typescript\n /// const recipients = envelope.recipients();\n /// console.log(`Envelope has ${recipients.length} recipients`);\n /// ```\n recipients(): SealedMessage[];\n }\n}\n\n/// Implementation of encryptSubjectToRecipient()\n// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions\nif (Envelope?.prototype) {\n Envelope.prototype.encryptSubjectToRecipient = function (\n this: Envelope,\n recipientPublicKey: PublicKeyBase,\n ): Envelope {\n // Generate a random content key\n const contentKey = SymmetricKey.generate();\n\n // Encrypt the subject with the content key\n const encrypted = this.encryptSubject(contentKey);\n\n // Add the recipient\n return encrypted.addRecipient(recipientPublicKey, contentKey);\n };\n\n /// Implementation of encryptSubjectToRecipients()\n Envelope.prototype.encryptSubjectToRecipients = function (\n this: Envelope,\n recipients: PublicKeyBase[],\n ): Envelope {\n if (recipients.length === 0) {\n throw EnvelopeError.general(\"Must provide at least one recipient\");\n }\n\n // Generate a random content key\n const contentKey = SymmetricKey.generate();\n\n // Encrypt the subject with the content key\n let result = this.encryptSubject(contentKey);\n\n // Add each recipient\n for (const recipient of recipients) {\n result = result.addRecipient(recipient, contentKey);\n }\n\n return result;\n };\n\n /// Implementation of addRecipient()\n Envelope.prototype.addRecipient = function (\n this: Envelope,\n recipientPublicKey: PublicKeyBase,\n contentKey: SymmetricKey,\n ): Envelope {\n // Create a sealed message with the content key\n const sealedMessage = SealedMessage.seal(contentKey, recipientPublicKey);\n\n // Store the sealed message as bytes in the assertion\n return this.addAssertion(HAS_RECIPIENT, sealedMessage.data());\n };\n\n /// Implementation of decryptSubjectToRecipient()\n Envelope.prototype.decryptSubjectToRecipient = function (\n this: Envelope,\n recipientPrivateKey: PrivateKeyBase,\n ): Envelope {\n // Check that the subject is encrypted\n const subjectCase = this.subject().case();\n if (subjectCase.type !== \"encrypted\") {\n throw EnvelopeError.general(\"Subject is not encrypted\");\n }\n\n // Get all recipient assertions\n const recipientAssertions = this.assertions().filter((assertion) => {\n try {\n const predicate = assertion.subject().asPredicate();\n if (predicate === undefined) return false;\n return predicate.asText() === HAS_RECIPIENT;\n } catch {\n return false;\n }\n });\n\n if (recipientAssertions.length === 0) {\n throw EnvelopeError.general(\"No recipients found\");\n }\n\n // Try each recipient assertion until one unseals successfully\n let contentKey: SymmetricKey | null = null;\n\n for (const assertion of recipientAssertions) {\n try {\n const obj = assertion.subject().asObject();\n if (obj === undefined) continue;\n const sealedData = obj.asByteString();\n if (sealedData === undefined) continue;\n const sealedMessage = new SealedMessage(sealedData);\n\n // Try to unseal with our private key\n contentKey = recipientPrivateKey.unseal(sealedMessage);\n break; // Success!\n } catch {\n // Not for us, try next one\n continue;\n }\n }\n\n if (contentKey === null) {\n throw EnvelopeError.general(\"Not a valid recipient\");\n }\n\n // Decrypt the subject using the content key\n return this.decryptSubject(contentKey);\n };\n\n /// Implementation of decryptToRecipient()\n Envelope.prototype.decryptToRecipient = function (\n this: Envelope,\n recipientPrivateKey: PrivateKeyBase,\n ): Envelope {\n const decrypted = this.decryptSubjectToRecipient(recipientPrivateKey);\n return decrypted.unwrap();\n };\n\n /// Implementation of encryptToRecipients()\n Envelope.prototype.encryptToRecipients = function (\n this: Envelope,\n recipients: PublicKeyBase[],\n ): Envelope {\n return this.wrap().encryptSubjectToRecipients(recipients);\n };\n\n /// Implementation of recipients()\n Envelope.prototype.recipients = function (this: Envelope): SealedMessage[] {\n const recipientAssertions = this.assertions().filter((assertion) => {\n try {\n const predicate = assertion.subject().asPredicate();\n if (predicate === undefined) return false;\n return predicate.asText() === HAS_RECIPIENT;\n } catch {\n return false;\n }\n });\n\n return recipientAssertions.map((assertion) => {\n const obj = assertion.subject().asObject();\n if (obj === undefined) {\n throw EnvelopeError.general(\"Invalid recipient assertion\");\n }\n const sealedData = obj.asByteString();\n if (sealedData === undefined) {\n throw EnvelopeError.general(\"Invalid recipient data\");\n }\n return new SealedMessage(sealedData);\n });\n };\n}\n\n// Import side-effect to register prototype extensions\nexport {};\n","import { Envelope } from \"../base/envelope\";\nimport { type EnvelopeEncodableValue } from \"../base/envelope-encodable\";\nimport { EnvelopeError } from \"../base/error\";\n\n/// Extension for envelope expressions.\n///\n/// This module implements the Gordian Envelope expression syntax as specified\n/// in BCR-2023-012. Expressions enable encoding of machine-evaluatable\n/// expressions using envelopes, providing a foundation for distributed\n/// function calls and computation.\n///\n/// ## Expression Structure\n///\n/// An expression consists of:\n/// - A function identifier (the subject)\n/// - Zero or more parameters (as assertions)\n/// - Optional metadata (non-parameter assertions)\n///\n/// ## CBOR Tags\n///\n/// - Function: #6.40006\n/// - Parameter: #6.40007\n/// - Placeholder: #6.40008\n/// - Replacement: #6.40009\n///\n/// @example\n/// ```typescript\n/// // Create a simple addition expression: add(lhs: 2, rhs: 3)\n/// const expr = new Function('add')\n/// .withParameter('lhs', 2)\n/// .withParameter('rhs', 3);\n///\n/// const envelope = expr.envelope();\n/// ```\n\n/// CBOR tag for function identifiers\nexport const CBOR_TAG_FUNCTION = 40006;\n\n/// CBOR tag for parameter identifiers\nexport const CBOR_TAG_PARAMETER = 40007;\n\n/// CBOR tag for placeholder identifiers\nexport const CBOR_TAG_PLACEHOLDER = 40008;\n\n/// CBOR tag for replacement identifiers\nexport const CBOR_TAG_REPLACEMENT = 40009;\n\n/// Well-known function identifiers (numeric)\nexport const FUNCTION_IDS = {\n ADD: 1, // addition\n SUB: 2, // subtraction\n MUL: 3, // multiplication\n DIV: 4, // division\n NEG: 5, // unary negation\n LT: 6, // less than\n LE: 7, // less than or equal\n GT: 8, // greater than\n GE: 9, // greater than or equal\n EQ: 10, // equal to\n NE: 11, // not equal to\n AND: 12, // logical and\n OR: 13, // logical or\n XOR: 14, // logical xor\n NOT: 15, // logical not\n} as const;\n\n/// Well-known parameter identifiers (numeric)\nexport const PARAMETER_IDS = {\n BLANK: 1, // blank/implicit parameter (_)\n LHS: 2, // left-hand side\n RHS: 3, // right-hand side\n} as const;\n\n/// Type for function identifier (number or string)\nexport type FunctionID = number | string;\n\n/// Type for parameter identifier (number or string)\nexport type ParameterID = number | string;\n\n/// Represents a function identifier in an expression\nexport class Function {\n readonly #id: FunctionID;\n\n constructor(id: FunctionID) {\n this.#id = id;\n }\n\n /// Returns the function identifier\n id(): FunctionID {\n return this.#id;\n }\n\n /// Returns true if this is a numeric function ID\n isNumeric(): boolean {\n return typeof this.#id === \"number\";\n }\n\n /// Returns true if this is a string function ID\n isString(): boolean {\n return typeof this.#id === \"string\";\n }\n\n /// Creates an expression envelope with this function as the subject\n envelope(): Envelope {\n // For now, create a simple envelope with the function ID\n // In a full implementation, this would use CBOR tag 40006\n const functionStr = typeof this.#id === \"number\" ? `«${this.#id}»` : `«\"${this.#id}\"»`;\n return Envelope.new(functionStr);\n }\n\n /// Creates an expression with a parameter\n withParameter(param: ParameterID, value: EnvelopeEncodableValue): Expression {\n const expr = new Expression(this);\n return expr.withParameter(param, value);\n }\n\n /// Creates a function from a known numeric ID\n static fromNumeric(id: number): Function {\n return new Function(id);\n }\n\n /// Creates a function from a string name\n static fromString(name: string): Function {\n return new Function(name);\n }\n\n /// Returns a string representation for display\n toString(): string {\n return typeof this.#id === \"number\" ? `«${this.#id}»` : `«\"${this.#id}\"»`;\n }\n}\n\n/// Represents a parameter in an expression\nexport class Parameter {\n readonly #id: ParameterID;\n readonly #value: Envelope;\n\n constructor(id: ParameterID, value: Envelope) {\n this.#id = id;\n this.#value = value;\n }\n\n /// Returns the parameter identifier\n id(): ParameterID {\n return this.#id;\n }\n\n /// Returns the parameter value as an envelope\n value(): Envelope {\n return this.#value;\n }\n\n /// Returns true if this is a numeric parameter ID\n isNumeric(): boolean {\n return typeof this.#id === \"number\";\n }\n\n /// Returns true if this is a string parameter ID\n isString(): boolean {\n return typeof this.#id === \"string\";\n }\n\n /// Creates a parameter envelope\n /// In a full implementation, this would use CBOR tag 40007\n envelope(): Envelope {\n const paramStr = typeof this.#id === \"number\" ? `❰${this.#id}❱` : `❰\"${this.#id}\"❱`;\n return Envelope.newAssertion(paramStr, this.#value);\n }\n\n /// Creates a parameter from known IDs\n static blank(value: EnvelopeEncodableValue): Parameter {\n return new Parameter(PARAMETER_IDS.BLANK, Envelope.new(value));\n }\n\n static lhs(value: EnvelopeEncodableValue): Parameter {\n return new Parameter(PARAMETER_IDS.LHS, Envelope.new(value));\n }\n\n static rhs(value: EnvelopeEncodableValue): Parameter {\n return new Parameter(PARAMETER_IDS.RHS, Envelope.new(value));\n }\n\n /// Returns a string representation for display\n toString(): string {\n const idStr = typeof this.#id === \"number\" ? `❰${this.#id}❱` : `❰\"${this.#id}\"❱`;\n return `${idStr}: ${this.#value.asText()}`;\n }\n}\n\n/// Represents a complete expression with function and parameters\nexport class Expression {\n readonly #function: Function;\n readonly #parameters = new Map<string, Parameter>();\n #envelope: Envelope | null = null;\n\n constructor(func: Function) {\n this.#function = func;\n }\n\n /// Returns the function\n function(): Function {\n return this.#function;\n }\n\n /// Returns all parameters\n parameters(): Parameter[] {\n return Array.from(this.#parameters.values());\n }\n\n /// Adds a parameter to the expression\n withParameter(param: ParameterID, value: EnvelopeEncodableValue): Expression {\n const key = typeof param === \"number\" ? param.toString() : param;\n this.#parameters.set(key, new Parameter(param, Envelope.new(value)));\n this.#envelope = null; // Invalidate cached envelope\n return this;\n }\n\n /// Adds multiple parameters at once\n withParameters(params: Record<string, EnvelopeEncodableValue>): Expression {\n for (const [key, value] of Object.entries(params)) {\n this.withParameter(key, value);\n }\n return this;\n }\n\n /// Gets a parameter value by ID\n getParameter(param: ParameterID): Envelope | undefined {\n const key = typeof param === \"number\" ? param.toString() : param;\n return this.#parameters.get(key)?.value();\n }\n\n /// Checks if a parameter exists\n hasParameter(param: ParameterID): boolean {\n const key = typeof param === \"number\" ? param.toString() : param;\n return this.#parameters.has(key);\n }\n\n /// Converts the expression to an envelope\n envelope(): Envelope {\n if (this.#envelope !== null) {\n return this.#envelope;\n }\n\n // Start with function envelope\n let env = this.#function.envelope();\n\n // Add all parameters as assertions\n for (const param of this.#parameters.values()) {\n const paramEnv = param.envelope();\n // Extract the assertion from the parameter envelope\n const assertion = paramEnv.assertions()[0];\n if (assertion !== undefined) {\n const predicate = assertion.subject().asPredicate();\n const object = assertion.subject().asObject();\n if (predicate !== undefined && object !== undefined) {\n env = env.addAssertion(predicate.asText(), object);\n }\n }\n }\n\n this.#envelope = env;\n return env;\n }\n\n /// Creates an expression from an envelope\n /// Note: This is a simplified implementation\n static fromEnvelope(envelope: Envelope): Expression {\n // Extract function from subject\n const subject = envelope.subject();\n const subjectText = subject.asText();\n if (subjectText === undefined) {\n throw EnvelopeError.general(\"Not a valid function envelope\");\n }\n\n // Parse function identifier\n let funcId: FunctionID;\n if (subjectText.startsWith(\"«\") && subjectText.endsWith(\"»\")) {\n const inner = subjectText.slice(1, -1);\n if (inner.startsWith('\"') && inner.endsWith('\"')) {\n funcId = inner.slice(1, -1); // String function\n } else {\n funcId = parseInt(inner, 10); // Numeric function\n }\n } else {\n throw EnvelopeError.general(\"Not a valid function envelope\");\n }\n\n const func = new Function(funcId);\n const expr = new Expression(func);\n\n // Extract parameters from assertions\n for (const assertion of envelope.assertions()) {\n try {\n const pred = assertion.subject().asPredicate();\n const obj = assertion.subject().asObject();\n\n if (pred !== undefined && obj !== undefined) {\n const predText = pred.asText();\n if (predText !== undefined && predText.startsWith(\"❰\") && predText.endsWith(\"❱\")) {\n const inner = predText.slice(1, -1);\n let paramId: ParameterID;\n if (inner.startsWith('\"') && inner.endsWith('\"')) {\n paramId = inner.slice(1, -1);\n } else {\n paramId = parseInt(inner, 10);\n }\n expr.withParameter(paramId, obj);\n }\n }\n } catch {\n // Skip non-parameter assertions\n continue;\n }\n }\n\n return expr;\n }\n\n /// Returns a string representation for display\n toString(): string {\n const params = Array.from(this.#parameters.values())\n .map((p) => p.toString())\n .join(\", \");\n return `${this.#function.toString()} [${params}]`;\n }\n}\n\n/// Helper functions for creating common expressions\n\n/// Creates an addition expression: lhs + rhs\nexport function add(lhs: EnvelopeEncodableValue, rhs: EnvelopeEncodableValue): Expression {\n return Function.fromNumeric(FUNCTION_IDS.ADD)\n .withParameter(PARAMETER_IDS.LHS, lhs)\n .withParameter(PARAMETER_IDS.RHS, rhs);\n}\n\n/// Creates a subtraction expression: lhs - rhs\nexport function sub(lhs: EnvelopeEncodableValue, rhs: EnvelopeEncodableValue): Expression {\n return Function.fromNumeric(FUNCTION_IDS.SUB)\n .withParameter(PARAMETER_IDS.LHS, lhs)\n .withParameter(PARAMETER_IDS.RHS, rhs);\n}\n\n/// Creates a multiplication expression: lhs * rhs\nexport function mul(lhs: EnvelopeEncodableValue, rhs: EnvelopeEncodableValue): Expression {\n return Function.fromNumeric(FUNCTION_IDS.MUL)\n .withParameter(PARAMETER_IDS.LHS, lhs)\n .withParameter(PARAMETER_IDS.RHS, rhs);\n}\n\n/// Creates a division expression: lhs / rhs\nexport function div(lhs: EnvelopeEncodableValue, rhs: EnvelopeEncodableValue): Expression {\n return Function.fromNumeric(FUNCTION_IDS.DIV)\n .withParameter(PARAMETER_IDS.LHS, lhs)\n .withParameter(PARAMETER_IDS.RHS, rhs);\n}\n\n/// Creates a negation expression: -value\nexport function neg(value: EnvelopeEncodableValue): Expression {\n return Function.fromNumeric(FUNCTION_IDS.NEG).withParameter(PARAMETER_IDS.BLANK, value);\n}\n\n/// Creates a less-than expression: lhs < rhs\nexport function lt(lhs: EnvelopeEncodableValue, rhs: EnvelopeEncodableValue): Expression {\n return Function.fromNumeric(FUNCTION_IDS.LT)\n .withParameter(PARAMETER_IDS.LHS, lhs)\n .withParameter(PARAMETER_IDS.RHS, rhs);\n}\n\n/// Creates a greater-than expression: lhs > rhs\nexport function gt(lhs: EnvelopeEncodableValue, rhs: EnvelopeEncodableValue): Expression {\n return Function.fromNumeric(FUNCTION_IDS.GT)\n .withParameter(PARAMETER_IDS.LHS, lhs)\n .withParameter(PARAMETER_IDS.RHS, rhs);\n}\n\n/// Creates an equality expression: lhs == rhs\nexport function eq(lhs: EnvelopeEncodableValue, rhs: EnvelopeEncodableValue): Expression {\n return Function.fromNumeric(FUNCTION_IDS.EQ)\n .withParameter(PARAMETER_IDS.LHS, lhs)\n .withParameter(PARAMETER_IDS.RHS, rhs);\n}\n\n/// Creates a logical AND expression: lhs && rhs\nexport function and(lhs: EnvelopeEncodableValue, rhs: EnvelopeEncodableValue): Expression {\n return Function.fromNumeric(FUNCTION_IDS.AND)\n .withParameter(PARAMETER_IDS.LHS, lhs)\n .withParameter(PARAMETER_IDS.RHS, rhs);\n}\n\n/// Creates a logical OR expression: lhs || rhs\nexport function or(lhs: EnvelopeEncodableValue, rhs: EnvelopeEncodableValue): Expression {\n return Function.fromNumeric(FUNCTION_IDS.OR)\n .withParameter(PARAMETER_IDS.LHS, lhs)\n .withParameter(PARAMETER_IDS.RHS, rhs);\n}\n\n/// Creates a logical NOT expression: !value\nexport function not(value: EnvelopeEncodableValue): Expression {\n return Function.fromNumeric(FUNCTION_IDS.NOT).withParameter(PARAMETER_IDS.BLANK, value);\n}\n\n// Export types and classes\nexport {};\n","import { Envelope } from \"../base/envelope\";\nimport { type Digest } from \"../base/digest\";\n\n/// Extension for envelope inclusion proofs.\n///\n/// Inclusion proofs allow a holder of an envelope to prove that specific\n/// elements exist within the envelope without revealing the entire contents.\n/// This is particularly useful for selective disclosure of information in\n/// privacy-preserving scenarios.\n///\n/// ## How Inclusion Proofs Work\n///\n/// The inclusion proof mechanism leverages the Merkle-like digest tree\n/// structure of envelopes:\n/// - The holder creates a minimal structure containing only the digests\n/// necessary to validate the proof\n/// - A verifier with a trusted root digest can confirm that the specific\n/// elements exist in the original envelope\n/// - All other content can remain elided, preserving privacy\n///\n/// For enhanced privacy, elements can be salted to prevent correlation attacks.\n///\n/// @example\n/// ```typescript\n/// // Create an envelope with multiple assertions\n/// const aliceFriends = Envelope.new('Alice')\n/// .addAssertion('knows', 'Bob')\n/// .addAssertion('knows', 'Carol')\n/// .addAssertion('knows', 'Dan');\n///\n/// // Create a representation of just the root digest\n/// const aliceFriendsRoot = aliceFriends.elideRevealingSet(new Set());\n///\n/// // Create the target we want to prove exists\n/// const knowsBobAssertion = Envelope.newAssertion('knows', 'Bob');\n///\n/// // Generate a proof that Alice knows Bob\n/// const aliceKnowsBobProof = aliceFriends.proofContainsTarget(knowsBobAssertion);\n///\n/// // A third party can verify the proof against the trusted root\n/// if (aliceKnowsBobProof) {\n/// const isValid = aliceFriendsRoot.confirmContainsTarget(\n/// knowsBobAssertion,\n/// aliceKnowsBobProof\n/// );\n/// console.log('Proof is valid:', isValid);\n/// }\n/// ```\n\ndeclare module \"../base/envelope\" {\n interface Envelope {\n /// Creates a proof that this envelope includes every element in the target set.\n ///\n /// An inclusion proof is a specially constructed envelope that:\n /// - Has the same digest as the original envelope (or an elided version of it)\n /// - Contains the minimal structure needed to prove the existence of target elements\n /// - Keeps all other content elided to preserve privacy\n ///\n /// @param target - The set of digests representing elements that the proof must include\n /// @returns A proof envelope if all targets can be proven to exist, undefined otherwise\n proofContainsSet(target: Set<Digest>): Envelope | undefined;\n\n /// Creates a proof that this envelope includes the single target element.\n ///\n /// This is a convenience method that wraps `proofContainsSet()` for the\n /// common case of proving the existence of just one element.\n ///\n /// @param target - The element that the proof must demonstrate exists in this envelope\n /// @returns A proof envelope if the target can be proven to exist, undefined otherwise\n proofContainsTarget(target: Envelope): Envelope | undefined;\n\n /// Verifies whether this envelope contains all elements in the target set\n /// using the given inclusion proof.\n ///\n /// This method is used by a verifier to check if a proof demonstrates the\n /// existence of all target elements within this envelope. The verification\n /// succeeds only if:\n /// 1. The proof's digest matches this envelope's digest\n /// 2. The proof contains all the target elements\n ///\n /// @param target - The set of digests representing elements that need to be proven to exist\n /// @param proof - The inclusion proof envelope to verify\n /// @returns true if all target elements are proven to exist in this envelope by the proof\n confirmContainsSet(target: Set<Digest>, proof: Envelope): boolean;\n\n /// Verifies whether this envelope contains the single target element using\n /// the given inclusion proof.\n ///\n /// This is a convenience method that wraps `confirmContainsSet()` for the\n /// common case of verifying just one element.\n ///\n /// @param target - The element that needs to be proven to exist in this envelope\n /// @param proof - The inclusion proof envelope to verify\n /// @returns true if the target element is proven to exist in this envelope by the proof\n confirmContainsTarget(target: Envelope, proof: Envelope): boolean;\n }\n}\n\n/// Implementation of proof methods on Envelope prototype\n// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions\nif (Envelope?.prototype) {\n Envelope.prototype.proofContainsSet = function (target: Set<Digest>): Envelope | undefined {\n const revealSet = revealSetOfSet(this, target);\n\n // Check if all targets can be revealed\n if (!isSubset(target, revealSet)) {\n return undefined;\n }\n\n // Create a proof by revealing only what's necessary, then eliding the targets\n const revealed = this.elideRevealingSet(revealSet);\n return revealed.elideRemovingSet(target);\n };\n\n Envelope.prototype.proofContainsTarget = function (target: Envelope): Envelope | undefined {\n const targetSet = new Set<Digest>([target.digest()]);\n return this.proofContainsSet(targetSet);\n };\n\n Envelope.prototype.confirmContainsSet = function (target: Set<Digest>, proof: Envelope): boolean {\n // Verify the proof has the same digest as this envelope\n if (this.digest().hex() !== proof.digest().hex()) {\n return false;\n }\n\n // Verify the proof contains all target elements\n return containsAll(proof, target);\n };\n\n Envelope.prototype.confirmContainsTarget = function (target: Envelope, proof: Envelope): boolean {\n const targetSet = new Set<Digest>([target.digest()]);\n return this.confirmContainsSet(targetSet, proof);\n };\n}\n\n/// Internal helper functions\n\n/// Builds a set of all digests needed to reveal the target set.\n///\n/// This collects all digests in the path from the envelope's root to each\n/// target element.\nfunction revealSetOfSet(envelope: Envelope, target: Set<Digest>): Set<Digest> {\n const result = new Set<Digest>();\n revealSets(envelope, target, new Set<Digest>(), result);\n return result;\n}\n\n/// Recursively traverses the envelope to collect all digests needed to\n/// reveal the target set.\n///\n/// Builds the set of digests forming the path from the root to each target element.\nfunction revealSets(\n envelope: Envelope,\n target: Set<Digest>,\n current: Set<Digest>,\n result: Set<Digest>,\n): void {\n // Add current envelope's digest to the path\n const newCurrent = new Set(current);\n newCurrent.add(envelope.digest());\n\n // If this is a target, add the entire path to the result\n if (containsDigest(target, envelope.digest())) {\n for (const digest of newCurrent) {\n result.add(digest);\n }\n }\n\n // Traverse the envelope structure\n const envelopeCase = envelope.case();\n\n if (envelopeCase.type === \"node\") {\n // Traverse subject\n revealSets(envelopeCase.subject, target, newCurrent, result);\n\n // Traverse all assertions\n for (const assertion of envelopeCase.assertions) {\n revealSets(assertion, target, newCurrent, result);\n }\n } else if (envelopeCase.type === \"wrapped\") {\n // Traverse wrapped envelope\n revealSets(envelopeCase.envelope, target, newCurrent, result);\n } else if (envelopeCase.type === \"assertion\") {\n // Traverse predicate and object\n const predicate = envelopeCase.assertion.predicate();\n const object = envelopeCase.assertion.object();\n revealSets(predicate, target, newCurrent, result);\n revealSets(object, target, newCurrent, result);\n }\n // For leaf envelopes (elided, encrypted, compressed, leaf), no further traversal needed\n}\n\n/// Checks if this envelope contains all elements in the target set.\n///\n/// Used during proof verification to confirm all target elements exist in the proof.\nfunction containsAll(envelope: Envelope, target: Set<Digest>): boolean {\n const targetCopy = new Set(target);\n removeAllFound(envelope, targetCopy);\n return targetCopy.size === 0;\n}\n\n/// Recursively traverses the envelope and removes found target elements from the set.\n///\n/// Used during proof verification to confirm all target elements are present.\nfunction removeAllFound(envelope: Envelope, target: Set<Digest>): void {\n // Check if this envelope's digest is in the target set\n if (containsDigest(target, envelope.digest())) {\n removeDigest(target, envelope.digest());\n }\n\n // Early exit if all targets found\n if (target.size === 0) {\n return;\n }\n\n // Traverse the envelope structure\n const envelopeCase = envelope.case();\n\n if (envelopeCase.type === \"node\") {\n // Traverse subject\n removeAllFound(envelopeCase.subject, target);\n\n // Traverse all assertions\n for (const assertion of envelopeCase.assertions) {\n removeAllFound(assertion, target);\n if (target.size === 0) break;\n }\n } else if (envelopeCase.type === \"wrapped\") {\n // Traverse wrapped envelope\n removeAllFound(envelopeCase.envelope, target);\n } else if (envelopeCase.type === \"assertion\") {\n // Traverse predicate and object\n const predicate = envelopeCase.assertion.predicate();\n const object = envelopeCase.assertion.object();\n removeAllFound(predicate, target);\n if (target.size > 0) {\n removeAllFound(object, target);\n }\n }\n // For leaf envelopes (elided, encrypted, compressed, leaf), no further traversal needed\n}\n\n/// Helper function to check if a set contains a digest (by hex comparison)\nfunction containsDigest(set: Set<Digest>, digest: Digest): boolean {\n const hexToFind = digest.hex();\n for (const d of set) {\n if (d.hex() === hexToFind) {\n return true;\n }\n }\n return false;\n}\n\n/// Helper function to remove a digest from a set (by hex comparison)\nfunction removeDigest(set: Set<Digest>, digest: Digest): void {\n const hexToFind = digest.hex();\n for (const d of set) {\n if (d.hex() === hexToFind) {\n set.delete(d);\n return;\n }\n }\n}\n\n/// Helper function to check if one set is a subset of another (by hex comparison)\nfunction isSubset(subset: Set<Digest>, superset: Set<Digest>): boolean {\n for (const digest of subset) {\n if (!containsDigest(superset, digest)) {\n return false;\n }\n }\n return true;\n}\n\n// Export empty object to make this a module\nexport {};\n","import { Envelope } from \"../base/envelope\";\nimport { cborData } from \"@bcts/dcbor\";\n\n/// Hex formatting for Gordian Envelopes.\n///\n/// This module provides methods for converting envelopes to hexadecimal\n/// representations of their CBOR encoding, useful for debugging and\n/// low-level inspection.\n\n// Note: Method declarations are in the base Envelope class.\n// This module provides the prototype implementations.\n\n/// Implementation of hex()\nEnvelope.prototype.hex = function (this: Envelope): string {\n const bytes = this.cborBytes();\n return Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n};\n\n/// Implementation of cborBytes()\nEnvelope.prototype.cborBytes = function (this: Envelope): Uint8Array {\n const cbor = this.taggedCbor();\n return cborData(cbor);\n};\n","import { Envelope } from \"../base/envelope\";\n\n// Type for CBOR values that can appear in diagnostic notation\ntype CborValue =\n | string\n | number\n | boolean\n | null\n | Uint8Array\n | CborValue[]\n | Map<CborValue, CborValue>\n | { tag: number; value: CborValue }\n | { type: number; value: unknown };\n\n/// Diagnostic notation formatting for Gordian Envelopes.\n///\n/// This module provides methods for converting envelopes to CBOR diagnostic\n/// notation, a human-readable text format defined in RFC 8949 §8.\n///\n/// See [RFC-8949 §8](https://www.rfc-editor.org/rfc/rfc8949.html#name-diagnostic-notation)\n/// for information on CBOR diagnostic notation.\n\n// Note: Method declarations are in the base Envelope class.\n// This module provides the prototype implementations.\n\n/// Converts a CBOR value to diagnostic notation\nfunction cborToDiagnostic(cbor: CborValue, indent = 0): string {\n // Handle tagged values (CBOR tags)\n if (typeof cbor === \"object\" && cbor !== null && \"tag\" in cbor && \"value\" in cbor) {\n const tagged = cbor as { tag: number; value: CborValue };\n return `${tagged.tag}(${cborToDiagnostic(tagged.value, indent)})`;\n }\n\n // Handle arrays\n if (Array.isArray(cbor)) {\n if (cbor.length === 0) {\n return \"[]\";\n }\n const items = cbor.map((item) => cborToDiagnostic(item, indent + 2));\n return `[${items.join(\", \")}]`;\n }\n\n // Handle Maps\n if (cbor instanceof Map) {\n if (cbor.size === 0) {\n return \"{}\";\n }\n const entries: string[] = [];\n for (const [key, value] of cbor) {\n const keyStr = cborToDiagnostic(key, indent + 2);\n const valueStr = cborToDiagnostic(value, indent + 2);\n entries.push(`${keyStr}: ${valueStr}`);\n }\n return `{${entries.join(\", \")}}`;\n }\n\n // Handle Uint8Array (byte strings)\n if (cbor instanceof Uint8Array) {\n const hex = Array.from(cbor)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n return `h'${hex}'`;\n }\n\n // Handle strings\n if (typeof cbor === \"string\") {\n return JSON.stringify(cbor);\n }\n\n // Handle CBOR objects with type information\n if (typeof cbor === \"object\" && cbor !== null && \"type\" in cbor) {\n const typed = cbor as { type: number; value: unknown };\n switch (typed.type) {\n case 0: // Unsigned\n return String(typed.value);\n case 1: // Negative\n return String(-1 - Number(typed.value));\n case 7: {\n // Simple\n const simpleValue = typed.value;\n if (simpleValue !== null && typeof simpleValue === \"object\" && \"type\" in simpleValue) {\n const floatValue = simpleValue as { type: string; value: unknown };\n if (floatValue.type === \"Float\") {\n return String(floatValue.value);\n }\n }\n if (simpleValue === 20) return \"false\";\n if (simpleValue === 21) return \"true\";\n if (simpleValue === 22) return \"null\";\n if (simpleValue === 23) return \"undefined\";\n return `simple(${String(simpleValue)})`;\n }\n }\n }\n\n // Fallback for primitives\n if (typeof cbor === \"boolean\") return String(cbor);\n if (typeof cbor === \"number\") return String(cbor);\n if (typeof cbor === \"bigint\") return String(cbor);\n if (cbor === null) return \"null\";\n if (cbor === undefined) return \"undefined\";\n\n // Unknown type - try JSON stringify\n try {\n return JSON.stringify(cbor);\n } catch {\n // eslint-disable-next-line @typescript-eslint/no-base-to-string\n return String(cbor);\n }\n}\n\n/// Implementation of diagnostic()\nEnvelope.prototype.diagnostic = function (this: Envelope): string {\n const cbor = this.taggedCbor();\n return cborToDiagnostic(cbor);\n};\n","import { Envelope } from \"../base/envelope\";\nimport { type EdgeType, edgeLabel } from \"../base/walk\";\n\n/// Tree formatting for Gordian Envelopes.\n///\n/// This module provides functionality for creating textual tree\n/// representations of envelopes, which is useful for debugging and visualizing\n/// the hierarchical structure of complex envelopes.\n///\n/// The tree format displays each component of an envelope (subject and\n/// assertions) as nodes in a tree, making it easy to understand the\n/// hierarchical structure of nested envelopes. Each node includes:\n///\n/// - The first 8 characters of the element's digest (for easy reference)\n/// - The type of the element (NODE, ASSERTION, ELIDED, etc.)\n/// - The content of the element (for leaf nodes)\n\n/// Options for tree formatting\nexport interface TreeFormatOptions {\n /// If true, hides NODE identifiers and only shows semantic content\n hideNodes?: boolean;\n /// Set of digest strings to highlight in the tree\n highlightDigests?: Set<string>;\n /// Format for displaying digests\n digestDisplay?: \"short\" | \"full\";\n}\n\n/// Represents an element in the tree representation\ninterface TreeElement {\n /// Indentation level\n level: number;\n /// The envelope element\n envelope: Envelope;\n /// Type of incoming edge\n incomingEdge: EdgeType;\n /// Whether to show the digest ID\n showId: boolean;\n /// Whether this element is highlighted\n isHighlighted: boolean;\n}\n\n// Note: Method declarations are in the base Envelope class.\n// This module provides the prototype implementations.\n\n/// Implementation of shortId()\nEnvelope.prototype.shortId = function (this: Envelope, format: \"short\" | \"full\" = \"short\"): string {\n const digest = this.digest();\n if (format === \"full\") {\n return digest.hex();\n }\n return digest.short();\n};\n\n/// Implementation of summary()\nEnvelope.prototype.summary = function (this: Envelope, maxLength = 40): string {\n const c = this.case();\n\n switch (c.type) {\n case \"node\":\n return \"NODE\";\n case \"leaf\": {\n // Try to extract a readable value\n try {\n const text = this.asText();\n if (text !== undefined) {\n const truncated = text.length > maxLength ? `${text.substring(0, maxLength)}...` : text;\n return JSON.stringify(truncated);\n }\n } catch {\n // Fall through\n }\n\n try {\n const num = this.extractNumber();\n return String(num);\n } catch {\n // Fall through\n }\n\n try {\n const bool = this.extractBoolean();\n return String(bool);\n } catch {\n // Fall through\n }\n\n if (this.isNull()) {\n return \"null\";\n }\n\n // Fallback: show byte string\n const bytes = this.asByteString();\n if (bytes !== undefined && bytes.length <= 16) {\n const hex = Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n return `h'${hex}'`;\n }\n\n return \"LEAF\";\n }\n case \"wrapped\":\n return \"WRAPPED\";\n case \"assertion\":\n return \"ASSERTION\";\n case \"elided\":\n return \"ELIDED\";\n case \"encrypted\":\n return \"ENCRYPTED\";\n case \"compressed\":\n return \"COMPRESSED\";\n case \"knownValue\":\n return \"KNOWN_VALUE\";\n default:\n return \"UNKNOWN\";\n }\n};\n\n/// Implementation of treeFormat()\nEnvelope.prototype.treeFormat = function (this: Envelope, options: TreeFormatOptions = {}): string {\n const hideNodes = options.hideNodes ?? false;\n const highlightDigests = options.highlightDigests ?? new Set<string>();\n const digestDisplay = options.digestDisplay ?? \"short\";\n\n const elements: TreeElement[] = [];\n\n // Walk the envelope and collect elements\n this.walk(hideNodes, undefined, (envelope, level, incomingEdge, _state) => {\n const digestStr = envelope.digest().short();\n const isHighlighted = highlightDigests.has(digestStr);\n\n elements.push({\n level,\n envelope,\n incomingEdge,\n showId: !hideNodes,\n isHighlighted,\n });\n\n return [undefined, false];\n });\n\n // Format each element as a line\n const lines = elements.map((elem) => {\n const parts: string[] = [];\n\n if (elem.isHighlighted) {\n parts.push(\"*\");\n }\n\n if (elem.showId) {\n parts.push(elem.envelope.shortId(digestDisplay));\n }\n\n const label = edgeLabel(elem.incomingEdge);\n if (label !== undefined && label !== \"\") {\n parts.push(label);\n }\n\n parts.push(elem.envelope.summary(40));\n\n const line = parts.join(\" \");\n const indent = \" \".repeat(elem.level * 4);\n return indent + line;\n });\n\n return lines.join(\"\\n\");\n};\n","/**\n * String utility functions used throughout the envelope library.\n *\n * Provides helper methods for string formatting and manipulation.\n */\n\n/**\n * Flanks a string with specified left and right delimiters.\n *\n * @param str - The string to flank\n * @param left - The left delimiter\n * @param right - The right delimiter\n * @returns The flanked string\n *\n * @example\n * ```typescript\n * flanked('hello', '\"', '\"') // Returns: \"hello\"\n * flanked('name', \"'\", \"'\") // Returns: 'name'\n * flanked('item', '[', ']') // Returns: [item]\n * ```\n */\nexport function flanked(str: string, left: string, right: string): string {\n return `${left}${str}${right}`;\n}\n\n/**\n * Extension methods for String objects to support fluent API style.\n */\ndeclare global {\n interface String {\n /**\n * Flanks this string with specified left and right delimiters.\n *\n * @param left - The left delimiter\n * @param right - The right delimiter\n * @returns The flanked string\n */\n flankedBy(left: string, right: string): string;\n }\n}\n\n// Extend String prototype with flankedBy method\nString.prototype.flankedBy = function (this: string, left: string, right: string): string {\n return flanked(this, left, right);\n};\n\n// Export the extension for side-effects\nexport {};\n","/// Gordian Envelope TypeScript Library\n///\n/// A TypeScript implementation of Blockchain Commons' Gordian Envelope\n/// specification for structured, privacy-focused data containers.\n///\n/// This is a 1:1 port of the Rust bc-envelope library, maintaining the same\n/// API structure and functionality.\n///\n/// @module bc-envelope\n\n// Re-export everything from the base module\nexport * from \"./base\";\n\n// Re-export everything from the extension module\nexport * from \"./extension\";\n\n// Import registration functions and call them to ensure proper initialization order\nimport { registerEncryptExtension } from \"./extension/encrypt\";\nimport { registerCompressExtension } from \"./extension/compress\";\nregisterEncryptExtension();\nregisterCompressExtension();\n\n// Re-export everything from the format module\n// Import for side effects (registers prototype extensions like treeFormat)\nimport \"./format\";\nexport type * from \"./format\";\n\n// Re-export everything from the utils module\nexport * from \"./utils\";\n\n// Version information\nexport const VERSION = \"0.37.0\";\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAUA,IAAa,SAAb,MAAa,OAAO;CAClB,CAASA;CAMT,YAAY,MAAkB;AAC5B,MAAI,KAAK,WAAW,GAClB,OAAM,IAAI,MAAM,wCAAwC,KAAK,OAAO,QAAQ;AAE9E,QAAKA,OAAQ;;CAMf,OAAmB;AACjB,SAAO,MAAKA;;CAed,OAAO,UAAU,OAA2B;AAE1C,SAAO,IAAI,iCADS,MAAM,CACH;;CAiBzB,OAAO,YAAY,SAA2B;EAC5C,MAAM,cAAc,QAAQ,SAAS;EACrC,MAAM,WAAW,IAAI,WAAW,YAAY;EAC5C,IAAI,SAAS;AACb,OAAK,MAAM,UAAU,SAAS;AAC5B,YAAS,IAAI,OAAO,MAAM,EAAE,OAAO;AACnC,aAAU;;AAEZ,SAAO,OAAO,UAAU,SAAS;;CAYnC,MAAc;AACZ,SAAO,MAAM,KAAK,MAAKA,KAAM,CAC1B,KAAK,MAAM,EAAE,SAAS,GAAG,CAAC,SAAS,GAAG,IAAI,CAAC,CAC3C,KAAK,GAAG;;CAgBb,QAAgB;AACd,SAAO,KAAK,KAAK,CAAC,UAAU,GAAG,EAAE;;CAanC,OAAO,QAAQ,KAAqB;AAClC,MAAI,IAAI,WAAW,GACjB,OAAM,IAAI,MAAM,iDAAiD,IAAI,SAAS;EAEhF,MAAM,OAAO,IAAI,WAAW,GAAG;AAC/B,OAAK,IAAI,IAAI,GAAG,IAAI,IAAI,IACtB,MAAK,KAAK,SAAS,IAAI,UAAU,IAAI,GAAG,IAAI,IAAI,EAAE,EAAE,GAAG;AAEzD,SAAO,IAAI,OAAO,KAAK;;CAOzB,OAAO,OAAwB;AAC7B,MAAI,MAAKA,KAAM,WAAW,OAAMA,KAAM,OACpC,QAAO;AAET,OAAK,IAAI,IAAI,GAAG,IAAI,MAAKA,KAAM,QAAQ,IACrC,KAAI,MAAKA,KAAM,OAAO,OAAMA,KAAM,GAChC,QAAO;AAGX,SAAO;;CAMT,WAAmB;AACjB,SAAO,KAAK,OAAO;;CAMrB,QAAgB;AACd,SAAO,IAAI,OAAO,IAAI,WAAW,MAAKA,KAAM,CAAC;;;;;;AC/IjD,IAAY,kDAAL;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AAGA;AACA;AAGA;AAGA;AAGA;AAGA;AACA;AACA;AACA;AACA;AAGA;AACA;AAGA;AACA;AAGA;AACA;AAGA;AACA;AACA;;;AAGF,IAAa,gBAAb,MAAa,sBAAsB,MAAM;CACvC,AAAS;CAGT,YAAY,MAAiB,SAAiB,OAAe;AAC3D,QAAM,QAAQ;AACd,OAAK,OAAO;AACZ,OAAK,OAAO;AACZ,MAAI,UAAU,OACZ,MAAK,QAAQ;AAIf,MAAI,uBAAuB,MACzB,CACE,MAGA,kBAAkB,MAAM,cAAc;;CAY5C,OAAO,gBAA+B;AACpC,SAAO,IAAI,cACT,UAAU,gBACV,+DACD;;CASH,OAAO,qBAAoC;AACzC,SAAO,IAAI,cACT,UAAU,qBACV,gDACD;;CAOH,OAAO,gBAA+B;AACpC,SAAO,IAAI,cAAc,UAAU,gBAAgB,uBAAuB;;CAO5E,OAAO,gBAA+B;AACpC,SAAO,IAAI,cAAc,UAAU,gBAAgB,iBAAiB;;CAOtE,OAAO,gBAA+B;AACpC,SAAO,IAAI,cAAc,UAAU,gBAAgB,sCAAsC;;CAQ3F,OAAO,uBAAsC;AAC3C,SAAO,IAAI,cAAc,UAAU,uBAAuB,qCAAqC;;CAOjG,OAAO,aAA4B;AACjC,SAAO,IAAI,cACT,UAAU,aACV,iDACD;;CAQH,OAAO,UAAyB;AAC9B,SAAO,IAAI,cAAc,UAAU,UAAU,uCAAuC;;CAQtF,OAAO,eAA8B;AACnC,SAAO,IAAI,cAAc,UAAU,eAAe,6CAA6C;;CAIjG,OAAO,mBAAkC;AACvC,SAAO,IAAI,cACT,UAAU,mBACV,mDACD;;CAUH,OAAO,oBAAmC;AACxC,SAAO,IAAI,cAAc,UAAU,oBAAoB,qBAAqB;;CAO9E,OAAO,wBAAuC;AAC5C,SAAO,IAAI,cAAc,UAAU,wBAAwB,yBAAyB;;CAOtF,OAAO,sBAAqC;AAC1C,SAAO,IAAI,cAAc,UAAU,sBAAsB,uBAAuB;;CAUlF,OAAO,oBAAmC;AACxC,SAAO,IAAI,cAAc,UAAU,oBAAoB,kCAAkC;;CAQ3F,OAAO,gBAA+B;AACpC,SAAO,IAAI,cACT,UAAU,gBACV,wDACD;;CAWH,OAAO,mBAAkC;AACvC,SAAO,IAAI,cACT,UAAU,mBACV,0EACD;;CAOH,OAAO,eAA8B;AACnC,SAAO,IAAI,cACT,UAAU,eACV,oDACD;;CAWH,OAAO,gBAA+B;AACpC,SAAO,IAAI,cACT,UAAU,iBACV,8CACD;;CAUH,OAAO,mBAAkC;AACvC,SAAO,IAAI,cAAc,UAAU,mBAAmB,oBAAoB;;CAU5E,OAAO,gBAA+B;AACpC,SAAO,IAAI,cAAc,UAAU,gBAAgB,mBAAmB;;CASxE,OAAO,sBAAqC;AAC1C,SAAO,IAAI,cAAc,UAAU,sBAAsB,+BAA+B;;CAI1F,OAAO,4BAA2C;AAChD,SAAO,IAAI,cACT,UAAU,8BACV,yCACD;;CAIH,OAAO,4BAA2C;AAChD,SAAO,IAAI,cACT,UAAU,8BACV,yCACD;;CAKH,OAAO,2BAA0C;AAC/C,SAAO,IAAI,cACT,UAAU,4BACV,4DACD;;CAIH,OAAO,uBAAsC;AAC3C,SAAO,IAAI,cAAc,UAAU,wBAAwB,mCAAmC;;CAWhG,OAAO,gBAA+B;AACpC,SAAO,IAAI,cAAc,UAAU,gBAAgB,sBAAsB;;CAI3E,OAAO,KAAK,SAAiB,OAA8B;AACzD,SAAO,IAAI,cAAc,UAAU,MAAM,eAAe,WAAW,MAAM;;CAS3E,OAAO,cAA6B;AAClC,SAAO,IAAI,cAAc,UAAU,cAAc,eAAe;;CAOlE,OAAO,gBAA+B;AACpC,SAAO,IAAI,cAAc,UAAU,gBAAgB,iBAAiB;;CAStE,OAAO,uBAAsC;AAC3C,SAAO,IAAI,cAAc,UAAU,wBAAwB,yBAAyB;;CAItF,OAAO,kBAAiC;AACtC,SAAO,IAAI,cAAc,UAAU,kBAAkB,mBAAmB;;CAM1E,OAAO,KAAK,SAAiB,OAA8B;AACzD,SAAO,IAAI,cAAc,UAAU,MAAM,gBAAgB,WAAW,MAAM;;CAI5E,OAAO,WAAW,SAAiB,OAA8B;AAC/D,SAAO,IAAI,cAAc,UAAU,YAAY,qBAAqB,WAAW,MAAM;;CAIvF,OAAO,QAAQ,SAAiB,OAA8B;AAC5D,SAAO,IAAI,cAAc,UAAU,SAAS,kBAAkB,WAAW,MAAM;;CAIjF,OAAO,IAAI,SAAgC;AACzC,SAAO,cAAc,QAAQ,QAAQ;;;;;;AClYzC,IAAa,YAAb,MAAa,UAAoC;CAC/C,CAASC;CACT,CAASC;CACT,CAASC;CA6BT,YAAY,WAAyC,QAAsC;AACzF,QAAKF,YAAa,qBAAqB,WAAW,YAAY,SAAS,IAAI,UAAU;AACrF,QAAKC,SAAU,kBAAkB,WAAW,SAAS,SAAS,IAAI,OAAO;AACzE,QAAKC,SAAU,OAAO,YAAY,CAAC,MAAKF,UAAW,QAAQ,EAAE,MAAKC,OAAQ,QAAQ,CAAC,CAAC;;CAStF,YAAsB;AACpB,SAAO,MAAKD;;CASd,SAAmB;AACjB,SAAO,MAAKC;;CAQd,SAAiB;AACf,SAAO,MAAKC;;CAUd,OAAO,OAA2B;AAChC,SAAO,MAAKA,OAAQ,OAAO,OAAMA,OAAQ;;CAU3C,SAAe;EACb,MAAM,MAAM,IAAIC,sBAAS;AACzB,MAAI,IAAI,MAAKH,UAAW,cAAc,EAAE,MAAKC,OAAQ,cAAc,CAAC;AACpE,SAAO;;CAWT,OAAO,SAAS,QAAuB;AAErC,MAAI,EAAEG,kBAAgBD,sBACpB,OAAM,cAAc,kBAAkB;AAGxC,SAAO,UAAU,YAAYC,OAAK;;CAYpC,OAAO,YAAY,KAAyB;AAC1C,MAAI,IAAI,SAAS,EACf,OAAM,cAAc,kBAAkB;EAIxC,MAAM,aADU,MAAM,KAAK,IAAI,SAAS,CAAC,CACd;AAC3B,MAAI,eAAe,OACjB,OAAM,cAAc,kBAAkB;EAExC,MAAM,CAAC,eAAe,cAAc;AAMpC,SAAO,IAAI,UAJO,SAAS,iBAAiB,cAAc,EAE3C,SAAS,iBAAiB,WAAW,CAEb;;CAMzC,WAAmB;AACjB,SAAO,aAAa,OAAO,MAAKJ,UAAW,CAAC,IAAI,OAAO,MAAKC,OAAQ,CAAC;;CASvE,QAAmB;AACjB,SAAO;;;;;;AC1IX,IAAa,aAAb,MAAa,WAAW;CACtB,CAASI;CACT,CAASC;CAET,YAAY,gBAA4B,QAAiB;AACvD,QAAKD,iBAAkB;AACvB,MAAI,WAAW,OACb,OAAKC,SAAU;;CAKnB,OAAO,qBAAqB,kBAA8B,QAA6B;AAErF,SAAO,IAAI,WADQ,KAAK,QAAQ,iBAAiB,EACf,OAAO;;CAI3C,iBAA6B;AAC3B,SAAO,MAAKD;;CAId,YAAgC;AAC9B,SAAO,MAAKC;;CAId,aAAyB;AACvB,SAAO,KAAK,QAAQ,MAAKD,eAAgB;;;AA4H7C,SAAgB,4BAAkC;AAChD,KAAI,UAAU,cAAc,OAC1B;AAIF,KAAI,OAAO,SAAS,UAAU,aAAa,WACzC;AAGF,UAAS,UAAU,WAAW,WAAoC;EAChE,MAAM,IAAI,KAAK,MAAM;AAGrB,MAAI,EAAE,SAAS,aACb,QAAO;AAIT,MAAI,EAAE,SAAS,YACb,OAAM,cAAc,QAAQ,qCAAqC;AAEnE,MAAI,EAAE,SAAS,SACb,OAAM,cAAc,QAAQ,kCAAkC;EAMhE,MAAM,8CAFO,KAAK,YAAY,CAES;EAEvC,MAAM,aAAa,WAAW,qBAAqB,kBAAkB,KAAK,QAAQ,CAAC;AAGnF,SAAO,SAAS,SAAS;GAAE,MAAM;GAAc,OAAO;GAAY,CAAC;;AAIrE,UAAS,UAAU,aAAa,WAAoC;EAClE,MAAM,IAAI,KAAK,MAAM;AAErB,MAAI,EAAE,SAAS,aACb,OAAM,cAAc,QAAQ,6BAA6B;EAG3D,MAAM,aAAa,EAAE;EACrB,MAAM,SAAS,WAAW,WAAW;AAErC,MAAI,WAAW,OACb,OAAM,cAAc,QAAQ,wCAAwC;AAItE,MAAI,CAAC,OAAO,OAAO,KAAK,QAAQ,CAAC,CAC/B,OAAM,cAAc,QAAQ,wCAAwC;EAQtE,MAAME,sCAJmB,WAAW,YAAY,CAIP;EACzC,MAAM,WAAW,SAAS,eAAeA,OAAK;AAG9C,MAAI,CAAC,SAAS,QAAQ,CAAC,OAAO,OAAO,CACnC,OAAM,cAAc,QAAQ,qCAAqC;AAGnE,SAAO;;AAIT,UAAS,UAAU,kBAAkB,WAAoC;AACvE,MAAI,KAAK,SAAS,CAAC,cAAc,CAC/B,QAAO;EAGT,MAAM,UAAU,KAAK,SAAS,CAAC,UAAU;AACzC,SAAO,KAAK,eAAe,QAAQ;;AAIrC,UAAS,UAAU,oBAAoB,WAAoC;AACzE,MAAI,KAAK,SAAS,CAAC,cAAc,EAAE;GACjC,MAAM,UAAU,KAAK,SAAS,CAAC,YAAY;AAC3C,UAAO,KAAK,eAAe,QAAQ;;AAGrC,SAAO;;AAIT,UAAS,UAAU,eAAe,WAAmC;AACnE,SAAO,KAAK,MAAM,CAAC,SAAS;;;AAMhC,2BAA2B;;;;ACpP3B,SAASC,oBAAyC;AAChD,QAAO,IAAIC,yCAA6B;;AAK1C,IAAa,eAAb,MAAa,aAAa;CACxB,CAASC;CAET,YAAY,KAAiB;AAC3B,MAAI,IAAI,WAAWC,iCACjB,OAAM,IAAI,MAAM,yBAAyBA,iCAAmB,QAAQ;AAEtE,QAAKD,MAAO;;CAId,OAAO,WAAyB;AAG9B,SAAO,IAAI,4CAFCF,mBAAiB,EACEG,iCAAmB,CACtB;;CAI9B,OAAO,KAAK,KAA+B;AACzC,SAAO,IAAI,aAAa,IAAI;;CAI9B,OAAmB;AACjB,SAAO,MAAKD;;CAKd,QAAQ,WAAuB,QAAkC;EAI/D,MAAM,uCAHMF,mBAAiB,EAGII,mCAAqB;EAGtD,MAAM,MAAM,OAAO,MAAM;EAGzB,MAAM,CAAC,YAAY,iEACjB,WACA,MAAKF,KACL,OACA,IACD;AAED,SAAO,IAAI,iBAAiB,YAAY,OAAO,SAAS,OAAO;;CAIjE,QAAQ,SAAuC;EAC7C,MAAM,SAAS,QAAQ,WAAW;AAClC,MAAI,WAAW,OACb,OAAM,cAAc,QAAQ,sCAAsC;EAGpE,MAAM,MAAM,OAAO,MAAM;AAEzB,MAAI;AASF,gEAPE,QAAQ,YAAY,EACpB,MAAKA,KACL,QAAQ,OAAO,EACf,KACA,QAAQ,SAAS,CAClB;WAGM,QAAQ;AACf,SAAM,cAAc,QAAQ,mDAAmD;;;;AAOrF,IAAa,mBAAb,MAA8B;CAC5B,CAASG;CACT,CAASC;CACT,CAASC;CACT,CAASC;CAET,YAAY,YAAwB,OAAmB,SAAqB,WAAoB;AAC9F,QAAKH,aAAc;AACnB,QAAKC,QAAS;AACd,QAAKC,UAAW;AAChB,MAAI,cAAc,OAChB,OAAKC,YAAa;;CAKtB,aAAyB;AACvB,SAAO,MAAKH;;CAId,QAAoB;AAClB,SAAO,MAAKC;;CAId,UAAsB;AACpB,SAAO,MAAKC;;CAId,YAAgC;AAC9B,SAAO,MAAKC;;CAId,SAAiB;AACf,MAAI,MAAKA,cAAe,OACtB,OAAM,IAAI,MAAM,uCAAuC;AAEzD,SAAO,MAAKA;;;AAyFhB,SAAgB,2BAAiC;AAC/C,KAAI,UAAU,cAAc,OAC1B;AAIF,KAAI,OAAO,SAAS,UAAU,mBAAmB,WAC/C;AAGF,UAAS,UAAU,iBAAiB,SAA0B,KAA6B;EACzF,MAAM,IAAI,KAAK,MAAM;AAGrB,MAAI,EAAE,SAAS,YACb,OAAM,cAAc,QAAQ,gCAAgC;AAE9D,MAAI,EAAE,SAAS,SACb,OAAM,cAAc,QAAQ,iCAAiC;AAI/D,MAAI,EAAE,SAAS,QAAQ;AACrB,OAAI,EAAE,QAAQ,aAAa,CACzB,OAAM,cAAc,QAAQ,+BAA+B;GAK7D,MAAMC,2CADc,EAAE,QAAQ,YAAY,CACD;GACzC,MAAM,gBAAgB,EAAE,QAAQ,QAAQ;GAGxC,MAAMC,qBAAmB,IAAI,QAAQD,eAAa,cAAc;GAGhE,MAAM,mBAAmB,SAAS,SAAS;IACzC,MAAM;IACN,SAASC;IACV,CAAC;AAGF,UAAO,SAAS,kBAAkB,kBAAkB,EAAE,WAAW;;EAKnE,MAAM,yCADO,KAAK,YAAY,CACI;EAClC,MAAM,SAAS,KAAK,QAAQ;EAE5B,MAAM,mBAAmB,IAAI,QAAQ,aAAa,OAAO;AAEzD,SAAO,SAAS,SAAS;GACvB,MAAM;GACN,SAAS;GACV,CAAC;;AAIJ,UAAS,UAAU,iBAAiB,SAA0B,KAA6B;EACzF,MAAM,cAAc,KAAK,SAAS,CAAC,MAAM;AAEzC,MAAI,YAAY,SAAS,YACvB,OAAM,cAAc,QAAQ,2BAA2B;EAGzD,MAAM,UAAU,YAAY;EAC5B,MAAM,gBAAgB,QAAQ,WAAW;AAEzC,MAAI,kBAAkB,OACpB,OAAM,cAAc,QAAQ,sCAAsC;EAOpE,MAAMC,sCAHgB,IAAI,QAAQ,QAAQ,CAGJ;EACtC,MAAM,gBAAgB,SAAS,eAAeA,OAAK;AAGnD,MAAI,CAAC,cAAc,QAAQ,CAAC,OAAO,cAAc,CAC/C,OAAM,cAAc,QAAQ,kCAAkC;EAGhE,MAAM,IAAI,KAAK,MAAM;AAGrB,MAAI,EAAE,SAAS,QAAQ;GACrB,MAAM,SAAS,SAAS,kBAAkB,eAAe,EAAE,WAAW;AACtE,OAAI,CAAC,OAAO,QAAQ,CAAC,OAAO,EAAE,OAAO,CACnC,OAAM,cAAc,QAAQ,2CAA2C;AAEzE,UAAO;;AAIT,SAAO;;AAIT,UAAS,UAAU,UAAU,SAA0B,KAA6B;AAClF,SAAO,KAAK,MAAM,CAAC,eAAe,IAAI;;AAIxC,UAAS,UAAU,UAAU,SAA0B,KAA6B;AAElF,SADkB,KAAK,eAAe,IAAI,CACzB,QAAQ;;AAI3B,UAAS,UAAU,cAAc,WAAmC;AAClE,SAAO,KAAK,MAAM,CAAC,SAAS;;;AAMhC,0BAA0B;;;;ACpW1B,MAAMC,iBAAeC,2BAAS;AAC9B,MAAM,WAAWC,uBAAK;AACtB,MAAM,gBAAgBC,4BAAU;AAChC,MAAM,iBAAiBC,6BAAW;AAyHlC,IAAa,WAAb,MAAa,SAAmC;CAC9C,CAASC;CAKT,AAAQ,YAAY,cAA4B;AAC9C,QAAKA,OAAQ;;CAWf,OAAqB;AACnB,SAAO,MAAKA;;CAed,OAAO,IAAI,SAA2C;AAEpD,MAAI,mBAAmB,SACrB,QAAO;AAIT,SAAO,SAAS,QAAQ,QAAQ;;CAOlC,OAAO,UAAU,SAAuD;AACtE,MAAI,YAAY,UAAa,YAAY,KACvC,QAAO,SAAS,MAAM;AAExB,SAAO,SAAS,IAAI,QAAQ;;CAO9B,OAAO,UAAU,SAAmE;AAClF,MAAI,YAAY,UAAa,YAAY,KACvC;AAEF,SAAO,SAAS,IAAI,QAAQ;;CAU9B,OAAO,SAAS,cAAsC;AACpD,SAAO,IAAI,SAAS,aAAa;;CAanC,OAAO,aAAa,WAAmC,QAA0C;EAC/F,MAAM,eAAe,qBAAqB,WAAW,YAAY,SAAS,IAAI,UAAU;EACxF,MAAM,YAAY,kBAAkB,WAAW,SAAS,SAAS,IAAI,OAAO;AAC5E,SAAO,SAAS,iBAAiB,IAAI,UAAU,cAAc,UAAU,CAAC;;CAM1E,OAAO,OAAiB;AACtB,SAAO,SAAS,QAAQ,KAAK;;CAc/B,OAAO,2BAA2B,SAAmB,qBAA2C;AAC9F,MAAI,oBAAoB,WAAW,EACjC,OAAM,IAAI,MAAM,mCAAmC;EAIrD,MAAM,mBAAmB,CAAC,GAAG,oBAAoB,CAAC,MAAM,GAAG,MAAM;GAC/D,MAAM,OAAO,EAAE,QAAQ,CAAC,KAAK;GAC7B,MAAM,OAAO,EAAE,QAAQ,CAAC,KAAK;AAC7B,UAAO,KAAK,cAAc,KAAK;IAC/B;EAGF,MAAM,UAAU,CAAC,QAAQ,QAAQ,EAAE,GAAG,iBAAiB,KAAK,MAAM,EAAE,QAAQ,CAAC,CAAC;AAG9E,SAAO,IAAI,SAAS;GAClB,MAAM;GACN;GACA,YAAY;GACZ,QANa,OAAO,YAAY,QAAQ;GAOzC,CAAC;;CAWJ,OAAO,kBAAkB,SAAmB,YAAkC;AAE5E,OAAK,MAAM,aAAa,WACtB,KAAI,CAAC,UAAU,oBAAoB,IAAI,CAAC,UAAU,mBAAmB,CACnE,OAAM,cAAc,eAAe;AAIvC,SAAO,SAAS,2BAA2B,SAAS,WAAW;;CAOjE,OAAO,iBAAiB,WAAgC;AACtD,SAAO,IAAI,SAAS;GAClB,MAAM;GACN;GACD,CAAC;;CAOJ,OAAO,kBAAkB,OAA+C;EACtE,MAAM,aAAa,iBAAiBC,iCAAa,QAAQ,IAAIA,+BAAW,MAAM;AAG9E,SAAO,IAAI,SAAS;GAClB,MAAM;GACN,OAAO;GACP,QAJa,OAAO,UAAU,WAAW,YAAY,CAAC;GAKvD,CAAC;;CAQJ,OAAO,iBAAiB,kBAA8C;AAKpE,SAAO,IAAI,SAAS;GAClB,MAAM;GACN,SAAS;GACV,CAAC;;CAQJ,OAAO,kBAAkB,YAAkC;AAKzD,SAAO,IAAI,SAAS;GAClB,MAAM;GACN,OAAO;GACR,CAAC;;CAOJ,OAAO,UAAU,QAA0B;AACzC,SAAO,IAAI,SAAS;GAClB,MAAM;GACN;GACD,CAAC;;CAOJ,OAAO,QAAQ,OAA0B;EAEvC,MAAMC,SAAO,SAAS,YAAY,MAAM;EAGxC,MAAM,YAAY,SAAS,YAAYA,OAAK;AAG5C,SAAO,IAAI,SAAS;GAClB,MAAM;GACN;GACA,QALa,OAAO,UAAU,UAAU;GAMzC,CAAC;;CAOJ,OAAO,WAAW,UAA8B;AAE9C,SAAO,IAAI,SAAS;GAClB,MAAM;GACN;GACA,QAJa,OAAO,YAAY,CAAC,SAAS,QAAQ,CAAC,CAAC;GAKrD,CAAC;;CAQJ,SAAiB;EACf,MAAM,IAAI,MAAKF;AACf,UAAQ,EAAE,MAAV;GACE,KAAK;GACL,KAAK;GACL,KAAK;GACL,KAAK;GACL,KAAK,aACH,QAAO,EAAE;GACX,KAAK,YACH,QAAO,EAAE,UAAU,QAAQ;GAC7B,KAAK,aAAa;IAEhB,MAAM,SAAS,EAAE,QAAQ,WAAW;AACpC,QAAI,WAAW,OACb,OAAM,IAAI,MAAM,oCAAoC;AAEtD,WAAO;;GAET,KAAK,cAAc;IAEjB,MAAM,SAAS,EAAE,MAAM,WAAW;AAClC,QAAI,WAAW,OACb,OAAM,IAAI,MAAM,qCAAqC;AAEvD,WAAO;;;;CAYb,UAAoB;EAClB,MAAM,IAAI,MAAKA;AACf,UAAQ,EAAE,MAAV;GACE,KAAK,OACH,QAAO,EAAE;GACX,KAAK;GACL,KAAK;GACL,KAAK;GACL,KAAK;GACL,KAAK;GACL,KAAK;GACL,KAAK,aACH,QAAO;;;CAOb,qBAA8B;AAC5B,SAAO,MAAKA,KAAM,SAAS;;CAM7B,oBAA6B;EAC3B,MAAM,IAAI,MAAKA,KAAM;AACrB,SAAO,MAAM,YAAY,MAAM,eAAe,MAAM;;CAWtD,OAAe,YAAY,OAAsB;AAG/C,gCAAY,MAAoC;;CAOlD,OAAe,YAAY,QAAwB;AAGjD,oCAAgBE,OAAK;;CAMvB,eAAqB;EACnB,MAAM,IAAI,MAAKF;AACf,UAAQ,EAAE,MAAV;GACE,KAAK,QAAQ;IAEX,MAAM,SAAS,CAAC,EAAE,QAAQ,cAAc,CAAC;AACzC,SAAK,MAAM,aAAa,EAAE,WACxB,QAAO,KAAK,UAAU,cAAc,CAAC;AAEvC,WAAO,SAAS,YAAY,OAAO;;GAErC,KAAK,OAEH,wCAAqB,UAAU,EAAE,KAAK;GACxC,KAAK,UAEH,QAAO,EAAE,SAAS,YAAY;GAChC,KAAK,YAEH,QAAO,EAAE,UAAU,QAAQ;GAC7B,KAAK,SAEH,QAAO,SAAS,YAAY,EAAE,OAAO,MAAM,CAAC;GAC9C,KAAK,aAEH,OAAM,IAAI,MAAM,2CAA2C;GAC7D,KAAK,aAAa;IAIhB,MAAM,UAAU,EAAE;IAClB,MAAM,SAAS,QAAQ,WAAW;IAClC,MAAM,MACJ,WAAW,SACP;KAAC,QAAQ,YAAY;KAAE,QAAQ,OAAO;KAAE,QAAQ,SAAS;KAAE,OAAO,MAAM;KAAC,GACzE;KAAC,QAAQ,YAAY;KAAE,QAAQ,OAAO;KAAE,QAAQ,SAAS;KAAC;AAChE,2CAAqB,eAAe,SAAS,YAAY,IAAI,CAAC;;GAEhE,KAAK,cAAc;IAGjB,MAAM,SAAS,EAAE,MAAM,WAAW;IAClC,MAAM,OAAO,EAAE,MAAM,gBAAgB;IACrC,MAAM,MAAM,WAAW,SAAY,CAAC,MAAM,OAAO,MAAM,CAAC,GAAG,CAAC,KAAK;AACjE,2CAAqB,gBAAgB,SAAS,YAAY,IAAI,CAAC;;;;CAUrE,aAAmB;AACjB,yCAAqBL,gBAAc,KAAK,cAAc,CAAC;;CAOzD,OAAO,iBAAiB,QAAsB;EAE5C,MAAM,yCAAuBO,OAAK;AAClC,MAAI,WAAW,QAAW;GACxB,MAAM,CAAC,KAAK,QAAQ;AACpB,WAAQ,IAAI,OAAZ;IACE,KAAK;IACL,KAAKC,8BAEH,QAAO,SAAS,QAAQ,KAAK;IAC/B,KAAKR,gBAAc;KAEjB,MAAM,WAAW,SAAS,iBAAiB,KAAK;AAChD,YAAO,SAAS,WAAW,SAAS;;IAEtC,KAAK,gBAAgB;KAEnB,MAAM,oCAAkB,KAAK;AAC7B,SAAI,QAAQ,UAAa,IAAI,SAAS,KAAK,IAAI,SAAS,EACtD,OAAM,cAAc,KAAK,gDAAgD;KAI3E,MAAM,gDAA8B,IAAI,IAAI,EAAE,CAAE;AAChD,SAAI,mBAAmB,OACrB,OAAM,cAAc,KAAK,sCAAsC;KAGjE,MAAM,cAAc,IAAI,WAAW,mCAAiB,IAAI,IAAI,EAAE,CAAE,GAAG;AACnE,SAAI,IAAI,WAAW,KAAK,gBAAgB,OACtC,OAAM,cAAc,KAAK,6BAA6B;KAMxD,MAAM,aAAa,IAAI,WAAW,gBAJnB,gBAAgB,SAAY,IAAI,OAAO,YAAY,GAAG,OAIZ;AACzD,YAAO,SAAS,SAAS;MAAE,MAAM;MAAc,OAAO;MAAY,CAAC;;IAErE,KAAK,eAAe;KAGlB,MAAM,oCAAkB,KAAK;AAC7B,SAAI,QAAQ,UAAa,IAAI,SAAS,KAAK,IAAI,SAAS,EACtD,OAAM,cAAc,KAAK,+CAA+C;KAI1E,MAAM,4CAA0B,IAAI,IAAI,EAAE,CAAE;KAE5C,MAAM,uCAAqB,IAAI,IAAI,EAAE,CAAE;KAEvC,MAAM,yCAAuB,IAAI,IAAI,EAAE,CAAE;AACzC,SAAI,eAAe,UAAa,UAAU,UAAa,YAAY,OACjE,OAAM,cAAc,KAAK,mDAAmD;KAG9E,MAAM,cAAc,IAAI,WAAW,mCAAiB,IAAI,IAAI,EAAE,CAAE,GAAG;AACnE,SAAI,IAAI,WAAW,KAAK,gBAAgB,OACtC,OAAM,cAAc,KAAK,iCAAiC;KAI5D,MAAM,UAAU,IAAI,iBAAiB,YAAY,OAAO,SAFzC,gBAAgB,SAAY,IAAI,OAAO,YAAY,GAAG,OAEG;AACxE,YAAO,SAAS,SAAS;MAAE,MAAM;MAAa;MAAS,CAAC;;IAE1D,QACE,OAAM,cAAc,KAAK,yBAAyB,IAAI,QAAQ;;;EAKpE,MAAM,uCAAqBO,OAAK;AAChC,MAAI,UAAU,QAAW;AACvB,OAAI,MAAM,WAAW,GACnB,OAAM,cAAc,KAAK,iCAAiC;AAE5D,UAAO,SAAS,UAAU,IAAI,OAAO,MAAM,CAAC;;EAI9C,MAAM,sCAAoBA,OAAK;AAC/B,MAAI,UAAU,QAAW;AACvB,OAAI,MAAM,SAAS,EACjB,OAAM,cAAc,KAAK,uCAAuC;GAElE,MAAM,cAAc,MAAM,IAAI,EAAE;AAChC,OAAI,gBAAgB,OAClB,OAAM,cAAc,KAAK,0BAA0B;GAErD,MAAM,UAAU,SAAS,iBAAiB,YAAY;GACtD,MAAME,aAAyB,EAAE;AACjC,QAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;IACrC,MAAM,gBAAgB,MAAM,IAAI,EAAE;AAClC,QAAI,kBAAkB,OACpB,OAAM,cAAc,KAAK,2BAA2B,EAAE,aAAa;AAErE,eAAW,KAAK,SAAS,iBAAiB,cAAc,CAAC;;AAE3D,UAAO,SAAS,kBAAkB,SAAS,WAAW;;EAIxD,MAAM,kCAAgBF,OAAK;AAC3B,MAAI,QAAQ,QAAW;GACrB,MAAM,YAAY,UAAU,YAAY,IAAI;AAC5C,UAAO,SAAS,iBAAiB,UAAU;;AAI7C,MAAIA,OAAK,SAASG,uBAAU,UAAU;GACpC,MAAM,aAAa,IAAIJ,+BAAWC,OAAK,MAAyB;AAChE,UAAO,SAAS,kBAAkB,WAAW;;AAG/C,QAAM,cAAc,KAAK,0BAA0B;;CAOrD,OAAO,eAAe,QAAsB;AAC1C,MAAI;GACF,MAAM,oDAAkCA,QAAMP,eAAa;AAC3D,UAAO,SAAS,iBAAiB,SAAS;WACnC,OAAO;AACd,SAAM,cAAc,KAClB,0BAA0BA,eAAa,IACvC,iBAAiB,QAAQ,QAAQ,OAClC;;;CAgBL,aAAa,WAAmC,QAA0C;EACxF,MAAM,YAAY,SAAS,aAAa,WAAW,OAAO;AAC1D,SAAO,KAAK,qBAAqB,UAAU;;CAO7C,qBAAqB,WAA+B;EAClD,MAAM,IAAI,MAAKK;AAGf,MAAI,EAAE,SAAS,OACb,QAAO,SAAS,kBAAkB,EAAE,SAAS,CAAC,GAAG,EAAE,YAAY,UAAU,CAAC;AAI5E,SAAO,SAAS,kBAAkB,MAAM,CAAC,UAAU,CAAC;;CAMtD,WAAmB;AACjB,SAAO,YAAY,MAAKA,KAAM,KAAK;;CAQrC,QAAkB;AAChB,SAAO;;;;;;AC5rBX,SAAgB,oBAAoB,OAA4C;AAC9E,QACE,OAAO,UAAU,YACjB,UAAU,QACV,kBAAkB,SAClB,OAAQ,MAA4B,iBAAiB;;;;;ACpCzD,MAAM,eAAeM,2BAAS;AAwB9B,IAAa,qBAAb,MAAsD;CACpD,WAA6C;AAC3C,yCAAqB,CAAC,aAAa,CAAC;;CAGtC,OAAO,WAAqB;AAC1B,yCAAqB,CAAC,aAAa,CAAC,CAAC,KAAK,QAAQ,OAAO,IAAI,MAAM,CAAC;;;AAOxE,IAAa,8BAAb,MAAwE;CACtE,YAAY,AAAiBC,UAAoB;EAApB;;CAE7B,WAA6C;AAC3C,yCAAqB,CAAC,aAAa,CAAC;;CAGtC,eAAqB;AACnB,SAAO,KAAK,SAAS,cAAc;;CAGrC,aAAmB;AACjB,SAAO,KAAK,SAAS,YAAY;;;AAOrC,IAAa,8BAAb,MAAyF;CACvF,WAA6C;AAC3C,yCAAqB,CAAC,aAAa,CAAC;;CAGtC,OAAO,iBAAiB,QAAsB;AAC5C,SAAO,SAAS,iBAAiBC,OAAK;;CAGxC,OAAO,eAAe,QAAsB;AAC1C,SAAO,SAAS,eAAeA,OAAK;;CAGtC,iBAAiB,QAAe;AAC9B,SAAO,SAAS,iBAAiBA,OAAK;;CAGxC,eAAe,QAAe;AAC5B,SAAO,SAAS,eAAeA,OAAK;;;AAQxC,SAAgB,eAAe,UAA0B;AACvD,QAAO,SAAS,YAAY;;AAO9B,SAAgB,iBAAiB,QAAsB;AACrD,QAAO,SAAS,eAAeA,OAAK;;AAOtC,SAAgB,gBAAgB,UAAgC;AAC9D,mCAAgB,SAAS,YAAY,CAAC;;AAOxC,SAAgB,kBAAkB,OAA6B;CAC7D,MAAMA,sCAAkB,MAAM;AAC9B,QAAO,SAAS,eAAeA,OAAK;;;;;ACrGtC,SAAgB,cAAc,UAA4B;CACxD,MAAMC,SAAO,SAAS,SAAS;AAC/B,KAAI;AACF,uCAAmBA,OAAK;UACjB,OAAO;AACd,QAAM,cAAc,KAClB,sCACA,iBAAiB,QAAQ,QAAQ,OAClC;;;AASL,SAAgB,cAAc,UAA4B;CACxD,MAAMA,SAAO,SAAS,SAAS;AAG/B,KAAI,UAAUA,OACZ,SAAQA,OAAK,MAAb;EACE,KAAK,EACH,QAAO,OAAOA,OAAK,UAAU,WAAW,OAAOA,OAAK,MAAM,GAAGA,OAAK;EACpE,KAAK,EAIH,QAAO,EADW,OAAOA,OAAK,UAAU,WAAW,OAAOA,OAAK,MAAM,GAAGA,OAAK,SACzD;EAEtB,KAAK;AACH,OACE,OAAOA,OAAK,UAAU,YACtBA,OAAK,UAAU,QACf,UAAUA,OAAK,SACfA,OAAK,MAAM,SAAS,QAEpB,QAAOA,OAAK,MAAM;AAEpB;EACF,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK,EAEH;;AAIN,OAAM,cAAc,KAAK,qCAAqC;;AAQhE,SAAgB,eAAe,UAA6B;CAC1D,MAAMA,SAAO,SAAS,SAAS;AAC/B,KAAI;AACF,uCAAmBA,OAAK;UACjB,OAAO;AACd,QAAM,cAAc,KAClB,uCACA,iBAAiB,QAAQ,QAAQ,OAClC;;;AASL,SAAgB,aAAa,UAAgC;CAC3D,MAAMA,SAAO,SAAS,SAAS;AAC/B,KAAI;AACF,6CAAyBA,OAAK;UACvB,OAAO;AACd,QAAM,cAAc,KAClB,mCACA,iBAAiB,QAAQ,QAAQ,OAClC;;;AAQL,SAAgB,YAAY,UAA0B;AAEpD,8BADa,SAAS,SAAS,CACf,CACd,QAAO;AAET,OAAM,cAAc,KAAK,iCAAiC;;AAiD5D,IAAa,kBAAb,MAAa,gBAAgB;CAM3B,OAAO,YAAY,QAAsB;AACvC,MAAI;AACF,UAAO,SAAS,eAAeA,OAAK;WAC7B,OAAO;AACd,SAAM,cAAc,KAAK,yBAAyB,iBAAiB,QAAQ,QAAQ,OAAU;;;CAUjG,OAAO,gBAAgB,MAA4B;AACjD,MAAI;GACF,MAAMA,sCAAkB,KAAK;AAC7B,UAAO,gBAAgB,YAAYA,OAAK;WACjC,OAAO;AACd,SAAM,cAAc,KAClB,8BACA,iBAAiB,QAAQ,QAAQ,OAClC;;;;AAQP,SAAS,UAAU,UAAU,WAAgC;CAC3D,MAAM,IAAI,KAAK,MAAM;AACrB,KAAI,EAAE,SAAS,OACb,OAAM,cAAc,SAAS;AAE/B,QAAO,EAAE;;AAIX,SAAS,UAAU,gBAAgB,WAAkC;AACnE,QAAO,cAAc,KAAK;;AAG5B,SAAS,UAAU,gBAAgB,WAAkC;AACnE,QAAO,cAAc,KAAK;;AAG5B,SAAS,UAAU,iBAAiB,WAAmC;AACrE,QAAO,eAAe,KAAK;;AAG7B,SAAS,UAAU,eAAe,WAAsC;AACtE,QAAO,aAAa,KAAK;;AAG3B,SAAS,UAAU,cAAc,WAAgC;AAC/D,QAAO,YAAY,KAAK;;;;;AC3N1B,IAAY,sDAAL;AAEL;AAIA;AAIA;;;AAaF,SAAgB,cAA6B;AAC3C,QAAO,EAAE,MAAM,SAAS;;AA4I1B,SAAS,UAAU,QAAQ,WAAoC;AAE7D,KADU,KAAK,MAAM,CACf,SAAS,SACb,QAAO;AAET,QAAO,SAAS,UAAU,KAAK,QAAQ,CAAC;;AAI1C,SAAS,mBACP,UACA,QACA,aACA,QACU;CACV,MAAM,aAAa,SAAS,QAAQ;AASpC,KAR2B,MAAM,KAAK,OAAO,CAAC,MAAM,MAAM,EAAE,OAAO,WAAW,CAAC,KAQpD,aAEzB;MAAI,OAAO,SAAS,QAClB,QAAO,SAAS,OAAO;WACd,OAAO,SAAS,UAEzB,OAAM,IAAI,MAAM,iCAAiC;WACxC,OAAO,SAAS,WAEzB,OAAM,IAAI,MAAM,kCAAkC;;CAItD,MAAM,IAAI,SAAS,MAAM;AAGzB,KAAI,EAAE,SAAS,aAAa;EAG1B,MAAM,kBAAkB,IAAI,UAFV,mBAAmB,EAAE,UAAU,WAAW,EAAE,QAAQ,aAAa,OAAO,EAC3E,mBAAmB,EAAE,UAAU,QAAQ,EAAE,QAAQ,aAAa,OAAO,CAC5B;AACxD,SAAO,SAAS,iBAAiB,gBAAgB;YACxC,EAAE,SAAS,QAAQ;EAC5B,MAAM,gBAAgB,mBAAmB,EAAE,SAAS,QAAQ,aAAa,OAAO;EAChF,MAAM,mBAAmB,EAAE,WAAW,KAAK,MACzC,mBAAmB,GAAG,QAAQ,aAAa,OAAO,CACnD;AACD,SAAO,SAAS,2BAA2B,eAAe,iBAAiB;YAClE,EAAE,SAAS,WAAW;EAC/B,MAAM,iBAAiB,mBAAmB,EAAE,UAAU,QAAQ,aAAa,OAAO;AAClF,SAAO,SAAS,WAAW,eAAe;;AAG5C,QAAO;;AAIT,SAAS,UAAU,6BAA6B,SAE9C,QACA,QACU;AACV,QAAO,mBAAmB,MAAM,QAAQ,OAAO,OAAO;;AAIxD,SAAS,UAAU,mBAAmB,SAA0B,QAA+B;AAC7F,QAAO,mBAAmB,MAAM,QAAQ,OAAO,aAAa,CAAC;;AAI/D,SAAS,UAAU,+BAA+B,SAEhD,QACA,QACU;CACV,MAAM,YAAY,IAAI,IAAI,OAAO,KAAK,MAAM,EAAE,QAAQ,CAAC,CAAC;AACxD,QAAO,mBAAmB,MAAM,WAAW,OAAO,OAAO;;AAI3D,SAAS,UAAU,qBAAqB,SAEtC,QACU;CACV,MAAM,YAAY,IAAI,IAAI,OAAO,KAAK,MAAM,EAAE,QAAQ,CAAC,CAAC;AACxD,QAAO,mBAAmB,MAAM,WAAW,OAAO,aAAa,CAAC;;AAIlE,SAAS,UAAU,gCAAgC,SAEjD,QACA,QACU;AACV,QAAO,KAAK,6BAA6B,CAAC,OAAO,EAAE,OAAO;;AAI5D,SAAS,UAAU,sBAAsB,SAEvC,QACU;AACV,QAAO,KAAK,mBAAmB,CAAC,OAAO,CAAC;;AAI1C,SAAS,UAAU,8BAA8B,SAE/C,QACA,QACU;AACV,QAAO,mBAAmB,MAAM,QAAQ,MAAM,OAAO;;AAIvD,SAAS,UAAU,oBAAoB,SAA0B,QAA+B;AAC9F,QAAO,mBAAmB,MAAM,QAAQ,MAAM,aAAa,CAAC;;AAI9D,SAAS,UAAU,gCAAgC,SAEjD,QACA,QACU;CACV,MAAM,YAAY,IAAI,IAAI,OAAO,KAAK,MAAM,EAAE,QAAQ,CAAC,CAAC;AACxD,QAAO,mBAAmB,MAAM,WAAW,MAAM,OAAO;;AAI1D,SAAS,UAAU,sBAAsB,SAEvC,QACU;CACV,MAAM,YAAY,IAAI,IAAI,OAAO,KAAK,MAAM,EAAE,QAAQ,CAAC,CAAC;AACxD,QAAO,mBAAmB,MAAM,WAAW,MAAM,aAAa,CAAC;;AAIjE,SAAS,UAAU,iCAAiC,SAElD,QACA,QACU;AACV,QAAO,KAAK,8BAA8B,CAAC,OAAO,EAAE,OAAO;;AAI7D,SAAS,UAAU,uBAAuB,SAExC,QACU;AACV,QAAO,KAAK,oBAAoB,CAAC,OAAO,CAAC;;AAI3C,SAAS,UAAU,UAAU,SAA0B,UAA8B;AACnF,KAAI,KAAK,QAAQ,CAAC,OAAO,SAAS,QAAQ,CAAC,CACzC,QAAO;AAET,OAAM,cAAc,eAAe;;AAIrC,SAAS,UAAU,gBAAgB,SAEjC,eACA,cACa;CACb,MAAM,yBAAS,IAAI,KAAa;CAEhC,MAAM,WAAW,aAA6B;AAM5C,MAAI,EAHF,kBAAkB,UAClB,MAAM,KAAK,cAAc,CAAC,MAAM,MAAM,EAAE,OAAO,SAAS,QAAQ,CAAC,CAAC,EAGlE;AAIF,MAAI,aAAa,WAAW,GAAG;AAC7B,UAAO,IAAI,SAAS,QAAQ,CAAC;AAC7B;;EAIF,MAAM,IAAI,SAAS,MAAM;AAczB,MAboB,aAAa,MAAM,gBAAgB;AACrD,OAAI,gBAAgB,YAAY,UAAU,EAAE,SAAS,SACnD,QAAO;AAET,OAAI,gBAAgB,YAAY,aAAa,EAAE,SAAS,YACtD,QAAO;AAET,OAAI,gBAAgB,YAAY,cAAc,EAAE,SAAS,aACvD,QAAO;AAET,UAAO;IACP,CAGA,QAAO,IAAI,SAAS,QAAQ,CAAC;;AAKjC,cAAa,MAAM,QAAQ;AAE3B,QAAO;;AAIT,SAAS,aAAa,UAAoB,SAAsC;AAC9E,SAAQ,SAAS;CAEjB,MAAM,IAAI,SAAS,MAAM;AACzB,KAAI,EAAE,SAAS,QAAQ;AACrB,eAAa,EAAE,SAAS,QAAQ;AAChC,OAAK,MAAM,aAAa,EAAE,WACxB,cAAa,WAAW,QAAQ;YAEzB,EAAE,SAAS,aAAa;AACjC,eAAa,EAAE,UAAU,WAAW,EAAE,QAAQ;AAC9C,eAAa,EAAE,UAAU,QAAQ,EAAE,QAAQ;YAClC,EAAE,SAAS,UACpB,cAAa,EAAE,UAAU,QAAQ;;AAKrC,SAAS,UAAU,cAAc,SAA0B,WAAiC;CAE1F,MAAM,8BAAc,IAAI,KAAuB;AAC/C,MAAK,MAAM,OAAO,UAChB,aAAY,IAAI,IAAI,QAAQ,CAAC,KAAK,EAAE,IAAI;AAG1C,QAAO,mBAAmB,MAAM,YAAY;;AAI9C,SAAS,mBAAmB,UAAoB,aAA8C;CAC5F,MAAM,IAAI,SAAS,MAAM;AAEzB,KAAI,EAAE,SAAS,SAGb,QADoB,YAAY,IAAI,SAAS,QAAQ,CAAC,KAAK,CAAC,IACtC;AAGxB,KAAI,EAAE,SAAS,QAAQ;EACrB,MAAM,aAAa,mBAAmB,EAAE,SAAS,YAAY;EAC7D,MAAM,gBAAgB,EAAE,WAAW,KAAK,MAAM,mBAAmB,GAAG,YAAY,CAAC;AAEjF,MACE,WAAW,cAAc,EAAE,QAAQ,IACnC,cAAc,OAAO,GAAG,MAAM,EAAE,cAAc,EAAE,WAAW,GAAG,CAAC,CAE/D,QAAO;AAGT,SAAO,SAAS,2BAA2B,YAAY,cAAc;;AAGvE,KAAI,EAAE,SAAS,WAAW;EACxB,MAAM,cAAc,mBAAmB,EAAE,UAAU,YAAY;AAC/D,MAAI,YAAY,cAAc,EAAE,SAAS,CACvC,QAAO;AAET,SAAO,SAAS,WAAW,YAAY;;AAGzC,KAAI,EAAE,SAAS,aAAa;EAC1B,MAAM,eAAe,mBAAmB,EAAE,UAAU,WAAW,EAAE,YAAY;EAC7E,MAAM,YAAY,mBAAmB,EAAE,UAAU,QAAQ,EAAE,YAAY;AAEvE,MACE,aAAa,cAAc,EAAE,UAAU,WAAW,CAAC,IACnD,UAAU,cAAc,EAAE,UAAU,QAAQ,CAAC,CAE7C,QAAO;AAGT,SAAO,SAAS,aAAa,cAAc,UAAU;;AAGvD,QAAO;;AAIT,SAAS,UAAU,cAAc,SAE/B,QACA,aACU;AAEV,KAAI,MAAM,KAAK,OAAO,CAAC,MAAM,MAAM,EAAE,OAAO,KAAK,QAAQ,CAAC,CAAC,CACzD,QAAO;CAGT,MAAM,IAAI,KAAK,MAAM;AAErB,KAAI,EAAE,SAAS,QAAQ;EACrB,MAAM,aAAa,EAAE,QAAQ,YAAY,QAAQ,YAAY;EAC7D,MAAM,gBAAgB,EAAE,WAAW,KAAK,MAAM,EAAE,YAAY,QAAQ,YAAY,CAAC;AAEjF,MACE,WAAW,cAAc,EAAE,QAAQ,IACnC,cAAc,OAAO,GAAG,MAAM,EAAE,cAAc,EAAE,WAAW,GAAG,CAAC,CAE/D,QAAO;AAIT,SAAO,SAAS,kBAAkB,YAAY,cAAc;;AAG9D,KAAI,EAAE,SAAS,WAAW;EACxB,MAAM,cAAc,EAAE,SAAS,YAAY,QAAQ,YAAY;AAC/D,MAAI,YAAY,cAAc,EAAE,SAAS,CACvC,QAAO;AAET,SAAO,SAAS,WAAW,YAAY;;AAGzC,KAAI,EAAE,SAAS,aAAa;EAC1B,MAAM,eAAe,EAAE,UAAU,WAAW,CAAC,YAAY,QAAQ,YAAY;EAC7E,MAAM,YAAY,EAAE,UAAU,QAAQ,CAAC,YAAY,QAAQ,YAAY;AAEvE,MACE,aAAa,cAAc,EAAE,UAAU,WAAW,CAAC,IACnD,UAAU,cAAc,EAAE,UAAU,QAAQ,CAAC,CAE7C,QAAO;AAGT,SAAO,SAAS,aAAa,cAAc,UAAU;;AAGvD,QAAO;;AAIT,SAAS,UAAU,gBAAgB,SAA0B,OAA0B;AAGrF,QAAO,KAAK,QAAQ,CAAC,OAAO,MAAM,QAAQ,CAAC,IAAI,KAAK,MAAM,CAAC,SAAS,MAAM,MAAM,CAAC;;;;;ACxfnF,IAAY,gDAAL;AAEL;AAEA;AAEA;AAEA;AAEA;AAEA;;;AAWF,SAAgB,UAAU,UAAwC;AAChE,SAAQ,UAAR;EACE,KAAK,SAAS,QACZ,QAAO;EACT,KAAK,SAAS,QACZ,QAAO;EACT,KAAK,SAAS,UACZ,QAAO;EACT,KAAK,SAAS,OACZ,QAAO;EACT,KAAK,SAAS;EACd,KAAK,SAAS,UACZ;EACF,QACE;;;AAmDN,SAAS,UAAU,OAAO,SAExB,WACA,OACA,OACM;AACN,KAAI,UACF,UAAS,MAAM,GAAG,SAAS,MAAM,OAAO,MAAM;KAE9C,eAAc,MAAM,GAAG,SAAS,MAAM,OAAO,MAAM;;AASvD,SAAS,cACP,UACA,OACA,cACA,OACA,OACM;CAEN,MAAM,CAAC,UAAU,QAAQ,MAAM,UAAU,OAAO,cAAc,MAAM;AACpE,KAAI,KACF;CAGF,MAAM,YAAY,QAAQ;CAC1B,MAAM,IAAI,SAAS,MAAM;AAEzB,SAAQ,EAAE,MAAV;EACE,KAAK;AAEH,iBAAc,EAAE,SAAS,WAAW,SAAS,SAAS,UAAU,MAAM;AAEtE,QAAK,MAAM,aAAa,EAAE,WACxB,eAAc,WAAW,WAAW,SAAS,WAAW,UAAU,MAAM;AAE1E;EAEF,KAAK;AAEH,iBAAc,EAAE,UAAU,WAAW,SAAS,SAAS,UAAU,MAAM;AACvE;EAEF,KAAK;AAEH,iBAAc,EAAE,UAAU,WAAW,EAAE,WAAW,SAAS,WAAW,UAAU,MAAM;AACtF,iBAAc,EAAE,UAAU,QAAQ,EAAE,WAAW,SAAS,QAAQ,UAAU,MAAM;AAChF;EAEF,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK,aAEH;;;AAUN,SAAS,SACP,UACA,OACA,cACA,OACA,OACO;CACP,IAAI,eAAe;CACnB,IAAI,eAAe;AAGnB,KAAI,CAAC,SAAS,QAAQ,EAAE;EACtB,MAAM,CAAC,UAAU,QAAQ,MAAM,UAAU,OAAO,cAAc,aAAa;AAC3E,MAAI,KACF,QAAO;AAET,iBAAe;AACf,iBAAe,QAAQ;;CAGzB,MAAM,IAAI,SAAS,MAAM;AAEzB,SAAQ,EAAE,MAAV;EACE,KAAK,QAAQ;GAEX,MAAM,iBAAiB,SACrB,EAAE,SACF,cACA,SAAS,SACT,cACA,MACD;GAED,MAAM,iBAAiB,eAAe;AACtC,QAAK,MAAM,aAAa,EAAE,WACxB,UAAS,WAAW,gBAAgB,SAAS,WAAW,gBAAgB,MAAM;AAEhF;;EAGF,KAAK;AAEH,YAAS,EAAE,UAAU,cAAc,SAAS,SAAS,cAAc,MAAM;AACzE;EAEF,KAAK;AAEH,YAAS,EAAE,UAAU,WAAW,EAAE,cAAc,SAAS,WAAW,cAAc,MAAM;AACxF,YAAS,EAAE,UAAU,QAAQ,EAAE,cAAc,SAAS,QAAQ,cAAc,MAAM;AAClF;EAEF,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK,aAEH;;AAGJ,QAAO;;;;;AC1ET,SAAS,UAAU,wBAAwB,SAEzC,YACU;AACV,QAAO,WAAW,QAAQ,QAAQ,cAAc,OAAO,qBAAqB,UAAU,EAAE,KAAK;;AAI/F,SAAS,UAAU,+BAA+B,SAEhD,WACU;AACV,KAAI,cAAc,OAChB,QAAO;AAIT,KAAI,CAAC,UAAU,oBAAoB,IAAI,CAAC,UAAU,mBAAmB,CACnE,OAAM,cAAc,eAAe;CAGrC,MAAM,IAAI,KAAK,MAAM;AAGrB,KAAI,EAAE,SAAS,QAAQ;AAGrB,MADoB,EAAE,WAAW,MAAM,MAAM,EAAE,QAAQ,CAAC,OAAO,UAAU,QAAQ,CAAC,CAAC,CAEjF,QAAO;AAIT,SAAO,SAAS,2BAA2B,EAAE,SAAS,CAAC,GAAG,EAAE,YAAY,UAAU,CAAC;;AAIrF,QAAO,SAAS,2BAA2B,KAAK,SAAS,EAAE,CAAC,UAAU,CAAC;;AAIzE,SAAS,UAAU,uBAAuB,SAExC,WACA,QACU;AACV,KAAI,WAAW,UAAa,WAAW,KACrC,QAAO;AAET,QAAO,KAAK,aAAa,WAAW,OAAO;;AAI7C,SAAS,UAAU,6BAA6B,SAE9C,WACA,KACU;AACV,KAAI,IAAI,WAAW,EACjB,QAAO;AAET,QAAO,KAAK,aAAa,WAAW,IAAI;;AAI1C,SAAS,UAAU,gBAAgB,SAA0B,WAAiC;AAC5F,QAAO,UAAU,QAAQ,QAAQ,aAAa,OAAO,qBAAqB,SAAS,EAAE,KAAK;;AAI5F,SAAS,UAAU,iBAAiB,SAElC,WACA,WACA,QACU;AACV,KAAI,UACF,QAAO,KAAK,aAAa,WAAW,OAAO;AAE7C,QAAO;;AAIT,SAAS,UAAU,yBAAyB,SAE1C,WACA,mBACU;AACV,KAAI,UACF,QAAO,KAAK,qBAAqB,kBAAkB;AAErD,QAAO;;AAIT,SAAS,UAAU,kBAAkB,SAA0B,QAA4B;CACzF,MAAM,aAAa,KAAK,YAAY;CACpC,MAAM,eAAe,OAAO,QAAQ;CAEpC,MAAM,QAAQ,WAAW,WAAW,MAAM,EAAE,QAAQ,CAAC,OAAO,aAAa,CAAC;AAE1E,KAAI,UAAU,GAEZ,QAAO;CAIT,MAAM,gBAAgB,CAAC,GAAG,WAAW,MAAM,GAAG,MAAM,EAAE,GAAG,WAAW,MAAM,QAAQ,EAAE,CAAC;AAErF,KAAI,cAAc,WAAW,EAE3B,QAAO,KAAK,SAAS;AAIvB,QAAO,SAAS,2BAA2B,KAAK,SAAS,EAAE,cAAc;;AAI3E,SAAS,UAAU,mBAAmB,SAEpC,WACA,cACU;AACV,QAAO,KAAK,gBAAgB,UAAU,CAAC,qBAAqB,aAAa;;AAI3E,SAAS,UAAU,iBAAiB,SAA0B,SAA6B;AACzF,QAAO,KAAK,YAAY,CAAC,QAAQ,GAAG,MAAM,EAAE,qBAAqB,EAAE,EAAE,QAAQ;;AAI/E,SAAS,UAAU,aAAa,WAAsC;CACpE,MAAM,IAAI,KAAK,MAAM;AACrB,KAAI,EAAE,SAAS,OACb,QAAO,EAAE;AAEX,QAAO,EAAE;;;;;ACjNX,AAAC,SAAkD,QAAQ,WAAsB;AAC/E,QAAO,SAAS,QAAQ,MAAM;;AAIhC,AAAC,SAAiD,OAAO,WAAsB;AAC7E,QAAO,SAAS,QAAQ,KAAK;;AAI/B,SAAS,UAAU,UAAU,WAAmC;AAC9D,KAAI;AACF,SAAO,KAAK,gBAAgB,KAAK;SAC3B;AACN,SAAO;;;AAKX,SAAS,UAAU,SAAS,WAAmC;AAC7D,KAAI;AACF,SAAO,KAAK,gBAAgB,KAAK;SAC3B;AACN,SAAO;;;AAKX,SAAS,UAAU,SAAS,WAAmC;AAC7D,KAAI;AAEF,SAAO,OADO,KAAK,gBAAgB,KACX;SAClB;AACN,SAAO;;;AAKX,SAAS,UAAU,WAAW,WAAmC;CAC/D,MAAM,OAAO,KAAK,QAAQ;AAC1B,KAAI,SAAS,OACX,QAAO;AAGT,mCAAgB,KAAK;;AAIvB,SAAS,UAAU,kBAAkB,WAAmC;AACtE,QAAO,KAAK,SAAS,CAAC,UAAU;;AAIlC,SAAS,UAAU,QAAQ,WAAmC;CAC5D,MAAM,OAAO,KAAK,QAAQ;AAC1B,KAAI,SAAS,OACX,QAAO;AAIT,KAAI,UAAU,QAAQ,KAAK,SAAS,EAClC,gCAAa,KAA+C;AAE9D,QAAO;;AAIT,SAAS,UAAU,eAAe,WAAmC;AACnE,QAAO,KAAK,SAAS,CAAC,OAAO;;AAI/B,SAAS,UAAU,SAAS,WAAmC;AAC7D,KAAI;AACF,OAAK,aAAa;AAClB,SAAO;UACA,QAAQ;AACf,SAAO;;;AAKX,SAAS,UAAU,gBAAgB,WAAsC;AACvE,QAAO,KAAK,cAAc;;AAI5B,SAAS,UAAU,eAAe,WAAkD;AAClF,KAAI;AACF,SAAO,KAAK,cAAc;SACpB;AACN;;;AAKJ,SAAS,UAAU,UAAU,WAAuD;CAClF,MAAM,OAAO,KAAK,QAAQ;AAC1B,KAAI,SAAS,OACX;AAGF,kCAAe,KAAK;;AAItB,SAAS,UAAU,QAAQ,WAA0B;CACnD,MAAM,OAAO,KAAK,QAAQ;AAC1B,KAAI,SAAS,OACX;AAGF,gCAAa,KAAK;;AAIpB,SAAS,UAAU,SAAS,WAA8C;CACxE,MAAM,OAAO,KAAK,QAAQ;AAC1B,KAAI,SAAS,OACX;AAGF,iCAAc,KAAK;;AAIrB,SAAS,UAAU,SAAS,WAA4C;CACtE,MAAM,IAAI,KAAK,MAAM;AACrB,KAAI,EAAE,SAAS,OACb,QAAO,EAAE;;;;;ACtEb,SAAS,UAAU,gBAAgB,WAAmC;CACpE,MAAM,IAAI,KAAK,MAAM;AACrB,QAAO,EAAE,SAAS,UAAU,EAAE,WAAW,SAAS;;AAIpD,SAAS,UAAU,cAAc,WAAgD;AAE/E,QADU,KAAK,MAAM,CACZ,SAAS,cAAc,OAAO;;AAIzC,SAAS,UAAU,eAAe,WAAoC;CACpE,MAAM,SAAS,KAAK,aAAa;AACjC,KAAI,WAAW,OACb,OAAM,cAAc,cAAc;AAEpC,QAAO;;AAIT,SAAS,UAAU,cAAc,WAAgD;CAI/E,MAAM,IADO,KAAK,SAAS,CACZ,MAAM;AACrB,KAAI,EAAE,SAAS,YACb,QAAO,EAAE,UAAU,WAAW;;AAMlC,SAAS,UAAU,eAAe,WAAoC;CACpE,MAAM,SAAS,KAAK,aAAa;AACjC,KAAI,WAAW,OACb,OAAM,cAAc,cAAc;AAEpC,QAAO;;AAIT,SAAS,UAAU,WAAW,WAAgD;CAI5E,MAAM,IADO,KAAK,SAAS,CACZ,MAAM;AACrB,KAAI,EAAE,SAAS,YACb,QAAO,EAAE,UAAU,QAAQ;;AAM/B,SAAS,UAAU,YAAY,WAAoC;CACjE,MAAM,SAAS,KAAK,UAAU;AAC9B,KAAI,WAAW,OACb,OAAM,cAAc,cAAc;AAEpC,QAAO;;AAIT,SAAS,UAAU,cAAc,WAAmC;AAClE,QAAO,KAAK,MAAM,CAAC,SAAS;;AAI9B,SAAS,UAAU,WAAW,WAAmC;AAC/D,QAAO,KAAK,MAAM,CAAC,SAAS;;AAI9B,SAAS,UAAU,SAAS,WAAmC;AAC7D,QAAO,KAAK,MAAM,CAAC,SAAS;;AAI9B,SAAS,UAAU,SAAS,WAAmC;AAC7D,QAAO,KAAK,MAAM,CAAC,SAAS;;AAI9B,SAAS,UAAU,YAAY,WAAmC;AAChE,QAAO,KAAK,MAAM,CAAC,SAAS;;AAI9B,SAAS,UAAU,aAAa,WAAmC;CACjE,MAAM,OAAO,KAAK,MAAM,CAAC;AACzB,QAAO,SAAS,UAAU,SAAS,aAAa,SAAS;;AAI3D,SAAS,UAAU,aAAa,WAAmC;CACjE,MAAM,OAAO,KAAK,MAAM,CAAC;AACzB,QAAO,SAAS,YAAY,SAAS,eAAe,SAAS;;AAI/D,SAAS,UAAU,0BAA0B,SAE3C,WACY;CAEZ,MAAM,kBADe,SAAS,IAAI,UAAU,CACP,QAAQ;AAE7C,QAAO,KAAK,YAAY,CAAC,QAAQ,cAAc;AAE7C,SADa,UAAU,SAAS,CAAC,aAAa,EACjC,QAAQ,CAAC,OAAO,gBAAgB,KAAK;GAClD;;AAIJ,SAAS,UAAU,yBAAyB,SAE1C,WACU;CACV,MAAM,UAAU,KAAK,wBAAwB,UAAU;AAEvD,KAAI,QAAQ,WAAW,EACrB,OAAM,cAAc,sBAAsB;AAE5C,KAAI,QAAQ,SAAS,EACnB,OAAM,cAAc,oBAAoB;AAG1C,QAAO,QAAQ;;AAIjB,SAAS,UAAU,iCAAiC,SAElD,WACsB;CACtB,MAAM,UAAU,KAAK,wBAAwB,UAAU;AAEvD,KAAI,QAAQ,WAAW,EACrB;AAEF,KAAI,QAAQ,SAAS,EACnB,OAAM,cAAc,oBAAoB;AAG1C,QAAO,QAAQ;;AAIjB,SAAS,UAAU,qBAAqB,SAEtC,WACU;CAEV,MAAM,MADY,KAAK,uBAAuB,UAAU,CAClC,UAAU;AAChC,KAAI,QAAQ,OACV,OAAM,cAAc,cAAc;AAEpC,QAAO;;AAIT,SAAS,UAAU,6BAA6B,SAE9C,WACsB;CACtB,MAAM,UAAU,KAAK,wBAAwB,UAAU;AAEvD,KAAI,QAAQ,WAAW,EACrB;AAEF,KAAI,QAAQ,SAAS,EACnB,OAAM,cAAc,oBAAoB;AAI1C,QADY,QAAQ,GAAG,SAAS,CAAC,UAAU;;AAK7C,SAAS,UAAU,sBAAsB,SAEvC,WACY;AACZ,QAAO,KAAK,wBAAwB,UAAU,CAAC,KAAK,cAAc;EAChE,MAAM,MAAM,UAAU,UAAU;AAChC,MAAI,QAAQ,OACV,OAAM,cAAc,cAAc;AAEpC,SAAO;GACP;;AAIJ,SAAS,UAAU,gBAAgB,WAAkC;CACnE,IAAI,QAAQ;CAEZ,MAAM,IAAI,KAAK,MAAM;AACrB,SAAQ,EAAE,MAAV;EACE,KAAK;AACH,YAAS,EAAE,QAAQ,eAAe;AAClC,QAAK,MAAM,aAAa,EAAE,WACxB,UAAS,UAAU,eAAe;AAEpC;EACF,KAAK;AACH,YAAS,EAAE,UAAU,WAAW,CAAC,eAAe;AAChD,YAAS,EAAE,UAAU,QAAQ,CAAC,eAAe;AAC7C;EACF,KAAK;AACH,YAAS,EAAE,SAAS,eAAe;AACnC;EACF,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK,aAEH;;AAGJ,QAAO;;;;;AC7TT,SAAS,UAAU,OAAO,WAAoC;AAC5D,QAAO,SAAS,WAAW,KAAK;;AAIlC,SAAS,UAAU,YAAY,WAAoC;CACjE,MAAM,IAAI,KAAK,SAAS,CAAC,MAAM;AAC/B,KAAI,EAAE,SAAS,UACb,QAAO,EAAE;AAEX,OAAM,cAAc,YAAY;;AAIlC,SAAS,UAAU,SAAS,WAAoC;AAC9D,QAAO,KAAK,WAAW;;;;;ACjBzB,MAAa,OAAO;AAsIpB,IAAI,UAAU,WAAW;AACvB,UAAS,UAAU,UAAU,SAA0B,QAA0C;AAC/F,SAAO,KAAK,aAAa,MAAM,OAAO;;AAIxC,UAAS,UAAU,QAAQ,WAAsC;AAC/D,SAAO,KAAK,oBAAoB,KAAK;;AAIvC,UAAS,UAAU,UAAU,WAAoC;EAC/D,MAAM,IAAI,KAAK,OAAO;AACtB,MAAI,EAAE,WAAW,EACf,OAAM,cAAc,aAAa;AAEnC,MAAI,EAAE,WAAW,EACf,QAAO,EAAE;AAEX,QAAM,cAAc,eAAe;;AAIrC,UAAS,UAAU,UAAU,SAA0B,GAAoC;EACzF,MAAM,IAAI,SAAS,IAAI,EAAE;AACzB,SAAO,KAAK,OAAO,CAAC,MAAM,MAAM,EAAE,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;;AAIhE,UAAS,UAAU,YAAY,SAA0B,GAAiC;AACxF,MAAI,CAAC,KAAK,QAAQ,EAAE,CAClB,OAAM,cAAc,aAAa;;;;;;ACtLvC,MAAa,OAAO;AAGpB,MAAM,gBAAgB;AAGtB,SAAS,kBAAyC;AAChD,QAAO,IAAIC,yCAA6B;;AAI1C,SAAS,oBAAoB,QAAgB,KAAyC;AAEpF,uCADkB,OAAO,iBAAiB,EACV,OAAO;;AAKzC,SAAS,8BAA8B,cAAsB,KAAqC;CAChG,MAAM,YAAY,OAAO,iBAAiB;CAC1C,MAAM,QAAQ;CACd,MAAM,UAAU,KAAK,IAAI,GAAG,KAAK,KAAK,QAAQ,IAAK,CAAC;AAEpD,iDAA+B,WAAW,SAD1B,KAAK,IAAI,UAAU,GAAG,KAAK,KAAK,QAAQ,IAAK,CAAC,CACH;;AAkH7D,IAAI,UAAU,WAAW;AACvB,UAAS,UAAU,UAAU,WAAoC;EAC/D,MAAM,MAAM,iBAAiB;EAC7B,MAAM,eAAe,KAAK,WAAW,CAAC;EAEtC,MAAM,YAAY,oBADD,8BAA8B,cAAc,IAAI,EACjB,IAAI;AACpD,SAAO,KAAK,aAAa,MAAM,UAAU;;AAI3C,UAAS,UAAU,oBAAoB,SAA0B,OAAyB;AACxF,MAAI,QAAQ,cACV,OAAM,cAAc,QAAQ,yBAAyB,cAAc,cAAc,QAAQ;EAE3F,MAAM,YAAY,oBAAoB,MAAM;AAC5C,SAAO,KAAK,aAAa,MAAM,UAAU;;AAI3C,UAAS,UAAU,eAAe,SAA0B,WAAiC;AAC3F,MAAI,UAAU,SAAS,cACrB,OAAM,cAAc,QAClB,yBAAyB,cAAc,cAAc,UAAU,SAChE;AAEH,SAAO,KAAK,aAAa,MAAM,UAAU;;AAI3C,UAAS,UAAU,iBAAiB,SAElC,KACA,KACU;AACV,MAAI,MAAM,cACR,OAAM,cAAc,QAClB,sCAAsC,cAAc,cAAc,MACnE;AAEH,MAAI,MAAM,IACR,OAAM,cAAc,QAClB,uDAAuD,IAAI,OAAO,MACnE;EAEH,MAAM,MAAM,iBAAiB;EAE7B,MAAM,YAAY,6DADuB,KAAK,KAAK,IAAI,EACP,IAAI;AACpD,SAAO,KAAK,aAAa,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;AC/L7C,MAAa,SAAS;;;;;AAMtB,MAAa,cAAc;;;;;AAM3B,MAAa,OAAO;;;;AAKpB,IAAa,YAAb,MAAa,UAAU;CACrB,CAASC;CAET,YAAY,MAAkB;AAC5B,QAAKA,OAAQ;;;;;CAMf,OAAmB;AACjB,SAAO,MAAKA;;;;;CAMd,MAAc;AACZ,SAAO,MAAM,KAAK,MAAKA,KAAM,CAC1B,KAAK,MAAM,EAAE,SAAS,GAAG,CAAC,SAAS,GAAG,IAAI,CAAC,CAC3C,KAAK,GAAG;;;;;CAMb,OAAO,QAAQ,KAAwB;EACrC,MAAM,QAAQ,IAAI,WAAW,IAAI,SAAS,EAAE;AAC5C,OAAK,IAAI,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK,EACnC,OAAM,IAAI,KAAK,SAAS,IAAI,OAAO,GAAG,EAAE,EAAE,GAAG;AAE/C,SAAO,IAAI,UAAU,MAAM;;;;;;;AA6B/B,IAAa,oBAAb,MAAa,kBAAoC;CAC/C,CAASC;CAET,YAAY,YAAwB;AAClC,MAAI,WAAW,WAAWC,qCACxB,OAAM,IAAI,MAAM,uBAAuBA,qCAAuB,QAAQ;AAExE,QAAKD,aAAc;;;;;CAMrB,OAAO,WAA8B;AAGnC,SAAO,IAAI,iDAFC,IAAIE,yCAA6B,EACPD,qCAAuB,CACrB;;;;;CAM1C,OAAO,QAAQ,KAAgC;EAC7C,MAAM,QAAQ,IAAI,WAAW,IAAI,SAAS,EAAE;AAC5C,OAAK,IAAI,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK,EACnC,OAAM,IAAI,KAAK,SAAS,IAAI,OAAO,GAAG,EAAE,EAAE,GAAG;AAE/C,SAAO,IAAI,kBAAkB,MAAM;;;;;CAMrC,YAA8B;AAE5B,SAAO,IAAI,iEADoC,MAAKD,WAAY,CAC1B;;;;;CAMxC,KAAK,MAA6B;AAEhC,SAAO,IAAI,uCADsB,MAAKA,YAAa,KAAK,CACpB;;;;;CAMtC,OAAmB;AACjB,SAAO,MAAKA;;;;;;;AAQhB,IAAa,mBAAb,MAAa,iBAAqC;CAChD,CAASG;CAET,YAAY,WAAuB;AACjC,MACE,UAAU,WAAWC,uCACrB,UAAU,WAAWC,iDAErB,OAAM,IAAI,MACR,sBAAsBD,oCAAsB,yBAAyBC,iDAAmC,uBACzG;AAEH,QAAKF,YAAa;;;;;CAMpB,OAAO,QAAQ,KAA+B;EAC5C,MAAM,QAAQ,IAAI,WAAW,IAAI,SAAS,EAAE;AAC5C,OAAK,IAAI,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK,EACnC,OAAM,IAAI,KAAK,SAAS,IAAI,OAAO,GAAG,EAAE,EAAE,GAAG;AAE/C,SAAO,IAAI,iBAAiB,MAAM;;;;;CAMpC,OAAO,MAAkB,WAA+B;AACtD,MAAI;AACF,yCAAmB,MAAKA,WAAY,UAAU,MAAM,EAAE,KAAK;UACrD;AACN,UAAO;;;;;;CAOX,OAAmB;AACjB,SAAO,MAAKA;;;;;CAMd,MAAc;AACZ,SAAO,MAAM,KAAK,MAAKA,UAAW,CAC/B,KAAK,MAAM,EAAE,SAAS,GAAG,CAAC,SAAS,GAAG,IAAI,CAAC,CAC3C,KAAK,GAAG;;;;;;AAOf,IAAa,oBAAb,MAAa,kBAAkB;CAC7B,CAASG,aAAmC,EAAE;;;;CAK9C,cAAc,WAAmB,QAAoC;EACnE,MAAM,WAAW,IAAI,mBAAmB;AACxC,YAASA,WAAY,KAAK,GAAG,MAAKA,WAAY;AAC9C,YAASA,WAAY,KAAK,CAAC,WAAW,OAAO,CAAC;AAC9C,SAAO;;;;;CAMT,aAAkC;AAChC,SAAO,MAAKA;;;;;CAMd,gBAAyB;AACvB,SAAO,MAAKA,WAAY,SAAS;;;AAuErC,IAAI,UAAU,WAAW;AACvB,UAAS,UAAU,eAAe,SAA0B,QAA0B;AACpF,SAAO,KAAK,yBAAyB,QAAQ,OAAU;;AAGzD,UAAS,UAAU,2BAA2B,SAE5C,QACA,UACU;EACV,MAAM,SAAS,KAAK,SAAS,CAAC,QAAQ;EACtC,MAAM,YAAY,OAAO,KAAK,OAAO,MAAM,CAAC;EAC5C,IAAI,oBAAoB,SAAS,IAAI,UAAU,MAAM,CAAC;AAEtD,MAAI,UAAU,eAAe,KAAK,MAAM;AAEtC,QAAK,MAAM,CAAC,WAAW,WAAW,SAAS,YAAY,CACrD,qBAAoB,kBAAkB,aACpC,WACA,OACD;AAIH,uBAAoB,kBAAkB,MAAM;GAG5C,MAAM,iBAAiB,OAAO,KAAK,kBAAkB,QAAQ,CAAC,MAAM,CAAC;AACrE,uBAAoB,kBAAkB,aAAa,QAAQ,eAAe,MAAM,CAAC;;AAGnF,SAAO,KAAK,aAAa,QAAQ,kBAAkB;;AAGrD,UAAS,UAAU,gBAAgB,SAA0B,SAA6B;AACxF,SAAO,QAAQ,QAAQ,UAAU,WAAW,SAAS,aAAa,OAAO,EAAE,KAAK;;AAGlF,UAAS,UAAU,mBAAmB,SAA0B,UAA6B;EAC3F,MAAM,gBAAgB,KAAK,SAAS,CAAC,QAAQ;EAC7C,MAAM,aAAa,KAAK,YAAY;AAEpC,OAAK,MAAM,eAAe,YAAY;GACpC,MAAM,IAAI,YAAY,MAAM;AAE5B,OAAI,EAAE,SAAS,OAEb,KAAI;IACF,MAAM,UAAU,YAAY,cAAc;AAC1C,QAAI,YAAY,QAAW;KACzB,MAAM,YAAY,IAAI,UAAU,QAAQ;AACxC,SAAI,SAAS,OAAO,cAAc,MAAM,EAAE,UAAU,CAClD,QAAO;;WAGL;AACN;;YAEO,EAAE,SAAS,QAAQ;IAI5B,MAAM,YAAY,YAAY,YAAY,CAAC,QAAQ,MAAM;KACvD,MAAM,KAAK,EAAE,MAAM;AACnB,SAAI,GAAG,SAAS,aAAa;MAC3B,MAAM,OAAO,GAAG,UAAU,WAAW;AACrC,UAAI;AACF,cAAO,KAAK,QAAQ,KAAK;cACnB;AACN,cAAO;;;AAGX,YAAO;MACP;AAEF,SAAK,MAAM,YAAY,WAAW;KAChC,MAAM,eAAe,SAAS,MAAM;AACpC,SAAI,aAAa,SAAS,aAAa;MACrC,MAAM,cAAc,aAAa,UAAU,QAAQ;AACnD,UAAI;OACF,MAAM,eAAe,YAAY,cAAc;AAC/C,WAAI,iBAAiB,QAAW;QAC9B,MAAM,iBAAiB,IAAI,UAAU,aAAa;QAGlD,MAAM,cAAc,EAAE;QACtB,MAAM,kBAAkB,YAAY,MAAM;AAG1C,YACE,gBAAgB,SAAS,aACzB,SAAS,OAAO,YAAY,QAAQ,CAAC,MAAM,EAAE,eAAe,EAC5D;SAIA,MAAM,eAFU,gBAAgB,SACP,SAAS,CACJ,cAAc;AAC5C,aAAI,iBAAiB,QAAW;UAC9B,MAAM,iBAAiB,IAAI,UAAU,aAAa;AAClD,cAAI,SAAS,OAAO,cAAc,MAAM,EAAE,eAAe,CACvD,QAAO;;;;cAKT;AACN;;;;;;AAOV,SAAO;;AAGT,UAAS,UAAU,sBAAsB,SAA0B,UAA8B;AAC/F,MAAI,KAAK,iBAAiB,SAAS,CACjC,QAAO;AAET,QAAM,cAAc,QAAQ,mDAAmD;;AAGjF,UAAS,UAAU,aAAa,WAAsC;AAEpE,SADmB,KAAK,YAAY,CAEjC,QAAQ,MAAM;GACb,MAAM,IAAI,EAAE,MAAM;AAClB,OAAI,EAAE,SAAS,aAAa;IAC1B,MAAM,OAAO,EAAE,UAAU,WAAW;AACpC,QAAI;AACF,YAAO,KAAK,QAAQ,KAAK;YACnB;AACN,YAAO;;;AAGX,UAAO;IACP,CACD,KAAK,MAAM;GACV,MAAM,IAAI,EAAE,MAAM;AAClB,OAAI,EAAE,SAAS,YACb,QAAO,EAAE,UAAU,QAAQ;AAE7B,SAAM,cAAc,QAAQ,8BAA8B;IAC1D;;;;;;;;;;;;;;;;;;;;;;;ACrbR,MAAa,aAAa;;;;AAK1B,MAAa,SAAS;;;;AAKtB,MAAa,cAAc;;;;;;;AAQ3B,IAAa,cAAb,MAAa,YAAY;CACvB,CAASC,4BAAa,IAAI,KAAuB;;;;CAMjD,cAAc;;;;;;;;CASd,IAAI,SAAiC,QAAgB,YAA2B;EAC9E,MAAM,aAAa,SAAS,cAAc,SAAS,QAAQ,WAAW;AACtE,QAAKA,UAAW,IAAI,WAAW,QAAQ,CAAC,KAAK,EAAE,WAAW;;;;;;;;CAS5D,IAAI,QAAsC;AACxC,SAAO,MAAKA,UAAW,IAAI,OAAO,KAAK,CAAC;;;;;;;;CAS1C,OAAO,QAAsC;EAC3C,MAAM,WAAW,MAAKA,UAAW,IAAI,OAAO,KAAK,CAAC;AAClD,QAAKA,UAAW,OAAO,OAAO,KAAK,CAAC;AACpC,SAAO;;;;;CAMT,QAAc;AACZ,QAAKA,UAAW,OAAO;;;;;CAMzB,UAAmB;AACjB,SAAO,MAAKA,UAAW,SAAS;;;;;;;;CASlC,cAAc,UAA8B;EAC1C,IAAI,SAAS;AACb,OAAK,MAAM,cAAc,MAAKA,UAAW,QAAQ,CAC/C,UAAS,OAAO,aAAa,YAAY,WAAW;AAEtD,SAAO;;;;;;;;CAST,OAAO,aAAa,UAAiC;EACnD,MAAM,cAAc,IAAI,aAAa;EACrC,MAAM,sBAAsB,SAAS,aAAa;AAElD,OAAK,MAAM,cAAc,oBACvB,cAAYA,UAAW,IAAI,WAAW,QAAQ,CAAC,KAAK,EAAE,WAAW;AAGnE,SAAO;;;;;;AAkGX,SAAS,gBAAgB,SACvB,SACA,QACA,YACU;CAEV,IAAI,gBAAgB,SAAS,IAAI,QAAQ,CAAC,MAAM,CAAC,aAAa,QAAQ,OAAO;AAG7E,KAAI,eAAe,OACjB,iBAAgB,cAAc,aAAa,aAAa,WAAW;AAMrE,QAD4B,SAAS,IAAI,WAAW,CACzB,aAAa,YAAY,cAAc,CAAC,YAAY,CAAC;;;;;AAOlF,IAAI,UAAU,WAAW;AACvB,UAAS,UAAU,gBAAgB,SAEjC,SACA,QACA,YACU;EACV,IAAI,gBAAgB,SAAS,IAAI,QAAQ,CAAC,MAAM,CAAC,aAAa,QAAQ,OAAO;AAE7E,MAAI,eAAe,OACjB,iBAAgB,cAAc,aAAa,aAAa,WAAW;AAGrE,SAAO,KAAK,aAAa,YAAY,cAAc;;;;;AAMrD,UAAS,UAAU,oBAAoB,WAAoC;EACzE,MAAM,IAAI,KAAK,MAAM;AACrB,MAAI,EAAE,SAAS,YACb,OAAM,cAAc,QAAQ,0CAA0C;AAIxE,SADY,EAAE,UAAU,QAAQ,CACrB,QAAQ;;;;;AAMrB,UAAS,UAAU,mBAAmB,WAAkC;EACtE,MAAM,IAAI,KAAK,MAAM;AACrB,MAAI,EAAE,SAAS,YACb,OAAM,cAAc,QAAQ,0CAA0C;EAKxE,MAAM,SAFM,EAAE,UAAU,QAAQ,CACV,mBAAmB,OAAO,CACvB,QAAQ;AAEjC,MAAI,WAAW,UAAa,WAAW,GACrC,OAAM,cAAc,QAAQ,2BAA2B;AAGzD,SAAO;;;;;AAMT,UAAS,UAAU,uBAAuB,WAA8C;EACtF,MAAM,IAAI,KAAK,MAAM;AACrB,MAAI,EAAE,SAAS,YACb,OAAM,cAAc,QAAQ,0CAA0C;EAIxE,MAAM,gBADM,EAAE,UAAU,QAAQ,CACN,2BAA2B,YAAY;AAEjE,MAAI,kBAAkB,OACpB;AAGF,SAAO,cAAc,QAAQ;;;;;AAM/B,UAAS,UAAU,cAAc,WAAsC;AACrE,SAAO,KAAK,wBAAwB,WAAW,CAAC,KAAK,MAAM;GACzD,MAAM,IAAI,EAAE,MAAM;AAClB,OAAI,EAAE,SAAS,YACb,QAAO,EAAE,UAAU,QAAQ;AAE7B,SAAM,cAAc,QAAQ,+BAA+B;IAC3D;;;;;AAMJ,UAAS,UAAU,qCAAqC,SAEtD,QACA,YACY;AAGZ,SAFuB,KAAK,aAAa,CAEnB,QAAQ,eAAe;AAC3C,OAAI;AAGF,QAAI,WAAW,QAGb;SAFkB,WAAW,mBAAmB,OAAO,CACpB,QAAQ,KAClB,OACvB,QAAO;;AAKX,QAAI,eAAe,QAAW;KAC5B,MAAM,gBAAgB,WAAW,2BAA2B,YAAY;AACxE,SAAI,kBAAkB,OACpB,QAAO;AAGT,SADuB,cAAc,QAAQ,KACtB,WACrB,QAAO;;AAIX,WAAO;WACD;AACN,WAAO;;IAET;;;;;;ACpTN,MAAa,gBAAgB;AAG7B,IAAa,gBAAb,MAAa,cAAc;CACzB,CAASC;CAET,YAAY,WAAuB;AACjC,MAAI,UAAU,WAAWC,qCACvB,OAAM,IAAI,MAAM,sBAAsBA,qCAAuB,QAAQ;AAEvE,QAAKD,YAAa;;CAIpB,OAAmB;AACjB,SAAO,MAAKA;;CAId,MAAc;AACZ,SAAO,MAAM,KAAK,MAAKA,UAAW,CAC/B,KAAK,MAAM,EAAE,SAAS,GAAG,CAAC,SAAS,GAAG,IAAI,CAAC,CAC3C,KAAK,GAAG;;CAIb,OAAO,QAAQ,KAA4B;AACzC,MAAI,IAAI,WAAW,GACjB,OAAM,IAAI,MAAM,8CAA8C;EAEhE,MAAM,QAAQ,IAAI,WAAW,GAAG;AAChC,OAAK,IAAI,IAAI,GAAG,IAAI,IAAI,IACtB,OAAM,KAAK,SAAS,IAAI,OAAO,IAAI,GAAG,EAAE,EAAE,GAAG;AAE/C,SAAO,IAAI,cAAc,MAAM;;;AAKnC,IAAa,iBAAb,MAAa,eAAe;CAC1B,CAASE;CACT,CAASF;CAET,AAAQ,YAAY,YAAwB,WAAuB;AACjE,QAAKE,aAAc;AACnB,QAAKF,YAAa,IAAI,cAAc,UAAU;;CAIhD,OAAO,WAA2B;EAEhC,MAAM,yDADM,IAAIG,yCAA6B,CACG;AAEhD,SAAO,IAAI,eAAe,6DADsB,WAAW,CACX;;CAIlD,OAAO,UAAU,YAAwB,WAAuC;AAC9E,MAAI,WAAW,WAAWC,sCACxB,OAAM,IAAI,MAAM,uBAAuBA,sCAAwB,QAAQ;AAEzE,MAAI,UAAU,WAAWH,qCACvB,OAAM,IAAI,MAAM,sBAAsBA,qCAAuB,QAAQ;AAEvE,SAAO,IAAI,eAAe,YAAY,UAAU;;CAIlD,OAAO,QAAQ,YAAoB,WAAmC;EACpE,MAAM,eAAe,IAAI,WAAW,GAAG;EACvC,MAAM,cAAc,IAAI,WAAW,GAAG;AAEtC,OAAK,IAAI,IAAI,GAAG,IAAI,IAAI,KAAK;AAC3B,gBAAa,KAAK,SAAS,WAAW,OAAO,IAAI,GAAG,EAAE,EAAE,GAAG;AAC3D,eAAY,KAAK,SAAS,UAAU,OAAO,IAAI,GAAG,EAAE,EAAE,GAAG;;AAG3D,SAAO,IAAI,eAAe,cAAc,YAAY;;CAItD,aAA4B;AAC1B,SAAO,MAAKD;;CAId,OAAmB;AACjB,SAAO,MAAKE;;CAId,MAAc;AACZ,SAAO,MAAM,KAAK,MAAKA,WAAY,CAChC,KAAK,MAAM,EAAE,SAAS,GAAG,CAAC,SAAS,GAAG,IAAI,CAAC,CAC3C,KAAK,GAAG;;CAIb,OAAO,eAA4C;AACjD,MAAI;GACF,MAAM,YAAY,cAAc,QAAQ,MAAKA,YAAa,MAAKF,UAAW,MAAM,CAAC;AACjF,UAAO,aAAa,KAAK,UAAU;WAC5B,QAAQ;AACf,SAAM,cAAc,QAAQ,4CAA4C;;;;AAS9E,IAAa,gBAAb,MAAa,cAAc;CACzB,CAASK;CAET,YAAY,MAAkB;AAC5B,QAAKA,OAAQ;;CAKf,OAAO,KAAK,YAA0B,oBAAkD;EACtF,MAAM,MAAM,IAAIF,yCAA6B;EAG7C,MAAM,+DAA4C,IAAI;EACtD,MAAM,mEAAgD,iBAAiB;EAOvE,MAAM,qFAJ+B,kBAAkB,mBAAmB,MAAM,CAAC,EAGpE,IAAI,aAAa,CAAC,OAAO,iBAAiB,EACE,GAAG;EAG5D,MAAM,uCAAsB,KAAKG,mCAAqB;EAItD,MAAM,CAAC,YAAY,iEADD,WAAW,MAAM,EAGjC,eACA,OACA,IAAI,WAAW,EAAE,CAClB;EAGD,MAAM,cAAc,gBAAgB,SAAS,MAAM,SAAS,WAAW,SAAS,QAAQ;EACxF,MAAM,SAAS,IAAI,WAAW,YAAY;EAC1C,IAAI,SAAS;AAEb,SAAO,IAAI,iBAAiB,OAAO;AACnC,YAAU,gBAAgB;AAE1B,SAAO,IAAI,OAAO,OAAO;AACzB,YAAU,MAAM;AAEhB,SAAO,IAAI,YAAY,OAAO;AAC9B,YAAU,WAAW;AAErB,SAAO,IAAI,SAAS,OAAO;AAE3B,SAAO,IAAI,cAAc,OAAO;;CAIlC,QAAQ,kBAA8B,kBAA0C;EAE9E,MAAM,YAAYL,uCAAyBK,qCAAuBC;AAClE,MAAI,MAAKF,KAAM,SAAS,UACtB,OAAM,IAAI,MAAM,2BAA2B;EAG7C,IAAI,SAAS;EAGb,MAAM,kBAAkB,MAAKA,KAAM,MAAM,QAAQ,SAASJ,qCAAuB;AACjF,YAAUA;EAGV,MAAM,QAAQ,MAAKI,KAAM,MAAM,QAAQ,SAASC,mCAAqB;AACrE,YAAUA;EAGV,MAAM,mBAAmB,MAAKD,KAAM,MAAM,OAAO;EACjD,MAAM,aAAa,iBAAiB,MAAM,GAAG,CAACE,kCAAoB;EAClE,MAAM,UAAU,iBAAiB,MAAM,CAACA,kCAAoB;AAkB5D,+DAPE,iFARmC,kBAAkB,gBAAgB,EAG1D,IAAI,aAAa,CAAC,OAAO,iBAAiB,EACE,GAAG,EAM1D,OACA,IAAI,WAAW,EAAE,EACjB,QACD;;CAMH,OAAmB;AACjB,SAAO,MAAKF;;CAId,MAAc;AACZ,SAAO,MAAM,KAAK,MAAKA,KAAM,CAC1B,KAAK,MAAM,EAAE,SAAS,GAAG,CAAC,SAAS,GAAG,IAAI,CAAC,CAC3C,KAAK,GAAG;;CAIb,OAAO,QAAQ,KAA4B;EACzC,MAAM,QAAQ,IAAI,WAAW,IAAI,SAAS,EAAE;AAC5C,OAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,IAChC,OAAM,KAAK,SAAS,IAAI,OAAO,IAAI,GAAG,EAAE,EAAE,GAAG;AAE/C,SAAO,IAAI,cAAc,MAAM;;;AA2HnC,IAAI,UAAU,WAAW;AACvB,UAAS,UAAU,4BAA4B,SAE7C,oBACU;EAEV,MAAM,aAAa,aAAa,UAAU;AAM1C,SAHkB,KAAK,eAAe,WAAW,CAGhC,aAAa,oBAAoB,WAAW;;AAI/D,UAAS,UAAU,6BAA6B,SAE9C,YACU;AACV,MAAI,WAAW,WAAW,EACxB,OAAM,cAAc,QAAQ,sCAAsC;EAIpE,MAAM,aAAa,aAAa,UAAU;EAG1C,IAAI,SAAS,KAAK,eAAe,WAAW;AAG5C,OAAK,MAAM,aAAa,WACtB,UAAS,OAAO,aAAa,WAAW,WAAW;AAGrD,SAAO;;AAIT,UAAS,UAAU,eAAe,SAEhC,oBACA,YACU;EAEV,MAAM,gBAAgB,cAAc,KAAK,YAAY,mBAAmB;AAGxE,SAAO,KAAK,aAAa,eAAe,cAAc,MAAM,CAAC;;AAI/D,UAAS,UAAU,4BAA4B,SAE7C,qBACU;AAGV,MADoB,KAAK,SAAS,CAAC,MAAM,CACzB,SAAS,YACvB,OAAM,cAAc,QAAQ,2BAA2B;EAIzD,MAAM,sBAAsB,KAAK,YAAY,CAAC,QAAQ,cAAc;AAClE,OAAI;IACF,MAAM,YAAY,UAAU,SAAS,CAAC,aAAa;AACnD,QAAI,cAAc,OAAW,QAAO;AACpC,WAAO,UAAU,QAAQ,KAAK;WACxB;AACN,WAAO;;IAET;AAEF,MAAI,oBAAoB,WAAW,EACjC,OAAM,cAAc,QAAQ,sBAAsB;EAIpD,IAAIG,aAAkC;AAEtC,OAAK,MAAM,aAAa,oBACtB,KAAI;GACF,MAAM,MAAM,UAAU,SAAS,CAAC,UAAU;AAC1C,OAAI,QAAQ,OAAW;GACvB,MAAM,aAAa,IAAI,cAAc;AACrC,OAAI,eAAe,OAAW;GAC9B,MAAM,gBAAgB,IAAI,cAAc,WAAW;AAGnD,gBAAa,oBAAoB,OAAO,cAAc;AACtD;UACM;AAEN;;AAIJ,MAAI,eAAe,KACjB,OAAM,cAAc,QAAQ,wBAAwB;AAItD,SAAO,KAAK,eAAe,WAAW;;AAIxC,UAAS,UAAU,qBAAqB,SAEtC,qBACU;AAEV,SADkB,KAAK,0BAA0B,oBAAoB,CACpD,QAAQ;;AAI3B,UAAS,UAAU,sBAAsB,SAEvC,YACU;AACV,SAAO,KAAK,MAAM,CAAC,2BAA2B,WAAW;;AAI3D,UAAS,UAAU,aAAa,WAA2C;AAWzE,SAV4B,KAAK,YAAY,CAAC,QAAQ,cAAc;AAClE,OAAI;IACF,MAAM,YAAY,UAAU,SAAS,CAAC,aAAa;AACnD,QAAI,cAAc,OAAW,QAAO;AACpC,WAAO,UAAU,QAAQ,KAAK;WACxB;AACN,WAAO;;IAET,CAEyB,KAAK,cAAc;GAC5C,MAAM,MAAM,UAAU,SAAS,CAAC,UAAU;AAC1C,OAAI,QAAQ,OACV,OAAM,cAAc,QAAQ,8BAA8B;GAE5D,MAAM,aAAa,IAAI,cAAc;AACrC,OAAI,eAAe,OACjB,OAAM,cAAc,QAAQ,yBAAyB;AAEvD,UAAO,IAAI,cAAc,WAAW;IACpC;;;;;;ACngBN,MAAa,oBAAoB;AAGjC,MAAa,qBAAqB;AAGlC,MAAa,uBAAuB;AAGpC,MAAa,uBAAuB;AAGpC,MAAa,eAAe;CAC1B,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,KAAK;CACL,IAAI;CACJ,KAAK;CACL,KAAK;CACN;AAGD,MAAa,gBAAgB;CAC3B,OAAO;CACP,KAAK;CACL,KAAK;CACN;AASD,IAAa,WAAb,MAAa,SAAS;CACpB,CAASC;CAET,YAAY,IAAgB;AAC1B,QAAKA,KAAM;;CAIb,KAAiB;AACf,SAAO,MAAKA;;CAId,YAAqB;AACnB,SAAO,OAAO,MAAKA,OAAQ;;CAI7B,WAAoB;AAClB,SAAO,OAAO,MAAKA,OAAQ;;CAI7B,WAAqB;EAGnB,MAAM,cAAc,OAAO,MAAKA,OAAQ,WAAW,IAAI,MAAKA,GAAI,KAAK,KAAK,MAAKA,GAAI;AACnF,SAAO,SAAS,IAAI,YAAY;;CAIlC,cAAc,OAAoB,OAA2C;AAE3E,SADa,IAAI,WAAW,KAAK,CACrB,cAAc,OAAO,MAAM;;CAIzC,OAAO,YAAY,IAAsB;AACvC,SAAO,IAAI,SAAS,GAAG;;CAIzB,OAAO,WAAW,MAAwB;AACxC,SAAO,IAAI,SAAS,KAAK;;CAI3B,WAAmB;AACjB,SAAO,OAAO,MAAKA,OAAQ,WAAW,IAAI,MAAKA,GAAI,KAAK,KAAK,MAAKA,GAAI;;;AAK1E,IAAa,YAAb,MAAa,UAAU;CACrB,CAASA;CACT,CAASC;CAET,YAAY,IAAiB,OAAiB;AAC5C,QAAKD,KAAM;AACX,QAAKC,QAAS;;CAIhB,KAAkB;AAChB,SAAO,MAAKD;;CAId,QAAkB;AAChB,SAAO,MAAKC;;CAId,YAAqB;AACnB,SAAO,OAAO,MAAKD,OAAQ;;CAI7B,WAAoB;AAClB,SAAO,OAAO,MAAKA,OAAQ;;CAK7B,WAAqB;EACnB,MAAM,WAAW,OAAO,MAAKA,OAAQ,WAAW,IAAI,MAAKA,GAAI,KAAK,KAAK,MAAKA,GAAI;AAChF,SAAO,SAAS,aAAa,UAAU,MAAKC,MAAO;;CAIrD,OAAO,MAAM,OAA0C;AACrD,SAAO,IAAI,UAAU,cAAc,OAAO,SAAS,IAAI,MAAM,CAAC;;CAGhE,OAAO,IAAI,OAA0C;AACnD,SAAO,IAAI,UAAU,cAAc,KAAK,SAAS,IAAI,MAAM,CAAC;;CAG9D,OAAO,IAAI,OAA0C;AACnD,SAAO,IAAI,UAAU,cAAc,KAAK,SAAS,IAAI,MAAM,CAAC;;CAI9D,WAAmB;AAEjB,SAAO,GADO,OAAO,MAAKD,OAAQ,WAAW,IAAI,MAAKA,GAAI,KAAK,KAAK,MAAKA,GAAI,IAC7D,IAAI,MAAKC,MAAO,QAAQ;;;AAK5C,IAAa,aAAb,MAAa,WAAW;CACtB,CAASC;CACT,CAASC,6BAAc,IAAI,KAAwB;CACnD,YAA6B;CAE7B,YAAY,MAAgB;AAC1B,QAAKD,WAAY;;CAInB,WAAqB;AACnB,SAAO,MAAKA;;CAId,aAA0B;AACxB,SAAO,MAAM,KAAK,MAAKC,WAAY,QAAQ,CAAC;;CAI9C,cAAc,OAAoB,OAA2C;EAC3E,MAAM,MAAM,OAAO,UAAU,WAAW,MAAM,UAAU,GAAG;AAC3D,QAAKA,WAAY,IAAI,KAAK,IAAI,UAAU,OAAO,SAAS,IAAI,MAAM,CAAC,CAAC;AACpE,QAAKC,WAAY;AACjB,SAAO;;CAIT,eAAe,QAA4D;AACzE,OAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,OAAO,CAC/C,MAAK,cAAc,KAAK,MAAM;AAEhC,SAAO;;CAIT,aAAa,OAA0C;EACrD,MAAM,MAAM,OAAO,UAAU,WAAW,MAAM,UAAU,GAAG;AAC3D,SAAO,MAAKD,WAAY,IAAI,IAAI,EAAE,OAAO;;CAI3C,aAAa,OAA6B;EACxC,MAAM,MAAM,OAAO,UAAU,WAAW,MAAM,UAAU,GAAG;AAC3D,SAAO,MAAKA,WAAY,IAAI,IAAI;;CAIlC,WAAqB;AACnB,MAAI,MAAKC,aAAc,KACrB,QAAO,MAAKA;EAId,IAAI,MAAM,MAAKF,SAAU,UAAU;AAGnC,OAAK,MAAM,SAAS,MAAKC,WAAY,QAAQ,EAAE;GAG7C,MAAM,YAFW,MAAM,UAAU,CAEN,YAAY,CAAC;AACxC,OAAI,cAAc,QAAW;IAC3B,MAAM,YAAY,UAAU,SAAS,CAAC,aAAa;IACnD,MAAM,SAAS,UAAU,SAAS,CAAC,UAAU;AAC7C,QAAI,cAAc,UAAa,WAAW,OACxC,OAAM,IAAI,aAAa,UAAU,QAAQ,EAAE,OAAO;;;AAKxD,QAAKC,WAAY;AACjB,SAAO;;CAKT,OAAO,aAAa,UAAgC;EAGlD,MAAM,cADU,SAAS,SAAS,CACN,QAAQ;AACpC,MAAI,gBAAgB,OAClB,OAAM,cAAc,QAAQ,gCAAgC;EAI9D,IAAIC;AACJ,MAAI,YAAY,WAAW,IAAI,IAAI,YAAY,SAAS,IAAI,EAAE;GAC5D,MAAM,QAAQ,YAAY,MAAM,GAAG,GAAG;AACtC,OAAI,MAAM,WAAW,KAAI,IAAI,MAAM,SAAS,KAAI,CAC9C,UAAS,MAAM,MAAM,GAAG,GAAG;OAE3B,UAAS,SAAS,OAAO,GAAG;QAG9B,OAAM,cAAc,QAAQ,gCAAgC;EAI9D,MAAM,OAAO,IAAI,WADJ,IAAI,SAAS,OAAO,CACA;AAGjC,OAAK,MAAM,aAAa,SAAS,YAAY,CAC3C,KAAI;GACF,MAAM,OAAO,UAAU,SAAS,CAAC,aAAa;GAC9C,MAAM,MAAM,UAAU,SAAS,CAAC,UAAU;AAE1C,OAAI,SAAS,UAAa,QAAQ,QAAW;IAC3C,MAAM,WAAW,KAAK,QAAQ;AAC9B,QAAI,aAAa,UAAa,SAAS,WAAW,IAAI,IAAI,SAAS,SAAS,IAAI,EAAE;KAChF,MAAM,QAAQ,SAAS,MAAM,GAAG,GAAG;KACnC,IAAIC;AACJ,SAAI,MAAM,WAAW,KAAI,IAAI,MAAM,SAAS,KAAI,CAC9C,WAAU,MAAM,MAAM,GAAG,GAAG;SAE5B,WAAU,SAAS,OAAO,GAAG;AAE/B,UAAK,cAAc,SAAS,IAAI;;;UAG9B;AAEN;;AAIJ,SAAO;;CAIT,WAAmB;EACjB,MAAM,SAAS,MAAM,KAAK,MAAKH,WAAY,QAAQ,CAAC,CACjD,KAAK,MAAM,EAAE,UAAU,CAAC,CACxB,KAAK,KAAK;AACb,SAAO,GAAG,MAAKD,SAAU,UAAU,CAAC,IAAI,OAAO;;;AAOnD,SAAgB,IAAI,KAA6B,KAAyC;AACxF,QAAO,SAAS,YAAY,aAAa,IAAI,CAC1C,cAAc,cAAc,KAAK,IAAI,CACrC,cAAc,cAAc,KAAK,IAAI;;AAI1C,SAAgB,IAAI,KAA6B,KAAyC;AACxF,QAAO,SAAS,YAAY,aAAa,IAAI,CAC1C,cAAc,cAAc,KAAK,IAAI,CACrC,cAAc,cAAc,KAAK,IAAI;;AAI1C,SAAgB,IAAI,KAA6B,KAAyC;AACxF,QAAO,SAAS,YAAY,aAAa,IAAI,CAC1C,cAAc,cAAc,KAAK,IAAI,CACrC,cAAc,cAAc,KAAK,IAAI;;AAI1C,SAAgB,IAAI,KAA6B,KAAyC;AACxF,QAAO,SAAS,YAAY,aAAa,IAAI,CAC1C,cAAc,cAAc,KAAK,IAAI,CACrC,cAAc,cAAc,KAAK,IAAI;;AAI1C,SAAgB,IAAI,OAA2C;AAC7D,QAAO,SAAS,YAAY,aAAa,IAAI,CAAC,cAAc,cAAc,OAAO,MAAM;;AAIzF,SAAgB,GAAG,KAA6B,KAAyC;AACvF,QAAO,SAAS,YAAY,aAAa,GAAG,CACzC,cAAc,cAAc,KAAK,IAAI,CACrC,cAAc,cAAc,KAAK,IAAI;;AAI1C,SAAgB,GAAG,KAA6B,KAAyC;AACvF,QAAO,SAAS,YAAY,aAAa,GAAG,CACzC,cAAc,cAAc,KAAK,IAAI,CACrC,cAAc,cAAc,KAAK,IAAI;;AAI1C,SAAgB,GAAG,KAA6B,KAAyC;AACvF,QAAO,SAAS,YAAY,aAAa,GAAG,CACzC,cAAc,cAAc,KAAK,IAAI,CACrC,cAAc,cAAc,KAAK,IAAI;;AAI1C,SAAgB,IAAI,KAA6B,KAAyC;AACxF,QAAO,SAAS,YAAY,aAAa,IAAI,CAC1C,cAAc,cAAc,KAAK,IAAI,CACrC,cAAc,cAAc,KAAK,IAAI;;AAI1C,SAAgB,GAAG,KAA6B,KAAyC;AACvF,QAAO,SAAS,YAAY,aAAa,GAAG,CACzC,cAAc,cAAc,KAAK,IAAI,CACrC,cAAc,cAAc,KAAK,IAAI;;AAI1C,SAAgB,IAAI,OAA2C;AAC7D,QAAO,SAAS,YAAY,aAAa,IAAI,CAAC,cAAc,cAAc,OAAO,MAAM;;;;;AC3SzF,IAAI,UAAU,WAAW;AACvB,UAAS,UAAU,mBAAmB,SAAU,QAA2C;EACzF,MAAM,YAAY,eAAe,MAAM,OAAO;AAG9C,MAAI,CAAC,SAAS,QAAQ,UAAU,CAC9B;AAKF,SADiB,KAAK,kBAAkB,UAAU,CAClC,iBAAiB,OAAO;;AAG1C,UAAS,UAAU,sBAAsB,SAAU,QAAwC;EACzF,MAAM,YAAY,IAAI,IAAY,CAAC,OAAO,QAAQ,CAAC,CAAC;AACpD,SAAO,KAAK,iBAAiB,UAAU;;AAGzC,UAAS,UAAU,qBAAqB,SAAU,QAAqB,OAA0B;AAE/F,MAAI,KAAK,QAAQ,CAAC,KAAK,KAAK,MAAM,QAAQ,CAAC,KAAK,CAC9C,QAAO;AAIT,SAAO,YAAY,OAAO,OAAO;;AAGnC,UAAS,UAAU,wBAAwB,SAAU,QAAkB,OAA0B;EAC/F,MAAM,YAAY,IAAI,IAAY,CAAC,OAAO,QAAQ,CAAC,CAAC;AACpD,SAAO,KAAK,mBAAmB,WAAW,MAAM;;;AAUpD,SAAS,eAAe,UAAoB,QAAkC;CAC5E,MAAM,yBAAS,IAAI,KAAa;AAChC,YAAW,UAAU,wBAAQ,IAAI,KAAa,EAAE,OAAO;AACvD,QAAO;;AAOT,SAAS,WACP,UACA,QACA,SACA,QACM;CAEN,MAAM,aAAa,IAAI,IAAI,QAAQ;AACnC,YAAW,IAAI,SAAS,QAAQ,CAAC;AAGjC,KAAI,eAAe,QAAQ,SAAS,QAAQ,CAAC,CAC3C,MAAK,MAAM,UAAU,WACnB,QAAO,IAAI,OAAO;CAKtB,MAAM,eAAe,SAAS,MAAM;AAEpC,KAAI,aAAa,SAAS,QAAQ;AAEhC,aAAW,aAAa,SAAS,QAAQ,YAAY,OAAO;AAG5D,OAAK,MAAM,aAAa,aAAa,WACnC,YAAW,WAAW,QAAQ,YAAY,OAAO;YAE1C,aAAa,SAAS,UAE/B,YAAW,aAAa,UAAU,QAAQ,YAAY,OAAO;UACpD,aAAa,SAAS,aAAa;EAE5C,MAAM,YAAY,aAAa,UAAU,WAAW;EACpD,MAAM,SAAS,aAAa,UAAU,QAAQ;AAC9C,aAAW,WAAW,QAAQ,YAAY,OAAO;AACjD,aAAW,QAAQ,QAAQ,YAAY,OAAO;;;AAQlD,SAAS,YAAY,UAAoB,QAA8B;CACrE,MAAM,aAAa,IAAI,IAAI,OAAO;AAClC,gBAAe,UAAU,WAAW;AACpC,QAAO,WAAW,SAAS;;AAM7B,SAAS,eAAe,UAAoB,QAA2B;AAErE,KAAI,eAAe,QAAQ,SAAS,QAAQ,CAAC,CAC3C,cAAa,QAAQ,SAAS,QAAQ,CAAC;AAIzC,KAAI,OAAO,SAAS,EAClB;CAIF,MAAM,eAAe,SAAS,MAAM;AAEpC,KAAI,aAAa,SAAS,QAAQ;AAEhC,iBAAe,aAAa,SAAS,OAAO;AAG5C,OAAK,MAAM,aAAa,aAAa,YAAY;AAC/C,kBAAe,WAAW,OAAO;AACjC,OAAI,OAAO,SAAS,EAAG;;YAEhB,aAAa,SAAS,UAE/B,gBAAe,aAAa,UAAU,OAAO;UACpC,aAAa,SAAS,aAAa;EAE5C,MAAM,YAAY,aAAa,UAAU,WAAW;EACpD,MAAM,SAAS,aAAa,UAAU,QAAQ;AAC9C,iBAAe,WAAW,OAAO;AACjC,MAAI,OAAO,OAAO,EAChB,gBAAe,QAAQ,OAAO;;;AAOpC,SAAS,eAAe,KAAkB,QAAyB;CACjE,MAAM,YAAY,OAAO,KAAK;AAC9B,MAAK,MAAM,KAAK,IACd,KAAI,EAAE,KAAK,KAAK,UACd,QAAO;AAGX,QAAO;;AAIT,SAAS,aAAa,KAAkB,QAAsB;CAC5D,MAAM,YAAY,OAAO,KAAK;AAC9B,MAAK,MAAM,KAAK,IACd,KAAI,EAAE,KAAK,KAAK,WAAW;AACzB,MAAI,OAAO,EAAE;AACb;;;AAMN,SAAS,SAAS,QAAqB,UAAgC;AACrE,MAAK,MAAM,UAAU,OACnB,KAAI,CAAC,eAAe,UAAU,OAAO,CACnC,QAAO;AAGX,QAAO;;;;;AClQT,SAAS,UAAU,MAAM,WAAkC;CACzD,MAAM,QAAQ,KAAK,WAAW;AAC9B,QAAO,MAAM,KAAK,MAAM,CACrB,KAAK,MAAM,EAAE,SAAS,GAAG,CAAC,SAAS,GAAG,IAAI,CAAC,CAC3C,KAAK,GAAG;;AAIb,SAAS,UAAU,YAAY,WAAsC;AAEnE,mCADa,KAAK,YAAY,CACT;;;;;ACGvB,SAAS,iBAAiB,QAAiB,SAAS,GAAW;AAE7D,KAAI,OAAOK,WAAS,YAAYA,WAAS,QAAQ,SAASA,UAAQ,WAAWA,QAAM;EACjF,MAAM,SAASA;AACf,SAAO,GAAG,OAAO,IAAI,GAAG,iBAAiB,OAAO,OAAO,OAAO,CAAC;;AAIjE,KAAI,MAAM,QAAQA,OAAK,EAAE;AACvB,MAAIA,OAAK,WAAW,EAClB,QAAO;AAGT,SAAO,IADOA,OAAK,KAAK,SAAS,iBAAiB,MAAM,SAAS,EAAE,CAAC,CACnD,KAAK,KAAK,CAAC;;AAI9B,KAAIA,kBAAgB,KAAK;AACvB,MAAIA,OAAK,SAAS,EAChB,QAAO;EAET,MAAMC,UAAoB,EAAE;AAC5B,OAAK,MAAM,CAAC,KAAK,UAAUD,QAAM;GAC/B,MAAM,SAAS,iBAAiB,KAAK,SAAS,EAAE;GAChD,MAAM,WAAW,iBAAiB,OAAO,SAAS,EAAE;AACpD,WAAQ,KAAK,GAAG,OAAO,IAAI,WAAW;;AAExC,SAAO,IAAI,QAAQ,KAAK,KAAK,CAAC;;AAIhC,KAAIA,kBAAgB,WAIlB,QAAO,KAHK,MAAM,KAAKA,OAAK,CACzB,KAAK,MAAM,EAAE,SAAS,GAAG,CAAC,SAAS,GAAG,IAAI,CAAC,CAC3C,KAAK,GAAG,CACK;AAIlB,KAAI,OAAOA,WAAS,SAClB,QAAO,KAAK,UAAUA,OAAK;AAI7B,KAAI,OAAOA,WAAS,YAAYA,WAAS,QAAQ,UAAUA,QAAM;EAC/D,MAAM,QAAQA;AACd,UAAQ,MAAM,MAAd;GACE,KAAK,EACH,QAAO,OAAO,MAAM,MAAM;GAC5B,KAAK,EACH,QAAO,OAAO,KAAK,OAAO,MAAM,MAAM,CAAC;GACzC,KAAK,GAAG;IAEN,MAAM,cAAc,MAAM;AAC1B,QAAI,gBAAgB,QAAQ,OAAO,gBAAgB,YAAY,UAAU,aAAa;KACpF,MAAM,aAAa;AACnB,SAAI,WAAW,SAAS,QACtB,QAAO,OAAO,WAAW,MAAM;;AAGnC,QAAI,gBAAgB,GAAI,QAAO;AAC/B,QAAI,gBAAgB,GAAI,QAAO;AAC/B,QAAI,gBAAgB,GAAI,QAAO;AAC/B,QAAI,gBAAgB,GAAI,QAAO;AAC/B,WAAO,UAAU,OAAO,YAAY,CAAC;;;;AAM3C,KAAI,OAAOA,WAAS,UAAW,QAAO,OAAOA,OAAK;AAClD,KAAI,OAAOA,WAAS,SAAU,QAAO,OAAOA,OAAK;AACjD,KAAI,OAAOA,WAAS,SAAU,QAAO,OAAOA,OAAK;AACjD,KAAIA,WAAS,KAAM,QAAO;AAC1B,KAAIA,WAAS,OAAW,QAAO;AAG/B,KAAI;AACF,SAAO,KAAK,UAAUA,OAAK;SACrB;AAEN,SAAO,OAAOA,OAAK;;;AAKvB,SAAS,UAAU,aAAa,WAAkC;AAEhE,QAAO,iBADM,KAAK,YAAY,CACD;;;;;ACrE/B,SAAS,UAAU,UAAU,SAA0B,SAA2B,SAAiB;CACjG,MAAM,SAAS,KAAK,QAAQ;AAC5B,KAAI,WAAW,OACb,QAAO,OAAO,KAAK;AAErB,QAAO,OAAO,OAAO;;AAIvB,SAAS,UAAU,UAAU,SAA0B,YAAY,IAAY;AAG7E,SAFU,KAAK,MAAM,CAEX,MAAV;EACE,KAAK,OACH,QAAO;EACT,KAAK,QAAQ;AAEX,OAAI;IACF,MAAM,OAAO,KAAK,QAAQ;AAC1B,QAAI,SAAS,QAAW;KACtB,MAAM,YAAY,KAAK,SAAS,YAAY,GAAG,KAAK,UAAU,GAAG,UAAU,CAAC,OAAO;AACnF,YAAO,KAAK,UAAU,UAAU;;WAE5B;AAIR,OAAI;IACF,MAAM,MAAM,KAAK,eAAe;AAChC,WAAO,OAAO,IAAI;WACZ;AAIR,OAAI;IACF,MAAM,OAAO,KAAK,gBAAgB;AAClC,WAAO,OAAO,KAAK;WACb;AAIR,OAAI,KAAK,QAAQ,CACf,QAAO;GAIT,MAAM,QAAQ,KAAK,cAAc;AACjC,OAAI,UAAU,UAAa,MAAM,UAAU,GAIzC,QAAO,KAHK,MAAM,KAAK,MAAM,CAC1B,KAAK,MAAM,EAAE,SAAS,GAAG,CAAC,SAAS,GAAG,IAAI,CAAC,CAC3C,KAAK,GAAG,CACK;AAGlB,UAAO;;EAET,KAAK,UACH,QAAO;EACT,KAAK,YACH,QAAO;EACT,KAAK,SACH,QAAO;EACT,KAAK,YACH,QAAO;EACT,KAAK,aACH,QAAO;EACT,KAAK,aACH,QAAO;EACT,QACE,QAAO;;;AAKb,SAAS,UAAU,aAAa,SAA0B,UAA6B,EAAE,EAAU;CACjG,MAAM,YAAY,QAAQ,aAAa;CACvC,MAAM,mBAAmB,QAAQ,oCAAoB,IAAI,KAAa;CACtE,MAAM,gBAAgB,QAAQ,iBAAiB;CAE/C,MAAME,WAA0B,EAAE;AAGlC,MAAK,KAAK,WAAW,SAAY,UAAU,OAAO,cAAc,WAAW;EACzE,MAAM,YAAY,SAAS,QAAQ,CAAC,OAAO;EAC3C,MAAM,gBAAgB,iBAAiB,IAAI,UAAU;AAErD,WAAS,KAAK;GACZ;GACA;GACA;GACA,QAAQ,CAAC;GACT;GACD,CAAC;AAEF,SAAO,CAAC,QAAW,MAAM;GACzB;AA0BF,QAvBc,SAAS,KAAK,SAAS;EACnC,MAAMC,QAAkB,EAAE;AAE1B,MAAI,KAAK,cACP,OAAM,KAAK,IAAI;AAGjB,MAAI,KAAK,OACP,OAAM,KAAK,KAAK,SAAS,QAAQ,cAAc,CAAC;EAGlD,MAAM,QAAQ,UAAU,KAAK,aAAa;AAC1C,MAAI,UAAU,UAAa,UAAU,GACnC,OAAM,KAAK,MAAM;AAGnB,QAAM,KAAK,KAAK,SAAS,QAAQ,GAAG,CAAC;EAErC,MAAM,OAAO,MAAM,KAAK,IAAI;AAE5B,SADe,IAAI,OAAO,KAAK,QAAQ,EAAE,GACzB;GAChB,CAEW,KAAK,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;ACjJzB,SAAgB,QAAQ,KAAa,MAAc,OAAuB;AACxE,QAAO,GAAG,OAAO,MAAM;;AAoBzB,OAAO,UAAU,YAAY,SAAwB,MAAc,OAAuB;AACxF,QAAO,QAAQ,MAAM,MAAM,MAAM;;;;;ACxBnC,0BAA0B;AAC1B,2BAA2B;AAW3B,MAAa,UAAU"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["#data","#predicate","#object","#digest","CborMap","cbor","#compressedData","#digest","cbor","createSecureRng","SecureRandomNumberGenerator","#key","SYMMETRIC_KEY_SIZE","SYMMETRIC_NONCE_SIZE","#ciphertext","#nonce","#authTag","#aadDigest","encodedCbor","encryptedMessage","cbor","TAG_ENVELOPE","ENVELOPE","LEAF","ENCRYPTED","COMPRESSED","#case","KnownValue","cbor","TAG_ENCODED_CBOR","assertions: Envelope[]","MajorType","ENVELOPE","envelope: Envelope","cbor","cbor","SecureRandomNumberGenerator","#data","#privateKey","ECDSA_PRIVATE_KEY_SIZE","SecureRandomNumberGenerator","#publicKey","ECDSA_PUBLIC_KEY_SIZE","ECDSA_UNCOMPRESSED_PUBLIC_KEY_SIZE","#assertions","#envelopes","#publicKey","X25519_PUBLIC_KEY_SIZE","#privateKey","SecureRandomNumberGenerator","X25519_PRIVATE_KEY_SIZE","#data","SYMMETRIC_NONCE_SIZE","SYMMETRIC_AUTH_SIZE","contentKey: SymmetricKey | null","#id","#value","#function","#parameters","#envelope","funcId: FunctionID","paramId: ParameterID","cbor","entries: string[]","elements: TreeElement[]","parts: string[]"],"sources":["../src/base/digest.ts","../src/base/error.ts","../src/base/assertion.ts","../src/extension/compress.ts","../src/extension/encrypt.ts","../src/base/envelope.ts","../src/base/envelope-encodable.ts","../src/base/cbor.ts","../src/base/envelope-decodable.ts","../src/base/elide.ts","../src/base/walk.ts","../src/base/assertions.ts","../src/base/leaf.ts","../src/base/queries.ts","../src/base/wrap.ts","../src/extension/types.ts","../src/extension/salt.ts","../src/extension/signature.ts","../src/extension/attachment.ts","../src/extension/recipient.ts","../src/extension/expression.ts","../src/extension/proof.ts","../src/format/hex.ts","../src/format/diagnostic.ts","../src/format/tree.ts","../src/utils/string.ts","../src/index.ts"],"sourcesContent":["import { sha256 } from \"@bcts/crypto\";\n\n/// A cryptographic digest used to uniquely identify digital objects.\n///\n/// Digests in Gordian Envelope are always SHA-256 hashes (32 bytes).\n/// This is a fundamental building block for the Merkle-like digest tree\n/// that enables privacy features while maintaining integrity.\n///\n/// Based on BCR-2021-002: Digests for Digital Objects\n/// @see https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2021-002-digest.md\nexport class Digest {\n readonly #data: Uint8Array;\n\n /// Creates a new Digest from raw bytes.\n ///\n /// @param data - The 32-byte digest data\n /// @throws {Error} If data is not exactly 32 bytes\n constructor(data: Uint8Array) {\n if (data.length !== 32) {\n throw new Error(`Digest must be exactly 32 bytes, got ${data.length} bytes`);\n }\n this.#data = data;\n }\n\n /// Returns the raw digest bytes.\n ///\n /// @returns A Uint8Array containing the 32-byte digest\n data(): Uint8Array {\n return this.#data;\n }\n\n /// Creates a digest from an image (arbitrary byte array).\n ///\n /// This is the primary way to create a digest from data. The data is\n /// hashed using SHA-256 to produce a 32-byte digest.\n ///\n /// @param image - The data to hash\n /// @returns A new Digest instance\n ///\n /// @example\n /// ```typescript\n /// const digest = Digest.fromImage(new TextEncoder().encode(\"Hello, world!\"));\n /// ```\n static fromImage(image: Uint8Array): Digest {\n const hash = sha256(image);\n return new Digest(hash);\n }\n\n /// Creates a digest from multiple digests.\n ///\n /// This is used to combine digests in the Merkle-like tree structure.\n /// The digests are concatenated and then hashed.\n ///\n /// @param digests - An array of digests to combine\n /// @returns A new Digest instance representing the combined digests\n ///\n /// @example\n /// ```typescript\n /// const digest1 = Digest.fromImage(data1);\n /// const digest2 = Digest.fromImage(data2);\n /// const combined = Digest.fromDigests([digest1, digest2]);\n /// ```\n static fromDigests(digests: Digest[]): Digest {\n const totalLength = digests.length * 32;\n const combined = new Uint8Array(totalLength);\n let offset = 0;\n for (const digest of digests) {\n combined.set(digest.data(), offset);\n offset += 32;\n }\n return Digest.fromImage(combined);\n }\n\n /// Returns the hexadecimal string representation of the digest.\n ///\n /// @returns A 64-character hexadecimal string\n ///\n /// @example\n /// ```typescript\n /// const digest = Digest.fromImage(data);\n /// console.log(digest.hex()); // \"5feceb66ffc86f38d952786c6d696c79c2dbc239dd4e91b46729d73a27fb57e9\"\n /// ```\n hex(): string {\n return Array.from(this.#data)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n }\n\n /// Returns an abbreviated hexadecimal representation for visual comparison.\n ///\n /// Following Blockchain Commons conventions, this returns the first 7\n /// hexadecimal digits of the digest, which provides sufficient entropy\n /// for human visual comparison while being easy to read.\n ///\n /// @returns A 7-character hexadecimal string\n ///\n /// @example\n /// ```typescript\n /// const digest = Digest.fromImage(data);\n /// console.log(digest.short()); // \"5feceb6\"\n /// ```\n short(): string {\n return this.hex().substring(0, 7);\n }\n\n /// Creates a digest from a hexadecimal string.\n ///\n /// @param hex - A 64-character hexadecimal string\n /// @returns A new Digest instance\n /// @throws {Error} If the hex string is not exactly 64 characters\n ///\n /// @example\n /// ```typescript\n /// const digest = Digest.fromHex(\"5feceb66ffc86f38d952786c6d696c79c2dbc239dd4e91b46729d73a27fb57e9\");\n /// ```\n static fromHex(hex: string): Digest {\n if (hex.length !== 64) {\n throw new Error(`Hex string must be exactly 64 characters, got ${hex.length}`);\n }\n const data = new Uint8Array(32);\n for (let i = 0; i < 32; i++) {\n data[i] = parseInt(hex.substring(i * 2, i * 2 + 2), 16);\n }\n return new Digest(data);\n }\n\n /// Checks if two digests are equal.\n ///\n /// @param other - The other digest to compare with\n /// @returns `true` if the digests are equal, `false` otherwise\n equals(other: Digest): boolean {\n if (this.#data.length !== other.#data.length) {\n return false;\n }\n for (let i = 0; i < this.#data.length; i++) {\n if (this.#data[i] !== other.#data[i]) {\n return false;\n }\n }\n return true;\n }\n\n /// Returns a string representation of the digest (short form).\n ///\n /// @returns The short hexadecimal representation\n toString(): string {\n return this.short();\n }\n\n /// Creates a deep copy of the digest.\n ///\n /// @returns A new Digest instance with the same data\n clone(): Digest {\n return new Digest(new Uint8Array(this.#data));\n }\n}\n\n/// Trait for types that can provide a digest.\n///\n/// This is equivalent to Rust's `DigestProvider` trait. Types that\n/// implement this interface can be used in contexts where a digest\n/// is needed for identity or integrity verification.\nexport interface DigestProvider {\n /// Returns the digest of this object.\n ///\n /// The digest uniquely identifies the semantic content of the object,\n /// regardless of whether parts of it are elided, encrypted, or compressed.\n digest(): Digest;\n}\n\n/// Helper function to create a digest from a string.\n///\n/// This is a convenience function for creating digests from text strings,\n/// which are encoded as UTF-8 before hashing.\n///\n/// @param text - The text to hash\n/// @returns A new Digest instance\n///\n/// @example\n/// ```typescript\n/// const digest = digestFromString(\"Hello, world!\");\n/// ```\nexport function digestFromString(text: string): Digest {\n const encoder = new TextEncoder();\n return Digest.fromImage(encoder.encode(text));\n}\n\n/// Helper function to create a digest from a number.\n///\n/// The number is converted to a big-endian byte representation before hashing.\n///\n/// @param num - The number to hash\n/// @returns A new Digest instance\n///\n/// @example\n/// ```typescript\n/// const digest = digestFromNumber(42);\n/// ```\nexport function digestFromNumber(num: number): Digest {\n const buffer = new ArrayBuffer(8);\n const view = new DataView(buffer);\n view.setFloat64(0, num, false); // big-endian\n return Digest.fromImage(new Uint8Array(buffer));\n}\n","/// Error types returned when operating on Gordian Envelopes.\n///\n/// These errors capture various conditions that can occur when working with\n/// envelopes, including structure validation, operation constraints, and\n/// extension-specific errors.\n///\n/// The errors are organized by category, reflecting the base envelope\n/// specification and various extensions defined in the Gordian Envelope\n/// Internet Draft and Blockchain Commons Research (BCR) documents.\n\nexport enum ErrorCode {\n // Base Specification\n ALREADY_ELIDED = \"ALREADY_ELIDED\",\n AMBIGUOUS_PREDICATE = \"AMBIGUOUS_PREDICATE\",\n INVALID_DIGEST = \"INVALID_DIGEST\",\n INVALID_FORMAT = \"INVALID_FORMAT\",\n MISSING_DIGEST = \"MISSING_DIGEST\",\n NONEXISTENT_PREDICATE = \"NONEXISTENT_PREDICATE\",\n NOT_WRAPPED = \"NOT_WRAPPED\",\n NOT_LEAF = \"NOT_LEAF\",\n NOT_ASSERTION = \"NOT_ASSERTION\",\n INVALID_ASSERTION = \"INVALID_ASSERTION\",\n\n // Attachments Extension\n INVALID_ATTACHMENT = \"INVALID_ATTACHMENT\",\n NONEXISTENT_ATTACHMENT = \"NONEXISTENT_ATTACHMENT\",\n AMBIGUOUS_ATTACHMENT = \"AMBIGUOUS_ATTACHMENT\",\n\n // Compression Extension\n ALREADY_COMPRESSED = \"ALREADY_COMPRESSED\",\n NOT_COMPRESSED = \"NOT_COMPRESSED\",\n\n // Symmetric Encryption Extension\n ALREADY_ENCRYPTED = \"ALREADY_ENCRYPTED\",\n NOT_ENCRYPTED = \"NOT_ENCRYPTED\",\n\n // Known Values Extension\n NOT_KNOWN_VALUE = \"NOT_KNOWN_VALUE\",\n\n // Public Key Encryption Extension\n UNKNOWN_RECIPIENT = \"UNKNOWN_RECIPIENT\",\n\n // Encrypted Key Extension\n UNKNOWN_SECRET = \"UNKNOWN_SECRET\",\n\n // Public Key Signing Extension\n UNVERIFIED_SIGNATURE = \"UNVERIFIED_SIGNATURE\",\n INVALID_OUTER_SIGNATURE_TYPE = \"INVALID_OUTER_SIGNATURE_TYPE\",\n INVALID_INNER_SIGNATURE_TYPE = \"INVALID_INNER_SIGNATURE_TYPE\",\n UNVERIFIED_INNER_SIGNATURE = \"UNVERIFIED_INNER_SIGNATURE\",\n INVALID_SIGNATURE_TYPE = \"INVALID_SIGNATURE_TYPE\",\n\n // SSKR Extension\n INVALID_SHARES = \"INVALID_SHARES\",\n SSKR = \"SSKR\",\n\n // Types Extension\n INVALID_TYPE = \"INVALID_TYPE\",\n AMBIGUOUS_TYPE = \"AMBIGUOUS_TYPE\",\n\n // Expressions Extension\n UNEXPECTED_RESPONSE_ID = \"UNEXPECTED_RESPONSE_ID\",\n INVALID_RESPONSE = \"INVALID_RESPONSE\",\n\n // External errors\n CBOR = \"CBOR\",\n COMPONENTS = \"COMPONENTS\",\n GENERAL = \"GENERAL\",\n}\n\nexport class EnvelopeError extends Error {\n readonly code: ErrorCode;\n declare readonly cause?: Error;\n\n constructor(code: ErrorCode, message: string, cause?: Error) {\n super(message);\n this.name = \"EnvelopeError\";\n this.code = code;\n if (cause !== undefined) {\n this.cause = cause;\n }\n\n // Maintains proper stack trace for where our error was thrown (only available on V8)\n if (\"captureStackTrace\" in Error) {\n (\n Error as {\n captureStackTrace(target: object, constructor: typeof EnvelopeError): void;\n }\n ).captureStackTrace(this, EnvelopeError);\n }\n }\n\n //\n // Base Specification\n /// Returned when attempting to compress or encrypt an envelope that has\n /// already been elided.\n ///\n /// This error occurs because an elided envelope only contains a digest\n /// reference and no longer has a subject that can be compressed or\n /// encrypted.\n static alreadyElided(): EnvelopeError {\n return new EnvelopeError(\n ErrorCode.ALREADY_ELIDED,\n \"envelope was elided, so it cannot be compressed or encrypted\",\n );\n }\n\n /// Returned when attempting to retrieve an assertion by predicate, but\n /// multiple matching assertions exist.\n ///\n /// For queries that expect a single result (like `objectForPredicate`),\n /// having multiple matching assertions is ambiguous and requires more\n /// specific targeting.\n static ambiguousPredicate(): EnvelopeError {\n return new EnvelopeError(\n ErrorCode.AMBIGUOUS_PREDICATE,\n \"more than one assertion matches the predicate\",\n );\n }\n\n /// Returned when a digest validation fails.\n ///\n /// This can occur when unwrapping an envelope, verifying signatures, or\n /// other operations that rely on the integrity of envelope digests.\n static invalidDigest(): EnvelopeError {\n return new EnvelopeError(ErrorCode.INVALID_DIGEST, \"digest did not match\");\n }\n\n /// Returned when an envelope's format is invalid.\n ///\n /// This typically occurs during parsing or decoding of an envelope from\n /// CBOR.\n static invalidFormat(): EnvelopeError {\n return new EnvelopeError(ErrorCode.INVALID_FORMAT, \"invalid format\");\n }\n\n /// Returned when a digest is expected but not found.\n ///\n /// This can occur when working with envelope structures that require digest\n /// information, such as when working with elided envelopes.\n static missingDigest(): EnvelopeError {\n return new EnvelopeError(ErrorCode.MISSING_DIGEST, \"a digest was expected but not found\");\n }\n\n /// Returned when attempting to retrieve an assertion by predicate, but no\n /// matching assertion exists.\n ///\n /// This error occurs with functions like `objectForPredicate` when the\n /// specified predicate doesn't match any assertion in the envelope.\n static nonexistentPredicate(): EnvelopeError {\n return new EnvelopeError(ErrorCode.NONEXISTENT_PREDICATE, \"no assertion matches the predicate\");\n }\n\n /// Returned when attempting to unwrap an envelope that wasn't wrapped.\n ///\n /// This error occurs when calling `Envelope.tryUnwrap` on an\n /// envelope that doesn't have the wrapped format.\n static notWrapped(): EnvelopeError {\n return new EnvelopeError(\n ErrorCode.NOT_WRAPPED,\n \"cannot unwrap an envelope that was not wrapped\",\n );\n }\n\n /// Returned when expecting an envelope's subject to be a leaf, but it\n /// isn't.\n ///\n /// This error occurs when calling methods that require access to a leaf\n /// value but the envelope's subject is an assertion, node, or elided.\n static notLeaf(): EnvelopeError {\n return new EnvelopeError(ErrorCode.NOT_LEAF, \"the envelope's subject is not a leaf\");\n }\n\n /// Returned when expecting an envelope's subject to be an assertion, but it\n /// isn't.\n ///\n /// This error occurs when calling methods that require an assertion\n /// structure but the envelope's subject has a different format.\n static notAssertion(): EnvelopeError {\n return new EnvelopeError(ErrorCode.NOT_ASSERTION, \"the envelope's subject is not an assertion\");\n }\n\n /// Returned when assertion is invalid\n static invalidAssertion(): EnvelopeError {\n return new EnvelopeError(\n ErrorCode.INVALID_ASSERTION,\n \"assertion must be a map with exactly one element\",\n );\n }\n\n //\n // Attachments Extension\n /// Returned when an attachment's format is invalid.\n ///\n /// This error occurs when an envelope contains an attachment with an\n /// invalid structure according to the Envelope Attachment specification\n /// (BCR-2023-006).\n static invalidAttachment(): EnvelopeError {\n return new EnvelopeError(ErrorCode.INVALID_ATTACHMENT, \"invalid attachment\");\n }\n\n /// Returned when an attachment is requested but does not exist.\n ///\n /// This error occurs when attempting to retrieve an attachment by ID that\n /// doesn't exist in the envelope.\n static nonexistentAttachment(): EnvelopeError {\n return new EnvelopeError(ErrorCode.NONEXISTENT_ATTACHMENT, \"nonexistent attachment\");\n }\n\n /// Returned when multiple attachments match a single query.\n ///\n /// This error occurs when multiple attachments have the same ID, making\n /// it ambiguous which attachment should be returned.\n static ambiguousAttachment(): EnvelopeError {\n return new EnvelopeError(ErrorCode.AMBIGUOUS_ATTACHMENT, \"ambiguous attachment\");\n }\n\n //\n // Compression Extension\n /// Returned when attempting to compress an envelope that is already\n /// compressed.\n ///\n /// This error occurs when calling compression functions on an envelope that\n /// already has compressed content, as defined in BCR-2023-005.\n static alreadyCompressed(): EnvelopeError {\n return new EnvelopeError(ErrorCode.ALREADY_COMPRESSED, \"envelope was already compressed\");\n }\n\n /// Returned when attempting to decompress an envelope that is not\n /// compressed.\n ///\n /// This error occurs when calling decompression functions on an envelope\n /// that doesn't contain compressed content.\n static notCompressed(): EnvelopeError {\n return new EnvelopeError(\n ErrorCode.NOT_COMPRESSED,\n \"cannot decompress an envelope that was not compressed\",\n );\n }\n\n //\n // Symmetric Encryption Extension\n /// Returned when attempting to encrypt an envelope that is already\n /// encrypted or compressed.\n ///\n /// This error occurs to prevent multiple layers of encryption or encryption\n /// of compressed data, which could reduce security, as defined in\n /// BCR-2023-004.\n static alreadyEncrypted(): EnvelopeError {\n return new EnvelopeError(\n ErrorCode.ALREADY_ENCRYPTED,\n \"envelope was already encrypted or compressed, so it cannot be encrypted\",\n );\n }\n\n /// Returned when attempting to decrypt an envelope that is not encrypted.\n ///\n /// This error occurs when calling decryption functions on an envelope that\n /// doesn't contain encrypted content.\n static notEncrypted(): EnvelopeError {\n return new EnvelopeError(\n ErrorCode.NOT_ENCRYPTED,\n \"cannot decrypt an envelope that was not encrypted\",\n );\n }\n\n //\n // Known Values Extension\n /// Returned when expecting an envelope's subject to be a known value, but\n /// it isn't.\n ///\n /// This error occurs when calling methods that require a known value (as\n /// defined in BCR-2023-003) but the envelope's subject is a different\n /// type.\n static notKnownValue(): EnvelopeError {\n return new EnvelopeError(\n ErrorCode.NOT_KNOWN_VALUE,\n \"the envelope's subject is not a known value\",\n );\n }\n\n //\n // Public Key Encryption Extension\n /// Returned when attempting to decrypt an envelope with a recipient that\n /// doesn't match.\n ///\n /// This error occurs when trying to use a private key to decrypt an\n /// envelope that wasn't encrypted for the corresponding public key.\n static unknownRecipient(): EnvelopeError {\n return new EnvelopeError(ErrorCode.UNKNOWN_RECIPIENT, \"unknown recipient\");\n }\n\n //\n // Encrypted Key Extension\n /// Returned when attempting to decrypt an envelope with a secret that\n /// doesn't match.\n ///\n /// This error occurs when trying to use a secret that does not correspond\n /// to the expected recipient, preventing successful decryption.\n static unknownSecret(): EnvelopeError {\n return new EnvelopeError(ErrorCode.UNKNOWN_SECRET, \"secret not found\");\n }\n\n //\n // Public Key Signing Extension\n /// Returned when a signature verification fails.\n ///\n /// This error occurs when a signature does not validate against its\n /// purported public key.\n static unverifiedSignature(): EnvelopeError {\n return new EnvelopeError(ErrorCode.UNVERIFIED_SIGNATURE, \"could not verify a signature\");\n }\n\n /// Returned when the outer signature object type is not `Signature`.\n static invalidOuterSignatureType(): EnvelopeError {\n return new EnvelopeError(\n ErrorCode.INVALID_OUTER_SIGNATURE_TYPE,\n \"unexpected outer signature object type\",\n );\n }\n\n /// Returned when the inner signature object type is not `Signature`.\n static invalidInnerSignatureType(): EnvelopeError {\n return new EnvelopeError(\n ErrorCode.INVALID_INNER_SIGNATURE_TYPE,\n \"unexpected inner signature object type\",\n );\n }\n\n /// Returned when the inner signature is not made with the same key as the\n /// outer signature.\n static unverifiedInnerSignature(): EnvelopeError {\n return new EnvelopeError(\n ErrorCode.UNVERIFIED_INNER_SIGNATURE,\n \"inner signature not made with same key as outer signature\",\n );\n }\n\n /// Returned when the signature object is not a `Signature`.\n static invalidSignatureType(): EnvelopeError {\n return new EnvelopeError(ErrorCode.INVALID_SIGNATURE_TYPE, \"unexpected signature object type\");\n }\n\n //\n // SSKR Extension\n /// Returned when SSKR shares are invalid or insufficient for\n /// reconstruction.\n ///\n /// This error occurs when attempting to join SSKR shares that are\n /// malformed, from different splits, or insufficient to meet the\n /// recovery threshold.\n static invalidShares(): EnvelopeError {\n return new EnvelopeError(ErrorCode.INVALID_SHARES, \"invalid SSKR shares\");\n }\n\n /// SSKR error wrapper\n static sskr(message: string, cause?: Error): EnvelopeError {\n return new EnvelopeError(ErrorCode.SSKR, `sskr error: ${message}`, cause);\n }\n\n //\n // Types Extension\n /// Returned when an envelope contains an invalid type.\n ///\n /// This error occurs when an envelope's type information doesn't match\n /// the expected format or value.\n static invalidType(): EnvelopeError {\n return new EnvelopeError(ErrorCode.INVALID_TYPE, \"invalid type\");\n }\n\n /// Returned when an envelope contains ambiguous type information.\n ///\n /// This error occurs when multiple type assertions exist that conflict\n /// with each other or create ambiguity about the envelope's type.\n static ambiguousType(): EnvelopeError {\n return new EnvelopeError(ErrorCode.AMBIGUOUS_TYPE, \"ambiguous type\");\n }\n\n //\n // Expressions Extension\n /// Returned when a response envelope has an unexpected ID.\n ///\n /// This error occurs when processing a response envelope and the ID doesn't\n /// match the expected request ID, as defined in BCR-2023-012.\n static unexpectedResponseId(): EnvelopeError {\n return new EnvelopeError(ErrorCode.UNEXPECTED_RESPONSE_ID, \"unexpected response ID\");\n }\n\n /// Returned when a response envelope is invalid.\n static invalidResponse(): EnvelopeError {\n return new EnvelopeError(ErrorCode.INVALID_RESPONSE, \"invalid response\");\n }\n\n //\n // External errors\n /// dcbor error wrapper\n static cbor(message: string, cause?: Error): EnvelopeError {\n return new EnvelopeError(ErrorCode.CBOR, `dcbor error: ${message}`, cause);\n }\n\n /// Components error wrapper\n static components(message: string, cause?: Error): EnvelopeError {\n return new EnvelopeError(ErrorCode.COMPONENTS, `components error: ${message}`, cause);\n }\n\n /// General error wrapper\n static general(message: string, cause?: Error): EnvelopeError {\n return new EnvelopeError(ErrorCode.GENERAL, `general error: ${message}`, cause);\n }\n\n /// Create error with custom message (equivalent to Rust's Error::msg)\n static msg(message: string): EnvelopeError {\n return EnvelopeError.general(message);\n }\n}\n\n/// Type alias for Result type (for Rust compatibility)\nexport type Result<T> = T;\n\n/// Export for backward compatibility\nexport type { EnvelopeError as Error };\n","import { Digest, type DigestProvider } from \"./digest\";\nimport { Envelope } from \"./envelope\";\nimport { type EnvelopeEncodable } from \"./envelope-encodable\";\nimport { EnvelopeError } from \"./error\";\nimport type { Cbor } from \"@bcts/dcbor\";\nimport { CborMap } from \"@bcts/dcbor\";\n\n/// A predicate-object relationship representing an assertion about a subject.\n///\n/// In Gordian Envelope, assertions are the basic building blocks for attaching\n/// information to a subject. An assertion consists of a predicate (which states\n/// what is being asserted) and an object (which provides the assertion's\n/// value).\n///\n/// Assertions can be attached to envelope subjects to form semantic statements\n/// like: \"subject hasAttribute value\" or \"document signedBy signature\".\n///\n/// Assertions are equivalent to RDF (Resource Description Framework) triples,\n/// where:\n/// - The envelope's subject is the subject of the triple\n/// - The assertion's predicate is the predicate of the triple\n/// - The assertion's object is the object of the triple\n///\n/// Generally you do not create an instance of this type directly, but\n/// instead use `Envelope.newAssertion()`, or the various functions\n/// on `Envelope` that create assertions.\nexport class Assertion implements DigestProvider {\n readonly #predicate: Envelope;\n readonly #object: Envelope;\n readonly #digest: Digest;\n\n /// Creates a new assertion and calculates its digest.\n ///\n /// This constructor takes a predicate and object, both of which are\n /// converted to envelopes using the `EnvelopeEncodable` trait. It then\n /// calculates the assertion's digest by combining the digests of the\n /// predicate and object.\n ///\n /// The digest is calculated according to the Gordian Envelope\n /// specification, which ensures that semantically equivalent assertions\n /// always produce the same digest.\n ///\n /// @param predicate - The predicate of the assertion, which states what is\n /// being asserted\n /// @param object - The object of the assertion, which provides the assertion's\n /// value\n ///\n /// @returns A new assertion with the specified predicate, object, and calculated\n /// digest.\n ///\n /// @example\n /// ```typescript\n /// // Direct method - create an assertion envelope\n /// const assertionEnvelope = Envelope.newAssertion(\"name\", \"Alice\");\n ///\n /// // Or create and add an assertion to a subject\n /// const person = Envelope.new(\"person\").addAssertion(\"name\", \"Alice\");\n /// ```\n constructor(predicate: EnvelopeEncodable | Envelope, object: EnvelopeEncodable | Envelope) {\n this.#predicate = predicate instanceof Envelope ? predicate : Envelope.new(predicate);\n this.#object = object instanceof Envelope ? object : Envelope.new(object);\n this.#digest = Digest.fromDigests([this.#predicate.digest(), this.#object.digest()]);\n }\n\n /// Returns the predicate of the assertion.\n ///\n /// The predicate states what is being asserted about the subject. It is\n /// typically a string or known value, but can be any envelope.\n ///\n /// @returns A clone of the assertion's predicate envelope.\n predicate(): Envelope {\n return this.#predicate;\n }\n\n /// Returns the object of the assertion.\n ///\n /// The object provides the value or content of the assertion. It can be any\n /// type that can be represented as an envelope.\n ///\n /// @returns A clone of the assertion's object envelope.\n object(): Envelope {\n return this.#object;\n }\n\n /// Returns the digest of this assertion.\n ///\n /// Implementation of the DigestProvider interface.\n ///\n /// @returns The assertion's digest\n digest(): Digest {\n return this.#digest;\n }\n\n /// Checks if two assertions are equal based on digest equality.\n ///\n /// Two assertions are considered equal if they have the same digest,\n /// regardless of how they were constructed.\n ///\n /// @param other - The other assertion to compare with\n /// @returns `true` if the assertions are equal, `false` otherwise\n equals(other: Assertion): boolean {\n return this.#digest.equals(other.#digest);\n }\n\n /// Converts this assertion to CBOR.\n ///\n /// The CBOR representation of an assertion is a map with a single key-value\n /// pair, where the key is the predicate's CBOR and the value is the object's\n /// CBOR.\n ///\n /// @returns A CBOR representation of this assertion\n toCbor(): Cbor {\n const map = new CborMap();\n map.set(this.#predicate.untaggedCbor(), this.#object.untaggedCbor());\n return map as unknown as Cbor;\n }\n\n /// Attempts to create an assertion from a CBOR value.\n ///\n /// The CBOR must be a map with exactly one entry, where the key represents\n /// the predicate and the value represents the object.\n ///\n /// @param cbor - The CBOR value to convert\n /// @returns A new Assertion instance\n /// @throws {EnvelopeError} If the CBOR is not a valid assertion\n static fromCbor(cbor: Cbor): Assertion {\n // Check if cbor is a Map\n if (!(cbor instanceof CborMap)) {\n throw EnvelopeError.invalidAssertion();\n }\n\n return Assertion.fromCborMap(cbor);\n }\n\n /// Attempts to create an assertion from a CBOR map.\n ///\n /// The map must have exactly one entry, where the key represents the\n /// predicate and the value represents the object. This is used in\n /// the deserialization process.\n ///\n /// @param map - The CBOR map to convert\n /// @returns A new Assertion instance\n /// @throws {EnvelopeError} If the map doesn't have exactly one entry\n static fromCborMap(map: CborMap): Assertion {\n if (map.size !== 1) {\n throw EnvelopeError.invalidAssertion();\n }\n\n const entries = Array.from(map.entries());\n const firstEntry = entries[0];\n if (firstEntry === undefined) {\n throw EnvelopeError.invalidAssertion();\n }\n const [predicateCbor, objectCbor] = firstEntry;\n\n const predicate = Envelope.fromUntaggedCbor(predicateCbor);\n\n const object = Envelope.fromUntaggedCbor(objectCbor);\n\n return new Assertion(predicate, object);\n }\n\n /// Creates a string representation of this assertion for debugging.\n ///\n /// @returns A string representation\n toString(): string {\n return `Assertion(${String(this.#predicate)}: ${String(this.#object)})`;\n }\n\n /// Creates a copy of this assertion.\n ///\n /// Since assertions are immutable and envelopes are cheap to clone,\n /// this returns the same instance.\n ///\n /// @returns This assertion instance\n clone(): Assertion {\n return this;\n }\n}\n","import { Envelope } from \"../base/envelope\";\nimport { EnvelopeError } from \"../base/error\";\nimport { type Digest } from \"../base/digest\";\nimport * as pako from \"pako\";\nimport { cborData, decodeCbor } from \"@bcts/dcbor\";\n\n/// Extension for compressing and decompressing envelopes.\n///\n/// This module provides functionality for compressing envelopes to reduce their\n/// size while maintaining their digests. Unlike elision, which removes content,\n/// compression preserves all the information in the envelope but represents it\n/// more efficiently.\n///\n/// Compression is implemented using the DEFLATE algorithm (via pako) and preserves\n/// the envelope's digest, making it compatible with the envelope's hierarchical\n/// digest tree structure.\n///\n/// @example\n/// ```typescript\n/// // Create an envelope with some larger, compressible content\n/// const lorem = \"Lorem ipsum dolor sit amet...\".repeat(10);\n/// const envelope = Envelope.new(lorem);\n///\n/// // Compress the envelope\n/// const compressed = envelope.compress();\n///\n/// // The compressed envelope has the same digest as the original\n/// console.log(envelope.digest().equals(compressed.digest())); // true\n///\n/// // But it takes up less space when serialized\n/// console.log(compressed.cborBytes().length < envelope.cborBytes().length); // true\n///\n/// // The envelope can be decompressed to recover the original content\n/// const decompressed = compressed.decompress();\n/// console.log(decompressed.asText() === lorem); // true\n/// ```\n\n/// Represents compressed data with optional digest\nexport class Compressed {\n readonly #compressedData: Uint8Array;\n readonly #digest?: Digest;\n\n constructor(compressedData: Uint8Array, digest?: Digest) {\n this.#compressedData = compressedData;\n if (digest !== undefined) {\n this.#digest = digest;\n }\n }\n\n /// Creates a Compressed instance from decompressed data\n static fromDecompressedData(decompressedData: Uint8Array, digest?: Digest): Compressed {\n const compressed = pako.deflate(decompressedData);\n return new Compressed(compressed, digest);\n }\n\n /// Returns the compressed data\n compressedData(): Uint8Array {\n return this.#compressedData;\n }\n\n /// Returns the optional digest\n digestOpt(): Digest | undefined {\n return this.#digest;\n }\n\n /// Decompresses the data\n decompress(): Uint8Array {\n return pako.inflate(this.#compressedData);\n }\n}\n\n/// Register compression extension methods on Envelope prototype\n/// This function is exported and called during module initialization\n/// to ensure Envelope is fully defined before attaching methods.\nexport function registerCompressExtension(): void {\n if (Envelope?.prototype === undefined) {\n return;\n }\n\n // Skip if already registered\n if (typeof Envelope.prototype.compress === \"function\") {\n return;\n }\n\n Envelope.prototype.compress = function (this: Envelope): Envelope {\n const c = this.case();\n\n // If already compressed, return as-is\n if (c.type === \"compressed\") {\n return this;\n }\n\n // Can't compress encrypted or elided envelopes\n if (c.type === \"encrypted\") {\n throw EnvelopeError.general(\"Cannot compress encrypted envelope\");\n }\n if (c.type === \"elided\") {\n throw EnvelopeError.general(\"Cannot compress elided envelope\");\n }\n\n // Compress the entire envelope\n const cbor = this.taggedCbor();\n\n const decompressedData = cborData(cbor);\n\n const compressed = Compressed.fromDecompressedData(decompressedData, this.digest());\n\n // Create a compressed envelope case\n return Envelope.fromCase({ type: \"compressed\", value: compressed });\n };\n\n /// Implementation of decompress()\n Envelope.prototype.decompress = function (this: Envelope): Envelope {\n const c = this.case();\n\n if (c.type !== \"compressed\") {\n throw EnvelopeError.general(\"Envelope is not compressed\");\n }\n\n const compressed = c.value;\n const digest = compressed.digestOpt();\n\n if (digest === undefined) {\n throw EnvelopeError.general(\"Missing digest in compressed envelope\");\n }\n\n // Verify the digest matches\n if (!digest.equals(this.digest())) {\n throw EnvelopeError.general(\"Invalid digest in compressed envelope\");\n }\n\n // Decompress the data\n const decompressedData = compressed.decompress();\n\n // Parse back to envelope\n\n const cbor = decodeCbor(decompressedData);\n const envelope = Envelope.fromTaggedCbor(cbor);\n\n // Verify the decompressed envelope has the correct digest\n if (!envelope.digest().equals(digest)) {\n throw EnvelopeError.general(\"Invalid digest after decompression\");\n }\n\n return envelope;\n };\n\n /// Implementation of compressSubject()\n Envelope.prototype.compressSubject = function (this: Envelope): Envelope {\n if (this.subject().isCompressed()) {\n return this;\n }\n\n const subject = this.subject().compress();\n return this.replaceSubject(subject);\n };\n\n /// Implementation of decompressSubject()\n Envelope.prototype.decompressSubject = function (this: Envelope): Envelope {\n if (this.subject().isCompressed()) {\n const subject = this.subject().decompress();\n return this.replaceSubject(subject);\n }\n\n return this;\n };\n\n /// Implementation of isCompressed()\n Envelope.prototype.isCompressed = function (this: Envelope): boolean {\n return this.case().type === \"compressed\";\n };\n}\n\n// Auto-register on module load - will be called again from index.ts\n// to ensure proper ordering after all modules are loaded\nregisterCompressExtension();\n","import { Envelope } from \"../base/envelope\";\nimport { EnvelopeError } from \"../base/error\";\nimport { type Digest } from \"../base/digest\";\nimport { cborData, decodeCbor } from \"@bcts/dcbor\";\nimport {\n aeadChaCha20Poly1305EncryptWithAad,\n aeadChaCha20Poly1305DecryptWithAad,\n SYMMETRIC_KEY_SIZE,\n SYMMETRIC_NONCE_SIZE,\n} from \"@bcts/crypto\";\nimport { SecureRandomNumberGenerator, rngRandomData, type RandomNumberGenerator } from \"@bcts/rand\";\n\n/// Extension for encrypting and decrypting envelopes using symmetric encryption.\n///\n/// This module extends Gordian Envelope with functions for symmetric encryption\n/// and decryption using the IETF-ChaCha20-Poly1305 construct. It enables\n/// privacy-enhancing operations by allowing envelope elements to be encrypted\n/// without changing the envelope's digest, similar to elision.\n///\n/// The encryption process preserves the envelope's digest tree structure, which\n/// means signatures, proofs, and other cryptographic artifacts remain valid\n/// even when parts of the envelope are encrypted.\n///\n/// @example\n/// ```typescript\n/// // Create an envelope\n/// const envelope = Envelope.new(\"Hello world\");\n///\n/// // Generate a symmetric key for encryption\n/// const key = SymmetricKey.generate();\n///\n/// // Encrypt the envelope's subject\n/// const encrypted = envelope.encryptSubject(key);\n///\n/// // The encrypted envelope has the same digest as the original\n/// console.log(envelope.digest().equals(encrypted.digest())); // true\n///\n/// // The subject is now encrypted\n/// console.log(encrypted.subject().isEncrypted()); // true\n///\n/// // Decrypt the envelope\n/// const decrypted = encrypted.decryptSubject(key);\n///\n/// // The decrypted envelope is equivalent to the original\n/// console.log(envelope.digest().equals(decrypted.digest())); // true\n/// ```\n\n/// Helper function to create a secure RNG\nfunction createSecureRng(): RandomNumberGenerator {\n return new SecureRandomNumberGenerator();\n}\n\n/// Represents a symmetric encryption key (256-bit)\n/// Matches bc-components-rust/src/symmetric/symmetric_key.rs\nexport class SymmetricKey {\n readonly #key: Uint8Array;\n\n constructor(key: Uint8Array) {\n if (key.length !== SYMMETRIC_KEY_SIZE) {\n throw new Error(`Symmetric key must be ${SYMMETRIC_KEY_SIZE} bytes`);\n }\n this.#key = key;\n }\n\n /// Generates a new random symmetric key\n static generate(): SymmetricKey {\n const rng = createSecureRng();\n const key = rngRandomData(rng, SYMMETRIC_KEY_SIZE);\n return new SymmetricKey(key);\n }\n\n /// Creates a symmetric key from existing bytes\n static from(key: Uint8Array): SymmetricKey {\n return new SymmetricKey(key);\n }\n\n /// Returns the raw key bytes\n data(): Uint8Array {\n return this.#key;\n }\n\n /// Encrypts data with associated digest (AAD)\n /// Uses IETF ChaCha20-Poly1305 with 12-byte nonce\n encrypt(plaintext: Uint8Array, digest: Digest): EncryptedMessage {\n const rng = createSecureRng();\n\n // Generate a random nonce (12 bytes for IETF ChaCha20-Poly1305)\n const nonce = rngRandomData(rng, SYMMETRIC_NONCE_SIZE);\n\n // Use digest as additional authenticated data (AAD)\n const aad = digest.data();\n\n // Encrypt using IETF ChaCha20-Poly1305\n const [ciphertext, authTag] = aeadChaCha20Poly1305EncryptWithAad(\n plaintext,\n this.#key,\n nonce,\n aad,\n );\n\n return new EncryptedMessage(ciphertext, nonce, authTag, digest);\n }\n\n /// Decrypts an encrypted message\n decrypt(message: EncryptedMessage): Uint8Array {\n const digest = message.aadDigest();\n if (digest === undefined) {\n throw EnvelopeError.general(\"Missing digest in encrypted message\");\n }\n\n const aad = digest.data();\n\n try {\n const plaintext = aeadChaCha20Poly1305DecryptWithAad(\n message.ciphertext(),\n this.#key,\n message.nonce(),\n aad,\n message.authTag(),\n );\n\n return plaintext;\n } catch (_error) {\n throw EnvelopeError.general(\"Decryption failed: invalid key or corrupted data\");\n }\n }\n}\n\n/// Represents an encrypted message with nonce, auth tag, and optional AAD digest\n/// Matches bc-components-rust/src/symmetric/encrypted_message.rs\nexport class EncryptedMessage {\n readonly #ciphertext: Uint8Array;\n readonly #nonce: Uint8Array;\n readonly #authTag: Uint8Array;\n readonly #aadDigest?: Digest;\n\n constructor(ciphertext: Uint8Array, nonce: Uint8Array, authTag: Uint8Array, aadDigest?: Digest) {\n this.#ciphertext = ciphertext;\n this.#nonce = nonce;\n this.#authTag = authTag;\n if (aadDigest !== undefined) {\n this.#aadDigest = aadDigest;\n }\n }\n\n /// Returns the ciphertext\n ciphertext(): Uint8Array {\n return this.#ciphertext;\n }\n\n /// Returns the nonce\n nonce(): Uint8Array {\n return this.#nonce;\n }\n\n /// Returns the authentication tag\n authTag(): Uint8Array {\n return this.#authTag;\n }\n\n /// Returns the optional AAD digest\n aadDigest(): Digest | undefined {\n return this.#aadDigest;\n }\n\n /// Returns the digest of this encrypted message (the AAD digest)\n digest(): Digest {\n if (this.#aadDigest === undefined) {\n throw new Error(\"Encrypted message missing AAD digest\");\n }\n return this.#aadDigest;\n }\n}\n\n/// Register encryption extension methods on Envelope prototype\n/// This function is exported and called during module initialization\n/// to ensure Envelope is fully defined before attaching methods.\nexport function registerEncryptExtension(): void {\n if (Envelope?.prototype === undefined) {\n return;\n }\n\n // Skip if already registered\n if (typeof Envelope.prototype.encryptSubject === \"function\") {\n return;\n }\n\n Envelope.prototype.encryptSubject = function (this: Envelope, key: SymmetricKey): Envelope {\n const c = this.case();\n\n // Can't encrypt if already encrypted or elided\n if (c.type === \"encrypted\") {\n throw EnvelopeError.general(\"Envelope is already encrypted\");\n }\n if (c.type === \"elided\") {\n throw EnvelopeError.general(\"Cannot encrypt elided envelope\");\n }\n\n // For node case, encrypt just the subject\n if (c.type === \"node\") {\n if (c.subject.isEncrypted()) {\n throw EnvelopeError.general(\"Subject is already encrypted\");\n }\n\n // Get the subject's CBOR data\n const subjectCbor = c.subject.taggedCbor();\n const encodedCbor = cborData(subjectCbor);\n const subjectDigest = c.subject.digest();\n\n // Encrypt the subject\n const encryptedMessage = key.encrypt(encodedCbor, subjectDigest);\n\n // Create encrypted envelope\n const encryptedSubject = Envelope.fromCase({\n type: \"encrypted\",\n message: encryptedMessage,\n });\n\n // Rebuild the node with encrypted subject and same assertions\n return Envelope.newWithAssertions(encryptedSubject, c.assertions);\n }\n\n // For other cases, encrypt the entire envelope\n const cbor = this.taggedCbor();\n const encodedCbor = cborData(cbor);\n const digest = this.digest();\n\n const encryptedMessage = key.encrypt(encodedCbor, digest);\n\n return Envelope.fromCase({\n type: \"encrypted\",\n message: encryptedMessage,\n });\n };\n\n /// Implementation of decryptSubject()\n Envelope.prototype.decryptSubject = function (this: Envelope, key: SymmetricKey): Envelope {\n const subjectCase = this.subject().case();\n\n if (subjectCase.type !== \"encrypted\") {\n throw EnvelopeError.general(\"Subject is not encrypted\");\n }\n\n const message = subjectCase.message;\n const subjectDigest = message.aadDigest();\n\n if (subjectDigest === undefined) {\n throw EnvelopeError.general(\"Missing digest in encrypted message\");\n }\n\n // Decrypt the subject\n const decryptedData = key.decrypt(message);\n\n // Parse back to envelope\n const cbor = decodeCbor(decryptedData);\n const resultSubject = Envelope.fromTaggedCbor(cbor);\n\n // Verify digest\n if (!resultSubject.digest().equals(subjectDigest)) {\n throw EnvelopeError.general(\"Invalid digest after decryption\");\n }\n\n const c = this.case();\n\n // If this is a node, rebuild with decrypted subject\n if (c.type === \"node\") {\n const result = Envelope.newWithAssertions(resultSubject, c.assertions);\n if (!result.digest().equals(c.digest)) {\n throw EnvelopeError.general(\"Invalid envelope digest after decryption\");\n }\n return result;\n }\n\n // Otherwise just return the decrypted subject\n return resultSubject;\n };\n\n /// Implementation of encrypt() - convenience method\n Envelope.prototype.encrypt = function (this: Envelope, key: SymmetricKey): Envelope {\n return this.wrap().encryptSubject(key);\n };\n\n /// Implementation of decrypt() - convenience method\n Envelope.prototype.decrypt = function (this: Envelope, key: SymmetricKey): Envelope {\n const decrypted = this.decryptSubject(key);\n return decrypted.unwrap();\n };\n\n /// Implementation of isEncrypted()\n Envelope.prototype.isEncrypted = function (this: Envelope): boolean {\n return this.case().type === \"encrypted\";\n };\n}\n\n// Auto-register on module load - will be called again from index.ts\n// to ensure proper ordering after all modules are loaded\nregisterEncryptExtension();\n","import { Digest, type DigestProvider } from \"./digest\";\nimport { Assertion } from \"./assertion\";\nimport { EnvelopeError } from \"./error\";\nimport type { EnvelopeEncodableValue } from \"./envelope-encodable\";\nimport { KnownValue } from \"@bcts/known-values\";\nimport type { Cbor, CborMap } from \"@bcts/dcbor\";\nimport {\n cbor,\n cborData,\n toTaggedValue,\n TAG_ENCODED_CBOR,\n MajorType,\n asByteString,\n asCborArray,\n asCborMap,\n asTaggedValue,\n tryExpectedTaggedValue,\n} from \"@bcts/dcbor\";\nimport { ENVELOPE, LEAF, ENCRYPTED, COMPRESSED } from \"@bcts/components\";\n\n// Type imports for extension method declarations\n// These are imported as types only to avoid circular dependencies at runtime\nimport type { ObscureAction, ObscureType } from \"./elide\";\nimport type { Visitor } from \"./walk\";\nimport type {\n SymmetricKey,\n SealedMessage,\n PublicKeyBase,\n PrivateKeyBase,\n Signer,\n Verifier,\n SignatureMetadata,\n} from \"../extension\";\n\n/// Import tag values from the tags registry\n/// These match the Rust reference implementation in bc-tags-rust\nconst TAG_ENVELOPE = ENVELOPE.value;\nconst TAG_LEAF = LEAF.value;\nconst TAG_ENCRYPTED = ENCRYPTED.value;\nconst TAG_COMPRESSED = COMPRESSED.value;\n\n/// The core structural variants of a Gordian Envelope.\n///\n/// Each variant represents a different structural form that an\n/// envelope can take, as defined in the Gordian Envelope IETF Internet Draft.\n/// The different cases provide different capabilities and serve different\n/// purposes in the envelope ecosystem.\n///\n/// The `EnvelopeCase` is the internal representation of an envelope's\n/// structure. While each case has unique properties, they all maintain a digest\n/// that ensures the integrity of the envelope.\n///\n/// It is advised to use the other Envelope APIs for most uses. Please see the\n/// queries module for more information on how to interact with envelopes.\nexport type EnvelopeCase =\n | {\n type: \"node\";\n /// The subject of the node\n subject: Envelope;\n /// The assertions attached to the subject\n assertions: Envelope[];\n /// The digest of the node\n digest: Digest;\n }\n | {\n type: \"leaf\";\n /// The CBOR value contained in the leaf\n cbor: Cbor;\n /// The digest of the leaf\n digest: Digest;\n }\n | {\n type: \"wrapped\";\n /// The envelope being wrapped\n envelope: Envelope;\n /// The digest of the wrapped envelope\n digest: Digest;\n }\n | {\n type: \"assertion\";\n /// The assertion\n assertion: Assertion;\n }\n | {\n type: \"elided\";\n /// The digest of the elided content\n digest: Digest;\n }\n | {\n type: \"knownValue\";\n /// The known value instance\n value: KnownValue;\n /// The digest of the known value\n digest: Digest;\n }\n | {\n type: \"encrypted\";\n /// The encrypted message\n message: EncryptedMessage;\n }\n | {\n type: \"compressed\";\n /// The compressed data\n value: Compressed;\n };\n\n// Import types from extension modules (will be available at runtime)\nimport { Compressed } from \"../extension/compress\";\nimport { EncryptedMessage } from \"../extension/encrypt\";\n\n/// A flexible container for structured data with built-in integrity\n/// verification.\n///\n/// Gordian Envelope is the primary data structure of this library. It provides a\n/// way to encapsulate and organize data with cryptographic integrity, privacy\n/// features, and selective disclosure capabilities.\n///\n/// Key characteristics of envelopes:\n///\n/// - **Immutability**: Envelopes are immutable. Operations that appear to\n/// \"modify\" an envelope actually create a new envelope. This immutability is\n/// fundamental to maintaining the integrity of the envelope's digest tree.\n///\n/// - **Efficient Cloning**: Envelopes use shallow copying for efficient O(1)\n/// cloning. Since they're immutable, clones share the same underlying data.\n///\n/// - **Semantic Structure**: Envelopes can represent various semantic\n/// relationships through subjects, predicates, and objects (similar to RDF\n/// triples).\n///\n/// - **Digest Tree**: Each envelope maintains a Merkle-like digest tree that\n/// ensures the integrity of its contents and enables verification of\n/// individual parts.\n///\n/// - **Privacy Features**: Envelopes support selective disclosure through\n/// elision, encryption, and compression of specific parts, while maintaining\n/// the overall integrity of the structure.\n///\n/// - **Deterministic Representation**: Envelopes use deterministic CBOR\n/// encoding to ensure consistent serialization across platforms.\n///\n/// The Gordian Envelope specification is defined in an IETF Internet Draft, and\n/// this implementation closely follows that specification.\n///\n/// @example\n/// ```typescript\n/// // Create an envelope representing a person\n/// const person = Envelope.new(\"person\")\n/// .addAssertion(\"name\", \"Alice\")\n/// .addAssertion(\"age\", 30)\n/// .addAssertion(\"email\", \"alice@example.com\");\n///\n/// // Create a partially redacted version by eliding the email\n/// const redacted = person.elideRemovingTarget(\n/// person.assertionWithPredicate(\"email\")\n/// );\n///\n/// // The digest of both envelopes remains the same\n/// assert(person.digest().equals(redacted.digest()));\n/// ```\nexport class Envelope implements DigestProvider {\n readonly #case: EnvelopeCase;\n\n /// Private constructor. Use static factory methods to create envelopes.\n ///\n /// @param envelopeCase - The envelope case variant\n private constructor(envelopeCase: EnvelopeCase) {\n this.#case = envelopeCase;\n }\n\n /// Returns a reference to the underlying envelope case.\n ///\n /// The `EnvelopeCase` enum represents the specific structural variant of\n /// this envelope. This method provides access to that underlying\n /// variant for operations that need to differentiate between the\n /// different envelope types.\n ///\n /// @returns The `EnvelopeCase` that defines this envelope's structure.\n case(): EnvelopeCase {\n return this.#case;\n }\n\n /// Creates an envelope with a subject, which can be any value that\n /// can be encoded as an envelope.\n ///\n /// @param subject - The subject value\n /// @returns A new envelope containing the subject\n ///\n /// @example\n /// ```typescript\n /// const envelope = Envelope.new(\"Hello, world!\");\n /// const numberEnvelope = Envelope.new(42);\n /// const binaryEnvelope = Envelope.new(new Uint8Array([1, 2, 3]));\n /// ```\n static new(subject: EnvelopeEncodableValue): Envelope {\n // Convert the subject to an envelope\n if (subject instanceof Envelope) {\n return subject;\n }\n\n // Handle primitives and create leaf envelopes\n return Envelope.newLeaf(subject);\n }\n\n /// Creates an envelope with a subject, or null if subject is undefined.\n ///\n /// @param subject - The optional subject value\n /// @returns A new envelope or null envelope\n static newOrNull(subject: EnvelopeEncodableValue | undefined): Envelope {\n if (subject === undefined || subject === null) {\n return Envelope.null();\n }\n return Envelope.new(subject);\n }\n\n /// Creates an envelope with a subject, or undefined if subject is undefined.\n ///\n /// @param subject - The optional subject value\n /// @returns A new envelope or undefined\n static newOrNone(subject: EnvelopeEncodableValue | undefined): Envelope | undefined {\n if (subject === undefined || subject === null) {\n return undefined;\n }\n return Envelope.new(subject);\n }\n\n /// Creates an envelope from an EnvelopeCase.\n ///\n /// This is an internal method used by extensions to create envelopes\n /// from custom case types like compressed or encrypted.\n ///\n /// @param envelopeCase - The envelope case to wrap\n /// @returns A new envelope with the given case\n static fromCase(envelopeCase: EnvelopeCase): Envelope {\n return new Envelope(envelopeCase);\n }\n\n /// Creates an assertion envelope with a predicate and object.\n ///\n /// @param predicate - The predicate of the assertion\n /// @param object - The object of the assertion\n /// @returns A new assertion envelope\n ///\n /// @example\n /// ```typescript\n /// const assertion = Envelope.newAssertion(\"name\", \"Alice\");\n /// ```\n static newAssertion(predicate: EnvelopeEncodableValue, object: EnvelopeEncodableValue): Envelope {\n const predicateEnv = predicate instanceof Envelope ? predicate : Envelope.new(predicate);\n const objectEnv = object instanceof Envelope ? object : Envelope.new(object);\n return Envelope.newWithAssertion(new Assertion(predicateEnv, objectEnv));\n }\n\n /// Creates a null envelope (containing CBOR null).\n ///\n /// @returns A null envelope\n static null(): Envelope {\n return Envelope.newLeaf(null);\n }\n\n //\n // Internal constructors\n //\n\n /// Creates an envelope with a subject and unchecked assertions.\n ///\n /// The assertions are sorted by digest and the envelope's digest is calculated.\n ///\n /// @param subject - The subject envelope\n /// @param uncheckedAssertions - The assertions to attach\n /// @returns A new node envelope\n static newWithUncheckedAssertions(subject: Envelope, uncheckedAssertions: Envelope[]): Envelope {\n if (uncheckedAssertions.length === 0) {\n throw new Error(\"Assertions array cannot be empty\");\n }\n\n // Sort assertions by digest\n const sortedAssertions = [...uncheckedAssertions].sort((a, b) => {\n const aHex = a.digest().hex();\n const bHex = b.digest().hex();\n return aHex.localeCompare(bHex);\n });\n\n // Calculate digest from subject and all assertions\n const digests = [subject.digest(), ...sortedAssertions.map((a) => a.digest())];\n const digest = Digest.fromDigests(digests);\n\n return new Envelope({\n type: \"node\",\n subject,\n assertions: sortedAssertions,\n digest,\n });\n }\n\n /// Creates an envelope with a subject and validated assertions.\n ///\n /// All assertions must be assertion or obscured envelopes.\n ///\n /// @param subject - The subject envelope\n /// @param assertions - The assertions to attach\n /// @returns A new node envelope\n /// @throws {EnvelopeError} If any assertion is not valid\n static newWithAssertions(subject: Envelope, assertions: Envelope[]): Envelope {\n // Validate that all assertions are assertion or obscured envelopes\n for (const assertion of assertions) {\n if (!assertion.isSubjectAssertion() && !assertion.isSubjectObscured()) {\n throw EnvelopeError.invalidFormat();\n }\n }\n\n return Envelope.newWithUncheckedAssertions(subject, assertions);\n }\n\n /// Creates an envelope with an assertion as its subject.\n ///\n /// @param assertion - The assertion\n /// @returns A new assertion envelope\n static newWithAssertion(assertion: Assertion): Envelope {\n return new Envelope({\n type: \"assertion\",\n assertion,\n });\n }\n\n /// Creates an envelope with a known value.\n ///\n /// @param value - The known value (can be a KnownValue instance or a number/bigint)\n /// @returns A new known value envelope\n static newWithKnownValue(value: KnownValue | number | bigint): Envelope {\n const knownValue = value instanceof KnownValue ? value : new KnownValue(value);\n // Calculate digest from CBOR encoding of the known value\n const digest = Digest.fromImage(knownValue.toCborData());\n return new Envelope({\n type: \"knownValue\",\n value: knownValue,\n digest,\n });\n }\n\n /// Creates an envelope with encrypted content.\n ///\n /// @param encryptedMessage - The encrypted message\n /// @returns A new encrypted envelope\n /// @throws {EnvelopeError} If the encrypted message doesn't have a digest\n static newWithEncrypted(encryptedMessage: EncryptedMessage): Envelope {\n // TODO: Validate that encrypted message has digest\n // if (!encryptedMessage.hasDigest()) {\n // throw EnvelopeError.missingDigest();\n // }\n return new Envelope({\n type: \"encrypted\",\n message: encryptedMessage,\n });\n }\n\n /// Creates an envelope with compressed content.\n ///\n /// @param compressed - The compressed data\n /// @returns A new compressed envelope\n /// @throws {EnvelopeError} If the compressed data doesn't have a digest\n static newWithCompressed(compressed: Compressed): Envelope {\n // TODO: Validate that compressed has digest\n // if (!compressed.hasDigest()) {\n // throw EnvelopeError.missingDigest();\n // }\n return new Envelope({\n type: \"compressed\",\n value: compressed,\n });\n }\n\n /// Creates an elided envelope containing only a digest.\n ///\n /// @param digest - The digest of the elided content\n /// @returns A new elided envelope\n static newElided(digest: Digest): Envelope {\n return new Envelope({\n type: \"elided\",\n digest,\n });\n }\n\n /// Creates a leaf envelope containing a CBOR value.\n ///\n /// @param value - The value to encode as CBOR\n /// @returns A new leaf envelope\n static newLeaf(value: unknown): Envelope {\n // Convert value to CBOR\n const cbor = Envelope.valueToCbor(value);\n\n // Calculate digest from CBOR bytes\n const cborBytes = Envelope.cborToBytes(cbor);\n const digest = Digest.fromImage(cborBytes);\n\n return new Envelope({\n type: \"leaf\",\n cbor,\n digest,\n });\n }\n\n /// Creates a wrapped envelope.\n ///\n /// @param envelope - The envelope to wrap\n /// @returns A new wrapped envelope\n static newWrapped(envelope: Envelope): Envelope {\n const digest = Digest.fromDigests([envelope.digest()]);\n return new Envelope({\n type: \"wrapped\",\n envelope,\n digest,\n });\n }\n\n /// Returns the digest of this envelope.\n ///\n /// Implementation of DigestProvider interface.\n ///\n /// @returns The envelope's digest\n digest(): Digest {\n const c = this.#case;\n switch (c.type) {\n case \"node\":\n case \"leaf\":\n case \"wrapped\":\n case \"elided\":\n case \"knownValue\":\n return c.digest;\n case \"assertion\":\n return c.assertion.digest();\n case \"encrypted\": {\n // Get digest from encrypted message (AAD)\n const digest = c.message.aadDigest();\n if (digest === undefined) {\n throw new Error(\"Encrypted envelope missing digest\");\n }\n return digest;\n }\n case \"compressed\": {\n // Get digest from compressed value\n const digest = c.value.digestOpt();\n if (digest === undefined) {\n throw new Error(\"Compressed envelope missing digest\");\n }\n return digest;\n }\n }\n }\n\n /// Returns the subject of this envelope.\n ///\n /// For different envelope cases:\n /// - Node: Returns the subject envelope\n /// - Other cases: Returns the envelope itself\n ///\n /// @returns The subject envelope\n subject(): Envelope {\n const c = this.#case;\n switch (c.type) {\n case \"node\":\n return c.subject;\n case \"leaf\":\n case \"wrapped\":\n case \"assertion\":\n case \"elided\":\n case \"knownValue\":\n case \"encrypted\":\n case \"compressed\":\n return this;\n }\n }\n\n /// Checks if the envelope's subject is an assertion.\n ///\n /// @returns `true` if the subject is an assertion, `false` otherwise\n isSubjectAssertion(): boolean {\n return this.#case.type === \"assertion\";\n }\n\n /// Checks if the envelope's subject is obscured (elided, encrypted, or compressed).\n ///\n /// @returns `true` if the subject is obscured, `false` otherwise\n isSubjectObscured(): boolean {\n const t = this.#case.type;\n return t === \"elided\" || t === \"encrypted\" || t === \"compressed\";\n }\n\n //\n // CBOR conversion helpers\n //\n\n /// Converts a value to CBOR.\n ///\n /// @param value - The value to convert\n /// @returns A CBOR representation\n private static valueToCbor(value: unknown): Cbor {\n // Import cbor function at runtime to avoid circular dependencies\n\n return cbor(value as Parameters<typeof cbor>[0]);\n }\n\n /// Converts CBOR to bytes.\n ///\n /// @param cbor - The CBOR value\n /// @returns Byte representation\n private static cborToBytes(cbor: Cbor): Uint8Array {\n // Import cborData function at runtime to avoid circular dependencies\n\n return cborData(cbor);\n }\n\n /// Returns the untagged CBOR representation of this envelope.\n ///\n /// @returns The untagged CBOR\n untaggedCbor(): Cbor {\n const c = this.#case;\n switch (c.type) {\n case \"node\": {\n // Array with subject followed by assertions\n const result = [c.subject.untaggedCbor()];\n for (const assertion of c.assertions) {\n result.push(assertion.untaggedCbor());\n }\n return Envelope.valueToCbor(result);\n }\n case \"leaf\":\n // Tagged with TAG_LEAF (204)\n return toTaggedValue(TAG_LEAF, c.cbor);\n case \"wrapped\":\n // Wrapped envelopes are tagged with TAG_ENVELOPE\n return c.envelope.taggedCbor();\n case \"assertion\":\n // Assertions convert to CBOR maps\n return c.assertion.toCbor();\n case \"elided\":\n // Elided is just the digest bytes\n return Envelope.valueToCbor(c.digest.data());\n case \"knownValue\":\n // TODO: Implement known value encoding\n throw new Error(\"Known value encoding not yet implemented\");\n case \"encrypted\": {\n // Encrypted is tagged with TAG_ENCRYPTED (40002)\n // Contains: [ciphertext, nonce, auth, optional_aad_digest]\n // Per BCR-2023-004 and BCR-2022-001\n const message = c.message;\n const digest = message.aadDigest();\n const arr =\n digest !== undefined\n ? [message.ciphertext(), message.nonce(), message.authTag(), digest.data()]\n : [message.ciphertext(), message.nonce(), message.authTag()];\n return toTaggedValue(TAG_ENCRYPTED, Envelope.valueToCbor(arr));\n }\n case \"compressed\": {\n // Compressed is tagged with TAG_COMPRESSED (40003)\n // and contains an array: [compressed_data, optional_digest]\n const digest = c.value.digestOpt();\n const data = c.value.compressedData();\n const arr = digest !== undefined ? [data, digest.data()] : [data];\n return toTaggedValue(TAG_COMPRESSED, Envelope.valueToCbor(arr));\n }\n }\n }\n\n /// Returns the tagged CBOR representation of this envelope.\n ///\n /// All envelopes are tagged with TAG_ENVELOPE (200).\n ///\n /// @returns The tagged CBOR\n taggedCbor(): Cbor {\n return toTaggedValue(TAG_ENVELOPE, this.untaggedCbor());\n }\n\n /// Creates an envelope from untagged CBOR.\n ///\n /// @param cbor - The untagged CBOR value\n /// @returns A new envelope\n static fromUntaggedCbor(cbor: Cbor): Envelope {\n // Check if it's a tagged value\n const tagged = asTaggedValue(cbor);\n if (tagged !== undefined) {\n const [tag, item] = tagged;\n switch (tag.value) {\n case TAG_LEAF:\n case TAG_ENCODED_CBOR:\n // Leaf envelope\n return Envelope.newLeaf(item);\n case TAG_ENVELOPE: {\n // Wrapped envelope\n const envelope = Envelope.fromUntaggedCbor(item);\n return Envelope.newWrapped(envelope);\n }\n case TAG_COMPRESSED: {\n // Compressed envelope: array with [compressed_data, optional_digest]\n const arr = asCborArray(item);\n if (arr === undefined || arr.length < 1 || arr.length > 2) {\n throw EnvelopeError.cbor(\"compressed envelope must have 1 or 2 elements\");\n }\n // We've already checked arr.length >= 1 above\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const compressedData = asByteString(arr.get(0)!);\n if (compressedData === undefined) {\n throw EnvelopeError.cbor(\"compressed data must be byte string\");\n }\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const digestBytes = arr.length === 2 ? asByteString(arr.get(1)!) : undefined;\n if (arr.length === 2 && digestBytes === undefined) {\n throw EnvelopeError.cbor(\"digest must be byte string\");\n }\n const digest = digestBytes !== undefined ? new Digest(digestBytes) : undefined;\n\n // Import Compressed class at runtime to avoid circular dependency\n\n const compressed = new Compressed(compressedData, digest);\n return Envelope.fromCase({ type: \"compressed\", value: compressed });\n }\n case TAG_ENCRYPTED: {\n // Encrypted envelope: array with [ciphertext, nonce, auth, optional_aad_digest]\n // Per BCR-2023-004 and BCR-2022-001\n const arr = asCborArray(item);\n if (arr === undefined || arr.length < 3 || arr.length > 4) {\n throw EnvelopeError.cbor(\"encrypted envelope must have 3 or 4 elements\");\n }\n // We've already checked arr.length >= 3 above\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const ciphertext = asByteString(arr.get(0)!);\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const nonce = asByteString(arr.get(1)!);\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const authTag = asByteString(arr.get(2)!);\n if (ciphertext === undefined || nonce === undefined || authTag === undefined) {\n throw EnvelopeError.cbor(\"ciphertext, nonce, and auth must be byte strings\");\n }\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const digestBytes = arr.length === 4 ? asByteString(arr.get(3)!) : undefined;\n if (arr.length === 4 && digestBytes === undefined) {\n throw EnvelopeError.cbor(\"aad digest must be byte string\");\n }\n const digest = digestBytes !== undefined ? new Digest(digestBytes) : undefined;\n\n const message = new EncryptedMessage(ciphertext, nonce, authTag, digest);\n return Envelope.fromCase({ type: \"encrypted\", message });\n }\n default:\n throw EnvelopeError.cbor(`unknown envelope tag: ${tag.value}`);\n }\n }\n\n // Check if it's a byte string (elided)\n const bytes = asByteString(cbor);\n if (bytes !== undefined) {\n if (bytes.length !== 32) {\n throw EnvelopeError.cbor(\"elided digest must be 32 bytes\");\n }\n return Envelope.newElided(new Digest(bytes));\n }\n\n // Check if it's an array (node)\n const array = asCborArray(cbor);\n if (array !== undefined) {\n if (array.length < 2) {\n throw EnvelopeError.cbor(\"node must have at least two elements\");\n }\n const subjectCbor = array.get(0);\n if (subjectCbor === undefined) {\n throw EnvelopeError.cbor(\"node subject is missing\");\n }\n const subject = Envelope.fromUntaggedCbor(subjectCbor);\n const assertions: Envelope[] = [];\n for (let i = 1; i < array.length; i++) {\n const assertionCbor = array.get(i);\n if (assertionCbor === undefined) {\n throw EnvelopeError.cbor(`node assertion at index ${i} is missing`);\n }\n assertions.push(Envelope.fromUntaggedCbor(assertionCbor));\n }\n return Envelope.newWithAssertions(subject, assertions);\n }\n\n // Check if it's a map (assertion)\n const map = asCborMap(cbor);\n if (map !== undefined) {\n const assertion = Assertion.fromCborMap(map);\n return Envelope.newWithAssertion(assertion);\n }\n\n // Handle known values (unsigned integers)\n if (cbor.type === MajorType.Unsigned) {\n const knownValue = new KnownValue(cbor.value as number | bigint);\n return Envelope.newWithKnownValue(knownValue);\n }\n\n throw EnvelopeError.cbor(\"invalid envelope format\");\n }\n\n /// Creates an envelope from tagged CBOR.\n ///\n /// @param cbor - The tagged CBOR value (should have TAG_ENVELOPE)\n /// @returns A new envelope\n static fromTaggedCbor(cbor: Cbor): Envelope {\n try {\n const untagged = tryExpectedTaggedValue(cbor, TAG_ENVELOPE);\n return Envelope.fromUntaggedCbor(untagged);\n } catch (error) {\n throw EnvelopeError.cbor(\n `expected TAG_ENVELOPE (${TAG_ENVELOPE})`,\n error instanceof Error ? error : undefined,\n );\n }\n }\n\n /// Adds an assertion to this envelope.\n ///\n /// @param predicate - The assertion predicate\n /// @param object - The assertion object\n /// @returns A new envelope with the assertion added\n ///\n /// @example\n /// ```typescript\n /// const person = Envelope.new(\"Alice\")\n /// .addAssertion(\"age\", 30)\n /// .addAssertion(\"city\", \"Boston\");\n /// ```\n addAssertion(predicate: EnvelopeEncodableValue, object: EnvelopeEncodableValue): Envelope {\n const assertion = Envelope.newAssertion(predicate, object);\n return this.addAssertionEnvelope(assertion);\n }\n\n /// Adds an assertion envelope to this envelope.\n ///\n /// @param assertion - The assertion envelope\n /// @returns A new envelope with the assertion added\n addAssertionEnvelope(assertion: Envelope): Envelope {\n const c = this.#case;\n\n // If this is already a node, add to existing assertions\n if (c.type === \"node\") {\n return Envelope.newWithAssertions(c.subject, [...c.assertions, assertion]);\n }\n\n // Otherwise, create a new node with this envelope as subject\n return Envelope.newWithAssertions(this, [assertion]);\n }\n\n /// Creates a string representation of this envelope.\n ///\n /// @returns A string representation\n toString(): string {\n return `Envelope(${this.#case.type})`;\n }\n\n /// Creates a shallow copy of this envelope.\n ///\n /// Since envelopes are immutable, this returns the same instance.\n ///\n /// @returns This envelope\n clone(): Envelope {\n return this;\n }\n\n //\n // Format methods (implemented via prototype extension in format module)\n //\n\n /// Returns a tree-formatted string representation of the envelope.\n ///\n /// The tree format displays the hierarchical structure of the envelope,\n /// showing subjects, assertions, and their relationships.\n ///\n /// @param options - Optional formatting options\n /// @returns A tree-formatted string\n declare treeFormat: (options?: {\n hideNodes?: boolean;\n highlightDigests?: Set<string>;\n digestDisplay?: \"short\" | \"full\";\n }) => string;\n\n /// Returns a short identifier for this envelope based on its digest.\n ///\n /// @param format - Format for the digest ('short' or 'full')\n /// @returns A digest identifier string\n declare shortId: (format?: \"short\" | \"full\") => string;\n\n /// Returns a summary string for this envelope.\n ///\n /// @param maxLength - Maximum length of the summary\n /// @returns A summary string\n declare summary: (maxLength?: number) => string;\n\n /// Returns a hex representation of the envelope's CBOR encoding.\n ///\n /// @returns A hex string\n declare hex: () => string;\n\n /// Returns the CBOR-encoded bytes of the envelope.\n ///\n /// @returns The CBOR bytes\n declare cborBytes: () => Uint8Array;\n\n /// Returns a CBOR diagnostic notation string for the envelope.\n ///\n /// @returns A diagnostic string\n declare diagnostic: () => string;\n\n //\n // Extension methods (implemented via prototype extension in extension modules)\n // These declarations ensure TypeScript recognizes the methods when consuming the package\n //\n\n // From assertions.ts\n declare addAssertionEnvelopes: (assertions: Envelope[]) => Envelope;\n declare addOptionalAssertionEnvelope: (assertion: Envelope | undefined) => Envelope;\n declare addOptionalAssertion: (\n predicate: EnvelopeEncodableValue,\n object: EnvelopeEncodableValue | undefined,\n ) => Envelope;\n declare addNonemptyStringAssertion: (predicate: EnvelopeEncodableValue, str: string) => Envelope;\n declare addAssertions: (envelopes: Envelope[]) => Envelope;\n declare addAssertionIf: (\n condition: boolean,\n predicate: EnvelopeEncodableValue,\n object: EnvelopeEncodableValue,\n ) => Envelope;\n declare addAssertionEnvelopeIf: (condition: boolean, assertionEnvelope: Envelope) => Envelope;\n declare removeAssertion: (target: Envelope) => Envelope;\n declare replaceAssertion: (assertion: Envelope, newAssertion: Envelope) => Envelope;\n declare replaceSubject: (subject: Envelope) => Envelope;\n\n // From elide.ts\n declare elide: () => Envelope;\n declare elideRemovingSetWithAction: (target: Set<Digest>, action: ObscureAction) => Envelope;\n declare elideRemovingSet: (target: Set<Digest>) => Envelope;\n declare elideRemovingArrayWithAction: (\n target: DigestProvider[],\n action: ObscureAction,\n ) => Envelope;\n declare elideRemovingArray: (target: DigestProvider[]) => Envelope;\n declare elideRemovingTargetWithAction: (\n target: DigestProvider,\n action: ObscureAction,\n ) => Envelope;\n declare elideRemovingTarget: (target: DigestProvider) => Envelope;\n declare elideRevealingSetWithAction: (target: Set<Digest>, action: ObscureAction) => Envelope;\n declare elideRevealingSet: (target: Set<Digest>) => Envelope;\n declare elideRevealingArrayWithAction: (\n target: DigestProvider[],\n action: ObscureAction,\n ) => Envelope;\n declare elideRevealingArray: (target: DigestProvider[]) => Envelope;\n declare elideRevealingTargetWithAction: (\n target: DigestProvider,\n action: ObscureAction,\n ) => Envelope;\n declare elideRevealingTarget: (target: DigestProvider) => Envelope;\n declare unelide: (envelope: Envelope) => Envelope;\n declare nodesMatching: (\n targetDigests: Set<Digest> | undefined,\n obscureTypes: ObscureType[],\n ) => Set<Digest>;\n declare walkUnelide: (envelopes: Envelope[]) => Envelope;\n declare walkReplace: (target: Set<Digest>, replacement: Envelope) => Envelope;\n declare isIdenticalTo: (other: Envelope) => boolean;\n\n // From leaf.ts\n declare tryLeaf: () => Cbor;\n declare extractString: () => string;\n declare extractNumber: () => number;\n declare extractBoolean: () => boolean;\n declare extractBytes: () => Uint8Array;\n declare extractNull: () => null;\n\n // From queries.ts\n declare isFalse: () => boolean;\n declare isTrue: () => boolean;\n declare isBool: () => boolean;\n declare isNumber: () => boolean;\n declare isSubjectNumber: () => boolean;\n declare isNaN: () => boolean;\n declare isSubjectNaN: () => boolean;\n declare isNull: () => boolean;\n declare tryByteString: () => Uint8Array;\n declare asByteString: () => Uint8Array | undefined;\n declare asArray: () => readonly Cbor[] | undefined;\n declare asMap: () => CborMap | undefined;\n declare asText: () => string | undefined;\n declare asLeaf: () => Cbor | undefined;\n declare hasAssertions: () => boolean;\n declare asAssertion: () => Envelope | undefined;\n declare tryAssertion: () => Envelope;\n declare asPredicate: () => Envelope | undefined;\n declare tryPredicate: () => Envelope;\n declare asObject: () => Envelope | undefined;\n declare tryObject: () => Envelope;\n declare isAssertion: () => boolean;\n declare isElided: () => boolean;\n declare isLeaf: () => boolean;\n declare isNode: () => boolean;\n declare isWrapped: () => boolean;\n declare isInternal: () => boolean;\n declare isObscured: () => boolean;\n declare assertions: () => Envelope[];\n declare assertionsWithPredicate: (predicate: EnvelopeEncodableValue) => Envelope[];\n declare assertionWithPredicate: (predicate: EnvelopeEncodableValue) => Envelope;\n declare optionalAssertionWithPredicate: (\n predicate: EnvelopeEncodableValue,\n ) => Envelope | undefined;\n declare objectForPredicate: (predicate: EnvelopeEncodableValue) => Envelope;\n declare optionalObjectForPredicate: (predicate: EnvelopeEncodableValue) => Envelope | undefined;\n declare objectsForPredicate: (predicate: EnvelopeEncodableValue) => Envelope[];\n declare elementsCount: () => number;\n\n // From walk.ts\n declare walk: <State>(hideNodes: boolean, state: State, visit: Visitor<State>) => void;\n\n // From wrap.ts\n declare wrap: () => Envelope;\n declare tryUnwrap: () => Envelope;\n declare unwrap: () => Envelope;\n\n // From attachment.ts\n declare addAttachment: (\n payload: EnvelopeEncodableValue,\n vendor: string,\n conformsTo?: string,\n ) => Envelope;\n declare attachmentPayload: () => Envelope;\n declare attachmentVendor: () => string;\n declare attachmentConformsTo: () => string | undefined;\n declare attachments: () => Envelope[];\n declare attachmentsWithVendorAndConformsTo: (vendor?: string, conformsTo?: string) => Envelope[];\n\n // From compress.ts\n declare compress: () => Envelope;\n declare decompress: () => Envelope;\n declare compressSubject: () => Envelope;\n declare decompressSubject: () => Envelope;\n declare isCompressed: () => boolean;\n\n // From encrypt.ts\n declare encryptSubject: (key: SymmetricKey) => Envelope;\n declare decryptSubject: (key: SymmetricKey) => Envelope;\n declare encrypt: (key: SymmetricKey) => Envelope;\n declare decrypt: (key: SymmetricKey) => Envelope;\n declare isEncrypted: () => boolean;\n\n // From proof.ts\n declare proofContainsSet: (target: Set<Digest>) => Envelope | undefined;\n declare proofContainsTarget: (target: Envelope) => Envelope | undefined;\n declare confirmContainsSet: (target: Set<Digest>, proof: Envelope) => boolean;\n declare confirmContainsTarget: (target: Envelope, proof: Envelope) => boolean;\n\n // From recipient.ts\n declare encryptSubjectToRecipient: (recipientPublicKey: PublicKeyBase) => Envelope;\n declare encryptSubjectToRecipients: (recipients: PublicKeyBase[]) => Envelope;\n declare addRecipient: (recipientPublicKey: PublicKeyBase, contentKey: SymmetricKey) => Envelope;\n declare decryptSubjectToRecipient: (recipientPrivateKey: PrivateKeyBase) => Envelope;\n declare decryptToRecipient: (recipientPrivateKey: PrivateKeyBase) => Envelope;\n declare encryptToRecipients: (recipients: PublicKeyBase[]) => Envelope;\n declare recipients: () => SealedMessage[];\n\n // From salt.ts\n declare addSalt: () => Envelope;\n declare addSaltWithLength: (count: number) => Envelope;\n declare addSaltBytes: (saltBytes: Uint8Array) => Envelope;\n declare addSaltInRange: (min: number, max: number) => Envelope;\n\n // From signature.ts\n declare addSignature: (signer: Signer) => Envelope;\n declare addSignatureWithMetadata: (signer: Signer, metadata?: SignatureMetadata) => Envelope;\n declare addSignatures: (signers: Signer[]) => Envelope;\n declare hasSignatureFrom: (verifier: Verifier) => boolean;\n declare verifySignatureFrom: (verifier: Verifier) => Envelope;\n declare signatures: () => Envelope[];\n\n // From types.ts\n declare addType: (object: EnvelopeEncodableValue) => Envelope;\n declare types: () => Envelope[];\n declare getType: () => Envelope;\n declare hasType: (t: EnvelopeEncodableValue) => boolean;\n declare checkType: (t: EnvelopeEncodableValue) => void;\n\n // Static methods from extensions\n declare static newAttachment: (\n payload: EnvelopeEncodableValue,\n vendor: string,\n conformsTo?: string,\n ) => Envelope;\n}\n","import type { Envelope } from \"./envelope\";\n\n/// A trait for types that can be encoded as a Gordian Envelope.\n///\n/// This interface defines the contract for converting a value into an envelope.\n/// Types implementing this interface can be used directly with envelope\n/// construction functions without explicit conversion.\n///\n/// There are numerous built-in implementations for common types including:\n/// - Primitive types (numbers, strings, booleans)\n/// - CBOR values\n/// - Cryptographic types (digests, keys, etc.)\n/// - Assertions\n/// - Other envelopes\n///\n/// @example\n/// ```typescript\n/// // String implements EnvelopeEncodable\n/// const e1 = Envelope.new(\"Hello\");\n///\n/// // Numbers implement EnvelopeEncodable\n/// const e2 = Envelope.new(42);\n///\n/// // Using in envelope construction\n/// const envelope = Envelope.new(\"subject\")\n/// .addAssertion(\"name\", \"Alice\") // Uses EnvelopeEncodable for both predicate and object\n/// .addAssertion(\"age\", 30); // Uses EnvelopeEncodable for the numeric object\n/// ```\nexport interface EnvelopeEncodable {\n /// Converts this value into a Gordian Envelope.\n ///\n /// This is the core method of the interface, converting the implementing type\n /// into an envelope representation. Most implementations will convert the\n /// value to a leaf envelope containing the value.\n ///\n /// @returns A new envelope containing the value.\n intoEnvelope(): Envelope;\n}\n\n/// Type guard to check if a value implements EnvelopeEncodable.\n///\n/// @param value - The value to check\n/// @returns `true` if the value implements EnvelopeEncodable, `false` otherwise\nexport function isEnvelopeEncodable(value: unknown): value is EnvelopeEncodable {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"intoEnvelope\" in value &&\n typeof (value as EnvelopeEncodable).intoEnvelope === \"function\"\n );\n}\n\n/// Helper type for values that can be encoded as envelopes.\n///\n/// This includes:\n/// - Types that directly implement EnvelopeEncodable\n/// - Primitive types (string, number, boolean)\n/// - Uint8Array (for binary data)\n/// - null and undefined\n///\n/// The Envelope class will handle conversion of these types automatically.\nexport type EnvelopeEncodableValue =\n | EnvelopeEncodable\n | string\n | number\n | boolean\n | bigint\n | Uint8Array\n | null\n | undefined\n | Envelope;\n","import type { Cbor } from \"@bcts/dcbor\";\nimport {\n type CborTagged,\n type CborTaggedEncodable,\n type CborTaggedDecodable,\n tagsForValues,\n cborData,\n decodeCbor,\n} from \"@bcts/dcbor\";\nimport { ENVELOPE } from \"@bcts/components\";\nimport { Envelope } from \"./envelope\";\n\nconst TAG_ENVELOPE = ENVELOPE.value;\n\n/// Support for CBOR encoding and decoding of `Envelope`.\n///\n/// All envelopes are tagged with the `envelope` tag (200). Within that tag,\n/// each of the envelope cases has a unique CBOR signature:\n///\n/// * `.node` contains a CBOR array, the first element of which is the subject,\n/// followed by one or more assertions.\n/// * `.leaf` is tagged #6.24 (TAG_ENCODED_CBOR) or #6.204 (TAG_LEAF), which\n/// are the IANA tag for embedded CBOR.\n/// * `.wrapped` is tagged with the `envelope` tag.\n/// * `.assertion` is a single-element map `{predicate: object}`.\n/// * `.knownValue` is an unsigned 64-bit integer.\n/// * `.encrypted` is tagged with the `crypto-msg` tag.\n/// * `.elided` is a byte string of length 32 (the digest).\n/// * `.compressed` is tagged with the `compressed` tag.\n///\n/// This module provides implementations of the CBOR encoding/decoding traits\n/// for the Envelope type, matching the Rust bc-envelope implementation.\n\n/// Implements CborTagged interface for Envelope.\n///\n/// Returns the tags that should be used for CBOR encoding.\nexport class EnvelopeCBORTagged implements CborTagged {\n cborTags(): ReturnType<typeof tagsForValues> {\n return tagsForValues([TAG_ENVELOPE]);\n }\n\n static cborTags(): number[] {\n return tagsForValues([TAG_ENVELOPE]).map((tag) => Number(tag.value));\n }\n}\n\n/// Implements CborTaggedEncodable for Envelope.\n///\n/// Provides the untagged CBOR representation of an envelope.\nexport class EnvelopeCBORTaggedEncodable implements CborTaggedEncodable {\n constructor(private readonly envelope: Envelope) {}\n\n cborTags(): ReturnType<typeof tagsForValues> {\n return tagsForValues([TAG_ENVELOPE]);\n }\n\n untaggedCbor(): Cbor {\n return this.envelope.untaggedCbor();\n }\n\n taggedCbor(): Cbor {\n return this.envelope.taggedCbor();\n }\n}\n\n/// Implements CborTaggedDecodable for Envelope.\n///\n/// Provides the ability to decode an envelope from untagged CBOR.\nexport class EnvelopeCBORTaggedDecodable<T = Envelope> implements CborTaggedDecodable<T> {\n cborTags(): ReturnType<typeof tagsForValues> {\n return tagsForValues([TAG_ENVELOPE]);\n }\n\n static fromUntaggedCbor(cbor: Cbor): Envelope {\n return Envelope.fromUntaggedCbor(cbor);\n }\n\n static fromTaggedCbor(cbor: Cbor): Envelope {\n return Envelope.fromTaggedCbor(cbor);\n }\n\n fromUntaggedCbor(cbor: Cbor): T {\n return Envelope.fromUntaggedCbor(cbor) as T;\n }\n\n fromTaggedCbor(cbor: Cbor): T {\n return Envelope.fromTaggedCbor(cbor) as T;\n }\n}\n\n/// Convenience function to convert an Envelope to CBOR.\n///\n/// @param envelope - The envelope to convert\n/// @returns The CBOR representation (tagged)\nexport function envelopeToCbor(envelope: Envelope): Cbor {\n return envelope.taggedCbor();\n}\n\n/// Convenience function to create an Envelope from CBOR.\n///\n/// @param cbor - The CBOR value (expected to be tagged with TAG_ENVELOPE)\n/// @returns A new Envelope\nexport function envelopeFromCbor(cbor: Cbor): Envelope {\n return Envelope.fromTaggedCbor(cbor);\n}\n\n/// Convenience function to encode an Envelope to CBOR bytes.\n///\n/// @param envelope - The envelope to encode\n/// @returns The CBOR bytes\nexport function envelopeToBytes(envelope: Envelope): Uint8Array {\n return cborData(envelope.taggedCbor());\n}\n\n/// Convenience function to decode an Envelope from CBOR bytes.\n///\n/// @param bytes - The CBOR bytes\n/// @returns A new Envelope\nexport function envelopeFromBytes(bytes: Uint8Array): Envelope {\n const cbor = decodeCbor(bytes);\n return Envelope.fromTaggedCbor(cbor);\n}\n","import type { Cbor } from \"@bcts/dcbor\";\nimport { tryIntoText, tryIntoBool, tryIntoByteString, isNull, decodeCbor } from \"@bcts/dcbor\";\nimport { Envelope } from \"./envelope\";\nimport { EnvelopeError } from \"./error\";\n\n/// Provides functions for extracting typed values from envelopes.\n///\n/// This module defines conversion functions that parallel Rust's `TryFrom<Envelope>`\n/// implementations. These allow extracting specific types from envelope leaf values.\n///\n/// In the Rust version, a macro (`impl_envelope_decodable!`) is used to generate\n/// these implementations for many types. In TypeScript, we provide explicit\n/// conversion functions instead.\n\n/// Extracts a string value from an envelope.\n///\n/// @param envelope - The envelope to extract from\n/// @returns The string value\n/// @throws {EnvelopeError} If the envelope is not a leaf or cannot be converted\nexport function extractString(envelope: Envelope): string {\n const cbor = envelope.tryLeaf();\n try {\n return tryIntoText(cbor);\n } catch (error) {\n throw EnvelopeError.cbor(\n \"envelope does not contain a string\",\n error instanceof Error ? error : undefined,\n );\n }\n}\n\n/// Extracts a number value from an envelope.\n///\n/// @param envelope - The envelope to extract from\n/// @returns The number value\n/// @throws {EnvelopeError} If the envelope is not a leaf or cannot be converted\nexport function extractNumber(envelope: Envelope): number {\n const cbor = envelope.tryLeaf();\n\n // Handle unsigned, negative, and simple (float) types\n if (\"type\" in cbor) {\n switch (cbor.type) {\n case 0: // MajorType.Unsigned\n return typeof cbor.value === \"bigint\" ? Number(cbor.value) : cbor.value;\n case 1: {\n // MajorType.Negative\n // Negative values are stored as magnitude, convert back\n const magnitude = typeof cbor.value === \"bigint\" ? Number(cbor.value) : cbor.value;\n return -magnitude - 1;\n }\n case 7: // MajorType.Simple\n if (\n typeof cbor.value === \"object\" &&\n cbor.value !== null &&\n \"type\" in cbor.value &&\n cbor.value.type === \"Float\"\n ) {\n return cbor.value.value;\n }\n break;\n case 2: // MajorType.ByteString\n case 3: // MajorType.TextString\n case 4: // MajorType.Array\n case 5: // MajorType.Map\n case 6: // MajorType.Tag\n // These CBOR types don't represent numbers\n break;\n }\n }\n\n throw EnvelopeError.cbor(\"envelope does not contain a number\");\n}\n\n/// Extracts a boolean value from an envelope.\n///\n/// @param envelope - The envelope to extract from\n/// @returns The boolean value\n/// @throws {EnvelopeError} If the envelope is not a leaf or cannot be converted\nexport function extractBoolean(envelope: Envelope): boolean {\n const cbor = envelope.tryLeaf();\n try {\n return tryIntoBool(cbor);\n } catch (error) {\n throw EnvelopeError.cbor(\n \"envelope does not contain a boolean\",\n error instanceof Error ? error : undefined,\n );\n }\n}\n\n/// Extracts a byte array value from an envelope.\n///\n/// @param envelope - The envelope to extract from\n/// @returns The byte array value\n/// @throws {EnvelopeError} If the envelope is not a leaf or cannot be converted\nexport function extractBytes(envelope: Envelope): Uint8Array {\n const cbor = envelope.tryLeaf();\n try {\n return tryIntoByteString(cbor);\n } catch (error) {\n throw EnvelopeError.cbor(\n \"envelope does not contain bytes\",\n error instanceof Error ? error : undefined,\n );\n }\n}\n\n/// Extracts null from an envelope.\n///\n/// @param envelope - The envelope to extract from\n/// @throws {EnvelopeError} If the envelope is not a leaf containing null\nexport function extractNull(envelope: Envelope): null {\n const cbor = envelope.tryLeaf();\n if (isNull(cbor)) {\n return null;\n }\n throw EnvelopeError.cbor(\"envelope does not contain null\");\n}\n\n/// Static methods for creating envelopes from CBOR data.\n///\n/// These are convenience methods that mirror the Rust implementation.\nexport class EnvelopeDecoder {\n /// Creates an envelope from a CBOR value.\n ///\n /// @param cbor - The CBOR value to convert into an envelope\n /// @returns A new envelope created from the CBOR data\n /// @throws {EnvelopeError} If the CBOR does not represent a valid envelope\n static tryFromCbor(cbor: Cbor): Envelope {\n try {\n return Envelope.fromTaggedCbor(cbor);\n } catch (error) {\n throw EnvelopeError.cbor(\"invalid envelope CBOR\", error instanceof Error ? error : undefined);\n }\n }\n\n /// Creates an envelope from raw CBOR binary data.\n ///\n /// @param data - The raw CBOR binary data to convert into an envelope\n /// @returns A new envelope created from the CBOR data\n /// @throws {EnvelopeError} If the data is not valid CBOR or does not\n /// represent a valid envelope structure\n static tryFromCborData(data: Uint8Array): Envelope {\n try {\n const cbor = decodeCbor(data);\n return EnvelopeDecoder.tryFromCbor(cbor);\n } catch (error) {\n throw EnvelopeError.cbor(\n \"invalid envelope CBOR data\",\n error instanceof Error ? error : undefined,\n );\n }\n }\n}\n\n/// Add the tryLeaf method to Envelope prototype.\n///\n/// This extracts the leaf CBOR value from an envelope.\nEnvelope.prototype.tryLeaf = function (this: Envelope): Cbor {\n const c = this.case();\n if (c.type !== \"leaf\") {\n throw EnvelopeError.notLeaf();\n }\n return c.cbor;\n};\n\n/// Add extraction convenience methods to Envelope prototype\nEnvelope.prototype.extractString = function (this: Envelope): string {\n return extractString(this);\n};\n\nEnvelope.prototype.extractNumber = function (this: Envelope): number {\n return extractNumber(this);\n};\n\nEnvelope.prototype.extractBoolean = function (this: Envelope): boolean {\n return extractBoolean(this);\n};\n\nEnvelope.prototype.extractBytes = function (this: Envelope): Uint8Array {\n return extractBytes(this);\n};\n\nEnvelope.prototype.extractNull = function (this: Envelope): null {\n return extractNull(this);\n};\n","import { type Digest, type DigestProvider } from \"./digest\";\nimport { Envelope } from \"./envelope\";\nimport { Assertion } from \"./assertion\";\nimport { EnvelopeError } from \"./error\";\n\n/// Types of obscuration that can be applied to envelope elements.\n///\n/// This enum identifies the different ways an envelope element can be obscured.\nexport enum ObscureType {\n /// The element has been elided, showing only its digest.\n Elided = \"elided\",\n\n /// The element has been encrypted using symmetric encryption.\n /// TODO: Implement when encrypt feature is added\n Encrypted = \"encrypted\",\n\n /// The element has been compressed to reduce its size.\n /// TODO: Implement when compress feature is added\n Compressed = \"compressed\",\n}\n\n/// Actions that can be performed on parts of an envelope to obscure them.\n///\n/// Gordian Envelope supports several ways to obscure parts of an envelope while\n/// maintaining its semantic integrity and digest tree.\nexport type ObscureAction =\n | { type: \"elide\" }\n | { type: \"encrypt\"; key: unknown } // TODO: SymmetricKey type\n | { type: \"compress\" };\n\n/// Helper to create elide action\nexport function elideAction(): ObscureAction {\n return { type: \"elide\" };\n}\n\n/// Implementation of elide()\nEnvelope.prototype.elide = function (this: Envelope): Envelope {\n const c = this.case();\n if (c.type === \"elided\") {\n return this;\n }\n return Envelope.newElided(this.digest());\n};\n\n/// Core elision logic\nfunction elideSetWithAction(\n envelope: Envelope,\n target: Set<Digest>,\n isRevealing: boolean,\n action: ObscureAction,\n): Envelope {\n const selfDigest = envelope.digest();\n const targetContainsSelf = Array.from(target).some((d) => d.equals(selfDigest));\n\n // Target Matches isRevealing elide\n // false false false\n // false true true\n // true false true\n // true true false\n\n if (targetContainsSelf !== isRevealing) {\n // Should obscure this envelope\n if (action.type === \"elide\") {\n return envelope.elide();\n } else if (action.type === \"encrypt\") {\n // TODO: Implement encryption\n throw new Error(\"Encryption not yet implemented\");\n } else if (action.type === \"compress\") {\n // TODO: Implement compression\n throw new Error(\"Compression not yet implemented\");\n }\n }\n\n const c = envelope.case();\n\n // Recursively process structure\n if (c.type === \"assertion\") {\n const predicate = elideSetWithAction(c.assertion.predicate(), target, isRevealing, action);\n const object = elideSetWithAction(c.assertion.object(), target, isRevealing, action);\n const elidedAssertion = new Assertion(predicate, object);\n return Envelope.newWithAssertion(elidedAssertion);\n } else if (c.type === \"node\") {\n const elidedSubject = elideSetWithAction(c.subject, target, isRevealing, action);\n const elidedAssertions = c.assertions.map((a) =>\n elideSetWithAction(a, target, isRevealing, action),\n );\n return Envelope.newWithUncheckedAssertions(elidedSubject, elidedAssertions);\n } else if (c.type === \"wrapped\") {\n const elidedEnvelope = elideSetWithAction(c.envelope, target, isRevealing, action);\n return Envelope.newWrapped(elidedEnvelope);\n }\n\n return envelope;\n}\n\n/// Implementation of elideRemovingSetWithAction\nEnvelope.prototype.elideRemovingSetWithAction = function (\n this: Envelope,\n target: Set<Digest>,\n action: ObscureAction,\n): Envelope {\n return elideSetWithAction(this, target, false, action);\n};\n\n/// Implementation of elideRemovingSet\nEnvelope.prototype.elideRemovingSet = function (this: Envelope, target: Set<Digest>): Envelope {\n return elideSetWithAction(this, target, false, elideAction());\n};\n\n/// Implementation of elideRemovingArrayWithAction\nEnvelope.prototype.elideRemovingArrayWithAction = function (\n this: Envelope,\n target: DigestProvider[],\n action: ObscureAction,\n): Envelope {\n const targetSet = new Set(target.map((p) => p.digest()));\n return elideSetWithAction(this, targetSet, false, action);\n};\n\n/// Implementation of elideRemovingArray\nEnvelope.prototype.elideRemovingArray = function (\n this: Envelope,\n target: DigestProvider[],\n): Envelope {\n const targetSet = new Set(target.map((p) => p.digest()));\n return elideSetWithAction(this, targetSet, false, elideAction());\n};\n\n/// Implementation of elideRemovingTargetWithAction\nEnvelope.prototype.elideRemovingTargetWithAction = function (\n this: Envelope,\n target: DigestProvider,\n action: ObscureAction,\n): Envelope {\n return this.elideRemovingArrayWithAction([target], action);\n};\n\n/// Implementation of elideRemovingTarget\nEnvelope.prototype.elideRemovingTarget = function (\n this: Envelope,\n target: DigestProvider,\n): Envelope {\n return this.elideRemovingArray([target]);\n};\n\n/// Implementation of elideRevealingSetWithAction\nEnvelope.prototype.elideRevealingSetWithAction = function (\n this: Envelope,\n target: Set<Digest>,\n action: ObscureAction,\n): Envelope {\n return elideSetWithAction(this, target, true, action);\n};\n\n/// Implementation of elideRevealingSet\nEnvelope.prototype.elideRevealingSet = function (this: Envelope, target: Set<Digest>): Envelope {\n return elideSetWithAction(this, target, true, elideAction());\n};\n\n/// Implementation of elideRevealingArrayWithAction\nEnvelope.prototype.elideRevealingArrayWithAction = function (\n this: Envelope,\n target: DigestProvider[],\n action: ObscureAction,\n): Envelope {\n const targetSet = new Set(target.map((p) => p.digest()));\n return elideSetWithAction(this, targetSet, true, action);\n};\n\n/// Implementation of elideRevealingArray\nEnvelope.prototype.elideRevealingArray = function (\n this: Envelope,\n target: DigestProvider[],\n): Envelope {\n const targetSet = new Set(target.map((p) => p.digest()));\n return elideSetWithAction(this, targetSet, true, elideAction());\n};\n\n/// Implementation of elideRevealingTargetWithAction\nEnvelope.prototype.elideRevealingTargetWithAction = function (\n this: Envelope,\n target: DigestProvider,\n action: ObscureAction,\n): Envelope {\n return this.elideRevealingArrayWithAction([target], action);\n};\n\n/// Implementation of elideRevealingTarget\nEnvelope.prototype.elideRevealingTarget = function (\n this: Envelope,\n target: DigestProvider,\n): Envelope {\n return this.elideRevealingArray([target]);\n};\n\n/// Implementation of unelide\nEnvelope.prototype.unelide = function (this: Envelope, envelope: Envelope): Envelope {\n if (this.digest().equals(envelope.digest())) {\n return envelope;\n }\n throw EnvelopeError.invalidDigest();\n};\n\n/// Implementation of nodesMatching\nEnvelope.prototype.nodesMatching = function (\n this: Envelope,\n targetDigests: Set<Digest> | undefined,\n obscureTypes: ObscureType[],\n): Set<Digest> {\n const result = new Set<Digest>();\n\n const visitor = (envelope: Envelope): void => {\n // Check if this node matches the target digests\n const digestMatches =\n targetDigests === undefined ||\n Array.from(targetDigests).some((d) => d.equals(envelope.digest()));\n\n if (!digestMatches) {\n return;\n }\n\n // If no obscure types specified, include all nodes\n if (obscureTypes.length === 0) {\n result.add(envelope.digest());\n return;\n }\n\n // Check if this node matches any of the specified obscure types\n const c = envelope.case();\n const typeMatches = obscureTypes.some((obscureType) => {\n if (obscureType === ObscureType.Elided && c.type === \"elided\") {\n return true;\n }\n if (obscureType === ObscureType.Encrypted && c.type === \"encrypted\") {\n return true;\n }\n if (obscureType === ObscureType.Compressed && c.type === \"compressed\") {\n return true;\n }\n return false;\n });\n\n if (typeMatches) {\n result.add(envelope.digest());\n }\n };\n\n // Walk the envelope tree\n walkEnvelope(this, visitor);\n\n return result;\n};\n\n/// Helper to walk envelope tree\nfunction walkEnvelope(envelope: Envelope, visitor: (e: Envelope) => void): void {\n visitor(envelope);\n\n const c = envelope.case();\n if (c.type === \"node\") {\n walkEnvelope(c.subject, visitor);\n for (const assertion of c.assertions) {\n walkEnvelope(assertion, visitor);\n }\n } else if (c.type === \"assertion\") {\n walkEnvelope(c.assertion.predicate(), visitor);\n walkEnvelope(c.assertion.object(), visitor);\n } else if (c.type === \"wrapped\") {\n walkEnvelope(c.envelope, visitor);\n }\n}\n\n/// Implementation of walkUnelide\nEnvelope.prototype.walkUnelide = function (this: Envelope, envelopes: Envelope[]): Envelope {\n // Build a lookup map of digest -> envelope\n const envelopeMap = new Map<string, Envelope>();\n for (const env of envelopes) {\n envelopeMap.set(env.digest().hex(), env);\n }\n\n return walkUnelideWithMap(this, envelopeMap);\n};\n\n/// Helper for walkUnelide with map\nfunction walkUnelideWithMap(envelope: Envelope, envelopeMap: Map<string, Envelope>): Envelope {\n const c = envelope.case();\n\n if (c.type === \"elided\") {\n // Try to find a matching envelope to restore\n const replacement = envelopeMap.get(envelope.digest().hex());\n return replacement ?? envelope;\n }\n\n if (c.type === \"node\") {\n const newSubject = walkUnelideWithMap(c.subject, envelopeMap);\n const newAssertions = c.assertions.map((a) => walkUnelideWithMap(a, envelopeMap));\n\n if (\n newSubject.isIdenticalTo(c.subject) &&\n newAssertions.every((a, i) => a.isIdenticalTo(c.assertions[i]))\n ) {\n return envelope;\n }\n\n return Envelope.newWithUncheckedAssertions(newSubject, newAssertions);\n }\n\n if (c.type === \"wrapped\") {\n const newEnvelope = walkUnelideWithMap(c.envelope, envelopeMap);\n if (newEnvelope.isIdenticalTo(c.envelope)) {\n return envelope;\n }\n return Envelope.newWrapped(newEnvelope);\n }\n\n if (c.type === \"assertion\") {\n const newPredicate = walkUnelideWithMap(c.assertion.predicate(), envelopeMap);\n const newObject = walkUnelideWithMap(c.assertion.object(), envelopeMap);\n\n if (\n newPredicate.isIdenticalTo(c.assertion.predicate()) &&\n newObject.isIdenticalTo(c.assertion.object())\n ) {\n return envelope;\n }\n\n return Envelope.newAssertion(newPredicate, newObject);\n }\n\n return envelope;\n}\n\n/// Implementation of walkReplace\nEnvelope.prototype.walkReplace = function (\n this: Envelope,\n target: Set<Digest>,\n replacement: Envelope,\n): Envelope {\n // Check if this node matches the target\n if (Array.from(target).some((d) => d.equals(this.digest()))) {\n return replacement;\n }\n\n const c = this.case();\n\n if (c.type === \"node\") {\n const newSubject = c.subject.walkReplace(target, replacement);\n const newAssertions = c.assertions.map((a) => a.walkReplace(target, replacement));\n\n if (\n newSubject.isIdenticalTo(c.subject) &&\n newAssertions.every((a, i) => a.isIdenticalTo(c.assertions[i]))\n ) {\n return this;\n }\n\n // Validate that all assertions are either assertions or obscured\n return Envelope.newWithAssertions(newSubject, newAssertions);\n }\n\n if (c.type === \"wrapped\") {\n const newEnvelope = c.envelope.walkReplace(target, replacement);\n if (newEnvelope.isIdenticalTo(c.envelope)) {\n return this;\n }\n return Envelope.newWrapped(newEnvelope);\n }\n\n if (c.type === \"assertion\") {\n const newPredicate = c.assertion.predicate().walkReplace(target, replacement);\n const newObject = c.assertion.object().walkReplace(target, replacement);\n\n if (\n newPredicate.isIdenticalTo(c.assertion.predicate()) &&\n newObject.isIdenticalTo(c.assertion.object())\n ) {\n return this;\n }\n\n return Envelope.newAssertion(newPredicate, newObject);\n }\n\n return this;\n};\n\n/// Implementation of isIdenticalTo\nEnvelope.prototype.isIdenticalTo = function (this: Envelope, other: Envelope): boolean {\n // Two envelopes are identical if they have the same digest\n // and the same case type (to handle wrapped vs unwrapped with same content)\n return this.digest().equals(other.digest()) && this.case().type === other.case().type;\n};\n","import { Envelope } from \"./envelope\";\n\n/// Functions for traversing and manipulating the envelope hierarchy.\n///\n/// This module provides functionality for traversing the hierarchical structure\n/// of envelopes, allowing for operations such as inspection, transformation,\n/// and extraction of specific elements. It implements a visitor pattern that\n/// enables executing arbitrary code on each element of an envelope in a\n/// structured way.\n///\n/// The traversal can be performed in two modes:\n/// - Structure-based traversal: Visits every element in the envelope hierarchy\n/// - Tree-based traversal: Skips node elements and focuses on the semantic\n/// content\n\n/// The type of incoming edge provided to the visitor.\n///\n/// This enum identifies how an envelope element is connected to its parent in\n/// the hierarchy during traversal. It helps the visitor function understand the\n/// semantic relationship between elements.\nexport enum EdgeType {\n /// No incoming edge (root)\n None = \"none\",\n /// Element is the subject of a node\n Subject = \"subject\",\n /// Element is an assertion on a node\n Assertion = \"assertion\",\n /// Element is the predicate of an assertion\n Predicate = \"predicate\",\n /// Element is the object of an assertion\n Object = \"object\",\n /// Element is the content wrapped by another envelope\n Content = \"content\",\n}\n\n/// Returns a short text label for the edge type, or undefined if no label is\n/// needed.\n///\n/// This is primarily used for tree formatting to identify relationships\n/// between elements.\n///\n/// @param edgeType - The edge type\n/// @returns A short label or undefined\nexport function edgeLabel(edgeType: EdgeType): string | undefined {\n switch (edgeType) {\n case EdgeType.Subject:\n return \"subj\";\n case EdgeType.Content:\n return \"cont\";\n case EdgeType.Predicate:\n return \"pred\";\n case EdgeType.Object:\n return \"obj\";\n case EdgeType.None:\n case EdgeType.Assertion:\n return undefined;\n default:\n return undefined;\n }\n}\n\n/// A visitor function that is called for each element in the envelope.\n///\n/// The visitor function takes the following parameters:\n/// - `envelope`: The current envelope element being visited\n/// - `level`: The depth level in the hierarchy (0 for root)\n/// - `incomingEdge`: The type of edge connecting this element to its parent\n/// - `state`: Optional context passed down from the parent's visitor call\n///\n/// The visitor returns a tuple of:\n/// - The state that will be passed to child elements\n/// - A boolean indicating whether to stop traversal (true = stop)\n///\n/// This enables accumulating state or passing context during traversal.\nexport type Visitor<State> = (\n envelope: Envelope,\n level: number,\n incomingEdge: EdgeType,\n state: State,\n) => [State, boolean];\n\n/// Implementation of walk()\nEnvelope.prototype.walk = function <State>(\n this: Envelope,\n hideNodes: boolean,\n state: State,\n visit: Visitor<State>,\n): void {\n if (hideNodes) {\n walkTree(this, 0, EdgeType.None, state, visit);\n } else {\n walkStructure(this, 0, EdgeType.None, state, visit);\n }\n};\n\n/// Recursive implementation of structure-based traversal.\n///\n/// This internal function performs the actual recursive traversal of the\n/// envelope structure, visiting every element and maintaining the\n/// correct level and edge relationships.\nfunction walkStructure<State>(\n envelope: Envelope,\n level: number,\n incomingEdge: EdgeType,\n state: State,\n visit: Visitor<State>,\n): void {\n // Visit this envelope\n const [newState, stop] = visit(envelope, level, incomingEdge, state);\n if (stop) {\n return;\n }\n\n const nextLevel = level + 1;\n const c = envelope.case();\n\n switch (c.type) {\n case \"node\":\n // Visit subject\n walkStructure(c.subject, nextLevel, EdgeType.Subject, newState, visit);\n // Visit all assertions\n for (const assertion of c.assertions) {\n walkStructure(assertion, nextLevel, EdgeType.Assertion, newState, visit);\n }\n break;\n\n case \"wrapped\":\n // Visit wrapped envelope\n walkStructure(c.envelope, nextLevel, EdgeType.Content, newState, visit);\n break;\n\n case \"assertion\":\n // Visit predicate and object\n walkStructure(c.assertion.predicate(), nextLevel, EdgeType.Predicate, newState, visit);\n walkStructure(c.assertion.object(), nextLevel, EdgeType.Object, newState, visit);\n break;\n\n case \"leaf\":\n case \"elided\":\n case \"knownValue\":\n case \"encrypted\":\n case \"compressed\":\n // Leaf nodes and other types have no children\n break;\n }\n}\n\n/// Recursive implementation of tree-based traversal.\n///\n/// This internal function performs the actual recursive traversal of the\n/// envelope's semantic tree, skipping node containers and focusing on\n/// the semantic content elements. It maintains the correct level and\n/// edge relationships while skipping structural elements.\nfunction walkTree<State>(\n envelope: Envelope,\n level: number,\n incomingEdge: EdgeType,\n state: State,\n visit: Visitor<State>,\n): State {\n let currentState = state;\n let subjectLevel = level;\n\n // Skip visiting if this is a node\n if (!envelope.isNode()) {\n const [newState, stop] = visit(envelope, level, incomingEdge, currentState);\n if (stop) {\n return newState;\n }\n currentState = newState;\n subjectLevel = level + 1;\n }\n\n const c = envelope.case();\n\n switch (c.type) {\n case \"node\": {\n // Visit subject\n const assertionState = walkTree(\n c.subject,\n subjectLevel,\n EdgeType.Subject,\n currentState,\n visit,\n );\n // Visit all assertions\n const assertionLevel = subjectLevel + 1;\n for (const assertion of c.assertions) {\n walkTree(assertion, assertionLevel, EdgeType.Assertion, assertionState, visit);\n }\n break;\n }\n\n case \"wrapped\":\n // Visit wrapped envelope\n walkTree(c.envelope, subjectLevel, EdgeType.Content, currentState, visit);\n break;\n\n case \"assertion\":\n // Visit predicate and object\n walkTree(c.assertion.predicate(), subjectLevel, EdgeType.Predicate, currentState, visit);\n walkTree(c.assertion.object(), subjectLevel, EdgeType.Object, currentState, visit);\n break;\n\n case \"leaf\":\n case \"elided\":\n case \"knownValue\":\n case \"encrypted\":\n case \"compressed\":\n // Leaf nodes and other types have no children\n break;\n }\n\n return currentState;\n}\n","import { Envelope } from \"./envelope\";\nimport type { EnvelopeEncodableValue } from \"./envelope-encodable\";\nimport { EnvelopeError } from \"./error\";\n\n/// Support for adding assertions.\n///\n/// Assertions are predicate-object pairs that make statements about an\n/// envelope's subject. This implementation provides methods for adding various\n/// types of assertions to envelopes.\n///\n/// These methods extend the Envelope class to provide a rich API for\n/// working with assertions, matching the Rust bc-envelope implementation.\n\n/// Implementation of addAssertionEnvelopes\nEnvelope.prototype.addAssertionEnvelopes = function (\n this: Envelope,\n assertions: Envelope[],\n): Envelope {\n return assertions.reduce((result, assertion) => result.addAssertionEnvelope(assertion), this);\n};\n\n/// Implementation of addOptionalAssertionEnvelope\nEnvelope.prototype.addOptionalAssertionEnvelope = function (\n this: Envelope,\n assertion: Envelope | undefined,\n): Envelope {\n if (assertion === undefined) {\n return this;\n }\n\n // Validate that the assertion is a valid assertion or obscured envelope\n if (!assertion.isSubjectAssertion() && !assertion.isSubjectObscured()) {\n throw EnvelopeError.invalidFormat();\n }\n\n const c = this.case();\n\n // Check if this is already a node\n if (c.type === \"node\") {\n // Check for duplicate assertions\n const isDuplicate = c.assertions.some((a) => a.digest().equals(assertion.digest()));\n if (isDuplicate) {\n return this;\n }\n\n // Add the new assertion\n return Envelope.newWithUncheckedAssertions(c.subject, [...c.assertions, assertion]);\n }\n\n // Otherwise, create a new node with this envelope as subject\n return Envelope.newWithUncheckedAssertions(this.subject(), [assertion]);\n};\n\n/// Implementation of addOptionalAssertion\nEnvelope.prototype.addOptionalAssertion = function (\n this: Envelope,\n predicate: EnvelopeEncodableValue,\n object: EnvelopeEncodableValue | undefined,\n): Envelope {\n if (object === undefined || object === null) {\n return this;\n }\n return this.addAssertion(predicate, object);\n};\n\n/// Implementation of addNonemptyStringAssertion\nEnvelope.prototype.addNonemptyStringAssertion = function (\n this: Envelope,\n predicate: EnvelopeEncodableValue,\n str: string,\n): Envelope {\n if (str.length === 0) {\n return this;\n }\n return this.addAssertion(predicate, str);\n};\n\n/// Implementation of addAssertions\nEnvelope.prototype.addAssertions = function (this: Envelope, envelopes: Envelope[]): Envelope {\n return envelopes.reduce((result, envelope) => result.addAssertionEnvelope(envelope), this);\n};\n\n/// Implementation of addAssertionIf\nEnvelope.prototype.addAssertionIf = function (\n this: Envelope,\n condition: boolean,\n predicate: EnvelopeEncodableValue,\n object: EnvelopeEncodableValue,\n): Envelope {\n if (condition) {\n return this.addAssertion(predicate, object);\n }\n return this;\n};\n\n/// Implementation of addAssertionEnvelopeIf\nEnvelope.prototype.addAssertionEnvelopeIf = function (\n this: Envelope,\n condition: boolean,\n assertionEnvelope: Envelope,\n): Envelope {\n if (condition) {\n return this.addAssertionEnvelope(assertionEnvelope);\n }\n return this;\n};\n\n/// Implementation of removeAssertion\nEnvelope.prototype.removeAssertion = function (this: Envelope, target: Envelope): Envelope {\n const assertions = this.assertions();\n const targetDigest = target.digest();\n\n const index = assertions.findIndex((a) => a.digest().equals(targetDigest));\n\n if (index === -1) {\n // Assertion not found, return unchanged\n return this;\n }\n\n // Remove the assertion\n const newAssertions = [...assertions.slice(0, index), ...assertions.slice(index + 1)];\n\n if (newAssertions.length === 0) {\n // No assertions left, return just the subject\n return this.subject();\n }\n\n // Return envelope with remaining assertions\n return Envelope.newWithUncheckedAssertions(this.subject(), newAssertions);\n};\n\n/// Implementation of replaceAssertion\nEnvelope.prototype.replaceAssertion = function (\n this: Envelope,\n assertion: Envelope,\n newAssertion: Envelope,\n): Envelope {\n return this.removeAssertion(assertion).addAssertionEnvelope(newAssertion);\n};\n\n/// Implementation of replaceSubject\nEnvelope.prototype.replaceSubject = function (this: Envelope, subject: Envelope): Envelope {\n return this.assertions().reduce((e, a) => e.addAssertionEnvelope(a), subject);\n};\n\n/// Implementation of assertions\nEnvelope.prototype.assertions = function (this: Envelope): Envelope[] {\n const c = this.case();\n if (c.type === \"node\") {\n return c.assertions;\n }\n return [];\n};\n","import type { Cbor } from \"@bcts/dcbor\";\nimport { isNumber, isNaN, asArray, asMap, asText } from \"@bcts/dcbor\";\nimport { Envelope } from \"./envelope\";\n\n/// Provides methods for working with envelope leaf nodes,\n/// which are dCBOR values of any kind.\n///\n/// This module extends the Envelope class with convenience methods for\n/// working with leaf values, including type checking and extraction.\n\n// Note: Static methods Envelope.false() and Envelope.true() are implemented below\n// but cannot be declared in TypeScript module augmentation due to reserved keywords.\n\n/// Implementation of static false()\n(Envelope as unknown as { false: () => Envelope }).false = function (): Envelope {\n return Envelope.newLeaf(false);\n};\n\n/// Implementation of static true()\n(Envelope as unknown as { true: () => Envelope }).true = function (): Envelope {\n return Envelope.newLeaf(true);\n};\n\n/// Implementation of isFalse()\nEnvelope.prototype.isFalse = function (this: Envelope): boolean {\n try {\n return this.extractBoolean() === false;\n } catch {\n return false;\n }\n};\n\n/// Implementation of isTrue()\nEnvelope.prototype.isTrue = function (this: Envelope): boolean {\n try {\n return this.extractBoolean() === true;\n } catch {\n return false;\n }\n};\n\n/// Implementation of isBool()\nEnvelope.prototype.isBool = function (this: Envelope): boolean {\n try {\n const value = this.extractBoolean();\n return typeof value === \"boolean\";\n } catch {\n return false;\n }\n};\n\n/// Implementation of isNumber()\nEnvelope.prototype.isNumber = function (this: Envelope): boolean {\n const leaf = this.asLeaf();\n if (leaf === undefined) {\n return false;\n }\n\n return isNumber(leaf);\n};\n\n/// Implementation of isSubjectNumber()\nEnvelope.prototype.isSubjectNumber = function (this: Envelope): boolean {\n return this.subject().isNumber();\n};\n\n/// Implementation of isNaN()\nEnvelope.prototype.isNaN = function (this: Envelope): boolean {\n const leaf = this.asLeaf();\n if (leaf === undefined) {\n return false;\n }\n\n // Check for NaN in CBOR simple types\n if (\"type\" in leaf && leaf.type === 7) {\n return isNaN(leaf as unknown as Parameters<typeof isNaN>[0]);\n }\n return false;\n};\n\n/// Implementation of isSubjectNaN()\nEnvelope.prototype.isSubjectNaN = function (this: Envelope): boolean {\n return this.subject().isNaN();\n};\n\n/// Implementation of isNull()\nEnvelope.prototype.isNull = function (this: Envelope): boolean {\n try {\n this.extractNull();\n return true;\n } catch (_error) {\n return false;\n }\n};\n\n/// Implementation of tryByteString()\nEnvelope.prototype.tryByteString = function (this: Envelope): Uint8Array {\n return this.extractBytes();\n};\n\n/// Implementation of asByteString()\nEnvelope.prototype.asByteString = function (this: Envelope): Uint8Array | undefined {\n try {\n return this.extractBytes();\n } catch {\n return undefined;\n }\n};\n\n/// Implementation of asArray()\nEnvelope.prototype.asArray = function (this: Envelope): readonly Cbor[] | undefined {\n const leaf = this.asLeaf();\n if (leaf === undefined) {\n return undefined;\n }\n\n return asArray(leaf);\n};\n\n/// Implementation of asMap()\nEnvelope.prototype.asMap = function (this: Envelope) {\n const leaf = this.asLeaf();\n if (leaf === undefined) {\n return undefined;\n }\n\n return asMap(leaf);\n};\n\n/// Implementation of asText()\nEnvelope.prototype.asText = function (this: Envelope): string | undefined {\n const leaf = this.asLeaf();\n if (leaf === undefined) {\n return undefined;\n }\n\n return asText(leaf);\n};\n\n/// Implementation of asLeaf()\nEnvelope.prototype.asLeaf = function (this: Envelope): Cbor | undefined {\n const c = this.case();\n if (c.type === \"leaf\") {\n return c.cbor;\n }\n return undefined;\n};\n","// Cbor type available if needed later\nimport { Envelope } from \"./envelope\";\nimport type { EnvelopeEncodableValue } from \"./envelope-encodable\";\nimport { EnvelopeError } from \"./error\";\n\n/// Provides methods for querying envelope structure and extracting data.\n///\n/// The `queries` module contains methods for:\n///\n/// 1. **Structural queries**: Methods for examining the envelope's structure\n/// (`subject()`, `assertions()`)\n/// 2. **Type queries**: Methods for determining the envelope's type\n/// (`isLeaf()`, `isNode()`, etc.)\n/// 3. **Content extraction**: Methods for extracting typed content from\n/// envelopes (`extractSubject()`, `extractObjectForPredicate()`)\n/// 4. **Assertion queries**: Methods for finding assertions with specific\n/// predicates (`assertionWithPredicate()`)\n///\n/// These methods enable traversal and inspection of envelope hierarchies,\n/// allowing for flexible manipulation and access to envelope data structures.\n\n/// Implementation of hasAssertions()\nEnvelope.prototype.hasAssertions = function (this: Envelope): boolean {\n const c = this.case();\n return c.type === \"node\" && c.assertions.length > 0;\n};\n\n/// Implementation of asAssertion()\nEnvelope.prototype.asAssertion = function (this: Envelope): Envelope | undefined {\n const c = this.case();\n return c.type === \"assertion\" ? this : undefined;\n};\n\n/// Implementation of tryAssertion()\nEnvelope.prototype.tryAssertion = function (this: Envelope): Envelope {\n const result = this.asAssertion();\n if (result === undefined) {\n throw EnvelopeError.notAssertion();\n }\n return result;\n};\n\n/// Implementation of asPredicate()\nEnvelope.prototype.asPredicate = function (this: Envelope): Envelope | undefined {\n // Refer to subject in case the assertion is a node and therefore has\n // its own assertions\n const subj = this.subject();\n const c = subj.case();\n if (c.type === \"assertion\") {\n return c.assertion.predicate();\n }\n return undefined;\n};\n\n/// Implementation of tryPredicate()\nEnvelope.prototype.tryPredicate = function (this: Envelope): Envelope {\n const result = this.asPredicate();\n if (result === undefined) {\n throw EnvelopeError.notAssertion();\n }\n return result;\n};\n\n/// Implementation of asObject()\nEnvelope.prototype.asObject = function (this: Envelope): Envelope | undefined {\n // Refer to subject in case the assertion is a node and therefore has\n // its own assertions\n const subj = this.subject();\n const c = subj.case();\n if (c.type === \"assertion\") {\n return c.assertion.object();\n }\n return undefined;\n};\n\n/// Implementation of tryObject()\nEnvelope.prototype.tryObject = function (this: Envelope): Envelope {\n const result = this.asObject();\n if (result === undefined) {\n throw EnvelopeError.notAssertion();\n }\n return result;\n};\n\n/// Implementation of isAssertion()\nEnvelope.prototype.isAssertion = function (this: Envelope): boolean {\n return this.case().type === \"assertion\";\n};\n\n/// Implementation of isElided()\nEnvelope.prototype.isElided = function (this: Envelope): boolean {\n return this.case().type === \"elided\";\n};\n\n/// Implementation of isLeaf()\nEnvelope.prototype.isLeaf = function (this: Envelope): boolean {\n return this.case().type === \"leaf\";\n};\n\n/// Implementation of isNode()\nEnvelope.prototype.isNode = function (this: Envelope): boolean {\n return this.case().type === \"node\";\n};\n\n/// Implementation of isWrapped()\nEnvelope.prototype.isWrapped = function (this: Envelope): boolean {\n return this.case().type === \"wrapped\";\n};\n\n/// Implementation of isInternal()\nEnvelope.prototype.isInternal = function (this: Envelope): boolean {\n const type = this.case().type;\n return type === \"node\" || type === \"wrapped\" || type === \"assertion\";\n};\n\n/// Implementation of isObscured()\nEnvelope.prototype.isObscured = function (this: Envelope): boolean {\n const type = this.case().type;\n return type === \"elided\" || type === \"encrypted\" || type === \"compressed\";\n};\n\n/// Implementation of assertionsWithPredicate()\nEnvelope.prototype.assertionsWithPredicate = function (\n this: Envelope,\n predicate: EnvelopeEncodableValue,\n): Envelope[] {\n const predicateEnv = Envelope.new(predicate);\n const predicateDigest = predicateEnv.digest();\n\n return this.assertions().filter((assertion) => {\n const pred = assertion.subject().asPredicate();\n return pred?.digest().equals(predicateDigest) === true;\n });\n};\n\n/// Implementation of assertionWithPredicate()\nEnvelope.prototype.assertionWithPredicate = function (\n this: Envelope,\n predicate: EnvelopeEncodableValue,\n): Envelope {\n const matches = this.assertionsWithPredicate(predicate);\n\n if (matches.length === 0) {\n throw EnvelopeError.nonexistentPredicate();\n }\n if (matches.length > 1) {\n throw EnvelopeError.ambiguousPredicate();\n }\n\n return matches[0];\n};\n\n/// Implementation of optionalAssertionWithPredicate()\nEnvelope.prototype.optionalAssertionWithPredicate = function (\n this: Envelope,\n predicate: EnvelopeEncodableValue,\n): Envelope | undefined {\n const matches = this.assertionsWithPredicate(predicate);\n\n if (matches.length === 0) {\n return undefined;\n }\n if (matches.length > 1) {\n throw EnvelopeError.ambiguousPredicate();\n }\n\n return matches[0];\n};\n\n/// Implementation of objectForPredicate()\nEnvelope.prototype.objectForPredicate = function (\n this: Envelope,\n predicate: EnvelopeEncodableValue,\n): Envelope {\n const assertion = this.assertionWithPredicate(predicate);\n const obj = assertion.asObject();\n if (obj === undefined) {\n throw EnvelopeError.notAssertion();\n }\n return obj;\n};\n\n/// Implementation of optionalObjectForPredicate()\nEnvelope.prototype.optionalObjectForPredicate = function (\n this: Envelope,\n predicate: EnvelopeEncodableValue,\n): Envelope | undefined {\n const matches = this.assertionsWithPredicate(predicate);\n\n if (matches.length === 0) {\n return undefined;\n }\n if (matches.length > 1) {\n throw EnvelopeError.ambiguousPredicate();\n }\n\n const obj = matches[0].subject().asObject();\n return obj;\n};\n\n/// Implementation of objectsForPredicate()\nEnvelope.prototype.objectsForPredicate = function (\n this: Envelope,\n predicate: EnvelopeEncodableValue,\n): Envelope[] {\n return this.assertionsWithPredicate(predicate).map((assertion) => {\n const obj = assertion.asObject();\n if (obj === undefined) {\n throw EnvelopeError.notAssertion();\n }\n return obj;\n });\n};\n\n/// Implementation of elementsCount()\nEnvelope.prototype.elementsCount = function (this: Envelope): number {\n let count = 1; // Count this envelope\n\n const c = this.case();\n switch (c.type) {\n case \"node\":\n count += c.subject.elementsCount();\n for (const assertion of c.assertions) {\n count += assertion.elementsCount();\n }\n break;\n case \"assertion\":\n count += c.assertion.predicate().elementsCount();\n count += c.assertion.object().elementsCount();\n break;\n case \"wrapped\":\n count += c.envelope.elementsCount();\n break;\n case \"leaf\":\n case \"elided\":\n case \"knownValue\":\n case \"encrypted\":\n case \"compressed\":\n // These cases don't contribute additional elements\n break;\n }\n\n return count;\n};\n","import { Envelope } from \"./envelope\";\nimport { EnvelopeError } from \"./error\";\n\n/// Support for wrapping and unwrapping envelopes.\n///\n/// Wrapping allows treating an envelope (including its assertions) as a single\n/// unit, making it possible to add assertions about the envelope as a whole.\n\n/// Implementation of wrap()\nEnvelope.prototype.wrap = function (this: Envelope): Envelope {\n return Envelope.newWrapped(this);\n};\n\n/// Implementation of tryUnwrap()\nEnvelope.prototype.tryUnwrap = function (this: Envelope): Envelope {\n const c = this.subject().case();\n if (c.type === \"wrapped\") {\n return c.envelope;\n }\n throw EnvelopeError.notWrapped();\n};\n\n/// Implementation of unwrap() - alias for tryUnwrap()\nEnvelope.prototype.unwrap = function (this: Envelope): Envelope {\n return this.tryUnwrap();\n};\n","import { Envelope } from \"../base/envelope\";\nimport { type EnvelopeEncodableValue } from \"../base/envelope-encodable\";\nimport { EnvelopeError } from \"../base/error\";\n\n/// Type system for Gordian Envelopes.\n///\n/// This module provides functionality for adding, querying, and verifying types\n/// within envelopes. In Gordian Envelope, types are implemented using the\n/// special `'isA'` predicate (the string \"isA\"), which is semantically\n/// equivalent to the RDF `rdf:type` concept.\n///\n/// Type information enables:\n/// - Semantic classification of envelopes\n/// - Type verification before processing content\n/// - Conversion between domain objects and envelopes\n/// - Schema validation\n///\n/// ## Type Representation\n///\n/// Types are represented as assertions with the `'isA'` predicate and an object\n/// that specifies the type. The type object is typically a string or an envelope.\n///\n/// ## Usage Patterns\n///\n/// The type system is commonly used in two ways:\n///\n/// 1. **Type Tagging**: Adding type information to envelopes to indicate their\n/// semantic meaning\n///\n/// ```typescript\n/// // Create an envelope representing a person\n/// const person = Envelope.new(\"Alice\")\n/// .addType(\"Person\")\n/// .addAssertion(\"age\", 30);\n/// ```\n///\n/// 2. **Type Checking**: Verifying that an envelope has the expected type\n/// before processing\n///\n/// ```typescript\n/// function processPerson(envelope: Envelope): void {\n/// // Verify this is a person before processing\n/// envelope.checkType(\"Person\");\n///\n/// // Now we can safely extract person-specific information\n/// const name = envelope.subject().extractString();\n/// const age = envelope.objectForPredicate(\"age\").extractNumber();\n///\n/// console.log(`${name} is ${age} years old`);\n/// }\n/// ```\n\n/// The standard predicate for type assertions\nexport const IS_A = \"isA\";\n\n/// Implementation of addType()\n// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions\nif (Envelope?.prototype) {\n Envelope.prototype.addType = function (this: Envelope, object: EnvelopeEncodableValue): Envelope {\n return this.addAssertion(IS_A, object);\n };\n\n /// Implementation of types()\n Envelope.prototype.types = function (this: Envelope): Envelope[] {\n return this.objectsForPredicate(IS_A);\n };\n\n /// Implementation of getType()\n Envelope.prototype.getType = function (this: Envelope): Envelope {\n const t = this.types();\n if (t.length === 0) {\n throw EnvelopeError.invalidType();\n }\n if (t.length === 1) {\n return t[0];\n }\n throw EnvelopeError.ambiguousType();\n };\n\n /// Implementation of hasType()\n Envelope.prototype.hasType = function (this: Envelope, t: EnvelopeEncodableValue): boolean {\n const e = Envelope.new(t);\n return this.types().some((x) => x.digest().equals(e.digest()));\n };\n\n /// Implementation of checkType()\n Envelope.prototype.checkType = function (this: Envelope, t: EnvelopeEncodableValue): void {\n if (!this.hasType(t)) {\n throw EnvelopeError.invalidType();\n }\n };\n}\n","import { Envelope } from \"../base/envelope\";\nimport { EnvelopeError } from \"../base/error\";\nimport {\n SecureRandomNumberGenerator,\n rngRandomData,\n rngNextInClosedRangeI32,\n type RandomNumberGenerator,\n} from \"@bcts/rand\";\n\n/// Extension for adding salt to envelopes to prevent correlation.\n///\n/// This module provides functionality for decorrelating envelopes by adding\n/// random salt. Salt is added as an assertion with the predicate 'salt' and\n/// a random value. When an envelope is elided, this salt ensures that the\n/// digest of the elided envelope cannot be correlated with other elided\n/// envelopes containing the same information.\n///\n/// Decorrelation is an important privacy feature that prevents third parties\n/// from determining whether two elided envelopes originally contained the same\n/// information by comparing their digests.\n///\n/// Based on bc-envelope-rust/src/extension/salt.rs and bc-components-rust/src/salt.rs\n///\n/// @example\n/// ```typescript\n/// // Create a simple envelope\n/// const envelope = Envelope.new(\"Hello\");\n///\n/// // Create a decorrelated version by adding salt\n/// const salted = envelope.addSalt();\n///\n/// // The salted envelope has a different digest than the original\n/// console.log(envelope.digest().equals(salted.digest())); // false\n/// ```\n\n/// The standard predicate for salt assertions\nexport const SALT = \"salt\";\n\n/// Minimum salt size in bytes (64 bits)\nconst MIN_SALT_SIZE = 8;\n\n/// Creates a new SecureRandomNumberGenerator instance\nfunction createSecureRng(): RandomNumberGenerator {\n return new SecureRandomNumberGenerator();\n}\n\n/// Generates random bytes using the rand package\nfunction generateRandomBytes(length: number, rng?: RandomNumberGenerator): Uint8Array {\n const actualRng = rng ?? createSecureRng();\n return rngRandomData(actualRng, length);\n}\n\n/// Calculates salt size proportional to envelope size\n/// This matches the Rust implementation in bc-components-rust/src/salt.rs\nfunction calculateProportionalSaltSize(envelopeSize: number, rng?: RandomNumberGenerator): number {\n const actualRng = rng ?? createSecureRng();\n const count = envelopeSize;\n const minSize = Math.max(8, Math.ceil(count * 0.05));\n const maxSize = Math.max(minSize + 8, Math.ceil(count * 0.25));\n return rngNextInClosedRangeI32(actualRng, minSize, maxSize);\n}\n\n/// Implementation of addSalt()\n// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions\nif (Envelope?.prototype) {\n Envelope.prototype.addSalt = function (this: Envelope): Envelope {\n const rng = createSecureRng();\n const envelopeSize = this.cborBytes().length;\n const saltSize = calculateProportionalSaltSize(envelopeSize, rng);\n const saltBytes = generateRandomBytes(saltSize, rng);\n return this.addAssertion(SALT, saltBytes);\n };\n\n /// Implementation of addSaltWithLength()\n Envelope.prototype.addSaltWithLength = function (this: Envelope, count: number): Envelope {\n if (count < MIN_SALT_SIZE) {\n throw EnvelopeError.general(`Salt must be at least ${MIN_SALT_SIZE} bytes, got ${count}`);\n }\n const saltBytes = generateRandomBytes(count);\n return this.addAssertion(SALT, saltBytes);\n };\n\n /// Implementation of addSaltBytes()\n Envelope.prototype.addSaltBytes = function (this: Envelope, saltBytes: Uint8Array): Envelope {\n if (saltBytes.length < MIN_SALT_SIZE) {\n throw EnvelopeError.general(\n `Salt must be at least ${MIN_SALT_SIZE} bytes, got ${saltBytes.length}`,\n );\n }\n return this.addAssertion(SALT, saltBytes);\n };\n\n /// Implementation of addSaltInRange()\n Envelope.prototype.addSaltInRange = function (\n this: Envelope,\n min: number,\n max: number,\n ): Envelope {\n if (min < MIN_SALT_SIZE) {\n throw EnvelopeError.general(\n `Minimum salt size must be at least ${MIN_SALT_SIZE} bytes, got ${min}`,\n );\n }\n if (max < min) {\n throw EnvelopeError.general(\n `Maximum salt size must be at least minimum, got min=${min} max=${max}`,\n );\n }\n const rng = createSecureRng();\n const saltSize = rngNextInClosedRangeI32(rng, min, max);\n const saltBytes = generateRandomBytes(saltSize, rng);\n return this.addAssertion(SALT, saltBytes);\n };\n}\n","/**\n * Signature Extension for Gordian Envelope\n *\n * Provides functionality for digitally signing Envelopes and verifying signatures,\n * with optional metadata support.\n *\n * The signature extension allows:\n * - Signing envelope subjects to validate their authenticity\n * - Adding metadata to signatures (e.g., signer identity, date, purpose)\n * - Verification of signatures, both with and without metadata\n * - Support for multiple signatures on a single envelope\n */\n\nimport { Envelope } from \"../base/envelope\";\nimport { EnvelopeError } from \"../base/error\";\nimport {\n ecdsaSign,\n ecdsaVerify,\n ecdsaPublicKeyFromPrivateKey,\n ECDSA_PRIVATE_KEY_SIZE,\n ECDSA_PUBLIC_KEY_SIZE,\n ECDSA_UNCOMPRESSED_PUBLIC_KEY_SIZE,\n} from \"@bcts/crypto\";\nimport { SecureRandomNumberGenerator, rngRandomData } from \"@bcts/rand\";\n\n/**\n * Known value for the 'signed' predicate.\n * This is the standard predicate used for signature assertions.\n */\nexport const SIGNED = \"signed\";\n\n/**\n * Known value for the 'verifiedBy' predicate.\n * Used to indicate verification status.\n */\nexport const VERIFIED_BY = \"verifiedBy\";\n\n/**\n * Known value for the 'note' predicate.\n * Used for adding notes/comments to signatures.\n */\nexport const NOTE = \"note\";\n\n/**\n * Represents a cryptographic signature.\n */\nexport class Signature {\n readonly #data: Uint8Array;\n\n constructor(data: Uint8Array) {\n this.#data = data;\n }\n\n /**\n * Returns the raw signature bytes.\n */\n data(): Uint8Array {\n return this.#data;\n }\n\n /**\n * Returns the hex-encoded signature.\n */\n hex(): string {\n return Array.from(this.#data)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n }\n\n /**\n * Creates a Signature from hex string.\n */\n static fromHex(hex: string): Signature {\n const bytes = new Uint8Array(hex.length / 2);\n for (let i = 0; i < hex.length; i += 2) {\n bytes[i / 2] = parseInt(hex.substr(i, 2), 16);\n }\n return new Signature(bytes);\n }\n}\n\n/**\n * Interface for types that can sign data.\n */\nexport interface Signer {\n /**\n * Signs the provided data and returns a Signature.\n */\n sign(data: Uint8Array): Signature;\n}\n\n/**\n * Interface for types that can verify signatures.\n */\nexport interface Verifier {\n /**\n * Verifies a signature against the provided data.\n * Returns true if the signature is valid.\n */\n verify(data: Uint8Array, signature: Signature): boolean;\n}\n\n/**\n * ECDSA signing key using secp256k1 curve.\n * Uses @bcts/crypto functions.\n */\nexport class SigningPrivateKey implements Signer {\n readonly #privateKey: Uint8Array;\n\n constructor(privateKey: Uint8Array) {\n if (privateKey.length !== ECDSA_PRIVATE_KEY_SIZE) {\n throw new Error(`Private key must be ${ECDSA_PRIVATE_KEY_SIZE} bytes`);\n }\n this.#privateKey = privateKey;\n }\n\n /**\n * Generates a new random private key.\n */\n static generate(): SigningPrivateKey {\n const rng = new SecureRandomNumberGenerator();\n const privateKey = rngRandomData(rng, ECDSA_PRIVATE_KEY_SIZE);\n return new SigningPrivateKey(privateKey);\n }\n\n /**\n * Creates a private key from hex string.\n */\n static fromHex(hex: string): SigningPrivateKey {\n const bytes = new Uint8Array(hex.length / 2);\n for (let i = 0; i < hex.length; i += 2) {\n bytes[i / 2] = parseInt(hex.substr(i, 2), 16);\n }\n return new SigningPrivateKey(bytes);\n }\n\n /**\n * Returns the corresponding public key.\n */\n publicKey(): SigningPublicKey {\n const publicKey = ecdsaPublicKeyFromPrivateKey(this.#privateKey);\n return new SigningPublicKey(publicKey);\n }\n\n /**\n * Signs data and returns a Signature.\n */\n sign(data: Uint8Array): Signature {\n const signatureBytes = ecdsaSign(this.#privateKey, data);\n return new Signature(signatureBytes);\n }\n\n /**\n * Returns the raw private key bytes.\n */\n data(): Uint8Array {\n return this.#privateKey;\n }\n}\n\n/**\n * ECDSA public key for signature verification using secp256k1 curve.\n * Uses @bcts/crypto functions.\n */\nexport class SigningPublicKey implements Verifier {\n readonly #publicKey: Uint8Array;\n\n constructor(publicKey: Uint8Array) {\n if (\n publicKey.length !== ECDSA_PUBLIC_KEY_SIZE &&\n publicKey.length !== ECDSA_UNCOMPRESSED_PUBLIC_KEY_SIZE\n ) {\n throw new Error(\n `Public key must be ${ECDSA_PUBLIC_KEY_SIZE} bytes (compressed) or ${ECDSA_UNCOMPRESSED_PUBLIC_KEY_SIZE} bytes (uncompressed)`,\n );\n }\n this.#publicKey = publicKey;\n }\n\n /**\n * Creates a public key from hex string.\n */\n static fromHex(hex: string): SigningPublicKey {\n const bytes = new Uint8Array(hex.length / 2);\n for (let i = 0; i < hex.length; i += 2) {\n bytes[i / 2] = parseInt(hex.substr(i, 2), 16);\n }\n return new SigningPublicKey(bytes);\n }\n\n /**\n * Verifies a signature against the provided data.\n */\n verify(data: Uint8Array, signature: Signature): boolean {\n try {\n return ecdsaVerify(this.#publicKey, signature.data(), data);\n } catch {\n return false;\n }\n }\n\n /**\n * Returns the raw public key bytes.\n */\n data(): Uint8Array {\n return this.#publicKey;\n }\n\n /**\n * Returns the hex-encoded public key.\n */\n hex(): string {\n return Array.from(this.#publicKey)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n }\n}\n\n/**\n * Metadata that can be attached to a signature.\n */\nexport class SignatureMetadata {\n readonly #assertions: [string, unknown][] = [];\n\n /**\n * Adds an assertion to the metadata.\n */\n withAssertion(predicate: string, object: unknown): SignatureMetadata {\n const metadata = new SignatureMetadata();\n metadata.#assertions.push(...this.#assertions);\n metadata.#assertions.push([predicate, object]);\n return metadata;\n }\n\n /**\n * Returns all assertions in the metadata.\n */\n assertions(): [string, unknown][] {\n return this.#assertions;\n }\n\n /**\n * Returns true if this metadata has any assertions.\n */\n hasAssertions(): boolean {\n return this.#assertions.length > 0;\n }\n}\n\n// Implementation\n// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions\nif (Envelope?.prototype) {\n Envelope.prototype.addSignature = function (this: Envelope, signer: Signer): Envelope {\n return this.addSignatureWithMetadata(signer, undefined);\n };\n\n Envelope.prototype.addSignatureWithMetadata = function (\n this: Envelope,\n signer: Signer,\n metadata?: SignatureMetadata,\n ): Envelope {\n const digest = this.subject().digest();\n const signature = signer.sign(digest.data());\n let signatureEnvelope = Envelope.new(signature.data());\n\n if (metadata?.hasAssertions() === true) {\n // Add metadata assertions to the signature\n for (const [predicate, object] of metadata.assertions()) {\n signatureEnvelope = signatureEnvelope.addAssertion(\n predicate,\n object as string | number | boolean,\n );\n }\n\n // Wrap the signature with metadata\n signatureEnvelope = signatureEnvelope.wrap();\n\n // Sign the wrapped envelope\n const outerSignature = signer.sign(signatureEnvelope.digest().data());\n signatureEnvelope = signatureEnvelope.addAssertion(SIGNED, outerSignature.data());\n }\n\n return this.addAssertion(SIGNED, signatureEnvelope);\n };\n\n Envelope.prototype.addSignatures = function (this: Envelope, signers: Signer[]): Envelope {\n return signers.reduce((envelope, signer) => envelope.addSignature(signer), this);\n };\n\n Envelope.prototype.hasSignatureFrom = function (this: Envelope, verifier: Verifier): boolean {\n const subjectDigest = this.subject().digest();\n const signatures = this.signatures();\n\n for (const sigEnvelope of signatures) {\n const c = sigEnvelope.case();\n\n if (c.type === \"leaf\") {\n // Simple signature - verify directly\n try {\n const sigData = sigEnvelope.asByteString();\n if (sigData !== undefined) {\n const signature = new Signature(sigData);\n if (verifier.verify(subjectDigest.data(), signature)) {\n return true;\n }\n }\n } catch {\n continue;\n }\n } else if (c.type === \"node\") {\n // Signature with metadata - it's a node with 'signed' assertion\n // The structure is: { wrapped_signature [signed: outer_signature] }\n // Check if this node has a 'signed' assertion\n const outerSigs = sigEnvelope.assertions().filter((a) => {\n const aC = a.case();\n if (aC.type === \"assertion\") {\n const pred = aC.assertion.predicate();\n try {\n return pred.asText() === SIGNED;\n } catch {\n return false;\n }\n }\n return false;\n });\n\n for (const outerSig of outerSigs) {\n const outerSigCase = outerSig.case();\n if (outerSigCase.type === \"assertion\") {\n const outerSigObj = outerSigCase.assertion.object();\n try {\n const outerSigData = outerSigObj.asByteString();\n if (outerSigData !== undefined) {\n const outerSignature = new Signature(outerSigData);\n\n // The subject of this node should be a wrapped envelope\n const nodeSubject = c.subject;\n const nodeSubjectCase = nodeSubject.case();\n\n // Verify outer signature against the wrapped envelope\n if (\n nodeSubjectCase.type === \"wrapped\" &&\n verifier.verify(nodeSubject.digest().data(), outerSignature)\n ) {\n // Now verify inner signature\n const wrapped = nodeSubjectCase.envelope;\n const innerSig = wrapped.subject();\n const innerSigData = innerSig.asByteString();\n if (innerSigData !== undefined) {\n const innerSignature = new Signature(innerSigData);\n if (verifier.verify(subjectDigest.data(), innerSignature)) {\n return true;\n }\n }\n }\n }\n } catch {\n continue;\n }\n }\n }\n }\n }\n\n return false;\n };\n\n Envelope.prototype.verifySignatureFrom = function (this: Envelope, verifier: Verifier): Envelope {\n if (this.hasSignatureFrom(verifier)) {\n return this;\n }\n throw EnvelopeError.general(\"No valid signature found from the given verifier\");\n };\n\n Envelope.prototype.signatures = function (this: Envelope): Envelope[] {\n const assertions = this.assertions();\n return assertions\n .filter((a) => {\n const c = a.case();\n if (c.type === \"assertion\") {\n const pred = c.assertion.predicate();\n try {\n return pred.asText() === SIGNED;\n } catch {\n return false;\n }\n }\n return false;\n })\n .map((a) => {\n const c = a.case();\n if (c.type === \"assertion\") {\n return c.assertion.object();\n }\n throw EnvelopeError.general(\"Invalid signature assertion\");\n });\n };\n}\n","/**\n * Attachment Extension for Gordian Envelope\n *\n * Provides functionality for attaching vendor-specific metadata to envelopes.\n * Attachments enable flexible, extensible data storage without modifying\n * the core data model, facilitating interoperability and future compatibility.\n *\n * Each attachment has:\n * - A payload (arbitrary data)\n * - A required vendor identifier (typically a reverse domain name)\n * - An optional conformsTo URI that indicates the format of the attachment\n *\n * See BCR-2023-006: https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2023-006-envelope-attachment.md\n */\n\nimport { Envelope } from \"../base/envelope\";\nimport { type Digest } from \"../base/digest\";\nimport { EnvelopeError } from \"../base/error\";\nimport type { EnvelopeEncodableValue } from \"../base/envelope-encodable\";\n\n/**\n * Known value for the 'attachment' predicate.\n */\nexport const ATTACHMENT = \"attachment\";\n\n/**\n * Known value for the 'vendor' predicate.\n */\nexport const VENDOR = \"vendor\";\n\n/**\n * Known value for the 'conformsTo' predicate.\n */\nexport const CONFORMS_TO = \"conformsTo\";\n\n/**\n * A container for vendor-specific metadata attachments.\n *\n * Attachments provides a flexible mechanism for attaching arbitrary metadata\n * to envelopes without modifying their core structure.\n */\nexport class Attachments {\n readonly #envelopes = new Map<string, Envelope>();\n\n /**\n * Creates a new empty attachments container.\n */\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n constructor() {}\n\n /**\n * Adds a new attachment with the specified payload and metadata.\n *\n * @param payload - The data to attach\n * @param vendor - A string identifying the entity that defined the attachment format\n * @param conformsTo - Optional URI identifying the structure the payload conforms to\n */\n add(payload: EnvelopeEncodableValue, vendor: string, conformsTo?: string): void {\n const attachment = Envelope.newAttachment(payload, vendor, conformsTo);\n this.#envelopes.set(attachment.digest().hex(), attachment);\n }\n\n /**\n * Retrieves an attachment by its digest.\n *\n * @param digest - The unique digest of the attachment to retrieve\n * @returns The envelope if found, or undefined\n */\n get(digest: Digest): Envelope | undefined {\n return this.#envelopes.get(digest.hex());\n }\n\n /**\n * Removes an attachment by its digest.\n *\n * @param digest - The unique digest of the attachment to remove\n * @returns The removed envelope if found, or undefined\n */\n remove(digest: Digest): Envelope | undefined {\n const envelope = this.#envelopes.get(digest.hex());\n this.#envelopes.delete(digest.hex());\n return envelope;\n }\n\n /**\n * Removes all attachments from the container.\n */\n clear(): void {\n this.#envelopes.clear();\n }\n\n /**\n * Returns whether the container has any attachments.\n */\n isEmpty(): boolean {\n return this.#envelopes.size === 0;\n }\n\n /**\n * Adds all attachments from this container to an envelope.\n *\n * @param envelope - The envelope to add attachments to\n * @returns A new envelope with all attachments added as assertions\n */\n addToEnvelope(envelope: Envelope): Envelope {\n let result = envelope;\n for (const attachment of this.#envelopes.values()) {\n result = result.addAssertion(ATTACHMENT, attachment);\n }\n return result;\n }\n\n /**\n * Creates an Attachments container from an envelope's attachment assertions.\n *\n * @param envelope - The envelope to extract attachments from\n * @returns A new Attachments container with the envelope's attachments\n */\n static fromEnvelope(envelope: Envelope): Attachments {\n const attachments = new Attachments();\n const attachmentEnvelopes = envelope.attachments();\n\n for (const attachment of attachmentEnvelopes) {\n attachments.#envelopes.set(attachment.digest().hex(), attachment);\n }\n\n return attachments;\n }\n}\n\n// Implementation\n\n/**\n * Creates a new attachment envelope.\n */\nEnvelope.newAttachment = function (\n payload: EnvelopeEncodableValue,\n vendor: string,\n conformsTo?: string,\n): Envelope {\n // Create the payload envelope wrapped with vendor assertion\n let attachmentObj = Envelope.new(payload).wrap().addAssertion(VENDOR, vendor);\n\n // Add optional conformsTo\n if (conformsTo !== undefined) {\n attachmentObj = attachmentObj.addAssertion(CONFORMS_TO, conformsTo);\n }\n\n // Create an assertion with 'attachment' as predicate and the wrapped payload as object\n // This returns an assertion envelope\n const attachmentPredicate = Envelope.new(ATTACHMENT);\n return attachmentPredicate.addAssertion(ATTACHMENT, attachmentObj).assertions()[0];\n};\n\n/**\n * Adds an attachment to an envelope.\n */\n// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions\nif (Envelope?.prototype) {\n Envelope.prototype.addAttachment = function (\n this: Envelope,\n payload: EnvelopeEncodableValue,\n vendor: string,\n conformsTo?: string,\n ): Envelope {\n let attachmentObj = Envelope.new(payload).wrap().addAssertion(VENDOR, vendor);\n\n if (conformsTo !== undefined) {\n attachmentObj = attachmentObj.addAssertion(CONFORMS_TO, conformsTo);\n }\n\n return this.addAssertion(ATTACHMENT, attachmentObj);\n };\n\n /**\n * Returns the payload of an attachment envelope.\n */\n Envelope.prototype.attachmentPayload = function (this: Envelope): Envelope {\n const c = this.case();\n if (c.type !== \"assertion\") {\n throw EnvelopeError.general(\"Envelope is not an attachment assertion\");\n }\n\n const obj = c.assertion.object();\n return obj.unwrap();\n };\n\n /**\n * Returns the vendor of an attachment envelope.\n */\n Envelope.prototype.attachmentVendor = function (this: Envelope): string {\n const c = this.case();\n if (c.type !== \"assertion\") {\n throw EnvelopeError.general(\"Envelope is not an attachment assertion\");\n }\n\n const obj = c.assertion.object();\n const vendorEnv = obj.objectForPredicate(VENDOR);\n const vendor = vendorEnv.asText();\n\n if (vendor === undefined || vendor === \"\") {\n throw EnvelopeError.general(\"Attachment has no vendor\");\n }\n\n return vendor;\n };\n\n /**\n * Returns the conformsTo of an attachment envelope.\n */\n Envelope.prototype.attachmentConformsTo = function (this: Envelope): string | undefined {\n const c = this.case();\n if (c.type !== \"assertion\") {\n throw EnvelopeError.general(\"Envelope is not an attachment assertion\");\n }\n\n const obj = c.assertion.object();\n const conformsToEnv = obj.optionalObjectForPredicate(CONFORMS_TO);\n\n if (conformsToEnv === undefined) {\n return undefined;\n }\n\n return conformsToEnv.asText();\n };\n\n /**\n * Returns all attachment assertions.\n */\n Envelope.prototype.attachments = function (this: Envelope): Envelope[] {\n return this.assertionsWithPredicate(ATTACHMENT).map((a) => {\n const c = a.case();\n if (c.type === \"assertion\") {\n return c.assertion.object();\n }\n throw EnvelopeError.general(\"Invalid attachment assertion\");\n });\n };\n\n /**\n * Returns attachments matching vendor and/or conformsTo.\n */\n Envelope.prototype.attachmentsWithVendorAndConformsTo = function (\n this: Envelope,\n vendor?: string,\n conformsTo?: string,\n ): Envelope[] {\n const allAttachments = this.attachments();\n\n return allAttachments.filter((attachment) => {\n try {\n // The attachment is already a wrapped envelope with vendor/conformsTo assertions\n // Check vendor if specified\n if (vendor !== undefined) {\n const vendorEnv = attachment.objectForPredicate(VENDOR);\n const attachmentVendor = vendorEnv.asText();\n if (attachmentVendor !== vendor) {\n return false;\n }\n }\n\n // Check conformsTo if specified\n if (conformsTo !== undefined) {\n const conformsToEnv = attachment.optionalObjectForPredicate(CONFORMS_TO);\n if (conformsToEnv === undefined) {\n return false;\n }\n const conformsToText = conformsToEnv.asText();\n if (conformsToText !== conformsTo) {\n return false;\n }\n }\n\n return true;\n } catch {\n return false;\n }\n });\n };\n}\n","import { Envelope } from \"../base/envelope\";\nimport { EnvelopeError } from \"../base/error\";\nimport { SymmetricKey } from \"./encrypt\";\nimport {\n x25519NewPrivateKeyUsing,\n x25519PublicKeyFromPrivateKey,\n x25519SharedKey,\n aeadChaCha20Poly1305EncryptWithAad,\n aeadChaCha20Poly1305DecryptWithAad,\n hkdfHmacSha256,\n X25519_PUBLIC_KEY_SIZE,\n X25519_PRIVATE_KEY_SIZE,\n SYMMETRIC_NONCE_SIZE,\n SYMMETRIC_AUTH_SIZE,\n} from \"@bcts/crypto\";\nimport { SecureRandomNumberGenerator, rngRandomData } from \"@bcts/rand\";\n\n/// Extension for public-key encryption to specific recipients.\n///\n/// This module implements multi-recipient public key encryption using the\n/// Gordian Envelope sealed message pattern. Each recipient gets a sealed\n/// message containing an encrypted content key, allowing multiple recipients\n/// to decrypt the same envelope using their private keys.\n///\n/// ## How it works:\n///\n/// 1. A random symmetric content key is generated\n/// 2. The envelope's subject is encrypted with the content key\n/// 3. The content key is encrypted to each recipient's public key using X25519 key agreement\n/// 4. Each encrypted content key is added as a `hasRecipient` assertion\n///\n/// ## Sealed Box Security:\n///\n/// Sealed boxes use ephemeral X25519 key pairs. The ephemeral private key\n/// is discarded after encryption, ensuring that even the sender cannot\n/// decrypt the message later. Recipients must try each sealed message\n/// until one decrypts successfully.\n///\n/// Uses @bcts/crypto functions for X25519 and ChaCha20-Poly1305.\n///\n/// @example\n/// ```typescript\n/// // Generate recipient keys\n/// const alice = PrivateKeyBase.generate();\n/// const bob = PrivateKeyBase.generate();\n///\n/// // Encrypt to multiple recipients\n/// const envelope = Envelope.new(\"Secret message\")\n/// .encryptSubjectToRecipients([alice.publicKeys(), bob.publicKeys()]);\n///\n/// // Alice decrypts\n/// const aliceDecrypted = envelope.decryptSubjectToRecipient(alice);\n///\n/// // Bob decrypts\n/// const bobDecrypted = envelope.decryptSubjectToRecipient(bob);\n/// ```\n\n/// Predicate constant for recipient assertions\nexport const HAS_RECIPIENT = \"hasRecipient\";\n\n/// Represents an X25519 public key for encryption\nexport class PublicKeyBase {\n readonly #publicKey: Uint8Array;\n\n constructor(publicKey: Uint8Array) {\n if (publicKey.length !== X25519_PUBLIC_KEY_SIZE) {\n throw new Error(`Public key must be ${X25519_PUBLIC_KEY_SIZE} bytes`);\n }\n this.#publicKey = publicKey;\n }\n\n /// Returns the raw public key bytes\n data(): Uint8Array {\n return this.#publicKey;\n }\n\n /// Returns the public key as a hex string\n hex(): string {\n return Array.from(this.#publicKey)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n }\n\n /// Creates a public key from hex string\n static fromHex(hex: string): PublicKeyBase {\n if (hex.length !== 64) {\n throw new Error(\"Hex string must be 64 characters (32 bytes)\");\n }\n const bytes = new Uint8Array(32);\n for (let i = 0; i < 32; i++) {\n bytes[i] = parseInt(hex.substr(i * 2, 2), 16);\n }\n return new PublicKeyBase(bytes);\n }\n}\n\n/// Represents an X25519 private key for decryption\nexport class PrivateKeyBase {\n readonly #privateKey: Uint8Array;\n readonly #publicKey: PublicKeyBase;\n\n private constructor(privateKey: Uint8Array, publicKey: Uint8Array) {\n this.#privateKey = privateKey;\n this.#publicKey = new PublicKeyBase(publicKey);\n }\n\n /// Generates a new random X25519 key pair\n static generate(): PrivateKeyBase {\n const rng = new SecureRandomNumberGenerator();\n const privateKey = x25519NewPrivateKeyUsing(rng);\n const publicKey = x25519PublicKeyFromPrivateKey(privateKey);\n return new PrivateKeyBase(privateKey, publicKey);\n }\n\n /// Creates a private key from existing bytes\n static fromBytes(privateKey: Uint8Array, publicKey: Uint8Array): PrivateKeyBase {\n if (privateKey.length !== X25519_PRIVATE_KEY_SIZE) {\n throw new Error(`Private key must be ${X25519_PRIVATE_KEY_SIZE} bytes`);\n }\n if (publicKey.length !== X25519_PUBLIC_KEY_SIZE) {\n throw new Error(`Public key must be ${X25519_PUBLIC_KEY_SIZE} bytes`);\n }\n return new PrivateKeyBase(privateKey, publicKey);\n }\n\n /// Creates a private key from hex strings\n static fromHex(privateHex: string, publicHex: string): PrivateKeyBase {\n const privateBytes = new Uint8Array(32);\n const publicBytes = new Uint8Array(32);\n\n for (let i = 0; i < 32; i++) {\n privateBytes[i] = parseInt(privateHex.substr(i * 2, 2), 16);\n publicBytes[i] = parseInt(publicHex.substr(i * 2, 2), 16);\n }\n\n return new PrivateKeyBase(privateBytes, publicBytes);\n }\n\n /// Returns the public key\n publicKeys(): PublicKeyBase {\n return this.#publicKey;\n }\n\n /// Returns the raw private key bytes\n data(): Uint8Array {\n return this.#privateKey;\n }\n\n /// Returns the private key as hex string\n hex(): string {\n return Array.from(this.#privateKey)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n }\n\n /// Decrypts a sealed message to get the content key\n unseal(sealedMessage: SealedMessage): SymmetricKey {\n try {\n const decrypted = sealedMessage.decrypt(this.#privateKey, this.#publicKey.data());\n return SymmetricKey.from(decrypted);\n } catch (_error) {\n throw EnvelopeError.general(\"Failed to unseal message: not a recipient\");\n }\n }\n}\n\n/// Represents a sealed message - encrypted content key for a recipient\n/// Uses X25519 key agreement + ChaCha20-Poly1305 AEAD\n///\n/// Format: ephemeral_public_key (32 bytes) || nonce (12 bytes) || ciphertext || auth_tag (16 bytes)\nexport class SealedMessage {\n readonly #data: Uint8Array;\n\n constructor(data: Uint8Array) {\n this.#data = data;\n }\n\n /// Creates a sealed message by encrypting a symmetric key to a recipient's public key\n /// Uses X25519 ECDH for key agreement and ChaCha20-Poly1305 for encryption\n static seal(contentKey: SymmetricKey, recipientPublicKey: PublicKeyBase): SealedMessage {\n const rng = new SecureRandomNumberGenerator();\n\n // Generate ephemeral key pair\n const ephemeralPrivate = x25519NewPrivateKeyUsing(rng);\n const ephemeralPublic = x25519PublicKeyFromPrivateKey(ephemeralPrivate);\n\n // Compute shared secret using X25519 ECDH\n const sharedSecret = x25519SharedKey(ephemeralPrivate, recipientPublicKey.data());\n\n // Derive encryption key from shared secret using HKDF\n const salt = new TextEncoder().encode(\"sealed_message\");\n const encryptionKey = hkdfHmacSha256(sharedSecret, salt, 32);\n\n // Generate random nonce\n const nonce = rngRandomData(rng, SYMMETRIC_NONCE_SIZE);\n\n // Encrypt content key using ChaCha20-Poly1305\n const plaintext = contentKey.data();\n const [ciphertext, authTag] = aeadChaCha20Poly1305EncryptWithAad(\n plaintext,\n encryptionKey,\n nonce,\n new Uint8Array(0), // No AAD for sealed box\n );\n\n // Format: ephemeral_public_key || nonce || ciphertext || auth_tag\n const totalLength = ephemeralPublic.length + nonce.length + ciphertext.length + authTag.length;\n const sealed = new Uint8Array(totalLength);\n let offset = 0;\n\n sealed.set(ephemeralPublic, offset);\n offset += ephemeralPublic.length;\n\n sealed.set(nonce, offset);\n offset += nonce.length;\n\n sealed.set(ciphertext, offset);\n offset += ciphertext.length;\n\n sealed.set(authTag, offset);\n\n return new SealedMessage(sealed);\n }\n\n /// Decrypts this sealed message using recipient's private key\n decrypt(recipientPrivate: Uint8Array, _recipientPublic: Uint8Array): Uint8Array {\n // Parse sealed message format: ephemeral_public_key || nonce || ciphertext || auth_tag\n const minLength = X25519_PUBLIC_KEY_SIZE + SYMMETRIC_NONCE_SIZE + SYMMETRIC_AUTH_SIZE;\n if (this.#data.length < minLength) {\n throw new Error(\"Sealed message too short\");\n }\n\n let offset = 0;\n\n // Extract ephemeral public key\n const ephemeralPublic = this.#data.slice(offset, offset + X25519_PUBLIC_KEY_SIZE);\n offset += X25519_PUBLIC_KEY_SIZE;\n\n // Extract nonce\n const nonce = this.#data.slice(offset, offset + SYMMETRIC_NONCE_SIZE);\n offset += SYMMETRIC_NONCE_SIZE;\n\n // Extract ciphertext and auth tag\n const ciphertextAndTag = this.#data.slice(offset);\n const ciphertext = ciphertextAndTag.slice(0, -SYMMETRIC_AUTH_SIZE);\n const authTag = ciphertextAndTag.slice(-SYMMETRIC_AUTH_SIZE);\n\n // Compute shared secret using X25519 ECDH\n const sharedSecret = x25519SharedKey(recipientPrivate, ephemeralPublic);\n\n // Derive decryption key from shared secret using HKDF\n const salt = new TextEncoder().encode(\"sealed_message\");\n const decryptionKey = hkdfHmacSha256(sharedSecret, salt, 32);\n\n // Decrypt using ChaCha20-Poly1305\n const plaintext = aeadChaCha20Poly1305DecryptWithAad(\n ciphertext,\n decryptionKey,\n nonce,\n new Uint8Array(0), // No AAD for sealed box\n authTag,\n );\n\n return plaintext;\n }\n\n /// Returns the raw sealed message bytes\n data(): Uint8Array {\n return this.#data;\n }\n\n /// Returns the sealed message as hex string\n hex(): string {\n return Array.from(this.#data)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n }\n\n /// Creates a sealed message from hex string\n static fromHex(hex: string): SealedMessage {\n const bytes = new Uint8Array(hex.length / 2);\n for (let i = 0; i < bytes.length; i++) {\n bytes[i] = parseInt(hex.substr(i * 2, 2), 16);\n }\n return new SealedMessage(bytes);\n }\n}\n\n/// Implementation of encryptSubjectToRecipient()\n// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions\nif (Envelope?.prototype) {\n Envelope.prototype.encryptSubjectToRecipient = function (\n this: Envelope,\n recipientPublicKey: PublicKeyBase,\n ): Envelope {\n // Generate a random content key\n const contentKey = SymmetricKey.generate();\n\n // Encrypt the subject with the content key\n const encrypted = this.encryptSubject(contentKey);\n\n // Add the recipient\n return encrypted.addRecipient(recipientPublicKey, contentKey);\n };\n\n /// Implementation of encryptSubjectToRecipients()\n Envelope.prototype.encryptSubjectToRecipients = function (\n this: Envelope,\n recipients: PublicKeyBase[],\n ): Envelope {\n if (recipients.length === 0) {\n throw EnvelopeError.general(\"Must provide at least one recipient\");\n }\n\n // Generate a random content key\n const contentKey = SymmetricKey.generate();\n\n // Encrypt the subject with the content key\n let result = this.encryptSubject(contentKey);\n\n // Add each recipient\n for (const recipient of recipients) {\n result = result.addRecipient(recipient, contentKey);\n }\n\n return result;\n };\n\n /// Implementation of addRecipient()\n Envelope.prototype.addRecipient = function (\n this: Envelope,\n recipientPublicKey: PublicKeyBase,\n contentKey: SymmetricKey,\n ): Envelope {\n // Create a sealed message with the content key\n const sealedMessage = SealedMessage.seal(contentKey, recipientPublicKey);\n\n // Store the sealed message as bytes in the assertion\n return this.addAssertion(HAS_RECIPIENT, sealedMessage.data());\n };\n\n /// Implementation of decryptSubjectToRecipient()\n Envelope.prototype.decryptSubjectToRecipient = function (\n this: Envelope,\n recipientPrivateKey: PrivateKeyBase,\n ): Envelope {\n // Check that the subject is encrypted\n const subjectCase = this.subject().case();\n if (subjectCase.type !== \"encrypted\") {\n throw EnvelopeError.general(\"Subject is not encrypted\");\n }\n\n // Get all recipient assertions\n const recipientAssertions = this.assertions().filter((assertion) => {\n try {\n const predicate = assertion.subject().asPredicate();\n if (predicate === undefined) return false;\n return predicate.asText() === HAS_RECIPIENT;\n } catch {\n return false;\n }\n });\n\n if (recipientAssertions.length === 0) {\n throw EnvelopeError.general(\"No recipients found\");\n }\n\n // Try each recipient assertion until one unseals successfully\n let contentKey: SymmetricKey | null = null;\n\n for (const assertion of recipientAssertions) {\n try {\n const obj = assertion.subject().asObject();\n if (obj === undefined) continue;\n const sealedData = obj.asByteString();\n if (sealedData === undefined) continue;\n const sealedMessage = new SealedMessage(sealedData);\n\n // Try to unseal with our private key\n contentKey = recipientPrivateKey.unseal(sealedMessage);\n break; // Success!\n } catch {\n // Not for us, try next one\n continue;\n }\n }\n\n if (contentKey === null) {\n throw EnvelopeError.general(\"Not a valid recipient\");\n }\n\n // Decrypt the subject using the content key\n return this.decryptSubject(contentKey);\n };\n\n /// Implementation of decryptToRecipient()\n Envelope.prototype.decryptToRecipient = function (\n this: Envelope,\n recipientPrivateKey: PrivateKeyBase,\n ): Envelope {\n const decrypted = this.decryptSubjectToRecipient(recipientPrivateKey);\n return decrypted.unwrap();\n };\n\n /// Implementation of encryptToRecipients()\n Envelope.prototype.encryptToRecipients = function (\n this: Envelope,\n recipients: PublicKeyBase[],\n ): Envelope {\n return this.wrap().encryptSubjectToRecipients(recipients);\n };\n\n /// Implementation of recipients()\n Envelope.prototype.recipients = function (this: Envelope): SealedMessage[] {\n const recipientAssertions = this.assertions().filter((assertion) => {\n try {\n const predicate = assertion.subject().asPredicate();\n if (predicate === undefined) return false;\n return predicate.asText() === HAS_RECIPIENT;\n } catch {\n return false;\n }\n });\n\n return recipientAssertions.map((assertion) => {\n const obj = assertion.subject().asObject();\n if (obj === undefined) {\n throw EnvelopeError.general(\"Invalid recipient assertion\");\n }\n const sealedData = obj.asByteString();\n if (sealedData === undefined) {\n throw EnvelopeError.general(\"Invalid recipient data\");\n }\n return new SealedMessage(sealedData);\n });\n };\n}\n\n// Import side-effect to register prototype extensions\nexport {};\n","import { Envelope } from \"../base/envelope\";\nimport { type EnvelopeEncodableValue } from \"../base/envelope-encodable\";\nimport { EnvelopeError } from \"../base/error\";\n\n/// Extension for envelope expressions.\n///\n/// This module implements the Gordian Envelope expression syntax as specified\n/// in BCR-2023-012. Expressions enable encoding of machine-evaluatable\n/// expressions using envelopes, providing a foundation for distributed\n/// function calls and computation.\n///\n/// ## Expression Structure\n///\n/// An expression consists of:\n/// - A function identifier (the subject)\n/// - Zero or more parameters (as assertions)\n/// - Optional metadata (non-parameter assertions)\n///\n/// ## CBOR Tags\n///\n/// - Function: #6.40006\n/// - Parameter: #6.40007\n/// - Placeholder: #6.40008\n/// - Replacement: #6.40009\n///\n/// @example\n/// ```typescript\n/// // Create a simple addition expression: add(lhs: 2, rhs: 3)\n/// const expr = new Function('add')\n/// .withParameter('lhs', 2)\n/// .withParameter('rhs', 3);\n///\n/// const envelope = expr.envelope();\n/// ```\n\n/// CBOR tag for function identifiers\nexport const CBOR_TAG_FUNCTION = 40006;\n\n/// CBOR tag for parameter identifiers\nexport const CBOR_TAG_PARAMETER = 40007;\n\n/// CBOR tag for placeholder identifiers\nexport const CBOR_TAG_PLACEHOLDER = 40008;\n\n/// CBOR tag for replacement identifiers\nexport const CBOR_TAG_REPLACEMENT = 40009;\n\n/// Well-known function identifiers (numeric)\nexport const FUNCTION_IDS = {\n ADD: 1, // addition\n SUB: 2, // subtraction\n MUL: 3, // multiplication\n DIV: 4, // division\n NEG: 5, // unary negation\n LT: 6, // less than\n LE: 7, // less than or equal\n GT: 8, // greater than\n GE: 9, // greater than or equal\n EQ: 10, // equal to\n NE: 11, // not equal to\n AND: 12, // logical and\n OR: 13, // logical or\n XOR: 14, // logical xor\n NOT: 15, // logical not\n} as const;\n\n/// Well-known parameter identifiers (numeric)\nexport const PARAMETER_IDS = {\n BLANK: 1, // blank/implicit parameter (_)\n LHS: 2, // left-hand side\n RHS: 3, // right-hand side\n} as const;\n\n/// Type for function identifier (number or string)\nexport type FunctionID = number | string;\n\n/// Type for parameter identifier (number or string)\nexport type ParameterID = number | string;\n\n/// Represents a function identifier in an expression\nexport class Function {\n readonly #id: FunctionID;\n\n constructor(id: FunctionID) {\n this.#id = id;\n }\n\n /// Returns the function identifier\n id(): FunctionID {\n return this.#id;\n }\n\n /// Returns true if this is a numeric function ID\n isNumeric(): boolean {\n return typeof this.#id === \"number\";\n }\n\n /// Returns true if this is a string function ID\n isString(): boolean {\n return typeof this.#id === \"string\";\n }\n\n /// Creates an expression envelope with this function as the subject\n envelope(): Envelope {\n // For now, create a simple envelope with the function ID\n // In a full implementation, this would use CBOR tag 40006\n const functionStr = typeof this.#id === \"number\" ? `«${this.#id}»` : `«\"${this.#id}\"»`;\n return Envelope.new(functionStr);\n }\n\n /// Creates an expression with a parameter\n withParameter(param: ParameterID, value: EnvelopeEncodableValue): Expression {\n const expr = new Expression(this);\n return expr.withParameter(param, value);\n }\n\n /// Creates a function from a known numeric ID\n static fromNumeric(id: number): Function {\n return new Function(id);\n }\n\n /// Creates a function from a string name\n static fromString(name: string): Function {\n return new Function(name);\n }\n\n /// Returns a string representation for display\n toString(): string {\n return typeof this.#id === \"number\" ? `«${this.#id}»` : `«\"${this.#id}\"»`;\n }\n}\n\n/// Represents a parameter in an expression\nexport class Parameter {\n readonly #id: ParameterID;\n readonly #value: Envelope;\n\n constructor(id: ParameterID, value: Envelope) {\n this.#id = id;\n this.#value = value;\n }\n\n /// Returns the parameter identifier\n id(): ParameterID {\n return this.#id;\n }\n\n /// Returns the parameter value as an envelope\n value(): Envelope {\n return this.#value;\n }\n\n /// Returns true if this is a numeric parameter ID\n isNumeric(): boolean {\n return typeof this.#id === \"number\";\n }\n\n /// Returns true if this is a string parameter ID\n isString(): boolean {\n return typeof this.#id === \"string\";\n }\n\n /// Creates a parameter envelope\n /// In a full implementation, this would use CBOR tag 40007\n envelope(): Envelope {\n const paramStr = typeof this.#id === \"number\" ? `❰${this.#id}❱` : `❰\"${this.#id}\"❱`;\n return Envelope.newAssertion(paramStr, this.#value);\n }\n\n /// Creates a parameter from known IDs\n static blank(value: EnvelopeEncodableValue): Parameter {\n return new Parameter(PARAMETER_IDS.BLANK, Envelope.new(value));\n }\n\n static lhs(value: EnvelopeEncodableValue): Parameter {\n return new Parameter(PARAMETER_IDS.LHS, Envelope.new(value));\n }\n\n static rhs(value: EnvelopeEncodableValue): Parameter {\n return new Parameter(PARAMETER_IDS.RHS, Envelope.new(value));\n }\n\n /// Returns a string representation for display\n toString(): string {\n const idStr = typeof this.#id === \"number\" ? `❰${this.#id}❱` : `❰\"${this.#id}\"❱`;\n return `${idStr}: ${this.#value.asText()}`;\n }\n}\n\n/// Represents a complete expression with function and parameters\nexport class Expression {\n readonly #function: Function;\n readonly #parameters = new Map<string, Parameter>();\n #envelope: Envelope | null = null;\n\n constructor(func: Function) {\n this.#function = func;\n }\n\n /// Returns the function\n function(): Function {\n return this.#function;\n }\n\n /// Returns all parameters\n parameters(): Parameter[] {\n return Array.from(this.#parameters.values());\n }\n\n /// Adds a parameter to the expression\n withParameter(param: ParameterID, value: EnvelopeEncodableValue): Expression {\n const key = typeof param === \"number\" ? param.toString() : param;\n this.#parameters.set(key, new Parameter(param, Envelope.new(value)));\n this.#envelope = null; // Invalidate cached envelope\n return this;\n }\n\n /// Adds multiple parameters at once\n withParameters(params: Record<string, EnvelopeEncodableValue>): Expression {\n for (const [key, value] of Object.entries(params)) {\n this.withParameter(key, value);\n }\n return this;\n }\n\n /// Gets a parameter value by ID\n getParameter(param: ParameterID): Envelope | undefined {\n const key = typeof param === \"number\" ? param.toString() : param;\n return this.#parameters.get(key)?.value();\n }\n\n /// Checks if a parameter exists\n hasParameter(param: ParameterID): boolean {\n const key = typeof param === \"number\" ? param.toString() : param;\n return this.#parameters.has(key);\n }\n\n /// Converts the expression to an envelope\n envelope(): Envelope {\n if (this.#envelope !== null) {\n return this.#envelope;\n }\n\n // Start with function envelope\n let env = this.#function.envelope();\n\n // Add all parameters as assertions\n for (const param of this.#parameters.values()) {\n const paramEnv = param.envelope();\n // Extract the assertion from the parameter envelope\n const assertion = paramEnv.assertions()[0];\n if (assertion !== undefined) {\n const predicate = assertion.subject().asPredicate();\n const object = assertion.subject().asObject();\n if (predicate !== undefined && object !== undefined) {\n env = env.addAssertion(predicate.asText(), object);\n }\n }\n }\n\n this.#envelope = env;\n return env;\n }\n\n /// Creates an expression from an envelope\n /// Note: This is a simplified implementation\n static fromEnvelope(envelope: Envelope): Expression {\n // Extract function from subject\n const subject = envelope.subject();\n const subjectText = subject.asText();\n if (subjectText === undefined) {\n throw EnvelopeError.general(\"Not a valid function envelope\");\n }\n\n // Parse function identifier\n let funcId: FunctionID;\n if (subjectText.startsWith(\"«\") && subjectText.endsWith(\"»\")) {\n const inner = subjectText.slice(1, -1);\n if (inner.startsWith('\"') && inner.endsWith('\"')) {\n funcId = inner.slice(1, -1); // String function\n } else {\n funcId = parseInt(inner, 10); // Numeric function\n }\n } else {\n throw EnvelopeError.general(\"Not a valid function envelope\");\n }\n\n const func = new Function(funcId);\n const expr = new Expression(func);\n\n // Extract parameters from assertions\n for (const assertion of envelope.assertions()) {\n try {\n const pred = assertion.subject().asPredicate();\n const obj = assertion.subject().asObject();\n\n if (pred !== undefined && obj !== undefined) {\n const predText = pred.asText();\n if (predText !== undefined && predText.startsWith(\"❰\") && predText.endsWith(\"❱\")) {\n const inner = predText.slice(1, -1);\n let paramId: ParameterID;\n if (inner.startsWith('\"') && inner.endsWith('\"')) {\n paramId = inner.slice(1, -1);\n } else {\n paramId = parseInt(inner, 10);\n }\n expr.withParameter(paramId, obj);\n }\n }\n } catch {\n // Skip non-parameter assertions\n continue;\n }\n }\n\n return expr;\n }\n\n /// Returns a string representation for display\n toString(): string {\n const params = Array.from(this.#parameters.values())\n .map((p) => p.toString())\n .join(\", \");\n return `${this.#function.toString()} [${params}]`;\n }\n}\n\n/// Helper functions for creating common expressions\n\n/// Creates an addition expression: lhs + rhs\nexport function add(lhs: EnvelopeEncodableValue, rhs: EnvelopeEncodableValue): Expression {\n return Function.fromNumeric(FUNCTION_IDS.ADD)\n .withParameter(PARAMETER_IDS.LHS, lhs)\n .withParameter(PARAMETER_IDS.RHS, rhs);\n}\n\n/// Creates a subtraction expression: lhs - rhs\nexport function sub(lhs: EnvelopeEncodableValue, rhs: EnvelopeEncodableValue): Expression {\n return Function.fromNumeric(FUNCTION_IDS.SUB)\n .withParameter(PARAMETER_IDS.LHS, lhs)\n .withParameter(PARAMETER_IDS.RHS, rhs);\n}\n\n/// Creates a multiplication expression: lhs * rhs\nexport function mul(lhs: EnvelopeEncodableValue, rhs: EnvelopeEncodableValue): Expression {\n return Function.fromNumeric(FUNCTION_IDS.MUL)\n .withParameter(PARAMETER_IDS.LHS, lhs)\n .withParameter(PARAMETER_IDS.RHS, rhs);\n}\n\n/// Creates a division expression: lhs / rhs\nexport function div(lhs: EnvelopeEncodableValue, rhs: EnvelopeEncodableValue): Expression {\n return Function.fromNumeric(FUNCTION_IDS.DIV)\n .withParameter(PARAMETER_IDS.LHS, lhs)\n .withParameter(PARAMETER_IDS.RHS, rhs);\n}\n\n/// Creates a negation expression: -value\nexport function neg(value: EnvelopeEncodableValue): Expression {\n return Function.fromNumeric(FUNCTION_IDS.NEG).withParameter(PARAMETER_IDS.BLANK, value);\n}\n\n/// Creates a less-than expression: lhs < rhs\nexport function lt(lhs: EnvelopeEncodableValue, rhs: EnvelopeEncodableValue): Expression {\n return Function.fromNumeric(FUNCTION_IDS.LT)\n .withParameter(PARAMETER_IDS.LHS, lhs)\n .withParameter(PARAMETER_IDS.RHS, rhs);\n}\n\n/// Creates a greater-than expression: lhs > rhs\nexport function gt(lhs: EnvelopeEncodableValue, rhs: EnvelopeEncodableValue): Expression {\n return Function.fromNumeric(FUNCTION_IDS.GT)\n .withParameter(PARAMETER_IDS.LHS, lhs)\n .withParameter(PARAMETER_IDS.RHS, rhs);\n}\n\n/// Creates an equality expression: lhs == rhs\nexport function eq(lhs: EnvelopeEncodableValue, rhs: EnvelopeEncodableValue): Expression {\n return Function.fromNumeric(FUNCTION_IDS.EQ)\n .withParameter(PARAMETER_IDS.LHS, lhs)\n .withParameter(PARAMETER_IDS.RHS, rhs);\n}\n\n/// Creates a logical AND expression: lhs && rhs\nexport function and(lhs: EnvelopeEncodableValue, rhs: EnvelopeEncodableValue): Expression {\n return Function.fromNumeric(FUNCTION_IDS.AND)\n .withParameter(PARAMETER_IDS.LHS, lhs)\n .withParameter(PARAMETER_IDS.RHS, rhs);\n}\n\n/// Creates a logical OR expression: lhs || rhs\nexport function or(lhs: EnvelopeEncodableValue, rhs: EnvelopeEncodableValue): Expression {\n return Function.fromNumeric(FUNCTION_IDS.OR)\n .withParameter(PARAMETER_IDS.LHS, lhs)\n .withParameter(PARAMETER_IDS.RHS, rhs);\n}\n\n/// Creates a logical NOT expression: !value\nexport function not(value: EnvelopeEncodableValue): Expression {\n return Function.fromNumeric(FUNCTION_IDS.NOT).withParameter(PARAMETER_IDS.BLANK, value);\n}\n\n// Export types and classes\nexport {};\n","import { Envelope } from \"../base/envelope\";\nimport { type Digest } from \"../base/digest\";\n\n/// Extension for envelope inclusion proofs.\n///\n/// Inclusion proofs allow a holder of an envelope to prove that specific\n/// elements exist within the envelope without revealing the entire contents.\n/// This is particularly useful for selective disclosure of information in\n/// privacy-preserving scenarios.\n///\n/// ## How Inclusion Proofs Work\n///\n/// The inclusion proof mechanism leverages the Merkle-like digest tree\n/// structure of envelopes:\n/// - The holder creates a minimal structure containing only the digests\n/// necessary to validate the proof\n/// - A verifier with a trusted root digest can confirm that the specific\n/// elements exist in the original envelope\n/// - All other content can remain elided, preserving privacy\n///\n/// For enhanced privacy, elements can be salted to prevent correlation attacks.\n///\n/// @example\n/// ```typescript\n/// // Create an envelope with multiple assertions\n/// const aliceFriends = Envelope.new('Alice')\n/// .addAssertion('knows', 'Bob')\n/// .addAssertion('knows', 'Carol')\n/// .addAssertion('knows', 'Dan');\n///\n/// // Create a representation of just the root digest\n/// const aliceFriendsRoot = aliceFriends.elideRevealingSet(new Set());\n///\n/// // Create the target we want to prove exists\n/// const knowsBobAssertion = Envelope.newAssertion('knows', 'Bob');\n///\n/// // Generate a proof that Alice knows Bob\n/// const aliceKnowsBobProof = aliceFriends.proofContainsTarget(knowsBobAssertion);\n///\n/// // A third party can verify the proof against the trusted root\n/// if (aliceKnowsBobProof) {\n/// const isValid = aliceFriendsRoot.confirmContainsTarget(\n/// knowsBobAssertion,\n/// aliceKnowsBobProof\n/// );\n/// console.log('Proof is valid:', isValid);\n/// }\n/// ```\n\n/// Implementation of proof methods on Envelope prototype\n// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions\nif (Envelope?.prototype) {\n Envelope.prototype.proofContainsSet = function (target: Set<Digest>): Envelope | undefined {\n const revealSet = revealSetOfSet(this, target);\n\n // Check if all targets can be revealed\n if (!isSubset(target, revealSet)) {\n return undefined;\n }\n\n // Create a proof by revealing only what's necessary, then eliding the targets\n const revealed = this.elideRevealingSet(revealSet);\n return revealed.elideRemovingSet(target);\n };\n\n Envelope.prototype.proofContainsTarget = function (target: Envelope): Envelope | undefined {\n const targetSet = new Set<Digest>([target.digest()]);\n return this.proofContainsSet(targetSet);\n };\n\n Envelope.prototype.confirmContainsSet = function (target: Set<Digest>, proof: Envelope): boolean {\n // Verify the proof has the same digest as this envelope\n if (this.digest().hex() !== proof.digest().hex()) {\n return false;\n }\n\n // Verify the proof contains all target elements\n return containsAll(proof, target);\n };\n\n Envelope.prototype.confirmContainsTarget = function (target: Envelope, proof: Envelope): boolean {\n const targetSet = new Set<Digest>([target.digest()]);\n return this.confirmContainsSet(targetSet, proof);\n };\n}\n\n/// Internal helper functions\n\n/// Builds a set of all digests needed to reveal the target set.\n///\n/// This collects all digests in the path from the envelope's root to each\n/// target element.\nfunction revealSetOfSet(envelope: Envelope, target: Set<Digest>): Set<Digest> {\n const result = new Set<Digest>();\n revealSets(envelope, target, new Set<Digest>(), result);\n return result;\n}\n\n/// Recursively traverses the envelope to collect all digests needed to\n/// reveal the target set.\n///\n/// Builds the set of digests forming the path from the root to each target element.\nfunction revealSets(\n envelope: Envelope,\n target: Set<Digest>,\n current: Set<Digest>,\n result: Set<Digest>,\n): void {\n // Add current envelope's digest to the path\n const newCurrent = new Set(current);\n newCurrent.add(envelope.digest());\n\n // If this is a target, add the entire path to the result\n if (containsDigest(target, envelope.digest())) {\n for (const digest of newCurrent) {\n result.add(digest);\n }\n }\n\n // Traverse the envelope structure\n const envelopeCase = envelope.case();\n\n if (envelopeCase.type === \"node\") {\n // Traverse subject\n revealSets(envelopeCase.subject, target, newCurrent, result);\n\n // Traverse all assertions\n for (const assertion of envelopeCase.assertions) {\n revealSets(assertion, target, newCurrent, result);\n }\n } else if (envelopeCase.type === \"wrapped\") {\n // Traverse wrapped envelope\n revealSets(envelopeCase.envelope, target, newCurrent, result);\n } else if (envelopeCase.type === \"assertion\") {\n // Traverse predicate and object\n const predicate = envelopeCase.assertion.predicate();\n const object = envelopeCase.assertion.object();\n revealSets(predicate, target, newCurrent, result);\n revealSets(object, target, newCurrent, result);\n }\n // For leaf envelopes (elided, encrypted, compressed, leaf), no further traversal needed\n}\n\n/// Checks if this envelope contains all elements in the target set.\n///\n/// Used during proof verification to confirm all target elements exist in the proof.\nfunction containsAll(envelope: Envelope, target: Set<Digest>): boolean {\n const targetCopy = new Set(target);\n removeAllFound(envelope, targetCopy);\n return targetCopy.size === 0;\n}\n\n/// Recursively traverses the envelope and removes found target elements from the set.\n///\n/// Used during proof verification to confirm all target elements are present.\nfunction removeAllFound(envelope: Envelope, target: Set<Digest>): void {\n // Check if this envelope's digest is in the target set\n if (containsDigest(target, envelope.digest())) {\n removeDigest(target, envelope.digest());\n }\n\n // Early exit if all targets found\n if (target.size === 0) {\n return;\n }\n\n // Traverse the envelope structure\n const envelopeCase = envelope.case();\n\n if (envelopeCase.type === \"node\") {\n // Traverse subject\n removeAllFound(envelopeCase.subject, target);\n\n // Traverse all assertions\n for (const assertion of envelopeCase.assertions) {\n removeAllFound(assertion, target);\n if (target.size === 0) break;\n }\n } else if (envelopeCase.type === \"wrapped\") {\n // Traverse wrapped envelope\n removeAllFound(envelopeCase.envelope, target);\n } else if (envelopeCase.type === \"assertion\") {\n // Traverse predicate and object\n const predicate = envelopeCase.assertion.predicate();\n const object = envelopeCase.assertion.object();\n removeAllFound(predicate, target);\n if (target.size > 0) {\n removeAllFound(object, target);\n }\n }\n // For leaf envelopes (elided, encrypted, compressed, leaf), no further traversal needed\n}\n\n/// Helper function to check if a set contains a digest (by hex comparison)\nfunction containsDigest(set: Set<Digest>, digest: Digest): boolean {\n const hexToFind = digest.hex();\n for (const d of set) {\n if (d.hex() === hexToFind) {\n return true;\n }\n }\n return false;\n}\n\n/// Helper function to remove a digest from a set (by hex comparison)\nfunction removeDigest(set: Set<Digest>, digest: Digest): void {\n const hexToFind = digest.hex();\n for (const d of set) {\n if (d.hex() === hexToFind) {\n set.delete(d);\n return;\n }\n }\n}\n\n/// Helper function to check if one set is a subset of another (by hex comparison)\nfunction isSubset(subset: Set<Digest>, superset: Set<Digest>): boolean {\n for (const digest of subset) {\n if (!containsDigest(superset, digest)) {\n return false;\n }\n }\n return true;\n}\n\n// Export empty object to make this a module\nexport {};\n","import { Envelope } from \"../base/envelope\";\nimport { cborData } from \"@bcts/dcbor\";\n\n/// Hex formatting for Gordian Envelopes.\n///\n/// This module provides methods for converting envelopes to hexadecimal\n/// representations of their CBOR encoding, useful for debugging and\n/// low-level inspection.\n\n// Note: Method declarations are in the base Envelope class.\n// This module provides the prototype implementations.\n\n/// Implementation of hex()\nEnvelope.prototype.hex = function (this: Envelope): string {\n const bytes = this.cborBytes();\n return Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n};\n\n/// Implementation of cborBytes()\nEnvelope.prototype.cborBytes = function (this: Envelope): Uint8Array {\n const cbor = this.taggedCbor();\n return cborData(cbor);\n};\n","import { Envelope } from \"../base/envelope\";\n\n// Type for CBOR values that can appear in diagnostic notation\ntype CborValue =\n | string\n | number\n | boolean\n | null\n | Uint8Array\n | CborValue[]\n | Map<CborValue, CborValue>\n | { tag: number; value: CborValue }\n | { type: number; value: unknown };\n\n/// Diagnostic notation formatting for Gordian Envelopes.\n///\n/// This module provides methods for converting envelopes to CBOR diagnostic\n/// notation, a human-readable text format defined in RFC 8949 §8.\n///\n/// See [RFC-8949 §8](https://www.rfc-editor.org/rfc/rfc8949.html#name-diagnostic-notation)\n/// for information on CBOR diagnostic notation.\n\n// Note: Method declarations are in the base Envelope class.\n// This module provides the prototype implementations.\n\n/// Converts a CBOR value to diagnostic notation\nfunction cborToDiagnostic(cbor: CborValue, indent = 0): string {\n // Handle tagged values (CBOR tags)\n if (typeof cbor === \"object\" && cbor !== null && \"tag\" in cbor && \"value\" in cbor) {\n const tagged = cbor as { tag: number; value: CborValue };\n return `${tagged.tag}(${cborToDiagnostic(tagged.value, indent)})`;\n }\n\n // Handle arrays\n if (Array.isArray(cbor)) {\n if (cbor.length === 0) {\n return \"[]\";\n }\n const items = cbor.map((item) => cborToDiagnostic(item, indent + 2));\n return `[${items.join(\", \")}]`;\n }\n\n // Handle Maps\n if (cbor instanceof Map) {\n if (cbor.size === 0) {\n return \"{}\";\n }\n const entries: string[] = [];\n for (const [key, value] of cbor) {\n const keyStr = cborToDiagnostic(key, indent + 2);\n const valueStr = cborToDiagnostic(value, indent + 2);\n entries.push(`${keyStr}: ${valueStr}`);\n }\n return `{${entries.join(\", \")}}`;\n }\n\n // Handle Uint8Array (byte strings)\n if (cbor instanceof Uint8Array) {\n const hex = Array.from(cbor)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n return `h'${hex}'`;\n }\n\n // Handle strings\n if (typeof cbor === \"string\") {\n return JSON.stringify(cbor);\n }\n\n // Handle CBOR objects with type information\n if (typeof cbor === \"object\" && cbor !== null && \"type\" in cbor) {\n const typed = cbor as { type: number; value: unknown };\n switch (typed.type) {\n case 0: // Unsigned\n return String(typed.value);\n case 1: // Negative\n return String(-1 - Number(typed.value));\n case 7: {\n // Simple\n const simpleValue = typed.value;\n if (simpleValue !== null && typeof simpleValue === \"object\" && \"type\" in simpleValue) {\n const floatValue = simpleValue as { type: string; value: unknown };\n if (floatValue.type === \"Float\") {\n return String(floatValue.value);\n }\n }\n if (simpleValue === 20) return \"false\";\n if (simpleValue === 21) return \"true\";\n if (simpleValue === 22) return \"null\";\n if (simpleValue === 23) return \"undefined\";\n return `simple(${String(simpleValue)})`;\n }\n }\n }\n\n // Fallback for primitives\n if (typeof cbor === \"boolean\") return String(cbor);\n if (typeof cbor === \"number\") return String(cbor);\n if (typeof cbor === \"bigint\") return String(cbor);\n if (cbor === null) return \"null\";\n if (cbor === undefined) return \"undefined\";\n\n // Unknown type - try JSON stringify\n try {\n return JSON.stringify(cbor);\n } catch {\n // eslint-disable-next-line @typescript-eslint/no-base-to-string\n return String(cbor);\n }\n}\n\n/// Implementation of diagnostic()\nEnvelope.prototype.diagnostic = function (this: Envelope): string {\n const cbor = this.taggedCbor();\n return cborToDiagnostic(cbor);\n};\n","import { Envelope } from \"../base/envelope\";\nimport { type EdgeType, edgeLabel } from \"../base/walk\";\n\n/// Tree formatting for Gordian Envelopes.\n///\n/// This module provides functionality for creating textual tree\n/// representations of envelopes, which is useful for debugging and visualizing\n/// the hierarchical structure of complex envelopes.\n///\n/// The tree format displays each component of an envelope (subject and\n/// assertions) as nodes in a tree, making it easy to understand the\n/// hierarchical structure of nested envelopes. Each node includes:\n///\n/// - The first 8 characters of the element's digest (for easy reference)\n/// - The type of the element (NODE, ASSERTION, ELIDED, etc.)\n/// - The content of the element (for leaf nodes)\n\n/// Options for tree formatting\nexport interface TreeFormatOptions {\n /// If true, hides NODE identifiers and only shows semantic content\n hideNodes?: boolean;\n /// Set of digest strings to highlight in the tree\n highlightDigests?: Set<string>;\n /// Format for displaying digests\n digestDisplay?: \"short\" | \"full\";\n}\n\n/// Represents an element in the tree representation\ninterface TreeElement {\n /// Indentation level\n level: number;\n /// The envelope element\n envelope: Envelope;\n /// Type of incoming edge\n incomingEdge: EdgeType;\n /// Whether to show the digest ID\n showId: boolean;\n /// Whether this element is highlighted\n isHighlighted: boolean;\n}\n\n// Note: Method declarations are in the base Envelope class.\n// This module provides the prototype implementations.\n\n/// Implementation of shortId()\nEnvelope.prototype.shortId = function (this: Envelope, format: \"short\" | \"full\" = \"short\"): string {\n const digest = this.digest();\n if (format === \"full\") {\n return digest.hex();\n }\n return digest.short();\n};\n\n/// Implementation of summary()\nEnvelope.prototype.summary = function (this: Envelope, maxLength = 40): string {\n const c = this.case();\n\n switch (c.type) {\n case \"node\":\n return \"NODE\";\n case \"leaf\": {\n // Try to extract a readable value\n try {\n const text = this.asText();\n if (text !== undefined) {\n const truncated = text.length > maxLength ? `${text.substring(0, maxLength)}...` : text;\n return JSON.stringify(truncated);\n }\n } catch {\n // Fall through\n }\n\n try {\n const num = this.extractNumber();\n return String(num);\n } catch {\n // Fall through\n }\n\n try {\n const bool = this.extractBoolean();\n return String(bool);\n } catch {\n // Fall through\n }\n\n if (this.isNull()) {\n return \"null\";\n }\n\n // Fallback: show byte string\n const bytes = this.asByteString();\n if (bytes !== undefined && bytes.length <= 16) {\n const hex = Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n return `h'${hex}'`;\n }\n\n return \"LEAF\";\n }\n case \"wrapped\":\n return \"WRAPPED\";\n case \"assertion\":\n return \"ASSERTION\";\n case \"elided\":\n return \"ELIDED\";\n case \"encrypted\":\n return \"ENCRYPTED\";\n case \"compressed\":\n return \"COMPRESSED\";\n case \"knownValue\":\n return \"KNOWN_VALUE\";\n default:\n return \"UNKNOWN\";\n }\n};\n\n/// Implementation of treeFormat()\nEnvelope.prototype.treeFormat = function (this: Envelope, options: TreeFormatOptions = {}): string {\n const hideNodes = options.hideNodes ?? false;\n const highlightDigests = options.highlightDigests ?? new Set<string>();\n const digestDisplay = options.digestDisplay ?? \"short\";\n\n const elements: TreeElement[] = [];\n\n // Walk the envelope and collect elements\n this.walk(hideNodes, undefined, (envelope, level, incomingEdge, _state) => {\n const digestStr = envelope.digest().short();\n const isHighlighted = highlightDigests.has(digestStr);\n\n elements.push({\n level,\n envelope,\n incomingEdge,\n showId: !hideNodes,\n isHighlighted,\n });\n\n return [undefined, false];\n });\n\n // Format each element as a line\n const lines = elements.map((elem) => {\n const parts: string[] = [];\n\n if (elem.isHighlighted) {\n parts.push(\"*\");\n }\n\n if (elem.showId) {\n parts.push(elem.envelope.shortId(digestDisplay));\n }\n\n const label = edgeLabel(elem.incomingEdge);\n if (label !== undefined && label !== \"\") {\n parts.push(label);\n }\n\n parts.push(elem.envelope.summary(40));\n\n const line = parts.join(\" \");\n const indent = \" \".repeat(elem.level * 4);\n return indent + line;\n });\n\n return lines.join(\"\\n\");\n};\n","/**\n * String utility functions used throughout the envelope library.\n *\n * Provides helper methods for string formatting and manipulation.\n */\n\n/**\n * Flanks a string with specified left and right delimiters.\n *\n * @param str - The string to flank\n * @param left - The left delimiter\n * @param right - The right delimiter\n * @returns The flanked string\n *\n * @example\n * ```typescript\n * flanked('hello', '\"', '\"') // Returns: \"hello\"\n * flanked('name', \"'\", \"'\") // Returns: 'name'\n * flanked('item', '[', ']') // Returns: [item]\n * ```\n */\nexport function flanked(str: string, left: string, right: string): string {\n return `${left}${str}${right}`;\n}\n\n/**\n * Extension methods for String objects to support fluent API style.\n */\ndeclare global {\n interface String {\n /**\n * Flanks this string with specified left and right delimiters.\n *\n * @param left - The left delimiter\n * @param right - The right delimiter\n * @returns The flanked string\n */\n flankedBy(left: string, right: string): string;\n }\n}\n\n// Extend String prototype with flankedBy method\nString.prototype.flankedBy = function (this: string, left: string, right: string): string {\n return flanked(this, left, right);\n};\n\n// Export the extension for side-effects\nexport {};\n","/// Gordian Envelope TypeScript Library\n///\n/// A TypeScript implementation of Blockchain Commons' Gordian Envelope\n/// specification for structured, privacy-focused data containers.\n///\n/// This is a 1:1 port of the Rust bc-envelope library, maintaining the same\n/// API structure and functionality.\n///\n/// @module bc-envelope\n\n// Re-export everything from the base module\nexport * from \"./base\";\n\n// Re-export everything from the extension module\nexport * from \"./extension\";\n\n// Import registration functions and call them to ensure proper initialization order\nimport { registerEncryptExtension } from \"./extension/encrypt\";\nimport { registerCompressExtension } from \"./extension/compress\";\nregisterEncryptExtension();\nregisterCompressExtension();\n\n// Re-export everything from the format module\n// Import for side effects (registers prototype extensions like treeFormat)\nimport \"./format\";\nexport type * from \"./format\";\n\n// Re-export everything from the utils module\nexport * from \"./utils\";\n\n// Version information\nexport const VERSION = \"0.37.0\";\n"],"mappings":"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"}
|