@bcts/uniform-resources 1.0.0-alpha.18 โ†’ 1.0.0-alpha.20

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 CHANGED
@@ -1,3 +1,4 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1
2
  let _bcts_dcbor = require("@bcts/dcbor");
2
3
  let _bcts_crypto = require("@bcts/crypto");
3
4
 
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["MajorType"],"sources":["../src/error.ts","../src/utils.ts","../src/ur-type.ts","../src/ur.ts","../src/ur-encodable.ts","../src/ur-decodable.ts","../src/ur-codable.ts","../src/xoshiro.ts","../src/fountain.ts","../src/multipart-encoder.ts","../src/multipart-decoder.ts"],"sourcesContent":["/**\n * Error type for UR encoding/decoding operations.\n */\nexport class URError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"URError\";\n }\n}\n\n/**\n * Error type for invalid UR schemes.\n */\nexport class InvalidSchemeError extends URError {\n constructor() {\n super(\"Invalid UR scheme\");\n this.name = \"InvalidSchemeError\";\n }\n}\n\n/**\n * Error type for unspecified UR types.\n */\nexport class TypeUnspecifiedError extends URError {\n constructor() {\n super(\"No UR type specified\");\n this.name = \"TypeUnspecifiedError\";\n }\n}\n\n/**\n * Error type for invalid UR types.\n */\nexport class InvalidTypeError extends URError {\n constructor() {\n super(\"Invalid UR type\");\n this.name = \"InvalidTypeError\";\n }\n}\n\n/**\n * Error type for non-single-part URs.\n */\nexport class NotSinglePartError extends URError {\n constructor() {\n super(\"UR is not a single-part\");\n this.name = \"NotSinglePartError\";\n }\n}\n\n/**\n * Error type for unexpected UR types.\n */\nexport class UnexpectedTypeError extends URError {\n constructor(expected: string, found: string) {\n super(`Expected UR type ${expected}, but found ${found}`);\n this.name = \"UnexpectedTypeError\";\n }\n}\n\n/**\n * Error type for Bytewords encoding/decoding errors.\n */\nexport class BytewordsError extends URError {\n constructor(message: string) {\n super(`Bytewords error: ${message}`);\n this.name = \"BytewordsError\";\n }\n}\n\n/**\n * Error type for CBOR encoding/decoding errors.\n */\nexport class CBORError extends URError {\n constructor(message: string) {\n super(`CBOR error: ${message}`);\n this.name = \"CBORError\";\n }\n}\n\n/**\n * Error type for UR decoder errors.\n * Matches Rust's Error::UR(String) variant.\n */\nexport class URDecodeError extends URError {\n constructor(message: string) {\n super(`UR decoder error (${message})`);\n this.name = \"URDecodeError\";\n }\n}\n\nexport type Result<T> = T | Error;\n\n/**\n * Helper function to check if a result is an error.\n */\nexport function isError(result: unknown): result is Error {\n return result instanceof Error;\n}\n","import { InvalidTypeError } from \"./error.js\";\n\n/**\n * Checks if a character is a valid UR type character.\n * Valid characters are lowercase letters, digits, and hyphens.\n */\nexport function isURTypeChar(char: string): boolean {\n const code = char.charCodeAt(0);\n // Check for lowercase letters (a-z)\n if (code >= 97 && code <= 122) return true;\n // Check for digits (0-9)\n if (code >= 48 && code <= 57) return true;\n // Check for hyphen (-)\n if (code === 45) return true;\n return false;\n}\n\n/**\n * Checks if a string is a valid UR type.\n * Valid UR types contain only lowercase letters, digits, and hyphens.\n */\nexport function isValidURType(urType: string): boolean {\n if (urType.length === 0) return false;\n return Array.from(urType).every((char) => isURTypeChar(char));\n}\n\n/**\n * Validates and returns a UR type, or throws an error if invalid.\n */\nexport function validateURType(urType: string): string {\n if (!isValidURType(urType)) {\n throw new InvalidTypeError();\n }\n return urType;\n}\n\n/**\n * Bytewords for encoding/decoding bytes as words.\n * See: https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-004-bytewords.md\n */\nexport const BYTEWORDS: string[] = [\n \"able\",\n \"acid\",\n \"also\",\n \"apex\",\n \"aqua\",\n \"arch\",\n \"atom\",\n \"aunt\",\n \"away\",\n \"axis\",\n \"back\",\n \"bald\",\n \"barn\",\n \"belt\",\n \"beta\",\n \"bias\",\n \"blue\",\n \"body\",\n \"brag\",\n \"brew\",\n \"bulb\",\n \"buzz\",\n \"calm\",\n \"cash\",\n \"cats\",\n \"chef\",\n \"city\",\n \"claw\",\n \"code\",\n \"cola\",\n \"cook\",\n \"cost\",\n \"crux\",\n \"curl\",\n \"cusp\",\n \"cyan\",\n \"dark\",\n \"data\",\n \"days\",\n \"deli\",\n \"dice\",\n \"diet\",\n \"door\",\n \"down\",\n \"draw\",\n \"drop\",\n \"drum\",\n \"dull\",\n \"duty\",\n \"each\",\n \"easy\",\n \"echo\",\n \"edge\",\n \"epic\",\n \"even\",\n \"exam\",\n \"exit\",\n \"eyes\",\n \"fact\",\n \"fair\",\n \"fern\",\n \"figs\",\n \"film\",\n \"fish\",\n \"fizz\",\n \"flap\",\n \"flew\",\n \"flux\",\n \"foxy\",\n \"free\",\n \"frog\",\n \"fuel\",\n \"fund\",\n \"gala\",\n \"game\",\n \"gear\",\n \"gems\",\n \"gift\",\n \"girl\",\n \"glow\",\n \"good\",\n \"gray\",\n \"grim\",\n \"guru\",\n \"gush\",\n \"gyro\",\n \"half\",\n \"hang\",\n \"hard\",\n \"hawk\",\n \"heat\",\n \"help\",\n \"high\",\n \"hill\",\n \"holy\",\n \"hope\",\n \"horn\",\n \"huts\",\n \"iced\",\n \"idea\",\n \"idle\",\n \"inch\",\n \"inky\",\n \"into\",\n \"iris\",\n \"iron\",\n \"item\",\n \"jade\",\n \"jazz\",\n \"join\",\n \"jolt\",\n \"jowl\",\n \"judo\",\n \"jugs\",\n \"jump\",\n \"junk\",\n \"jury\",\n \"keep\",\n \"keno\",\n \"kept\",\n \"keys\",\n \"kick\",\n \"kiln\",\n \"king\",\n \"kite\",\n \"kiwi\",\n \"knob\",\n \"lamb\",\n \"lava\",\n \"lazy\",\n \"leaf\",\n \"legs\",\n \"liar\",\n \"limp\",\n \"lion\",\n \"list\",\n \"logo\",\n \"loud\",\n \"love\",\n \"luau\",\n \"luck\",\n \"lung\",\n \"main\",\n \"many\",\n \"math\",\n \"maze\",\n \"memo\",\n \"menu\",\n \"meow\",\n \"mild\",\n \"mint\",\n \"miss\",\n \"monk\",\n \"nail\",\n \"navy\",\n \"need\",\n \"news\",\n \"next\",\n \"noon\",\n \"note\",\n \"numb\",\n \"obey\",\n \"oboe\",\n \"omit\",\n \"onyx\",\n \"open\",\n \"oval\",\n \"owls\",\n \"paid\",\n \"part\",\n \"peck\",\n \"play\",\n \"plus\",\n \"poem\",\n \"pool\",\n \"pose\",\n \"puff\",\n \"puma\",\n \"purr\",\n \"quad\",\n \"quiz\",\n \"race\",\n \"ramp\",\n \"real\",\n \"redo\",\n \"rich\",\n \"road\",\n \"rock\",\n \"roof\",\n \"ruby\",\n \"ruin\",\n \"runs\",\n \"rust\",\n \"safe\",\n \"saga\",\n \"scar\",\n \"sets\",\n \"silk\",\n \"skew\",\n \"slot\",\n \"soap\",\n \"solo\",\n \"song\",\n \"stub\",\n \"surf\",\n \"swan\",\n \"taco\",\n \"task\",\n \"taxi\",\n \"tent\",\n \"tied\",\n \"time\",\n \"tiny\",\n \"toil\",\n \"tomb\",\n \"toys\",\n \"trip\",\n \"tuna\",\n \"twin\",\n \"ugly\",\n \"undo\",\n \"unit\",\n \"urge\",\n \"user\",\n \"vast\",\n \"very\",\n \"veto\",\n \"vial\",\n \"vibe\",\n \"view\",\n \"visa\",\n \"void\",\n \"vows\",\n \"wall\",\n \"wand\",\n \"warm\",\n \"wasp\",\n \"wave\",\n \"waxy\",\n \"webs\",\n \"what\",\n \"when\",\n \"whiz\",\n \"wolf\",\n \"work\",\n \"yank\",\n \"yawn\",\n \"yell\",\n \"yoga\",\n \"yurt\",\n \"zaps\",\n \"zero\",\n \"zest\",\n \"zinc\",\n \"zone\",\n \"zoom\",\n];\n\n/**\n * Create a reverse mapping for fast byteword lookup.\n */\nfunction createBytewordsMap(): Map<string, number> {\n const map = new Map<string, number>();\n BYTEWORDS.forEach((word, index) => {\n map.set(word, index);\n });\n return map;\n}\n\nexport const BYTEWORDS_MAP = createBytewordsMap();\n\n/**\n * Bytemojis for encoding/decoding bytes as emojis.\n * See: https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2024-008-bytemoji.md\n */\nexport const BYTEMOJIS: string[] = [\n \"๐Ÿ˜€\",\n \"๐Ÿ˜‚\",\n \"๐Ÿ˜†\",\n \"๐Ÿ˜‰\",\n \"๐Ÿ™„\",\n \"๐Ÿ˜‹\",\n \"๐Ÿ˜Ž\",\n \"๐Ÿ˜\",\n \"๐Ÿ˜˜\",\n \"๐Ÿ˜ญ\",\n \"๐Ÿซ \",\n \"๐Ÿฅฑ\",\n \"๐Ÿคฉ\",\n \"๐Ÿ˜ถ\",\n \"๐Ÿคจ\",\n \"๐Ÿซฅ\",\n \"๐Ÿฅต\",\n \"๐Ÿฅถ\",\n \"๐Ÿ˜ณ\",\n \"๐Ÿคช\",\n \"๐Ÿ˜ต\",\n \"๐Ÿ˜ก\",\n \"๐Ÿคข\",\n \"๐Ÿ˜‡\",\n \"๐Ÿค \",\n \"๐Ÿคก\",\n \"๐Ÿฅณ\",\n \"๐Ÿฅบ\",\n \"๐Ÿ˜ฌ\",\n \"๐Ÿค‘\",\n \"๐Ÿ™ƒ\",\n \"๐Ÿคฏ\",\n \"๐Ÿ˜ˆ\",\n \"๐Ÿ‘น\",\n \"๐Ÿ‘บ\",\n \"๐Ÿ’€\",\n \"๐Ÿ‘ป\",\n \"๐Ÿ‘ฝ\",\n \"๐Ÿ˜บ\",\n \"๐Ÿ˜น\",\n \"๐Ÿ˜ป\",\n \"๐Ÿ˜ฝ\",\n \"๐Ÿ™€\",\n \"๐Ÿ˜ฟ\",\n \"๐Ÿซถ\",\n \"๐Ÿคฒ\",\n \"๐Ÿ™Œ\",\n \"๐Ÿค\",\n \"๐Ÿ‘\",\n \"๐Ÿ‘Ž\",\n \"๐Ÿ‘ˆ\",\n \"๐Ÿ‘†\",\n \"๐Ÿ’ช\",\n \"๐Ÿ‘„\",\n \"๐Ÿฆท\",\n \"๐Ÿ‘‚\",\n \"๐Ÿ‘ƒ\",\n \"๐Ÿง \",\n \"๐Ÿ‘€\",\n \"๐Ÿคš\",\n \"๐Ÿฆถ\",\n \"๐ŸŽ\",\n \"๐ŸŠ\",\n \"๐Ÿ‹\",\n \"๐ŸŒ\",\n \"๐Ÿ‰\",\n \"๐Ÿ‡\",\n \"๐Ÿ“\",\n \"๐Ÿซ\",\n \"๐Ÿ’\",\n \"๐Ÿ‘\",\n \"๐Ÿ\",\n \"๐Ÿฅ\",\n \"๐Ÿ†\",\n \"๐Ÿฅ‘\",\n \"๐Ÿฅฆ\",\n \"๐Ÿ…\",\n \"๐ŸŒฝ\",\n \"๐Ÿฅ•\",\n \"๐Ÿซ’\",\n \"๐Ÿง„\",\n \"๐Ÿฅ\",\n \"๐Ÿฅฏ\",\n \"๐Ÿž\",\n \"๐Ÿง€\",\n \"๐Ÿฅš\",\n \"๐Ÿ—\",\n \"๐ŸŒญ\",\n \"๐Ÿ”\",\n \"๐ŸŸ\",\n \"๐Ÿ•\",\n \"๐ŸŒฎ\",\n \"๐Ÿฅ™\",\n \"๐Ÿฑ\",\n \"๐Ÿœ\",\n \"๐Ÿค\",\n \"๐Ÿš\",\n \"๐Ÿฅ \",\n \"๐Ÿจ\",\n \"๐Ÿฆ\",\n \"๐ŸŽ‚\",\n \"๐Ÿชด\",\n \"๐ŸŒต\",\n \"๐ŸŒฑ\",\n \"๐Ÿ’\",\n \"๐Ÿ\",\n \"๐Ÿ„\",\n \"๐ŸŒน\",\n \"๐ŸŒบ\",\n \"๐ŸŒผ\",\n \"๐ŸŒป\",\n \"๐ŸŒธ\",\n \"๐Ÿ’จ\",\n \"๐ŸŒŠ\",\n \"๐Ÿ’ง\",\n \"๐Ÿ’ฆ\",\n \"๐ŸŒ€\",\n \"๐ŸŒˆ\",\n \"๐ŸŒž\",\n \"๐ŸŒ\",\n \"๐ŸŒ›\",\n \"๐ŸŒœ\",\n \"๐ŸŒ™\",\n \"๐ŸŒŽ\",\n \"๐Ÿ’ซ\",\n \"โญ\",\n \"๐Ÿช\",\n \"๐ŸŒ\",\n \"๐Ÿ’›\",\n \"๐Ÿ’”\",\n \"๐Ÿ’˜\",\n \"๐Ÿ’–\",\n \"๐Ÿ’•\",\n \"๐Ÿ\",\n \"๐Ÿšฉ\",\n \"๐Ÿ’ฌ\",\n \"๐Ÿ’ฏ\",\n \"๐Ÿšซ\",\n \"๐Ÿ”ด\",\n \"๐Ÿ”ท\",\n \"๐ŸŸฉ\",\n \"๐Ÿ›‘\",\n \"๐Ÿ”บ\",\n \"๐Ÿš—\",\n \"๐Ÿš‘\",\n \"๐Ÿš’\",\n \"๐Ÿšœ\",\n \"๐Ÿ›ต\",\n \"๐Ÿšจ\",\n \"๐Ÿš€\",\n \"๐Ÿš\",\n \"๐Ÿ›Ÿ\",\n \"๐Ÿšฆ\",\n \"๐Ÿฐ\",\n \"๐ŸŽก\",\n \"๐ŸŽข\",\n \"๐ŸŽ \",\n \"๐Ÿ \",\n \"๐Ÿ””\",\n \"๐Ÿ”‘\",\n \"๐Ÿšช\",\n \"๐Ÿช‘\",\n \"๐ŸŽˆ\",\n \"๐Ÿ’Œ\",\n \"๐Ÿ“ฆ\",\n \"๐Ÿ“ซ\",\n \"๐Ÿ“–\",\n \"๐Ÿ“š\",\n \"๐Ÿ“Œ\",\n \"๐Ÿงฎ\",\n \"๐Ÿ”’\",\n \"๐Ÿ’Ž\",\n \"๐Ÿ“ท\",\n \"โฐ\",\n \"โณ\",\n \"๐Ÿ“ก\",\n \"๐Ÿ’ก\",\n \"๐Ÿ’ฐ\",\n \"๐Ÿงฒ\",\n \"๐Ÿงธ\",\n \"๐ŸŽ\",\n \"๐ŸŽ€\",\n \"๐ŸŽ‰\",\n \"๐Ÿชญ\",\n \"๐Ÿ‘‘\",\n \"๐Ÿซ–\",\n \"๐Ÿ”ญ\",\n \"๐Ÿ›\",\n \"๐Ÿ†\",\n \"๐Ÿฅ\",\n \"๐ŸŽท\",\n \"๐ŸŽบ\",\n \"๐Ÿ€\",\n \"๐Ÿˆ\",\n \"๐ŸŽพ\",\n \"๐Ÿ“\",\n \"โœจ\",\n \"๐Ÿ”ฅ\",\n \"๐Ÿ’ฅ\",\n \"๐Ÿ‘•\",\n \"๐Ÿ‘š\",\n \"๐Ÿ‘–\",\n \"๐Ÿฉณ\",\n \"๐Ÿ‘—\",\n \"๐Ÿ‘”\",\n \"๐Ÿงข\",\n \"๐Ÿ‘“\",\n \"๐Ÿงถ\",\n \"๐Ÿงต\",\n \"๐Ÿ’\",\n \"๐Ÿ‘ \",\n \"๐Ÿ‘Ÿ\",\n \"๐Ÿงฆ\",\n \"๐Ÿงค\",\n \"๐Ÿ‘’\",\n \"๐Ÿ‘œ\",\n \"๐Ÿฑ\",\n \"๐Ÿถ\",\n \"๐Ÿญ\",\n \"๐Ÿน\",\n \"๐Ÿฐ\",\n \"๐ŸฆŠ\",\n \"๐Ÿป\",\n \"๐Ÿผ\",\n \"๐Ÿจ\",\n \"๐Ÿฏ\",\n \"๐Ÿฆ\",\n \"๐Ÿฎ\",\n \"๐Ÿท\",\n \"๐Ÿธ\",\n \"๐Ÿต\",\n \"๐Ÿ”\",\n \"๐Ÿฅ\",\n \"๐Ÿฆ†\",\n \"๐Ÿฆ‰\",\n \"๐Ÿด\",\n \"๐Ÿฆ„\",\n \"๐Ÿ\",\n \"๐Ÿ›\",\n \"๐Ÿฆ‹\",\n \"๐ŸŒ\",\n \"๐Ÿž\",\n \"๐Ÿข\",\n \"๐Ÿบ\",\n \"๐Ÿ\",\n \"๐Ÿชฝ\",\n \"๐Ÿ™\",\n \"๐Ÿฆ‘\",\n \"๐Ÿชผ\",\n \"๐Ÿฆž\",\n \"๐Ÿฆ€\",\n \"๐Ÿš\",\n \"๐Ÿฆญ\",\n \"๐ŸŸ\",\n \"๐Ÿฌ\",\n \"๐Ÿณ\",\n];\n\n/**\n * Encodes a 4-byte slice as a string of bytewords for identification.\n */\nexport function encodeBytewordsIdentifier(data: Uint8Array): string {\n if (data.length !== 4) {\n throw new Error(\"Identifier data must be exactly 4 bytes\");\n }\n const words: string[] = [];\n for (let i = 0; i < 4; i++) {\n const byte = data[i];\n if (byte === undefined) throw new Error(\"Invalid byte\");\n const word = BYTEWORDS[byte];\n if (word === \"\" || word === undefined) throw new Error(\"Invalid byteword mapping\");\n words.push(word);\n }\n return words.join(\" \");\n}\n\n/**\n * Encodes a 4-byte slice as a string of bytemojis for identification.\n */\nexport function encodeBytemojisIdentifier(data: Uint8Array): string {\n if (data.length !== 4) {\n throw new Error(\"Identifier data must be exactly 4 bytes\");\n }\n const emojis: string[] = [];\n for (let i = 0; i < 4; i++) {\n const byte = data[i];\n if (byte === undefined) throw new Error(\"Invalid byte\");\n const emoji = BYTEMOJIS[byte];\n if (emoji === \"\" || emoji === undefined) throw new Error(\"Invalid bytemoji mapping\");\n emojis.push(emoji);\n }\n return emojis.join(\" \");\n}\n\n/**\n * Bytewords encoding style.\n */\nexport enum BytewordsStyle {\n /** Full 4-letter words separated by spaces */\n Standard = \"standard\",\n /** Full 4-letter words separated by hyphens (URI-safe) */\n Uri = \"uri\",\n /** First and last character only (minimal) - used by UR encoding */\n Minimal = \"minimal\",\n}\n\n/**\n * Create a reverse mapping for minimal bytewords (first+last char) lookup.\n */\nfunction createMinimalBytewordsMap(): Map<string, number> {\n const map = new Map<string, number>();\n BYTEWORDS.forEach((word, index) => {\n // Minimal encoding uses first and last character\n const minimal = word[0] + word[3];\n map.set(minimal, index);\n });\n return map;\n}\n\nexport const MINIMAL_BYTEWORDS_MAP = createMinimalBytewordsMap();\n\n/**\n * CRC32 lookup table (IEEE polynomial).\n */\nconst CRC32_TABLE: number[] = (() => {\n const table: number[] = [];\n for (let i = 0; i < 256; i++) {\n let c = i;\n for (let j = 0; j < 8; j++) {\n c = (c & 1) !== 0 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;\n }\n table.push(c >>> 0);\n }\n return table;\n})();\n\n/**\n * Calculate CRC32 checksum of data.\n */\nexport function crc32(data: Uint8Array): number {\n let crc = 0xffffffff;\n for (const byte of data) {\n crc = (CRC32_TABLE[(crc ^ byte) & 0xff] ^ (crc >>> 8)) >>> 0;\n }\n return (crc ^ 0xffffffff) >>> 0;\n}\n\n/**\n * Convert a 32-bit number to 4 bytes (big-endian).\n */\nfunction uint32ToBytes(value: number): Uint8Array {\n return new Uint8Array([\n (value >>> 24) & 0xff,\n (value >>> 16) & 0xff,\n (value >>> 8) & 0xff,\n value & 0xff,\n ]);\n}\n\n/**\n * Encode data as bytewords with the specified style.\n * Includes CRC32 checksum.\n */\nexport function encodeBytewords(\n data: Uint8Array,\n style: BytewordsStyle = BytewordsStyle.Minimal,\n): string {\n // Append CRC32 checksum\n const checksum = crc32(data);\n const checksumBytes = uint32ToBytes(checksum);\n const dataWithChecksum = new Uint8Array(data.length + 4);\n dataWithChecksum.set(data);\n dataWithChecksum.set(checksumBytes, data.length);\n\n const words: string[] = [];\n for (const byte of dataWithChecksum) {\n const word = BYTEWORDS[byte];\n if (word === undefined) throw new Error(`Invalid byte value: ${byte}`);\n\n switch (style) {\n case BytewordsStyle.Standard:\n words.push(word);\n break;\n case BytewordsStyle.Uri:\n words.push(word);\n break;\n case BytewordsStyle.Minimal:\n // First and last character\n words.push(word[0] + word[3]);\n break;\n }\n }\n\n switch (style) {\n case BytewordsStyle.Standard:\n return words.join(\" \");\n case BytewordsStyle.Uri:\n return words.join(\"-\");\n case BytewordsStyle.Minimal:\n return words.join(\"\");\n }\n}\n\n/**\n * Decode bytewords string back to data.\n * Validates and removes CRC32 checksum.\n */\nexport function decodeBytewords(\n encoded: string,\n style: BytewordsStyle = BytewordsStyle.Minimal,\n): Uint8Array {\n const lowercased = encoded.toLowerCase();\n let bytes: number[];\n\n switch (style) {\n case BytewordsStyle.Standard: {\n const words = lowercased.split(\" \");\n bytes = words.map((word) => {\n const index = BYTEWORDS_MAP.get(word);\n if (index === undefined) {\n throw new Error(`Invalid byteword: ${word}`);\n }\n return index;\n });\n break;\n }\n case BytewordsStyle.Uri: {\n // 4-character words separated by hyphens\n const words = lowercased.split(\"-\");\n bytes = words.map((word) => {\n const index = BYTEWORDS_MAP.get(word);\n if (index === undefined) {\n throw new Error(`Invalid byteword: ${word}`);\n }\n return index;\n });\n break;\n }\n case BytewordsStyle.Minimal: {\n // 2-character minimal words with no separator\n if (lowercased.length % 2 !== 0) {\n throw new Error(\"Invalid minimal bytewords length\");\n }\n bytes = [];\n for (let i = 0; i < lowercased.length; i += 2) {\n const minimal = lowercased.slice(i, i + 2);\n const index = MINIMAL_BYTEWORDS_MAP.get(minimal);\n if (index === undefined) {\n throw new Error(`Invalid minimal byteword: ${minimal}`);\n }\n bytes.push(index);\n }\n break;\n }\n }\n\n if (bytes.length < 4) {\n throw new Error(\"Bytewords data too short (missing checksum)\");\n }\n\n // Extract data and checksum\n const dataWithChecksum = new Uint8Array(bytes);\n const data = dataWithChecksum.slice(0, -4);\n const checksumBytes = dataWithChecksum.slice(-4);\n\n // Verify checksum\n const expectedChecksum = crc32(data);\n const actualChecksum =\n ((checksumBytes[0] << 24) |\n (checksumBytes[1] << 16) |\n (checksumBytes[2] << 8) |\n checksumBytes[3]) >>>\n 0;\n\n if (expectedChecksum !== actualChecksum) {\n throw new Error(\n `Bytewords checksum mismatch: expected ${expectedChecksum.toString(16)}, got ${actualChecksum.toString(16)}`,\n );\n }\n\n return data;\n}\n","import { InvalidTypeError } from \"./error\";\nimport { isValidURType } from \"./utils\";\n\n/**\n * Represents a UR (Uniform Resource) type identifier.\n *\n * Valid UR types contain only lowercase letters, digits, and hyphens.\n *\n * @example\n * ```typescript\n * const urType = new URType('test');\n * console.log(urType.string()); // \"test\"\n * ```\n */\nexport class URType {\n private readonly _type: string;\n\n /**\n * Creates a new URType from the provided type string.\n *\n * @param urType - The UR type as a string\n * @throws {InvalidTypeError} If the type contains invalid characters\n *\n * @example\n * ```typescript\n * const urType = new URType('test');\n * ```\n */\n constructor(urType: string) {\n if (!isValidURType(urType)) {\n throw new InvalidTypeError();\n }\n this._type = urType;\n }\n\n /**\n * Returns the string representation of the URType.\n *\n * @example\n * ```typescript\n * const urType = new URType('test');\n * console.log(urType.string()); // \"test\"\n * ```\n */\n string(): string {\n return this._type;\n }\n\n /**\n * Checks equality with another URType based on the type string.\n */\n equals(other: URType): boolean {\n return this._type === other._type;\n }\n\n /**\n * Returns the string representation.\n */\n toString(): string {\n return this._type;\n }\n\n /**\n * Creates a URType from a string, throwing an error if invalid.\n *\n * @param value - The UR type string\n * @returns A new URType instance\n * @throws {InvalidTypeError} If the type is invalid\n */\n static from(value: string): URType {\n return new URType(value);\n }\n\n /**\n * Safely creates a URType, returning an error if invalid.\n *\n * @param value - The UR type string\n * @returns Either a URType or an error\n */\n static tryFrom(value: string): URType | InvalidTypeError {\n try {\n return new URType(value);\n } catch (error) {\n return error as InvalidTypeError;\n }\n }\n}\n","import type { Cbor } from \"@bcts/dcbor\";\nimport { decodeCbor } from \"@bcts/dcbor\";\nimport { InvalidSchemeError, TypeUnspecifiedError, UnexpectedTypeError, URError } from \"./error.js\";\nimport { URType } from \"./ur-type.js\";\nimport { encodeBytewords, decodeBytewords, BytewordsStyle } from \"./utils.js\";\n\n/**\n * A Uniform Resource (UR) is a URI-encoded CBOR object.\n *\n * URs are defined in [BCR-2020-005: Uniform Resources](https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-005-ur.md).\n *\n * @example\n * ```typescript\n * import { UR } from '@bcts/uniform-resources';\n * import { CBOR } from '@bcts/dcbor';\n *\n * // Create a UR from a CBOR object\n * const cbor = CBOR.fromArray([1, 2, 3]);\n * const ur = UR.new('test', cbor);\n *\n * // Encode to string\n * const urString = ur.string();\n * console.log(urString); // \"ur:test/...\"\n *\n * // Decode from string\n * const decodedUR = UR.fromURString(urString);\n * console.log(decodedUR.urTypeStr()); // \"test\"\n * ```\n */\nexport class UR {\n private readonly _urType: URType;\n private readonly _cbor: Cbor;\n\n /**\n * Creates a new UR from the provided type and CBOR data.\n *\n * @param urType - The UR type (will be validated)\n * @param cbor - The CBOR data to encode\n * @throws {InvalidTypeError} If the type is invalid\n *\n * @example\n * ```typescript\n * const ur = UR.new('bytes', CBOR.fromString('hello'));\n * ```\n */\n static new(urType: string | URType, cbor: Cbor): UR {\n const type = typeof urType === \"string\" ? new URType(urType) : urType;\n return new UR(type, cbor);\n }\n\n /**\n * Creates a new UR from a UR string.\n *\n * @param urString - A UR string like \"ur:test/...\"\n * @throws {InvalidSchemeError} If the string doesn't start with \"ur:\"\n * @throws {TypeUnspecifiedError} If no type is specified\n * @throws {NotSinglePartError} If the UR is multi-part\n * @throws {URError} If decoding fails\n *\n * @example\n * ```typescript\n * const ur = UR.fromURString('ur:test/lsadaoaxjygonesw');\n * ```\n */\n static fromURString(urString: string): UR {\n // Decode the UR string to get the type and CBOR data\n const decodedUR = URStringDecoder.decode(urString);\n if (decodedUR === null || decodedUR === undefined) {\n throw new URError(\"Failed to decode UR string\");\n }\n const { urType, cbor } = decodedUR;\n return new UR(new URType(urType), cbor);\n }\n\n private constructor(urType: URType, cbor: Cbor) {\n this._urType = urType;\n this._cbor = cbor;\n }\n\n /**\n * Returns the UR type.\n */\n urType(): URType {\n return this._urType;\n }\n\n /**\n * Returns the UR type as a string.\n */\n urTypeStr(): string {\n return this._urType.string();\n }\n\n /**\n * Returns the CBOR data.\n */\n cbor(): Cbor {\n return this._cbor;\n }\n\n /**\n * Returns the string representation of the UR (lowercase, suitable for display).\n *\n * @example\n * ```typescript\n * const ur = UR.new('test', CBOR.fromArray([1, 2, 3]));\n * console.log(ur.string()); // \"ur:test/lsadaoaxjygonesw\"\n * ```\n */\n string(): string {\n const cborData = this._cbor.toData();\n return URStringEncoder.encode(this._urType.string(), cborData);\n }\n\n /**\n * Returns the QR string representation (uppercase, most efficient for QR codes).\n */\n qrString(): string {\n return this.string().toUpperCase();\n }\n\n /**\n * Returns the QR data as bytes (uppercase UR string as UTF-8).\n */\n qrData(): Uint8Array {\n // Use a helper to convert string to bytes across platforms\n const str = this.qrString();\n const bytes = new Uint8Array(str.length);\n for (let i = 0; i < str.length; i++) {\n bytes[i] = str.charCodeAt(i);\n }\n return bytes;\n }\n\n /**\n * Checks if the UR type matches the expected type.\n *\n * @param expectedType - The expected type\n * @throws {UnexpectedTypeError} If the types don't match\n */\n checkType(expectedType: string | URType): void {\n const expected = typeof expectedType === \"string\" ? new URType(expectedType) : expectedType;\n if (!this._urType.equals(expected)) {\n throw new UnexpectedTypeError(expected.string(), this._urType.string());\n }\n }\n\n /**\n * Returns the string representation.\n */\n toString(): string {\n return this.string();\n }\n\n /**\n * Checks equality with another UR.\n */\n equals(other: UR): boolean {\n return (\n this._urType.equals(other._urType) &&\n this._cbor.toData().toString() === other._cbor.toData().toString()\n );\n }\n}\n\n/**\n * Encodes a UR string using Bytewords minimal encoding.\n * This handles single-part URs according to BCR-2020-005.\n */\nclass URStringEncoder {\n static encode(urType: string, cborData: Uint8Array): string {\n // Encode CBOR data using bytewords minimal style (with CRC32 checksum)\n const encoded = encodeBytewords(cborData, BytewordsStyle.Minimal);\n return `ur:${urType}/${encoded}`;\n }\n}\n\n/**\n * Decodes a UR string back to its components.\n */\nclass URStringDecoder {\n static decode(urString: string): { urType: string; cbor: Cbor } | null {\n const lowercased = urString.toLowerCase();\n\n // Check scheme\n if (!lowercased.startsWith(\"ur:\")) {\n throw new InvalidSchemeError();\n }\n\n // Strip scheme\n const afterScheme = lowercased.substring(3);\n\n // Split into type and data\n const [urType, ...dataParts] = afterScheme.split(\"/\");\n\n if (urType === \"\" || urType === undefined) {\n throw new TypeUnspecifiedError();\n }\n\n const data = dataParts.join(\"/\");\n if (data === \"\" || data === undefined) {\n throw new TypeUnspecifiedError();\n }\n\n try {\n // Decode the bytewords-encoded data (validates CRC32 checksum)\n const cborData = decodeBytewords(data, BytewordsStyle.Minimal);\n const cbor = decodeCbor(cborData);\n return { urType, cbor };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new URError(`Failed to decode UR: ${errorMessage}`);\n }\n }\n}\n","import type { UR } from \"./ur.js\";\n\n/**\n * A type that can be encoded to a UR (Uniform Resource).\n *\n * Types implementing this interface should be able to convert themselves\n * to CBOR data and associate that with a UR type identifier.\n *\n * @example\n * ```typescript\n * class MyType implements UREncodable {\n * toCBOR(): CBOR {\n * // Convert to CBOR\n * }\n *\n * ur(): UR {\n * const cbor = this.toCBOR();\n * return UR.new('mytype', cbor);\n * }\n * }\n * ```\n */\nexport interface UREncodable {\n /**\n * Returns the UR representation of the object.\n */\n ur(): UR;\n\n /**\n * Returns the UR string representation of the object.\n */\n urString(): string;\n}\n\n/**\n * Helper function to check if an object implements UREncodable.\n */\nexport function isUREncodable(obj: unknown): obj is UREncodable {\n return (\n typeof obj === \"object\" &&\n obj !== null &&\n \"ur\" in obj &&\n \"urString\" in obj &&\n typeof (obj as Record<string, unknown>)[\"ur\"] === \"function\" &&\n typeof (obj as Record<string, unknown>)[\"urString\"] === \"function\"\n );\n}\n","import type { UR } from \"./ur.js\";\n\n/**\n * A type that can be decoded from a UR (Uniform Resource).\n *\n * Types implementing this interface should be able to create themselves\n * from a UR containing their data.\n *\n * @example\n * ```typescript\n * class MyType implements URDecodable {\n * fromUR(ur: UR): MyType {\n * const cbor = ur.cbor();\n * // Decode from CBOR and return MyType instance\n * }\n *\n * fromURString(urString: string): MyType {\n * return this.fromUR(UR.fromURString(urString));\n * }\n * }\n * ```\n */\nexport interface URDecodable {\n /**\n * Creates an instance of this type from a UR.\n *\n * @param ur - The UR to decode from\n * @returns An instance of this type\n * @throws If the UR type is wrong or data is malformed\n */\n fromUR(ur: UR): unknown;\n\n /**\n * Creates an instance of this type from a UR string.\n *\n * This is a convenience method that parses the UR string and then\n * calls fromUR().\n *\n * @param urString - The UR string to decode from (e.g., \"ur:type/...\")\n * @returns An instance of this type\n * @throws If the UR string is invalid or data is malformed\n */\n fromURString?(urString: string): unknown;\n}\n\n/**\n * Helper function to check if an object implements URDecodable.\n */\nexport function isURDecodable(obj: unknown): obj is URDecodable {\n return (\n typeof obj === \"object\" &&\n obj !== null &&\n \"fromUR\" in obj &&\n typeof (obj as Record<string, unknown>)[\"fromUR\"] === \"function\"\n );\n}\n","import type { UREncodable } from \"./ur-encodable.js\";\nimport type { URDecodable } from \"./ur-decodable.js\";\n\n/**\n * A type that can be both encoded to and decoded from a UR.\n *\n * This combines the UREncodable and URDecodable interfaces for types\n * that support bidirectional UR conversion.\n *\n * @example\n * ```typescript\n * class MyType implements URCodable {\n * ur(): UR {\n * // Encode to UR\n * }\n *\n * urString(): string {\n * // Return UR string\n * }\n *\n * fromUR(ur: UR): MyType {\n * // Decode from UR\n * }\n *\n * fromURString(urString: string): MyType {\n * // Decode from UR string (convenience method)\n * return this.fromUR(UR.fromURString(urString));\n * }\n * }\n * ```\n */\nexport interface URCodable extends UREncodable, URDecodable {}\n\n/**\n * Helper function to check if an object implements URCodable.\n */\nexport function isURCodable(obj: unknown): obj is URCodable {\n return (\n typeof obj === \"object\" &&\n obj !== null &&\n \"ur\" in obj &&\n \"urString\" in obj &&\n \"fromUR\" in obj &&\n typeof (obj as Record<string, unknown>)[\"ur\"] === \"function\" &&\n typeof (obj as Record<string, unknown>)[\"urString\"] === \"function\" &&\n typeof (obj as Record<string, unknown>)[\"fromUR\"] === \"function\"\n );\n}\n","/**\n * Xoshiro256** PRNG implementation.\n *\n * This is a high-quality, fast pseudo-random number generator used\n * for deterministic fragment selection in fountain codes.\n *\n * Reference: https://prng.di.unimi.it/\n * BC-UR Reference: https://github.com/nicklockwood/fountain-codes\n */\n\nimport { sha256 } from \"@bcts/crypto\";\n\nconst MAX_UINT64 = BigInt(\"0xffffffffffffffff\");\n\n/**\n * Performs a left rotation on a 64-bit BigInt.\n */\nfunction rotl(x: bigint, k: number): bigint {\n const kBigInt = BigInt(k);\n return ((x << kBigInt) | (x >> (64n - kBigInt))) & MAX_UINT64;\n}\n\n/**\n * Xoshiro256** pseudo-random number generator.\n *\n * This PRNG is used for deterministic mixing in fountain codes,\n * allowing both encoder and decoder to agree on which fragments\n * are combined without transmitting that information.\n */\nexport class Xoshiro256 {\n private s: [bigint, bigint, bigint, bigint];\n\n /**\n * Creates a new Xoshiro256** instance from a 32-byte seed.\n *\n * The seed must be exactly 32 bytes (256 bits). The bytes are interpreted\n * using the BC-UR reference algorithm: each 8-byte chunk is read as\n * big-endian then stored as little-endian for the state.\n *\n * @param seed - The seed bytes (must be exactly 32 bytes)\n */\n constructor(seed: Uint8Array) {\n if (seed.length !== 32) {\n throw new Error(`Seed must be 32 bytes, got ${seed.length}`);\n }\n\n // BC-UR reference implementation:\n // For each 8-byte chunk, read as big-endian u64, then convert to little-endian bytes\n // This effectively swaps the byte order within each 8-byte segment\n const s: [bigint, bigint, bigint, bigint] = [0n, 0n, 0n, 0n];\n for (let i = 0; i < 4; i++) {\n // Read 8 bytes as big-endian u64\n let v = 0n;\n for (let n = 0; n < 8; n++) {\n v = (v << 8n) | BigInt(seed[8 * i + n] ?? 0);\n }\n s[i] = v;\n }\n\n this.s = s;\n }\n\n /**\n * Creates a Xoshiro256** instance from raw state values.\n * Useful for seeding with specific values.\n */\n static fromState(s0: bigint, s1: bigint, s2: bigint, s3: bigint): Xoshiro256 {\n const instance = Object.create(Xoshiro256.prototype) as Xoshiro256;\n instance.s = [s0, s1, s2, s3];\n return instance;\n }\n\n /**\n * Generates the next 64-bit random value.\n */\n next(): bigint {\n const result = (rotl((this.s[1] * 5n) & MAX_UINT64, 7) * 9n) & MAX_UINT64;\n\n const t = (this.s[1] << 17n) & MAX_UINT64;\n\n this.s[2] ^= this.s[0];\n this.s[3] ^= this.s[1];\n this.s[1] ^= this.s[2];\n this.s[0] ^= this.s[3];\n\n this.s[2] ^= t;\n this.s[3] = rotl(this.s[3], 45);\n\n return result;\n }\n\n /**\n * Generates a random double in [0, 1).\n * Matches BC-UR reference: self.next() as f64 / (u64::MAX as f64 + 1.0)\n */\n nextDouble(): number {\n const value = this.next();\n // u64::MAX as f64 + 1.0 = 18446744073709551616.0\n return Number(value) / 18446744073709551616.0;\n }\n\n /**\n * Generates a random integer in [low, high] (inclusive).\n * Matches BC-UR reference: (self.next_double() * ((high - low + 1) as f64)) as u64 + low\n */\n nextInt(low: number, high: number): number {\n const range = high - low + 1;\n return Math.floor(this.nextDouble() * range) + low;\n }\n\n /**\n * Generates a random byte [0, 255].\n */\n nextByte(): number {\n return Number(this.next() & 0xffn);\n }\n\n /**\n * Generates an array of random bytes.\n */\n nextData(count: number): Uint8Array {\n const result = new Uint8Array(count);\n for (let i = 0; i < count; i++) {\n result[i] = this.nextByte();\n }\n return result;\n }\n\n /**\n * Shuffles items by repeatedly picking random indices.\n * Matches BC-UR reference implementation.\n */\n shuffled<T>(items: T[]): T[] {\n const source = [...items];\n const shuffled: T[] = [];\n while (source.length > 0) {\n const index = this.nextInt(0, source.length - 1);\n const item = source.splice(index, 1)[0];\n if (item !== undefined) {\n shuffled.push(item);\n }\n }\n return shuffled;\n }\n\n /**\n * Chooses the degree (number of fragments to mix) using a weighted sampler.\n * Uses the robust soliton distribution with weights [1/1, 1/2, 1/3, ..., 1/n].\n * Matches BC-UR reference implementation.\n */\n chooseDegree(seqLen: number): number {\n // Create weights: [1/1, 1/2, 1/3, ..., 1/seqLen]\n const weights: number[] = [];\n for (let i = 1; i <= seqLen; i++) {\n weights.push(1.0 / i);\n }\n\n // Use Vose's alias method for weighted sampling\n const sampler = new WeightedSampler(weights);\n return sampler.next(this) + 1; // 1-indexed degree\n }\n}\n\n/**\n * Weighted sampler using Vose's alias method.\n * Allows O(1) sampling from a discrete probability distribution.\n */\nclass WeightedSampler {\n private readonly aliases: number[];\n private readonly probs: number[];\n\n constructor(weights: number[]) {\n const n = weights.length;\n if (n === 0) {\n throw new Error(\"Weights array cannot be empty\");\n }\n\n // Normalize weights\n const sum = weights.reduce((a, b) => a + b, 0);\n if (sum <= 0) {\n throw new Error(\"Weights must sum to a positive value\");\n }\n\n const normalized = weights.map((w) => (w * n) / sum);\n\n // Initialize alias table\n this.aliases = Array.from<number>({ length: n }).fill(0);\n this.probs = Array.from<number>({ length: n }).fill(0);\n\n // Partition into small and large\n const small: number[] = [];\n const large: number[] = [];\n\n for (let i = n - 1; i >= 0; i--) {\n if (normalized[i] < 1.0) {\n small.push(i);\n } else {\n large.push(i);\n }\n }\n\n // Build the alias table\n while (small.length > 0 && large.length > 0) {\n const a = small.pop();\n const g = large.pop();\n if (a === undefined || g === undefined) break;\n this.probs[a] = normalized[a] ?? 0;\n this.aliases[a] = g;\n const normalizedG = normalized[g] ?? 0;\n const normalizedA = normalized[a] ?? 0;\n normalized[g] = normalizedG + normalizedA - 1.0;\n if (normalized[g] !== undefined && normalized[g] < 1.0) {\n small.push(g);\n } else {\n large.push(g);\n }\n }\n\n while (large.length > 0) {\n const g = large.pop();\n if (g === undefined) break;\n this.probs[g] = 1.0;\n }\n\n while (small.length > 0) {\n const a = small.pop();\n if (a === undefined) break;\n this.probs[a] = 1.0;\n }\n }\n\n /**\n * Sample from the distribution.\n */\n next(rng: Xoshiro256): number {\n const r1 = rng.nextDouble();\n const r2 = rng.nextDouble();\n const n = this.probs.length;\n const i = Math.floor(n * r1);\n if (r2 < this.probs[i]) {\n return i;\n } else {\n return this.aliases[i];\n }\n }\n}\n\n/**\n * Creates a Xoshiro256 PRNG instance from message checksum and sequence number.\n *\n * This creates an 8-byte seed by concatenating seqNum and checksum (both in\n * big-endian), then hashes it with SHA-256 to get the 32-byte seed for Xoshiro.\n *\n * This matches the BC-UR reference implementation.\n */\nexport function createSeed(checksum: number, seqNum: number): Uint8Array {\n // Create 8-byte seed: seqNum (big-endian) || checksum (big-endian)\n const seed8 = new Uint8Array(8);\n\n // seqNum in big-endian (bytes 0-3)\n seed8[0] = (seqNum >>> 24) & 0xff;\n seed8[1] = (seqNum >>> 16) & 0xff;\n seed8[2] = (seqNum >>> 8) & 0xff;\n seed8[3] = seqNum & 0xff;\n\n // checksum in big-endian (bytes 4-7)\n seed8[4] = (checksum >>> 24) & 0xff;\n seed8[5] = (checksum >>> 16) & 0xff;\n seed8[6] = (checksum >>> 8) & 0xff;\n seed8[7] = checksum & 0xff;\n\n // Hash with SHA-256 to get 32 bytes\n return sha256(seed8);\n}\n","/**\n * Fountain code implementation for multipart URs.\n *\n * This implements a hybrid fixed-rate and rateless fountain code system\n * as specified in BCR-2020-005 and BCR-2024-001.\n *\n * Key concepts:\n * - Parts 1-seqLen are \"pure\" fragments (fixed-rate)\n * - Parts > seqLen are \"mixed\" fragments using XOR (rateless)\n * - Xoshiro256** PRNG ensures encoder/decoder agree on mixing\n */\n\nimport { Xoshiro256, createSeed } from \"./xoshiro.js\";\nimport { crc32 } from \"./utils.js\";\n\n/**\n * Represents a fountain code part with metadata.\n */\nexport interface FountainPart {\n /** Sequence number (1-based) */\n seqNum: number;\n /** Total number of pure fragments */\n seqLen: number;\n /** Length of original message */\n messageLen: number;\n /** CRC32 checksum of original message */\n checksum: number;\n /** Fragment data */\n data: Uint8Array;\n}\n\n/**\n * Splits data into fragments of the specified size.\n */\nexport function splitMessage(message: Uint8Array, fragmentLen: number): Uint8Array[] {\n const fragments: Uint8Array[] = [];\n const fragmentCount = Math.ceil(message.length / fragmentLen);\n\n for (let i = 0; i < fragmentCount; i++) {\n const start = i * fragmentLen;\n const end = Math.min(start + fragmentLen, message.length);\n const fragment = new Uint8Array(fragmentLen);\n\n // Copy data and pad with zeros if needed\n const sourceSlice = message.slice(start, end);\n fragment.set(sourceSlice);\n\n fragments.push(fragment);\n }\n\n return fragments;\n}\n\n/**\n * XOR two Uint8Arrays together.\n */\nexport function xorBytes(a: Uint8Array, b: Uint8Array): Uint8Array {\n const len = Math.max(a.length, b.length);\n const result = new Uint8Array(len);\n\n for (let i = 0; i < len; i++) {\n result[i] = (a[i] ?? 0) ^ (b[i] ?? 0);\n }\n\n return result;\n}\n\n/**\n * Chooses which fragments to mix for a given sequence number.\n *\n * This uses a seeded Xoshiro256** PRNG to deterministically select fragments,\n * ensuring encoder and decoder agree without explicit coordination.\n *\n * The algorithm matches the BC-UR reference implementation:\n * 1. For pure parts (seqNum <= seqLen), return single fragment index\n * 2. For mixed parts, use weighted sampling to choose degree\n * 3. Shuffle all indices and take the first 'degree' indices\n *\n * @param seqNum - The sequence number (1-based)\n * @param seqLen - Total number of pure fragments\n * @param checksum - CRC32 checksum of the message\n * @returns Array of fragment indices (0-based)\n */\nexport function chooseFragments(seqNum: number, seqLen: number, checksum: number): number[] {\n // Pure parts (seqNum <= seqLen) contain exactly one fragment\n if (seqNum <= seqLen) {\n return [seqNum - 1];\n }\n\n // Mixed parts use PRNG to select fragments\n const seed = createSeed(checksum, seqNum);\n const rng = new Xoshiro256(seed);\n\n // Choose degree using weighted sampler (1/k distribution)\n const degree = rng.chooseDegree(seqLen);\n\n // Create array of all indices [0, 1, 2, ..., seqLen-1]\n const allIndices: number[] = [];\n for (let i = 0; i < seqLen; i++) {\n allIndices.push(i);\n }\n\n // Shuffle all indices and take the first 'degree' indices\n const shuffled = rng.shuffled(allIndices);\n return shuffled.slice(0, degree);\n}\n\n/**\n * Mixes the selected fragments using XOR.\n */\nexport function mixFragments(fragments: Uint8Array[], indices: number[]): Uint8Array {\n if (indices.length === 0) {\n throw new Error(\"No fragments to mix\");\n }\n\n let result: Uint8Array = new Uint8Array(fragments[0].length);\n\n for (const index of indices) {\n const fragment = fragments[index];\n if (fragment === undefined) {\n throw new Error(`Fragment at index ${index} not found`);\n }\n result = xorBytes(result, fragment);\n }\n\n return result;\n}\n\n/**\n * Fountain encoder for creating multipart URs.\n */\nexport class FountainEncoder {\n private readonly fragments: Uint8Array[];\n private readonly messageLen: number;\n private readonly checksum: number;\n private seqNum = 0;\n\n /**\n * Creates a fountain encoder for the given message.\n *\n * @param message - The message to encode\n * @param maxFragmentLen - Maximum length of each fragment\n */\n constructor(message: Uint8Array, maxFragmentLen: number) {\n if (maxFragmentLen < 1) {\n throw new Error(\"Fragment length must be at least 1\");\n }\n\n this.messageLen = message.length;\n this.checksum = crc32(message);\n this.fragments = splitMessage(message, maxFragmentLen);\n }\n\n /**\n * Returns the number of pure fragments.\n */\n get seqLen(): number {\n return this.fragments.length;\n }\n\n /**\n * Returns whether the message fits in a single part.\n */\n isSinglePart(): boolean {\n return this.fragments.length === 1;\n }\n\n /**\n * Returns whether all pure parts have been emitted.\n */\n isComplete(): boolean {\n return this.seqNum >= this.seqLen;\n }\n\n /**\n * Generates the next fountain part.\n */\n nextPart(): FountainPart {\n this.seqNum++;\n\n const indices = chooseFragments(this.seqNum, this.seqLen, this.checksum);\n const data = mixFragments(this.fragments, indices);\n\n return {\n seqNum: this.seqNum,\n seqLen: this.seqLen,\n messageLen: this.messageLen,\n checksum: this.checksum,\n data,\n };\n }\n\n /**\n * Returns the current sequence number.\n */\n currentSeqNum(): number {\n return this.seqNum;\n }\n\n /**\n * Resets the encoder to start from the beginning.\n */\n reset(): void {\n this.seqNum = 0;\n }\n}\n\n/**\n * Fountain decoder for reassembling multipart URs.\n */\nexport class FountainDecoder {\n private seqLen: number | null = null;\n private messageLen: number | null = null;\n private checksum: number | null = null;\n\n // Storage for received data\n private readonly pureFragments = new Map<number, Uint8Array>();\n private readonly mixedParts = new Map<number, { indices: number[]; data: Uint8Array }>();\n\n /**\n * Receives a fountain part and attempts to decode.\n *\n * @param part - The fountain part to receive\n * @returns true if the message is now complete\n */\n receive(part: FountainPart): boolean {\n // Initialize on first part\n if (this.seqLen === null) {\n this.seqLen = part.seqLen;\n this.messageLen = part.messageLen;\n this.checksum = part.checksum;\n }\n\n // Validate consistency\n if (\n part.seqLen !== this.seqLen ||\n part.messageLen !== this.messageLen ||\n part.checksum !== this.checksum\n ) {\n throw new Error(\"Inconsistent part metadata\");\n }\n\n // Determine which fragments this part contains\n const indices = chooseFragments(part.seqNum, this.seqLen, this.checksum);\n\n if (indices.length === 1) {\n // Pure fragment (or degree-1 mixed that acts like pure)\n const index = indices[0];\n if (!this.pureFragments.has(index)) {\n this.pureFragments.set(index, part.data);\n }\n } else {\n // Mixed fragment - store for later reduction\n if (!this.mixedParts.has(part.seqNum)) {\n this.mixedParts.set(part.seqNum, { indices, data: part.data });\n }\n }\n\n // Try to reduce mixed parts\n this.reduceMixedParts();\n\n return this.isComplete();\n }\n\n /**\n * Attempts to extract pure fragments from mixed parts.\n */\n private reduceMixedParts(): void {\n let progress = true;\n\n while (progress) {\n progress = false;\n\n for (const [seqNum, mixed] of this.mixedParts) {\n // Find which indices we're missing\n const missing: number[] = [];\n let reduced = mixed.data;\n\n for (const index of mixed.indices) {\n const pure = this.pureFragments.get(index);\n if (pure !== undefined) {\n // XOR out the known fragment\n reduced = xorBytes(reduced, pure);\n } else {\n missing.push(index);\n }\n }\n\n if (missing.length === 0) {\n // All fragments known, remove this mixed part\n this.mixedParts.delete(seqNum);\n progress = true;\n } else if (missing.length === 1) {\n // Can extract the missing fragment\n const missingIndex = missing[0];\n this.pureFragments.set(missingIndex, reduced);\n this.mixedParts.delete(seqNum);\n progress = true;\n }\n }\n }\n }\n\n /**\n * Returns whether all fragments have been received.\n */\n isComplete(): boolean {\n if (this.seqLen === null) {\n return false;\n }\n\n return this.pureFragments.size === this.seqLen;\n }\n\n /**\n * Reconstructs the original message.\n *\n * @returns The original message, or null if not yet complete\n */\n message(): Uint8Array | null {\n if (!this.isComplete() || this.seqLen === null || this.messageLen === null) {\n return null;\n }\n\n // Calculate fragment size from first fragment\n const firstFragment = this.pureFragments.get(0);\n if (firstFragment === undefined) {\n return null;\n }\n\n const fragmentLen = firstFragment.length;\n const result = new Uint8Array(this.messageLen);\n\n // Assemble fragments\n for (let i = 0; i < this.seqLen; i++) {\n const fragment = this.pureFragments.get(i);\n if (fragment === undefined) {\n return null;\n }\n\n const start = i * fragmentLen;\n const end = Math.min(start + fragmentLen, this.messageLen);\n const len = end - start;\n\n result.set(fragment.slice(0, len), start);\n }\n\n // Verify checksum\n const actualChecksum = crc32(result);\n if (actualChecksum !== this.checksum) {\n throw new Error(`Checksum mismatch: expected ${this.checksum}, got ${actualChecksum}`);\n }\n\n return result;\n }\n\n /**\n * Returns the progress as a fraction (0 to 1).\n */\n progress(): number {\n if (this.seqLen === null) {\n return 0;\n }\n return this.pureFragments.size / this.seqLen;\n }\n\n /**\n * Resets the decoder.\n */\n reset(): void {\n this.seqLen = null;\n this.messageLen = null;\n this.checksum = null;\n this.pureFragments.clear();\n this.mixedParts.clear();\n }\n}\n","import type { UR } from \"./ur.js\";\nimport { URError } from \"./error.js\";\nimport { FountainEncoder, type FountainPart } from \"./fountain.js\";\nimport { encodeBytewords, BytewordsStyle } from \"./utils.js\";\nimport { cbor } from \"@bcts/dcbor\";\n\n/**\n * Encodes a UR as multiple parts using fountain codes.\n *\n * This allows large CBOR structures to be split into multiple UR strings\n * that can be transmitted separately and reassembled. The encoder uses\n * fountain codes for resilient transmission over lossy channels.\n *\n * For single-part URs (small payloads), use the regular UR.string() method.\n *\n * @example\n * ```typescript\n * const ur = UR.new('bytes', cbor);\n * const encoder = new MultipartEncoder(ur, 100);\n *\n * // Generate all pure parts\n * while (!encoder.isComplete()) {\n * const part = encoder.nextPart();\n * console.log(part); // \"ur:bytes/1-10/...\"\n * }\n *\n * // Generate additional rateless parts for redundancy\n * for (let i = 0; i < 5; i++) {\n * const part = encoder.nextPart();\n * console.log(part); // \"ur:bytes/11-10/...\"\n * }\n * ```\n */\nexport class MultipartEncoder {\n private readonly _ur: UR;\n private readonly _fountainEncoder: FountainEncoder;\n private _currentIndex = 0;\n\n /**\n * Creates a new multipart encoder for the given UR.\n *\n * @param ur - The UR to encode\n * @param maxFragmentLen - Maximum length of each fragment in bytes\n * @throws {URError} If encoding fails\n *\n * @example\n * ```typescript\n * const encoder = new MultipartEncoder(ur, 100);\n * ```\n */\n constructor(ur: UR, maxFragmentLen: number) {\n if (maxFragmentLen < 1) {\n throw new URError(\"Max fragment length must be at least 1\");\n }\n this._ur = ur;\n\n // Create fountain encoder from CBOR data\n const cborData = ur.cbor().toData();\n this._fountainEncoder = new FountainEncoder(cborData, maxFragmentLen);\n }\n\n /**\n * Gets the next part of the encoding.\n *\n * Parts 1 through seqLen are \"pure\" fragments containing one piece each.\n * Parts beyond seqLen are \"mixed\" fragments using fountain codes for redundancy.\n *\n * @returns The next UR string part\n *\n * @example\n * ```typescript\n * const part = encoder.nextPart();\n * // Returns: \"ur:bytes/1-3/lsadaoaxjygonesw\"\n * ```\n */\n nextPart(): string {\n const part = this._fountainEncoder.nextPart();\n this._currentIndex++;\n return this._encodePart(part);\n }\n\n /**\n * Encodes a fountain part as a UR string.\n */\n private _encodePart(part: FountainPart): string {\n // For single-part messages, use simple format\n if (part.seqLen === 1) {\n return this._ur.string();\n }\n\n // Encode the part data as CBOR: [seqNum, seqLen, messageLen, checksum, data]\n // Using a simple format: seqNum-seqLen prefix followed by bytewords-encoded part\n const partData = this._encodePartData(part);\n const encoded = encodeBytewords(partData, BytewordsStyle.Minimal);\n\n return `ur:${this._ur.urTypeStr()}/${part.seqNum}-${part.seqLen}/${encoded}`;\n }\n\n /**\n * Encodes part metadata and data as CBOR for bytewords encoding.\n * Format: CBOR array [seqNum, seqLen, messageLen, checksum, data]\n */\n private _encodePartData(part: FountainPart): Uint8Array {\n // Create CBOR array with 5 elements: [seqNum, seqLen, messageLen, checksum, data]\n const cborArray = cbor([part.seqNum, part.seqLen, part.messageLen, part.checksum, part.data]);\n\n return cborArray.toData();\n }\n\n /**\n * Gets the current part index.\n */\n currentIndex(): number {\n return this._currentIndex;\n }\n\n /**\n * Gets the total number of pure parts.\n *\n * Note: Fountain codes can generate unlimited parts beyond this count\n * for additional redundancy.\n */\n partsCount(): number {\n return this._fountainEncoder.seqLen;\n }\n}\n","import { decodeCbor, MajorType, type Cbor } from \"@bcts/dcbor\";\nimport { InvalidSchemeError, InvalidTypeError, UnexpectedTypeError, URError } from \"./error.js\";\nimport { UR } from \"./ur.js\";\nimport { URType } from \"./ur-type.js\";\nimport { FountainDecoder, type FountainPart } from \"./fountain.js\";\nimport { decodeBytewords, BytewordsStyle } from \"./utils.js\";\n\n/**\n * Decodes multiple UR parts back into a single UR.\n *\n * This reassembles multipart URs that were encoded using fountain codes.\n * The decoder can handle out-of-order reception and packet loss.\n *\n * @example\n * ```typescript\n * const decoder = new MultipartDecoder();\n *\n * for (const urPart of urParts) {\n * decoder.receive(urPart);\n * if (decoder.isComplete()) {\n * const ur = decoder.message();\n * break;\n * }\n * }\n * ```\n */\nexport class MultipartDecoder {\n private _urType: URType | null = null;\n private _fountainDecoder: FountainDecoder | null = null;\n private _decodedMessage: UR | null = null;\n\n /**\n * Receives a UR part string.\n *\n * @param part - A UR part string (e.g., \"ur:bytes/1-10/...\" or \"ur:bytes/...\")\n * @throws {InvalidSchemeError} If the part doesn't start with \"ur:\"\n * @throws {UnexpectedTypeError} If the type doesn't match previous parts\n */\n receive(part: string): void {\n const { urType, partInfo } = this._parsePart(part);\n\n // Validate type consistency\n if (this._urType === null) {\n this._urType = urType;\n } else if (!this._urType.equals(urType)) {\n throw new UnexpectedTypeError(this._urType.string(), urType.string());\n }\n\n // Handle the part\n if (partInfo.isSinglePart) {\n // Single-part UR - decode immediately\n this._decodedMessage = UR.fromURString(part);\n } else {\n // Multipart UR - use fountain decoder\n this._fountainDecoder ??= new FountainDecoder();\n\n const fountainPart = this._decodeFountainPart(partInfo);\n this._fountainDecoder.receive(fountainPart);\n\n // Try to get the complete message\n if (this._fountainDecoder.isComplete()) {\n const message = this._fountainDecoder.message();\n if (message !== null) {\n const cbor = decodeCbor(message);\n this._decodedMessage = UR.new(this._urType, cbor);\n }\n }\n }\n }\n\n /**\n * Parses a UR part string to extract type and part info.\n */\n private _parsePart(part: string): { urType: URType; partInfo: PartInfo } {\n const lowercased = part.toLowerCase();\n\n if (!lowercased.startsWith(\"ur:\")) {\n throw new InvalidSchemeError();\n }\n\n const afterScheme = lowercased.substring(3);\n const components = afterScheme.split(\"/\");\n\n if (components.length === 0 || components[0] === \"\") {\n throw new InvalidTypeError();\n }\n\n const urType = new URType(components[0]);\n\n // Check if this is a multipart UR (format: type/seqNum-seqLen/data)\n if (components.length >= 3) {\n const seqPart = components[1];\n const seqMatch = /^(\\d+)-(\\d+)$/.exec(seqPart);\n\n if (seqMatch !== null) {\n const seqNum = parseInt(seqMatch[1], 10);\n const seqLen = parseInt(seqMatch[2], 10);\n const encodedData = components.slice(2).join(\"/\");\n\n return {\n urType,\n partInfo: {\n isSinglePart: false,\n seqNum,\n seqLen,\n encodedData,\n },\n };\n }\n }\n\n // Single-part UR\n return {\n urType,\n partInfo: { isSinglePart: true },\n };\n }\n\n /**\n * Decodes a multipart UR's fountain part data.\n *\n * The multipart body is a CBOR array: [seqNum, seqLen, messageLen, checksum, data]\n */\n private _decodeFountainPart(partInfo: MultipartInfo): FountainPart {\n // Decode bytewords to get CBOR data\n const cborData = decodeBytewords(partInfo.encodedData, BytewordsStyle.Minimal);\n\n // Decode the CBOR array\n const decoded = decodeCbor(cborData);\n\n // The decoded value should be an array with 5 elements\n if (decoded.type !== MajorType.Array) {\n throw new URError(\"Invalid multipart data: expected CBOR array\");\n }\n\n const items = decoded.value as Cbor[];\n if (items.length !== 5) {\n throw new URError(`Invalid multipart data: expected 5 elements, got ${items.length}`);\n }\n\n // Extract the fields: [seqNum, seqLen, messageLen, checksum, data]\n const seqNum = Number(items[0].value);\n const seqLen = Number(items[1].value);\n const messageLen = Number(items[2].value);\n const checksum = Number(items[3].value);\n const data = items[4].value as Uint8Array;\n\n // Verify seqNum and seqLen match the URL path values\n if (seqNum !== partInfo.seqNum || seqLen !== partInfo.seqLen) {\n throw new URError(\n `Multipart metadata mismatch: URL says ${partInfo.seqNum}-${partInfo.seqLen}, CBOR says ${seqNum}-${seqLen}`,\n );\n }\n\n return {\n seqNum,\n seqLen,\n messageLen,\n checksum,\n data,\n };\n }\n\n /**\n * Checks if the message is complete.\n */\n isComplete(): boolean {\n return this._decodedMessage !== null;\n }\n\n /**\n * Gets the decoded UR message.\n *\n * @returns The decoded UR, or null if not yet complete\n */\n message(): UR | null {\n return this._decodedMessage;\n }\n}\n\n/**\n * Part info for single-part URs.\n */\ninterface SinglePartInfo {\n isSinglePart: true;\n}\n\n/**\n * Part info for multipart URs.\n */\ninterface MultipartInfo {\n isSinglePart: false;\n seqNum: number;\n seqLen: number;\n encodedData: string;\n}\n\ntype PartInfo = SinglePartInfo | MultipartInfo;\n"],"mappings":";;;;;;;AAGA,IAAa,UAAb,cAA6B,MAAM;CACjC,YAAY,SAAiB;AAC3B,QAAM,QAAQ;AACd,OAAK,OAAO;;;;;;AAOhB,IAAa,qBAAb,cAAwC,QAAQ;CAC9C,cAAc;AACZ,QAAM,oBAAoB;AAC1B,OAAK,OAAO;;;;;;AAOhB,IAAa,uBAAb,cAA0C,QAAQ;CAChD,cAAc;AACZ,QAAM,uBAAuB;AAC7B,OAAK,OAAO;;;;;;AAOhB,IAAa,mBAAb,cAAsC,QAAQ;CAC5C,cAAc;AACZ,QAAM,kBAAkB;AACxB,OAAK,OAAO;;;;;;AAOhB,IAAa,qBAAb,cAAwC,QAAQ;CAC9C,cAAc;AACZ,QAAM,0BAA0B;AAChC,OAAK,OAAO;;;;;;AAOhB,IAAa,sBAAb,cAAyC,QAAQ;CAC/C,YAAY,UAAkB,OAAe;AAC3C,QAAM,oBAAoB,SAAS,cAAc,QAAQ;AACzD,OAAK,OAAO;;;;;;AAOhB,IAAa,iBAAb,cAAoC,QAAQ;CAC1C,YAAY,SAAiB;AAC3B,QAAM,oBAAoB,UAAU;AACpC,OAAK,OAAO;;;;;;AAOhB,IAAa,YAAb,cAA+B,QAAQ;CACrC,YAAY,SAAiB;AAC3B,QAAM,eAAe,UAAU;AAC/B,OAAK,OAAO;;;;;;;AAQhB,IAAa,gBAAb,cAAmC,QAAQ;CACzC,YAAY,SAAiB;AAC3B,QAAM,qBAAqB,QAAQ,GAAG;AACtC,OAAK,OAAO;;;;;;AAShB,SAAgB,QAAQ,QAAkC;AACxD,QAAO,kBAAkB;;;;;;;;;AC3F3B,SAAgB,aAAa,MAAuB;CAClD,MAAM,OAAO,KAAK,WAAW,EAAE;AAE/B,KAAI,QAAQ,MAAM,QAAQ,IAAK,QAAO;AAEtC,KAAI,QAAQ,MAAM,QAAQ,GAAI,QAAO;AAErC,KAAI,SAAS,GAAI,QAAO;AACxB,QAAO;;;;;;AAOT,SAAgB,cAAc,QAAyB;AACrD,KAAI,OAAO,WAAW,EAAG,QAAO;AAChC,QAAO,MAAM,KAAK,OAAO,CAAC,OAAO,SAAS,aAAa,KAAK,CAAC;;;;;;AAiB/D,MAAa,YAAsB;CACjC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;;;;AAKD,SAAS,qBAA0C;CACjD,MAAM,sBAAM,IAAI,KAAqB;AACrC,WAAU,SAAS,MAAM,UAAU;AACjC,MAAI,IAAI,MAAM,MAAM;GACpB;AACF,QAAO;;AAGT,MAAa,gBAAgB,oBAAoB;;;;;AAMjD,MAAa,YAAsB;CACjC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CAC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"}
1
+ {"version":3,"file":"index.cjs","names":["MajorType"],"sources":["../src/error.ts","../src/utils.ts","../src/ur-type.ts","../src/ur.ts","../src/ur-encodable.ts","../src/ur-decodable.ts","../src/ur-codable.ts","../src/xoshiro.ts","../src/fountain.ts","../src/multipart-encoder.ts","../src/multipart-decoder.ts"],"sourcesContent":["/**\n * Error type for UR encoding/decoding operations.\n */\nexport class URError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"URError\";\n }\n}\n\n/**\n * Error type for invalid UR schemes.\n */\nexport class InvalidSchemeError extends URError {\n constructor() {\n super(\"Invalid UR scheme\");\n this.name = \"InvalidSchemeError\";\n }\n}\n\n/**\n * Error type for unspecified UR types.\n */\nexport class TypeUnspecifiedError extends URError {\n constructor() {\n super(\"No UR type specified\");\n this.name = \"TypeUnspecifiedError\";\n }\n}\n\n/**\n * Error type for invalid UR types.\n */\nexport class InvalidTypeError extends URError {\n constructor() {\n super(\"Invalid UR type\");\n this.name = \"InvalidTypeError\";\n }\n}\n\n/**\n * Error type for non-single-part URs.\n */\nexport class NotSinglePartError extends URError {\n constructor() {\n super(\"UR is not a single-part\");\n this.name = \"NotSinglePartError\";\n }\n}\n\n/**\n * Error type for unexpected UR types.\n */\nexport class UnexpectedTypeError extends URError {\n constructor(expected: string, found: string) {\n super(`Expected UR type ${expected}, but found ${found}`);\n this.name = \"UnexpectedTypeError\";\n }\n}\n\n/**\n * Error type for Bytewords encoding/decoding errors.\n */\nexport class BytewordsError extends URError {\n constructor(message: string) {\n super(`Bytewords error: ${message}`);\n this.name = \"BytewordsError\";\n }\n}\n\n/**\n * Error type for CBOR encoding/decoding errors.\n */\nexport class CBORError extends URError {\n constructor(message: string) {\n super(`CBOR error: ${message}`);\n this.name = \"CBORError\";\n }\n}\n\n/**\n * Error type for UR decoder errors.\n * Matches Rust's Error::UR(String) variant.\n */\nexport class URDecodeError extends URError {\n constructor(message: string) {\n super(`UR decoder error (${message})`);\n this.name = \"URDecodeError\";\n }\n}\n\nexport type Result<T> = T | Error;\n\n/**\n * Helper function to check if a result is an error.\n */\nexport function isError(result: unknown): result is Error {\n return result instanceof Error;\n}\n","import { InvalidTypeError } from \"./error.js\";\n\n/**\n * Checks if a character is a valid UR type character.\n * Valid characters are lowercase letters, digits, and hyphens.\n */\nexport function isURTypeChar(char: string): boolean {\n const code = char.charCodeAt(0);\n // Check for lowercase letters (a-z)\n if (code >= 97 && code <= 122) return true;\n // Check for digits (0-9)\n if (code >= 48 && code <= 57) return true;\n // Check for hyphen (-)\n if (code === 45) return true;\n return false;\n}\n\n/**\n * Checks if a string is a valid UR type.\n * Valid UR types contain only lowercase letters, digits, and hyphens.\n */\nexport function isValidURType(urType: string): boolean {\n if (urType.length === 0) return false;\n return Array.from(urType).every((char) => isURTypeChar(char));\n}\n\n/**\n * Validates and returns a UR type, or throws an error if invalid.\n */\nexport function validateURType(urType: string): string {\n if (!isValidURType(urType)) {\n throw new InvalidTypeError();\n }\n return urType;\n}\n\n/**\n * Bytewords for encoding/decoding bytes as words.\n * See: https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-004-bytewords.md\n */\nexport const BYTEWORDS: string[] = [\n \"able\",\n \"acid\",\n \"also\",\n \"apex\",\n \"aqua\",\n \"arch\",\n \"atom\",\n \"aunt\",\n \"away\",\n \"axis\",\n \"back\",\n \"bald\",\n \"barn\",\n \"belt\",\n \"beta\",\n \"bias\",\n \"blue\",\n \"body\",\n \"brag\",\n \"brew\",\n \"bulb\",\n \"buzz\",\n \"calm\",\n \"cash\",\n \"cats\",\n \"chef\",\n \"city\",\n \"claw\",\n \"code\",\n \"cola\",\n \"cook\",\n \"cost\",\n \"crux\",\n \"curl\",\n \"cusp\",\n \"cyan\",\n \"dark\",\n \"data\",\n \"days\",\n \"deli\",\n \"dice\",\n \"diet\",\n \"door\",\n \"down\",\n \"draw\",\n \"drop\",\n \"drum\",\n \"dull\",\n \"duty\",\n \"each\",\n \"easy\",\n \"echo\",\n \"edge\",\n \"epic\",\n \"even\",\n \"exam\",\n \"exit\",\n \"eyes\",\n \"fact\",\n \"fair\",\n \"fern\",\n \"figs\",\n \"film\",\n \"fish\",\n \"fizz\",\n \"flap\",\n \"flew\",\n \"flux\",\n \"foxy\",\n \"free\",\n \"frog\",\n \"fuel\",\n \"fund\",\n \"gala\",\n \"game\",\n \"gear\",\n \"gems\",\n \"gift\",\n \"girl\",\n \"glow\",\n \"good\",\n \"gray\",\n \"grim\",\n \"guru\",\n \"gush\",\n \"gyro\",\n \"half\",\n \"hang\",\n \"hard\",\n \"hawk\",\n \"heat\",\n \"help\",\n \"high\",\n \"hill\",\n \"holy\",\n \"hope\",\n \"horn\",\n \"huts\",\n \"iced\",\n \"idea\",\n \"idle\",\n \"inch\",\n \"inky\",\n \"into\",\n \"iris\",\n \"iron\",\n \"item\",\n \"jade\",\n \"jazz\",\n \"join\",\n \"jolt\",\n \"jowl\",\n \"judo\",\n \"jugs\",\n \"jump\",\n \"junk\",\n \"jury\",\n \"keep\",\n \"keno\",\n \"kept\",\n \"keys\",\n \"kick\",\n \"kiln\",\n \"king\",\n \"kite\",\n \"kiwi\",\n \"knob\",\n \"lamb\",\n \"lava\",\n \"lazy\",\n \"leaf\",\n \"legs\",\n \"liar\",\n \"limp\",\n \"lion\",\n \"list\",\n \"logo\",\n \"loud\",\n \"love\",\n \"luau\",\n \"luck\",\n \"lung\",\n \"main\",\n \"many\",\n \"math\",\n \"maze\",\n \"memo\",\n \"menu\",\n \"meow\",\n \"mild\",\n \"mint\",\n \"miss\",\n \"monk\",\n \"nail\",\n \"navy\",\n \"need\",\n \"news\",\n \"next\",\n \"noon\",\n \"note\",\n \"numb\",\n \"obey\",\n \"oboe\",\n \"omit\",\n \"onyx\",\n \"open\",\n \"oval\",\n \"owls\",\n \"paid\",\n \"part\",\n \"peck\",\n \"play\",\n \"plus\",\n \"poem\",\n \"pool\",\n \"pose\",\n \"puff\",\n \"puma\",\n \"purr\",\n \"quad\",\n \"quiz\",\n \"race\",\n \"ramp\",\n \"real\",\n \"redo\",\n \"rich\",\n \"road\",\n \"rock\",\n \"roof\",\n \"ruby\",\n \"ruin\",\n \"runs\",\n \"rust\",\n \"safe\",\n \"saga\",\n \"scar\",\n \"sets\",\n \"silk\",\n \"skew\",\n \"slot\",\n \"soap\",\n \"solo\",\n \"song\",\n \"stub\",\n \"surf\",\n \"swan\",\n \"taco\",\n \"task\",\n \"taxi\",\n \"tent\",\n \"tied\",\n \"time\",\n \"tiny\",\n \"toil\",\n \"tomb\",\n \"toys\",\n \"trip\",\n \"tuna\",\n \"twin\",\n \"ugly\",\n \"undo\",\n \"unit\",\n \"urge\",\n \"user\",\n \"vast\",\n \"very\",\n \"veto\",\n \"vial\",\n \"vibe\",\n \"view\",\n \"visa\",\n \"void\",\n \"vows\",\n \"wall\",\n \"wand\",\n \"warm\",\n \"wasp\",\n \"wave\",\n \"waxy\",\n \"webs\",\n \"what\",\n \"when\",\n \"whiz\",\n \"wolf\",\n \"work\",\n \"yank\",\n \"yawn\",\n \"yell\",\n \"yoga\",\n \"yurt\",\n \"zaps\",\n \"zero\",\n \"zest\",\n \"zinc\",\n \"zone\",\n \"zoom\",\n];\n\n/**\n * Create a reverse mapping for fast byteword lookup.\n */\nfunction createBytewordsMap(): Map<string, number> {\n const map = new Map<string, number>();\n BYTEWORDS.forEach((word, index) => {\n map.set(word, index);\n });\n return map;\n}\n\nexport const BYTEWORDS_MAP = createBytewordsMap();\n\n/**\n * Bytemojis for encoding/decoding bytes as emojis.\n * See: https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2024-008-bytemoji.md\n */\nexport const BYTEMOJIS: string[] = [\n \"๐Ÿ˜€\",\n \"๐Ÿ˜‚\",\n \"๐Ÿ˜†\",\n \"๐Ÿ˜‰\",\n \"๐Ÿ™„\",\n \"๐Ÿ˜‹\",\n \"๐Ÿ˜Ž\",\n \"๐Ÿ˜\",\n \"๐Ÿ˜˜\",\n \"๐Ÿ˜ญ\",\n \"๐Ÿซ \",\n \"๐Ÿฅฑ\",\n \"๐Ÿคฉ\",\n \"๐Ÿ˜ถ\",\n \"๐Ÿคจ\",\n \"๐Ÿซฅ\",\n \"๐Ÿฅต\",\n \"๐Ÿฅถ\",\n \"๐Ÿ˜ณ\",\n \"๐Ÿคช\",\n \"๐Ÿ˜ต\",\n \"๐Ÿ˜ก\",\n \"๐Ÿคข\",\n \"๐Ÿ˜‡\",\n \"๐Ÿค \",\n \"๐Ÿคก\",\n \"๐Ÿฅณ\",\n \"๐Ÿฅบ\",\n \"๐Ÿ˜ฌ\",\n \"๐Ÿค‘\",\n \"๐Ÿ™ƒ\",\n \"๐Ÿคฏ\",\n \"๐Ÿ˜ˆ\",\n \"๐Ÿ‘น\",\n \"๐Ÿ‘บ\",\n \"๐Ÿ’€\",\n \"๐Ÿ‘ป\",\n \"๐Ÿ‘ฝ\",\n \"๐Ÿ˜บ\",\n \"๐Ÿ˜น\",\n \"๐Ÿ˜ป\",\n \"๐Ÿ˜ฝ\",\n \"๐Ÿ™€\",\n \"๐Ÿ˜ฟ\",\n \"๐Ÿซถ\",\n \"๐Ÿคฒ\",\n \"๐Ÿ™Œ\",\n \"๐Ÿค\",\n \"๐Ÿ‘\",\n \"๐Ÿ‘Ž\",\n \"๐Ÿ‘ˆ\",\n \"๐Ÿ‘†\",\n \"๐Ÿ’ช\",\n \"๐Ÿ‘„\",\n \"๐Ÿฆท\",\n \"๐Ÿ‘‚\",\n \"๐Ÿ‘ƒ\",\n \"๐Ÿง \",\n \"๐Ÿ‘€\",\n \"๐Ÿคš\",\n \"๐Ÿฆถ\",\n \"๐ŸŽ\",\n \"๐ŸŠ\",\n \"๐Ÿ‹\",\n \"๐ŸŒ\",\n \"๐Ÿ‰\",\n \"๐Ÿ‡\",\n \"๐Ÿ“\",\n \"๐Ÿซ\",\n \"๐Ÿ’\",\n \"๐Ÿ‘\",\n \"๐Ÿ\",\n \"๐Ÿฅ\",\n \"๐Ÿ†\",\n \"๐Ÿฅ‘\",\n \"๐Ÿฅฆ\",\n \"๐Ÿ…\",\n \"๐ŸŒฝ\",\n \"๐Ÿฅ•\",\n \"๐Ÿซ’\",\n \"๐Ÿง„\",\n \"๐Ÿฅ\",\n \"๐Ÿฅฏ\",\n \"๐Ÿž\",\n \"๐Ÿง€\",\n \"๐Ÿฅš\",\n \"๐Ÿ—\",\n \"๐ŸŒญ\",\n \"๐Ÿ”\",\n \"๐ŸŸ\",\n \"๐Ÿ•\",\n \"๐ŸŒฎ\",\n \"๐Ÿฅ™\",\n \"๐Ÿฑ\",\n \"๐Ÿœ\",\n \"๐Ÿค\",\n \"๐Ÿš\",\n \"๐Ÿฅ \",\n \"๐Ÿจ\",\n \"๐Ÿฆ\",\n \"๐ŸŽ‚\",\n \"๐Ÿชด\",\n \"๐ŸŒต\",\n \"๐ŸŒฑ\",\n \"๐Ÿ’\",\n \"๐Ÿ\",\n \"๐Ÿ„\",\n \"๐ŸŒน\",\n \"๐ŸŒบ\",\n \"๐ŸŒผ\",\n \"๐ŸŒป\",\n \"๐ŸŒธ\",\n \"๐Ÿ’จ\",\n \"๐ŸŒŠ\",\n \"๐Ÿ’ง\",\n \"๐Ÿ’ฆ\",\n \"๐ŸŒ€\",\n \"๐ŸŒˆ\",\n \"๐ŸŒž\",\n \"๐ŸŒ\",\n \"๐ŸŒ›\",\n \"๐ŸŒœ\",\n \"๐ŸŒ™\",\n \"๐ŸŒŽ\",\n \"๐Ÿ’ซ\",\n \"โญ\",\n \"๐Ÿช\",\n \"๐ŸŒ\",\n \"๐Ÿ’›\",\n \"๐Ÿ’”\",\n \"๐Ÿ’˜\",\n \"๐Ÿ’–\",\n \"๐Ÿ’•\",\n \"๐Ÿ\",\n \"๐Ÿšฉ\",\n \"๐Ÿ’ฌ\",\n \"๐Ÿ’ฏ\",\n \"๐Ÿšซ\",\n \"๐Ÿ”ด\",\n \"๐Ÿ”ท\",\n \"๐ŸŸฉ\",\n \"๐Ÿ›‘\",\n \"๐Ÿ”บ\",\n \"๐Ÿš—\",\n \"๐Ÿš‘\",\n \"๐Ÿš’\",\n \"๐Ÿšœ\",\n \"๐Ÿ›ต\",\n \"๐Ÿšจ\",\n \"๐Ÿš€\",\n \"๐Ÿš\",\n \"๐Ÿ›Ÿ\",\n \"๐Ÿšฆ\",\n \"๐Ÿฐ\",\n \"๐ŸŽก\",\n \"๐ŸŽข\",\n \"๐ŸŽ \",\n \"๐Ÿ \",\n \"๐Ÿ””\",\n \"๐Ÿ”‘\",\n \"๐Ÿšช\",\n \"๐Ÿช‘\",\n \"๐ŸŽˆ\",\n \"๐Ÿ’Œ\",\n \"๐Ÿ“ฆ\",\n \"๐Ÿ“ซ\",\n \"๐Ÿ“–\",\n \"๐Ÿ“š\",\n \"๐Ÿ“Œ\",\n \"๐Ÿงฎ\",\n \"๐Ÿ”’\",\n \"๐Ÿ’Ž\",\n \"๐Ÿ“ท\",\n \"โฐ\",\n \"โณ\",\n \"๐Ÿ“ก\",\n \"๐Ÿ’ก\",\n \"๐Ÿ’ฐ\",\n \"๐Ÿงฒ\",\n \"๐Ÿงธ\",\n \"๐ŸŽ\",\n \"๐ŸŽ€\",\n \"๐ŸŽ‰\",\n \"๐Ÿชญ\",\n \"๐Ÿ‘‘\",\n \"๐Ÿซ–\",\n \"๐Ÿ”ญ\",\n \"๐Ÿ›\",\n \"๐Ÿ†\",\n \"๐Ÿฅ\",\n \"๐ŸŽท\",\n \"๐ŸŽบ\",\n \"๐Ÿ€\",\n \"๐Ÿˆ\",\n \"๐ŸŽพ\",\n \"๐Ÿ“\",\n \"โœจ\",\n \"๐Ÿ”ฅ\",\n \"๐Ÿ’ฅ\",\n \"๐Ÿ‘•\",\n \"๐Ÿ‘š\",\n \"๐Ÿ‘–\",\n \"๐Ÿฉณ\",\n \"๐Ÿ‘—\",\n \"๐Ÿ‘”\",\n \"๐Ÿงข\",\n \"๐Ÿ‘“\",\n \"๐Ÿงถ\",\n \"๐Ÿงต\",\n \"๐Ÿ’\",\n \"๐Ÿ‘ \",\n \"๐Ÿ‘Ÿ\",\n \"๐Ÿงฆ\",\n \"๐Ÿงค\",\n \"๐Ÿ‘’\",\n \"๐Ÿ‘œ\",\n \"๐Ÿฑ\",\n \"๐Ÿถ\",\n \"๐Ÿญ\",\n \"๐Ÿน\",\n \"๐Ÿฐ\",\n \"๐ŸฆŠ\",\n \"๐Ÿป\",\n \"๐Ÿผ\",\n \"๐Ÿจ\",\n \"๐Ÿฏ\",\n \"๐Ÿฆ\",\n \"๐Ÿฎ\",\n \"๐Ÿท\",\n \"๐Ÿธ\",\n \"๐Ÿต\",\n \"๐Ÿ”\",\n \"๐Ÿฅ\",\n \"๐Ÿฆ†\",\n \"๐Ÿฆ‰\",\n \"๐Ÿด\",\n \"๐Ÿฆ„\",\n \"๐Ÿ\",\n \"๐Ÿ›\",\n \"๐Ÿฆ‹\",\n \"๐ŸŒ\",\n \"๐Ÿž\",\n \"๐Ÿข\",\n \"๐Ÿบ\",\n \"๐Ÿ\",\n \"๐Ÿชฝ\",\n \"๐Ÿ™\",\n \"๐Ÿฆ‘\",\n \"๐Ÿชผ\",\n \"๐Ÿฆž\",\n \"๐Ÿฆ€\",\n \"๐Ÿš\",\n \"๐Ÿฆญ\",\n \"๐ŸŸ\",\n \"๐Ÿฌ\",\n \"๐Ÿณ\",\n];\n\n/**\n * Encodes a 4-byte slice as a string of bytewords for identification.\n */\nexport function encodeBytewordsIdentifier(data: Uint8Array): string {\n if (data.length !== 4) {\n throw new Error(\"Identifier data must be exactly 4 bytes\");\n }\n const words: string[] = [];\n for (let i = 0; i < 4; i++) {\n const byte = data[i];\n if (byte === undefined) throw new Error(\"Invalid byte\");\n const word = BYTEWORDS[byte];\n if (word === \"\" || word === undefined) throw new Error(\"Invalid byteword mapping\");\n words.push(word);\n }\n return words.join(\" \");\n}\n\n/**\n * Encodes a 4-byte slice as a string of bytemojis for identification.\n */\nexport function encodeBytemojisIdentifier(data: Uint8Array): string {\n if (data.length !== 4) {\n throw new Error(\"Identifier data must be exactly 4 bytes\");\n }\n const emojis: string[] = [];\n for (let i = 0; i < 4; i++) {\n const byte = data[i];\n if (byte === undefined) throw new Error(\"Invalid byte\");\n const emoji = BYTEMOJIS[byte];\n if (emoji === \"\" || emoji === undefined) throw new Error(\"Invalid bytemoji mapping\");\n emojis.push(emoji);\n }\n return emojis.join(\" \");\n}\n\n/**\n * Bytewords encoding style.\n */\nexport enum BytewordsStyle {\n /** Full 4-letter words separated by spaces */\n Standard = \"standard\",\n /** Full 4-letter words separated by hyphens (URI-safe) */\n Uri = \"uri\",\n /** First and last character only (minimal) - used by UR encoding */\n Minimal = \"minimal\",\n}\n\n/**\n * Create a reverse mapping for minimal bytewords (first+last char) lookup.\n */\nfunction createMinimalBytewordsMap(): Map<string, number> {\n const map = new Map<string, number>();\n BYTEWORDS.forEach((word, index) => {\n // Minimal encoding uses first and last character\n const minimal = word[0] + word[3];\n map.set(minimal, index);\n });\n return map;\n}\n\nexport const MINIMAL_BYTEWORDS_MAP = createMinimalBytewordsMap();\n\n/**\n * CRC32 lookup table (IEEE polynomial).\n */\nconst CRC32_TABLE: number[] = (() => {\n const table: number[] = [];\n for (let i = 0; i < 256; i++) {\n let c = i;\n for (let j = 0; j < 8; j++) {\n c = (c & 1) !== 0 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;\n }\n table.push(c >>> 0);\n }\n return table;\n})();\n\n/**\n * Calculate CRC32 checksum of data.\n */\nexport function crc32(data: Uint8Array): number {\n let crc = 0xffffffff;\n for (const byte of data) {\n crc = (CRC32_TABLE[(crc ^ byte) & 0xff] ^ (crc >>> 8)) >>> 0;\n }\n return (crc ^ 0xffffffff) >>> 0;\n}\n\n/**\n * Convert a 32-bit number to 4 bytes (big-endian).\n */\nfunction uint32ToBytes(value: number): Uint8Array {\n return new Uint8Array([\n (value >>> 24) & 0xff,\n (value >>> 16) & 0xff,\n (value >>> 8) & 0xff,\n value & 0xff,\n ]);\n}\n\n/**\n * Encode data as bytewords with the specified style.\n * Includes CRC32 checksum.\n */\nexport function encodeBytewords(\n data: Uint8Array,\n style: BytewordsStyle = BytewordsStyle.Minimal,\n): string {\n // Append CRC32 checksum\n const checksum = crc32(data);\n const checksumBytes = uint32ToBytes(checksum);\n const dataWithChecksum = new Uint8Array(data.length + 4);\n dataWithChecksum.set(data);\n dataWithChecksum.set(checksumBytes, data.length);\n\n const words: string[] = [];\n for (const byte of dataWithChecksum) {\n const word = BYTEWORDS[byte];\n if (word === undefined) throw new Error(`Invalid byte value: ${byte}`);\n\n switch (style) {\n case BytewordsStyle.Standard:\n words.push(word);\n break;\n case BytewordsStyle.Uri:\n words.push(word);\n break;\n case BytewordsStyle.Minimal:\n // First and last character\n words.push(word[0] + word[3]);\n break;\n }\n }\n\n switch (style) {\n case BytewordsStyle.Standard:\n return words.join(\" \");\n case BytewordsStyle.Uri:\n return words.join(\"-\");\n case BytewordsStyle.Minimal:\n return words.join(\"\");\n }\n}\n\n/**\n * Decode bytewords string back to data.\n * Validates and removes CRC32 checksum.\n */\nexport function decodeBytewords(\n encoded: string,\n style: BytewordsStyle = BytewordsStyle.Minimal,\n): Uint8Array {\n const lowercased = encoded.toLowerCase();\n let bytes: number[];\n\n switch (style) {\n case BytewordsStyle.Standard: {\n const words = lowercased.split(\" \");\n bytes = words.map((word) => {\n const index = BYTEWORDS_MAP.get(word);\n if (index === undefined) {\n throw new Error(`Invalid byteword: ${word}`);\n }\n return index;\n });\n break;\n }\n case BytewordsStyle.Uri: {\n // 4-character words separated by hyphens\n const words = lowercased.split(\"-\");\n bytes = words.map((word) => {\n const index = BYTEWORDS_MAP.get(word);\n if (index === undefined) {\n throw new Error(`Invalid byteword: ${word}`);\n }\n return index;\n });\n break;\n }\n case BytewordsStyle.Minimal: {\n // 2-character minimal words with no separator\n if (lowercased.length % 2 !== 0) {\n throw new Error(\"Invalid minimal bytewords length\");\n }\n bytes = [];\n for (let i = 0; i < lowercased.length; i += 2) {\n const minimal = lowercased.slice(i, i + 2);\n const index = MINIMAL_BYTEWORDS_MAP.get(minimal);\n if (index === undefined) {\n throw new Error(`Invalid minimal byteword: ${minimal}`);\n }\n bytes.push(index);\n }\n break;\n }\n }\n\n if (bytes.length < 4) {\n throw new Error(\"Bytewords data too short (missing checksum)\");\n }\n\n // Extract data and checksum\n const dataWithChecksum = new Uint8Array(bytes);\n const data = dataWithChecksum.slice(0, -4);\n const checksumBytes = dataWithChecksum.slice(-4);\n\n // Verify checksum\n const expectedChecksum = crc32(data);\n const actualChecksum =\n ((checksumBytes[0] << 24) |\n (checksumBytes[1] << 16) |\n (checksumBytes[2] << 8) |\n checksumBytes[3]) >>>\n 0;\n\n if (expectedChecksum !== actualChecksum) {\n throw new Error(\n `Bytewords checksum mismatch: expected ${expectedChecksum.toString(16)}, got ${actualChecksum.toString(16)}`,\n );\n }\n\n return data;\n}\n","import { InvalidTypeError } from \"./error\";\nimport { isValidURType } from \"./utils\";\n\n/**\n * Represents a UR (Uniform Resource) type identifier.\n *\n * Valid UR types contain only lowercase letters, digits, and hyphens.\n *\n * @example\n * ```typescript\n * const urType = new URType('test');\n * console.log(urType.string()); // \"test\"\n * ```\n */\nexport class URType {\n private readonly _type: string;\n\n /**\n * Creates a new URType from the provided type string.\n *\n * @param urType - The UR type as a string\n * @throws {InvalidTypeError} If the type contains invalid characters\n *\n * @example\n * ```typescript\n * const urType = new URType('test');\n * ```\n */\n constructor(urType: string) {\n if (!isValidURType(urType)) {\n throw new InvalidTypeError();\n }\n this._type = urType;\n }\n\n /**\n * Returns the string representation of the URType.\n *\n * @example\n * ```typescript\n * const urType = new URType('test');\n * console.log(urType.string()); // \"test\"\n * ```\n */\n string(): string {\n return this._type;\n }\n\n /**\n * Checks equality with another URType based on the type string.\n */\n equals(other: URType): boolean {\n return this._type === other._type;\n }\n\n /**\n * Returns the string representation.\n */\n toString(): string {\n return this._type;\n }\n\n /**\n * Creates a URType from a string, throwing an error if invalid.\n *\n * @param value - The UR type string\n * @returns A new URType instance\n * @throws {InvalidTypeError} If the type is invalid\n */\n static from(value: string): URType {\n return new URType(value);\n }\n\n /**\n * Safely creates a URType, returning an error if invalid.\n *\n * @param value - The UR type string\n * @returns Either a URType or an error\n */\n static tryFrom(value: string): URType | InvalidTypeError {\n try {\n return new URType(value);\n } catch (error) {\n return error as InvalidTypeError;\n }\n }\n}\n","import type { Cbor } from \"@bcts/dcbor\";\nimport { decodeCbor } from \"@bcts/dcbor\";\nimport { InvalidSchemeError, TypeUnspecifiedError, UnexpectedTypeError, URError } from \"./error.js\";\nimport { URType } from \"./ur-type.js\";\nimport { encodeBytewords, decodeBytewords, BytewordsStyle } from \"./utils.js\";\n\n/**\n * A Uniform Resource (UR) is a URI-encoded CBOR object.\n *\n * URs are defined in [BCR-2020-005: Uniform Resources](https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-005-ur.md).\n *\n * @example\n * ```typescript\n * import { UR } from '@bcts/uniform-resources';\n * import { CBOR } from '@bcts/dcbor';\n *\n * // Create a UR from a CBOR object\n * const cbor = CBOR.fromArray([1, 2, 3]);\n * const ur = UR.new('test', cbor);\n *\n * // Encode to string\n * const urString = ur.string();\n * console.log(urString); // \"ur:test/...\"\n *\n * // Decode from string\n * const decodedUR = UR.fromURString(urString);\n * console.log(decodedUR.urTypeStr()); // \"test\"\n * ```\n */\nexport class UR {\n private readonly _urType: URType;\n private readonly _cbor: Cbor;\n\n /**\n * Creates a new UR from the provided type and CBOR data.\n *\n * @param urType - The UR type (will be validated)\n * @param cbor - The CBOR data to encode\n * @throws {InvalidTypeError} If the type is invalid\n *\n * @example\n * ```typescript\n * const ur = UR.new('bytes', CBOR.fromString('hello'));\n * ```\n */\n static new(urType: string | URType, cbor: Cbor): UR {\n const type = typeof urType === \"string\" ? new URType(urType) : urType;\n return new UR(type, cbor);\n }\n\n /**\n * Creates a new UR from a UR string.\n *\n * @param urString - A UR string like \"ur:test/...\"\n * @throws {InvalidSchemeError} If the string doesn't start with \"ur:\"\n * @throws {TypeUnspecifiedError} If no type is specified\n * @throws {NotSinglePartError} If the UR is multi-part\n * @throws {URError} If decoding fails\n *\n * @example\n * ```typescript\n * const ur = UR.fromURString('ur:test/lsadaoaxjygonesw');\n * ```\n */\n static fromURString(urString: string): UR {\n // Decode the UR string to get the type and CBOR data\n const decodedUR = URStringDecoder.decode(urString);\n if (decodedUR === null || decodedUR === undefined) {\n throw new URError(\"Failed to decode UR string\");\n }\n const { urType, cbor } = decodedUR;\n return new UR(new URType(urType), cbor);\n }\n\n private constructor(urType: URType, cbor: Cbor) {\n this._urType = urType;\n this._cbor = cbor;\n }\n\n /**\n * Returns the UR type.\n */\n urType(): URType {\n return this._urType;\n }\n\n /**\n * Returns the UR type as a string.\n */\n urTypeStr(): string {\n return this._urType.string();\n }\n\n /**\n * Returns the CBOR data.\n */\n cbor(): Cbor {\n return this._cbor;\n }\n\n /**\n * Returns the string representation of the UR (lowercase, suitable for display).\n *\n * @example\n * ```typescript\n * const ur = UR.new('test', CBOR.fromArray([1, 2, 3]));\n * console.log(ur.string()); // \"ur:test/lsadaoaxjygonesw\"\n * ```\n */\n string(): string {\n const cborData = this._cbor.toData();\n return URStringEncoder.encode(this._urType.string(), cborData);\n }\n\n /**\n * Returns the QR string representation (uppercase, most efficient for QR codes).\n */\n qrString(): string {\n return this.string().toUpperCase();\n }\n\n /**\n * Returns the QR data as bytes (uppercase UR string as UTF-8).\n */\n qrData(): Uint8Array {\n // Use a helper to convert string to bytes across platforms\n const str = this.qrString();\n const bytes = new Uint8Array(str.length);\n for (let i = 0; i < str.length; i++) {\n bytes[i] = str.charCodeAt(i);\n }\n return bytes;\n }\n\n /**\n * Checks if the UR type matches the expected type.\n *\n * @param expectedType - The expected type\n * @throws {UnexpectedTypeError} If the types don't match\n */\n checkType(expectedType: string | URType): void {\n const expected = typeof expectedType === \"string\" ? new URType(expectedType) : expectedType;\n if (!this._urType.equals(expected)) {\n throw new UnexpectedTypeError(expected.string(), this._urType.string());\n }\n }\n\n /**\n * Returns the string representation.\n */\n toString(): string {\n return this.string();\n }\n\n /**\n * Checks equality with another UR.\n */\n equals(other: UR): boolean {\n return (\n this._urType.equals(other._urType) &&\n this._cbor.toData().toString() === other._cbor.toData().toString()\n );\n }\n}\n\n/**\n * Encodes a UR string using Bytewords minimal encoding.\n * This handles single-part URs according to BCR-2020-005.\n */\nclass URStringEncoder {\n static encode(urType: string, cborData: Uint8Array): string {\n // Encode CBOR data using bytewords minimal style (with CRC32 checksum)\n const encoded = encodeBytewords(cborData, BytewordsStyle.Minimal);\n return `ur:${urType}/${encoded}`;\n }\n}\n\n/**\n * Decodes a UR string back to its components.\n */\nclass URStringDecoder {\n static decode(urString: string): { urType: string; cbor: Cbor } | null {\n const lowercased = urString.toLowerCase();\n\n // Check scheme\n if (!lowercased.startsWith(\"ur:\")) {\n throw new InvalidSchemeError();\n }\n\n // Strip scheme\n const afterScheme = lowercased.substring(3);\n\n // Split into type and data\n const [urType, ...dataParts] = afterScheme.split(\"/\");\n\n if (urType === \"\" || urType === undefined) {\n throw new TypeUnspecifiedError();\n }\n\n const data = dataParts.join(\"/\");\n if (data === \"\" || data === undefined) {\n throw new TypeUnspecifiedError();\n }\n\n try {\n // Decode the bytewords-encoded data (validates CRC32 checksum)\n const cborData = decodeBytewords(data, BytewordsStyle.Minimal);\n const cbor = decodeCbor(cborData);\n return { urType, cbor };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new URError(`Failed to decode UR: ${errorMessage}`);\n }\n }\n}\n","import type { UR } from \"./ur.js\";\n\n/**\n * A type that can be encoded to a UR (Uniform Resource).\n *\n * Types implementing this interface should be able to convert themselves\n * to CBOR data and associate that with a UR type identifier.\n *\n * @example\n * ```typescript\n * class MyType implements UREncodable {\n * toCBOR(): CBOR {\n * // Convert to CBOR\n * }\n *\n * ur(): UR {\n * const cbor = this.toCBOR();\n * return UR.new('mytype', cbor);\n * }\n * }\n * ```\n */\nexport interface UREncodable {\n /**\n * Returns the UR representation of the object.\n */\n ur(): UR;\n\n /**\n * Returns the UR string representation of the object.\n */\n urString(): string;\n}\n\n/**\n * Helper function to check if an object implements UREncodable.\n */\nexport function isUREncodable(obj: unknown): obj is UREncodable {\n return (\n typeof obj === \"object\" &&\n obj !== null &&\n \"ur\" in obj &&\n \"urString\" in obj &&\n typeof (obj as Record<string, unknown>)[\"ur\"] === \"function\" &&\n typeof (obj as Record<string, unknown>)[\"urString\"] === \"function\"\n );\n}\n","import type { UR } from \"./ur.js\";\n\n/**\n * A type that can be decoded from a UR (Uniform Resource).\n *\n * Types implementing this interface should be able to create themselves\n * from a UR containing their data.\n *\n * @example\n * ```typescript\n * class MyType implements URDecodable {\n * fromUR(ur: UR): MyType {\n * const cbor = ur.cbor();\n * // Decode from CBOR and return MyType instance\n * }\n *\n * fromURString(urString: string): MyType {\n * return this.fromUR(UR.fromURString(urString));\n * }\n * }\n * ```\n */\nexport interface URDecodable {\n /**\n * Creates an instance of this type from a UR.\n *\n * @param ur - The UR to decode from\n * @returns An instance of this type\n * @throws If the UR type is wrong or data is malformed\n */\n fromUR(ur: UR): unknown;\n\n /**\n * Creates an instance of this type from a UR string.\n *\n * This is a convenience method that parses the UR string and then\n * calls fromUR().\n *\n * @param urString - The UR string to decode from (e.g., \"ur:type/...\")\n * @returns An instance of this type\n * @throws If the UR string is invalid or data is malformed\n */\n fromURString?(urString: string): unknown;\n}\n\n/**\n * Helper function to check if an object implements URDecodable.\n */\nexport function isURDecodable(obj: unknown): obj is URDecodable {\n return (\n typeof obj === \"object\" &&\n obj !== null &&\n \"fromUR\" in obj &&\n typeof (obj as Record<string, unknown>)[\"fromUR\"] === \"function\"\n );\n}\n","import type { UREncodable } from \"./ur-encodable.js\";\nimport type { URDecodable } from \"./ur-decodable.js\";\n\n/**\n * A type that can be both encoded to and decoded from a UR.\n *\n * This combines the UREncodable and URDecodable interfaces for types\n * that support bidirectional UR conversion.\n *\n * @example\n * ```typescript\n * class MyType implements URCodable {\n * ur(): UR {\n * // Encode to UR\n * }\n *\n * urString(): string {\n * // Return UR string\n * }\n *\n * fromUR(ur: UR): MyType {\n * // Decode from UR\n * }\n *\n * fromURString(urString: string): MyType {\n * // Decode from UR string (convenience method)\n * return this.fromUR(UR.fromURString(urString));\n * }\n * }\n * ```\n */\nexport interface URCodable extends UREncodable, URDecodable {}\n\n/**\n * Helper function to check if an object implements URCodable.\n */\nexport function isURCodable(obj: unknown): obj is URCodable {\n return (\n typeof obj === \"object\" &&\n obj !== null &&\n \"ur\" in obj &&\n \"urString\" in obj &&\n \"fromUR\" in obj &&\n typeof (obj as Record<string, unknown>)[\"ur\"] === \"function\" &&\n typeof (obj as Record<string, unknown>)[\"urString\"] === \"function\" &&\n typeof (obj as Record<string, unknown>)[\"fromUR\"] === \"function\"\n );\n}\n","/**\n * Xoshiro256** PRNG implementation.\n *\n * This is a high-quality, fast pseudo-random number generator used\n * for deterministic fragment selection in fountain codes.\n *\n * Reference: https://prng.di.unimi.it/\n * BC-UR Reference: https://github.com/nicklockwood/fountain-codes\n */\n\nimport { sha256 } from \"@bcts/crypto\";\n\nconst MAX_UINT64 = BigInt(\"0xffffffffffffffff\");\n\n/**\n * Performs a left rotation on a 64-bit BigInt.\n */\nfunction rotl(x: bigint, k: number): bigint {\n const kBigInt = BigInt(k);\n return ((x << kBigInt) | (x >> (64n - kBigInt))) & MAX_UINT64;\n}\n\n/**\n * Xoshiro256** pseudo-random number generator.\n *\n * This PRNG is used for deterministic mixing in fountain codes,\n * allowing both encoder and decoder to agree on which fragments\n * are combined without transmitting that information.\n */\nexport class Xoshiro256 {\n private s: [bigint, bigint, bigint, bigint];\n\n /**\n * Creates a new Xoshiro256** instance from a 32-byte seed.\n *\n * The seed must be exactly 32 bytes (256 bits). The bytes are interpreted\n * using the BC-UR reference algorithm: each 8-byte chunk is read as\n * big-endian then stored as little-endian for the state.\n *\n * @param seed - The seed bytes (must be exactly 32 bytes)\n */\n constructor(seed: Uint8Array) {\n if (seed.length !== 32) {\n throw new Error(`Seed must be 32 bytes, got ${seed.length}`);\n }\n\n // BC-UR reference implementation:\n // For each 8-byte chunk, read as big-endian u64, then convert to little-endian bytes\n // This effectively swaps the byte order within each 8-byte segment\n const s: [bigint, bigint, bigint, bigint] = [0n, 0n, 0n, 0n];\n for (let i = 0; i < 4; i++) {\n // Read 8 bytes as big-endian u64\n let v = 0n;\n for (let n = 0; n < 8; n++) {\n v = (v << 8n) | BigInt(seed[8 * i + n] ?? 0);\n }\n s[i] = v;\n }\n\n this.s = s;\n }\n\n /**\n * Creates a Xoshiro256** instance from raw state values.\n * Useful for seeding with specific values.\n */\n static fromState(s0: bigint, s1: bigint, s2: bigint, s3: bigint): Xoshiro256 {\n const instance = Object.create(Xoshiro256.prototype) as Xoshiro256;\n instance.s = [s0, s1, s2, s3];\n return instance;\n }\n\n /**\n * Generates the next 64-bit random value.\n */\n next(): bigint {\n const result = (rotl((this.s[1] * 5n) & MAX_UINT64, 7) * 9n) & MAX_UINT64;\n\n const t = (this.s[1] << 17n) & MAX_UINT64;\n\n this.s[2] ^= this.s[0];\n this.s[3] ^= this.s[1];\n this.s[1] ^= this.s[2];\n this.s[0] ^= this.s[3];\n\n this.s[2] ^= t;\n this.s[3] = rotl(this.s[3], 45);\n\n return result;\n }\n\n /**\n * Generates a random double in [0, 1).\n * Matches BC-UR reference: self.next() as f64 / (u64::MAX as f64 + 1.0)\n */\n nextDouble(): number {\n const value = this.next();\n // u64::MAX as f64 + 1.0 = 18446744073709551616.0\n return Number(value) / 18446744073709551616.0;\n }\n\n /**\n * Generates a random integer in [low, high] (inclusive).\n * Matches BC-UR reference: (self.next_double() * ((high - low + 1) as f64)) as u64 + low\n */\n nextInt(low: number, high: number): number {\n const range = high - low + 1;\n return Math.floor(this.nextDouble() * range) + low;\n }\n\n /**\n * Generates a random byte [0, 255].\n */\n nextByte(): number {\n return Number(this.next() & 0xffn);\n }\n\n /**\n * Generates an array of random bytes.\n */\n nextData(count: number): Uint8Array {\n const result = new Uint8Array(count);\n for (let i = 0; i < count; i++) {\n result[i] = this.nextByte();\n }\n return result;\n }\n\n /**\n * Shuffles items by repeatedly picking random indices.\n * Matches BC-UR reference implementation.\n */\n shuffled<T>(items: T[]): T[] {\n const source = [...items];\n const shuffled: T[] = [];\n while (source.length > 0) {\n const index = this.nextInt(0, source.length - 1);\n const item = source.splice(index, 1)[0];\n if (item !== undefined) {\n shuffled.push(item);\n }\n }\n return shuffled;\n }\n\n /**\n * Chooses the degree (number of fragments to mix) using a weighted sampler.\n * Uses the robust soliton distribution with weights [1/1, 1/2, 1/3, ..., 1/n].\n * Matches BC-UR reference implementation.\n */\n chooseDegree(seqLen: number): number {\n // Create weights: [1/1, 1/2, 1/3, ..., 1/seqLen]\n const weights: number[] = [];\n for (let i = 1; i <= seqLen; i++) {\n weights.push(1.0 / i);\n }\n\n // Use Vose's alias method for weighted sampling\n const sampler = new WeightedSampler(weights);\n return sampler.next(this) + 1; // 1-indexed degree\n }\n}\n\n/**\n * Weighted sampler using Vose's alias method.\n * Allows O(1) sampling from a discrete probability distribution.\n */\nclass WeightedSampler {\n private readonly aliases: number[];\n private readonly probs: number[];\n\n constructor(weights: number[]) {\n const n = weights.length;\n if (n === 0) {\n throw new Error(\"Weights array cannot be empty\");\n }\n\n // Normalize weights\n const sum = weights.reduce((a, b) => a + b, 0);\n if (sum <= 0) {\n throw new Error(\"Weights must sum to a positive value\");\n }\n\n const normalized = weights.map((w) => (w * n) / sum);\n\n // Initialize alias table\n this.aliases = Array.from<number>({ length: n }).fill(0);\n this.probs = Array.from<number>({ length: n }).fill(0);\n\n // Partition into small and large\n const small: number[] = [];\n const large: number[] = [];\n\n for (let i = n - 1; i >= 0; i--) {\n if (normalized[i] < 1.0) {\n small.push(i);\n } else {\n large.push(i);\n }\n }\n\n // Build the alias table\n while (small.length > 0 && large.length > 0) {\n const a = small.pop();\n const g = large.pop();\n if (a === undefined || g === undefined) break;\n this.probs[a] = normalized[a] ?? 0;\n this.aliases[a] = g;\n const normalizedG = normalized[g] ?? 0;\n const normalizedA = normalized[a] ?? 0;\n normalized[g] = normalizedG + normalizedA - 1.0;\n if (normalized[g] !== undefined && normalized[g] < 1.0) {\n small.push(g);\n } else {\n large.push(g);\n }\n }\n\n while (large.length > 0) {\n const g = large.pop();\n if (g === undefined) break;\n this.probs[g] = 1.0;\n }\n\n while (small.length > 0) {\n const a = small.pop();\n if (a === undefined) break;\n this.probs[a] = 1.0;\n }\n }\n\n /**\n * Sample from the distribution.\n */\n next(rng: Xoshiro256): number {\n const r1 = rng.nextDouble();\n const r2 = rng.nextDouble();\n const n = this.probs.length;\n const i = Math.floor(n * r1);\n if (r2 < this.probs[i]) {\n return i;\n } else {\n return this.aliases[i];\n }\n }\n}\n\n/**\n * Creates a Xoshiro256 PRNG instance from message checksum and sequence number.\n *\n * This creates an 8-byte seed by concatenating seqNum and checksum (both in\n * big-endian), then hashes it with SHA-256 to get the 32-byte seed for Xoshiro.\n *\n * This matches the BC-UR reference implementation.\n */\nexport function createSeed(checksum: number, seqNum: number): Uint8Array {\n // Create 8-byte seed: seqNum (big-endian) || checksum (big-endian)\n const seed8 = new Uint8Array(8);\n\n // seqNum in big-endian (bytes 0-3)\n seed8[0] = (seqNum >>> 24) & 0xff;\n seed8[1] = (seqNum >>> 16) & 0xff;\n seed8[2] = (seqNum >>> 8) & 0xff;\n seed8[3] = seqNum & 0xff;\n\n // checksum in big-endian (bytes 4-7)\n seed8[4] = (checksum >>> 24) & 0xff;\n seed8[5] = (checksum >>> 16) & 0xff;\n seed8[6] = (checksum >>> 8) & 0xff;\n seed8[7] = checksum & 0xff;\n\n // Hash with SHA-256 to get 32 bytes\n return sha256(seed8);\n}\n","/**\n * Fountain code implementation for multipart URs.\n *\n * This implements a hybrid fixed-rate and rateless fountain code system\n * as specified in BCR-2020-005 and BCR-2024-001.\n *\n * Key concepts:\n * - Parts 1-seqLen are \"pure\" fragments (fixed-rate)\n * - Parts > seqLen are \"mixed\" fragments using XOR (rateless)\n * - Xoshiro256** PRNG ensures encoder/decoder agree on mixing\n */\n\nimport { Xoshiro256, createSeed } from \"./xoshiro.js\";\nimport { crc32 } from \"./utils.js\";\n\n/**\n * Represents a fountain code part with metadata.\n */\nexport interface FountainPart {\n /** Sequence number (1-based) */\n seqNum: number;\n /** Total number of pure fragments */\n seqLen: number;\n /** Length of original message */\n messageLen: number;\n /** CRC32 checksum of original message */\n checksum: number;\n /** Fragment data */\n data: Uint8Array;\n}\n\n/**\n * Splits data into fragments of the specified size.\n */\nexport function splitMessage(message: Uint8Array, fragmentLen: number): Uint8Array[] {\n const fragments: Uint8Array[] = [];\n const fragmentCount = Math.ceil(message.length / fragmentLen);\n\n for (let i = 0; i < fragmentCount; i++) {\n const start = i * fragmentLen;\n const end = Math.min(start + fragmentLen, message.length);\n const fragment = new Uint8Array(fragmentLen);\n\n // Copy data and pad with zeros if needed\n const sourceSlice = message.slice(start, end);\n fragment.set(sourceSlice);\n\n fragments.push(fragment);\n }\n\n return fragments;\n}\n\n/**\n * XOR two Uint8Arrays together.\n */\nexport function xorBytes(a: Uint8Array, b: Uint8Array): Uint8Array {\n const len = Math.max(a.length, b.length);\n const result = new Uint8Array(len);\n\n for (let i = 0; i < len; i++) {\n result[i] = (a[i] ?? 0) ^ (b[i] ?? 0);\n }\n\n return result;\n}\n\n/**\n * Chooses which fragments to mix for a given sequence number.\n *\n * This uses a seeded Xoshiro256** PRNG to deterministically select fragments,\n * ensuring encoder and decoder agree without explicit coordination.\n *\n * The algorithm matches the BC-UR reference implementation:\n * 1. For pure parts (seqNum <= seqLen), return single fragment index\n * 2. For mixed parts, use weighted sampling to choose degree\n * 3. Shuffle all indices and take the first 'degree' indices\n *\n * @param seqNum - The sequence number (1-based)\n * @param seqLen - Total number of pure fragments\n * @param checksum - CRC32 checksum of the message\n * @returns Array of fragment indices (0-based)\n */\nexport function chooseFragments(seqNum: number, seqLen: number, checksum: number): number[] {\n // Pure parts (seqNum <= seqLen) contain exactly one fragment\n if (seqNum <= seqLen) {\n return [seqNum - 1];\n }\n\n // Mixed parts use PRNG to select fragments\n const seed = createSeed(checksum, seqNum);\n const rng = new Xoshiro256(seed);\n\n // Choose degree using weighted sampler (1/k distribution)\n const degree = rng.chooseDegree(seqLen);\n\n // Create array of all indices [0, 1, 2, ..., seqLen-1]\n const allIndices: number[] = [];\n for (let i = 0; i < seqLen; i++) {\n allIndices.push(i);\n }\n\n // Shuffle all indices and take the first 'degree' indices\n const shuffled = rng.shuffled(allIndices);\n return shuffled.slice(0, degree);\n}\n\n/**\n * Mixes the selected fragments using XOR.\n */\nexport function mixFragments(fragments: Uint8Array[], indices: number[]): Uint8Array {\n if (indices.length === 0) {\n throw new Error(\"No fragments to mix\");\n }\n\n let result: Uint8Array = new Uint8Array(fragments[0].length);\n\n for (const index of indices) {\n const fragment = fragments[index];\n if (fragment === undefined) {\n throw new Error(`Fragment at index ${index} not found`);\n }\n result = xorBytes(result, fragment);\n }\n\n return result;\n}\n\n/**\n * Fountain encoder for creating multipart URs.\n */\nexport class FountainEncoder {\n private readonly fragments: Uint8Array[];\n private readonly messageLen: number;\n private readonly checksum: number;\n private seqNum = 0;\n\n /**\n * Creates a fountain encoder for the given message.\n *\n * @param message - The message to encode\n * @param maxFragmentLen - Maximum length of each fragment\n */\n constructor(message: Uint8Array, maxFragmentLen: number) {\n if (maxFragmentLen < 1) {\n throw new Error(\"Fragment length must be at least 1\");\n }\n\n this.messageLen = message.length;\n this.checksum = crc32(message);\n this.fragments = splitMessage(message, maxFragmentLen);\n }\n\n /**\n * Returns the number of pure fragments.\n */\n get seqLen(): number {\n return this.fragments.length;\n }\n\n /**\n * Returns whether the message fits in a single part.\n */\n isSinglePart(): boolean {\n return this.fragments.length === 1;\n }\n\n /**\n * Returns whether all pure parts have been emitted.\n */\n isComplete(): boolean {\n return this.seqNum >= this.seqLen;\n }\n\n /**\n * Generates the next fountain part.\n */\n nextPart(): FountainPart {\n this.seqNum++;\n\n const indices = chooseFragments(this.seqNum, this.seqLen, this.checksum);\n const data = mixFragments(this.fragments, indices);\n\n return {\n seqNum: this.seqNum,\n seqLen: this.seqLen,\n messageLen: this.messageLen,\n checksum: this.checksum,\n data,\n };\n }\n\n /**\n * Returns the current sequence number.\n */\n currentSeqNum(): number {\n return this.seqNum;\n }\n\n /**\n * Resets the encoder to start from the beginning.\n */\n reset(): void {\n this.seqNum = 0;\n }\n}\n\n/**\n * Fountain decoder for reassembling multipart URs.\n */\nexport class FountainDecoder {\n private seqLen: number | null = null;\n private messageLen: number | null = null;\n private checksum: number | null = null;\n\n // Storage for received data\n private readonly pureFragments = new Map<number, Uint8Array>();\n private readonly mixedParts = new Map<number, { indices: number[]; data: Uint8Array }>();\n\n /**\n * Receives a fountain part and attempts to decode.\n *\n * @param part - The fountain part to receive\n * @returns true if the message is now complete\n */\n receive(part: FountainPart): boolean {\n // Initialize on first part\n if (this.seqLen === null) {\n this.seqLen = part.seqLen;\n this.messageLen = part.messageLen;\n this.checksum = part.checksum;\n }\n\n // Validate consistency\n if (\n part.seqLen !== this.seqLen ||\n part.messageLen !== this.messageLen ||\n part.checksum !== this.checksum\n ) {\n throw new Error(\"Inconsistent part metadata\");\n }\n\n // Determine which fragments this part contains\n const indices = chooseFragments(part.seqNum, this.seqLen, this.checksum);\n\n if (indices.length === 1) {\n // Pure fragment (or degree-1 mixed that acts like pure)\n const index = indices[0];\n if (!this.pureFragments.has(index)) {\n this.pureFragments.set(index, part.data);\n }\n } else {\n // Mixed fragment - store for later reduction\n if (!this.mixedParts.has(part.seqNum)) {\n this.mixedParts.set(part.seqNum, { indices, data: part.data });\n }\n }\n\n // Try to reduce mixed parts\n this.reduceMixedParts();\n\n return this.isComplete();\n }\n\n /**\n * Attempts to extract pure fragments from mixed parts.\n */\n private reduceMixedParts(): void {\n let progress = true;\n\n while (progress) {\n progress = false;\n\n for (const [seqNum, mixed] of this.mixedParts) {\n // Find which indices we're missing\n const missing: number[] = [];\n let reduced = mixed.data;\n\n for (const index of mixed.indices) {\n const pure = this.pureFragments.get(index);\n if (pure !== undefined) {\n // XOR out the known fragment\n reduced = xorBytes(reduced, pure);\n } else {\n missing.push(index);\n }\n }\n\n if (missing.length === 0) {\n // All fragments known, remove this mixed part\n this.mixedParts.delete(seqNum);\n progress = true;\n } else if (missing.length === 1) {\n // Can extract the missing fragment\n const missingIndex = missing[0];\n this.pureFragments.set(missingIndex, reduced);\n this.mixedParts.delete(seqNum);\n progress = true;\n }\n }\n }\n }\n\n /**\n * Returns whether all fragments have been received.\n */\n isComplete(): boolean {\n if (this.seqLen === null) {\n return false;\n }\n\n return this.pureFragments.size === this.seqLen;\n }\n\n /**\n * Reconstructs the original message.\n *\n * @returns The original message, or null if not yet complete\n */\n message(): Uint8Array | null {\n if (!this.isComplete() || this.seqLen === null || this.messageLen === null) {\n return null;\n }\n\n // Calculate fragment size from first fragment\n const firstFragment = this.pureFragments.get(0);\n if (firstFragment === undefined) {\n return null;\n }\n\n const fragmentLen = firstFragment.length;\n const result = new Uint8Array(this.messageLen);\n\n // Assemble fragments\n for (let i = 0; i < this.seqLen; i++) {\n const fragment = this.pureFragments.get(i);\n if (fragment === undefined) {\n return null;\n }\n\n const start = i * fragmentLen;\n const end = Math.min(start + fragmentLen, this.messageLen);\n const len = end - start;\n\n result.set(fragment.slice(0, len), start);\n }\n\n // Verify checksum\n const actualChecksum = crc32(result);\n if (actualChecksum !== this.checksum) {\n throw new Error(`Checksum mismatch: expected ${this.checksum}, got ${actualChecksum}`);\n }\n\n return result;\n }\n\n /**\n * Returns the progress as a fraction (0 to 1).\n */\n progress(): number {\n if (this.seqLen === null) {\n return 0;\n }\n return this.pureFragments.size / this.seqLen;\n }\n\n /**\n * Resets the decoder.\n */\n reset(): void {\n this.seqLen = null;\n this.messageLen = null;\n this.checksum = null;\n this.pureFragments.clear();\n this.mixedParts.clear();\n }\n}\n","import type { UR } from \"./ur.js\";\nimport { URError } from \"./error.js\";\nimport { FountainEncoder, type FountainPart } from \"./fountain.js\";\nimport { encodeBytewords, BytewordsStyle } from \"./utils.js\";\nimport { cbor } from \"@bcts/dcbor\";\n\n/**\n * Encodes a UR as multiple parts using fountain codes.\n *\n * This allows large CBOR structures to be split into multiple UR strings\n * that can be transmitted separately and reassembled. The encoder uses\n * fountain codes for resilient transmission over lossy channels.\n *\n * For single-part URs (small payloads), use the regular UR.string() method.\n *\n * @example\n * ```typescript\n * const ur = UR.new('bytes', cbor);\n * const encoder = new MultipartEncoder(ur, 100);\n *\n * // Generate all pure parts\n * while (!encoder.isComplete()) {\n * const part = encoder.nextPart();\n * console.log(part); // \"ur:bytes/1-10/...\"\n * }\n *\n * // Generate additional rateless parts for redundancy\n * for (let i = 0; i < 5; i++) {\n * const part = encoder.nextPart();\n * console.log(part); // \"ur:bytes/11-10/...\"\n * }\n * ```\n */\nexport class MultipartEncoder {\n private readonly _ur: UR;\n private readonly _fountainEncoder: FountainEncoder;\n private _currentIndex = 0;\n\n /**\n * Creates a new multipart encoder for the given UR.\n *\n * @param ur - The UR to encode\n * @param maxFragmentLen - Maximum length of each fragment in bytes\n * @throws {URError} If encoding fails\n *\n * @example\n * ```typescript\n * const encoder = new MultipartEncoder(ur, 100);\n * ```\n */\n constructor(ur: UR, maxFragmentLen: number) {\n if (maxFragmentLen < 1) {\n throw new URError(\"Max fragment length must be at least 1\");\n }\n this._ur = ur;\n\n // Create fountain encoder from CBOR data\n const cborData = ur.cbor().toData();\n this._fountainEncoder = new FountainEncoder(cborData, maxFragmentLen);\n }\n\n /**\n * Gets the next part of the encoding.\n *\n * Parts 1 through seqLen are \"pure\" fragments containing one piece each.\n * Parts beyond seqLen are \"mixed\" fragments using fountain codes for redundancy.\n *\n * @returns The next UR string part\n *\n * @example\n * ```typescript\n * const part = encoder.nextPart();\n * // Returns: \"ur:bytes/1-3/lsadaoaxjygonesw\"\n * ```\n */\n nextPart(): string {\n const part = this._fountainEncoder.nextPart();\n this._currentIndex++;\n return this._encodePart(part);\n }\n\n /**\n * Encodes a fountain part as a UR string.\n */\n private _encodePart(part: FountainPart): string {\n // For single-part messages, use simple format\n if (part.seqLen === 1) {\n return this._ur.string();\n }\n\n // Encode the part data as CBOR: [seqNum, seqLen, messageLen, checksum, data]\n // Using a simple format: seqNum-seqLen prefix followed by bytewords-encoded part\n const partData = this._encodePartData(part);\n const encoded = encodeBytewords(partData, BytewordsStyle.Minimal);\n\n return `ur:${this._ur.urTypeStr()}/${part.seqNum}-${part.seqLen}/${encoded}`;\n }\n\n /**\n * Encodes part metadata and data as CBOR for bytewords encoding.\n * Format: CBOR array [seqNum, seqLen, messageLen, checksum, data]\n */\n private _encodePartData(part: FountainPart): Uint8Array {\n // Create CBOR array with 5 elements: [seqNum, seqLen, messageLen, checksum, data]\n const cborArray = cbor([part.seqNum, part.seqLen, part.messageLen, part.checksum, part.data]);\n\n return cborArray.toData();\n }\n\n /**\n * Gets the current part index.\n */\n currentIndex(): number {\n return this._currentIndex;\n }\n\n /**\n * Gets the total number of pure parts.\n *\n * Note: Fountain codes can generate unlimited parts beyond this count\n * for additional redundancy.\n */\n partsCount(): number {\n return this._fountainEncoder.seqLen;\n }\n}\n","import { decodeCbor, MajorType, type Cbor } from \"@bcts/dcbor\";\nimport { InvalidSchemeError, InvalidTypeError, UnexpectedTypeError, URError } from \"./error.js\";\nimport { UR } from \"./ur.js\";\nimport { URType } from \"./ur-type.js\";\nimport { FountainDecoder, type FountainPart } from \"./fountain.js\";\nimport { decodeBytewords, BytewordsStyle } from \"./utils.js\";\n\n/**\n * Decodes multiple UR parts back into a single UR.\n *\n * This reassembles multipart URs that were encoded using fountain codes.\n * The decoder can handle out-of-order reception and packet loss.\n *\n * @example\n * ```typescript\n * const decoder = new MultipartDecoder();\n *\n * for (const urPart of urParts) {\n * decoder.receive(urPart);\n * if (decoder.isComplete()) {\n * const ur = decoder.message();\n * break;\n * }\n * }\n * ```\n */\nexport class MultipartDecoder {\n private _urType: URType | null = null;\n private _fountainDecoder: FountainDecoder | null = null;\n private _decodedMessage: UR | null = null;\n\n /**\n * Receives a UR part string.\n *\n * @param part - A UR part string (e.g., \"ur:bytes/1-10/...\" or \"ur:bytes/...\")\n * @throws {InvalidSchemeError} If the part doesn't start with \"ur:\"\n * @throws {UnexpectedTypeError} If the type doesn't match previous parts\n */\n receive(part: string): void {\n const { urType, partInfo } = this._parsePart(part);\n\n // Validate type consistency\n if (this._urType === null) {\n this._urType = urType;\n } else if (!this._urType.equals(urType)) {\n throw new UnexpectedTypeError(this._urType.string(), urType.string());\n }\n\n // Handle the part\n if (partInfo.isSinglePart) {\n // Single-part UR - decode immediately\n this._decodedMessage = UR.fromURString(part);\n } else {\n // Multipart UR - use fountain decoder\n this._fountainDecoder ??= new FountainDecoder();\n\n const fountainPart = this._decodeFountainPart(partInfo);\n this._fountainDecoder.receive(fountainPart);\n\n // Try to get the complete message\n if (this._fountainDecoder.isComplete()) {\n const message = this._fountainDecoder.message();\n if (message !== null) {\n const cbor = decodeCbor(message);\n this._decodedMessage = UR.new(this._urType, cbor);\n }\n }\n }\n }\n\n /**\n * Parses a UR part string to extract type and part info.\n */\n private _parsePart(part: string): { urType: URType; partInfo: PartInfo } {\n const lowercased = part.toLowerCase();\n\n if (!lowercased.startsWith(\"ur:\")) {\n throw new InvalidSchemeError();\n }\n\n const afterScheme = lowercased.substring(3);\n const components = afterScheme.split(\"/\");\n\n if (components.length === 0 || components[0] === \"\") {\n throw new InvalidTypeError();\n }\n\n const urType = new URType(components[0]);\n\n // Check if this is a multipart UR (format: type/seqNum-seqLen/data)\n if (components.length >= 3) {\n const seqPart = components[1];\n const seqMatch = /^(\\d+)-(\\d+)$/.exec(seqPart);\n\n if (seqMatch !== null) {\n const seqNum = parseInt(seqMatch[1], 10);\n const seqLen = parseInt(seqMatch[2], 10);\n const encodedData = components.slice(2).join(\"/\");\n\n return {\n urType,\n partInfo: {\n isSinglePart: false,\n seqNum,\n seqLen,\n encodedData,\n },\n };\n }\n }\n\n // Single-part UR\n return {\n urType,\n partInfo: { isSinglePart: true },\n };\n }\n\n /**\n * Decodes a multipart UR's fountain part data.\n *\n * The multipart body is a CBOR array: [seqNum, seqLen, messageLen, checksum, data]\n */\n private _decodeFountainPart(partInfo: MultipartInfo): FountainPart {\n // Decode bytewords to get CBOR data\n const cborData = decodeBytewords(partInfo.encodedData, BytewordsStyle.Minimal);\n\n // Decode the CBOR array\n const decoded = decodeCbor(cborData);\n\n // The decoded value should be an array with 5 elements\n if (decoded.type !== MajorType.Array) {\n throw new URError(\"Invalid multipart data: expected CBOR array\");\n }\n\n const items = decoded.value as Cbor[];\n if (items.length !== 5) {\n throw new URError(`Invalid multipart data: expected 5 elements, got ${items.length}`);\n }\n\n // Extract the fields: [seqNum, seqLen, messageLen, checksum, data]\n const seqNum = Number(items[0].value);\n const seqLen = Number(items[1].value);\n const messageLen = Number(items[2].value);\n const checksum = Number(items[3].value);\n const data = items[4].value as Uint8Array;\n\n // Verify seqNum and seqLen match the URL path values\n if (seqNum !== partInfo.seqNum || seqLen !== partInfo.seqLen) {\n throw new URError(\n `Multipart metadata mismatch: URL says ${partInfo.seqNum}-${partInfo.seqLen}, CBOR says ${seqNum}-${seqLen}`,\n );\n }\n\n return {\n seqNum,\n seqLen,\n messageLen,\n checksum,\n data,\n };\n }\n\n /**\n * Checks if the message is complete.\n */\n isComplete(): boolean {\n return this._decodedMessage !== null;\n }\n\n /**\n * Gets the decoded UR message.\n *\n * @returns The decoded UR, or null if not yet complete\n */\n message(): UR | null {\n return this._decodedMessage;\n }\n}\n\n/**\n * Part info for single-part URs.\n */\ninterface SinglePartInfo {\n isSinglePart: true;\n}\n\n/**\n * Part info for multipart URs.\n */\ninterface MultipartInfo {\n isSinglePart: false;\n seqNum: number;\n seqLen: number;\n encodedData: string;\n}\n\ntype PartInfo = SinglePartInfo | MultipartInfo;\n"],"mappings":";;;;;;;;AAGA,IAAa,UAAb,cAA6B,MAAM;CACjC,YAAY,SAAiB;AAC3B,QAAM,QAAQ;AACd,OAAK,OAAO;;;;;;AAOhB,IAAa,qBAAb,cAAwC,QAAQ;CAC9C,cAAc;AACZ,QAAM,oBAAoB;AAC1B,OAAK,OAAO;;;;;;AAOhB,IAAa,uBAAb,cAA0C,QAAQ;CAChD,cAAc;AACZ,QAAM,uBAAuB;AAC7B,OAAK,OAAO;;;;;;AAOhB,IAAa,mBAAb,cAAsC,QAAQ;CAC5C,cAAc;AACZ,QAAM,kBAAkB;AACxB,OAAK,OAAO;;;;;;AAOhB,IAAa,qBAAb,cAAwC,QAAQ;CAC9C,cAAc;AACZ,QAAM,0BAA0B;AAChC,OAAK,OAAO;;;;;;AAOhB,IAAa,sBAAb,cAAyC,QAAQ;CAC/C,YAAY,UAAkB,OAAe;AAC3C,QAAM,oBAAoB,SAAS,cAAc,QAAQ;AACzD,OAAK,OAAO;;;;;;AAOhB,IAAa,iBAAb,cAAoC,QAAQ;CAC1C,YAAY,SAAiB;AAC3B,QAAM,oBAAoB,UAAU;AACpC,OAAK,OAAO;;;;;;AAOhB,IAAa,YAAb,cAA+B,QAAQ;CACrC,YAAY,SAAiB;AAC3B,QAAM,eAAe,UAAU;AAC/B,OAAK,OAAO;;;;;;;AAQhB,IAAa,gBAAb,cAAmC,QAAQ;CACzC,YAAY,SAAiB;AAC3B,QAAM,qBAAqB,QAAQ,GAAG;AACtC,OAAK,OAAO;;;;;;AAShB,SAAgB,QAAQ,QAAkC;AACxD,QAAO,kBAAkB;;;;;;;;;AC3F3B,SAAgB,aAAa,MAAuB;CAClD,MAAM,OAAO,KAAK,WAAW,EAAE;AAE/B,KAAI,QAAQ,MAAM,QAAQ,IAAK,QAAO;AAEtC,KAAI,QAAQ,MAAM,QAAQ,GAAI,QAAO;AAErC,KAAI,SAAS,GAAI,QAAO;AACxB,QAAO;;;;;;AAOT,SAAgB,cAAc,QAAyB;AACrD,KAAI,OAAO,WAAW,EAAG,QAAO;AAChC,QAAO,MAAM,KAAK,OAAO,CAAC,OAAO,SAAS,aAAa,KAAK,CAAC;;;;;;AAiB/D,MAAa,YAAsB;CACjC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;;;;AAKD,SAAS,qBAA0C;CACjD,MAAM,sBAAM,IAAI,KAAqB;AACrC,WAAU,SAAS,MAAM,UAAU;AACjC,MAAI,IAAI,MAAM,MAAM;GACpB;AACF,QAAO;;AAGT,MAAa,gBAAgB,oBAAoB;;;;;AAMjD,MAAa,YAAsB;CACjC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;;;;AAKD,SAAgB,0BAA0B,MAA0B;AAClE,KAAI,KAAK,WAAW,EAClB,OAAM,IAAI,MAAM,0CAA0C;CAE5D,MAAM,QAAkB,EAAE;AAC1B,MAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK;EAC1B,MAAM,OAAO,KAAK;AAClB,MAAI,SAAS,OAAW,OAAM,IAAI,MAAM,eAAe;EACvD,MAAM,OAAO,UAAU;AACvB,MAAI,SAAS,MAAM,SAAS,OAAW,OAAM,IAAI,MAAM,2BAA2B;AAClF,QAAM,KAAK,KAAK;;AAElB,QAAO,MAAM,KAAK,IAAI;;;;;AAMxB,SAAgB,0BAA0B,MAA0B;AAClE,KAAI,KAAK,WAAW,EAClB,OAAM,IAAI,MAAM,0CAA0C;CAE5D,MAAM,SAAmB,EAAE;AAC3B,MAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK;EAC1B,MAAM,OAAO,KAAK;AAClB,MAAI,SAAS,OAAW,OAAM,IAAI,MAAM,eAAe;EACvD,MAAM,QAAQ,UAAU;AACxB,MAAI,UAAU,MAAM,UAAU,OAAW,OAAM,IAAI,MAAM,2BAA2B;AACpF,SAAO,KAAK,MAAM;;AAEpB,QAAO,OAAO,KAAK,IAAI;;;;;AAMzB,IAAY,0DAAL;;AAEL;;AAEA;;AAEA;;;;;;AAMF,SAAS,4BAAiD;CACxD,MAAM,sBAAM,IAAI,KAAqB;AACrC,WAAU,SAAS,MAAM,UAAU;EAEjC,MAAM,UAAU,KAAK,KAAK,KAAK;AAC/B,MAAI,IAAI,SAAS,MAAM;GACvB;AACF,QAAO;;AAGT,MAAa,wBAAwB,2BAA2B;;;;AAKhE,MAAM,qBAA+B;CACnC,MAAM,QAAkB,EAAE;AAC1B,MAAK,IAAI,IAAI,GAAG,IAAI,KAAK,KAAK;EAC5B,IAAI,IAAI;AACR,OAAK,IAAI,IAAI,GAAG,IAAI,GAAG,IACrB,MAAK,IAAI,OAAO,IAAI,aAAc,MAAM,IAAK,MAAM;AAErD,QAAM,KAAK,MAAM,EAAE;;AAErB,QAAO;IACL;;;;AAKJ,SAAgB,MAAM,MAA0B;CAC9C,IAAI,MAAM;AACV,MAAK,MAAM,QAAQ,KACjB,QAAO,aAAa,MAAM,QAAQ,OAAS,QAAQ,OAAQ;AAE7D,SAAQ,MAAM,gBAAgB;;;;;AAMhC,SAAS,cAAc,OAA2B;AAChD,QAAO,IAAI,WAAW;EACnB,UAAU,KAAM;EAChB,UAAU,KAAM;EAChB,UAAU,IAAK;EAChB,QAAQ;EACT,CAAC;;;;;;AAOJ,SAAgB,gBACd,MACA,QAAwB,eAAe,SAC/B;CAGR,MAAM,gBAAgB,cADL,MAAM,KAAK,CACiB;CAC7C,MAAM,mBAAmB,IAAI,WAAW,KAAK,SAAS,EAAE;AACxD,kBAAiB,IAAI,KAAK;AAC1B,kBAAiB,IAAI,eAAe,KAAK,OAAO;CAEhD,MAAM,QAAkB,EAAE;AAC1B,MAAK,MAAM,QAAQ,kBAAkB;EACnC,MAAM,OAAO,UAAU;AACvB,MAAI,SAAS,OAAW,OAAM,IAAI,MAAM,uBAAuB,OAAO;AAEtE,UAAQ,OAAR;GACE,KAAK,eAAe;AAClB,UAAM,KAAK,KAAK;AAChB;GACF,KAAK,eAAe;AAClB,UAAM,KAAK,KAAK;AAChB;GACF,KAAK,eAAe;AAElB,UAAM,KAAK,KAAK,KAAK,KAAK,GAAG;AAC7B;;;AAIN,SAAQ,OAAR;EACE,KAAK,eAAe,SAClB,QAAO,MAAM,KAAK,IAAI;EACxB,KAAK,eAAe,IAClB,QAAO,MAAM,KAAK,IAAI;EACxB,KAAK,eAAe,QAClB,QAAO,MAAM,KAAK,GAAG;;;;;;;AAQ3B,SAAgB,gBACd,SACA,QAAwB,eAAe,SAC3B;CACZ,MAAM,aAAa,QAAQ,aAAa;CACxC,IAAI;AAEJ,SAAQ,OAAR;EACE,KAAK,eAAe;AAElB,WADc,WAAW,MAAM,IAAI,CACrB,KAAK,SAAS;IAC1B,MAAM,QAAQ,cAAc,IAAI,KAAK;AACrC,QAAI,UAAU,OACZ,OAAM,IAAI,MAAM,qBAAqB,OAAO;AAE9C,WAAO;KACP;AACF;EAEF,KAAK,eAAe;AAGlB,WADc,WAAW,MAAM,IAAI,CACrB,KAAK,SAAS;IAC1B,MAAM,QAAQ,cAAc,IAAI,KAAK;AACrC,QAAI,UAAU,OACZ,OAAM,IAAI,MAAM,qBAAqB,OAAO;AAE9C,WAAO;KACP;AACF;EAEF,KAAK,eAAe;AAElB,OAAI,WAAW,SAAS,MAAM,EAC5B,OAAM,IAAI,MAAM,mCAAmC;AAErD,WAAQ,EAAE;AACV,QAAK,IAAI,IAAI,GAAG,IAAI,WAAW,QAAQ,KAAK,GAAG;IAC7C,MAAM,UAAU,WAAW,MAAM,GAAG,IAAI,EAAE;IAC1C,MAAM,QAAQ,sBAAsB,IAAI,QAAQ;AAChD,QAAI,UAAU,OACZ,OAAM,IAAI,MAAM,6BAA6B,UAAU;AAEzD,UAAM,KAAK,MAAM;;AAEnB;;AAIJ,KAAI,MAAM,SAAS,EACjB,OAAM,IAAI,MAAM,8CAA8C;CAIhE,MAAM,mBAAmB,IAAI,WAAW,MAAM;CAC9C,MAAM,OAAO,iBAAiB,MAAM,GAAG,GAAG;CAC1C,MAAM,gBAAgB,iBAAiB,MAAM,GAAG;CAGhD,MAAM,mBAAmB,MAAM,KAAK;CACpC,MAAM,kBACF,cAAc,MAAM,KACnB,cAAc,MAAM,KACpB,cAAc,MAAM,IACrB,cAAc,QAChB;AAEF,KAAI,qBAAqB,eACvB,OAAM,IAAI,MACR,yCAAyC,iBAAiB,SAAS,GAAG,CAAC,QAAQ,eAAe,SAAS,GAAG,GAC3G;AAGH,QAAO;;;;;;;;;;;;;;;;AC/wBT,IAAa,SAAb,MAAa,OAAO;CAClB,AAAiB;;;;;;;;;;;;CAajB,YAAY,QAAgB;AAC1B,MAAI,CAAC,cAAc,OAAO,CACxB,OAAM,IAAI,kBAAkB;AAE9B,OAAK,QAAQ;;;;;;;;;;;CAYf,SAAiB;AACf,SAAO,KAAK;;;;;CAMd,OAAO,OAAwB;AAC7B,SAAO,KAAK,UAAU,MAAM;;;;;CAM9B,WAAmB;AACjB,SAAO,KAAK;;;;;;;;;CAUd,OAAO,KAAK,OAAuB;AACjC,SAAO,IAAI,OAAO,MAAM;;;;;;;;CAS1B,OAAO,QAAQ,OAA0C;AACvD,MAAI;AACF,UAAO,IAAI,OAAO,MAAM;WACjB,OAAO;AACd,UAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACtDb,IAAa,KAAb,MAAa,GAAG;CACd,AAAiB;CACjB,AAAiB;;;;;;;;;;;;;CAcjB,OAAO,IAAI,QAAyB,MAAgB;AAElD,SAAO,IAAI,GADE,OAAO,WAAW,WAAW,IAAI,OAAO,OAAO,GAAG,QAC3C,KAAK;;;;;;;;;;;;;;;;CAiB3B,OAAO,aAAa,UAAsB;EAExC,MAAM,YAAY,gBAAgB,OAAO,SAAS;AAClD,MAAI,cAAc,QAAQ,cAAc,OACtC,OAAM,IAAI,QAAQ,6BAA6B;EAEjD,MAAM,EAAE,QAAQ,SAAS;AACzB,SAAO,IAAI,GAAG,IAAI,OAAO,OAAO,EAAE,KAAK;;CAGzC,AAAQ,YAAY,QAAgB,MAAY;AAC9C,OAAK,UAAU;AACf,OAAK,QAAQ;;;;;CAMf,SAAiB;AACf,SAAO,KAAK;;;;;CAMd,YAAoB;AAClB,SAAO,KAAK,QAAQ,QAAQ;;;;;CAM9B,OAAa;AACX,SAAO,KAAK;;;;;;;;;;;CAYd,SAAiB;EACf,MAAM,WAAW,KAAK,MAAM,QAAQ;AACpC,SAAO,gBAAgB,OAAO,KAAK,QAAQ,QAAQ,EAAE,SAAS;;;;;CAMhE,WAAmB;AACjB,SAAO,KAAK,QAAQ,CAAC,aAAa;;;;;CAMpC,SAAqB;EAEnB,MAAM,MAAM,KAAK,UAAU;EAC3B,MAAM,QAAQ,IAAI,WAAW,IAAI,OAAO;AACxC,OAAK,IAAI,IAAI,GAAG,IAAI,IAAI,QAAQ,IAC9B,OAAM,KAAK,IAAI,WAAW,EAAE;AAE9B,SAAO;;;;;;;;CAST,UAAU,cAAqC;EAC7C,MAAM,WAAW,OAAO,iBAAiB,WAAW,IAAI,OAAO,aAAa,GAAG;AAC/E,MAAI,CAAC,KAAK,QAAQ,OAAO,SAAS,CAChC,OAAM,IAAI,oBAAoB,SAAS,QAAQ,EAAE,KAAK,QAAQ,QAAQ,CAAC;;;;;CAO3E,WAAmB;AACjB,SAAO,KAAK,QAAQ;;;;;CAMtB,OAAO,OAAoB;AACzB,SACE,KAAK,QAAQ,OAAO,MAAM,QAAQ,IAClC,KAAK,MAAM,QAAQ,CAAC,UAAU,KAAK,MAAM,MAAM,QAAQ,CAAC,UAAU;;;;;;;AASxE,IAAM,kBAAN,MAAsB;CACpB,OAAO,OAAO,QAAgB,UAA8B;AAG1D,SAAO,MAAM,OAAO,GADJ,gBAAgB,UAAU,eAAe,QAAQ;;;;;;AAQrE,IAAM,kBAAN,MAAsB;CACpB,OAAO,OAAO,UAAyD;EACrE,MAAM,aAAa,SAAS,aAAa;AAGzC,MAAI,CAAC,WAAW,WAAW,MAAM,CAC/B,OAAM,IAAI,oBAAoB;EAOhC,MAAM,CAAC,QAAQ,GAAG,aAHE,WAAW,UAAU,EAAE,CAGA,MAAM,IAAI;AAErD,MAAI,WAAW,MAAM,WAAW,OAC9B,OAAM,IAAI,sBAAsB;EAGlC,MAAM,OAAO,UAAU,KAAK,IAAI;AAChC,MAAI,SAAS,MAAM,SAAS,OAC1B,OAAM,IAAI,sBAAsB;AAGlC,MAAI;AAIF,UAAO;IAAE;IAAQ,kCAFA,gBAAgB,MAAM,eAAe,QAAQ,CAC7B;IACV;WAChB,OAAO;AAEd,SAAM,IAAI,QAAQ,wBADG,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,GAClB;;;;;;;;;;AC9K/D,SAAgB,cAAc,KAAkC;AAC9D,QACE,OAAO,QAAQ,YACf,QAAQ,QACR,QAAQ,OACR,cAAc,OACd,OAAQ,IAAgC,UAAU,cAClD,OAAQ,IAAgC,gBAAgB;;;;;;;;ACI5D,SAAgB,cAAc,KAAkC;AAC9D,QACE,OAAO,QAAQ,YACf,QAAQ,QACR,YAAY,OACZ,OAAQ,IAAgC,cAAc;;;;;;;;ACjB1D,SAAgB,YAAY,KAAgC;AAC1D,QACE,OAAO,QAAQ,YACf,QAAQ,QACR,QAAQ,OACR,cAAc,OACd,YAAY,OACZ,OAAQ,IAAgC,UAAU,cAClD,OAAQ,IAAgC,gBAAgB,cACxD,OAAQ,IAAgC,cAAc;;;;;;;;;;;;;;ACjC1D,MAAM,aAAa,OAAO,qBAAqB;;;;AAK/C,SAAS,KAAK,GAAW,GAAmB;CAC1C,MAAM,UAAU,OAAO,EAAE;AACzB,SAAS,KAAK,UAAY,KAAM,MAAM,WAAa;;;;;;;;;AAUrD,IAAa,aAAb,MAAa,WAAW;CACtB,AAAQ;;;;;;;;;;CAWR,YAAY,MAAkB;AAC5B,MAAI,KAAK,WAAW,GAClB,OAAM,IAAI,MAAM,8BAA8B,KAAK,SAAS;EAM9D,MAAM,IAAsC;GAAC;GAAI;GAAI;GAAI;GAAG;AAC5D,OAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK;GAE1B,IAAI,IAAI;AACR,QAAK,IAAI,IAAI,GAAG,IAAI,GAAG,IACrB,KAAK,KAAK,KAAM,OAAO,KAAK,IAAI,IAAI,MAAM,EAAE;AAE9C,KAAE,KAAK;;AAGT,OAAK,IAAI;;;;;;CAOX,OAAO,UAAU,IAAY,IAAY,IAAY,IAAwB;EAC3E,MAAM,WAAW,OAAO,OAAO,WAAW,UAAU;AACpD,WAAS,IAAI;GAAC;GAAI;GAAI;GAAI;GAAG;AAC7B,SAAO;;;;;CAMT,OAAe;EACb,MAAM,SAAU,KAAM,KAAK,EAAE,KAAK,KAAM,YAAY,EAAE,GAAG,KAAM;EAE/D,MAAM,IAAK,KAAK,EAAE,MAAM,MAAO;AAE/B,OAAK,EAAE,MAAM,KAAK,EAAE;AACpB,OAAK,EAAE,MAAM,KAAK,EAAE;AACpB,OAAK,EAAE,MAAM,KAAK,EAAE;AACpB,OAAK,EAAE,MAAM,KAAK,EAAE;AAEpB,OAAK,EAAE,MAAM;AACb,OAAK,EAAE,KAAK,KAAK,KAAK,EAAE,IAAI,GAAG;AAE/B,SAAO;;;;;;CAOT,aAAqB;EACnB,MAAM,QAAQ,KAAK,MAAM;AAEzB,SAAO,OAAO,MAAM,GAAG;;;;;;CAOzB,QAAQ,KAAa,MAAsB;EACzC,MAAM,QAAQ,OAAO,MAAM;AAC3B,SAAO,KAAK,MAAM,KAAK,YAAY,GAAG,MAAM,GAAG;;;;;CAMjD,WAAmB;AACjB,SAAO,OAAO,KAAK,MAAM,GAAG,KAAM;;;;;CAMpC,SAAS,OAA2B;EAClC,MAAM,SAAS,IAAI,WAAW,MAAM;AACpC,OAAK,IAAI,IAAI,GAAG,IAAI,OAAO,IACzB,QAAO,KAAK,KAAK,UAAU;AAE7B,SAAO;;;;;;CAOT,SAAY,OAAiB;EAC3B,MAAM,SAAS,CAAC,GAAG,MAAM;EACzB,MAAM,WAAgB,EAAE;AACxB,SAAO,OAAO,SAAS,GAAG;GACxB,MAAM,QAAQ,KAAK,QAAQ,GAAG,OAAO,SAAS,EAAE;GAChD,MAAM,OAAO,OAAO,OAAO,OAAO,EAAE,CAAC;AACrC,OAAI,SAAS,OACX,UAAS,KAAK,KAAK;;AAGvB,SAAO;;;;;;;CAQT,aAAa,QAAwB;EAEnC,MAAM,UAAoB,EAAE;AAC5B,OAAK,IAAI,IAAI,GAAG,KAAK,QAAQ,IAC3B,SAAQ,KAAK,IAAM,EAAE;AAKvB,SADgB,IAAI,gBAAgB,QAAQ,CAC7B,KAAK,KAAK,GAAG;;;;;;;AAQhC,IAAM,kBAAN,MAAsB;CACpB,AAAiB;CACjB,AAAiB;CAEjB,YAAY,SAAmB;EAC7B,MAAM,IAAI,QAAQ;AAClB,MAAI,MAAM,EACR,OAAM,IAAI,MAAM,gCAAgC;EAIlD,MAAM,MAAM,QAAQ,QAAQ,GAAG,MAAM,IAAI,GAAG,EAAE;AAC9C,MAAI,OAAO,EACT,OAAM,IAAI,MAAM,uCAAuC;EAGzD,MAAM,aAAa,QAAQ,KAAK,MAAO,IAAI,IAAK,IAAI;AAGpD,OAAK,UAAU,MAAM,KAAa,EAAE,QAAQ,GAAG,CAAC,CAAC,KAAK,EAAE;AACxD,OAAK,QAAQ,MAAM,KAAa,EAAE,QAAQ,GAAG,CAAC,CAAC,KAAK,EAAE;EAGtD,MAAM,QAAkB,EAAE;EAC1B,MAAM,QAAkB,EAAE;AAE1B,OAAK,IAAI,IAAI,IAAI,GAAG,KAAK,GAAG,IAC1B,KAAI,WAAW,KAAK,EAClB,OAAM,KAAK,EAAE;MAEb,OAAM,KAAK,EAAE;AAKjB,SAAO,MAAM,SAAS,KAAK,MAAM,SAAS,GAAG;GAC3C,MAAM,IAAI,MAAM,KAAK;GACrB,MAAM,IAAI,MAAM,KAAK;AACrB,OAAI,MAAM,UAAa,MAAM,OAAW;AACxC,QAAK,MAAM,KAAK,WAAW,MAAM;AACjC,QAAK,QAAQ,KAAK;AAGlB,cAAW,MAFS,WAAW,MAAM,MACjB,WAAW,MAAM,KACO;AAC5C,OAAI,WAAW,OAAO,UAAa,WAAW,KAAK,EACjD,OAAM,KAAK,EAAE;OAEb,OAAM,KAAK,EAAE;;AAIjB,SAAO,MAAM,SAAS,GAAG;GACvB,MAAM,IAAI,MAAM,KAAK;AACrB,OAAI,MAAM,OAAW;AACrB,QAAK,MAAM,KAAK;;AAGlB,SAAO,MAAM,SAAS,GAAG;GACvB,MAAM,IAAI,MAAM,KAAK;AACrB,OAAI,MAAM,OAAW;AACrB,QAAK,MAAM,KAAK;;;;;;CAOpB,KAAK,KAAyB;EAC5B,MAAM,KAAK,IAAI,YAAY;EAC3B,MAAM,KAAK,IAAI,YAAY;EAC3B,MAAM,IAAI,KAAK,MAAM;EACrB,MAAM,IAAI,KAAK,MAAM,IAAI,GAAG;AAC5B,MAAI,KAAK,KAAK,MAAM,GAClB,QAAO;MAEP,QAAO,KAAK,QAAQ;;;;;;;;;;;AAa1B,SAAgB,WAAW,UAAkB,QAA4B;CAEvE,MAAM,QAAQ,IAAI,WAAW,EAAE;AAG/B,OAAM,KAAM,WAAW,KAAM;AAC7B,OAAM,KAAM,WAAW,KAAM;AAC7B,OAAM,KAAM,WAAW,IAAK;AAC5B,OAAM,KAAK,SAAS;AAGpB,OAAM,KAAM,aAAa,KAAM;AAC/B,OAAM,KAAM,aAAa,KAAM;AAC/B,OAAM,KAAM,aAAa,IAAK;AAC9B,OAAM,KAAK,WAAW;AAGtB,iCAAc,MAAM;;;;;;;;;;;;;;;;;;;AC9OtB,SAAgB,aAAa,SAAqB,aAAmC;CACnF,MAAM,YAA0B,EAAE;CAClC,MAAM,gBAAgB,KAAK,KAAK,QAAQ,SAAS,YAAY;AAE7D,MAAK,IAAI,IAAI,GAAG,IAAI,eAAe,KAAK;EACtC,MAAM,QAAQ,IAAI;EAClB,MAAM,MAAM,KAAK,IAAI,QAAQ,aAAa,QAAQ,OAAO;EACzD,MAAM,WAAW,IAAI,WAAW,YAAY;EAG5C,MAAM,cAAc,QAAQ,MAAM,OAAO,IAAI;AAC7C,WAAS,IAAI,YAAY;AAEzB,YAAU,KAAK,SAAS;;AAG1B,QAAO;;;;;AAMT,SAAgB,SAAS,GAAe,GAA2B;CACjE,MAAM,MAAM,KAAK,IAAI,EAAE,QAAQ,EAAE,OAAO;CACxC,MAAM,SAAS,IAAI,WAAW,IAAI;AAElC,MAAK,IAAI,IAAI,GAAG,IAAI,KAAK,IACvB,QAAO,MAAM,EAAE,MAAM,MAAM,EAAE,MAAM;AAGrC,QAAO;;;;;;;;;;;;;;;;;;AAmBT,SAAgB,gBAAgB,QAAgB,QAAgB,UAA4B;AAE1F,KAAI,UAAU,OACZ,QAAO,CAAC,SAAS,EAAE;CAKrB,MAAM,MAAM,IAAI,WADH,WAAW,UAAU,OAAO,CACT;CAGhC,MAAM,SAAS,IAAI,aAAa,OAAO;CAGvC,MAAM,aAAuB,EAAE;AAC/B,MAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,IAC1B,YAAW,KAAK,EAAE;AAKpB,QADiB,IAAI,SAAS,WAAW,CACzB,MAAM,GAAG,OAAO;;;;;AAMlC,SAAgB,aAAa,WAAyB,SAA+B;AACnF,KAAI,QAAQ,WAAW,EACrB,OAAM,IAAI,MAAM,sBAAsB;CAGxC,IAAI,SAAqB,IAAI,WAAW,UAAU,GAAG,OAAO;AAE5D,MAAK,MAAM,SAAS,SAAS;EAC3B,MAAM,WAAW,UAAU;AAC3B,MAAI,aAAa,OACf,OAAM,IAAI,MAAM,qBAAqB,MAAM,YAAY;AAEzD,WAAS,SAAS,QAAQ,SAAS;;AAGrC,QAAO;;;;;AAMT,IAAa,kBAAb,MAA6B;CAC3B,AAAiB;CACjB,AAAiB;CACjB,AAAiB;CACjB,AAAQ,SAAS;;;;;;;CAQjB,YAAY,SAAqB,gBAAwB;AACvD,MAAI,iBAAiB,EACnB,OAAM,IAAI,MAAM,qCAAqC;AAGvD,OAAK,aAAa,QAAQ;AAC1B,OAAK,WAAW,MAAM,QAAQ;AAC9B,OAAK,YAAY,aAAa,SAAS,eAAe;;;;;CAMxD,IAAI,SAAiB;AACnB,SAAO,KAAK,UAAU;;;;;CAMxB,eAAwB;AACtB,SAAO,KAAK,UAAU,WAAW;;;;;CAMnC,aAAsB;AACpB,SAAO,KAAK,UAAU,KAAK;;;;;CAM7B,WAAyB;AACvB,OAAK;EAEL,MAAM,UAAU,gBAAgB,KAAK,QAAQ,KAAK,QAAQ,KAAK,SAAS;EACxE,MAAM,OAAO,aAAa,KAAK,WAAW,QAAQ;AAElD,SAAO;GACL,QAAQ,KAAK;GACb,QAAQ,KAAK;GACb,YAAY,KAAK;GACjB,UAAU,KAAK;GACf;GACD;;;;;CAMH,gBAAwB;AACtB,SAAO,KAAK;;;;;CAMd,QAAc;AACZ,OAAK,SAAS;;;;;;AAOlB,IAAa,kBAAb,MAA6B;CAC3B,AAAQ,SAAwB;CAChC,AAAQ,aAA4B;CACpC,AAAQ,WAA0B;CAGlC,AAAiB,gCAAgB,IAAI,KAAyB;CAC9D,AAAiB,6BAAa,IAAI,KAAsD;;;;;;;CAQxF,QAAQ,MAA6B;AAEnC,MAAI,KAAK,WAAW,MAAM;AACxB,QAAK,SAAS,KAAK;AACnB,QAAK,aAAa,KAAK;AACvB,QAAK,WAAW,KAAK;;AAIvB,MACE,KAAK,WAAW,KAAK,UACrB,KAAK,eAAe,KAAK,cACzB,KAAK,aAAa,KAAK,SAEvB,OAAM,IAAI,MAAM,6BAA6B;EAI/C,MAAM,UAAU,gBAAgB,KAAK,QAAQ,KAAK,QAAQ,KAAK,SAAS;AAExE,MAAI,QAAQ,WAAW,GAAG;GAExB,MAAM,QAAQ,QAAQ;AACtB,OAAI,CAAC,KAAK,cAAc,IAAI,MAAM,CAChC,MAAK,cAAc,IAAI,OAAO,KAAK,KAAK;aAItC,CAAC,KAAK,WAAW,IAAI,KAAK,OAAO,CACnC,MAAK,WAAW,IAAI,KAAK,QAAQ;GAAE;GAAS,MAAM,KAAK;GAAM,CAAC;AAKlE,OAAK,kBAAkB;AAEvB,SAAO,KAAK,YAAY;;;;;CAM1B,AAAQ,mBAAyB;EAC/B,IAAI,WAAW;AAEf,SAAO,UAAU;AACf,cAAW;AAEX,QAAK,MAAM,CAAC,QAAQ,UAAU,KAAK,YAAY;IAE7C,MAAM,UAAoB,EAAE;IAC5B,IAAI,UAAU,MAAM;AAEpB,SAAK,MAAM,SAAS,MAAM,SAAS;KACjC,MAAM,OAAO,KAAK,cAAc,IAAI,MAAM;AAC1C,SAAI,SAAS,OAEX,WAAU,SAAS,SAAS,KAAK;SAEjC,SAAQ,KAAK,MAAM;;AAIvB,QAAI,QAAQ,WAAW,GAAG;AAExB,UAAK,WAAW,OAAO,OAAO;AAC9B,gBAAW;eACF,QAAQ,WAAW,GAAG;KAE/B,MAAM,eAAe,QAAQ;AAC7B,UAAK,cAAc,IAAI,cAAc,QAAQ;AAC7C,UAAK,WAAW,OAAO,OAAO;AAC9B,gBAAW;;;;;;;;CASnB,aAAsB;AACpB,MAAI,KAAK,WAAW,KAClB,QAAO;AAGT,SAAO,KAAK,cAAc,SAAS,KAAK;;;;;;;CAQ1C,UAA6B;AAC3B,MAAI,CAAC,KAAK,YAAY,IAAI,KAAK,WAAW,QAAQ,KAAK,eAAe,KACpE,QAAO;EAIT,MAAM,gBAAgB,KAAK,cAAc,IAAI,EAAE;AAC/C,MAAI,kBAAkB,OACpB,QAAO;EAGT,MAAM,cAAc,cAAc;EAClC,MAAM,SAAS,IAAI,WAAW,KAAK,WAAW;AAG9C,OAAK,IAAI,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;GACpC,MAAM,WAAW,KAAK,cAAc,IAAI,EAAE;AAC1C,OAAI,aAAa,OACf,QAAO;GAGT,MAAM,QAAQ,IAAI;GAElB,MAAM,MADM,KAAK,IAAI,QAAQ,aAAa,KAAK,WAAW,GACxC;AAElB,UAAO,IAAI,SAAS,MAAM,GAAG,IAAI,EAAE,MAAM;;EAI3C,MAAM,iBAAiB,MAAM,OAAO;AACpC,MAAI,mBAAmB,KAAK,SAC1B,OAAM,IAAI,MAAM,+BAA+B,KAAK,SAAS,QAAQ,iBAAiB;AAGxF,SAAO;;;;;CAMT,WAAmB;AACjB,MAAI,KAAK,WAAW,KAClB,QAAO;AAET,SAAO,KAAK,cAAc,OAAO,KAAK;;;;;CAMxC,QAAc;AACZ,OAAK,SAAS;AACd,OAAK,aAAa;AAClB,OAAK,WAAW;AAChB,OAAK,cAAc,OAAO;AAC1B,OAAK,WAAW,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACrV3B,IAAa,mBAAb,MAA8B;CAC5B,AAAiB;CACjB,AAAiB;CACjB,AAAQ,gBAAgB;;;;;;;;;;;;;CAcxB,YAAY,IAAQ,gBAAwB;AAC1C,MAAI,iBAAiB,EACnB,OAAM,IAAI,QAAQ,yCAAyC;AAE7D,OAAK,MAAM;AAIX,OAAK,mBAAmB,IAAI,gBADX,GAAG,MAAM,CAAC,QAAQ,EACmB,eAAe;;;;;;;;;;;;;;;;CAiBvE,WAAmB;EACjB,MAAM,OAAO,KAAK,iBAAiB,UAAU;AAC7C,OAAK;AACL,SAAO,KAAK,YAAY,KAAK;;;;;CAM/B,AAAQ,YAAY,MAA4B;AAE9C,MAAI,KAAK,WAAW,EAClB,QAAO,KAAK,IAAI,QAAQ;EAM1B,MAAM,UAAU,gBADC,KAAK,gBAAgB,KAAK,EACD,eAAe,QAAQ;AAEjE,SAAO,MAAM,KAAK,IAAI,WAAW,CAAC,GAAG,KAAK,OAAO,GAAG,KAAK,OAAO,GAAG;;;;;;CAOrE,AAAQ,gBAAgB,MAAgC;AAItD,+BAFuB;GAAC,KAAK;GAAQ,KAAK;GAAQ,KAAK;GAAY,KAAK;GAAU,KAAK;GAAK,CAAC,CAE5E,QAAQ;;;;;CAM3B,eAAuB;AACrB,SAAO,KAAK;;;;;;;;CASd,aAAqB;AACnB,SAAO,KAAK,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;ACjGjC,IAAa,mBAAb,MAA8B;CAC5B,AAAQ,UAAyB;CACjC,AAAQ,mBAA2C;CACnD,AAAQ,kBAA6B;;;;;;;;CASrC,QAAQ,MAAoB;EAC1B,MAAM,EAAE,QAAQ,aAAa,KAAK,WAAW,KAAK;AAGlD,MAAI,KAAK,YAAY,KACnB,MAAK,UAAU;WACN,CAAC,KAAK,QAAQ,OAAO,OAAO,CACrC,OAAM,IAAI,oBAAoB,KAAK,QAAQ,QAAQ,EAAE,OAAO,QAAQ,CAAC;AAIvE,MAAI,SAAS,aAEX,MAAK,kBAAkB,GAAG,aAAa,KAAK;OACvC;AAEL,QAAK,qBAAqB,IAAI,iBAAiB;GAE/C,MAAM,eAAe,KAAK,oBAAoB,SAAS;AACvD,QAAK,iBAAiB,QAAQ,aAAa;AAG3C,OAAI,KAAK,iBAAiB,YAAY,EAAE;IACtC,MAAM,UAAU,KAAK,iBAAiB,SAAS;AAC/C,QAAI,YAAY,MAAM;KACpB,MAAM,mCAAkB,QAAQ;AAChC,UAAK,kBAAkB,GAAG,IAAI,KAAK,SAAS,KAAK;;;;;;;;CASzD,AAAQ,WAAW,MAAsD;EACvE,MAAM,aAAa,KAAK,aAAa;AAErC,MAAI,CAAC,WAAW,WAAW,MAAM,CAC/B,OAAM,IAAI,oBAAoB;EAIhC,MAAM,aADc,WAAW,UAAU,EAAE,CACZ,MAAM,IAAI;AAEzC,MAAI,WAAW,WAAW,KAAK,WAAW,OAAO,GAC/C,OAAM,IAAI,kBAAkB;EAG9B,MAAM,SAAS,IAAI,OAAO,WAAW,GAAG;AAGxC,MAAI,WAAW,UAAU,GAAG;GAC1B,MAAM,UAAU,WAAW;GAC3B,MAAM,WAAW,gBAAgB,KAAK,QAAQ;AAE9C,OAAI,aAAa,KAKf,QAAO;IACL;IACA,UAAU;KACR,cAAc;KACd,QARW,SAAS,SAAS,IAAI,GAAG;KASpC,QARW,SAAS,SAAS,IAAI,GAAG;KASpC,aARgB,WAAW,MAAM,EAAE,CAAC,KAAK,IAAI;KAS9C;IACF;;AAKL,SAAO;GACL;GACA,UAAU,EAAE,cAAc,MAAM;GACjC;;;;;;;CAQH,AAAQ,oBAAoB,UAAuC;EAKjE,MAAM,sCAHW,gBAAgB,SAAS,aAAa,eAAe,QAAQ,CAG1C;AAGpC,MAAI,QAAQ,SAASA,sBAAU,MAC7B,OAAM,IAAI,QAAQ,8CAA8C;EAGlE,MAAM,QAAQ,QAAQ;AACtB,MAAI,MAAM,WAAW,EACnB,OAAM,IAAI,QAAQ,oDAAoD,MAAM,SAAS;EAIvF,MAAM,SAAS,OAAO,MAAM,GAAG,MAAM;EACrC,MAAM,SAAS,OAAO,MAAM,GAAG,MAAM;EACrC,MAAM,aAAa,OAAO,MAAM,GAAG,MAAM;EACzC,MAAM,WAAW,OAAO,MAAM,GAAG,MAAM;EACvC,MAAM,OAAO,MAAM,GAAG;AAGtB,MAAI,WAAW,SAAS,UAAU,WAAW,SAAS,OACpD,OAAM,IAAI,QACR,yCAAyC,SAAS,OAAO,GAAG,SAAS,OAAO,cAAc,OAAO,GAAG,SACrG;AAGH,SAAO;GACL;GACA;GACA;GACA;GACA;GACD;;;;;CAMH,aAAsB;AACpB,SAAO,KAAK,oBAAoB;;;;;;;CAQlC,UAAqB;AACnB,SAAO,KAAK"}
@@ -1,5 +1,6 @@
1
1
  var bctsUniformResources = (function(exports, _bcts_dcbor, _bcts_crypto) {
2
2
 
3
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
3
4
 
4
5
  //#region src/error.ts
5
6
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"index.iife.js","names":["MajorType"],"sources":["../src/error.ts","../src/utils.ts","../src/ur-type.ts","../src/ur.ts","../src/ur-encodable.ts","../src/ur-decodable.ts","../src/ur-codable.ts","../src/xoshiro.ts","../src/fountain.ts","../src/multipart-encoder.ts","../src/multipart-decoder.ts"],"sourcesContent":["/**\n * Error type for UR encoding/decoding operations.\n */\nexport class URError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"URError\";\n }\n}\n\n/**\n * Error type for invalid UR schemes.\n */\nexport class InvalidSchemeError extends URError {\n constructor() {\n super(\"Invalid UR scheme\");\n this.name = \"InvalidSchemeError\";\n }\n}\n\n/**\n * Error type for unspecified UR types.\n */\nexport class TypeUnspecifiedError extends URError {\n constructor() {\n super(\"No UR type specified\");\n this.name = \"TypeUnspecifiedError\";\n }\n}\n\n/**\n * Error type for invalid UR types.\n */\nexport class InvalidTypeError extends URError {\n constructor() {\n super(\"Invalid UR type\");\n this.name = \"InvalidTypeError\";\n }\n}\n\n/**\n * Error type for non-single-part URs.\n */\nexport class NotSinglePartError extends URError {\n constructor() {\n super(\"UR is not a single-part\");\n this.name = \"NotSinglePartError\";\n }\n}\n\n/**\n * Error type for unexpected UR types.\n */\nexport class UnexpectedTypeError extends URError {\n constructor(expected: string, found: string) {\n super(`Expected UR type ${expected}, but found ${found}`);\n this.name = \"UnexpectedTypeError\";\n }\n}\n\n/**\n * Error type for Bytewords encoding/decoding errors.\n */\nexport class BytewordsError extends URError {\n constructor(message: string) {\n super(`Bytewords error: ${message}`);\n this.name = \"BytewordsError\";\n }\n}\n\n/**\n * Error type for CBOR encoding/decoding errors.\n */\nexport class CBORError extends URError {\n constructor(message: string) {\n super(`CBOR error: ${message}`);\n this.name = \"CBORError\";\n }\n}\n\n/**\n * Error type for UR decoder errors.\n * Matches Rust's Error::UR(String) variant.\n */\nexport class URDecodeError extends URError {\n constructor(message: string) {\n super(`UR decoder error (${message})`);\n this.name = \"URDecodeError\";\n }\n}\n\nexport type Result<T> = T | Error;\n\n/**\n * Helper function to check if a result is an error.\n */\nexport function isError(result: unknown): result is Error {\n return result instanceof Error;\n}\n","import { InvalidTypeError } from \"./error.js\";\n\n/**\n * Checks if a character is a valid UR type character.\n * Valid characters are lowercase letters, digits, and hyphens.\n */\nexport function isURTypeChar(char: string): boolean {\n const code = char.charCodeAt(0);\n // Check for lowercase letters (a-z)\n if (code >= 97 && code <= 122) return true;\n // Check for digits (0-9)\n if (code >= 48 && code <= 57) return true;\n // Check for hyphen (-)\n if (code === 45) return true;\n return false;\n}\n\n/**\n * Checks if a string is a valid UR type.\n * Valid UR types contain only lowercase letters, digits, and hyphens.\n */\nexport function isValidURType(urType: string): boolean {\n if (urType.length === 0) return false;\n return Array.from(urType).every((char) => isURTypeChar(char));\n}\n\n/**\n * Validates and returns a UR type, or throws an error if invalid.\n */\nexport function validateURType(urType: string): string {\n if (!isValidURType(urType)) {\n throw new InvalidTypeError();\n }\n return urType;\n}\n\n/**\n * Bytewords for encoding/decoding bytes as words.\n * See: https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-004-bytewords.md\n */\nexport const BYTEWORDS: string[] = [\n \"able\",\n \"acid\",\n \"also\",\n \"apex\",\n \"aqua\",\n \"arch\",\n \"atom\",\n \"aunt\",\n \"away\",\n \"axis\",\n \"back\",\n \"bald\",\n \"barn\",\n \"belt\",\n \"beta\",\n \"bias\",\n \"blue\",\n \"body\",\n \"brag\",\n \"brew\",\n \"bulb\",\n \"buzz\",\n \"calm\",\n \"cash\",\n \"cats\",\n \"chef\",\n \"city\",\n \"claw\",\n \"code\",\n \"cola\",\n \"cook\",\n \"cost\",\n \"crux\",\n \"curl\",\n \"cusp\",\n \"cyan\",\n \"dark\",\n \"data\",\n \"days\",\n \"deli\",\n \"dice\",\n \"diet\",\n \"door\",\n \"down\",\n \"draw\",\n \"drop\",\n \"drum\",\n \"dull\",\n \"duty\",\n \"each\",\n \"easy\",\n \"echo\",\n \"edge\",\n \"epic\",\n \"even\",\n \"exam\",\n \"exit\",\n \"eyes\",\n \"fact\",\n \"fair\",\n \"fern\",\n \"figs\",\n \"film\",\n \"fish\",\n \"fizz\",\n \"flap\",\n \"flew\",\n \"flux\",\n \"foxy\",\n \"free\",\n \"frog\",\n \"fuel\",\n \"fund\",\n \"gala\",\n \"game\",\n \"gear\",\n \"gems\",\n \"gift\",\n \"girl\",\n \"glow\",\n \"good\",\n \"gray\",\n \"grim\",\n \"guru\",\n \"gush\",\n \"gyro\",\n \"half\",\n \"hang\",\n \"hard\",\n \"hawk\",\n \"heat\",\n \"help\",\n \"high\",\n \"hill\",\n \"holy\",\n \"hope\",\n \"horn\",\n \"huts\",\n \"iced\",\n \"idea\",\n \"idle\",\n \"inch\",\n \"inky\",\n \"into\",\n \"iris\",\n \"iron\",\n \"item\",\n \"jade\",\n \"jazz\",\n \"join\",\n \"jolt\",\n \"jowl\",\n \"judo\",\n \"jugs\",\n \"jump\",\n \"junk\",\n \"jury\",\n \"keep\",\n \"keno\",\n \"kept\",\n \"keys\",\n \"kick\",\n \"kiln\",\n \"king\",\n \"kite\",\n \"kiwi\",\n \"knob\",\n \"lamb\",\n \"lava\",\n \"lazy\",\n \"leaf\",\n \"legs\",\n \"liar\",\n \"limp\",\n \"lion\",\n \"list\",\n \"logo\",\n \"loud\",\n \"love\",\n \"luau\",\n \"luck\",\n \"lung\",\n \"main\",\n \"many\",\n \"math\",\n \"maze\",\n \"memo\",\n \"menu\",\n \"meow\",\n \"mild\",\n \"mint\",\n \"miss\",\n \"monk\",\n \"nail\",\n \"navy\",\n \"need\",\n \"news\",\n \"next\",\n \"noon\",\n \"note\",\n \"numb\",\n \"obey\",\n \"oboe\",\n \"omit\",\n \"onyx\",\n \"open\",\n \"oval\",\n \"owls\",\n \"paid\",\n \"part\",\n \"peck\",\n \"play\",\n \"plus\",\n \"poem\",\n \"pool\",\n \"pose\",\n \"puff\",\n \"puma\",\n \"purr\",\n \"quad\",\n \"quiz\",\n \"race\",\n \"ramp\",\n \"real\",\n \"redo\",\n \"rich\",\n \"road\",\n \"rock\",\n \"roof\",\n \"ruby\",\n \"ruin\",\n \"runs\",\n \"rust\",\n \"safe\",\n \"saga\",\n \"scar\",\n \"sets\",\n \"silk\",\n \"skew\",\n \"slot\",\n \"soap\",\n \"solo\",\n \"song\",\n \"stub\",\n \"surf\",\n \"swan\",\n \"taco\",\n \"task\",\n \"taxi\",\n \"tent\",\n \"tied\",\n \"time\",\n \"tiny\",\n \"toil\",\n \"tomb\",\n \"toys\",\n \"trip\",\n \"tuna\",\n \"twin\",\n \"ugly\",\n \"undo\",\n \"unit\",\n \"urge\",\n \"user\",\n \"vast\",\n \"very\",\n \"veto\",\n \"vial\",\n \"vibe\",\n \"view\",\n \"visa\",\n \"void\",\n \"vows\",\n \"wall\",\n \"wand\",\n \"warm\",\n \"wasp\",\n \"wave\",\n \"waxy\",\n \"webs\",\n \"what\",\n \"when\",\n \"whiz\",\n \"wolf\",\n \"work\",\n \"yank\",\n \"yawn\",\n \"yell\",\n \"yoga\",\n \"yurt\",\n \"zaps\",\n \"zero\",\n \"zest\",\n \"zinc\",\n \"zone\",\n \"zoom\",\n];\n\n/**\n * Create a reverse mapping for fast byteword lookup.\n */\nfunction createBytewordsMap(): Map<string, number> {\n const map = new Map<string, number>();\n BYTEWORDS.forEach((word, index) => {\n map.set(word, index);\n });\n return map;\n}\n\nexport const BYTEWORDS_MAP = createBytewordsMap();\n\n/**\n * Bytemojis for encoding/decoding bytes as emojis.\n * See: https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2024-008-bytemoji.md\n */\nexport const BYTEMOJIS: string[] = [\n \"๐Ÿ˜€\",\n \"๐Ÿ˜‚\",\n \"๐Ÿ˜†\",\n \"๐Ÿ˜‰\",\n \"๐Ÿ™„\",\n \"๐Ÿ˜‹\",\n \"๐Ÿ˜Ž\",\n \"๐Ÿ˜\",\n \"๐Ÿ˜˜\",\n \"๐Ÿ˜ญ\",\n \"๐Ÿซ \",\n \"๐Ÿฅฑ\",\n \"๐Ÿคฉ\",\n \"๐Ÿ˜ถ\",\n \"๐Ÿคจ\",\n \"๐Ÿซฅ\",\n \"๐Ÿฅต\",\n \"๐Ÿฅถ\",\n \"๐Ÿ˜ณ\",\n \"๐Ÿคช\",\n \"๐Ÿ˜ต\",\n \"๐Ÿ˜ก\",\n \"๐Ÿคข\",\n \"๐Ÿ˜‡\",\n \"๐Ÿค \",\n \"๐Ÿคก\",\n \"๐Ÿฅณ\",\n \"๐Ÿฅบ\",\n \"๐Ÿ˜ฌ\",\n \"๐Ÿค‘\",\n \"๐Ÿ™ƒ\",\n \"๐Ÿคฏ\",\n \"๐Ÿ˜ˆ\",\n \"๐Ÿ‘น\",\n \"๐Ÿ‘บ\",\n \"๐Ÿ’€\",\n \"๐Ÿ‘ป\",\n \"๐Ÿ‘ฝ\",\n \"๐Ÿ˜บ\",\n \"๐Ÿ˜น\",\n \"๐Ÿ˜ป\",\n \"๐Ÿ˜ฝ\",\n \"๐Ÿ™€\",\n \"๐Ÿ˜ฟ\",\n \"๐Ÿซถ\",\n \"๐Ÿคฒ\",\n \"๐Ÿ™Œ\",\n \"๐Ÿค\",\n \"๐Ÿ‘\",\n \"๐Ÿ‘Ž\",\n \"๐Ÿ‘ˆ\",\n \"๐Ÿ‘†\",\n \"๐Ÿ’ช\",\n \"๐Ÿ‘„\",\n \"๐Ÿฆท\",\n \"๐Ÿ‘‚\",\n \"๐Ÿ‘ƒ\",\n \"๐Ÿง \",\n \"๐Ÿ‘€\",\n \"๐Ÿคš\",\n \"๐Ÿฆถ\",\n \"๐ŸŽ\",\n \"๐ŸŠ\",\n \"๐Ÿ‹\",\n \"๐ŸŒ\",\n \"๐Ÿ‰\",\n \"๐Ÿ‡\",\n \"๐Ÿ“\",\n \"๐Ÿซ\",\n \"๐Ÿ’\",\n \"๐Ÿ‘\",\n \"๐Ÿ\",\n \"๐Ÿฅ\",\n \"๐Ÿ†\",\n \"๐Ÿฅ‘\",\n \"๐Ÿฅฆ\",\n \"๐Ÿ…\",\n \"๐ŸŒฝ\",\n \"๐Ÿฅ•\",\n \"๐Ÿซ’\",\n \"๐Ÿง„\",\n \"๐Ÿฅ\",\n \"๐Ÿฅฏ\",\n \"๐Ÿž\",\n \"๐Ÿง€\",\n \"๐Ÿฅš\",\n \"๐Ÿ—\",\n \"๐ŸŒญ\",\n \"๐Ÿ”\",\n \"๐ŸŸ\",\n \"๐Ÿ•\",\n \"๐ŸŒฎ\",\n \"๐Ÿฅ™\",\n \"๐Ÿฑ\",\n \"๐Ÿœ\",\n \"๐Ÿค\",\n \"๐Ÿš\",\n \"๐Ÿฅ \",\n \"๐Ÿจ\",\n \"๐Ÿฆ\",\n \"๐ŸŽ‚\",\n \"๐Ÿชด\",\n \"๐ŸŒต\",\n \"๐ŸŒฑ\",\n \"๐Ÿ’\",\n \"๐Ÿ\",\n \"๐Ÿ„\",\n \"๐ŸŒน\",\n \"๐ŸŒบ\",\n \"๐ŸŒผ\",\n \"๐ŸŒป\",\n \"๐ŸŒธ\",\n \"๐Ÿ’จ\",\n \"๐ŸŒŠ\",\n \"๐Ÿ’ง\",\n \"๐Ÿ’ฆ\",\n \"๐ŸŒ€\",\n \"๐ŸŒˆ\",\n \"๐ŸŒž\",\n \"๐ŸŒ\",\n \"๐ŸŒ›\",\n \"๐ŸŒœ\",\n \"๐ŸŒ™\",\n \"๐ŸŒŽ\",\n \"๐Ÿ’ซ\",\n \"โญ\",\n \"๐Ÿช\",\n \"๐ŸŒ\",\n \"๐Ÿ’›\",\n \"๐Ÿ’”\",\n \"๐Ÿ’˜\",\n \"๐Ÿ’–\",\n \"๐Ÿ’•\",\n \"๐Ÿ\",\n \"๐Ÿšฉ\",\n \"๐Ÿ’ฌ\",\n \"๐Ÿ’ฏ\",\n \"๐Ÿšซ\",\n \"๐Ÿ”ด\",\n \"๐Ÿ”ท\",\n \"๐ŸŸฉ\",\n \"๐Ÿ›‘\",\n \"๐Ÿ”บ\",\n \"๐Ÿš—\",\n \"๐Ÿš‘\",\n \"๐Ÿš’\",\n \"๐Ÿšœ\",\n \"๐Ÿ›ต\",\n \"๐Ÿšจ\",\n \"๐Ÿš€\",\n \"๐Ÿš\",\n \"๐Ÿ›Ÿ\",\n \"๐Ÿšฆ\",\n \"๐Ÿฐ\",\n \"๐ŸŽก\",\n \"๐ŸŽข\",\n \"๐ŸŽ \",\n \"๐Ÿ \",\n \"๐Ÿ””\",\n \"๐Ÿ”‘\",\n \"๐Ÿšช\",\n \"๐Ÿช‘\",\n \"๐ŸŽˆ\",\n \"๐Ÿ’Œ\",\n \"๐Ÿ“ฆ\",\n \"๐Ÿ“ซ\",\n \"๐Ÿ“–\",\n \"๐Ÿ“š\",\n \"๐Ÿ“Œ\",\n \"๐Ÿงฎ\",\n \"๐Ÿ”’\",\n \"๐Ÿ’Ž\",\n \"๐Ÿ“ท\",\n \"โฐ\",\n \"โณ\",\n \"๐Ÿ“ก\",\n \"๐Ÿ’ก\",\n \"๐Ÿ’ฐ\",\n \"๐Ÿงฒ\",\n \"๐Ÿงธ\",\n \"๐ŸŽ\",\n \"๐ŸŽ€\",\n \"๐ŸŽ‰\",\n \"๐Ÿชญ\",\n \"๐Ÿ‘‘\",\n \"๐Ÿซ–\",\n \"๐Ÿ”ญ\",\n \"๐Ÿ›\",\n \"๐Ÿ†\",\n \"๐Ÿฅ\",\n \"๐ŸŽท\",\n \"๐ŸŽบ\",\n \"๐Ÿ€\",\n \"๐Ÿˆ\",\n \"๐ŸŽพ\",\n \"๐Ÿ“\",\n \"โœจ\",\n \"๐Ÿ”ฅ\",\n \"๐Ÿ’ฅ\",\n \"๐Ÿ‘•\",\n \"๐Ÿ‘š\",\n \"๐Ÿ‘–\",\n \"๐Ÿฉณ\",\n \"๐Ÿ‘—\",\n \"๐Ÿ‘”\",\n \"๐Ÿงข\",\n \"๐Ÿ‘“\",\n \"๐Ÿงถ\",\n \"๐Ÿงต\",\n \"๐Ÿ’\",\n \"๐Ÿ‘ \",\n \"๐Ÿ‘Ÿ\",\n \"๐Ÿงฆ\",\n \"๐Ÿงค\",\n \"๐Ÿ‘’\",\n \"๐Ÿ‘œ\",\n \"๐Ÿฑ\",\n \"๐Ÿถ\",\n \"๐Ÿญ\",\n \"๐Ÿน\",\n \"๐Ÿฐ\",\n \"๐ŸฆŠ\",\n \"๐Ÿป\",\n \"๐Ÿผ\",\n \"๐Ÿจ\",\n \"๐Ÿฏ\",\n \"๐Ÿฆ\",\n \"๐Ÿฎ\",\n \"๐Ÿท\",\n \"๐Ÿธ\",\n \"๐Ÿต\",\n \"๐Ÿ”\",\n \"๐Ÿฅ\",\n \"๐Ÿฆ†\",\n \"๐Ÿฆ‰\",\n \"๐Ÿด\",\n \"๐Ÿฆ„\",\n \"๐Ÿ\",\n \"๐Ÿ›\",\n \"๐Ÿฆ‹\",\n \"๐ŸŒ\",\n \"๐Ÿž\",\n \"๐Ÿข\",\n \"๐Ÿบ\",\n \"๐Ÿ\",\n \"๐Ÿชฝ\",\n \"๐Ÿ™\",\n \"๐Ÿฆ‘\",\n \"๐Ÿชผ\",\n \"๐Ÿฆž\",\n \"๐Ÿฆ€\",\n \"๐Ÿš\",\n \"๐Ÿฆญ\",\n \"๐ŸŸ\",\n \"๐Ÿฌ\",\n \"๐Ÿณ\",\n];\n\n/**\n * Encodes a 4-byte slice as a string of bytewords for identification.\n */\nexport function encodeBytewordsIdentifier(data: Uint8Array): string {\n if (data.length !== 4) {\n throw new Error(\"Identifier data must be exactly 4 bytes\");\n }\n const words: string[] = [];\n for (let i = 0; i < 4; i++) {\n const byte = data[i];\n if (byte === undefined) throw new Error(\"Invalid byte\");\n const word = BYTEWORDS[byte];\n if (word === \"\" || word === undefined) throw new Error(\"Invalid byteword mapping\");\n words.push(word);\n }\n return words.join(\" \");\n}\n\n/**\n * Encodes a 4-byte slice as a string of bytemojis for identification.\n */\nexport function encodeBytemojisIdentifier(data: Uint8Array): string {\n if (data.length !== 4) {\n throw new Error(\"Identifier data must be exactly 4 bytes\");\n }\n const emojis: string[] = [];\n for (let i = 0; i < 4; i++) {\n const byte = data[i];\n if (byte === undefined) throw new Error(\"Invalid byte\");\n const emoji = BYTEMOJIS[byte];\n if (emoji === \"\" || emoji === undefined) throw new Error(\"Invalid bytemoji mapping\");\n emojis.push(emoji);\n }\n return emojis.join(\" \");\n}\n\n/**\n * Bytewords encoding style.\n */\nexport enum BytewordsStyle {\n /** Full 4-letter words separated by spaces */\n Standard = \"standard\",\n /** Full 4-letter words separated by hyphens (URI-safe) */\n Uri = \"uri\",\n /** First and last character only (minimal) - used by UR encoding */\n Minimal = \"minimal\",\n}\n\n/**\n * Create a reverse mapping for minimal bytewords (first+last char) lookup.\n */\nfunction createMinimalBytewordsMap(): Map<string, number> {\n const map = new Map<string, number>();\n BYTEWORDS.forEach((word, index) => {\n // Minimal encoding uses first and last character\n const minimal = word[0] + word[3];\n map.set(minimal, index);\n });\n return map;\n}\n\nexport const MINIMAL_BYTEWORDS_MAP = createMinimalBytewordsMap();\n\n/**\n * CRC32 lookup table (IEEE polynomial).\n */\nconst CRC32_TABLE: number[] = (() => {\n const table: number[] = [];\n for (let i = 0; i < 256; i++) {\n let c = i;\n for (let j = 0; j < 8; j++) {\n c = (c & 1) !== 0 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;\n }\n table.push(c >>> 0);\n }\n return table;\n})();\n\n/**\n * Calculate CRC32 checksum of data.\n */\nexport function crc32(data: Uint8Array): number {\n let crc = 0xffffffff;\n for (const byte of data) {\n crc = (CRC32_TABLE[(crc ^ byte) & 0xff] ^ (crc >>> 8)) >>> 0;\n }\n return (crc ^ 0xffffffff) >>> 0;\n}\n\n/**\n * Convert a 32-bit number to 4 bytes (big-endian).\n */\nfunction uint32ToBytes(value: number): Uint8Array {\n return new Uint8Array([\n (value >>> 24) & 0xff,\n (value >>> 16) & 0xff,\n (value >>> 8) & 0xff,\n value & 0xff,\n ]);\n}\n\n/**\n * Encode data as bytewords with the specified style.\n * Includes CRC32 checksum.\n */\nexport function encodeBytewords(\n data: Uint8Array,\n style: BytewordsStyle = BytewordsStyle.Minimal,\n): string {\n // Append CRC32 checksum\n const checksum = crc32(data);\n const checksumBytes = uint32ToBytes(checksum);\n const dataWithChecksum = new Uint8Array(data.length + 4);\n dataWithChecksum.set(data);\n dataWithChecksum.set(checksumBytes, data.length);\n\n const words: string[] = [];\n for (const byte of dataWithChecksum) {\n const word = BYTEWORDS[byte];\n if (word === undefined) throw new Error(`Invalid byte value: ${byte}`);\n\n switch (style) {\n case BytewordsStyle.Standard:\n words.push(word);\n break;\n case BytewordsStyle.Uri:\n words.push(word);\n break;\n case BytewordsStyle.Minimal:\n // First and last character\n words.push(word[0] + word[3]);\n break;\n }\n }\n\n switch (style) {\n case BytewordsStyle.Standard:\n return words.join(\" \");\n case BytewordsStyle.Uri:\n return words.join(\"-\");\n case BytewordsStyle.Minimal:\n return words.join(\"\");\n }\n}\n\n/**\n * Decode bytewords string back to data.\n * Validates and removes CRC32 checksum.\n */\nexport function decodeBytewords(\n encoded: string,\n style: BytewordsStyle = BytewordsStyle.Minimal,\n): Uint8Array {\n const lowercased = encoded.toLowerCase();\n let bytes: number[];\n\n switch (style) {\n case BytewordsStyle.Standard: {\n const words = lowercased.split(\" \");\n bytes = words.map((word) => {\n const index = BYTEWORDS_MAP.get(word);\n if (index === undefined) {\n throw new Error(`Invalid byteword: ${word}`);\n }\n return index;\n });\n break;\n }\n case BytewordsStyle.Uri: {\n // 4-character words separated by hyphens\n const words = lowercased.split(\"-\");\n bytes = words.map((word) => {\n const index = BYTEWORDS_MAP.get(word);\n if (index === undefined) {\n throw new Error(`Invalid byteword: ${word}`);\n }\n return index;\n });\n break;\n }\n case BytewordsStyle.Minimal: {\n // 2-character minimal words with no separator\n if (lowercased.length % 2 !== 0) {\n throw new Error(\"Invalid minimal bytewords length\");\n }\n bytes = [];\n for (let i = 0; i < lowercased.length; i += 2) {\n const minimal = lowercased.slice(i, i + 2);\n const index = MINIMAL_BYTEWORDS_MAP.get(minimal);\n if (index === undefined) {\n throw new Error(`Invalid minimal byteword: ${minimal}`);\n }\n bytes.push(index);\n }\n break;\n }\n }\n\n if (bytes.length < 4) {\n throw new Error(\"Bytewords data too short (missing checksum)\");\n }\n\n // Extract data and checksum\n const dataWithChecksum = new Uint8Array(bytes);\n const data = dataWithChecksum.slice(0, -4);\n const checksumBytes = dataWithChecksum.slice(-4);\n\n // Verify checksum\n const expectedChecksum = crc32(data);\n const actualChecksum =\n ((checksumBytes[0] << 24) |\n (checksumBytes[1] << 16) |\n (checksumBytes[2] << 8) |\n checksumBytes[3]) >>>\n 0;\n\n if (expectedChecksum !== actualChecksum) {\n throw new Error(\n `Bytewords checksum mismatch: expected ${expectedChecksum.toString(16)}, got ${actualChecksum.toString(16)}`,\n );\n }\n\n return data;\n}\n","import { InvalidTypeError } from \"./error\";\nimport { isValidURType } from \"./utils\";\n\n/**\n * Represents a UR (Uniform Resource) type identifier.\n *\n * Valid UR types contain only lowercase letters, digits, and hyphens.\n *\n * @example\n * ```typescript\n * const urType = new URType('test');\n * console.log(urType.string()); // \"test\"\n * ```\n */\nexport class URType {\n private readonly _type: string;\n\n /**\n * Creates a new URType from the provided type string.\n *\n * @param urType - The UR type as a string\n * @throws {InvalidTypeError} If the type contains invalid characters\n *\n * @example\n * ```typescript\n * const urType = new URType('test');\n * ```\n */\n constructor(urType: string) {\n if (!isValidURType(urType)) {\n throw new InvalidTypeError();\n }\n this._type = urType;\n }\n\n /**\n * Returns the string representation of the URType.\n *\n * @example\n * ```typescript\n * const urType = new URType('test');\n * console.log(urType.string()); // \"test\"\n * ```\n */\n string(): string {\n return this._type;\n }\n\n /**\n * Checks equality with another URType based on the type string.\n */\n equals(other: URType): boolean {\n return this._type === other._type;\n }\n\n /**\n * Returns the string representation.\n */\n toString(): string {\n return this._type;\n }\n\n /**\n * Creates a URType from a string, throwing an error if invalid.\n *\n * @param value - The UR type string\n * @returns A new URType instance\n * @throws {InvalidTypeError} If the type is invalid\n */\n static from(value: string): URType {\n return new URType(value);\n }\n\n /**\n * Safely creates a URType, returning an error if invalid.\n *\n * @param value - The UR type string\n * @returns Either a URType or an error\n */\n static tryFrom(value: string): URType | InvalidTypeError {\n try {\n return new URType(value);\n } catch (error) {\n return error as InvalidTypeError;\n }\n }\n}\n","import type { Cbor } from \"@bcts/dcbor\";\nimport { decodeCbor } from \"@bcts/dcbor\";\nimport { InvalidSchemeError, TypeUnspecifiedError, UnexpectedTypeError, URError } from \"./error.js\";\nimport { URType } from \"./ur-type.js\";\nimport { encodeBytewords, decodeBytewords, BytewordsStyle } from \"./utils.js\";\n\n/**\n * A Uniform Resource (UR) is a URI-encoded CBOR object.\n *\n * URs are defined in [BCR-2020-005: Uniform Resources](https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-005-ur.md).\n *\n * @example\n * ```typescript\n * import { UR } from '@bcts/uniform-resources';\n * import { CBOR } from '@bcts/dcbor';\n *\n * // Create a UR from a CBOR object\n * const cbor = CBOR.fromArray([1, 2, 3]);\n * const ur = UR.new('test', cbor);\n *\n * // Encode to string\n * const urString = ur.string();\n * console.log(urString); // \"ur:test/...\"\n *\n * // Decode from string\n * const decodedUR = UR.fromURString(urString);\n * console.log(decodedUR.urTypeStr()); // \"test\"\n * ```\n */\nexport class UR {\n private readonly _urType: URType;\n private readonly _cbor: Cbor;\n\n /**\n * Creates a new UR from the provided type and CBOR data.\n *\n * @param urType - The UR type (will be validated)\n * @param cbor - The CBOR data to encode\n * @throws {InvalidTypeError} If the type is invalid\n *\n * @example\n * ```typescript\n * const ur = UR.new('bytes', CBOR.fromString('hello'));\n * ```\n */\n static new(urType: string | URType, cbor: Cbor): UR {\n const type = typeof urType === \"string\" ? new URType(urType) : urType;\n return new UR(type, cbor);\n }\n\n /**\n * Creates a new UR from a UR string.\n *\n * @param urString - A UR string like \"ur:test/...\"\n * @throws {InvalidSchemeError} If the string doesn't start with \"ur:\"\n * @throws {TypeUnspecifiedError} If no type is specified\n * @throws {NotSinglePartError} If the UR is multi-part\n * @throws {URError} If decoding fails\n *\n * @example\n * ```typescript\n * const ur = UR.fromURString('ur:test/lsadaoaxjygonesw');\n * ```\n */\n static fromURString(urString: string): UR {\n // Decode the UR string to get the type and CBOR data\n const decodedUR = URStringDecoder.decode(urString);\n if (decodedUR === null || decodedUR === undefined) {\n throw new URError(\"Failed to decode UR string\");\n }\n const { urType, cbor } = decodedUR;\n return new UR(new URType(urType), cbor);\n }\n\n private constructor(urType: URType, cbor: Cbor) {\n this._urType = urType;\n this._cbor = cbor;\n }\n\n /**\n * Returns the UR type.\n */\n urType(): URType {\n return this._urType;\n }\n\n /**\n * Returns the UR type as a string.\n */\n urTypeStr(): string {\n return this._urType.string();\n }\n\n /**\n * Returns the CBOR data.\n */\n cbor(): Cbor {\n return this._cbor;\n }\n\n /**\n * Returns the string representation of the UR (lowercase, suitable for display).\n *\n * @example\n * ```typescript\n * const ur = UR.new('test', CBOR.fromArray([1, 2, 3]));\n * console.log(ur.string()); // \"ur:test/lsadaoaxjygonesw\"\n * ```\n */\n string(): string {\n const cborData = this._cbor.toData();\n return URStringEncoder.encode(this._urType.string(), cborData);\n }\n\n /**\n * Returns the QR string representation (uppercase, most efficient for QR codes).\n */\n qrString(): string {\n return this.string().toUpperCase();\n }\n\n /**\n * Returns the QR data as bytes (uppercase UR string as UTF-8).\n */\n qrData(): Uint8Array {\n // Use a helper to convert string to bytes across platforms\n const str = this.qrString();\n const bytes = new Uint8Array(str.length);\n for (let i = 0; i < str.length; i++) {\n bytes[i] = str.charCodeAt(i);\n }\n return bytes;\n }\n\n /**\n * Checks if the UR type matches the expected type.\n *\n * @param expectedType - The expected type\n * @throws {UnexpectedTypeError} If the types don't match\n */\n checkType(expectedType: string | URType): void {\n const expected = typeof expectedType === \"string\" ? new URType(expectedType) : expectedType;\n if (!this._urType.equals(expected)) {\n throw new UnexpectedTypeError(expected.string(), this._urType.string());\n }\n }\n\n /**\n * Returns the string representation.\n */\n toString(): string {\n return this.string();\n }\n\n /**\n * Checks equality with another UR.\n */\n equals(other: UR): boolean {\n return (\n this._urType.equals(other._urType) &&\n this._cbor.toData().toString() === other._cbor.toData().toString()\n );\n }\n}\n\n/**\n * Encodes a UR string using Bytewords minimal encoding.\n * This handles single-part URs according to BCR-2020-005.\n */\nclass URStringEncoder {\n static encode(urType: string, cborData: Uint8Array): string {\n // Encode CBOR data using bytewords minimal style (with CRC32 checksum)\n const encoded = encodeBytewords(cborData, BytewordsStyle.Minimal);\n return `ur:${urType}/${encoded}`;\n }\n}\n\n/**\n * Decodes a UR string back to its components.\n */\nclass URStringDecoder {\n static decode(urString: string): { urType: string; cbor: Cbor } | null {\n const lowercased = urString.toLowerCase();\n\n // Check scheme\n if (!lowercased.startsWith(\"ur:\")) {\n throw new InvalidSchemeError();\n }\n\n // Strip scheme\n const afterScheme = lowercased.substring(3);\n\n // Split into type and data\n const [urType, ...dataParts] = afterScheme.split(\"/\");\n\n if (urType === \"\" || urType === undefined) {\n throw new TypeUnspecifiedError();\n }\n\n const data = dataParts.join(\"/\");\n if (data === \"\" || data === undefined) {\n throw new TypeUnspecifiedError();\n }\n\n try {\n // Decode the bytewords-encoded data (validates CRC32 checksum)\n const cborData = decodeBytewords(data, BytewordsStyle.Minimal);\n const cbor = decodeCbor(cborData);\n return { urType, cbor };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new URError(`Failed to decode UR: ${errorMessage}`);\n }\n }\n}\n","import type { UR } from \"./ur.js\";\n\n/**\n * A type that can be encoded to a UR (Uniform Resource).\n *\n * Types implementing this interface should be able to convert themselves\n * to CBOR data and associate that with a UR type identifier.\n *\n * @example\n * ```typescript\n * class MyType implements UREncodable {\n * toCBOR(): CBOR {\n * // Convert to CBOR\n * }\n *\n * ur(): UR {\n * const cbor = this.toCBOR();\n * return UR.new('mytype', cbor);\n * }\n * }\n * ```\n */\nexport interface UREncodable {\n /**\n * Returns the UR representation of the object.\n */\n ur(): UR;\n\n /**\n * Returns the UR string representation of the object.\n */\n urString(): string;\n}\n\n/**\n * Helper function to check if an object implements UREncodable.\n */\nexport function isUREncodable(obj: unknown): obj is UREncodable {\n return (\n typeof obj === \"object\" &&\n obj !== null &&\n \"ur\" in obj &&\n \"urString\" in obj &&\n typeof (obj as Record<string, unknown>)[\"ur\"] === \"function\" &&\n typeof (obj as Record<string, unknown>)[\"urString\"] === \"function\"\n );\n}\n","import type { UR } from \"./ur.js\";\n\n/**\n * A type that can be decoded from a UR (Uniform Resource).\n *\n * Types implementing this interface should be able to create themselves\n * from a UR containing their data.\n *\n * @example\n * ```typescript\n * class MyType implements URDecodable {\n * fromUR(ur: UR): MyType {\n * const cbor = ur.cbor();\n * // Decode from CBOR and return MyType instance\n * }\n *\n * fromURString(urString: string): MyType {\n * return this.fromUR(UR.fromURString(urString));\n * }\n * }\n * ```\n */\nexport interface URDecodable {\n /**\n * Creates an instance of this type from a UR.\n *\n * @param ur - The UR to decode from\n * @returns An instance of this type\n * @throws If the UR type is wrong or data is malformed\n */\n fromUR(ur: UR): unknown;\n\n /**\n * Creates an instance of this type from a UR string.\n *\n * This is a convenience method that parses the UR string and then\n * calls fromUR().\n *\n * @param urString - The UR string to decode from (e.g., \"ur:type/...\")\n * @returns An instance of this type\n * @throws If the UR string is invalid or data is malformed\n */\n fromURString?(urString: string): unknown;\n}\n\n/**\n * Helper function to check if an object implements URDecodable.\n */\nexport function isURDecodable(obj: unknown): obj is URDecodable {\n return (\n typeof obj === \"object\" &&\n obj !== null &&\n \"fromUR\" in obj &&\n typeof (obj as Record<string, unknown>)[\"fromUR\"] === \"function\"\n );\n}\n","import type { UREncodable } from \"./ur-encodable.js\";\nimport type { URDecodable } from \"./ur-decodable.js\";\n\n/**\n * A type that can be both encoded to and decoded from a UR.\n *\n * This combines the UREncodable and URDecodable interfaces for types\n * that support bidirectional UR conversion.\n *\n * @example\n * ```typescript\n * class MyType implements URCodable {\n * ur(): UR {\n * // Encode to UR\n * }\n *\n * urString(): string {\n * // Return UR string\n * }\n *\n * fromUR(ur: UR): MyType {\n * // Decode from UR\n * }\n *\n * fromURString(urString: string): MyType {\n * // Decode from UR string (convenience method)\n * return this.fromUR(UR.fromURString(urString));\n * }\n * }\n * ```\n */\nexport interface URCodable extends UREncodable, URDecodable {}\n\n/**\n * Helper function to check if an object implements URCodable.\n */\nexport function isURCodable(obj: unknown): obj is URCodable {\n return (\n typeof obj === \"object\" &&\n obj !== null &&\n \"ur\" in obj &&\n \"urString\" in obj &&\n \"fromUR\" in obj &&\n typeof (obj as Record<string, unknown>)[\"ur\"] === \"function\" &&\n typeof (obj as Record<string, unknown>)[\"urString\"] === \"function\" &&\n typeof (obj as Record<string, unknown>)[\"fromUR\"] === \"function\"\n );\n}\n","/**\n * Xoshiro256** PRNG implementation.\n *\n * This is a high-quality, fast pseudo-random number generator used\n * for deterministic fragment selection in fountain codes.\n *\n * Reference: https://prng.di.unimi.it/\n * BC-UR Reference: https://github.com/nicklockwood/fountain-codes\n */\n\nimport { sha256 } from \"@bcts/crypto\";\n\nconst MAX_UINT64 = BigInt(\"0xffffffffffffffff\");\n\n/**\n * Performs a left rotation on a 64-bit BigInt.\n */\nfunction rotl(x: bigint, k: number): bigint {\n const kBigInt = BigInt(k);\n return ((x << kBigInt) | (x >> (64n - kBigInt))) & MAX_UINT64;\n}\n\n/**\n * Xoshiro256** pseudo-random number generator.\n *\n * This PRNG is used for deterministic mixing in fountain codes,\n * allowing both encoder and decoder to agree on which fragments\n * are combined without transmitting that information.\n */\nexport class Xoshiro256 {\n private s: [bigint, bigint, bigint, bigint];\n\n /**\n * Creates a new Xoshiro256** instance from a 32-byte seed.\n *\n * The seed must be exactly 32 bytes (256 bits). The bytes are interpreted\n * using the BC-UR reference algorithm: each 8-byte chunk is read as\n * big-endian then stored as little-endian for the state.\n *\n * @param seed - The seed bytes (must be exactly 32 bytes)\n */\n constructor(seed: Uint8Array) {\n if (seed.length !== 32) {\n throw new Error(`Seed must be 32 bytes, got ${seed.length}`);\n }\n\n // BC-UR reference implementation:\n // For each 8-byte chunk, read as big-endian u64, then convert to little-endian bytes\n // This effectively swaps the byte order within each 8-byte segment\n const s: [bigint, bigint, bigint, bigint] = [0n, 0n, 0n, 0n];\n for (let i = 0; i < 4; i++) {\n // Read 8 bytes as big-endian u64\n let v = 0n;\n for (let n = 0; n < 8; n++) {\n v = (v << 8n) | BigInt(seed[8 * i + n] ?? 0);\n }\n s[i] = v;\n }\n\n this.s = s;\n }\n\n /**\n * Creates a Xoshiro256** instance from raw state values.\n * Useful for seeding with specific values.\n */\n static fromState(s0: bigint, s1: bigint, s2: bigint, s3: bigint): Xoshiro256 {\n const instance = Object.create(Xoshiro256.prototype) as Xoshiro256;\n instance.s = [s0, s1, s2, s3];\n return instance;\n }\n\n /**\n * Generates the next 64-bit random value.\n */\n next(): bigint {\n const result = (rotl((this.s[1] * 5n) & MAX_UINT64, 7) * 9n) & MAX_UINT64;\n\n const t = (this.s[1] << 17n) & MAX_UINT64;\n\n this.s[2] ^= this.s[0];\n this.s[3] ^= this.s[1];\n this.s[1] ^= this.s[2];\n this.s[0] ^= this.s[3];\n\n this.s[2] ^= t;\n this.s[3] = rotl(this.s[3], 45);\n\n return result;\n }\n\n /**\n * Generates a random double in [0, 1).\n * Matches BC-UR reference: self.next() as f64 / (u64::MAX as f64 + 1.0)\n */\n nextDouble(): number {\n const value = this.next();\n // u64::MAX as f64 + 1.0 = 18446744073709551616.0\n return Number(value) / 18446744073709551616.0;\n }\n\n /**\n * Generates a random integer in [low, high] (inclusive).\n * Matches BC-UR reference: (self.next_double() * ((high - low + 1) as f64)) as u64 + low\n */\n nextInt(low: number, high: number): number {\n const range = high - low + 1;\n return Math.floor(this.nextDouble() * range) + low;\n }\n\n /**\n * Generates a random byte [0, 255].\n */\n nextByte(): number {\n return Number(this.next() & 0xffn);\n }\n\n /**\n * Generates an array of random bytes.\n */\n nextData(count: number): Uint8Array {\n const result = new Uint8Array(count);\n for (let i = 0; i < count; i++) {\n result[i] = this.nextByte();\n }\n return result;\n }\n\n /**\n * Shuffles items by repeatedly picking random indices.\n * Matches BC-UR reference implementation.\n */\n shuffled<T>(items: T[]): T[] {\n const source = [...items];\n const shuffled: T[] = [];\n while (source.length > 0) {\n const index = this.nextInt(0, source.length - 1);\n const item = source.splice(index, 1)[0];\n if (item !== undefined) {\n shuffled.push(item);\n }\n }\n return shuffled;\n }\n\n /**\n * Chooses the degree (number of fragments to mix) using a weighted sampler.\n * Uses the robust soliton distribution with weights [1/1, 1/2, 1/3, ..., 1/n].\n * Matches BC-UR reference implementation.\n */\n chooseDegree(seqLen: number): number {\n // Create weights: [1/1, 1/2, 1/3, ..., 1/seqLen]\n const weights: number[] = [];\n for (let i = 1; i <= seqLen; i++) {\n weights.push(1.0 / i);\n }\n\n // Use Vose's alias method for weighted sampling\n const sampler = new WeightedSampler(weights);\n return sampler.next(this) + 1; // 1-indexed degree\n }\n}\n\n/**\n * Weighted sampler using Vose's alias method.\n * Allows O(1) sampling from a discrete probability distribution.\n */\nclass WeightedSampler {\n private readonly aliases: number[];\n private readonly probs: number[];\n\n constructor(weights: number[]) {\n const n = weights.length;\n if (n === 0) {\n throw new Error(\"Weights array cannot be empty\");\n }\n\n // Normalize weights\n const sum = weights.reduce((a, b) => a + b, 0);\n if (sum <= 0) {\n throw new Error(\"Weights must sum to a positive value\");\n }\n\n const normalized = weights.map((w) => (w * n) / sum);\n\n // Initialize alias table\n this.aliases = Array.from<number>({ length: n }).fill(0);\n this.probs = Array.from<number>({ length: n }).fill(0);\n\n // Partition into small and large\n const small: number[] = [];\n const large: number[] = [];\n\n for (let i = n - 1; i >= 0; i--) {\n if (normalized[i] < 1.0) {\n small.push(i);\n } else {\n large.push(i);\n }\n }\n\n // Build the alias table\n while (small.length > 0 && large.length > 0) {\n const a = small.pop();\n const g = large.pop();\n if (a === undefined || g === undefined) break;\n this.probs[a] = normalized[a] ?? 0;\n this.aliases[a] = g;\n const normalizedG = normalized[g] ?? 0;\n const normalizedA = normalized[a] ?? 0;\n normalized[g] = normalizedG + normalizedA - 1.0;\n if (normalized[g] !== undefined && normalized[g] < 1.0) {\n small.push(g);\n } else {\n large.push(g);\n }\n }\n\n while (large.length > 0) {\n const g = large.pop();\n if (g === undefined) break;\n this.probs[g] = 1.0;\n }\n\n while (small.length > 0) {\n const a = small.pop();\n if (a === undefined) break;\n this.probs[a] = 1.0;\n }\n }\n\n /**\n * Sample from the distribution.\n */\n next(rng: Xoshiro256): number {\n const r1 = rng.nextDouble();\n const r2 = rng.nextDouble();\n const n = this.probs.length;\n const i = Math.floor(n * r1);\n if (r2 < this.probs[i]) {\n return i;\n } else {\n return this.aliases[i];\n }\n }\n}\n\n/**\n * Creates a Xoshiro256 PRNG instance from message checksum and sequence number.\n *\n * This creates an 8-byte seed by concatenating seqNum and checksum (both in\n * big-endian), then hashes it with SHA-256 to get the 32-byte seed for Xoshiro.\n *\n * This matches the BC-UR reference implementation.\n */\nexport function createSeed(checksum: number, seqNum: number): Uint8Array {\n // Create 8-byte seed: seqNum (big-endian) || checksum (big-endian)\n const seed8 = new Uint8Array(8);\n\n // seqNum in big-endian (bytes 0-3)\n seed8[0] = (seqNum >>> 24) & 0xff;\n seed8[1] = (seqNum >>> 16) & 0xff;\n seed8[2] = (seqNum >>> 8) & 0xff;\n seed8[3] = seqNum & 0xff;\n\n // checksum in big-endian (bytes 4-7)\n seed8[4] = (checksum >>> 24) & 0xff;\n seed8[5] = (checksum >>> 16) & 0xff;\n seed8[6] = (checksum >>> 8) & 0xff;\n seed8[7] = checksum & 0xff;\n\n // Hash with SHA-256 to get 32 bytes\n return sha256(seed8);\n}\n","/**\n * Fountain code implementation for multipart URs.\n *\n * This implements a hybrid fixed-rate and rateless fountain code system\n * as specified in BCR-2020-005 and BCR-2024-001.\n *\n * Key concepts:\n * - Parts 1-seqLen are \"pure\" fragments (fixed-rate)\n * - Parts > seqLen are \"mixed\" fragments using XOR (rateless)\n * - Xoshiro256** PRNG ensures encoder/decoder agree on mixing\n */\n\nimport { Xoshiro256, createSeed } from \"./xoshiro.js\";\nimport { crc32 } from \"./utils.js\";\n\n/**\n * Represents a fountain code part with metadata.\n */\nexport interface FountainPart {\n /** Sequence number (1-based) */\n seqNum: number;\n /** Total number of pure fragments */\n seqLen: number;\n /** Length of original message */\n messageLen: number;\n /** CRC32 checksum of original message */\n checksum: number;\n /** Fragment data */\n data: Uint8Array;\n}\n\n/**\n * Splits data into fragments of the specified size.\n */\nexport function splitMessage(message: Uint8Array, fragmentLen: number): Uint8Array[] {\n const fragments: Uint8Array[] = [];\n const fragmentCount = Math.ceil(message.length / fragmentLen);\n\n for (let i = 0; i < fragmentCount; i++) {\n const start = i * fragmentLen;\n const end = Math.min(start + fragmentLen, message.length);\n const fragment = new Uint8Array(fragmentLen);\n\n // Copy data and pad with zeros if needed\n const sourceSlice = message.slice(start, end);\n fragment.set(sourceSlice);\n\n fragments.push(fragment);\n }\n\n return fragments;\n}\n\n/**\n * XOR two Uint8Arrays together.\n */\nexport function xorBytes(a: Uint8Array, b: Uint8Array): Uint8Array {\n const len = Math.max(a.length, b.length);\n const result = new Uint8Array(len);\n\n for (let i = 0; i < len; i++) {\n result[i] = (a[i] ?? 0) ^ (b[i] ?? 0);\n }\n\n return result;\n}\n\n/**\n * Chooses which fragments to mix for a given sequence number.\n *\n * This uses a seeded Xoshiro256** PRNG to deterministically select fragments,\n * ensuring encoder and decoder agree without explicit coordination.\n *\n * The algorithm matches the BC-UR reference implementation:\n * 1. For pure parts (seqNum <= seqLen), return single fragment index\n * 2. For mixed parts, use weighted sampling to choose degree\n * 3. Shuffle all indices and take the first 'degree' indices\n *\n * @param seqNum - The sequence number (1-based)\n * @param seqLen - Total number of pure fragments\n * @param checksum - CRC32 checksum of the message\n * @returns Array of fragment indices (0-based)\n */\nexport function chooseFragments(seqNum: number, seqLen: number, checksum: number): number[] {\n // Pure parts (seqNum <= seqLen) contain exactly one fragment\n if (seqNum <= seqLen) {\n return [seqNum - 1];\n }\n\n // Mixed parts use PRNG to select fragments\n const seed = createSeed(checksum, seqNum);\n const rng = new Xoshiro256(seed);\n\n // Choose degree using weighted sampler (1/k distribution)\n const degree = rng.chooseDegree(seqLen);\n\n // Create array of all indices [0, 1, 2, ..., seqLen-1]\n const allIndices: number[] = [];\n for (let i = 0; i < seqLen; i++) {\n allIndices.push(i);\n }\n\n // Shuffle all indices and take the first 'degree' indices\n const shuffled = rng.shuffled(allIndices);\n return shuffled.slice(0, degree);\n}\n\n/**\n * Mixes the selected fragments using XOR.\n */\nexport function mixFragments(fragments: Uint8Array[], indices: number[]): Uint8Array {\n if (indices.length === 0) {\n throw new Error(\"No fragments to mix\");\n }\n\n let result: Uint8Array = new Uint8Array(fragments[0].length);\n\n for (const index of indices) {\n const fragment = fragments[index];\n if (fragment === undefined) {\n throw new Error(`Fragment at index ${index} not found`);\n }\n result = xorBytes(result, fragment);\n }\n\n return result;\n}\n\n/**\n * Fountain encoder for creating multipart URs.\n */\nexport class FountainEncoder {\n private readonly fragments: Uint8Array[];\n private readonly messageLen: number;\n private readonly checksum: number;\n private seqNum = 0;\n\n /**\n * Creates a fountain encoder for the given message.\n *\n * @param message - The message to encode\n * @param maxFragmentLen - Maximum length of each fragment\n */\n constructor(message: Uint8Array, maxFragmentLen: number) {\n if (maxFragmentLen < 1) {\n throw new Error(\"Fragment length must be at least 1\");\n }\n\n this.messageLen = message.length;\n this.checksum = crc32(message);\n this.fragments = splitMessage(message, maxFragmentLen);\n }\n\n /**\n * Returns the number of pure fragments.\n */\n get seqLen(): number {\n return this.fragments.length;\n }\n\n /**\n * Returns whether the message fits in a single part.\n */\n isSinglePart(): boolean {\n return this.fragments.length === 1;\n }\n\n /**\n * Returns whether all pure parts have been emitted.\n */\n isComplete(): boolean {\n return this.seqNum >= this.seqLen;\n }\n\n /**\n * Generates the next fountain part.\n */\n nextPart(): FountainPart {\n this.seqNum++;\n\n const indices = chooseFragments(this.seqNum, this.seqLen, this.checksum);\n const data = mixFragments(this.fragments, indices);\n\n return {\n seqNum: this.seqNum,\n seqLen: this.seqLen,\n messageLen: this.messageLen,\n checksum: this.checksum,\n data,\n };\n }\n\n /**\n * Returns the current sequence number.\n */\n currentSeqNum(): number {\n return this.seqNum;\n }\n\n /**\n * Resets the encoder to start from the beginning.\n */\n reset(): void {\n this.seqNum = 0;\n }\n}\n\n/**\n * Fountain decoder for reassembling multipart URs.\n */\nexport class FountainDecoder {\n private seqLen: number | null = null;\n private messageLen: number | null = null;\n private checksum: number | null = null;\n\n // Storage for received data\n private readonly pureFragments = new Map<number, Uint8Array>();\n private readonly mixedParts = new Map<number, { indices: number[]; data: Uint8Array }>();\n\n /**\n * Receives a fountain part and attempts to decode.\n *\n * @param part - The fountain part to receive\n * @returns true if the message is now complete\n */\n receive(part: FountainPart): boolean {\n // Initialize on first part\n if (this.seqLen === null) {\n this.seqLen = part.seqLen;\n this.messageLen = part.messageLen;\n this.checksum = part.checksum;\n }\n\n // Validate consistency\n if (\n part.seqLen !== this.seqLen ||\n part.messageLen !== this.messageLen ||\n part.checksum !== this.checksum\n ) {\n throw new Error(\"Inconsistent part metadata\");\n }\n\n // Determine which fragments this part contains\n const indices = chooseFragments(part.seqNum, this.seqLen, this.checksum);\n\n if (indices.length === 1) {\n // Pure fragment (or degree-1 mixed that acts like pure)\n const index = indices[0];\n if (!this.pureFragments.has(index)) {\n this.pureFragments.set(index, part.data);\n }\n } else {\n // Mixed fragment - store for later reduction\n if (!this.mixedParts.has(part.seqNum)) {\n this.mixedParts.set(part.seqNum, { indices, data: part.data });\n }\n }\n\n // Try to reduce mixed parts\n this.reduceMixedParts();\n\n return this.isComplete();\n }\n\n /**\n * Attempts to extract pure fragments from mixed parts.\n */\n private reduceMixedParts(): void {\n let progress = true;\n\n while (progress) {\n progress = false;\n\n for (const [seqNum, mixed] of this.mixedParts) {\n // Find which indices we're missing\n const missing: number[] = [];\n let reduced = mixed.data;\n\n for (const index of mixed.indices) {\n const pure = this.pureFragments.get(index);\n if (pure !== undefined) {\n // XOR out the known fragment\n reduced = xorBytes(reduced, pure);\n } else {\n missing.push(index);\n }\n }\n\n if (missing.length === 0) {\n // All fragments known, remove this mixed part\n this.mixedParts.delete(seqNum);\n progress = true;\n } else if (missing.length === 1) {\n // Can extract the missing fragment\n const missingIndex = missing[0];\n this.pureFragments.set(missingIndex, reduced);\n this.mixedParts.delete(seqNum);\n progress = true;\n }\n }\n }\n }\n\n /**\n * Returns whether all fragments have been received.\n */\n isComplete(): boolean {\n if (this.seqLen === null) {\n return false;\n }\n\n return this.pureFragments.size === this.seqLen;\n }\n\n /**\n * Reconstructs the original message.\n *\n * @returns The original message, or null if not yet complete\n */\n message(): Uint8Array | null {\n if (!this.isComplete() || this.seqLen === null || this.messageLen === null) {\n return null;\n }\n\n // Calculate fragment size from first fragment\n const firstFragment = this.pureFragments.get(0);\n if (firstFragment === undefined) {\n return null;\n }\n\n const fragmentLen = firstFragment.length;\n const result = new Uint8Array(this.messageLen);\n\n // Assemble fragments\n for (let i = 0; i < this.seqLen; i++) {\n const fragment = this.pureFragments.get(i);\n if (fragment === undefined) {\n return null;\n }\n\n const start = i * fragmentLen;\n const end = Math.min(start + fragmentLen, this.messageLen);\n const len = end - start;\n\n result.set(fragment.slice(0, len), start);\n }\n\n // Verify checksum\n const actualChecksum = crc32(result);\n if (actualChecksum !== this.checksum) {\n throw new Error(`Checksum mismatch: expected ${this.checksum}, got ${actualChecksum}`);\n }\n\n return result;\n }\n\n /**\n * Returns the progress as a fraction (0 to 1).\n */\n progress(): number {\n if (this.seqLen === null) {\n return 0;\n }\n return this.pureFragments.size / this.seqLen;\n }\n\n /**\n * Resets the decoder.\n */\n reset(): void {\n this.seqLen = null;\n this.messageLen = null;\n this.checksum = null;\n this.pureFragments.clear();\n this.mixedParts.clear();\n }\n}\n","import type { UR } from \"./ur.js\";\nimport { URError } from \"./error.js\";\nimport { FountainEncoder, type FountainPart } from \"./fountain.js\";\nimport { encodeBytewords, BytewordsStyle } from \"./utils.js\";\nimport { cbor } from \"@bcts/dcbor\";\n\n/**\n * Encodes a UR as multiple parts using fountain codes.\n *\n * This allows large CBOR structures to be split into multiple UR strings\n * that can be transmitted separately and reassembled. The encoder uses\n * fountain codes for resilient transmission over lossy channels.\n *\n * For single-part URs (small payloads), use the regular UR.string() method.\n *\n * @example\n * ```typescript\n * const ur = UR.new('bytes', cbor);\n * const encoder = new MultipartEncoder(ur, 100);\n *\n * // Generate all pure parts\n * while (!encoder.isComplete()) {\n * const part = encoder.nextPart();\n * console.log(part); // \"ur:bytes/1-10/...\"\n * }\n *\n * // Generate additional rateless parts for redundancy\n * for (let i = 0; i < 5; i++) {\n * const part = encoder.nextPart();\n * console.log(part); // \"ur:bytes/11-10/...\"\n * }\n * ```\n */\nexport class MultipartEncoder {\n private readonly _ur: UR;\n private readonly _fountainEncoder: FountainEncoder;\n private _currentIndex = 0;\n\n /**\n * Creates a new multipart encoder for the given UR.\n *\n * @param ur - The UR to encode\n * @param maxFragmentLen - Maximum length of each fragment in bytes\n * @throws {URError} If encoding fails\n *\n * @example\n * ```typescript\n * const encoder = new MultipartEncoder(ur, 100);\n * ```\n */\n constructor(ur: UR, maxFragmentLen: number) {\n if (maxFragmentLen < 1) {\n throw new URError(\"Max fragment length must be at least 1\");\n }\n this._ur = ur;\n\n // Create fountain encoder from CBOR data\n const cborData = ur.cbor().toData();\n this._fountainEncoder = new FountainEncoder(cborData, maxFragmentLen);\n }\n\n /**\n * Gets the next part of the encoding.\n *\n * Parts 1 through seqLen are \"pure\" fragments containing one piece each.\n * Parts beyond seqLen are \"mixed\" fragments using fountain codes for redundancy.\n *\n * @returns The next UR string part\n *\n * @example\n * ```typescript\n * const part = encoder.nextPart();\n * // Returns: \"ur:bytes/1-3/lsadaoaxjygonesw\"\n * ```\n */\n nextPart(): string {\n const part = this._fountainEncoder.nextPart();\n this._currentIndex++;\n return this._encodePart(part);\n }\n\n /**\n * Encodes a fountain part as a UR string.\n */\n private _encodePart(part: FountainPart): string {\n // For single-part messages, use simple format\n if (part.seqLen === 1) {\n return this._ur.string();\n }\n\n // Encode the part data as CBOR: [seqNum, seqLen, messageLen, checksum, data]\n // Using a simple format: seqNum-seqLen prefix followed by bytewords-encoded part\n const partData = this._encodePartData(part);\n const encoded = encodeBytewords(partData, BytewordsStyle.Minimal);\n\n return `ur:${this._ur.urTypeStr()}/${part.seqNum}-${part.seqLen}/${encoded}`;\n }\n\n /**\n * Encodes part metadata and data as CBOR for bytewords encoding.\n * Format: CBOR array [seqNum, seqLen, messageLen, checksum, data]\n */\n private _encodePartData(part: FountainPart): Uint8Array {\n // Create CBOR array with 5 elements: [seqNum, seqLen, messageLen, checksum, data]\n const cborArray = cbor([part.seqNum, part.seqLen, part.messageLen, part.checksum, part.data]);\n\n return cborArray.toData();\n }\n\n /**\n * Gets the current part index.\n */\n currentIndex(): number {\n return this._currentIndex;\n }\n\n /**\n * Gets the total number of pure parts.\n *\n * Note: Fountain codes can generate unlimited parts beyond this count\n * for additional redundancy.\n */\n partsCount(): number {\n return this._fountainEncoder.seqLen;\n }\n}\n","import { decodeCbor, MajorType, type Cbor } from \"@bcts/dcbor\";\nimport { InvalidSchemeError, InvalidTypeError, UnexpectedTypeError, URError } from \"./error.js\";\nimport { UR } from \"./ur.js\";\nimport { URType } from \"./ur-type.js\";\nimport { FountainDecoder, type FountainPart } from \"./fountain.js\";\nimport { decodeBytewords, BytewordsStyle } from \"./utils.js\";\n\n/**\n * Decodes multiple UR parts back into a single UR.\n *\n * This reassembles multipart URs that were encoded using fountain codes.\n * The decoder can handle out-of-order reception and packet loss.\n *\n * @example\n * ```typescript\n * const decoder = new MultipartDecoder();\n *\n * for (const urPart of urParts) {\n * decoder.receive(urPart);\n * if (decoder.isComplete()) {\n * const ur = decoder.message();\n * break;\n * }\n * }\n * ```\n */\nexport class MultipartDecoder {\n private _urType: URType | null = null;\n private _fountainDecoder: FountainDecoder | null = null;\n private _decodedMessage: UR | null = null;\n\n /**\n * Receives a UR part string.\n *\n * @param part - A UR part string (e.g., \"ur:bytes/1-10/...\" or \"ur:bytes/...\")\n * @throws {InvalidSchemeError} If the part doesn't start with \"ur:\"\n * @throws {UnexpectedTypeError} If the type doesn't match previous parts\n */\n receive(part: string): void {\n const { urType, partInfo } = this._parsePart(part);\n\n // Validate type consistency\n if (this._urType === null) {\n this._urType = urType;\n } else if (!this._urType.equals(urType)) {\n throw new UnexpectedTypeError(this._urType.string(), urType.string());\n }\n\n // Handle the part\n if (partInfo.isSinglePart) {\n // Single-part UR - decode immediately\n this._decodedMessage = UR.fromURString(part);\n } else {\n // Multipart UR - use fountain decoder\n this._fountainDecoder ??= new FountainDecoder();\n\n const fountainPart = this._decodeFountainPart(partInfo);\n this._fountainDecoder.receive(fountainPart);\n\n // Try to get the complete message\n if (this._fountainDecoder.isComplete()) {\n const message = this._fountainDecoder.message();\n if (message !== null) {\n const cbor = decodeCbor(message);\n this._decodedMessage = UR.new(this._urType, cbor);\n }\n }\n }\n }\n\n /**\n * Parses a UR part string to extract type and part info.\n */\n private _parsePart(part: string): { urType: URType; partInfo: PartInfo } {\n const lowercased = part.toLowerCase();\n\n if (!lowercased.startsWith(\"ur:\")) {\n throw new InvalidSchemeError();\n }\n\n const afterScheme = lowercased.substring(3);\n const components = afterScheme.split(\"/\");\n\n if (components.length === 0 || components[0] === \"\") {\n throw new InvalidTypeError();\n }\n\n const urType = new URType(components[0]);\n\n // Check if this is a multipart UR (format: type/seqNum-seqLen/data)\n if (components.length >= 3) {\n const seqPart = components[1];\n const seqMatch = /^(\\d+)-(\\d+)$/.exec(seqPart);\n\n if (seqMatch !== null) {\n const seqNum = parseInt(seqMatch[1], 10);\n const seqLen = parseInt(seqMatch[2], 10);\n const encodedData = components.slice(2).join(\"/\");\n\n return {\n urType,\n partInfo: {\n isSinglePart: false,\n seqNum,\n seqLen,\n encodedData,\n },\n };\n }\n }\n\n // Single-part UR\n return {\n urType,\n partInfo: { isSinglePart: true },\n };\n }\n\n /**\n * Decodes a multipart UR's fountain part data.\n *\n * The multipart body is a CBOR array: [seqNum, seqLen, messageLen, checksum, data]\n */\n private _decodeFountainPart(partInfo: MultipartInfo): FountainPart {\n // Decode bytewords to get CBOR data\n const cborData = decodeBytewords(partInfo.encodedData, BytewordsStyle.Minimal);\n\n // Decode the CBOR array\n const decoded = decodeCbor(cborData);\n\n // The decoded value should be an array with 5 elements\n if (decoded.type !== MajorType.Array) {\n throw new URError(\"Invalid multipart data: expected CBOR array\");\n }\n\n const items = decoded.value as Cbor[];\n if (items.length !== 5) {\n throw new URError(`Invalid multipart data: expected 5 elements, got ${items.length}`);\n }\n\n // Extract the fields: [seqNum, seqLen, messageLen, checksum, data]\n const seqNum = Number(items[0].value);\n const seqLen = Number(items[1].value);\n const messageLen = Number(items[2].value);\n const checksum = Number(items[3].value);\n const data = items[4].value as Uint8Array;\n\n // Verify seqNum and seqLen match the URL path values\n if (seqNum !== partInfo.seqNum || seqLen !== partInfo.seqLen) {\n throw new URError(\n `Multipart metadata mismatch: URL says ${partInfo.seqNum}-${partInfo.seqLen}, CBOR says ${seqNum}-${seqLen}`,\n );\n }\n\n return {\n seqNum,\n seqLen,\n messageLen,\n checksum,\n data,\n };\n }\n\n /**\n * Checks if the message is complete.\n */\n isComplete(): boolean {\n return this._decodedMessage !== null;\n }\n\n /**\n * Gets the decoded UR message.\n *\n * @returns The decoded UR, or null if not yet complete\n */\n message(): UR | null {\n return this._decodedMessage;\n }\n}\n\n/**\n * Part info for single-part URs.\n */\ninterface SinglePartInfo {\n isSinglePart: true;\n}\n\n/**\n * Part info for multipart URs.\n */\ninterface MultipartInfo {\n isSinglePart: false;\n seqNum: number;\n seqLen: number;\n encodedData: string;\n}\n\ntype PartInfo = SinglePartInfo | MultipartInfo;\n"],"mappings":";;;;;;;CAGA,IAAa,UAAb,cAA6B,MAAM;EACjC,YAAY,SAAiB;AAC3B,SAAM,QAAQ;AACd,QAAK,OAAO;;;;;;CAOhB,IAAa,qBAAb,cAAwC,QAAQ;EAC9C,cAAc;AACZ,SAAM,oBAAoB;AAC1B,QAAK,OAAO;;;;;;CAOhB,IAAa,uBAAb,cAA0C,QAAQ;EAChD,cAAc;AACZ,SAAM,uBAAuB;AAC7B,QAAK,OAAO;;;;;;CAOhB,IAAa,mBAAb,cAAsC,QAAQ;EAC5C,cAAc;AACZ,SAAM,kBAAkB;AACxB,QAAK,OAAO;;;;;;CAOhB,IAAa,qBAAb,cAAwC,QAAQ;EAC9C,cAAc;AACZ,SAAM,0BAA0B;AAChC,QAAK,OAAO;;;;;;CAOhB,IAAa,sBAAb,cAAyC,QAAQ;EAC/C,YAAY,UAAkB,OAAe;AAC3C,SAAM,oBAAoB,SAAS,cAAc,QAAQ;AACzD,QAAK,OAAO;;;;;;CAOhB,IAAa,iBAAb,cAAoC,QAAQ;EAC1C,YAAY,SAAiB;AAC3B,SAAM,oBAAoB,UAAU;AACpC,QAAK,OAAO;;;;;;CAOhB,IAAa,YAAb,cAA+B,QAAQ;EACrC,YAAY,SAAiB;AAC3B,SAAM,eAAe,UAAU;AAC/B,QAAK,OAAO;;;;;;;CAQhB,IAAa,gBAAb,cAAmC,QAAQ;EACzC,YAAY,SAAiB;AAC3B,SAAM,qBAAqB,QAAQ,GAAG;AACtC,QAAK,OAAO;;;;;;CAShB,SAAgB,QAAQ,QAAkC;AACxD,SAAO,kBAAkB;;;;;;;;;CC3F3B,SAAgB,aAAa,MAAuB;EAClD,MAAM,OAAO,KAAK,WAAW,EAAE;AAE/B,MAAI,QAAQ,MAAM,QAAQ,IAAK,QAAO;AAEtC,MAAI,QAAQ,MAAM,QAAQ,GAAI,QAAO;AAErC,MAAI,SAAS,GAAI,QAAO;AACxB,SAAO;;;;;;CAOT,SAAgB,cAAc,QAAyB;AACrD,MAAI,OAAO,WAAW,EAAG,QAAO;AAChC,SAAO,MAAM,KAAK,OAAO,CAAC,OAAO,SAAS,aAAa,KAAK,CAAC;;;;;;CAiB/D,MAAa,YAAsB;EACjC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD;;;;CAKD,SAAS,qBAA0C;EACjD,MAAM,sBAAM,IAAI,KAAqB;AACrC,YAAU,SAAS,MAAM,UAAU;AACjC,OAAI,IAAI,MAAM,MAAM;IACpB;AACF,SAAO;;CAGT,MAAa,gBAAgB,oBAAoB;;;;;CAMjD,MAAa,YAAsB;EACjC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAC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"}
1
+ {"version":3,"file":"index.iife.js","names":["MajorType"],"sources":["../src/error.ts","../src/utils.ts","../src/ur-type.ts","../src/ur.ts","../src/ur-encodable.ts","../src/ur-decodable.ts","../src/ur-codable.ts","../src/xoshiro.ts","../src/fountain.ts","../src/multipart-encoder.ts","../src/multipart-decoder.ts"],"sourcesContent":["/**\n * Error type for UR encoding/decoding operations.\n */\nexport class URError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"URError\";\n }\n}\n\n/**\n * Error type for invalid UR schemes.\n */\nexport class InvalidSchemeError extends URError {\n constructor() {\n super(\"Invalid UR scheme\");\n this.name = \"InvalidSchemeError\";\n }\n}\n\n/**\n * Error type for unspecified UR types.\n */\nexport class TypeUnspecifiedError extends URError {\n constructor() {\n super(\"No UR type specified\");\n this.name = \"TypeUnspecifiedError\";\n }\n}\n\n/**\n * Error type for invalid UR types.\n */\nexport class InvalidTypeError extends URError {\n constructor() {\n super(\"Invalid UR type\");\n this.name = \"InvalidTypeError\";\n }\n}\n\n/**\n * Error type for non-single-part URs.\n */\nexport class NotSinglePartError extends URError {\n constructor() {\n super(\"UR is not a single-part\");\n this.name = \"NotSinglePartError\";\n }\n}\n\n/**\n * Error type for unexpected UR types.\n */\nexport class UnexpectedTypeError extends URError {\n constructor(expected: string, found: string) {\n super(`Expected UR type ${expected}, but found ${found}`);\n this.name = \"UnexpectedTypeError\";\n }\n}\n\n/**\n * Error type for Bytewords encoding/decoding errors.\n */\nexport class BytewordsError extends URError {\n constructor(message: string) {\n super(`Bytewords error: ${message}`);\n this.name = \"BytewordsError\";\n }\n}\n\n/**\n * Error type for CBOR encoding/decoding errors.\n */\nexport class CBORError extends URError {\n constructor(message: string) {\n super(`CBOR error: ${message}`);\n this.name = \"CBORError\";\n }\n}\n\n/**\n * Error type for UR decoder errors.\n * Matches Rust's Error::UR(String) variant.\n */\nexport class URDecodeError extends URError {\n constructor(message: string) {\n super(`UR decoder error (${message})`);\n this.name = \"URDecodeError\";\n }\n}\n\nexport type Result<T> = T | Error;\n\n/**\n * Helper function to check if a result is an error.\n */\nexport function isError(result: unknown): result is Error {\n return result instanceof Error;\n}\n","import { InvalidTypeError } from \"./error.js\";\n\n/**\n * Checks if a character is a valid UR type character.\n * Valid characters are lowercase letters, digits, and hyphens.\n */\nexport function isURTypeChar(char: string): boolean {\n const code = char.charCodeAt(0);\n // Check for lowercase letters (a-z)\n if (code >= 97 && code <= 122) return true;\n // Check for digits (0-9)\n if (code >= 48 && code <= 57) return true;\n // Check for hyphen (-)\n if (code === 45) return true;\n return false;\n}\n\n/**\n * Checks if a string is a valid UR type.\n * Valid UR types contain only lowercase letters, digits, and hyphens.\n */\nexport function isValidURType(urType: string): boolean {\n if (urType.length === 0) return false;\n return Array.from(urType).every((char) => isURTypeChar(char));\n}\n\n/**\n * Validates and returns a UR type, or throws an error if invalid.\n */\nexport function validateURType(urType: string): string {\n if (!isValidURType(urType)) {\n throw new InvalidTypeError();\n }\n return urType;\n}\n\n/**\n * Bytewords for encoding/decoding bytes as words.\n * See: https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-004-bytewords.md\n */\nexport const BYTEWORDS: string[] = [\n \"able\",\n \"acid\",\n \"also\",\n \"apex\",\n \"aqua\",\n \"arch\",\n \"atom\",\n \"aunt\",\n \"away\",\n \"axis\",\n \"back\",\n \"bald\",\n \"barn\",\n \"belt\",\n \"beta\",\n \"bias\",\n \"blue\",\n \"body\",\n \"brag\",\n \"brew\",\n \"bulb\",\n \"buzz\",\n \"calm\",\n \"cash\",\n \"cats\",\n \"chef\",\n \"city\",\n \"claw\",\n \"code\",\n \"cola\",\n \"cook\",\n \"cost\",\n \"crux\",\n \"curl\",\n \"cusp\",\n \"cyan\",\n \"dark\",\n \"data\",\n \"days\",\n \"deli\",\n \"dice\",\n \"diet\",\n \"door\",\n \"down\",\n \"draw\",\n \"drop\",\n \"drum\",\n \"dull\",\n \"duty\",\n \"each\",\n \"easy\",\n \"echo\",\n \"edge\",\n \"epic\",\n \"even\",\n \"exam\",\n \"exit\",\n \"eyes\",\n \"fact\",\n \"fair\",\n \"fern\",\n \"figs\",\n \"film\",\n \"fish\",\n \"fizz\",\n \"flap\",\n \"flew\",\n \"flux\",\n \"foxy\",\n \"free\",\n \"frog\",\n \"fuel\",\n \"fund\",\n \"gala\",\n \"game\",\n \"gear\",\n \"gems\",\n \"gift\",\n \"girl\",\n \"glow\",\n \"good\",\n \"gray\",\n \"grim\",\n \"guru\",\n \"gush\",\n \"gyro\",\n \"half\",\n \"hang\",\n \"hard\",\n \"hawk\",\n \"heat\",\n \"help\",\n \"high\",\n \"hill\",\n \"holy\",\n \"hope\",\n \"horn\",\n \"huts\",\n \"iced\",\n \"idea\",\n \"idle\",\n \"inch\",\n \"inky\",\n \"into\",\n \"iris\",\n \"iron\",\n \"item\",\n \"jade\",\n \"jazz\",\n \"join\",\n \"jolt\",\n \"jowl\",\n \"judo\",\n \"jugs\",\n \"jump\",\n \"junk\",\n \"jury\",\n \"keep\",\n \"keno\",\n \"kept\",\n \"keys\",\n \"kick\",\n \"kiln\",\n \"king\",\n \"kite\",\n \"kiwi\",\n \"knob\",\n \"lamb\",\n \"lava\",\n \"lazy\",\n \"leaf\",\n \"legs\",\n \"liar\",\n \"limp\",\n \"lion\",\n \"list\",\n \"logo\",\n \"loud\",\n \"love\",\n \"luau\",\n \"luck\",\n \"lung\",\n \"main\",\n \"many\",\n \"math\",\n \"maze\",\n \"memo\",\n \"menu\",\n \"meow\",\n \"mild\",\n \"mint\",\n \"miss\",\n \"monk\",\n \"nail\",\n \"navy\",\n \"need\",\n \"news\",\n \"next\",\n \"noon\",\n \"note\",\n \"numb\",\n \"obey\",\n \"oboe\",\n \"omit\",\n \"onyx\",\n \"open\",\n \"oval\",\n \"owls\",\n \"paid\",\n \"part\",\n \"peck\",\n \"play\",\n \"plus\",\n \"poem\",\n \"pool\",\n \"pose\",\n \"puff\",\n \"puma\",\n \"purr\",\n \"quad\",\n \"quiz\",\n \"race\",\n \"ramp\",\n \"real\",\n \"redo\",\n \"rich\",\n \"road\",\n \"rock\",\n \"roof\",\n \"ruby\",\n \"ruin\",\n \"runs\",\n \"rust\",\n \"safe\",\n \"saga\",\n \"scar\",\n \"sets\",\n \"silk\",\n \"skew\",\n \"slot\",\n \"soap\",\n \"solo\",\n \"song\",\n \"stub\",\n \"surf\",\n \"swan\",\n \"taco\",\n \"task\",\n \"taxi\",\n \"tent\",\n \"tied\",\n \"time\",\n \"tiny\",\n \"toil\",\n \"tomb\",\n \"toys\",\n \"trip\",\n \"tuna\",\n \"twin\",\n \"ugly\",\n \"undo\",\n \"unit\",\n \"urge\",\n \"user\",\n \"vast\",\n \"very\",\n \"veto\",\n \"vial\",\n \"vibe\",\n \"view\",\n \"visa\",\n \"void\",\n \"vows\",\n \"wall\",\n \"wand\",\n \"warm\",\n \"wasp\",\n \"wave\",\n \"waxy\",\n \"webs\",\n \"what\",\n \"when\",\n \"whiz\",\n \"wolf\",\n \"work\",\n \"yank\",\n \"yawn\",\n \"yell\",\n \"yoga\",\n \"yurt\",\n \"zaps\",\n \"zero\",\n \"zest\",\n \"zinc\",\n \"zone\",\n \"zoom\",\n];\n\n/**\n * Create a reverse mapping for fast byteword lookup.\n */\nfunction createBytewordsMap(): Map<string, number> {\n const map = new Map<string, number>();\n BYTEWORDS.forEach((word, index) => {\n map.set(word, index);\n });\n return map;\n}\n\nexport const BYTEWORDS_MAP = createBytewordsMap();\n\n/**\n * Bytemojis for encoding/decoding bytes as emojis.\n * See: https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2024-008-bytemoji.md\n */\nexport const BYTEMOJIS: string[] = [\n \"๐Ÿ˜€\",\n \"๐Ÿ˜‚\",\n \"๐Ÿ˜†\",\n \"๐Ÿ˜‰\",\n \"๐Ÿ™„\",\n \"๐Ÿ˜‹\",\n \"๐Ÿ˜Ž\",\n \"๐Ÿ˜\",\n \"๐Ÿ˜˜\",\n \"๐Ÿ˜ญ\",\n \"๐Ÿซ \",\n \"๐Ÿฅฑ\",\n \"๐Ÿคฉ\",\n \"๐Ÿ˜ถ\",\n \"๐Ÿคจ\",\n \"๐Ÿซฅ\",\n \"๐Ÿฅต\",\n \"๐Ÿฅถ\",\n \"๐Ÿ˜ณ\",\n \"๐Ÿคช\",\n \"๐Ÿ˜ต\",\n \"๐Ÿ˜ก\",\n \"๐Ÿคข\",\n \"๐Ÿ˜‡\",\n \"๐Ÿค \",\n \"๐Ÿคก\",\n \"๐Ÿฅณ\",\n \"๐Ÿฅบ\",\n \"๐Ÿ˜ฌ\",\n \"๐Ÿค‘\",\n \"๐Ÿ™ƒ\",\n \"๐Ÿคฏ\",\n \"๐Ÿ˜ˆ\",\n \"๐Ÿ‘น\",\n \"๐Ÿ‘บ\",\n \"๐Ÿ’€\",\n \"๐Ÿ‘ป\",\n \"๐Ÿ‘ฝ\",\n \"๐Ÿ˜บ\",\n \"๐Ÿ˜น\",\n \"๐Ÿ˜ป\",\n \"๐Ÿ˜ฝ\",\n \"๐Ÿ™€\",\n \"๐Ÿ˜ฟ\",\n \"๐Ÿซถ\",\n \"๐Ÿคฒ\",\n \"๐Ÿ™Œ\",\n \"๐Ÿค\",\n \"๐Ÿ‘\",\n \"๐Ÿ‘Ž\",\n \"๐Ÿ‘ˆ\",\n \"๐Ÿ‘†\",\n \"๐Ÿ’ช\",\n \"๐Ÿ‘„\",\n \"๐Ÿฆท\",\n \"๐Ÿ‘‚\",\n \"๐Ÿ‘ƒ\",\n \"๐Ÿง \",\n \"๐Ÿ‘€\",\n \"๐Ÿคš\",\n \"๐Ÿฆถ\",\n \"๐ŸŽ\",\n \"๐ŸŠ\",\n \"๐Ÿ‹\",\n \"๐ŸŒ\",\n \"๐Ÿ‰\",\n \"๐Ÿ‡\",\n \"๐Ÿ“\",\n \"๐Ÿซ\",\n \"๐Ÿ’\",\n \"๐Ÿ‘\",\n \"๐Ÿ\",\n \"๐Ÿฅ\",\n \"๐Ÿ†\",\n \"๐Ÿฅ‘\",\n \"๐Ÿฅฆ\",\n \"๐Ÿ…\",\n \"๐ŸŒฝ\",\n \"๐Ÿฅ•\",\n \"๐Ÿซ’\",\n \"๐Ÿง„\",\n \"๐Ÿฅ\",\n \"๐Ÿฅฏ\",\n \"๐Ÿž\",\n \"๐Ÿง€\",\n \"๐Ÿฅš\",\n \"๐Ÿ—\",\n \"๐ŸŒญ\",\n \"๐Ÿ”\",\n \"๐ŸŸ\",\n \"๐Ÿ•\",\n \"๐ŸŒฎ\",\n \"๐Ÿฅ™\",\n \"๐Ÿฑ\",\n \"๐Ÿœ\",\n \"๐Ÿค\",\n \"๐Ÿš\",\n \"๐Ÿฅ \",\n \"๐Ÿจ\",\n \"๐Ÿฆ\",\n \"๐ŸŽ‚\",\n \"๐Ÿชด\",\n \"๐ŸŒต\",\n \"๐ŸŒฑ\",\n \"๐Ÿ’\",\n \"๐Ÿ\",\n \"๐Ÿ„\",\n \"๐ŸŒน\",\n \"๐ŸŒบ\",\n \"๐ŸŒผ\",\n \"๐ŸŒป\",\n \"๐ŸŒธ\",\n \"๐Ÿ’จ\",\n \"๐ŸŒŠ\",\n \"๐Ÿ’ง\",\n \"๐Ÿ’ฆ\",\n \"๐ŸŒ€\",\n \"๐ŸŒˆ\",\n \"๐ŸŒž\",\n \"๐ŸŒ\",\n \"๐ŸŒ›\",\n \"๐ŸŒœ\",\n \"๐ŸŒ™\",\n \"๐ŸŒŽ\",\n \"๐Ÿ’ซ\",\n \"โญ\",\n \"๐Ÿช\",\n \"๐ŸŒ\",\n \"๐Ÿ’›\",\n \"๐Ÿ’”\",\n \"๐Ÿ’˜\",\n \"๐Ÿ’–\",\n \"๐Ÿ’•\",\n \"๐Ÿ\",\n \"๐Ÿšฉ\",\n \"๐Ÿ’ฌ\",\n \"๐Ÿ’ฏ\",\n \"๐Ÿšซ\",\n \"๐Ÿ”ด\",\n \"๐Ÿ”ท\",\n \"๐ŸŸฉ\",\n \"๐Ÿ›‘\",\n \"๐Ÿ”บ\",\n \"๐Ÿš—\",\n \"๐Ÿš‘\",\n \"๐Ÿš’\",\n \"๐Ÿšœ\",\n \"๐Ÿ›ต\",\n \"๐Ÿšจ\",\n \"๐Ÿš€\",\n \"๐Ÿš\",\n \"๐Ÿ›Ÿ\",\n \"๐Ÿšฆ\",\n \"๐Ÿฐ\",\n \"๐ŸŽก\",\n \"๐ŸŽข\",\n \"๐ŸŽ \",\n \"๐Ÿ \",\n \"๐Ÿ””\",\n \"๐Ÿ”‘\",\n \"๐Ÿšช\",\n \"๐Ÿช‘\",\n \"๐ŸŽˆ\",\n \"๐Ÿ’Œ\",\n \"๐Ÿ“ฆ\",\n \"๐Ÿ“ซ\",\n \"๐Ÿ“–\",\n \"๐Ÿ“š\",\n \"๐Ÿ“Œ\",\n \"๐Ÿงฎ\",\n \"๐Ÿ”’\",\n \"๐Ÿ’Ž\",\n \"๐Ÿ“ท\",\n \"โฐ\",\n \"โณ\",\n \"๐Ÿ“ก\",\n \"๐Ÿ’ก\",\n \"๐Ÿ’ฐ\",\n \"๐Ÿงฒ\",\n \"๐Ÿงธ\",\n \"๐ŸŽ\",\n \"๐ŸŽ€\",\n \"๐ŸŽ‰\",\n \"๐Ÿชญ\",\n \"๐Ÿ‘‘\",\n \"๐Ÿซ–\",\n \"๐Ÿ”ญ\",\n \"๐Ÿ›\",\n \"๐Ÿ†\",\n \"๐Ÿฅ\",\n \"๐ŸŽท\",\n \"๐ŸŽบ\",\n \"๐Ÿ€\",\n \"๐Ÿˆ\",\n \"๐ŸŽพ\",\n \"๐Ÿ“\",\n \"โœจ\",\n \"๐Ÿ”ฅ\",\n \"๐Ÿ’ฅ\",\n \"๐Ÿ‘•\",\n \"๐Ÿ‘š\",\n \"๐Ÿ‘–\",\n \"๐Ÿฉณ\",\n \"๐Ÿ‘—\",\n \"๐Ÿ‘”\",\n \"๐Ÿงข\",\n \"๐Ÿ‘“\",\n \"๐Ÿงถ\",\n \"๐Ÿงต\",\n \"๐Ÿ’\",\n \"๐Ÿ‘ \",\n \"๐Ÿ‘Ÿ\",\n \"๐Ÿงฆ\",\n \"๐Ÿงค\",\n \"๐Ÿ‘’\",\n \"๐Ÿ‘œ\",\n \"๐Ÿฑ\",\n \"๐Ÿถ\",\n \"๐Ÿญ\",\n \"๐Ÿน\",\n \"๐Ÿฐ\",\n \"๐ŸฆŠ\",\n \"๐Ÿป\",\n \"๐Ÿผ\",\n \"๐Ÿจ\",\n \"๐Ÿฏ\",\n \"๐Ÿฆ\",\n \"๐Ÿฎ\",\n \"๐Ÿท\",\n \"๐Ÿธ\",\n \"๐Ÿต\",\n \"๐Ÿ”\",\n \"๐Ÿฅ\",\n \"๐Ÿฆ†\",\n \"๐Ÿฆ‰\",\n \"๐Ÿด\",\n \"๐Ÿฆ„\",\n \"๐Ÿ\",\n \"๐Ÿ›\",\n \"๐Ÿฆ‹\",\n \"๐ŸŒ\",\n \"๐Ÿž\",\n \"๐Ÿข\",\n \"๐Ÿบ\",\n \"๐Ÿ\",\n \"๐Ÿชฝ\",\n \"๐Ÿ™\",\n \"๐Ÿฆ‘\",\n \"๐Ÿชผ\",\n \"๐Ÿฆž\",\n \"๐Ÿฆ€\",\n \"๐Ÿš\",\n \"๐Ÿฆญ\",\n \"๐ŸŸ\",\n \"๐Ÿฌ\",\n \"๐Ÿณ\",\n];\n\n/**\n * Encodes a 4-byte slice as a string of bytewords for identification.\n */\nexport function encodeBytewordsIdentifier(data: Uint8Array): string {\n if (data.length !== 4) {\n throw new Error(\"Identifier data must be exactly 4 bytes\");\n }\n const words: string[] = [];\n for (let i = 0; i < 4; i++) {\n const byte = data[i];\n if (byte === undefined) throw new Error(\"Invalid byte\");\n const word = BYTEWORDS[byte];\n if (word === \"\" || word === undefined) throw new Error(\"Invalid byteword mapping\");\n words.push(word);\n }\n return words.join(\" \");\n}\n\n/**\n * Encodes a 4-byte slice as a string of bytemojis for identification.\n */\nexport function encodeBytemojisIdentifier(data: Uint8Array): string {\n if (data.length !== 4) {\n throw new Error(\"Identifier data must be exactly 4 bytes\");\n }\n const emojis: string[] = [];\n for (let i = 0; i < 4; i++) {\n const byte = data[i];\n if (byte === undefined) throw new Error(\"Invalid byte\");\n const emoji = BYTEMOJIS[byte];\n if (emoji === \"\" || emoji === undefined) throw new Error(\"Invalid bytemoji mapping\");\n emojis.push(emoji);\n }\n return emojis.join(\" \");\n}\n\n/**\n * Bytewords encoding style.\n */\nexport enum BytewordsStyle {\n /** Full 4-letter words separated by spaces */\n Standard = \"standard\",\n /** Full 4-letter words separated by hyphens (URI-safe) */\n Uri = \"uri\",\n /** First and last character only (minimal) - used by UR encoding */\n Minimal = \"minimal\",\n}\n\n/**\n * Create a reverse mapping for minimal bytewords (first+last char) lookup.\n */\nfunction createMinimalBytewordsMap(): Map<string, number> {\n const map = new Map<string, number>();\n BYTEWORDS.forEach((word, index) => {\n // Minimal encoding uses first and last character\n const minimal = word[0] + word[3];\n map.set(minimal, index);\n });\n return map;\n}\n\nexport const MINIMAL_BYTEWORDS_MAP = createMinimalBytewordsMap();\n\n/**\n * CRC32 lookup table (IEEE polynomial).\n */\nconst CRC32_TABLE: number[] = (() => {\n const table: number[] = [];\n for (let i = 0; i < 256; i++) {\n let c = i;\n for (let j = 0; j < 8; j++) {\n c = (c & 1) !== 0 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;\n }\n table.push(c >>> 0);\n }\n return table;\n})();\n\n/**\n * Calculate CRC32 checksum of data.\n */\nexport function crc32(data: Uint8Array): number {\n let crc = 0xffffffff;\n for (const byte of data) {\n crc = (CRC32_TABLE[(crc ^ byte) & 0xff] ^ (crc >>> 8)) >>> 0;\n }\n return (crc ^ 0xffffffff) >>> 0;\n}\n\n/**\n * Convert a 32-bit number to 4 bytes (big-endian).\n */\nfunction uint32ToBytes(value: number): Uint8Array {\n return new Uint8Array([\n (value >>> 24) & 0xff,\n (value >>> 16) & 0xff,\n (value >>> 8) & 0xff,\n value & 0xff,\n ]);\n}\n\n/**\n * Encode data as bytewords with the specified style.\n * Includes CRC32 checksum.\n */\nexport function encodeBytewords(\n data: Uint8Array,\n style: BytewordsStyle = BytewordsStyle.Minimal,\n): string {\n // Append CRC32 checksum\n const checksum = crc32(data);\n const checksumBytes = uint32ToBytes(checksum);\n const dataWithChecksum = new Uint8Array(data.length + 4);\n dataWithChecksum.set(data);\n dataWithChecksum.set(checksumBytes, data.length);\n\n const words: string[] = [];\n for (const byte of dataWithChecksum) {\n const word = BYTEWORDS[byte];\n if (word === undefined) throw new Error(`Invalid byte value: ${byte}`);\n\n switch (style) {\n case BytewordsStyle.Standard:\n words.push(word);\n break;\n case BytewordsStyle.Uri:\n words.push(word);\n break;\n case BytewordsStyle.Minimal:\n // First and last character\n words.push(word[0] + word[3]);\n break;\n }\n }\n\n switch (style) {\n case BytewordsStyle.Standard:\n return words.join(\" \");\n case BytewordsStyle.Uri:\n return words.join(\"-\");\n case BytewordsStyle.Minimal:\n return words.join(\"\");\n }\n}\n\n/**\n * Decode bytewords string back to data.\n * Validates and removes CRC32 checksum.\n */\nexport function decodeBytewords(\n encoded: string,\n style: BytewordsStyle = BytewordsStyle.Minimal,\n): Uint8Array {\n const lowercased = encoded.toLowerCase();\n let bytes: number[];\n\n switch (style) {\n case BytewordsStyle.Standard: {\n const words = lowercased.split(\" \");\n bytes = words.map((word) => {\n const index = BYTEWORDS_MAP.get(word);\n if (index === undefined) {\n throw new Error(`Invalid byteword: ${word}`);\n }\n return index;\n });\n break;\n }\n case BytewordsStyle.Uri: {\n // 4-character words separated by hyphens\n const words = lowercased.split(\"-\");\n bytes = words.map((word) => {\n const index = BYTEWORDS_MAP.get(word);\n if (index === undefined) {\n throw new Error(`Invalid byteword: ${word}`);\n }\n return index;\n });\n break;\n }\n case BytewordsStyle.Minimal: {\n // 2-character minimal words with no separator\n if (lowercased.length % 2 !== 0) {\n throw new Error(\"Invalid minimal bytewords length\");\n }\n bytes = [];\n for (let i = 0; i < lowercased.length; i += 2) {\n const minimal = lowercased.slice(i, i + 2);\n const index = MINIMAL_BYTEWORDS_MAP.get(minimal);\n if (index === undefined) {\n throw new Error(`Invalid minimal byteword: ${minimal}`);\n }\n bytes.push(index);\n }\n break;\n }\n }\n\n if (bytes.length < 4) {\n throw new Error(\"Bytewords data too short (missing checksum)\");\n }\n\n // Extract data and checksum\n const dataWithChecksum = new Uint8Array(bytes);\n const data = dataWithChecksum.slice(0, -4);\n const checksumBytes = dataWithChecksum.slice(-4);\n\n // Verify checksum\n const expectedChecksum = crc32(data);\n const actualChecksum =\n ((checksumBytes[0] << 24) |\n (checksumBytes[1] << 16) |\n (checksumBytes[2] << 8) |\n checksumBytes[3]) >>>\n 0;\n\n if (expectedChecksum !== actualChecksum) {\n throw new Error(\n `Bytewords checksum mismatch: expected ${expectedChecksum.toString(16)}, got ${actualChecksum.toString(16)}`,\n );\n }\n\n return data;\n}\n","import { InvalidTypeError } from \"./error\";\nimport { isValidURType } from \"./utils\";\n\n/**\n * Represents a UR (Uniform Resource) type identifier.\n *\n * Valid UR types contain only lowercase letters, digits, and hyphens.\n *\n * @example\n * ```typescript\n * const urType = new URType('test');\n * console.log(urType.string()); // \"test\"\n * ```\n */\nexport class URType {\n private readonly _type: string;\n\n /**\n * Creates a new URType from the provided type string.\n *\n * @param urType - The UR type as a string\n * @throws {InvalidTypeError} If the type contains invalid characters\n *\n * @example\n * ```typescript\n * const urType = new URType('test');\n * ```\n */\n constructor(urType: string) {\n if (!isValidURType(urType)) {\n throw new InvalidTypeError();\n }\n this._type = urType;\n }\n\n /**\n * Returns the string representation of the URType.\n *\n * @example\n * ```typescript\n * const urType = new URType('test');\n * console.log(urType.string()); // \"test\"\n * ```\n */\n string(): string {\n return this._type;\n }\n\n /**\n * Checks equality with another URType based on the type string.\n */\n equals(other: URType): boolean {\n return this._type === other._type;\n }\n\n /**\n * Returns the string representation.\n */\n toString(): string {\n return this._type;\n }\n\n /**\n * Creates a URType from a string, throwing an error if invalid.\n *\n * @param value - The UR type string\n * @returns A new URType instance\n * @throws {InvalidTypeError} If the type is invalid\n */\n static from(value: string): URType {\n return new URType(value);\n }\n\n /**\n * Safely creates a URType, returning an error if invalid.\n *\n * @param value - The UR type string\n * @returns Either a URType or an error\n */\n static tryFrom(value: string): URType | InvalidTypeError {\n try {\n return new URType(value);\n } catch (error) {\n return error as InvalidTypeError;\n }\n }\n}\n","import type { Cbor } from \"@bcts/dcbor\";\nimport { decodeCbor } from \"@bcts/dcbor\";\nimport { InvalidSchemeError, TypeUnspecifiedError, UnexpectedTypeError, URError } from \"./error.js\";\nimport { URType } from \"./ur-type.js\";\nimport { encodeBytewords, decodeBytewords, BytewordsStyle } from \"./utils.js\";\n\n/**\n * A Uniform Resource (UR) is a URI-encoded CBOR object.\n *\n * URs are defined in [BCR-2020-005: Uniform Resources](https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-005-ur.md).\n *\n * @example\n * ```typescript\n * import { UR } from '@bcts/uniform-resources';\n * import { CBOR } from '@bcts/dcbor';\n *\n * // Create a UR from a CBOR object\n * const cbor = CBOR.fromArray([1, 2, 3]);\n * const ur = UR.new('test', cbor);\n *\n * // Encode to string\n * const urString = ur.string();\n * console.log(urString); // \"ur:test/...\"\n *\n * // Decode from string\n * const decodedUR = UR.fromURString(urString);\n * console.log(decodedUR.urTypeStr()); // \"test\"\n * ```\n */\nexport class UR {\n private readonly _urType: URType;\n private readonly _cbor: Cbor;\n\n /**\n * Creates a new UR from the provided type and CBOR data.\n *\n * @param urType - The UR type (will be validated)\n * @param cbor - The CBOR data to encode\n * @throws {InvalidTypeError} If the type is invalid\n *\n * @example\n * ```typescript\n * const ur = UR.new('bytes', CBOR.fromString('hello'));\n * ```\n */\n static new(urType: string | URType, cbor: Cbor): UR {\n const type = typeof urType === \"string\" ? new URType(urType) : urType;\n return new UR(type, cbor);\n }\n\n /**\n * Creates a new UR from a UR string.\n *\n * @param urString - A UR string like \"ur:test/...\"\n * @throws {InvalidSchemeError} If the string doesn't start with \"ur:\"\n * @throws {TypeUnspecifiedError} If no type is specified\n * @throws {NotSinglePartError} If the UR is multi-part\n * @throws {URError} If decoding fails\n *\n * @example\n * ```typescript\n * const ur = UR.fromURString('ur:test/lsadaoaxjygonesw');\n * ```\n */\n static fromURString(urString: string): UR {\n // Decode the UR string to get the type and CBOR data\n const decodedUR = URStringDecoder.decode(urString);\n if (decodedUR === null || decodedUR === undefined) {\n throw new URError(\"Failed to decode UR string\");\n }\n const { urType, cbor } = decodedUR;\n return new UR(new URType(urType), cbor);\n }\n\n private constructor(urType: URType, cbor: Cbor) {\n this._urType = urType;\n this._cbor = cbor;\n }\n\n /**\n * Returns the UR type.\n */\n urType(): URType {\n return this._urType;\n }\n\n /**\n * Returns the UR type as a string.\n */\n urTypeStr(): string {\n return this._urType.string();\n }\n\n /**\n * Returns the CBOR data.\n */\n cbor(): Cbor {\n return this._cbor;\n }\n\n /**\n * Returns the string representation of the UR (lowercase, suitable for display).\n *\n * @example\n * ```typescript\n * const ur = UR.new('test', CBOR.fromArray([1, 2, 3]));\n * console.log(ur.string()); // \"ur:test/lsadaoaxjygonesw\"\n * ```\n */\n string(): string {\n const cborData = this._cbor.toData();\n return URStringEncoder.encode(this._urType.string(), cborData);\n }\n\n /**\n * Returns the QR string representation (uppercase, most efficient for QR codes).\n */\n qrString(): string {\n return this.string().toUpperCase();\n }\n\n /**\n * Returns the QR data as bytes (uppercase UR string as UTF-8).\n */\n qrData(): Uint8Array {\n // Use a helper to convert string to bytes across platforms\n const str = this.qrString();\n const bytes = new Uint8Array(str.length);\n for (let i = 0; i < str.length; i++) {\n bytes[i] = str.charCodeAt(i);\n }\n return bytes;\n }\n\n /**\n * Checks if the UR type matches the expected type.\n *\n * @param expectedType - The expected type\n * @throws {UnexpectedTypeError} If the types don't match\n */\n checkType(expectedType: string | URType): void {\n const expected = typeof expectedType === \"string\" ? new URType(expectedType) : expectedType;\n if (!this._urType.equals(expected)) {\n throw new UnexpectedTypeError(expected.string(), this._urType.string());\n }\n }\n\n /**\n * Returns the string representation.\n */\n toString(): string {\n return this.string();\n }\n\n /**\n * Checks equality with another UR.\n */\n equals(other: UR): boolean {\n return (\n this._urType.equals(other._urType) &&\n this._cbor.toData().toString() === other._cbor.toData().toString()\n );\n }\n}\n\n/**\n * Encodes a UR string using Bytewords minimal encoding.\n * This handles single-part URs according to BCR-2020-005.\n */\nclass URStringEncoder {\n static encode(urType: string, cborData: Uint8Array): string {\n // Encode CBOR data using bytewords minimal style (with CRC32 checksum)\n const encoded = encodeBytewords(cborData, BytewordsStyle.Minimal);\n return `ur:${urType}/${encoded}`;\n }\n}\n\n/**\n * Decodes a UR string back to its components.\n */\nclass URStringDecoder {\n static decode(urString: string): { urType: string; cbor: Cbor } | null {\n const lowercased = urString.toLowerCase();\n\n // Check scheme\n if (!lowercased.startsWith(\"ur:\")) {\n throw new InvalidSchemeError();\n }\n\n // Strip scheme\n const afterScheme = lowercased.substring(3);\n\n // Split into type and data\n const [urType, ...dataParts] = afterScheme.split(\"/\");\n\n if (urType === \"\" || urType === undefined) {\n throw new TypeUnspecifiedError();\n }\n\n const data = dataParts.join(\"/\");\n if (data === \"\" || data === undefined) {\n throw new TypeUnspecifiedError();\n }\n\n try {\n // Decode the bytewords-encoded data (validates CRC32 checksum)\n const cborData = decodeBytewords(data, BytewordsStyle.Minimal);\n const cbor = decodeCbor(cborData);\n return { urType, cbor };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new URError(`Failed to decode UR: ${errorMessage}`);\n }\n }\n}\n","import type { UR } from \"./ur.js\";\n\n/**\n * A type that can be encoded to a UR (Uniform Resource).\n *\n * Types implementing this interface should be able to convert themselves\n * to CBOR data and associate that with a UR type identifier.\n *\n * @example\n * ```typescript\n * class MyType implements UREncodable {\n * toCBOR(): CBOR {\n * // Convert to CBOR\n * }\n *\n * ur(): UR {\n * const cbor = this.toCBOR();\n * return UR.new('mytype', cbor);\n * }\n * }\n * ```\n */\nexport interface UREncodable {\n /**\n * Returns the UR representation of the object.\n */\n ur(): UR;\n\n /**\n * Returns the UR string representation of the object.\n */\n urString(): string;\n}\n\n/**\n * Helper function to check if an object implements UREncodable.\n */\nexport function isUREncodable(obj: unknown): obj is UREncodable {\n return (\n typeof obj === \"object\" &&\n obj !== null &&\n \"ur\" in obj &&\n \"urString\" in obj &&\n typeof (obj as Record<string, unknown>)[\"ur\"] === \"function\" &&\n typeof (obj as Record<string, unknown>)[\"urString\"] === \"function\"\n );\n}\n","import type { UR } from \"./ur.js\";\n\n/**\n * A type that can be decoded from a UR (Uniform Resource).\n *\n * Types implementing this interface should be able to create themselves\n * from a UR containing their data.\n *\n * @example\n * ```typescript\n * class MyType implements URDecodable {\n * fromUR(ur: UR): MyType {\n * const cbor = ur.cbor();\n * // Decode from CBOR and return MyType instance\n * }\n *\n * fromURString(urString: string): MyType {\n * return this.fromUR(UR.fromURString(urString));\n * }\n * }\n * ```\n */\nexport interface URDecodable {\n /**\n * Creates an instance of this type from a UR.\n *\n * @param ur - The UR to decode from\n * @returns An instance of this type\n * @throws If the UR type is wrong or data is malformed\n */\n fromUR(ur: UR): unknown;\n\n /**\n * Creates an instance of this type from a UR string.\n *\n * This is a convenience method that parses the UR string and then\n * calls fromUR().\n *\n * @param urString - The UR string to decode from (e.g., \"ur:type/...\")\n * @returns An instance of this type\n * @throws If the UR string is invalid or data is malformed\n */\n fromURString?(urString: string): unknown;\n}\n\n/**\n * Helper function to check if an object implements URDecodable.\n */\nexport function isURDecodable(obj: unknown): obj is URDecodable {\n return (\n typeof obj === \"object\" &&\n obj !== null &&\n \"fromUR\" in obj &&\n typeof (obj as Record<string, unknown>)[\"fromUR\"] === \"function\"\n );\n}\n","import type { UREncodable } from \"./ur-encodable.js\";\nimport type { URDecodable } from \"./ur-decodable.js\";\n\n/**\n * A type that can be both encoded to and decoded from a UR.\n *\n * This combines the UREncodable and URDecodable interfaces for types\n * that support bidirectional UR conversion.\n *\n * @example\n * ```typescript\n * class MyType implements URCodable {\n * ur(): UR {\n * // Encode to UR\n * }\n *\n * urString(): string {\n * // Return UR string\n * }\n *\n * fromUR(ur: UR): MyType {\n * // Decode from UR\n * }\n *\n * fromURString(urString: string): MyType {\n * // Decode from UR string (convenience method)\n * return this.fromUR(UR.fromURString(urString));\n * }\n * }\n * ```\n */\nexport interface URCodable extends UREncodable, URDecodable {}\n\n/**\n * Helper function to check if an object implements URCodable.\n */\nexport function isURCodable(obj: unknown): obj is URCodable {\n return (\n typeof obj === \"object\" &&\n obj !== null &&\n \"ur\" in obj &&\n \"urString\" in obj &&\n \"fromUR\" in obj &&\n typeof (obj as Record<string, unknown>)[\"ur\"] === \"function\" &&\n typeof (obj as Record<string, unknown>)[\"urString\"] === \"function\" &&\n typeof (obj as Record<string, unknown>)[\"fromUR\"] === \"function\"\n );\n}\n","/**\n * Xoshiro256** PRNG implementation.\n *\n * This is a high-quality, fast pseudo-random number generator used\n * for deterministic fragment selection in fountain codes.\n *\n * Reference: https://prng.di.unimi.it/\n * BC-UR Reference: https://github.com/nicklockwood/fountain-codes\n */\n\nimport { sha256 } from \"@bcts/crypto\";\n\nconst MAX_UINT64 = BigInt(\"0xffffffffffffffff\");\n\n/**\n * Performs a left rotation on a 64-bit BigInt.\n */\nfunction rotl(x: bigint, k: number): bigint {\n const kBigInt = BigInt(k);\n return ((x << kBigInt) | (x >> (64n - kBigInt))) & MAX_UINT64;\n}\n\n/**\n * Xoshiro256** pseudo-random number generator.\n *\n * This PRNG is used for deterministic mixing in fountain codes,\n * allowing both encoder and decoder to agree on which fragments\n * are combined without transmitting that information.\n */\nexport class Xoshiro256 {\n private s: [bigint, bigint, bigint, bigint];\n\n /**\n * Creates a new Xoshiro256** instance from a 32-byte seed.\n *\n * The seed must be exactly 32 bytes (256 bits). The bytes are interpreted\n * using the BC-UR reference algorithm: each 8-byte chunk is read as\n * big-endian then stored as little-endian for the state.\n *\n * @param seed - The seed bytes (must be exactly 32 bytes)\n */\n constructor(seed: Uint8Array) {\n if (seed.length !== 32) {\n throw new Error(`Seed must be 32 bytes, got ${seed.length}`);\n }\n\n // BC-UR reference implementation:\n // For each 8-byte chunk, read as big-endian u64, then convert to little-endian bytes\n // This effectively swaps the byte order within each 8-byte segment\n const s: [bigint, bigint, bigint, bigint] = [0n, 0n, 0n, 0n];\n for (let i = 0; i < 4; i++) {\n // Read 8 bytes as big-endian u64\n let v = 0n;\n for (let n = 0; n < 8; n++) {\n v = (v << 8n) | BigInt(seed[8 * i + n] ?? 0);\n }\n s[i] = v;\n }\n\n this.s = s;\n }\n\n /**\n * Creates a Xoshiro256** instance from raw state values.\n * Useful for seeding with specific values.\n */\n static fromState(s0: bigint, s1: bigint, s2: bigint, s3: bigint): Xoshiro256 {\n const instance = Object.create(Xoshiro256.prototype) as Xoshiro256;\n instance.s = [s0, s1, s2, s3];\n return instance;\n }\n\n /**\n * Generates the next 64-bit random value.\n */\n next(): bigint {\n const result = (rotl((this.s[1] * 5n) & MAX_UINT64, 7) * 9n) & MAX_UINT64;\n\n const t = (this.s[1] << 17n) & MAX_UINT64;\n\n this.s[2] ^= this.s[0];\n this.s[3] ^= this.s[1];\n this.s[1] ^= this.s[2];\n this.s[0] ^= this.s[3];\n\n this.s[2] ^= t;\n this.s[3] = rotl(this.s[3], 45);\n\n return result;\n }\n\n /**\n * Generates a random double in [0, 1).\n * Matches BC-UR reference: self.next() as f64 / (u64::MAX as f64 + 1.0)\n */\n nextDouble(): number {\n const value = this.next();\n // u64::MAX as f64 + 1.0 = 18446744073709551616.0\n return Number(value) / 18446744073709551616.0;\n }\n\n /**\n * Generates a random integer in [low, high] (inclusive).\n * Matches BC-UR reference: (self.next_double() * ((high - low + 1) as f64)) as u64 + low\n */\n nextInt(low: number, high: number): number {\n const range = high - low + 1;\n return Math.floor(this.nextDouble() * range) + low;\n }\n\n /**\n * Generates a random byte [0, 255].\n */\n nextByte(): number {\n return Number(this.next() & 0xffn);\n }\n\n /**\n * Generates an array of random bytes.\n */\n nextData(count: number): Uint8Array {\n const result = new Uint8Array(count);\n for (let i = 0; i < count; i++) {\n result[i] = this.nextByte();\n }\n return result;\n }\n\n /**\n * Shuffles items by repeatedly picking random indices.\n * Matches BC-UR reference implementation.\n */\n shuffled<T>(items: T[]): T[] {\n const source = [...items];\n const shuffled: T[] = [];\n while (source.length > 0) {\n const index = this.nextInt(0, source.length - 1);\n const item = source.splice(index, 1)[0];\n if (item !== undefined) {\n shuffled.push(item);\n }\n }\n return shuffled;\n }\n\n /**\n * Chooses the degree (number of fragments to mix) using a weighted sampler.\n * Uses the robust soliton distribution with weights [1/1, 1/2, 1/3, ..., 1/n].\n * Matches BC-UR reference implementation.\n */\n chooseDegree(seqLen: number): number {\n // Create weights: [1/1, 1/2, 1/3, ..., 1/seqLen]\n const weights: number[] = [];\n for (let i = 1; i <= seqLen; i++) {\n weights.push(1.0 / i);\n }\n\n // Use Vose's alias method for weighted sampling\n const sampler = new WeightedSampler(weights);\n return sampler.next(this) + 1; // 1-indexed degree\n }\n}\n\n/**\n * Weighted sampler using Vose's alias method.\n * Allows O(1) sampling from a discrete probability distribution.\n */\nclass WeightedSampler {\n private readonly aliases: number[];\n private readonly probs: number[];\n\n constructor(weights: number[]) {\n const n = weights.length;\n if (n === 0) {\n throw new Error(\"Weights array cannot be empty\");\n }\n\n // Normalize weights\n const sum = weights.reduce((a, b) => a + b, 0);\n if (sum <= 0) {\n throw new Error(\"Weights must sum to a positive value\");\n }\n\n const normalized = weights.map((w) => (w * n) / sum);\n\n // Initialize alias table\n this.aliases = Array.from<number>({ length: n }).fill(0);\n this.probs = Array.from<number>({ length: n }).fill(0);\n\n // Partition into small and large\n const small: number[] = [];\n const large: number[] = [];\n\n for (let i = n - 1; i >= 0; i--) {\n if (normalized[i] < 1.0) {\n small.push(i);\n } else {\n large.push(i);\n }\n }\n\n // Build the alias table\n while (small.length > 0 && large.length > 0) {\n const a = small.pop();\n const g = large.pop();\n if (a === undefined || g === undefined) break;\n this.probs[a] = normalized[a] ?? 0;\n this.aliases[a] = g;\n const normalizedG = normalized[g] ?? 0;\n const normalizedA = normalized[a] ?? 0;\n normalized[g] = normalizedG + normalizedA - 1.0;\n if (normalized[g] !== undefined && normalized[g] < 1.0) {\n small.push(g);\n } else {\n large.push(g);\n }\n }\n\n while (large.length > 0) {\n const g = large.pop();\n if (g === undefined) break;\n this.probs[g] = 1.0;\n }\n\n while (small.length > 0) {\n const a = small.pop();\n if (a === undefined) break;\n this.probs[a] = 1.0;\n }\n }\n\n /**\n * Sample from the distribution.\n */\n next(rng: Xoshiro256): number {\n const r1 = rng.nextDouble();\n const r2 = rng.nextDouble();\n const n = this.probs.length;\n const i = Math.floor(n * r1);\n if (r2 < this.probs[i]) {\n return i;\n } else {\n return this.aliases[i];\n }\n }\n}\n\n/**\n * Creates a Xoshiro256 PRNG instance from message checksum and sequence number.\n *\n * This creates an 8-byte seed by concatenating seqNum and checksum (both in\n * big-endian), then hashes it with SHA-256 to get the 32-byte seed for Xoshiro.\n *\n * This matches the BC-UR reference implementation.\n */\nexport function createSeed(checksum: number, seqNum: number): Uint8Array {\n // Create 8-byte seed: seqNum (big-endian) || checksum (big-endian)\n const seed8 = new Uint8Array(8);\n\n // seqNum in big-endian (bytes 0-3)\n seed8[0] = (seqNum >>> 24) & 0xff;\n seed8[1] = (seqNum >>> 16) & 0xff;\n seed8[2] = (seqNum >>> 8) & 0xff;\n seed8[3] = seqNum & 0xff;\n\n // checksum in big-endian (bytes 4-7)\n seed8[4] = (checksum >>> 24) & 0xff;\n seed8[5] = (checksum >>> 16) & 0xff;\n seed8[6] = (checksum >>> 8) & 0xff;\n seed8[7] = checksum & 0xff;\n\n // Hash with SHA-256 to get 32 bytes\n return sha256(seed8);\n}\n","/**\n * Fountain code implementation for multipart URs.\n *\n * This implements a hybrid fixed-rate and rateless fountain code system\n * as specified in BCR-2020-005 and BCR-2024-001.\n *\n * Key concepts:\n * - Parts 1-seqLen are \"pure\" fragments (fixed-rate)\n * - Parts > seqLen are \"mixed\" fragments using XOR (rateless)\n * - Xoshiro256** PRNG ensures encoder/decoder agree on mixing\n */\n\nimport { Xoshiro256, createSeed } from \"./xoshiro.js\";\nimport { crc32 } from \"./utils.js\";\n\n/**\n * Represents a fountain code part with metadata.\n */\nexport interface FountainPart {\n /** Sequence number (1-based) */\n seqNum: number;\n /** Total number of pure fragments */\n seqLen: number;\n /** Length of original message */\n messageLen: number;\n /** CRC32 checksum of original message */\n checksum: number;\n /** Fragment data */\n data: Uint8Array;\n}\n\n/**\n * Splits data into fragments of the specified size.\n */\nexport function splitMessage(message: Uint8Array, fragmentLen: number): Uint8Array[] {\n const fragments: Uint8Array[] = [];\n const fragmentCount = Math.ceil(message.length / fragmentLen);\n\n for (let i = 0; i < fragmentCount; i++) {\n const start = i * fragmentLen;\n const end = Math.min(start + fragmentLen, message.length);\n const fragment = new Uint8Array(fragmentLen);\n\n // Copy data and pad with zeros if needed\n const sourceSlice = message.slice(start, end);\n fragment.set(sourceSlice);\n\n fragments.push(fragment);\n }\n\n return fragments;\n}\n\n/**\n * XOR two Uint8Arrays together.\n */\nexport function xorBytes(a: Uint8Array, b: Uint8Array): Uint8Array {\n const len = Math.max(a.length, b.length);\n const result = new Uint8Array(len);\n\n for (let i = 0; i < len; i++) {\n result[i] = (a[i] ?? 0) ^ (b[i] ?? 0);\n }\n\n return result;\n}\n\n/**\n * Chooses which fragments to mix for a given sequence number.\n *\n * This uses a seeded Xoshiro256** PRNG to deterministically select fragments,\n * ensuring encoder and decoder agree without explicit coordination.\n *\n * The algorithm matches the BC-UR reference implementation:\n * 1. For pure parts (seqNum <= seqLen), return single fragment index\n * 2. For mixed parts, use weighted sampling to choose degree\n * 3. Shuffle all indices and take the first 'degree' indices\n *\n * @param seqNum - The sequence number (1-based)\n * @param seqLen - Total number of pure fragments\n * @param checksum - CRC32 checksum of the message\n * @returns Array of fragment indices (0-based)\n */\nexport function chooseFragments(seqNum: number, seqLen: number, checksum: number): number[] {\n // Pure parts (seqNum <= seqLen) contain exactly one fragment\n if (seqNum <= seqLen) {\n return [seqNum - 1];\n }\n\n // Mixed parts use PRNG to select fragments\n const seed = createSeed(checksum, seqNum);\n const rng = new Xoshiro256(seed);\n\n // Choose degree using weighted sampler (1/k distribution)\n const degree = rng.chooseDegree(seqLen);\n\n // Create array of all indices [0, 1, 2, ..., seqLen-1]\n const allIndices: number[] = [];\n for (let i = 0; i < seqLen; i++) {\n allIndices.push(i);\n }\n\n // Shuffle all indices and take the first 'degree' indices\n const shuffled = rng.shuffled(allIndices);\n return shuffled.slice(0, degree);\n}\n\n/**\n * Mixes the selected fragments using XOR.\n */\nexport function mixFragments(fragments: Uint8Array[], indices: number[]): Uint8Array {\n if (indices.length === 0) {\n throw new Error(\"No fragments to mix\");\n }\n\n let result: Uint8Array = new Uint8Array(fragments[0].length);\n\n for (const index of indices) {\n const fragment = fragments[index];\n if (fragment === undefined) {\n throw new Error(`Fragment at index ${index} not found`);\n }\n result = xorBytes(result, fragment);\n }\n\n return result;\n}\n\n/**\n * Fountain encoder for creating multipart URs.\n */\nexport class FountainEncoder {\n private readonly fragments: Uint8Array[];\n private readonly messageLen: number;\n private readonly checksum: number;\n private seqNum = 0;\n\n /**\n * Creates a fountain encoder for the given message.\n *\n * @param message - The message to encode\n * @param maxFragmentLen - Maximum length of each fragment\n */\n constructor(message: Uint8Array, maxFragmentLen: number) {\n if (maxFragmentLen < 1) {\n throw new Error(\"Fragment length must be at least 1\");\n }\n\n this.messageLen = message.length;\n this.checksum = crc32(message);\n this.fragments = splitMessage(message, maxFragmentLen);\n }\n\n /**\n * Returns the number of pure fragments.\n */\n get seqLen(): number {\n return this.fragments.length;\n }\n\n /**\n * Returns whether the message fits in a single part.\n */\n isSinglePart(): boolean {\n return this.fragments.length === 1;\n }\n\n /**\n * Returns whether all pure parts have been emitted.\n */\n isComplete(): boolean {\n return this.seqNum >= this.seqLen;\n }\n\n /**\n * Generates the next fountain part.\n */\n nextPart(): FountainPart {\n this.seqNum++;\n\n const indices = chooseFragments(this.seqNum, this.seqLen, this.checksum);\n const data = mixFragments(this.fragments, indices);\n\n return {\n seqNum: this.seqNum,\n seqLen: this.seqLen,\n messageLen: this.messageLen,\n checksum: this.checksum,\n data,\n };\n }\n\n /**\n * Returns the current sequence number.\n */\n currentSeqNum(): number {\n return this.seqNum;\n }\n\n /**\n * Resets the encoder to start from the beginning.\n */\n reset(): void {\n this.seqNum = 0;\n }\n}\n\n/**\n * Fountain decoder for reassembling multipart URs.\n */\nexport class FountainDecoder {\n private seqLen: number | null = null;\n private messageLen: number | null = null;\n private checksum: number | null = null;\n\n // Storage for received data\n private readonly pureFragments = new Map<number, Uint8Array>();\n private readonly mixedParts = new Map<number, { indices: number[]; data: Uint8Array }>();\n\n /**\n * Receives a fountain part and attempts to decode.\n *\n * @param part - The fountain part to receive\n * @returns true if the message is now complete\n */\n receive(part: FountainPart): boolean {\n // Initialize on first part\n if (this.seqLen === null) {\n this.seqLen = part.seqLen;\n this.messageLen = part.messageLen;\n this.checksum = part.checksum;\n }\n\n // Validate consistency\n if (\n part.seqLen !== this.seqLen ||\n part.messageLen !== this.messageLen ||\n part.checksum !== this.checksum\n ) {\n throw new Error(\"Inconsistent part metadata\");\n }\n\n // Determine which fragments this part contains\n const indices = chooseFragments(part.seqNum, this.seqLen, this.checksum);\n\n if (indices.length === 1) {\n // Pure fragment (or degree-1 mixed that acts like pure)\n const index = indices[0];\n if (!this.pureFragments.has(index)) {\n this.pureFragments.set(index, part.data);\n }\n } else {\n // Mixed fragment - store for later reduction\n if (!this.mixedParts.has(part.seqNum)) {\n this.mixedParts.set(part.seqNum, { indices, data: part.data });\n }\n }\n\n // Try to reduce mixed parts\n this.reduceMixedParts();\n\n return this.isComplete();\n }\n\n /**\n * Attempts to extract pure fragments from mixed parts.\n */\n private reduceMixedParts(): void {\n let progress = true;\n\n while (progress) {\n progress = false;\n\n for (const [seqNum, mixed] of this.mixedParts) {\n // Find which indices we're missing\n const missing: number[] = [];\n let reduced = mixed.data;\n\n for (const index of mixed.indices) {\n const pure = this.pureFragments.get(index);\n if (pure !== undefined) {\n // XOR out the known fragment\n reduced = xorBytes(reduced, pure);\n } else {\n missing.push(index);\n }\n }\n\n if (missing.length === 0) {\n // All fragments known, remove this mixed part\n this.mixedParts.delete(seqNum);\n progress = true;\n } else if (missing.length === 1) {\n // Can extract the missing fragment\n const missingIndex = missing[0];\n this.pureFragments.set(missingIndex, reduced);\n this.mixedParts.delete(seqNum);\n progress = true;\n }\n }\n }\n }\n\n /**\n * Returns whether all fragments have been received.\n */\n isComplete(): boolean {\n if (this.seqLen === null) {\n return false;\n }\n\n return this.pureFragments.size === this.seqLen;\n }\n\n /**\n * Reconstructs the original message.\n *\n * @returns The original message, or null if not yet complete\n */\n message(): Uint8Array | null {\n if (!this.isComplete() || this.seqLen === null || this.messageLen === null) {\n return null;\n }\n\n // Calculate fragment size from first fragment\n const firstFragment = this.pureFragments.get(0);\n if (firstFragment === undefined) {\n return null;\n }\n\n const fragmentLen = firstFragment.length;\n const result = new Uint8Array(this.messageLen);\n\n // Assemble fragments\n for (let i = 0; i < this.seqLen; i++) {\n const fragment = this.pureFragments.get(i);\n if (fragment === undefined) {\n return null;\n }\n\n const start = i * fragmentLen;\n const end = Math.min(start + fragmentLen, this.messageLen);\n const len = end - start;\n\n result.set(fragment.slice(0, len), start);\n }\n\n // Verify checksum\n const actualChecksum = crc32(result);\n if (actualChecksum !== this.checksum) {\n throw new Error(`Checksum mismatch: expected ${this.checksum}, got ${actualChecksum}`);\n }\n\n return result;\n }\n\n /**\n * Returns the progress as a fraction (0 to 1).\n */\n progress(): number {\n if (this.seqLen === null) {\n return 0;\n }\n return this.pureFragments.size / this.seqLen;\n }\n\n /**\n * Resets the decoder.\n */\n reset(): void {\n this.seqLen = null;\n this.messageLen = null;\n this.checksum = null;\n this.pureFragments.clear();\n this.mixedParts.clear();\n }\n}\n","import type { UR } from \"./ur.js\";\nimport { URError } from \"./error.js\";\nimport { FountainEncoder, type FountainPart } from \"./fountain.js\";\nimport { encodeBytewords, BytewordsStyle } from \"./utils.js\";\nimport { cbor } from \"@bcts/dcbor\";\n\n/**\n * Encodes a UR as multiple parts using fountain codes.\n *\n * This allows large CBOR structures to be split into multiple UR strings\n * that can be transmitted separately and reassembled. The encoder uses\n * fountain codes for resilient transmission over lossy channels.\n *\n * For single-part URs (small payloads), use the regular UR.string() method.\n *\n * @example\n * ```typescript\n * const ur = UR.new('bytes', cbor);\n * const encoder = new MultipartEncoder(ur, 100);\n *\n * // Generate all pure parts\n * while (!encoder.isComplete()) {\n * const part = encoder.nextPart();\n * console.log(part); // \"ur:bytes/1-10/...\"\n * }\n *\n * // Generate additional rateless parts for redundancy\n * for (let i = 0; i < 5; i++) {\n * const part = encoder.nextPart();\n * console.log(part); // \"ur:bytes/11-10/...\"\n * }\n * ```\n */\nexport class MultipartEncoder {\n private readonly _ur: UR;\n private readonly _fountainEncoder: FountainEncoder;\n private _currentIndex = 0;\n\n /**\n * Creates a new multipart encoder for the given UR.\n *\n * @param ur - The UR to encode\n * @param maxFragmentLen - Maximum length of each fragment in bytes\n * @throws {URError} If encoding fails\n *\n * @example\n * ```typescript\n * const encoder = new MultipartEncoder(ur, 100);\n * ```\n */\n constructor(ur: UR, maxFragmentLen: number) {\n if (maxFragmentLen < 1) {\n throw new URError(\"Max fragment length must be at least 1\");\n }\n this._ur = ur;\n\n // Create fountain encoder from CBOR data\n const cborData = ur.cbor().toData();\n this._fountainEncoder = new FountainEncoder(cborData, maxFragmentLen);\n }\n\n /**\n * Gets the next part of the encoding.\n *\n * Parts 1 through seqLen are \"pure\" fragments containing one piece each.\n * Parts beyond seqLen are \"mixed\" fragments using fountain codes for redundancy.\n *\n * @returns The next UR string part\n *\n * @example\n * ```typescript\n * const part = encoder.nextPart();\n * // Returns: \"ur:bytes/1-3/lsadaoaxjygonesw\"\n * ```\n */\n nextPart(): string {\n const part = this._fountainEncoder.nextPart();\n this._currentIndex++;\n return this._encodePart(part);\n }\n\n /**\n * Encodes a fountain part as a UR string.\n */\n private _encodePart(part: FountainPart): string {\n // For single-part messages, use simple format\n if (part.seqLen === 1) {\n return this._ur.string();\n }\n\n // Encode the part data as CBOR: [seqNum, seqLen, messageLen, checksum, data]\n // Using a simple format: seqNum-seqLen prefix followed by bytewords-encoded part\n const partData = this._encodePartData(part);\n const encoded = encodeBytewords(partData, BytewordsStyle.Minimal);\n\n return `ur:${this._ur.urTypeStr()}/${part.seqNum}-${part.seqLen}/${encoded}`;\n }\n\n /**\n * Encodes part metadata and data as CBOR for bytewords encoding.\n * Format: CBOR array [seqNum, seqLen, messageLen, checksum, data]\n */\n private _encodePartData(part: FountainPart): Uint8Array {\n // Create CBOR array with 5 elements: [seqNum, seqLen, messageLen, checksum, data]\n const cborArray = cbor([part.seqNum, part.seqLen, part.messageLen, part.checksum, part.data]);\n\n return cborArray.toData();\n }\n\n /**\n * Gets the current part index.\n */\n currentIndex(): number {\n return this._currentIndex;\n }\n\n /**\n * Gets the total number of pure parts.\n *\n * Note: Fountain codes can generate unlimited parts beyond this count\n * for additional redundancy.\n */\n partsCount(): number {\n return this._fountainEncoder.seqLen;\n }\n}\n","import { decodeCbor, MajorType, type Cbor } from \"@bcts/dcbor\";\nimport { InvalidSchemeError, InvalidTypeError, UnexpectedTypeError, URError } from \"./error.js\";\nimport { UR } from \"./ur.js\";\nimport { URType } from \"./ur-type.js\";\nimport { FountainDecoder, type FountainPart } from \"./fountain.js\";\nimport { decodeBytewords, BytewordsStyle } from \"./utils.js\";\n\n/**\n * Decodes multiple UR parts back into a single UR.\n *\n * This reassembles multipart URs that were encoded using fountain codes.\n * The decoder can handle out-of-order reception and packet loss.\n *\n * @example\n * ```typescript\n * const decoder = new MultipartDecoder();\n *\n * for (const urPart of urParts) {\n * decoder.receive(urPart);\n * if (decoder.isComplete()) {\n * const ur = decoder.message();\n * break;\n * }\n * }\n * ```\n */\nexport class MultipartDecoder {\n private _urType: URType | null = null;\n private _fountainDecoder: FountainDecoder | null = null;\n private _decodedMessage: UR | null = null;\n\n /**\n * Receives a UR part string.\n *\n * @param part - A UR part string (e.g., \"ur:bytes/1-10/...\" or \"ur:bytes/...\")\n * @throws {InvalidSchemeError} If the part doesn't start with \"ur:\"\n * @throws {UnexpectedTypeError} If the type doesn't match previous parts\n */\n receive(part: string): void {\n const { urType, partInfo } = this._parsePart(part);\n\n // Validate type consistency\n if (this._urType === null) {\n this._urType = urType;\n } else if (!this._urType.equals(urType)) {\n throw new UnexpectedTypeError(this._urType.string(), urType.string());\n }\n\n // Handle the part\n if (partInfo.isSinglePart) {\n // Single-part UR - decode immediately\n this._decodedMessage = UR.fromURString(part);\n } else {\n // Multipart UR - use fountain decoder\n this._fountainDecoder ??= new FountainDecoder();\n\n const fountainPart = this._decodeFountainPart(partInfo);\n this._fountainDecoder.receive(fountainPart);\n\n // Try to get the complete message\n if (this._fountainDecoder.isComplete()) {\n const message = this._fountainDecoder.message();\n if (message !== null) {\n const cbor = decodeCbor(message);\n this._decodedMessage = UR.new(this._urType, cbor);\n }\n }\n }\n }\n\n /**\n * Parses a UR part string to extract type and part info.\n */\n private _parsePart(part: string): { urType: URType; partInfo: PartInfo } {\n const lowercased = part.toLowerCase();\n\n if (!lowercased.startsWith(\"ur:\")) {\n throw new InvalidSchemeError();\n }\n\n const afterScheme = lowercased.substring(3);\n const components = afterScheme.split(\"/\");\n\n if (components.length === 0 || components[0] === \"\") {\n throw new InvalidTypeError();\n }\n\n const urType = new URType(components[0]);\n\n // Check if this is a multipart UR (format: type/seqNum-seqLen/data)\n if (components.length >= 3) {\n const seqPart = components[1];\n const seqMatch = /^(\\d+)-(\\d+)$/.exec(seqPart);\n\n if (seqMatch !== null) {\n const seqNum = parseInt(seqMatch[1], 10);\n const seqLen = parseInt(seqMatch[2], 10);\n const encodedData = components.slice(2).join(\"/\");\n\n return {\n urType,\n partInfo: {\n isSinglePart: false,\n seqNum,\n seqLen,\n encodedData,\n },\n };\n }\n }\n\n // Single-part UR\n return {\n urType,\n partInfo: { isSinglePart: true },\n };\n }\n\n /**\n * Decodes a multipart UR's fountain part data.\n *\n * The multipart body is a CBOR array: [seqNum, seqLen, messageLen, checksum, data]\n */\n private _decodeFountainPart(partInfo: MultipartInfo): FountainPart {\n // Decode bytewords to get CBOR data\n const cborData = decodeBytewords(partInfo.encodedData, BytewordsStyle.Minimal);\n\n // Decode the CBOR array\n const decoded = decodeCbor(cborData);\n\n // The decoded value should be an array with 5 elements\n if (decoded.type !== MajorType.Array) {\n throw new URError(\"Invalid multipart data: expected CBOR array\");\n }\n\n const items = decoded.value as Cbor[];\n if (items.length !== 5) {\n throw new URError(`Invalid multipart data: expected 5 elements, got ${items.length}`);\n }\n\n // Extract the fields: [seqNum, seqLen, messageLen, checksum, data]\n const seqNum = Number(items[0].value);\n const seqLen = Number(items[1].value);\n const messageLen = Number(items[2].value);\n const checksum = Number(items[3].value);\n const data = items[4].value as Uint8Array;\n\n // Verify seqNum and seqLen match the URL path values\n if (seqNum !== partInfo.seqNum || seqLen !== partInfo.seqLen) {\n throw new URError(\n `Multipart metadata mismatch: URL says ${partInfo.seqNum}-${partInfo.seqLen}, CBOR says ${seqNum}-${seqLen}`,\n );\n }\n\n return {\n seqNum,\n seqLen,\n messageLen,\n checksum,\n data,\n };\n }\n\n /**\n * Checks if the message is complete.\n */\n isComplete(): boolean {\n return this._decodedMessage !== null;\n }\n\n /**\n * Gets the decoded UR message.\n *\n * @returns The decoded UR, or null if not yet complete\n */\n message(): UR | null {\n return this._decodedMessage;\n }\n}\n\n/**\n * Part info for single-part URs.\n */\ninterface SinglePartInfo {\n isSinglePart: true;\n}\n\n/**\n * Part info for multipart URs.\n */\ninterface MultipartInfo {\n isSinglePart: false;\n seqNum: number;\n seqLen: number;\n encodedData: string;\n}\n\ntype PartInfo = SinglePartInfo | MultipartInfo;\n"],"mappings":";;;;;;;;CAGA,IAAa,UAAb,cAA6B,MAAM;EACjC,YAAY,SAAiB;AAC3B,SAAM,QAAQ;AACd,QAAK,OAAO;;;;;;CAOhB,IAAa,qBAAb,cAAwC,QAAQ;EAC9C,cAAc;AACZ,SAAM,oBAAoB;AAC1B,QAAK,OAAO;;;;;;CAOhB,IAAa,uBAAb,cAA0C,QAAQ;EAChD,cAAc;AACZ,SAAM,uBAAuB;AAC7B,QAAK,OAAO;;;;;;CAOhB,IAAa,mBAAb,cAAsC,QAAQ;EAC5C,cAAc;AACZ,SAAM,kBAAkB;AACxB,QAAK,OAAO;;;;;;CAOhB,IAAa,qBAAb,cAAwC,QAAQ;EAC9C,cAAc;AACZ,SAAM,0BAA0B;AAChC,QAAK,OAAO;;;;;;CAOhB,IAAa,sBAAb,cAAyC,QAAQ;EAC/C,YAAY,UAAkB,OAAe;AAC3C,SAAM,oBAAoB,SAAS,cAAc,QAAQ;AACzD,QAAK,OAAO;;;;;;CAOhB,IAAa,iBAAb,cAAoC,QAAQ;EAC1C,YAAY,SAAiB;AAC3B,SAAM,oBAAoB,UAAU;AACpC,QAAK,OAAO;;;;;;CAOhB,IAAa,YAAb,cAA+B,QAAQ;EACrC,YAAY,SAAiB;AAC3B,SAAM,eAAe,UAAU;AAC/B,QAAK,OAAO;;;;;;;CAQhB,IAAa,gBAAb,cAAmC,QAAQ;EACzC,YAAY,SAAiB;AAC3B,SAAM,qBAAqB,QAAQ,GAAG;AACtC,QAAK,OAAO;;;;;;CAShB,SAAgB,QAAQ,QAAkC;AACxD,SAAO,kBAAkB;;;;;;;;;CC3F3B,SAAgB,aAAa,MAAuB;EAClD,MAAM,OAAO,KAAK,WAAW,EAAE;AAE/B,MAAI,QAAQ,MAAM,QAAQ,IAAK,QAAO;AAEtC,MAAI,QAAQ,MAAM,QAAQ,GAAI,QAAO;AAErC,MAAI,SAAS,GAAI,QAAO;AACxB,SAAO;;;;;;CAOT,SAAgB,cAAc,QAAyB;AACrD,MAAI,OAAO,WAAW,EAAG,QAAO;AAChC,SAAO,MAAM,KAAK,OAAO,CAAC,OAAO,SAAS,aAAa,KAAK,CAAC;;;;;;CAiB/D,MAAa,YAAsB;EACjC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD;;;;CAKD,SAAS,qBAA0C;EACjD,MAAM,sBAAM,IAAI,KAAqB;AACrC,YAAU,SAAS,MAAM,UAAU;AACjC,OAAI,IAAI,MAAM,MAAM;IACpB;AACF,SAAO;;CAGT,MAAa,gBAAgB,oBAAoB;;;;;CAMjD,MAAa,YAAsB;EACjC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EA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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bcts/uniform-resources",
3
- "version": "1.0.0-alpha.18",
3
+ "version": "1.0.0-alpha.20",
4
4
  "type": "module",
5
5
  "description": "Blockchain Commons Uniform Resources (UR) for TypeScript",
6
6
  "license": "BSD-2-Clause-Patent",
@@ -66,19 +66,19 @@
66
66
  "node": ">=18.0.0"
67
67
  },
68
68
  "dependencies": {
69
- "@bcts/crypto": "^1.0.0-alpha.18",
70
- "@bcts/dcbor": "^1.0.0-alpha.18"
69
+ "@bcts/crypto": "^1.0.0-alpha.20",
70
+ "@bcts/dcbor": "^1.0.0-alpha.20"
71
71
  },
72
72
  "devDependencies": {
73
73
  "@bcts/eslint": "^0.1.0",
74
74
  "@bcts/tsconfig": "^0.1.0",
75
75
  "@eslint/js": "^9.39.2",
76
- "@types/node": "^25.2.0",
76
+ "@types/node": "^25.2.1",
77
77
  "@types/pako": "^2.0.4",
78
78
  "eslint": "^9.39.2",
79
79
  "prettier": "^3.8.1",
80
80
  "ts-node": "^10.9.2",
81
- "tsdown": "^0.20.1",
81
+ "tsdown": "^0.20.3",
82
82
  "typedoc": "^0.28.16",
83
83
  "typescript": "^5.9.3",
84
84
  "vitest": "^4.0.18"