jbrowse-plugin-graphgenomeviewer 7.2.0 → 7.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunks/GbzBaseSyntenyAdapter-FXMGIM7Z.js +2 -0
- package/dist/chunks/{GbzBaseSyntenyAdapter-NB6WBBZH.js.map → GbzBaseSyntenyAdapter-FXMGIM7Z.js.map} +3 -3
- package/dist/chunks/{GraphGenomeView-4O5F5I37.js → GraphGenomeView-WJ3FIDY2.js} +2 -2
- package/dist/chunks/{GraphTrackSettingsDialog-WZEJAF7F.js → GraphTrackSettingsDialog-ZW7ALMDV.js} +2 -2
- package/dist/chunks/{HighlightColorDialog-SRT2FPXP.js → HighlightColorDialog-VBZRUKD5.js} +2 -2
- package/dist/chunks/{LinearGraphDisplay-Z33PVCJL.js → LinearGraphDisplay-SPOPTJEN.js} +2 -2
- package/dist/chunks/MinigraphBubbleAdapter-QCOMFPLL.js +2 -0
- package/dist/chunks/{MinigraphBubbleAdapter-HDLUZ6YF.js.map → MinigraphBubbleAdapter-QCOMFPLL.js.map} +1 -1
- package/dist/chunks/RgfaTabixAdapter-O3NMNRZ2.js +2 -0
- package/dist/chunks/RgfaTabixAdapter-O3NMNRZ2.js.map +7 -0
- package/dist/chunks/WalkTabixSyntenyAdapter-I3PY6HJ2.js +2 -0
- package/dist/chunks/{WalkTabixSyntenyAdapter-WBHOZLAN.js.map → WalkTabixSyntenyAdapter-I3PY6HJ2.js.map} +1 -1
- package/dist/chunks/chunk-2M4XYSLG.js +2 -0
- package/dist/chunks/chunk-2M4XYSLG.js.map +7 -0
- package/dist/chunks/{chunk-JLGPQO5L.js → chunk-2O3YVA2I.js} +2 -2
- package/dist/chunks/{chunk-CWNJR5XB.js → chunk-44CJ2N3N.js} +1 -1
- package/dist/chunks/{chunk-CWNJR5XB.js.map → chunk-44CJ2N3N.js.map} +1 -1
- package/dist/chunks/chunk-6KUHGRHU.js +2 -0
- package/dist/chunks/chunk-6KUHGRHU.js.map +7 -0
- package/dist/chunks/chunk-6MUBJVBG.js +2 -0
- package/dist/chunks/chunk-6MUBJVBG.js.map +7 -0
- package/dist/chunks/{chunk-GUXZESDR.js → chunk-7HWHWPRW.js} +1 -1
- package/dist/chunks/{chunk-GUXZESDR.js.map → chunk-7HWHWPRW.js.map} +1 -1
- package/dist/chunks/chunk-B2EP6FOQ.js +3 -0
- package/dist/chunks/chunk-B2EP6FOQ.js.map +7 -0
- package/dist/chunks/{chunk-44HZPYGC.js → chunk-BXRTG7FU.js} +2 -2
- package/dist/chunks/{chunk-44HZPYGC.js.map → chunk-BXRTG7FU.js.map} +1 -1
- package/dist/chunks/{chunk-HLKZCTQ3.js → chunk-DBPEUVUC.js} +1 -1
- package/dist/chunks/{chunk-HLKZCTQ3.js.map → chunk-DBPEUVUC.js.map} +1 -1
- package/dist/chunks/{chunk-FME624X3.js → chunk-DUR437TH.js} +2 -2
- package/dist/chunks/{chunk-FME624X3.js.map → chunk-DUR437TH.js.map} +1 -1
- package/dist/chunks/{chunk-6WA6WF6A.js → chunk-FIRQAKMX.js} +1 -1
- package/dist/chunks/{chunk-6WA6WF6A.js.map → chunk-FIRQAKMX.js.map} +1 -1
- package/dist/chunks/chunk-JCAZTNYG.js +2 -0
- package/dist/chunks/chunk-JCAZTNYG.js.map +7 -0
- package/dist/chunks/chunk-N74HGPAW.js +3 -0
- package/dist/chunks/chunk-N74HGPAW.js.map +7 -0
- package/dist/chunks/chunk-PEDWEPNK.js +2 -0
- package/dist/chunks/chunk-PEDWEPNK.js.map +7 -0
- package/dist/chunks/chunk-PYQG3JHP.js +3 -0
- package/dist/chunks/chunk-PYQG3JHP.js.map +7 -0
- package/dist/chunks/chunk-RFDSEB2X.js +4 -0
- package/dist/chunks/chunk-RFDSEB2X.js.map +7 -0
- package/dist/chunks/{chunk-O7Y7LYN6.js → chunk-RW775LQN.js} +2 -2
- package/dist/chunks/{chunk-O7Y7LYN6.js.map → chunk-RW775LQN.js.map} +1 -1
- package/dist/chunks/{chunk-N4WBX2OS.js → chunk-VQ77X5QU.js} +2 -2
- package/dist/chunks/{chunk-N4WBX2OS.js.map → chunk-VQ77X5QU.js.map} +1 -1
- package/dist/chunks/{chunk-LXCMWL7B.js → chunk-WUSKVEA6.js} +2 -2
- package/dist/chunks/{chunk-LXCMWL7B.js.map → chunk-WUSKVEA6.js.map} +1 -1
- package/dist/chunks/{chunk-ZNT7TQLN.js → chunk-YKSUKPYY.js} +2 -2
- package/dist/chunks/chunk-YKSUKPYY.js.map +7 -0
- package/dist/chunks/{renderSvg-RRWCAEGF.js → renderSvg-WD6YDV2I.js} +2 -2
- package/dist/jbrowse-plugin-graphgenomeviewer.esm.js +4 -4
- package/dist/jbrowse-plugin-graphgenomeviewer.esm.js.map +4 -4
- package/package.json +3 -3
- package/src/GbzBaseSyntenyAdapter/GbzBaseSyntenyAdapter.test.ts +2 -2
- package/src/GbzBaseSyntenyAdapter/GbzBaseSyntenyAdapter.ts +1 -1
- package/src/GetSubgraph.ts +1 -1
- package/src/GraphGenomeView/genes/genes.test.ts +20 -2
- package/src/GraphGenomeView/legendSections.test.ts +1 -1
- package/src/GraphGenomeView/legendSections.ts +1 -7
- package/src/GraphGenomeView/model.test.ts +1 -2
- package/src/GraphGenomeView/pane/graphViews.ts +24 -35
- package/src/GraphGenomeView/pane/loadActions.ts +4 -3
- package/src/GraphGenomeView/pane/paneBase.ts +1 -1
- package/src/GraphGenomeView/subgraphLoad.test.ts +41 -1
- package/src/GraphGenomeView/walkRowsCut.ts +10 -44
- package/src/RgfaTabixAdapter/RgfaTabixAdapter.test.ts +23 -4
- package/src/RgfaTabixAdapter/RgfaTabixAdapter.ts +2 -3
- package/src/RgfaTabixAdapter/bubbleTier.test.ts +1 -1
- package/src/RgfaTabixAdapter/walkCut.ts +20 -0
- package/src/RgfaTabixAdapter/walkFiles.test.ts +2 -2
- package/src/RgfaTabixAdapter/walkReader.ts +1 -1
- package/src/WalkTabixSyntenyAdapter/WalkTabixSyntenyAdapter.test.ts +1 -1
- package/src/version.ts +1 -1
- package/dist/chunks/GbzBaseSyntenyAdapter-NB6WBBZH.js +0 -2
- package/dist/chunks/MinigraphBubbleAdapter-HDLUZ6YF.js +0 -2
- package/dist/chunks/RgfaTabixAdapter-XZRTWQMZ.js +0 -3
- package/dist/chunks/RgfaTabixAdapter-XZRTWQMZ.js.map +0 -7
- package/dist/chunks/WalkTabixSyntenyAdapter-WBHOZLAN.js +0 -2
- package/dist/chunks/chunk-BWP3XYKD.js +0 -2
- package/dist/chunks/chunk-BWP3XYKD.js.map +0 -7
- package/dist/chunks/chunk-EDSIYH4H.js +0 -2
- package/dist/chunks/chunk-EDSIYH4H.js.map +0 -7
- package/dist/chunks/chunk-III4GT4G.js +0 -2
- package/dist/chunks/chunk-III4GT4G.js.map +0 -7
- package/dist/chunks/chunk-N5GYTUIL.js +0 -3
- package/dist/chunks/chunk-N5GYTUIL.js.map +0 -7
- package/dist/chunks/chunk-PA4HKAUJ.js +0 -2
- package/dist/chunks/chunk-PA4HKAUJ.js.map +0 -7
- package/dist/chunks/chunk-PFAHNHMM.js +0 -2
- package/dist/chunks/chunk-PFAHNHMM.js.map +0 -7
- package/dist/chunks/chunk-UFQTIWSN.js +0 -4
- package/dist/chunks/chunk-UFQTIWSN.js.map +0 -7
- package/dist/chunks/chunk-VDHDEEMF.js +0 -2
- package/dist/chunks/chunk-VDHDEEMF.js.map +0 -7
- package/dist/chunks/chunk-WGVATZLM.js +0 -3
- package/dist/chunks/chunk-WGVATZLM.js.map +0 -7
- package/dist/chunks/chunk-ZNT7TQLN.js.map +0 -7
- package/src/RgfaTabixAdapter/rgfaBed.test.ts +0 -254
- package/src/RgfaTabixAdapter/rgfaBed.ts +0 -314
- package/src/RgfaTabixAdapter/rgfaCut.ts +0 -139
- package/src/RgfaTabixAdapter/walkRowRuns.test.ts +0 -192
- package/src/RgfaTabixAdapter/walkRowRuns.ts +0 -520
- /package/dist/chunks/{GraphGenomeView-4O5F5I37.js.map → GraphGenomeView-WJ3FIDY2.js.map} +0 -0
- /package/dist/chunks/{GraphTrackSettingsDialog-WZEJAF7F.js.map → GraphTrackSettingsDialog-ZW7ALMDV.js.map} +0 -0
- /package/dist/chunks/{HighlightColorDialog-SRT2FPXP.js.map → HighlightColorDialog-VBZRUKD5.js.map} +0 -0
- /package/dist/chunks/{LinearGraphDisplay-Z33PVCJL.js.map → LinearGraphDisplay-SPOPTJEN.js.map} +0 -0
- /package/dist/chunks/{chunk-JLGPQO5L.js.map → chunk-2O3YVA2I.js.map} +0 -0
- /package/dist/chunks/{renderSvg-RRWCAEGF.js.map → renderSvg-WD6YDV2I.js.map} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../../node_modules/.pnpm/@gmod+gbz-base@7.4.1/node_modules/@gmod/gbz-base/src/chosenPaths.ts", "../../node_modules/.pnpm/@gmod+gbz-base@7.4.1/node_modules/@gmod/gbz-base/src/sha256.ts", "../../node_modules/.pnpm/@gmod+gbz-base@7.4.1/node_modules/@gmod/gbz-base/src/graphName.ts", "../../node_modules/.pnpm/@gmod+gbz-base@7.4.1/node_modules/@gmod/gbz-base/src/pathName.ts", "../../node_modules/.pnpm/@gmod+gbz-base@7.4.1/node_modules/@gmod/gbz-base/src/subgraph.ts", "../../node_modules/.pnpm/@gmod+gbz-base@7.4.1/node_modules/@gmod/gbz-base/src/gbwt/bytecode.ts", "../../node_modules/.pnpm/@gmod+gbz-base@7.4.1/node_modules/@gmod/gbz-base/src/gbwt/record.ts", "../../node_modules/.pnpm/@gmod+gbz-base@7.4.1/node_modules/@gmod/gbz-base/src/query.ts", "../../node_modules/.pnpm/@gmod+gbz-base@7.4.1/node_modules/@gmod/gbz-base/src/sqlite/record.ts", "../../node_modules/.pnpm/@gmod+gbz-base@7.4.1/node_modules/@gmod/gbz-base/src/sqlite/btree.ts", "../../node_modules/.pnpm/@gmod+gbz-base@7.4.1/node_modules/@gmod/gbz-base/src/sqlite/pager.ts", "../../node_modules/.pnpm/@gmod+gbz-base@7.4.1/node_modules/@gmod/gbz-base/src/sqlite/database.ts", "../../node_modules/.pnpm/@gmod+gbz-base@7.4.1/node_modules/@gmod/gbz-base/src/db.ts", "../../node_modules/.pnpm/@jbrowse+bandage-core@11.
|
|
3
|
+
"sources": ["../../node_modules/.pnpm/@gmod+gbz-base@7.4.1/node_modules/@gmod/gbz-base/src/chosenPaths.ts", "../../node_modules/.pnpm/@gmod+gbz-base@7.4.1/node_modules/@gmod/gbz-base/src/sha256.ts", "../../node_modules/.pnpm/@gmod+gbz-base@7.4.1/node_modules/@gmod/gbz-base/src/graphName.ts", "../../node_modules/.pnpm/@gmod+gbz-base@7.4.1/node_modules/@gmod/gbz-base/src/pathName.ts", "../../node_modules/.pnpm/@gmod+gbz-base@7.4.1/node_modules/@gmod/gbz-base/src/subgraph.ts", "../../node_modules/.pnpm/@gmod+gbz-base@7.4.1/node_modules/@gmod/gbz-base/src/gbwt/bytecode.ts", "../../node_modules/.pnpm/@gmod+gbz-base@7.4.1/node_modules/@gmod/gbz-base/src/gbwt/record.ts", "../../node_modules/.pnpm/@gmod+gbz-base@7.4.1/node_modules/@gmod/gbz-base/src/query.ts", "../../node_modules/.pnpm/@gmod+gbz-base@7.4.1/node_modules/@gmod/gbz-base/src/sqlite/record.ts", "../../node_modules/.pnpm/@gmod+gbz-base@7.4.1/node_modules/@gmod/gbz-base/src/sqlite/btree.ts", "../../node_modules/.pnpm/@gmod+gbz-base@7.4.1/node_modules/@gmod/gbz-base/src/sqlite/pager.ts", "../../node_modules/.pnpm/@gmod+gbz-base@7.4.1/node_modules/@gmod/gbz-base/src/sqlite/database.ts", "../../node_modules/.pnpm/@gmod+gbz-base@7.4.1/node_modules/@gmod/gbz-base/src/db.ts", "../../node_modules/.pnpm/@jbrowse+bandage-core@11.4.0/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-HNWJ4B7S.js", "../../node_modules/.pnpm/@jbrowse+bandage-core@11.4.0/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-NMWQUFPF.js"],
|
|
4
4
|
"sourcesContent": ["import {\n ENDMARKER,\n flipNode,\n isReverse,\n nodeId,\n pathEndsAreCanonical,\n} from './gbwt/node.ts'\n\nimport type {\n GBZBase,\n GbzRecord,\n HaplotypeAnchorRow,\n HaplotypeSample,\n HaplotypeStrayOptions,\n} from './db.ts'\nimport type { Orientation } from './gbwt/node.ts'\nimport type { Pos } from './gbwt/record.ts'\nimport type { PathName } from './pathName.ts'\nimport type { SnarlFill, SnarlOutput } from './subgraph.ts'\n\nconst SCAN_GAP = 4096\n\n// Runs of sorted handles close enough to read the haplotype index samples on\n// them with one scan each.\nexport function handleRuns(sortedHandles: number[]) {\n const runs: [number, number][] = []\n for (const handle of sortedHandles) {\n const last = runs[runs.length - 1]\n if (last && handle - last[1] <= SCAN_GAP) {\n last[1] = handle\n } else {\n runs.push([handle, handle])\n }\n }\n return runs\n}\n\n// How far a chain from a twin piece goes outside the subgraph before it stops.\nexport const CHAIN_BOUND = 32768\n\n// Above this many chosen paths at the anchors, extracting and identifying\n// every walk took less time than walking the chosen ones, on HPRC chr22 windows\n// with 42 haplotypes. On HPRC v2.1 the crossover moves with the window: about\n// 12 at C4 and a quiet chr20 window, where walking loses by under 80 ms at 32,\n// and past 32 at MHC class II and AMY1, where it still wins by 0.9 s and 0.2 s,\n// so 32 stays. Tests raise it to run the walks on large sets.\nexport const keepTuning = { mostChosenPaths: 32 }\n\nexport type ChosenPieceSource =\n 'reference' | 'section' | 'stray' | 'chain' | 'twin'\n\nexport interface ChosenPiece {\n pathHandle: number\n orientation: Orientation\n handles: number[]\n offsets: number[]\n len: number\n hapStart: number\n hapEnd: number\n canonical: boolean\n source: ChosenPieceSource\n}\n\nexport type KeepWalkEnd =\n 'merge' | 'landed' | 'bound' | 'endmarker' | 'past the far anchor'\n\nexport interface KeepStats {\n spacing: number | undefined\n // The anchors before and after the window.\n anchors: [number, number] | undefined\n // The anchors within the walks' bound of the bins the window touches, and\n // one beyond on each side.\n anchorsRead: number\n chosenPaths: number\n scans: [number, number][]\n scanRows: number\n // The bins the window touches, the stray rows read in them, those of chosen\n // paths walked, and the bases all walks took outside the subgraph.\n strays:\n | { bins: number; rows: number; walked: number; outsideBp: number }\n | undefined\n pieces: number\n sources: Record<ChosenPieceSource, number>\n walks: Record<string, number>\n twins: { tried: number; found: number }\n graphFetches: number\n // Why the query extracted and identified every walk instead, when it did.\n fallback: string | undefined\n ms: {\n scan: number\n walks: number\n check: number\n twins: number\n }\n}\n\nexport interface ChosenPathsInput {\n db: GBZBase\n records: Map<number, GbzRecord>\n referenceHandle: number\n referencePos: Pos\n referenceLeft: number\n window: { start: number; end: number }\n context: number\n // The snarls the subgraph filled and the nodes those fills added.\n snarls: { mode: SnarlOutput; fills: SnarlFill[]; inserted: Set<number> }\n keep: (name: PathName) => boolean\n signal: AbortSignal | undefined\n prefetchReferenceRange: (\n pathHandle: number,\n fromOffset: number,\n toOffset: number,\n ) => Promise<unknown>\n}\n\ninterface Cursor {\n pos: Pos\n left: number\n}\n\nclass PositionIndex {\n private byNode = new Map<number, Map<number, number>>()\n\n get(pos: Pos) {\n return this.byNode.get(pos.node)?.get(pos.offset)\n }\n\n set(pos: Pos, id: number) {\n let offsets = this.byNode.get(pos.node)\n if (!offsets) {\n offsets = new Map()\n this.byNode.set(pos.node, offsets)\n }\n offsets.set(pos.offset, id)\n }\n}\n\nclass Fallback extends Error {}\n\nfunction forwardLeft(\n orientation: Orientation,\n left: number,\n currentLen: number,\n nextLen: number,\n) {\n return orientation === 'forward' ? left + currentLen : left - nextLen\n}\n\nfunction backwardLeft(\n orientation: Orientation,\n left: number,\n currentLen: number,\n previousLen: number,\n) {\n return orientation === 'forward' ? left - previousLen : left + currentLen\n}\n\nfunction twinIsCanonical(piece: ChosenPiece) {\n return pathEndsAreCanonical(\n flipNode(piece.handles[piece.handles.length - 1]!),\n flipNode(piece.handles[0]!),\n )\n}\n\nfunction pieceKey(piece: ChosenPiece) {\n return `${piece.pathHandle}:${piece.hapStart}:${piece.hapEnd}`\n}\n\n// The pieces a chosen set of haplotypes leaves in a subgraph: every maximal\n// run of one path's positions whose nodes all lie in the subgraph, the pieces\n// extractPaths and identifyPaths find by walking and naming every haplotype.\n// When the haplotype index cannot show that the walks below pass every such\n// piece, the result carries a fallback reason and no pieces, and the caller\n// identifies every walk.\nexport async function findChosenPieces(input: ChosenPathsInput) {\n const { db, records, signal } = input\n let clock = performance.now()\n const lap = () => {\n const now = performance.now()\n const elapsed = now - clock\n clock = now\n return elapsed\n }\n const stats: KeepStats = {\n spacing: await db.haplotypeAnchorSpacing(),\n anchors: undefined,\n anchorsRead: 0,\n chosenPaths: 0,\n scans: [],\n scanRows: 0,\n strays: undefined,\n pieces: 0,\n sources: {\n reference: 0,\n section: 0,\n stray: 0,\n chain: 0,\n twin: 0,\n },\n walks: {},\n twins: { tried: 0, found: 0 },\n graphFetches: 0,\n fallback: undefined,\n ms: { scan: 0, walks: 0, check: 0, twins: 0 },\n }\n const countWalk = (kind: string, end: KeepWalkEnd) => {\n const key = `${kind}: ${end}`\n stats.walks[key] = (stats.walks[key] ?? 0) + 1\n }\n const interval = (await db.haplotypeSampleInterval()) ?? 4096\n const outside = new Map<number, GbzRecord>()\n const record = async (handle: number) => {\n const inside = records.get(handle) ?? outside.get(handle)\n if (inside) {\n return inside\n }\n const fetched = await db.getRecord(handle)\n stats.graphFetches += 1\n if (!fetched) {\n throw new Error(`Node record ${handle} is missing from the database`)\n }\n outside.set(handle, fetched)\n return fetched\n }\n const lengthIn = (handle: number) => records.get(handle)!.sequenceLen\n const pathsByHandle = await db.pathsByHandle()\n const chosen = (pathHandle: number) => {\n const path = pathsByHandle.get(pathHandle)\n return path !== undefined && input.keep(path.name)\n }\n\n const pieces: ChosenPiece[] = []\n const pieceAt = new PositionIndex()\n const piecesOfPath = new Map<number, number[]>()\n const forwardDone = new Set<number>()\n const backwardDone = new Set<number>()\n\n const next = async (pos: Pos): Promise<Pos | undefined> => {\n const successor = (await record(pos.node)).gbwt().lf(pos.offset)\n return successor === undefined || successor.node === ENDMARKER\n ? undefined\n : successor\n }\n const previous = async (\n pos: Pos,\n within?: Map<number, GbzRecord>,\n ): Promise<Pos | undefined> => {\n const predecessor = (await record(flipNode(pos.node)))\n .gbwt()\n .predecessorAt(pos.offset)\n if (\n predecessor === undefined ||\n (within !== undefined && !within.has(predecessor))\n ) {\n return undefined\n }\n const offset = (await record(predecessor)).gbwt().offsetTo(pos)\n if (offset === undefined) {\n throw new Error(\n `No offset in ${predecessor} leads to ${pos.node}:${pos.offset}`,\n )\n }\n return { node: predecessor, offset }\n }\n\n const addPiece = (\n pathHandle: number,\n orientation: Orientation,\n cursors: Cursor[],\n source: ChosenPieceSource,\n ) => {\n const handles = cursors.map(c => c.pos.node)\n const offsets = cursors.map(c => c.pos.offset)\n let len = 0\n for (const handle of handles) {\n len += lengthIn(handle)\n }\n const hapStart =\n orientation === 'forward'\n ? cursors[0]!.left\n : cursors[cursors.length - 1]!.left\n const id = pieces.length\n pieces.push({\n pathHandle,\n orientation,\n handles,\n offsets,\n len,\n hapStart,\n hapEnd: hapStart + len,\n canonical: pathEndsAreCanonical(handles[0], handles[handles.length - 1]),\n source,\n })\n for (const cursor of cursors) {\n pieceAt.set(cursor.pos, id)\n }\n const ofPath = piecesOfPath.get(pathHandle)\n if (ofPath) {\n ofPath.push(id)\n } else {\n piecesOfPath.set(pathHandle, [id])\n }\n return id\n }\n\n // The piece through a position in the subgraph, in that position's\n // orientation of its path.\n const pieceThrough = async (\n seed: Cursor,\n pathHandle: number,\n orientation: Orientation,\n source: ChosenPieceSource,\n ) => {\n const before: Cursor[] = []\n let cursor = seed\n for (;;) {\n signal?.throwIfAborted()\n const pos = await previous(cursor.pos, records)\n if (!pos) {\n break\n }\n cursor = {\n pos,\n left: backwardLeft(\n orientation,\n cursor.left,\n lengthIn(cursor.pos.node),\n lengthIn(pos.node),\n ),\n }\n before.push(cursor)\n }\n before.reverse()\n const after: Cursor[] = [seed]\n cursor = seed\n for (;;) {\n signal?.throwIfAborted()\n const pos = await next(cursor.pos)\n if (!pos || !records.has(pos.node)) {\n break\n }\n cursor = {\n pos,\n left: forwardLeft(\n orientation,\n cursor.left,\n lengthIn(cursor.pos.node),\n lengthIn(pos.node),\n ),\n }\n after.push(cursor)\n }\n return addPiece(pathHandle, orientation, [...before, ...after], source)\n }\n const pieceAtOrThrough = async (\n cursor: Cursor,\n pathHandle: number,\n orientation: Orientation,\n source: ChosenPieceSource,\n ) =>\n pieces[\n pieceAt.get(cursor.pos) ??\n (await pieceThrough(cursor, pathHandle, orientation, source))\n ]!\n\n const lastCursor = (piece: ChosenPiece): Cursor => {\n const node = piece.handles[piece.handles.length - 1]!\n return {\n pos: { node, offset: piece.offsets[piece.offsets.length - 1]! },\n left:\n piece.orientation === 'forward'\n ? piece.hapEnd - lengthIn(node)\n : piece.hapStart,\n }\n }\n const firstCursor = (piece: ChosenPiece): Cursor => {\n const node = piece.handles[0]!\n return {\n pos: { node, offset: piece.offsets[0]! },\n left:\n piece.orientation === 'forward'\n ? piece.hapStart\n : piece.hapEnd - lengthIn(node),\n }\n }\n\n const referenceId = await pieceThrough(\n { pos: input.referencePos, left: input.referenceLeft },\n input.referenceHandle,\n 'forward',\n 'reference',\n )\n const reference = pieces[referenceId]!\n const result = () => {\n if (stats.fallback !== undefined) {\n return { reference, pieces: [], stats }\n }\n // What extractPaths keeps: the canonical twin of each piece, and both twins\n // when both are canonical.\n const byKey = new Map<string, ChosenPiece[]>()\n pieces.forEach((piece, id) => {\n if (id !== referenceId) {\n byKey.set(pieceKey(piece), [\n ...(byKey.get(pieceKey(piece)) ?? []),\n piece,\n ])\n }\n })\n const emitted: ChosenPiece[] = []\n for (const group of byKey.values()) {\n const orientations = new Set<Orientation>()\n for (const piece of group) {\n if (piece.canonical && !orientations.has(piece.orientation)) {\n orientations.add(piece.orientation)\n emitted.push(piece)\n stats.sources[piece.source] += 1\n }\n }\n }\n stats.sources.reference = 1\n stats.pieces = emitted.length + 1\n return { reference, pieces: emitted, stats }\n }\n\n // A chain from a piece, forward or backward, through every piece it lands\n // in, until it meets a known position or runs CHAIN_BOUND bp outside the\n // subgraph.\n const chain = async (id: number, forward: boolean) => {\n const done = forward ? forwardDone : backwardDone\n const other = forward ? backwardDone : forwardDone\n let current = id\n for (;;) {\n if (done.has(current)) {\n return\n }\n done.add(current)\n const piece = pieces[current]!\n let cursor = forward ? lastCursor(piece) : firstCursor(piece)\n let bp = 0\n let end: KeepWalkEnd | undefined\n while (end === undefined) {\n signal?.throwIfAborted()\n const pos = forward\n ? await next(cursor.pos)\n : await previous(cursor.pos)\n if (!pos) {\n end = 'endmarker'\n break\n }\n const currentLen = (await record(cursor.pos.node)).sequenceLen\n const len = (await record(pos.node)).sequenceLen\n const left = forward\n ? forwardLeft(piece.orientation, cursor.left, currentLen, len)\n : backwardLeft(piece.orientation, cursor.left, currentLen, len)\n if (records.has(pos.node)) {\n const known = pieceAt.get(pos)\n if (known === undefined) {\n current = await pieceThrough(\n { pos, left },\n piece.pathHandle,\n piece.orientation,\n 'chain',\n )\n other.add(current)\n end = 'landed'\n } else {\n other.add(known)\n end = 'merge'\n }\n } else if (bp > CHAIN_BOUND) {\n end = 'bound'\n } else {\n bp += len\n cursor = { pos, left }\n }\n }\n countWalk('chain', end)\n if (end !== 'landed') {\n return\n }\n }\n }\n\n // With HaplotypeStrays and HaplotypeBinNodes. The haplotype index lists the\n // nodes of each bin of the reference path, and for each bin the stretches of\n // each path whose visits to those nodes the section walks below can miss.\n // The subgraph is checked against the bins the window touches, so every\n // visit of a chosen path to it lies on a section walk or in a stray row,\n // except inside a filled snarl, where the piece through a boundary node runs\n // on into the snarl, and a path that stays inside the snarl has a row.\n const strayRoute = async (strays: HaplotypeStrayOptions) => {\n if (input.context > strays.context) {\n throw new Fallback(\n `the context of ${input.context} bp exceeds the ${strays.context} bp the haplotype index's stray rows cover`,\n )\n }\n const spacing = stats.spacing\n if (spacing === undefined) {\n throw new Fallback('the haplotype index has no anchors')\n }\n const { bin, bound } = strays\n const { fills, inserted } = input.snarls\n if (input.snarls.mode === 'overlapping' && fills.length > 0) {\n throw new Fallback(\n \"the haplotype index's stray rows cover contained snarls only\",\n )\n }\n for (const fill of fills) {\n if (fill.inserted > 0 && fill.low === fill.high) {\n throw new Fallback(\n `the haplotype index's stray rows leave out the snarl bounded by node ${fill.low} at both ends`,\n )\n }\n if (\n fill.inserted > 0 &&\n (strays.snarlNodes === undefined || fill.nodes > strays.snarlNodes)\n ) {\n throw new Fallback(\n strays.snarlNodes === undefined\n ? \"the haplotype index's stray rows leave snarls out\"\n : `a snarl of ${fill.nodes} nodes exceeds the ${strays.snarlNodes} the haplotype index's stray rows cover`,\n )\n }\n }\n const firstBin = Math.floor(input.window.start / bin)\n const lastBin = Math.floor((input.window.end - 1) / bin)\n const lo = firstBin * bin\n const hi = (lastBin + 1) * bin\n\n // Every anchor within `bound` of the bins, and one beyond on each side.\n // The indexer counts a section whose anchor lies exactly `bound` outside\n // the bins as reaching the visits around it, so the anchor past that one\n // must be read too, or the section between them is never planned. An\n // anchor's node can start far before its multiple, so the first read\n // does not settle it. The bins' node lists and stray rows come in the\n // same round trip.\n const anchorOf = new Map<number, HaplotypeAnchorRow>()\n const readAnchors = async (fromK: number, toK: number) => {\n const rows = await db.haplotypeAnchorsBetween(\n input.referenceHandle,\n fromK * spacing,\n toK * spacing,\n )\n for (const row of rows) {\n anchorOf.set(row.anchorOffset / spacing, row)\n }\n }\n let lowest = Math.max(0, Math.floor((lo - bound) / spacing) - 1)\n let highest = Math.ceil((hi + bound) / spacing) + 1\n const [{ listed, strays: found }] = await Promise.all([\n db.haplotypeBinData(input.referenceHandle, firstBin, lastBin),\n readAnchors(lowest, highest),\n ])\n for (const handle of records.keys()) {\n const id = nodeId(handle)\n if (!isReverse(handle) && !listed(id) && !inserted.has(id)) {\n throw new Fallback(\n `the haplotype index lists node ${id} of the subgraph in no bin that the window touches`,\n )\n }\n }\n // The samples on the subgraph's nodes, for the check after the walks,\n // read while the walks run.\n stats.scans = handleRuns([...records.keys()].sort((x, y) => x - y))\n const scanning = Promise.all(\n stats.scans.map(([first, last]) =>\n db.haplotypeSamplesInRange(first, last),\n ),\n )\n scanning.catch(() => undefined)\n while (\n lowest > 0 &&\n (anchorOf.get(lowest)?.pathOffset ?? Number.POSITIVE_INFINITY) >=\n lo - bound\n ) {\n lowest -= 1\n await readAnchors(lowest, lowest)\n }\n while (\n anchorOf.has(highest) &&\n anchorOf.get(highest)!.pathOffset <= hi + bound\n ) {\n highest += 1\n await readAnchors(highest, highest)\n }\n const multiples = [...anchorOf.keys()].sort((x, y) => x - y)\n const own = anchorOf.get(multiples[0] ?? -1)\n if (!own) {\n throw new Fallback('the haplotype index has no anchors on this path')\n }\n const anchorOffset = (k: number) => anchorOf.get(k)!.pathOffset\n // A node that is the anchor of two multiples ends no section.\n const multiplesOf = new Map<number, number[]>()\n for (const k of multiples) {\n const id = nodeId(anchorOf.get(k)!.node)\n multiplesOf.set(id, [...(multiplesOf.get(id) ?? []), k])\n }\n const anchorNodes = [...multiplesOf.keys()]\n const anchorRows = anchorNodes.map(\n id => anchorOf.get(multiplesOf.get(id)![0]!)!.visits,\n )\n if (\n !anchorRows[anchorNodes.indexOf(nodeId(own.node))]!.some(\n row =>\n row.pathHandle === input.referenceHandle &&\n row.orientation === 'forward' &&\n row.pathOffset === own.pathOffset,\n )\n ) {\n throw new Error(\n `The haplotype index has no anchor row for the reference path ${input.referenceHandle} at offset ${own.pathOffset} (node ${nodeId(own.node)}); it does not match this graph`,\n )\n }\n const before = multiples.filter(k => anchorOffset(k) <= input.window.start)\n const after = multiples.filter(k => anchorOffset(k) >= input.window.end)\n stats.anchors = [\n anchorOffset(before[before.length - 1] ?? multiples[0]!),\n anchorOffset(after[0] ?? multiples[multiples.length - 1]!),\n ]\n stats.anchorsRead = multiples.length\n const visits = new Map<\n number,\n { k: number | undefined; row: HaplotypeSample }[]\n >()\n const atAnchors = new Set<number>()\n anchorNodes.forEach((id, i) => {\n const ks = multiplesOf.get(id)!\n const k = ks.length === 1 ? ks[0] : undefined\n for (const row of anchorRows[i]!) {\n atAnchors.add(row.pathHandle)\n if (row.orientation === 'forward' && chosen(row.pathHandle)) {\n visits.set(row.pathHandle, [\n ...(visits.get(row.pathHandle) ?? []),\n { k, row },\n ])\n }\n }\n })\n stats.chosenPaths = [...atAnchors].filter(chosen).length\n if (stats.chosenPaths > keepTuning.mostChosenPaths) {\n throw new Fallback(\n `${stats.chosenPaths} chosen paths pass the anchors, more than ${keepTuning.mostChosenPaths}`,\n )\n }\n\n // A section between visits to adjacent anchors whose span meets the bins\n // is walked whole, `bound` past both visits. One whose span ends up to\n // `bound` outside the bins is walked `bound` to each side of the visit at\n // that end. These are the walks the stray rows count on.\n interface Plan {\n pathHandle: number\n from: HaplotypeSample\n to: HaplotypeSample | undefined\n }\n const plans: Plan[] = []\n let prefetchLo = Number.POSITIVE_INFINITY\n let prefetchHi = 0\n for (const [pathHandle, list] of visits) {\n list.sort((x, y) => x.row.pathOffset - y.row.pathOffset)\n for (let i = 0; i + 1 < list.length; i++) {\n const from = list[i]!\n const to = list[i + 1]!\n if (\n from.k === undefined ||\n to.k === undefined ||\n Math.abs(from.k - to.k) !== 1\n ) {\n continue\n }\n const [low, high] =\n anchorOffset(from.k) <= anchorOffset(to.k) ? [from, to] : [to, from]\n const a = anchorOffset(low.k!)\n const b = anchorOffset(high.k!)\n if (a < hi && b >= lo) {\n plans.push({ pathHandle, from: from.row, to: to.row })\n prefetchLo = Math.min(prefetchLo, a - bound)\n prefetchHi = Math.max(prefetchHi, b + bound)\n } else if (a >= hi && a - hi <= bound) {\n plans.push({ pathHandle, from: low.row, to: undefined })\n prefetchLo = Math.min(prefetchLo, a - bound)\n prefetchHi = Math.max(prefetchHi, a + bound)\n } else if (b < lo && lo - b <= bound) {\n plans.push({ pathHandle, from: high.row, to: undefined })\n prefetchLo = Math.min(prefetchLo, b - bound)\n prefetchHi = Math.max(prefetchHi, b + bound)\n }\n }\n }\n const filled = new Set(fills.map(fill => `${fill.low}:${fill.high}`))\n const rows = found\n .filter(\n row =>\n chosen(row.pathHandle) &&\n (row.snarl === undefined ||\n filled.has(`${row.snarl[0]}:${row.snarl[1]}`)),\n )\n .sort((x, y) => x.pathHandle - y.pathHandle || x.pathStart - y.pathStart)\n stats.strays = {\n bins: lastBin - firstBin + 1,\n rows: found.length,\n walked: 0,\n outsideBp: 0,\n }\n if (prefetchHi > 0) {\n await input.prefetchReferenceRange(\n input.referenceHandle,\n Math.max(0, prefetchLo),\n prefetchHi + 1,\n )\n }\n stats.ms.scan = lap()\n\n // A cap on each walk's bases outside the subgraph.\n const cap = 8 * spacing + 2 * (input.window.end - input.window.start)\n const counted = stats.strays\n let walkBp = 0\n const outside = (len: number) => {\n counted.outsideBp += len\n walkBp += len\n if (walkBp > cap) {\n throw new Fallback(\n `a walk of a chosen path near the window went past its cap of ${cap} bp`,\n )\n }\n }\n // The stretches of each path that walks passed: every node that starts in\n // [x, y). A visit is named by its node's start, so one at `to` is covered\n // when the stretch ends past it.\n const walkedRanges = new Map<number, [number, number][]>()\n const covered = (pathHandle: number, from: number, to: number) =>\n (walkedRanges.get(pathHandle) ?? []).some(([x, y]) => x <= from && to < y)\n const markWalked = (pathHandle: number, from: number, to: number) => {\n walkedRanges.set(pathHandle, [\n ...(walkedRanges.get(pathHandle) ?? []),\n [from, to],\n ])\n }\n // Forward along a path from a position through every node that starts at\n // or before `until`, jumping over the pieces it lands in; returns the\n // offset it reached.\n const walkForward = async (\n pathHandle: number,\n start: Pos,\n startLeft: number,\n until: number,\n source: ChosenPieceSource,\n ) => {\n let pos: Pos | undefined = start\n let left = startLeft\n let reached = left\n while (pos && left <= until) {\n signal?.throwIfAborted()\n let len: number\n if (records.has(pos.node)) {\n const piece = await pieceAtOrThrough(\n { pos, left },\n pathHandle,\n 'forward',\n source,\n )\n const last = lastCursor(piece)\n pos = last.pos\n left = last.left\n len = lengthIn(pos.node)\n reached = Math.max(reached, piece.hapEnd)\n } else {\n len = (await record(pos.node)).sequenceLen\n outside(len)\n reached = Math.max(reached, left + len)\n }\n pos = await next(pos)\n left += len\n }\n return reached\n }\n // Backward from a position through every node that ends after `until`;\n // returns the offset reached.\n const walkBackward = async (\n pathHandle: number,\n start: Pos,\n startLeft: number,\n until: number,\n ) => {\n let cursor: Cursor = { pos: start, left: startLeft }\n let reached = startLeft\n while (cursor.left > until) {\n signal?.throwIfAborted()\n const earlier = await previous(cursor.pos)\n if (!earlier) {\n break\n }\n const len = (await record(earlier.node)).sequenceLen\n const earlierLeft = cursor.left - len\n if (records.has(earlier.node)) {\n const piece = await pieceAtOrThrough(\n { pos: earlier, left: earlierLeft },\n pathHandle,\n 'forward',\n 'section',\n )\n cursor = firstCursor(piece)\n reached = Math.min(reached, piece.hapStart)\n } else {\n outside(len)\n cursor = { pos: earlier, left: earlierLeft }\n reached = Math.min(reached, earlierLeft)\n }\n }\n return reached\n }\n\n for (const { pathHandle, from, to } of plans) {\n const start = from.pathOffset\n const stop = (to ?? from).pathOffset + bound\n if (covered(pathHandle, start - bound, stop)) {\n continue\n }\n const pos = { node: from.node, offset: from.offset }\n walkBp = 0\n const reachedEnd = await walkForward(\n pathHandle,\n pos,\n start,\n stop,\n 'section',\n )\n walkBp = 0\n const reachedStart = await walkBackward(\n pathHandle,\n pos,\n start,\n start - bound,\n )\n markWalked(\n pathHandle,\n Math.min(reachedStart, start - bound),\n Math.max(reachedEnd, stop + 1),\n )\n countWalk(to ? 'section' : 'visit', to ? 'past the far anchor' : 'bound')\n }\n for (const row of rows) {\n if (covered(row.pathHandle, row.pathStart, row.pathEnd)) {\n continue\n }\n walkBp = 0\n const reachedEnd = await walkForward(\n row.pathHandle,\n { node: row.node, offset: row.offset },\n row.pathStart,\n row.pathEnd,\n 'stray',\n )\n markWalked(\n row.pathHandle,\n row.pathStart,\n Math.max(reachedEnd, row.pathEnd + 1),\n )\n counted.walked += 1\n }\n stats.ms.walks = lap()\n\n // A sample of a chosen path on the subgraph's nodes outside every piece\n // would contradict the haplotype index's rows. A sample of the reverse\n // orientation gives a position of the piece's twin.\n const reversed: HaplotypeSample[] = []\n for (const samples of await scanning) {\n for (const sample of samples) {\n stats.scanRows += 1\n if (records.has(sample.node) && chosen(sample.pathHandle)) {\n if (\n !(piecesOfPath.get(sample.pathHandle) ?? []).some(id => {\n const piece = pieces[id]!\n return (\n piece.hapStart <= sample.pathOffset &&\n sample.pathOffset < piece.hapEnd\n )\n })\n ) {\n throw new Fallback(\n `chosen path ${sample.pathHandle} has a sample at ${sample.pathOffset} on the window's nodes that no walk reached`,\n )\n }\n if (sample.orientation === 'reverse') {\n reversed.push(sample)\n }\n }\n }\n }\n for (const sample of reversed) {\n await pieceAtOrThrough(\n {\n pos: { node: sample.node, offset: sample.offset },\n left: sample.pathOffset,\n },\n sample.pathHandle,\n 'reverse',\n 'twin',\n )\n }\n stats.ms.check = lap()\n }\n\n const canonicalTwins = async () => {\n // Canonical twins: a piece found only in the orientation extractPaths\n // drops, or in one of two orientations it keeps, is walked on in that\n // orientation while the samples of the other orientation at each node are\n // read by coordinate. A matching sample gives a position of the other\n // orientation, which is walked forward into the subgraph.\n const orientationsOf = new Map<string, Set<Orientation>>()\n const note = (piece: ChosenPiece) => {\n const key = pieceKey(piece)\n const seen = orientationsOf.get(key)\n if (seen) {\n seen.add(piece.orientation)\n } else {\n orientationsOf.set(key, new Set([piece.orientation]))\n }\n }\n let noted = 0\n const noteNew = () => {\n for (; noted < pieces.length; noted++) {\n note(pieces[noted]!)\n }\n }\n noteNew()\n const hasTwin = (piece: ChosenPiece) =>\n (orientationsOf.get(pieceKey(piece))?.size ?? 0) > 1\n const twinBound = 2 * interval\n // extractPaths keeps the reference walk in either orientation, and its\n // twin like any other walk, which matters when the reference is chosen.\n const needsTwin = (piece: ChosenPiece, id: number) =>\n id === referenceId\n ? chosen(input.referenceHandle) && twinIsCanonical(piece)\n : !piece.canonical || twinIsCanonical(piece)\n for (let id = 0; id < pieces.length; id++) {\n const piece = pieces[id]!\n if (hasTwin(piece) || !needsTwin(piece, id)) {\n continue\n }\n stats.twins.tried += 1\n const other: Orientation =\n piece.orientation === 'forward' ? 'reverse' : 'forward'\n let cursor = lastCursor(piece)\n let walkedBp = 0\n let hit: HaplotypeSample | undefined\n while (!hit && walkedBp <= twinBound) {\n signal?.throwIfAborted()\n const pos = await next(cursor.pos)\n if (!pos) {\n break\n }\n const len = (await record(pos.node)).sequenceLen\n const left = forwardLeft(\n piece.orientation,\n cursor.left,\n (await record(cursor.pos.node)).sequenceLen,\n len,\n )\n const flipped = flipNode(pos.node)\n hit = (await db.haplotypeSamplesInRange(flipped, flipped)).find(\n s =>\n s.pathHandle === piece.pathHandle &&\n s.orientation === other &&\n s.pathOffset === left,\n )\n walkedBp += len\n cursor = { pos, left }\n }\n let walk: Cursor | undefined = hit && {\n pos: { node: hit.node, offset: hit.offset },\n left: hit.pathOffset,\n }\n let toPiece = 0\n while (walk && !hasTwin(piece) && toPiece <= twinBound + piece.len) {\n signal?.throwIfAborted()\n if (records.has(walk.pos.node)) {\n const landed = await pieceAtOrThrough(\n walk,\n piece.pathHandle,\n other,\n 'twin',\n )\n const landedId = pieces.indexOf(landed)\n await chain(landedId, true)\n await chain(landedId, false)\n noteNew()\n walk = lastCursor(landed)\n }\n if (!hasTwin(piece)) {\n const len: number = (await record(walk.pos.node)).sequenceLen\n toPiece += len\n const pos = await next(walk.pos)\n walk = pos\n ? {\n pos,\n left: forwardLeft(\n other,\n walk.left,\n len,\n (await record(pos.node)).sequenceLen,\n ),\n }\n : undefined\n }\n }\n noteNew()\n if (!hasTwin(piece)) {\n throw new Fallback(\n `piece ${pieceKey(piece)} was found in one orientation where extractPaths keeps the other`,\n )\n }\n stats.twins.found += 1\n }\n stats.ms.twins = lap()\n }\n\n try {\n const strays = await db.haplotypeStrayOptions()\n if (strays === undefined) {\n throw new Fallback(\n 'the haplotype index has no stray rows; gbz-haplotype-index 0.2.0 writes them',\n )\n }\n await strayRoute(strays)\n await canonicalTwins()\n } catch (error) {\n if (!(error instanceof Fallback)) {\n throw error\n }\n stats.fallback = error.message\n }\n return result()\n}\n\n// extractPaths's order, which is upstream's: by the walk's start position,\n// handle then offset.\nexport function extractionOrder(a: ChosenPiece, b: ChosenPiece) {\n return a.handles[0]! - b.handles[0]! || a.offsets[0]! - b.offsets[0]!\n}\n", "const K = Uint32Array.from([\n 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1,\n 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,\n 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786,\n 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,\n 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,\n 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,\n 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,\n 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,\n 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,\n 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,\n 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,\n])\n\nconst rotr = (x: number, n: number) => (x >>> n) | (x << (32 - n))\n\n// FIPS 180-4, for pages without crypto.subtle (insecure contexts)\nexport function sha256(bytes: Uint8Array) {\n const blocks = Math.ceil((bytes.length + 9) / 64)\n const padded = new Uint8Array(blocks * 64)\n padded.set(bytes)\n padded[bytes.length] = 0x80\n const view = new DataView(padded.buffer)\n const bits = bytes.length * 8\n view.setUint32(padded.length - 8, Math.floor(bits / 2 ** 32))\n view.setUint32(padded.length - 4, bits >>> 0)\n const h = Uint32Array.from([\n 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c,\n 0x1f83d9ab, 0x5be0cd19,\n ])\n const w = new Uint32Array(64)\n for (let block = 0; block < blocks; block++) {\n for (let t = 0; t < 16; t++) {\n w[t] = view.getUint32(block * 64 + t * 4)\n }\n for (let t = 16; t < 64; t++) {\n const a = w[t - 15]!\n const b = w[t - 2]!\n const s0 = rotr(a, 7) ^ rotr(a, 18) ^ (a >>> 3)\n const s1 = rotr(b, 17) ^ rotr(b, 19) ^ (b >>> 10)\n w[t] = w[t - 16]! + s0 + w[t - 7]! + s1\n }\n let a = h[0]!\n let b = h[1]!\n let c = h[2]!\n let d = h[3]!\n let e = h[4]!\n let f = h[5]!\n let g = h[6]!\n let hh = h[7]!\n for (let t = 0; t < 64; t++) {\n const s1 = rotr(e, 6) ^ rotr(e, 11) ^ rotr(e, 25)\n const ch = (e & f) ^ (~e & g)\n const t1 = (hh + s1 + ch + K[t]! + w[t]!) | 0\n const s0 = rotr(a, 2) ^ rotr(a, 13) ^ rotr(a, 22)\n const maj = (a & b) ^ (a & c) ^ (b & c)\n hh = g\n g = f\n f = e\n e = (d + t1) | 0\n d = c\n c = b\n b = a\n a = (t1 + s0 + maj) | 0\n }\n ;[a, b, c, d, e, f, g, hh].forEach((value, i) => {\n h[i] = h[i]! + value\n })\n }\n const out = new Uint8Array(32)\n const outView = new DataView(out.buffer)\n for (let i = 0; i < 8; i++) {\n outView.setUint32(i * 4, h[i]!)\n }\n return out\n}\n", "import { sha256 } from './sha256.ts'\n\nexport interface GraphName {\n name: string | undefined\n subgraph: Map<string, Set<string>>\n translation: Map<string, Set<string>>\n}\n\nfunction parseRelationships(field: string | undefined, what: string) {\n const relationships = new Map<string, Set<string>>()\n if (field !== undefined) {\n for (const rel of field.split(';')) {\n const parts = rel.split(',')\n const [from, to] = parts\n if (parts.length !== 2 || !from || !to) {\n throw new Error(`Invalid ${what} relationship: ${rel}`)\n }\n let targets = relationships.get(from)\n if (!targets) {\n targets = new Set()\n relationships.set(from, targets)\n }\n targets.add(to)\n }\n }\n return relationships\n}\n\nexport function graphNameFromTags(tags: Map<string, string>): GraphName {\n return {\n name: tags.get('pggname'),\n subgraph: parseRelationships(tags.get('subgraph'), 'subgraph'),\n translation: parseRelationships(tags.get('translation'), 'translation'),\n }\n}\n\nfunction merge(into: Map<string, Set<string>>, from: Map<string, Set<string>>) {\n for (const [key, values] of from) {\n let targets = into.get(key)\n if (!targets) {\n targets = new Set()\n into.set(key, targets)\n }\n for (const value of values) {\n targets.add(value)\n }\n }\n}\n\nexport function subgraphName(name: string, parent: GraphName): GraphName {\n const result: GraphName = {\n name,\n subgraph: new Map(),\n translation: new Map(),\n }\n if (parent.name !== undefined) {\n result.subgraph.set(name, new Set([parent.name]))\n merge(result.subgraph, parent.subgraph)\n merge(result.translation, parent.translation)\n }\n return result\n}\n\nfunction sortedEntries(relationships: Map<string, Set<string>>) {\n return [...relationships.entries()]\n .sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))\n .flatMap(([from, tos]) => [...tos].sort().map(to => [from, to] as const))\n}\n\nexport function gfaHeaderLines(graphName: GraphName) {\n const lines: string[] = []\n if (graphName.name !== undefined) {\n lines.push(`H\\tNM:Z:${graphName.name}`)\n }\n for (const [subgraph, supergraph] of sortedEntries(graphName.subgraph)) {\n lines.push(`H\\tSG:Z:${subgraph},${supergraph}`)\n }\n for (const [from, to] of sortedEntries(graphName.translation)) {\n lines.push(`H\\tTL:Z:${from},${to}`)\n }\n return lines\n}\n\nexport async function sha256Hex(chunks: Uint8Array[]) {\n const total = chunks.reduce((sum, chunk) => sum + chunk.length, 0)\n const bytes = new Uint8Array(total)\n let offset = 0\n for (const chunk of chunks) {\n bytes.set(chunk, offset)\n offset += chunk.length\n }\n const subtle = (globalThis.crypto as Crypto | undefined)?.subtle\n const digest = subtle\n ? new Uint8Array(await subtle.digest('SHA-256', bytes))\n : sha256(bytes)\n return [...digest].map(byte => byte.toString(16).padStart(2, '0')).join('')\n}\n", "export interface PathName {\n sample: string\n contig: string\n haplotype: number\n fragment: number\n}\n\nexport interface PathQuery {\n sample?: string | undefined\n contig: string\n haplotype?: number | undefined\n}\n\nexport type PathRef = string | PathQuery\n\nexport const GENERIC_SAMPLE = '_gbwt_ref'\n\nexport function formatPathName(name: PathName & { end?: number | undefined }) {\n const base = `${name.sample}#${name.haplotype}#${name.contig}`\n return name.end === undefined ? base : `${base}[${name.fragment}-${name.end}]`\n}\n\nconst PAN_SN = /^([^#]+)#(\\d+)#([^#]+?)(?:\\[\\d+-\\d+\\])?$/\nconst BARE_CONTIG = /^([^#]+?)(?:\\[\\d+-\\d+\\])?$/\n\nexport function parsePathName(name: string): PathQuery {\n const panSn = PAN_SN.exec(name)\n if (panSn) {\n return {\n sample: panSn[1]!,\n haplotype: Number(panSn[2]),\n contig: panSn[3]!,\n }\n }\n const bare = BARE_CONTIG.exec(name)\n if (bare) {\n return { contig: bare[1]! }\n }\n throw new Error(\n `\"${name}\" is not a path name; expected \"sample#haplotype#contig\" or a bare contig`,\n )\n}\n\nexport function toPathQuery(ref: PathRef) {\n return typeof ref === 'string' ? parsePathName(ref) : ref\n}\n\nexport function pathNameFor(query: PathQuery, fragment: number): PathName {\n return {\n sample: query.sample ?? GENERIC_SAMPLE,\n contig: query.contig,\n haplotype: query.haplotype ?? 0,\n fragment,\n }\n}\n", "import { extractionOrder, findChosenPieces, handleRuns } from './chosenPaths.ts'\nimport {\n ENDMARKER,\n edgeIsCanonical,\n encodeNode,\n entryOrientation,\n entrySide,\n exitOrientation,\n exitSide,\n flipNode,\n flipSide,\n isReverse,\n nodeId,\n nodeOrientation,\n pathEndsAreCanonical,\n pathIsCanonical,\n} from './gbwt/node.ts'\nimport { gfaHeaderLines, sha256Hex, subgraphName } from './graphName.ts'\nimport { weightedLcs } from './lcs.ts'\nimport { pairAlignments, pairCigar } from './pairAlignment.ts'\nimport { formatPathName } from './pathName.ts'\n\nimport type { ChosenPiece, KeepStats } from './chosenPaths.ts'\nimport type { GBZBase, GbzPath, GbzRecord, HaplotypeSample } from './db.ts'\nimport type { NodeSide, Orientation } from './gbwt/node.ts'\nimport type { Pos } from './gbwt/record.ts'\nimport type { PathName } from './pathName.ts'\n\nexport type HaplotypeOutput = 'all' | 'distinct' | 'reference-only' | 'none'\n\nexport type SnarlOutput = 'none' | 'contained' | 'overlapping'\n\ntype HandleType =\n | { kind: 'snarl-exit'; snarl: [number, number] }\n | { kind: 'chain' }\n | { kind: 'regular' }\n\n// A snarl filled between two boundary nodes: their ids, lower first, the\n// nodes between them, and how many of those the fill added to the subgraph.\nexport interface SnarlFill {\n low: number\n high: number\n nodes: number\n inserted: number\n}\n\nexport interface PathPosition {\n seqOffset: number\n handle: number\n nodeOffset: number\n gbwtOffset: number\n}\n\nexport interface ReferencePath {\n position: PathPosition\n name: PathName\n handle: number\n}\n\nexport interface PathIdentity {\n pathHandle: number\n name: PathName\n orientation: Orientation\n hapStart: number\n hapEnd: number\n}\n\ninterface PathInfo {\n path: number[]\n offsets: number[]\n len: number\n weight: number | undefined\n identity: PathIdentity | undefined\n}\n\ntype EditOp = 'M' | 'I' | 'D'\ntype Edit = [EditOp, number]\n\nexport interface WalkSpan {\n name: PathName\n start: number\n end: number\n}\n\nexport interface SubgraphPath {\n name: string\n weight?: number\n cigar?: string\n path: { id: string; is_reverse: boolean }[]\n}\n\nexport interface SubgraphJson {\n nodes: { id: string; sequence: string }[]\n edges: {\n from: string\n from_is_reverse: boolean\n to: string\n to_is_reverse: boolean\n }[]\n paths: SubgraphPath[]\n}\n\n// A step, and either end of an edge, is a GBWT handle: 2 * nodeId for the\n// forward orientation and 2 * nodeId + 1 for the reverse, which is how the\n// GBWT itself numbers them. nodeId and isReverse read the two halves back.\nexport interface CompactPath {\n name: string\n weight: number | undefined\n cigar: string | undefined\n steps: Int32Array\n}\n\nexport interface CompactSubgraph {\n // Ascending, one entry per node; nodeSequences runs parallel to it.\n nodeIds: Int32Array\n nodeSequences: string[]\n // Handle pairs laid end to end: edges[2i] -> edges[2i + 1].\n edges: Int32Array\n paths: CompactPath[]\n}\n\nexport interface AlignmentSpan {\n strand: '+' | '-'\n refStart: number\n refEnd: number\n cigar: string\n weight: number | undefined\n path: number[]\n start: Pos\n}\n\nexport type HaplotypeAlignment = AlignmentSpan &\n (\n | {\n resolved: true\n name: PathName\n label: string\n pathHandle: number\n hapStart: number\n hapEnd: number\n }\n | { resolved: false }\n )\n\nexport interface HaplotypeRef {\n sample: string\n haplotype: number\n}\n\nexport interface PairAlignmentOptions {\n target: HaplotypeRef\n query?: HaplotypeRef | undefined\n maxGap?: number | undefined\n minMatch?: number | undefined\n bases?: boolean | undefined\n}\n\nexport interface PairAlignment {\n query: PathName\n queryStart: number\n queryEnd: number\n strand: '+' | '-'\n target: PathName\n targetStart: number\n targetEnd: number\n cigar: string\n matches: number\n columns: number\n sharedBases: number\n}\n\nexport interface SubgraphOutputOptions {\n cigar?: boolean | undefined\n names?: 'anonymous' | 'resolved' | undefined\n}\n\nexport interface SubgraphOptions {\n limit?: number | undefined\n signal?: AbortSignal | undefined\n}\n\nexport class SubgraphLimitError extends Error {\n override name = 'SubgraphLimitError'\n readonly limit: number\n readonly windowBp: number | undefined\n readonly walkedBp: number | undefined\n\n constructor(limit: number, walk?: { windowBp: number; walkedBp: number }) {\n super(\n walk === undefined\n ? `Subgraph size limit of ${limit} nodes exceeded`\n : `Subgraph size limit of ${limit} nodes exceeded ${walk.walkedBp} bp into a ${walk.windowBp} bp window`,\n )\n this.limit = limit\n this.windowBp = walk?.windowBp\n this.walkedBp = walk?.walkedBp\n }\n}\n\nfunction sideBefore(\n a: [number, number, NodeSide],\n b: [number, number, NodeSide],\n) {\n return (\n a[0] < b[0] ||\n (a[0] === b[0] && (a[1] < b[1] || (a[1] === b[1] && a[2] < b[2])))\n )\n}\n\nclass SideQueue {\n private heap: [number, number, NodeSide][] = []\n\n push(distance: number, node: number, side: NodeSide) {\n const heap = this.heap\n heap.push([distance, node, side])\n let i = heap.length - 1\n while (i > 0) {\n const parent = (i - 1) >> 1\n if (sideBefore(heap[i]!, heap[parent]!)) {\n ;[heap[i], heap[parent]] = [heap[parent]!, heap[i]!]\n i = parent\n } else {\n break\n }\n }\n }\n\n pop() {\n const heap = this.heap\n const top = heap[0]\n const last = heap.pop()\n if (heap.length > 0 && last !== undefined) {\n heap[0] = last\n let i = 0\n for (;;) {\n const left = 2 * i + 1\n const right = left + 1\n let smallest = i\n if (left < heap.length && sideBefore(heap[left]!, heap[smallest]!)) {\n smallest = left\n }\n if (right < heap.length && sideBefore(heap[right]!, heap[smallest]!)) {\n smallest = right\n }\n if (smallest === i) {\n break\n }\n ;[heap[i], heap[smallest]] = [heap[smallest]!, heap[i]!]\n i = smallest\n }\n }\n return top\n }\n\n get size() {\n return this.heap.length\n }\n}\n\n// Which step of a walk matches which step of the reference, as two parallel\n// arrays rather than a list of pairs: there is one entry per step of every\n// walk being aligned, and a window at HPRC scale has millions of them.\ninterface Matches {\n pathAt: Int32Array\n refAt: Int32Array\n count: number\n}\n\nfunction asMatches(pairs: [number, number][]): Matches {\n const pathAt = new Int32Array(pairs.length)\n const refAt = new Int32Array(pairs.length)\n pairs.forEach(([a, b], i) => {\n pathAt[i] = a\n refAt[i] = b\n })\n return { pathAt, refAt, count: pairs.length }\n}\n\n// The first entry above `bound` of an ascending list, or undefined. Called\n// once per step of every walk being aligned, which is where `Array.find` hurt:\n// it allocated a closure over the bound each time, and scanned from the front\n// of a reference node's occurrence list, which a repeat locus makes long.\nfunction firstAbove(ascending: number[], bound: number) {\n let lo = 0\n let hi = ascending.length\n while (lo < hi) {\n const mid = (lo + hi) >> 1\n if (ascending[mid]! > bound) {\n hi = mid\n } else {\n lo = mid + 1\n }\n }\n return ascending[lo]\n}\n\nfunction posKey(pos: Pos) {\n return `${pos.node}:${pos.offset}`\n}\n\ninterface FragmentAlignment {\n strand: '+' | '-'\n refStart: number\n refEnd: number\n edits: Edit[]\n weight: number | undefined\n path: number[]\n start: Pos\n // Indices into the subgraph's paths, in walk order, and the bases of each\n // that the CIGAR aligns when the piece is aligned alone.\n pieces: number[]\n soloAligned: number[]\n identity:\n | {\n pathHandle: number\n name: PathName\n hapStart: number\n hapEnd: number\n walkForward: boolean\n }\n | undefined\n}\n\nfunction flipPath(path: number[]) {\n return path.map(handle => flipNode(handle)).reverse()\n}\n\nfunction joinable(a: FragmentAlignment, b: FragmentAlignment) {\n const insertion = b.identity!.hapStart - a.identity!.hapEnd\n const deletion =\n a.strand === '+' ? b.refStart - a.refEnd : a.refStart - b.refEnd\n return a.strand === b.strand && insertion >= 0 && deletion >= 0\n ? { insertion, deletion }\n : undefined\n}\n\nfunction joinPair(\n a: FragmentAlignment,\n b: FragmentAlignment,\n gap: { insertion: number; deletion: number },\n): FragmentAlignment {\n const [left, right] = a.strand === '+' ? [a, b] : [b, a]\n const edits = left.edits.map(([op, len]): Edit => [op, len])\n appendGap(edits, gap.insertion, gap.deletion)\n for (const [op, len] of right.edits) {\n appendEdit(edits, op, len)\n }\n const walkForward = a.identity!.walkForward\n const [first, second] = walkForward ? [a, b] : [b, a]\n return {\n strand: a.strand,\n refStart: left.refStart,\n refEnd: right.refEnd,\n edits,\n weight: undefined,\n path: [...first.path, ...second.path],\n start: first.start,\n pieces: [...first.pieces, ...second.pieces],\n soloAligned: [...first.soloAligned, ...second.soloAligned],\n identity: {\n pathHandle: a.identity!.pathHandle,\n name: a.identity!.name,\n hapStart: a.identity!.hapStart,\n hapEnd: b.identity!.hapEnd,\n walkForward,\n },\n }\n}\n\n// Pieces of one path in haplotype order, joined where they are colinear on\n// the reference, and otherwise aligned again as one walk. A piece aligned over\n// less than half its length joins only between two that are.\nfunction joinSiblings(\n fragments: FragmentAlignment[],\n mostlyAligned: (fragment: FragmentAlignment) => boolean,\n alignJointly: (parts: FragmentAlignment[]) => FragmentAlignment | undefined,\n) {\n if (fragments.some(f => f.weight !== undefined)) {\n return fragments\n }\n const byPath = new Map<number, number[]>()\n fragments.forEach((fragment, index) => {\n if (fragment.identity) {\n const siblings = byPath.get(fragment.identity.pathHandle)\n if (siblings) {\n siblings.push(index)\n } else {\n byPath.set(fragment.identity.pathHandle, [index])\n }\n }\n })\n const joined = new Map<number, FragmentAlignment>()\n const consumed = new Set<number>()\n for (const siblings of byPath.values()) {\n siblings.sort(\n (x, y) =>\n fragments[x]!.identity!.hapStart - fragments[y]!.identity!.hapStart,\n )\n let head = siblings[0]!\n let current = fragments[head]!\n let between: number[] = []\n for (const index of siblings.slice(1)) {\n const next = fragments[index]!\n const gap = between.length === 0 ? joinable(current, next) : undefined\n if (gap) {\n current = joinPair(current, next, gap)\n consumed.add(index)\n continue\n }\n if (!mostlyAligned(next)) {\n between.push(index)\n continue\n }\n const joint = mostlyAligned(current)\n ? alignJointly([current, ...between.map(i => fragments[i]!), next])\n : undefined\n if (joint) {\n current = joint\n for (const i of [...between, index]) {\n consumed.add(i)\n }\n } else {\n joined.set(head, current)\n head = index\n current = next\n }\n between = []\n }\n joined.set(head, current)\n }\n return fragments.flatMap((fragment, index) =>\n consumed.has(index) ? [] : [joined.get(index) ?? fragment],\n )\n}\n\nfunction pathPosition(info: PathInfo, k: number): Pos {\n return { node: info.path[k]!, offset: info.offsets[k]! }\n}\n\ninterface Anchor {\n pathHandle: number\n orientation: Orientation\n base: number\n}\n\nexport type ChainEnd =\n | 'in-fragment sample'\n | 'identified sibling'\n | 'out-of-window sample'\n | 'bound'\n | 'endmarker'\n | 'cycle'\n\nexport interface ChainRecord {\n fragments: number\n steps: number\n seeks: number\n reentries: number\n twinLandings: number\n end: ChainEnd\n pathHandle: number | undefined\n}\n\nexport interface IdentificationStats {\n interval: number\n scans: [number, number][]\n windowSamples: number\n fragmentLengths: number[]\n companionSeeks: number\n companionMisses: number\n graphLookups: number\n graphFetches: number\n chains: ChainRecord[]\n}\n\ninterface SubgraphStats {\n orderedAlignments: number\n lcsAlignments: number\n identificationSteps: number\n identificationFetches: number\n identification: IdentificationStats\n // the top-level snarls the query filled, and the nodes those fills added\n snarls: { fills: number; inserted: number }\n keep: KeepStats | undefined\n}\n\nconst PREFETCH_RUN_GAP = 32768\n\nfunction rowidRuns(handles: number[]) {\n const sorted = [...handles].sort((a, b) => a - b)\n const runs: [number, number][] = []\n for (const handle of sorted) {\n const last = runs[runs.length - 1]\n if (last && handle - last[1] <= PREFETCH_RUN_GAP) {\n last[1] = handle\n } else {\n runs.push([handle, handle])\n }\n }\n return runs\n}\n\nexport class Subgraph {\n private records = new Map<number, GbzRecord>()\n private paths: PathInfo[] = []\n private twinStarts = new Set<string>()\n private twinDeferred = false\n private unsettled:\n { paths: PathInfo[]; refId: number | undefined } | undefined\n private refId: number | undefined\n private refPath: PathName | undefined\n private refHandle: number | undefined\n private refInterval: [number, number] | undefined\n private refIndexCache: Map<number, number[]> | undefined\n private refPrefixCache: number[] | undefined\n private walkedBp: number | undefined\n private snarlMode: SnarlOutput = 'none'\n private snarlFills: SnarlFill[] = []\n private snarlNodes = new Set<number>()\n /** @internal */\n readonly stats: SubgraphStats = {\n orderedAlignments: 0,\n lcsAlignments: 0,\n snarls: { fills: 0, inserted: 0 },\n identificationSteps: 0,\n identificationFetches: 0,\n identification: {\n interval: 0,\n scans: [],\n windowSamples: 0,\n fragmentLengths: [],\n companionSeeks: 0,\n companionMisses: 0,\n graphLookups: 0,\n graphFetches: 0,\n chains: [],\n },\n keep: undefined,\n }\n\n private db: GBZBase\n private readonly limit: number | undefined\n private readonly signal: AbortSignal | undefined\n\n private constructor(db: GBZBase, opts: SubgraphOptions) {\n this.db = db\n this.limit = opts.limit\n this.signal = opts.signal\n }\n\n /** @internal */\n static create(db: GBZBase, opts: SubgraphOptions = {}) {\n return new Subgraph(db, opts)\n }\n\n get nodeCount() {\n return this.records.size / 2\n }\n\n get pathCount() {\n this.settleDeferred()\n return this.paths.length\n }\n\n get referenceInterval() {\n return this.refInterval && this.refPath\n ? {\n name: this.refPath,\n start: this.refPath.fragment + this.refInterval[0],\n end: this.refPath.fragment + this.refInterval[1],\n }\n : undefined\n }\n\n hasNode(id: number) {\n return this.records.has(encodeNode(id, 'forward'))\n }\n\n hasHandle(handle: number) {\n return this.records.has(handle)\n }\n\n private record(handle: number) {\n const record = this.records.get(handle)\n if (!record) {\n throw new Error(`Subgraph has no record for handle ${handle}`)\n }\n return record\n }\n\n private sortedHandles() {\n return [...this.records.keys()].sort((a, b) => a - b)\n }\n\n private async addNode(id: number) {\n this.signal?.throwIfAborted()\n if (this.limit !== undefined && this.nodeCount >= this.limit) {\n throw new SubgraphLimitError(this.limit)\n }\n const forward = await this.db.getRecord(encodeNode(id, 'forward'))\n const reverse = await this.db.getRecord(encodeNode(id, 'reverse'))\n if (!forward || !reverse) {\n throw new Error(`Node ${id} does not exist in the graph`)\n }\n this.records.set(forward.handle, forward)\n this.records.set(reverse.handle, reverse)\n }\n\n private async ensureNode(id: number) {\n if (!this.hasNode(id)) {\n await this.addNode(id)\n }\n }\n\n private clearPaths() {\n this.paths = []\n this.twinStarts.clear()\n this.twinDeferred = false\n this.unsettled = undefined\n this.refId = undefined\n this.refPath = undefined\n this.refHandle = undefined\n this.refInterval = undefined\n this.refIndexCache = undefined\n this.refPrefixCache = undefined\n }\n\n /** @internal */\n async pathPosition(query: PathName): Promise<ReferencePath> {\n const path = await this.db.findPath(query)\n if (!path) {\n throw new Error(\n `Cannot find a path covering offset ${query.fragment} of ${formatPathName(query)}`,\n )\n }\n if (!path.isIndexed) {\n throw new Error(\n `The fragment of ${formatPathName(path.name)} at ${path.name.fragment} has not been indexed for random access`,\n )\n }\n const queryOffset = query.fragment - path.name.fragment\n const indexed = await this.db.indexedPosition(path.handle, queryOffset)\n if (!indexed) {\n throw new Error(\n `The fragment of ${formatPathName(path.name)} at ${path.name.fragment} has not been indexed for random access`,\n )\n }\n return this.findPathPosition(\n path,\n queryOffset,\n indexed.pathOffset,\n indexed.pos,\n )\n }\n\n private async findPathPosition(\n path: GbzPath,\n queryOffset: number,\n startOffset: number,\n start: Pos,\n ): Promise<ReferencePath> {\n let pathOffset = startOffset\n let pos = start\n for (;;) {\n await this.ensureNode(nodeId(pos.node))\n const record = this.record(pos.node)\n if (pathOffset + record.sequenceLen > queryOffset) {\n return {\n position: {\n seqOffset: queryOffset,\n handle: pos.node,\n nodeOffset: queryOffset - pathOffset,\n gbwtOffset: pos.offset,\n },\n name: path.name,\n handle: path.handle,\n }\n }\n pathOffset += record.sequenceLen\n const next = record.gbwt().lf(pos.offset)\n if (!next) {\n throw new Error(\n `The fragment of ${formatPathName(path.name)} at ${path.name.fragment} does not contain offset ${queryOffset}`,\n )\n }\n pos = next\n }\n }\n\n /** @internal */\n async aroundPosition(handle: number, nodeOffset: number, context: number) {\n const id = nodeId(handle)\n await this.ensureNode(id)\n const record = this.record(handle)\n const orientation = nodeOrientation(handle)\n const active = new SideQueue()\n active.push(nodeOffset, id, entrySide(orientation))\n active.push(record.sequenceLen - nodeOffset - 1, id, exitSide(orientation))\n return this.insertContext(active, context)\n }\n\n /** @internal */\n prefetchReferenceWalk(reference: ReferencePath, len: number) {\n return this.prefetchReferenceRange(\n reference.handle,\n reference.position.seqOffset,\n reference.position.seqOffset + len,\n )\n }\n\n // One request for the reference walk's node records where their rowids are\n // close, and one prefetch over the runs of them where the walk crosses a gap\n // in node ids (AMY1's reference walk spans two gaps of millions), so the walk\n // after it never fetches leaf pages one at a time.\n private async prefetchReferenceRange(\n pathHandle: number,\n fromOffset: number,\n toOffset: number,\n ) {\n const [first, last] = await Promise.all([\n this.db.indexedPosition(pathHandle, fromOffset),\n this.db.indexedPosition(pathHandle, toOffset),\n ])\n if (first && last) {\n const a = first.pos.node\n const b = last.pos.node\n const whole = await this.db.prefetchRecords([\n [Math.min(a, b), Math.max(a, b) + 1],\n ])\n if (!whole) {\n const positions = await this.db.indexedPositionsBetween(\n pathHandle,\n fromOffset,\n toOffset,\n )\n await this.db.prefetchRecords(\n rowidRuns(positions.map(p => p.pos.node)).map(([lo, hi]) => [\n lo,\n hi + 2,\n ]),\n true,\n )\n }\n }\n return first\n }\n\n /** @internal */\n async aroundInterval(start: PathPosition, len: number, context: number) {\n if (!(len > 0)) {\n throw new Error('Interval length must be greater than 0')\n }\n this.walkedBp = 0\n try {\n return await this.walkInterval(start, len, context)\n } catch (error) {\n throw error instanceof SubgraphLimitError && error.windowBp === undefined\n ? new SubgraphLimitError(error.limit, {\n windowBp: len,\n walkedBp: this.walkedBp,\n })\n : error\n }\n }\n\n /** @internal */\n get referenceWalkedBp() {\n return this.walkedBp\n }\n\n private async walkInterval(\n start: PathPosition,\n len: number,\n context: number,\n ) {\n let pos: Pos = { node: start.handle, offset: start.gbwtOffset }\n let offset = start.nodeOffset\n let remaining = len\n const active = new SideQueue()\n for (;;) {\n const id = nodeId(pos.node)\n const orientation = nodeOrientation(pos.node)\n this.walkedBp = len - remaining\n await this.ensureNode(id)\n const record = this.record(pos.node)\n if (offset >= record.sequenceLen) {\n throw new Error(\n `Offset ${offset} in node ${id} of length ${record.sequenceLen}`,\n )\n }\n active.push(offset, id, entrySide(orientation))\n const distanceToNext = record.sequenceLen - offset\n if (remaining <= distanceToNext) {\n active.push(\n remaining === distanceToNext ? 0 : distanceToNext - remaining - 1,\n id,\n exitSide(orientation),\n )\n break\n }\n active.push(0, id, exitSide(orientation))\n const next = record.gbwt().lf(pos.offset)\n if (!next) {\n throw new Error(\n `No successor for GBWT position (${pos.node}, ${pos.offset})`,\n )\n }\n pos = next\n offset = 0\n remaining -= distanceToNext\n }\n this.walkedBp = len\n return this.insertContext(active, context)\n }\n\n /** @internal */\n async aroundNodes(nodes: Iterable<number>, context: number) {\n const active = new SideQueue()\n for (const id of nodes) {\n await this.ensureNode(id)\n active.push(0, id, 'left')\n active.push(0, id, 'right')\n }\n return this.insertContext(active, context)\n }\n\n private async insertContext(active: SideQueue, context: number) {\n this.clearPaths()\n this.snarlMode = 'none'\n this.snarlFills = []\n this.snarlNodes.clear()\n this.stats.snarls = { fills: 0, inserted: 0 }\n const visited = new Set<string>()\n const toRemove = new Set<number>()\n for (const handle of this.records.keys()) {\n toRemove.add(nodeId(handle))\n }\n let inserted = 0\n while (active.size > 0) {\n const [distance, id, side] = active.pop()!\n const key = `${id}:${side}`\n if (visited.has(key)) {\n continue\n }\n visited.add(key)\n toRemove.delete(id)\n if (!this.hasNode(id)) {\n await this.addNode(id)\n inserted += 1\n }\n const otherSide = flipSide(side)\n if (!visited.has(`${id}:${otherSide}`)) {\n const record = this.record(encodeNode(id, entryOrientation(side)))\n const nextDistance = distance + record.sequenceLen - 1\n if (nextDistance <= context) {\n active.push(nextDistance, id, otherSide)\n }\n }\n const record = this.record(encodeNode(id, exitOrientation(side)))\n const nextDistance = distance + 1\n if (nextDistance <= context) {\n for (const successor of record.successors()) {\n const successorId = nodeId(successor)\n const successorSide = entrySide(nodeOrientation(successor))\n if (!visited.has(`${successorId}:${successorSide}`)) {\n active.push(nextDistance, successorId, successorSide)\n }\n }\n }\n }\n for (const id of toRemove) {\n this.records.delete(encodeNode(id, 'forward'))\n this.records.delete(encodeNode(id, 'reverse'))\n }\n return { inserted, removed: toRemove.size }\n }\n\n /** @internal */\n async betweenNodes(start: number, end: number) {\n return (await this.fillBetween(start, end)).inserted.length\n }\n\n private async fillBetween(start: number, end: number) {\n this.clearPaths()\n const active = [start, flipNode(end)]\n const visited = new Set([nodeId(start), nodeId(end)])\n const inserted: number[] = []\n while (active.length > 0) {\n const curr = active.pop()!\n const id = nodeId(curr)\n if (!this.hasNode(id)) {\n await this.addNode(id)\n inserted.push(id)\n }\n for (const successor of this.record(curr).successors()) {\n const successorId = nodeId(successor)\n if (!visited.has(successorId)) {\n active.push(successor, flipNode(successor))\n visited.add(successorId)\n }\n }\n }\n return { inserted, nodes: visited.size - 2 }\n }\n\n /** @internal */\n async extractSnarls(snarls: SnarlOutput) {\n let total = 0\n this.snarlMode = snarls\n for (const [start, end] of await this.overlappingSnarls(snarls)) {\n const { inserted, nodes } = await this.fillBetween(start, end)\n const a = nodeId(start)\n const b = nodeId(end)\n this.snarlFills.push({\n low: Math.min(a, b),\n high: Math.max(a, b),\n nodes,\n inserted: inserted.length,\n })\n for (const id of inserted) {\n this.snarlNodes.add(id)\n }\n total += inserted.length\n }\n this.stats.snarls = {\n fills: this.snarlFills.length,\n inserted: this.snarlNodes.size,\n }\n return total\n }\n\n private async overlappingSnarls(snarls: SnarlOutput) {\n const result: [number, number][] = []\n if (snarls !== 'none') {\n let foundLink = false\n for (const handle of this.sortedHandles()) {\n const record = this.record(handle)\n const next = record.next\n if (next !== undefined) {\n foundLink = true\n if (this.hasHandle(next)) {\n if (edgeIsCanonical(handle, next)) {\n result.push([handle, next])\n }\n } else if (\n snarls === 'overlapping' &&\n this.isSnarlEntryInSubgraph(record)\n ) {\n result.push([handle, next])\n }\n }\n }\n if (\n !foundLink &&\n snarls === 'overlapping' &&\n (await this.db.hasChainLinks())\n ) {\n const covering = await this.findCoveringSnarl()\n if (covering) {\n result.push(covering)\n }\n }\n }\n return result\n }\n\n private isSnarlEntryInSubgraph(record: GbzRecord) {\n const successors = record.successors()\n const first = successors.find(handle => this.hasHandle(handle))\n return first === undefined\n ? false\n : successors.length > 1 ||\n this.record(flipNode(first)).successors().length > 1\n }\n\n private recordReader(onFetch?: () => void) {\n const outside = new Map<number, GbzRecord>()\n return async (handle: number) => {\n const inside = this.records.get(handle)\n if (inside) {\n return inside\n }\n let record = outside.get(handle)\n if (!record) {\n record = await this.db.getRecord(handle)\n onFetch?.()\n if (!record) {\n throw new Error(`Node record ${handle} is missing from the database`)\n }\n outside.set(handle, record)\n }\n return record\n }\n }\n\n private async findCoveringSnarl() {\n const read = this.recordReader()\n const isSnarlEntry = async (record: GbzRecord) => {\n const successors = record.successors()\n const first = successors[0]\n return first === undefined\n ? false\n : successors.length > 1 ||\n (await read(flipNode(first))).successors().length > 1\n }\n const classify = async (handle: number): Promise<HandleType> => {\n const reverse = await read(flipNode(handle))\n return reverse.next !== undefined\n ? (await isSnarlEntry(reverse))\n ? { kind: 'snarl-exit', snarl: [flipNode(handle), reverse.next] }\n : { kind: 'chain' }\n : (await read(handle)).next !== undefined\n ? { kind: 'chain' }\n : { kind: 'regular' }\n }\n const visited = new Set<number>()\n const queue = this.sortedHandles().flatMap(handle =>\n this.record(handle).successors(),\n )\n let result: [number, number] | undefined\n let done = false\n while (!done && queue.length > 0) {\n const handle = queue.shift()!\n const id = nodeId(handle)\n if (!this.hasHandle(handle) && !visited.has(id)) {\n visited.add(id)\n const type = await classify(handle)\n if (type.kind === 'snarl-exit') {\n result = type.snarl\n done = true\n } else if (type.kind === 'chain') {\n done = true\n } else {\n for (const orientation of ['forward', 'reverse'] as const) {\n queue.push(\n ...(await read(encodeNode(id, orientation))).successors(),\n )\n }\n }\n }\n }\n return result\n }\n\n /** @internal */\n extractPaths(reference: ReferencePath | undefined, output: HaplotypeOutput) {\n this.clearPaths()\n if (output === 'none') {\n return\n }\n const refPos = reference?.position\n this.refPath = reference?.name\n this.refHandle = reference?.handle\n const handles = this.sortedHandles()\n const count = handles.length\n const indexOf = new Map<number, number>()\n handles.forEach((handle, i) => indexOf.set(handle, i))\n // One flat pair for the whole subgraph, indexed by rowStart[node] + offset,\n // rather than an Int32Array per node. walk() reads a successor on every one\n // of a window's steps \u2014 9.9M of them at MHC class II \u2014 and through an array\n // of forty thousand small buffers each of those is a pointer chase into\n // scattered memory. The per-node arrays die before the walking starts.\n const rowStart = new Int32Array(count + 1)\n const seqLen = new Int32Array(count)\n const rows: { nodes: Int32Array; offsets: Int32Array }[] = []\n for (let i = 0; i < count; i++) {\n const record = this.record(handles[i]!)\n const row = record.gbwt().decompressArrays()\n seqLen[i] = record.sequenceLen\n rows.push(row)\n rowStart[i + 1] = rowStart[i]! + row.nodes.length\n }\n const positions = rowStart[count]!\n const nextIndex = new Int32Array(positions)\n const nextOffset = new Int32Array(positions)\n const hasPredecessor = new Uint8Array(positions)\n for (let i = 0; i < count; i++) {\n const row = rows[i]!\n nextIndex.set(row.nodes, rowStart[i])\n nextOffset.set(row.offsets, rowStart[i])\n }\n rows.length = 0\n for (let k = 0; k < positions; k++) {\n const j = indexOf.get(nextIndex[k]!)\n if (j === undefined) {\n nextIndex[k] = -1\n } else {\n nextIndex[k] = j\n hasPredecessor[rowStart[j]! + nextOffset[k]!] = 1\n }\n }\n const refIndex =\n refPos === undefined ? undefined : indexOf.get(refPos.handle)\n const refGbwtOffset = refPos?.gbwtOffset\n let refOffset: number | undefined\n const walk = (i: number, offset: number, path: number[] | undefined) => {\n const offsets: number[] = []\n let steps = 0\n let len = 0\n let refAt = -1\n let cur = i\n let off = offset\n for (;;) {\n if (cur === refIndex && off === refGbwtOffset) {\n refAt = steps\n }\n if (path) {\n path.push(handles[cur]!)\n offsets.push(off)\n }\n steps += 1\n len += seqLen[cur]!\n const at = rowStart[cur]! + off\n const next = nextIndex[at]!\n if (next < 0) {\n break\n }\n off = nextOffset[at]!\n cur = next\n }\n return { offsets, len, refAt, last: cur }\n }\n const keep = (\n path: number[],\n offsets: number[],\n len: number,\n refAt: number,\n ) => {\n if (refAt >= 0) {\n this.refId = this.paths.length\n refOffset = refAt\n }\n this.paths.push({\n path,\n offsets,\n len,\n weight: undefined,\n identity: undefined,\n })\n }\n const twinsExpected = new Int32Array(count)\n for (let i = 0; i < count; i++) {\n const first = handles[i]!\n if (!isReverse(first)) {\n const from = rowStart[i]!\n const degree = rowStart[i + 1]! - from\n for (let offset = 0; offset < degree; offset++) {\n if (hasPredecessor[from + offset] === 0) {\n const path: number[] = []\n const { offsets, len, refAt, last } = walk(i, offset, path)\n const lastHandle = handles[last]!\n if (refAt >= 0 || pathEndsAreCanonical(first, lastHandle)) {\n keep(path, offsets, len, refAt)\n if (!isReverse(lastHandle)) {\n const twinRecord = indexOf.get(flipNode(lastHandle))!\n twinsExpected[twinRecord] = twinsExpected[twinRecord]! + 1\n }\n } else {\n this.twinStarts.add(posKey({ node: first, offset }))\n }\n }\n }\n }\n }\n for (let i = 0; i < count; i++) {\n const first = handles[i]!\n if (isReverse(first)) {\n const from = rowStart[i]!\n const degree = rowStart[i + 1]! - from\n let startCount = 0\n for (let offset = 0; offset < degree; offset++) {\n if (hasPredecessor[from + offset] === 0) {\n startCount += 1\n }\n }\n // Until the reference walk is found, it can be one of these starts,\n // with its twin kept above as a walk like any other.\n const allTwins =\n (refIndex === undefined || refOffset !== undefined) &&\n startCount === twinsExpected[i]\n for (let offset = 0; offset < degree; offset++) {\n if (hasPredecessor[from + offset] === 0) {\n const bare = allTwins ? undefined : walk(i, offset, undefined)\n if (\n bare &&\n (bare.refAt >= 0 ||\n pathEndsAreCanonical(first, handles[bare.last]))\n ) {\n const path: number[] = []\n const { offsets, len, refAt } = walk(i, offset, path)\n keep(path, offsets, len, refAt)\n } else {\n this.twinStarts.add(posKey({ node: first, offset }))\n }\n }\n }\n }\n }\n // Upstream lists walks by start position, handle then offset; the two\n // passes above find the forward-start walks first.\n const refInfo =\n this.refId === undefined ? undefined : this.paths[this.refId]\n this.paths.sort(\n (x, y) => x.path[0]! - y.path[0]! || x.offsets[0]! - y.offsets[0]!,\n )\n if (refInfo) {\n this.refId = this.paths.indexOf(refInfo)\n }\n if (refPos) {\n if (refOffset === undefined || this.refId === undefined) {\n this.clearPaths()\n throw new Error('Could not find the reference path')\n }\n const info = this.paths[this.refId]!\n let before = refPos.nodeOffset\n for (const handle of info.path.slice(0, refOffset)) {\n before += this.record(handle).sequenceLen\n }\n const start = refPos.seqOffset - before\n this.refInterval = [start, start + info.len]\n info.identity = {\n pathHandle: reference.handle,\n name: reference.name,\n orientation: 'forward',\n hapStart: start,\n hapEnd: start + info.len,\n }\n }\n if (output === 'distinct') {\n this.distinctPaths(true)\n } else if (output === 'reference-only') {\n if (this.refId === undefined) {\n throw new Error('Reference path is required for reference-only output')\n }\n this.paths = [this.paths[this.refId]!]\n this.refId = 0\n }\n }\n\n // Identical walks become one record whose weight counts them, and the\n // reference walk stands for its own group, since the outputs read its\n // offsets and identity. Walks that identification will drop as twins\n // (dropTwins) stay apart until then, so that the record they would have\n // merged into keeps a name and a weight of its own: the twin of a reference\n // walk that is not canonical, which a haplotype stored against the reference\n // walks handle for handle, and a walk canonical in both orientations, as\n // through a hairpin, which extractPaths keeps twice.\n private distinctPaths(deferTwins: boolean) {\n const refInfo =\n this.refId === undefined ? undefined : this.paths[this.refId]\n const refPath = refInfo?.path\n const referenceTwin =\n refPath && !pathIsCanonical(refPath) ? flipPath(refPath) : undefined\n const deferred = (path: number[]) =>\n (referenceTwin !== undefined &&\n comparePaths(path, referenceTwin) === 0) ||\n pathIsCanonical(flipPath(path))\n const defer = deferTwins && this.db.hasHaplotypeIndex\n this.twinDeferred = false\n this.paths.sort(\n (x, y) =>\n comparePaths(x.path, y.path) ||\n x.len - y.len ||\n (x === refInfo ? -1 : y === refInfo ? 1 : 0),\n )\n const merged: PathInfo[] = []\n let refId: number | undefined\n for (const info of this.paths) {\n const last = merged[merged.length - 1]\n const apart = defer && info !== refInfo && deferred(info.path)\n this.twinDeferred ||= apart\n if (last && comparePaths(last.path, info.path) === 0 && !apart) {\n last.weight = (last.weight ?? 1) + (info.weight ?? 1)\n } else {\n if (info === refInfo) {\n refId = merged.length\n }\n merged.push({ ...info, weight: info.weight ?? 1 })\n }\n }\n this.paths = merged\n this.refId = refId\n }\n\n // Merges identical walks into one record with a weight, as extractPaths does\n // for 'distinct'. After keepHaplotypes the weights count kept haplotypes.\n mergeDistinct() {\n if (this.twinDeferred) {\n this.settleDeferred()\n } else {\n this.distinctPaths(false)\n }\n }\n\n // Output read before identifyPaths sees the walks merged as they would be\n // without a haplotype index; identifyPaths takes them apart again.\n private settleDeferred() {\n if (this.twinDeferred) {\n this.unsettled = { paths: [...this.paths], refId: this.refId }\n this.distinctPaths(false)\n }\n }\n\n // extractPaths keeps the canonical orientation of each walk, and both\n // orientations are canonical when a walk starts and ends at one node in\n // opposite orientations, as through a hairpin; the twin of a reference walk\n // that is not canonical is kept too. Named, a twin is the same stretch of\n // the same path as another walk, read the other way, and the reverse one\n // goes.\n private dropTwins() {\n const refInfo =\n this.refId === undefined ? undefined : this.paths[this.refId]\n const interval = this.refInterval\n const span = (identity: PathIdentity) =>\n `${identity.pathHandle}:${identity.hapStart}-${identity.hapEnd}`\n const forward = new Set<string>()\n if (refInfo?.identity && interval) {\n forward.add(\n span({\n ...refInfo.identity,\n hapStart: interval[0],\n hapEnd: interval[1],\n }),\n )\n }\n for (const info of this.paths) {\n if (info !== refInfo && info.identity?.orientation === 'forward') {\n forward.add(span(info.identity))\n }\n }\n const kept = this.paths.filter(\n info =>\n info === refInfo ||\n info.identity?.orientation !== 'reverse' ||\n !forward.has(span(info.identity)),\n )\n if (kept.length < this.paths.length) {\n this.paths = kept\n this.refId = refInfo === undefined ? undefined : kept.indexOf(refInfo)\n }\n if (this.twinDeferred) {\n this.distinctPaths(false)\n }\n }\n\n // Narrows an identified subgraph to the reference walk and the named walks\n // `wanted` accepts, and drops every node only the discarded walks visited,\n // so a cut for a chosen set draws that set's private sequence and nothing\n // else's. It needs a name for every walk, since a walk without one could\n // belong to a wanted haplotype, and one walk per haplotype, since a record\n // of merged walks carries the name of one of them.\n keepHaplotypes(wanted: (name: PathName) => boolean) {\n if (this.paths.some(info => info.weight !== undefined)) {\n throw new Error(\n \"keepHaplotypes needs one walk per haplotype: extract with haplotypes 'all', then call mergeDistinct()\",\n )\n }\n const unnamed = this.paths.filter(\n (info, index) => index !== this.refId && info.identity === undefined,\n ).length\n if (unnamed > 0) {\n throw new Error(\n `${unnamed} of the window's ${this.paths.length} walks have no name, so the haplotypes to keep cannot be told from the rest; call identifyPaths() first, and check that the haplotype index was built for this graph`,\n )\n }\n const refInfo =\n this.refId === undefined ? undefined : this.paths[this.refId]\n const kept = this.paths.filter(\n (info, index) =>\n index === this.refId ||\n (info.identity !== undefined && wanted(info.identity.name)),\n )\n const visited = new Set<number>()\n for (const info of kept) {\n for (const handle of info.path) {\n visited.add(nodeId(handle))\n }\n }\n for (const handle of [...this.records.keys()]) {\n if (!visited.has(nodeId(handle))) {\n this.records.delete(handle)\n }\n }\n this.paths = kept\n this.refId = refInfo === undefined ? undefined : kept.indexOf(refInfo)\n }\n\n // The walks extractPaths and identifyPaths would give this subgraph for the\n // haplotypes `keep` accepts, found from the haplotype index without walking\n // the others. Returns false, leaving no walks, when the haplotype index\n // cannot show that the walks it found are all of them; the caller then\n // extracts and identifies every walk, and stats.keep.fallback says why.\n /** @internal */\n async extractChosenPaths(\n reference: ReferencePath,\n len: number,\n keep: (name: PathName) => boolean,\n context: number,\n ) {\n this.clearPaths()\n const start = reference.position.seqOffset\n const found = await findChosenPieces({\n db: this.db,\n records: this.records,\n referenceHandle: reference.handle,\n referencePos: {\n node: reference.position.handle,\n offset: reference.position.gbwtOffset,\n },\n referenceLeft: start - reference.position.nodeOffset,\n window: { start, end: start + len },\n context,\n snarls: {\n mode: this.snarlMode,\n fills: this.snarlFills,\n inserted: this.snarlNodes,\n },\n keep,\n signal: this.signal,\n prefetchReferenceRange: (pathHandle, fromOffset, toOffset) =>\n this.prefetchReferenceRange(pathHandle, fromOffset, toOffset),\n })\n this.stats.keep = found.stats\n if (found.stats.fallback !== undefined) {\n return false\n }\n const pathsByHandle = await this.db.pathsByHandle()\n const infoOf = (piece: ChosenPiece): PathInfo => ({\n path: piece.handles,\n offsets: piece.offsets,\n len: piece.len,\n weight: undefined,\n identity: {\n pathHandle: piece.pathHandle,\n name:\n piece === found.reference\n ? reference.name\n : pathsByHandle.get(piece.pathHandle)!.name,\n orientation: piece.orientation,\n hapStart: piece.hapStart,\n hapEnd: piece.hapEnd,\n },\n })\n const ordered = [found.reference, ...found.pieces].sort(extractionOrder)\n this.paths = ordered.map(infoOf)\n this.refId = ordered.indexOf(found.reference)\n this.refPath = reference.name\n this.refHandle = reference.handle\n this.refInterval = [found.reference.hapStart, found.reference.hapEnd]\n this.dropTwins()\n return true\n }\n\n async identifyPaths() {\n if (!this.db.hasHaplotypeIndex) {\n throw new Error(\n 'The database has no HaplotypeSamples table; run gbz-haplotype-index on it',\n )\n }\n if (this.unsettled) {\n ;({ paths: this.paths, refId: this.refId } = this.unsettled)\n this.unsettled = undefined\n this.twinDeferred = true\n }\n const interval = (await this.db.haplotypeSampleGap()) ?? 4096\n const runs = handleRuns(this.sortedHandles())\n if (runs.length === 0) {\n return\n }\n const samples = new Map<string, HaplotypeSample>()\n const fetched = await Promise.all(\n runs.map(([first, last]) => this.db.haplotypeSamplesInRange(first, last)),\n )\n for (const sample of fetched.flat()) {\n samples.set(posKey(sample), sample)\n }\n const scanned = (handle: number) => {\n let lo = 0\n let hi = runs.length - 1\n while (lo < hi) {\n const mid = (lo + hi + 1) >> 1\n if (runs[mid]![0] <= handle) {\n lo = mid\n } else {\n hi = mid - 1\n }\n }\n const run = runs[lo]!\n return run[0] <= handle && handle <= run[1]\n }\n const starts = new Map<string, number>()\n this.paths.forEach((info, index) => {\n if (info.path.length > 0 && index !== this.refId) {\n starts.set(posKey(pathPosition(info, 0)), index)\n }\n })\n const identification = this.stats.identification\n identification.interval = interval\n identification.scans = runs\n identification.windowSamples = samples.size\n this.paths.forEach((info, index) => {\n if (index !== this.refId) {\n identification.fragmentLengths.push(info.len)\n }\n })\n const readRecord = this.recordReader(() => {\n this.stats.identificationFetches += 1\n identification.graphFetches += 1\n })\n const recordAt = (handle: number) => {\n identification.graphLookups += 1\n return readRecord(handle)\n }\n const sampleAt = async (pos: Pos, chain: ChainRecord) => {\n if (scanned(pos.node)) {\n return samples.get(posKey(pos))\n }\n this.stats.identificationFetches += 1\n identification.companionSeeks += 1\n chain.seeks += 1\n const sample = await this.db.haplotypeSampleAt(pos.node, pos.offset)\n if (!sample) {\n identification.companionMisses += 1\n }\n return sample\n }\n const names = new Map<number, PathName>()\n const nameOf = async (pathHandle: number) => {\n let name = names.get(pathHandle)\n if (!name) {\n const path = await this.db.getPath(pathHandle)\n if (!path) {\n throw new Error(`Path ${pathHandle} is missing from the database`)\n }\n name = path.name\n names.set(pathHandle, name)\n }\n return name\n }\n const anchorFromSample = (\n sample: HaplotypeSample,\n counter: number,\n nodeLen: number,\n ): Anchor =>\n sample.orientation === 'forward'\n ? {\n pathHandle: sample.pathHandle,\n orientation: 'forward',\n base: sample.pathOffset - counter,\n }\n : {\n pathHandle: sample.pathHandle,\n orientation: 'reverse',\n base: sample.pathOffset + counter + nodeLen,\n }\n const anchorFromIdentity = (\n identity: PathIdentity,\n counter: number,\n ): Anchor =>\n identity.orientation === 'forward'\n ? {\n pathHandle: identity.pathHandle,\n orientation: 'forward',\n base: identity.hapStart - counter,\n }\n : {\n pathHandle: identity.pathHandle,\n orientation: 'reverse',\n base: identity.hapEnd + counter,\n }\n\n for (let start = 0; start < this.paths.length; start++) {\n const startInfo = this.paths[start]!\n if (start === this.refId || startInfo.identity) {\n continue\n }\n const chain: { index: number; startBp: number }[] = []\n const visited = new Set<number>()\n const record: ChainRecord = {\n fragments: 0,\n steps: 0,\n seeks: 0,\n reentries: 0,\n twinLandings: 0,\n end: 'endmarker',\n pathHandle: undefined,\n }\n identification.chains.push(record)\n let anchor: Anchor | undefined\n let counter = 0\n let current: number | undefined = start\n let pos: Pos | undefined\n while (anchor === undefined) {\n this.signal?.throwIfAborted()\n if (current !== undefined) {\n if (visited.has(current)) {\n record.end = 'cycle'\n break\n }\n visited.add(current)\n const info = this.paths[current]!\n chain.push({ index: current, startBp: counter })\n record.fragments += 1\n let bp = counter\n for (let k = 0; k < info.path.length; k++) {\n const position = pathPosition(info, k)\n const sample = samples.get(posKey(position))\n const nodeLen = this.record(position.node).sequenceLen\n if (sample) {\n anchor = anchorFromSample(sample, bp, nodeLen)\n break\n }\n bp += nodeLen\n }\n counter += info.len\n if (anchor) {\n record.end = 'in-fragment sample'\n break\n }\n const last = pathPosition(info, info.path.length - 1)\n pos = this.record(last.node).gbwt().lf(last.offset)\n current = undefined\n }\n if (pos === undefined || pos.node === ENDMARKER) {\n record.end = 'endmarker'\n break\n }\n const key = posKey(pos)\n const known = starts.get(key)\n if (known !== undefined) {\n const identity = this.paths[known]!.identity\n if (identity) {\n anchor = anchorFromIdentity(identity, counter)\n record.end = 'identified sibling'\n break\n }\n current = known\n continue\n }\n if (this.records.has(pos.node)) {\n record.reentries += 1\n }\n if (this.twinStarts.has(key)) {\n record.twinLandings += 1\n }\n const sample = await sampleAt(pos, record)\n const node = await recordAt(pos.node)\n if (sample) {\n anchor = anchorFromSample(sample, counter, node.sequenceLen)\n record.end = 'out-of-window sample'\n break\n }\n this.stats.identificationSteps += 1\n record.steps += 1\n if (\n counter - (chain[chain.length - 1] as { startBp: number }).startBp >\n 4 * interval + 4 * node.sequenceLen\n ) {\n record.end = 'bound'\n break\n }\n counter += node.sequenceLen\n pos = node.gbwt().lf(pos.offset)\n }\n if (anchor) {\n record.pathHandle = anchor.pathHandle\n const name = await nameOf(anchor.pathHandle)\n for (const { index, startBp } of chain) {\n const info = this.paths[index]!\n info.identity =\n anchor.orientation === 'forward'\n ? {\n pathHandle: anchor.pathHandle,\n name,\n orientation: 'forward',\n hapStart: anchor.base + startBp,\n hapEnd: anchor.base + startBp + info.len,\n }\n : {\n pathHandle: anchor.pathHandle,\n name,\n orientation: 'reverse',\n hapStart: anchor.base - startBp - info.len,\n hapEnd: anchor.base - startBp,\n }\n }\n }\n }\n this.dropTwins()\n }\n\n private refIndex(ref: number[]) {\n if (this.refIndexCache === undefined) {\n const index = new Map<number, number[]>()\n ref.forEach((handle, i) => {\n const occurrences = index.get(handle)\n if (occurrences) {\n occurrences.push(i)\n } else {\n index.set(handle, [i])\n }\n })\n this.refIndexCache = index\n }\n return this.refIndexCache\n }\n\n private refPrefix(ref: number[]) {\n if (this.refPrefixCache === undefined) {\n const prefix = [0]\n ref.forEach((handle, i) => {\n prefix.push(prefix[i]! + this.record(handle).sequenceLen)\n })\n this.refPrefixCache = prefix\n }\n return this.refPrefixCache\n }\n\n private orderedMatches(path: number[], ref: number[]): Matches | undefined {\n const index = this.refIndex(ref)\n const pathAt = new Int32Array(path.length)\n const refAt = new Int32Array(path.length)\n let count = 0\n let last = -1\n for (let i = 0; i < path.length; i++) {\n const occurrences = index.get(path[i]!)\n if (occurrences) {\n const j = firstAbove(occurrences, last)\n if (j === undefined) {\n return undefined\n }\n pathAt[count] = i\n refAt[count] = j\n count += 1\n last = j\n }\n }\n return { pathAt, refAt, count }\n }\n\n private pathLen(path: number[]) {\n let total = 0\n for (const handle of path) {\n total += this.record(handle).sequenceLen\n }\n return total\n }\n\n private prefixMatches(path: number[], ref: number[]) {\n let result = 0\n let pi = 0\n let ri = 0\n let pb = 0\n let rb = 0\n while (pi < path.length && ri < ref.length) {\n const a = this.record(path[pi]!).sequence\n const b = this.record(ref[ri]!).sequence\n while (pb < a.length && rb < b.length) {\n if (a[pb] !== b[rb]) {\n return result\n }\n pb += 1\n rb += 1\n result += 1\n }\n if (pb === a.length) {\n pi += 1\n pb = 0\n }\n if (rb === b.length) {\n ri += 1\n rb = 0\n }\n }\n return result\n }\n\n private suffixMatches(path: number[], ref: number[]) {\n let result = 0\n let pi = 0\n let ri = 0\n let pb = 0\n let rb = 0\n while (pi < path.length && ri < ref.length) {\n const a = this.record(path[path.length - pi - 1]!).sequence\n const b = this.record(ref[ref.length - ri - 1]!).sequence\n while (pb < a.length && rb < b.length) {\n if (a[a.length - pb - 1] !== b[b.length - rb - 1]) {\n return result\n }\n pb += 1\n rb += 1\n result += 1\n }\n if (pb === a.length) {\n pi += 1\n pb = 0\n }\n if (rb === b.length) {\n ri += 1\n rb = 0\n }\n }\n return result\n }\n\n private align(path: number[], ref: number[], edits: Edit[]) {\n const pathLen = this.pathLen(path)\n const refLen = this.pathLen(ref)\n const prefix = this.prefixMatches(path, ref)\n let suffix = this.suffixMatches(path, ref)\n if (prefix + suffix > pathLen) {\n suffix = pathLen - prefix\n }\n if (prefix + suffix > refLen) {\n suffix = refLen - prefix\n }\n appendEdit(edits, 'M', prefix)\n appendGap(edits, pathLen - prefix - suffix, refLen - prefix - suffix)\n appendEdit(edits, 'M', suffix)\n }\n\n private sharedWeight(path: number[], ref: number[]) {\n const index = this.refIndex(ref)\n let weight = 0\n for (const handle of path) {\n if (index.has(handle)) {\n weight += this.record(handle).sequenceLen\n }\n }\n return weight\n }\n\n private editsAgainst(path: number[], ref: number[]) {\n const ordered = this.orderedMatches(path, ref)\n if (ordered) {\n this.stats.orderedAlignments += 1\n } else {\n this.stats.lcsAlignments += 1\n }\n const lcs =\n ordered ??\n asMatches(\n weightedLcs(path, ref, handle => this.record(handle).sequenceLen)[0],\n )\n const edits: Edit[] = []\n const refPrefix = this.refPrefix(ref)\n const alignGap = (\n pathFrom: number,\n pathTo: number,\n refFrom: number,\n refTo: number,\n ) => {\n if (pathFrom === pathTo) {\n appendEdit(edits, 'D', refPrefix[refTo]! - refPrefix[refFrom]!)\n } else if (refFrom === refTo) {\n appendEdit(edits, 'I', this.pathLen(path.slice(pathFrom, pathTo)))\n } else {\n this.align(\n path.slice(pathFrom, pathTo),\n ref.slice(refFrom, refTo),\n edits,\n )\n }\n }\n let matched = 0\n let pathOffset = 0\n let refOffset = 0\n for (let m = 0; m < lcs.count; m++) {\n const nextPath = lcs.pathAt[m]!\n const nextRef = lcs.refAt[m]!\n // Adjacent matches are the overwhelming majority of a walk's steps, and\n // for those alignGap has nothing to append; only the gaps are worth a\n // call.\n if (pathOffset !== nextPath || refOffset !== nextRef) {\n alignGap(pathOffset, nextPath, refOffset, nextRef)\n }\n const nodeLen = this.record(path[nextPath]!).sequenceLen\n appendEdit(edits, 'M', nodeLen)\n matched += nodeLen\n pathOffset = nextPath + 1\n refOffset = nextRef + 1\n }\n alignGap(pathOffset, path.length, refOffset, ref.length)\n return { edits, matched, matches: lcs }\n }\n\n private alignment(pathIndex: number) {\n const info = this.paths[pathIndex]\n if (this.refId === undefined || pathIndex === this.refId || !info) {\n return undefined\n }\n const ref = this.paths[this.refId]!.path\n let result: { edits: Edit[]; matched: number; flipped: boolean }\n if (\n pathIsCanonical(ref) &&\n (info.identity === undefined || !pathIsCanonical(flipPath(info.path)))\n ) {\n // A canonical walk against a canonical reference has nothing to gain\n // from being flipped, so neither bound is worth the pass over its steps\n // that measuring one costs. A walk through a hairpin is canonical both\n // ways and either way aligns about half of it; once named, dropTwins\n // has left one of them, and it takes the better way. Unnamed, both are\n // walks as upstream prints them, each aligned as it stands.\n result = { ...this.editsAgainst(info.path, ref), flipped: false }\n } else {\n const flippedPath = flipPath(info.path)\n const forwardBound = this.sharedWeight(info.path, ref)\n const flippedBound = this.sharedWeight(flippedPath, ref)\n if (flippedBound === 0) {\n result = { ...this.editsAgainst(info.path, ref), flipped: false }\n } else if (forwardBound === 0) {\n result = { ...this.editsAgainst(flippedPath, ref), flipped: true }\n } else {\n const forward = this.editsAgainst(info.path, ref)\n const flipped = this.editsAgainst(flippedPath, ref)\n result =\n flipped.matched > forward.matched\n ? { ...flipped, flipped: true }\n : { ...forward, flipped: false }\n }\n }\n return result\n }\n\n /** @internal */\n alignToRef(pathIndex: number) {\n this.settleDeferred()\n return this.alignment(pathIndex)\n ?.edits.map(([op, len]) => `${len}${op}`)\n .join('')\n }\n\n alignments(): HaplotypeAlignment[] {\n this.settleDeferred()\n const reference = this.referenceInterval\n if (this.refId === undefined || !reference) {\n throw new Error('Alignments need a reference path')\n }\n const ref = this.paths[this.refId]!.path\n const refTotal = this.refPrefix(ref)[ref.length]!\n const fragment = (\n edits: Edit[],\n strand: '+' | '-',\n pieces: number[],\n soloAligned: number[],\n ): FragmentAlignment => {\n const trimmed = trimEnds(edits)\n const first = this.paths[pieces[0]!]!\n const last = this.paths[pieces[pieces.length - 1]!]!\n const identity = first.identity\n const walkForward = identity?.orientation === 'forward'\n const [low, high] = walkForward ? [first, last] : [last, first]\n return {\n strand,\n refStart: reference.start + trimmed.leading,\n refEnd: reference.start + refTotal - trimmed.trailing,\n edits: trimmed.edits,\n weight: first.weight,\n path: pieces.flatMap(index => this.paths[index]!.path),\n start: pathPosition(first, 0),\n pieces,\n soloAligned,\n identity:\n identity === undefined\n ? undefined\n : {\n pathHandle: identity.pathHandle,\n name: identity.name,\n hapStart: identity.name.fragment + low.identity!.hapStart,\n hapEnd: identity.name.fragment + high.identity!.hapEnd,\n walkForward,\n },\n }\n }\n // A walk that leaves the subgraph and comes back is two pieces here, and a\n // piece whose tail touches reference nodes past where the next piece\n // aligns cannot be joined after the fact. Aligned as one walk, with the\n // bases outside the subgraph as an insertion between the pieces, they read\n // as the detour they are. Each end of the join must be aligned over at\n // least half its length alone, which keeps out a pass hundreds of kb away\n // that the context reached through a rare edge, and must keep at least half\n // its aligned bases jointly, which keeps out the second pass of a collapsed\n // paralog. Pieces between the ends, often most of the detour, join with\n // them whatever their alignment.\n const aligned = (f: FragmentAlignment) =>\n f.soloAligned.reduce((sum, bases) => sum + bases, 0)\n const length = (f: FragmentAlignment) =>\n f.pieces.reduce((sum, index) => sum + this.paths[index]!.len, 0)\n const mostlyAligned = (f: FragmentAlignment) => 2 * aligned(f) >= length(f)\n const alignJointly = (parts: FragmentAlignment[]) => {\n const first = parts[0]!\n const last = parts[parts.length - 1]!\n const walkForward = first.identity!.walkForward\n if (\n parts.some(\n (part, k) =>\n part.strand !== first.strand ||\n part.identity!.walkForward !== walkForward ||\n (k > 0 && part.identity!.hapStart < parts[k - 1]!.identity!.hapEnd),\n )\n ) {\n return undefined\n }\n const inWalkOrder = walkForward ? parts : [...parts].reverse()\n const pieces = inWalkOrder.flatMap(part => part.pieces)\n const soloAligned = inWalkOrder.flatMap(part => part.soloAligned)\n const flipped = (first.strand === '+') !== walkForward\n const infos = pieces.map(index => this.paths[index]!)\n const gaps = infos.slice(1).map((info, k) => {\n const before = infos[k]!.identity!\n return walkForward\n ? info.identity!.hapStart - before.hapEnd\n : before.hapStart - info.identity!.hapEnd\n })\n const alignedInfos = flipped ? [...infos].reverse() : infos\n const alignedGaps = flipped ? [...gaps].reverse() : gaps\n const steps = alignedInfos.flatMap(info =>\n flipped ? flipPath(info.path) : info.path,\n )\n const { edits } = this.editsAgainst(steps, ref)\n const keptInOrder = alignedIn(\n edits,\n alignedInfos.map(info => info.len),\n )\n const kept = new Map(\n (flipped ? [...pieces].reverse() : pieces).map((index, k) => [\n index,\n keptInOrder[k]!,\n ]),\n )\n const keeps = (part: FragmentAlignment) =>\n 2 * part.pieces.reduce((sum, index) => sum + kept.get(index)!, 0) >=\n aligned(part)\n if (!keeps(first) || !keeps(last)) {\n return undefined\n }\n const insertions: [number, number][] = []\n let walked = 0\n alignedInfos.slice(0, -1).forEach((info, k) => {\n walked += info.len\n insertions.push([walked, alignedGaps[k]!])\n })\n return fragment(\n spliceInsertions(edits, insertions),\n first.strand,\n pieces,\n soloAligned,\n )\n }\n const fragments: FragmentAlignment[] = []\n this.paths.forEach((info, index) => {\n if (index === this.refId) {\n return\n }\n const { edits, flipped } = this.alignment(index)!\n const identity = info.identity\n const alongReference = identity\n ? (identity.orientation === 'forward') !== flipped\n : !flipped\n fragments.push(\n fragment(\n edits,\n alongReference ? '+' : '-',\n [index],\n alignedIn(edits, [info.len]),\n ),\n )\n })\n return joinSiblings(fragments, mostlyAligned, alignJointly).map(joined => {\n const { edits, identity, pieces, soloAligned, ...rest } = joined\n const span: AlignmentSpan = { ...rest, cigar: cigarOf(edits) }\n return identity\n ? {\n ...span,\n resolved: true,\n name: identity.name,\n label: formatPathName({\n ...identity.name,\n fragment: identity.hapStart,\n end: identity.hapEnd,\n }),\n pathHandle: identity.pathHandle,\n hapStart: identity.hapStart,\n hapEnd: identity.hapEnd,\n }\n : { ...span, resolved: false }\n })\n }\n\n // One haplotype's walks aligned to another's, on both haplotypes' own\n // coordinates, with the bases between two shared nodes compared unless bases\n // is false. The reference path is a named walk like any other, on either\n // side. With no query, every other named walk in the window is one.\n pairAlignments(opts: PairAlignmentOptions): PairAlignment[] {\n const { target, query, ...pairOptions } = opts\n const walks = this.paths.flatMap(info => {\n const { identity } = info\n return identity\n ? [\n {\n name: identity.name,\n start: identity.name.fragment + identity.hapStart,\n steps: haplotypeOrderedPath(info, identity),\n },\n ]\n : []\n })\n const names = (haplotype: HaplotypeRef) => (name: PathName) =>\n name.sample === haplotype.sample && name.haplotype === haplotype.haplotype\n const isTarget = names(target)\n const isQuery = query ? names(query) : (name: PathName) => !isTarget(name)\n const sequenceOf = (id: number) =>\n this.record(encodeNode(id, 'forward')).sequence\n return walks\n .filter(walk => isTarget(walk.name))\n .flatMap(targetWalk =>\n walks\n .filter(walk => isQuery(walk.name))\n .flatMap(queryWalk =>\n pairAlignments({\n ...pairOptions,\n query: queryWalk.steps,\n target: targetWalk.steps,\n sequenceOf,\n }).map(chain => ({\n query: queryWalk.name,\n queryStart: queryWalk.start + chain.queryStart,\n queryEnd: queryWalk.start + chain.queryEnd,\n strand: chain.strand,\n target: targetWalk.name,\n targetStart: targetWalk.start + chain.targetStart,\n targetEnd: targetWalk.start + chain.targetEnd,\n cigar: pairCigar(chain.edits),\n matches: chain.edits.reduce(\n (sum, [op, len]) => sum + (op === '=' ? len : 0),\n 0,\n ),\n columns: chain.edits.reduce((sum, [, len]) => sum + len, 0),\n sharedBases: chain.sharedBases,\n })),\n ),\n )\n }\n\n private canonicalEdges(id: number) {\n const edges: [number, number, number][] = []\n for (const orientation of ['forward', 'reverse'] as const) {\n const handle = encodeNode(id, orientation)\n for (const successor of this.record(handle).successors()) {\n if (this.hasHandle(successor) && edgeIsCanonical(handle, successor)) {\n edges.push([\n orientation === 'reverse' ? 1 : 0,\n nodeId(successor),\n isReverse(successor) ? 1 : 0,\n ])\n }\n }\n }\n edges.sort((a, b) => a[0] - b[0] || a[1] - b[1] || a[2] - b[2])\n return edges.filter(\n (edge, i) =>\n i === 0 ||\n edge[0] !== edges[i - 1]![0] ||\n edge[1] !== edges[i - 1]![1] ||\n edge[2] !== edges[i - 1]![2],\n )\n }\n\n async stableName() {\n const encoder = new TextEncoder()\n const chunks: Uint8Array[] = []\n for (const handle of this.sortedHandles()) {\n if (!isReverse(handle)) {\n const id = nodeId(handle)\n let text = `S\\t${id}\\t${this.record(handle).sequence}\\n`\n for (const [fromReverse, toId, toReverse] of this.canonicalEdges(id)) {\n text += `L\\t${id}\\t${fromReverse ? '-' : '+'}\\t${toId}\\t${toReverse ? '-' : '+'}\\n`\n }\n chunks.push(encoder.encode(text))\n }\n }\n return sha256Hex(chunks)\n }\n\n async toGFA(opts: SubgraphOutputOptions = {}) {\n this.settleDeferred()\n const cigar = opts.cigar ?? false\n const lines = [\n this.refPath ? `H\\tVN:Z:1.1\\tRS:Z:${this.refPath.sample}` : 'H\\tVN:Z:1.1',\n ...gfaHeaderLines(\n subgraphName(await this.stableName(), await this.db.graphName()),\n ),\n ]\n const handles = this.sortedHandles()\n for (const handle of handles) {\n if (!isReverse(handle)) {\n lines.push(`S\\t${nodeId(handle)}\\t${this.record(handle).sequence}`)\n }\n }\n const sign = (handle: number) => (isReverse(handle) ? '-' : '+')\n for (const handle of handles) {\n for (const successor of this.record(handle).successors()) {\n if (this.hasHandle(successor) && edgeIsCanonical(handle, successor)) {\n lines.push(\n `L\\t${nodeId(handle)}\\t${sign(handle)}\\t${nodeId(successor)}\\t${sign(successor)}\\t0M`,\n )\n }\n }\n }\n const walk = (\n info: PathInfo,\n identity: PathIdentity | undefined,\n name: PathName,\n end: number,\n cigarString: string | undefined,\n ) => {\n const steps = haplotypeOrderedPath(info, identity)\n .map(handle => `${isReverse(handle) ? '<' : '>'}${nodeId(handle)}`)\n .join('')\n const weight = info.weight === undefined ? '' : `\\tWT:i:${info.weight}`\n const cg = cigarString === undefined ? '' : `\\tCG:Z:${cigarString}`\n return `W\\t${name.sample}\\t${name.haplotype}\\t${name.contig}\\t${name.fragment}\\t${end}\\t${steps}${weight}${cg}`\n }\n const contig = this.refPath?.contig ?? 'unknown'\n if (this.refId !== undefined && this.refPath && this.refInterval) {\n lines.push(\n walk(\n this.paths[this.refId]!,\n undefined,\n {\n ...this.refPath,\n fragment: this.refPath.fragment + this.refInterval[0],\n },\n this.refPath.fragment + this.refInterval[1],\n undefined,\n ),\n )\n }\n let haplotype = 1\n this.paths.forEach((info, index) => {\n if (index !== this.refId) {\n const resolved = opts.names !== 'anonymous' ? info.identity : undefined\n const cigarString = cigar ? this.alignToRef(index) : undefined\n lines.push(\n resolved\n ? walk(\n info,\n resolved,\n {\n ...resolved.name,\n fragment: resolved.name.fragment + resolved.hapStart,\n },\n resolved.name.fragment + resolved.hapEnd,\n cigarString,\n )\n : walk(\n info,\n undefined,\n { sample: 'unknown', contig, haplotype, fragment: 0 },\n info.len,\n cigarString,\n ),\n )\n haplotype += 1\n }\n })\n return `${lines.join('\\n')}\\n`\n }\n\n // The reference walk first under the interval it covers, then one entry per\n // haplotype in extraction order. Both outputs read this so a name, a weight\n // or a CIGAR cannot mean one thing in the upstream JSON and another in the\n // compact form.\n private outputPaths(opts: SubgraphOutputOptions) {\n this.settleDeferred()\n const cigar = opts.cigar ?? false\n const entries: {\n info: PathInfo\n identity: PathIdentity | undefined\n name: string\n cigar: string | undefined\n }[] = []\n const contig = this.refPath?.contig ?? 'unknown'\n if (this.refId !== undefined && this.refPath && this.refInterval) {\n const start = {\n ...this.refPath,\n fragment: this.refPath.fragment + this.refInterval[0],\n }\n entries.push({\n info: this.paths[this.refId]!,\n identity: undefined,\n name: formatPathName({\n ...start,\n end: this.refPath.fragment + this.refInterval[1],\n }),\n cigar: undefined,\n })\n }\n let haplotype = 1\n this.paths.forEach((info, index) => {\n if (index === this.refId) {\n return\n }\n const identity = opts.names !== 'anonymous' ? info.identity : undefined\n entries.push({\n info,\n identity,\n name: identity\n ? formatPathName({\n ...identity.name,\n fragment: identity.name.fragment + identity.hapStart,\n end: identity.name.fragment + identity.hapEnd,\n })\n : formatPathName({\n sample: 'unknown',\n contig,\n haplotype,\n fragment: 0,\n end: info.len,\n }),\n cigar: cigar ? this.alignToRef(index) : undefined,\n })\n haplotype += 1\n })\n return entries\n }\n\n private *outputEdges() {\n for (const handle of this.sortedHandles()) {\n for (const successor of this.record(handle).successors()) {\n if (this.hasHandle(successor) && edgeIsCanonical(handle, successor)) {\n yield [handle, successor] as const\n }\n }\n }\n }\n\n // Each named walk the cut holds and its span on its own path. Two spans of\n // one path with a gap between them are a walk that left the cut's nodes and\n // came back: a window is cut by graph distance from the reference, so a\n // haplotype's detour longer than the context is not in it.\n walkSpans(): WalkSpan[] {\n this.settleDeferred()\n return this.paths.flatMap((info, index) => {\n const identity = index === this.refId ? undefined : info.identity\n return identity\n ? [\n {\n name: identity.name,\n start: identity.name.fragment + identity.hapStart,\n end: identity.name.fragment + identity.hapEnd,\n },\n ]\n : []\n })\n }\n\n toSubgraphJson(opts: SubgraphOutputOptions = {}): SubgraphJson {\n const nodes = this.sortedHandles()\n .filter(handle => !isReverse(handle))\n .map(handle => ({\n id: String(nodeId(handle)),\n sequence: this.record(handle).sequence,\n }))\n const edges: SubgraphJson['edges'] = []\n for (const [from, to] of this.outputEdges()) {\n edges.push({\n from: String(nodeId(from)),\n from_is_reverse: isReverse(from),\n to: String(nodeId(to)),\n to_is_reverse: isReverse(to),\n })\n }\n const paths = this.outputPaths(opts).map(entry =>\n jsonPath(entry.info, entry.identity, entry.name, entry.cigar),\n )\n return { nodes, edges, paths }\n }\n\n // The same subgraph as typed arrays of GBWT handles. toSubgraphJson spends\n // an object and a stringified id on every step of every walk, which a\n // 200 kb human window has about 350,000 of; this hands back the numbers the\n // extraction already holds, so it survives a structured clone into a worker\n // for about the cost of the memcpy rather than of rebuilding the objects.\n // Measured on HPRC chr20 CHM13#0#chr20 30.0-30.2 Mb, 5,943 nodes and 178\n // haplotypes: 295 ms to clone the upstream shape against 1.9 ms for this one.\n //\n // Packing the other two fields the way bam-js packs NUMERIC_SEQ and\n // NUMERIC_CIGAR was measured on the same window and rejected, because what\n // pays there is a long per-record field and both of these are short. Node\n // sequences average 34 bp: base-6 bytes plus offsets are 2.86x smaller but\n // cost more to build than to hand over the cached strings (1.07 ms against\n // 0.95 ms all in), and a consumer drawing the graph wants the strings for\n // every node anyway. CIGARs average 323 chars over 17,555 total ops: packing\n // them into one Int32Array per path is 1.7 ms against 2.4 ms to join the\n // strings, but then clones SLOWER (0.20 ms against 0.09 ms) because 178 small\n // typed arrays cost more than 178 strings. Steps are the only field here long\n // enough to be worth it. The CIGAR phase is 103 ms of edit computation and\n // 2 ms of string building, so neither field is where that time goes.\n toCompactSubgraph(opts: SubgraphOutputOptions = {}): CompactSubgraph {\n const forward = this.sortedHandles().filter(handle => !isReverse(handle))\n const nodeIds = new Int32Array(forward.length)\n const nodeSequences: string[] = []\n forward.forEach((handle, i) => {\n nodeIds[i] = nodeId(handle)\n nodeSequences.push(this.record(handle).sequence)\n })\n const edgeHandles: number[] = []\n for (const [from, to] of this.outputEdges()) {\n edgeHandles.push(from, to)\n }\n return {\n nodeIds,\n nodeSequences,\n edges: Int32Array.from(edgeHandles),\n paths: this.outputPaths(opts).map(entry => ({\n name: entry.name,\n weight: entry.info.weight,\n cigar: entry.cigar,\n steps: Int32Array.from(\n haplotypeOrderedPath(entry.info, entry.identity),\n ),\n })),\n }\n }\n}\n\n// The buffers a CompactSubgraph owns outright, for the transfer list of a\n// postMessage that hands it to another thread. Transferring detaches them, so\n// the sending side must not read the subgraph afterwards.\nexport function compactSubgraphTransferables(subgraph: CompactSubgraph) {\n return [\n subgraph.nodeIds.buffer,\n subgraph.edges.buffer,\n ...subgraph.paths.map(path => path.steps.buffer),\n ]\n}\n\n// A named walk lists its steps in the haplotype's own direction, as the W line\n// spec and the start..end coordinates beside it require. extractPaths keeps\n// whichever twin of a walk is canonical, which is a property of the handles\n// and not of the haplotype, so the kept walk runs against the haplotype for\n// about half of them; identification records which.\nfunction haplotypeOrderedPath(\n info: PathInfo,\n identity: PathIdentity | undefined,\n) {\n return identity?.orientation === 'reverse'\n ? info.path.map(handle => flipNode(handle)).reverse()\n : info.path\n}\n\nfunction jsonPath(\n info: PathInfo,\n identity: PathIdentity | undefined,\n name: string,\n cigar: string | undefined,\n): SubgraphPath {\n return {\n name,\n ...(info.weight === undefined ? {} : { weight: info.weight }),\n ...(cigar === undefined ? {} : { cigar }),\n path: haplotypeOrderedPath(info, identity).map(handle => ({\n id: String(nodeId(handle)),\n is_reverse: isReverse(handle),\n })),\n }\n}\n\nfunction comparePaths(a: number[], b: number[]) {\n const n = Math.min(a.length, b.length)\n for (let i = 0; i < n; i++) {\n const x = a[i]!\n const y = b[i]!\n if (x !== y) {\n return x < y ? -1 : 1\n }\n }\n return a.length - b.length\n}\n\nfunction appendEdit(edits: Edit[], op: EditOp, len: number) {\n if (len === 0) {\n return\n }\n const last = edits[edits.length - 1]\n if (last?.[0] === op) {\n last[1] += len\n } else {\n edits.push([op, len])\n }\n}\n\nfunction gapPenalty(len: number) {\n return len === 0 ? 0 : 6 + (len - 1)\n}\n\nfunction appendGap(edits: Edit[], pathMiddle: number, refMiddle: number) {\n if (pathMiddle === 0) {\n appendEdit(edits, 'D', refMiddle)\n } else if (refMiddle === 0) {\n appendEdit(edits, 'I', pathMiddle)\n } else {\n const mismatch = Math.min(pathMiddle, refMiddle)\n const mismatchIndel =\n 4 * mismatch +\n gapPenalty(pathMiddle - mismatch) +\n gapPenalty(refMiddle - mismatch)\n const insertionDeletion = gapPenalty(pathMiddle) + gapPenalty(refMiddle)\n if (mismatchIndel <= insertionDeletion) {\n appendEdit(edits, 'M', mismatch)\n appendEdit(edits, 'I', pathMiddle - mismatch)\n appendEdit(edits, 'D', refMiddle - mismatch)\n } else {\n appendEdit(edits, 'I', pathMiddle)\n appendEdit(edits, 'D', refMiddle)\n }\n }\n}\n\n// A record starts and ends at an aligned base: the deletions in a run of\n// insertions and deletions at either end move its reference start or end, and\n// the insertions stay. An alignment with no aligned base keeps its insertion at\n// the reference start.\nfunction trimEnds(edits: Edit[]) {\n let first = 0\n while (first < edits.length && edits[first]![0] !== 'M') {\n first += 1\n }\n if (first === edits.length) {\n const inserted = edits.filter(([op]) => op === 'I')\n const trailing = edits\n .filter(([op]) => op === 'D')\n .reduce((sum, [, len]) => sum + len, 0)\n return {\n edits: inserted.map(([op, len]): Edit => [op, len]),\n leading: 0,\n trailing,\n }\n }\n let last = edits.length\n while (edits[last - 1]![0] !== 'M') {\n last -= 1\n }\n const ends = (run: Edit[]) => ({\n inserted: run.reduce((sum, [op, len]) => sum + (op === 'I' ? len : 0), 0),\n deleted: run.reduce((sum, [op, len]) => sum + (op === 'D' ? len : 0), 0),\n })\n const head = ends(edits.slice(0, first))\n const tail = ends(edits.slice(last))\n const trimmed: Edit[] = []\n appendEdit(trimmed, 'I', head.inserted)\n for (const [op, len] of edits.slice(first, last)) {\n appendEdit(trimmed, op, len)\n }\n appendEdit(trimmed, 'I', tail.inserted)\n return { edits: trimmed, leading: head.deleted, trailing: tail.deleted }\n}\n\n// The bases the CIGAR aligns within each of consecutive stretches of the walk.\nfunction alignedIn(edits: Edit[], lengths: number[]) {\n const aligned = lengths.map(() => 0)\n const last = lengths.length - 1\n let piece = 0\n let pieceEnd = lengths[0]!\n let walked = 0\n for (const [op, len] of edits) {\n if (op === 'D') {\n continue\n }\n let rest = len\n while (rest > 0) {\n while (piece < last && walked >= pieceEnd) {\n piece += 1\n pieceEnd += lengths[piece]!\n }\n const step = piece < last ? Math.min(rest, pieceEnd - walked) : rest\n if (op === 'M') {\n aligned[piece]! += step\n }\n walked += step\n rest -= step\n }\n }\n return aligned\n}\n\n// Insertions at walk offsets, after any deletions that end at the same offset.\nfunction spliceInsertions(edits: Edit[], insertions: [number, number][]) {\n const spliced: Edit[] = []\n let walked = 0\n let next = 0\n for (const [op, len] of edits) {\n if (op === 'D') {\n appendEdit(spliced, op, len)\n continue\n }\n let from = walked\n while (next < insertions.length && insertions[next]![0] < walked + len) {\n const [at, inserted] = insertions[next]!\n appendEdit(spliced, op, at - from)\n appendEdit(spliced, 'I', inserted)\n from = at\n next += 1\n }\n appendEdit(spliced, op, walked + len - from)\n walked += len\n }\n for (; next < insertions.length; next++) {\n appendEdit(spliced, 'I', insertions[next]![1])\n }\n return spliced\n}\n\nfunction cigarOf(edits: Edit[]) {\n return edits.map(([op, len]) => `${len}${op}`).join('')\n}\n", "export class ByteCodeReader {\n offset = 0\n private bytes: Uint8Array\n\n constructor(bytes: Uint8Array) {\n this.bytes = bytes\n }\n\n get done() {\n return this.offset >= this.bytes.length\n }\n\n byte() {\n const value = this.bytes[this.offset]\n if (value === undefined) {\n return undefined\n }\n this.offset += 1\n return value\n }\n\n int() {\n let shift = 1\n let result = 0\n while (this.offset < this.bytes.length) {\n const value = this.bytes[this.offset]!\n this.offset += 1\n result += (value & 0x7f) * shift\n shift *= 128\n if ((value & 0x80) === 0) {\n return result\n }\n }\n return undefined\n }\n}\n\nexport interface Run {\n value: number\n len: number\n}\n\nconst RLE_THRESHOLD = 255\nconst RLE_UNIVERSE = 256\n\nexport class RunReader {\n private source: ByteCodeReader\n private sigma: number\n private threshold: number\n\n constructor(bytes: Uint8Array, sigma: number) {\n this.source = new ByteCodeReader(bytes)\n this.sigma = sigma === 0 ? Number.MAX_SAFE_INTEGER : sigma\n this.threshold =\n this.sigma < RLE_THRESHOLD ? Math.floor(RLE_UNIVERSE / this.sigma) : 0\n }\n\n next(): Run | undefined {\n if (this.sigma >= RLE_THRESHOLD) {\n const value = this.source.int()\n const len = this.source.int()\n return value === undefined || len === undefined\n ? undefined\n : { value, len: len + 1 }\n }\n const byte = this.source.byte()\n if (byte === undefined) {\n return undefined\n }\n const value = byte % this.sigma\n let len = Math.floor(byte / this.sigma) + 1\n if (len === this.threshold) {\n const extra = this.source.int()\n if (extra === undefined) {\n return undefined\n }\n len += extra\n }\n return { value, len }\n }\n\n *[Symbol.iterator]() {\n for (let run = this.next(); run !== undefined; run = this.next()) {\n yield run\n }\n }\n}\n", "import { ByteCodeReader, RunReader } from './bytecode.ts'\nimport { ENDMARKER, flipNode, nodeId } from './node.ts'\n\nexport interface Pos {\n node: number\n offset: number\n}\n\nexport function decompressEdges(bytes: Uint8Array): Pos[] {\n const reader = new ByteCodeReader(bytes)\n const sigma = reader.int()\n if (sigma === undefined || sigma === 0) {\n return []\n }\n const edges: Pos[] = []\n let prev = 0\n for (let i = 0; i < sigma; i++) {\n const delta = reader.int()\n const offset = reader.int()\n if (delta === undefined || offset === undefined) {\n throw new Error('GBWT edge list ends early')\n }\n prev += delta\n edges.push({ node: prev, offset })\n }\n return edges\n}\n\nexport class GbwtRecord {\n readonly edges: Pos[]\n readonly bwt: Uint8Array\n\n constructor(edges: Pos[], bwt: Uint8Array) {\n this.edges = edges\n this.bwt = bwt\n }\n\n runs() {\n return new RunReader(this.bwt, this.edges.length)\n }\n\n private edge(rank: number) {\n const edge = this.edges[rank]\n if (edge === undefined) {\n throw new Error(\n `GBWT run refers to edge rank ${rank} of ${this.edges.length}`,\n )\n }\n return edge\n }\n\n lf(i: number): Pos | undefined {\n const offsets = this.edges.map(e => e.offset)\n let offset = 0\n for (const run of this.runs()) {\n const edge = this.edge(run.value)\n const soFar = offsets[run.value]!\n if (offset + run.len > i) {\n return edge.node === ENDMARKER\n ? undefined\n : { node: edge.node, offset: soFar + (i - offset) }\n }\n offsets[run.value] = soFar + run.len\n offset += run.len\n }\n return undefined\n }\n\n private edgeTo(node: number) {\n let low = 0\n let high = this.edges.length\n while (low < high) {\n const mid = (low + high) >> 1\n const edge = this.edges[mid]!\n if (edge.node === node) {\n return mid\n }\n if (edge.node < node) {\n low = mid + 1\n } else {\n high = mid\n }\n }\n return undefined\n }\n\n offsetTo(pos: Pos): number | undefined {\n if (pos.node === ENDMARKER) {\n return undefined\n }\n const rank = this.edgeTo(pos.node)\n if (rank === undefined) {\n return undefined\n }\n let succRank = this.edges[rank]!.offset\n if (succRank > pos.offset) {\n return undefined\n }\n let offset = 0\n for (const run of this.runs()) {\n offset += run.len\n if (run.value !== rank) {\n continue\n }\n succRank += run.len\n if (succRank > pos.offset) {\n return offset - (succRank - pos.offset)\n }\n }\n return undefined\n }\n\n predecessorAt(i: number): number | undefined {\n const counts = this.edges.map(e => ({\n node: e.node === ENDMARKER ? ENDMARKER : flipNode(e.node),\n count: 0,\n }))\n for (const run of this.runs()) {\n const entry = counts[run.value]\n if (entry) {\n entry.count += run.len\n }\n }\n for (let rank = 1; rank < counts.length; rank++) {\n const prev = counts[rank - 1] as { node: number; count: number }\n const curr = counts[rank] as { node: number; count: number }\n if (nodeId(prev.node) === nodeId(curr.node)) {\n counts[rank - 1] = curr\n counts[rank] = prev\n }\n }\n let offset = 0\n for (const entry of counts) {\n offset += entry.count\n if (offset > i) {\n return entry.node === ENDMARKER ? undefined : entry.node\n }\n }\n return undefined\n }\n\n decompressArrays() {\n const offsets = this.edges.map(e => e.offset)\n let total = 0\n for (const run of this.runs()) {\n total += run.len\n }\n const nodes = new Int32Array(total)\n const nextOffsets = new Int32Array(total)\n let i = 0\n for (const run of this.runs()) {\n const edge = this.edge(run.value)\n let offset = offsets[run.value]!\n for (let k = 0; k < run.len; k++) {\n nodes[i] = edge.node\n nextOffsets[i] = offset\n offset += 1\n i += 1\n }\n offsets[run.value] = offset\n }\n return { nodes, offsets: nextOffsets }\n }\n\n decompress(): Pos[] {\n const offsets = this.edges.map(e => e.offset)\n const result: Pos[] = []\n for (const run of this.runs()) {\n const edge = this.edge(run.value)\n for (let k = 0; k < run.len; k++) {\n result.push({ node: edge.node, offset: offsets[run.value]! })\n offsets[run.value] = offsets[run.value]! + 1\n }\n }\n return result\n }\n}\n", "import { pathNameFor, toPathQuery } from './pathName.ts'\nimport { Subgraph, SubgraphLimitError } from './subgraph.ts'\n\nimport type { GBZBase } from './db.ts'\nimport type { PathName, PathRef } from './pathName.ts'\nimport type { HaplotypeOutput, SnarlOutput } from './subgraph.ts'\n\nexport interface QueryOptions {\n context?: number | undefined\n haplotypes?: HaplotypeOutput | undefined\n snarls?: SnarlOutput | undefined\n limit?: number | undefined\n signal?: AbortSignal | undefined\n}\n\nexport interface PathWindow {\n path: PathRef\n start: number\n end: number\n}\n\nexport interface IntervalQuery extends PathWindow, QueryOptions {\n keep?: ((name: PathName) => boolean) | undefined\n}\n\nexport interface OffsetQuery extends QueryOptions {\n path: PathRef\n offset: number\n}\n\nexport type NodeHaplotypeOutput = Exclude<HaplotypeOutput, 'reference-only'>\n\nexport interface NodesQuery extends Omit<QueryOptions, 'haplotypes'> {\n nodeIds: number[]\n haplotypes?: NodeHaplotypeOutput | undefined\n}\n\nexport interface BetweenQuery {\n startHandle: number\n endHandle: number\n haplotypes?: NodeHaplotypeOutput | undefined\n limit?: number | undefined\n signal?: AbortSignal | undefined\n}\n\nfunction wholeNumber(name: string, value: number, min = 0) {\n if (!Number.isSafeInteger(value) || value < min) {\n throw new Error(\n `${name} must be a whole number${min > 0 ? ` of at least ${min}` : ''}, not ${value}`,\n )\n }\n return value\n}\n\nfunction contextOf(opts: QueryOptions) {\n return wholeNumber('context', opts.context ?? 100)\n}\n\nfunction createSubgraph(db: GBZBase, opts: QueryOptions | BetweenQuery) {\n if (opts.limit !== undefined) {\n wholeNumber('limit', opts.limit)\n }\n return Subgraph.create(db, opts)\n}\n\nexport async function subgraphAtOffset(db: GBZBase, opts: OffsetQuery) {\n const context = contextOf(opts)\n const subgraph = createSubgraph(db, opts)\n const reference = await subgraph.pathPosition(\n pathNameFor(toPathQuery(opts.path), wholeNumber('offset', opts.offset)),\n )\n await subgraph.aroundPosition(\n reference.position.handle,\n reference.position.nodeOffset,\n context,\n )\n await subgraph.extractSnarls(opts.snarls ?? 'none')\n subgraph.extractPaths(reference, opts.haplotypes ?? 'all')\n return subgraph\n}\n\n// The subgraph both routes read a window from: the reference walk through it,\n// `context` bp around that, and the snarls `snarls` selects.\nasync function aroundWindow(db: GBZBase, opts: IntervalQuery) {\n const start = wholeNumber('start', opts.start)\n const end = wholeNumber('end', opts.end)\n const context = contextOf(opts)\n const subgraph = createSubgraph(db, opts)\n try {\n const reference = await subgraph.pathPosition(\n pathNameFor(toPathQuery(opts.path), start),\n )\n await subgraph.prefetchReferenceWalk(reference, end - start)\n await subgraph.aroundInterval(reference.position, end - start, context)\n await subgraph.extractSnarls(opts.snarls ?? 'none')\n return { subgraph, reference }\n } catch (error) {\n throw error instanceof SubgraphLimitError && error.windowBp === undefined\n ? new SubgraphLimitError(error.limit, {\n windowBp: end - start,\n walkedBp: subgraph.referenceWalkedBp ?? 0,\n })\n : error\n }\n}\n\n// With `keep`, the window for a chosen set of haplotypes: the same subgraph and\n// the same walks as the sampled route narrowed by keepHaplotypes, found from\n// the haplotype index without walking the haplotypes `keep` rejects, or by\n// extracting and identifying every walk when the index cannot show those walks\n// complete. 'distinct' merges the kept walks afterwards, so its weights count\n// kept haplotypes.\nexport async function subgraphInInterval(db: GBZBase, opts: IntervalQuery) {\n const { keep } = opts\n const haplotypes = opts.haplotypes ?? 'all'\n const named = haplotypes === 'all' || haplotypes === 'distinct'\n if (keep !== undefined && named && !db.hasHaplotypeIndex) {\n throw new Error(\n 'keep needs the haplotype index: this database cannot name its walks',\n )\n }\n const { subgraph, reference } = await aroundWindow(db, opts)\n if (keep === undefined || !named) {\n subgraph.extractPaths(reference, haplotypes)\n return subgraph\n }\n if (\n !(await subgraph.extractChosenPaths(\n reference,\n opts.end - opts.start,\n keep,\n contextOf(opts),\n ))\n ) {\n subgraph.extractPaths(reference, 'all')\n await subgraph.identifyPaths()\n }\n subgraph.keepHaplotypes(keep)\n if (haplotypes === 'distinct') {\n subgraph.mergeDistinct()\n }\n return subgraph\n}\n\nexport async function subgraphAroundNodes(db: GBZBase, opts: NodesQuery) {\n const haplotypes = (opts.haplotypes ?? 'all') as HaplotypeOutput\n const snarls = opts.snarls ?? 'none'\n if (haplotypes === 'reference-only') {\n throw new Error('Cannot output a reference path in a node-based query')\n }\n if (snarls === 'overlapping' && new Set(opts.nodeIds).size > 1) {\n throw new Error(\n 'Overlapping snarls cannot be extracted for a node-based query with multiple nodes',\n )\n }\n const context = contextOf(opts)\n for (const id of opts.nodeIds) {\n wholeNumber('node id', id, 1)\n }\n const subgraph = createSubgraph(db, opts)\n await subgraph.aroundNodes(opts.nodeIds, context)\n await subgraph.extractSnarls(snarls)\n subgraph.extractPaths(undefined, haplotypes)\n return subgraph\n}\n\nexport async function subgraphBetween(db: GBZBase, opts: BetweenQuery) {\n const haplotypes = (opts.haplotypes ?? 'all') as HaplotypeOutput\n if (haplotypes === 'reference-only') {\n throw new Error('Cannot output a reference path in a node-based query')\n }\n const subgraph = createSubgraph(db, opts)\n await subgraph.betweenNodes(\n wholeNumber('startHandle', opts.startHandle, 2),\n wholeNumber('endHandle', opts.endHandle, 2),\n )\n subgraph.extractPaths(undefined, haplotypes)\n return subgraph\n}\n", "export type SqlValue = null | number | string | Uint8Array\n\nexport function readVarint(\n bytes: Uint8Array,\n offset: number,\n): [value: number, next: number] {\n let value = 0\n for (let i = 0; i < 8; i++) {\n const byte = bytes[offset + i]\n if (byte === undefined) {\n throw new Error('SQLite varint runs past the end of the buffer')\n }\n value = value * 128 + (byte & 0x7f)\n if ((byte & 0x80) === 0) {\n if (i === 7 && !Number.isSafeInteger(value)) {\n throw new Error('SQLite varint exceeds the safe integer range')\n }\n return [value, offset + i + 1]\n }\n }\n const last = bytes[offset + 8]\n if (last === undefined) {\n throw new Error('SQLite varint runs past the end of the buffer')\n }\n value = value * 256 + last\n if (!Number.isSafeInteger(value)) {\n throw new Error('SQLite varint exceeds the safe integer range')\n }\n return [value, offset + 9]\n}\n\nfunction readSignedInt(view: DataView, offset: number, width: number) {\n switch (width) {\n case 1:\n return view.getInt8(offset)\n case 2:\n return view.getInt16(offset)\n case 3:\n return (view.getInt8(offset) << 16) | view.getUint16(offset + 1)\n case 4:\n return view.getInt32(offset)\n case 6:\n return view.getInt16(offset) * 4294967296 + view.getUint32(offset + 2)\n default: {\n const big = view.getBigInt64(offset)\n if (\n big > BigInt(Number.MAX_SAFE_INTEGER) ||\n big < BigInt(Number.MIN_SAFE_INTEGER)\n ) {\n throw new Error(`SQLite integer ${big} exceeds the safe integer range`)\n }\n return Number(big)\n }\n }\n}\n\nconst decoder = new TextDecoder()\n\nexport function decodeRecord(payload: Uint8Array): SqlValue[] {\n const [headerSize, firstType] = readVarint(payload, 0)\n const types: number[] = []\n let offset = firstType\n while (offset < headerSize) {\n const [type, next] = readVarint(payload, offset)\n types.push(type)\n offset = next\n }\n const view = new DataView(\n payload.buffer,\n payload.byteOffset,\n payload.byteLength,\n )\n let body = headerSize\n return types.map(type => {\n if (type === 0) {\n return null\n }\n if (type >= 1 && type <= 6) {\n const width = type <= 4 ? type : type === 5 ? 6 : 8\n const value = readSignedInt(view, body, width)\n body += width\n return value\n }\n if (type === 7) {\n const value = view.getFloat64(body)\n body += 8\n return value\n }\n if (type === 8) {\n return 0\n }\n if (type === 9) {\n return 1\n }\n if (type >= 12) {\n const length = (type - 12) >> 1\n const slice = payload.subarray(body, body + length)\n body += length\n return type % 2 === 0 ? slice : decoder.decode(slice)\n }\n throw new Error(`SQLite serial type ${type} is reserved`)\n })\n}\n", "import { decodeRecord, readVarint } from './record.ts'\n\nimport type { Pager } from './pager.ts'\nimport type { SqlValue } from './record.ts'\n\nconst INTERIOR_INDEX = 0x02\nconst INTERIOR_TABLE = 0x05\nconst LEAF_INDEX = 0x0a\nconst LEAF_TABLE = 0x0d\n\ninterface PageHeader {\n type: number\n cellCount: number\n rightChild: number\n cellPointers: number\n}\n\nfunction readUint16(page: Uint8Array, offset: number) {\n return page[offset]! * 256 + page[offset + 1]!\n}\n\nfunction readUint32(page: Uint8Array, offset: number) {\n return (\n page[offset]! * 16777216 +\n page[offset + 1]! * 65536 +\n page[offset + 2]! * 256 +\n page[offset + 3]!\n )\n}\n\nfunction readHeader(page: Uint8Array, start: number): PageHeader {\n const type = page[start]\n if (\n type !== INTERIOR_INDEX &&\n type !== INTERIOR_TABLE &&\n type !== LEAF_INDEX &&\n type !== LEAF_TABLE\n ) {\n throw new Error(`SQLite page has unknown b-tree type ${type}`)\n }\n const interior = type === INTERIOR_INDEX || type === INTERIOR_TABLE\n return {\n type,\n cellCount: readUint16(page, start + 3),\n rightChild: interior ? readUint32(page, start + 8) : 0,\n cellPointers: start + (interior ? 12 : 8),\n }\n}\n\nfunction cellOffset(page: Uint8Array, header: PageHeader, index: number) {\n return readUint16(page, header.cellPointers + 2 * index)\n}\n\ninterface IndexCell {\n values: SqlValue[]\n leftChild: number\n}\n\nconst MAX_DECODED_INDEX_PAGES = 4096\n\nexport class BTree {\n private readonly usable: number\n private pager: Pager\n private decodedIndexPages = new Map<number, (IndexCell | undefined)[]>()\n private tableDepths = new Map<number, Promise<number>>()\n\n constructor(pager: Pager, reservedBytes: number) {\n this.pager = pager\n this.usable = pager.pageSize - reservedBytes\n }\n\n private localPayloadSize(total: number, isIndex: boolean) {\n const usable = this.usable\n const maxLocal = isIndex\n ? Math.floor(((usable - 12) * 64) / 255) - 23\n : usable - 35\n if (total <= maxLocal) {\n return total\n }\n const minLocal = Math.floor(((usable - 12) * 32) / 255) - 23\n const spill = minLocal + ((total - minLocal) % (usable - 4))\n return spill <= maxLocal ? spill : minLocal\n }\n\n private async payload(\n page: Uint8Array,\n offset: number,\n total: number,\n isIndex: boolean,\n ) {\n const local = this.localPayloadSize(total, isIndex)\n if (local === total) {\n return page.subarray(offset, offset + total)\n }\n const result = new Uint8Array(total)\n result.set(page.subarray(offset, offset + local), 0)\n let filled = local\n let next = readUint32(page, offset + local)\n while (next !== 0 && filled < total) {\n const overflow = await this.pager.page(next)\n const chunk = overflow.subarray(\n 4,\n 4 + Math.min(this.usable - 4, total - filled),\n )\n result.set(chunk, filled)\n filled += chunk.length\n next = readUint32(overflow, 0)\n }\n if (filled !== total) {\n throw new Error(\n 'SQLite overflow chain ended before the payload was complete',\n )\n }\n return result\n }\n\n private async pageAt(pageNumber: number) {\n const page = await this.pager.page(pageNumber)\n return { page, header: readHeader(page, pageNumber === 1 ? 100 : 0) }\n }\n\n private tableDepth(root: number, towards: number) {\n let depth = this.tableDepths.get(root)\n if (!depth) {\n depth = (async () => {\n let pageNumber = root\n for (let level = 0; ; level++) {\n const { page, header } = await this.pageAt(pageNumber)\n if (header.type === LEAF_TABLE) {\n return level\n }\n if (header.type !== INTERIOR_TABLE) {\n throw new Error('SQLite table b-tree contains an index page')\n }\n const child = this.childIndexFor(page, header, towards)\n pageNumber =\n child === header.cellCount\n ? header.rightChild\n : readUint32(page, cellOffset(page, header, child))\n }\n })()\n this.tableDepths.set(root, depth)\n depth.catch(() => this.tableDepths.delete(root))\n }\n return depth\n }\n\n private childIndexFor(page: Uint8Array, header: PageHeader, rowid: number) {\n let low = 0\n let high = header.cellCount\n while (low < high) {\n const mid = (low + high) >> 1\n const [key] = readVarint(page, cellOffset(page, header, mid) + 4)\n if (key < rowid) {\n low = mid + 1\n } else {\n high = mid\n }\n }\n return low\n }\n\n // Fetches the pages that hold the rows of the ranges, level by level. Up to\n // the pager's budget they come at once; past it a strict prefetch gives up\n // and returns false, and a streaming one fetches the leading blocks now and\n // the rest in chunks as reads approach them.\n async prefetchRowidRanges(\n root: number,\n ranges: [number, number][],\n stream = false,\n ) {\n if (ranges.length === 0) {\n return true\n }\n const leafLevel = await this.tableDepth(root, ranges[0]![0])\n let frontiers = ranges.map(() => [root])\n for (let level = 0; level < leafLevel; level++) {\n frontiers = await Promise.all(\n frontiers.map((pages, r) => this.childrenInRange(pages, ...ranges[r]!)),\n )\n const pages = frontiers.flat()\n if (stream) {\n this.pager.prefetchLeading(pages)\n } else if (!this.pager.prefetch(pages)) {\n return false\n }\n }\n return true\n }\n\n private async childrenInRange(pages: number[], lo: number, hi: number) {\n const decoded = await Promise.all(pages.map(n => this.pageAt(n)))\n const children: number[] = []\n decoded.forEach(({ page, header }, i) => {\n const from = i === 0 ? this.childIndexFor(page, header, lo) : 0\n const to =\n i === decoded.length - 1\n ? this.childIndexFor(page, header, hi)\n : header.cellCount\n for (let c = from; c <= to; c++) {\n children.push(\n c === header.cellCount\n ? header.rightChild\n : readUint32(page, cellOffset(page, header, c)),\n )\n }\n })\n return children\n }\n\n async tableRowid(\n root: number,\n rowid: number,\n ): Promise<SqlValue[] | undefined> {\n let pageNumber = root\n for (;;) {\n const { page, header } = await this.pageAt(pageNumber)\n if (header.type === LEAF_TABLE) {\n let low = 0\n let high = header.cellCount\n while (low < high) {\n const mid = (low + high) >> 1\n const offset = cellOffset(page, header, mid)\n const [size, afterSize] = readVarint(page, offset)\n const [key, afterKey] = readVarint(page, afterSize)\n if (key === rowid) {\n return decodeRecord(await this.payload(page, afterKey, size, false))\n }\n if (key < rowid) {\n low = mid + 1\n } else {\n high = mid\n }\n }\n return undefined\n }\n if (header.type !== INTERIOR_TABLE) {\n throw new Error('SQLite table b-tree contains an index page')\n }\n let low = 0\n let high = header.cellCount\n while (low < high) {\n const mid = (low + high) >> 1\n const offset = cellOffset(page, header, mid)\n const [key] = readVarint(page, offset + 4)\n if (key < rowid) {\n low = mid + 1\n } else {\n high = mid\n }\n }\n pageNumber =\n low === header.cellCount\n ? header.rightChild\n : readUint32(page, cellOffset(page, header, low))\n }\n }\n\n async *tableScan(\n root: number,\n ): AsyncGenerator<{ rowid: number; values: SqlValue[] }> {\n yield* this.scanPage(root, await this.tableDepth(root, 0))\n }\n\n // Prefetches only leaves: interior pages prefetched a level up would be\n // evicted by the leaf prefetches below them before they were read\n private async *scanPage(\n pageNumber: number,\n depth: number,\n ): AsyncGenerator<{ rowid: number; values: SqlValue[] }> {\n const { page, header } = await this.pageAt(pageNumber)\n if (header.type === LEAF_TABLE) {\n for (let i = 0; i < header.cellCount; i++) {\n const offset = cellOffset(page, header, i)\n const [size, afterSize] = readVarint(page, offset)\n const [rowid, afterKey] = readVarint(page, afterSize)\n yield {\n rowid,\n values: decodeRecord(await this.payload(page, afterKey, size, false)),\n }\n }\n } else {\n const children: number[] = []\n for (let i = 0; i < header.cellCount; i++) {\n children.push(readUint32(page, cellOffset(page, header, i)))\n }\n children.push(header.rightChild)\n if (depth === 1) {\n this.pager.prefetchLeading(children)\n }\n for (const child of children) {\n yield* this.scanPage(child, depth - 1)\n }\n }\n }\n\n private decodedCells(pageNumber: number, header: PageHeader) {\n let cells = this.decodedIndexPages.get(pageNumber)\n if (cells) {\n this.decodedIndexPages.delete(pageNumber)\n } else {\n cells = new Array<IndexCell | undefined>(header.cellCount)\n if (this.decodedIndexPages.size >= MAX_DECODED_INDEX_PAGES) {\n const oldest = this.decodedIndexPages.keys().next().value\n if (oldest !== undefined) {\n this.decodedIndexPages.delete(oldest)\n }\n }\n }\n this.decodedIndexPages.set(pageNumber, cells)\n return cells\n }\n\n private async indexCell(\n pageNumber: number,\n page: Uint8Array,\n header: PageHeader,\n index: number,\n ): Promise<IndexCell> {\n const cells = this.decodedCells(pageNumber, header)\n let cell = cells[index]\n if (!cell) {\n const offset = cellOffset(page, header, index)\n const interior = header.type === INTERIOR_INDEX\n const [size, afterSize] = readVarint(page, interior ? offset + 4 : offset)\n cell = {\n values: decodeRecord(await this.payload(page, afterSize, size, true)),\n leftChild: interior ? readUint32(page, offset) : 0,\n }\n cells[index] = cell\n }\n return cell\n }\n\n // The first cell at or past `key`, by binary search from `from`.\n private async lowerBound(\n pageNumber: number,\n page: Uint8Array,\n header: PageHeader,\n key: number[],\n from: number,\n inclusive: boolean,\n ) {\n let low = from\n let high = header.cellCount\n while (low < high) {\n const mid = (low + high) >> 1\n const cell = await this.indexCell(pageNumber, page, header, mid)\n const order = compareKey(cell.values, key)\n if (order < 0 || (inclusive && order === 0)) {\n low = mid + 1\n } else {\n high = mid\n }\n }\n return low\n }\n\n // The entries from `low` on in key order, and with `high` only those up to\n // it, their pages read ahead.\n async *indexScanFrom(\n root: number,\n low: number[],\n high?: number[],\n ): AsyncGenerator<SqlValue[]> {\n const { page, header } = await this.pageAt(root)\n const first = await this.lowerBound(root, page, header, low, 0, false)\n const interior = header.type === INTERIOR_INDEX\n if (interior && high) {\n const past = await this.lowerBound(root, page, header, high, first, true)\n const children: number[] = []\n for (let c = first; c <= past; c++) {\n children.push(\n c === header.cellCount\n ? header.rightChild\n : (await this.indexCell(root, page, header, c)).leftChild,\n )\n }\n this.pager.prefetchLeading(children)\n }\n for (let i = first; i < header.cellCount; i++) {\n const cell = await this.indexCell(root, page, header, i)\n if (interior) {\n yield* this.indexScanFrom(cell.leftChild, low, high)\n }\n if (high && compareKey(cell.values, high) > 0) {\n return\n }\n yield cell.values\n }\n if (interior) {\n yield* this.indexScanFrom(header.rightChild, low, high)\n }\n }\n\n async indexSeekLE(\n root: number,\n key: number[],\n ): Promise<SqlValue[] | undefined> {\n let best: SqlValue[] | undefined\n let pageNumber = root\n for (;;) {\n const { page, header } = await this.pageAt(pageNumber)\n let low = 0\n let high = header.cellCount\n let child = 0\n while (low < high) {\n const mid = (low + high) >> 1\n const cell = await this.indexCell(pageNumber, page, header, mid)\n if (compareKey(cell.values, key) <= 0) {\n best = cell.values\n low = mid + 1\n } else {\n child = cell.leftChild\n high = mid\n }\n }\n if (header.type === LEAF_INDEX) {\n return best\n }\n pageNumber = low === header.cellCount ? header.rightChild : child\n }\n }\n}\n\nfunction compareKey(values: SqlValue[], key: number[]) {\n for (let i = 0; i < key.length; i++) {\n const a = values[i]\n const b = key[i]\n if (typeof a !== 'number' || b === undefined) {\n throw new Error('SQLite index key is not numeric')\n }\n if (a !== b) {\n return a < b ? -1 : 1\n }\n }\n return 0\n}\n", "import type { ByteSource } from '../filehandle.ts'\n\nexport interface PagerOptions {\n blockSize?: number | undefined\n maxBlocks?: number | undefined\n}\n\nexport function checkPagerOptions({ blockSize, maxBlocks }: PagerOptions) {\n if (\n blockSize !== undefined &&\n !(Number.isSafeInteger(blockSize) && blockSize > 0)\n ) {\n throw new Error(`blockSize must be a positive integer, not ${blockSize}`)\n }\n if (\n maxBlocks !== undefined &&\n !(Number.isSafeInteger(maxBlocks) && maxBlocks > 0)\n ) {\n throw new Error(`maxBlocks must be a positive integer, not ${maxBlocks}`)\n }\n}\n\n// Blocks a reader asked for ahead of time, fetched in chunks as its reads\n// approach the end of what has been fetched.\ninterface Plan {\n blocks: number[]\n position: Map<number, number>\n next: number\n}\n\nexport class Pager {\n private blocks = new Map<number, Promise<Uint8Array>>()\n private readonly blockSize: number\n private readonly maxBlocks: number\n private plan: Plan | undefined\n bytesFetched = 0\n fetches = 0\n\n private source: ByteSource\n readonly pageSize: number\n private fileSize: number\n\n constructor(\n source: ByteSource,\n pageSize: number,\n fileSize: number,\n opts: PagerOptions = {},\n ) {\n this.source = source\n this.pageSize = pageSize\n this.fileSize = fileSize\n const requested = opts.blockSize ?? 65536\n this.blockSize = Math.max(\n pageSize,\n Math.ceil(requested / pageSize) * pageSize,\n )\n this.maxBlocks = opts.maxBlocks ?? 256\n }\n\n private async read(length: number, start: number) {\n const bytes = await this.readRetrying(length, start)\n this.bytesFetched += bytes.length\n if (bytes.length < length) {\n throw new Error(\n `the file ends at byte ${start + bytes.length}, short of the ${this.fileSize} bytes its SQLite header gives`,\n )\n }\n return bytes\n }\n\n private async readRetrying(length: number, start: number) {\n let attempt = 0\n for (;;) {\n try {\n return await this.source.read(length, start)\n } catch (error) {\n attempt += 1\n if (attempt >= 3) {\n throw error\n }\n await new Promise(resolve => setTimeout(resolve, 200 * attempt))\n }\n }\n }\n\n seed(index: number, bytes: Uint8Array) {\n if (\n bytes.length ===\n Math.min(this.blockSize, this.fileSize - index * this.blockSize)\n ) {\n this.blocks.set(index, Promise.resolve(bytes))\n }\n }\n\n private block(index: number) {\n this.follow(index)\n const cached = this.touch(index)\n if (cached) {\n return cached\n }\n const start = index * this.blockSize\n const length = Math.min(this.blockSize, this.fileSize - start)\n const pending = this.read(length, start)\n this.fetches += 1\n this.store(index, pending)\n this.evict()\n return pending\n }\n\n private touch(index: number) {\n const cached = this.blocks.get(index)\n if (cached) {\n this.blocks.delete(index)\n this.blocks.set(index, cached)\n }\n return cached\n }\n\n private blockOf(pageNumber: number) {\n return Math.floor(((pageNumber - 1) * this.pageSize) / this.blockSize)\n }\n\n // half the cache, so a prefetch cannot evict its own blocks\n private get prefetchBudget() {\n return Math.max(1, Math.floor(this.maxBlocks / 2))\n }\n\n private get chunk() {\n return Math.max(1, Math.floor(this.prefetchBudget / 2))\n }\n\n // Fetches the pages' blocks when they fit the budget together.\n prefetch(pageNumbers: number[]) {\n const indexes = new Set(pageNumbers.map(n => this.blockOf(n)))\n if (indexes.size > this.prefetchBudget) {\n return false\n }\n this.fetchBlocks(indexes)\n return true\n }\n\n // Fetches the first pages' blocks now, up to the budget, and plans the rest\n // in the pages' order, to be fetched chunk by chunk as reads approach them.\n prefetchLeading(pageNumbers: number[]) {\n const blocks: number[] = []\n const position = new Map<number, number>()\n for (const pageNumber of pageNumbers) {\n const index = this.blockOf(pageNumber)\n if (!position.has(index)) {\n position.set(index, blocks.length)\n blocks.push(index)\n }\n }\n this.plan = { blocks, position, next: 0 }\n this.advance(this.prefetchBudget)\n }\n\n private advance(count: number) {\n const plan = this.plan\n if (!plan) {\n return\n }\n const slice = plan.blocks.slice(plan.next, plan.next + count)\n plan.next += slice.length\n if (plan.next >= plan.blocks.length) {\n this.plan = undefined\n }\n this.fetchBlocks(new Set(slice))\n }\n\n // A read within half a chunk of the end of the fetched part of the plan\n // brings in the next chunk.\n private follow(index: number) {\n const plan = this.plan\n const at = plan?.position.get(index)\n if (\n plan &&\n at !== undefined &&\n at >= plan.next - Math.ceil(this.chunk / 2)\n ) {\n this.advance(this.chunk)\n }\n }\n\n private fetchBlocks(indexes: Set<number>) {\n const wanted = [...indexes]\n .filter(index => !this.touch(index))\n .sort((a, b) => a - b)\n let runStart = 0\n while (runStart < wanted.length) {\n let runEnd = runStart + 1\n while (\n runEnd < wanted.length &&\n wanted[runEnd] === wanted[runEnd - 1]! + 1\n ) {\n runEnd += 1\n }\n this.fetchRun(wanted[runStart]!, runEnd - runStart)\n runStart = runEnd\n }\n }\n\n private fetchRun(firstIndex: number, count: number) {\n const start = firstIndex * this.blockSize\n const length = Math.min(count * this.blockSize, this.fileSize - start)\n const pending = this.read(length, start)\n this.fetches += 1\n for (let i = 0; i < count; i++) {\n const within = i * this.blockSize\n this.store(\n firstIndex + i,\n pending.then(bytes => bytes.subarray(within, within + this.blockSize)),\n )\n }\n this.evict()\n }\n\n private store(index: number, block: Promise<Uint8Array>) {\n this.blocks.set(index, block)\n block.catch(() => {\n if (this.blocks.get(index) === block) {\n this.blocks.delete(index)\n }\n })\n }\n\n private evict() {\n while (this.blocks.size > this.maxBlocks) {\n const oldest = this.blocks.keys().next().value\n if (oldest === undefined) {\n break\n }\n this.blocks.delete(oldest)\n }\n }\n\n async page(pageNumber: number) {\n const offset = (pageNumber - 1) * this.pageSize\n if (pageNumber < 1 || offset + this.pageSize > this.fileSize) {\n throw new Error(`SQLite page ${pageNumber} is outside the file`)\n }\n const bytes = await this.block(Math.floor(offset / this.blockSize))\n const within = offset % this.blockSize\n return bytes.subarray(within, within + this.pageSize)\n }\n}\n", "import { BTree } from './btree.ts'\nimport { Pager, checkPagerOptions } from './pager.ts'\n\nimport type { ByteSource } from '../filehandle.ts'\nimport type { PagerOptions } from './pager.ts'\nimport type { SqlValue } from './record.ts'\n\nexport interface SqliteObject {\n type: string\n name: string\n tableName: string\n rootPage: number\n sql: string\n}\n\nexport class SqliteDatabase {\n readonly pager: Pager\n readonly btree: BTree\n readonly objects: Map<string, SqliteObject>\n\n private constructor(\n pager: Pager,\n btree: BTree,\n objects: Map<string, SqliteObject>,\n ) {\n this.pager = pager\n this.btree = btree\n this.objects = objects\n }\n\n static async open(source: ByteSource, opts: PagerOptions = {}) {\n checkPagerOptions(opts)\n const firstBlock = await source.read(\n Math.max(512, opts.blockSize ?? 65536),\n 0,\n )\n const header = firstBlock.subarray(0, 100)\n const magic = new TextDecoder().decode(header.subarray(0, 15))\n if (magic !== 'SQLite format 3' || header.length < 100) {\n throw new Error('Not a SQLite database')\n }\n const view = new DataView(\n header.buffer,\n header.byteOffset,\n header.byteLength,\n )\n const rawPageSize = view.getUint16(16)\n const pageSize = rawPageSize === 1 ? 65536 : rawPageSize\n const reserved = header[20] ?? 0\n const encoding = view.getUint32(56)\n if (encoding !== 1) {\n throw new Error(`SQLite text encoding ${encoding} is not UTF-8`)\n }\n const pageCount = view.getUint32(28)\n if (pageCount === 0 || view.getUint32(24) !== view.getUint32(92)) {\n throw new Error(\n 'SQLite header has no valid database size; the file was written by SQLite older than 3.7.0',\n )\n }\n const size = pageCount * pageSize\n const pager = new Pager(source, pageSize, size, opts)\n pager.seed(0, firstBlock)\n pager.fetches += 1\n pager.bytesFetched += firstBlock.length\n const btree = new BTree(pager, reserved)\n const objects = new Map<string, SqliteObject>()\n for await (const { values } of btree.tableScan(1)) {\n const [type, name, tableName, rootPage, sql] = values\n if (\n typeof type === 'string' &&\n typeof name === 'string' &&\n typeof tableName === 'string' &&\n typeof rootPage === 'number'\n ) {\n objects.set(name, {\n type,\n name,\n tableName,\n rootPage,\n sql: typeof sql === 'string' ? sql : '',\n })\n }\n }\n return new SqliteDatabase(pager, btree, objects)\n }\n\n rootPage(name: string) {\n const object = this.objects.get(name)\n if (!object) {\n throw new Error(`SQLite database has no object named ${name}`)\n }\n return object.rootPage\n }\n\n // Whether a table keeps its whole rows in the b-tree of its primary key.\n withoutRowid(tableName: string) {\n const table = this.objects.get(tableName)\n return table?.type === 'table' && /without\\s+rowid/i.test(table.sql)\n }\n\n // The b-tree keyed by a table's primary key: its automatic index, or the\n // table itself when it is WITHOUT ROWID.\n indexOn(tableName: string) {\n const index = [...this.objects.values()].find(\n o => o.type === 'index' && o.tableName === tableName,\n )\n if (index) {\n return index.rootPage\n }\n if (this.withoutRowid(tableName)) {\n return this.rootPage(tableName)\n }\n throw new Error(`SQLite table ${tableName} has no index`)\n }\n\n byRowid(table: string, rowid: number) {\n return this.btree.tableRowid(this.rootPage(table), rowid)\n }\n\n prefetchRows(table: string, ranges: [number, number][], stream = false) {\n return this.btree.prefetchRowidRanges(this.rootPage(table), ranges, stream)\n }\n\n scan(table: string) {\n return this.btree.tableScan(this.rootPage(table))\n }\n\n indexSeekLE(table: string, key: number[]): Promise<SqlValue[] | undefined> {\n return this.btree.indexSeekLE(this.indexOn(table), key)\n }\n\n // The entries of a table's primary key from `low` on, or up to `high`.\n indexScanFrom(table: string, low: number[], high?: number[]) {\n return this.btree.indexScanFrom(this.indexOn(table), low, high)\n }\n\n has(name: string) {\n return this.objects.has(name)\n }\n}\n", "import { ENDMARKER, nodeId, nodeOrientation } from './gbwt/node.ts'\nimport { GbwtRecord, decompressEdges } from './gbwt/record.ts'\nimport { decodeSequence, encodedSequenceLength } from './gbwt/sequence.ts'\nimport { graphNameFromTags } from './graphName.ts'\nimport { formatPathName, pathNameFor, toPathQuery } from './pathName.ts'\nimport {\n subgraphAroundNodes,\n subgraphAtOffset,\n subgraphBetween,\n subgraphInInterval,\n} from './query.ts'\nimport { SqliteDatabase } from './sqlite/database.ts'\nimport { SubgraphLimitError } from './subgraph.ts'\n\nimport type { ByteSource } from './filehandle.ts'\nimport type { Pos } from './gbwt/record.ts'\nimport type { GraphName } from './graphName.ts'\nimport type { PathName, PathRef } from './pathName.ts'\nimport type {\n BetweenQuery,\n IntervalQuery,\n NodesQuery,\n OffsetQuery,\n PathWindow,\n} from './query.ts'\nimport type { PagerOptions } from './sqlite/pager.ts'\nimport type { SqlValue } from './sqlite/record.ts'\nimport type { HaplotypeAlignment, Subgraph } from './subgraph.ts'\n\nexport const SCHEMA_VERSION = 'GBZ-base version 4'\n\nexport interface PathFragment {\n path: GbzPath\n start: number\n end: number\n}\n\nexport type WindowQuery = IntervalQuery\n\nexport interface AlignmentQuery extends Omit<\n WindowQuery,\n 'haplotypes' | 'snarls'\n> {\n haplotypes?: 'all' | 'distinct' | undefined\n}\n\nexport class UnknownPathError extends Error {\n override name = 'UnknownPathError'\n\n readonly path: PathName\n\n constructor(path: PathName) {\n super(`the graph has no path named ${formatPathName(path)}`)\n this.path = path\n }\n}\n\nexport class ForwardOnlyIndexError extends Error {\n override name = 'ForwardOnlyIndexError'\n\n constructor() {\n super(\n 'the haplotype index was written with --forward-only, which cannot name the walks stored against their reference (about half of them); rebuild it with gbz-haplotype-index without --forward-only',\n )\n }\n}\n\nexport class SchemaVersionError extends Error {\n override name = 'SchemaVersionError'\n\n readonly found: string | undefined\n\n constructor(found: string | undefined) {\n super(\n found === undefined\n ? `not a gbz-base database: it has no version tag`\n : `unsupported database schema \"${found}\"; this reader understands \"${SCHEMA_VERSION}\"`,\n )\n this.found = found\n }\n}\n\nexport interface IndexedPosition {\n pathOffset: number\n pos: Pos\n}\n\nexport interface HaplotypeSample {\n node: number\n offset: number\n pathHandle: number\n orientation: 'forward' | 'reverse'\n pathOffset: number\n}\n\nexport interface HaplotypeAnchor {\n node: number\n pathOffset: number\n}\n\n// An anchor of a reference path with the forward samples at its node: one\n// visit of every haplotype that passes it, each with its GBWT position and\n// its offset along its own path.\nexport interface HaplotypeAnchorRow extends HaplotypeAnchor {\n anchorOffset: number\n visits: HaplotypeSample[]\n}\n\n// One bin of a reference path in the haplotype index's overview: how many\n// haplotypes fall in each class there, and the excursions from the reference\n// that start in it.\nexport interface OverviewBin {\n start: number\n end: number\n // haplotypes that are absent, reference-like, partial and variant\n classes: [number, number, number, number]\n excursions: number\n variants: number\n longestExcursion: number\n}\n\nexport const OVERVIEW_ABSENT = 0\nexport const OVERVIEW_REFERENCE = 1\nexport const OVERVIEW_PARTIAL = 2\nexport const OVERVIEW_VARIANT = 3\n\n// A binned summary of every haplotype along a stretch of a reference path,\n// at one zoom level. `cells` holds bins.length \u00D7 haplotypes.length entries,\n// bin by bin: the class in the low two bits, and for a variant cell a bucket\n// of the bin's variant marks in the next two (1, 2 to 3, 4 to 15, 16 or\n// more).\nexport interface HaplotypeOverview {\n level: number\n bin: number\n haplotypes: { sample: string; haplotype: number }[]\n bins: OverviewBin[]\n cells: Uint8Array\n}\n\nexport interface OverviewQuery extends PathWindow {\n // The zoom level, clamped to those the index holds, or the bp per pixel to\n // choose the coarsest level whose bins are no larger than it. Level 0\n // without either.\n level?: number | undefined\n bpPerPixel?: number | undefined\n signal?: AbortSignal | undefined\n}\n\nfunction concatBytes(parts: Uint8Array[]) {\n if (parts.length === 1) {\n return parts[0]!\n }\n const whole = new Uint8Array(parts.reduce((n, p) => n + p.length, 0))\n let at = 0\n for (const part of parts) {\n whole.set(part, at)\n at += part.length\n }\n return whole\n}\n\n// The format of the haplotype index this reader understands: the samples in\n// their key b-tree, each anchor's visits with the anchor and each bin's stray\n// rows with its node list, which gbz-haplotype-index 0.3 writes.\nconst INDEX_FORMAT = 3\n\nclass Varints {\n private at = 0\n private bytes: Uint8Array\n\n constructor(bytes: Uint8Array) {\n this.bytes = bytes\n }\n\n get done() {\n return this.at >= this.bytes.length\n }\n\n next() {\n let value = 0\n let scale = 1\n for (;;) {\n const byte = this.bytes[this.at++]\n if (byte === undefined) {\n throw new Error('a haplotype index blob ends inside a number')\n }\n value += (byte & 0x7f) * scale\n scale *= 128\n if ((byte & 0x80) === 0) {\n return value\n }\n }\n }\n}\n\n// Appends the runs of node ids a HaplotypeBins node-list part encodes: per\n// run, the gap from the previous run's last id and the length less one.\nfunction decodeRuns(bytes: Uint8Array, runs: [number, number][]) {\n const reader = new Varints(bytes)\n let previous = 0\n while (!reader.done) {\n const start = previous + reader.next()\n previous = start + reader.next()\n runs.push([start, previous])\n }\n}\n\n// A test of membership in the union of the runs.\nfunction runTester(runs: [number, number][]) {\n runs.sort((x, y) => x[0] - y[0])\n const starts: number[] = []\n const ends: number[] = []\n for (const [start, end] of runs) {\n const last = ends.length - 1\n if (last >= 0 && start <= ends[last]! + 1) {\n ends[last] = Math.max(ends[last]!, end)\n } else {\n starts.push(start)\n ends.push(end)\n }\n }\n return (id: number) => {\n let lo = 0\n let hi = starts.length\n while (lo < hi) {\n const mid = (lo + hi) >> 1\n if (starts[mid]! <= id) {\n lo = mid + 1\n } else {\n hi = mid\n }\n }\n return lo > 0 && id <= ends[lo - 1]!\n }\n}\n\nfunction decodeStrays(bin: number, bytes: Uint8Array, rows: HaplotypeStray[]) {\n const reader = new Varints(bytes)\n while (!reader.done) {\n const pathHandle = reader.next()\n const pathStart = reader.next()\n const pathEnd = reader.next()\n const low = reader.next()\n const high = reader.next()\n rows.push({\n bin,\n pathHandle,\n pathStart,\n pathEnd,\n snarl: high > 0 ? [low, high] : undefined,\n node: reader.next(),\n offset: reader.next(),\n })\n }\n}\n\n// The visits of a format 3 anchor row: per visit, the path handle doubled\n// plus the orientation bit of the node handle, the node offset and the path\n// offset.\nfunction decodeVisits(\n anchorNode: number,\n parts: Uint8Array[],\n visits: HaplotypeSample[],\n) {\n const id = nodeId(anchorNode)\n for (const part of parts) {\n const reader = new Varints(part)\n while (!reader.done) {\n const pathAndBit = reader.next()\n const bit = pathAndBit % 2\n visits.push({\n node: 2 * id + bit,\n offset: reader.next(),\n pathHandle: (pathAndBit - bit) / 2,\n orientation: 'forward',\n pathOffset: reader.next(),\n })\n }\n }\n}\n\n// A row of HaplotypeStrays: a stretch of one path, from pathStart to the visit\n// at pathEnd, holding visits to nodes of one bin that the walks from anchor\n// visits can miss. `node` and `offset` are the GBWT position of its first\n// visit in the path's forward orientation. A row with a snarl names a path\n// that lies between those two boundary nodes from end to end.\nexport interface HaplotypeStray {\n bin: number\n pathHandle: number\n pathStart: number\n pathEnd: number\n snarl: [number, number] | undefined\n node: number\n offset: number\n}\n\nexport interface HaplotypeStrayOptions {\n // The largest query context the rows cover.\n context: number\n bin: number\n bound: number\n // The most nodes between a filled snarl's boundaries for the rows to cover\n // it, or undefined when the rows leave snarls out.\n snarlNodes: number | undefined\n}\n\nexport interface GbzPath {\n handle: number\n /** @internal */\n fwStart: Pos\n /** @internal */\n revStart: Pos\n name: PathName\n isIndexed: boolean\n}\n\nexport class GbzRecord {\n readonly sequenceLen: number\n readonly handle: number\n readonly edges: Pos[]\n readonly bwt: Uint8Array\n readonly encodedSequence: Uint8Array\n readonly next: number | undefined\n private decoded: string | undefined\n\n constructor(\n handle: number,\n edges: Pos[],\n bwt: Uint8Array,\n encodedSequence: Uint8Array,\n next: number | undefined,\n ) {\n this.handle = handle\n this.edges = edges\n this.bwt = bwt\n this.encodedSequence = encodedSequence\n this.next = next\n this.sequenceLen = encodedSequenceLength(encodedSequence)\n }\n\n get id() {\n return nodeId(this.handle)\n }\n\n get orientation() {\n return nodeOrientation(this.handle)\n }\n\n get sequence() {\n this.decoded ??= decodeSequence(this.encodedSequence)\n return this.decoded\n }\n\n successors() {\n return this.edges.filter(e => e.node !== ENDMARKER).map(e => e.node)\n }\n\n gbwt() {\n if (this.edges.length === 0) {\n throw new Error(`GBWT record for handle ${this.handle} is empty`)\n }\n return new GbwtRecord(this.edges, this.bwt)\n }\n}\n\nfunction num(value: SqlValue | undefined, what: string) {\n if (typeof value !== 'number') {\n throw new Error(`${what} is not a number in the database`)\n }\n return value\n}\n\nfunction str(value: SqlValue | undefined, what: string) {\n if (typeof value !== 'string') {\n throw new Error(`${what} is not text in the database`)\n }\n return value\n}\n\nfunction blob(value: SqlValue | undefined, what: string) {\n if (!(value instanceof Uint8Array)) {\n throw new Error(`${what} is not a blob in the database`)\n }\n return value\n}\n\nfunction rowToPath(rowid: number, values: SqlValue[]): GbzPath {\n return {\n handle: rowid,\n fwStart: {\n node: num(values[1], 'Paths.fw_node'),\n offset: num(values[2], 'Paths.fw_offset'),\n },\n revStart: {\n node: num(values[3], 'Paths.rev_node'),\n offset: num(values[4], 'Paths.rev_offset'),\n },\n name: {\n sample: str(values[5], 'Paths.sample'),\n contig: str(values[6], 'Paths.contig'),\n haplotype: num(values[7], 'Paths.haplotype'),\n fragment: num(values[8], 'Paths.fragment'),\n },\n isIndexed: num(values[9], 'Paths.is_indexed') !== 0,\n }\n}\n\nexport interface OpenOptions {\n source: ByteSource\n haplotypeIndex?: ByteSource | undefined\n blockSize?: number | undefined\n maxBlocks?: number | undefined\n}\n\nexport interface FetchStats {\n fetches: number\n bytesFetched: number\n}\n\nfunction forgetOnRejection<T>(pending: Promise<T>, forget: () => void) {\n pending.catch(forget)\n return pending\n}\n\nasync function readTags(sqlite: SqliteDatabase) {\n const tags = new Map<string, string>()\n for await (const { values } of sqlite.scan('Tags')) {\n tags.set(str(values[0], 'Tags.key'), str(values[1], 'Tags.value'))\n }\n return tags\n}\n\nexport class GBZBase {\n private pathCache: Promise<GbzPath[]> | undefined\n private pathMapCache: Promise<Map<number, GbzPath>> | undefined\n private indexTags = new Map<string, string>()\n private overviewRowsCache:\n Promise<{ sample: string; haplotype: number }[]> | undefined\n\n /** @internal */\n readonly sqlite: SqliteDatabase\n /** @internal */\n readonly index: SqliteDatabase | undefined\n private readonly tagMap: Map<string, string>\n\n private constructor(\n sqlite: SqliteDatabase,\n index: SqliteDatabase | undefined,\n tags: Map<string, string>,\n ) {\n this.sqlite = sqlite\n this.index = index\n this.tagMap = tags\n }\n\n static async open(opts: OpenOptions) {\n const { source, haplotypeIndex } = opts\n const pagerOptions: PagerOptions = {\n blockSize: opts.blockSize,\n maxBlocks: opts.maxBlocks,\n }\n const sqlite = await SqliteDatabase.open(source, pagerOptions)\n const tags = sqlite.objects.has('Tags')\n ? await readTags(sqlite)\n : new Map<string, string>()\n const version = tags.get('version')\n if (version !== SCHEMA_VERSION) {\n throw new SchemaVersionError(version)\n }\n for (const table of ['Nodes', 'Paths', 'ReferenceIndex']) {\n sqlite.rootPage(table)\n }\n const index = haplotypeIndex\n ? await SqliteDatabase.open(haplotypeIndex, pagerOptions)\n : undefined\n const db = new GBZBase(sqlite, index, tags)\n if (index) {\n for (const table of ['Tags', 'HaplotypeSamples', 'HaplotypeLengths']) {\n if (!index.objects.has(table)) {\n throw new Error(\n `haplotypeIndex is not a gbz-base haplotype index: it has no ${table} table`,\n )\n }\n }\n db.indexTags = await readTags(index)\n const indexed = db.indexTags.get('haplotype_index_paths')\n const paths = await db.tag('paths')\n if (indexed !== paths) {\n throw new Error(\n `haplotype index was built for ${indexed ?? 'an unknown number of'} paths but the graph has ${paths}`,\n )\n }\n const indexedNodes = db.indexTags.get('haplotype_index_nodes')\n const nodes = await db.tag('nodes')\n if (indexedNodes !== undefined && indexedNodes !== nodes) {\n throw new Error(\n `haplotype index was built for a graph with ${indexedNodes} nodes but this one has ${nodes}`,\n )\n }\n if (db.indexTags.get('haplotype_index_orientations') === 'forward') {\n throw new ForwardOnlyIndexError()\n }\n const format = db.indexTags.get('haplotype_index_format')\n if (Number(format) !== INDEX_FORMAT) {\n throw new Error(\n format === undefined\n ? `the haplotype index predates format ${INDEX_FORMAT}; rebuild it with gbz-haplotype-index 0.3`\n : `the haplotype index has format ${format}; this version of @gmod/gbz-base reads format ${INDEX_FORMAT}`,\n )\n }\n }\n return db\n }\n\n async tags() {\n return this.tagMap\n }\n\n async tag(key: string) {\n return this.tagMap.get(key)\n }\n\n /** @internal */\n prefetchRecords(ranges: [number, number][], stream = false) {\n return this.sqlite.prefetchRows('Nodes', ranges, stream)\n }\n\n /** @internal */\n async getRecord(handle: number) {\n const row = await this.sqlite.byRowid('Nodes', handle)\n if (!row) {\n return undefined\n }\n const next = row[4]\n return new GbzRecord(\n handle,\n decompressEdges(blob(row[1], 'Nodes.edges')),\n blob(row[2], 'Nodes.bwt'),\n blob(row[3], 'Nodes.sequence'),\n typeof next === 'number' ? next : undefined,\n )\n }\n\n paths() {\n this.pathCache ??= forgetOnRejection(this.scanPaths(), () => {\n this.pathCache = undefined\n })\n return this.pathCache\n }\n\n private async scanPaths() {\n const paths: GbzPath[] = []\n for await (const { rowid, values } of this.sqlite.scan('Paths')) {\n paths.push(rowToPath(rowid, values))\n }\n return paths\n }\n\n /** @internal */\n async getPath(handle: number) {\n const row = await this.sqlite.byRowid('Paths', handle)\n return row ? rowToPath(handle, row) : undefined\n }\n\n /** @internal */\n pathsByHandle() {\n this.pathMapCache ??= forgetOnRejection(\n this.paths().then(\n paths => new Map(paths.map(path => [path.handle, path])),\n ),\n () => {\n this.pathMapCache = undefined\n },\n )\n return this.pathMapCache\n }\n\n /** @internal */\n async findPath(name: PathName) {\n const candidates = (await this.paths()).filter(\n p =>\n p.name.sample === name.sample &&\n p.name.contig === name.contig &&\n p.name.haplotype === name.haplotype &&\n p.name.fragment <= name.fragment,\n )\n return candidates.sort((a, b) => b.name.fragment - a.name.fragment)[0]\n }\n\n private async pathsNamed(ref: PathRef) {\n const name = pathNameFor(toPathQuery(ref), 0)\n return (await this.paths())\n .filter(\n p =>\n p.name.sample === name.sample &&\n p.name.contig === name.contig &&\n p.name.haplotype === name.haplotype,\n )\n .sort((a, b) => a.name.fragment - b.name.fragment)\n }\n\n async hasPath(ref: PathRef) {\n return (await this.pathsNamed(ref)).length > 0\n }\n\n private pathLengths = new Map<number, Promise<number>>()\n\n /** @internal */\n pathLength(handle: number) {\n let length = this.pathLengths.get(handle)\n if (!length) {\n length = this.walkPathLength(handle)\n this.pathLengths.set(handle, length)\n length.catch(() => this.pathLengths.delete(handle))\n }\n return length\n }\n\n private async walkPathLength(handle: number) {\n const indexed = this.hasHaplotypeIndex\n ? await this.haplotypeLength(handle)\n : undefined\n if (indexed === undefined) {\n const last = await this.indexedPosition(handle, Number.MAX_SAFE_INTEGER)\n if (!last) {\n const path = await this.getPath(handle)\n throw new Error(\n `${path ? `The fragment of ${formatPathName(path.name)} at ${path.name.fragment}` : `Path ${handle}`} has not been indexed for random access`,\n )\n }\n let length = last.pathOffset\n let pos = last.pos\n for (;;) {\n const record = await this.getRecord(pos.node)\n if (!record) {\n throw new Error(`Node ${pos.node} does not exist in the graph`)\n }\n length += record.sequenceLen\n const next = record.gbwt().lf(pos.offset)\n if (!next || next.node === ENDMARKER) {\n return length\n }\n pos = next\n }\n }\n return indexed\n }\n\n async getPathFragments(opts: PathWindow): Promise<PathFragment[]> {\n const { start, end } = opts\n if (Number.isNaN(start) || Number.isNaN(end)) {\n throw new Error(`The window ${start}..${end} is not a number range`)\n }\n const ordered = await this.pathsNamed(opts.path)\n if (ordered.length === 0) {\n throw new UnknownPathError(pathNameFor(toPathQuery(opts.path), 0))\n }\n if (end <= start) {\n return []\n }\n const covering = ordered.filter(p => p.name.fragment <= start).slice(-1)\n const within = ordered.filter(\n p => p.name.fragment > start && p.name.fragment < end,\n )\n const fragments = await Promise.all(\n [...covering, ...within].map(async path => ({\n path,\n start: path.name.fragment,\n end: path.name.fragment + (await this.pathLength(path.handle)),\n })),\n )\n return fragments.filter(f => start < f.end)\n }\n\n private async subgraphForFragment(fragment: PathFragment, opts: WindowQuery) {\n const { sample, contig, haplotype } = fragment.path.name\n const start = Math.max(opts.start, fragment.start)\n const haplotypes = opts.haplotypes ?? 'all'\n try {\n const subgraph = await subgraphInInterval(this, {\n ...opts,\n path: { sample, contig, haplotype },\n start,\n end: Math.min(opts.end, fragment.end),\n })\n if (\n opts.keep === undefined &&\n this.hasHaplotypeIndex &&\n (haplotypes === 'all' || haplotypes === 'distinct')\n ) {\n await subgraph.identifyPaths()\n }\n return subgraph\n } catch (error) {\n throw error instanceof SubgraphLimitError && error.walkedBp !== undefined\n ? new SubgraphLimitError(error.limit, {\n windowBp: opts.end - opts.start,\n walkedBp: start - opts.start + error.walkedBp,\n })\n : error\n }\n }\n\n async getSubgraphs(opts: WindowQuery): Promise<Subgraph[]> {\n const fragments = await this.getPathFragments(opts)\n const settled = await Promise.allSettled(\n fragments.map(fragment => this.subgraphForFragment(fragment, opts)),\n )\n return settled.map(result => {\n if (result.status === 'rejected') {\n throw result.reason\n }\n return result.value\n })\n }\n\n async getAlignments(opts: AlignmentQuery): Promise<HaplotypeAlignment[]> {\n return (await this.getSubgraphs(opts)).flatMap(subgraph =>\n subgraph.alignments(),\n )\n }\n\n subgraphInInterval(opts: IntervalQuery) {\n return subgraphInInterval(this, opts)\n }\n\n subgraphAtOffset(opts: OffsetQuery) {\n return subgraphAtOffset(this, opts)\n }\n\n subgraphAroundNodes(opts: NodesQuery) {\n return subgraphAroundNodes(this, opts)\n }\n\n subgraphBetween(opts: BetweenQuery) {\n return subgraphBetween(this, opts)\n }\n\n fetchStats(): { graph: FetchStats; haplotypeIndex: FetchStats | undefined } {\n const stats = ({ pager }: SqliteDatabase) => ({\n fetches: pager.fetches,\n bytesFetched: pager.bytesFetched,\n })\n return {\n graph: stats(this.sqlite),\n haplotypeIndex: this.index ? stats(this.index) : undefined,\n }\n }\n\n async graphName() {\n const gbzTags = new Map<string, string>()\n for (const [key, value] of await this.tags()) {\n if (key.startsWith('gbz_')) {\n gbzTags.set(key.slice('gbz_'.length), value)\n }\n }\n let name: GraphName = {\n name: undefined,\n subgraph: new Map(),\n translation: new Map(),\n }\n try {\n name = graphNameFromTags(gbzTags)\n } catch {\n // upstream falls back to an empty name when the tags do not parse\n }\n return name\n }\n\n async hasChainLinks() {\n const links = await this.tag('chain_links')\n return links !== undefined && Number(links) > 0\n }\n\n get hasHaplotypeIndex() {\n return this.index !== undefined\n }\n\n private get companion() {\n if (!this.index) {\n throw new Error('no haplotype index was opened with this database')\n }\n return this.index\n }\n\n /** @internal */\n async haplotypeSampleInterval() {\n const value = this.indexTags.get('haplotype_index_interval')\n return value === undefined ? undefined : Number(value)\n }\n\n // The most bp between two samples of any path: the reference paths take\n // --reference-interval, which can exceed --interval.\n /** @internal */\n async haplotypeSampleGap() {\n const interval = await this.haplotypeSampleInterval()\n const reference = this.indexTags.get('haplotype_index_reference_interval')\n return interval === undefined\n ? undefined\n : Math.max(interval, reference === undefined ? 0 : Number(reference))\n }\n\n /** @internal */\n async haplotypeAnchorSpacing() {\n const value = this.index?.has('HaplotypeAnchors')\n ? this.indexTags.get('haplotype_index_anchor_spacing')\n : undefined\n return value === undefined ? undefined : Number(value)\n }\n\n // How the bins' node lists and stray rows were built, or undefined without\n // them.\n /** @internal */\n async haplotypeStrayOptions(): Promise<HaplotypeStrayOptions | undefined> {\n const tag = (key: string) =>\n this.indexTags.get(`haplotype_index_stray_${key}`)\n if (!this.index?.has('HaplotypeBins') || tag('format') !== '2') {\n return undefined\n }\n const snarls =\n tag('snarls') === 'modeled' &&\n tag('chain_links') === ((await this.tag('chain_links')) ?? '0')\n return {\n context: Number(tag('context')),\n bin: Number(tag('bin')),\n bound: Number(tag('bound')),\n snarlNodes: snarls ? Number(tag('snarl_nodes')) : undefined,\n }\n }\n\n // The rows of a table with blobs whose keys lie in low..high: a key scan of\n // its index, then its rows, which the indexer wrote in key order, prefetched\n // as one range.\n private async blobRows(table: string, low: number[], high: number[]) {\n const rows: SqlValue[][] = []\n const rowids: number[] = []\n for await (const key of this.companion.indexScanFrom(table, low, high)) {\n rowids.push(num(key[key.length - 1], `${table} rowid`))\n }\n if (rowids.length > 1) {\n await this.companion.prefetchRows(\n table,\n [[Math.min(...rowids), Math.max(...rowids) + 1]],\n true,\n )\n }\n for (const rowid of rowids) {\n const row = await this.companion.byRowid(table, rowid)\n if (row) {\n rows.push(row)\n }\n }\n return rows\n }\n\n // The node lists and stray rows of the bins firstBin..lastBin of one\n // reference path: a test of whether a node id is listed, and the rows.\n /** @internal */\n async haplotypeBinData(\n referenceHandle: number,\n firstBin: number,\n lastBin: number,\n ): Promise<{ listed: (id: number) => boolean; strays: HaplotypeStray[] }> {\n const runs: [number, number][] = []\n const strays: HaplotypeStray[] = []\n for (const row of await this.blobRows(\n 'HaplotypeBins',\n [referenceHandle, firstBin],\n [referenceHandle, lastBin],\n )) {\n const bin = num(row[1], 'HaplotypeBins.bin')\n decodeRuns(blob(row[3], 'HaplotypeBins.nodes'), runs)\n decodeStrays(bin, blob(row[4], 'HaplotypeBins.strays'), strays)\n }\n return { listed: runTester(runs), strays }\n }\n\n // The anchors of one reference path at offsets from lowOffset to\n // highOffset, each with the forward samples at its node.\n /** @internal */\n async haplotypeAnchorsBetween(\n pathHandle: number,\n lowOffset: number,\n highOffset: number,\n ): Promise<HaplotypeAnchorRow[]> {\n const rows: HaplotypeAnchorRow[] = []\n let parts: Uint8Array[] = []\n const flush = () => {\n const last = rows[rows.length - 1]\n if (last) {\n decodeVisits(last.node, parts, last.visits)\n }\n parts = []\n }\n for (const row of await this.blobRows(\n 'HaplotypeAnchors',\n [pathHandle, lowOffset],\n [pathHandle, highOffset],\n )) {\n const anchorOffset = num(row[1], 'HaplotypeAnchors.anchor_offset')\n if (rows[rows.length - 1]?.anchorOffset !== anchorOffset) {\n flush()\n rows.push({\n anchorOffset,\n node: num(row[3], 'HaplotypeAnchors.node_handle'),\n pathOffset: num(row[4], 'HaplotypeAnchors.path_offset'),\n visits: [],\n })\n }\n parts.push(blob(row[5], 'HaplotypeAnchors.visits'))\n }\n flush()\n return rows\n }\n\n /** @internal */\n async haplotypeAnchor(\n pathHandle: number,\n anchorOffset: number,\n ): Promise<HaplotypeAnchor | undefined> {\n const [row] = await this.haplotypeAnchorsBetween(\n pathHandle,\n anchorOffset,\n anchorOffset,\n )\n return row && { node: row.node, pathOffset: row.pathOffset }\n }\n\n /** @internal */\n haplotypeSamplesAtNode(handle: number) {\n return this.haplotypeSamplesInRange(handle, handle)\n }\n\n private sampleFromRow(values: SqlValue[]): HaplotypeSample {\n return {\n node: num(values[0], 'HaplotypeSamples.node_handle'),\n offset: num(values[1], 'HaplotypeSamples.node_offset'),\n pathHandle: num(values[2], 'HaplotypeSamples.path_handle'),\n orientation:\n num(values[3], 'HaplotypeSamples.orientation') === 0\n ? 'forward'\n : 'reverse',\n pathOffset: num(values[4], 'HaplotypeSamples.path_offset'),\n }\n }\n\n // The samples at the node handles minHandle..maxHandle, from the b-tree of\n // their key.\n /** @internal */\n async haplotypeSamplesInRange(minHandle: number, maxHandle: number) {\n const samples: HaplotypeSample[] = []\n for await (const row of this.companion.indexScanFrom(\n 'HaplotypeSamples',\n [minHandle, 0],\n [maxHandle, Number.MAX_SAFE_INTEGER],\n )) {\n samples.push(this.sampleFromRow(row))\n }\n return samples\n }\n\n /** @internal */\n async haplotypeSampleAt(node: number, offset: number) {\n const row = await this.companion.indexSeekLE('HaplotypeSamples', [\n node,\n offset,\n ])\n return row?.[0] === node && row[1] === offset\n ? this.sampleFromRow(row)\n : undefined\n }\n\n private overviewRows() {\n this.overviewRowsCache ??= forgetOnRejection(\n (async () => {\n const rows: { sample: string; haplotype: number }[] = []\n for await (const { rowid, values } of this.companion.scan(\n 'HaplotypeOverviewRows',\n )) {\n rows[rowid] = {\n sample: str(values[1], 'HaplotypeOverviewRows.sample'),\n haplotype: num(values[2], 'HaplotypeOverviewRows.haplotype'),\n }\n }\n return rows\n })(),\n () => {\n this.overviewRowsCache = undefined\n },\n )\n return this.overviewRowsCache\n }\n\n // The parts of one overview table for the chunks firstChunk..lastChunk of\n // one reference path at one level, joined per chunk.\n private async overviewChunks(\n table: string,\n pathHandle: number,\n level: number,\n firstChunk: number,\n lastChunk: number,\n ) {\n const parts = new Map<number, Uint8Array[]>()\n for (const row of await this.blobRows(\n table,\n [pathHandle, level, firstChunk],\n [pathHandle, level, lastChunk],\n )) {\n const chunk = num(row[2], `${table}.chunk`)\n const list = parts.get(chunk) ?? []\n list.push(blob(row[4], `${table} blob`))\n parts.set(chunk, list)\n }\n return new Map(\n [...parts].map(([chunk, list]) => [chunk, concatBytes(list)]),\n )\n }\n\n // The haplotype index's binned summary of every haplotype over a window of\n // a reference path, or undefined when the index has no overview or none for\n // this path, which is not a reference path of a sample with anchors.\n async haplotypeOverview(\n opts: OverviewQuery,\n ): Promise<HaplotypeOverview | undefined> {\n const { signal } = opts\n signal?.throwIfAborted()\n const tag = (key: string) =>\n this.indexTags.get(`haplotype_index_overview_${key}`)\n if (!this.index?.has('HaplotypeOverviewClasses') || tag('format') !== '1') {\n return undefined\n }\n const baseBin = Number(tag('bin'))\n const chunkBins = Number(tag('chunk'))\n const levels = Number(tag('levels'))\n let level = Math.max(\n 0,\n Math.min(Math.floor(opts.level ?? 0) || 0, levels - 1),\n )\n if (opts.level === undefined && opts.bpPerPixel !== undefined) {\n while (\n level + 1 < levels &&\n baseBin * 4 ** (level + 1) <= opts.bpPerPixel\n ) {\n level += 1\n }\n }\n const bin = baseBin * 4 ** level\n const [fragments, haplotypes] = await Promise.all([\n this.getPathFragments(opts),\n this.overviewRows(),\n ])\n signal?.throwIfAborted()\n const bytesPerBin = Math.ceil(haplotypes.length / 2)\n const bins: OverviewBin[] = []\n const cellRows: Uint8Array[] = []\n for (const fragment of fragments) {\n const length = fragment.end - fragment.start\n const from = Math.max(opts.start, fragment.start) - fragment.start\n const to = Math.min(opts.end, fragment.end) - fragment.start\n const firstBin = Math.floor(from / bin)\n const lastBin = Math.floor((to - 1) / bin)\n const firstChunk = Math.floor(firstBin / chunkBins)\n const lastChunk = Math.floor(lastBin / chunkBins)\n const [summaries, cells] = await Promise.all([\n this.overviewChunks(\n 'HaplotypeOverviewBins',\n fragment.path.handle,\n level,\n firstChunk,\n lastChunk,\n ),\n this.overviewChunks(\n 'HaplotypeOverviewClasses',\n fragment.path.handle,\n level,\n firstChunk,\n lastChunk,\n ),\n ])\n signal?.throwIfAborted()\n for (let chunk = firstChunk; chunk <= lastChunk; chunk++) {\n const reader = new Varints(summaries.get(chunk) ?? new Uint8Array())\n const packed = cells.get(chunk) ?? new Uint8Array()\n for (let b = chunk * chunkBins; !reader.done; b++) {\n const values = Array.from({ length: 7 }, () => reader.next())\n if (b < firstBin || b > lastBin) {\n continue\n }\n bins.push({\n start: fragment.start + b * bin,\n end: fragment.start + Math.min((b + 1) * bin, length),\n classes: [values[0]!, values[1]!, values[2]!, values[3]!],\n excursions: values[4]!,\n variants: values[5]!,\n longestExcursion: values[6]!,\n })\n const at = (b - chunk * chunkBins) * bytesPerBin\n cellRows.push(packed.subarray(at, at + bytesPerBin))\n }\n }\n }\n if (bins.length === 0) {\n return undefined\n }\n const cells = new Uint8Array(bins.length * haplotypes.length)\n cellRows.forEach((packed, b) => {\n for (let row = 0; row < haplotypes.length; row++) {\n cells[b * haplotypes.length + row] =\n ((packed[row >> 1] ?? 0) >> (4 * (row % 2))) & 0xf\n }\n })\n return { level, bin, haplotypes, bins, cells }\n }\n\n /** @internal */\n async haplotypeLength(pathHandle: number) {\n const row = await this.companion.byRowid('HaplotypeLengths', pathHandle)\n return row ? num(row[1], 'HaplotypeLengths.length') : undefined\n }\n\n private async indexedRow(rowid: number): Promise<IndexedPosition> {\n const row = await this.sqlite.byRowid('ReferenceIndex', rowid)\n if (!row) {\n throw new Error('ReferenceIndex row referenced by its index is missing')\n }\n return {\n pathOffset: num(row[1], 'ReferenceIndex.path_offset'),\n pos: {\n node: num(row[2], 'ReferenceIndex.node_handle'),\n offset: num(row[3], 'ReferenceIndex.node_offset'),\n },\n }\n }\n\n private async indexedRowid(pathHandle: number, pathOffset: number) {\n const key = await this.sqlite.indexSeekLE('ReferenceIndex', [\n pathHandle,\n pathOffset,\n ])\n return key?.[0] === pathHandle\n ? num(key[2], 'ReferenceIndex rowid')\n : undefined\n }\n\n /** @internal */\n async indexedPosition(\n pathHandle: number,\n pathOffset: number,\n ): Promise<IndexedPosition | undefined> {\n const rowid = await this.indexedRowid(pathHandle, pathOffset)\n return rowid === undefined ? undefined : this.indexedRow(rowid)\n }\n\n /** @internal */\n async indexedPositionsBetween(\n pathHandle: number,\n fromOffset: number,\n toOffset: number,\n ) {\n const [first, last] = await Promise.all([\n this.indexedRowid(pathHandle, fromOffset),\n this.indexedRowid(pathHandle, toOffset),\n ])\n const positions: IndexedPosition[] = []\n if (first !== undefined && last !== undefined) {\n await this.sqlite.prefetchRows('ReferenceIndex', [[first, last + 1]])\n for (let rowid = first; rowid <= last; rowid++) {\n positions.push(await this.indexedRow(rowid))\n }\n }\n return positions\n }\n}\n", "import {\n groupBy\n} from \"./chunk-BSOZW3FC.js\";\n\n// src/gbzJoin.ts\nvar UNKNOWN_SAMPLE = \"unknown\";\nfunction parseWalk(line) {\n const fields = line.split(\"\t\");\n return {\n fields,\n name: fields.slice(1, 4).join(\"\t\"),\n start: +fields[4],\n end: +fields[5]\n };\n}\nvar stepsOf = (walk) => walk.fields[6].match(/[<>][^<>]+/g) ?? [];\nfunction segmentLengths(lines) {\n const lengths = /* @__PURE__ */ new Map();\n for (const line of lines) {\n if (line.startsWith(\"S\t\")) {\n const [, id, sequence, ...tags] = line.split(\"\t\");\n const ln = tags.find((tag) => tag.startsWith(\"LN:i:\"));\n lengths.set(\n id,\n sequence !== \"*\" ? sequence.length : ln ? +ln.slice(\"LN:i:\".length) : 0\n );\n }\n }\n return lengths;\n}\nfunction extend(a, b, lengths) {\n if (b.end <= a.end) {\n return a;\n }\n const steps = stepsOf(b);\n let pos = b.start;\n for (const [i, step] of steps.entries()) {\n if (pos === a.end) {\n const fields = [...a.fields];\n fields[5] = String(b.end);\n fields[6] = a.fields[6] + steps.slice(i).join(\"\");\n return { ...a, fields, end: b.end };\n }\n const length = lengths.get(step.slice(1));\n if (pos > a.end || length === void 0) {\n return void 0;\n }\n pos += length;\n }\n return void 0;\n}\nfunction joinPieces(pieces, lengths, startsPath) {\n const joined = [];\n for (const piece of pieces.sort((a, b) => a.start - b.start)) {\n const last = joined.at(-1);\n const [, sample, haplotype, contig] = piece.fields;\n const joins = last !== void 0 && (piece.start < last.end || piece.start === last.end && !startsPath(sample, +haplotype, contig, piece.start));\n const extended = joins ? extend(last, piece, lengths) : void 0;\n if (extended) {\n joined[joined.length - 1] = extended;\n } else {\n joined.push(piece);\n }\n }\n return joined;\n}\nvar flip = (sign) => sign === \"+\" ? \"-\" : \"+\";\nfunction* stepLinks(walk) {\n const steps = stepsOf(walk).map((step) => ({\n id: step.slice(1),\n sign: step.startsWith(\">\") ? \"+\" : \"-\"\n }));\n for (let i = 1; i < steps.length; i++) {\n const a = steps[i - 1];\n const b = steps[i];\n yield {\n forward: `L\t${a.id}\t${a.sign}\t${b.id}\t${b.sign}\t0M`,\n reverse: `L\t${b.id}\t${flip(b.sign)}\t${a.id}\t${flip(a.sign)}\t0M`\n };\n }\n}\nfunction joinCuts(gfas, startsPath) {\n if (gfas.length <= 1) {\n return gfas[0] ?? \"\";\n }\n const cuts = gfas.map((gfa) => gfa.split(\"\\n\").filter((line) => line !== \"\"));\n const ofType = (cut, type) => cut.filter((line) => line.startsWith(`${type}\t`));\n const lengths = segmentLengths(cuts.flat());\n let unknownOffset = 0;\n const walksByCut = cuts.map((cut) => {\n const walks2 = ofType(cut, \"W\").map(parseWalk);\n const offset = unknownOffset;\n for (const walk of walks2.filter((w) => w.fields[1] === UNKNOWN_SAMPLE)) {\n const haplotype = +walk.fields[2] + offset;\n walk.fields[2] = String(haplotype);\n walk.name = walk.fields.slice(1, 4).join(\"\t\");\n unknownOffset = Math.max(unknownOffset, haplotype);\n }\n return walks2;\n });\n const byName = groupBy(\n [\n ...walksByCut.flatMap((walks2) => walks2.slice(0, 1)),\n ...walksByCut.flatMap((walks2) => walks2.slice(1))\n ],\n (walk) => walk.name\n );\n const walks = [...byName.values()].flatMap(\n (pieces) => joinPieces(pieces, lengths, startsPath)\n );\n const links = new Set(cuts.flatMap((cut) => ofType(cut, \"L\")));\n for (const walk of walks) {\n for (const link of stepLinks(walk)) {\n if (!links.has(link.forward) && !links.has(link.reverse)) {\n links.add(link.forward);\n }\n }\n }\n const lines = /* @__PURE__ */ new Set([\n ...ofType(cuts[0], \"H\"),\n ...cuts.flatMap((cut) => ofType(cut, \"S\")),\n ...links,\n ...walks.map((walk) => walk.fields.join(\"\t\"))\n ]);\n return `${[...lines].join(\"\\n\")}\n`;\n}\n\nexport {\n joinCuts\n};\n", "import {\n joinCuts\n} from \"./chunk-HNWJ4B7S.js\";\nimport {\n wellKnownSample\n} from \"./chunk-234NFZS4.js\";\nimport {\n gfaTables\n} from \"./chunk-DZR37KXT.js\";\nimport {\n panSNMatchesPrefix,\n panSNSample\n} from \"./chunk-4XWZNPQ2.js\";\n\n// src/gbzWindow.ts\nimport { isReverse, nodeId } from \"@gmod/gbz-base\";\nvar NoReferenceSampleError = class extends Error {\n constructor(anchor, referenceSamples) {\n super(\n referenceSamples.length === 0 ? `the graph names no reference sample (gbwt_reference_samples) and the anchor \"${anchor}\" maps to none; set referenceSample` : `the anchor \"${anchor}\" is none of the graph's reference samples (${referenceSamples.join(\", \")}); set referenceSample or map it through assemblyNameToPanSN`\n );\n this.name = \"NoReferenceSampleError\";\n }\n};\nvar NodeLimitError = class extends Error {\n constructor(limit, windowBp, fitsBp) {\n super(\n `this ${windowBp.toLocaleString()} bp window reads more than nodeLimit (${limit.toLocaleString()}) graph nodes; zoom in to about ${fitsBp.toLocaleString()} bp or raise nodeLimit`\n );\n this.fitsBp = fitsBp;\n this.name = \"NodeLimitError\";\n this.regionTooLarge = true;\n }\n};\nfunction haplotypePrefix(name) {\n return `${name.sample}#${name.haplotype}`;\n}\nfunction haplotypeWanted(name, wanted) {\n const prefix = haplotypePrefix(name);\n return wanted === void 0 || wanted.some((candidate) => panSNMatchesPrefix(prefix, candidate));\n}\nasync function referenceSamplesOf(db) {\n return (await db.tag(\"gbwt_reference_samples\") ?? \"\").split(/\\s+/).filter((sample) => sample !== \"\");\n}\nfunction aliasedSample(anchorSample, referenceSamples) {\n const lower = anchorSample.toLowerCase();\n const alias = wellKnownSample(anchorSample)?.toLowerCase();\n return referenceSamples.find((s) => s === anchorSample) ?? referenceSamples.find((s) => s.toLowerCase() === lower) ?? referenceSamples.find((s) => s.toLowerCase() === alias);\n}\nfunction resolveReferenceSample({\n configured,\n anchorPrefix,\n referenceSamples\n}) {\n if (configured !== \"\") {\n return configured;\n }\n const sample = aliasedSample(panSNSample(anchorPrefix), referenceSamples) ?? (referenceSamples.length === 1 ? referenceSamples[0] : void 0);\n if (sample === void 0) {\n throw new NoReferenceSampleError(anchorPrefix, referenceSamples);\n }\n return sample;\n}\nasync function referencePathQuery(db, referenceSample, refName) {\n const path = (await db.paths()).find(\n (p) => p.isIndexed && p.name.sample === referenceSample && p.name.contig === refName\n );\n return path ? {\n sample: path.name.sample,\n contig: refName,\n haplotype: path.name.haplotype\n } : void 0;\n}\nfunction nodeLimitError(error, limit, windowBp) {\n const isLimit = error instanceof Error && (error.name === \"SubgraphLimitError\" || /^Subgraph size limit of \\d+ nodes exceeded/.test(error.message));\n if (!isLimit) {\n return void 0;\n } else {\n const walked = error.walkedBp;\n const fits = typeof walked === \"number\" && walked > 0 ? Math.floor(walked * 0.8) : Math.floor(windowBp / 2);\n return new NodeLimitError(limit, windowBp, Math.max(fits, 1));\n }\n}\nvar GBZ_CUT_DEFAULTS = {\n context: 1e3,\n snarls: \"contained\",\n limit: 1e5\n};\nasync function windowCuts(db, query, start, end, opts) {\n return db.getSubgraphs({ ...opts, path: query, start, end, haplotypes: \"all\" }).catch((error) => {\n throw nodeLimitError(error, opts.limit, end - start) ?? error;\n });\n}\nasync function joinedGFA(db, subgraphs) {\n const paths = await db.paths();\n return joinCuts(\n await Promise.all(subgraphs.map((subgraph) => subgraph.toGFA())),\n (sample, haplotype, contig, at) => paths.some(\n ({ name }) => name.sample === sample && name.haplotype === haplotype && name.contig === contig && name.fragment === at\n )\n );\n}\nasync function cutWindowGFA(db, query, start, end, opts) {\n return query ? joinedGFA(db, await windowCuts(db, query, start, end, opts)) : \"\";\n}\nasync function cutWindowTables(db, query, start, end, opts) {\n if (!query) {\n return \"\";\n }\n const subgraphs = await windowCuts(db, query, start, end, opts);\n if (subgraphs.length === 1) {\n return compactTables(subgraphs[0].toCompactSubgraph());\n }\n const text = await joinedGFA(db, subgraphs);\n return text && gfaTables(text) || text;\n}\nfunction segmentIndex(ids, names) {\n let low = Infinity;\n let high = -Infinity;\n for (const id of ids) {\n low = Math.min(low, id);\n high = Math.max(high, id);\n }\n const span = high - low + 1;\n const table = ids.length > 0 && span <= 16 * ids.length ? new Int32Array(span).fill(-1) : void 0;\n const extra = /* @__PURE__ */ new Map();\n ids.forEach((id, i) => {\n if (table) {\n table[id - low] = i;\n } else {\n extra.set(id, i);\n }\n });\n return (handle) => {\n const id = nodeId(handle);\n const tabled = table !== void 0 && id >= low && id <= high;\n const i = tabled ? table[id - low] : extra.get(id) ?? -1;\n if (i >= 0) {\n return i;\n }\n if (tabled) {\n table[id - low] = names.length;\n } else {\n extra.set(id, names.length);\n }\n names.push(String(id));\n return names.length - 1;\n };\n}\nvar WALK_NAME = /^(.*)\\[(\\d+)-(\\d+)\\]$/;\nfunction compactTables(cut) {\n const names = Array.from(cut.nodeIds, String);\n const indexOf = segmentIndex(cut.nodeIds, names);\n const declared = cut.nodeIds.length;\n const linkCount = cut.edges.length / 2;\n const from = new Int32Array(linkCount);\n const to = new Int32Array(linkCount);\n const strands = new Uint8Array(linkCount);\n for (let k = 0; k < linkCount; k++) {\n const a = cut.edges[2 * k];\n const b = cut.edges[2 * k + 1];\n from[k] = indexOf(a);\n to[k] = indexOf(b);\n strands[k] = (isReverse(a) ? 1 : 0) | (isReverse(b) ? 2 : 0);\n }\n const walks = cut.paths.filter((path) => path.steps.length > 0);\n const offsets = new Int32Array(walks.length + 1);\n walks.forEach((walk, p) => {\n offsets[p + 1] = offsets[p] + walk.steps.length;\n });\n const steps = new Int32Array(offsets[walks.length]);\n const reversed = new Uint8Array(steps.length);\n const starts = new Float64Array(walks.length);\n const ends = new Float64Array(walks.length);\n const walkNames = walks.map((walk, p) => {\n const named = WALK_NAME.exec(walk.name);\n starts[p] = named ? +named[2] : 0;\n ends[p] = named ? +named[3] : -1;\n let at = offsets[p];\n for (const handle of walk.steps) {\n steps[at] = indexOf(handle);\n reversed[at++] = isReverse(handle) ? 1 : 0;\n }\n return named ? named[1] : walk.name;\n });\n return {\n nodes: {\n names,\n lengths: Int32Array.from(cut.nodeSequences, (s) => s.length),\n refs: new Int32Array(declared).fill(-1),\n starts: new Float64Array(declared),\n ranks: new Int32Array(declared),\n refNames: []\n },\n links: { from, to, strands },\n walks: {\n names: walkNames,\n starts,\n ends,\n offsets,\n steps,\n reversed\n }\n };\n}\n\nexport {\n NoReferenceSampleError,\n NodeLimitError,\n haplotypePrefix,\n haplotypeWanted,\n referenceSamplesOf,\n aliasedSample,\n resolveReferenceSample,\n referencePathQuery,\n nodeLimitError,\n GBZ_CUT_DEFAULTS,\n cutWindowGFA,\n cutWindowTables,\n compactTables\n};\n"],
|
|
5
5
|
"mappings": "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",
|
|
6
6
|
"names": ["SCAN_GAP", "handleRuns", "sortedHandles", "runs", "handle", "last", "CHAIN_BOUND", "keepTuning", "PositionIndex", "pos", "id", "offsets", "Fallback", "forwardLeft", "orientation", "left", "currentLen", "nextLen", "backwardLeft", "previousLen", "twinIsCanonical", "piece", "pathEndsAreCanonical", "flipNode", "pieceKey", "findChosenPieces", "input", "db", "records", "signal", "clock", "lap", "now", "elapsed", "stats", "countWalk", "kind", "end", "key", "interval", "outside", "record", "inside", "fetched", "lengthIn", "pathsByHandle", "chosen", "pathHandle", "path", "pieces", "pieceAt", "piecesOfPath", "forwardDone", "backwardDone", "next", "successor", "previous", "within", "predecessor", "offset", "addPiece", "cursors", "source", "handles", "c", "len", "hapStart", "cursor", "ofPath", "pieceThrough", "seed", "before", "after", "pieceAtOrThrough", "lastCursor", "node", "firstCursor", "referenceId", "reference", "result", "byKey", "emitted", "group", "orientations", "chain", "forward", "done", "other", "current", "bp", "known", "strayRoute", "strays", "spacing", "bin", "bound", "fills", "inserted", "fill", "firstBin", "lastBin", "lo", "hi", "anchorOf", "readAnchors", "fromK", "toK", "rows", "row", "lowest", "highest", "listed", "found", "nodeId", "isReverse", "x", "y", "scanning", "first", "multiples", "own", "anchorOffset", "k", "multiplesOf", "anchorNodes", "anchorRows", "visits", "atAnchors", "i", "ks", "plans", "prefetchLo", "prefetchHi", "list", "from", "to", "low", "high", "a", "b", "filled", "cap", "counted", "walkBp", "walkedRanges", "covered", "markWalked", "walkForward", "start", "startLeft", "until", "reached", "walkBackward", "earlier", "earlierLeft", "stop", "reachedEnd", "reachedStart", "reversed", "samples", "sample", "canonicalTwins", "orientationsOf", "note", "seen", "noted", "noteNew", "hasTwin", "twinBound", "needsTwin", "walkedBp", "hit", "flipped", "s", "walk", "toPiece", "landed", "landedId", "error", "extractionOrder", "K", "rotr", "x", "n", "sha256", "bytes", "blocks", "padded", "view", "bits", "h", "w", "block", "t", "a", "b", "s0", "s1", "c", "d", "e", "f", "g", "hh", "ch", "t1", "maj", "value", "i", "out", "outView", "parseRelationships", "field", "what", "relationships", "rel", "parts", "from", "to", "targets", "graphNameFromTags", "tags", "merge", "into", "key", "values", "value", "subgraphName", "name", "parent", "result", "sortedEntries", "a", "b", "tos", "gfaHeaderLines", "graphName", "lines", "subgraph", "supergraph", "sha256Hex", "chunks", "total", "sum", "chunk", "bytes", "offset", "subtle", "sha256", "byte", "GENERIC_SAMPLE", "formatPathName", "name", "base", "PAN_SN", "BARE_CONTIG", "parsePathName", "panSn", "bare", "toPathQuery", "ref", "pathNameFor", "query", "fragment", "SubgraphLimitError", "limit", "walk", "sideBefore", "b", "SideQueue", "distance", "node", "side", "heap", "i", "parent", "top", "last", "left", "right", "smallest", "asMatches", "pairs", "pathAt", "refAt", "a", "firstAbove", "ascending", "bound", "lo", "hi", "mid", "posKey", "pos", "flipPath", "path", "handle", "flipNode", "joinable", "insertion", "deletion", "joinPair", "gap", "edits", "op", "len", "appendGap", "appendEdit", "walkForward", "first", "second", "joinSiblings", "fragments", "mostlyAligned", "alignJointly", "f", "byPath", "fragment", "index", "siblings", "joined", "consumed", "x", "y", "head", "current", "between", "next", "joint", "pathPosition", "info", "k", "PREFETCH_RUN_GAP", "rowidRuns", "handles", "sorted", "runs", "Subgraph", "_Subgraph", "db", "opts", "id", "encodeNode", "record", "forward", "reverse", "query", "formatPathName", "queryOffset", "indexed", "startOffset", "start", "pathOffset", "nodeId", "nodeOffset", "context", "orientation", "nodeOrientation", "active", "entrySide", "exitSide", "reference", "pathHandle", "fromOffset", "toOffset", "positions", "p", "error", "offset", "remaining", "distanceToNext", "nodes", "visited", "toRemove", "inserted", "key", "otherSide", "flipSide", "entryOrientation", "nextDistance", "exitOrientation", "successor", "successorId", "successorSide", "end", "curr", "snarls", "total", "result", "foundLink", "edgeIsCanonical", "covering", "successors", "onFetch", "outside", "inside", "read", "isSnarlEntry", "classify", "queue", "done", "type", "output", "refPos", "count", "indexOf", "rowStart", "seqLen", "rows", "row", "nextIndex", "nextOffset", "hasPredecessor", "j", "refIndex", "refGbwtOffset", "refOffset", "offsets", "steps", "cur", "off", "at", "keep", "twinsExpected", "isReverse", "from", "degree", "lastHandle", "pathEndsAreCanonical", "twinRecord", "startCount", "allTwins", "bare", "refInfo", "before", "deferTwins", "refPath", "referenceTwin", "pathIsCanonical", "deferred", "comparePaths", "defer", "merged", "refId", "apart", "interval", "span", "identity", "kept", "wanted", "unnamed", "found", "findChosenPieces", "pathsByHandle", "infoOf", "piece", "ordered", "extractionOrder", "handleRuns", "samples", "fetched", "sample", "scanned", "run", "starts", "identification", "readRecord", "recordAt", "sampleAt", "chain", "names", "nameOf", "name", "anchorFromSample", "counter", "nodeLen", "anchorFromIdentity", "startInfo", "anchor", "bp", "position", "known", "startBp", "ref", "occurrences", "prefix", "pi", "ri", "pb", "rb", "pathLen", "refLen", "suffix", "weight", "lcs", "weightedLcs", "refPrefix", "alignGap", "pathFrom", "pathTo", "refFrom", "refTo", "matched", "m", "nextPath", "nextRef", "pathIndex", "flippedPath", "forwardBound", "flipped", "refTotal", "strand", "pieces", "soloAligned", "trimmed", "trimEnds", "low", "high", "aligned", "sum", "bases", "length", "parts", "part", "inWalkOrder", "infos", "gaps", "alignedInfos", "alignedGaps", "keptInOrder", "alignedIn", "keeps", "insertions", "walked", "spliceInsertions", "alongReference", "rest", "cigarOf", "target", "pairOptions", "walks", "haplotypeOrderedPath", "haplotype", "isTarget", "isQuery", "sequenceOf", "targetWalk", "queryWalk", "pairAlignments", "pairCigar", "edges", "edge", "encoder", "chunks", "text", "fromReverse", "toId", "toReverse", "sha256Hex", "cigar", "lines", "gfaHeaderLines", "subgraphName", "sign", "cigarString", "cg", "contig", "resolved", "entries", "to", "paths", "entry", "jsonPath", "nodeIds", "nodeSequences", "edgeHandles", "haplotypeOrderedPath", "info", "identity", "handle", "flipNode", "jsonPath", "name", "cigar", "nodeId", "isReverse", "comparePaths", "b", "n", "i", "x", "y", "appendEdit", "edits", "op", "len", "last", "gapPenalty", "appendGap", "pathMiddle", "refMiddle", "mismatch", "mismatchIndel", "insertionDeletion", "trimEnds", "first", "inserted", "trailing", "sum", "ends", "run", "head", "tail", "trimmed", "alignedIn", "lengths", "aligned", "piece", "pieceEnd", "walked", "rest", "step", "spliceInsertions", "insertions", "spliced", "next", "from", "at", "cigarOf", "ByteCodeReader", "bytes", "value", "shift", "result", "RLE_THRESHOLD", "RLE_UNIVERSE", "RunReader", "sigma", "len", "byte", "extra", "run", "decompressEdges", "bytes", "reader", "ByteCodeReader", "sigma", "edges", "prev", "i", "delta", "offset", "GbwtRecord", "bwt", "RunReader", "rank", "edge", "offsets", "e", "run", "soFar", "node", "low", "high", "mid", "pos", "succRank", "counts", "flipNode", "entry", "curr", "nodeId", "total", "nodes", "nextOffsets", "k", "result", "wholeNumber", "name", "value", "min", "contextOf", "opts", "createSubgraph", "db", "Subgraph", "subgraphAtOffset", "context", "subgraph", "reference", "pathNameFor", "toPathQuery", "aroundWindow", "start", "end", "error", "SubgraphLimitError", "subgraphInInterval", "keep", "haplotypes", "named", "subgraphAroundNodes", "snarls", "id", "subgraphBetween", "readVarint", "bytes", "offset", "value", "i", "byte", "last", "readSignedInt", "view", "width", "big", "decoder", "decodeRecord", "payload", "headerSize", "firstType", "types", "type", "next", "body", "length", "slice", "INTERIOR_INDEX", "INTERIOR_TABLE", "LEAF_INDEX", "LEAF_TABLE", "readUint16", "page", "offset", "readUint32", "readHeader", "start", "type", "interior", "cellOffset", "header", "index", "MAX_DECODED_INDEX_PAGES", "BTree", "pager", "reservedBytes", "total", "isIndex", "usable", "maxLocal", "minLocal", "spill", "local", "result", "filled", "next", "overflow", "chunk", "pageNumber", "root", "towards", "depth", "level", "child", "rowid", "low", "high", "mid", "key", "readVarint", "ranges", "stream", "leafLevel", "frontiers", "pages", "r", "lo", "hi", "decoded", "n", "children", "i", "from", "to", "c", "size", "afterSize", "afterKey", "decodeRecord", "cells", "oldest", "cell", "inclusive", "order", "compareKey", "first", "past", "best", "values", "a", "b", "checkPagerOptions", "blockSize", "maxBlocks", "Pager", "source", "pageSize", "fileSize", "opts", "requested", "length", "start", "bytes", "attempt", "error", "resolve", "index", "cached", "pending", "pageNumber", "pageNumbers", "indexes", "blocks", "position", "count", "plan", "slice", "at", "wanted", "a", "b", "runStart", "runEnd", "firstIndex", "i", "within", "block", "oldest", "offset", "SqliteDatabase", "_SqliteDatabase", "pager", "btree", "objects", "source", "opts", "checkPagerOptions", "firstBlock", "header", "view", "rawPageSize", "pageSize", "reserved", "encoding", "pageCount", "size", "Pager", "BTree", "values", "type", "name", "tableName", "rootPage", "sql", "object", "table", "index", "o", "rowid", "ranges", "stream", "key", "low", "high", "SCHEMA_VERSION", "UnknownPathError", "path", "formatPathName", "ForwardOnlyIndexError", "SchemaVersionError", "found", "concatBytes", "parts", "whole", "p", "at", "part", "INDEX_FORMAT", "Varints", "bytes", "value", "scale", "byte", "decodeRuns", "runs", "reader", "previous", "start", "runTester", "x", "y", "starts", "ends", "end", "last", "id", "lo", "hi", "mid", "decodeStrays", "bin", "rows", "pathHandle", "pathStart", "pathEnd", "low", "high", "decodeVisits", "anchorNode", "visits", "nodeId", "pathAndBit", "bit", "GbzRecord", "handle", "edges", "bwt", "encodedSequence", "next", "encodedSequenceLength", "nodeOrientation", "decodeSequence", "GbwtRecord", "num", "what", "str", "blob", "rowToPath", "rowid", "values", "forgetOnRejection", "pending", "forget", "readTags", "sqlite", "tags", "GBZBase", "_GBZBase", "index", "opts", "source", "haplotypeIndex", "pagerOptions", "SqliteDatabase", "version", "SCHEMA_VERSION", "SchemaVersionError", "table", "db", "indexed", "paths", "indexedNodes", "nodes", "ForwardOnlyIndexError", "format", "key", "ranges", "stream", "row", "decompressEdges", "path", "name", "a", "b", "ref", "pathNameFor", "toPathQuery", "length", "formatPathName", "pos", "record", "ordered", "UnknownPathError", "covering", "within", "f", "fragment", "sample", "contig", "haplotype", "haplotypes", "subgraph", "subgraphInInterval", "error", "SubgraphLimitError", "fragments", "result", "subgraphAtOffset", "subgraphAroundNodes", "subgraphBetween", "stats", "pager", "gbzTags", "graphNameFromTags", "links", "interval", "reference", "tag", "snarls", "rowids", "referenceHandle", "firstBin", "lastBin", "strays", "lowOffset", "highOffset", "flush", "anchorOffset", "minHandle", "maxHandle", "samples", "node", "offset", "level", "firstChunk", "lastChunk", "chunk", "list", "signal", "baseBin", "chunkBins", "levels", "bytesPerBin", "bins", "cellRows", "from", "to", "summaries", "cells", "packed", "pathOffset", "fromOffset", "toOffset", "first", "positions", "UNKNOWN_SAMPLE", "parseWalk", "line", "fields", "stepsOf", "walk", "segmentLengths", "lines", "lengths", "id", "sequence", "tags", "ln", "tag", "extend", "b", "steps", "pos", "i", "step", "length", "joinPieces", "pieces", "startsPath", "joined", "piece", "a", "last", "sample", "haplotype", "contig", "extended", "flip", "sign", "stepLinks", "joinCuts", "gfas", "cuts", "gfa", "ofType", "cut", "type", "unknownOffset", "walksByCut", "walks2", "offset", "w", "walks", "groupBy", "links", "link", "NoReferenceSampleError", "anchor", "referenceSamples", "NodeLimitError", "limit", "windowBp", "fitsBp", "haplotypePrefix", "name", "haplotypeWanted", "wanted", "prefix", "candidate", "panSNMatchesPrefix", "referenceSamplesOf", "db", "sample", "aliasedSample", "anchorSample", "lower", "alias", "wellKnownSample", "resolveReferenceSample", "configured", "anchorPrefix", "panSNSample", "referencePathQuery", "referenceSample", "refName", "path", "p", "nodeLimitError", "error", "walked", "fits", "GBZ_CUT_DEFAULTS", "windowCuts", "query", "start", "end", "opts", "joinedGFA", "subgraphs", "paths", "joinCuts", "subgraph", "haplotype", "contig", "at", "cutWindowTables", "db", "query", "start", "end", "opts", "subgraphs", "windowCuts", "compactTables", "text", "joinedGFA", "gfaTables", "segmentIndex", "ids", "names", "low", "high", "id", "span", "table", "extra", "i", "handle", "nodeId", "tabled", "WALK_NAME", "cut", "indexOf", "declared", "linkCount", "from", "to", "strands", "k", "a", "b", "isReverse", "walks", "path", "offsets", "walk", "p", "steps", "reversed", "starts", "ends", "walkNames", "named", "at", "s"]
|