@fishka/seqio 0.5.0 → 0.6.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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/abif/bytes.ts","../src/abif/abif-format.ts","../src/abif/view.ts","../src/abif/parser.ts","../src/abif/setters.ts","../src/fastx.ts"],"names":["asciiString","bytes","s","i","asciiBytes","out","asDataView","subview","start","length","tagNameFromInt32","n","HEADER_SIZE","ENTRY_SIZE","readAbif","macBinaryOffset","base","view","version","dirEntry","decodeEntry","rawDirCount","numEntries","dirOffset","entries","dirDataSize","entriesEnd","padLen","tdir","headerReserved","macBinaryHeader","unreferencedRanges","computeUnreferencedRanges","total","covered","dirCovered","e","norm","en","a","b","merged","last","gaps","cursor","off","tagName","tagNumber","elementType","elementSize","rawElementCount","declaredDataSize","dataHandle","computedDataSize","payloadSize","inline","elementCount","payload","dataOffset","at","dataOffsetBytes","writeAbif","file","originalCount","verbatimRaw","anchor","raw","r","dirGrew","freshOffsets","size","outView","writeDirRecord","dataSize","rec","staleTail","findEntry","name","number","findEntries","upsertEntry","defaults","existing","getDataChannel","arr","getFwo","isFwoPermutation","fwo","hasData9To12Block","dataChannelRole","getReverseComplemented","getChannelMap","getSequence","read","e2","e1","getConfidences","getPositions","getSamplingRate","v","TYPE_NAMES","typeName","t","previewNumbers","max","truncate","previewBytes","slice","hex","asNumbers","d","decodeNumeric","byteLength","decodePayload","o","year","month","day","len","previewDecoded","hour","minute","second","parseAbif","input","fileName","decoded","baseOrder","dataChannels","data1To4","data9To12","metadata","pbas","pcon","ploc","channelKey","idx","nums","baseCallVariants","baseCalls","pbasVersion","seq","confidences","c","positions","pp","pos","data9Len","chromatogram","hasSignals","channelMaxLength","setSequence","sequence","setConfidences","q","buf","setPositions","setAveragePeakSpacing","spacing","basecallerName","f1","nameBytes","p","f3","averagePeakSpacing","ensureRawDataChannels","src","target","MAX_PHRED","formatFasta","records","options","width","toArray","headerLine","wrapResidues","formatFastq","formatFastqRecord","formatQual","wrapScores","hasUsableQuality","qualities","record","id","description","quality","phredToChar","prefix","values","clampPhred","perLine","value"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Tiny binary helpers used across the ABIF reader/writer.\n *\n * Everything here operates on Uint8Array + DataView so the same code runs in\n * Node (where Buffer extends Uint8Array) and the browser.\n */\n\nexport function asciiString(bytes: Uint8Array): string {\n let s = '';\n for (let i = 0; i < bytes.length; i++) s += String.fromCharCode(bytes[i]);\n return s;\n}\n\nexport function asciiBytes(s: string): Uint8Array {\n const out = new Uint8Array(s.length);\n for (let i = 0; i < s.length; i++) out[i] = s.charCodeAt(i) & 0xff;\n return out;\n}\n\n/** Returns a DataView over the given bytes, regardless of input shape. */\nexport function asDataView(bytes: Uint8Array): DataView {\n return new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);\n}\n\n/** Returns a Uint8Array view over a slice; never copies. */\nexport function subview(bytes: Uint8Array, start: number, length: number): Uint8Array {\n return bytes.subarray(start, start + length);\n}\n\n/** Tag name encoded as a big-endian uint32 (e.g. \"DATA\" → 0x44415441). */\nexport function tagNameToInt32(tag: string): number {\n return (\n ((tag.charCodeAt(0) & 0xff) << 24) |\n ((tag.charCodeAt(1) & 0xff) << 16) |\n ((tag.charCodeAt(2) & 0xff) << 8) |\n (tag.charCodeAt(3) & 0xff)\n );\n}\n\nexport function tagNameFromInt32(n: number): string {\n return String.fromCharCode((n >>> 24) & 0xff, (n >>> 16) & 0xff, (n >>> 8) & 0xff, n & 0xff);\n}\n","/**\n * Raw layer: the ABIF byte<->struct codec. Every directory entry (including unknown\n * vendor tags) is preserved as a raw payload (Uint8Array), and writeAbif() reproduces\n * the original bytes exactly for an unmodified round-trip (see its own doc comment).\n * The domain layer (view.ts, setters.ts, parser.ts, abif-op-*.ts) provides typed,\n * format-aware access on top of this — this file knows nothing about what any tag\n * means.\n *\n * ABIF file layout:\n * [0..3] \"ABIF\" magic\n * [4..5] version (int16 BE; 101 = v1.01)\n * [6..33] TdirEntry describing the directory itself\n * [34..127] reserved (94 bytes, zero-filled)\n * [...] directory block (N * 28-byte entries) and payload blocks\n *\n * TdirEntry (28 bytes, big-endian):\n * off size field\n * 0 4 tagName (ASCII)\n * 4 4 tagNumber (int32)\n * 8 2 elementType (int16)\n * 10 2 elementSize (int16)\n * 12 4 elementCount (int32)\n * 16 4 dataSize (int32; total payload bytes — authoritative; for\n * well-formed entries equals count*size, but user/\n * opaque types may differ, so we read by dataSize)\n * 20 4 dataOffset (int32) OR inline data if dataSize <= 4\n * 24 4 dataHandle (int32; usually 0)\n *\n * Inline rule (per ABIF spec): when the declared dataSize <= 4 the payload bytes\n * are stored directly in the dataOffset field (left-aligned, padded to 4 bytes).\n *\n * MacBinary preamble: some ABIF files (older Mac-origin) start with a 128-byte\n * MacBinary header before the actual ABIF magic. We detect and skip it.\n */\n\nimport { asciiBytes, asciiString, asDataView, subview, tagNameFromInt32 } from './bytes';\nimport { AbifByteRange, AbifDirectory, AbifEntry, AbifEntryRaw, AbifFile } from './types';\n\nexport const HEADER_SIZE = 128;\nexport const ENTRY_SIZE = 28;\n\n/**\n * Parse an ABIF file from raw bytes into its verbatim directory structure.\n *\n * This is the RAW source of truth: it reads the tdir header and every entry as\n * stored — real dataSize, dataOffset, numElements (see `entry.raw`), the 4 inline\n * bytes, and the tdir/directory metadata — and interprets nothing. For a\n * high-level, opinionated view (typed channels, basecalls, metadata) layer\n * {@link parseAbif} on top.\n *\n * Accepts Uint8Array (works in Node and the browser). Node's Buffer extends\n * Uint8Array, so `readAbif(buffer)` and `readAbif(new Uint8Array(arrayBuffer))`\n * both work.\n *\n * Throws if the magic header is missing. Does NOT require any specific tags\n * (PBAS, DATA, ...) to be present — raw pre-basecalled files are supported.\n */\nexport function readAbif(bytes: Uint8Array): AbifFile {\n if (bytes.byteLength < HEADER_SIZE) {\n throw new Error(`ABIF too small: ${bytes.byteLength} bytes`);\n }\n\n // MacBinary wrap support: skip 128 bytes if magic is at offset 128.\n let macBinaryOffset = 0;\n if (asciiString(subview(bytes, 0, 4)) !== 'ABIF') {\n if (bytes.byteLength >= 128 + 4 && asciiString(subview(bytes, 128, 4)) === 'ABIF') {\n macBinaryOffset = 128;\n } else {\n throw new Error('Not an ABIF file: missing \"ABIF\" magic.');\n }\n }\n const base = macBinaryOffset;\n // After skipping any MacBinary wrap, the ABIF part itself must still hold a full 128-byte header;\n // otherwise reading version/tdir below would run past the DataView (a raw RangeError, not ours).\n if (bytes.byteLength - base < HEADER_SIZE) {\n throw new Error(`ABIF too small: ${bytes.byteLength - base} bytes after offset ${base}`);\n }\n const view = asDataView(bytes);\n\n const version = view.getInt16(base + 4, false);\n\n // Header bytes [base+6 .. base+34) are a TdirEntry describing the directory itself.\n const dirEntry = decodeEntry(bytes, view, base + 6, base);\n if (dirEntry.tagName !== 'tdir') {\n throw new Error(`Expected \"tdir\" header entry, got \"${dirEntry.tagName}\"`);\n }\n if (dirEntry.elementSize !== ENTRY_SIZE) {\n throw new Error(`Expected dir element size ${ENTRY_SIZE}, got ${dirEntry.elementSize}`);\n }\n\n // The directory's numElements (raw) is the authoritative entry count — like BioPython, we trust\n // it rather than clamp against tdir.dataSize, which is a redundant byte-count that some writers\n // desync. Physical bounds are enforced below; a negative/garbage count just yields 0 entries.\n const rawDirCount = dirEntry.raw?.elementCount ?? dirEntry.elementCount;\n const numEntries = Math.max(0, rawDirCount);\n // tdir.dataSize is always > 4 (28*N), so the dataOffset field is an external offset.\n const dirOffset = view.getInt32(base + 6 + 20, false);\n if (dirOffset < 0 || dirOffset + numEntries * ENTRY_SIZE > bytes.byteLength - base) {\n throw new Error(\n `Directory out of bounds: offset=${dirOffset}, entries=${numEntries}, file=${bytes.byteLength - base}`,\n );\n }\n\n const entries: AbifEntry[] = [];\n for (let i = 0; i < numEntries; i++) {\n entries.push(decodeEntry(bytes, view, base + dirOffset + i * ENTRY_SIZE, base));\n }\n\n // Root directory (tdir) header, as read — its dataSize may exceed numEntries*28 (directory padding).\n const dirDataSize = dirEntry.raw?.dataSize ?? numEntries * ENTRY_SIZE;\n const entriesEnd = base + dirOffset + numEntries * ENTRY_SIZE;\n const padLen = Math.min(\n Math.max(0, dirDataSize - numEntries * ENTRY_SIZE),\n Math.max(0, bytes.byteLength - entriesEnd),\n );\n const tdir: AbifDirectory = {\n entryCount: numEntries, // effective count actually read (== entries.length)\n rawEntryCount: rawDirCount, // tdir numElements verbatim, before any reconciliation\n elementType: dirEntry.elementType, // 1023 (tdir)\n tagNumber: dirEntry.tagNumber, // usually 1\n entrySize: dirEntry.elementSize,\n dataSize: dirDataSize,\n dataOffset: dirOffset,\n dataOffsetBytes: dirEntry.raw?.dataOffsetBytes ?? new Uint8Array(4),\n dataHandle: dirEntry.dataHandle,\n paddingBytes: new Uint8Array(subview(bytes, entriesEnd, padLen)),\n };\n\n // Reserved header bytes [base+34 .. base+128) — verbatim, so a raw reader keeps the whole header.\n const headerReserved = new Uint8Array(subview(bytes, base + 6 + ENTRY_SIZE, HEADER_SIZE - 6 - ENTRY_SIZE));\n\n // The MacBinary preamble bytes themselves, when present — verbatim, so the wrapper is reproducible.\n const macBinaryHeader = macBinaryOffset === 128 ? new Uint8Array(subview(bytes, 0, 128)) : undefined;\n\n const unreferencedRanges = computeUnreferencedRanges(bytes, base, dirOffset, dirDataSize, entries, macBinaryOffset);\n\n return { version, tdir, entries, macBinaryOffset, macBinaryHeader, headerReserved, unreferencedRanges };\n}\n\n/**\n * Find the file's physical byte ranges that no header/directory/entry payload covers — orphaned\n * blocks, trailing padding, etc. Computes the complement of every referenced interval so a raw\n * reader can account for all bytes without the writer having to be byte-exact.\n */\nfunction computeUnreferencedRanges(\n bytes: Uint8Array,\n base: number,\n dirOffset: number,\n dirDataSize: number,\n entries: AbifEntry[],\n macBinaryOffset: number,\n): AbifByteRange[] {\n const total = bytes.byteLength;\n const covered: Array<[number, number]> = [];\n if (macBinaryOffset === 128) covered.push([0, 128]); // preamble\n covered.push([base, base + HEADER_SIZE]); // 128-byte header (magic/version/tdir/reserved)\n // Directory spans the bytes actually read (numElements entries) OR the declared dataSize when it is\n // larger (padding) — whichever is bigger, so a desynced dataSize < numElements*28 doesn't mislabel\n // already-read entries as orphan bytes. A negative dataSize collapses to the physical entry span.\n const dirCovered = Math.max(entries.length * ENTRY_SIZE, Math.max(0, dirDataSize));\n covered.push([base + dirOffset, base + dirOffset + dirCovered]);\n for (const e of entries) {\n if (e.raw && !e.raw.inline) {\n const start = base + e.raw.dataOffset;\n covered.push([start, start + e.payload.byteLength]); // external payload\n }\n }\n\n const norm = covered\n .map(([s, en]): [number, number] => [Math.max(0, Math.min(s, total)), Math.max(0, Math.min(en, total))])\n .filter(([s, en]) => en > s)\n .sort((a, b) => a[0] - b[0]);\n\n const merged: Array<[number, number]> = [];\n for (const [s, en] of norm) {\n const last = merged[merged.length - 1];\n if (last && s <= last[1]) last[1] = Math.max(last[1], en);\n else merged.push([s, en]);\n }\n\n const gaps: AbifByteRange[] = [];\n let cursor = 0;\n for (const [s, en] of merged) {\n if (s > cursor) gaps.push({ offset: cursor, bytes: new Uint8Array(subview(bytes, cursor, s - cursor)) });\n cursor = Math.max(cursor, en);\n }\n if (cursor < total) gaps.push({ offset: cursor, bytes: new Uint8Array(subview(bytes, cursor, total - cursor)) });\n return gaps;\n}\n\n/**\n * Decode a 28-byte TdirEntry at the given absolute byte offset.\n *\n * Two robustness measures applied here that BioPython also uses and that real\n * ABIF files in the wild require:\n *\n * 1. The payload is exactly `dataSize` bytes — the authoritative directory field.\n * ABIF allows `numElements * elementSize != dataSize` for user/opaque types,\n * so we never derive the payload length from count*size (that both truncates\n * a larger declared payload and over-reads a smaller one).\n *\n * 2. Inline vs external follows the spec: inline iff `dataSize <= 4` (the payload\n * fits in the 4-byte dataOffset field). Data > 4 bytes is always external,\n * even when count*size <= 4. We fall back to count*size only when the declared\n * field is negative/garbage.\n *\n * 3. `elementCount` is reconciled down to what the payload can hold, so a desynced\n * (over-large) count can't drive readers past the real bytes.\n *\n * 4. External payload offsets are relative to the ABIF start, so we add `base`\n * (the MacBinary preamble length) when reading them.\n */\nfunction decodeEntry(bytes: Uint8Array, view: DataView, off: number, base: number): AbifEntry {\n const tagName = asciiString(subview(bytes, off, 4));\n const tagNumber = view.getInt32(off + 4, false);\n const elementType = view.getInt16(off + 8, false);\n const elementSize = view.getInt16(off + 10, false);\n const rawElementCount = view.getInt32(off + 12, false);\n const declaredDataSize = view.getInt32(off + 16, false);\n const dataHandle = view.getInt32(off + 24, false);\n\n const computedDataSize = Math.max(0, rawElementCount * Math.max(0, elementSize));\n // Payload length is the declared dataSize; a negative/garbage declared field falls back to the\n // computed count*size (consistent with the inline decision below).\n const payloadSize = declaredDataSize >= 0 ? declaredDataSize : computedDataSize;\n // Inline iff dataSize <= 4; fall back to computed size only for an invalid declared field.\n const inline = declaredDataSize >= 0 ? declaredDataSize <= 4 : computedDataSize <= 4;\n // Reconcile the element count down to what the payload holds, and never expose a negative count\n // (a malformed numElements would otherwise crash Array/TypedArray helpers downstream). When\n // elementSize <= 0 the per-element stride is unknown, so cap by payloadSize (≤ 1 byte/element)\n // rather than trusting the raw count — otherwise a typed getter reads past a 0-byte payload.\n const elementCount = Math.max(\n 0,\n elementSize > 0\n ? Math.min(rawElementCount, Math.floor(payloadSize / elementSize))\n : Math.min(rawElementCount, payloadSize),\n );\n\n let payload: Uint8Array;\n let dataOffset: number;\n if (inline) {\n dataOffset = -1;\n payload = new Uint8Array(subview(bytes, off + 20, Math.min(4, payloadSize)));\n } else {\n dataOffset = view.getInt32(off + 20, false);\n const at = base + dataOffset;\n if (dataOffset < 0 || at + payloadSize > bytes.byteLength) {\n throw new Error(\n `Entry ${tagName}${tagNumber}: payload out of bounds (offset=${dataOffset}, size=${payloadSize})`,\n );\n }\n payload = new Uint8Array(subview(bytes, at, payloadSize));\n }\n\n // The raw 4 bytes of the data/offset slot, verbatim (payload+padding when inline, offset when external).\n const dataOffsetBytes = new Uint8Array(subview(bytes, off + 20, 4));\n\n return {\n tagName,\n tagNumber,\n elementType,\n elementSize,\n elementCount,\n payload,\n dataHandle,\n raw: { elementCount: rawElementCount, dataSize: declaredDataSize, dataOffset, inline, dataOffsetBytes },\n };\n}\n\n/**\n * Serialize an AbifFile back to a Uint8Array.\n *\n * Byte-exact on an unmodified round-trip for well-formed records and the tolerated\n * count/dataSize desyncs readAbif() accepts: readAbif() followed right back by\n * writeAbif(), with nothing touched in between, reproduces the original bytes\n * exactly (a MacBinary-wrapped input round-trips its ABIF payload byte-exact, but\n * the preamble itself is never re-added — see the AGENTS.md note on why). The one\n * exception is a genuinely invalid negative `dataSize`/`numElements` field (readAbif\n * tolerates these defensively, falling back to a computed size, but never treats them\n * as verbatim-eligible on write — see the byteLength check below) — such an entry\n * round-trips meaning-lossless (correct payload/content) but its declared dataSize\n * field gets normalized to the real payload length rather than reproducing the\n * original garbage value.\n *\n * This works by keeping every entry whose payload size hasn't changed since it was\n * read (`entry.raw` present — upsertEntry() clears it on any mutation — and\n * `payload.byteLength === raw.dataSize`) at its exact original directory slot and\n * file offset, writing the *original* on-disk numElements/dataSize/offset-or-inline-\n * padding instead of the reconciled/current ones. A new or resized entry is appended\n * past the highest byte offset still known to hold preserved content (every verbatim\n * entry's span, the directory, and any unreferenced range); only its own directory\n * record changes, so every other entry's bytes stay untouched. A resized/removed\n * entry's *old* span is not itself reserved — nothing points at it anymore, so it is\n * free to be reused by whatever gets appended next; the output is not padded out to\n * the original file's true end.\n *\n * The directory is kept at its original file offset as long as the entry count\n * didn't grow (removing entries just shortens it in place; the original directory\n * padding is only reused when the count is exactly unchanged, since a shorter\n * directory can't reuse padding sized for more entries). Only a growing entry count\n * relocates the whole directory to freshly appended space.\n */\nexport function writeAbif(file: AbifFile): Uint8Array {\n const base = file.macBinaryOffset;\n const numEntries = file.entries.length;\n const originalCount = file.tdir.entryCount;\n\n // An entry is verbatim-eligible when its payload is exactly the size it was read\n // at — the only case where its original directory record/offset can be reused.\n const verbatimRaw: Array<AbifEntryRaw | undefined> = file.entries.map(e =>\n e.raw && e.payload.byteLength === e.raw.dataSize ? e.raw : undefined,\n );\n\n // Anchor: the highest byte offset known to belong to the original (unwrapped)\n // file — header, directory span, every verbatim entry's external payload, and any\n // orphan byte range. Fresh content is appended after this, so an unmodified\n // round-trip never appends anything and the output ends exactly here.\n let anchor = HEADER_SIZE;\n // A malformed original can declare tdir.dataSize smaller than the entries actually occupy\n // (readAbif trusts numElements over dataSize — see the \"desynced tdir.dataSize\" test); the\n // *physical* directory span must still be protected even though the reused dataSize field\n // below intentionally reproduces the original (desynced) declared value byte-for-byte.\n anchor = Math.max(anchor, file.tdir.dataOffset + Math.max(file.tdir.dataSize, originalCount * ENTRY_SIZE));\n for (const raw of verbatimRaw) {\n if (raw && !raw.inline) anchor = Math.max(anchor, raw.dataOffset + raw.dataSize);\n }\n for (const r of file.unreferencedRanges) {\n anchor = Math.max(anchor, r.offset - base + r.bytes.length);\n }\n\n // Directory placement: reuse the original slot unless the entry count grew past it.\n const dirGrew = numEntries > originalCount;\n let cursor = anchor;\n const dirOffset = dirGrew ? cursor : file.tdir.dataOffset;\n const dirDataSize = numEntries === originalCount ? file.tdir.dataSize : numEntries * ENTRY_SIZE;\n if (dirGrew) cursor += dirDataSize;\n\n // Fresh (non-verbatim) external payloads are appended past the anchor, in entry order.\n const freshOffsets: number[] = new Array(numEntries);\n for (let i = 0; i < numEntries; i++) {\n const size = file.entries[i].payload.byteLength;\n if (verbatimRaw[i] || size <= 4) {\n freshOffsets[i] = -1; // reused verbatim placement, or inline — no fresh external slot\n continue;\n }\n freshOffsets[i] = cursor;\n cursor += size;\n }\n\n const out = new Uint8Array(cursor);\n const outView = asDataView(out);\n\n // Header: \"ABIF\" + version (int16 BE) + tdir entry (below) + reserved bytes verbatim.\n out.set(asciiBytes('ABIF'), 0);\n outView.setInt16(4, file.version, false);\n out.set(file.headerReserved, 6 + ENTRY_SIZE);\n writeDirRecord(out, outView, 6, {\n tagName: 'tdir',\n tagNumber: file.tdir.tagNumber,\n elementType: file.tdir.elementType,\n elementSize: file.tdir.entrySize,\n elementCount: numEntries,\n dataSize: dirDataSize,\n dataHandle: file.tdir.dataHandle,\n offsetSlot: { kind: 'external', value: dirOffset },\n });\n\n // Directory padding only carries over when the entry count is exactly unchanged.\n if (numEntries === originalCount && file.tdir.paddingBytes.length > 0) {\n out.set(file.tdir.paddingBytes, dirOffset + numEntries * ENTRY_SIZE);\n }\n\n for (let i = 0; i < numEntries; i++) {\n const e = file.entries[i];\n const raw = verbatimRaw[i];\n const off = dirOffset + i * ENTRY_SIZE;\n const dataSize = e.payload.byteLength;\n writeDirRecord(out, outView, off, {\n tagName: e.tagName,\n tagNumber: e.tagNumber,\n elementType: e.elementType,\n elementSize: e.elementSize,\n elementCount: raw ? raw.elementCount : e.elementCount,\n dataSize: raw ? raw.dataSize : dataSize,\n dataHandle: e.dataHandle,\n offsetSlot:\n dataSize <= 4\n ? { kind: 'inline', payload: e.payload, dataSize, staleTail: raw?.dataOffsetBytes }\n : { kind: 'external', value: raw ? raw.dataOffset : freshOffsets[i] },\n });\n if (dataSize > 4) {\n out.set(e.payload, raw ? raw.dataOffset : freshOffsets[i]);\n }\n }\n\n for (const r of file.unreferencedRanges) {\n out.set(r.bytes, r.offset - base);\n }\n\n return out;\n}\n\ntype OffsetSlot =\n | { kind: 'external'; value: number }\n | { kind: 'inline'; payload: Uint8Array; dataSize: number; staleTail?: Uint8Array };\n\nfunction writeDirRecord(\n out: Uint8Array,\n outView: DataView,\n off: number,\n rec: {\n tagName: string;\n tagNumber: number;\n elementType: number;\n elementSize: number;\n elementCount: number;\n dataSize: number;\n dataHandle: number;\n offsetSlot: OffsetSlot;\n },\n): void {\n if (rec.tagName.length !== 4) {\n throw new Error(`tagName must be 4 chars: \"${rec.tagName}\"`);\n }\n out.set(asciiBytes(rec.tagName), off);\n outView.setInt32(off + 4, rec.tagNumber, false);\n outView.setInt16(off + 8, rec.elementType, false);\n outView.setInt16(off + 10, rec.elementSize, false);\n outView.setInt32(off + 12, rec.elementCount, false);\n outView.setInt32(off + 16, rec.dataSize, false);\n if (rec.offsetSlot.kind === 'external') {\n outView.setInt32(off + 20, rec.offsetSlot.value, false);\n } else {\n // Inline: clear 4 bytes, place the payload, then restore any stale tail byte(s)\n // beyond dataSize from the original slot — a byte-exact round-trip needs them,\n // since they're not derivable from any semantic field.\n const { payload, dataSize, staleTail } = rec.offsetSlot;\n out.fill(0, off + 20, off + 24);\n out.set(payload.subarray(0, dataSize), off + 20);\n if (staleTail && dataSize < 4) {\n out.set(staleTail.subarray(dataSize, 4), off + 20 + dataSize);\n }\n }\n outView.setInt32(off + 24, rec.dataHandle, false);\n}\n\n// =====================================================================\n// Lookup / mutation helpers\n// =====================================================================\n\n/** Find an entry by name+number, or undefined. */\nexport function findEntry(file: AbifFile, name: string, number: number): AbifEntry | undefined {\n return file.entries.find(e => e.tagName === name && e.tagNumber === number);\n}\n\n/** Find all entries with the given tag name. */\nexport function findEntries(file: AbifFile, name: string): AbifEntry[] {\n return file.entries.filter(e => e.tagName === name);\n}\n\n/**\n * Replace the payload of an existing entry, or append a new one.\n * elementType/elementSize/elementCount must be supplied for new entries.\n *\n * This is the required way to mutate an entry read from a file — it clears `.raw`\n * on replacement so writeAbif() never reuses a now-stale on-disk shape. Setting\n * `entry.payload`/`elementType`/`elementSize`/`elementCount` directly instead\n * leaves `.raw` behind and can corrupt the written directory record.\n */\nexport function upsertEntry(\n file: AbifFile,\n name: string,\n number: number,\n payload: Uint8Array,\n defaults: { elementType: number; elementSize: number; elementCount: number },\n): void {\n if (payload.byteLength !== defaults.elementCount * defaults.elementSize) {\n throw new Error(`upsertEntry ${name}${number}: payload length ${payload.byteLength} != count*size`);\n }\n const existing = findEntry(file, name, number);\n if (existing) {\n existing.elementType = defaults.elementType;\n existing.elementSize = defaults.elementSize;\n existing.elementCount = defaults.elementCount;\n existing.payload = payload;\n // `raw` describes the entry's shape as read from disk; once mutated it no longer applies —\n // clearing it forces writeAbif() to place this entry fresh rather than reuse a stale record\n // (e.g. a same-length content edit would otherwise silently keep the old elementCount/dataSize).\n existing.raw = undefined;\n } else {\n file.entries.push({\n tagName: name,\n tagNumber: number,\n elementType: defaults.elementType,\n elementSize: defaults.elementSize,\n elementCount: defaults.elementCount,\n payload,\n dataHandle: 0,\n });\n }\n}\n\n/** Re-export for users who want to interpret raw tag bytes themselves. */\nexport { tagNameFromInt32 };\n","/**\n * High-level typed view over an AbifFile.\n *\n * Reading helpers that interpret the raw payloads of well-known tags. For\n * mutation helpers (setSequence, setConfidences, ...) see ./setters.\n */\n\nimport { findEntry } from './abif-format';\nimport { asciiString, asDataView } from './bytes';\nimport { AbifDataChannelRole, AbifEntry, AbifFile } from './types';\n\n/** Get DATA<n> as a signed-int16 array, or undefined. */\nexport function getDataChannel(file: AbifFile, n: number): Int16Array | undefined {\n const e = findEntry(file, 'DATA', n);\n if (!e) return undefined;\n if (e.elementSize !== 2) {\n throw new Error(`DATA${n}: expected elementSize=2, got ${e.elementSize}`);\n }\n const arr = new Int16Array(e.elementCount);\n const view = asDataView(e.payload);\n for (let i = 0; i < e.elementCount; i++) {\n arr[i] = view.getInt16(i * 2, false);\n }\n return arr;\n}\n\n/**\n * Dye order, 4 ASCII chars (e.g. \"GATC\"). Defaults to \"GATC\" if FWO_ absent.\n *\n * GATC is the dye order produced by modern ABI 3730/3500 instruments and the\n * dominant default in the wild. Older \"ACGT\" defaults caused channel\n * mis-mapping on files where FWO_ is missing or malformed.\n */\nexport function getFwo(file: AbifFile): string {\n const e = findEntry(file, 'FWO_', 1);\n if (!e) return 'GATC';\n // Read only the declared elements — payload may carry trailing padding beyond elementCount.\n return asciiString(e.payload.subarray(0, e.elementCount));\n}\n\n/**\n * Whether an FWO_ string is a genuine dye order: a permutation of A/C/G/T with all\n * four bases distinct. `\"GATC\"` passes; `\"AAAA\"` (regex-valid but degenerate) does\n * not — mapping four channels through it would collapse them onto one base.\n */\nexport function isFwoPermutation(fwo: string): boolean {\n return /^[ACGT]{4}$/.test(fwo) && new Set(fwo).size === 4;\n}\n\n/**\n * Fact: the file carries a second dye-trace block, DATA9..12 (all four tags), in\n * addition to DATA1..4. Reports presence only — it does NOT say which block is\n * raw and which is analyzed/processed; that convention isn't stored in the file.\n */\nexport function hasData9To12Block(file: AbifFile): boolean {\n return !!(\n findEntry(file, 'DATA', 9) &&\n findEntry(file, 'DATA', 10) &&\n findEntry(file, 'DATA', 11) &&\n findEntry(file, 'DATA', 12)\n );\n}\n\n/**\n * Spec-defined role of a DATA<n> tag, limited to the numbers the ABIF spec names:\n *\n * - `'trace'` — dye-signal channels: DATA1..4 (raw dyes 1-4), DATA9..12\n * (analyzed dyes 1-4), and the two optional 5th-dye blocks\n * DATA105 (raw dye 5) and DATA205 (analyzed dye 5).\n * - `'telemetry'` — DATA5..8: instrument run telemetry (voltage, current,\n * power, temperature), one value per scan — NOT dye signal.\n * - `'other'` — any other DATA number. The spec does not enumerate higher\n * extra-dye tags (106/206/…), so we don't claim a role for them.\n *\n * A fact from the ABIF specification, not an inference about content.\n */\nexport function dataChannelRole(n: number): AbifDataChannelRole {\n if (n >= 5 && n <= 8) return 'telemetry';\n if ((n >= 1 && n <= 4) || (n >= 9 && n <= 12) || n === 105 || n === 205) return 'trace';\n return 'other';\n}\n\n/**\n * Whether the file declares its sequence already reverse-complemented, from the\n * RevC1 flag (int16, non-zero = true). undefined when RevC1 is absent. Reported\n * as-is; the consumer decides how to act on it.\n */\nexport function getReverseComplemented(file: AbifFile): boolean | undefined {\n const e = findEntry(file, 'RevC', 1);\n if (!e) return undefined;\n const view = asDataView(e.payload);\n return e.payload.byteLength >= 2 ? view.getInt16(0, false) !== 0 : e.payload.some(b => b !== 0);\n}\n\n/**\n * Map from base letter (\"A\"|\"C\"|\"G\"|\"T\") to the DATA1..4 tag number that holds\n * its channel, using the dye order declared by FWO_. If FWO_=\"GATC\" then\n * G→1, A→2, T→3, C→4.\n *\n * This follows the file's own FWO_ declaration for the DATA1..4 block; it makes\n * no claim about whether that block is raw or processed.\n */\nexport function getChannelMap(file: AbifFile): Record<'A' | 'C' | 'G' | 'T', number> {\n const fwo = getFwo(file);\n if (!isFwoPermutation(fwo)) {\n throw new Error(`FWO_ is not a permutation of A/C/G/T: \"${fwo}\"`);\n }\n return {\n [fwo[0]]: 1,\n [fwo[1]]: 2,\n [fwo[2]]: 3,\n [fwo[3]]: 4,\n } as Record<'A' | 'C' | 'G' | 'T', number>;\n}\n\n/** Get PBAS sequence (prefer PBAS2 over PBAS1). undefined if neither present. */\nexport function getSequence(file: AbifFile): string | undefined {\n // Bound by elementCount (payload may be padded) and drop trailing NULs, matching parseAbif.\n const read = (e: AbifEntry): string => asciiString(e.payload.subarray(0, e.elementCount)).replace(/\\0+$/g, '');\n const e2 = findEntry(file, 'PBAS', 2);\n if (e2) return read(e2);\n const e1 = findEntry(file, 'PBAS', 1);\n if (e1) return read(e1);\n return undefined;\n}\n\n/**\n * Get per-base Phred-like quality scores (0..255 byte values, typically 0..60\n * for Sanger). Prefers PCON2 over PCON1.\n *\n * PCON is declared in the ABIF spec as elementType=2 (char) but the byte\n * values ARE the Q-scores — we read raw bytes regardless of declared type.\n */\nexport function getConfidences(file: AbifFile): number[] | undefined {\n const e = findEntry(file, 'PCON', 2) ?? findEntry(file, 'PCON', 1);\n if (!e) return undefined;\n const out: number[] = new Array(e.elementCount);\n for (let i = 0; i < e.elementCount; i++) out[i] = e.payload[i];\n return out;\n}\n\n/**\n * Get peak scan positions (one per base). Prefers PLOC2 over PLOC1.\n *\n * Read as UNSIGNED int16: PLOC indexes into the sample trace and is always\n * non-negative, but values > 32767 (long traces) would wrap to negative\n * if interpreted as signed.\n */\nexport function getPositions(file: AbifFile): number[] | undefined {\n const e = findEntry(file, 'PLOC', 2) ?? findEntry(file, 'PLOC', 1);\n if (!e) return undefined;\n if (e.elementSize !== 2) {\n throw new Error(`PLOC: expected elementSize=2, got ${e.elementSize}`);\n }\n const view = asDataView(e.payload);\n const out: number[] = new Array(e.elementCount);\n for (let i = 0; i < e.elementCount; i++) out[i] = view.getUint16(i * 2, false);\n return out;\n}\n\n/**\n * Get average peak spacing (samples per base), from SPAC/1.\n *\n * ABIF spec defines SPAC as float32 (elementType=7); some legacy files\n * mislabel it as long (type=5). Both are 4 bytes and on disk the payload\n * is always a 32-bit float, so we read as float regardless of declared type.\n *\n * Returns undefined if SPAC is absent or non-positive.\n */\nexport function getSamplingRate(file: AbifFile): number | undefined {\n const e = findEntry(file, 'SPAC', 1);\n if (!e || e.elementSize !== 4 || e.payload.byteLength < 4) return undefined;\n const v = asDataView(e.payload).getFloat32(0, false);\n return Number.isFinite(v) && v > 0 ? v : undefined;\n}\n","/**\n * High-level \"parse everything\" wrapper around the raw + view layers.\n *\n * Returns a single ParsedAbif object with metadata, the FWO_-aware\n * DATA1..4 / DATA9..12 channel split, basecalls, and decoded directory entries\n * for diagnostics. Mirrors what typical viewers (chromatogram UIs, sample\n * inspectors) need from a single file.\n *\n * For round-trip authoring (basecallers), prefer {@link readAbif} +\n * setters from ./setters which operate directly on the raw AbifFile.\n */\n\nimport { readAbif } from './abif-format';\nimport { asciiString, asDataView, subview } from './bytes';\nimport {\n AbifBaseCalls,\n AbifBaseCallVariant,\n AbifChromatogramBundle,\n AbifDecodedValue,\n AbifDirEntry,\n AbifEntry,\n AbifMetadata,\n ChannelSignals,\n ParsedAbif,\n} from './types';\nimport { getFwo, isFwoPermutation } from './view';\n\nconst TYPE_NAMES: Record<number, string> = {\n 1: 'byte',\n 2: 'char',\n 3: 'word',\n 4: 'short',\n 5: 'long',\n 7: 'float',\n 8: 'double',\n 10: 'date',\n 11: 'time',\n 12: 'thumb',\n 13: 'bool',\n 18: 'pString',\n 19: 'cString',\n 1023: 'tdir',\n};\n\nfunction typeName(t: number): string {\n return TYPE_NAMES[t] ?? (t >= 1024 ? `user${t}` : `type${t}`);\n}\n\nfunction previewNumbers(arr: number[], max = 10): string {\n if (arr.length <= max) return `[${arr.join(', ')}]`;\n return `[${arr.slice(0, max).join(', ')}, … +${arr.length - max}] (n=${arr.length})`;\n}\n\nfunction truncate(s: string, n = 80): string {\n return s.length > n ? s.slice(0, n) + '…' : s;\n}\n\nfunction previewBytes(bytes: Uint8Array): string {\n const slice = bytes.subarray(0, 16);\n const hex = Array.from(slice, b => b.toString(16).padStart(2, '0')).join(' ');\n return `${bytes.byteLength}B [${hex}${bytes.byteLength > 16 ? ' …' : ''}]`;\n}\n\n/** Coerce a decoded value to a number array, treating a single scalar as a one-element array. */\nfunction asNumbers(d: AbifDecodedValue): number[] | undefined {\n if (d.kind === 'numbers') return d.value;\n if (d.kind === 'number') return [d.value];\n return undefined;\n}\n\n/**\n * Decode a run of fixed-width numbers, bounded by BOTH the element count and the\n * actual payload length — so a malformed entry whose declared elementSize/dataSize\n * disagrees with the type's real width can never drive a read past the buffer.\n */\nfunction decodeNumeric(\n byteLength: number,\n elementCount: number,\n size: number,\n read: (offset: number) => number,\n): AbifDecodedValue {\n const n = Math.max(0, Math.min(elementCount, Math.floor(byteLength / size)));\n const arr: number[] = [];\n for (let i = 0; i < n; i++) arr.push(read(i * size));\n return arr.length === 1 ? { kind: 'number', value: arr[0] } : { kind: 'numbers', value: arr };\n}\n\n/**\n * Decode a payload best-effort by ABIF element type.\n *\n * Strings have trailing NULs stripped (cString/pString convention).\n * pString (type 18) is decoded as `length-prefix + chars`.\n */\nfunction decodePayload(elementType: number, elementCount: number, payload: Uint8Array): AbifDecodedValue {\n const view = asDataView(payload);\n switch (elementType) {\n case 1: {\n const arr = Array.from(payload.subarray(0, elementCount));\n return { kind: 'numbers', value: arr };\n }\n case 2:\n case 19: {\n const s = asciiString(payload.subarray(0, elementCount)).replace(/\\0+$/g, '');\n return { kind: 'string', value: s };\n }\n case 3:\n return decodeNumeric(payload.byteLength, elementCount, 2, o => view.getUint16(o, false));\n case 4:\n return decodeNumeric(payload.byteLength, elementCount, 2, o => view.getInt16(o, false));\n case 5:\n return decodeNumeric(payload.byteLength, elementCount, 4, o => view.getInt32(o, false));\n case 7:\n return decodeNumeric(payload.byteLength, elementCount, 4, o => view.getFloat32(o, false));\n case 8:\n return decodeNumeric(payload.byteLength, elementCount, 8, o => view.getFloat64(o, false));\n case 10: {\n // A date needs 4 bytes; a short/truncated payload falls back to raw bytes rather than throwing.\n if (payload.byteLength < 4) return { kind: 'unknown', value: payload };\n const year = view.getInt16(0, false);\n const month = view.getUint8(2);\n const day = view.getUint8(3);\n return { kind: 'date', value: { year, month, day } };\n }\n case 11: {\n // A time needs 4 bytes; short payload → raw bytes, not a RangeError.\n if (payload.byteLength < 4) return { kind: 'unknown', value: payload };\n return {\n kind: 'time',\n value: {\n hour: view.getUint8(0),\n minute: view.getUint8(1),\n second: view.getUint8(2),\n hsec: view.getUint8(3),\n },\n };\n }\n case 13: {\n const arr: boolean[] = [];\n for (let i = 0; i < Math.min(elementCount, payload.byteLength); i++) arr.push(view.getUint8(i) !== 0);\n return { kind: 'bools', value: arr };\n }\n case 18: {\n // pString = length prefix + chars; an empty payload is just the empty string.\n if (payload.byteLength < 1) return { kind: 'string', value: '' };\n const len = view.getUint8(0);\n const s = asciiString(subview(payload, 1, Math.min(len, Math.max(0, elementCount - 1))));\n return { kind: 'string', value: s };\n }\n default:\n return { kind: 'unknown', value: payload };\n }\n}\n\nfunction previewDecoded(d: AbifDecodedValue, elementType: number): string {\n switch (d.kind) {\n case 'number':\n return String(d.value);\n case 'numbers':\n return previewNumbers(d.value);\n case 'string':\n return truncate(JSON.stringify(d.value));\n case 'bools':\n return d.value.length === 1 ? String(d.value[0]) : `[${d.value.join(', ')}]`;\n case 'date': {\n const { year, month, day } = d.value;\n return `${year}-${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')}`;\n }\n case 'time': {\n const { hour, minute, second } = d.value;\n return `${String(hour).padStart(2, '0')}:${String(minute).padStart(2, '0')}:${String(second).padStart(2, '0')}`;\n }\n case 'bytes':\n return `${typeName(elementType)} ${previewBytes(d.value)}`;\n case 'unknown':\n return `${typeName(elementType)} ${previewBytes(d.value)}`;\n }\n}\n\n/**\n * Parse an ABIF file into a high-level view: metadata, channels, basecalls,\n * and decoded directory entries.\n *\n * This is the INTERPRETING layer — it makes convenience choices (FWO_ → \"GATC\"\n * fallback, derived samplingRate, preferred/upper-cased PBAS2 baseCalls). It is\n * not the raw structural truth: for that use {@link readAbif}, which reads the\n * directory verbatim (raw dataSize/offset/counts, tdir, inline bytes) and makes\n * no interpretation. `parseAbif` builds on top of it.\n *\n * Accepts ArrayBuffer or Uint8Array (Buffer in Node works too — it extends\n * Uint8Array). The `fileName` argument is informational only; it's preserved\n * in the result.\n */\nexport function parseAbif(input: ArrayBuffer | Uint8Array, fileName = ''): ParsedAbif {\n const bytes = input instanceof Uint8Array ? input : new Uint8Array(input);\n const file = readAbif(bytes);\n\n const entries: AbifDirEntry[] = file.entries.map(e => {\n // PCON is declared char (type 2) but its bytes ARE Q-scores; decode it as numbers so the\n // diagnostic view keeps zeros the char decoder would strip (matches baseCalls.confidences).\n const decoded =\n e.tagName === 'PCON' && e.elementSize === 1\n ? decodePayload(1, e.elementCount, e.payload) // type 1 = byte → { kind: 'numbers' }\n : decodePayload(e.elementType, e.elementCount, e.payload);\n // Prefer the real on-disk directory fields (present when read from a file) over\n // reconciled/computed values, so the diagnostic view reflects the actual record.\n return {\n tag: e.tagName,\n tagNumber: e.tagNumber,\n elementType: e.elementType,\n elementTypeName: typeName(e.elementType),\n elementSize: e.elementSize,\n elementCount: e.elementCount,\n rawElementCount: e.raw?.elementCount ?? e.elementCount,\n dataSize: e.raw?.dataSize ?? e.elementCount * e.elementSize,\n dataOffset: e.raw?.dataOffset ?? -1,\n inline: e.raw?.inline ?? e.elementCount * e.elementSize <= 4,\n decoded,\n preview: previewDecoded(decoded, e.elementType),\n };\n });\n\n // FWO_ → base order. Fall back to GATC unless FWO_ is a real permutation of A/C/G/T\n // (a degenerate value like \"AAAA\" is regex-valid but would collapse channels).\n let baseOrder = getFwo(file);\n if (!isFwoPermutation(baseOrder)) baseOrder = 'GATC';\n\n const dataChannels: Record<number, number[]> = {};\n const data1To4: ChannelSignals = { A: [], C: [], G: [], T: [] };\n const data9To12: ChannelSignals = { A: [], C: [], G: [], T: [] };\n const metadata: AbifMetadata = { comments: [] };\n const pbas: Record<number, string> = {};\n const pcon: Record<number, number[]> = {};\n const ploc: Record<number, number[]> = {};\n\n const channelKey = (i: number): keyof ChannelSignals => baseOrder[i] as keyof ChannelSignals;\n\n for (let idx = 0; idx < file.entries.length; idx++) {\n const e = file.entries[idx];\n const decoded = entries[idx].decoded;\n\n if (e.tagName === 'DATA') {\n // Accept single-element channels too (decodePayload collapses length-1 to a scalar).\n const nums = asNumbers(decoded);\n if (nums) {\n dataChannels[e.tagNumber] = nums;\n if (e.tagNumber >= 1 && e.tagNumber <= 4) data1To4[channelKey(e.tagNumber - 1)] = nums;\n else if (e.tagNumber >= 9 && e.tagNumber <= 12) data9To12[channelKey(e.tagNumber - 9)] = nums;\n }\n } else if (e.tagName === 'PBAS' && decoded.kind === 'string') {\n pbas[e.tagNumber] = decoded.value;\n } else if (e.tagName === 'PCON') {\n // PCON Q-scores are 1 byte each (elementType=2/char). Read them straight from the payload —\n // a trailing zero is a valid score, but the char decoder strips trailing NULs and would drop it.\n const nums = e.elementSize === 1 ? Array.from(e.payload.subarray(0, e.elementCount)) : asNumbers(decoded);\n if (nums) pcon[e.tagNumber] = nums;\n } else if (e.tagName === 'PLOC') {\n // PLOC sample indices are always non-negative — reinterpret int16 as uint16.\n const nums = asNumbers(decoded);\n if (nums) ploc[e.tagNumber] = nums.map(v => (v < 0 ? v + 0x10000 : v));\n } else if (e.tagName === 'SPAC') {\n // ABIF spec defines SPAC as float (elementType=7). Some legacy files mislabel\n // it as long (type=5); both are 4 bytes and the payload is always a float.\n if (e.elementSize === 4 && e.payload.byteLength >= 4) {\n const v = asDataView(e.payload).getFloat32(0, false);\n if (Number.isFinite(v) && v > 0) metadata.samplingRate = v;\n } else if (decoded.kind === 'number') {\n metadata.samplingRate = decoded.value;\n }\n } else if (e.tagName === 'SMPL' && decoded.kind === 'string') {\n metadata.sampleName = decoded.value;\n } else if (e.tagName === 'LANE' && decoded.kind === 'number') {\n metadata.laneNumber = decoded.value;\n } else if (e.tagName === 'TUBE' && decoded.kind === 'string') {\n metadata.tube = decoded.value;\n } else if (e.tagName === 'MCHN' && decoded.kind === 'string') {\n metadata.machineName = decoded.value;\n } else if (e.tagName === 'MODL' && decoded.kind === 'string') {\n metadata.machineModel = decoded.value;\n } else if (e.tagName === 'RUND' && decoded.kind === 'date') {\n const d = decoded.value;\n metadata.runDate = `${d.year}-${String(d.month).padStart(2, '0')}-${String(d.day).padStart(2, '0')}`;\n } else if (e.tagName === 'RUNT' && decoded.kind === 'time') {\n const t = decoded.value;\n metadata.runTime = `${String(t.hour).padStart(2, '0')}:${String(t.minute).padStart(2, '0')}:${String(t.second).padStart(2, '0')}`;\n } else if (e.tagName === 'CMNT' && decoded.kind === 'string') {\n metadata.comments.push(decoded.value);\n } else if (e.tagName === 'RevC' && e.tagNumber === 1) {\n // RevC1 (int16): file's own flag for whether the sequence is already\n // reverse-complemented. Only tagNumber 1 is defined by the spec. Reported\n // as-is; we draw no conclusion from it.\n if (decoded.kind === 'number') metadata.reverseComplemented = decoded.value !== 0;\n else if (decoded.kind === 'numbers') metadata.reverseComplemented = decoded.value.some(v => v !== 0);\n }\n }\n\n // Every basecall version the file carries, exactly as stored — the source of\n // truth. Per-version PCON/PLOC are kept strictly (no cross-version borrowing):\n // a variant reports only what its own tag number holds.\n const baseCallVariants: AbifBaseCallVariant[] = Object.keys(pbas)\n .map(Number)\n .sort((a, b) => a - b)\n .map(\n (v): AbifBaseCallVariant => ({\n version: v,\n role: v === 1 ? 'edited' : v === 2 ? 'called' : 'unknown',\n // As stored: case is preserved (lower-case can encode masking/edits). The\n // uppercased convenience view lives on `baseCalls`, not here.\n sequence: pbas[v],\n confidences: pcon[v] ?? [],\n positions: ploc[v] ?? [],\n }),\n );\n\n // Basecalls: prefer PBAS2 (called) over PBAS1 (edited) — a spec-role choice. Test key\n // presence, not string truthiness, so an existing-but-empty PBAS2 is still honored.\n let baseCalls: AbifBaseCalls | undefined;\n const pbasVersion = 2 in pbas ? 2 : 1 in pbas ? 1 : Object.keys(pbas).map(Number)[0];\n if (pbasVersion !== undefined && pbas[pbasVersion] !== undefined) {\n // Don't .trim(): keep length aligned with PCON/PLOC (trailing nulls already stripped).\n const seq = pbas[pbasVersion].toUpperCase();\n // Fall back to whichever PCON has a length matching the chosen PBAS — some\n // files ship PCON only under one tagNumber even when PBAS exists under both.\n // Fall back to whichever version's PCON/PLOC matches the chosen PBAS length — triggered when the\n // preferred version's array is missing OR present-but-length-mismatched. Expose none rather than a\n // broken array when nothing matches, so baseCalls stays self-consistent (baseCallVariants stays strict).\n let confidences = pcon[pbasVersion] ?? [];\n if (confidences.length !== seq.length) {\n confidences =\n Object.keys(pcon)\n .map(Number)\n .map(v => pcon[v])\n .find(c => c.length === seq.length) ?? [];\n }\n let positions = ploc[pbasVersion] ?? [];\n if (positions.length !== seq.length) {\n positions =\n Object.keys(ploc)\n .map(Number)\n .map(v => ploc[v])\n .find(pp => pp.length === seq.length) ?? [];\n }\n baseCalls = { sequence: seq, confidences, positions, pbasVersion };\n }\n\n // SPAC fallback: derive from PLOC positions or DATA9 length when missing.\n if (!Number.isFinite(metadata.samplingRate) || (metadata.samplingRate ?? 0) <= 0) {\n const pos = baseCalls?.positions;\n const data9Len = Math.max(data9To12.A.length, data9To12.C.length, data9To12.G.length, data9To12.T.length);\n if (pos && pos.length > 1) {\n metadata.samplingRate = (pos[pos.length - 1] - pos[0]) / (pos.length - 1);\n } else if (baseCalls && baseCalls.sequence.length > 0 && data9Len > 0) {\n metadata.samplingRate = data9Len / baseCalls.sequence.length;\n }\n }\n\n const chromatogram: AbifChromatogramBundle = { baseOrder, dataChannels, data1To4, data9To12 };\n\n return {\n fileName,\n fileSize: bytes.byteLength,\n abifVersion: file.version,\n macBinaryOffset: file.macBinaryOffset,\n dirEntryCount: file.entries.length,\n metadata,\n chromatogram,\n baseCalls,\n baseCallVariants,\n entries,\n };\n}\n\n/** True when any channel has at least one signal value. */\nexport function hasSignals(s: ChannelSignals): boolean {\n return s.A.length > 0 || s.C.length > 0 || s.G.length > 0 || s.T.length > 0;\n}\n\n/** Length of the longest channel in a ChannelSignals bundle. */\nexport function channelMaxLength(s: ChannelSignals): number {\n return Math.max(s.A.length, s.C.length, s.G.length, s.T.length);\n}\n\n// Quiet unused-import for the AbifEntry type if it isn't reachable elsewhere.\nexport type { AbifEntry };\n","/**\n * Mutation helpers for AbifFile: write PBAS/PCON/PLOC/SPAC and ensure DATA9..12\n * are present. Used by basecallers to author ABIF output.\n */\n\nimport { findEntry, upsertEntry } from './abif-format';\nimport { asciiBytes, asDataView } from './bytes';\nimport { AbifFile } from './types';\nimport { hasData9To12Block } from './view';\n\n/** Set PBAS2 (replaces if present). */\nexport function setSequence(file: AbifFile, sequence: string): void {\n upsertEntry(file, 'PBAS', 2, asciiBytes(sequence), {\n elementType: 2, // char\n elementSize: 1,\n elementCount: sequence.length,\n });\n}\n\n/** Set PCON2 (replaces if present). Values clamped to [0, 255]. */\nexport function setConfidences(file: AbifFile, q: ArrayLike<number>): void {\n const buf = new Uint8Array(q.length);\n for (let i = 0; i < q.length; i++) {\n buf[i] = Math.max(0, Math.min(255, Math.round(q[i])));\n }\n upsertEntry(file, 'PCON', 2, buf, {\n elementType: 2,\n elementSize: 1,\n elementCount: q.length,\n });\n}\n\n/**\n * Set PLOC2 (replaces if present).\n *\n * Written as UNSIGNED int16 so positions up to 65535 are preserved on disk\n * (signed int16 would wrap on traces with > 32k scans).\n */\nexport function setPositions(file: AbifFile, positions: ArrayLike<number>): void {\n const buf = new Uint8Array(positions.length * 2);\n const view = asDataView(buf);\n for (let i = 0; i < positions.length; i++) {\n view.setUint16(i * 2, Math.max(0, Math.min(0xffff, positions[i])), false);\n }\n upsertEntry(file, 'PLOC', 2, buf, {\n elementType: 4,\n elementSize: 2,\n elementCount: positions.length,\n });\n}\n\n/**\n * Set SPAC/1, SPAC/2, SPAC/3 — the standard ABIF \"average peak spacing\" trio\n * that KB-basecaller writes and downstream tools (BioPython, Sequencher,\n * KB-aware viewers) expect:\n *\n * - SPAC/1 (float32) — average peak spacing used in last analysis.\n * - SPAC/2 (pString) — basecaller name / identifier.\n * - SPAC/3 (float32) — average peak spacing computed by the basecaller.\n *\n * Both float fields are written with the same value.\n */\nexport function setAveragePeakSpacing(file: AbifFile, spacing: number, basecallerName: string): void {\n const f1 = new Uint8Array(4);\n asDataView(f1).setFloat32(0, spacing, false);\n upsertEntry(file, 'SPAC', 1, f1, { elementType: 7, elementSize: 4, elementCount: 1 });\n\n const nameBytes = asciiBytes(basecallerName);\n const len = Math.min(255, nameBytes.length);\n const p = new Uint8Array(1 + len);\n p[0] = len;\n p.set(nameBytes.subarray(0, len), 1);\n upsertEntry(file, 'SPAC', 2, p, { elementType: 18, elementSize: 1, elementCount: 1 + len });\n\n const f3 = new Uint8Array(4);\n asDataView(f3).setFloat32(0, spacing, false);\n upsertEntry(file, 'SPAC', 3, f3, { elementType: 7, elementSize: 4, elementCount: 1 });\n}\n\n/**\n * Mean consecutive peak-to-peak distance in scans, from a positions array.\n * Returns 0 when fewer than 2 positions are present.\n */\nexport function averagePeakSpacing(positions: ArrayLike<number>): number {\n if (positions.length < 2) return 0;\n return (positions[positions.length - 1] - positions[0]) / (positions.length - 1);\n}\n\n/**\n * Ensure DATA9..12 are present in the file. Many downstream consumers\n * (BioPython-style readers, viewers) read the chromatogram signal from\n * DATA9..12 by convention — these tags are the raw fluorescence on newer\n * instruments. Older files that only carry DATA1..8 break those consumers\n * with a \"no signal\" error after re-basecalling.\n *\n * We populate DATA9..12 by copying DATA1..4 (which on DATA1..8-only files IS\n * the raw signal). The DATA1..4 tags are left untouched so any tool that\n * reads them keeps working.\n *\n * No-op when DATA9..12 already exist.\n */\nexport function ensureRawDataChannels(file: AbifFile): void {\n if (hasData9To12Block(file)) return;\n for (let i = 1; i <= 4; i++) {\n const src = findEntry(file, 'DATA', i);\n if (!src) continue;\n const target = 8 + i;\n if (findEntry(file, 'DATA', target)) continue;\n file.entries.push({\n tagName: 'DATA',\n tagNumber: target,\n elementType: src.elementType,\n elementSize: src.elementSize,\n elementCount: src.elementCount,\n payload: new Uint8Array(src.payload),\n dataHandle: 0,\n });\n }\n}\n","/**\n * FASTA / FASTQ / .qual text serialization.\n *\n * Pure, format-level writers: they turn a sequence plus optional per-base Phred\n * quality into text. No coupling to any binary format — callers build records\n * from ABIF basecalls (PBAS/PCON), alignments, consensus, etc.\n *\n * Quality is encoded as Phred+33 (Sanger / Illumina 1.8+). Scores are clamped\n * to [0, {@link MAX_PHRED}]: the upper bound is the largest value representable\n * as Phred+33 ('~' = ASCII 126 = 93 + 33). Callers must NOT feed quality for\n * reads that lack it — gate on {@link hasUsableQuality} and emit FASTA only,\n * rather than letting the 255 \"no quality\" sentinel clamp to a perfect '~'.\n */\n\n/** Largest Phred score representable as Phred+33 ('~' = ASCII 126 = 93 + 33). */\nexport const MAX_PHRED = 93;\n\nconst PHRED_OFFSET = 33;\nconst DEFAULT_LINE_WIDTH = 60;\nconst NO_QUALITY = 255;\n\n/** A FASTA record: identifier, optional description, and residues. */\nexport interface FastaRecord {\n /** Identifier written after '>', up to the first space. */\n id: string;\n /** Optional free text after the id on the header line. */\n description?: string;\n /** Residues, written verbatim (case and gaps preserved). */\n sequence: string;\n}\n\n/** A FASTQ record: a {@link FastaRecord} plus one Phred score per residue. */\nexport interface FastqRecord extends FastaRecord {\n /** Per-base Phred scores; must be one per residue in {@link FastaRecord.sequence}. */\n qualities: readonly number[];\n}\n\n/** A .qual record: identifier, optional description, and per-base Phred scores. */\nexport interface QualRecord {\n id: string;\n description?: string;\n qualities: readonly number[];\n}\n\n/** Line-wrapping shared by the FASTA and .qual writers. */\nexport interface WrapOptions {\n /** Residues (FASTA) or scores (.qual) per line; <= 0 writes one line. Default 60. */\n lineWidth?: number;\n}\n\n/** Serialize one or more records to FASTA text (trailing newline included). */\nexport function formatFasta(records: FastaRecord | readonly FastaRecord[], options?: WrapOptions): string {\n const width = options?.lineWidth ?? DEFAULT_LINE_WIDTH;\n return toArray(records)\n .map(r => `${headerLine('>', r.id, r.description)}\\n${wrapResidues(r.sequence, width)}`)\n .join('');\n}\n\n/** Serialize one or more records to FASTQ text, Phred+33 (trailing newline included). */\nexport function formatFastq(records: FastqRecord | readonly FastqRecord[]): string {\n return toArray(records).map(formatFastqRecord).join('');\n}\n\n/** Serialize one or more records to .qual text: space-separated Phred ints, wrapped. */\nexport function formatQual(records: QualRecord | readonly QualRecord[], options?: WrapOptions): string {\n const width = options?.lineWidth ?? DEFAULT_LINE_WIDTH;\n return toArray(records)\n .map(r => `${headerLine('>', r.id, r.description)}\\n${wrapScores(r.qualities, width)}`)\n .join('');\n}\n\n/**\n * Report whether quality scores are present and usable. False for missing or\n * empty scores and for the all-255 sentinel (ABIF PCON uses 255 for \"no\n * quality\"), so a caller can offer FASTA only instead of inventing perfect Q.\n */\nexport function hasUsableQuality(qualities?: readonly number[]): boolean {\n return !!qualities && qualities.length > 0 && !qualities.every(q => q === NO_QUALITY);\n}\n\n/** Build one FASTQ record; the '+' separator is left bare (no id repeat). */\nfunction formatFastqRecord(record: FastqRecord): string {\n const { id, description, sequence, qualities } = record;\n if (qualities.length !== sequence.length) {\n throw new Error(`FASTQ ${id}: ${qualities.length} quality scores for ${sequence.length} bases`);\n }\n const quality = qualities.map(phredToChar).join('');\n return `${headerLine('@', id, description)}\\n${sequence}\\n+\\n${quality}\\n`;\n}\n\n/** Join id + optional description into a header line; reject embedded newlines. */\nfunction headerLine(prefix: '>' | '@', id: string, description?: string): string {\n const name = description ? `${id} ${description}` : id;\n if (name.includes('\\n')) {\n throw new Error('FASTX header must not contain a newline');\n }\n return prefix + name;\n}\n\n/** Wrap residues to `width` per line; an empty sequence yields no body line. */\nfunction wrapResidues(sequence: string, width: number): string {\n if (sequence.length === 0) return '';\n if (width <= 0 || sequence.length <= width) return `${sequence}\\n`;\n let out = '';\n for (let i = 0; i < sequence.length; i += width) {\n out += `${sequence.slice(i, i + width)}\\n`;\n }\n return out;\n}\n\n/** Wrap clamped Phred ints to `width` per line, space-separated. */\nfunction wrapScores(qualities: readonly number[], width: number): string {\n if (qualities.length === 0) return '';\n const values = qualities.map(clampPhred);\n const perLine = width <= 0 ? values.length : width;\n let out = '';\n for (let i = 0; i < values.length; i += perLine) {\n out += `${values.slice(i, i + perLine).join(' ')}\\n`;\n }\n return out;\n}\n\n/** Round and clamp a score to the Phred+33 range [0, MAX_PHRED]. */\nfunction clampPhred(q: number): number {\n const r = Math.round(q);\n return r < 0 ? 0 : r > MAX_PHRED ? MAX_PHRED : r;\n}\n\n/** Encode one Phred score as a Phred+33 ASCII character. */\nfunction phredToChar(q: number): string {\n return String.fromCharCode(clampPhred(q) + PHRED_OFFSET);\n}\n\n/** Normalize a single record or array into a readonly array. */\nfunction toArray<T>(value: T | readonly T[]): readonly T[] {\n // Array.isArray does not narrow readonly arrays, so cast the single-value branch.\n return Array.isArray(value) ? value : [value as T];\n}\n"]}
1
+ {"version":3,"sources":["../src/abif/bytes.ts","../src/abif/abif-format.ts","../src/abif/view.ts","../src/abif/abif-op-crop.ts","../src/abif/parser.ts","../src/abif/setters.ts","../src/fastx.ts"],"names":["asciiString","bytes","s","i","asciiBytes","out","asDataView","subview","start","length","tagNameFromInt32","n","HEADER_SIZE","ENTRY_SIZE","readAbif","macBinaryOffset","base","view","version","dirEntry","decodeEntry","rawDirCount","numEntries","dirOffset","entries","dirDataSize","entriesEnd","padLen","tdir","headerReserved","macBinaryHeader","unreferencedRanges","computeUnreferencedRanges","total","covered","dirCovered","e","norm","en","a","b","merged","last","gaps","cursor","off","tagName","tagNumber","elementType","elementSize","rawElementCount","declaredDataSize","dataHandle","computedDataSize","payloadSize","inline","elementCount","payload","dataOffset","at","dataOffsetBytes","writeAbif","file","originalCount","verbatimRaw","anchor","raw","r","dirGrew","freshOffsets","size","outView","writeDirRecord","dataSize","rec","staleTail","findEntry","name","number","findEntries","compareEntries","insertEntrySorted","entry","upsertEntry","defaults","existing","getDataChannel","arr","getFwo","isFwoPermutation","fwo","hasData9To12Block","dataChannelRole","getReverseComplemented","getChannelMap","getSequence","getSequenceForVersion","getConfidences","getConfidencesForVersion","getPositions","getPositionsForVersion","getSamplingRate","v","cropAbif","range","options","end","processedLength","entryElementCount","rawTrace","cropDataEntry","basecallVersionsIn","cropBasecallVersion","versions","sequence","positions","confidences","kept","croppedSequence","croppedPositions","encodeUnsignedShorts","croppedConfidences","values","buf","TYPE_NAMES","typeName","t","previewNumbers","max","truncate","previewBytes","slice","hex","asNumbers","d","decodeNumeric","byteLength","read","decodePayload","o","year","month","day","len","previewDecoded","hour","minute","second","parseAbif","input","fileName","decoded","baseOrder","dataChannels","data1To4","data9To12","metadata","pbas","pcon","ploc","channelKey","idx","nums","baseCallVariants","baseCalls","pbasVersion","seq","c","pp","pos","data9Len","chromatogram","hasSignals","channelMaxLength","setSequence","setConfidences","q","setPositions","setAveragePeakSpacing","spacing","basecallerName","f1","nameBytes","p","f3","averagePeakSpacing","ensureRawDataChannels","src","target","MAX_PHRED","formatFasta","records","width","toArray","headerLine","wrapResidues","formatFastq","formatFastqRecord","formatQual","wrapScores","hasUsableQuality","qualities","record","id","description","quality","phredToChar","prefix","clampPhred","perLine","value"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Tiny binary helpers used across the ABIF reader/writer.\n *\n * Everything here operates on Uint8Array + DataView so the same code runs in\n * Node (where Buffer extends Uint8Array) and the browser.\n */\n\nexport function asciiString(bytes: Uint8Array): string {\n let s = '';\n for (let i = 0; i < bytes.length; i++) s += String.fromCharCode(bytes[i]);\n return s;\n}\n\nexport function asciiBytes(s: string): Uint8Array {\n const out = new Uint8Array(s.length);\n for (let i = 0; i < s.length; i++) out[i] = s.charCodeAt(i) & 0xff;\n return out;\n}\n\n/** Returns a DataView over the given bytes, regardless of input shape. */\nexport function asDataView(bytes: Uint8Array): DataView {\n return new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);\n}\n\n/** Returns a Uint8Array view over a slice; never copies. */\nexport function subview(bytes: Uint8Array, start: number, length: number): Uint8Array {\n return bytes.subarray(start, start + length);\n}\n\n/** Tag name encoded as a big-endian uint32 (e.g. \"DATA\" → 0x44415441). */\nexport function tagNameToInt32(tag: string): number {\n return (\n ((tag.charCodeAt(0) & 0xff) << 24) |\n ((tag.charCodeAt(1) & 0xff) << 16) |\n ((tag.charCodeAt(2) & 0xff) << 8) |\n (tag.charCodeAt(3) & 0xff)\n );\n}\n\nexport function tagNameFromInt32(n: number): string {\n return String.fromCharCode((n >>> 24) & 0xff, (n >>> 16) & 0xff, (n >>> 8) & 0xff, n & 0xff);\n}\n","/**\n * Raw layer: the ABIF byte<->struct codec. Every directory entry (including unknown\n * vendor tags) is preserved as a raw payload (Uint8Array), and writeAbif() reproduces\n * the original bytes exactly for an unmodified round-trip (see its own doc comment).\n * The domain layer (view.ts, setters.ts, parser.ts, abif-op-*.ts) provides typed,\n * format-aware access on top of this — this file knows nothing about what any tag\n * means.\n *\n * ABIF file layout:\n * [0..3] \"ABIF\" magic\n * [4..5] version (int16 BE; 101 = v1.01)\n * [6..33] TdirEntry describing the directory itself\n * [34..127] reserved (94 bytes, zero-filled)\n * [...] directory block (N * 28-byte entries) and payload blocks\n *\n * TdirEntry (28 bytes, big-endian):\n * off size field\n * 0 4 tagName (ASCII)\n * 4 4 tagNumber (int32)\n * 8 2 elementType (int16)\n * 10 2 elementSize (int16)\n * 12 4 elementCount (int32)\n * 16 4 dataSize (int32; total payload bytes — authoritative; for\n * well-formed entries equals count*size, but user/\n * opaque types may differ, so we read by dataSize)\n * 20 4 dataOffset (int32) OR inline data if dataSize <= 4\n * 24 4 dataHandle (int32; usually 0)\n *\n * Inline rule (per ABIF spec): when the declared dataSize <= 4 the payload bytes\n * are stored directly in the dataOffset field (left-aligned, padded to 4 bytes).\n *\n * MacBinary preamble: some ABIF files (older Mac-origin) start with a 128-byte\n * MacBinary header before the actual ABIF magic. We detect and skip it.\n */\n\nimport { asciiBytes, asciiString, asDataView, subview, tagNameFromInt32 } from './bytes';\nimport { AbifByteRange, AbifDirectory, AbifEntry, AbifEntryRaw, AbifFile } from './types';\n\nexport const HEADER_SIZE = 128;\nexport const ENTRY_SIZE = 28;\n\n/**\n * Parse an ABIF file from raw bytes into its verbatim directory structure.\n *\n * This is the RAW source of truth: it reads the tdir header and every entry as\n * stored — real dataSize, dataOffset, numElements (see `entry.raw`), the 4 inline\n * bytes, and the tdir/directory metadata — and interprets nothing. For a\n * high-level, opinionated view (typed channels, basecalls, metadata) layer\n * {@link parseAbif} on top.\n *\n * Accepts Uint8Array (works in Node and the browser). Node's Buffer extends\n * Uint8Array, so `readAbif(buffer)` and `readAbif(new Uint8Array(arrayBuffer))`\n * both work.\n *\n * Throws if the magic header is missing. Does NOT require any specific tags\n * (PBAS, DATA, ...) to be present — raw pre-basecalled files are supported.\n */\nexport function readAbif(bytes: Uint8Array): AbifFile {\n if (bytes.byteLength < HEADER_SIZE) {\n throw new Error(`ABIF too small: ${bytes.byteLength} bytes`);\n }\n\n // MacBinary wrap support: skip 128 bytes if magic is at offset 128.\n let macBinaryOffset = 0;\n if (asciiString(subview(bytes, 0, 4)) !== 'ABIF') {\n if (bytes.byteLength >= 128 + 4 && asciiString(subview(bytes, 128, 4)) === 'ABIF') {\n macBinaryOffset = 128;\n } else {\n throw new Error('Not an ABIF file: missing \"ABIF\" magic.');\n }\n }\n const base = macBinaryOffset;\n // After skipping any MacBinary wrap, the ABIF part itself must still hold a full 128-byte header;\n // otherwise reading version/tdir below would run past the DataView (a raw RangeError, not ours).\n if (bytes.byteLength - base < HEADER_SIZE) {\n throw new Error(`ABIF too small: ${bytes.byteLength - base} bytes after offset ${base}`);\n }\n const view = asDataView(bytes);\n\n const version = view.getInt16(base + 4, false);\n\n // Header bytes [base+6 .. base+34) are a TdirEntry describing the directory itself.\n const dirEntry = decodeEntry(bytes, view, base + 6, base);\n if (dirEntry.tagName !== 'tdir') {\n throw new Error(`Expected \"tdir\" header entry, got \"${dirEntry.tagName}\"`);\n }\n if (dirEntry.elementSize !== ENTRY_SIZE) {\n throw new Error(`Expected dir element size ${ENTRY_SIZE}, got ${dirEntry.elementSize}`);\n }\n\n // The directory's numElements (raw) is the authoritative entry count — like BioPython, we trust\n // it rather than clamp against tdir.dataSize, which is a redundant byte-count that some writers\n // desync. Physical bounds are enforced below; a negative/garbage count just yields 0 entries.\n const rawDirCount = dirEntry.raw?.elementCount ?? dirEntry.elementCount;\n const numEntries = Math.max(0, rawDirCount);\n // tdir.dataSize is always > 4 (28*N), so the dataOffset field is an external offset.\n const dirOffset = view.getInt32(base + 6 + 20, false);\n if (dirOffset < 0 || dirOffset + numEntries * ENTRY_SIZE > bytes.byteLength - base) {\n throw new Error(\n `Directory out of bounds: offset=${dirOffset}, entries=${numEntries}, file=${bytes.byteLength - base}`,\n );\n }\n\n const entries: AbifEntry[] = [];\n for (let i = 0; i < numEntries; i++) {\n entries.push(decodeEntry(bytes, view, base + dirOffset + i * ENTRY_SIZE, base));\n }\n\n // Root directory (tdir) header, as read — its dataSize may exceed numEntries*28 (directory padding).\n const dirDataSize = dirEntry.raw?.dataSize ?? numEntries * ENTRY_SIZE;\n const entriesEnd = base + dirOffset + numEntries * ENTRY_SIZE;\n const padLen = Math.min(\n Math.max(0, dirDataSize - numEntries * ENTRY_SIZE),\n Math.max(0, bytes.byteLength - entriesEnd),\n );\n const tdir: AbifDirectory = {\n entryCount: numEntries, // effective count actually read (== entries.length)\n rawEntryCount: rawDirCount, // tdir numElements verbatim, before any reconciliation\n elementType: dirEntry.elementType, // 1023 (tdir)\n tagNumber: dirEntry.tagNumber, // usually 1\n entrySize: dirEntry.elementSize,\n dataSize: dirDataSize,\n dataOffset: dirOffset,\n dataOffsetBytes: dirEntry.raw?.dataOffsetBytes ?? new Uint8Array(4),\n dataHandle: dirEntry.dataHandle,\n paddingBytes: new Uint8Array(subview(bytes, entriesEnd, padLen)),\n };\n\n // Reserved header bytes [base+34 .. base+128) — verbatim, so a raw reader keeps the whole header.\n const headerReserved = new Uint8Array(subview(bytes, base + 6 + ENTRY_SIZE, HEADER_SIZE - 6 - ENTRY_SIZE));\n\n // The MacBinary preamble bytes themselves, when present — verbatim, so the wrapper is reproducible.\n const macBinaryHeader = macBinaryOffset === 128 ? new Uint8Array(subview(bytes, 0, 128)) : undefined;\n\n const unreferencedRanges = computeUnreferencedRanges(bytes, base, dirOffset, dirDataSize, entries, macBinaryOffset);\n\n return { version, tdir, entries, macBinaryOffset, macBinaryHeader, headerReserved, unreferencedRanges };\n}\n\n/**\n * Find the file's physical byte ranges that no header/directory/entry payload covers — orphaned\n * blocks, trailing padding, etc. Computes the complement of every referenced interval so a raw\n * reader can account for all bytes without the writer having to be byte-exact.\n */\nfunction computeUnreferencedRanges(\n bytes: Uint8Array,\n base: number,\n dirOffset: number,\n dirDataSize: number,\n entries: AbifEntry[],\n macBinaryOffset: number,\n): AbifByteRange[] {\n const total = bytes.byteLength;\n const covered: Array<[number, number]> = [];\n if (macBinaryOffset === 128) covered.push([0, 128]); // preamble\n covered.push([base, base + HEADER_SIZE]); // 128-byte header (magic/version/tdir/reserved)\n // Directory spans the bytes actually read (numElements entries) OR the declared dataSize when it is\n // larger (padding) — whichever is bigger, so a desynced dataSize < numElements*28 doesn't mislabel\n // already-read entries as orphan bytes. A negative dataSize collapses to the physical entry span.\n const dirCovered = Math.max(entries.length * ENTRY_SIZE, Math.max(0, dirDataSize));\n covered.push([base + dirOffset, base + dirOffset + dirCovered]);\n for (const e of entries) {\n if (e.raw && !e.raw.inline) {\n const start = base + e.raw.dataOffset;\n covered.push([start, start + e.payload.byteLength]); // external payload\n }\n }\n\n const norm = covered\n .map(([s, en]): [number, number] => [Math.max(0, Math.min(s, total)), Math.max(0, Math.min(en, total))])\n .filter(([s, en]) => en > s)\n .sort((a, b) => a[0] - b[0]);\n\n const merged: Array<[number, number]> = [];\n for (const [s, en] of norm) {\n const last = merged[merged.length - 1];\n if (last && s <= last[1]) last[1] = Math.max(last[1], en);\n else merged.push([s, en]);\n }\n\n const gaps: AbifByteRange[] = [];\n let cursor = 0;\n for (const [s, en] of merged) {\n if (s > cursor) gaps.push({ offset: cursor, bytes: new Uint8Array(subview(bytes, cursor, s - cursor)) });\n cursor = Math.max(cursor, en);\n }\n if (cursor < total) gaps.push({ offset: cursor, bytes: new Uint8Array(subview(bytes, cursor, total - cursor)) });\n return gaps;\n}\n\n/**\n * Decode a 28-byte TdirEntry at the given absolute byte offset.\n *\n * Two robustness measures applied here that BioPython also uses and that real\n * ABIF files in the wild require:\n *\n * 1. The payload is exactly `dataSize` bytes — the authoritative directory field.\n * ABIF allows `numElements * elementSize != dataSize` for user/opaque types,\n * so we never derive the payload length from count*size (that both truncates\n * a larger declared payload and over-reads a smaller one).\n *\n * 2. Inline vs external follows the spec: inline iff `dataSize <= 4` (the payload\n * fits in the 4-byte dataOffset field). Data > 4 bytes is always external,\n * even when count*size <= 4. We fall back to count*size only when the declared\n * field is negative/garbage.\n *\n * 3. `elementCount` is reconciled down to what the payload can hold, so a desynced\n * (over-large) count can't drive readers past the real bytes.\n *\n * 4. External payload offsets are relative to the ABIF start, so we add `base`\n * (the MacBinary preamble length) when reading them.\n */\nfunction decodeEntry(bytes: Uint8Array, view: DataView, off: number, base: number): AbifEntry {\n const tagName = asciiString(subview(bytes, off, 4));\n const tagNumber = view.getInt32(off + 4, false);\n const elementType = view.getInt16(off + 8, false);\n const elementSize = view.getInt16(off + 10, false);\n const rawElementCount = view.getInt32(off + 12, false);\n const declaredDataSize = view.getInt32(off + 16, false);\n const dataHandle = view.getInt32(off + 24, false);\n\n const computedDataSize = Math.max(0, rawElementCount * Math.max(0, elementSize));\n // Payload length is the declared dataSize; a negative/garbage declared field falls back to the\n // computed count*size (consistent with the inline decision below).\n const payloadSize = declaredDataSize >= 0 ? declaredDataSize : computedDataSize;\n // Inline iff dataSize <= 4; fall back to computed size only for an invalid declared field.\n const inline = declaredDataSize >= 0 ? declaredDataSize <= 4 : computedDataSize <= 4;\n // Reconcile the element count down to what the payload holds, and never expose a negative count\n // (a malformed numElements would otherwise crash Array/TypedArray helpers downstream). When\n // elementSize <= 0 the per-element stride is unknown, so cap by payloadSize (≤ 1 byte/element)\n // rather than trusting the raw count — otherwise a typed getter reads past a 0-byte payload.\n const elementCount = Math.max(\n 0,\n elementSize > 0\n ? Math.min(rawElementCount, Math.floor(payloadSize / elementSize))\n : Math.min(rawElementCount, payloadSize),\n );\n\n let payload: Uint8Array;\n let dataOffset: number;\n if (inline) {\n dataOffset = -1;\n payload = new Uint8Array(subview(bytes, off + 20, Math.min(4, payloadSize)));\n } else {\n dataOffset = view.getInt32(off + 20, false);\n const at = base + dataOffset;\n if (dataOffset < 0 || at + payloadSize > bytes.byteLength) {\n throw new Error(\n `Entry ${tagName}${tagNumber}: payload out of bounds (offset=${dataOffset}, size=${payloadSize})`,\n );\n }\n payload = new Uint8Array(subview(bytes, at, payloadSize));\n }\n\n // The raw 4 bytes of the data/offset slot, verbatim (payload+padding when inline, offset when external).\n const dataOffsetBytes = new Uint8Array(subview(bytes, off + 20, 4));\n\n return {\n tagName,\n tagNumber,\n elementType,\n elementSize,\n elementCount,\n payload,\n dataHandle,\n raw: { elementCount: rawElementCount, dataSize: declaredDataSize, dataOffset, inline, dataOffsetBytes },\n };\n}\n\n/**\n * Serialize an AbifFile back to a Uint8Array.\n *\n * Byte-exact on an unmodified round-trip for well-formed records and the tolerated\n * count/dataSize desyncs readAbif() accepts: readAbif() followed right back by\n * writeAbif(), with nothing touched in between, reproduces the original bytes\n * exactly (a MacBinary-wrapped input round-trips its ABIF payload byte-exact, but\n * the preamble itself is never re-added — see the AGENTS.md note on why). The one\n * exception is a genuinely invalid negative `dataSize`/`numElements` field (readAbif\n * tolerates these defensively, falling back to a computed size, but never treats them\n * as verbatim-eligible on write — see the byteLength check below) — such an entry\n * round-trips meaning-lossless (correct payload/content) but its declared dataSize\n * field gets normalized to the real payload length rather than reproducing the\n * original garbage value.\n *\n * This works by keeping every entry whose payload size hasn't changed since it was\n * read (`entry.raw` present — upsertEntry() clears it on any mutation — and\n * `payload.byteLength === raw.dataSize`) at its exact original directory slot and\n * file offset, writing the *original* on-disk numElements/dataSize/offset-or-inline-\n * padding instead of the reconciled/current ones. A new or resized entry is appended\n * past the highest byte offset still known to hold preserved content (every verbatim\n * entry's span, the directory, and any unreferenced range); only its own directory\n * record changes, so every other entry's bytes stay untouched. A resized/removed\n * entry's *old* span is not itself reserved — nothing points at it anymore, so it is\n * free to be reused by whatever gets appended next; the output is not padded out to\n * the original file's true end.\n *\n * The directory is kept at its original file offset as long as the entry count\n * didn't grow (removing entries just shortens it in place; the original directory\n * padding is only reused when the count is exactly unchanged, since a shorter\n * directory can't reuse padding sized for more entries). Only a growing entry count\n * relocates the whole directory to freshly appended space.\n */\nexport function writeAbif(file: AbifFile): Uint8Array {\n const base = file.macBinaryOffset;\n const numEntries = file.entries.length;\n const originalCount = file.tdir.entryCount;\n\n // An entry is verbatim-eligible when its payload is exactly the size it was read\n // at — the only case where its original directory record/offset can be reused.\n const verbatimRaw: Array<AbifEntryRaw | undefined> = file.entries.map(e =>\n e.raw && e.payload.byteLength === e.raw.dataSize ? e.raw : undefined,\n );\n\n // Anchor: the highest byte offset known to belong to the original (unwrapped)\n // file — header, directory span, every verbatim entry's external payload, and any\n // orphan byte range. Fresh content is appended after this, so an unmodified\n // round-trip never appends anything and the output ends exactly here.\n let anchor = HEADER_SIZE;\n // A malformed original can declare tdir.dataSize smaller than the entries actually occupy\n // (readAbif trusts numElements over dataSize — see the \"desynced tdir.dataSize\" test); the\n // *physical* directory span must still be protected even though the reused dataSize field\n // below intentionally reproduces the original (desynced) declared value byte-for-byte.\n anchor = Math.max(anchor, file.tdir.dataOffset + Math.max(file.tdir.dataSize, originalCount * ENTRY_SIZE));\n for (const raw of verbatimRaw) {\n if (raw && !raw.inline) anchor = Math.max(anchor, raw.dataOffset + raw.dataSize);\n }\n for (const r of file.unreferencedRanges) {\n anchor = Math.max(anchor, r.offset - base + r.bytes.length);\n }\n\n // Directory placement: reuse the original slot unless the entry count grew past it.\n const dirGrew = numEntries > originalCount;\n let cursor = anchor;\n const dirOffset = dirGrew ? cursor : file.tdir.dataOffset;\n const dirDataSize = numEntries === originalCount ? file.tdir.dataSize : numEntries * ENTRY_SIZE;\n if (dirGrew) cursor += dirDataSize;\n\n // Fresh (non-verbatim) external payloads are appended past the anchor, in entry order.\n const freshOffsets: number[] = new Array(numEntries);\n for (let i = 0; i < numEntries; i++) {\n const size = file.entries[i].payload.byteLength;\n if (verbatimRaw[i] || size <= 4) {\n freshOffsets[i] = -1; // reused verbatim placement, or inline — no fresh external slot\n continue;\n }\n freshOffsets[i] = cursor;\n cursor += size;\n }\n\n const out = new Uint8Array(cursor);\n const outView = asDataView(out);\n\n // Header: \"ABIF\" + version (int16 BE) + tdir entry (below) + reserved bytes verbatim.\n out.set(asciiBytes('ABIF'), 0);\n outView.setInt16(4, file.version, false);\n out.set(file.headerReserved, 6 + ENTRY_SIZE);\n writeDirRecord(out, outView, 6, {\n tagName: 'tdir',\n tagNumber: file.tdir.tagNumber,\n elementType: file.tdir.elementType,\n elementSize: file.tdir.entrySize,\n elementCount: numEntries,\n dataSize: dirDataSize,\n dataHandle: file.tdir.dataHandle,\n offsetSlot: { kind: 'external', value: dirOffset },\n });\n\n // Directory padding only carries over when the entry count is exactly unchanged.\n if (numEntries === originalCount && file.tdir.paddingBytes.length > 0) {\n out.set(file.tdir.paddingBytes, dirOffset + numEntries * ENTRY_SIZE);\n }\n\n for (let i = 0; i < numEntries; i++) {\n const e = file.entries[i];\n const raw = verbatimRaw[i];\n const off = dirOffset + i * ENTRY_SIZE;\n const dataSize = e.payload.byteLength;\n writeDirRecord(out, outView, off, {\n tagName: e.tagName,\n tagNumber: e.tagNumber,\n elementType: e.elementType,\n elementSize: e.elementSize,\n elementCount: raw ? raw.elementCount : e.elementCount,\n dataSize: raw ? raw.dataSize : dataSize,\n dataHandle: e.dataHandle,\n offsetSlot:\n dataSize <= 4\n ? { kind: 'inline', payload: e.payload, dataSize, staleTail: raw?.dataOffsetBytes }\n : { kind: 'external', value: raw ? raw.dataOffset : freshOffsets[i] },\n });\n if (dataSize > 4) {\n out.set(e.payload, raw ? raw.dataOffset : freshOffsets[i]);\n }\n }\n\n for (const r of file.unreferencedRanges) {\n out.set(r.bytes, r.offset - base);\n }\n\n return out;\n}\n\ntype OffsetSlot =\n | { kind: 'external'; value: number }\n | { kind: 'inline'; payload: Uint8Array; dataSize: number; staleTail?: Uint8Array };\n\nfunction writeDirRecord(\n out: Uint8Array,\n outView: DataView,\n off: number,\n rec: {\n tagName: string;\n tagNumber: number;\n elementType: number;\n elementSize: number;\n elementCount: number;\n dataSize: number;\n dataHandle: number;\n offsetSlot: OffsetSlot;\n },\n): void {\n if (rec.tagName.length !== 4) {\n throw new Error(`tagName must be 4 chars: \"${rec.tagName}\"`);\n }\n out.set(asciiBytes(rec.tagName), off);\n outView.setInt32(off + 4, rec.tagNumber, false);\n outView.setInt16(off + 8, rec.elementType, false);\n outView.setInt16(off + 10, rec.elementSize, false);\n outView.setInt32(off + 12, rec.elementCount, false);\n outView.setInt32(off + 16, rec.dataSize, false);\n if (rec.offsetSlot.kind === 'external') {\n outView.setInt32(off + 20, rec.offsetSlot.value, false);\n } else {\n // Inline: clear 4 bytes, place the payload, then restore any stale tail byte(s)\n // beyond dataSize from the original slot — a byte-exact round-trip needs them,\n // since they're not derivable from any semantic field.\n const { payload, dataSize, staleTail } = rec.offsetSlot;\n out.fill(0, off + 20, off + 24);\n out.set(payload.subarray(0, dataSize), off + 20);\n if (staleTail && dataSize < 4) {\n out.set(staleTail.subarray(dataSize, 4), off + 20 + dataSize);\n }\n }\n outView.setInt32(off + 24, rec.dataHandle, false);\n}\n\n// =====================================================================\n// Lookup / mutation helpers\n// =====================================================================\n\n/** Find an entry by name+number, or undefined. */\nexport function findEntry(file: AbifFile, name: string, number: number): AbifEntry | undefined {\n return file.entries.find(e => e.tagName === name && e.tagNumber === number);\n}\n\n/** Find all entries with the given tag name. */\nexport function findEntries(file: AbifFile, name: string): AbifEntry[] {\n return file.entries.filter(e => e.tagName === name);\n}\n\n/* Compare two directory records by ABIF directory order: tag name ascending\n * (ASCII bytes), then tag number ascending. */\nfunction compareEntries(a: AbifEntry, b: AbifEntry): number {\n if (a.tagName !== b.tagName) return a.tagName < b.tagName ? -1 : 1;\n return a.tagNumber - b.tagNumber;\n}\n\n/**\n * Insert a new entry at the slot that keeps the directory sorted by\n * (tagName, tagNumber) — the order genuine ABI instruments emit and the ABIF\n * spec prescribes. Readers that binary-search the directory (e.g. Chromas)\n * silently miss a tag appended out of order — a re-basecalled file loses its\n * quality bars because PCON2 is not found. Existing entries are never reordered,\n * so an unmodified file still round-trips byte-exact; only the freshly added tag\n * lands in its sorted place.\n *\n * Prefer {@link upsertEntry}; use this directly only to add an entry whose\n * payload intentionally desyncs from `elementCount * elementSize` (e.g. copying\n * a tolerated malformed record verbatim), which upsertEntry rejects.\n */\nexport function insertEntrySorted(entries: AbifEntry[], entry: AbifEntry): void {\n const at = entries.findIndex(e => compareEntries(e, entry) > 0);\n entries.splice(at < 0 ? entries.length : at, 0, entry);\n}\n\n/**\n * Replace the payload of an existing entry, or insert a new one in sorted\n * directory order. elementType/elementSize/elementCount must be supplied for\n * new entries.\n *\n * This is the required way to mutate an entry read from a file — it clears `.raw`\n * on replacement so writeAbif() never reuses a now-stale on-disk shape. Setting\n * `entry.payload`/`elementType`/`elementSize`/`elementCount` directly instead\n * leaves `.raw` behind and can corrupt the written directory record.\n */\nexport function upsertEntry(\n file: AbifFile,\n name: string,\n number: number,\n payload: Uint8Array,\n defaults: { elementType: number; elementSize: number; elementCount: number },\n): void {\n if (payload.byteLength !== defaults.elementCount * defaults.elementSize) {\n throw new Error(`upsertEntry ${name}${number}: payload length ${payload.byteLength} != count*size`);\n }\n const existing = findEntry(file, name, number);\n if (existing) {\n existing.elementType = defaults.elementType;\n existing.elementSize = defaults.elementSize;\n existing.elementCount = defaults.elementCount;\n existing.payload = payload;\n // `raw` describes the entry's shape as read from disk; once mutated it no longer applies —\n // clearing it forces writeAbif() to place this entry fresh rather than reuse a stale record\n // (e.g. a same-length content edit would otherwise silently keep the old elementCount/dataSize).\n existing.raw = undefined;\n } else {\n insertEntrySorted(file.entries, {\n tagName: name,\n tagNumber: number,\n elementType: defaults.elementType,\n elementSize: defaults.elementSize,\n elementCount: defaults.elementCount,\n payload,\n dataHandle: 0,\n });\n }\n}\n\n/** Re-export for users who want to interpret raw tag bytes themselves. */\nexport { tagNameFromInt32 };\n","/**\n * High-level typed view over an AbifFile.\n *\n * Reading helpers that interpret the raw payloads of well-known tags. For\n * mutation helpers (setSequence, setConfidences, ...) see ./setters.\n */\n\nimport { findEntry } from './abif-format';\nimport { asciiString, asDataView } from './bytes';\nimport { AbifDataChannelRole, AbifFile } from './types';\n\n/** Get DATA<n> as a signed-int16 array, or undefined. */\nexport function getDataChannel(file: AbifFile, n: number): Int16Array | undefined {\n const e = findEntry(file, 'DATA', n);\n if (!e) return undefined;\n if (e.elementSize !== 2) {\n throw new Error(`DATA${n}: expected elementSize=2, got ${e.elementSize}`);\n }\n const arr = new Int16Array(e.elementCount);\n const view = asDataView(e.payload);\n for (let i = 0; i < e.elementCount; i++) {\n arr[i] = view.getInt16(i * 2, false);\n }\n return arr;\n}\n\n/**\n * Dye order, 4 ASCII chars (e.g. \"GATC\"). Defaults to \"GATC\" if FWO_ absent.\n *\n * GATC is the dye order produced by modern ABI 3730/3500 instruments and the\n * dominant default in the wild. Older \"ACGT\" defaults caused channel\n * mis-mapping on files where FWO_ is missing or malformed.\n */\nexport function getFwo(file: AbifFile): string {\n const e = findEntry(file, 'FWO_', 1);\n if (!e) return 'GATC';\n // Read only the declared elements — payload may carry trailing padding beyond elementCount.\n return asciiString(e.payload.subarray(0, e.elementCount));\n}\n\n/**\n * Whether an FWO_ string is a genuine dye order: a permutation of A/C/G/T with all\n * four bases distinct. `\"GATC\"` passes; `\"AAAA\"` (regex-valid but degenerate) does\n * not — mapping four channels through it would collapse them onto one base.\n */\nexport function isFwoPermutation(fwo: string): boolean {\n return /^[ACGT]{4}$/.test(fwo) && new Set(fwo).size === 4;\n}\n\n/**\n * Fact: the file carries a second dye-trace block, DATA9..12 (all four tags), in\n * addition to DATA1..4. Reports presence only — it does NOT say which block is\n * raw and which is analyzed/processed; that convention isn't stored in the file.\n */\nexport function hasData9To12Block(file: AbifFile): boolean {\n return !!(\n findEntry(file, 'DATA', 9) &&\n findEntry(file, 'DATA', 10) &&\n findEntry(file, 'DATA', 11) &&\n findEntry(file, 'DATA', 12)\n );\n}\n\n/**\n * Spec-defined role of a DATA<n> tag, limited to the numbers the ABIF spec names:\n *\n * - `'trace'` — dye-signal channels: DATA1..4 (raw dyes 1-4), DATA9..12\n * (analyzed dyes 1-4), and the two optional 5th-dye blocks\n * DATA105 (raw dye 5) and DATA205 (analyzed dye 5).\n * - `'telemetry'` — DATA5..8: instrument run telemetry (voltage, current,\n * power, temperature), one value per scan — NOT dye signal.\n * - `'other'` — any other DATA number. The spec does not enumerate higher\n * extra-dye tags (106/206/…), so we don't claim a role for them.\n *\n * A fact from the ABIF specification, not an inference about content.\n */\nexport function dataChannelRole(n: number): AbifDataChannelRole {\n if (n >= 5 && n <= 8) return 'telemetry';\n if ((n >= 1 && n <= 4) || (n >= 9 && n <= 12) || n === 105 || n === 205) return 'trace';\n return 'other';\n}\n\n/**\n * Whether the file declares its sequence already reverse-complemented, from the\n * RevC1 flag (int16, non-zero = true). undefined when RevC1 is absent. Reported\n * as-is; the consumer decides how to act on it.\n */\nexport function getReverseComplemented(file: AbifFile): boolean | undefined {\n const e = findEntry(file, 'RevC', 1);\n if (!e) return undefined;\n const view = asDataView(e.payload);\n return e.payload.byteLength >= 2 ? view.getInt16(0, false) !== 0 : e.payload.some(b => b !== 0);\n}\n\n/**\n * Map from base letter (\"A\"|\"C\"|\"G\"|\"T\") to the DATA1..4 tag number that holds\n * its channel, using the dye order declared by FWO_. If FWO_=\"GATC\" then\n * G→1, A→2, T→3, C→4.\n *\n * This follows the file's own FWO_ declaration for the DATA1..4 block; it makes\n * no claim about whether that block is raw or processed.\n */\nexport function getChannelMap(file: AbifFile): Record<'A' | 'C' | 'G' | 'T', number> {\n const fwo = getFwo(file);\n if (!isFwoPermutation(fwo)) {\n throw new Error(`FWO_ is not a permutation of A/C/G/T: \"${fwo}\"`);\n }\n return {\n [fwo[0]]: 1,\n [fwo[1]]: 2,\n [fwo[2]]: 3,\n [fwo[3]]: 4,\n } as Record<'A' | 'C' | 'G' | 'T', number>;\n}\n\n/** Get PBAS sequence (prefer PBAS2 over PBAS1). undefined if neither present. */\nexport function getSequence(file: AbifFile): string | undefined {\n return getSequenceForVersion(file, 2) ?? getSequenceForVersion(file, 1);\n}\n\n/**\n * Get PBAS<version> exactly as stored — no called/edited preference, unlike\n * {@link getSequence}. Used where each basecall version must be handled on its\n * own (e.g. cropping every version a file carries, not just the preferred one).\n */\nexport function getSequenceForVersion(file: AbifFile, version: number): string | undefined {\n const e = findEntry(file, 'PBAS', version);\n if (!e) return undefined;\n // Bound by elementCount (payload may be padded) and drop trailing NULs, matching parseAbif.\n return asciiString(e.payload.subarray(0, e.elementCount)).replace(/\\0+$/g, '');\n}\n\n/**\n * Get per-base Phred-like quality scores (0..255 byte values, typically 0..60\n * for Sanger). Prefers PCON2 over PCON1.\n *\n * PCON is declared in the ABIF spec as elementType=2 (char) but the byte\n * values ARE the Q-scores — we read raw bytes regardless of declared type.\n */\nexport function getConfidences(file: AbifFile): number[] | undefined {\n return getConfidencesForVersion(file, 2) ?? getConfidencesForVersion(file, 1);\n}\n\n/**\n * Get PCON<version> exactly as stored — no called/edited preference, unlike\n * {@link getConfidences}. See {@link getSequenceForVersion} for why this exists.\n */\nexport function getConfidencesForVersion(file: AbifFile, version: number): number[] | undefined {\n const e = findEntry(file, 'PCON', version);\n if (!e) return undefined;\n const out: number[] = new Array(e.elementCount);\n for (let i = 0; i < e.elementCount; i++) out[i] = e.payload[i];\n return out;\n}\n\n/**\n * Get peak scan positions (one per base). Prefers PLOC2 over PLOC1.\n *\n * Read as UNSIGNED int16: PLOC indexes into the sample trace and is always\n * non-negative, but values > 32767 (long traces) would wrap to negative\n * if interpreted as signed.\n */\nexport function getPositions(file: AbifFile): number[] | undefined {\n return getPositionsForVersion(file, 2) ?? getPositionsForVersion(file, 1);\n}\n\n/**\n * Get PLOC<version> exactly as stored — no called/edited preference, unlike\n * {@link getPositions}. See {@link getSequenceForVersion} for why this exists.\n */\nexport function getPositionsForVersion(file: AbifFile, version: number): number[] | undefined {\n const e = findEntry(file, 'PLOC', version);\n if (!e) return undefined;\n if (e.elementSize !== 2) {\n throw new Error(`PLOC${version}: expected elementSize=2, got ${e.elementSize}`);\n }\n const view = asDataView(e.payload);\n const out: number[] = new Array(e.elementCount);\n for (let i = 0; i < e.elementCount; i++) out[i] = view.getUint16(i * 2, false);\n return out;\n}\n\n/**\n * Get average peak spacing (samples per base), from SPAC/1.\n *\n * ABIF spec defines SPAC as float32 (elementType=7); some legacy files\n * mislabel it as long (type=5). Both are 4 bytes and on disk the payload\n * is always a 32-bit float, so we read as float regardless of declared type.\n *\n * Returns undefined if SPAC is absent or non-positive.\n */\nexport function getSamplingRate(file: AbifFile): number | undefined {\n const e = findEntry(file, 'SPAC', 1);\n if (!e || e.elementSize !== 4 || e.payload.byteLength < 4) return undefined;\n const v = asDataView(e.payload).getFloat32(0, false);\n return Number.isFinite(v) && v > 0 ? v : undefined;\n}\n","/**\n * Domain-layer operation: crop an ABIF file to a sample range.\n *\n * `{ start, end }` is a half-open sample range in the DATA9..12 (processed/analyzed)\n * domain — the only domain PLOC maps into (see AGENTS.md's \"raw vs processed\" note).\n * DATA9..12 are sliced exactly by that range. DATA1..4/5..8 (raw dye trace and\n * instrument telemetry) have no honest sample-for-sample correspondence to the\n * processed domain (the mapping is non-linear mobility correction, not stored in the\n * file), so they are never approximated: `rawTrace` keeps them whole and untouched,\n * or omits them, never a proportional slice.\n *\n * Every basecall version the file carries (PBAS1/PCON1/PLOC1 \"edited\",\n * PBAS2/PCON2/PLOC2 \"called\", or any vendor version) is cropped independently by its\n * OWN PLOC — two versions are not guaranteed to share base positions or even length\n * (edits insert/delete bases), so there is no shared coordinate to crop them together\n * by. A version with no PLOC of its own cannot be cropped and is rejected rather than\n * silently dropped or left un-cropped.\n *\n * Everything else (metadata, FWO_, SPAC, ...) is carried over untouched — this is a\n * structural crop, not a re-derivation of run metadata for the new region.\n *\n * Reverse-complement is out of scope here; this function has no RC option.\n *\n * Returns a new, independently mutable AbifFile — the input is not mutated, and\n * neither is the output if the input is later touched. Untouched entries are\n * shallow-copied (a new AbifEntry object; the underlying payload bytes are shared,\n * which is safe since nothing ever mutates payload bytes in place — only replaces\n * them wholesale), so a later upsertEntry() on either file's copy of a shared tag\n * can't reach into the other file's entries.\n */\n\nimport { findEntry } from './abif-format';\nimport { asciiBytes, asDataView } from './bytes';\nimport { AbifEntry, AbifFile } from './types';\nimport { getConfidencesForVersion, getPositionsForVersion, getSequenceForVersion, hasData9To12Block } from './view';\n\nexport interface CropAbifRange {\n /** Inclusive start sample index into DATA9..12. */\n start: number;\n /** Exclusive end sample index into DATA9..12. */\n end: number;\n}\n\nexport interface CropAbifOptions {\n /**\n * DATA1..4 (raw dye trace) and DATA5..8 (telemetry): 'full' keeps them whole and\n * untouched (the exported file's raw trace no longer lines up sample-for-sample\n * with the cropped DATA9..12/PLOC, by design — see the module doc comment);\n * 'omit' drops them from the output entirely. Default 'omit'.\n */\n rawTrace?: 'full' | 'omit';\n}\n\n/** Crop an AbifFile to a DATA9..12 sample range. See the module doc comment for the model. */\nexport function cropAbif(file: AbifFile, range: CropAbifRange, options: CropAbifOptions = {}): AbifFile {\n const { start, end } = range;\n if (!Number.isInteger(start) || !Number.isInteger(end) || start < 0 || end <= start) {\n throw new Error(`cropAbif: invalid range [${start}, ${end})`);\n }\n if (!hasData9To12Block(file)) {\n throw new Error('cropAbif: no DATA9..12 block to crop — the range has nothing to apply to');\n }\n // The range's meaning is bounded by the processed trace itself: clamping a too-large `end`\n // instead of rejecting it would let a kept base's PLOC point past the (now shorter) cropped\n // DATA9..12 — a structurally inconsistent result. Bound by the shortest of the four channels,\n // in case a malformed file's DATA9..12 lengths ever disagree.\n const processedLength = Math.min(\n entryElementCount(file, 9),\n entryElementCount(file, 10),\n entryElementCount(file, 11),\n entryElementCount(file, 12),\n );\n if (end > processedLength) {\n throw new Error(`cropAbif: range end ${end} exceeds the processed trace length ${processedLength}`);\n }\n const rawTrace = options.rawTrace ?? 'omit';\n\n const entries: AbifEntry[] = [];\n for (const e of file.entries) {\n if (e.tagName === 'DATA' && e.tagNumber >= 9 && e.tagNumber <= 12) {\n entries.push(cropDataEntry(e, start, end));\n } else if (e.tagName === 'DATA' && e.tagNumber >= 1 && e.tagNumber <= 8) {\n // Shallow-copy so a later upsertEntry() on the cropped file's copy (mutates in place)\n // can never reach back and corrupt the input file's own entry object.\n if (rawTrace === 'full') entries.push({ ...e });\n } else if (e.tagName === 'PBAS' || e.tagName === 'PCON' || e.tagName === 'PLOC') {\n // Handled per-version below, once per version rather than once per tag.\n } else {\n entries.push({ ...e });\n }\n }\n\n for (const version of basecallVersionsIn(file)) {\n entries.push(...cropBasecallVersion(file, version, start, end));\n }\n\n return {\n version: file.version,\n tdir: file.tdir,\n entries,\n macBinaryOffset: 0,\n macBinaryHeader: undefined,\n headerReserved: file.headerReserved,\n // Orphan byte ranges belong to the pre-crop file's specific byte layout; carrying\n // them into a structurally different (smaller) file would preserve meaningless bytes.\n unreferencedRanges: [],\n };\n}\n\n/** DATA<n>'s elementCount, or 0 if absent — used to bound the requested range up front. */\nfunction entryElementCount(file: AbifFile, n: number): number {\n return findEntry(file, 'DATA', n)?.elementCount ?? 0;\n}\n\nfunction cropDataEntry(e: AbifEntry, start: number, end: number): AbifEntry {\n if (e.elementSize !== 2) {\n throw new Error(`cropAbif: DATA${e.tagNumber} expected elementSize=2, got ${e.elementSize}`);\n }\n // Callers only reach here once cropAbif has already validated end <= the processed trace length.\n const payload = new Uint8Array(e.payload.subarray(start * 2, end * 2));\n return {\n tagName: 'DATA',\n tagNumber: e.tagNumber,\n elementType: e.elementType,\n elementSize: 2,\n elementCount: end - start,\n payload,\n dataHandle: e.dataHandle,\n };\n}\n\n/** Every PBAS tag number present, ascending (1 = edited, 2 = called, other = vendor). */\nfunction basecallVersionsIn(file: AbifFile): number[] {\n const versions = new Set<number>();\n for (const e of file.entries) {\n if (e.tagName === 'PBAS') versions.add(e.tagNumber);\n }\n return Array.from(versions).sort((a, b) => a - b);\n}\n\n/** Crop one basecall version's PBAS/PCON/PLOC by its own PLOC, independent of any other version. */\nfunction cropBasecallVersion(file: AbifFile, version: number, start: number, end: number): AbifEntry[] {\n const sequence = getSequenceForVersion(file, version);\n if (sequence === undefined) return [];\n const positions = getPositionsForVersion(file, version);\n if (positions === undefined) {\n throw new Error(`cropAbif: PBAS${version} has no PLOC${version} to crop by`);\n }\n if (positions.length !== sequence.length) {\n throw new Error(\n `cropAbif: PBAS${version}/PLOC${version} length mismatch (${sequence.length} vs ${positions.length})`,\n );\n }\n const confidences = getConfidencesForVersion(file, version);\n if (confidences !== undefined && confidences.length !== sequence.length) {\n throw new Error(`cropAbif: PBAS${version}/PCON${version} length mismatch`);\n }\n\n const kept: number[] = [];\n for (let i = 0; i < positions.length; i++) {\n if (positions[i] >= start && positions[i] < end) kept.push(i);\n }\n\n const croppedSequence = kept.map(i => sequence[i]).join('');\n const croppedPositions = kept.map(i => positions[i] - start);\n\n const out: AbifEntry[] = [\n {\n tagName: 'PBAS',\n tagNumber: version,\n elementType: 2, // char\n elementSize: 1,\n elementCount: croppedSequence.length,\n payload: asciiBytes(croppedSequence),\n dataHandle: 0,\n },\n {\n tagName: 'PLOC',\n tagNumber: version,\n elementType: 4, // short, but PLOC values are unsigned (see setPositions)\n elementSize: 2,\n elementCount: croppedPositions.length,\n payload: encodeUnsignedShorts(croppedPositions),\n dataHandle: 0,\n },\n ];\n if (confidences !== undefined) {\n const croppedConfidences = kept.map(i => confidences[i]);\n out.push({\n tagName: 'PCON',\n tagNumber: version,\n elementType: 2, // declared char; bytes ARE Q-scores, see getConfidencesForVersion\n elementSize: 1,\n elementCount: croppedConfidences.length,\n payload: Uint8Array.from(croppedConfidences),\n dataHandle: 0,\n });\n }\n return out;\n}\n\nfunction encodeUnsignedShorts(values: readonly number[]): Uint8Array {\n const buf = new Uint8Array(values.length * 2);\n const view = asDataView(buf);\n for (let i = 0; i < values.length; i++) {\n view.setUint16(i * 2, Math.max(0, Math.min(0xffff, values[i])), false);\n }\n return buf;\n}\n","/**\n * High-level \"parse everything\" wrapper around the raw + view layers.\n *\n * Returns a single ParsedAbif object with metadata, the FWO_-aware\n * DATA1..4 / DATA9..12 channel split, basecalls, and decoded directory entries\n * for diagnostics. Mirrors what typical viewers (chromatogram UIs, sample\n * inspectors) need from a single file.\n *\n * For round-trip authoring (basecallers), prefer {@link readAbif} +\n * setters from ./setters which operate directly on the raw AbifFile.\n */\n\nimport { readAbif } from './abif-format';\nimport { asciiString, asDataView, subview } from './bytes';\nimport {\n AbifBaseCalls,\n AbifBaseCallVariant,\n AbifChromatogramBundle,\n AbifDecodedValue,\n AbifDirEntry,\n AbifEntry,\n AbifMetadata,\n ChannelSignals,\n ParsedAbif,\n} from './types';\nimport { getFwo, isFwoPermutation } from './view';\n\nconst TYPE_NAMES: Record<number, string> = {\n 1: 'byte',\n 2: 'char',\n 3: 'word',\n 4: 'short',\n 5: 'long',\n 7: 'float',\n 8: 'double',\n 10: 'date',\n 11: 'time',\n 12: 'thumb',\n 13: 'bool',\n 18: 'pString',\n 19: 'cString',\n 1023: 'tdir',\n};\n\nfunction typeName(t: number): string {\n return TYPE_NAMES[t] ?? (t >= 1024 ? `user${t}` : `type${t}`);\n}\n\nfunction previewNumbers(arr: number[], max = 10): string {\n if (arr.length <= max) return `[${arr.join(', ')}]`;\n return `[${arr.slice(0, max).join(', ')}, … +${arr.length - max}] (n=${arr.length})`;\n}\n\nfunction truncate(s: string, n = 80): string {\n return s.length > n ? s.slice(0, n) + '…' : s;\n}\n\nfunction previewBytes(bytes: Uint8Array): string {\n const slice = bytes.subarray(0, 16);\n const hex = Array.from(slice, b => b.toString(16).padStart(2, '0')).join(' ');\n return `${bytes.byteLength}B [${hex}${bytes.byteLength > 16 ? ' …' : ''}]`;\n}\n\n/** Coerce a decoded value to a number array, treating a single scalar as a one-element array. */\nfunction asNumbers(d: AbifDecodedValue): number[] | undefined {\n if (d.kind === 'numbers') return d.value;\n if (d.kind === 'number') return [d.value];\n return undefined;\n}\n\n/**\n * Decode a run of fixed-width numbers, bounded by BOTH the element count and the\n * actual payload length — so a malformed entry whose declared elementSize/dataSize\n * disagrees with the type's real width can never drive a read past the buffer.\n */\nfunction decodeNumeric(\n byteLength: number,\n elementCount: number,\n size: number,\n read: (offset: number) => number,\n): AbifDecodedValue {\n const n = Math.max(0, Math.min(elementCount, Math.floor(byteLength / size)));\n const arr: number[] = [];\n for (let i = 0; i < n; i++) arr.push(read(i * size));\n return arr.length === 1 ? { kind: 'number', value: arr[0] } : { kind: 'numbers', value: arr };\n}\n\n/**\n * Decode a payload best-effort by ABIF element type.\n *\n * Strings have trailing NULs stripped (cString/pString convention).\n * pString (type 18) is decoded as `length-prefix + chars`.\n */\nfunction decodePayload(elementType: number, elementCount: number, payload: Uint8Array): AbifDecodedValue {\n const view = asDataView(payload);\n switch (elementType) {\n case 1: {\n const arr = Array.from(payload.subarray(0, elementCount));\n return { kind: 'numbers', value: arr };\n }\n case 2:\n case 19: {\n const s = asciiString(payload.subarray(0, elementCount)).replace(/\\0+$/g, '');\n return { kind: 'string', value: s };\n }\n case 3:\n return decodeNumeric(payload.byteLength, elementCount, 2, o => view.getUint16(o, false));\n case 4:\n return decodeNumeric(payload.byteLength, elementCount, 2, o => view.getInt16(o, false));\n case 5:\n return decodeNumeric(payload.byteLength, elementCount, 4, o => view.getInt32(o, false));\n case 7:\n return decodeNumeric(payload.byteLength, elementCount, 4, o => view.getFloat32(o, false));\n case 8:\n return decodeNumeric(payload.byteLength, elementCount, 8, o => view.getFloat64(o, false));\n case 10: {\n // A date needs 4 bytes; a short/truncated payload falls back to raw bytes rather than throwing.\n if (payload.byteLength < 4) return { kind: 'unknown', value: payload };\n const year = view.getInt16(0, false);\n const month = view.getUint8(2);\n const day = view.getUint8(3);\n return { kind: 'date', value: { year, month, day } };\n }\n case 11: {\n // A time needs 4 bytes; short payload → raw bytes, not a RangeError.\n if (payload.byteLength < 4) return { kind: 'unknown', value: payload };\n return {\n kind: 'time',\n value: {\n hour: view.getUint8(0),\n minute: view.getUint8(1),\n second: view.getUint8(2),\n hsec: view.getUint8(3),\n },\n };\n }\n case 13: {\n const arr: boolean[] = [];\n for (let i = 0; i < Math.min(elementCount, payload.byteLength); i++) arr.push(view.getUint8(i) !== 0);\n return { kind: 'bools', value: arr };\n }\n case 18: {\n // pString = length prefix + chars; an empty payload is just the empty string.\n if (payload.byteLength < 1) return { kind: 'string', value: '' };\n const len = view.getUint8(0);\n const s = asciiString(subview(payload, 1, Math.min(len, Math.max(0, elementCount - 1))));\n return { kind: 'string', value: s };\n }\n default:\n return { kind: 'unknown', value: payload };\n }\n}\n\nfunction previewDecoded(d: AbifDecodedValue, elementType: number): string {\n switch (d.kind) {\n case 'number':\n return String(d.value);\n case 'numbers':\n return previewNumbers(d.value);\n case 'string':\n return truncate(JSON.stringify(d.value));\n case 'bools':\n return d.value.length === 1 ? String(d.value[0]) : `[${d.value.join(', ')}]`;\n case 'date': {\n const { year, month, day } = d.value;\n return `${year}-${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')}`;\n }\n case 'time': {\n const { hour, minute, second } = d.value;\n return `${String(hour).padStart(2, '0')}:${String(minute).padStart(2, '0')}:${String(second).padStart(2, '0')}`;\n }\n case 'bytes':\n return `${typeName(elementType)} ${previewBytes(d.value)}`;\n case 'unknown':\n return `${typeName(elementType)} ${previewBytes(d.value)}`;\n }\n}\n\n/**\n * Parse an ABIF file into a high-level view: metadata, channels, basecalls,\n * and decoded directory entries.\n *\n * This is the INTERPRETING layer — it makes convenience choices (FWO_ → \"GATC\"\n * fallback, derived samplingRate, preferred/upper-cased PBAS2 baseCalls). It is\n * not the raw structural truth: for that use {@link readAbif}, which reads the\n * directory verbatim (raw dataSize/offset/counts, tdir, inline bytes) and makes\n * no interpretation. `parseAbif` builds on top of it.\n *\n * Accepts ArrayBuffer or Uint8Array (Buffer in Node works too — it extends\n * Uint8Array). The `fileName` argument is informational only; it's preserved\n * in the result.\n */\nexport function parseAbif(input: ArrayBuffer | Uint8Array, fileName = ''): ParsedAbif {\n const bytes = input instanceof Uint8Array ? input : new Uint8Array(input);\n const file = readAbif(bytes);\n\n const entries: AbifDirEntry[] = file.entries.map(e => {\n // PCON is declared char (type 2) but its bytes ARE Q-scores; decode it as numbers so the\n // diagnostic view keeps zeros the char decoder would strip (matches baseCalls.confidences).\n const decoded =\n e.tagName === 'PCON' && e.elementSize === 1\n ? decodePayload(1, e.elementCount, e.payload) // type 1 = byte → { kind: 'numbers' }\n : decodePayload(e.elementType, e.elementCount, e.payload);\n // Prefer the real on-disk directory fields (present when read from a file) over\n // reconciled/computed values, so the diagnostic view reflects the actual record.\n return {\n tag: e.tagName,\n tagNumber: e.tagNumber,\n elementType: e.elementType,\n elementTypeName: typeName(e.elementType),\n elementSize: e.elementSize,\n elementCount: e.elementCount,\n rawElementCount: e.raw?.elementCount ?? e.elementCount,\n dataSize: e.raw?.dataSize ?? e.elementCount * e.elementSize,\n dataOffset: e.raw?.dataOffset ?? -1,\n inline: e.raw?.inline ?? e.elementCount * e.elementSize <= 4,\n decoded,\n preview: previewDecoded(decoded, e.elementType),\n };\n });\n\n // FWO_ → base order. Fall back to GATC unless FWO_ is a real permutation of A/C/G/T\n // (a degenerate value like \"AAAA\" is regex-valid but would collapse channels).\n let baseOrder = getFwo(file);\n if (!isFwoPermutation(baseOrder)) baseOrder = 'GATC';\n\n const dataChannels: Record<number, number[]> = {};\n const data1To4: ChannelSignals = { A: [], C: [], G: [], T: [] };\n const data9To12: ChannelSignals = { A: [], C: [], G: [], T: [] };\n const metadata: AbifMetadata = { comments: [] };\n const pbas: Record<number, string> = {};\n const pcon: Record<number, number[]> = {};\n const ploc: Record<number, number[]> = {};\n\n const channelKey = (i: number): keyof ChannelSignals => baseOrder[i] as keyof ChannelSignals;\n\n for (let idx = 0; idx < file.entries.length; idx++) {\n const e = file.entries[idx];\n const decoded = entries[idx].decoded;\n\n if (e.tagName === 'DATA') {\n // Accept single-element channels too (decodePayload collapses length-1 to a scalar).\n const nums = asNumbers(decoded);\n if (nums) {\n dataChannels[e.tagNumber] = nums;\n if (e.tagNumber >= 1 && e.tagNumber <= 4) data1To4[channelKey(e.tagNumber - 1)] = nums;\n else if (e.tagNumber >= 9 && e.tagNumber <= 12) data9To12[channelKey(e.tagNumber - 9)] = nums;\n }\n } else if (e.tagName === 'PBAS' && decoded.kind === 'string') {\n pbas[e.tagNumber] = decoded.value;\n } else if (e.tagName === 'PCON') {\n // PCON Q-scores are 1 byte each (elementType=2/char). Read them straight from the payload —\n // a trailing zero is a valid score, but the char decoder strips trailing NULs and would drop it.\n const nums = e.elementSize === 1 ? Array.from(e.payload.subarray(0, e.elementCount)) : asNumbers(decoded);\n if (nums) pcon[e.tagNumber] = nums;\n } else if (e.tagName === 'PLOC') {\n // PLOC sample indices are always non-negative — reinterpret int16 as uint16.\n const nums = asNumbers(decoded);\n if (nums) ploc[e.tagNumber] = nums.map(v => (v < 0 ? v + 0x10000 : v));\n } else if (e.tagName === 'SPAC') {\n // ABIF spec defines SPAC as float (elementType=7). Some legacy files mislabel\n // it as long (type=5); both are 4 bytes and the payload is always a float.\n if (e.elementSize === 4 && e.payload.byteLength >= 4) {\n const v = asDataView(e.payload).getFloat32(0, false);\n if (Number.isFinite(v) && v > 0) metadata.samplingRate = v;\n } else if (decoded.kind === 'number') {\n metadata.samplingRate = decoded.value;\n }\n } else if (e.tagName === 'SMPL' && decoded.kind === 'string') {\n metadata.sampleName = decoded.value;\n } else if (e.tagName === 'LANE' && decoded.kind === 'number') {\n metadata.laneNumber = decoded.value;\n } else if (e.tagName === 'TUBE' && decoded.kind === 'string') {\n metadata.tube = decoded.value;\n } else if (e.tagName === 'MCHN' && decoded.kind === 'string') {\n metadata.machineName = decoded.value;\n } else if (e.tagName === 'MODL' && decoded.kind === 'string') {\n metadata.machineModel = decoded.value;\n } else if (e.tagName === 'RUND' && decoded.kind === 'date') {\n const d = decoded.value;\n metadata.runDate = `${d.year}-${String(d.month).padStart(2, '0')}-${String(d.day).padStart(2, '0')}`;\n } else if (e.tagName === 'RUNT' && decoded.kind === 'time') {\n const t = decoded.value;\n metadata.runTime = `${String(t.hour).padStart(2, '0')}:${String(t.minute).padStart(2, '0')}:${String(t.second).padStart(2, '0')}`;\n } else if (e.tagName === 'CMNT' && decoded.kind === 'string') {\n metadata.comments.push(decoded.value);\n } else if (e.tagName === 'RevC' && e.tagNumber === 1) {\n // RevC1 (int16): file's own flag for whether the sequence is already\n // reverse-complemented. Only tagNumber 1 is defined by the spec. Reported\n // as-is; we draw no conclusion from it.\n if (decoded.kind === 'number') metadata.reverseComplemented = decoded.value !== 0;\n else if (decoded.kind === 'numbers') metadata.reverseComplemented = decoded.value.some(v => v !== 0);\n }\n }\n\n // Every basecall version the file carries, exactly as stored — the source of\n // truth. Per-version PCON/PLOC are kept strictly (no cross-version borrowing):\n // a variant reports only what its own tag number holds.\n const baseCallVariants: AbifBaseCallVariant[] = Object.keys(pbas)\n .map(Number)\n .sort((a, b) => a - b)\n .map(\n (v): AbifBaseCallVariant => ({\n version: v,\n role: v === 1 ? 'edited' : v === 2 ? 'called' : 'unknown',\n // As stored: case is preserved (lower-case can encode masking/edits). The\n // uppercased convenience view lives on `baseCalls`, not here.\n sequence: pbas[v],\n confidences: pcon[v] ?? [],\n positions: ploc[v] ?? [],\n }),\n );\n\n // Basecalls: prefer PBAS2 (called) over PBAS1 (edited) — a spec-role choice. Test key\n // presence, not string truthiness, so an existing-but-empty PBAS2 is still honored.\n let baseCalls: AbifBaseCalls | undefined;\n const pbasVersion = 2 in pbas ? 2 : 1 in pbas ? 1 : Object.keys(pbas).map(Number)[0];\n if (pbasVersion !== undefined && pbas[pbasVersion] !== undefined) {\n // Don't .trim(): keep length aligned with PCON/PLOC (trailing nulls already stripped).\n const seq = pbas[pbasVersion].toUpperCase();\n // Fall back to whichever PCON has a length matching the chosen PBAS — some\n // files ship PCON only under one tagNumber even when PBAS exists under both.\n // Fall back to whichever version's PCON/PLOC matches the chosen PBAS length — triggered when the\n // preferred version's array is missing OR present-but-length-mismatched. Expose none rather than a\n // broken array when nothing matches, so baseCalls stays self-consistent (baseCallVariants stays strict).\n let confidences = pcon[pbasVersion] ?? [];\n if (confidences.length !== seq.length) {\n confidences =\n Object.keys(pcon)\n .map(Number)\n .map(v => pcon[v])\n .find(c => c.length === seq.length) ?? [];\n }\n let positions = ploc[pbasVersion] ?? [];\n if (positions.length !== seq.length) {\n positions =\n Object.keys(ploc)\n .map(Number)\n .map(v => ploc[v])\n .find(pp => pp.length === seq.length) ?? [];\n }\n baseCalls = { sequence: seq, confidences, positions, pbasVersion };\n }\n\n // SPAC fallback: derive from PLOC positions or DATA9 length when missing.\n if (!Number.isFinite(metadata.samplingRate) || (metadata.samplingRate ?? 0) <= 0) {\n const pos = baseCalls?.positions;\n const data9Len = Math.max(data9To12.A.length, data9To12.C.length, data9To12.G.length, data9To12.T.length);\n if (pos && pos.length > 1) {\n metadata.samplingRate = (pos[pos.length - 1] - pos[0]) / (pos.length - 1);\n } else if (baseCalls && baseCalls.sequence.length > 0 && data9Len > 0) {\n metadata.samplingRate = data9Len / baseCalls.sequence.length;\n }\n }\n\n const chromatogram: AbifChromatogramBundle = { baseOrder, dataChannels, data1To4, data9To12 };\n\n return {\n fileName,\n fileSize: bytes.byteLength,\n abifVersion: file.version,\n macBinaryOffset: file.macBinaryOffset,\n dirEntryCount: file.entries.length,\n metadata,\n chromatogram,\n baseCalls,\n baseCallVariants,\n entries,\n };\n}\n\n/** True when any channel has at least one signal value. */\nexport function hasSignals(s: ChannelSignals): boolean {\n return s.A.length > 0 || s.C.length > 0 || s.G.length > 0 || s.T.length > 0;\n}\n\n/** Length of the longest channel in a ChannelSignals bundle. */\nexport function channelMaxLength(s: ChannelSignals): number {\n return Math.max(s.A.length, s.C.length, s.G.length, s.T.length);\n}\n\n// Quiet unused-import for the AbifEntry type if it isn't reachable elsewhere.\nexport type { AbifEntry };\n","/**\n * Mutation helpers for AbifFile: write PBAS/PCON/PLOC/SPAC and ensure DATA9..12\n * are present. Used by basecallers to author ABIF output.\n */\n\nimport { findEntry, insertEntrySorted, upsertEntry } from './abif-format';\nimport { asciiBytes, asDataView } from './bytes';\nimport { AbifFile } from './types';\nimport { hasData9To12Block } from './view';\n\n/** Set PBAS2 (replaces if present). */\nexport function setSequence(file: AbifFile, sequence: string): void {\n upsertEntry(file, 'PBAS', 2, asciiBytes(sequence), {\n elementType: 2, // char\n elementSize: 1,\n elementCount: sequence.length,\n });\n}\n\n/** Set PCON2 (replaces if present). Values clamped to [0, 255]. */\nexport function setConfidences(file: AbifFile, q: ArrayLike<number>): void {\n const buf = new Uint8Array(q.length);\n for (let i = 0; i < q.length; i++) {\n buf[i] = Math.max(0, Math.min(255, Math.round(q[i])));\n }\n upsertEntry(file, 'PCON', 2, buf, {\n elementType: 2,\n elementSize: 1,\n elementCount: q.length,\n });\n}\n\n/**\n * Set PLOC2 (replaces if present).\n *\n * Written as UNSIGNED int16 so positions up to 65535 are preserved on disk\n * (signed int16 would wrap on traces with > 32k scans).\n */\nexport function setPositions(file: AbifFile, positions: ArrayLike<number>): void {\n const buf = new Uint8Array(positions.length * 2);\n const view = asDataView(buf);\n for (let i = 0; i < positions.length; i++) {\n view.setUint16(i * 2, Math.max(0, Math.min(0xffff, positions[i])), false);\n }\n upsertEntry(file, 'PLOC', 2, buf, {\n elementType: 4,\n elementSize: 2,\n elementCount: positions.length,\n });\n}\n\n/**\n * Set SPAC/1, SPAC/2, SPAC/3 — the standard ABIF \"average peak spacing\" trio\n * that KB-basecaller writes and downstream tools (BioPython, Sequencher,\n * KB-aware viewers) expect:\n *\n * - SPAC/1 (float32) — average peak spacing used in last analysis.\n * - SPAC/2 (pString) — basecaller name / identifier.\n * - SPAC/3 (float32) — average peak spacing computed by the basecaller.\n *\n * Both float fields are written with the same value.\n */\nexport function setAveragePeakSpacing(file: AbifFile, spacing: number, basecallerName: string): void {\n const f1 = new Uint8Array(4);\n asDataView(f1).setFloat32(0, spacing, false);\n upsertEntry(file, 'SPAC', 1, f1, { elementType: 7, elementSize: 4, elementCount: 1 });\n\n const nameBytes = asciiBytes(basecallerName);\n const len = Math.min(255, nameBytes.length);\n const p = new Uint8Array(1 + len);\n p[0] = len;\n p.set(nameBytes.subarray(0, len), 1);\n upsertEntry(file, 'SPAC', 2, p, { elementType: 18, elementSize: 1, elementCount: 1 + len });\n\n const f3 = new Uint8Array(4);\n asDataView(f3).setFloat32(0, spacing, false);\n upsertEntry(file, 'SPAC', 3, f3, { elementType: 7, elementSize: 4, elementCount: 1 });\n}\n\n/**\n * Mean consecutive peak-to-peak distance in scans, from a positions array.\n * Returns 0 when fewer than 2 positions are present.\n */\nexport function averagePeakSpacing(positions: ArrayLike<number>): number {\n if (positions.length < 2) return 0;\n return (positions[positions.length - 1] - positions[0]) / (positions.length - 1);\n}\n\n/**\n * Ensure DATA9..12 are present in the file. Many downstream consumers\n * (BioPython-style readers, viewers) read the chromatogram signal from\n * DATA9..12 by convention — these tags are the raw fluorescence on newer\n * instruments. Older files that only carry DATA1..8 break those consumers\n * with a \"no signal\" error after re-basecalling.\n *\n * We populate DATA9..12 by copying DATA1..4 (which on DATA1..8-only files IS\n * the raw signal). The DATA1..4 tags are left untouched so any tool that\n * reads them keeps working.\n *\n * No-op when DATA9..12 already exist.\n */\nexport function ensureRawDataChannels(file: AbifFile): void {\n if (hasData9To12Block(file)) return;\n for (let i = 1; i <= 4; i++) {\n const src = findEntry(file, 'DATA', i);\n if (!src) continue;\n const target = 8 + i;\n if (findEntry(file, 'DATA', target)) continue;\n // Copy DATA1..4's payload bytes + reconciled shape (dataHandle reset to 0),\n // preserving any tolerated payload/count desync that upsertEntry would reject,\n // and place it in sorted directory order.\n insertEntrySorted(file.entries, {\n tagName: 'DATA',\n tagNumber: target,\n elementType: src.elementType,\n elementSize: src.elementSize,\n elementCount: src.elementCount,\n payload: new Uint8Array(src.payload),\n dataHandle: 0,\n });\n }\n}\n","/**\n * FASTA / FASTQ / .qual text serialization.\n *\n * Pure, format-level writers: they turn a sequence plus optional per-base Phred\n * quality into text. No coupling to any binary format — callers build records\n * from ABIF basecalls (PBAS/PCON), alignments, consensus, etc.\n *\n * Quality is encoded as Phred+33 (Sanger / Illumina 1.8+). Scores are clamped\n * to [0, {@link MAX_PHRED}]: the upper bound is the largest value representable\n * as Phred+33 ('~' = ASCII 126 = 93 + 33). Callers must NOT feed quality for\n * reads that lack it — gate on {@link hasUsableQuality} and emit FASTA only,\n * rather than letting the 255 \"no quality\" sentinel clamp to a perfect '~'.\n */\n\n/** Largest Phred score representable as Phred+33 ('~' = ASCII 126 = 93 + 33). */\nexport const MAX_PHRED = 93;\n\nconst PHRED_OFFSET = 33;\nconst DEFAULT_LINE_WIDTH = 60;\nconst NO_QUALITY = 255;\n\n/** A FASTA record: identifier, optional description, and residues. */\nexport interface FastaRecord {\n /** Identifier written after '>', up to the first space. */\n id: string;\n /** Optional free text after the id on the header line. */\n description?: string;\n /** Residues, written verbatim (case and gaps preserved). */\n sequence: string;\n}\n\n/** A FASTQ record: a {@link FastaRecord} plus one Phred score per residue. */\nexport interface FastqRecord extends FastaRecord {\n /** Per-base Phred scores; must be one per residue in {@link FastaRecord.sequence}. */\n qualities: readonly number[];\n}\n\n/** A .qual record: identifier, optional description, and per-base Phred scores. */\nexport interface QualRecord {\n id: string;\n description?: string;\n qualities: readonly number[];\n}\n\n/** Line-wrapping shared by the FASTA and .qual writers. */\nexport interface WrapOptions {\n /** Residues (FASTA) or scores (.qual) per line; <= 0 writes one line. Default 60. */\n lineWidth?: number;\n}\n\n/** Serialize one or more records to FASTA text (trailing newline included). */\nexport function formatFasta(records: FastaRecord | readonly FastaRecord[], options?: WrapOptions): string {\n const width = options?.lineWidth ?? DEFAULT_LINE_WIDTH;\n return toArray(records)\n .map(r => `${headerLine('>', r.id, r.description)}\\n${wrapResidues(r.sequence, width)}`)\n .join('');\n}\n\n/** Serialize one or more records to FASTQ text, Phred+33 (trailing newline included). */\nexport function formatFastq(records: FastqRecord | readonly FastqRecord[]): string {\n return toArray(records).map(formatFastqRecord).join('');\n}\n\n/** Serialize one or more records to .qual text: space-separated Phred ints, wrapped. */\nexport function formatQual(records: QualRecord | readonly QualRecord[], options?: WrapOptions): string {\n const width = options?.lineWidth ?? DEFAULT_LINE_WIDTH;\n return toArray(records)\n .map(r => `${headerLine('>', r.id, r.description)}\\n${wrapScores(r.qualities, width)}`)\n .join('');\n}\n\n/**\n * Report whether quality scores are present and usable. False for missing or\n * empty scores and for the all-255 sentinel (ABIF PCON uses 255 for \"no\n * quality\"), so a caller can offer FASTA only instead of inventing perfect Q.\n */\nexport function hasUsableQuality(qualities?: readonly number[]): boolean {\n return !!qualities && qualities.length > 0 && !qualities.every(q => q === NO_QUALITY);\n}\n\n/** Build one FASTQ record; the '+' separator is left bare (no id repeat). */\nfunction formatFastqRecord(record: FastqRecord): string {\n const { id, description, sequence, qualities } = record;\n if (qualities.length !== sequence.length) {\n throw new Error(`FASTQ ${id}: ${qualities.length} quality scores for ${sequence.length} bases`);\n }\n const quality = qualities.map(phredToChar).join('');\n return `${headerLine('@', id, description)}\\n${sequence}\\n+\\n${quality}\\n`;\n}\n\n/** Join id + optional description into a header line; reject embedded newlines. */\nfunction headerLine(prefix: '>' | '@', id: string, description?: string): string {\n const name = description ? `${id} ${description}` : id;\n if (name.includes('\\n')) {\n throw new Error('FASTX header must not contain a newline');\n }\n return prefix + name;\n}\n\n/** Wrap residues to `width` per line; an empty sequence yields no body line. */\nfunction wrapResidues(sequence: string, width: number): string {\n if (sequence.length === 0) return '';\n if (width <= 0 || sequence.length <= width) return `${sequence}\\n`;\n let out = '';\n for (let i = 0; i < sequence.length; i += width) {\n out += `${sequence.slice(i, i + width)}\\n`;\n }\n return out;\n}\n\n/** Wrap clamped Phred ints to `width` per line, space-separated. */\nfunction wrapScores(qualities: readonly number[], width: number): string {\n if (qualities.length === 0) return '';\n const values = qualities.map(clampPhred);\n const perLine = width <= 0 ? values.length : width;\n let out = '';\n for (let i = 0; i < values.length; i += perLine) {\n out += `${values.slice(i, i + perLine).join(' ')}\\n`;\n }\n return out;\n}\n\n/** Round and clamp a score to the Phred+33 range [0, MAX_PHRED]. */\nfunction clampPhred(q: number): number {\n const r = Math.round(q);\n return r < 0 ? 0 : r > MAX_PHRED ? MAX_PHRED : r;\n}\n\n/** Encode one Phred score as a Phred+33 ASCII character. */\nfunction phredToChar(q: number): string {\n return String.fromCharCode(clampPhred(q) + PHRED_OFFSET);\n}\n\n/** Normalize a single record or array into a readonly array. */\nfunction toArray<T>(value: T | readonly T[]): readonly T[] {\n // Array.isArray does not narrow readonly arrays, so cast the single-value branch.\n return Array.isArray(value) ? value : [value as T];\n}\n"]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@fishka/seqio",
3
3
  "description": "Sequencing file parsers and writers for bioinformatics data",
4
- "version": "0.5.0",
4
+ "version": "0.6.1",
5
5
  "license": "MIT",
6
6
  "main": "./dist/index.js",
7
7
  "module": "./dist/index.mjs",