@cbortech/cbor 0.27.0 → 0.27.1

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.
Files changed (48) hide show
  1. package/README.ja.md +73 -0
  2. package/README.md +75 -0
  3. package/dist/ast/CborAppSeqResult.d.ts +37 -4
  4. package/dist/ast/CborArray.d.ts +2 -2
  5. package/dist/ast/CborByteString.d.ts +2 -2
  6. package/dist/ast/CborEmbeddedCBOR.d.ts +1 -1
  7. package/dist/ast/CborFloat.d.ts +1 -1
  8. package/dist/ast/CborIndefiniteByteString.d.ts +1 -1
  9. package/dist/ast/CborIndefiniteTextString.d.ts +1 -1
  10. package/dist/ast/CborItem.d.ts +297 -7
  11. package/dist/ast/CborMap.d.ts +2 -2
  12. package/dist/ast/CborNint.d.ts +1 -1
  13. package/dist/ast/CborTag.d.ts +4 -4
  14. package/dist/ast/CborTextString.d.ts +2 -2
  15. package/dist/ast/CborUint.d.ts +1 -1
  16. package/dist/ast/index.cjs +1 -1
  17. package/dist/ast/index.js +1 -1
  18. package/dist/cddl/index.cjs +1 -1
  19. package/dist/cddl/index.js +1 -1
  20. package/dist/cdn/index.cjs +1 -1
  21. package/dist/cdn/index.js +1 -1
  22. package/dist/cdn/serialize-utils.d.ts +30 -2
  23. package/dist/extensions/cri.d.ts +2 -2
  24. package/dist/extensions/dt.d.ts +4 -4
  25. package/dist/extensions/ip.d.ts +3 -3
  26. package/dist/extensions/types.d.ts +40 -1
  27. package/dist/index.cjs +1 -1
  28. package/dist/index.d.ts +1 -1
  29. package/dist/index.js +3 -3
  30. package/dist/{mapEntries-CvLdiN0h.js → mapEntries-CCLaJSaJ.js} +1114 -933
  31. package/dist/mapEntries-CCLaJSaJ.js.map +1 -0
  32. package/dist/mapEntries-CZZJScaj.cjs +13 -0
  33. package/dist/mapEntries-CZZJScaj.cjs.map +1 -0
  34. package/dist/{schema-CNfrVRYp.js → schema-DN9inJny.js} +3 -3
  35. package/dist/{schema-CNfrVRYp.js.map → schema-DN9inJny.js.map} +1 -1
  36. package/dist/{schema-iXpYtKQl.cjs → schema-zsg5yCPK.cjs} +2 -2
  37. package/dist/{schema-iXpYtKQl.cjs.map → schema-zsg5yCPK.cjs.map} +1 -1
  38. package/dist/{serialize-utils-CjTqQivB.cjs → serialize-utils-DhlW61ZX.cjs} +6 -6
  39. package/dist/serialize-utils-DhlW61ZX.cjs.map +1 -0
  40. package/dist/{serialize-utils-BuIZPaUc.js → serialize-utils-h-CVB9rg.js} +57 -47
  41. package/dist/{serialize-utils-BuIZPaUc.js.map → serialize-utils-h-CVB9rg.js.map} +1 -1
  42. package/dist/types.d.ts +273 -0
  43. package/dist/utils/hexfloat.d.ts +10 -2
  44. package/package.json +7 -8
  45. package/dist/mapEntries-C1f7G0AM.cjs +0 -13
  46. package/dist/mapEntries-C1f7G0AM.cjs.map +0 -1
  47. package/dist/mapEntries-CvLdiN0h.js.map +0 -1
  48. package/dist/serialize-utils-CjTqQivB.cjs.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mapEntries-CCLaJSaJ.js","names":[],"sources":["../src/tag.ts","../src/types.ts","../src/simple.ts","../src/utils/float16.ts","../src/cbor/encode.ts","../src/ast/CborItem.ts","../src/ast/CborUint.ts","../src/ast/CborNint.ts","../src/utils/hexfloat.ts","../src/ast/CborFloat.ts","../src/ast/CborTag.ts","../src/ast/CborByteString.ts","../src/ast/CborIndefiniteByteString.ts","../src/ast/CborIndefiniteTextString.ts","../src/ast/CborArray.ts","../src/ast/CborMap.ts","../src/ast/CborSimple.ts","../src/ast/CborEmbeddedCBOR.ts","../src/utils/strip-comments.ts","../src/extensions/b32.ts","../src/ast/CborUnresolvedAppExt.ts","../src/ast/CborAppSeqResult.ts","../src/ast/CborEllipsis.ts","../src/ast/CborBignum.ts","../src/cdn/parser.ts","../src/ast/CborTextString.ts","../src/extensions/dt.ts","../src/utils/ip.ts","../src/extensions/ip.ts","../src/extensions/cri.ts","../src/extensions/bignum.ts","../src/cbor/decoder.ts","../src/extensions/cbordata.ts","../src/extensions/ellipsis.ts","../src/extensions/concat.ts","../src/extensions/ilstrings.ts","../src/extensions/float.ts","../src/extensions/builtins.ts","../src/js/fromJS.ts","../src/mapEntries.ts"],"sourcesContent":["export const CBOR_TAG: unique symbol = Symbol.for('cbor.tag');\n\n// ─── Internal wrappers ────────────────────────────────────────────────────────\n\nexport class Null {\n valueOf(): null {\n return null;\n }\n toJSON(): null {\n return null;\n }\n}\n\nexport class Undefined {\n valueOf(): undefined {\n return undefined;\n }\n toJSON(): undefined {\n return undefined;\n }\n}\n\n// ─── Public helpers ───────────────────────────────────────────────────────────\n\n/** @internal */\nexport function getCborTag(value: unknown): bigint | undefined {\n if (!_canHaveTag(value)) return undefined;\n const sym = (value as Record<symbol, unknown>)[CBOR_TAG];\n return typeof sym === 'bigint' ? sym : undefined;\n}\n\n/** @internal */\nexport function setCborTag(value: unknown, tag: bigint): object {\n let obj: object;\n switch (typeof value) {\n case 'number':\n obj = new Number(value);\n break;\n case 'string':\n obj = new String(value);\n break;\n case 'boolean':\n obj = new Boolean(value);\n break;\n case 'bigint':\n obj = Object(value);\n break;\n case 'undefined':\n obj = new Undefined();\n break;\n case 'object':\n if (value === null) {\n obj = new Null();\n break;\n }\n obj = value as object;\n break;\n default:\n throw new TypeError(\n `setCborTag: cannot tag value of type ${typeof value}`\n );\n }\n (obj as Record<symbol, bigint>)[CBOR_TAG] = tag;\n return obj;\n}\n\n/** @internal */\nexport function removeCborTag(value: unknown): unknown {\n if (value instanceof Number) return value.valueOf();\n if (value instanceof String) return value.valueOf();\n if (value instanceof Boolean) return value.valueOf();\n if (Object.prototype.toString.call(value) === '[object BigInt]')\n return (value as { valueOf(): bigint }).valueOf();\n if (value instanceof Null) return null;\n if (value instanceof Undefined) return undefined;\n if (typeof value === 'object' && value !== null) {\n delete (value as Record<symbol, unknown>)[CBOR_TAG];\n return value;\n }\n return value;\n}\n\n/** @internal */\nexport function getCborTaggedValue(value: unknown): unknown {\n if (value instanceof Number) return value.valueOf();\n if (value instanceof String) return value.valueOf();\n if (value instanceof Boolean) return value.valueOf();\n if (Object.prototype.toString.call(value) === '[object BigInt]')\n return (value as { valueOf(): bigint }).valueOf();\n if (value instanceof Null) return null;\n if (value instanceof Undefined) return undefined;\n return value;\n}\n\n// ─── Internal helper ──────────────────────────────────────────────────────────\n\n/** Return true if value can carry the [CBOR_TAG] symbol (i.e. is a non-null object). */\nfunction _canHaveTag(value: unknown): value is object {\n // All boxed primitives (Number, String, Boolean, BigInt objects) also have\n // typeof === 'object', so a single check covers all cases.\n return typeof value === 'object' && value !== null;\n}\n\n// ─── Tag namespace ────────────────────────────────────────────────────────────\n\n/**\n * Namespace for CBOR tag annotation utilities.\n *\n * @example\n * const v = CBOR.fromCDN('42(\"hello\")').toJS();\n * Tag.get(v); // 42n\n * Tag.getValue(v); // \"hello\"\n *\n * const tagged = Tag.set([1, 2, 3], 100n);\n * Tag.remove(tagged); // [1, 2, 3]\n */\nexport class Tag {\n private constructor() {}\n\n /** Unique symbol used to attach a CBOR tag number to a JS value. */\n static readonly symbol: typeof CBOR_TAG = CBOR_TAG;\n\n /** Wrapper class for tagged `null` values. */\n static readonly Null = Null;\n\n /** Wrapper class for tagged `undefined` values. */\n static readonly Undefined = Undefined;\n\n /** Return the CBOR tag number attached to `value`, or `undefined` if none. */\n static get(value: unknown): bigint | undefined {\n return getCborTag(value);\n }\n\n /** Attach a CBOR tag number to `value` and return the annotated value. */\n static set(value: unknown, tag: bigint): object {\n return setCborTag(value, tag);\n }\n\n /** Remove the `[Tag.symbol]` annotation from `value` and return the plain value. */\n static remove(value: unknown): unknown {\n return removeCborTag(value);\n }\n\n /** Return the underlying plain JS value held inside a tagged wrapper. */\n static getValue(value: unknown): unknown {\n return getCborTaggedValue(value);\n }\n}\n","/**\n * Shared option types and plugin interfaces.\n */\n\n// ─── Omit sentinel ───────────────────────────────────────────────────────────\n\n/**\n * Sentinel returned from a replacer or reviver to omit the key/element from\n * the output. Use this instead of returning `undefined` when `undefinedOmits`\n * is `false` (the default) and you need to drop a specific entry.\n *\n * Accessible as `CBOR.OMIT` on the main class.\n */\nexport const CBOR_OMIT: unique symbol = Symbol('cbor.omit');\n\n// ─── Extension plugin ─────────────────────────────────────────────────────────\n// Defined in extensions/types.ts and re-exported here for convenience.\nexport type { CborExtension } from './extensions/types';\nimport type { CborExtension } from './extensions/types';\n\n// Type-only; used only by ItemContext/itemOptions below. Safe despite the\n// reverse direction (ast/CborItem.ts imports types from here) because type\n// imports are erased at compile time — there is no runtime circular require.\nimport type { CborItem } from './ast/CborItem';\n\n// ─── CDDL ─────────────────────────────────────────────────────────────────────\n// Type-only imports; note however that supporting CDDL source text as the\n// `cddl` option makes the facade (cbor.ts) import the compiler at runtime,\n// so the main entry loads the CDDL chunks as well. Accepting only compiled\n// schemas would keep the compiler exclusive to the `/cddl` subpath.\nimport type { CddlSchema } from './cddl/schema';\nimport type { ValidateOptions as CddlValidateOptions } from './cddl/validator';\nimport type { CddlValidationError, CddlValidationWarning } from './cddl/errors';\n\n// ─── Per-item option overrides ─────────────────────────────────────────────────\n\n/**\n * Context passed to an `itemOptions` callback (see `ToJSOptions.itemOptions`)\n * describing where the node being visited sits in the tree.\n */\nexport interface ItemContext {\n /**\n * The direct parent AST node. `undefined` for the root value being\n * converted. A tag or app-sequence wrapper is its content's `parent` —\n * see `path` for how wrappers affect addressing.\n */\n parent?: CborItem;\n\n /**\n * The path segment identifying this node: an array index (`number`), or a\n * map key's JS value (any type — CBOR keys are not limited to strings).\n * Always equal to the last element of `path`, except `undefined` for the\n * root value and while converting a map key itself (`isMapKey: true`),\n * since a key has no path of its own — it names its sibling value's\n * segment instead. A tag or app-sequence wrapper's content inherits the\n * wrapper's own `key` (and `path`) unchanged, since the wrapper adds no\n * segment of its own — see `path`.\n */\n key?: unknown;\n\n /**\n * The map key's own AST node, present when this node is a map entry's key\n * or value — but *not* inherited into a tag/app-sequence wrapper's\n * content the way `key`/`path` are, so it is only reliable at the map\n * entry itself. Lets a callback inspect a non-scalar key structurally\n * (e.g. via `keyNode._toCDN()`) instead of relying only on `key`'s\n * computed JS value.\n */\n keyNode?: CborItem;\n\n /**\n * `true` when this invocation is for converting a map key itself, rather\n * than one of that key's sibling value's descendants.\n */\n isMapKey?: boolean;\n\n /**\n * Path from the root to this node, as a sequence of array indices and map\n * key JS values. Empty for the root value. A tag or app-sequence wrapper\n * does not add a segment of its own — its content shares the wrapper's own\n * path.\n */\n readonly path: readonly unknown[];\n\n /**\n * The options in effect for this node going into this call — i.e. the\n * root options merged with whatever overrides its ancestors already\n * returned, *before* this callback's own return value is merged on top.\n * Read from this to build on the current value of an option (e.g. add an\n * extension to whatever list is already in effect) instead of overriding\n * it outright, or to make a decision based on an option's current value.\n *\n * A mutable-looking field here (currently just `extensions`) is a fresh\n * copy, not the live array in effect elsewhere — mutating it in place\n * (e.g. `ctx.options.extensions.push(ext)`) has no effect on this node,\n * its siblings, or the caller's own options; return an override instead.\n *\n * Has no `reviver` — its type is `ReadonlyToJSNodeOptions`, not\n * `ToJSOptions` — for the same reason this callback's own return value\n * can't set one:\n * since this callback may run more than once for the same node (see\n * `ToJSOptions.itemOptions`), always reflecting only the reviver-\n * independent options keeps what it reads consistent with what it can\n * write, and keeps a callback that only inspects `options` pure across\n * every one of those calls.\n *\n * @example\n * // Add `dt_as_Date` to whatever extensions are already configured,\n * // rather than replacing them.\n * itemOptions: (_node, ctx) => ({\n * extensions: [...(ctx.options.extensions ?? []), dt_as_Date],\n * })\n */\n readonly options: ReadonlyToJSNodeOptions;\n}\n\n/**\n * `ToJSOptions` with `reviver` removed. Used wherever an API only ever\n * needs to see the reviver-*independent* part of the options in effect for\n * a node — an `itemOptions` callback's return value, and the `options`\n * parameter of `CborExtension.toJS()` — because reviving the value a node\n * converts to always happens afterwards, exactly once per visit, in the\n * container holding it (see `CborArray`/`CborMap`); it is never something\n * the conversion of the node itself should (or, for `CborExtension.toJS()`,\n * even can) branch on. Keeping `reviver` out of both signatures — rather\n * than merely documenting that it should be ignored — means neither can\n * observe whether one is present, which is what makes it safe for a\n * `reviver`-driven `CborArray`/`CborMap` to convert a child more than once\n * (see `ToJSOptions.itemOptions`) without either one's result depending on\n * *which* of those conversions it was called for.\n */\nexport type ToJSNodeOptions = Omit<ToJSOptions, 'reviver'>;\n\n/**\n * `ToJSNodeOptions`, as handed to code that must not mutate it in place:\n * `ItemContext.options` and the `options` parameter of\n * `CborExtension.toJS()`. Both describe options actually in effect\n * elsewhere in the tree, so mutating what's handed out here must not be\n * able to reach that: reassigning a top-level property is a type error\n * (`Readonly<...>`), and `extensions`, the one field on `ToJSOptions`\n * that's an ordinary mutable array, is narrowed to a readonly array so an\n * in-place mutation like `.push()` is one too. This only guards against\n * *accidental* mutation via the type system — the implementation\n * additionally hands out a fresh snapshot, with its own copy of\n * `extensions`, on every call, so even a deliberate cast past this type\n * can't corrupt what another node, sibling, hook, or pass sees (see\n * `_toJSChild`'s `toReadonlyNodeOptions`).\n */\nexport type ReadonlyToJSNodeOptions = Readonly<\n Omit<ToJSNodeOptions, 'extensions'>\n> & {\n readonly extensions?: readonly CborExtension[];\n};\n\n// ─── Options ──────────────────────────────────────────────────────────────────\n\nexport interface ToHexDumpOptions {\n /**\n * Indentation per nesting level.\n * - `number`: number of spaces (e.g. `3` → `\" \"`)\n * - `string`: literal indent string (e.g. `'\\t'`)\n * @default 3\n */\n indent?: number | string;\n /** Comment marker used in the hex dump. Default: `'--'` */\n commentStyle?: '--' | '#';\n}\n\nexport interface ToJSOptions {\n /**\n * How to represent CBOR integer values (major type 0 / 1) in JavaScript.\n * - `'auto'`: `number` when the value is within the safe integer range\n * (±`Number.MAX_SAFE_INTEGER`), `bigint` otherwise.\n * - `'number'`: always `number` (precision may be lost for large values).\n * - `'bigint'`: always `bigint`.\n * @default 'auto'\n */\n integerAs?: 'auto' | 'number' | 'bigint';\n\n /**\n * How to represent CBOR map values when converting to JavaScript.\n * - `'auto'`: text-string-only keys → `Record<string, unknown>`,\n * other key types → `Map<unknown, unknown>`.\n * Duplicate keys are silently overwritten (last value wins).\n * - `'object'`: always `Record<string, unknown>` — non-string keys are\n * converted via `String()`. Duplicate keys are overwritten (last wins).\n * - `'entries'`: always `MapEntries` (a typed `Array` subclass) — preserves all\n * entries including duplicate keys (§2.4.2 of draft-ietf-cbor-edn-literals-27).\n * `fromJS()` recognises `MapEntries` instances and converts them back to `CborMap`.\n * @default 'auto'\n */\n mapAs?: 'auto' | 'object' | 'entries';\n\n /**\n * When `true`, CBOR tag annotations are omitted from the JavaScript value.\n *\n * By default, generic tags are preserved using `CBOR.Tag` so that\n * `toJS()` → `fromJS()` can round-trip CBOR tags. Enable this option when\n * you only need the tagged content as a plain JavaScript value.\n *\n * @default false\n */\n stripTags?: boolean;\n\n /**\n * Post-conversion reviver function, applied bottom-up after the CBOR value\n * has been converted to JavaScript.\n *\n * Called for every key/value pair — including map entries with non-string\n * keys — and finally for the root value with key `''`.\n * Return `CBOR.OMIT` to remove the entry from its parent container.\n * When `undefinedOmits` is `true`, returning `undefined` also removes the\n * entry (matching `JSON.parse` behavior).\n *\n * Note: this option is honoured by `CborItem.toJS()` and the `CBOR.*`\n * shortcut methods. Calling `_toJS()` directly bypasses it.\n */\n reviver?: (this: unknown, key: unknown, value: unknown) => unknown;\n\n /**\n * When `true`, a reviver returning `undefined` removes the entry from its\n * parent container, matching `JSON.parse` behavior.\n * When `false` (default), only `CBOR.OMIT` removes an entry; returning\n * `undefined` keeps the entry as CBOR `undefined` (simple 23).\n * @default false\n */\n undefinedOmits?: boolean;\n\n /**\n * Extension plugins consulted during `toJS()`, tried in order for every\n * node before its own default conversion. An extension takes part by\n * implementing `CborExtension.toJS()`; the first one to return a result\n * for a given node wins and that node's own `_toJS()` is not called.\n *\n * Unlike the `extensions` option on `FromCDNOptions`/`FromCBOROptions`,\n * this does not affect parsing — it only lets `toJS()` reinterpret nodes\n * that a *different* extension configuration already produced. For\n * example, a tree parsed with the plain `dt` extension (`DT'...'` →\n * `number`) can still be converted with `dt_as_Date` selected here\n * (`DT'...'` → `Date`), and vice versa — see `itemOptions` below to apply\n * this to only part of a tree.\n *\n * There is no `builtinExtensions` equivalent for `toJS()`: leaving this\n * unset (the default) keeps every node's own built-in conversion\n * behavior, so no bundled extension needs to be \"re-added\" here just to\n * get default output.\n */\n extensions?: CborExtension[];\n\n /**\n * Called for every node during `toJS()`, before that node is converted,\n * to override the options used for its subtree. Return a partial options\n * object to merge over the options in effect for this node (they apply to\n * this node and are inherited by its descendants, who may override them\n * again); return `undefined` to make no change.\n *\n * This is the mechanism for applying an option — including `extensions`,\n * to select a different conversion for one node without affecting its\n * siblings — to only part of a document, keyed off `ctx.path` or the\n * node's own shape (`item instanceof ...`).\n *\n * **May be called more than once for the same AST node.** With a\n * `reviver` present, `CborArray`/`CborMap` convert each child at least\n * twice: once (with `reviver` itself withheld from the options this\n * callback sees, though its own return value is honoured as normal) to\n * build a holder a `reviver` call can inspect via `this[j]` for a\n * not-yet-processed sibling `j`, and once more, for real, to compute the\n * value the container actually keeps — and a node several levels down\n * can in principle be offered to this callback more than twice, if a\n * container at some intermediate level runs a pre-population pass of its\n * own while itself sitting inside an *outer* container's. Each call is\n * independent and reflects only the state relevant to *that* particular\n * conversion (e.g. `ctx.path` for a value under a composite map key\n * shows whatever that key currently converts to, which can differ\n * between an earlier, not-yet-revived call and a later one after the\n * key's own `reviver` has run). Write this callback as a pure function of\n * `item`/`ctx` — it must not assume, or count, how many times it runs.\n *\n * @example\n * // Convert only `date1` with `dt_as_Date`, leaving other DT values as\n * // the epoch numbers the tree was originally parsed with.\n * item.toJS({\n * itemOptions: (node, ctx) =>\n * ctx.path.length === 1 && ctx.path[0] === 'date1'\n * ? { extensions: [dt_as_Date] }\n * : undefined,\n * });\n */\n itemOptions?: (\n item: CborItem,\n ctx: ItemContext\n ) => Partial<ToJSNodeOptions> | undefined;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport interface ToCBOROptions {}\n\n/**\n * A CBOR validity violation detected during decoding.\n */\nexport interface DecodeWarning {\n /** Human-readable description of the violation. */\n message: string;\n /** Byte offset within the decoded input where the violation was detected. */\n offset: number;\n}\n\n/**\n * A CDN/EDN validity violation detected during parsing.\n */\nexport interface ParseWarning {\n /** Human-readable description of the violation. */\n message: string;\n /** Character offset within the input text where the violation was detected. */\n offset?: number;\n /** Line number (1-based) where the violation was detected. */\n line?: number;\n /** Column number (1-based) where the violation was detected. */\n column?: number;\n /**\n * Character offset just past the end of the offending range, when the\n * violation is attributable to a specific token. Lets tooling underline\n * the exact range instead of a single position.\n */\n endOffset?: number;\n /**\n * `true` when the violation is a hard syntax error that stopped parsing\n * (emitted by non-strict sequence parsing, which reports the failure as a\n * warning and abandons the rest of the input). Tooling should present\n * fatal warnings as errors.\n */\n fatal?: boolean;\n\n /**\n * `true` when this entry is an informational hint (e.g. an app-string\n * prefix matches a known optional extension that isn't registered) rather\n * than a validity violation. Parsing is unaffected either way, but tooling\n * that treats `onWarning` calls as failures (see `CBOR.validate()`) should\n * not count these against validity.\n */\n hint?: boolean;\n\n /**\n * For a `fatal` warning built from a caught syntax error (see\n * `CdnSyntaxError`), the original error object with its position fields\n * intact. `CBOR.validate()` promotes this into `ValidateResult.error`.\n */\n cause?: Error;\n}\n\nexport interface FromCBOROptions {\n /**\n * Byte offset within the supplied input at which CBOR decoding starts.\n * Useful for reading one item from a CBOR Sequence.\n *\n * @default 0\n */\n offset?: number;\n\n /**\n * Allow bytes after the decoded item.\n *\n * When `false`, decoding still requires the item to consume the remaining\n * input, preserving the historical single-item behaviour. With `strict: false`\n * a trailing byte becomes a recoverable warning rather than an error, but\n * truly malformed trailing data (e.g. truncated items) still throws. Set this\n * to `true` when using `CborItem.end` to continue decoding a CBOR Sequence.\n *\n * @example\n * // Read two items from a CBOR Sequence, validating that the second is last.\n * const first = CBOR.fromCBOR(bytes, { allowTrailing: true });\n * const second = CBOR.fromCBOR(bytes, { offset: first.end });\n *\n * @default false\n */\n allowTrailing?: boolean;\n\n /**\n * Extension plugins applied during CBOR decoding.\n * Extensions with `parseTag()` are invoked when a tagged item is\n * encountered; returning a non-`undefined` value replaces the default\n * `CborTag` node.\n */\n extensions?: CborExtension[];\n\n /**\n * Override the default set of bundled app-extensions\n * (`dt`, `ip`, `cri`, `t1`, `b1`, `ilbs`, `ilts`, `float`).\n *\n * - omitted (default): use the standard bundled set.\n * - array: replace the bundled set with exactly these extensions.\n * - `false`: disable all of them.\n *\n * `bignum` (tags 2/3) and embedded-CBOR (tag 24) support are core RFC 8949\n * representation features, not app-extensions, and are always active\n * regardless of this option.\n *\n * `dt`, `ip`, `t1`, and `b1` are mandatory-to-implement per §3 of\n * draft-ietf-cbor-edn-literals-27; disabling them produces a decoder that\n * no longer conforms to that recommendation. This is intended for\n * allowlisting scenarios (see §8 Security considerations of the same\n * draft) where an application wants explicit control over which\n * extensions it accepts.\n */\n builtinExtensions?: CborExtension[] | false;\n\n /**\n * Controls how CBOR validity violations are handled.\n *\n * - `true` (default): violations call `onWarning` and then throw, stopping\n * decoding immediately.\n * - `false`: recoverable violations call `onWarning` and decoding continues\n * with a best-effort interpretation of the data.\n *\n * Truly malformed data (e.g. truncated input, reserved AI values) always\n * throws regardless of this setting. Trailing bytes after a successfully\n * decoded item are a recoverable violation and are therefore controlled by\n * this flag.\n *\n * @default true\n */\n strict?: boolean;\n\n /**\n * Callback invoked when a CBOR validity violation is detected.\n *\n * In strict mode (the default), this is called before the error is thrown.\n * In non-strict mode (`strict: false`), this is called and decoding\n * continues.\n *\n * If not supplied and `silent` is not `true`, violations are reported via\n * `console.warn`.\n */\n onWarning?: (warning: DecodeWarning) => void;\n\n /**\n * When `true`, suppresses the default `console.warn` output for validity\n * violations. An explicit `onWarning` callback is still invoked even when\n * `silent` is `true`.\n *\n * @default false\n */\n silent?: boolean;\n\n /**\n * CDDL schema to validate decoded items against: either a compiled schema\n * (`CDDL.compile()` from `@cbortech/cbor/cddl`) or CDDL source text.\n * Source text is compiled on first use with default compile options and\n * cached, so passing the same string repeatedly does not recompile; pass a\n * compiled schema to control `CompileOptions` yourself. Invalid CDDL text\n * throws `CddlSyntaxError` / `CddlSemanticError` at the call site.\n *\n * Each decoded item is validated after decoding, against the schema's\n * root rule by default (or `cddlValidationOptions.rule`, if set); a\n * mismatch throws {@link CddlMismatchError}. Sequence entry points\n * (`fromCBORSeq`, `decodeSeq`, …) validate each item of the sequence\n * individually against that same rule. `CBOR.validate()` collects\n * mismatches into `ValidateResult.cddlErrors` instead of throwing.\n */\n cddl?: CddlSchema | string;\n\n /**\n * Options forwarded to the CDDL validator when `cddl` is supplied\n * (`features` for the `.feature` control operator, `maxDepth`,\n * `maxSteps`, and `rule` to validate against a rule other than the\n * schema's root). Ignored without `cddl`.\n */\n cddlValidationOptions?: CddlValidateOptions;\n}\n\n/**\n * Options for parsing an annotated hex dump.\n */\nexport interface FromHexDumpOptions {\n /**\n * Extension plugins applied during CBOR decoding.\n * Extensions with `parseTag()` are invoked when a tagged item is encountered;\n * returning a non-`undefined` value replaces the default `CborTag` node.\n */\n extensions?: CborExtension[];\n\n /**\n * Override the default set of bundled app-extensions.\n * Mirrors `FromCBOROptions.builtinExtensions`.\n */\n builtinExtensions?: CborExtension[] | false;\n\n /**\n * Controls how CBOR validity violations are handled during hex-dump decoding.\n * Mirrors `FromCBOROptions.strict`. With `strict: false`, trailing bytes after\n * the first decoded item (i.e. a CBOR Sequence) emit a warning instead of\n * throwing, allowing the first item to be returned.\n *\n * @default true\n */\n strict?: boolean;\n\n /**\n * Callback invoked when a CBOR validity violation is detected.\n * Mirrors `FromCBOROptions.onWarning`.\n */\n onWarning?: (warning: DecodeWarning) => void;\n\n /**\n * When `true`, suppresses the default `console.warn` output for violations.\n * Mirrors `FromCBOROptions.silent`.\n *\n * @default false\n */\n silent?: boolean;\n\n /**\n * Compiled CDDL schema to validate decoded items against.\n * Mirrors `FromCBOROptions.cddl`.\n */\n cddl?: CddlSchema | string;\n\n /**\n * Options forwarded to the CDDL validator.\n * Mirrors `FromCBOROptions.cddlValidationOptions`.\n */\n cddlValidationOptions?: CddlValidateOptions;\n}\n\nexport interface FromCDNOptions {\n /**\n * Character offset within the supplied text at which CDN parsing starts.\n * Leading whitespace/comments at or after this offset are skipped as usual.\n *\n * @default 0\n */\n offset?: number;\n\n /**\n * Allow tokens after the parsed item.\n *\n * When `false`, parsing still requires the item to consume the remaining\n * input, preserving the historical single-item behaviour. With `strict: false`\n * a trailing token becomes a recoverable warning rather than an error, but\n * hard lexer errors in the trailing content (e.g. unterminated strings) still\n * throw. Set this to `true` when using `CborItem.end` to continue parsing a\n * CDN sequence.\n * Top-level comma separators are not skipped by `fromCDN()` itself; handle\n * them in sequence-level code before passing the next `offset`. For example,\n * after parsing `1, 2`, the first item's `end` points just before the comma;\n * advance past that comma before parsing the next item.\n *\n * @example\n * // Read two whitespace-separated items, validating that the second is last.\n * const first = CBOR.fromCDN(text, { allowTrailing: true });\n * const second = CBOR.fromCDN(text, { offset: first.end });\n *\n * @default false\n */\n allowTrailing?: boolean;\n\n /**\n * Extension plugins for CDN parsing.\n * Each extension declares which app-string prefixes (and, in future, tag\n * numbers) it handles via `appStringPrefixes` / `tagNumbers`, and provides\n * callback methods that return `CborItem`-subclassed objects controlling\n * subsequent serialisation.\n *\n * User-supplied extensions take priority over the built-in `dt`/`DT`\n * extension for the same prefix.\n */\n extensions?: CborExtension[];\n\n /**\n * Override the default set of bundled app-extensions\n * (`dt`, `ip`, `cri`, `t1`, `b1`, `ilbs`, `ilts`, `float`).\n *\n * - omitted (default): use the standard bundled set.\n * - array: replace the bundled set with exactly these extensions.\n * - `false`: disable all of them; app-string literals using their\n * prefixes then fall through to `unresolvedExtension` handling.\n *\n * `dt`, `ip`, `t1`, and `b1` are mandatory-to-implement per §3 of\n * draft-ietf-cbor-edn-literals-27; disabling them produces a parser that\n * no longer conforms to that recommendation. This is intended for\n * allowlisting scenarios (see §8 Security considerations of the same\n * draft) where an application wants explicit control over which\n * extensions it accepts from untrusted CDN input.\n *\n * @example\n * // Only accept dt/DT — everything else becomes an Unresolved (tag 999) node.\n * import { CBOR, dt } from '@cbortech/cbor';\n * CBOR.fromCDN(text, { builtinExtensions: [dt] });\n */\n builtinExtensions?: CborExtension[] | false;\n\n /**\n * How to handle unrecognised app-extension identifiers\n * (§5.1 of draft-ietf-cbor-edn-literals-27).\n *\n * - `'cpa999'`: wrap the literal in a `CPA999` tag\n * (`CborUnresolvedAppExt`) instead of failing. The resulting node\n * round-trips through `toCDN()` back to the original notation.\n * - `'error'`: throw `SyntaxError` for unknown prefixes.\n * @default 'cpa999'\n */\n unresolvedExtension?: 'cpa999' | 'error';\n\n /**\n * When `true`, byte-string chunks in text string concatenation\n * (`\"a\" + h'...'`) that are not valid UTF-8 are decoded with the Unicode\n * replacement character (U+FFFD) instead of throwing a `SyntaxError`.\n *\n * The CBOR text string type (RFC 8949 §3.1) requires valid UTF-8;\n * enabling this option produces non-conformant output and should only be\n * used when interoperating with lenient producers.\n *\n * @default false\n */\n allowInvalidUtf8?: boolean;\n\n /**\n * Preserve comments found between CDN values and attach them to the AST.\n *\n * Comments are metadata only: they are ignored by CBOR binary encoding and\n * JavaScript conversion. Use together with `ToCDNOptions.preserveComments`\n * (or `comments`) to include them when formatting back to CDN.\n *\n * Passing `'c-style'`/`'cdn-style'` directly is a deprecated shorthand for\n * `true` plus the equivalent `comments` — still accepted, but prefer\n * `comments` for the output style going forward.\n *\n * @default false\n */\n preserveComments?: boolean | 'c-style' | 'cdn-style';\n\n /**\n * Companion to `preserveComments` for a single options object shared with\n * `toCDN()` (as `CBOR.format()` does internally) — see\n * `ToCDNOptions.comments` for what each value means there. On the\n * parse side, only *whether* a style other than `'strip'` was requested\n * matters: comments are captured when `preserveComments` is `true`, or\n * when `comments` is set to anything other than `'strip'`. Left\n * unset alongside an unset/`false` `preserveComments`, nothing is\n * captured.\n *\n * @default undefined\n */\n comments?: 'strip' | 'c-style' | 'cdn-style';\n\n /**\n * Shorthand for `ToCDNOptions.preserveAll`, so a single option enables\n * round-tripping through both `fromCDN()` and `toCDN()` (as\n * `CBOR.format()` does internally). On the parse side, this only implies\n * `preserveComments: true` (comments must be captured while parsing to be\n * re-emittable); the other `preserve*` behaviors are always captured by\n * the parser and only need to be turned on for `toCDN()`.\n *\n * @default false\n */\n preserveAll?: boolean;\n\n /**\n * Controls how CDN/EDN validity violations are handled.\n *\n * - `true` (default): recoverable violations call `onWarning` and then throw.\n * - `false`: recoverable violations call `onWarning` and parsing continues\n * with a best-effort interpretation of the input.\n *\n * Hard syntax errors (e.g. unterminated strings, unexpected tokens that\n * prevent parsing a value) always throw regardless of this setting.\n * A trailing token after a successfully-parsed value is a recoverable\n * violation and is therefore controlled by this flag.\n *\n * @default true\n */\n strict?: boolean;\n\n /**\n * Callback invoked when a CDN/EDN validity violation is detected.\n *\n * In strict mode (the default), this is called before the error is thrown.\n * In non-strict mode (`strict: false`), this is called and parsing continues.\n *\n * If not supplied and `silent` is not `true`, violations are reported via\n * `console.warn`.\n */\n onWarning?: (warning: ParseWarning) => void;\n\n /**\n * When `true`, suppresses the default `console.warn` output for validity\n * violations. An explicit `onWarning` callback is still invoked even when\n * `silent` is `true`.\n *\n * @default false\n */\n silent?: boolean;\n\n /**\n * Compiled CDDL schema to validate parsed items against.\n * Mirrors `FromCBOROptions.cddl`.\n */\n cddl?: CddlSchema | string;\n\n /**\n * Options forwarded to the CDDL validator.\n * Mirrors `FromCBOROptions.cddlValidationOptions`.\n */\n cddlValidationOptions?: CddlValidateOptions;\n}\n\n/**\n * Options for parsing Concise Diagnostic Notation (CDN).\n *\n * @deprecated Use `FromCDNOptions` instead.\n */\nexport type FromEDNOptions = FromCDNOptions;\n\nexport interface FromJSOptions {\n /**\n * Extension plugins applied during `fromJS()`.\n * Extensions with `fromJS()` are given first chance to convert each value.\n */\n extensions?: CborExtension[];\n\n /**\n * Override the default set of bundled app-extensions.\n * Mirrors `FromCDNOptions.builtinExtensions`. Only affects builtins that\n * implement `fromJS()` / `parseTag()` (none of the bundled app-extensions\n * implement `fromJS()` by default — use `dt_as_Date` via\n * `extensions` for `Date` round-tripping).\n */\n builtinExtensions?: CborExtension[] | false;\n\n /**\n * How to encode integer-valued JS `number`s.\n * - `'int'`: encode as CborUint / CborNint\n * - `'float'`: always encode as CborFloat\n * @default 'int'\n */\n encodeIntegerAs?: 'int' | 'float';\n\n /**\n * How to encode `Uint8Array` values.\n * - `'bytes'`: encode as CborByteString\n * - `'array'`: encode as CborArray of CborUint\n * @default 'bytes'\n */\n uint8ArrayAs?: 'bytes' | 'array';\n\n /**\n * Pre-encoding replacer function or key allowlist, applied before the\n * JavaScript value is converted to a CBOR AST node.\n *\n * - Function: called for every key/value pair (including `MapEntries`\n * entries with non-string keys). Return `CBOR.OMIT` to remove the entry.\n * When `undefinedOmits` is `true`, returning `undefined` also removes it.\n * - Array of strings/numbers: allowlist of object keys to include.\n * `MapEntries` entries retain all entries; their values are recursively\n * filtered.\n *\n * Note: this option is honoured by `fromJS()` and the `CBOR.*` shortcut\n * methods.\n */\n replacer?:\n | ((this: unknown, key: unknown, value: unknown) => unknown)\n | (string | number)[];\n\n /**\n * When `true`, a replacer returning `undefined` removes the entry from the\n * output, matching `JSON.stringify` behavior.\n * When `false` (default), only `CBOR.OMIT` removes an entry; returning\n * `undefined` keeps the entry as CBOR `undefined` (simple 23).\n * @default false\n */\n undefinedOmits?: boolean;\n\n /**\n * Compiled CDDL schema to validate the constructed item against, before\n * encoding/serialization. Mirrors `FromCBOROptions.cddl`.\n */\n cddl?: CddlSchema | string;\n\n /**\n * Options forwarded to the CDDL validator.\n * Mirrors `FromCBOROptions.cddlValidationOptions`.\n */\n cddlValidationOptions?: CddlValidateOptions;\n}\n\n// ─── Per-item option overrides (toCDN) ─────────────────────────────────────────\n\n/**\n * Context passed to a `toCDN()` `itemOptions` callback (see\n * `ToCDNOptions.itemOptions`) describing where the node being visited sits\n * in the tree. Structurally the same shape as `ItemContext` (`toJS()`'s\n * own per-item context — see there for the full rationale behind each\n * field), but `path`'s map-key segments are derived the CDN way: a\n * text-string key contributes its string value, any other key contributes\n * its own `toCDN()` rendering — there is no \"JS value\" for a CDN key to\n * contribute instead, since converting to JS is not what this call is\n * doing.\n *\n * Unlike `ItemContext`, a node's `toCDN()` `itemOptions` callback can run\n * more than once for reasons `toJS()`'s never does: `inlineLeafContainers`\n * (and a tag/app-sequence value's own multi-word check) render an entry a\n * second time, at the *same* depth and options, purely to answer a layout\n * question (does it fit on one line? is it multi-word?) before the real\n * render — an existing, deliberate characteristic of `toCDN()` itself (see\n * `serializeContainer` in `cdn/serialize-utils.ts`), not something\n * `itemOptions` introduces. Write this callback as a pure function of\n * `item`/`ctx`, the same guidance as `ItemContext`'s own, for the same\n * reason: it must not assume, or count, how many times it runs.\n */\nexport interface CdnItemContext {\n /** The direct parent AST node. `undefined` for the root value being converted. */\n parent?: CborItem;\n\n /**\n * The path segment identifying this node: an array index (`number`), or\n * a map key's string value/`toCDN()` rendering (see `CdnItemContext`'s\n * own note). Always equal to the last element of `path`, except\n * `undefined` for the root value and while converting a map key itself\n * (`isMapKey: true`). A tag or app-sequence wrapper's content inherits\n * the wrapper's own `key` (and `path`) unchanged, since the wrapper adds\n * no segment of its own.\n */\n key?: unknown;\n\n /** The map key's own AST node, present when this node is a map entry's key or value. */\n keyNode?: CborItem;\n\n /**\n * `true` when this invocation is for converting a map key itself, rather\n * than one of that key's sibling value's descendants.\n */\n isMapKey?: boolean;\n\n /**\n * Path from the root to this node, as a sequence of array indices and\n * map key identifiers (see `CdnItemContext`'s own note). Empty for the\n * root value. A tag or app-sequence wrapper does not add a segment of\n * its own — its content shares the wrapper's own path.\n */\n readonly path: readonly unknown[];\n\n /**\n * The options in effect for this node going into this call — the root\n * options merged with whatever overrides its ancestors already\n * returned, *before* this callback's own return value is merged on top.\n * A mutable-looking field here (currently just the deprecated\n * `textStringFormat`) is a fresh copy, not the live array in effect\n * elsewhere — mutating it in place has no effect on this node, its\n * siblings, or the caller's own options; return an override instead.\n */\n readonly options: ReadonlyToCDNOptions;\n}\n\n/**\n * `ToCDNOptions`, as handed to code that must not mutate it in place —\n * `CdnItemContext.options` — the `toCDN()` counterpart of\n * `ReadonlyToJSNodeOptions`. `textStringFormat` (the one field on\n * `ToCDNOptions` that's an ordinary mutable array, and already deprecated)\n * is narrowed to a readonly array for the same reason `extensions` is\n * there; see `ReadonlyToJSNodeOptions`'s own doc for the full rationale.\n */\nexport type ReadonlyToCDNOptions = Readonly<\n Omit<ToCDNOptions, 'textStringFormat'>\n> & {\n readonly textStringFormat?: readonly TextStringFormat[];\n};\n\nexport interface ToCDNOptions {\n /**\n * Indentation for pretty-printing.\n * - `number`: number of spaces\n * - `string`: literal indent string (e.g. `'\\t'`)\n * - omit for single-line output\n *\n * Like `JSON.stringify`, `0` and `''` are equivalent to omitting the\n * option: the output is a single line. Single-line output is guaranteed\n * to contain no newlines; layout-dependent options (`preserveComments`,\n * `preserveBlankLines`, `splitCdn`, `splitNewline`, `preserveConcatenation`)\n * are ignored.\n */\n indent?: number | string;\n\n /**\n * Master switch that turns on every `preserve*` option below at once,\n * except the deprecated `preserveTextString` — `preserveComments`,\n * `preserveByteString`, `preserveRawString`, `preserveConcatenation`,\n * `preserveNumberFormat`, `preserveAppPrefix`, and\n * `preserveBlankLines` — for reformatting CDN text (e.g. on save in an\n * editor) with minimal changes: only whitespace/indentation, plus\n * anything an explicitly-set individual option overrides.\n *\n * An option explicitly set to a value (including `false`) is left as-is;\n * `preserveAll` only fills in the ones left `undefined`. So\n * `{ preserveAll: true, preserveNumberFormat: false }` preserves\n * everything except number literal spelling. `preserveComments` is filled\n * in with `true` only when `comments` is *also* left unset — an\n * explicit `comments` with no `preserveComments` still normalizes\n * comments to that style under `preserveAll`, instead of being overridden\n * by the verbatim fill-in.\n *\n * When parsing via `CBOR.fromCDN()` separately from `toCDN()` (rather\n * than through `CBOR.format()`, which passes the same options to both),\n * also pass `preserveAll` (or `preserveComments`) to `FromCDNOptions` so\n * comments are captured in the first place — see\n * `FromCDNOptions.preserveAll`. Bignums are unaffected by\n * `preserveNumberFormat` even under `preserveAll`; see that option.\n *\n * @default false\n */\n preserveAll?: boolean;\n\n /**\n * Emit comments previously captured by `FromCDNOptions.preserveComments`,\n * with their original markers kept as-is (no normalization) — takes\n * precedence over `comments` when `true`.\n *\n * - `true`: emit comments verbatim, with whichever marker each one was\n * originally written with.\n * - `false` / omitted: defer to `comments` (see below) — `'strip'` (the\n * default when that's also unset) or unset means no comments are\n * emitted.\n * - `'c-style'` / `'cdn-style'`: deprecated shorthand for `false` plus the\n * equivalent `comments`; still accepted, but prefer setting\n * `comments` directly.\n *\n * Only effective when `indent` enables pretty-printing: single-line\n * output strips all comments regardless, since line comments (`#`, `//`)\n * can only be terminated by a newline.\n *\n * @default false\n */\n preserveComments?: boolean | 'c-style' | 'cdn-style';\n\n /**\n * Style to normalize comment markers to when emitting comments previously\n * captured by `FromCDNOptions.preserveComments` — only consulted when\n * `preserveComments` is not `true` (see there).\n *\n * - `'strip'` / omitted: don't emit comments at all.\n * - `'c-style'`: emit comments, normalising line comments to `//` and block\n * comments to `/* … *\\/`.\n * - `'cdn-style'`: emit comments, normalising line comments to `#` and block\n * comments to `/ … /`. When a `/* … *\\/` comment's content contains `/`\n * (which cannot be represented inside `/ … /`), the `/* … *\\/` form is\n * kept as-is.\n *\n * Only effective when `indent` enables pretty-printing; see\n * `preserveComments`.\n *\n * @default 'strip'\n */\n comments?: 'strip' | 'c-style' | 'cdn-style';\n\n /**\n * Re-emit a blank line above an array/map entry (or indefinite-length\n * string chunk) that had one before it anywhere in the parsed CDN source,\n * so paragraph-like groupings of entries survive a reformat. At most one\n * blank line is ever emitted per gap, regardless of how many blank lines\n * were originally there.\n *\n * Detection is based purely on entry source positions — it does not\n * require `preserveComments` and is unaffected by whether comments are\n * emitted.\n *\n * Only effective when `indent` enables pretty-printing. A container with\n * a preserved blank line is always emitted one-entry-per-line, the same\n * as a container with preserved comments (see `inlineLeafContainers`).\n *\n * @default false\n */\n preserveBlankLines?: boolean;\n\n /**\n * Re-emit byte string literals parsed from CDN using their original source\n * text when available.\n *\n * This preserves the spelling and interior layout of non-concatenated\n * `h'...'`, `b64'...'`, `b32'...'`, `h32'...'`, raw-backtick byte strings,\n * and single-quoted byte strings — including a `h'xx...yy'`-family elided\n * literal (§5.2), whose spelling is kept independently of\n * `preserveConcatenation` when it has no `+` of its own (see that\n * option). Byte strings produced by `+` concatenation are normalised as\n * usual; combine with `preserveConcatenation` to keep both the part\n * boundaries and each part's spelling.\n *\n * A comment inside the literal is stripped unless `preserveComments` is\n * also set — `preserveByteString` alone preserves everything about the\n * literal's spelling *except* its comments, the same as an unpreserved\n * literal (re-derived from the decoded value) never has comments either.\n *\n * When enabled, this takes precedence over `bstrEncoding` and `sqstr` for\n * byte strings that carry original EDN source text.\n *\n * In single-line output (no `indent`), an original spelling that spans\n * multiple lines — after any comment is stripped — falls back to normal\n * serialization; single-line spellings are kept.\n *\n * @default false\n */\n preserveByteString?: boolean;\n\n /**\n * Re-emit text strings written as raw backtick literals (`` `...` ``,\n * ``` ``...`` ```, …) using their original source text instead of\n * converting them to double-quoted form.\n *\n * Applies to non-concatenated raw string literals; combine with\n * `preserveConcatenation` to also keep the spelling of raw string parts\n * inside a `+` chain. Preserved raw strings are emitted verbatim: they are\n * never re-escaped, re-indented, or split by `splitCdn` / `splitNewline`.\n *\n * Raw byte string forms (e.g. `` h`...` ``) are covered by\n * `preserveByteString`, not this option.\n *\n * In single-line output (no `indent`), a spelling that spans multiple\n * lines falls back to normal escaping; single-line spellings are kept.\n *\n * @default false\n */\n preserveRawString?: boolean;\n\n /**\n * Re-emit double-quoted text strings (`\"...\"`) using their original CDN\n * source spelling — escape sequences (`é` vs. the literal character),\n * quoting choices, etc. — instead of re-escaping them from the decoded\n * string value.\n *\n * Applies to non-concatenated double-quoted literals only; a string\n * reached via `+` concatenation is normalised as usual regardless of this\n * option. Preserved strings are emitted verbatim: they are never\n * re-indented or split by `splitCdn` / `splitNewline`.\n *\n * Raw backtick literals (`` `...` ``) are covered by `preserveRawString`,\n * not this option.\n *\n * In single-line output (no `indent`), a spelling that spans multiple\n * lines falls back to normal escaping; single-line spellings are kept.\n *\n * @deprecated Verbatim spelling and `splitCdn` / `splitNewline` reflow\n * are mutually exclusive for a given literal — enabling this option\n * silently defeats both for any non-concatenated double-quoted string.\n * It still works when set explicitly, but no longer participates in\n * `preserveAll` and has been removed from the playground's preserve\n * options.\n *\n * @default false\n */\n preserveTextString?: boolean;\n\n /**\n * Re-emit integer and floating-point literals using their original CDN\n * source spelling — base (`0xff` / `0o377` / `0b101` / decimal), digit\n * spelling, decimal point / exponent form, and encoding-indicator suffix\n * (e.g. `1.5_1`) — instead of normalising them via `intFormat` /\n * `floatFormat` and recomputed encoding indicators.\n *\n * Takes precedence over `intFormat` and `floatFormat` for literals parsed\n * from CDN text. Values that did not originate from CDN text (e.g. built\n * via `CBOR.from()` or decoded from CBOR bytes) always fall back to normal\n * formatting, since there is no original spelling to preserve. Bignums\n * (integers outside the uint64/int64 range) are unaffected and always\n * render as plain decimal.\n *\n * Combine with `preserveByteString`, `preserveRawString`,\n * `preserveConcatenation`, and `preserveComments` to reformat CDN text\n * (e.g. whitespace/indentation only) with minimal changes to the rest of\n * the source.\n *\n * @default false\n */\n preserveNumberFormat?: boolean;\n\n /**\n * Whether to emit commas between array/map elements.\n * - `'comma'`: emit commas (`[1, 2, 3]`)\n * - `'none'`: omit commas, use spaces only (`[1 2 3]`)\n * - `'trailing'`: emit commas including a trailing comma after the last element\n * @default 'comma'\n */\n commas?: 'comma' | 'none' | 'trailing';\n\n /**\n * Fallback binary encoding for byte string literals when sqstr is not applicable.\n * - `'hex'`: `h'...'`\n * - `'base64'`: `b64'...'`\n * - `'base64url'`: `b64'...'` (base64url alphabet)\n * @default 'hex'\n */\n bstrEncoding?: 'hex' | 'base64' | 'base64url';\n\n /**\n * Whether to prefer single-quoted string form (`sqstr`) for byte strings.\n * - `'printable-string'`: emit `'...'` when the bytes are valid UTF-8 and\n * contain no control characters; fall back to `bstrEncoding` otherwise.\n * - `'string'`: emit `'...'` when the bytes are valid UTF-8;\n * fall back to `bstrEncoding` otherwise.\n * - `'none'`: never emit sqstr; always use `bstrEncoding`.\n * @default 'printable-string'\n */\n sqstr?: 'printable-string' | 'string' | 'none';\n\n /**\n * Whether to use app-prefix notation — app-string (`dt'...'`, `` dt`...` ``)\n * or app-sequence (`dt<<...>>`) — for built-in extensions.\n * - `true`: emit extension notation (`DT'2023-01-01T12:00:00Z'`)\n * - `false`: emit raw CBOR notation (`1(-14159024)`, `52(h'c000022a')`)\n *\n * Named after `app-prefix` (§6.1 of draft-ietf-cbor-edn-literals-27), the\n * identifier both notations are built from — not just the app-string form,\n * despite the old `appStrings` name (`false` also falls back to raw tag\n * notation for a preserved app-sequence spelling; see `preserveAppPrefix`).\n *\n * @default true\n */\n appPrefix?: boolean;\n\n /**\n * @deprecated Renamed to `appPrefix` — the old name only described the\n * app-string form even though this option also gates app-sequence\n * (`<<...>>`) notation. Still honoured when `appPrefix` is left unset,\n * but `appPrefix` wins if both are set.\n */\n appStrings?: boolean;\n\n /**\n * For built-in extensions that support app-string notation\n * (`prefix'...'` or `` prefix`...` ``), app-sequence notation\n * (`prefix<<...>>`), and/or a raw tag literal (`N(...)`), re-emit a value\n * using its exact original spelling instead of normalizing it to the\n * regenerated `prefix'...'` form.\n *\n * By default, an extension like `dt`/`DT` or `ip`/`IP` regenerates its\n * notation from the resolved value on every call — so\n * `` DT`1969-07-21T02:56:16Z` ``, `DT<<'1969-07-21T02:56:16Z'>>`, and even\n * the raw tag form `1(1749772800)` all become\n * `DT'2025-06-13T00:00:00Z'`-style `prefix'...'` notation, even though all\n * of these denote the same value. `preserveAppPrefix` keeps the\n * original spelling instead — whichever quoting (`'...'` vs `` `...` ``),\n * bracketing (`<<...>>`), or raw tag form was used. Has no effect when\n * `appPrefix` is `false` (raw tag notation is used either way regardless\n * of the original spelling), or on values not parsed from one of these\n * forms.\n *\n * In single-line output (no `indent`), a spelling that spans multiple\n * lines falls back to normal (regenerated) notation; single-line\n * spellings are kept.\n *\n * An explicit `preserveComments`/`comments` setting is still applied\n * to comments inside a preserved app-sequence spelling: marker styles are\n * normalised without changing the notation family, and stripping comments\n * (`preserveComments: false` with `comments` unset or `'strip'`)\n * removes them while retaining the surrounding source spelling. Leaving\n * *both* unset keeps the spelling's comments exactly as originally\n * written, since nothing was explicitly requested.\n *\n * Named after `app-prefix` (§6.1 of draft-ietf-cbor-edn-literals-27; e.g.\n * `dt`, `DT`, `ip`, `IP`), the identifier that `app-string`/`app-sequence`\n * notation is built from. The raw tag literal case is still covered: it's\n * the source spelling that used *no* app-prefix at all, and this option\n * preserves that choice too, not just spellings that did use one.\n * `preserveAppSequence` was the old, narrower name for this same option,\n * since it also preserves app-string and raw-tag spellings, not just\n * `<<...>>` sequences.\n *\n * @default false\n */\n preserveAppPrefix?: boolean;\n\n /**\n * @deprecated Renamed to `preserveAppPrefix` — the old name only\n * described the `<<...>>` form even though this option also preserves\n * `prefix'...'` / `` prefix`...` `` and raw tag (`N(...)`) spellings.\n * Still honoured when `preserveAppPrefix` is left unset, but\n * `preserveAppPrefix` wins if both are set, and it no longer\n * participates in `preserveAll` (use `preserveAppPrefix` for that).\n */\n preserveAppSequence?: boolean;\n\n /**\n * Numeric format for integer values in CDN output.\n * - `'decimal'`: standard decimal notation (e.g. `42`, `-14159024`)\n * - `'hex'`: hexadecimal notation (e.g. `0x2a`, `-0xd83130`)\n * - `'octal'`: octal notation (e.g. `0o52`, `-0o67061560`)\n * - `'binary'`: binary notation (e.g. `0b101010`, `-0b110110000011000100110000`)\n * @default 'decimal'\n */\n intFormat?: 'decimal' | 'hex' | 'octal' | 'binary';\n\n /**\n * Numeric format for floating-point values in CDN output.\n * - `'decimal'`: standard decimal notation (e.g. `1.5`, `145544.0_3`)\n * - `'hex'`: C99-style hex float notation (e.g. `0x1.8p+0`, `0x1.1c54p+17_3`)\n * - `'app-extension'`: `float'...'` app-string notation carrying the\n * value's exact IEEE 754 bit pattern (e.g. `float'3fc00000'`), per §3.8\n * of draft-ietf-cbor-edn-literals-27. Unlike `'decimal'`/`'hex'`, this\n * is derived from the value's actual encoded bytes rather than its\n * numeric text, so it losslessly represents NaN payloads and\n * ±Infinity too (not just finite values). Falls back to `'decimal'`\n * when `appPrefix` is `false`, matching how other built-in extensions\n * fall back to raw notation.\n *\n * A value originally parsed from a `float'...'`/`float<<...>>` literal\n * normally re-emits that exact source spelling regardless of this option\n * (so its own encoding-width choice, or a non-canonical bit pattern, isn't\n * silently normalized away) — leaving `floatFormat` unset, or setting it\n * to `'app-extension'`, keeps that round-trip. Explicitly requesting\n * `'decimal'` or `'hex'` opts out of it and reformats the value like any\n * other float, since that's the point of asking for a different format.\n * @default 'decimal'\n */\n floatFormat?: 'decimal' | 'hex' | 'app-extension';\n\n /**\n * Split long text strings using CDN string concatenation syntax (`\"a\" + \"b\"`).\n * Only effective when `indent` enables pretty-printing.\n *\n * - `'newline'`: split at newline characters\n * - `'cdn'`: split according to CDN structure when the string content\n * is parseable as CDN (JSON superset)\n * - `'cboredn'`: deprecated alias for `'cdn'`\n *\n * When both are specified, CDN structure split points are combined with\n * newline split points.\n *\n * @deprecated Use `splitCdn` / `splitNewline` instead. When one of those\n * is specified, it takes precedence over the corresponding array entry.\n */\n textStringFormat?: TextStringFormat[];\n\n /**\n * Format text strings whose content is parseable as CDN (a JSON superset)\n * by splitting them with CDN string concatenation (`\"{\" + \"1:2\" + \"}\"`)\n * and structure-aware indentation, the same way the surrounding CDN is\n * formatted. Only effective when `indent` is specified.\n *\n * When the string content parses as CDN, this takes precedence over\n * `preserveConcatenation`; when it does not, the original concatenation\n * is preserved as usual.\n *\n * `inlineLeafContainers` applies to the embedded CDN structure too: an\n * array/map/`<<...>>` in the string content that would stay on one line\n * as a real value keeps its split points collapsed here as well (e.g.\n * `\"[1, 2, 3]\"` stays a single literal instead of splitting per element).\n *\n * Replaces the deprecated `textStringFormat: ['cdn']`.\n *\n * @default false\n */\n splitCdn?: boolean;\n\n /**\n * Split text strings at newline characters using CDN string concatenation\n * (`\"line1\\n\" + \"line2\"`). Only effective when `indent` is specified.\n *\n * Combines with `preserveConcatenation`: preserved concatenation parts\n * are further split at the newline characters they contain.\n *\n * Replaces the deprecated `textStringFormat: ['newline']`.\n *\n * @default false\n */\n splitNewline?: boolean;\n\n /**\n * Preserve `+` string concatenation from the parsed CDN source.\n *\n * When a text string or byte string was parsed from a CDN concatenation\n * chain (e.g. `\"a\" + \"b\"` or `h'01' + h'02'`), re-emit it as a\n * concatenation with the original part boundaries instead of joining the\n * parts into a single literal. Each part is re-serialized with the normal\n * rules (`bstrEncoding` / `sqstr` for byte strings); combine with\n * `preserveByteString` to also keep the original spelling of byte string\n * parts.\n *\n * Interaction with the split options: `splitCdn` takes precedence for\n * text strings whose content parses as CDN, while `splitNewline` combines\n * with this option by further splitting the preserved parts at newline\n * characters. Has no effect on values that did not originate from a CDN\n * concatenation, and only takes effect when `indent` enables\n * pretty-printing (single-line output joins the parts into one literal).\n *\n * Also applies within an elision (`...`, §5.2 of\n * draft-ietf-cbor-edn-literals-27): a `+`-joined fragment on either side of\n * an ellipsis keeps its own part boundaries too (e.g. `'test' +\n * h'1234...abcd' + ...` stays exactly as written instead of merging\n * `'test'` into the byte fragment before it), and byte-string elision\n * keeps the `h'xx' + ... + h'yy'` spelling instead of the default compact\n * `h'xx...yy'` literal. Unlike the text/byte-string case above, this\n * applies regardless of `indent`, and the parts stay on one line even\n * under `indent` (elision is always single-line): a `+` boundary inside an\n * ellipsis is never a lossless merge — the elided middle can't be \"joined\n * in\" — so there's no indent-dependent fallback to prefer, and no reason\n * to reflow it.\n *\n * @default false\n */\n preserveConcatenation?: boolean;\n\n /**\n * Render preserved `+` string concatenation (see `preserveConcatenation`)\n * or an elision chain (`...`, §5.2) using `t1<<...>>` / `b1<<...>>`\n * app-sequence notation (draft-ietf-cbor-edn-literals-27 §3.5)\n * instead of the legacy `+` operator.\n *\n * - `false` (default): `\"a\" + \"b\"` / `'test' + h'1234...abcd' + ...`.\n * - `true`: `t1<<\"a\", \"b\">>` / `b1<<h'1234', h'..abcd'>>`. Falls back to\n * `false`'s rendering when `appPrefix` is `false`, since this notation\n * is itself an app-string form.\n *\n * For a plain (non-elision) concatenation, only changes the spelling used\n * where `preserveConcatenation` already causes multi-part rendering; has\n * no effect when concatenation collapses into a single merged literal\n * (e.g. `preserveConcatenation` unset, or a text string whose content is\n * reflowed by `splitCdn` instead). An elision chain is different: `...`\n * denotes genuinely unknown content, so it always renders as multiple\n * parts regardless of `preserveConcatenation` — `modernConcat` therefore\n * also applies to it unconditionally (`preserveConcatenation` there only\n * controls how much of a fragment's *own* internal boundary is shown, not\n * whether the chain itself is shown as multiple parts).\n *\n * Has no effect on a value that was itself parsed from `t1<<...>>` /\n * `b1<<...>>` source: when `appPrefix` is not `false`, `encodingIndicators`\n * is `'auto'` (both defaults), and the source is either single-line or\n * being rendered with `indent` enabled, that spelling is kept verbatim\n * regardless of `modernConcat` (see `t1`/`b1` in\n * [String Concatenation and Indefinite-Length Strings](../README.md#string-concatenation-and-indefinite-length-strings)).\n * A multi-line source falls back to normalized (collapsed) output in\n * single-line mode, since that layout can't be reproduced without\n * `indent`. `modernConcat` only affects values reconstructed from a `+`\n * chain.\n *\n * @default false\n */\n modernConcat?: boolean;\n\n /**\n * Render an indefinite-length string using `ilts<<...>>` / `ilbs<<...>>`\n * app-sequence notation (draft-ietf-cbor-edn-literals-27 §3.6)\n * instead of the legacy `(_ \"a\", \"b\")` streamstring form.\n *\n * - `false` (default): `(_ \"a\", \"b\")`.\n * - `true`: `ilts<<\"a\", \"b\">>` / `ilbs<<h'..', h'..'>>`. Falls back to\n * `false`'s rendering when `appPrefix` is `false`, since this notation\n * is itself an app-string form.\n *\n * Applies whenever an indefinite-length string is rendered as chunks;\n * unaffected by `encodingIndicators: 'never'`, which merges the chunks\n * into a single definite-length literal regardless of this option.\n *\n * Has no effect on a value that was itself parsed from `ilts<<...>>` /\n * `ilbs<<...>>` source: when `appPrefix` is not `false`, `encodingIndicators`\n * is `'auto'` (both defaults), and the source is either single-line or\n * being rendered with `indent` enabled, that spelling is kept verbatim\n * regardless of `modernStreamSyntax`. A multi-line source falls back to\n * normalized (collapsed) output in single-line mode, since that layout\n * can't be reproduced without `indent`. `modernStreamSyntax` only affects\n * values reconstructed from a legacy `(_ ...)` chunk list.\n *\n * @default false\n */\n modernStreamSyntax?: boolean;\n\n /**\n * When pretty-printing with `indent`, keep an array, map, or\n * indefinite-length string group (`(_ \"a\", \"b\")`) on a single line when\n * none of its entries contains an array or map (even wrapped in a tag),\n * none of its entries is a text string with two or more words (also even\n * wrapped in a tag), and every entry serializes without a line break\n * (e.g. `[1, 2, 3]`, `{\"a\": 1}`, `(_ \"a\", \"b\")`). Word boundaries follow\n * `Intl.Segmenter`'s word-break rules, so `[\"hello\", \"world\"]` still\n * collapses to one line (each entry is a single word) while `[\"Hello,\n * World!\", \"This is the CBOR library.\"]` renders one entry per line (each\n * has two or more) — space-less scripts (Japanese, Chinese, ...) are still\n * split on their own dictionary-based word boundaries. Nested leaf\n * containers still collapse individually: `[[1, 2], [3, 4]]` renders with\n * one inner array per line.\n *\n * `<<...>>` (CBOR Sequence Literal / embedded CBOR) is not governed by\n * this option at all: its own parens never require an additional line\n * break by themselves, regardless of `inlineLeafContainers`'s value,\n * since (unlike an array, map, or indefinite-length string group) it has\n * no nested-structure display of its own to spread out — it's a flat\n * sequence of encoded items. Instead it stays on one line exactly when\n * every entry's own actual rendering already does — an entry that is\n * itself an array/map is not disqualified just for being one, unlike in\n * an outer array/map. Concretely: `<<{1: -7}>>` renders as `<<{1: -7}>>`\n * when `inlineLeafContainers` lets the inner map collapse to one line,\n * but as `<<\\n {\\n 1: -7\\n }\\n>>` when it doesn't (the map itself\n * still spreads one entry per line without the option, same as it would\n * anywhere else — `<<...>>` just doesn't add a break of its own on top\n * of that). `[{1: -7}]`, by contrast, always spreads its `{1: -7}` entry\n * onto its own line regardless of whether the map itself collapses,\n * since a nested array/map always disqualifies an outer array/map's\n * entry. A two-or-more-word text entry still forces a break inside\n * `<<...>>` either way, irrespective of `inlineLeafContainers`.\n *\n * Containers with preserved comments are always emitted in multi-line\n * form. Has no effect when `indent` is omitted.\n *\n * @default false\n */\n inlineLeafContainers?: boolean;\n\n /**\n * Control whether CBOR encoding-width indicators (`_N`) are appended to CDN output.\n *\n * - `'always'`: always emit the encoding indicator, even for canonical encodings\n * (e.g. `1_i`, `\"hello\"_i`, `[_i 1, 2]`)\n * - `'auto'`: emit indicators only when the CBOR encoding is non-canonical —\n * i.e. more bytes were used than necessary (e.g. `1_3` for a uint encoded with 8 bytes)\n * - `'never'`: never emit encoding indicators\n *\n * @default 'auto'\n */\n encodingIndicators?: 'always' | 'auto' | 'never';\n\n /**\n * Called for every node during `toCDN()`, before that node is rendered,\n * to override the options used for its subtree. Return a partial options\n * object to merge over the options in effect for this node (they apply to\n * this node and are inherited by its descendants, who may override them\n * again); return `undefined` to make no change.\n *\n * This is the mechanism for applying an option to only part of a\n * document — e.g. rendering one array element in hex while the rest stay\n * decimal — keyed off `ctx.path` or the node's own shape\n * (`item instanceof ...`).\n *\n * **May be called more than once for the same AST node** — see\n * `CdnItemContext`'s own note on why, and why this callback should be a\n * pure function of `item`/`ctx` rather than relying on how many times it\n * runs.\n *\n * Not called for keys of an indefinite-length string's chunks or a\n * `<<...>>` sequence's items, which have no key of their own to convert\n * (only array elements and map entries/keys have a `path` segment).\n *\n * @example\n * // Render only the value at key \"raw\" using hex integers, leaving the\n * // rest of the document in the default decimal format.\n * item.toCDN({\n * indent: 2,\n * itemOptions: (_node, ctx) =>\n * ctx.path.length === 1 && ctx.path[0] === 'raw'\n * ? { intFormat: 'hex' }\n * : undefined,\n * });\n */\n itemOptions?: (\n item: CborItem,\n ctx: CdnItemContext\n ) => Partial<ToCDNOptions> | undefined;\n}\n\nexport type TextStringFormat = 'newline' | 'cdn' | DeprecatedTextStringFormat;\n\n/** @deprecated Use `'cdn'` instead. */\nexport type DeprecatedTextStringFormat = 'cboredn';\n\n/**\n * Options for serializing Concise Diagnostic Notation (CDN).\n *\n * @deprecated Use `ToCDNOptions` instead.\n */\nexport type ToEDNOptions = ToCDNOptions;\n\nexport interface CborComment {\n kind: 'line' | 'block';\n marker: '#' | '//' | '/*' | '/';\n text: string;\n start: number;\n end: number;\n line: number;\n col: number;\n /**\n * `true` when this is a `leading` comment that ends on the same source\n * line as the node it's attached to — e.g. `/ protected / << ... >>` in an\n * RFC 9052-style annotated array, as opposed to a comment on its own line\n * above the value. `toCDN()` renders these as an inline prefix on the\n * value's own line instead of a separate line above it. `undefined` for\n * `trailing`/`dangling` comments, where it doesn't apply.\n */\n sameLine?: boolean;\n}\n\nexport interface CborComments {\n leading?: CborComment[];\n trailing?: CborComment[];\n dangling?: CborComment[];\n}\n\n/**\n * Options for `CBOR.validate()`.\n */\nexport interface ValidateOptions {\n /**\n * Input format.\n * - `'cbor'`: binary CBOR, decoded as a CBOR Sequence (RFC 8742).\n * - `'cdn'`: CDN text, parsed as a CDN Sequence.\n * - `'hex'`: annotated hex dump text, decoded as a CBOR Sequence.\n * @default 'cbor'\n */\n type?: 'cbor' | 'cdn' | 'hex';\n\n /**\n * Extension plugins used while decoding/parsing.\n * Mirrors `FromCBOROptions.extensions` / `FromCDNOptions.extensions`.\n */\n extensions?: CborExtension[];\n\n /**\n * Override the default set of bundled app-extensions.\n * Mirrors `FromCBOROptions.builtinExtensions`.\n */\n builtinExtensions?: CborExtension[] | false;\n\n /**\n * How to handle unrecognised app-extension identifiers.\n * Only applies when `type` is `'cdn'`; mirrors `FromCDNOptions.unresolvedExtension`.\n * @default 'cpa999'\n */\n unresolvedExtension?: 'cpa999' | 'error';\n\n /**\n * CDDL schema to validate each decoded/parsed item against: either a\n * compiled schema (`CDDL.compile()` from `@cbortech/cbor/cddl`) or CDDL\n * source text (compiled on first use and cached; mirrors\n * `FromCBOROptions.cddl`).\n *\n * Unlike the throwing entry points, `CBOR.validate()` does not throw on a\n * mismatch: failures are collected into `ValidateResult.cddlErrors` (and\n * validator observations into `ValidateResult.cddlWarnings`), and any\n * mismatch makes `valid` `false`. Each item of a sequence is validated\n * individually against the schema's root rule by default (or\n * `cddlValidationOptions.rule`, if set). Note that invalid CDDL source\n * text itself still throws (`CddlSyntaxError` / `CddlSemanticError`): the\n * schema is part of the call, not the data being validated.\n */\n cddl?: CddlSchema | string;\n\n /**\n * Options forwarded to the CDDL validator.\n * Mirrors `FromCBOROptions.cddlValidationOptions`.\n */\n cddlValidationOptions?: CddlValidateOptions;\n}\n\n/**\n * Result of `CBOR.validate()`.\n */\nexport interface ValidateResult {\n /**\n * `true` when every item decoded/parsed without error and without any\n * warnings. `false` when the input was malformed (see `error`) or\n * well-formed but in violation of a validity constraint (see `warnings`).\n */\n valid: boolean;\n\n /** Number of items successfully decoded/parsed before any error. */\n count: number;\n\n /**\n * Validity violations encountered while decoding/parsing in non-strict\n * mode (recoverable — decoding continued after each one). Excludes\n * informational hints (see `hints`) and the fatal CDN warning that\n * `error` is built from, if any.\n */\n warnings: (DecodeWarning | ParseWarning)[];\n\n /**\n * Informational hints (`ParseWarning.hint`) encountered while parsing,\n * e.g. an app-string prefix that matches a known optional extension which\n * isn't registered. Hints never affect `valid`; they are collected here so\n * tooling can still surface them.\n */\n hints: ParseWarning[];\n\n /**\n * Set when decoding/parsing failed outright: either it threw (e.g.\n * truncated CBOR data), or — for CDN input — `fromCDNSeq()` abandoned the\n * rest of the sequence after a hard syntax error (reported internally as a\n * `fatal` warning, which `validate()` promotes to `error` rather than\n * including in `warnings`). For a CDN syntax error this is the original\n * `CdnSyntaxError`, position fields intact.\n */\n error?: Error;\n\n /**\n * CDDL validation failures, collected per decoded item. Only present when\n * `ValidateOptions.cddl` was supplied (empty array when every item\n * matched). Any entry makes `valid` `false`.\n */\n cddlErrors?: CddlValidationError[];\n\n /**\n * Non-fatal CDDL validator observations (e.g. unsupported control\n * operators whose constraints were skipped). Only present when\n * `ValidateOptions.cddl` was supplied. Never affects `valid`.\n */\n cddlWarnings?: CddlValidationWarning[];\n}\n\n/** Options for `fromCBORSeq()` (`offset`/`allowTrailing` are excluded — the generator manages them). */\nexport type FromCBORSeqOptions = Omit<\n FromCBOROptions,\n 'offset' | 'allowTrailing'\n>;\n\n/** Options for `fromCDNSeq()` (`offset`/`allowTrailing` are excluded — the generator manages them). */\nexport type FromCDNSeqOptions = Omit<\n FromCDNOptions,\n 'offset' | 'allowTrailing'\n>;\n\n/**\n * Combined options for the `CBOR` constructor.\n *\n * These defaults are applied to every subsequent method call on the instance.\n * Per-call options always take precedence over these defaults.\n *\n * Note: `encodeIntegerAs` (from {@link FromJSOptions}) and `integerAs` (from\n * {@link ToJSOptions}) are distinct fields and do not conflict.\n */\nexport type CBOROptions = FromCDNOptions &\n FromJSOptions &\n ToCBOROptions &\n ToCDNOptions &\n ToJSOptions &\n ToHexDumpOptions;\n","/**\n * Wrapper for unrecognised CBOR simple values (0–255, excluding false/true/\n * null/undefined). Returned by CborSimple.toJS() so that fromJS() can\n * reconstruct the original CborSimple node and preserve the round-trip.\n *\n * Also serves as a namespace for simple-value utilities.\n *\n * @example\n * const v = CBOR.fromCDN('simple(19)').toJS();\n * Simple.is(v); // true\n * Simple.get(v); // 19\n *\n * const node = CBOR.fromJS(new Simple(19));\n * node.toCDN(); // \"simple(19)\"\n */\nexport class Simple {\n readonly value: number;\n\n constructor(value: number) {\n if (!Number.isInteger(value) || value < 0 || value > 255)\n throw new RangeError('Simple value must be an integer in 0–255');\n this.value = value;\n }\n\n valueOf(): number {\n return this.value;\n }\n\n toJSON(): never {\n throw new TypeError(`simple(${this.value}) cannot be serialized to JSON`);\n }\n\n /** Return true if value is a Simple instance. */\n static is(value: unknown): value is Simple {\n return value instanceof Simple;\n }\n\n /** Return the simple number if value is a Simple instance, otherwise undefined. */\n static get(value: unknown): number | undefined {\n return value instanceof Simple ? value.value : undefined;\n }\n}\n","/**\n * Float16 (IEEE 754 binary16) encode/decode utilities.\n *\n * Uses native DataView.getFloat16 / setFloat16 when both are available,\n * and falls back to a manual bit-manipulation implementation otherwise.\n *\n * binary16 format:\n * bit 15 : sign\n * bits 14-10: exponent (5 bits, bias = 15)\n * bits 9- 0: mantissa (10 bits)\n */\n\nexport const hasNativeFloat16 =\n 'getFloat16' in DataView.prototype && 'setFloat16' in DataView.prototype;\n\n// Reusable 8-byte buffer for float64 bit extraction (avoids per-call allocation)\nconst _buf8 = new ArrayBuffer(8);\nconst _dv8 = new DataView(_buf8);\n\n/**\n * float64 → float16 bit pattern (16-bit unsigned integer).\n *\n * Operates directly on float64 bits to avoid double-rounding artifacts that\n * arise from a float64 → float32 → float16 two-step conversion.\n * Implements IEEE 754 round-to-nearest-ties-to-even (RN-TE).\n *\n * Exported for testing (manual vs native consistency checks).\n */\nexport function float64ToFloat16Bits(value: number): number {\n // Store the float64 in big-endian order so the bit layout is predictable\n _dv8.setFloat64(0, value, false);\n const hi = _dv8.getUint32(0, false); // bits 63-32 of IEEE 754 binary64\n const lo = _dv8.getUint32(4, false); // bits 31-0\n\n const sign = (hi >>> 31) & 1;\n const exp64 = (hi >>> 20) & 0x7ff; // 11-bit exponent, bias 1023\n const mantHi = hi & 0x000f_ffff; // top 20 bits of the 52-bit mantissa\n // lo = lower 32 bits of the mantissa\n\n // ── Infinity / NaN ──────────────────────────────────────────────────────────\n if (exp64 === 0x7ff) {\n if (mantHi === 0 && lo === 0) return (sign << 15) | 0x7c00; // ±Infinity\n // NaN: carry top 10 mantissa bits; guarantee at least one bit is set\n const f16mant = (mantHi >> 10) | (lo !== 0 ? 1 : 0) || 1;\n return (sign << 15) | 0x7c00 | (f16mant & 0x3ff);\n }\n\n // Rebias: float64 exponent bias 1023 → float16 bias 15\n const f16Exp = exp64 - 1023 + 15;\n\n // ── Overflow → ±Infinity ────────────────────────────────────────────────────\n if (f16Exp >= 31) return (sign << 15) | 0x7c00;\n\n let f16mant: number;\n let roundBit: number;\n let sticky: boolean;\n\n if (f16Exp <= 0) {\n // ── Underflow ──────────────────────────────────────────────────────────────\n if (f16Exp < -10) return sign << 15; // → ±0\n\n // ── Denormal ───────────────────────────────────────────────────────────────\n // Reconstruct the 53-bit significand's top 21 bits: [implicit 1][mantHi 20-bit]\n const top21 = (1 << 20) | mantHi;\n\n // Right-shift amount to align the significand for a float16 denormal:\n // f16mant = round(top53 / 2^(43 - f16Exp))\n // We approximate top53 ≈ top21 × 2^32 (low bits from `lo` affect only rounding).\n const s = 11 - f16Exp; // s ∈ [11, 21]\n\n if (s <= 20) {\n f16mant = (top21 >> s) & 0x3ff;\n roundBit = (top21 >> (s - 1)) & 1;\n sticky = (top21 & ((1 << (s - 1)) - 1)) !== 0 || lo !== 0;\n } else {\n // s = 21: the implicit-1 bit becomes the round bit; truncated result is 0\n f16mant = 0;\n roundBit = 1; // implicit 1 is always present\n sticky = mantHi !== 0 || lo !== 0;\n }\n } else {\n // ── Normal ─────────────────────────────────────────────────────────────────\n // Take the top 10 bits of the 52-bit mantissa; round using the next bits.\n f16mant = mantHi >> 10;\n roundBit = (mantHi >> 9) & 1;\n sticky = (mantHi & 0x1ff) !== 0 || lo !== 0;\n }\n\n // ── Round-to-nearest-ties-to-even (RN-TE) ───────────────────────────────────\n if (roundBit !== 0 && (sticky || (f16mant & 1) !== 0)) {\n f16mant++;\n }\n\n // ── Mantissa overflow: carry into exponent ───────────────────────────────────\n if (f16mant >= 1024) {\n // Denormal rounds up to the smallest normal (exp = 1), or normal exponent increments\n const newExp = f16Exp <= 0 ? 1 : f16Exp + 1;\n if (newExp >= 31) return (sign << 15) | 0x7c00; // overflow to Infinity\n return (sign << 15) | (newExp << 10); // mant = 0\n }\n\n const outExp = f16Exp <= 0 ? 0 : f16Exp;\n return (sign << 15) | (outExp << 10) | f16mant;\n}\n\n/**\n * float16 bit pattern → float64.\n * Exported for testing purposes.\n */\nexport function float16BitsToFloat64(bits: number): number {\n const sign = (bits >>> 15) & 1;\n const exp = (bits >>> 10) & 0x1f;\n const mant = bits & 0x3ff;\n\n if (exp === 0x1f) {\n return mant === 0 ? (sign ? -Infinity : Infinity) : NaN;\n }\n if (exp === 0) {\n if (mant === 0) return sign ? -0 : 0;\n // Denormal: (-1)^sign × 2^(-14) × (mant / 1024)\n return (sign ? -1 : 1) * 2 ** -14 * (mant / 1024);\n }\n // Normal: (-1)^sign × 2^(exp-15) × (1 + mant/1024)\n return (sign ? -1 : 1) * 2 ** (exp - 15) * (1 + mant / 1024);\n}\n\n/**\n * Write a float16 value at the given offset in a DataView.\n */\ntype WriteFloat16 = (\n view: DataView,\n offset: number,\n value: number,\n littleEndian: boolean\n) => void;\n\n/**\n * Read a float16 value from the given offset in a DataView, returned as float64.\n */\ntype ReadFloat16 = (\n view: DataView,\n offset: number,\n littleEndian: boolean\n) => number;\n\nconst writeFloat16Native: WriteFloat16 = (\n view,\n offset,\n value,\n littleEndian\n) => {\n view.setFloat16(offset, value, littleEndian);\n};\n\nconst writeFloat16Fallback: WriteFloat16 = (\n view,\n offset,\n value,\n littleEndian\n) => {\n view.setUint16(offset, float64ToFloat16Bits(value), littleEndian);\n};\n\nconst readFloat16Native: ReadFloat16 = (view, offset, littleEndian) => {\n return view.getFloat16(offset, littleEndian);\n};\n\nconst readFloat16Fallback: ReadFloat16 = (view, offset, littleEndian) => {\n return float16BitsToFloat64(view.getUint16(offset, littleEndian));\n};\n\n// Dispatch between native and fallback once at module initialization time.\nexport const writeFloat16: WriteFloat16 = hasNativeFloat16\n ? writeFloat16Native\n : writeFloat16Fallback;\n\nexport const readFloat16: ReadFloat16 = hasNativeFloat16\n ? readFloat16Native\n : readFloat16Fallback;\n","import {\n float64ToFloat16Bits,\n float16BitsToFloat64,\n writeFloat16 as writeFloat16ToView,\n} from '../utils/float16';\nimport type { FloatPrecision } from '../ast/CborFloat';\nimport { AI_1BYTE, AI_2BYTE, AI_4BYTE, AI_8BYTE } from './constants';\n\n// ─── Encoding width ───────────────────────────────────────────────────────────\n\n/**\n * EDN encoding indicator, mapping to a specific CBOR AI encoding:\n * 'i' → ai 0–23 (argument in initial byte, value must be 0–23)\n * 0 → AI 24 (1-byte argument, value must be 0–0xFF)\n * 1 → AI 25 (2-byte argument, value must be 0–0xFFFF)\n * 2 → AI 26 (4-byte argument, value must be 0–0xFFFFFFFF)\n * 3 → AI 27 (8-byte argument, value must be 0–0xFFFFFFFFFFFFFFFF)\n */\nexport type EncodingWidth = 'i' | 0 | 1 | 2 | 3;\n\n// ─── Output writer ────────────────────────────────────────────────────────────\n\n/** Scratch space for float conversions (single-threaded use only). */\nconst SCRATCH = new DataView(new ArrayBuffer(8));\nconst SCRATCH_BYTES = new Uint8Array(SCRATCH.buffer);\n\n/** Shared encoder — constructing TextEncoder per string is needlessly slow. */\nconst textEncoder = new TextEncoder();\nconst hasEncodeInto = typeof textEncoder.encodeInto === 'function';\n\n/** CBOR head size in bytes for an auto-width argument `n`. */\nfunction headSizeFor(n: number): number {\n if (n <= 23) return 1;\n if (n <= 0xff) return 2;\n if (n <= 0xffff) return 3;\n if (n <= 0xffff_ffff) return 5;\n return 9;\n}\n\n/** CBOR head size in bytes for an explicit encoding width. */\nfunction headSizeForWidth(ew: EncodingWidth): number {\n return ew === 'i' ? 1 : [2, 3, 5, 9][ew];\n}\n\n/**\n * Growable byte buffer used by the CBOR encoder.\n *\n * AST nodes write themselves into a single shared writer via `_encodeTo`,\n * so an encode pass performs one buffer copy at the end instead of\n * re-copying every child's bytes at each nesting level.\n *\n * @internal\n */\nexport class CborWriter {\n private buf: Uint8Array;\n private len = 0;\n\n constructor(initialCapacity = 256) {\n this.buf = new Uint8Array(initialCapacity);\n }\n\n private _ensure(extra: number): void {\n const needed = this.len + extra;\n if (needed <= this.buf.length) return;\n let capacity = this.buf.length * 2;\n while (capacity < needed) capacity *= 2;\n const grown = new Uint8Array(capacity);\n grown.set(this.buf);\n this.buf = grown;\n }\n\n writeByte(b: number): void {\n this._ensure(1);\n this.buf[this.len++] = b;\n }\n\n writeBytes(bytes: Uint8Array): void {\n this._ensure(bytes.length);\n this.buf.set(bytes, this.len);\n this.len += bytes.length;\n }\n\n writeUint16(value: number): void {\n this._ensure(2);\n const b = this.buf;\n b[this.len++] = (value >>> 8) & 0xff;\n b[this.len++] = value & 0xff;\n }\n\n writeUint32(value: number): void {\n this._ensure(4);\n const b = this.buf;\n b[this.len++] = (value >>> 24) & 0xff;\n b[this.len++] = (value >>> 16) & 0xff;\n b[this.len++] = (value >>> 8) & 0xff;\n b[this.len++] = value & 0xff;\n }\n\n writeBigUint64(value: bigint): void {\n SCRATCH.setBigUint64(0, value, false);\n this._ensure(8);\n this.buf.set(SCRATCH_BYTES, this.len);\n this.len += 8;\n }\n\n writeFloat16(value: number): void {\n writeFloat16ToView(SCRATCH, 0, value, false);\n this._ensure(2);\n const b = this.buf;\n b[this.len++] = SCRATCH_BYTES[0];\n b[this.len++] = SCRATCH_BYTES[1];\n }\n\n writeFloat32(value: number): void {\n SCRATCH.setFloat32(0, value, false);\n this._ensure(4);\n const b = this.buf;\n b[this.len++] = SCRATCH_BYTES[0];\n b[this.len++] = SCRATCH_BYTES[1];\n b[this.len++] = SCRATCH_BYTES[2];\n b[this.len++] = SCRATCH_BYTES[3];\n }\n\n writeFloat64(value: number): void {\n SCRATCH.setFloat64(0, value, false);\n this._ensure(8);\n this.buf.set(SCRATCH_BYTES, this.len);\n this.len += 8;\n }\n\n /**\n * Write a definite-length string head + UTF-8 body in one pass.\n *\n * The body is encoded directly into this writer's buffer with\n * TextEncoder.encodeInto(), avoiding the temporary Uint8Array that\n * TextEncoder.encode() allocates for every string. The head position is\n * predicted from the UTF-16 length (a lower bound on the UTF-8 length);\n * when multi-byte characters push the byte count across a head-width\n * boundary the body is shifted up with copyWithin (rare in practice).\n */\n writeTextString(\n mt: number,\n value: string,\n encodingWidth?: EncodingWidth\n ): void {\n if (!hasEncodeInto) {\n // Environments without encodeInto: one temporary array, as before.\n const encoded = textEncoder.encode(value);\n writeHeadTo(this, mt, encoded.length, encodingWidth);\n this.writeBytes(encoded);\n return;\n }\n const predictedHead =\n encodingWidth === undefined\n ? headSizeFor(value.length)\n : headSizeForWidth(encodingWidth);\n // Worst case: 3 UTF-8 bytes per UTF-16 code unit, plus the largest head.\n this._ensure(9 + 3 * value.length);\n const { written } = textEncoder.encodeInto(\n value,\n this.buf.subarray(this.len + predictedHead)\n );\n // The UTF-8 length is never smaller than the UTF-16 length, so the head\n // can only grow; the _ensure above already covers the largest head.\n const head =\n encodingWidth === undefined ? headSizeFor(written) : predictedHead;\n if (head !== predictedHead) {\n this.buf.copyWithin(\n this.len + head,\n this.len + predictedHead,\n this.len + predictedHead + written\n );\n }\n // For an explicit encodingWidth too small for `written` this throws\n // RangeError before writing anything; this.len is untouched in that case.\n writeHeadTo(this, mt, written, encodingWidth);\n this.len += written;\n }\n\n /** Copy of the bytes written so far. */\n finish(): Uint8Array {\n return this.buf.slice(0, this.len);\n }\n}\n\n// ─── Header encoding ──────────────────────────────────────────────────────────\n\nconst MAX_FOR_WIDTH = [\n 0xffn,\n 0xffffn,\n 0xffff_ffffn,\n 0xffff_ffff_ffff_ffffn,\n] as const;\n\n/** Maximum CBOR argument value representable with the given encoding width. */\nexport function maxForEncodingWidth(ew: EncodingWidth): bigint {\n return ew === 'i' ? 23n : MAX_FOR_WIDTH[ew];\n}\n\n/**\n * Write a CBOR initial byte + argument into `w`.\n *\n * When `encodingWidth` is provided the argument is always written using that\n * many additional bytes (AI = 24 + encodingWidth), even if the value would fit\n * in fewer bytes. Without it the smallest valid encoding is chosen.\n *\n * `value` may be a number (common for lengths and counts — avoids a BigInt\n * allocation per head) or a bigint (required for full uint64 range).\n */\nexport function writeHeadTo(\n w: CborWriter,\n mt: number,\n value: number | bigint,\n encodingWidth?: EncodingWidth\n): void {\n // Fast path: auto-width number argument below 2^32\n if (\n encodingWidth === undefined &&\n typeof value === 'number' &&\n value < 0x1_0000_0000\n ) {\n if (value <= 23) {\n w.writeByte((mt << 5) | value);\n } else if (value <= 0xff) {\n w.writeByte((mt << 5) | AI_1BYTE);\n w.writeByte(value);\n } else if (value <= 0xffff) {\n w.writeByte((mt << 5) | AI_2BYTE);\n w.writeUint16(value);\n } else {\n w.writeByte((mt << 5) | AI_4BYTE);\n w.writeUint32(value);\n }\n return;\n }\n\n const v = typeof value === 'number' ? BigInt(value) : value;\n if (encodingWidth !== undefined) {\n // Immediate encoding: value must fit in the lower 5 bits of the initial byte\n if (encodingWidth === 'i') {\n if (v > 23n)\n throw new RangeError(\n `value ${v} does not fit in immediate encoding _i (max 23)`\n );\n w.writeByte((mt << 5) | Number(v));\n return;\n }\n if (v > MAX_FOR_WIDTH[encodingWidth]) {\n throw new RangeError(\n `value ${v} does not fit in encodingWidth _${encodingWidth} (max ${MAX_FOR_WIDTH[encodingWidth]})`\n );\n }\n const ai = AI_1BYTE + encodingWidth; // 24, 25, 26, or 27\n w.writeByte((mt << 5) | ai);\n if (ai === AI_1BYTE) w.writeByte(Number(v));\n else if (ai === AI_2BYTE) w.writeUint16(Number(v));\n else if (ai === AI_4BYTE) w.writeUint32(Number(v));\n else w.writeBigUint64(v);\n return;\n }\n if (v <= 23n) {\n w.writeByte((mt << 5) | Number(v));\n } else if (v <= 0xffn) {\n w.writeByte((mt << 5) | AI_1BYTE);\n w.writeByte(Number(v));\n } else if (v <= 0xffffn) {\n w.writeByte((mt << 5) | AI_2BYTE);\n w.writeUint16(Number(v));\n } else if (v <= 0xffff_ffffn) {\n w.writeByte((mt << 5) | AI_4BYTE);\n w.writeUint32(Number(v));\n } else {\n w.writeByte((mt << 5) | AI_8BYTE);\n w.writeBigUint64(v);\n }\n}\n\n/**\n * Encode a CBOR initial byte + argument into a Uint8Array.\n * Convenience wrapper around {@link writeHeadTo} for callers that need the\n * bytes directly (e.g. hex dumps).\n */\nexport function writeHead(\n mt: number,\n value: number | bigint,\n encodingWidth?: EncodingWidth\n): Uint8Array {\n const w = new CborWriter(9);\n writeHeadTo(w, mt, value, encodingWidth);\n return w.finish();\n}\n\n// ─── Float precision helpers ──────────────────────────────────────────────────\n\nconst _f32buf = new DataView(new ArrayBuffer(4));\n\n/**\n * Returns true if `value` can be exactly represented as a float16 without\n * precision loss (including -0, Infinity, -Infinity, NaN identity).\n */\nexport function canEncodeAsFloat16(value: number): boolean {\n return Object.is(float16BitsToFloat64(float64ToFloat16Bits(value)), value);\n}\n\n/**\n * Returns true if `value` can be exactly represented as a float32 without\n * precision loss.\n */\nexport function canEncodeAsFloat32(value: number): boolean {\n _f32buf.setFloat32(0, value, false);\n return Object.is(_f32buf.getFloat32(0, false), value);\n}\n\n/**\n * Choose the smallest float precision that represents `value` exactly.\n * Used by CborFloat.toCBOR() when `precision` is undefined.\n */\nexport function autoSelectFloatPrecision(value: number): FloatPrecision {\n if (canEncodeAsFloat16(value)) return 'half';\n if (canEncodeAsFloat32(value)) return 'single';\n return 'double';\n}\n","import type {\n CBOROptions,\n ToCDNOptions,\n ToJSOptions,\n ToHexDumpOptions,\n ToCBOROptions,\n CborComment,\n CborComments,\n DecodeWarning,\n ParseWarning,\n ItemContext,\n ReadonlyToJSNodeOptions,\n CdnItemContext,\n ReadonlyToCDNOptions,\n} from '../types';\nimport { CBOR_OMIT } from '../types';\nimport {\n convertCommentText,\n resolveIndent,\n splitLeadingComments,\n shouldEmitComments,\n resolveCommentStyle,\n} from '../cdn/serialize-utils';\nimport { CborWriter } from '../cbor/encode';\nimport { bytesToSpacedHexUpper } from '../utils/hex';\n\n/** @internal One line of an annotated hex dump. */\nexport interface AnnotatedLine {\n depth: number;\n hex: string;\n comment: string;\n}\n\nexport interface AppSeqEncodingEdit {\n /** Start/end offsets within appSeqSource of an existing indicator. */\n start: number;\n end: number;\n /** Replacement used by encodingIndicators: 'always'. */\n always: string;\n /** Replacement used by encodingIndicators: 'never'. */\n never: string;\n}\n\n/**\n * Original literal features used by the sole item inside a preserved\n * `prefix<<item>>` source. They let serialization honour an explicitly\n * disabled sibling `preserve*` option instead of replaying that literal\n * verbatim through `preserveAppPrefix`.\n */\nexport interface AppSeqSourceFeatures {\n byteString?: boolean;\n textString?: boolean;\n rawString?: boolean;\n concatenation?: boolean;\n}\n\n/**\n * Fill in every `preserve*` option left `undefined` with `true`, for\n * `ToCDNOptions.preserveAll` — except the deprecated `preserveTextString`,\n * which no longer participates in `preserveAll`. An option the caller\n * explicitly set (including to `false`) is left untouched.\n *\n * `preserveComments` is only filled in with `true` (verbatim) when\n * `comments` is *also* left unset — an explicit `comments` with no\n * `preserveComments` should still normalize comments to that style under\n * `preserveAll`, not be overridden by the verbatim fill-in (see\n * `ToCDNOptions.preserveComments`).\n *\n * Assumes `preserveAppPrefix` has already been resolved from the\n * deprecated `preserveAppSequence` alias by the caller (see `toCDN()`); like\n * `preserveTextString`, the deprecated name itself no longer participates\n * directly. (`appStrings`/`appPrefix` aren't part of the `preserve*` family\n * and don't participate in `preserveAll` at all.)\n */\nfunction expandPreserveAll(options: ToCDNOptions): ToCDNOptions {\n return {\n ...options,\n preserveComments:\n options.comments !== undefined\n ? options.preserveComments\n : (options.preserveComments ?? true),\n preserveByteString: options.preserveByteString ?? true,\n preserveRawString: options.preserveRawString ?? true,\n preserveConcatenation: options.preserveConcatenation ?? true,\n preserveNumberFormat: options.preserveNumberFormat ?? true,\n preserveAppPrefix: options.preserveAppPrefix ?? true,\n preserveBlankLines: options.preserveBlankLines ?? true,\n };\n}\n\n/**\n * Resolve deprecated `ToCDNOptions` aliases — `preserveAppSequence` into\n * `preserveAppPrefix`, and `appStrings` into `appPrefix` — for whichever\n * canonical name was left unset by the caller. Each canonical name always\n * wins over its deprecated alias when both are explicitly set.\n */\nfunction resolveDeprecatedAppPrefixAliases(\n options: ToCDNOptions\n): ToCDNOptions {\n if (\n options.preserveAppSequence === undefined &&\n options.appStrings === undefined\n )\n return options;\n return {\n ...options,\n preserveAppPrefix: options.preserveAppPrefix ?? options.preserveAppSequence,\n appPrefix: options.appPrefix ?? options.appStrings,\n };\n}\n\n/**\n * Resolve deprecated `ToCDNOptions` aliases within an `itemOptions` override\n * *in isolation*, before it is merged onto the ambient effective options.\n *\n * `resolveDeprecatedAppPrefixAliases` only fills in a canonical name when\n * that name is itself left `undefined` on the object it's given. An override\n * like `{ appStrings: false }` must be resolved against *itself* — where\n * `appPrefix` is absent — not against the already-merged effective options,\n * where an ancestor's resolved `appPrefix: true` would already occupy\n * that slot and win, silently discarding the child's own alias-based\n * override (this is `_resolveCdnOptions`'s exact bug this guards against).\n *\n * Because `resolveDeprecatedAppPrefixAliases` unconditionally assigns\n * `preserveAppPrefix`/`appPrefix` (via `??`) whenever either deprecated name\n * is set, resolving against the override alone can introduce a literal\n * `undefined` for a canonical key the override never mentioned (e.g.\n * `preserveAppPrefix: undefined` from an override that only ever touched\n * `appStrings`). Copying that back verbatim would overwrite an inherited\n * value with `undefined` instead of leaving it untouched, so only a\n * genuinely resolved (non-`undefined`) key is copied into the result.\n */\nfunction normalizeCdnOverride(\n override: Partial<ToCDNOptions>\n): Partial<ToCDNOptions> {\n if (\n override.preserveAppSequence === undefined &&\n override.appStrings === undefined\n )\n return override;\n const resolved = resolveDeprecatedAppPrefixAliases(override as ToCDNOptions);\n const result: Partial<ToCDNOptions> = { ...override };\n if (resolved.preserveAppPrefix !== undefined)\n result.preserveAppPrefix = resolved.preserveAppPrefix;\n if (resolved.appPrefix !== undefined) result.appPrefix = resolved.appPrefix;\n return result;\n}\n\n/**\n * @internal\n * Shared, frozen empty path passed as the default `path` argument to\n * `_toJS()`/`_toJSChild()` so that not using `itemOptions` never allocates a\n * path array.\n */\nconst EMPTY_PATH: readonly unknown[] = Object.freeze([]);\n\n/**\n * @internal\n * Cheap upfront check for whether per-node option/extension resolution is\n * needed at all for a given `toJS()` options object. Container nodes use\n * this to choose between the plain `child._toJS(options)` recursion (when\n * `false`, identical cost to before `itemOptions`/`extensions` existed) and\n * `child._toJSChild(options, path, ctx)` (when `true`).\n */\nexport function needsItemDispatch(options: ToJSOptions | undefined): boolean {\n return !!(options?.itemOptions || options?.extensions?.length);\n}\n\n/**\n * @internal\n * Options for a reviver-driven container's \"raw\" structural pre-population\n * pass (see `CborArray`/`CborMap.toObject`) — `reviver` removed, everything\n * else (including `itemOptions`/`extensions`) left as-is.\n *\n * This pass's output is never returned to the caller as the final result —\n * every position it computes is unconditionally overwritten by the *real*\n * (revived) pass's own result before `toJS()` returns — but it is not\n * write-only scaffolding either: a `reviver` reads it directly, as `this[j]`\n * for a not-yet-processed sibling `j`, while deciding how to revive an\n * *earlier* sibling (matching `JSON.parse`'s own reviver contract, which\n * this replicates). That value must reflect `itemOptions`/`extensions`\n * exactly as the real pass would — e.g. an `integerAs: 'bigint'` override\n * for position `j` — or a reviver reading `this[j]` would see the wrong\n * type. So `itemOptions`/`extensions` stay active here, unlike `reviver`\n * itself.\n *\n * Running dispatch during this pass is safe only because callers building\n * a child's occurrence for it — `CborArray`/`CborMap.toObject` — insert\n * `RAW_PASS_MARKER` into that occurrence (see `Occurrence`), so its\n * resolutions are filed under a different `DispatchCache` key than the\n * real pass's and can never be reused *by* the real pass, however many\n * ancestor levels apart the two passes are. That distinction matters for\n * more than consistency — a composite (non-scalar) map key is itself\n * revived differently between the two passes (this pass leaves its own\n * nested content entirely unrevived, matching `this[j]`'s contract above;\n * the real pass revives it normally), so a value node whose\n * `ItemContext.path` is built from that key's converted JS value would\n * otherwise see a stale, pre-revival path if the real pass reused this\n * pass's cached decision.\n */\nexport function withoutReviver(\n options: ToJSOptions | undefined\n): ToJSOptions | undefined {\n if (!options) return options;\n return { ...options, reviver: undefined };\n}\n\n/**\n * @internal\n * Build the `reviver`-free, `extensions`-copied view of `options` handed\n * to code that must not be able to mutate options actually in effect\n * elsewhere in the tree — `ItemContext.options` and the `options`\n * parameter of `CborExtension.toJS()` — see `ReadonlyToJSNodeOptions`.\n *\n * A plain `{ ...options, reviver: undefined }` spread (as `withoutReviver`\n * does) is not enough here: `extensions`, if present, would still be the\n * *same array* `options.extensions` is, so `.push()`/`.splice()`/etc. on\n * the copy would still mutate the original in place — corrupting it for\n * this node's own later use, its siblings, and the caller. `extensions` is\n * the only field on `ToJSOptions` that's an ordinary mutable container, so\n * it's the only one that needs its own copy here.\n */\nexport function toReadonlyNodeOptions(\n options: ToJSOptions\n): ReadonlyToJSNodeOptions {\n const { reviver: _reviver, extensions, ...rest } = options;\n return extensions ? { ...rest, extensions: [...extensions] } : rest;\n}\n\n/**\n * @internal\n * Symbol-keyed slot, stashed on the top-level `toJS()` options object,\n * holding the per-call dispatch cache (see `DispatchCache` below). Reading\n * and writing through this indirection (rather than a typed field on\n * `ToJSOptions`) keeps the cache out of the public option surface while\n * still surviving every `{ ...options, ...override }` copy made while\n * resolving `itemOptions` overrides — object spread carries own-enumerable\n * symbol-keyed properties along with string-keyed ones — so the *same*\n * cache reaches every node touched by one `toJS()` call, however deep.\n */\nconst kDispatchCache = Symbol('cbor.itemOptions.dispatchCache');\n\n/**\n * @internal\n * A node's resolved `itemOptions`/`extensions` outcome at one occurrence,\n * cached across the duplicate visits that occurrence can receive within\n * one `toJS()` call (see `DispatchCache`).\n *\n * - `'value'`: an extension's `toJS()` hook matched and fully resolved this\n * occurrence — reused verbatim on a later visit to the same occurrence,\n * since the hook never even sees `reviver` itself (see `_toJSChild`'s\n * stripped `hookOptions`) and so cannot have produced a result that\n * depends on it; only the container holding the *returned* value still\n * applies reviver to it, once per visit, as usual.\n * - `'override'`: `options.itemOptions()` ran (and no extension matched);\n * `override` is its raw return value, applied at use time as\n * `{ ...options, ...override }` rather than stored pre-merged.\n */\ntype DispatchOutcome =\n | { kind: 'value'; value: unknown }\n | { kind: 'override'; override: Partial<ToJSOptions> | undefined };\n\n/**\n * @internal\n * Stable, allocation-light identifier for \"this occurrence of a node\" —\n * used only to key `DispatchCache` lookups, never exposed via\n * `ItemContext`. Built exactly the way `ItemContext.path` is (accumulated\n * from the root, one element per container level, unchanged through a\n * tag/app-sequence wrapper), but from *structural* container positions —\n * an array index, or a map entry's ordinal paired with a `'k'`/`'v'` role\n * tag (see `CborArray`/`CborMap`) — rather than from the JS values `path`\n * is built from.\n *\n * That distinction matters in two ways `path` alone (or even `path` plus\n * only the *immediate* container's identity) does not cover:\n *\n * - A composite (non-scalar) map key re-converts to a *new* array/object\n * every time its JS value is asked for, so two visits to the very same\n * logical position produce `path`s that are structurally equal but not\n * reference-equal at that segment — unusable for matching.\n * - Two different positions can legitimately produce the very same `path`,\n * when duplicate map entries carry equal keys (e.g. two `\"a\"` entries).\n * - A *container* (not just a leaf) can itself be a shared node instance\n * reused at two positions (e.g. the same `CborArray` placed at two\n * different indices of an outer array). Matching only on `{immediate\n * parent identity, local slot}` — as an earlier version of this type\n * did — correctly distinguishes the *container's own* two occurrences,\n * but not its *descendants'*: each of the shared container's children\n * would resolve `{parent: <the shared container>, slot: <local index>}`\n * identically regardless of which of the container's own two\n * occurrences was being converted, silently conflating them. Chaining\n * the full occurrence from the root — rather than just one level —\n * avoids this: the shared container's own two occurrences differ\n * earlier in the chain, so appending the same local slot to each still\n * yields two different full chains for its children.\n *\n * A local slot only needs to be unique among its own container's direct\n * children — `CborArray` uses the element index (`number`) directly;\n * `CborMap` prefixes a map entry's ordinal with `'k'`/`'v'`\n * (`` `k${i}` ``/`` `v${i}` ``) so a key and its own value, which share an\n * ordinal, don't collide.\n *\n * `RAW_PASS_MARKER` (see below) is the one non-structural element this\n * chain can contain: `CborArray`/`CborMap.toObject` insert it — once,\n * immediately before that level's own local slot — only when building a\n * child's occurrence for their raw structural pre-population pass (see\n * `withoutReviver`), never for the real, revived pass. That's what lets\n * `_toJSChild`'s cache correctly tell apart the *distinct* raw-pass\n * resolutions a single occurrence can otherwise receive when more than one\n * ancestor level forks — e.g. the very same value node visited once\n * through an outer container's own raw pass (before *any* ancestor has\n * revived anything) and once more through a different, inner container's\n * own raw pass nested inside the outer's real pass (after some ancestor,\n * such as a composite map key, *has* already been revived) — two visits\n * that share every structural coordinate yet must not share a cached\n * decision, since what a reviver-sensitive value like that key converts to\n * differs between them (see `DispatchCacheEntry`). A container that isn't\n * itself forking (no `reviver` in its own options, so it takes the plain,\n * unsplit path) never inserts the marker — it simply passes the\n * occurrence chain it was given through unchanged before extending it with\n * its own children's local slots, the same way it always did.\n */\nexport type Occurrence = readonly unknown[];\n\n/**\n * @internal\n * Sentinel inserted into an `Occurrence` chain by `CborArray`/\n * `CborMap.toObject` when building a child's occurrence for their own raw\n * structural pre-population pass — see `Occurrence`'s own note. A\n * dedicated symbol rather than a string/number so it can never collide\n * with an ordinary local slot value (an array index or a `` `k${i}` ``/\n * `` `v${i}` `` map-entry tag).\n */\nexport const RAW_PASS_MARKER: unique symbol = Symbol(\n 'cbor.itemOptions.rawPass'\n);\n\n/**\n * @internal\n * The root value's occurrence, for `toJS()`'s own top-level `_toJSChild()`\n * call — empty, the same way `ItemContext.path` is empty at the root. Also\n * used by `CborTag`/`CborAppSeqResult` as a defensive fallback if `_toJS()`\n * is ever invoked without an `occurrence` (only possible via a direct,\n * non-`toJS()` call to `_toJS()`, which the dispatch cache never sees).\n */\nexport const ROOT_OCCURRENCE: Occurrence = Object.freeze([]);\n\n/**\n * @internal\n * One resolved occurrence of a node, cached under that node in\n * `DispatchCache`. `occurrence` identifies *which* occurrence this is — a\n * single `CborItem` instance can legitimately appear at more than one\n * occurrence in a hand-built tree (e.g. the same shared node reused at two\n * array indices, or as the value of two entries sharing a duplicate map\n * key — or, transitively, as a descendant of such a shared node), and a\n * reviver-driven container's raw structural pre-population pass (see\n * `withoutReviver`) produces yet more distinct occurrences of its own for\n * the very same node, via `RAW_PASS_MARKER` — see `Occurrence`. A later\n * visit only reuses `outcome` once `occurrence` matches elementwise —\n * seeing this node again at a *different* occurrence (a distinct\n * `DispatchCacheEntry` in the same node's list, see `DispatchCache`)\n * resolves fresh instead, exactly as if no caching were happening for that\n * occurrence yet.\n *\n * The raw pass's own resolutions are never reused by the real, revived\n * pass (or vice versa) purely because their occurrences differ by\n * `RAW_PASS_MARKER` — not because of any separate bookkeeping — so\n * `itemOptions`/an extension's `toJS()` hook can run more than once for\n * what looks like \"the same node\" from the outside: once for each\n * distinct raw pass it's reachable through (there can be more than one,\n * nested — see `Occurrence`), plus once more for the real pass. That is\n * the accepted cost of a raw pass's placeholder value being observable\n * (`this[j]` for a not-yet-processed sibling `j`, inside an *earlier*\n * sibling's own reviver call) and therefore needing to reflect\n * `itemOptions`/`extensions` accurately rather than being computed as if\n * neither were configured.\n */\ninterface DispatchCacheEntry {\n occurrence: Occurrence;\n outcome: DispatchOutcome;\n}\n\n/**\n * @internal\n * One `toJS()` call's dispatch cache, keyed by node identity, each node\n * mapped to the list of occurrences resolved for it so far (almost always\n * exactly one — see `DispatchCacheEntry`). Exists because `CborArray`/\n * `CborMap` (with a `reviver`) and any nesting through `CborTag`/\n * `CborAppSeqResult` wrappers each visit the *same* occurrence more than\n * once — see `DispatchOutcome` — and `itemOptions`/an extension's `toJS()`\n * hook must still each run exactly once per occurrence, since either may be\n * stateful or otherwise have observable side effects.\n */\ntype DispatchCache = WeakMap<CborItem, DispatchCacheEntry[]>;\n\nfunction getDispatchCache(\n options: ToJSOptions | undefined\n): DispatchCache | undefined {\n return (options as Record<symbol, unknown> | undefined)?.[kDispatchCache] as\n DispatchCache | undefined;\n}\n\n/**\n * @internal\n * Attach a fresh dispatch cache to a top-level `toJS()` call's merged\n * options. Called once per `toJS()` invocation (never by internal\n * recursion), so unrelated calls never share a cache.\n */\nfunction withDispatchCache(options: ToJSOptions): ToJSOptions {\n const cache: DispatchCache = new WeakMap();\n return Object.assign({}, options, { [kDispatchCache]: cache });\n}\n\nfunction sameOccurrence(a: Occurrence, b: Occurrence): boolean {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;\n return true;\n}\n\n/**\n * @internal\n * Find the cached entry (if any) for the exact occurrence among a node's\n * previously-resolved occurrences.\n */\nfunction findOccurrence(\n entries: DispatchCacheEntry[] | undefined,\n occurrence: Occurrence\n): DispatchCacheEntry | undefined {\n return entries?.find((e) => sameOccurrence(e.occurrence, occurrence));\n}\n\n/**\n * @internal\n * Record a newly-resolved occurrence, appending to (rather than replacing)\n * whatever occurrences of this node were already recorded — see\n * `DispatchCacheEntry`.\n */\nfunction recordOccurrence(\n cache: DispatchCache,\n node: CborItem,\n entry: DispatchCacheEntry\n): void {\n const existing = cache.get(node);\n if (existing) existing.push(entry);\n else cache.set(node, [entry]);\n}\n\n// ─── toCDN() per-item dispatch ──────────────────────────────────────────────\n//\n// Much simpler than toJS()'s: there is no reviver, so no scenario ever\n// needs a node's itemOptions decision to be tied to *which* of two\n// differently-revived contexts produced it — the one thing DispatchCache's\n// whole occurrence/RAW_PASS_MARKER design exists for. toCDN() already has\n// its own, unrelated reason a node can be rendered more than once per\n// parent render (see `CdnItemContext`'s own doc), and the existing code's\n// own answer to that (see `serializeContainer` in cdn/serialize-utils.ts)\n// is to accept it rather than cache around it — a real, resolved\n// instance-level cache having already turned out unsafe there (see\n// `CborTag._isMultiWordText`). So `itemOptions` here just resolves fresh\n// on every call, with no cache at all.\n\n/**\n * @internal\n * Cheap upfront check for whether per-node option resolution is needed at\n * all for a given `toCDN()` options object — the `toCDN()` analogue of\n * `needsItemDispatch`.\n */\nexport function needsCdnItemDispatch(\n options: ToCDNOptions | undefined\n): boolean {\n return !!options?.itemOptions;\n}\n\n/**\n * @internal\n * Build the copied-`textStringFormat` view of `options` handed to\n * `CdnItemContext.options` — the `toCDN()` analogue of\n * `toReadonlyNodeOptions`; see `ReadonlyToCDNOptions`. Also strips\n * `CDN_OVERRIDE_TRACKER` (see there) — `ctx.options` is documented as\n * reflecting the current *effective options*, so it should never expose an\n * internal, out-of-band bookkeeping key that isn't part of `ToCDNOptions` at\n * all, even though it isn't otherwise observable through any named field.\n */\nexport function toReadonlyCdnOptions(\n options: ToCDNOptions\n): ReadonlyToCDNOptions {\n const { textStringFormat, ...rest } = options as ToCDNOptions & {\n [CDN_OVERRIDE_TRACKER]?: CdnOverrideTrackerBox;\n };\n delete rest[CDN_OVERRIDE_TRACKER];\n return textStringFormat\n ? { ...rest, textStringFormat: [...textStringFormat] }\n : rest;\n}\n\n/**\n * @internal\n * Out-of-band symbol key that lets a caller (currently only\n * `CborAppSeqResult._toCDN`) track, across an entire `_resolveCdnOptions()`\n * subtree, whether `itemOptions` ever actually returned an override —\n * without touching `options.itemOptions` itself.\n *\n * `CborAppSeqResult` needs to know whether its preserved verbatim source is\n * still exactly right after offering `itemOptions` a chance to override one\n * of its descendants (see its own doc). Wrapping `options.itemOptions` in a\n * tracking function was tried first, but that function becomes\n * `ctx.options.itemOptions` for every descendant (`_resolveCdnOptions`\n * builds `ctx.options` from the very `options` it was given) — a pure\n * `itemOptions` callback could tell it apart from the caller's own function\n * by identity, observing a difference between an ordinary subtree and one\n * reached through an app-sequence wrapper that `ctx.options`'s \"current\n * effective options\" contract never promises.\n *\n * A symbol-keyed property on `options` instead survives every\n * `{...options, ...override}` merge `_resolveCdnOptions` performs exactly\n * the same way `itemOptions` itself does (object spread copies symbol keys\n * too, and by reference — the same tracker box is shared, never cloned, by\n * every node in the subtree), while never being part of the public\n * `ToCDNOptions` shape or observable through any named field — see\n * `toReadonlyCdnOptions`, which explicitly strips it before building\n * `ctx.options`.\n */\nexport const CDN_OVERRIDE_TRACKER: unique symbol = Symbol('cdnOverrideTracker');\n\n/** @internal Mutable box referenced (never copied) via `CDN_OVERRIDE_TRACKER`. */\nexport interface CdnOverrideTrackerBox {\n applied: boolean;\n}\n\n/**\n * Abstract base class for all CBOR AST nodes.\n *\n * Every node can serialize itself to CBOR binary, CDN text, and a\n * plain JavaScript value. Concrete implementations are provided in each\n * subclass (added in later phases).\n */\nexport abstract class CborItem {\n /**\n * Character offset of the first character of this item in the parsed source.\n * Set by parsers; undefined when the node was constructed directly.\n * For CBOR input this is a byte offset.\n */\n start?: number;\n\n /**\n * Character offset just past the last character of this item in the parsed source.\n * Set by parsers; undefined when the node was constructed directly.\n * For CBOR input this is a byte offset.\n */\n end?: number;\n\n /**\n * Comments captured from CDN source when `preserveComments` is enabled.\n * They do not affect CBOR bytes or JS conversion.\n */\n comments?: CborComments;\n\n /**\n * `true` when this node is an array/map entry (or indefinite-length\n * string chunk) immediately preceded by a blank line in the parsed CDN\n * source — set unconditionally by the parser, regardless of any\n * `preserve*` option, mirroring `start`/`end`. Only consulted by\n * `toCDN()` when `ToCDNOptions.preserveBlankLines` is set; otherwise\n * ignored. Left `undefined` for nodes not parsed as a container entry, or\n * with no blank line before them.\n */\n blankLineBefore?: boolean;\n\n /**\n * Original app-string/-sequence source text — `prefix'...'`,\n * `` prefix`...` ``, or `prefix<<...>>` — set by the parser when the\n * resolving extension declares `preserveAppSeqSource: 'optional'`. A\n * subclass's own `_toCDN()` override may check this (gated behind\n * `ToCDNOptions.preserveAppPrefix`) to round-trip the exact original\n * spelling instead of always regenerating `prefix'...'` notation from the\n * resolved value. Left `undefined` for nodes not parsed from one of these\n * forms.\n */\n appSeqSource?: string;\n\n /**\n * Comments contained within `appSeqSource`, with `start`/`end` offsets\n * relative to that string. These spans allow comment markers to be\n * converted (or comments to be removed) without regenerating and thereby\n * losing the original app-string/-sequence notation.\n */\n appSeqComments?: CborComment[];\n\n /**\n * Source edits for encoding indicators contained in a raw-tag\n * `appSeqSource`. Includes zero-width edits where an indicator was absent\n * so `encodingIndicators: 'always'` can insert one without regenerating\n * the surrounding source.\n */\n appSeqEncodingEdits?: AppSeqEncodingEdit[];\n\n /**\n * `false` when `appSeqEncodingEdits` does not cover every encoding\n * indicator nested inside a raw-tag `appSeqSource` — i.e. its content\n * contains a node type `collectContentEncodingEdits` doesn't know how to\n * edit (e.g. a `CborMap`, `CborTag`, or indefinite-length string inside an\n * `ip` array). Left `undefined` (treated as complete) when coverage is\n * exhaustive, which holds for every tag content type `dt` accepts and for\n * most content `ip` accepts. When `false`, `decideTaggedAppSeqRendering`\n * must not choose the `'source'` decision under `encodingIndicators !==\n * 'auto'`, since surgical span edits would silently leave the uncovered\n * node's indicator unchanged; it falls back to `'structural'` instead.\n */\n appSeqEncodingEditsComplete?: boolean;\n\n /**\n * For an `appSeqSource` parsed from `prefix<<item>>` notation: the offset\n * within `appSeqSource`, relative to its own start, where the sole inner\n * item's own consumption ends — i.e. right after its own encoding\n * indicator, if it had one. Lets `adjustAppSeqIndicator` locate and strip\n * that inner indicator exactly, regardless of what (whitespace, a\n * trailing comma, a comment) separates it from the closing `>>`, rather\n * than pattern-matching text near `>>`. `undefined` when `appSeqSource`\n * isn't `<<...>>` notation, or wasn't captured with a single inner item.\n */\n appSeqInnerEnd?: number;\n\n /**\n * Literal-preservation features present in the sole item of a captured\n * `prefix<<item>>` source. Used to resolve explicitly disabled\n * `preserve*` options without treating unrelated options as conflicts.\n */\n appSeqSourceFeatures?: AppSeqSourceFeatures;\n\n /**\n * Validity violations detected while decoding or parsing this node.\n * Populated when `strict: false` is set in `FromCBOROptions` or\n * `FromCDNOptions`.\n */\n warnings?: (DecodeWarning | ParseWarning)[];\n\n /**\n * Default options bound by a {@link CBOR} instance factory method.\n * Per-call options always take precedence.\n * @internal\n */\n _defaults?: CBOROptions;\n\n /**\n * @internal\n * True when this node is, or contains through wrapper nodes (tags,\n * app-sequence results), an array or map. `inlineLeafContainers` never\n * inlines a container whose entries contain another container, even one\n * that renders on a single line. `CborEmbeddedCBOR` (`<<...>>`) is the one\n * exception: it inlines its own entries based purely on whether they\n * render without a line break, regardless of this flag — see its\n * `_toCDN()`, which omits `entryIsLeaf` for that reason.\n */\n get _containsCdnContainer(): boolean {\n return false;\n }\n\n /**\n * @internal\n * True when this node's own text content (a text string, or a byte\n * string that would render as bare sqstr text) has two or more words —\n * `inlineLeafContainers` never collapses a container whose entries hold\n * such a string onto the container's own line, even though the entry\n * itself has no nested array/map, since a multi-word string reads better\n * with room of its own. See `isMultiWordText()`/`isMultiWordByteString()`\n * in `cdn/serialize-utils.ts`. Takes `options` because whether a byte\n * string even renders as text (`'...'`) rather than a prefixed literal\n * (`h'...'`, `b64'...'`, ...) depends on the `sqstr` option.\n *\n * This method deliberately does *not* also cover the \"is this (or does\n * it wrap) a prefixed literal\" question — a prefixed literal has no word\n * count to check, but still disqualifies under the strict rule (and, per\n * `strict`, is an ordinary leaf under the loose one). That's handled\n * generically elsewhere instead, from the *actual rendered text* rather\n * than predicted from this node's type: `isPrefixedLiteralText` for a\n * bare entry (`serializeContainer` checks it against the already\n * rendered `s`), or `isMultiWordRenderedLiteral` for `CborTag`, which\n * overrides this method entirely to tokenize its own `_toCDN()` output\n * instead of delegating here — necessary because a `CborTag` subclass\n * (`CborTaggedIpExt`, `CborTaggedEpochDtExt`, ...) may override `_toCDN()`\n * to render something that doesn't look like generic `tagNum(content)`\n * notation at all, which a semantic prediction from `this.content` alone\n * could never know about.\n *\n * `strict` (default `true`) is passed down by whichever container's own\n * `_toCDN` directly holds this entry: `true` for the strict rule\n * (`CborArray`/`CborMap`, and `CborIndefiniteTextString`/\n * `CborIndefiniteByteString` too — all four provide `entryIsLeaf`),\n * `false` only for `CborEmbeddedCBOR` (`<<...>>`), the one container\n * whose collapse isn't gated behind `inlineLeafContainers` at all and\n * the only one that omits `entryIsLeaf`. This base implementation and\n * `CborTextString`/`CborByteString`'s overrides ignore `strict` (a text\n * string's, or byte string's own sqstr-text, word count is unaffected by\n * it either way) — only `CborTag` (and, transitively, `CborAppSeqResult`\n * delegating to its inner value) actually consult it.\n *\n * `path` is this entry's own full path (see `CdnItemContext.path`),\n * passed down by the same caller for the same reason `renderEntry`\n * receives it: `CborTag`/`CborAppSeqResult` re-render `this` here (see\n * their own overrides) purely to answer this method's question, and that\n * re-render must resolve any of *its own* descendants' `itemOptions`\n * against the entry's real path — not an empty one — or a descendant\n * several levels inside a tag-wrapped entry could see a different\n * `ctx.path` here than the real render further down gives it. Only\n * `CborTag`/`CborAppSeqResult` consult it; every other override ignores\n * it, the same as `strict`.\n */\n _isMultiWordText(\n _options: ToCDNOptions | undefined,\n _strict = true,\n _path?: readonly unknown[]\n ): boolean {\n return false;\n }\n\n // ─── Public template methods ────────────────────────────────────────────────\n\n /** Serialize this node to CBOR binary. */\n toCBOR(options?: ToCBOROptions): Uint8Array {\n const merged = this._defaults ? { ...this._defaults, ...options } : options;\n const writer = new CborWriter();\n this._encode(writer, merged);\n return writer.finish();\n }\n\n /** Serialize this node to a CDN text string. */\n toCDN(options?: ToCDNOptions): string {\n let merged = this._defaults ? { ...this._defaults, ...options } : options;\n if (merged) merged = resolveDeprecatedAppPrefixAliases(merged);\n if (merged?.preserveAll) merged = expandPreserveAll(merged);\n const eff = this._resolveCdnOptions(merged, EMPTY_PATH, {});\n const body = this._toCDN(eff, 0, EMPTY_PATH);\n // Single-line output strips comments: `#`/`//` comments need a newline\n // to terminate, so they cannot be emitted without breaking the guarantee\n // that single-line output contains no newlines.\n if (!shouldEmitComments(eff) || resolveIndent(eff) === null) return body;\n const style = resolveCommentStyle(eff);\n const { ownLines, inlinePrefix } = splitLeadingComments(this, '', style);\n const trailing = this.comments?.trailing ?? [];\n const bodyWithTrailing =\n trailing.length === 0\n ? body\n : `${body} ${trailing.map((c) => convertCommentText(c, style).trimEnd()).join(' ')}`;\n return [...ownLines, `${inlinePrefix}${bodyWithTrailing}`].join('\\n');\n }\n\n /**\n * Serialize this node to a CDN text string.\n *\n * @deprecated Use `toCDN()` instead.\n */\n toEDN(options?: ToCDNOptions): string {\n return this.toCDN(options);\n }\n\n /**\n * Convert this CBOR AST node to a plain JavaScript value.\n *\n * If `options.reviver` is supplied it is called with key `''` on the root\n * result after the full tree has been converted (matching the semantics of\n * `JSON.parse`). Container nodes call the reviver on each of their direct\n * children during conversion, so the walk is bottom-up.\n */\n toJS(options?: ToJSOptions): unknown {\n const merged = this._defaults ? { ...this._defaults, ...options } : options;\n const result = needsItemDispatch(merged)\n ? this._toJSChild(\n withDispatchCache(merged!),\n EMPTY_PATH,\n ROOT_OCCURRENCE,\n {}\n )\n : this._toJS(merged);\n if (!merged?.reviver) return result;\n const rv = merged.reviver.call({ '': result }, '', result);\n return rv === CBOR_OMIT ? undefined : rv;\n }\n\n /**\n * Generate an RFC 8949 §3 style annotated hex dump of this value.\n *\n * @example\n * const cbor = CBOR.fromCDN('[_ 1, [2, 3]]');\n * console.log(cbor.toHexDump());\n * // 9F -- Start indefinite-length array\n * // 01 -- 1\n * // 82 -- Array of length 2\n * // 02 -- 2\n * // 03 -- 3\n * // FF -- \"break\"\n * // FF -- \"break\"\n */\n toHexDump(options?: ToHexDumpOptions): string {\n let merged: (ToHexDumpOptions & ToCDNOptions) | undefined = this._defaults\n ? { ...this._defaults, ...options }\n : options;\n if (merged) merged = resolveDeprecatedAppPrefixAliases(merged);\n const raw = merged?.indent ?? 3;\n const indentStr = typeof raw === 'string' ? raw : ' '.repeat(raw);\n const marker = (merged?.commentStyle ?? '--') + ' ';\n const lines = this._toHexDump(0, merged);\n // A plain loop, not Math.max(...spread): spreading one argument per line\n // overflows the call stack for items with hundreds of thousands of lines.\n let maxPrefixLen = 0;\n for (const l of lines) {\n const prefixLen = l.depth * indentStr.length + l.hex.length;\n if (prefixLen > maxPrefixLen) maxPrefixLen = prefixLen;\n }\n const col = maxPrefixLen + 2;\n return lines\n .map((l) => {\n const prefix = indentStr.repeat(l.depth) + l.hex;\n return prefix.padEnd(col) + marker + l.comment;\n })\n .join('\\n');\n }\n\n // ─── Internal abstract methods ───────────────────────────────────────────────\n\n /**\n * @internal\n * Encode this node into `writer`, honoring `_toCBOR()` overrides.\n *\n * This is the entry point used by `toCBOR()` and by container nodes when\n * recursing into children. A subclass that overrides `_toCBOR()` (e.g. to\n * emit a pre-computed bit pattern) is authoritative even when one of its\n * built-in base classes implements `_encodeTo()`.\n */\n _encode(writer: CborWriter, options?: ToCBOROptions): void {\n if (this._toCBOR !== CborItem.prototype._toCBOR) {\n writer.writeBytes(this._toCBOR(options));\n return;\n }\n this._encodeTo(writer, options);\n }\n\n /**\n * @internal\n * Write this node's CBOR encoding into `writer`.\n *\n * Built-in nodes override this so that an entire encode pass shares one\n * growing buffer (no per-node Uint8Array allocations or re-copies).\n * Container implementations must recurse via `child._encode()`, never\n * `child._encodeTo()`, so that `_toCBOR()` overrides are honored.\n */\n _encodeTo(writer: CborWriter, options?: ToCBOROptions): void {\n if (this._toCBOR === CborItem.prototype._toCBOR)\n throw new TypeError(\n 'CborItem subclass must implement _encodeTo() or _toCBOR()'\n );\n writer.writeBytes(this._toCBOR(options));\n }\n\n /**\n * @internal\n * Subclass CBOR encoding implementation.\n * The default builds the bytes via `_encodeTo()`; subclasses may instead\n * override this method directly when producing a standalone byte array is\n * more natural (e.g. emitting a pre-computed bit pattern).\n */\n _toCBOR(options?: ToCBOROptions): Uint8Array {\n const writer = new CborWriter();\n this._encodeTo(writer, options);\n return writer.finish();\n }\n\n /**\n * @internal\n * Depth-aware CDN serialization.\n * Leaf nodes receive `depth` but may ignore it.\n * Container nodes use `depth` for indentation and, when recursing, must\n * resolve each child's options via `child._resolveCdnOptions()` first\n * (rather than passing `options` straight through) so `itemOptions` is\n * honored for every node, not just the root — see `_resolveCdnOptions`.\n * `path` is this node's own full path from the root (see\n * `CdnItemContext.path`); only meaningful when `needsCdnItemDispatch()`\n * is `true` for the options in effect — leaf implementations that don't\n * recurse can ignore it, as can any implementation when dispatch isn't\n * in play.\n */\n abstract _toCDN(\n options: ToCDNOptions | undefined,\n depth: number,\n path?: readonly unknown[]\n ): string;\n\n /**\n * @internal\n * Resolve `options.itemOptions` for this node (if any), returning the\n * options a caller should use for both this node's own `_toCDN()` call\n * and (via `_isMultiWordText()`) any layout probe of it — see\n * `CdnItemContext`. Unlike `toJS()`'s `_toJSChild()`, this never caches:\n * see the \"toCDN() per-item dispatch\" note above `needsCdnItemDispatch`\n * for why that's both unnecessary and, per this codebase's own prior\n * experience with `CborTag._isMultiWordText`, unsafe here specifically.\n *\n * `ctx` follows the same \"no `key`, derived from `path`'s last element\"\n * convention `_toJSChild()` uses (see there) — a caller passes\n * `parent`/`keyNode`/`isMapKey` only; `key` is filled in here.\n */\n _resolveCdnOptions(\n options: ToCDNOptions | undefined,\n path: readonly unknown[],\n ctx: Omit<CdnItemContext, 'path' | 'key' | 'options'>\n ): ToCDNOptions | undefined {\n if (!needsCdnItemDispatch(options)) return options;\n const key =\n ctx.isMapKey || path.length === 0 ? undefined : path[path.length - 1];\n const override = options!.itemOptions!(this, {\n ...ctx,\n key,\n path,\n options: toReadonlyCdnOptions(options!),\n });\n if (!override) return options;\n const tracker = (\n options as ToCDNOptions & {\n [CDN_OVERRIDE_TRACKER]?: CdnOverrideTrackerBox;\n }\n )[CDN_OVERRIDE_TRACKER];\n if (tracker) tracker.applied = true;\n // Normalize the override's own deprecated aliases *before* merging: see\n // `normalizeCdnOverride` for why resolving them after merging would let\n // an already-resolved, inherited canonical value silently outrank the\n // child's own alias-based override.\n let eff: ToCDNOptions = { ...options, ...normalizeCdnOverride(override) };\n if (eff.preserveAll) eff = expandPreserveAll(eff);\n return eff;\n }\n\n /**\n * @internal\n * Core conversion logic implemented by each subclass.\n * Container nodes apply `options.reviver` to their direct children, and\n * must recurse via `child._toJSChild()` (never `child._toJS()` directly)\n * so that `options.itemOptions`/`options.extensions` are honored for\n * every node, not just the root — see `_toJSChild`.\n * `path` is this node's own full path from the root (see `ItemContext.path`);\n * only meaningful, and only ever non-empty, when `needsItemDispatch()` is\n * `true` for the options in effect — leaf implementations that don't\n * recurse can ignore it. `occurrence` is this node's own cache-matching\n * identity (see `Occurrence`) — `CborArray`/`CborMap` build on it to\n * derive their children's own occurrences, and `CborTag`/`CborAppSeqResult`\n * pass it through unchanged to their content's `_toJSChild()` call; leaf\n * implementations that don't recurse can ignore it.\n * Do not call this directly — use `toJS()` instead.\n */\n abstract _toJS(\n options?: ToJSOptions,\n path?: readonly unknown[],\n occurrence?: Occurrence\n ): unknown;\n\n /**\n * @internal\n * Entry point container nodes must use when recursing into a child during\n * `toJS()`, instead of calling `child._toJS(options)` directly, so that\n * `options.itemOptions` and `options.extensions` (toJS hooks) are honored\n * for every node in the tree, not just the root.\n *\n * Guarded by `needsItemDispatch()` at each call site rather than\n * internally, so that containers can skip straight to the cheap\n * `child._toJS(options)` call — matching pre-`itemOptions` behavior\n * exactly, with no extra allocation — whenever neither option is in play\n * for the whole conversion.\n *\n * `path` is this child's own full path from the root, already computed by\n * the caller: `[...parentPath, key]` for an array element or map\n * entry/key, or the parent's own `path` unchanged for a transparent\n * wrapper's content (`CborTag`, `CborAppSeqResult`) — see\n * `ItemContext.path`. `ctx.key` is *not* supplied by the caller — it's\n * derived here from `path`'s own last element (or left `undefined` for\n * the root and for `isMapKey` visits), which is what keeps a wrapper's\n * content correctly reporting its outer key: since `CborTag`/\n * `CborAppSeqResult` pass their own unmodified `path` straight through,\n * that derivation naturally recovers the tag's own key for its content\n * too, matching `ItemContext.key`'s documented invariant of always\n * equalling `path`'s last element outside those two exceptions.\n *\n * `occurrence` identifies this child's position for cache-matching\n * purposes only (see `Occurrence`) — deliberately separate from `path`,\n * which is built from *converted JS values* and so is unreliable for\n * that: matching on `path` alone either double-resolves the same position\n * (a composite map key converts to a fresh, non-`===` array/object every\n * time) or wrongly conflates two different positions that happen to\n * convert to equal `path`s (duplicate map entries with equal keys).\n * `occurrence` avoids both by construction — see `Occurrence`.\n *\n * A single node can be visited more than once *at the same occurrence* in\n * one `toJS()` call — a `reviver`-driven `CborArray`/`CborMap` converts\n * each child once to pre-populate an unrevived holder and once more to\n * compute the revived value (see their own `_toJS()`), and either pass\n * may itself recurse through a `CborTag`/`CborAppSeqResult` wrapper that\n * adds no occurrence of its own (content shares the wrapper's). The raw\n * pre-population pass's own occurrence for a child is distinguished from\n * the real pass's by `RAW_PASS_MARKER` (see `Occurrence`), so that even\n * distinct, *nested* raw passes reaching the same node — one from an\n * outer container's own split, one from a different, inner container's\n * own split nested inside the outer's real pass — resolve independently\n * rather than colliding with each other. Neither `options.itemOptions`\n * nor an `extensions` `toJS()` hook may run more than once for the same\n * occurrence despite all that, since either may be stateful — so the\n * *decision* (not the reviver-dependent application of an `itemOptions`\n * override — see `DispatchOutcome`) is cached in `options`'s dispatch\n * cache, when one is present, and reused on a later visit to that exact\n * occurrence. A node *reused* at more than one occurrence (the same\n * `CborItem` instance placed at two positions in a hand-built tree)\n * still resolves once per occurrence, never conflating two different\n * ones.\n */\n _toJSChild(\n options: ToJSOptions | undefined,\n path: readonly unknown[],\n occurrence: Occurrence,\n ctx: Omit<ItemContext, 'path' | 'key' | 'options'>\n ): unknown {\n const cache = getDispatchCache(options);\n const cached = findOccurrence(cache?.get(this), occurrence);\n if (cached) {\n if (cached.outcome.kind === 'value') return cached.outcome.value;\n const eff = cached.outcome.override\n ? { ...options, ...cached.outcome.override }\n : options;\n return this._toJS(eff, path, occurrence);\n }\n\n const key =\n ctx.isMapKey || path.length === 0 ? undefined : path[path.length - 1];\n let eff = options;\n let override: Partial<ToJSOptions> | undefined;\n if (options?.itemOptions) {\n // `ctx.options` is `options` itself, read-only and with `extensions`\n // (if any) copied — see `toReadonlyNodeOptions` — so the callback\n // can't corrupt what this node, its siblings, or the caller see by\n // mutating what it read. Computed fresh here (never cached) so it\n // always reflects exactly what's in effect for *this* call, not a\n // stale snapshot from an earlier resolution of the same occurrence.\n override = options.itemOptions(this, {\n ...ctx,\n key,\n path,\n options: toReadonlyNodeOptions(options),\n });\n if (override) eff = { ...options, ...override };\n }\n if (eff?.extensions?.length) {\n // Hooks never see `reviver` (see `ReadonlyToJSNodeOptions`) — not\n // merely by convention, but because its type omits the field — so\n // their result can never itself depend on it, which is what makes\n // caching that result across a reviver-driven container's repeat\n // visits sound. `extensions` is likewise copied — freshly for *each*\n // hook, not once and shared across the loop — so one hook mutating\n // it in place (bypassing the readonly type) can't leak into what a\n // later hook in the same loop sees.\n for (const ext of eff.extensions) {\n const hooked = ext.toJS?.(this, toReadonlyNodeOptions(eff));\n if (hooked) {\n if (cache)\n recordOccurrence(cache, this, {\n occurrence,\n outcome: { kind: 'value', value: hooked.value },\n });\n return hooked.value;\n }\n }\n }\n if (cache)\n recordOccurrence(cache, this, {\n occurrence,\n outcome: { kind: 'override', override },\n });\n return this._toJS(eff, path, occurrence);\n }\n\n /**\n * @internal\n * Collect annotated-hex lines for this node.\n * Leaf nodes emit a single line; container nodes override to emit\n * open/close lines with recursively collected children.\n */\n _toHexDump(depth: number, options?: ToCDNOptions): AnnotatedLine[] {\n const hex = bytesToSpacedHexUpper(this._toCBOR());\n return [{ depth, hex, comment: this._toCDN(options, 0) }];\n }\n}\n","import type { ToCDNOptions, ToJSOptions, ToCBOROptions } from '../types';\nimport { CborItem } from './CborItem';\nimport { MT_UINT } from '../cbor/constants';\nimport {\n writeHeadTo,\n type CborWriter,\n type EncodingWidth,\n} from '../cbor/encode';\nimport {\n resolveEiSuffix,\n canonicalEncodingWidth,\n} from '../cdn/serialize-utils';\n\n/** CBOR Major Type 0 — unsigned integer (0 … 2^64−1). */\nexport class CborUint extends CborItem {\n readonly value: bigint;\n encodingWidth: EncodingWidth | undefined;\n /**\n * Original CDN digit spelling (base + digits, without the encoding-\n * indicator suffix), set by the parser when this value came from CDN\n * text. Used by `_toCDN()` to round-trip the literal's base (`0xff`,\n * `0o377`, `0b101`, decimal) when `preserveNumberFormat` is set.\n */\n readonly ednSource?: string;\n\n constructor(\n value: number | bigint,\n options?: { encodingWidth?: EncodingWidth; ednSource?: string }\n ) {\n super();\n this.value = BigInt(value);\n if (this.value < 0n)\n throw new RangeError('CborUint value must be non-negative');\n if (this.value > 0xffff_ffff_ffff_ffffn)\n throw new RangeError('CborUint value exceeds maximum uint64');\n this.encodingWidth = options?.encodingWidth;\n this.ednSource = options?.ednSource;\n }\n\n override _encodeTo(writer: CborWriter, _options?: ToCBOROptions): void {\n writeHeadTo(writer, MT_UINT, this.value, this.encodingWidth);\n }\n\n _toCDN(\n options: ToCDNOptions | undefined,\n _depth: number,\n _path?: readonly unknown[]\n ): string {\n const suffix = resolveEiSuffix(options, this.encodingWidth, () =>\n canonicalEncodingWidth(this.value)\n );\n if (options?.preserveNumberFormat && this.ednSource !== undefined) {\n return this.ednSource + suffix;\n }\n const v = this.value;\n switch (options?.intFormat) {\n case 'hex':\n return `0x${v.toString(16)}${suffix}`;\n case 'octal':\n return `0o${v.toString(8)}${suffix}`;\n case 'binary':\n return `0b${v.toString(2)}${suffix}`;\n default:\n return v.toString() + suffix;\n }\n }\n\n _toJS(options?: ToJSOptions): unknown {\n const mode = options?.integerAs ?? 'auto';\n if (mode === 'bigint') return this.value;\n if (mode === 'number') return Number(this.value);\n return this.value <= BigInt(Number.MAX_SAFE_INTEGER)\n ? Number(this.value)\n : this.value;\n }\n}\n","import type { ToCDNOptions, ToJSOptions, ToCBOROptions } from '../types';\nimport { CborItem } from './CborItem';\nimport { MT_NINT } from '../cbor/constants';\nimport {\n writeHeadTo,\n type CborWriter,\n type EncodingWidth,\n} from '../cbor/encode';\nimport {\n resolveEiSuffix,\n canonicalEncodingWidth,\n} from '../cdn/serialize-utils';\n\n/**\n * CBOR Major Type 1 — negative integer (−2^64 … −1).\n *\n * The constructor accepts the actual negative value (e.g. `-5n`).\n * Internally the CBOR \"argument\" `n` is stored, where the decoded value\n * equals `−1 − n`. This matches the wire encoding directly.\n *\n * Examples:\n * new CborNint(-1n) → argument = 0n\n * new CborNint(-5n) → argument = 4n\n */\nexport class CborNint extends CborItem {\n /** CBOR raw argument n, where actual value = −1 − n. */\n readonly argument: bigint;\n encodingWidth: EncodingWidth | undefined;\n /**\n * Original CDN digit spelling (sign + base + digits, without the\n * encoding-indicator suffix), set by the parser when this value came\n * from CDN text. Used by `_toCDN()` to round-trip the literal's base\n * (`-0xff`, `-0o377`, `-0b101`, decimal) when `preserveNumberFormat` is\n * set.\n */\n readonly ednSource?: string;\n\n constructor(\n value: number | bigint,\n options?: { encodingWidth?: EncodingWidth; ednSource?: string }\n ) {\n super();\n const v = BigInt(value);\n if (v >= 0n) throw new RangeError('CborNint value must be negative');\n if (v < -(0xffff_ffff_ffff_ffffn + 1n))\n throw new RangeError('CborNint value exceeds minimum int64');\n this.argument = -1n - v;\n this.encodingWidth = options?.encodingWidth;\n this.ednSource = options?.ednSource;\n }\n\n /** The actual decoded negative value (−1 − argument). */\n get value(): bigint {\n return -1n - this.argument;\n }\n\n override _encodeTo(writer: CborWriter, _options?: ToCBOROptions): void {\n writeHeadTo(writer, MT_NINT, this.argument, this.encodingWidth);\n }\n\n _toCDN(\n options: ToCDNOptions | undefined,\n _depth: number,\n _path?: readonly unknown[]\n ): string {\n const suffix = resolveEiSuffix(options, this.encodingWidth, () =>\n canonicalEncodingWidth(this.argument)\n );\n if (options?.preserveNumberFormat && this.ednSource !== undefined) {\n return this.ednSource + suffix;\n }\n const abs = this.argument + 1n; // absolute value of the negative number\n switch (options?.intFormat) {\n case 'hex':\n return `-0x${abs.toString(16)}${suffix}`;\n case 'octal':\n return `-0o${abs.toString(8)}${suffix}`;\n case 'binary':\n return `-0b${abs.toString(2)}${suffix}`;\n default:\n return this.value.toString() + suffix;\n }\n }\n\n _toJS(options?: ToJSOptions): unknown {\n const v = this.value;\n const mode = options?.integerAs ?? 'auto';\n if (mode === 'bigint') return v;\n if (mode === 'number') return Number(v);\n return v >= BigInt(Number.MIN_SAFE_INTEGER) ? Number(v) : v;\n }\n}\n","/**\n * Hex float (C99-style, e.g. `0x1.8p+0`) encode/decode utilities.\n *\n * Hex float format:\n * [-] 0x [hex digits] [. [hex digits]] p [+-] [decimal exponent]\n *\n * This notation appears in CDN (draft-ietf-cbor-edn-literals-27) as an\n * alternative representation for floating-point values (major type 7).\n */\n\n// Reusable 8-byte buffer for float64 bit extraction\nconst _buf8 = new ArrayBuffer(8);\nconst _dv8 = new DataView(_buf8);\n\n/**\n * Parse a hex float literal (e.g. `0x4711p+03`, `0x1.8p+0`, `-0x1.fp-2`)\n * to a JS number.\n *\n * Assumes the string has already been stripped of any encoding-indicator\n * suffix (`_1`, `_2`, `_3`).\n */\nexport function parseHexFloat(s: string): number {\n const neg = s.startsWith('-');\n const body = s.slice(neg ? 3 : 2); // strip optional '-' and '0x'/'0X'\n\n const pIdx = body.search(/[pP]/);\n if (pIdx === -1)\n throw new SyntaxError(\n `EDN parse error: hex float missing 'p' exponent: ${s}`\n );\n\n const mantissaStr = body.slice(0, pIdx);\n const expStr = body.slice(pIdx + 1);\n\n // Exponent must be a non-empty decimal integer (optional sign + digits)\n if (!/^[+-]?\\d+$/.test(expStr))\n throw new SyntaxError(\n `EDN parse error: hex float has invalid or missing exponent: ${s}`\n );\n\n const exp = parseInt(expStr, 10);\n\n const dotIdx = mantissaStr.indexOf('.');\n let mantissa: number;\n if (dotIdx === -1) {\n // No decimal point: must have at least one hex digit\n if (!/^[0-9a-fA-F]+$/.test(mantissaStr))\n throw new SyntaxError(\n `EDN parse error: hex float has no mantissa digits: ${s}`\n );\n mantissa = parseInt(mantissaStr, 16);\n } else {\n const intPart = mantissaStr.slice(0, dotIdx);\n const fracStr = mantissaStr.slice(dotIdx + 1);\n // At least one hex digit required on either side of the decimal point\n if (intPart === '' && fracStr === '')\n throw new SyntaxError(\n `EDN parse error: hex float has no mantissa digits: ${s}`\n );\n if (intPart !== '' && !/^[0-9a-fA-F]+$/.test(intPart))\n throw new SyntaxError(\n `EDN parse error: hex float has invalid mantissa: ${s}`\n );\n if (fracStr !== '' && !/^[0-9a-fA-F]+$/.test(fracStr))\n throw new SyntaxError(\n `EDN parse error: hex float has invalid mantissa: ${s}`\n );\n const intVal = intPart === '' ? 0 : parseInt(intPart, 16);\n const fracVal =\n fracStr === '' ? 0 : parseInt(fracStr, 16) / Math.pow(16, fracStr.length);\n mantissa = intVal + fracVal;\n }\n\n const result = mantissa * Math.pow(2, exp);\n return neg ? -result : result;\n}\n\n/**\n * Convert a JS number to a normalized hex float string compatible with\n * CDN diagnostic notation.\n *\n * - Every nonzero finite value: `0x1.[hex fraction]p[+-][exp]` (e.g.\n * `0x1.8p+0` for 1.5) — including a *subnormal* double, renormalized\n * into this same leading-`1` form rather than spelled out anchored to\n * its own stored field layout (`0x0.[hex fraction]p-1022`, still a\n * correct spelling of the same value, but needlessly longer: e.g.\n * `Number.MIN_VALUE` used to read `0x0.0000000000001p-1022`, equal to\n * but far longer than the normalized `0x1p-1074`. A hex-float literal\n * is just `significand * 2^exponent` — there's no reason its spelling\n * should vary by whether the *double* happened to run out of exponent\n * range, once it's just text.)\n * - Zero: `0x0p+0` / `-0x0p+0`\n * - Non-finite values (NaN, ±Infinity) are returned unchanged as EDN tokens.\n */\nexport function floatToHexFloat(v: number): string {\n if (isNaN(v)) return 'NaN';\n if (!isFinite(v)) return v > 0 ? 'Infinity' : '-Infinity';\n\n const neg = Object.is(v, -0) || v < 0;\n const abs = Math.abs(v);\n\n if (abs === 0) return neg ? '-0x0p+0' : '0x0p+0';\n\n _dv8.setFloat64(0, abs, false); // big-endian\n const hi = _dv8.getUint32(0, false);\n const lo = _dv8.getUint32(4, false);\n\n // bits [30:20] of hi = biased exponent (11 bits)\n const biasedExp = (hi >>> 20) & 0x7ff;\n // bits [19:0] of hi = upper 20 bits of 52-bit mantissa\n const mantHi = hi & 0xfffff;\n // lo = lower 32 bits of mantissa\n const mantLo = lo;\n\n let mantissa52: bigint; // the 52 fraction bits that go after \"1.\"\n let exp: number;\n if (biasedExp === 0) {\n // Subnormal: value = 0.[52-bit mantissa] * 2^-1022, with no implicit\n // leading 1 of its own. Renormalize by finding the mantissa's own\n // leading set bit (`mantHi`/`mantLo` can't both be zero here — that\n // combination, with `biasedExp === 0`, would mean `abs === 0`,\n // already returned above) and shifting it up to become the implicit\n // \"1\", the same renormalization step CPU hardware performs when it\n // promotes a subnormal operand.\n const mantissa = (BigInt(mantHi) << 32n) | BigInt(mantLo);\n const bitLength = mantissa.toString(2).length; // 1..52\n const leadingBit = 1n << BigInt(bitLength - 1);\n mantissa52 = (mantissa - leadingBit) << BigInt(52 - (bitLength - 1));\n // value = (leadingBit + r)/2^52 * 2^-1022, with leadingBit = 2^(bitLength-1)\n // and r = mantissa - leadingBit — factor out leadingBit/2^52 to land on\n // the normalized `1.[mantissa52/2^52] * 2^exp` form: exp is the *true*\n // exponent of that leading bit, `bitLength - 1 - 52 - 1022`, not just\n // `bitLength - 1 - 1022` (that's `2^-1022`'s own exponent, before\n // dividing by the mantissa field's `2^52` scale — still needed here,\n // unlike the normal branch below, whose `biasedExp - 1023` already *is*\n // the final exponent by definition of the bias).\n exp = bitLength - 1075;\n } else {\n // Normal: value = 1.[52-bit mantissa] * 2^(biasedExp-1023)\n mantissa52 = (BigInt(mantHi) << 32n) | BigInt(mantLo);\n exp = biasedExp - 1023;\n }\n\n // Format mantissa as 13 hex digits (52 bits / 4), strip trailing zeros\n const hexMant = mantissa52.toString(16).padStart(13, '0');\n const trimmed = hexMant.replace(/0+$/, '');\n const mantPart = trimmed === '' ? '' : `.${trimmed}`;\n\n const expStr = exp >= 0 ? `+${exp}` : `${exp}`;\n const result = `0x1${mantPart}p${expStr}`;\n return neg ? `-${result}` : result;\n}\n","import type { ToCDNOptions, ToJSOptions, ToCBOROptions } from '../types';\nimport { CborItem } from './CborItem';\nimport { MT_SIMPLE, AI_2BYTE, AI_4BYTE, AI_8BYTE } from '../cbor/constants';\nimport { autoSelectFloatPrecision, type CborWriter } from '../cbor/encode';\nimport {\n floatValueToString,\n floatSuffix,\n resolveIndent,\n} from '../cdn/serialize-utils';\nimport { floatToHexFloat } from '../utils/hexfloat';\nimport { bytesToHex } from '../utils/hex';\n\nexport type FloatPrecision = 'half' | 'single' | 'double';\n\n/**\n * CBOR Major Type 7 — IEEE 754 floating-point number.\n *\n * `precision` records the encoding size from the original CBOR stream so\n * that lossless round-trips are preserved. When constructing from a JS\n * `number`, omit `precision` (`undefined`) and the encoder will choose\n * the smallest encoding that preserves the value exactly.\n */\nexport class CborFloat extends CborItem {\n readonly value: number;\n /**\n * Encoding size hint.\n * - `'half'` / `'single'` / `'double'`: use exactly this size (set by the\n * decoder to guarantee lossless round-trips).\n * - `undefined`: encoder auto-selects the smallest lossless size.\n */\n precision: FloatPrecision | undefined;\n /**\n * Original app-string source (e.g. `float'7e00'`), set by the parser when\n * this float is the result of a `float'...'` app-string. Used by toCDN()\n * to round-trip the literal when `appPrefix` is not false.\n */\n ednSource?: string;\n\n /**\n * Original CDN literal source text (e.g. `1.50`, `1.5_1`, `0x1.8p+0_1`),\n * set by the parser when this float came from a plain CDN float literal\n * (as opposed to a `float'...'` app-string, which uses `ednSource`\n * above). Used by `_toCDN()` to round-trip the literal's exact spelling,\n * including its encoding-indicator suffix, when `preserveNumberFormat`\n * is set.\n */\n literalSource?: string;\n\n /**\n * Original encoded payload bytes (big-endian, without the initial byte),\n * set by the decoder when the value is NaN so that NaN payloads survive a\n * decode → encode round-trip (a JS `number` cannot carry them).\n * Used by the encoder only when `value` is NaN and the length matches the\n * byte size of the encoded `precision`; ignored otherwise.\n */\n rawBits?: Uint8Array;\n\n constructor(\n value: number,\n options?: {\n precision?: FloatPrecision;\n rawBits?: Uint8Array;\n literalSource?: string;\n }\n ) {\n super();\n this.value = value;\n this.precision = options?.precision;\n this.rawBits = options?.rawBits;\n this.literalSource = options?.literalSource;\n }\n\n override _encodeTo(writer: CborWriter, _options?: ToCBOROptions): void {\n const precision = this.precision ?? autoSelectFloatPrecision(this.value);\n const initial = MT_SIMPLE << 5;\n // rawBits carries a NaN payload only; for any other value it would let\n // the encoded bytes contradict `value`, so it is ignored.\n const rawBits = Number.isNaN(this.value) ? this.rawBits : undefined;\n\n if (precision === 'half') {\n writer.writeByte(initial | AI_2BYTE); // 0xf9\n if (rawBits?.length === 2) writer.writeBytes(rawBits);\n else writer.writeFloat16(this.value);\n } else if (precision === 'single') {\n writer.writeByte(initial | AI_4BYTE); // 0xfa\n if (rawBits?.length === 4) writer.writeBytes(rawBits);\n else writer.writeFloat32(this.value);\n } else {\n // double\n writer.writeByte(initial | AI_8BYTE); // 0xfb\n if (rawBits?.length === 8) writer.writeBytes(rawBits);\n else writer.writeFloat64(this.value);\n }\n }\n\n _toCDN(\n options: ToCDNOptions | undefined,\n _depth: number,\n _path?: readonly unknown[]\n ): string {\n const mode = options?.encodingIndicators ?? 'auto';\n // In single-line output (no `indent`), a source spelling that spans\n // multiple lines (e.g. a `float<<...>>` app-sequence written across\n // lines) cannot be re-emitted, so it falls back to normal serialization.\n // An explicit `floatFormat` request (anything other than leaving it\n // unset, or asking for the app-extension form it's already in) opts out\n // of this round-trip too — the whole point of asking for `'decimal'`/\n // `'hex'` is to reformat every float, including one that started out as\n // a `float'...'` literal.\n if (\n options?.appPrefix !== false &&\n (options?.floatFormat === undefined ||\n options?.floatFormat === 'app-extension') &&\n this.ednSource !== undefined &&\n (resolveIndent(options) !== null || !/[\\r\\n]/.test(this.ednSource))\n ) {\n const ednSource = this.ednSource;\n if (mode === 'never') return ednSource.replace(/_[0-3i]$/, '');\n if (mode === 'always') {\n if (/_[0-3i]$/.test(ednSource)) return ednSource;\n const actual = this.precision ?? autoSelectFloatPrecision(this.value);\n const suffix =\n actual === 'half' ? '_1' : actual === 'single' ? '_2' : '_3';\n return ednSource + suffix;\n }\n return ednSource;\n }\n if (options?.preserveNumberFormat && this.literalSource !== undefined) {\n const literalSource = this.literalSource;\n // Encoding-indicator suffixes are embedded directly in the literal\n // text; _[0-7i] matches the full grammar (not just _[0-3i]) so that a\n // syntactically-present-but-semantically-invalid suffix (e.g. the \"_7\"\n // in a leniently-parsed \"1.5_7\") is still recognised and stripped.\n if (mode === 'never') return literalSource.replace(/_[0-7i]$/, '');\n if (mode === 'always') {\n if (/_[0-7i]$/.test(literalSource)) return literalSource;\n const autoSelected = autoSelectFloatPrecision(this.value);\n return (\n literalSource +\n floatSuffix(this.value, this.precision, autoSelected, 'always')\n );\n }\n return literalSource;\n }\n const autoSelected = autoSelectFloatPrecision(this.value);\n if (\n options?.floatFormat === 'app-extension' &&\n options?.appPrefix !== false\n ) {\n // Derived from the value's actual encoded bytes (via toCBOR(), which\n // honors a _toCBOR() override for e.g. a NaN-payload-preserving\n // subclass) rather than reimplementing bit-pattern logic here — the\n // first byte is the major-7 initial byte, not part of the payload.\n const bytes = this.toCBOR();\n const hex = bytesToHex(bytes.subarray(1));\n return (\n `float'${hex}'` +\n floatSuffix(this.value, this.precision, autoSelected, mode)\n );\n }\n const numStr =\n options?.floatFormat === 'hex'\n ? floatToHexFloat(this.value)\n : floatValueToString(this.value);\n return numStr + floatSuffix(this.value, this.precision, autoSelected, mode);\n }\n\n _toJS(_options?: ToJSOptions): unknown {\n return this.value;\n }\n}\n","import type { ToCDNOptions, ToJSOptions, ToCBOROptions } from '../types';\nimport { CborItem, needsItemDispatch, ROOT_OCCURRENCE } from './CborItem';\nimport { Tag } from '../tag';\nimport type { AnnotatedLine, Occurrence } from './CborItem';\nimport { MT_TAG } from '../cbor/constants';\nimport {\n writeHead,\n writeHeadTo,\n type CborWriter,\n type EncodingWidth,\n} from '../cbor/encode';\nimport {\n resolveEiSuffix,\n canonicalEncodingWidth,\n isMultiWordRenderedLiteral,\n pushAll,\n renderSingleChildWithComments,\n} from '../cdn/serialize-utils';\nimport { bytesToSpacedHexUpper } from '../utils/hex';\n\n/** CBOR Major Type 6 — tagged data item. */\nexport class CborTag extends CborItem {\n readonly tag: bigint;\n readonly content: CborItem;\n encodingWidth: EncodingWidth | undefined;\n /**\n * Original CDN digit spelling of the tag number (base + digits, without\n * the encoding-indicator suffix), set by the parser when this tag came\n * from CDN text. Used by `_toCDN()` to round-trip the tag number's base\n * (`0x3e7`, decimal, …) when `preserveNumberFormat` is set.\n */\n ednSource?: string;\n\n constructor(\n tag: number | bigint,\n content: CborItem,\n options?: { encodingWidth?: EncodingWidth; ednSource?: string }\n ) {\n super();\n this.tag = BigInt(tag);\n if (this.tag < 0n)\n throw new RangeError('CborTag tag number must be non-negative');\n this.content = content;\n this.encodingWidth = options?.encodingWidth;\n this.ednSource = options?.ednSource;\n }\n\n override get _containsCdnContainer(): boolean {\n return this.content._containsCdnContainer;\n }\n\n /**\n * Checked by tokenizing `this._toCDN()`'s own actual output — not by\n * delegating to `this.content._isMultiWordText()` (a semantic prediction\n * from the AST) — because a subclass may override `_toCDN()` to render\n * something that doesn't match generic `tagNum(content)` notation at all\n * (`CborTaggedIpExt` renders `IP<<'192.0.2.42'>>`, `CborTaggedEpochDtExt`\n * renders `DT'...'`/`DT<<...>>`, ...); a check based on `this.content`\n * would be looking at the wrong thing entirely for those. Tokenizing the\n * real output instead is exact regardless of which class produced it —\n * see `isMultiWordRenderedLiteral`, which also handles the plain,\n * generic-tag case (peeling `tagNum[_EI](...)` to see what's inside, so\n * `100(dt'...')` and `100(\"two words\")` still work the same as before).\n *\n * Deliberately *not* cached: an earlier version cached this render on\n * the instance keyed by `options` reference alone, which was wrong two\n * ways — (1) `preserveConcatenation`'s continuation-line indentation\n * *does* depend on depth even for leaf content, so a render cached at\n * depth 0 here and reused by `_toCDN`'s real render at a different depth\n * produced under-indented continuation lines; (2) the cache persisted\n * on the node forever and was keyed only by object identity, so\n * mutating the same `options` object between two `toCDN()` calls\n * silently returned the first call's stale result. `this` is re-rendered\n * here and again by the real `_toCDN` call from whatever holds this\n * entry — an accepted, narrow cost (only tag-wrapped entries reach this\n * at all).\n */\n override _isMultiWordText(\n options: ToCDNOptions | undefined,\n strict = true,\n path?: readonly unknown[]\n ): boolean {\n return isMultiWordRenderedLiteral(this._toCDN(options, 0, path), strict);\n }\n\n override _encodeTo(writer: CborWriter, options?: ToCBOROptions): void {\n writeHeadTo(writer, MT_TAG, this.tag, this.encodingWidth);\n this.content._encode(writer, options);\n }\n\n override _toCDN(\n options: ToCDNOptions | undefined,\n depth: number,\n path?: readonly unknown[]\n ): string {\n const suffix = resolveEiSuffix(options, this.encodingWidth, () =>\n canonicalEncodingWidth(this.tag)\n );\n const tagStr =\n options?.preserveNumberFormat && this.ednSource !== undefined\n ? this.ednSource\n : this.tag.toString();\n // A tag wrapper adds no path segment of its own — the content shares\n // this tag's own path (see CdnItemContext.path) and gets its own\n // itemOptions resolved against it (`_resolveCdnOptions` is a no-op\n // when itemOptions isn't in play, so this is always safe to call).\n const contentOptions = this.content._resolveCdnOptions(\n options,\n path ?? [],\n { parent: this }\n );\n const wrapped = renderSingleChildWithComments(\n this.content,\n this,\n options,\n contentOptions,\n depth,\n (childDepth) => this.content._toCDN(contentOptions, childDepth, path),\n '(',\n ')'\n );\n return `${tagStr}${suffix}${wrapped}`;\n }\n\n override _toHexDump(depth: number, options?: ToCDNOptions): AnnotatedLine[] {\n const lines: AnnotatedLine[] = [\n {\n depth,\n hex: bytesToSpacedHexUpper(\n writeHead(MT_TAG, this.tag, this.encodingWidth)\n ),\n comment: `Tag ${this.tag}`,\n },\n ];\n pushAll(\n lines,\n this.content._toHexDump(depth + 1, { ...options, appPrefix: false })\n );\n return lines;\n }\n\n _toJS(\n options?: ToJSOptions,\n path?: readonly unknown[],\n occurrence?: Occurrence\n ): unknown {\n // A tag wrapper adds no path segment — or occurrence — of its own: the\n // content shares this tag's own path (see ItemContext.path) and its own\n // cache-matching identity (see Occurrence) unchanged.\n const value = needsItemDispatch(options)\n ? this.content._toJSChild(\n options,\n path ?? [],\n occurrence ?? ROOT_OCCURRENCE,\n { parent: this }\n )\n : this.content._toJS(options);\n return options?.stripTags ? value : Tag.set(value, this.tag);\n }\n}\n","import type { ToCDNOptions, ToJSOptions, ToCBOROptions } from '../types';\nimport { CborItem } from './CborItem';\nimport { MT_BYTES } from '../cbor/constants';\nimport {\n writeHeadTo,\n type CborWriter,\n type EncodingWidth,\n} from '../cbor/encode';\nimport {\n serializeBytes,\n isMultiWordByteString,\n resolveEiSuffix,\n resolveIndent,\n joinConcatParts,\n joinAppSeqParts,\n canonicalEncodingWidth,\n stripByteLiteralComments,\n danglingCommentsByGap,\n shouldEmitComments,\n resolveCommentStyle,\n type ByteCommentSyntax,\n} from '../cdn/serialize-utils';\n\n/**\n * A preserved literal source, with any embedded comment stripped unless\n * comments are requested (`preserveComments`/`comments`) — the preserved\n * spelling should still drop comments by default, the same as an\n * unpreserved literal re-derived from its decoded value would.\n * `commentSyntax` is `undefined` for a literal\n * family with no comment syntax at all (bare sqstr `'...'`) or one whose\n * comment syntax isn't known (an app-string extension other than the\n * specific built-in `b32`/`h32` objects — see `ednCommentSyntax`); in\n * either case the source is returned verbatim, since there's nothing safe\n * to strip.\n */\nfunction preservedSource(\n source: string | undefined,\n options: ToCDNOptions | undefined,\n commentSyntax: ByteCommentSyntax | undefined\n): string | undefined {\n if (source === undefined) return undefined;\n if (shouldEmitComments(options) || commentSyntax === undefined) return source;\n return stripByteLiteralComments(source, commentSyntax);\n}\n\n/** One part of a byte string parsed from a CDN `+` concatenation chain. */\nexport interface CborByteStringPart {\n bytes: Uint8Array;\n /** Original literal source text, when the part came from a byte string token. */\n source?: string;\n /** Which comment syntax `source` recognizes, if any — see `ednCommentSyntax`. */\n commentSyntax?: ByteCommentSyntax;\n /**\n * Source span of this part's own literal token, when known — used to place\n * a comment sitting between two `+`-joined parts (attached to the whole\n * `CborByteString` as a `dangling` comment, since there is no per-part AST\n * node for it to attach to) at the right gap in `_toCDN`'s\n * `preserveConcatenation` branch. `undefined` for a part merged from a\n * single elided literal's own internal segments, which cannot have a\n * comment between them.\n */\n start?: number;\n end?: number;\n}\n\n/** CBOR Major Type 2 — definite-length byte string. */\nexport class CborByteString extends CborItem {\n readonly indefiniteLength = false as const;\n readonly value: Uint8Array;\n /** Preferred EDN encoding for this byte string. */\n readonly ednEncoding: 'hex' | 'base64' | 'base64url' | 'base32' | 'base32hex';\n encodingWidth: EncodingWidth | undefined;\n readonly ednSource: string | undefined;\n /**\n * Which comment syntax `ednSource` recognizes, if any — set once at parse\n * time by whoever actually knows the literal's real origin (see\n * `ByteCommentSyntax`), never re-derived later from its prefix string:\n * a user extension can register under any prefix, including one a\n * built-in (`b32`/`h32`) also uses, so the prefix string alone can't say\n * which comment rules (if any) actually apply. `undefined` when\n * `ednSource` has no comment syntax, or its extension's isn't known.\n */\n readonly ednCommentSyntax: ByteCommentSyntax | undefined;\n /** Part boundaries of the original `+` concatenation chain, if any. */\n readonly ednParts: readonly CborByteStringPart[] | undefined;\n\n constructor(\n value: Uint8Array,\n options?: {\n ednEncoding?: 'hex' | 'base64' | 'base64url' | 'base32' | 'base32hex';\n encodingWidth?: EncodingWidth;\n ednSource?: string;\n ednCommentSyntax?: ByteCommentSyntax;\n ednParts?: readonly CborByteStringPart[];\n }\n ) {\n super();\n this.value = value;\n this.ednEncoding = options?.ednEncoding ?? 'hex';\n this.encodingWidth = options?.encodingWidth;\n this.ednSource = options?.ednSource;\n this.ednCommentSyntax = options?.ednCommentSyntax;\n this.ednParts = options?.ednParts;\n }\n\n /**\n * Only the \"bare sqstr text with 2+ words\" case — the \"is this a\n * prefixed literal\" question is deliberately *not* predicted here from\n * raw bytes at all (a subclass like `CborIpExt` might override `_toCDN()`\n * to render something else entirely, e.g. a preserved\n * `ip<<'192.0.2.42'>>` app-sequence spelling, that raw-byte prediction\n * knows nothing about — see `isMultiWordByteString`'s doc). That\n * question is instead answered from the *actual rendering*: for a bare\n * entry, `serializeContainer`'s own `isPrefixedLiteralText(s)` check\n * already covers it (this node's render *is* `s`, unobscured); for one\n * wrapped in a `CborTag`, `CborTag._isMultiWordText`'s\n * `isMultiWordRenderedLiteral` check covers it instead. `strict` isn't\n * needed here at all now — it's accepted purely for interface\n * consistency with the base class.\n */\n override _isMultiWordText(\n options: ToCDNOptions | undefined,\n _strict = true,\n _path?: readonly unknown[]\n ): boolean {\n return isMultiWordByteString(this.value, options?.sqstr);\n }\n\n override _encodeTo(writer: CborWriter, _options?: ToCBOROptions): void {\n writeHeadTo(writer, MT_BYTES, this.value.length, this.encodingWidth);\n writer.writeBytes(this.value);\n }\n\n _toCDN(\n options: ToCDNOptions | undefined,\n _depth: number,\n _path?: readonly unknown[]\n ): string {\n const indentStr = resolveIndent(options);\n if (\n options?.preserveConcatenation &&\n // Preserved concatenation is a layout feature; single-line mode joins\n // the parts into one literal instead.\n indentStr !== null &&\n this.ednParts !== undefined &&\n this.ednParts.length > 1\n ) {\n const suffix = resolveEiSuffix(options, this.encodingWidth, () =>\n canonicalEncodingWidth(BigInt(this.value.length))\n );\n let encoding = options?.bstrEncoding ?? this.ednEncoding;\n if (options?.appPrefix === false && encoding !== 'hex') encoding = 'hex';\n const literals = this.ednParts.map((part) => {\n const source = options?.preserveByteString\n ? preservedSource(part.source, options, part.commentSyntax)\n : undefined;\n return source !== undefined\n ? source\n : serializeBytes(part.bytes, encoding, options?.sqstr);\n });\n const midComments = shouldEmitComments(options)\n ? danglingCommentsByGap(\n this.comments?.dangling,\n this.ednParts,\n resolveCommentStyle(options)\n )\n : undefined;\n if (options?.modernConcat && options?.appPrefix !== false) {\n return joinAppSeqParts(\n 'b1',\n literals,\n suffix,\n indentStr,\n _depth,\n midComments\n );\n }\n literals[literals.length - 1] += suffix;\n return joinConcatParts(literals, indentStr, _depth, midComments);\n }\n const preservedWhole = options?.preserveByteString\n ? preservedSource(this.ednSource, options, this.ednCommentSyntax)\n : undefined;\n if (\n preservedWhole !== undefined &&\n // In single-line mode a spelling that spans multiple lines (e.g. a\n // byte string with an interior line comment that survived stripping,\n // or a genuine interior line break) cannot be re-emitted.\n (indentStr !== null || !/[\\r\\n]/.test(preservedWhole))\n ) {\n // App-string byte strings (e.g. b32'...'_1) embed the EI inside ednSource.\n // Regular byte strings (h'...', b64'...') store EI separately in encodingWidth.\n if (/_[0-3i]$/.test(preservedWhole)) {\n const mode = options?.encodingIndicators ?? 'auto';\n if (mode === 'never') return preservedWhole.replace(/_[0-3i]$/, '');\n return preservedWhole; // 'auto' or 'always': EI already present\n }\n const suffix = resolveEiSuffix(options, this.encodingWidth, () =>\n canonicalEncodingWidth(BigInt(this.value.length))\n );\n return preservedWhole + suffix;\n }\n const suffix = resolveEiSuffix(options, this.encodingWidth, () =>\n canonicalEncodingWidth(BigInt(this.value.length))\n );\n let encoding = options?.bstrEncoding ?? this.ednEncoding;\n if (options?.appPrefix === false && encoding !== 'hex') encoding = 'hex';\n return serializeBytes(this.value, encoding, options?.sqstr) + suffix;\n }\n\n _toJS(_options?: ToJSOptions): unknown {\n return this.value;\n }\n}\n","import type { ToCDNOptions, ToJSOptions, ToCBOROptions } from '../types';\nimport { CborItem, needsCdnItemDispatch } from './CborItem';\nimport type { AnnotatedLine } from './CborItem';\nimport { CborByteString } from './CborByteString';\nimport { MT_BYTES, AI_INDEFINITE, BREAK_CODE } from '../cbor/constants';\nimport type { CborWriter } from '../cbor/encode';\nimport {\n formatTrailingComments,\n hasPreservedComments,\n pushAll,\n serializeContainer,\n} from '../cdn/serialize-utils';\nimport { byteToHexUpper } from '../utils/hex';\n\n/** CBOR Major Type 2 — indefinite-length byte string (chunked). */\nexport class CborIndefiniteByteString extends CborItem {\n readonly indefiniteLength = true as const;\n readonly chunks: CborByteString[];\n\n constructor(chunks: CborByteString[]) {\n super();\n this.chunks = chunks;\n }\n\n override _encodeTo(writer: CborWriter, options?: ToCBOROptions): void {\n writer.writeByte((MT_BYTES << 5) | AI_INDEFINITE);\n for (const chunk of this.chunks) chunk._encode(writer, options);\n writer.writeByte(BREAK_CODE);\n }\n\n /**\n * True when any chunk's own decoded content, if it renders as bare sqstr\n * text, has two or more words. Reachable when this node is a *direct*\n * entry of another container (`[(_ \"two words\")]`) — though even then,\n * its own `_toCDN()` already self-disqualifies internally in that case\n * (a multi-word chunk forces a multi-line self-render), which the\n * ordinary \"entry's own rendering has a line break\" check would catch\n * regardless of what this method answers, so this mostly exists for\n * robustness/consistency with `CborTextString`/`CborByteString` rather\n * than because some case is otherwise unreachable.\n *\n * `CborAppSeqResult`, which wraps this node for results like\n * `ilbs<<...>>`, does *not* delegate to this method — it tokenizes its\n * own rendered output directly instead (`isMultiWordRenderedLiteral`),\n * which is exactly why `ilbs<<h'00'>>` stays an ordinary leaf (checked\n * under the loose rule, matching `<<...>>`) while `[h'00']`/`(_ h'00')`\n * still always disqualify — this method's own `_strict` (always `true`,\n * matching how a chunk renders when this container *is* regenerated\n * directly) plays no part in that distinction anymore, and a byte string\n * chunk's own `_isMultiWordText` doesn't consult `strict` at all\n * regardless (see `CborByteString`'s doc — its \"prefixed literal\" case\n * was removed there too).\n */\n override _isMultiWordText(\n options: ToCDNOptions | undefined,\n _strict = true\n ): boolean {\n return this.chunks.some((c) => c._isMultiWordText(options));\n }\n\n _toCDN(\n options: ToCDNOptions | undefined,\n depth: number,\n path?: readonly unknown[]\n ): string {\n if ((options?.encodingIndicators ?? 'auto') === 'never') {\n const totalLen = this.chunks.reduce((sum, c) => sum + c.value.length, 0);\n const merged = new Uint8Array(totalLen);\n let offset = 0;\n for (const chunk of this.chunks) {\n merged.set(chunk.value, offset);\n offset += chunk.value.length;\n }\n return new CborByteString(merged)._toCDN(options, depth);\n }\n const basePath = path ?? [];\n const dispatch = needsCdnItemDispatch(options);\n const childOptions = (i: number): ToCDNOptions | undefined =>\n dispatch\n ? this.chunks[i]._resolveCdnOptions(options, [...basePath, i], {\n parent: this,\n })\n : options;\n // `ilbs<<...>>` (draft-27 §3.6) replaces the legacy `(_ ...)` marker\n // notation; falls back to it when `appPrefix` disables app-string\n // notation entirely.\n const useIlbs =\n !!options?.modernStreamSyntax && options?.appPrefix !== false;\n if (!useIlbs && this.chunks.length === 0) return \"''_\";\n return serializeContainer({\n node: this,\n options,\n depth,\n openChar: useIlbs ? 'ilbs<<' : '(',\n closeChar: useIlbs ? '>>' : ')',\n count: this.chunks.length,\n indefiniteLength: true,\n indefiniteMarker: !useIlbs,\n encodingWidth: undefined,\n hasEntryComments: (i) => hasPreservedComments(this.chunks[i]),\n renderEntry: (i) =>\n this.chunks[i]._toCDN(\n childOptions(i),\n depth + 1,\n dispatch ? [...basePath, i] : undefined\n ),\n // Unlike CborEmbeddedCBOR (`<<...>>`), the legacy `(_ ...)` group\n // follows the same strict rule as CborArray/CborMap, gated behind\n // inlineLeafContainers: entryIsLeaf is trivially always true (chunks\n // can never be containers), but its presence is what signals \"strict\"\n // to serializeContainer's probe — so a chunk that renders as a\n // prefixed literal (`h'...'`) always disqualifies inlining here, same\n // as it would in `[h'...']`. `ilbs<<...>>` is itself an\n // app-sequence form, so it always collapses like\n // CborEmbeddedCBOR instead (loose rule, entryIsLeaf omitted).\n entryIsLeaf: useIlbs ? undefined : () => true,\n alwaysInlineLeaf: useIlbs,\n entryIsMultiWordText: (i) =>\n this.chunks[i]._isMultiWordText(\n childOptions(i),\n !useIlbs,\n dispatch ? [...basePath, i] : undefined\n ),\n entryLeadingNode: (i) => this.chunks[i],\n entryTrailing: (i, style) =>\n formatTrailingComments(this.chunks[i], style),\n entryOptions: dispatch ? childOptions : undefined,\n });\n }\n\n override _toHexDump(depth: number, options?: ToCDNOptions): AnnotatedLine[] {\n const lines: AnnotatedLine[] = [\n {\n depth,\n hex: byteToHexUpper((MT_BYTES << 5) | AI_INDEFINITE),\n comment: 'Start indefinite-length byte string',\n },\n ];\n for (const chunk of this.chunks)\n pushAll(lines, chunk._toHexDump(depth + 1, options));\n lines.push({ depth, hex: byteToHexUpper(BREAK_CODE), comment: '\"break\"' });\n return lines;\n }\n\n _toJS(_options?: ToJSOptions): unknown {\n const totalLen = this.chunks.reduce((sum, c) => sum + c.value.length, 0);\n const result = new Uint8Array(totalLen);\n let offset = 0;\n for (const chunk of this.chunks) {\n result.set(chunk.value, offset);\n offset += chunk.value.length;\n }\n return result;\n }\n}\n","import type { ToCDNOptions, ToJSOptions, ToCBOROptions } from '../types';\nimport { CborItem, needsCdnItemDispatch } from './CborItem';\nimport type { AnnotatedLine } from './CborItem';\nimport { CborTextString } from './CborTextString';\nimport { MT_TEXT, AI_INDEFINITE, BREAK_CODE } from '../cbor/constants';\nimport type { CborWriter } from '../cbor/encode';\nimport {\n formatTrailingComments,\n hasPreservedComments,\n pushAll,\n serializeContainer,\n} from '../cdn/serialize-utils';\nimport { byteToHexUpper } from '../utils/hex';\n\n/** CBOR Major Type 3 — indefinite-length UTF-8 text string (chunked). */\nexport class CborIndefiniteTextString extends CborItem {\n readonly indefiniteLength = true as const;\n readonly chunks: CborTextString[];\n\n constructor(chunks: CborTextString[]) {\n super();\n this.chunks = chunks;\n }\n\n override _encodeTo(writer: CborWriter, options?: ToCBOROptions): void {\n writer.writeByte((MT_TEXT << 5) | AI_INDEFINITE);\n for (const chunk of this.chunks) chunk._encode(writer, options);\n writer.writeByte(BREAK_CODE);\n }\n\n /**\n * True when any chunk is multi-word. Reachable when this node is a\n * *direct* entry of another container (`[(_ \"two words\")]`) — though even\n * then, its own `_toCDN()` already self-disqualifies internally in that\n * case, producing a multi-line self-render that the ordinary \"entry's own\n * rendering has a line break\" check would catch regardless of what this\n * method answers, so this mostly exists for robustness/consistency with\n * `CborTextString`/`CborByteString` rather than because some case is\n * otherwise unreachable. (`CborAppSeqResult`, which wraps this node for\n * results like `ilts<<...>>`, does *not* delegate to this method — it\n * tokenizes its own rendered output directly instead; see its doc for\n * why that turned out to be necessary.) `_strict` is intentionally\n * unused: a chunk is always CborTextString, whose own word count doesn't\n * depend on it.\n */\n override _isMultiWordText(\n options: ToCDNOptions | undefined,\n _strict = true\n ): boolean {\n return this.chunks.some((c) => c._isMultiWordText(options));\n }\n\n _toCDN(\n options: ToCDNOptions | undefined,\n depth: number,\n path?: readonly unknown[]\n ): string {\n if ((options?.encodingIndicators ?? 'auto') === 'never') {\n const merged = this.chunks.map((c) => c.value).join('');\n return new CborTextString(merged)._toCDN(options, depth);\n }\n const basePath = path ?? [];\n const dispatch = needsCdnItemDispatch(options);\n const childOptions = (i: number): ToCDNOptions | undefined =>\n dispatch\n ? this.chunks[i]._resolveCdnOptions(options, [...basePath, i], {\n parent: this,\n })\n : options;\n // `ilts<<...>>` (draft-27 §3.6) replaces the legacy `(_ ...)` marker\n // notation; falls back to it when `appPrefix` disables app-string\n // notation entirely.\n const useIlts =\n !!options?.modernStreamSyntax && options?.appPrefix !== false;\n if (!useIlts && this.chunks.length === 0) return '\"\"_';\n return serializeContainer({\n node: this,\n options,\n depth,\n openChar: useIlts ? 'ilts<<' : '(',\n closeChar: useIlts ? '>>' : ')',\n count: this.chunks.length,\n indefiniteLength: true,\n indefiniteMarker: !useIlts,\n encodingWidth: undefined,\n hasEntryComments: (i) => hasPreservedComments(this.chunks[i]),\n renderEntry: (i) =>\n this.chunks[i]._toCDN(\n childOptions(i),\n depth + 1,\n dispatch ? [...basePath, i] : undefined\n ),\n // Unlike CborEmbeddedCBOR (`<<...>>`), the legacy `(_ ...)` group\n // follows the same strict rule as CborArray/CborMap, gated behind\n // inlineLeafContainers: entryIsLeaf is trivially always true (chunks\n // can never be containers), but its presence is what signals \"strict\"\n // to serializeContainer's probe. `ilts<<...>>` is itself an\n // app-sequence form, so it always collapses like\n // CborEmbeddedCBOR instead (loose rule, entryIsLeaf omitted).\n entryIsLeaf: useIlts ? undefined : () => true,\n alwaysInlineLeaf: useIlts,\n entryIsMultiWordText: (i) =>\n this.chunks[i]._isMultiWordText(\n childOptions(i),\n !useIlts,\n dispatch ? [...basePath, i] : undefined\n ),\n entryLeadingNode: (i) => this.chunks[i],\n entryTrailing: (i, style) =>\n formatTrailingComments(this.chunks[i], style),\n entryOptions: dispatch ? childOptions : undefined,\n });\n }\n\n override _toHexDump(depth: number, options?: ToCDNOptions): AnnotatedLine[] {\n const lines: AnnotatedLine[] = [\n {\n depth,\n hex: byteToHexUpper((MT_TEXT << 5) | AI_INDEFINITE),\n comment: 'Start indefinite-length text string',\n },\n ];\n for (const chunk of this.chunks)\n pushAll(lines, chunk._toHexDump(depth + 1, options));\n lines.push({ depth, hex: byteToHexUpper(BREAK_CODE), comment: '\"break\"' });\n return lines;\n }\n\n _toJS(_options?: ToJSOptions): unknown {\n return this.chunks.map((c) => c.value).join('');\n }\n}\n","import type { ToCDNOptions, ToJSOptions, ToCBOROptions } from '../types';\nimport { CBOR_OMIT } from '../types';\nimport {\n CborItem,\n needsItemDispatch,\n needsCdnItemDispatch,\n withoutReviver,\n ROOT_OCCURRENCE,\n RAW_PASS_MARKER,\n} from './CborItem';\nimport type { AnnotatedLine } from './CborItem';\nimport { MT_ARRAY, AI_INDEFINITE, BREAK_CODE } from '../cbor/constants';\nimport {\n writeHead,\n writeHeadTo,\n type CborWriter,\n type EncodingWidth,\n} from '../cbor/encode';\nimport {\n formatTrailingComments,\n hasPreservedComments,\n pushAll,\n serializeContainer,\n} from '../cdn/serialize-utils';\nimport { byteToHexUpper, bytesToSpacedHexUpper } from '../utils/hex';\n\n/** CBOR Major Type 4 — array (definite- or indefinite-length). */\nexport class CborArray extends CborItem {\n readonly items: CborItem[];\n readonly indefiniteLength: boolean;\n encodingWidth: EncodingWidth | undefined;\n\n constructor(\n items: CborItem[],\n options?: { indefiniteLength?: boolean; encodingWidth?: EncodingWidth }\n ) {\n super();\n this.items = items;\n this.indefiniteLength = options?.indefiniteLength ?? false;\n this.encodingWidth = options?.encodingWidth;\n }\n\n override get _containsCdnContainer(): boolean {\n return true;\n }\n\n override _encodeTo(writer: CborWriter, options?: ToCBOROptions): void {\n if (this.indefiniteLength) {\n writer.writeByte((MT_ARRAY << 5) | AI_INDEFINITE);\n for (const item of this.items) item._encode(writer, options);\n writer.writeByte(BREAK_CODE);\n return;\n }\n writeHeadTo(writer, MT_ARRAY, this.items.length, this.encodingWidth);\n for (const item of this.items) item._encode(writer, options);\n }\n\n override _toCDN(\n options: ToCDNOptions | undefined,\n depth: number,\n path?: readonly unknown[]\n ): string {\n const basePath = path ?? [];\n const dispatch = needsCdnItemDispatch(options);\n // Resolves itemOptions for element `i` fresh on each call — including\n // when both `renderEntry` and `entryIsMultiWordText` ask for the same\n // `i` during one parent render — rather than caching, matching this\n // whole mechanism's design (see the \"toCDN() per-item dispatch\" note\n // in CborItem.ts).\n const childOptions = (i: number): ToCDNOptions | undefined =>\n dispatch\n ? this.items[i]._resolveCdnOptions(options, [...basePath, i], {\n parent: this,\n })\n : options;\n return serializeContainer({\n node: this,\n options,\n depth,\n openChar: '[',\n closeChar: ']',\n count: this.items.length,\n indefiniteLength: this.indefiniteLength,\n encodingWidth: this.encodingWidth,\n hasEntryComments: (i) => hasPreservedComments(this.items[i]),\n renderEntry: (i) =>\n this.items[i]._toCDN(\n childOptions(i),\n depth + 1,\n dispatch ? [...basePath, i] : undefined\n ),\n entryIsLeaf: (i) => !this.items[i]._containsCdnContainer,\n entryIsMultiWordText: (i) =>\n this.items[i]._isMultiWordText(\n childOptions(i),\n true,\n dispatch ? [...basePath, i] : undefined\n ),\n entryLeadingNode: (i) => this.items[i],\n entryTrailing: (i, style) => formatTrailingComments(this.items[i], style),\n entryOptions: dispatch ? childOptions : undefined,\n });\n }\n\n override _toHexDump(depth: number, options?: ToCDNOptions): AnnotatedLine[] {\n if (this.indefiniteLength) {\n const lines: AnnotatedLine[] = [\n {\n depth,\n hex: byteToHexUpper((MT_ARRAY << 5) | AI_INDEFINITE),\n comment: 'Start indefinite-length array',\n },\n ];\n for (const item of this.items)\n pushAll(lines, item._toHexDump(depth + 1, options));\n lines.push({\n depth,\n hex: byteToHexUpper(BREAK_CODE),\n comment: '\"break\"',\n });\n return lines;\n }\n const lines: AnnotatedLine[] = [\n {\n depth,\n hex: bytesToSpacedHexUpper(\n writeHead(MT_ARRAY, BigInt(this.items.length), this.encodingWidth)\n ),\n comment: `Array of length ${this.items.length}`,\n },\n ];\n for (const item of this.items)\n pushAll(lines, item._toHexDump(depth + 1, options));\n return lines;\n }\n\n _toJS(\n options?: ToJSOptions,\n path?: readonly unknown[],\n occurrence?: readonly unknown[]\n ): unknown {\n const reviver = options?.reviver;\n const dispatch = needsItemDispatch(options);\n const occ = occurrence ?? ROOT_OCCURRENCE;\n // `rawPass` marks a call as belonging to the raw pre-population pass\n // below — its occurrence gets `RAW_PASS_MARKER` inserted (see\n // `Occurrence`) so it can never be reused by the real, revived pass,\n // even indirectly through some other, more deeply nested raw pass.\n const convert = (\n item: CborItem,\n i: number,\n opts: ToJSOptions | undefined,\n rawPass: boolean\n ) =>\n dispatch\n ? item._toJSChild(\n opts,\n [...(path ?? []), i],\n // Cache-matching identity: chained from this array's own\n // occurrence plus the element's own index, never from a\n // converted JS value — see `Occurrence`.\n rawPass ? [...occ, RAW_PASS_MARKER, i] : [...occ, i],\n { parent: this }\n )\n : item._toJS(opts);\n if (!reviver)\n return this.items.map((item, i) => convert(item, i, options, false));\n // First pass: pre-populate holder with unrevived values so later siblings\n // are still raw when earlier callbacks run (matches JSON.parse sibling\n // timing). `itemOptions`/`extensions` still apply here — see\n // `withoutReviver` — since this holder is directly observable through\n // `this[j]` inside an earlier sibling's own reviver call, not just\n // internal scaffolding; the `RAW_PASS_MARKER` in each element's\n // occurrence above keeps this pass's resolutions from being reused by\n // the real, revived pass below.\n const optNoReviver = withoutReviver(options);\n const holder: unknown[] = this.items.map((item, i) =>\n convert(item, i, optNoReviver, true)\n );\n // Second pass: revive each element depth-first, splice out undefined entries\n // immediately so `this` reflects the compacted in-progress array.\n // Original indices are used as reviver keys; undefined → omit (compact,\n // differs from JSON.parse which leaves holes).\n let deleted = 0;\n for (let i = 0; i < this.items.length; i++) {\n const hIdx = i - deleted;\n const val = convert(this.items[i], i, options, false);\n const rv = reviver.call(holder, String(i), val);\n const omit =\n rv === CBOR_OMIT || (options?.undefinedOmits && rv === undefined);\n if (omit) {\n holder.splice(hIdx, 1);\n deleted++;\n } else {\n holder[hIdx] = rv;\n }\n }\n return holder;\n }\n}\n","import type {\n CborComment,\n ToCDNOptions,\n ToJSOptions,\n ToCBOROptions,\n} from '../types';\nimport { CBOR_OMIT } from '../types';\nimport { MapEntries } from '../mapEntries';\nimport {\n CborItem,\n needsItemDispatch,\n needsCdnItemDispatch,\n withoutReviver,\n ROOT_OCCURRENCE,\n RAW_PASS_MARKER,\n} from './CborItem';\nimport type { AnnotatedLine } from './CborItem';\nimport { CborTextString } from './CborTextString';\nimport { MT_MAP, AI_INDEFINITE, BREAK_CODE } from '../cbor/constants';\nimport {\n writeHead,\n writeHeadTo,\n type CborWriter,\n type EncodingWidth,\n} from '../cbor/encode';\nimport {\n convertCommentText,\n hasPreservedComments,\n isPrefixedLiteralText,\n pushAll,\n serializeContainer,\n} from '../cdn/serialize-utils';\nimport { byteToHexUpper, bytesToSpacedHexUpper } from '../utils/hex';\n\n/** CBOR Major Type 5 — map (definite- or indefinite-length). */\nexport class CborMap extends CborItem {\n readonly entries: [CborItem, CborItem][];\n readonly indefiniteLength: boolean;\n encodingWidth: EncodingWidth | undefined;\n\n constructor(\n entries: [CborItem, CborItem][],\n options?: { indefiniteLength?: boolean; encodingWidth?: EncodingWidth }\n ) {\n super();\n this.entries = entries;\n this.indefiniteLength = options?.indefiniteLength ?? false;\n this.encodingWidth = options?.encodingWidth;\n }\n\n override get _containsCdnContainer(): boolean {\n return true;\n }\n\n override _encodeTo(writer: CborWriter, options?: ToCBOROptions): void {\n if (this.indefiniteLength) {\n writer.writeByte((MT_MAP << 5) | AI_INDEFINITE);\n for (const [k, v] of this.entries) {\n k._encode(writer, options);\n v._encode(writer, options);\n }\n writer.writeByte(BREAK_CODE);\n return;\n }\n writeHeadTo(writer, MT_MAP, this.entries.length, this.encodingWidth);\n for (const [k, v] of this.entries) {\n k._encode(writer, options);\n v._encode(writer, options);\n }\n }\n\n override _toCDN(\n options: ToCDNOptions | undefined,\n depth: number,\n path?: readonly unknown[]\n ): string {\n const basePath = path ?? [];\n const dispatch = needsCdnItemDispatch(options);\n // `entryIsMultiWordText` needs each side's own rendering (not just the\n // combined \"key: value\" string serializeContainer sees — see its\n // comment below), and `renderEntry` needs the exact same strings right\n // after — cached per index so a custom key/value's `_toCDN()` is never\n // called twice for the same render, matching serializeContainer's own\n // \"never serialize more than once per parent render\" invariant. The\n // resolved per-item options (and, for a non-text key, the `toCDN()`\n // rendering used as its path label — see `ItemContext.path`'s CDN\n // counterpart) are cached the same way, for the same reason: an\n // `itemOptions` callback should not be asked twice for one entry\n // within a single parent render just because both `renderEntry` and\n // `entryIsMultiWordText` need its result.\n const optsCache: (\n [unknown, ToCDNOptions | undefined, ToCDNOptions | undefined] | undefined\n )[] = [];\n const resolveKV = (\n i: number\n ): [unknown, ToCDNOptions | undefined, ToCDNOptions | undefined] => {\n let r = optsCache[i];\n if (!r) {\n const [k, v] = this.entries[i];\n if (!dispatch) {\n r = [undefined, options, options];\n } else {\n // Independent of `options`/depth — a stable label identifying\n // this entry's key for path purposes, same derivation `toJS()`'s\n // own object-mode key naming uses, not the entry's real render.\n const key = k instanceof CborTextString ? k.value : k.toCDN();\n r = [\n key,\n k._resolveCdnOptions(options, basePath, {\n parent: this,\n isMapKey: true,\n keyNode: k,\n }),\n v._resolveCdnOptions(options, [...basePath, key], {\n parent: this,\n keyNode: k,\n }),\n ];\n }\n optsCache[i] = r;\n }\n return r;\n };\n const kvCache: ([string, string] | undefined)[] = [];\n const renderKV = (i: number): [string, string] => {\n let kv = kvCache[i];\n if (!kv) {\n const [k, v] = this.entries[i];\n const [key, kOpts, vOpts] = resolveKV(i);\n kv = [\n k._toCDN(kOpts, depth + 1, dispatch ? basePath : undefined),\n v._toCDN(vOpts, depth + 1, dispatch ? [...basePath, key] : undefined),\n ];\n kvCache[i] = kv;\n }\n return kv;\n };\n return serializeContainer({\n node: this,\n options,\n depth,\n openChar: '{',\n closeChar: '}',\n count: this.entries.length,\n indefiniteLength: this.indefiniteLength,\n encodingWidth: this.encodingWidth,\n hasEntryComments: (i) => {\n const [key, value] = this.entries[i];\n return hasPreservedComments(key) || hasPreservedComments(value);\n },\n renderEntry: (i, colSep) => {\n const [kStr, vStr] = renderKV(i);\n return `${kStr}${colSep}${vStr}`;\n },\n entryIsLeaf: (i) => {\n const [k, v] = this.entries[i];\n return !k._containsCdnContainer && !v._containsCdnContainer;\n },\n entryIsMultiWordText: (i) => {\n const [k, v] = this.entries[i];\n const [key, kOpts, vOpts] = resolveKV(i);\n const kPath = dispatch ? basePath : undefined;\n const vPath = dispatch ? [...basePath, key] : undefined;\n if (\n k._isMultiWordText(kOpts, true, kPath) ||\n v._isMultiWordText(vOpts, true, vPath)\n )\n return true;\n // serializeContainer's own isPrefixedLiteralText check only sees a\n // map entry's combined \"key: value\" rendering, which can't tell a\n // prefixed literal in the value (or a non-leading key) apart from\n // one embedded inside the other's own quoted content — so check\n // each side's own rendering here instead, same as the multi-word\n // check above already does for text/byte strings.\n const [kStr, vStr] = renderKV(i);\n return isPrefixedLiteralText(kStr) || isPrefixedLiteralText(vStr);\n },\n // Leading comments come from the key; the value's leading comments\n // render inline after the entry (see entryTrailing).\n entryLeadingNode: (i) => this.entries[i][0],\n entryTrailing: (i, style) => {\n const [k, v] = this.entries[i];\n return formatMapEntryTrailingComments(\n [\n ...(k.comments?.trailing ?? []),\n ...(v.comments?.leading ?? []),\n ...(v.comments?.trailing ?? []),\n ],\n style\n );\n },\n // The entry's own comment handling follows the key's resolved\n // options — same as entryLeadingNode's own choice of the key as the\n // entry's leading-comment anchor.\n entryOptions: dispatch ? (i) => resolveKV(i)[1] : undefined,\n });\n }\n\n override _toHexDump(depth: number, options?: ToCDNOptions): AnnotatedLine[] {\n if (this.indefiniteLength) {\n const lines: AnnotatedLine[] = [\n {\n depth,\n hex: byteToHexUpper((MT_MAP << 5) | AI_INDEFINITE),\n comment: 'Start indefinite-length map',\n },\n ];\n for (const [k, v] of this.entries) {\n pushAll(lines, k._toHexDump(depth + 1, options));\n pushAll(lines, v._toHexDump(depth + 1, options));\n }\n lines.push({\n depth,\n hex: byteToHexUpper(BREAK_CODE),\n comment: '\"break\"',\n });\n return lines;\n }\n const lines: AnnotatedLine[] = [\n {\n depth,\n hex: bytesToSpacedHexUpper(\n writeHead(MT_MAP, BigInt(this.entries.length), this.encodingWidth)\n ),\n comment: `Map of length ${this.entries.length}`,\n },\n ];\n for (const [k, v] of this.entries) {\n pushAll(lines, k._toHexDump(depth + 1, options));\n pushAll(lines, v._toHexDump(depth + 1, options));\n }\n return lines;\n }\n\n _toJS(\n options?: ToJSOptions,\n path?: readonly unknown[],\n occurrence?: readonly unknown[]\n ): unknown {\n const reviver = options?.reviver;\n const dispatch = needsItemDispatch(options);\n const basePath = path ?? [];\n const occ = occurrence ?? ROOT_OCCURRENCE;\n const toEntries = () => {\n const convertPair = (\n k: CborItem,\n v: CborItem,\n i: number,\n opts: ToJSOptions | undefined\n ): [unknown, unknown] => {\n if (!dispatch) return [k._toJS(opts), v._toJS(opts)];\n // The key has no path segment of its own — it names the value's —\n // so it's converted first, against the parent's own path, and its\n // result becomes the value's path segment. The occurrence chains\n // (unlike path) are derived purely from this map's own occurrence\n // plus this entry's own ordinal `i`, never from the key's converted\n // JS value — see `Occurrence`.\n const kJs = k._toJSChild(opts, basePath, [...occ, `k${i}`], {\n parent: this,\n isMapKey: true,\n keyNode: k,\n });\n const vJs = v._toJSChild(opts, [...basePath, kJs], [...occ, `v${i}`], {\n parent: this,\n keyNode: k,\n });\n return [kJs, vJs];\n };\n const result = MapEntries.from(this.entries, ([k, v], i) =>\n convertPair(k, v, i, options)\n );\n if (!reviver) return result;\n const uOmits = options?.undefinedOmits;\n for (let i = 0; i < result.length; i++) {\n const [k, v] = result[i];\n const rv = reviver.call(result, k, v);\n if (rv === CBOR_OMIT || (uOmits && rv === undefined))\n result.splice(i--, 1);\n else result[i] = [k, rv];\n }\n return result;\n };\n const toObject = () => {\n // `rawPass` marks a call as belonging to the raw pre-population pass\n // below — its occurrence gets `RAW_PASS_MARKER` inserted (see\n // `Occurrence`) so it can never be reused by the real, revived pass,\n // even indirectly through some other, more deeply nested raw pass.\n const convertValue = (\n k: CborItem,\n v: CborItem,\n key: string,\n i: number,\n opts: ToJSOptions | undefined,\n rawPass: boolean\n ) =>\n dispatch\n ? v._toJSChild(\n opts,\n [...basePath, key],\n // Derived from this map's own occurrence plus this entry's\n // own ordinal `i`, not from `key` (a converted JS value) —\n // see `Occurrence`.\n rawPass ? [...occ, RAW_PASS_MARKER, `v${i}`] : [...occ, `v${i}`],\n { parent: this, keyNode: k }\n )\n : v._toJS(opts);\n // First pass: pre-populate holder with unrevived values so all sibling\n // keys are visible in `this` when reviver runs (matches JSON.parse).\n // `itemOptions`/`extensions` still apply here — see `withoutReviver`\n // — since this holder is directly observable through `this[key]`\n // inside an earlier sibling's own reviver call, not just internal\n // scaffolding; the `RAW_PASS_MARKER` in each value's occurrence above\n // keeps this pass's resolutions from being reused by the real,\n // revived pass below. When there's no reviver, this loop's result\n // *is* the final output (see `if (!reviver) return holder` below) —\n // `withoutReviver` is then a no-op (`reviver` was already unset), and\n // `rawPass` is `false` so no marker is inserted, matching that this\n // loop is not throwaway in that case.\n const optNoReviver = withoutReviver(options);\n const holder: Record<string, unknown> = {};\n for (let i = 0; i < this.entries.length; i++) {\n const [k, v] = this.entries[i];\n const key = k instanceof CborTextString ? k.value : k.toCDN();\n const raw = convertValue(k, v, key, i, optNoReviver, !!reviver);\n if (key === '__proto__') {\n Object.defineProperty(holder, key, {\n value: raw,\n writable: true,\n enumerable: true,\n configurable: true,\n });\n } else {\n holder[key] = raw;\n }\n }\n if (!reviver) return holder;\n // Second pass: process each property sequentially depth-first.\n // Only the last occurrence of each key is revived to avoid duplicate\n // callbacks when CBOR maps contain repeated keys.\n const lastIdx = new Map<string, number>();\n for (let i = 0; i < this.entries.length; i++) {\n const [k] = this.entries[i];\n lastIdx.set(k instanceof CborTextString ? k.value : k.toCDN(), i);\n }\n for (let i = 0; i < this.entries.length; i++) {\n const [k, v] = this.entries[i];\n const key = k instanceof CborTextString ? k.value : k.toCDN();\n if (lastIdx.get(key) !== i) continue;\n const val = convertValue(k, v, key, i, options, false);\n const rv = reviver.call(holder, key, val);\n const omit =\n rv === CBOR_OMIT || (options?.undefinedOmits && rv === undefined);\n if (!omit) {\n if (key === '__proto__') {\n Object.defineProperty(holder, key, {\n value: rv,\n writable: true,\n enumerable: true,\n configurable: true,\n });\n } else {\n holder[key] = rv;\n }\n } else {\n delete holder[key];\n }\n }\n return holder;\n };\n\n if (options?.mapAs === 'entries') return toEntries();\n if (options?.mapAs === 'object') return toObject();\n if (this.entries.every(([k]) => k instanceof CborTextString))\n return toObject();\n return toEntries();\n }\n}\n\nfunction formatMapEntryTrailingComments(\n comments: CborComment[],\n style?: 'c-style' | 'cdn-style'\n): string {\n if (comments.length === 0) return '';\n return (\n ' ' +\n comments\n .map((comment) => convertCommentText(comment, style).trimEnd())\n .join(' ')\n );\n}\n","import type { ToCDNOptions, ToJSOptions, ToCBOROptions } from '../types';\nimport { CborItem } from './CborItem';\nimport { Simple } from '../simple';\nimport { MT_SIMPLE, AI_1BYTE } from '../cbor/constants';\nimport type { CborWriter } from '../cbor/encode';\n\n/**\n * CBOR Major Type 7 — simple value (0–255).\n *\n * Well-known values:\n * 20 → false\n * 21 → true\n * 22 → null\n * 23 → undefined\n */\nexport class CborSimple extends CborItem {\n readonly value: number;\n /**\n * Original CDN digit spelling of the argument to `simple(...)` (base +\n * digits), set by the parser when this value came from CDN text. Used by\n * `_toCDN()` to round-trip the argument's base (`0x10`, decimal, …) when\n * `preserveNumberFormat` is set.\n */\n readonly ednSource?: string;\n\n constructor(value: number, options?: { ednSource?: string }) {\n super();\n if (!Number.isInteger(value) || value < 0 || value > 255)\n throw new RangeError('CborSimple value must be an integer in 0–255');\n this.value = value;\n this.ednSource = options?.ednSource;\n }\n\n static readonly FALSE = new CborSimple(20);\n static readonly TRUE = new CborSimple(21);\n static readonly NULL = new CborSimple(22);\n static readonly UNDEFINED = new CborSimple(23);\n\n override _encodeTo(writer: CborWriter, _options?: ToCBOROptions): void {\n // Values 0–23: encoded in the initial byte (MT7 | value)\n if (this.value <= 23) {\n writer.writeByte((MT_SIMPLE << 5) | this.value);\n return;\n }\n // Values 24–255: MT7, AI_1BYTE, then one value byte\n writer.writeByte((MT_SIMPLE << 5) | AI_1BYTE);\n writer.writeByte(this.value);\n }\n\n _toCDN(options: ToCDNOptions | undefined, _depth: number): string {\n // A value written as simple(20) etc. is a different spelling choice from\n // the false/true/null/undefined keywords, even though it denotes the\n // same value — so preserveNumberFormat must keep simple(...) notation\n // (checked before the keyword shortcuts below, which only apply to\n // values that were never parsed via simple(...) in the first place).\n if (options?.preserveNumberFormat && this.ednSource !== undefined)\n return `simple(${this.ednSource})`;\n switch (this.value) {\n case 20:\n return 'false';\n case 21:\n return 'true';\n case 22:\n return 'null';\n case 23:\n return 'undefined';\n default:\n return `simple(${this.value})`;\n }\n }\n\n _toJS(_options?: ToJSOptions): unknown {\n switch (this.value) {\n case 20:\n return false;\n case 21:\n return true;\n case 22:\n return null;\n case 23:\n return undefined;\n default:\n return new Simple(this.value);\n }\n }\n}\n","import type { ToCDNOptions, ToJSOptions, ToCBOROptions } from '../types';\nimport { CborItem, needsCdnItemDispatch } from './CborItem';\nimport type { AnnotatedLine } from './CborItem';\nimport { MT_BYTES } from '../cbor/constants';\nimport {\n writeHead,\n writeHeadTo,\n CborWriter,\n type EncodingWidth,\n} from '../cbor/encode';\nimport {\n formatTrailingComments,\n hasPreservedComments,\n pushAll,\n serializeContainer,\n} from '../cdn/serialize-utils';\nimport { bytesToSpacedHexUpper } from '../utils/hex';\n\n/**\n * CBOR Sequence Literal (§2.3.4) — `<<item, item, ...>>`.\n *\n * Encodes as a definite-length byte string whose value is the concatenation\n * of the CBOR encodings of the contained items.\n *\n * @example\n * // <<1, 2>> → h'0102'\n * new CborEmbeddedCBOR([new CborUint(1n), new CborUint(2n)])\n */\nexport class CborEmbeddedCBOR extends CborItem {\n readonly items: CborItem[];\n encodingWidth: EncodingWidth | undefined;\n\n constructor(items: CborItem[], options?: { encodingWidth?: EncodingWidth }) {\n super();\n this.items = items;\n this.encodingWidth = options?.encodingWidth;\n }\n\n override get _containsCdnContainer(): boolean {\n return this.items.some((item) => item._containsCdnContainer);\n }\n\n /** The raw concatenated CBOR bytes of all contained items. */\n private _content(options?: ToCBOROptions): Uint8Array {\n const inner = new CborWriter();\n for (const item of this.items) item._encode(inner, options);\n return inner.finish();\n }\n\n override _encodeTo(writer: CborWriter, options?: ToCBOROptions): void {\n // The head needs the content's byte length, so the items are encoded\n // into a separate buffer first.\n const content = this._content(options);\n writeHeadTo(writer, MT_BYTES, content.length, this.encodingWidth);\n writer.writeBytes(content);\n }\n\n override _toCDN(\n options: ToCDNOptions | undefined,\n depth: number,\n path?: readonly unknown[]\n ): string {\n const basePath = path ?? [];\n const dispatch = needsCdnItemDispatch(options);\n const childOptions = (i: number): ToCDNOptions | undefined =>\n dispatch\n ? this.items[i]._resolveCdnOptions(options, [...basePath, i], {\n parent: this,\n })\n : options;\n return serializeContainer({\n node: this,\n options,\n depth,\n openChar: '<<',\n closeChar: '>>',\n count: this.items.length,\n indefiniteLength: false,\n encodingWidth: this.encodingWidth,\n eiPosition: 'close',\n canonicalCount: () => BigInt(this._content(options).length),\n hasEntryComments: (i) => hasPreservedComments(this.items[i]),\n renderEntry: (i) =>\n this.items[i]._toCDN(\n childOptions(i),\n depth + 1,\n dispatch ? [...basePath, i] : undefined\n ),\n // entryIsLeaf is intentionally omitted (defaults to \"always a leaf\"):\n // unlike CborArray/CborMap, an item that is itself an array/map still\n // inlines here as long as its own rendering fits on one line — <<...>>\n // is a flat sequence of encoded items, not a nested-structure display.\n // alwaysInlineLeaf: this collapse isn't gated behind\n // inlineLeafContainers at all — there's no structural reason to ever\n // spread a flat encoded-item sequence one item per line if it fits.\n alwaysInlineLeaf: true,\n entryIsMultiWordText: (i) =>\n this.items[i]._isMultiWordText(\n childOptions(i),\n false,\n dispatch ? [...basePath, i] : undefined\n ),\n entryLeadingNode: (i) => this.items[i],\n entryTrailing: (i, style) => formatTrailingComments(this.items[i], style),\n entryOptions: dispatch ? childOptions : undefined,\n });\n }\n\n override _toHexDump(depth: number, options?: ToCDNOptions): AnnotatedLine[] {\n const content = this._content();\n const n = content.length;\n const lines: AnnotatedLine[] = [\n {\n depth,\n hex: bytesToSpacedHexUpper(\n writeHead(MT_BYTES, BigInt(n), this.encodingWidth)\n ),\n comment: `Embedded CBOR sequence, ${n} byte${n !== 1 ? 's' : ''}`,\n },\n ];\n for (const item of this.items) {\n pushAll(lines, item._toHexDump(depth + 1, options));\n }\n return lines;\n }\n\n _toJS(_options?: ToJSOptions): unknown {\n return this._content();\n }\n}\n","/**\n * Strip whitespace and EDN §2.1 comments from app-string content.\n *\n * Used by extensions whose content allows the same comment syntax as byte\n * string literals (b32, h32, float, …):\n * SP / LF / CR — whitespace, skipped\n * # … LF — line comment\n * // … LF — line comment\n * /* … *\\/ — block comment (unterminated → SyntaxError)\n * / … / — block comment (unterminated → SyntaxError)\n */\nexport function stripComments(str: string): string {\n let out = '';\n let i = 0;\n while (i < str.length) {\n const ch = str[i];\n if (ch === ' ' || ch === '\\n' || ch === '\\r') {\n i++;\n continue;\n }\n if (ch === '#') {\n while (i < str.length && str[i] !== '\\n') i++;\n continue;\n }\n if (ch === '/') {\n const next = str[i + 1] ?? '';\n if (next === '/') {\n while (i < str.length && str[i] !== '\\n') i++;\n continue;\n }\n if (next === '*') {\n i += 2;\n while (\n i < str.length &&\n !(str[i] === '*' && (str[i + 1] ?? '') === '/')\n )\n i++;\n if (i >= str.length)\n throw new SyntaxError('unterminated block comment');\n i += 2; // consume */\n continue;\n }\n // / … / block comment\n i++;\n while (i < str.length && str[i] !== '/') i++;\n if (i >= str.length) throw new SyntaxError('unterminated block comment');\n i++; // consume closing /\n continue;\n }\n out += ch;\n i++;\n }\n return out;\n}\n","import type { CborExtension } from './types';\nimport { CborByteString } from '../ast/CborByteString';\nimport { stripComments } from '../utils/strip-comments';\n\nconst B32_ALPHA = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567';\nconst H32_ALPHA = '0123456789ABCDEFGHIJKLMNOPQRSTUV';\n\nfunction stripBase32Padding(str: string): string {\n let end = str.length;\n while (end > 0 && str.charCodeAt(end - 1) === 0x3d) end--;\n return str.slice(0, end);\n}\n\nfunction base32Decode(\n str: string,\n alpha: string,\n onError?: (msg: string) => void\n): Uint8Array {\n // Padding is optional; strip it before decoding.\n const s = stripBase32Padding(str).toUpperCase();\n // RFC 4648 §6: valid unpadded lengths mod 8 are 0, 2, 4, 5, 7.\n // Lengths 1, 3, 6 can never result from any valid byte sequence.\n const rem = s.length % 8;\n if (rem === 1 || rem === 3 || rem === 6)\n throw new SyntaxError(`invalid base32 length: ${s.length} characters`);\n const lookup = new Uint8Array(128).fill(0xff);\n for (let i = 0; i < alpha.length; i++) lookup[alpha.charCodeAt(i)] = i;\n const out = new Uint8Array(Math.floor((s.length * 5) / 8));\n let buf = 0,\n bufBits = 0,\n outIdx = 0;\n for (const ch of s) {\n const code = ch.charCodeAt(0);\n const val = code < 128 ? lookup[code] : 0xff;\n if (val === 0xff)\n throw new SyntaxError(\n `invalid character in byte string: ${JSON.stringify(ch)}`\n );\n buf = (buf << 5) | val;\n bufBits += 5;\n if (bufBits >= 8) {\n bufBits -= 8;\n out[outIdx++] = (buf >> bufBits) & 0xff;\n }\n }\n // RFC 4648 §3.5: trailing bits in the final quantum must be zero.\n if (bufBits > 0 && (buf & ((1 << bufBits) - 1)) !== 0) {\n const msg = 'non-zero trailing bits in base32 input';\n if (onError) onError(msg);\n else throw new SyntaxError(msg);\n }\n return out;\n}\n\n/** RFC 4648 §6 Base32 (A–Z 2–7) app-string extension. */\nexport const b32: CborExtension = {\n appStringPrefixes: ['b32'],\n parseAppString(_prefix, content, onError) {\n return new CborByteString(\n base32Decode(stripComments(content), B32_ALPHA, onError),\n {\n ednEncoding: 'base32',\n }\n );\n },\n};\n\n/** RFC 4648 §7 Base32Hex (0–9 A–V) app-string extension. */\nexport const h32: CborExtension = {\n appStringPrefixes: ['h32'],\n parseAppString(_prefix, content, onError) {\n return new CborByteString(\n base32Decode(stripComments(content), H32_ALPHA, onError),\n {\n ednEncoding: 'base32hex',\n }\n );\n },\n};\n","/**\n * §5.1 of draft-ietf-cbor-edn-literals-27 — Stand-in for unknown app-extensions.\n *\n * When the CDN parser encounters an unrecognised app-extension\n * identifier (the default `unresolvedExtension: 'cpa999'` behaviour), it wraps\n * the literal in a CPA999 tag instead of throwing a SyntaxError.\n *\n * Structure:\n * CPA999([<prefix>, [<content-items...>]])\n *\n * Examples:\n * cri'https://example.com' → CPA999([\"cri\", [\"https://example.com\"]])\n * hash<<\"data\", -44>> → CPA999([\"hash\", [\"data\", -44]])\n *\n * toCDN() reconstructs the original app-string / app-sequence notation:\n * CPA999([\"cri\", [\"https://example.com\"]]) → cri'https://example.com'\n * CPA999([\"hash\", [\"data\", -44]]) → hash<<\"data\", -44>>\n *\n * Note: CPA999 is a provisional tag number (CPA = Code Point Allocation).\n * It will be replaced by an IANA-assigned tag number upon RFC publication.\n */\n\nimport type { ToCDNOptions } from '../types';\nimport { CborTag } from './CborTag';\nimport { CborArray } from './CborArray';\nimport { CborTextString } from './CborTextString';\nimport type { CborItem } from './CborItem';\nimport { escapeAppString } from '../cdn/serialize-utils';\n\n/** Provisional tag number for the Unresolved App-Extension stand-in. */\nexport const CPA999_TAG = 999n;\n\n/**\n * Stand-in for an unrecognised EDN app-extension literal.\n *\n * Structure:\n * App-string: CPA999([prefix, text])\n * App-sequence: CPA999([prefix, [items...]])\n */\nexport class CborUnresolvedAppExt extends CborTag {\n constructor(prefix: string, items: CborItem[]) {\n // App-string: single text item → tag(999, [prefix, text])\n // App-sequence: otherwise → tag(999, [prefix, [items...]])\n const content =\n items.length === 1 && items[0] instanceof CborTextString\n ? items[0]\n : new CborArray(items);\n super(CPA999_TAG, new CborArray([new CborTextString(prefix), content]));\n }\n\n override _toCDN(options: ToCDNOptions | undefined, depth: number): string {\n if (options?.appPrefix === false) return super._toCDN(options, depth);\n\n const arr = this.content as CborArray;\n const prefix = (arr.items[0] as CborTextString).value;\n const contentItem = arr.items[1];\n\n // Text string → reconstruct app-string form: prefix'content'\n if (contentItem instanceof CborTextString) {\n return `${prefix}${escapeAppString(contentItem.value)}`;\n }\n\n // Array → reconstruct app-sequence form: prefix<<item, item, ...>>\n const contentArr = contentItem as CborArray;\n const inner = contentArr.items\n .map((item) => item._toCDN(options, depth))\n .join(', ');\n return `${prefix}<<${inner}>>`;\n }\n}\n","import type { ToCDNOptions, ToCBOROptions, ToJSOptions } from '../types';\nimport {\n CborItem,\n needsItemDispatch,\n needsCdnItemDispatch,\n ROOT_OCCURRENCE,\n CDN_OVERRIDE_TRACKER,\n} from './CborItem';\nimport type { Occurrence, CdnOverrideTrackerBox } from './CborItem';\nimport type { CborWriter } from '../cbor/encode';\nimport {\n isMultiWordRenderedLiteral,\n resolveIndent,\n} from '../cdn/serialize-utils';\n\n/**\n * Wraps a resolved app-sequence result and preserves the original EDN source\n * text for round-trip fidelity.\n *\n * In the default `encodingIndicators: 'auto'` mode, `_toCDN` returns the\n * stored source text verbatim. For `'always'` and `'never'`, it delegates to\n * the resolved item so the option is applied recursively to every data item;\n * preserving the source verbatim would leave nested indicators unchanged.\n * In single-line output (no `indent`), a source spelling that spans multiple\n * lines also delegates to the inner item, since it cannot be re-emitted\n * without breaking the single-line guarantee.\n *\n * When `toCDN()`'s `itemOptions` is configured (see `needsCdnItemDispatch`),\n * the verbatim `ednSource` fast path alone can't be trusted: it was produced\n * without ever visiting `this.inner`'s own descendants, so an override\n * targeting one of them (e.g. one chunk of an `ilbs<<...>>`) would otherwise\n * never even be offered the chance to apply. But merely *having* `itemOptions`\n * configured must not by itself change the output — many callers set it\n * without it ever matching anything in this particular subtree, and\n * `itemOptions` returning `undefined` everywhere is documented to mean \"no\n * change\" (see `CdnItemContext`). So this renders through the normal\n * recursive path while tracking, via `CDN_OVERRIDE_TRACKER` (an out-of-band\n * symbol key, *not* a wrapped `itemOptions` — wrapping it would make\n * `ctx.options.itemOptions` a different function for every descendant here\n * than everywhere else in the tree, observable even to a pure callback),\n * whether any call in the subtree actually returned an override, and only\n * swaps in that freshly rendered text when one did; otherwise the exact\n * preserved `ednSource` is still returned.\n *\n * Each `_toCDN()` call installs its *own fresh* tracker box before\n * recursing, rather than reusing whatever tracker it was handed — reusing\n * one directly would let an override applied by some unrelated part of the\n * tree that merely happens to share the same ambient `options` object (a\n * later sibling reached through the same `itemOptions`, say) falsely mark\n * *this* wrapper's own verbatim source as stale. But a genuinely *nested*\n * app-sequence (e.g. a custom `wrap<<ilbs<<h'61'>>>>` extension wrapping an\n * `ilbs<<...>>` result) must still have its own outer verbatim source\n * abandoned when the inner wrapper's own tracked render found something to\n * apply — an inner override changes what the outer source would need to\n * embed too. So once this call's own local tracker comes back `applied`,\n * that fact is additionally bubbled up to whichever ancestor tracker (if\n * any) this call itself received via `options` — the exact wrapper this\n * call is nested inside, never a sibling reached only through shared\n * top-level `options`.\n *\n * CBOR encoding and JS conversion always delegate to the inner item so the\n * wrapper is fully transparent for those operations.\n */\nexport class CborAppSeqResult extends CborItem {\n constructor(\n readonly inner: CborItem,\n readonly ednSource: string\n ) {\n super();\n }\n\n override get _containsCdnContainer(): boolean {\n return this.inner._containsCdnContainer;\n }\n\n /**\n * Same approach as `CborTag`: tokenize this wrapper's own `_toCDN()`\n * output rather than delegating to `this.inner._isMultiWordText()`.\n * Delegating to `this.inner` was tried and found wrong: for\n * `ilbs<<h'68656c6c6f20776f726c64'>>`, the chunk's raw bytes decode to\n * printable \"hello world\", so `this.inner`'s own semantic check reports\n * it as multi-word — but the *actual* rendering is the preserved\n * `ilbs<<...>>` app-sequence spelling, where that chunk appears as a\n * `h'...'` literal, never as decoded text; the semantic prediction and\n * the real output disagree. Tokenizing `this._toCDN()` directly sees\n * whichever one actually happens: the preserved `ednSource` verbatim\n * (`isMultiWordRenderedLiteral` peels the `prefix<<...>>` wrapper and\n * checks each item under the loose rule, same as `<<...>>` — a\n * multi-word text item like `ilts<<\"two words\">>` still always counts,\n * a prefixed-literal item like `ilbs<<h'00'>>` does not) or, in the\n * 'always'/'never' `encodingIndicators` modes, a pure passthrough to\n * `this.inner._toCDN()` with no extra wrapping (any node needing that to\n * be caught, like a self-disqualifying `CborIndefiniteByteString`, has\n * already produced a `\\n` in that string, which the caller's own\n * `s.includes('\\n')` check picks up independently either way).\n */\n override _isMultiWordText(\n options: ToCDNOptions | undefined,\n strict = true,\n path?: readonly unknown[]\n ): boolean {\n return isMultiWordRenderedLiteral(this._toCDN(options, 0, path), strict);\n }\n\n override _encodeTo(writer: CborWriter, options?: ToCBOROptions): void {\n this.inner._encode(writer, options);\n }\n\n _toCDN(\n options: ToCDNOptions | undefined,\n depth: number,\n path?: readonly unknown[]\n ): string {\n const mode = options?.encodingIndicators ?? 'auto';\n const sourceEligible =\n options?.appPrefix !== false &&\n mode === 'auto' &&\n (resolveIndent(options) !== null || !/[\\r\\n]/.test(this.ednSource));\n if (!sourceEligible)\n // Transparent wrapper — the inner item shares this wrapper's own path\n // (see CdnItemContext.path) and gets its own itemOptions resolved\n // against it (`_resolveCdnOptions` is a no-op when itemOptions isn't\n // in play, so this is always safe to call).\n return this.inner._toCDN(\n this.inner._resolveCdnOptions(options, path ?? [], { parent: this }),\n depth,\n path\n );\n if (!needsCdnItemDispatch(options)) return this.ednSource;\n // itemOptions is configured, so some descendant *could* override\n // something the verbatim source doesn't reflect — but \"undefined\n // everywhere = no change\" must still hold. Render through the normal\n // recursive path while tracking, via the `CDN_OVERRIDE_TRACKER`\n // out-of-band box (not a wrapped `itemOptions` — see this class's own\n // doc for why that's observably different from the real thing), whether\n // any call in the subtree actually returned a non-undefined override;\n // only then is it safe to decide between the freshly rendered text (an\n // override applied) and the still-exact preserved source (none did).\n //\n // The ancestor tracker (if this call is itself nested inside another\n // app-sequence wrapper's own tracked render) is captured *before* it's\n // shadowed below, so a genuine override found only once this call\n // recurses into `this.inner` can still be bubbled up to it afterwards —\n // see this class's own doc.\n const ancestorTracker = (\n options as ToCDNOptions & {\n [CDN_OVERRIDE_TRACKER]?: CdnOverrideTrackerBox;\n }\n )[CDN_OVERRIDE_TRACKER];\n const tracker: CdnOverrideTrackerBox = { applied: false };\n const tracked: ToCDNOptions & {\n [CDN_OVERRIDE_TRACKER]?: CdnOverrideTrackerBox;\n } = {\n ...options,\n [CDN_OVERRIDE_TRACKER]: tracker,\n };\n const rendered = this.inner._toCDN(\n this.inner._resolveCdnOptions(tracked, path ?? [], { parent: this }),\n depth,\n path\n );\n if (tracker.applied && ancestorTracker) ancestorTracker.applied = true;\n return tracker.applied ? rendered : this.ednSource;\n }\n\n _toJS(\n options?: ToJSOptions,\n path?: readonly unknown[],\n occurrence?: Occurrence\n ): unknown {\n // Transparent wrapper — the inner item shares this wrapper's own path\n // (see ItemContext.path) and its own cache-matching identity (see\n // Occurrence) unchanged.\n return needsItemDispatch(options)\n ? this.inner._toJSChild(\n options,\n path ?? [],\n occurrence ?? ROOT_OCCURRENCE,\n { parent: this }\n )\n : this.inner._toJS(options);\n }\n}\n","/**\n * §5.2 of draft-ietf-cbor-edn-literals-27 — Ellipsis (Elision) tag.\n *\n * Two forms:\n * 888(null) — subtree elision: a whole data item replaced by ...\n * 888([frag, 888(null), frag, ...])\n * — string/bytes elision: fragments alternating with ellipses\n *\n * Note: CPA888 is a provisional tag number.\n */\n\nimport type { ToCDNOptions } from '../types';\nimport { CborTag } from './CborTag';\nimport { CborArray } from './CborArray';\nimport { CborByteString } from './CborByteString';\nimport { CborTextString } from './CborTextString';\nimport { CborSimple } from './CborSimple';\nimport type { CborItem } from './CborItem';\nimport { bytesToHex } from '../utils/hex';\nimport {\n escapeString,\n resolveIndent,\n serializeBytes,\n stripByteLiteralComments,\n convertCommentText,\n danglingCommentsByGap,\n joinConcatParts,\n joinAppSeqParts,\n shouldEmitComments,\n resolveCommentStyle,\n type ByteCommentSyntax,\n} from '../cdn/serialize-utils';\n\nexport const CPA888_TAG = 888n;\n\n/**\n * Comments between two top-level `items` entries (a real `+` the parser\n * never fused away — see `CborByteString.ednParts`/`CborTextString\n * .ednPartSpans` for the case where two literals *did* fuse into one node\n * with no per-part AST node of their own) land on one of them as ordinary\n * `leading`/`trailing`, exactly like any other array entry: `attachComments`\n * runs generically over the whole tree, and both entries are real\n * `CborItem`s once the parser stamps their `start`/`end`.\n */\nfunction boundaryComments(\n prev: CborItem,\n next: CborItem,\n preserveComments: boolean,\n style: 'c-style' | 'cdn-style' | undefined\n): string[] {\n if (!preserveComments) return [];\n return [\n ...(prev.comments?.trailing ?? []).map((c) => convertCommentText(c, style)),\n ...(next.comments?.leading ?? []).map((c) => convertCommentText(c, style)),\n ];\n}\n\n/**\n * Join elision fragments with `+`. Elision is compact/single-line by\n * default — an abbreviated, inherently short summary of the underlying\n * value, not something meant to be reflowed across lines — but reflows\n * across multiple lines, one fragment per line like a real `+`\n * concatenation, when `indent` is enabled *and* there's a *mid-chain*\n * comment to preserve: a single line has nowhere to put a `#`/`//` line\n * comment sitting between two fragments (it has no way to terminate before\n * the rest of the chain), and a block comment kept inline there would be\n * indistinguishable from one actually written that way. With nothing to\n * preserve, or with `indent` disabled (nothing can safely hold a newline),\n * the whole chain still collapses onto one line and any such comment is\n * dropped — matching every other comment kind in single-line output.\n *\n * A comment trailing the *whole* chain needs none of this: it's promoted\n * onto this `CborEllipsis`'s own `comments.trailing` by the parser (see\n * `promoteEllipsisTailComments`), so the ordinary `entryTrailing`/root-\n * `toCDN()` machinery appends it after the rendered body — on the same\n * line if the body stayed single-line, which is always safe since nothing\n * else follows it there.\n */\nfunction joinElisionParts(\n rendered: readonly string[],\n gapComments: readonly (readonly string[])[],\n indentStr: string | null,\n depth: number\n): string {\n if (indentStr === null || !gapComments.some((g) => g.length > 0)) {\n return rendered.join(' + ');\n }\n return joinConcatParts(rendered, indentStr, depth, gapComments);\n}\n\n/**\n * Resolve a preserved source spelling: strip any embedded comment unless\n * comments are requested (`preserveComments`/`comments`) — a preserved\n * spelling should still drop comments by default, the same as an\n * unpreserved literal re-derived from\n * its decoded value would — then, only when the (possibly stripped) result\n * is safe to re-emit verbatim, return it. It's safe when `indent` enables\n * multi-line output, or it doesn't actually contain a newline itself\n * (interior whitespace, or a surviving `#`/`//` line comment) — otherwise it\n * would break `ToCDNOptions.indent`'s single-line guarantee. Mirrors\n * `CborByteString`/`CborTextString`'s own preserved-source fallback check.\n * Returns `undefined` when `source` is `undefined`, or isn't usable.\n */\nfunction preservedSource(\n source: string | undefined,\n options: ToCDNOptions | undefined,\n indentStr: string | null,\n commentSyntax: ByteCommentSyntax | undefined\n): string | undefined {\n if (source === undefined) return undefined;\n const stripped =\n shouldEmitComments(options) || commentSyntax === undefined\n ? source\n : stripByteLiteralComments(source, commentSyntax);\n return isSafeForCurrentMode(stripped, indentStr) ? stripped : undefined;\n}\n\n/**\n * Like `preservedSource`, but for a text source (`CborTextString`'s\n * `ednPartSources`) — text literals have no embedded-comment notation to\n * strip (a `#`/`//` there is just literal text content), so this only\n * applies the single-line safety check.\n */\nfunction usableTextSource(\n source: string | undefined,\n indentStr: string | null\n): source is string {\n return source !== undefined && isSafeForCurrentMode(source, indentStr);\n}\n\nfunction isSafeForCurrentMode(\n source: string,\n indentStr: string | null\n): boolean {\n return indentStr !== null || !/[\\r\\n]/.test(source);\n}\n\nexport class CborEllipsis extends CborTag {\n /**\n * For the array (string/bytes elision) form: `realBoundary[i]` is `true`\n * when a genuine `+` from the source precedes `items[i]` — as opposed to\n * `items[i]` sitting *inside* a single `h'xx...yy'` literal's own `...`\n * notation (index 0's value is never consulted — there is nothing before\n * the first item). `preserveConcatenation` uses this to show only the\n * real boundaries and fuse everything else, exactly as each source\n * literal was spelled.\n *\n * `undefined` means no boundary information is available at all (e.g.\n * reconstructed from raw CBOR bytes, which carry no notion of \"was there\n * a `+` here\" to begin with) — `preserveConcatenation` then has no effect,\n * the same as for a value that didn't originate from CDN source.\n */\n readonly realBoundary: readonly boolean[] | undefined;\n\n /**\n * For a subtree-elision placeholder (`888(null)`, i.e. `content\n * instanceof CborSimple`) that sits *inside* another `CborEllipsis`'s\n * items: `true` when it came from a `h'xx...yy'`-family literal's own\n * `...` notation — even a fully-elided `h'...'` with no hex digits at all\n * — as opposed to a bare standalone `...` token. Only consulted when this\n * placeholder ends up isolated as its own preserved fragment (nothing to\n * fuse it with on either side), to pick the right spelling: `h'...'` vs\n * plain `...`.\n */\n readonly fromByteLiteral: boolean;\n\n /**\n * When `fromByteLiteral` is `true`: that `h'xx...yy'`-family literal's own\n * raw source text (e.g. `h'AB...CD'` verbatim — case, interior whitespace,\n * and any `/ ... /`/`# ...` comments included), for `preserveByteString`\n * to round-trip instead of re-emitting a freshly lower-cased, comment-free\n * `h'...'` literal. `undefined` when `fromByteLiteral` is `false`.\n */\n readonly literalSource: string | undefined;\n\n /** Subtree elision: 888(null) */\n constructor(fromByteLiteral?: boolean, literalSource?: string);\n /** String/bytes elision: 888([items...]) */\n constructor(items: CborItem[], realBoundary?: readonly boolean[]);\n constructor(\n itemsOrFromByteLiteral?: CborItem[] | boolean,\n realBoundaryOrLiteralSource?: readonly boolean[] | string\n ) {\n if (Array.isArray(itemsOrFromByteLiteral)) {\n super(CPA888_TAG, new CborArray(itemsOrFromByteLiteral));\n this.fromByteLiteral = false;\n this.literalSource = undefined;\n this.realBoundary = realBoundaryOrLiteralSource as\n readonly boolean[] | undefined;\n } else {\n super(CPA888_TAG, CborSimple.NULL);\n this.fromByteLiteral = itemsOrFromByteLiteral ?? false;\n this.literalSource = realBoundaryOrLiteralSource as string | undefined;\n this.realBoundary = undefined;\n }\n }\n\n override _toCDN(options: ToCDNOptions | undefined, depth: number): string {\n if (options?.appPrefix === false) return super._toCDN(options, depth);\n if (this.content instanceof CborSimple) {\n // Subtree elision → \"...\"\n return '...';\n }\n if (this.content instanceof CborArray) {\n const preserveConcat = !!options?.preserveConcatenation;\n if (\n preserveConcat ||\n (options?.preserveByteString && !this._hasRealConcatenation())\n ) {\n // Show only the real `+` boundaries, fusing everything else exactly\n // as each source literal (e.g. a `h'xx...yy'`, however its own\n // `...` is positioned) was spelled — see `realBoundary`. With no\n // real boundary at all, this is just the one literal's own spelling.\n const preserved = this._renderPreservedBytesElision(options, depth);\n if (preserved !== undefined) return preserved;\n }\n if (!preserveConcat || this.realBoundary === undefined) {\n // Bytes elision where every fragment is a plain byte string: re-emit\n // the compact `h'xx...yy'` literal — the actual CDN grammar for this\n // (§5.2) — instead of expanding it into `h'xx' + ... + h'yy'`. Always\n // hex, regardless of `bstrEncoding`/`sqstr`: `h'...'` is the only\n // elidable literal form: there is no elided base64 or sqstr spelling.\n // Also the fallback when `preserveConcatenation` is set but there is\n // no boundary information to preserve in the first place.\n const compactHex = this._compactHexElided();\n if (compactHex !== undefined) return compactHex;\n }\n // Otherwise (text elision, or bytes elision mixed with something\n // else): frag + ... + frag, single-line unless a comment needs the\n // extra room — see `joinElisionParts`. Under `modernConcat`, the same\n // fragments become one flat `t1<<frag, ..., frag>>` / `b1<<...>>`\n // argument list instead (`...` renders as the literal ellipsis\n // argument concat.ts's own grammar accepts) — unlike the plain\n // (non-elision) concatenation case, this isn't gated on\n // `preserveConcatenation`: an elision chain has no \"collapsed single\n // literal\" state to fall back to in the first place (the `...` denotes\n // genuinely unknown content, so it always renders as multiple parts —\n // see `preserveConcat` only ever affecting *how much* of a fragment's\n // own internal boundary is shown, e.g. `_renderFragment` vs a fused\n // fragment's own plain `_toCDN()`, never *whether* the top-level chain\n // itself is shown as multiple parts).\n const items = this.content.items;\n const parts = items.map((item) =>\n preserveConcat\n ? this._renderFragment(item, options, depth)\n : item._toCDN(options, depth)\n );\n const preserveComments = shouldEmitComments(options);\n const style = resolveCommentStyle(options);\n const gapComments = items\n .slice(1)\n .map((item, i) =>\n boundaryComments(items[i]!, item, preserveComments, style)\n );\n if (options?.modernConcat) {\n // A group already collapsed to the compact `h'xx...yy'` form (via\n // `_compactHexElided`) never reaches here — only a byte fragment\n // that survives *uncollapsed* (mixed with a text fragment, or with\n // an ellipsis this function doesn't know is byte-typed) counts\n // toward \"every real fragment is byte-typed\" for prefix selection.\n const isByteOnly = items.every(\n (item) =>\n item instanceof CborByteString ||\n (item instanceof CborEllipsis && item.content instanceof CborSimple)\n );\n return joinAppSeqParts(\n isByteOnly ? 'b1' : 't1',\n parts,\n '',\n resolveIndent(options),\n depth,\n gapComments\n );\n }\n return joinElisionParts(\n parts,\n gapComments,\n resolveIndent(options),\n depth\n );\n }\n return super._toCDN(options, depth);\n }\n\n /**\n * `true` when this bytes elision has at least one real `+` boundary\n * somewhere — as opposed to being a single `h'xx...yy'` literal's own\n * `...` notation, which is not \"produced by + concatenation\" (see\n * `preserveByteString`'s own docs) and so has its spelling preserved by\n * `preserveByteString` alone, the same as a non-elided `h'...'` literal.\n *\n * A real boundary can hide two ways: as `realBoundary[i]` (`i > 0`) on the\n * items array itself, or *inside* a merged `CborByteString` whose\n * `ednParts.length > 1` — two `+`-joined literals that sat next to each\n * other with no ellipsis between them (e.g. `h'AB' + h'CD...EF'`) merge\n * into one item during parsing, so their boundary doesn't show up in\n * `realBoundary` at that item's own index.\n */\n private _hasRealConcatenation(): boolean {\n if (this.realBoundary?.some((real, i) => i > 0 && real)) return true;\n const items = (this.content as CborArray).items;\n return items.some(\n (item) =>\n item instanceof CborByteString &&\n item.ednParts !== undefined &&\n item.ednParts.length > 1\n );\n }\n\n /**\n * Render one elision fragment as it should appear under\n * `preserveConcatenation`: a merged multi-part `CborTextString` (see the\n * parser's `currentParts` consolidation) is expanded back into its\n * original `+`-joined literals, single-line, honoring `preserveRawString`\n * per part. Anything else (a single-part fragment, or a nested\n * `CborEllipsis`) renders normally.\n *\n * Only reached for text elision (or anything not shaped like a pure bytes\n * elision, or a bytes elision with no `realBoundary` information) —\n * `_renderPreservedBytesElision` handles the bytes case that has that\n * information, since it needs to see all the fragments together to know\n * which `...`s are real `+`-joined ellipses and which are internal to one\n * `h'...'` literal.\n */\n private _renderFragment(\n item: CborItem,\n options: ToCDNOptions | undefined,\n depth: number\n ): string {\n const indentStr = resolveIndent(options);\n const preserveComments = shouldEmitComments(options);\n const style = resolveCommentStyle(options);\n // `options?.appPrefix === false` already returned via `super._toCDN`\n // before any caller reaches `_renderFragment` — see this class's own\n // `_toCDN` — so `modernConcat` alone is sufficient here.\n const useT1B1 = !!options?.modernConcat;\n if (\n item instanceof CborByteString &&\n item.ednParts !== undefined &&\n item.ednParts.length > 1\n ) {\n const encoding =\n options?.appPrefix === false\n ? 'hex'\n : (options?.bstrEncoding ?? item.ednEncoding);\n const literals = item.ednParts.map((part) => {\n const source = options?.preserveByteString\n ? preservedSource(part.source, options, indentStr, part.commentSyntax)\n : undefined;\n return source !== undefined\n ? source\n : serializeBytes(part.bytes, encoding, options?.sqstr);\n });\n // These parts merged into one `CborByteString` with no per-part AST\n // node of their own — see `_renderPreservedBytesElision`'s equivalent\n // comment — so a comment between two of them landed as `dangling` on\n // `item` as a whole instead.\n const internalGaps = preserveComments\n ? (danglingCommentsByGap(\n item.comments?.dangling,\n item.ednParts,\n style\n ) ?? [])\n : [];\n // Rendered directly here (rather than delegating to `item._toCDN()`,\n // which already knows how to expand its own `ednParts` under\n // `modernConcat` — see `CborByteString.ts`) because that expansion is\n // gated behind multi-line `indent` there, while an elision fragment's\n // own part boundaries must show regardless of indent, same as the\n // legacy `+` case just below.\n return useT1B1\n ? joinAppSeqParts('b1', literals, '', indentStr, depth, internalGaps)\n : joinElisionParts(literals, internalGaps, indentStr, depth);\n }\n if (\n item instanceof CborTextString &&\n item.ednParts !== undefined &&\n item.ednParts.length > 1\n ) {\n const partSources = options?.preserveRawString\n ? item.ednPartSources\n : undefined;\n const literals = item.ednParts.map((text, i) => {\n const source = partSources?.[i];\n return usableTextSource(source, indentStr)\n ? source\n : escapeString(text);\n });\n const internalGaps = preserveComments\n ? (danglingCommentsByGap(\n item.comments?.dangling,\n item.ednPartSpans,\n style\n ) ?? [])\n : [];\n return useT1B1\n ? joinAppSeqParts('t1', literals, '', indentStr, depth, internalGaps)\n : joinElisionParts(literals, internalGaps, indentStr, depth);\n }\n return item._toCDN(options, depth);\n }\n\n /**\n * Re-emit a `888([...])` bytes elision as a single `h'xx...yy'` literal\n * when every item is either a plain `CborByteString` fragment or a\n * subtree-elision placeholder (`888(null)`) — i.e. exactly what\n * `h'xx...yy'` parses into. Returns `undefined` when the items don't\n * match that shape (e.g. text-string elision, or a fragment that isn't a\n * plain byte string), so the caller falls back to the `frag + ... + frag`\n * form.\n */\n private _compactHexElided(): string | undefined {\n const items = (this.content as CborArray).items;\n let hex = '';\n let hasByteFragment = false;\n for (const item of items) {\n if (item instanceof CborByteString) {\n hex += bytesToHex(item.value);\n hasByteFragment = true;\n } else if (\n item instanceof CborEllipsis &&\n item.content instanceof CborSimple\n ) {\n hex += '...';\n } else {\n return undefined;\n }\n }\n // Without an actual byte fragment (e.g. the single-item `888([888(null)])`\n // form), there's nothing bytes-specific to show; fall back to the plain\n // `frag + ... + frag` path, which collapses a lone item to just `...`.\n if (!hasByteFragment) return undefined;\n return `h'${hex}'`;\n }\n\n /**\n * `preserveConcatenation` rendering for a bytes elision. Groups the\n * fragments at every *real* boundary (`realBoundary[i]`) and renders each\n * group as one unit — fusing together whatever sits between real\n * boundaries, including any `h'xx...yy'` literal's own internal `...`\n * (wherever it's positioned — leading, trailing, or in the middle) and\n * the fragments on either side of it, exactly as that literal was\n * written. Within a group, a `CborByteString` that itself merged several\n * `+`-joined literals (`ednParts.length > 1`, always a real boundary\n * internally — see the parser) is further split at each of those parts.\n *\n * Returns `undefined` when there's no `realBoundary` to work from, or an\n * item isn't a plain `CborByteString` or subtree-elision placeholder\n * (e.g. text elision), so the caller falls back to the compact literal or\n * the simpler per-fragment `frag + ... + frag` rendering.\n */\n private _renderPreservedBytesElision(\n options: ToCDNOptions | undefined,\n depth: number\n ): string | undefined {\n if (this.realBoundary === undefined) return undefined;\n const boundary = this.realBoundary;\n const items = (this.content as CborArray).items;\n\n type Segment =\n | {\n bytes: Uint8Array;\n source?: string;\n commentSyntax?: ByteCommentSyntax;\n }\n | { ellipsis: true; fromByteLiteral: boolean; literalSource?: string };\n const groups: Segment[][] = [];\n // `gapComments[i]` holds already-converted comment text that sat\n // between `groups[i]` and `groups[i + 1]` in the source. Every\n // `flush(comments)` call happens exactly at such a gap — `current`\n // (about to become `groups[gapComments.length]`) is whatever came\n // *before* the gap, and whatever gets pushed to `current` right after\n // this call is what comes *after* it — so each call always records one\n // entry, except the final, argument-less flush at the very end of the\n // method (nothing follows the last group).\n const gapComments: string[][] = [];\n let current: Segment[] = [];\n const flush = (comments?: string[]) => {\n if (current.length > 0) {\n groups.push(current);\n gapComments.push(comments ?? []);\n current = [];\n }\n };\n\n const preserveComments = shouldEmitComments(options);\n const style = resolveCommentStyle(options);\n\n for (let i = 0; i < items.length; i++) {\n const item = items[i]!;\n if (i > 0 && boundary[i])\n flush(boundaryComments(items[i - 1]!, item, preserveComments, style));\n if (item instanceof CborEllipsis && item.content instanceof CborSimple) {\n current.push({\n ellipsis: true,\n fromByteLiteral: item.fromByteLiteral,\n literalSource: item.literalSource,\n });\n } else if (item instanceof CborByteString) {\n if (item.ednParts !== undefined && item.ednParts.length > 1) {\n const [firstPart, ...restParts] = item.ednParts;\n current.push({\n bytes: firstPart.bytes,\n source: firstPart.source,\n commentSyntax: firstPart.commentSyntax,\n });\n // These parts merged into one `CborByteString` with no per-part\n // AST node of their own (no ellipsis sat between them — see\n // `CborEllipsis._hasRealConcatenation`'s doc), so a comment\n // between two of them landed as `dangling` on `item` as a whole\n // instead; re-derive which internal gap each one belongs to.\n const internalGaps = preserveComments\n ? danglingCommentsByGap(\n item.comments?.dangling,\n item.ednParts,\n style\n )\n : undefined;\n restParts.forEach((part, j) => {\n flush(internalGaps?.[j]);\n current.push({\n bytes: part.bytes,\n source: part.source,\n commentSyntax: part.commentSyntax,\n });\n });\n } else {\n current.push({\n bytes: item.value,\n source: item.ednSource,\n commentSyntax: item.ednCommentSyntax,\n });\n }\n } else {\n return undefined;\n }\n }\n // The closing flush has no gap after it, so it bypasses `flush()`'s own\n // comment recording — pushing directly keeps `gapComments.length` at\n // exactly `groups.length - 1`.\n if (current.length > 0) groups.push(current);\n if (groups.length === 0) return undefined;\n\n const encoding =\n options?.appPrefix === false ? 'hex' : (options?.bstrEncoding ?? 'hex');\n // A preserved source spelling can itself contain embedded newlines\n // (interior whitespace, or a surviving `#`/`//` line comment) — those\n // are only safe to re-emit verbatim when `indent` enables multi-line\n // output; see `preservedSource`. Otherwise fall back to freshly\n // re-serializing the bytes.\n const indentStr = resolveIndent(options);\n const rendered = groups.map((group) => {\n // A group with more than one segment, or a single ellipsis-only\n // group, always came from exactly one `h'xx...yy'` literal (see the\n // parser: nothing but that literal's own atoms ever ends up fused\n // together) — so any ellipsis segment's `literalSource` is that\n // whole group's original spelling.\n if (options?.preserveByteString) {\n for (const s of group) {\n if (!('ellipsis' in s)) continue;\n // Always came from a BYTES_HEX_ELIDED token (see `_elidedHexAtoms`),\n // so its comment syntax is unconditionally hex's full syntax.\n const literalSource = preservedSource(\n s.literalSource,\n options,\n indentStr,\n 'full'\n );\n if (literalSource !== undefined) return literalSource;\n }\n }\n const byteSegments = group.filter(\n (\n s\n ): s is {\n bytes: Uint8Array;\n source?: string;\n commentSyntax?: ByteCommentSyntax;\n } => !('ellipsis' in s)\n );\n if (byteSegments.length === 0) {\n // Isolated ellipsis-only group with no preserved source: bare\n // `...` for a genuine standalone ellipsis token, `h'...'` when it\n // came from an elided-hex literal (even an entirely-elided one)\n // to keep its byte-typed spelling.\n const fromByteLiteral = group.some(\n (s) => 'ellipsis' in s && s.fromByteLiteral\n );\n return fromByteLiteral ? \"h'...'\" : '...';\n }\n if (group.length === 1) {\n const segment = byteSegments[0];\n const source = options?.preserveByteString\n ? preservedSource(\n segment.source,\n options,\n indentStr,\n segment.commentSyntax\n )\n : undefined;\n return source !== undefined\n ? source\n : serializeBytes(segment.bytes, encoding, options?.sqstr);\n }\n const hex = group\n .map((s) => ('ellipsis' in s ? '...' : bytesToHex(s.bytes)))\n .join('');\n return `h'${hex}'`;\n });\n // `groups.length === 1` (nothing to concatenate — this method can also\n // be reached via `preserveByteString` alone, with no real `+` boundary\n // at all) has nothing for `modernConcat` to change: both branches\n // collapse to the one rendered literal, so only switch notation when\n // there's an actual boundary to show.\n if (\n options?.preserveConcatenation &&\n options?.modernConcat &&\n rendered.length > 1\n ) {\n return joinAppSeqParts('b1', rendered, '', indentStr, depth, gapComments);\n }\n return joinElisionParts(rendered, gapComments, indentStr, depth);\n }\n}\n","/**\n * CBOR bignum tags (RFC 8949 §3.4.3).\n *\n * Tag 2 — unsigned bignum: tag(2, bstr) where bstr is the big-endian\n * encoding of a non-negative integer.\n * Tag 3 — negative bignum: tag(3, bstr) where the value = -1 - unsigned(bstr).\n *\n * These classes are used for integers that fall outside the uint64 / nint64\n * range of CBOR major types 0 and 1:\n * CborBigUint — value ≥ 2^64\n * CborBigNint — value ≤ -(2^64 + 1)\n *\n * toCDN() emits the plain decimal form (e.g. \"18446744073709551616\") so that\n * round-trips through EDN text are human-readable.\n */\n\nimport type { ToCDNOptions, ToJSOptions } from '../types';\nimport { CborTag } from './CborTag';\nimport { CborByteString } from './CborByteString';\n\nexport const BIGNUM_UINT_TAG = 2n;\nexport const BIGNUM_NINT_TAG = 3n;\n\nconst UINT64_MAX = 0xffff_ffff_ffff_ffffn;\nconst NINT64_MIN = -(UINT64_MAX + 1n); // -18446744073709551616n\n\n// ─── Bigint ↔ bytes helpers ───────────────────────────────────────────────────\n\n/**\n * Encode a non-negative bigint as a minimal big-endian byte string.\n * Zero is encoded as the empty byte string per RFC 8949 §3.4.3.\n */\nexport function bigintToBytes(n: bigint): Uint8Array {\n if (n < 0n)\n throw new RangeError('bigintToBytes requires a non-negative value');\n if (n === 0n) return new Uint8Array(0);\n let hex = n.toString(16);\n if (hex.length % 2 !== 0) hex = '0' + hex;\n const bytes = new Uint8Array(hex.length / 2);\n for (let i = 0; i < bytes.length; i++)\n bytes[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);\n return bytes;\n}\n\n/**\n * Decode a big-endian byte string to a non-negative bigint.\n * Empty bytes → 0n.\n */\nexport function bytesToBigint(bytes: Uint8Array): bigint {\n let n = 0n;\n for (const b of bytes) n = (n << 8n) | BigInt(b);\n return n;\n}\n\n// ─── AST nodes ────────────────────────────────────────────────────────────────\n\n/**\n * Unsigned bignum — integers ≥ 2^64.\n * Wire format: tag(2, big-endian byte string).\n * toCDN() emits the plain decimal integer.\n */\nexport class CborBigUint extends CborTag {\n readonly bigValue: bigint;\n\n constructor(value: bigint) {\n if (value <= UINT64_MAX)\n throw new RangeError(\n `CborBigUint value ${value} fits in CborUint; use CborUint instead`\n );\n super(BIGNUM_UINT_TAG, new CborByteString(bigintToBytes(value)));\n this.bigValue = value;\n }\n\n override _toCDN(_options: ToCDNOptions | undefined, _depth: number): string {\n return this.bigValue.toString();\n }\n\n override _toJS(_options?: ToJSOptions): bigint {\n return this.bigValue;\n }\n}\n\n/**\n * Negative bignum — integers ≤ -(2^64 + 1).\n * Wire format: tag(3, big-endian byte string of (-1 - value)).\n * toCDN() emits the plain decimal integer.\n */\nexport class CborBigNint extends CborTag {\n readonly bigValue: bigint;\n\n constructor(value: bigint) {\n if (value >= NINT64_MIN)\n throw new RangeError(\n `CborBigNint value ${value} fits in CborNint; use CborNint instead`\n );\n super(BIGNUM_NINT_TAG, new CborByteString(bigintToBytes(-1n - value)));\n this.bigValue = value;\n }\n\n override _toCDN(_options: ToCDNOptions | undefined, _depth: number): string {\n return this.bigValue.toString();\n }\n\n override _toJS(_options?: ToJSOptions): bigint {\n return this.bigValue;\n }\n}\n","import {\n Tokenizer,\n type EdnComment,\n type SqstrToken,\n type Token,\n type TokenType,\n} from './tokenizer';\nimport { CdnSyntaxError } from './errors';\nimport type {\n AppSeqEncodingEdit,\n AppSeqSourceFeatures,\n CborItem,\n} from '../ast/CborItem';\nimport type {\n CborComment,\n FromCDNOptions,\n CborExtension,\n ParseWarning,\n} from '../types';\nimport { CborUint } from '../ast/CborUint';\nimport { CborNint } from '../ast/CborNint';\nimport { CborByteString } from '../ast/CborByteString';\nimport { CborIndefiniteByteString } from '../ast/CborIndefiniteByteString';\nimport { CborTextString } from '../ast/CborTextString';\nimport { CborIndefiniteTextString } from '../ast/CborIndefiniteTextString';\nimport { CborArray } from '../ast/CborArray';\nimport { CborMap } from '../ast/CborMap';\nimport { CborTag } from '../ast/CborTag';\nimport { CborFloat, type FloatPrecision } from '../ast/CborFloat';\nimport { CborSimple } from '../ast/CborSimple';\nimport { CborEmbeddedCBOR } from '../ast/CborEmbeddedCBOR';\nimport {\n autoSelectFloatPrecision,\n maxForEncodingWidth,\n type EncodingWidth,\n} from '../cbor/encode';\nimport {\n canonicalEncodingWidth,\n pushAll,\n shouldEmitComments,\n type ByteCommentSyntax,\n} from './serialize-utils';\nimport { b32, h32 } from '../extensions/b32';\nimport { parseHexFloat } from '../utils/hexfloat';\nimport { hexToBytes } from '../utils/hex';\nimport { base64ToBytes } from '../utils/base64';\nimport { float64ToFloat16Bits, float16BitsToFloat64 } from '../utils/float16';\nimport { resolveBuiltinExtensions } from '../extensions/builtins';\nimport { CborUnresolvedAppExt } from '../ast/CborUnresolvedAppExt';\nimport { CborAppSeqResult } from '../ast/CborAppSeqResult';\nimport { CborEllipsis } from '../ast/CborEllipsis';\nimport { CborBigUint, CborBigNint } from '../ast/CborBignum';\n\n// Shared codec instances — constructing TextEncoder/TextDecoder per call is\n// measurably expensive in hot parsing paths.\nconst textEncoder = new TextEncoder();\nconst utf8Strict = new TextDecoder('utf-8', { fatal: true });\nconst utf8Lenient = new TextDecoder('utf-8', { fatal: false });\n\n// ─── Public entry point ───────────────────────────────────────────────────────\n\n/**\n * Parse a CDN text string into a CborItem AST node.\n * Throws SyntaxError on invalid input.\n */\nexport function parseCDN(text: string, options?: FromCDNOptions): CborItem {\n const tokenizer = new Tokenizer(text, {\n offset: options?.offset,\n skipRS: (options as (FromCDNOptions & { _skipRS?: boolean }) | undefined)\n ?._skipRS,\n });\n const parser = new CDNParser(tokenizer, options ?? {});\n const node = parser.parse();\n if (shouldEmitComments(options) || options?.preserveAll) {\n attachComments(node, tokenizer.comments, text);\n promoteEllipsisTailComments(node);\n }\n return node;\n}\n\n// ─── Value helpers ────────────────────────────────────────────────────────────\n\n/** Strip an optional _0/_1/_2/_3/_i encoding-indicator suffix from a raw\n * integer token value and return both the numeric string and the width. */\nfunction parseIntegerRaw(raw: string): {\n numStr: string;\n rawSuffix: string | undefined;\n} {\n let numStr = raw;\n let rawSuffix: string | undefined;\n if (/[_][0-7i]$/.test(raw)) {\n rawSuffix = raw[raw.length - 1]!;\n numStr = raw.slice(0, -2);\n }\n return { numStr, rawSuffix };\n}\n\nfunction parseBigInt(raw: string): bigint {\n if (raw.startsWith('-')) return -BigInt(raw.slice(1));\n return BigInt(raw);\n}\n\n/**\n * `item`'s own literal-preservation features, combined with those of\n * whatever it structurally contains.\n *\n * A node can carry `appSeqSourceFeatures` on itself — set when it is *also*\n * the result of parsing a `prefix<<item>>` / `prefix'...'` source, recording\n * features of *that* inner item (see the `appSeqSourceFeatures` field on\n * `CborItem`) — independently of whatever `structuralAppSeqSourceFeatures`\n * finds by walking its children. Both must be combined: a nested extension\n * result (e.g. a `dt<<b64'...'>>` that resolved to a plain epoch number, so\n * `structuralAppSeqSourceFeatures` finds nothing byte-string-like in it\n * structurally) still carries its own inner byte-string literal's features\n * on itself, and an explicitly disabled sibling `preserve*` option must see\n * that when this node is nested inside an outer `preserveAppPrefix`\n * raw-tag/`<<...>>` source (e.g. `ip`'s array content).\n */\nfunction appSeqSourceFeatures(\n item: CborItem | undefined\n): AppSeqSourceFeatures | undefined {\n if (item === undefined) return undefined;\n return combineAppSeqSourceFeatures([\n item.appSeqSourceFeatures,\n structuralAppSeqSourceFeatures(item),\n ]);\n}\n\nfunction structuralAppSeqSourceFeatures(\n item: CborItem\n): AppSeqSourceFeatures | undefined {\n if (item instanceof CborByteString) {\n return {\n byteString: true,\n concatenation: item.ednParts !== undefined && item.ednParts.length > 1,\n };\n }\n if (item instanceof CborTextString) {\n const hasParts = item.ednParts !== undefined;\n const rawPartCount =\n item.ednPartSources?.filter((source) => source !== undefined).length ?? 0;\n // A part with no preserved raw source is ambiguous by itself — it could\n // be an unpreservable double-quoted literal (textString) or a\n // byte-string literal decoded to text per draft-25 §5.1 (byteString); only\n // ednPartIsByteString distinguishes them.\n const byteStringPartCount = hasParts\n ? item.ednParts!.reduce((count, _text, i) => {\n const hasSource = item.ednPartSources?.[i] !== undefined;\n const isByteString = item.ednPartIsByteString?.[i] ?? false;\n return hasSource || !isByteString ? count : count + 1;\n }, 0)\n : 0;\n const unpreservedTextPartCount =\n (hasParts ? item.ednParts!.length : 0) -\n rawPartCount -\n byteStringPartCount;\n return {\n byteString: byteStringPartCount > 0,\n textString:\n item.quotedEdnSource !== undefined || unpreservedTextPartCount > 0,\n rawString: item.ednSource !== undefined || rawPartCount > 0,\n concatenation: hasParts && item.ednParts!.length > 1,\n };\n }\n if (item instanceof CborArray) {\n return combineAppSeqSourceFeatures(item.items.map(appSeqSourceFeatures));\n }\n if (item instanceof CborMap) {\n // ip accepts an arbitrary CborArray as tag content, so a nested map's\n // own byte-string/text-string/concatenation literals must also be\n // detected — otherwise an explicitly disabled sibling `preserve*`\n // option silently has no effect on them (see collectContentEncodingEdits,\n // which has the analogous \"unsupported nested node\" concern for\n // encoding-indicator edits).\n return combineAppSeqSourceFeatures(\n item.entries.flatMap(([k, v]) => [\n appSeqSourceFeatures(k),\n appSeqSourceFeatures(v),\n ])\n );\n }\n if (item instanceof CborTag) return appSeqSourceFeatures(item.content);\n if (\n item instanceof CborIndefiniteByteString ||\n item instanceof CborIndefiniteTextString ||\n item instanceof CborEmbeddedCBOR\n ) {\n const children: CborItem[] =\n item instanceof CborEmbeddedCBOR ? item.items : item.chunks;\n return combineAppSeqSourceFeatures(children.map(appSeqSourceFeatures));\n }\n return undefined;\n}\n\nfunction combineAppSeqSourceFeatures(\n values: (AppSeqSourceFeatures | undefined)[]\n): AppSeqSourceFeatures | undefined {\n const features = values.filter((value) => value !== undefined);\n if (features.length === 0) return undefined;\n return {\n byteString: features.some((value) => value.byteString),\n textString: features.some((value) => value.textString),\n rawString: features.some((value) => value.rawString),\n concatenation: features.some((value) => value.concatenation),\n };\n}\n\nfunction parseFloatToken(\n raw: string,\n onRecoverableError?: (msg: string) => void\n): {\n value: number;\n precision: FloatPrecision | undefined;\n} {\n // Strip any invalid encoding indicator first, before NaN/Infinity checks,\n // so that e.g. \"NaN_7\" still resolves to NaN after the suffix is removed.\n if (raw.endsWith('_i') || raw.endsWith('_0')) {\n const msg =\n '_0 and _i encoding indicators are not valid for floating-point values';\n if (onRecoverableError) {\n onRecoverableError(msg);\n raw = raw.slice(0, -2);\n } else {\n throw new SyntaxError(`EDN parse error: ${msg}`);\n }\n } else if (/[_][4567]$/.test(raw)) {\n const suffix = raw[raw.length - 1]!;\n const msg =\n suffix === '7'\n ? 'indefinite-length encoding (_7) is not valid for floating-point values'\n : `encoding indicator _${suffix} (AI ${Number(suffix) + 24}) is reserved and not valid`;\n if (onRecoverableError) {\n onRecoverableError(msg);\n raw = raw.slice(0, -2);\n } else {\n throw new SyntaxError(`EDN parse error: ${msg}`);\n }\n }\n\n if (raw === 'NaN') return { value: NaN, precision: undefined };\n if (raw === 'Infinity') return { value: Infinity, precision: undefined };\n if (raw === '-Infinity') return { value: -Infinity, precision: undefined };\n\n let numStr = raw;\n let precision: FloatPrecision | undefined;\n if (raw.endsWith('_1')) {\n precision = 'half';\n numStr = raw.slice(0, -2);\n } else if (raw.endsWith('_2')) {\n precision = 'single';\n numStr = raw.slice(0, -2);\n } else if (raw.endsWith('_3')) {\n precision = 'double';\n numStr = raw.slice(0, -2);\n }\n\n // Hex float literal: 0x[hex]p[exp] or -0x[hex]p[exp]\n if (/^-?0[xX]/.test(numStr))\n return { value: parseHexFloat(numStr), precision };\n\n return { value: parseFloat(numStr), precision };\n}\n\n// ─── Blank-line tracking ─────────────────────────────────────────────────────\n\n/**\n * A blank line is a line containing only whitespace between two other lines\n * — i.e. two newlines with nothing but horizontal whitespace between them.\n * Applied to the raw gap between one container entry and the next\n * (comments and all), so a blank line is detected regardless of whether it\n * sits before, after, or inside a leading comment block.\n */\nconst BLANK_LINE_RE = /\\r?\\n[ \\t]*\\r?\\n/;\n\nfunction hasBlankLineBetween(\n text: string,\n start: number,\n end: number\n): boolean {\n return BLANK_LINE_RE.test(text.slice(start, end));\n}\n\n// ─── Comment attachment ──────────────────────────────────────────────────────\n\ninterface NodeInfo {\n node: CborItem;\n start: number;\n end: number;\n}\n\nfunction relativeComments(\n comments: readonly EdnComment[],\n fromIndex: number,\n start: number,\n end: number\n): CborComment[] {\n const result: CborComment[] = [];\n for (let i = fromIndex; i < comments.length; i++) {\n const comment = comments[i]!;\n if (comment.start >= end) break;\n if (comment.start >= start && comment.end <= end)\n result.push({\n ...comment,\n start: comment.start - start,\n end: comment.end - start,\n });\n }\n return result;\n}\n\nfunction sourceSuffixEdit(\n source: string,\n sourceStart: number,\n node: CborItem,\n always: string\n): AppSeqEncodingEdit | undefined {\n if (node.end === undefined) return undefined;\n const hasIndicator = /_[0-7i]$/.test(\n source.slice(Math.max(0, node.end - 2), node.end)\n );\n const start = (hasIndicator ? node.end - 2 : node.end) - sourceStart;\n return {\n start,\n end: node.end - sourceStart,\n always,\n never: '',\n };\n}\n\n/**\n * Collect source-span edits for every encoding indicator nested inside a\n * raw-tag's content, for `adjustRawAppSeqSource`.\n *\n * Returns `undefined` — instead of a partial edit list — when `node` (or\n * anything nested inside it) is a type this function doesn't know how to\n * produce an edit for (e.g. `CborMap`, `CborTag`, `CborSimple`, an\n * indefinite-length string). A partial list would silently leave that\n * node's own indicator un-edited under `encodingIndicators: 'always'` /\n * `'never'`; the caller must fall back to structural re-serialization\n * instead so every nested indicator is actually applied. `ip` accepts an\n * arbitrary `CborArray` as tag content, so this bails out for any element\n * type beyond the ones explicitly handled below rather than assuming\n * coverage is complete.\n */\nfunction collectContentEncodingEdits(\n source: string,\n sourceStart: number,\n node: CborItem\n): AppSeqEncodingEdit[] | undefined {\n if (node instanceof CborUint) {\n const width = node.encodingWidth ?? canonicalEncodingWidth(node.value);\n const edit = sourceSuffixEdit(source, sourceStart, node, `_${width}`);\n return edit ? [edit] : [];\n }\n if (node instanceof CborNint) {\n const width = node.encodingWidth ?? canonicalEncodingWidth(node.argument);\n const edit = sourceSuffixEdit(source, sourceStart, node, `_${width}`);\n return edit ? [edit] : [];\n }\n if (node instanceof CborFloat) {\n const precision = node.precision ?? autoSelectFloatPrecision(node.value);\n const suffix =\n precision === 'half' ? '_1' : precision === 'single' ? '_2' : '_3';\n const edit = sourceSuffixEdit(source, sourceStart, node, suffix);\n return edit ? [edit] : [];\n }\n if (node instanceof CborByteString) {\n const width =\n node.encodingWidth ?? canonicalEncodingWidth(BigInt(node.value.length));\n const edit = sourceSuffixEdit(source, sourceStart, node, `_${width}`);\n return edit ? [edit] : [];\n }\n if (node instanceof CborTextString) {\n const width =\n node.encodingWidth ??\n canonicalEncodingWidth(BigInt(textEncoder.encode(node.value).length));\n const edit = sourceSuffixEdit(source, sourceStart, node, `_${width}`);\n return edit ? [edit] : [];\n }\n if (node instanceof CborArray) {\n const edits: AppSeqEncodingEdit[] = [];\n if (node.indefiniteLength) return undefined;\n if (node.start !== undefined) {\n const tokenizer = new Tokenizer(source, { offset: node.start });\n const open = tokenizer.consume();\n const next = tokenizer.peek();\n const hasIndicator = next.type === 'ENCODING_INDICATOR';\n const width =\n node.encodingWidth ?? canonicalEncodingWidth(BigInt(node.items.length));\n const suffix = `_${width}`;\n const nextSourceChar = source[open.endOffset] ?? '';\n const separator =\n !hasIndicator && /[+\\-.0-9A-Z_a-z]/.test(nextSourceChar) ? ' ' : '';\n edits.push({\n start: (hasIndicator ? next.offset : open.endOffset) - sourceStart,\n end: (hasIndicator ? next.endOffset : open.endOffset) - sourceStart,\n // An inserted container indicator needs a separator before an\n // immediately-adjacent item (`[_i24]` lexes as one identifier).\n always: suffix + separator,\n never: '',\n });\n }\n for (const item of node.items) {\n const itemEdits = collectContentEncodingEdits(source, sourceStart, item);\n if (itemEdits === undefined) return undefined;\n pushAll(edits, itemEdits);\n }\n return edits;\n }\n return undefined;\n}\n\nfunction attachComments(\n root: CborItem,\n comments: EdnComment[],\n source: string\n): void {\n if (comments.length === 0) return;\n const nodes = collectNodes(root);\n const lineAt = buildLineAt(source);\n\n // Two sorted views over the pre-order node list, so each comment resolves\n // its neighbours in O(log N) instead of re-filtering and re-sorting the\n // whole list per comment. Both sorts are stable, so nodes with equal keys\n // keep their pre-order (parent before child) relative order.\n const byStart = [...nodes].sort((a, b) => a.start - b.start || b.end - a.end);\n const byEnd = [...nodes].sort((a, b) => a.end - b.end || a.start - b.start);\n\n // The tokenizer appends comments in source order; sort defensively so the\n // container sweep below stays correct for out-of-order callers.\n const ordered = [...comments].sort((a, b) => a.start - b.start);\n\n // Container-sweep state shared across comments (comments are processed in\n // ascending start order, so pushes and pops are monotone).\n const enclosing: NodeInfo[] = [];\n let nextToPush = 0;\n\n for (const raw of ordered) {\n const comment: CborComment = { ...raw };\n\n // prev: node with the largest end <= comment start (ties: largest start).\n // byEnd is (end asc, start asc), so this is the last index with\n // end <= raw.start, found by upper-bound binary search.\n let lo = 0;\n let hi = byEnd.length;\n while (lo < hi) {\n const mid = (lo + hi) >> 1;\n if (byEnd[mid].end <= raw.start) lo = mid + 1;\n else hi = mid;\n }\n const prev = lo > 0 ? byEnd[lo - 1] : undefined;\n\n const separatorBeforeComment = prev\n ? source.slice(prev.end, raw.start)\n : '';\n if (\n prev &&\n lineAt(prev.end) === raw.line &&\n !separatorBeforeComment.includes(':')\n ) {\n addComment(prev.node, 'trailing', comment);\n continue;\n }\n\n // container: innermost node with start < comment start and comment end\n // < node end. Node spans nest properly and a comment never straddles a\n // node boundary (it is whitespace between tokens), so an interval-stack\n // sweep over byStart works: push nodes starting before the comment,\n // pop nodes that ended before it — the stack top is the container.\n while (\n nextToPush < byStart.length &&\n byStart[nextToPush].start < raw.start\n ) {\n const n = byStart[nextToPush++];\n while (\n enclosing.length > 0 &&\n enclosing[enclosing.length - 1].end <= n.start\n )\n enclosing.pop();\n enclosing.push(n);\n }\n while (\n enclosing.length > 0 &&\n enclosing[enclosing.length - 1].end <= raw.start\n )\n enclosing.pop();\n const container =\n enclosing.length > 0 ? enclosing[enclosing.length - 1] : undefined;\n\n // next: node with the smallest start >= comment end (ties: largest end).\n // byStart is (start asc, end desc), so this is the first index with\n // start >= raw.end, found by lower-bound binary search.\n lo = 0;\n hi = byStart.length;\n while (lo < hi) {\n const mid = (lo + hi) >> 1;\n if (byStart[mid].start < raw.end) lo = mid + 1;\n else hi = mid;\n }\n const next = lo < byStart.length ? byStart[lo] : undefined;\n\n if (!container || (next && next.end <= container.end)) {\n if (next) {\n comment.sameLine = lineAt(raw.end) === lineAt(next.start);\n addComment(next.node, 'leading', comment);\n continue;\n }\n }\n\n // No enclosing node and no following node: the comment lies entirely\n // after `root.end` (a comment before `root.start` is always caught by\n // the `next`-leading branch above, since `root` is itself a collected\n // node). This happens when this parse is one item of a CDN Sequence\n // (`allowTrailing: true`) — the tokenizer's one-token lookahead reads\n // past this item's closing bracket into a comment that actually\n // belongs to whatever follows. Attaching it here would duplicate the\n // sequence-level leading-comment assignment `fromCDNSeq` already makes\n // for the next item, so it is dropped instead of defaulting to `root`.\n if (!container) continue;\n\n addComment(container.node, 'dangling', comment);\n }\n}\n\nfunction collectNodes(root: CborItem): NodeInfo[] {\n const out: NodeInfo[] = [];\n const visit = (node: CborItem) => {\n if (node.start !== undefined && node.end !== undefined)\n out.push({ node, start: node.start, end: node.end });\n if (node instanceof CborArray || node instanceof CborEmbeddedCBOR) {\n for (const item of node.items) visit(item);\n return;\n }\n if (node instanceof CborMap) {\n for (const [key, value] of node.entries) {\n visit(key);\n visit(value);\n }\n return;\n }\n if (\n node instanceof CborIndefiniteByteString ||\n node instanceof CborIndefiniteTextString\n ) {\n for (const chunk of node.chunks) visit(chunk);\n return;\n }\n if (node instanceof CborTag) visit(node.content);\n };\n visit(root);\n return out;\n}\n\nfunction addComment(\n node: CborItem,\n placement: 'leading' | 'trailing' | 'dangling',\n comment: CborComment\n): void {\n node.comments ??= {};\n node.comments[placement] ??= [];\n node.comments[placement].push(comment);\n}\n\n/**\n * A comment right after the very last fragment of a `+`/`...` chain ties,\n * in source position, with the enclosing `CborEllipsis`'s own end — there\n * is no closing delimiter after the last fragment (unlike an array's `]` or\n * a map's `}`) to give the chain a later end of its own — so\n * `attachComments`'s prev/next tie-break resolves it in favour of the more\n * specific, innermost node: the comment lands as `trailing` on the last\n * fragment itself, not on the `CborEllipsis`.\n *\n * Move it up onto the `CborEllipsis`'s own `comments.trailing` so the\n * ordinary `entryTrailing`/root-`toCDN()` machinery renders it after\n * whatever separator the parent adds (`,`, `:`, a closing bracket) instead\n * of `CborEllipsis._toCDN()` folding it into the chain's own body — which\n * would place a `#`/`//` line comment *before* that separator, swallowing\n * it into the comment on re-parse (e.g. `[h'aa' + ..., # next\\n 1]` would\n * otherwise render the trailing `,` inside the comment text itself).\n */\nfunction promoteEllipsisTailComments(node: CborItem): void {\n if (node instanceof CborEllipsis) {\n if (node.content instanceof CborArray) {\n const items = node.content.items;\n for (const item of items) promoteEllipsisTailComments(item);\n const last = items[items.length - 1];\n const lastTrailing = last?.comments?.trailing;\n if (\n lastTrailing !== undefined &&\n lastTrailing.length > 0 &&\n !node.comments?.trailing?.length\n ) {\n node.comments ??= {};\n node.comments.trailing = lastTrailing;\n last.comments!.trailing = undefined;\n }\n }\n return;\n }\n if (node instanceof CborArray || node instanceof CborEmbeddedCBOR) {\n for (const item of node.items) promoteEllipsisTailComments(item);\n return;\n }\n if (node instanceof CborMap) {\n for (const [key, value] of node.entries) {\n promoteEllipsisTailComments(key);\n promoteEllipsisTailComments(value);\n }\n return;\n }\n if (\n node instanceof CborIndefiniteByteString ||\n node instanceof CborIndefiniteTextString\n ) {\n for (const chunk of node.chunks) promoteEllipsisTailComments(chunk);\n return;\n }\n if (node instanceof CborTag) promoteEllipsisTailComments(node.content);\n}\n\nfunction buildLineAt(source: string): (offset: number) => number {\n const starts = [0];\n for (let i = 0; i < source.length; i++) {\n if (source[i] === '\\n') starts.push(i + 1);\n }\n return (offset: number): number => {\n let target = Math.max(0, Math.min(source.length, offset));\n if (target > 0 && target === source.length) target--;\n let lo = 0;\n let hi = starts.length - 1;\n while (lo <= hi) {\n const mid = (lo + hi) >> 1;\n if (starts[mid] <= target) lo = mid + 1;\n else hi = mid - 1;\n }\n return hi + 1;\n };\n}\n\n// ─── Missing-extension hints ──────────────────────────────────────────────────\n\nconst bundledExtensionHint = (name: string): string =>\n `import { ${name} } from '@cbortech/cbor' and pass it via the 'extensions' option (extensions: [${name}])`;\nconst externalExtensionHint = (name: string, pkg: string): string =>\n `install ${pkg}, import { ${name} } from '${pkg}', and pass it via the 'extensions' option (extensions: [${name}])`;\nconst builtinDisabledHint = (name: string): string =>\n `'${name}' is a default built-in extension that was excluded via the 'builtinExtensions' option; add it back to that array (or omit 'builtinExtensions' to use the default set)`;\n\n/**\n * App-string prefixes handled by known opt-in extensions or by default\n * built-ins that can be excluded via `builtinExtensions`, mapped to guidance\n * on how to (re-)enable them. Used to emit a non-fatal hint when such a\n * prefix is encountered without the corresponding extension registered.\n */\nconst MISSING_EXTENSION_HINTS: ReadonlyMap<string, string> = new Map([\n ['b32', bundledExtensionHint('b32')],\n ['h32', bundledExtensionHint('h32')],\n ['same', bundledExtensionHint('same')],\n ['hash', externalExtensionHint('hash', '@cbortech/hash-extension')],\n ['uuid', externalExtensionHint('uuid', '@cbortech/uuid-extension')],\n ['UUID', externalExtensionHint('uuid', '@cbortech/uuid-extension')],\n // Only reachable via a non-default `builtinExtensions` override — these\n // are otherwise always present in the default bundled set.\n ['dt', builtinDisabledHint('dt')],\n ['DT', builtinDisabledHint('dt')],\n ['ip', builtinDisabledHint('ip')],\n ['IP', builtinDisabledHint('ip')],\n ['cri', builtinDisabledHint('cri')],\n ['CRI', builtinDisabledHint('cri')],\n ['t1', builtinDisabledHint('t1')],\n ['b1', builtinDisabledHint('b1')],\n ['ilbs', builtinDisabledHint('ilbs')],\n ['ilts', builtinDisabledHint('ilts')],\n ['float', builtinDisabledHint('float')],\n]);\n\n/**\n * One atom of a byte-string `+`/ellipsis chain: either a byte fragment or an\n * ellipsis marker, tagged with whether a genuine `+` from the source\n * precedes it (`real`) as opposed to sitting inside a single `h'xx...yy'`\n * literal's own `...` notation. An ellipsis atom also tracks whether it came\n * from such a literal at all (`fromByteLiteral`), regardless of its own\n * position within it (leading, trailing, or in the middle) — as opposed to a\n * bare standalone `...` token — and, when it did, that literal's own raw\n * source text (`literalSource`, e.g. `h'AB...CD'` verbatim, case/whitespace/\n * comments and all) for `preserveByteString` to round-trip. See\n * `CDNParser._consumeByteEllipsisChain`.\n */\ntype ByteEllipsisAtom =\n | {\n bytes: Uint8Array;\n source?: string;\n commentSyntax?: ByteCommentSyntax;\n real: boolean;\n /**\n * Source span this atom occupies — its own literal token's span for a\n * direct `+`-joined fragment, or the enclosing `h'xx...yy'` token's\n * whole span for an internal segment split out of it (see\n * `_elidedHexAtoms`: no comment can ever sit between two of that\n * token's own internal segments, so sharing the outer span is safe and\n * still lets an *outer* boundary comment resolve correctly against the\n * group as a whole). Lets `_buildFromByteAtoms` stamp `start`/`end` on\n * the `CborByteString`/`CborEllipsis` nodes it builds, so the generic\n * `attachComments` pass (and `CborByteString._toCDN`'s /\n * `CborEllipsis._renderPreservedBytesElision`'s own dangling-comment\n * lookups) can place a comment between two `+`-joined parts instead of\n * dropping it.\n */\n start?: number;\n end?: number;\n }\n | {\n ellipsis: true;\n real: boolean;\n fromByteLiteral: boolean;\n literalSource?: string;\n /** See the byte-atom variant's `start`/`end` doc above. */\n start?: number;\n end?: number;\n };\n\n// ─── Parser ───────────────────────────────────────────────────────────────────\n\nclass CDNParser {\n /** Lookup from app-prefix → extension (user extensions override built-ins). */\n private readonly extByPrefix: Map<string, CborExtension>;\n /** Lookup from tag number → extension. */\n private readonly extByTag: Map<bigint, CborExtension>;\n\n private readonly unresolvedExtension: 'cpa999' | 'error';\n\n /** Warnings accumulated during the current parseValue() call. */\n private _pendingWarnings: ParseWarning[] = [];\n\n /** Prefixes for which a missing-extension hint has already been emitted. */\n private readonly _hintedPrefixes = new Set<string>();\n\n constructor(\n private readonly t: Tokenizer,\n private readonly _options: FromCDNOptions\n ) {\n this.extByPrefix = new Map();\n this.extByTag = new Map();\n this.unresolvedExtension = _options.unresolvedExtension ?? 'cpa999';\n const builtins = resolveBuiltinExtensions(_options.builtinExtensions);\n for (const ext of [...builtins, ...(_options.extensions ?? [])]) {\n for (const prefix of ext.appStringPrefixes ?? [])\n this.extByPrefix.set(prefix, ext);\n for (const tag of ext.tagNumbers ?? []) this.extByTag.set(tag, ext);\n }\n this.t.onEscapeWarning = (msg, offset, line, col, endOffset) => {\n const w: ParseWarning = {\n message: msg,\n offset,\n line,\n column: col,\n endOffset,\n };\n this._pendingWarnings.push(w);\n if (this._options.onWarning) this._options.onWarning(w);\n else if (!this._options.silent)\n console.warn(\n `CDN strict violation at line ${line}, column ${col}: ${msg}`\n );\n if (this._options.strict !== false)\n throw new CdnSyntaxError(msg, { offset, line, column: col, endOffset });\n };\n }\n\n parse(): CborItem {\n const value = this.parseValue();\n if (this._options.allowTrailing) return value;\n const next = this.t.peek();\n if (next.type !== 'EOF') {\n this._warnOrFail(\n `unexpected token after value: ${JSON.stringify(next.value)}`,\n next\n );\n // Reached only in non-strict mode (_warnOrFail throws in strict mode).\n // Drain the pending warning into the returned value's AST node so it\n // is visible to callers that inspect node.warnings directly.\n if (this._pendingWarnings.length > 0) {\n value.warnings ??= [];\n value.warnings.push(...this._pendingWarnings);\n this._pendingWarnings = [];\n }\n // Scan the rest of the input so that hard lexer errors in the trailing\n // content (e.g. unterminated strings) still throw regardless of the\n // strict setting.\n while (this.t.peek().type !== 'EOF') this.t.consume();\n }\n return value;\n }\n\n parseValue(): CborItem {\n const start = this.t.peek().offset;\n const node = this._parseValueNode();\n if (this.t.peek().type === 'UNDERSCORE') {\n const tok = this.t.consume();\n this._warnOrFail(\n 'bare _ is not a valid encoding indicator; use _0, _1, _2, _3, or _i',\n tok\n );\n }\n if (this._pendingWarnings.length > 0) {\n node.warnings ??= [];\n for (const w of this._pendingWarnings) node.warnings.push(w);\n this._pendingWarnings = [];\n }\n node.start = start;\n node.end = this.t.lastEndOffset;\n return node;\n }\n\n private _parseValueNode(): CborItem {\n const tok = this.t.peek();\n switch (tok.type) {\n case 'INTEGER':\n return this.parseIntegerOrTag();\n case 'FLOAT':\n return this.parseFloat();\n case 'TSTR':\n case 'RAWSTRING':\n return this.parseString();\n case 'BYTES_HEX':\n case 'SQSTR':\n case 'BYTES_B64': {\n this.t.consume();\n return this._parseBytesConcat(\n this._decodeBytesToken(tok),\n tok.type,\n tok.raw,\n tok.offset,\n tok.endOffset\n );\n }\n case 'EMPTY_INDEF_BYTES':\n this.t.consume();\n return new CborIndefiniteByteString([]);\n case 'EMPTY_INDEF_TEXT':\n this.t.consume();\n return new CborIndefiniteTextString([]);\n case 'TRUE':\n this.t.consume();\n return new CborSimple(21);\n case 'FALSE':\n this.t.consume();\n return new CborSimple(20);\n case 'NULL':\n this.t.consume();\n return new CborSimple(22);\n case 'UNDEFINED':\n this.t.consume();\n return new CborSimple(23);\n case 'SIMPLE':\n return this.parseSimple();\n case 'LBRACKET':\n return this.parseArray();\n case 'LBRACE':\n return this.parseMap();\n case 'LPAREN':\n return this.parseIndefGroup();\n case 'LT_LT':\n return this.parseEmbeddedCBOR();\n case 'APP_STRING': {\n this.t.consume();\n // Consume optional encoding indicator (e.g. float'fe00'_2).\n let appStrEw: EncodingWidth | undefined;\n let appStrEiRaw = '';\n if (this.t.peek().type === 'ENCODING_INDICATOR') {\n const eiTok = this.t.consume();\n appStrEw = this._resolveEncodingWidth(eiTok.value, eiTok);\n appStrEiRaw = eiTok.raw;\n }\n const ext = this.extByPrefix.get(tok.appPrefix!);\n if (!ext?.parseAppString) {\n if (!ext) this._hintMissingExtension(tok.appPrefix!, tok);\n if (this.unresolvedExtension === 'cpa999')\n return new CborUnresolvedAppExt(tok.appPrefix!, [\n new CborTextString(tok.value),\n ]);\n this._fail(\n `unknown app-string extension: ${JSON.stringify(tok.appPrefix)}`,\n tok\n );\n }\n {\n const warnsBefore = this._pendingWarnings.length;\n try {\n const result = ext.parseAppString(\n tok.appPrefix!,\n tok.value,\n this._extOnError(tok),\n appStrEw !== undefined ? { encodingWidth: appStrEw } : undefined\n );\n // Generic EI post-processing: apply encoding indicator when the\n // extension didn't handle it itself (e.g. dt'...'_2).\n if (appStrEw !== undefined)\n this._applyEiToResult(result, appStrEw, tok);\n if (ext.preserveAppSeqSource === 'optional') {\n // Same rationale as the APP_SEQUENCE case below: tack the\n // source onto the same result node so preserveAppPrefix can\n // round-trip prefix`...` (and non-canonical prefix'...')\n // spellings without changing the node's class/identity.\n result.appSeqSource = tok.raw + appStrEiRaw;\n return result;\n }\n // Propagate ednSource so preserveByteString / appPrefix round-trips correctly.\n // instanceof narrows the type; getPrototypeOf excludes subclasses like CborIpExt.\n if (\n result instanceof CborByteString &&\n Object.getPrototypeOf(result) === CborByteString.prototype &&\n result.ednSource === undefined\n )\n return new CborByteString(result.value, {\n ednEncoding: result.ednEncoding,\n encodingWidth: result.encodingWidth,\n ednSource: tok.raw + appStrEiRaw,\n // A prefix name alone can't say which comment syntax (if\n // any) this content actually uses: a user extension may be\n // registered under the same prefix as a built-in (`ext`\n // here is whichever one actually resolved — see the\n // registration order in the constructor). Only strip\n // comments from preserveByteString's spelling when `ext` is\n // provably the specific built-in b32/h32 object.\n ednCommentSyntax:\n ext === b32 || ext === h32 ? 'full' : undefined,\n });\n if (result instanceof CborFloat && result.ednSource === undefined)\n result.ednSource = tok.raw + appStrEiRaw;\n return result;\n } catch (e) {\n if (this._options.strict !== false) throw e;\n if (this._pendingWarnings.length === warnsBefore)\n this._warn(e instanceof Error ? e.message : String(e), tok);\n return new CborUnresolvedAppExt(tok.appPrefix!, [\n new CborTextString(tok.value),\n ]);\n }\n }\n }\n case 'APP_SEQUENCE': {\n const commentStartIndex = this.t.comments.length;\n this.t.consume();\n const items: CborItem[] = [];\n while (this.t.peek().type !== 'GT_GT') {\n if (this.t.peek().type === 'EOF')\n this._fail(`unterminated ${tok.appPrefix!}<<...>>`, tok);\n if (items.length > 0) {\n if (this.t.peek().type === 'COMMA') {\n this.t.consume();\n if (this.t.peek().type === 'GT_GT') break; // trailing comma\n } else if (this.t.peek().offset === this.t.lastEndOffset) {\n this._warnOrFail(\n '<<...>> items must be separated by \",\" or whitespace',\n this.t.peek()\n );\n }\n }\n items.push(this.parseValue());\n }\n this.expect('GT_GT');\n let seqEw: EncodingWidth | undefined;\n let seqEiTok: Token | undefined;\n if (this.t.peek().type === 'ENCODING_INDICATOR') {\n seqEiTok = this.t.consume();\n seqEw = this._resolveEncodingWidth(seqEiTok.value, seqEiTok);\n }\n const seqExt = this.extByPrefix.get(tok.appPrefix!);\n if (!seqExt) {\n this._hintMissingExtension(tok.appPrefix!, tok);\n if (this.unresolvedExtension === 'cpa999')\n return new CborUnresolvedAppExt(tok.appPrefix!, items);\n this._fail(\n `unknown app-string extension: ${JSON.stringify(tok.appPrefix)}`,\n tok\n );\n }\n if (!seqExt.parseAppSequence)\n this._fail(\n `app-string extension ${JSON.stringify(tok.appPrefix)} does not support <<...>> form`,\n tok\n );\n {\n const warnsBefore = this._pendingWarnings.length;\n try {\n const result = seqExt.parseAppSequence(\n tok.appPrefix!,\n items,\n this._extOnError(tok)\n );\n if (seqEw !== undefined)\n this._applyEiToResult(result, seqEw, seqEiTok ?? tok);\n const rawSource = this.t.source.slice(\n tok.offset,\n this.t.lastEndOffset\n );\n if (seqExt.preserveAppSeqSource === 'optional') {\n // Tack the source onto the same result node (preserving its\n // class/identity) rather than wrapping it; the node's own\n // _toCDN() decides whether to use it (see preserveAppPrefix).\n result.appSeqSource = rawSource;\n result.appSeqComments = relativeComments(\n this.t.comments,\n commentStartIndex,\n tok.offset,\n this.t.lastEndOffset\n );\n // Exact split point for adjustAppSeqIndicator to strip the\n // sole inner item's own indicator by position rather than by\n // pattern-matching text near '>>' (which whitespace, a\n // trailing comma, or a comment between the item and '>>'\n // would defeat).\n if (items.length === 1) {\n if (items[0].end !== undefined)\n result.appSeqInnerEnd = items[0].end - tok.offset;\n result.appSeqSourceFeatures = appSeqSourceFeatures(items[0]);\n }\n } else if (result instanceof CborFloat) {\n if (result.ednSource === undefined) result.ednSource = rawSource;\n } else if (seqExt.preserveAppSeqSource) {\n return new CborAppSeqResult(result, rawSource);\n }\n return result;\n } catch (e) {\n if (this._options.strict !== false) throw e;\n if (this._pendingWarnings.length === warnsBefore)\n this._warn(e instanceof Error ? e.message : String(e), tok);\n return new CborUnresolvedAppExt(tok.appPrefix!, items);\n }\n }\n }\n case 'ELLIPSIS': {\n this.t.consume();\n if (this.t.peek().type !== 'PLUS') return new CborEllipsis();\n const items: CborItem[] = [new CborEllipsis()];\n while (this.t.peek().type === 'PLUS') {\n this.t.consume();\n items.push(this.parseValue());\n }\n // Every item here came from an explicit `+` (this generic chain has\n // no notion of an elided-hex literal's internal `...`), so every\n // boundary is real.\n return new CborEllipsis(\n items,\n items.map(() => true)\n );\n }\n case 'BYTES_HEX_ELIDED': {\n this.t.consume();\n return this._parseHexElidedConcat(tok);\n }\n default:\n this._fail(`unexpected token: ${JSON.stringify(tok.value)}`, tok);\n }\n }\n\n private parseIntegerOrTag(): CborItem {\n const commentStartIndex = this.t.comments.length;\n const tok = this.t.consume(); // INTEGER\n const { numStr, rawSuffix } = parseIntegerRaw(tok.value);\n let tagIndicatorStart =\n rawSuffix !== undefined ? tok.endOffset - 2 : tok.endOffset;\n let tagIndicatorEnd = tok.endOffset;\n // Hex/octal/binary literals return before the suffix check in the tokenizer,\n // so their encoding indicator arrives as a separate ENCODING_INDICATOR token.\n let encodingWidth =\n rawSuffix !== undefined\n ? this._resolveEncodingWidth(rawSuffix, tok)\n : this.consumeEncodingIndicator(undefined, (eiTok) => {\n tagIndicatorStart = eiTok.offset;\n tagIndicatorEnd = eiTok.endOffset;\n });\n const n = parseBigInt(numStr);\n // tok.raw keeps a leading '+' that tok.value drops (e.g. \"+42\" → value\n // \"42\", raw \"+42\"); mirror the same suffix stripping applied to numStr\n // so the preserved spelling matches what the user actually wrote.\n const ednSource = rawSuffix !== undefined ? tok.raw.slice(0, -2) : tok.raw;\n\n // Out-of-range integers become bignum tags per RFC 8949 §3.4.3.\n // Tag numbers must fit in uint64, so a value > UINT64_MAX before '(' is an error.\n if (n > 0xffff_ffff_ffff_ffffn) {\n if (this.t.peek().type === 'LPAREN')\n this._fail('tag number exceeds maximum uint64', tok);\n return new CborBigUint(n);\n }\n if (n < -(0xffff_ffff_ffff_ffffn + 1n)) {\n return new CborBigNint(n);\n }\n\n // Validate that the value fits in the requested encoding width.\n // For nint, the CBOR argument is abs(n)−1 (e.g. -1 → 0, -24 → 23).\n if (encodingWidth !== undefined) {\n const storedValue = n >= 0n ? n : -(n + 1n);\n encodingWidth = this._validateEncodingFit(\n storedValue,\n encodingWidth,\n tok\n );\n }\n\n const intNode =\n n >= 0n\n ? new CborUint(n, { encodingWidth, ednSource })\n : new CborNint(n, { encodingWidth, ednSource });\n\n // integer followed by '(' → tagged data item\n if (this.t.peek().type === 'LPAREN') {\n if (!(intNode instanceof CborUint))\n this._fail('tag number must be non-negative', tok);\n this.t.consume(); // (\n // Rescue setup warnings before content's parseValue() drains them into the content node.\n const setupWarnings = this._pendingWarnings.splice(0);\n const content = this.parseValue();\n this.expect('RPAREN');\n const tagNum = intNode.value;\n const ext = this.extByTag.get(tagNum);\n if (ext?.parseTag) {\n const result = ext.parseTag(tagNum, content);\n if (result !== undefined) {\n if (result instanceof CborTag) {\n if (\n encodingWidth !== undefined &&\n result.encodingWidth === undefined\n )\n result.encodingWidth = encodingWidth;\n if (result.ednSource === undefined) result.ednSource = ednSource;\n if (\n ext.preserveAppSeqSource === 'optional' &&\n result.appSeqSource === undefined\n ) {\n // Raw tag notation (e.g. 1(1749772800)) is itself a spelling\n // that preserveAppPrefix should be able to keep instead of\n // upgrading it to regenerated DT'...' notation.\n result.appSeqSource = this.t.source.slice(\n tok.offset,\n this.t.lastEndOffset\n );\n result.appSeqComments = relativeComments(\n this.t.comments,\n commentStartIndex,\n tok.offset,\n this.t.lastEndOffset\n );\n const tagWidth =\n result.encodingWidth ?? canonicalEncodingWidth(result.tag);\n const contentEdits = collectContentEncodingEdits(\n this.t.source,\n tok.offset,\n result.content\n );\n result.appSeqEncodingEdits = [\n {\n start: tagIndicatorStart - tok.offset,\n end: tagIndicatorEnd - tok.offset,\n always: `_${tagWidth}`,\n never: '',\n },\n ...(contentEdits ?? []),\n ];\n if (contentEdits === undefined)\n result.appSeqEncodingEditsComplete = false;\n result.appSeqSourceFeatures = appSeqSourceFeatures(content);\n }\n }\n if (setupWarnings.length > 0) {\n result.warnings ??= [];\n result.warnings.push(...setupWarnings);\n }\n return result;\n }\n }\n const tagResult = new CborTag(tagNum, content, {\n encodingWidth,\n ednSource,\n });\n if (setupWarnings.length > 0) {\n tagResult.warnings ??= [];\n tagResult.warnings.push(...setupWarnings);\n }\n return tagResult;\n }\n return intNode;\n }\n\n private parseFloat(): CborItem {\n const tok = this.t.consume(); // FLOAT\n const onRecoverableError = (msg: string) => this._warnOrFail(msg, tok);\n const { value, precision } = parseFloatToken(tok.value, onRecoverableError);\n if (precision === 'half' || precision === 'single') {\n const roundTripped =\n precision === 'half'\n ? float16BitsToFloat64(float64ToFloat16Bits(value))\n : Math.fround(value);\n const lossless =\n Object.is(value, roundTripped) || (isNaN(value) && isNaN(roundTripped));\n if (!lossless)\n onRecoverableError(\n `${value} cannot be exactly represented as ${precision === 'half' ? 'f16 (_1)' : 'f32 (_2)'}; use _3 or remove the indicator`\n );\n }\n // tok.raw keeps a leading '+' that tok.value drops (e.g. \"+1.5\" → value\n // \"1.5\", raw \"+1.5\"; likewise \"+Infinity\" → value \"Infinity\").\n return new CborFloat(value, { precision, literalSource: tok.raw });\n }\n\n private parseString(): CborItem {\n const tok = this.t.consume(); // STRING\n\n // Fast path: no concatenation\n if (this.t.peek().type !== 'PLUS') {\n const ew = this.consumeEncodingIndicator(() =>\n BigInt(textEncoder.encode(tok.value).length)\n );\n if (tok.type === 'RAWSTRING')\n return new CborTextString(tok.value, {\n ednSource: tok.raw,\n ...(ew !== undefined ? { encodingWidth: ew } : {}),\n });\n return new CborTextString(tok.value, {\n quotedEdnSource: tok.raw,\n ...(ew !== undefined ? { encodingWidth: ew } : {}),\n });\n }\n\n // Concatenation chain — may include ellipsis, producing CborEllipsis\n let hasEllipsis = false;\n const parts: Array<\n | {\n text: string;\n source?: string;\n isByteString?: boolean;\n start: number;\n end: number;\n }\n | { ellipsis: true; start: number; end: number }\n > = [\n tok.type === 'RAWSTRING'\n ? {\n text: tok.value,\n source: tok.raw,\n start: tok.offset,\n end: tok.endOffset,\n }\n : { text: tok.value, start: tok.offset, end: tok.endOffset },\n ];\n\n while (this.t.peek().type === 'PLUS') {\n this.t.consume(); // +\n const next = this.t.peek();\n if (next.type === 'ELLIPSIS') {\n this.t.consume();\n parts.push({ ellipsis: true, start: next.offset, end: next.endOffset });\n hasEllipsis = true;\n } else if (next.type === 'TSTR' || next.type === 'RAWSTRING') {\n this.t.consume();\n parts.push(\n next.type === 'RAWSTRING'\n ? {\n text: next.value,\n source: next.raw,\n start: next.offset,\n end: next.endOffset,\n }\n : { text: next.value, start: next.offset, end: next.endOffset }\n );\n } else if (this._isBytesToken(next.type)) {\n this.t.consume();\n parts.push({\n text: this._decodeUtf8(this._decodeBytesToken(next), next),\n // draft-25 §5.1: this part is a byte-string literal decoded to text, not a\n // double-quoted literal — appSeqSourceFeatures must attribute it\n // to `byteString`, not the unpreservable `textString`, since both\n // leave `source` undefined here.\n isByteString: true,\n start: next.offset,\n end: next.endOffset,\n });\n } else {\n this._fail(\n `expected string or byte string after +, got ${JSON.stringify(next.value)}`,\n next\n );\n }\n }\n\n if (!hasEllipsis) {\n // No ellipsis — join all text fragments into a single CborTextString,\n // keeping the part boundaries for `preserveConcatenation`.\n const texts = parts.map((p) => ('text' in p ? p.text : ''));\n const sources = parts.map((p) => ('text' in p ? p.source : undefined));\n const isByteStringFlags = parts.map((p) =>\n 'text' in p ? (p.isByteString ?? false) : false\n );\n const spans = parts.map((p) => ({ start: p.start, end: p.end }));\n const joined = texts.join('');\n const ew = this.consumeEncodingIndicator(() =>\n BigInt(textEncoder.encode(joined).length)\n );\n return new CborTextString(joined, {\n ednParts: texts,\n ednPartSpans: spans,\n ...(sources.some((s) => s !== undefined)\n ? { ednPartSources: sources }\n : {}),\n ...(isByteStringFlags.some((b) => b)\n ? { ednPartIsByteString: isByteStringFlags }\n : {}),\n ...(ew !== undefined ? { encodingWidth: ew } : {}),\n });\n }\n\n // Build 888([...]) with consolidated adjacent text fragments, retaining\n // the original boundaries and raw source spellings within each fragment.\n const items: CborItem[] = [];\n const currentParts: Array<{\n text: string;\n source?: string;\n isByteString?: boolean;\n start: number;\n end: number;\n }> = [];\n const flushCurrentParts = () => {\n const texts = currentParts.map((part) => part.text);\n const currentText = texts.join('');\n if (currentText !== '') {\n const sources = currentParts.map((part) => part.source);\n const isByteStringFlags = currentParts.map(\n (part) => part.isByteString ?? false\n );\n const spans = currentParts.map((part) => ({\n start: part.start,\n end: part.end,\n }));\n const node = new CborTextString(currentText, {\n ednParts: texts,\n ednPartSpans: spans,\n ...(sources.some((source) => source !== undefined)\n ? { ednPartSources: sources }\n : {}),\n ...(isByteStringFlags.some((b) => b)\n ? { ednPartIsByteString: isByteStringFlags }\n : {}),\n });\n // Stamp the generic start/end span so `attachComments` (run once,\n // after the whole tree is built) can attach a comment between this\n // item and its neighbour in `items` as `leading`/`trailing`, exactly\n // like any other array entry — see\n // `CborEllipsis._toCDN`'s text-elision rendering.\n node.start = currentParts[0]!.start;\n node.end = currentParts[currentParts.length - 1]!.end;\n items.push(node);\n }\n currentParts.length = 0;\n };\n for (const part of parts) {\n if ('ellipsis' in part) {\n flushCurrentParts();\n const ellipsisNode = new CborEllipsis();\n ellipsisNode.start = part.start;\n ellipsisNode.end = part.end;\n items.push(ellipsisNode);\n } else {\n currentParts.push(part);\n }\n }\n flushCurrentParts();\n\n return new CborEllipsis(items);\n }\n\n private _isBytesToken(type: string): boolean {\n return type === 'BYTES_HEX' || type === 'SQSTR' || type === 'BYTES_B64';\n }\n\n /**\n * Decode a hex payload, converting the codec's plain SyntaxError (e.g. odd\n * length) into a CdnSyntaxError carrying the token's position.\n */\n private _hexToBytes(hex: string, tok: Token): Uint8Array {\n try {\n return hexToBytes(hex);\n } catch (e) {\n if (e instanceof CdnSyntaxError || !(e instanceof SyntaxError)) throw e;\n this._fail(e.message, tok);\n }\n }\n\n private _decodeBytesToken(tok: Token): Uint8Array {\n const onRecoverableError = (msg: string) => this._warnOrFail(msg, tok);\n switch (tok.type) {\n case 'SQSTR': {\n // The tokenizer attaches the UTF-8 payload it already encoded;\n // decoding the hex `value` again would just rebuild the same bytes.\n const bytes = (tok as SqstrToken)._sqstrBytes;\n if (bytes !== undefined) return bytes;\n return this._hexToBytes(tok.value, tok);\n }\n case 'BYTES_HEX':\n return this._hexToBytes(tok.value, tok);\n case 'BYTES_B64':\n try {\n return base64ToBytes(tok.value, onRecoverableError);\n } catch (e) {\n if (e instanceof CdnSyntaxError || !(e instanceof SyntaxError))\n throw e;\n this._fail(e.message, tok);\n }\n default:\n this._fail(`expected byte string token`, tok);\n }\n }\n\n private _decodeUtf8(bytes: Uint8Array, tok: Token): string {\n if (this._options.allowInvalidUtf8) return utf8Lenient.decode(bytes);\n try {\n return utf8Strict.decode(bytes);\n } catch {\n const msg = 'byte string in text concatenation is not valid UTF-8';\n this._warnOrFail(msg, tok);\n return utf8Lenient.decode(bytes);\n }\n }\n\n private _tokenTypeToCdnEncoding(type: string): 'hex' | 'base64' {\n return type === 'BYTES_B64' ? 'base64' : 'hex';\n }\n\n /**\n * Comment syntax (if any) for a *core* byte-string token type (never an\n * app-string extension's — those are resolved by extension identity, not\n * token type, since `_isBytesToken` excludes `APP_STRING` and extension\n * prefixes can never take part in `+`/ellipsis concatenation). `BYTES_HEX`\n * (and its elided form) uses the full syntax; `BYTES_B64` only `#`; `SQSTR`\n * none at all.\n */\n private _tokenTypeToCommentSyntax(\n type: string\n ): ByteCommentSyntax | undefined {\n if (type === 'BYTES_HEX') return 'full';\n if (type === 'BYTES_B64') return 'hash-only';\n return undefined;\n }\n\n private _parseBytesConcat(\n first: Uint8Array,\n firstType: string,\n firstSource: string,\n firstStart: number,\n firstEnd: number\n ): CborByteString | CborEllipsis {\n if (this.t.peek().type !== 'PLUS') {\n const ew = this.consumeEncodingIndicator(() => BigInt(first.length));\n const ednEncoding = this._tokenTypeToCdnEncoding(firstType);\n return new CborByteString(first, {\n ednEncoding,\n ednSource: firstSource,\n ednCommentSyntax: this._tokenTypeToCommentSyntax(firstType),\n ...(ew !== undefined ? { encodingWidth: ew } : {}),\n });\n }\n const initial: ByteEllipsisAtom[] = [\n {\n bytes: first,\n source: firstSource,\n commentSyntax: this._tokenTypeToCommentSyntax(firstType),\n real: false,\n start: firstStart,\n end: firstEnd,\n },\n ];\n const atoms = this._consumeByteEllipsisChain(initial);\n return this._buildFromByteAtoms(\n atoms,\n this._tokenTypeToCdnEncoding(firstType)\n );\n }\n\n /**\n * Parse a BYTES_HEX_ELIDED token (h'xx...yy') and any trailing + concatenation\n * into a CborEllipsis([h'xx', 888(null), h'yy', ...]).\n */\n private _parseHexElidedConcat(firstTok: Token): CborEllipsis {\n const atoms = this._consumeByteEllipsisChain(\n this._elidedHexAtoms(firstTok.value, firstTok)\n );\n // Always has at least one ellipsis atom — it came from an elided token.\n return this._buildFromByteAtoms(atoms, 'hex') as CborEllipsis;\n }\n\n /**\n * Consume a `+`-chain of byte-string / `...` / `h'xx...yy'` tokens\n * following an already-parsed first fragment, returning the flattened,\n * source-ordered atom list (`initial` plus everything the chain adds).\n *\n * Each atom carries `real`: whether a genuine `+` from the source\n * precedes it — as opposed to an ellipsis or byte segment that sits\n * *inside* a single `h'xx...yy'` literal's own notation. Two literal\n * tokens can only end up adjacent with no ellipsis between them by\n * sitting across a `+` (a single elided-hex token's internal segments are\n * always ellipsis-separated from each other), so every atom appended here\n * — the first one from each new token, and every atom of a plain\n * (non-elided) byte token — is real; only an elided token's *internal*\n * segments (beyond its first) are not.\n */\n private _consumeByteEllipsisChain(\n initial: ByteEllipsisAtom[]\n ): ByteEllipsisAtom[] {\n const atoms = initial;\n while (this.t.peek().type === 'PLUS') {\n this.t.consume(); // +\n const next = this.t.peek();\n if (next.type === 'ELLIPSIS') {\n this.t.consume();\n atoms.push({\n ellipsis: true,\n real: true,\n fromByteLiteral: false,\n start: next.offset,\n end: next.endOffset,\n });\n } else if (next.type === 'BYTES_HEX_ELIDED') {\n this.t.consume();\n const sub = this._elidedHexAtoms(next.value, next);\n if (sub.length > 0) sub[0]!.real = true;\n pushAll(atoms, sub);\n } else if (this._isBytesToken(next.type)) {\n this.t.consume();\n atoms.push({\n bytes: this._decodeBytesToken(next),\n source: next.raw,\n commentSyntax: this._tokenTypeToCommentSyntax(next.type),\n real: true,\n start: next.offset,\n end: next.endOffset,\n });\n } else if (next.type === 'TSTR' || next.type === 'RAWSTRING') {\n // draft-25 §5.1: when a byte string leads, the right-hand side must also be a\n // byte string. Text strings are only allowed on the right of a\n // text-leading concatenation. In non-strict mode we UTF-8 encode\n // the text and continue; in strict mode this is a hard error.\n this.t.consume();\n const mixMsg =\n 'text string in a byte-string concatenation is not allowed; ' +\n \"use a byte string literal (h'...', b64'...', or '...') instead\";\n this._warnOrFail(mixMsg, next);\n atoms.push({\n bytes: textEncoder.encode(next.value),\n real: true,\n start: next.offset,\n end: next.endOffset,\n });\n } else {\n this._fail(\n `expected byte string after +, got ${JSON.stringify(next.value)}`,\n next\n );\n }\n }\n return atoms;\n }\n\n /** Flatten a single BYTES_HEX_ELIDED token's own `h'xx...yy...zz'` content\n * into atoms, all marked non-`real`: none of its internal segments sit\n * across an actual `+`. Every ellipsis atom is `fromByteLiteral: true` —\n * it came from this literal's own notation, regardless of where within\n * it (leading, trailing, or in the middle). The caller fixes up the very\n * first atom's `real` flag if this token itself followed a `+`. */\n private _elidedHexAtoms(\n hexWithEllipsis: string,\n tok: Token\n ): ByteEllipsisAtom[] {\n const segments = hexWithEllipsis.split('...');\n const atoms: ByteEllipsisAtom[] = [];\n for (let i = 0; i < segments.length; i++) {\n if (i > 0)\n atoms.push({\n ellipsis: true,\n real: false,\n fromByteLiteral: true,\n literalSource: tok.raw,\n start: tok.offset,\n end: tok.endOffset,\n });\n if (segments[i].length > 0) {\n atoms.push({\n bytes: this._hexToBytes(segments[i], tok),\n commentSyntax: 'full',\n real: false,\n start: tok.offset,\n end: tok.endOffset,\n });\n }\n }\n return atoms;\n }\n\n /**\n * Build the final `CborByteString` (no ellipsis anywhere) or `CborEllipsis`\n * from a flattened atom list, consolidating adjacent byte atoms with no\n * ellipsis between them into one `CborByteString` — retaining `ednParts`\n * for a fragment that merged multiple `real` (`+`-joined) atoms — and\n * building a `realBoundary` array parallel to the resulting `CborEllipsis`\n * items, so `preserveConcatenation` can tell real `+` boundaries apart\n * from a `h'xx...yy'` literal's own internal notation regardless of where\n * the `...` falls within it.\n */\n private _buildFromByteAtoms(\n atoms: ByteEllipsisAtom[],\n ednEncoding: 'hex' | 'base64'\n ): CborByteString | CborEllipsis {\n const hasEllipsis = atoms.some((a) => 'ellipsis' in a);\n if (!hasEllipsis) {\n const byteParts = atoms as Array<{\n bytes: Uint8Array;\n source?: string;\n commentSyntax?: ByteCommentSyntax;\n start?: number;\n end?: number;\n }>;\n const concat = this._concatBytes(byteParts.map((p) => p.bytes));\n const ew = this.consumeEncodingIndicator(() => BigInt(concat.length));\n return new CborByteString(concat, {\n ednEncoding,\n ednParts: byteParts,\n ...(ew !== undefined ? { encodingWidth: ew } : {}),\n });\n }\n\n const items: CborItem[] = [];\n const realBoundary: boolean[] = [];\n const pending: Array<{\n bytes: Uint8Array;\n source?: string;\n commentSyntax?: ByteCommentSyntax;\n real: boolean;\n start?: number;\n end?: number;\n }> = [];\n const flushPending = () => {\n if (pending.length > 0) {\n const node = new CborByteString(\n this._concatBytes(pending.map((p) => p.bytes)),\n {\n // A single fragment (no merge across a real `+`) still needs its\n // own source spelling preserved — e.g. the sole byte atom\n // adjacent to an ellipsis in `h'41' + ...` — so\n // `preserveByteString` has something to round-trip.\n ...(pending.length > 1\n ? {\n ednParts: pending.map(\n ({ bytes, source, commentSyntax, start, end }) => ({\n bytes,\n source,\n commentSyntax,\n start,\n end,\n })\n ),\n }\n : {\n ednSource: pending[0]!.source,\n ednCommentSyntax: pending[0]!.commentSyntax,\n }),\n }\n );\n // Stamp the generic start/end span so `attachComments` (run once,\n // after the whole tree is built) can attach a comment between this\n // item and its neighbour in `items` as `leading`/`trailing`, exactly\n // like any other array entry — see `CborEllipsis._renderPreservedBytesElision`.\n node.start = pending[0]!.start;\n node.end = pending[pending.length - 1]!.end;\n items.push(node);\n realBoundary.push(pending[0]!.real);\n pending.length = 0;\n }\n };\n for (const atom of atoms) {\n if ('ellipsis' in atom) {\n flushPending();\n const ellipsisNode = new CborEllipsis(\n atom.fromByteLiteral,\n atom.literalSource\n );\n ellipsisNode.start = atom.start;\n ellipsisNode.end = atom.end;\n items.push(ellipsisNode);\n realBoundary.push(atom.real);\n } else {\n pending.push(atom);\n }\n }\n flushPending();\n\n return new CborEllipsis(items, realBoundary);\n }\n\n private _concatBytes(parts: Uint8Array[]): Uint8Array {\n const total = parts.reduce((n, p) => n + p.byteLength, 0);\n const out = new Uint8Array(total);\n let off = 0;\n for (const p of parts) {\n out.set(p, off);\n off += p.byteLength;\n }\n return out;\n }\n\n private parseSimple(): CborSimple {\n this.t.consume(); // 'simple'\n this.expect('LPAREN');\n const numTok = this.t.peek();\n if (numTok.type !== 'INTEGER')\n this._fail(\n `expected integer inside simple(), got ${JSON.stringify(numTok.value)}`,\n numTok\n );\n this.t.consume();\n const { numStr } = parseIntegerRaw(numTok.value);\n const n = Number(parseBigInt(numStr));\n this.expect('RPAREN');\n return new CborSimple(n, { ednSource: numTok.raw });\n }\n\n private parseEmbeddedCBOR(): CborEmbeddedCBOR {\n this.t.consume(); // <<\n const items: CborItem[] = [];\n while (this.t.peek().type !== 'GT_GT') {\n if (items.length > 0) {\n if (this.t.peek().type === 'COMMA') {\n this.t.consume();\n if (this.t.peek().type === 'GT_GT') break; // trailing comma\n } else if (this.t.peek().offset === this.t.lastEndOffset) {\n this._warnOrFail(\n '<<...>> items must be separated by \",\" or whitespace',\n this.t.peek()\n );\n }\n }\n items.push(this.parseValue());\n }\n this.expect('GT_GT');\n let encodingWidth: EncodingWidth | undefined;\n if (this.t.peek().type === 'ENCODING_INDICATOR') {\n const eiTok = this.t.consume();\n encodingWidth = this._resolveEncodingWidth(eiTok.value, eiTok);\n }\n return new CborEmbeddedCBOR(items, { encodingWidth });\n }\n\n private parseArray(): CborArray {\n this.t.consume(); // [\n let indefiniteLength = false;\n let encodingWidth: EncodingWidth | undefined;\n let eiTok: Token | undefined;\n if (this.t.peek().type === 'UNDERSCORE') {\n this.t.consume();\n indefiniteLength = true;\n } else if (this.t.peek().type === 'ENCODING_INDICATOR') {\n eiTok = this.t.consume();\n if (eiTok.value === '7') {\n indefiniteLength = true;\n const msg =\n 'encoding indicator _7 is non-standard; use _ to indicate indefinite length';\n this._warnOrFail(msg, eiTok);\n eiTok = undefined;\n } else {\n encodingWidth = this._resolveEncodingWidth(eiTok.value, eiTok);\n }\n }\n // Rescue setup warnings before inner parseValue() calls drain them into child nodes.\n const setupWarnings = this._pendingWarnings.splice(0);\n const items: CborItem[] = [];\n let blankLineBoundary = this.t.lastEndOffset;\n while (this.t.peek().type !== 'RBRACKET') {\n if (items.length > 0) {\n if (this.t.peek().type === 'COMMA') {\n this.t.consume();\n if (this.t.peek().type === 'RBRACKET') break; // trailing comma\n } else if (this.t.peek().offset === this.t.lastEndOffset) {\n this._warnOrFail(\n 'array items must be separated by \",\" or whitespace',\n this.t.peek()\n );\n }\n }\n const item = this.parseValue();\n if (hasBlankLineBetween(this.t.source, blankLineBoundary, item.start!))\n item.blankLineBefore = true;\n blankLineBoundary = item.end!;\n items.push(item);\n }\n this.expect('RBRACKET');\n if (encodingWidth !== undefined && eiTok !== undefined) {\n encodingWidth = this._validateEncodingFit(\n BigInt(items.length),\n encodingWidth,\n eiTok\n );\n // _validateEncodingFit may add to _pendingWarnings; outer parseValue() flushes those.\n }\n const arrayResult = new CborArray(items, {\n indefiniteLength,\n encodingWidth,\n });\n if (setupWarnings.length > 0) {\n arrayResult.warnings ??= [];\n arrayResult.warnings.push(...setupWarnings);\n }\n return arrayResult;\n }\n\n private parseMap(): CborMap {\n this.t.consume(); // {\n let indefiniteLength = false;\n let encodingWidth: EncodingWidth | undefined;\n let eiTok: Token | undefined;\n if (this.t.peek().type === 'UNDERSCORE') {\n this.t.consume();\n indefiniteLength = true;\n } else if (this.t.peek().type === 'ENCODING_INDICATOR') {\n eiTok = this.t.consume();\n if (eiTok.value === '7') {\n indefiniteLength = true;\n const msg =\n 'encoding indicator _7 is non-standard; use _ to indicate indefinite length';\n this._warnOrFail(msg, eiTok);\n eiTok = undefined;\n } else {\n encodingWidth = this._resolveEncodingWidth(eiTok.value, eiTok);\n }\n }\n // Rescue setup warnings before inner parseValue() calls drain them into child nodes.\n const setupWarnings = this._pendingWarnings.splice(0);\n const entries: [CborItem, CborItem][] = [];\n let blankLineBoundary = this.t.lastEndOffset;\n while (this.t.peek().type !== 'RBRACE') {\n if (entries.length > 0) {\n if (this.t.peek().type === 'COMMA') {\n this.t.consume();\n if (this.t.peek().type === 'RBRACE') break; // trailing comma\n } else if (this.t.peek().offset === this.t.lastEndOffset) {\n this._warnOrFail(\n 'map entries must be separated by \",\" or whitespace',\n this.t.peek()\n );\n }\n }\n const key = this.parseValue();\n if (hasBlankLineBetween(this.t.source, blankLineBoundary, key.start!))\n key.blankLineBefore = true;\n this.expect('COLON');\n const val = this.parseValue();\n blankLineBoundary = val.end!;\n entries.push([key, val]);\n }\n this.expect('RBRACE');\n if (encodingWidth !== undefined && eiTok !== undefined) {\n encodingWidth = this._validateEncodingFit(\n BigInt(entries.length),\n encodingWidth,\n eiTok\n );\n }\n const mapResult = new CborMap(entries, { indefiniteLength, encodingWidth });\n if (setupWarnings.length > 0) {\n mapResult.warnings ??= [];\n mapResult.warnings.push(...setupWarnings);\n }\n return mapResult;\n }\n\n /** Parses `(_ chunk, chunk, ...)` — indefinite byte or text string. */\n private parseIndefGroup():\n CborIndefiniteByteString | CborIndefiniteTextString {\n this.t.consume(); // (\n const next = this.t.peek();\n if (next.type === 'UNDERSCORE') {\n this.t.consume(); // _\n } else if (next.type === 'ENCODING_INDICATOR' && next.value === '7') {\n this.t.consume(); // _7 — alias for _, but non-standard\n const msg7 =\n 'encoding indicator _7 is non-standard; use _ to indicate indefinite length';\n this._warnOrFail(msg7, next);\n } else if (next.type === 'ENCODING_INDICATOR') {\n // _0–_6: not meaningful here; warn and drop, then parse chunks\n const tok = this.t.consume();\n const msg = `encoding indicator _${tok.value} is not valid in an indefinite string group; use _`;\n this._warnOrFail(msg, tok);\n } else if (next.type !== 'RPAREN') {\n // No indicator at all — warn that _ is expected, then parse chunks\n const msg =\n 'indefinite string group is missing _ after (; interpreting as (_ ...)';\n this._warnOrFail(msg, next);\n // Do not consume — the next token is the first chunk\n }\n\n // Rescue any warnings emitted above from _pendingWarnings before inner\n // parseValue() calls for each chunk drain them into the wrong node.\n const setupWarnings = this._pendingWarnings.splice(0);\n\n const chunks: CborItem[] = [];\n let blankLineBoundary = this.t.lastEndOffset;\n while (this.t.peek().type !== 'RPAREN') {\n if (chunks.length > 0) {\n if (this.t.peek().type === 'COMMA') {\n this.t.consume();\n if (this.t.peek().type === 'RPAREN') break; // trailing comma\n } else if (this.t.peek().offset === this.t.lastEndOffset) {\n this._warnOrFail(\n 'indefinite string chunks must be separated by \",\" or whitespace',\n this.t.peek()\n );\n }\n }\n const chunk = this.parseValue();\n if (hasBlankLineBetween(this.t.source, blankLineBoundary, chunk.start!))\n chunk.blankLineBefore = true;\n blankLineBoundary = chunk.end!;\n chunks.push(chunk);\n }\n this.expect('RPAREN');\n\n if (chunks.length === 0)\n this._fail(\n 'empty indefinite group (_ ) is ambiguous; use \\'\\'_ for bytes or \"\"_ for text'\n );\n\n const first = chunks[0];\n // All chunks must be the same type — mixing byte and text strings is\n // a SyntaxError per draft §4.3.\n if (first instanceof CborByteString) {\n const byteChunks = chunks.map((c, i) => {\n if (c instanceof CborByteString) return c;\n this._fail(\n `indefinite byte string chunk ${i} must be a byte string, not a text string`\n );\n });\n const result = new CborIndefiniteByteString(byteChunks);\n if (setupWarnings.length > 0) result.warnings = setupWarnings;\n return result;\n }\n if (first instanceof CborTextString) {\n const textChunks = chunks.map((c, i) => {\n if (c instanceof CborTextString) return c;\n this._fail(\n `indefinite text string chunk ${i} must be a text string, not a byte string`\n );\n });\n const result = new CborIndefiniteTextString(textChunks);\n if (setupWarnings.length > 0) result.warnings = setupWarnings;\n return result;\n }\n this._fail('indefinite group chunks must be byte strings or text strings');\n }\n\n // ── Helpers ─────────────────────────────────────────────────────────────\n\n /**\n * Consume an ENCODING_INDICATOR token if present.\n * Validates the indicator type (reserved/indefinite), and when\n * `getStoredValue` is supplied also checks that the value fits in the\n * requested encoding width. The stored value is computed lazily — only\n * when an indicator is actually present — so callers can pass e.g. a\n * UTF-8 byte-length computation without paying for it on every string.\n */\n private consumeEncodingIndicator(\n getStoredValue?: () => bigint,\n onToken?: (token: Token) => void\n ): EncodingWidth | undefined {\n if (this.t.peek().type === 'ENCODING_INDICATOR') {\n const tok = this.t.consume();\n onToken?.(tok);\n let ew = this._resolveEncodingWidth(tok.value, tok);\n if (ew !== undefined && getStoredValue !== undefined) {\n ew = this._validateEncodingFit(getStoredValue(), ew, tok);\n }\n return ew;\n }\n return undefined;\n }\n\n private expect(type: TokenType): Token {\n const tok = this.t.consume();\n if (tok.type !== type)\n this._fail(\n `expected ${type}, got ${tok.type} (${JSON.stringify(tok.value)})`,\n tok\n );\n return tok;\n }\n\n /**\n * Validate that `storedValue` fits in the given encoding width.\n * Returns `ew` if valid; warns and returns `undefined` if not (throws in strict mode).\n * `storedValue` is the CBOR argument: the integer itself for uint/tag, `abs(n)−1` for nint,\n * the byte-length for strings, or the item count for arrays/maps.\n */\n /** Apply an encoding indicator to a parsed app-string / app-sequence result. */\n private _applyEiToResult(\n result: CborItem,\n ew: EncodingWidth,\n tok: Token\n ): void {\n if (result instanceof CborFloat) {\n const targetPrec: FloatPrecision | undefined =\n ew === 1\n ? 'half'\n : ew === 2\n ? 'single'\n : ew === 3\n ? 'double'\n : undefined;\n if (targetPrec === undefined) {\n this._warnOrFail(\n `encoding indicator _${ew} is not valid for a float; use _1, _2, or _3`,\n tok\n );\n } else if (result.precision !== targetPrec) {\n if (targetPrec !== 'double') {\n const rt =\n targetPrec === 'half'\n ? float16BitsToFloat64(float64ToFloat16Bits(result.value))\n : Math.fround(result.value);\n if (!Object.is(rt, result.value) && !isNaN(result.value))\n this._warnOrFail(\n `${result.value} cannot be exactly represented as ${targetPrec === 'half' ? 'float16 (_1)' : 'float32 (_2)'}`,\n tok\n );\n }\n result.precision = targetPrec;\n }\n } else if (result instanceof CborUint) {\n if (result.encodingWidth === undefined) {\n const ewv = this._validateEncodingFit(result.value, ew, tok);\n if (ewv !== undefined) result.encodingWidth = ewv;\n }\n } else if (result instanceof CborNint) {\n if (result.encodingWidth === undefined) {\n const ewv = this._validateEncodingFit(result.argument, ew, tok);\n if (ewv !== undefined) result.encodingWidth = ewv;\n }\n } else if (result instanceof CborByteString) {\n if (result.encodingWidth === undefined) {\n const ewv = this._validateEncodingFit(\n BigInt(result.value.length),\n ew,\n tok\n );\n if (ewv !== undefined) result.encodingWidth = ewv;\n }\n } else if (result instanceof CborTextString) {\n if (result.encodingWidth === undefined) {\n const ewv = this._validateEncodingFit(\n BigInt(textEncoder.encode(result.value).length),\n ew,\n tok\n );\n if (ewv !== undefined) result.encodingWidth = ewv;\n }\n } else if (result instanceof CborArray) {\n if (result.encodingWidth === undefined) {\n const ewv = this._validateEncodingFit(\n BigInt(result.items.length),\n ew,\n tok\n );\n if (ewv !== undefined) result.encodingWidth = ewv;\n }\n } else if (result instanceof CborMap) {\n if (result.encodingWidth === undefined) {\n const ewv = this._validateEncodingFit(\n BigInt(result.entries.length),\n ew,\n tok\n );\n if (ewv !== undefined) result.encodingWidth = ewv;\n }\n } else if (result instanceof CborTag) {\n // Per draft-ietf-cbor-edn-literals-27 §4.1, the EI applies to\n // the tag number, not to the content (e.g. 1_1(4711) → 2-byte tag).\n if (result.encodingWidth === undefined) {\n const ewv = this._validateEncodingFit(result.tag, ew, tok);\n if (ewv !== undefined) result.encodingWidth = ewv;\n }\n } else {\n this._warnOrFail(\n `encoding indicator _${ew} is not applicable to this app-string result type`,\n tok\n );\n }\n }\n\n private _validateEncodingFit(\n storedValue: bigint,\n ew: EncodingWidth,\n tok: Token\n ): EncodingWidth | undefined {\n const max = maxForEncodingWidth(ew);\n if (storedValue <= max) return ew;\n const label = ew === 'i' ? '_i (max 23)' : `_${ew} (max ${max})`;\n const msg = `value ${storedValue} does not fit in encoding indicator ${label}`;\n this._warnOrFail(msg, tok);\n return undefined;\n }\n\n private _resolveEncodingWidth(\n raw: string,\n tok: Token\n ): EncodingWidth | undefined {\n if (raw === '4' || raw === '5' || raw === '6') {\n const ai = Number(raw) + 24; // 28, 29, or 30 — reserved in RFC 8949\n const msg = `encoding indicator _${raw} (AI ${ai}) is reserved and not valid`;\n this._warnOrFail(msg, tok);\n return undefined;\n }\n if (raw === '7') {\n const msg =\n 'indefinite-length encoding (_7) is not valid here; use [_ ...] or {_ ...} for indefinite collections';\n this._warnOrFail(msg, tok);\n return undefined;\n }\n if (raw === 'i') return 'i';\n return Number(raw) as EncodingWidth; // '0'–'3' → 0–3\n }\n\n /** Builds the onError callback passed to extension parseAppString/parseAppSequence. */\n private _extOnError(tok: Token): (msg: string) => void {\n return (msg: string) => this._warnOrFail(msg, tok);\n }\n\n /**\n * Record a strict violation: always emits a ParseWarning, and in strict\n * mode (the default) also throws a SyntaxError at the token's location.\n */\n private _warnOrFail(msg: string, tok?: Token): void {\n this._warn(msg, tok);\n if (this._options.strict !== false) this._fail(msg, tok);\n }\n\n /**\n * Emit a one-time, non-fatal hint when a known opt-in extension prefix\n * (b32, h32, float, same, hash, uuid) is used without the corresponding\n * extension registered. Never throws and does not attach node warnings;\n * parsing continues with the usual unresolved-extension handling.\n */\n private _hintMissingExtension(prefix: string, tok: Token): void {\n const hint = MISSING_EXTENSION_HINTS.get(prefix);\n if (hint === undefined || this._hintedPrefixes.has(prefix)) return;\n this._hintedPrefixes.add(prefix);\n const message = `app-string prefix '${prefix}' requires an extension that is not enabled; ${hint}`;\n if (this._options.onWarning) {\n this._options.onWarning({ message, ...tokenPosition(tok), hint: true });\n } else if (!this._options.silent) {\n console.warn(`CDN: ${message}`);\n }\n }\n\n private _warn(msg: string, tok?: Token): void {\n const warning: ParseWarning = { message: msg };\n if (tok !== undefined) Object.assign(warning, tokenPosition(tok));\n this._pendingWarnings.push(warning);\n if (this._options.onWarning) {\n this._options.onWarning(warning);\n } else if (!this._options.silent) {\n const loc = tok ? ` at line ${tok.line}, column ${tok.col}` : '';\n console.warn(`CDN strict violation${loc}: ${msg}`);\n }\n }\n\n private _fail(msg: string, tok?: Token): never {\n throw new CdnSyntaxError(msg, tok ? tokenPosition(tok) : undefined);\n }\n}\n\n/** A token's source position in the shape shared by ParseWarning and CdnSyntaxError. */\nfunction tokenPosition(tok: Token): {\n offset: number;\n line: number;\n column: number;\n endOffset: number;\n} {\n return {\n offset: tok.offset,\n line: tok.line,\n column: tok.col,\n endOffset: tok.endOffset,\n };\n}\n","import type {\n ToCDNOptions,\n ToJSOptions,\n ToCBOROptions,\n CborComment,\n} from '../types';\nimport { CborItem } from './CborItem';\nimport { MT_TEXT } from '../cbor/constants';\nimport type { CborWriter, EncodingWidth } from '../cbor/encode';\nimport { parseCDN } from '../cdn/parser';\n// Internal lexer reuse: parseCDN() validates embedded CDN first; this pass\n// only needs token offsets so string formatting can split without changing text.\nimport { Tokenizer, type TokenType, type SqstrToken } from '../cdn/tokenizer';\nimport {\n escapeString,\n indentOf,\n resolveIndent,\n resolveEiSuffix,\n canonicalEncodingWidth,\n danglingCommentsByGap,\n isMultiWordText,\n joinAppSeqParts,\n pushAll,\n shouldEmitComments,\n resolveCommentStyle,\n} from '../cdn/serialize-utils';\nimport { hexToBytes } from '../utils/hex';\nimport { base64ToBytes } from '../utils/base64';\n\nconst textEncoder = new TextEncoder();\nconst textDecoder = new TextDecoder();\nlet didWarnCborEdnTextStringFormat = false;\n\n/** CBOR Major Type 3 — definite-length UTF-8 text string. */\nexport class CborTextString extends CborItem {\n readonly indefiniteLength = false as const;\n readonly value: string;\n encodingWidth: EncodingWidth | undefined;\n /** Part boundaries of the original `+` concatenation chain, if any. */\n readonly ednParts: readonly string[] | undefined;\n /** Original raw-string source text, when parsed from a single backtick literal. */\n readonly ednSource: string | undefined;\n /**\n * Original double-quoted source text (including its escape sequences),\n * when parsed from a single non-concatenated `\"...\"` literal. Used by\n * `_toCDN()` to round-trip the literal's exact spelling when\n * `preserveTextString` is set.\n */\n readonly quotedEdnSource: string | undefined;\n /**\n * Original source text per `ednParts` entry, aligned by index; `undefined`\n * for parts that were not raw backtick literals.\n */\n readonly ednPartSources: readonly (string | undefined)[] | undefined;\n /**\n * `true` at index `i`, aligned with `ednParts`, when that part came from a\n * byte-string literal on the right of a text-leading `+` concatenation\n * (decoded as UTF-8 and merged in per draft-25 §5.1) rather than a double-quoted\n * `\"...\"` literal. Both cases leave `ednPartSources[i]` `undefined` (byte\n * strings have no preserved raw source here, same as an unpreserved\n * double-quoted literal), so this is what lets `appSeqSourceFeatures`\n * attribute the part to `byteString` instead of the unpreservable\n * `textString`.\n */\n readonly ednPartIsByteString: readonly boolean[] | undefined;\n /**\n * Source span of each `ednParts` entry's own literal token, aligned by\n * index — used to place a comment sitting between two `+`-joined parts at\n * the right gap instead of dropping it (there is no per-part AST node for\n * such a comment to attach to; it lands as `dangling` on this whole node\n * instead — see `CborByteString.ednParts`'s equivalent doc). `undefined`\n * for a node not parsed from a `+` chain at all.\n */\n readonly ednPartSpans: readonly { start: number; end: number }[] | undefined;\n\n constructor(\n value: string,\n options?: {\n encodingWidth?: EncodingWidth;\n ednParts?: readonly string[];\n ednSource?: string;\n quotedEdnSource?: string;\n ednPartSources?: readonly (string | undefined)[];\n ednPartIsByteString?: readonly boolean[];\n ednPartSpans?: readonly { start: number; end: number }[];\n }\n ) {\n super();\n this.value = value;\n this.encodingWidth = options?.encodingWidth;\n this.ednParts = options?.ednParts;\n this.ednSource = options?.ednSource;\n this.quotedEdnSource = options?.quotedEdnSource;\n this.ednPartSources = options?.ednPartSources;\n this.ednPartIsByteString = options?.ednPartIsByteString;\n this.ednPartSpans = options?.ednPartSpans;\n }\n\n override _isMultiWordText(\n _options: ToCDNOptions | undefined,\n _strict = true,\n _path?: readonly unknown[]\n ): boolean {\n return isMultiWordText(this.value);\n }\n\n override _encodeTo(writer: CborWriter, _options?: ToCBOROptions): void {\n writer.writeTextString(MT_TEXT, this.value, this.encodingWidth);\n }\n\n _toCDN(\n options: ToCDNOptions | undefined,\n depth: number,\n _path?: readonly unknown[]\n ): string {\n const suffix = resolveEiSuffix(options, this.encodingWidth, () =>\n canonicalEncodingWidth(BigInt(textEncoder.encode(this.value).length))\n );\n return formatTextString(\n this.value,\n suffix,\n options,\n depth,\n this.ednParts,\n this.ednSource,\n this.quotedEdnSource,\n this.ednPartSources,\n this.ednPartSpans,\n this.comments?.dangling\n );\n }\n\n _toJS(_options?: ToJSOptions): unknown {\n return this.value;\n }\n}\n\nfunction formatTextString(\n value: string,\n suffix: string,\n options: ToCDNOptions | undefined,\n depth: number,\n ednParts: readonly string[] | undefined,\n ednSource: string | undefined,\n quotedEdnSource: string | undefined,\n ednPartSources: readonly (string | undefined)[] | undefined,\n ednPartSpans: readonly { start: number; end: number }[] | undefined,\n dangling: readonly CborComment[] | undefined\n): string {\n const indentStr = resolveIndent(options);\n // A preserved raw backtick literal is emitted verbatim — re-escaping,\n // re-indenting, or splitting it would change its meaning or its\n // deliberately chosen form. In single-line mode a spelling that spans\n // multiple lines (raw strings are often written that way) cannot be\n // re-emitted, so it falls back to normal escaping instead.\n if (\n options?.preserveRawString &&\n ednSource !== undefined &&\n (indentStr !== null || !/[\\r\\n]/.test(ednSource))\n ) {\n return ednSource + suffix;\n }\n // Likewise for a preserved double-quoted literal: keep its original\n // escape-sequence spelling instead of re-escaping the decoded value.\n if (\n options?.preserveTextString &&\n quotedEdnSource !== undefined &&\n (indentStr !== null || !/[\\r\\n]/.test(quotedEdnSource))\n ) {\n return quotedEdnSource + suffix;\n }\n // Splits and preserved concatenation are layout features, disabled in\n // single-line mode: the string collapses to one literal.\n if (indentStr === null) {\n return escapeString(value) + suffix;\n }\n const partSources = options?.preserveRawString ? ednPartSources : undefined;\n const hasPreservedRawPart =\n partSources?.some((source) => source !== undefined) ?? false;\n const { cdn, newline } = resolveTextStringSplits(options);\n const preservedParts =\n options?.preserveConcatenation &&\n ednParts !== undefined &&\n (ednParts.length > 1 || hasPreservedRawPart)\n ? ednParts\n : undefined;\n\n if (!cdn && !newline && preservedParts === undefined) {\n return escapeString(value) + suffix;\n }\n\n const cdnBreakpoints = cdn\n ? collectCdnBreakpoints(value, !!options?.inlineLeafContainers, newline)\n : null;\n\n // Preserved concatenation applies unless CDN reflow is applicable (the\n // string content parses as CDN — then structure-aware indentation wins).\n // A preserved raw part takes precedence over CDN reflow because changing\n // its spelling would violate preserveRawString. `splitNewline` combines\n // with this path by further splitting only the non-raw parts.\n if (\n preservedParts !== undefined &&\n (cdnBreakpoints === null || hasPreservedRawPart)\n ) {\n // A comment between two `+`-joined parts has no per-part AST node of\n // its own to attach to — it lands as `dangling` on this whole node\n // instead (see `ednPartSpans`'s doc) — so re-derive which gap each one\n // belongs to from each part's own source span.\n const gapComments = shouldEmitComments(options)\n ? danglingCommentsByGap(\n dangling,\n ednPartSpans,\n resolveCommentStyle(options)\n )\n : undefined;\n const parts: StringPart[] = [];\n for (const [i, text] of preservedParts.entries()) {\n const source = partSources?.[i];\n if (source !== undefined) {\n parts.push({ text, contentDepth: 0, source });\n } else if (newline) {\n const partBreakpoints = new Map<number, number>();\n for (const { point, contentDepth } of collectNewlineBreakpoints(\n text,\n 0\n )) {\n partBreakpoints.set(point, contentDepth);\n }\n pushAll(parts, splitAtBreakpoints(text, partBreakpoints));\n } else {\n parts.push({ text, contentDepth: 0 });\n }\n // Whichever output part `text` ended up split into, the comment for\n // the gap right after it (if any) belongs on the last one — the true\n // `+` boundary to the next preserved part sits right there.\n const comments = gapComments?.[i];\n if (comments && comments.length > 0) {\n parts[parts.length - 1]!.commentsAfter = comments;\n }\n }\n if (options?.modernConcat && options?.appPrefix !== false) {\n const literals = parts.map(\n ({ text, source }) => source ?? escapeString(text)\n );\n const midComments = parts.map((p) => p.commentsAfter ?? []);\n return joinAppSeqParts(\n 't1',\n literals,\n suffix,\n indentStr,\n depth,\n midComments\n );\n }\n return emitParts(parts, suffix, indentStr, depth);\n }\n\n const breakpoints = new Map<number, number>();\n if (cdnBreakpoints !== null) {\n for (const { point, contentDepth } of cdnBreakpoints) {\n breakpoints.set(point, contentDepth);\n }\n }\n if (newline) {\n const newlineBreakpoints =\n cdnBreakpoints !== null\n ? collectCdnNewlineBreakpoints(value)\n : collectNewlineBreakpoints(value, 0);\n for (const { point, contentDepth } of newlineBreakpoints) {\n if (!breakpoints.has(point)) {\n breakpoints.set(point, contentDepth);\n }\n }\n }\n\n const parts = splitAtBreakpoints(value, breakpoints);\n if (parts.length <= 1) return escapeString(value) + suffix;\n return emitParts(parts, suffix, indentStr, depth);\n}\n\n/**\n * Serialize string parts as a `+` concatenation chain, one part per\n * continuation line indented by `depth + 1 + contentDepth`. The EI suffix\n * is appended to the last part. Only reached in multi-line mode — preserved\n * concatenation is disabled in single-line output.\n */\nfunction emitParts(\n parts: readonly StringPart[],\n suffix: string,\n indentStr: string,\n depth: number\n): string {\n const literals = parts.map(({ text, source }, i) => {\n const literal = source ?? escapeString(text);\n return i === parts.length - 1 ? literal + suffix : literal;\n });\n let result = literals[0]!;\n for (let i = 1; i < literals.length; i++) {\n const continuationIndent = indentOf(\n indentStr,\n depth + 1 + parts[i]!.contentDepth\n );\n result += ' +\\n';\n for (const comment of parts[i - 1]!.commentsAfter ?? []) {\n result += `${continuationIndent}${comment}\\n`;\n }\n result += `${continuationIndent}${literals[i]}`;\n }\n return result;\n}\n\n/**\n * Resolve the effective split strategies from `splitCdn` / `splitNewline`,\n * falling back per-field to the deprecated array-valued `textStringFormat`.\n */\nfunction resolveTextStringSplits(options: ToCDNOptions | undefined): {\n cdn: boolean;\n newline: boolean;\n} {\n const formats =\n options?.splitCdn === undefined || options?.splitNewline === undefined\n ? normalizeTextStringFormats(options?.textStringFormat ?? [])\n : [];\n return {\n cdn: options?.splitCdn ?? formats.includes('cdn'),\n newline: options?.splitNewline ?? formats.includes('newline'),\n };\n}\n\nfunction normalizeTextStringFormats(\n formats: NonNullable<ToCDNOptions['textStringFormat']>\n): ('newline' | 'cdn')[] {\n return formats.map((format) => {\n if (format !== 'cboredn') return format;\n if (!didWarnCborEdnTextStringFormat) {\n didWarnCborEdnTextStringFormat = true;\n console.warn(\n \"`textStringFormat: ['cboredn']` is deprecated; use `textStringFormat: ['cdn']` instead.\"\n );\n }\n return 'cdn';\n });\n}\n\ninterface StringBreakpoint {\n point: number;\n contentDepth: number;\n}\n\ninterface StringPart {\n text: string;\n contentDepth: number;\n /** Preserved literal source; emitted verbatim instead of escaping `text`. */\n source?: string;\n /**\n * Already-converted comment text that sat right after this part in the\n * source — a genuine `+` boundary this part precedes, not a further split\n * of the same original preserved part — emitted by `emitParts` right\n * before the next part.\n */\n commentsAfter?: string[];\n}\n\nfunction collectNewlineBreakpoints(\n value: string,\n contentDepth: number\n): StringBreakpoint[] {\n const points: StringBreakpoint[] = [];\n for (let i = 0; i < value.length; i++) {\n const ch = value[i];\n if (ch === '\\r') {\n if (value[i + 1] === '\\n') {\n points.push({ point: i + 2, contentDepth });\n i++;\n } else {\n points.push({ point: i + 1, contentDepth });\n }\n } else if (ch === '\\n') {\n points.push({ point: i + 1, contentDepth });\n }\n }\n return points;\n}\n\nfunction collectCdnBreakpoints(\n value: string,\n inlineLeafContainers: boolean,\n newline: boolean\n): StringBreakpoint[] | null {\n try {\n parseCDN(value);\n } catch {\n return null;\n }\n\n // The parse above validates structure. This second tokenizer pass only\n // collects original-source offsets and nesting depth for non-mutating splits.\n const points: StringBreakpoint[] = [];\n const tokenizer = new Tokenizer(value);\n let nesting = 0;\n let pending: {\n point: number;\n contentDepth: number;\n kind: 'opener' | 'comma';\n } | null = null;\n let sawToken = false;\n let lastTokenEnd = 0;\n // The token immediately before the current one (ignoring the EOF/first\n // iteration), used only to tell an integer-tag's `(` (`100(2)`) apart\n // from an indefinite-length string group's `(` (`(_ \"a\", \"b\")`) — both\n // tokenize as a bare LPAREN.\n let prevType: TokenType | null = null;\n\n // Mirrors serializeContainer's `inlineLeafContainers` probe on the real\n // AST, but over token spans instead of rendered strings: a bracket's own\n // breakpoints are held in `ownCandidates` until it closes, then either\n // discarded (stays on one line) or merged into the parent frame (or\n // `points`, at depth 0). Breakpoints inherited from a child that itself\n // couldn't be fully suppressed live separately in `childCandidates` —\n // those are never discardable no matter what this frame decides for its\n // own brackets (see the tag-paren case below), so they always forward.\n //\n // - LBRACKET/LBRACE (array/map) use the strict rule — no entry may\n // contain a nested array/map at any depth (`entryHasContainer`, set on\n // every currently-open frame so it reaches ancestors through wrapper\n // brackets), matching `_containsCdnContainer`.\n // - LT_LT (embedded CBOR) and APP_SEQUENCE (`prefix<<...>>`) use the\n // loose rule — the *only* frames whose own suppression is unconditional\n // (`isLooseFrame`, independent of `inlineLeafContainers`): an entry only\n // has to render without a break of its own (`entryForcedBreak`),\n // regardless of what it contains — matching CborEmbeddedCBOR's\n // `entryIsLeaf`-less, `alwaysInlineLeaf` probe. Resolved app-sequence\n // extensions vary in how they render, but this is the closest\n // approximation without invoking the parser's extension resolution.\n // - LPAREN as an indefinite-length string group (`(_ ...)` /\n // `CborIndefiniteTextString`/`ByteString`) uses the *strict* rule\n // instead, same as LBRACKET/LBRACE (and gated behind\n // `inlineLeafContainers` the same way, unlike LT_LT/APP_SEQUENCE) — a\n // chunk can never actually contain a nested array/map, so this only\n // differs from the loose rule in practice for a prefixed-literal byte\n // chunk (`h'...'`), which disqualifies here but not inside `<<...>>`.\n // - LPAREN as tag content (`100(2)`) has its *own* `(`/`)` breakpoints\n // unconditionally suppressed (once `inlineLeafContainers` is on)\n // regardless of `allOk`: real `CborTag` wraps its content with bare\n // parens (`renderSingleChildWithComments`) that never add their own\n // line break, even when the content itself renders multi-line — only\n // a comment forces it. But content that itself required real breaks\n // (e.g. `100([[1, 2], [3, 4]])`) still needs those breaks to show up\n // and to keep propagating outward — that's exactly what\n // `childCandidates` carries regardless of this frame's own decision.\n //\n // `entryForcedBreak` is only ever set on the immediate parent frame (not\n // eagerly on every ancestor like `entryHasContainer`): forwarding a\n // frame's breakpoints (own, child-inherited, or both) always marks the\n // parent's current entry forced, which in turn forwards *its* parent's\n // entry when it closes — so it cascades upward one level at a time.\n // `anyForcedBreak` is the same signal, but never reset between entries —\n // needed because a tag-paren frame ignores `entryForcedBreak`/`allOk`\n // for its *own* suppression (its parens stay tight either way), yet\n // still must tell its parent a break happened somewhere inside, even\n // when that break produced no breakpoint of its own to carry the\n // signal (e.g. a `splitNewline` break inside a nested string — the\n // actual breakpoint for that is added by a separate pass entirely).\n interface CdnFrame {\n kind: TokenType;\n isTagParen: boolean;\n // `true` for the one frame pushed immediately after `pushChainSuspend`\n // — the outermost bracket/tag of an ellipsis-led chain's own\n // continuation value (`... + (_ \"a\")`, `... + 100(\"a\")`, ...). Used\n // only to decide, when *this exact* frame closes and is a tag-paren,\n // whether a purely semantic multi-word signal from its content may\n // propagate outward — see `entryForcedBreakStructural` and the\n // `CLOSE_TOKENS` handling below.\n isChainContinuationRoot: boolean;\n openOffset: number;\n ownCandidates: StringBreakpoint[];\n childCandidates: StringBreakpoint[];\n entryHasContainer: boolean;\n entryForcedBreak: boolean;\n anyForcedBreak: boolean;\n // Mirrors `entryForcedBreak`/`anyForcedBreak`, but only for a\n // *structural* reason (a real embedded newline, or an actual forwarded\n // breakpoint from a nested container that genuinely expanded) — never\n // for the purely semantic \"this content is multi-word\" reason. A tag\n // never collapses/expands based on its content's word count the way a\n // real container does, and `CborEllipsis`'s own rendering never\n // delegates to a fragment's semantic multi-word-ness either (it only\n // ever joins each fragment's *actual* rendered text) — so when an\n // `isChainContinuationRoot` tag-paren closes, only this structural\n // signal (not the ordinary one) may propagate to the chain state it's\n // about to restore.\n entryForcedBreakStructural: boolean;\n anyForcedBreakStructural: boolean;\n allOk: boolean;\n }\n const stack: CdnFrame[] = [];\n\n const emit = (point: number, contentDepth: number): void => {\n const top = stack[stack.length - 1];\n if (top) top.ownCandidates.push({ point, contentDepth });\n else points.push({ point, contentDepth });\n };\n\n // Only <<...>>/app-sequence are \"loose\" in the sense of always collapsing\n // regardless of inlineLeafContainers (mirrors CborEmbeddedCBOR's\n // `alwaysInlineLeaf`). An indefinite-length string group (non-tag-paren\n // LPAREN) follows the same strict rule as CborArray/CborMap instead,\n // gated behind inlineLeafContainers like everything else — see\n // `suppressible` below.\n const isLooseFrame = (frame: CdnFrame): boolean =>\n frame.kind === 'LT_LT' || frame.kind === 'APP_SEQUENCE';\n\n // A tag-paren frame is transparent for the strict/loose decision — like\n // real CborTag, which just forwards whatever `strict` it was given to its\n // content rather than deciding independently — so a prefixed byte-string\n // literal's forced-break check (see the BYTES_HEX branch below) must walk\n // up past any enclosing tag-paren frames to find the frame whose own\n // strict/loose rule actually governs it (e.g. `<<100(h'00')>>` stays\n // inline: the tag is transparent, and the governing frame is the loose\n // `<<...>>`, not the tag's own parens).\n const nearestRuleFrame = (): CdnFrame | undefined => {\n for (let i = stack.length - 1; i >= 0; i--) {\n const frame = stack[i];\n if (frame.kind === 'LPAREN' && frame.isTagParen) continue;\n return frame;\n }\n return undefined;\n };\n\n // Folds the entry that just ended (at a comma, or at the closing\n // bracket) into the frame's running \"can this stay on one line\" verdict,\n // then resets the per-entry flags for the next entry. Tag-paren frames\n // never gate their own suppression on this — see the class comment\n // above — but `anyForcedBreak` still accumulates for them.\n const foldEntry = (frame: CdnFrame): void => {\n const ok = isLooseFrame(frame)\n ? !frame.entryForcedBreak\n : !frame.entryHasContainer && !frame.entryForcedBreak;\n frame.allOk = frame.allOk && ok;\n frame.anyForcedBreak = frame.anyForcedBreak || frame.entryForcedBreak;\n frame.anyForcedBreakStructural =\n frame.anyForcedBreakStructural || frame.entryForcedBreakStructural;\n frame.entryHasContainer = false;\n frame.entryForcedBreak = false;\n frame.entryForcedBreakStructural = false;\n };\n\n // Chain-aware multi-word tracking for `+`-concatenation, mirroring\n // isMultiWordTokenRange's chain handling in serialize-utils.ts:\n // `\"one \" + \"word\"` denotes one 2-word text string, not two 1-word ones,\n // so checking each TSTR individually (as every other token type in this\n // scan is checked, immediately, in isolation) under-counts. `chainKind`\n // tracks *which* chain (if any) is in progress — not just whether one is,\n // since a byte-leading chain (first part a prefixed `h'...'`/`b64'...'`)\n // must stay marked as such through every continuation part, even a bare\n // `SQSTR` one that would look text-leading in isolation: that\n // continuation is still part of the *byte* string the chain denotes\n // (concatenation never re-spells a byte-leading chain as one bare\n // `sqstr`), so it must not start its own independent text-leading\n // sub-chain — a byte-leading chain already forces a break unconditionally\n // via the existing BYTES_HEX/etc branch (on its first token, regardless\n // of continuation), independent of chain length, so `finalizeChain` never\n // needs to check anything for one. Only a text-leading chain (first part\n // TSTR/RAWSTRING/bare SQSTR — the same types the branches below check by\n // decoded word count rather than always-strict) accumulates into\n // `chainTexts`. `chainBroken` marks a part that couldn't be decoded\n // (elided hex, an elision-chain `...` link, or a malformed part that\n // shouldn't occur in this library's own output but isn't assumed) so a\n // text-leading chain is never falsely flagged from incomplete data.\n let chainKind: 'none' | 'text' | 'byte' = 'none';\n let chainTexts: string[] = [];\n let chainBroken = false;\n // Whether the chain currently in progress has seen at least one\n // `ELLIPSIS` link and at least one real `+` — i.e. it's a genuine elision\n // *chain* (`\"a\" + ...`, `... + h'00'`, `... + (_ \"a\")`, ...), not a bare\n // standalone `...` with nothing to concatenate at all. See `finalizeChain`\n // for why that distinction matters.\n let chainHasEllipsis = false;\n let chainSawPlus = false;\n // `true` right after an `INTEGER` was seen as an ellipsis-led chain's\n // continuation start — `parseValue()` accepts a bare integer *or* a tag\n // (`INTEGER [ENCODING_INDICATOR] LPAREN ... RPAREN`) there, and the two\n // aren't distinguishable until the token right after the integer (and its\n // own possible encoding indicator) is seen: `LPAREN` means it's a tag\n // (pushes into bracket tracking, same as any other bracketed\n // continuation, below); anything else means it was just a bare integer,\n // and that token is re-resolved as an ordinary chain-continuation check\n // instead.\n let chainAwaitingTagCheck = false;\n\n interface SavedChainState {\n depth: number;\n kind: 'none' | 'text' | 'byte';\n texts: string[];\n broken: boolean;\n hasEllipsis: boolean;\n sawPlus: boolean;\n awaitingTagCheck: boolean;\n }\n // A stack of *saved* (outer) chain states, one per bracketed value\n // currently being scanned as a continuation of an ellipsis-led chain\n // (`... + (_ \"a\")`, `... + [1, 2]`, ...) — only an ellipsis-led chain's\n // continuations can be arbitrary value shapes at all (the restricted\n // string/byte-literal-led grammar never allows one), matching\n // consumeOneItem's recursive handling in serialize-utils.ts. Pushing\n // saves the outer chain exactly as it was and resets the live\n // `chainKind`/etc. variables to a *fresh*, empty chain — the bracket's own\n // content is scanned completely normally against that fresh chain (its\n // own entries need their own, ordinary multi-word tracking; suspending\n // that entirely, an earlier version of this fix's bug, silently dropped\n // e.g. `[\"two words\"]`'s own multi-word check). Each entry's `depth` is\n // the `nesting` level from *before* that bracket opened, so its own\n // matching close (nesting back down to this value) can be recognized\n // regardless of further brackets nested inside it — popping then restores\n // the outer chain exactly as it was, so a further `+` after the bracket\n // resumes the *same* chain rather than starting a new one.\n const chainSuspendStack: SavedChainState[] = [];\n // One-shot: set by `pushChainSuspend`, consumed by the very next\n // `OPEN_TOKENS` push (which is always the bracket/tag that triggered the\n // suspend, in the same iteration) to mark that frame\n // `isChainContinuationRoot`.\n let nextFrameIsChainContinuationRoot = false;\n\n const pushChainSuspend = (depth: number): void => {\n chainSuspendStack.push({\n depth,\n kind: chainKind,\n texts: chainTexts,\n broken: chainBroken,\n hasEllipsis: chainHasEllipsis,\n sawPlus: chainSawPlus,\n awaitingTagCheck: chainAwaitingTagCheck,\n });\n chainKind = 'none';\n chainTexts = [];\n chainBroken = false;\n chainHasEllipsis = false;\n chainSawPlus = false;\n chainAwaitingTagCheck = false;\n nextFrameIsChainContinuationRoot = true;\n };\n\n const popChainSuspendIfDepthMatches = (): void => {\n const saved = chainSuspendStack[chainSuspendStack.length - 1];\n if (saved !== undefined && nesting === saved.depth) {\n chainSuspendStack.pop();\n chainKind = saved.kind;\n chainTexts = saved.texts;\n chainBroken = saved.broken;\n chainHasEllipsis = saved.hasEllipsis;\n chainSawPlus = saved.sawPlus;\n chainAwaitingTagCheck = saved.awaitingTagCheck;\n }\n };\n\n const finalizeChain = (): void => {\n if (chainHasEllipsis && chainSawPlus) {\n // An elision chain resolves, in the real AST, to a `CborEllipsis`\n // wrapping a `CborArray` of fragments (see `src/cdn/parser.ts`'s\n // `concatenate()`) — a *container*-shaped node per\n // `CborArray._containsCdnContainer` (always `true`) and\n // `CborTag._containsCdnContainer` (delegates to its content) — even\n // though its own written source has no literal `[`/`{` of its own.\n // So it disqualifies a strict array/map's inlining the same way an\n // actual nested `[...]`/`{...}` would (mirrors the `LBRACKET`/\n // `LBRACE` handling below: propagated to *every* open frame, since a\n // nested container disqualifies every ancestor's current entry no\n // matter how deep it sits), regardless of what the word-count check\n // above concludes. A loose frame (`<<...>>`/app-sequence) ignores\n // `entryHasContainer` entirely in its own `foldEntry` check, so\n // setting it unconditionally here is safe — it only has an effect\n // where the strict rule already looks at it. A truly standalone bare\n // `...` (no `+` at all, `chainSawPlus` stays `false`) does *not* get\n // this: it resolves to `CborEllipsis(CborSimple.NULL)` — no array, no\n // container.\n for (const frame of stack) frame.entryHasContainer = true;\n }\n if (chainKind === 'text' && !chainBroken && chainTexts.length > 0) {\n if (isMultiWordText(chainTexts.join(''))) {\n const top = stack[stack.length - 1];\n if (top) top.entryForcedBreak = true;\n }\n }\n chainKind = 'none';\n chainTexts = [];\n chainBroken = false;\n chainHasEllipsis = false;\n chainSawPlus = false;\n chainAwaitingTagCheck = false;\n };\n\n for (;;) {\n const token = tokenizer.consume();\n if (token.type === 'EOF') {\n finalizeChain();\n break;\n }\n let skipClosePoint = false;\n\n // A chain can still be waiting to continue past `PLUS`, an\n // `ENCODING_INDICATOR` trailing an individual part, straight into the\n // next chained literal or elision-chain `...` link, or (for an\n // ellipsis-led chain specifically, whose continuations aren't\n // restricted to string/byte literals at all — `parseValue()` in\n // src/cdn/parser.ts accepts *any* value there) into a bracketed value,\n // a tag, or a bare atom — anything else means it's over, and must be\n // resolved before this token's own handling (e.g. a closing bracket\n // popping the frame the chain's break belongs on). This always\n // operates on whatever the *current* chain is — the outer one, or (see\n // `chainSuspendStack`) a bracketed continuation's own fresh one, once\n // pushed — never anything that needs its own suspension.\n let chainContinuationResolved = false;\n if (chainAwaitingTagCheck) {\n if (token.type === 'ENCODING_INDICATOR') {\n // Still deciding — this is the integer's own encoding indicator;\n // wait for what follows it.\n chainContinuationResolved = true;\n } else if (token.type === 'LPAREN') {\n // It's a tag after all (`100(...)`, `100_1(...)`): push into the\n // same bracket tracking as any other bracketed continuation —\n // `nesting` is incremented for this same `LPAREN` by the ordinary\n // `OPEN_TOKENS` handling below, in this same iteration.\n chainAwaitingTagCheck = false;\n pushChainSuspend(nesting);\n chainContinuationResolved = true;\n } else {\n // Just a bare integer after all — fall through to the ordinary\n // check below for this same token, as if nothing special had\n // intervened (mirrors consumeOneItem's own \"not a tag, return\n // p\" — the integer's own extent already ended).\n chainAwaitingTagCheck = false;\n }\n }\n if (!chainContinuationResolved) {\n const chainCanContinueHere =\n token.type === 'PLUS' ||\n token.type === 'ENCODING_INDICATOR' ||\n (prevType === 'PLUS' &&\n (STRINGISH_CHAIN_TYPES.has(token.type) || token.type === 'ELLIPSIS'));\n if (chainKind !== 'none' && !chainCanContinueHere) {\n if (prevType === 'PLUS' && chainHasEllipsis) {\n if (OPEN_TOKENS.has(token.type)) {\n // An ellipsis-led chain's continuation may itself be an\n // arbitrary bracketed value (`... + (_ \"a\")`, `... + [1, 2]`,\n // ...) — push a fresh chain for this bracket's own content\n // (handled entirely normally below, on its own frame, exactly\n // like a standalone entry — it needs its *own* ordinary\n // multi-word tracking, e.g. `[\"two words\"]`'s own entry, not a\n // suspension that would silently skip it) rather than\n // finalizing the outer one.\n pushChainSuspend(nesting);\n } else if (token.type === 'INTEGER') {\n // Could be a bare integer continuation, or the start of a tag\n // (`100(...)`) — not distinguishable yet; resolved on the next\n // token, above.\n chainAwaitingTagCheck = true;\n }\n // Any other bare atom (a float, a simple value, ...): the\n // continuation is exactly this one token (plus an optional\n // trailing encoding indicator, already deferred by the\n // unconditional `ENCODING_INDICATOR` clause above) — nothing to\n // track, since none of the chain-state-mutating branches below\n // match any of these token types anyway; just don't finalize\n // here, and let the *next* token's own check (this token's type\n // becomes the new `prevType`, not `PLUS`) decide normally\n // whether the chain continues (`+`) or ends.\n } else {\n finalizeChain();\n }\n }\n if (token.type === 'PLUS' && chainKind !== 'none') {\n chainSawPlus = true;\n }\n }\n\n if (!sawToken) {\n sawToken = true;\n if (\n token.offset > 0 &&\n hasCommentBetween(tokenizer.comments, 0, token.offset)\n ) {\n emit(token.offset, nesting);\n }\n }\n\n // After an opener/comma, split before the next token so intervening layout\n // whitespace stays at the end of the previous chunk.\n if (pending !== null) {\n if (pending.kind === 'opener' && OPENER_MODIFIER_TOKENS.has(token.type)) {\n pending.point = token.endOffset;\n prevType = token.type;\n lastTokenEnd = token.endOffset;\n continue;\n } else if (\n pending.kind === 'opener' &&\n CLOSE_TOKENS.has(token.type) &&\n hasOnlyWhitespaceBetween(value, pending.point, token.offset)\n ) {\n skipClosePoint = true;\n } else {\n emit(token.offset, pending.contentDepth);\n }\n pending = null;\n }\n\n if (OPEN_TOKENS.has(token.type)) {\n if (token.type === 'LBRACKET' || token.type === 'LBRACE') {\n // A nested array/map disqualifies every ancestor's current entry\n // from the strict leaf rule, no matter how deep it sits.\n for (const frame of stack) frame.entryHasContainer = true;\n }\n nesting++;\n pending = {\n point: token.endOffset,\n contentDepth: nesting,\n kind: 'opener',\n };\n stack.push({\n kind: token.type,\n isTagParen: token.type === 'LPAREN' && prevType === 'INTEGER',\n isChainContinuationRoot: nextFrameIsChainContinuationRoot,\n openOffset: token.offset,\n ownCandidates: [],\n childCandidates: [],\n entryHasContainer: false,\n entryForcedBreak: false,\n anyForcedBreak: false,\n entryForcedBreakStructural: false,\n anyForcedBreakStructural: false,\n allOk: true,\n });\n nextFrameIsChainContinuationRoot = false;\n } else if (CLOSE_TOKENS.has(token.type)) {\n nesting = Math.max(0, nesting - 1);\n // If this closes the bracket that pushed a fresh chain for an\n // ellipsis-led chain's continuation, restore the outer chain exactly\n // as it was before that (matching brackets nested inside it, if any,\n // already came and went via their own push/pop) — the very next\n // iteration's `chainCanContinueHere` check then decides, from that\n // restored state, whether a further `+` continues it or it's time to\n // finalize. The fresh chain this bracket's own content was using (if\n // any) was already finalized against *this* frame by the top-of-loop\n // check earlier in this same iteration, before it's popped below.\n popChainSuspendIfDepthMatches();\n if (!skipClosePoint) {\n emit(token.offset, nesting);\n }\n const frame = stack.pop();\n if (frame) {\n foldEntry(frame);\n const isTag = frame.kind === 'LPAREN' && frame.isTagParen;\n // A loose frame (LT_LT/APP_SEQUENCE) collapses onto one line\n // whenever it fits regardless of inlineLeafContainers — mirrors\n // serializeContainer's `alwaysInlineLeaf`, since there's no\n // structural reason to ever spread a flat encoded-item sequence one\n // item per line if it fits. Everything else — array/map brackets,\n // tag parens, *and* an indefinite-length string group's parens\n // (LPAREN, tag or not) — stays gated behind inlineLeafContainers.\n const suppressible = isLooseFrame(frame)\n ? true\n : inlineLeafContainers &&\n (frame.kind === 'LBRACKET' ||\n frame.kind === 'LBRACE' ||\n frame.kind === 'LPAREN');\n const suppressOwn =\n suppressible &&\n frame.ownCandidates.length > 0 &&\n (isTag || frame.allOk) &&\n !hasCommentBetween(\n tokenizer.comments,\n frame.openOffset,\n token.endOffset\n );\n // Child-inherited breakpoints always forward, regardless of what\n // this frame decided for its own brackets — they represent breaks\n // some descendant already determined were unavoidable.\n const forwarded = suppressOwn\n ? frame.childCandidates\n : [...frame.ownCandidates, ...frame.childCandidates];\n const parent = stack[stack.length - 1];\n // Looped rather than `push(...forwarded)`: spreading a huge array\n // as call arguments can exceed the engine's argument-count limit\n // (a ~130k-item CDN array reproduces a RangeError here).\n if (parent) {\n for (const candidate of forwarded) {\n parent.childCandidates.push(candidate);\n }\n // Even when nothing here produced a breakpoint of its own to\n // carry forward (a suppressed tag paren whose content still had\n // a forced break somewhere inside it), the break itself still\n // happened and still needs to reach the parent — *unless* this\n // frame is the outermost bracket/tag of an ellipsis-led chain's\n // continuation (`isChainContinuationRoot`) and a tag-paren\n // specifically: closing it is about to restore the chain state\n // it was pushed to protect, and only a *structural* reason (a\n // real newline, or an actual forwarded breakpoint) should reach\n // that restored chain — a purely semantic \"my content is\n // multi-word\" signal has no real analogue there (see\n // `entryForcedBreakStructural`'s doc; `CborEllipsis`'s own\n // rendering never delegates to a fragment's semantic\n // multi-word-ness, only its actual rendered text).\n const hasStructuralBreak =\n forwarded.length > 0 || frame.anyForcedBreakStructural;\n const shouldPropagate =\n frame.isChainContinuationRoot && frame.isTagParen\n ? hasStructuralBreak\n : forwarded.length > 0 || frame.anyForcedBreak;\n if (shouldPropagate) {\n parent.entryForcedBreak = true;\n }\n if (hasStructuralBreak) {\n parent.entryForcedBreakStructural = true;\n }\n } else {\n for (const candidate of forwarded) {\n points.push(candidate);\n }\n }\n }\n } else if (token.type === 'COMMA') {\n const top = stack[stack.length - 1];\n if (top) foldEntry(top);\n pending = {\n point: token.endOffset,\n contentDepth: nesting,\n kind: 'comma',\n };\n } else if (token.type === 'TSTR' || token.type === 'RAWSTRING') {\n // A literal/escaped newline inside this token will itself become a\n // breakpoint once `splitNewline` runs (merged in by the caller,\n // outside this function) — that forces this entry's own rendering\n // to contain a line break, exactly like a child bracket that\n // couldn't be suppressed. Mirrors serializeContainer's `s.includes\n // ('\\n')` check on a rendered entry.\n const tokenText = value.slice(token.offset, token.endOffset);\n const hasNewline =\n newline &&\n (token.type === 'TSTR'\n ? collectTstrNewlineBreakpoints(tokenText).length > 0\n : collectNewlineBreakpoints(tokenText, 0).length > 0);\n // A literal/escaped newline always forces a break immediately,\n // independent of concatenation. Not gated on `inlineLeafContainers`\n // here — setting `entryForcedBreak` is a no-op whenever the\n // enclosing frame isn't suppressible anyway (see `suppressible`\n // above), so this stays correct for a loose frame's unconditional\n // collapse too, without needing to know which case applies at this\n // point in the scan.\n if (hasNewline) {\n const top = stack[stack.length - 1];\n if (top) {\n top.entryForcedBreak = true;\n // A real, literal newline — unlike the multi-word check just\n // below — is a genuinely structural fact that would show up in\n // the actual rendered text regardless of what wraps it; see\n // `entryForcedBreakStructural`'s doc.\n top.entryForcedBreakStructural = true;\n }\n }\n // Multi-word-ness (mirrors serializeContainer's `entryIsMultiWordText`\n // probe) is chain-aware: append to an in-progress text-leading chain\n // continuation, or start a new (possibly single-part) one — resolved\n // by `finalizeChain` once the chain is known to be over (see above).\n // Always operates on whichever chain is *current* (see\n // `chainSuspendStack`) — a bracketed continuation's own fresh chain\n // needs this exact same tracking for its own entries (e.g. a plain\n // `\"two words\"` inside `... + [\"two words\"]`), not a suspension that\n // would silently skip it.\n if (prevType === 'PLUS' && chainKind === 'text') {\n chainTexts.push(token.value);\n } else {\n chainKind = 'text';\n chainTexts = [token.value];\n chainBroken = false;\n }\n } else if (token.type === 'SQSTR') {\n // A bare sqstr byte-string literal (`'...'`) is printable text by\n // construction — mirrors CborByteString._isMultiWordText's sqstr\n // branch. `.value` holds hex bytes for SQSTR (byte-string convention),\n // so the decoded UTF-8 payload comes from `_sqstrBytes` instead. As a\n // *continuation* of an already-byte-leading chain (`h'' + 'two\n // words'`), though, it must NOT start its own independent\n // text-leading chain — see the `chainKind` block comment above; it's\n // still just a further byte span of that same byte string, already\n // exempted from the multi-word check by the byte-leading chain's own\n // start (the BYTES_HEX/etc branch below). Always operates on\n // whichever chain is *current*, same as the TSTR/RAWSTRING branch\n // above.\n if (prevType === 'PLUS' && chainKind === 'byte') {\n // no-op: part of an already-exempt byte-leading chain\n } else {\n const bytes = (token as SqstrToken)._sqstrBytes;\n const decoded = bytes ? textDecoder.decode(bytes) : null;\n if (prevType === 'PLUS' && chainKind === 'text') {\n if (decoded === null) chainBroken = true;\n else chainTexts.push(decoded);\n } else {\n chainKind = 'text';\n chainTexts = decoded !== null ? [decoded] : [];\n chainBroken = decoded === null;\n }\n }\n } else if (\n token.type === 'BYTES_HEX' ||\n token.type === 'BYTES_HEX_ELIDED' ||\n token.type === 'BYTES_B64' ||\n token.type === 'APP_STRING'\n ) {\n if (prevType === 'PLUS' && chainKind === 'text') {\n // A continuation of a *text*-leading chain (`\"a\" + h'62'`) is\n // decoded and merged into the accumulated text instead — the\n // unconditional \"always strict\" rule below only applies when *this*\n // token is what fixes the chain's element type (byte-leading, or\n // standalone); a byte-shaped *continuation* of an already\n // text-leading chain doesn't get its own independent say — the\n // combined word count, computed once the chain ends, is what\n // decides it, exactly like isMultiWordTokenRange's chain decoding\n // in serialize-utils.ts (`\"a\" + h'62'` merges to `\"ab\"`, one word,\n // and must not be disqualified just because one part happened to\n // be spelled as `h'62'`). APP_STRING never participates in\n // concatenation (draft-25 §5.1), so it never continues one; `BYTES_HEX_ELIDED`'s\n // missing data can't be decoded, so it always breaks the chain\n // instead of silently under-counting.\n let decoded: string | null = null;\n try {\n if (token.type === 'BYTES_HEX') {\n decoded = textDecoder.decode(hexToBytes(token.value));\n } else if (token.type === 'BYTES_B64') {\n decoded = textDecoder.decode(base64ToBytes(token.value));\n }\n } catch {\n decoded = null;\n }\n if (decoded === null) chainBroken = true;\n else chainTexts.push(decoded);\n } else {\n // Mirrors CborByteString._isMultiWordText's prefixed-literal branch\n // (and, via APP_STRING, `isPrefixedLiteralText`'s generic catch-all\n // for other app-string extensions like `ip'...'`/`dt'...'`): none of\n // these have natural word boundaries to check, so they always count\n // as multi-word under the strict rule (array/map, and — unlike a\n // multi-word text entry — an indefinite-length string group too) —\n // but the *only* loose frame (`<<...>>`/app-sequence) treats it as\n // an ordinary leaf instead, e.g. `<<h'00'>>`/`<<ip'...'>>` stay\n // inline while `(_ h'00')` still breaks. The governing frame is\n // found by `nearestRuleFrame`, not just `top`, since an enclosing\n // tag paren is transparent to this decision. This unconditional\n // check applies whether this literal starts a byte-leading chain or\n // stands alone — a byte-leading chain is never re-spelled as one\n // bare `sqstr`, so it disqualifies the same way a lone prefixed\n // literal already does, independent of chain length (see\n // serialize-utils.ts's isMultiWordTokenRange for the same\n // reasoning) — but *not* when it's really a continuation of a\n // text-leading chain, handled above instead.\n const top = stack[stack.length - 1];\n const ruleFrame = nearestRuleFrame();\n if (top && (!ruleFrame || !isLooseFrame(ruleFrame))) {\n top.entryForcedBreak = true;\n }\n if (prevType !== 'PLUS' || chainKind === 'none') {\n // Not a continuation — this token starts a fresh, byte-leading\n // chain (or stands alone, which is the same thing as a one-part\n // chain). Recorded so a *following* continuation part (including\n // a bare SQSTR, which would otherwise look text-leading in\n // isolation) is correctly recognized as still belonging to this\n // byte-leading chain rather than starting an independent one.\n chainKind = 'byte';\n }\n }\n } else if (token.type === 'ELLIPSIS') {\n // An elision-chain link (`\"a\" + ...`, or leading — `... + \"b\"`, an\n // unknown prefix concatenated with a known suffix — CDN's notation\n // for a value with a part deliberately omitted; see\n // serialize-utils.ts's `CHAIN_ATOM_TYPES` for the same grammar,\n // accepted both as a chain's own first value and as any later\n // continuation). Either way its missing content makes the *combined*\n // word count of the whole chain unknowable, never just this part's —\n // so as a *continuation* of a text-leading chain, it poisons that\n // chain (without ending it — more parts may still follow) rather\n // than silently under-counting from only the visible parts; as a\n // *fresh start* (nothing to continue), it begins one already\n // poisoned, so a *later* continuation part (including a bare SQSTR,\n // which would otherwise look like its own fresh text-leading start)\n // is still recognized as belonging to this now-indeterminate chain\n // instead of starting an independent one. A byte-leading chain\n // doesn't track decoded text at all, so there's nothing to poison\n // there. Set unconditionally, regardless of which case below applies\n // (including a continuation of a *byte*-kind chain, e.g. `h'00' +\n // ...`, which none of those cases otherwise touch) — see\n // `finalizeChain`'s `chainHasEllipsis`/`chainSawPlus` check for why a\n // truly standalone `...` (this flag set, but `chainSawPlus` never\n // becomes true) is harmless. Always operates on whichever chain is\n // *current* — an `ELLIPSIS` inside an ellipsis-led chain's own\n // bracketed continuation, if that's even reachable, correctly poisons\n // *that* (fresh, pushed) chain rather than the outer one.\n chainHasEllipsis = true;\n if (prevType === 'PLUS' && chainKind === 'text') {\n chainBroken = true;\n } else if (prevType !== 'PLUS' || chainKind === 'none') {\n chainKind = 'text';\n chainTexts = [];\n chainBroken = true;\n }\n }\n prevType = token.type;\n lastTokenEnd = token.endOffset;\n }\n\n const trailingComment = tokenizer.comments.find(\n (comment) => comment.start >= lastTokenEnd\n );\n if (trailingComment !== undefined) {\n points.push({ point: trailingComment.start, contentDepth: nesting });\n }\n return points;\n}\n\nfunction collectCdnNewlineBreakpoints(value: string): StringBreakpoint[] {\n const points: StringBreakpoint[] = [];\n const tokenizer = new Tokenizer(value);\n let nesting = 0;\n for (;;) {\n const token = tokenizer.consume();\n if (token.type === 'EOF') break;\n\n if (OPEN_TOKENS.has(token.type)) {\n nesting++;\n } else if (CLOSE_TOKENS.has(token.type)) {\n nesting = Math.max(0, nesting - 1);\n } else if (token.type === 'COMMA') {\n // Commas can create structural split points, but never contain newline\n // split points themselves.\n } else if (token.type === 'TSTR') {\n // TSTR uses escape sequences (\\n, \\r) for newlines in addition to\n // literal newline characters.\n const tokenText = value.slice(token.offset, token.endOffset);\n for (const point of collectTstrNewlineBreakpoints(tokenText)) {\n points.push({ point: token.offset + point, contentDepth: nesting + 1 });\n }\n } else if (token.type === 'RAWSTRING') {\n // RAWSTRING has no escape sequences; only literal newlines apply.\n const tokenText = value.slice(token.offset, token.endOffset);\n for (const { point } of collectNewlineBreakpoints(tokenText, 0)) {\n points.push({ point: token.offset + point, contentDepth: nesting + 1 });\n }\n }\n }\n return points;\n}\n\n// Scans the raw source of a CDN double-quoted string (TSTR) for newline\n// escape sequences (\\n, \\r) and literal newline characters, returning the\n// position within tokenText immediately after each such sequence.\nfunction collectTstrNewlineBreakpoints(tokenText: string): number[] {\n const points: number[] = [];\n let i = 1; // skip opening \"\n const end = tokenText.length - 1; // stop before closing \"\n while (i < end) {\n const ch = tokenText[i];\n if (ch === '\\\\') {\n const next = tokenText[i + 1];\n if (next === 'n' || next === 'r') {\n points.push(i + 2);\n i += 2;\n } else if (next === 'u') {\n if (tokenText[i + 2] === '{') {\n const close = tokenText.indexOf('}', i + 3);\n i = close >= 0 ? close + 1 : i + 2;\n } else {\n i += 6; // \\uXXXX\n }\n } else {\n i += 2; // \\\\, \\\", \\t, etc.\n }\n } else if (ch === '\\r') {\n if (tokenText[i + 1] === '\\n') {\n points.push(i + 2);\n i += 2;\n } else {\n points.push(i + 1);\n i++;\n }\n } else if (ch === '\\n') {\n points.push(i + 1);\n i++;\n } else {\n i++;\n }\n }\n return points;\n}\n\nconst OPENER_MODIFIER_TOKENS = new Set<TokenType>([\n 'ENCODING_INDICATOR',\n 'UNDERSCORE',\n]);\n\nconst OPEN_TOKENS = new Set<TokenType>([\n 'LBRACKET',\n 'LBRACE',\n 'LPAREN',\n 'LT_LT',\n // `prefix<<` (app-sequence) is tokenized as one token, unlike a plain\n // `<<`; its close is still a separate GT_GT (in CLOSE_TOKENS), so it\n // must be tracked as an opener here too or nesting/frame bookkeeping\n // desyncs on the matching close.\n 'APP_SEQUENCE',\n]);\n\nconst CLOSE_TOKENS = new Set<TokenType>([\n 'RBRACKET',\n 'RBRACE',\n 'RPAREN',\n 'GT_GT',\n]);\n\n// Token types that can appear as one part of a `+`-concatenation chain\n// (draft-25 §5.1) — mirrors `STRINGISH_TYPES` in serialize-utils.ts.\nconst STRINGISH_CHAIN_TYPES = new Set<TokenType>([\n 'TSTR',\n 'RAWSTRING',\n 'SQSTR',\n 'BYTES_HEX',\n 'BYTES_HEX_ELIDED',\n 'BYTES_B64',\n]);\n\nfunction hasCommentBetween(\n comments: readonly { start: number; end: number }[],\n start: number,\n end: number\n): boolean {\n // Comments use half-open source ranges; this checks for comments wholly\n // contained in [start, end), including one that ends exactly at `end`.\n return comments.some(\n (comment) => comment.start >= start && comment.end <= end\n );\n}\n\nfunction hasOnlyWhitespaceBetween(\n value: string,\n start: number,\n end: number\n): boolean {\n return /^[\\t\\n\\r ]*$/.test(value.slice(start, end));\n}\n\nfunction splitAtBreakpoints(\n value: string,\n breakpoints: Map<number, number>\n): StringPart[] {\n const points = [...breakpoints]\n .filter(([point]) => point > 0 && point < value.length)\n .sort(([a], [b]) => a - b);\n if (points.length === 0) return [{ text: value, contentDepth: 0 }];\n\n const parts: StringPart[] = [];\n let start = 0;\n let contentDepth = 0;\n for (const [point, nextContentDepth] of points) {\n if (point === start) continue;\n parts.push({ text: value.slice(start, point), contentDepth });\n start = point;\n contentDepth = nextContentDepth;\n }\n if (start < value.length) {\n parts.push({ text: value.slice(start), contentDepth });\n }\n return parts;\n}\n","/**\n * Standard CDN \"dt\" / \"DT\" app-extension (§3.2 of draft-ietf-cbor-edn-literals-27).\n *\n * Parses RFC 3339 date-time app-strings into epoch-based numeric CBOR values.\n * The resulting CborItem subclasses override toCDN() so the value round-trips\n * back to dt'...' / DT'...' notation.\n *\n * For a richer variant that makes toJS() return Date objects, use dt_as_Date\n * from ./date instead.\n */\n\nimport type {\n ToCDNOptions,\n ToJSOptions,\n ReadonlyToJSNodeOptions,\n FromJSOptions,\n} from '../types';\nimport type { CborExtension } from './types';\nimport type { CborItem } from '../ast/CborItem';\nimport { CborUint } from '../ast/CborUint';\nimport { CborNint } from '../ast/CborNint';\nimport { CborFloat } from '../ast/CborFloat';\nimport { CborTag } from '../ast/CborTag';\nimport { Tag } from '../tag';\nimport type { EncodingWidth } from '../cbor/encode';\nimport { autoSelectFloatPrecision } from '../cbor/encode';\nimport { CborTextString } from '../ast/CborTextString';\nimport { CborByteString } from '../ast/CborByteString';\nimport {\n resolveEiSuffix,\n canonicalEncodingWidth,\n floatSuffix,\n decideTaggedAppSeqRendering,\n adjustRawAppSeqSource,\n adjustAppSeqIndicator,\n} from '../cdn/serialize-utils';\n\n// ─── Helpers ──────────────────────────────────────────────────────────────────\n\n/**\n * Convert epoch seconds to an RFC 3339 string with appropriate precision.\n *\n * - Integer epoch → \"…Z\" (no fractional part)\n * - Millisecond-precision → \"….SSSZ\" (3 decimal places, e.g. \".500Z\")\n * - Sub-millisecond → \"….S…Z\" (minimal digits, e.g. \".0001Z\")\n *\n * Millisecond precision is used whenever `Math.round(epochSeconds * 1000)`\n * round-trips back to the same float64 value, which is the common case for\n * timestamps stored as integer milliseconds (the JavaScript Date range).\n * Otherwise the shortest decimal representation of the fractional seconds is\n * used so that the float64 value is faithfully represented.\n */\nexport function epochToRfc3339(epochSeconds: number): string {\n if (Number.isInteger(epochSeconds))\n return new Date(epochSeconds * 1000).toISOString().replace(/\\.000Z$/, 'Z');\n\n // Check if millisecond precision suffices (the common case).\n const roundedMs = Math.round(epochSeconds * 1000);\n if (roundedMs / 1000 === epochSeconds)\n return new Date(roundedMs).toISOString().replace(/\\.000Z$/, 'Z');\n\n // Sub-millisecond precision: decompose into whole seconds + fractional part.\n // Math.floor ensures the fractional part is always in [0, 1), which is\n // correct for negative epochs too (e.g. -0.5 → floor=-1, frac=0.5).\n const wholeSeconds = Math.floor(epochSeconds);\n const frac = epochSeconds - wholeSeconds;\n\n // Base timestamp formatted to the second, without any fractional part.\n const base = new Date(wholeSeconds * 1000)\n .toISOString()\n .replace(/\\.\\d+Z$/, '');\n\n // Minimal decimal representation of the fractional seconds (JavaScript's\n // Number.prototype.toString uses the shortest round-trip string).\n const fracStr = frac.toString(); // e.g. \"0.0001\" or \"0.123456\"\n const dotIdx = fracStr.indexOf('.');\n let decDigits = dotIdx >= 0 ? fracStr.slice(dotIdx + 1) : '0';\n // Ensure at least 3 decimal places for conventional readability.\n while (decDigits.length < 3) decDigits += '0';\n\n return `${base}.${decDigits}Z`;\n}\n\n/**\n * Extract a date-time string from a single-item app-sequence.\n * Accepts CborTextString (dt<<\"...\">> ) and CborByteString (dt<<'...'>> , UTF-8).\n */\nconst utf8Strict = new TextDecoder('utf-8', { fatal: true });\n\nfunction stringFromAppSequence(items: CborItem[]): string {\n if (items.length !== 1)\n throw new SyntaxError('dt<<...>>: expected exactly one item');\n const item = items[0];\n if (item instanceof CborTextString) return item.value;\n if (item instanceof CborByteString) return utf8Strict.decode(item.value);\n throw new SyntaxError('dt<<...>>: expected a text string or byte string');\n}\n\n/**\n * Parse an RFC 3339 string and produce the appropriate epoch CborItem subclass.\n * Integer seconds → CborEpochDtExtUint or CborEpochDtExtNint.\n * Fractional seconds → CborEpochDtExtFloat.\n *\n * Fractional seconds are extracted from the string directly (via parseFloat)\n * before passing the remainder to Date.parse, so sub-millisecond precision\n * is preserved rather than being rounded to the nearest millisecond.\n */\n// RFC 3339 §5.6: date-time = full-date \"T\" full-time, where full-time requires\n// an offset (Z or ±HH:MM). Anything shorter is rejected before Date.parse().\nconst RFC3339_RE =\n /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?(Z|[+-]\\d{2}:\\d{2})$/i;\n\nexport function parseDtAppString(\n str: string,\n onError?: (msg: string) => void\n): CborEpochDtExtUint | CborEpochDtExtNint | CborEpochDtExtFloat {\n if (!RFC3339_RE.test(str)) {\n const msg = `dt: invalid RFC 3339 date-time: ${JSON.stringify(str)}`;\n if (onError) onError(msg);\n else throw new SyntaxError(msg);\n }\n\n // Separate the fractional-seconds part (if any) from the rest of the string.\n // This avoids Date.parse() truncating to millisecond precision.\n // Pattern: ...THH:MM:SS(.frac)(Z|±HH:MM)\n const fracMatch = str.match(\n /^(.+T\\d{2}:\\d{2}:\\d{2})(\\.\\d+)(Z|[+-]\\d{2}:\\d{2})$/i\n );\n\n let wholeStr: string;\n let fracValue: number | undefined;\n\n if (fracMatch) {\n // Parse the integer-seconds part (without the fractional digits).\n wholeStr = fracMatch[1] + fracMatch[3];\n // Parse the fractional seconds string with full float64 precision.\n fracValue = parseFloat('0' + fracMatch[2]); // e.g. parseFloat(\"0.0001\")\n } else {\n wholeStr = str;\n fracValue = undefined;\n }\n\n const ms = Date.parse(wholeStr);\n if (isNaN(ms))\n throw new SyntaxError(\n `dt: invalid RFC 3339 date-time: ${JSON.stringify(str)}`\n );\n\n if (fracValue === undefined) {\n const seconds = ms / 1000;\n if (seconds >= 0) return new CborEpochDtExtUint(BigInt(seconds));\n return new CborEpochDtExtNint(BigInt(seconds));\n }\n\n return new CborEpochDtExtFloat(ms / 1000 + fracValue);\n}\n\n// ─── Constants ────────────────────────────────────────────────────────────────\n\nexport const PREFIX_DT = 'dt';\nexport const PREFIX_DT_TAGGED = 'DT';\nexport const TAG_EPOCH = 1n;\n\n// ─── CborItem subclasses ─────────────────────────────────────────────────────\n\n/**\n * Unsigned epoch timestamp whose toCDN() emits dt'…' notation.\n * The RFC 3339 string is re-derived from the numeric value on each call.\n */\nexport class CborEpochDtExtUint extends CborUint {\n constructor(\n value: number | bigint,\n options?: { encodingWidth?: EncodingWidth; ednSource?: string }\n ) {\n super(value, options);\n }\n\n override _toCDN(\n options: ToCDNOptions | undefined,\n _depth: number,\n path?: readonly unknown[]\n ): string {\n if (options?.appPrefix === false)\n return super._toCDN(options, _depth, path);\n const eiSuffix = resolveEiSuffix(options, this.encodingWidth, () =>\n canonicalEncodingWidth(this.value)\n );\n const decision = decideTaggedAppSeqRendering(\n options,\n this.appSeqSource,\n undefined,\n this.appSeqSourceFeatures\n );\n if (decision === 'adjusted')\n return adjustAppSeqIndicator(\n this.appSeqSource!,\n eiSuffix,\n options,\n this.appSeqInnerEnd,\n this.appSeqComments\n );\n return `${PREFIX_DT}'${epochToRfc3339(Number(this.value))}'${eiSuffix}`;\n }\n}\n\n/**\n * Negative epoch timestamp whose toCDN() emits dt'…' notation.\n * The RFC 3339 string is re-derived from the numeric value on each call.\n */\nexport class CborEpochDtExtNint extends CborNint {\n constructor(\n value: number | bigint,\n options?: { encodingWidth?: EncodingWidth; ednSource?: string }\n ) {\n super(value, options);\n }\n\n override _toCDN(\n options: ToCDNOptions | undefined,\n _depth: number,\n path?: readonly unknown[]\n ): string {\n if (options?.appPrefix === false)\n return super._toCDN(options, _depth, path);\n const eiSuffix = resolveEiSuffix(options, this.encodingWidth, () =>\n canonicalEncodingWidth(this.argument)\n );\n const decision = decideTaggedAppSeqRendering(\n options,\n this.appSeqSource,\n undefined,\n this.appSeqSourceFeatures\n );\n if (decision === 'adjusted')\n return adjustAppSeqIndicator(\n this.appSeqSource!,\n eiSuffix,\n options,\n this.appSeqInnerEnd,\n this.appSeqComments\n );\n return `${PREFIX_DT}'${epochToRfc3339(Number(this.value))}'${eiSuffix}`;\n }\n}\n\n/**\n * Float epoch timestamp whose toCDN() emits dt'…' notation.\n * The RFC 3339 string is re-derived from the numeric value on each call.\n */\nexport class CborEpochDtExtFloat extends CborFloat {\n constructor(\n value: number,\n options?: {\n precision?: 'half' | 'single' | 'double';\n literalSource?: string;\n }\n ) {\n super(value, options);\n }\n\n override _toCDN(\n options: ToCDNOptions | undefined,\n _depth: number,\n path?: readonly unknown[]\n ): string {\n if (options?.appPrefix === false)\n return super._toCDN(options, _depth, path);\n const autoSelected = autoSelectFloatPrecision(this.value);\n const eiSuffix = floatSuffix(\n this.value,\n this.precision,\n autoSelected,\n options?.encodingIndicators ?? 'auto'\n );\n const decision = decideTaggedAppSeqRendering(\n options,\n this.appSeqSource,\n undefined,\n this.appSeqSourceFeatures\n );\n if (decision === 'adjusted')\n return adjustAppSeqIndicator(\n this.appSeqSource!,\n eiSuffix,\n options,\n this.appSeqInnerEnd,\n this.appSeqComments\n );\n return `${PREFIX_DT}'${epochToRfc3339(this.value)}'${eiSuffix}`;\n }\n}\n\n/**\n * CBOR tag(1, epoch) whose toCDN() emits DT'…' notation.\n * The RFC 3339 string is re-derived from the numeric content on each call.\n */\nexport class CborTaggedEpochDtExt extends CborTag {\n constructor(\n datetimeOrContent:\n string | CborEpochDtExtUint | CborEpochDtExtNint | CborEpochDtExtFloat,\n options?: { encodingWidth?: EncodingWidth }\n ) {\n super(\n TAG_EPOCH,\n typeof datetimeOrContent === 'string'\n ? parseDtAppString(datetimeOrContent)\n : datetimeOrContent,\n options\n );\n }\n\n override _toCDN(\n options: ToCDNOptions | undefined,\n depth: number,\n path?: readonly unknown[]\n ): string {\n if (options?.appPrefix === false) return super._toCDN(options, depth, path);\n const decision = decideTaggedAppSeqRendering(\n options,\n this.appSeqSource,\n this.ednSource,\n this.appSeqSourceFeatures,\n this.appSeqEncodingEditsComplete\n );\n if (decision === 'verbatim') return this.appSeqSource!;\n if (decision === 'source')\n return adjustRawAppSeqSource(\n this.appSeqSource!,\n options,\n this.appSeqComments,\n this.appSeqEncodingEdits\n );\n if (decision === 'structural')\n return super._toCDN({ ...options, appPrefix: false }, depth, path);\n const eiSuffix = resolveEiSuffix(options, this.encodingWidth, () =>\n canonicalEncodingWidth(TAG_EPOCH)\n );\n if (decision === 'adjusted')\n return adjustAppSeqIndicator(\n this.appSeqSource!,\n eiSuffix,\n options,\n this.appSeqInnerEnd,\n this.appSeqComments\n );\n // Per §4.1, DT'...'_N encodes only the tag number's width.\n // If the inner content has non-canonical encoding, fall back to generic tag\n // notation so the inner EI (e.g. dt'...'_3) is not silently discarded.\n const c = this.content as\n CborEpochDtExtUint | CborEpochDtExtNint | CborEpochDtExtFloat;\n const innerIsNonCanonical =\n c instanceof CborFloat\n ? c.precision !== undefined &&\n c.precision !== autoSelectFloatPrecision(c.value)\n : (c as CborUint | CborNint).encodingWidth !== undefined;\n if (innerIsNonCanonical)\n return super._toCDN({ ...options, appPrefix: false }, depth, path);\n const epochSec = c instanceof CborFloat ? c.value : Number(c.value);\n return `${PREFIX_DT_TAGGED}'${epochToRfc3339(epochSec)}'${eiSuffix}`;\n }\n}\n\n/**\n * CBOR tag(1, epoch) whose toJS() returns a plain Date object.\n * Use dt_as_Date (or createDtExtension({ jsDate: true })) to produce these nodes.\n */\nexport class CborTaggedEpochDtAsDateExt extends CborTaggedEpochDtExt {\n constructor(\n datetimeOrContent:\n string | CborEpochDtExtUint | CborEpochDtExtNint | CborEpochDtExtFloat,\n options?: { encodingWidth?: EncodingWidth }\n ) {\n super(datetimeOrContent, options);\n }\n\n override _toJS(_options?: ToJSOptions): Date {\n const c = this.content as\n CborEpochDtExtUint | CborEpochDtExtNint | CborEpochDtExtFloat;\n const epochMs =\n c instanceof CborFloat ? c.value * 1000 : Number(c.value) * 1000;\n return new Date(epochMs);\n }\n}\n\n/**\n * `CborExtension.toJS()` hook shared by `dt` and `dt_as_Date`: lets `toJS()`\n * reinterpret *any* `CborTaggedEpochDtExt` node (including the\n * `CborTaggedEpochDtAsDateExt` subclass) as either a `number` or a `Date`,\n * regardless of which variant produced it during parsing — see\n * `ToJSOptions.extensions`/`itemOptions`.\n *\n * The `number` branch replicates `CborTag._toJS()`'s own default behaviour\n * (honouring `stripTags`/`integerAs` and round-tripping via `Tag.set`)\n * rather than assuming a tag wrapper is unwanted, so selecting the plain\n * `dt` extension here for a subtree parsed with `dt_as_Date` reproduces\n * exactly what parsing that subtree with `dt` would have produced.\n */\nfunction dtToJSHook(\n useDate: boolean\n): (\n item: CborItem,\n options: ReadonlyToJSNodeOptions\n) => { value: unknown } | undefined {\n return (item, options) => {\n if (!(item instanceof CborTaggedEpochDtExt)) return undefined;\n const c = item.content as\n CborEpochDtExtUint | CborEpochDtExtNint | CborEpochDtExtFloat;\n if (useDate) {\n const epochMs =\n c instanceof CborFloat ? c.value * 1000 : Number(c.value) * 1000;\n return { value: new Date(epochMs) };\n }\n // Read-only view (see ReadonlyToJSNodeOptions) passed straight through\n // to a plain conversion that only ever reads it, same as `_toJS` does\n // for its own `options` parameter elsewhere.\n const value = c._toJS(options as ToJSOptions);\n return { value: options.stripTags ? value : Tag.set(value, item.tag) };\n };\n}\n\n// ─── Factory ──────────────────────────────────────────────────────────────────\n\n/**\n * Create a dt/DT CborExtension.\n *\n * - `createDtExtension()` — tagged DT values produce `CborTaggedEpochDtExt`;\n * toJS() returns a number (epoch seconds).\n * - `createDtExtension({ jsDate: true })` — tagged DT values produce\n * `CborTaggedEpochDtAsDateExt`; toJS() returns a `Date` object, and\n * `fromJS(Date)` converts `Date` instances back to tagged epoch values.\n */\nexport function createDtExtension(options?: {\n jsDate?: boolean;\n}): CborExtension {\n const useDate = options?.jsDate ?? false;\n\n function makeTagged(\n datetime: string\n ): CborTaggedEpochDtExt | CborTaggedEpochDtAsDateExt {\n return useDate\n ? new CborTaggedEpochDtAsDateExt(datetime)\n : new CborTaggedEpochDtExt(datetime);\n }\n\n const ext: CborExtension = {\n appStringPrefixes: [PREFIX_DT, PREFIX_DT_TAGGED],\n tagNumbers: [TAG_EPOCH],\n // dt/DT results always have a dedicated subclass (CborEpochDtExt* /\n // CborTaggedEpochDtExt) that regenerates its notation by default;\n // 'optional' preserves the <<...>> spelling only when\n // ToCDNOptions.preserveAppPrefix is set, without changing the\n // returned node's class/identity (see preservedAppSeqSpelling above).\n preserveAppSeqSource: 'optional',\n\n // Lets ToJSOptions.extensions/itemOptions select number-vs-Date output\n // for a CborTaggedEpochDtExt node regardless of which of `dt`/\n // `dt_as_Date` actually parsed it — see dtToJSHook.\n toJS: dtToJSHook(useDate),\n\n parseAppString(\n prefix: string,\n content: string,\n onError?: (msg: string) => void\n ): CborItem {\n if (prefix === PREFIX_DT_TAGGED) return makeTagged(content);\n return parseDtAppString(content, onError);\n },\n\n parseAppSequence(\n prefix: string,\n items: CborItem[],\n onError?: (msg: string) => void\n ): CborItem {\n const str = stringFromAppSequence(items);\n if (prefix === PREFIX_DT_TAGGED) return makeTagged(str);\n return parseDtAppString(str, onError);\n },\n\n parseTag(tag: bigint, value: CborItem): CborItem | undefined {\n if (tag !== TAG_EPOCH) return undefined;\n let content:\n CborEpochDtExtUint | CborEpochDtExtNint | CborEpochDtExtFloat;\n if (value instanceof CborUint) {\n content = new CborEpochDtExtUint(value.value, {\n encodingWidth: value.encodingWidth,\n ednSource: value.ednSource,\n });\n } else if (value instanceof CborNint) {\n content = new CborEpochDtExtNint(value.value, {\n encodingWidth: value.encodingWidth,\n ednSource: value.ednSource,\n });\n } else if (value instanceof CborFloat) {\n // Always preserve as float to avoid losing the original CBOR encoding\n // type (e.g. float64(1.0) must not silently become uint(1)).\n content = new CborEpochDtExtFloat(value.value, {\n precision: value.precision,\n literalSource: value.literalSource,\n });\n } else {\n return undefined;\n }\n content.start = value.start;\n content.end = value.end;\n const result = useDate\n ? new CborTaggedEpochDtAsDateExt(content)\n : new CborTaggedEpochDtExt(content);\n return result;\n },\n };\n\n if (useDate) {\n ext.fromJS = (\n value: unknown,\n _options: FromJSOptions\n ): CborItem | undefined => {\n if (value instanceof Date)\n return new CborTaggedEpochDtAsDateExt(\n epochToRfc3339(value.getTime() / 1000)\n );\n return undefined;\n };\n ext.isJSType = (value: unknown): value is Date => value instanceof Date;\n }\n\n return ext;\n}\n\n// ─── Extension objects ────────────────────────────────────────────────────────\n\n/**\n * Standard dt/DT CborExtension.\n * Tagged DT values produce CborTaggedEpochDtExt; toJS() returns a number.\n * For Date-based toJS() use dt_as_Date or createDtExtension({ jsDate: true }).\n */\nexport const dt: CborExtension = createDtExtension();\n\n/**\n * Full-featured dt/DT CborExtension with Date support.\n * Tagged DT values produce CborTaggedEpochDtAsDateExt; toJS() returns a Date.\n * fromJS(Date) converts Date instances to tagged epoch values.\n */\nexport const dt_as_Date: CborExtension = createDtExtension({ jsDate: true });\n\nexport default dt;\n","/**\n * Shared IPv4 / IPv6 address parsing and formatting utilities.\n * Used by the \"ip\"/\"IP\" extension (RFC 9164) and the \"cri\"/\"CRI\" extension\n * (draft-ietf-core-href).\n */\n\n// ─── Parsing ──────────────────────────────────────────────────────────────────\n\nexport function parseIPv4(str: string): Uint8Array {\n const parts = str.split('.');\n if (parts.length !== 4)\n throw new SyntaxError(`ip: invalid IPv4 address: ${JSON.stringify(str)}`);\n const bytes = new Uint8Array(4);\n for (let i = 0; i < 4; i++) {\n const s = parts[i];\n if (!/^\\d+$/.test(s) || (s.length > 1 && s[0] === '0'))\n throw new SyntaxError(`ip: invalid IPv4 octet: ${JSON.stringify(s)}`);\n const n = parseInt(s, 10);\n if (n > 255) throw new SyntaxError(`ip: IPv4 octet out of range: ${n}`);\n bytes[i] = n;\n }\n return bytes;\n}\n\nexport function parseIPv6(str: string): Uint8Array {\n const bytes = new Uint8Array(16);\n if (str === '::') return bytes;\n\n // Handle IPv4-mapped suffix, e.g. ::ffff:192.0.2.1\n let head = str;\n let ipv4Tail: Uint8Array | null = null;\n const ipv4Match = str.match(/^(.*):(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})$/);\n if (ipv4Match) {\n head = ipv4Match[1];\n if (head.endsWith(':')) head += ':'; // restore :: split by the regex\n ipv4Tail = parseIPv4(ipv4Match[2]);\n }\n\n const halves = head.split('::');\n if (halves.length > 2)\n throw new SyntaxError(`ip: invalid IPv6 address: ${JSON.stringify(str)}`);\n\n const doubleColon = halves.length === 2;\n const leftParts = halves[0] ? halves[0].split(':') : [];\n const rightParts = doubleColon && halves[1] ? halves[1].split(':') : [];\n const totalGroups = ipv4Tail ? 6 : 8;\n\n if (!doubleColon && leftParts.length !== totalGroups)\n throw new SyntaxError(`ip: invalid IPv6 address: ${JSON.stringify(str)}`);\n if (doubleColon && leftParts.length + rightParts.length >= totalGroups)\n throw new SyntaxError(`ip: invalid IPv6 address: ${JSON.stringify(str)}`);\n\n const zeroCount = totalGroups - leftParts.length - rightParts.length;\n const groups = [...leftParts, ...Array(zeroCount).fill('0'), ...rightParts];\n\n let offset = 0;\n for (const g of groups) {\n if (!/^[0-9a-fA-F]{1,4}$/.test(g))\n throw new SyntaxError(`ip: invalid IPv6 group: ${JSON.stringify(g)}`);\n const n = parseInt(g, 16);\n bytes[offset++] = (n >> 8) & 0xff;\n bytes[offset++] = n & 0xff;\n }\n if (ipv4Tail) bytes.set(ipv4Tail, 12);\n return bytes;\n}\n\n// ─── Formatting ───────────────────────────────────────────────────────────────\n\nexport function formatIPv4(bytes: Uint8Array): string {\n return Array.from(bytes).join('.');\n}\n\nexport function formatIPv6(bytes: Uint8Array): string {\n // RFC 5952 §5: IPv4-mapped (::ffff:a.b.c.d) — bytes 0-9 zero, 10-11 = 0xffff\n const isIpv4Mapped =\n bytes.slice(0, 10).every((b) => b === 0) &&\n bytes[10] === 0xff &&\n bytes[11] === 0xff;\n\n const ipv4Suffix = isIpv4Mapped ? formatIPv4(bytes.slice(12)) : null;\n\n const hexGroups = ipv4Suffix ? 6 : 8;\n const groups: number[] = [];\n for (let i = 0; i < hexGroups * 2; i += 2)\n groups.push((bytes[i] << 8) | bytes[i + 1]);\n\n // RFC 5952 §4.2.3: find longest run of consecutive zero groups (≥ 2) for ::\n let bestStart = -1,\n bestLen = 0;\n let i = 0;\n while (i < hexGroups) {\n if (groups[i] === 0) {\n let j = i + 1;\n while (j < hexGroups && groups[j] === 0) j++;\n if (j - i > bestLen) {\n bestStart = i;\n bestLen = j - i;\n }\n i = j;\n } else {\n i++;\n }\n }\n if (bestLen < 2) bestStart = -1;\n\n const fmt = (g: number) => g.toString(16);\n let hexPart: string;\n if (bestStart === -1) {\n hexPart = groups.map(fmt).join(':');\n } else {\n const left = groups.slice(0, bestStart).map(fmt).join(':');\n const right = groups\n .slice(bestStart + bestLen)\n .map(fmt)\n .join(':');\n hexPart = `${left}::${right}`;\n }\n\n return ipv4Suffix ? `${hexPart}:${ipv4Suffix}` : hexPart;\n}\n","/**\n * CDN \"ip\" / \"IP\" app-extension (§3.3 of draft-ietf-cbor-edn-literals-27).\n *\n * Parses IPv4 / IPv6 address strings (RFC 3986 §3.2.2) into byte strings,\n * and optionally wraps them in CBOR tags per RFC 9164:\n * - tag 52 IPv4 address or prefix\n * - tag 54 IPv6 address or prefix\n *\n * Syntax:\n * ip'192.0.2.42' → CborIpExt bare 4-byte string\n * ip'2001:db8::1' → CborIpExt bare 16-byte string\n * ip'192.0.2.0/24' → CborIpPrefixExt bare [24, h'c00002']\n * ip'2001:db8::/32' → CborIpPrefixExt bare [32, h'20010db8']\n * IP'192.0.2.42' → CborTaggedIpExt tag(52, h'...')\n * IP'2001:db8::1' → CborTaggedIpExt tag(54, h'...')\n * IP'192.0.2.0/24' → CborTaggedIpExt tag(52, [24, h'c00002'])\n * IP'2001:db8::/32' → CborTaggedIpExt tag(54, [32, h'20010db8'])\n *\n * Lowercase ip produces the unwrapped content; uppercase IP additionally\n * wraps it in the IANA address family tag (52 for IPv4, 54 for IPv6).\n */\n\nimport type { ToCDNOptions } from '../types';\nimport type { CborExtension } from './types';\nimport type { CborItem } from '../ast/CborItem';\nimport { CborByteString } from '../ast/CborByteString';\nimport { CborTag } from '../ast/CborTag';\nimport { CborArray } from '../ast/CborArray';\nimport { CborUint } from '../ast/CborUint';\nimport { CborTextString } from '../ast/CborTextString';\nimport { parseIPv4, parseIPv6, formatIPv4, formatIPv6 } from '../utils/ip';\nimport {\n resolveEiSuffix,\n canonicalEncodingWidth,\n decideTaggedAppSeqRendering,\n adjustRawAppSeqSource,\n adjustAppSeqIndicator,\n} from '../cdn/serialize-utils';\n\nconst PREFIX_IP = 'ip';\nconst PREFIX_IP_TAGGED = 'IP';\nconst TAG_IPV4 = 52n;\nconst TAG_IPV6 = 54n;\n\nconst utf8Strict = new TextDecoder('utf-8', { fatal: true });\n\nfunction stringFromAppSequence(items: CborItem[]): string {\n if (items.length !== 1)\n throw new SyntaxError('ip<<...>>: expected exactly one item');\n const item = items[0];\n if (item instanceof CborTextString) return item.value;\n if (item instanceof CborByteString) return utf8Strict.decode(item.value);\n throw new SyntaxError('ip<<...>>: expected a text string or byte string');\n}\n\n// ─── Address parsing ──────────────────────────────────────────────────────────\n\nfunction parseAddress(str: string): { bytes: Uint8Array; isV4: boolean } {\n if (/^\\d/.test(str) && str.includes('.') && !str.includes(':'))\n return { bytes: parseIPv4(str), isV4: true };\n return { bytes: parseIPv6(str), isV4: false };\n}\n\n// ─── Address formatting ───────────────────────────────────────────────────────\n\nfunction formatAddress(bytes: Uint8Array): string {\n if (bytes.length === 4) return formatIPv4(bytes);\n if (bytes.length === 16) return formatIPv6(bytes);\n throw new SyntaxError(`ip: unexpected byte length: ${bytes.length}`);\n}\n\n// ─── CIDR helpers ─────────────────────────────────────────────────────────────\n\nfunction truncateToPrefix(bytes: Uint8Array, prefixLen: number): Uint8Array {\n // RFC 9164 §2.3: zero host bits, then strip trailing zero bytes.\n const masked = new Uint8Array(bytes.length);\n masked.set(bytes);\n const fullBytes = Math.floor(prefixLen / 8);\n const extraBits = prefixLen % 8;\n if (extraBits > 0 && fullBytes < bytes.length)\n masked[fullBytes] &= (0xff << (8 - extraBits)) & 0xff;\n for (let i = fullBytes + (extraBits > 0 ? 1 : 0); i < bytes.length; i++)\n masked[i] = 0;\n let end = Math.ceil(prefixLen / 8);\n while (end > 0 && masked[end - 1] === 0) end--;\n return masked.slice(0, end);\n}\n\nfunction expandToFull(truncated: Uint8Array, fullLen: number): Uint8Array {\n const full = new Uint8Array(fullLen);\n full.set(truncated);\n return full;\n}\n\n// ─── CborItem subclasses ─────────────────────────────────────────────────────\n\n/**\n * Bare IP address byte string whose toCDN() emits ip'…' notation.\n */\nexport class CborIpExt extends CborByteString {\n override _toCDN(\n options: ToCDNOptions | undefined,\n _depth: number,\n path?: readonly unknown[]\n ): string {\n if (options?.appPrefix === false)\n return super._toCDN(options, _depth, path);\n const eiSuffix = resolveEiSuffix(options, this.encodingWidth, () =>\n canonicalEncodingWidth(BigInt(this.value.length))\n );\n const decision = decideTaggedAppSeqRendering(\n options,\n this.appSeqSource,\n undefined,\n this.appSeqSourceFeatures\n );\n if (decision === 'adjusted')\n return adjustAppSeqIndicator(\n this.appSeqSource!,\n eiSuffix,\n options,\n this.appSeqInnerEnd,\n this.appSeqComments\n );\n return `${PREFIX_IP}'${formatAddress(this.value)}'${eiSuffix}`;\n }\n}\n\n/**\n * Bare IP address prefix (CIDR) whose toCDN() emits ip'…/prefix' notation.\n * Encoded as [prefixLen, truncatedBytes] per RFC 9164 §2.3, without a tag.\n */\nexport class CborIpPrefixExt extends CborArray {\n private readonly _isV4: boolean;\n\n constructor(prefixLen: number, truncated: Uint8Array, isV4: boolean) {\n super([new CborUint(BigInt(prefixLen)), new CborByteString(truncated)]);\n this._isV4 = isV4;\n }\n\n override _toCDN(\n options: ToCDNOptions | undefined,\n depth: number,\n path?: readonly unknown[]\n ): string {\n if (options?.appPrefix === false) return super._toCDN(options, depth, path);\n const decision = decideTaggedAppSeqRendering(\n options,\n this.appSeqSource,\n undefined,\n this.appSeqSourceFeatures\n );\n // This form never emits an encoding indicator of its own (unlike the\n // other ip/dt notations), so 'adjusted' only ever strips one.\n if (decision === 'adjusted')\n return adjustAppSeqIndicator(\n this.appSeqSource!,\n '',\n options,\n this.appSeqInnerEnd,\n this.appSeqComments\n );\n const prefixLen = Number((this.items[0] as CborUint).value);\n const truncated = (this.items[1] as CborByteString).value;\n const full = expandToFull(truncated, this._isV4 ? 4 : 16);\n return `${PREFIX_IP}'${formatAddress(full)}/${prefixLen}'`;\n }\n}\n\n/**\n * CBOR tag(52/54, …) IP address whose toCDN() emits IP'…' notation.\n * Content may be a byte string (plain address) or an array [prefix, bytes]\n * (CIDR prefix per RFC 9164).\n */\nexport class CborTaggedIpExt extends CborTag {\n constructor(tag: bigint, content: CborItem) {\n super(tag, content);\n }\n\n override _toCDN(\n options: ToCDNOptions | undefined,\n depth: number,\n path?: readonly unknown[]\n ): string {\n if (options?.appPrefix === false) return super._toCDN(options, depth, path);\n const decision = decideTaggedAppSeqRendering(\n options,\n this.appSeqSource,\n this.ednSource,\n this.appSeqSourceFeatures,\n this.appSeqEncodingEditsComplete\n );\n if (decision === 'verbatim') return this.appSeqSource!;\n if (decision === 'source')\n return adjustRawAppSeqSource(\n this.appSeqSource!,\n options,\n this.appSeqComments,\n this.appSeqEncodingEdits\n );\n // Unlike dt's content classes, ip's content (CborByteString / CborArray\n // / CborUint) never self-switches on `appPrefix`, so no need to force\n // it false here — doing so would also force hex byte-string encoding\n // (see CborByteString._toCDN), overriding `bstrEncoding`/`sqstr`.\n if (decision === 'structural') return super._toCDN(options, depth, path);\n if (decision === 'adjusted') {\n const eiSuffix = resolveEiSuffix(options, this.encodingWidth, () =>\n canonicalEncodingWidth(this.tag)\n );\n return adjustAppSeqIndicator(\n this.appSeqSource!,\n eiSuffix,\n options,\n this.appSeqInnerEnd,\n this.appSeqComments\n );\n }\n const fullLen = this.tag === TAG_IPV4 ? 4 : 16;\n const c = this.content as CborItem;\n if (c instanceof CborByteString) {\n // IP'...'_N only encodes the tag's width. If the inner byte string uses a\n // non-canonical length header, fall back to generic tag notation to preserve it.\n if (c.encodingWidth !== undefined)\n return super._toCDN(options, depth, path);\n const eiSuffix = resolveEiSuffix(options, this.encodingWidth, () =>\n canonicalEncodingWidth(this.tag)\n );\n return `${PREFIX_IP_TAGGED}'${formatAddress(c.value)}'${eiSuffix}`;\n }\n if (\n c instanceof CborArray &&\n c.items.length === 2 &&\n c.items[0] instanceof CborUint &&\n c.items[1] instanceof CborByteString\n ) {\n // Fall back if the inner array or either of its items has non-canonical encoding.\n if (\n c.encodingWidth !== undefined ||\n (c.items[0] as CborUint).encodingWidth !== undefined ||\n (c.items[1] as CborByteString).encodingWidth !== undefined\n )\n return super._toCDN(options, depth, path);\n const prefixLen = Number((c.items[0] as CborUint).value);\n const full = expandToFull((c.items[1] as CborByteString).value, fullLen);\n const eiSuffix = resolveEiSuffix(options, this.encodingWidth, () =>\n canonicalEncodingWidth(this.tag)\n );\n return `${PREFIX_IP_TAGGED}'${formatAddress(full)}/${prefixLen}'${eiSuffix}`;\n }\n return super._toCDN(options, depth, path);\n }\n}\n\n// ─── Factory ──────────────────────────────────────────────────────────────────\n\nfunction buildIpValue(prefix: string, content: string): CborItem {\n const slashIdx = content.indexOf('/');\n\n if (slashIdx === -1) {\n const { bytes, isV4 } = parseAddress(content);\n if (prefix === PREFIX_IP_TAGGED)\n return new CborTaggedIpExt(\n isV4 ? TAG_IPV4 : TAG_IPV6,\n new CborByteString(bytes)\n );\n return new CborIpExt(bytes);\n }\n\n // CIDR notation — supported with both lowercase ip and uppercase IP.\n // lowercase ip → bare [prefixLen, truncatedBytes] (no tag)\n // uppercase IP → tag(52/54, [prefixLen, truncatedBytes])\n const addrStr = content.slice(0, slashIdx);\n const lenStr = content.slice(slashIdx + 1);\n if (!/^\\d+$/.test(lenStr))\n throw new SyntaxError(\n `ip: invalid prefix length: ${JSON.stringify(lenStr)}`\n );\n const prefixLen = parseInt(lenStr, 10);\n\n const { bytes, isV4 } = parseAddress(addrStr);\n const maxLen = isV4 ? 32 : 128;\n if (prefixLen > maxLen)\n throw new SyntaxError(\n `ip: prefix length ${prefixLen} exceeds maximum ${maxLen} for ${isV4 ? 'IPv4' : 'IPv6'}`\n );\n\n const truncated = truncateToPrefix(bytes, prefixLen);\n if (prefix === PREFIX_IP_TAGGED) {\n return new CborTaggedIpExt(\n isV4 ? TAG_IPV4 : TAG_IPV6,\n new CborArray([\n new CborUint(BigInt(prefixLen)),\n new CborByteString(truncated),\n ])\n );\n }\n return new CborIpPrefixExt(prefixLen, truncated, isV4);\n}\n\n// ─── Factory ──────────────────────────────────────────────────────────────────\n\n/**\n * Create an ip/IP CborExtension (RFC 9164 / §3.3 of draft-ietf-cbor-edn-literals-27).\n *\n * - `ip'addr'` → CborIpExt (bare byte string, 4 or 16 bytes)\n * - `IP'addr'` → CborTaggedIpExt tag(52 or 54, bytes)\n * - `IP'addr/prefix'` → CborTaggedIpExt tag(52 or 54, [prefix_len, bytes])\n * - parseTag(52/54, …) → CborTaggedIpExt (reversible via fromCBOR)\n * - fromJS(tagged obj) → CborTaggedIpExt (reversible via fromJS)\n */\nexport const ip: CborExtension = {\n appStringPrefixes: [PREFIX_IP, PREFIX_IP_TAGGED],\n tagNumbers: [TAG_IPV4, TAG_IPV6],\n // ip/IP results always have a dedicated subclass (CborIpExt /\n // CborIpPrefixExt / CborTaggedIpExt) that regenerates its notation by\n // default; 'optional' preserves the <<...>> spelling only when\n // ToCDNOptions.preserveAppPrefix is set, without changing the\n // returned node's class/identity (see preservedAppSeqSpelling).\n preserveAppSeqSource: 'optional',\n\n parseAppString(prefix: string, content: string): CborItem {\n return buildIpValue(prefix, content);\n },\n\n parseAppSequence(prefix: string, items: CborItem[]): CborItem {\n return buildIpValue(prefix, stringFromAppSequence(items));\n },\n\n parseTag(tag: bigint, value: CborItem): CborItem | undefined {\n if (tag !== TAG_IPV4 && tag !== TAG_IPV6) return undefined;\n if (value instanceof CborByteString || value instanceof CborArray)\n return new CborTaggedIpExt(tag, value);\n return undefined;\n },\n};\n\nexport default ip;\n","/**\n * Standard CDN \"cri\" / \"CRI\" app-extension (§3.7 and §6.2.5 of draft-ietf-cbor-edn-literals-27).\n *\n * Converts URI references (RFC 3986) to CRI (Constrained Resource Identifier,\n * draft-ietf-core-href) CBOR array format and back.\n *\n * Syntax:\n * cri'https://example.com/path' → bare CRI array (no CBOR tag)\n * CRI'https://example.com/path' → tag(99, CRI array)\n *\n * CRI array structures (trailing defaults removed):\n * Absolute: [scheme, authority, path, ?query, ?fragment]\n * Network-path: [false, authority, path, ?query, ?fragment]\n * Absolute-path: [true, path, ?query, ?fragment]\n * Relative-path: [uint(discard), path, ?query, ?fragment]\n * Same-document: [0, ?query, ?fragment]\n *\n * where:\n * scheme = scheme-id (nint, e.g. -4 for https) or scheme-name (text)\n * authority = [?userinfo, host, ?port] — host is text labels or IP bytes\n * path = [\"seg1\", \"seg2\", ...]\n * query = [\"k=v\", ...]\n * fragment = text\n * discard = uint — number of path segments to remove from base before appending\n * (1 = same directory, 2 = one level up \"../\", N = (N-1) levels up)\n *\n * Tag number 99 is used for the tagged \"CRI\" variant (§3.7 of draft-ietf-cbor-edn-literals-27).\n */\n\nimport type { ToCDNOptions } from '../types';\nimport type { CborExtension } from './types';\nimport type { CborItem } from '../ast/CborItem';\nimport { CborArray } from '../ast/CborArray';\nimport { CborTag } from '../ast/CborTag';\nimport { CborNint } from '../ast/CborNint';\nimport { CborUint } from '../ast/CborUint';\nimport { CborTextString } from '../ast/CborTextString';\nimport { CborByteString } from '../ast/CborByteString';\nimport { CborSimple } from '../ast/CborSimple';\nimport { parseIPv4, parseIPv6, formatIPv4, formatIPv6 } from '../utils/ip';\nimport {\n resolveEiSuffix,\n canonicalEncodingWidth,\n decideTaggedAppSeqRendering,\n adjustRawAppSeqSource,\n adjustAppSeqIndicator,\n} from '../cdn/serialize-utils';\n\n// ─── Constants ────────────────────────────────────────────────────────────────\n\nconst PREFIX_CRI = 'cri';\nconst PREFIX_CRI_TAGGED = 'CRI';\n\n/**\n * CBOR tag number for the tagged CRI variant (§3.7 and §6.2.5 of draft-ietf-cbor-edn-literals-27).\n */\nexport const TAG_CRI = 99n;\n\n// ─── Scheme-ID table ──────────────────────────────────────────────────────────\n\n/**\n * Scheme-id values from the IANA URI Schemes Registry.\n * Formula: scheme-id = -(scheme-number + 1)\n * https://www.iana.org/assignments/uri-schemes/uri-schemes.xhtml\n */\nconst SCHEME_ID_BY_NAME = new Map<string, bigint>([\n ['coap', -1n],\n ['coaps', -2n],\n ['http', -3n],\n ['https', -4n],\n ['urn', -5n],\n ['did', -6n],\n ['coap+tcp', -7n],\n ['coaps+tcp', -8n],\n ['coap+ws', -25n],\n ['coaps+ws', -26n],\n]);\n\nconst SCHEME_NAME_BY_ID = new Map<bigint, string>(\n [...SCHEME_ID_BY_NAME.entries()].map(([name, id]) => [id, name])\n);\n\n// ─── Percent-encoding helpers ─────────────────────────────────────────────────\n\nfunction pctDecode(s: string): string {\n try {\n return decodeURIComponent(s);\n } catch {\n return s;\n }\n}\n\nconst textEncoder = new TextEncoder();\nconst utf8Strict = new TextDecoder('utf-8', { fatal: true });\n\nfunction pctEncodeChar(c: string): string {\n return Array.from(\n textEncoder.encode(c),\n (b) => `%${b.toString(16).toUpperCase().padStart(2, '0')}`\n ).join('');\n}\n\nfunction encodePct(s: string, isAllowed: (c: string) => boolean): string {\n let out = '';\n for (const c of s) {\n out += isAllowed(c) ? c : pctEncodeChar(c);\n }\n return out;\n}\n\n// unreserved = A-Za-z0-9 \"-\" \".\" \"_\" \"~\"\n// sub-delims = \"!\" / \"$\" / \"&\" / \"'\" / \"(\" / \")\" / \"*\" / \"+\" / \",\" / \";\" / \"=\"\nfunction isUnreserved(c: string): boolean {\n return /[A-Za-z0-9\\-._~]/.test(c);\n}\nfunction isSubDelim(c: string): boolean {\n return /[!$&'()*+,;=]/.test(c);\n}\n\n// path segment: unreserved | sub-delims | \":\" | \"@\"\nfunction isPathAllowed(c: string): boolean {\n return isUnreserved(c) || isSubDelim(c) || c === ':' || c === '@';\n}\n\n// query item: path chars | \"/\" | \"?\" — but NOT \"&\" (used as item separator between items)\nfunction isQueryItemAllowed(c: string): boolean {\n return (isPathAllowed(c) || c === '/' || c === '?') && c !== '&';\n}\n\n// fragment: same as query\nfunction isFragmentAllowed(c: string): boolean {\n return isPathAllowed(c) || c === '/' || c === '?';\n}\n\n// userinfo: unreserved | sub-delims | \":\" (RFC 3986 §3.2.1: \":\" is allowed in userinfo)\nfunction isUserinfoAllowed(c: string): boolean {\n return isUnreserved(c) || isSubDelim(c) || c === ':';\n}\n\n// registered name label: unreserved | sub-delims\nfunction isRegNameAllowed(c: string): boolean {\n return isUnreserved(c) || isSubDelim(c);\n}\n\n// ─── Authority conversion ──────────────────────────────────────────────────────\n\n/**\n * Parse URI authority string → CRI authority array.\n *\n * CRI authority = [?userinfo, host, ?port]\n * userinfo = (false, text) — two inline elements\n * host-name = *text — zero-or-more text labels, inline\n * host-ip = bytes (4 or 16 bytes) — single inline element\n * port = uint 0..65535 — trailing optional element\n */\nfunction parseAuthorityStr(authStr: string): CborArray {\n const items: CborItem[] = [];\n let str = authStr;\n\n // Strip userinfo (everything up to the last '@')\n const atIdx = str.indexOf('@');\n if (atIdx >= 0) {\n items.push(CborSimple.FALSE);\n items.push(new CborTextString(pctDecode(str.slice(0, atIdx))));\n str = str.slice(atIdx + 1);\n }\n\n // IPv6 bracket literal: [addr]:port\n let hostStr: string;\n let portStr: string | null = null;\n\n if (str.startsWith('[')) {\n const close = str.indexOf(']');\n if (close < 0)\n throw new SyntaxError('cri: unterminated IPv6 bracket in authority');\n hostStr = str.slice(1, close);\n const after = str.slice(close + 1);\n if (after.startsWith(':')) portStr = after.slice(1);\n else if (after.length > 0)\n throw new SyntaxError(\n `cri: unexpected characters after ']' in authority`\n );\n items.push(new CborByteString(parseIPv6(hostStr)));\n } else {\n // IPv4 address or registered name — find port via last ':'\n const colonIdx = str.lastIndexOf(':');\n if (colonIdx >= 0) {\n hostStr = str.slice(0, colonIdx);\n portStr = str.slice(colonIdx + 1);\n } else {\n hostStr = str;\n }\n\n if (hostStr === '') {\n // Empty host (e.g. file:///path) — zero labels, nothing pushed\n } else if (/^\\d{1,3}(\\.\\d{1,3}){3}$/.test(hostStr)) {\n items.push(new CborByteString(parseIPv4(hostStr)));\n } else {\n // Registered name: split by '.' into lowercase labels\n for (const label of hostStr.toLowerCase().split('.')) {\n items.push(new CborTextString(label));\n }\n }\n }\n\n // Optional port\n if (portStr !== null && portStr !== '') {\n if (!/^\\d+$/.test(portStr))\n throw new SyntaxError(`cri: invalid port: ${JSON.stringify(portStr)}`);\n const port = parseInt(portStr, 10);\n if (port > 65535) throw new SyntaxError(`cri: port ${port} out of range`);\n items.push(new CborUint(BigInt(port)));\n }\n\n return new CborArray(items);\n}\n\n/**\n * Convert CRI authority array → URI authority string.\n */\nfunction criAuthorityToUri(auth: CborArray): string {\n const items = auth.items;\n let idx = 0;\n let result = '';\n\n // Userinfo: (false, text) as two consecutive elements\n if (\n idx < items.length &&\n items[idx] instanceof CborSimple &&\n (items[idx] as CborSimple).value === 20\n ) {\n idx++; // skip false sentinel\n const user = items[idx++] as CborTextString;\n result += encodePct(user.value, isUserinfoAllowed) + '@';\n }\n\n if (idx >= items.length) return result; // empty host\n\n const hostFirst = items[idx];\n if (hostFirst instanceof CborByteString) {\n idx++;\n const { length } = hostFirst.value;\n if (length === 4) {\n result += formatIPv4(hostFirst.value);\n } else if (length === 16) {\n result += '[' + formatIPv6(hostFirst.value) + ']';\n } else {\n throw new Error(`cri: unexpected host-ip byte length: ${length}`);\n }\n // Optional zone-id (text string immediately after the IP bytes)\n if (idx < items.length && items[idx] instanceof CborTextString) {\n result += `%25${encodePct((items[idx++] as CborTextString).value, isRegNameAllowed)}`;\n }\n } else {\n // Registered name: consecutive text strings up to the optional uint port\n const labels: string[] = [];\n while (idx < items.length && items[idx] instanceof CborTextString) {\n labels.push(\n encodePct((items[idx++] as CborTextString).value, isRegNameAllowed)\n );\n }\n result += labels.join('.');\n }\n\n // Optional port\n if (idx < items.length && items[idx] instanceof CborUint) {\n result += ':' + (items[idx] as CborUint).value.toString();\n }\n\n return result;\n}\n\n// ─── CRI array ↔ URI string ───────────────────────────────────────────────────\n\n/**\n * Parse `//authority/path` from a string starting with `//`.\n * Returns the CRI authority array and path segments.\n */\nfunction _parseHierarchicalPart(rest: string): {\n authority: CborArray;\n pathSegments: CborTextString[];\n} {\n const afterSlashes = rest.slice(2);\n const slashIdx = afterSlashes.indexOf('/');\n let authStr: string;\n let pathSegments: CborTextString[];\n if (slashIdx >= 0) {\n authStr = afterSlashes.slice(0, slashIdx);\n const pathStr = afterSlashes.slice(slashIdx + 1);\n pathSegments = pathStr\n .split('/')\n .map((s) => new CborTextString(pctDecode(s)));\n } else {\n authStr = afterSlashes;\n pathSegments = [];\n }\n return { authority: parseAuthorityStr(authStr), pathSegments };\n}\n\n/**\n * Parse a URI or URI-reference string into CRI array items.\n *\n * Supports all RFC 3986 reference forms:\n * Absolute URI: https://example.com/path → [scheme, authority, path, ...]\n * Network-path ref: //other.example.com/path → [false, authority, path, ...]\n * Absolute-path ref: /abs/path → [true, path, ...]\n * Relative-path ref: foo, ../bar → [uint(discard), path, ...]\n * Same-document ref: #frag, ?q=1, (empty) → [0, ...]\n *\n * Produces a compact representation with trailing defaults removed.\n */\nfunction uriToCriItems(str: string): CborItem[] {\n // ── 1. Fragment ────────────────────────────────────────────────────────────\n let rest = str;\n let fragment: string | null = null;\n const hashIdx = rest.indexOf('#');\n if (hashIdx >= 0) {\n fragment = pctDecode(rest.slice(hashIdx + 1));\n rest = rest.slice(0, hashIdx);\n }\n\n // ── 2. Query ───────────────────────────────────────────────────────────────\n let queryItems: CborTextString[] | null = null;\n const qIdx = rest.indexOf('?');\n if (qIdx >= 0) {\n const qs = rest.slice(qIdx + 1);\n rest = rest.slice(0, qIdx);\n // Per draft-ietf-core-href §5.1:\n // [] (empty array) = absent query (no \"?\") — this is the trailing default\n // [\"\"] (one empty string) = present but empty query (\"?\")\n // [\"k=v\", ...] = query with parameters\n queryItems = qs.split('&').map((s) => new CborTextString(pctDecode(s)));\n }\n\n // ── 3. Detect reference form and build leading items ───────────────────────\n const items: CborItem[] = [];\n\n const schemeMatch = /^([a-zA-Z][a-zA-Z0-9+.\\-]*):([\\s\\S]*)$/.exec(rest);\n if (schemeMatch) {\n // Absolute URI: scheme + hier-part\n const schemeName = schemeMatch[1].toLowerCase();\n const hierPart = schemeMatch[2];\n const schemeId = SCHEME_ID_BY_NAME.get(schemeName);\n items.push(\n schemeId !== undefined\n ? new CborNint(schemeId)\n : new CborTextString(schemeName)\n );\n if (hierPart.startsWith('//')) {\n const { authority, pathSegments } = _parseHierarchicalPart(hierPart);\n items.push(authority, new CborArray(pathSegments));\n } else if (hierPart.startsWith('/')) {\n const pathSegments = hierPart\n .slice(1)\n .split('/')\n .map((s) => new CborTextString(pctDecode(s)));\n items.push(CborSimple.NULL, new CborArray(pathSegments));\n } else {\n const pathSegments = hierPart\n .split('/')\n .map((s) => new CborTextString(pctDecode(s)));\n items.push(CborSimple.TRUE, new CborArray(pathSegments));\n }\n } else if (rest.startsWith('//')) {\n // Network-path reference: //authority/path\n const { authority, pathSegments } = _parseHierarchicalPart(rest);\n items.push(CborSimple.FALSE, authority, new CborArray(pathSegments));\n } else if (rest.startsWith('/')) {\n // Absolute-path reference: /path\n const pathSegments = rest\n .slice(1)\n .split('/')\n .map((s) => new CborTextString(pctDecode(s)));\n items.push(CborSimple.TRUE, new CborArray(pathSegments));\n } else if (rest === '') {\n // Same-document reference (only query/fragment differ from base)\n items.push(new CborUint(0n));\n } else {\n // Relative-path reference: count leading ../ sequences\n let discard = 1n;\n let pathRest = rest;\n let hasDotSlash = false;\n if (pathRest.startsWith('./')) {\n hasDotSlash = true;\n pathRest = pathRest.slice(2);\n }\n while (pathRest.startsWith('../')) {\n discard++;\n pathRest = pathRest.slice(3);\n }\n // Handle lone '..' or '.' at end\n if (pathRest === '..') {\n discard++;\n pathRest = '';\n } else if (pathRest === '.') {\n pathRest = '';\n }\n // RFC 3986 §3.3 path-noscheme: the first segment of a relative-path reference\n // must not contain ':' unless the path was explicitly prefixed with \"./\"\n // (which disambiguates it from a scheme). Without \"./\" the colon makes the\n // reference look like an absolute URI to parsers, and is most likely a typo.\n // This check applies only when discard=1 (same-directory) and no \"./\" was given.\n // For discard≥2 (e.g. \"../foo:bar\") the leading \"../\" already disambiguates.\n if (discard === 1n && !hasDotSlash && pathRest !== '') {\n const firstSeg = pathRest.split('/')[0];\n if (firstSeg.includes(':'))\n throw new SyntaxError(\n `cri: invalid relative-path reference — first segment must not contain ':' without a './' prefix (RFC 3986 §3.3): ${JSON.stringify(str)}`\n );\n }\n const pathSegments =\n pathRest === ''\n ? []\n : pathRest.split('/').map((s) => new CborTextString(pctDecode(s)));\n items.push(new CborUint(discard), new CborArray(pathSegments));\n }\n\n // ── 4. Append query and fragment ──────────────────────────────────────────\n if (queryItems !== null) items.push(new CborArray(queryItems));\n if (fragment !== null) {\n // When fragment is present but query is absent, use null as placeholder so that\n // \"no query\" is distinguishable from \"empty query []\" at the query position.\n if (queryItems === null) items.push(CborSimple.NULL);\n items.push(new CborTextString(fragment));\n }\n\n // ── 5. Trim trailing defaults ─────────────────────────────────────────────\n // Remove null placeholder for absent query (always at items.length - 2 when present)\n if (fragment !== null && queryItems === null) {\n items.splice(items.length - 2, 1);\n }\n // Remove trailing empty PATH array — but only when it is truly the last element\n // (i.e., neither a query nor a fragment follows it). An empty QUERY array []\n // means \"query is present but empty\" (?), which must be preserved.\n if (queryItems === null && fragment === null) {\n const last = items[items.length - 1];\n if (last instanceof CborArray && last.items.length === 0) {\n items.pop();\n }\n }\n\n // ── 6. Canonical same-document form ──────────────────────────────────────\n // Per §5.2: [discard=0] with no other items is sent as [] (empty array).\n if (\n items.length === 1 &&\n items[0] instanceof CborUint &&\n (items[0] as CborUint).value === 0n\n ) {\n return [];\n }\n\n return items;\n}\n\n/**\n * Encode query and fragment items from `items[startIdx..]` into a URI suffix string.\n * Handles both the `[] = empty query`, `[items] = query params`, `null = absent query`,\n * and optional trailing text fragment.\n */\nfunction _criSuffix(items: readonly CborItem[], startIdx: number): string {\n let idx = startIdx;\n let result = '';\n\n if (idx < items.length) {\n const qi = items[idx];\n if (qi instanceof CborArray) {\n idx++;\n // Per §5.1 / draft-ietf-core-href:\n // [] (empty array) = absent query — omit \"?\" entirely (trailing default)\n // [\"\"] = present but empty query — emit \"?\"\n // [\"k=v\", ...] = query with parameters — emit \"?k=v&...\"\n if (qi.items.length > 0) {\n const params = qi.items.map((s) => {\n if (!(s instanceof CborTextString))\n throw new Error('cri: query item must be a text string');\n return encodePct(s.value, isQueryItemAllowed);\n });\n result += '?' + params.join('&');\n }\n // [] = absent query → no '?' emitted\n } else if (qi instanceof CborSimple && qi.value === 22) {\n idx++; // explicit null = absent query component\n }\n // else: not a query item (text fragment follows); leave idx unchanged\n }\n\n if (idx < items.length && items[idx] instanceof CborTextString) {\n result +=\n '#' + encodePct((items[idx] as CborTextString).value, isFragmentAllowed);\n }\n\n return result;\n}\n\n/**\n * Encode a CRI path array into URI path segments.\n */\nfunction _criPathSegs(pathArr: CborArray): string[] {\n return pathArr.items.map((s) => {\n if (!(s instanceof CborTextString))\n throw new Error('cri: path segment must be a text string');\n return encodePct(s.value, isPathAllowed);\n });\n}\n\n/**\n * Convert CRI array items → URI string.\n *\n * Handles all CRI reference forms:\n * Absolute: first element is CborNint or CborTextString (scheme)\n * Network-path: first element is false (CborSimple(20))\n * Absolute-path: first element is true (CborSimple(21))\n * Relative-path: first element is CborUint (discard count ≥ 1)\n * Same-document: first element is CborUint(0)\n */\nfunction criItemsToUri(items: readonly CborItem[]): string {\n // Per §5.2: [] (empty array) is the canonical form of the same-document\n // reference [discard=0] with no query or fragment.\n if (items.length === 0) return '';\n\n let idx = 0;\n const first = items[idx++];\n\n // ── Absolute URI ──────────────────────────────────────────────────────────\n if (first instanceof CborNint || first instanceof CborTextString) {\n let schemePart: string;\n if (first instanceof CborNint) {\n const name = SCHEME_NAME_BY_ID.get(first.value);\n if (name === undefined)\n throw new Error(`cri: unrecognised scheme-id ${first.value}`);\n schemePart = name + ':';\n } else {\n schemePart = (first as CborTextString).value + ':';\n }\n\n if (idx >= items.length) return schemePart;\n\n const second = items[idx++];\n let authorityPart = '';\n let rootedPath = false;\n\n if (second instanceof CborArray) {\n authorityPart = '//' + criAuthorityToUri(second);\n rootedPath = true;\n } else if (second instanceof CborSimple) {\n if (second.value === 22)\n rootedPath = true; // null = NOAUTH-ROOTBASED\n else if (second.value === 21)\n rootedPath = false; // true = NOAUTH-ROOTLESS\n else\n throw new Error(\n `cri: unexpected no-authority value: simple(${second.value})`\n );\n } else {\n throw new Error('cri: unexpected type for authority element');\n }\n\n let pathPart = '';\n if (idx < items.length && items[idx] instanceof CborArray) {\n const pathArr = items[idx++] as CborArray;\n if (pathArr.items.length > 0) {\n pathPart = (rootedPath ? '/' : '') + _criPathSegs(pathArr).join('/');\n }\n }\n\n return schemePart + authorityPart + pathPart + _criSuffix(items, idx);\n }\n\n // ── Network-path reference: [false, authority-array, path-array, ...] ─────\n if (first instanceof CborSimple && first.value === 20) {\n if (idx >= items.length || !(items[idx] instanceof CborArray))\n throw new Error(\n 'cri: network-path reference requires an authority array'\n );\n const authority = criAuthorityToUri(items[idx++] as CborArray);\n let pathPart = '';\n if (idx < items.length && items[idx] instanceof CborArray) {\n const pathArr = items[idx++] as CborArray;\n if (pathArr.items.length > 0) {\n pathPart = '/' + _criPathSegs(pathArr).join('/');\n }\n }\n return '//' + authority + pathPart + _criSuffix(items, idx);\n }\n\n // ── Absolute-path reference: [true, path-array, ...] ─────────────────────\n if (first instanceof CborSimple && first.value === 21) {\n let pathPart = '/';\n if (idx < items.length && items[idx] instanceof CborArray) {\n const pathArr = items[idx++] as CborArray;\n pathPart = '/' + _criPathSegs(pathArr).join('/');\n }\n return pathPart + _criSuffix(items, idx);\n }\n\n // ── Relative-path / same-document: [uint(discard), ...] ──────────────────\n if (first instanceof CborUint) {\n const discard = first.value;\n\n if (discard === 0n) {\n // Same-document reference: path unchanged, only query/fragment differ\n return _criSuffix(items, idx);\n }\n\n // discard=1 → same directory (no \"../\" prefix)\n // discard=N → (N-1) \"../\" prefixes\n const dotdots = discard === 1n ? '' : '../'.repeat(Number(discard) - 1);\n\n let pathPart: string;\n if (idx < items.length && items[idx] instanceof CborArray) {\n const pathArr = items[idx++] as CborArray;\n if (pathArr.items.length > 0) {\n const segs = _criPathSegs(pathArr);\n // §6.1: when discard=1, prefix with \"./\" if the first segment contains \":\"\n // to prevent URI parsers from misreading it as a scheme (RFC 3986 §3.3).\n const needsDotSlash = discard === 1n && segs[0].includes(':');\n pathPart = (needsDotSlash ? './' : dotdots) + segs.join('/');\n } else {\n // Empty path array (should be trimmed, but handle defensively)\n pathPart = dotdots === '' ? './' : dotdots;\n }\n } else {\n // No path array (trimmed away)\n pathPart = dotdots === '' ? './' : dotdots;\n }\n\n return pathPart + _criSuffix(items, idx);\n }\n\n throw new Error(`cri: unrecognised first element type in CRI array`);\n}\n\n// ─── CborItem subclasses ──────────────────────────────────────────────────────\n\n/**\n * Bare CRI array whose toCDN() emits cri'…' notation.\n * Falls back to generic array notation if the content cannot be expressed as a URI.\n */\nexport class CborCriExt extends CborArray {\n override _toCDN(\n options: ToCDNOptions | undefined,\n depth: number,\n path?: readonly unknown[]\n ): string {\n if (options?.appPrefix === false) return super._toCDN(options, depth, path);\n const eiSuffix = resolveEiSuffix(options, this.encodingWidth, () =>\n canonicalEncodingWidth(BigInt(this.items.length))\n );\n const decision = decideTaggedAppSeqRendering(\n options,\n this.appSeqSource,\n undefined,\n this.appSeqSourceFeatures\n );\n if (decision === 'adjusted')\n return adjustAppSeqIndicator(\n this.appSeqSource!,\n eiSuffix,\n options,\n this.appSeqInnerEnd,\n this.appSeqComments\n );\n try {\n return `${PREFIX_CRI}'${criItemsToUri(this.items)}'${eiSuffix}`;\n } catch {\n return super._toCDN(options, depth, path);\n }\n }\n}\n\n/**\n * tag(99, CRI array) whose toCDN() emits CRI'…' notation.\n * Falls back to generic tag notation if the content cannot be expressed as a URI.\n */\nexport class CborTaggedCriExt extends CborTag {\n constructor(content: CborArray) {\n super(TAG_CRI, content);\n }\n\n override _toCDN(\n options: ToCDNOptions | undefined,\n depth: number,\n path?: readonly unknown[]\n ): string {\n if (options?.appPrefix === false) return super._toCDN(options, depth, path);\n const decision = decideTaggedAppSeqRendering(\n options,\n this.appSeqSource,\n this.ednSource,\n this.appSeqSourceFeatures,\n this.appSeqEncodingEditsComplete\n );\n if (decision === 'verbatim') return this.appSeqSource!;\n if (decision === 'source')\n return adjustRawAppSeqSource(\n this.appSeqSource!,\n options,\n this.appSeqComments,\n this.appSeqEncodingEdits\n );\n // Like dt's content classes, cri's content (CborCriExt) re-switches to\n // its own app-string notation unless `appPrefix` is forced false here.\n if (decision === 'structural')\n return super._toCDN({ ...options, appPrefix: false }, depth, path);\n try {\n const inner = this.content as CborArray;\n // CRI'...'_N only encodes the tag's width. If the inner array uses a\n // non-canonical count header, fall back to generic tag notation to preserve it.\n if (inner.encodingWidth !== undefined)\n return super._toCDN(options, depth, path);\n const eiSuffix = resolveEiSuffix(options, this.encodingWidth, () =>\n canonicalEncodingWidth(TAG_CRI)\n );\n if (decision === 'adjusted')\n return adjustAppSeqIndicator(\n this.appSeqSource!,\n eiSuffix,\n options,\n this.appSeqInnerEnd,\n this.appSeqComments\n );\n return `${PREFIX_CRI_TAGGED}'${criItemsToUri(inner.items)}'${eiSuffix}`;\n } catch {\n return super._toCDN(options, depth, path);\n }\n }\n}\n\n// ─── Builder ──────────────────────────────────────────────────────────────────\n\nfunction stringFromAppSequence(items: CborItem[]): string {\n if (items.length !== 1)\n throw new SyntaxError('cri<<...>>: expected exactly one item');\n const item = items[0];\n if (item instanceof CborTextString) return item.value;\n if (item instanceof CborByteString) return utf8Strict.decode(item.value);\n throw new SyntaxError('cri<<...>>: expected a text string or byte string');\n}\n\nfunction buildCriValue(prefix: string, uri: string): CborItem {\n const criItems = uriToCriItems(uri);\n const arr = new CborCriExt(criItems);\n if (prefix === PREFIX_CRI_TAGGED) return new CborTaggedCriExt(arr);\n return arr;\n}\n\n// ─── Extension factory ────────────────────────────────────────────────────────\n\n/**\n * Create the cri/CRI CborExtension (§3.7 and §6.2.5 of draft-ietf-cbor-edn-literals-27).\n *\n * - `cri'uri'` → CborCriExt (bare CRI array, no CBOR tag)\n * - `CRI'uri'` → CborTaggedCriExt tag(99, CRI array)\n * - parseTag(99n, …) → CborTaggedCriExt (roundtrip from CBOR binary)\n */\nexport const cri: CborExtension = {\n appStringPrefixes: [PREFIX_CRI, PREFIX_CRI_TAGGED],\n tagNumbers: [TAG_CRI],\n // cri/CRI results always have a dedicated subclass (CborCriExt /\n // CborTaggedCriExt) that regenerates its notation by default; 'optional'\n // preserves the source spelling only when ToCDNOptions.preserveAppPrefix\n // is set, without changing the returned node's class/identity.\n preserveAppSeqSource: 'optional',\n\n parseAppString(prefix: string, content: string): CborItem {\n return buildCriValue(prefix, content);\n },\n\n parseAppSequence(prefix: string, items: CborItem[]): CborItem {\n return buildCriValue(prefix, stringFromAppSequence(items));\n },\n\n parseTag(tag: bigint, value: CborItem): CborItem | undefined {\n if (tag !== TAG_CRI) return undefined;\n if (!(value instanceof CborArray)) return undefined;\n const inner = new CborCriExt(value.items, {\n indefiniteLength: value.indefiniteLength,\n encodingWidth: value.encodingWidth,\n });\n inner.start = value.start;\n inner.end = value.end;\n return new CborTaggedCriExt(inner);\n },\n};\n\nexport default cri;\n","/**\n * Built-in bignum extension (RFC 8949 §3.4.3).\n *\n * Intercepts tag 2 (unsigned bignum) and tag 3 (negative bignum) during\n * fromCBOR() and fromCDN() so that out-of-range values are decoded as\n * CborBigUint / CborBigNint rather than plain CborTag nodes.\n *\n * In-range values (those that fit in uint64 / nint64) are left as plain\n * CborTag so that non-canonical bignum encodings of small integers don't\n * silently change behaviour.\n */\n\nimport type { CborExtension } from './types';\nimport type { CborItem } from '../ast/CborItem';\nimport { CborByteString } from '../ast/CborByteString';\nimport {\n CborBigUint,\n CborBigNint,\n bytesToBigint,\n BIGNUM_UINT_TAG,\n BIGNUM_NINT_TAG,\n} from '../ast/CborBignum';\n\nconst UINT64_MAX = 0xffff_ffff_ffff_ffffn;\nconst NINT64_MIN = -(UINT64_MAX + 1n);\n\nexport const bignum: CborExtension = {\n tagNumbers: [BIGNUM_UINT_TAG, BIGNUM_NINT_TAG],\n\n parseTag(tag: bigint, value: CborItem): CborItem | undefined {\n if (!(value instanceof CborByteString)) return undefined;\n\n if (tag === BIGNUM_UINT_TAG) {\n const n = bytesToBigint(value.value);\n if (n > UINT64_MAX) return new CborBigUint(n);\n return undefined; // fits in uint64 — leave as plain CborTag\n }\n\n if (tag === BIGNUM_NINT_TAG) {\n const n = -1n - bytesToBigint(value.value);\n if (n < NINT64_MIN) return new CborBigNint(n);\n return undefined; // fits in nint64 — leave as plain CborTag\n }\n\n return undefined;\n },\n};\n\nexport default bignum;\n","import type { FromCBOROptions, DecodeWarning, CborExtension } from '../types';\nimport type { CborItem } from '../ast/CborItem';\nimport { resolveBuiltinExtensions } from '../extensions/builtins';\nimport { CborUint } from '../ast/CborUint';\nimport { CborNint } from '../ast/CborNint';\nimport { CborByteString } from '../ast/CborByteString';\nimport { CborIndefiniteByteString } from '../ast/CborIndefiniteByteString';\nimport { CborTextString } from '../ast/CborTextString';\nimport { CborIndefiniteTextString } from '../ast/CborIndefiniteTextString';\nimport { CborArray } from '../ast/CborArray';\nimport { CborMap } from '../ast/CborMap';\nimport { CborTag } from '../ast/CborTag';\nimport { CborFloat } from '../ast/CborFloat';\nimport { CborSimple } from '../ast/CborSimple';\nimport { float16BitsToFloat64 } from '../utils/float16';\nimport { bytesToHex } from '../utils/hex';\nimport {\n MT_UINT,\n MT_NINT,\n MT_BYTES,\n MT_TEXT,\n MT_ARRAY,\n MT_MAP,\n MT_TAG,\n MT_SIMPLE,\n AI_1BYTE,\n AI_2BYTE,\n AI_4BYTE,\n AI_8BYTE,\n AI_INDEFINITE,\n BREAK_CODE,\n} from './constants';\nimport type { EncodingWidth } from './encode';\n\n// ─── Helpers ──────────────────────────────────────────────────────────────────\n\n/**\n * Returns a non-canonical EncodingWidth when the CBOR additional-info byte\n * uses more bytes than the minimum needed for `value`. Returns undefined for\n * canonical (minimum-width) encodings so they round-trip without an _N marker.\n *\n * Canonical ranges: immediate 0–23, 1-byte 24–255, 2-byte 256–65535,\n * 4-byte 65536–4294967295, 8-byte ≥ 4294967296.\n */\nfunction aiToNonCanonicalEW(\n ai: number,\n value: bigint\n): EncodingWidth | undefined {\n if (ai === AI_1BYTE && value <= 23n) return 0;\n if (ai === AI_2BYTE && value <= 0xffn) return 1;\n if (ai === AI_4BYTE && value <= 0xffffn) return 2;\n if (ai === AI_8BYTE && value <= 0xffff_ffffn) return 3;\n return undefined;\n}\n\n/**\n * Number twin of {@link aiToNonCanonicalEW}, for the length/count arguments\n * read by {@link readLength}. Values ≥ 2^53 arrive rounded, but they are far\n * above every threshold here, so the result is unaffected.\n */\nfunction aiToNonCanonicalEWLen(\n ai: number,\n value: number\n): EncodingWidth | undefined {\n if (ai === AI_1BYTE && value <= 23) return 0;\n if (ai === AI_2BYTE && value <= 0xff) return 1;\n if (ai === AI_4BYTE && value <= 0xffff) return 2;\n if (ai === AI_8BYTE && value <= 0xffff_ffff) return 3;\n return undefined;\n}\n\nconst textDecoderStrict = new TextDecoder('utf-8', {\n fatal: true,\n ignoreBOM: true,\n});\n\nconst textDecoderLenient = new TextDecoder('utf-8', {\n fatal: false,\n ignoreBOM: true,\n});\n\nfunction decodeError(msg: string): never {\n throw new Error(`CBOR decode error: ${msg}`);\n}\n\n/**\n * Emit a CBOR validity violation warning and, unless `strict: false`, throw.\n * Returns the created `DecodeWarning` (only reachable in non-strict mode).\n * For truly malformed data that cannot be recovered, use `decodeError` instead.\n */\nfunction strictViolation(\n msg: string,\n offset: number,\n options: FromCBOROptions | undefined\n): DecodeWarning {\n const warning: DecodeWarning = { message: msg, offset };\n if (options?.onWarning) {\n options.onWarning(warning);\n } else if (!options?.silent) {\n console.warn(`CBOR strict violation at offset ${offset}: ${msg}`);\n }\n if (options?.strict !== false) {\n throw new Error(`CBOR decode error: ${msg}`);\n }\n return warning;\n}\n\nfunction addWarning(node: CborItem, warning: DecodeWarning): void {\n node.warnings ??= [];\n node.warnings.push(warning);\n}\n\n/**\n * Return a data-model fingerprint for a CBOR map key.\n *\n * The fingerprint is designed so that two keys are equal if and only if they\n * represent the same CBOR data-model value, regardless of the encoding form:\n * - Integers: compared by numeric value (width differences ignored)\n * - Text strings: compared by Unicode string content (definite vs indefinite ignored)\n * - Byte strings: compared by raw byte sequence (definite vs indefinite ignored)\n * - Floats: compared by numeric value (precision ignored; all NaN treated equal)\n * - Simple values: compared by simple value number\n * - Arrays/maps/tags: recursively fingerprinted\n *\n * Implemented as two functions: `fingerprintKeyVal` builds a nested-array\n * structure (no pre-serialised strings), and `fingerprintKey` serialises it\n * with a single JSON.stringify call. Keeping recursion in the array domain\n * avoids the exponential character-escaping blowup that occurs when\n * pre-serialised JSON strings are embedded inside further JSON.stringify calls.\n */\nfunction fingerprintKeyVal(key: CborItem): unknown {\n if (key instanceof CborUint) return ['u', String(key.value)];\n if (key instanceof CborNint) return ['n', String(key.value)];\n if (key instanceof CborTextString) return ['t', key.value];\n if (key instanceof CborIndefiniteTextString)\n return ['t', key.chunks.map((c) => c.value).join('')];\n if (key instanceof CborByteString) return ['b', bytesToHex(key.value)];\n if (key instanceof CborIndefiniteByteString) {\n let h = '';\n for (const chunk of key.chunks) h += bytesToHex(chunk.value);\n return ['b', h];\n }\n if (key instanceof CborFloat) {\n // Use String() for all float cases: avoids JSON.stringify silently converting\n // NaN and ±Infinity to null, and -0 to \"0\".\n if (isNaN(key.value)) return ['f', 'NaN'];\n if (Object.is(key.value, -0)) return ['f', '-0'];\n return ['f', String(key.value)];\n }\n if (key instanceof CborSimple) return ['s', key.value];\n if (key instanceof CborArray) return ['A', key.items.map(fingerprintKeyVal)];\n if (key instanceof CborMap) {\n const pairs = key.entries.map(([k, v]) => [\n fingerprintKeyVal(k),\n fingerprintKeyVal(v),\n ]);\n // 0/1 entries: nothing to sort — and skipping the stringify here keeps\n // deeply-nested single-entry map chains linear instead of quadratic.\n if (pairs.length <= 1) return ['M', pairs];\n // Sort by key fingerprint so that maps with the same entries in different\n // insertion order fingerprint identically (RFC 8949 data model: unordered).\n // Decorate-sort-undecorate: stringify each key once, not per comparison.\n const decorated = pairs.map(\n (pair) => [JSON.stringify(pair[0]), pair] as const\n );\n decorated.sort((a, b) => (a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0));\n return ['M', decorated.map((d) => d[1])];\n }\n if (key instanceof CborTag)\n return ['G', String(key.tag), fingerprintKeyVal(key.content)];\n // Fallback for any remaining AST node (e.g. CborEmbeddedCBOR): canonical CBOR bytes.\n return ['c', bytesToHex(key.toCBOR())];\n}\n\nfunction fingerprintKey(key: CborItem): string {\n // Fast paths for scalar keys (the overwhelmingly common case) — avoids a\n // throwaway array + JSON.stringify per key. JSON fingerprints always start\n // with '[', so these single-letter prefixes cannot collide with them, and\n // each fast-path prefix is distinct so they cannot collide with each other.\n if (key instanceof CborUint) return 'u' + key.value;\n if (key instanceof CborNint) return 'n' + key.value;\n if (key instanceof CborTextString) return 't' + key.value;\n if (key instanceof CborIndefiniteTextString) {\n let s = 't';\n for (const c of key.chunks) s += c.value;\n return s;\n }\n if (key instanceof CborByteString) return 'b' + bytesToHex(key.value);\n if (key instanceof CborIndefiniteByteString) {\n let s = 'b';\n for (const chunk of key.chunks) s += bytesToHex(chunk.value);\n return s;\n }\n if (key instanceof CborFloat) {\n if (isNaN(key.value)) return 'fNaN';\n if (Object.is(key.value, -0)) return 'f-0';\n return 'f' + key.value;\n }\n if (key instanceof CborSimple) return 's' + key.value;\n return JSON.stringify(fingerprintKeyVal(key));\n}\n\n/**\n * Pre-computed BigInt values for CBOR inline arguments 0–23.\n * readArgument() is called for every data item header; avoiding BigInt()\n * construction for the common small-integer case saves measurable time.\n */\nconst SMALL_BIGINTS: readonly bigint[] = Array.from({ length: 24 }, (_, i) =>\n BigInt(i)\n);\n\n/**\n * Default resolved builtins (no `builtinExtensions` override) filtered to\n * those with a parseTag hook, cached after first use. Lazy (not module-level)\n * because cbordata.ts imports decoder.ts, forming a cycle that leaves the\n * builtins module's exports undefined at module init time.\n */\nlet _defaultTagExts: readonly CborExtension[] | undefined;\nfunction getBuiltinTagExts(\n builtinExtensions: CborExtension[] | false | undefined\n): readonly CborExtension[] {\n if (builtinExtensions === undefined)\n return (_defaultTagExts ??= resolveBuiltinExtensions(undefined).filter(\n (ext) => ext.parseTag !== undefined\n ));\n return resolveBuiltinExtensions(builtinExtensions).filter(\n (ext) => ext.parseTag !== undefined\n );\n}\n\n/**\n * Decode a short (< 64 byte) pure-ASCII UTF-8 sequence without invoking\n * TextDecoder. Returns undefined if any byte is >= 0x80 (non-ASCII).\n * Only called for length < 64; longer strings use TextDecoder directly to\n * avoid the double-scan cost of failing mid-way through a large buffer.\n */\nfunction tryDecodeAscii(bytes: Uint8Array, length: number): string | undefined {\n for (let i = 0; i < length; i++) {\n if (bytes[i] >= 0x80) return undefined;\n }\n // eslint-disable-next-line prefer-spread\n return String.fromCharCode.apply(null, bytes as unknown as number[]);\n}\n\n/**\n * Read the CBOR \"argument\" that follows the initial byte.\n * For ai 0–23 the argument is inline; for 24–27 it occupies 1/2/4/8 bytes.\n */\nfunction readArgument(\n view: DataView,\n offset: number,\n ai: number\n): { value: bigint; nextOffset: number } {\n if (ai <= 23) {\n return { value: SMALL_BIGINTS[ai], nextOffset: offset };\n }\n switch (ai) {\n case AI_1BYTE:\n if (offset + 1 > view.byteLength) decodeError('unexpected end of input');\n return { value: BigInt(view.getUint8(offset)), nextOffset: offset + 1 };\n case AI_2BYTE:\n if (offset + 2 > view.byteLength) decodeError('unexpected end of input');\n return {\n value: BigInt(view.getUint16(offset, false)),\n nextOffset: offset + 2,\n };\n case AI_4BYTE:\n if (offset + 4 > view.byteLength) decodeError('unexpected end of input');\n return {\n value: BigInt(view.getUint32(offset, false)),\n nextOffset: offset + 4,\n };\n case AI_8BYTE:\n if (offset + 8 > view.byteLength) decodeError('unexpected end of input');\n return {\n value: view.getBigUint64(offset, false),\n nextOffset: offset + 8,\n };\n default:\n decodeError(`reserved additional info value: ${ai}`);\n }\n}\n\n/**\n * Read the CBOR argument as a JS number — used for the length/count of major\n * types 2–5, where {@link readArgument}'s bigint would immediately be\n * converted back via Number(). Avoids a BigInt allocation per non-immediate\n * header on the decode hot path.\n *\n * An 8-byte argument ≥ 2^53 loses precision exactly as Number(bigint) would\n * (both round to nearest double); such lengths always exceed any real input,\n * so the subsequent bounds check fails identically either way.\n */\nfunction readLength(\n view: DataView,\n offset: number,\n ai: number\n): { value: number; nextOffset: number } {\n if (ai <= 23) {\n return { value: ai, nextOffset: offset };\n }\n switch (ai) {\n case AI_1BYTE:\n if (offset + 1 > view.byteLength) decodeError('unexpected end of input');\n return { value: view.getUint8(offset), nextOffset: offset + 1 };\n case AI_2BYTE:\n if (offset + 2 > view.byteLength) decodeError('unexpected end of input');\n return { value: view.getUint16(offset, false), nextOffset: offset + 2 };\n case AI_4BYTE:\n if (offset + 4 > view.byteLength) decodeError('unexpected end of input');\n return { value: view.getUint32(offset, false), nextOffset: offset + 4 };\n case AI_8BYTE: {\n if (offset + 8 > view.byteLength) decodeError('unexpected end of input');\n const hi = view.getUint32(offset, false);\n const lo = view.getUint32(offset + 4, false);\n return { value: hi * 0x1_0000_0000 + lo, nextOffset: offset + 8 };\n }\n default:\n decodeError(`reserved additional info value: ${ai}`);\n }\n}\n\n// ─── Core recursive decoder ───────────────────────────────────────────────────\n\ntype DecodeResult = { value: CborItem; nextOffset: number };\n\n/**\n * Decode the chunks of an indefinite-length string (major type 2 or 3) up to\n * and including the \"break\" code. `what` is used in error messages and\n * `isChunk` enforces that every chunk is a definite string of that type.\n */\nfunction decodeIndefiniteChunks<T extends CborItem>(\n view: DataView,\n offset: number,\n options: FromCBOROptions | undefined,\n tagExts: readonly CborExtension[],\n what: 'byte string' | 'text string',\n isChunk: (item: CborItem) => item is T\n): { chunks: T[]; nextOffset: number } {\n const chunks: T[] = [];\n let pos = offset;\n while (true) {\n if (pos >= view.byteLength)\n decodeError(`unexpected end of indefinite ${what}`);\n if (view.getUint8(pos) === BREAK_CODE) {\n pos++;\n break;\n }\n const result = decodeItem(view, pos, options, tagExts);\n if (!isChunk(result.value))\n decodeError(`indefinite-length ${what} chunk must be a definite ${what}`);\n chunks.push(result.value);\n pos = result.nextOffset;\n }\n return { chunks, nextOffset: pos };\n}\n\n/**\n * Record a duplicate-key strict violation if `key` was already seen.\n * Mutates `seenKeys` and appends any non-strict-mode warning to `warnings`.\n */\nfunction checkDuplicateKey(\n key: CborItem,\n seenKeys: Set<string>,\n warnings: DecodeWarning[],\n options: FromCBOROptions | undefined\n): void {\n const fp = fingerprintKey(key);\n if (seenKeys.has(fp)) {\n warnings.push(\n strictViolation(\n `duplicate map key at offset ${key.start}`,\n key.start!,\n options\n )\n );\n }\n seenKeys.add(fp);\n}\n\nfunction decodeItem(\n view: DataView,\n offset: number,\n options: FromCBOROptions | undefined,\n tagExts: readonly CborExtension[]\n): DecodeResult {\n const startOffset = offset;\n const result = decodeItemInner(view, offset, options, tagExts);\n result.value.start = startOffset;\n result.value.end = result.nextOffset;\n return result;\n}\n\n/**\n * Copy a float's encoded payload bytes out of the input, so NaN payloads\n * survive a decode → encode round-trip (see `CborFloat.rawBits`).\n */\nfunction floatPayloadBytes(\n view: DataView,\n offset: number,\n length: number\n): Uint8Array {\n return new Uint8Array(view.buffer, view.byteOffset + offset, length).slice();\n}\n\nfunction decodeItemInner(\n view: DataView,\n offset: number,\n options: FromCBOROptions | undefined,\n tagExts: readonly CborExtension[]\n): DecodeResult {\n if (offset >= view.byteLength) decodeError('unexpected end of input');\n\n const initialByte = view.getUint8(offset++);\n const mt = initialByte >> 5;\n const ai = initialByte & 0x1f;\n\n switch (mt) {\n // ── Major Type 0: unsigned integer ────────────────────────────────────────\n case MT_UINT: {\n const { value, nextOffset } = readArgument(view, offset, ai);\n const encodingWidth = aiToNonCanonicalEW(ai, value);\n return { value: new CborUint(value, { encodingWidth }), nextOffset };\n }\n\n // ── Major Type 1: negative integer ───────────────────────────────────────\n case MT_NINT: {\n const { value, nextOffset } = readArgument(view, offset, ai);\n const encodingWidth = aiToNonCanonicalEW(ai, value);\n // CBOR encodes negative integers as -1 - argument\n return {\n value: new CborNint(-1n - value, { encodingWidth }),\n nextOffset,\n };\n }\n\n // ── Major Type 2: byte string ─────────────────────────────────────────────\n case MT_BYTES: {\n if (ai === AI_INDEFINITE) {\n const { chunks, nextOffset } = decodeIndefiniteChunks(\n view,\n offset,\n options,\n tagExts,\n 'byte string',\n (item): item is CborByteString => item instanceof CborByteString\n );\n return { value: new CborIndefiniteByteString(chunks), nextOffset };\n }\n const { value: length, nextOffset: dataOffset } = readLength(\n view,\n offset,\n ai\n );\n const encodingWidth = aiToNonCanonicalEWLen(ai, length);\n if (dataOffset + length > view.byteLength)\n decodeError('byte string extends beyond input');\n const bytes = new Uint8Array(\n view.buffer,\n view.byteOffset + dataOffset,\n length\n );\n return {\n value: new CborByteString(bytes.slice(), { encodingWidth }),\n nextOffset: dataOffset + length,\n };\n }\n\n // ── Major Type 3: text string ─────────────────────────────────────────────\n case MT_TEXT: {\n if (ai === AI_INDEFINITE) {\n const { chunks, nextOffset } = decodeIndefiniteChunks(\n view,\n offset,\n options,\n tagExts,\n 'text string',\n (item): item is CborTextString => item instanceof CborTextString\n );\n return { value: new CborIndefiniteTextString(chunks), nextOffset };\n }\n const { value: length, nextOffset: dataOffset } = readLength(\n view,\n offset,\n ai\n );\n const encodingWidth = aiToNonCanonicalEWLen(ai, length);\n if (dataOffset + length > view.byteLength)\n decodeError('text string extends beyond input');\n const bytes = new Uint8Array(\n view.buffer,\n view.byteOffset + dataOffset,\n length\n );\n let text: string;\n let utf8Warning: DecodeWarning | undefined;\n // Fast path: short pure-ASCII strings (map keys, identifiers) avoid\n // TextDecoder overhead. Capped at 64 bytes to prevent double-scanning\n // long buffers that turn out to contain non-ASCII bytes.\n const asciiText = length < 64 ? tryDecodeAscii(bytes, length) : undefined;\n if (asciiText !== undefined) {\n text = asciiText;\n } else {\n try {\n text = textDecoderStrict.decode(bytes);\n } catch {\n utf8Warning = strictViolation(\n 'invalid UTF-8 sequence in text string',\n dataOffset,\n options\n );\n // Only reached in non-strict mode — decode with replacement characters\n text = textDecoderLenient.decode(bytes);\n }\n }\n const textNode = new CborTextString(text, { encodingWidth });\n if (utf8Warning) addWarning(textNode, utf8Warning);\n return { value: textNode, nextOffset: dataOffset + length };\n }\n\n // ── Major Type 4: array ───────────────────────────────────────────────────\n case MT_ARRAY: {\n if (ai === AI_INDEFINITE) {\n const items: CborItem[] = [];\n let pos = offset;\n while (true) {\n if (pos >= view.byteLength)\n decodeError('unexpected end of indefinite array');\n if (view.getUint8(pos) === BREAK_CODE) {\n pos++;\n break;\n }\n const result = decodeItem(view, pos, options, tagExts);\n items.push(result.value);\n pos = result.nextOffset;\n }\n return {\n value: new CborArray(items, { indefiniteLength: true }),\n nextOffset: pos,\n };\n }\n const { value: length, nextOffset: itemsStart } = readLength(\n view,\n offset,\n ai\n );\n const encodingWidth = aiToNonCanonicalEWLen(ai, length);\n const items: CborItem[] = [];\n let pos = itemsStart;\n for (let i = 0; i < length; i++) {\n const result = decodeItem(view, pos, options, tagExts);\n items.push(result.value);\n pos = result.nextOffset;\n }\n return {\n value: new CborArray(items, { encodingWidth }),\n nextOffset: pos,\n };\n }\n\n // ── Major Type 5: map ─────────────────────────────────────────────────────\n case MT_MAP: {\n if (ai === AI_INDEFINITE) {\n const entries: [CborItem, CborItem][] = [];\n const seenKeysIndef = new Set<string>();\n const indefMapWarnings: DecodeWarning[] = [];\n let pos = offset;\n while (true) {\n if (pos >= view.byteLength)\n decodeError('unexpected end of indefinite map');\n if (view.getUint8(pos) === BREAK_CODE) {\n pos++;\n break;\n }\n const keyResult = decodeItem(view, pos, options, tagExts);\n checkDuplicateKey(\n keyResult.value,\n seenKeysIndef,\n indefMapWarnings,\n options\n );\n pos = keyResult.nextOffset;\n const valResult = decodeItem(view, pos, options, tagExts);\n pos = valResult.nextOffset;\n entries.push([keyResult.value, valResult.value]);\n }\n const indefMapNode = new CborMap(entries, { indefiniteLength: true });\n for (const w of indefMapWarnings) addWarning(indefMapNode, w);\n return { value: indefMapNode, nextOffset: pos };\n }\n const { value: length, nextOffset: entriesStart } = readLength(\n view,\n offset,\n ai\n );\n const encodingWidth = aiToNonCanonicalEWLen(ai, length);\n const entries: [CborItem, CborItem][] = [];\n const seenKeys = new Set<string>();\n const mapWarnings: DecodeWarning[] = [];\n let pos = entriesStart;\n for (let i = 0; i < length; i++) {\n const keyResult = decodeItem(view, pos, options, tagExts);\n checkDuplicateKey(keyResult.value, seenKeys, mapWarnings, options);\n pos = keyResult.nextOffset;\n const valResult = decodeItem(view, pos, options, tagExts);\n pos = valResult.nextOffset;\n entries.push([keyResult.value, valResult.value]);\n }\n const mapNode = new CborMap(entries, { encodingWidth });\n for (const w of mapWarnings) addWarning(mapNode, w);\n return { value: mapNode, nextOffset: pos };\n }\n\n // ── Major Type 6: tagged item ─────────────────────────────────────────────\n case MT_TAG: {\n if (ai === AI_INDEFINITE)\n decodeError('tags cannot use indefinite-length encoding');\n const { value: tagNum, nextOffset: contentStart } = readArgument(\n view,\n offset,\n ai\n );\n const tagEncodingWidth = aiToNonCanonicalEW(ai, tagNum);\n const contentResult = decodeItem(view, contentStart, options, tagExts);\n for (const ext of tagExts) {\n const result = ext.parseTag!(tagNum, contentResult.value, options);\n if (result !== undefined) {\n if (result instanceof CborTag && tagEncodingWidth !== undefined)\n result.encodingWidth = tagEncodingWidth;\n return { value: result, nextOffset: contentResult.nextOffset };\n }\n }\n return {\n value: new CborTag(tagNum, contentResult.value, {\n encodingWidth: tagEncodingWidth,\n }),\n nextOffset: contentResult.nextOffset,\n };\n }\n\n // ── Major Type 7: float / simple value ────────────────────────────────────\n case MT_SIMPLE: {\n // ai 0–19: simple value encoded inline\n if (ai <= 19) {\n return { value: new CborSimple(ai), nextOffset: offset };\n }\n // ai 20–23: false / true / null / undefined\n // Use new instances (not the static singletons) so that decodeItem() can\n // safely set byte-offset properties without corrupting any concurrently\n // live CDN AST that shares the same singleton.\n if (ai === 20) return { value: new CborSimple(20), nextOffset: offset };\n if (ai === 21) return { value: new CborSimple(21), nextOffset: offset };\n if (ai === 22) return { value: new CborSimple(22), nextOffset: offset };\n if (ai === 23) return { value: new CborSimple(23), nextOffset: offset };\n\n // ai 24: simple value in next byte (value must be >= 32)\n if (ai === AI_1BYTE) {\n if (offset + 1 > view.byteLength)\n decodeError('unexpected end of input');\n const simpleVal = view.getUint8(offset);\n if (simpleVal < 32) {\n const w = strictViolation(\n `simple value ${simpleVal} must be encoded in initial byte (0–31 reserved for extended encoding)`,\n offset - 1,\n options\n );\n // Only reached in non-strict mode — decode the value as-is\n const simpleNode = new CborSimple(simpleVal);\n addWarning(simpleNode, w);\n return { value: simpleNode, nextOffset: offset + 1 };\n }\n return { value: new CborSimple(simpleVal), nextOffset: offset + 1 };\n }\n\n // ai 25: half-precision float\n if (ai === AI_2BYTE) {\n if (offset + 2 > view.byteLength)\n decodeError('unexpected end of input');\n const bits = view.getUint16(offset, false);\n const value = float16BitsToFloat64(bits);\n return {\n value: new CborFloat(value, {\n precision: 'half',\n rawBits: Number.isNaN(value)\n ? floatPayloadBytes(view, offset, 2)\n : undefined,\n }),\n nextOffset: offset + 2,\n };\n }\n\n // ai 26: single-precision float\n if (ai === AI_4BYTE) {\n if (offset + 4 > view.byteLength)\n decodeError('unexpected end of input');\n const value = view.getFloat32(offset, false);\n return {\n value: new CborFloat(value, {\n precision: 'single',\n rawBits: Number.isNaN(value)\n ? floatPayloadBytes(view, offset, 4)\n : undefined,\n }),\n nextOffset: offset + 4,\n };\n }\n\n // ai 27: double-precision float\n if (ai === AI_8BYTE) {\n if (offset + 8 > view.byteLength)\n decodeError('unexpected end of input');\n const value = view.getFloat64(offset, false);\n return {\n value: new CborFloat(value, {\n precision: 'double',\n rawBits: Number.isNaN(value)\n ? floatPayloadBytes(view, offset, 8)\n : undefined,\n }),\n nextOffset: offset + 8,\n };\n }\n\n // ai 28–30: reserved\n if (ai < AI_INDEFINITE) {\n decodeError(`reserved additional info value in major type 7: ${ai}`);\n }\n\n // ai 31: break code — not valid at item level\n return decodeError(\n 'unexpected break code outside indefinite-length item'\n );\n }\n }\n // unreachable: all major types 0–7 are handled above\n return decodeError(`unknown major type: ${mt}`);\n}\n\n// ─── Public API ───────────────────────────────────────────────────────────────\n\nfunction toInputBytes(data: ArrayBufferView | ArrayBufferLike): Uint8Array {\n if (\n data instanceof ArrayBuffer ||\n (typeof SharedArrayBuffer !== 'undefined' &&\n data instanceof SharedArrayBuffer)\n ) {\n return new Uint8Array(data);\n }\n if (ArrayBuffer.isView(data)) {\n return new Uint8Array(data.buffer, data.byteOffset, data.byteLength);\n }\n throw new TypeError('expected ArrayBufferView or ArrayBufferLike');\n}\n\n/**\n * Decode a CBOR-encoded byte array into a CborItem AST node.\n *\n * Accepts any `ArrayBufferView` (e.g. `Uint8Array`, `DataView`) or\n * `ArrayBufferLike` (e.g. `ArrayBuffer`, `SharedArrayBuffer`).\n *\n * Throws if the input is not well-formed CBOR or contains trailing bytes.\n */\nexport function decodeCBOR(\n input: ArrayBufferView | ArrayBufferLike,\n options?: FromCBOROptions\n): CborItem {\n const bytes = toInputBytes(input);\n const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);\n const offset = options?.offset ?? 0;\n if (!Number.isInteger(offset) || offset < 0 || offset > view.byteLength) {\n throw new RangeError(\n `CBOR decode offset must be an integer between 0 and ${view.byteLength}`\n );\n }\n // Build the tag-extension list once per decode call.\n // For the common case (no user extensions) reuse the pre-filtered module-level\n // constant to avoid a spread + filter allocation on every decode call.\n const builtinTagExts = getBuiltinTagExts(options?.builtinExtensions);\n const tagExts = options?.extensions?.length\n ? [\n ...options.extensions.filter((e) => e.parseTag !== undefined),\n ...builtinTagExts,\n ]\n : builtinTagExts;\n const { value, nextOffset } = decodeItem(view, offset, options, tagExts);\n if (!options?.allowTrailing && nextOffset !== view.byteLength) {\n const w = strictViolation(\n `${view.byteLength - nextOffset} trailing byte(s) after end of CBOR item`,\n nextOffset,\n options\n );\n // Only reached in non-strict mode (strictViolation throws in strict mode).\n addWarning(value, w);\n // Scan the trailing bytes so that truly malformed trailing items\n // (e.g. truncated input, reserved additional-info values) still throw,\n // even though the leading item decoded successfully.\n const scanOpts: FromCBOROptions = { strict: false, silent: true };\n let pos = nextOffset;\n while (pos < view.byteLength) {\n ({ nextOffset: pos } = decodeItem(view, pos, scanOpts, tagExts));\n }\n }\n return value;\n}\n","/**\n * Built-in embedded CBOR extension (RFC 8949 §3.4.5.1).\n *\n * Intercepts tag 24 during fromCBOR() so that the byte string content is\n * decoded as a CBOR data item and represented as CborEmbeddedCBOR. This\n * allows toCDN() to render the value as 24(<<item>>) instead of 24(h'...').\n *\n * If the byte string is not valid CBOR (or has trailing bytes), the extension\n * returns undefined and falls back to the plain CborTag representation.\n */\n\nimport type { CborExtension } from './types';\nimport type { CborItem } from '../ast/CborItem';\nimport type { DecodeWarning, FromCBOROptions } from '../types';\nimport { CborByteString } from '../ast/CborByteString';\nimport { CborEmbeddedCBOR } from '../ast/CborEmbeddedCBOR';\nimport { CborTag } from '../ast/CborTag';\nimport { decodeCBOR } from '../cbor/decoder';\n\nexport const TAG_CBOR_DATA = 24n;\n\nconst cbordata: CborExtension = {\n tagNumbers: [TAG_CBOR_DATA],\n\n parseTag(\n tag: bigint,\n value: CborItem,\n options?: FromCBOROptions\n ): CborItem | undefined {\n if (tag !== TAG_CBOR_DATA) return undefined;\n if (!(value instanceof CborByteString)) return undefined;\n // The embedded bytes are decoded as a fresh buffer starting at offset 0,\n // so any offset reported by the inner decode (via onWarning, or a thrown\n // error) is relative to that buffer and must be translated back to the\n // payload's actual position in the outer input before it reaches callers.\n const payloadStart = (value.end ?? value.value.length) - value.value.length;\n // Forward strict/silent/builtinExtensions into the inner decode, but\n // reset offset and allowTrailing since the embedded bytes start at 0.\n // Forwarding builtinExtensions matters for the allowlist story: a\n // disabled built-in (e.g. dt via builtinExtensions: false) must not\n // re-enable itself for tags found inside embedded CBOR.\n const innerOptions: FromCBOROptions | undefined = options\n ? {\n extensions: options.extensions,\n builtinExtensions: options.builtinExtensions,\n strict: options.strict,\n onWarning: options.onWarning\n ? (w: DecodeWarning) =>\n options.onWarning!({ ...w, offset: w.offset + payloadStart })\n : undefined,\n silent: options.silent,\n }\n : undefined;\n try {\n const decoded = decodeCBOR(value.value, innerOptions);\n return new CborTag(\n TAG_CBOR_DATA,\n new CborEmbeddedCBOR([decoded], { encodingWidth: value.encodingWidth })\n );\n } catch (e) {\n if (innerOptions?.strict !== false) {\n // In strict mode, propagate inner violations to the outer decode.\n throw e;\n }\n // In non-strict mode, fall back to a plain CborTag, but still surface\n // the violation via onWarning — otherwise callers that rely on it to\n // detect problems (e.g. CBOR.validate()) would see no signal at all\n // for tag 24 content that isn't valid CBOR.\n const message = `tag 24 content is not valid CBOR: ${\n e instanceof Error ? e.message : String(e)\n }`;\n const warning: DecodeWarning = { message, offset: payloadStart };\n if (options?.onWarning) {\n options.onWarning(warning);\n } else if (!options?.silent) {\n console.warn(\n `CBOR strict violation at offset ${warning.offset}: ${message}`\n );\n }\n return undefined;\n }\n },\n};\n\nexport default cbordata;\n","/**\n * Core decode support for the CPA888 ellipsis (elision) tag (§5.2 of\n * draft-ietf-cbor-edn-literals-27).\n *\n * Intercepts tag 888 during fromCBOR() and integer-tagged EDN parsing so\n * that elided items decode back to CborEllipsis and round-trip as `...`\n * notation instead of `888(null)` / `888([...])`.\n *\n * Ellipsis is core EDN syntax (the CDN parser handles `...` directly, not\n * via an app-string extension), so this lives in CORE_EXTENSIONS and is not\n * affected by the `builtinExtensions` option.\n */\n\nimport type { CborExtension } from './types';\nimport type { CborItem } from '../ast/CborItem';\nimport { CborEllipsis, CPA888_TAG } from '../ast/CborEllipsis';\nimport { CborArray } from '../ast/CborArray';\nimport { CborSimple } from '../ast/CborSimple';\nimport { CborTextString } from '../ast/CborTextString';\nimport { CborByteString } from '../ast/CborByteString';\n\n/** Subtree elision marker: 888(null), already reconstructed bottom-up. */\nfunction isSubtreeEllipsis(item: CborItem): boolean {\n return item instanceof CborEllipsis && !(item.content instanceof CborArray);\n}\n\n/**\n * A well-formed string-elision array: string fragments of a single kind\n * (all text or all byte) strictly alternating with at least one subtree\n * ellipsis (`h'...'` yields the single-item form `888([888(null)])`).\n * Any other shape stays a plain CborTag — a lenient reconstruction (e.g. of\n * adjacent fragments or adjacent ellipses) would not re-parse to the same\n * data item.\n */\nfunction isElisionArray(items: readonly CborItem[]): boolean {\n let text = false;\n let byte = false;\n let sawEllipsis = false;\n let prevWasEllipsis: boolean | undefined;\n for (const item of items) {\n let isEllipsis: boolean;\n if (isSubtreeEllipsis(item)) {\n isEllipsis = true;\n sawEllipsis = true;\n } else if (item instanceof CborTextString) {\n isEllipsis = false;\n text = true;\n } else if (item instanceof CborByteString) {\n isEllipsis = false;\n byte = true;\n } else {\n return false;\n }\n if (isEllipsis === prevWasEllipsis) return false; // no strict alternation\n prevWasEllipsis = isEllipsis;\n }\n return sawEllipsis && !(text && byte); // fragments must be homogeneous\n}\n\nexport const ellipsis: CborExtension = {\n tagNumbers: [CPA888_TAG],\n\n parseTag(tag: bigint, value: CborItem): CborItem | undefined {\n if (tag !== CPA888_TAG) return undefined;\n if (value instanceof CborSimple && value.value === 22)\n return new CborEllipsis();\n if (value instanceof CborArray && isElisionArray(value.items))\n return new CborEllipsis(value.items);\n return undefined;\n },\n};\n\nexport default ellipsis;\n","/**\n * `t1'...'` / `t1<<...>>` and `b1'...'` / `b1<<...>>` string-concatenation\n * app-extensions (§3.5 of draft-ietf-cbor-edn-literals-27).\n *\n * Builds a single (text or byte) string by joining the bytes of the (text or\n * byte) string arguments from left to right:\n * - `t1` produces a text string; the joined bytes must be valid UTF-8.\n * - `b1` produces a byte string.\n * Text and byte strings can mix within one concatenation.\n *\n * Arguments may include ellipses (`...`); the result is then an ellipsis\n * data item — tag CPA888 wrapping an array of joined string spans\n * alternating with `888(null)` markers (§5.2). Adjacent ellipses collapse\n * into one, and nested ellipsis arguments are flattened.\n *\n * `t1` and `b1` are mandatory-to-implement in draft-27 and are included in\n * the default extension set.\n *\n * NOTE: the identifiers \"t1\" and \"b1\" are explicitly provisional in\n * draft-27 (§3.5) and may be renamed by the CBOR WG.\n */\n\nimport type { CborExtension } from './types';\nimport type { CborItem } from '../ast/CborItem';\nimport { CborTextString } from '../ast/CborTextString';\nimport { CborByteString } from '../ast/CborByteString';\nimport { CborIndefiniteTextString } from '../ast/CborIndefiniteTextString';\nimport { CborIndefiniteByteString } from '../ast/CborIndefiniteByteString';\nimport { CborEllipsis } from '../ast/CborEllipsis';\nimport { CborAppSeqResult } from '../ast/CborAppSeqResult';\nimport { CborArray } from '../ast/CborArray';\n\nconst textEncoder = new TextEncoder();\nconst utf8Strict = new TextDecoder('utf-8', { fatal: true });\nconst utf8Lenient = new TextDecoder('utf-8', { fatal: false });\n\n/** Marker for an elision within the flattened argument list. */\nconst ELLIPSIS = Symbol('ellipsis');\ntype Part = Uint8Array | typeof ELLIPSIS;\n\nfunction concatBytes(parts: Uint8Array[]): Uint8Array {\n let total = 0;\n for (const p of parts) total += p.length;\n const out = new Uint8Array(total);\n let offset = 0;\n for (const p of parts) {\n out.set(p, offset);\n offset += p.length;\n }\n return out;\n}\n\n/**\n * Flatten one argument into byte spans and ellipsis markers.\n * Nested ellipsis items (e.g. from `h'aa...bb'` arguments) are expanded so\n * that the equivalences of §3.5 hold.\n */\nfunction flattenArg(prefix: string, item: CborItem, parts: Part[]): void {\n if (item instanceof CborAppSeqResult) {\n flattenArg(prefix, item.inner, parts);\n return;\n }\n if (item instanceof CborEllipsis) {\n if (item.content instanceof CborArray) {\n for (const inner of item.content.items) flattenArg(prefix, inner, parts);\n } else {\n parts.push(ELLIPSIS);\n }\n return;\n }\n if (item instanceof CborTextString) {\n parts.push(textEncoder.encode(item.value));\n return;\n }\n if (item instanceof CborByteString) {\n parts.push(item.value);\n return;\n }\n if (item instanceof CborIndefiniteTextString) {\n parts.push(textEncoder.encode(item.chunks.map((c) => c.value).join('')));\n return;\n }\n if (item instanceof CborIndefiniteByteString) {\n parts.push(concatBytes(item.chunks.map((c) => c.value)));\n return;\n }\n throw new SyntaxError(\n `${prefix}<<...>> arguments must be (text or byte) strings or ellipses`\n );\n}\n\n/** Decode joined bytes as UTF-8; recoverable violation when invalid. */\nfunction decodeText(\n bytes: Uint8Array,\n onError: ((msg: string) => void) | undefined\n): string {\n try {\n return utf8Strict.decode(bytes);\n } catch {\n const msg = `t1 concatenation result is not valid UTF-8`;\n if (onError) onError(msg);\n else throw new SyntaxError(msg);\n return utf8Lenient.decode(bytes);\n }\n}\n\nfunction concatenate(\n prefix: string,\n items: CborItem[],\n onError?: (msg: string) => void\n): CborItem {\n const parts: Part[] = [];\n for (const item of items) flattenArg(prefix, item, parts);\n\n const isText = prefix === 't1';\n\n // Consolidate adjacent byte spans; collapse adjacent ellipses (§3.5).\n const fragments: CborItem[] = [];\n let hasEllipsis = false;\n const pending: Uint8Array[] = [];\n const flushPending = () => {\n if (pending.length === 0) return;\n const bytes = concatBytes(pending);\n pending.length = 0;\n if (bytes.length === 0) return; // empty spans add nothing to the 888 array\n fragments.push(\n isText\n ? new CborTextString(decodeText(bytes, onError))\n : new CborByteString(bytes)\n );\n };\n for (const part of parts) {\n if (part === ELLIPSIS) {\n flushPending();\n if (!(fragments[fragments.length - 1] instanceof CborEllipsis)) {\n fragments.push(new CborEllipsis());\n hasEllipsis = true;\n }\n } else {\n pending.push(part);\n }\n }\n\n if (!hasEllipsis) {\n const bytes = concatBytes(pending);\n return isText\n ? new CborTextString(decodeText(bytes, onError))\n : new CborByteString(bytes);\n }\n flushPending();\n\n // A lone ellipsis argument list is equivalent to a single ellipsis.\n if (fragments.length === 1) return new CborEllipsis();\n return new CborEllipsis(fragments);\n}\n\nfunction makeExtension(prefix: 't1' | 'b1'): CborExtension {\n return {\n appStringPrefixes: [prefix],\n preserveAppSeqSource: true,\n\n // prefix'...' / prefix`...` is shorthand for a sequence with exactly\n // that one text string (§3).\n parseAppString(_prefix, content, onError) {\n return concatenate(prefix, [new CborTextString(content)], onError);\n },\n\n parseAppSequence(_prefix, items, onError) {\n return concatenate(prefix, items, onError);\n },\n };\n}\n\n/** Extension object for `t1'...'` / `t1<<...>>` (text-string concatenation). */\nexport const t1: CborExtension = makeExtension('t1');\n\n/** Extension object for `b1'...'` / `b1<<...>>` (byte-string concatenation). */\nexport const b1: CborExtension = makeExtension('b1');\n","/**\n * `ilbs'...'` / `ilbs<<...>>` and `ilts'...'` / `ilts<<...>>` app-extensions\n * (§3.6 of draft-ietf-cbor-edn-literals-27) — build indefinite-length\n * encoded strings.\n *\n * Semantically identical to `b1` / `t1` at the data model level, but instead\n * of concatenating the arguments into a single string, one chunk is created\n * per argument:\n * - `ilbs` produces an indefinite-length byte string (byte chunks),\n * - `ilts` produces an indefinite-length text string (text chunks).\n *\n * Encoding indicators on individual arguments are honored — the chunk keeps\n * the same encoding (e.g. `ilbs<<'Hello '_0, 'world'>>` → `5f 5806 ... ff`).\n * An indefinite-length string argument (e.g. a legacy `(_ ...)` streamstring)\n * is a string at the data model level and contributes one chunk with its\n * merged value. Ellipses cannot be used: there is no way to include an\n * elision in an indefinite-length string.\n *\n * These extensions replace the now-deprecated `(_ chunk, ...)` streamstring\n * syntax for new CDN documents (§4.3); this library keeps accepting the\n * legacy syntax on input.\n */\n\nimport type { CborExtension } from './types';\nimport type { CborItem } from '../ast/CborItem';\nimport type { EncodingWidth } from '../cbor/encode';\nimport { CborTextString } from '../ast/CborTextString';\nimport { CborByteString } from '../ast/CborByteString';\nimport { CborIndefiniteTextString } from '../ast/CborIndefiniteTextString';\nimport { CborIndefiniteByteString } from '../ast/CborIndefiniteByteString';\nimport { CborEllipsis } from '../ast/CborEllipsis';\nimport { CborAppSeqResult } from '../ast/CborAppSeqResult';\nimport { escapeAppString } from '../cdn/serialize-utils';\n\nconst textEncoder = new TextEncoder();\nconst utf8Strict = new TextDecoder('utf-8', { fatal: true });\nconst utf8Lenient = new TextDecoder('utf-8', { fatal: false });\n\nfunction concatBytes(parts: Uint8Array[]): Uint8Array {\n let total = 0;\n for (const p of parts) total += p.length;\n const out = new Uint8Array(total);\n let offset = 0;\n for (const p of parts) {\n out.set(p, offset);\n offset += p.length;\n }\n return out;\n}\n\nfunction buildIndefinite(\n prefix: string,\n items: CborItem[],\n onError?: (msg: string) => void\n): CborItem {\n const isText = prefix === 'ilts';\n const byteChunks: CborByteString[] = [];\n const textChunks: CborTextString[] = [];\n\n for (let item of items) {\n if (item instanceof CborAppSeqResult) item = item.inner;\n if (item instanceof CborEllipsis)\n throw new SyntaxError(\n `${prefix}<<...>> cannot contain ellipses; there is no way to include an elision in an indefinite-length string`\n );\n\n // Normalize the argument to its data-model string value. Indefinite-\n // length string arguments (e.g. a legacy `(_ ...)` streamstring) are\n // strings at the data model level; their merged value becomes one chunk.\n let argText: string | undefined;\n let argBytes: Uint8Array | undefined;\n // Encoding indicators are only carried by definite-length arguments.\n let ew: EncodingWidth | undefined;\n if (item instanceof CborTextString) {\n argText = item.value;\n ew = item.encodingWidth;\n } else if (item instanceof CborByteString) {\n argBytes = item.value;\n ew = item.encodingWidth;\n } else if (item instanceof CborIndefiniteTextString) {\n argText = item.chunks.map((c) => c.value).join('');\n } else if (item instanceof CborIndefiniteByteString) {\n argBytes = concatBytes(item.chunks.map((c) => c.value));\n } else {\n throw new SyntaxError(\n `${prefix}<<...>> arguments must be (text or byte) strings`\n );\n }\n\n // One chunk per argument, keeping the argument's encoding indicator.\n if (isText) {\n let text: string;\n if (argText !== undefined) {\n text = argText;\n } else {\n try {\n text = utf8Strict.decode(argBytes!);\n } catch {\n // RFC 8949 §3.2.3: each text-string chunk must itself be valid UTF-8.\n const msg = `ilts chunk is not valid UTF-8`;\n if (onError) onError(msg);\n else throw new SyntaxError(msg);\n text = utf8Lenient.decode(argBytes!);\n }\n }\n textChunks.push(\n new CborTextString(\n text,\n ew !== undefined ? { encodingWidth: ew } : undefined\n )\n );\n } else {\n const bytes = argBytes ?? textEncoder.encode(argText!);\n byteChunks.push(\n new CborByteString(\n bytes,\n ew !== undefined ? { encodingWidth: ew } : undefined\n )\n );\n }\n }\n\n return isText\n ? new CborIndefiniteTextString(textChunks)\n : new CborIndefiniteByteString(byteChunks);\n}\n\nfunction makeExtension(prefix: 'ilbs' | 'ilts'): CborExtension {\n return {\n appStringPrefixes: [prefix],\n preserveAppSeqSource: true,\n\n // prefix'...' / prefix`...` is shorthand for a sequence with exactly\n // that one text string (§3) — the result has a single chunk.\n // The result is wrapped so that toCDN() round-trips an app-string form\n // instead of normalizing to the deprecated `(_ ...)` streamstring\n // syntax. The source is reconstructed from the content, so the raw\n // string form prefix`...` normalizes to the single-quoted form.\n parseAppString(_prefix, content, onError) {\n const result = buildIndefinite(\n prefix,\n [new CborTextString(content)],\n onError\n );\n return new CborAppSeqResult(\n result,\n `${prefix}${escapeAppString(content)}`\n );\n },\n\n parseAppSequence(_prefix, items, onError) {\n return buildIndefinite(prefix, items, onError);\n },\n };\n}\n\n/** Extension object for `ilbs<<...>>` (indefinite-length byte string). */\nexport const ilbs: CborExtension = makeExtension('ilbs');\n\n/** Extension object for `ilts<<...>>` (indefinite-length text string). */\nexport const ilts: CborExtension = makeExtension('ilts');\n","/**\n * `float'...'` / `float<<...>>` app-string extension.\n *\n * Interprets a hex bit-pattern as an IEEE 754 floating-point value:\n * - 4 hex digits (2 bytes) → float16 (CBOR major-7, additional 25 / 0xf9)\n * - 8 hex digits (4 bytes) → float32 (CBOR major-7, additional 26 / 0xfa)\n * - 16 hex digits (8 bytes) → float64 (CBOR major-7, additional 27 / 0xfb)\n *\n * The string form `float'...'` supports the same comment syntax as `h'...'`:\n * slash-delimited block comments, C-style block comments, line comments (`//`\n * and `#`). The extension strips comments from the raw content itself.\n *\n * The sequence form `float<<byteStr>>` accepts a single byte-string expression\n * (e.g. `float<<h'7ef0'>>`) and interprets its bytes as float bits.\n *\n * Defined in draft-ietf-cbor-edn-literals-27 §3.8 and included in the default\n * extension set:\n *\n * @example\n * parseCDN(\"float'7ef0'\"); // NaN as float16\n */\n\nimport type { CborExtension } from './types';\nimport type { CborItem } from '../ast/CborItem';\nimport { CborFloat } from '../ast/CborFloat';\nimport { CborByteString } from '../ast/CborByteString';\nimport { float16BitsToFloat64, float64ToFloat16Bits } from '../utils/float16';\nimport { stripComments } from '../utils/strip-comments';\nimport { hexToBytes } from '../utils/hex';\nimport type { EncodingWidth } from '../cbor/encode';\n\n// ── Bit-preserving CborFloat subclasses ───────────────────────────────────────\n// CborFloat stores a JS `number`, which loses NaN payloads. These subclasses\n// override _toCBOR() to emit the original bit pattern verbatim.\n\nclass CborFloat16Bits extends CborFloat {\n private readonly _bits: number;\n constructor(bits: number) {\n super(float16BitsToFloat64(bits), { precision: 'half' });\n this._bits = bits & 0xffff;\n }\n override _toCBOR(): Uint8Array {\n return new Uint8Array([0xf9, (this._bits >> 8) & 0xff, this._bits & 0xff]);\n }\n}\n\nclass CborFloat32Bits extends CborFloat {\n private readonly _raw: Uint8Array;\n constructor(bytes: Uint8Array) {\n super(new DataView(bytes.buffer, bytes.byteOffset).getFloat32(0, false), {\n precision: 'single',\n });\n this._raw = bytes.slice();\n }\n override _toCBOR(): Uint8Array {\n const out = new Uint8Array(5);\n out[0] = 0xfa;\n out.set(this._raw, 1);\n return out;\n }\n}\n\nclass CborFloat64Bits extends CborFloat {\n private readonly _raw: Uint8Array;\n constructor(bytes: Uint8Array) {\n super(new DataView(bytes.buffer, bytes.byteOffset).getFloat64(0, false), {\n precision: 'double',\n });\n this._raw = bytes.slice();\n }\n override _toCBOR(): Uint8Array {\n const out = new Uint8Array(9);\n out[0] = 0xfb;\n out.set(this._raw, 1);\n return out;\n }\n}\n\nfunction floatFromBytes(bytes: Uint8Array): CborFloat {\n if (bytes.length === 2) {\n const bits = (bytes[0]! << 8) | bytes[1]!;\n return new CborFloat16Bits(bits);\n }\n if (bytes.length === 4) return new CborFloat32Bits(bytes);\n if (bytes.length === 8) return new CborFloat64Bits(bytes);\n throw new SyntaxError(\n `float'...' requires 4, 8, or 16 hex digits (2, 4, or 8 bytes); got ${bytes.length} bytes`\n );\n}\n\n/** Expand float16 bit pattern to 4-byte float32 (bit-exact, preserves NaN payloads). */\nfunction float16BitsToFloat32Bytes(bits16: number): Uint8Array {\n const sign = (bits16 >>> 15) & 1;\n const exp16 = (bits16 >>> 10) & 0x1f;\n const mant16 = bits16 & 0x3ff;\n let bits32: number;\n if (exp16 === 0x1f) {\n bits32 = (sign << 31) | 0x7f800000 | (mant16 << 13);\n } else if (exp16 === 0 && mant16 === 0) {\n bits32 = sign << 31;\n } else if (exp16 === 0) {\n // Denormal float16 → normal float32\n let m = mant16;\n let shifts = 0;\n while ((m & 0x200) === 0) {\n m <<= 1;\n shifts++;\n }\n bits32 = (sign << 31) | ((112 - shifts) << 23) | ((m & 0x1ff) << 14);\n } else {\n bits32 = (sign << 31) | ((exp16 + 112) << 23) | (mant16 << 13);\n }\n const out = new Uint8Array(4);\n new DataView(out.buffer).setUint32(0, bits32 >>> 0, false);\n return out;\n}\n\n/** Expand float16 bit pattern to 8-byte float64 (bit-exact, preserves NaN payloads). */\nfunction float16BitsToFloat64Bytes(bits16: number): Uint8Array {\n const sign = (bits16 >>> 15) & 1;\n const exp16 = (bits16 >>> 10) & 0x1f;\n const mant16 = bits16 & 0x3ff;\n const out = new Uint8Array(8);\n const dv = new DataView(out.buffer);\n if (exp16 === 0x1f) {\n dv.setUint32(0, ((sign << 31) | 0x7ff00000 | (mant16 << 10)) >>> 0, false);\n dv.setUint32(4, 0, false);\n } else if (exp16 === 0 && mant16 === 0) {\n dv.setUint32(0, (sign << 31) >>> 0, false);\n dv.setUint32(4, 0, false);\n } else if (exp16 === 0) {\n // Denormal float16 → normal float64\n let m = mant16;\n let shifts = 0;\n while ((m & 0x200) === 0) {\n m <<= 1;\n shifts++;\n }\n dv.setUint32(\n 0,\n ((sign << 31) | ((1008 - shifts) << 20) | ((m & 0x1ff) << 11)) >>> 0,\n false\n );\n dv.setUint32(4, 0, false);\n } else {\n dv.setUint32(\n 0,\n ((sign << 31) | ((exp16 + 1008) << 20) | (mant16 << 10)) >>> 0,\n false\n );\n dv.setUint32(4, 0, false);\n }\n return out;\n}\n\n/** Expand float32 bit pattern to 8-byte float64 (bit-exact, preserves NaN payloads). */\nfunction float32BitsToFloat64Bytes(bytes4: Uint8Array): Uint8Array {\n const bits32 = new DataView(bytes4.buffer, bytes4.byteOffset).getUint32(\n 0,\n false\n );\n const sign = (bits32 >>> 31) & 1;\n const exp32 = (bits32 >>> 23) & 0xff;\n const mant32 = bits32 & 0x7fffff;\n const out = new Uint8Array(8);\n const dv = new DataView(out.buffer);\n if (exp32 === 0xff) {\n dv.setUint32(0, ((sign << 31) | 0x7ff00000 | (mant32 >>> 3)) >>> 0, false);\n dv.setUint32(4, (mant32 & 7) << 29, false);\n } else if (exp32 === 0 && mant32 === 0) {\n dv.setUint32(0, (sign << 31) >>> 0, false);\n dv.setUint32(4, 0, false);\n } else {\n // Normal or denormal: JS arithmetic is exact (float32 ⊂ float64), NaN handled above.\n const f64 = new DataView(bytes4.buffer, bytes4.byteOffset).getFloat32(\n 0,\n false\n );\n dv.setFloat64(0, f64, false);\n }\n return out;\n}\n\n/**\n * Re-encode float bytes at a target precision (_1=half, _2=single, _3=double).\n * Returns undefined if the conversion is lossy (caller should warn).\n */\nfunction reencodeFloat(\n bytes: Uint8Array,\n targetWidth: 1 | 2 | 3,\n onError: (msg: string) => void\n): CborFloat {\n const naturalWidth = bytes.length === 2 ? 1 : bytes.length === 4 ? 2 : 3;\n\n if (naturalWidth === 1) {\n const bits16 = (bytes[0]! << 8) | bytes[1]!;\n if (targetWidth === 2)\n return new CborFloat32Bits(float16BitsToFloat32Bytes(bits16));\n if (targetWidth === 3)\n return new CborFloat64Bits(float16BitsToFloat64Bytes(bits16));\n }\n\n if (naturalWidth === 2) {\n if (targetWidth === 3)\n return new CborFloat64Bits(float32BitsToFloat64Bytes(bytes));\n if (targetWidth === 1) {\n const f32 = new DataView(bytes.buffer, bytes.byteOffset).getFloat32(\n 0,\n false\n );\n const bits16 = float64ToFloat16Bits(f32);\n if (!Object.is(float16BitsToFloat64(bits16), f32) && !isNaN(f32)) {\n onError(\n `float'...' value cannot be exactly represented as float16 (_1)`\n );\n }\n return new CborFloat16Bits(bits16);\n }\n }\n\n if (naturalWidth === 3) {\n const f64 = new DataView(bytes.buffer, bytes.byteOffset).getFloat64(\n 0,\n false\n );\n if (targetWidth === 1) {\n const bits16 = float64ToFloat16Bits(f64);\n if (!Object.is(float16BitsToFloat64(bits16), f64) && !isNaN(f64)) {\n onError(\n `float'...' value cannot be exactly represented as float16 (_1)`\n );\n }\n return new CborFloat16Bits(bits16);\n }\n if (targetWidth === 2) {\n const f32 = Math.fround(f64);\n if (!Object.is(f32, f64) && !isNaN(f64)) {\n onError(\n `float'...' value cannot be exactly represented as float32 (_2)`\n );\n }\n const out = new Uint8Array(4);\n new DataView(out.buffer).setFloat32(0, f32, false);\n return new CborFloat32Bits(out);\n }\n }\n\n // naturalWidth === targetWidth: identity (already handled by caller)\n return floatFromBytes(bytes);\n}\n\n/**\n * Extension object for `float'...'` / `float<<...>>`.\n * Pass to `parseCDN(..., { extensions: [float] })`.\n */\nexport const float: CborExtension = {\n appStringPrefixes: ['float'],\n\n parseAppString(\n _prefix: string,\n content: string,\n onError?: (msg: string) => void,\n options?: { encodingWidth?: EncodingWidth }\n ): CborItem {\n const hex = stripComments(content);\n if (!/^[0-9a-fA-F]*$/.test(hex))\n throw new SyntaxError(`float'...' contains non-hex characters`);\n if (hex.length % 2 !== 0)\n throw new SyntaxError(\n `float'...' hex content has odd length (${hex.length} digits)`\n );\n const bytes = hexToBytes(hex);\n const ew = options?.encodingWidth;\n if (ew === undefined) return floatFromBytes(bytes);\n if (ew !== 1 && ew !== 2 && ew !== 3) {\n const msg = `float'...' encoding indicator _${ew} is not valid; use _1, _2, or _3`;\n if (onError) {\n onError(msg);\n return floatFromBytes(bytes);\n }\n throw new SyntaxError(msg);\n }\n const naturalWidth = bytes.length === 2 ? 1 : bytes.length === 4 ? 2 : 3;\n if (ew === naturalWidth) return floatFromBytes(bytes);\n const fallbackOnError =\n onError ??\n ((msg: string) => {\n throw new SyntaxError(msg);\n });\n return reencodeFloat(bytes, ew, fallbackOnError);\n },\n\n parseAppSequence(\n _prefix: string,\n items: CborItem[],\n onError?: (msg: string) => void\n ): CborItem {\n if (items.length === 0)\n throw new SyntaxError(\n `float<<...>> requires exactly one byte-string item`\n );\n if (items.length > 1) {\n const msg = `float<<...>> expects 1 item; got ${items.length} — using first`;\n if (onError) onError(msg);\n else throw new SyntaxError(msg);\n }\n if (!(items[0] instanceof CborByteString))\n throw new SyntaxError(`float<<...>> item must be a byte string`);\n return floatFromBytes(items[0].value);\n },\n};\n\nexport default float;\n","import type { CborExtension } from './types';\nimport dt from './dt';\nimport ip from './ip';\nimport cri from './cri';\nimport bignum from './bignum';\nimport cbordata from './cbordata';\nimport ellipsis from './ellipsis';\nimport { t1, b1 } from './concat';\nimport { ilbs, ilts } from './ilstrings';\nimport float from './float';\n\n/**\n * Core data-model extensions (bignum tags 2/3, embedded-CBOR tag 24, and the\n * CPA888 ellipsis tag). These implement base CBOR/EDN representation rather\n * than an app-extension, so they are always active and are not affected by\n * the `builtinExtensions` option.\n */\nexport const CORE_EXTENSIONS: readonly CborExtension[] = [\n bignum,\n cbordata,\n ellipsis,\n];\n\n/**\n * Default app-extensions bundled with the library.\n * Overridable per call via `builtinExtensions` (an array to use instead, or\n * `false` to disable all of them).\n *\n * `dt`, `ip`, `t1`, and `b1` are mandatory-to-implement per §3 of\n * draft-ietf-cbor-edn-literals-27; `cri`, `ilbs`, `ilts`, and `float` are\n * bundled but not mandatory.\n */\nexport const BUILTIN_EXTENSIONS: readonly CborExtension[] = [\n dt,\n ip,\n cri,\n t1,\n b1,\n ilbs,\n ilts,\n float,\n];\n\nlet _defaultResolved: readonly CborExtension[] | undefined;\n\n/**\n * Resolve the `builtinExtensions` option to the full list of built-in\n * extensions that should be active: `CORE_EXTENSIONS` plus either the\n * default `BUILTIN_EXTENSIONS` set (`undefined`), a caller-supplied\n * replacement array, or nothing beyond core (`false`).\n */\nexport function resolveBuiltinExtensions(\n builtinExtensions?: CborExtension[] | false\n): readonly CborExtension[] {\n if (builtinExtensions === undefined)\n return (_defaultResolved ??= [...CORE_EXTENSIONS, ...BUILTIN_EXTENSIONS]);\n if (builtinExtensions === false) return CORE_EXTENSIONS;\n return [...CORE_EXTENSIONS, ...builtinExtensions];\n}\n","import type { FromJSOptions } from '../types';\nimport { CBOR_OMIT } from '../types';\nimport type { CborItem } from '../ast/CborItem';\nimport type { CborExtension } from '../extensions/types';\nimport { resolveBuiltinExtensions } from '../extensions/builtins';\nimport { CborUint } from '../ast/CborUint';\nimport { CborNint } from '../ast/CborNint';\nimport { CborBigUint, CborBigNint } from '../ast/CborBignum';\nimport { CborByteString } from '../ast/CborByteString';\nimport { CborTextString } from '../ast/CborTextString';\nimport { CborArray } from '../ast/CborArray';\nimport { CborMap } from '../ast/CborMap';\nimport { CborFloat } from '../ast/CborFloat';\nimport { CborSimple } from '../ast/CborSimple';\nimport { CborTag } from '../ast/CborTag';\nimport { Tag } from '../tag';\nimport { Simple } from '../simple';\nimport { MapEntries } from '../mapEntries';\n\n/**\n * Extension hooks used by _fromJS, pre-filtered so the per-node loops touch\n * only extensions that actually implement each hook.\n */\ninterface ResolvedExtensions {\n /** Extensions with a fromJS hook (user extensions first). */\n fromJS: readonly CborExtension[];\n /** Extensions with a parseTag hook (user extensions first). */\n parseTag: readonly CborExtension[];\n}\n\n/**\n * Default resolved builtins (no `builtinExtensions` override) pre-filtered\n * per hook, cached after first use. Lazy (not module-level) because\n * mapEntries.ts imports fromJS.ts, forming a cycle that leaves the builtins\n * module's exports undefined at module init time.\n */\nlet _defaultResolvedExts: ResolvedExtensions | undefined;\nfunction getBuiltinResolvedExts(\n builtinExtensions: CborExtension[] | false | undefined\n): ResolvedExtensions {\n if (builtinExtensions === undefined) {\n if (_defaultResolvedExts) return _defaultResolvedExts;\n const resolved = resolveBuiltinExtensions(undefined);\n return (_defaultResolvedExts = {\n fromJS: resolved.filter((ext) => ext.fromJS !== undefined),\n parseTag: resolved.filter((ext) => ext.parseTag !== undefined),\n });\n }\n const resolved = resolveBuiltinExtensions(builtinExtensions);\n return {\n fromJS: resolved.filter((ext) => ext.fromJS !== undefined),\n parseTag: resolved.filter((ext) => ext.parseTag !== undefined),\n };\n}\n\n/**\n * Build the hook lists once per fromJS() entry call — _fromJS recursion is\n * per-node, so rebuilding a spread extension array there is measurably slow.\n */\nfunction resolveExtensions(\n options: FromJSOptions | undefined\n): ResolvedExtensions {\n const user = options?.extensions;\n const builtin = getBuiltinResolvedExts(options?.builtinExtensions);\n if (!user?.length) return builtin;\n return {\n fromJS: [\n ...user.filter((ext) => ext.fromJS !== undefined),\n ...builtin.fromJS,\n ],\n parseTag: [\n ...user.filter((ext) => ext.parseTag !== undefined),\n ...builtin.parseTag,\n ],\n };\n}\n\n/**\n * Convert a plain JavaScript value to a CborItem AST node.\n *\n * Type dispatch order:\n * object with [Tag.symbol] symbol → CborTag (wraps the inner value)\n * null / undefined / boolean → CborSimple\n * bigint → CborUint / CborNint / CborBigUint / CborBigNint\n * number → CborFloat, or CborUint/CborNint if integerAs='int' (default)\n * string → CborTextString\n * Number / Boolean / String / BigInt object → unwrapped primitive (recurse)\n * Tag.Null / Tag.Undefined → CborSimple.NULL / UNDEFINED\n * ArrayBuffer / SharedArrayBuffer → CborByteString\n * ArrayBufferView (TypedArray, DataView, …) → CborByteString (Uint8Array respects uint8ArrayAs)\n * Array → CborArray (recursive)\n * Map → CborMap (keys also converted recursively)\n * plain object → CborMap (string keys → CborTextString)\n */\nexport function fromJS(value: unknown, options?: FromJSOptions): CborItem {\n if (options?.replacer) {\n const { replacer, ...rest } = options;\n const replaced = _applyReplacer(\n value,\n replacer,\n rest.extensions,\n rest.undefinedOmits,\n rest.builtinExtensions\n );\n if (replaced === CBOR_OMIT) return CborSimple.UNDEFINED;\n return fromJS(\n replaced,\n Object.keys(rest).length > 0 ? (rest as FromJSOptions) : undefined\n );\n }\n return _fromJS(value, options, true, resolveExtensions(options));\n}\n\nfunction _fromJS(\n value: unknown,\n options: FromJSOptions | undefined,\n checkTag: boolean,\n exts: ResolvedExtensions\n): CborItem {\n // ── Extension fromJS hooks ───────────────────────────────────────────────────\n for (const ext of exts.fromJS) {\n const result = ext.fromJS!(value, options ?? {});\n if (result !== undefined) return result;\n }\n\n // ── CBOR tag annotation (Symbol key) ────────────────────────────────────────\n // checkTag=false on the recursive call to skip this branch and convert the\n // inner value normally, avoiding infinite recursion.\n // After converting the inner value, try parseTag() hooks so that e.g.\n // dt / ip can produce their specialised subclasses without needing\n // a separate fromJS() hook on the extension.\n if (\n checkTag &&\n typeof value === 'object' &&\n value !== null &&\n Tag.symbol in (value as object)\n ) {\n const tag = (value as Record<symbol, bigint>)[Tag.symbol];\n const innerValue = _fromJS(value, options, false, exts);\n for (const ext of exts.parseTag) {\n const result = ext.parseTag!(tag, innerValue);\n if (result !== undefined) return result;\n }\n return new CborTag(tag, innerValue);\n }\n\n // ── Null wrapper (from CborTag.toJS() of tagged null) ───────────────────────\n // Must come AFTER the Tag.symbol check so that Tag.Null (which carries\n // a [Tag.symbol] symbol) is first wrapped in CborTag, then unwrapped as NULL\n // in the recursive checkTag=false call.\n if (value instanceof Tag.Null) return CborSimple.NULL;\n if (value instanceof Tag.Undefined) return CborSimple.UNDEFINED;\n if (value instanceof Simple) return new CborSimple(value.value);\n\n // ── Primitives ───────────────────────────────────────────────────────────────\n if (value === null) return CborSimple.NULL;\n if (value === undefined) return CborSimple.UNDEFINED;\n if (value === true) return CborSimple.TRUE;\n if (value === false) return CborSimple.FALSE;\n\n if (typeof value === 'bigint') {\n if (value > 0xffff_ffff_ffff_ffffn) return new CborBigUint(value);\n if (value < -(0xffff_ffff_ffff_ffffn + 1n)) return new CborBigNint(value);\n return value >= 0n ? new CborUint(value) : new CborNint(value);\n }\n\n if (typeof value === 'number') {\n const integerAs = options?.encodeIntegerAs ?? 'int';\n if (\n integerAs === 'int' &&\n Number.isInteger(value) &&\n !Object.is(value, -0)\n ) {\n if (value >= 0) return new CborUint(BigInt(value));\n return new CborNint(BigInt(value));\n }\n return new CborFloat(value);\n }\n\n if (typeof value === 'string') return new CborTextString(value);\n\n // ── Boxed primitives — unwrap and recurse ───────────────────────────────────\n if (value instanceof Number)\n return _fromJS(value.valueOf(), options, false, exts);\n if (value instanceof Boolean)\n return _fromJS(value.valueOf(), options, false, exts);\n if (value instanceof String)\n return _fromJS(value.valueOf(), options, false, exts);\n // Object(bigint) — detected via Object.prototype.toString\n if (Object.prototype.toString.call(value) === '[object BigInt]')\n return _fromJS(\n (value as { valueOf(): bigint }).valueOf(),\n options,\n false,\n exts\n );\n\n // ── ArrayBuffer / SharedArrayBuffer ─────────────────────────────────────────\n if (\n value instanceof ArrayBuffer ||\n (typeof SharedArrayBuffer !== 'undefined' &&\n value instanceof SharedArrayBuffer)\n ) {\n return new CborByteString(new Uint8Array(value as ArrayBuffer));\n }\n\n // ── ArrayBufferView (TypedArray variants, DataView) ─────────────────────────\n if (ArrayBuffer.isView(value)) {\n if (value instanceof Uint8Array && options?.uint8ArrayAs === 'array') {\n return new CborArray(Array.from(value, (b) => new CborUint(BigInt(b))));\n }\n return new CborByteString(\n new Uint8Array(value.buffer, value.byteOffset, value.byteLength)\n );\n }\n\n if (value instanceof MapEntries) {\n return new CborMap(\n [...value].map(\n ([k, v]) =>\n [\n _fromJS(k, options, true, exts),\n _fromJS(v, options, true, exts),\n ] as [CborItem, CborItem]\n )\n );\n }\n\n if (Array.isArray(value)) {\n return new CborArray(\n value.map((item) => _fromJS(item, options, true, exts))\n );\n }\n\n if (typeof value === 'object') {\n const entries: [CborItem, CborItem][] = [];\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n entries.push([new CborTextString(k), _fromJS(v, options, true, exts)]);\n }\n return new CborMap(entries);\n }\n\n throw new TypeError(`fromJS: unsupported value type: ${typeof value}`);\n}\n\n// ─── Replacer helper ────────────────────────────────────────────────────────\n\ntype _FnReplacer = (this: unknown, key: unknown, value: unknown) => unknown;\ntype _Replacer = _FnReplacer | (string | number)[];\n\n/** True for values that _fromJS handles via a dedicated branch (not Object.entries). */\nfunction _isNativelyHandled(v: object): boolean {\n return (\n ArrayBuffer.isView(v) ||\n v instanceof ArrayBuffer ||\n (typeof SharedArrayBuffer !== 'undefined' &&\n v instanceof SharedArrayBuffer) ||\n v instanceof Number ||\n v instanceof Boolean ||\n v instanceof String ||\n Object.prototype.toString.call(v) === '[object BigInt]' ||\n v instanceof Tag.Null ||\n v instanceof Tag.Undefined ||\n v instanceof Simple\n );\n}\n\nexport function _applyReplacer(\n value: unknown,\n replacer: _Replacer,\n extensions?: readonly CborExtension[],\n undefinedOmits?: boolean,\n builtinExtensions?: CborExtension[] | false\n): unknown {\n // Only isJSType hooks are consulted below; filter once, not per node.\n const jsTypeExts: readonly CborExtension[] = [\n ...(extensions ?? []),\n ...resolveBuiltinExtensions(builtinExtensions),\n ].filter((ext) => ext.isJSType !== undefined);\n\n /** True when a replacer/reviver result should cause the entry to be dropped. */\n function _omits(v: unknown): boolean {\n return v === CBOR_OMIT || (undefinedOmits === true && v === undefined);\n }\n\n if (Array.isArray(replacer)) {\n const allowed = (replacer as (string | number)[]).map(String);\n function filterKeys(v: unknown): unknown {\n if (v === null || typeof v !== 'object') return v;\n if (v instanceof MapEntries)\n return MapEntries.from(\n v,\n ([k, val]) => [k, filterKeys(val)] as [unknown, unknown]\n );\n if (Array.isArray(v)) return v.map(filterKeys);\n // Tagged objects pass through so fromJS can encode the tag natively.\n if (Tag.symbol in (v as object)) return v;\n // Built-in types pass through so fromJS can handle them natively.\n if (_isNativelyHandled(v as object)) return v;\n // Extension-owned values pass through so fromJS can handle them natively.\n if (jsTypeExts.some((ext) => ext.isJSType!(v))) return v;\n // Plain objects only: honor toJSON() first (matches JSON.stringify semantics).\n const proto = Object.getPrototypeOf(v as object) as unknown;\n if (proto === Object.prototype || proto === null) {\n const toJSON = (v as Record<string, unknown>)['toJSON'];\n if (typeof toJSON === 'function')\n return filterKeys((toJSON as () => unknown).call(v));\n }\n const result: Record<string, unknown> = {};\n for (const k of allowed) {\n if (Object.prototype.hasOwnProperty.call(v, k))\n result[k] = filterKeys((v as Record<string, unknown>)[k]);\n }\n return result;\n }\n return filterKeys(value);\n }\n\n const fn = replacer as _FnReplacer;\n function applyFn(val: unknown, key: unknown, holder: unknown): unknown {\n // Call toJSON() only on plain objects (proto === Object.prototype or null).\n // Non-plain objects (Date, TypedArray, extension-backed classes…) pass\n // through so fromJS extensions can handle them; MapEntries is also skipped\n // so its integer keys and structure are preserved for CBOR encoding.\n if (\n val !== null &&\n typeof val === 'object' &&\n !(val instanceof MapEntries)\n ) {\n const proto = Object.getPrototypeOf(val as object) as unknown;\n if (proto === Object.prototype || proto === null) {\n const toJSON = (val as Record<string, unknown>)['toJSON'];\n if (typeof toJSON === 'function')\n val = (toJSON as (k: unknown) => unknown).call(val, key);\n }\n }\n val = fn.call(holder, key, val);\n if (val !== null && typeof val === 'object') {\n // Tagged objects pass through so fromJS can encode the tag natively.\n if (Tag.symbol in (val as object)) return val;\n if (val instanceof MapEntries) {\n const result = new MapEntries();\n for (const [k, v] of val) {\n const newV = applyFn(v, k, val);\n if (!_omits(newV)) result.push([k, newV]);\n }\n return result;\n }\n if (Array.isArray(val)) {\n return (val as unknown[]).map((v, i) => {\n const child = applyFn(v, String(i), val);\n // CBOR.OMIT / undefined-omits in arrays → null (matches JSON.stringify).\n return _omits(child) ? null : child;\n });\n }\n // Built-in types pass through to fromJS unchanged.\n if (_isNativelyHandled(val as object)) return val;\n // Extension-owned values pass through so fromJS can handle them natively.\n if (jsTypeExts.some((ext) => ext.isJSType!(val))) return val;\n const result: Record<string, unknown> = {};\n for (const k of Object.keys(val as object)) {\n const child = applyFn((val as Record<string, unknown>)[k], k, val);\n if (!_omits(child)) result[k] = child;\n }\n return result;\n }\n return val;\n }\n return applyFn(value, '', { '': value });\n}\n","import { fromJS } from './js/fromJS';\n\nexport class MapEntries extends Array<[unknown, unknown]> {\n toJSON(): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n for (const [k, v] of this) {\n const key = typeof k === 'string' ? k : fromJS(k).toCDN();\n if (key === '__proto__') {\n Object.defineProperty(result, key, {\n value: v,\n writable: true,\n enumerable: true,\n configurable: true,\n });\n } else {\n result[key] = v;\n }\n }\n return result;\n }\n}\n"],"mappings":"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"}