@genome-spy/app 0.56.1 → 0.58.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/_commonjsHelpers-DjF3Plf2.js +26 -0
- package/dist/app.css +1 -0
- package/dist/index-BftNdA0O.js +27 -0
- package/dist/index-C08YCM2T.js +539 -0
- package/dist/index-CCJIjehY.js +218 -0
- package/dist/index-CalimFw3.js +2131 -0
- package/dist/index-DS2hvLgl.js +3425 -0
- package/dist/index-DTcHjAHp.js +505 -0
- package/dist/index-Dec7VcMU.js +626 -0
- package/dist/index-DnIkxb0L.js +1025 -0
- package/dist/index-DwLfOHEk.js +1319 -0
- package/dist/{index-HGQZ77IK.js → index-Ww3TAo6_.js} +7 -7
- package/dist/{index-CjesiOz_.js → index-vgGDWUPz.js} +24 -24
- package/dist/index.es.js +9704 -10544
- package/dist/index.js +598 -789
- package/dist/long-BviWyoZx.js +2387 -0
- package/dist/remoteFile-BuaqFGWk.js +94 -0
- package/package.json +3 -3
- package/dist/_commonjsHelpers-DSebQMb9.js +0 -28
- package/dist/index-B6haPltu.js +0 -1042
- package/dist/index-BhtH2nrr.js +0 -513
- package/dist/index-BpoXW6_f.js +0 -1370
- package/dist/index-COovE1Oo.js +0 -3997
- package/dist/index-WACuLhO6.js +0 -2136
- package/dist/index-_ftu0t0z.js +0 -500
- package/dist/index-nCZhu2o-.js +0 -613
- package/dist/long-BXK3UEks.js +0 -2375
- package/dist/remoteFile-DuIsnepi.js +0 -90
- package/dist/style.css +0 -1
@@ -0,0 +1,1319 @@
|
|
1
|
+
import { L as Y, u as P, a as Q } from "./long-BviWyoZx.js";
|
2
|
+
import { b as y } from "./index-BftNdA0O.js";
|
3
|
+
import { L as C } from "./__vite-browser-external-C--ziKoh.js";
|
4
|
+
import { R as L } from "./remoteFile-BuaqFGWk.js";
|
5
|
+
import { A as W, L as X } from "./index-CCJIjehY.js";
|
6
|
+
class O {
|
7
|
+
constructor(e, t) {
|
8
|
+
this.blockPosition = e, this.dataPosition = t;
|
9
|
+
}
|
10
|
+
toString() {
|
11
|
+
return `${this.blockPosition}:${this.dataPosition}`;
|
12
|
+
}
|
13
|
+
compareTo(e) {
|
14
|
+
return this.blockPosition - e.blockPosition || this.dataPosition - e.dataPosition;
|
15
|
+
}
|
16
|
+
static min(...e) {
|
17
|
+
let t, n = 0;
|
18
|
+
for (; !t; n += 1)
|
19
|
+
t = e[n];
|
20
|
+
for (; n < e.length; n += 1)
|
21
|
+
t.compareTo(e[n]) > 0 && (t = e[n]);
|
22
|
+
return t;
|
23
|
+
}
|
24
|
+
}
|
25
|
+
function E(o, e = 0, t = !1) {
|
26
|
+
if (t)
|
27
|
+
throw new Error("big-endian virtual file offsets not implemented");
|
28
|
+
return new O(o[e + 7] * 1099511627776 + o[e + 6] * 4294967296 + o[e + 5] * 16777216 + o[e + 4] * 65536 + o[e + 3] * 256 + o[e + 2], o[e + 1] << 8 | o[e]);
|
29
|
+
}
|
30
|
+
class F {
|
31
|
+
constructor(e, t, n, r) {
|
32
|
+
this.minv = e, this.maxv = t, this.bin = n, this._fetchedSize = r;
|
33
|
+
}
|
34
|
+
toUniqueString() {
|
35
|
+
return `${this.minv.toString()}..${this.maxv.toString()} (bin ${this.bin}, fetchedSize ${this.fetchedSize()})`;
|
36
|
+
}
|
37
|
+
toString() {
|
38
|
+
return this.toUniqueString();
|
39
|
+
}
|
40
|
+
compareTo(e) {
|
41
|
+
return this.minv.compareTo(e.minv) || this.maxv.compareTo(e.maxv) || this.bin - e.bin;
|
42
|
+
}
|
43
|
+
fetchedSize() {
|
44
|
+
return this._fetchedSize !== void 0 ? this._fetchedSize : this.maxv.blockPosition + 65536 - this.minv.blockPosition;
|
45
|
+
}
|
46
|
+
}
|
47
|
+
function J(o) {
|
48
|
+
return new Promise((e) => setTimeout(e, o));
|
49
|
+
}
|
50
|
+
function K(o) {
|
51
|
+
if (o && o.aborted)
|
52
|
+
if (typeof DOMException > "u") {
|
53
|
+
const e = new Error("aborted");
|
54
|
+
throw e.code = "ERR_ABORTED", e;
|
55
|
+
} else
|
56
|
+
throw new DOMException("aborted", "AbortError");
|
57
|
+
}
|
58
|
+
function Z(o, e) {
|
59
|
+
return e.minv.blockPosition - o.maxv.blockPosition < 65e3 && e.maxv.blockPosition - o.minv.blockPosition < 5e6;
|
60
|
+
}
|
61
|
+
function ee(o = {}) {
|
62
|
+
return "aborted" in o ? { signal: o } : o;
|
63
|
+
}
|
64
|
+
function z(o, e) {
|
65
|
+
const t = [];
|
66
|
+
let n;
|
67
|
+
if (o.length === 0)
|
68
|
+
return o;
|
69
|
+
o.sort((r, s) => {
|
70
|
+
const i = r.minv.blockPosition - s.minv.blockPosition;
|
71
|
+
return i === 0 ? r.minv.dataPosition - s.minv.dataPosition : i;
|
72
|
+
});
|
73
|
+
for (const r of o)
|
74
|
+
(!e || r.maxv.compareTo(e) > 0) && (n === void 0 ? (t.push(r), n = r) : Z(n, r) ? r.maxv.compareTo(n.maxv) > 0 && (n.maxv = r.maxv) : (t.push(r), n = r));
|
75
|
+
return t;
|
76
|
+
}
|
77
|
+
function G(o, e) {
|
78
|
+
return {
|
79
|
+
lineCount: Y.fromBytesLE(Array.prototype.slice.call(o, e, e + 8), !0).toNumber()
|
80
|
+
};
|
81
|
+
}
|
82
|
+
function S(o, e) {
|
83
|
+
return o ? o.compareTo(e) > 0 ? e : o : e;
|
84
|
+
}
|
85
|
+
function te(o, e = (t) => t) {
|
86
|
+
let t = 0, n = 0;
|
87
|
+
const r = [], s = {};
|
88
|
+
for (let i = 0; i < o.length; i += 1)
|
89
|
+
if (!o[i]) {
|
90
|
+
if (n < i) {
|
91
|
+
let c = o.toString("utf8", n, i);
|
92
|
+
c = e(c), r[t] = c, s[c] = t;
|
93
|
+
}
|
94
|
+
n = i + 1, t += 1;
|
95
|
+
}
|
96
|
+
return { refNameToId: s, refIdToName: r };
|
97
|
+
}
|
98
|
+
class H {
|
99
|
+
/**
|
100
|
+
* @param {filehandle} filehandle
|
101
|
+
* @param {function} [renameRefSeqs]
|
102
|
+
*/
|
103
|
+
constructor({ filehandle: e, renameRefSeq: t = (n) => n }) {
|
104
|
+
this.filehandle = e, this.renameRefSeq = t;
|
105
|
+
}
|
106
|
+
}
|
107
|
+
const ne = 21578050;
|
108
|
+
function re(o, e) {
|
109
|
+
return o - o % e;
|
110
|
+
}
|
111
|
+
function se(o, e) {
|
112
|
+
return o - o % e + e;
|
113
|
+
}
|
114
|
+
function ie(o, e) {
|
115
|
+
return e -= 1, [
|
116
|
+
[0, 0],
|
117
|
+
[1 + (o >> 26), 1 + (e >> 26)],
|
118
|
+
[9 + (o >> 23), 9 + (e >> 23)],
|
119
|
+
[73 + (o >> 20), 73 + (e >> 20)],
|
120
|
+
[585 + (o >> 17), 585 + (e >> 17)],
|
121
|
+
[4681 + (o >> 14), 4681 + (e >> 14)]
|
122
|
+
];
|
123
|
+
}
|
124
|
+
class v extends H {
|
125
|
+
async lineCount(e, t) {
|
126
|
+
var n, r;
|
127
|
+
return ((r = (n = (await this.parse(t)).indices[e]) === null || n === void 0 ? void 0 : n.stats) === null || r === void 0 ? void 0 : r.lineCount) || 0;
|
128
|
+
}
|
129
|
+
// fetch and parse the index
|
130
|
+
async _parse(e) {
|
131
|
+
const t = await this.filehandle.readFile(e);
|
132
|
+
if (t.readUInt32LE(0) !== ne)
|
133
|
+
throw new Error("Not a BAI file");
|
134
|
+
const n = t.readInt32LE(4), s = ((1 << (5 + 1) * 3) - 1) / 7;
|
135
|
+
let i = 8, c;
|
136
|
+
const a = new Array(n);
|
137
|
+
for (let d = 0; d < n; d++) {
|
138
|
+
const f = t.readInt32LE(i);
|
139
|
+
let h;
|
140
|
+
i += 4;
|
141
|
+
const l = {};
|
142
|
+
for (let b = 0; b < f; b += 1) {
|
143
|
+
const u = t.readUInt32LE(i);
|
144
|
+
if (i += 4, u === s + 1)
|
145
|
+
i += 4, h = G(t, i + 16), i += 32;
|
146
|
+
else {
|
147
|
+
if (u > s + 1)
|
148
|
+
throw new Error("bai index contains too many bins, please use CSI");
|
149
|
+
{
|
150
|
+
const g = t.readInt32LE(i);
|
151
|
+
i += 4;
|
152
|
+
const w = new Array(g);
|
153
|
+
for (let _ = 0; _ < g; _++) {
|
154
|
+
const I = E(t, i);
|
155
|
+
i += 8;
|
156
|
+
const M = E(t, i);
|
157
|
+
i += 8, c = S(c, I), w[_] = new F(I, M, u);
|
158
|
+
}
|
159
|
+
l[u] = w;
|
160
|
+
}
|
161
|
+
}
|
162
|
+
}
|
163
|
+
const x = t.readInt32LE(i);
|
164
|
+
i += 4;
|
165
|
+
const m = new Array(x);
|
166
|
+
for (let b = 0; b < x; b++) {
|
167
|
+
const u = E(t, i);
|
168
|
+
i += 8, c = S(c, u), m[b] = u;
|
169
|
+
}
|
170
|
+
a[d] = { binIndex: l, linearIndex: m, stats: h };
|
171
|
+
}
|
172
|
+
return {
|
173
|
+
bai: !0,
|
174
|
+
firstDataLine: c,
|
175
|
+
maxBlockSize: 65536,
|
176
|
+
indices: a,
|
177
|
+
refCount: n
|
178
|
+
};
|
179
|
+
}
|
180
|
+
async indexCov(e, t, n, r = {}) {
|
181
|
+
const i = t !== void 0, a = (await this.parse(r)).indices[e];
|
182
|
+
if (!a)
|
183
|
+
return [];
|
184
|
+
const { linearIndex: d = [], stats: f } = a;
|
185
|
+
if (d.length === 0)
|
186
|
+
return [];
|
187
|
+
const h = n === void 0 ? (d.length - 1) * 16384 : se(n, 16384), l = t === void 0 ? 0 : re(t, 16384), x = i ? new Array((h - l) / 16384) : new Array(d.length - 1), m = d[d.length - 1].blockPosition;
|
188
|
+
if (h > (d.length - 1) * 16384)
|
189
|
+
throw new Error("query outside of range of linear index");
|
190
|
+
let b = d[l / 16384].blockPosition;
|
191
|
+
for (let u = l / 16384, g = 0; u < h / 16384; u++, g++)
|
192
|
+
x[g] = {
|
193
|
+
score: d[u + 1].blockPosition - b,
|
194
|
+
start: u * 16384,
|
195
|
+
end: u * 16384 + 16384
|
196
|
+
}, b = d[u + 1].blockPosition;
|
197
|
+
return x.map((u) => ({
|
198
|
+
...u,
|
199
|
+
score: u.score * ((f == null ? void 0 : f.lineCount) || 0) / m
|
200
|
+
}));
|
201
|
+
}
|
202
|
+
async blocksForRange(e, t, n, r = {}) {
|
203
|
+
t < 0 && (t = 0);
|
204
|
+
const s = await this.parse(r);
|
205
|
+
if (!s)
|
206
|
+
return [];
|
207
|
+
const i = s.indices[e];
|
208
|
+
if (!i)
|
209
|
+
return [];
|
210
|
+
const c = ie(t, n), a = [];
|
211
|
+
for (const [x, m] of c)
|
212
|
+
for (let b = x; b <= m; b++)
|
213
|
+
if (i.binIndex[b]) {
|
214
|
+
const u = i.binIndex[b];
|
215
|
+
for (const g of u)
|
216
|
+
a.push(new F(g.minv, g.maxv, b));
|
217
|
+
}
|
218
|
+
const d = i.linearIndex.length;
|
219
|
+
let f;
|
220
|
+
const h = Math.min(t >> 14, d - 1), l = Math.min(n >> 14, d - 1);
|
221
|
+
for (let x = h; x <= l; ++x) {
|
222
|
+
const m = i.linearIndex[x];
|
223
|
+
m && (!f || m.compareTo(f) < 0) && (f = m);
|
224
|
+
}
|
225
|
+
return z(a, f);
|
226
|
+
}
|
227
|
+
async parse(e = {}) {
|
228
|
+
return this.setupP || (this.setupP = this._parse(e).catch((t) => {
|
229
|
+
throw this.setupP = void 0, t;
|
230
|
+
})), this.setupP;
|
231
|
+
}
|
232
|
+
async hasRefSeq(e, t = {}) {
|
233
|
+
var n;
|
234
|
+
return !!(!((n = (await this.parse(t)).indices[e]) === null || n === void 0) && n.binIndex);
|
235
|
+
}
|
236
|
+
}
|
237
|
+
let B = [
|
238
|
+
0,
|
239
|
+
1996959894,
|
240
|
+
3993919788,
|
241
|
+
2567524794,
|
242
|
+
124634137,
|
243
|
+
1886057615,
|
244
|
+
3915621685,
|
245
|
+
2657392035,
|
246
|
+
249268274,
|
247
|
+
2044508324,
|
248
|
+
3772115230,
|
249
|
+
2547177864,
|
250
|
+
162941995,
|
251
|
+
2125561021,
|
252
|
+
3887607047,
|
253
|
+
2428444049,
|
254
|
+
498536548,
|
255
|
+
1789927666,
|
256
|
+
4089016648,
|
257
|
+
2227061214,
|
258
|
+
450548861,
|
259
|
+
1843258603,
|
260
|
+
4107580753,
|
261
|
+
2211677639,
|
262
|
+
325883990,
|
263
|
+
1684777152,
|
264
|
+
4251122042,
|
265
|
+
2321926636,
|
266
|
+
335633487,
|
267
|
+
1661365465,
|
268
|
+
4195302755,
|
269
|
+
2366115317,
|
270
|
+
997073096,
|
271
|
+
1281953886,
|
272
|
+
3579855332,
|
273
|
+
2724688242,
|
274
|
+
1006888145,
|
275
|
+
1258607687,
|
276
|
+
3524101629,
|
277
|
+
2768942443,
|
278
|
+
901097722,
|
279
|
+
1119000684,
|
280
|
+
3686517206,
|
281
|
+
2898065728,
|
282
|
+
853044451,
|
283
|
+
1172266101,
|
284
|
+
3705015759,
|
285
|
+
2882616665,
|
286
|
+
651767980,
|
287
|
+
1373503546,
|
288
|
+
3369554304,
|
289
|
+
3218104598,
|
290
|
+
565507253,
|
291
|
+
1454621731,
|
292
|
+
3485111705,
|
293
|
+
3099436303,
|
294
|
+
671266974,
|
295
|
+
1594198024,
|
296
|
+
3322730930,
|
297
|
+
2970347812,
|
298
|
+
795835527,
|
299
|
+
1483230225,
|
300
|
+
3244367275,
|
301
|
+
3060149565,
|
302
|
+
1994146192,
|
303
|
+
31158534,
|
304
|
+
2563907772,
|
305
|
+
4023717930,
|
306
|
+
1907459465,
|
307
|
+
112637215,
|
308
|
+
2680153253,
|
309
|
+
3904427059,
|
310
|
+
2013776290,
|
311
|
+
251722036,
|
312
|
+
2517215374,
|
313
|
+
3775830040,
|
314
|
+
2137656763,
|
315
|
+
141376813,
|
316
|
+
2439277719,
|
317
|
+
3865271297,
|
318
|
+
1802195444,
|
319
|
+
476864866,
|
320
|
+
2238001368,
|
321
|
+
4066508878,
|
322
|
+
1812370925,
|
323
|
+
453092731,
|
324
|
+
2181625025,
|
325
|
+
4111451223,
|
326
|
+
1706088902,
|
327
|
+
314042704,
|
328
|
+
2344532202,
|
329
|
+
4240017532,
|
330
|
+
1658658271,
|
331
|
+
366619977,
|
332
|
+
2362670323,
|
333
|
+
4224994405,
|
334
|
+
1303535960,
|
335
|
+
984961486,
|
336
|
+
2747007092,
|
337
|
+
3569037538,
|
338
|
+
1256170817,
|
339
|
+
1037604311,
|
340
|
+
2765210733,
|
341
|
+
3554079995,
|
342
|
+
1131014506,
|
343
|
+
879679996,
|
344
|
+
2909243462,
|
345
|
+
3663771856,
|
346
|
+
1141124467,
|
347
|
+
855842277,
|
348
|
+
2852801631,
|
349
|
+
3708648649,
|
350
|
+
1342533948,
|
351
|
+
654459306,
|
352
|
+
3188396048,
|
353
|
+
3373015174,
|
354
|
+
1466479909,
|
355
|
+
544179635,
|
356
|
+
3110523913,
|
357
|
+
3462522015,
|
358
|
+
1591671054,
|
359
|
+
702138776,
|
360
|
+
2966460450,
|
361
|
+
3352799412,
|
362
|
+
1504918807,
|
363
|
+
783551873,
|
364
|
+
3082640443,
|
365
|
+
3233442989,
|
366
|
+
3988292384,
|
367
|
+
2596254646,
|
368
|
+
62317068,
|
369
|
+
1957810842,
|
370
|
+
3939845945,
|
371
|
+
2647816111,
|
372
|
+
81470997,
|
373
|
+
1943803523,
|
374
|
+
3814918930,
|
375
|
+
2489596804,
|
376
|
+
225274430,
|
377
|
+
2053790376,
|
378
|
+
3826175755,
|
379
|
+
2466906013,
|
380
|
+
167816743,
|
381
|
+
2097651377,
|
382
|
+
4027552580,
|
383
|
+
2265490386,
|
384
|
+
503444072,
|
385
|
+
1762050814,
|
386
|
+
4150417245,
|
387
|
+
2154129355,
|
388
|
+
426522225,
|
389
|
+
1852507879,
|
390
|
+
4275313526,
|
391
|
+
2312317920,
|
392
|
+
282753626,
|
393
|
+
1742555852,
|
394
|
+
4189708143,
|
395
|
+
2394877945,
|
396
|
+
397917763,
|
397
|
+
1622183637,
|
398
|
+
3604390888,
|
399
|
+
2714866558,
|
400
|
+
953729732,
|
401
|
+
1340076626,
|
402
|
+
3518719985,
|
403
|
+
2797360999,
|
404
|
+
1068828381,
|
405
|
+
1219638859,
|
406
|
+
3624741850,
|
407
|
+
2936675148,
|
408
|
+
906185462,
|
409
|
+
1090812512,
|
410
|
+
3747672003,
|
411
|
+
2825379669,
|
412
|
+
829329135,
|
413
|
+
1181335161,
|
414
|
+
3412177804,
|
415
|
+
3160834842,
|
416
|
+
628085408,
|
417
|
+
1382605366,
|
418
|
+
3423369109,
|
419
|
+
3138078467,
|
420
|
+
570562233,
|
421
|
+
1426400815,
|
422
|
+
3317316542,
|
423
|
+
2998733608,
|
424
|
+
733239954,
|
425
|
+
1555261956,
|
426
|
+
3268935591,
|
427
|
+
3050360625,
|
428
|
+
752459403,
|
429
|
+
1541320221,
|
430
|
+
2607071920,
|
431
|
+
3965973030,
|
432
|
+
1969922972,
|
433
|
+
40735498,
|
434
|
+
2617837225,
|
435
|
+
3943577151,
|
436
|
+
1913087877,
|
437
|
+
83908371,
|
438
|
+
2512341634,
|
439
|
+
3803740692,
|
440
|
+
2075208622,
|
441
|
+
213261112,
|
442
|
+
2463272603,
|
443
|
+
3855990285,
|
444
|
+
2094854071,
|
445
|
+
198958881,
|
446
|
+
2262029012,
|
447
|
+
4057260610,
|
448
|
+
1759359992,
|
449
|
+
534414190,
|
450
|
+
2176718541,
|
451
|
+
4139329115,
|
452
|
+
1873836001,
|
453
|
+
414664567,
|
454
|
+
2282248934,
|
455
|
+
4279200368,
|
456
|
+
1711684554,
|
457
|
+
285281116,
|
458
|
+
2405801727,
|
459
|
+
4167216745,
|
460
|
+
1634467795,
|
461
|
+
376229701,
|
462
|
+
2685067896,
|
463
|
+
3608007406,
|
464
|
+
1308918612,
|
465
|
+
956543938,
|
466
|
+
2808555105,
|
467
|
+
3495958263,
|
468
|
+
1231636301,
|
469
|
+
1047427035,
|
470
|
+
2932959818,
|
471
|
+
3654703836,
|
472
|
+
1088359270,
|
473
|
+
936918e3,
|
474
|
+
2847714899,
|
475
|
+
3736837829,
|
476
|
+
1202900863,
|
477
|
+
817233897,
|
478
|
+
3183342108,
|
479
|
+
3401237130,
|
480
|
+
1404277552,
|
481
|
+
615818150,
|
482
|
+
3134207493,
|
483
|
+
3453421203,
|
484
|
+
1423857449,
|
485
|
+
601450431,
|
486
|
+
3009837614,
|
487
|
+
3294710456,
|
488
|
+
1567103746,
|
489
|
+
711928724,
|
490
|
+
3020668471,
|
491
|
+
3272380065,
|
492
|
+
1510334235,
|
493
|
+
755167117
|
494
|
+
];
|
495
|
+
typeof Int32Array < "u" && (B = new Int32Array(B));
|
496
|
+
const ae = (o, e) => {
|
497
|
+
let t = e === 0 ? 0 : ~~e ^ -1;
|
498
|
+
for (let n = 0; n < o.length; n++)
|
499
|
+
t = B[(t ^ o[n]) & 255] ^ t >>> 8;
|
500
|
+
return t ^ -1;
|
501
|
+
}, N = (o, e) => y.Buffer.from(o, e);
|
502
|
+
function oe(o, e) {
|
503
|
+
const t = (n, r) => e(N(n), r) >>> 0;
|
504
|
+
return t.signed = (n, r) => e(N(n), r), t.unsigned = t, t.model = o, t;
|
505
|
+
}
|
506
|
+
const ce = oe("crc-32", ae), de = 21582659, fe = 38359875;
|
507
|
+
function he(o, e) {
|
508
|
+
return o * 2 ** e;
|
509
|
+
}
|
510
|
+
function q(o, e) {
|
511
|
+
return Math.floor(o / 2 ** e);
|
512
|
+
}
|
513
|
+
class T extends H {
|
514
|
+
constructor() {
|
515
|
+
super(...arguments), this.maxBinNumber = 0, this.depth = 0, this.minShift = 0;
|
516
|
+
}
|
517
|
+
async lineCount(e, t) {
|
518
|
+
var n, r;
|
519
|
+
return ((r = (n = (await this.parse(t)).indices[e]) === null || n === void 0 ? void 0 : n.stats) === null || r === void 0 ? void 0 : r.lineCount) || 0;
|
520
|
+
}
|
521
|
+
async indexCov() {
|
522
|
+
return [];
|
523
|
+
}
|
524
|
+
parseAuxData(e, t) {
|
525
|
+
const n = e.readInt32LE(t), r = n & 65536 ? "zero-based-half-open" : "1-based-closed", s = { 0: "generic", 1: "SAM", 2: "VCF" }[n & 15];
|
526
|
+
if (!s)
|
527
|
+
throw new Error(`invalid Tabix preset format flags ${n}`);
|
528
|
+
const i = {
|
529
|
+
ref: e.readInt32LE(t + 4),
|
530
|
+
start: e.readInt32LE(t + 8),
|
531
|
+
end: e.readInt32LE(t + 12)
|
532
|
+
}, c = e.readInt32LE(t + 16), a = c ? String.fromCharCode(c) : "", d = e.readInt32LE(t + 20), f = e.readInt32LE(t + 24);
|
533
|
+
return {
|
534
|
+
columnNumbers: i,
|
535
|
+
coordinateType: r,
|
536
|
+
metaValue: c,
|
537
|
+
metaChar: a,
|
538
|
+
skipLines: d,
|
539
|
+
format: s,
|
540
|
+
formatFlags: n,
|
541
|
+
...te(e.subarray(t + 28, t + 28 + f), this.renameRefSeq)
|
542
|
+
};
|
543
|
+
}
|
544
|
+
// fetch and parse the index
|
545
|
+
async _parse(e) {
|
546
|
+
const t = await this.filehandle.readFile(e), n = await P(t);
|
547
|
+
let r;
|
548
|
+
if (n.readUInt32LE(0) === de)
|
549
|
+
r = 1;
|
550
|
+
else if (n.readUInt32LE(0) === fe)
|
551
|
+
r = 2;
|
552
|
+
else
|
553
|
+
throw new Error("Not a CSI file");
|
554
|
+
this.minShift = n.readInt32LE(4), this.depth = n.readInt32LE(8), this.maxBinNumber = ((1 << (this.depth + 1) * 3) - 1) / 7;
|
555
|
+
const s = n.readInt32LE(12), i = s >= 30 ? this.parseAuxData(n, 16) : void 0, c = n.readInt32LE(16 + s);
|
556
|
+
let a = 16 + s + 4, d;
|
557
|
+
const f = new Array(c);
|
558
|
+
for (let h = 0; h < c; h++) {
|
559
|
+
const l = n.readInt32LE(a);
|
560
|
+
a += 4;
|
561
|
+
const x = {};
|
562
|
+
let m;
|
563
|
+
for (let b = 0; b < l; b++) {
|
564
|
+
const u = n.readUInt32LE(a);
|
565
|
+
if (a += 4, u > this.maxBinNumber)
|
566
|
+
m = G(n, a + 28), a += 44;
|
567
|
+
else {
|
568
|
+
d = S(d, E(n, a)), a += 8;
|
569
|
+
const g = n.readInt32LE(a);
|
570
|
+
a += 4;
|
571
|
+
const w = new Array(g);
|
572
|
+
for (let _ = 0; _ < g; _ += 1) {
|
573
|
+
const I = E(n, a);
|
574
|
+
a += 8;
|
575
|
+
const M = E(n, a);
|
576
|
+
a += 8, d = S(d, I), w[_] = new F(I, M, u);
|
577
|
+
}
|
578
|
+
x[u] = w;
|
579
|
+
}
|
580
|
+
}
|
581
|
+
f[h] = { binIndex: x, stats: m };
|
582
|
+
}
|
583
|
+
return {
|
584
|
+
csiVersion: r,
|
585
|
+
firstDataLine: d,
|
586
|
+
indices: f,
|
587
|
+
refCount: c,
|
588
|
+
csi: !0,
|
589
|
+
maxBlockSize: 65536,
|
590
|
+
...i
|
591
|
+
};
|
592
|
+
}
|
593
|
+
async blocksForRange(e, t, n, r = {}) {
|
594
|
+
t < 0 && (t = 0);
|
595
|
+
const i = (await this.parse(r)).indices[e];
|
596
|
+
if (!i)
|
597
|
+
return [];
|
598
|
+
const c = this.reg2bins(t, n);
|
599
|
+
if (c.length === 0)
|
600
|
+
return [];
|
601
|
+
const a = [];
|
602
|
+
for (const [d, f] of c)
|
603
|
+
for (let h = d; h <= f; h++)
|
604
|
+
if (i.binIndex[h]) {
|
605
|
+
const l = i.binIndex[h];
|
606
|
+
for (const x of l)
|
607
|
+
a.push(x);
|
608
|
+
}
|
609
|
+
return z(a, new O(0, 0));
|
610
|
+
}
|
611
|
+
/**
|
612
|
+
* calculate the list of bins that may overlap with region [beg,end)
|
613
|
+
* (zero-based half-open)
|
614
|
+
*/
|
615
|
+
reg2bins(e, t) {
|
616
|
+
e -= 1, e < 1 && (e = 1), t > 2 ** 50 && (t = 2 ** 34), t -= 1;
|
617
|
+
let n = 0, r = 0, s = this.minShift + this.depth * 3;
|
618
|
+
const i = [];
|
619
|
+
for (; n <= this.depth; s -= 3, r += he(1, n * 3), n += 1) {
|
620
|
+
const c = r + q(e, s), a = r + q(t, s);
|
621
|
+
if (a - c + i.length > this.maxBinNumber)
|
622
|
+
throw new Error(`query ${e}-${t} is too large for current binning scheme (shift ${this.minShift}, depth ${this.depth}), try a smaller query or a coarser index binning scheme`);
|
623
|
+
i.push([c, a]);
|
624
|
+
}
|
625
|
+
return i;
|
626
|
+
}
|
627
|
+
async parse(e = {}) {
|
628
|
+
return this.setupP || (this.setupP = this._parse(e).catch((t) => {
|
629
|
+
throw this.setupP = void 0, t;
|
630
|
+
})), this.setupP;
|
631
|
+
}
|
632
|
+
async hasRefSeq(e, t = {}) {
|
633
|
+
var n;
|
634
|
+
return !!(!((n = (await this.parse(t)).indices[e]) === null || n === void 0) && n.binIndex);
|
635
|
+
}
|
636
|
+
}
|
637
|
+
const p = {
|
638
|
+
// the read is paired in sequencing, no matter whether it is mapped in a pair
|
639
|
+
BAM_FPAIRED: 1,
|
640
|
+
// the read is mapped in a proper pair
|
641
|
+
BAM_FPROPER_PAIR: 2,
|
642
|
+
// the read itself is unmapped; conflictive with BAM_FPROPER_PAIR
|
643
|
+
BAM_FUNMAP: 4,
|
644
|
+
// the mate is unmapped
|
645
|
+
BAM_FMUNMAP: 8,
|
646
|
+
// the read is mapped to the reverse strand
|
647
|
+
BAM_FREVERSE: 16,
|
648
|
+
// the mate is mapped to the reverse strand
|
649
|
+
BAM_FMREVERSE: 32,
|
650
|
+
// this is read1
|
651
|
+
BAM_FREAD1: 64,
|
652
|
+
// this is read2
|
653
|
+
BAM_FREAD2: 128,
|
654
|
+
// not primary alignment
|
655
|
+
BAM_FSECONDARY: 256,
|
656
|
+
// QC failure
|
657
|
+
BAM_FQCFAIL: 512,
|
658
|
+
// optical or PCR duplicate
|
659
|
+
BAM_FDUP: 1024,
|
660
|
+
// supplementary alignment
|
661
|
+
BAM_FSUPPLEMENTARY: 2048
|
662
|
+
}, D = "=ACMGRSVTWYHKDBN".split(""), A = "MIDNSHP=X???????".split("");
|
663
|
+
class R {
|
664
|
+
constructor(e) {
|
665
|
+
this.bytes = e.bytes, this.fileOffset = e.fileOffset;
|
666
|
+
}
|
667
|
+
get byteArray() {
|
668
|
+
return this.bytes.byteArray;
|
669
|
+
}
|
670
|
+
get flags() {
|
671
|
+
return (this.byteArray.readInt32LE(this.bytes.start + 16) & 4294901760) >> 16;
|
672
|
+
}
|
673
|
+
get ref_id() {
|
674
|
+
return this.byteArray.readInt32LE(this.bytes.start + 4);
|
675
|
+
}
|
676
|
+
get start() {
|
677
|
+
return this.byteArray.readInt32LE(this.bytes.start + 8);
|
678
|
+
}
|
679
|
+
get end() {
|
680
|
+
return this.start + this.length_on_ref;
|
681
|
+
}
|
682
|
+
get id() {
|
683
|
+
return this.fileOffset;
|
684
|
+
}
|
685
|
+
get mq() {
|
686
|
+
const e = (this.bin_mq_nl & 65280) >> 8;
|
687
|
+
return e === 255 ? void 0 : e;
|
688
|
+
}
|
689
|
+
get score() {
|
690
|
+
return this.mq;
|
691
|
+
}
|
692
|
+
get qual() {
|
693
|
+
if (this.isSegmentUnmapped())
|
694
|
+
return;
|
695
|
+
const e = this.b0 + this.read_name_length + this.num_cigar_ops * 4 + this.num_seq_bytes;
|
696
|
+
return this.byteArray.subarray(e, e + this.seq_length);
|
697
|
+
}
|
698
|
+
get strand() {
|
699
|
+
return this.isReverseComplemented() ? -1 : 1;
|
700
|
+
}
|
701
|
+
get b0() {
|
702
|
+
return this.bytes.start + 36;
|
703
|
+
}
|
704
|
+
get name() {
|
705
|
+
return this.byteArray.toString("ascii", this.b0, this.b0 + this.read_name_length - 1);
|
706
|
+
}
|
707
|
+
get tags() {
|
708
|
+
const { byteArray: e } = this.bytes;
|
709
|
+
let t = this.b0 + this.read_name_length + this.num_cigar_ops * 4 + this.num_seq_bytes + this.seq_length;
|
710
|
+
const n = this.bytes.end, r = {};
|
711
|
+
for (; t < n; ) {
|
712
|
+
const s = String.fromCharCode(e[t], e[t + 1]), i = String.fromCharCode(e[t + 2]);
|
713
|
+
if (t += 3, i === "A")
|
714
|
+
r[s] = String.fromCharCode(e[t]), t += 1;
|
715
|
+
else if (i === "i")
|
716
|
+
r[s] = e.readInt32LE(t), t += 4;
|
717
|
+
else if (i === "I")
|
718
|
+
r[s] = e.readUInt32LE(t), t += 4;
|
719
|
+
else if (i === "c")
|
720
|
+
r[s] = e.readInt8(t), t += 1;
|
721
|
+
else if (i === "C")
|
722
|
+
r[s] = e.readUInt8(t), t += 1;
|
723
|
+
else if (i === "s")
|
724
|
+
r[s] = e.readInt16LE(t), t += 2;
|
725
|
+
else if (i === "S")
|
726
|
+
r[s] = e.readUInt16LE(t), t += 2;
|
727
|
+
else if (i === "f")
|
728
|
+
r[s] = e.readFloatLE(t), t += 4;
|
729
|
+
else if (i === "Z" || i === "H") {
|
730
|
+
const c = [];
|
731
|
+
for (; t <= n; ) {
|
732
|
+
const a = e[t++];
|
733
|
+
if (a !== 0)
|
734
|
+
c.push(String.fromCharCode(a));
|
735
|
+
else
|
736
|
+
break;
|
737
|
+
}
|
738
|
+
r[s] = c.join("");
|
739
|
+
} else if (i === "B") {
|
740
|
+
const c = e[t++], a = String.fromCharCode(c), d = e.readInt32LE(t);
|
741
|
+
if (t += 4, a === "i")
|
742
|
+
if (s === "CG") {
|
743
|
+
const f = [];
|
744
|
+
for (let h = 0; h < d; h++) {
|
745
|
+
const l = e.readInt32LE(t), x = l >> 4, m = A[l & 15];
|
746
|
+
f.push(x + m), t += 4;
|
747
|
+
}
|
748
|
+
r[s] = f.join("");
|
749
|
+
} else {
|
750
|
+
const f = [];
|
751
|
+
for (let h = 0; h < d; h++)
|
752
|
+
f.push(e.readInt32LE(t)), t += 4;
|
753
|
+
r[s] = f;
|
754
|
+
}
|
755
|
+
else if (a === "I")
|
756
|
+
if (s === "CG") {
|
757
|
+
const f = [];
|
758
|
+
for (let h = 0; h < d; h++) {
|
759
|
+
const l = e.readUInt32LE(t), x = l >> 4, m = A[l & 15];
|
760
|
+
f.push(x + m), t += 4;
|
761
|
+
}
|
762
|
+
r[s] = f.join("");
|
763
|
+
} else {
|
764
|
+
const f = [];
|
765
|
+
for (let h = 0; h < d; h++)
|
766
|
+
f.push(e.readUInt32LE(t)), t += 4;
|
767
|
+
r[s] = f;
|
768
|
+
}
|
769
|
+
else if (a === "s") {
|
770
|
+
const f = [];
|
771
|
+
for (let h = 0; h < d; h++)
|
772
|
+
f.push(e.readInt16LE(t)), t += 2;
|
773
|
+
r[s] = f;
|
774
|
+
} else if (a === "S") {
|
775
|
+
const f = [];
|
776
|
+
for (let h = 0; h < d; h++)
|
777
|
+
f.push(e.readUInt16LE(t)), t += 2;
|
778
|
+
r[s] = f;
|
779
|
+
} else if (a === "c") {
|
780
|
+
const f = [];
|
781
|
+
for (let h = 0; h < d; h++)
|
782
|
+
f.push(e.readInt8(t)), t += 1;
|
783
|
+
r[s] = f;
|
784
|
+
} else if (a === "C") {
|
785
|
+
const f = [];
|
786
|
+
for (let h = 0; h < d; h++)
|
787
|
+
f.push(e.readUInt8(t)), t += 1;
|
788
|
+
r[s] = f;
|
789
|
+
} else if (a === "f") {
|
790
|
+
const f = [];
|
791
|
+
for (let h = 0; h < d; h++)
|
792
|
+
f.push(e.readFloatLE(t)), t += 4;
|
793
|
+
r[s] = f;
|
794
|
+
}
|
795
|
+
} else {
|
796
|
+
console.error("Unknown BAM tag type", i);
|
797
|
+
break;
|
798
|
+
}
|
799
|
+
}
|
800
|
+
return r;
|
801
|
+
}
|
802
|
+
/**
|
803
|
+
* @returns {boolean} true if the read is paired, regardless of whether both
|
804
|
+
* segments are mapped
|
805
|
+
*/
|
806
|
+
isPaired() {
|
807
|
+
return !!(this.flags & p.BAM_FPAIRED);
|
808
|
+
}
|
809
|
+
/** @returns {boolean} true if the read is paired, and both segments are mapped */
|
810
|
+
isProperlyPaired() {
|
811
|
+
return !!(this.flags & p.BAM_FPROPER_PAIR);
|
812
|
+
}
|
813
|
+
/** @returns {boolean} true if the read itself is unmapped; conflictive with isProperlyPaired */
|
814
|
+
isSegmentUnmapped() {
|
815
|
+
return !!(this.flags & p.BAM_FUNMAP);
|
816
|
+
}
|
817
|
+
/** @returns {boolean} true if the read itself is unmapped; conflictive with isProperlyPaired */
|
818
|
+
isMateUnmapped() {
|
819
|
+
return !!(this.flags & p.BAM_FMUNMAP);
|
820
|
+
}
|
821
|
+
/** @returns {boolean} true if the read is mapped to the reverse strand */
|
822
|
+
isReverseComplemented() {
|
823
|
+
return !!(this.flags & p.BAM_FREVERSE);
|
824
|
+
}
|
825
|
+
/** @returns {boolean} true if the mate is mapped to the reverse strand */
|
826
|
+
isMateReverseComplemented() {
|
827
|
+
return !!(this.flags & p.BAM_FMREVERSE);
|
828
|
+
}
|
829
|
+
/** @returns {boolean} true if this is read number 1 in a pair */
|
830
|
+
isRead1() {
|
831
|
+
return !!(this.flags & p.BAM_FREAD1);
|
832
|
+
}
|
833
|
+
/** @returns {boolean} true if this is read number 2 in a pair */
|
834
|
+
isRead2() {
|
835
|
+
return !!(this.flags & p.BAM_FREAD2);
|
836
|
+
}
|
837
|
+
/** @returns {boolean} true if this is a secondary alignment */
|
838
|
+
isSecondary() {
|
839
|
+
return !!(this.flags & p.BAM_FSECONDARY);
|
840
|
+
}
|
841
|
+
/** @returns {boolean} true if this read has failed QC checks */
|
842
|
+
isFailedQc() {
|
843
|
+
return !!(this.flags & p.BAM_FQCFAIL);
|
844
|
+
}
|
845
|
+
/** @returns {boolean} true if the read is an optical or PCR duplicate */
|
846
|
+
isDuplicate() {
|
847
|
+
return !!(this.flags & p.BAM_FDUP);
|
848
|
+
}
|
849
|
+
/** @returns {boolean} true if this is a supplementary alignment */
|
850
|
+
isSupplementary() {
|
851
|
+
return !!(this.flags & p.BAM_FSUPPLEMENTARY);
|
852
|
+
}
|
853
|
+
get cigarAndLength() {
|
854
|
+
if (this.isSegmentUnmapped())
|
855
|
+
return {
|
856
|
+
length_on_ref: 0,
|
857
|
+
CIGAR: ""
|
858
|
+
};
|
859
|
+
const e = this.num_cigar_ops;
|
860
|
+
let t = this.b0 + this.read_name_length;
|
861
|
+
const n = [];
|
862
|
+
let r = this.byteArray.readInt32LE(t), s = r >> 4, i = A[r & 15];
|
863
|
+
if (i === "S" && s === this.seq_length)
|
864
|
+
return t += 4, r = this.byteArray.readInt32LE(t), s = r >> 4, i = A[r & 15], i !== "N" && console.warn("CG tag with no N tag"), {
|
865
|
+
CIGAR: this.tags.CG,
|
866
|
+
length_on_ref: s
|
867
|
+
};
|
868
|
+
{
|
869
|
+
let c = 0;
|
870
|
+
for (let a = 0; a < e; ++a)
|
871
|
+
r = this.byteArray.readInt32LE(t), s = r >> 4, i = A[r & 15], n.push(s + i), i !== "H" && i !== "S" && i !== "I" && (c += s), t += 4;
|
872
|
+
return {
|
873
|
+
CIGAR: n.join(""),
|
874
|
+
length_on_ref: c
|
875
|
+
};
|
876
|
+
}
|
877
|
+
}
|
878
|
+
get length_on_ref() {
|
879
|
+
return this.cigarAndLength.length_on_ref;
|
880
|
+
}
|
881
|
+
get CIGAR() {
|
882
|
+
return this.cigarAndLength.CIGAR;
|
883
|
+
}
|
884
|
+
get num_cigar_ops() {
|
885
|
+
return this.flag_nc & 65535;
|
886
|
+
}
|
887
|
+
get read_name_length() {
|
888
|
+
return this.bin_mq_nl & 255;
|
889
|
+
}
|
890
|
+
get num_seq_bytes() {
|
891
|
+
return this.seq_length + 1 >> 1;
|
892
|
+
}
|
893
|
+
get seq() {
|
894
|
+
const { byteArray: e } = this.bytes, t = this.b0 + this.read_name_length + this.num_cigar_ops * 4, n = this.num_seq_bytes, r = this.seq_length, s = [];
|
895
|
+
let i = 0;
|
896
|
+
for (let c = 0; c < n; ++c) {
|
897
|
+
const a = e[t + c];
|
898
|
+
s.push(D[(a & 240) >> 4]), i++, i < r && (s.push(D[a & 15]), i++);
|
899
|
+
}
|
900
|
+
return s.join("");
|
901
|
+
}
|
902
|
+
// adapted from igv.js
|
903
|
+
get pair_orientation() {
|
904
|
+
if (!this.isSegmentUnmapped() && !this.isMateUnmapped() && this.ref_id === this.next_refid) {
|
905
|
+
const e = this.isReverseComplemented() ? "R" : "F", t = this.isMateReverseComplemented() ? "R" : "F";
|
906
|
+
let n = " ", r = " ";
|
907
|
+
this.isRead1() ? (n = "1", r = "2") : this.isRead2() && (n = "2", r = "1");
|
908
|
+
const s = [];
|
909
|
+
return this.template_length > 0 ? (s[0] = e, s[1] = n, s[2] = t, s[3] = r) : (s[2] = e, s[3] = n, s[0] = t, s[1] = r), s.join("");
|
910
|
+
}
|
911
|
+
}
|
912
|
+
get bin_mq_nl() {
|
913
|
+
return this.byteArray.readInt32LE(this.bytes.start + 12);
|
914
|
+
}
|
915
|
+
get flag_nc() {
|
916
|
+
return this.byteArray.readInt32LE(this.bytes.start + 16);
|
917
|
+
}
|
918
|
+
get seq_length() {
|
919
|
+
return this.byteArray.readInt32LE(this.bytes.start + 20);
|
920
|
+
}
|
921
|
+
get next_refid() {
|
922
|
+
return this.byteArray.readInt32LE(this.bytes.start + 24);
|
923
|
+
}
|
924
|
+
get next_pos() {
|
925
|
+
return this.byteArray.readInt32LE(this.bytes.start + 28);
|
926
|
+
}
|
927
|
+
get template_length() {
|
928
|
+
return this.byteArray.readInt32LE(this.bytes.start + 32);
|
929
|
+
}
|
930
|
+
toJSON() {
|
931
|
+
const e = {};
|
932
|
+
for (const t of Object.keys(this))
|
933
|
+
t.startsWith("_") || t === "bytes" || (e[t] = this[t]);
|
934
|
+
return e;
|
935
|
+
}
|
936
|
+
}
|
937
|
+
function k(o, e) {
|
938
|
+
const t = Object.getOwnPropertyDescriptor(o.prototype, e);
|
939
|
+
if (!t)
|
940
|
+
throw new Error("OH NO, NO PROPERTY DESCRIPTOR");
|
941
|
+
const n = t.get;
|
942
|
+
if (!n)
|
943
|
+
throw new Error("OH NO, NOT A GETTER");
|
944
|
+
Object.defineProperty(o.prototype, e, {
|
945
|
+
get() {
|
946
|
+
const r = n.call(this);
|
947
|
+
return Object.defineProperty(this, e, { value: r }), r;
|
948
|
+
}
|
949
|
+
});
|
950
|
+
}
|
951
|
+
k(R, "tags");
|
952
|
+
k(R, "cigarAndLength");
|
953
|
+
k(R, "seq");
|
954
|
+
k(R, "qual");
|
955
|
+
function j(o) {
|
956
|
+
const e = o.split(/\r?\n/), t = [];
|
957
|
+
for (const n of e) {
|
958
|
+
const [r, ...s] = n.split(/\t/);
|
959
|
+
r && t.push({
|
960
|
+
tag: r.slice(1),
|
961
|
+
data: s.map((i) => {
|
962
|
+
const c = i.indexOf(":"), a = i.slice(0, c), d = i.slice(c + 1);
|
963
|
+
return { tag: a, value: d };
|
964
|
+
})
|
965
|
+
});
|
966
|
+
}
|
967
|
+
return t;
|
968
|
+
}
|
969
|
+
const V = 21840194, $ = 65536;
|
970
|
+
async function le(o) {
|
971
|
+
let e = [];
|
972
|
+
for await (const t of o)
|
973
|
+
e = e.concat(t);
|
974
|
+
return e;
|
975
|
+
}
|
976
|
+
class xe {
|
977
|
+
read() {
|
978
|
+
throw new Error("never called");
|
979
|
+
}
|
980
|
+
stat() {
|
981
|
+
throw new Error("never called");
|
982
|
+
}
|
983
|
+
readFile() {
|
984
|
+
throw new Error("never called");
|
985
|
+
}
|
986
|
+
close() {
|
987
|
+
throw new Error("never called");
|
988
|
+
}
|
989
|
+
}
|
990
|
+
class ue {
|
991
|
+
constructor({ bamFilehandle: e, bamPath: t, bamUrl: n, baiPath: r, baiFilehandle: s, baiUrl: i, csiPath: c, csiFilehandle: a, csiUrl: d, htsget: f, yieldThreadTime: h = 100, renameRefSeqs: l = (x) => x }) {
|
992
|
+
if (this.htsget = !1, this.featureCache = new W({
|
993
|
+
cache: new X({
|
994
|
+
maxSize: 50
|
995
|
+
}),
|
996
|
+
fill: async (x, m) => {
|
997
|
+
const { chunk: b, opts: u } = x, { data: g, cpositions: w, dpositions: _ } = await this._readChunk({
|
998
|
+
chunk: b,
|
999
|
+
opts: { ...u, signal: m }
|
1000
|
+
});
|
1001
|
+
return this.readBamFeatures(g, w, _, b);
|
1002
|
+
}
|
1003
|
+
}), this.renameRefSeq = l, e)
|
1004
|
+
this.bam = e;
|
1005
|
+
else if (t)
|
1006
|
+
this.bam = new C(t);
|
1007
|
+
else if (n)
|
1008
|
+
this.bam = new L(n);
|
1009
|
+
else if (f)
|
1010
|
+
this.htsget = !0, this.bam = new xe();
|
1011
|
+
else
|
1012
|
+
throw new Error("unable to initialize bam");
|
1013
|
+
if (a)
|
1014
|
+
this.index = new T({ filehandle: a });
|
1015
|
+
else if (c)
|
1016
|
+
this.index = new T({ filehandle: new C(c) });
|
1017
|
+
else if (d)
|
1018
|
+
this.index = new T({ filehandle: new L(d) });
|
1019
|
+
else if (s)
|
1020
|
+
this.index = new v({ filehandle: s });
|
1021
|
+
else if (r)
|
1022
|
+
this.index = new v({ filehandle: new C(r) });
|
1023
|
+
else if (i)
|
1024
|
+
this.index = new v({ filehandle: new L(i) });
|
1025
|
+
else if (t)
|
1026
|
+
this.index = new v({ filehandle: new C(`${t}.bai`) });
|
1027
|
+
else if (n)
|
1028
|
+
this.index = new v({ filehandle: new L(`${n}.bai`) });
|
1029
|
+
else if (f)
|
1030
|
+
this.htsget = !0;
|
1031
|
+
else
|
1032
|
+
throw new Error("unable to infer index format");
|
1033
|
+
this.yieldThreadTime = h;
|
1034
|
+
}
|
1035
|
+
async getHeaderPre(e) {
|
1036
|
+
const t = ee(e);
|
1037
|
+
if (!this.index)
|
1038
|
+
return;
|
1039
|
+
const n = await this.index.parse(t), r = n.firstDataLine ? n.firstDataLine.blockPosition + 65535 : void 0;
|
1040
|
+
let s;
|
1041
|
+
if (r) {
|
1042
|
+
const f = r + $, h = await this.bam.read(y.Buffer.alloc(f), 0, f, 0, t);
|
1043
|
+
if (!h.bytesRead)
|
1044
|
+
throw new Error("Error reading header");
|
1045
|
+
s = h.buffer.subarray(0, Math.min(h.bytesRead, r));
|
1046
|
+
} else
|
1047
|
+
s = await this.bam.readFile(t);
|
1048
|
+
const i = await P(s);
|
1049
|
+
if (i.readInt32LE(0) !== V)
|
1050
|
+
throw new Error("Not a BAM file");
|
1051
|
+
const c = i.readInt32LE(4);
|
1052
|
+
this.header = i.toString("utf8", 8, 8 + c);
|
1053
|
+
const { chrToIndex: a, indexToChr: d } = await this._readRefSeqs(c + 8, 65535, t);
|
1054
|
+
return this.chrToIndex = a, this.indexToChr = d, j(this.header);
|
1055
|
+
}
|
1056
|
+
getHeader(e) {
|
1057
|
+
return this.headerP || (this.headerP = this.getHeaderPre(e).catch((t) => {
|
1058
|
+
throw this.headerP = void 0, t;
|
1059
|
+
})), this.headerP;
|
1060
|
+
}
|
1061
|
+
async getHeaderText(e = {}) {
|
1062
|
+
return await this.getHeader(e), this.header;
|
1063
|
+
}
|
1064
|
+
// the full length of the refseq block is not given in advance so this grabs
|
1065
|
+
// a chunk and doubles it if all refseqs haven't been processed
|
1066
|
+
async _readRefSeqs(e, t, n) {
|
1067
|
+
if (e > t)
|
1068
|
+
return this._readRefSeqs(e, t * 2, n);
|
1069
|
+
const r = t + $, { bytesRead: s, buffer: i } = await this.bam.read(y.Buffer.alloc(r), 0, t, 0, n);
|
1070
|
+
if (!s)
|
1071
|
+
throw new Error("Error reading refseqs from header");
|
1072
|
+
const c = await P(i.subarray(0, Math.min(s, t))), a = c.readInt32LE(e);
|
1073
|
+
let d = e + 4;
|
1074
|
+
const f = {}, h = [];
|
1075
|
+
for (let l = 0; l < a; l += 1) {
|
1076
|
+
const x = c.readInt32LE(d), m = this.renameRefSeq(c.toString("utf8", d + 4, d + 4 + x - 1)), b = c.readInt32LE(d + x + 4);
|
1077
|
+
if (f[m] = l, h.push({ refName: m, length: b }), d = d + 8 + x, d > c.length)
|
1078
|
+
return console.warn(`BAM header is very big. Re-fetching ${t} bytes.`), this._readRefSeqs(e, t * 2, n);
|
1079
|
+
}
|
1080
|
+
return { chrToIndex: f, indexToChr: h };
|
1081
|
+
}
|
1082
|
+
async getRecordsForRange(e, t, n, r) {
|
1083
|
+
return le(this.streamRecordsForRange(e, t, n, r));
|
1084
|
+
}
|
1085
|
+
async *streamRecordsForRange(e, t, n, r) {
|
1086
|
+
var s;
|
1087
|
+
await this.getHeader(r);
|
1088
|
+
const i = (s = this.chrToIndex) === null || s === void 0 ? void 0 : s[e];
|
1089
|
+
if (i === void 0 || !this.index)
|
1090
|
+
yield [];
|
1091
|
+
else {
|
1092
|
+
const c = await this.index.blocksForRange(i, t - 1, n, r);
|
1093
|
+
yield* this._fetchChunkFeatures(c, i, t, n, r);
|
1094
|
+
}
|
1095
|
+
}
|
1096
|
+
async *_fetchChunkFeatures(e, t, n, r, s = {}) {
|
1097
|
+
const { viewAsPairs: i } = s, c = [];
|
1098
|
+
let a = !1;
|
1099
|
+
for (const d of e) {
|
1100
|
+
const f = await this.featureCache.get(d.toString(), { chunk: d, opts: s }, s.signal), h = [];
|
1101
|
+
for (const l of f)
|
1102
|
+
if (l.ref_id === t)
|
1103
|
+
if (l.start >= r) {
|
1104
|
+
a = !0;
|
1105
|
+
break;
|
1106
|
+
} else l.end >= n && h.push(l);
|
1107
|
+
if (c.push(h), yield h, a)
|
1108
|
+
break;
|
1109
|
+
}
|
1110
|
+
K(s.signal), i && (yield this.fetchPairs(t, c, s));
|
1111
|
+
}
|
1112
|
+
async fetchPairs(e, t, n) {
|
1113
|
+
const { pairAcrossChr: r, maxInsertSize: s = 2e5 } = n, i = {}, c = {};
|
1114
|
+
t.map((l) => {
|
1115
|
+
const x = {};
|
1116
|
+
for (const m of l) {
|
1117
|
+
const b = m.name, u = m.id;
|
1118
|
+
x[b] || (x[b] = 0), x[b]++, c[u] = 1;
|
1119
|
+
}
|
1120
|
+
for (const [m, b] of Object.entries(x))
|
1121
|
+
b === 1 && (i[m] = !0);
|
1122
|
+
});
|
1123
|
+
const a = [];
|
1124
|
+
t.map((l) => {
|
1125
|
+
for (const x of l) {
|
1126
|
+
const m = x.name, b = x.start, u = x.next_pos, g = x.next_refid;
|
1127
|
+
this.index && i[m] && (r || g === e && Math.abs(b - u) < s) && a.push(this.index.blocksForRange(g, u, u + 1, n));
|
1128
|
+
}
|
1129
|
+
});
|
1130
|
+
const d = /* @__PURE__ */ new Map(), f = await Promise.all(a);
|
1131
|
+
for (const l of f.flat())
|
1132
|
+
d.has(l.toString()) || d.set(l.toString(), l);
|
1133
|
+
return (await Promise.all([...d.values()].map(async (l) => {
|
1134
|
+
const { data: x, cpositions: m, dpositions: b, chunk: u } = await this._readChunk({
|
1135
|
+
chunk: l,
|
1136
|
+
opts: n
|
1137
|
+
}), g = [];
|
1138
|
+
for (const w of await this.readBamFeatures(x, m, b, u))
|
1139
|
+
i[w.name] && !c[w.id] && g.push(w);
|
1140
|
+
return g;
|
1141
|
+
}))).flat();
|
1142
|
+
}
|
1143
|
+
async _readRegion(e, t, n = {}) {
|
1144
|
+
const { bytesRead: r, buffer: s } = await this.bam.read(y.Buffer.alloc(t), 0, t, e, n);
|
1145
|
+
return s.subarray(0, Math.min(r, t));
|
1146
|
+
}
|
1147
|
+
async _readChunk({ chunk: e, opts: t }) {
|
1148
|
+
const n = await this._readRegion(e.minv.blockPosition, e.fetchedSize(), t), { buffer: r, cpositions: s, dpositions: i } = await Q(n, e);
|
1149
|
+
return { data: r, cpositions: s, dpositions: i, chunk: e };
|
1150
|
+
}
|
1151
|
+
async readBamFeatures(e, t, n, r) {
|
1152
|
+
let s = 0;
|
1153
|
+
const i = [];
|
1154
|
+
let c = 0, a = +Date.now();
|
1155
|
+
for (; s + 4 < e.length; ) {
|
1156
|
+
const d = e.readInt32LE(s), f = s + 4 + d - 1;
|
1157
|
+
if (n) {
|
1158
|
+
for (; s + r.minv.dataPosition >= n[c++]; )
|
1159
|
+
;
|
1160
|
+
c--;
|
1161
|
+
}
|
1162
|
+
if (f < e.length) {
|
1163
|
+
const h = new R({
|
1164
|
+
bytes: {
|
1165
|
+
byteArray: e,
|
1166
|
+
start: s,
|
1167
|
+
end: f
|
1168
|
+
},
|
1169
|
+
// the below results in an automatically calculated file-offset based
|
1170
|
+
// ID if the info for that is available, otherwise crc32 of the
|
1171
|
+
// features
|
1172
|
+
//
|
1173
|
+
// cpositions[pos] refers to actual file offset of a bgzip block
|
1174
|
+
// boundaries
|
1175
|
+
//
|
1176
|
+
// we multiply by (1 <<8) in order to make sure each block has a
|
1177
|
+
// "unique" address space so that data in that block could never
|
1178
|
+
// overlap
|
1179
|
+
//
|
1180
|
+
// then the blockStart-dpositions is an uncompressed file offset from
|
1181
|
+
// that bgzip block boundary, and since the cpositions are multiplied
|
1182
|
+
// by (1 << 8) these uncompressed offsets get a unique space
|
1183
|
+
//
|
1184
|
+
// this has an extra chunk.minv.dataPosition added on because it
|
1185
|
+
// blockStart starts at 0 instead of chunk.minv.dataPosition
|
1186
|
+
//
|
1187
|
+
// the +1 is just to avoid any possible uniqueId 0 but this does not
|
1188
|
+
// realistically happen
|
1189
|
+
fileOffset: t.length > 0 ? t[c] * 256 + (s - n[c]) + r.minv.dataPosition + 1 : (
|
1190
|
+
// must be slice, not subarray for buffer polyfill on web
|
1191
|
+
// eslint-disable-next-line @typescript-eslint/no-deprecated
|
1192
|
+
ce.signed(e.slice(s, f))
|
1193
|
+
)
|
1194
|
+
});
|
1195
|
+
i.push(h), this.yieldThreadTime && +Date.now() - a > this.yieldThreadTime && (await J(1), a = +Date.now());
|
1196
|
+
}
|
1197
|
+
s = f + 1;
|
1198
|
+
}
|
1199
|
+
return i;
|
1200
|
+
}
|
1201
|
+
async hasRefSeq(e) {
|
1202
|
+
var t, n;
|
1203
|
+
const r = (t = this.chrToIndex) === null || t === void 0 ? void 0 : t[e];
|
1204
|
+
return r === void 0 ? !1 : (n = this.index) === null || n === void 0 ? void 0 : n.hasRefSeq(r);
|
1205
|
+
}
|
1206
|
+
async lineCount(e) {
|
1207
|
+
var t;
|
1208
|
+
const n = (t = this.chrToIndex) === null || t === void 0 ? void 0 : t[e];
|
1209
|
+
return n === void 0 || !this.index ? 0 : this.index.lineCount(n);
|
1210
|
+
}
|
1211
|
+
async indexCov(e, t, n) {
|
1212
|
+
var r;
|
1213
|
+
if (!this.index)
|
1214
|
+
return [];
|
1215
|
+
await this.index.parse();
|
1216
|
+
const s = (r = this.chrToIndex) === null || r === void 0 ? void 0 : r[e];
|
1217
|
+
return s === void 0 ? [] : this.index.indexCov(s, t, n);
|
1218
|
+
}
|
1219
|
+
async blocksForRange(e, t, n, r) {
|
1220
|
+
var s;
|
1221
|
+
if (!this.index)
|
1222
|
+
return [];
|
1223
|
+
await this.index.parse();
|
1224
|
+
const i = (s = this.chrToIndex) === null || s === void 0 ? void 0 : s[e];
|
1225
|
+
return i === void 0 ? [] : this.index.blocksForRange(i, t, n, r);
|
1226
|
+
}
|
1227
|
+
}
|
1228
|
+
async function U(o, e) {
|
1229
|
+
const t = await Promise.all(o.map(async (n) => {
|
1230
|
+
const { url: r, headers: s } = n;
|
1231
|
+
if (r.startsWith("data:"))
|
1232
|
+
return y.Buffer.from(r.split(",")[1], "base64");
|
1233
|
+
{
|
1234
|
+
const { referer: i, ...c } = s, a = await fetch(r, {
|
1235
|
+
...e,
|
1236
|
+
headers: { ...e == null ? void 0 : e.headers, ...c }
|
1237
|
+
});
|
1238
|
+
if (!a.ok)
|
1239
|
+
throw new Error(`HTTP ${a.status} fetching ${r}: ${await a.text()}`);
|
1240
|
+
return y.Buffer.from(await a.arrayBuffer());
|
1241
|
+
}
|
1242
|
+
}));
|
1243
|
+
return y.Buffer.concat(await Promise.all(t.map((n) => P(n))));
|
1244
|
+
}
|
1245
|
+
class _e extends ue {
|
1246
|
+
constructor(e) {
|
1247
|
+
super({ htsget: !0 }), this.baseUrl = e.baseUrl, this.trackId = e.trackId;
|
1248
|
+
}
|
1249
|
+
async *streamRecordsForRange(e, t, n, r) {
|
1250
|
+
var s;
|
1251
|
+
const c = `${`${this.baseUrl}/${this.trackId}`}?referenceName=${e}&start=${t}&end=${n}&format=BAM`, a = (s = this.chrToIndex) === null || s === void 0 ? void 0 : s[e];
|
1252
|
+
if (a === void 0)
|
1253
|
+
yield [];
|
1254
|
+
else {
|
1255
|
+
const d = await fetch(c, { ...r });
|
1256
|
+
if (!d.ok)
|
1257
|
+
throw new Error(`HTTP ${d.status} fetching ${c}: ${await d.text()}`);
|
1258
|
+
const f = await d.json(), h = await U(f.htsget.urls.slice(1), r);
|
1259
|
+
yield* this._fetchChunkFeatures([
|
1260
|
+
// fake stuff to pretend to be a Chunk
|
1261
|
+
{
|
1262
|
+
buffer: h,
|
1263
|
+
_fetchedSize: void 0,
|
1264
|
+
bin: 0,
|
1265
|
+
compareTo() {
|
1266
|
+
return 0;
|
1267
|
+
},
|
1268
|
+
toUniqueString() {
|
1269
|
+
return `${e}_${t}_${n}`;
|
1270
|
+
},
|
1271
|
+
fetchedSize() {
|
1272
|
+
return 0;
|
1273
|
+
},
|
1274
|
+
minv: {
|
1275
|
+
dataPosition: 0,
|
1276
|
+
blockPosition: 0,
|
1277
|
+
compareTo: () => 0
|
1278
|
+
},
|
1279
|
+
maxv: {
|
1280
|
+
dataPosition: Number.MAX_SAFE_INTEGER,
|
1281
|
+
blockPosition: 0,
|
1282
|
+
compareTo: () => 0
|
1283
|
+
},
|
1284
|
+
toString() {
|
1285
|
+
return `${e}_${t}_${n}`;
|
1286
|
+
}
|
1287
|
+
}
|
1288
|
+
], a, t, n, r);
|
1289
|
+
}
|
1290
|
+
}
|
1291
|
+
async _readChunk({ chunk: e }) {
|
1292
|
+
if (!e.buffer)
|
1293
|
+
throw new Error("expected chunk.buffer in htsget");
|
1294
|
+
return { data: e.buffer, cpositions: [], dpositions: [], chunk: e };
|
1295
|
+
}
|
1296
|
+
async getHeader(e = {}) {
|
1297
|
+
const t = `${this.baseUrl}/${this.trackId}?referenceName=na&class=header`, n = await fetch(t, e);
|
1298
|
+
if (!n.ok)
|
1299
|
+
throw new Error(`HTTP ${n.status} fetching ${t}: ${await n.text()}`);
|
1300
|
+
const r = await n.json(), s = await U(r.htsget.urls, e);
|
1301
|
+
if (s.readInt32LE(0) !== V)
|
1302
|
+
throw new Error("Not a BAM file");
|
1303
|
+
const i = s.readInt32LE(4), c = s.toString("utf8", 8, 8 + i), a = j(c), d = [], f = {}, h = a.filter((l) => l.tag === "SQ");
|
1304
|
+
for (const [l, x] of h.entries()) {
|
1305
|
+
let m = "", b = 0;
|
1306
|
+
for (const u of x.data)
|
1307
|
+
u.tag === "SN" ? m = u.value : u.tag === "LN" && (b = +u.value);
|
1308
|
+
f[m] = l, d[l] = { refName: m, length: b };
|
1309
|
+
}
|
1310
|
+
return this.chrToIndex = f, this.indexToChr = d, a;
|
1311
|
+
}
|
1312
|
+
}
|
1313
|
+
export {
|
1314
|
+
v as BAI,
|
1315
|
+
ue as BamFile,
|
1316
|
+
R as BamRecord,
|
1317
|
+
T as CSI,
|
1318
|
+
_e as HtsgetFile
|
1319
|
+
};
|