@jbrowse/bandage-core 11.5.0 → 11.6.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 (138) hide show
  1. package/dist/alleleProjection/projectAlleles.js +1 -1
  2. package/dist/bubbles/bubbleHalos.js +9 -6
  3. package/dist/bubbles/classifyBubble.js +8 -5
  4. package/dist/bubbles/popBubble.js +3 -3
  5. package/dist/bubbles/superbubbles.js +11 -11
  6. package/dist/chunks/{chunk-FFHJGWDK.js → chunk-2C5SATRZ.js} +5 -5
  7. package/dist/chunks/{chunk-4XWZNPQ2.js → chunk-2JL2JVZ2.js} +1 -1
  8. package/dist/chunks/{chunk-BZFOFC4D.js → chunk-2VMKQKVO.js} +17 -7
  9. package/dist/chunks/{chunk-HN3WHMPJ.js → chunk-2XEAITWM.js} +15 -5
  10. package/dist/chunks/{chunk-7BTO7MZS.js → chunk-376YFQOY.js} +2 -2
  11. package/dist/chunks/{chunk-K5LDBMLX.js → chunk-3FWNQNF7.js} +1 -1
  12. package/dist/chunks/{chunk-B5X2RLJG.js → chunk-3YBP46PB.js} +27 -2
  13. package/dist/chunks/{chunk-EJRJAAN7.js → chunk-4DMSPNYV.js} +47 -27
  14. package/dist/chunks/{chunk-A32ZKSHN.js → chunk-4WXFQOYV.js} +5 -5
  15. package/dist/chunks/{chunk-OMUPUB4J.js → chunk-56L6R6D2.js} +2 -2
  16. package/dist/chunks/{chunk-C44YRP5F.js → chunk-5OJZV6YT.js} +3 -2
  17. package/dist/chunks/{chunk-234NFZS4.js → chunk-5ORP7EFJ.js} +1 -1
  18. package/dist/chunks/{chunk-J3JODFDF.js → chunk-5WB7O7IT.js} +3 -3
  19. package/dist/chunks/{chunk-3VCKBSML.js → chunk-6YRSOL4K.js} +2 -2
  20. package/dist/chunks/{chunk-WG5D2H7X.js → chunk-7OTWJQGA.js} +10 -10
  21. package/dist/chunks/{chunk-77EGQQJU.js → chunk-BFUS3ENH.js} +2 -2
  22. package/dist/chunks/{chunk-TGUFT6KK.js → chunk-BLUEFYIR.js} +4 -1
  23. package/dist/chunks/{chunk-3BCVMZUT.js → chunk-BVWMVWLJ.js} +10 -10
  24. package/dist/chunks/{chunk-3GP3KT5L.js → chunk-BW2NMXRV.js} +5 -5
  25. package/dist/chunks/{chunk-2E25TX4G.js → chunk-C6E6HXP5.js} +4 -4
  26. package/dist/chunks/{chunk-5I3K4R2G.js → chunk-CFXXFHRK.js} +2 -1
  27. package/dist/chunks/{chunk-JMABOQWL.js → chunk-CO6RGQAD.js} +1 -6
  28. package/dist/chunks/{chunk-64FCX424.js → chunk-D3E7AXBB.js} +40 -9
  29. package/dist/chunks/{chunk-CGMSKIEO.js → chunk-DV5B5UU7.js} +55 -8
  30. package/dist/chunks/{chunk-G6UIYQZR.js → chunk-EQDQ7P4Y.js} +3 -2
  31. package/dist/chunks/{chunk-VQ7474EH.js → chunk-EVXXFMZ7.js} +8 -7
  32. package/dist/chunks/{chunk-AKLSY4GD.js → chunk-F3KQQDKP.js} +1 -1
  33. package/dist/chunks/{chunk-6EOB6ANX.js → chunk-GZ36HNPJ.js} +1 -1
  34. package/dist/chunks/{chunk-3U3C4PRK.js → chunk-HV35LDYH.js} +3 -3
  35. package/dist/chunks/{chunk-JOWKKQAL.js → chunk-JGHZ3N34.js} +14 -9
  36. package/dist/chunks/{chunk-D4ZFRBB4.js → chunk-JGQQAUVL.js} +3 -3
  37. package/dist/chunks/{chunk-PSCSZSVK.js → chunk-KA4F3N55.js} +4 -4
  38. package/dist/chunks/{chunk-SOMZGDVS.js → chunk-KJDERUQF.js} +1 -1
  39. package/dist/chunks/{chunk-E4ZM4OOJ.js → chunk-KZMSSPS6.js} +2 -2
  40. package/dist/chunks/{chunk-IOWLTUEB.js → chunk-MEVTV4FI.js} +1 -1
  41. package/dist/chunks/{chunk-PNMJFFNB.js → chunk-MHZTTLBU.js} +1 -1
  42. package/dist/chunks/{chunk-TRGKMLXT.js → chunk-MXLYBDOX.js} +14 -13
  43. package/dist/chunks/{chunk-RK3HRRCW.js → chunk-NXBW6KY6.js} +6 -7
  44. package/dist/chunks/{chunk-WC6HX6GJ.js → chunk-OUM54ZSQ.js} +2 -2
  45. package/dist/chunks/{chunk-WA5WNP6V.js → chunk-OYCQVJYY.js} +1 -1
  46. package/dist/chunks/{chunk-FWSERUJV.js → chunk-P5PBJONQ.js} +1 -1
  47. package/dist/chunks/{chunk-JOLLU34X.js → chunk-PQIFYQVI.js} +1 -1
  48. package/dist/chunks/{chunk-EGBBIXTG.js → chunk-QCOVHLJO.js} +1 -1
  49. package/dist/chunks/{chunk-5F4D35U5.js → chunk-QD35GH4C.js} +3 -3
  50. package/dist/chunks/{chunk-XKZ56L5A.js → chunk-RLCYVZ4B.js} +1 -1
  51. package/dist/chunks/{chunk-PQBALYSO.js → chunk-ROLACYCO.js} +16 -16
  52. package/dist/chunks/{chunk-A7H753BA.js → chunk-SDI6BVG7.js} +5 -6
  53. package/dist/chunks/{chunk-A4JDEUAI.js → chunk-SNF2MIEF.js} +1 -1
  54. package/dist/chunks/{chunk-NMWQUFPF.js → chunk-SVVFWTG4.js} +2 -2
  55. package/dist/chunks/{chunk-PFRQBCGC.js → chunk-T3H5ELLA.js} +4 -4
  56. package/dist/chunks/{chunk-WLR4KJVI.js → chunk-TXTSE44S.js} +1 -1
  57. package/dist/chunks/{chunk-UBQSRCWR.js → chunk-VACK24HF.js} +43 -3
  58. package/dist/chunks/{chunk-HSVFCA2J.js → chunk-VO6FKNZE.js} +1 -1
  59. package/dist/chunks/{chunk-NJGYLYU7.js → chunk-W2YAW36J.js} +1 -1
  60. package/dist/chunks/{chunk-VD4MLYEK.js → chunk-WI6SUU5B.js} +2 -2
  61. package/dist/chunks/{chunk-GJU6BJJA.js → chunk-XR2HMGAS.js} +1 -1
  62. package/dist/chunks/{chunk-KOJKFNCW.js → chunk-XXOBCANT.js} +26 -12
  63. package/dist/chunks/{chunk-7EDGWT67.js → chunk-YEYQFNFQ.js} +1 -1
  64. package/dist/chunks/{chunk-UFUSPK2A.js → chunk-YYIU7P73.js} +4 -1
  65. package/dist/chunks/{chunk-CRCD3ODN.js → chunk-ZANALBSX.js} +11 -3
  66. package/dist/cli/figure.js +51 -46
  67. package/dist/cli/fold.js +11 -11
  68. package/dist/deletionEdges.js +5 -2
  69. package/dist/facetGrid.js +2 -2
  70. package/dist/figure.js +35 -35
  71. package/dist/figureData.js +37 -37
  72. package/dist/figureScene.js +25 -25
  73. package/dist/figureSettings.js +11 -11
  74. package/dist/foldVariants.js +2 -2
  75. package/dist/gaf/parseGaf.js +1 -1
  76. package/dist/gbzCut.js +4 -4
  77. package/dist/gbzWindow.js +3 -3
  78. package/dist/genes/backboneGenes.js +4 -4
  79. package/dist/genes/geneFiles.js +1 -1
  80. package/dist/genes/genePins.js +3 -3
  81. package/dist/gfa/gfaConverter.js +4 -4
  82. package/dist/gfa/graphTables.js +2 -2
  83. package/dist/gfa-core/gfaParser.js +1 -1
  84. package/dist/gfa-core/index.js +1 -1
  85. package/dist/graphLabels.js +7 -4
  86. package/dist/index.js +62 -62
  87. package/dist/labelLayout.js +11 -8
  88. package/dist/layout/anchoredLayout.js +1 -1
  89. package/dist/layout/forceCache.js +11 -11
  90. package/dist/layout/mergeRuns.js +2 -2
  91. package/dist/layout/placeOffReference.js +1 -1
  92. package/dist/layout/sampleRowLayout.js +2 -2
  93. package/dist/layout/trimToWindow.js +2 -2
  94. package/dist/layout/tubeMapLayout.js +14 -14
  95. package/dist/layout/walkRowDraw.js +12 -12
  96. package/dist/layout/walkRowLayout.js +7 -7
  97. package/dist/layout/walkRowLinks.js +1 -1
  98. package/dist/layout/walkRowRuns.js +4 -4
  99. package/dist/layout/walkRows.js +5 -5
  100. package/dist/layout/walkStrip.js +17 -17
  101. package/dist/layoutEngines.js +1 -1
  102. package/dist/layoutModes.js +17 -17
  103. package/dist/locus.js +1 -1
  104. package/dist/nodeWidths.js +5 -3
  105. package/dist/pansn.js +1 -1
  106. package/dist/pathAnchoring.js +4 -2
  107. package/dist/pathColors.js +8 -8
  108. package/dist/pipeline.js +10 -10
  109. package/dist/reference.js +2 -2
  110. package/dist/referenceStrip.js +12 -12
  111. package/dist/renderer/Canvas2DRenderer.js +1 -1
  112. package/dist/renderer/GeometryBuilder.js +11 -11
  113. package/dist/tubeMap/axis.js +8 -5
  114. package/dist/tubeMap/bundle.js +15 -15
  115. package/dist/tubeMap/coarsen.js +15 -15
  116. package/dist/tubeMap/deviations.js +18 -18
  117. package/dist/tubeMap/draw.js +10 -8
  118. package/dist/tubeMap/genes.js +9 -6
  119. package/dist/tubeMap/nodeColors.js +12 -12
  120. package/dist/tubeMap/reads.js +4 -4
  121. package/dist/types/figureData.d.ts +12 -0
  122. package/dist/types/gaf/parseGaf.d.ts +1 -1
  123. package/dist/types/nodeWidths.d.ts +2 -1
  124. package/dist/types/pathAnchoring.d.ts +2 -0
  125. package/dist/types/renderer/Canvas2DRenderer.d.ts +2 -0
  126. package/dist/types/tubeMap/reads.d.ts +0 -1
  127. package/dist/types/util/geometry.d.ts +7 -1
  128. package/dist/types/version.d.ts +1 -1
  129. package/dist/util/SpatialIndex.js +7 -4
  130. package/dist/util/edgeCurves.js +6 -3
  131. package/dist/util/geometry.js +1 -1
  132. package/dist/util/hitDetection.js +8 -5
  133. package/dist/version.js +1 -1
  134. package/dist/viewport.js +11 -11
  135. package/dist/walkEncoding.js +12 -12
  136. package/dist/walkHighlight.js +13 -13
  137. package/dist/walkKey.js +8 -5
  138. package/package.json +1 -1
@@ -7,7 +7,7 @@ import "../chunks/chunk-RJWPJCIB.js";
7
7
  import "../chunks/chunk-HOAIOEI7.js";
8
8
  import {
9
9
  parsePanSN
10
- } from "../chunks/chunk-4XWZNPQ2.js";
10
+ } from "../chunks/chunk-2JL2JVZ2.js";
11
11
  export {
12
12
  parsePanSN,
13
13
  projectAlleles
@@ -1,19 +1,22 @@
1
1
  import {
2
2
  bubbleHalos,
3
3
  coversGraph
4
- } from "../chunks/chunk-E4ZM4OOJ.js";
5
- import "../chunks/chunk-A4JDEUAI.js";
4
+ } from "../chunks/chunk-KZMSSPS6.js";
5
+ import "../chunks/chunk-SNF2MIEF.js";
6
6
  import "../chunks/chunk-FX4RDMDN.js";
7
- import "../chunks/chunk-PFRQBCGC.js";
7
+ import "../chunks/chunk-T3H5ELLA.js";
8
8
  import "../chunks/chunk-HMXCN6PG.js";
9
9
  import "../chunks/chunk-AB35TJST.js";
10
- import "../chunks/chunk-BZFOFC4D.js";
11
- import "../chunks/chunk-CGMSKIEO.js";
12
- import "../chunks/chunk-UBQSRCWR.js";
10
+ import "../chunks/chunk-2VMKQKVO.js";
11
+ import "../chunks/chunk-DV5B5UU7.js";
12
+ import "../chunks/chunk-3YBP46PB.js";
13
+ import "../chunks/chunk-VACK24HF.js";
13
14
  import "../chunks/chunk-CPMHA4W5.js";
15
+ import "../chunks/chunk-ZPZ7GNBT.js";
14
16
  import "../chunks/chunk-BSOZW3FC.js";
15
17
  import "../chunks/chunk-RJWPJCIB.js";
16
18
  import "../chunks/chunk-HOAIOEI7.js";
19
+ import "../chunks/chunk-2JL2JVZ2.js";
17
20
  export {
18
21
  bubbleHalos,
19
22
  coversGraph
@@ -3,18 +3,21 @@ import {
3
3
  BUBBLE_KIND_NAMES,
4
4
  bubbleSegmentIds,
5
5
  classifyBubble
6
- } from "../chunks/chunk-A4JDEUAI.js";
6
+ } from "../chunks/chunk-SNF2MIEF.js";
7
7
  import "../chunks/chunk-FX4RDMDN.js";
8
- import "../chunks/chunk-PFRQBCGC.js";
8
+ import "../chunks/chunk-T3H5ELLA.js";
9
9
  import "../chunks/chunk-HMXCN6PG.js";
10
10
  import "../chunks/chunk-AB35TJST.js";
11
- import "../chunks/chunk-BZFOFC4D.js";
12
- import "../chunks/chunk-CGMSKIEO.js";
13
- import "../chunks/chunk-UBQSRCWR.js";
11
+ import "../chunks/chunk-2VMKQKVO.js";
12
+ import "../chunks/chunk-DV5B5UU7.js";
13
+ import "../chunks/chunk-3YBP46PB.js";
14
+ import "../chunks/chunk-VACK24HF.js";
14
15
  import "../chunks/chunk-CPMHA4W5.js";
16
+ import "../chunks/chunk-ZPZ7GNBT.js";
15
17
  import "../chunks/chunk-BSOZW3FC.js";
16
18
  import "../chunks/chunk-RJWPJCIB.js";
17
19
  import "../chunks/chunk-HOAIOEI7.js";
20
+ import "../chunks/chunk-2JL2JVZ2.js";
18
21
  export {
19
22
  BUBBLE_KIND_COLORS,
20
23
  BUBBLE_KIND_NAMES,
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  bubbleSubgraph
3
- } from "../chunks/chunk-PNMJFFNB.js";
4
- import "../chunks/chunk-B5X2RLJG.js";
3
+ } from "../chunks/chunk-MHZTTLBU.js";
4
+ import "../chunks/chunk-3YBP46PB.js";
5
5
  import "../chunks/chunk-ZPZ7GNBT.js";
6
6
  import "../chunks/chunk-BSOZW3FC.js";
7
7
  import "../chunks/chunk-RJWPJCIB.js";
8
8
  import "../chunks/chunk-HOAIOEI7.js";
9
- import "../chunks/chunk-4XWZNPQ2.js";
9
+ import "../chunks/chunk-2JL2JVZ2.js";
10
10
  export {
11
11
  bubbleSubgraph
12
12
  };
@@ -1,27 +1,27 @@
1
1
  import {
2
2
  graphBubbles,
3
3
  superbubblesFromGraph
4
- } from "../chunks/chunk-2E25TX4G.js";
5
- import "../chunks/chunk-E4ZM4OOJ.js";
4
+ } from "../chunks/chunk-C6E6HXP5.js";
5
+ import "../chunks/chunk-KZMSSPS6.js";
6
6
  import "../chunks/chunk-RFG42VIO.js";
7
- import "../chunks/chunk-A4JDEUAI.js";
7
+ import "../chunks/chunk-SNF2MIEF.js";
8
8
  import "../chunks/chunk-FX4RDMDN.js";
9
- import "../chunks/chunk-PNMJFFNB.js";
9
+ import "../chunks/chunk-MHZTTLBU.js";
10
10
  import "../chunks/chunk-UAFATXYA.js";
11
- import "../chunks/chunk-B5X2RLJG.js";
12
11
  import "../chunks/chunk-VX656OAZ.js";
13
- import "../chunks/chunk-ZPZ7GNBT.js";
14
- import "../chunks/chunk-PFRQBCGC.js";
12
+ import "../chunks/chunk-T3H5ELLA.js";
15
13
  import "../chunks/chunk-HMXCN6PG.js";
16
14
  import "../chunks/chunk-AB35TJST.js";
17
- import "../chunks/chunk-BZFOFC4D.js";
18
- import "../chunks/chunk-CGMSKIEO.js";
19
- import "../chunks/chunk-UBQSRCWR.js";
15
+ import "../chunks/chunk-2VMKQKVO.js";
16
+ import "../chunks/chunk-DV5B5UU7.js";
17
+ import "../chunks/chunk-3YBP46PB.js";
18
+ import "../chunks/chunk-VACK24HF.js";
20
19
  import "../chunks/chunk-CPMHA4W5.js";
20
+ import "../chunks/chunk-ZPZ7GNBT.js";
21
21
  import "../chunks/chunk-BSOZW3FC.js";
22
22
  import "../chunks/chunk-RJWPJCIB.js";
23
23
  import "../chunks/chunk-HOAIOEI7.js";
24
- import "../chunks/chunk-4XWZNPQ2.js";
24
+ import "../chunks/chunk-2JL2JVZ2.js";
25
25
  export {
26
26
  graphBubbles,
27
27
  superbubblesFromGraph
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  stableCoordinate
3
- } from "./chunk-5I3K4R2G.js";
4
- import {
5
- pathOrigin,
6
- surveyPaths
7
- } from "./chunk-B5X2RLJG.js";
3
+ } from "./chunk-CFXXFHRK.js";
8
4
  import {
9
5
  walkStopFields
10
6
  } from "./chunk-EIY2SKD3.js";
7
+ import {
8
+ pathOrigin,
9
+ surveyPaths
10
+ } from "./chunk-3YBP46PB.js";
11
11
 
12
12
  // src/gfa/gfaConverter.ts
13
13
  function surveySegments(gfaGraph, pathSteps) {
@@ -21,7 +21,7 @@ function panSNFields(name) {
21
21
  }
22
22
  function parsePanSN(refName) {
23
23
  const parts = refName.split(SEP);
24
- const haplotype = parts.length >= 2 ? Number(parts[1]) : Number.NaN;
24
+ const haplotype = parts.length >= 2 && parts[1] !== "" ? Number(parts[1]) : Number.NaN;
25
25
  return {
26
26
  sample: parts[0],
27
27
  haplotype: Number.isFinite(haplotype) ? haplotype : void 0
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  ownStrand,
3
3
  strandSides
4
- } from "./chunk-UBQSRCWR.js";
4
+ } from "./chunk-VACK24HF.js";
5
5
  import {
6
6
  pushTo
7
7
  } from "./chunk-BSOZW3FC.js";
@@ -151,14 +151,24 @@ function arcPrefix(line) {
151
151
  }
152
152
  return arc;
153
153
  }
154
+ function firstReaching(arc, s) {
155
+ let lo = 0;
156
+ let hi = arc.length;
157
+ while (lo < hi) {
158
+ const mid = lo + hi >> 1;
159
+ if (arc[mid] < s) {
160
+ lo = mid + 1;
161
+ } else {
162
+ hi = mid;
163
+ }
164
+ }
165
+ return lo;
166
+ }
154
167
  function pointAt(line, arc, s) {
155
168
  if (s <= 0) {
156
169
  return { ...line[0] };
157
170
  }
158
- let i = 1;
159
- while (i < arc.length && arc[i] < s) {
160
- i++;
161
- }
171
+ const i = firstReaching(arc, s);
162
172
  if (i >= arc.length) {
163
173
  return { ...line.at(-1) };
164
174
  }
@@ -170,8 +180,8 @@ function pointAt(line, arc, s) {
170
180
  }
171
181
  function slice(line, arc, from, to) {
172
182
  const points = [pointAt(line, arc, from)];
173
- for (let i = 0; i < line.length; i++) {
174
- if (arc[i] > from && arc[i] < to) {
183
+ for (let i = firstReaching(arc, from); i < line.length && arc[i] < to; i++) {
184
+ if (arc[i] > from) {
175
185
  points.push({ ...line[i] });
176
186
  }
177
187
  }
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  REFERENCE_RAMP_ALT_COLOR,
3
3
  hslToRgb
4
- } from "./chunk-JOWKKQAL.js";
4
+ } from "./chunk-JGHZ3N34.js";
5
5
  import {
6
6
  packAbgr
7
7
  } from "./chunk-G2FD7S3C.js";
@@ -61,18 +61,28 @@ function oklabToRgb([L, a, b]) {
61
61
  -0.0041960863 * l - 0.7034186147 * m + 1.707614701 * s
62
62
  ].map((c) => toGamma(Math.max(0, Math.min(1, c))) * 255);
63
63
  }
64
+ var endsCache = /* @__PURE__ */ new Map();
65
+ function oklabEnds(scheme) {
66
+ if (!endsCache.has(scheme)) {
67
+ const family = WALK_SCHEMES.find((s) => s.value === scheme);
68
+ endsCache.set(
69
+ scheme,
70
+ family && "ends" in family ? family.ends.map(oklab) : void 0
71
+ );
72
+ }
73
+ return endsCache.get(scheme);
74
+ }
64
75
  function schemeRgb(scheme, t) {
65
76
  const x = Math.max(0, Math.min(1, t));
66
- const family = WALK_SCHEMES.find((s) => s.value === scheme);
67
- if (!family || !("ends" in family)) {
77
+ const ends = oklabEnds(scheme);
78
+ if (!ends) {
68
79
  return hslToRgb(
69
80
  rampHueAt(x),
70
81
  REFERENCE_RAMP_SATURATION,
71
82
  REFERENCE_RAMP_LIGHTNESS
72
83
  ).map((c) => c * 255);
73
84
  }
74
- const from = oklab(family.ends[0]);
75
- const to = oklab(family.ends[1]);
85
+ const [from, to] = ends;
76
86
  return oklabToRgb(from.map((v, i) => v + (to[i] - v) * x));
77
87
  }
78
88
  function schemeCss(scheme, t) {
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  genesFromText
3
- } from "./chunk-G6UIYQZR.js";
3
+ } from "./chunk-EQDQ7P4Y.js";
4
4
  import {
5
5
  featuresOnBackbone,
6
6
  graphBackbone,
7
7
  refNameBinding
8
- } from "./chunk-234NFZS4.js";
8
+ } from "./chunk-5ORP7EFJ.js";
9
9
 
10
10
  // src/genes/backboneGenes.ts
11
11
  async function backboneGenes(graph, source) {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  ENGINE_DEFAULTS
3
- } from "./chunk-WG5D2H7X.js";
3
+ } from "./chunk-7OTWJQGA.js";
4
4
 
5
5
  // src/figureSettings.ts
6
6
  var FIGURE_DEFAULTS = {
@@ -9,7 +9,7 @@ import {
9
9
  } from "./chunk-RJWPJCIB.js";
10
10
  import {
11
11
  panSNSample
12
- } from "./chunk-4XWZNPQ2.js";
12
+ } from "./chunk-2JL2JVZ2.js";
13
13
 
14
14
  // src/pathAnchoring.ts
15
15
  var RANGE_SUFFIX = /:(\d+)-\d+$/;
@@ -155,6 +155,30 @@ function trimOrigins(graph, kept) {
155
155
  } : o;
156
156
  });
157
157
  }
158
+ function referenceVisitStarts(graph) {
159
+ const { pathVisits } = graph;
160
+ const cache = /* @__PURE__ */ new Map();
161
+ return (node) => {
162
+ let starts = cache.get(node.id);
163
+ if (!starts) {
164
+ starts = [];
165
+ const slot = pathVisits ? pathVisits.slot(node.name) : -1;
166
+ const p = slot >= 0 ? pathVisits.pathIndex(node.stable.refName) : -1;
167
+ if (p >= 0) {
168
+ for (let i = pathVisits.offsets[slot]; i < pathVisits.offsets[slot + 1]; i++) {
169
+ if (pathVisits.path[i] === p) {
170
+ starts.push(pathVisits.start[i]);
171
+ }
172
+ }
173
+ }
174
+ if (starts.length < 2) {
175
+ starts = [node.stable.start];
176
+ }
177
+ cache.set(node.id, starts);
178
+ }
179
+ return starts;
180
+ };
181
+ }
158
182
 
159
183
  export {
160
184
  pathOrigin,
@@ -162,5 +186,6 @@ export {
162
186
  chooseReferencePath,
163
187
  anchorFromPaths,
164
188
  anchorGraph,
165
- trimOrigins
189
+ trimOrigins,
190
+ referenceVisitStarts
166
191
  };
@@ -17,6 +17,7 @@ var Canvas2DRenderer = class {
17
17
  this.highlightedEdge = null;
18
18
  this.highlightFactor = 1;
19
19
  this.fit = 1;
20
+ this.painted = null;
20
21
  const ctx = canvas.getContext("2d");
21
22
  if (!ctx) {
22
23
  throw new Error("Canvas 2D context not available");
@@ -37,13 +38,16 @@ var Canvas2DRenderer = class {
37
38
  uploadGeometry(batch) {
38
39
  this.batch = batch;
39
40
  this.highlightedEdge = null;
41
+ this.painted = null;
40
42
  }
41
43
  setNodeHighlights(factors) {
42
44
  this.nodeHighlights = factors;
45
+ this.painted = null;
43
46
  }
44
47
  setEdgeHighlight(edgeIndex, factor) {
45
48
  this.highlightedEdge = edgeIndex;
46
49
  this.highlightFactor = factor;
50
+ this.painted = null;
47
51
  }
48
52
  updateTransform(transform) {
49
53
  this.transform = transform;
@@ -70,46 +74,61 @@ var Canvas2DRenderer = class {
70
74
  if (clearColor[3] < 1) {
71
75
  ctx.clearRect(0, 0, width, height);
72
76
  }
73
- ctx.fillStyle = normalizedRgbToCssRgba(
74
- [clearColor[0], clearColor[1], clearColor[2]],
75
- clearColor[3]
76
- );
77
- ctx.fillRect(0, 0, width, height);
77
+ if (clearColor[3] > 0) {
78
+ ctx.fillStyle = normalizedRgbToCssRgba(
79
+ [clearColor[0], clearColor[1], clearColor[2]],
80
+ clearColor[3]
81
+ );
82
+ ctx.fillRect(0, 0, width, height);
83
+ }
78
84
  const batch = this.batch;
79
85
  if (!batch) {
80
86
  return;
81
87
  }
82
88
  ctx.lineCap = "round";
83
89
  ctx.lineJoin = "round";
84
- const factor = this.highlightFactor;
85
- const edgeRun = this.edgeRun(batch.edgeCurveRuns);
86
- for (const { color, items } of groupByPaint(batch.edgeCurves, (e, i) => ({
87
- color: inRun(edgeRun, i) ? brightenAbgr(e.color, factor) : e.color,
88
- weight: e.thickness,
89
- last: inRun(edgeRun, i)
90
- }))) {
90
+ const { edges, nodes, arrows } = this.paintedGroups(batch);
91
+ for (const { color, items } of edges) {
91
92
  this.strokeCurves(items, color, t);
92
93
  }
93
- const lifted = this.liftedStrokes(batch);
94
- for (const { color, items } of groupByPaint(batch.nodeStrokes, (s, i) => {
95
- const f = lifted.get(i);
96
- return {
97
- color: f === void 0 ? s.color : brightenAbgr(s.color, f),
98
- weight: s.thickness,
99
- last: f !== void 0
100
- };
101
- })) {
94
+ for (const { color, items } of nodes) {
102
95
  this.strokeNodes(items, color, t);
103
96
  }
104
- const arrowRun = this.edgeRun(batch.arrowRuns);
105
- for (const { color, items } of groupByPaint(batch.arrows, (a, i) => ({
106
- color: inRun(arrowRun, i) ? brightenAbgr(a.color, factor) : a.color,
107
- weight: 0,
108
- last: inRun(arrowRun, i)
109
- }))) {
97
+ for (const { color, items } of arrows) {
110
98
  this.fillArrows(items, color, t);
111
99
  }
112
100
  }
101
+ // Grouping depends on the batch and the highlights, not on the transform, so
102
+ // a pan or zoom redraws from the groups it already has
103
+ paintedGroups(batch) {
104
+ if (this.painted) {
105
+ return this.painted;
106
+ }
107
+ const factor = this.highlightFactor;
108
+ const edgeRun = this.edgeRun(batch.edgeCurveRuns);
109
+ const arrowRun = this.edgeRun(batch.arrowRuns);
110
+ const lifted = this.liftedStrokes(batch);
111
+ return this.painted = {
112
+ edges: groupByPaint(batch.edgeCurves, (e, i) => ({
113
+ color: inRun(edgeRun, i) ? brightenAbgr(e.color, factor) : e.color,
114
+ weight: e.thickness,
115
+ last: inRun(edgeRun, i)
116
+ })),
117
+ nodes: groupByPaint(batch.nodeStrokes, (s, i) => {
118
+ const f = lifted.get(i);
119
+ return {
120
+ color: f === void 0 ? s.color : brightenAbgr(s.color, f),
121
+ weight: s.thickness,
122
+ last: f !== void 0
123
+ };
124
+ }),
125
+ arrows: groupByPaint(batch.arrows, (a, i) => ({
126
+ color: inRun(arrowRun, i) ? brightenAbgr(a.color, factor) : a.color,
127
+ weight: 0,
128
+ last: inRun(arrowRun, i)
129
+ }))
130
+ };
131
+ }
113
132
  // Only what the highlights lift, over a transparent clear, for a hover layer
114
133
  // stacked on a canvas that drew the batch without them: a pointer move then
115
134
  // repaints one node or edge rather than the whole drawing
@@ -226,6 +245,7 @@ var Canvas2DRenderer = class {
226
245
  this.batch = null;
227
246
  this.nodeHighlights = /* @__PURE__ */ new Map();
228
247
  this.highlightedEdge = null;
248
+ this.painted = null;
229
249
  }
230
250
  };
231
251
  var ARROW_NOTCH = 0.25;
@@ -3,20 +3,20 @@ import {
3
3
  boxesGenes,
4
4
  rowPitch,
5
5
  rowSpan
6
- } from "./chunk-TRGKMLXT.js";
6
+ } from "./chunk-MXLYBDOX.js";
7
7
  import {
8
8
  el
9
9
  } from "./chunk-H2H4Y3TV.js";
10
10
  import {
11
11
  READOUT_ROOM,
12
12
  longestBar
13
- } from "./chunk-FWSERUJV.js";
14
- import {
15
- pathOrigin
16
- } from "./chunk-B5X2RLJG.js";
13
+ } from "./chunk-P5PBJONQ.js";
17
14
  import {
18
15
  LABEL_CHAR_PX
19
16
  } from "./chunk-AB35TJST.js";
17
+ import {
18
+ pathOrigin
19
+ } from "./chunk-3YBP46PB.js";
20
20
  import {
21
21
  partitionPoint
22
22
  } from "./chunk-HOAIOEI7.js";
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  EdgeSpatialIndex,
3
3
  SpatialIndex
4
- } from "./chunk-3VCKBSML.js";
4
+ } from "./chunk-6YRSOL4K.js";
5
5
  import {
6
6
  weakMemo
7
7
  } from "./chunk-HMXCN6PG.js";
@@ -9,7 +9,7 @@ import {
9
9
  pathRibbonOffsets,
10
10
  translateCurves,
11
11
  yToXOf
12
- } from "./chunk-UBQSRCWR.js";
12
+ } from "./chunk-VACK24HF.js";
13
13
 
14
14
  // src/util/hitDetection.ts
15
15
  function distanceToSegment(px, py, x1, y1, x2, y2) {
@@ -10,7 +10,8 @@ function parseGafPath(column) {
10
10
  }
11
11
  return steps;
12
12
  }
13
- function parseGafLine(line) {
13
+ function parseGafLine(text) {
14
+ const line = text.trimEnd();
14
15
  const columns = line.split(" ");
15
16
  if (columns.length < 12 || line.startsWith("#")) {
16
17
  return void 0;
@@ -49,7 +50,7 @@ function parseGafLine(line) {
49
50
  function parseGaf(text) {
50
51
  const records = [];
51
52
  for (const line of text.split("\n")) {
52
- const record = parseGafLine(line.trimEnd());
53
+ const record = parseGafLine(line);
53
54
  if (record) {
54
55
  records.push(record);
55
56
  }
@@ -9,7 +9,7 @@ import {
9
9
  panSNContig,
10
10
  panSNHaplotype,
11
11
  panSNSample
12
- } from "./chunk-4XWZNPQ2.js";
12
+ } from "./chunk-2JL2JVZ2.js";
13
13
 
14
14
  // src/reference.ts
15
15
  var WELL_KNOWN_SAMPLES = /* @__PURE__ */ new Map([
@@ -6,10 +6,10 @@ import {
6
6
  haplotypeWanted,
7
7
  referencePathQuery,
8
8
  referenceSamplesOf
9
- } from "./chunk-NMWQUFPF.js";
9
+ } from "./chunk-SVVFWTG4.js";
10
10
  import {
11
11
  panSNSample
12
- } from "./chunk-4XWZNPQ2.js";
12
+ } from "./chunk-2JL2JVZ2.js";
13
13
 
14
14
  // src/gbzCut.ts
15
15
  import { GBZBase } from "@gmod/gbz-base";
@@ -25,7 +25,7 @@ function haplotypeIndexBeside(db) {
25
25
  return GBZ_DB.test(db) ? db.replace(GBZ_DB, ".haplotype-index.db") : void 0;
26
26
  }
27
27
  function parseRegion(text) {
28
- const m = /^\s*([^:\s]+):([\d,]+)-([\d,]+)\s*$/.exec(text);
28
+ const m = /^\s*(\S+?):([\d,]+)-([\d,]+)\s*$/.exec(text);
29
29
  if (!m) {
30
30
  throw new Error(
31
31
  `"${text}" is not a 0-based region like chr6:160,614,797-160,647,758`
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  baseEdgeCurves
3
- } from "./chunk-WA5WNP6V.js";
3
+ } from "./chunk-OYCQVJYY.js";
4
4
  import {
5
5
  curveBounds,
6
6
  pathRibbonOffsets
7
- } from "./chunk-UBQSRCWR.js";
7
+ } from "./chunk-VACK24HF.js";
8
8
 
9
9
  // src/util/SpatialIndex.ts
10
10
  var FALLBACK_CELL_SIZE = 50;
@@ -14,23 +14,20 @@ import {
14
14
  } from "./chunk-VPE4AYP7.js";
15
15
  import {
16
16
  convertGFAToGraph
17
- } from "./chunk-FFHJGWDK.js";
17
+ } from "./chunk-2C5SATRZ.js";
18
18
  import {
19
19
  parseGFA
20
- } from "./chunk-5I3K4R2G.js";
20
+ } from "./chunk-CFXXFHRK.js";
21
21
  import {
22
22
  graphFromTables
23
- } from "./chunk-NJGYLYU7.js";
24
- import {
25
- anchorGraph
26
- } from "./chunk-B5X2RLJG.js";
23
+ } from "./chunk-W2YAW36J.js";
27
24
  import {
28
25
  gfaTables
29
26
  } from "./chunk-DZR37KXT.js";
30
27
  import {
31
28
  mergeRuns,
32
29
  splitRuns
33
- } from "./chunk-BZFOFC4D.js";
30
+ } from "./chunk-2VMKQKVO.js";
34
31
  import {
35
32
  spreadFor
36
33
  } from "./chunk-HKYXWZQS.js";
@@ -42,7 +39,10 @@ import {
42
39
  import {
43
40
  deletionDrawing,
44
41
  deletionEdges
45
- } from "./chunk-CGMSKIEO.js";
42
+ } from "./chunk-DV5B5UU7.js";
43
+ import {
44
+ anchorGraph
45
+ } from "./chunk-3YBP46PB.js";
46
46
  import {
47
47
  isBackbone
48
48
  } from "./chunk-RJWPJCIB.js";
@@ -56,7 +56,7 @@ function graphOf(source, name) {
56
56
  return tables ? graphFromTables(tables, name) : convertGFAToGraph(parseGFA(source), name);
57
57
  }
58
58
  function loadGraph(source, name, opts = {}) {
59
- const graph = anchorGraph(graphOf(source, name), opts.referencePath);
59
+ const graph = graphOf(source, name);
60
60
  if (graph.nodes.length === 0) {
61
61
  throw new Error(`No graph segments in ${name}`);
62
62
  }
@@ -65,7 +65,7 @@ function loadGraph(source, name, opts = {}) {
65
65
  `Graph too large to draw: ${graph.nodes.length.toLocaleString()} nodes (limit ${opts.maxNodes.toLocaleString()}). Zoom in to a smaller region, or raise maxGraphNodes on this view.`
66
66
  );
67
67
  }
68
- return graph;
68
+ return anchorGraph(graph, opts.referencePath);
69
69
  }
70
70
  var ENGINE_DEFAULTS = {
71
71
  engine: "fmmm",
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  polylineSlice
3
- } from "./chunk-BZFOFC4D.js";
3
+ } from "./chunk-2VMKQKVO.js";
4
4
  import {
5
5
  svgPath
6
- } from "./chunk-UBQSRCWR.js";
6
+ } from "./chunk-VACK24HF.js";
7
7
  import {
8
8
  firstNodeAtOrAfter,
9
9
  isAnchored
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  panSNFields
3
- } from "./chunk-4XWZNPQ2.js";
3
+ } from "./chunk-2JL2JVZ2.js";
4
4
 
5
5
  // src/facetGrid.ts
6
6
  var FACET_GAP_PX = 8;
@@ -43,6 +43,9 @@ function facetGrid({
43
43
  return tile(Math.max(1, Math.min(count, Math.round(columns))));
44
44
  }
45
45
  let best = tile(1);
46
+ if (pixelRows) {
47
+ return best;
48
+ }
46
49
  for (let across = 2; across <= count; across++) {
47
50
  const grid = tile(across);
48
51
  if (grid.scale > best.scale) {