@jbrowse/bandage-core 10.2.6 → 10.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (191) hide show
  1. package/dist/alleleProjection/projectAlleles.js +8 -4
  2. package/dist/anchoredNodes.js +2 -1
  3. package/dist/bubbleSpreads.js +2 -2
  4. package/dist/bubbles/bubbleHalos.js +10 -11
  5. package/dist/bubbles/bubblesFromGraph.js +8 -3
  6. package/dist/bubbles/classifyBubble.js +9 -6
  7. package/dist/bubbles/popBubble.js +7 -5
  8. package/dist/bubbles/superbubbles.js +18 -14
  9. package/dist/chunks/{chunk-RAKOB6IV.js → chunk-234NFZS4.js} +8 -6
  10. package/dist/chunks/{chunk-A4PFFC4Q.js → chunk-2XEQR54X.js} +60 -102
  11. package/dist/chunks/{chunk-6JEWNXCQ.js → chunk-34BOZKIE.js} +0 -2
  12. package/dist/chunks/{chunk-RVS2QCOX.js → chunk-3GLG3ZLE.js} +2 -11
  13. package/dist/chunks/{chunk-PUG7LXDF.js → chunk-3PZSBNLI.js} +4 -1
  14. package/dist/chunks/{chunk-KBEP7VYK.js → chunk-3VCKBSML.js} +4 -4
  15. package/dist/chunks/{chunk-BPLIXMH7.js → chunk-4XWZNPQ2.js} +14 -0
  16. package/dist/chunks/{chunk-LKW2TP4N.js → chunk-5YILQTHE.js} +18 -16
  17. package/dist/chunks/{chunk-B6IW3IRE.js → chunk-65ILXEIN.js} +14 -15
  18. package/dist/chunks/{chunk-4DRQTBBE.js → chunk-6EOB6ANX.js} +1 -1
  19. package/dist/chunks/{chunk-XBHMXTOR.js → chunk-7JGLJK44.js} +41 -36
  20. package/dist/chunks/{chunk-T2PCSAFY.js → chunk-7XR26JST.js} +2 -2
  21. package/dist/chunks/{chunk-URZ3CH2R.js → chunk-A4JDEUAI.js} +1 -1
  22. package/dist/chunks/{chunk-JLSJMCDJ.js → chunk-A54O52XZ.js} +3 -3
  23. package/dist/chunks/chunk-A55OZVYX.js +327 -0
  24. package/dist/chunks/{chunk-CWFNEKST.js → chunk-A7H753BA.js} +3 -3
  25. package/dist/chunks/{chunk-FB5RKZQY.js → chunk-AMX4OQAW.js} +18 -27
  26. package/dist/chunks/{chunk-RPRHR56C.js → chunk-BS6HPYCZ.js} +3 -3
  27. package/dist/chunks/chunk-BSOZW3FC.js +30 -0
  28. package/dist/chunks/{chunk-CU6P5RUG.js → chunk-BVYR7IFN.js} +22 -16
  29. package/dist/chunks/{chunk-XXT2JCAC.js → chunk-BX4AUMZE.js} +11 -13
  30. package/dist/chunks/{chunk-N73TI3VG.js → chunk-BZFOFC4D.js} +6 -9
  31. package/dist/chunks/{chunk-4ETPXDO6.js → chunk-CGFPFBT2.js} +1 -1
  32. package/dist/chunks/{chunk-24WITXQY.js → chunk-CGMSKIEO.js} +9 -25
  33. package/dist/chunks/{chunk-IGVV37VI.js → chunk-CKUVEHSS.js} +3 -3
  34. package/dist/chunks/{chunk-JBCZIBFC.js → chunk-CRCD3ODN.js} +0 -1
  35. package/dist/chunks/{chunk-PSMKPSO4.js → chunk-DBLV7PGG.js} +33 -27
  36. package/dist/chunks/{chunk-JA2HJIYS.js → chunk-E4ZM4OOJ.js} +3 -5
  37. package/dist/chunks/{chunk-ABUIN5AK.js → chunk-EHXBZ5JZ.js} +29 -24
  38. package/dist/chunks/{chunk-QLWI2PZ3.js → chunk-EJRJAAN7.js} +24 -21
  39. package/dist/chunks/{chunk-Q7LYHGGQ.js → chunk-GIHTHYXY.js} +5 -4
  40. package/dist/chunks/{chunk-L3O7AWLI.js → chunk-GJLZ2MKE.js} +2 -2
  41. package/dist/chunks/{chunk-LOEA5IHZ.js → chunk-GJU6BJJA.js} +8 -8
  42. package/dist/chunks/{chunk-XL472HHD.js → chunk-GQZVR5DW.js} +12 -7
  43. package/dist/chunks/{chunk-UVBGRJQX.js → chunk-HKYXWZQS.js} +1 -1
  44. package/dist/chunks/chunk-HMXCN6PG.js +17 -0
  45. package/dist/chunks/{chunk-WSIFAZU7.js → chunk-HNWJ4B7S.js} +12 -13
  46. package/dist/chunks/chunk-HOAIOEI7.js +18 -0
  47. package/dist/chunks/{chunk-XMW266WS.js → chunk-HSVFCA2J.js} +18 -20
  48. package/dist/chunks/{chunk-3XSM4OZU.js → chunk-IYALCKNB.js} +5 -5
  49. package/dist/chunks/{chunk-2QLLQJ72.js → chunk-KWHWNOTY.js} +22 -17
  50. package/dist/chunks/{chunk-M6LK4GII.js → chunk-LGJBB5BP.js} +8 -9
  51. package/dist/chunks/{chunk-VQWHMWLF.js → chunk-M5NPD55W.js} +18 -14
  52. package/dist/chunks/{chunk-TKIJ5535.js → chunk-MD5VPXXT.js} +6 -6
  53. package/dist/chunks/{chunk-HK5Y2YWV.js → chunk-MYDHU2UV.js} +6 -11
  54. package/dist/chunks/{chunk-TZFWUT2C.js → chunk-MYLAJDKB.js} +2 -2
  55. package/dist/chunks/{chunk-4HWM3FNK.js → chunk-OMUPUB4J.js} +39 -56
  56. package/dist/chunks/{chunk-PTABFYQ7.js → chunk-PFRQBCGC.js} +49 -60
  57. package/dist/chunks/{chunk-T6V4KI2L.js → chunk-PPDE4IVT.js} +1 -1
  58. package/dist/chunks/{chunk-KC7T5RWG.js → chunk-PSCSZSVK.js} +9 -16
  59. package/dist/chunks/{chunk-YYMW5XOF.js → chunk-PTQPTDZH.js} +1 -1
  60. package/dist/chunks/{chunk-L2HDM2R3.js → chunk-QQCOVMMT.js} +7 -7
  61. package/dist/chunks/{chunk-CQHUZHET.js → chunk-RFG42VIO.js} +46 -30
  62. package/dist/chunks/{chunk-FYQWPEEY.js → chunk-RJWPJCIB.js} +5 -11
  63. package/dist/chunks/{chunk-AR4BUBMU.js → chunk-RWKP7UO4.js} +34 -35
  64. package/dist/chunks/{chunk-WBSWROE6.js → chunk-SHKGYGM4.js} +14 -18
  65. package/dist/chunks/{chunk-2CMYNW3E.js → chunk-SI3BB4DO.js} +1 -1
  66. package/dist/chunks/{chunk-DY3JCAMX.js → chunk-SOMZGDVS.js} +7 -16
  67. package/dist/chunks/{chunk-EFQLEGWM.js → chunk-SZHQK6GL.js} +7 -8
  68. package/dist/chunks/{chunk-5GMFEPWR.js → chunk-TCOLHD7N.js} +16 -28
  69. package/dist/chunks/{chunk-XV4P5KEQ.js → chunk-TGUFT6KK.js} +6 -3
  70. package/dist/chunks/{chunk-CM6LO6OC.js → chunk-UAFATXYA.js} +10 -14
  71. package/dist/chunks/{chunk-7SRWJLSC.js → chunk-UBQSRCWR.js} +11 -8
  72. package/dist/chunks/{chunk-RUCH6ZFL.js → chunk-V4YML3GR.js} +2 -1
  73. package/dist/chunks/{chunk-VQC7KELB.js → chunk-V7J6U4XC.js} +11 -3
  74. package/dist/chunks/{chunk-ES2N6V56.js → chunk-VX656OAZ.js} +6 -11
  75. package/dist/chunks/chunk-WA5WNP6V.js +37 -0
  76. package/dist/chunks/{chunk-WZNPX7Q6.js → chunk-WJ4TIAVA.js} +1 -1
  77. package/dist/chunks/{chunk-BS4UZ44I.js → chunk-WONB6LMC.js} +1 -1
  78. package/dist/chunks/{chunk-HFVGGB3U.js → chunk-XUT4HXVE.js} +29 -13
  79. package/dist/chunks/{chunk-G45YY72K.js → chunk-Z6XZWPXK.js} +17 -25
  80. package/dist/chunks/{chunk-XI3ZUTWF.js → chunk-ZNJ4JAPT.js} +14 -20
  81. package/dist/chunks/{chunk-HNCXR2VS.js → chunk-ZPBEUOBM.js} +3 -1
  82. package/dist/chunks/{chunk-RAEABQNW.js → chunk-ZPZ7GNBT.js} +1 -0
  83. package/dist/cli/figure.js +59 -56
  84. package/dist/cli/fold.js +19 -17
  85. package/dist/deletionEdges.js +5 -7
  86. package/dist/facetGrid.js +2 -1
  87. package/dist/figure.js +45 -42
  88. package/dist/figureData.js +48 -44
  89. package/dist/figureScene.js +34 -29
  90. package/dist/figureSettings.js +19 -17
  91. package/dist/foldVariants.js +5 -3
  92. package/dist/gbzCut.js +12 -7
  93. package/dist/gbzJoin.js +2 -1
  94. package/dist/gbzWindow.js +11 -6
  95. package/dist/genes/genePins.js +6 -4
  96. package/dist/gfa/gfaConverter.js +7 -5
  97. package/dist/gfa/gfaTables.js +2 -1
  98. package/dist/gfa/graphTables.js +3 -3
  99. package/dist/graphLabels.js +8 -5
  100. package/dist/index.js +88 -85
  101. package/dist/labelLayout.js +12 -9
  102. package/dist/layout/anchoredLayout.js +8 -5
  103. package/dist/layout/drawnScale.js +1 -5
  104. package/dist/layout/forceCache.js +19 -17
  105. package/dist/layout/mergeRuns.js +5 -3
  106. package/dist/layout/orderedLayout.js +5 -2
  107. package/dist/layout/orientToReference.js +3 -2
  108. package/dist/layout/placeOffReference.js +7 -4
  109. package/dist/layout/referenceSeeds.js +6 -4
  110. package/dist/layout/sampleRowLayout.js +8 -5
  111. package/dist/layout/trimToWindow.js +6 -4
  112. package/dist/layout/tubeMapLayout.js +17 -19
  113. package/dist/layout/walkRowDraw.js +18 -17
  114. package/dist/layout/walkRowLayout.js +10 -6
  115. package/dist/layout/walkRows.js +9 -5
  116. package/dist/layout/walkStrip.js +21 -18
  117. package/dist/layoutModes.js +23 -20
  118. package/dist/nodeWidths.js +1 -3
  119. package/dist/pansn.js +5 -1
  120. package/dist/pathAnchoring.js +6 -4
  121. package/dist/pathColors.js +12 -9
  122. package/dist/pathVisits.js +3 -1
  123. package/dist/pipeline.js +18 -16
  124. package/dist/reference.js +5 -3
  125. package/dist/referenceRampCss.js +9 -17
  126. package/dist/referenceSpan.js +4 -2
  127. package/dist/referenceStrip.js +18 -14
  128. package/dist/renderer/Canvas2DRenderer.js +1 -1
  129. package/dist/renderer/GeometryBuilder.js +19 -14
  130. package/dist/renderer/svgCanvas.js +1 -1
  131. package/dist/tubeMap/axis.js +11 -6
  132. package/dist/tubeMap/bundle.js +16 -12
  133. package/dist/tubeMap/coarsen.js +20 -345
  134. package/dist/tubeMap/deviations.js +53 -23
  135. package/dist/tubeMap/draw.js +11 -8
  136. package/dist/tubeMap/frame.js +3 -2
  137. package/dist/tubeMap/genes.js +10 -7
  138. package/dist/tubeMap/mismatches.js +1 -1
  139. package/dist/tubeMap/nodeColors.js +18 -14
  140. package/dist/tubeMap/reads.js +1 -1
  141. package/dist/tubeMap/warp.js +2 -1
  142. package/dist/types/alleleProjection/projectAlleles.d.ts +1 -4
  143. package/dist/types/bubbles/bubbleHalos.d.ts +0 -2
  144. package/dist/types/bubbles/bubblesFromGraph.d.ts +6 -4
  145. package/dist/types/bubbles/classifyBubble.d.ts +2 -1
  146. package/dist/types/deletionEdges.d.ts +0 -8
  147. package/dist/types/figureScene.d.ts +17 -7
  148. package/dist/types/figureSettings.d.ts +2 -0
  149. package/dist/types/gbzCut.d.ts +4 -0
  150. package/dist/types/gbzWindow.d.ts +1 -0
  151. package/dist/types/gfa/graphTables.d.ts +3 -1
  152. package/dist/types/gfa-core/gfaParser.d.ts +1 -1
  153. package/dist/types/graphLabels.d.ts +2 -1
  154. package/dist/types/layout/drawnScale.d.ts +0 -2
  155. package/dist/types/layout/referenceSeeds.d.ts +2 -1
  156. package/dist/types/layout/tubeMapLayout.d.ts +0 -7
  157. package/dist/types/layout/walkRowDraw.d.ts +0 -1
  158. package/dist/types/layout/walkRowLayout.d.ts +1 -0
  159. package/dist/types/layout/walkRows.d.ts +1 -0
  160. package/dist/types/nodeWidths.d.ts +0 -1
  161. package/dist/types/pansn.d.ts +9 -0
  162. package/dist/types/pathVisits.d.ts +6 -0
  163. package/dist/types/referenceRampCss.d.ts +4 -0
  164. package/dist/types/renderer/Canvas2DRenderer.d.ts +1 -0
  165. package/dist/types/renderer/GeometryBuilder.d.ts +3 -2
  166. package/dist/types/tubeMap/axis.d.ts +3 -1
  167. package/dist/types/tubeMap/coarsen.d.ts +3 -1
  168. package/dist/types/tubeMap/deviations.d.ts +2 -1
  169. package/dist/types/tubeMap/mismatches.d.ts +0 -1
  170. package/dist/types/tubeMap/warp.d.ts +2 -1
  171. package/dist/types/util/SpatialIndex.d.ts +1 -1
  172. package/dist/types/util/geometry.d.ts +4 -0
  173. package/dist/types/util/groups.d.ts +3 -0
  174. package/dist/types/util/hitDetection.d.ts +2 -2
  175. package/dist/types/util/partitionPoint.d.ts +1 -0
  176. package/dist/types/util/weakMemo.d.ts +1 -0
  177. package/dist/types/version.d.ts +1 -1
  178. package/dist/util/SpatialIndex.js +8 -5
  179. package/dist/util/edgeCurves.js +7 -4
  180. package/dist/util/geometry.js +3 -1
  181. package/dist/util/groups.js +10 -0
  182. package/dist/util/hitDetection.js +9 -6
  183. package/dist/util/partitionPoint.js +6 -0
  184. package/dist/util/weakMemo.js +6 -0
  185. package/dist/version.js +1 -1
  186. package/dist/viewport.js +19 -17
  187. package/dist/walkEncoding.js +18 -14
  188. package/dist/walkHighlight.js +19 -15
  189. package/dist/walkKey.js +9 -6
  190. package/package.json +2 -2
  191. package/dist/chunks/chunk-ZY2AFL4Y.js +0 -43
@@ -1,3 +1,7 @@
1
+ import {
2
+ partitionPoint
3
+ } from "./chunk-HOAIOEI7.js";
4
+
1
5
  // src/anchoredNodes.ts
2
6
  var REFERENCE_RANK = 0;
3
7
  function isAnchored(node) {
@@ -26,17 +30,7 @@ function backbonePositions(backbone) {
26
30
  return positions;
27
31
  }
28
32
  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;
33
+ return partitionPoint(nodes.length, (i) => nodes[i].stable.start < bp);
40
34
  }
41
35
  function backboneSpan(backbone) {
42
36
  let min = Infinity;
@@ -4,10 +4,10 @@ import {
4
4
  import {
5
5
  pathOrigin,
6
6
  surveyPaths
7
- } from "./chunk-M6LK4GII.js";
7
+ } from "./chunk-LGJBB5BP.js";
8
8
 
9
9
  // src/gfa/gfaConverter.ts
10
- function surveySegments(gfaGraph) {
10
+ function surveySegments(gfaGraph, pathSteps) {
11
11
  const canonical = /* @__PURE__ */ new Map();
12
12
  const traversals = /* @__PURE__ */ new Map();
13
13
  function claim(id, strand) {
@@ -26,36 +26,35 @@ function surveySegments(gfaGraph) {
26
26
  claim(link.source, link.strand1 === "-" ? "-" : "+");
27
27
  claim(link.target, link.strand2 === "-" ? "-" : "+");
28
28
  }
29
- for (const gfaPath of gfaGraph.paths) {
30
- for (const segment of gfaPath.path.split(",")) {
31
- traverse(segment.slice(0, -1), segment.endsWith("-") ? "-" : "+");
29
+ for (const { steps } of pathSteps) {
30
+ for (const step of steps) {
31
+ traverse(step.id, step.strand);
32
32
  }
33
33
  }
34
34
  for (const walk of gfaGraph.walks) {
35
- for (const seg of walk.segments) {
36
- traverse(seg.id, seg.strand === "-" ? "-" : "+");
35
+ for (const step of walk.segments) {
36
+ traverse(step.id, step.strand);
37
37
  }
38
38
  }
39
39
  return { canonical, traversals };
40
40
  }
41
41
  var walkStart = (w) => w.start === -1 ? 0 : w.start;
42
- var stranded = (s) => s.strand === "+" || s.strand === "-";
43
- function anchorablePaths(gfaGraph) {
42
+ function stepsOfPath(p) {
43
+ return {
44
+ ...pathOrigin(p.name),
45
+ steps: p.path.split(",").map((segment) => ({
46
+ id: segment.slice(0, -1),
47
+ strand: segment.endsWith("-") ? "-" : "+"
48
+ }))
49
+ };
50
+ }
51
+ function anchorablePaths(gfaGraph, pathSteps) {
44
52
  return [
45
- ...gfaGraph.paths.map((p) => ({
46
- ...pathOrigin(p.name),
47
- steps: p.path.split(",").map((segment) => ({
48
- id: segment.slice(0, -1),
49
- strand: segment.endsWith("-") ? "-" : "+"
50
- }))
51
- })),
53
+ ...pathSteps,
52
54
  ...gfaGraph.walks.map((w) => ({
53
55
  name: `${w.sample}#${w.haplotype}#${w.contig}`,
54
56
  start: walkStart(w),
55
- steps: w.segments.every(stranded) ? w.segments : w.segments.map((s) => ({
56
- id: s.id,
57
- strand: s.strand === "-" ? "-" : "+"
58
- }))
57
+ steps: w.segments
59
58
  }))
60
59
  ];
61
60
  }
@@ -85,7 +84,8 @@ function makeNode(gfaNode, strand, depth) {
85
84
  function convertGFAToGraph(gfaGraph, name = "Imported GFA") {
86
85
  const nodes = [];
87
86
  const edges = [];
88
- const { canonical, traversals } = surveySegments(gfaGraph);
87
+ const pathSteps = gfaGraph.paths.map(stepsOfPath);
88
+ const { canonical, traversals } = surveySegments(gfaGraph, pathSteps);
89
89
  const nodeIds = /* @__PURE__ */ new Map();
90
90
  const nodeId = (segmentId) => {
91
91
  let id = nodeIds.get(segmentId);
@@ -95,12 +95,12 @@ function convertGFAToGraph(gfaGraph, name = "Imported GFA") {
95
95
  }
96
96
  return id;
97
97
  };
98
- const declared = /* @__PURE__ */ new Set();
98
+ const lengths = /* @__PURE__ */ new Map();
99
99
  for (const gfaNode of gfaGraph.nodes) {
100
- if (declared.has(gfaNode.id)) {
100
+ if (lengths.has(gfaNode.id)) {
101
101
  continue;
102
102
  }
103
- declared.add(gfaNode.id);
103
+ lengths.set(gfaNode.id, gfaNode.length);
104
104
  const depth = statedDepth(gfaNode) ?? Math.max(traversals.get(gfaNode.id) ?? 1, 1);
105
105
  nodes.push(makeNode(gfaNode, canonical.get(gfaNode.id) ?? "+", depth));
106
106
  }
@@ -137,15 +137,12 @@ function convertGFAToGraph(gfaGraph, name = "Imported GFA") {
137
137
  pairPaths(nodeIds2[i], nodeIds2[i + 1])?.add(name2);
138
138
  }
139
139
  }
140
- for (const gfaPath of gfaGraph.paths) {
141
- const nodeIds2 = gfaPath.path.split(",").map((segment) => nodeId(segment.slice(0, -1)));
142
- paths.push({
143
- name: gfaPath.name,
144
- nodeIds: nodeIds2,
145
- start: pathOrigin(gfaPath.name).start
146
- });
147
- recordPathEdges(nodeIds2, gfaPath.name);
148
- }
140
+ gfaGraph.paths.forEach(({ name: name2 }, i) => {
141
+ const { start, steps } = pathSteps[i];
142
+ const nodeIds2 = steps.map((step) => nodeId(step.id));
143
+ paths.push({ name: name2, nodeIds: nodeIds2, start });
144
+ recordPathEdges(nodeIds2, name2);
145
+ });
149
146
  for (const walk of gfaGraph.walks) {
150
147
  const nodeIds2 = walk.segments.map((seg) => nodeId(seg.id));
151
148
  const name2 = `${walk.sample}#${walk.haplotype}#${walk.contig}`;
@@ -165,8 +162,10 @@ function convertGFAToGraph(gfaGraph, name = "Imported GFA") {
165
162
  edge.pathIds = [...pathIds];
166
163
  }
167
164
  });
168
- const lengths = new Map(gfaGraph.nodes.map((n) => [n.id, n.length]));
169
- const anchoring = gfaGraph.paths.length > 0 || gfaGraph.walks.length > 0 ? surveyPaths(anchorablePaths(gfaGraph), (id) => lengths.get(id) ?? 0) : void 0;
165
+ const anchoring = gfaGraph.paths.length > 0 || gfaGraph.walks.length > 0 ? surveyPaths(
166
+ anchorablePaths(gfaGraph, pathSteps),
167
+ (id) => lengths.get(id) ?? 0
168
+ ) : void 0;
170
169
  return {
171
170
  name,
172
171
  nodes,
@@ -1,20 +1,25 @@
1
1
  import {
2
2
  alongRow,
3
3
  boxesGenes,
4
- rowPitch
5
- } from "./chunk-EFQLEGWM.js";
4
+ rowPitch,
5
+ rowSpan
6
+ } from "./chunk-SZHQK6GL.js";
6
7
  import {
7
8
  el
8
9
  } from "./chunk-H2H4Y3TV.js";
9
10
  import {
10
- READOUT_ROOM
11
- } from "./chunk-L2HDM2R3.js";
11
+ READOUT_ROOM,
12
+ longestBar
13
+ } from "./chunk-QQCOVMMT.js";
12
14
  import {
13
15
  pathOrigin
14
- } from "./chunk-M6LK4GII.js";
16
+ } from "./chunk-LGJBB5BP.js";
15
17
  import {
16
18
  LABEL_CHAR_PX
17
19
  } from "./chunk-AB35TJST.js";
20
+ import {
21
+ partitionPoint
22
+ } from "./chunk-HOAIOEI7.js";
18
23
 
19
24
  // src/layout/walkStrip.ts
20
25
  function walkStripApplies(o) {
@@ -63,7 +68,7 @@ function spansOf(graph, name) {
63
68
  const lengthOf = new Map(graph.nodes.map((n) => [n.id, n.length]));
64
69
  const origin = pathOrigin(name).name;
65
70
  const pieces = (graph.paths ?? []).filter(
66
- (p) => origin === graph.referencePath ? pathOrigin(p.name).name === origin : p.name === name
71
+ (p) => pathOrigin(p.name).name === origin
67
72
  );
68
73
  let spans;
69
74
  if (pieces.every((p) => p.start !== void 0)) {
@@ -90,19 +95,10 @@ function segmentAt(graph, row, offset, pxPerBp) {
90
95
  }
91
96
  const at = axis.reversed ? axis.start - offset : axis.start + offset;
92
97
  const tol = 0.5 / pxPerBp;
93
- const bar = axis.reversed ? { start: axis.start - row.bp, end: axis.start } : { start: axis.start, end: axis.start + row.bp };
98
+ const bar = rowSpan(axis, row.bp);
94
99
  const from = Math.max(at - tol, bar.start);
95
100
  const to = Math.min(at + tol, bar.end);
96
- let lo = 0;
97
- let hi = spans.starts.length;
98
- while (lo < hi) {
99
- const mid = lo + hi >> 1;
100
- if (spans.ends[mid] <= from) {
101
- lo = mid + 1;
102
- } else {
103
- hi = mid;
104
- }
105
- }
101
+ const lo = partitionPoint(spans.starts.length, (i) => spans.ends[i] <= from);
106
102
  let best;
107
103
  let bestLen = -1;
108
104
  let bestHolds = false;
@@ -126,7 +122,7 @@ function walkStripFrame(bars, o) {
126
122
  maxHeight - 2 * PAD_PX,
127
123
  MIN_ROW_PX
128
124
  );
129
- const longest = Math.max(bars.reference.bp, ...bars.rows.map((r) => r.bp), 1);
125
+ const longest = Math.max(longestBar(bars), 1);
130
126
  const left = labelled ? labelPx : PAD_PX;
131
127
  const usable = Math.max(1, o.width - left - PAD_PX);
132
128
  const scaleX = usable / (longest * (readouts ? READOUT_ROOM : 1));
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  referenceKnots,
3
3
  warpX
4
- } from "./chunk-HK5Y2YWV.js";
4
+ } from "./chunk-MYDHU2UV.js";
5
5
 
6
6
  // src/tubeMap/frame.ts
7
7
  var MIN_TUBE_Y_SCALE = 0.05;
@@ -1,9 +1,12 @@
1
1
  import {
2
2
  ownStrand
3
- } from "./chunk-7SRWJLSC.js";
3
+ } from "./chunk-UBQSRCWR.js";
4
+ import {
5
+ groupBy
6
+ } from "./chunk-BSOZW3FC.js";
4
7
  import {
5
8
  isBackbone
6
- } from "./chunk-FYQWPEEY.js";
9
+ } from "./chunk-RJWPJCIB.js";
7
10
 
8
11
  // src/foldVariants.ts
9
12
  function foldVariants(graph, belowBp) {
@@ -15,7 +18,7 @@ function foldVariants(graph, belowBp) {
15
18
  const sides = edges.map(forwardSides);
16
19
  const links = linksAt(nodes.length, edges, sides, index);
17
20
  const allele = alleleOf(nodes, edges, sides, index);
18
- const members = groupBy(allele);
21
+ const members = groupBy(allele.keys(), (i) => allele[i]);
19
22
  const kept = new Uint8Array(nodes.length);
20
23
  const big = [];
21
24
  for (const group of members.values()) {
@@ -137,18 +140,6 @@ function alleleOf(nodes, edges, sides, index) {
137
140
  });
138
141
  return nodes.map((_, i) => find(i));
139
142
  }
140
- function groupBy(allele) {
141
- const groups = /* @__PURE__ */ new Map();
142
- allele.forEach((root, i) => {
143
- const group = groups.get(root);
144
- if (group) {
145
- group.push(i);
146
- } else {
147
- groups.set(root, [i]);
148
- }
149
- });
150
- return groups;
151
- }
152
143
  function alleleContent(group, nodes, links, allele) {
153
144
  if (isBackbone(nodes[group[0]])) {
154
145
  return Infinity;
@@ -311,7 +302,7 @@ function mergeAlleleRuns(graph, kept, allele) {
311
302
  const internal = /* @__PURE__ */ new Set();
312
303
  ends.forEach(([a, b], k) => {
313
304
  if (a.i !== b.i && allele[a.i] === allele[b.i] && continues(nodes[a.i], a.side, nodes[b.i], b.side) && degree.get(sideKey(a.i, a.side)) === 1 && degree.get(sideKey(b.i, b.side)) === 1) {
314
- const [left, right] = nodes[a.i].stable.start < nodes[b.i].stable.start ? [a, b] : [b, a];
305
+ const [left, right] = a.side === "e" ? [a, b] : [b, a];
315
306
  next.set(left.i, { j: right.i, out: left.side, in: right.side });
316
307
  hasPrev.add(right.i);
317
308
  internal.add(k);
@@ -1,15 +1,15 @@
1
- import {
2
- RAMP_GRADIENT_CSS,
3
- RAMP_GRADIENT_STOPS,
4
- rampHueCss,
5
- rampStops
6
- } from "./chunk-XL472HHD.js";
7
1
  import {
8
2
  el
9
3
  } from "./chunk-H2H4Y3TV.js";
10
4
  import {
11
5
  REFERENCE_RAMP_ALT_CSS
12
- } from "./chunk-A4PFFC4Q.js";
6
+ } from "./chunk-2XEQR54X.js";
7
+ import {
8
+ RAMP_GRADIENT_CSS,
9
+ RAMP_GRADIENT_STOPS,
10
+ rampHueCss,
11
+ rampStops
12
+ } from "./chunk-GQZVR5DW.js";
13
13
  import {
14
14
  LABEL_CHAR_PX
15
15
  } from "./chunk-AB35TJST.js";
@@ -490,7 +490,6 @@ export {
490
490
  BAR_PX,
491
491
  GAP_PX,
492
492
  LABELLED_ROW_PX,
493
- kb,
494
493
  walkRowReadout,
495
494
  readoutPlacement,
496
495
  unitTicks,
@@ -1,29 +1,27 @@
1
1
  import {
2
2
  pathSteps
3
- } from "./chunk-XI3ZUTWF.js";
3
+ } from "./chunk-ZNJ4JAPT.js";
4
4
  import {
5
5
  pathOrigin
6
- } from "./chunk-M6LK4GII.js";
6
+ } from "./chunk-LGJBB5BP.js";
7
+ import {
8
+ pushTo
9
+ } from "./chunk-BSOZW3FC.js";
7
10
 
8
11
  // src/tubeMap/bundle.ts
9
12
  function bundleRoutes(graph, groupOf = () => "", merge = true) {
10
13
  const paths = graph.paths ?? [];
11
14
  const steps = pathSteps(graph);
12
- const routes = /* @__PURE__ */ new Map();
15
+ const piecesOf = /* @__PURE__ */ new Map();
13
16
  paths.forEach((path, i) => {
14
- const walk = pathOrigin(path.name).name;
15
- const route = steps[i].map((s) => `${s.node.id}${s.strand}`).join(",");
16
- const pieces = routes.get(walk);
17
- if (pieces) {
18
- pieces.push(route);
19
- } else {
20
- routes.set(walk, [route]);
21
- }
17
+ pushTo(piecesOf, pathOrigin(path.name).name, i);
22
18
  });
19
+ const routeOf = (i) => steps[i].map((s) => `${s.node.id}${s.strand}`).join(",");
20
+ const recordsOf = (walk) => piecesOf.get(walk).map((i) => paths[i]);
23
21
  const routeRank = /* @__PURE__ */ new Map();
24
22
  const bundles = /* @__PURE__ */ new Map();
25
- for (const [walk, pieces] of routes) {
26
- const route = walk === graph.referencePath ? `\0${walk}` : pieces.join("|");
23
+ for (const [walk, pieces] of piecesOf) {
24
+ const route = walk === graph.referencePath ? `\0${walk}` : pieces.map(routeOf).join("|");
27
25
  const group = groupOf(walk);
28
26
  const rank = routeRank.get(route) ?? routeRank.size;
29
27
  routeRank.set(route, rank);
@@ -35,32 +33,22 @@ function bundleRoutes(graph, groupOf = () => "", merge = true) {
35
33
  bundles.set(key, { rank, group, walks: [walk] });
36
34
  }
37
35
  }
38
- if (merge && bundles.size === routes.size) {
36
+ if (merge && bundles.size === piecesOf.size) {
39
37
  return graph;
40
38
  }
41
39
  const ordered = [...bundles.values()].sort(
42
40
  (a, b) => a.rank - b.rank || a.group.localeCompare(b.group)
43
41
  );
44
- const recordsOf = /* @__PURE__ */ new Map();
45
- for (const path of paths) {
46
- const walk = pathOrigin(path.name).name;
47
- const records = recordsOf.get(walk);
48
- if (records) {
49
- records.push(path);
50
- } else {
51
- recordsOf.set(walk, [path]);
52
- }
53
- }
54
42
  if (!merge) {
55
43
  return {
56
44
  ...graph,
57
- paths: ordered.flatMap(
58
- ({ walks }) => walks.flatMap((walk) => recordsOf.get(walk))
59
- )
45
+ paths: ordered.flatMap(({ walks }) => walks.flatMap(recordsOf))
60
46
  };
61
47
  }
62
48
  const kept = ordered.flatMap(
63
- ({ walks }) => recordsOf.get(walks[0]).map((path) => walks.length > 1 ? { ...path, members: walks } : path)
49
+ ({ walks }) => recordsOf(walks[0]).map(
50
+ (path) => walks.length > 1 ? { ...path, members: walks } : path
51
+ )
64
52
  );
65
53
  const keptWalks = new Set(ordered.map((b) => b.walks[0]));
66
54
  return {
@@ -1,3 +1,7 @@
1
+ import {
2
+ panSNFields
3
+ } from "./chunk-4XWZNPQ2.js";
4
+
1
5
  // src/facetGrid.ts
2
6
  var FACET_GAP_PX = 8;
3
7
  var FACET_TITLE_PX = 34;
@@ -85,9 +89,8 @@ function facetCells(names, by, domain = []) {
85
89
  return wrap;
86
90
  }
87
91
  const places = names.map((name) => {
88
- const [sample, haplotype, contig] = name.split("#");
89
- const n = Number(haplotype);
90
- return contig !== void 0 && Number.isInteger(n) && n >= 0 ? { sample, column: Math.max(0, n - 1) } : void 0;
92
+ const fields = panSNFields(name);
93
+ return fields && Number.isInteger(fields.haplotype) && fields.haplotype >= 0 ? { sample: fields.sample, column: Math.max(0, fields.haplotype - 1) } : void 0;
91
94
  });
92
95
  const rows = domainFirst(
93
96
  [...new Set(places.flatMap((p) => p ? [p.sample] : []))],
@@ -1,9 +1,12 @@
1
+ import {
2
+ buildNeighbors
3
+ } from "./chunk-VX656OAZ.js";
1
4
  import {
2
5
  ROW_HEIGHT_PX
3
6
  } from "./chunk-CPMHA4W5.js";
4
7
  import {
5
8
  isBackbone
6
- } from "./chunk-FYQWPEEY.js";
9
+ } from "./chunk-RJWPJCIB.js";
7
10
 
8
11
  // src/layout/orderedLayout.ts
9
12
  var GUTTER = 12;
@@ -99,13 +102,13 @@ function placeByWalks(graph, backbone) {
99
102
  }
100
103
  return placed;
101
104
  }
102
- function placeBySearch(adjacent, key) {
105
+ function placeBySearch(adjacent, key, isNode) {
103
106
  const queue = [...key.entries()].sort(([a, ka], [b, kb]) => compareKeys(ka, kb) || compare(a, b)).map(([id]) => id);
104
107
  const placed = queue.length;
105
108
  for (const id of queue) {
106
109
  const from = key.get(id);
107
110
  for (const nb of adjacent.get(id) ?? []) {
108
- if (!key.has(nb)) {
111
+ if (isNode.has(nb) && !key.has(nb)) {
109
112
  key.set(nb, { at: from.at, side: 1, hops: from.hops + 1 });
110
113
  queue.push(nb);
111
114
  }
@@ -127,6 +130,9 @@ function placeBySearch(adjacent, key) {
127
130
  let touchesLeft = false;
128
131
  for (const nb of adjacent.get(id) ?? []) {
129
132
  const other = key.get(nb);
133
+ if (!other) {
134
+ continue;
135
+ }
130
136
  if (other.at === at && searched.has(nb)) {
131
137
  deadEnd &&= other.hops <= hops;
132
138
  if (!sided.has(nb)) {
@@ -149,16 +155,6 @@ function placeBySearch(adjacent, key) {
149
155
  }
150
156
  }
151
157
  function orderKeys(graph) {
152
- const ids = new Set(graph.nodes.map((n) => n.id));
153
- const adjacent = /* @__PURE__ */ new Map();
154
- for (const e of graph.edges) {
155
- if (!ids.has(e.from) || !ids.has(e.to)) {
156
- continue;
157
- }
158
- ;
159
- (adjacent.get(e.from) ?? adjacent.set(e.from, []).get(e.from)).push(e.to);
160
- (adjacent.get(e.to) ?? adjacent.set(e.to, []).get(e.to)).push(e.from);
161
- }
162
158
  const backbone = graph.nodes.filter(isBackbone).sort(
163
159
  (a, b) => compare(a.stable.start, b.stable.start) || compare(a.name, b.name)
164
160
  );
@@ -166,7 +162,7 @@ function orderKeys(graph) {
166
162
  placeByWalks(graph, backbone).forEach((id, rank) => {
167
163
  key.set(id, { at: rank, side: 0, hops: 0 });
168
164
  });
169
- placeBySearch(adjacent, key);
165
+ placeBySearch(buildNeighbors(graph), key, new Set(graph.nodes.map((n) => n.id)));
170
166
  return key;
171
167
  }
172
168
  function layerGraph(graph) {
@@ -240,17 +240,19 @@ function unscaleYOf(curves, yToX) {
240
240
  }
241
241
  return curves;
242
242
  }
243
+ function polylinePx(points, scaleX, scaleY) {
244
+ let total = 0;
245
+ for (let i = 1; i < points.length; i++) {
246
+ const a = points[i - 1];
247
+ const b = points[i];
248
+ total += Math.hypot((b.x - a.x) * scaleX, (b.y - a.y) * scaleY);
249
+ }
250
+ return total;
251
+ }
243
252
  var SELF_LOOP_MIN_PX = 12;
244
253
  var SELF_LOOP_MAX_PX = 40;
245
254
  function selfLoopReach(segments, scale) {
246
- let length = 0;
247
- for (let i = 1; i < segments.length; i++) {
248
- length += Math.hypot(
249
- segments[i].x - segments[i - 1].x,
250
- segments[i].y - segments[i - 1].y
251
- );
252
- }
253
- const nodePx = length * scale;
255
+ const nodePx = polylinePx(segments, scale, scale);
254
256
  const reachPx = Math.min(
255
257
  SELF_LOOP_MAX_PX,
256
258
  Math.max(SELF_LOOP_MIN_PX, nodePx / 2)
@@ -520,6 +522,7 @@ export {
520
522
  yToXOf,
521
523
  PATH_RIBBON_SPACING_PX,
522
524
  pathRibbonOffsets,
525
+ polylinePx,
523
526
  selfLinkOf,
524
527
  edgeJoinOf,
525
528
  computeEdgeCurves,
@@ -1,5 +1,6 @@
1
1
  // src/renderer/svgCanvas.ts
2
2
  var n = (v) => +v.toFixed(1);
3
+ var alpha = (v) => +v.toFixed(3);
3
4
  function paint(css) {
4
5
  const m = /^rgba?\(([^,]+),([^,]+),([^,)]+)(?:,([^)]+))?\)$/.exec(
5
6
  css.replaceAll(" ", "")
@@ -12,7 +13,7 @@ function paint(css) {
12
13
  }
13
14
  function paintAttrs(kind, css) {
14
15
  const { color, opacity } = paint(css);
15
- return `${kind}="${color}"${opacity < 1 ? ` ${kind}-opacity="${n(opacity)}"` : ""}`;
16
+ return `${kind}="${color}"${opacity < 1 ? ` ${kind}-opacity="${alpha(opacity)}"` : ""}`;
16
17
  }
17
18
  var DOT_PX = 0.5;
18
19
  var DOT_CELL_PX = 0.25;
@@ -1,11 +1,15 @@
1
1
  import {
2
2
  REFERENCE_RAMP_ALT_COLOR,
3
- REFERENCE_RAMP_MAX_HUE,
4
3
  hslToRgb
5
- } from "./chunk-A4PFFC4Q.js";
4
+ } from "./chunk-2XEQR54X.js";
6
5
  import {
7
6
  packAbgr
8
7
  } from "./chunk-G2FD7S3C.js";
8
+ import {
9
+ REFERENCE_RAMP_LIGHTNESS,
10
+ REFERENCE_RAMP_SATURATION,
11
+ rampHueAt
12
+ } from "./chunk-GQZVR5DW.js";
9
13
 
10
14
  // src/walkEncoding.ts
11
15
  var WALK_FIELDS = [
@@ -61,7 +65,11 @@ function schemeRgb(scheme, t) {
61
65
  const x = Math.max(0, Math.min(1, t));
62
66
  const family = WALK_SCHEMES.find((s) => s.value === scheme);
63
67
  if (!family || !("ends" in family)) {
64
- return hslToRgb(x * REFERENCE_RAMP_MAX_HUE, 0.7, 0.5).map((c) => c * 255);
68
+ return hslToRgb(
69
+ rampHueAt(x),
70
+ REFERENCE_RAMP_SATURATION,
71
+ REFERENCE_RAMP_LIGHTNESS
72
+ ).map((c) => c * 255);
65
73
  }
66
74
  const from = oklab(family.ends[0]);
67
75
  const to = oklab(family.ends[1]);
@@ -1,22 +1,17 @@
1
+ import {
2
+ pushTo
3
+ } from "./chunk-BSOZW3FC.js";
1
4
  import {
2
5
  isBackbone
3
- } from "./chunk-FYQWPEEY.js";
6
+ } from "./chunk-RJWPJCIB.js";
4
7
 
5
8
  // src/referenceSpan.ts
6
9
  var MAX_BACKBONE_HOPS = 4;
7
10
  function buildNeighbors(graph) {
8
11
  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
12
  for (const edge of graph.edges) {
18
- add(edge.from, edge.to);
19
- add(edge.to, edge.from);
13
+ pushTo(neighbors, edge.from, edge.to);
14
+ pushTo(neighbors, edge.to, edge.from);
20
15
  }
21
16
  return neighbors;
22
17
  }
@@ -0,0 +1,37 @@
1
+ import {
2
+ weakMemo
3
+ } from "./chunk-HMXCN6PG.js";
4
+ import {
5
+ edgeCurvesOf
6
+ } from "./chunk-CGMSKIEO.js";
7
+
8
+ // src/util/edgeCurves.ts
9
+ var cache = weakMemo();
10
+ function baseEdgeCurves(nodePositions, graph, axis, deletions, version, routes, stranded = false) {
11
+ return cache(
12
+ nodePositions,
13
+ [graph, axis.scaleX, axis.scaleY, deletions, routes, stranded, version],
14
+ () => {
15
+ const curves = /* @__PURE__ */ new Map();
16
+ for (let ei = 0; ei < graph.edges.length; ei++) {
17
+ const bypassed = deletions?.get(ei);
18
+ const edgeCurves = edgeCurvesOf(
19
+ nodePositions,
20
+ graph.edges[ei],
21
+ axis,
22
+ bypassed,
23
+ bypassed && routes?.[ei],
24
+ stranded
25
+ );
26
+ if (edgeCurves) {
27
+ curves.set(ei, edgeCurves);
28
+ }
29
+ }
30
+ return curves;
31
+ }
32
+ );
33
+ }
34
+
35
+ export {
36
+ baseEdgeCurves
37
+ };
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  engineKey,
3
3
  forceLayout
4
- } from "./chunk-2QLLQJ72.js";
4
+ } from "./chunk-KWHWNOTY.js";
5
5
 
6
6
  // src/layout/forceCache.ts
7
7
  var DEFAULT_SIZE = 4;
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  clampZoom
3
- } from "./chunk-2QLLQJ72.js";
3
+ } from "./chunk-KWHWNOTY.js";
4
4
 
5
5
  // src/viewport.ts
6
6
  function axisScaleOf(scale, pixelRows) {