jbrowse-plugin-graphgenomeviewer 4.8.0 → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -0
- package/dist/chunks/GbzBaseSyntenyAdapter-CKKVHC2R.js +4 -0
- package/dist/chunks/GbzBaseSyntenyAdapter-CKKVHC2R.js.map +7 -0
- package/dist/chunks/LinearGraphDisplay-7YE624D5.js +2 -0
- package/dist/chunks/LinearGraphDisplay-7YE624D5.js.map +7 -0
- package/dist/chunks/chunk-2H7GDQ3R.js +6 -0
- package/dist/chunks/chunk-2H7GDQ3R.js.map +7 -0
- package/dist/chunks/chunk-BZOIENU5.js +2 -0
- package/dist/chunks/chunk-BZOIENU5.js.map +7 -0
- package/dist/jbrowse-plugin-graphgenomeviewer.esm.js +5 -5
- package/dist/jbrowse-plugin-graphgenomeviewer.esm.js.map +4 -4
- package/package.json +3 -3
- package/src/GbzBaseSyntenyAdapter/GbzBaseSyntenyAdapter.test.ts +36 -2
- package/src/GbzBaseSyntenyAdapter/GbzBaseSyntenyAdapter.ts +67 -1
- package/src/GbzBaseSyntenyAdapter/test_data/fragmented.haplotype-index.db +0 -0
- package/src/GbzBaseSyntenyAdapter/test_data/micb-kir3dl1.haplotype-index.db +0 -0
- package/src/GbzBaseSyntenyAdapter/test_data/micb-kir3dl1.sampled.haplotype-index.db +0 -0
- package/src/GetHaplotypeOverview.ts +77 -0
- package/src/GraphGenomeView/host.ts +6 -0
- package/src/HaplotypeOverview/HaplotypeOverviewCanvas.tsx +203 -0
- package/src/HaplotypeOverview/draw.test.ts +136 -0
- package/src/HaplotypeOverview/draw.ts +433 -0
- package/src/HaplotypeOverview/model.ts +163 -0
- package/src/LinearGraphDisplay/LinearGraphDisplay.test.ts +184 -0
- package/src/LinearGraphDisplay/components/LinearGraphDisplay.tsx +12 -2
- package/src/LinearGraphDisplay/model.ts +107 -3
- package/src/index.ts +2 -0
- package/src/version.ts +1 -1
- package/dist/chunks/GbzBaseSyntenyAdapter-VOGKGHQ6.js +0 -8
- package/dist/chunks/GbzBaseSyntenyAdapter-VOGKGHQ6.js.map +0 -7
- package/dist/chunks/LinearGraphDisplay-4HYL7PDU.js +0 -2
- package/dist/chunks/LinearGraphDisplay-4HYL7PDU.js.map +0 -7
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{b as S,g as N,h as X,i as E,j as Y,k as A,m as k,n as W,o as J}from"./chunk-BZOIENU5.js";import"./chunk-2H7GDQ3R.js";import{a as B}from"./chunk-WKVVIDCS.js";import"./chunk-SJNG2XK7.js";import"./chunk-O4XV3K35.js";import"./chunk-H54W6OQQ.js";import"./chunk-UQEPPJEO.js";import"./chunk-SCMIJAAX.js";import"./chunk-7BKUWQE5.js";import"./chunk-KULNKXPT.js";import"./chunk-FCWXYIFC.js";import{a as Q}from"./chunk-J6KYLXRD.js";import{a as O,c as G}from"./chunk-TYJTJGPO.js";import{a as R,b as a}from"./chunk-FY3BTKY4.js";var I=R((ee,F)=>{F.exports=JBrowseExports["@jbrowse/display-kit/DisplayChrome"]});var _=R((te,V)=>{V.exports=JBrowseExports["@jbrowse/core/ui/BaseTooltip"]});var z=a(I(),1),K=a(G(),1);var s=a(Q(),1),j=a(_(),1),L=a(G(),1);var n=a(O(),1),U=(0,L.observer)(function({data:e,region:y,pointer:o}){let c=k(e,o.bin),t=o.row===void 0?void 0:e.cells[o.bin*e.rows.length+o.row];return(0,n.jsxs)(j.default,{clientPoint:{x:o.clientX,y:o.clientY},children:[(0,n.jsxs)("div",{children:[y.refName,":",c.span]}),o.row!==void 0&&t!==void 0?(0,n.jsxs)("div",{children:[(0,n.jsx)("strong",{children:e.rows[o.row]}),": ",X(t)]}):(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)("div",{children:c.classes}),(0,n.jsx)("div",{children:c.excursions})]}),(0,n.jsx)("div",{style:{opacity:.7},children:N})]})}),Z=(0,L.observer)(function({model:e}){let y=(0,s.useRef)(null),[o,c]=(0,s.useState)(),{overview:t,overviewRegion:u,overviewCounts:M,overviewAllRows:T,height:l,host:w}=e,m=w?.width??0,x=w&&u?S(w,u):void 0,f=x?.scale,h=x?.translateX,d=(0,s.useMemo)(()=>t?E(t,T,l):void 0,[t,T,l]),v=typeof window>"u"?1:window.devicePixelRatio||1,D=(0,s.useMemo)(()=>t&&d?W(t,d,v):[],[t,d,v]);(0,s.useEffect)(()=>{let i=y.current,r=i?.getContext("2d");if(!i||!r||!t||!d||f===void 0||h===void 0)return;let p=Math.round(m*v),g=Math.round(l*v);(i.width!==p||i.height!==g)&&(i.width=p,i.height=g),r.setTransform(v,0,0,v,0,0),J(r,t,M,d,D,{xOf:b=>b*f+h,width:m,height:l,dpr:v}),e.setOverviewPainted(t)},[e,t,M,d,D,f,h,m,l,v]);let P=i=>{if(!t||!d||!f||h===void 0)return;let r=i.currentTarget.getBoundingClientRect(),p=i.clientX-r.left,g=i.clientY-r.top,b=A(t,(p-h)/f);return b===void 0?void 0:{bin:b,row:Y(d,g),clientX:i.clientX,clientY:i.clientY}};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)("canvas",{ref:y,"data-testid":"haplotype-overview",style:{width:m,height:l,display:"block",cursor:"pointer"},onMouseMove:i=>{c(P(i))},onMouseLeave:()=>{c(void 0)},onClick:i=>{let r=P(i),p=r&&t?.bins[r.bin];p&&u&&w?.navTo&&w.navTo({refName:u.refName,assemblyName:u.assemblyName,start:p.start,end:p.end})}}),o&&t&&u?(0,n.jsx)(U,{data:t,region:u,pointer:o}):null]})}),q=Z;var C=a(O(),1),$=(0,K.observer)(function({model:e}){return(0,C.jsx)(z.DisplayStatusChrome,{model:e,phase:e.displayPhase,drawn:e.showsOverview?e.overview!==void 0&&e.overviewPainted===e.overview:e.painted&&e.geometryPainted,testid:"linear-graph-display","data-layout":e.chosenLayoutMode,"data-cut-tier":e.cutTier,"data-recuts":e.recuts,"data-node-count":e.hasGraph?e.nodeCount:void 0,"data-loading":e.isLoading?"":void 0,style:{width:e.paneWidth,height:e.height,overflow:"hidden"},children:e.showsOverview?(0,C.jsx)(q,{model:e}):(0,C.jsx)(B,{model:e,ownChrome:!1})})}),se=$;export{se as default};
|
|
2
|
+
//# sourceMappingURL=LinearGraphDisplay-7YE624D5.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["global-externals:@jbrowse/display-kit/DisplayChrome", "global-externals:@jbrowse/core/ui/BaseTooltip", "../../src/LinearGraphDisplay/components/LinearGraphDisplay.tsx", "../../src/HaplotypeOverview/HaplotypeOverviewCanvas.tsx"],
|
|
4
|
+
"sourcesContent": ["module.exports = JBrowseExports[\"@jbrowse/display-kit/DisplayChrome\"];", "module.exports = JBrowseExports[\"@jbrowse/core/ui/BaseTooltip\"];", "import { DisplayStatusChrome } from '@jbrowse/display-kit/DisplayChrome'\nimport { observer } from 'mobx-react'\n\nimport GraphCanvas from '../../GraphGenomeView/components/GraphCanvas'\nimport HaplotypeOverviewCanvas from '../../HaplotypeOverview/HaplotypeOverviewCanvas'\n\nimport type { LinearGraphDisplayModel } from '../model'\n\nconst LinearGraphDisplay = observer(function LinearGraphDisplay({\n model,\n}: {\n model: LinearGraphDisplayModel\n}) {\n return (\n <DisplayStatusChrome\n model={model}\n phase={model.displayPhase}\n drawn={\n model.showsOverview\n ? model.overview !== undefined &&\n model.overviewPainted === model.overview\n : model.painted && model.geometryPainted\n }\n testid=\"linear-graph-display\"\n data-layout={model.chosenLayoutMode}\n data-cut-tier={model.cutTier}\n data-recuts={model.recuts}\n data-node-count={model.hasGraph ? model.nodeCount : undefined}\n data-loading={model.isLoading ? '' : undefined}\n style={{\n width: model.paneWidth,\n height: model.height,\n overflow: 'hidden',\n }}\n >\n {model.showsOverview ? (\n <HaplotypeOverviewCanvas model={model} />\n ) : (\n <GraphCanvas model={model} ownChrome={false} />\n )}\n </DisplayStatusChrome>\n )\n})\n\nexport default LinearGraphDisplay\n", "import { useEffect, useMemo, useRef, useState } from 'react'\n\nimport BaseTooltip from '@jbrowse/core/ui/BaseTooltip'\nimport { observer } from 'mobx-react'\n\nimport {\n NOT_SHOWN,\n binAt,\n cellLabel,\n describeBin,\n drawOverview,\n overviewLayout,\n rowAt,\n rowImages,\n} from './draw'\nimport { hostFrame } from '../GraphGenomeView/host'\n\nimport type { OverviewLayout } from './draw'\nimport type { HaplotypeOverviewData } from '../GetHaplotypeOverview'\nimport type { SubgraphRegion } from '../GetSubgraph'\nimport type { LinearHost } from '../GraphGenomeView/host'\n\nexport interface OverviewCanvasModel {\n overview: HaplotypeOverviewData | undefined\n overviewRegion: SubgraphRegion | undefined\n overviewCounts: number[][] | undefined\n overviewAllRows: boolean\n height: number\n host: LinearHost | undefined\n setOverviewPainted: (data: HaplotypeOverviewData) => void\n}\n\ninterface Pointer {\n bin: number\n row: number | undefined\n clientX: number\n clientY: number\n}\n\nconst OverviewTooltip = observer(function OverviewTooltip({\n data,\n region,\n pointer,\n}: {\n data: HaplotypeOverviewData\n region: SubgraphRegion\n pointer: Pointer\n}) {\n const bin = describeBin(data, pointer.bin)\n const cell =\n pointer.row === undefined\n ? undefined\n : data.cells[pointer.bin * data.rows.length + pointer.row]\n return (\n <BaseTooltip clientPoint={{ x: pointer.clientX, y: pointer.clientY }}>\n <div>\n {region.refName}:{bin.span}\n </div>\n {pointer.row !== undefined && cell !== undefined ? (\n <div>\n <strong>{data.rows[pointer.row]}</strong>: {cellLabel(cell)}\n </div>\n ) : (\n <>\n <div>{bin.classes}</div>\n <div>{bin.excursions}</div>\n </>\n )}\n <div style={{ opacity: 0.7 }}>{NOT_SHOWN}</div>\n </BaseTooltip>\n )\n})\n\n// The haplotype index's overview on the linear view's axis: a density row of\n// the haplotypes that differ from the reference, then a row per haplotype.\n// A click zooms to the bin under the pointer.\nconst HaplotypeOverviewCanvas = observer(function HaplotypeOverviewCanvas({\n model,\n}: {\n model: OverviewCanvasModel\n}) {\n const ref = useRef<HTMLCanvasElement>(null)\n const [pointer, setPointer] = useState<Pointer>()\n const {\n overview,\n overviewRegion,\n overviewCounts,\n overviewAllRows,\n height,\n host,\n } = model\n const width = host?.width ?? 0\n const frame =\n host && overviewRegion ? hostFrame(host, overviewRegion) : undefined\n const scale = frame?.scale\n const translateX = frame?.translateX\n const layout = useMemo<OverviewLayout | undefined>(\n () =>\n overview ? overviewLayout(overview, overviewAllRows, height) : undefined,\n [overview, overviewAllRows, height],\n )\n\n const dpr = typeof window === 'undefined' ? 1 : window.devicePixelRatio || 1\n const images = useMemo(\n () => (overview && layout ? rowImages(overview, layout, dpr) : []),\n [overview, layout, dpr],\n )\n\n useEffect(() => {\n const canvas = ref.current\n const ctx = canvas?.getContext('2d')\n if (\n !canvas ||\n !ctx ||\n !overview ||\n !layout ||\n scale === undefined ||\n translateX === undefined\n ) {\n return\n }\n const deviceWidth = Math.round(width * dpr)\n const deviceHeight = Math.round(height * dpr)\n if (canvas.width !== deviceWidth || canvas.height !== deviceHeight) {\n canvas.width = deviceWidth\n canvas.height = deviceHeight\n }\n ctx.setTransform(dpr, 0, 0, dpr, 0, 0)\n drawOverview(ctx, overview, overviewCounts, layout, images, {\n xOf: bp => bp * scale + translateX,\n width,\n height,\n dpr,\n })\n model.setOverviewPainted(overview)\n }, [\n model,\n overview,\n overviewCounts,\n layout,\n images,\n scale,\n translateX,\n width,\n height,\n dpr,\n ])\n\n const locate = (event: React.MouseEvent<HTMLCanvasElement>) => {\n if (!overview || !layout || !scale || translateX === undefined) {\n return undefined\n }\n const rect = event.currentTarget.getBoundingClientRect()\n const x = event.clientX - rect.left\n const y = event.clientY - rect.top\n const bin = binAt(overview, (x - translateX) / scale)\n return bin === undefined\n ? undefined\n : {\n bin,\n row: rowAt(layout, y),\n clientX: event.clientX,\n clientY: event.clientY,\n }\n }\n\n return (\n <>\n <canvas\n ref={ref}\n data-testid=\"haplotype-overview\"\n style={{ width, height, display: 'block', cursor: 'pointer' }}\n onMouseMove={event => {\n setPointer(locate(event))\n }}\n onMouseLeave={() => {\n setPointer(undefined)\n }}\n onClick={event => {\n const at = locate(event)\n const bin = at && overview?.bins[at.bin]\n if (bin && overviewRegion && host?.navTo) {\n host.navTo({\n refName: overviewRegion.refName,\n assemblyName: overviewRegion.assemblyName,\n start: bin.start,\n end: bin.end,\n })\n }\n }}\n />\n {pointer && overview && overviewRegion ? (\n <OverviewTooltip\n data={overview}\n region={overviewRegion}\n pointer={pointer}\n />\n ) : null}\n </>\n )\n})\n\nexport default HaplotypeOverviewCanvas\n"],
|
|
5
|
+
"mappings": "0gBAAA,IAAAA,EAAAC,EAAA,CAAAC,GAAAC,IAAA,CAAAA,EAAO,QAAU,eAAe,oCAAoC,ICApE,IAAAC,EAAAC,EAAA,CAAAC,GAAAC,IAAA,CAAAA,EAAO,QAAU,eAAe,8BAA8B,ICA9D,IAAAC,EAAoC,SACpCC,EAAyB,SCDzB,IAAAC,EAAqD,SAErDC,EAAwB,SACxBC,EAAyB,SAoDnB,IAAAC,EAAA,SAhBAC,KAAkB,YAAS,SAAyB,CACxD,KAAAC,EACA,OAAAC,EACA,QAAAC,CACF,EAIG,CACD,IAAMC,EAAMC,EAAYJ,EAAME,EAAQ,GAAG,EACnCG,EACJH,EAAQ,MAAQ,OACZ,OACAF,EAAK,MAAME,EAAQ,IAAMF,EAAK,KAAK,OAASE,EAAQ,GAAG,EAC7D,SACE,QAAC,EAAAI,QAAA,CAAY,YAAa,CAAE,EAAGJ,EAAQ,QAAS,EAAGA,EAAQ,OAAQ,EACjE,qBAAC,OACE,UAAAD,EAAO,QAAQ,IAAEE,EAAI,MACxB,EACCD,EAAQ,MAAQ,QAAaG,IAAS,UACrC,QAAC,OACC,oBAAC,UAAQ,SAAAL,EAAK,KAAKE,EAAQ,GAAG,EAAE,EAAS,KAAGK,EAAUF,CAAI,GAC5D,KAEA,oBACE,oBAAC,OAAK,SAAAF,EAAI,QAAQ,KAClB,OAAC,OAAK,SAAAA,EAAI,WAAW,GACvB,KAEF,OAAC,OAAI,MAAO,CAAE,QAAS,EAAI,EAAI,SAAAK,EAAU,GAC3C,CAEJ,CAAC,EAKKC,KAA0B,YAAS,SAAiC,CACxE,MAAAC,CACF,EAEG,CACD,IAAMC,KAAM,UAA0B,IAAI,EACpC,CAACT,EAASU,CAAU,KAAI,YAAkB,EAC1C,CACJ,SAAAC,EACA,eAAAC,EACA,eAAAC,EACA,gBAAAC,EACA,OAAAC,EACA,KAAAC,CACF,EAAIR,EACES,EAAQD,GAAM,OAAS,EACvBE,EACJF,GAAQJ,EAAiBO,EAAUH,EAAMJ,CAAc,EAAI,OACvDQ,EAAQF,GAAO,MACfG,EAAaH,GAAO,WACpBI,KAAS,WACb,IACEX,EAAWY,EAAeZ,EAAUG,EAAiBC,CAAM,EAAI,OACjE,CAACJ,EAAUG,EAAiBC,CAAM,CACpC,EAEMS,EAAM,OAAO,OAAW,IAAc,EAAI,OAAO,kBAAoB,EACrEC,KAAS,WACb,IAAOd,GAAYW,EAASI,EAAUf,EAAUW,EAAQE,CAAG,EAAI,CAAC,EAChE,CAACb,EAAUW,EAAQE,CAAG,CACxB,KAEA,aAAU,IAAM,CACd,IAAMG,EAASlB,EAAI,QACbmB,EAAMD,GAAQ,WAAW,IAAI,EACnC,GACE,CAACA,GACD,CAACC,GACD,CAACjB,GACD,CAACW,GACDF,IAAU,QACVC,IAAe,OAEf,OAEF,IAAMQ,EAAc,KAAK,MAAMZ,EAAQO,CAAG,EACpCM,EAAe,KAAK,MAAMf,EAASS,CAAG,GACxCG,EAAO,QAAUE,GAAeF,EAAO,SAAWG,KACpDH,EAAO,MAAQE,EACfF,EAAO,OAASG,GAElBF,EAAI,aAAaJ,EAAK,EAAG,EAAGA,EAAK,EAAG,CAAC,EACrCO,EAAaH,EAAKjB,EAAUE,EAAgBS,EAAQG,EAAQ,CAC1D,IAAKO,GAAMA,EAAKZ,EAAQC,EACxB,MAAAJ,EACA,OAAAF,EACA,IAAAS,CACF,CAAC,EACDhB,EAAM,mBAAmBG,CAAQ,CACnC,EAAG,CACDH,EACAG,EACAE,EACAS,EACAG,EACAL,EACAC,EACAJ,EACAF,EACAS,CACF,CAAC,EAED,IAAMS,EAAUC,GAA+C,CAC7D,GAAI,CAACvB,GAAY,CAACW,GAAU,CAACF,GAASC,IAAe,OACnD,OAEF,IAAMc,EAAOD,EAAM,cAAc,sBAAsB,EACjDE,EAAIF,EAAM,QAAUC,EAAK,KACzBE,EAAIH,EAAM,QAAUC,EAAK,IACzBlC,EAAMqC,EAAM3B,GAAWyB,EAAIf,GAAcD,CAAK,EACpD,OAAOnB,IAAQ,OACX,OACA,CACE,IAAAA,EACA,IAAKsC,EAAMjB,EAAQe,CAAC,EACpB,QAASH,EAAM,QACf,QAASA,EAAM,OACjB,CACN,EAEA,SACE,oBACE,oBAAC,UACC,IAAKzB,EACL,cAAY,qBACZ,MAAO,CAAE,MAAAQ,EAAO,OAAAF,EAAQ,QAAS,QAAS,OAAQ,SAAU,EAC5D,YAAamB,GAAS,CACpBxB,EAAWuB,EAAOC,CAAK,CAAC,CAC1B,EACA,aAAc,IAAM,CAClBxB,EAAW,MAAS,CACtB,EACA,QAASwB,GAAS,CAChB,IAAMM,EAAKP,EAAOC,CAAK,EACjBjC,EAAMuC,GAAM7B,GAAU,KAAK6B,EAAG,GAAG,EACnCvC,GAAOW,GAAkBI,GAAM,OACjCA,EAAK,MAAM,CACT,QAASJ,EAAe,QACxB,aAAcA,EAAe,aAC7B,MAAOX,EAAI,MACX,IAAKA,EAAI,GACX,CAAC,CAEL,EACF,EACCD,GAAWW,GAAYC,KACtB,OAACf,EAAA,CACC,KAAMc,EACN,OAAQC,EACR,QAASZ,EACX,EACE,MACN,CAEJ,CAAC,EAEMyC,EAAQlC,EDtKP,IAAAmC,EAAA,SA5BFC,KAAqB,YAAS,SAA4B,CAC9D,MAAAC,CACF,EAEG,CACD,SACE,OAAC,uBACC,MAAOA,EACP,MAAOA,EAAM,aACb,MACEA,EAAM,cACFA,EAAM,WAAa,QACnBA,EAAM,kBAAoBA,EAAM,SAChCA,EAAM,SAAWA,EAAM,gBAE7B,OAAO,uBACP,cAAaA,EAAM,iBACnB,gBAAeA,EAAM,QACrB,cAAaA,EAAM,OACnB,kBAAiBA,EAAM,SAAWA,EAAM,UAAY,OACpD,eAAcA,EAAM,UAAY,GAAK,OACrC,MAAO,CACL,MAAOA,EAAM,UACb,OAAQA,EAAM,OACd,SAAU,QACZ,EAEC,SAAAA,EAAM,iBACL,OAACC,EAAA,CAAwB,MAAOD,EAAO,KAEvC,OAACE,EAAA,CAAY,MAAOF,EAAO,UAAW,GAAO,EAEjD,CAEJ,CAAC,EAEMG,GAAQJ",
|
|
6
|
+
"names": ["require_DisplayChrome", "__commonJSMin", "exports", "module", "require_BaseTooltip", "__commonJSMin", "exports", "module", "import_DisplayChrome", "import_mobx_react", "import_react", "import_BaseTooltip", "import_mobx_react", "import_jsx_runtime", "OverviewTooltip", "data", "region", "pointer", "bin", "describeBin", "cell", "BaseTooltip", "cellLabel", "NOT_SHOWN", "HaplotypeOverviewCanvas", "model", "ref", "setPointer", "overview", "overviewRegion", "overviewCounts", "overviewAllRows", "height", "host", "width", "frame", "hostFrame", "scale", "translateX", "layout", "overviewLayout", "dpr", "images", "rowImages", "canvas", "ctx", "deviceWidth", "deviceHeight", "drawOverview", "bp", "locate", "event", "rect", "x", "y", "binAt", "rowAt", "at", "HaplotypeOverviewCanvas_default", "import_jsx_runtime", "LinearGraphDisplay", "model", "HaplotypeOverviewCanvas_default", "GraphCanvas_default", "LinearGraphDisplay_default"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
function ue(i,e){return 2*i+(e==="reverse"?1:0)}function R(i){return Math.floor(i/2)}function Ne(i){return i%2===0?"forward":"reverse"}function z(i){return i%2===1}function ne(i){return i%2===0?i+1:i-1}function en(i){return i==="left"?"right":"left"}function We(i){return i==="forward"?"left":"right"}function Ke(i){return i==="forward"?"right":"left"}function tn(i){return i==="left"?"forward":"reverse"}function nn(i){return i==="right"?"forward":"reverse"}function qe(i,e){let t=R(i),n=R(e);return z(i)?n>t||n===t&&!z(e):n>=t}function _e(i){return Me(i[0],i[i.length-1])}function Me(i,e){return i===void 0||e===void 0?!0:z(i)===z(e)?!z(i):qe(i,e)}var De=class{offset=0;bytes;constructor(e){this.bytes=e}get done(){return this.offset>=this.bytes.length}byte(){let e=this.bytes[this.offset];if(e!==void 0)return this.offset+=1,e}int(){let e=1,t=0;for(;this.offset<this.bytes.length;){let n=this.bytes[this.offset];if(this.offset+=1,t+=(n&127)*e,e*=128,(n&128)===0)return t}}},sn=255,Kn=256,Xe=class{source;sigma;threshold;constructor(e,t){this.source=new De(e),this.sigma=t===0?Number.MAX_SAFE_INTEGER:t,this.threshold=this.sigma<sn?Math.floor(Kn/this.sigma):0}next(){if(this.sigma>=sn){let s=this.source.int(),r=this.source.int();return s===void 0||r===void 0?void 0:{value:s,len:r+1}}let e=this.source.byte();if(e===void 0)return;let t=e%this.sigma,n=Math.floor(e/this.sigma)+1;if(n===this.threshold){let s=this.source.int();if(s===void 0)return;n+=s}return{value:t,len:n}}*[Symbol.iterator](){for(let e=this.next();e!==void 0;e=this.next())yield e}};function on(i){let e=new De(i),t=e.int();if(t===void 0||t===0)return[];let n=[],s=0;for(let r=0;r<t;r++){let o=e.int(),a=e.int();if(o===void 0||a===void 0)throw new Error("GBWT edge list ends early");s+=o,n.push({node:s,offset:a})}return n}var Ze=class{edges;bwt;constructor(e,t){this.edges=e,this.bwt=t}runs(){return new Xe(this.bwt,this.edges.length)}edge(e){let t=this.edges[e];if(t===void 0)throw new Error(`GBWT run refers to edge rank ${e} of ${this.edges.length}`);return t}lf(e){let t=this.edges.map(s=>s.offset),n=0;for(let s of this.runs()){let r=this.edge(s.value),o=t[s.value];if(n+s.len>e)return r.node===0?void 0:{node:r.node,offset:o+(e-n)};t[s.value]=o+s.len,n+=s.len}}edgeTo(e){let t=0,n=this.edges.length;for(;t<n;){let s=t+n>>1,r=this.edges[s];if(r.node===e)return s;r.node<e?t=s+1:n=s}}offsetTo(e){if(e.node===0)return;let t=this.edgeTo(e.node);if(t===void 0)return;let n=this.edges[t].offset;if(n>e.offset)return;let s=0;for(let r of this.runs())if(s+=r.len,r.value===t&&(n+=r.len,n>e.offset))return s-(n-e.offset)}predecessorAt(e){let t=this.edges.map(s=>({node:s.node===0?0:ne(s.node),count:0}));for(let s of this.runs()){let r=t[s.value];r&&(r.count+=s.len)}for(let s=1;s<t.length;s++){let r=t[s-1],o=t[s];R(r.node)===R(o.node)&&(t[s-1]=o,t[s]=r)}let n=0;for(let s of t)if(n+=s.count,n>e)return s.node===0?void 0:s.node}decompressArrays(){let e=this.edges.map(o=>o.offset),t=0;for(let o of this.runs())t+=o.len;let n=new Int32Array(t),s=new Int32Array(t),r=0;for(let o of this.runs()){let a=this.edge(o.value),h=e[o.value];for(let c=0;c<o.len;c++)n[r]=a.node,s[r]=h,h+=1,r+=1;e[o.value]=h}return{nodes:n,offsets:s}}decompress(){let e=this.edges.map(n=>n.offset),t=[];for(let n of this.runs()){let s=this.edge(n.value);for(let r=0;r<n.len;r++)t.push({node:s.node,offset:e[n.value]}),e[n.value]=e[n.value]+1}return t}};var Xn=["","A","C","G","T","N"];function rn(i){let e=i[i.length-1];if(e===void 0)return 0;let t=e,n=0;for(let s=0;s<3&&t%6!==0;s++)t=Math.floor(t/6),n+=1;return 3*(i.length-1)+n}function an(i){let e="";for(let t of i){let n=t;for(let s=0;s<3;s++){let r=Xn[n%6];if(r==="")return e;n=Math.floor(n/6),e+=r}}return e}var Zn={A:"T",C:"G",G:"C",T:"A",N:"N"};function Je(i){let e="";for(let t=i.length-1;t>=0;t--)e+=Zn[i[t]]??"N";return e}var Jn=Uint32Array.from([1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298]),me=(i,e)=>i>>>e|i<<32-e;function hn(i){let e=Math.ceil((i.length+9)/64),t=new Uint8Array(e*64);t.set(i),t[i.length]=128;let n=new DataView(t.buffer),s=i.length*8;n.setUint32(t.length-8,Math.floor(s/2**32)),n.setUint32(t.length-4,s>>>0);let r=Uint32Array.from([1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]),o=new Uint32Array(64);for(let c=0;c<e;c++){for(let I=0;I<16;I++)o[I]=n.getUint32(c*64+I*4);for(let I=16;I<64;I++){let w=o[I-15],b=o[I-2],y=me(w,7)^me(w,18)^w>>>3,k=me(b,17)^me(b,19)^b>>>10;o[I]=o[I-16]+y+o[I-7]+k}let d=r[0],f=r[1],l=r[2],g=r[3],p=r[4],u=r[5],m=r[6],E=r[7];for(let I=0;I<64;I++){let w=me(p,6)^me(p,11)^me(p,25),b=p&u^~p&m,y=E+w+b+Jn[I]+o[I]|0,k=me(d,2)^me(d,13)^me(d,22),v=d&f^d&l^f&l;E=m,m=u,u=p,p=g+y|0,g=l,l=f,f=d,d=y+k+v|0}[d,f,l,g,p,u,m,E].forEach((I,w)=>{r[w]=r[w]+I})}let a=new Uint8Array(32),h=new DataView(a.buffer);for(let c=0;c<8;c++)h.setUint32(c*4,r[c]);return a}function cn(i,e){let t=new Map;if(i!==void 0)for(let n of i.split(";")){let s=n.split(","),[r,o]=s;if(s.length!==2||!r||!o)throw new Error(`Invalid ${e} relationship: ${n}`);let a=t.get(r);a||(a=new Set,t.set(r,a)),a.add(o)}return t}function ln(i){return{name:i.get("pggname"),subgraph:cn(i.get("subgraph"),"subgraph"),translation:cn(i.get("translation"),"translation")}}function dn(i,e){for(let[t,n]of e){let s=i.get(t);s||(s=new Set,i.set(t,s));for(let r of n)s.add(r)}}function pn(i,e){let t={name:i,subgraph:new Map,translation:new Map};return e.name!==void 0&&(t.subgraph.set(i,new Set([e.name])),dn(t.subgraph,e.subgraph),dn(t.translation,e.translation)),t}function fn(i){return[...i.entries()].sort(([e],[t])=>e<t?-1:e>t?1:0).flatMap(([e,t])=>[...t].sort().map(n=>[e,n]))}function un(i){let e=[];i.name!==void 0&&e.push(`H NM:Z:${i.name}`);for(let[t,n]of fn(i.subgraph))e.push(`H SG:Z:${t},${n}`);for(let[t,n]of fn(i.translation))e.push(`H TL:Z:${t},${n}`);return e}async function wn(i){let e=i.reduce((o,a)=>o+a.length,0),t=new Uint8Array(e),n=0;for(let o of i)t.set(o,n),n+=o.length;let s=globalThis.crypto?.subtle;return[...s?new Uint8Array(await s.digest("SHA-256",t)):hn(t)].map(o=>o.toString(16).padStart(2,"0")).join("")}var Yn="_gbwt_ref";function le(i){let e=`${i.sample}#${i.haplotype}#${i.contig}`;return i.end===void 0?e:`${e}[${i.fragment}-${i.end}]`}var es=/^([^#]+)#(\d+)#([^#]+?)(?:\[\d+-\d+\])?$/,ts=/^([^#]+?)(?:\[\d+-\d+\])?$/;function ns(i){let e=es.exec(i);if(e)return{sample:e[1],haplotype:Number(e[2]),contig:e[3]};let t=ts.exec(i);if(t)return{contig:t[1]};throw new Error(`"${i}" is not a path name; expected "sample#haplotype#contig" or a bare contig`)}function $e(i){return typeof i=="string"?ns(i):i}function He(i,e){return{sample:i.sample??Yn,contig:i.contig,haplotype:i.haplotype??0,fragment:e}}var ss=4096;function kt(i){let e=[];for(let t of i){let n=e[e.length-1];n&&t-n[1]<=ss?n[1]=t:e.push([t,t])}return e}var os=32768,gn={mostChosenPaths:32},It=class{byNode=new Map;get(e){return this.byNode.get(e.node)?.get(e.offset)}set(e,t){let n=this.byNode.get(e.node);n||(n=new Map,this.byNode.set(e.node,n)),n.set(e.offset,t)}},re=class extends Error{};function Ye(i,e,t,n){return i==="forward"?e+t:e-n}function mn(i,e,t,n){return i==="forward"?e-n:e+t}function yn(i){return Me(ne(i.handles[i.handles.length-1]),ne(i.handles[0]))}function Fe(i){return`${i.pathHandle}:${i.hapStart}:${i.hapEnd}`}async function xn(i){let{db:e,records:t,signal:n}=i,s=performance.now(),r=()=>{let S=performance.now(),M=S-s;return s=S,M},o={spacing:await e.haplotypeAnchorSpacing(),anchors:void 0,anchorsRead:0,chosenPaths:0,scans:[],scanRows:0,strays:void 0,pieces:0,sources:{reference:0,section:0,stray:0,chain:0,twin:0},walks:{},twins:{tried:0,found:0},graphFetches:0,fallback:void 0,ms:{scan:0,walks:0,check:0,twins:0}},a=(S,M)=>{let P=`${S}: ${M}`;o.walks[P]=(o.walks[P]??0)+1},h=await e.haplotypeSampleInterval()??4096,c=new Map,d=async S=>{let M=t.get(S)??c.get(S);if(M)return M;let P=await e.getRecord(S);if(o.graphFetches+=1,!P)throw new Error(`Node record ${S} is missing from the database`);return c.set(S,P),P},f=S=>t.get(S).sequenceLen,l=await e.pathsByHandle(),g=S=>{let M=l.get(S);return M!==void 0&&i.keep(M.name)},p=[],u=new It,m=new Map,E=new Set,I=new Set,w=async S=>{let M=(await d(S.node)).gbwt().lf(S.offset);return M===void 0||M.node===0?void 0:M},b=async(S,M)=>{let P=(await d(ne(S.node))).gbwt().predecessorAt(S.offset);if(P===void 0||M!==void 0&&!M.has(P))return;let H=(await d(P)).gbwt().offsetTo(S);if(H===void 0)throw new Error(`No offset in ${P} leads to ${S.node}:${S.offset}`);return{node:P,offset:H}},y=(S,M,P,H)=>{let T=P.map(V=>V.pos.node),j=P.map(V=>V.pos.offset),J=0;for(let V of T)J+=f(V);let L=M==="forward"?P[0].left:P[P.length-1].left,C=p.length;p.push({pathHandle:S,orientation:M,handles:T,offsets:j,len:J,hapStart:L,hapEnd:L+J,canonical:Me(T[0],T[T.length-1]),source:H});for(let V of P)u.set(V.pos,C);let W=m.get(S);return W?W.push(C):m.set(S,[C]),C},k=async(S,M,P,H)=>{let T=[],j=S;for(;;){n?.throwIfAborted();let L=await b(j.pos,t);if(!L)break;j={pos:L,left:mn(P,j.left,f(j.pos.node),f(L.node))},T.push(j)}T.reverse();let J=[S];for(j=S;;){n?.throwIfAborted();let L=await w(j.pos);if(!L||!t.has(L.node))break;j={pos:L,left:Ye(P,j.left,f(j.pos.node),f(L.node))},J.push(j)}return y(M,P,[...T,...J],H)},v=async(S,M,P,H)=>p[u.get(S.pos)??await k(S,M,P,H)],O=S=>{let M=S.handles[S.handles.length-1];return{pos:{node:M,offset:S.offsets[S.offsets.length-1]},left:S.orientation==="forward"?S.hapEnd-f(M):S.hapStart}},B=S=>{let M=S.handles[0];return{pos:{node:M,offset:S.offsets[0]},left:S.orientation==="forward"?S.hapStart:S.hapEnd-f(M)}},D=await k({pos:i.referencePos,left:i.referenceLeft},i.referenceHandle,"forward","reference"),q=p[D],$=()=>{if(o.fallback!==void 0)return{reference:q,pieces:[],stats:o};let S=new Map;p.forEach((P,H)=>{H!==D&&S.set(Fe(P),[...S.get(Fe(P))??[],P])});let M=[];for(let P of S.values()){let H=new Set;for(let T of P)T.canonical&&!H.has(T.orientation)&&(H.add(T.orientation),M.push(T),o.sources[T.source]+=1)}return o.sources.reference=1,o.pieces=M.length+1,{reference:q,pieces:M,stats:o}},N=async(S,M)=>{let P=M?E:I,H=M?I:E,T=S;for(;;){if(P.has(T))return;P.add(T);let j=p[T],J=M?O(j):B(j),L=0,C;for(;C===void 0;){n?.throwIfAborted();let W=M?await w(J.pos):await b(J.pos);if(!W){C="endmarker";break}let V=(await d(J.pos.node)).sequenceLen,ge=(await d(W.node)).sequenceLen,se=M?Ye(j.orientation,J.left,V,ge):mn(j.orientation,J.left,V,ge);if(t.has(W.node)){let Y=u.get(W);Y===void 0?(T=await k({pos:W,left:se},j.pathHandle,j.orientation,"chain"),H.add(T),C="landed"):(H.add(Y),C="merge")}else L>os?C="bound":(L+=ge,J={pos:W,left:se})}if(a("chain",C),C!=="landed")return}},Q=async S=>{if(i.context>S.context)throw new re(`the context of ${i.context} bp exceeds the ${S.context} bp the haplotype index's stray rows cover`);let M=o.spacing;if(M===void 0)throw new re("the haplotype index has no anchors");let{bin:P,bound:H}=S,{fills:T,inserted:j}=i.snarls;if(i.snarls.mode==="overlapping"&&T.length>0)throw new re("the haplotype index's stray rows cover contained snarls only");for(let x of T){if(x.inserted>0&&x.low===x.high)throw new re(`the haplotype index's stray rows leave out the snarl bounded by node ${x.low} at both ends`);if(x.inserted>0&&(S.snarlNodes===void 0||x.nodes>S.snarlNodes))throw new re(S.snarlNodes===void 0?"the haplotype index's stray rows leave snarls out":`a snarl of ${x.nodes} nodes exceeds the ${S.snarlNodes} the haplotype index's stray rows cover`)}let J=Math.floor(i.window.start/P),L=Math.floor((i.window.end-1)/P),C=J*P,W=(L+1)*P,V=new Map,ge=async(x,A)=>{let U=await e.haplotypeAnchorsBetween(i.referenceHandle,x*M,A*M);for(let _ of U)V.set(_.anchorOffset/M,_)},se=Math.max(0,Math.floor((C-H)/M)-1),Y=Math.ceil((W+H)/M)+1,[{listed:Ge,strays:ae}]=await Promise.all([e.haplotypeBinData(i.referenceHandle,J,L),ge(se,Y)]);for(let x of t.keys()){let A=R(x);if(!z(x)&&!Ge(A)&&!j.has(A))throw new re(`the haplotype index lists node ${A} of the subgraph in no bin that the window touches`)}o.scans=kt([...t.keys()].sort((x,A)=>x-A));let ce=Promise.all(o.scans.map(([x,A])=>e.haplotypeSamplesInRange(x,A)));for(ce.catch(()=>{});se>0&&(V.get(se)?.pathOffset??Number.POSITIVE_INFINITY)>=C-H;)se-=1,await ge(se,se);for(;V.has(Y)&&V.get(Y).pathOffset<=W+H;)Y+=1,await ge(Y,Y);let pe=[...V.keys()].sort((x,A)=>x-A),Se=V.get(pe[0]??-1);if(!Se)throw new re("the haplotype index has no anchors on this path");let de=x=>V.get(x).pathOffset,Le=new Map;for(let x of pe){let A=R(V.get(x).node);Le.set(A,[...Le.get(A)??[],x])}let bt=[...Le.keys()],Ut=bt.map(x=>V.get(Le.get(x)[0]).visits);if(!Ut[bt.indexOf(R(Se.node))].some(x=>x.pathHandle===i.referenceHandle&&x.orientation==="forward"&&x.pathOffset===Se.pathOffset))throw new Error(`The haplotype index has no anchor row for the reference path ${i.referenceHandle} at offset ${Se.pathOffset} (node ${R(Se.node)}); it does not match this graph`);let jt=pe.filter(x=>de(x)<=i.window.start),Vn=pe.filter(x=>de(x)>=i.window.end);o.anchors=[de(jt[jt.length-1]??pe[0]),de(Vn[0]??pe[pe.length-1])],o.anchorsRead=pe.length;let St=new Map,Vt=new Set;if(bt.forEach((x,A)=>{let U=Le.get(x),_=U.length===1?U[0]:void 0;for(let F of Ut[A])Vt.add(F.pathHandle),F.orientation==="forward"&&g(F.pathHandle)&&St.set(F.pathHandle,[...St.get(F.pathHandle)??[],{k:_,row:F}])}),o.chosenPaths=[...Vt].filter(g).length,o.chosenPaths>gn.mostChosenPaths)throw new re(`${o.chosenPaths} chosen paths pass the anchors, more than ${gn.mostChosenPaths}`);let Qe=[],ve=Number.POSITIVE_INFINITY,Ee=0;for(let[x,A]of St){A.sort((U,_)=>U.row.pathOffset-_.row.pathOffset);for(let U=0;U+1<A.length;U++){let _=A[U],F=A[U+1];if(_.k===void 0||F.k===void 0||Math.abs(_.k-F.k)!==1)continue;let[X,ee]=de(_.k)<=de(F.k)?[_,F]:[F,_],te=de(X.k),oe=de(ee.k);te<W&&oe>=C?(Qe.push({pathHandle:x,from:_.row,to:F.row}),ve=Math.min(ve,te-H),Ee=Math.max(Ee,oe+H)):te>=W&&te-W<=H?(Qe.push({pathHandle:x,from:X.row,to:void 0}),ve=Math.min(ve,te-H),Ee=Math.max(Ee,te+H)):oe<C&&C-oe<=H&&(Qe.push({pathHandle:x,from:ee.row,to:void 0}),ve=Math.min(ve,oe-H),Ee=Math.max(Ee,oe+H))}}let Gn=new Set(T.map(x=>`${x.low}:${x.high}`)),Qn=ae.filter(x=>g(x.pathHandle)&&(x.snarl===void 0||Gn.has(`${x.snarl[0]}:${x.snarl[1]}`))).sort((x,A)=>x.pathHandle-A.pathHandle||x.pathStart-A.pathStart);o.strays={bins:L-J+1,rows:ae.length,walked:0,outsideBp:0},Ee>0&&await i.prefetchReferenceRange(i.referenceHandle,Math.max(0,ve),Ee+1),o.ms.scan=r();let Gt=8*M+2*(i.window.end-i.window.start),Qt=o.strays,Be=0,Wt=x=>{if(Qt.outsideBp+=x,Be+=x,Be>Gt)throw new re(`a walk of a chosen path near the window went past its cap of ${Gt} bp`)},Et=new Map,Kt=(x,A,U)=>(Et.get(x)??[]).some(([_,F])=>_<=A&&U<F),Xt=(x,A,U)=>{Et.set(x,[...Et.get(x)??[],[A,U]])},Zt=async(x,A,U,_,F)=>{let X=A,ee=U,te=ee;for(;X&&ee<=_;){n?.throwIfAborted();let oe;if(t.has(X.node)){let Te=await v({pos:X,left:ee},x,"forward",F),Yt=O(Te);X=Yt.pos,ee=Yt.left,oe=f(X.node),te=Math.max(te,Te.hapEnd)}else oe=(await d(X.node)).sequenceLen,Wt(oe),te=Math.max(te,ee+oe);X=await w(X),ee+=oe}return te},Wn=async(x,A,U,_)=>{let F={pos:A,left:U},X=U;for(;F.left>_;){n?.throwIfAborted();let ee=await b(F.pos);if(!ee)break;let te=(await d(ee.node)).sequenceLen,oe=F.left-te;if(t.has(ee.node)){let Te=await v({pos:ee,left:oe},x,"forward","section");F=B(Te),X=Math.min(X,Te.hapStart)}else Wt(te),F={pos:ee,left:oe},X=Math.min(X,oe)}return X};for(let{pathHandle:x,from:A,to:U}of Qe){let _=A.pathOffset,F=(U??A).pathOffset+H;if(Kt(x,_-H,F))continue;let X={node:A.node,offset:A.offset};Be=0;let ee=await Zt(x,X,_,F,"section");Be=0;let te=await Wn(x,X,_,_-H);Xt(x,Math.min(te,_-H),Math.max(ee,F+1)),a(U?"section":"visit",U?"past the far anchor":"bound")}for(let x of Qn){if(Kt(x.pathHandle,x.pathStart,x.pathEnd))continue;Be=0;let A=await Zt(x.pathHandle,{node:x.node,offset:x.offset},x.pathStart,x.pathEnd,"stray");Xt(x.pathHandle,x.pathStart,Math.max(A,x.pathEnd+1)),Qt.walked+=1}o.ms.walks=r();let Jt=[];for(let x of await ce)for(let A of x)if(o.scanRows+=1,t.has(A.node)&&g(A.pathHandle)){if(!(m.get(A.pathHandle)??[]).some(U=>{let _=p[U];return _.hapStart<=A.pathOffset&&A.pathOffset<_.hapEnd}))throw new re(`chosen path ${A.pathHandle} has a sample at ${A.pathOffset} on the window's nodes that no walk reached`);A.orientation==="reverse"&&Jt.push(A)}for(let x of Jt)await v({pos:{node:x.node,offset:x.offset},left:x.pathOffset},x.pathHandle,"reverse","twin");o.ms.check=r()},Z=async()=>{let S=new Map,M=L=>{let C=Fe(L),W=S.get(C);W?W.add(L.orientation):S.set(C,new Set([L.orientation]))},P=0,H=()=>{for(;P<p.length;P++)M(p[P])};H();let T=L=>(S.get(Fe(L))?.size??0)>1,j=2*h,J=(L,C)=>C===D?g(i.referenceHandle)&&yn(L):!L.canonical||yn(L);for(let L=0;L<p.length;L++){let C=p[L];if(T(C)||!J(C,L))continue;o.twins.tried+=1;let W=C.orientation==="forward"?"reverse":"forward",V=O(C),ge=0,se;for(;!se&&ge<=j;){n?.throwIfAborted();let ae=await w(V.pos);if(!ae)break;let ce=(await d(ae.node)).sequenceLen,pe=Ye(C.orientation,V.left,(await d(V.pos.node)).sequenceLen,ce),Se=ne(ae.node);se=(await e.haplotypeSamplesInRange(Se,Se)).find(de=>de.pathHandle===C.pathHandle&&de.orientation===W&&de.pathOffset===pe),ge+=ce,V={pos:ae,left:pe}}let Y=se&&{pos:{node:se.node,offset:se.offset},left:se.pathOffset},Ge=0;for(;Y&&!T(C)&&Ge<=j+C.len;){if(n?.throwIfAborted(),t.has(Y.pos.node)){let ae=await v(Y,C.pathHandle,W,"twin"),ce=p.indexOf(ae);await N(ce,!0),await N(ce,!1),H(),Y=O(ae)}if(!T(C)){let ae=(await d(Y.pos.node)).sequenceLen;Ge+=ae;let ce=await w(Y.pos);Y=ce?{pos:ce,left:Ye(W,Y.left,ae,(await d(ce.node)).sequenceLen)}:void 0}}if(H(),!T(C))throw new re(`piece ${Fe(C)} was found in one orientation where extractPaths keeps the other`);o.twins.found+=1}o.ms.twins=r()};try{let S=await e.haplotypeStrayOptions();if(S===void 0)throw new re("the haplotype index has no stray rows; gbz-haplotype-index 0.2.0 writes them");await Q(S),await Z()}catch(S){if(!(S instanceof re))throw S;o.fallback=S.message}return $()}function bn(i,e){return i.handles[0]-e.handles[0]||i.offsets[0]-e.offsets[0]}function et(i,e){let t=0,n=i.length;for(;t<n;){let s=t+n>>1;i[s]<e?t=s+1:n=s}return t}var tt=class{ending;tree;constructor(e){this.ending=new Float64Array(e),this.tree=new Int32Array(e+1).fill(-1)}bestBefore(e){let t=-1;for(let n=e;n>0;n-=n&-n){let s=this.tree[n];s!==-1&&(t===-1||this.ending[s]>this.ending[t])&&(t=s)}return t}raise(e,t){this.ending[e]=t;for(let n=e+1;n<this.tree.length;n+=n&-n){let s=this.tree[n];(s===-1||t>this.ending[s])&&(this.tree[n]=e)}}},vt=class{pairs=[];total=0;a;b;weight;occurrences=new Map;constructor(e,t,n){this.a=e,this.b=t,this.weight=n,t.forEach((s,r)=>{let o=this.occurrences.get(s);o?o.push(r):this.occurrences.set(s,[r])})}solve(e,t,n,s){let r=0;for(;e+r<t&&n+r<s&&this.a[e+r]===this.b[n+r];)this.match(e+r,n+r),r+=1;let o=0;for(;t-o>e+r&&s-o>n+r&&this.a[t-o-1]===this.b[s-o-1];)o+=1;this.solveMiddle(e+r,t-o,n+r,s-o);for(let a=o;a>0;a--)this.match(t-a,s-a)}match(e,t){this.pairs.push([e,t]),this.total+=this.weight(this.a[e])}solveMiddle(e,t,n,s){if(e===t||n===s)return;let r=this.matchCount(e,t,n,s);if(r===0)return;if(r<=t-e+(s-n)){this.chain(e,t,n,s,r);return}let o=e+t>>1,a=this.split(e,o,t,n,s);this.solve(e,o,n,a),this.solve(o,t,a,s)}matchCount(e,t,n,s){let r=0;for(let o=e;o<t;o++){let a=this.occurrences.get(this.a[o]);a&&(r+=et(a,s)-et(a,n))}return r}sweep(e,t,n,s,r,o,a){for(let h=e;h!==t;h+=n){let c=this.occurrences.get(this.a[h]);if(!c)continue;let d=this.weight(this.a[h]),f=et(c,s),l=et(c,r);for(let g=0;g<l-f;g++){let p=n===1?c[l-1-g]-s:r-1-c[f+g],u=o.bestBefore(p),m=(u===-1?0:o.ending[u])+d;if(m>o.ending[p]&&(o.raise(p,m),a)){let E=a.count++;a.row[E]=h,a.column[E]=p,a.previous[E]=u===-1?-1:a.endingMatch[u],a.endingMatch[p]=E}}}}chain(e,t,n,s,r){let o=new tt(s-n),a={row:new Int32Array(r),column:new Int32Array(r),previous:new Int32Array(r),endingMatch:new Int32Array(s-n),count:0};this.sweep(e,t,1,n,s,o,a);let h=o.bestBefore(s-n);if(h===-1)return;this.total+=o.ending[h];let c=[];for(let d=a.endingMatch[h];d!==-1;d=a.previous[d])c.push([a.row[d],n+a.column[d]]);for(let d=c.length-1;d>=0;d--)this.pairs.push(c[d])}frontier(e,t,n,s,r){let o=new tt(r-s);this.sweep(e,t,n,s,r,o);let a=new Float64Array(r-s+1);for(let h=0;h<r-s;h++)a[h+1]=Math.max(a[h],o.ending[h]);return a}split(e,t,n,s,r){let o=r-s,a=this.frontier(e,t,1,s,r),h=this.frontier(n-1,t-1,-1,s,r),c=0,d=-1;for(let f=0;f<=o;f++){let l=a[f]+h[o-f];l>d&&(d=l,c=f)}return s+c}};function Sn(i,e,t){let n=new vt(i,e,t);return n.solve(0,i.length,0,e.length),[n.pairs,n.total]}var rs=100,Pt=4e6,is=5e3,he=15,as=64,hs=8,Pn=1,Rt=-4,ie=-6,xe=-1,Ce=-(2**30),st=0,Mt=1,Rn=2;function Ae(i,e,t){let n=i.at(-1);t>0&&(n?.[0]===e?n[1]+=t:i.push([e,t]))}function nt(i,e,t){return i>=t&&i>=e?st:t>=e?Rn:Mt}function Nn(i,e,t){let n=i.length,s=e.length,r=s+1,o=new Uint8Array((n+1)*r),a=new Int32Array(r).fill(Ce),h=new Int32Array(r).fill(Ce),c=new Int32Array(r).fill(Ce);a[0]=0;for(let p=1;p<=s;p++)c[p]=ie+(p-1)*xe,o[p]=(p===1?st:Rn)<<4;for(let p=1;p<=n;p++){let u=new Int32Array(r).fill(Ce),m=new Int32Array(r).fill(Ce),E=new Int32Array(r).fill(Ce);m[0]=ie+(p-1)*xe,o[p*r]=(p===1?st:Mt)<<2;let I=i.charCodeAt(p-1);for(let w=1;w<=s;w++){let b=nt(a[w-1],h[w-1],c[w-1]);u[w]=Math.max(a[w-1],h[w-1],c[w-1])+(I===e.charCodeAt(w-1)?Pn:Rt);let y=nt(a[w]+ie,h[w]+xe,c[w]+ie);m[w]=Math.max(a[w]+ie,h[w]+xe,c[w]+ie);let k=nt(u[w-1]+ie,m[w-1]+ie,E[w-1]+xe);E[w]=Math.max(u[w-1]+ie,m[w-1]+ie,E[w-1]+xe),o[p*r+w]=b|y<<2|k<<4}a=u,h=m,c=E}let d=[],f=n,l=s,g=nt(a[s],h[s],c[s]);for(;f>0||l>0;){let p=o[f*r+l]>>2*g&3;g===st?(d.push(i[f-1]===e[l-1]?"=":"X"),f-=1,l-=1):g===Mt?(d.push("I"),f-=1):(d.push("D"),l-=1),g=p}for(let p of d.reverse())Ae(t,p,1)}function cs(i,e){let t=Math.abs(i-e);return(t===0?0:Math.min(-ie-(t-1)*xe,-ie+10*Math.log2(t)))+(Math.min(i,e)>0?-Rt:0)}function qn(i,e){let t=Math.abs(i-e);return t===0?0:.01*he*t+.5*Math.log2(t)}function En(i,e,t){return{qs:i.qs+e,qe:i.qs+t,ts:i.flipped?i.te-t:i.ts+e,te:i.flipped?i.te-e:i.ts+t,flipped:i.flipped}}function ds(i,e,t){let n=i.qe-i.qs,s=[];for(let[a,h]of e){let c=Math.max(0,a-i.qs),d=Math.min(n,h-i.qs);c<d&&s.push([c,d])}for(let[a,h]of t){let c=Math.max(0,i.flipped?i.te-h:a-i.ts),d=Math.min(n,i.flipped?i.te-a:h-i.ts);c<d&&s.push([c,d])}if(s.length===0)return[i];s.sort((a,h)=>a[0]-h[0]);let r=[],o=0;for(let[a,h]of s)a-o>=he&&r.push(En(i,o,a)),o=Math.max(o,h);return n-o>=he&&r.push(En(i,o,n)),r}function Nt(i,e,t,n,s=1/0){let r=[],o={query:[],target:[]},a={forward:{query:[],target:[]},flipped:{query:[],target:[]}},h=[...i].sort((c,d)=>c.qs-d.qs||c.ts-d.ts);for(;h.length>0&&r.length<s;){let c=h.map(w=>w.qe-w.qs),d=new Int32Array(h.length).fill(-1),f=new Int32Array(h.length);for(let w=0;w<h.length;w++){let b=h[w],y=b.qe-b.qs;for(let k=w-1;k>=Math.max(0,w-is);k--){if(c[k]+y<=c[w])continue;let v=h[k];if(v.flipped===b.flipped&&v.qs<b.qs&&(b.flipped?b.te<v.te:v.ts<b.ts)){let B=Math.max(0,v.qe-b.qs,b.flipped?b.te-v.ts:v.te-b.ts),D=b.qs+B-v.qe,q=b.flipped?v.ts-(b.te-B):b.ts+B-v.te;if(B<y&&D<=e&&q<=e){let $=c[k]+y-B-n(D,q);$>c[w]&&(c[w]=$,d[w]=k,f[w]=B)}}}}let l=new Int32Array(h.length),g=-1;for(let w=0;w<h.length;w++){let b=h[w];l[w]=(l[d[w]]??0)+b.qe-b.qs-f[w],l[w]>=t&&(g<0||c[w]>c[g])&&(g=w)}if(g<0)break;let p=[];for(let w=g;w>=0;w=d[w])p.push({run:h[w],trim:f[w]});p.reverse(),r.push(p);let u=p[0],m=p.at(-1),{flipped:E}=u.run,I=E?a.flipped:a.forward;I.query.push([u.run.qs+u.trim,m.run.qe]),I.target.push(E?[m.run.ts,u.run.te-u.trim]:[u.run.ts+u.trim,m.run.te]);for(let{run:w,trim:b}of p)o.query.push([w.qs+b,w.qe]),o.target.push(w.flipped?[w.ts,w.te-b]:[w.ts+b,w.te]);h=h.flatMap(w=>{let b=w.flipped?a.flipped:a.forward;return ds(w,[...o.query,...b.query],[...o.target,...b.target])}).sort((w,b)=>w.qs-b.qs||w.ts-b.ts)}return r}function At(i,e){let t=new Map;for(let r=0;r+he<=e.length;r++){let o=e.slice(r,r+he),a=t.get(o);a?a.push(r):t.set(o,[r])}let n=[],s=new Map;for(let r=0;r+he<=i.length;r++){let o=t.get(i.slice(r,r+he));if(o&&o.length<=as)for(let a of o){let h=a-r,c=s.get(h);if(c&&r<=c.qe)c.qe=r+he,c.te=a+he;else{let d={qs:r,qe:r+he,ts:a,te:a+he,flipped:!1};s.set(h,d),n.push(d)}}}return n}function fs(i,e){return[...At(i,e),...At(i,Je(e)).map(t=>({...t,ts:e.length-t.te,te:e.length-t.ts,flipped:!0}))]}function ot(i,e,t,n,s){let r;for(let{run:o,trim:a}of i){let h=o.qs+a;if(r){let c=o.flipped?o.te-a:r.te,d=o.flipped?r.ts:o.ts+a,f=t.slice(c,d);s(e.slice(r.qe,h),o.flipped?Je(f):f,n,r.qe,c)}Ae(n,"=",o.qe-h),r=o}}function qt(i,e,t){Ae(t,"I",i.length),Ae(t,"D",e.length)}function $n(i,e,t){i.length*e.length<=Pt?Nn(i,e,t):qt(i,e,t)}function $t(i,e,t,n=0){let[s]=i.length*e.length>Pt&&n<hs?Nt(At(i,e),1/0,he,qn,1):[];if(!s){$n(i,e,t);return}let r=(h,c,d)=>{$t(h,c,d,n+1)},o=s[0].run,a=s.at(-1).run;r(i.slice(0,o.qs),e.slice(0,o.ts),t),ot(s,i,e,t,r),r(i.slice(a.qe),e.slice(a.te),t)}function ls(i,e,t){$t(i,e,t)}function ps(i,e,t){let n=[];ot(i,e,t,n,ls);let s=i[0],r=i.at(-1),{flipped:o}=s.run;return{queryStart:s.run.qs+s.trim,queryEnd:r.run.qe,targetStart:o?r.run.ts:s.run.ts+s.trim,targetEnd:o?s.run.te-s.trim:r.run.te,strand:o?"-":"+",edits:o?n.reverse():n,sharedBases:0}}function us(i,e,t,n){let s=[];if(i.length*e.length<=Pt)Nn(i,e,t);else{let r=Nt(fs(i,e),1/0,Math.max(n,he),qn),o=r.find(a=>!a[0].run.flipped);if(s=r.filter(a=>a[0].run.flipped).map(a=>ps(a,i,e)),o){let a=(d,f,l,g,p)=>{s.some(m=>g<m.queryEnd&&m.queryStart<g+d.length||p<m.targetEnd&&m.targetStart<p+f.length)?$n(d,f,l):$t(d,f,l)},h=o[0].run,c=o.at(-1).run;a(i.slice(0,h.qs),e.slice(0,h.ts),t,0,0),ot(o,i,e,t,a),a(i.slice(c.qe),e.slice(c.te),t,c.qe,c.te)}else qt(i,e,t)}return s}function Ht(i,e){let t=i.strand==="-",n=0,s=0;for(let[r,o]of i.edits)e(r,o,t?i.queryEnd-1-n:i.queryStart+n,i.targetStart+s),r!=="D"&&(n+=o),r!=="I"&&(s+=o)}function In(i,e,t,n){let s=e==="query"&&i.strand==="-"?-1:1,r=0;return Ht(i,(o,a,h,c)=>{let d=e==="query"?h:c,f=l=>{let g=d+s*l;return g>=t&&g<n};if(o==="="||o==="X")for(let l=0;l<a;l++)f(l)&&(r+=o==="="?Pn:Rt);else if(o==="I"==(e==="query"))for(let l=0;l<a;l++)f(l)&&(r+=l===0?ie:xe);else f(0)&&(r+=ie+(a-1)*xe)}),r}function kn(i,e){return e==="query"?[i.queryStart,i.queryEnd]:[i.targetStart,i.targetEnd]}function ws(i,e){let t=i.strand==="-",n=[],s=0,r=0,o=0,a=0,h=new Uint8Array(i.queryEnd-i.queryStart);for(let[g,p]of i.shared)h.fill(1,g-i.queryStart,p-i.queryStart);let c=g=>h[g-i.queryStart]===1,d=()=>{Ae(n,"I",s),Ae(n,"D",r),s=0,r=0};Ht(i,(g,p,u)=>{if(g==="I")s+=p;else if(g==="D")r+=p;else{for(let m=0;m<p;m++)e[o+m]?(s+=1,r+=1,c(t?u-m:u+m)&&(a+=1)):((s>0||r>0)&&d(),Ae(n,g,1));o+=p}}),d();let f={I:0,D:0};for(;n[0]?.[0]==="I"||n[0]?.[0]==="D";){let[g,p]=n.shift();f[g]+=p}let l={I:0,D:0};for(;n.at(-1)?.[0]==="I"||n.at(-1)?.[0]==="D";){let[g,p]=n.pop();l[g]+=p}return n.length===0?void 0:{...i,queryStart:i.queryStart+(t?l.I:f.I),queryEnd:i.queryEnd-(t?f.I:l.I),targetStart:i.targetStart+f.D,targetEnd:i.targetEnd-l.D,edits:n,sharedBases:i.sharedBases-a}}function gs(i,e,t,n){let s={query:new Uint8Array(e),target:new Uint8Array(t)},r=i.map(c=>{let d=[];Ht(c,(f,l,g,p)=>{if(f==="="||f==="X")for(let u=0;u<l;u++)d.push([c.strand==="-"?g-u:g+u,p+u])});for(let[f,l]of d)s.query[f]=Math.min(255,s.query[f]+1),s.target[l]=Math.min(255,s.target[l]+1);return d}),o={query:new Map,target:new Map};r.forEach((c,d)=>{for(let[f,l]of c)for(let[g,p]of[["query",f],["target",l]])if(s[g][p]>1){let u=o[g].get(p);u?u.at(-1)!==d&&u.push(d):o[g].set(p,[d])}});let a=new Map,h=(c,d,f)=>{let l=`${f}:${c}:${d}`,g=a.get(l);if(g===void 0){let[p,u]=kn(i[c],f),[m,E]=kn(i[d],f),I=Math.max(p,m),w=Math.min(u,E),[b,y]=[i[c],i[d]];g=[In(y,f,I,w)-In(b,f,I,w),y.sharedBases-b.sharedBases,c-d].find(v=>v!==0)>0,a.set(l,g)}return g};return i.flatMap((c,d)=>{let f=r[d],l=new Uint8Array(f.length);if(f.forEach(([u,m],E)=>{for(let[I,w]of[["query",u],["target",m]])!l[E]&&o[I].get(w)?.some(b=>b!==d&&h(d,b,I))&&(l[E]=1)}),!l.includes(1))return[c];let g=ws(c,l),p=g?.edits.reduce((u,[m,E])=>u+(m==="="?E:0),0)??0;return g&&p>=n?[g]:[]})}function vn(i,e){return i.map(t=>{let n=e(R(t));return z(t)?Je(n):n}).join("")}function Mn(i,e){let t=[0];for(let n of i)t.push(t.at(-1)+e(R(n)).length);return t}function An(i){let e=new Map,t=new Map;i.forEach((o,a)=>{let h=R(o);e.has(h)?t.set(h,a):e.set(h,a)});let n=new Int32Array(i.length+1);for(let[o,a]of t)n[e.get(o)]+=1,n[a+1]-=1;let s=new Uint8Array(i.length),r=0;for(let o=0;o<i.length;o++)r+=n[o],s[o]=r>0?1:0;return s}function ms(i,e,t,n){let s=An(i),r=An(e),o=new Map;e.forEach((f,l)=>{r[l]||o.set(R(f),[l])});let a=2*e.length,h=(f,l,g)=>f*a+2*l+(g?1:0),c=new Set;i.forEach((f,l)=>{for(let g of s[l]?[]:o.get(R(f))??[])c.add(h(l,g,z(f)!==z(e[g])))});let d=[];return i.forEach((f,l)=>{for(let g of s[l]?[]:o.get(R(f))??[]){let p=z(f)!==z(e[g]),u=p?-1:1,m=g-u;if(!(l>0&&m>=0&&m<e.length&&c.has(h(l-1,m,p)))){let I=l,w=g;for(;I<i.length&&w>=0&&w<e.length&&c.has(h(I,w,p));)I+=1,w+=u;let b=w-u;d.push({qs:t[l],qe:t[I],ts:n[Math.min(g,b)],te:n[Math.max(g,b)+1],flipped:p})}}}),d}function Hn(i){let{query:e,target:t,sequenceOf:n}=i,s=vn(e,n),r=vn(t,n),o=ms(e,t,Mn(e,n),Mn(t,n)),a=i.minMatch??rs,h=i.bases??!0,c=[];for(let d of Nt(o,i.maxGap??1/0,a,cs)){let f=[],l=d[0],g=d.at(-1),{flipped:p}=l.run;ot(d,s,r,f,h?(m,E,I,w,b)=>{for(let y of us(m,E,I,a)){let k=b+E.length;c.push({...y,queryStart:w+y.queryStart,queryEnd:w+y.queryEnd,targetStart:p?k-y.targetEnd:b+y.targetStart,targetEnd:p?k-y.targetStart:b+y.targetEnd,strand:p?"+":"-",edits:p?y.edits.reverse():y.edits,shared:[]})}}:qt),c.push({queryStart:l.run.qs+l.trim,queryEnd:g.run.qe,targetStart:p?g.run.ts:l.run.ts+l.trim,targetEnd:p?l.run.te-l.trim:g.run.te,strand:p?"-":"+",edits:p?f.reverse():f,sharedBases:d.reduce((m,{run:E,trim:I})=>m+E.qe-E.qs-I,0),shared:d.map(({run:m,trim:E})=>[m.qs+E,m.qe])})}return gs(c,s.length,r.length,a).map(({shared:d,...f})=>f).sort((d,f)=>d.queryStart-f.queryStart)}function Cn(i){return i.map(([e,t])=>`${t}${e}`).join("")}var we=class extends Error{name="SubgraphLimitError";limit;windowBp;walkedBp;constructor(e,t){super(t===void 0?`Subgraph size limit of ${e} nodes exceeded`:`Subgraph size limit of ${e} nodes exceeded ${t.walkedBp} bp into a ${t.windowBp} bp window`),this.limit=e,this.windowBp=t?.windowBp,this.walkedBp=t?.walkedBp}};function Ct(i,e){return i[0]<e[0]||i[0]===e[0]&&(i[1]<e[1]||i[1]===e[1]&&i[2]<e[2])}var Ue=class{heap=[];push(e,t,n){let s=this.heap;s.push([e,t,n]);let r=s.length-1;for(;r>0;){let o=r-1>>1;if(Ct(s[r],s[o]))[s[r],s[o]]=[s[o],s[r]],r=o;else break}}pop(){let e=this.heap,t=e[0],n=e.pop();if(e.length>0&&n!==void 0){e[0]=n;let s=0;for(;;){let r=2*s+1,o=r+1,a=s;if(r<e.length&&Ct(e[r],e[a])&&(a=r),o<e.length&&Ct(e[o],e[a])&&(a=o),a===s)break;[e[s],e[a]]=[e[a],e[s]],s=a}}return t}get size(){return this.heap.length}};function ys(i){let e=new Int32Array(i.length),t=new Int32Array(i.length);return i.forEach(([n,s],r)=>{e[r]=n,t[r]=s}),{pathAt:e,refAt:t,count:i.length}}function xs(i,e){let t=0,n=i.length;for(;t<n;){let s=t+n>>1;i[s]>e?n=s:t=s+1}return i[t]}function Pe(i){return`${i.node}:${i.offset}`}function ze(i){return i.map(e=>ne(e)).reverse()}function bs(i,e){let t=e.identity.hapStart-i.identity.hapEnd,n=i.strand==="+"?e.refStart-i.refEnd:i.refStart-e.refEnd;return i.strand===e.strand&&t>=0&&n>=0?{insertion:t,deletion:n}:void 0}function Ss(i,e,t){let[n,s]=i.strand==="+"?[i,e]:[e,i],r=n.edits.map(([c,d])=>[c,d]);Ln(r,t.insertion,t.deletion);for(let[c,d]of s.edits)K(r,c,d);let o=i.identity.walkForward,[a,h]=o?[i,e]:[e,i];return{strand:i.strand,refStart:n.refStart,refEnd:s.refEnd,edits:r,weight:void 0,path:[...a.path,...h.path],start:a.start,pieces:[...a.pieces,...h.pieces],soloAligned:[...a.soloAligned,...h.soloAligned],identity:{pathHandle:i.identity.pathHandle,name:i.identity.name,hapStart:i.identity.hapStart,hapEnd:e.identity.hapEnd,walkForward:o}}}function Es(i,e,t){if(i.some(o=>o.weight!==void 0))return i;let n=new Map;i.forEach((o,a)=>{if(o.identity){let h=n.get(o.identity.pathHandle);h?h.push(a):n.set(o.identity.pathHandle,[a])}});let s=new Map,r=new Set;for(let o of n.values()){o.sort((d,f)=>i[d].identity.hapStart-i[f].identity.hapStart);let a=o[0],h=i[a],c=[];for(let d of o.slice(1)){let f=i[d],l=c.length===0?bs(h,f):void 0;if(l){h=Ss(h,f,l),r.add(d);continue}if(!e(f)){c.push(d);continue}let g=e(h)?t([h,...c.map(p=>i[p]),f]):void 0;if(g){h=g;for(let p of[...c,d])r.add(p)}else s.set(a,h),a=d,h=f;c=[]}s.set(a,h)}return i.flatMap((o,a)=>r.has(a)?[]:[s.get(a)??o])}function rt(i,e){return{node:i.path[e],offset:i.offsets[e]}}var Is=32768;function ks(i){let e=[...i].sort((n,s)=>n-s),t=[];for(let n of e){let s=t[t.length-1];s&&n-s[1]<=Is?s[1]=n:t.push([n,n])}return t}var ht=class i{records=new Map;paths=[];twinStarts=new Set;twinDeferred=!1;unsettled;refId;refPath;refHandle;refInterval;refIndexCache;refPrefixCache;walkedBp;snarlMode="none";snarlFills=[];snarlNodes=new Set;stats={orderedAlignments:0,lcsAlignments:0,snarls:{fills:0,inserted:0},identificationSteps:0,identificationFetches:0,identification:{interval:0,scans:[],windowSamples:0,fragmentLengths:[],companionSeeks:0,companionMisses:0,graphLookups:0,graphFetches:0,chains:[]},keep:void 0};db;limit;signal;constructor(e,t){this.db=e,this.limit=t.limit,this.signal=t.signal}static create(e,t={}){return new i(e,t)}get nodeCount(){return this.records.size/2}get pathCount(){return this.settleDeferred(),this.paths.length}get referenceInterval(){return this.refInterval&&this.refPath?{name:this.refPath,start:this.refPath.fragment+this.refInterval[0],end:this.refPath.fragment+this.refInterval[1]}:void 0}hasNode(e){return this.records.has(ue(e,"forward"))}hasHandle(e){return this.records.has(e)}record(e){let t=this.records.get(e);if(!t)throw new Error(`Subgraph has no record for handle ${e}`);return t}sortedHandles(){return[...this.records.keys()].sort((e,t)=>e-t)}async addNode(e){if(this.signal?.throwIfAborted(),this.limit!==void 0&&this.nodeCount>=this.limit)throw new we(this.limit);let t=await this.db.getRecord(ue(e,"forward")),n=await this.db.getRecord(ue(e,"reverse"));if(!t||!n)throw new Error(`Node ${e} does not exist in the graph`);this.records.set(t.handle,t),this.records.set(n.handle,n)}async ensureNode(e){this.hasNode(e)||await this.addNode(e)}clearPaths(){this.paths=[],this.twinStarts.clear(),this.twinDeferred=!1,this.unsettled=void 0,this.refId=void 0,this.refPath=void 0,this.refHandle=void 0,this.refInterval=void 0,this.refIndexCache=void 0,this.refPrefixCache=void 0}async pathPosition(e){let t=await this.db.findPath(e);if(!t)throw new Error(`Cannot find a path covering offset ${e.fragment} of ${le(e)}`);if(!t.isIndexed)throw new Error(`The fragment of ${le(t.name)} at ${t.name.fragment} has not been indexed for random access`);let n=e.fragment-t.name.fragment,s=await this.db.indexedPosition(t.handle,n);if(!s)throw new Error(`The fragment of ${le(t.name)} at ${t.name.fragment} has not been indexed for random access`);return this.findPathPosition(t,n,s.pathOffset,s.pos)}async findPathPosition(e,t,n,s){let r=n,o=s;for(;;){await this.ensureNode(R(o.node));let a=this.record(o.node);if(r+a.sequenceLen>t)return{position:{seqOffset:t,handle:o.node,nodeOffset:t-r,gbwtOffset:o.offset},name:e.name,handle:e.handle};r+=a.sequenceLen;let h=a.gbwt().lf(o.offset);if(!h)throw new Error(`The fragment of ${le(e.name)} at ${e.name.fragment} does not contain offset ${t}`);o=h}}async aroundPosition(e,t,n){let s=R(e);await this.ensureNode(s);let r=this.record(e),o=Ne(e),a=new Ue;return a.push(t,s,We(o)),a.push(r.sequenceLen-t-1,s,Ke(o)),this.insertContext(a,n)}prefetchReferenceWalk(e,t){return this.prefetchReferenceRange(e.handle,e.position.seqOffset,e.position.seqOffset+t)}async prefetchReferenceRange(e,t,n){let[s,r]=await Promise.all([this.db.indexedPosition(e,t),this.db.indexedPosition(e,n)]);if(s&&r){let o=s.pos.node,a=r.pos.node;if(!await this.db.prefetchRecords([[Math.min(o,a),Math.max(o,a)+1]])){let c=await this.db.indexedPositionsBetween(e,t,n);await this.db.prefetchRecords(ks(c.map(d=>d.pos.node)).map(([d,f])=>[d,f+2]),!0)}}return s}async aroundInterval(e,t,n){if(!(t>0))throw new Error("Interval length must be greater than 0");this.walkedBp=0;try{return await this.walkInterval(e,t,n)}catch(s){throw s instanceof we&&s.windowBp===void 0?new we(s.limit,{windowBp:t,walkedBp:this.walkedBp}):s}}get referenceWalkedBp(){return this.walkedBp}async walkInterval(e,t,n){let s={node:e.handle,offset:e.gbwtOffset},r=e.nodeOffset,o=t,a=new Ue;for(;;){let h=R(s.node),c=Ne(s.node);this.walkedBp=t-o,await this.ensureNode(h);let d=this.record(s.node);if(r>=d.sequenceLen)throw new Error(`Offset ${r} in node ${h} of length ${d.sequenceLen}`);a.push(r,h,We(c));let f=d.sequenceLen-r;if(o<=f){a.push(o===f?0:f-o-1,h,Ke(c));break}a.push(0,h,Ke(c));let l=d.gbwt().lf(s.offset);if(!l)throw new Error(`No successor for GBWT position (${s.node}, ${s.offset})`);s=l,r=0,o-=f}return this.walkedBp=t,this.insertContext(a,n)}async aroundNodes(e,t){let n=new Ue;for(let s of e)await this.ensureNode(s),n.push(0,s,"left"),n.push(0,s,"right");return this.insertContext(n,t)}async insertContext(e,t){this.clearPaths(),this.snarlMode="none",this.snarlFills=[],this.snarlNodes.clear(),this.stats.snarls={fills:0,inserted:0};let n=new Set,s=new Set;for(let o of this.records.keys())s.add(R(o));let r=0;for(;e.size>0;){let[o,a,h]=e.pop(),c=`${a}:${h}`;if(n.has(c))continue;n.add(c),s.delete(a),this.hasNode(a)||(await this.addNode(a),r+=1);let d=en(h);if(!n.has(`${a}:${d}`)){let g=this.record(ue(a,tn(h))),p=o+g.sequenceLen-1;p<=t&&e.push(p,a,d)}let f=this.record(ue(a,nn(h))),l=o+1;if(l<=t)for(let g of f.successors()){let p=R(g),u=We(Ne(g));n.has(`${p}:${u}`)||e.push(l,p,u)}}for(let o of s)this.records.delete(ue(o,"forward")),this.records.delete(ue(o,"reverse"));return{inserted:r,removed:s.size}}async betweenNodes(e,t){return(await this.fillBetween(e,t)).inserted.length}async fillBetween(e,t){this.clearPaths();let n=[e,ne(t)],s=new Set([R(e),R(t)]),r=[];for(;n.length>0;){let o=n.pop(),a=R(o);this.hasNode(a)||(await this.addNode(a),r.push(a));for(let h of this.record(o).successors()){let c=R(h);s.has(c)||(n.push(h,ne(h)),s.add(c))}}return{inserted:r,nodes:s.size-2}}async extractSnarls(e){let t=0;this.snarlMode=e;for(let[n,s]of await this.overlappingSnarls(e)){let{inserted:r,nodes:o}=await this.fillBetween(n,s),a=R(n),h=R(s);this.snarlFills.push({low:Math.min(a,h),high:Math.max(a,h),nodes:o,inserted:r.length});for(let c of r)this.snarlNodes.add(c);t+=r.length}return this.stats.snarls={fills:this.snarlFills.length,inserted:this.snarlNodes.size},t}async overlappingSnarls(e){let t=[];if(e!=="none"){let n=!1;for(let s of this.sortedHandles()){let r=this.record(s),o=r.next;o!==void 0&&(n=!0,this.hasHandle(o)?qe(s,o)&&t.push([s,o]):e==="overlapping"&&this.isSnarlEntryInSubgraph(r)&&t.push([s,o]))}if(!n&&e==="overlapping"&&await this.db.hasChainLinks()){let s=await this.findCoveringSnarl();s&&t.push(s)}}return t}isSnarlEntryInSubgraph(e){let t=e.successors(),n=t.find(s=>this.hasHandle(s));return n===void 0?!1:t.length>1||this.record(ne(n)).successors().length>1}recordReader(e){let t=new Map;return async n=>{let s=this.records.get(n);if(s)return s;let r=t.get(n);if(!r){if(r=await this.db.getRecord(n),e?.(),!r)throw new Error(`Node record ${n} is missing from the database`);t.set(n,r)}return r}}async findCoveringSnarl(){let e=this.recordReader(),t=async h=>{let c=h.successors(),d=c[0];return d===void 0?!1:c.length>1||(await e(ne(d))).successors().length>1},n=async h=>{let c=await e(ne(h));return c.next!==void 0?await t(c)?{kind:"snarl-exit",snarl:[ne(h),c.next]}:{kind:"chain"}:(await e(h)).next!==void 0?{kind:"chain"}:{kind:"regular"}},s=new Set,r=this.sortedHandles().flatMap(h=>this.record(h).successors()),o,a=!1;for(;!a&&r.length>0;){let h=r.shift(),c=R(h);if(!this.hasHandle(h)&&!s.has(c)){s.add(c);let d=await n(h);if(d.kind==="snarl-exit")o=d.snarl,a=!0;else if(d.kind==="chain")a=!0;else for(let f of["forward","reverse"])r.push(...(await e(ue(c,f))).successors())}}return o}extractPaths(e,t){if(this.clearPaths(),t==="none")return;let n=e?.position;this.refPath=e?.name,this.refHandle=e?.handle;let s=this.sortedHandles(),r=s.length,o=new Map;s.forEach((y,k)=>o.set(y,k));let a=new Int32Array(r+1),h=new Int32Array(r),c=[];for(let y=0;y<r;y++){let k=this.record(s[y]),v=k.gbwt().decompressArrays();h[y]=k.sequenceLen,c.push(v),a[y+1]=a[y]+v.nodes.length}let d=a[r],f=new Int32Array(d),l=new Int32Array(d),g=new Uint8Array(d);for(let y=0;y<r;y++){let k=c[y];f.set(k.nodes,a[y]),l.set(k.offsets,a[y])}c.length=0;for(let y=0;y<d;y++){let k=o.get(f[y]);k===void 0?f[y]=-1:(f[y]=k,g[a[k]+l[y]]=1)}let p=n===void 0?void 0:o.get(n.handle),u=n?.gbwtOffset,m,E=(y,k,v)=>{let O=[],B=0,D=0,q=-1,$=y,N=k;for(;;){$===p&&N===u&&(q=B),v&&(v.push(s[$]),O.push(N)),B+=1,D+=h[$];let Q=a[$]+N,Z=f[Q];if(Z<0)break;N=l[Q],$=Z}return{offsets:O,len:D,refAt:q,last:$}},I=(y,k,v,O)=>{O>=0&&(this.refId=this.paths.length,m=O),this.paths.push({path:y,offsets:k,len:v,weight:void 0,identity:void 0})},w=new Int32Array(r);for(let y=0;y<r;y++){let k=s[y];if(!z(k)){let v=a[y],O=a[y+1]-v;for(let B=0;B<O;B++)if(g[v+B]===0){let D=[],{offsets:q,len:$,refAt:N,last:Q}=E(y,B,D),Z=s[Q];if(N>=0||Me(k,Z)){if(I(D,q,$,N),!z(Z)){let S=o.get(ne(Z));w[S]=w[S]+1}}else this.twinStarts.add(Pe({node:k,offset:B}))}}}for(let y=0;y<r;y++){let k=s[y];if(z(k)){let v=a[y],O=a[y+1]-v,B=0;for(let q=0;q<O;q++)g[v+q]===0&&(B+=1);let D=(p===void 0||m!==void 0)&&B===w[y];for(let q=0;q<O;q++)if(g[v+q]===0){let $=D?void 0:E(y,q,void 0);if($&&($.refAt>=0||Me(k,s[$.last]))){let N=[],{offsets:Q,len:Z,refAt:S}=E(y,q,N);I(N,Q,Z,S)}else this.twinStarts.add(Pe({node:k,offset:q}))}}}let b=this.refId===void 0?void 0:this.paths[this.refId];if(this.paths.sort((y,k)=>y.path[0]-k.path[0]||y.offsets[0]-k.offsets[0]),b&&(this.refId=this.paths.indexOf(b)),n){if(m===void 0||this.refId===void 0)throw this.clearPaths(),new Error("Could not find the reference path");let y=this.paths[this.refId],k=n.nodeOffset;for(let O of y.path.slice(0,m))k+=this.record(O).sequenceLen;let v=n.seqOffset-k;this.refInterval=[v,v+y.len],y.identity={pathHandle:e.handle,name:e.name,orientation:"forward",hapStart:v,hapEnd:v+y.len}}if(t==="distinct")this.distinctPaths(!0);else if(t==="reference-only"){if(this.refId===void 0)throw new Error("Reference path is required for reference-only output");this.paths=[this.paths[this.refId]],this.refId=0}}distinctPaths(e){let t=this.refId===void 0?void 0:this.paths[this.refId],n=t?.path,s=n&&!_e(n)?ze(n):void 0,r=c=>s!==void 0&&Ot(c,s)===0||_e(ze(c)),o=e&&this.db.hasHaplotypeIndex;this.twinDeferred=!1,this.paths.sort((c,d)=>Ot(c.path,d.path)||c.len-d.len||(c===t?-1:d===t?1:0));let a=[],h;for(let c of this.paths){let d=a[a.length-1],f=o&&c!==t&&r(c.path);this.twinDeferred||=f,d&&Ot(d.path,c.path)===0&&!f?d.weight=(d.weight??1)+(c.weight??1):(c===t&&(h=a.length),a.push({...c,weight:c.weight??1}))}this.paths=a,this.refId=h}mergeDistinct(){this.twinDeferred?this.settleDeferred():this.distinctPaths(!1)}settleDeferred(){this.twinDeferred&&(this.unsettled={paths:[...this.paths],refId:this.refId},this.distinctPaths(!1))}dropTwins(){let e=this.refId===void 0?void 0:this.paths[this.refId],t=this.refInterval,n=o=>`${o.pathHandle}:${o.hapStart}-${o.hapEnd}`,s=new Set;e?.identity&&t&&s.add(n({...e.identity,hapStart:t[0],hapEnd:t[1]}));for(let o of this.paths)o!==e&&o.identity?.orientation==="forward"&&s.add(n(o.identity));let r=this.paths.filter(o=>o===e||o.identity?.orientation!=="reverse"||!s.has(n(o.identity)));r.length<this.paths.length&&(this.paths=r,this.refId=e===void 0?void 0:r.indexOf(e)),this.twinDeferred&&this.distinctPaths(!1)}keepHaplotypes(e){if(this.paths.some(o=>o.weight!==void 0))throw new Error("keepHaplotypes needs one walk per haplotype: extract with haplotypes 'all', then call mergeDistinct()");let t=this.paths.filter((o,a)=>a!==this.refId&&o.identity===void 0).length;if(t>0)throw new Error(`${t} 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`);let n=this.refId===void 0?void 0:this.paths[this.refId],s=this.paths.filter((o,a)=>a===this.refId||o.identity!==void 0&&e(o.identity.name)),r=new Set;for(let o of s)for(let a of o.path)r.add(R(a));for(let o of[...this.records.keys()])r.has(R(o))||this.records.delete(o);this.paths=s,this.refId=n===void 0?void 0:s.indexOf(n)}async extractChosenPaths(e,t,n,s){this.clearPaths();let r=e.position.seqOffset,o=await xn({db:this.db,records:this.records,referenceHandle:e.handle,referencePos:{node:e.position.handle,offset:e.position.gbwtOffset},referenceLeft:r-e.position.nodeOffset,window:{start:r,end:r+t},context:s,snarls:{mode:this.snarlMode,fills:this.snarlFills,inserted:this.snarlNodes},keep:n,signal:this.signal,prefetchReferenceRange:(d,f,l)=>this.prefetchReferenceRange(d,f,l)});if(this.stats.keep=o.stats,o.stats.fallback!==void 0)return!1;let a=await this.db.pathsByHandle(),h=d=>({path:d.handles,offsets:d.offsets,len:d.len,weight:void 0,identity:{pathHandle:d.pathHandle,name:d===o.reference?e.name:a.get(d.pathHandle).name,orientation:d.orientation,hapStart:d.hapStart,hapEnd:d.hapEnd}}),c=[o.reference,...o.pieces].sort(bn);return this.paths=c.map(h),this.refId=c.indexOf(o.reference),this.refPath=e.name,this.refHandle=e.handle,this.refInterval=[o.reference.hapStart,o.reference.hapEnd],this.dropTwins(),!0}async identifyPaths(){if(!this.db.hasHaplotypeIndex)throw new Error("The database has no HaplotypeSamples table; run gbz-haplotype-index on it");this.unsettled&&({paths:this.paths,refId:this.refId}=this.unsettled,this.unsettled=void 0,this.twinDeferred=!0);let e=await this.db.haplotypeSampleGap()??4096,t=kt(this.sortedHandles());if(t.length===0)return;let n=new Map,s=await Promise.all(t.map(([u,m])=>this.db.haplotypeSamplesInRange(u,m)));for(let u of s.flat())n.set(Pe(u),u);let r=u=>{let m=0,E=t.length-1;for(;m<E;){let w=m+E+1>>1;t[w][0]<=u?m=w:E=w-1}let I=t[m];return I[0]<=u&&u<=I[1]},o=new Map;this.paths.forEach((u,m)=>{u.path.length>0&&m!==this.refId&&o.set(Pe(rt(u,0)),m)});let a=this.stats.identification;a.interval=e,a.scans=t,a.windowSamples=n.size,this.paths.forEach((u,m)=>{m!==this.refId&&a.fragmentLengths.push(u.len)});let h=this.recordReader(()=>{this.stats.identificationFetches+=1,a.graphFetches+=1}),c=u=>(a.graphLookups+=1,h(u)),d=async(u,m)=>{if(r(u.node))return n.get(Pe(u));this.stats.identificationFetches+=1,a.companionSeeks+=1,m.seeks+=1;let E=await this.db.haplotypeSampleAt(u.node,u.offset);return E||(a.companionMisses+=1),E},f=new Map,l=async u=>{let m=f.get(u);if(!m){let E=await this.db.getPath(u);if(!E)throw new Error(`Path ${u} is missing from the database`);m=E.name,f.set(u,m)}return m},g=(u,m,E)=>u.orientation==="forward"?{pathHandle:u.pathHandle,orientation:"forward",base:u.pathOffset-m}:{pathHandle:u.pathHandle,orientation:"reverse",base:u.pathOffset+m+E},p=(u,m)=>u.orientation==="forward"?{pathHandle:u.pathHandle,orientation:"forward",base:u.hapStart-m}:{pathHandle:u.pathHandle,orientation:"reverse",base:u.hapEnd+m};for(let u=0;u<this.paths.length;u++){let m=this.paths[u];if(u===this.refId||m.identity)continue;let E=[],I=new Set,w={fragments:0,steps:0,seeks:0,reentries:0,twinLandings:0,end:"endmarker",pathHandle:void 0};a.chains.push(w);let b,y=0,k=u,v;for(;b===void 0;){if(this.signal?.throwIfAborted(),k!==void 0){if(I.has(k)){w.end="cycle";break}I.add(k);let $=this.paths[k];E.push({index:k,startBp:y}),w.fragments+=1;let N=y;for(let Z=0;Z<$.path.length;Z++){let S=rt($,Z),M=n.get(Pe(S)),P=this.record(S.node).sequenceLen;if(M){b=g(M,N,P);break}N+=P}if(y+=$.len,b){w.end="in-fragment sample";break}let Q=rt($,$.path.length-1);v=this.record(Q.node).gbwt().lf(Q.offset),k=void 0}if(v===void 0||v.node===0){w.end="endmarker";break}let O=Pe(v),B=o.get(O);if(B!==void 0){let $=this.paths[B].identity;if($){b=p($,y),w.end="identified sibling";break}k=B;continue}this.records.has(v.node)&&(w.reentries+=1),this.twinStarts.has(O)&&(w.twinLandings+=1);let D=await d(v,w),q=await c(v.node);if(D){b=g(D,y,q.sequenceLen),w.end="out-of-window sample";break}if(this.stats.identificationSteps+=1,w.steps+=1,y-E[E.length-1].startBp>4*e+4*q.sequenceLen){w.end="bound";break}y+=q.sequenceLen,v=q.gbwt().lf(v.offset)}if(b){w.pathHandle=b.pathHandle;let O=await l(b.pathHandle);for(let{index:B,startBp:D}of E){let q=this.paths[B];q.identity=b.orientation==="forward"?{pathHandle:b.pathHandle,name:O,orientation:"forward",hapStart:b.base+D,hapEnd:b.base+D+q.len}:{pathHandle:b.pathHandle,name:O,orientation:"reverse",hapStart:b.base-D-q.len,hapEnd:b.base-D}}}}this.dropTwins()}refIndex(e){if(this.refIndexCache===void 0){let t=new Map;e.forEach((n,s)=>{let r=t.get(n);r?r.push(s):t.set(n,[s])}),this.refIndexCache=t}return this.refIndexCache}refPrefix(e){if(this.refPrefixCache===void 0){let t=[0];e.forEach((n,s)=>{t.push(t[s]+this.record(n).sequenceLen)}),this.refPrefixCache=t}return this.refPrefixCache}orderedMatches(e,t){let n=this.refIndex(t),s=new Int32Array(e.length),r=new Int32Array(e.length),o=0,a=-1;for(let h=0;h<e.length;h++){let c=n.get(e[h]);if(c){let d=xs(c,a);if(d===void 0)return;s[o]=h,r[o]=d,o+=1,a=d}}return{pathAt:s,refAt:r,count:o}}pathLen(e){let t=0;for(let n of e)t+=this.record(n).sequenceLen;return t}prefixMatches(e,t){let n=0,s=0,r=0,o=0,a=0;for(;s<e.length&&r<t.length;){let h=this.record(e[s]).sequence,c=this.record(t[r]).sequence;for(;o<h.length&&a<c.length;){if(h[o]!==c[a])return n;o+=1,a+=1,n+=1}o===h.length&&(s+=1,o=0),a===c.length&&(r+=1,a=0)}return n}suffixMatches(e,t){let n=0,s=0,r=0,o=0,a=0;for(;s<e.length&&r<t.length;){let h=this.record(e[e.length-s-1]).sequence,c=this.record(t[t.length-r-1]).sequence;for(;o<h.length&&a<c.length;){if(h[h.length-o-1]!==c[c.length-a-1])return n;o+=1,a+=1,n+=1}o===h.length&&(s+=1,o=0),a===c.length&&(r+=1,a=0)}return n}align(e,t,n){let s=this.pathLen(e),r=this.pathLen(t),o=this.prefixMatches(e,t),a=this.suffixMatches(e,t);o+a>s&&(a=s-o),o+a>r&&(a=r-o),K(n,"M",o),Ln(n,s-o-a,r-o-a),K(n,"M",a)}sharedWeight(e,t){let n=this.refIndex(t),s=0;for(let r of e)n.has(r)&&(s+=this.record(r).sequenceLen);return s}editsAgainst(e,t){let n=this.orderedMatches(e,t);n?this.stats.orderedAlignments+=1:this.stats.lcsAlignments+=1;let s=n??ys(Sn(e,t,f=>this.record(f).sequenceLen)[0]),r=[],o=this.refPrefix(t),a=(f,l,g,p)=>{f===l?K(r,"D",o[p]-o[g]):g===p?K(r,"I",this.pathLen(e.slice(f,l))):this.align(e.slice(f,l),t.slice(g,p),r)},h=0,c=0,d=0;for(let f=0;f<s.count;f++){let l=s.pathAt[f],g=s.refAt[f];(c!==l||d!==g)&&a(c,l,d,g);let p=this.record(e[l]).sequenceLen;K(r,"M",p),h+=p,c=l+1,d=g+1}return a(c,e.length,d,t.length),{edits:r,matched:h,matches:s}}alignment(e){let t=this.paths[e];if(this.refId===void 0||e===this.refId||!t)return;let n=this.paths[this.refId].path,s;if(_e(n)&&(t.identity===void 0||!_e(ze(t.path))))s={...this.editsAgainst(t.path,n),flipped:!1};else{let r=ze(t.path),o=this.sharedWeight(t.path,n);if(this.sharedWeight(r,n)===0)s={...this.editsAgainst(t.path,n),flipped:!1};else if(o===0)s={...this.editsAgainst(r,n),flipped:!0};else{let h=this.editsAgainst(t.path,n),c=this.editsAgainst(r,n);s=c.matched>h.matched?{...c,flipped:!0}:{...h,flipped:!1}}}return s}alignToRef(e){return this.settleDeferred(),this.alignment(e)?.edits.map(([t,n])=>`${n}${t}`).join("")}alignments(){this.settleDeferred();let e=this.referenceInterval;if(this.refId===void 0||!e)throw new Error("Alignments need a reference path");let t=this.paths[this.refId].path,n=this.refPrefix(t)[t.length],s=(d,f,l,g)=>{let p=Ms(d),u=this.paths[l[0]],m=this.paths[l[l.length-1]],E=u.identity,I=E?.orientation==="forward",[w,b]=I?[u,m]:[m,u];return{strand:f,refStart:e.start+p.leading,refEnd:e.start+n-p.trailing,edits:p.edits,weight:u.weight,path:l.flatMap(y=>this.paths[y].path),start:rt(u,0),pieces:l,soloAligned:g,identity:E===void 0?void 0:{pathHandle:E.pathHandle,name:E.name,hapStart:E.name.fragment+w.identity.hapStart,hapEnd:E.name.fragment+b.identity.hapEnd,walkForward:I}}},r=d=>d.soloAligned.reduce((f,l)=>f+l,0),o=d=>d.pieces.reduce((f,l)=>f+this.paths[l].len,0),a=d=>2*r(d)>=o(d),h=d=>{let f=d[0],l=d[d.length-1],g=f.identity.walkForward;if(d.some((N,Q)=>N.strand!==f.strand||N.identity.walkForward!==g||Q>0&&N.identity.hapStart<d[Q-1].identity.hapEnd))return;let p=g?d:[...d].reverse(),u=p.flatMap(N=>N.pieces),m=p.flatMap(N=>N.soloAligned),E=f.strand==="+"!==g,I=u.map(N=>this.paths[N]),w=I.slice(1).map((N,Q)=>{let Z=I[Q].identity;return g?N.identity.hapStart-Z.hapEnd:Z.hapStart-N.identity.hapEnd}),b=E?[...I].reverse():I,y=E?[...w].reverse():w,k=b.flatMap(N=>E?ze(N.path):N.path),{edits:v}=this.editsAgainst(k,t),O=On(v,b.map(N=>N.len)),B=new Map((E?[...u].reverse():u).map((N,Q)=>[N,O[Q]])),D=N=>2*N.pieces.reduce((Q,Z)=>Q+B.get(Z),0)>=r(N);if(!D(f)||!D(l))return;let q=[],$=0;return b.slice(0,-1).forEach((N,Q)=>{$+=N.len,q.push([$,y[Q]])}),s(As(v,q),f.strand,u,m)},c=[];return this.paths.forEach((d,f)=>{if(f===this.refId)return;let{edits:l,flipped:g}=this.alignment(f),p=d.identity,u=p?p.orientation==="forward"!==g:!g;c.push(s(l,u?"+":"-",[f],On(l,[d.len])))}),Es(c,a,h).map(d=>{let{edits:f,identity:l,pieces:g,soloAligned:p,...u}=d,m={...u,cigar:Ps(f)};return l?{...m,resolved:!0,name:l.name,label:le({...l.name,fragment:l.hapStart,end:l.hapEnd}),pathHandle:l.pathHandle,hapStart:l.hapStart,hapEnd:l.hapEnd}:{...m,resolved:!1}})}pairAlignments(e){let{target:t,query:n,...s}=e,r=this.paths.flatMap(d=>{let{identity:f}=d;return f?[{name:f.name,start:f.name.fragment+f.hapStart,steps:at(d,f)}]:[]}),o=d=>f=>f.sample===d.sample&&f.haplotype===d.haplotype,a=o(t),h=n?o(n):d=>!a(d),c=d=>this.record(ue(d,"forward")).sequence;return r.filter(d=>a(d.name)).flatMap(d=>r.filter(f=>h(f.name)).flatMap(f=>Hn({...s,query:f.steps,target:d.steps,sequenceOf:c}).map(l=>({query:f.name,queryStart:f.start+l.queryStart,queryEnd:f.start+l.queryEnd,strand:l.strand,target:d.name,targetStart:d.start+l.targetStart,targetEnd:d.start+l.targetEnd,cigar:Cn(l.edits),matches:l.edits.reduce((g,[p,u])=>g+(p==="="?u:0),0),columns:l.edits.reduce((g,[,p])=>g+p,0),sharedBases:l.sharedBases}))))}canonicalEdges(e){let t=[];for(let n of["forward","reverse"]){let s=ue(e,n);for(let r of this.record(s).successors())this.hasHandle(r)&&qe(s,r)&&t.push([n==="reverse"?1:0,R(r),z(r)?1:0])}return t.sort((n,s)=>n[0]-s[0]||n[1]-s[1]||n[2]-s[2]),t.filter((n,s)=>s===0||n[0]!==t[s-1][0]||n[1]!==t[s-1][1]||n[2]!==t[s-1][2])}async stableName(){let e=new TextEncoder,t=[];for(let n of this.sortedHandles())if(!z(n)){let s=R(n),r=`S ${s} ${this.record(n).sequence}
|
|
2
|
+
`;for(let[o,a,h]of this.canonicalEdges(s))r+=`L ${s} ${o?"-":"+"} ${a} ${h?"-":"+"}
|
|
3
|
+
`;t.push(e.encode(r))}return wn(t)}async toGFA(e={}){this.settleDeferred();let t=e.cigar??!1,n=[this.refPath?`H VN:Z:1.1 RS:Z:${this.refPath.sample}`:"H VN:Z:1.1",...un(pn(await this.stableName(),await this.db.graphName()))],s=this.sortedHandles();for(let c of s)z(c)||n.push(`S ${R(c)} ${this.record(c).sequence}`);let r=c=>z(c)?"-":"+";for(let c of s)for(let d of this.record(c).successors())this.hasHandle(d)&&qe(c,d)&&n.push(`L ${R(c)} ${r(c)} ${R(d)} ${r(d)} 0M`);let o=(c,d,f,l,g)=>{let p=at(c,d).map(E=>`${z(E)?"<":">"}${R(E)}`).join(""),u=c.weight===void 0?"":` WT:i:${c.weight}`,m=g===void 0?"":` CG:Z:${g}`;return`W ${f.sample} ${f.haplotype} ${f.contig} ${f.fragment} ${l} ${p}${u}${m}`},a=this.refPath?.contig??"unknown";this.refId!==void 0&&this.refPath&&this.refInterval&&n.push(o(this.paths[this.refId],void 0,{...this.refPath,fragment:this.refPath.fragment+this.refInterval[0]},this.refPath.fragment+this.refInterval[1],void 0));let h=1;return this.paths.forEach((c,d)=>{if(d!==this.refId){let f=e.names!=="anonymous"?c.identity:void 0,l=t?this.alignToRef(d):void 0;n.push(f?o(c,f,{...f.name,fragment:f.name.fragment+f.hapStart},f.name.fragment+f.hapEnd,l):o(c,void 0,{sample:"unknown",contig:a,haplotype:h,fragment:0},c.len,l)),h+=1}}),`${n.join(`
|
|
4
|
+
`)}
|
|
5
|
+
`}outputPaths(e){this.settleDeferred();let t=e.cigar??!1,n=[],s=this.refPath?.contig??"unknown";if(this.refId!==void 0&&this.refPath&&this.refInterval){let o={...this.refPath,fragment:this.refPath.fragment+this.refInterval[0]};n.push({info:this.paths[this.refId],identity:void 0,name:le({...o,end:this.refPath.fragment+this.refInterval[1]}),cigar:void 0})}let r=1;return this.paths.forEach((o,a)=>{if(a===this.refId)return;let h=e.names!=="anonymous"?o.identity:void 0;n.push({info:o,identity:h,name:h?le({...h.name,fragment:h.name.fragment+h.hapStart,end:h.name.fragment+h.hapEnd}):le({sample:"unknown",contig:s,haplotype:r,fragment:0,end:o.len}),cigar:t?this.alignToRef(a):void 0}),r+=1}),n}*outputEdges(){for(let e of this.sortedHandles())for(let t of this.record(e).successors())this.hasHandle(t)&&qe(e,t)&&(yield[e,t])}toSubgraphJson(e={}){let t=this.sortedHandles().filter(r=>!z(r)).map(r=>({id:String(R(r)),sequence:this.record(r).sequence})),n=[];for(let[r,o]of this.outputEdges())n.push({from:String(R(r)),from_is_reverse:z(r),to:String(R(o)),to_is_reverse:z(o)});let s=this.outputPaths(e).map(r=>vs(r.info,r.identity,r.name,r.cigar));return{nodes:t,edges:n,paths:s}}toCompactSubgraph(e={}){let t=this.sortedHandles().filter(o=>!z(o)),n=new Int32Array(t.length),s=[];t.forEach((o,a)=>{n[a]=R(o),s.push(this.record(o).sequence)});let r=[];for(let[o,a]of this.outputEdges())r.push(o,a);return{nodeIds:n,nodeSequences:s,edges:Int32Array.from(r),paths:this.outputPaths(e).map(o=>({name:o.name,weight:o.info.weight,cigar:o.cigar,steps:Int32Array.from(at(o.info,o.identity))}))}}};function at(i,e){return e?.orientation==="reverse"?i.path.map(t=>ne(t)).reverse():i.path}function vs(i,e,t,n){return{name:t,...i.weight===void 0?{}:{weight:i.weight},...n===void 0?{}:{cigar:n},path:at(i,e).map(s=>({id:String(R(s)),is_reverse:z(s)}))}}function Ot(i,e){let t=Math.min(i.length,e.length);for(let n=0;n<t;n++){let s=i[n],r=e[n];if(s!==r)return s<r?-1:1}return i.length-e.length}function K(i,e,t){if(t===0)return;let n=i[i.length-1];n?.[0]===e?n[1]+=t:i.push([e,t])}function it(i){return i===0?0:6+(i-1)}function Ln(i,e,t){if(e===0)K(i,"D",t);else if(t===0)K(i,"I",e);else{let n=Math.min(e,t),s=4*n+it(e-n)+it(t-n),r=it(e)+it(t);s<=r?(K(i,"M",n),K(i,"I",e-n),K(i,"D",t-n)):(K(i,"I",e),K(i,"D",t))}}function Ms(i){let e=0;for(;e<i.length&&i[e][0]!=="M";)e+=1;if(e===i.length){let a=i.filter(([c])=>c==="I"),h=i.filter(([c])=>c==="D").reduce((c,[,d])=>c+d,0);return{edits:a.map(([c,d])=>[c,d]),leading:0,trailing:h}}let t=i.length;for(;i[t-1][0]!=="M";)t-=1;let n=a=>({inserted:a.reduce((h,[c,d])=>h+(c==="I"?d:0),0),deleted:a.reduce((h,[c,d])=>h+(c==="D"?d:0),0)}),s=n(i.slice(0,e)),r=n(i.slice(t)),o=[];K(o,"I",s.inserted);for(let[a,h]of i.slice(e,t))K(o,a,h);return K(o,"I",r.inserted),{edits:o,leading:s.deleted,trailing:r.deleted}}function On(i,e){let t=e.map(()=>0),n=e.length-1,s=0,r=e[0],o=0;for(let[a,h]of i){if(a==="D")continue;let c=h;for(;c>0;){for(;s<n&&o>=r;)s+=1,r+=e[s];let d=s<n?Math.min(c,r-o):c;a==="M"&&(t[s]+=d),o+=d,c-=d}}return t}function As(i,e){let t=[],n=0,s=0;for(let[r,o]of i){if(r==="D"){K(t,r,o);continue}let a=n;for(;s<e.length&&e[s][0]<n+o;){let[h,c]=e[s];K(t,r,h-a),K(t,"I",c),a=h,s+=1}K(t,r,n+o-a),n+=o}for(;s<e.length;s++)K(t,"I",e[s][1]);return t}function Ps(i){return i.map(([e,t])=>`${t}${e}`).join("")}function Ie(i,e,t=0){if(!Number.isSafeInteger(e)||e<t)throw new Error(`${i} must be a whole number${t>0?` of at least ${t}`:""}, not ${e}`);return e}function ct(i){return Ie("context",i.context??100)}function dt(i,e){return e.limit!==void 0&&Ie("limit",e.limit),ht.create(i,e)}async function Bn(i,e){let t=ct(e),n=dt(i,e),s=await n.pathPosition(He($e(e.path),Ie("offset",e.offset)));return await n.aroundPosition(s.position.handle,s.position.nodeOffset,t),await n.extractSnarls(e.snarls??"none"),n.extractPaths(s,e.haplotypes??"all"),n}async function Rs(i,e){let t=Ie("start",e.start),n=Ie("end",e.end),s=ct(e),r=dt(i,e);try{let o=await r.pathPosition(He($e(e.path),t));return await r.prefetchReferenceWalk(o,n-t),await r.aroundInterval(o.position,n-t,s),await r.extractSnarls(e.snarls??"none"),{subgraph:r,reference:o}}catch(o){throw o instanceof we&&o.windowBp===void 0?new we(o.limit,{windowBp:n-t,walkedBp:r.referenceWalkedBp??0}):o}}async function Lt(i,e){let{keep:t}=e,n=e.haplotypes??"all",s=n==="all"||n==="distinct";if(t!==void 0&&s&&!i.hasHaplotypeIndex)throw new Error("keep needs the haplotype index: this database cannot name its walks");let{subgraph:r,reference:o}=await Rs(i,e);return t===void 0||!s?(r.extractPaths(o,n),r):(await r.extractChosenPaths(o,e.end-e.start,t,ct(e))||(r.extractPaths(o,"all"),await r.identifyPaths()),r.keepHaplotypes(t),n==="distinct"&&r.mergeDistinct(),r)}async function Tn(i,e){let t=e.haplotypes??"all",n=e.snarls??"none";if(t==="reference-only")throw new Error("Cannot output a reference path in a node-based query");if(n==="overlapping"&&new Set(e.nodeIds).size>1)throw new Error("Overlapping snarls cannot be extracted for a node-based query with multiple nodes");let s=ct(e);for(let o of e.nodeIds)Ie("node id",o,1);let r=dt(i,e);return await r.aroundNodes(e.nodeIds,s),await r.extractSnarls(n),r.extractPaths(void 0,t),r}async function _n(i,e){let t=e.haplotypes??"all";if(t==="reference-only")throw new Error("Cannot output a reference path in a node-based query");let n=dt(i,e);return await n.betweenNodes(Ie("startHandle",e.startHandle,2),Ie("endHandle",e.endHandle,2)),n.extractPaths(void 0,t),n}function ye(i,e){let t=0;for(let s=0;s<8;s++){let r=i[e+s];if(r===void 0)throw new Error("SQLite varint runs past the end of the buffer");if(t=t*128+(r&127),(r&128)===0){if(s===7&&!Number.isSafeInteger(t))throw new Error("SQLite varint exceeds the safe integer range");return[t,e+s+1]}}let n=i[e+8];if(n===void 0)throw new Error("SQLite varint runs past the end of the buffer");if(t=t*256+n,!Number.isSafeInteger(t))throw new Error("SQLite varint exceeds the safe integer range");return[t,e+9]}function Ns(i,e,t){switch(t){case 1:return i.getInt8(e);case 2:return i.getInt16(e);case 3:return i.getInt8(e)<<16|i.getUint16(e+1);case 4:return i.getInt32(e);case 6:return i.getInt16(e)*4294967296+i.getUint32(e+2);default:{let n=i.getBigInt64(e);if(n>BigInt(Number.MAX_SAFE_INTEGER)||n<BigInt(Number.MIN_SAFE_INTEGER))throw new Error(`SQLite integer ${n} exceeds the safe integer range`);return Number(n)}}}var qs=new TextDecoder;function ft(i){let[e,t]=ye(i,0),n=[],s=t;for(;s<e;){let[a,h]=ye(i,s);n.push(a),s=h}let r=new DataView(i.buffer,i.byteOffset,i.byteLength),o=e;return n.map(a=>{if(a===0)return null;if(a>=1&&a<=6){let h=a<=4?a:a===5?6:8,c=Ns(r,o,h);return o+=h,c}if(a===7){let h=r.getFloat64(o);return o+=8,h}if(a===8)return 0;if(a===9)return 1;if(a>=12){let h=a-12>>1,c=i.subarray(o,o+h);return o+=h,a%2===0?c:qs.decode(c)}throw new Error(`SQLite serial type ${a} is reserved`)})}var pt=2,ut=5,Dn=10,lt=13;function Fn(i,e){return i[e]*256+i[e+1]}function ke(i,e){return i[e]*16777216+i[e+1]*65536+i[e+2]*256+i[e+3]}function $s(i,e){let t=i[e];if(t!==pt&&t!==ut&&t!==Dn&&t!==lt)throw new Error(`SQLite page has unknown b-tree type ${t}`);let n=t===pt||t===ut;return{type:t,cellCount:Fn(i,e+3),rightChild:n?ke(i,e+8):0,cellPointers:e+(n?12:8)}}function be(i,e,t){return Fn(i,e.cellPointers+2*t)}var Hs=4096,wt=class{usable;pager;decodedIndexPages=new Map;tableDepths=new Map;constructor(e,t){this.pager=e,this.usable=e.pageSize-t}localPayloadSize(e,t){let n=this.usable,s=t?Math.floor((n-12)*64/255)-23:n-35;if(e<=s)return e;let r=Math.floor((n-12)*32/255)-23,o=r+(e-r)%(n-4);return o<=s?o:r}async payload(e,t,n,s){let r=this.localPayloadSize(n,s);if(r===n)return e.subarray(t,t+n);let o=new Uint8Array(n);o.set(e.subarray(t,t+r),0);let a=r,h=ke(e,t+r);for(;h!==0&&a<n;){let c=await this.pager.page(h),d=c.subarray(4,4+Math.min(this.usable-4,n-a));o.set(d,a),a+=d.length,h=ke(c,0)}if(a!==n)throw new Error("SQLite overflow chain ended before the payload was complete");return o}async pageAt(e){let t=await this.pager.page(e);return{page:t,header:$s(t,e===1?100:0)}}tableDepth(e,t){let n=this.tableDepths.get(e);return n||(n=(async()=>{let s=e;for(let r=0;;r++){let{page:o,header:a}=await this.pageAt(s);if(a.type===lt)return r;if(a.type!==ut)throw new Error("SQLite table b-tree contains an index page");let h=this.childIndexFor(o,a,t);s=h===a.cellCount?a.rightChild:ke(o,be(o,a,h))}})(),this.tableDepths.set(e,n),n.catch(()=>this.tableDepths.delete(e))),n}childIndexFor(e,t,n){let s=0,r=t.cellCount;for(;s<r;){let o=s+r>>1,[a]=ye(e,be(e,t,o)+4);a<n?s=o+1:r=o}return s}async prefetchRowidRanges(e,t,n=!1){if(t.length===0)return!0;let s=await this.tableDepth(e,t[0][0]),r=t.map(()=>[e]);for(let o=0;o<s;o++){r=await Promise.all(r.map((h,c)=>this.childrenInRange(h,...t[c])));let a=r.flat();if(n)this.pager.prefetchLeading(a);else if(!this.pager.prefetch(a))return!1}return!0}async childrenInRange(e,t,n){let s=await Promise.all(e.map(o=>this.pageAt(o))),r=[];return s.forEach(({page:o,header:a},h)=>{let c=h===0?this.childIndexFor(o,a,t):0,d=h===s.length-1?this.childIndexFor(o,a,n):a.cellCount;for(let f=c;f<=d;f++)r.push(f===a.cellCount?a.rightChild:ke(o,be(o,a,f)))}),r}async tableRowid(e,t){let n=e;for(;;){let{page:s,header:r}=await this.pageAt(n);if(r.type===lt){let h=0,c=r.cellCount;for(;h<c;){let d=h+c>>1,f=be(s,r,d),[l,g]=ye(s,f),[p,u]=ye(s,g);if(p===t)return ft(await this.payload(s,u,l,!1));p<t?h=d+1:c=d}return}if(r.type!==ut)throw new Error("SQLite table b-tree contains an index page");let o=0,a=r.cellCount;for(;o<a;){let h=o+a>>1,c=be(s,r,h),[d]=ye(s,c+4);d<t?o=h+1:a=h}n=o===r.cellCount?r.rightChild:ke(s,be(s,r,o))}}async*tableScan(e){yield*this.scanPage(e,await this.tableDepth(e,0))}async*scanPage(e,t){let{page:n,header:s}=await this.pageAt(e);if(s.type===lt)for(let r=0;r<s.cellCount;r++){let o=be(n,s,r),[a,h]=ye(n,o),[c,d]=ye(n,h);yield{rowid:c,values:ft(await this.payload(n,d,a,!1))}}else{let r=[];for(let o=0;o<s.cellCount;o++)r.push(ke(n,be(n,s,o)));r.push(s.rightChild),t===1&&this.pager.prefetchLeading(r);for(let o of r)yield*this.scanPage(o,t-1)}}decodedCells(e,t){let n=this.decodedIndexPages.get(e);if(n)this.decodedIndexPages.delete(e);else if(n=new Array(t.cellCount),this.decodedIndexPages.size>=Hs){let s=this.decodedIndexPages.keys().next().value;s!==void 0&&this.decodedIndexPages.delete(s)}return this.decodedIndexPages.set(e,n),n}async indexCell(e,t,n,s){let r=this.decodedCells(e,n),o=r[s];if(!o){let a=be(t,n,s),h=n.type===pt,[c,d]=ye(t,h?a+4:a);o={values:ft(await this.payload(t,d,c,!0)),leftChild:h?ke(t,a):0},r[s]=o}return o}async lowerBound(e,t,n,s,r,o){let a=r,h=n.cellCount;for(;a<h;){let c=a+h>>1,d=await this.indexCell(e,t,n,c),f=Bt(d.values,s);f<0||o&&f===0?a=c+1:h=c}return a}async*indexScanFrom(e,t,n){let{page:s,header:r}=await this.pageAt(e),o=await this.lowerBound(e,s,r,t,0,!1),a=r.type===pt;if(a&&n){let h=await this.lowerBound(e,s,r,n,o,!0),c=[];for(let d=o;d<=h;d++)c.push(d===r.cellCount?r.rightChild:(await this.indexCell(e,s,r,d)).leftChild);this.pager.prefetchLeading(c)}for(let h=o;h<r.cellCount;h++){let c=await this.indexCell(e,s,r,h);if(a&&(yield*this.indexScanFrom(c.leftChild,t,n)),n&&Bt(c.values,n)>0)return;yield c.values}a&&(yield*this.indexScanFrom(r.rightChild,t,n))}async indexSeekLE(e,t){let n,s=e;for(;;){let{page:r,header:o}=await this.pageAt(s),a=0,h=o.cellCount,c=0;for(;a<h;){let d=a+h>>1,f=await this.indexCell(s,r,o,d);Bt(f.values,t)<=0?(n=f.values,a=d+1):(c=f.leftChild,h=d)}if(o.type===Dn)return n;s=a===o.cellCount?o.rightChild:c}}};function Bt(i,e){for(let t=0;t<e.length;t++){let n=i[t],s=e[t];if(typeof n!="number"||s===void 0)throw new Error("SQLite index key is not numeric");if(n!==s)return n<s?-1:1}return 0}function zn({blockSize:i,maxBlocks:e}){if(i!==void 0&&!(Number.isSafeInteger(i)&&i>0))throw new Error(`blockSize must be a positive integer, not ${i}`);if(e!==void 0&&!(Number.isSafeInteger(e)&&e>0))throw new Error(`maxBlocks must be a positive integer, not ${e}`)}var gt=class{blocks=new Map;blockSize;maxBlocks;plan;bytesFetched=0;fetches=0;source;pageSize;fileSize;constructor(e,t,n,s={}){this.source=e,this.pageSize=t,this.fileSize=n;let r=s.blockSize??65536;this.blockSize=Math.max(t,Math.ceil(r/t)*t),this.maxBlocks=s.maxBlocks??256}async read(e,t){let n=await this.readRetrying(e,t);if(this.bytesFetched+=n.length,n.length<e)throw new Error(`the file ends at byte ${t+n.length}, short of the ${this.fileSize} bytes its SQLite header gives`);return n}async readRetrying(e,t){let n=0;for(;;)try{return await this.source.read(e,t)}catch(s){if(n+=1,n>=3)throw s;await new Promise(r=>setTimeout(r,200*n))}}seed(e,t){t.length===Math.min(this.blockSize,this.fileSize-e*this.blockSize)&&this.blocks.set(e,Promise.resolve(t))}block(e){this.follow(e);let t=this.touch(e);if(t)return t;let n=e*this.blockSize,s=Math.min(this.blockSize,this.fileSize-n),r=this.read(s,n);return this.fetches+=1,this.store(e,r),this.evict(),r}touch(e){let t=this.blocks.get(e);return t&&(this.blocks.delete(e),this.blocks.set(e,t)),t}blockOf(e){return Math.floor((e-1)*this.pageSize/this.blockSize)}get prefetchBudget(){return Math.max(1,Math.floor(this.maxBlocks/2))}get chunk(){return Math.max(1,Math.floor(this.prefetchBudget/2))}prefetch(e){let t=new Set(e.map(n=>this.blockOf(n)));return t.size>this.prefetchBudget?!1:(this.fetchBlocks(t),!0)}prefetchLeading(e){let t=[],n=new Map;for(let s of e){let r=this.blockOf(s);n.has(r)||(n.set(r,t.length),t.push(r))}this.plan={blocks:t,position:n,next:0},this.advance(this.prefetchBudget)}advance(e){let t=this.plan;if(!t)return;let n=t.blocks.slice(t.next,t.next+e);t.next+=n.length,t.next>=t.blocks.length&&(this.plan=void 0),this.fetchBlocks(new Set(n))}follow(e){let t=this.plan,n=t?.position.get(e);t&&n!==void 0&&n>=t.next-Math.ceil(this.chunk/2)&&this.advance(this.chunk)}fetchBlocks(e){let t=[...e].filter(s=>!this.touch(s)).sort((s,r)=>s-r),n=0;for(;n<t.length;){let s=n+1;for(;s<t.length&&t[s]===t[s-1]+1;)s+=1;this.fetchRun(t[n],s-n),n=s}}fetchRun(e,t){let n=e*this.blockSize,s=Math.min(t*this.blockSize,this.fileSize-n),r=this.read(s,n);this.fetches+=1;for(let o=0;o<t;o++){let a=o*this.blockSize;this.store(e+o,r.then(h=>h.subarray(a,a+this.blockSize)))}this.evict()}store(e,t){this.blocks.set(e,t),t.catch(()=>{this.blocks.get(e)===t&&this.blocks.delete(e)})}evict(){for(;this.blocks.size>this.maxBlocks;){let e=this.blocks.keys().next().value;if(e===void 0)break;this.blocks.delete(e)}}async page(e){let t=(e-1)*this.pageSize;if(e<1||t+this.pageSize>this.fileSize)throw new Error(`SQLite page ${e} is outside the file`);let n=await this.block(Math.floor(t/this.blockSize)),s=t%this.blockSize;return n.subarray(s,s+this.pageSize)}};var je=class i{pager;btree;objects;constructor(e,t,n){this.pager=e,this.btree=t,this.objects=n}static async open(e,t={}){zn(t);let n=await e.read(Math.max(512,t.blockSize??65536),0),s=n.subarray(0,100);if(new TextDecoder().decode(s.subarray(0,15))!=="SQLite format 3"||s.length<100)throw new Error("Not a SQLite database");let o=new DataView(s.buffer,s.byteOffset,s.byteLength),a=o.getUint16(16),h=a===1?65536:a,c=s[20]??0,d=o.getUint32(56);if(d!==1)throw new Error(`SQLite text encoding ${d} is not UTF-8`);let f=o.getUint32(28);if(f===0||o.getUint32(24)!==o.getUint32(92))throw new Error("SQLite header has no valid database size; the file was written by SQLite older than 3.7.0");let l=f*h,g=new gt(e,h,l,t);g.seed(0,n),g.fetches+=1,g.bytesFetched+=n.length;let p=new wt(g,c),u=new Map;for await(let{values:m}of p.tableScan(1)){let[E,I,w,b,y]=m;typeof E=="string"&&typeof I=="string"&&typeof w=="string"&&typeof b=="number"&&u.set(I,{type:E,name:I,tableName:w,rootPage:b,sql:typeof y=="string"?y:""})}return new i(g,p,u)}rootPage(e){let t=this.objects.get(e);if(!t)throw new Error(`SQLite database has no object named ${e}`);return t.rootPage}withoutRowid(e){let t=this.objects.get(e);return t?.type==="table"&&/without\s+rowid/i.test(t.sql)}indexOn(e){let t=[...this.objects.values()].find(n=>n.type==="index"&&n.tableName===e);if(t)return t.rootPage;if(this.withoutRowid(e))return this.rootPage(e);throw new Error(`SQLite table ${e} has no index`)}byRowid(e,t){return this.btree.tableRowid(this.rootPage(e),t)}prefetchRows(e,t,n=!1){return this.btree.prefetchRowidRanges(this.rootPage(e),t,n)}scan(e){return this.btree.tableScan(this.rootPage(e))}indexSeekLE(e,t){return this.btree.indexSeekLE(this.indexOn(e),t)}indexScanFrom(e,t,n){return this.btree.indexScanFrom(this.indexOn(e),t,n)}has(e){return this.objects.has(e)}};var zt="GBZ-base version 4",mt=class extends Error{name="UnknownPathError";path;constructor(e){super(`the graph has no path named ${le(e)}`),this.path=e}},yt=class extends Error{name="ForwardOnlyIndexError";constructor(){super("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")}},xt=class extends Error{name="SchemaVersionError";found;constructor(e){super(e===void 0?"not a gbz-base database: it has no version tag":`unsupported database schema "${e}"; this reader understands "${zt}"`),this.found=e}},Cs=0,Os=1,Ls=2,Bs=3;function Ts(i){if(i.length===1)return i[0];let e=new Uint8Array(i.reduce((n,s)=>n+s.length,0)),t=0;for(let n of i)e.set(n,t),t+=n.length;return e}var Tt=3,Oe=class{at=0;bytes;constructor(e){this.bytes=e}get done(){return this.at>=this.bytes.length}next(){let e=0,t=1;for(;;){let n=this.bytes[this.at++];if(n===void 0)throw new Error("a haplotype index blob ends inside a number");if(e+=(n&127)*t,t*=128,(n&128)===0)return e}}};function _s(i,e){let t=new Oe(i),n=0;for(;!t.done;){let s=n+t.next();n=s+t.next(),e.push([s,n])}}function Ds(i){i.sort((n,s)=>n[0]-s[0]);let e=[],t=[];for(let[n,s]of i){let r=t.length-1;r>=0&&n<=t[r]+1?t[r]=Math.max(t[r],s):(e.push(n),t.push(s))}return n=>{let s=0,r=e.length;for(;s<r;){let o=s+r>>1;e[o]<=n?s=o+1:r=o}return s>0&&n<=t[s-1]}}function Fs(i,e,t){let n=new Oe(e);for(;!n.done;){let s=n.next(),r=n.next(),o=n.next(),a=n.next(),h=n.next();t.push({bin:i,pathHandle:s,pathStart:r,pathEnd:o,snarl:h>0?[a,h]:void 0,node:n.next(),offset:n.next()})}}function zs(i,e,t){let n=R(i);for(let s of e){let r=new Oe(s);for(;!r.done;){let o=r.next(),a=o%2;t.push({node:2*n+a,offset:r.next(),pathHandle:(o-a)/2,orientation:"forward",pathOffset:r.next()})}}}var Dt=class{sequenceLen;handle;edges;bwt;encodedSequence;next;decoded;constructor(e,t,n,s,r){this.handle=e,this.edges=t,this.bwt=n,this.encodedSequence=s,this.next=r,this.sequenceLen=rn(s)}get id(){return R(this.handle)}get orientation(){return Ne(this.handle)}get sequence(){return this.decoded??=an(this.encodedSequence),this.decoded}successors(){return this.edges.filter(e=>e.node!==0).map(e=>e.node)}gbwt(){if(this.edges.length===0)throw new Error(`GBWT record for handle ${this.handle} is empty`);return new Ze(this.edges,this.bwt)}};function G(i,e){if(typeof i!="number")throw new Error(`${e} is not a number in the database`);return i}function Ve(i,e){if(typeof i!="string")throw new Error(`${e} is not text in the database`);return i}function Re(i,e){if(!(i instanceof Uint8Array))throw new Error(`${e} is not a blob in the database`);return i}function Un(i,e){return{handle:i,fwStart:{node:G(e[1],"Paths.fw_node"),offset:G(e[2],"Paths.fw_offset")},revStart:{node:G(e[3],"Paths.rev_node"),offset:G(e[4],"Paths.rev_offset")},name:{sample:Ve(e[5],"Paths.sample"),contig:Ve(e[6],"Paths.contig"),haplotype:G(e[7],"Paths.haplotype"),fragment:G(e[8],"Paths.fragment")},isIndexed:G(e[9],"Paths.is_indexed")!==0}}function _t(i,e){return i.catch(e),i}async function jn(i){let e=new Map;for await(let{values:t}of i.scan("Tags"))e.set(Ve(t[0],"Tags.key"),Ve(t[1],"Tags.value"));return e}var Ft=class i{pathCache;pathMapCache;indexTags=new Map;overviewRowsCache;sqlite;index;tagMap;constructor(e,t,n){this.sqlite=e,this.index=t,this.tagMap=n}static async open(e){let{source:t,haplotypeIndex:n}=e,s={blockSize:e.blockSize,maxBlocks:e.maxBlocks},r=await je.open(t,s),o=r.objects.has("Tags")?await jn(r):new Map,a=o.get("version");if(a!==zt)throw new xt(a);for(let d of["Nodes","Paths","ReferenceIndex"])r.rootPage(d);let h=n?await je.open(n,s):void 0,c=new i(r,h,o);if(h){for(let u of["Tags","HaplotypeSamples","HaplotypeLengths"])if(!h.objects.has(u))throw new Error(`haplotypeIndex is not a gbz-base haplotype index: it has no ${u} table`);c.indexTags=await jn(h);let d=c.indexTags.get("haplotype_index_paths"),f=await c.tag("paths");if(d!==f)throw new Error(`haplotype index was built for ${d??"an unknown number of"} paths but the graph has ${f}`);let l=c.indexTags.get("haplotype_index_nodes"),g=await c.tag("nodes");if(l!==void 0&&l!==g)throw new Error(`haplotype index was built for a graph with ${l} nodes but this one has ${g}`);if(c.indexTags.get("haplotype_index_orientations")==="forward")throw new yt;let p=c.indexTags.get("haplotype_index_format");if(Number(p)!==Tt)throw new Error(p===void 0?`the haplotype index predates format ${Tt}; rebuild it with gbz-haplotype-index 0.3`:`the haplotype index has format ${p}; this version of @gmod/gbz-base reads format ${Tt}`)}return c}async tags(){return this.tagMap}async tag(e){return this.tagMap.get(e)}prefetchRecords(e,t=!1){return this.sqlite.prefetchRows("Nodes",e,t)}async getRecord(e){let t=await this.sqlite.byRowid("Nodes",e);if(!t)return;let n=t[4];return new Dt(e,on(Re(t[1],"Nodes.edges")),Re(t[2],"Nodes.bwt"),Re(t[3],"Nodes.sequence"),typeof n=="number"?n:void 0)}paths(){return this.pathCache??=_t(this.scanPaths(),()=>{this.pathCache=void 0}),this.pathCache}async scanPaths(){let e=[];for await(let{rowid:t,values:n}of this.sqlite.scan("Paths"))e.push(Un(t,n));return e}async getPath(e){let t=await this.sqlite.byRowid("Paths",e);return t?Un(e,t):void 0}pathsByHandle(){return this.pathMapCache??=_t(this.paths().then(e=>new Map(e.map(t=>[t.handle,t]))),()=>{this.pathMapCache=void 0}),this.pathMapCache}async findPath(e){return(await this.paths()).filter(n=>n.name.sample===e.sample&&n.name.contig===e.contig&&n.name.haplotype===e.haplotype&&n.name.fragment<=e.fragment).sort((n,s)=>s.name.fragment-n.name.fragment)[0]}async pathsNamed(e){let t=He($e(e),0);return(await this.paths()).filter(n=>n.name.sample===t.sample&&n.name.contig===t.contig&&n.name.haplotype===t.haplotype).sort((n,s)=>n.name.fragment-s.name.fragment)}async hasPath(e){return(await this.pathsNamed(e)).length>0}pathLengths=new Map;pathLength(e){let t=this.pathLengths.get(e);return t||(t=this.walkPathLength(e),this.pathLengths.set(e,t),t.catch(()=>this.pathLengths.delete(e))),t}async walkPathLength(e){let t=this.hasHaplotypeIndex?await this.haplotypeLength(e):void 0;if(t===void 0){let n=await this.indexedPosition(e,Number.MAX_SAFE_INTEGER);if(!n){let o=await this.getPath(e);throw new Error(`${o?`The fragment of ${le(o.name)} at ${o.name.fragment}`:`Path ${e}`} has not been indexed for random access`)}let s=n.pathOffset,r=n.pos;for(;;){let o=await this.getRecord(r.node);if(!o)throw new Error(`Node ${r.node} does not exist in the graph`);s+=o.sequenceLen;let a=o.gbwt().lf(r.offset);if(!a||a.node===0)return s;r=a}}return t}async getPathFragments(e){let{start:t,end:n}=e;if(Number.isNaN(t)||Number.isNaN(n))throw new Error(`The window ${t}..${n} is not a number range`);let s=await this.pathsNamed(e.path);if(s.length===0)throw new mt(He($e(e.path),0));if(n<=t)return[];let r=s.filter(h=>h.name.fragment<=t).slice(-1),o=s.filter(h=>h.name.fragment>t&&h.name.fragment<n);return(await Promise.all([...r,...o].map(async h=>({path:h,start:h.name.fragment,end:h.name.fragment+await this.pathLength(h.handle)})))).filter(h=>t<h.end)}async subgraphForFragment(e,t){let{sample:n,contig:s,haplotype:r}=e.path.name,o=Math.max(t.start,e.start),a=t.haplotypes??"all";try{let h=await Lt(this,{...t,path:{sample:n,contig:s,haplotype:r},start:o,end:Math.min(t.end,e.end)});return t.keep===void 0&&this.hasHaplotypeIndex&&(a==="all"||a==="distinct")&&await h.identifyPaths(),h}catch(h){throw h instanceof we&&h.walkedBp!==void 0?new we(h.limit,{windowBp:t.end-t.start,walkedBp:o-t.start+h.walkedBp}):h}}async getSubgraphs(e){let t=await this.getPathFragments(e);return(await Promise.allSettled(t.map(s=>this.subgraphForFragment(s,e)))).map(s=>{if(s.status==="rejected")throw s.reason;return s.value})}async getAlignments(e){return(await this.getSubgraphs(e)).flatMap(t=>t.alignments())}subgraphInInterval(e){return Lt(this,e)}subgraphAtOffset(e){return Bn(this,e)}subgraphAroundNodes(e){return Tn(this,e)}subgraphBetween(e){return _n(this,e)}fetchStats(){let e=({pager:t})=>({fetches:t.fetches,bytesFetched:t.bytesFetched});return{graph:e(this.sqlite),haplotypeIndex:this.index?e(this.index):void 0}}async graphName(){let e=new Map;for(let[n,s]of await this.tags())n.startsWith("gbz_")&&e.set(n.slice(4),s);let t={name:void 0,subgraph:new Map,translation:new Map};try{t=ln(e)}catch{}return t}async hasChainLinks(){let e=await this.tag("chain_links");return e!==void 0&&Number(e)>0}get hasHaplotypeIndex(){return this.index!==void 0}get companion(){if(!this.index)throw new Error("no haplotype index was opened with this database");return this.index}async haplotypeSampleInterval(){let e=this.indexTags.get("haplotype_index_interval");return e===void 0?void 0:Number(e)}async haplotypeSampleGap(){let e=await this.haplotypeSampleInterval(),t=this.indexTags.get("haplotype_index_reference_interval");return e===void 0?void 0:Math.max(e,t===void 0?0:Number(t))}async haplotypeAnchorSpacing(){let e=this.index?.has("HaplotypeAnchors")?this.indexTags.get("haplotype_index_anchor_spacing"):void 0;return e===void 0?void 0:Number(e)}async haplotypeStrayOptions(){let e=n=>this.indexTags.get(`haplotype_index_stray_${n}`);if(!this.index?.has("HaplotypeBins")||e("format")!=="2")return;let t=e("snarls")==="modeled"&&e("chain_links")===(await this.tag("chain_links")??"0");return{context:Number(e("context")),bin:Number(e("bin")),bound:Number(e("bound")),snarlNodes:t?Number(e("snarl_nodes")):void 0}}async blobRows(e,t,n){let s=[],r=[];for await(let o of this.companion.indexScanFrom(e,t,n))r.push(G(o[o.length-1],`${e} rowid`));r.length>1&&await this.companion.prefetchRows(e,[[Math.min(...r),Math.max(...r)+1]],!0);for(let o of r){let a=await this.companion.byRowid(e,o);a&&s.push(a)}return s}async haplotypeBinData(e,t,n){let s=[],r=[];for(let o of await this.blobRows("HaplotypeBins",[e,t],[e,n])){let a=G(o[1],"HaplotypeBins.bin");_s(Re(o[3],"HaplotypeBins.nodes"),s),Fs(a,Re(o[4],"HaplotypeBins.strays"),r)}return{listed:Ds(s),strays:r}}async haplotypeAnchorsBetween(e,t,n){let s=[],r=[],o=()=>{let a=s[s.length-1];a&&zs(a.node,r,a.visits),r=[]};for(let a of await this.blobRows("HaplotypeAnchors",[e,t],[e,n])){let h=G(a[1],"HaplotypeAnchors.anchor_offset");s[s.length-1]?.anchorOffset!==h&&(o(),s.push({anchorOffset:h,node:G(a[3],"HaplotypeAnchors.node_handle"),pathOffset:G(a[4],"HaplotypeAnchors.path_offset"),visits:[]})),r.push(Re(a[5],"HaplotypeAnchors.visits"))}return o(),s}async haplotypeAnchor(e,t){let[n]=await this.haplotypeAnchorsBetween(e,t,t);return n&&{node:n.node,pathOffset:n.pathOffset}}haplotypeSamplesAtNode(e){return this.haplotypeSamplesInRange(e,e)}sampleFromRow(e){return{node:G(e[0],"HaplotypeSamples.node_handle"),offset:G(e[1],"HaplotypeSamples.node_offset"),pathHandle:G(e[2],"HaplotypeSamples.path_handle"),orientation:G(e[3],"HaplotypeSamples.orientation")===0?"forward":"reverse",pathOffset:G(e[4],"HaplotypeSamples.path_offset")}}async haplotypeSamplesInRange(e,t){let n=[];for await(let s of this.companion.indexScanFrom("HaplotypeSamples",[e,0],[t,Number.MAX_SAFE_INTEGER]))n.push(this.sampleFromRow(s));return n}async haplotypeSampleAt(e,t){let n=await this.companion.indexSeekLE("HaplotypeSamples",[e,t]);return n?.[0]===e&&n[1]===t?this.sampleFromRow(n):void 0}overviewRows(){return this.overviewRowsCache??=_t((async()=>{let e=[];for await(let{rowid:t,values:n}of this.companion.scan("HaplotypeOverviewRows"))e[t]={sample:Ve(n[1],"HaplotypeOverviewRows.sample"),haplotype:G(n[2],"HaplotypeOverviewRows.haplotype")};return e})(),()=>{this.overviewRowsCache=void 0}),this.overviewRowsCache}async overviewChunks(e,t,n,s,r){let o=new Map;for(let a of await this.blobRows(e,[t,n,s],[t,n,r])){let h=G(a[2],`${e}.chunk`),c=o.get(h)??[];c.push(Re(a[4],`${e} blob`)),o.set(h,c)}return new Map([...o].map(([a,h])=>[a,Ts(h)]))}async haplotypeOverview(e){let t=p=>this.indexTags.get(`haplotype_index_overview_${p}`);if(!this.index?.has("HaplotypeOverviewClasses")||t("format")!=="1")return;let n=Number(t("bin")),s=Number(t("chunk")),r=Number(t("levels")),o=Math.max(0,Math.min(Math.floor(e.level??0)||0,r-1));if(e.level===void 0&&e.bpPerPixel!==void 0)for(;o+1<r&&n*4**(o+1)<=e.bpPerPixel;)o+=1;let a=n*4**o,[h,c]=await Promise.all([this.getPathFragments(e),this.overviewRows()]),d=Math.ceil(c.length/2),f=[],l=[];for(let p of h){let u=p.end-p.start,m=Math.max(e.start,p.start)-p.start,E=Math.min(e.end,p.end)-p.start,I=Math.floor(m/a),w=Math.floor((E-1)/a),b=Math.floor(I/s),y=Math.floor(w/s),[k,v]=await Promise.all([this.overviewChunks("HaplotypeOverviewBins",p.path.handle,o,b,y),this.overviewChunks("HaplotypeOverviewClasses",p.path.handle,o,b,y)]);for(let O=b;O<=y;O++){let B=new Oe(k.get(O)??new Uint8Array),D=v.get(O)??new Uint8Array;for(let q=O*s;!B.done;q++){let $=Array.from({length:7},()=>B.next());if(q<I||q>w)continue;f.push({start:p.start+q*a,end:p.start+Math.min((q+1)*a,u),classes:[$[0],$[1],$[2],$[3]],excursions:$[4],variants:$[5],longestExcursion:$[6]});let N=(q-O*s)*d;l.push(D.subarray(N,N+d))}}}if(f.length===0)return;let g=new Uint8Array(f.length*c.length);return l.forEach((p,u)=>{for(let m=0;m<c.length;m++)g[u*c.length+m]=(p[m>>1]??0)>>4*(m%2)&15}),{level:o,bin:a,haplotypes:c,bins:f,cells:g}}async haplotypeLength(e){let t=await this.companion.byRowid("HaplotypeLengths",e);return t?G(t[1],"HaplotypeLengths.length"):void 0}async indexedRow(e){let t=await this.sqlite.byRowid("ReferenceIndex",e);if(!t)throw new Error("ReferenceIndex row referenced by its index is missing");return{pathOffset:G(t[1],"ReferenceIndex.path_offset"),pos:{node:G(t[2],"ReferenceIndex.node_handle"),offset:G(t[3],"ReferenceIndex.node_offset")}}}async indexedRowid(e,t){let n=await this.sqlite.indexSeekLE("ReferenceIndex",[e,t]);return n?.[0]===e?G(n[2],"ReferenceIndex rowid"):void 0}async indexedPosition(e,t){let n=await this.indexedRowid(e,t);return n===void 0?void 0:this.indexedRow(n)}async indexedPositionsBetween(e,t,n){let[s,r]=await Promise.all([this.indexedRowid(e,t),this.indexedRowid(e,n)]),o=[];if(s!==void 0&&r!==void 0){await this.sqlite.prefetchRows("ReferenceIndex",[[s,r+1]]);for(let a=s;a<=r;a++)o.push(await this.indexedRow(a))}return o}};export{Cs as a,Os as b,Ls as c,Bs as d,Ft as e};
|
|
6
|
+
//# sourceMappingURL=chunk-2H7GDQ3R.js.map
|