@jbrowse/bandage-core 10.2.7 → 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 (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-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-QBHPHLAQ.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-VV6KGJ7M.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-OIV2GBAJ.js → chunk-DBLV7PGG.js} +27 -17
  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-QXUEF3AJ.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-CG35S2S2.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-EQ2NIFRH.js → chunk-WJ4TIAVA.js} +1 -1
  77. package/dist/chunks/{chunk-A7CFWFQS.js → chunk-WONB6LMC.js} +1 -1
  78. package/dist/chunks/{chunk-23YFB5BB.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-AUFAPUO4.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-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,3 +1,7 @@
1
+ import {
2
+ partitionPoint
3
+ } from "./chunk-HOAIOEI7.js";
4
+
1
5
  // src/tubeMap/warp.ts
2
6
  var MAX_GAP_PX = 24;
3
7
  var MAX_GAP_SHARE = 0.5;
@@ -55,17 +59,8 @@ function warpX(knots, tx) {
55
59
  if (tx >= last.tx) {
56
60
  return last.sx + (tx - last.tx);
57
61
  }
58
- let lo = 0;
59
- let hi = n - 1;
60
- while (hi - lo > 1) {
61
- const mid = lo + hi >> 1;
62
- if (knots[mid].tx <= tx) {
63
- lo = mid;
64
- } else {
65
- hi = mid;
66
- }
67
- }
68
- const a = knots[lo];
62
+ const hi = 1 + partitionPoint(n - 2, (i) => knots[i + 1].tx <= tx);
63
+ const a = knots[hi - 1];
69
64
  const b = knots[hi];
70
65
  const span = b.tx - a.tx;
71
66
  return span > 0 ? a.sx + (tx - a.tx) / span * (b.sx - a.sx) : a.sx;
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  projectAlleles
3
- } from "./chunk-RVS2QCOX.js";
3
+ } from "./chunk-3GLG3ZLE.js";
4
4
  import {
5
5
  buildNeighbors
6
- } from "./chunk-ES2N6V56.js";
6
+ } from "./chunk-VX656OAZ.js";
7
7
 
8
8
  // src/layout/placeOffReference.ts
9
9
  var MIN_DELETION_BP = 1;
@@ -1,12 +1,15 @@
1
1
  import {
2
2
  EdgeSpatialIndex,
3
3
  SpatialIndex
4
- } from "./chunk-KBEP7VYK.js";
4
+ } from "./chunk-3VCKBSML.js";
5
+ import {
6
+ weakMemo
7
+ } from "./chunk-HMXCN6PG.js";
5
8
  import {
6
9
  pathRibbonOffsets,
7
10
  translateCurves,
8
11
  yToXOf
9
- } from "./chunk-7SRWJLSC.js";
12
+ } from "./chunk-UBQSRCWR.js";
10
13
 
11
14
  // src/util/hitDetection.ts
12
15
  function distanceToSegment(px, py, x1, y1, x2, y2) {
@@ -19,40 +22,26 @@ function distanceToSegment(px, py, x1, y1, x2, y2) {
19
22
  const t = Math.max(0, Math.min(1, ((px - x1) * dx + (py - y1) * dy) / lenSq));
20
23
  return Math.hypot(px - (x1 + t * dx), py - (y1 + t * dy));
21
24
  }
22
- function distanceToCubicBezier(px, py, x1, y1, cx1, cy1, cx2, cy2, x2, y2) {
25
+ function distanceToCubicBezier(px, py, c) {
23
26
  let minDist = Infinity;
24
27
  const samples = 20;
25
- let lastX = x1;
26
- let lastY = y1;
28
+ let lastX = c.x0;
29
+ let lastY = c.y0;
27
30
  for (let i = 1; i <= samples; i++) {
28
31
  const t = i / samples;
29
32
  const u = 1 - t;
30
- const bx = u * u * u * x1 + 3 * u * u * t * cx1 + 3 * u * t * t * cx2 + t * t * t * x2;
31
- const by = u * u * u * y1 + 3 * u * u * t * cy1 + 3 * u * t * t * cy2 + t * t * t * y2;
33
+ const bx = u * u * u * c.x0 + 3 * u * u * t * c.cx0 + 3 * u * t * t * c.cx1 + t * t * t * c.x1;
34
+ const by = u * u * u * c.y0 + 3 * u * u * t * c.cy0 + 3 * u * t * t * c.cy1 + t * t * t * c.y1;
32
35
  minDist = Math.min(minDist, distanceToSegment(px, py, lastX, lastY, bx, by));
33
36
  lastX = bx;
34
37
  lastY = by;
35
38
  }
36
39
  return minDist;
37
40
  }
38
- function distanceToBezierCurve(px, py, c) {
39
- return distanceToCubicBezier(
40
- px,
41
- py,
42
- c.x0,
43
- c.y0,
44
- c.cx0,
45
- c.cy0,
46
- c.cx1,
47
- c.cy1,
48
- c.x1,
49
- c.y1
50
- );
51
- }
52
41
  function distanceToEdgeCurves(px, py, curves, yToX = 1) {
53
42
  let minDist = Infinity;
54
43
  for (const c of curves) {
55
- const d = distanceToBezierCurve(
44
+ const d = distanceToCubicBezier(
56
45
  px,
57
46
  py,
58
47
  yToX === 1 ? c : {
@@ -72,45 +61,39 @@ function distanceToEdgeCurves(px, py, curves, yToX = 1) {
72
61
  }
73
62
  return minDist;
74
63
  }
75
- var nodeCache = /* @__PURE__ */ new WeakMap();
64
+ var nodeCache = weakMemo();
76
65
  function getSpatialIndex(nodePositions, version) {
77
- const cached = nodeCache.get(nodePositions);
78
- if (cached?.version === version) {
79
- return cached.index;
80
- }
81
- const index = new SpatialIndex(nodePositions);
82
- nodeCache.set(nodePositions, { version, index });
83
- return index;
66
+ return nodeCache(
67
+ nodePositions,
68
+ [version],
69
+ () => new SpatialIndex(nodePositions)
70
+ );
84
71
  }
85
- var edgeCache = /* @__PURE__ */ new WeakMap();
72
+ var edgeCache = weakMemo();
86
73
  function getEdgeSpatialIndex(nodePositions, graph, drawPaths, axis, version, deletions, routes, stranded = false) {
87
- const cached = edgeCache.get(nodePositions);
88
- 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) {
89
- return cached.index;
90
- }
91
- const index = new EdgeSpatialIndex(
74
+ return edgeCache(
92
75
  nodePositions,
93
- graph,
94
- drawPaths,
95
- axis,
96
- void 0,
97
- deletions,
98
- version,
99
- routes,
100
- stranded
76
+ [
77
+ graph,
78
+ drawPaths,
79
+ axis.scaleX,
80
+ axis.scaleY,
81
+ version,
82
+ deletions,
83
+ routes,
84
+ stranded
85
+ ],
86
+ () => new EdgeSpatialIndex(
87
+ nodePositions,
88
+ graph,
89
+ drawPaths,
90
+ axis,
91
+ deletions,
92
+ version,
93
+ routes,
94
+ stranded
95
+ )
101
96
  );
102
- edgeCache.set(nodePositions, {
103
- graph,
104
- drawPaths,
105
- scaleX: axis.scaleX,
106
- scaleY: axis.scaleY,
107
- version,
108
- index,
109
- deletions,
110
- routes,
111
- stranded
112
- });
113
- return index;
114
97
  }
115
98
  var MIN_NODE_REACH_PX = 5;
116
99
  function findHoveredNode(nodePositions, graphX, graphY, axis, version = 0, ink) {
@@ -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-LGJBB5BP.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
 
@@ -1,5 +1,5 @@
1
1
  // src/version.ts
2
- var version = "10.2.7";
2
+ var version = "10.3.0";
3
3
 
4
4
  export {
5
5
  version
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  walkRows
3
- } from "./chunk-LKW2TP4N.js";
3
+ } from "./chunk-5YILQTHE.js";
4
4
  import {
5
5
  ROW_HEIGHT_PX
6
6
  } from "./chunk-CPMHA4W5.js";
@@ -8,20 +8,19 @@ import {
8
8
  backboneNodes,
9
9
  backbonePositions,
10
10
  overlapsWindow
11
- } from "./chunk-FYQWPEEY.js";
11
+ } from "./chunk-RJWPJCIB.js";
12
12
 
13
13
  // src/layout/walkRowLayout.ts
14
14
  var READOUT_ROOM = 1.3;
15
+ function longestBar(walks) {
16
+ return Math.max(walks.reference.bp, ...walks.rows.map((r) => r.bp));
17
+ }
15
18
  function walkRowsExtent(walks, pitch = {
16
19
  rowPx: ROW_HEIGHT_PX,
17
20
  readouts: true
18
21
  }) {
19
- let longest = walks.reference.bp;
20
- for (const row of walks.rows) {
21
- longest = Math.max(longest, row.bp);
22
- }
23
22
  return {
24
- maxX: walks.origin + longest * (pitch.readouts ? READOUT_ROOM : 1),
23
+ maxX: walks.origin + longestBar(walks) * (pitch.readouts ? READOUT_ROOM : 1),
25
24
  maxY: walks.rows.length * pitch.rowPx
26
25
  };
27
26
  }
@@ -58,6 +57,7 @@ function walkRowLayout(graph, region) {
58
57
 
59
58
  export {
60
59
  READOUT_ROOM,
60
+ longestBar,
61
61
  walkRowsExtent,
62
62
  walkRowLabels,
63
63
  walkRowLayout
@@ -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;