@jbrowse/bandage-core 10.2.7 → 10.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (190) 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-ABUIN5AK.js → chunk-2Q22S52W.js} +29 -24
  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-3XSM4OZU.js → chunk-3GP3KT5L.js} +5 -5
  14. package/dist/chunks/{chunk-PUG7LXDF.js → chunk-3PZSBNLI.js} +4 -1
  15. package/dist/chunks/{chunk-JLSJMCDJ.js → chunk-3UST3ZQE.js} +3 -3
  16. package/dist/chunks/{chunk-KBEP7VYK.js → chunk-3VCKBSML.js} +4 -4
  17. package/dist/chunks/{chunk-BPLIXMH7.js → chunk-4XWZNPQ2.js} +14 -0
  18. package/dist/chunks/{chunk-4DRQTBBE.js → chunk-6EOB6ANX.js} +1 -1
  19. package/dist/chunks/{chunk-L2HDM2R3.js → chunk-A2TJ5UX6.js} +7 -7
  20. package/dist/chunks/{chunk-URZ3CH2R.js → chunk-A4JDEUAI.js} +1 -1
  21. package/dist/chunks/{chunk-CWFNEKST.js → chunk-A7H753BA.js} +3 -3
  22. package/dist/chunks/{chunk-CG35S2S2.js → chunk-AQCOIE5R.js} +1 -1
  23. package/dist/chunks/{chunk-TKIJ5535.js → chunk-AZ4EEF6Q.js} +6 -6
  24. package/dist/chunks/{chunk-M6LK4GII.js → chunk-B5X2RLJG.js} +17 -10
  25. package/dist/chunks/{chunk-A7CFWFQS.js → chunk-BKEZLETL.js} +1 -1
  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-XXT2JCAC.js → chunk-BX4AUMZE.js} +11 -13
  29. package/dist/chunks/{chunk-N73TI3VG.js → chunk-BZFOFC4D.js} +6 -9
  30. package/dist/chunks/{chunk-4ETPXDO6.js → chunk-CGFPFBT2.js} +1 -1
  31. package/dist/chunks/{chunk-24WITXQY.js → chunk-CGMSKIEO.js} +9 -25
  32. package/dist/chunks/{chunk-VV6KGJ7M.js → chunk-CHNESV7L.js} +18 -27
  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-AUFAPUO4.js → chunk-D7WIYPG3.js} +3 -1
  36. package/dist/chunks/{chunk-OIV2GBAJ.js → chunk-DBLV7PGG.js} +27 -17
  37. package/dist/chunks/{chunk-VQC7KELB.js → chunk-DO62DG26.js} +11 -3
  38. package/dist/chunks/{chunk-JA2HJIYS.js → chunk-E4ZM4OOJ.js} +3 -5
  39. package/dist/chunks/{chunk-QLWI2PZ3.js → chunk-EJRJAAN7.js} +24 -21
  40. package/dist/chunks/{chunk-QBHPHLAQ.js → chunk-EWLXU3UG.js} +41 -36
  41. package/dist/chunks/{chunk-XI3ZUTWF.js → chunk-FW2R7UDZ.js} +14 -20
  42. package/dist/chunks/{chunk-Q7LYHGGQ.js → chunk-GIHTHYXY.js} +5 -4
  43. package/dist/chunks/{chunk-L3O7AWLI.js → chunk-GJLZ2MKE.js} +2 -2
  44. package/dist/chunks/{chunk-LOEA5IHZ.js → chunk-GJU6BJJA.js} +8 -8
  45. package/dist/chunks/{chunk-XL472HHD.js → chunk-GQZVR5DW.js} +12 -7
  46. package/dist/chunks/{chunk-UVBGRJQX.js → chunk-HKYXWZQS.js} +1 -1
  47. package/dist/chunks/chunk-HMXCN6PG.js +17 -0
  48. package/dist/chunks/{chunk-WSIFAZU7.js → chunk-HNWJ4B7S.js} +12 -13
  49. package/dist/chunks/chunk-HOAIOEI7.js +18 -0
  50. package/dist/chunks/{chunk-XMW266WS.js → chunk-HSVFCA2J.js} +18 -20
  51. package/dist/chunks/{chunk-QXUEF3AJ.js → chunk-KMBE2Q42.js} +22 -17
  52. package/dist/chunks/{chunk-VQWHMWLF.js → chunk-M5NPD55W.js} +18 -14
  53. package/dist/chunks/chunk-MWOVW4AH.js +327 -0
  54. package/dist/chunks/{chunk-HK5Y2YWV.js → chunk-MYDHU2UV.js} +6 -11
  55. package/dist/chunks/{chunk-TZFWUT2C.js → chunk-MYLAJDKB.js} +2 -2
  56. package/dist/chunks/{chunk-AR4BUBMU.js → chunk-NZTYV3JL.js} +34 -35
  57. package/dist/chunks/{chunk-4HWM3FNK.js → chunk-OMUPUB4J.js} +39 -56
  58. package/dist/chunks/{chunk-LKW2TP4N.js → chunk-OOIOX36I.js} +18 -16
  59. package/dist/chunks/{chunk-EQ2NIFRH.js → chunk-OXRUPNSV.js} +1 -1
  60. package/dist/chunks/{chunk-PTABFYQ7.js → chunk-PFRQBCGC.js} +49 -60
  61. package/dist/chunks/{chunk-T6V4KI2L.js → chunk-PNMJFFNB.js} +1 -1
  62. package/dist/chunks/{chunk-KC7T5RWG.js → chunk-PSCSZSVK.js} +9 -16
  63. package/dist/chunks/{chunk-23YFB5BB.js → chunk-QH2MIXBA.js} +29 -13
  64. package/dist/chunks/{chunk-5GMFEPWR.js → chunk-R2PJKD3Y.js} +16 -28
  65. package/dist/chunks/{chunk-CQHUZHET.js → chunk-RFG42VIO.js} +46 -30
  66. package/dist/chunks/{chunk-FYQWPEEY.js → chunk-RJWPJCIB.js} +5 -11
  67. package/dist/chunks/{chunk-WBSWROE6.js → chunk-SFP3E4RI.js} +14 -18
  68. package/dist/chunks/{chunk-2CMYNW3E.js → chunk-SI3BB4DO.js} +1 -1
  69. package/dist/chunks/{chunk-DY3JCAMX.js → chunk-SOMZGDVS.js} +7 -16
  70. package/dist/chunks/{chunk-A4PFFC4Q.js → chunk-SWCULW6S.js} +60 -102
  71. package/dist/chunks/{chunk-XV4P5KEQ.js → chunk-TGUFT6KK.js} +6 -3
  72. package/dist/chunks/{chunk-CM6LO6OC.js → chunk-UAFATXYA.js} +10 -14
  73. package/dist/chunks/{chunk-7SRWJLSC.js → chunk-UBQSRCWR.js} +11 -8
  74. package/dist/chunks/{chunk-RUCH6ZFL.js → chunk-V4YML3GR.js} +2 -1
  75. package/dist/chunks/{chunk-ES2N6V56.js → chunk-VX656OAZ.js} +6 -11
  76. package/dist/chunks/chunk-WA5WNP6V.js +37 -0
  77. package/dist/chunks/{chunk-B6IW3IRE.js → chunk-WYJQIC75.js} +14 -15
  78. package/dist/chunks/{chunk-T2PCSAFY.js → chunk-XVS52NMZ.js} +2 -2
  79. package/dist/chunks/{chunk-CU6P5RUG.js → chunk-YZQI35UJ.js} +22 -16
  80. package/dist/chunks/{chunk-G45YY72K.js → chunk-Z6XZWPXK.js} +17 -25
  81. package/dist/chunks/{chunk-EFQLEGWM.js → chunk-ZJBOM73S.js} +7 -8
  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-core/gfaParser.d.ts +1 -1
  152. package/dist/types/graphLabels.d.ts +2 -1
  153. package/dist/types/layout/drawnScale.d.ts +0 -2
  154. package/dist/types/layout/referenceSeeds.d.ts +2 -1
  155. package/dist/types/layout/tubeMapLayout.d.ts +0 -7
  156. package/dist/types/layout/walkRowDraw.d.ts +0 -1
  157. package/dist/types/layout/walkRowLayout.d.ts +1 -0
  158. package/dist/types/layout/walkRows.d.ts +1 -0
  159. package/dist/types/nodeWidths.d.ts +0 -1
  160. package/dist/types/pansn.d.ts +9 -0
  161. package/dist/types/pathVisits.d.ts +6 -0
  162. package/dist/types/referenceRampCss.d.ts +4 -0
  163. package/dist/types/renderer/Canvas2DRenderer.d.ts +1 -0
  164. package/dist/types/renderer/GeometryBuilder.d.ts +3 -2
  165. package/dist/types/tubeMap/axis.d.ts +3 -1
  166. package/dist/types/tubeMap/coarsen.d.ts +3 -1
  167. package/dist/types/tubeMap/deviations.d.ts +2 -1
  168. package/dist/types/tubeMap/mismatches.d.ts +0 -1
  169. package/dist/types/tubeMap/warp.d.ts +2 -1
  170. package/dist/types/util/SpatialIndex.d.ts +1 -1
  171. package/dist/types/util/geometry.d.ts +4 -0
  172. package/dist/types/util/groups.d.ts +3 -0
  173. package/dist/types/util/hitDetection.d.ts +2 -2
  174. package/dist/types/util/partitionPoint.d.ts +1 -0
  175. package/dist/types/util/weakMemo.d.ts +1 -0
  176. package/dist/types/version.d.ts +1 -1
  177. package/dist/util/SpatialIndex.js +8 -5
  178. package/dist/util/edgeCurves.js +7 -4
  179. package/dist/util/geometry.js +3 -1
  180. package/dist/util/groups.js +10 -0
  181. package/dist/util/hitDetection.js +9 -6
  182. package/dist/util/partitionPoint.js +6 -0
  183. package/dist/util/weakMemo.js +6 -0
  184. package/dist/version.js +1 -1
  185. package/dist/viewport.js +19 -17
  186. package/dist/walkEncoding.js +18 -14
  187. package/dist/walkHighlight.js +19 -15
  188. package/dist/walkKey.js +9 -6
  189. package/package.json +2 -2
  190. package/dist/chunks/chunk-ZY2AFL4Y.js +0 -43
@@ -1,10 +1,13 @@
1
1
  import {
2
2
  pathOrigin
3
- } from "./chunk-M6LK4GII.js";
3
+ } from "./chunk-B5X2RLJG.js";
4
+ import {
5
+ groupBy
6
+ } from "./chunk-BSOZW3FC.js";
4
7
  import {
5
8
  panSNContig,
6
9
  panSNSample
7
- } from "./chunk-BPLIXMH7.js";
10
+ } from "./chunk-4XWZNPQ2.js";
8
11
 
9
12
  // src/layout/walkRows.ts
10
13
  function sampleOf(path) {
@@ -150,29 +153,27 @@ function filterSamples(rows, samples) {
150
153
  (a, b) => samples.indexOf(a.sample) - samples.indexOf(b.sample) || a.label.localeCompare(b.label)
151
154
  ) : rows;
152
155
  }
153
- function walkRows(graph, region, unit) {
154
- const paths = graph.paths ?? [];
155
- const nameOf = (p) => pathOrigin(p.name).name;
156
+ function referenceWalkName(graph) {
157
+ const names = (graph.paths ?? []).map((p) => pathOrigin(p.name).name);
158
+ if (graph.referencePath !== void 0 && names.includes(graph.referencePath)) {
159
+ return graph.referencePath;
160
+ }
156
161
  const rankZero = new Set(
157
162
  graph.nodes.flatMap((n) => n.stable?.rank === 0 ? [n.stable.refName] : [])
158
163
  );
159
- const names = paths.map(nameOf);
160
- const referenceName = graph.referencePath !== void 0 && names.includes(graph.referencePath) ? graph.referencePath : names.find((n) => rankZero.has(n)) ?? names[0];
164
+ return names.find((n) => rankZero.has(n)) ?? names[0];
165
+ }
166
+ function walkRows(graph, region, unit) {
167
+ const paths = graph.paths ?? [];
168
+ const nameOf = (p) => pathOrigin(p.name).name;
169
+ const referenceName = referenceWalkName(graph);
161
170
  const referencePieces = paths.filter((p) => nameOf(p) === referenceName).sort((a, b) => (a.start ?? 0) - (b.start ?? 0));
162
171
  const first = referencePieces[0];
163
172
  const others = paths.filter((p) => !referencePieces.includes(p));
164
173
  if (!first || others.length === 0) {
165
174
  return void 0;
166
175
  }
167
- const walks = /* @__PURE__ */ new Map();
168
- for (const path of others) {
169
- const pieces = walks.get(path.name);
170
- if (pieces) {
171
- pieces.push(path);
172
- } else {
173
- walks.set(path.name, [path]);
174
- }
175
- }
176
+ const walks = groupBy(others, nameOf);
176
177
  const table = new NodeTable(graph);
177
178
  const referenceStart = first.start ?? 0;
178
179
  const cut = region && region.end > region.start ? region : void 0;
@@ -285,5 +286,6 @@ function walkRows(graph, region, unit) {
285
286
 
286
287
  export {
287
288
  filterSamples,
289
+ referenceWalkName,
288
290
  walkRows
289
291
  };
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  engineKey,
3
3
  forceLayout
4
- } from "./chunk-QXUEF3AJ.js";
4
+ } from "./chunk-KMBE2Q42.js";
5
5
 
6
6
  // src/layout/forceCache.ts
7
7
  var DEFAULT_SIZE = 4;
@@ -1,16 +1,21 @@
1
1
  import {
2
+ weakMemo
3
+ } from "./chunk-HMXCN6PG.js";
4
+ import {
5
+ labelWidth,
2
6
  occupancy
3
7
  } from "./chunk-AB35TJST.js";
4
8
  import {
5
9
  polylineMidpoint
6
- } from "./chunk-N73TI3VG.js";
10
+ } from "./chunk-BZFOFC4D.js";
7
11
  import {
8
- deletionArcCurves
9
- } from "./chunk-24WITXQY.js";
12
+ edgeCurvesOf
13
+ } from "./chunk-CGMSKIEO.js";
10
14
  import {
11
15
  curveBounds,
12
- curveMidpoint
13
- } from "./chunk-7SRWJLSC.js";
16
+ curveMidpoint,
17
+ polylinePx
18
+ } from "./chunk-UBQSRCWR.js";
14
19
 
15
20
  // src/graphLabels.ts
16
21
  var MIN_DELETION_LABEL_PX = 26;
@@ -38,7 +43,7 @@ function boxAt(halfW, x, y) {
38
43
  function rowLabelBox(text, screenY) {
39
44
  return {
40
45
  x0: 6,
41
- x1: 6 + text.length * 6.2 + 8 + LABEL_GAP_PX,
46
+ x1: 6 + labelWidth(text) + LABEL_GAP_PX,
42
47
  y0: screenY - 8 - LABEL_GAP_PX / 2,
43
48
  y1: screenY + 8 + LABEL_GAP_PX / 2
44
49
  };
@@ -78,15 +83,6 @@ function boxRayCrossing(box, dir) {
78
83
  dir.y === 0 ? Infinity : halfH / Math.abs(dir.y)
79
84
  );
80
85
  }
81
- function drawnLength(segments, scaleX, scaleY) {
82
- let total = 0;
83
- for (let i = 1; i < segments.length; i++) {
84
- const a = segments[i - 1];
85
- const b = segments[i];
86
- total += Math.hypot((b.x - a.x) * scaleX, (b.y - a.y) * scaleY);
87
- }
88
- return total;
89
- }
90
86
  function runBounds(nodeIds, nodePositions) {
91
87
  let minX = Infinity;
92
88
  let minY = Infinity;
@@ -102,54 +98,46 @@ function runBounds(nodeIds, nodePositions) {
102
98
  }
103
99
  return minX === Infinity ? void 0 : { minX, minY, maxX, maxY };
104
100
  }
105
- var nodeOrderCache = /* @__PURE__ */ new WeakMap();
101
+ var nodeOrderCache = weakMemo();
106
102
  function labelOrder(nodePositions, nodeLengths) {
107
- const cached = nodeOrderCache.get(nodePositions);
108
- if (cached?.nodeLengths === nodeLengths) {
109
- return cached.order;
110
- }
111
- const order = Object.entries(nodePositions).filter(([id, segments]) => segments.length > 0 && nodeLengths.has(id)).sort(([a], [b]) => nodeLengths.get(b) - nodeLengths.get(a));
112
- nodeOrderCache.set(nodePositions, { nodeLengths, order });
113
- return order;
103
+ return nodeOrderCache(
104
+ nodePositions,
105
+ [nodeLengths],
106
+ () => Object.entries(nodePositions).filter(([id, segments]) => segments.length > 0 && nodeLengths.has(id)).sort(([a], [b]) => nodeLengths.get(b) - nodeLengths.get(a))
107
+ );
114
108
  }
115
- var arcCache = /* @__PURE__ */ new WeakMap();
109
+ var arcCache = weakMemo();
116
110
  function arcPlacements(nodePositions, deletions, axis, version, routes, stranded) {
117
111
  const { scaleX, scaleY } = axis;
118
- const cached = arcCache.get(nodePositions);
119
- if (cached?.deletions === deletions && cached.routes === routes && cached.stranded === stranded && cached.scaleX === scaleX && cached.scaleY === scaleY && cached.version === version) {
120
- return cached.arcs;
121
- }
122
- const arcs = [];
123
- for (const deletion of [...deletions].sort((a, b) => b.bp - a.bp)) {
124
- const curves = deletionArcCurves(
125
- nodePositions,
126
- deletion,
127
- axis,
128
- routes?.[deletion.edgeIndex],
129
- stranded
130
- );
131
- const apex = curves ? curveMidpoint(curves) : void 0;
132
- if (curves && apex) {
133
- const { minX, minY, maxX, maxY } = curveBounds(curves);
134
- arcs.push({
135
- deletion,
136
- curves,
137
- apex,
138
- // in screen px, so the two axes' units cannot be added by accident
139
- extent: Math.max((maxX - minX) * scaleX, (maxY - minY) * scaleY)
140
- });
112
+ return arcCache(
113
+ nodePositions,
114
+ [deletions, routes, stranded, scaleX, scaleY, version],
115
+ () => {
116
+ const arcs = [];
117
+ for (const deletion of [...deletions].sort((a, b) => b.bp - a.bp)) {
118
+ const curves = edgeCurvesOf(
119
+ nodePositions,
120
+ deletion,
121
+ axis,
122
+ deletion.bypassed,
123
+ routes?.[deletion.edgeIndex],
124
+ stranded
125
+ );
126
+ const apex = curves ? curveMidpoint(curves) : void 0;
127
+ if (curves && apex) {
128
+ const { minX, minY, maxX, maxY } = curveBounds(curves);
129
+ arcs.push({
130
+ deletion,
131
+ curves,
132
+ apex,
133
+ // in screen px, so the two axes' units cannot be added by accident
134
+ extent: Math.max((maxX - minX) * scaleX, (maxY - minY) * scaleY)
135
+ });
136
+ }
137
+ }
138
+ return arcs;
141
139
  }
142
- }
143
- arcCache.set(nodePositions, {
144
- deletions,
145
- routes,
146
- stranded,
147
- scaleX,
148
- scaleY,
149
- version,
150
- arcs
151
- });
152
- return arcs;
140
+ );
153
141
  }
154
142
  function sizeLabelCandidates({
155
143
  nodePositions,
@@ -267,7 +255,7 @@ function sizeLabelCandidates({
267
255
  if (screenY + LABEL_HALF_HEIGHT <= 0 || screenY - LABEL_HALF_HEIGHT >= height) {
268
256
  continue;
269
257
  }
270
- const drawn = drawnLength(segments, scaleX, scaleY);
258
+ const drawn = polylinePx(segments, scaleX, scaleY);
271
259
  if (drawn < MIN_LABEL_HALF_WIDTH * 2 / MAX_LABEL_OVERHANG) {
272
260
  continue;
273
261
  }
@@ -309,9 +297,10 @@ function placeSizeLabels(candidates, take, budget = Infinity) {
309
297
  }
310
298
  function graphLabels({
311
299
  reserved,
300
+ take,
312
301
  ...args
313
302
  }) {
314
- const take = occupancy(args, reserved);
303
+ take ??= occupancy(args, reserved);
315
304
  const { deletions, nodes } = sizeLabelCandidates(args);
316
305
  return [
317
306
  ...placeSizeLabels(deletions, take),
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  trimOrigins
3
- } from "./chunk-M6LK4GII.js";
3
+ } from "./chunk-B5X2RLJG.js";
4
4
 
5
5
  // src/bubbles/popBubble.ts
6
6
  function bubbleSubgraph(graph, segmentIds) {
@@ -1,12 +1,10 @@
1
1
  import {
2
2
  nodesUnderBox
3
- } from "./chunk-4HWM3FNK.js";
3
+ } from "./chunk-OMUPUB4J.js";
4
4
  import {
5
- nodeLabelBudget,
6
- placeSizeLabels,
7
- rowLabelBox,
8
- sizeLabelCandidates
9
- } from "./chunk-PTABFYQ7.js";
5
+ graphLabels,
6
+ rowLabelBox
7
+ } from "./chunk-PFRQBCGC.js";
10
8
  import {
11
9
  LABEL_CHAR_PX,
12
10
  LABEL_PAD,
@@ -131,7 +129,7 @@ function layoutLabels(m) {
131
129
  frame,
132
130
  take
133
131
  );
134
- const sizeCandidates = m.nodePositions && m.labelsNodeSizes ? sizeLabelCandidates({
132
+ const sizes = m.nodePositions && m.labelsNodeSizes ? graphLabels({
135
133
  nodePositions: m.nodePositions,
136
134
  nodeLengths: m.nodeLengths,
137
135
  deletions: m.deletions,
@@ -143,19 +141,14 @@ function layoutLabels(m) {
143
141
  translateY,
144
142
  width,
145
143
  height,
146
- version: m.positionsVersion
147
- }) : { deletions: [], nodes: [] };
148
- const deletionLabels = placeSizeLabels(sizeCandidates.deletions, take);
149
- const nodeLabels = placeSizeLabels(
150
- sizeCandidates.nodes,
151
- take,
152
- nodeLabelBudget(width, height)
153
- );
144
+ version: m.positionsVersion,
145
+ take
146
+ }) : [];
154
147
  return {
155
148
  bubbles,
156
149
  ticks,
157
150
  genes,
158
- sizes: [...deletionLabels, ...nodeLabels]
151
+ sizes
159
152
  };
160
153
  }
161
154
 
@@ -4,37 +4,41 @@ import {
4
4
  import {
5
5
  facetLifts,
6
6
  walkLift
7
- } from "./chunk-CU6P5RUG.js";
7
+ } from "./chunk-YZQI35UJ.js";
8
+ import {
9
+ walkKey
10
+ } from "./chunk-CGFPFBT2.js";
8
11
  import {
9
12
  buildGeometry,
10
13
  computeReferenceRamp
11
- } from "./chunk-A4PFFC4Q.js";
14
+ } from "./chunk-SWCULW6S.js";
12
15
  import {
13
16
  walkRowsExtent
14
- } from "./chunk-L2HDM2R3.js";
17
+ } from "./chunk-A2TJ5UX6.js";
15
18
  import {
16
19
  pathLegend,
17
20
  walkLabelsOf
18
- } from "./chunk-3XSM4OZU.js";
21
+ } from "./chunk-3GP3KT5L.js";
19
22
  import {
20
23
  FIGURE_DEFAULTS
21
- } from "./chunk-AUFAPUO4.js";
24
+ } from "./chunk-D7WIYPG3.js";
22
25
  import {
23
26
  drawingBounds
24
- } from "./chunk-QXUEF3AJ.js";
27
+ } from "./chunk-KMBE2Q42.js";
25
28
  import {
26
29
  referenceLabel
27
- } from "./chunk-RAKOB6IV.js";
30
+ } from "./chunk-234NFZS4.js";
28
31
  import {
29
32
  resolveColorScheme
30
33
  } from "./chunk-JKJWSY4V.js";
31
34
  import {
32
35
  deletionDrawing,
33
36
  deletionEdges
34
- } from "./chunk-24WITXQY.js";
37
+ } from "./chunk-CGMSKIEO.js";
35
38
  import {
39
+ facetCells,
36
40
  facetSettingOf
37
- } from "./chunk-XV4P5KEQ.js";
41
+ } from "./chunk-TGUFT6KK.js";
38
42
 
39
43
  // src/figureScene.ts
40
44
  function figureScene(graph, layout, o) {
@@ -61,12 +65,24 @@ function figureScene(graph, layout, o) {
61
65
  const lift = layers.length > 0 && !layout.tubeMap ? walkLift(graph, layers, walkRamp) : void 0;
62
66
  const facet = facetSettingOf(o.facet);
63
67
  const panels = facet.field && lift && lift.walks.length > 1 ? facetLifts(graph, lift, layers, walkRamp) : void 0;
68
+ const facets = facet.field && panels ? {
69
+ panels,
70
+ place: facetCells(
71
+ panels.map((p) => p.walks[0].name),
72
+ facet.field,
73
+ facet.domain
74
+ )
75
+ } : void 0;
64
76
  const labels = walkLabelsOf(
65
77
  graph.paths?.length ? pathLegend(graph.paths) : []
66
78
  );
67
79
  const referenceName = o.referenceName ?? referenceLabel(graph, region);
68
80
  const contigThickness = o.contigThickness ?? FIGURE_DEFAULTS.contigThickness;
69
81
  const nodeWidth = o.nodeWidth ?? FIGURE_DEFAULTS.nodeWidth;
82
+ const reference = lift?.referenceDomain && {
83
+ ...lift.referenceDomain,
84
+ name: referenceName
85
+ };
70
86
  return {
71
87
  bounds,
72
88
  nodeById,
@@ -76,12 +92,12 @@ function figureScene(graph, layout, o) {
76
92
  layers,
77
93
  lift,
78
94
  facet,
79
- panels,
95
+ facets,
80
96
  labelOf: (name) => labels.get(name) ?? name,
81
97
  referenceName,
82
- reference: lift?.referenceDomain && {
83
- ...lift.referenceDomain,
84
- name: referenceName
98
+ keyText: (walk) => {
99
+ const key = walkKey(walk, reference);
100
+ return { note: key.delta + key.outside + key.reversed, scale: key.scale };
85
101
  },
86
102
  contigThickness,
87
103
  nodeWidth,
@@ -1,29 +1,27 @@
1
1
  import {
2
2
  pathSteps
3
- } from "./chunk-XI3ZUTWF.js";
3
+ } from "./chunk-FW2R7UDZ.js";
4
4
  import {
5
5
  pathOrigin
6
- } from "./chunk-M6LK4GII.js";
6
+ } from "./chunk-B5X2RLJG.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 {
@@ -3,10 +3,13 @@ import {
3
3
  } from "./chunk-FX4RDMDN.js";
4
4
  import {
5
5
  referenceOrder
6
- } from "./chunk-CM6LO6OC.js";
6
+ } from "./chunk-UAFATXYA.js";
7
+ import {
8
+ addTo
9
+ } from "./chunk-BSOZW3FC.js";
7
10
  import {
8
11
  isBackbone
9
- } from "./chunk-FYQWPEEY.js";
12
+ } from "./chunk-RJWPJCIB.js";
10
13
 
11
14
  // src/bubbles/bubblesFromGraph.ts
12
15
  function relax(best, to, cur, add) {
@@ -38,7 +41,7 @@ function bubblesFromGraph(graph) {
38
41
  reach[lo + 1]++;
39
42
  reach[hi]--;
40
43
  const [from, to] = a < b ? [e.from, e.to] : [e.to, e.from];
41
- (succ.get(from) ?? succ.set(from, /* @__PURE__ */ new Set()).get(from)).add(to);
44
+ addTo(succ, from, to);
42
45
  }
43
46
  for (let i = 1; i < reach.length; i++) {
44
47
  reach[i] += reach[i - 1];
@@ -72,10 +75,14 @@ function bubblesFromGraph(graph) {
72
75
  relax(best, t, cur, t === end.id ? 0 : byId.get(t).length);
73
76
  }
74
77
  }
75
- const walked = walkIndex && walkRoutes(graph, byId, walkIndex, start.id, end.id);
76
- const crossed = walked?.n ? walked : void 0;
77
- const routes = crossed ?? best.get(end.id) ?? { min: 0, max: 0, n: 0 };
78
- const walksLeave = walked !== void 0 && walked.left > 0;
78
+ const walked = walkRoutes(
79
+ graph,
80
+ byId,
81
+ walkIndex,
82
+ start.id,
83
+ end.id,
84
+ () => best.get(end.id) ?? { min: 0, max: 0, n: 0 }
85
+ );
79
86
  const refStart = start.stable.start + start.length;
80
87
  const refEnd = end.stable.start;
81
88
  const chain = [
@@ -86,26 +93,15 @@ function bubblesFromGraph(graph) {
86
93
  const chainBroken = chain.some(
87
94
  (id, k) => k > 0 && !linked.has(`${chain[k - 1]}>${id}`)
88
95
  );
89
- const partial = chainBroken || walksLeave;
90
- const fallback = chainBroken && !crossed;
91
- bubbles.push({
92
- refName: start.stable.refName,
93
- start: refStart,
94
- end: refEnd,
95
- segmentCount: interior.length + 2,
96
- pathCount: routes.n,
97
- // a real inversion test needs each walk's direction relative to the
98
- // reference; the first visit's strand is just whichever path anchored the
99
- // node
100
- inversion: false,
101
- shortestAlleleLength: fallback ? refEnd - refStart : routes.min,
102
- longestAlleleLength: fallback ? refEnd - refStart : routes.max,
103
- segments: [start, ...interior.map((id) => byId.get(id)), end].map((n) => n.name).join(","),
104
- shortestAllele: void 0,
105
- longestAllele: void 0,
106
- partial,
107
- routes: crossed?.routes
108
- });
96
+ const refLength = refEnd - refStart;
97
+ bubbles.push(
98
+ derivedBubble(
99
+ { refName: start.stable.refName, start: refStart, end: refEnd },
100
+ [start, ...interior.map((id) => byId.get(id)), end],
101
+ chainBroken && !walked.routes ? { ...walked, min: refLength, max: refLength } : walked,
102
+ chainBroken || walked.walksLeave
103
+ )
104
+ );
109
105
  }
110
106
  return bubbles;
111
107
  }
@@ -129,7 +125,10 @@ function walkIndexOf(graph, ids) {
129
125
  });
130
126
  return index;
131
127
  }
132
- function walkRoutes(graph, byId, walkIndex, startId, endId) {
128
+ function walkRoutes(graph, byId, walkIndex, startId, endId, fallback) {
129
+ if (!walkIndex) {
130
+ return { ...fallback(), walksLeave: false };
131
+ }
133
132
  const routes = [];
134
133
  let min = Infinity;
135
134
  let max = -Infinity;
@@ -165,12 +164,29 @@ function walkRoutes(graph, byId, walkIndex, startId, endId) {
165
164
  min = Math.min(min, route.bp);
166
165
  max = Math.max(max, route.bp);
167
166
  });
168
- return routes.length || left ? { min, max, n: routes.length, left, routes } : void 0;
167
+ const walksLeave = left > 0;
168
+ return routes.length ? { min, max, n: routes.length, routes, walksLeave } : { ...fallback(), walksLeave };
169
+ }
170
+ function derivedBubble(place, segments, { min, max, n, routes }, partial) {
171
+ return {
172
+ ...place,
173
+ segmentCount: segments.length,
174
+ pathCount: n,
175
+ inversion: false,
176
+ shortestAlleleLength: min,
177
+ longestAlleleLength: max,
178
+ segments: segments.map((s) => s.name).join(","),
179
+ shortestAllele: void 0,
180
+ longestAllele: void 0,
181
+ partial,
182
+ routes
183
+ };
169
184
  }
170
185
 
171
186
  export {
172
187
  relax,
173
188
  bubblesFromGraph,
174
189
  walkIndexOf,
175
- walkRoutes
190
+ walkRoutes,
191
+ derivedBubble
176
192
  };
@@ -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;