@jbrowse/bandage-core 6.0.1 → 6.0.3

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.
Files changed (162) hide show
  1. package/README.md +23 -7
  2. package/dist/alleleProjection/projectAlleles.js +10 -0
  3. package/dist/anchoredNodes.js +24 -0
  4. package/dist/bubbleSpreads.js +11 -0
  5. package/dist/bubbles/bubbleHalos.js +11 -0
  6. package/dist/bubbles/bubbleLine.js +14 -0
  7. package/dist/bubbles/bubblesFromGraph.js +10 -0
  8. package/dist/bubbles/classifyBubble.js +15 -0
  9. package/dist/bubbles/popBubble.js +9 -0
  10. package/dist/chunks/chunk-2CVHXFK7.js +530 -0
  11. package/dist/chunks/chunk-3S3YVOJ7.js +69 -0
  12. package/dist/chunks/chunk-47DYCZOK.js +115 -0
  13. package/dist/chunks/chunk-4EMPBO7S.js +117 -0
  14. package/dist/chunks/chunk-4S47XRYA.js +149 -0
  15. package/dist/chunks/chunk-5XQDMQXU.js +431 -0
  16. package/dist/chunks/chunk-6JEWNXCQ.js +90 -0
  17. package/dist/chunks/chunk-6SBUFFTB.js +97 -0
  18. package/dist/chunks/chunk-6SXMCK6I.js +476 -0
  19. package/dist/chunks/chunk-72N5DJHZ.js +155 -0
  20. package/dist/chunks/chunk-73RSLGZT.js +73 -0
  21. package/dist/chunks/chunk-7XHHVYG7.js +13 -0
  22. package/dist/chunks/chunk-AB35TJST.js +67 -0
  23. package/dist/chunks/chunk-BPLIXMH7.js +52 -0
  24. package/dist/chunks/chunk-BUBZ32IC.js +101 -0
  25. package/dist/chunks/chunk-BXEPA4KS.js +179 -0
  26. package/dist/chunks/chunk-C44YRP5F.js +85 -0
  27. package/dist/chunks/chunk-CDLPYR5O.js +135 -0
  28. package/dist/chunks/chunk-CJ2EE4AF.js +40 -0
  29. package/dist/chunks/chunk-CPMHA4W5.js +6 -0
  30. package/dist/chunks/chunk-CR7EGAFE.js +241 -0
  31. package/dist/chunks/chunk-CS3E4ETM.js +202 -0
  32. package/dist/chunks/chunk-CTSBC2O6.js +90 -0
  33. package/dist/chunks/chunk-D3M7SBKL.js +210 -0
  34. package/dist/chunks/chunk-DKOB2OPC.js +177 -0
  35. package/dist/chunks/chunk-EJ5OZTCK.js +52 -0
  36. package/dist/chunks/chunk-EK4HGYO7.js +174 -0
  37. package/dist/chunks/chunk-EPZORFTI.js +23 -0
  38. package/dist/chunks/chunk-ES2N6V56.js +83 -0
  39. package/dist/chunks/chunk-EZPBJPK6.js +54 -0
  40. package/dist/chunks/chunk-FYQWPEEY.js +65 -0
  41. package/dist/chunks/chunk-GGQRADFS.js +170 -0
  42. package/dist/chunks/chunk-GOY6REMT.js +43 -0
  43. package/dist/chunks/chunk-GQ2AOHU4.js +112 -0
  44. package/dist/chunks/chunk-HNQPEMYE.js +297 -0
  45. package/dist/chunks/chunk-IGVV37VI.js +60 -0
  46. package/dist/chunks/chunk-IO2PCPZI.js +218 -0
  47. package/dist/chunks/chunk-ISEI2FH3.js +108 -0
  48. package/dist/chunks/chunk-JKJWSY4V.js +32 -0
  49. package/dist/chunks/chunk-KQFOCDFY.js +73 -0
  50. package/dist/chunks/chunk-L3O7AWLI.js +52 -0
  51. package/dist/chunks/chunk-LLJUG2H7.js +6 -0
  52. package/dist/chunks/chunk-LOEA5IHZ.js +71 -0
  53. package/dist/chunks/chunk-LTUWJKHD.js +112 -0
  54. package/dist/chunks/chunk-MFKORG3F.js +44 -0
  55. package/dist/chunks/chunk-MI35EUIE.js +76 -0
  56. package/dist/chunks/chunk-MNUSQCLG.js +29 -0
  57. package/dist/chunks/chunk-MQJUG2D2.js +53 -0
  58. package/dist/chunks/chunk-MREQ7GIA.js +181 -0
  59. package/dist/chunks/chunk-N62KBLFC.js +326 -0
  60. package/dist/chunks/chunk-NNODIW4U.js +26 -0
  61. package/dist/chunks/chunk-PBENCR5L.js +60 -0
  62. package/dist/chunks/chunk-PCZ4PTYC.js +726 -0
  63. package/dist/chunks/chunk-PUG7LXDF.js +70 -0
  64. package/dist/chunks/chunk-QYBZZI5H.js +0 -0
  65. package/dist/chunks/chunk-R6ZUK4Y3.js +232 -0
  66. package/dist/chunks/chunk-RAKOB6IV.js +169 -0
  67. package/dist/chunks/chunk-ROF2R3RF.js +205 -0
  68. package/dist/chunks/chunk-RVS2QCOX.js +135 -0
  69. package/dist/chunks/chunk-ST2IBUAN.js +119 -0
  70. package/dist/chunks/chunk-SZNZ2T6D.js +198 -0
  71. package/dist/chunks/chunk-T43W7NKK.js +122 -0
  72. package/dist/chunks/chunk-TAMCZHLW.js +190 -0
  73. package/dist/chunks/chunk-TDQLINVI.js +16 -0
  74. package/dist/chunks/chunk-TEDQJPMI.js +131 -0
  75. package/dist/chunks/chunk-TZFWUT2C.js +66 -0
  76. package/dist/chunks/chunk-UVBGRJQX.js +50 -0
  77. package/dist/chunks/chunk-VHW7FDHU.js +42 -0
  78. package/dist/chunks/chunk-VZQ4FKLR.js +38 -0
  79. package/dist/chunks/chunk-WFX3MAKA.js +102 -0
  80. package/dist/chunks/chunk-WOO7QYKB.js +121 -0
  81. package/dist/chunks/chunk-WSIFAZU7.js +132 -0
  82. package/dist/chunks/chunk-X5L37W4J.js +82 -0
  83. package/dist/chunks/chunk-Y3IOTZJA.js +61 -0
  84. package/dist/chunks/chunk-YMSSF2RK.js +257 -0
  85. package/dist/cli/figure.js +84 -17
  86. package/dist/colorSchemes.js +10 -0
  87. package/dist/deletionEdges.js +13 -0
  88. package/dist/el.js +8 -0
  89. package/dist/facetGrid.js +16 -0
  90. package/dist/figure.js +51 -0
  91. package/dist/gaf/parseGaf.js +12 -0
  92. package/dist/gbzCut.js +19 -0
  93. package/dist/gbzJoin.js +6 -0
  94. package/dist/gbzWindow.js +28 -0
  95. package/dist/genes/exonOutline.js +11 -0
  96. package/dist/genes/geneFiles.js +14 -0
  97. package/dist/genes/genePins.js +10 -0
  98. package/dist/gfa/gfaConverter.js +11 -0
  99. package/dist/gfa-core/gfaParser.js +8 -0
  100. package/dist/gfa-core/index.js +9 -0
  101. package/dist/graphLabels.js +24 -0
  102. package/dist/index.js +262 -1407
  103. package/dist/labelLayout.js +24 -0
  104. package/dist/layout/anchoredLayout.js +11 -0
  105. package/dist/layout/deletionRoutes.js +10 -0
  106. package/dist/layout/drawnScale.js +22 -0
  107. package/dist/layout/mergeRuns.js +15 -0
  108. package/dist/layout/orderedLayout.js +12 -0
  109. package/dist/layout/orientToReference.js +7 -0
  110. package/dist/layout/placeOffReference.js +9 -0
  111. package/dist/layout/referenceSeeds.js +11 -0
  112. package/dist/layout/rowSpacing.js +6 -0
  113. package/dist/layout/sampleRowLayout.js +11 -0
  114. package/dist/layout/trimToWindow.js +99 -0
  115. package/dist/layout/tubeMapLayout.js +28 -0
  116. package/dist/layout/walkRowDraw.js +65 -0
  117. package/dist/layout/walkRowLayout.js +13 -0
  118. package/dist/layout/walkRows.js +11 -0
  119. package/dist/layout/walkStrip.js +40 -0
  120. package/dist/layoutModes.js +35 -0
  121. package/dist/loadBandage.js +6 -0
  122. package/dist/nodeWidths.js +18 -0
  123. package/dist/overlayLabels.js +18 -0
  124. package/dist/pansn.js +18 -0
  125. package/dist/pathAnchoring.js +18 -0
  126. package/dist/pathColors.js +31 -0
  127. package/dist/pipeline.js +40 -0
  128. package/dist/reference.js +24 -0
  129. package/dist/referenceRampCss.js +29 -0
  130. package/dist/referenceSpan.js +11 -0
  131. package/dist/referenceStrip.js +35 -0
  132. package/dist/renderer/Canvas2DRenderer.js +9 -0
  133. package/dist/renderer/GeometryBuilder.js +42 -0
  134. package/dist/renderer/colorBits.js +8 -0
  135. package/dist/renderer/recordingCanvas.js +44 -0
  136. package/dist/renderer/svgCanvas.js +6 -0
  137. package/dist/renderer/types.js +0 -0
  138. package/dist/tubeMap/axis.js +25 -0
  139. package/dist/tubeMap/coarsen.js +361 -0
  140. package/dist/tubeMap/connectors.js +13 -0
  141. package/dist/tubeMap/deviations.js +85 -0
  142. package/dist/tubeMap/draw.js +15 -0
  143. package/dist/tubeMap/frame.js +9 -0
  144. package/dist/tubeMap/genes.js +20 -0
  145. package/dist/tubeMap/mismatches.js +6 -0
  146. package/dist/tubeMap/nodeColors.js +21 -0
  147. package/dist/tubeMap/reads.js +17 -0
  148. package/dist/tubeMap/warp.js +8 -0
  149. package/dist/types/version.d.ts +1 -1
  150. package/dist/types.js +0 -0
  151. package/dist/util/SpatialIndex.js +13 -0
  152. package/dist/util/edgeCurves.js +10 -0
  153. package/dist/util/geometry.js +39 -0
  154. package/dist/util/hitDetection.js +20 -0
  155. package/dist/util/wheelZoom.js +6 -0
  156. package/dist/version.js +6 -0
  157. package/dist/viewport.js +33 -0
  158. package/dist/walkEncoding.js +39 -0
  159. package/dist/walkHighlight.js +26 -0
  160. package/dist/walkKey.js +17 -0
  161. package/package.json +38 -5
  162. package/dist/chunks/chunk-EXSFRX2F.js +0 -7400
@@ -0,0 +1,83 @@
1
+ import {
2
+ isBackbone
3
+ } from "./chunk-FYQWPEEY.js";
4
+
5
+ // src/referenceSpan.ts
6
+ var MAX_BACKBONE_HOPS = 4;
7
+ function buildNeighbors(graph) {
8
+ const neighbors = /* @__PURE__ */ new Map();
9
+ function add(from, to) {
10
+ const list = neighbors.get(from);
11
+ if (list) {
12
+ list.push(to);
13
+ } else {
14
+ neighbors.set(from, [to]);
15
+ }
16
+ }
17
+ for (const edge of graph.edges) {
18
+ add(edge.from, edge.to);
19
+ add(edge.to, edge.from);
20
+ }
21
+ return neighbors;
22
+ }
23
+ function flankingSpan({
24
+ nodeId,
25
+ nodeById,
26
+ neighbors
27
+ }) {
28
+ const seen = /* @__PURE__ */ new Set([nodeId]);
29
+ let frontier = [nodeId];
30
+ let minEnd = Infinity;
31
+ let maxStart = -Infinity;
32
+ for (let hop = 0; hop < MAX_BACKBONE_HOPS && frontier.length > 0; hop++) {
33
+ const next = [];
34
+ for (const id of frontier) {
35
+ const adjacent = neighbors.get(id);
36
+ if (adjacent) {
37
+ for (const neighborId of adjacent) {
38
+ if (!seen.has(neighborId)) {
39
+ seen.add(neighborId);
40
+ const neighbor = nodeById.get(neighborId);
41
+ if (neighbor && isBackbone(neighbor)) {
42
+ minEnd = Math.min(minEnd, neighbor.stable.start + neighbor.length);
43
+ maxStart = Math.max(maxStart, neighbor.stable.start);
44
+ } else {
45
+ next.push(neighborId);
46
+ }
47
+ }
48
+ }
49
+ }
50
+ }
51
+ frontier = next;
52
+ }
53
+ return minEnd === Infinity ? void 0 : {
54
+ start: Math.min(minEnd, maxStart),
55
+ end: Math.max(minEnd, maxStart)
56
+ };
57
+ }
58
+ function nodeReferenceSpan({
59
+ nodeId,
60
+ nodeById,
61
+ neighbors
62
+ }) {
63
+ const node = nodeById.get(nodeId);
64
+ return node === void 0 ? void 0 : isBackbone(node) ? { start: node.stable.start, end: node.stable.start + node.length } : flankingSpan({ nodeId, nodeById, neighbors });
65
+ }
66
+ function referenceMidpoints(graph) {
67
+ const nodeById = new Map(graph.nodes.map((node) => [node.id, node]));
68
+ const neighbors = buildNeighbors(graph);
69
+ const midpoints = /* @__PURE__ */ new Map();
70
+ for (const node of graph.nodes) {
71
+ const span = nodeReferenceSpan({ nodeId: node.id, nodeById, neighbors });
72
+ if (span) {
73
+ midpoints.set(node.id, (span.start + span.end) / 2);
74
+ }
75
+ }
76
+ return midpoints;
77
+ }
78
+
79
+ export {
80
+ buildNeighbors,
81
+ nodeReferenceSpan,
82
+ referenceMidpoints
83
+ };
@@ -0,0 +1,54 @@
1
+ import {
2
+ walkRows
3
+ } from "./chunk-SZNZ2T6D.js";
4
+ import {
5
+ ROW_HEIGHT_PX
6
+ } from "./chunk-CPMHA4W5.js";
7
+ import {
8
+ backboneNodes,
9
+ backbonePositions,
10
+ overlapsWindow
11
+ } from "./chunk-FYQWPEEY.js";
12
+
13
+ // src/layout/walkRowLayout.ts
14
+ var READOUT_ROOM = 1.3;
15
+ function walkRowsExtent(walks) {
16
+ let longest = walks.reference.bp;
17
+ for (const row of walks.rows) {
18
+ longest = Math.max(longest, row.bp);
19
+ }
20
+ return {
21
+ maxX: walks.origin + longest * READOUT_ROOM,
22
+ maxY: walks.rows.length * ROW_HEIGHT_PX
23
+ };
24
+ }
25
+ function walkRowLayout(graph, region) {
26
+ const backbone = backboneNodes(graph);
27
+ const walks = walkRows(graph, region);
28
+ if (backbone.length === 0 || !walks) {
29
+ return void 0;
30
+ }
31
+ const overWindow = region ? backbone.filter((n) => overlapsWindow(n, region)) : backbone;
32
+ const nodePositions = backbonePositions(
33
+ overWindow.length > 0 ? overWindow : backbone
34
+ );
35
+ const rowLabels = [
36
+ { label: walks.reference.label, y: 0 },
37
+ ...walks.rows.map((row, i) => ({
38
+ label: row.label,
39
+ y: (i + 1) * ROW_HEIGHT_PX
40
+ }))
41
+ ];
42
+ return {
43
+ nodePositions,
44
+ rowLabels,
45
+ referenceAxis: true,
46
+ pixelRows: true,
47
+ extent: walkRowsExtent(walks)
48
+ };
49
+ }
50
+
51
+ export {
52
+ walkRowsExtent,
53
+ walkRowLayout
54
+ };
@@ -0,0 +1,65 @@
1
+ // src/anchoredNodes.ts
2
+ var REFERENCE_RANK = 0;
3
+ function isAnchored(node) {
4
+ return node.stable !== void 0;
5
+ }
6
+ function isBackbone(node) {
7
+ return node.stable?.rank === REFERENCE_RANK;
8
+ }
9
+ function isOffReference(node) {
10
+ return node.stable !== void 0 && node.stable.rank > REFERENCE_RANK;
11
+ }
12
+ function backboneNodes(graph) {
13
+ return graph.nodes.filter(isBackbone);
14
+ }
15
+ function overlapsWindow(node, window) {
16
+ return node.stable.start < window.end && node.stable.start + node.length > window.start;
17
+ }
18
+ function backbonePositions(backbone) {
19
+ const positions = {};
20
+ for (const node of backbone) {
21
+ positions[node.id] = [
22
+ { x: node.stable.start, y: 0 },
23
+ { x: node.stable.start + node.length, y: 0 }
24
+ ];
25
+ }
26
+ return positions;
27
+ }
28
+ function firstNodeAtOrAfter(nodes, bp) {
29
+ let lo = 0;
30
+ let hi = nodes.length;
31
+ while (lo < hi) {
32
+ const mid = lo + hi >> 1;
33
+ if (nodes[mid].stable.start < bp) {
34
+ lo = mid + 1;
35
+ } else {
36
+ hi = mid;
37
+ }
38
+ }
39
+ return lo;
40
+ }
41
+ function backboneSpan(backbone) {
42
+ let min = Infinity;
43
+ let max = -Infinity;
44
+ for (const node of backbone) {
45
+ min = Math.min(min, node.stable.start);
46
+ max = Math.max(max, node.stable.start + node.length);
47
+ }
48
+ return max - min;
49
+ }
50
+ function referenceSpan(backbone, region) {
51
+ return region && region.end > region.start ? region.end - region.start : backboneSpan(backbone);
52
+ }
53
+
54
+ export {
55
+ REFERENCE_RANK,
56
+ isAnchored,
57
+ isBackbone,
58
+ isOffReference,
59
+ backboneNodes,
60
+ overlapsWindow,
61
+ backbonePositions,
62
+ firstNodeAtOrAfter,
63
+ backboneSpan,
64
+ referenceSpan
65
+ };
@@ -0,0 +1,170 @@
1
+ import {
2
+ encodedColor,
3
+ resolveEncoding
4
+ } from "./chunk-WFX3MAKA.js";
5
+ import {
6
+ pathOrigin
7
+ } from "./chunk-ST2IBUAN.js";
8
+ import {
9
+ panSNContig
10
+ } from "./chunk-BPLIXMH7.js";
11
+
12
+ // src/walkHighlight.ts
13
+ var isReference = (graph, name) => !!graph.referencePath && pathOrigin(name).name === graph.referencePath;
14
+ function piecesOf(graph, name) {
15
+ return (graph.paths ?? []).filter((p) => p.name === name).sort((a, b) => (a.start ?? 0) - (b.start ?? 0));
16
+ }
17
+ function walkHighlight(graph, name) {
18
+ const pieces = piecesOf(graph, name);
19
+ const first = pieces[0];
20
+ if (!first) {
21
+ return void 0;
22
+ }
23
+ const byId = new Map(graph.nodes.map((n) => [n.id, n]));
24
+ const edgeAt = /* @__PURE__ */ new Map();
25
+ graph.edges.forEach((e, i) => {
26
+ edgeAt.set(`${e.from}>${e.to}`, i);
27
+ });
28
+ const lengthOf = (id) => byId.get(id)?.length ?? 0;
29
+ const bpOf = (path) => path.nodeIds.reduce((sum, id) => sum + lengthOf(id), 0);
30
+ const bp = pieces.reduce((sum, piece) => sum + bpOf(piece), 0);
31
+ const range = first.start === void 0 ? void 0 : {
32
+ contig: first.contig ?? panSNContig(pathOrigin(name).name),
33
+ start: first.start,
34
+ end: Math.max(...pieces.map((p) => (p.start ?? 0) + bpOf(p)))
35
+ };
36
+ const span = range ? range.end - range.start : bp;
37
+ const nodeIds = /* @__PURE__ */ new Set();
38
+ const edgeIndexes = /* @__PURE__ */ new Set();
39
+ const progress = /* @__PURE__ */ new Map();
40
+ let before = 0;
41
+ for (const piece of pieces) {
42
+ if (range) {
43
+ before = Math.max(before, (piece.start ?? 0) - range.start);
44
+ }
45
+ piece.nodeIds.forEach((id, i) => {
46
+ nodeIds.add(id);
47
+ if (i > 0) {
48
+ const a = piece.nodeIds[i - 1];
49
+ const index = edgeAt.get(`${a}>${id}`) ?? edgeAt.get(`${id}>${a}`);
50
+ if (index !== void 0) {
51
+ edgeIndexes.add(index);
52
+ }
53
+ }
54
+ const length = lengthOf(id);
55
+ if (!progress.has(id)) {
56
+ progress.set(id, span > 0 ? (before + length / 2) / span : 0);
57
+ }
58
+ before += length;
59
+ });
60
+ }
61
+ const reference = isReference(graph, name);
62
+ const referencePieces = reference ? [] : (graph.paths ?? []).filter((p) => isReference(graph, p.name));
63
+ return {
64
+ name,
65
+ reference,
66
+ range,
67
+ nodeIds,
68
+ edgeIndexes,
69
+ progress,
70
+ steps: pieces.reduce((sum, piece) => sum + piece.nodeIds.length, 0),
71
+ bp,
72
+ referenceBp: referencePieces.length > 0 ? referencePieces.reduce((sum, piece) => sum + bpOf(piece), 0) : void 0
73
+ };
74
+ }
75
+ function laneColors(graph, walk, encoding, ramp) {
76
+ const byId = new Map(graph.nodes.map((n) => [n.id, n]));
77
+ const colors = /* @__PURE__ */ new Map();
78
+ for (const [id, progress] of walk.progress) {
79
+ const node = byId.get(id);
80
+ const mid = ramp?.midpoints.get(id);
81
+ const t = encoding.field === "progress" ? progress : ramp && mid !== void 0 && !(node?.stable && node.stable.rank > 0) ? (mid - ramp.start) / ramp.span : void 0;
82
+ colors.set(id, encodedColor(encoding, t));
83
+ }
84
+ return colors;
85
+ }
86
+ function reversedNodes(graph, walk) {
87
+ const reversed = /* @__PURE__ */ new Set();
88
+ let bp = 0;
89
+ const referencePath = graph.referencePath;
90
+ if (!referencePath || walk.reference) {
91
+ return { reversed, bp };
92
+ }
93
+ const walkPath = pathOrigin(walk.name).name;
94
+ const byId = new Map(graph.nodes.map((n) => [n.id, n]));
95
+ for (const id of walk.progress.keys()) {
96
+ const node = byId.get(id);
97
+ const visits = node ? graph.pathVisits?.get(node.name) : void 0;
98
+ const own = visits?.find((v) => v.path === walkPath)?.strand;
99
+ const theirs = visits?.find((v) => v.path === referencePath)?.strand;
100
+ if (own && theirs && own !== theirs) {
101
+ reversed.add(id);
102
+ bp += node.length;
103
+ }
104
+ }
105
+ return { reversed, bp };
106
+ }
107
+ function walkLift(graph, layers, ramp) {
108
+ const seen = /* @__PURE__ */ new Set();
109
+ const lifted = layers.filter((layer) => !seen.has(layer.walk) && seen.add(layer.walk)).flatMap((layer) => {
110
+ const walk = walkHighlight(graph, layer.walk);
111
+ return walk ? [{ walk, layer }] : [];
112
+ }).sort((a, b) => Number(b.walk.reference) - Number(a.walk.reference));
113
+ if (lifted.length === 0) {
114
+ return void 0;
115
+ }
116
+ let picked = 0;
117
+ const walks = lifted.map(({ walk, layer }) => {
118
+ const encoding = resolveEncoding(
119
+ layer,
120
+ walk.reference,
121
+ walk.reference ? 0 : picked++,
122
+ lifted.length === 1
123
+ );
124
+ const { reversed, bp } = reversedNodes(graph, walk);
125
+ return {
126
+ ...walk,
127
+ encoding,
128
+ colors: laneColors(graph, walk, encoding, ramp),
129
+ reversed,
130
+ reversedBp: bp
131
+ };
132
+ });
133
+ return liftOf(walks, ramp);
134
+ }
135
+ var FACET_COLOR = { field: "progress", scheme: "red" };
136
+ function facetLifts(graph, lift, layers, ramp) {
137
+ return lift.walks.map((walk) => {
138
+ const stated = layers.find((l) => l.walk === walk.name)?.color;
139
+ const encoding = resolveEncoding(
140
+ { walk: walk.name, color: { ...FACET_COLOR, ...stated } },
141
+ walk.reference,
142
+ 0
143
+ );
144
+ return liftOf(
145
+ [
146
+ {
147
+ ...walk,
148
+ encoding,
149
+ colors: laneColors(graph, walk, encoding, ramp)
150
+ }
151
+ ],
152
+ ramp
153
+ );
154
+ });
155
+ }
156
+ function liftOf(walks, ramp) {
157
+ return {
158
+ walks,
159
+ referenceDomain: ramp ? { start: ramp.start, end: ramp.start + ramp.span } : void 0,
160
+ nodeIds: new Set(walks.flatMap((w) => [...w.nodeIds])),
161
+ edgeIndexes: new Set(walks.flatMap((w) => [...w.edgeIndexes])),
162
+ names: new Set(walks.map((w) => w.name))
163
+ };
164
+ }
165
+
166
+ export {
167
+ walkHighlight,
168
+ walkLift,
169
+ facetLifts
170
+ };
@@ -0,0 +1,43 @@
1
+ import {
2
+ formatBp,
3
+ groupDigits
4
+ } from "./chunk-N62KBLFC.js";
5
+
6
+ // src/walkKey.ts
7
+ function rangeText(contig, start, end) {
8
+ const s = Math.round(start);
9
+ const e = Math.round(end);
10
+ return `${contig ? `${contig}:` : ""}${groupDigits(s)}-${groupDigits(e)} (${formatBp(e - s)})`;
11
+ }
12
+ function walkKey(walk, reference) {
13
+ const { field } = walk.encoding;
14
+ const own = walk.range ? rangeText(walk.range.contig, walk.range.start, walk.range.end) : void 0;
15
+ const scale = field === "progress" ? own : field === "reference" && reference ? rangeText(reference.name, reference.start, reference.end) : void 0;
16
+ const spanned = walk.range ? walk.range.end - walk.range.start : walk.bp;
17
+ const outside = spanned - walk.bp;
18
+ return {
19
+ delta: walk.referenceBp === void 0 || spanned === walk.referenceBp ? "" : ` ${spanned > walk.referenceBp ? "+" : "\u2212"}${formatBp(Math.abs(spanned - walk.referenceBp))}`,
20
+ outside: outside > 0 ? `, ${formatBp(outside)} outside the cut` : "",
21
+ reversed: walk.reversedBp > 0 ? `, ${formatBp(walk.reversedBp)} reversed` : "",
22
+ shades: field !== "walk",
23
+ scale,
24
+ hover: scale === own ? void 0 : own
25
+ };
26
+ }
27
+ function walkPosition(walk, nodeId, length) {
28
+ const progress = walk.progress.get(nodeId);
29
+ const range = walk.range;
30
+ if (progress === void 0 || !range) {
31
+ return void 0;
32
+ }
33
+ const start = Math.round(
34
+ range.start + progress * (range.end - range.start) - length / 2
35
+ );
36
+ return `${range.contig}:${groupDigits(start)}-${groupDigits(start + length)}`;
37
+ }
38
+
39
+ export {
40
+ rangeText,
41
+ walkKey,
42
+ walkPosition
43
+ };
@@ -0,0 +1,112 @@
1
+ import {
2
+ isBackbone
3
+ } from "./chunk-FYQWPEEY.js";
4
+
5
+ // src/tubeMap/connectors.ts
6
+ function referenceNodes(graph, layout) {
7
+ const nodeById = new Map(graph.nodes.map((n) => [n.id, n]));
8
+ const out = [];
9
+ layout.nodes.forEach((node) => {
10
+ const graphNode = nodeById.get(node.name);
11
+ if (node.order >= 0 && graphNode && isBackbone(graphNode)) {
12
+ out.push({
13
+ node: node.name,
14
+ bp0: graphNode.stable.start,
15
+ bp1: graphNode.stable.start + node.sequenceLength,
16
+ x0: node.x,
17
+ x1: node.x + node.pixelWidth
18
+ });
19
+ }
20
+ });
21
+ return out;
22
+ }
23
+ function tubeMapConnectors(nodes, bpToScreen, tubeToScreen, width) {
24
+ const out = [];
25
+ for (const n of nodes) {
26
+ const bottom0 = tubeToScreen(n.x0);
27
+ const bottom1 = tubeToScreen(n.x1);
28
+ if (bottom1 >= 0 && bottom0 <= width) {
29
+ out.push({
30
+ node: n.node,
31
+ top0: bpToScreen(n.bp0),
32
+ top1: bpToScreen(n.bp1),
33
+ bottom0,
34
+ bottom1
35
+ });
36
+ }
37
+ }
38
+ return out;
39
+ }
40
+ var HIT_SLOP_PX = 3;
41
+ function connectorAt(connectors, zoneBottom, sx, sy) {
42
+ if (zoneBottom <= 0 || sy < 0 || sy > zoneBottom) {
43
+ return void 0;
44
+ }
45
+ const t = sy / zoneBottom;
46
+ let hit;
47
+ let best = HIT_SLOP_PX;
48
+ for (const c of connectors) {
49
+ const a = c.top0 + (c.bottom0 - c.top0) * t;
50
+ const b = c.top1 + (c.bottom1 - c.top1) * t;
51
+ const dist = Math.max(0, Math.min(a, b) - sx, sx - Math.max(a, b));
52
+ if (dist < best) {
53
+ best = dist;
54
+ hit = c.node;
55
+ }
56
+ }
57
+ return hit;
58
+ }
59
+ function band(ctx, c, bottom) {
60
+ ctx.moveTo(c.top0, 0);
61
+ ctx.lineTo(c.top1, 0);
62
+ ctx.lineTo(c.bottom1, bottom);
63
+ ctx.lineTo(c.bottom0, bottom);
64
+ ctx.closePath();
65
+ }
66
+ function sides(ctx, c, bottom) {
67
+ ctx.moveTo(c.top0, 0);
68
+ ctx.lineTo(c.bottom0, bottom);
69
+ ctx.moveTo(c.top1, 0);
70
+ ctx.lineTo(c.bottom1, bottom);
71
+ }
72
+ function drawTubeMapConnectors(ctx, connectors, bottom, {
73
+ highlightNode,
74
+ darkMode
75
+ }) {
76
+ if (bottom <= 0 || connectors.length === 0) {
77
+ return;
78
+ }
79
+ const ink = darkMode ? "255,255,255" : "0,0,0";
80
+ ctx.beginPath();
81
+ for (const c of connectors) {
82
+ band(ctx, c, bottom);
83
+ }
84
+ ctx.fillStyle = `rgba(${ink},0.07)`;
85
+ ctx.fill();
86
+ ctx.beginPath();
87
+ for (const c of connectors) {
88
+ sides(ctx, c, bottom);
89
+ }
90
+ ctx.strokeStyle = `rgba(${ink},0.35)`;
91
+ ctx.lineWidth = 0.5;
92
+ ctx.stroke();
93
+ const lit = connectors.find((c) => c.node === highlightNode);
94
+ if (lit) {
95
+ ctx.beginPath();
96
+ band(ctx, lit, bottom);
97
+ ctx.fillStyle = "rgba(255,192,203,0.5)";
98
+ ctx.fill();
99
+ ctx.beginPath();
100
+ sides(ctx, lit, bottom);
101
+ ctx.strokeStyle = "#ff0000";
102
+ ctx.lineWidth = 1;
103
+ ctx.stroke();
104
+ }
105
+ }
106
+
107
+ export {
108
+ referenceNodes,
109
+ tubeMapConnectors,
110
+ connectorAt,
111
+ drawTubeMapConnectors
112
+ };