@jbrowse/bandage-core 9.8.0 → 9.9.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.
- package/dist/bubbles/popBubble.js +2 -2
- package/dist/bubbles/superbubbles.js +3 -3
- package/dist/chunks/{chunk-75HR3756.js → chunk-2NROXCK3.js} +47 -16
- package/dist/chunks/{chunk-MAUEPAMG.js → chunk-6PYZYBBF.js} +1 -1
- package/dist/chunks/{chunk-VHW7FDHU.js → chunk-A6PSWTLX.js} +1 -1
- package/dist/chunks/{chunk-CG77WIFD.js → chunk-BEMPOHHG.js} +13 -13
- package/dist/chunks/{chunk-7GBL7SJY.js → chunk-EDASNMLY.js} +1 -1
- package/dist/chunks/{chunk-3FVITQAJ.js → chunk-EE37PVQY.js} +2 -2
- package/dist/chunks/{chunk-BOHK5BD3.js → chunk-F4BKWWLS.js} +1 -1
- package/dist/chunks/{chunk-AM3P3WWO.js → chunk-F5BYHLIN.js} +1 -1
- package/dist/chunks/{chunk-ZGRYFUXE.js → chunk-FPTI3WAV.js} +13 -6
- package/dist/chunks/chunk-G45YY72K.js +220 -0
- package/dist/chunks/{chunk-6N7H22SS.js → chunk-HOZI3FBG.js} +2 -2
- package/dist/chunks/{chunk-ST2IBUAN.js → chunk-IGJCTPFB.js} +30 -5
- package/dist/chunks/{chunk-Z7UWHVOM.js → chunk-IJRNMO4D.js} +2 -2
- package/dist/chunks/chunk-IJYFJVIT.js +77 -0
- package/dist/chunks/{chunk-OCMBULGN.js → chunk-J7YKQ5YW.js} +1 -1
- package/dist/chunks/{chunk-VZQ4FKLR.js → chunk-JABM3MUS.js} +1 -1
- package/dist/chunks/{chunk-ZBWMTXTM.js → chunk-KJEMKHVB.js} +1 -1
- package/dist/chunks/{chunk-QMJXHYVQ.js → chunk-MECWJY2R.js} +2 -2
- package/dist/chunks/{chunk-EPREHMKU.js → chunk-P6O4RSOQ.js} +2 -2
- package/dist/chunks/{chunk-373Y3KUJ.js → chunk-RK3MF4FD.js} +1 -1
- package/dist/chunks/{chunk-C55SC5AJ.js → chunk-ROQGMTFB.js} +1 -1
- package/dist/chunks/{chunk-3C5UXR2U.js → chunk-TOVOJNT7.js} +1 -1
- package/dist/chunks/{chunk-JEF73V3A.js → chunk-UVZ56CZX.js} +1 -1
- package/dist/chunks/{chunk-5QOMIEHX.js → chunk-WVBYR6Y7.js} +2 -2
- package/dist/chunks/{chunk-BV64PQ2C.js → chunk-YAN2ZPNV.js} +1 -1
- package/dist/chunks/{chunk-BLRJ6IGK.js → chunk-YGN4KL7W.js} +1 -1
- package/dist/chunks/{chunk-QG5IVMRS.js → chunk-YS7VA5SI.js} +1 -1
- package/dist/chunks/{chunk-XKM5OHQQ.js → chunk-ZBLKAWSD.js} +1 -1
- package/dist/cli/figure.js +19 -18
- package/dist/cli/fold.js +4 -3
- package/dist/figure.js +17 -16
- package/dist/figureSettings.js +5 -4
- package/dist/gfa/gfaConverter.js +2 -2
- package/dist/gfa/gfaTables.js +6 -0
- package/dist/index.js +40 -36
- package/dist/layout/forceCache.js +5 -4
- package/dist/layout/trimToWindow.js +1 -1
- package/dist/layout/tubeMapLayout.js +3 -3
- package/dist/layout/walkRowDraw.js +5 -5
- package/dist/layout/walkRowLayout.js +3 -3
- package/dist/layout/walkRows.js +2 -2
- package/dist/layout/walkStrip.js +6 -6
- package/dist/layoutModes.js +6 -6
- package/dist/pathAnchoring.js +1 -1
- package/dist/pathColors.js +2 -2
- package/dist/pipeline.js +4 -3
- package/dist/referenceRampCss.js +4 -4
- package/dist/referenceStrip.js +4 -4
- package/dist/renderer/GeometryBuilder.js +3 -3
- package/dist/tubeMap/bundle.js +4 -4
- package/dist/tubeMap/coarsen.js +3 -3
- package/dist/tubeMap/draw.js +4 -1
- package/dist/tubeMap/frame.js +2 -2
- package/dist/tubeMap/nodeColors.js +4 -4
- package/dist/tubeMap/warp.js +1 -1
- package/dist/types/gfa/gfaTables.d.ts +10 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/tubeMap/draw.d.ts +2 -1
- package/dist/types/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/viewport.js +5 -4
- package/dist/walkEncoding.js +4 -4
- package/dist/walkHighlight.js +5 -5
- package/package.json +1 -1
- package/dist/chunks/chunk-KQFOCDFY.js +0 -73
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
bubbleSubgraph
|
|
3
|
-
} from "../chunks/chunk-
|
|
4
|
-
import "../chunks/chunk-
|
|
3
|
+
} from "../chunks/chunk-A6PSWTLX.js";
|
|
4
|
+
import "../chunks/chunk-IGJCTPFB.js";
|
|
5
5
|
import "../chunks/chunk-BPLIXMH7.js";
|
|
6
6
|
import "../chunks/chunk-FYQWPEEY.js";
|
|
7
7
|
export {
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
2
|
graphBubbles,
|
|
3
3
|
superbubblesFromGraph
|
|
4
|
-
} from "../chunks/chunk-
|
|
5
|
-
import "../chunks/chunk-
|
|
4
|
+
} from "../chunks/chunk-ROQGMTFB.js";
|
|
5
|
+
import "../chunks/chunk-A6PSWTLX.js";
|
|
6
6
|
import "../chunks/chunk-EHUBJDDB.js";
|
|
7
7
|
import "../chunks/chunk-XKWD2RY3.js";
|
|
8
8
|
import "../chunks/chunk-CLOP7UVD.js";
|
|
9
9
|
import "../chunks/chunk-FX4RDMDN.js";
|
|
10
10
|
import "../chunks/chunk-HNQPEMYE.js";
|
|
11
|
-
import "../chunks/chunk-
|
|
11
|
+
import "../chunks/chunk-IGJCTPFB.js";
|
|
12
12
|
import "../chunks/chunk-BPLIXMH7.js";
|
|
13
13
|
import "../chunks/chunk-2CVHXFK7.js";
|
|
14
14
|
import "../chunks/chunk-CPMHA4W5.js";
|
|
@@ -4,6 +4,9 @@ import {
|
|
|
4
4
|
import {
|
|
5
5
|
readColor
|
|
6
6
|
} from "./chunk-CWFNEKST.js";
|
|
7
|
+
import {
|
|
8
|
+
pathOrigin
|
|
9
|
+
} from "./chunk-IGJCTPFB.js";
|
|
7
10
|
|
|
8
11
|
// src/tubeMap/draw.ts
|
|
9
12
|
import { curvePaths, nodeOutlinePath } from "@jbrowse/tubemap-core";
|
|
@@ -53,9 +56,9 @@ function extentOf(commands) {
|
|
|
53
56
|
}
|
|
54
57
|
return { x0, x1 };
|
|
55
58
|
}
|
|
56
|
-
function shapeOf(d, color, id, haplotype) {
|
|
59
|
+
function shapeOf(d, color, id, haplotype, reference) {
|
|
57
60
|
const commands = parsePath(d);
|
|
58
|
-
return { commands, color, id, haplotype, ...extentOf(commands) };
|
|
61
|
+
return { commands, color, id, haplotype, reference, ...extentOf(commands) };
|
|
59
62
|
}
|
|
60
63
|
function trackColors(layout, pathColors) {
|
|
61
64
|
return new Map(
|
|
@@ -65,30 +68,43 @@ function trackColors(layout, pathColors) {
|
|
|
65
68
|
])
|
|
66
69
|
);
|
|
67
70
|
}
|
|
68
|
-
function layerOf(layout, type, colors) {
|
|
71
|
+
function layerOf(layout, type, colors, referenceIds) {
|
|
69
72
|
const { shapes } = layout;
|
|
70
73
|
const haplotype = type === "haplotype";
|
|
71
74
|
const colorOf = (s) => colors.get(s.id);
|
|
75
|
+
const isReference = (s) => haplotype && referenceIds.has(s.id);
|
|
72
76
|
const rects = [...shapes.rectangles, ...shapes.verticalRectangles].filter((r) => r.type === type).map((r) => ({
|
|
73
77
|
color: colorOf(r),
|
|
74
78
|
id: r.id,
|
|
75
79
|
haplotype,
|
|
80
|
+
reference: isReference(r),
|
|
76
81
|
x0: r.xStart,
|
|
77
82
|
x1: r.xEnd + 1,
|
|
78
83
|
y0: r.yStart,
|
|
79
84
|
y1: r.yEnd + 1
|
|
80
85
|
}));
|
|
81
86
|
const curves = curvePaths(shapes.curves, type).map(
|
|
82
|
-
(c) => shapeOf(c.path, colorOf(c), c.id, haplotype)
|
|
87
|
+
(c) => shapeOf(c.path, colorOf(c), c.id, haplotype, isReference(c))
|
|
83
88
|
);
|
|
84
|
-
const corners = shapes.corners.filter((c) => c.type === type).map((c) => shapeOf(c.path, colorOf(c), c.id, haplotype));
|
|
89
|
+
const corners = shapes.corners.filter((c) => c.type === type).map((c) => shapeOf(c.path, colorOf(c), c.id, haplotype, isReference(c)));
|
|
85
90
|
return { rects, shapes: [...curves, ...corners] };
|
|
86
91
|
}
|
|
92
|
+
function referenceTrackIds(graph) {
|
|
93
|
+
const ids = /* @__PURE__ */ new Set();
|
|
94
|
+
graph?.paths?.forEach((path, i) => {
|
|
95
|
+
if (pathOrigin(path.name).name === graph.referencePath) {
|
|
96
|
+
ids.add(i);
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
return ids;
|
|
100
|
+
}
|
|
87
101
|
function tubeMapPicture({
|
|
88
102
|
layout,
|
|
89
|
-
pathColors
|
|
103
|
+
pathColors,
|
|
104
|
+
graph
|
|
90
105
|
}) {
|
|
91
106
|
const colors = trackColors(layout, pathColors);
|
|
107
|
+
const referenceIds = referenceTrackIds(graph);
|
|
92
108
|
const nodes = [];
|
|
93
109
|
layout.nodes.forEach((node) => {
|
|
94
110
|
if (node.order >= 0) {
|
|
@@ -99,8 +115,8 @@ function tubeMapPicture({
|
|
|
99
115
|
return {
|
|
100
116
|
bounds: layout.bounds,
|
|
101
117
|
layers: [
|
|
102
|
-
layerOf(layout, "haplotype", colors),
|
|
103
|
-
layerOf(layout, "read", colors)
|
|
118
|
+
layerOf(layout, "haplotype", colors, referenceIds),
|
|
119
|
+
layerOf(layout, "read", colors, referenceIds)
|
|
104
120
|
],
|
|
105
121
|
nodes,
|
|
106
122
|
mismatches: tubeMapMismatches(layout).filter(
|
|
@@ -181,14 +197,29 @@ function drawTubeMap(ctx, picture, frame) {
|
|
|
181
197
|
const colorOf = (item) => item.haplotype && frame.tubeColors?.[item.id] || item.color;
|
|
182
198
|
ctx.globalAlpha = 1;
|
|
183
199
|
for (const layer of picture.layers) {
|
|
184
|
-
|
|
185
|
-
const
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
200
|
+
for (const reference of [false, true]) {
|
|
201
|
+
const inPass = (item) => item.reference === reference;
|
|
202
|
+
fillByColor(
|
|
203
|
+
ctx,
|
|
204
|
+
layer.rects,
|
|
205
|
+
(r) => inPass(r) && visible(r),
|
|
206
|
+
colorOf,
|
|
207
|
+
(r) => {
|
|
208
|
+
const left = x(r.x0);
|
|
209
|
+
const top = y(r.y0);
|
|
210
|
+
ctx.rect(left, top, x(r.x1) - left, y(r.y1) - top);
|
|
211
|
+
}
|
|
212
|
+
);
|
|
213
|
+
fillByColor(
|
|
214
|
+
ctx,
|
|
215
|
+
layer.shapes,
|
|
216
|
+
(s) => inPass(s) && visible(s),
|
|
217
|
+
colorOf,
|
|
218
|
+
(s) => {
|
|
219
|
+
trace(ctx, s.commands, x, y);
|
|
220
|
+
}
|
|
221
|
+
);
|
|
222
|
+
}
|
|
192
223
|
}
|
|
193
224
|
const stroke = frame.darkMode ? "#d0d0d0" : "#000000";
|
|
194
225
|
const fill = frame.darkMode ? "rgba(40,40,40,0.4)" : "rgba(255,255,255,0.4)";
|
|
@@ -1,22 +1,22 @@
|
|
|
1
|
+
import {
|
|
2
|
+
svgCanvas
|
|
3
|
+
} from "./chunk-47DYCZOK.js";
|
|
1
4
|
import {
|
|
2
5
|
stripGeneGaps,
|
|
3
6
|
walkStripFrame,
|
|
4
7
|
walkStripLabelsTree
|
|
5
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-MECWJY2R.js";
|
|
6
9
|
import {
|
|
7
10
|
Canvas2DRenderer
|
|
8
11
|
} from "./chunk-WBCOREDZ.js";
|
|
9
12
|
import {
|
|
10
13
|
layoutGeometryInputs
|
|
11
14
|
} from "./chunk-LOCJN3BZ.js";
|
|
12
|
-
import {
|
|
13
|
-
svgCanvas
|
|
14
|
-
} from "./chunk-47DYCZOK.js";
|
|
15
15
|
import {
|
|
16
16
|
walkRowsKey,
|
|
17
17
|
walkRowsKeyTree,
|
|
18
18
|
walkRowsTree
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-P6O4RSOQ.js";
|
|
20
20
|
import {
|
|
21
21
|
genePins
|
|
22
22
|
} from "./chunk-BUBZ32IC.js";
|
|
@@ -27,14 +27,14 @@ import {
|
|
|
27
27
|
} from "./chunk-3S3YVOJ7.js";
|
|
28
28
|
import {
|
|
29
29
|
axisScaleOf
|
|
30
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-ZBLKAWSD.js";
|
|
31
31
|
import {
|
|
32
32
|
facetLifts,
|
|
33
33
|
walkLift
|
|
34
|
-
} from "./chunk-
|
|
34
|
+
} from "./chunk-EE37PVQY.js";
|
|
35
35
|
import {
|
|
36
36
|
encodingStops
|
|
37
|
-
} from "./chunk-
|
|
37
|
+
} from "./chunk-F5BYHLIN.js";
|
|
38
38
|
import {
|
|
39
39
|
rangeText,
|
|
40
40
|
walkKey
|
|
@@ -42,18 +42,18 @@ import {
|
|
|
42
42
|
import {
|
|
43
43
|
buildGeometry,
|
|
44
44
|
computeReferenceRamp
|
|
45
|
-
} from "./chunk-
|
|
45
|
+
} from "./chunk-F4BKWWLS.js";
|
|
46
46
|
import {
|
|
47
47
|
version
|
|
48
|
-
} from "./chunk-
|
|
48
|
+
} from "./chunk-UVZ56CZX.js";
|
|
49
49
|
import {
|
|
50
50
|
walkRowLabels,
|
|
51
51
|
walkRowsExtent
|
|
52
|
-
} from "./chunk-
|
|
52
|
+
} from "./chunk-TOVOJNT7.js";
|
|
53
53
|
import {
|
|
54
54
|
pathLegend,
|
|
55
55
|
walkLabelsOf
|
|
56
|
-
} from "./chunk-
|
|
56
|
+
} from "./chunk-EDASNMLY.js";
|
|
57
57
|
import {
|
|
58
58
|
nodeInk
|
|
59
59
|
} from "./chunk-PBENCR5L.js";
|
|
@@ -91,7 +91,7 @@ import {
|
|
|
91
91
|
FIT_PADDING,
|
|
92
92
|
drawingBounds,
|
|
93
93
|
fitTransform
|
|
94
|
-
} from "./chunk-
|
|
94
|
+
} from "./chunk-FPTI3WAV.js";
|
|
95
95
|
import {
|
|
96
96
|
deletionDrawing,
|
|
97
97
|
deletionEdges
|
|
@@ -6,7 +6,10 @@ import {
|
|
|
6
6
|
} from "./chunk-IGVV37VI.js";
|
|
7
7
|
import {
|
|
8
8
|
convertGFAToGraph
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-J7YKQ5YW.js";
|
|
10
|
+
import {
|
|
11
|
+
gfaTables
|
|
12
|
+
} from "./chunk-G45YY72K.js";
|
|
10
13
|
import {
|
|
11
14
|
graphFromTables
|
|
12
15
|
} from "./chunk-OA7RIMZ2.js";
|
|
@@ -20,7 +23,7 @@ import {
|
|
|
20
23
|
} from "./chunk-JVLURPFW.js";
|
|
21
24
|
import {
|
|
22
25
|
anchorGraph
|
|
23
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-IGJCTPFB.js";
|
|
24
27
|
import {
|
|
25
28
|
mergeRuns,
|
|
26
29
|
splitRuns
|
|
@@ -42,11 +45,15 @@ import {
|
|
|
42
45
|
} from "./chunk-FYQWPEEY.js";
|
|
43
46
|
|
|
44
47
|
// src/pipeline.ts
|
|
48
|
+
function graphOf(source, name) {
|
|
49
|
+
if (typeof source !== "string") {
|
|
50
|
+
return graphFromTables(source, name);
|
|
51
|
+
}
|
|
52
|
+
const tables = gfaTables(source);
|
|
53
|
+
return tables ? graphFromTables(tables, name) : convertGFAToGraph(parseGFA(source), name);
|
|
54
|
+
}
|
|
45
55
|
function loadGraph(source, name, opts = {}) {
|
|
46
|
-
const graph = anchorGraph(
|
|
47
|
-
typeof source === "string" ? convertGFAToGraph(parseGFA(source), name) : graphFromTables(source, name),
|
|
48
|
-
opts.referencePath
|
|
49
|
-
);
|
|
56
|
+
const graph = anchorGraph(graphOf(source, name), opts.referencePath);
|
|
50
57
|
if (graph.nodes.length === 0) {
|
|
51
58
|
throw new Error(`No graph segments in ${name}`);
|
|
52
59
|
}
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
// src/gfa/gfaTables.ts
|
|
2
|
+
var GT = 62;
|
|
3
|
+
var LT = 60;
|
|
4
|
+
var TAB = 9;
|
|
5
|
+
var ZERO = 48;
|
|
6
|
+
var NINE = 57;
|
|
7
|
+
var TABLE_TAG = /^(?:LN:i|SN:Z|SO:i|SR:i):/;
|
|
8
|
+
var UNTABLED_RECORD = /^[PEOUFG]\t/;
|
|
9
|
+
var trimCR = (line) => line.endsWith("\r") ? line.slice(0, -1) : line;
|
|
10
|
+
var Steps = class {
|
|
11
|
+
constructor() {
|
|
12
|
+
this.nodes = new Int32Array(1 << 16);
|
|
13
|
+
this.reversed = new Uint8Array(1 << 16);
|
|
14
|
+
this.length = 0;
|
|
15
|
+
}
|
|
16
|
+
push(node, reversed) {
|
|
17
|
+
if (this.length === this.nodes.length) {
|
|
18
|
+
const nodes = new Int32Array(this.length * 2);
|
|
19
|
+
nodes.set(this.nodes);
|
|
20
|
+
this.nodes = nodes;
|
|
21
|
+
const rev = new Uint8Array(this.length * 2);
|
|
22
|
+
rev.set(this.reversed);
|
|
23
|
+
this.reversed = rev;
|
|
24
|
+
}
|
|
25
|
+
this.nodes[this.length] = node;
|
|
26
|
+
this.reversed[this.length++] = reversed;
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
var SegmentIndex = class {
|
|
30
|
+
constructor() {
|
|
31
|
+
this.names = [];
|
|
32
|
+
this.byName = /* @__PURE__ */ new Map();
|
|
33
|
+
// ids that are plain decimal, so a walk step finds its segment without
|
|
34
|
+
// slicing a string out of the body
|
|
35
|
+
this.byNumber = /* @__PURE__ */ new Map();
|
|
36
|
+
}
|
|
37
|
+
has(name) {
|
|
38
|
+
return this.byName.has(name);
|
|
39
|
+
}
|
|
40
|
+
add(name) {
|
|
41
|
+
const i = this.names.length;
|
|
42
|
+
this.byName.set(name, i);
|
|
43
|
+
this.names.push(name);
|
|
44
|
+
const n = +name;
|
|
45
|
+
if (Number.isSafeInteger(n) && String(n) === name) {
|
|
46
|
+
this.byNumber.set(n, i);
|
|
47
|
+
}
|
|
48
|
+
return i;
|
|
49
|
+
}
|
|
50
|
+
of(name) {
|
|
51
|
+
return this.byName.get(name) ?? this.add(name);
|
|
52
|
+
}
|
|
53
|
+
ofNumber(n) {
|
|
54
|
+
return this.byNumber.get(n);
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
function readSegment(line) {
|
|
58
|
+
const [, name, sequence = "*", ...tags] = line.split(" ");
|
|
59
|
+
if (!name || /^\d+$/.test(sequence)) {
|
|
60
|
+
return void 0;
|
|
61
|
+
}
|
|
62
|
+
let length = sequence === "*" ? 0 : sequence.length;
|
|
63
|
+
let refName;
|
|
64
|
+
let start;
|
|
65
|
+
let rank;
|
|
66
|
+
for (const tag of tags) {
|
|
67
|
+
if (!TABLE_TAG.test(tag)) {
|
|
68
|
+
return void 0;
|
|
69
|
+
}
|
|
70
|
+
const value = tag.slice(5);
|
|
71
|
+
const key = tag.slice(0, 2);
|
|
72
|
+
if (key === "LN") {
|
|
73
|
+
length = +value;
|
|
74
|
+
} else if (key === "SN") {
|
|
75
|
+
refName = value;
|
|
76
|
+
} else if (key === "SO") {
|
|
77
|
+
start = +value;
|
|
78
|
+
} else {
|
|
79
|
+
rank = +value;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
const stable = refName !== void 0 && start !== void 0 && rank !== void 0 ? { refName, start, rank } : void 0;
|
|
83
|
+
return { name, length, stable };
|
|
84
|
+
}
|
|
85
|
+
function readWalkBody(line, from, segments, steps) {
|
|
86
|
+
let reversed = 0;
|
|
87
|
+
let start = -1;
|
|
88
|
+
let value = 0;
|
|
89
|
+
let decimal = true;
|
|
90
|
+
const finish = (end) => {
|
|
91
|
+
if (start >= 0 && end > start) {
|
|
92
|
+
const node = decimal && end - start < 16 && (end - start === 1 || line.charCodeAt(start) !== ZERO) ? segments.ofNumber(value) : void 0;
|
|
93
|
+
steps.push(node ?? segments.of(line.slice(start, end)), reversed);
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
let i = from;
|
|
97
|
+
for (; i < line.length; i++) {
|
|
98
|
+
const ch = line.charCodeAt(i);
|
|
99
|
+
if (ch === GT || ch === LT) {
|
|
100
|
+
finish(i);
|
|
101
|
+
reversed = ch === LT ? 1 : 0;
|
|
102
|
+
start = i + 1;
|
|
103
|
+
value = 0;
|
|
104
|
+
decimal = true;
|
|
105
|
+
} else if (ch === TAB) {
|
|
106
|
+
break;
|
|
107
|
+
} else if (decimal && ch >= ZERO && ch <= NINE) {
|
|
108
|
+
value = value * 10 + ch - ZERO;
|
|
109
|
+
} else {
|
|
110
|
+
decimal = false;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
finish(i);
|
|
114
|
+
}
|
|
115
|
+
function walkFields(line) {
|
|
116
|
+
const fields = [];
|
|
117
|
+
let at = 0;
|
|
118
|
+
while (fields.length < 6) {
|
|
119
|
+
const tab = line.indexOf(" ", at);
|
|
120
|
+
if (tab === -1) {
|
|
121
|
+
return void 0;
|
|
122
|
+
}
|
|
123
|
+
fields.push(line.slice(at, tab));
|
|
124
|
+
at = tab + 1;
|
|
125
|
+
}
|
|
126
|
+
const [, sample, haplotype, contig, start, end] = fields;
|
|
127
|
+
return sample && haplotype && contig && start && end && at < line.length ? { sample, haplotype, contig, start, end, body: at } : void 0;
|
|
128
|
+
}
|
|
129
|
+
function gfaTables(text) {
|
|
130
|
+
const lines = text.split("\n");
|
|
131
|
+
const segments = new SegmentIndex();
|
|
132
|
+
const lengths = [];
|
|
133
|
+
const refs = [];
|
|
134
|
+
const starts = [];
|
|
135
|
+
const ranks = [];
|
|
136
|
+
const refNames = [];
|
|
137
|
+
const refIndex = /* @__PURE__ */ new Map();
|
|
138
|
+
for (const raw of lines) {
|
|
139
|
+
if (UNTABLED_RECORD.test(raw)) {
|
|
140
|
+
return void 0;
|
|
141
|
+
}
|
|
142
|
+
if (raw.startsWith("S ")) {
|
|
143
|
+
const s = readSegment(trimCR(raw));
|
|
144
|
+
if (!s || segments.has(s.name)) {
|
|
145
|
+
return void 0;
|
|
146
|
+
}
|
|
147
|
+
segments.add(s.name);
|
|
148
|
+
lengths.push(s.length);
|
|
149
|
+
let ref = -1;
|
|
150
|
+
if (s.stable) {
|
|
151
|
+
ref = refIndex.get(s.stable.refName) ?? refNames.length;
|
|
152
|
+
if (ref === refNames.length) {
|
|
153
|
+
refNames.push(s.stable.refName);
|
|
154
|
+
refIndex.set(s.stable.refName, ref);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
refs.push(ref);
|
|
158
|
+
starts.push(s.stable?.start ?? 0);
|
|
159
|
+
ranks.push(s.stable?.rank ?? 0);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
const from = [];
|
|
163
|
+
const to = [];
|
|
164
|
+
const strands = [];
|
|
165
|
+
const names = [];
|
|
166
|
+
const walkStarts = [];
|
|
167
|
+
const walkEnds = [];
|
|
168
|
+
const offsets = [0];
|
|
169
|
+
const steps = new Steps();
|
|
170
|
+
for (const raw of lines) {
|
|
171
|
+
if (raw.startsWith("L ")) {
|
|
172
|
+
const [, source, strand1, target, strand2] = trimCR(raw).split(" ");
|
|
173
|
+
if (source && target && strand2) {
|
|
174
|
+
from.push(segments.of(source));
|
|
175
|
+
to.push(segments.of(target));
|
|
176
|
+
strands.push((strand1 === "-" ? 1 : 0) | (strand2 === "-" ? 2 : 0));
|
|
177
|
+
}
|
|
178
|
+
} else if (raw.startsWith("W ")) {
|
|
179
|
+
const line = trimCR(raw);
|
|
180
|
+
const w = walkFields(line);
|
|
181
|
+
if (w) {
|
|
182
|
+
names.push(`${w.sample}#${w.haplotype}#${w.contig}`);
|
|
183
|
+
walkStarts.push(w.start === "*" ? 0 : +w.start);
|
|
184
|
+
walkEnds.push(w.end === "*" ? -1 : +w.end);
|
|
185
|
+
readWalkBody(line, w.body, segments, steps);
|
|
186
|
+
if (steps.length === offsets.at(-1)) {
|
|
187
|
+
return void 0;
|
|
188
|
+
}
|
|
189
|
+
offsets.push(steps.length);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
return {
|
|
194
|
+
nodes: {
|
|
195
|
+
names: segments.names,
|
|
196
|
+
lengths: Int32Array.from(lengths),
|
|
197
|
+
refs: Int32Array.from(refs),
|
|
198
|
+
starts: Float64Array.from(starts),
|
|
199
|
+
ranks: Int32Array.from(ranks),
|
|
200
|
+
refNames
|
|
201
|
+
},
|
|
202
|
+
links: {
|
|
203
|
+
from: Int32Array.from(from),
|
|
204
|
+
to: Int32Array.from(to),
|
|
205
|
+
strands: Uint8Array.from(strands)
|
|
206
|
+
},
|
|
207
|
+
walks: {
|
|
208
|
+
names,
|
|
209
|
+
starts: Float64Array.from(walkStarts),
|
|
210
|
+
ends: Float64Array.from(walkEnds),
|
|
211
|
+
offsets: Int32Array.from(offsets),
|
|
212
|
+
steps: steps.nodes.slice(0, steps.length),
|
|
213
|
+
reversed: steps.reversed.slice(0, steps.length)
|
|
214
|
+
}
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
export {
|
|
219
|
+
gfaTables
|
|
220
|
+
};
|
|
@@ -48,7 +48,7 @@ function chooseReferencePath(anchorPaths, preferred) {
|
|
|
48
48
|
return named ?? anchorPaths[0];
|
|
49
49
|
}
|
|
50
50
|
var OFF_REFERENCE_RANK = 1;
|
|
51
|
-
function anchorNode(node, visits, reference) {
|
|
51
|
+
function anchorNode(node, visits, reference, samplesOf) {
|
|
52
52
|
let anchored = node;
|
|
53
53
|
if (visits && visits.length > 0) {
|
|
54
54
|
const anchor = visits.find((v) => v.path === reference) ?? visits[0];
|
|
@@ -60,22 +60,47 @@ function anchorNode(node, visits, reference) {
|
|
|
60
60
|
rank: anchor.path === reference ? REFERENCE_RANK : OFF_REFERENCE_RANK,
|
|
61
61
|
strand: anchor.strand
|
|
62
62
|
},
|
|
63
|
-
samples:
|
|
63
|
+
samples: samplesOf(visits)
|
|
64
64
|
};
|
|
65
65
|
}
|
|
66
66
|
return anchored;
|
|
67
67
|
}
|
|
68
|
+
function sampleSorter(paths) {
|
|
69
|
+
const sorted = [...new Set(paths.map((p) => p.sample))].sort();
|
|
70
|
+
const rank = new Map(sorted.map((sample, i) => [sample, i]));
|
|
71
|
+
const seen = new Uint8Array(sorted.length);
|
|
72
|
+
return (visits) => {
|
|
73
|
+
const ranks = [];
|
|
74
|
+
for (const { sample } of visits) {
|
|
75
|
+
const r = rank.get(sample);
|
|
76
|
+
if (r === void 0) {
|
|
77
|
+
ranks.forEach((r2) => seen[r2] = 0);
|
|
78
|
+
return [...new Set(visits.map((v) => v.sample))].sort();
|
|
79
|
+
}
|
|
80
|
+
if (seen[r] === 0) {
|
|
81
|
+
seen[r] = 1;
|
|
82
|
+
ranks.push(r);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
ranks.forEach((r) => seen[r] = 0);
|
|
86
|
+
return Array.from(Int32Array.from(ranks).sort(), (r) => sorted[r]);
|
|
87
|
+
};
|
|
88
|
+
}
|
|
68
89
|
function anchorFromPaths(graph, preferred) {
|
|
69
90
|
const { anchorPaths, pathVisits } = graph;
|
|
70
91
|
const reference = anchorPaths && pathVisits ? chooseReferencePath(anchorPaths, preferred) : void 0;
|
|
71
|
-
|
|
92
|
+
if (!reference || !anchorPaths || !pathVisits) {
|
|
93
|
+
return graph;
|
|
94
|
+
}
|
|
95
|
+
const samplesOf = sampleSorter(anchorPaths);
|
|
96
|
+
return {
|
|
72
97
|
...graph,
|
|
73
98
|
nodes: graph.nodes.map(
|
|
74
|
-
(node) => anchorNode(node, pathVisits.get(node.name), reference.name)
|
|
99
|
+
(node) => anchorNode(node, pathVisits.get(node.name), reference.name, samplesOf)
|
|
75
100
|
),
|
|
76
101
|
anchoredBy: "paths",
|
|
77
102
|
referencePath: reference.name
|
|
78
|
-
}
|
|
103
|
+
};
|
|
79
104
|
}
|
|
80
105
|
function anchorGraph(graph, preferred) {
|
|
81
106
|
return graph.anchoredBy === "tags" ? graph : anchorFromPaths(graph, preferred);
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
hasTubeMapPaths,
|
|
7
7
|
tubeMapLayout,
|
|
8
8
|
tubeMapReferenceLayout
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-HOZI3FBG.js";
|
|
10
10
|
import {
|
|
11
11
|
anchoredLayout
|
|
12
12
|
} from "./chunk-L3O7AWLI.js";
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
} from "./chunk-HNQPEMYE.js";
|
|
16
16
|
import {
|
|
17
17
|
walkRowLayout
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-TOVOJNT7.js";
|
|
19
19
|
import {
|
|
20
20
|
isBackbone,
|
|
21
21
|
isOffReference
|