jbrowse-plugin-graphgenomeviewer 7.1.2 → 7.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunks/{GraphGenomeView-NJ5XCREB.js → GraphGenomeView-PSDUS64B.js} +2 -2
- package/dist/chunks/{HighlightColorDialog-UK5VDDV6.js → HighlightColorDialog-2MP3C5AK.js} +2 -2
- package/dist/chunks/{LinearGraphDisplay-TXTKAACH.js → LinearGraphDisplay-FTFJFNKT.js} +2 -2
- package/dist/chunks/{WalkTabixSyntenyAdapter-U53JLYVU.js → WalkTabixSyntenyAdapter-GH6NYQTF.js} +2 -2
- package/dist/chunks/{WalkTabixSyntenyAdapter-U53JLYVU.js.map → WalkTabixSyntenyAdapter-GH6NYQTF.js.map} +1 -1
- package/dist/chunks/chunk-HM57SCYO.js +4 -0
- package/dist/chunks/chunk-HM57SCYO.js.map +7 -0
- package/dist/chunks/{chunk-WEGWTC52.js → chunk-LELA7BG7.js} +2 -2
- package/dist/chunks/{chunk-WEGWTC52.js.map → chunk-LELA7BG7.js.map} +4 -4
- package/dist/chunks/chunk-NP42Y2MV.js +2 -0
- package/dist/chunks/chunk-NP42Y2MV.js.map +7 -0
- package/dist/chunks/chunk-PJ43KEV6.js +2 -0
- package/dist/chunks/chunk-PJ43KEV6.js.map +7 -0
- package/dist/chunks/chunk-RP3L3Z5W.js +3 -0
- package/dist/chunks/chunk-RP3L3Z5W.js.map +7 -0
- package/dist/chunks/{chunk-FITPB5X6.js → chunk-VQUMZEGN.js} +2 -2
- package/dist/chunks/renderSvg-V4OYQTQZ.js +2 -0
- package/dist/chunks/renderSvg-V4OYQTQZ.js.map +7 -0
- package/dist/jbrowse-plugin-graphgenomeviewer.esm.js +4 -4
- package/dist/jbrowse-plugin-graphgenomeviewer.esm.js.map +4 -4
- package/package.json +2 -2
- package/src/GbzBaseSyntenyAdapter/configSchema.ts +2 -2
- package/src/GetSubgraph.ts +1 -1
- package/src/GraphAddTrackWorkflow/buildTrackConfig.test.ts +2 -2
- package/src/GraphGenomeView/components/GraphCanvas.test.tsx +108 -0
- package/src/GraphGenomeView/components/GraphCanvas.tsx +11 -8
- package/src/GraphGenomeView/components/Legend.tsx +3 -121
- package/src/GraphGenomeView/components/LegendSwatch.tsx +237 -0
- package/src/GraphGenomeView/components/PaneSvg.tsx +3 -190
- package/src/GraphGenomeView/components/WalkStrip.tsx +1 -1
- package/src/GraphGenomeView/model.test.ts +13 -5
- package/src/GraphGenomeView/pane/graphViews.ts +10 -0
- package/src/GraphGenomeView/pane/loadActions.ts +5 -1
- package/src/GraphGenomeView/pane/morph.test.ts +34 -1
- package/src/GraphGenomeView/pane/morph.ts +74 -5
- package/src/GraphGenomeView/pane/renderingActions.ts +1 -1
- package/src/GraphGenomeView/pane/settingActions.ts +10 -43
- package/src/GraphGenomeView/subgraphLoad.test.ts +56 -1
- package/src/GraphGenomeView/viewModel.ts +55 -33
- package/src/GraphGenomeView/walkRowSpans.ts +4 -10
- package/src/GraphTrack/index.ts +2 -2
- package/src/LinearGraphDisplay/LinearGraphDisplay.test.ts +12 -2
- package/src/LinearGraphDisplay/denseWindow.ts +0 -14
- package/src/LinearGraphDisplay/model.ts +2 -1
- package/src/RgfaTabixAdapter/walkFiles.test.ts +1 -0
- package/src/WalkTabixSyntenyAdapter/WalkTabixSyntenyAdapter.ts +1 -1
- package/src/graphTrackDefaults/graphTrackDefaults.test.ts +15 -3
- package/src/graphTrackDefaults/index.ts +10 -5
- package/src/launchFromGraph/launchFromGraph.test.ts +7 -10
- package/src/launchFromGraph/launchFromGraph.ts +26 -2
- package/src/nodeLimitError.ts +12 -0
- package/src/panSNAliases/panSNAliases.test.ts +129 -3
- package/src/panSNAliases/trackAdapterConfig.ts +55 -11
- package/src/version.ts +1 -1
- package/dist/chunks/chunk-2MCOY3YG.js +0 -3
- package/dist/chunks/chunk-2MCOY3YG.js.map +0 -7
- package/dist/chunks/chunk-MURN3JPK.js +0 -2
- package/dist/chunks/chunk-MURN3JPK.js.map +0 -7
- package/dist/chunks/chunk-NWJYLP6Z.js +0 -4
- package/dist/chunks/chunk-NWJYLP6Z.js.map +0 -7
- package/dist/chunks/chunk-WCGVUZWP.js +0 -2
- package/dist/chunks/chunk-WCGVUZWP.js.map +0 -7
- package/dist/chunks/renderSvg-KSQI5DH6.js +0 -2
- package/dist/chunks/renderSvg-KSQI5DH6.js.map +0 -7
- /package/dist/chunks/{GraphGenomeView-NJ5XCREB.js.map → GraphGenomeView-PSDUS64B.js.map} +0 -0
- /package/dist/chunks/{HighlightColorDialog-UK5VDDV6.js.map → HighlightColorDialog-2MP3C5AK.js.map} +0 -0
- /package/dist/chunks/{LinearGraphDisplay-TXTKAACH.js.map → LinearGraphDisplay-FTFJFNKT.js.map} +0 -0
- /package/dist/chunks/{chunk-FITPB5X6.js.map → chunk-VQUMZEGN.js.map} +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../../node_modules/.pnpm/@jbrowse+bandage-core@10.2.6/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-XV4P5KEQ.js", "../../node_modules/.pnpm/@jbrowse+bandage-core@10.2.6/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-
|
|
4
|
-
"sourcesContent": ["// src/facetGrid.ts\nvar FACET_GAP_PX = 8;\nvar FACET_TITLE_PX = 34;\nvar FACET_PAD_PX = 12;\nvar MIN_FACET_PANEL_PX = 60;\nfunction facetGrid({\n count,\n bounds,\n pixelRows,\n width,\n room,\n columns\n}) {\n function tile(across) {\n const rows = Math.ceil(count / across);\n const panelWidth = Math.floor(\n (width - (across - 1) * FACET_GAP_PX) / across\n );\n const panelRoom = (room - rows * FACET_TITLE_PX - (rows - 1) * FACET_GAP_PX) / rows;\n const fitX = (panelWidth - 2 * FACET_PAD_PX) / bounds.w;\n const fitY = bounds.h > 0 ? (panelRoom - 2 * FACET_PAD_PX) / bounds.h : Infinity;\n const scale = pixelRows ? fitX : Math.min(fitX, fitY);\n const drawn = pixelRows ? bounds.h : bounds.h * scale;\n const height = Math.floor(\n Math.max(\n MIN_FACET_PANEL_PX,\n Math.min(drawn + 2 * FACET_PAD_PX, panelRoom)\n )\n );\n return {\n columns: across,\n width: panelWidth,\n height,\n scale,\n total: rows * (height + FACET_TITLE_PX) + (rows - 1) * FACET_GAP_PX\n };\n }\n if (columns !== void 0) {\n return tile(Math.max(1, Math.min(count, Math.round(columns))));\n }\n let best = tile(1);\n for (let across = 2; across <= count; across++) {\n const grid = tile(across);\n if (grid.scale > best.scale) {\n best = grid;\n }\n }\n return best;\n}\nvar FACET_FIELDS = [\n { value: \"\", label: \"None\", description: \"Every lifted walk in one drawing\" },\n {\n value: \"walk\",\n label: \"A panel per walk\",\n description: \"One panel per lifted walk, side by side\"\n },\n {\n value: \"sample\",\n label: \"A row per sample\",\n description: \"A row per sample, a column per haplotype\"\n }\n];\nfunction facetSettingOf(facet) {\n const raw = typeof facet === \"string\" ? { field: facet } : facet ?? {};\n const field = raw.field === \"walk\" || raw.field === \"sample\" ? raw.field : \"\";\n return {\n field,\n domain: [...raw.domain ?? []],\n ...raw.columns === void 0 ? {} : { columns: raw.columns }\n };\n}\nfunction domainFirst(names, domain) {\n const rank = new Map(domain.map((name, i) => [name, i]));\n const listed = (name) => rank.get(name) ?? domain.length;\n return names.map((name, i) => ({ name, i })).sort((a, b) => listed(a.name) - listed(b.name) || a.i - b.i).map(({ name }) => name);\n}\nfunction facetCells(names, by, domain = []) {\n const wrapOrder = domainFirst(names, domain);\n const wrap = {\n columns: void 0,\n count: names.length,\n cells: names.map((name) => wrapOrder.indexOf(name))\n };\n if (by === \"walk\") {\n return wrap;\n }\n const places = names.map((name) => {\n const [sample, haplotype, contig] = name.split(\"#\");\n const n = Number(haplotype);\n return contig !== void 0 && Number.isInteger(n) && n >= 0 ? { sample, column: Math.max(0, n - 1) } : void 0;\n });\n const rows = domainFirst(\n [...new Set(places.flatMap((p) => p ? [p.sample] : []))],\n domain\n );\n const columns = Math.max(1, ...places.map((p) => p ? p.column + 1 : 1));\n const cells = places.map(\n (p) => p ? rows.indexOf(p.sample) * columns + p.column : -1\n );\n return cells.includes(-1) || new Set(cells).size < cells.length ? wrap : { columns, count: rows.length * columns, cells };\n}\n\nexport {\n FACET_GAP_PX,\n FACET_TITLE_PX,\n FACET_PAD_PX,\n facetGrid,\n FACET_FIELDS,\n facetSettingOf,\n facetCells\n};\n", "import {\n formatBp\n} from \"./chunk-PTABFYQ7.js\";\nimport {\n isBackbone\n} from \"./chunk-FYQWPEEY.js\";\n\n// src/tubeMap/axis.ts\nfunction referenceBoxes({\n graph,\n layout\n}) {\n const nodeById = new Map(graph.nodes.map((n) => [n.id, n]));\n const byRefName = /* @__PURE__ */ new Map();\n layout.nodes.forEach((node, index) => {\n const graphNode = nodeById.get(node.name);\n if (node.order >= 0 && graphNode && isBackbone(graphNode)) {\n const { refName, start } = graphNode.stable;\n const boxes = byRefName.get(refName) ?? byRefName.set(refName, []).get(refName);\n boxes.push({\n name: node.name,\n index,\n bp0: start,\n bp1: start + graphNode.length,\n x0: node.x,\n x1: node.x + node.pixelWidth\n });\n }\n });\n for (const boxes of byRefName.values()) {\n boxes.sort((a, b) => a.bp0 - b.bp0);\n }\n return byRefName;\n}\nfunction tubeX(boxes, bp, isEnd = false) {\n let lo = 0;\n let hi = boxes.length - 1;\n while (lo < hi) {\n const mid = lo + hi >> 1;\n const bp1 = boxes[mid].bp1;\n if (isEnd ? bp1 < bp : bp1 <= bp) {\n lo = mid + 1;\n } else {\n hi = mid;\n }\n }\n const box = boxes[lo];\n if (bp <= box.bp0) {\n return box.x0;\n }\n const span = box.bp1 - box.bp0;\n return span > 0 ? box.x0 + (Math.min(bp, box.bp1) - box.bp0) / span * (box.x1 - box.x0) : box.x0;\n}\nfunction tubeSpan(boxes, start, end) {\n const a = tubeX(boxes, start);\n const b = tubeX(boxes, end, true);\n return { x0: Math.min(a, b), x1: Math.max(a, b) };\n}\nfunction rulerBoxes(byRefName) {\n let best;\n for (const boxes of byRefName.values()) {\n if (!best || boxes.length > best.length) {\n best = boxes;\n }\n }\n return best;\n}\nvar TICK_PX = 5;\nvar LABEL_GAP_PX = 10;\nvar TARGET_TICK_PX = 110;\nvar MIN_BRACKET_PX = 3;\nfunction rulerInk(darkMode) {\n return darkMode ? \"#b0b0b8\" : \"#55555c\";\n}\nfunction niceStep(raw) {\n const pow = 10 ** Math.floor(Math.log10(raw));\n const m = raw / pow;\n return (m <= 1 ? 1 : m <= 2 ? 2 : m <= 5 ? 5 : 10) * pow;\n}\nfunction placeLabels(candidates) {\n const placed = [];\n for (const a of candidates) {\n if (placed.every(\n (b) => Math.abs(a.at - b.at) >= (a.width + b.width) / 2 + LABEL_GAP_PX\n )) {\n placed.push(a);\n }\n }\n return placed.map(({ text, at }) => ({ text, at }));\n}\nfunction scaleMarks(boxes, x, width, measure) {\n const first = boxes[0];\n const last = boxes.at(-1);\n if (!first || !last) {\n return void 0;\n }\n const from = x(first.x0);\n const to = x(last.x1);\n const bpSpan = last.bp1 - first.bp0;\n if (to <= from || bpSpan <= 0) {\n return void 0;\n }\n const step = niceStep(bpSpan / (to - from) * TARGET_TICK_PX);\n const ticks = [];\n const positions = [];\n for (let bp = Math.ceil(first.bp0 / step) * step; bp <= last.bp1; bp += step) {\n const sx = Math.round(x(tubeX(boxes, bp))) + 0.5;\n if (sx >= 0 && sx <= width) {\n ticks.push(sx);\n const text = bp.toLocaleString(\"en-US\");\n positions.push({ text, at: sx, width: measure(text) });\n }\n }\n return {\n spans: [{ x0: from, x1: to }],\n ticks,\n labels: placeLabels(positions)\n };\n}\nfunction boxMarks(boxes, x, width, measure) {\n const shown = boxes.map((box) => ({ box, s0: x(box.x0), s1: x(box.x1) })).filter(({ s0, s1 }) => s1 >= 0 && s0 <= width);\n const first = shown[0];\n const last = shown.at(-1);\n if (!first || !last) {\n return void 0;\n }\n const label = (text, at) => ({\n text,\n at,\n width: measure(text)\n });\n const position = (bp, at) => label(bp.toLocaleString(\"en-US\"), at);\n const spans = [];\n const ticks = [];\n const lengths = [];\n const boundaries = [];\n for (const { box, s0, s1 } of shown) {\n spans.push({ x0: s0, x1: s1 });\n ticks.push(Math.round(s0) + 0.5);\n if (s1 - s0 >= MIN_BRACKET_PX) {\n ticks.push(Math.round(s1) + 0.5);\n }\n const length = label(formatBp(box.bp1 - box.bp0), (s0 + s1) / 2);\n if (length.width <= s1 - s0) {\n lengths.push(length);\n }\n if (box !== first.box) {\n boundaries.push(position(box.bp0, s0));\n }\n }\n const ends = [\n position(first.box.bp0, first.s0),\n position(last.box.bp1, last.s1)\n ];\n return {\n spans,\n ticks,\n labels: placeLabels([...ends, ...lengths, ...boundaries])\n };\n}\nfunction rulerMarks(boxes, x, width, measure, referenceAxis = false) {\n return (referenceAxis ? scaleMarks : boxMarks)(boxes, x, width, measure);\n}\nfunction drawTubeMapRuler(ctx, boxes, frame, top, referenceAxis = false) {\n const { x, width, darkMode } = frame;\n ctx.font = \"10px sans-serif\";\n const marks = rulerMarks(\n boxes,\n x,\n width,\n (text) => ctx.measureText(text).width,\n referenceAxis\n );\n if (!marks) {\n return;\n }\n const ink = rulerInk(darkMode);\n const y = top + 0.5;\n ctx.strokeStyle = ink;\n ctx.fillStyle = ink;\n ctx.lineWidth = 1;\n ctx.textAlign = \"center\";\n ctx.textBaseline = \"top\";\n ctx.beginPath();\n for (const { x0, x1 } of marks.spans) {\n ctx.moveTo(Math.max(0, x0), y);\n ctx.lineTo(Math.min(width, x1), y);\n }\n for (const sx of marks.ticks) {\n ctx.moveTo(sx, top);\n ctx.lineTo(sx, top + TICK_PX);\n }\n ctx.stroke();\n for (const { text, at } of marks.labels) {\n ctx.fillText(text, at, top + TICK_PX + 2);\n }\n}\n\nexport {\n referenceBoxes,\n tubeX,\n tubeSpan,\n rulerBoxes,\n rulerInk,\n rulerMarks,\n drawTubeMapRuler\n};\n", "// src/renderer/svgCanvas.ts\nvar n = (v) => +v.toFixed(1);\nfunction paint(css) {\n const m = /^rgba?\\(([^,]+),([^,]+),([^,)]+)(?:,([^)]+))?\\)$/.exec(\n css.replaceAll(\" \", \"\")\n );\n if (!m) {\n return { color: css, opacity: 1 };\n }\n const opacity = m[4] === void 0 ? 1 : Number(m[4]);\n return { color: `rgb(${m[1]},${m[2]},${m[3]})`, opacity };\n}\nfunction paintAttrs(kind, css) {\n const { color, opacity } = paint(css);\n return `${kind}=\"${color}\"${opacity < 1 ? ` ${kind}-opacity=\"${n(opacity)}\"` : \"\"}`;\n}\nvar DOT_PX = 0.5;\nvar DOT_CELL_PX = 0.25;\nfunction svgCanvas(width, height) {\n const out = [];\n let subpaths = [];\n const start = (x, y) => {\n const s = { d: `M${n(x)} ${n(y)}`, segments: 0, x0: x, x1: x, y0: y, y1: y };\n subpaths.push(s);\n return s;\n };\n const reach = (points) => {\n const s = subpaths.at(-1) ?? start(points[0], points[1]);\n for (let i = 0; i < points.length; i += 2) {\n s.x0 = Math.min(s.x0, points[i]);\n s.x1 = Math.max(s.x1, points[i]);\n s.y0 = Math.min(s.y0, points[i + 1]);\n s.y1 = Math.max(s.y1, points[i + 1]);\n }\n s.segments++;\n return s;\n };\n const pathData = (dots) => {\n const seen = /* @__PURE__ */ new Set();\n return subpaths.map((s) => {\n if (!dots || s.x1 - s.x0 >= DOT_PX || s.y1 - s.y0 >= DOT_PX) {\n return s.d;\n }\n const x = (s.x0 + s.x1) / 2;\n const y = (s.y0 + s.y1) / 2;\n const cell = `${Math.round(x / DOT_CELL_PX)} ${Math.round(y / DOT_CELL_PX)}`;\n if (s.segments === 0 || seen.has(cell)) {\n return \"\";\n }\n seen.add(cell);\n return `M${n(x)} ${n(y)}h0`;\n }).join(\"\");\n };\n const ctx = {\n canvas: void 0,\n fillStyle: \"#000\",\n strokeStyle: \"#000\",\n lineWidth: 1,\n lineCap: \"butt\",\n lineJoin: \"miter\",\n beginPath() {\n subpaths = [];\n },\n moveTo(x, y) {\n start(x, y);\n },\n lineTo(x, y) {\n reach([x, y]).d += `L${n(x)} ${n(y)}`;\n },\n bezierCurveTo(cx0, cy0, cx1, cy1, x, y) {\n reach([cx0, cy0, cx1, cy1, x, y]).d += `C${n(cx0)} ${n(cy0)} ${n(cx1)} ${n(cy1)} ${n(x)} ${n(y)}`;\n },\n closePath() {\n const s = subpaths.at(-1);\n if (s) {\n s.d += \"Z\";\n }\n },\n stroke() {\n const d = pathData(ctx.lineCap !== \"butt\");\n if (d) {\n out.push(\n `<path d=\"${d}\" fill=\"none\" ${paintAttrs(\"stroke\", ctx.strokeStyle)} stroke-width=\"${n(ctx.lineWidth)}\" stroke-linecap=\"${ctx.lineCap}\" stroke-linejoin=\"${ctx.lineJoin}\"/>`\n );\n }\n },\n fill() {\n const d = pathData(false);\n if (d) {\n out.push(`<path d=\"${d}\" ${paintAttrs(\"fill\", ctx.fillStyle)}/>`);\n }\n },\n // the renderer only ever clears the whole canvas\n clearRect() {\n out.length = 0;\n },\n fillRect(x, y, w, h) {\n out.push(\n `<rect x=\"${n(x)}\" y=\"${n(y)}\" width=\"${n(w)}\" height=\"${n(h)}\" ${paintAttrs(\"fill\", ctx.fillStyle)}/>`\n );\n }\n };\n const canvas = {\n width,\n height,\n style: {},\n getContext: () => ctx\n };\n ctx.canvas = canvas;\n return {\n canvas,\n // the drawing so far, as SVG elements in canvas pixels\n markup: () => out.join(\"\")\n };\n}\n\nexport {\n svgCanvas\n};\n", "// src/renderer/canvas.ts\nvar MAX_DPR = 2;\nvar MAX_CANVAS_DIM_PX = 8192;\nfunction getDpr(width = 0, height = 0) {\n const dpr = typeof devicePixelRatio === \"undefined\" ? 1 : Math.min(devicePixelRatio, MAX_DPR);\n return Math.min(dpr, MAX_CANVAS_DIM_PX / Math.max(width, height, 1));\n}\nfunction syncCanvasSize(canvas, width, height) {\n const dpr = getDpr(width, height);\n const pw = Math.round(width * dpr);\n const ph = Math.round(height * dpr);\n if (canvas.width !== pw || canvas.height !== ph) {\n canvas.width = pw;\n canvas.height = ph;\n }\n const cssWidth = `${width}px`;\n const cssHeight = `${height}px`;\n if (canvas.style.width !== cssWidth) {\n canvas.style.width = cssWidth;\n }\n if (canvas.style.height !== cssHeight) {\n canvas.style.height = cssHeight;\n }\n return dpr;\n}\n\nexport {\n MAX_DPR,\n MAX_CANVAS_DIM_PX,\n getDpr,\n syncCanvasSize\n};\n", "import {\n getDpr,\n syncCanvasSize\n} from \"./chunk-RBCE2OQH.js\";\nimport {\n abgrToCssRgba,\n brightenAbgr,\n normalizedRgbToCssRgba\n} from \"./chunk-G2FD7S3C.js\";\n\n// src/renderer/Canvas2DRenderer.ts\nvar Canvas2DRenderer = class {\n constructor(canvas) {\n this.transform = null;\n this.batch = null;\n this.nodeHighlights = /* @__PURE__ */ new Map();\n this.highlightedEdge = null;\n this.highlightFactor = 1;\n this.fit = 1;\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) {\n throw new Error(\"Canvas 2D context not available\");\n }\n this.canvas = canvas;\n this.ctx = ctx;\n }\n setErrorHandler(_handler) {\n }\n releaseOffscreenTargets() {\n }\n // A host builds its transform at `getDpr()`. Where syncCanvasSize had to\n // shrink the ratio to stay under MAX_CANVAS_DIM_PX, `fit` shrinks the\n // transform to match, so the picture still fills the css box.\n resize(width, height) {\n this.fit = syncCanvasSize(this.canvas, width, height) / getDpr();\n }\n uploadGeometry(batch) {\n this.batch = batch;\n this.highlightedEdge = null;\n }\n setNodeHighlights(factors) {\n this.nodeHighlights = factors;\n }\n setEdgeHighlight(edgeIndex, factor) {\n this.highlightedEdge = edgeIndex;\n this.highlightFactor = factor;\n }\n updateTransform(transform) {\n const k = this.fit;\n this.transform = k === 1 ? transform : {\n ...transform,\n scaleX: transform.scaleX * k,\n scaleY: transform.scaleY * k,\n translateX: transform.translateX * k,\n translateY: transform.translateY * k,\n dpr: transform.dpr * k\n };\n }\n render(clearColor) {\n const t = this.transform;\n if (!t) {\n return;\n }\n const ctx = this.ctx;\n const { width, height } = ctx.canvas;\n if (clearColor[3] < 1) {\n ctx.clearRect(0, 0, width, height);\n }\n ctx.fillStyle = normalizedRgbToCssRgba(\n [clearColor[0], clearColor[1], clearColor[2]],\n clearColor[3]\n );\n ctx.fillRect(0, 0, width, height);\n const batch = this.batch;\n if (!batch) {\n return;\n }\n ctx.lineCap = \"round\";\n ctx.lineJoin = \"round\";\n const factor = this.highlightFactor;\n const edgeRun = this.edgeRun(batch.edgeCurveRuns);\n for (const { color, items } of groupByPaint(batch.edgeCurves, (e, i) => ({\n color: inRun(edgeRun, i) ? brightenAbgr(e.color, factor) : e.color,\n weight: e.thickness,\n last: inRun(edgeRun, i)\n }))) {\n this.strokeCurves(items, color);\n }\n const lifted = this.liftedStrokes(batch);\n for (const { color, items } of groupByPaint(batch.nodeStrokes, (s, i) => {\n const f = lifted.get(i);\n return {\n color: f === void 0 ? s.color : brightenAbgr(s.color, f),\n weight: s.thickness,\n last: f !== void 0\n };\n })) {\n this.strokeNodes(items, color);\n }\n const arrowRun = this.edgeRun(batch.arrowRuns);\n for (const { color, items } of groupByPaint(batch.arrows, (a, i) => ({\n color: inRun(arrowRun, i) ? brightenAbgr(a.color, factor) : a.color,\n weight: 0,\n last: inRun(arrowRun, i)\n }))) {\n this.fillArrows(items, color);\n }\n }\n // Only what the highlights lift, over a transparent clear, for a hover layer\n // stacked on a canvas that drew the batch without them: a pointer move then\n // repaints one node or edge rather than the whole drawing\n renderHighlights() {\n const ctx = this.ctx;\n ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);\n const batch = this.batch;\n if (!this.transform || !batch) {\n return;\n }\n ctx.lineCap = \"round\";\n ctx.lineJoin = \"round\";\n const factor = this.highlightFactor;\n const curves = runItems(batch.edgeCurves, this.edgeRun(batch.edgeCurveRuns));\n for (const { color, items } of groupByPaint(curves, (e) => ({\n color: brightenAbgr(e.color, factor),\n weight: e.thickness,\n last: false\n }))) {\n this.strokeCurves(items, color);\n }\n const lifted = [...this.liftedStrokes(batch)];\n for (const { color, items } of groupByPaint(lifted, ([i, f]) => ({\n color: brightenAbgr(batch.nodeStrokes[i].color, f),\n weight: batch.nodeStrokes[i].thickness,\n last: false\n }))) {\n this.strokeNodes(\n items.map(([i]) => batch.nodeStrokes[i]),\n color\n );\n }\n const arrows = runItems(batch.arrows, this.edgeRun(batch.arrowRuns));\n for (const { color, items } of groupByPaint(arrows, (a) => ({\n color: brightenAbgr(a.color, factor),\n weight: 0,\n last: false\n }))) {\n this.fillArrows(items, color);\n }\n }\n edgeRun(runs) {\n return this.highlightedEdge === null ? void 0 : runs.get(this.highlightedEdge);\n }\n // stroke index -> brighten factor, for the nodes the model lifted\n liftedStrokes(batch) {\n const lifted = /* @__PURE__ */ new Map();\n for (const [nodeId, factor] of this.nodeHighlights) {\n const run = batch.nodeStrokeRuns.get(nodeId);\n if (run) {\n for (let i = run.start; i < run.start + run.count; i++) {\n lifted.set(i, factor);\n }\n }\n }\n return lifted;\n }\n strokeCurves(items, color) {\n const t = this.transform;\n const ctx = this.ctx;\n ctx.strokeStyle = abgrToCssRgba(color);\n ctx.lineWidth = items[0].thickness * 2 * t.dpr;\n ctx.beginPath();\n for (const e of items) {\n const first = e.curves[0];\n ctx.moveTo(\n first.x0 * t.scaleX + t.translateX,\n first.y0 * t.scaleY + t.translateY\n );\n for (const c of e.curves) {\n ctx.bezierCurveTo(\n c.cx0 * t.scaleX + t.translateX,\n c.cy0 * t.scaleY + t.translateY,\n c.cx1 * t.scaleX + t.translateX,\n c.cy1 * t.scaleY + t.translateY,\n c.x1 * t.scaleX + t.translateX,\n c.y1 * t.scaleY + t.translateY\n );\n }\n }\n ctx.stroke();\n }\n strokeNodes(items, color) {\n const t = this.transform;\n const ctx = this.ctx;\n ctx.strokeStyle = abgrToCssRgba(color);\n ctx.lineWidth = items[0].thickness * 2 * t.dpr;\n ctx.beginPath();\n for (const s of items) {\n const p0 = s.points[0];\n ctx.moveTo(p0.x * t.scaleX + t.translateX, p0.y * t.scaleY + t.translateY);\n for (let i = 1, l = s.points.length; i < l; i++) {\n const p = s.points[i];\n ctx.lineTo(p.x * t.scaleX + t.translateX, p.y * t.scaleY + t.translateY);\n }\n }\n ctx.stroke();\n }\n fillArrows(items, color) {\n const t = this.transform;\n const ctx = this.ctx;\n ctx.fillStyle = abgrToCssRgba(color);\n ctx.beginPath();\n for (const a of items) {\n const [tip, left, notch, right] = arrowheadOutline(a, t);\n ctx.moveTo(tip.x, tip.y);\n ctx.lineTo(left.x, left.y);\n ctx.lineTo(notch.x, notch.y);\n ctx.lineTo(right.x, right.y);\n ctx.closePath();\n }\n ctx.fill();\n }\n dispose() {\n this.batch = null;\n this.nodeHighlights = /* @__PURE__ */ new Map();\n this.highlightedEdge = null;\n }\n};\nvar ARROW_NOTCH = 0.25;\nfunction arrowheadOutline(a, t) {\n const ux = Math.cos(a.angle);\n const uy = Math.sin(a.angle);\n const tipX = a.x * t.scaleX + t.translateX;\n const tipY = a.y * t.scaleY + t.translateY;\n const length = a.length * t.dpr;\n const halfWidth = a.halfWidth * t.dpr;\n const backX = tipX - ux * length;\n const backY = tipY - uy * length;\n const notchBack = length * (1 - ARROW_NOTCH);\n return [\n { x: tipX, y: tipY },\n { x: backX - uy * halfWidth, y: backY + ux * halfWidth },\n { x: tipX - ux * notchBack, y: tipY - uy * notchBack },\n { x: backX + uy * halfWidth, y: backY - ux * halfWidth }\n ];\n}\nfunction runItems(items, run) {\n return run ? items.slice(run.start, run.start + run.count) : [];\n}\nfunction inRun(run, i) {\n return run !== void 0 && i >= run.start && i < run.start + run.count;\n}\nfunction groupByPaint(items, paintOf) {\n const groups = /* @__PURE__ */ new Map();\n const deferred = /* @__PURE__ */ new Map();\n for (let i = 0, l = items.length; i < l; i++) {\n const item = items[i];\n const { color, weight, last } = paintOf(item, i);\n const into = last ? deferred : groups;\n const key = `${color}:${weight}`;\n const group = into.get(key);\n if (group) {\n group.items.push(item);\n } else {\n into.set(key, { color, items: [item] });\n }\n }\n return [...groups.values(), ...deferred.values()];\n}\n\nexport {\n Canvas2DRenderer,\n arrowheadOutline\n};\n", "import {\n baseEdgeCurves\n} from \"./chunk-ZY2AFL4Y.js\";\nimport {\n curveBounds,\n pathRibbonOffsets\n} from \"./chunk-7SRWJLSC.js\";\n\n// src/util/SpatialIndex.ts\nvar FALLBACK_CELL_SIZE = 50;\nfunction meanExtentCellSize(extentTotal, count) {\n return count > 0 ? Math.max(1, extentTotal / count) : FALLBACK_CELL_SIZE;\n}\nfunction rowPitchOf(boxes) {\n const distinct = /* @__PURE__ */ new Set();\n let min = Infinity;\n let max = -Infinity;\n for (const box of boxes) {\n distinct.add(box.minY);\n min = Math.min(min, box.minY);\n max = Math.max(max, box.minY);\n }\n return distinct.size > 1 ? (max - min) / (distinct.size - 1) : void 0;\n}\nfunction cellSizeFrom(boxes, extentX, extentY) {\n const x = meanExtentCellSize(extentX, boxes.length);\n return {\n x,\n y: extentY > 0 ? meanExtentCellSize(extentY, boxes.length) : rowPitchOf(boxes) ?? x\n };\n}\nfunction resolveCellSize(given, boxes, extentX, extentY) {\n return given === void 0 ? cellSizeFrom(boxes, extentX, extentY) : typeof given === \"number\" ? { x: given, y: given } : given;\n}\nfunction getOrCreateCell(cells, cx, cy) {\n let row = cells.get(cx);\n if (!row) {\n row = /* @__PURE__ */ new Map();\n cells.set(cx, row);\n }\n let cell = row.get(cy);\n if (!cell) {\n cell = [];\n row.set(cy, cell);\n }\n return cell;\n}\nfunction addToGrid(cells, cellSize, minX, minY, maxX, maxY, entry) {\n const cx0 = Math.floor(minX / cellSize.x);\n const cx1 = Math.floor(maxX / cellSize.x);\n const cy0 = Math.floor(minY / cellSize.y);\n const cy1 = Math.floor(maxY / cellSize.y);\n for (let cx = cx0; cx <= cx1; cx++) {\n for (let cy = cy0; cy <= cy1; cy++) {\n getOrCreateCell(cells, cx, cy).push(entry);\n }\n }\n}\nfunction queryGrid(cells, cellSize, x, y, radiusX, radiusY) {\n const cx0 = Math.floor((x - radiusX) / cellSize.x);\n const cx1 = Math.floor((x + radiusX) / cellSize.x);\n const cy0 = Math.floor((y - radiusY) / cellSize.y);\n const cy1 = Math.floor((y + radiusY) / cellSize.y);\n const results = [];\n const seen = /* @__PURE__ */ new Set();\n for (let cx = cx0; cx <= cx1; cx++) {\n const row = cells.get(cx);\n if (row) {\n for (let cy = cy0; cy <= cy1; cy++) {\n const cell = row.get(cy);\n if (cell) {\n for (const entry of cell) {\n if (!seen.has(entry)) {\n seen.add(entry);\n results.push(entry);\n }\n }\n }\n }\n }\n }\n return results;\n}\nvar SpatialIndex = class {\n constructor(nodePositions, cellSize) {\n this.cells = /* @__PURE__ */ new Map();\n const boxes = [];\n let extentX = 0;\n let extentY = 0;\n for (const [nodeId, segments] of Object.entries(nodePositions)) {\n for (let i = 0; i < segments.length - 1; i++) {\n const seg = segments[i];\n const next = segments[i + 1];\n const minX = Math.min(seg.x, next.x);\n const minY = Math.min(seg.y, next.y);\n const maxX = Math.max(seg.x, next.x);\n const maxY = Math.max(seg.y, next.y);\n extentX += maxX - minX;\n extentY += maxY - minY;\n boxes.push({ entry: { nodeId, segmentIdx: i }, minX, minY, maxX, maxY });\n }\n }\n this.cellSize = resolveCellSize(cellSize, boxes, extentX, extentY);\n for (const b of boxes) {\n addToGrid(\n this.cells,\n this.cellSize,\n b.minX,\n b.minY,\n b.maxX,\n b.maxY,\n b.entry\n );\n }\n }\n query(x, y, radiusX, radiusY = radiusX) {\n return queryGrid(this.cells, this.cellSize, x, y, radiusX, radiusY);\n }\n};\nvar EdgeSpatialIndex = class {\n constructor(nodePositions, graph, drawPaths, axis, cellSize, deletions, version = 0, routes, stranded = false) {\n this.cells = /* @__PURE__ */ new Map();\n this.edgeCurves = baseEdgeCurves(\n nodePositions,\n graph,\n axis,\n deletions,\n version,\n routes,\n stranded\n );\n const boxes = [];\n let extentX = 0;\n let extentY = 0;\n for (let ei = 0; ei < graph.edges.length; ei++) {\n const edge = graph.edges[ei];\n const fromSegments = nodePositions[edge.from];\n const toSegments = nodePositions[edge.to];\n const curves = this.edgeCurves.get(ei);\n if (fromSegments?.length && toSegments?.length && curves) {\n let { minX, minY, maxX, maxY } = curveBounds(curves);\n const numPaths = edge.pathIds?.length ?? 0;\n if (drawPaths && numPaths > 0) {\n let padX = 0;\n let padY = 0;\n for (const o of pathRibbonOffsets(\n fromSegments,\n toSegments,\n numPaths,\n axis\n )) {\n padX = Math.max(padX, Math.abs(o.x));\n padY = Math.max(padY, Math.abs(o.y));\n }\n minX -= padX;\n minY -= padY;\n maxX += padX;\n maxY += padY;\n }\n extentX += maxX - minX;\n extentY += maxY - minY;\n boxes.push({ ei, minX, minY, maxX, maxY });\n }\n }\n this.cellSize = resolveCellSize(cellSize, boxes, extentX, extentY);\n for (const b of boxes) {\n addToGrid(this.cells, this.cellSize, b.minX, b.minY, b.maxX, b.maxY, b.ei);\n }\n }\n getCurves(ei) {\n return this.edgeCurves.get(ei);\n }\n query(x, y, radiusX, radiusY = radiusX) {\n return queryGrid(this.cells, this.cellSize, x, y, radiusX, radiusY);\n }\n};\n\nexport {\n SpatialIndex,\n EdgeSpatialIndex\n};\n", "import {\n EdgeSpatialIndex,\n SpatialIndex\n} from \"./chunk-KBEP7VYK.js\";\nimport {\n pathRibbonOffsets,\n translateCurves,\n yToXOf\n} from \"./chunk-7SRWJLSC.js\";\n\n// src/util/hitDetection.ts\nfunction distanceToSegment(px, py, x1, y1, x2, y2) {\n const dx = x2 - x1;\n const dy = y2 - y1;\n const lenSq = dx * dx + dy * dy;\n if (lenSq === 0) {\n return Math.hypot(px - x1, py - y1);\n }\n const t = Math.max(0, Math.min(1, ((px - x1) * dx + (py - y1) * dy) / lenSq));\n return Math.hypot(px - (x1 + t * dx), py - (y1 + t * dy));\n}\nfunction distanceToCubicBezier(px, py, x1, y1, cx1, cy1, cx2, cy2, x2, y2) {\n let minDist = Infinity;\n const samples = 20;\n let lastX = x1;\n let lastY = y1;\n for (let i = 1; i <= samples; i++) {\n const t = i / samples;\n const u = 1 - t;\n const bx = u * u * u * x1 + 3 * u * u * t * cx1 + 3 * u * t * t * cx2 + t * t * t * x2;\n const by = u * u * u * y1 + 3 * u * u * t * cy1 + 3 * u * t * t * cy2 + t * t * t * y2;\n minDist = Math.min(minDist, distanceToSegment(px, py, lastX, lastY, bx, by));\n lastX = bx;\n lastY = by;\n }\n return minDist;\n}\nfunction distanceToBezierCurve(px, py, c) {\n return distanceToCubicBezier(\n px,\n py,\n c.x0,\n c.y0,\n c.cx0,\n c.cy0,\n c.cx1,\n c.cy1,\n c.x1,\n c.y1\n );\n}\nfunction distanceToEdgeCurves(px, py, curves, yToX = 1) {\n let minDist = Infinity;\n for (const c of curves) {\n const d = distanceToBezierCurve(\n px,\n py,\n yToX === 1 ? c : {\n x0: c.x0,\n y0: c.y0 * yToX,\n cx0: c.cx0,\n cy0: c.cy0 * yToX,\n cx1: c.cx1,\n cy1: c.cy1 * yToX,\n x1: c.x1,\n y1: c.y1 * yToX\n }\n );\n if (d < minDist) {\n minDist = d;\n }\n }\n return minDist;\n}\nvar nodeCache = /* @__PURE__ */ new WeakMap();\nfunction getSpatialIndex(nodePositions, version) {\n const cached = nodeCache.get(nodePositions);\n if (cached?.version === version) {\n return cached.index;\n }\n const index = new SpatialIndex(nodePositions);\n nodeCache.set(nodePositions, { version, index });\n return index;\n}\nvar edgeCache = /* @__PURE__ */ new WeakMap();\nfunction getEdgeSpatialIndex(nodePositions, graph, drawPaths, axis, version, deletions, routes, stranded = false) {\n const cached = edgeCache.get(nodePositions);\n if (cached?.graph === graph && cached.drawPaths === drawPaths && cached.scaleX === axis.scaleX && cached.scaleY === axis.scaleY && cached.version === version && cached.deletions === deletions && cached.routes === routes && cached.stranded === stranded) {\n return cached.index;\n }\n const index = new EdgeSpatialIndex(\n nodePositions,\n graph,\n drawPaths,\n axis,\n void 0,\n deletions,\n version,\n routes,\n stranded\n );\n edgeCache.set(nodePositions, {\n graph,\n drawPaths,\n scaleX: axis.scaleX,\n scaleY: axis.scaleY,\n version,\n index,\n deletions,\n routes,\n stranded\n });\n return index;\n}\nvar MIN_NODE_REACH_PX = 5;\nfunction findHoveredNode(nodePositions, graphX, graphY, axis, version = 0, ink) {\n const yToX = yToXOf(axis);\n const index = getSpatialIndex(nodePositions, version);\n const reach = (px) => Math.max(MIN_NODE_REACH_PX, px) / axis.scaleX;\n const queryReach = reach(ink?.maxHalfWidthPx ?? 0);\n const candidates = index.query(graphX, graphY, queryReach, queryReach / yToX);\n let hovered = null;\n let best = Infinity;\n for (const { nodeId, segmentIdx } of candidates) {\n const segments = nodePositions[nodeId];\n const dist = distanceToSegment(\n graphX,\n graphY * yToX,\n segments[segmentIdx].x,\n segments[segmentIdx].y * yToX,\n segments[segmentIdx + 1].x,\n segments[segmentIdx + 1].y * yToX\n );\n if (dist < best && dist < reach(ink?.halfWidthPx(nodeId) ?? 0)) {\n best = dist;\n hovered = nodeId;\n }\n }\n return hovered;\n}\nfunction segmentMeetsBox(a, b, box) {\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n let t0 = 0;\n let t1 = 1;\n for (const [p, q] of [\n [-dx, a.x - box.x0],\n [dx, box.x1 - a.x],\n [-dy, a.y - box.y0],\n [dy, box.y1 - a.y]\n ]) {\n if (p === 0) {\n if (q < 0) {\n return false;\n }\n } else if (p < 0) {\n t0 = Math.max(t0, q / p);\n } else {\n t1 = Math.min(t1, q / p);\n }\n }\n return t0 <= t1;\n}\nfunction nodesUnderBox(nodePositions, t, version = 0) {\n const index = getSpatialIndex(nodePositions, version);\n const screen = (p) => ({\n x: p.x * t.scaleX + t.translateX,\n y: p.y * t.scaleY + t.translateY\n });\n return (box) => {\n const hits = /* @__PURE__ */ new Set();\n const candidates = index.query(\n ((box.x0 + box.x1) / 2 - t.translateX) / t.scaleX,\n ((box.y0 + box.y1) / 2 - t.translateY) / t.scaleY,\n Math.abs((box.x1 - box.x0) / 2 / t.scaleX),\n Math.abs((box.y1 - box.y0) / 2 / t.scaleY)\n );\n for (const { nodeId, segmentIdx } of candidates) {\n const line = nodePositions[nodeId];\n if (!hits.has(nodeId) && segmentMeetsBox(\n screen(line[segmentIdx]),\n screen(line[segmentIdx + 1]),\n box\n )) {\n hits.add(nodeId);\n }\n }\n return hits;\n };\n}\nfunction findHoveredEdge(nodePositions, graph, graphX, graphY, axis, drawPaths, version = 0, deletions, hiddenEdges, deletionRoutes, stranded = false) {\n const yToX = yToXOf(axis);\n const edgeThreshold = 10 / axis.scaleX;\n const edgeIndex = getEdgeSpatialIndex(\n nodePositions,\n graph,\n drawPaths,\n axis,\n version,\n deletions,\n deletionRoutes,\n stranded\n );\n const candidates = edgeIndex.query(\n graphX,\n graphY,\n edgeThreshold,\n edgeThreshold / yToX\n );\n let hovered = null;\n let best = edgeThreshold;\n for (const edgeIdx of candidates) {\n const edge = graph.edges[edgeIdx];\n const fromSegments = nodePositions[edge.from];\n const toSegments = nodePositions[edge.to];\n if (!fromSegments?.length || !toSegments?.length || hiddenEdges?.has(edgeIdx)) {\n continue;\n }\n const numPaths = edge.pathIds?.length ?? 0;\n const baseCurves = edgeIndex.getCurves(edgeIdx);\n if (!baseCurves) {\n continue;\n }\n let dist;\n if (!drawPaths || numPaths === 0) {\n dist = distanceToEdgeCurves(graphX, graphY * yToX, baseCurves, yToX);\n } else {\n let minDist = Infinity;\n for (const offset of pathRibbonOffsets(\n fromSegments,\n toSegments,\n numPaths,\n axis\n )) {\n const curves = offset.x === 0 && offset.y === 0 ? baseCurves : translateCurves(baseCurves, offset.x, offset.y);\n const d = distanceToEdgeCurves(graphX, graphY * yToX, curves, yToX);\n if (d < minDist) {\n minDist = d;\n }\n }\n dist = minDist;\n }\n if (dist < best) {\n best = dist;\n hovered = edgeIdx;\n }\n }\n return hovered;\n}\n\nexport {\n distanceToSegment,\n distanceToCubicBezier,\n findHoveredNode,\n nodesUnderBox,\n findHoveredEdge\n};\n", "import {\n nodesUnderBox\n} from \"./chunk-4HWM3FNK.js\";\nimport {\n nodeLabelBudget,\n placeSizeLabels,\n rowLabelBox,\n sizeLabelCandidates\n} from \"./chunk-PTABFYQ7.js\";\nimport {\n LABEL_CHAR_PX,\n LABEL_PAD,\n LABEL_PX,\n occupancy,\n placeLabels\n} from \"./chunk-AB35TJST.js\";\n\n// src/labelLayout.ts\nvar HALO_FACTOR = 3.4;\nvar LEGEND_INSET_PX = 6;\nvar GENE_PIN_DROP_PX = 18;\nvar GENE_STACK = 2;\nvar BUBBLE_STACK = 3;\nvar TOPMOST_BASELINE = LABEL_PX + LABEL_PAD;\nfunction geneCoverageNote(pin) {\n const length = pin.gene.end - pin.gene.start;\n if (pin.covered >= 0.98) {\n return void 0;\n }\n const [per, unit] = length >= 1e6 ? [1e6, \"Mb\"] : length >= 1e3 ? [1e3, \"kb\"] : [1, \"bp\"];\n const amount = (bp) => +(bp / per).toFixed(per === 1 ? 0 : 1);\n return `${amount(pin.covered * length)} of ${amount(length)} ${unit}`;\n}\nfunction geneLabelCandidates(pins, screen, contigThickness, nodesUnder) {\n const ink = contigThickness / 2;\n return byExtent(pins, (pin) => pin.gene.end - pin.gene.start).map((pin) => {\n const { x, y } = screen(pin.at);\n const note = geneCoverageNote(pin);\n return {\n item: pin,\n x,\n y: y + contigThickness + GENE_PIN_DROP_PX,\n text: note ? `${pin.gene.name} \\xB7 ${note}` : pin.gene.name,\n fallback: note ? `${pin.gene.name} \\u2026` : void 0,\n stack: GENE_STACK,\n fits: (box) => [\n ...nodesUnder({\n x0: box.x0 - ink,\n x1: box.x1 + ink,\n y0: box.y0 - ink,\n y1: box.y1 + ink\n })\n ].every((id) => pin.nodeIds.has(id))\n };\n });\n}\nfunction byExtent(items, extent) {\n return [...items].sort((a, b) => extent(b) - extent(a));\n}\nfunction layoutLabels(m) {\n const { paneWidth: width, canvasHeight: height, translateX, translateY } = m;\n const { scaleX, scaleY } = m.axisScale;\n const frame = { width, height };\n const screen = (p) => ({\n x: p.x * scaleX + translateX,\n y: p.y * scaleY + translateY\n });\n const reserved = m.drawnRowLabels.map(\n ({ label, y }) => rowLabelBox(label, y * scaleY + translateY)\n );\n const stripPx = m.referenceStripZonePx ?? 0;\n if (stripPx > 0) {\n reserved.push({ x0: 0, x1: width, y0: 0, y1: stripPx });\n }\n if (m.legendSize.width > 0) {\n reserved.push({\n x0: width - LEGEND_INSET_PX - m.legendSize.width,\n x1: width,\n y0: 0,\n y1: stripPx + LEGEND_INSET_PX + m.legendSize.height\n });\n }\n if (m.poppedFrom) {\n reserved.push({\n x0: 0,\n x1: 60 + m.poppedFrom.label.length * LABEL_CHAR_PX * 1.2,\n y0: 0,\n y1: 44\n });\n }\n const take = occupancy(frame, reserved);\n const onRows = m.drawnRowLabels.length > 0;\n const rowsTop = onRows ? Math.min(...m.drawnRowLabels.map((r) => r.y)) : Infinity;\n const halo = m.contigThickness * HALO_FACTOR;\n const above = (h, gap) => {\n const { x, y } = screen({\n x: h.labelAt.x,\n y: Math.min(h.labelAt.y, rowsTop)\n });\n const baseline = y - halo / 2 - gap;\n return { x, y: onRows ? Math.max(baseline, TOPMOST_BASELINE) : baseline };\n };\n const byBubble = byExtent(\n m.bubbleHalos.filter((h) => !h.tick),\n (h) => h.whole ? -1 : h.members\n );\n const bubbles = placeLabels(\n byBubble.map((h) => ({\n item: h,\n ...above(h, 6),\n text: h.label,\n // `0 bp\u201311 kb superbubble` where `\u2026, 1198 segments, 5 routes` does not fit\n fallback: h.label.includes(\",\") ? h.label.split(\",\")[0] : void 0,\n stack: BUBBLE_STACK\n })),\n frame,\n take\n );\n const ticks = m.bubbleHalos.filter((h) => h.tick && !h.whole).map((h) => ({ item: h, ...above(h, 2) })).filter((t) => t.x >= 0 && t.x <= width && t.y >= 0 && t.y <= height);\n const genes = placeLabels(\n geneLabelCandidates(\n m.genePins,\n screen,\n m.contigThickness,\n nodesUnderBox(\n m.nodePositions ?? {},\n { scaleX, scaleY, translateX, translateY },\n m.positionsVersion\n )\n ),\n frame,\n take\n );\n const sizeCandidates = m.nodePositions && m.labelsNodeSizes ? sizeLabelCandidates({\n nodePositions: m.nodePositions,\n nodeLengths: m.nodeLengths,\n deletions: m.deletions,\n deletionRoutes: m.deletionRoutes,\n stranded: m.stranded,\n alleleDeletions: m.alleleDeletions,\n axis: m.axisScale,\n translateX,\n translateY,\n width,\n height,\n version: m.positionsVersion\n }) : { deletions: [], nodes: [] };\n const deletionLabels = placeSizeLabels(sizeCandidates.deletions, take);\n const nodeLabels = placeSizeLabels(\n sizeCandidates.nodes,\n take,\n nodeLabelBudget(width, height)\n );\n return {\n bubbles,\n ticks,\n genes,\n sizes: [...deletionLabels, ...nodeLabels]\n };\n}\n\nexport {\n HALO_FACTOR,\n LEGEND_INSET_PX,\n geneCoverageNote,\n geneLabelCandidates,\n layoutLabels\n};\n", "const host = JBrowseExports[\"mobx\"]\nconst read = name =>\n host != null && name in Object(host)\n ? host[name]\n : Object.assign(\n function () {\n throw new Error(\n \"This JBrowse does not provide '\" + name + \"' from '\" + \"mobx\" + \"' to plugins: GraphGenomeView was built for a different JBrowse version, so update the plugin or JBrowse\",\n )\n },\n { jbrowseHostMissing: name },\n )\nexport const $mobx = /* @__PURE__ */ read(\"$mobx\")\nexport const FlowCancellationError = /* @__PURE__ */ read(\"FlowCancellationError\")\nexport const ObservableMap = /* @__PURE__ */ read(\"ObservableMap\")\nexport const ObservableSet = /* @__PURE__ */ read(\"ObservableSet\")\nexport const Reaction = /* @__PURE__ */ read(\"Reaction\")\nexport const _allowStateChanges = /* @__PURE__ */ read(\"_allowStateChanges\")\nexport const _allowStateChangesInsideComputed = /* @__PURE__ */ read(\"_allowStateChangesInsideComputed\")\nexport const _allowStateReadsEnd = /* @__PURE__ */ read(\"_allowStateReadsEnd\")\nexport const _allowStateReadsStart = /* @__PURE__ */ read(\"_allowStateReadsStart\")\nexport const _autoAction = /* @__PURE__ */ read(\"_autoAction\")\nexport const _autoActionBound = /* @__PURE__ */ read(\"_autoActionBound\")\nexport const _endAction = /* @__PURE__ */ read(\"_endAction\")\nexport const _getAdministration = /* @__PURE__ */ read(\"_getAdministration\")\nexport const _getGlobalState = /* @__PURE__ */ read(\"_getGlobalState\")\nexport const _interceptReads = /* @__PURE__ */ read(\"_interceptReads\")\nexport const _isComputingDerivation = /* @__PURE__ */ read(\"_isComputingDerivation\")\nexport const _resetGlobalState = /* @__PURE__ */ read(\"_resetGlobalState\")\nexport const _startAction = /* @__PURE__ */ read(\"_startAction\")\nexport const action = /* @__PURE__ */ read(\"action\")\nexport const actionBound = /* @__PURE__ */ read(\"actionBound\")\nexport const autorun = /* @__PURE__ */ read(\"autorun\")\nexport const compareDefault = /* @__PURE__ */ read(\"compareDefault\")\nexport const compareIdentity = /* @__PURE__ */ read(\"compareIdentity\")\nexport const compareShallow = /* @__PURE__ */ read(\"compareShallow\")\nexport const compareStructural = /* @__PURE__ */ read(\"compareStructural\")\nexport const computed = /* @__PURE__ */ read(\"computed\")\nexport const computedStruct = /* @__PURE__ */ read(\"computedStruct\")\nexport const configure = /* @__PURE__ */ read(\"configure\")\nexport const createAtom = /* @__PURE__ */ read(\"createAtom\")\nexport const defineProperty = /* @__PURE__ */ read(\"defineProperty\")\nexport const entries = /* @__PURE__ */ read(\"entries\")\nexport const extendObservable = /* @__PURE__ */ read(\"extendObservable\")\nexport const flow = /* @__PURE__ */ read(\"flow\")\nexport const flowBound = /* @__PURE__ */ read(\"flowBound\")\nexport const flowResult = /* @__PURE__ */ read(\"flowResult\")\nexport const get = /* @__PURE__ */ read(\"get\")\nexport const getAtom = /* @__PURE__ */ read(\"getAtom\")\nexport const getDebugName = /* @__PURE__ */ read(\"getDebugName\")\nexport const getDependencyTree = /* @__PURE__ */ read(\"getDependencyTree\")\nexport const getObserverTree = /* @__PURE__ */ read(\"getObserverTree\")\nexport const has = /* @__PURE__ */ read(\"has\")\nexport const intercept = /* @__PURE__ */ read(\"intercept\")\nexport const isAction = /* @__PURE__ */ read(\"isAction\")\nexport const isBoxedObservable = /* @__PURE__ */ read(\"isBoxedObservable\")\nexport const isComputed = /* @__PURE__ */ read(\"isComputed\")\nexport const isComputedProp = /* @__PURE__ */ read(\"isComputedProp\")\nexport const isFlow = /* @__PURE__ */ read(\"isFlow\")\nexport const isFlowCancellationError = /* @__PURE__ */ read(\"isFlowCancellationError\")\nexport const isObservable = /* @__PURE__ */ read(\"isObservable\")\nexport const isObservableArray = /* @__PURE__ */ read(\"isObservableArray\")\nexport const isObservableMap = /* @__PURE__ */ read(\"isObservableMap\")\nexport const isObservableObject = /* @__PURE__ */ read(\"isObservableObject\")\nexport const isObservableProp = /* @__PURE__ */ read(\"isObservableProp\")\nexport const isObservableSet = /* @__PURE__ */ read(\"isObservableSet\")\nexport const keys = /* @__PURE__ */ read(\"keys\")\nexport const makeAutoObservable = /* @__PURE__ */ read(\"makeAutoObservable\")\nexport const makeObservable = /* @__PURE__ */ read(\"makeObservable\")\nexport const observable = /* @__PURE__ */ read(\"observable\")\nexport const observableDeep = /* @__PURE__ */ read(\"observableDeep\")\nexport const observableRef = /* @__PURE__ */ read(\"observableRef\")\nexport const observableShallow = /* @__PURE__ */ read(\"observableShallow\")\nexport const observableStruct = /* @__PURE__ */ read(\"observableStruct\")\nexport const observe = /* @__PURE__ */ read(\"observe\")\nexport const onBecomeObserved = /* @__PURE__ */ read(\"onBecomeObserved\")\nexport const onBecomeUnobserved = /* @__PURE__ */ read(\"onBecomeUnobserved\")\nexport const onReactionError = /* @__PURE__ */ read(\"onReactionError\")\nexport const override = /* @__PURE__ */ read(\"override\")\nexport const ownKeys = /* @__PURE__ */ read(\"ownKeys\")\nexport const reaction = /* @__PURE__ */ read(\"reaction\")\nexport const remove = /* @__PURE__ */ read(\"remove\")\nexport const runInAction = /* @__PURE__ */ read(\"runInAction\")\nexport const set = /* @__PURE__ */ read(\"set\")\nexport const spy = /* @__PURE__ */ read(\"spy\")\nexport const toJS = /* @__PURE__ */ read(\"toJS\")\nexport const transaction = /* @__PURE__ */ read(\"transaction\")\nexport const untracked = /* @__PURE__ */ read(\"untracked\")\nexport const values = /* @__PURE__ */ read(\"values\")\nexport const when = /* @__PURE__ */ read(\"when\")\nexport default host && host.__esModule ? host.default : host", "import {\n parseCs\n} from \"./chunk-C44YRP5F.js\";\n\n// src/tubeMap/reads.ts\nfunction canonicalStrand(node) {\n return node.id.endsWith(\"-\") ? \"-\" : \"+\";\n}\nfunction stepName(node, strand) {\n return strand === canonicalStrand(node) ? node.id : `-${node.id}`;\n}\nfunction stepStarts(lengths, total) {\n const starts = lengths.map(() => void 0);\n let head = 0;\n let i = 0;\n for (; i < lengths.length && lengths[i] !== void 0; i++) {\n starts[i] = head;\n head += lengths[i];\n }\n let tail = total;\n for (let j = lengths.length - 1; j > i && lengths[j] !== void 0; j--) {\n tail -= lengths[j];\n starts[j] = tail;\n }\n return starts;\n}\nfunction mismatchesByStep(record, lengths) {\n const byStep = record.path.map(() => []);\n if (record.cs === void 0) {\n return byStep;\n }\n const starts = stepStarts(lengths, record.pathLength);\n const known = starts.flatMap((start, s) => start === void 0 ? [] : [s]);\n const startOf = (k) => starts[known[k]];\n const endOf = (k) => startOf(k) + lengths[known[k]];\n let first = 0;\n const stepAt = (pos2, atEnd = false) => {\n while (first < known.length && endOf(first) < pos2) {\n first++;\n }\n for (let k = first; k < known.length && startOf(k) <= pos2; k++) {\n const end = endOf(k);\n if (pos2 < end || atEnd && pos2 === end) {\n return { s: known[k], local: pos2 - startOf(k), room: end - pos2 };\n }\n }\n return void 0;\n };\n const unplacedFrom = (pos2) => {\n for (let k = first; k < known.length; k++) {\n if (startOf(k) > pos2) {\n return startOf(k) - pos2;\n }\n }\n return Infinity;\n };\n const add = (s, mismatch) => {\n const list = byStep[s];\n const last = list.at(-1);\n if (mismatch.type === \"substitution\" && last?.type === \"substitution\" && last.pos + last.seq.length === mismatch.pos) {\n last.seq += mismatch.seq;\n } else {\n list.push(mismatch);\n }\n };\n let pos = record.pathStart;\n for (const op of parseCs(record.cs)) {\n if (op.op === \"match\") {\n pos += op.length;\n } else if (op.op === \"substitution\") {\n const at = stepAt(pos);\n if (at) {\n add(at.s, { type: \"substitution\", pos: at.local, seq: op.seq });\n }\n pos += 1;\n } else if (op.op === \"insertion\") {\n const at = stepAt(pos, pos === record.pathEnd);\n if (at) {\n add(at.s, { type: \"insertion\", pos: at.local, seq: op.seq });\n }\n } else {\n let left = op.length;\n while (left > 0) {\n const at = stepAt(pos);\n const take = Math.min(left, at ? at.room : unplacedFrom(pos));\n if (at) {\n add(at.s, { type: \"deletion\", pos: at.local, length: take });\n }\n pos += take;\n left -= take;\n }\n }\n }\n return byStep;\n}\nfunction tubeMapReads(graph, records, firstId) {\n const nodeByName = new Map(graph.nodes.map((n) => [n.name, n]));\n const reads = [];\n for (const record of records) {\n const nodes = record.path.map((step) => nodeByName.get(step.name));\n const kept = nodes.flatMap((node, i) => node ? [i] : []);\n const first = kept[0];\n const last = kept.at(-1);\n if (first !== void 0 && last !== void 0) {\n const mismatches = mismatchesByStep(\n record,\n nodes.map((n) => n?.length)\n );\n const names = kept.map((i) => stepName(nodes[i], record.path[i].strand));\n const lastLength = nodes[last].length;\n reads.push({\n id: firstId + reads.length,\n name: record.name,\n type: \"read\",\n sourceTrackID: 1,\n sequence: names,\n sequenceNew: kept.map((i, k) => ({\n nodeName: names[k],\n mismatches: mismatches[i]\n })),\n firstNodeOffset: first === 0 ? record.pathStart : 0,\n finalNodeCoverLength: last === record.path.length - 1 ? lastLength - (record.pathLength - record.pathEnd) : lastLength,\n // 255 is GAF's missing MAPQ\n mapping_quality: record.mappingQuality === 255 ? void 0 : record.mappingQuality,\n is_secondary: record.secondary,\n is_reverse: record.strand === \"-\"\n });\n }\n }\n return reads;\n}\nvar FORWARD_READ_COLORS = [\"#6baed6\", \"#4292c6\", \"#2171b5\", \"#08519c\"];\nvar REVERSE_READ_COLORS = [\"#fb6a4a\", \"#ef3b2c\", \"#cb181d\", \"#a50f15\"];\nfunction readColor(read) {\n const colors = read.is_reverse ? REVERSE_READ_COLORS : FORWARD_READ_COLORS;\n return colors[read.id % colors.length];\n}\n\nexport {\n canonicalStrand,\n stepName,\n tubeMapReads,\n FORWARD_READ_COLORS,\n REVERSE_READ_COLORS,\n readColor\n};\n", "import {\n REFERENCE_RAMP_MAX_HUE\n} from \"./chunk-A4PFFC4Q.js\";\n\n// src/referenceRampCss.ts\nfunction rampHueCss(hue) {\n return `hsl(${hue}, 70%, 50%)`;\n}\nfunction rampHue(bp, domain) {\n const frac = (bp - domain.start) / (domain.end - domain.start);\n return Math.max(0, Math.min(1, frac)) * REFERENCE_RAMP_MAX_HUE;\n}\nvar HUE_STOP_DEG = 30;\nfunction rampStops({ start, bp, reversed }, domain) {\n const low = rampHue(start, domain);\n const high = rampHue(start + bp, domain);\n if (high - low < 1) {\n return [(low + high) / 2];\n }\n const n = Math.ceil((high - low) / HUE_STOP_DEG);\n return Array.from(\n { length: n + 1 },\n (_, i) => rampHue(start + bp * (reversed ? n - i : i) / n, domain)\n );\n}\nvar RAMP_GRADIENT_STOPS = Array.from({ length: 7 }, (_, i) => ({\n offset: i / 6,\n color: rampHueCss(i / 6 * REFERENCE_RAMP_MAX_HUE)\n}));\nvar RAMP_GRADIENT_CSS = `linear-gradient(to right, ${RAMP_GRADIENT_STOPS.map(\n (s) => `${s.color} ${s.offset * 100}%`\n).join(\", \")})`;\n\nexport {\n rampHueCss,\n rampHue,\n rampStops,\n RAMP_GRADIENT_STOPS,\n RAMP_GRADIENT_CSS\n};\n", "// src/el.ts\nfunction el(tag, attrs = {}, ...children) {\n return {\n tag,\n attrs,\n children: children.filter((c) => !!c || c === \"\")\n };\n}\nfunction escapeText(s) {\n return s.replaceAll(\"&\", \"&\").replaceAll(\"<\", \"<\").replaceAll(\">\", \">\");\n}\nfunction escapeAttr(s) {\n return escapeText(s).replaceAll('\"', \""\");\n}\nfunction serializeEl(node) {\n if (typeof node === \"string\") {\n return escapeText(node);\n }\n const attrs = Object.entries(node.attrs).filter(([, v]) => v !== void 0).map(([k, v]) => ` ${k}=\"${escapeAttr(String(v))}\"`).join(\"\");\n return `<${node.tag}${attrs}>${node.children.map(serializeEl).join(\"\")}</${node.tag}>`;\n}\n\nexport {\n el,\n escapeAttr,\n serializeEl\n};\n", "import {\n RAMP_GRADIENT_CSS,\n RAMP_GRADIENT_STOPS,\n rampHueCss,\n rampStops\n} from \"./chunk-XL472HHD.js\";\nimport {\n el\n} from \"./chunk-H2H4Y3TV.js\";\nimport {\n REFERENCE_RAMP_ALT_CSS\n} from \"./chunk-A4PFFC4Q.js\";\nimport {\n LABEL_CHAR_PX\n} from \"./chunk-AB35TJST.js\";\nimport {\n ROW_HEIGHT_PX\n} from \"./chunk-CPMHA4W5.js\";\n\n// src/layout/walkRowDraw.ts\nvar ON_REFERENCE = \"#2f8fd6\";\nvar OFF_REFERENCE = \"#8e3fbf\";\nvar OUTSIDE_CUT = \"#bdbdbd\";\nvar GENE_INK = \"#1c1c22\";\nvar BAR_PX = 12;\nvar GAP_PX = 4;\nvar LABELLED_ROW_PX = 12;\nvar MIN_TILED_BAR_PX = 6;\nvar MIN_TILE_PX = 3;\nfunction kb(bp) {\n return `${(bp / 1e3).toFixed(bp < 1e4 ? 1 : 0)} kb`;\n}\nfunction signedLength(delta) {\n const size = Math.abs(delta);\n return `${delta > 0 ? \"+\" : \"\\u2212\"}${size < 1e3 ? `${size} bp` : kb(size)}`;\n}\nfunction units(bp, unit) {\n return unit ? ` \\u2248 ${Math.round(bp / unit)} units` : \"\";\n}\nfunction walkRowReadout(row, reference, unit, call) {\n const { bp, gapBp, complete, stop } = row;\n if (!reference) {\n return `${kb(bp)}${units(bp, unit)}`;\n }\n const outside = gapBp > 0 ? ` \\xB7 ${kb(gapBp)} outside the cut` : \"\";\n const called = call ? ` \\xB7 called ${kb(call.bp)}${call.spanningReads === 0 ? \" \\xB7 no spanning read\" : \"\"}` : \"\";\n if (complete) {\n const delta = bp - reference.bp;\n const against = delta === 0 ? \"\" : ` (${signedLength(delta)})`;\n return `${kb(bp)}${units(bp, unit)}${against}${outside}${called}`;\n }\n const region = unit ? \"repeat\" : \"window\";\n if (stop?.contigEnds && bp === 0) {\n const where = stop.shortBp > 0 ? `${kb(stop.shortBp)} before` : \"at\";\n return `contig ends ${where} the ${region}${called}`;\n }\n const why = !stop ? \"partial walk\" : stop.contigEnds ? `contig ends inside the ${region}` : \"does not rejoin the reference within the cut\";\n return `\\u2265 ${kb(bp)}${units(bp, unit)} \\xB7 ${why}${outside}${called}`;\n}\nfunction readoutPlacement(text, endX, width) {\n const x = endX + 6;\n const fits = x + text.length * LABEL_CHAR_PX < width;\n return fits ? { x, anchor: \"start\", halo: false } : { x: endX - 6, anchor: \"end\", halo: true };\n}\nfunction unitTicks(bp, unit, pxPerBp) {\n if (unit * pxPerBp < MIN_TILE_PX) {\n return [];\n }\n const ticks = [];\n for (let k = unit; k < bp; k += unit) {\n ticks.push(k);\n }\n return ticks;\n}\nfunction runPaint(run, ramp) {\n if (run.gap) {\n return { fill: OUTSIDE_CUT };\n }\n if (!ramp) {\n return { fill: run.onReference ? ON_REFERENCE : OFF_REFERENCE };\n }\n if (run.referenceStart === void 0) {\n return { fill: REFERENCE_RAMP_ALT_CSS };\n }\n const stops = rampStops({ ...run, start: run.referenceStart }, ramp);\n return stops.length === 1 ? { fill: rampHueCss(stops[0]) } : { stops: stops.map(rampHueCss) };\n}\nfunction alongRow(axis, start, end) {\n return axis.reversed ? { start: axis.start - end, end: axis.start - start } : { start: start - axis.start, end: end - axis.start };\n}\nfunction rowSpan(axis, bp) {\n return axis.reversed ? { start: axis.start - bp, end: axis.start } : { start: axis.start, end: axis.start + bp };\n}\nfunction genesOnRow(row, genes) {\n const contig = row.axis?.contig;\n return genes.filter(\n (g) => g.refName === contig || g.refName.endsWith(`#${contig}`)\n );\n}\nfunction placeRowGenes(rows, byRow) {\n const placed = /* @__PURE__ */ new Map();\n for (const row of rows) {\n const genes = byRow.get(row.name);\n if (!row.axis || !genes) {\n continue;\n }\n const axis = row.axis;\n const clip = ({ start, end }) => ({\n start: Math.max(0, start),\n end: Math.min(row.bp, end)\n });\n placed.set(\n row.name,\n genes.map((g) => ({\n name: g.name,\n ...clip(alongRow(axis, g.start, g.end)),\n exons: g.exons.map((e) => clip(alongRow(axis, e.start, e.end))).filter((e) => e.end > e.start)\n })).filter((g) => g.end > g.start).sort((a, b) => a.start - b.start)\n );\n }\n return placed;\n}\nvar GENE_FONT_PX = 9;\nvar GENE_CHAR_PX = 5.2;\nvar MIN_LETTERED_BAR_PX = 8;\nvar genePad = (rowPx, barPx) => Math.min(2, (rowPx - barPx) / 2 - 1);\nfunction boxesGenes(rowPx, barPx) {\n return genePad(rowPx, barPx) >= 1;\n}\nfunction rowGeneBoxes(genes, X, y, { rowPx = ROW_HEIGHT_PX, barPx = BAR_PX } = {}) {\n if (!boxesGenes(rowPx, barPx)) {\n return [];\n }\n const pad = genePad(rowPx, barPx);\n const boxes = genes.map((g) => {\n const x = X(g.start);\n return {\n g,\n x,\n w: Math.max(2, X(g.end) - x)\n };\n });\n const taken = [];\n const named = new Set(\n (barPx >= MIN_LETTERED_BAR_PX ? [...boxes] : []).sort((a, b) => a.w - b.w).filter(({ g, x, w }) => {\n const half = g.name.length * GENE_CHAR_PX / 2;\n const at = [x + w / 2 - half, x + w / 2 + half];\n if (2 * half > w + 6 || taken.some(([a, b]) => at[0] < b + 2 && at[1] > a - 2)) {\n return false;\n }\n taken.push(at);\n return true;\n })\n );\n return boxes.map((box) => ({\n name: box.g.name,\n x: box.x,\n y: y - barPx / 2 - pad,\n w: box.w,\n h: barPx + 2 * pad,\n exons: box.g.exons.map((e) => ({\n x: X(e.start),\n w: Math.max(1, X(e.end) - X(e.start))\n })),\n label: named.has(box) ? { x: box.x + box.w / 2, y: y + 3, size: GENE_FONT_PX } : void 0\n }));\n}\nvar rowsText = (n) => `${n} row${n === 1 ? \"\" : \"s\"}`;\nfunction walkRowsKey(bars, o = {}) {\n const entries = [\n {\n swatch: o.ramp ? { kind: \"bar\", fill: o.rampCss ?? RAMP_GRADIENT_CSS, ramp: true } : { kind: \"bar\", fill: ON_REFERENCE },\n label: `on ${bars.reference.label}'s path`\n },\n {\n swatch: {\n kind: \"bar\",\n fill: o.ramp ? REFERENCE_RAMP_ALT_CSS : OFF_REFERENCE\n },\n label: `off ${bars.reference.label}'s path`\n }\n ];\n if ([bars.reference, ...bars.rows].some((row) => row.gapBp > 0)) {\n entries.push({\n swatch: { kind: \"gap\", fill: OUTSIDE_CUT },\n label: \"walked outside the cut\"\n });\n }\n if (o.genes?.crowded) {\n entries.push({\n swatch: { kind: \"gene\" },\n label: \"genes left out: too many rows to box them in\",\n note: true\n });\n } else if (o.genes) {\n entries.push({\n swatch: { kind: \"gene\" },\n label: \"gene\"\n });\n if (o.genes.untracked) {\n entries.push({\n swatch: { kind: \"gene\" },\n label: `no gene track for ${rowsText(o.genes.untracked)}`,\n note: true\n });\n }\n if (o.genes.unplaced) {\n entries.push({\n swatch: { kind: \"gene\" },\n label: `no contig coordinates for ${rowsText(o.genes.unplaced)}`,\n note: true\n });\n }\n if (o.genes.unread) {\n entries.push({\n swatch: { kind: \"gene\" },\n label: `genes not read for the last ${rowsText(o.genes.unread)}`,\n note: true\n });\n }\n }\n return entries;\n}\nvar CALL_TICK = \"#111\";\nvar UNBACKED_TICK = \"#9e9e9e\";\nvar DISAGREES = \"#c62828\";\nfunction callTickInk(call) {\n return call.agrees === false ? DISAGREES : call.spanningReads === 0 ? UNBACKED_TICK : CALL_TICK;\n}\nfunction walkRowsKeyTree(entries, x, y, idPrefix = \"walk-key\") {\n let at = 0;\n const parts = entries.flatMap((e, i) => {\n const rampId = `${idPrefix}-ramp-${i}`;\n const ramp = !e.note && e.swatch.kind === \"bar\" && e.swatch.ramp ? el(\n \"linearGradient\",\n { id: rampId },\n ...RAMP_GRADIENT_STOPS.map(\n (s) => el(\"stop\", { offset: s.offset, \"stop-color\": s.color })\n )\n ) : void 0;\n const swatch = e.note ? void 0 : e.swatch.kind === \"gene\" ? el(\"rect\", {\n x: at,\n y: 5,\n width: 18,\n height: 8,\n fill: \"none\",\n stroke: GENE_INK,\n \"stroke-width\": 1.5\n }) : el(\"rect\", {\n x: at,\n y: e.swatch.kind === \"gap\" ? 7 : 5,\n width: 18,\n height: e.swatch.kind === \"gap\" ? GAP_PX : 8,\n rx: 2,\n fill: ramp ? `url(#${rampId})` : e.swatch.fill\n });\n const text = el(\n \"text\",\n {\n x: e.note ? at : at + 23,\n y: 13,\n \"font-style\": e.note ? \"italic\" : void 0,\n fill: e.note ? \"#666\" : void 0\n },\n e.label\n );\n at += (e.note ? 0 : 23) + e.label.length * LABEL_CHAR_PX + 16;\n return [ramp, swatch, text].filter((p) => p !== void 0);\n });\n return {\n width: at,\n tree: el(\n \"g\",\n {\n transform: `translate(${x} ${y})`,\n \"font-family\": \"Helvetica, Arial, sans-serif\",\n \"font-size\": 11\n },\n ...parts\n )\n };\n}\nfunction rowPitch(count, room, minRowPx = 0) {\n const fit = room / Math.max(1, count);\n const rowPx = Math.max(\n minRowPx,\n Math.min(ROW_HEIGHT_PX, fit >= 1 ? Math.floor(fit) : fit)\n );\n return {\n rowPx,\n barPx: rowPx <= 3 ? rowPx : Math.max(3, Math.round(rowPx * 0.6)),\n labelled: rowPx >= LABELLED_ROW_PX,\n readouts: rowPx >= LABELLED_ROW_PX\n };\n}\nfunction coalesceRuns(runs, pxPerBp) {\n const minBp = 1 / pxPerBp;\n const out = [];\n let bucket = [];\n const flush = () => {\n if (bucket.length === 0) {\n return;\n }\n if (bucket.length === 1) {\n out.push(bucket[0]);\n } else {\n let on = 0;\n let off = 0;\n for (const r of bucket) {\n if (r.onReference) {\n on += r.bp;\n } else {\n off += r.bp;\n }\n }\n const onReference = on >= off;\n const lead = bucket.find((r) => r.onReference === onReference);\n out.push({\n start: bucket[0].start,\n bp: on + off,\n onReference,\n referenceStart: onReference ? lead.referenceStart : void 0,\n ...lead.reversed ? { reversed: true } : {}\n });\n }\n bucket = [];\n };\n let held = 0;\n for (const run of runs) {\n if (run.gap || run.bp >= minBp) {\n flush();\n held = 0;\n out.push(run);\n continue;\n }\n bucket.push(run);\n held += run.bp;\n if (held >= minBp) {\n flush();\n held = 0;\n }\n }\n flush();\n return out;\n}\nfunction geneTree(box, y, barPx) {\n return el(\n \"g\",\n { class: \"row-gene\", \"data-testid\": \"graph-walk-gene\" },\n el(\"title\", {}, box.name),\n ...box.exons.map(\n (e) => el(\"rect\", {\n x: e.x,\n y: y - barPx / 2,\n width: e.w,\n height: barPx,\n fill: GENE_INK,\n opacity: 0.35\n })\n ),\n el(\"rect\", {\n x: box.x,\n y: box.y,\n width: box.w,\n height: box.h,\n fill: \"none\",\n stroke: GENE_INK,\n \"stroke-width\": 1.5\n }),\n box.label && el(\n \"text\",\n {\n x: box.label.x,\n y: box.label.y,\n \"font-family\": \"sans-serif\",\n \"font-size\": box.label.size,\n \"font-weight\": 600,\n \"text-anchor\": \"middle\",\n fill: GENE_INK,\n stroke: \"white\",\n \"stroke-width\": 2.5,\n \"paint-order\": \"stroke\"\n },\n box.name\n )\n );\n}\nfunction walkRowsTree(bars, frame, o = {}) {\n const X = (bp) => bp * frame.scaleX + frame.translateX;\n const rowPx = frame.rowPx ?? ROW_HEIGHT_PX;\n const barPx = frame.barPx ?? BAR_PX;\n const overhang = Math.min(3, Math.max(0, (rowPx - barPx) / 2));\n const Y = (row) => row * rowPx * frame.scaleY + frame.translateY;\n const { origin, unit, reference, rows } = bars;\n const along = (offset) => X(origin + offset);\n const prefix = o.idPrefix ?? \"walkrow\";\n const rowTree = (row, i) => {\n const y = Y(i);\n if (y < -barPx || y > frame.height + barPx) {\n return void 0;\n }\n const runs = coalesceRuns(row.runs, frame.scaleX).flatMap((run) => {\n const paint = runPaint(run, o.ramp);\n const h = run.gap ? Math.min(GAP_PX, barPx) : barPx;\n const id = `${prefix}-${i}-${run.start}`;\n const rect = el(\"rect\", {\n x: along(run.start),\n y: y - h / 2,\n width: Math.max(1, run.bp * frame.scaleX),\n height: h,\n fill: \"stops\" in paint ? `url(#${id})` : paint.fill\n });\n return \"stops\" in paint ? [\n el(\n \"linearGradient\",\n { id },\n ...paint.stops.map(\n (color, k) => el(\"stop\", {\n offset: k / (paint.stops.length - 1),\n \"stop-color\": color\n })\n )\n ),\n rect\n ] : [rect];\n });\n const ticks = unit && barPx >= MIN_TILED_BAR_PX ? unitTicks(row.bp, unit, frame.scaleX).map(\n (k) => el(\"line\", {\n x1: along(k),\n x2: along(k),\n y1: y - barPx / 2,\n y2: y + barPx / 2,\n stroke: \"white\",\n \"stroke-width\": 1\n })\n ) : [];\n const { call } = row;\n const text = walkRowReadout(\n row,\n i === 0 ? void 0 : reference,\n unit,\n call\n );\n const at = readoutPlacement(text, along(row.bp), frame.width);\n const readouts = frame.readouts ?? true;\n return el(\n \"g\",\n {\n \"data-testid\": i === 0 ? \"graph-walk-reference\" : \"graph-walk-row\"\n },\n ...runs,\n ...ticks,\n ...rowGeneBoxes(o.rowGenes?.get(row.name) ?? [], along, y, {\n rowPx,\n barPx\n }).map((box) => geneTree(box, y, barPx)),\n call && el(\"rect\", {\n \"data-testid\": \"graph-walk-call\",\n x: along(call.bp) - 1,\n y: y - barPx / 2 - overhang,\n width: 2,\n height: barPx + 2 * overhang,\n fill: callTickInk(call)\n }),\n readouts && el(\n \"text\",\n {\n x: at.x,\n y: y + 4,\n \"font-family\": \"sans-serif\",\n \"font-size\": 11,\n fill: call?.agrees === false ? DISAGREES : \"#333\",\n stroke: at.halo ? \"white\" : void 0,\n \"stroke-width\": at.halo ? 3 : void 0,\n \"paint-order\": \"stroke\",\n \"text-anchor\": at.anchor\n },\n text\n )\n );\n };\n return el(\"g\", {}, ...[reference, ...rows].map(rowTree));\n}\n\nexport {\n ON_REFERENCE,\n OFF_REFERENCE,\n OUTSIDE_CUT,\n GENE_INK,\n BAR_PX,\n GAP_PX,\n LABELLED_ROW_PX,\n kb,\n walkRowReadout,\n readoutPlacement,\n unitTicks,\n runPaint,\n alongRow,\n rowSpan,\n genesOnRow,\n placeRowGenes,\n boxesGenes,\n rowGeneBoxes,\n walkRowsKey,\n CALL_TICK,\n UNBACKED_TICK,\n DISAGREES,\n callTickInk,\n walkRowsKeyTree,\n rowPitch,\n coalesceRuns,\n walkRowsTree\n};\n", "import {\n SATURATED_PATH_COUNT\n} from \"./chunk-FX4RDMDN.js\";\nimport {\n formatBp\n} from \"./chunk-PTABFYQ7.js\";\n\n// src/bubbles/classifyBubble.ts\nvar REPEAT_GROWTH = 10;\nfunction coveringRepeat(b, repeats) {\n const span = b.end - b.start;\n const growth = b.longestAlleleLength - b.shortestAlleleLength;\n return repeats.find(\n (r) => growth <= REPEAT_GROWTH * (r.end - r.start) && (span === 0 ? r.start <= b.start && b.start <= r.end : Math.min(b.end, r.end) - Math.max(b.start, r.start) >= span / 2)\n );\n}\nvar SUPERBUBBLE_SEGMENTS = 40;\nfunction formatBpRange(shortest, longest) {\n const low = formatBp(shortest);\n const high = formatBp(longest);\n const unit = high.slice(high.indexOf(\" \"));\n return low.endsWith(unit) ? `${low.slice(0, -unit.length)}\\u2013${high}` : `${low}\\u2013${high}`;\n}\nfunction routes(count) {\n if (count >= SATURATED_PATH_COUNT) {\n return \"\\u22652.1B routes\";\n }\n if (count >= 1e5) {\n return `${(count / 1e3).toFixed(0)}k routes`;\n }\n return `${count} routes`;\n}\nfunction classifyBubble(b, repeats = []) {\n const c = classifyShape(b, repeats);\n return b.partial ? { ...c, label: `${c.label}, partial` } : c;\n}\nfunction classifyShape(b, repeats) {\n const refSpan = b.end - b.start;\n const {\n shortestAlleleLength: shortest,\n longestAlleleLength: longest,\n pathCount,\n segmentCount,\n inversion\n } = b;\n const range = formatBpRange(shortest, longest);\n if (segmentCount >= SUPERBUBBLE_SEGMENTS) {\n return {\n kind: \"superbubble\",\n label: `${range} superbubble, ${segmentCount} segments, ${routes(pathCount)}${inversion ? \", inv\" : \"\"}`\n };\n }\n if (inversion) {\n return { kind: \"inversion\", label: `${formatBp(longest)} inv` };\n }\n if (b.offReference) {\n return shortest === longest ? sameLength(shortest) : { kind: \"complex\", label: `${range}, ${routes(pathCount)}` };\n }\n const repeat = longest !== shortest ? coveringRepeat(b, repeats) : void 0;\n if (repeat) {\n const name = repeat.name ? ` (${repeat.name})` : \"\";\n return {\n kind: \"repeat\",\n label: `${range} repeat array${name}, ${routes(pathCount)}`\n };\n }\n const alleles = pathCount > 2 ? `, ${pathCount} alleles` : \"\";\n if (shortest === longest && shortest === refSpan) {\n return sameLength(refSpan);\n }\n if (refSpan === 0 || shortest === refSpan) {\n return {\n kind: \"insertion\",\n label: `\\u2264${formatBp(longest - refSpan)} ins${alleles}`\n };\n }\n if (longest === refSpan) {\n return {\n kind: \"deletion\",\n label: `${formatBp(refSpan - shortest)} del${alleles}`\n };\n }\n return {\n kind: \"complex\",\n label: `${formatBp(refSpan)} ref \\u2192 ${range}, ${pathCount} alleles`\n };\n}\nfunction sameLength(bp) {\n return bp <= 1 ? { kind: \"snp\", label: \"SNP\" } : { kind: \"substitution\", label: `${formatBp(bp)} sub` };\n}\nvar BUBBLE_KIND_COLORS = {\n snp: \"#5b6b7a\",\n substitution: \"#5b6b7a\",\n insertion: \"#2f8fd6\",\n deletion: \"#c94040\",\n inversion: \"#e07b00\",\n repeat: \"#8e3fbf\",\n superbubble: \"#8e3fbf\",\n complex: \"#8e3fbf\"\n};\nvar BUBBLE_KIND_NAMES = {\n snp: \"SNP\",\n substitution: \"substitution\",\n insertion: \"insertion\",\n deletion: \"deletion\",\n inversion: \"inversion\",\n repeat: \"repeat array\",\n superbubble: \"superbubble\",\n complex: \"site\"\n};\nfunction bubbleSegmentIds(b) {\n return b.segments.split(\",\").filter(Boolean);\n}\n\nexport {\n classifyBubble,\n BUBBLE_KIND_COLORS,\n BUBBLE_KIND_NAMES,\n bubbleSegmentIds\n};\n", "// src/tubeMap/connectors.ts\nfunction tubeMapConnectors(boxes, bpToScreen, tubeToScreen, width) {\n const out = [];\n for (const box of boxes) {\n const bottom0 = tubeToScreen(box.x0);\n const bottom1 = tubeToScreen(box.x1);\n if (bottom1 >= 0 && bottom0 <= width) {\n out.push({\n node: box.name,\n top0: bpToScreen(box.bp0),\n top1: bpToScreen(box.bp1),\n bottom0,\n bottom1\n });\n }\n }\n return out;\n}\nvar HIT_SLOP_PX = 3;\nfunction connectorAt(connectors, zoneBottom, sx, sy) {\n if (zoneBottom <= 0 || sy < 0 || sy > zoneBottom) {\n return void 0;\n }\n const t = sy / zoneBottom;\n let hit;\n let best = HIT_SLOP_PX;\n for (const c of connectors) {\n const a = c.top0 + (c.bottom0 - c.top0) * t;\n const b = c.top1 + (c.bottom1 - c.top1) * t;\n const dist = Math.max(0, Math.min(a, b) - sx, sx - Math.max(a, b));\n if (dist < best) {\n best = dist;\n hit = c.node;\n }\n }\n return hit;\n}\nfunction band(ctx, c, bottom) {\n ctx.moveTo(c.top0, 0);\n ctx.lineTo(c.top1, 0);\n ctx.lineTo(c.bottom1, bottom);\n ctx.lineTo(c.bottom0, bottom);\n ctx.closePath();\n}\nfunction sides(ctx, c, bottom) {\n ctx.moveTo(c.top0, 0);\n ctx.lineTo(c.bottom0, bottom);\n ctx.moveTo(c.top1, 0);\n ctx.lineTo(c.bottom1, bottom);\n}\nfunction drawTubeMapConnectors(ctx, connectors, bottom, {\n highlightNode,\n darkMode\n}) {\n if (bottom <= 0 || connectors.length === 0) {\n return;\n }\n const ink = darkMode ? \"255,255,255\" : \"0,0,0\";\n ctx.beginPath();\n for (const c of connectors) {\n band(ctx, c, bottom);\n }\n ctx.fillStyle = `rgba(${ink},0.07)`;\n ctx.fill();\n ctx.beginPath();\n for (const c of connectors) {\n sides(ctx, c, bottom);\n }\n ctx.strokeStyle = `rgba(${ink},0.35)`;\n ctx.lineWidth = 0.5;\n ctx.stroke();\n drawLitConnector(ctx, connectors, bottom, highlightNode);\n}\nfunction drawLitConnector(ctx, connectors, bottom, node) {\n const lit = bottom > 0 && node ? connectors.find((c) => c.node === node) : void 0;\n if (lit) {\n ctx.beginPath();\n band(ctx, lit, bottom);\n ctx.fillStyle = \"rgba(255,192,203,0.5)\";\n ctx.fill();\n ctx.beginPath();\n sides(ctx, lit, bottom);\n ctx.strokeStyle = \"#ff0000\";\n ctx.lineWidth = 1;\n ctx.stroke();\n }\n}\n\nexport {\n tubeMapConnectors,\n connectorAt,\n drawTubeMapConnectors,\n drawLitConnector\n};\n", "import {\n referenceBoxes\n} from \"../chunks/chunk-XMW266WS.js\";\nimport \"../chunks/chunk-PTABFYQ7.js\";\nimport \"../chunks/chunk-AB35TJST.js\";\nimport \"../chunks/chunk-N73TI3VG.js\";\nimport \"../chunks/chunk-24WITXQY.js\";\nimport \"../chunks/chunk-7SRWJLSC.js\";\nimport \"../chunks/chunk-CPMHA4W5.js\";\nimport \"../chunks/chunk-FYQWPEEY.js\";\n\n// src/tubeMap/deviations.ts\nfunction boxAt(boxes, bp, visited) {\n let lo = 0;\n let hi = boxes.length - 1;\n while (lo < hi) {\n const mid = lo + hi + 1 >> 1;\n if (boxes[mid].bp0 <= bp) {\n lo = mid;\n } else {\n hi = mid - 1;\n }\n }\n return [boxes[lo], boxes[lo - 1]].find(\n (box) => box && visited.has(box.index) && box.bp0 <= bp && bp <= box.bp1\n );\n}\nfunction deviationMarks(drawing, deviations) {\n const { layout } = drawing;\n const boxes = [...referenceBoxes(drawing).values()].flat().sort((a, b) => a.bp0 - b.bp0);\n const marks = [];\n for (const track of layout.tracks) {\n const devs = track.name ? deviations.get(track.name) : void 0;\n if (devs?.length) {\n const visited = /* @__PURE__ */ new Map();\n for (const segment of track.path) {\n if (segment.node !== null && segment.y !== void 0 && !visited.has(segment.node)) {\n visited.set(segment.node, segment.y);\n }\n }\n for (const d of devs) {\n const box = boxAt(boxes, d.start, visited);\n if (box) {\n const { bp0, bp1, x0, x1, index } = box;\n const at = (bp) => x0 + (Math.min(bp, bp1) - bp0) / (bp1 - bp0) * (x1 - x0);\n marks.push({\n x0: at(d.start),\n x1: at(d.end),\n y: visited.get(index),\n height: track.width\n });\n }\n }\n }\n }\n return marks;\n}\nfunction deviationInk(darkMode) {\n return darkMode ? \"rgba(255,255,255,0.9)\" : \"rgba(0,0,0,0.8)\";\n}\nfunction drawDeviationMarks(ctx, marks, { x, y, width, darkMode }) {\n if (marks.length === 0) {\n return;\n }\n ctx.fillStyle = deviationInk(darkMode);\n ctx.beginPath();\n for (const m of marks) {\n const left = x(m.x0);\n const right = Math.max(x(m.x1), left + 1);\n if (right >= 0 && left <= width) {\n const top = y(m.y);\n ctx.rect(left, top, right - left, y(m.y + m.height) - top);\n }\n }\n ctx.fill();\n}\nexport {\n deviationInk,\n deviationMarks,\n drawDeviationMarks\n};\n", "export type MismatchType = 'insertion' | 'deletion' | 'substitution'\n\nexport interface Mismatch {\n type: MismatchType\n pos: number\n seq?: string\n length?: number\n}\n\nexport interface ReadSequenceEntry {\n nodeName: string\n mismatches: Mismatch[]\n}\n\nexport type TrackType = 'haplotype' | 'read'\n\nexport interface TrackRectangle {\n xStart: number\n yStart: number\n xEnd: number\n yEnd: number\n id: number\n name?: string | undefined\n type?: TrackType | undefined\n}\n\nexport interface TrackCurve {\n xStart: number\n yStart: number\n xEnd: number\n yEnd: number\n width: number\n id: number\n name?: string | undefined\n type?: TrackType | undefined\n // the nodes the curve leaves and enters, null at a gap in a track's path\n nodeStart: number | null\n nodeEnd: number | null\n // the order slots it leaves and enters\n orderStart: number\n orderEnd: number\n // a curve of track 0, the reference, which a steep gap gives its width first\n reference?: boolean\n path?: string\n}\n\nexport interface TrackCorner {\n path: string\n id: number\n name?: string | undefined\n type?: TrackType | undefined\n}\n\nexport interface Segment {\n order: number\n lane?: number\n isForward: boolean\n node: number | null\n y?: number\n betweenCycleReverseTraversal?: boolean\n}\n\n// Loose input shape: just the basics produced by vgExtractTracks /\n// vgExtractReads. Layout passes accrete indexSequence / path / width.\nexport interface InputTrack {\n id: number\n name?: string\n sequence: string[]\n type?: TrackType\n freq?: number\n hidden?: boolean\n sourceTrackID: number\n indexOfFirstBase?: number\n isCompletelyReverse?: boolean\n // Read-specific fields populated by vgExtractReads.\n sequenceNew?: ReadSequenceEntry[]\n firstNodeOffset?: number\n finalNodeCoverLength?: number\n mapping_quality?: number\n is_secondary?: boolean\n is_reverse?: boolean\n sample_name?: string | null\n read_group?: string | null\n cigar_string?: string\n score?: number\n}\n\n// How many of the banded haplotypes take a coarsened band\nexport interface HaplotypeShare {\n count: number\n total: number\n}\n\n// Layout-complete track shape, as layoutTubeMap returns it.\nexport interface Track extends InputTrack {\n indexSequence: number[]\n path: Segment[]\n width: number\n haplotypeShare?: HaplotypeShare | undefined\n}\n\n// Loose input shape passed to layoutTubeMap. Its passes (generateNodeWidth \u2192\n// generateNodeOrder \u2192 generateLaneAssignment \u2192 generateNodeXCoords) accrete\n// more fields, producing the full `Node` below. A graph fetched with\n// removeSequences has no seq, and sequenceLength defaults to seq's length.\nexport interface InputNode {\n name: string\n seq?: string\n sequenceLength?: number\n}\n\n// Layout-complete node \u2014 fields used by drawing code after the pipeline.\n// (Marked optional only for the genuinely conditional fields like switched/d.)\n// layoutTubeMap fills in seq, as '' when the input had none, and\n// sequenceLength.\nexport interface Node extends InputNode {\n seq: string\n sequenceLength: number\n width: number\n pixelWidth: number\n order?: number | undefined\n y: number\n contentHeight: number\n x: number\n topLane: number\n successors: number[]\n predecessors: number[]\n tracks: number[]\n degree: number\n switched?: boolean\n incomingReads: [number, number][]\n outgoingReads: [number, number][]\n internalReads: number[]\n d?: string\n}\n\n// Node after generateNodeOrder() has run \u2014 order is guaranteed to be set.\nexport interface LayoutNode extends Node {\n order: number\n}\n\nexport interface SegmentAssignment {\n trackID: number\n segmentID: number\n compareToFromSame: SegmentAssignment | null\n idealLane?: number | undefined\n idealY?: number | null | undefined\n lane?: number\n}\n\nexport interface NodeAssignment {\n type: 'single' | 'multiple'\n node: number | null\n tracks: SegmentAssignment[]\n idealLane?: number | undefined\n}\n\n// Drawing instructions from one layout, in layout coordinates.\nexport interface TrackShapes {\n rectangles: TrackRectangle[]\n curves: TrackCurve[]\n corners: TrackCorner[]\n // drawn separately so they don't overlap the horizontal rectangles\n verticalRectangles: TrackRectangle[]\n}\n\nexport function emptyTrackShapes(): TrackShapes {\n return {\n rectangles: [],\n curves: [],\n corners: [],\n verticalRectangles: [],\n }\n}\n\n// The extent of the drawn content, in layout coordinates.\nexport interface ImageBounds {\n minX: number\n maxX: number\n minY: number\n maxY: number\n}\n", "// A PanSN path name: sample#haplotype#contig, sometimes with further\n// #-separated fields such as a fragment offset after the contig.\n// https://github.com/pangenome/PanSN-spec\nexport interface PanSNName {\n sample: string\n haplotype: number\n contig: string\n}\n\n// gbz-base names a generic reference `_gbwt_ref#0#contig` and a haplotype the\n// GBWT kept no metadata for `unknown#N#contig`; neither names a sample.\nconst NOT_SAMPLES = new Set(['_gbwt_ref', 'unknown'])\n\n// The sample, haplotype and contig of a PanSN name, or undefined for any other\n// name: fewer than three fields, an empty sample or contig, a haplotype that\n// isn't a whole number, or a placeholder sample.\nexport function parsePanSN(name: string | undefined): PanSNName | undefined {\n const [sample, haplotype, contig] = name?.split('#') ?? []\n if (\n sample === undefined ||\n sample === '' ||\n NOT_SAMPLES.has(sample) ||\n haplotype === undefined ||\n !/^\\d+$/.test(haplotype) ||\n contig === undefined ||\n contig === ''\n ) {\n return undefined\n }\n return { sample, haplotype: Number(haplotype), contig }\n}\n", "// The tube map layout, from input nodes and tracks to drawable shapes. Ported\n// from the original sequenceTubeMap JS, where it shared one module with the d3\n// drawing. It runs in two phases, each on a fresh LayoutState: layoutTopology\n// merges, orders, orients and sizes the nodes and fixes their x, and\n// placeTubeMap stacks a chosen set of tracks and reads on that topology.\nimport { parsePanSN } from './panSN.ts'\nimport { emptyTrackShapes } from './types.ts'\n\nimport type {\n HaplotypeShare,\n ImageBounds,\n InputNode,\n InputTrack,\n LayoutNode,\n Mismatch,\n Node,\n NodeAssignment,\n ReadSequenceEntry,\n Segment,\n SegmentAssignment,\n Track,\n TrackShapes,\n TrackType,\n} from './types.ts'\n\nconst DEBUG = false as boolean\n\nfunction debugLog(...args: unknown[]): void {\n if (DEBUG) {\n // eslint-disable-next-line no-console\n console.log(...args)\n }\n}\n\n// Node and Track declare some fields that not every entry gets: layout places\n// only the nodes a track or read reaches, and a normal read has no width until\n// assignReadsToNodes.\ntype MaybeUnset<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>\ntype MaybeUnplacedNode = MaybeUnset<LayoutNode, 'x' | 'y'>\n\nexport type NodeWidthOption = 'normal' | 'compressed' | 'small' | 'fixed'\n\n// The fields of a placed track a renderer colors it by. Shapes carry only the\n// track's id, so a renderer can recolor without laying out again.\nexport interface ColorableTrack {\n id: number\n sourceTrackID: number\n type?: TrackType\n name?: string\n mapping_quality?: number\n is_reverse?: boolean\n haplotypeShare?: HaplotypeShare\n}\n\nexport type LayerData = 'haplotypes' | 'reads'\n\n// A track set placement draws, and the stat it runs first. `coarsen` turns\n// the set into one band per edge; banded haplotypes keep the reference's lane.\nexport interface Layer {\n data: LayerData\n stat?: 'coarsen'\n}\n\n// The options a topology fixes. trackWidth, the layers and ignoreStrand leave\n// node order alone, but the topology measures x from placing every track and\n// read under them.\nexport interface TopologyOptions {\n mergeNodes?: boolean\n showReads?: boolean\n // Shorthand for `layers` when those are unset: band the reads, or the\n // haplotypes when no reads were loaded\n coarsenedReadView?: boolean\n // The haplotypes draw first and the reads stack under them, each data under\n // the stat of its first layer here\n layers?: readonly Layer[]\n ignoreStrand?: boolean\n // normal: width is sequence length, at `charWidth` per base\n // compressed: log2 of sequence length\n // small: 1% of sequence length\n // fixed: every node one width\n nodeWidthOption?: NodeWidthOption\n charWidth?: number\n // a haplotype tube's width in layout px, where no `freq` scales it\n trackWidth?: number\n // how `freq` widens a tube: log grows slowly, as sequenceTubeMap draws vg's\n // frequencies; linear makes a walk standing for n haplotypes n tubes wide,\n // so widths compare as counts\n freqWidth?: 'log' | 'linear'\n}\n\nexport const READ_FACET_FIELDS = ['read_group', 'sample_name'] as const\nexport type ReadFacetBy = (typeof READ_FACET_FIELDS)[number]\n// A read field, or the sample in the haplotypes' PanSN names\nexport const FACET_FIELDS = [...READ_FACET_FIELDS, 'haplotype_sample'] as const\nexport type FacetBy = (typeof FACET_FIELDS)[number]\n\n// One panel's subset. A read facet keeps every haplotype and the reads whose\n// `by` field is `key`, or that lack one when `key` is null. A haplotype facet\n// keeps the reference and no reads, plus the haplotypes of sample `key`, or\n// those with no PanSN sample when `key` is null; its `reads` panel keeps the\n// reference and the reads.\nexport interface ReadFacet {\n by: ReadFacetBy\n key: string | null\n}\nexport type HaplotypeFacet =\n | { by: 'haplotype_sample'; key: string | null }\n | { by: 'haplotype_sample'; reads: true }\nexport type Facet = ReadFacet | HaplotypeFacet\n\n// Which of a topology's tracks and reads a placement draws\nexport interface PlacementOptions {\n mappingQualityCutoff?: number\n focusReadNames?: string[] | null\n facet?: Facet | undefined\n}\n\nexport interface FacetOptions extends PlacementOptions {\n // One panel per value of this field\n facetBy?: FacetBy | null\n}\n\nexport interface LayoutOptions extends TopologyOptions, PlacementOptions {}\n\nexport type CoarsenedUnit = 'read' | 'haplotype'\n\n// A coarsened band's count of contributing reads or haplotypes and its label,\n// keyed by the band's synthetic track id, unique across layers\nexport interface CoarsenedEdgeMeta {\n count: number\n label: string\n}\n\n// What a layer's coarsening drew as bands, how many reads or haplotypes it\n// banded (counting a deduplicated walk `freq` times), and whether any band\n// runs reverse-strand\nexport interface Coarsening {\n unit: CoarsenedUnit\n total: number\n reverse: boolean\n}\n\n// Each layer that drew bands, by its data\nexport type Coarsenings = Partial<Record<LayerData, Coarsening>>\n\nexport interface TubeMapLayout {\n // 1-indexed with a hole at 0: a signed index\n // is an oriented visit, and 0 has no sign\n nodes: LayoutNode[]\n // the haplotype tracks and placed reads together, sorted by where each\n // first meets the others, which is the order their shapes were made in\n tracks: Track[]\n // the placed reads alone\n reads: Track[]\n nodeMap: ReadonlyMap<string, number>\n shapes: TrackShapes\n bounds: ImageBounds\n maxOrder: number\n // the name of the track that carries a coordinate for the ruler\n trackForRuler: string | undefined\n coarsenedEdgeMeta: Map<number, CoarsenedEdgeMeta>\n coarsened: Coarsenings\n}\n\n// A node before placement gives it a y and the reads through it\nexport type TopologyNode = Omit<\n LayoutNode,\n | 'y'\n | 'contentHeight'\n | 'topLane'\n | 'incomingReads'\n | 'outgoingReads'\n | 'internalReads'\n>\n\n// A haplotype or read before placement gives it a width and lanes\nexport type TopologyTrack = Omit<Track, 'path' | 'width'>\n\n// What every placement of one input shares: the merged, ordered and oriented\n// nodes with their widths and x positions, and the oriented haplotypes and\n// reads. A placement reads it and never changes it.\nexport interface TubeMapTopology {\n options: Required<TopologyOptions>\n // 1-indexed with a hole at 0, like TubeMapLayout.nodes. A node no track or\n // read reaches has order UNREACHABLE_ORDER and no x.\n nodes: readonly TopologyNode[]\n // the visible haplotypes, track 0 read left to right\n tracks: readonly TopologyTrack[]\n // every primary alignment that shares a node with a track, unfiltered\n reads: readonly TopologyTrack[]\n nodeMap: ReadonlyMap<string, number>\n maxOrder: number\n trackForRuler: string | undefined\n}\n\ntype LayoutConfig = Required<TopologyOptions>\n\n// The coarsened view bands haplotypes only when no reads were loaded, not when\n// a filter hides them all\nfunction layersFrom(\n { layers, coarsenedReadView = false, showReads = true }: TopologyOptions,\n hasReads: boolean,\n): readonly Layer[] {\n if (layers !== undefined) {\n return layers\n }\n const coarsen = coarsenedReadView && showReads\n const stat = (banded: boolean): Pick<Layer, 'stat'> =>\n banded ? { stat: 'coarsen' } : {}\n return [\n { data: 'haplotypes', ...stat(coarsen && !hasReads) },\n { data: 'reads', ...stat(coarsen && hasReads) },\n ]\n}\n\nfunction statOf(layers: readonly Layer[], data: LayerData) {\n return layers.find(layer => layer.data === data)?.stat\n}\n\nfunction configFrom(options: TopologyOptions, hasReads: boolean): LayoutConfig {\n return {\n mergeNodes: options.mergeNodes ?? true,\n showReads: options.showReads ?? true,\n coarsenedReadView: options.coarsenedReadView ?? false,\n layers: layersFrom(options, hasReads),\n ignoreStrand: options.ignoreStrand ?? false,\n nodeWidthOption: options.nodeWidthOption ?? 'normal',\n charWidth: options.charWidth ?? 8.401,\n trackWidth: options.trackWidth ?? 15,\n freqWidth: options.freqWidth ?? 'log',\n }\n}\n\n// The working state of one topology or placement, shared by its passes.\ninterface LayoutState {\n config: LayoutConfig\n // Sparse like TubeMapLayout.nodes, but forEach, map and sort skip the hole\n // and noUncheckedIndexedAccess already types indexed reads as possibly\n // undefined, so only for...of would ever see it.\n nodes: LayoutNode[]\n // Each track's `path` lists the Segments to draw, in order along the path.\n tracks: Track[]\n // Reads have a `path` too, but stack vertically by a different system.\n reads: Track[]\n nodeMap: ReadonlyMap<string, number>\n nodesPerOrder: number[][]\n // generateNodeOrder's scratch, by node index; undefined until assigned.\n nodeOrders: (number | undefined)[]\n // Lane assignments for tracks (not reads), one list per order slot.\n assignments: NodeAssignment[][]\n extraLeft: number[]\n extraRight: number[]\n // horizontal order of the rightmost node\n maxOrder: number\n shapes: TrackShapes\n imageBounds: ImageBounds\n trackForRuler: string | undefined\n coarsenedEdgeMeta: Map<number, CoarsenedEdgeMeta>\n}\n\nfunction emptyState(config: LayoutConfig): LayoutState {\n return {\n config,\n nodes: [],\n tracks: [],\n reads: [],\n nodeMap: new Map(),\n nodesPerOrder: [],\n nodeOrders: [],\n assignments: [],\n extraLeft: [],\n extraRight: [],\n maxOrder: -1,\n shapes: emptyTrackShapes(),\n imageBounds: { minX: 0, maxX: 0, minY: 0, maxY: 0 },\n trackForRuler: undefined,\n coarsenedEdgeMeta: new Map(),\n }\n}\n\n// placeTubeMap(layoutTopology(...), options). Undefined when nothing visible\n// is left to draw.\nexport function layoutTubeMap(\n inputNodes: readonly InputNode[],\n inputTracks: readonly InputTrack[],\n inputReads: readonly InputTrack[] = [],\n options: LayoutOptions = {},\n): TubeMapLayout | undefined {\n const topology = layoutTopology(inputNodes, inputTracks, inputReads, options)\n return topology && placeTubeMap(topology, options)\n}\n\n// Each topology's placement of every track and read, which fixed its x\nconst measurements = new WeakMap<TubeMapTopology, TubeMapLayout>()\n\n// Merge, order and orient the nodes under the visible `inputTracks` and, when\n// `showReads`, every primary alignment in `inputReads`, then size them and\n// fix their x positions. Undefined when nothing visible is left to draw.\n// Neither input is modified. Track 0 is the reference the layout straightens.\n// The x gaps between order slots make room for the tracks' turns and slopes,\n// so the topology takes its x positions from placing every track and read.\nexport function layoutTopology(\n inputNodes: readonly InputNode[],\n inputTracks: readonly InputTrack[],\n inputReads: readonly InputTrack[] = [],\n options: TopologyOptions = {},\n): TubeMapTopology | undefined {\n const topology = arrangeTopology(inputNodes, inputTracks, inputReads, options)\n if (topology === undefined) {\n return undefined\n }\n const everything = place(topology, topology.tracks, topology.reads, 'measure')\n everything.nodes.forEach((node, i) => {\n if (node.order >= 0) {\n topology.nodes[i]!.x = node.x\n }\n })\n measurements.set(topology, everything)\n return topology\n}\n\n// Lay out the haplotypes and reads `options` keep at the topology's x\n// positions, stacking each read under the nodes it visits. When they keep\n// everything, this returns the placement layoutTopology measured x from, the\n// same object on every such call.\nexport function placeTubeMap(\n topology: TubeMapTopology,\n options: PlacementOptions = {},\n): TubeMapLayout {\n return placeSubset(\n topology,\n selectTracks(topology, options.facet),\n selectReads(topology, options),\n )\n}\n\nfunction placeSubset(\n topology: TubeMapTopology,\n tracks: readonly TopologyTrack[],\n reads: readonly TopologyTrack[],\n bandIdBase?: BandIdBase,\n): TubeMapLayout {\n const measured = measurements.get(topology)\n return measured !== undefined &&\n tracks.length === topology.tracks.length &&\n reads.length === topology.reads.length\n ? measured\n : place(topology, tracks, reads, 'topology', bandIdBase)\n}\n\nfunction arrangeTopology(\n inputNodes: readonly InputNode[],\n inputTracks: readonly InputTrack[],\n inputReads: readonly InputTrack[],\n options: TopologyOptions,\n): TubeMapTopology | undefined {\n const state = emptyState(configFrom(options, inputReads.length > 0))\n\n if (inputNodes.length === 0 || inputTracks.length === 0) {\n return undefined\n }\n\n // Boundary promotion: layout passes below populate the Node/Track fields\n // (width, order, x/y, path, indexSequence, etc.) before any reader runs.\n //\n // Nodes are referenced in inputs by internal `name` attribute and not by\n // index. Internally in e.g. a path's indexSequence we need to reference\n // nodes by *signed* index, so index 0 can never be used: budge everything\n // down and leave a hole (rather than an `undefined` entry) at 0, which we\n // won't iterate over. Made after the copy, because not every structuredClone\n // keeps a hole.\n structuredClone(inputNodes).forEach((node, i) => {\n node.seq ??= ''\n node.sequenceLength ??= node.seq.length\n state.nodes[i + 1] = node as LayoutNode\n })\n state.tracks = structuredClone(inputTracks) as Track[]\n // Secondary alignments never draw, so drop them before the deep copy, the\n // most expensive step in a redraw.\n state.reads = state.config.showReads\n ? (structuredClone(\n inputReads.filter(read => read.is_secondary !== true),\n ) as Track[])\n : []\n\n for (let i = state.tracks.length - 1; i >= 0; i -= 1) {\n const t = state.tracks[i]!\n t.type ??= 'haplotype'\n if (t.hidden === true) {\n state.tracks.splice(i, 1)\n continue\n }\n if (t.indexOfFirstBase !== undefined) {\n state.trackForRuler = t.name\n }\n }\n if (state.tracks.length === 0) {\n return undefined\n }\n\n // Run against the visible tracks only, so hiding the reference doesn't leave\n // the layout straightened around a track that is no longer drawn.\n straightenTrack(state, 0)\n\n state.nodeMap = generateNodeMap(state)\n generateTrackIndexSequences(state, state.tracks)\n generateTrackIndexSequences(state, state.reads)\n generateNodeWidth(state)\n\n if (state.config.mergeNodes) {\n generateNodeSuccessors(state)\n generateNodeOrder(state)\n reverseReversedReads(state)\n mergeNodes(state)\n state.nodeMap = generateNodeMap(state)\n generateNodeWidth(state)\n generateTrackIndexSequences(state, state.tracks)\n generateTrackIndexSequences(state, state.reads)\n }\n\n generateNodeSuccessors(state)\n generateNodeDegree(state)\n generateNodeOrder(state)\n\n // can cause problems when there is a reversed single track node\n // OTOH, can solve problems with complex inversion patterns\n switchNodeOrientation(state)\n generateNodeOrder(state)\n reverseReversedReads(state)\n generateTrackIndexSequences(state, state.reads)\n\n return {\n options: state.config,\n nodes: state.nodes,\n tracks: state.tracks,\n reads: state.reads,\n nodeMap: state.nodeMap,\n maxOrder: getMaxOrder(state),\n trackForRuler: state.trackForRuler,\n }\n}\n\nfunction selectReads(\n topology: TubeMapTopology,\n { mappingQualityCutoff = 0, focusReadNames = null, facet }: PlacementOptions,\n): readonly TopologyTrack[] {\n const focus = focusReadNames ? new Set(focusReadNames) : null\n return topology.reads.filter(\n read =>\n (read.mapping_quality ?? 0) >= mappingQualityCutoff &&\n (focus === null || (read.name !== undefined && focus.has(read.name))) &&\n (facet === undefined || facetHoldsRead(facet, read)),\n )\n}\n\n// Whether a panel of `facet` draws this read when the read filters keep it\nexport function facetHoldsRead(\n facet: Facet,\n read: Pick<TopologyTrack, ReadFacetBy>,\n): boolean {\n return facet.by === 'haplotype_sample'\n ? 'reads' in facet\n : (read[facet.by] ?? null) === facet.key\n}\n\n// What every haplotype panel keeps: track 0, which the topology straightened,\n// and the track carrying the ruler's coordinates, when that is another\nfunction references(topology: TubeMapTopology): Set<TopologyTrack> {\n return new Set(\n topology.tracks.filter(\n (track, i) => i === 0 || track.name === topology.trackForRuler,\n ),\n )\n}\n\nfunction selectTracks(\n topology: TubeMapTopology,\n facet: Facet | undefined,\n): readonly TopologyTrack[] {\n if (facet?.by !== 'haplotype_sample') {\n return topology.tracks\n }\n const kept = references(topology)\n return topology.tracks.filter(\n track =>\n kept.has(track) || (!('reads' in facet) && sampleOf(track) === facet.key),\n )\n}\n\nfunction sampleOf(track: TopologyTrack): string | null {\n return parsePanSN(track.name)?.sample ?? null\n}\n\n// The haplotypes among `tracks` beside the reference, a PanSN haplotype\n// counted once however many walks it makes through the window\nfunction haplotypeCount(\n topology: TubeMapTopology,\n tracks: readonly TopologyTrack[],\n): number {\n const skip = references(topology)\n return new Set(\n tracks.flatMap(track => {\n if (skip.has(track)) {\n return []\n }\n const name = parsePanSN(track.name)\n return [name ? `${name.sample}#${name.haplotype}` : track]\n }),\n ).size\n}\n\n// A facet and the haplotypes and reads it draws\nexport interface FacetSubset<F extends Facet = Facet> {\n facet: F\n tracks: readonly TopologyTrack[]\n reads: readonly TopologyTrack[]\n}\n\n// Group `items` by key: in sort order, the null key last\nfunction groupBy<T>(\n items: readonly T[],\n keyOf: (item: T) => string | null,\n): [string | null, T[]][] {\n const groups = new Map<string | null, T[]>()\n for (const item of items) {\n const key = keyOf(item)\n const group = groups.get(key)\n if (group === undefined) {\n groups.set(key, [item])\n } else {\n group.push(item)\n }\n }\n return [...groups].sort(([a], [b]) =>\n a === null || b === null\n ? Number(a === null) - Number(b === null)\n : a.localeCompare(b, undefined, { numeric: true }),\n )\n}\n\n// Split the reads `options` keep by their `by` field: one subset per value,\n// in sort order with the reads lacking one last, and none left empty. Every\n// subset keeps every haplotype.\nexport function facetReads(\n topology: TubeMapTopology,\n by: ReadFacetBy,\n options: PlacementOptions = {},\n): FacetSubset<ReadFacet>[] {\n return groupBy(\n selectReads(topology, { ...options, facet: undefined }),\n read => read[by] ?? null,\n ).map(([key, reads]) => ({\n facet: { by, key },\n tracks: topology.tracks,\n reads,\n }))\n}\n\n// Split the haplotypes beside the reference by the sample in their PanSN\n// names: one subset per sample, in sort order, then one for the haplotypes\n// with no PanSN name, each holding the reference too and no reads. The reads\n// `options` keep, when any, go in a last subset with the reference alone. No\n// haplotype beside the reference leaves nothing to split.\nexport function facetHaplotypes(\n topology: TubeMapTopology,\n options: PlacementOptions = {},\n): FacetSubset<HaplotypeFacet>[] {\n const kept = references(topology)\n const samples = groupBy(\n topology.tracks.filter(track => !kept.has(track)),\n sampleOf,\n )\n if (samples.length === 0) {\n return []\n }\n const ofSample = samples.map(([key]) => {\n const facet: HaplotypeFacet = { by: 'haplotype_sample', key }\n return { facet, tracks: selectTracks(topology, facet), reads: [] }\n })\n const facet: HaplotypeFacet = { by: 'haplotype_sample', reads: true }\n const reads = selectReads(topology, { ...options, facet })\n return reads.length === 0\n ? ofSample\n : [...ofSample, { facet, tracks: selectTracks(topology, facet), reads }]\n}\n\n// One placement in a stack of them. Its layout keeps its own coordinates;\n// `offsetY` moves it into the stack.\nexport interface FacetPanel {\n // undefined for the one panel of an unfaceted view\n facet?: Facet\n readCount: number\n // beside the reference, a PanSN haplotype counted once\n haplotypeCount: number\n layout: TubeMapLayout\n offsetY: number\n}\n\nexport interface FacetedLayout {\n panels: FacetPanel[]\n // every panel and its label, in stack coordinates\n bounds: ImageBounds\n}\n\n// Room above each faceted panel for its label, and between one panel and the\n// next label\nexport const FACET_LABEL_HEIGHT = 30\nexport const FACET_GAP = 40\n\n// Place the topology once per facet and stack the placements top to bottom,\n// the first where an unfaceted placement would draw. Every panel takes the\n// topology's x, so the panels line up in x. Band ids run on from one panel to\n// the next where panels band different tracks: the reads under a read facet,\n// the haplotypes under a haplotype facet, whose bands then take their share\n// of the panel's haplotypes. Without `facetBy`, or with nothing to split, this\n// is one panel of placeTubeMap's layout.\nexport function placeFacets(\n topology: TubeMapTopology,\n options: FacetOptions = {},\n): FacetedLayout {\n const { facetBy, ...placement } = options\n const subsets =\n facetBy === undefined || facetBy === null\n ? []\n : facetBy === 'haplotype_sample'\n ? facetHaplotypes(topology, placement)\n : facetReads(topology, facetBy, placement)\n if (subsets.length === 0) {\n const layout = placeTubeMap(topology, placement)\n return {\n panels: [\n {\n layout,\n readCount: layout.reads.length,\n haplotypeCount: haplotypeCount(topology, topology.tracks),\n offsetY: 0,\n },\n ],\n bounds: layout.bounds,\n }\n }\n const banded: LayerData =\n facetBy === 'haplotype_sample' ? 'haplotypes' : 'reads'\n let nextBandId: number | undefined\n let bottom = 0\n const panels = subsets.map(({ facet, tracks, reads }, i) => {\n const layout = placeSubset(\n topology,\n tracks,\n reads,\n nextBandId === undefined ? undefined : { [banded]: nextBandId },\n )\n for (const id of layout.coarsenedEdgeMeta.keys()) {\n if (nextBandId === undefined || id >= nextBandId) {\n nextBandId = id + 1\n }\n }\n const offsetY =\n i === 0 ? 0 : bottom + FACET_GAP + FACET_LABEL_HEIGHT - layout.bounds.minY\n bottom = offsetY + layout.bounds.maxY\n return {\n facet,\n readCount: reads.length,\n haplotypeCount: haplotypeCount(topology, tracks),\n layout,\n offsetY,\n }\n })\n return {\n panels,\n bounds: {\n minX: Math.min(...panels.map(p => p.layout.bounds.minX)),\n maxX: Math.max(...panels.map(p => p.layout.bounds.maxX)),\n minY: panels[0]!.layout.bounds.minY - FACET_LABEL_HEIGHT,\n maxY: bottom,\n },\n }\n}\n\n// The first id each layer's bands take\ntype BandIdBase = Partial<Record<LayerData, number>>\n\n// Place copies of the topology's nodes and the given tracks and reads,\n// measuring x from them or taking the topology's. Haplotype bands take ids\n// from COARSENED_ID_BASE and read bands straight after, unless `bandIdBase`\n// says otherwise.\nfunction place(\n topology: TubeMapTopology,\n tracks: readonly TopologyTrack[],\n reads: readonly TopologyTrack[],\n x: 'measure' | 'topology',\n bandIdBase: BandIdBase = {},\n): TubeMapLayout {\n const state = emptyState(topology.options)\n topology.nodes.forEach((node, i) => {\n state.nodes[i] = { ...node } as LayoutNode\n })\n state.tracks = tracks.map(track => ({ ...track }) as Track)\n state.reads = reads.map(read => ({ ...read }) as Track)\n state.nodeMap = topology.nodeMap\n state.maxOrder = topology.maxOrder\n state.trackForRuler = topology.trackForRuler\n\n // Banded haplotypes leave the reference its lane and join the reads'\n // overlay, above the reads, before calculateTrackWidth and\n // generateLaneAssignment see the tracks.\n const { layers, ignoreStrand } = state.config\n const haplotypeBandIdBase = bandIdBase.haplotypes ?? COARSENED_ID_BASE\n const haplotypeBands =\n statOf(layers, 'haplotypes') === 'coarsen'\n ? bandHaplotypes(state, haplotypeBandIdBase)\n : undefined\n if (haplotypeBands !== undefined) {\n state.tracks = [haplotypeBands.ref]\n }\n\n calculateTrackWidth(state)\n generateLaneAssignment(state)\n // also places the nodes that only filtered-out reads visit\n generateReadOnlyNodeAttributes(state)\n\n // A band crosses exactly two nodes, so placeReads and the shapes handle it\n // like any read, and node heights grow with the edge count rather than the\n // read or haplotype count.\n const readBands =\n statOf(layers, 'reads') === 'coarsen' && state.reads.length > 0\n ? buildCoarsenedSyntheticBands(\n state,\n state.reads,\n 'read',\n bandIdBase.reads ??\n haplotypeBandIdBase + (haplotypeBands?.bands.length ?? 0),\n )\n : undefined\n if (readBands !== undefined) {\n state.reads = readBands.bands\n }\n const coarsened: Coarsenings = {}\n for (const [data, unit, banding] of [\n ['haplotypes', 'haplotype', haplotypeBands],\n ['reads', 'read', readBands],\n ] as const) {\n if (banding !== undefined) {\n reverseReversedReads(state, banding.bands)\n generateTrackIndexSequences(state, banding.bands)\n coarsened[data] = {\n unit,\n total: banding.total,\n reverse: !ignoreStrand && banding.bands.some(b => b.is_reverse),\n }\n }\n }\n if (haplotypeBands !== undefined) {\n state.reads = haplotypeBands.bands.concat(state.reads)\n }\n\n if (state.reads.length > 0) {\n placeReads(state)\n state.tracks = state.tracks.concat(state.reads)\n } else {\n state.nodes.forEach(node => {\n node.incomingReads = []\n node.outgoingReads = []\n node.internalReads = []\n })\n }\n\n if (x === 'measure') {\n generateNodeXCoords(state)\n }\n\n generateSVGShapesFromPath(state)\n debugLog('Tracks:', state.tracks)\n debugLog('Nodes:', state.nodes)\n debugLog('Lane assignment:', state.assignments)\n getImageDimensions(state)\n return {\n nodes: state.nodes,\n tracks: state.tracks,\n reads: state.reads,\n nodeMap: state.nodeMap,\n shapes: state.shapes,\n bounds: state.imageBounds,\n maxOrder: state.maxOrder,\n trackForRuler: state.trackForRuler,\n coarsenedEdgeMeta: state.coarsenedEdgeMeta,\n coarsened,\n }\n}\n\n// Return true if the given name names a reverse strand node, and false otherwise.\nexport function isReverse(nodeName: string): boolean {\n return nodeName.startsWith('-')\n}\n\n// Get the forward version of a node name, which may be either forward or backward (negative)\nexport function forward(nodeName: string): string {\n return isReverse(nodeName) ? nodeName.substring(1) : nodeName\n}\n\n// Get the reverse version of a node name, which may be either forward or backward (negative)\nexport function reverse(nodeName: string): string {\n return isReverse(nodeName) ? nodeName : `-${nodeName}`\n}\n\n// Get the opposite orientation node name for the given node.\nexport function flip(nodeName: string): string {\n return isReverse(nodeName) ? forward(nodeName) : reverse(nodeName)\n}\n\n// Whether a signed node index visits its node forward. Index 0 is never a\n// node, so no visit is -0.\nexport function isForwardIndex(n: number): boolean {\n return n > 0\n}\n\n// Turn around every node the given track visits in reverse before it visits\n// it forward, so that track reads left to right, and flip every track's and\n// read's visits to those nodes to match, as switchNodeOrientationForPaths\n// does for the nodes it switches.\nfunction straightenTrack(state: LayoutState, index: number): void {\n const nodesToInvert = new Set<string>()\n const visitedForward = new Set<string>()\n for (const visit of state.tracks[index]!.sequence) {\n if (!isReverse(visit)) {\n visitedForward.add(visit)\n } else if (!visitedForward.has(forward(visit))) {\n nodesToInvert.add(forward(visit))\n }\n }\n if (nodesToInvert.size === 0) {\n return\n }\n\n for (const { sequence } of [...state.tracks, ...state.reads]) {\n for (let j = 0; j < sequence.length; j += 1) {\n if (nodesToInvert.has(forward(sequence[j]!))) {\n sequence[j] = flip(sequence[j]!)\n }\n }\n }\n\n state.nodes.forEach(node => {\n if (nodesToInvert.has(node.name)) {\n node.seq = getReverseComplement(node.seq)\n }\n })\n}\n\n// generates attributes (node.y, node.contentHeight) for nodes without tracks, only reads\nfunction generateReadOnlyNodeAttributes(state: LayoutState): void {\n state.nodesPerOrder = []\n for (let i = 0; i <= state.maxOrder; i += 1) {\n state.nodesPerOrder[i] = []\n }\n\n const orderY = new Map<number, number>()\n state.nodes.forEach((node: MaybeUnplacedNode) => {\n if (node.y !== undefined) {\n setMapToMax(orderY, node.order, node.y + node.contentHeight)\n }\n })\n\n // for order values where there is no node with haplotypes, orderY is calculated via tracks\n state.tracks.forEach(track => {\n if (track.type === 'haplotype') {\n track.path.forEach(step => {\n setMapToMax(orderY, step.order, (step.y ?? 0) + track.width)\n })\n }\n })\n\n state.nodes.forEach((node: MaybeUnplacedNode, i) => {\n if (node.order >= 0 && node.y === undefined) {\n node.y = (orderY.get(node.order) ?? 0) + 25\n node.contentHeight = 0\n state.nodesPerOrder[node.order]!.push(i)\n }\n })\n}\n\nfunction setMapToMax<K>(map: Map<K, number>, key: K, value: number): void {\n const existing = map.get(key)\n if (existing === undefined) {\n map.set(key, value)\n } else {\n map.set(key, Math.max(existing, value))\n }\n}\n\nexport const READ_WIDTH = 7\n\n// add info about reads to nodes (incoming, outgoing and internal reads)\nfunction assignReadsToNodes(state: LayoutState): void {\n state.nodes.forEach(node => {\n node.incomingReads = []\n node.outgoingReads = []\n node.internalReads = []\n })\n state.reads.forEach((read: MaybeUnset<Track, 'width'>, idx) => {\n // coarsened bands arrive sized by their crossing count\n if (read.width === undefined || read.width === 0) {\n read.width = READ_WIDTH\n }\n if (read.path.length === 1) {\n const firstNode = read.path[0]!.node\n if (firstNode !== null) {\n state.nodes[firstNode]!.internalReads.push(idx)\n }\n } else {\n read.path.forEach((element, pathIdx) => {\n if (pathIdx === 0) {\n const firstNode = read.path[0]!.node\n if (firstNode !== null) {\n state.nodes[firstNode]!.outgoingReads.push([idx, pathIdx])\n }\n } else {\n const elemNode = element.node\n if (elemNode !== null) {\n state.nodes[elemNode]!.incomingReads.push([idx, pathIdx])\n }\n }\n })\n }\n })\n}\n\n// calculate paths (incl. correct y coordinate) for all reads\nfunction placeReads(state: LayoutState): void {\n state.reads.forEach(read => {\n read.path = basicPath(state, read)\n })\n assignReadsToNodes(state)\n\n // placed nodes by order, then by y-coordinate\n const sortedNodes = state.nodes.filter(node => node.order >= 0)\n sortedNodes.sort(compareNodesByOrder)\n\n // One set per layer and source track: haplotype bands, then each read file\n const sets = new Map<\n string,\n { layer: number; source: number; reads: Set<number> }\n >()\n for (let i = 0; i < state.reads.length; i++) {\n const read = state.reads[i]!\n const layer = read.haplotypeShare === undefined ? 1 : 0\n const source = read.sourceTrackID\n const key = `${layer}:${source}`\n const set = sets.get(key)\n if (set === undefined) {\n sets.set(key, { layer, source, reads: new Set([i]) })\n } else {\n set.reads.add(i)\n }\n }\n const orderedSets = [...sets.values()].sort(\n (a, b) => a.layer - b.layer || a.source - b.source,\n )\n\n // A margin sets each set apart from the one above it\n const topMargin = orderedSets.length > 1 ? READ_WIDTH : 0\n sortedNodes.forEach(node => {\n for (const { reads } of orderedSets) {\n placeReadSet(state, reads, node, topMargin)\n }\n })\n\n // place read segments which are without node\n const bottomY = calculateBottomY(state)\n const elementsWithoutNode: ElementWithoutNode[] = []\n state.reads.forEach((read, idx) => {\n const len = read.path.length\n\n // For each path index, precompute the nearest preceding/following segment\n // whose node is non-null and truthy. Falls back to the boundary segment when\n // none qualifies, matching the original walking-loop semantics.\n const prevSegment = new Array<Segment | undefined>(len)\n let lastValidPrev: Segment | undefined\n for (let i = 0; i < len; i++) {\n if (i === 0) {\n prevSegment[i] = undefined\n } else {\n prevSegment[i] = lastValidPrev ?? read.path[0]\n }\n const seg = read.path[i]!\n if (seg.node !== null && seg.node) {\n lastValidPrev = seg\n }\n }\n const nextSegment = new Array<Segment | undefined>(len)\n let firstValidNext: Segment | undefined\n for (let i = len - 1; i >= 0; i--) {\n if (i === len - 1) {\n nextSegment[i] = undefined\n } else {\n nextSegment[i] = firstValidNext ?? read.path[len - 1]\n }\n const seg = read.path[i]!\n if (seg.node !== null && seg.node) {\n firstValidNext = seg\n }\n }\n\n read.path.forEach((element, pathIdx) => {\n if (element.y === undefined) {\n const previousVisitToNode = prevSegment[pathIdx]\n const nextVisitToNode = nextSegment[pathIdx]\n\n // Specifically referring to segments between a cycle that's traversing from right to left\n const betweenCycleReverseTraversal = Boolean(\n // A segment can be between a cycle if it there are nodes on both sides\n nextVisitToNode &&\n previousVisitToNode &&\n // A segment is between a cycle if the next node it visits is behind the previous node it visited\n (previousVisitToNode.order > nextVisitToNode.order ||\n // A segment can also be between a cycle if it's visiting the same node it just visited in the same direction\n (nextVisitToNode.order === previousVisitToNode.order &&\n nextVisitToNode.isForward === previousVisitToNode.isForward)),\n )\n\n element.betweenCycleReverseTraversal = betweenCycleReverseTraversal\n\n elementsWithoutNode.push({\n readIndex: idx,\n pathIndex: pathIdx,\n previousY: previousVisitToNode?.y,\n previousNode: previousVisitToNode?.node,\n })\n }\n })\n })\n\n elementsWithoutNode.sort((a, b) => compareNoNodeReads(state, a, b))\n elementsWithoutNode.forEach(element => {\n const read = state.reads[element.readIndex]!\n const segment = read.path[element.pathIndex]!\n segment.y = bottomY[segment.order]!\n bottomY[segment.order]! += read.width\n })\n\n debugLog('Reads:', state.reads)\n}\n\n// Place a particular collection of reads, identified by a list of read\n// numbers, into the given node at the right Y coordinates. All reads in all\n// nodes above it, and no reads in any nodes below it, are already placed.\n// Makes the given node bigger if needed and moves other nodes down if needed.\n// If topMargin is set, applies that amount of spacing down from whatever is above the reads.\nfunction placeReadSet(\n state: LayoutState,\n toPlace: Set<number>,\n node: LayoutNode,\n topMargin: number,\n): void {\n // Get arrays of the read entry/exit/internal-ness records we want to work on\n let incomingReads = node.incomingReads.filter(([readID]) =>\n toPlace.has(readID),\n )\n const outgoingReads = node.outgoingReads.filter(([readID]) =>\n toPlace.has(readID),\n )\n const internalReads = node.internalReads.filter(readID => toPlace.has(readID))\n\n // Only actually use the top margin if we have any reads on the node.\n if (\n incomingReads.length === 0 &&\n outgoingReads.length === 0 &&\n internalReads.length === 0\n ) {\n topMargin = 0\n }\n\n // Determine where we start vertically in the node.\n // TODO: Why do we have to double this to keep reads out of adjacent lanes???\n const startY = node.y + node.contentHeight + topMargin * 2\n\n // sort incoming reads \u2014 decorate with a precomputed key so each compare is O(1).\n // The original comparator walks pathIdx backwards in lockstep on both sides, picking\n // the first step where either has a defined y (or reaches index 0). The walk's outcome\n // for a single entry is fully captured by:\n // decisionStep: the smallest k>=1 where path[pathIdx-k].y is defined, or pathIdx+1\n // if no preceding segment has a defined y (the \"reached 0\" case).\n // y: the defined y at decisionStep, or undefined for \"reached 0\".\n // Smaller decisionStep wins; ties put the \"reached 0\" entries first;\n // otherwise compare y's.\n const incomingKeys = incomingReads.map(entry => {\n const [readID, pathIdx] = entry\n const path = state.reads[readID]!.path\n let decisionStep = pathIdx + 1\n let foundY: number | undefined\n for (let k = 1; k <= pathIdx; k++) {\n const y = path[pathIdx - k]?.y\n if (y !== undefined) {\n decisionStep = k\n foundY = y\n break\n }\n }\n return { entry, decisionStep, y: foundY }\n })\n incomingKeys.sort(compareIncomingReadKeys)\n incomingReads = incomingKeys.map(k => k.entry)\n\n // place incoming reads\n let currentY = startY\n const occupiedUntil = new Map<number, number>()\n incomingReads.forEach(readElement => {\n const read = state.reads[readElement[0]]!\n read.path[readElement[1]]!.y = currentY\n setOccupiedUntil(occupiedUntil, read, readElement[1], currentY, node)\n currentY += read.width\n })\n let maxY = currentY\n\n // sort outgoing reads\n outgoingReads.sort((a, b) =>\n compareReadOutgoingSegmentsByGoingTo(state, a, b),\n )\n\n // place outgoing reads\n const occupiedFrom = new Map<number, number>()\n currentY = startY\n outgoingReads.forEach(readElement => {\n const read = state.reads[readElement[0]]!\n const firstNodeOffset = read.firstNodeOffset ?? 0\n // place in next lane\n read.path[readElement[1]]!.y = currentY\n occupiedFrom.set(currentY, firstNodeOffset)\n // if no conflicts. The original predicate was strict-less-than, which\n // treats two reads that exactly touch (incoming ends at base K, outgoing\n // starts at base K+1) as conflicting. They don't overlap, so they can\n // share a lane \u2014 relax to <=. This also matters for coarsened Sankey\n // bands at single-base nodes (e.g. a 1bp \"G\" node): with edge-only offsets\n // the math becomes 0+1 < 1 (conflict, wrong) vs. 0+1 <= 1 (no conflict).\n const occUntil = occupiedUntil.get(currentY)\n if (occUntil === undefined || occUntil + 1 <= firstNodeOffset) {\n currentY += read.width\n maxY = Math.max(maxY, currentY)\n } else {\n // otherwise push down incoming reads to make place for outgoing Read\n occupiedUntil.set(currentY, 0)\n incomingReads.forEach(incReadElementIndices => {\n const incRead = state.reads[incReadElementIndices[0]]!\n const incReadPathElement = incRead.path[incReadElementIndices[1]]!\n if (\n incReadPathElement.y !== undefined &&\n incReadPathElement.y >= currentY\n ) {\n incReadPathElement.y += read.width\n setOccupiedUntil(\n occupiedUntil,\n incRead,\n incReadElementIndices[1],\n incReadPathElement.y,\n node,\n )\n }\n })\n currentY += read.width\n maxY += read.width\n }\n })\n\n // sort internal reads\n internalReads.sort((a, b) => compareInternalReads(state, a, b))\n\n // place internal reads\n internalReads.forEach(readIdx => {\n const currentRead = state.reads[readIdx]!\n const firstNodeOffset = currentRead.firstNodeOffset ?? 0\n const finalNodeCoverLength = currentRead.finalNodeCoverLength ?? 0\n currentY = startY\n while (\n firstNodeOffset < (occupiedUntil.get(currentY) ?? -Infinity) + 2 ||\n finalNodeCoverLength > (occupiedFrom.get(currentY) ?? Infinity) - 3\n ) {\n currentY += currentRead.width || READ_WIDTH\n }\n currentRead.path[0]!.y = currentY\n occupiedUntil.set(currentY, finalNodeCoverLength)\n maxY = Math.max(maxY, currentY)\n })\n\n // adjust node height and move other nodes vertically down\n const heightIncrease = maxY - node.y - node.contentHeight\n node.contentHeight += heightIncrease\n adjustVertically3(state, node, heightIncrease)\n}\n\n// The decorated sort key for one incoming read segment; see the comment in\n// placeReadSet for how it is derived. Exported for testing.\nexport interface IncomingReadKey {\n decisionStep: number\n y: number | undefined\n}\n\n// Smaller decisionStep wins. On a tie, entries that walked off the front of the\n// path (no defined y) sort first and tie with each other; otherwise compare y.\nexport function compareIncomingReadKeys(\n a: IncomingReadKey,\n b: IncomingReadKey,\n): number {\n if (a.decisionStep !== b.decisionStep) {\n return a.decisionStep - b.decisionStep\n }\n if (a.y === undefined || b.y === undefined) {\n return (a.y === undefined ? 0 : 1) - (b.y === undefined ? 0 : 1)\n }\n return a.y - b.y\n}\n\n// keeps track of where reads end within nodes\nfunction setOccupiedUntil(\n map: Map<number, number>,\n read: Track,\n pathIndex: number,\n y: number,\n node: Node,\n): void {\n if (pathIndex === read.path.length - 1) {\n // last node of current read\n map.set(y, read.finalNodeCoverLength ?? 0)\n } else {\n // read covers the whole node\n map.set(y, node.sequenceLength)\n }\n}\n\ninterface ElementWithoutNode {\n readIndex: number\n pathIndex: number\n previousY: number | undefined\n previousNode: number | null | undefined\n}\n\n// compare read segments which are outside of nodes to sort them in a good horizontal\n// and then vertical display order.\nfunction compareNoNodeReads(\n state: LayoutState,\n a: ElementWithoutNode,\n b: ElementWithoutNode,\n): number {\n const readA = state.reads[a.readIndex]!\n const readB = state.reads[b.readIndex]!\n const segmentA = readA.path[a.pathIndex]!\n const segmentB = readB.path[b.pathIndex]!\n // Sort by order by segments\n if (segmentA.order !== segmentB.order) {\n return segmentA.order - segmentB.order\n }\n // Sort by reads' source track\n if (readA.sourceTrackID !== readB.sourceTrackID) {\n return readA.sourceTrackID - readB.sourceTrackID\n }\n // Sort by order of previous node\n if (a.previousNode && b.previousNode) {\n const prevNodeA = state.nodes[a.previousNode]\n const prevNodeB = state.nodes[b.previousNode]\n if (prevNodeA && prevNodeB && prevNodeA.order !== prevNodeB.order) {\n return prevNodeA.order - prevNodeB.order\n }\n }\n // Segments on the reverse-going part of a cycle go below the rest, in\n // reverse order, so a loop that starts on the outside stays there and rolls\n // up in order with the other loops.\n const aPrev = a.previousY ?? 0\n const bPrev = b.previousY ?? 0\n const aReverse = segmentA.betweenCycleReverseTraversal === true\n const bReverse = segmentB.betweenCycleReverseTraversal === true\n if (aReverse !== bReverse) {\n return aReverse ? 1 : -1\n }\n return aReverse ? bPrev - aPrev : aPrev - bPrev\n}\n\n// compare read segments by where they are going to\nfunction compareReadOutgoingSegmentsByGoingTo(\n state: LayoutState,\n [readIndexA, pathIndexA]: [number, number],\n [readIndexB, pathIndexB]: [number, number],\n): number {\n // Expect two arrays both containing 2 integers.\n // The first index of each array contains the read index\n // The second index of each array contains the path index\n\n // Segments are first sorted by the y value of their last node,\n // then by the node they end on,\n // then by length in final node\n const readA = state.reads[readIndexA]!\n const readB = state.reads[readIndexB]!\n let previousValidYA: number | undefined\n let previousValidYB: number | undefined\n let lastPathIndexA = readA.path.length - 1\n let lastPathIndexB = readB.path.length - 1\n while (previousValidYA === undefined && lastPathIndexA >= 0) {\n previousValidYA = readA.path[lastPathIndexA]?.y\n lastPathIndexA -= 1\n }\n while (previousValidYB === undefined && lastPathIndexB >= 0) {\n previousValidYB = readB.path[lastPathIndexB]?.y\n lastPathIndexB -= 1\n }\n\n if (previousValidYA !== undefined && previousValidYB !== undefined) {\n return previousValidYA - previousValidYB\n }\n\n // Couldn't find a valid y value for at least one of the reads, sort by which node reads end on\n const initialNodeA = readA.path[pathIndexA]?.node\n const initialNodeB = readB.path[pathIndexB]?.node\n let nodeA: LayoutNode | null | undefined =\n typeof initialNodeA === 'number' ? state.nodes[initialNodeA] : null\n let nodeB: LayoutNode | null | undefined =\n typeof initialNodeB === 'number' ? state.nodes[initialNodeB] : null\n // Follow the reads' paths until we find the node they diverge at\n // Or, they go through all the same nodes and we do a tiebreaker at the end\n while (nodeA && nodeB && nodeA === nodeB) {\n if (pathIndexA < readA.path.length - 1) {\n pathIndexA += 1\n while (readA.path[pathIndexA]?.node === null) {\n pathIndexA += 1\n } // skip null nodes in path\n const nextNodeIdx = readA.path[pathIndexA]?.node\n nodeA = typeof nextNodeIdx === 'number' ? state.nodes[nextNodeIdx] : null\n } else {\n nodeA = null\n }\n if (pathIndexB < readB.path.length - 1) {\n pathIndexB += 1\n while (readB.path[pathIndexB]?.node === null) {\n pathIndexB += 1\n } // skip null nodes in path\n const nextNodeIdx = readB.path[pathIndexB]?.node\n nodeB = typeof nextNodeIdx === 'number' ? state.nodes[nextNodeIdx] : null\n } else {\n nodeB = null\n }\n }\n if (nodeA) {\n if (nodeB) {\n return compareNodesByOrder(nodeA, nodeB)\n }\n return 1 // nodeB is null, nodeA not null\n }\n if (nodeB) {\n return -1\n } // nodeB not null, nodeA null\n // both nodes are null -> both end in the same node\n const beginDiff = (readA.firstNodeOffset ?? 0) - (readB.firstNodeOffset ?? 0)\n if (beginDiff !== 0) {\n return beginDiff\n }\n\n // break tie: both reads cover the same nodes and begin at the same position\n\n // One or both reads didn't have a previously valid Y value, compare by the endPosition of the read\n return (readA.finalNodeCoverLength ?? 0) - (readB.finalNodeCoverLength ?? 0)\n}\n\n// Compare tracks based on ordering at their first convergence\nfunction compareTrackByInitialOrdering(trackA: Track, trackB: Track): number {\n // Find the first node where the two tracks converge, sort by layer.\n const pathA = trackA.path\n const pathB = trackB.path\n\n let AIndex = 0\n let BIndex = 0\n while (AIndex < pathA.length && BIndex < pathB.length) {\n const a = pathA[AIndex]!\n const b = pathB[BIndex]!\n const trackAOrder = a.order\n const trackBOrder = b.order\n if (trackAOrder === trackBOrder && a.node && b.node) {\n return (b.y ?? 0) - (a.y ?? 0)\n } else if (trackAOrder < trackBOrder) {\n AIndex += 1\n } else if (trackAOrder > trackBOrder) {\n BIndex += 1\n } else {\n // Orders are equal but are traversing out of nodes\n AIndex += 1\n BIndex += 1\n }\n }\n\n // Tracks do not converge, keep the same ordering\n return 0\n}\n\n// compare 2 reads which are completely within a single node\nfunction compareInternalReads(\n state: LayoutState,\n idxA: number,\n idxB: number,\n): number {\n const a = state.reads[idxA]!\n const b = state.reads[idxB]!\n // compare by first base within first node\n const aFirst = a.firstNodeOffset ?? 0\n const bFirst = b.firstNodeOffset ?? 0\n if (aFirst < bFirst) {\n return -1\n } else if (aFirst > bFirst) {\n return 1\n }\n\n // compare by last base within last node\n const aLast = a.finalNodeCoverLength ?? 0\n const bLast = b.finalNodeCoverLength ?? 0\n if (aLast < bLast) {\n return -1\n } else if (aLast > bLast) {\n return 1\n }\n\n return 0\n}\n\n// determine biggest y-coordinate for each order-value\nfunction calculateBottomY(state: LayoutState): number[] {\n const bottomY: number[] = []\n for (let i = 0; i <= state.maxOrder; i += 1) {\n bottomY.push(0)\n }\n\n state.nodes.forEach((node: MaybeUnplacedNode) => {\n if (node.y !== undefined) {\n bottomY[node.order] = Math.max(\n bottomY[node.order]!,\n node.y + node.contentHeight + 20,\n )\n }\n })\n\n state.tracks.forEach(track => {\n track.path.forEach(element => {\n bottomY[element.order] = Math.max(\n bottomY[element.order]!,\n (element.y ?? 0) + track.width,\n )\n })\n })\n return bottomY\n}\n\n// The segments a track draws, in order: one per node visit, plus one per\n// order slot it passes or turns around in without visiting a node. They carry\n// no lanes or coordinates yet.\nfunction basicPath(state: LayoutState, track: Track): Segment[] {\n const path: Segment[] = []\n const pass = (order: number, isForward: boolean): void => {\n path.push({ order, isForward, node: null })\n }\n const visit = (order: number, isForward: boolean, node: number): void => {\n path.push({ order, isForward, node })\n }\n\n let currentNodeIndex = Math.abs(track.indexSequence[0]!)\n let currentNodeIsForward = isForwardIndex(track.indexSequence[0]!)\n let currentNode = state.nodes[currentNodeIndex]!\n visit(currentNode.order, currentNodeIsForward, currentNodeIndex)\n\n for (let i = 1; i < track.sequence.length; i += 1) {\n const previousNode = currentNode\n const previousNodeIsForward = currentNodeIsForward\n currentNodeIndex = Math.abs(track.indexSequence[i]!)\n currentNodeIsForward = isForwardIndex(track.indexSequence[i]!)\n currentNode = state.nodes[currentNodeIndex]!\n const { order } = currentNode\n\n if (order > previousNode.order) {\n if (!previousNodeIsForward) {\n pass(previousNode.order, true)\n }\n for (let j = previousNode.order + 1; j < order; j += 1) {\n pass(j, true)\n }\n if (!currentNodeIsForward) {\n pass(order, true)\n }\n } else if (order < previousNode.order) {\n if (previousNodeIsForward) {\n pass(previousNode.order, false)\n }\n for (let j = previousNode.order - 1; j > order; j -= 1) {\n pass(j, false)\n }\n if (currentNodeIsForward) {\n pass(order, false)\n }\n } else if (currentNodeIsForward === previousNodeIsForward) {\n pass(order, !currentNodeIsForward)\n }\n visit(order, currentNodeIsForward, currentNodeIndex)\n }\n return path\n}\n\n// Turn each read that visits only reverse nodes around to visit them forward\nfunction reverseReversedReads(\n state: LayoutState,\n reads: readonly Track[] = state.reads,\n): void {\n reads.forEach(read => {\n let pos = 0\n while (pos < read.sequence.length && read.sequence[pos]!.startsWith('-')) {\n pos += 1\n }\n if (pos === read.sequence.length) {\n // completely reversed read\n read.is_reverse = true\n read.sequence = read.sequence.reverse() // invert sequence\n for (let i = 0; i < read.sequence.length; i += 1) {\n read.sequence[i] = forward(read.sequence[i]!) // visit nodes forward\n // TODO: Do we really want to visit all the nodes forward here? Are we\n // sure we aren't in mixed orientation?\n }\n\n const sequenceNew = read.sequenceNew ?? []\n sequenceNew.reverse() // invert sequence\n read.sequenceNew = sequenceNew\n for (const entry of sequenceNew) {\n entry.nodeName = forward(entry.nodeName) // visit nodes forward\n reverseMismatches(\n entry.mismatches,\n nodeByName(state, entry.nodeName).sequenceLength,\n )\n }\n\n // adjust firstNodeOffset and finalNodeCoverLength\n const temp = read.firstNodeOffset ?? 0\n const firstLen = nodeByName(state, read.sequence[0]!).sequenceLength\n read.firstNodeOffset = firstLen - (read.finalNodeCoverLength ?? 0)\n const lastLen = nodeByName(\n state,\n read.sequence[read.sequence.length - 1]!,\n ).sequenceLength\n read.finalNodeCoverLength = lastLen - temp\n }\n })\n}\n\n// Flip a node's mismatches onto the opposite strand: positions are measured\n// from the other end of the node, and sequences are reverse-complemented.\n// sequenceLength (not node.width, which is only equal to it in 'normal'\n// node-width mode) is the right pivot because mismatch positions are base\n// offsets.\nexport function reverseMismatches(\n mismatches: Mismatch[],\n sequenceLength: number,\n): void {\n mismatches.forEach(mm => {\n Object.assign(mm, mirroredMismatch(mm, sequenceLength))\n })\n}\n\nexport function mirroredMismatch(\n mm: Mismatch,\n sequenceLength: number,\n): Mismatch {\n const span =\n mm.type === 'insertion'\n ? 0\n : mm.type === 'deletion'\n ? (mm.length ?? 0)\n : (mm.seq?.length ?? 0)\n return {\n ...mm,\n pos: sequenceLength - mm.pos - span,\n ...(mm.seq !== undefined && { seq: getReverseComplement(mm.seq) }),\n }\n}\n\nconst COMPLEMENT: Record<string, string> = { A: 'T', T: 'A', C: 'G', G: 'C' }\n\nfunction getReverseComplement(s: string): string {\n let result = ''\n for (let i = s.length - 1; i >= 0; i -= 1) {\n result += COMPLEMENT[s.charAt(i)] ?? 'N'\n }\n return result\n}\n\n// for each track: generate sequence of node indices from seq. of node names.\n// Tracks revisit the same names, so each name resolves once per call.\nfunction generateTrackIndexSequences(\n state: LayoutState,\n tracksOrReads: Track[],\n): void {\n const signedIndexOf = new Map<string, number>()\n tracksOrReads.forEach(track => {\n track.indexSequence = track.sequence.map(nodeName => {\n let signed = signedIndexOf.get(nodeName)\n if (signed === undefined) {\n const index = state.nodeMap.get(forward(nodeName))\n if (index === undefined) {\n throw new Error(\n `Track ${track.name ?? track.id} visits unknown node ${nodeName}`,\n )\n }\n signed = isReverse(nodeName) ? -index : index\n signedIndexOf.set(nodeName, signed)\n }\n return signed\n })\n })\n}\n\n// Tracks enter and leave a node this far outside it horizontally\nconst NODE_HORIZONTAL_SLACK = 20\n\n// The box around every node outline and track shape. A turnaround's corners\n// reach no further out than its vertical rectangles, so the rectangles and\n// curves stand in for them.\nfunction getImageDimensions(state: LayoutState): void {\n // Sentinels, deliberately crossed: if nothing below runs, minZoom() and\n // alignSVG() detect the empty content rather than computing a negative scale.\n const bounds: ImageBounds = { minX: 99, maxX: -99, minY: 99, maxY: -99 }\n\n const { rectangles, verticalRectangles, curves } = state.shapes\n for (const shapes of [rectangles, verticalRectangles, curves]) {\n for (const { xStart, xEnd } of shapes) {\n bounds.minX = Math.min(bounds.minX, xStart, xEnd)\n bounds.maxX = Math.max(bounds.maxX, xStart, xEnd)\n }\n }\n\n state.nodes.forEach((node: MaybeUnplacedNode) => {\n if (node.x !== undefined) {\n bounds.minX = Math.min(bounds.minX, node.x - 9)\n bounds.maxX = Math.max(\n bounds.maxX,\n node.x + NODE_HORIZONTAL_SLACK + node.pixelWidth,\n )\n }\n if (node.y !== undefined) {\n bounds.minY = Math.min(bounds.minY, node.y - 10)\n bounds.maxY = Math.max(bounds.maxY, node.y + node.contentHeight + 10)\n }\n })\n\n state.tracks.forEach(track => {\n track.path.forEach(segment => {\n const y = segment.y ?? 0\n bounds.maxY = Math.max(bounds.maxY, y + track.width)\n bounds.minY = Math.min(bounds.minY, y)\n })\n })\n\n state.imageBounds = bounds\n}\n\n// Resolve a (possibly reverse-oriented) node name to its layout node. Every\n// caller runs after generateNodeMap, so a miss is a programming error.\nfunction nodeByName(state: LayoutState, nodeName: string): LayoutNode {\n const index = state.nodeMap.get(forward(nodeName))\n const node = index === undefined ? undefined : state.nodes[index]\n if (node === undefined) {\n throw new Error(`Unknown node ${nodeName}`)\n }\n return node\n}\n\n// map node names to node indices\nfunction generateNodeMap(state: LayoutState): Map<string, number> {\n const nodeMap = new Map<string, number>()\n state.nodes.forEach((node, index) => {\n nodeMap.set(node.name, index)\n })\n return nodeMap\n}\n\n// adds a successor-array to each node containing the indices of the nodes coming directly after the current node\nfunction generateNodeSuccessors(state: LayoutState): void {\n const successorSets: Set<number>[] = state.nodes.map(() => new Set())\n const predecessorSets: Set<number>[] = state.nodes.map(() => new Set())\n\n const addEdges = (track: Track): void => {\n for (let i = 0; i < track.indexSequence.length - 1; i += 1) {\n const current = Math.abs(track.indexSequence[i]!)\n const follower = Math.abs(track.indexSequence[i + 1]!)\n successorSets[current]!.add(follower)\n predecessorSets[follower]!.add(current)\n }\n }\n\n state.tracks.forEach(addEdges)\n state.reads.forEach(addEdges)\n\n state.nodes.forEach((node, i) => {\n node.successors = Array.from(successorSets[i]!)\n node.predecessors = Array.from(predecessorSets[i]!)\n })\n}\n\nfunction generateNodeOrderOfSingleTrack(\n state: LayoutState,\n sequence: number[],\n): void {\n let forwardOrder = 0\n let backwardOrder = 0\n let minOrder = 0\n\n sequence.forEach(nodeIndex => {\n const idx = Math.abs(nodeIndex)\n if (nodeIndex < 0) {\n const order = (state.nodeOrders[idx] ??= backwardOrder)\n if (order < minOrder) {\n minOrder = order\n }\n forwardOrder = order\n backwardOrder = order - 1\n } else {\n const order = (state.nodeOrders[idx] ??= forwardOrder)\n forwardOrder = order + 1\n backwardOrder = order\n }\n })\n if (minOrder < 0) {\n increaseOrderForAllNodes(state, -minOrder)\n }\n}\n\n// calculate the order-value of nodes contained in sequence which are to the left of the first node which already has an order-value\nfunction generateNodeOrderTrackBeginning(\n state: LayoutState,\n sequence: number[],\n): number | null {\n let anchorIndex = 0\n let minOrder = 0\n\n while (\n anchorIndex < sequence.length &&\n state.nodeOrders[Math.abs(sequence[anchorIndex]!)] === undefined\n ) {\n anchorIndex += 1 // anchor = first node in common with existing graph\n }\n if (anchorIndex >= sequence.length) {\n return null\n }\n\n const anchorSeqVal = sequence[anchorIndex]!\n let currentOrder: number\n let increment: number\n if (anchorSeqVal >= 0) {\n // regular node\n currentOrder = state.nodeOrders[anchorSeqVal]! - 1\n increment = -1\n } else {\n // reverse node\n currentOrder = state.nodeOrders[-anchorSeqVal]! + 1\n increment = 1\n }\n\n for (let j = anchorIndex - 1; j >= 0; j -= 1) {\n // assign order to nodes which are left of anchor node\n const idx = Math.abs(sequence[j]!)\n if (state.nodeOrders[idx] === undefined) {\n state.nodeOrders[idx] = currentOrder\n minOrder = Math.min(minOrder, currentOrder)\n currentOrder += increment\n }\n }\n\n if (minOrder < 0) {\n increaseOrderForAllNodes(state, -minOrder)\n }\n return anchorIndex\n}\n\n// Sentinel order for nodes no track or read reaches.\nexport const UNREACHABLE_ORDER = -1\n\n// Replace every unassigned entry with UNREACHABLE_ORDER, producing a dense\n// array. Holes matter here: `new Array(n)` is all holes and forEach/map skip\n// them, so an in-place forEach would leave the sentinel unset.\nexport function fillUnassignedOrders(\n orders: readonly (number | undefined)[],\n): number[] {\n const filled: number[] = []\n for (const order of orders) {\n filled.push(order ?? UNREACHABLE_ORDER)\n }\n return filled\n}\n\n// generate global sequence of nodes from left to right, starting with first track and adding other tracks sequentially\nfunction generateNodeOrder(state: LayoutState): void {\n let modifiedSequence: number[]\n let currentOrder: number\n let rightIndex: number | null\n let leftIndex: number\n let minOrder = 0\n const tracksAndReads = state.tracks.concat(state.reads)\n const reachability: ReachabilityScratch = {\n stamp: new Int32Array(state.nodes.length),\n generation: 0,\n }\n\n // fill() makes the array dense: `new Array(n)` alone is all holes, which\n // forEach skips, so neither the sentinel pass nor the copy-back below ran.\n state.nodeOrders = new Array<number | undefined>(state.nodes.length).fill(\n undefined,\n )\n // Widened to Node, whose order is optional, to clear the previous run's orders\n state.nodes.forEach((node: Node) => {\n node.order = undefined\n })\n\n generateNodeOrderOfSingleTrack(state, state.tracks[0]!.indexSequence)\n\n for (let i = 1; i < tracksAndReads.length; i += 1) {\n debugLog(`generating order for track ${i + 1}`)\n rightIndex = generateNodeOrderTrackBeginning(\n state,\n tracksAndReads[i]!.indexSequence,\n )\n if (rightIndex === null) {\n if (i < state.tracks.length) {\n generateNodeOrderOfSingleTrack(state, tracksAndReads[i]!.indexSequence)\n } else {\n tracksAndReads.splice(i, 1)\n state.reads.splice(i - state.tracks.length, 1)\n i -= 1\n }\n continue\n }\n modifiedSequence = uninvert(tracksAndReads[i]!.indexSequence)\n\n while (rightIndex < modifiedSequence.length) {\n // move right until the end of the sequence\n leftIndex = rightIndex\n rightIndex += 1\n while (\n rightIndex < modifiedSequence.length &&\n state.nodeOrders[modifiedSequence[rightIndex]!] === undefined\n ) {\n rightIndex += 1\n }\n\n if (rightIndex < modifiedSequence.length) {\n // middle segment between two anchors\n currentOrder = state.nodeOrders[modifiedSequence[leftIndex]!]! + 1\n for (let j = leftIndex + 1; j < rightIndex; j += 1) {\n state.nodeOrders[modifiedSequence[j]!] = currentOrder\n currentOrder += 1\n }\n\n if (\n state.nodeOrders[modifiedSequence[rightIndex]!]! >\n state.nodeOrders[modifiedSequence[leftIndex]!]!\n ) {\n if (state.nodeOrders[modifiedSequence[rightIndex]!]! < currentOrder) {\n increaseOrderForSuccessors(\n state,\n modifiedSequence[rightIndex]!,\n modifiedSequence[rightIndex - 1]!,\n currentOrder,\n )\n }\n } else {\n if (\n tracksAndReads[i]!.indexSequence[rightIndex]! >= 0 &&\n !isSuccessor(\n state,\n modifiedSequence[rightIndex]!,\n modifiedSequence[leftIndex]!,\n reachability,\n )\n ) {\n // no real reversal\n increaseOrderForSuccessors(\n state,\n modifiedSequence[rightIndex]!,\n modifiedSequence[rightIndex - 1]!,\n currentOrder,\n )\n } else {\n // real reversal\n if (\n tracksAndReads[i]!.indexSequence[leftIndex]! < 0 ||\n (state.nodes[modifiedSequence[leftIndex + 1]!]!.degree < 2 &&\n state.nodeOrders[modifiedSequence[rightIndex]!]! <\n state.nodeOrders[modifiedSequence[leftIndex]!]!)\n ) {\n currentOrder = state.nodeOrders[modifiedSequence[leftIndex]!]! - 1\n for (let j = leftIndex + 1; j < rightIndex; j += 1) {\n state.nodeOrders[modifiedSequence[j]!] = currentOrder\n minOrder = Math.min(minOrder, currentOrder)\n currentOrder -= 1\n }\n }\n }\n }\n } else {\n // right segment to the right of last anchor\n if (tracksAndReads[i]!.indexSequence[leftIndex]! >= 0) {\n // elongate towards the right\n currentOrder = state.nodeOrders[modifiedSequence[leftIndex]!]! + 1\n for (let j = leftIndex + 1; j < modifiedSequence.length; j += 1) {\n const idx = modifiedSequence[j]!\n if (state.nodeOrders[idx] === undefined) {\n state.nodeOrders[idx] = currentOrder\n currentOrder += 1\n }\n }\n } else {\n // elongate towards the left\n currentOrder = state.nodeOrders[modifiedSequence[leftIndex]!]! - 1\n for (let j = leftIndex + 1; j < modifiedSequence.length; j += 1) {\n const idx = modifiedSequence[j]!\n if (state.nodeOrders[idx] === undefined) {\n state.nodeOrders[idx] = currentOrder\n minOrder = Math.min(minOrder, currentOrder)\n currentOrder -= 1\n }\n }\n }\n }\n }\n }\n\n if (minOrder < 0) {\n increaseOrderForAllNodes(state, -minOrder)\n }\n\n // Nodes unreachable from any track get UNREACHABLE_ORDER so every node ends\n // up with a defined order; downstream code uses `order >= 0` to skip them.\n const finalOrders = fillUnassignedOrders(state.nodeOrders)\n state.nodeOrders = finalOrders\n finalOrders.forEach((order, i) => {\n const node = state.nodes[i]\n if (node !== undefined) {\n node.order = order\n }\n })\n}\n\n// Reusable visited-set for the reachability searches in generateNodeOrder.\n// Stamping with a generation counter avoids reallocating (and re-zeroing) an\n// array of nodes.length booleans on every call.\ninterface ReachabilityScratch {\n stamp: Int32Array\n generation: number\n}\n\nfunction isSuccessor(\n state: LayoutState,\n first: number,\n second: number,\n scratch: ReachabilityScratch,\n): boolean {\n scratch.generation += 1\n const { stamp, generation } = scratch\n const stack: number[] = [first]\n stamp[first] = generation\n while (stack.length > 0) {\n const current = stack.pop()!\n if (current === second) {\n return true\n }\n for (const childIndex of state.nodes[current]!.successors) {\n if (stamp[childIndex] !== generation) {\n stamp[childIndex] = generation\n stack.push(childIndex)\n }\n }\n }\n return false\n}\n\n// get order number of the rightmost node\nfunction getMaxOrder(state: LayoutState): number {\n let max = -1\n state.nodeOrders.forEach(order => {\n if (order !== undefined && order > max) {\n max = order\n }\n })\n return max\n}\n\n// generates sequence keeping the order but switching all reversed (negative) nodes to forward nodes\nfunction uninvert(sequence: number[]): number[] {\n return sequence.map(v => Math.abs(v))\n}\n\n// increases the order-value of all nodes by amount\nfunction increaseOrderForAllNodes(state: LayoutState, amount: number): void {\n state.nodeOrders.forEach((order, i) => {\n if (order !== undefined) {\n state.nodeOrders[i] = order + amount\n }\n })\n}\n\n// increases the order-value for currentNode and (if necessary) successor nodes recursively\nfunction increaseOrderForSuccessors(\n state: LayoutState,\n startingNode: number,\n tabuNode: number,\n newOrder: number,\n): void {\n const increasedOrders = new Map<number, number>()\n // Walked with a head pointer rather than shift(), which is O(length) per pop.\n const queue: [number, number][] = [[startingNode, newOrder]]\n let head = 0\n\n while (head < queue.length) {\n const [currentNode, currentOrder] = queue[head]!\n head += 1\n const currentNodeOrder = state.nodeOrders[currentNode]\n\n if (currentNodeOrder !== undefined && currentNodeOrder < currentOrder) {\n if (\n !increasedOrders.has(currentNode) ||\n increasedOrders.get(currentNode)! < currentOrder\n ) {\n increasedOrders.set(currentNode, currentOrder)\n state.nodes[currentNode]!.successors.forEach(successor => {\n if (\n state.nodeOrders[successor]! > currentNodeOrder &&\n successor !== tabuNode\n ) {\n // only increase order of successors to the right of currentNode\n queue.push([successor, currentOrder + 1])\n }\n })\n if (currentNode !== startingNode) {\n state.nodes[currentNode]!.predecessors.forEach(predecessor => {\n if (\n state.nodeOrders[predecessor]! > currentNodeOrder &&\n predecessor !== tabuNode\n ) {\n // only increase order of predecessors to the right of currentNode\n queue.push([predecessor, currentOrder + 1])\n }\n })\n }\n }\n }\n }\n\n increasedOrders.forEach((value, key) => {\n state.nodeOrders[key] = value\n })\n}\n\n// calculates the node degree: the number of tracks passing through the node / the node height\nfunction generateNodeDegree(state: LayoutState): void {\n state.nodes.forEach(node => {\n node.tracks = []\n })\n\n state.tracks.forEach(track => {\n track.indexSequence.forEach(nodeIndex => {\n state.nodes[Math.abs(nodeIndex)]!.tracks.push(track.id)\n })\n })\n\n state.nodes.forEach(node => {\n node.degree = node.tracks.length\n })\n}\n\n// Orient the nodes to suit the tracks and reads\nfunction switchNodeOrientation(state: LayoutState): void {\n switchNodeOrientationForPaths(\n state,\n [...state.tracks.slice(1), ...state.reads],\n state.tracks[0]!,\n )\n}\n\n// If more of the given paths pass through a specific node in reverse direction than in\n// regular direction, switch its orientation. Nodes the pivot path visits\n// forward keep theirs. Processes all paths' nodes in place, reading each\n// visit's node from its indexSequence, which must match its sequence.\nfunction switchNodeOrientationForPaths(\n state: LayoutState,\n paths: Track[],\n pivotPath: Track,\n): void {\n const scores = new Int32Array(state.nodes.length)\n const onPivot = new Uint8Array(state.nodes.length)\n for (const nodeName of pivotPath.sequence) {\n const index = isReverse(nodeName) ? undefined : state.nodeMap.get(nodeName)\n if (index !== undefined) {\n onPivot[index] = 1\n }\n }\n\n for (const path of paths) {\n const { sequence, indexSequence } = path\n const last = indexSequence.length - 1\n for (let j = 0; j <= last; j += 1) {\n const index = Math.abs(indexSequence[j]!)\n if (onPivot[index] === 1) {\n continue\n }\n const order = state.nodes[index]!.order\n const prevOrder =\n j > 0 ? state.nodes[Math.abs(indexSequence[j - 1]!)]!.order : undefined\n const nextOrder =\n j < last\n ? state.nodes[Math.abs(indexSequence[j + 1]!)]!.order\n : undefined\n // A reverse visit votes for switching when the path runs left to right\n // through the node, and against when it runs right to left.\n const vote = isReverse(sequence[j]!) ? 1 : -1\n if (\n (prevOrder === undefined || prevOrder < order) &&\n (nextOrder === undefined || order < nextOrder)\n ) {\n scores[index]! += vote\n }\n if (\n (prevOrder === undefined || prevOrder > order) &&\n (nextOrder === undefined || order > nextOrder)\n ) {\n scores[index]! -= vote\n }\n }\n }\n\n for (const path of paths) {\n const { sequence, indexSequence } = path\n for (let j = 0; j < indexSequence.length; j += 1) {\n if (scores[Math.abs(indexSequence[j]!)]! > 0) {\n sequence[j] = flip(sequence[j]!)\n indexSequence[j] = -indexSequence[j]!\n }\n }\n }\n\n state.nodes.forEach((node, index) => {\n if (scores[index]! > 0) {\n node.seq = getReverseComplement(node.seq)\n node.switched = true\n }\n })\n}\n\n// calculates the concrete values for the nodes' x-coordinates\nfunction generateNodeXCoords(state: LayoutState): void {\n let currentX = 0\n let nextX = 20\n let currentOrder = -1\n const sortedNodes = state.nodes.slice()\n sortedNodes.sort(compareNodesByOrder)\n const extra = calculateExtraSpace(state)\n\n sortedNodes.forEach(node => {\n if (node.order >= 0) {\n if (node.order > currentOrder) {\n currentOrder = node.order\n currentX = nextX + 10 * extra[node.order]!\n }\n node.x = currentX\n nextX = Math.max(nextX, currentX + 40 + node.pixelWidth)\n }\n })\n}\n\n// A lane change rising or falling this many px or less keeps sequenceTubeMap's\n// slope; one rising further turns steeper\nconst RISE_KNEE = 35\n\n// The extra space, in units of 10 px, that a gap takes for a track rising or\n// falling `rise` px across it. Past RISE_KNEE it grows with the square root of\n// the rise, so a long jump steepens its curve more than it widens the column.\nfunction riseExtra(rise: number): number {\n return rise <= RISE_KNEE\n ? rise / 17.5\n : (RISE_KNEE / 17.5) * Math.sqrt(rise / RISE_KNEE)\n}\n\n// calculates additional horizontal space needed between two nodes\n// two neighboring nodes have to be moved further apart if there is a lot going on in between them\n// -> edges turning to vertical orientation should not overlap\nfunction calculateExtraSpace(state: LayoutState): number[] {\n const leftSideEdges: number[] = []\n const rightSideEdges: number[] = []\n const fallAngleAdjustment: number[] = []\n const extra: number[] = []\n\n for (let i = 0; i <= state.maxOrder; i += 1) {\n leftSideEdges.push(0)\n rightSideEdges.push(0)\n fallAngleAdjustment.push(0)\n }\n\n state.tracks.forEach(track => {\n for (let i = 1; i < track.path.length; i += 1) {\n const seg = track.path[i]!\n const prevSeg = track.path[i - 1]!\n // Track is going to the same node, account for space taken up by edges looping around\n if (seg.order === prevSeg.order) {\n // repeat or translocation\n if (seg.isForward) {\n leftSideEdges[seg.order] = leftSideEdges[seg.order]! + 1\n } else {\n rightSideEdges[seg.order] = rightSideEdges[seg.order]! + 1\n }\n } else {\n // TODO: Extra space should also be accounted when there are too many tracks curving at the nodes\n fallAngleAdjustment[seg.order] = Math.max(\n riseExtra(Math.abs((seg.y ?? 0) - (prevSeg.y ?? 0))),\n fallAngleAdjustment[seg.order]!,\n )\n }\n }\n })\n\n extra.push(Math.max(0, leftSideEdges[0]! - 1))\n for (let i = 1; i <= state.maxOrder; i += 1) {\n // Extra space uses space needed for edges(tracks looping), or space needed to limit rise/fall angle, whichever is larger\n extra.push(\n Math.max(\n Math.max(0, leftSideEdges[i]! - 1) +\n Math.max(0, rightSideEdges[i - 1]! - 1),\n fallAngleAdjustment[i]!,\n ),\n )\n }\n return extra\n}\n\n// create and fill assignment-variable, which contains info about tracks and lanes for each order-value\nfunction generateLaneAssignment(state: LayoutState): void {\n // For each horizontal order slot, for each track number, holds the\n // SegmentAssignment object for the visit of that track to that order slot.\n // When an order slot is visited multiple times, holds whatever\n // SegmentAssignment was created most recently.\n const prevSegmentPerOrderPerTrack: SegmentAssignment[][] = []\n // Index into assignments[order] by node, so addToAssignment can find an\n // existing entry without scanning the whole order slot.\n const assignmentByOrderAndNode: Map<number, NodeAssignment>[] = []\n\n // create empty variables\n for (let i = 0; i <= state.maxOrder; i += 1) {\n state.assignments[i] = []\n assignmentByOrderAndNode[i] = new Map()\n prevSegmentPerOrderPerTrack[i] = []\n }\n\n // Record each track's segments in the order slots they cross, leaving the\n // lanes for the sweep below.\n state.tracks.forEach((track, trackNo) => {\n track.path = basicPath(state, track)\n track.path.forEach((segment, segmentNumber) => {\n addToAssignment(\n state,\n segment.order,\n segment.node,\n trackNo,\n segmentNumber,\n prevSegmentPerOrderPerTrack,\n assignmentByOrderAndNode,\n )\n })\n })\n\n // Now sweep left to right across order slots and assign vertical lanes to all the segments.\n for (let i = 0; i <= state.maxOrder; i += 1) {\n generateSingleLaneAssignment(state, state.assignments[i]!, i) // this is where the lanes get assigned\n }\n}\n\nfunction addToAssignment(\n state: LayoutState,\n order: number,\n nodeIndex: number | null,\n trackNo: number,\n segmentID: number,\n prevSegmentPerOrderPerTrack: SegmentAssignment[][],\n assignmentByOrderAndNode: Map<number, NodeAssignment>[],\n): void {\n const segment: SegmentAssignment = {\n trackID: trackNo,\n segmentID,\n compareToFromSame: prevSegmentPerOrderPerTrack[order]![trackNo] ?? null,\n }\n // A null node means the track is passing through / turning around here rather\n // than visiting a node, so such segments never share a NodeAssignment.\n const existing =\n nodeIndex === null\n ? undefined\n : assignmentByOrderAndNode[order]!.get(nodeIndex)\n\n if (existing === undefined) {\n const assignment: NodeAssignment = {\n type: 'single',\n node: nodeIndex,\n tracks: [segment],\n }\n state.assignments[order]!.push(assignment)\n if (nodeIndex !== null) {\n assignmentByOrderAndNode[order]!.set(nodeIndex, assignment)\n }\n } else {\n // add to existing node in assignment\n existing.type = 'multiple'\n existing.tracks.push(segment)\n }\n prevSegmentPerOrderPerTrack[order]![trackNo] = segment\n}\n\n// looks at assignment and sets idealY and idealLane by looking at where the tracks come from\nfunction getIdealLanesAndCoords(\n state: LayoutState,\n assignment: NodeAssignment[],\n order: number,\n): void {\n let index: number\n\n assignment.forEach(node => {\n node.idealLane = 0\n node.tracks.forEach(track => {\n if (track.segmentID === 0) {\n track.idealLane = track.trackID\n track.idealY = null\n } else {\n if (\n state.tracks[track.trackID]!.path[track.segmentID - 1]!.order ===\n order - 1\n ) {\n track.idealLane =\n state.tracks[track.trackID]!.path[track.segmentID - 1]!.lane ??\n undefined\n track.idealY =\n state.tracks[track.trackID]!.path[track.segmentID - 1]!.y\n } else if (\n track.segmentID < state.tracks[track.trackID]!.path.length - 1 &&\n state.tracks[track.trackID]!.path[track.segmentID + 1]!.order ===\n order - 1\n ) {\n track.idealLane =\n state.tracks[track.trackID]!.path[track.segmentID + 1]!.lane ??\n undefined\n track.idealY =\n state.tracks[track.trackID]!.path[track.segmentID + 1]!.y\n } else {\n index = track.segmentID - 1\n while (\n index >= 0 &&\n state.tracks[track.trackID]!.path[index]!.order !== order - 1\n ) {\n index -= 1\n }\n if (index < 0) {\n track.idealLane = track.trackID\n track.idealY = null\n } else {\n track.idealLane = state.tracks[track.trackID]!.path[index]!.lane\n track.idealY = state.tracks[track.trackID]!.path[index]!.y\n }\n }\n }\n node.idealLane! += track.idealLane!\n })\n node.idealLane /= node.tracks.length\n })\n}\n\n// assigns the optimal lanes for a single horizontal position (=order)\n// first an ideal lane is calculated for each track (which is ~ the lane of its predecessor)\n// then the nodes are sorted by their average ideal lane\n// and the whole construct is then moved up or down if necessary\nfunction generateSingleLaneAssignment(\n state: LayoutState,\n assignment: NodeAssignment[],\n order: number,\n): void {\n let currentLane = 0\n const potentialAdjustmentValues = new Set<number>()\n let currentY = 20\n let prevNameIsNull = false\n let prevTrack = -1\n\n getIdealLanesAndCoords(state, assignment, order)\n assignment.sort(compareByIdealLane)\n\n assignment.forEach(node => {\n if (node.node !== null) {\n state.nodes[node.node]!.topLane = currentLane\n if (prevNameIsNull) {\n currentY -= 10\n }\n state.nodes[node.node]!.y = currentY\n state.nodes[node.node]!.contentHeight = 0\n prevNameIsNull = false\n } else {\n if (prevNameIsNull) {\n currentY -= 25\n } else if (currentY > 20) {\n currentY -= 10\n }\n prevNameIsNull = true\n }\n\n node.tracks.sort(compareByIdealLane)\n node.tracks.forEach(track => {\n track.lane = currentLane\n if (track.trackID === prevTrack && node.node === null && prevNameIsNull) {\n currentY += 10\n }\n state.tracks[track.trackID]!.path[track.segmentID]!.lane = currentLane\n state.tracks[track.trackID]!.path[track.segmentID]!.y = currentY\n if (typeof track.idealY === 'number') {\n potentialAdjustmentValues.add(track.idealY - currentY)\n }\n currentLane += 1\n currentY += state.tracks[track.trackID]!.width\n if (node.node !== null) {\n state.nodes[node.node]!.contentHeight +=\n state.tracks[track.trackID]!.width\n }\n prevTrack = track.trackID\n })\n currentY += 25\n })\n\n adjustVertically(state, assignment, potentialAdjustmentValues)\n}\n\n// moves all tracks at a single horizontal location (=order) up/down to minimize lane changes\nfunction adjustVertically(\n state: LayoutState,\n assignment: NodeAssignment[],\n potentialAdjustmentValues: Set<number>,\n): void {\n let verticalAdjustment = 0\n let minAdjustmentCost = Number.MAX_SAFE_INTEGER\n\n potentialAdjustmentValues.forEach(moveBy => {\n const cost = getVerticalAdjustmentCost(state, assignment, moveBy)\n if (cost < minAdjustmentCost) {\n minAdjustmentCost = cost\n verticalAdjustment = moveBy\n }\n })\n\n assignment.forEach(node => {\n if (node.node !== null) {\n state.nodes[node.node]!.y += verticalAdjustment\n }\n node.tracks.forEach(track => {\n const seg = state.tracks[track.trackID]!.path[track.segmentID]!\n seg.y = seg.y! + verticalAdjustment\n })\n })\n}\n\n// Budge down all nodes and out-of-node tracks below this node by this amount\nfunction adjustVertically3(\n state: LayoutState,\n node: LayoutNode,\n adjustBy: number,\n): void {\n if (node.order < 0 || state.assignments[node.order] === undefined) {\n return\n }\n state.assignments[node.order]!.forEach(assignmentNode => {\n if (assignmentNode.node !== null) {\n const aNode = state.nodes[assignmentNode.node]!\n if (aNode !== node && aNode.y > node.y) {\n aNode.y += adjustBy\n assignmentNode.tracks.forEach(track => {\n const seg = state.tracks[track.trackID]!.path[track.segmentID]!\n seg.y = seg.y! + adjustBy\n })\n }\n } else {\n // track-segment not within a node\n assignmentNode.tracks.forEach(track => {\n const seg = state.tracks[track.trackID]!.path[track.segmentID]!\n if (seg.y! >= node.y) {\n seg.y = seg.y! + adjustBy\n }\n })\n }\n })\n if (state.nodesPerOrder[node.order]!.length > 0) {\n state.nodesPerOrder[node.order]!.forEach(nodeIndex => {\n if (\n state.nodes[nodeIndex] !== node &&\n state.nodes[nodeIndex]!.y > node.y\n ) {\n state.nodes[nodeIndex]!.y += adjustBy\n }\n })\n }\n}\n\n// calculates cost of vertical adjustment as vertical distance * width of track\nfunction getVerticalAdjustmentCost(\n state: LayoutState,\n assignment: NodeAssignment[],\n moveBy: number,\n): number {\n let result = 0\n assignment.forEach(node => {\n node.tracks.forEach(track => {\n if (\n typeof track.idealY === 'number' &&\n state.tracks[track.trackID]!.type !== 'read'\n ) {\n result +=\n Math.abs(\n track.idealY -\n moveBy -\n state.tracks[track.trackID]!.path[track.segmentID]!.y!,\n ) * state.tracks[track.trackID]!.width\n }\n })\n })\n return result\n}\n\nfunction compareByIdealLane(\n a: { idealLane?: number | undefined },\n b: { idealLane?: number | undefined },\n): number {\n if (a.idealLane !== undefined) {\n if (b.idealLane !== undefined) {\n if (a.idealLane < b.idealLane) {\n return -1\n } else if (a.idealLane > b.idealLane) {\n return 1\n }\n return 0\n }\n return -1\n }\n if (b.idealLane !== undefined) {\n return 1\n }\n return 0\n}\n\nfunction compareNodesByOrder(\n a: MaybeUnplacedNode,\n b: MaybeUnplacedNode,\n): number {\n if (a.order !== b.order) {\n return a.order - b.order\n }\n if (a.y !== undefined && b.y !== undefined) {\n return a.y - b.y\n }\n return 0\n}\n\nfunction calculateTrackWidth(state: LayoutState): void {\n // flag: if vg returns freq of 0 for all tracks, we will increase width manually\n let allAreFour = true\n\n const NARROW_WIDTH = 4\n const WIDE_WIDTH = state.config.trackWidth\n\n if (state.config.freqWidth === 'linear') {\n for (const track of state.tracks) {\n track.width =\n track.type === 'read'\n ? NARROW_WIDTH\n : Math.max(1, Math.round(track.freq ?? 1)) * WIDE_WIDTH\n }\n return\n }\n\n for (const track of state.tracks) {\n if (track.freq !== undefined) {\n track.width = Math.round(\n (Math.log(Math.max(track.freq, 1)) + 1) * NARROW_WIDTH,\n )\n } else {\n // default track width\n track.width = WIDE_WIDTH\n if (track.type !== undefined && track.type === 'read') {\n track.width = NARROW_WIDTH\n }\n }\n if (track.width !== NARROW_WIDTH) {\n allAreFour = false\n }\n }\n\n if (allAreFour) {\n state.tracks.forEach(track => {\n if (track.freq !== undefined) {\n track.width = WIDE_WIDTH\n }\n })\n }\n}\n\nfunction getReadXStart(state: LayoutState, read: Track): number {\n const seg = read.path[0]!\n const node = state.nodes[seg.node!]!\n const offset = read.firstNodeOffset ?? 0\n // read starts in forward direction, or backward from the node's far end\n return clampedXCoordinateOfBaseWithinNode(\n node,\n seg.isForward ? offset : node.sequenceLength - offset,\n )\n}\n\nfunction getReadXEnd(state: LayoutState, read: Track): number {\n const seg = read.path[read.path.length - 1]!\n const node = state.nodes[seg.node!]!\n const cover = read.finalNodeCoverLength ?? 0\n // read ends in forward direction, or backward from the node's far end\n return clampedXCoordinateOfBaseWithinNode(\n node,\n seg.isForward ? cover : node.sequenceLength - cover,\n )\n}\n\n// returns the x coordinate (in pixels) of (the left side) of the given base\n// position within the given node, or null if the position is past its end\nexport function getXCoordinateOfBaseWithinNode(\n node: Node,\n base: number,\n): number | null {\n if (base > node.sequenceLength) {\n return null\n } // equality is allowed\n return clampedXCoordinateOfBaseWithinNode(node, base)\n}\n\n// Same, but a base outside the node maps to the nearest node edge. Callers that\n// have to produce a coordinate no matter what use this: falling back to 0 would\n// put the shape at the far left of the whole image instead.\nexport function clampedXCoordinateOfBaseWithinNode(\n node: Node,\n base: number,\n): number {\n const [nodeLeftX, nodeRightX] = nodePixelCoordinatesInX(node)\n if (node.sequenceLength === 0) {\n return nodeLeftX\n }\n const clamped = Math.min(Math.max(base, 0), node.sequenceLength)\n return nodeLeftX + (clamped / node.sequenceLength) * (nodeRightX - nodeLeftX)\n}\n\n// transforms the info in the tracks' path attribute into actual coordinates\n// and saves them in shapes.rectangles and shapes.curves\nfunction generateSVGShapesFromPath(state: LayoutState): void {\n let xStart: number\n let xEnd: number\n let yStart: number\n let yEnd: number\n\n for (let i = 0; i <= state.maxOrder; i += 1) {\n state.extraLeft.push(0)\n state.extraRight.push(0)\n }\n\n // generate x coords where each order starts and ends\n const orderStartX: number[] = []\n const orderEndX: number[] = []\n state.nodes.forEach((node: MaybeUnplacedNode) => {\n if (node.x !== undefined) {\n orderStartX[node.order] = node.x\n if (orderEndX[node.order] === undefined) {\n orderEndX[node.order] = node.x + node.pixelWidth\n } else {\n orderEndX[node.order] = Math.max(\n orderEndX[node.order]!,\n node.x + node.pixelWidth,\n )\n }\n }\n })\n\n const reference = state.tracks[0]\n\n // Helps generation of verticalRectangles, correct increments of extraRight and extraLeft\n state.tracks.sort(compareTrackByInitialOrdering)\n\n state.tracks.forEach(track => {\n // start of path\n yStart = track.path[0]!.y!\n if (track.type !== 'read') {\n if (track.sequence[0]!.startsWith('-')) {\n // The track starts with an inversed node\n xStart = orderEndX[track.path[0]!.order]! + 20\n } else {\n // The track starts with a forward node\n xStart = orderStartX[track.path[0]!.order]! - 20\n }\n } else {\n xStart = getReadXStart(state, track)\n }\n\n // middle of path\n for (let i = 0; i < track.path.length; i += 1) {\n if (track.path[i]!.y !== yStart) {\n if (track.path[i - 1]!.isForward) {\n xEnd = orderEndX[track.path[i - 1]!.order]!\n } else {\n xEnd = orderStartX[track.path[i - 1]!.order]!\n }\n if (xEnd !== xStart) {\n state.shapes.rectangles.push({\n xStart: Math.min(xStart, xEnd),\n yStart,\n xEnd: Math.max(xStart, xEnd),\n yEnd: yStart + track.width - 1,\n // TODO: This is not actually the index of the track!\n id: track.id,\n name: track.name,\n type: track.type,\n })\n }\n\n if (track.path[i]!.order - 1 === track.path[i - 1]!.order) {\n // regular forward connection\n xStart = xEnd\n xEnd = orderStartX[track.path[i]!.order]!\n yEnd = track.path[i]!.y!\n state.shapes.curves.push({\n xStart,\n yStart,\n xEnd: xEnd + 1,\n yEnd,\n width: track.width,\n id: track.id,\n name: track.name,\n type: track.type,\n nodeStart: track.path[i - 1]!.node,\n nodeEnd: track.path[i]!.node,\n orderStart: track.path[i - 1]!.order,\n orderEnd: track.path[i]!.order,\n ...(track === reference ? { reference: true } : {}),\n })\n xStart = xEnd\n yStart = yEnd\n } else if (track.path[i]!.order + 1 === track.path[i - 1]!.order) {\n // regular backward connection\n xStart = xEnd\n xEnd = orderEndX[track.path[i]!.order]!\n yEnd = track.path[i]!.y!\n state.shapes.curves.push({\n xStart: xStart + 1,\n yStart,\n xEnd,\n yEnd,\n width: track.width,\n id: track.id,\n name: track.name,\n type: track.type,\n nodeStart: track.path[i - 1]!.node,\n nodeEnd: track.path[i]!.node,\n orderStart: track.path[i - 1]!.order,\n orderEnd: track.path[i]!.order,\n ...(track === reference ? { reference: true } : {}),\n })\n xStart = xEnd\n yStart = yEnd\n } else {\n // change of direction\n if (track.path[i - 1]!.isForward) {\n yEnd = track.path[i]!.y!\n generateTurnaround(\n state,\n 1,\n xEnd,\n yStart,\n yEnd,\n track.width,\n track.id,\n track.path[i]!.order,\n track.type,\n track.name,\n )\n xStart = orderEndX[track.path[i]!.order]!\n yStart = track.path[i]!.y!\n } else {\n yEnd = track.path[i]!.y!\n generateTurnaround(\n state,\n -1,\n xEnd,\n yStart,\n yEnd,\n track.width,\n track.id,\n track.path[i]!.order,\n track.type,\n track.name,\n )\n xStart = orderStartX[track.path[i]!.order]!\n yStart = track.path[i]!.y!\n }\n }\n }\n }\n\n // ending edges\n if (track.type !== 'read') {\n if (!track.path[track.path.length - 1]!.isForward) {\n // The track ends with an inversed node\n xEnd = orderStartX[track.path[track.path.length - 1]!.order]! - 20\n } else {\n // The track ends with a forward node\n xEnd = orderEndX[track.path[track.path.length - 1]!.order]! + 20\n }\n } else {\n xEnd = getReadXEnd(state, track)\n }\n state.shapes.rectangles.push({\n xStart: Math.min(xStart, xEnd),\n yStart,\n xEnd: Math.max(xStart, xEnd),\n yEnd: yStart + track.width - 1,\n id: track.id,\n name: track.name,\n type: track.type,\n })\n })\n}\n\n// Sankey-mode synthesis: one synthetic \"read\" per (srcSigned \u2192 dstSigned) edge,\n// fed through the normal placeReads/generateSVGShapesFromPath pipeline so the\n// band gets the same lane assignment, loop topology and bezier shape as a real\n// read. A read band takes its source's palette; a haplotype band carries its\n// share of the haplotypes for the colorer to shade by.\n//\n// Synthetic-track ids live above this base so they don't collide with real\n// track ids and so click/hover handlers can show count info instead of the\n// per-read info dialog.\nconst COARSENED_ID_BASE = 1_000_000_000\nexport const isCoarsenedId = (id: number) => id >= COARSENED_ID_BASE\n\n// Build one synthetic read per (srcSigned \u2192 dstSigned) edge in `source`\n// (real reads, or the alt haplotype tracks). The synthetic reads replace the\n// real ones BEFORE placeReads runs, so:\n// \u2022 placeReads sees N_edges reads instead of N_reads (huge node-height win),\n// \u2022 each band gets a lane and an \"right-down-left-up-right\" loop topology\n// for free (placeReads handles reversals and out-of-order jumps),\n// \u2022 generateSVGShapesFromPath emits exactly one TrackCurve per band using\n// the same bezier as a real read \u2014 no special draw path needed.\n//\n// The synthetic track's `sequence` is just the two signed node names. After\n// generateTrackIndexSequences runs, indexSequence is set and the rest of the\n// layout follows.\nfunction buildCoarsenedSyntheticBands(\n state: LayoutState,\n source: Track[],\n unit: CoarsenedUnit,\n firstId = COARSENED_ID_BASE,\n): { bands: Track[]; total: number } {\n // Aggregate by signed-edge key. Preserve orientation so e.g. (+A\u2192+B) and\n // (-B\u2192-A) stack as separate bands \u2014 they're different visual flows.\n interface EdgeAgg {\n sSigned: number\n dSigned: number\n sName: string\n dName: string\n // distinct walks, so a walk that loops back over an edge, or crosses it\n // both ways under ignoreStrand, counts once\n count: number\n // every crossing, loops included, which is what sizes the band\n crossings: number\n sourceTrackID: number\n lastSource: number\n }\n const edges = new Map<number, EdgeAgg>()\n let total = 0\n // One number per signed edge: signed indices run from -span to span.\n const span = state.nodes.length\n const edgeKey = (s: number, d: number): number =>\n (s + span) * (2 * span + 1) + d + span\n // When ignoring strand, (+A\u2192+B) and (-B\u2192-A) refer to the same underlying\n // graph connection, so both collapse into the smaller of their two keys;\n // whichever orientation is seen first determines the visual band direction.\n const ignoreStrand = state.config.ignoreStrand\n for (const [sourceIndex, item] of source.entries()) {\n // a deduplicated walk stands for `freq` identical haplotypes\n const weight = Math.max(item.freq ?? 1, 1)\n total += weight\n const seq = item.indexSequence\n if (seq.length < 2) {\n continue\n }\n for (let i = 0; i < seq.length - 1; i += 1) {\n const sSigned = seq[i]!\n const dSigned = seq[i + 1]!\n const srcNode = state.nodes[Math.abs(sSigned)]!\n const dstNode = state.nodes[Math.abs(dSigned)]!\n const key = ignoreStrand\n ? Math.min(edgeKey(sSigned, dSigned), edgeKey(-dSigned, -sSigned))\n : edgeKey(sSigned, dSigned)\n const existing = edges.get(key)\n if (existing === undefined) {\n edges.set(key, {\n sSigned,\n dSigned,\n sName: sSigned < 0 ? `-${srcNode.name}` : srcNode.name,\n dName: dSigned < 0 ? `-${dstNode.name}` : dstNode.name,\n count: weight,\n crossings: weight,\n sourceTrackID: item.sourceTrackID,\n lastSource: sourceIndex,\n })\n } else {\n existing.crossings += weight\n if (existing.lastSource !== sourceIndex) {\n existing.count += weight\n existing.lastSource = sourceIndex\n }\n }\n }\n }\n\n // Square-root scaling on crossings gives heavy edges visible weight without\n // letting one massive edge dwarf everything else. Min stays near READ_WIDTH\n // so single-read edges still look like a normal read; max is generous so\n // hot edges read as obvious \"highways.\"\n let maxEdgeCount = 0\n for (const e of edges.values()) {\n if (e.crossings > maxEdgeCount) {\n maxEdgeCount = e.crossings\n }\n }\n const BAND_MIN_WIDTH = READ_WIDTH\n const BAND_MAX_WIDTH = 60\n const widthForCount = (c: number): number => {\n if (maxEdgeCount <= 1) {\n return BAND_MIN_WIDTH\n }\n return (\n BAND_MIN_WIDTH +\n (BAND_MAX_WIDTH - BAND_MIN_WIDTH) * Math.sqrt(c / maxEdgeCount)\n )\n }\n\n const synthetic: Track[] = []\n let i = 0\n for (const edge of edges.values()) {\n const id = firstId + i\n const share =\n unit === 'haplotype' ? { count: edge.count, total } : undefined\n const shareText = share === undefined ? '' : ` (${formatShare(share)})`\n const crossingsText =\n edge.crossings === edge.count\n ? ''\n : `, ${edge.crossings.toLocaleString()} crossings`\n const label = `${edge.count.toLocaleString()} ${unit}${edge.count === 1 ? '' : 's'}${shareText}${crossingsText}: Node ${edge.sName} \u2192 Node ${edge.dName}`\n state.coarsenedEdgeMeta.set(id, { count: edge.count, label })\n // Place each synthetic band so it touches *only* its endpoint nodes' edges:\n // \u2022 firstNodeOffset = src.sequenceLength \u2192 curve exits at src's right\n // pixel edge, no rectangle drawn inside src.\n // \u2022 finalNodeCoverLength = 0 \u2192 curve enters at dst's left pixel edge,\n // no rectangle drawn inside dst.\n // The crucial side effect is in placeReadSet's conflict check: at any\n // node B with an incoming edge (A\u2192B) and an outgoing edge (B\u2192C), the\n // incoming's finalNodeCoverLength=0 and the outgoing's firstNodeOffset=\n // B.length leave them with no horizontal overlap, so they share a single\n // lane. Node heights collapse from ~(N_in + N_out) lanes down to\n // ~max(N_in, N_out) lanes.\n //\n // Note: reverseReversedReads will swap firstNodeOffset/finalNodeCoverLength\n // for fully-reverse synthetics. The math works out: pre-flip values of\n // (srcLen, 0) become post-flip (newSrcLen, 0), which is the same pattern\n // \u2014 bands stay edge-only regardless of orientation.\n const srcLen = state.nodes[Math.abs(edge.sSigned)]!.sequenceLength\n synthetic.push({\n id,\n sourceTrackID: edge.sourceTrackID,\n type: 'read',\n // Human-readable so the name surfaces sensibly in any UI that uses it\n // (right-click \u2192 add to group, etc.) \u2014 and so trackTooltipText fallback\n // shows something meaningful.\n name: label,\n sequence: [edge.sName, edge.dName],\n indexSequence: [],\n path: [],\n // Pre-set width so placeReads / placeReadSet allocate the right vertical\n // space and assignReadsToNodes (patched to honor pre-set widths) leaves\n // it alone.\n width: widthForCount(edge.crossings),\n firstNodeOffset: srcLen,\n finalNodeCoverLength: 0,\n sequenceNew: [\n { nodeName: edge.sName, mismatches: [] },\n { nodeName: edge.dName, mismatches: [] },\n ],\n mapping_quality: 0,\n is_secondary: false,\n sample_name: null,\n read_group: null,\n score: edge.count,\n haplotypeShare: share,\n })\n i += 1\n }\n\n if (DEBUG) {\n let tallestName = '?'\n let tallestH = 0\n state.nodes.forEach(n => {\n if (n.contentHeight > tallestH) {\n tallestH = n.contentHeight\n tallestName = n.name\n }\n })\n debugLog(\n `[coarsened] ${unit}s_in=${source.length} edges_out=${synthetic.length} ` +\n `tallestNodeBeforePlace=${tallestName}(${tallestH.toFixed(1)})`,\n )\n }\n return { bands: synthetic, total }\n}\n\n// Band every haplotype but the reference, which keeps its lane and the ruler.\n// Undefined when no alternate crosses an edge: a haplotype that stays on one\n// node makes no band, and its node would get no y from the read overlay.\nfunction bandHaplotypes(\n state: LayoutState,\n firstId: number,\n): { ref: Track; bands: Track[]; total: number } | undefined {\n const rulerIndex =\n state.trackForRuler === undefined\n ? -1\n : state.tracks.findIndex(t => t.name === state.trackForRuler)\n const refIndex = rulerIndex === -1 ? 0 : rulerIndex\n const ref = state.tracks[refIndex]!\n // A deduplicated reference walk also stands for the haplotypes identical to\n // it through the window; those belong in the bands, not the reference lane.\n const refDuplicates = (ref.freq ?? 1) - 1\n const refSigns = firstVisitSigns(state, ref)\n const altHaplotypes = state.tracks\n .filter((_, i) => i !== refIndex)\n .map(walk => orientedLike(refSigns, walk))\n if (refDuplicates > 0) {\n altHaplotypes.push({ ...ref, freq: refDuplicates })\n }\n if (altHaplotypes.length === 0) {\n return undefined\n }\n const { bands, total } = buildCoarsenedSyntheticBands(\n state,\n altHaplotypes,\n 'haplotype',\n firstId,\n )\n return bands.length > 0 ? { ref, bands, total } : undefined\n}\n\n// A graph can store a walk in either orientation, so a haplotype can arrive\n// back to front relative to the reference. Banded that way, one allele splits\n// into a forward and a reverse band. Turn a walk around when it runs against\n// the reference on most of the nodes they share.\nfunction orientedLike(refSigns: Int8Array, walk: Track): Track {\n let agreement = 0\n for (const visit of walk.indexSequence) {\n const sign = refSigns[Math.abs(visit)]\n if (sign !== undefined && sign !== 0) {\n agreement += sign === Math.sign(visit) ? 1 : -1\n }\n }\n return agreement >= 0\n ? walk\n : {\n ...walk,\n sequence: walk.sequence.map(flip).reverse(),\n indexSequence: walk.indexSequence.map(visit => -visit).reverse(),\n }\n}\n\n// The sign of `ref`'s first visit to each node index, 0 where it never visits.\nfunction firstVisitSigns(state: LayoutState, ref: Track): Int8Array {\n const signs = new Int8Array(state.nodes.length)\n for (const visit of ref.indexSequence) {\n const node = Math.abs(visit)\n if (signs[node] === 0) {\n signs[node] = Math.sign(visit)\n }\n }\n return signs\n}\n\nfunction formatShare({ count, total }: HaplotypeShare): string {\n const share = count / total\n if (share < 0.01) {\n return '<1%'\n }\n if (share > 0.99 && count < total) {\n return '>99%'\n }\n return `${Math.round(share * 100)}%`\n}\n\nconst MIN_BEND_WIDTH = 7\n\n// Emit the vertical rectangles + rounded corners for a track turning around at\n// one end of an order slot. The two directions are mirror images of each other:\n// a forward-to-reverse turn bulges out to the right of the node and consumes an\n// `extraRight` slot, a reverse-to-forward turn bulges out to the left and\n// consumes an `extraLeft` slot. `dir` is +1 for right, -1 for left.\nfunction generateTurnaround(\n state: LayoutState,\n dir: 1 | -1,\n x: number,\n yStart: number,\n yEnd: number,\n trackWidth: number,\n trackID: number,\n order: number,\n type: TrackType | undefined,\n trackName: string | undefined,\n): void {\n const extra = dir === 1 ? state.extraRight : state.extraLeft\n const offset = 10 * extra[order]!\n // The turn's apex, and the outward direction from it.\n const apex = x + dir * (offset + 5)\n const radius = MIN_BEND_WIDTH\n const stem = Math.min(MIN_BEND_WIDTH, trackWidth)\n const yTop = Math.min(yStart, yEnd)\n const yBottom = Math.max(yStart, yEnd)\n // The incoming/outgoing stubs run from the node's edge out to the apex. The\n // one-pixel asymmetry between the two directions is carried over verbatim\n // from the original pair of functions.\n const stubNear = dir === 1 ? x : apex - 1\n const stubFar = dir === 1 ? apex : x\n\n const horizontal = (segTop: number): void => {\n state.shapes.verticalRectangles.push({\n xStart: stubNear,\n yStart: segTop,\n xEnd: stubFar,\n yEnd: segTop + trackWidth - 1,\n id: trackID,\n name: trackName,\n type,\n })\n }\n // elongate the incoming and outgoing rectangles a bit past the node\n horizontal(yStart)\n state.shapes.verticalRectangles.push({\n xStart: dir === 1 ? apex + radius : apex - radius - stem,\n yStart: yTop + trackWidth + radius - 1,\n xEnd: dir === 1 ? apex + radius + stem - 1 : apex - radius - 1,\n yEnd: yBottom - radius + 1,\n id: trackID,\n name: trackName,\n type,\n })\n horizontal(yEnd)\n\n const inner = apex + dir * radius\n const outer = apex + dir * (radius + stem)\n\n // bottom 90 degree bend\n let d = `M ${apex} ${yBottom}`\n d += ` Q ${inner} ${yBottom} ${inner} ${yBottom - radius}`\n d += ` H ${outer}`\n d += ` Q ${outer} ${yBottom + trackWidth} ${apex} ${yBottom + trackWidth}`\n d += ' Z '\n state.shapes.corners.push({ path: d, id: trackID, type })\n\n // top 90 degree bend\n d = `M ${apex} ${yTop}`\n d += ` Q ${outer} ${yTop} ${outer} ${yTop + trackWidth + radius}`\n d += ` H ${inner}`\n d += ` Q ${inner} ${yTop + trackWidth} ${apex} ${yTop + trackWidth}`\n d += ' Z '\n state.shapes.corners.push({ path: d, id: trackID, type })\n extra[order]! += 1\n}\n\n// The x extent of a node's bases: pixelWidth, plus about half a character\n// each side under nodeWidthOption 'normal'\nexport function nodePixelCoordinatesInX(node: Node): [number, number] {\n const nodeLeftX = node.x - 4\n const nodeRightX = node.x + node.pixelWidth + 4\n return [nodeLeftX, nodeRightX]\n}\n\n// calculate node widths depending on sequence lengths and chosen calculation method\nfunction generateNodeWidth(state: LayoutState): void {\n switch (state.config.nodeWidthOption) {\n case 'compressed':\n state.nodes.forEach(node => {\n node.width = 1 + Math.log2(Math.max(node.sequenceLength, 1))\n node.pixelWidth = Math.round((node.width - 1) * 8.401)\n })\n break\n case 'small':\n state.nodes.forEach(node => {\n node.width = node.sequenceLength / 100\n node.pixelWidth = Math.max(Math.round((node.width - 1) * 8.401), 0)\n })\n break\n case 'fixed':\n state.nodes.forEach(node => {\n node.width = 10\n node.pixelWidth = Math.round(node.width * 8.401)\n })\n break\n case 'normal': {\n // The label draws a base per character from x - 4, in a monospace font\n // whose character width the caller measures. pixelWidth runs from the\n // first character to the last, so the outline, 9 px wider each side,\n // holds the whole label, and nodePixelCoordinatesInX's half character\n // each side puts base i under letter i.\n const charWidth = state.config.charWidth\n state.nodes.forEach(node => {\n node.width = node.sequenceLength\n node.pixelWidth = Math.round(\n charWidth * Math.max(node.sequenceLength - 1, 0),\n )\n })\n break\n }\n default:\n throw new Error(`${state.config.nodeWidthOption} not implemented`)\n }\n}\n\n// A node's distinct neighbors on one side, kept only as far as mergeNodes\n// needs them: none, exactly one, or several. A neighbor is a signed node index,\n// or TRACK_END where a haplotype starts or stops.\ninterface Neighbors {\n first: Int32Array\n count: Uint8Array\n}\n\nconst TRACK_END = 0\n\nfunction noNeighbors(nodeCount: number): Neighbors {\n return { first: new Int32Array(nodeCount), count: new Uint8Array(nodeCount) }\n}\n\nfunction addNeighbor(\n neighbors: Neighbors,\n index: number,\n neighbor: number,\n): void {\n const count = neighbors.count[index]!\n if (count === 0) {\n neighbors.first[index] = neighbor\n neighbors.count[index] = 1\n } else if (count === 1 && neighbors.first[index] !== neighbor) {\n neighbors.count[index] = 2\n }\n}\n\n// The index of a node's one neighbor on this side, or 0 when it has none,\n// several, or a track end.\nfunction soleNeighbor(neighbors: Neighbors, index: number): number {\n return neighbors.count[index] === 1 ? Math.abs(neighbors.first[index]!) : 0\n}\n\n// remove redundant nodes\n// two nodes A and B can be merged if all tracks leaving A go directly into B\n// and all tracks entering B come directly from A\n// (plus no inversions involved)\nfunction mergeNodes(state: LayoutState): void {\n const pred = noNeighbors(state.nodes.length)\n const succ = noNeighbors(state.nodes.length)\n const signedIndexOf = new Map<string, number>()\n const visit = (nodeName: string): number => {\n let signed = signedIndexOf.get(nodeName)\n if (signed === undefined) {\n const index = state.nodeMap.get(forward(nodeName))!\n signed = isReverse(nodeName) ? -index : index\n signedIndexOf.set(nodeName, signed)\n }\n return signed\n }\n\n const tracksAndReads = state.tracks.concat(state.reads)\n\n // A reverse visit on either side adds both orientations of the neighbor, so\n // no merge happens across an inversion.\n tracksAndReads.forEach(track => {\n const { sequence } = track\n const isHaplotype = track.type === 'haplotype'\n const last = sequence.length - 1\n let previous = TRACK_END\n let current = last >= 0 ? visit(sequence[0]!) : TRACK_END\n for (let i = 0; i <= last; i += 1) {\n const next = i < last ? visit(sequence[i + 1]!) : TRACK_END\n if (current > 0) {\n if (i > 0) {\n addNeighbor(pred, current, previous)\n if (previous < 0) {\n addNeighbor(pred, current, -previous)\n }\n } else if (isHaplotype) {\n addNeighbor(pred, current, TRACK_END)\n }\n if (i < last) {\n addNeighbor(succ, current, next)\n if (next < 0) {\n addNeighbor(succ, current, -next)\n }\n } else if (isHaplotype) {\n addNeighbor(succ, current, TRACK_END)\n }\n } else {\n const index = -current\n if (i > 0) {\n addNeighbor(succ, index, -previous)\n if (previous > 0) {\n addNeighbor(succ, index, previous)\n }\n } else if (isHaplotype) {\n addNeighbor(succ, index, TRACK_END)\n }\n if (i < last) {\n addNeighbor(pred, index, -next)\n if (next > 0) {\n addNeighbor(pred, index, next)\n }\n } else if (isHaplotype) {\n addNeighbor(pred, index, TRACK_END)\n }\n }\n previous = current\n current = next\n }\n })\n\n const absorbed = new Uint8Array(state.nodes.length)\n state.nodes.forEach((_, i) => {\n if (mergeableWithPred(i, pred, succ) !== 0) {\n absorbed[i] = 1\n }\n })\n\n // Merge each run into its first node, noting the node every run member\n // merges into and where the member's bases start and end within it.\n const origin = new Int32Array(state.nodes.length)\n const start = new Float64Array(state.nodes.length)\n const end = new Float64Array(state.nodes.length)\n state.nodes.forEach((node, head) => {\n if (absorbed[head] === 1) {\n return\n }\n origin[head] = head\n end[head] = node.sequenceLength\n for (let donor = head; mergeableWithSucc(donor, pred, succ);) {\n donor = soleNeighbor(succ, donor)\n origin[donor] = head\n start[donor] = node.sequenceLength\n node.sequenceLength += state.nodes[donor]!.sequenceLength\n node.seq += state.nodes[donor]!.seq\n end[donor] = node.sequenceLength\n }\n })\n\n // A read's offsets and mismatch positions count along the strand it visits\n // a node on: from the left end of a forward visit, the right end of a\n // reverse one. A forward visit to an absorbed node folds into the visit\n // before it, a reverse one into the visit after it.\n state.reads.forEach(read => {\n const { sequence } = read\n const entries =\n read.sequenceNew ??\n sequence.map(nodeName => ({ nodeName, mismatches: [] as Mismatch[] }))\n const shift = (nodeName: string): number => {\n const index = Math.abs(visit(nodeName))\n return isReverse(nodeName)\n ? state.nodes[origin[index]!]!.sequenceLength - end[index]!\n : start[index]!\n }\n const last = sequence.length - 1\n read.firstNodeOffset = (read.firstNodeOffset ?? 0) + shift(sequence[0]!)\n read.finalNodeCoverLength =\n (read.finalNodeCoverLength ?? 0) + shift(sequence[last]!)\n\n const mergedSequence: string[] = []\n const mergedEntries: ReadSequenceEntry[] = []\n let carried: Mismatch[] = []\n sequence.forEach((nodeName, i) => {\n const index = Math.abs(visit(nodeName))\n const { mismatches } = entries[i]!\n const by = shift(nodeName)\n mismatches.forEach(mismatch => {\n mismatch.pos += by\n })\n if (absorbed[index] === 1 && !isReverse(nodeName) && i > 0) {\n mergedEntries.at(-1)!.mismatches.push(...mismatches)\n } else if (absorbed[index] === 1 && isReverse(nodeName) && i < last) {\n carried.push(...mismatches)\n } else {\n const name = state.nodes[origin[index]!]!.name\n const merged = isReverse(nodeName) ? reverse(name) : name\n mergedSequence.push(merged)\n mergedEntries.push({\n nodeName: merged,\n mismatches: carried.concat(mismatches),\n })\n carried = []\n }\n })\n read.sequence = mergedSequence\n if (read.sequenceNew !== undefined) {\n read.sequenceNew = mergedEntries\n }\n })\n\n state.tracks.forEach(track => {\n const { sequence } = track\n let kept = 0\n for (const nodeName of sequence) {\n if (absorbed[Math.abs(visit(nodeName))] === 0) {\n sequence[kept] = nodeName\n kept += 1\n }\n }\n sequence.length = kept\n })\n\n let kept = 1\n for (let i = 1; i < state.nodes.length; i += 1) {\n if (absorbed[i] === 0) {\n state.nodes[kept] = state.nodes[i]!\n kept += 1\n }\n }\n state.nodes.length = kept\n}\n\n// The index of the node `index` merges into, or 0 when it merges into none.\nfunction mergeableWithPred(\n index: number,\n pred: Neighbors,\n succ: Neighbors,\n): number {\n const predecessor = soleNeighbor(pred, index)\n return predecessor !== 0 && soleNeighbor(succ, predecessor) !== 0\n ? predecessor\n : 0\n}\n\nfunction mergeableWithSucc(\n index: number,\n pred: Neighbors,\n succ: Neighbors,\n): boolean {\n const successor = soleNeighbor(succ, index)\n return successor !== 0 && soleNeighbor(pred, successor) !== 0\n}\n", "// SVG path data for the shapes a layout leaves as coordinates: a curve's\n// ribbon and a node's rounded outline. Both are strings so the same geometry\n// draws as an SVG `d` attribute or, through Path2D, on a canvas, and\n// flattenPath turns either into points for a renderer that fills polygons.\nimport type { Node, TrackCurve, TrackType } from './types.ts'\n\nfunction groupBy<T, K>(items: readonly T[], key: (item: T) => K): Map<K, T[]> {\n const groups = new Map<K, T[]>()\n for (const item of items) {\n const k = key(item)\n const group = groups.get(k)\n if (group === undefined) {\n groups.set(k, [item])\n } else {\n group.push(item)\n }\n }\n return groups\n}\n\nfunction compareCurvesByXYStartValue(a: TrackCurve, b: TrackCurve): number {\n if (a.xStart < b.xStart) {\n return 1\n } else if (a.xStart > b.xStart) {\n return -1\n } else if (a.yStart > b.yStart) {\n return 1\n } else if (a.yStart < b.yStart) {\n return -1\n }\n return 0\n}\n\n// Where a curve leaves and enters: a node, or a gap at an order slot\nfunction curveEnds(curve: TrackCurve): [number, number, number, number] {\n return [\n curve.nodeStart ?? -1,\n curve.nodeEnd ?? -1,\n curve.nodeStart === null ? curve.orderStart : -1,\n curve.nodeEnd === null ? curve.orderEnd : -1,\n ]\n}\n\nfunction compareTuples(a: readonly number[], b: readonly number[]): number {\n for (let i = 0; i < a.length; i += 1) {\n const d = a[i]! - b[i]!\n if (d !== 0) {\n return d\n }\n }\n return 0\n}\n\n// Where a cubic with both control points at one x is steepest, it is 3/4 of\n// the way from the ends' mean x to that control x\nconst STEEP_SHARE = 0.75\n// The most of a gap a group's steep stretch may spread over, so its edges keep\n// some of the turn\nconst MAX_SPREAD = 0.8\n\n// How far apart, as shares of the gap, each curve of a group puts its top and\n// bottom edges' control points. A ribbon whose edges turn at one x is only as\n// thick across as its width times the cosine of its slope, which on a steep\n// lane change is a hairline; with its outer edge turning late and its inner\n// edge early, its steep stretch keeps its width, or as much as the gap allows.\n// A shallow curve needs none. The reference takes what it needs first, so its\n// line stays legible where a wide tube shares its gap. Groups of more than five\n// keep at least sequenceTubeMap's 0.4 in all, which stops their curves\n// crossing at one x.\nfunction spreads(group: readonly TrackCurve[], gapWidth: number) {\n const first = group[0]!\n const span = Math.min(Math.abs(first.xEnd - first.xStart), gapWidth)\n if (span === 0) {\n return group.map(() => 0)\n }\n const floor = group.length > 5 ? 0.4 / group.length : 0\n const wanted = group.map(c => {\n const rise = Math.abs(c.yEnd - c.yStart)\n const across =\n (rise / Math.hypot(rise, span)) *\n Math.min(c.width, MAX_SPREAD * STEEP_SHARE * span)\n return Math.max(floor, across / (STEEP_SHARE * span))\n })\n const sum = (pick: (c: TrackCurve) => boolean) =>\n wanted.reduce((total, w, i) => total + (pick(group[i]!) ? w : 0), 0)\n const reference = sum(c => c.reference === true)\n const others = sum(c => c.reference !== true)\n const referenceScale = reference > MAX_SPREAD ? MAX_SPREAD / reference : 1\n const room = MAX_SPREAD - reference * referenceScale\n const othersScale = others > room ? room / others : 1\n return wanted.map(\n (w, i) => w * (group[i]!.reference ? referenceScale : othersScale),\n )\n}\n\nexport interface CurvePathOptions {\n // The most px a gap between columns draws across, where the drawing squeezes\n // the layout's x, as a reference axis does; a curve's steepness is judged at\n // that width\n gapWidth?: number\n}\n\n// The curves of one track type in draw order, each with its `path` set. Curves\n// between the same pair of nodes, or gaps, form a group whose control points\n// fan out top to bottom, so a bundle of tracks changing lanes together stays\n// parallel rather than crossing at one x, and each curve's bottom edge is the\n// next one's top edge.\nexport function curvePaths(\n curves: readonly TrackCurve[],\n type: TrackType | undefined,\n { gapWidth = Infinity }: CurvePathOptions = {},\n): TrackCurve[] {\n const groupedCurves = groupBy(\n curves.filter(curve => curve.type === type),\n curve => curveEnds(curve).join(','),\n )\n\n groupedCurves.forEach(curveGroup => {\n curveGroup.sort(compareCurvesByXYStartValue)\n const spread = spreads(curveGroup, gapWidth)\n // share of the gap at which a boundary between the group's tubes turns,\n // for a curve that rises; one that falls turns at its complement\n let adjustValue = 0.5 - spread.reduce((sum, s) => sum + s, 0) / 2\n\n curveGroup.forEach((curve, i) => {\n const at = (share: number) =>\n curve.xStart +\n (curve.xEnd - curve.xStart) *\n (curve.yStart < curve.yEnd ? 1 - share : share)\n const xAdjusted = at(adjustValue)\n adjustValue += spread[i]!\n // the bottom edge, on the way back, parallel to the next curve's top\n const xNextAdjusted = at(adjustValue)\n let d = `M ${curve.xStart} ${curve.yStart}`\n d += ` C ${xAdjusted} ${curve.yStart} ${xAdjusted} ${curve.yEnd} ${curve.xEnd} ${curve.yEnd}`\n d += ` V ${curve.yEnd + curve.width}`\n d += ` C ${xNextAdjusted} ${curve.yEnd + curve.width} ${xNextAdjusted} ${\n curve.yStart + curve.width\n } ${curve.xStart} ${curve.yStart + curve.width}`\n d += ' Z'\n curve.path = d\n })\n })\n\n // One flat list ordered by group, then by the within-group sort\n return [...groupedCurves.values()]\n .sort((a, b) => compareTuples(curveEnds(a[0]!), curveEnds(b[0]!)))\n .flat()\n}\n\n// The outline that path data from curvePaths, nodeOutlinePath or a corner\n// traces, as points, for a renderer that fills polygons rather than paths.\n// Each B\u00E9zier becomes `steps` straight pieces; the closing Z adds no point.\nexport function flattenPath(d: string, steps = 16): [number, number][] {\n const tokens = d.match(/[A-Za-z]|-?(?:\\d+\\.?\\d*|\\.\\d+)(?:e[-+]?\\d+)?/g) ?? []\n const points: [number, number][] = []\n let x = 0\n let y = 0\n let i = 0\n const num = () => Number(tokens[i++])\n while (i < tokens.length) {\n const command = tokens[i++]\n if (command === 'M' || command === 'L') {\n x = num()\n y = num()\n points.push([x, y])\n } else if (command === 'H') {\n x = num()\n points.push([x, y])\n } else if (command === 'V') {\n y = num()\n points.push([x, y])\n } else if (command === 'C') {\n const [x1, y1, x2, y2, x3, y3] = [\n num(),\n num(),\n num(),\n num(),\n num(),\n num(),\n ]\n for (let s = 1; s <= steps; s += 1) {\n const t = s / steps\n const u = 1 - t\n const a = u * u * u\n const b = 3 * u * u * t\n const c = 3 * u * t * t\n const e = t * t * t\n points.push([\n a * x + b * x1 + c * x2 + e * x3,\n a * y + b * y1 + c * y2 + e * y3,\n ])\n }\n x = x3\n y = y3\n } else if (command === 'Q') {\n const [x1, y1, x2, y2] = [num(), num(), num(), num()]\n for (let s = 1; s <= steps; s += 1) {\n const t = s / steps\n const u = 1 - t\n points.push([\n u * u * x + 2 * u * t * x1 + t * t * x2,\n u * u * y + 2 * u * t * y1 + t * t * y2,\n ])\n }\n x = x2\n y = y2\n } else if (command !== 'Z') {\n throw new Error(`flattenPath: unsupported path command ${command}`)\n }\n }\n return points\n}\n\n// A node's outline: a rounded box 9 units outside the node's x extent and its\n// content height, the tracks through it inside.\nexport function nodeOutlinePath(node: Node): string {\n // top left arc\n let d = `M ${node.x - 9} ${node.y} Q ${node.x - 9} ${node.y - 9} ${\n node.x\n } ${node.y - 9}`\n let x = node.x\n let y = node.y - 9\n\n // top straight\n if (node.width > 1) {\n x += node.pixelWidth\n d += ` L ${x} ${y}`\n }\n\n // top right arc\n d += ` Q ${x + 9} ${y} ${x + 9} ${y + 9}`\n x += 9\n y += 9\n\n // right straight\n if (node.contentHeight > 0) {\n y += node.contentHeight\n d += ` L ${x} ${y}`\n }\n\n // bottom right arc\n d += ` Q ${x} ${y + 9} ${x - 9} ${y + 9}`\n x -= 9\n y += 9\n\n // bottom straight\n if (node.width > 1) {\n x -= node.pixelWidth\n d += ` L ${x} ${y}`\n }\n\n // bottom left arc\n d += ` Q ${x - 9} ${y} ${x - 9} ${y - 9}`\n x -= 9\n y -= 9\n\n // left straight\n if (node.contentHeight > 0) {\n y -= node.contentHeight\n d += ` L ${x} ${y}`\n }\n return d\n}\n", "// src/tubeMap/mismatches.ts\nimport { forward, getXCoordinateOfBaseWithinNode } from \"@jbrowse/tubemap-core\";\nfunction readMismatches(read, layout) {\n const marks = [];\n const entries = read.sequenceNew ?? [];\n const visits = read.path.filter((segment) => segment.node !== null);\n entries.forEach((entry, i) => {\n const nodeIndex = layout.nodeMap.get(forward(entry.nodeName));\n const node = nodeIndex === void 0 ? void 0 : layout.nodes[nodeIndex];\n const y = visits[i]?.y;\n if (node && y !== void 0) {\n const base = { readId: read.id, y, height: read.width };\n const at = (pos) => getXCoordinateOfBaseWithinNode(node, pos);\n for (const mm of entry.mismatches) {\n const x0 = at(mm.pos);\n if (x0 !== null) {\n if (mm.type === \"insertion\") {\n const softClip = i === 0 && mm.pos === read.firstNodeOffset || i === entries.length - 1 && mm.pos === read.finalNodeCoverLength;\n marks.push({\n ...base,\n kind: \"insertion\",\n x: x0,\n seq: mm.seq,\n softClip\n });\n } else if (mm.type === \"deletion\" && mm.length !== void 0) {\n const x1 = at(mm.pos + mm.length);\n if (x1 !== null) {\n marks.push({\n ...base,\n kind: \"deletion\",\n x0,\n x1,\n length: mm.length\n });\n }\n } else if (mm.type === \"substitution\" && mm.seq !== void 0) {\n const x1 = at(mm.pos + mm.seq.length);\n if (x1 !== null) {\n marks.push({ ...base, kind: \"substitution\", x0, x1, seq: mm.seq });\n }\n }\n }\n }\n }\n });\n return marks;\n}\nfunction tubeMapMismatches(layout) {\n return layout.reads.flatMap((read) => readMismatches(read, layout));\n}\n\nexport {\n tubeMapMismatches\n};\n", "// src/tubeMap/warp.ts\nvar MAX_GAP_PX = 24;\nvar MAX_GAP_SHARE = 0.5;\nvar isReal = (c) => c.bp1 > c.bp0;\nfunction referenceKnots(columns, bpToScreen) {\n const real = columns.filter(isReal);\n if (real.length === 0) {\n const first = columns[0];\n return first ? [{ tx: first.x0, sx: bpToScreen(first.bp0) }] : [];\n }\n const tx = [];\n const target = [];\n const gap = [];\n real.forEach((c, i) => {\n tx.push(c.x0, c.x1);\n target.push(bpToScreen(c.bp0), bpToScreen(c.bp1));\n gap.push(i === 0 ? 0 : Math.min(c.x0 - real[i - 1].x1, MAX_GAP_PX), 0);\n });\n const span = target.at(-1) - target[0];\n const demand = gap.reduce((a, b) => a + b, 0);\n const scale = demand > 0 ? Math.min(1, MAX_GAP_SHARE * span / demand) : 1;\n return spread(target, gap, scale).map((sx, k) => ({ tx: tx[k], sx }));\n}\nfunction spread(target, gap, scale) {\n const offset = [];\n let sum = 0;\n for (const g of gap) {\n sum += g * scale;\n offset.push(sum);\n }\n const blocks = [];\n target.forEach((t, k) => {\n let block = { mean: t - offset[k], n: 1 };\n let last = blocks.at(-1);\n while (last && last.mean >= block.mean) {\n blocks.pop();\n const n = last.n + block.n;\n block = { mean: (last.mean * last.n + block.mean * block.n) / n, n };\n last = blocks.at(-1);\n }\n blocks.push(block);\n });\n return blocks.flatMap((b) => Array(b.n).fill(b.mean)).map((q, k) => q + offset[k]);\n}\nfunction warpX(knots, tx) {\n const n = knots.length;\n if (n === 0) {\n return tx;\n }\n const first = knots[0];\n const last = knots[n - 1];\n if (tx <= first.tx) {\n return first.sx + (tx - first.tx);\n }\n if (tx >= last.tx) {\n return last.sx + (tx - last.tx);\n }\n let lo = 0;\n let hi = n - 1;\n while (hi - lo > 1) {\n const mid = lo + hi >> 1;\n if (knots[mid].tx <= tx) {\n lo = mid;\n } else {\n hi = mid;\n }\n }\n const a = knots[lo];\n const b = knots[hi];\n const span = b.tx - a.tx;\n return span > 0 ? a.sx + (tx - a.tx) / span * (b.sx - a.sx) : a.sx;\n}\n\nexport {\n MAX_GAP_PX,\n referenceKnots,\n warpX\n};\n", "import {\n tubeMapMismatches\n} from \"./chunk-XXT2JCAC.js\";\nimport {\n MAX_GAP_PX\n} from \"./chunk-HK5Y2YWV.js\";\nimport {\n readColor\n} from \"./chunk-CWFNEKST.js\";\nimport {\n pathOrigin\n} from \"./chunk-M6LK4GII.js\";\n\n// src/tubeMap/draw.ts\nimport { curvePaths, flattenPath, nodeOutlinePath } from \"@jbrowse/tubemap-core\";\nfunction parsePath(d) {\n const tokens = d.trim().split(/[\\s,]+/);\n const commands = [];\n let i = 0;\n const num = () => Number(tokens[i++]);\n while (i < tokens.length) {\n const op = tokens[i++];\n if (op === \"M\" || op === \"L\") {\n commands.push({ op, x: num(), y: num() });\n } else if (op === \"H\") {\n commands.push({ op, x: num() });\n } else if (op === \"V\") {\n commands.push({ op, y: num() });\n } else if (op === \"Q\") {\n commands.push({ op, x1: num(), y1: num(), x: num(), y: num() });\n } else if (op === \"C\") {\n commands.push({\n op,\n x1: num(),\n y1: num(),\n x2: num(),\n y2: num(),\n x: num(),\n y: num()\n });\n } else if (op === \"Z\") {\n commands.push({ op });\n }\n }\n return commands;\n}\nfunction extentOf(commands) {\n let x0 = Infinity;\n let x1 = -Infinity;\n for (const c of commands) {\n if (\"x\" in c) {\n x0 = Math.min(x0, c.x);\n x1 = Math.max(x1, c.x);\n }\n if (\"x1\" in c) {\n x0 = Math.min(x0, c.x1);\n x1 = Math.max(x1, c.x1);\n }\n }\n return { x0, x1 };\n}\nfunction shapeOf(d, color, id, haplotype, reference) {\n const commands = parsePath(d);\n return {\n commands,\n outline: flattenPath(d, 12),\n color,\n id,\n haplotype,\n reference,\n ...extentOf(commands)\n };\n}\nfunction trackColors(layout, pathColors) {\n return new Map(\n layout.tracks.map((track) => [\n track.id,\n track.type === \"read\" ? readColor(track) : pathColors[track.id]\n ])\n );\n}\nfunction layerOf(layout, type, colors, referenceIds, gapWidth) {\n const { shapes } = layout;\n const haplotype = type === \"haplotype\";\n const colorOf = (s) => colors.get(s.id);\n const isReference = (s) => haplotype && referenceIds.has(s.id);\n const rects = [...shapes.rectangles, ...shapes.verticalRectangles].filter((r) => r.type === type).map((r) => ({\n color: colorOf(r),\n id: r.id,\n haplotype,\n reference: isReference(r),\n x0: r.xStart,\n x1: r.xEnd + 1,\n y0: r.yStart,\n y1: r.yEnd + 1\n }));\n const curves = curvePaths(shapes.curves, type, { gapWidth }).map(\n (c) => shapeOf(c.path, colorOf(c), c.id, haplotype, isReference(c))\n );\n const corners = shapes.corners.filter((c) => c.type === type).map((c) => shapeOf(c.path, colorOf(c), c.id, haplotype, isReference(c)));\n return { rects, shapes: [...curves, ...corners] };\n}\nfunction referenceTrackIds(graph) {\n const ids = /* @__PURE__ */ new Set();\n graph?.paths?.forEach((path, i) => {\n if (pathOrigin(path.name).name === graph.referencePath) {\n ids.add(i);\n }\n });\n return ids;\n}\nfunction tubeMapPicture({\n layout,\n pathColors,\n graph,\n columns\n}) {\n const colors = trackColors(layout, pathColors);\n const referenceIds = referenceTrackIds(graph);\n const gapWidth = columns ? MAX_GAP_PX : void 0;\n const nodes = [];\n layout.nodes.forEach((node) => {\n if (node.order >= 0) {\n const commands = parsePath(nodeOutlinePath(node));\n nodes.push({ name: node.name, commands, ...extentOf(commands) });\n }\n });\n return {\n bounds: layout.bounds,\n layers: [\n layerOf(layout, \"haplotype\", colors, referenceIds, gapWidth),\n layerOf(layout, \"read\", colors, referenceIds, gapWidth)\n ],\n nodes,\n mismatches: tubeMapMismatches(layout).filter(\n (m) => m.kind !== \"insertion\" || !m.softClip\n )\n };\n}\nfunction trace(ctx, commands, x, y) {\n let cx = 0;\n let cy = 0;\n for (const c of commands) {\n switch (c.op) {\n case \"M\":\n cx = c.x;\n cy = c.y;\n ctx.moveTo(x(cx), y(cy));\n break;\n case \"L\":\n cx = c.x;\n cy = c.y;\n ctx.lineTo(x(cx), y(cy));\n break;\n case \"H\":\n cx = c.x;\n ctx.lineTo(x(cx), y(cy));\n break;\n case \"V\":\n cy = c.y;\n ctx.lineTo(x(cx), y(cy));\n break;\n case \"Q\":\n cx = c.x;\n cy = c.y;\n ctx.quadraticCurveTo(x(c.x1), y(c.y1), x(cx), y(cy));\n break;\n case \"C\":\n cx = c.x;\n cy = c.y;\n ctx.bezierCurveTo(x(c.x1), y(c.y1), x(c.x2), y(c.y2), x(cx), y(cy));\n break;\n case \"Z\":\n ctx.closePath();\n break;\n }\n }\n}\nfunction fillByColor(ctx, items, visible, colorOf, addTo) {\n const byColor = /* @__PURE__ */ new Map();\n for (const item of items) {\n if (visible(item)) {\n const color = colorOf(item);\n const list = byColor.get(color);\n if (list) {\n list.push(item);\n } else {\n byColor.set(color, [item]);\n }\n }\n }\n for (const list of byColor.values()) {\n ctx.fillStyle = colorOf(list[0]);\n ctx.beginPath();\n for (const item of list) {\n addTo(item);\n }\n ctx.fill();\n }\n}\nvar FULL_OUTLINE_PX = 12;\nvar MIN_OUTLINE_ALPHA = 0.15;\nfunction outlineAlpha(screenWidth) {\n return Math.max(MIN_OUTLINE_ALPHA, Math.min(1, screenWidth / FULL_OUTLINE_PX));\n}\nvar NODE_TINT_ALPHA = 0.55;\nfunction drawTubeMap(ctx, picture, frame) {\n const { x, y, width } = frame;\n const visible = (item) => x(item.x1) >= 0 && x(item.x0) <= width;\n const colorOf = (item) => item.haplotype && frame.tubeColors?.[item.id] || item.color;\n ctx.globalAlpha = 1;\n for (const layer of picture.layers) {\n for (const reference of [false, true]) {\n const inPass = (item) => item.reference === reference;\n fillByColor(\n ctx,\n layer.rects,\n (r) => inPass(r) && visible(r),\n colorOf,\n (r) => {\n const left = x(r.x0);\n const top = y(r.y0);\n ctx.rect(left, top, x(r.x1) - left, y(r.y1) - top);\n }\n );\n fillByColor(\n ctx,\n layer.shapes,\n (s) => inPass(s) && visible(s),\n colorOf,\n (s) => {\n trace(ctx, s.commands, x, y);\n }\n );\n }\n }\n const stroke = frame.darkMode ? \"#d0d0d0\" : \"#000000\";\n const fill = frame.darkMode ? \"rgba(40,40,40,0.4)\" : \"rgba(255,255,255,0.4)\";\n ctx.lineWidth = outlineWidth(frame);\n for (const node of picture.nodes) {\n if (visible(node) && node.name !== frame.highlightNode) {\n ctx.beginPath();\n trace(ctx, node.commands, x, y);\n const tint = frame.nodeColors?.get(node.name);\n ctx.fillStyle = tint ?? fill;\n ctx.strokeStyle = stroke;\n ctx.globalAlpha = tint ? NODE_TINT_ALPHA : 1;\n ctx.fill();\n ctx.globalAlpha = outlineAlpha(x(node.x1) - x(node.x0));\n ctx.stroke();\n ctx.globalAlpha = 1;\n }\n }\n drawTubeMapHighlight(ctx, picture, frame);\n drawMismatches(ctx, picture.mismatches, frame);\n}\nfunction outlineWidth(frame) {\n return 2 * Math.max(0.25, Math.min(1, frame.yScale));\n}\nfunction drawTubeMapHighlight(ctx, picture, frame) {\n const node = frame.highlightNode ? picture.nodes.find((n) => n.name === frame.highlightNode) : void 0;\n if (node) {\n ctx.beginPath();\n trace(ctx, node.commands, frame.x, frame.y);\n ctx.globalAlpha = 1;\n ctx.lineWidth = outlineWidth(frame);\n ctx.fillStyle = \"rgba(255,192,203,0.5)\";\n ctx.strokeStyle = \"#ff0000\";\n ctx.fill();\n ctx.stroke();\n }\n}\nvar MISMATCH_FONT_PX = 12;\nvar MIN_MISMATCH_FONT_PX = 6;\nfunction mismatchesLegible(yScale) {\n return MISMATCH_FONT_PX * yScale >= MIN_MISMATCH_FONT_PX;\n}\nfunction mismatchOnScreen(m, { x, width }) {\n const [x0, x1] = m.kind === \"insertion\" ? [m.x, m.x] : [m.x0, m.x1];\n return x(x1) >= 0 && x(x0) <= width;\n}\nfunction drawMismatches(ctx, marks, frame) {\n const { x, y, yScale, darkMode } = frame;\n if (!mismatchesLegible(yScale) || marks.length === 0) {\n return;\n }\n const fontPx = MISMATCH_FONT_PX * yScale;\n ctx.fillStyle = \"grey\";\n ctx.beginPath();\n for (const m of marks) {\n if (m.kind === \"deletion\" && mismatchOnScreen(m, frame)) {\n const left = x(m.x0);\n const top = y(m.y);\n ctx.rect(left, top, x(m.x1) - left, y(m.y + m.height) - top);\n }\n }\n ctx.fill();\n ctx.font = `${fontPx}px monospace`;\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"alphabetic\";\n ctx.fillStyle = darkMode ? \"#ffffff\" : \"#000000\";\n for (const m of marks) {\n if (!mismatchOnScreen(m, frame)) {\n continue;\n }\n if (m.kind === \"substitution\") {\n ctx.fillText(m.seq, x(m.x0) + 1, y(m.y + m.height));\n } else if (m.kind === \"insertion\") {\n ctx.fillText(\"*\", x(m.x) - 3, y(m.y + m.height));\n }\n }\n}\nfunction inside(points, sx, sy) {\n let hit = false;\n for (let i = 0, j = points.length - 1; i < points.length; j = i++) {\n const [xi, yi] = points[i];\n const [xj, yj] = points[j];\n if (yi > sy !== yj > sy && sx < (xj - xi) * (sy - yi) / (yj - yi) + xi) {\n hit = !hit;\n }\n }\n return hit;\n}\nfunction tubeMapTrackAt(picture, { x, y }, sx, sy) {\n for (let l = picture.layers.length - 1; l >= 0; l--) {\n const { rects, shapes } = picture.layers[l];\n for (const reference of [true, false]) {\n for (const r of rects) {\n if (r.reference === reference && x(r.x0) <= sx && sx <= x(r.x1) && y(r.y0) <= sy && sy <= y(r.y1)) {\n return r.id;\n }\n }\n for (const s of shapes) {\n if (s.reference === reference && x(s.x0) <= sx && sx <= x(s.x1) && inside(\n s.outline.map(([px, py]) => [x(px), y(py)]),\n sx,\n sy\n )) {\n return s.id;\n }\n }\n }\n }\n return void 0;\n}\nvar INSERTION_SLOP_PX = 4;\nfunction tubeMapMismatchAt(picture, frame, sx, sy) {\n const { x, y, yScale } = frame;\n return mismatchesLegible(yScale) ? picture.mismatches.find(\n (m) => y(m.y) <= sy && sy <= y(m.y + m.height) && (m.kind === \"insertion\" ? Math.abs(x(m.x) - sx) <= INSERTION_SLOP_PX : x(m.x0) <= sx && sx <= x(m.x1))\n ) : void 0;\n}\n\nexport {\n parsePath,\n trackColors,\n tubeMapPicture,\n drawTubeMap,\n drawTubeMapHighlight,\n mismatchesLegible,\n mismatchOnScreen,\n tubeMapTrackAt,\n tubeMapMismatchAt\n};\n", "const host = JBrowseExports[\"@jbrowse/core/util/groupKeys\"]\nconst read = name =>\n host != null && name in Object(host)\n ? host[name]\n : Object.assign(\n function () {\n throw new Error(\n \"This JBrowse does not provide '\" + name + \"' from '\" + \"@jbrowse/core/util/groupKeys\" + \"' to plugins: GraphGenomeView was built for a different JBrowse version, so update the plugin or JBrowse\",\n )\n },\n { jbrowseHostMissing: name },\n )\nexport const MAX_GROUPS = /* @__PURE__ */ read(\"MAX_GROUPS\")\nexport const OVERFLOW_GROUP_KEY = /* @__PURE__ */ read(\"OVERFLOW_GROUP_KEY\")\nexport const capGroupKeys = /* @__PURE__ */ read(\"capGroupKeys\")\nexport const carryGroupDomain = /* @__PURE__ */ read(\"carryGroupDomain\")\nexport const compareGroupKeys = /* @__PURE__ */ read(\"compareGroupKeys\")\nexport const groupKeyComparator = /* @__PURE__ */ read(\"groupKeyComparator\")\nexport const groupKeySpaceOf = /* @__PURE__ */ read(\"groupKeySpaceOf\")\nexport const overflowLabel = /* @__PURE__ */ read(\"overflowLabel\")\nexport const valueText = /* @__PURE__ */ read(\"valueText\")\nexport default host && host.__esModule ? host.default : host", "import { walkRowsTree } from '@jbrowse/bandage-core/layout/walkRowDraw'\nimport { groupKeyComparator } from '@jbrowse/core/util/groupKeys'\n\nimport type { El } from '@jbrowse/bandage-core/el'\nimport type {\n WalkRowsFrame,\n WalkRowsWithCalls,\n} from '@jbrowse/bandage-core/layout/walkRowDraw'\n\n// Walk rows stacked into one section per value of a sample table's column,\n// as jbrowse-plugin-tandem-repeat's \"Group by\u2026\" stacks its alleles. Placement\n// here, not in bandage-core's walkRowsTree, which puts row i at i * rowPx.\n\n// One row of a samples TSV: the sample's name and a value per column\nexport type SampleRow = { name: string } & Record<string, string>\n\nexport interface WalkRowGroupBy {\n field: string\n domain?: string[]\n}\n\nexport interface WalkRowSection {\n // '' for the rows with no value\n key: string\n title: string\n // index of the section's first row among the reference row and the rows\n first: number\n count: number\n}\n\nexport const SECTION_HEADER_PX = 16\n\n// A samples TSV as core's samplesTsv reads one: a header row, the sample's\n// name in the first column, the first row of a repeated name kept. Hosts\n// re-export that module only from v5.0.0-beta.11, so it is read here.\nexport function parseSamplesTsv(text: string): SampleRow[] {\n const [head = '', ...lines] = text.split(/\\r\\n|\\r|\\n/)\n const columns = head.split('\\t').slice(1)\n const rows = new Map<string, SampleRow>()\n for (const line of lines) {\n if (!line) {\n continue\n }\n const [name = '', ...values] = line.split('\\t')\n if (name && !rows.has(name)) {\n rows.set(name, {\n ...Object.fromEntries(columns.map((c, i) => [c, values[i] ?? ''])),\n name,\n })\n }\n }\n return [...rows.values()]\n}\n\nexport function metadataColumns(rows: SampleRow[] | undefined) {\n const columns = new Set<string>()\n for (const row of rows ?? []) {\n for (const key of Object.keys(row)) {\n if (key !== 'name') {\n columns.add(key)\n }\n }\n }\n return [...columns]\n}\n\n// The setting as a snapshot may hold it: a bare field name, or the object\nexport function groupByOf(value: unknown): WalkRowGroupBy | undefined {\n if (typeof value === 'string') {\n return value ? { field: value } : undefined\n }\n const { field, domain } = (value ?? {}) as Record<string, unknown>\n if (typeof field !== 'string' || !field) {\n return undefined\n }\n return Array.isArray(domain)\n ? { field, domain: domain.filter(d => typeof d === 'string') }\n : { field }\n}\n\nexport function plural(n: number, noun: string) {\n return `${n} ${noun}${n === 1 ? '' : 's'}`\n}\n\n// A walk's value in a column: its haplotype's row (`HG00097#1`), else its\n// sample's (`HG00097`), else ''\nexport function columnValueOf(field: string, table: SampleRow[]) {\n const valueOf = new Map(table.map(row => [row.name, row[field] ?? '']))\n return (haplotype: string, sample: string) =>\n valueOf.get(haplotype) || valueOf.get(sample) || ''\n}\n\n// Items grouped by their value in a column, each group in the order its items\n// came in, the groups in the order a JBrowse Group by sorts them, and each\n// titled with its value and how many distinct `noun`s its items are\nexport function groupsByColumn<T>(\n items: readonly T[],\n valueOf: (item: T) => string,\n { field, domain }: { field: string; domain?: readonly string[] },\n noun: string,\n nounOf: (item: T) => string,\n) {\n const groups = new Map<string, T[]>()\n for (const item of items) {\n const key = valueOf(item)\n const group = groups.get(key)\n if (group) {\n group.push(item)\n } else {\n groups.set(key, [item])\n }\n }\n return [...groups.keys()].sort(groupKeyComparator(domain)).map(key => {\n const members = groups.get(key)!\n const n = new Set(members.map(nounOf)).size\n return {\n key,\n members,\n title: `${key || `${field}: none`} \u00B7 ${plural(n, noun)}`,\n }\n })\n}\n\n// The rows reordered section by section; rows with no value stack last\nexport function groupWalkRows<R extends { sample: string; label: string }>(\n rows: R[],\n table: SampleRow[],\n groupBy: WalkRowGroupBy,\n) {\n const valueOf = columnValueOf(groupBy.field, table)\n const groups = groupsByColumn(\n rows,\n row => valueOf(row.label, row.sample),\n groupBy,\n 'haplotype',\n row => row.label,\n )\n let first = 1\n const sections: WalkRowSection[] = groups.map(({ key, members, title }) => {\n const section = { key, title, first, count: members.length }\n first += members.length\n return section\n })\n return {\n rows: groups.flatMap(g => g.members),\n sections,\n }\n}\n\n// Where rows and section headers sit, in px down from the reference row's\n// centre, at one row pitch shared by every section: a header strip above\n// each section's first row pushes every row after it down\nexport function sectionPlacement(sections: WalkRowSection[], rowPx: number) {\n const sectionOf = (i: number) => {\n let k = -1\n while (k + 1 < sections.length && sections[k + 1]!.first <= i) {\n k++\n }\n return k\n }\n const rowY = (i: number) => i * rowPx + (sectionOf(i) + 1) * SECTION_HEADER_PX\n return {\n rowY,\n headers: sections.map((s, k) => ({\n ...s,\n top: (s.first - 0.5) * rowPx + k * SECTION_HEADER_PX,\n })),\n headersPx: sections.length * SECTION_HEADER_PX,\n // the row whose centre is nearest y\n rowAt(y: number, rows: number) {\n let best = 0\n for (let k = -1; k < sections.length; k++) {\n const lo = k < 0 ? 0 : sections[k]!.first\n const hi =\n k < 0\n ? Math.min(rows, sections[0]?.first ?? rows)\n : lo + sections[k]!.count\n const shift = (k + 1) * SECTION_HEADER_PX\n const i = Math.min(\n hi - 1,\n Math.max(lo, Math.round((y - shift) / rowPx)),\n )\n if (Math.abs(rowY(i) - y) < Math.abs(rowY(best) - y)) {\n best = i\n }\n }\n return best\n },\n }\n}\n\n// The rows' trees, a section at a time while grouped. walkRowsTree puts its\n// i-th row at i * rowPx below its reference row and draws that row too, so\n// each section is drawn shifted down to its place with its reference row\n// dropped.\nexport function walkRowTrees(\n bars: WalkRowsWithCalls,\n sections: WalkRowSection[],\n rowY: (i: number) => number,\n frame: WalkRowsFrame & { rowPx: number },\n o: Parameters<typeof walkRowsTree>[2] & { idPrefix: string },\n): El[] {\n if (sections.length === 0) {\n return [walkRowsTree(bars, frame, o)]\n }\n return [\n walkRowsTree({ ...bars, rows: [] }, frame, o),\n ...sections.flatMap((section, k) => {\n const tree = walkRowsTree(\n {\n ...bars,\n rows: bars.rows.slice(\n section.first - 1,\n section.first - 1 + section.count,\n ),\n },\n {\n ...frame,\n translateY:\n frame.translateY +\n (rowY(section.first) - frame.rowPx) * frame.scaleY,\n },\n { ...o, idPrefix: `${o.idPrefix}-s${k}` },\n )\n return tree.children.filter(\n (c): c is El =>\n typeof c !== 'string' &&\n c.attrs['data-testid'] !== 'graph-walk-reference',\n )\n }),\n ]\n}\n", "import {\n buildNeighbors\n} from \"./chunk-ES2N6V56.js\";\nimport {\n REFERENCE_RANK,\n isAnchored\n} from \"./chunk-FYQWPEEY.js\";\n\n// src/alleleProjection/projectAlleles.ts\nfunction parsePanSN(refName) {\n const parts = refName.split(\"#\");\n const haplotype = parts.length >= 2 ? Number(parts[1]) : Number.NaN;\n return {\n sample: parts[0] ?? refName,\n haplotype: Number.isFinite(haplotype) ? haplotype : void 0\n };\n}\nfunction collectRun(seed, byId, adj, claimed) {\n const members = [];\n const anchors = [];\n const queue = [seed];\n claimed.add(seed);\n while (queue.length > 0) {\n const id = queue.pop();\n const node = byId.get(id);\n if (node) {\n members.push(node);\n for (const neighborId of adj.get(id) ?? []) {\n const neighbor = byId.get(neighborId);\n if (neighbor) {\n if (neighbor.stable.rank === REFERENCE_RANK) {\n anchors.push(neighbor);\n } else if (!claimed.has(neighborId)) {\n claimed.add(neighborId);\n queue.push(neighborId);\n }\n }\n }\n }\n }\n return { members, anchors };\n}\nfunction anchorSpan(anchors) {\n const refNames = new Set(anchors.map((a) => a.stable.refName));\n if (refNames.size !== 1 || anchors.length < 2) {\n return void 0;\n }\n const sorted = [...anchors].sort((a, b) => a.stable.start - b.stable.start);\n const first = sorted[0];\n const last = sorted.at(-1);\n const start = first.stable.start + first.length;\n const end = last.stable.start;\n return end >= start ? { start, end, entry: first } : void 0;\n}\nfunction runDistances(members, entry, adj) {\n const byId = new Map(members.map((m) => [m.id, m]));\n const dist = /* @__PURE__ */ new Map();\n const queue = [];\n for (const neighborId of adj.get(entry.id) ?? []) {\n if (byId.has(neighborId)) {\n dist.set(neighborId, 0);\n queue.push(neighborId);\n }\n }\n if (queue.length === 0) {\n for (const member of members) {\n dist.set(member.id, 0);\n queue.push(member.id);\n }\n }\n for (const id of queue) {\n const reach = dist.get(id) + byId.get(id).length;\n for (const neighborId of adj.get(id) ?? []) {\n if (byId.has(neighborId)) {\n const known = dist.get(neighborId);\n if (known === void 0 || reach < known) {\n dist.set(neighborId, reach);\n queue.push(neighborId);\n }\n }\n }\n }\n return dist;\n}\nfunction runOffsets(members, entry, adj) {\n const dist = runDistances(members, entry, adj);\n const ordered = [...members].sort((a, b) => dist.get(a.id) - dist.get(b.id));\n const rank = new Map(ordered.map((m, i) => [m.id, i]));\n const byId = new Map(members.map((m) => [m.id, m]));\n const offsets = /* @__PURE__ */ new Map();\n for (const [i, member] of ordered.entries()) {\n let offset = 0;\n for (const neighborId of adj.get(member.id) ?? []) {\n const neighbor = byId.get(neighborId);\n if (neighbor && rank.get(neighborId) < i) {\n offset = Math.max(offset, offsets.get(neighborId) + neighbor.length);\n }\n }\n offsets.set(member.id, offset);\n }\n return { offsets, ordered };\n}\nfunction projectAlleles(graph) {\n const byId = new Map(\n graph.nodes.filter(isAnchored).map((n) => [n.id, n])\n );\n const adj = buildNeighbors(graph);\n const claimed = /* @__PURE__ */ new Set();\n const alleles = [];\n for (const node of byId.values()) {\n if (node.stable.rank !== REFERENCE_RANK && !claimed.has(node.id)) {\n const { members, anchors } = collectRun(node.id, byId, adj, claimed);\n const span = anchorSpan(anchors);\n if (span) {\n const { offsets, ordered } = runOffsets(members, span.entry, adj);\n alleles.push({\n start: span.start,\n refSpan: span.end - span.start,\n nodeIds: ordered.map((m) => m.id),\n nodeOffsets: ordered.map((m) => offsets.get(m.id)),\n pathLength: ordered.reduce(\n (max, m) => Math.max(max, offsets.get(m.id) + m.length),\n 0\n )\n });\n }\n }\n }\n return alleles.sort((a, b) => a.start - b.start);\n}\n\nexport {\n parsePanSN,\n projectAlleles\n};\n", "import { parsePanSN } from '@jbrowse/bandage-core/alleleProjection/projectAlleles'\nimport { formatBp } from '@jbrowse/bandage-core/graphLabels'\nimport { pathOrigin } from '@jbrowse/bandage-core/pathAnchoring'\nimport { drawTubeMapHighlight } from '@jbrowse/bandage-core/tubeMap/draw'\nimport { groupKeyComparator } from '@jbrowse/core/util/groupKeys'\n\nimport { columnValueOf, groupsByColumn, plural } from './walkRowGroups'\n\nimport type { SampleRow } from './walkRowGroups'\nimport type { FacetBy } from '@jbrowse/bandage-core/facetGrid'\nimport type { TubeMapDrawing } from '@jbrowse/bandage-core/layout/tubeMapLayout'\nimport type { TubeMapPicture } from '@jbrowse/bandage-core/tubeMap/draw'\nimport type { TubeMapTransform } from '@jbrowse/bandage-core/tubeMap/frame'\nimport type { Graph, LayoutResult } from '@jbrowse/bandage-core/types'\n\n// A tube map split into small multiples: a panel per sample, or per walk, each\n// the reference and that group's walks laid out alone, stacked down the pane.\n// On the reference axis every panel's columns sit at their bp, so a box lines\n// up across the panels and with the linear view's tracks.\n\n// px above each panel, which its title takes\nexport const PANEL_GAP = 28\nexport const PANEL_REFERENCE_TUBE = '#4d4d4d'\nexport const PANEL_TUBE = '#5b8cc4'\nexport const PANEL_TUBES = [PANEL_TUBE, '#82abd9']\n// greys beside boxes tinted by the node scheme, so no tube shares a box's hue\nexport const TINTED_TUBES = ['#8c8c8c', '#adadad']\nexport const PANEL_TITLE_FONT = '12px sans-serif'\n\nexport const TUBE_MAP_PANELS: { field: '' | FacetBy; label: string }[] = [\n { field: '', label: 'None' },\n { field: 'sample', label: 'A panel per sample' },\n { field: 'walk', label: 'A panel per haplotype' },\n]\n\n// How the walks split: by sample or walk, the groups the domain names first\n// and the rest in the graph's order, or by a sample table column, its values\n// in the order a JBrowse Group by sorts them\nexport type TubeMapPanelSplit =\n | { by: FacetBy; domain?: readonly string[] }\n | { by: 'column'; field: string; table: SampleRow[]; domain?: string[] }\n\nexport interface TubeMapPanelGroup {\n key: string\n // the graph's own path names, pieces of one walk included\n paths: string[]\n // a column's value names a group of samples, and says how many\n label?: string\n}\n\nexport interface TubeMapPanel extends TubeMapPanelGroup {\n result: LayoutResult & { tubeMap: TubeMapDrawing }\n // where the panel's drawing starts down the stack, in tube px\n top: number\n height: number\n}\n\n// a pane's layout: a tube map split into panels carries them, and the stack's\n// extent and node positions in place of the whole map's\nexport type PaneLayout = LayoutResult & { tubeMapPanels?: TubeMapPanel[] }\n\nconst walkOf = (name: string) => pathOrigin(name).name\n\n// A tube coloured by its role where no key could name a hue per walk: the\n// reference charcoal and the haplotypes blue, or grey beside tinted boxes,\n// neighbours alternating two shades so each stays countable in a bundle\nexport function roleTubeColors(\n paths: readonly { name: string }[],\n reference: string | undefined,\n tubes = PANEL_TUBES,\n) {\n let haplotype = 0\n return paths.map(p =>\n walkOf(p.name) === reference\n ? PANEL_REFERENCE_TUBE\n : tubes[haplotype++ % tubes.length]!,\n )\n}\n\n// a categorical palette for a column's values, a hue each in sorted order\nconst VALUE_TUBES = [\n '#4e79a7',\n '#f28e2b',\n '#59a14f',\n '#e15759',\n '#b07aa1',\n '#76b7b2',\n '#edc948',\n '#9c755f',\n '#ff9da7',\n '#bab0ac',\n]\nexport const NO_VALUE_TUBE = '#c8c8c8'\n\n// Each of a column's values its hue, in the order a JBrowse Group by sorts\n// them; a value past the palette, or none, is grey\nexport function valueTubePalette(values: Iterable<string>) {\n const sorted = [...new Set(values)]\n .filter(v => v !== '')\n .sort(groupKeyComparator())\n return new Map(sorted.map((v, i) => [v, VALUE_TUBES[i] ?? NO_VALUE_TUBE]))\n}\n\n// The reference charcoal and each walk, or the bundle it stands for, in its\n// value's hue\nexport function valueTubeColors(\n paths: readonly { name: string; members?: string[] }[],\n reference: string | undefined,\n valueOf: (walk: string) => string,\n palette: ReadonlyMap<string, string>,\n) {\n return paths.map(p => {\n const walk = walkOf(p.name)\n return walk === reference\n ? PANEL_REFERENCE_TUBE\n : (palette.get(valueOf(p.members?.[0] ?? walk)) ?? NO_VALUE_TUBE)\n })\n}\n\n// A PanSN walk's value in a column\nexport function columnKeyOf(field: string, table: SampleRow[]) {\n const valueOf = columnValueOf(field, table)\n return (walk: string) => {\n const { sample, haplotype } = parsePanSN(walk)\n return valueOf(`${sample}#${haplotype}`, sample)\n }\n}\n\n// Each non-reference walk's group\nexport function tubeMapPanelGroups(\n graph: Graph,\n split: TubeMapPanelSplit,\n): TubeMapPanelGroup[] {\n const names = (graph.paths ?? [])\n .map(p => p.name)\n .filter(name => walkOf(name) !== graph.referencePath)\n if (split.by === 'column') {\n const keyOf = columnKeyOf(split.field, split.table)\n return groupsByColumn(\n names,\n name => keyOf(walkOf(name)),\n split,\n 'sample',\n name => parsePanSN(walkOf(name)).sample,\n ).map(({ key, members, title }) => ({ key, paths: members, label: title }))\n }\n const keyOf =\n split.by === 'sample'\n ? (walk: string) => parsePanSN(walk).sample\n : (walk: string) => walk\n const groups = new Map<string, string[]>()\n for (const name of names) {\n const key = keyOf(walkOf(name))\n const list = groups.get(key)\n if (list) {\n list.push(name)\n } else {\n groups.set(key, [name])\n }\n }\n const domain = split.domain ?? []\n const rank = new Map(domain.map((key, i) => [key, i]))\n const listed = (key: string) => rank.get(key) ?? domain.length\n return [...groups]\n .map(([key, paths], i) => ({ key, paths, i }))\n .sort((a, b) => listed(a.key) - listed(b.key) || a.i - b.i)\n .map(({ key, paths }) => ({ key, paths }))\n}\n\n// The box a panel draws a node of the laid graph in: the node itself, or the\n// merged run holding it\nexport function boxOf(drawing: TubeMapDrawing, node: string) {\n if (drawing.graph.nodes.some(n => n.id === node)) {\n return node\n }\n for (const [box, members] of drawing.members) {\n if (members.includes(node)) {\n return box\n }\n }\n return undefined\n}\n\n// The member of a merged run under pane x `sx`, a run drawn from `left` to\n// `right` across its members' bp, so a panel's count is of the bp the pointer\n// is on, not of the whole run. Undefined when no member has a span.\nexport function memberAt(\n members: readonly string[],\n spanOf: (id: string) => { start: number; end: number } | undefined,\n left: number,\n right: number,\n sx: number,\n) {\n const spans = members.flatMap(id => {\n const span = spanOf(id)\n return span ? [{ id, ...span }] : []\n })\n if (spans.length === 0) {\n return undefined\n }\n const start = Math.min(...spans.map(s => s.start))\n const end = Math.max(...spans.map(s => s.end))\n const share = right > left ? (sx - left) / (right - left) : 0\n const bp = start + Math.min(1, Math.max(0, share)) * (end - start)\n const distance = (s: { start: number; end: number }) =>\n bp < s.start ? s.start - bp : bp >= s.end ? bp - s.end + 1 : 0\n return spans.reduce((a, b) => (distance(b) < distance(a) ? b : a)).id\n}\n\n// How many of a panel's walks pass through `box`, of how many it holds, a\n// bundle counting each walk it stands for\nexport function walksThrough(graph: Graph, box: string) {\n const all = new Set<string>()\n const here = new Set<string>()\n for (const p of graph.paths ?? []) {\n const walk = walkOf(p.name)\n if (walk !== graph.referencePath) {\n for (const member of p.members ?? [walk]) {\n all.add(member)\n if (p.nodeIds.includes(box)) {\n here.add(member)\n }\n }\n }\n }\n return { here: here.size, of: all.size }\n}\n\nconst COUNT_FONT = 'bold 11px sans-serif'\nconst MIN_COUNT_RUN_PX = 80\nconst MIN_COUNT_TUBE_PX = 9\n\n// Each bundle's count on its tube, along every straight run wide and tall\n// enough to hold it, so the count stands where its route parts from others\nexport function drawBundleCounts(\n ctx: CanvasRenderingContext2D,\n picture: TubeMapPicture,\n graph: Graph,\n { x, y, width }: TubeMapTransform & { width: number },\n) {\n const paths = graph.paths ?? []\n if (!paths.some(p => p.members)) {\n return\n }\n const counts = new Map<number, number>()\n paths.forEach((p, i) => {\n if (walkOf(p.name) !== graph.referencePath) {\n counts.set(i, p.members?.length ?? 1)\n }\n })\n ctx.font = COUNT_FONT\n ctx.textAlign = 'left'\n ctx.textBaseline = 'middle'\n ctx.fillStyle = '#0b1f3a'\n for (const r of picture.layers[0]?.rects ?? []) {\n const n = counts.get(r.id)\n const left = Math.max(0, x(r.x0))\n const right = Math.min(width, x(r.x1))\n const top = y(r.y0)\n const bottom = y(r.y1)\n if (\n n !== undefined &&\n right - left >= MIN_COUNT_RUN_PX &&\n bottom - top >= MIN_COUNT_TUBE_PX\n ) {\n ctx.fillText(`\u00D7${n}`, left + 4, (top + bottom) / 2)\n }\n }\n}\n\nconst LENGTH_FONT = '10px sans-serif'\nconst MIN_LENGTH_LABEL_BP = 1000\n\n// Each box of a reference-axis map whose sequence the axis squeezes narrower\n// than its length's label, labelled beside it: off the reference a 33 kb\n// module draws a few px wide, as a SNP's box does. Boxes of one length\n// stacked in a column share a label, \"each\", at the lowest, where the stack\n// has room; a label that would overlap one already drawn is left out.\nexport function drawSqueezedLengths(\n ctx: CanvasRenderingContext2D,\n drawing: TubeMapDrawing,\n { x, y, width }: TubeMapTransform & { width: number },\n) {\n if (!drawing.columns) {\n return\n }\n const lengthOf = new Map(drawing.graph.nodes.map(n => [n.id, n.length]))\n ctx.font = LENGTH_FONT\n const stacks = new Map<\n string,\n { text: string; right: number; mid: number; count: number }\n >()\n // sparse, so forEach, which skips its holes\n drawing.layout.nodes.forEach(node => {\n const bp = lengthOf.get(node.name) ?? 0\n const left = x(node.x)\n const right = x(node.x + node.pixelWidth)\n const text = formatBp(bp)\n if (\n node.order >= 0 &&\n bp >= MIN_LENGTH_LABEL_BP &&\n right - left < ctx.measureText(text).width\n ) {\n const mid = (y(node.y) + y(node.y + node.contentHeight)) / 2\n const key = `${Math.round(right)}:${text}`\n const stack = stacks.get(key)\n if (stack) {\n stack.count++\n stack.mid = Math.max(stack.mid, mid)\n } else {\n stacks.set(key, { text, right, mid, count: 1 })\n }\n }\n })\n ctx.textAlign = 'left'\n ctx.textBaseline = 'middle'\n ctx.lineJoin = 'round'\n ctx.lineWidth = 3\n ctx.strokeStyle = 'rgba(255,255,255,0.9)'\n ctx.fillStyle = 'rgba(0,0,0,0.75)'\n const drawn: { x0: number; x1: number; y0: number; y1: number }[] = []\n for (const { text, right, mid, count } of stacks.values()) {\n const label = count > 1 ? `${text} each` : text\n const box = {\n x0: right + 3,\n x1: right + 3 + ctx.measureText(label).width,\n y0: mid - 6,\n y1: mid + 6,\n }\n if (\n box.x1 <= width &&\n !drawn.some(\n d => d.x0 < box.x1 && box.x0 < d.x1 && d.y0 < box.y1 && box.y0 < d.y1,\n )\n ) {\n drawn.push(box)\n ctx.strokeText(label, box.x0, mid)\n ctx.fillText(label, box.x0, mid)\n }\n }\n}\n\ninterface PanelOnScreen {\n picture: TubeMapPicture\n frame: TubeMapTransform\n label: string\n titleTop: number\n top: number\n}\n\n// The hovered box in each panel that draws it, and beside each title how many\n// of that panel's haplotypes pass through it. On the hover layer, so a hover\n// repaints no tube.\nexport function paintPanelHover(\n ctx: CanvasRenderingContext2D,\n panels: PanelOnScreen[],\n hover: ({ box: string; here: number; of: number } | undefined)[] | undefined,\n { width, lit }: { width: number; lit: boolean },\n) {\n panels.forEach((p, i) => {\n const hit = hover?.[i]\n if (!hit) {\n return\n }\n if (lit) {\n drawTubeMapHighlight(ctx, p.picture, {\n ...p.frame,\n width,\n highlightNode: hit.box,\n })\n }\n ctx.font = PANEL_TITLE_FONT\n ctx.textAlign = 'left'\n ctx.textBaseline = 'top'\n ctx.fillStyle = '#c00000'\n ctx.fillText(\n ` \u00B7 ${hit.here} of ${plural(hit.of, 'haplotype')} here`,\n 6 + ctx.measureText(p.label).width,\n p.titleTop + 4,\n )\n })\n}\n\n// The reference and `paths` alone: the nodes they visit and the links between\n// them, without reads, which name no sample\nexport function graphOfPaths(graph: Graph, paths: readonly string[]): Graph {\n const kept = new Set(paths)\n const keptPaths = (graph.paths ?? []).filter(\n p => kept.has(p.name) || walkOf(p.name) === graph.referencePath,\n )\n const walks = new Set(keptPaths.map(p => walkOf(p.name)))\n const nodeIds = new Set(keptPaths.flatMap(p => p.nodeIds))\n const nodes = graph.nodes.filter(n => nodeIds.has(n.id))\n const names = new Set(nodes.map(n => n.name))\n const pathVisits = graph.pathVisits?.filter(\n path => walks.has(path),\n segment => names.has(segment),\n )\n return {\n ...graph,\n nodes,\n edges: graph.edges.filter(e => nodeIds.has(e.from) && nodeIds.has(e.to)),\n paths: keptPaths,\n anchorPaths: graph.anchorPaths?.filter(p => walks.has(p.name)),\n pathVisits,\n reads: undefined,\n }\n}\n\n// `whole` with each group's own tube map stacked in its place, a title's gap\n// above each, or `whole` alone when fewer than two groups draw\nexport function withTubeMapPanels(\n whole: LayoutResult,\n laidOut: (TubeMapPanelGroup & { result: LayoutResult | undefined })[],\n): PaneLayout {\n const panels: TubeMapPanel[] = []\n const nodePositions: LayoutResult['nodePositions'] = {}\n let y = 0\n let minX = Infinity\n let maxX = -Infinity\n for (const { key, paths, label, result } of laidOut) {\n const tubeMap = result?.tubeMap\n const extent = result?.extent\n if (tubeMap && extent) {\n const top = y + PANEL_GAP\n const height = (extent.maxY ?? 0) - (extent.minY ?? 0)\n panels.push({\n key,\n paths,\n label,\n result: { ...result, tubeMap },\n top,\n height,\n })\n const dy = top - (extent.minY ?? 0)\n for (const [id, segments] of Object.entries(result.nodePositions)) {\n nodePositions[id] = segments.map(s => ({ x: s.x, y: s.y + dy }))\n }\n y = top + height\n minX = Math.min(minX, extent.minX ?? minX)\n maxX = Math.max(maxX, extent.maxX ?? maxX)\n }\n }\n return panels.length > 1\n ? {\n ...whole,\n nodePositions,\n extent: {\n ...(minX <= maxX ? { minX, maxX } : {}),\n minY: 0,\n maxY: y,\n },\n tubeMapPanels: panels,\n }\n : whole\n}\n", "import {\n el\n} from \"./chunk-H2H4Y3TV.js\";\n\n// src/genes/exonOutline.ts\nvar EXON_COLOR = \"#daa520\";\nvar EXON_GAP_PX = 1;\nvar EXON_LINE_PX = 2;\nvar MIN_LANE_PX = 4;\nfunction exonStretches(pins, halfWidthPx, lift, pathOf = (d) => d) {\n const inkPx = (nodeId) => {\n const own = halfWidthPx(nodeId) * 2;\n return lift?.nodeIds.has(nodeId) ? Math.max(own, lift.walks.length * MIN_LANE_PX) : own;\n };\n return pins.flatMap(\n (pin) => pin.exonsByNode.map(({ nodeId, d }) => ({\n key: `${pin.gene.name}-${pin.gene.start}-${nodeId}`,\n d: pathOf(d),\n inner: inkPx(nodeId) + 2 * EXON_GAP_PX\n }))\n );\n}\nfunction exonOutlineTree(stretches, o) {\n if (stretches.length === 0) {\n return void 0;\n }\n const stroke = (s, color, width) => el(\"path\", {\n d: s.d,\n fill: \"none\",\n stroke: color,\n \"stroke-width\": width,\n \"stroke-linecap\": \"round\",\n \"stroke-linejoin\": \"round\",\n \"vector-effect\": o.transform ? \"non-scaling-stroke\" : void 0\n });\n return el(\n \"g\",\n {},\n el(\n \"mask\",\n {\n id: o.id,\n maskUnits: \"userSpaceOnUse\",\n x: 0,\n y: 0,\n width: o.width,\n height: o.height\n },\n el(\n \"g\",\n { transform: o.transform },\n ...stretches.map((s) => stroke(s, \"#fff\", s.inner + 2 * EXON_LINE_PX)),\n ...stretches.map((s) => stroke(s, \"#000\", s.inner))\n )\n ),\n el(\"rect\", {\n width: o.width,\n height: o.height,\n fill: EXON_COLOR,\n mask: `url(#${o.id})`\n })\n );\n}\n\nexport {\n EXON_COLOR,\n exonStretches,\n exonOutlineTree\n};\n", "import {\n formatBp,\n groupDigits\n} from \"./chunk-PTABFYQ7.js\";\n\n// src/walkKey.ts\nfunction rangeText(contig, start, end) {\n const s = Math.round(start);\n const e = Math.round(end);\n return `${contig ? `${contig}:` : \"\"}${groupDigits(s)}-${groupDigits(e)} (${formatBp(e - s)})`;\n}\nfunction walkKey(walk, reference) {\n const { field } = walk.encoding;\n const own = walk.range ? rangeText(walk.range.contig, walk.range.start, walk.range.end) : void 0;\n const scale = field === \"progress\" ? own : field === \"reference\" && reference ? rangeText(reference.name, reference.start, reference.end) : void 0;\n const spanned = walk.range ? walk.range.end - walk.range.start : walk.bp;\n const outside = spanned - walk.bp;\n return {\n delta: walk.referenceBp === void 0 || spanned === walk.referenceBp ? \"\" : ` ${spanned > walk.referenceBp ? \"+\" : \"\\u2212\"}${formatBp(Math.abs(spanned - walk.referenceBp))}`,\n outside: outside > 0 ? `, ${formatBp(outside)} outside the cut` : \"\",\n reversed: walk.reversedBp > 0 ? `, ${formatBp(walk.reversedBp)} reversed` : \"\",\n shades: field !== \"walk\",\n scale,\n hover: scale === own ? void 0 : own\n };\n}\nfunction walkPosition(walk, nodeId, length) {\n const progress = walk.progress.get(nodeId);\n const range = walk.range;\n if (progress === void 0 || !range) {\n return void 0;\n }\n const start = Math.round(\n range.start + progress * (range.end - range.start) - length / 2\n );\n return `${range.contig}:${groupDigits(start)}-${groupDigits(start + length)}`;\n}\n\nexport {\n rangeText,\n walkKey,\n walkPosition\n};\n", "import {\n tubeSpan\n} from \"./chunk-XMW266WS.js\";\n\n// src/tubeMap/genes.ts\nfunction tubeMapGenes(byRefName, genes) {\n const out = [];\n for (const gene of genes) {\n const boxes = byRefName.get(gene.refName);\n const first = boxes?.[0];\n const last = boxes?.at(-1);\n if (!boxes || !first || !last) {\n continue;\n }\n const start = Math.max(gene.start, first.bp0);\n const end = Math.min(gene.end, last.bp1);\n if (end <= start) {\n continue;\n }\n out.push({\n gene,\n ...tubeSpan(boxes, start, end),\n exons: gene.exons.filter((e) => e.end > start && e.start < end).map(\n (e) => tubeSpan(boxes, Math.max(e.start, start), Math.min(e.end, end))\n )\n });\n }\n return out;\n}\nvar GENE_ROW_PX = 22;\nvar MAX_GENE_ROWS = 4;\nvar EXON_PX = 8;\nvar NAME_FONT = \"11px sans-serif\";\nvar NAME_GAP_PX = 8;\nfunction tubeMapGeneRows(genes) {\n const edges = genes.flatMap((g) => [\n { x: g.x0, step: 1 },\n { x: g.x1, step: -1 }\n ]).sort((a, b) => a.x - b.x || a.step - b.step);\n let depth = 0;\n let most = 0;\n for (const { step } of edges) {\n depth += step;\n most = Math.max(most, depth);\n }\n return Math.min(MAX_GENE_ROWS, most);\n}\nfunction drawTubeMapGenes(ctx, genes, frame, bottom, top = 0) {\n const { x, width, darkMode } = frame;\n const rows = Math.max(1, Math.floor((bottom - top) / GENE_ROW_PX));\n const rowEnds = [];\n const ink = darkMode ? \"#e0e0e6\" : \"#1c1c22\";\n ctx.font = NAME_FONT;\n ctx.textAlign = \"center\";\n ctx.textBaseline = \"alphabetic\";\n ctx.fillStyle = ink;\n ctx.strokeStyle = ink;\n ctx.lineWidth = 1;\n const placed = genes.map((g) => ({ g, s0: x(g.x0), s1: x(g.x1) })).filter(({ s0, s1 }) => s1 >= 0 && s0 <= width).sort((a, b) => a.s0 - b.s0);\n for (const { g, s0, s1 } of placed) {\n const arrow = g.gene.strand > 0 ? \" \\u2192\" : g.gene.strand < 0 ? \"\\u2190 \" : \"\";\n const label = g.gene.strand < 0 ? `${arrow}${g.gene.name}` : `${g.gene.name}${arrow}`;\n const mid = (Math.max(s0, 0) + Math.min(s1, width)) / 2;\n const half = ctx.measureText(label).width / 2;\n const left = Math.min(s0, mid - half);\n const right = Math.max(s1, mid + half);\n let row = rowEnds.findIndex((end) => end + NAME_GAP_PX <= left);\n if (row === -1) {\n row = Math.min(rowEnds.length, rows - 1);\n }\n rowEnds[row] = Math.max(rowEnds[row] ?? -Infinity, right);\n const glyphY = bottom - row * GENE_ROW_PX - EXON_PX / 2;\n ctx.beginPath();\n ctx.moveTo(s0, glyphY + 0.5);\n ctx.lineTo(s1, glyphY + 0.5);\n ctx.stroke();\n for (const e of g.exons) {\n const e0 = x(e.x0);\n ctx.fillRect(e0, glyphY - EXON_PX / 2, Math.max(1, x(e.x1) - e0), EXON_PX);\n }\n ctx.fillText(label, mid, glyphY - EXON_PX / 2 - 2);\n }\n}\n\nexport {\n tubeMapGenes,\n GENE_ROW_PX,\n tubeMapGeneRows,\n drawTubeMapGenes\n};\n", "import {\n LIFT_BACKDROP_CSS,\n computeColorSchemeRange,\n getNodeColor\n} from \"./chunk-A4PFFC4Q.js\";\nimport {\n abgrToCssRgba\n} from \"./chunk-G2FD7S3C.js\";\nimport {\n isBackbone\n} from \"./chunk-FYQWPEEY.js\";\n\n// src/referenceStrip.ts\nvar REFERENCE_STRIP_PX = 12;\nvar REFERENCE_STRIP_ZONE_PX = REFERENCE_STRIP_PX + 8;\nvar OVERHANG_PX = 8;\nvar OVERHANG_CAP_PX = OVERHANG_PX + 3;\nvar MIN_STAGGER_PX = 12;\nfunction referenceStripBlocks(graph, {\n colorScheme,\n referenceRamp,\n walks\n}) {\n const range = { ...computeColorSchemeRange(graph), referenceRamp };\n const out = [];\n graph.nodes.forEach((node, index) => {\n if (isBackbone(node)) {\n const colors = walks ? walks.map((w) => {\n const lane = w.colors.get(node.id);\n return lane === void 0 ? LIFT_BACKDROP_CSS : abgrToCssRgba(lane);\n }) : [abgrToCssRgba(getNodeColor(node, index, colorScheme, range))];\n out.push({\n node: node.id,\n bp0: node.stable.start,\n bp1: node.stable.start + node.length,\n colors,\n faded: colors.includes(LIFT_BACKDROP_CSS)\n });\n }\n });\n return out.sort((a, b) => a.bp0 - b.bp0);\n}\nfunction span(frame, bp0, bp1) {\n const a = bp0 * frame.scale + frame.translateX;\n const b = bp1 * frame.scale + frame.translateX;\n return a < b ? [a, b] : [b, a];\n}\nvar HIT_SLOP_PX = 2;\nfunction stripOverhang(blocks, frame, width) {\n const a = -frame.translateX / frame.scale;\n const b = (width - frame.translateX) / frame.scale;\n const lo = Math.min(a, b);\n const hi = Math.max(a, b);\n let below = 0;\n let above = 0;\n for (const block of blocks) {\n below += Math.max(0, Math.min(block.bp1, lo) - block.bp0);\n above += Math.max(0, block.bp1 - Math.max(block.bp0, hi));\n }\n return frame.scale >= 0 ? { left: Math.round(below), right: Math.round(above) } : { left: Math.round(above), right: Math.round(below) };\n}\nfunction stripBlockAt(blocks, frame, sx, sy) {\n if (sy < 0 || sy > REFERENCE_STRIP_PX + HIT_SLOP_PX) {\n return void 0;\n }\n let hit;\n let best = HIT_SLOP_PX;\n for (const b of blocks) {\n const [x0, x1] = span(frame, b.bp0, b.bp1);\n const dist = Math.max(0, x0 - sx, sx - x1);\n if (dist <= best) {\n best = dist;\n hit = b.node;\n }\n }\n return hit;\n}\nfunction nodeAnchor(segments, toScreen) {\n const p = segments?.[Math.floor(segments.length / 2)];\n return p ? toScreen(p) : void 0;\n}\nfunction stripPixels(blocks, frame, width, dpr) {\n const placed = blocks.map((b) => {\n const [x0, x1] = span(frame, b.bp0, b.bp1);\n const px0 = Math.round(x0 * dpr);\n return {\n colors: b.colors,\n x0,\n px0,\n px1: Math.max(Math.round(x1 * dpr), px0 + 1)\n };\n }).filter((b) => b.px1 > 0 && b.px0 < width * dpr).sort((a, b) => a.x0 - b.x0);\n const out = [];\n let claimed = -Infinity;\n const tierEnds = [-Infinity, -Infinity];\n for (const { colors, px0, px1 } of placed) {\n const start = Math.max(px0, claimed);\n if (px1 > start) {\n const tier = tierEnds[0] < start ? 0 : 1;\n tierEnds[tier] = px1;\n out.push({ colors, x0: start / dpr, x1: px1 / dpr, tier });\n claimed = px1;\n }\n }\n const covered = out.length > 0 ? out.at(-1).x1 - out[0].x0 : 0;\n return covered >= out.length * MIN_STAGGER_PX ? out : out.map(({ tier: _, ...b }) => b);\n}\nfunction drawOverhang(ctx, edgeX, inward, ink) {\n const capX = inward > 0 ? edgeX : edgeX - OVERHANG_CAP_PX;\n ctx.clearRect(capX, 0, OVERHANG_CAP_PX, REFERENCE_STRIP_PX);\n const tipX = edgeX + inward;\n const baseX = tipX + inward * OVERHANG_PX;\n ctx.beginPath();\n ctx.moveTo(tipX, REFERENCE_STRIP_PX / 2);\n ctx.lineTo(baseX, 0);\n ctx.lineTo(baseX, REFERENCE_STRIP_PX);\n ctx.closePath();\n ctx.fillStyle = ink;\n ctx.fill();\n}\nfunction rowEdge(row, rows, dpr) {\n return Math.round(row * REFERENCE_STRIP_PX * dpr / rows) / dpr;\n}\nfunction drawReferenceStrip(ctx, blocks, frame, {\n width,\n lit,\n darkMode,\n dpr = 1\n}) {\n const ink = darkMode ? \"#ffffff\" : \"#18181c\";\n ctx.clearRect(0, 0, width, REFERENCE_STRIP_ZONE_PX);\n for (const b of stripPixels(blocks, frame, width, dpr)) {\n const { tier } = b;\n const staggered = tier !== void 0 && b.colors.length === 1;\n const rows = staggered ? 2 : b.colors.length;\n b.colors.forEach((color, i) => {\n const row = staggered ? tier : i;\n const y0 = rowEdge(row, rows, dpr);\n ctx.fillStyle = color;\n ctx.fillRect(b.x0, y0, b.x1 - b.x0, rowEdge(row + 1, rows, dpr) - y0);\n });\n }\n const overhang = stripOverhang(blocks, frame, width);\n if (overhang.left > 0) {\n drawOverhang(ctx, 0, 1, ink);\n }\n if (overhang.right > 0) {\n drawOverhang(ctx, width, -1, ink);\n }\n if (lit) {\n const [x0, x1] = span(frame, lit.start, lit.end);\n const w = Math.max(x1 - x0, 3);\n const left = (x0 + x1) / 2 - w / 2;\n ctx.strokeStyle = ink;\n ctx.lineWidth = 1.5;\n ctx.strokeRect(left, 0.75, w, REFERENCE_STRIP_PX - 1.5);\n if (lit.anchor) {\n ctx.beginPath();\n ctx.moveTo(left + w / 2, REFERENCE_STRIP_PX);\n ctx.lineTo(lit.anchor.x, lit.anchor.y);\n ctx.lineWidth = 1;\n ctx.stroke();\n }\n }\n}\n\nexport {\n REFERENCE_STRIP_PX,\n REFERENCE_STRIP_ZONE_PX,\n referenceStripBlocks,\n stripOverhang,\n stripBlockAt,\n nodeAnchor,\n stripPixels,\n drawReferenceStrip\n};\n", "import type { RepeatCall } from './repeatFeatures'\n\n// Which genotyped allele belongs to which haplotype walk. A VCF states a\n// sample's alleles in genotype order, which is the genotyper's own order and\n// carries no correspondence to the assembly's haplotype numbering \u2014 TRGTdb's\n// ABCA7 record, for one, lists them shortest first. So the walks and the\n// alleles are paired by length instead: the pairing whose total difference is\n// smallest, which for lengths on a line is the non-crossing one.\n//\n// A walk that does not reach both flanking reference nodes is measured whole\n// rather than across the array, and an allele no read spanned is a copy of the\n// one that was called. Neither states a length for this array, so they pair\n// last and take no verdict \u2014 pairing them first let a walk that stops inside\n// the array take the allele that fit one spanning it, and the spanning walk\n// then read as a disagreement.\n\ninterface WalkCall extends RepeatCall {\n // undefined where the walk and the allele are not both measurements\n agrees?: boolean\n}\n\n// Every walk/call pair over the 94 HPRC samples TRGT genotyped at the ABCA7\n// VNTR is either within 8% of its allele or more than 14% from it, so any\n// threshold across that gap separates them the same way.\nexport const CALL_TOLERANCE = 0.1\n\nfunction agrees(walkBp: number, callBp: number) {\n return Math.abs(callBp - walkBp) <= CALL_TOLERANCE * Math.max(walkBp, callBp)\n}\n\n// Pair two ascending lists of lengths, leaving out the surplus of whichever is\n// longer. `out[i]` is the index in `calls` that `walks[i]` took.\nfunction nearest(walks: number[], calls: number[]) {\n const W = walks.length\n const C = calls.length\n const cost = Array.from({ length: W + 1 }, () => new Array(C + 1).fill(0))\n const paired = Array.from({ length: W + 1 }, () =>\n new Array<boolean>(C + 1).fill(false),\n )\n for (let i = W - 1; i >= 0; i--) {\n for (let j = C - 1; j >= 0; j--) {\n const together = Math.abs(walks[i]! - calls[j]!) + cost[i + 1]![j + 1]!\n const dropWalk = W - i > C - j ? cost[i + 1]![j]! : Infinity\n const dropCall = C - j > W - i ? cost[i]![j + 1]! : Infinity\n cost[i]![j] = Math.min(together, dropWalk, dropCall)\n paired[i]![j] = cost[i]![j] === together\n }\n }\n const out = new Array<number | undefined>(W).fill(undefined)\n for (let i = 0, j = 0; i < W && j < C;) {\n if (paired[i]![j]) {\n out[i++] = j++\n } else if (W - i > C - j) {\n i++\n } else {\n j++\n }\n }\n return out\n}\n\nfunction byLength<T>(items: T[], bp: (item: T) => number) {\n return items\n .map((item, i) => ({ item, i }))\n .sort((a, b) => bp(a.item) - bp(b.item))\n}\n\nconst backed = (call: RepeatCall) => call.spanningReads !== 0\n\nfunction scored(row: { bp: number; complete: boolean }, call: RepeatCall) {\n return {\n ...call,\n agrees: row.complete && backed(call) ? agrees(row.bp, call.bp) : undefined,\n }\n}\n\n// A phased genotype names its walk's haplotype outright, though a contig\n// break can give that haplotype two walks. Within a haplotype, and among the\n// unphased alleles, pairing goes by length: the walks that span the array\n// against the alleles reads spanned, then everything else against what those\n// two left. That decides the ambiguous cases on merit: which walk takes the\n// one allele a lone spanning read supports, and which allele a walk that stops\n// inside the array is drawn against.\nfunction pairSample<\n R extends { bp: number; complete: boolean; haplotype?: number },\n>(rows: R[], calls: RepeatCall[]) {\n const out = new Map<number, WalkCall>()\n const taken = new Set<RepeatCall>()\n const ranked = byLength(rows, r => r.bp)\n const pair = (pool: typeof ranked, group: RepeatCall[]) => {\n const stages = [\n [pool.filter(r => r.item.complete), group.filter(backed)],\n [pool, group],\n ] as const\n for (const [walks, alleles] of stages) {\n const free = walks.filter(r => !out.has(r.i))\n const open = byLength(\n alleles.filter(call => !taken.has(call)),\n call => call.bp,\n )\n nearest(\n free.map(r => r.item.bp),\n open.map(c => c.item.bp),\n ).forEach((pick, k) => {\n if (pick !== undefined) {\n const row = free[k]!\n const call = open[pick]!.item\n taken.add(call)\n out.set(row.i, scored(row.item, call))\n }\n })\n }\n }\n for (const haplotype of new Set(calls.flatMap(c => c.haplotype ?? []))) {\n pair(\n ranked.filter(r => r.item.haplotype === haplotype),\n calls.filter(c => c.haplotype === haplotype),\n )\n }\n pair(\n ranked,\n calls.filter(c => c.haplotype === undefined),\n )\n return out\n}\n\nexport function withCalls<\n R extends {\n sample: string\n bp: number\n complete: boolean\n haplotype?: number\n },\n>(rows: R[], calls: Record<string, RepeatCall[]> | undefined) {\n if (!calls) {\n return rows as (R & { call?: WalkCall })[]\n }\n const paired = new Map<R, WalkCall>()\n const bySample = new Map<string, R[]>()\n for (const row of rows) {\n const group = bySample.get(row.sample)\n if (group) {\n group.push(row)\n } else {\n bySample.set(row.sample, [row])\n }\n }\n for (const [sample, group] of bySample) {\n const called = calls[sample]\n if (called) {\n for (const [i, call] of pairSample(group, called)) {\n paired.set(group[i]!, call)\n }\n }\n }\n return rows.map(row => ({ ...row, call: paired.get(row) }))\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["FACET_GAP_PX", "FACET_TITLE_PX", "FACET_PAD_PX", "MIN_FACET_PANEL_PX", "facetGrid", "count", "bounds", "pixelRows", "width", "room", "columns", "tile", "across", "rows", "panelWidth", "panelRoom", "fitX", "fitY", "scale", "drawn", "height", "best", "grid", "FACET_FIELDS", "facetSettingOf", "facet", "raw", "domainFirst", "names", "domain", "rank", "name", "i", "listed", "a", "b", "facetCells", "by", "wrapOrder", "wrap", "places", "sample", "haplotype", "contig", "n", "p", "cells", "referenceBoxes", "graph", "layout", "nodeById", "n", "byRefName", "node", "index", "graphNode", "isBackbone", "refName", "start", "boxes", "a", "b", "tubeX", "bp", "isEnd", "lo", "hi", "mid", "bp1", "box", "span", "tubeSpan", "end", "rulerBoxes", "best", "TICK_PX", "LABEL_GAP_PX", "TARGET_TICK_PX", "MIN_BRACKET_PX", "rulerInk", "darkMode", "niceStep", "raw", "pow", "m", "placeLabels", "candidates", "placed", "text", "at", "scaleMarks", "x", "width", "measure", "first", "last", "from", "to", "bpSpan", "step", "ticks", "positions", "sx", "boxMarks", "shown", "s0", "s1", "label", "position", "spans", "lengths", "boundaries", "length", "formatBp", "ends", "rulerMarks", "referenceAxis", "drawTubeMapRuler", "ctx", "frame", "top", "marks", "ink", "y", "x0", "x1", "n", "v", "paint", "css", "m", "opacity", "paintAttrs", "kind", "color", "DOT_PX", "DOT_CELL_PX", "svgCanvas", "width", "height", "out", "subpaths", "start", "x", "y", "s", "reach", "points", "i", "pathData", "dots", "seen", "cell", "ctx", "cx0", "cy0", "cx1", "cy1", "d", "w", "h", "canvas", "MAX_DPR", "MAX_CANVAS_DIM_PX", "getDpr", "width", "height", "dpr", "syncCanvasSize", "canvas", "pw", "ph", "cssWidth", "cssHeight", "Canvas2DRenderer", "canvas", "ctx", "_handler", "width", "height", "syncCanvasSize", "getDpr", "batch", "factors", "edgeIndex", "factor", "transform", "k", "clearColor", "normalizedRgbToCssRgba", "edgeRun", "color", "items", "groupByPaint", "e", "i", "inRun", "brightenAbgr", "lifted", "s", "f", "arrowRun", "a", "curves", "runItems", "arrows", "runs", "nodeId", "run", "t", "abgrToCssRgba", "first", "c", "p0", "l", "p", "tip", "left", "notch", "right", "arrowheadOutline", "ARROW_NOTCH", "ux", "uy", "tipX", "tipY", "length", "halfWidth", "backX", "backY", "notchBack", "paintOf", "groups", "deferred", "item", "weight", "last", "into", "key", "group", "FALLBACK_CELL_SIZE", "meanExtentCellSize", "extentTotal", "count", "rowPitchOf", "boxes", "distinct", "min", "max", "box", "cellSizeFrom", "extentX", "extentY", "x", "resolveCellSize", "given", "getOrCreateCell", "cells", "cx", "cy", "row", "cell", "addToGrid", "cellSize", "minX", "minY", "maxX", "maxY", "entry", "cx0", "cx1", "cy0", "cy1", "queryGrid", "y", "radiusX", "radiusY", "results", "seen", "SpatialIndex", "nodePositions", "nodeId", "segments", "i", "seg", "next", "b", "EdgeSpatialIndex", "graph", "drawPaths", "axis", "deletions", "version", "routes", "stranded", "baseEdgeCurves", "ei", "edge", "fromSegments", "toSegments", "curves", "curveBounds", "numPaths", "padX", "padY", "o", "pathRibbonOffsets", "distanceToSegment", "px", "py", "x1", "y1", "x2", "y2", "dx", "dy", "lenSq", "t", "distanceToCubicBezier", "cx1", "cy1", "cx2", "cy2", "minDist", "samples", "lastX", "lastY", "i", "u", "bx", "by", "distanceToBezierCurve", "c", "distanceToEdgeCurves", "curves", "yToX", "d", "nodeCache", "getSpatialIndex", "nodePositions", "version", "cached", "index", "SpatialIndex", "edgeCache", "getEdgeSpatialIndex", "graph", "drawPaths", "axis", "deletions", "routes", "stranded", "EdgeSpatialIndex", "MIN_NODE_REACH_PX", "findHoveredNode", "graphX", "graphY", "ink", "yToXOf", "reach", "queryReach", "candidates", "hovered", "best", "nodeId", "segmentIdx", "segments", "dist", "segmentMeetsBox", "a", "b", "box", "t0", "t1", "p", "q", "nodesUnderBox", "screen", "hits", "line", "findHoveredEdge", "hiddenEdges", "deletionRoutes", "edgeThreshold", "edgeIndex", "edgeIdx", "edge", "fromSegments", "toSegments", "numPaths", "baseCurves", "offset", "pathRibbonOffsets", "translateCurves", "HALO_FACTOR", "LEGEND_INSET_PX", "GENE_PIN_DROP_PX", "GENE_STACK", "BUBBLE_STACK", "TOPMOST_BASELINE", "LABEL_PX", "LABEL_PAD", "geneCoverageNote", "pin", "length", "per", "unit", "amount", "bp", "geneLabelCandidates", "pins", "screen", "contigThickness", "nodesUnder", "ink", "byExtent", "x", "y", "note", "box", "id", "items", "extent", "a", "b", "layoutLabels", "m", "width", "height", "translateX", "translateY", "scaleX", "scaleY", "frame", "p", "reserved", "label", "rowLabelBox", "stripPx", "LABEL_CHAR_PX", "take", "occupancy", "onRows", "rowsTop", "r", "halo", "above", "h", "gap", "baseline", "byBubble", "bubbles", "placeLabels", "ticks", "t", "genes", "nodesUnderBox", "sizeCandidates", "sizeLabelCandidates", "deletionLabels", "placeSizeLabels", "nodeLabels", "nodeLabelBudget", "host", "read", "name", "autorun", "read", "computed", "read", "reaction", "read", "untracked", "read", "mobx_default", "host", "canonicalStrand", "node", "stepName", "strand", "stepStarts", "lengths", "total", "starts", "head", "i", "tail", "j", "mismatchesByStep", "record", "byStep", "known", "start", "s", "startOf", "k", "endOf", "first", "stepAt", "pos2", "atEnd", "end", "unplacedFrom", "add", "mismatch", "list", "last", "pos", "op", "parseCs", "at", "left", "take", "tubeMapReads", "graph", "records", "firstId", "nodeByName", "n", "reads", "nodes", "step", "kept", "mismatches", "names", "lastLength", "FORWARD_READ_COLORS", "REVERSE_READ_COLORS", "readColor", "read", "colors", "rampHueCss", "hue", "rampHue", "bp", "domain", "frac", "REFERENCE_RAMP_MAX_HUE", "HUE_STOP_DEG", "rampStops", "start", "reversed", "low", "high", "n", "_", "RAMP_GRADIENT_STOPS", "i", "RAMP_GRADIENT_CSS", "s", "el", "tag", "attrs", "children", "c", "escapeText", "s", "escapeAttr", "serializeEl", "node", "v", "k", "ON_REFERENCE", "OFF_REFERENCE", "OUTSIDE_CUT", "GENE_INK", "BAR_PX", "GAP_PX", "LABELLED_ROW_PX", "MIN_TILED_BAR_PX", "MIN_TILE_PX", "kb", "bp", "signedLength", "delta", "size", "units", "unit", "walkRowReadout", "row", "reference", "call", "gapBp", "complete", "stop", "outside", "called", "against", "region", "why", "readoutPlacement", "text", "endX", "width", "x", "LABEL_CHAR_PX", "unitTicks", "pxPerBp", "ticks", "k", "runPaint", "run", "ramp", "REFERENCE_RAMP_ALT_CSS", "stops", "rampStops", "rampHueCss", "alongRow", "axis", "start", "end", "rowSpan", "placeRowGenes", "rows", "byRow", "placed", "row", "genes", "axis", "clip", "start", "end", "g", "alongRow", "e", "a", "b", "GENE_FONT_PX", "GENE_CHAR_PX", "MIN_LETTERED_BAR_PX", "genePad", "rowPx", "barPx", "boxesGenes", "rowGeneBoxes", "X", "y", "ROW_HEIGHT_PX", "BAR_PX", "pad", "boxes", "x", "taken", "named", "w", "half", "at", "box", "rowsText", "n", "walkRowsKey", "bars", "o", "entries", "RAMP_GRADIENT_CSS", "ON_REFERENCE", "REFERENCE_RAMP_ALT_CSS", "OFF_REFERENCE", "OUTSIDE_CUT", "CALL_TICK", "UNBACKED_TICK", "DISAGREES", "callTickInk", "call", "walkRowsKeyTree", "idPrefix", "parts", "i", "rampId", "ramp", "el", "RAMP_GRADIENT_STOPS", "s", "swatch", "GENE_INK", "GAP_PX", "text", "LABEL_CHAR_PX", "p", "rowPitch", "count", "room", "minRowPx", "fit", "LABELLED_ROW_PX", "coalesceRuns", "runs", "pxPerBp", "minBp", "out", "bucket", "flush", "on", "off", "r", "onReference", "lead", "held", "run", "geneTree", "walkRowsTree", "frame", "bp", "overhang", "Y", "origin", "unit", "reference", "along", "offset", "prefix", "rowTree", "paint", "runPaint", "h", "id", "rect", "color", "k", "ticks", "MIN_TILED_BAR_PX", "unitTicks", "walkRowReadout", "readoutPlacement", "readouts", "REPEAT_GROWTH", "coveringRepeat", "b", "repeats", "span", "growth", "SUPERBUBBLE_SEGMENTS", "formatBpRange", "shortest", "longest", "low", "formatBp", "high", "unit", "routes", "count", "SATURATED_PATH_COUNT", "classifyBubble", "c", "classifyShape", "refSpan", "pathCount", "segmentCount", "inversion", "range", "sameLength", "repeat", "name", "alleles", "bp", "BUBBLE_KIND_COLORS", "BUBBLE_KIND_NAMES", "bubbleSegmentIds", "tubeMapConnectors", "boxes", "bpToScreen", "tubeToScreen", "width", "out", "box", "bottom0", "bottom1", "HIT_SLOP_PX", "connectorAt", "connectors", "zoneBottom", "sx", "sy", "t", "hit", "best", "a", "b", "dist", "band", "ctx", "c", "bottom", "sides", "drawTubeMapConnectors", "highlightNode", "darkMode", "ink", "drawLitConnector", "node", "lit", "boxAt", "boxes", "bp", "visited", "lo", "hi", "mid", "box", "deviationMarks", "drawing", "deviations", "layout", "referenceBoxes", "a", "b", "marks", "track", "devs", "segment", "d", "bp0", "bp1", "x0", "x1", "index", "at", "deviationInk", "darkMode", "drawDeviationMarks", "ctx", "x", "y", "width", "m", "left", "right", "top", "emptyTrackShapes", "NOT_SAMPLES", "parsePanSN", "name", "sample", "haplotype", "contig", "DEBUG", "debugLog", "args", "READ_FACET_FIELDS", "FACET_FIELDS", "layersFrom", "layers", "coarsenedReadView", "showReads", "hasReads", "coarsen", "stat", "banded", "statOf", "data", "layer", "configFrom", "options", "emptyState", "config", "emptyTrackShapes", "layoutTubeMap", "inputNodes", "inputTracks", "inputReads", "topology", "layoutTopology", "placeTubeMap", "measurements", "arrangeTopology", "everything", "place", "node", "i", "placeSubset", "selectTracks", "selectReads", "tracks", "reads", "bandIdBase", "measured", "state", "read", "t", "straightenTrack", "generateNodeMap", "generateTrackIndexSequences", "generateNodeWidth", "generateNodeSuccessors", "generateNodeOrder", "reverseReversedReads", "mergeNodes", "generateNodeDegree", "switchNodeOrientation", "getMaxOrder", "mappingQualityCutoff", "focusReadNames", "facet", "focus", "facetHoldsRead", "references", "track", "kept", "sampleOf", "parsePanSN", "place", "topology", "tracks", "reads", "x", "bandIdBase", "state", "emptyState", "node", "i", "track", "read", "layers", "ignoreStrand", "haplotypeBandIdBase", "COARSENED_ID_BASE", "haplotypeBands", "statOf", "bandHaplotypes", "calculateTrackWidth", "generateLaneAssignment", "generateReadOnlyNodeAttributes", "readBands", "buildCoarsenedSyntheticBands", "coarsened", "data", "unit", "banding", "reverseReversedReads", "generateTrackIndexSequences", "b", "placeReads", "generateNodeXCoords", "generateSVGShapesFromPath", "debugLog", "getImageDimensions", "isReverse", "nodeName", "forward", "reverse", "flip", "isForwardIndex", "n", "straightenTrack", "index", "nodesToInvert", "visitedForward", "visit", "sequence", "j", "getReverseComplement", "orderY", "setMapToMax", "step", "map", "key", "value", "existing", "READ_WIDTH", "assignReadsToNodes", "idx", "firstNode", "element", "pathIdx", "elemNode", "basicPath", "sortedNodes", "compareNodesByOrder", "sets", "layer", "source", "set", "orderedSets", "a", "topMargin", "placeReadSet", "bottomY", "calculateBottomY", "elementsWithoutNode", "len", "prevSegment", "lastValidPrev", "seg", "nextSegment", "firstValidNext", "previousVisitToNode", "nextVisitToNode", "betweenCycleReverseTraversal", "compareNoNodeReads", "segment", "toPlace", "incomingReads", "readID", "outgoingReads", "internalReads", "startY", "incomingKeys", "entry", "path", "decisionStep", "foundY", "k", "y", "compareIncomingReadKeys", "currentY", "occupiedUntil", "readElement", "setOccupiedUntil", "maxY", "compareReadOutgoingSegmentsByGoingTo", "occupiedFrom", "firstNodeOffset", "occUntil", "incReadElementIndices", "incRead", "incReadPathElement", "compareInternalReads", "readIdx", "currentRead", "finalNodeCoverLength", "heightIncrease", "adjustVertically3", "pathIndex", "readA", "readB", "segmentA", "segmentB", "prevNodeA", "prevNodeB", "aPrev", "bPrev", "aReverse", "bReverse", "readIndexA", "pathIndexA", "readIndexB", "pathIndexB", "previousValidYA", "previousValidYB", "lastPathIndexA", "lastPathIndexB", "initialNodeA", "initialNodeB", "nodeA", "nodeB", "nextNodeIdx", "beginDiff", "compareTrackByInitialOrdering", "trackA", "trackB", "pathA", "pathB", "AIndex", "BIndex", "trackAOrder", "trackBOrder", "idxA", "idxB", "aFirst", "bFirst", "aLast", "bLast", "pass", "order", "isForward", "currentNodeIndex", "currentNodeIsForward", "currentNode", "previousNode", "previousNodeIsForward", "pos", "sequenceNew", "reverseMismatches", "nodeByName", "temp", "firstLen", "lastLen", "mismatches", "sequenceLength", "mm", "mirroredMismatch", "span", "COMPLEMENT", "s", "result", "tracksOrReads", "signedIndexOf", "signed", "NODE_HORIZONTAL_SLACK", "bounds", "rectangles", "verticalRectangles", "curves", "shapes", "xStart", "xEnd", "generateNodeMap", "nodeMap", "generateNodeSuccessors", "successorSets", "predecessorSets", "addEdges", "current", "follower", "generateNodeOrderOfSingleTrack", "forwardOrder", "backwardOrder", "minOrder", "nodeIndex", "increaseOrderForAllNodes", "generateNodeOrderTrackBeginning", "anchorIndex", "anchorSeqVal", "currentOrder", "increment", "UNREACHABLE_ORDER", "fillUnassignedOrders", "orders", "filled", "generateNodeOrder", "modifiedSequence", "rightIndex", "leftIndex", "tracksAndReads", "reachability", "uninvert", "increaseOrderForSuccessors", "isSuccessor", "finalOrders", "first", "second", "scratch", "stamp", "generation", "stack", "childIndex", "getMaxOrder", "max", "v", "amount", "startingNode", "tabuNode", "newOrder", "increasedOrders", "queue", "head", "currentNodeOrder", "successor", "predecessor", "generateNodeDegree", "switchNodeOrientation", "switchNodeOrientationForPaths", "paths", "pivotPath", "scores", "onPivot", "indexSequence", "last", "prevOrder", "nextOrder", "vote", "currentX", "nextX", "extra", "calculateExtraSpace", "RISE_KNEE", "riseExtra", "rise", "leftSideEdges", "rightSideEdges", "fallAngleAdjustment", "prevSeg", "prevSegmentPerOrderPerTrack", "assignmentByOrderAndNode", "trackNo", "segmentNumber", "addToAssignment", "generateSingleLaneAssignment", "segmentID", "assignment", "getIdealLanesAndCoords", "currentLane", "potentialAdjustmentValues", "prevNameIsNull", "prevTrack", "compareByIdealLane", "adjustVertically", "verticalAdjustment", "minAdjustmentCost", "moveBy", "cost", "getVerticalAdjustmentCost", "adjustBy", "assignmentNode", "aNode", "allAreFour", "NARROW_WIDTH", "WIDE_WIDTH", "getReadXStart", "offset", "clampedXCoordinateOfBaseWithinNode", "getReadXEnd", "cover", "getXCoordinateOfBaseWithinNode", "base", "nodeLeftX", "nodeRightX", "nodePixelCoordinatesInX", "clamped", "yStart", "yEnd", "orderStartX", "orderEndX", "reference", "generateTurnaround", "buildCoarsenedSyntheticBands", "state", "source", "unit", "firstId", "COARSENED_ID_BASE", "edges", "total", "span", "edgeKey", "s", "d", "ignoreStrand", "sourceIndex", "item", "weight", "seq", "i", "sSigned", "dSigned", "srcNode", "dstNode", "key", "existing", "maxEdgeCount", "e", "BAND_MIN_WIDTH", "READ_WIDTH", "BAND_MAX_WIDTH", "widthForCount", "c", "synthetic", "edge", "id", "share", "shareText", "formatShare", "crossingsText", "label", "srcLen", "DEBUG", "tallestName", "tallestH", "n", "debugLog", "bandHaplotypes", "rulerIndex", "t", "refIndex", "ref", "refDuplicates", "refSigns", "firstVisitSigns", "altHaplotypes", "_", "walk", "orientedLike", "bands", "agreement", "visit", "sign", "flip", "signs", "node", "count", "MIN_BEND_WIDTH", "generateTurnaround", "dir", "x", "yStart", "yEnd", "trackWidth", "trackID", "order", "type", "trackName", "extra", "offset", "apex", "radius", "stem", "yTop", "yBottom", "stubNear", "stubFar", "horizontal", "segTop", "inner", "outer", "nodePixelCoordinatesInX", "nodeLeftX", "nodeRightX", "generateNodeWidth", "charWidth", "TRACK_END", "noNeighbors", "nodeCount", "addNeighbor", "neighbors", "index", "neighbor", "soleNeighbor", "mergeNodes", "pred", "succ", "signedIndexOf", "nodeName", "signed", "forward", "isReverse", "track", "sequence", "isHaplotype", "last", "previous", "current", "next", "absorbed", "mergeableWithPred", "origin", "start", "end", "head", "donor", "mergeableWithSucc", "read", "entries", "shift", "mergedSequence", "mergedEntries", "carried", "mismatches", "by", "mismatch", "name", "merged", "reverse", "kept", "predecessor", "successor", "groupBy", "items", "key", "groups", "item", "k", "group", "compareCurvesByXYStartValue", "a", "b", "curveEnds", "curve", "compareTuples", "i", "d", "STEEP_SHARE", "MAX_SPREAD", "spreads", "gapWidth", "first", "span", "floor", "wanted", "c", "rise", "across", "sum", "pick", "total", "w", "reference", "others", "referenceScale", "room", "othersScale", "curvePaths", "curves", "type", "groupedCurves", "curveGroup", "spread", "adjustValue", "s", "at", "share", "xAdjusted", "xNextAdjusted", "flattenPath", "steps", "tokens", "points", "x", "y", "num", "command", "x1", "y1", "x2", "y2", "x3", "y3", "t", "u", "e", "nodeOutlinePath", "node", "readMismatches", "read", "layout", "marks", "entries", "visits", "segment", "entry", "i", "nodeIndex", "forward", "node", "y", "base", "at", "pos", "getXCoordinateOfBaseWithinNode", "mm", "x0", "softClip", "x1", "tubeMapMismatches", "MAX_GAP_PX", "MAX_GAP_SHARE", "isReal", "c", "referenceKnots", "columns", "bpToScreen", "real", "first", "tx", "target", "gap", "i", "span", "demand", "a", "b", "scale", "spread", "sx", "k", "offset", "sum", "g", "blocks", "t", "block", "last", "n", "q", "warpX", "knots", "lo", "hi", "mid", "parsePath", "d", "tokens", "commands", "i", "num", "op", "extentOf", "x0", "x1", "c", "shapeOf", "color", "id", "haplotype", "reference", "flattenPath", "trackColors", "layout", "pathColors", "track", "readColor", "layerOf", "type", "colors", "referenceIds", "gapWidth", "shapes", "colorOf", "s", "isReference", "rects", "r", "curves", "curvePaths", "corners", "referenceTrackIds", "graph", "ids", "path", "pathOrigin", "tubeMapPicture", "columns", "MAX_GAP_PX", "nodes", "node", "nodeOutlinePath", "tubeMapMismatches", "m", "trace", "ctx", "x", "y", "cx", "cy", "fillByColor", "items", "visible", "addTo", "byColor", "item", "list", "FULL_OUTLINE_PX", "MIN_OUTLINE_ALPHA", "outlineAlpha", "screenWidth", "NODE_TINT_ALPHA", "drawTubeMap", "picture", "frame", "width", "layer", "inPass", "left", "top", "stroke", "fill", "outlineWidth", "tint", "drawTubeMapHighlight", "drawMismatches", "n", "MISMATCH_FONT_PX", "MIN_MISMATCH_FONT_PX", "mismatchesLegible", "yScale", "mismatchOnScreen", "marks", "darkMode", "fontPx", "inside", "points", "sx", "sy", "hit", "j", "xi", "yi", "xj", "yj", "tubeMapTrackAt", "l", "px", "py", "INSERTION_SLOP_PX", "tubeMapMismatchAt", "host", "read", "name", "groupKeyComparator", "read", "groupKeys_default", "host", "SECTION_HEADER_PX", "parseSamplesTsv", "text", "head", "lines", "columns", "rows", "line", "name", "values", "c", "i", "metadataColumns", "row", "key", "groupByOf", "value", "field", "domain", "d", "plural", "n", "noun", "columnValueOf", "table", "valueOf", "haplotype", "sample", "groupsByColumn", "items", "nounOf", "groups", "item", "group", "groupKeyComparator", "members", "groupWalkRows", "groupBy", "first", "sections", "title", "section", "g", "sectionPlacement", "rowPx", "sectionOf", "k", "rowY", "s", "y", "best", "lo", "hi", "shift", "walkRowTrees", "bars", "frame", "o", "walkRowsTree", "parsePanSN", "refName", "parts", "haplotype", "collectRun", "seed", "byId", "adj", "claimed", "members", "anchors", "queue", "id", "node", "neighborId", "neighbor", "REFERENCE_RANK", "anchorSpan", "a", "sorted", "b", "first", "last", "start", "end", "runDistances", "entry", "m", "dist", "member", "reach", "known", "runOffsets", "ordered", "rank", "i", "offsets", "offset", "projectAlleles", "graph", "isAnchored", "n", "buildNeighbors", "alleles", "span", "max", "PANEL_GAP", "PANEL_REFERENCE_TUBE", "PANEL_TUBE", "PANEL_TUBES", "TINTED_TUBES", "PANEL_TITLE_FONT", "TUBE_MAP_PANELS", "walkOf", "name", "pathOrigin", "roleTubeColors", "paths", "reference", "tubes", "haplotype", "p", "VALUE_TUBES", "NO_VALUE_TUBE", "valueTubePalette", "values", "sorted", "v", "groupKeyComparator", "i", "valueTubeColors", "valueOf", "palette", "walk", "columnKeyOf", "field", "table", "columnValueOf", "sample", "parsePanSN", "tubeMapPanelGroups", "graph", "split", "names", "keyOf", "groupsByColumn", "key", "members", "title", "groups", "list", "domain", "rank", "listed", "a", "b", "boxOf", "drawing", "node", "box", "memberAt", "spanOf", "left", "right", "sx", "spans", "id", "span", "start", "s", "end", "share", "bp", "distance", "walksThrough", "all", "here", "member", "COUNT_FONT", "MIN_COUNT_RUN_PX", "MIN_COUNT_TUBE_PX", "drawBundleCounts", "ctx", "picture", "x", "y", "width", "counts", "r", "n", "top", "bottom", "LENGTH_FONT", "MIN_LENGTH_LABEL_BP", "drawSqueezedLengths", "lengthOf", "stacks", "text", "formatBp", "mid", "stack", "drawn", "count", "label", "d", "paintPanelHover", "panels", "hover", "lit", "hit", "drawTubeMapHighlight", "plural", "graphOfPaths", "kept", "keptPaths", "walks", "nodeIds", "nodes", "pathVisits", "path", "segment", "e", "withTubeMapPanels", "whole", "laidOut", "nodePositions", "minX", "maxX", "result", "tubeMap", "extent", "height", "dy", "segments", "EXON_COLOR", "EXON_GAP_PX", "EXON_LINE_PX", "MIN_LANE_PX", "exonStretches", "pins", "halfWidthPx", "lift", "pathOf", "d", "inkPx", "nodeId", "own", "pin", "exonOutlineTree", "stretches", "o", "stroke", "s", "color", "width", "el", "rangeText", "contig", "start", "end", "s", "e", "groupDigits", "formatBp", "walkKey", "walk", "reference", "field", "own", "scale", "spanned", "outside", "walkPosition", "nodeId", "length", "progress", "range", "tubeMapGenes", "byRefName", "genes", "out", "gene", "boxes", "first", "last", "start", "end", "tubeSpan", "e", "GENE_ROW_PX", "MAX_GENE_ROWS", "EXON_PX", "NAME_FONT", "NAME_GAP_PX", "tubeMapGeneRows", "edges", "g", "a", "b", "depth", "most", "step", "drawTubeMapGenes", "ctx", "frame", "bottom", "top", "x", "width", "darkMode", "rows", "rowEnds", "ink", "placed", "s0", "s1", "arrow", "label", "mid", "half", "left", "right", "row", "glyphY", "e0", "REFERENCE_STRIP_PX", "REFERENCE_STRIP_ZONE_PX", "OVERHANG_PX", "OVERHANG_CAP_PX", "MIN_STAGGER_PX", "referenceStripBlocks", "graph", "colorScheme", "referenceRamp", "walks", "range", "computeColorSchemeRange", "out", "node", "index", "isBackbone", "colors", "w", "lane", "LIFT_BACKDROP_CSS", "abgrToCssRgba", "getNodeColor", "b", "span", "frame", "bp0", "bp1", "a", "HIT_SLOP_PX", "stripOverhang", "blocks", "width", "lo", "hi", "below", "above", "block", "stripBlockAt", "sx", "sy", "hit", "best", "x0", "x1", "dist", "nodeAnchor", "segments", "toScreen", "p", "stripPixels", "dpr", "placed", "px0", "claimed", "tierEnds", "px1", "start", "tier", "_", "drawOverhang", "ctx", "edgeX", "inward", "ink", "capX", "tipX", "baseX", "rowEdge", "row", "rows", "drawReferenceStrip", "lit", "darkMode", "staggered", "color", "i", "y0", "overhang", "left", "agrees", "walkBp", "callBp", "nearest", "walks", "calls", "W", "C", "cost", "paired", "i", "j", "together", "dropWalk", "dropCall", "out", "byLength", "items", "bp", "item", "a", "b", "backed", "call", "scored", "row", "pairSample", "rows", "taken", "ranked", "r", "pair", "pool", "group", "stages", "alleles", "free", "open", "c", "pick", "k", "haplotype", "withCalls", "bySample", "sample", "called"]
|
|
3
|
+
"sources": ["../../node_modules/.pnpm/@jbrowse+bandage-core@10.2.6/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-XV4P5KEQ.js", "../../node_modules/.pnpm/@jbrowse+bandage-core@10.2.6/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-RUCH6ZFL.js", "../../node_modules/.pnpm/@jbrowse+bandage-core@10.2.6/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-RBCE2OQH.js", "../../node_modules/.pnpm/@jbrowse+bandage-core@10.2.6/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-QLWI2PZ3.js", "../../node_modules/.pnpm/@jbrowse+bandage-core@10.2.6/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-KBEP7VYK.js", "../../node_modules/.pnpm/@jbrowse+bandage-core@10.2.6/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-4HWM3FNK.js", "../../node_modules/.pnpm/@jbrowse+bandage-core@10.2.6/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-KC7T5RWG.js", "host:mobx", "../../node_modules/.pnpm/@jbrowse+bandage-core@10.2.6/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-CWFNEKST.js", "../../node_modules/.pnpm/@jbrowse+bandage-core@10.2.6/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-XL472HHD.js", "../../node_modules/.pnpm/@jbrowse+bandage-core@10.2.6/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-H2H4Y3TV.js", "../../node_modules/.pnpm/@jbrowse+bandage-core@10.2.6/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-EFQLEGWM.js", "../../node_modules/.pnpm/@jbrowse+bandage-core@10.2.6/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-URZ3CH2R.js", "../../node_modules/.pnpm/@jbrowse+bandage-core@10.2.6/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-XMW266WS.js", "../../node_modules/.pnpm/@jbrowse+bandage-core@10.2.6/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-2ZT7ZF7A.js", "../../node_modules/.pnpm/@jbrowse+bandage-core@10.2.6/node_modules/@jbrowse/bandage-core/dist/tubeMap/deviations.js", "../../node_modules/.pnpm/@jbrowse+tubemap-core@1.1.0/node_modules/@jbrowse/tubemap-core/src/types.ts", "../../node_modules/.pnpm/@jbrowse+tubemap-core@1.1.0/node_modules/@jbrowse/tubemap-core/src/panSN.ts", "../../node_modules/.pnpm/@jbrowse+tubemap-core@1.1.0/node_modules/@jbrowse/tubemap-core/src/layout.ts", "../../node_modules/.pnpm/@jbrowse+tubemap-core@1.1.0/node_modules/@jbrowse/tubemap-core/src/geometry.ts", "../../node_modules/.pnpm/@jbrowse+bandage-core@10.2.6/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-XXT2JCAC.js", "../../node_modules/.pnpm/@jbrowse+bandage-core@10.2.6/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-HK5Y2YWV.js", "../../node_modules/.pnpm/@jbrowse+bandage-core@10.2.6/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-B6IW3IRE.js", "host:@jbrowse/core/util/groupKeys", "../../src/GraphGenomeView/walkRowGroups.ts", "../../node_modules/.pnpm/@jbrowse+bandage-core@10.2.6/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-RVS2QCOX.js", "../../src/GraphGenomeView/tubeMapPanels.ts", "../../node_modules/.pnpm/@jbrowse+bandage-core@10.2.6/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-JSUCGZ6K.js", "../../node_modules/.pnpm/@jbrowse+bandage-core@10.2.6/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-4ETPXDO6.js", "../../node_modules/.pnpm/@jbrowse+bandage-core@10.2.6/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-4DRQTBBE.js", "../../node_modules/.pnpm/@jbrowse+bandage-core@10.2.6/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-JLSJMCDJ.js", "../../src/GraphGenomeView/repeats/walkCalls.ts"],
|
|
4
|
+
"sourcesContent": ["// src/facetGrid.ts\nvar FACET_GAP_PX = 8;\nvar FACET_TITLE_PX = 34;\nvar FACET_PAD_PX = 12;\nvar MIN_FACET_PANEL_PX = 60;\nfunction facetGrid({\n count,\n bounds,\n pixelRows,\n width,\n room,\n columns\n}) {\n function tile(across) {\n const rows = Math.ceil(count / across);\n const panelWidth = Math.floor(\n (width - (across - 1) * FACET_GAP_PX) / across\n );\n const panelRoom = (room - rows * FACET_TITLE_PX - (rows - 1) * FACET_GAP_PX) / rows;\n const fitX = (panelWidth - 2 * FACET_PAD_PX) / bounds.w;\n const fitY = bounds.h > 0 ? (panelRoom - 2 * FACET_PAD_PX) / bounds.h : Infinity;\n const scale = pixelRows ? fitX : Math.min(fitX, fitY);\n const drawn = pixelRows ? bounds.h : bounds.h * scale;\n const height = Math.floor(\n Math.max(\n MIN_FACET_PANEL_PX,\n Math.min(drawn + 2 * FACET_PAD_PX, panelRoom)\n )\n );\n return {\n columns: across,\n width: panelWidth,\n height,\n scale,\n total: rows * (height + FACET_TITLE_PX) + (rows - 1) * FACET_GAP_PX\n };\n }\n if (columns !== void 0) {\n return tile(Math.max(1, Math.min(count, Math.round(columns))));\n }\n let best = tile(1);\n for (let across = 2; across <= count; across++) {\n const grid = tile(across);\n if (grid.scale > best.scale) {\n best = grid;\n }\n }\n return best;\n}\nvar FACET_FIELDS = [\n { value: \"\", label: \"None\", description: \"Every lifted walk in one drawing\" },\n {\n value: \"walk\",\n label: \"A panel per walk\",\n description: \"One panel per lifted walk, side by side\"\n },\n {\n value: \"sample\",\n label: \"A row per sample\",\n description: \"A row per sample, a column per haplotype\"\n }\n];\nfunction facetSettingOf(facet) {\n const raw = typeof facet === \"string\" ? { field: facet } : facet ?? {};\n const field = raw.field === \"walk\" || raw.field === \"sample\" ? raw.field : \"\";\n return {\n field,\n domain: [...raw.domain ?? []],\n ...raw.columns === void 0 ? {} : { columns: raw.columns }\n };\n}\nfunction domainFirst(names, domain) {\n const rank = new Map(domain.map((name, i) => [name, i]));\n const listed = (name) => rank.get(name) ?? domain.length;\n return names.map((name, i) => ({ name, i })).sort((a, b) => listed(a.name) - listed(b.name) || a.i - b.i).map(({ name }) => name);\n}\nfunction facetCells(names, by, domain = []) {\n const wrapOrder = domainFirst(names, domain);\n const wrap = {\n columns: void 0,\n count: names.length,\n cells: names.map((name) => wrapOrder.indexOf(name))\n };\n if (by === \"walk\") {\n return wrap;\n }\n const places = names.map((name) => {\n const [sample, haplotype, contig] = name.split(\"#\");\n const n = Number(haplotype);\n return contig !== void 0 && Number.isInteger(n) && n >= 0 ? { sample, column: Math.max(0, n - 1) } : void 0;\n });\n const rows = domainFirst(\n [...new Set(places.flatMap((p) => p ? [p.sample] : []))],\n domain\n );\n const columns = Math.max(1, ...places.map((p) => p ? p.column + 1 : 1));\n const cells = places.map(\n (p) => p ? rows.indexOf(p.sample) * columns + p.column : -1\n );\n return cells.includes(-1) || new Set(cells).size < cells.length ? wrap : { columns, count: rows.length * columns, cells };\n}\n\nexport {\n FACET_GAP_PX,\n FACET_TITLE_PX,\n FACET_PAD_PX,\n facetGrid,\n FACET_FIELDS,\n facetSettingOf,\n facetCells\n};\n", "// src/renderer/svgCanvas.ts\nvar n = (v) => +v.toFixed(1);\nfunction paint(css) {\n const m = /^rgba?\\(([^,]+),([^,]+),([^,)]+)(?:,([^)]+))?\\)$/.exec(\n css.replaceAll(\" \", \"\")\n );\n if (!m) {\n return { color: css, opacity: 1 };\n }\n const opacity = m[4] === void 0 ? 1 : Number(m[4]);\n return { color: `rgb(${m[1]},${m[2]},${m[3]})`, opacity };\n}\nfunction paintAttrs(kind, css) {\n const { color, opacity } = paint(css);\n return `${kind}=\"${color}\"${opacity < 1 ? ` ${kind}-opacity=\"${n(opacity)}\"` : \"\"}`;\n}\nvar DOT_PX = 0.5;\nvar DOT_CELL_PX = 0.25;\nfunction svgCanvas(width, height) {\n const out = [];\n let subpaths = [];\n const start = (x, y) => {\n const s = { d: `M${n(x)} ${n(y)}`, segments: 0, x0: x, x1: x, y0: y, y1: y };\n subpaths.push(s);\n return s;\n };\n const reach = (points) => {\n const s = subpaths.at(-1) ?? start(points[0], points[1]);\n for (let i = 0; i < points.length; i += 2) {\n s.x0 = Math.min(s.x0, points[i]);\n s.x1 = Math.max(s.x1, points[i]);\n s.y0 = Math.min(s.y0, points[i + 1]);\n s.y1 = Math.max(s.y1, points[i + 1]);\n }\n s.segments++;\n return s;\n };\n const pathData = (dots) => {\n const seen = /* @__PURE__ */ new Set();\n return subpaths.map((s) => {\n if (!dots || s.x1 - s.x0 >= DOT_PX || s.y1 - s.y0 >= DOT_PX) {\n return s.d;\n }\n const x = (s.x0 + s.x1) / 2;\n const y = (s.y0 + s.y1) / 2;\n const cell = `${Math.round(x / DOT_CELL_PX)} ${Math.round(y / DOT_CELL_PX)}`;\n if (s.segments === 0 || seen.has(cell)) {\n return \"\";\n }\n seen.add(cell);\n return `M${n(x)} ${n(y)}h0`;\n }).join(\"\");\n };\n const ctx = {\n canvas: void 0,\n fillStyle: \"#000\",\n strokeStyle: \"#000\",\n lineWidth: 1,\n lineCap: \"butt\",\n lineJoin: \"miter\",\n beginPath() {\n subpaths = [];\n },\n moveTo(x, y) {\n start(x, y);\n },\n lineTo(x, y) {\n reach([x, y]).d += `L${n(x)} ${n(y)}`;\n },\n bezierCurveTo(cx0, cy0, cx1, cy1, x, y) {\n reach([cx0, cy0, cx1, cy1, x, y]).d += `C${n(cx0)} ${n(cy0)} ${n(cx1)} ${n(cy1)} ${n(x)} ${n(y)}`;\n },\n closePath() {\n const s = subpaths.at(-1);\n if (s) {\n s.d += \"Z\";\n }\n },\n stroke() {\n const d = pathData(ctx.lineCap !== \"butt\");\n if (d) {\n out.push(\n `<path d=\"${d}\" fill=\"none\" ${paintAttrs(\"stroke\", ctx.strokeStyle)} stroke-width=\"${n(ctx.lineWidth)}\" stroke-linecap=\"${ctx.lineCap}\" stroke-linejoin=\"${ctx.lineJoin}\"/>`\n );\n }\n },\n fill() {\n const d = pathData(false);\n if (d) {\n out.push(`<path d=\"${d}\" ${paintAttrs(\"fill\", ctx.fillStyle)}/>`);\n }\n },\n // the renderer only ever clears the whole canvas\n clearRect() {\n out.length = 0;\n },\n fillRect(x, y, w, h) {\n out.push(\n `<rect x=\"${n(x)}\" y=\"${n(y)}\" width=\"${n(w)}\" height=\"${n(h)}\" ${paintAttrs(\"fill\", ctx.fillStyle)}/>`\n );\n }\n };\n const canvas = {\n width,\n height,\n style: {},\n getContext: () => ctx\n };\n ctx.canvas = canvas;\n return {\n canvas,\n // the drawing so far, as SVG elements in canvas pixels\n markup: () => out.join(\"\")\n };\n}\n\nexport {\n svgCanvas\n};\n", "// src/renderer/canvas.ts\nvar MAX_DPR = 2;\nvar MAX_CANVAS_DIM_PX = 8192;\nfunction getDpr(width = 0, height = 0) {\n const dpr = typeof devicePixelRatio === \"undefined\" ? 1 : Math.min(devicePixelRatio, MAX_DPR);\n return Math.min(dpr, MAX_CANVAS_DIM_PX / Math.max(width, height, 1));\n}\nfunction syncCanvasSize(canvas, width, height) {\n const dpr = getDpr(width, height);\n const pw = Math.round(width * dpr);\n const ph = Math.round(height * dpr);\n if (canvas.width !== pw || canvas.height !== ph) {\n canvas.width = pw;\n canvas.height = ph;\n }\n const cssWidth = `${width}px`;\n const cssHeight = `${height}px`;\n if (canvas.style.width !== cssWidth) {\n canvas.style.width = cssWidth;\n }\n if (canvas.style.height !== cssHeight) {\n canvas.style.height = cssHeight;\n }\n return dpr;\n}\n\nexport {\n MAX_DPR,\n MAX_CANVAS_DIM_PX,\n getDpr,\n syncCanvasSize\n};\n", "import {\n getDpr,\n syncCanvasSize\n} from \"./chunk-RBCE2OQH.js\";\nimport {\n abgrToCssRgba,\n brightenAbgr,\n normalizedRgbToCssRgba\n} from \"./chunk-G2FD7S3C.js\";\n\n// src/renderer/Canvas2DRenderer.ts\nvar Canvas2DRenderer = class {\n constructor(canvas) {\n this.transform = null;\n this.batch = null;\n this.nodeHighlights = /* @__PURE__ */ new Map();\n this.highlightedEdge = null;\n this.highlightFactor = 1;\n this.fit = 1;\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) {\n throw new Error(\"Canvas 2D context not available\");\n }\n this.canvas = canvas;\n this.ctx = ctx;\n }\n setErrorHandler(_handler) {\n }\n releaseOffscreenTargets() {\n }\n // A host builds its transform at `getDpr()`. Where syncCanvasSize had to\n // shrink the ratio to stay under MAX_CANVAS_DIM_PX, `fit` shrinks the\n // transform to match, so the picture still fills the css box.\n resize(width, height) {\n this.fit = syncCanvasSize(this.canvas, width, height) / getDpr();\n }\n uploadGeometry(batch) {\n this.batch = batch;\n this.highlightedEdge = null;\n }\n setNodeHighlights(factors) {\n this.nodeHighlights = factors;\n }\n setEdgeHighlight(edgeIndex, factor) {\n this.highlightedEdge = edgeIndex;\n this.highlightFactor = factor;\n }\n updateTransform(transform) {\n const k = this.fit;\n this.transform = k === 1 ? transform : {\n ...transform,\n scaleX: transform.scaleX * k,\n scaleY: transform.scaleY * k,\n translateX: transform.translateX * k,\n translateY: transform.translateY * k,\n dpr: transform.dpr * k\n };\n }\n render(clearColor) {\n const t = this.transform;\n if (!t) {\n return;\n }\n const ctx = this.ctx;\n const { width, height } = ctx.canvas;\n if (clearColor[3] < 1) {\n ctx.clearRect(0, 0, width, height);\n }\n ctx.fillStyle = normalizedRgbToCssRgba(\n [clearColor[0], clearColor[1], clearColor[2]],\n clearColor[3]\n );\n ctx.fillRect(0, 0, width, height);\n const batch = this.batch;\n if (!batch) {\n return;\n }\n ctx.lineCap = \"round\";\n ctx.lineJoin = \"round\";\n const factor = this.highlightFactor;\n const edgeRun = this.edgeRun(batch.edgeCurveRuns);\n for (const { color, items } of groupByPaint(batch.edgeCurves, (e, i) => ({\n color: inRun(edgeRun, i) ? brightenAbgr(e.color, factor) : e.color,\n weight: e.thickness,\n last: inRun(edgeRun, i)\n }))) {\n this.strokeCurves(items, color);\n }\n const lifted = this.liftedStrokes(batch);\n for (const { color, items } of groupByPaint(batch.nodeStrokes, (s, i) => {\n const f = lifted.get(i);\n return {\n color: f === void 0 ? s.color : brightenAbgr(s.color, f),\n weight: s.thickness,\n last: f !== void 0\n };\n })) {\n this.strokeNodes(items, color);\n }\n const arrowRun = this.edgeRun(batch.arrowRuns);\n for (const { color, items } of groupByPaint(batch.arrows, (a, i) => ({\n color: inRun(arrowRun, i) ? brightenAbgr(a.color, factor) : a.color,\n weight: 0,\n last: inRun(arrowRun, i)\n }))) {\n this.fillArrows(items, color);\n }\n }\n // Only what the highlights lift, over a transparent clear, for a hover layer\n // stacked on a canvas that drew the batch without them: a pointer move then\n // repaints one node or edge rather than the whole drawing\n renderHighlights() {\n const ctx = this.ctx;\n ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);\n const batch = this.batch;\n if (!this.transform || !batch) {\n return;\n }\n ctx.lineCap = \"round\";\n ctx.lineJoin = \"round\";\n const factor = this.highlightFactor;\n const curves = runItems(batch.edgeCurves, this.edgeRun(batch.edgeCurveRuns));\n for (const { color, items } of groupByPaint(curves, (e) => ({\n color: brightenAbgr(e.color, factor),\n weight: e.thickness,\n last: false\n }))) {\n this.strokeCurves(items, color);\n }\n const lifted = [...this.liftedStrokes(batch)];\n for (const { color, items } of groupByPaint(lifted, ([i, f]) => ({\n color: brightenAbgr(batch.nodeStrokes[i].color, f),\n weight: batch.nodeStrokes[i].thickness,\n last: false\n }))) {\n this.strokeNodes(\n items.map(([i]) => batch.nodeStrokes[i]),\n color\n );\n }\n const arrows = runItems(batch.arrows, this.edgeRun(batch.arrowRuns));\n for (const { color, items } of groupByPaint(arrows, (a) => ({\n color: brightenAbgr(a.color, factor),\n weight: 0,\n last: false\n }))) {\n this.fillArrows(items, color);\n }\n }\n edgeRun(runs) {\n return this.highlightedEdge === null ? void 0 : runs.get(this.highlightedEdge);\n }\n // stroke index -> brighten factor, for the nodes the model lifted\n liftedStrokes(batch) {\n const lifted = /* @__PURE__ */ new Map();\n for (const [nodeId, factor] of this.nodeHighlights) {\n const run = batch.nodeStrokeRuns.get(nodeId);\n if (run) {\n for (let i = run.start; i < run.start + run.count; i++) {\n lifted.set(i, factor);\n }\n }\n }\n return lifted;\n }\n strokeCurves(items, color) {\n const t = this.transform;\n const ctx = this.ctx;\n ctx.strokeStyle = abgrToCssRgba(color);\n ctx.lineWidth = items[0].thickness * 2 * t.dpr;\n ctx.beginPath();\n for (const e of items) {\n const first = e.curves[0];\n ctx.moveTo(\n first.x0 * t.scaleX + t.translateX,\n first.y0 * t.scaleY + t.translateY\n );\n for (const c of e.curves) {\n ctx.bezierCurveTo(\n c.cx0 * t.scaleX + t.translateX,\n c.cy0 * t.scaleY + t.translateY,\n c.cx1 * t.scaleX + t.translateX,\n c.cy1 * t.scaleY + t.translateY,\n c.x1 * t.scaleX + t.translateX,\n c.y1 * t.scaleY + t.translateY\n );\n }\n }\n ctx.stroke();\n }\n strokeNodes(items, color) {\n const t = this.transform;\n const ctx = this.ctx;\n ctx.strokeStyle = abgrToCssRgba(color);\n ctx.lineWidth = items[0].thickness * 2 * t.dpr;\n ctx.beginPath();\n for (const s of items) {\n const p0 = s.points[0];\n ctx.moveTo(p0.x * t.scaleX + t.translateX, p0.y * t.scaleY + t.translateY);\n for (let i = 1, l = s.points.length; i < l; i++) {\n const p = s.points[i];\n ctx.lineTo(p.x * t.scaleX + t.translateX, p.y * t.scaleY + t.translateY);\n }\n }\n ctx.stroke();\n }\n fillArrows(items, color) {\n const t = this.transform;\n const ctx = this.ctx;\n ctx.fillStyle = abgrToCssRgba(color);\n ctx.beginPath();\n for (const a of items) {\n const [tip, left, notch, right] = arrowheadOutline(a, t);\n ctx.moveTo(tip.x, tip.y);\n ctx.lineTo(left.x, left.y);\n ctx.lineTo(notch.x, notch.y);\n ctx.lineTo(right.x, right.y);\n ctx.closePath();\n }\n ctx.fill();\n }\n dispose() {\n this.batch = null;\n this.nodeHighlights = /* @__PURE__ */ new Map();\n this.highlightedEdge = null;\n }\n};\nvar ARROW_NOTCH = 0.25;\nfunction arrowheadOutline(a, t) {\n const ux = Math.cos(a.angle);\n const uy = Math.sin(a.angle);\n const tipX = a.x * t.scaleX + t.translateX;\n const tipY = a.y * t.scaleY + t.translateY;\n const length = a.length * t.dpr;\n const halfWidth = a.halfWidth * t.dpr;\n const backX = tipX - ux * length;\n const backY = tipY - uy * length;\n const notchBack = length * (1 - ARROW_NOTCH);\n return [\n { x: tipX, y: tipY },\n { x: backX - uy * halfWidth, y: backY + ux * halfWidth },\n { x: tipX - ux * notchBack, y: tipY - uy * notchBack },\n { x: backX + uy * halfWidth, y: backY - ux * halfWidth }\n ];\n}\nfunction runItems(items, run) {\n return run ? items.slice(run.start, run.start + run.count) : [];\n}\nfunction inRun(run, i) {\n return run !== void 0 && i >= run.start && i < run.start + run.count;\n}\nfunction groupByPaint(items, paintOf) {\n const groups = /* @__PURE__ */ new Map();\n const deferred = /* @__PURE__ */ new Map();\n for (let i = 0, l = items.length; i < l; i++) {\n const item = items[i];\n const { color, weight, last } = paintOf(item, i);\n const into = last ? deferred : groups;\n const key = `${color}:${weight}`;\n const group = into.get(key);\n if (group) {\n group.items.push(item);\n } else {\n into.set(key, { color, items: [item] });\n }\n }\n return [...groups.values(), ...deferred.values()];\n}\n\nexport {\n Canvas2DRenderer,\n arrowheadOutline\n};\n", "import {\n baseEdgeCurves\n} from \"./chunk-ZY2AFL4Y.js\";\nimport {\n curveBounds,\n pathRibbonOffsets\n} from \"./chunk-7SRWJLSC.js\";\n\n// src/util/SpatialIndex.ts\nvar FALLBACK_CELL_SIZE = 50;\nfunction meanExtentCellSize(extentTotal, count) {\n return count > 0 ? Math.max(1, extentTotal / count) : FALLBACK_CELL_SIZE;\n}\nfunction rowPitchOf(boxes) {\n const distinct = /* @__PURE__ */ new Set();\n let min = Infinity;\n let max = -Infinity;\n for (const box of boxes) {\n distinct.add(box.minY);\n min = Math.min(min, box.minY);\n max = Math.max(max, box.minY);\n }\n return distinct.size > 1 ? (max - min) / (distinct.size - 1) : void 0;\n}\nfunction cellSizeFrom(boxes, extentX, extentY) {\n const x = meanExtentCellSize(extentX, boxes.length);\n return {\n x,\n y: extentY > 0 ? meanExtentCellSize(extentY, boxes.length) : rowPitchOf(boxes) ?? x\n };\n}\nfunction resolveCellSize(given, boxes, extentX, extentY) {\n return given === void 0 ? cellSizeFrom(boxes, extentX, extentY) : typeof given === \"number\" ? { x: given, y: given } : given;\n}\nfunction getOrCreateCell(cells, cx, cy) {\n let row = cells.get(cx);\n if (!row) {\n row = /* @__PURE__ */ new Map();\n cells.set(cx, row);\n }\n let cell = row.get(cy);\n if (!cell) {\n cell = [];\n row.set(cy, cell);\n }\n return cell;\n}\nfunction addToGrid(cells, cellSize, minX, minY, maxX, maxY, entry) {\n const cx0 = Math.floor(minX / cellSize.x);\n const cx1 = Math.floor(maxX / cellSize.x);\n const cy0 = Math.floor(minY / cellSize.y);\n const cy1 = Math.floor(maxY / cellSize.y);\n for (let cx = cx0; cx <= cx1; cx++) {\n for (let cy = cy0; cy <= cy1; cy++) {\n getOrCreateCell(cells, cx, cy).push(entry);\n }\n }\n}\nfunction queryGrid(cells, cellSize, x, y, radiusX, radiusY) {\n const cx0 = Math.floor((x - radiusX) / cellSize.x);\n const cx1 = Math.floor((x + radiusX) / cellSize.x);\n const cy0 = Math.floor((y - radiusY) / cellSize.y);\n const cy1 = Math.floor((y + radiusY) / cellSize.y);\n const results = [];\n const seen = /* @__PURE__ */ new Set();\n for (let cx = cx0; cx <= cx1; cx++) {\n const row = cells.get(cx);\n if (row) {\n for (let cy = cy0; cy <= cy1; cy++) {\n const cell = row.get(cy);\n if (cell) {\n for (const entry of cell) {\n if (!seen.has(entry)) {\n seen.add(entry);\n results.push(entry);\n }\n }\n }\n }\n }\n }\n return results;\n}\nvar SpatialIndex = class {\n constructor(nodePositions, cellSize) {\n this.cells = /* @__PURE__ */ new Map();\n const boxes = [];\n let extentX = 0;\n let extentY = 0;\n for (const [nodeId, segments] of Object.entries(nodePositions)) {\n for (let i = 0; i < segments.length - 1; i++) {\n const seg = segments[i];\n const next = segments[i + 1];\n const minX = Math.min(seg.x, next.x);\n const minY = Math.min(seg.y, next.y);\n const maxX = Math.max(seg.x, next.x);\n const maxY = Math.max(seg.y, next.y);\n extentX += maxX - minX;\n extentY += maxY - minY;\n boxes.push({ entry: { nodeId, segmentIdx: i }, minX, minY, maxX, maxY });\n }\n }\n this.cellSize = resolveCellSize(cellSize, boxes, extentX, extentY);\n for (const b of boxes) {\n addToGrid(\n this.cells,\n this.cellSize,\n b.minX,\n b.minY,\n b.maxX,\n b.maxY,\n b.entry\n );\n }\n }\n query(x, y, radiusX, radiusY = radiusX) {\n return queryGrid(this.cells, this.cellSize, x, y, radiusX, radiusY);\n }\n};\nvar EdgeSpatialIndex = class {\n constructor(nodePositions, graph, drawPaths, axis, cellSize, deletions, version = 0, routes, stranded = false) {\n this.cells = /* @__PURE__ */ new Map();\n this.edgeCurves = baseEdgeCurves(\n nodePositions,\n graph,\n axis,\n deletions,\n version,\n routes,\n stranded\n );\n const boxes = [];\n let extentX = 0;\n let extentY = 0;\n for (let ei = 0; ei < graph.edges.length; ei++) {\n const edge = graph.edges[ei];\n const fromSegments = nodePositions[edge.from];\n const toSegments = nodePositions[edge.to];\n const curves = this.edgeCurves.get(ei);\n if (fromSegments?.length && toSegments?.length && curves) {\n let { minX, minY, maxX, maxY } = curveBounds(curves);\n const numPaths = edge.pathIds?.length ?? 0;\n if (drawPaths && numPaths > 0) {\n let padX = 0;\n let padY = 0;\n for (const o of pathRibbonOffsets(\n fromSegments,\n toSegments,\n numPaths,\n axis\n )) {\n padX = Math.max(padX, Math.abs(o.x));\n padY = Math.max(padY, Math.abs(o.y));\n }\n minX -= padX;\n minY -= padY;\n maxX += padX;\n maxY += padY;\n }\n extentX += maxX - minX;\n extentY += maxY - minY;\n boxes.push({ ei, minX, minY, maxX, maxY });\n }\n }\n this.cellSize = resolveCellSize(cellSize, boxes, extentX, extentY);\n for (const b of boxes) {\n addToGrid(this.cells, this.cellSize, b.minX, b.minY, b.maxX, b.maxY, b.ei);\n }\n }\n getCurves(ei) {\n return this.edgeCurves.get(ei);\n }\n query(x, y, radiusX, radiusY = radiusX) {\n return queryGrid(this.cells, this.cellSize, x, y, radiusX, radiusY);\n }\n};\n\nexport {\n SpatialIndex,\n EdgeSpatialIndex\n};\n", "import {\n EdgeSpatialIndex,\n SpatialIndex\n} from \"./chunk-KBEP7VYK.js\";\nimport {\n pathRibbonOffsets,\n translateCurves,\n yToXOf\n} from \"./chunk-7SRWJLSC.js\";\n\n// src/util/hitDetection.ts\nfunction distanceToSegment(px, py, x1, y1, x2, y2) {\n const dx = x2 - x1;\n const dy = y2 - y1;\n const lenSq = dx * dx + dy * dy;\n if (lenSq === 0) {\n return Math.hypot(px - x1, py - y1);\n }\n const t = Math.max(0, Math.min(1, ((px - x1) * dx + (py - y1) * dy) / lenSq));\n return Math.hypot(px - (x1 + t * dx), py - (y1 + t * dy));\n}\nfunction distanceToCubicBezier(px, py, x1, y1, cx1, cy1, cx2, cy2, x2, y2) {\n let minDist = Infinity;\n const samples = 20;\n let lastX = x1;\n let lastY = y1;\n for (let i = 1; i <= samples; i++) {\n const t = i / samples;\n const u = 1 - t;\n const bx = u * u * u * x1 + 3 * u * u * t * cx1 + 3 * u * t * t * cx2 + t * t * t * x2;\n const by = u * u * u * y1 + 3 * u * u * t * cy1 + 3 * u * t * t * cy2 + t * t * t * y2;\n minDist = Math.min(minDist, distanceToSegment(px, py, lastX, lastY, bx, by));\n lastX = bx;\n lastY = by;\n }\n return minDist;\n}\nfunction distanceToBezierCurve(px, py, c) {\n return distanceToCubicBezier(\n px,\n py,\n c.x0,\n c.y0,\n c.cx0,\n c.cy0,\n c.cx1,\n c.cy1,\n c.x1,\n c.y1\n );\n}\nfunction distanceToEdgeCurves(px, py, curves, yToX = 1) {\n let minDist = Infinity;\n for (const c of curves) {\n const d = distanceToBezierCurve(\n px,\n py,\n yToX === 1 ? c : {\n x0: c.x0,\n y0: c.y0 * yToX,\n cx0: c.cx0,\n cy0: c.cy0 * yToX,\n cx1: c.cx1,\n cy1: c.cy1 * yToX,\n x1: c.x1,\n y1: c.y1 * yToX\n }\n );\n if (d < minDist) {\n minDist = d;\n }\n }\n return minDist;\n}\nvar nodeCache = /* @__PURE__ */ new WeakMap();\nfunction getSpatialIndex(nodePositions, version) {\n const cached = nodeCache.get(nodePositions);\n if (cached?.version === version) {\n return cached.index;\n }\n const index = new SpatialIndex(nodePositions);\n nodeCache.set(nodePositions, { version, index });\n return index;\n}\nvar edgeCache = /* @__PURE__ */ new WeakMap();\nfunction getEdgeSpatialIndex(nodePositions, graph, drawPaths, axis, version, deletions, routes, stranded = false) {\n const cached = edgeCache.get(nodePositions);\n if (cached?.graph === graph && cached.drawPaths === drawPaths && cached.scaleX === axis.scaleX && cached.scaleY === axis.scaleY && cached.version === version && cached.deletions === deletions && cached.routes === routes && cached.stranded === stranded) {\n return cached.index;\n }\n const index = new EdgeSpatialIndex(\n nodePositions,\n graph,\n drawPaths,\n axis,\n void 0,\n deletions,\n version,\n routes,\n stranded\n );\n edgeCache.set(nodePositions, {\n graph,\n drawPaths,\n scaleX: axis.scaleX,\n scaleY: axis.scaleY,\n version,\n index,\n deletions,\n routes,\n stranded\n });\n return index;\n}\nvar MIN_NODE_REACH_PX = 5;\nfunction findHoveredNode(nodePositions, graphX, graphY, axis, version = 0, ink) {\n const yToX = yToXOf(axis);\n const index = getSpatialIndex(nodePositions, version);\n const reach = (px) => Math.max(MIN_NODE_REACH_PX, px) / axis.scaleX;\n const queryReach = reach(ink?.maxHalfWidthPx ?? 0);\n const candidates = index.query(graphX, graphY, queryReach, queryReach / yToX);\n let hovered = null;\n let best = Infinity;\n for (const { nodeId, segmentIdx } of candidates) {\n const segments = nodePositions[nodeId];\n const dist = distanceToSegment(\n graphX,\n graphY * yToX,\n segments[segmentIdx].x,\n segments[segmentIdx].y * yToX,\n segments[segmentIdx + 1].x,\n segments[segmentIdx + 1].y * yToX\n );\n if (dist < best && dist < reach(ink?.halfWidthPx(nodeId) ?? 0)) {\n best = dist;\n hovered = nodeId;\n }\n }\n return hovered;\n}\nfunction segmentMeetsBox(a, b, box) {\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n let t0 = 0;\n let t1 = 1;\n for (const [p, q] of [\n [-dx, a.x - box.x0],\n [dx, box.x1 - a.x],\n [-dy, a.y - box.y0],\n [dy, box.y1 - a.y]\n ]) {\n if (p === 0) {\n if (q < 0) {\n return false;\n }\n } else if (p < 0) {\n t0 = Math.max(t0, q / p);\n } else {\n t1 = Math.min(t1, q / p);\n }\n }\n return t0 <= t1;\n}\nfunction nodesUnderBox(nodePositions, t, version = 0) {\n const index = getSpatialIndex(nodePositions, version);\n const screen = (p) => ({\n x: p.x * t.scaleX + t.translateX,\n y: p.y * t.scaleY + t.translateY\n });\n return (box) => {\n const hits = /* @__PURE__ */ new Set();\n const candidates = index.query(\n ((box.x0 + box.x1) / 2 - t.translateX) / t.scaleX,\n ((box.y0 + box.y1) / 2 - t.translateY) / t.scaleY,\n Math.abs((box.x1 - box.x0) / 2 / t.scaleX),\n Math.abs((box.y1 - box.y0) / 2 / t.scaleY)\n );\n for (const { nodeId, segmentIdx } of candidates) {\n const line = nodePositions[nodeId];\n if (!hits.has(nodeId) && segmentMeetsBox(\n screen(line[segmentIdx]),\n screen(line[segmentIdx + 1]),\n box\n )) {\n hits.add(nodeId);\n }\n }\n return hits;\n };\n}\nfunction findHoveredEdge(nodePositions, graph, graphX, graphY, axis, drawPaths, version = 0, deletions, hiddenEdges, deletionRoutes, stranded = false) {\n const yToX = yToXOf(axis);\n const edgeThreshold = 10 / axis.scaleX;\n const edgeIndex = getEdgeSpatialIndex(\n nodePositions,\n graph,\n drawPaths,\n axis,\n version,\n deletions,\n deletionRoutes,\n stranded\n );\n const candidates = edgeIndex.query(\n graphX,\n graphY,\n edgeThreshold,\n edgeThreshold / yToX\n );\n let hovered = null;\n let best = edgeThreshold;\n for (const edgeIdx of candidates) {\n const edge = graph.edges[edgeIdx];\n const fromSegments = nodePositions[edge.from];\n const toSegments = nodePositions[edge.to];\n if (!fromSegments?.length || !toSegments?.length || hiddenEdges?.has(edgeIdx)) {\n continue;\n }\n const numPaths = edge.pathIds?.length ?? 0;\n const baseCurves = edgeIndex.getCurves(edgeIdx);\n if (!baseCurves) {\n continue;\n }\n let dist;\n if (!drawPaths || numPaths === 0) {\n dist = distanceToEdgeCurves(graphX, graphY * yToX, baseCurves, yToX);\n } else {\n let minDist = Infinity;\n for (const offset of pathRibbonOffsets(\n fromSegments,\n toSegments,\n numPaths,\n axis\n )) {\n const curves = offset.x === 0 && offset.y === 0 ? baseCurves : translateCurves(baseCurves, offset.x, offset.y);\n const d = distanceToEdgeCurves(graphX, graphY * yToX, curves, yToX);\n if (d < minDist) {\n minDist = d;\n }\n }\n dist = minDist;\n }\n if (dist < best) {\n best = dist;\n hovered = edgeIdx;\n }\n }\n return hovered;\n}\n\nexport {\n distanceToSegment,\n distanceToCubicBezier,\n findHoveredNode,\n nodesUnderBox,\n findHoveredEdge\n};\n", "import {\n nodesUnderBox\n} from \"./chunk-4HWM3FNK.js\";\nimport {\n nodeLabelBudget,\n placeSizeLabels,\n rowLabelBox,\n sizeLabelCandidates\n} from \"./chunk-PTABFYQ7.js\";\nimport {\n LABEL_CHAR_PX,\n LABEL_PAD,\n LABEL_PX,\n occupancy,\n placeLabels\n} from \"./chunk-AB35TJST.js\";\n\n// src/labelLayout.ts\nvar HALO_FACTOR = 3.4;\nvar LEGEND_INSET_PX = 6;\nvar GENE_PIN_DROP_PX = 18;\nvar GENE_STACK = 2;\nvar BUBBLE_STACK = 3;\nvar TOPMOST_BASELINE = LABEL_PX + LABEL_PAD;\nfunction geneCoverageNote(pin) {\n const length = pin.gene.end - pin.gene.start;\n if (pin.covered >= 0.98) {\n return void 0;\n }\n const [per, unit] = length >= 1e6 ? [1e6, \"Mb\"] : length >= 1e3 ? [1e3, \"kb\"] : [1, \"bp\"];\n const amount = (bp) => +(bp / per).toFixed(per === 1 ? 0 : 1);\n return `${amount(pin.covered * length)} of ${amount(length)} ${unit}`;\n}\nfunction geneLabelCandidates(pins, screen, contigThickness, nodesUnder) {\n const ink = contigThickness / 2;\n return byExtent(pins, (pin) => pin.gene.end - pin.gene.start).map((pin) => {\n const { x, y } = screen(pin.at);\n const note = geneCoverageNote(pin);\n return {\n item: pin,\n x,\n y: y + contigThickness + GENE_PIN_DROP_PX,\n text: note ? `${pin.gene.name} \\xB7 ${note}` : pin.gene.name,\n fallback: note ? `${pin.gene.name} \\u2026` : void 0,\n stack: GENE_STACK,\n fits: (box) => [\n ...nodesUnder({\n x0: box.x0 - ink,\n x1: box.x1 + ink,\n y0: box.y0 - ink,\n y1: box.y1 + ink\n })\n ].every((id) => pin.nodeIds.has(id))\n };\n });\n}\nfunction byExtent(items, extent) {\n return [...items].sort((a, b) => extent(b) - extent(a));\n}\nfunction layoutLabels(m) {\n const { paneWidth: width, canvasHeight: height, translateX, translateY } = m;\n const { scaleX, scaleY } = m.axisScale;\n const frame = { width, height };\n const screen = (p) => ({\n x: p.x * scaleX + translateX,\n y: p.y * scaleY + translateY\n });\n const reserved = m.drawnRowLabels.map(\n ({ label, y }) => rowLabelBox(label, y * scaleY + translateY)\n );\n const stripPx = m.referenceStripZonePx ?? 0;\n if (stripPx > 0) {\n reserved.push({ x0: 0, x1: width, y0: 0, y1: stripPx });\n }\n if (m.legendSize.width > 0) {\n reserved.push({\n x0: width - LEGEND_INSET_PX - m.legendSize.width,\n x1: width,\n y0: 0,\n y1: stripPx + LEGEND_INSET_PX + m.legendSize.height\n });\n }\n if (m.poppedFrom) {\n reserved.push({\n x0: 0,\n x1: 60 + m.poppedFrom.label.length * LABEL_CHAR_PX * 1.2,\n y0: 0,\n y1: 44\n });\n }\n const take = occupancy(frame, reserved);\n const onRows = m.drawnRowLabels.length > 0;\n const rowsTop = onRows ? Math.min(...m.drawnRowLabels.map((r) => r.y)) : Infinity;\n const halo = m.contigThickness * HALO_FACTOR;\n const above = (h, gap) => {\n const { x, y } = screen({\n x: h.labelAt.x,\n y: Math.min(h.labelAt.y, rowsTop)\n });\n const baseline = y - halo / 2 - gap;\n return { x, y: onRows ? Math.max(baseline, TOPMOST_BASELINE) : baseline };\n };\n const byBubble = byExtent(\n m.bubbleHalos.filter((h) => !h.tick),\n (h) => h.whole ? -1 : h.members\n );\n const bubbles = placeLabels(\n byBubble.map((h) => ({\n item: h,\n ...above(h, 6),\n text: h.label,\n // `0 bp\u201311 kb superbubble` where `\u2026, 1198 segments, 5 routes` does not fit\n fallback: h.label.includes(\",\") ? h.label.split(\",\")[0] : void 0,\n stack: BUBBLE_STACK\n })),\n frame,\n take\n );\n const ticks = m.bubbleHalos.filter((h) => h.tick && !h.whole).map((h) => ({ item: h, ...above(h, 2) })).filter((t) => t.x >= 0 && t.x <= width && t.y >= 0 && t.y <= height);\n const genes = placeLabels(\n geneLabelCandidates(\n m.genePins,\n screen,\n m.contigThickness,\n nodesUnderBox(\n m.nodePositions ?? {},\n { scaleX, scaleY, translateX, translateY },\n m.positionsVersion\n )\n ),\n frame,\n take\n );\n const sizeCandidates = m.nodePositions && m.labelsNodeSizes ? sizeLabelCandidates({\n nodePositions: m.nodePositions,\n nodeLengths: m.nodeLengths,\n deletions: m.deletions,\n deletionRoutes: m.deletionRoutes,\n stranded: m.stranded,\n alleleDeletions: m.alleleDeletions,\n axis: m.axisScale,\n translateX,\n translateY,\n width,\n height,\n version: m.positionsVersion\n }) : { deletions: [], nodes: [] };\n const deletionLabels = placeSizeLabels(sizeCandidates.deletions, take);\n const nodeLabels = placeSizeLabels(\n sizeCandidates.nodes,\n take,\n nodeLabelBudget(width, height)\n );\n return {\n bubbles,\n ticks,\n genes,\n sizes: [...deletionLabels, ...nodeLabels]\n };\n}\n\nexport {\n HALO_FACTOR,\n LEGEND_INSET_PX,\n geneCoverageNote,\n geneLabelCandidates,\n layoutLabels\n};\n", "const host = JBrowseExports[\"mobx\"]\nconst read = name =>\n host != null && name in Object(host)\n ? host[name]\n : Object.assign(\n function () {\n throw new Error(\n \"This JBrowse does not provide '\" + name + \"' from '\" + \"mobx\" + \"' to plugins: GraphGenomeView was built for a different JBrowse version, so update the plugin or JBrowse\",\n )\n },\n { jbrowseHostMissing: name },\n )\nexport const $mobx = /* @__PURE__ */ read(\"$mobx\")\nexport const FlowCancellationError = /* @__PURE__ */ read(\"FlowCancellationError\")\nexport const ObservableMap = /* @__PURE__ */ read(\"ObservableMap\")\nexport const ObservableSet = /* @__PURE__ */ read(\"ObservableSet\")\nexport const Reaction = /* @__PURE__ */ read(\"Reaction\")\nexport const _allowStateChanges = /* @__PURE__ */ read(\"_allowStateChanges\")\nexport const _allowStateChangesInsideComputed = /* @__PURE__ */ read(\"_allowStateChangesInsideComputed\")\nexport const _allowStateReadsEnd = /* @__PURE__ */ read(\"_allowStateReadsEnd\")\nexport const _allowStateReadsStart = /* @__PURE__ */ read(\"_allowStateReadsStart\")\nexport const _autoAction = /* @__PURE__ */ read(\"_autoAction\")\nexport const _autoActionBound = /* @__PURE__ */ read(\"_autoActionBound\")\nexport const _endAction = /* @__PURE__ */ read(\"_endAction\")\nexport const _getAdministration = /* @__PURE__ */ read(\"_getAdministration\")\nexport const _getGlobalState = /* @__PURE__ */ read(\"_getGlobalState\")\nexport const _interceptReads = /* @__PURE__ */ read(\"_interceptReads\")\nexport const _isComputingDerivation = /* @__PURE__ */ read(\"_isComputingDerivation\")\nexport const _resetGlobalState = /* @__PURE__ */ read(\"_resetGlobalState\")\nexport const _startAction = /* @__PURE__ */ read(\"_startAction\")\nexport const action = /* @__PURE__ */ read(\"action\")\nexport const actionBound = /* @__PURE__ */ read(\"actionBound\")\nexport const autorun = /* @__PURE__ */ read(\"autorun\")\nexport const compareDefault = /* @__PURE__ */ read(\"compareDefault\")\nexport const compareIdentity = /* @__PURE__ */ read(\"compareIdentity\")\nexport const compareShallow = /* @__PURE__ */ read(\"compareShallow\")\nexport const compareStructural = /* @__PURE__ */ read(\"compareStructural\")\nexport const computed = /* @__PURE__ */ read(\"computed\")\nexport const computedStruct = /* @__PURE__ */ read(\"computedStruct\")\nexport const configure = /* @__PURE__ */ read(\"configure\")\nexport const createAtom = /* @__PURE__ */ read(\"createAtom\")\nexport const defineProperty = /* @__PURE__ */ read(\"defineProperty\")\nexport const entries = /* @__PURE__ */ read(\"entries\")\nexport const extendObservable = /* @__PURE__ */ read(\"extendObservable\")\nexport const flow = /* @__PURE__ */ read(\"flow\")\nexport const flowBound = /* @__PURE__ */ read(\"flowBound\")\nexport const flowResult = /* @__PURE__ */ read(\"flowResult\")\nexport const get = /* @__PURE__ */ read(\"get\")\nexport const getAtom = /* @__PURE__ */ read(\"getAtom\")\nexport const getDebugName = /* @__PURE__ */ read(\"getDebugName\")\nexport const getDependencyTree = /* @__PURE__ */ read(\"getDependencyTree\")\nexport const getObserverTree = /* @__PURE__ */ read(\"getObserverTree\")\nexport const has = /* @__PURE__ */ read(\"has\")\nexport const intercept = /* @__PURE__ */ read(\"intercept\")\nexport const isAction = /* @__PURE__ */ read(\"isAction\")\nexport const isBoxedObservable = /* @__PURE__ */ read(\"isBoxedObservable\")\nexport const isComputed = /* @__PURE__ */ read(\"isComputed\")\nexport const isComputedProp = /* @__PURE__ */ read(\"isComputedProp\")\nexport const isFlow = /* @__PURE__ */ read(\"isFlow\")\nexport const isFlowCancellationError = /* @__PURE__ */ read(\"isFlowCancellationError\")\nexport const isObservable = /* @__PURE__ */ read(\"isObservable\")\nexport const isObservableArray = /* @__PURE__ */ read(\"isObservableArray\")\nexport const isObservableMap = /* @__PURE__ */ read(\"isObservableMap\")\nexport const isObservableObject = /* @__PURE__ */ read(\"isObservableObject\")\nexport const isObservableProp = /* @__PURE__ */ read(\"isObservableProp\")\nexport const isObservableSet = /* @__PURE__ */ read(\"isObservableSet\")\nexport const keys = /* @__PURE__ */ read(\"keys\")\nexport const makeAutoObservable = /* @__PURE__ */ read(\"makeAutoObservable\")\nexport const makeObservable = /* @__PURE__ */ read(\"makeObservable\")\nexport const observable = /* @__PURE__ */ read(\"observable\")\nexport const observableDeep = /* @__PURE__ */ read(\"observableDeep\")\nexport const observableRef = /* @__PURE__ */ read(\"observableRef\")\nexport const observableShallow = /* @__PURE__ */ read(\"observableShallow\")\nexport const observableStruct = /* @__PURE__ */ read(\"observableStruct\")\nexport const observe = /* @__PURE__ */ read(\"observe\")\nexport const onBecomeObserved = /* @__PURE__ */ read(\"onBecomeObserved\")\nexport const onBecomeUnobserved = /* @__PURE__ */ read(\"onBecomeUnobserved\")\nexport const onReactionError = /* @__PURE__ */ read(\"onReactionError\")\nexport const override = /* @__PURE__ */ read(\"override\")\nexport const ownKeys = /* @__PURE__ */ read(\"ownKeys\")\nexport const reaction = /* @__PURE__ */ read(\"reaction\")\nexport const remove = /* @__PURE__ */ read(\"remove\")\nexport const runInAction = /* @__PURE__ */ read(\"runInAction\")\nexport const set = /* @__PURE__ */ read(\"set\")\nexport const spy = /* @__PURE__ */ read(\"spy\")\nexport const toJS = /* @__PURE__ */ read(\"toJS\")\nexport const transaction = /* @__PURE__ */ read(\"transaction\")\nexport const untracked = /* @__PURE__ */ read(\"untracked\")\nexport const values = /* @__PURE__ */ read(\"values\")\nexport const when = /* @__PURE__ */ read(\"when\")\nexport default host && host.__esModule ? host.default : host", "import {\n parseCs\n} from \"./chunk-C44YRP5F.js\";\n\n// src/tubeMap/reads.ts\nfunction canonicalStrand(node) {\n return node.id.endsWith(\"-\") ? \"-\" : \"+\";\n}\nfunction stepName(node, strand) {\n return strand === canonicalStrand(node) ? node.id : `-${node.id}`;\n}\nfunction stepStarts(lengths, total) {\n const starts = lengths.map(() => void 0);\n let head = 0;\n let i = 0;\n for (; i < lengths.length && lengths[i] !== void 0; i++) {\n starts[i] = head;\n head += lengths[i];\n }\n let tail = total;\n for (let j = lengths.length - 1; j > i && lengths[j] !== void 0; j--) {\n tail -= lengths[j];\n starts[j] = tail;\n }\n return starts;\n}\nfunction mismatchesByStep(record, lengths) {\n const byStep = record.path.map(() => []);\n if (record.cs === void 0) {\n return byStep;\n }\n const starts = stepStarts(lengths, record.pathLength);\n const known = starts.flatMap((start, s) => start === void 0 ? [] : [s]);\n const startOf = (k) => starts[known[k]];\n const endOf = (k) => startOf(k) + lengths[known[k]];\n let first = 0;\n const stepAt = (pos2, atEnd = false) => {\n while (first < known.length && endOf(first) < pos2) {\n first++;\n }\n for (let k = first; k < known.length && startOf(k) <= pos2; k++) {\n const end = endOf(k);\n if (pos2 < end || atEnd && pos2 === end) {\n return { s: known[k], local: pos2 - startOf(k), room: end - pos2 };\n }\n }\n return void 0;\n };\n const unplacedFrom = (pos2) => {\n for (let k = first; k < known.length; k++) {\n if (startOf(k) > pos2) {\n return startOf(k) - pos2;\n }\n }\n return Infinity;\n };\n const add = (s, mismatch) => {\n const list = byStep[s];\n const last = list.at(-1);\n if (mismatch.type === \"substitution\" && last?.type === \"substitution\" && last.pos + last.seq.length === mismatch.pos) {\n last.seq += mismatch.seq;\n } else {\n list.push(mismatch);\n }\n };\n let pos = record.pathStart;\n for (const op of parseCs(record.cs)) {\n if (op.op === \"match\") {\n pos += op.length;\n } else if (op.op === \"substitution\") {\n const at = stepAt(pos);\n if (at) {\n add(at.s, { type: \"substitution\", pos: at.local, seq: op.seq });\n }\n pos += 1;\n } else if (op.op === \"insertion\") {\n const at = stepAt(pos, pos === record.pathEnd);\n if (at) {\n add(at.s, { type: \"insertion\", pos: at.local, seq: op.seq });\n }\n } else {\n let left = op.length;\n while (left > 0) {\n const at = stepAt(pos);\n const take = Math.min(left, at ? at.room : unplacedFrom(pos));\n if (at) {\n add(at.s, { type: \"deletion\", pos: at.local, length: take });\n }\n pos += take;\n left -= take;\n }\n }\n }\n return byStep;\n}\nfunction tubeMapReads(graph, records, firstId) {\n const nodeByName = new Map(graph.nodes.map((n) => [n.name, n]));\n const reads = [];\n for (const record of records) {\n const nodes = record.path.map((step) => nodeByName.get(step.name));\n const kept = nodes.flatMap((node, i) => node ? [i] : []);\n const first = kept[0];\n const last = kept.at(-1);\n if (first !== void 0 && last !== void 0) {\n const mismatches = mismatchesByStep(\n record,\n nodes.map((n) => n?.length)\n );\n const names = kept.map((i) => stepName(nodes[i], record.path[i].strand));\n const lastLength = nodes[last].length;\n reads.push({\n id: firstId + reads.length,\n name: record.name,\n type: \"read\",\n sourceTrackID: 1,\n sequence: names,\n sequenceNew: kept.map((i, k) => ({\n nodeName: names[k],\n mismatches: mismatches[i]\n })),\n firstNodeOffset: first === 0 ? record.pathStart : 0,\n finalNodeCoverLength: last === record.path.length - 1 ? lastLength - (record.pathLength - record.pathEnd) : lastLength,\n // 255 is GAF's missing MAPQ\n mapping_quality: record.mappingQuality === 255 ? void 0 : record.mappingQuality,\n is_secondary: record.secondary,\n is_reverse: record.strand === \"-\"\n });\n }\n }\n return reads;\n}\nvar FORWARD_READ_COLORS = [\"#6baed6\", \"#4292c6\", \"#2171b5\", \"#08519c\"];\nvar REVERSE_READ_COLORS = [\"#fb6a4a\", \"#ef3b2c\", \"#cb181d\", \"#a50f15\"];\nfunction readColor(read) {\n const colors = read.is_reverse ? REVERSE_READ_COLORS : FORWARD_READ_COLORS;\n return colors[read.id % colors.length];\n}\n\nexport {\n canonicalStrand,\n stepName,\n tubeMapReads,\n FORWARD_READ_COLORS,\n REVERSE_READ_COLORS,\n readColor\n};\n", "import {\n REFERENCE_RAMP_MAX_HUE\n} from \"./chunk-A4PFFC4Q.js\";\n\n// src/referenceRampCss.ts\nfunction rampHueCss(hue) {\n return `hsl(${hue}, 70%, 50%)`;\n}\nfunction rampHue(bp, domain) {\n const frac = (bp - domain.start) / (domain.end - domain.start);\n return Math.max(0, Math.min(1, frac)) * REFERENCE_RAMP_MAX_HUE;\n}\nvar HUE_STOP_DEG = 30;\nfunction rampStops({ start, bp, reversed }, domain) {\n const low = rampHue(start, domain);\n const high = rampHue(start + bp, domain);\n if (high - low < 1) {\n return [(low + high) / 2];\n }\n const n = Math.ceil((high - low) / HUE_STOP_DEG);\n return Array.from(\n { length: n + 1 },\n (_, i) => rampHue(start + bp * (reversed ? n - i : i) / n, domain)\n );\n}\nvar RAMP_GRADIENT_STOPS = Array.from({ length: 7 }, (_, i) => ({\n offset: i / 6,\n color: rampHueCss(i / 6 * REFERENCE_RAMP_MAX_HUE)\n}));\nvar RAMP_GRADIENT_CSS = `linear-gradient(to right, ${RAMP_GRADIENT_STOPS.map(\n (s) => `${s.color} ${s.offset * 100}%`\n).join(\", \")})`;\n\nexport {\n rampHueCss,\n rampHue,\n rampStops,\n RAMP_GRADIENT_STOPS,\n RAMP_GRADIENT_CSS\n};\n", "// src/el.ts\nfunction el(tag, attrs = {}, ...children) {\n return {\n tag,\n attrs,\n children: children.filter((c) => !!c || c === \"\")\n };\n}\nfunction escapeText(s) {\n return s.replaceAll(\"&\", \"&\").replaceAll(\"<\", \"<\").replaceAll(\">\", \">\");\n}\nfunction escapeAttr(s) {\n return escapeText(s).replaceAll('\"', \""\");\n}\nfunction serializeEl(node) {\n if (typeof node === \"string\") {\n return escapeText(node);\n }\n const attrs = Object.entries(node.attrs).filter(([, v]) => v !== void 0).map(([k, v]) => ` ${k}=\"${escapeAttr(String(v))}\"`).join(\"\");\n return `<${node.tag}${attrs}>${node.children.map(serializeEl).join(\"\")}</${node.tag}>`;\n}\n\nexport {\n el,\n escapeAttr,\n serializeEl\n};\n", "import {\n RAMP_GRADIENT_CSS,\n RAMP_GRADIENT_STOPS,\n rampHueCss,\n rampStops\n} from \"./chunk-XL472HHD.js\";\nimport {\n el\n} from \"./chunk-H2H4Y3TV.js\";\nimport {\n REFERENCE_RAMP_ALT_CSS\n} from \"./chunk-A4PFFC4Q.js\";\nimport {\n LABEL_CHAR_PX\n} from \"./chunk-AB35TJST.js\";\nimport {\n ROW_HEIGHT_PX\n} from \"./chunk-CPMHA4W5.js\";\n\n// src/layout/walkRowDraw.ts\nvar ON_REFERENCE = \"#2f8fd6\";\nvar OFF_REFERENCE = \"#8e3fbf\";\nvar OUTSIDE_CUT = \"#bdbdbd\";\nvar GENE_INK = \"#1c1c22\";\nvar BAR_PX = 12;\nvar GAP_PX = 4;\nvar LABELLED_ROW_PX = 12;\nvar MIN_TILED_BAR_PX = 6;\nvar MIN_TILE_PX = 3;\nfunction kb(bp) {\n return `${(bp / 1e3).toFixed(bp < 1e4 ? 1 : 0)} kb`;\n}\nfunction signedLength(delta) {\n const size = Math.abs(delta);\n return `${delta > 0 ? \"+\" : \"\\u2212\"}${size < 1e3 ? `${size} bp` : kb(size)}`;\n}\nfunction units(bp, unit) {\n return unit ? ` \\u2248 ${Math.round(bp / unit)} units` : \"\";\n}\nfunction walkRowReadout(row, reference, unit, call) {\n const { bp, gapBp, complete, stop } = row;\n if (!reference) {\n return `${kb(bp)}${units(bp, unit)}`;\n }\n const outside = gapBp > 0 ? ` \\xB7 ${kb(gapBp)} outside the cut` : \"\";\n const called = call ? ` \\xB7 called ${kb(call.bp)}${call.spanningReads === 0 ? \" \\xB7 no spanning read\" : \"\"}` : \"\";\n if (complete) {\n const delta = bp - reference.bp;\n const against = delta === 0 ? \"\" : ` (${signedLength(delta)})`;\n return `${kb(bp)}${units(bp, unit)}${against}${outside}${called}`;\n }\n const region = unit ? \"repeat\" : \"window\";\n if (stop?.contigEnds && bp === 0) {\n const where = stop.shortBp > 0 ? `${kb(stop.shortBp)} before` : \"at\";\n return `contig ends ${where} the ${region}${called}`;\n }\n const why = !stop ? \"partial walk\" : stop.contigEnds ? `contig ends inside the ${region}` : \"does not rejoin the reference within the cut\";\n return `\\u2265 ${kb(bp)}${units(bp, unit)} \\xB7 ${why}${outside}${called}`;\n}\nfunction readoutPlacement(text, endX, width) {\n const x = endX + 6;\n const fits = x + text.length * LABEL_CHAR_PX < width;\n return fits ? { x, anchor: \"start\", halo: false } : { x: endX - 6, anchor: \"end\", halo: true };\n}\nfunction unitTicks(bp, unit, pxPerBp) {\n if (unit * pxPerBp < MIN_TILE_PX) {\n return [];\n }\n const ticks = [];\n for (let k = unit; k < bp; k += unit) {\n ticks.push(k);\n }\n return ticks;\n}\nfunction runPaint(run, ramp) {\n if (run.gap) {\n return { fill: OUTSIDE_CUT };\n }\n if (!ramp) {\n return { fill: run.onReference ? ON_REFERENCE : OFF_REFERENCE };\n }\n if (run.referenceStart === void 0) {\n return { fill: REFERENCE_RAMP_ALT_CSS };\n }\n const stops = rampStops({ ...run, start: run.referenceStart }, ramp);\n return stops.length === 1 ? { fill: rampHueCss(stops[0]) } : { stops: stops.map(rampHueCss) };\n}\nfunction alongRow(axis, start, end) {\n return axis.reversed ? { start: axis.start - end, end: axis.start - start } : { start: start - axis.start, end: end - axis.start };\n}\nfunction rowSpan(axis, bp) {\n return axis.reversed ? { start: axis.start - bp, end: axis.start } : { start: axis.start, end: axis.start + bp };\n}\nfunction genesOnRow(row, genes) {\n const contig = row.axis?.contig;\n return genes.filter(\n (g) => g.refName === contig || g.refName.endsWith(`#${contig}`)\n );\n}\nfunction placeRowGenes(rows, byRow) {\n const placed = /* @__PURE__ */ new Map();\n for (const row of rows) {\n const genes = byRow.get(row.name);\n if (!row.axis || !genes) {\n continue;\n }\n const axis = row.axis;\n const clip = ({ start, end }) => ({\n start: Math.max(0, start),\n end: Math.min(row.bp, end)\n });\n placed.set(\n row.name,\n genes.map((g) => ({\n name: g.name,\n ...clip(alongRow(axis, g.start, g.end)),\n exons: g.exons.map((e) => clip(alongRow(axis, e.start, e.end))).filter((e) => e.end > e.start)\n })).filter((g) => g.end > g.start).sort((a, b) => a.start - b.start)\n );\n }\n return placed;\n}\nvar GENE_FONT_PX = 9;\nvar GENE_CHAR_PX = 5.2;\nvar MIN_LETTERED_BAR_PX = 8;\nvar genePad = (rowPx, barPx) => Math.min(2, (rowPx - barPx) / 2 - 1);\nfunction boxesGenes(rowPx, barPx) {\n return genePad(rowPx, barPx) >= 1;\n}\nfunction rowGeneBoxes(genes, X, y, { rowPx = ROW_HEIGHT_PX, barPx = BAR_PX } = {}) {\n if (!boxesGenes(rowPx, barPx)) {\n return [];\n }\n const pad = genePad(rowPx, barPx);\n const boxes = genes.map((g) => {\n const x = X(g.start);\n return {\n g,\n x,\n w: Math.max(2, X(g.end) - x)\n };\n });\n const taken = [];\n const named = new Set(\n (barPx >= MIN_LETTERED_BAR_PX ? [...boxes] : []).sort((a, b) => a.w - b.w).filter(({ g, x, w }) => {\n const half = g.name.length * GENE_CHAR_PX / 2;\n const at = [x + w / 2 - half, x + w / 2 + half];\n if (2 * half > w + 6 || taken.some(([a, b]) => at[0] < b + 2 && at[1] > a - 2)) {\n return false;\n }\n taken.push(at);\n return true;\n })\n );\n return boxes.map((box) => ({\n name: box.g.name,\n x: box.x,\n y: y - barPx / 2 - pad,\n w: box.w,\n h: barPx + 2 * pad,\n exons: box.g.exons.map((e) => ({\n x: X(e.start),\n w: Math.max(1, X(e.end) - X(e.start))\n })),\n label: named.has(box) ? { x: box.x + box.w / 2, y: y + 3, size: GENE_FONT_PX } : void 0\n }));\n}\nvar rowsText = (n) => `${n} row${n === 1 ? \"\" : \"s\"}`;\nfunction walkRowsKey(bars, o = {}) {\n const entries = [\n {\n swatch: o.ramp ? { kind: \"bar\", fill: o.rampCss ?? RAMP_GRADIENT_CSS, ramp: true } : { kind: \"bar\", fill: ON_REFERENCE },\n label: `on ${bars.reference.label}'s path`\n },\n {\n swatch: {\n kind: \"bar\",\n fill: o.ramp ? REFERENCE_RAMP_ALT_CSS : OFF_REFERENCE\n },\n label: `off ${bars.reference.label}'s path`\n }\n ];\n if ([bars.reference, ...bars.rows].some((row) => row.gapBp > 0)) {\n entries.push({\n swatch: { kind: \"gap\", fill: OUTSIDE_CUT },\n label: \"walked outside the cut\"\n });\n }\n if (o.genes?.crowded) {\n entries.push({\n swatch: { kind: \"gene\" },\n label: \"genes left out: too many rows to box them in\",\n note: true\n });\n } else if (o.genes) {\n entries.push({\n swatch: { kind: \"gene\" },\n label: \"gene\"\n });\n if (o.genes.untracked) {\n entries.push({\n swatch: { kind: \"gene\" },\n label: `no gene track for ${rowsText(o.genes.untracked)}`,\n note: true\n });\n }\n if (o.genes.unplaced) {\n entries.push({\n swatch: { kind: \"gene\" },\n label: `no contig coordinates for ${rowsText(o.genes.unplaced)}`,\n note: true\n });\n }\n if (o.genes.unread) {\n entries.push({\n swatch: { kind: \"gene\" },\n label: `genes not read for the last ${rowsText(o.genes.unread)}`,\n note: true\n });\n }\n }\n return entries;\n}\nvar CALL_TICK = \"#111\";\nvar UNBACKED_TICK = \"#9e9e9e\";\nvar DISAGREES = \"#c62828\";\nfunction callTickInk(call) {\n return call.agrees === false ? DISAGREES : call.spanningReads === 0 ? UNBACKED_TICK : CALL_TICK;\n}\nfunction walkRowsKeyTree(entries, x, y, idPrefix = \"walk-key\") {\n let at = 0;\n const parts = entries.flatMap((e, i) => {\n const rampId = `${idPrefix}-ramp-${i}`;\n const ramp = !e.note && e.swatch.kind === \"bar\" && e.swatch.ramp ? el(\n \"linearGradient\",\n { id: rampId },\n ...RAMP_GRADIENT_STOPS.map(\n (s) => el(\"stop\", { offset: s.offset, \"stop-color\": s.color })\n )\n ) : void 0;\n const swatch = e.note ? void 0 : e.swatch.kind === \"gene\" ? el(\"rect\", {\n x: at,\n y: 5,\n width: 18,\n height: 8,\n fill: \"none\",\n stroke: GENE_INK,\n \"stroke-width\": 1.5\n }) : el(\"rect\", {\n x: at,\n y: e.swatch.kind === \"gap\" ? 7 : 5,\n width: 18,\n height: e.swatch.kind === \"gap\" ? GAP_PX : 8,\n rx: 2,\n fill: ramp ? `url(#${rampId})` : e.swatch.fill\n });\n const text = el(\n \"text\",\n {\n x: e.note ? at : at + 23,\n y: 13,\n \"font-style\": e.note ? \"italic\" : void 0,\n fill: e.note ? \"#666\" : void 0\n },\n e.label\n );\n at += (e.note ? 0 : 23) + e.label.length * LABEL_CHAR_PX + 16;\n return [ramp, swatch, text].filter((p) => p !== void 0);\n });\n return {\n width: at,\n tree: el(\n \"g\",\n {\n transform: `translate(${x} ${y})`,\n \"font-family\": \"Helvetica, Arial, sans-serif\",\n \"font-size\": 11\n },\n ...parts\n )\n };\n}\nfunction rowPitch(count, room, minRowPx = 0) {\n const fit = room / Math.max(1, count);\n const rowPx = Math.max(\n minRowPx,\n Math.min(ROW_HEIGHT_PX, fit >= 1 ? Math.floor(fit) : fit)\n );\n return {\n rowPx,\n barPx: rowPx <= 3 ? rowPx : Math.max(3, Math.round(rowPx * 0.6)),\n labelled: rowPx >= LABELLED_ROW_PX,\n readouts: rowPx >= LABELLED_ROW_PX\n };\n}\nfunction coalesceRuns(runs, pxPerBp) {\n const minBp = 1 / pxPerBp;\n const out = [];\n let bucket = [];\n const flush = () => {\n if (bucket.length === 0) {\n return;\n }\n if (bucket.length === 1) {\n out.push(bucket[0]);\n } else {\n let on = 0;\n let off = 0;\n for (const r of bucket) {\n if (r.onReference) {\n on += r.bp;\n } else {\n off += r.bp;\n }\n }\n const onReference = on >= off;\n const lead = bucket.find((r) => r.onReference === onReference);\n out.push({\n start: bucket[0].start,\n bp: on + off,\n onReference,\n referenceStart: onReference ? lead.referenceStart : void 0,\n ...lead.reversed ? { reversed: true } : {}\n });\n }\n bucket = [];\n };\n let held = 0;\n for (const run of runs) {\n if (run.gap || run.bp >= minBp) {\n flush();\n held = 0;\n out.push(run);\n continue;\n }\n bucket.push(run);\n held += run.bp;\n if (held >= minBp) {\n flush();\n held = 0;\n }\n }\n flush();\n return out;\n}\nfunction geneTree(box, y, barPx) {\n return el(\n \"g\",\n { class: \"row-gene\", \"data-testid\": \"graph-walk-gene\" },\n el(\"title\", {}, box.name),\n ...box.exons.map(\n (e) => el(\"rect\", {\n x: e.x,\n y: y - barPx / 2,\n width: e.w,\n height: barPx,\n fill: GENE_INK,\n opacity: 0.35\n })\n ),\n el(\"rect\", {\n x: box.x,\n y: box.y,\n width: box.w,\n height: box.h,\n fill: \"none\",\n stroke: GENE_INK,\n \"stroke-width\": 1.5\n }),\n box.label && el(\n \"text\",\n {\n x: box.label.x,\n y: box.label.y,\n \"font-family\": \"sans-serif\",\n \"font-size\": box.label.size,\n \"font-weight\": 600,\n \"text-anchor\": \"middle\",\n fill: GENE_INK,\n stroke: \"white\",\n \"stroke-width\": 2.5,\n \"paint-order\": \"stroke\"\n },\n box.name\n )\n );\n}\nfunction walkRowsTree(bars, frame, o = {}) {\n const X = (bp) => bp * frame.scaleX + frame.translateX;\n const rowPx = frame.rowPx ?? ROW_HEIGHT_PX;\n const barPx = frame.barPx ?? BAR_PX;\n const overhang = Math.min(3, Math.max(0, (rowPx - barPx) / 2));\n const Y = (row) => row * rowPx * frame.scaleY + frame.translateY;\n const { origin, unit, reference, rows } = bars;\n const along = (offset) => X(origin + offset);\n const prefix = o.idPrefix ?? \"walkrow\";\n const rowTree = (row, i) => {\n const y = Y(i);\n if (y < -barPx || y > frame.height + barPx) {\n return void 0;\n }\n const runs = coalesceRuns(row.runs, frame.scaleX).flatMap((run) => {\n const paint = runPaint(run, o.ramp);\n const h = run.gap ? Math.min(GAP_PX, barPx) : barPx;\n const id = `${prefix}-${i}-${run.start}`;\n const rect = el(\"rect\", {\n x: along(run.start),\n y: y - h / 2,\n width: Math.max(1, run.bp * frame.scaleX),\n height: h,\n fill: \"stops\" in paint ? `url(#${id})` : paint.fill\n });\n return \"stops\" in paint ? [\n el(\n \"linearGradient\",\n { id },\n ...paint.stops.map(\n (color, k) => el(\"stop\", {\n offset: k / (paint.stops.length - 1),\n \"stop-color\": color\n })\n )\n ),\n rect\n ] : [rect];\n });\n const ticks = unit && barPx >= MIN_TILED_BAR_PX ? unitTicks(row.bp, unit, frame.scaleX).map(\n (k) => el(\"line\", {\n x1: along(k),\n x2: along(k),\n y1: y - barPx / 2,\n y2: y + barPx / 2,\n stroke: \"white\",\n \"stroke-width\": 1\n })\n ) : [];\n const { call } = row;\n const text = walkRowReadout(\n row,\n i === 0 ? void 0 : reference,\n unit,\n call\n );\n const at = readoutPlacement(text, along(row.bp), frame.width);\n const readouts = frame.readouts ?? true;\n return el(\n \"g\",\n {\n \"data-testid\": i === 0 ? \"graph-walk-reference\" : \"graph-walk-row\"\n },\n ...runs,\n ...ticks,\n ...rowGeneBoxes(o.rowGenes?.get(row.name) ?? [], along, y, {\n rowPx,\n barPx\n }).map((box) => geneTree(box, y, barPx)),\n call && el(\"rect\", {\n \"data-testid\": \"graph-walk-call\",\n x: along(call.bp) - 1,\n y: y - barPx / 2 - overhang,\n width: 2,\n height: barPx + 2 * overhang,\n fill: callTickInk(call)\n }),\n readouts && el(\n \"text\",\n {\n x: at.x,\n y: y + 4,\n \"font-family\": \"sans-serif\",\n \"font-size\": 11,\n fill: call?.agrees === false ? DISAGREES : \"#333\",\n stroke: at.halo ? \"white\" : void 0,\n \"stroke-width\": at.halo ? 3 : void 0,\n \"paint-order\": \"stroke\",\n \"text-anchor\": at.anchor\n },\n text\n )\n );\n };\n return el(\"g\", {}, ...[reference, ...rows].map(rowTree));\n}\n\nexport {\n ON_REFERENCE,\n OFF_REFERENCE,\n OUTSIDE_CUT,\n GENE_INK,\n BAR_PX,\n GAP_PX,\n LABELLED_ROW_PX,\n kb,\n walkRowReadout,\n readoutPlacement,\n unitTicks,\n runPaint,\n alongRow,\n rowSpan,\n genesOnRow,\n placeRowGenes,\n boxesGenes,\n rowGeneBoxes,\n walkRowsKey,\n CALL_TICK,\n UNBACKED_TICK,\n DISAGREES,\n callTickInk,\n walkRowsKeyTree,\n rowPitch,\n coalesceRuns,\n walkRowsTree\n};\n", "import {\n SATURATED_PATH_COUNT\n} from \"./chunk-FX4RDMDN.js\";\nimport {\n formatBp\n} from \"./chunk-PTABFYQ7.js\";\n\n// src/bubbles/classifyBubble.ts\nvar REPEAT_GROWTH = 10;\nfunction coveringRepeat(b, repeats) {\n const span = b.end - b.start;\n const growth = b.longestAlleleLength - b.shortestAlleleLength;\n return repeats.find(\n (r) => growth <= REPEAT_GROWTH * (r.end - r.start) && (span === 0 ? r.start <= b.start && b.start <= r.end : Math.min(b.end, r.end) - Math.max(b.start, r.start) >= span / 2)\n );\n}\nvar SUPERBUBBLE_SEGMENTS = 40;\nfunction formatBpRange(shortest, longest) {\n const low = formatBp(shortest);\n const high = formatBp(longest);\n const unit = high.slice(high.indexOf(\" \"));\n return low.endsWith(unit) ? `${low.slice(0, -unit.length)}\\u2013${high}` : `${low}\\u2013${high}`;\n}\nfunction routes(count) {\n if (count >= SATURATED_PATH_COUNT) {\n return \"\\u22652.1B routes\";\n }\n if (count >= 1e5) {\n return `${(count / 1e3).toFixed(0)}k routes`;\n }\n return `${count} routes`;\n}\nfunction classifyBubble(b, repeats = []) {\n const c = classifyShape(b, repeats);\n return b.partial ? { ...c, label: `${c.label}, partial` } : c;\n}\nfunction classifyShape(b, repeats) {\n const refSpan = b.end - b.start;\n const {\n shortestAlleleLength: shortest,\n longestAlleleLength: longest,\n pathCount,\n segmentCount,\n inversion\n } = b;\n const range = formatBpRange(shortest, longest);\n if (segmentCount >= SUPERBUBBLE_SEGMENTS) {\n return {\n kind: \"superbubble\",\n label: `${range} superbubble, ${segmentCount} segments, ${routes(pathCount)}${inversion ? \", inv\" : \"\"}`\n };\n }\n if (inversion) {\n return { kind: \"inversion\", label: `${formatBp(longest)} inv` };\n }\n if (b.offReference) {\n return shortest === longest ? sameLength(shortest) : { kind: \"complex\", label: `${range}, ${routes(pathCount)}` };\n }\n const repeat = longest !== shortest ? coveringRepeat(b, repeats) : void 0;\n if (repeat) {\n const name = repeat.name ? ` (${repeat.name})` : \"\";\n return {\n kind: \"repeat\",\n label: `${range} repeat array${name}, ${routes(pathCount)}`\n };\n }\n const alleles = pathCount > 2 ? `, ${pathCount} alleles` : \"\";\n if (shortest === longest && shortest === refSpan) {\n return sameLength(refSpan);\n }\n if (refSpan === 0 || shortest === refSpan) {\n return {\n kind: \"insertion\",\n label: `\\u2264${formatBp(longest - refSpan)} ins${alleles}`\n };\n }\n if (longest === refSpan) {\n return {\n kind: \"deletion\",\n label: `${formatBp(refSpan - shortest)} del${alleles}`\n };\n }\n return {\n kind: \"complex\",\n label: `${formatBp(refSpan)} ref \\u2192 ${range}, ${pathCount} alleles`\n };\n}\nfunction sameLength(bp) {\n return bp <= 1 ? { kind: \"snp\", label: \"SNP\" } : { kind: \"substitution\", label: `${formatBp(bp)} sub` };\n}\nvar BUBBLE_KIND_COLORS = {\n snp: \"#5b6b7a\",\n substitution: \"#5b6b7a\",\n insertion: \"#2f8fd6\",\n deletion: \"#c94040\",\n inversion: \"#e07b00\",\n repeat: \"#8e3fbf\",\n superbubble: \"#8e3fbf\",\n complex: \"#8e3fbf\"\n};\nvar BUBBLE_KIND_NAMES = {\n snp: \"SNP\",\n substitution: \"substitution\",\n insertion: \"insertion\",\n deletion: \"deletion\",\n inversion: \"inversion\",\n repeat: \"repeat array\",\n superbubble: \"superbubble\",\n complex: \"site\"\n};\nfunction bubbleSegmentIds(b) {\n return b.segments.split(\",\").filter(Boolean);\n}\n\nexport {\n classifyBubble,\n BUBBLE_KIND_COLORS,\n BUBBLE_KIND_NAMES,\n bubbleSegmentIds\n};\n", "import {\n formatBp\n} from \"./chunk-PTABFYQ7.js\";\nimport {\n isBackbone\n} from \"./chunk-FYQWPEEY.js\";\n\n// src/tubeMap/axis.ts\nfunction referenceBoxes({\n graph,\n layout\n}) {\n const nodeById = new Map(graph.nodes.map((n) => [n.id, n]));\n const byRefName = /* @__PURE__ */ new Map();\n layout.nodes.forEach((node, index) => {\n const graphNode = nodeById.get(node.name);\n if (node.order >= 0 && graphNode && isBackbone(graphNode)) {\n const { refName, start } = graphNode.stable;\n const boxes = byRefName.get(refName) ?? byRefName.set(refName, []).get(refName);\n boxes.push({\n name: node.name,\n index,\n bp0: start,\n bp1: start + graphNode.length,\n x0: node.x,\n x1: node.x + node.pixelWidth\n });\n }\n });\n for (const boxes of byRefName.values()) {\n boxes.sort((a, b) => a.bp0 - b.bp0);\n }\n return byRefName;\n}\nfunction tubeX(boxes, bp, isEnd = false) {\n let lo = 0;\n let hi = boxes.length - 1;\n while (lo < hi) {\n const mid = lo + hi >> 1;\n const bp1 = boxes[mid].bp1;\n if (isEnd ? bp1 < bp : bp1 <= bp) {\n lo = mid + 1;\n } else {\n hi = mid;\n }\n }\n const box = boxes[lo];\n if (bp <= box.bp0) {\n return box.x0;\n }\n const span = box.bp1 - box.bp0;\n return span > 0 ? box.x0 + (Math.min(bp, box.bp1) - box.bp0) / span * (box.x1 - box.x0) : box.x0;\n}\nfunction tubeSpan(boxes, start, end) {\n const a = tubeX(boxes, start);\n const b = tubeX(boxes, end, true);\n return { x0: Math.min(a, b), x1: Math.max(a, b) };\n}\nfunction rulerBoxes(byRefName) {\n let best;\n for (const boxes of byRefName.values()) {\n if (!best || boxes.length > best.length) {\n best = boxes;\n }\n }\n return best;\n}\nvar TICK_PX = 5;\nvar LABEL_GAP_PX = 10;\nvar TARGET_TICK_PX = 110;\nvar MIN_BRACKET_PX = 3;\nfunction rulerInk(darkMode) {\n return darkMode ? \"#b0b0b8\" : \"#55555c\";\n}\nfunction niceStep(raw) {\n const pow = 10 ** Math.floor(Math.log10(raw));\n const m = raw / pow;\n return (m <= 1 ? 1 : m <= 2 ? 2 : m <= 5 ? 5 : 10) * pow;\n}\nfunction placeLabels(candidates) {\n const placed = [];\n for (const a of candidates) {\n if (placed.every(\n (b) => Math.abs(a.at - b.at) >= (a.width + b.width) / 2 + LABEL_GAP_PX\n )) {\n placed.push(a);\n }\n }\n return placed.map(({ text, at }) => ({ text, at }));\n}\nfunction scaleMarks(boxes, x, width, measure) {\n const first = boxes[0];\n const last = boxes.at(-1);\n if (!first || !last) {\n return void 0;\n }\n const from = x(first.x0);\n const to = x(last.x1);\n const bpSpan = last.bp1 - first.bp0;\n if (to <= from || bpSpan <= 0) {\n return void 0;\n }\n const step = niceStep(bpSpan / (to - from) * TARGET_TICK_PX);\n const ticks = [];\n const positions = [];\n for (let bp = Math.ceil(first.bp0 / step) * step; bp <= last.bp1; bp += step) {\n const sx = Math.round(x(tubeX(boxes, bp))) + 0.5;\n if (sx >= 0 && sx <= width) {\n ticks.push(sx);\n const text = bp.toLocaleString(\"en-US\");\n positions.push({ text, at: sx, width: measure(text) });\n }\n }\n return {\n spans: [{ x0: from, x1: to }],\n ticks,\n labels: placeLabels(positions)\n };\n}\nfunction boxMarks(boxes, x, width, measure) {\n const shown = boxes.map((box) => ({ box, s0: x(box.x0), s1: x(box.x1) })).filter(({ s0, s1 }) => s1 >= 0 && s0 <= width);\n const first = shown[0];\n const last = shown.at(-1);\n if (!first || !last) {\n return void 0;\n }\n const label = (text, at) => ({\n text,\n at,\n width: measure(text)\n });\n const position = (bp, at) => label(bp.toLocaleString(\"en-US\"), at);\n const spans = [];\n const ticks = [];\n const lengths = [];\n const boundaries = [];\n for (const { box, s0, s1 } of shown) {\n spans.push({ x0: s0, x1: s1 });\n ticks.push(Math.round(s0) + 0.5);\n if (s1 - s0 >= MIN_BRACKET_PX) {\n ticks.push(Math.round(s1) + 0.5);\n }\n const length = label(formatBp(box.bp1 - box.bp0), (s0 + s1) / 2);\n if (length.width <= s1 - s0) {\n lengths.push(length);\n }\n if (box !== first.box) {\n boundaries.push(position(box.bp0, s0));\n }\n }\n const ends = [\n position(first.box.bp0, first.s0),\n position(last.box.bp1, last.s1)\n ];\n return {\n spans,\n ticks,\n labels: placeLabels([...ends, ...lengths, ...boundaries])\n };\n}\nfunction rulerMarks(boxes, x, width, measure, referenceAxis = false) {\n return (referenceAxis ? scaleMarks : boxMarks)(boxes, x, width, measure);\n}\nfunction drawTubeMapRuler(ctx, boxes, frame, top, referenceAxis = false) {\n const { x, width, darkMode } = frame;\n ctx.font = \"10px sans-serif\";\n const marks = rulerMarks(\n boxes,\n x,\n width,\n (text) => ctx.measureText(text).width,\n referenceAxis\n );\n if (!marks) {\n return;\n }\n const ink = rulerInk(darkMode);\n const y = top + 0.5;\n ctx.strokeStyle = ink;\n ctx.fillStyle = ink;\n ctx.lineWidth = 1;\n ctx.textAlign = \"center\";\n ctx.textBaseline = \"top\";\n ctx.beginPath();\n for (const { x0, x1 } of marks.spans) {\n ctx.moveTo(Math.max(0, x0), y);\n ctx.lineTo(Math.min(width, x1), y);\n }\n for (const sx of marks.ticks) {\n ctx.moveTo(sx, top);\n ctx.lineTo(sx, top + TICK_PX);\n }\n ctx.stroke();\n for (const { text, at } of marks.labels) {\n ctx.fillText(text, at, top + TICK_PX + 2);\n }\n}\n\nexport {\n referenceBoxes,\n tubeX,\n tubeSpan,\n rulerBoxes,\n rulerInk,\n rulerMarks,\n drawTubeMapRuler\n};\n", "// src/tubeMap/connectors.ts\nfunction tubeMapConnectors(boxes, bpToScreen, tubeToScreen, width) {\n const out = [];\n for (const box of boxes) {\n const bottom0 = tubeToScreen(box.x0);\n const bottom1 = tubeToScreen(box.x1);\n if (bottom1 >= 0 && bottom0 <= width) {\n out.push({\n node: box.name,\n top0: bpToScreen(box.bp0),\n top1: bpToScreen(box.bp1),\n bottom0,\n bottom1\n });\n }\n }\n return out;\n}\nvar HIT_SLOP_PX = 3;\nfunction connectorAt(connectors, zoneBottom, sx, sy) {\n if (zoneBottom <= 0 || sy < 0 || sy > zoneBottom) {\n return void 0;\n }\n const t = sy / zoneBottom;\n let hit;\n let best = HIT_SLOP_PX;\n for (const c of connectors) {\n const a = c.top0 + (c.bottom0 - c.top0) * t;\n const b = c.top1 + (c.bottom1 - c.top1) * t;\n const dist = Math.max(0, Math.min(a, b) - sx, sx - Math.max(a, b));\n if (dist < best) {\n best = dist;\n hit = c.node;\n }\n }\n return hit;\n}\nfunction band(ctx, c, bottom) {\n ctx.moveTo(c.top0, 0);\n ctx.lineTo(c.top1, 0);\n ctx.lineTo(c.bottom1, bottom);\n ctx.lineTo(c.bottom0, bottom);\n ctx.closePath();\n}\nfunction sides(ctx, c, bottom) {\n ctx.moveTo(c.top0, 0);\n ctx.lineTo(c.bottom0, bottom);\n ctx.moveTo(c.top1, 0);\n ctx.lineTo(c.bottom1, bottom);\n}\nfunction drawTubeMapConnectors(ctx, connectors, bottom, {\n highlightNode,\n darkMode\n}) {\n if (bottom <= 0 || connectors.length === 0) {\n return;\n }\n const ink = darkMode ? \"255,255,255\" : \"0,0,0\";\n ctx.beginPath();\n for (const c of connectors) {\n band(ctx, c, bottom);\n }\n ctx.fillStyle = `rgba(${ink},0.07)`;\n ctx.fill();\n ctx.beginPath();\n for (const c of connectors) {\n sides(ctx, c, bottom);\n }\n ctx.strokeStyle = `rgba(${ink},0.35)`;\n ctx.lineWidth = 0.5;\n ctx.stroke();\n drawLitConnector(ctx, connectors, bottom, highlightNode);\n}\nfunction drawLitConnector(ctx, connectors, bottom, node) {\n const lit = bottom > 0 && node ? connectors.find((c) => c.node === node) : void 0;\n if (lit) {\n ctx.beginPath();\n band(ctx, lit, bottom);\n ctx.fillStyle = \"rgba(255,192,203,0.5)\";\n ctx.fill();\n ctx.beginPath();\n sides(ctx, lit, bottom);\n ctx.strokeStyle = \"#ff0000\";\n ctx.lineWidth = 1;\n ctx.stroke();\n }\n}\n\nexport {\n tubeMapConnectors,\n connectorAt,\n drawTubeMapConnectors,\n drawLitConnector\n};\n", "import {\n referenceBoxes\n} from \"../chunks/chunk-XMW266WS.js\";\nimport \"../chunks/chunk-PTABFYQ7.js\";\nimport \"../chunks/chunk-AB35TJST.js\";\nimport \"../chunks/chunk-N73TI3VG.js\";\nimport \"../chunks/chunk-24WITXQY.js\";\nimport \"../chunks/chunk-7SRWJLSC.js\";\nimport \"../chunks/chunk-CPMHA4W5.js\";\nimport \"../chunks/chunk-FYQWPEEY.js\";\n\n// src/tubeMap/deviations.ts\nfunction boxAt(boxes, bp, visited) {\n let lo = 0;\n let hi = boxes.length - 1;\n while (lo < hi) {\n const mid = lo + hi + 1 >> 1;\n if (boxes[mid].bp0 <= bp) {\n lo = mid;\n } else {\n hi = mid - 1;\n }\n }\n return [boxes[lo], boxes[lo - 1]].find(\n (box) => box && visited.has(box.index) && box.bp0 <= bp && bp <= box.bp1\n );\n}\nfunction deviationMarks(drawing, deviations) {\n const { layout } = drawing;\n const boxes = [...referenceBoxes(drawing).values()].flat().sort((a, b) => a.bp0 - b.bp0);\n const marks = [];\n for (const track of layout.tracks) {\n const devs = track.name ? deviations.get(track.name) : void 0;\n if (devs?.length) {\n const visited = /* @__PURE__ */ new Map();\n for (const segment of track.path) {\n if (segment.node !== null && segment.y !== void 0 && !visited.has(segment.node)) {\n visited.set(segment.node, segment.y);\n }\n }\n for (const d of devs) {\n const box = boxAt(boxes, d.start, visited);\n if (box) {\n const { bp0, bp1, x0, x1, index } = box;\n const at = (bp) => x0 + (Math.min(bp, bp1) - bp0) / (bp1 - bp0) * (x1 - x0);\n marks.push({\n x0: at(d.start),\n x1: at(d.end),\n y: visited.get(index),\n height: track.width\n });\n }\n }\n }\n }\n return marks;\n}\nfunction deviationInk(darkMode) {\n return darkMode ? \"rgba(255,255,255,0.9)\" : \"rgba(0,0,0,0.8)\";\n}\nfunction drawDeviationMarks(ctx, marks, { x, y, width, darkMode }) {\n if (marks.length === 0) {\n return;\n }\n ctx.fillStyle = deviationInk(darkMode);\n ctx.beginPath();\n for (const m of marks) {\n const left = x(m.x0);\n const right = Math.max(x(m.x1), left + 1);\n if (right >= 0 && left <= width) {\n const top = y(m.y);\n ctx.rect(left, top, right - left, y(m.y + m.height) - top);\n }\n }\n ctx.fill();\n}\nexport {\n deviationInk,\n deviationMarks,\n drawDeviationMarks\n};\n", "export type MismatchType = 'insertion' | 'deletion' | 'substitution'\n\nexport interface Mismatch {\n type: MismatchType\n pos: number\n seq?: string\n length?: number\n}\n\nexport interface ReadSequenceEntry {\n nodeName: string\n mismatches: Mismatch[]\n}\n\nexport type TrackType = 'haplotype' | 'read'\n\nexport interface TrackRectangle {\n xStart: number\n yStart: number\n xEnd: number\n yEnd: number\n id: number\n name?: string | undefined\n type?: TrackType | undefined\n}\n\nexport interface TrackCurve {\n xStart: number\n yStart: number\n xEnd: number\n yEnd: number\n width: number\n id: number\n name?: string | undefined\n type?: TrackType | undefined\n // the nodes the curve leaves and enters, null at a gap in a track's path\n nodeStart: number | null\n nodeEnd: number | null\n // the order slots it leaves and enters\n orderStart: number\n orderEnd: number\n // a curve of track 0, the reference, which a steep gap gives its width first\n reference?: boolean\n path?: string\n}\n\nexport interface TrackCorner {\n path: string\n id: number\n name?: string | undefined\n type?: TrackType | undefined\n}\n\nexport interface Segment {\n order: number\n lane?: number\n isForward: boolean\n node: number | null\n y?: number\n betweenCycleReverseTraversal?: boolean\n}\n\n// Loose input shape: just the basics produced by vgExtractTracks /\n// vgExtractReads. Layout passes accrete indexSequence / path / width.\nexport interface InputTrack {\n id: number\n name?: string\n sequence: string[]\n type?: TrackType\n freq?: number\n hidden?: boolean\n sourceTrackID: number\n indexOfFirstBase?: number\n isCompletelyReverse?: boolean\n // Read-specific fields populated by vgExtractReads.\n sequenceNew?: ReadSequenceEntry[]\n firstNodeOffset?: number\n finalNodeCoverLength?: number\n mapping_quality?: number\n is_secondary?: boolean\n is_reverse?: boolean\n sample_name?: string | null\n read_group?: string | null\n cigar_string?: string\n score?: number\n}\n\n// How many of the banded haplotypes take a coarsened band\nexport interface HaplotypeShare {\n count: number\n total: number\n}\n\n// Layout-complete track shape, as layoutTubeMap returns it.\nexport interface Track extends InputTrack {\n indexSequence: number[]\n path: Segment[]\n width: number\n haplotypeShare?: HaplotypeShare | undefined\n}\n\n// Loose input shape passed to layoutTubeMap. Its passes (generateNodeWidth \u2192\n// generateNodeOrder \u2192 generateLaneAssignment \u2192 generateNodeXCoords) accrete\n// more fields, producing the full `Node` below. A graph fetched with\n// removeSequences has no seq, and sequenceLength defaults to seq's length.\nexport interface InputNode {\n name: string\n seq?: string\n sequenceLength?: number\n}\n\n// Layout-complete node \u2014 fields used by drawing code after the pipeline.\n// (Marked optional only for the genuinely conditional fields like switched/d.)\n// layoutTubeMap fills in seq, as '' when the input had none, and\n// sequenceLength.\nexport interface Node extends InputNode {\n seq: string\n sequenceLength: number\n width: number\n pixelWidth: number\n order?: number | undefined\n y: number\n contentHeight: number\n x: number\n topLane: number\n successors: number[]\n predecessors: number[]\n tracks: number[]\n degree: number\n switched?: boolean\n incomingReads: [number, number][]\n outgoingReads: [number, number][]\n internalReads: number[]\n d?: string\n}\n\n// Node after generateNodeOrder() has run \u2014 order is guaranteed to be set.\nexport interface LayoutNode extends Node {\n order: number\n}\n\nexport interface SegmentAssignment {\n trackID: number\n segmentID: number\n compareToFromSame: SegmentAssignment | null\n idealLane?: number | undefined\n idealY?: number | null | undefined\n lane?: number\n}\n\nexport interface NodeAssignment {\n type: 'single' | 'multiple'\n node: number | null\n tracks: SegmentAssignment[]\n idealLane?: number | undefined\n}\n\n// Drawing instructions from one layout, in layout coordinates.\nexport interface TrackShapes {\n rectangles: TrackRectangle[]\n curves: TrackCurve[]\n corners: TrackCorner[]\n // drawn separately so they don't overlap the horizontal rectangles\n verticalRectangles: TrackRectangle[]\n}\n\nexport function emptyTrackShapes(): TrackShapes {\n return {\n rectangles: [],\n curves: [],\n corners: [],\n verticalRectangles: [],\n }\n}\n\n// The extent of the drawn content, in layout coordinates.\nexport interface ImageBounds {\n minX: number\n maxX: number\n minY: number\n maxY: number\n}\n", "// A PanSN path name: sample#haplotype#contig, sometimes with further\n// #-separated fields such as a fragment offset after the contig.\n// https://github.com/pangenome/PanSN-spec\nexport interface PanSNName {\n sample: string\n haplotype: number\n contig: string\n}\n\n// gbz-base names a generic reference `_gbwt_ref#0#contig` and a haplotype the\n// GBWT kept no metadata for `unknown#N#contig`; neither names a sample.\nconst NOT_SAMPLES = new Set(['_gbwt_ref', 'unknown'])\n\n// The sample, haplotype and contig of a PanSN name, or undefined for any other\n// name: fewer than three fields, an empty sample or contig, a haplotype that\n// isn't a whole number, or a placeholder sample.\nexport function parsePanSN(name: string | undefined): PanSNName | undefined {\n const [sample, haplotype, contig] = name?.split('#') ?? []\n if (\n sample === undefined ||\n sample === '' ||\n NOT_SAMPLES.has(sample) ||\n haplotype === undefined ||\n !/^\\d+$/.test(haplotype) ||\n contig === undefined ||\n contig === ''\n ) {\n return undefined\n }\n return { sample, haplotype: Number(haplotype), contig }\n}\n", "// The tube map layout, from input nodes and tracks to drawable shapes. Ported\n// from the original sequenceTubeMap JS, where it shared one module with the d3\n// drawing. It runs in two phases, each on a fresh LayoutState: layoutTopology\n// merges, orders, orients and sizes the nodes and fixes their x, and\n// placeTubeMap stacks a chosen set of tracks and reads on that topology.\nimport { parsePanSN } from './panSN.ts'\nimport { emptyTrackShapes } from './types.ts'\n\nimport type {\n HaplotypeShare,\n ImageBounds,\n InputNode,\n InputTrack,\n LayoutNode,\n Mismatch,\n Node,\n NodeAssignment,\n ReadSequenceEntry,\n Segment,\n SegmentAssignment,\n Track,\n TrackShapes,\n TrackType,\n} from './types.ts'\n\nconst DEBUG = false as boolean\n\nfunction debugLog(...args: unknown[]): void {\n if (DEBUG) {\n // eslint-disable-next-line no-console\n console.log(...args)\n }\n}\n\n// Node and Track declare some fields that not every entry gets: layout places\n// only the nodes a track or read reaches, and a normal read has no width until\n// assignReadsToNodes.\ntype MaybeUnset<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>\ntype MaybeUnplacedNode = MaybeUnset<LayoutNode, 'x' | 'y'>\n\nexport type NodeWidthOption = 'normal' | 'compressed' | 'small' | 'fixed'\n\n// The fields of a placed track a renderer colors it by. Shapes carry only the\n// track's id, so a renderer can recolor without laying out again.\nexport interface ColorableTrack {\n id: number\n sourceTrackID: number\n type?: TrackType\n name?: string\n mapping_quality?: number\n is_reverse?: boolean\n haplotypeShare?: HaplotypeShare\n}\n\nexport type LayerData = 'haplotypes' | 'reads'\n\n// A track set placement draws, and the stat it runs first. `coarsen` turns\n// the set into one band per edge; banded haplotypes keep the reference's lane.\nexport interface Layer {\n data: LayerData\n stat?: 'coarsen'\n}\n\n// The options a topology fixes. trackWidth, the layers and ignoreStrand leave\n// node order alone, but the topology measures x from placing every track and\n// read under them.\nexport interface TopologyOptions {\n mergeNodes?: boolean\n showReads?: boolean\n // Shorthand for `layers` when those are unset: band the reads, or the\n // haplotypes when no reads were loaded\n coarsenedReadView?: boolean\n // The haplotypes draw first and the reads stack under them, each data under\n // the stat of its first layer here\n layers?: readonly Layer[]\n ignoreStrand?: boolean\n // normal: width is sequence length, at `charWidth` per base\n // compressed: log2 of sequence length\n // small: 1% of sequence length\n // fixed: every node one width\n nodeWidthOption?: NodeWidthOption\n charWidth?: number\n // a haplotype tube's width in layout px, where no `freq` scales it\n trackWidth?: number\n // how `freq` widens a tube: log grows slowly, as sequenceTubeMap draws vg's\n // frequencies; linear makes a walk standing for n haplotypes n tubes wide,\n // so widths compare as counts\n freqWidth?: 'log' | 'linear'\n}\n\nexport const READ_FACET_FIELDS = ['read_group', 'sample_name'] as const\nexport type ReadFacetBy = (typeof READ_FACET_FIELDS)[number]\n// A read field, or the sample in the haplotypes' PanSN names\nexport const FACET_FIELDS = [...READ_FACET_FIELDS, 'haplotype_sample'] as const\nexport type FacetBy = (typeof FACET_FIELDS)[number]\n\n// One panel's subset. A read facet keeps every haplotype and the reads whose\n// `by` field is `key`, or that lack one when `key` is null. A haplotype facet\n// keeps the reference and no reads, plus the haplotypes of sample `key`, or\n// those with no PanSN sample when `key` is null; its `reads` panel keeps the\n// reference and the reads.\nexport interface ReadFacet {\n by: ReadFacetBy\n key: string | null\n}\nexport type HaplotypeFacet =\n | { by: 'haplotype_sample'; key: string | null }\n | { by: 'haplotype_sample'; reads: true }\nexport type Facet = ReadFacet | HaplotypeFacet\n\n// Which of a topology's tracks and reads a placement draws\nexport interface PlacementOptions {\n mappingQualityCutoff?: number\n focusReadNames?: string[] | null\n facet?: Facet | undefined\n}\n\nexport interface FacetOptions extends PlacementOptions {\n // One panel per value of this field\n facetBy?: FacetBy | null\n}\n\nexport interface LayoutOptions extends TopologyOptions, PlacementOptions {}\n\nexport type CoarsenedUnit = 'read' | 'haplotype'\n\n// A coarsened band's count of contributing reads or haplotypes and its label,\n// keyed by the band's synthetic track id, unique across layers\nexport interface CoarsenedEdgeMeta {\n count: number\n label: string\n}\n\n// What a layer's coarsening drew as bands, how many reads or haplotypes it\n// banded (counting a deduplicated walk `freq` times), and whether any band\n// runs reverse-strand\nexport interface Coarsening {\n unit: CoarsenedUnit\n total: number\n reverse: boolean\n}\n\n// Each layer that drew bands, by its data\nexport type Coarsenings = Partial<Record<LayerData, Coarsening>>\n\nexport interface TubeMapLayout {\n // 1-indexed with a hole at 0: a signed index\n // is an oriented visit, and 0 has no sign\n nodes: LayoutNode[]\n // the haplotype tracks and placed reads together, sorted by where each\n // first meets the others, which is the order their shapes were made in\n tracks: Track[]\n // the placed reads alone\n reads: Track[]\n nodeMap: ReadonlyMap<string, number>\n shapes: TrackShapes\n bounds: ImageBounds\n maxOrder: number\n // the name of the track that carries a coordinate for the ruler\n trackForRuler: string | undefined\n coarsenedEdgeMeta: Map<number, CoarsenedEdgeMeta>\n coarsened: Coarsenings\n}\n\n// A node before placement gives it a y and the reads through it\nexport type TopologyNode = Omit<\n LayoutNode,\n | 'y'\n | 'contentHeight'\n | 'topLane'\n | 'incomingReads'\n | 'outgoingReads'\n | 'internalReads'\n>\n\n// A haplotype or read before placement gives it a width and lanes\nexport type TopologyTrack = Omit<Track, 'path' | 'width'>\n\n// What every placement of one input shares: the merged, ordered and oriented\n// nodes with their widths and x positions, and the oriented haplotypes and\n// reads. A placement reads it and never changes it.\nexport interface TubeMapTopology {\n options: Required<TopologyOptions>\n // 1-indexed with a hole at 0, like TubeMapLayout.nodes. A node no track or\n // read reaches has order UNREACHABLE_ORDER and no x.\n nodes: readonly TopologyNode[]\n // the visible haplotypes, track 0 read left to right\n tracks: readonly TopologyTrack[]\n // every primary alignment that shares a node with a track, unfiltered\n reads: readonly TopologyTrack[]\n nodeMap: ReadonlyMap<string, number>\n maxOrder: number\n trackForRuler: string | undefined\n}\n\ntype LayoutConfig = Required<TopologyOptions>\n\n// The coarsened view bands haplotypes only when no reads were loaded, not when\n// a filter hides them all\nfunction layersFrom(\n { layers, coarsenedReadView = false, showReads = true }: TopologyOptions,\n hasReads: boolean,\n): readonly Layer[] {\n if (layers !== undefined) {\n return layers\n }\n const coarsen = coarsenedReadView && showReads\n const stat = (banded: boolean): Pick<Layer, 'stat'> =>\n banded ? { stat: 'coarsen' } : {}\n return [\n { data: 'haplotypes', ...stat(coarsen && !hasReads) },\n { data: 'reads', ...stat(coarsen && hasReads) },\n ]\n}\n\nfunction statOf(layers: readonly Layer[], data: LayerData) {\n return layers.find(layer => layer.data === data)?.stat\n}\n\nfunction configFrom(options: TopologyOptions, hasReads: boolean): LayoutConfig {\n return {\n mergeNodes: options.mergeNodes ?? true,\n showReads: options.showReads ?? true,\n coarsenedReadView: options.coarsenedReadView ?? false,\n layers: layersFrom(options, hasReads),\n ignoreStrand: options.ignoreStrand ?? false,\n nodeWidthOption: options.nodeWidthOption ?? 'normal',\n charWidth: options.charWidth ?? 8.401,\n trackWidth: options.trackWidth ?? 15,\n freqWidth: options.freqWidth ?? 'log',\n }\n}\n\n// The working state of one topology or placement, shared by its passes.\ninterface LayoutState {\n config: LayoutConfig\n // Sparse like TubeMapLayout.nodes, but forEach, map and sort skip the hole\n // and noUncheckedIndexedAccess already types indexed reads as possibly\n // undefined, so only for...of would ever see it.\n nodes: LayoutNode[]\n // Each track's `path` lists the Segments to draw, in order along the path.\n tracks: Track[]\n // Reads have a `path` too, but stack vertically by a different system.\n reads: Track[]\n nodeMap: ReadonlyMap<string, number>\n nodesPerOrder: number[][]\n // generateNodeOrder's scratch, by node index; undefined until assigned.\n nodeOrders: (number | undefined)[]\n // Lane assignments for tracks (not reads), one list per order slot.\n assignments: NodeAssignment[][]\n extraLeft: number[]\n extraRight: number[]\n // horizontal order of the rightmost node\n maxOrder: number\n shapes: TrackShapes\n imageBounds: ImageBounds\n trackForRuler: string | undefined\n coarsenedEdgeMeta: Map<number, CoarsenedEdgeMeta>\n}\n\nfunction emptyState(config: LayoutConfig): LayoutState {\n return {\n config,\n nodes: [],\n tracks: [],\n reads: [],\n nodeMap: new Map(),\n nodesPerOrder: [],\n nodeOrders: [],\n assignments: [],\n extraLeft: [],\n extraRight: [],\n maxOrder: -1,\n shapes: emptyTrackShapes(),\n imageBounds: { minX: 0, maxX: 0, minY: 0, maxY: 0 },\n trackForRuler: undefined,\n coarsenedEdgeMeta: new Map(),\n }\n}\n\n// placeTubeMap(layoutTopology(...), options). Undefined when nothing visible\n// is left to draw.\nexport function layoutTubeMap(\n inputNodes: readonly InputNode[],\n inputTracks: readonly InputTrack[],\n inputReads: readonly InputTrack[] = [],\n options: LayoutOptions = {},\n): TubeMapLayout | undefined {\n const topology = layoutTopology(inputNodes, inputTracks, inputReads, options)\n return topology && placeTubeMap(topology, options)\n}\n\n// Each topology's placement of every track and read, which fixed its x\nconst measurements = new WeakMap<TubeMapTopology, TubeMapLayout>()\n\n// Merge, order and orient the nodes under the visible `inputTracks` and, when\n// `showReads`, every primary alignment in `inputReads`, then size them and\n// fix their x positions. Undefined when nothing visible is left to draw.\n// Neither input is modified. Track 0 is the reference the layout straightens.\n// The x gaps between order slots make room for the tracks' turns and slopes,\n// so the topology takes its x positions from placing every track and read.\nexport function layoutTopology(\n inputNodes: readonly InputNode[],\n inputTracks: readonly InputTrack[],\n inputReads: readonly InputTrack[] = [],\n options: TopologyOptions = {},\n): TubeMapTopology | undefined {\n const topology = arrangeTopology(inputNodes, inputTracks, inputReads, options)\n if (topology === undefined) {\n return undefined\n }\n const everything = place(topology, topology.tracks, topology.reads, 'measure')\n everything.nodes.forEach((node, i) => {\n if (node.order >= 0) {\n topology.nodes[i]!.x = node.x\n }\n })\n measurements.set(topology, everything)\n return topology\n}\n\n// Lay out the haplotypes and reads `options` keep at the topology's x\n// positions, stacking each read under the nodes it visits. When they keep\n// everything, this returns the placement layoutTopology measured x from, the\n// same object on every such call.\nexport function placeTubeMap(\n topology: TubeMapTopology,\n options: PlacementOptions = {},\n): TubeMapLayout {\n return placeSubset(\n topology,\n selectTracks(topology, options.facet),\n selectReads(topology, options),\n )\n}\n\nfunction placeSubset(\n topology: TubeMapTopology,\n tracks: readonly TopologyTrack[],\n reads: readonly TopologyTrack[],\n bandIdBase?: BandIdBase,\n): TubeMapLayout {\n const measured = measurements.get(topology)\n return measured !== undefined &&\n tracks.length === topology.tracks.length &&\n reads.length === topology.reads.length\n ? measured\n : place(topology, tracks, reads, 'topology', bandIdBase)\n}\n\nfunction arrangeTopology(\n inputNodes: readonly InputNode[],\n inputTracks: readonly InputTrack[],\n inputReads: readonly InputTrack[],\n options: TopologyOptions,\n): TubeMapTopology | undefined {\n const state = emptyState(configFrom(options, inputReads.length > 0))\n\n if (inputNodes.length === 0 || inputTracks.length === 0) {\n return undefined\n }\n\n // Boundary promotion: layout passes below populate the Node/Track fields\n // (width, order, x/y, path, indexSequence, etc.) before any reader runs.\n //\n // Nodes are referenced in inputs by internal `name` attribute and not by\n // index. Internally in e.g. a path's indexSequence we need to reference\n // nodes by *signed* index, so index 0 can never be used: budge everything\n // down and leave a hole (rather than an `undefined` entry) at 0, which we\n // won't iterate over. Made after the copy, because not every structuredClone\n // keeps a hole.\n structuredClone(inputNodes).forEach((node, i) => {\n node.seq ??= ''\n node.sequenceLength ??= node.seq.length\n state.nodes[i + 1] = node as LayoutNode\n })\n state.tracks = structuredClone(inputTracks) as Track[]\n // Secondary alignments never draw, so drop them before the deep copy, the\n // most expensive step in a redraw.\n state.reads = state.config.showReads\n ? (structuredClone(\n inputReads.filter(read => read.is_secondary !== true),\n ) as Track[])\n : []\n\n for (let i = state.tracks.length - 1; i >= 0; i -= 1) {\n const t = state.tracks[i]!\n t.type ??= 'haplotype'\n if (t.hidden === true) {\n state.tracks.splice(i, 1)\n continue\n }\n if (t.indexOfFirstBase !== undefined) {\n state.trackForRuler = t.name\n }\n }\n if (state.tracks.length === 0) {\n return undefined\n }\n\n // Run against the visible tracks only, so hiding the reference doesn't leave\n // the layout straightened around a track that is no longer drawn.\n straightenTrack(state, 0)\n\n state.nodeMap = generateNodeMap(state)\n generateTrackIndexSequences(state, state.tracks)\n generateTrackIndexSequences(state, state.reads)\n generateNodeWidth(state)\n\n if (state.config.mergeNodes) {\n generateNodeSuccessors(state)\n generateNodeOrder(state)\n reverseReversedReads(state)\n mergeNodes(state)\n state.nodeMap = generateNodeMap(state)\n generateNodeWidth(state)\n generateTrackIndexSequences(state, state.tracks)\n generateTrackIndexSequences(state, state.reads)\n }\n\n generateNodeSuccessors(state)\n generateNodeDegree(state)\n generateNodeOrder(state)\n\n // can cause problems when there is a reversed single track node\n // OTOH, can solve problems with complex inversion patterns\n switchNodeOrientation(state)\n generateNodeOrder(state)\n reverseReversedReads(state)\n generateTrackIndexSequences(state, state.reads)\n\n return {\n options: state.config,\n nodes: state.nodes,\n tracks: state.tracks,\n reads: state.reads,\n nodeMap: state.nodeMap,\n maxOrder: getMaxOrder(state),\n trackForRuler: state.trackForRuler,\n }\n}\n\nfunction selectReads(\n topology: TubeMapTopology,\n { mappingQualityCutoff = 0, focusReadNames = null, facet }: PlacementOptions,\n): readonly TopologyTrack[] {\n const focus = focusReadNames ? new Set(focusReadNames) : null\n return topology.reads.filter(\n read =>\n (read.mapping_quality ?? 0) >= mappingQualityCutoff &&\n (focus === null || (read.name !== undefined && focus.has(read.name))) &&\n (facet === undefined || facetHoldsRead(facet, read)),\n )\n}\n\n// Whether a panel of `facet` draws this read when the read filters keep it\nexport function facetHoldsRead(\n facet: Facet,\n read: Pick<TopologyTrack, ReadFacetBy>,\n): boolean {\n return facet.by === 'haplotype_sample'\n ? 'reads' in facet\n : (read[facet.by] ?? null) === facet.key\n}\n\n// What every haplotype panel keeps: track 0, which the topology straightened,\n// and the track carrying the ruler's coordinates, when that is another\nfunction references(topology: TubeMapTopology): Set<TopologyTrack> {\n return new Set(\n topology.tracks.filter(\n (track, i) => i === 0 || track.name === topology.trackForRuler,\n ),\n )\n}\n\nfunction selectTracks(\n topology: TubeMapTopology,\n facet: Facet | undefined,\n): readonly TopologyTrack[] {\n if (facet?.by !== 'haplotype_sample') {\n return topology.tracks\n }\n const kept = references(topology)\n return topology.tracks.filter(\n track =>\n kept.has(track) || (!('reads' in facet) && sampleOf(track) === facet.key),\n )\n}\n\nfunction sampleOf(track: TopologyTrack): string | null {\n return parsePanSN(track.name)?.sample ?? null\n}\n\n// The haplotypes among `tracks` beside the reference, a PanSN haplotype\n// counted once however many walks it makes through the window\nfunction haplotypeCount(\n topology: TubeMapTopology,\n tracks: readonly TopologyTrack[],\n): number {\n const skip = references(topology)\n return new Set(\n tracks.flatMap(track => {\n if (skip.has(track)) {\n return []\n }\n const name = parsePanSN(track.name)\n return [name ? `${name.sample}#${name.haplotype}` : track]\n }),\n ).size\n}\n\n// A facet and the haplotypes and reads it draws\nexport interface FacetSubset<F extends Facet = Facet> {\n facet: F\n tracks: readonly TopologyTrack[]\n reads: readonly TopologyTrack[]\n}\n\n// Group `items` by key: in sort order, the null key last\nfunction groupBy<T>(\n items: readonly T[],\n keyOf: (item: T) => string | null,\n): [string | null, T[]][] {\n const groups = new Map<string | null, T[]>()\n for (const item of items) {\n const key = keyOf(item)\n const group = groups.get(key)\n if (group === undefined) {\n groups.set(key, [item])\n } else {\n group.push(item)\n }\n }\n return [...groups].sort(([a], [b]) =>\n a === null || b === null\n ? Number(a === null) - Number(b === null)\n : a.localeCompare(b, undefined, { numeric: true }),\n )\n}\n\n// Split the reads `options` keep by their `by` field: one subset per value,\n// in sort order with the reads lacking one last, and none left empty. Every\n// subset keeps every haplotype.\nexport function facetReads(\n topology: TubeMapTopology,\n by: ReadFacetBy,\n options: PlacementOptions = {},\n): FacetSubset<ReadFacet>[] {\n return groupBy(\n selectReads(topology, { ...options, facet: undefined }),\n read => read[by] ?? null,\n ).map(([key, reads]) => ({\n facet: { by, key },\n tracks: topology.tracks,\n reads,\n }))\n}\n\n// Split the haplotypes beside the reference by the sample in their PanSN\n// names: one subset per sample, in sort order, then one for the haplotypes\n// with no PanSN name, each holding the reference too and no reads. The reads\n// `options` keep, when any, go in a last subset with the reference alone. No\n// haplotype beside the reference leaves nothing to split.\nexport function facetHaplotypes(\n topology: TubeMapTopology,\n options: PlacementOptions = {},\n): FacetSubset<HaplotypeFacet>[] {\n const kept = references(topology)\n const samples = groupBy(\n topology.tracks.filter(track => !kept.has(track)),\n sampleOf,\n )\n if (samples.length === 0) {\n return []\n }\n const ofSample = samples.map(([key]) => {\n const facet: HaplotypeFacet = { by: 'haplotype_sample', key }\n return { facet, tracks: selectTracks(topology, facet), reads: [] }\n })\n const facet: HaplotypeFacet = { by: 'haplotype_sample', reads: true }\n const reads = selectReads(topology, { ...options, facet })\n return reads.length === 0\n ? ofSample\n : [...ofSample, { facet, tracks: selectTracks(topology, facet), reads }]\n}\n\n// One placement in a stack of them. Its layout keeps its own coordinates;\n// `offsetY` moves it into the stack.\nexport interface FacetPanel {\n // undefined for the one panel of an unfaceted view\n facet?: Facet\n readCount: number\n // beside the reference, a PanSN haplotype counted once\n haplotypeCount: number\n layout: TubeMapLayout\n offsetY: number\n}\n\nexport interface FacetedLayout {\n panels: FacetPanel[]\n // every panel and its label, in stack coordinates\n bounds: ImageBounds\n}\n\n// Room above each faceted panel for its label, and between one panel and the\n// next label\nexport const FACET_LABEL_HEIGHT = 30\nexport const FACET_GAP = 40\n\n// Place the topology once per facet and stack the placements top to bottom,\n// the first where an unfaceted placement would draw. Every panel takes the\n// topology's x, so the panels line up in x. Band ids run on from one panel to\n// the next where panels band different tracks: the reads under a read facet,\n// the haplotypes under a haplotype facet, whose bands then take their share\n// of the panel's haplotypes. Without `facetBy`, or with nothing to split, this\n// is one panel of placeTubeMap's layout.\nexport function placeFacets(\n topology: TubeMapTopology,\n options: FacetOptions = {},\n): FacetedLayout {\n const { facetBy, ...placement } = options\n const subsets =\n facetBy === undefined || facetBy === null\n ? []\n : facetBy === 'haplotype_sample'\n ? facetHaplotypes(topology, placement)\n : facetReads(topology, facetBy, placement)\n if (subsets.length === 0) {\n const layout = placeTubeMap(topology, placement)\n return {\n panels: [\n {\n layout,\n readCount: layout.reads.length,\n haplotypeCount: haplotypeCount(topology, topology.tracks),\n offsetY: 0,\n },\n ],\n bounds: layout.bounds,\n }\n }\n const banded: LayerData =\n facetBy === 'haplotype_sample' ? 'haplotypes' : 'reads'\n let nextBandId: number | undefined\n let bottom = 0\n const panels = subsets.map(({ facet, tracks, reads }, i) => {\n const layout = placeSubset(\n topology,\n tracks,\n reads,\n nextBandId === undefined ? undefined : { [banded]: nextBandId },\n )\n for (const id of layout.coarsenedEdgeMeta.keys()) {\n if (nextBandId === undefined || id >= nextBandId) {\n nextBandId = id + 1\n }\n }\n const offsetY =\n i === 0 ? 0 : bottom + FACET_GAP + FACET_LABEL_HEIGHT - layout.bounds.minY\n bottom = offsetY + layout.bounds.maxY\n return {\n facet,\n readCount: reads.length,\n haplotypeCount: haplotypeCount(topology, tracks),\n layout,\n offsetY,\n }\n })\n return {\n panels,\n bounds: {\n minX: Math.min(...panels.map(p => p.layout.bounds.minX)),\n maxX: Math.max(...panels.map(p => p.layout.bounds.maxX)),\n minY: panels[0]!.layout.bounds.minY - FACET_LABEL_HEIGHT,\n maxY: bottom,\n },\n }\n}\n\n// The first id each layer's bands take\ntype BandIdBase = Partial<Record<LayerData, number>>\n\n// Place copies of the topology's nodes and the given tracks and reads,\n// measuring x from them or taking the topology's. Haplotype bands take ids\n// from COARSENED_ID_BASE and read bands straight after, unless `bandIdBase`\n// says otherwise.\nfunction place(\n topology: TubeMapTopology,\n tracks: readonly TopologyTrack[],\n reads: readonly TopologyTrack[],\n x: 'measure' | 'topology',\n bandIdBase: BandIdBase = {},\n): TubeMapLayout {\n const state = emptyState(topology.options)\n topology.nodes.forEach((node, i) => {\n state.nodes[i] = { ...node } as LayoutNode\n })\n state.tracks = tracks.map(track => ({ ...track }) as Track)\n state.reads = reads.map(read => ({ ...read }) as Track)\n state.nodeMap = topology.nodeMap\n state.maxOrder = topology.maxOrder\n state.trackForRuler = topology.trackForRuler\n\n // Banded haplotypes leave the reference its lane and join the reads'\n // overlay, above the reads, before calculateTrackWidth and\n // generateLaneAssignment see the tracks.\n const { layers, ignoreStrand } = state.config\n const haplotypeBandIdBase = bandIdBase.haplotypes ?? COARSENED_ID_BASE\n const haplotypeBands =\n statOf(layers, 'haplotypes') === 'coarsen'\n ? bandHaplotypes(state, haplotypeBandIdBase)\n : undefined\n if (haplotypeBands !== undefined) {\n state.tracks = [haplotypeBands.ref]\n }\n\n calculateTrackWidth(state)\n generateLaneAssignment(state)\n // also places the nodes that only filtered-out reads visit\n generateReadOnlyNodeAttributes(state)\n\n // A band crosses exactly two nodes, so placeReads and the shapes handle it\n // like any read, and node heights grow with the edge count rather than the\n // read or haplotype count.\n const readBands =\n statOf(layers, 'reads') === 'coarsen' && state.reads.length > 0\n ? buildCoarsenedSyntheticBands(\n state,\n state.reads,\n 'read',\n bandIdBase.reads ??\n haplotypeBandIdBase + (haplotypeBands?.bands.length ?? 0),\n )\n : undefined\n if (readBands !== undefined) {\n state.reads = readBands.bands\n }\n const coarsened: Coarsenings = {}\n for (const [data, unit, banding] of [\n ['haplotypes', 'haplotype', haplotypeBands],\n ['reads', 'read', readBands],\n ] as const) {\n if (banding !== undefined) {\n reverseReversedReads(state, banding.bands)\n generateTrackIndexSequences(state, banding.bands)\n coarsened[data] = {\n unit,\n total: banding.total,\n reverse: !ignoreStrand && banding.bands.some(b => b.is_reverse),\n }\n }\n }\n if (haplotypeBands !== undefined) {\n state.reads = haplotypeBands.bands.concat(state.reads)\n }\n\n if (state.reads.length > 0) {\n placeReads(state)\n state.tracks = state.tracks.concat(state.reads)\n } else {\n state.nodes.forEach(node => {\n node.incomingReads = []\n node.outgoingReads = []\n node.internalReads = []\n })\n }\n\n if (x === 'measure') {\n generateNodeXCoords(state)\n }\n\n generateSVGShapesFromPath(state)\n debugLog('Tracks:', state.tracks)\n debugLog('Nodes:', state.nodes)\n debugLog('Lane assignment:', state.assignments)\n getImageDimensions(state)\n return {\n nodes: state.nodes,\n tracks: state.tracks,\n reads: state.reads,\n nodeMap: state.nodeMap,\n shapes: state.shapes,\n bounds: state.imageBounds,\n maxOrder: state.maxOrder,\n trackForRuler: state.trackForRuler,\n coarsenedEdgeMeta: state.coarsenedEdgeMeta,\n coarsened,\n }\n}\n\n// Return true if the given name names a reverse strand node, and false otherwise.\nexport function isReverse(nodeName: string): boolean {\n return nodeName.startsWith('-')\n}\n\n// Get the forward version of a node name, which may be either forward or backward (negative)\nexport function forward(nodeName: string): string {\n return isReverse(nodeName) ? nodeName.substring(1) : nodeName\n}\n\n// Get the reverse version of a node name, which may be either forward or backward (negative)\nexport function reverse(nodeName: string): string {\n return isReverse(nodeName) ? nodeName : `-${nodeName}`\n}\n\n// Get the opposite orientation node name for the given node.\nexport function flip(nodeName: string): string {\n return isReverse(nodeName) ? forward(nodeName) : reverse(nodeName)\n}\n\n// Whether a signed node index visits its node forward. Index 0 is never a\n// node, so no visit is -0.\nexport function isForwardIndex(n: number): boolean {\n return n > 0\n}\n\n// Turn around every node the given track visits in reverse before it visits\n// it forward, so that track reads left to right, and flip every track's and\n// read's visits to those nodes to match, as switchNodeOrientationForPaths\n// does for the nodes it switches.\nfunction straightenTrack(state: LayoutState, index: number): void {\n const nodesToInvert = new Set<string>()\n const visitedForward = new Set<string>()\n for (const visit of state.tracks[index]!.sequence) {\n if (!isReverse(visit)) {\n visitedForward.add(visit)\n } else if (!visitedForward.has(forward(visit))) {\n nodesToInvert.add(forward(visit))\n }\n }\n if (nodesToInvert.size === 0) {\n return\n }\n\n for (const { sequence } of [...state.tracks, ...state.reads]) {\n for (let j = 0; j < sequence.length; j += 1) {\n if (nodesToInvert.has(forward(sequence[j]!))) {\n sequence[j] = flip(sequence[j]!)\n }\n }\n }\n\n state.nodes.forEach(node => {\n if (nodesToInvert.has(node.name)) {\n node.seq = getReverseComplement(node.seq)\n }\n })\n}\n\n// generates attributes (node.y, node.contentHeight) for nodes without tracks, only reads\nfunction generateReadOnlyNodeAttributes(state: LayoutState): void {\n state.nodesPerOrder = []\n for (let i = 0; i <= state.maxOrder; i += 1) {\n state.nodesPerOrder[i] = []\n }\n\n const orderY = new Map<number, number>()\n state.nodes.forEach((node: MaybeUnplacedNode) => {\n if (node.y !== undefined) {\n setMapToMax(orderY, node.order, node.y + node.contentHeight)\n }\n })\n\n // for order values where there is no node with haplotypes, orderY is calculated via tracks\n state.tracks.forEach(track => {\n if (track.type === 'haplotype') {\n track.path.forEach(step => {\n setMapToMax(orderY, step.order, (step.y ?? 0) + track.width)\n })\n }\n })\n\n state.nodes.forEach((node: MaybeUnplacedNode, i) => {\n if (node.order >= 0 && node.y === undefined) {\n node.y = (orderY.get(node.order) ?? 0) + 25\n node.contentHeight = 0\n state.nodesPerOrder[node.order]!.push(i)\n }\n })\n}\n\nfunction setMapToMax<K>(map: Map<K, number>, key: K, value: number): void {\n const existing = map.get(key)\n if (existing === undefined) {\n map.set(key, value)\n } else {\n map.set(key, Math.max(existing, value))\n }\n}\n\nexport const READ_WIDTH = 7\n\n// add info about reads to nodes (incoming, outgoing and internal reads)\nfunction assignReadsToNodes(state: LayoutState): void {\n state.nodes.forEach(node => {\n node.incomingReads = []\n node.outgoingReads = []\n node.internalReads = []\n })\n state.reads.forEach((read: MaybeUnset<Track, 'width'>, idx) => {\n // coarsened bands arrive sized by their crossing count\n if (read.width === undefined || read.width === 0) {\n read.width = READ_WIDTH\n }\n if (read.path.length === 1) {\n const firstNode = read.path[0]!.node\n if (firstNode !== null) {\n state.nodes[firstNode]!.internalReads.push(idx)\n }\n } else {\n read.path.forEach((element, pathIdx) => {\n if (pathIdx === 0) {\n const firstNode = read.path[0]!.node\n if (firstNode !== null) {\n state.nodes[firstNode]!.outgoingReads.push([idx, pathIdx])\n }\n } else {\n const elemNode = element.node\n if (elemNode !== null) {\n state.nodes[elemNode]!.incomingReads.push([idx, pathIdx])\n }\n }\n })\n }\n })\n}\n\n// calculate paths (incl. correct y coordinate) for all reads\nfunction placeReads(state: LayoutState): void {\n state.reads.forEach(read => {\n read.path = basicPath(state, read)\n })\n assignReadsToNodes(state)\n\n // placed nodes by order, then by y-coordinate\n const sortedNodes = state.nodes.filter(node => node.order >= 0)\n sortedNodes.sort(compareNodesByOrder)\n\n // One set per layer and source track: haplotype bands, then each read file\n const sets = new Map<\n string,\n { layer: number; source: number; reads: Set<number> }\n >()\n for (let i = 0; i < state.reads.length; i++) {\n const read = state.reads[i]!\n const layer = read.haplotypeShare === undefined ? 1 : 0\n const source = read.sourceTrackID\n const key = `${layer}:${source}`\n const set = sets.get(key)\n if (set === undefined) {\n sets.set(key, { layer, source, reads: new Set([i]) })\n } else {\n set.reads.add(i)\n }\n }\n const orderedSets = [...sets.values()].sort(\n (a, b) => a.layer - b.layer || a.source - b.source,\n )\n\n // A margin sets each set apart from the one above it\n const topMargin = orderedSets.length > 1 ? READ_WIDTH : 0\n sortedNodes.forEach(node => {\n for (const { reads } of orderedSets) {\n placeReadSet(state, reads, node, topMargin)\n }\n })\n\n // place read segments which are without node\n const bottomY = calculateBottomY(state)\n const elementsWithoutNode: ElementWithoutNode[] = []\n state.reads.forEach((read, idx) => {\n const len = read.path.length\n\n // For each path index, precompute the nearest preceding/following segment\n // whose node is non-null and truthy. Falls back to the boundary segment when\n // none qualifies, matching the original walking-loop semantics.\n const prevSegment = new Array<Segment | undefined>(len)\n let lastValidPrev: Segment | undefined\n for (let i = 0; i < len; i++) {\n if (i === 0) {\n prevSegment[i] = undefined\n } else {\n prevSegment[i] = lastValidPrev ?? read.path[0]\n }\n const seg = read.path[i]!\n if (seg.node !== null && seg.node) {\n lastValidPrev = seg\n }\n }\n const nextSegment = new Array<Segment | undefined>(len)\n let firstValidNext: Segment | undefined\n for (let i = len - 1; i >= 0; i--) {\n if (i === len - 1) {\n nextSegment[i] = undefined\n } else {\n nextSegment[i] = firstValidNext ?? read.path[len - 1]\n }\n const seg = read.path[i]!\n if (seg.node !== null && seg.node) {\n firstValidNext = seg\n }\n }\n\n read.path.forEach((element, pathIdx) => {\n if (element.y === undefined) {\n const previousVisitToNode = prevSegment[pathIdx]\n const nextVisitToNode = nextSegment[pathIdx]\n\n // Specifically referring to segments between a cycle that's traversing from right to left\n const betweenCycleReverseTraversal = Boolean(\n // A segment can be between a cycle if it there are nodes on both sides\n nextVisitToNode &&\n previousVisitToNode &&\n // A segment is between a cycle if the next node it visits is behind the previous node it visited\n (previousVisitToNode.order > nextVisitToNode.order ||\n // A segment can also be between a cycle if it's visiting the same node it just visited in the same direction\n (nextVisitToNode.order === previousVisitToNode.order &&\n nextVisitToNode.isForward === previousVisitToNode.isForward)),\n )\n\n element.betweenCycleReverseTraversal = betweenCycleReverseTraversal\n\n elementsWithoutNode.push({\n readIndex: idx,\n pathIndex: pathIdx,\n previousY: previousVisitToNode?.y,\n previousNode: previousVisitToNode?.node,\n })\n }\n })\n })\n\n elementsWithoutNode.sort((a, b) => compareNoNodeReads(state, a, b))\n elementsWithoutNode.forEach(element => {\n const read = state.reads[element.readIndex]!\n const segment = read.path[element.pathIndex]!\n segment.y = bottomY[segment.order]!\n bottomY[segment.order]! += read.width\n })\n\n debugLog('Reads:', state.reads)\n}\n\n// Place a particular collection of reads, identified by a list of read\n// numbers, into the given node at the right Y coordinates. All reads in all\n// nodes above it, and no reads in any nodes below it, are already placed.\n// Makes the given node bigger if needed and moves other nodes down if needed.\n// If topMargin is set, applies that amount of spacing down from whatever is above the reads.\nfunction placeReadSet(\n state: LayoutState,\n toPlace: Set<number>,\n node: LayoutNode,\n topMargin: number,\n): void {\n // Get arrays of the read entry/exit/internal-ness records we want to work on\n let incomingReads = node.incomingReads.filter(([readID]) =>\n toPlace.has(readID),\n )\n const outgoingReads = node.outgoingReads.filter(([readID]) =>\n toPlace.has(readID),\n )\n const internalReads = node.internalReads.filter(readID => toPlace.has(readID))\n\n // Only actually use the top margin if we have any reads on the node.\n if (\n incomingReads.length === 0 &&\n outgoingReads.length === 0 &&\n internalReads.length === 0\n ) {\n topMargin = 0\n }\n\n // Determine where we start vertically in the node.\n // TODO: Why do we have to double this to keep reads out of adjacent lanes???\n const startY = node.y + node.contentHeight + topMargin * 2\n\n // sort incoming reads \u2014 decorate with a precomputed key so each compare is O(1).\n // The original comparator walks pathIdx backwards in lockstep on both sides, picking\n // the first step where either has a defined y (or reaches index 0). The walk's outcome\n // for a single entry is fully captured by:\n // decisionStep: the smallest k>=1 where path[pathIdx-k].y is defined, or pathIdx+1\n // if no preceding segment has a defined y (the \"reached 0\" case).\n // y: the defined y at decisionStep, or undefined for \"reached 0\".\n // Smaller decisionStep wins; ties put the \"reached 0\" entries first;\n // otherwise compare y's.\n const incomingKeys = incomingReads.map(entry => {\n const [readID, pathIdx] = entry\n const path = state.reads[readID]!.path\n let decisionStep = pathIdx + 1\n let foundY: number | undefined\n for (let k = 1; k <= pathIdx; k++) {\n const y = path[pathIdx - k]?.y\n if (y !== undefined) {\n decisionStep = k\n foundY = y\n break\n }\n }\n return { entry, decisionStep, y: foundY }\n })\n incomingKeys.sort(compareIncomingReadKeys)\n incomingReads = incomingKeys.map(k => k.entry)\n\n // place incoming reads\n let currentY = startY\n const occupiedUntil = new Map<number, number>()\n incomingReads.forEach(readElement => {\n const read = state.reads[readElement[0]]!\n read.path[readElement[1]]!.y = currentY\n setOccupiedUntil(occupiedUntil, read, readElement[1], currentY, node)\n currentY += read.width\n })\n let maxY = currentY\n\n // sort outgoing reads\n outgoingReads.sort((a, b) =>\n compareReadOutgoingSegmentsByGoingTo(state, a, b),\n )\n\n // place outgoing reads\n const occupiedFrom = new Map<number, number>()\n currentY = startY\n outgoingReads.forEach(readElement => {\n const read = state.reads[readElement[0]]!\n const firstNodeOffset = read.firstNodeOffset ?? 0\n // place in next lane\n read.path[readElement[1]]!.y = currentY\n occupiedFrom.set(currentY, firstNodeOffset)\n // if no conflicts. The original predicate was strict-less-than, which\n // treats two reads that exactly touch (incoming ends at base K, outgoing\n // starts at base K+1) as conflicting. They don't overlap, so they can\n // share a lane \u2014 relax to <=. This also matters for coarsened Sankey\n // bands at single-base nodes (e.g. a 1bp \"G\" node): with edge-only offsets\n // the math becomes 0+1 < 1 (conflict, wrong) vs. 0+1 <= 1 (no conflict).\n const occUntil = occupiedUntil.get(currentY)\n if (occUntil === undefined || occUntil + 1 <= firstNodeOffset) {\n currentY += read.width\n maxY = Math.max(maxY, currentY)\n } else {\n // otherwise push down incoming reads to make place for outgoing Read\n occupiedUntil.set(currentY, 0)\n incomingReads.forEach(incReadElementIndices => {\n const incRead = state.reads[incReadElementIndices[0]]!\n const incReadPathElement = incRead.path[incReadElementIndices[1]]!\n if (\n incReadPathElement.y !== undefined &&\n incReadPathElement.y >= currentY\n ) {\n incReadPathElement.y += read.width\n setOccupiedUntil(\n occupiedUntil,\n incRead,\n incReadElementIndices[1],\n incReadPathElement.y,\n node,\n )\n }\n })\n currentY += read.width\n maxY += read.width\n }\n })\n\n // sort internal reads\n internalReads.sort((a, b) => compareInternalReads(state, a, b))\n\n // place internal reads\n internalReads.forEach(readIdx => {\n const currentRead = state.reads[readIdx]!\n const firstNodeOffset = currentRead.firstNodeOffset ?? 0\n const finalNodeCoverLength = currentRead.finalNodeCoverLength ?? 0\n currentY = startY\n while (\n firstNodeOffset < (occupiedUntil.get(currentY) ?? -Infinity) + 2 ||\n finalNodeCoverLength > (occupiedFrom.get(currentY) ?? Infinity) - 3\n ) {\n currentY += currentRead.width || READ_WIDTH\n }\n currentRead.path[0]!.y = currentY\n occupiedUntil.set(currentY, finalNodeCoverLength)\n maxY = Math.max(maxY, currentY)\n })\n\n // adjust node height and move other nodes vertically down\n const heightIncrease = maxY - node.y - node.contentHeight\n node.contentHeight += heightIncrease\n adjustVertically3(state, node, heightIncrease)\n}\n\n// The decorated sort key for one incoming read segment; see the comment in\n// placeReadSet for how it is derived. Exported for testing.\nexport interface IncomingReadKey {\n decisionStep: number\n y: number | undefined\n}\n\n// Smaller decisionStep wins. On a tie, entries that walked off the front of the\n// path (no defined y) sort first and tie with each other; otherwise compare y.\nexport function compareIncomingReadKeys(\n a: IncomingReadKey,\n b: IncomingReadKey,\n): number {\n if (a.decisionStep !== b.decisionStep) {\n return a.decisionStep - b.decisionStep\n }\n if (a.y === undefined || b.y === undefined) {\n return (a.y === undefined ? 0 : 1) - (b.y === undefined ? 0 : 1)\n }\n return a.y - b.y\n}\n\n// keeps track of where reads end within nodes\nfunction setOccupiedUntil(\n map: Map<number, number>,\n read: Track,\n pathIndex: number,\n y: number,\n node: Node,\n): void {\n if (pathIndex === read.path.length - 1) {\n // last node of current read\n map.set(y, read.finalNodeCoverLength ?? 0)\n } else {\n // read covers the whole node\n map.set(y, node.sequenceLength)\n }\n}\n\ninterface ElementWithoutNode {\n readIndex: number\n pathIndex: number\n previousY: number | undefined\n previousNode: number | null | undefined\n}\n\n// compare read segments which are outside of nodes to sort them in a good horizontal\n// and then vertical display order.\nfunction compareNoNodeReads(\n state: LayoutState,\n a: ElementWithoutNode,\n b: ElementWithoutNode,\n): number {\n const readA = state.reads[a.readIndex]!\n const readB = state.reads[b.readIndex]!\n const segmentA = readA.path[a.pathIndex]!\n const segmentB = readB.path[b.pathIndex]!\n // Sort by order by segments\n if (segmentA.order !== segmentB.order) {\n return segmentA.order - segmentB.order\n }\n // Sort by reads' source track\n if (readA.sourceTrackID !== readB.sourceTrackID) {\n return readA.sourceTrackID - readB.sourceTrackID\n }\n // Sort by order of previous node\n if (a.previousNode && b.previousNode) {\n const prevNodeA = state.nodes[a.previousNode]\n const prevNodeB = state.nodes[b.previousNode]\n if (prevNodeA && prevNodeB && prevNodeA.order !== prevNodeB.order) {\n return prevNodeA.order - prevNodeB.order\n }\n }\n // Segments on the reverse-going part of a cycle go below the rest, in\n // reverse order, so a loop that starts on the outside stays there and rolls\n // up in order with the other loops.\n const aPrev = a.previousY ?? 0\n const bPrev = b.previousY ?? 0\n const aReverse = segmentA.betweenCycleReverseTraversal === true\n const bReverse = segmentB.betweenCycleReverseTraversal === true\n if (aReverse !== bReverse) {\n return aReverse ? 1 : -1\n }\n return aReverse ? bPrev - aPrev : aPrev - bPrev\n}\n\n// compare read segments by where they are going to\nfunction compareReadOutgoingSegmentsByGoingTo(\n state: LayoutState,\n [readIndexA, pathIndexA]: [number, number],\n [readIndexB, pathIndexB]: [number, number],\n): number {\n // Expect two arrays both containing 2 integers.\n // The first index of each array contains the read index\n // The second index of each array contains the path index\n\n // Segments are first sorted by the y value of their last node,\n // then by the node they end on,\n // then by length in final node\n const readA = state.reads[readIndexA]!\n const readB = state.reads[readIndexB]!\n let previousValidYA: number | undefined\n let previousValidYB: number | undefined\n let lastPathIndexA = readA.path.length - 1\n let lastPathIndexB = readB.path.length - 1\n while (previousValidYA === undefined && lastPathIndexA >= 0) {\n previousValidYA = readA.path[lastPathIndexA]?.y\n lastPathIndexA -= 1\n }\n while (previousValidYB === undefined && lastPathIndexB >= 0) {\n previousValidYB = readB.path[lastPathIndexB]?.y\n lastPathIndexB -= 1\n }\n\n if (previousValidYA !== undefined && previousValidYB !== undefined) {\n return previousValidYA - previousValidYB\n }\n\n // Couldn't find a valid y value for at least one of the reads, sort by which node reads end on\n const initialNodeA = readA.path[pathIndexA]?.node\n const initialNodeB = readB.path[pathIndexB]?.node\n let nodeA: LayoutNode | null | undefined =\n typeof initialNodeA === 'number' ? state.nodes[initialNodeA] : null\n let nodeB: LayoutNode | null | undefined =\n typeof initialNodeB === 'number' ? state.nodes[initialNodeB] : null\n // Follow the reads' paths until we find the node they diverge at\n // Or, they go through all the same nodes and we do a tiebreaker at the end\n while (nodeA && nodeB && nodeA === nodeB) {\n if (pathIndexA < readA.path.length - 1) {\n pathIndexA += 1\n while (readA.path[pathIndexA]?.node === null) {\n pathIndexA += 1\n } // skip null nodes in path\n const nextNodeIdx = readA.path[pathIndexA]?.node\n nodeA = typeof nextNodeIdx === 'number' ? state.nodes[nextNodeIdx] : null\n } else {\n nodeA = null\n }\n if (pathIndexB < readB.path.length - 1) {\n pathIndexB += 1\n while (readB.path[pathIndexB]?.node === null) {\n pathIndexB += 1\n } // skip null nodes in path\n const nextNodeIdx = readB.path[pathIndexB]?.node\n nodeB = typeof nextNodeIdx === 'number' ? state.nodes[nextNodeIdx] : null\n } else {\n nodeB = null\n }\n }\n if (nodeA) {\n if (nodeB) {\n return compareNodesByOrder(nodeA, nodeB)\n }\n return 1 // nodeB is null, nodeA not null\n }\n if (nodeB) {\n return -1\n } // nodeB not null, nodeA null\n // both nodes are null -> both end in the same node\n const beginDiff = (readA.firstNodeOffset ?? 0) - (readB.firstNodeOffset ?? 0)\n if (beginDiff !== 0) {\n return beginDiff\n }\n\n // break tie: both reads cover the same nodes and begin at the same position\n\n // One or both reads didn't have a previously valid Y value, compare by the endPosition of the read\n return (readA.finalNodeCoverLength ?? 0) - (readB.finalNodeCoverLength ?? 0)\n}\n\n// Compare tracks based on ordering at their first convergence\nfunction compareTrackByInitialOrdering(trackA: Track, trackB: Track): number {\n // Find the first node where the two tracks converge, sort by layer.\n const pathA = trackA.path\n const pathB = trackB.path\n\n let AIndex = 0\n let BIndex = 0\n while (AIndex < pathA.length && BIndex < pathB.length) {\n const a = pathA[AIndex]!\n const b = pathB[BIndex]!\n const trackAOrder = a.order\n const trackBOrder = b.order\n if (trackAOrder === trackBOrder && a.node && b.node) {\n return (b.y ?? 0) - (a.y ?? 0)\n } else if (trackAOrder < trackBOrder) {\n AIndex += 1\n } else if (trackAOrder > trackBOrder) {\n BIndex += 1\n } else {\n // Orders are equal but are traversing out of nodes\n AIndex += 1\n BIndex += 1\n }\n }\n\n // Tracks do not converge, keep the same ordering\n return 0\n}\n\n// compare 2 reads which are completely within a single node\nfunction compareInternalReads(\n state: LayoutState,\n idxA: number,\n idxB: number,\n): number {\n const a = state.reads[idxA]!\n const b = state.reads[idxB]!\n // compare by first base within first node\n const aFirst = a.firstNodeOffset ?? 0\n const bFirst = b.firstNodeOffset ?? 0\n if (aFirst < bFirst) {\n return -1\n } else if (aFirst > bFirst) {\n return 1\n }\n\n // compare by last base within last node\n const aLast = a.finalNodeCoverLength ?? 0\n const bLast = b.finalNodeCoverLength ?? 0\n if (aLast < bLast) {\n return -1\n } else if (aLast > bLast) {\n return 1\n }\n\n return 0\n}\n\n// determine biggest y-coordinate for each order-value\nfunction calculateBottomY(state: LayoutState): number[] {\n const bottomY: number[] = []\n for (let i = 0; i <= state.maxOrder; i += 1) {\n bottomY.push(0)\n }\n\n state.nodes.forEach((node: MaybeUnplacedNode) => {\n if (node.y !== undefined) {\n bottomY[node.order] = Math.max(\n bottomY[node.order]!,\n node.y + node.contentHeight + 20,\n )\n }\n })\n\n state.tracks.forEach(track => {\n track.path.forEach(element => {\n bottomY[element.order] = Math.max(\n bottomY[element.order]!,\n (element.y ?? 0) + track.width,\n )\n })\n })\n return bottomY\n}\n\n// The segments a track draws, in order: one per node visit, plus one per\n// order slot it passes or turns around in without visiting a node. They carry\n// no lanes or coordinates yet.\nfunction basicPath(state: LayoutState, track: Track): Segment[] {\n const path: Segment[] = []\n const pass = (order: number, isForward: boolean): void => {\n path.push({ order, isForward, node: null })\n }\n const visit = (order: number, isForward: boolean, node: number): void => {\n path.push({ order, isForward, node })\n }\n\n let currentNodeIndex = Math.abs(track.indexSequence[0]!)\n let currentNodeIsForward = isForwardIndex(track.indexSequence[0]!)\n let currentNode = state.nodes[currentNodeIndex]!\n visit(currentNode.order, currentNodeIsForward, currentNodeIndex)\n\n for (let i = 1; i < track.sequence.length; i += 1) {\n const previousNode = currentNode\n const previousNodeIsForward = currentNodeIsForward\n currentNodeIndex = Math.abs(track.indexSequence[i]!)\n currentNodeIsForward = isForwardIndex(track.indexSequence[i]!)\n currentNode = state.nodes[currentNodeIndex]!\n const { order } = currentNode\n\n if (order > previousNode.order) {\n if (!previousNodeIsForward) {\n pass(previousNode.order, true)\n }\n for (let j = previousNode.order + 1; j < order; j += 1) {\n pass(j, true)\n }\n if (!currentNodeIsForward) {\n pass(order, true)\n }\n } else if (order < previousNode.order) {\n if (previousNodeIsForward) {\n pass(previousNode.order, false)\n }\n for (let j = previousNode.order - 1; j > order; j -= 1) {\n pass(j, false)\n }\n if (currentNodeIsForward) {\n pass(order, false)\n }\n } else if (currentNodeIsForward === previousNodeIsForward) {\n pass(order, !currentNodeIsForward)\n }\n visit(order, currentNodeIsForward, currentNodeIndex)\n }\n return path\n}\n\n// Turn each read that visits only reverse nodes around to visit them forward\nfunction reverseReversedReads(\n state: LayoutState,\n reads: readonly Track[] = state.reads,\n): void {\n reads.forEach(read => {\n let pos = 0\n while (pos < read.sequence.length && read.sequence[pos]!.startsWith('-')) {\n pos += 1\n }\n if (pos === read.sequence.length) {\n // completely reversed read\n read.is_reverse = true\n read.sequence = read.sequence.reverse() // invert sequence\n for (let i = 0; i < read.sequence.length; i += 1) {\n read.sequence[i] = forward(read.sequence[i]!) // visit nodes forward\n // TODO: Do we really want to visit all the nodes forward here? Are we\n // sure we aren't in mixed orientation?\n }\n\n const sequenceNew = read.sequenceNew ?? []\n sequenceNew.reverse() // invert sequence\n read.sequenceNew = sequenceNew\n for (const entry of sequenceNew) {\n entry.nodeName = forward(entry.nodeName) // visit nodes forward\n reverseMismatches(\n entry.mismatches,\n nodeByName(state, entry.nodeName).sequenceLength,\n )\n }\n\n // adjust firstNodeOffset and finalNodeCoverLength\n const temp = read.firstNodeOffset ?? 0\n const firstLen = nodeByName(state, read.sequence[0]!).sequenceLength\n read.firstNodeOffset = firstLen - (read.finalNodeCoverLength ?? 0)\n const lastLen = nodeByName(\n state,\n read.sequence[read.sequence.length - 1]!,\n ).sequenceLength\n read.finalNodeCoverLength = lastLen - temp\n }\n })\n}\n\n// Flip a node's mismatches onto the opposite strand: positions are measured\n// from the other end of the node, and sequences are reverse-complemented.\n// sequenceLength (not node.width, which is only equal to it in 'normal'\n// node-width mode) is the right pivot because mismatch positions are base\n// offsets.\nexport function reverseMismatches(\n mismatches: Mismatch[],\n sequenceLength: number,\n): void {\n mismatches.forEach(mm => {\n Object.assign(mm, mirroredMismatch(mm, sequenceLength))\n })\n}\n\nexport function mirroredMismatch(\n mm: Mismatch,\n sequenceLength: number,\n): Mismatch {\n const span =\n mm.type === 'insertion'\n ? 0\n : mm.type === 'deletion'\n ? (mm.length ?? 0)\n : (mm.seq?.length ?? 0)\n return {\n ...mm,\n pos: sequenceLength - mm.pos - span,\n ...(mm.seq !== undefined && { seq: getReverseComplement(mm.seq) }),\n }\n}\n\nconst COMPLEMENT: Record<string, string> = { A: 'T', T: 'A', C: 'G', G: 'C' }\n\nfunction getReverseComplement(s: string): string {\n let result = ''\n for (let i = s.length - 1; i >= 0; i -= 1) {\n result += COMPLEMENT[s.charAt(i)] ?? 'N'\n }\n return result\n}\n\n// for each track: generate sequence of node indices from seq. of node names.\n// Tracks revisit the same names, so each name resolves once per call.\nfunction generateTrackIndexSequences(\n state: LayoutState,\n tracksOrReads: Track[],\n): void {\n const signedIndexOf = new Map<string, number>()\n tracksOrReads.forEach(track => {\n track.indexSequence = track.sequence.map(nodeName => {\n let signed = signedIndexOf.get(nodeName)\n if (signed === undefined) {\n const index = state.nodeMap.get(forward(nodeName))\n if (index === undefined) {\n throw new Error(\n `Track ${track.name ?? track.id} visits unknown node ${nodeName}`,\n )\n }\n signed = isReverse(nodeName) ? -index : index\n signedIndexOf.set(nodeName, signed)\n }\n return signed\n })\n })\n}\n\n// Tracks enter and leave a node this far outside it horizontally\nconst NODE_HORIZONTAL_SLACK = 20\n\n// The box around every node outline and track shape. A turnaround's corners\n// reach no further out than its vertical rectangles, so the rectangles and\n// curves stand in for them.\nfunction getImageDimensions(state: LayoutState): void {\n // Sentinels, deliberately crossed: if nothing below runs, minZoom() and\n // alignSVG() detect the empty content rather than computing a negative scale.\n const bounds: ImageBounds = { minX: 99, maxX: -99, minY: 99, maxY: -99 }\n\n const { rectangles, verticalRectangles, curves } = state.shapes\n for (const shapes of [rectangles, verticalRectangles, curves]) {\n for (const { xStart, xEnd } of shapes) {\n bounds.minX = Math.min(bounds.minX, xStart, xEnd)\n bounds.maxX = Math.max(bounds.maxX, xStart, xEnd)\n }\n }\n\n state.nodes.forEach((node: MaybeUnplacedNode) => {\n if (node.x !== undefined) {\n bounds.minX = Math.min(bounds.minX, node.x - 9)\n bounds.maxX = Math.max(\n bounds.maxX,\n node.x + NODE_HORIZONTAL_SLACK + node.pixelWidth,\n )\n }\n if (node.y !== undefined) {\n bounds.minY = Math.min(bounds.minY, node.y - 10)\n bounds.maxY = Math.max(bounds.maxY, node.y + node.contentHeight + 10)\n }\n })\n\n state.tracks.forEach(track => {\n track.path.forEach(segment => {\n const y = segment.y ?? 0\n bounds.maxY = Math.max(bounds.maxY, y + track.width)\n bounds.minY = Math.min(bounds.minY, y)\n })\n })\n\n state.imageBounds = bounds\n}\n\n// Resolve a (possibly reverse-oriented) node name to its layout node. Every\n// caller runs after generateNodeMap, so a miss is a programming error.\nfunction nodeByName(state: LayoutState, nodeName: string): LayoutNode {\n const index = state.nodeMap.get(forward(nodeName))\n const node = index === undefined ? undefined : state.nodes[index]\n if (node === undefined) {\n throw new Error(`Unknown node ${nodeName}`)\n }\n return node\n}\n\n// map node names to node indices\nfunction generateNodeMap(state: LayoutState): Map<string, number> {\n const nodeMap = new Map<string, number>()\n state.nodes.forEach((node, index) => {\n nodeMap.set(node.name, index)\n })\n return nodeMap\n}\n\n// adds a successor-array to each node containing the indices of the nodes coming directly after the current node\nfunction generateNodeSuccessors(state: LayoutState): void {\n const successorSets: Set<number>[] = state.nodes.map(() => new Set())\n const predecessorSets: Set<number>[] = state.nodes.map(() => new Set())\n\n const addEdges = (track: Track): void => {\n for (let i = 0; i < track.indexSequence.length - 1; i += 1) {\n const current = Math.abs(track.indexSequence[i]!)\n const follower = Math.abs(track.indexSequence[i + 1]!)\n successorSets[current]!.add(follower)\n predecessorSets[follower]!.add(current)\n }\n }\n\n state.tracks.forEach(addEdges)\n state.reads.forEach(addEdges)\n\n state.nodes.forEach((node, i) => {\n node.successors = Array.from(successorSets[i]!)\n node.predecessors = Array.from(predecessorSets[i]!)\n })\n}\n\nfunction generateNodeOrderOfSingleTrack(\n state: LayoutState,\n sequence: number[],\n): void {\n let forwardOrder = 0\n let backwardOrder = 0\n let minOrder = 0\n\n sequence.forEach(nodeIndex => {\n const idx = Math.abs(nodeIndex)\n if (nodeIndex < 0) {\n const order = (state.nodeOrders[idx] ??= backwardOrder)\n if (order < minOrder) {\n minOrder = order\n }\n forwardOrder = order\n backwardOrder = order - 1\n } else {\n const order = (state.nodeOrders[idx] ??= forwardOrder)\n forwardOrder = order + 1\n backwardOrder = order\n }\n })\n if (minOrder < 0) {\n increaseOrderForAllNodes(state, -minOrder)\n }\n}\n\n// calculate the order-value of nodes contained in sequence which are to the left of the first node which already has an order-value\nfunction generateNodeOrderTrackBeginning(\n state: LayoutState,\n sequence: number[],\n): number | null {\n let anchorIndex = 0\n let minOrder = 0\n\n while (\n anchorIndex < sequence.length &&\n state.nodeOrders[Math.abs(sequence[anchorIndex]!)] === undefined\n ) {\n anchorIndex += 1 // anchor = first node in common with existing graph\n }\n if (anchorIndex >= sequence.length) {\n return null\n }\n\n const anchorSeqVal = sequence[anchorIndex]!\n let currentOrder: number\n let increment: number\n if (anchorSeqVal >= 0) {\n // regular node\n currentOrder = state.nodeOrders[anchorSeqVal]! - 1\n increment = -1\n } else {\n // reverse node\n currentOrder = state.nodeOrders[-anchorSeqVal]! + 1\n increment = 1\n }\n\n for (let j = anchorIndex - 1; j >= 0; j -= 1) {\n // assign order to nodes which are left of anchor node\n const idx = Math.abs(sequence[j]!)\n if (state.nodeOrders[idx] === undefined) {\n state.nodeOrders[idx] = currentOrder\n minOrder = Math.min(minOrder, currentOrder)\n currentOrder += increment\n }\n }\n\n if (minOrder < 0) {\n increaseOrderForAllNodes(state, -minOrder)\n }\n return anchorIndex\n}\n\n// Sentinel order for nodes no track or read reaches.\nexport const UNREACHABLE_ORDER = -1\n\n// Replace every unassigned entry with UNREACHABLE_ORDER, producing a dense\n// array. Holes matter here: `new Array(n)` is all holes and forEach/map skip\n// them, so an in-place forEach would leave the sentinel unset.\nexport function fillUnassignedOrders(\n orders: readonly (number | undefined)[],\n): number[] {\n const filled: number[] = []\n for (const order of orders) {\n filled.push(order ?? UNREACHABLE_ORDER)\n }\n return filled\n}\n\n// generate global sequence of nodes from left to right, starting with first track and adding other tracks sequentially\nfunction generateNodeOrder(state: LayoutState): void {\n let modifiedSequence: number[]\n let currentOrder: number\n let rightIndex: number | null\n let leftIndex: number\n let minOrder = 0\n const tracksAndReads = state.tracks.concat(state.reads)\n const reachability: ReachabilityScratch = {\n stamp: new Int32Array(state.nodes.length),\n generation: 0,\n }\n\n // fill() makes the array dense: `new Array(n)` alone is all holes, which\n // forEach skips, so neither the sentinel pass nor the copy-back below ran.\n state.nodeOrders = new Array<number | undefined>(state.nodes.length).fill(\n undefined,\n )\n // Widened to Node, whose order is optional, to clear the previous run's orders\n state.nodes.forEach((node: Node) => {\n node.order = undefined\n })\n\n generateNodeOrderOfSingleTrack(state, state.tracks[0]!.indexSequence)\n\n for (let i = 1; i < tracksAndReads.length; i += 1) {\n debugLog(`generating order for track ${i + 1}`)\n rightIndex = generateNodeOrderTrackBeginning(\n state,\n tracksAndReads[i]!.indexSequence,\n )\n if (rightIndex === null) {\n if (i < state.tracks.length) {\n generateNodeOrderOfSingleTrack(state, tracksAndReads[i]!.indexSequence)\n } else {\n tracksAndReads.splice(i, 1)\n state.reads.splice(i - state.tracks.length, 1)\n i -= 1\n }\n continue\n }\n modifiedSequence = uninvert(tracksAndReads[i]!.indexSequence)\n\n while (rightIndex < modifiedSequence.length) {\n // move right until the end of the sequence\n leftIndex = rightIndex\n rightIndex += 1\n while (\n rightIndex < modifiedSequence.length &&\n state.nodeOrders[modifiedSequence[rightIndex]!] === undefined\n ) {\n rightIndex += 1\n }\n\n if (rightIndex < modifiedSequence.length) {\n // middle segment between two anchors\n currentOrder = state.nodeOrders[modifiedSequence[leftIndex]!]! + 1\n for (let j = leftIndex + 1; j < rightIndex; j += 1) {\n state.nodeOrders[modifiedSequence[j]!] = currentOrder\n currentOrder += 1\n }\n\n if (\n state.nodeOrders[modifiedSequence[rightIndex]!]! >\n state.nodeOrders[modifiedSequence[leftIndex]!]!\n ) {\n if (state.nodeOrders[modifiedSequence[rightIndex]!]! < currentOrder) {\n increaseOrderForSuccessors(\n state,\n modifiedSequence[rightIndex]!,\n modifiedSequence[rightIndex - 1]!,\n currentOrder,\n )\n }\n } else {\n if (\n tracksAndReads[i]!.indexSequence[rightIndex]! >= 0 &&\n !isSuccessor(\n state,\n modifiedSequence[rightIndex]!,\n modifiedSequence[leftIndex]!,\n reachability,\n )\n ) {\n // no real reversal\n increaseOrderForSuccessors(\n state,\n modifiedSequence[rightIndex]!,\n modifiedSequence[rightIndex - 1]!,\n currentOrder,\n )\n } else {\n // real reversal\n if (\n tracksAndReads[i]!.indexSequence[leftIndex]! < 0 ||\n (state.nodes[modifiedSequence[leftIndex + 1]!]!.degree < 2 &&\n state.nodeOrders[modifiedSequence[rightIndex]!]! <\n state.nodeOrders[modifiedSequence[leftIndex]!]!)\n ) {\n currentOrder = state.nodeOrders[modifiedSequence[leftIndex]!]! - 1\n for (let j = leftIndex + 1; j < rightIndex; j += 1) {\n state.nodeOrders[modifiedSequence[j]!] = currentOrder\n minOrder = Math.min(minOrder, currentOrder)\n currentOrder -= 1\n }\n }\n }\n }\n } else {\n // right segment to the right of last anchor\n if (tracksAndReads[i]!.indexSequence[leftIndex]! >= 0) {\n // elongate towards the right\n currentOrder = state.nodeOrders[modifiedSequence[leftIndex]!]! + 1\n for (let j = leftIndex + 1; j < modifiedSequence.length; j += 1) {\n const idx = modifiedSequence[j]!\n if (state.nodeOrders[idx] === undefined) {\n state.nodeOrders[idx] = currentOrder\n currentOrder += 1\n }\n }\n } else {\n // elongate towards the left\n currentOrder = state.nodeOrders[modifiedSequence[leftIndex]!]! - 1\n for (let j = leftIndex + 1; j < modifiedSequence.length; j += 1) {\n const idx = modifiedSequence[j]!\n if (state.nodeOrders[idx] === undefined) {\n state.nodeOrders[idx] = currentOrder\n minOrder = Math.min(minOrder, currentOrder)\n currentOrder -= 1\n }\n }\n }\n }\n }\n }\n\n if (minOrder < 0) {\n increaseOrderForAllNodes(state, -minOrder)\n }\n\n // Nodes unreachable from any track get UNREACHABLE_ORDER so every node ends\n // up with a defined order; downstream code uses `order >= 0` to skip them.\n const finalOrders = fillUnassignedOrders(state.nodeOrders)\n state.nodeOrders = finalOrders\n finalOrders.forEach((order, i) => {\n const node = state.nodes[i]\n if (node !== undefined) {\n node.order = order\n }\n })\n}\n\n// Reusable visited-set for the reachability searches in generateNodeOrder.\n// Stamping with a generation counter avoids reallocating (and re-zeroing) an\n// array of nodes.length booleans on every call.\ninterface ReachabilityScratch {\n stamp: Int32Array\n generation: number\n}\n\nfunction isSuccessor(\n state: LayoutState,\n first: number,\n second: number,\n scratch: ReachabilityScratch,\n): boolean {\n scratch.generation += 1\n const { stamp, generation } = scratch\n const stack: number[] = [first]\n stamp[first] = generation\n while (stack.length > 0) {\n const current = stack.pop()!\n if (current === second) {\n return true\n }\n for (const childIndex of state.nodes[current]!.successors) {\n if (stamp[childIndex] !== generation) {\n stamp[childIndex] = generation\n stack.push(childIndex)\n }\n }\n }\n return false\n}\n\n// get order number of the rightmost node\nfunction getMaxOrder(state: LayoutState): number {\n let max = -1\n state.nodeOrders.forEach(order => {\n if (order !== undefined && order > max) {\n max = order\n }\n })\n return max\n}\n\n// generates sequence keeping the order but switching all reversed (negative) nodes to forward nodes\nfunction uninvert(sequence: number[]): number[] {\n return sequence.map(v => Math.abs(v))\n}\n\n// increases the order-value of all nodes by amount\nfunction increaseOrderForAllNodes(state: LayoutState, amount: number): void {\n state.nodeOrders.forEach((order, i) => {\n if (order !== undefined) {\n state.nodeOrders[i] = order + amount\n }\n })\n}\n\n// increases the order-value for currentNode and (if necessary) successor nodes recursively\nfunction increaseOrderForSuccessors(\n state: LayoutState,\n startingNode: number,\n tabuNode: number,\n newOrder: number,\n): void {\n const increasedOrders = new Map<number, number>()\n // Walked with a head pointer rather than shift(), which is O(length) per pop.\n const queue: [number, number][] = [[startingNode, newOrder]]\n let head = 0\n\n while (head < queue.length) {\n const [currentNode, currentOrder] = queue[head]!\n head += 1\n const currentNodeOrder = state.nodeOrders[currentNode]\n\n if (currentNodeOrder !== undefined && currentNodeOrder < currentOrder) {\n if (\n !increasedOrders.has(currentNode) ||\n increasedOrders.get(currentNode)! < currentOrder\n ) {\n increasedOrders.set(currentNode, currentOrder)\n state.nodes[currentNode]!.successors.forEach(successor => {\n if (\n state.nodeOrders[successor]! > currentNodeOrder &&\n successor !== tabuNode\n ) {\n // only increase order of successors to the right of currentNode\n queue.push([successor, currentOrder + 1])\n }\n })\n if (currentNode !== startingNode) {\n state.nodes[currentNode]!.predecessors.forEach(predecessor => {\n if (\n state.nodeOrders[predecessor]! > currentNodeOrder &&\n predecessor !== tabuNode\n ) {\n // only increase order of predecessors to the right of currentNode\n queue.push([predecessor, currentOrder + 1])\n }\n })\n }\n }\n }\n }\n\n increasedOrders.forEach((value, key) => {\n state.nodeOrders[key] = value\n })\n}\n\n// calculates the node degree: the number of tracks passing through the node / the node height\nfunction generateNodeDegree(state: LayoutState): void {\n state.nodes.forEach(node => {\n node.tracks = []\n })\n\n state.tracks.forEach(track => {\n track.indexSequence.forEach(nodeIndex => {\n state.nodes[Math.abs(nodeIndex)]!.tracks.push(track.id)\n })\n })\n\n state.nodes.forEach(node => {\n node.degree = node.tracks.length\n })\n}\n\n// Orient the nodes to suit the tracks and reads\nfunction switchNodeOrientation(state: LayoutState): void {\n switchNodeOrientationForPaths(\n state,\n [...state.tracks.slice(1), ...state.reads],\n state.tracks[0]!,\n )\n}\n\n// If more of the given paths pass through a specific node in reverse direction than in\n// regular direction, switch its orientation. Nodes the pivot path visits\n// forward keep theirs. Processes all paths' nodes in place, reading each\n// visit's node from its indexSequence, which must match its sequence.\nfunction switchNodeOrientationForPaths(\n state: LayoutState,\n paths: Track[],\n pivotPath: Track,\n): void {\n const scores = new Int32Array(state.nodes.length)\n const onPivot = new Uint8Array(state.nodes.length)\n for (const nodeName of pivotPath.sequence) {\n const index = isReverse(nodeName) ? undefined : state.nodeMap.get(nodeName)\n if (index !== undefined) {\n onPivot[index] = 1\n }\n }\n\n for (const path of paths) {\n const { sequence, indexSequence } = path\n const last = indexSequence.length - 1\n for (let j = 0; j <= last; j += 1) {\n const index = Math.abs(indexSequence[j]!)\n if (onPivot[index] === 1) {\n continue\n }\n const order = state.nodes[index]!.order\n const prevOrder =\n j > 0 ? state.nodes[Math.abs(indexSequence[j - 1]!)]!.order : undefined\n const nextOrder =\n j < last\n ? state.nodes[Math.abs(indexSequence[j + 1]!)]!.order\n : undefined\n // A reverse visit votes for switching when the path runs left to right\n // through the node, and against when it runs right to left.\n const vote = isReverse(sequence[j]!) ? 1 : -1\n if (\n (prevOrder === undefined || prevOrder < order) &&\n (nextOrder === undefined || order < nextOrder)\n ) {\n scores[index]! += vote\n }\n if (\n (prevOrder === undefined || prevOrder > order) &&\n (nextOrder === undefined || order > nextOrder)\n ) {\n scores[index]! -= vote\n }\n }\n }\n\n for (const path of paths) {\n const { sequence, indexSequence } = path\n for (let j = 0; j < indexSequence.length; j += 1) {\n if (scores[Math.abs(indexSequence[j]!)]! > 0) {\n sequence[j] = flip(sequence[j]!)\n indexSequence[j] = -indexSequence[j]!\n }\n }\n }\n\n state.nodes.forEach((node, index) => {\n if (scores[index]! > 0) {\n node.seq = getReverseComplement(node.seq)\n node.switched = true\n }\n })\n}\n\n// calculates the concrete values for the nodes' x-coordinates\nfunction generateNodeXCoords(state: LayoutState): void {\n let currentX = 0\n let nextX = 20\n let currentOrder = -1\n const sortedNodes = state.nodes.slice()\n sortedNodes.sort(compareNodesByOrder)\n const extra = calculateExtraSpace(state)\n\n sortedNodes.forEach(node => {\n if (node.order >= 0) {\n if (node.order > currentOrder) {\n currentOrder = node.order\n currentX = nextX + 10 * extra[node.order]!\n }\n node.x = currentX\n nextX = Math.max(nextX, currentX + 40 + node.pixelWidth)\n }\n })\n}\n\n// A lane change rising or falling this many px or less keeps sequenceTubeMap's\n// slope; one rising further turns steeper\nconst RISE_KNEE = 35\n\n// The extra space, in units of 10 px, that a gap takes for a track rising or\n// falling `rise` px across it. Past RISE_KNEE it grows with the square root of\n// the rise, so a long jump steepens its curve more than it widens the column.\nfunction riseExtra(rise: number): number {\n return rise <= RISE_KNEE\n ? rise / 17.5\n : (RISE_KNEE / 17.5) * Math.sqrt(rise / RISE_KNEE)\n}\n\n// calculates additional horizontal space needed between two nodes\n// two neighboring nodes have to be moved further apart if there is a lot going on in between them\n// -> edges turning to vertical orientation should not overlap\nfunction calculateExtraSpace(state: LayoutState): number[] {\n const leftSideEdges: number[] = []\n const rightSideEdges: number[] = []\n const fallAngleAdjustment: number[] = []\n const extra: number[] = []\n\n for (let i = 0; i <= state.maxOrder; i += 1) {\n leftSideEdges.push(0)\n rightSideEdges.push(0)\n fallAngleAdjustment.push(0)\n }\n\n state.tracks.forEach(track => {\n for (let i = 1; i < track.path.length; i += 1) {\n const seg = track.path[i]!\n const prevSeg = track.path[i - 1]!\n // Track is going to the same node, account for space taken up by edges looping around\n if (seg.order === prevSeg.order) {\n // repeat or translocation\n if (seg.isForward) {\n leftSideEdges[seg.order] = leftSideEdges[seg.order]! + 1\n } else {\n rightSideEdges[seg.order] = rightSideEdges[seg.order]! + 1\n }\n } else {\n // TODO: Extra space should also be accounted when there are too many tracks curving at the nodes\n fallAngleAdjustment[seg.order] = Math.max(\n riseExtra(Math.abs((seg.y ?? 0) - (prevSeg.y ?? 0))),\n fallAngleAdjustment[seg.order]!,\n )\n }\n }\n })\n\n extra.push(Math.max(0, leftSideEdges[0]! - 1))\n for (let i = 1; i <= state.maxOrder; i += 1) {\n // Extra space uses space needed for edges(tracks looping), or space needed to limit rise/fall angle, whichever is larger\n extra.push(\n Math.max(\n Math.max(0, leftSideEdges[i]! - 1) +\n Math.max(0, rightSideEdges[i - 1]! - 1),\n fallAngleAdjustment[i]!,\n ),\n )\n }\n return extra\n}\n\n// create and fill assignment-variable, which contains info about tracks and lanes for each order-value\nfunction generateLaneAssignment(state: LayoutState): void {\n // For each horizontal order slot, for each track number, holds the\n // SegmentAssignment object for the visit of that track to that order slot.\n // When an order slot is visited multiple times, holds whatever\n // SegmentAssignment was created most recently.\n const prevSegmentPerOrderPerTrack: SegmentAssignment[][] = []\n // Index into assignments[order] by node, so addToAssignment can find an\n // existing entry without scanning the whole order slot.\n const assignmentByOrderAndNode: Map<number, NodeAssignment>[] = []\n\n // create empty variables\n for (let i = 0; i <= state.maxOrder; i += 1) {\n state.assignments[i] = []\n assignmentByOrderAndNode[i] = new Map()\n prevSegmentPerOrderPerTrack[i] = []\n }\n\n // Record each track's segments in the order slots they cross, leaving the\n // lanes for the sweep below.\n state.tracks.forEach((track, trackNo) => {\n track.path = basicPath(state, track)\n track.path.forEach((segment, segmentNumber) => {\n addToAssignment(\n state,\n segment.order,\n segment.node,\n trackNo,\n segmentNumber,\n prevSegmentPerOrderPerTrack,\n assignmentByOrderAndNode,\n )\n })\n })\n\n // Now sweep left to right across order slots and assign vertical lanes to all the segments.\n for (let i = 0; i <= state.maxOrder; i += 1) {\n generateSingleLaneAssignment(state, state.assignments[i]!, i) // this is where the lanes get assigned\n }\n}\n\nfunction addToAssignment(\n state: LayoutState,\n order: number,\n nodeIndex: number | null,\n trackNo: number,\n segmentID: number,\n prevSegmentPerOrderPerTrack: SegmentAssignment[][],\n assignmentByOrderAndNode: Map<number, NodeAssignment>[],\n): void {\n const segment: SegmentAssignment = {\n trackID: trackNo,\n segmentID,\n compareToFromSame: prevSegmentPerOrderPerTrack[order]![trackNo] ?? null,\n }\n // A null node means the track is passing through / turning around here rather\n // than visiting a node, so such segments never share a NodeAssignment.\n const existing =\n nodeIndex === null\n ? undefined\n : assignmentByOrderAndNode[order]!.get(nodeIndex)\n\n if (existing === undefined) {\n const assignment: NodeAssignment = {\n type: 'single',\n node: nodeIndex,\n tracks: [segment],\n }\n state.assignments[order]!.push(assignment)\n if (nodeIndex !== null) {\n assignmentByOrderAndNode[order]!.set(nodeIndex, assignment)\n }\n } else {\n // add to existing node in assignment\n existing.type = 'multiple'\n existing.tracks.push(segment)\n }\n prevSegmentPerOrderPerTrack[order]![trackNo] = segment\n}\n\n// looks at assignment and sets idealY and idealLane by looking at where the tracks come from\nfunction getIdealLanesAndCoords(\n state: LayoutState,\n assignment: NodeAssignment[],\n order: number,\n): void {\n let index: number\n\n assignment.forEach(node => {\n node.idealLane = 0\n node.tracks.forEach(track => {\n if (track.segmentID === 0) {\n track.idealLane = track.trackID\n track.idealY = null\n } else {\n if (\n state.tracks[track.trackID]!.path[track.segmentID - 1]!.order ===\n order - 1\n ) {\n track.idealLane =\n state.tracks[track.trackID]!.path[track.segmentID - 1]!.lane ??\n undefined\n track.idealY =\n state.tracks[track.trackID]!.path[track.segmentID - 1]!.y\n } else if (\n track.segmentID < state.tracks[track.trackID]!.path.length - 1 &&\n state.tracks[track.trackID]!.path[track.segmentID + 1]!.order ===\n order - 1\n ) {\n track.idealLane =\n state.tracks[track.trackID]!.path[track.segmentID + 1]!.lane ??\n undefined\n track.idealY =\n state.tracks[track.trackID]!.path[track.segmentID + 1]!.y\n } else {\n index = track.segmentID - 1\n while (\n index >= 0 &&\n state.tracks[track.trackID]!.path[index]!.order !== order - 1\n ) {\n index -= 1\n }\n if (index < 0) {\n track.idealLane = track.trackID\n track.idealY = null\n } else {\n track.idealLane = state.tracks[track.trackID]!.path[index]!.lane\n track.idealY = state.tracks[track.trackID]!.path[index]!.y\n }\n }\n }\n node.idealLane! += track.idealLane!\n })\n node.idealLane /= node.tracks.length\n })\n}\n\n// assigns the optimal lanes for a single horizontal position (=order)\n// first an ideal lane is calculated for each track (which is ~ the lane of its predecessor)\n// then the nodes are sorted by their average ideal lane\n// and the whole construct is then moved up or down if necessary\nfunction generateSingleLaneAssignment(\n state: LayoutState,\n assignment: NodeAssignment[],\n order: number,\n): void {\n let currentLane = 0\n const potentialAdjustmentValues = new Set<number>()\n let currentY = 20\n let prevNameIsNull = false\n let prevTrack = -1\n\n getIdealLanesAndCoords(state, assignment, order)\n assignment.sort(compareByIdealLane)\n\n assignment.forEach(node => {\n if (node.node !== null) {\n state.nodes[node.node]!.topLane = currentLane\n if (prevNameIsNull) {\n currentY -= 10\n }\n state.nodes[node.node]!.y = currentY\n state.nodes[node.node]!.contentHeight = 0\n prevNameIsNull = false\n } else {\n if (prevNameIsNull) {\n currentY -= 25\n } else if (currentY > 20) {\n currentY -= 10\n }\n prevNameIsNull = true\n }\n\n node.tracks.sort(compareByIdealLane)\n node.tracks.forEach(track => {\n track.lane = currentLane\n if (track.trackID === prevTrack && node.node === null && prevNameIsNull) {\n currentY += 10\n }\n state.tracks[track.trackID]!.path[track.segmentID]!.lane = currentLane\n state.tracks[track.trackID]!.path[track.segmentID]!.y = currentY\n if (typeof track.idealY === 'number') {\n potentialAdjustmentValues.add(track.idealY - currentY)\n }\n currentLane += 1\n currentY += state.tracks[track.trackID]!.width\n if (node.node !== null) {\n state.nodes[node.node]!.contentHeight +=\n state.tracks[track.trackID]!.width\n }\n prevTrack = track.trackID\n })\n currentY += 25\n })\n\n adjustVertically(state, assignment, potentialAdjustmentValues)\n}\n\n// moves all tracks at a single horizontal location (=order) up/down to minimize lane changes\nfunction adjustVertically(\n state: LayoutState,\n assignment: NodeAssignment[],\n potentialAdjustmentValues: Set<number>,\n): void {\n let verticalAdjustment = 0\n let minAdjustmentCost = Number.MAX_SAFE_INTEGER\n\n potentialAdjustmentValues.forEach(moveBy => {\n const cost = getVerticalAdjustmentCost(state, assignment, moveBy)\n if (cost < minAdjustmentCost) {\n minAdjustmentCost = cost\n verticalAdjustment = moveBy\n }\n })\n\n assignment.forEach(node => {\n if (node.node !== null) {\n state.nodes[node.node]!.y += verticalAdjustment\n }\n node.tracks.forEach(track => {\n const seg = state.tracks[track.trackID]!.path[track.segmentID]!\n seg.y = seg.y! + verticalAdjustment\n })\n })\n}\n\n// Budge down all nodes and out-of-node tracks below this node by this amount\nfunction adjustVertically3(\n state: LayoutState,\n node: LayoutNode,\n adjustBy: number,\n): void {\n if (node.order < 0 || state.assignments[node.order] === undefined) {\n return\n }\n state.assignments[node.order]!.forEach(assignmentNode => {\n if (assignmentNode.node !== null) {\n const aNode = state.nodes[assignmentNode.node]!\n if (aNode !== node && aNode.y > node.y) {\n aNode.y += adjustBy\n assignmentNode.tracks.forEach(track => {\n const seg = state.tracks[track.trackID]!.path[track.segmentID]!\n seg.y = seg.y! + adjustBy\n })\n }\n } else {\n // track-segment not within a node\n assignmentNode.tracks.forEach(track => {\n const seg = state.tracks[track.trackID]!.path[track.segmentID]!\n if (seg.y! >= node.y) {\n seg.y = seg.y! + adjustBy\n }\n })\n }\n })\n if (state.nodesPerOrder[node.order]!.length > 0) {\n state.nodesPerOrder[node.order]!.forEach(nodeIndex => {\n if (\n state.nodes[nodeIndex] !== node &&\n state.nodes[nodeIndex]!.y > node.y\n ) {\n state.nodes[nodeIndex]!.y += adjustBy\n }\n })\n }\n}\n\n// calculates cost of vertical adjustment as vertical distance * width of track\nfunction getVerticalAdjustmentCost(\n state: LayoutState,\n assignment: NodeAssignment[],\n moveBy: number,\n): number {\n let result = 0\n assignment.forEach(node => {\n node.tracks.forEach(track => {\n if (\n typeof track.idealY === 'number' &&\n state.tracks[track.trackID]!.type !== 'read'\n ) {\n result +=\n Math.abs(\n track.idealY -\n moveBy -\n state.tracks[track.trackID]!.path[track.segmentID]!.y!,\n ) * state.tracks[track.trackID]!.width\n }\n })\n })\n return result\n}\n\nfunction compareByIdealLane(\n a: { idealLane?: number | undefined },\n b: { idealLane?: number | undefined },\n): number {\n if (a.idealLane !== undefined) {\n if (b.idealLane !== undefined) {\n if (a.idealLane < b.idealLane) {\n return -1\n } else if (a.idealLane > b.idealLane) {\n return 1\n }\n return 0\n }\n return -1\n }\n if (b.idealLane !== undefined) {\n return 1\n }\n return 0\n}\n\nfunction compareNodesByOrder(\n a: MaybeUnplacedNode,\n b: MaybeUnplacedNode,\n): number {\n if (a.order !== b.order) {\n return a.order - b.order\n }\n if (a.y !== undefined && b.y !== undefined) {\n return a.y - b.y\n }\n return 0\n}\n\nfunction calculateTrackWidth(state: LayoutState): void {\n // flag: if vg returns freq of 0 for all tracks, we will increase width manually\n let allAreFour = true\n\n const NARROW_WIDTH = 4\n const WIDE_WIDTH = state.config.trackWidth\n\n if (state.config.freqWidth === 'linear') {\n for (const track of state.tracks) {\n track.width =\n track.type === 'read'\n ? NARROW_WIDTH\n : Math.max(1, Math.round(track.freq ?? 1)) * WIDE_WIDTH\n }\n return\n }\n\n for (const track of state.tracks) {\n if (track.freq !== undefined) {\n track.width = Math.round(\n (Math.log(Math.max(track.freq, 1)) + 1) * NARROW_WIDTH,\n )\n } else {\n // default track width\n track.width = WIDE_WIDTH\n if (track.type !== undefined && track.type === 'read') {\n track.width = NARROW_WIDTH\n }\n }\n if (track.width !== NARROW_WIDTH) {\n allAreFour = false\n }\n }\n\n if (allAreFour) {\n state.tracks.forEach(track => {\n if (track.freq !== undefined) {\n track.width = WIDE_WIDTH\n }\n })\n }\n}\n\nfunction getReadXStart(state: LayoutState, read: Track): number {\n const seg = read.path[0]!\n const node = state.nodes[seg.node!]!\n const offset = read.firstNodeOffset ?? 0\n // read starts in forward direction, or backward from the node's far end\n return clampedXCoordinateOfBaseWithinNode(\n node,\n seg.isForward ? offset : node.sequenceLength - offset,\n )\n}\n\nfunction getReadXEnd(state: LayoutState, read: Track): number {\n const seg = read.path[read.path.length - 1]!\n const node = state.nodes[seg.node!]!\n const cover = read.finalNodeCoverLength ?? 0\n // read ends in forward direction, or backward from the node's far end\n return clampedXCoordinateOfBaseWithinNode(\n node,\n seg.isForward ? cover : node.sequenceLength - cover,\n )\n}\n\n// returns the x coordinate (in pixels) of (the left side) of the given base\n// position within the given node, or null if the position is past its end\nexport function getXCoordinateOfBaseWithinNode(\n node: Node,\n base: number,\n): number | null {\n if (base > node.sequenceLength) {\n return null\n } // equality is allowed\n return clampedXCoordinateOfBaseWithinNode(node, base)\n}\n\n// Same, but a base outside the node maps to the nearest node edge. Callers that\n// have to produce a coordinate no matter what use this: falling back to 0 would\n// put the shape at the far left of the whole image instead.\nexport function clampedXCoordinateOfBaseWithinNode(\n node: Node,\n base: number,\n): number {\n const [nodeLeftX, nodeRightX] = nodePixelCoordinatesInX(node)\n if (node.sequenceLength === 0) {\n return nodeLeftX\n }\n const clamped = Math.min(Math.max(base, 0), node.sequenceLength)\n return nodeLeftX + (clamped / node.sequenceLength) * (nodeRightX - nodeLeftX)\n}\n\n// transforms the info in the tracks' path attribute into actual coordinates\n// and saves them in shapes.rectangles and shapes.curves\nfunction generateSVGShapesFromPath(state: LayoutState): void {\n let xStart: number\n let xEnd: number\n let yStart: number\n let yEnd: number\n\n for (let i = 0; i <= state.maxOrder; i += 1) {\n state.extraLeft.push(0)\n state.extraRight.push(0)\n }\n\n // generate x coords where each order starts and ends\n const orderStartX: number[] = []\n const orderEndX: number[] = []\n state.nodes.forEach((node: MaybeUnplacedNode) => {\n if (node.x !== undefined) {\n orderStartX[node.order] = node.x\n if (orderEndX[node.order] === undefined) {\n orderEndX[node.order] = node.x + node.pixelWidth\n } else {\n orderEndX[node.order] = Math.max(\n orderEndX[node.order]!,\n node.x + node.pixelWidth,\n )\n }\n }\n })\n\n const reference = state.tracks[0]\n\n // Helps generation of verticalRectangles, correct increments of extraRight and extraLeft\n state.tracks.sort(compareTrackByInitialOrdering)\n\n state.tracks.forEach(track => {\n // start of path\n yStart = track.path[0]!.y!\n if (track.type !== 'read') {\n if (track.sequence[0]!.startsWith('-')) {\n // The track starts with an inversed node\n xStart = orderEndX[track.path[0]!.order]! + 20\n } else {\n // The track starts with a forward node\n xStart = orderStartX[track.path[0]!.order]! - 20\n }\n } else {\n xStart = getReadXStart(state, track)\n }\n\n // middle of path\n for (let i = 0; i < track.path.length; i += 1) {\n if (track.path[i]!.y !== yStart) {\n if (track.path[i - 1]!.isForward) {\n xEnd = orderEndX[track.path[i - 1]!.order]!\n } else {\n xEnd = orderStartX[track.path[i - 1]!.order]!\n }\n if (xEnd !== xStart) {\n state.shapes.rectangles.push({\n xStart: Math.min(xStart, xEnd),\n yStart,\n xEnd: Math.max(xStart, xEnd),\n yEnd: yStart + track.width - 1,\n // TODO: This is not actually the index of the track!\n id: track.id,\n name: track.name,\n type: track.type,\n })\n }\n\n if (track.path[i]!.order - 1 === track.path[i - 1]!.order) {\n // regular forward connection\n xStart = xEnd\n xEnd = orderStartX[track.path[i]!.order]!\n yEnd = track.path[i]!.y!\n state.shapes.curves.push({\n xStart,\n yStart,\n xEnd: xEnd + 1,\n yEnd,\n width: track.width,\n id: track.id,\n name: track.name,\n type: track.type,\n nodeStart: track.path[i - 1]!.node,\n nodeEnd: track.path[i]!.node,\n orderStart: track.path[i - 1]!.order,\n orderEnd: track.path[i]!.order,\n ...(track === reference ? { reference: true } : {}),\n })\n xStart = xEnd\n yStart = yEnd\n } else if (track.path[i]!.order + 1 === track.path[i - 1]!.order) {\n // regular backward connection\n xStart = xEnd\n xEnd = orderEndX[track.path[i]!.order]!\n yEnd = track.path[i]!.y!\n state.shapes.curves.push({\n xStart: xStart + 1,\n yStart,\n xEnd,\n yEnd,\n width: track.width,\n id: track.id,\n name: track.name,\n type: track.type,\n nodeStart: track.path[i - 1]!.node,\n nodeEnd: track.path[i]!.node,\n orderStart: track.path[i - 1]!.order,\n orderEnd: track.path[i]!.order,\n ...(track === reference ? { reference: true } : {}),\n })\n xStart = xEnd\n yStart = yEnd\n } else {\n // change of direction\n if (track.path[i - 1]!.isForward) {\n yEnd = track.path[i]!.y!\n generateTurnaround(\n state,\n 1,\n xEnd,\n yStart,\n yEnd,\n track.width,\n track.id,\n track.path[i]!.order,\n track.type,\n track.name,\n )\n xStart = orderEndX[track.path[i]!.order]!\n yStart = track.path[i]!.y!\n } else {\n yEnd = track.path[i]!.y!\n generateTurnaround(\n state,\n -1,\n xEnd,\n yStart,\n yEnd,\n track.width,\n track.id,\n track.path[i]!.order,\n track.type,\n track.name,\n )\n xStart = orderStartX[track.path[i]!.order]!\n yStart = track.path[i]!.y!\n }\n }\n }\n }\n\n // ending edges\n if (track.type !== 'read') {\n if (!track.path[track.path.length - 1]!.isForward) {\n // The track ends with an inversed node\n xEnd = orderStartX[track.path[track.path.length - 1]!.order]! - 20\n } else {\n // The track ends with a forward node\n xEnd = orderEndX[track.path[track.path.length - 1]!.order]! + 20\n }\n } else {\n xEnd = getReadXEnd(state, track)\n }\n state.shapes.rectangles.push({\n xStart: Math.min(xStart, xEnd),\n yStart,\n xEnd: Math.max(xStart, xEnd),\n yEnd: yStart + track.width - 1,\n id: track.id,\n name: track.name,\n type: track.type,\n })\n })\n}\n\n// Sankey-mode synthesis: one synthetic \"read\" per (srcSigned \u2192 dstSigned) edge,\n// fed through the normal placeReads/generateSVGShapesFromPath pipeline so the\n// band gets the same lane assignment, loop topology and bezier shape as a real\n// read. A read band takes its source's palette; a haplotype band carries its\n// share of the haplotypes for the colorer to shade by.\n//\n// Synthetic-track ids live above this base so they don't collide with real\n// track ids and so click/hover handlers can show count info instead of the\n// per-read info dialog.\nconst COARSENED_ID_BASE = 1_000_000_000\nexport const isCoarsenedId = (id: number) => id >= COARSENED_ID_BASE\n\n// Build one synthetic read per (srcSigned \u2192 dstSigned) edge in `source`\n// (real reads, or the alt haplotype tracks). The synthetic reads replace the\n// real ones BEFORE placeReads runs, so:\n// \u2022 placeReads sees N_edges reads instead of N_reads (huge node-height win),\n// \u2022 each band gets a lane and an \"right-down-left-up-right\" loop topology\n// for free (placeReads handles reversals and out-of-order jumps),\n// \u2022 generateSVGShapesFromPath emits exactly one TrackCurve per band using\n// the same bezier as a real read \u2014 no special draw path needed.\n//\n// The synthetic track's `sequence` is just the two signed node names. After\n// generateTrackIndexSequences runs, indexSequence is set and the rest of the\n// layout follows.\nfunction buildCoarsenedSyntheticBands(\n state: LayoutState,\n source: Track[],\n unit: CoarsenedUnit,\n firstId = COARSENED_ID_BASE,\n): { bands: Track[]; total: number } {\n // Aggregate by signed-edge key. Preserve orientation so e.g. (+A\u2192+B) and\n // (-B\u2192-A) stack as separate bands \u2014 they're different visual flows.\n interface EdgeAgg {\n sSigned: number\n dSigned: number\n sName: string\n dName: string\n // distinct walks, so a walk that loops back over an edge, or crosses it\n // both ways under ignoreStrand, counts once\n count: number\n // every crossing, loops included, which is what sizes the band\n crossings: number\n sourceTrackID: number\n lastSource: number\n }\n const edges = new Map<number, EdgeAgg>()\n let total = 0\n // One number per signed edge: signed indices run from -span to span.\n const span = state.nodes.length\n const edgeKey = (s: number, d: number): number =>\n (s + span) * (2 * span + 1) + d + span\n // When ignoring strand, (+A\u2192+B) and (-B\u2192-A) refer to the same underlying\n // graph connection, so both collapse into the smaller of their two keys;\n // whichever orientation is seen first determines the visual band direction.\n const ignoreStrand = state.config.ignoreStrand\n for (const [sourceIndex, item] of source.entries()) {\n // a deduplicated walk stands for `freq` identical haplotypes\n const weight = Math.max(item.freq ?? 1, 1)\n total += weight\n const seq = item.indexSequence\n if (seq.length < 2) {\n continue\n }\n for (let i = 0; i < seq.length - 1; i += 1) {\n const sSigned = seq[i]!\n const dSigned = seq[i + 1]!\n const srcNode = state.nodes[Math.abs(sSigned)]!\n const dstNode = state.nodes[Math.abs(dSigned)]!\n const key = ignoreStrand\n ? Math.min(edgeKey(sSigned, dSigned), edgeKey(-dSigned, -sSigned))\n : edgeKey(sSigned, dSigned)\n const existing = edges.get(key)\n if (existing === undefined) {\n edges.set(key, {\n sSigned,\n dSigned,\n sName: sSigned < 0 ? `-${srcNode.name}` : srcNode.name,\n dName: dSigned < 0 ? `-${dstNode.name}` : dstNode.name,\n count: weight,\n crossings: weight,\n sourceTrackID: item.sourceTrackID,\n lastSource: sourceIndex,\n })\n } else {\n existing.crossings += weight\n if (existing.lastSource !== sourceIndex) {\n existing.count += weight\n existing.lastSource = sourceIndex\n }\n }\n }\n }\n\n // Square-root scaling on crossings gives heavy edges visible weight without\n // letting one massive edge dwarf everything else. Min stays near READ_WIDTH\n // so single-read edges still look like a normal read; max is generous so\n // hot edges read as obvious \"highways.\"\n let maxEdgeCount = 0\n for (const e of edges.values()) {\n if (e.crossings > maxEdgeCount) {\n maxEdgeCount = e.crossings\n }\n }\n const BAND_MIN_WIDTH = READ_WIDTH\n const BAND_MAX_WIDTH = 60\n const widthForCount = (c: number): number => {\n if (maxEdgeCount <= 1) {\n return BAND_MIN_WIDTH\n }\n return (\n BAND_MIN_WIDTH +\n (BAND_MAX_WIDTH - BAND_MIN_WIDTH) * Math.sqrt(c / maxEdgeCount)\n )\n }\n\n const synthetic: Track[] = []\n let i = 0\n for (const edge of edges.values()) {\n const id = firstId + i\n const share =\n unit === 'haplotype' ? { count: edge.count, total } : undefined\n const shareText = share === undefined ? '' : ` (${formatShare(share)})`\n const crossingsText =\n edge.crossings === edge.count\n ? ''\n : `, ${edge.crossings.toLocaleString()} crossings`\n const label = `${edge.count.toLocaleString()} ${unit}${edge.count === 1 ? '' : 's'}${shareText}${crossingsText}: Node ${edge.sName} \u2192 Node ${edge.dName}`\n state.coarsenedEdgeMeta.set(id, { count: edge.count, label })\n // Place each synthetic band so it touches *only* its endpoint nodes' edges:\n // \u2022 firstNodeOffset = src.sequenceLength \u2192 curve exits at src's right\n // pixel edge, no rectangle drawn inside src.\n // \u2022 finalNodeCoverLength = 0 \u2192 curve enters at dst's left pixel edge,\n // no rectangle drawn inside dst.\n // The crucial side effect is in placeReadSet's conflict check: at any\n // node B with an incoming edge (A\u2192B) and an outgoing edge (B\u2192C), the\n // incoming's finalNodeCoverLength=0 and the outgoing's firstNodeOffset=\n // B.length leave them with no horizontal overlap, so they share a single\n // lane. Node heights collapse from ~(N_in + N_out) lanes down to\n // ~max(N_in, N_out) lanes.\n //\n // Note: reverseReversedReads will swap firstNodeOffset/finalNodeCoverLength\n // for fully-reverse synthetics. The math works out: pre-flip values of\n // (srcLen, 0) become post-flip (newSrcLen, 0), which is the same pattern\n // \u2014 bands stay edge-only regardless of orientation.\n const srcLen = state.nodes[Math.abs(edge.sSigned)]!.sequenceLength\n synthetic.push({\n id,\n sourceTrackID: edge.sourceTrackID,\n type: 'read',\n // Human-readable so the name surfaces sensibly in any UI that uses it\n // (right-click \u2192 add to group, etc.) \u2014 and so trackTooltipText fallback\n // shows something meaningful.\n name: label,\n sequence: [edge.sName, edge.dName],\n indexSequence: [],\n path: [],\n // Pre-set width so placeReads / placeReadSet allocate the right vertical\n // space and assignReadsToNodes (patched to honor pre-set widths) leaves\n // it alone.\n width: widthForCount(edge.crossings),\n firstNodeOffset: srcLen,\n finalNodeCoverLength: 0,\n sequenceNew: [\n { nodeName: edge.sName, mismatches: [] },\n { nodeName: edge.dName, mismatches: [] },\n ],\n mapping_quality: 0,\n is_secondary: false,\n sample_name: null,\n read_group: null,\n score: edge.count,\n haplotypeShare: share,\n })\n i += 1\n }\n\n if (DEBUG) {\n let tallestName = '?'\n let tallestH = 0\n state.nodes.forEach(n => {\n if (n.contentHeight > tallestH) {\n tallestH = n.contentHeight\n tallestName = n.name\n }\n })\n debugLog(\n `[coarsened] ${unit}s_in=${source.length} edges_out=${synthetic.length} ` +\n `tallestNodeBeforePlace=${tallestName}(${tallestH.toFixed(1)})`,\n )\n }\n return { bands: synthetic, total }\n}\n\n// Band every haplotype but the reference, which keeps its lane and the ruler.\n// Undefined when no alternate crosses an edge: a haplotype that stays on one\n// node makes no band, and its node would get no y from the read overlay.\nfunction bandHaplotypes(\n state: LayoutState,\n firstId: number,\n): { ref: Track; bands: Track[]; total: number } | undefined {\n const rulerIndex =\n state.trackForRuler === undefined\n ? -1\n : state.tracks.findIndex(t => t.name === state.trackForRuler)\n const refIndex = rulerIndex === -1 ? 0 : rulerIndex\n const ref = state.tracks[refIndex]!\n // A deduplicated reference walk also stands for the haplotypes identical to\n // it through the window; those belong in the bands, not the reference lane.\n const refDuplicates = (ref.freq ?? 1) - 1\n const refSigns = firstVisitSigns(state, ref)\n const altHaplotypes = state.tracks\n .filter((_, i) => i !== refIndex)\n .map(walk => orientedLike(refSigns, walk))\n if (refDuplicates > 0) {\n altHaplotypes.push({ ...ref, freq: refDuplicates })\n }\n if (altHaplotypes.length === 0) {\n return undefined\n }\n const { bands, total } = buildCoarsenedSyntheticBands(\n state,\n altHaplotypes,\n 'haplotype',\n firstId,\n )\n return bands.length > 0 ? { ref, bands, total } : undefined\n}\n\n// A graph can store a walk in either orientation, so a haplotype can arrive\n// back to front relative to the reference. Banded that way, one allele splits\n// into a forward and a reverse band. Turn a walk around when it runs against\n// the reference on most of the nodes they share.\nfunction orientedLike(refSigns: Int8Array, walk: Track): Track {\n let agreement = 0\n for (const visit of walk.indexSequence) {\n const sign = refSigns[Math.abs(visit)]\n if (sign !== undefined && sign !== 0) {\n agreement += sign === Math.sign(visit) ? 1 : -1\n }\n }\n return agreement >= 0\n ? walk\n : {\n ...walk,\n sequence: walk.sequence.map(flip).reverse(),\n indexSequence: walk.indexSequence.map(visit => -visit).reverse(),\n }\n}\n\n// The sign of `ref`'s first visit to each node index, 0 where it never visits.\nfunction firstVisitSigns(state: LayoutState, ref: Track): Int8Array {\n const signs = new Int8Array(state.nodes.length)\n for (const visit of ref.indexSequence) {\n const node = Math.abs(visit)\n if (signs[node] === 0) {\n signs[node] = Math.sign(visit)\n }\n }\n return signs\n}\n\nfunction formatShare({ count, total }: HaplotypeShare): string {\n const share = count / total\n if (share < 0.01) {\n return '<1%'\n }\n if (share > 0.99 && count < total) {\n return '>99%'\n }\n return `${Math.round(share * 100)}%`\n}\n\nconst MIN_BEND_WIDTH = 7\n\n// Emit the vertical rectangles + rounded corners for a track turning around at\n// one end of an order slot. The two directions are mirror images of each other:\n// a forward-to-reverse turn bulges out to the right of the node and consumes an\n// `extraRight` slot, a reverse-to-forward turn bulges out to the left and\n// consumes an `extraLeft` slot. `dir` is +1 for right, -1 for left.\nfunction generateTurnaround(\n state: LayoutState,\n dir: 1 | -1,\n x: number,\n yStart: number,\n yEnd: number,\n trackWidth: number,\n trackID: number,\n order: number,\n type: TrackType | undefined,\n trackName: string | undefined,\n): void {\n const extra = dir === 1 ? state.extraRight : state.extraLeft\n const offset = 10 * extra[order]!\n // The turn's apex, and the outward direction from it.\n const apex = x + dir * (offset + 5)\n const radius = MIN_BEND_WIDTH\n const stem = Math.min(MIN_BEND_WIDTH, trackWidth)\n const yTop = Math.min(yStart, yEnd)\n const yBottom = Math.max(yStart, yEnd)\n // The incoming/outgoing stubs run from the node's edge out to the apex. The\n // one-pixel asymmetry between the two directions is carried over verbatim\n // from the original pair of functions.\n const stubNear = dir === 1 ? x : apex - 1\n const stubFar = dir === 1 ? apex : x\n\n const horizontal = (segTop: number): void => {\n state.shapes.verticalRectangles.push({\n xStart: stubNear,\n yStart: segTop,\n xEnd: stubFar,\n yEnd: segTop + trackWidth - 1,\n id: trackID,\n name: trackName,\n type,\n })\n }\n // elongate the incoming and outgoing rectangles a bit past the node\n horizontal(yStart)\n state.shapes.verticalRectangles.push({\n xStart: dir === 1 ? apex + radius : apex - radius - stem,\n yStart: yTop + trackWidth + radius - 1,\n xEnd: dir === 1 ? apex + radius + stem - 1 : apex - radius - 1,\n yEnd: yBottom - radius + 1,\n id: trackID,\n name: trackName,\n type,\n })\n horizontal(yEnd)\n\n const inner = apex + dir * radius\n const outer = apex + dir * (radius + stem)\n\n // bottom 90 degree bend\n let d = `M ${apex} ${yBottom}`\n d += ` Q ${inner} ${yBottom} ${inner} ${yBottom - radius}`\n d += ` H ${outer}`\n d += ` Q ${outer} ${yBottom + trackWidth} ${apex} ${yBottom + trackWidth}`\n d += ' Z '\n state.shapes.corners.push({ path: d, id: trackID, type })\n\n // top 90 degree bend\n d = `M ${apex} ${yTop}`\n d += ` Q ${outer} ${yTop} ${outer} ${yTop + trackWidth + radius}`\n d += ` H ${inner}`\n d += ` Q ${inner} ${yTop + trackWidth} ${apex} ${yTop + trackWidth}`\n d += ' Z '\n state.shapes.corners.push({ path: d, id: trackID, type })\n extra[order]! += 1\n}\n\n// The x extent of a node's bases: pixelWidth, plus about half a character\n// each side under nodeWidthOption 'normal'\nexport function nodePixelCoordinatesInX(node: Node): [number, number] {\n const nodeLeftX = node.x - 4\n const nodeRightX = node.x + node.pixelWidth + 4\n return [nodeLeftX, nodeRightX]\n}\n\n// calculate node widths depending on sequence lengths and chosen calculation method\nfunction generateNodeWidth(state: LayoutState): void {\n switch (state.config.nodeWidthOption) {\n case 'compressed':\n state.nodes.forEach(node => {\n node.width = 1 + Math.log2(Math.max(node.sequenceLength, 1))\n node.pixelWidth = Math.round((node.width - 1) * 8.401)\n })\n break\n case 'small':\n state.nodes.forEach(node => {\n node.width = node.sequenceLength / 100\n node.pixelWidth = Math.max(Math.round((node.width - 1) * 8.401), 0)\n })\n break\n case 'fixed':\n state.nodes.forEach(node => {\n node.width = 10\n node.pixelWidth = Math.round(node.width * 8.401)\n })\n break\n case 'normal': {\n // The label draws a base per character from x - 4, in a monospace font\n // whose character width the caller measures. pixelWidth runs from the\n // first character to the last, so the outline, 9 px wider each side,\n // holds the whole label, and nodePixelCoordinatesInX's half character\n // each side puts base i under letter i.\n const charWidth = state.config.charWidth\n state.nodes.forEach(node => {\n node.width = node.sequenceLength\n node.pixelWidth = Math.round(\n charWidth * Math.max(node.sequenceLength - 1, 0),\n )\n })\n break\n }\n default:\n throw new Error(`${state.config.nodeWidthOption} not implemented`)\n }\n}\n\n// A node's distinct neighbors on one side, kept only as far as mergeNodes\n// needs them: none, exactly one, or several. A neighbor is a signed node index,\n// or TRACK_END where a haplotype starts or stops.\ninterface Neighbors {\n first: Int32Array\n count: Uint8Array\n}\n\nconst TRACK_END = 0\n\nfunction noNeighbors(nodeCount: number): Neighbors {\n return { first: new Int32Array(nodeCount), count: new Uint8Array(nodeCount) }\n}\n\nfunction addNeighbor(\n neighbors: Neighbors,\n index: number,\n neighbor: number,\n): void {\n const count = neighbors.count[index]!\n if (count === 0) {\n neighbors.first[index] = neighbor\n neighbors.count[index] = 1\n } else if (count === 1 && neighbors.first[index] !== neighbor) {\n neighbors.count[index] = 2\n }\n}\n\n// The index of a node's one neighbor on this side, or 0 when it has none,\n// several, or a track end.\nfunction soleNeighbor(neighbors: Neighbors, index: number): number {\n return neighbors.count[index] === 1 ? Math.abs(neighbors.first[index]!) : 0\n}\n\n// remove redundant nodes\n// two nodes A and B can be merged if all tracks leaving A go directly into B\n// and all tracks entering B come directly from A\n// (plus no inversions involved)\nfunction mergeNodes(state: LayoutState): void {\n const pred = noNeighbors(state.nodes.length)\n const succ = noNeighbors(state.nodes.length)\n const signedIndexOf = new Map<string, number>()\n const visit = (nodeName: string): number => {\n let signed = signedIndexOf.get(nodeName)\n if (signed === undefined) {\n const index = state.nodeMap.get(forward(nodeName))!\n signed = isReverse(nodeName) ? -index : index\n signedIndexOf.set(nodeName, signed)\n }\n return signed\n }\n\n const tracksAndReads = state.tracks.concat(state.reads)\n\n // A reverse visit on either side adds both orientations of the neighbor, so\n // no merge happens across an inversion.\n tracksAndReads.forEach(track => {\n const { sequence } = track\n const isHaplotype = track.type === 'haplotype'\n const last = sequence.length - 1\n let previous = TRACK_END\n let current = last >= 0 ? visit(sequence[0]!) : TRACK_END\n for (let i = 0; i <= last; i += 1) {\n const next = i < last ? visit(sequence[i + 1]!) : TRACK_END\n if (current > 0) {\n if (i > 0) {\n addNeighbor(pred, current, previous)\n if (previous < 0) {\n addNeighbor(pred, current, -previous)\n }\n } else if (isHaplotype) {\n addNeighbor(pred, current, TRACK_END)\n }\n if (i < last) {\n addNeighbor(succ, current, next)\n if (next < 0) {\n addNeighbor(succ, current, -next)\n }\n } else if (isHaplotype) {\n addNeighbor(succ, current, TRACK_END)\n }\n } else {\n const index = -current\n if (i > 0) {\n addNeighbor(succ, index, -previous)\n if (previous > 0) {\n addNeighbor(succ, index, previous)\n }\n } else if (isHaplotype) {\n addNeighbor(succ, index, TRACK_END)\n }\n if (i < last) {\n addNeighbor(pred, index, -next)\n if (next > 0) {\n addNeighbor(pred, index, next)\n }\n } else if (isHaplotype) {\n addNeighbor(pred, index, TRACK_END)\n }\n }\n previous = current\n current = next\n }\n })\n\n const absorbed = new Uint8Array(state.nodes.length)\n state.nodes.forEach((_, i) => {\n if (mergeableWithPred(i, pred, succ) !== 0) {\n absorbed[i] = 1\n }\n })\n\n // Merge each run into its first node, noting the node every run member\n // merges into and where the member's bases start and end within it.\n const origin = new Int32Array(state.nodes.length)\n const start = new Float64Array(state.nodes.length)\n const end = new Float64Array(state.nodes.length)\n state.nodes.forEach((node, head) => {\n if (absorbed[head] === 1) {\n return\n }\n origin[head] = head\n end[head] = node.sequenceLength\n for (let donor = head; mergeableWithSucc(donor, pred, succ);) {\n donor = soleNeighbor(succ, donor)\n origin[donor] = head\n start[donor] = node.sequenceLength\n node.sequenceLength += state.nodes[donor]!.sequenceLength\n node.seq += state.nodes[donor]!.seq\n end[donor] = node.sequenceLength\n }\n })\n\n // A read's offsets and mismatch positions count along the strand it visits\n // a node on: from the left end of a forward visit, the right end of a\n // reverse one. A forward visit to an absorbed node folds into the visit\n // before it, a reverse one into the visit after it.\n state.reads.forEach(read => {\n const { sequence } = read\n const entries =\n read.sequenceNew ??\n sequence.map(nodeName => ({ nodeName, mismatches: [] as Mismatch[] }))\n const shift = (nodeName: string): number => {\n const index = Math.abs(visit(nodeName))\n return isReverse(nodeName)\n ? state.nodes[origin[index]!]!.sequenceLength - end[index]!\n : start[index]!\n }\n const last = sequence.length - 1\n read.firstNodeOffset = (read.firstNodeOffset ?? 0) + shift(sequence[0]!)\n read.finalNodeCoverLength =\n (read.finalNodeCoverLength ?? 0) + shift(sequence[last]!)\n\n const mergedSequence: string[] = []\n const mergedEntries: ReadSequenceEntry[] = []\n let carried: Mismatch[] = []\n sequence.forEach((nodeName, i) => {\n const index = Math.abs(visit(nodeName))\n const { mismatches } = entries[i]!\n const by = shift(nodeName)\n mismatches.forEach(mismatch => {\n mismatch.pos += by\n })\n if (absorbed[index] === 1 && !isReverse(nodeName) && i > 0) {\n mergedEntries.at(-1)!.mismatches.push(...mismatches)\n } else if (absorbed[index] === 1 && isReverse(nodeName) && i < last) {\n carried.push(...mismatches)\n } else {\n const name = state.nodes[origin[index]!]!.name\n const merged = isReverse(nodeName) ? reverse(name) : name\n mergedSequence.push(merged)\n mergedEntries.push({\n nodeName: merged,\n mismatches: carried.concat(mismatches),\n })\n carried = []\n }\n })\n read.sequence = mergedSequence\n if (read.sequenceNew !== undefined) {\n read.sequenceNew = mergedEntries\n }\n })\n\n state.tracks.forEach(track => {\n const { sequence } = track\n let kept = 0\n for (const nodeName of sequence) {\n if (absorbed[Math.abs(visit(nodeName))] === 0) {\n sequence[kept] = nodeName\n kept += 1\n }\n }\n sequence.length = kept\n })\n\n let kept = 1\n for (let i = 1; i < state.nodes.length; i += 1) {\n if (absorbed[i] === 0) {\n state.nodes[kept] = state.nodes[i]!\n kept += 1\n }\n }\n state.nodes.length = kept\n}\n\n// The index of the node `index` merges into, or 0 when it merges into none.\nfunction mergeableWithPred(\n index: number,\n pred: Neighbors,\n succ: Neighbors,\n): number {\n const predecessor = soleNeighbor(pred, index)\n return predecessor !== 0 && soleNeighbor(succ, predecessor) !== 0\n ? predecessor\n : 0\n}\n\nfunction mergeableWithSucc(\n index: number,\n pred: Neighbors,\n succ: Neighbors,\n): boolean {\n const successor = soleNeighbor(succ, index)\n return successor !== 0 && soleNeighbor(pred, successor) !== 0\n}\n", "// SVG path data for the shapes a layout leaves as coordinates: a curve's\n// ribbon and a node's rounded outline. Both are strings so the same geometry\n// draws as an SVG `d` attribute or, through Path2D, on a canvas, and\n// flattenPath turns either into points for a renderer that fills polygons.\nimport type { Node, TrackCurve, TrackType } from './types.ts'\n\nfunction groupBy<T, K>(items: readonly T[], key: (item: T) => K): Map<K, T[]> {\n const groups = new Map<K, T[]>()\n for (const item of items) {\n const k = key(item)\n const group = groups.get(k)\n if (group === undefined) {\n groups.set(k, [item])\n } else {\n group.push(item)\n }\n }\n return groups\n}\n\nfunction compareCurvesByXYStartValue(a: TrackCurve, b: TrackCurve): number {\n if (a.xStart < b.xStart) {\n return 1\n } else if (a.xStart > b.xStart) {\n return -1\n } else if (a.yStart > b.yStart) {\n return 1\n } else if (a.yStart < b.yStart) {\n return -1\n }\n return 0\n}\n\n// Where a curve leaves and enters: a node, or a gap at an order slot\nfunction curveEnds(curve: TrackCurve): [number, number, number, number] {\n return [\n curve.nodeStart ?? -1,\n curve.nodeEnd ?? -1,\n curve.nodeStart === null ? curve.orderStart : -1,\n curve.nodeEnd === null ? curve.orderEnd : -1,\n ]\n}\n\nfunction compareTuples(a: readonly number[], b: readonly number[]): number {\n for (let i = 0; i < a.length; i += 1) {\n const d = a[i]! - b[i]!\n if (d !== 0) {\n return d\n }\n }\n return 0\n}\n\n// Where a cubic with both control points at one x is steepest, it is 3/4 of\n// the way from the ends' mean x to that control x\nconst STEEP_SHARE = 0.75\n// The most of a gap a group's steep stretch may spread over, so its edges keep\n// some of the turn\nconst MAX_SPREAD = 0.8\n\n// How far apart, as shares of the gap, each curve of a group puts its top and\n// bottom edges' control points. A ribbon whose edges turn at one x is only as\n// thick across as its width times the cosine of its slope, which on a steep\n// lane change is a hairline; with its outer edge turning late and its inner\n// edge early, its steep stretch keeps its width, or as much as the gap allows.\n// A shallow curve needs none. The reference takes what it needs first, so its\n// line stays legible where a wide tube shares its gap. Groups of more than five\n// keep at least sequenceTubeMap's 0.4 in all, which stops their curves\n// crossing at one x.\nfunction spreads(group: readonly TrackCurve[], gapWidth: number) {\n const first = group[0]!\n const span = Math.min(Math.abs(first.xEnd - first.xStart), gapWidth)\n if (span === 0) {\n return group.map(() => 0)\n }\n const floor = group.length > 5 ? 0.4 / group.length : 0\n const wanted = group.map(c => {\n const rise = Math.abs(c.yEnd - c.yStart)\n const across =\n (rise / Math.hypot(rise, span)) *\n Math.min(c.width, MAX_SPREAD * STEEP_SHARE * span)\n return Math.max(floor, across / (STEEP_SHARE * span))\n })\n const sum = (pick: (c: TrackCurve) => boolean) =>\n wanted.reduce((total, w, i) => total + (pick(group[i]!) ? w : 0), 0)\n const reference = sum(c => c.reference === true)\n const others = sum(c => c.reference !== true)\n const referenceScale = reference > MAX_SPREAD ? MAX_SPREAD / reference : 1\n const room = MAX_SPREAD - reference * referenceScale\n const othersScale = others > room ? room / others : 1\n return wanted.map(\n (w, i) => w * (group[i]!.reference ? referenceScale : othersScale),\n )\n}\n\nexport interface CurvePathOptions {\n // The most px a gap between columns draws across, where the drawing squeezes\n // the layout's x, as a reference axis does; a curve's steepness is judged at\n // that width\n gapWidth?: number\n}\n\n// The curves of one track type in draw order, each with its `path` set. Curves\n// between the same pair of nodes, or gaps, form a group whose control points\n// fan out top to bottom, so a bundle of tracks changing lanes together stays\n// parallel rather than crossing at one x, and each curve's bottom edge is the\n// next one's top edge.\nexport function curvePaths(\n curves: readonly TrackCurve[],\n type: TrackType | undefined,\n { gapWidth = Infinity }: CurvePathOptions = {},\n): TrackCurve[] {\n const groupedCurves = groupBy(\n curves.filter(curve => curve.type === type),\n curve => curveEnds(curve).join(','),\n )\n\n groupedCurves.forEach(curveGroup => {\n curveGroup.sort(compareCurvesByXYStartValue)\n const spread = spreads(curveGroup, gapWidth)\n // share of the gap at which a boundary between the group's tubes turns,\n // for a curve that rises; one that falls turns at its complement\n let adjustValue = 0.5 - spread.reduce((sum, s) => sum + s, 0) / 2\n\n curveGroup.forEach((curve, i) => {\n const at = (share: number) =>\n curve.xStart +\n (curve.xEnd - curve.xStart) *\n (curve.yStart < curve.yEnd ? 1 - share : share)\n const xAdjusted = at(adjustValue)\n adjustValue += spread[i]!\n // the bottom edge, on the way back, parallel to the next curve's top\n const xNextAdjusted = at(adjustValue)\n let d = `M ${curve.xStart} ${curve.yStart}`\n d += ` C ${xAdjusted} ${curve.yStart} ${xAdjusted} ${curve.yEnd} ${curve.xEnd} ${curve.yEnd}`\n d += ` V ${curve.yEnd + curve.width}`\n d += ` C ${xNextAdjusted} ${curve.yEnd + curve.width} ${xNextAdjusted} ${\n curve.yStart + curve.width\n } ${curve.xStart} ${curve.yStart + curve.width}`\n d += ' Z'\n curve.path = d\n })\n })\n\n // One flat list ordered by group, then by the within-group sort\n return [...groupedCurves.values()]\n .sort((a, b) => compareTuples(curveEnds(a[0]!), curveEnds(b[0]!)))\n .flat()\n}\n\n// The outline that path data from curvePaths, nodeOutlinePath or a corner\n// traces, as points, for a renderer that fills polygons rather than paths.\n// Each B\u00E9zier becomes `steps` straight pieces; the closing Z adds no point.\nexport function flattenPath(d: string, steps = 16): [number, number][] {\n const tokens = d.match(/[A-Za-z]|-?(?:\\d+\\.?\\d*|\\.\\d+)(?:e[-+]?\\d+)?/g) ?? []\n const points: [number, number][] = []\n let x = 0\n let y = 0\n let i = 0\n const num = () => Number(tokens[i++])\n while (i < tokens.length) {\n const command = tokens[i++]\n if (command === 'M' || command === 'L') {\n x = num()\n y = num()\n points.push([x, y])\n } else if (command === 'H') {\n x = num()\n points.push([x, y])\n } else if (command === 'V') {\n y = num()\n points.push([x, y])\n } else if (command === 'C') {\n const [x1, y1, x2, y2, x3, y3] = [\n num(),\n num(),\n num(),\n num(),\n num(),\n num(),\n ]\n for (let s = 1; s <= steps; s += 1) {\n const t = s / steps\n const u = 1 - t\n const a = u * u * u\n const b = 3 * u * u * t\n const c = 3 * u * t * t\n const e = t * t * t\n points.push([\n a * x + b * x1 + c * x2 + e * x3,\n a * y + b * y1 + c * y2 + e * y3,\n ])\n }\n x = x3\n y = y3\n } else if (command === 'Q') {\n const [x1, y1, x2, y2] = [num(), num(), num(), num()]\n for (let s = 1; s <= steps; s += 1) {\n const t = s / steps\n const u = 1 - t\n points.push([\n u * u * x + 2 * u * t * x1 + t * t * x2,\n u * u * y + 2 * u * t * y1 + t * t * y2,\n ])\n }\n x = x2\n y = y2\n } else if (command !== 'Z') {\n throw new Error(`flattenPath: unsupported path command ${command}`)\n }\n }\n return points\n}\n\n// A node's outline: a rounded box 9 units outside the node's x extent and its\n// content height, the tracks through it inside.\nexport function nodeOutlinePath(node: Node): string {\n // top left arc\n let d = `M ${node.x - 9} ${node.y} Q ${node.x - 9} ${node.y - 9} ${\n node.x\n } ${node.y - 9}`\n let x = node.x\n let y = node.y - 9\n\n // top straight\n if (node.width > 1) {\n x += node.pixelWidth\n d += ` L ${x} ${y}`\n }\n\n // top right arc\n d += ` Q ${x + 9} ${y} ${x + 9} ${y + 9}`\n x += 9\n y += 9\n\n // right straight\n if (node.contentHeight > 0) {\n y += node.contentHeight\n d += ` L ${x} ${y}`\n }\n\n // bottom right arc\n d += ` Q ${x} ${y + 9} ${x - 9} ${y + 9}`\n x -= 9\n y += 9\n\n // bottom straight\n if (node.width > 1) {\n x -= node.pixelWidth\n d += ` L ${x} ${y}`\n }\n\n // bottom left arc\n d += ` Q ${x - 9} ${y} ${x - 9} ${y - 9}`\n x -= 9\n y -= 9\n\n // left straight\n if (node.contentHeight > 0) {\n y -= node.contentHeight\n d += ` L ${x} ${y}`\n }\n return d\n}\n", "// src/tubeMap/mismatches.ts\nimport { forward, getXCoordinateOfBaseWithinNode } from \"@jbrowse/tubemap-core\";\nfunction readMismatches(read, layout) {\n const marks = [];\n const entries = read.sequenceNew ?? [];\n const visits = read.path.filter((segment) => segment.node !== null);\n entries.forEach((entry, i) => {\n const nodeIndex = layout.nodeMap.get(forward(entry.nodeName));\n const node = nodeIndex === void 0 ? void 0 : layout.nodes[nodeIndex];\n const y = visits[i]?.y;\n if (node && y !== void 0) {\n const base = { readId: read.id, y, height: read.width };\n const at = (pos) => getXCoordinateOfBaseWithinNode(node, pos);\n for (const mm of entry.mismatches) {\n const x0 = at(mm.pos);\n if (x0 !== null) {\n if (mm.type === \"insertion\") {\n const softClip = i === 0 && mm.pos === read.firstNodeOffset || i === entries.length - 1 && mm.pos === read.finalNodeCoverLength;\n marks.push({\n ...base,\n kind: \"insertion\",\n x: x0,\n seq: mm.seq,\n softClip\n });\n } else if (mm.type === \"deletion\" && mm.length !== void 0) {\n const x1 = at(mm.pos + mm.length);\n if (x1 !== null) {\n marks.push({\n ...base,\n kind: \"deletion\",\n x0,\n x1,\n length: mm.length\n });\n }\n } else if (mm.type === \"substitution\" && mm.seq !== void 0) {\n const x1 = at(mm.pos + mm.seq.length);\n if (x1 !== null) {\n marks.push({ ...base, kind: \"substitution\", x0, x1, seq: mm.seq });\n }\n }\n }\n }\n }\n });\n return marks;\n}\nfunction tubeMapMismatches(layout) {\n return layout.reads.flatMap((read) => readMismatches(read, layout));\n}\n\nexport {\n tubeMapMismatches\n};\n", "// src/tubeMap/warp.ts\nvar MAX_GAP_PX = 24;\nvar MAX_GAP_SHARE = 0.5;\nvar isReal = (c) => c.bp1 > c.bp0;\nfunction referenceKnots(columns, bpToScreen) {\n const real = columns.filter(isReal);\n if (real.length === 0) {\n const first = columns[0];\n return first ? [{ tx: first.x0, sx: bpToScreen(first.bp0) }] : [];\n }\n const tx = [];\n const target = [];\n const gap = [];\n real.forEach((c, i) => {\n tx.push(c.x0, c.x1);\n target.push(bpToScreen(c.bp0), bpToScreen(c.bp1));\n gap.push(i === 0 ? 0 : Math.min(c.x0 - real[i - 1].x1, MAX_GAP_PX), 0);\n });\n const span = target.at(-1) - target[0];\n const demand = gap.reduce((a, b) => a + b, 0);\n const scale = demand > 0 ? Math.min(1, MAX_GAP_SHARE * span / demand) : 1;\n return spread(target, gap, scale).map((sx, k) => ({ tx: tx[k], sx }));\n}\nfunction spread(target, gap, scale) {\n const offset = [];\n let sum = 0;\n for (const g of gap) {\n sum += g * scale;\n offset.push(sum);\n }\n const blocks = [];\n target.forEach((t, k) => {\n let block = { mean: t - offset[k], n: 1 };\n let last = blocks.at(-1);\n while (last && last.mean >= block.mean) {\n blocks.pop();\n const n = last.n + block.n;\n block = { mean: (last.mean * last.n + block.mean * block.n) / n, n };\n last = blocks.at(-1);\n }\n blocks.push(block);\n });\n return blocks.flatMap((b) => Array(b.n).fill(b.mean)).map((q, k) => q + offset[k]);\n}\nfunction warpX(knots, tx) {\n const n = knots.length;\n if (n === 0) {\n return tx;\n }\n const first = knots[0];\n const last = knots[n - 1];\n if (tx <= first.tx) {\n return first.sx + (tx - first.tx);\n }\n if (tx >= last.tx) {\n return last.sx + (tx - last.tx);\n }\n let lo = 0;\n let hi = n - 1;\n while (hi - lo > 1) {\n const mid = lo + hi >> 1;\n if (knots[mid].tx <= tx) {\n lo = mid;\n } else {\n hi = mid;\n }\n }\n const a = knots[lo];\n const b = knots[hi];\n const span = b.tx - a.tx;\n return span > 0 ? a.sx + (tx - a.tx) / span * (b.sx - a.sx) : a.sx;\n}\n\nexport {\n MAX_GAP_PX,\n referenceKnots,\n warpX\n};\n", "import {\n tubeMapMismatches\n} from \"./chunk-XXT2JCAC.js\";\nimport {\n MAX_GAP_PX\n} from \"./chunk-HK5Y2YWV.js\";\nimport {\n readColor\n} from \"./chunk-CWFNEKST.js\";\nimport {\n pathOrigin\n} from \"./chunk-M6LK4GII.js\";\n\n// src/tubeMap/draw.ts\nimport { curvePaths, flattenPath, nodeOutlinePath } from \"@jbrowse/tubemap-core\";\nfunction parsePath(d) {\n const tokens = d.trim().split(/[\\s,]+/);\n const commands = [];\n let i = 0;\n const num = () => Number(tokens[i++]);\n while (i < tokens.length) {\n const op = tokens[i++];\n if (op === \"M\" || op === \"L\") {\n commands.push({ op, x: num(), y: num() });\n } else if (op === \"H\") {\n commands.push({ op, x: num() });\n } else if (op === \"V\") {\n commands.push({ op, y: num() });\n } else if (op === \"Q\") {\n commands.push({ op, x1: num(), y1: num(), x: num(), y: num() });\n } else if (op === \"C\") {\n commands.push({\n op,\n x1: num(),\n y1: num(),\n x2: num(),\n y2: num(),\n x: num(),\n y: num()\n });\n } else if (op === \"Z\") {\n commands.push({ op });\n }\n }\n return commands;\n}\nfunction extentOf(commands) {\n let x0 = Infinity;\n let x1 = -Infinity;\n for (const c of commands) {\n if (\"x\" in c) {\n x0 = Math.min(x0, c.x);\n x1 = Math.max(x1, c.x);\n }\n if (\"x1\" in c) {\n x0 = Math.min(x0, c.x1);\n x1 = Math.max(x1, c.x1);\n }\n }\n return { x0, x1 };\n}\nfunction shapeOf(d, color, id, haplotype, reference) {\n const commands = parsePath(d);\n return {\n commands,\n outline: flattenPath(d, 12),\n color,\n id,\n haplotype,\n reference,\n ...extentOf(commands)\n };\n}\nfunction trackColors(layout, pathColors) {\n return new Map(\n layout.tracks.map((track) => [\n track.id,\n track.type === \"read\" ? readColor(track) : pathColors[track.id]\n ])\n );\n}\nfunction layerOf(layout, type, colors, referenceIds, gapWidth) {\n const { shapes } = layout;\n const haplotype = type === \"haplotype\";\n const colorOf = (s) => colors.get(s.id);\n const isReference = (s) => haplotype && referenceIds.has(s.id);\n const rects = [...shapes.rectangles, ...shapes.verticalRectangles].filter((r) => r.type === type).map((r) => ({\n color: colorOf(r),\n id: r.id,\n haplotype,\n reference: isReference(r),\n x0: r.xStart,\n x1: r.xEnd + 1,\n y0: r.yStart,\n y1: r.yEnd + 1\n }));\n const curves = curvePaths(shapes.curves, type, { gapWidth }).map(\n (c) => shapeOf(c.path, colorOf(c), c.id, haplotype, isReference(c))\n );\n const corners = shapes.corners.filter((c) => c.type === type).map((c) => shapeOf(c.path, colorOf(c), c.id, haplotype, isReference(c)));\n return { rects, shapes: [...curves, ...corners] };\n}\nfunction referenceTrackIds(graph) {\n const ids = /* @__PURE__ */ new Set();\n graph?.paths?.forEach((path, i) => {\n if (pathOrigin(path.name).name === graph.referencePath) {\n ids.add(i);\n }\n });\n return ids;\n}\nfunction tubeMapPicture({\n layout,\n pathColors,\n graph,\n columns\n}) {\n const colors = trackColors(layout, pathColors);\n const referenceIds = referenceTrackIds(graph);\n const gapWidth = columns ? MAX_GAP_PX : void 0;\n const nodes = [];\n layout.nodes.forEach((node) => {\n if (node.order >= 0) {\n const commands = parsePath(nodeOutlinePath(node));\n nodes.push({ name: node.name, commands, ...extentOf(commands) });\n }\n });\n return {\n bounds: layout.bounds,\n layers: [\n layerOf(layout, \"haplotype\", colors, referenceIds, gapWidth),\n layerOf(layout, \"read\", colors, referenceIds, gapWidth)\n ],\n nodes,\n mismatches: tubeMapMismatches(layout).filter(\n (m) => m.kind !== \"insertion\" || !m.softClip\n )\n };\n}\nfunction trace(ctx, commands, x, y) {\n let cx = 0;\n let cy = 0;\n for (const c of commands) {\n switch (c.op) {\n case \"M\":\n cx = c.x;\n cy = c.y;\n ctx.moveTo(x(cx), y(cy));\n break;\n case \"L\":\n cx = c.x;\n cy = c.y;\n ctx.lineTo(x(cx), y(cy));\n break;\n case \"H\":\n cx = c.x;\n ctx.lineTo(x(cx), y(cy));\n break;\n case \"V\":\n cy = c.y;\n ctx.lineTo(x(cx), y(cy));\n break;\n case \"Q\":\n cx = c.x;\n cy = c.y;\n ctx.quadraticCurveTo(x(c.x1), y(c.y1), x(cx), y(cy));\n break;\n case \"C\":\n cx = c.x;\n cy = c.y;\n ctx.bezierCurveTo(x(c.x1), y(c.y1), x(c.x2), y(c.y2), x(cx), y(cy));\n break;\n case \"Z\":\n ctx.closePath();\n break;\n }\n }\n}\nfunction fillByColor(ctx, items, visible, colorOf, addTo) {\n const byColor = /* @__PURE__ */ new Map();\n for (const item of items) {\n if (visible(item)) {\n const color = colorOf(item);\n const list = byColor.get(color);\n if (list) {\n list.push(item);\n } else {\n byColor.set(color, [item]);\n }\n }\n }\n for (const list of byColor.values()) {\n ctx.fillStyle = colorOf(list[0]);\n ctx.beginPath();\n for (const item of list) {\n addTo(item);\n }\n ctx.fill();\n }\n}\nvar FULL_OUTLINE_PX = 12;\nvar MIN_OUTLINE_ALPHA = 0.15;\nfunction outlineAlpha(screenWidth) {\n return Math.max(MIN_OUTLINE_ALPHA, Math.min(1, screenWidth / FULL_OUTLINE_PX));\n}\nvar NODE_TINT_ALPHA = 0.55;\nfunction drawTubeMap(ctx, picture, frame) {\n const { x, y, width } = frame;\n const visible = (item) => x(item.x1) >= 0 && x(item.x0) <= width;\n const colorOf = (item) => item.haplotype && frame.tubeColors?.[item.id] || item.color;\n ctx.globalAlpha = 1;\n for (const layer of picture.layers) {\n for (const reference of [false, true]) {\n const inPass = (item) => item.reference === reference;\n fillByColor(\n ctx,\n layer.rects,\n (r) => inPass(r) && visible(r),\n colorOf,\n (r) => {\n const left = x(r.x0);\n const top = y(r.y0);\n ctx.rect(left, top, x(r.x1) - left, y(r.y1) - top);\n }\n );\n fillByColor(\n ctx,\n layer.shapes,\n (s) => inPass(s) && visible(s),\n colorOf,\n (s) => {\n trace(ctx, s.commands, x, y);\n }\n );\n }\n }\n const stroke = frame.darkMode ? \"#d0d0d0\" : \"#000000\";\n const fill = frame.darkMode ? \"rgba(40,40,40,0.4)\" : \"rgba(255,255,255,0.4)\";\n ctx.lineWidth = outlineWidth(frame);\n for (const node of picture.nodes) {\n if (visible(node) && node.name !== frame.highlightNode) {\n ctx.beginPath();\n trace(ctx, node.commands, x, y);\n const tint = frame.nodeColors?.get(node.name);\n ctx.fillStyle = tint ?? fill;\n ctx.strokeStyle = stroke;\n ctx.globalAlpha = tint ? NODE_TINT_ALPHA : 1;\n ctx.fill();\n ctx.globalAlpha = outlineAlpha(x(node.x1) - x(node.x0));\n ctx.stroke();\n ctx.globalAlpha = 1;\n }\n }\n drawTubeMapHighlight(ctx, picture, frame);\n drawMismatches(ctx, picture.mismatches, frame);\n}\nfunction outlineWidth(frame) {\n return 2 * Math.max(0.25, Math.min(1, frame.yScale));\n}\nfunction drawTubeMapHighlight(ctx, picture, frame) {\n const node = frame.highlightNode ? picture.nodes.find((n) => n.name === frame.highlightNode) : void 0;\n if (node) {\n ctx.beginPath();\n trace(ctx, node.commands, frame.x, frame.y);\n ctx.globalAlpha = 1;\n ctx.lineWidth = outlineWidth(frame);\n ctx.fillStyle = \"rgba(255,192,203,0.5)\";\n ctx.strokeStyle = \"#ff0000\";\n ctx.fill();\n ctx.stroke();\n }\n}\nvar MISMATCH_FONT_PX = 12;\nvar MIN_MISMATCH_FONT_PX = 6;\nfunction mismatchesLegible(yScale) {\n return MISMATCH_FONT_PX * yScale >= MIN_MISMATCH_FONT_PX;\n}\nfunction mismatchOnScreen(m, { x, width }) {\n const [x0, x1] = m.kind === \"insertion\" ? [m.x, m.x] : [m.x0, m.x1];\n return x(x1) >= 0 && x(x0) <= width;\n}\nfunction drawMismatches(ctx, marks, frame) {\n const { x, y, yScale, darkMode } = frame;\n if (!mismatchesLegible(yScale) || marks.length === 0) {\n return;\n }\n const fontPx = MISMATCH_FONT_PX * yScale;\n ctx.fillStyle = \"grey\";\n ctx.beginPath();\n for (const m of marks) {\n if (m.kind === \"deletion\" && mismatchOnScreen(m, frame)) {\n const left = x(m.x0);\n const top = y(m.y);\n ctx.rect(left, top, x(m.x1) - left, y(m.y + m.height) - top);\n }\n }\n ctx.fill();\n ctx.font = `${fontPx}px monospace`;\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"alphabetic\";\n ctx.fillStyle = darkMode ? \"#ffffff\" : \"#000000\";\n for (const m of marks) {\n if (!mismatchOnScreen(m, frame)) {\n continue;\n }\n if (m.kind === \"substitution\") {\n ctx.fillText(m.seq, x(m.x0) + 1, y(m.y + m.height));\n } else if (m.kind === \"insertion\") {\n ctx.fillText(\"*\", x(m.x) - 3, y(m.y + m.height));\n }\n }\n}\nfunction inside(points, sx, sy) {\n let hit = false;\n for (let i = 0, j = points.length - 1; i < points.length; j = i++) {\n const [xi, yi] = points[i];\n const [xj, yj] = points[j];\n if (yi > sy !== yj > sy && sx < (xj - xi) * (sy - yi) / (yj - yi) + xi) {\n hit = !hit;\n }\n }\n return hit;\n}\nfunction tubeMapTrackAt(picture, { x, y }, sx, sy) {\n for (let l = picture.layers.length - 1; l >= 0; l--) {\n const { rects, shapes } = picture.layers[l];\n for (const reference of [true, false]) {\n for (const r of rects) {\n if (r.reference === reference && x(r.x0) <= sx && sx <= x(r.x1) && y(r.y0) <= sy && sy <= y(r.y1)) {\n return r.id;\n }\n }\n for (const s of shapes) {\n if (s.reference === reference && x(s.x0) <= sx && sx <= x(s.x1) && inside(\n s.outline.map(([px, py]) => [x(px), y(py)]),\n sx,\n sy\n )) {\n return s.id;\n }\n }\n }\n }\n return void 0;\n}\nvar INSERTION_SLOP_PX = 4;\nfunction tubeMapMismatchAt(picture, frame, sx, sy) {\n const { x, y, yScale } = frame;\n return mismatchesLegible(yScale) ? picture.mismatches.find(\n (m) => y(m.y) <= sy && sy <= y(m.y + m.height) && (m.kind === \"insertion\" ? Math.abs(x(m.x) - sx) <= INSERTION_SLOP_PX : x(m.x0) <= sx && sx <= x(m.x1))\n ) : void 0;\n}\n\nexport {\n parsePath,\n trackColors,\n tubeMapPicture,\n drawTubeMap,\n drawTubeMapHighlight,\n mismatchesLegible,\n mismatchOnScreen,\n tubeMapTrackAt,\n tubeMapMismatchAt\n};\n", "const host = JBrowseExports[\"@jbrowse/core/util/groupKeys\"]\nconst read = name =>\n host != null && name in Object(host)\n ? host[name]\n : Object.assign(\n function () {\n throw new Error(\n \"This JBrowse does not provide '\" + name + \"' from '\" + \"@jbrowse/core/util/groupKeys\" + \"' to plugins: GraphGenomeView was built for a different JBrowse version, so update the plugin or JBrowse\",\n )\n },\n { jbrowseHostMissing: name },\n )\nexport const MAX_GROUPS = /* @__PURE__ */ read(\"MAX_GROUPS\")\nexport const OVERFLOW_GROUP_KEY = /* @__PURE__ */ read(\"OVERFLOW_GROUP_KEY\")\nexport const capGroupKeys = /* @__PURE__ */ read(\"capGroupKeys\")\nexport const carryGroupDomain = /* @__PURE__ */ read(\"carryGroupDomain\")\nexport const compareGroupKeys = /* @__PURE__ */ read(\"compareGroupKeys\")\nexport const groupKeyComparator = /* @__PURE__ */ read(\"groupKeyComparator\")\nexport const groupKeySpaceOf = /* @__PURE__ */ read(\"groupKeySpaceOf\")\nexport const overflowLabel = /* @__PURE__ */ read(\"overflowLabel\")\nexport const valueText = /* @__PURE__ */ read(\"valueText\")\nexport default host && host.__esModule ? host.default : host", "import { walkRowsTree } from '@jbrowse/bandage-core/layout/walkRowDraw'\nimport { groupKeyComparator } from '@jbrowse/core/util/groupKeys'\n\nimport type { El } from '@jbrowse/bandage-core/el'\nimport type {\n WalkRowsFrame,\n WalkRowsWithCalls,\n} from '@jbrowse/bandage-core/layout/walkRowDraw'\n\n// Walk rows stacked into one section per value of a sample table's column,\n// as jbrowse-plugin-tandem-repeat's \"Group by\u2026\" stacks its alleles. Placement\n// here, not in bandage-core's walkRowsTree, which puts row i at i * rowPx.\n\n// One row of a samples TSV: the sample's name and a value per column\nexport type SampleRow = { name: string } & Record<string, string>\n\nexport interface WalkRowGroupBy {\n field: string\n domain?: string[]\n}\n\nexport interface WalkRowSection {\n // '' for the rows with no value\n key: string\n title: string\n // index of the section's first row among the reference row and the rows\n first: number\n count: number\n}\n\nexport const SECTION_HEADER_PX = 16\n\n// A samples TSV as core's samplesTsv reads one: a header row, the sample's\n// name in the first column, the first row of a repeated name kept. Hosts\n// re-export that module only from v5.0.0-beta.11, so it is read here.\nexport function parseSamplesTsv(text: string): SampleRow[] {\n const [head = '', ...lines] = text.split(/\\r\\n|\\r|\\n/)\n const columns = head.split('\\t').slice(1)\n const rows = new Map<string, SampleRow>()\n for (const line of lines) {\n if (!line) {\n continue\n }\n const [name = '', ...values] = line.split('\\t')\n if (name && !rows.has(name)) {\n rows.set(name, {\n ...Object.fromEntries(columns.map((c, i) => [c, values[i] ?? ''])),\n name,\n })\n }\n }\n return [...rows.values()]\n}\n\nexport function metadataColumns(rows: SampleRow[] | undefined) {\n const columns = new Set<string>()\n for (const row of rows ?? []) {\n for (const key of Object.keys(row)) {\n if (key !== 'name') {\n columns.add(key)\n }\n }\n }\n return [...columns]\n}\n\n// The setting as a snapshot may hold it: a bare field name, or the object\nexport function groupByOf(value: unknown): WalkRowGroupBy | undefined {\n if (typeof value === 'string') {\n return value ? { field: value } : undefined\n }\n const { field, domain } = (value ?? {}) as Record<string, unknown>\n if (typeof field !== 'string' || !field) {\n return undefined\n }\n return Array.isArray(domain)\n ? { field, domain: domain.filter(d => typeof d === 'string') }\n : { field }\n}\n\nexport function plural(n: number, noun: string) {\n return `${n} ${noun}${n === 1 ? '' : 's'}`\n}\n\n// A walk's value in a column: its haplotype's row (`HG00097#1`), else its\n// sample's (`HG00097`), else ''\nexport function columnValueOf(field: string, table: SampleRow[]) {\n const valueOf = new Map(table.map(row => [row.name, row[field] ?? '']))\n return (haplotype: string, sample: string) =>\n valueOf.get(haplotype) || valueOf.get(sample) || ''\n}\n\n// Items grouped by their value in a column, each group in the order its items\n// came in, the groups in the order a JBrowse Group by sorts them, and each\n// titled with its value and how many distinct `noun`s its items are\nexport function groupsByColumn<T>(\n items: readonly T[],\n valueOf: (item: T) => string,\n { field, domain }: { field: string; domain?: readonly string[] },\n noun: string,\n nounOf: (item: T) => string,\n) {\n const groups = new Map<string, T[]>()\n for (const item of items) {\n const key = valueOf(item)\n const group = groups.get(key)\n if (group) {\n group.push(item)\n } else {\n groups.set(key, [item])\n }\n }\n return [...groups.keys()].sort(groupKeyComparator(domain)).map(key => {\n const members = groups.get(key)!\n const n = new Set(members.map(nounOf)).size\n return {\n key,\n members,\n title: `${key || `${field}: none`} \u00B7 ${plural(n, noun)}`,\n }\n })\n}\n\n// The rows reordered section by section; rows with no value stack last\nexport function groupWalkRows<R extends { sample: string; label: string }>(\n rows: R[],\n table: SampleRow[],\n groupBy: WalkRowGroupBy,\n) {\n const valueOf = columnValueOf(groupBy.field, table)\n const groups = groupsByColumn(\n rows,\n row => valueOf(row.label, row.sample),\n groupBy,\n 'haplotype',\n row => row.label,\n )\n let first = 1\n const sections: WalkRowSection[] = groups.map(({ key, members, title }) => {\n const section = { key, title, first, count: members.length }\n first += members.length\n return section\n })\n return {\n rows: groups.flatMap(g => g.members),\n sections,\n }\n}\n\n// Where rows and section headers sit, in px down from the reference row's\n// centre, at one row pitch shared by every section: a header strip above\n// each section's first row pushes every row after it down\nexport function sectionPlacement(sections: WalkRowSection[], rowPx: number) {\n const sectionOf = (i: number) => {\n let k = -1\n while (k + 1 < sections.length && sections[k + 1]!.first <= i) {\n k++\n }\n return k\n }\n const rowY = (i: number) => i * rowPx + (sectionOf(i) + 1) * SECTION_HEADER_PX\n return {\n rowY,\n headers: sections.map((s, k) => ({\n ...s,\n top: (s.first - 0.5) * rowPx + k * SECTION_HEADER_PX,\n })),\n headersPx: sections.length * SECTION_HEADER_PX,\n // the row whose centre is nearest y\n rowAt(y: number, rows: number) {\n let best = 0\n for (let k = -1; k < sections.length; k++) {\n const lo = k < 0 ? 0 : sections[k]!.first\n const hi =\n k < 0\n ? Math.min(rows, sections[0]?.first ?? rows)\n : lo + sections[k]!.count\n const shift = (k + 1) * SECTION_HEADER_PX\n const i = Math.min(\n hi - 1,\n Math.max(lo, Math.round((y - shift) / rowPx)),\n )\n if (Math.abs(rowY(i) - y) < Math.abs(rowY(best) - y)) {\n best = i\n }\n }\n return best\n },\n }\n}\n\n// The rows' trees, a section at a time while grouped. walkRowsTree puts its\n// i-th row at i * rowPx below its reference row and draws that row too, so\n// each section is drawn shifted down to its place with its reference row\n// dropped.\nexport function walkRowTrees(\n bars: WalkRowsWithCalls,\n sections: WalkRowSection[],\n rowY: (i: number) => number,\n frame: WalkRowsFrame & { rowPx: number },\n o: Parameters<typeof walkRowsTree>[2] & { idPrefix: string },\n): El[] {\n if (sections.length === 0) {\n return [walkRowsTree(bars, frame, o)]\n }\n return [\n walkRowsTree({ ...bars, rows: [] }, frame, o),\n ...sections.flatMap((section, k) => {\n const tree = walkRowsTree(\n {\n ...bars,\n rows: bars.rows.slice(\n section.first - 1,\n section.first - 1 + section.count,\n ),\n },\n {\n ...frame,\n translateY:\n frame.translateY +\n (rowY(section.first) - frame.rowPx) * frame.scaleY,\n },\n { ...o, idPrefix: `${o.idPrefix}-s${k}` },\n )\n return tree.children.filter(\n (c): c is El =>\n typeof c !== 'string' &&\n c.attrs['data-testid'] !== 'graph-walk-reference',\n )\n }),\n ]\n}\n", "import {\n buildNeighbors\n} from \"./chunk-ES2N6V56.js\";\nimport {\n REFERENCE_RANK,\n isAnchored\n} from \"./chunk-FYQWPEEY.js\";\n\n// src/alleleProjection/projectAlleles.ts\nfunction parsePanSN(refName) {\n const parts = refName.split(\"#\");\n const haplotype = parts.length >= 2 ? Number(parts[1]) : Number.NaN;\n return {\n sample: parts[0] ?? refName,\n haplotype: Number.isFinite(haplotype) ? haplotype : void 0\n };\n}\nfunction collectRun(seed, byId, adj, claimed) {\n const members = [];\n const anchors = [];\n const queue = [seed];\n claimed.add(seed);\n while (queue.length > 0) {\n const id = queue.pop();\n const node = byId.get(id);\n if (node) {\n members.push(node);\n for (const neighborId of adj.get(id) ?? []) {\n const neighbor = byId.get(neighborId);\n if (neighbor) {\n if (neighbor.stable.rank === REFERENCE_RANK) {\n anchors.push(neighbor);\n } else if (!claimed.has(neighborId)) {\n claimed.add(neighborId);\n queue.push(neighborId);\n }\n }\n }\n }\n }\n return { members, anchors };\n}\nfunction anchorSpan(anchors) {\n const refNames = new Set(anchors.map((a) => a.stable.refName));\n if (refNames.size !== 1 || anchors.length < 2) {\n return void 0;\n }\n const sorted = [...anchors].sort((a, b) => a.stable.start - b.stable.start);\n const first = sorted[0];\n const last = sorted.at(-1);\n const start = first.stable.start + first.length;\n const end = last.stable.start;\n return end >= start ? { start, end, entry: first } : void 0;\n}\nfunction runDistances(members, entry, adj) {\n const byId = new Map(members.map((m) => [m.id, m]));\n const dist = /* @__PURE__ */ new Map();\n const queue = [];\n for (const neighborId of adj.get(entry.id) ?? []) {\n if (byId.has(neighborId)) {\n dist.set(neighborId, 0);\n queue.push(neighborId);\n }\n }\n if (queue.length === 0) {\n for (const member of members) {\n dist.set(member.id, 0);\n queue.push(member.id);\n }\n }\n for (const id of queue) {\n const reach = dist.get(id) + byId.get(id).length;\n for (const neighborId of adj.get(id) ?? []) {\n if (byId.has(neighborId)) {\n const known = dist.get(neighborId);\n if (known === void 0 || reach < known) {\n dist.set(neighborId, reach);\n queue.push(neighborId);\n }\n }\n }\n }\n return dist;\n}\nfunction runOffsets(members, entry, adj) {\n const dist = runDistances(members, entry, adj);\n const ordered = [...members].sort((a, b) => dist.get(a.id) - dist.get(b.id));\n const rank = new Map(ordered.map((m, i) => [m.id, i]));\n const byId = new Map(members.map((m) => [m.id, m]));\n const offsets = /* @__PURE__ */ new Map();\n for (const [i, member] of ordered.entries()) {\n let offset = 0;\n for (const neighborId of adj.get(member.id) ?? []) {\n const neighbor = byId.get(neighborId);\n if (neighbor && rank.get(neighborId) < i) {\n offset = Math.max(offset, offsets.get(neighborId) + neighbor.length);\n }\n }\n offsets.set(member.id, offset);\n }\n return { offsets, ordered };\n}\nfunction projectAlleles(graph) {\n const byId = new Map(\n graph.nodes.filter(isAnchored).map((n) => [n.id, n])\n );\n const adj = buildNeighbors(graph);\n const claimed = /* @__PURE__ */ new Set();\n const alleles = [];\n for (const node of byId.values()) {\n if (node.stable.rank !== REFERENCE_RANK && !claimed.has(node.id)) {\n const { members, anchors } = collectRun(node.id, byId, adj, claimed);\n const span = anchorSpan(anchors);\n if (span) {\n const { offsets, ordered } = runOffsets(members, span.entry, adj);\n alleles.push({\n start: span.start,\n refSpan: span.end - span.start,\n nodeIds: ordered.map((m) => m.id),\n nodeOffsets: ordered.map((m) => offsets.get(m.id)),\n pathLength: ordered.reduce(\n (max, m) => Math.max(max, offsets.get(m.id) + m.length),\n 0\n )\n });\n }\n }\n }\n return alleles.sort((a, b) => a.start - b.start);\n}\n\nexport {\n parsePanSN,\n projectAlleles\n};\n", "import { parsePanSN } from '@jbrowse/bandage-core/alleleProjection/projectAlleles'\nimport { formatBp } from '@jbrowse/bandage-core/graphLabels'\nimport { pathOrigin } from '@jbrowse/bandage-core/pathAnchoring'\nimport { drawTubeMapHighlight } from '@jbrowse/bandage-core/tubeMap/draw'\nimport { groupKeyComparator } from '@jbrowse/core/util/groupKeys'\n\nimport { columnValueOf, groupsByColumn, plural } from './walkRowGroups'\n\nimport type { SampleRow } from './walkRowGroups'\nimport type { FacetBy } from '@jbrowse/bandage-core/facetGrid'\nimport type { TubeMapDrawing } from '@jbrowse/bandage-core/layout/tubeMapLayout'\nimport type { TubeMapPicture } from '@jbrowse/bandage-core/tubeMap/draw'\nimport type { TubeMapTransform } from '@jbrowse/bandage-core/tubeMap/frame'\nimport type { Graph, LayoutResult } from '@jbrowse/bandage-core/types'\n\n// A tube map split into small multiples: a panel per sample, or per walk, each\n// the reference and that group's walks laid out alone, stacked down the pane.\n// On the reference axis every panel's columns sit at their bp, so a box lines\n// up across the panels and with the linear view's tracks.\n\n// px above each panel, which its title takes\nexport const PANEL_GAP = 28\nexport const PANEL_REFERENCE_TUBE = '#4d4d4d'\nexport const PANEL_TUBE = '#5b8cc4'\nexport const PANEL_TUBES = [PANEL_TUBE, '#82abd9']\n// greys beside boxes tinted by the node scheme, so no tube shares a box's hue\nexport const TINTED_TUBES = ['#8c8c8c', '#adadad']\nexport const PANEL_TITLE_FONT = '12px sans-serif'\n\nexport const TUBE_MAP_PANELS: { field: '' | FacetBy; label: string }[] = [\n { field: '', label: 'None' },\n { field: 'sample', label: 'A panel per sample' },\n { field: 'walk', label: 'A panel per haplotype' },\n]\n\n// How the walks split: by sample or walk, the groups the domain names first\n// and the rest in the graph's order, or by a sample table column, its values\n// in the order a JBrowse Group by sorts them\nexport type TubeMapPanelSplit =\n | { by: FacetBy; domain?: readonly string[] }\n | { by: 'column'; field: string; table: SampleRow[]; domain?: string[] }\n\nexport interface TubeMapPanelGroup {\n key: string\n // the graph's own path names, pieces of one walk included\n paths: string[]\n // a column's value names a group of samples, and says how many\n label?: string\n}\n\nexport interface TubeMapPanel extends TubeMapPanelGroup {\n result: LayoutResult & { tubeMap: TubeMapDrawing }\n // where the panel's drawing starts down the stack, in tube px\n top: number\n height: number\n}\n\n// a pane's layout: a tube map split into panels carries them, and the stack's\n// extent and node positions in place of the whole map's\nexport type PaneLayout = LayoutResult & { tubeMapPanels?: TubeMapPanel[] }\n\nconst walkOf = (name: string) => pathOrigin(name).name\n\n// A tube coloured by its role where no key could name a hue per walk: the\n// reference charcoal and the haplotypes blue, or grey beside tinted boxes,\n// neighbours alternating two shades so each stays countable in a bundle\nexport function roleTubeColors(\n paths: readonly { name: string }[],\n reference: string | undefined,\n tubes = PANEL_TUBES,\n) {\n let haplotype = 0\n return paths.map(p =>\n walkOf(p.name) === reference\n ? PANEL_REFERENCE_TUBE\n : tubes[haplotype++ % tubes.length]!,\n )\n}\n\n// a categorical palette for a column's values, a hue each in sorted order\nconst VALUE_TUBES = [\n '#4e79a7',\n '#f28e2b',\n '#59a14f',\n '#e15759',\n '#b07aa1',\n '#76b7b2',\n '#edc948',\n '#9c755f',\n '#ff9da7',\n '#bab0ac',\n]\nexport const NO_VALUE_TUBE = '#c8c8c8'\n\n// Each of a column's values its hue, in the order a JBrowse Group by sorts\n// them; a value past the palette, or none, is grey\nexport function valueTubePalette(values: Iterable<string>) {\n const sorted = [...new Set(values)]\n .filter(v => v !== '')\n .sort(groupKeyComparator())\n return new Map(sorted.map((v, i) => [v, VALUE_TUBES[i] ?? NO_VALUE_TUBE]))\n}\n\n// The reference charcoal and each walk, or the bundle it stands for, in its\n// value's hue\nexport function valueTubeColors(\n paths: readonly { name: string; members?: string[] }[],\n reference: string | undefined,\n valueOf: (walk: string) => string,\n palette: ReadonlyMap<string, string>,\n) {\n return paths.map(p => {\n const walk = walkOf(p.name)\n return walk === reference\n ? PANEL_REFERENCE_TUBE\n : (palette.get(valueOf(p.members?.[0] ?? walk)) ?? NO_VALUE_TUBE)\n })\n}\n\n// A PanSN walk's value in a column\nexport function columnKeyOf(field: string, table: SampleRow[]) {\n const valueOf = columnValueOf(field, table)\n return (walk: string) => {\n const { sample, haplotype } = parsePanSN(walk)\n return valueOf(`${sample}#${haplotype}`, sample)\n }\n}\n\n// Each non-reference walk's group\nexport function tubeMapPanelGroups(\n graph: Graph,\n split: TubeMapPanelSplit,\n): TubeMapPanelGroup[] {\n const names = (graph.paths ?? [])\n .map(p => p.name)\n .filter(name => walkOf(name) !== graph.referencePath)\n if (split.by === 'column') {\n const keyOf = columnKeyOf(split.field, split.table)\n return groupsByColumn(\n names,\n name => keyOf(walkOf(name)),\n split,\n 'sample',\n name => parsePanSN(walkOf(name)).sample,\n ).map(({ key, members, title }) => ({ key, paths: members, label: title }))\n }\n const keyOf =\n split.by === 'sample'\n ? (walk: string) => parsePanSN(walk).sample\n : (walk: string) => walk\n const groups = new Map<string, string[]>()\n for (const name of names) {\n const key = keyOf(walkOf(name))\n const list = groups.get(key)\n if (list) {\n list.push(name)\n } else {\n groups.set(key, [name])\n }\n }\n const domain = split.domain ?? []\n const rank = new Map(domain.map((key, i) => [key, i]))\n const listed = (key: string) => rank.get(key) ?? domain.length\n return [...groups]\n .map(([key, paths], i) => ({ key, paths, i }))\n .sort((a, b) => listed(a.key) - listed(b.key) || a.i - b.i)\n .map(({ key, paths }) => ({ key, paths }))\n}\n\n// The box a panel draws a node of the laid graph in: the node itself, or the\n// merged run holding it\nexport function boxOf(drawing: TubeMapDrawing, node: string) {\n if (drawing.graph.nodes.some(n => n.id === node)) {\n return node\n }\n for (const [box, members] of drawing.members) {\n if (members.includes(node)) {\n return box\n }\n }\n return undefined\n}\n\n// The member of a merged run under pane x `sx`, a run drawn from `left` to\n// `right` across its members' bp, so a panel's count is of the bp the pointer\n// is on, not of the whole run. Undefined when no member has a span.\nexport function memberAt(\n members: readonly string[],\n spanOf: (id: string) => { start: number; end: number } | undefined,\n left: number,\n right: number,\n sx: number,\n) {\n const spans = members.flatMap(id => {\n const span = spanOf(id)\n return span ? [{ id, ...span }] : []\n })\n if (spans.length === 0) {\n return undefined\n }\n const start = Math.min(...spans.map(s => s.start))\n const end = Math.max(...spans.map(s => s.end))\n const share = right > left ? (sx - left) / (right - left) : 0\n const bp = start + Math.min(1, Math.max(0, share)) * (end - start)\n const distance = (s: { start: number; end: number }) =>\n bp < s.start ? s.start - bp : bp >= s.end ? bp - s.end + 1 : 0\n return spans.reduce((a, b) => (distance(b) < distance(a) ? b : a)).id\n}\n\n// How many of a panel's walks pass through `box`, of how many it holds, a\n// bundle counting each walk it stands for\nexport function walksThrough(graph: Graph, box: string) {\n const all = new Set<string>()\n const here = new Set<string>()\n for (const p of graph.paths ?? []) {\n const walk = walkOf(p.name)\n if (walk !== graph.referencePath) {\n for (const member of p.members ?? [walk]) {\n all.add(member)\n if (p.nodeIds.includes(box)) {\n here.add(member)\n }\n }\n }\n }\n return { here: here.size, of: all.size }\n}\n\nconst COUNT_FONT = 'bold 11px sans-serif'\nconst MIN_COUNT_RUN_PX = 80\nconst MIN_COUNT_TUBE_PX = 9\n\n// Each bundle's count on its tube, along every straight run wide and tall\n// enough to hold it, so the count stands where its route parts from others\nexport function drawBundleCounts(\n ctx: CanvasRenderingContext2D,\n picture: TubeMapPicture,\n graph: Graph,\n { x, y, width }: TubeMapTransform & { width: number },\n) {\n const paths = graph.paths ?? []\n if (!paths.some(p => p.members)) {\n return\n }\n const counts = new Map<number, number>()\n paths.forEach((p, i) => {\n if (walkOf(p.name) !== graph.referencePath) {\n counts.set(i, p.members?.length ?? 1)\n }\n })\n ctx.font = COUNT_FONT\n ctx.textAlign = 'left'\n ctx.textBaseline = 'middle'\n ctx.fillStyle = '#0b1f3a'\n for (const r of picture.layers[0]?.rects ?? []) {\n const n = counts.get(r.id)\n const left = Math.max(0, x(r.x0))\n const right = Math.min(width, x(r.x1))\n const top = y(r.y0)\n const bottom = y(r.y1)\n if (\n n !== undefined &&\n right - left >= MIN_COUNT_RUN_PX &&\n bottom - top >= MIN_COUNT_TUBE_PX\n ) {\n ctx.fillText(`\u00D7${n}`, left + 4, (top + bottom) / 2)\n }\n }\n}\n\nconst LENGTH_FONT = '10px sans-serif'\nconst MIN_LENGTH_LABEL_BP = 1000\n\n// Each box of a reference-axis map whose sequence the axis squeezes narrower\n// than its length's label, labelled beside it: off the reference a 33 kb\n// module draws a few px wide, as a SNP's box does. Boxes of one length\n// stacked in a column share a label, \"each\", at the lowest, where the stack\n// has room; a label that would overlap one already drawn is left out.\nexport function drawSqueezedLengths(\n ctx: CanvasRenderingContext2D,\n drawing: TubeMapDrawing,\n { x, y, width }: TubeMapTransform & { width: number },\n) {\n if (!drawing.columns) {\n return\n }\n const lengthOf = new Map(drawing.graph.nodes.map(n => [n.id, n.length]))\n ctx.font = LENGTH_FONT\n const stacks = new Map<\n string,\n { text: string; right: number; mid: number; count: number }\n >()\n // sparse, so forEach, which skips its holes\n drawing.layout.nodes.forEach(node => {\n const bp = lengthOf.get(node.name) ?? 0\n const left = x(node.x)\n const right = x(node.x + node.pixelWidth)\n const text = formatBp(bp)\n if (\n node.order >= 0 &&\n bp >= MIN_LENGTH_LABEL_BP &&\n right - left < ctx.measureText(text).width\n ) {\n const mid = (y(node.y) + y(node.y + node.contentHeight)) / 2\n const key = `${Math.round(right)}:${text}`\n const stack = stacks.get(key)\n if (stack) {\n stack.count++\n stack.mid = Math.max(stack.mid, mid)\n } else {\n stacks.set(key, { text, right, mid, count: 1 })\n }\n }\n })\n ctx.textAlign = 'left'\n ctx.textBaseline = 'middle'\n ctx.lineJoin = 'round'\n ctx.lineWidth = 3\n ctx.strokeStyle = 'rgba(255,255,255,0.9)'\n ctx.fillStyle = 'rgba(0,0,0,0.75)'\n const drawn: { x0: number; x1: number; y0: number; y1: number }[] = []\n for (const { text, right, mid, count } of stacks.values()) {\n const label = count > 1 ? `${text} each` : text\n const box = {\n x0: right + 3,\n x1: right + 3 + ctx.measureText(label).width,\n y0: mid - 6,\n y1: mid + 6,\n }\n if (\n box.x1 <= width &&\n !drawn.some(\n d => d.x0 < box.x1 && box.x0 < d.x1 && d.y0 < box.y1 && box.y0 < d.y1,\n )\n ) {\n drawn.push(box)\n ctx.strokeText(label, box.x0, mid)\n ctx.fillText(label, box.x0, mid)\n }\n }\n}\n\ninterface PanelOnScreen {\n picture: TubeMapPicture\n frame: TubeMapTransform\n label: string\n titleTop: number\n top: number\n}\n\n// The hovered box in each panel that draws it, and beside each title how many\n// of that panel's haplotypes pass through it. On the hover layer, so a hover\n// repaints no tube.\nexport function paintPanelHover(\n ctx: CanvasRenderingContext2D,\n panels: PanelOnScreen[],\n hover: ({ box: string; here: number; of: number } | undefined)[] | undefined,\n { width, lit }: { width: number; lit: boolean },\n) {\n panels.forEach((p, i) => {\n const hit = hover?.[i]\n if (!hit) {\n return\n }\n if (lit) {\n drawTubeMapHighlight(ctx, p.picture, {\n ...p.frame,\n width,\n highlightNode: hit.box,\n })\n }\n ctx.font = PANEL_TITLE_FONT\n ctx.textAlign = 'left'\n ctx.textBaseline = 'top'\n ctx.fillStyle = '#c00000'\n ctx.fillText(\n ` \u00B7 ${hit.here} of ${plural(hit.of, 'haplotype')} here`,\n 6 + ctx.measureText(p.label).width,\n p.titleTop + 4,\n )\n })\n}\n\n// The reference and `paths` alone: the nodes they visit and the links between\n// them, without reads, which name no sample\nexport function graphOfPaths(graph: Graph, paths: readonly string[]): Graph {\n const kept = new Set(paths)\n const keptPaths = (graph.paths ?? []).filter(\n p => kept.has(p.name) || walkOf(p.name) === graph.referencePath,\n )\n const walks = new Set(keptPaths.map(p => walkOf(p.name)))\n const nodeIds = new Set(keptPaths.flatMap(p => p.nodeIds))\n const nodes = graph.nodes.filter(n => nodeIds.has(n.id))\n const names = new Set(nodes.map(n => n.name))\n const pathVisits = graph.pathVisits?.filter(\n path => walks.has(path),\n segment => names.has(segment),\n )\n return {\n ...graph,\n nodes,\n edges: graph.edges.filter(e => nodeIds.has(e.from) && nodeIds.has(e.to)),\n paths: keptPaths,\n anchorPaths: graph.anchorPaths?.filter(p => walks.has(p.name)),\n pathVisits,\n reads: undefined,\n }\n}\n\n// `whole` with each group's own tube map stacked in its place, a title's gap\n// above each, or `whole` alone when fewer than two groups draw\nexport function withTubeMapPanels(\n whole: LayoutResult,\n laidOut: (TubeMapPanelGroup & { result: LayoutResult | undefined })[],\n): PaneLayout {\n const panels: TubeMapPanel[] = []\n const nodePositions: LayoutResult['nodePositions'] = {}\n let y = 0\n let minX = Infinity\n let maxX = -Infinity\n for (const { key, paths, label, result } of laidOut) {\n const tubeMap = result?.tubeMap\n const extent = result?.extent\n if (tubeMap && extent) {\n const top = y + PANEL_GAP\n const height = (extent.maxY ?? 0) - (extent.minY ?? 0)\n panels.push({\n key,\n paths,\n label,\n result: { ...result, tubeMap },\n top,\n height,\n })\n const dy = top - (extent.minY ?? 0)\n for (const [id, segments] of Object.entries(result.nodePositions)) {\n nodePositions[id] = segments.map(s => ({ x: s.x, y: s.y + dy }))\n }\n y = top + height\n minX = Math.min(minX, extent.minX ?? minX)\n maxX = Math.max(maxX, extent.maxX ?? maxX)\n }\n }\n return panels.length > 1\n ? {\n ...whole,\n nodePositions,\n extent: {\n ...(minX <= maxX ? { minX, maxX } : {}),\n minY: 0,\n maxY: y,\n },\n tubeMapPanels: panels,\n }\n : whole\n}\n", "import {\n el\n} from \"./chunk-H2H4Y3TV.js\";\n\n// src/genes/exonOutline.ts\nvar EXON_COLOR = \"#daa520\";\nvar EXON_GAP_PX = 1;\nvar EXON_LINE_PX = 2;\nvar MIN_LANE_PX = 4;\nfunction exonStretches(pins, halfWidthPx, lift, pathOf = (d) => d) {\n const inkPx = (nodeId) => {\n const own = halfWidthPx(nodeId) * 2;\n return lift?.nodeIds.has(nodeId) ? Math.max(own, lift.walks.length * MIN_LANE_PX) : own;\n };\n return pins.flatMap(\n (pin) => pin.exonsByNode.map(({ nodeId, d }) => ({\n key: `${pin.gene.name}-${pin.gene.start}-${nodeId}`,\n d: pathOf(d),\n inner: inkPx(nodeId) + 2 * EXON_GAP_PX\n }))\n );\n}\nfunction exonOutlineTree(stretches, o) {\n if (stretches.length === 0) {\n return void 0;\n }\n const stroke = (s, color, width) => el(\"path\", {\n d: s.d,\n fill: \"none\",\n stroke: color,\n \"stroke-width\": width,\n \"stroke-linecap\": \"round\",\n \"stroke-linejoin\": \"round\",\n \"vector-effect\": o.transform ? \"non-scaling-stroke\" : void 0\n });\n return el(\n \"g\",\n {},\n el(\n \"mask\",\n {\n id: o.id,\n maskUnits: \"userSpaceOnUse\",\n x: 0,\n y: 0,\n width: o.width,\n height: o.height\n },\n el(\n \"g\",\n { transform: o.transform },\n ...stretches.map((s) => stroke(s, \"#fff\", s.inner + 2 * EXON_LINE_PX)),\n ...stretches.map((s) => stroke(s, \"#000\", s.inner))\n )\n ),\n el(\"rect\", {\n width: o.width,\n height: o.height,\n fill: EXON_COLOR,\n mask: `url(#${o.id})`\n })\n );\n}\n\nexport {\n EXON_COLOR,\n exonStretches,\n exonOutlineTree\n};\n", "import {\n formatBp,\n groupDigits\n} from \"./chunk-PTABFYQ7.js\";\n\n// src/walkKey.ts\nfunction rangeText(contig, start, end) {\n const s = Math.round(start);\n const e = Math.round(end);\n return `${contig ? `${contig}:` : \"\"}${groupDigits(s)}-${groupDigits(e)} (${formatBp(e - s)})`;\n}\nfunction walkKey(walk, reference) {\n const { field } = walk.encoding;\n const own = walk.range ? rangeText(walk.range.contig, walk.range.start, walk.range.end) : void 0;\n const scale = field === \"progress\" ? own : field === \"reference\" && reference ? rangeText(reference.name, reference.start, reference.end) : void 0;\n const spanned = walk.range ? walk.range.end - walk.range.start : walk.bp;\n const outside = spanned - walk.bp;\n return {\n delta: walk.referenceBp === void 0 || spanned === walk.referenceBp ? \"\" : ` ${spanned > walk.referenceBp ? \"+\" : \"\\u2212\"}${formatBp(Math.abs(spanned - walk.referenceBp))}`,\n outside: outside > 0 ? `, ${formatBp(outside)} outside the cut` : \"\",\n reversed: walk.reversedBp > 0 ? `, ${formatBp(walk.reversedBp)} reversed` : \"\",\n shades: field !== \"walk\",\n scale,\n hover: scale === own ? void 0 : own\n };\n}\nfunction walkPosition(walk, nodeId, length) {\n const progress = walk.progress.get(nodeId);\n const range = walk.range;\n if (progress === void 0 || !range) {\n return void 0;\n }\n const start = Math.round(\n range.start + progress * (range.end - range.start) - length / 2\n );\n return `${range.contig}:${groupDigits(start)}-${groupDigits(start + length)}`;\n}\n\nexport {\n rangeText,\n walkKey,\n walkPosition\n};\n", "import {\n tubeSpan\n} from \"./chunk-XMW266WS.js\";\n\n// src/tubeMap/genes.ts\nfunction tubeMapGenes(byRefName, genes) {\n const out = [];\n for (const gene of genes) {\n const boxes = byRefName.get(gene.refName);\n const first = boxes?.[0];\n const last = boxes?.at(-1);\n if (!boxes || !first || !last) {\n continue;\n }\n const start = Math.max(gene.start, first.bp0);\n const end = Math.min(gene.end, last.bp1);\n if (end <= start) {\n continue;\n }\n out.push({\n gene,\n ...tubeSpan(boxes, start, end),\n exons: gene.exons.filter((e) => e.end > start && e.start < end).map(\n (e) => tubeSpan(boxes, Math.max(e.start, start), Math.min(e.end, end))\n )\n });\n }\n return out;\n}\nvar GENE_ROW_PX = 22;\nvar MAX_GENE_ROWS = 4;\nvar EXON_PX = 8;\nvar NAME_FONT = \"11px sans-serif\";\nvar NAME_GAP_PX = 8;\nfunction tubeMapGeneRows(genes) {\n const edges = genes.flatMap((g) => [\n { x: g.x0, step: 1 },\n { x: g.x1, step: -1 }\n ]).sort((a, b) => a.x - b.x || a.step - b.step);\n let depth = 0;\n let most = 0;\n for (const { step } of edges) {\n depth += step;\n most = Math.max(most, depth);\n }\n return Math.min(MAX_GENE_ROWS, most);\n}\nfunction drawTubeMapGenes(ctx, genes, frame, bottom, top = 0) {\n const { x, width, darkMode } = frame;\n const rows = Math.max(1, Math.floor((bottom - top) / GENE_ROW_PX));\n const rowEnds = [];\n const ink = darkMode ? \"#e0e0e6\" : \"#1c1c22\";\n ctx.font = NAME_FONT;\n ctx.textAlign = \"center\";\n ctx.textBaseline = \"alphabetic\";\n ctx.fillStyle = ink;\n ctx.strokeStyle = ink;\n ctx.lineWidth = 1;\n const placed = genes.map((g) => ({ g, s0: x(g.x0), s1: x(g.x1) })).filter(({ s0, s1 }) => s1 >= 0 && s0 <= width).sort((a, b) => a.s0 - b.s0);\n for (const { g, s0, s1 } of placed) {\n const arrow = g.gene.strand > 0 ? \" \\u2192\" : g.gene.strand < 0 ? \"\\u2190 \" : \"\";\n const label = g.gene.strand < 0 ? `${arrow}${g.gene.name}` : `${g.gene.name}${arrow}`;\n const mid = (Math.max(s0, 0) + Math.min(s1, width)) / 2;\n const half = ctx.measureText(label).width / 2;\n const left = Math.min(s0, mid - half);\n const right = Math.max(s1, mid + half);\n let row = rowEnds.findIndex((end) => end + NAME_GAP_PX <= left);\n if (row === -1) {\n row = Math.min(rowEnds.length, rows - 1);\n }\n rowEnds[row] = Math.max(rowEnds[row] ?? -Infinity, right);\n const glyphY = bottom - row * GENE_ROW_PX - EXON_PX / 2;\n ctx.beginPath();\n ctx.moveTo(s0, glyphY + 0.5);\n ctx.lineTo(s1, glyphY + 0.5);\n ctx.stroke();\n for (const e of g.exons) {\n const e0 = x(e.x0);\n ctx.fillRect(e0, glyphY - EXON_PX / 2, Math.max(1, x(e.x1) - e0), EXON_PX);\n }\n ctx.fillText(label, mid, glyphY - EXON_PX / 2 - 2);\n }\n}\n\nexport {\n tubeMapGenes,\n GENE_ROW_PX,\n tubeMapGeneRows,\n drawTubeMapGenes\n};\n", "import {\n LIFT_BACKDROP_CSS,\n computeColorSchemeRange,\n getNodeColor\n} from \"./chunk-A4PFFC4Q.js\";\nimport {\n abgrToCssRgba\n} from \"./chunk-G2FD7S3C.js\";\nimport {\n isBackbone\n} from \"./chunk-FYQWPEEY.js\";\n\n// src/referenceStrip.ts\nvar REFERENCE_STRIP_PX = 12;\nvar REFERENCE_STRIP_ZONE_PX = REFERENCE_STRIP_PX + 8;\nvar OVERHANG_PX = 8;\nvar OVERHANG_CAP_PX = OVERHANG_PX + 3;\nvar MIN_STAGGER_PX = 12;\nfunction referenceStripBlocks(graph, {\n colorScheme,\n referenceRamp,\n walks\n}) {\n const range = { ...computeColorSchemeRange(graph), referenceRamp };\n const out = [];\n graph.nodes.forEach((node, index) => {\n if (isBackbone(node)) {\n const colors = walks ? walks.map((w) => {\n const lane = w.colors.get(node.id);\n return lane === void 0 ? LIFT_BACKDROP_CSS : abgrToCssRgba(lane);\n }) : [abgrToCssRgba(getNodeColor(node, index, colorScheme, range))];\n out.push({\n node: node.id,\n bp0: node.stable.start,\n bp1: node.stable.start + node.length,\n colors,\n faded: colors.includes(LIFT_BACKDROP_CSS)\n });\n }\n });\n return out.sort((a, b) => a.bp0 - b.bp0);\n}\nfunction span(frame, bp0, bp1) {\n const a = bp0 * frame.scale + frame.translateX;\n const b = bp1 * frame.scale + frame.translateX;\n return a < b ? [a, b] : [b, a];\n}\nvar HIT_SLOP_PX = 2;\nfunction stripOverhang(blocks, frame, width) {\n const a = -frame.translateX / frame.scale;\n const b = (width - frame.translateX) / frame.scale;\n const lo = Math.min(a, b);\n const hi = Math.max(a, b);\n let below = 0;\n let above = 0;\n for (const block of blocks) {\n below += Math.max(0, Math.min(block.bp1, lo) - block.bp0);\n above += Math.max(0, block.bp1 - Math.max(block.bp0, hi));\n }\n return frame.scale >= 0 ? { left: Math.round(below), right: Math.round(above) } : { left: Math.round(above), right: Math.round(below) };\n}\nfunction stripBlockAt(blocks, frame, sx, sy) {\n if (sy < 0 || sy > REFERENCE_STRIP_PX + HIT_SLOP_PX) {\n return void 0;\n }\n let hit;\n let best = HIT_SLOP_PX;\n for (const b of blocks) {\n const [x0, x1] = span(frame, b.bp0, b.bp1);\n const dist = Math.max(0, x0 - sx, sx - x1);\n if (dist <= best) {\n best = dist;\n hit = b.node;\n }\n }\n return hit;\n}\nfunction nodeAnchor(segments, toScreen) {\n const p = segments?.[Math.floor(segments.length / 2)];\n return p ? toScreen(p) : void 0;\n}\nfunction stripPixels(blocks, frame, width, dpr) {\n const placed = blocks.map((b) => {\n const [x0, x1] = span(frame, b.bp0, b.bp1);\n const px0 = Math.round(x0 * dpr);\n return {\n colors: b.colors,\n x0,\n px0,\n px1: Math.max(Math.round(x1 * dpr), px0 + 1)\n };\n }).filter((b) => b.px1 > 0 && b.px0 < width * dpr).sort((a, b) => a.x0 - b.x0);\n const out = [];\n let claimed = -Infinity;\n const tierEnds = [-Infinity, -Infinity];\n for (const { colors, px0, px1 } of placed) {\n const start = Math.max(px0, claimed);\n if (px1 > start) {\n const tier = tierEnds[0] < start ? 0 : 1;\n tierEnds[tier] = px1;\n out.push({ colors, x0: start / dpr, x1: px1 / dpr, tier });\n claimed = px1;\n }\n }\n const covered = out.length > 0 ? out.at(-1).x1 - out[0].x0 : 0;\n return covered >= out.length * MIN_STAGGER_PX ? out : out.map(({ tier: _, ...b }) => b);\n}\nfunction drawOverhang(ctx, edgeX, inward, ink) {\n const capX = inward > 0 ? edgeX : edgeX - OVERHANG_CAP_PX;\n ctx.clearRect(capX, 0, OVERHANG_CAP_PX, REFERENCE_STRIP_PX);\n const tipX = edgeX + inward;\n const baseX = tipX + inward * OVERHANG_PX;\n ctx.beginPath();\n ctx.moveTo(tipX, REFERENCE_STRIP_PX / 2);\n ctx.lineTo(baseX, 0);\n ctx.lineTo(baseX, REFERENCE_STRIP_PX);\n ctx.closePath();\n ctx.fillStyle = ink;\n ctx.fill();\n}\nfunction rowEdge(row, rows, dpr) {\n return Math.round(row * REFERENCE_STRIP_PX * dpr / rows) / dpr;\n}\nfunction drawReferenceStrip(ctx, blocks, frame, {\n width,\n lit,\n darkMode,\n dpr = 1\n}) {\n const ink = darkMode ? \"#ffffff\" : \"#18181c\";\n ctx.clearRect(0, 0, width, REFERENCE_STRIP_ZONE_PX);\n for (const b of stripPixels(blocks, frame, width, dpr)) {\n const { tier } = b;\n const staggered = tier !== void 0 && b.colors.length === 1;\n const rows = staggered ? 2 : b.colors.length;\n b.colors.forEach((color, i) => {\n const row = staggered ? tier : i;\n const y0 = rowEdge(row, rows, dpr);\n ctx.fillStyle = color;\n ctx.fillRect(b.x0, y0, b.x1 - b.x0, rowEdge(row + 1, rows, dpr) - y0);\n });\n }\n const overhang = stripOverhang(blocks, frame, width);\n if (overhang.left > 0) {\n drawOverhang(ctx, 0, 1, ink);\n }\n if (overhang.right > 0) {\n drawOverhang(ctx, width, -1, ink);\n }\n if (lit) {\n const [x0, x1] = span(frame, lit.start, lit.end);\n const w = Math.max(x1 - x0, 3);\n const left = (x0 + x1) / 2 - w / 2;\n ctx.strokeStyle = ink;\n ctx.lineWidth = 1.5;\n ctx.strokeRect(left, 0.75, w, REFERENCE_STRIP_PX - 1.5);\n if (lit.anchor) {\n ctx.beginPath();\n ctx.moveTo(left + w / 2, REFERENCE_STRIP_PX);\n ctx.lineTo(lit.anchor.x, lit.anchor.y);\n ctx.lineWidth = 1;\n ctx.stroke();\n }\n }\n}\n\nexport {\n REFERENCE_STRIP_PX,\n REFERENCE_STRIP_ZONE_PX,\n referenceStripBlocks,\n stripOverhang,\n stripBlockAt,\n nodeAnchor,\n stripPixels,\n drawReferenceStrip\n};\n", "import type { RepeatCall } from './repeatFeatures'\n\n// Which genotyped allele belongs to which haplotype walk. A VCF states a\n// sample's alleles in genotype order, which is the genotyper's own order and\n// carries no correspondence to the assembly's haplotype numbering \u2014 TRGTdb's\n// ABCA7 record, for one, lists them shortest first. So the walks and the\n// alleles are paired by length instead: the pairing whose total difference is\n// smallest, which for lengths on a line is the non-crossing one.\n//\n// A walk that does not reach both flanking reference nodes is measured whole\n// rather than across the array, and an allele no read spanned is a copy of the\n// one that was called. Neither states a length for this array, so they pair\n// last and take no verdict \u2014 pairing them first let a walk that stops inside\n// the array take the allele that fit one spanning it, and the spanning walk\n// then read as a disagreement.\n\ninterface WalkCall extends RepeatCall {\n // undefined where the walk and the allele are not both measurements\n agrees?: boolean\n}\n\n// Every walk/call pair over the 94 HPRC samples TRGT genotyped at the ABCA7\n// VNTR is either within 8% of its allele or more than 14% from it, so any\n// threshold across that gap separates them the same way.\nexport const CALL_TOLERANCE = 0.1\n\nfunction agrees(walkBp: number, callBp: number) {\n return Math.abs(callBp - walkBp) <= CALL_TOLERANCE * Math.max(walkBp, callBp)\n}\n\n// Pair two ascending lists of lengths, leaving out the surplus of whichever is\n// longer. `out[i]` is the index in `calls` that `walks[i]` took.\nfunction nearest(walks: number[], calls: number[]) {\n const W = walks.length\n const C = calls.length\n const cost = Array.from({ length: W + 1 }, () => new Array(C + 1).fill(0))\n const paired = Array.from({ length: W + 1 }, () =>\n new Array<boolean>(C + 1).fill(false),\n )\n for (let i = W - 1; i >= 0; i--) {\n for (let j = C - 1; j >= 0; j--) {\n const together = Math.abs(walks[i]! - calls[j]!) + cost[i + 1]![j + 1]!\n const dropWalk = W - i > C - j ? cost[i + 1]![j]! : Infinity\n const dropCall = C - j > W - i ? cost[i]![j + 1]! : Infinity\n cost[i]![j] = Math.min(together, dropWalk, dropCall)\n paired[i]![j] = cost[i]![j] === together\n }\n }\n const out = new Array<number | undefined>(W).fill(undefined)\n for (let i = 0, j = 0; i < W && j < C;) {\n if (paired[i]![j]) {\n out[i++] = j++\n } else if (W - i > C - j) {\n i++\n } else {\n j++\n }\n }\n return out\n}\n\nfunction byLength<T>(items: T[], bp: (item: T) => number) {\n return items\n .map((item, i) => ({ item, i }))\n .sort((a, b) => bp(a.item) - bp(b.item))\n}\n\nconst backed = (call: RepeatCall) => call.spanningReads !== 0\n\nfunction scored(row: { bp: number; complete: boolean }, call: RepeatCall) {\n return {\n ...call,\n agrees: row.complete && backed(call) ? agrees(row.bp, call.bp) : undefined,\n }\n}\n\n// A phased genotype names its walk's haplotype outright, though a contig\n// break can give that haplotype two walks. Within a haplotype, and among the\n// unphased alleles, pairing goes by length: the walks that span the array\n// against the alleles reads spanned, then everything else against what those\n// two left. That decides the ambiguous cases on merit: which walk takes the\n// one allele a lone spanning read supports, and which allele a walk that stops\n// inside the array is drawn against.\nfunction pairSample<\n R extends { bp: number; complete: boolean; haplotype?: number },\n>(rows: R[], calls: RepeatCall[]) {\n const out = new Map<number, WalkCall>()\n const taken = new Set<RepeatCall>()\n const ranked = byLength(rows, r => r.bp)\n const pair = (pool: typeof ranked, group: RepeatCall[]) => {\n const stages = [\n [pool.filter(r => r.item.complete), group.filter(backed)],\n [pool, group],\n ] as const\n for (const [walks, alleles] of stages) {\n const free = walks.filter(r => !out.has(r.i))\n const open = byLength(\n alleles.filter(call => !taken.has(call)),\n call => call.bp,\n )\n nearest(\n free.map(r => r.item.bp),\n open.map(c => c.item.bp),\n ).forEach((pick, k) => {\n if (pick !== undefined) {\n const row = free[k]!\n const call = open[pick]!.item\n taken.add(call)\n out.set(row.i, scored(row.item, call))\n }\n })\n }\n }\n for (const haplotype of new Set(calls.flatMap(c => c.haplotype ?? []))) {\n pair(\n ranked.filter(r => r.item.haplotype === haplotype),\n calls.filter(c => c.haplotype === haplotype),\n )\n }\n pair(\n ranked,\n calls.filter(c => c.haplotype === undefined),\n )\n return out\n}\n\nexport function withCalls<\n R extends {\n sample: string\n bp: number\n complete: boolean\n haplotype?: number\n },\n>(rows: R[], calls: Record<string, RepeatCall[]> | undefined) {\n if (!calls) {\n return rows as (R & { call?: WalkCall })[]\n }\n const paired = new Map<R, WalkCall>()\n const bySample = new Map<string, R[]>()\n for (const row of rows) {\n const group = bySample.get(row.sample)\n if (group) {\n group.push(row)\n } else {\n bySample.set(row.sample, [row])\n }\n }\n for (const [sample, group] of bySample) {\n const called = calls[sample]\n if (called) {\n for (const [i, call] of pairSample(group, called)) {\n paired.set(group[i]!, call)\n }\n }\n }\n return rows.map(row => ({ ...row, call: paired.get(row) }))\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["FACET_GAP_PX", "FACET_TITLE_PX", "FACET_PAD_PX", "MIN_FACET_PANEL_PX", "facetGrid", "count", "bounds", "pixelRows", "width", "room", "columns", "tile", "across", "rows", "panelWidth", "panelRoom", "fitX", "fitY", "scale", "drawn", "height", "best", "grid", "FACET_FIELDS", "facetSettingOf", "facet", "raw", "domainFirst", "names", "domain", "rank", "name", "i", "listed", "a", "b", "facetCells", "by", "wrapOrder", "wrap", "places", "sample", "haplotype", "contig", "n", "p", "cells", "n", "v", "paint", "css", "m", "opacity", "paintAttrs", "kind", "color", "DOT_PX", "DOT_CELL_PX", "svgCanvas", "width", "height", "out", "subpaths", "start", "x", "y", "s", "reach", "points", "i", "pathData", "dots", "seen", "cell", "ctx", "cx0", "cy0", "cx1", "cy1", "d", "w", "h", "canvas", "MAX_DPR", "MAX_CANVAS_DIM_PX", "getDpr", "width", "height", "dpr", "syncCanvasSize", "canvas", "pw", "ph", "cssWidth", "cssHeight", "Canvas2DRenderer", "canvas", "ctx", "_handler", "width", "height", "syncCanvasSize", "getDpr", "batch", "factors", "edgeIndex", "factor", "transform", "k", "clearColor", "normalizedRgbToCssRgba", "edgeRun", "color", "items", "groupByPaint", "e", "i", "inRun", "brightenAbgr", "lifted", "s", "f", "arrowRun", "a", "curves", "runItems", "arrows", "runs", "nodeId", "run", "t", "abgrToCssRgba", "first", "c", "p0", "l", "p", "tip", "left", "notch", "right", "arrowheadOutline", "ARROW_NOTCH", "ux", "uy", "tipX", "tipY", "length", "halfWidth", "backX", "backY", "notchBack", "paintOf", "groups", "deferred", "item", "weight", "last", "into", "key", "group", "FALLBACK_CELL_SIZE", "meanExtentCellSize", "extentTotal", "count", "rowPitchOf", "boxes", "distinct", "min", "max", "box", "cellSizeFrom", "extentX", "extentY", "x", "resolveCellSize", "given", "getOrCreateCell", "cells", "cx", "cy", "row", "cell", "addToGrid", "cellSize", "minX", "minY", "maxX", "maxY", "entry", "cx0", "cx1", "cy0", "cy1", "queryGrid", "y", "radiusX", "radiusY", "results", "seen", "SpatialIndex", "nodePositions", "nodeId", "segments", "i", "seg", "next", "b", "EdgeSpatialIndex", "graph", "drawPaths", "axis", "deletions", "version", "routes", "stranded", "baseEdgeCurves", "ei", "edge", "fromSegments", "toSegments", "curves", "curveBounds", "numPaths", "padX", "padY", "o", "pathRibbonOffsets", "distanceToSegment", "px", "py", "x1", "y1", "x2", "y2", "dx", "dy", "lenSq", "t", "distanceToCubicBezier", "cx1", "cy1", "cx2", "cy2", "minDist", "samples", "lastX", "lastY", "i", "u", "bx", "by", "distanceToBezierCurve", "c", "distanceToEdgeCurves", "curves", "yToX", "d", "nodeCache", "getSpatialIndex", "nodePositions", "version", "cached", "index", "SpatialIndex", "edgeCache", "getEdgeSpatialIndex", "graph", "drawPaths", "axis", "deletions", "routes", "stranded", "EdgeSpatialIndex", "MIN_NODE_REACH_PX", "findHoveredNode", "graphX", "graphY", "ink", "yToXOf", "reach", "queryReach", "candidates", "hovered", "best", "nodeId", "segmentIdx", "segments", "dist", "segmentMeetsBox", "a", "b", "box", "t0", "t1", "p", "q", "nodesUnderBox", "screen", "hits", "line", "findHoveredEdge", "hiddenEdges", "deletionRoutes", "edgeThreshold", "edgeIndex", "edgeIdx", "edge", "fromSegments", "toSegments", "numPaths", "baseCurves", "offset", "pathRibbonOffsets", "translateCurves", "HALO_FACTOR", "LEGEND_INSET_PX", "GENE_PIN_DROP_PX", "GENE_STACK", "BUBBLE_STACK", "TOPMOST_BASELINE", "LABEL_PX", "LABEL_PAD", "geneCoverageNote", "pin", "length", "per", "unit", "amount", "bp", "geneLabelCandidates", "pins", "screen", "contigThickness", "nodesUnder", "ink", "byExtent", "x", "y", "note", "box", "id", "items", "extent", "a", "b", "layoutLabels", "m", "width", "height", "translateX", "translateY", "scaleX", "scaleY", "frame", "p", "reserved", "label", "rowLabelBox", "stripPx", "LABEL_CHAR_PX", "take", "occupancy", "onRows", "rowsTop", "r", "halo", "above", "h", "gap", "baseline", "byBubble", "bubbles", "placeLabels", "ticks", "t", "genes", "nodesUnderBox", "sizeCandidates", "sizeLabelCandidates", "deletionLabels", "placeSizeLabels", "nodeLabels", "nodeLabelBudget", "host", "read", "name", "autorun", "read", "computed", "read", "reaction", "read", "untracked", "read", "mobx_default", "host", "canonicalStrand", "node", "stepName", "strand", "stepStarts", "lengths", "total", "starts", "head", "i", "tail", "j", "mismatchesByStep", "record", "byStep", "known", "start", "s", "startOf", "k", "endOf", "first", "stepAt", "pos2", "atEnd", "end", "unplacedFrom", "add", "mismatch", "list", "last", "pos", "op", "parseCs", "at", "left", "take", "tubeMapReads", "graph", "records", "firstId", "nodeByName", "n", "reads", "nodes", "step", "kept", "mismatches", "names", "lastLength", "FORWARD_READ_COLORS", "REVERSE_READ_COLORS", "readColor", "read", "colors", "rampHueCss", "hue", "rampHue", "bp", "domain", "frac", "REFERENCE_RAMP_MAX_HUE", "HUE_STOP_DEG", "rampStops", "start", "reversed", "low", "high", "n", "_", "RAMP_GRADIENT_STOPS", "i", "RAMP_GRADIENT_CSS", "s", "el", "tag", "attrs", "children", "c", "escapeText", "s", "escapeAttr", "serializeEl", "node", "v", "k", "ON_REFERENCE", "OFF_REFERENCE", "OUTSIDE_CUT", "GENE_INK", "BAR_PX", "GAP_PX", "LABELLED_ROW_PX", "MIN_TILED_BAR_PX", "MIN_TILE_PX", "kb", "bp", "signedLength", "delta", "size", "units", "unit", "walkRowReadout", "row", "reference", "call", "gapBp", "complete", "stop", "outside", "called", "against", "region", "why", "readoutPlacement", "text", "endX", "width", "x", "LABEL_CHAR_PX", "unitTicks", "pxPerBp", "ticks", "k", "runPaint", "run", "ramp", "REFERENCE_RAMP_ALT_CSS", "stops", "rampStops", "rampHueCss", "alongRow", "axis", "start", "end", "rowSpan", "placeRowGenes", "rows", "byRow", "placed", "row", "genes", "axis", "clip", "start", "end", "g", "alongRow", "e", "a", "b", "GENE_FONT_PX", "GENE_CHAR_PX", "MIN_LETTERED_BAR_PX", "genePad", "rowPx", "barPx", "boxesGenes", "rowGeneBoxes", "X", "y", "ROW_HEIGHT_PX", "BAR_PX", "pad", "boxes", "x", "taken", "named", "w", "half", "at", "box", "rowsText", "n", "walkRowsKey", "bars", "o", "entries", "RAMP_GRADIENT_CSS", "ON_REFERENCE", "REFERENCE_RAMP_ALT_CSS", "OFF_REFERENCE", "OUTSIDE_CUT", "CALL_TICK", "UNBACKED_TICK", "DISAGREES", "callTickInk", "call", "walkRowsKeyTree", "idPrefix", "parts", "i", "rampId", "ramp", "el", "RAMP_GRADIENT_STOPS", "s", "swatch", "GENE_INK", "GAP_PX", "text", "LABEL_CHAR_PX", "p", "rowPitch", "count", "room", "minRowPx", "fit", "LABELLED_ROW_PX", "coalesceRuns", "runs", "pxPerBp", "minBp", "out", "bucket", "flush", "on", "off", "r", "onReference", "lead", "held", "run", "geneTree", "walkRowsTree", "frame", "bp", "overhang", "Y", "origin", "unit", "reference", "along", "offset", "prefix", "rowTree", "paint", "runPaint", "h", "id", "rect", "color", "k", "ticks", "MIN_TILED_BAR_PX", "unitTicks", "walkRowReadout", "readoutPlacement", "readouts", "REPEAT_GROWTH", "coveringRepeat", "b", "repeats", "span", "growth", "SUPERBUBBLE_SEGMENTS", "formatBpRange", "shortest", "longest", "low", "formatBp", "high", "unit", "routes", "count", "SATURATED_PATH_COUNT", "classifyBubble", "c", "classifyShape", "refSpan", "pathCount", "segmentCount", "inversion", "range", "sameLength", "repeat", "name", "alleles", "bp", "BUBBLE_KIND_COLORS", "BUBBLE_KIND_NAMES", "bubbleSegmentIds", "referenceBoxes", "graph", "layout", "nodeById", "n", "byRefName", "node", "index", "graphNode", "isBackbone", "refName", "start", "boxes", "a", "b", "tubeX", "bp", "isEnd", "lo", "hi", "mid", "bp1", "box", "span", "tubeSpan", "end", "rulerBoxes", "best", "TICK_PX", "LABEL_GAP_PX", "TARGET_TICK_PX", "MIN_BRACKET_PX", "rulerInk", "darkMode", "niceStep", "raw", "pow", "m", "placeLabels", "candidates", "placed", "text", "at", "scaleMarks", "x", "width", "measure", "first", "last", "from", "to", "bpSpan", "step", "ticks", "positions", "sx", "boxMarks", "shown", "s0", "s1", "label", "position", "spans", "lengths", "boundaries", "length", "formatBp", "ends", "rulerMarks", "referenceAxis", "drawTubeMapRuler", "ctx", "frame", "top", "marks", "ink", "y", "x0", "x1", "tubeMapConnectors", "boxes", "bpToScreen", "tubeToScreen", "width", "out", "box", "bottom0", "bottom1", "HIT_SLOP_PX", "connectorAt", "connectors", "zoneBottom", "sx", "sy", "t", "hit", "best", "a", "b", "dist", "band", "ctx", "c", "bottom", "sides", "drawTubeMapConnectors", "highlightNode", "darkMode", "ink", "drawLitConnector", "node", "lit", "boxAt", "boxes", "bp", "visited", "lo", "hi", "mid", "box", "deviationMarks", "drawing", "deviations", "layout", "referenceBoxes", "a", "b", "marks", "track", "devs", "segment", "d", "bp0", "bp1", "x0", "x1", "index", "at", "deviationInk", "darkMode", "drawDeviationMarks", "ctx", "x", "y", "width", "m", "left", "right", "top", "emptyTrackShapes", "NOT_SAMPLES", "parsePanSN", "name", "sample", "haplotype", "contig", "DEBUG", "debugLog", "args", "READ_FACET_FIELDS", "FACET_FIELDS", "layersFrom", "layers", "coarsenedReadView", "showReads", "hasReads", "coarsen", "stat", "banded", "statOf", "data", "layer", "configFrom", "options", "emptyState", "config", "emptyTrackShapes", "layoutTubeMap", "inputNodes", "inputTracks", "inputReads", "topology", "layoutTopology", "placeTubeMap", "measurements", "arrangeTopology", "everything", "place", "node", "i", "placeSubset", "selectTracks", "selectReads", "tracks", "reads", "bandIdBase", "measured", "state", "read", "t", "straightenTrack", "generateNodeMap", "generateTrackIndexSequences", "generateNodeWidth", "generateNodeSuccessors", "generateNodeOrder", "reverseReversedReads", "mergeNodes", "generateNodeDegree", "switchNodeOrientation", "getMaxOrder", "mappingQualityCutoff", "focusReadNames", "facet", "focus", "facetHoldsRead", "references", "track", "kept", "sampleOf", "parsePanSN", "place", "topology", "tracks", "reads", "x", "bandIdBase", "state", "emptyState", "node", "i", "track", "read", "layers", "ignoreStrand", "haplotypeBandIdBase", "COARSENED_ID_BASE", "haplotypeBands", "statOf", "bandHaplotypes", "calculateTrackWidth", "generateLaneAssignment", "generateReadOnlyNodeAttributes", "readBands", "buildCoarsenedSyntheticBands", "coarsened", "data", "unit", "banding", "reverseReversedReads", "generateTrackIndexSequences", "b", "placeReads", "generateNodeXCoords", "generateSVGShapesFromPath", "debugLog", "getImageDimensions", "isReverse", "nodeName", "forward", "reverse", "flip", "isForwardIndex", "n", "straightenTrack", "index", "nodesToInvert", "visitedForward", "visit", "sequence", "j", "getReverseComplement", "orderY", "setMapToMax", "step", "map", "key", "value", "existing", "READ_WIDTH", "assignReadsToNodes", "idx", "firstNode", "element", "pathIdx", "elemNode", "basicPath", "sortedNodes", "compareNodesByOrder", "sets", "layer", "source", "set", "orderedSets", "a", "topMargin", "placeReadSet", "bottomY", "calculateBottomY", "elementsWithoutNode", "len", "prevSegment", "lastValidPrev", "seg", "nextSegment", "firstValidNext", "previousVisitToNode", "nextVisitToNode", "betweenCycleReverseTraversal", "compareNoNodeReads", "segment", "toPlace", "incomingReads", "readID", "outgoingReads", "internalReads", "startY", "incomingKeys", "entry", "path", "decisionStep", "foundY", "k", "y", "compareIncomingReadKeys", "currentY", "occupiedUntil", "readElement", "setOccupiedUntil", "maxY", "compareReadOutgoingSegmentsByGoingTo", "occupiedFrom", "firstNodeOffset", "occUntil", "incReadElementIndices", "incRead", "incReadPathElement", "compareInternalReads", "readIdx", "currentRead", "finalNodeCoverLength", "heightIncrease", "adjustVertically3", "pathIndex", "readA", "readB", "segmentA", "segmentB", "prevNodeA", "prevNodeB", "aPrev", "bPrev", "aReverse", "bReverse", "readIndexA", "pathIndexA", "readIndexB", "pathIndexB", "previousValidYA", "previousValidYB", "lastPathIndexA", "lastPathIndexB", "initialNodeA", "initialNodeB", "nodeA", "nodeB", "nextNodeIdx", "beginDiff", "compareTrackByInitialOrdering", "trackA", "trackB", "pathA", "pathB", "AIndex", "BIndex", "trackAOrder", "trackBOrder", "idxA", "idxB", "aFirst", "bFirst", "aLast", "bLast", "pass", "order", "isForward", "currentNodeIndex", "currentNodeIsForward", "currentNode", "previousNode", "previousNodeIsForward", "pos", "sequenceNew", "reverseMismatches", "nodeByName", "temp", "firstLen", "lastLen", "mismatches", "sequenceLength", "mm", "mirroredMismatch", "span", "COMPLEMENT", "s", "result", "tracksOrReads", "signedIndexOf", "signed", "NODE_HORIZONTAL_SLACK", "bounds", "rectangles", "verticalRectangles", "curves", "shapes", "xStart", "xEnd", "generateNodeMap", "nodeMap", "generateNodeSuccessors", "successorSets", "predecessorSets", "addEdges", "current", "follower", "generateNodeOrderOfSingleTrack", "forwardOrder", "backwardOrder", "minOrder", "nodeIndex", "increaseOrderForAllNodes", "generateNodeOrderTrackBeginning", "anchorIndex", "anchorSeqVal", "currentOrder", "increment", "UNREACHABLE_ORDER", "fillUnassignedOrders", "orders", "filled", "generateNodeOrder", "modifiedSequence", "rightIndex", "leftIndex", "tracksAndReads", "reachability", "uninvert", "increaseOrderForSuccessors", "isSuccessor", "finalOrders", "first", "second", "scratch", "stamp", "generation", "stack", "childIndex", "getMaxOrder", "max", "v", "amount", "startingNode", "tabuNode", "newOrder", "increasedOrders", "queue", "head", "currentNodeOrder", "successor", "predecessor", "generateNodeDegree", "switchNodeOrientation", "switchNodeOrientationForPaths", "paths", "pivotPath", "scores", "onPivot", "indexSequence", "last", "prevOrder", "nextOrder", "vote", "currentX", "nextX", "extra", "calculateExtraSpace", "RISE_KNEE", "riseExtra", "rise", "leftSideEdges", "rightSideEdges", "fallAngleAdjustment", "prevSeg", "prevSegmentPerOrderPerTrack", "assignmentByOrderAndNode", "trackNo", "segmentNumber", "addToAssignment", "generateSingleLaneAssignment", "segmentID", "assignment", "getIdealLanesAndCoords", "currentLane", "potentialAdjustmentValues", "prevNameIsNull", "prevTrack", "compareByIdealLane", "adjustVertically", "verticalAdjustment", "minAdjustmentCost", "moveBy", "cost", "getVerticalAdjustmentCost", "adjustBy", "assignmentNode", "aNode", "allAreFour", "NARROW_WIDTH", "WIDE_WIDTH", "getReadXStart", "offset", "clampedXCoordinateOfBaseWithinNode", "getReadXEnd", "cover", "getXCoordinateOfBaseWithinNode", "base", "nodeLeftX", "nodeRightX", "nodePixelCoordinatesInX", "clamped", "yStart", "yEnd", "orderStartX", "orderEndX", "reference", "generateTurnaround", "buildCoarsenedSyntheticBands", "state", "source", "unit", "firstId", "COARSENED_ID_BASE", "edges", "total", "span", "edgeKey", "s", "d", "ignoreStrand", "sourceIndex", "item", "weight", "seq", "i", "sSigned", "dSigned", "srcNode", "dstNode", "key", "existing", "maxEdgeCount", "e", "BAND_MIN_WIDTH", "READ_WIDTH", "BAND_MAX_WIDTH", "widthForCount", "c", "synthetic", "edge", "id", "share", "shareText", "formatShare", "crossingsText", "label", "srcLen", "DEBUG", "tallestName", "tallestH", "n", "debugLog", "bandHaplotypes", "rulerIndex", "t", "refIndex", "ref", "refDuplicates", "refSigns", "firstVisitSigns", "altHaplotypes", "_", "walk", "orientedLike", "bands", "agreement", "visit", "sign", "flip", "signs", "node", "count", "MIN_BEND_WIDTH", "generateTurnaround", "dir", "x", "yStart", "yEnd", "trackWidth", "trackID", "order", "type", "trackName", "extra", "offset", "apex", "radius", "stem", "yTop", "yBottom", "stubNear", "stubFar", "horizontal", "segTop", "inner", "outer", "nodePixelCoordinatesInX", "nodeLeftX", "nodeRightX", "generateNodeWidth", "charWidth", "TRACK_END", "noNeighbors", "nodeCount", "addNeighbor", "neighbors", "index", "neighbor", "soleNeighbor", "mergeNodes", "pred", "succ", "signedIndexOf", "nodeName", "signed", "forward", "isReverse", "track", "sequence", "isHaplotype", "last", "previous", "current", "next", "absorbed", "mergeableWithPred", "origin", "start", "end", "head", "donor", "mergeableWithSucc", "read", "entries", "shift", "mergedSequence", "mergedEntries", "carried", "mismatches", "by", "mismatch", "name", "merged", "reverse", "kept", "predecessor", "successor", "groupBy", "items", "key", "groups", "item", "k", "group", "compareCurvesByXYStartValue", "a", "b", "curveEnds", "curve", "compareTuples", "i", "d", "STEEP_SHARE", "MAX_SPREAD", "spreads", "gapWidth", "first", "span", "floor", "wanted", "c", "rise", "across", "sum", "pick", "total", "w", "reference", "others", "referenceScale", "room", "othersScale", "curvePaths", "curves", "type", "groupedCurves", "curveGroup", "spread", "adjustValue", "s", "at", "share", "xAdjusted", "xNextAdjusted", "flattenPath", "steps", "tokens", "points", "x", "y", "num", "command", "x1", "y1", "x2", "y2", "x3", "y3", "t", "u", "e", "nodeOutlinePath", "node", "readMismatches", "read", "layout", "marks", "entries", "visits", "segment", "entry", "i", "nodeIndex", "forward", "node", "y", "base", "at", "pos", "getXCoordinateOfBaseWithinNode", "mm", "x0", "softClip", "x1", "tubeMapMismatches", "MAX_GAP_PX", "MAX_GAP_SHARE", "isReal", "c", "referenceKnots", "columns", "bpToScreen", "real", "first", "tx", "target", "gap", "i", "span", "demand", "a", "b", "scale", "spread", "sx", "k", "offset", "sum", "g", "blocks", "t", "block", "last", "n", "q", "warpX", "knots", "lo", "hi", "mid", "parsePath", "d", "tokens", "commands", "i", "num", "op", "extentOf", "x0", "x1", "c", "shapeOf", "color", "id", "haplotype", "reference", "flattenPath", "trackColors", "layout", "pathColors", "track", "readColor", "layerOf", "type", "colors", "referenceIds", "gapWidth", "shapes", "colorOf", "s", "isReference", "rects", "r", "curves", "curvePaths", "corners", "referenceTrackIds", "graph", "ids", "path", "pathOrigin", "tubeMapPicture", "columns", "MAX_GAP_PX", "nodes", "node", "nodeOutlinePath", "tubeMapMismatches", "m", "trace", "ctx", "x", "y", "cx", "cy", "fillByColor", "items", "visible", "addTo", "byColor", "item", "list", "FULL_OUTLINE_PX", "MIN_OUTLINE_ALPHA", "outlineAlpha", "screenWidth", "NODE_TINT_ALPHA", "drawTubeMap", "picture", "frame", "width", "layer", "inPass", "left", "top", "stroke", "fill", "outlineWidth", "tint", "drawTubeMapHighlight", "drawMismatches", "n", "MISMATCH_FONT_PX", "MIN_MISMATCH_FONT_PX", "mismatchesLegible", "yScale", "mismatchOnScreen", "marks", "darkMode", "fontPx", "inside", "points", "sx", "sy", "hit", "j", "xi", "yi", "xj", "yj", "tubeMapTrackAt", "l", "px", "py", "INSERTION_SLOP_PX", "tubeMapMismatchAt", "host", "read", "name", "groupKeyComparator", "read", "groupKeys_default", "host", "SECTION_HEADER_PX", "parseSamplesTsv", "text", "head", "lines", "columns", "rows", "line", "name", "values", "c", "i", "metadataColumns", "row", "key", "groupByOf", "value", "field", "domain", "d", "plural", "n", "noun", "columnValueOf", "table", "valueOf", "haplotype", "sample", "groupsByColumn", "items", "nounOf", "groups", "item", "group", "groupKeyComparator", "members", "groupWalkRows", "groupBy", "first", "sections", "title", "section", "g", "sectionPlacement", "rowPx", "sectionOf", "k", "rowY", "s", "y", "best", "lo", "hi", "shift", "walkRowTrees", "bars", "frame", "o", "walkRowsTree", "parsePanSN", "refName", "parts", "haplotype", "collectRun", "seed", "byId", "adj", "claimed", "members", "anchors", "queue", "id", "node", "neighborId", "neighbor", "REFERENCE_RANK", "anchorSpan", "a", "sorted", "b", "first", "last", "start", "end", "runDistances", "entry", "m", "dist", "member", "reach", "known", "runOffsets", "ordered", "rank", "i", "offsets", "offset", "projectAlleles", "graph", "isAnchored", "n", "buildNeighbors", "alleles", "span", "max", "PANEL_GAP", "PANEL_REFERENCE_TUBE", "PANEL_TUBE", "PANEL_TUBES", "TINTED_TUBES", "PANEL_TITLE_FONT", "TUBE_MAP_PANELS", "walkOf", "name", "pathOrigin", "roleTubeColors", "paths", "reference", "tubes", "haplotype", "p", "VALUE_TUBES", "NO_VALUE_TUBE", "valueTubePalette", "values", "sorted", "v", "groupKeyComparator", "i", "valueTubeColors", "valueOf", "palette", "walk", "columnKeyOf", "field", "table", "columnValueOf", "sample", "parsePanSN", "tubeMapPanelGroups", "graph", "split", "names", "keyOf", "groupsByColumn", "key", "members", "title", "groups", "list", "domain", "rank", "listed", "a", "b", "boxOf", "drawing", "node", "box", "memberAt", "spanOf", "left", "right", "sx", "spans", "id", "span", "start", "s", "end", "share", "bp", "distance", "walksThrough", "all", "here", "member", "COUNT_FONT", "MIN_COUNT_RUN_PX", "MIN_COUNT_TUBE_PX", "drawBundleCounts", "ctx", "picture", "x", "y", "width", "counts", "r", "n", "top", "bottom", "LENGTH_FONT", "MIN_LENGTH_LABEL_BP", "drawSqueezedLengths", "lengthOf", "stacks", "text", "formatBp", "mid", "stack", "drawn", "count", "label", "d", "paintPanelHover", "panels", "hover", "lit", "hit", "drawTubeMapHighlight", "plural", "graphOfPaths", "kept", "keptPaths", "walks", "nodeIds", "nodes", "pathVisits", "path", "segment", "e", "withTubeMapPanels", "whole", "laidOut", "nodePositions", "minX", "maxX", "result", "tubeMap", "extent", "height", "dy", "segments", "EXON_COLOR", "EXON_GAP_PX", "EXON_LINE_PX", "MIN_LANE_PX", "exonStretches", "pins", "halfWidthPx", "lift", "pathOf", "d", "inkPx", "nodeId", "own", "pin", "exonOutlineTree", "stretches", "o", "stroke", "s", "color", "width", "el", "rangeText", "contig", "start", "end", "s", "e", "groupDigits", "formatBp", "walkKey", "walk", "reference", "field", "own", "scale", "spanned", "outside", "walkPosition", "nodeId", "length", "progress", "range", "tubeMapGenes", "byRefName", "genes", "out", "gene", "boxes", "first", "last", "start", "end", "tubeSpan", "e", "GENE_ROW_PX", "MAX_GENE_ROWS", "EXON_PX", "NAME_FONT", "NAME_GAP_PX", "tubeMapGeneRows", "edges", "g", "a", "b", "depth", "most", "step", "drawTubeMapGenes", "ctx", "frame", "bottom", "top", "x", "width", "darkMode", "rows", "rowEnds", "ink", "placed", "s0", "s1", "arrow", "label", "mid", "half", "left", "right", "row", "glyphY", "e0", "REFERENCE_STRIP_PX", "REFERENCE_STRIP_ZONE_PX", "OVERHANG_PX", "OVERHANG_CAP_PX", "MIN_STAGGER_PX", "referenceStripBlocks", "graph", "colorScheme", "referenceRamp", "walks", "range", "computeColorSchemeRange", "out", "node", "index", "isBackbone", "colors", "w", "lane", "LIFT_BACKDROP_CSS", "abgrToCssRgba", "getNodeColor", "b", "span", "frame", "bp0", "bp1", "a", "HIT_SLOP_PX", "stripOverhang", "blocks", "width", "lo", "hi", "below", "above", "block", "stripBlockAt", "sx", "sy", "hit", "best", "x0", "x1", "dist", "nodeAnchor", "segments", "toScreen", "p", "stripPixels", "dpr", "placed", "px0", "claimed", "tierEnds", "px1", "start", "tier", "_", "drawOverhang", "ctx", "edgeX", "inward", "ink", "capX", "tipX", "baseX", "rowEdge", "row", "rows", "drawReferenceStrip", "lit", "darkMode", "staggered", "color", "i", "y0", "overhang", "left", "agrees", "walkBp", "callBp", "nearest", "walks", "calls", "W", "C", "cost", "paired", "i", "j", "together", "dropWalk", "dropCall", "out", "byLength", "items", "bp", "item", "a", "b", "backed", "call", "scored", "row", "pairSample", "rows", "taken", "ranked", "r", "pair", "pool", "group", "stages", "alleles", "free", "open", "c", "pick", "k", "haplotype", "withCalls", "bySample", "sample", "called"]
|
|
7
7
|
}
|