@jbrowse/bandage-core 9.1.0 → 9.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 (53) hide show
  1. package/dist/bubbles/bubbleHalos.js +3 -1
  2. package/dist/bubbles/superbubbles.js +3 -5
  3. package/dist/chunks/{chunk-GJMC3PGM.js → chunk-3FOOZ5VL.js} +15 -14
  4. package/dist/chunks/{chunk-FFFQNQUI.js → chunk-A4MYLGKG.js} +1 -1
  5. package/dist/chunks/{chunk-2AWUWGAD.js → chunk-ABOZYAN5.js} +4 -0
  6. package/dist/chunks/chunk-B4645SM2.js +358 -0
  7. package/dist/chunks/chunk-B4YH42OP.js +24 -0
  8. package/dist/chunks/{chunk-XLCTQHBE.js → chunk-BLRJ6IGK.js} +1 -1
  9. package/dist/chunks/{chunk-UID3QBWH.js → chunk-BTMPPLDF.js} +1 -1
  10. package/dist/chunks/{chunk-RRZMMYBG.js → chunk-BV64PQ2C.js} +1 -1
  11. package/dist/chunks/{chunk-W253V6RR.js → chunk-CVYDR2OP.js} +1 -1
  12. package/dist/chunks/{chunk-MIW3HYPE.js → chunk-GFRPX6M2.js} +2 -2
  13. package/dist/chunks/{chunk-MBB7ATM6.js → chunk-LFKMASER.js} +1 -1
  14. package/dist/chunks/{chunk-6ZNQJ5ZD.js → chunk-OXTR3BVF.js} +1 -1
  15. package/dist/chunks/{chunk-FUVI4WQP.js → chunk-ROYHPOYF.js} +7 -7
  16. package/dist/chunks/{chunk-3TGUKQWQ.js → chunk-TL3TYSCP.js} +22 -22
  17. package/dist/chunks/{chunk-WDTXW7T2.js → chunk-UD5FOCI2.js} +1 -1
  18. package/dist/chunks/{chunk-MXDQGA7A.js → chunk-XKM5OHQQ.js} +1 -1
  19. package/dist/chunks/{chunk-DPV2CUIE.js → chunk-XPT66H6H.js} +1 -1
  20. package/dist/cli/figure.js +27 -27
  21. package/dist/cli/fold.js +72 -0
  22. package/dist/figure.js +17 -17
  23. package/dist/figureSettings.js +4 -4
  24. package/dist/foldVariants.js +9 -0
  25. package/dist/gfa/writeRgfa.js +6 -0
  26. package/dist/index.js +63 -63
  27. package/dist/labelLayout.js +1 -1
  28. package/dist/layout/forceCache.js +4 -4
  29. package/dist/layout/trimToWindow.js +13 -0
  30. package/dist/layout/walkRowDraw.js +4 -4
  31. package/dist/layout/walkStrip.js +5 -5
  32. package/dist/layoutModes.js +2 -2
  33. package/dist/pipeline.js +3 -3
  34. package/dist/referenceRampCss.js +3 -3
  35. package/dist/referenceStrip.js +3 -3
  36. package/dist/renderer/GeometryBuilder.js +2 -2
  37. package/dist/tubeMap/nodeColors.js +3 -3
  38. package/dist/types/bubbles/bubbleHalos.d.ts +2 -0
  39. package/dist/types/bubbles/superbubbles.d.ts +0 -1
  40. package/dist/types/cli/fold.d.ts +1 -0
  41. package/dist/types/foldVariants.d.ts +2 -0
  42. package/dist/types/gfa/writeRgfa.d.ts +2 -0
  43. package/dist/types/labelLayout.d.ts +6 -0
  44. package/dist/types/layout/trimToWindow.d.ts +4 -0
  45. package/dist/types/version.d.ts +1 -1
  46. package/dist/version.js +1 -1
  47. package/dist/viewport.js +4 -4
  48. package/dist/walkEncoding.js +3 -3
  49. package/dist/walkHighlight.js +4 -4
  50. package/package.json +3 -2
  51. package/dist/chunks/{chunk-HBEKUQO4.js → chunk-BR25DGIJ.js} +4 -4
  52. package/dist/chunks/{chunk-WNUZP3WQ.js → chunk-M7SRZJ32.js} +3 -3
  53. package/dist/chunks/{chunk-OOXIMURX.js → chunk-ZGRYFUXE.js} +8 -8
@@ -1,14 +1,16 @@
1
1
  import {
2
+ SMALL_VARIANT_BP,
2
3
  WHOLE_FRACTION,
3
4
  bubbleHalos,
4
5
  coversGraph
5
- } from "../chunks/chunk-2AWUWGAD.js";
6
+ } from "../chunks/chunk-ABOZYAN5.js";
6
7
  import "../chunks/chunk-XKWD2RY3.js";
7
8
  import "../chunks/chunk-FX4RDMDN.js";
8
9
  import "../chunks/chunk-2CVHXFK7.js";
9
10
  import "../chunks/chunk-CPMHA4W5.js";
10
11
  import "../chunks/chunk-FYQWPEEY.js";
11
12
  export {
13
+ SMALL_VARIANT_BP,
12
14
  WHOLE_FRACTION,
13
15
  bubbleHalos,
14
16
  coversGraph
@@ -1,12 +1,11 @@
1
1
  import {
2
- MAX_SUPERBUBBLES,
3
2
  graphBubbles,
4
3
  superbubblesFromGraph
5
- } from "../chunks/chunk-FUVI4WQP.js";
4
+ } from "../chunks/chunk-ROYHPOYF.js";
6
5
  import "../chunks/chunk-VHW7FDHU.js";
7
- import "../chunks/chunk-2AWUWGAD.js";
8
- import "../chunks/chunk-GOZYKNQ2.js";
6
+ import "../chunks/chunk-ABOZYAN5.js";
9
7
  import "../chunks/chunk-XKWD2RY3.js";
8
+ import "../chunks/chunk-GOZYKNQ2.js";
10
9
  import "../chunks/chunk-FX4RDMDN.js";
11
10
  import "../chunks/chunk-HNQPEMYE.js";
12
11
  import "../chunks/chunk-ST2IBUAN.js";
@@ -15,7 +14,6 @@ import "../chunks/chunk-2CVHXFK7.js";
15
14
  import "../chunks/chunk-CPMHA4W5.js";
16
15
  import "../chunks/chunk-FYQWPEEY.js";
17
16
  export {
18
- MAX_SUPERBUBBLES,
19
17
  graphBubbles,
20
18
  superbubblesFromGraph
21
19
  };
@@ -92,24 +92,24 @@ function layoutLabels(m) {
92
92
  const onRows = m.drawnRowLabels.length > 0;
93
93
  const rowsTop = onRows ? Math.min(...m.drawnRowLabels.map((r) => r.y)) : Infinity;
94
94
  const halo = m.contigThickness * HALO_FACTOR;
95
- const byBubble = byExtent(m.bubbleHalos, (h) => h.members);
95
+ const above = (h, gap) => {
96
+ const { x, y } = screen({
97
+ x: h.labelAt.x,
98
+ y: Math.min(h.labelAt.y, rowsTop)
99
+ });
100
+ const baseline = y - halo / 2 - gap;
101
+ return { x, y: onRows ? Math.max(baseline, TOPMOST_BASELINE) : baseline };
102
+ };
103
+ const byBubble = byExtent(
104
+ m.bubbleHalos.filter((h) => !h.tick),
105
+ (h) => h.members
106
+ );
96
107
  const bubbles = placeLabels(
97
- byBubble.map((h) => {
98
- const { x, y } = screen({
99
- x: h.labelAt.x,
100
- y: Math.min(h.labelAt.y, rowsTop)
101
- });
102
- const baseline = y - halo / 2 - 6;
103
- return {
104
- item: h,
105
- x,
106
- y: onRows ? Math.max(baseline, TOPMOST_BASELINE) : baseline,
107
- text: h.label
108
- };
109
- }),
108
+ byBubble.map((h) => ({ item: h, ...above(h, 6), text: h.label })),
110
109
  frame,
111
110
  take
112
111
  );
112
+ const ticks = m.bubbleHalos.filter((h) => h.tick && !h.whole).map((h) => ({ item: h, ...above(h, 2) })).filter((t) => t.x >= 0 && t.x <= width && t.y >= 0 && t.y <= height);
113
113
  const genes = placeLabels(
114
114
  geneLabelCandidates(
115
115
  m.genePins,
@@ -162,6 +162,7 @@ function layoutLabels(m) {
162
162
  );
163
163
  return {
164
164
  bubbles,
165
+ ticks,
165
166
  genes,
166
167
  routes,
167
168
  sizes: [...deletionLabels, ...nodeLabels]
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  computeColorSchemeRange,
3
3
  getNodeColor
4
- } from "./chunk-HBEKUQO4.js";
4
+ } from "./chunk-BR25DGIJ.js";
5
5
  import {
6
6
  abgrToCssRgba
7
7
  } from "./chunk-G2FD7S3C.js";
@@ -15,6 +15,7 @@ var WHOLE_FRACTION = 0.9;
15
15
  function coversGraph(members, nodes) {
16
16
  return members + 2 >= nodes || members >= WHOLE_FRACTION * nodes;
17
17
  }
18
+ var SMALL_VARIANT_BP = 50;
18
19
  var NAMED_WALKS = 2;
19
20
  var MIN_CHIPPED_BP = 1e3;
20
21
  function bubbleHalos(graph, bubbles, positions, walkLabel = (name) => name, repeats = []) {
@@ -95,6 +96,8 @@ function bubbleHalos(graph, bubbles, positions, walkLabel = (name) => name, repe
95
96
  members: nodeIds.length,
96
97
  nodeIds,
97
98
  whole: coversGraph(nodeIds.length, graph.nodes.length),
99
+ // a partial bubble's lengths are a floor, so it may be no small variant
100
+ tick: !bubble.partial && bubble.longestAlleleLength < SMALL_VARIANT_BP,
98
101
  routes
99
102
  });
100
103
  }
@@ -110,5 +113,6 @@ function routeText(route, walkLabel) {
110
113
  export {
111
114
  WHOLE_FRACTION,
112
115
  coversGraph,
116
+ SMALL_VARIANT_BP,
113
117
  bubbleHalos
114
118
  };
@@ -0,0 +1,358 @@
1
+ import {
2
+ ownStrand
3
+ } from "./chunk-2CVHXFK7.js";
4
+ import {
5
+ isBackbone
6
+ } from "./chunk-FYQWPEEY.js";
7
+
8
+ // src/foldVariants.ts
9
+ function foldVariants(graph, belowBp) {
10
+ if (!(belowBp > 0) || graph.paths?.length || !graph.nodes.some((node) => isBackbone(node))) {
11
+ return graph;
12
+ }
13
+ const { nodes, edges } = graph;
14
+ const index = new Map(nodes.map((node, i) => [node.id, i]));
15
+ const sides = edges.map(forwardSides);
16
+ const links = linksAt(nodes.length, edges, sides, index);
17
+ const allele = alleleOf(nodes, edges, sides, index);
18
+ const members = groupBy(allele);
19
+ const kept = new Uint8Array(nodes.length);
20
+ const big = [];
21
+ for (const group of members.values()) {
22
+ if (alleleContent(group, nodes, links, allele) >= belowBp) {
23
+ for (const i of group) {
24
+ kept[i] = 1;
25
+ }
26
+ if (!isBackbone(nodes[group[0]])) {
27
+ big.push(group);
28
+ }
29
+ }
30
+ }
31
+ const { dist, pred } = distancesFromBackbone(nodes, links);
32
+ for (const group of big) {
33
+ for (const [i, side] of alleleEnds(group, nodes, links, allele)) {
34
+ let next = nearestOutside(i, side, links, allele, dist, nodes);
35
+ while (next !== void 0 && !kept[next]) {
36
+ kept[next] = 1;
37
+ next = isBackbone(nodes[next]) ? void 0 : pred[next];
38
+ }
39
+ }
40
+ }
41
+ const keptEdges = edges.filter((edge, k) => {
42
+ const a = index.get(edge.from);
43
+ const b = index.get(edge.to);
44
+ if (a === void 0 || b === void 0) {
45
+ return false;
46
+ }
47
+ const skip = skipped(nodes[a], sides[k].from, nodes[b], sides[k].to);
48
+ return kept[a] && kept[b] && !(skip > 0 && skip < belowBp);
49
+ });
50
+ return mergeAlleleRuns({ ...graph, edges: keptEdges }, kept, allele);
51
+ }
52
+ function forwardSides(edge) {
53
+ return {
54
+ from: (edge.fromStrand ?? ownStrand(edge.from)) === "+" ? "e" : "s",
55
+ to: (edge.toStrand ?? ownStrand(edge.to)) === "+" ? "s" : "e"
56
+ };
57
+ }
58
+ function linksAt(count, edges, sides, index) {
59
+ const links = Array.from({ length: count }, () => []);
60
+ edges.forEach((edge, k) => {
61
+ const a = index.get(edge.from);
62
+ const b = index.get(edge.to);
63
+ if (a !== void 0 && b !== void 0) {
64
+ links[a].push({ other: b, side: sides[k].from });
65
+ links[b].push({ other: a, side: sides[k].to });
66
+ }
67
+ });
68
+ return links;
69
+ }
70
+ function onOneSequence(a, b) {
71
+ const sa = a.stable;
72
+ const sb = b.stable;
73
+ return sa && sb?.refName === sa.refName && sb.rank === sa.rank ? [sa, sb] : void 0;
74
+ }
75
+ function continues(a, aSide, b, bSide) {
76
+ const pair = onOneSequence(a, b);
77
+ if (!pair || aSide === bSide) {
78
+ return false;
79
+ }
80
+ const [sa, sb] = pair;
81
+ return sa.start + a.length === sb.start || sb.start + b.length === sa.start;
82
+ }
83
+ function skipped(a, aSide, b, bSide) {
84
+ const pair = onOneSequence(a, b);
85
+ if (!pair || continues(a, aSide, b, bSide)) {
86
+ return 0;
87
+ }
88
+ const [sa, sb] = pair;
89
+ return Math.max(
90
+ sb.start - (sa.start + a.length),
91
+ sa.start - (sb.start + b.length)
92
+ );
93
+ }
94
+ function alleleOf(nodes, edges, sides, index) {
95
+ const parent = nodes.map((_, i) => i);
96
+ const find = (i) => {
97
+ while (parent[i] !== i) {
98
+ parent[i] = parent[parent[i]];
99
+ i = parent[i];
100
+ }
101
+ return i;
102
+ };
103
+ edges.forEach((edge, k) => {
104
+ const a = index.get(edge.from);
105
+ const b = index.get(edge.to);
106
+ if (a !== void 0 && b !== void 0 && continues(nodes[a], sides[k].from, nodes[b], sides[k].to)) {
107
+ parent[find(a)] = find(b);
108
+ }
109
+ });
110
+ return nodes.map((_, i) => find(i));
111
+ }
112
+ function groupBy(allele) {
113
+ const groups = /* @__PURE__ */ new Map();
114
+ allele.forEach((root, i) => {
115
+ const group = groups.get(root);
116
+ if (group) {
117
+ group.push(i);
118
+ } else {
119
+ groups.set(root, [i]);
120
+ }
121
+ });
122
+ return groups;
123
+ }
124
+ function alleleContent(group, nodes, links, allele) {
125
+ if (isBackbone(nodes[group[0]])) {
126
+ return Infinity;
127
+ }
128
+ let length = 0;
129
+ let refName;
130
+ let lo = Infinity;
131
+ let hi = -Infinity;
132
+ let oneSequence = true;
133
+ for (const i of group) {
134
+ length += nodes[i].length;
135
+ for (const { other } of links[i]) {
136
+ const node = nodes[other];
137
+ if (allele[other] !== allele[i] && isBackbone(node)) {
138
+ refName ??= node.stable.refName;
139
+ oneSequence &&= node.stable.refName === refName;
140
+ lo = Math.min(lo, node.stable.start + node.length);
141
+ hi = Math.max(hi, node.stable.start);
142
+ }
143
+ }
144
+ }
145
+ return oneSequence && hi > lo ? Math.max(length, hi - lo) : length;
146
+ }
147
+ function alleleEnds(group, nodes, links, allele) {
148
+ const start = (i) => nodes[i].stable?.start ?? 0;
149
+ const end = (i) => start(i) + nodes[i].length;
150
+ let first = group[0];
151
+ let last = group[0];
152
+ for (const i of group) {
153
+ if (start(i) < start(first)) {
154
+ first = i;
155
+ }
156
+ if (end(i) > end(last)) {
157
+ last = i;
158
+ }
159
+ }
160
+ const ends = [];
161
+ for (const i of /* @__PURE__ */ new Set([first, last])) {
162
+ for (const side of ["s", "e"]) {
163
+ if (!links[i].some(
164
+ (link) => link.side === side && allele[link.other] === allele[i]
165
+ )) {
166
+ ends.push([i, side]);
167
+ }
168
+ }
169
+ }
170
+ return ends;
171
+ }
172
+ function nearestOutside(i, side, links, allele, dist, nodes) {
173
+ let best;
174
+ for (const link of links[i]) {
175
+ const j = link.other;
176
+ if (link.side === side && allele[j] !== allele[i] && Number.isFinite(dist[j]) && (best === void 0 || dist[j] < dist[best] || dist[j] === dist[best] && nodes[j].id < nodes[best].id)) {
177
+ best = j;
178
+ }
179
+ }
180
+ return best;
181
+ }
182
+ function distancesFromBackbone(nodes, links) {
183
+ const dist = new Float64Array(nodes.length).fill(Infinity);
184
+ const pred = new Int32Array(nodes.length).fill(-1);
185
+ const heap = new MinHeap(
186
+ ([da, a], [db, b]) => da - db || cmp(nodes[a].id, nodes[b].id)
187
+ );
188
+ nodes.forEach((node, i) => {
189
+ if (isBackbone(node)) {
190
+ dist[i] = 0;
191
+ heap.push([0, i]);
192
+ }
193
+ });
194
+ for (let top = heap.pop(); top !== void 0; top = heap.pop()) {
195
+ const [d0, i] = top;
196
+ if (d0 > dist[i]) {
197
+ continue;
198
+ }
199
+ for (const { other } of links[i]) {
200
+ if (isBackbone(nodes[other])) {
201
+ continue;
202
+ }
203
+ const d = d0 + nodes[other].length;
204
+ if (d < dist[other]) {
205
+ dist[other] = d;
206
+ pred[other] = i;
207
+ heap.push([d, other]);
208
+ } else if (d === dist[other] && cmp(nodes[i].id, nodes[pred[other]].id) < 0) {
209
+ pred[other] = i;
210
+ }
211
+ }
212
+ }
213
+ return { dist, pred: Array.from(pred, (p) => p < 0 ? void 0 : p) };
214
+ }
215
+ function cmp(a, b) {
216
+ return a < b ? -1 : a > b ? 1 : 0;
217
+ }
218
+ var MinHeap = class {
219
+ constructor(order) {
220
+ this.order = order;
221
+ this.items = [];
222
+ }
223
+ push(item) {
224
+ const { items } = this;
225
+ items.push(item);
226
+ let i = items.length - 1;
227
+ while (i > 0) {
228
+ const up = i - 1 >> 1;
229
+ if (this.order(items[i], items[up]) >= 0) {
230
+ break;
231
+ }
232
+ ;
233
+ [items[i], items[up]] = [items[up], items[i]];
234
+ i = up;
235
+ }
236
+ }
237
+ pop() {
238
+ const { items } = this;
239
+ const top = items[0];
240
+ const last = items.pop();
241
+ if (items.length > 0 && last !== void 0) {
242
+ items[0] = last;
243
+ let i = 0;
244
+ for (; ; ) {
245
+ const l = 2 * i + 1;
246
+ const r = l + 1;
247
+ let m = i;
248
+ if (l < items.length && this.order(items[l], items[m]) < 0) {
249
+ m = l;
250
+ }
251
+ if (r < items.length && this.order(items[r], items[m]) < 0) {
252
+ m = r;
253
+ }
254
+ if (m === i) {
255
+ break;
256
+ }
257
+ ;
258
+ [items[i], items[m]] = [items[m], items[i]];
259
+ i = m;
260
+ }
261
+ }
262
+ return top;
263
+ }
264
+ };
265
+ function mergeAlleleRuns(graph, kept, allele) {
266
+ const { nodes, edges } = graph;
267
+ const index = new Map(nodes.map((node, i) => [node.id, i]));
268
+ const sides = edges.map(forwardSides);
269
+ const ends = edges.map((edge, k) => [
270
+ { i: index.get(edge.from), side: sides[k].from },
271
+ { i: index.get(edge.to), side: sides[k].to }
272
+ ]);
273
+ const degree = /* @__PURE__ */ new Map();
274
+ const sideKey = (i, side) => `${i}${side}`;
275
+ for (const pair of ends) {
276
+ for (const { i, side } of pair) {
277
+ degree.set(sideKey(i, side), (degree.get(sideKey(i, side)) ?? 0) + 1);
278
+ }
279
+ }
280
+ const next = /* @__PURE__ */ new Map();
281
+ const hasPrev = /* @__PURE__ */ new Set();
282
+ const internal = /* @__PURE__ */ new Set();
283
+ ends.forEach(([a, b], k) => {
284
+ 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) {
285
+ const [left, right] = nodes[a.i].stable.start < nodes[b.i].stable.start ? [a, b] : [b, a];
286
+ next.set(left.i, { j: right.i, out: left.side, in: right.side });
287
+ hasPrev.add(right.i);
288
+ internal.add(k);
289
+ }
290
+ });
291
+ const headOf = nodes.map((_, i) => i);
292
+ const outer = /* @__PURE__ */ new Map();
293
+ const merged = /* @__PURE__ */ new Map();
294
+ nodes.forEach((_, i) => {
295
+ if (!kept[i] || hasPrev.has(i) || !next.has(i)) {
296
+ return;
297
+ }
298
+ const run = [i];
299
+ let into = flip(next.get(i).out);
300
+ outer.set(sideKey(i, into), "s");
301
+ for (let step = next.get(i); step; step = next.get(step.j)) {
302
+ run.push(step.j);
303
+ into = step.in;
304
+ }
305
+ outer.set(sideKey(run.at(-1), flip(into)), "e");
306
+ for (const j of run) {
307
+ headOf[j] = i;
308
+ }
309
+ merged.set(i, mergedNode(run.map((j) => nodes[j])));
310
+ });
311
+ const endpoint = ({ i, side }) => ({
312
+ id: nodes[headOf[i]].id,
313
+ side: headOf[i] === i && !merged.has(i) ? side : outer.get(sideKey(i, side))
314
+ });
315
+ return {
316
+ ...graph,
317
+ nodes: nodes.flatMap(
318
+ (node, i) => !kept[i] || headOf[i] !== i ? [] : [merged.get(i) ?? node]
319
+ ),
320
+ edges: edges.flatMap((edge, k) => {
321
+ if (internal.has(k)) {
322
+ return [];
323
+ }
324
+ const [a, b] = ends[k];
325
+ if (!merged.has(headOf[a.i]) && !merged.has(headOf[b.i])) {
326
+ return [edge];
327
+ }
328
+ const from = endpoint(a);
329
+ const to = endpoint(b);
330
+ return [
331
+ {
332
+ ...edge,
333
+ from: from.id,
334
+ to: to.id,
335
+ fromStrand: from.side === "e" ? "+" : "-",
336
+ toStrand: to.side === "s" ? "+" : "-"
337
+ }
338
+ ];
339
+ })
340
+ };
341
+ }
342
+ function flip(side) {
343
+ return side === "s" ? "e" : "s";
344
+ }
345
+ function mergedNode(run) {
346
+ const { samples: firstSamples, ...first } = run[0];
347
+ const length = run.reduce((sum, node) => sum + node.length, 0);
348
+ const depth = length > 0 ? run.reduce((sum, node) => sum + node.depth * node.length, 0) / length : first.depth;
349
+ const samples = run.every((node) => node.samples) ? run.reduce(
350
+ (common, node) => common.filter((s) => node.samples.includes(s)),
351
+ firstSamples
352
+ ) : void 0;
353
+ return samples ? { ...first, length, depth, samples } : { ...first, length, depth };
354
+ }
355
+
356
+ export {
357
+ foldVariants
358
+ };
@@ -0,0 +1,24 @@
1
+ // src/gfa/writeRgfa.ts
2
+ function writeRgfa(graph) {
3
+ const nameOf = new Map(graph.nodes.map((n) => [n.id, n.name]));
4
+ return [
5
+ "H VN:Z:1.0",
6
+ ...graph.nodes.map(segmentLine),
7
+ ...graph.edges.map(
8
+ (e) => `L ${nameOf.get(e.from)} ${e.fromStrand ?? "+"} ${nameOf.get(e.to)} ${e.toStrand ?? "+"} 0M`
9
+ ),
10
+ ""
11
+ ].join("\n");
12
+ }
13
+ function segmentLine(node) {
14
+ const { stable } = node;
15
+ if (!stable) {
16
+ throw new Error(`segment ${node.name} has no stable coordinate to file`);
17
+ }
18
+ const samples = node.samples?.length ? ` SM:Z:${node.samples.join(",")}` : "";
19
+ return `S ${node.name} * LN:i:${node.length} SN:Z:${stable.refName} SO:i:${stable.start} SR:i:${stable.rank}${samples}`;
20
+ }
21
+
22
+ export {
23
+ writeRgfa
24
+ };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  ENGINE_DEFAULTS
3
- } from "./chunk-OOXIMURX.js";
3
+ } from "./chunk-ZGRYFUXE.js";
4
4
 
5
5
  // src/figureSettings.ts
6
6
  var FIGURE_DEFAULTS = {
@@ -1,5 +1,5 @@
1
1
  // src/version.ts
2
- var version = "9.1.0";
2
+ var version = "9.3.0";
3
3
 
4
4
  export {
5
5
  version
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  engineKey,
3
3
  forceLayout
4
- } from "./chunk-OOXIMURX.js";
4
+ } from "./chunk-ZGRYFUXE.js";
5
5
 
6
6
  // src/layout/forceCache.ts
7
7
  var DEFAULT_SIZE = 4;
@@ -2,7 +2,7 @@ import {
2
2
  LIFT_BACKDROP_CSS,
3
3
  computeColorSchemeRange,
4
4
  getNodeColor
5
- } from "./chunk-HBEKUQO4.js";
5
+ } from "./chunk-BR25DGIJ.js";
6
6
  import {
7
7
  abgrToCssRgba
8
8
  } from "./chunk-G2FD7S3C.js";
@@ -3,10 +3,10 @@ import {
3
3
  RAMP_GRADIENT_STOPS,
4
4
  rampHueCss,
5
5
  rampStops
6
- } from "./chunk-6ZNQJ5ZD.js";
6
+ } from "./chunk-OXTR3BVF.js";
7
7
  import {
8
8
  REFERENCE_RAMP_ALT_CSS
9
- } from "./chunk-HBEKUQO4.js";
9
+ } from "./chunk-BR25DGIJ.js";
10
10
  import {
11
11
  LABEL_CHAR_PX
12
12
  } from "./chunk-AB35TJST.js";
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  encodedColor,
3
3
  resolveEncoding
4
- } from "./chunk-DPV2CUIE.js";
4
+ } from "./chunk-XPT66H6H.js";
5
5
  import {
6
6
  pathOrigin
7
7
  } from "./chunk-ST2IBUAN.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  REFERENCE_RAMP_MAX_HUE
3
- } from "./chunk-HBEKUQO4.js";
3
+ } from "./chunk-BR25DGIJ.js";
4
4
 
5
5
  // src/referenceRampCss.ts
6
6
  function rampHueCss(hue) {
@@ -3,15 +3,15 @@ import {
3
3
  } from "./chunk-VHW7FDHU.js";
4
4
  import {
5
5
  coversGraph
6
- } from "./chunk-2AWUWGAD.js";
6
+ } from "./chunk-ABOZYAN5.js";
7
+ import {
8
+ bubbleSegmentIds
9
+ } from "./chunk-XKWD2RY3.js";
7
10
  import {
8
11
  bubblesFromGraph,
9
12
  walkIndexOf,
10
13
  walkRoutes
11
14
  } from "./chunk-GOZYKNQ2.js";
12
- import {
13
- bubbleSegmentIds
14
- } from "./chunk-XKWD2RY3.js";
15
15
  import {
16
16
  SATURATED_PATH_COUNT
17
17
  } from "./chunk-FX4RDMDN.js";
@@ -23,7 +23,6 @@ import {
23
23
  } from "./chunk-FYQWPEEY.js";
24
24
 
25
25
  // src/bubbles/superbubbles.ts
26
- var MAX_SUPERBUBBLES = 50;
27
26
  function slotGraph(graph, index) {
28
27
  const slots = graph.nodes.length * 2;
29
28
  const seen = /* @__PURE__ */ new Set();
@@ -224,7 +223,9 @@ function superbubblesFromGraph(graph, span) {
224
223
  (j) => j !== i && !covers[j] && members[j].length > members[i].length && members[i].every((v) => holders.get(v).includes(j))
225
224
  );
226
225
  const placed = (f) => span !== void 0 || onReference(nodes[f.source >> 1], nodes[f.sink >> 1]);
227
- const outermost = found.filter((f, i) => !covers[i] && placed(f) && !nested(f, i)).sort((a, b) => b.inside.length - a.inside.length).slice(0, MAX_SUPERBUBBLES);
226
+ const outermost = found.filter(
227
+ (f, i) => !covers[i] && placed(f) && !nested(f, i)
228
+ );
228
229
  const byId = new Map(nodes.map((n) => [n.id, n]));
229
230
  const walkIndex = walkIndexOf(graph);
230
231
  return outermost.map((f) => {
@@ -267,7 +268,6 @@ function graphBubbles(graph, span) {
267
268
  }
268
269
 
269
270
  export {
270
- MAX_SUPERBUBBLES,
271
271
  superbubblesFromGraph,
272
272
  graphBubbles
273
273
  };