@fishka/seqio 0.6.1 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +272 -16
- package/dist/index.d.ts +272 -16
- package/dist/index.js +10 -8
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +10 -8
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
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"]}
|
|
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/text.ts","../src/detect.ts","../src/seq-record.ts","../src/embl/embl-format.ts","../src/fastx/fastx-format.ts","../src/genbank/genbank-format.ts","../src/gfa/gfa-format.ts","../src/gff/gff-format.ts","../src/msa/msa-format.ts","../src/pir/pir-format.ts","../src/sam/common.ts","../src/sam/bam-format.ts","../src/sam/sam-format.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","decodeText","text","toLines","stripWhitespace","isBlank","line","firstToken","space","MACBINARY_OFFSET","SNIFF_BYTES","detectFormat","hasAscii","firstNonBlankLine","detectFromLine","isSamRecord","f","flag","mapq","cigar","head","offset","magic","makeSeqRecord","id","description","parseEmbl","parseEmblStyle","parseSwissprot","policy","lines","records","started","idLine","ac","de","mode","flush","chooseId","code","parts","acc","sv","part","m","MAX_PHRED","PHRED_OFFSET","DEFAULT_LINE_WIDTH","NO_QUALITY","parseFasta","header","residues","makeFasta","parseFastq","seqParts","makeFastq","quality","startsRecord","formatFasta","width","toArray","headerLine","wrapResidues","formatFastq","formatFastqRecord","formatQual","wrapScores","hasUsableQuality","qualities","splitHeader","k","clampPhred","trimmed","j","record","phredToChar","prefix","perLine","value","KEYWORD","parseGenbank","locus","accession","definition","isKeyword","key","parseGfa","parseGff","fastaAt","Alignment","block","ALIGN_BLOCK","parseClustal","aln","seenFirst","parseStockholm","parsePhylip","ntax","nchar","names","rows","nt","cap","parseNexus","inMatrix","endsMatrix","data","parseMsf","inSeq","parsePir","awaitingTitle","semi","isSecondaryOrSupplementary","mateId","qname","locusHint","rname","SEQ_NT16","ALIGN_FIXED","parseBam","dv","dec","cstr","lText","nRef","refs","lName","blockSize","refID","lReadName","nCigar","lSeq","seqBytes","decodeSeq","byte","parseSam","int"],"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 * Small text helpers shared by the text-format readers (FASTA/FASTQ, GenBank, EMBL,\n * Swiss-Prot, the alignment family, …). Browser- and Node-safe: decoding goes through\n * TextDecoder, never Node's Buffer.\n */\n\n/** Decode bytes as UTF-8 (ASCII is a subset), dropping a leading BOM; pass strings through. */\nexport function decodeText(input: string | Uint8Array): string {\n let text = typeof input === 'string' ? input : new TextDecoder().decode(input);\n // A leading UTF-8 BOM (U+FEFF) from a Windows editor would otherwise hide the first\n // line's marker. TextDecoder already strips it from byte input; this covers strings.\n if (text.charCodeAt(0) === 0xfeff) text = text.slice(1);\n return text;\n}\n\n/** Decode and split into lines on any newline style (LF, CRLF, CR). */\nexport function toLines(input: string | Uint8Array): string[] {\n return decodeText(input).split(/\\r\\n|\\r|\\n/);\n}\n\n/** Remove every whitespace character (used to concatenate wrapped residue/quality lines). */\nexport function stripWhitespace(s: string): string {\n return s.replace(/\\s+/g, '');\n}\n\n/** Whether a line is empty or whitespace-only. */\nexport function isBlank(line: string): boolean {\n return line.trim().length === 0;\n}\n\n/** The first whitespace-delimited token of a string (trimmed); '' when there is none. */\nexport function firstToken(s: string): string {\n const t = s.trim();\n const space = t.search(/\\s/);\n return space < 0 ? t : t.slice(0, space);\n}\n","/**\n * Content-based file-format detection.\n *\n * Sniffs the bytes, never the file extension: binary magic first (ABIF at offset 0, or at\n * 128 behind a MacBinary preamble; SCF's \".scf\" magic), then the first non-blank line for\n * the text formats. Text signatures are matched on the leading line's content (a keyword\n * like `LOCUS`, or the first character `>` / `;` / `@`), so a mislabeled or extension-less\n * file still resolves.\n */\n\nimport { decodeText } from './text';\n\n/** A format {@link detectFormat} can recognize. Some are detected before their reader ships. */\nexport type SeqFileFormat =\n | 'abif'\n | 'scf'\n | 'fasta'\n | 'fastq'\n | 'genbank'\n | 'embl'\n | 'swissprot'\n | 'clustal'\n | 'stockholm'\n | 'phylip'\n | 'nexus'\n | 'msf'\n | 'pir'\n | 'gff'\n | 'sam'\n | 'bam'\n | 'gfa'\n | 'unknown';\n\n/** MacBinary preamble length: an ABIF may sit 128 bytes into the file behind one. */\nconst MACBINARY_OFFSET = 128;\n\n/** Only the file's start matters for detection; decode at most this many bytes. */\nconst SNIFF_BYTES = 8192;\n\n/**\n * Detect the sequencing file format from its content. Returns 'unknown' when no signature\n * matches (empty input, or a leading line that is neither a known magic nor a recognized\n * text marker).\n */\nexport function detectFormat(bytes: Uint8Array): SeqFileFormat {\n if (hasAscii(bytes, 0, 'ABIF') || hasAscii(bytes, MACBINARY_OFFSET, 'ABIF')) return 'abif';\n if (hasAscii(bytes, 0, '.scf')) return 'scf';\n // BAM's magic is \"BAM\\1\". On disk a BAM is BGZF-compressed (starts with the gzip magic 1f 8b), so\n // this matches only once that wrapper has been inflated — the caller peels gzip before detecting.\n if (hasAscii(bytes, 0, 'BAM\\x01')) return 'bam';\n const line = firstNonBlankLine(bytes);\n return line === undefined ? 'unknown' : detectFromLine(line);\n}\n\n/** Classify a text file from its first non-blank line (leading whitespace ignored). */\nfunction detectFromLine(raw: string): SeqFileFormat {\n const line = raw.trimStart();\n if (/^LOCUS\\s/.test(line)) return 'genbank';\n // EMBL and Swiss-Prot both open with an \"ID\" line; Swiss-Prot's ends in \"… NN AA.\" and\n // carries the Reviewed/Unreviewed status, whereas EMBL's ends in \"… NN BP.\"\n if (/^ID\\s/.test(line)) return /(Reviewed|Unreviewed);| AA\\.\\s*$/.test(line) ? 'swissprot' : 'embl';\n // Alignment formats — each names itself on the first line, except PHYLIP (a \"<ntax> <nchar>\" line).\n if (/^#\\s*STOCKHOLM/i.test(line)) return 'stockholm';\n if (/^#NEXUS/i.test(line)) return 'nexus';\n // Clustal-format alignments carry a program banner: Clustal itself, or MUSCLE/MAFFT/… which\n // emit the same layout. The generic \"multiple sequence alignment\" phrase is guarded against a\n // '>'/'@' sequence header that merely mentions it.\n if (/^(CLUSTAL|MUSCLE|MAFFT|T-?COFFEE|PROBCONS|KALIGN|MVIEW|PROMALS)\\b/i.test(line)) return 'clustal';\n if (/multiple (sequence )?alignment/i.test(line) && !/^[>@#]/.test(line)) return 'clustal';\n if (/^!!(NA|AA)_MULTIPLE_ALIGNMENT/i.test(line) || /\\bMSF:\\s*\\d/.test(line)) return 'msf';\n if (/^\\d+\\s+\\d+\\s*$/.test(line)) return 'phylip';\n if (/^##gff-version/i.test(line)) return 'gff';\n // GFA (assembly graph): the version header (an `H` line carrying `VN:Z:1.x`/`2.x`, in any tag\n // position), or a headerless file that opens on a Segment line `S\\t<name>\\t…` (see below).\n if (/^H\\t(?:[^\\t]*\\t)*VN:Z:[12]\\./.test(line)) return 'gfa';\n // SAM: `@`-prefixed header whose tag is a known two-letter record type + TAB — distinct from a\n // FASTQ read id (which also starts with '@'), so this must precede the '@' → fastq rule below.\n if (/^@(HD|SQ|RG|PG|CO)\\t/.test(line)) return 'sam';\n // PIR/NBRF headers are '>XX;id' with a specific two-letter type code — matched before the\n // bare '>' → FASTA rule so a PIR file isn't taken for FASTA.\n if (/^>(P1|F1|DL|DC|RL|RC|N1|N3|XX);/i.test(line)) return 'pir';\n switch (line.charCodeAt(0)) {\n case 0x3e: // '>'\n case 0x3b: // ';' — legacy Pearson FASTA comment line\n return 'fasta';\n case 0x40: // '@'\n return 'fastq';\n }\n // Headerless variants, checked last (their signatures are structural, not a leading marker). SAM\n // first: it's the stricter check (11 mandatory fields), so a SAM record whose QNAME happens to be\n // \"S\" isn't misread as a GFA segment line (which is only 3 fields).\n if (isSamRecord(line)) return 'sam';\n if (/^S\\t[!-~]+\\t/.test(line)) return 'gfa'; // GFA segment line\n return 'unknown';\n}\n\n/**\n * Whether a line is a headerless SAM alignment record: at least the 11 mandatory tab fields, with\n * FLAG/POS/MAPQ integer and a valid CIGAR (`*` or runs of <len><op>). This structural check keeps a\n * generic TSV from being mistaken for SAM.\n */\nfunction isSamRecord(line: string): boolean {\n const f = line.split('\\t');\n if (f.length < 11) return false;\n const [, flag, , pos, mapq, cigar] = f;\n return /^\\d+$/.test(flag) && /^\\d+$/.test(pos) && /^\\d+$/.test(mapq) && /^(\\*|(\\d+[MIDNSHPX=])+)$/.test(cigar);\n}\n\n/** The first non-blank line within the sniff window, or undefined if there is none. */\nfunction firstNonBlankLine(bytes: Uint8Array): string | undefined {\n const head = bytes.length > SNIFF_BYTES ? bytes.subarray(0, SNIFF_BYTES) : bytes;\n for (const line of decodeText(head).split(/\\r\\n|\\r|\\n/)) {\n if (line.trim().length > 0) return line;\n }\n return undefined;\n}\n\n/** Whether `magic` (ASCII) appears verbatim at `offset`. */\nfunction hasAscii(bytes: Uint8Array, offset: number, magic: string): boolean {\n if (bytes.length < offset + magic.length) return false;\n for (let i = 0; i < magic.length; i++) {\n if (bytes[offset + i] !== magic.charCodeAt(i)) return false;\n }\n return true;\n}\n","/**\n * The common \"a sequence with a name\" record produced by every reader that extracts\n * sequences for downstream picking/export (GenBank, EMBL, Swiss-Prot, the alignment\n * formats, …). Data only — same shape as {@link FastaRecord}, so all readers feed one\n * uniform list regardless of source format.\n */\nexport interface SeqRecord {\n /** Identifier (accession/version/locus/name, per the source format's convention). */\n id: string;\n /** Free-text description/definition when the format carries one. */\n description?: string;\n /**\n * Residues with line wrapping removed. Case is preserved as written; alignment gap\n * characters ('-', '.') are kept (an aligned row is stored verbatim, not de-gapped).\n */\n sequence: string;\n}\n\n/** Build a {@link SeqRecord}, dropping an empty description so records compare cleanly. */\nexport function makeSeqRecord(id: string, description: string, sequence: string): SeqRecord {\n return description ? { id, description, sequence } : { id, sequence };\n}\n","/**\n * EMBL / Swiss-Prot (UniProtKB) flat-file reader — sequence extraction only.\n *\n * Both formats share one container: two-letter line-type codes in columns 0–1, an `SQ`\n * line that introduces the sequence, indented sequence lines (residues + trailing position\n * counters), and `//` between records. UniProtKB is historically derived from the EMBL\n * format, so a single scanner serves both; they differ only in which field is the id:\n * - EMBL: the `ID` line's accession, suffixed with the sequence version (`SV n` → `.n`),\n * falling back to `AC`.\n * - Swiss-Prot: the primary `AC` accession (the `ID` line is the entry name), falling\n * back to that entry name.\n * Description comes from the `DE` line(s), joined. Feature tables (`FT`) and all other codes\n * are skipped — this is the sequence-reading path only.\n *\n * Deliberately lenient (see AGENTS.md): never throws. No `SQ` block → empty sequence; a\n * missing `//` between records flushes the previous one when the next `ID` appears; a\n * truncated final record is flushed at EOF. Residue case is preserved as written.\n */\n\nimport { makeSeqRecord, SeqRecord } from '../seq-record';\nimport { firstToken, stripWhitespace, toLines } from '../text';\n\ntype IdPolicy = 'embl' | 'swissprot';\n\n/** Read EMBL flat files (`.embl`/`.dat`): id = accession.version from the ID line. */\nexport function parseEmbl(input: string | Uint8Array): SeqRecord[] {\n return parseEmblStyle(input, 'embl');\n}\n\n/** Read UniProtKB/Swiss-Prot flat files (`.dat`/`.txt`): id = primary AC accession. */\nexport function parseSwissprot(input: string | Uint8Array): SeqRecord[] {\n return parseEmblStyle(input, 'swissprot');\n}\n\nfunction parseEmblStyle(input: string | Uint8Array, policy: IdPolicy): SeqRecord[] {\n const lines = toLines(input);\n const records: SeqRecord[] = [];\n\n let started = false;\n let idLine = '';\n let ac = '';\n let de: string[] = [];\n let seq: string[] = [];\n let mode: 'header' | 'sequence' = 'header';\n\n const flush = (): void => {\n if (!started) return;\n records.push(makeSeqRecord(chooseId(policy, idLine, ac), de.join(' ').trim(), stripWhitespace(seq.join(''))));\n started = false;\n idLine = '';\n ac = '';\n de = [];\n seq = [];\n mode = 'header';\n };\n\n for (const line of lines) {\n if (line.startsWith('//')) {\n flush();\n continue;\n }\n if (mode === 'sequence') {\n // Indented (or blank) lines are sequence data; a code line ends the block, re-handled below.\n if (line.length === 0 || /^\\s/.test(line)) {\n seq.push(line.replace(/[\\s\\d]/g, '')); // drop column spacing and the trailing position counter\n continue;\n }\n mode = 'header';\n }\n\n const code = line.slice(0, 2);\n if (code === 'ID') {\n if (started) flush(); // next record without a preceding '//'\n started = true;\n idLine = line.slice(2).trim();\n } else if (code === 'AC') {\n if (!ac) ac = line.slice(2).split(';')[0].trim(); // primary accession (first of a ';'-list)\n started = true;\n } else if (code === 'DE') {\n de.push(line.slice(2).trim());\n started = true;\n } else if (code === 'SQ') {\n mode = 'sequence';\n started = true;\n }\n // XX / FH / FT / OS / RN … — not needed for sequence extraction\n }\n flush();\n return records;\n}\n\n/** Pick the record id per format: EMBL accession.version from the ID line, or Swiss-Prot's AC. */\nfunction chooseId(policy: IdPolicy, idLine: string, ac: string): string {\n if (policy === 'swissprot') return ac || firstToken(idLine);\n // EMBL ID line: \"X56734; SV 1; linear; mRNA; STD; PLN; 1859 BP.\" (modern) or\n // \"AB000263 standard; RNA; PRI; 368 BP.\" (old). Accession is the first token; SV is the\n // sequence version, appended as \".n\" to match the accession.version convention.\n const parts = idLine.split(';');\n const acc = firstToken(parts[0]);\n let sv = '';\n for (const part of parts) {\n const m = /^\\s*SV\\s+(\\d+)/.exec(part);\n if (m) sv = m[1];\n }\n return (sv ? `${acc}.${sv}` : acc) || ac;\n}\n","/**\n * FASTA / FASTQ / .qual text codec: readers (parseFasta / parseFastq) and writers\n * (formatFasta / formatFastq / formatQual).\n *\n * Text formats have no on-disk container, so there is no separate raw layer — this\n * one file is the codec (the `<family>-format.ts` analog of `abif-format.ts`).\n *\n * Data only: the readers keep residues and per-base Phred scores and drop cosmetic\n * formatting (line wrapping, blank lines, `\\r\\n` vs `\\n`); the writers re-impose a\n * chosen wrap width. Quality is Phred+33 (Sanger / Illumina 1.8+); scores are clamped\n * to [0, {@link MAX_PHRED}] on write ('~' = ASCII 126 = 93 + 33).\n */\n\nimport { isBlank, stripWhitespace, toLines } from '../text';\nimport { FastaRecord, FastqRecord, QualRecord, WrapOptions } from './types';\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// ---------------------------------------------------------------------------\n// Readers\n// ---------------------------------------------------------------------------\n\n/**\n * Parse FASTA text (or bytes) into records. Deliberately lenient — it never refuses a\n * file: blank lines and legacy ';' comment lines are ignored, residue lines are\n * concatenated with inner whitespace stripped (case and gaps preserved), and any stray\n * text before the first '>' header is skipped. id = the header up to the first\n * whitespace, description = the remainder.\n */\nexport function parseFasta(input: string | Uint8Array): FastaRecord[] {\n const lines = toLines(input);\n const records: FastaRecord[] = [];\n let header: string | undefined;\n let residues: string[] = [];\n const flush = (): void => {\n if (header !== undefined) records.push(makeFasta(header, residues.join('')));\n };\n for (const line of lines) {\n if (line[0] === '>') {\n flush();\n header = line.slice(1);\n residues = [];\n } else if (isBlank(line) || line[0] === ';') {\n // Blank separators and old-style ';' comment lines carry no residues.\n continue;\n } else if (header === undefined) {\n // Stray text before the first '>' header (BOM, junk): skip it, don't refuse the file.\n continue;\n } else {\n residues.push(line);\n }\n }\n flush();\n return records;\n}\n\n/**\n * Parse FASTQ text (or bytes) into records with decoded Phred+33 qualities.\n *\n * Handles multi-line records: the sequence runs to the '+' separator, then the quality\n * runs until it has as many chars as the sequence has residues. Length — not \"the next\n * line starting with @\" — terminates the quality block, because a quality character can\n * itself be '@' (Phred 31) or '+' (Phred 10); this is the one subtlety the spec calls\n * out (Cock et al. 2010).\n *\n * Deliberately lenient — it never refuses a file, and never lets one malformed record\n * cost a *following* one. A stray line where a '@' header is expected is skipped (resync\n * at the next '@'); a record with no '+' separator (truncated, or the next record starts)\n * keeps its sequence with unknown quality; a short/over-long or out-of-range quality is\n * reconciled to the residue count in {@link makeFastq}. The sequence — what callers\n * actually pick — is always preserved intact, for every record.\n *\n * Cross-record safety comes from recognizing a real next-record header structurally: a\n * line beginning '@' is the next header (not this record's quality) when a '+' separator\n * follows its sequence before any other '@' — see {@link startsRecord}. This is exact for\n * strict 4-line FASTQ (the real-world norm, where a quality line is followed only by the\n * next '@' header or EOF) and preserves every following record even when a quality block is\n * badly truncated. The one accepted blind spot is a deliberate trade-off: '@' and '+' are\n * both valid Phred+33 characters, so in *wrapped* multi-line quality a continuation line\n * that begins '@' and is later followed (before the next header) by one beginning '+' is\n * misread as a header. That pattern is vanishingly rare, and favoring \"never drop the next\n * record's sequence on truncated input\" over it is the right call for this parser's use.\n */\nexport function parseFastq(input: string | Uint8Array): FastqRecord[] {\n const lines = toLines(input);\n const records: FastqRecord[] = [];\n let i = 0;\n while (i < lines.length) {\n if (isBlank(lines[i]) || lines[i][0] !== '@') {\n // Blank line, or a stray/garbled line where a header is expected: skip and resync.\n i++;\n continue;\n }\n const header = lines[i].slice(1);\n i++;\n // Sequence: up to the '+' separator (may span multiple lines). Stop early at a '@'\n // too: residue lines never begin '@', so it means the '+' is missing and the next\n // record has started — don't swallow it.\n const seqParts: string[] = [];\n while (i < lines.length && lines[i][0] !== '+' && lines[i][0] !== '@') {\n seqParts.push(lines[i]);\n i++;\n }\n const sequence = stripWhitespace(seqParts.join(''));\n if (i >= lines.length || lines[i][0] === '@') {\n // No '+' separator: truncated final record, or the next record begins here. Keep\n // this sequence (quality unknown); the '@', if any, is re-read as the next header.\n records.push(makeFastq(header, sequence, ''));\n continue;\n }\n i++; // skip the '+' line (it may repeat the id; we do not require or check that)\n // Quality: accumulate until it matches the residue count. Whitespace-only wrap is\n // stripped (a real Phred+33 char is never a space/tab), so it never inflates the count.\n // A line beginning '@' that opens a well-formed record is the NEXT header even while\n // this quality is still short — hand it back rather than swallowing that record.\n let quality = '';\n while (i < lines.length && quality.length < sequence.length) {\n if (lines[i][0] === '@' && startsRecord(lines, i)) break;\n quality += stripWhitespace(lines[i]);\n i++;\n }\n records.push(makeFastq(header, sequence, quality));\n }\n return records;\n}\n\n// ---------------------------------------------------------------------------\n// Writers\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// ---------------------------------------------------------------------------\n// Internals — readers\n// ---------------------------------------------------------------------------\n\n/** Build a FASTA record from a raw header (sans '>') and joined residue text. */\nfunction makeFasta(header: string, residues: string): FastaRecord {\n const { id, description } = splitHeader(header);\n const sequence = stripWhitespace(residues);\n return description === undefined ? { id, sequence } : { id, description, sequence };\n}\n\n/**\n * Build a FASTQ record, decoding quality to Phred scores reconciled to the residue\n * count: missing trailing quality (short / truncated line) reads as Phred 0, extra\n * quality chars are dropped, and bytes outside the printable Phred+33 range are clamped\n * into [0, MAX_PHRED]. Never throws — a malformed quality never costs the caller the\n * sequence.\n */\nfunction makeFastq(header: string, sequence: string, quality: string): FastqRecord {\n const { id, description } = splitHeader(header);\n const qualities = new Array<number>(sequence.length);\n for (let k = 0; k < sequence.length; k++) {\n const code = k < quality.length ? quality.charCodeAt(k) : PHRED_OFFSET;\n qualities[k] = clampPhred(code - PHRED_OFFSET);\n }\n return description === undefined ? { id, sequence, qualities } : { id, description, sequence, qualities };\n}\n\n/** Split a header line (already stripped of its '>'/'@') into id and optional description. */\nfunction splitHeader(header: string): { id: string; description?: string } {\n const trimmed = header.trim();\n const space = trimmed.search(/\\s/);\n if (space < 0) return { id: trimmed };\n return { id: trimmed.slice(0, space), description: trimmed.slice(space + 1).trim() || undefined };\n}\n\n/**\n * Whether line `i` (already known to begin '@') opens a FASTQ record rather than being a\n * quality line that merely starts with '@'. True when a '+' separator follows its sequence\n * lines before the next '@' or EOF. Exact for strict 4-line FASTQ; for the rare wrapped-\n * quality blind spot this shares, see {@link parseFastq}.\n */\nfunction startsRecord(lines: string[], i: number): boolean {\n let j = i + 1;\n while (j < lines.length && lines[j][0] !== '+' && lines[j][0] !== '@') j++;\n return lines[j]?.[0] === '+';\n}\n\n// ---------------------------------------------------------------------------\n// Internals — writers\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","/**\n * GenBank / GenPept flat-file reader — sequence extraction only.\n *\n * Reads the sequence(s) and their identity out of GenBank flat files (`.gb`/`.gbk`/`.gbff`,\n * and the protein `.gp` variant). One file may hold many records, each ending in `//`. We\n * take what a \"pick a sequence\" caller needs and skip the rest:\n * - id: VERSION (accession.version) if present, else ACCESSION, else the LOCUS name.\n * - description: DEFINITION (its continuation lines joined).\n * - sequence: the ORIGIN block, with the leading base counters and spacing stripped.\n * Feature-table parsing (locations, /translation, join/complement) is intentionally out of\n * scope here — this is the sequence-reading path, not a full annotation model.\n *\n * Deliberately lenient (see AGENTS.md): never throws. A record with no ORIGIN yields an\n * empty sequence rather than an error; a missing `//` between records (or a truncated final\n * record) still yields every record whose LOCUS was seen. Sequence case is preserved as\n * written (GenBank ORIGIN is conventionally lowercase).\n */\n\nimport { makeSeqRecord, SeqRecord } from '../seq-record';\nimport { firstToken, stripWhitespace, toLines } from '../text';\n\n/** A top-level GenBank keyword: starts in column 0 (letters/digits), unlike indented lines. */\nconst KEYWORD = /^([A-Za-z][A-Za-z0-9_]*)/;\n\nexport function parseGenbank(input: string | Uint8Array): SeqRecord[] {\n const lines = toLines(input);\n const records: SeqRecord[] = [];\n\n let started = false;\n let locus = '';\n let accession = '';\n let version = '';\n let definition: string[] = [];\n let seq: string[] = [];\n let mode: 'header' | 'definition' | 'origin' = 'header';\n\n const flush = (): void => {\n if (!started) return;\n const id = version || accession || locus;\n records.push(makeSeqRecord(id, definition.join(' ').trim(), stripWhitespace(seq.join(''))));\n started = false;\n locus = accession = version = '';\n definition = [];\n seq = [];\n mode = 'header';\n };\n\n for (const line of lines) {\n if (line.startsWith('//')) {\n flush();\n continue;\n }\n const isKeyword = line.length > 0 && !/^\\s/.test(line);\n\n if (mode === 'origin') {\n if (isKeyword)\n mode = 'header'; // a keyword ends the ORIGIN block; handle it below\n else {\n seq.push(line.replace(/[\\s\\d]/g, '')); // drop the position counter and column spacing\n continue;\n }\n }\n if (mode === 'definition' && !isKeyword) {\n definition.push(line.trim()); // DEFINITION continues onto indented lines\n continue;\n }\n if (!isKeyword) continue; // an indented line we don't collect (feature qualifiers, etc.)\n\n const key = (KEYWORD.exec(line)?.[1] ?? '').toUpperCase();\n const value = line.slice(key.length).trim();\n if (key === 'LOCUS' && started) flush(); // next record without a preceding '//'\n started = true;\n mode = 'header';\n if (key === 'LOCUS') locus = firstToken(value);\n else if (key === 'ACCESSION') accession = firstToken(value);\n else if (key === 'VERSION') version = firstToken(value);\n else if (key === 'DEFINITION') {\n definition = [value];\n mode = 'definition';\n } else if (key === 'ORIGIN') mode = 'origin';\n }\n flush();\n return records;\n}\n","/**\n * GFA (Graphical Fragment Assembly, `.gfa`) reader — sequence extraction.\n *\n * Assembly / pangenome graphs. Only Segment (`S`) lines carry sequence; links, paths, jumps and\n * containments are graph topology and hold none. Both dialects are supported by field position:\n *\n * GFA1: S <name> <sequence> [tags…]\n * GFA2: S <sid> <slen> <sequence> [tags…]\n *\n * GFA2 inserts an integer segment length between the name and the sequence, so when the field after\n * the name is a bare integer AND another field follows, the sequence is that next field; otherwise\n * it's the field right after the name (GFA1). A `*` sequence (a segment declared without residues)\n * is skipped — there's nothing to pick. Lenient: never throws; malformed lines are ignored.\n */\n\nimport { makeSeqRecord, SeqRecord } from '../seq-record';\nimport { toLines } from '../text';\n\nexport function parseGfa(input: string | Uint8Array): SeqRecord[] {\n const records: SeqRecord[] = [];\n for (const line of toLines(input)) {\n // Segment lines only: 'S' followed by a tab.\n if (line.charCodeAt(0) !== 0x53 || line.charCodeAt(1) !== 0x09) continue;\n const f = line.split('\\t');\n const name = f[1];\n if (!name) continue;\n // GFA2 puts an integer length between name and sequence; GFA1 puts the sequence there.\n const seq = /^\\d+$/.test(f[2] ?? '') && f[3] !== undefined ? f[3] : f[2];\n if (!seq || seq === '*') continue;\n records.push(makeSeqRecord(name, '', seq));\n }\n return records;\n}\n","/**\n * GFF3 (`.gff`/`.gff3`) reader — sequence extraction.\n *\n * A GFF3 file is annotation (feature coordinates), which carries NO sequence — except when it\n * embeds a FASTA section after a `##FASTA` directive. This reader returns the records of that\n * embedded FASTA and nothing else; a GFF with no `##FASTA` section yields `[]` (there is no\n * sequence to pick). Feature lines are never turned into sequence.\n */\n\nimport { parseFasta } from '../fastx';\nimport { SeqRecord } from '../seq-record';\nimport { toLines } from '../text';\n\nexport function parseGff(input: string | Uint8Array): SeqRecord[] {\n const lines = toLines(input);\n const fastaAt = lines.findIndex(line => /^##FASTA\\s*$/i.test(line.trim()));\n if (fastaAt < 0) return []; // annotation only — no embedded sequence\n return parseFasta(lines.slice(fastaAt + 1).join('\\n'));\n}\n","/**\n * Multiple-sequence-alignment readers — one aligned row = one record.\n *\n * Covers the common alignment formats: Clustal (`.aln`), Stockholm (`.sto`/`.stk`),\n * PHYLIP (`.phy`), NEXUS (`.nex`) and GCG/MSF (`.msf`). Each returns the alignment's rows\n * as {@link SeqRecord}s: `id` = the taxon/sequence name, `sequence` = that row **with its\n * gap characters preserved** (an aligned row is data; de-gapping is a caller's choice).\n * Only line spacing and wrap are removed. No description field — these formats don't carry\n * a per-row one.\n *\n * Deliberately lenient (see AGENTS.md): never throws, best-effort on malformed input, and\n * always returns every row it can. Interleaved blocks are accumulated by name.\n */\n\nimport { makeSeqRecord, SeqRecord } from '../seq-record';\nimport { decodeText, isBlank, stripWhitespace, toLines } from '../text';\n\n/** Accumulates aligned blocks by row name, preserving first-seen order (handles interleaving). */\nclass Alignment {\n private readonly order: string[] = [];\n private readonly blocks = new Map<string, string[]>();\n\n add(name: string, block: string): void {\n const parts = this.blocks.get(name);\n if (parts) parts.push(block);\n else {\n this.blocks.set(name, [block]);\n this.order.push(name);\n }\n }\n\n toRecords(): SeqRecord[] {\n return this.order.map(name => makeSeqRecord(name, '', stripWhitespace((this.blocks.get(name) ?? []).join(''))));\n }\n}\n\n/** Alignment-column characters: residues (any letter/digit), gaps and match/missing symbols. */\nconst ALIGN_BLOCK = /^[A-Za-z0-9.*?~-]+$/;\n\n/** Read a Clustal (`.aln`) alignment. Also handles the Clustal-format output of MUSCLE, MAFFT, etc. */\nexport function parseClustal(input: string | Uint8Array): SeqRecord[] {\n const aln = new Alignment();\n let seenFirst = false;\n for (const line of toLines(input)) {\n // Blank lines separate blocks; a conservation line is indented (no name in column 0).\n if (isBlank(line) || /^\\s/.test(line)) continue;\n if (!seenFirst) {\n seenFirst = true;\n // The program banner is the first line; every aligner emits its own. Skip it — the\n // block guard below also rejects a banner's prose token, so this is belt-and-braces.\n if (\n /multiple (sequence )?alignment/i.test(line) ||\n /^(CLUSTAL|MUSCLE|MAFFT|T-?COFFEE|PROBCONS|KALIGN|MVIEW|PROMALS)/i.test(line)\n ) {\n continue;\n }\n }\n const m = /^(\\S+)\\s+(\\S+)/.exec(line); // name + one block (trailing coordinate columns ignored)\n if (m && ALIGN_BLOCK.test(m[2])) aln.add(m[1], m[2]);\n }\n return aln.toRecords();\n}\n\n/** Read a Stockholm (`.sto`/`.stk`) alignment; multiple `//`-separated alignments are all returned. */\nexport function parseStockholm(input: string | Uint8Array): SeqRecord[] {\n const records: SeqRecord[] = [];\n let aln = new Alignment();\n for (const line of toLines(input)) {\n if (line.startsWith('//')) {\n records.push(...aln.toRecords());\n aln = new Alignment();\n continue;\n }\n // '#' lines are the header and #=GF/#=GC/#=GR/#=GS markup — not sequence rows.\n if (isBlank(line) || line.startsWith('#')) continue;\n const m = /^(\\S+)\\s+(\\S+)/.exec(line);\n if (m) aln.add(m[1], m[2]);\n }\n records.push(...aln.toRecords());\n return records;\n}\n\n/**\n * Read a PHYLIP (`.phy`) alignment. Supports relaxed (whitespace-delimited names) interleaved\n * and single-block layouts — the common modern output (RAxML/PhyML/aligners). The first line is\n * `<ntax> <nchar>`; the next `ntax` non-blank lines carry names + the first block; any further\n * non-blank lines are interleaved continuation, appended round-robin and clipped at `nchar` so a\n * stray line can't overrun residues into another taxon.\n *\n * Limitation: multi-line *sequential* PHYLIP (each taxon's whole sequence spanning consecutive\n * lines before the next taxon) is read as interleaved and would be misassigned; it is rare next to\n * interleaved output. Single-line sequential (one line per taxon) reads correctly.\n */\nexport function parsePhylip(input: string | Uint8Array): SeqRecord[] {\n const lines = toLines(input);\n let i = 0;\n while (i < lines.length && isBlank(lines[i])) i++;\n const header = (lines[i] ?? '').trim().split(/\\s+/);\n const ntax = Number.parseInt(header[0] ?? '', 10);\n const nchar = Number.parseInt(header[1] ?? '', 10);\n if (!Number.isFinite(ntax) || ntax <= 0) return []; // no \"<ntax> <nchar>\" header — not PHYLIP\n i++;\n\n const names: string[] = [];\n const rows: string[] = [];\n for (; i < lines.length && names.length < ntax; i++) {\n if (isBlank(lines[i])) continue;\n const m = /^(\\S+)\\s+(.*)$/.exec(lines[i]);\n if (!m) continue;\n names.push(m[1]);\n rows.push(m[2].replace(/\\s+/g, ''));\n }\n const nt = names.length;\n if (nt === 0) return [];\n\n // Remaining non-blank lines: interleaved continuation, appended round-robin. Bound each row\n // at nchar (when known) so a stray/sequential line can't overrun residues into another taxon.\n const cap = Number.isFinite(nchar) && nchar > 0 ? nchar : Number.POSITIVE_INFINITY;\n for (let k = 0; i < lines.length; i++) {\n if (isBlank(lines[i])) continue;\n const idx = k % nt;\n if (rows[idx].length < cap) rows[idx] += lines[i].replace(/\\s+/g, '');\n k++;\n }\n return names.map((name, idx) =>\n makeSeqRecord(name, '', cap === Number.POSITIVE_INFINITY ? rows[idx] : rows[idx].slice(0, cap)),\n );\n}\n\n/**\n * Read a NEXUS (`.nex`) DATA/CHARACTERS block's MATRIX. Handles interleaved matrices (names\n * repeat across blocks), space-grouped rows, and a final row that closes the matrix with `;`.\n *\n * Not resolved (kept verbatim / unsupported): `FORMAT MATCHCHAR=.` — a `.` meaning \"same residue\n * as the first taxon here\" is left literal rather than substituted; and label-less matrices\n * (`FORMAT LABELS=NO`, relying on TAXLABELS order) whose rows carry no name are skipped.\n */\nexport function parseNexus(input: string | Uint8Array): SeqRecord[] {\n const text = decodeText(input).replace(/\\[[^\\]]*\\]/g, ''); // drop [ … ] comments (may be inline)\n const aln = new Alignment();\n let inMatrix = false;\n for (const line of text.split(/\\r\\n|\\r|\\n/)) {\n if (!inMatrix) {\n if (/^\\s*matrix\\b/i.test(line)) inMatrix = true; // the MATRIX keyword opens the data\n continue;\n }\n const trimmed = line.trim();\n if (trimmed === ';') break; // MATRIX ends at a ';'\n if (isBlank(trimmed)) continue;\n const endsMatrix = trimmed.endsWith(';');\n const data = endsMatrix ? trimmed.slice(0, -1).trim() : trimmed;\n // name + the REST of the row (residues may be space-grouped), unquoting a 'quoted name'.\n const m = /^(\"[^\"]+\"|'[^']+'|\\S+)\\s+(.+)$/.exec(data);\n if (m) aln.add(m[1].replace(/^['\"]|['\"]$/g, ''), m[2].replace(/\\s+/g, ''));\n if (endsMatrix) break;\n }\n return aln.toRecords();\n}\n\n/** Read a GCG/MSF (`.msf`) alignment (the sequence blocks after the header's `//`). */\nexport function parseMsf(input: string | Uint8Array): SeqRecord[] {\n const aln = new Alignment();\n let inSeq = false;\n for (const line of toLines(input)) {\n if (!inSeq) {\n if (line.trimStart().startsWith('//')) inSeq = true; // '//' separates header from sequence\n continue;\n }\n if (isBlank(line)) continue;\n const m = /^\\s*(\\S+)\\s+(.+)$/.exec(line);\n if (m) aln.add(m[1], m[2].replace(/\\s+/g, '')); // name + space-grouped residues (gaps '.'/'~' kept)\n }\n return aln.toRecords();\n}\n","/**\n * PIR / NBRF (`.pir`) reader — sequence extraction.\n *\n * A PIR record is: a header `>XX;identifier` (the two-letter code XX is the sequence type —\n * P1/F1 protein, DL/DC DNA, RL/RC RNA, N1/N3 nucleotide, XX other), a free-text title line,\n * then the residues, terminated by `*`. One file may hold many records.\n * - id: the identifier after the `;` (or the whole header when there is no `;`).\n * - description: the title line.\n * - sequence: the residues with spacing removed and the single trailing `*` terminator dropped.\n *\n * Deliberately lenient (see AGENTS.md): never throws; a truncated record (no `*`) keeps its\n * residues; the first line after a header is taken as the title.\n */\n\nimport { makeSeqRecord, SeqRecord } from '../seq-record';\nimport { stripWhitespace, toLines } from '../text';\n\nexport function parsePir(input: string | Uint8Array): SeqRecord[] {\n const records: SeqRecord[] = [];\n let id: string | undefined;\n let description = '';\n let seq: string[] = [];\n let awaitingTitle = false;\n\n const flush = (): void => {\n if (id === undefined) return;\n let sequence = stripWhitespace(seq.join(''));\n if (sequence.endsWith('*')) sequence = sequence.slice(0, -1); // drop the PIR terminator\n records.push(makeSeqRecord(id, description, sequence));\n id = undefined;\n description = '';\n seq = [];\n awaitingTitle = false;\n };\n\n for (const line of toLines(input)) {\n if (line.startsWith('>')) {\n flush();\n const header = line.slice(1);\n const semi = header.indexOf(';');\n id = (semi >= 0 ? header.slice(semi + 1) : header).trim();\n awaitingTitle = true;\n } else if (id === undefined) {\n continue; // stray text before the first header\n } else if (awaitingTitle) {\n description = line.trim(); // the line right after the header is the title\n awaitingTitle = false;\n } else {\n seq.push(line);\n }\n }\n flush();\n return records;\n}\n","/**\n * Shared SAM/BAM alignment-flag helpers — the two readers (text SAM, binary BAM) apply identical\n * record semantics, so the FLAG bits and the id/description conventions live here once.\n */\n\nexport const FLAG_PAIRED = 0x1;\nexport const FLAG_UNMAPPED = 0x4;\nexport const FLAG_REVERSE = 0x10;\nexport const FLAG_FIRST = 0x40;\nexport const FLAG_LAST = 0x80;\nexport const FLAG_SECONDARY = 0x100;\nexport const FLAG_SUPPLEMENTARY = 0x800;\n\n/** Skip records that re-map an already-seen read, so each read yields one sequence. */\nexport function isSecondaryOrSupplementary(flag: number): boolean {\n return (flag & (FLAG_SECONDARY | FLAG_SUPPLEMENTARY)) !== 0;\n}\n\n/** QNAME, plus a /1 or /2 mate suffix for paired reads so both mates of a pair stay distinct. */\nexport function mateId(qname: string, flag: number): string {\n if (flag & FLAG_PAIRED) {\n if (flag & FLAG_FIRST) return `${qname}/1`;\n if (flag & FLAG_LAST) return `${qname}/2`;\n }\n return qname;\n}\n\n/** Short mapping hint: \"RNAME:POS (+/-)\" when mapped, else \"unmapped\". `pos` is 1-based here. */\nexport function locusHint(rname: string | undefined, pos: number, flag: number): string {\n if (flag & FLAG_UNMAPPED || !rname || rname === '*') return 'unmapped';\n return `${rname}:${pos} (${flag & FLAG_REVERSE ? '-' : '+'})`;\n}\n","/**\n * BAM (`.bam`) reader — read-sequence extraction from the binary alignment format.\n *\n * BAM is the binary twin of SAM. On disk it is BGZF-compressed (a gzip stream of concatenated\n * blocks); this reader expects the INFLATED bytes — starting with the \"BAM\\1\" magic. The caller\n * peels the gzip/BGZF wrapper first (a gzip decompressor decodes BGZF's concatenated members), so\n * this stays a synchronous, dependency-free binary parser.\n *\n * Semantics mirror the SAM reader exactly (see {@link parseSam}): one sequence per read (secondary\n * 0x100 / supplementary 0x800 skipped), reverse-strand sequence stored verbatim (reference-forward),\n * id = read name (+ /1,/2 for paired mates), description = \"RNAME:POS (+/-)\" or \"unmapped\". Records\n * without a stored sequence (l_seq = 0) are skipped. Lenient: on any truncation or garble it stops\n * and returns what it parsed cleanly, never throwing.\n */\n\nimport { makeSeqRecord, SeqRecord } from '../seq-record';\nimport { isSecondaryOrSupplementary, locusHint, mateId } from './common';\n\n/** 4-bit encoded base → IUPAC letter (BAM spec `seq_nt16_str`), indexed by nibble 0–15. */\nconst SEQ_NT16 = '=ACMGRSVTWYHKDBN';\n\n/** Fixed-size prefix of an alignment record before the variable read_name/cigar/seq/qual/tags. */\nconst ALIGN_FIXED = 32;\n\nexport function parseBam(bytes: Uint8Array): SeqRecord[] {\n const records: SeqRecord[] = [];\n // \"BAM\\1\" magic — absent unless the BGZF/gzip wrapper was already inflated by the caller.\n if (!(bytes[0] === 0x42 && bytes[1] === 0x41 && bytes[2] === 0x4d && bytes[3] === 0x01)) return records;\n\n const dv = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);\n const dec = new TextDecoder();\n const cstr = (at: number, len: number): string => dec.decode(bytes.subarray(at, at + Math.max(0, len - 1)));\n\n try {\n // Header + reference table. Every length is bounds-checked BEFORE advancing: a malformed header\n // (e.g. a huge n_ref with a non-advancing negative l_name) must not loop/allocate unboundedly on\n // untrusted input — bail out with whatever was parsed (nothing, here) instead.\n const len = bytes.length;\n let p = 4;\n if (p + 4 > len) return records;\n const lText = dv.getInt32(p, true);\n p += 4;\n if (lText < 0 || p + lText + 4 > len) return records;\n p += lText; // skip the SAM header text\n const nRef = dv.getInt32(p, true);\n p += 4;\n if (nRef < 0) return records;\n const refs: string[] = [];\n for (let i = 0; i < nRef; i++) {\n if (p + 4 > len) return records;\n const lName = dv.getInt32(p, true);\n p += 4;\n if (lName <= 0 || p + lName + 4 > len) return records;\n refs.push(cstr(p, lName));\n p += lName + 4; // name + l_ref\n }\n\n while (p + 4 <= bytes.length) {\n const blockSize = dv.getInt32(p, true);\n p += 4;\n if (blockSize < ALIGN_FIXED || p + blockSize > bytes.length) break; // truncated → stop cleanly\n const end = p + blockSize;\n\n const refID = dv.getInt32(p, true);\n const pos = dv.getInt32(p + 4, true);\n const lReadName = dv.getUint8(p + 8);\n const nCigar = dv.getUint16(p + 12, true);\n const flag = dv.getUint16(p + 14, true);\n const lSeq = dv.getInt32(p + 16, true);\n\n let q = p + ALIGN_FIXED;\n const name = cstr(q, lReadName);\n q += lReadName + nCigar * 4; // skip read_name + CIGAR\n const seqBytes = (lSeq + 1) >> 1;\n if (lSeq > 0 && q + seqBytes <= end && !isSecondaryOrSupplementary(flag)) {\n const rname = refID >= 0 && refID < refs.length ? refs[refID] : '*';\n records.push(makeSeqRecord(mateId(name, flag), locusHint(rname, pos + 1, flag), decodeSeq(bytes, q, lSeq)));\n }\n p = end;\n }\n } catch {\n // Truncated/garbled binary — keep whatever parsed cleanly.\n }\n return records;\n}\n\n/** Decode `lSeq` 4-bit-packed bases (2 per byte, high nibble first) starting at byte offset `at`. */\nfunction decodeSeq(bytes: Uint8Array, at: number, lSeq: number): string {\n let s = '';\n for (let i = 0; i < lSeq; i++) {\n const byte = bytes[at + (i >> 1)];\n s += SEQ_NT16[i & 1 ? byte & 0x0f : byte >> 4];\n }\n return s;\n}\n","/**\n * SAM (`.sam`) reader — read-sequence extraction.\n *\n * SAM is a read-alignment format: one record per alignment, tab-delimited, with 11 mandatory\n * fields (QNAME FLAG RNAME POS MAPQ CIGAR RNEXT PNEXT TLEN SEQ QUAL). This reader returns each\n * record's read sequence — field 10, `SEQ`. Records whose SEQ is `*` (sequence not stored) are\n * skipped: there's nothing to pick.\n *\n * The sequence is returned VERBATIM as written. For a reverse-strand alignment (FLAG bit 0x10) SAM\n * already stores the reverse complement (reference-forward orientation), so that reference-oriented\n * sequence is what you get — it is deliberately not un-flipped to the original read orientation.\n *\n * One sequence per read: secondary (FLAG 0x100) and supplementary (0x800) alignments are skipped —\n * they re-map the same read (a duplicate, or a hard-clipped split fragment), which would pollute a\n * \"pick the sequences\" list. What's kept is the read's SEQ from its primary (or unmapped) record —\n * i.e. the sequence as SAM stores it, which for a hard-clipped primary alignment omits the clipped\n * flanks rather than reconstructing the original full read.\n *\n * `@`-prefixed lines are skipped as headers — the SAM spec's QNAME charset `[!-?A-~]` excludes '@'\n * (0x40) precisely so a read name can never be confused with a header. Lenient: never throws; lines\n * with fewer than 11 fields are ignored rather than rejected.\n */\n\nimport { makeSeqRecord, SeqRecord } from '../seq-record';\nimport { toLines } from '../text';\nimport { isSecondaryOrSupplementary, locusHint, mateId } from './common';\n\nexport function parseSam(input: string | Uint8Array): SeqRecord[] {\n const records: SeqRecord[] = [];\n for (const line of toLines(input)) {\n if (line.length === 0 || line.charCodeAt(0) === 0x40) continue; // '@' header / blank\n const f = line.split('\\t');\n if (f.length < 11) continue;\n const seq = f[9];\n if (!seq || seq === '*') continue;\n const flag = int(f[1]);\n if (isSecondaryOrSupplementary(flag)) continue; // one sequence per read\n records.push(makeSeqRecord(mateId(f[0], flag), locusHint(f[2], int(f[3]), flag), seq));\n }\n return records;\n}\n\nfunction int(s: string): number {\n const n = Number.parseInt(s, 10);\n return Number.isFinite(n) ? n : 0;\n}\n"]}
|