igv 2.13.7 → 2.13.8
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/README.md +10 -10
- package/dist/igv.esm.js +378 -179
- package/dist/igv.esm.min.js +8 -8
- package/dist/igv.esm.min.js.map +1 -1
- package/dist/igv.js +395 -172
- package/dist/igv.min.js +5 -5
- package/dist/igv.min.js.map +1 -1
- package/package.json +1 -1
package/dist/igv.js
CHANGED
|
@@ -13966,7 +13966,7 @@
|
|
|
13966
13966
|
const {
|
|
13967
13967
|
Inflate,
|
|
13968
13968
|
inflate: inflate$3,
|
|
13969
|
-
inflateRaw,
|
|
13969
|
+
inflateRaw: inflateRaw$2,
|
|
13970
13970
|
ungzip: ungzip$2
|
|
13971
13971
|
} = inflate_1$1;
|
|
13972
13972
|
var Deflate_1 = Deflate;
|
|
@@ -13975,7 +13975,7 @@
|
|
|
13975
13975
|
var gzip_1 = gzip;
|
|
13976
13976
|
var Inflate_1 = Inflate;
|
|
13977
13977
|
var inflate_1 = inflate$3;
|
|
13978
|
-
var inflateRaw_1 = inflateRaw;
|
|
13978
|
+
var inflateRaw_1 = inflateRaw$2;
|
|
13979
13979
|
var ungzip_1 = ungzip$2;
|
|
13980
13980
|
var constants_1 = constants$2;
|
|
13981
13981
|
var pako = {
|
|
@@ -14008,7 +14008,7 @@
|
|
|
14008
14008
|
|
|
14009
14009
|
pako.deflateRaw;
|
|
14010
14010
|
pako.deflate;
|
|
14011
|
-
pako.inflateRaw;
|
|
14011
|
+
const inflateRaw = pako.inflateRaw;
|
|
14012
14012
|
const inflate = pako.inflate;
|
|
14013
14013
|
pako.gzip;
|
|
14014
14014
|
const FEXTRA = 4; // gzip spec F.EXTRA flag
|
|
@@ -14080,7 +14080,7 @@
|
|
|
14080
14080
|
return out;
|
|
14081
14081
|
}
|
|
14082
14082
|
}
|
|
14083
|
-
function bgzBlockSize(data) {
|
|
14083
|
+
function bgzBlockSize$1(data) {
|
|
14084
14084
|
const ba = ArrayBuffer.isView(data) ? data : new Uint8Array(data);
|
|
14085
14085
|
const bsize = (ba[17] << 8 | ba[16]) + 1;
|
|
14086
14086
|
return bsize;
|
|
@@ -18865,7 +18865,7 @@
|
|
|
18865
18865
|
|
|
18866
18866
|
const doAutoscale = function (features) {
|
|
18867
18867
|
var min, max;
|
|
18868
|
-
if (features.length > 0) {
|
|
18868
|
+
if (features && features.length > 0) {
|
|
18869
18869
|
min = Number.MAX_VALUE;
|
|
18870
18870
|
max = -Number.MAX_VALUE;
|
|
18871
18871
|
features.forEach(function (f) {
|
|
@@ -21939,7 +21939,7 @@
|
|
|
21939
21939
|
}
|
|
21940
21940
|
};
|
|
21941
21941
|
|
|
21942
|
-
const _version = "2.13.
|
|
21942
|
+
const _version = "2.13.8";
|
|
21943
21943
|
function version$1() {
|
|
21944
21944
|
return _version;
|
|
21945
21945
|
}
|
|
@@ -26462,12 +26462,81 @@
|
|
|
26462
26462
|
isGreaterThan(vp) {
|
|
26463
26463
|
return this.block > vp.block || this.block === vp.block && this.offset > vp.offset;
|
|
26464
26464
|
}
|
|
26465
|
+
isEqualTo(vp) {
|
|
26466
|
+
return this.block === vp.block && this.offset === vp.offset;
|
|
26467
|
+
}
|
|
26465
26468
|
print() {
|
|
26466
26469
|
return "" + this.block + ":" + this.offset;
|
|
26467
26470
|
}
|
|
26468
26471
|
}
|
|
26469
26472
|
|
|
26470
|
-
|
|
26473
|
+
function optimizeChunks(chunks, lowest) {
|
|
26474
|
+
if (chunks.length === 0) return chunks;
|
|
26475
|
+
chunks.sort(function (c0, c1) {
|
|
26476
|
+
const dif = c0.minv.block - c1.minv.block;
|
|
26477
|
+
if (dif !== 0) {
|
|
26478
|
+
return dif;
|
|
26479
|
+
} else {
|
|
26480
|
+
return c0.minv.offset - c1.minv.offset;
|
|
26481
|
+
}
|
|
26482
|
+
});
|
|
26483
|
+
if (chunks.length <= 1) {
|
|
26484
|
+
return chunks;
|
|
26485
|
+
}
|
|
26486
|
+
|
|
26487
|
+
// console.log("Before trimming " + chunks.length)
|
|
26488
|
+
// for (let c of chunks) {
|
|
26489
|
+
// console.log(`${c.minv.block} ${c.minv.offset} - ${c.maxv.block} ${c.maxv.offset}`)
|
|
26490
|
+
// }
|
|
26491
|
+
|
|
26492
|
+
if (lowest) {
|
|
26493
|
+
chunks = chunks.filter(c => c.maxv.isGreaterThan(lowest));
|
|
26494
|
+
}
|
|
26495
|
+
|
|
26496
|
+
// console.log("Before merging " + chunks.length)
|
|
26497
|
+
// for (let c of chunks) {
|
|
26498
|
+
// console.log(`${c.minv.block} ${c.minv.offset} - ${c.maxv.block} ${c.maxv.offset}`)
|
|
26499
|
+
// }
|
|
26500
|
+
|
|
26501
|
+
const mergedChunks = [];
|
|
26502
|
+
let lastChunk;
|
|
26503
|
+
for (let chunk of chunks) {
|
|
26504
|
+
if (!lastChunk) {
|
|
26505
|
+
mergedChunks.push(chunk);
|
|
26506
|
+
lastChunk = chunk;
|
|
26507
|
+
} else {
|
|
26508
|
+
if (canMerge(lastChunk, chunk)) {
|
|
26509
|
+
if (chunk.maxv.isGreaterThan(lastChunk.maxv)) {
|
|
26510
|
+
lastChunk.maxv = chunk.maxv;
|
|
26511
|
+
}
|
|
26512
|
+
} else {
|
|
26513
|
+
mergedChunks.push(chunk);
|
|
26514
|
+
lastChunk = chunk;
|
|
26515
|
+
}
|
|
26516
|
+
}
|
|
26517
|
+
}
|
|
26518
|
+
|
|
26519
|
+
// console.log("After merging " + mergedChunks.length)
|
|
26520
|
+
// for (let c of mergedChunks) {
|
|
26521
|
+
// console.log(`${c.minv.block} ${c.minv.offset} - ${c.maxv.block} ${c.maxv.offset}`)
|
|
26522
|
+
// }
|
|
26523
|
+
|
|
26524
|
+
return mergedChunks;
|
|
26525
|
+
}
|
|
26526
|
+
|
|
26527
|
+
/**
|
|
26528
|
+
* Merge 2 blocks if the file position gap between them is < 16 kb, and the total size is < ~5 mb
|
|
26529
|
+
* @param chunk1
|
|
26530
|
+
* @param chunk2
|
|
26531
|
+
* @returns {boolean|boolean}
|
|
26532
|
+
*/
|
|
26533
|
+
function canMerge(chunk1, chunk2) {
|
|
26534
|
+
const gap = chunk2.minv.block - chunk1.maxv.block;
|
|
26535
|
+
const sizeEstimate = chunk1.maxv.block - chunk1.minv.block;
|
|
26536
|
+
return gap < 65000 && sizeEstimate < 5000000;
|
|
26537
|
+
}
|
|
26538
|
+
|
|
26539
|
+
// Represents a CSI Bam or Tabix index
|
|
26471
26540
|
const CSI1_MAGIC$1 = 21582659; // CSI\1
|
|
26472
26541
|
const CSI2_MAGIC$1 = 38359875; // CSI\2
|
|
26473
26542
|
|
|
@@ -26579,7 +26648,7 @@
|
|
|
26579
26648
|
* @param max genomic end position
|
|
26580
26649
|
* @param return an array of {minv: {filePointer, offset}, {maxv: {filePointer, offset}}
|
|
26581
26650
|
*/
|
|
26582
|
-
|
|
26651
|
+
chunksForRange(refId, min, max) {
|
|
26583
26652
|
const ba = this.indices[refId];
|
|
26584
26653
|
if (!ba) {
|
|
26585
26654
|
return [];
|
|
@@ -26605,7 +26674,7 @@
|
|
|
26605
26674
|
}
|
|
26606
26675
|
}
|
|
26607
26676
|
const lowestOffset = ba.loffset[overlappingBins[0]];
|
|
26608
|
-
return optimizeChunks
|
|
26677
|
+
return optimizeChunks(chunks, lowestOffset);
|
|
26609
26678
|
}
|
|
26610
26679
|
}
|
|
26611
26680
|
|
|
@@ -26637,48 +26706,10 @@
|
|
|
26637
26706
|
return ((1 << (this.depth + 1) * 3) - 1) / 7;
|
|
26638
26707
|
}
|
|
26639
26708
|
}
|
|
26640
|
-
function optimizeChunks$1(chunks, lowest) {
|
|
26641
|
-
const mergedChunks = [];
|
|
26642
|
-
let lastChunk = null;
|
|
26643
|
-
if (chunks.length === 0) return chunks;
|
|
26644
|
-
chunks.sort(function (c0, c1) {
|
|
26645
|
-
const dif = c0.minv.block - c1.minv.block;
|
|
26646
|
-
if (dif !== 0) {
|
|
26647
|
-
return dif;
|
|
26648
|
-
} else {
|
|
26649
|
-
return c0.minv.offset - c1.minv.offset;
|
|
26650
|
-
}
|
|
26651
|
-
});
|
|
26652
|
-
chunks.forEach(function (chunk) {
|
|
26653
|
-
if (!lowest || chunk.maxv.isGreaterThan(lowest)) {
|
|
26654
|
-
if (lastChunk === null) {
|
|
26655
|
-
mergedChunks.push(chunk);
|
|
26656
|
-
lastChunk = chunk;
|
|
26657
|
-
} else {
|
|
26658
|
-
if (canMerge$1(lastChunk, chunk)) {
|
|
26659
|
-
if (chunk.maxv.isGreaterThan(lastChunk.maxv)) {
|
|
26660
|
-
lastChunk.maxv = chunk.maxv;
|
|
26661
|
-
}
|
|
26662
|
-
} else {
|
|
26663
|
-
mergedChunks.push(chunk);
|
|
26664
|
-
lastChunk = chunk;
|
|
26665
|
-
}
|
|
26666
|
-
}
|
|
26667
|
-
}
|
|
26668
|
-
});
|
|
26669
|
-
return mergedChunks;
|
|
26670
|
-
}
|
|
26671
|
-
function canMerge$1(chunk1, chunk2) {
|
|
26672
|
-
return chunk2.minv.block - chunk1.maxv.block < 65000 && chunk2.maxv.block - chunk1.minv.block < 5000000;
|
|
26673
|
-
// lastChunk.minv.block === lastChunk.maxv.block &&
|
|
26674
|
-
// lastChunk.maxv.block === chunk.minv.block &&
|
|
26675
|
-
// chunk.minv.block === chunk.maxv.block
|
|
26676
|
-
}
|
|
26677
26709
|
|
|
26678
|
-
// Represents a BAM index.
|
|
26710
|
+
// Represents a BAM or Tabix index.
|
|
26679
26711
|
const BAI_MAGIC$1 = 21578050;
|
|
26680
26712
|
const TABIX_MAGIC$1 = 21578324;
|
|
26681
|
-
const MB = 1000000;
|
|
26682
26713
|
async function parseBamIndex(arrayBuffer, genome) {
|
|
26683
26714
|
const index = new BamIndex();
|
|
26684
26715
|
await index.parse(arrayBuffer, false, genome);
|
|
@@ -26780,22 +26811,27 @@
|
|
|
26780
26811
|
}
|
|
26781
26812
|
|
|
26782
26813
|
/**
|
|
26783
|
-
* Fetch
|
|
26814
|
+
* Fetch chunks for a particular genomic range. This method is public so it can be unit-tested.
|
|
26784
26815
|
*
|
|
26785
26816
|
* @param refId the sequence dictionary index of the chromosome
|
|
26786
26817
|
* @param min genomic start position
|
|
26787
26818
|
* @param max genomic end position
|
|
26788
|
-
* @param return an array of {minv: {
|
|
26819
|
+
* @param return an array of objects representing chunks (file spans) {minv: {block, offset}, {maxv: {block, offset}}
|
|
26789
26820
|
*/
|
|
26790
|
-
|
|
26821
|
+
chunksForRange(refId, min, max) {
|
|
26791
26822
|
const bam = this;
|
|
26792
26823
|
const ba = bam.indices[refId];
|
|
26793
26824
|
if (!ba) {
|
|
26794
26825
|
return [];
|
|
26795
26826
|
} else {
|
|
26796
26827
|
const overlappingBins = reg2bins(min, max); // List of bin #s that overlap min, max
|
|
26797
|
-
const chunks = [];
|
|
26798
26828
|
|
|
26829
|
+
//console.log("bin ranges")
|
|
26830
|
+
//for(let b of overlappingBins) {
|
|
26831
|
+
// console.log(`${b[0]} - ${b[1]}`)
|
|
26832
|
+
//}
|
|
26833
|
+
|
|
26834
|
+
const chunks = [];
|
|
26799
26835
|
// Find chunks in overlapping bins. Leaf bins (< 4681) are not pruned
|
|
26800
26836
|
for (let binRange of overlappingBins) {
|
|
26801
26837
|
for (let bin = binRange[0]; bin <= binRange[1]; bin++) {
|
|
@@ -26806,8 +26842,7 @@
|
|
|
26806
26842
|
const ce = c[1];
|
|
26807
26843
|
chunks.push({
|
|
26808
26844
|
minv: cs,
|
|
26809
|
-
maxv: ce
|
|
26810
|
-
bin: bin
|
|
26845
|
+
maxv: ce
|
|
26811
26846
|
});
|
|
26812
26847
|
}
|
|
26813
26848
|
}
|
|
@@ -26816,65 +26851,20 @@
|
|
|
26816
26851
|
|
|
26817
26852
|
// Use the linear index to find minimum file position of chunks that could contain alignments in the region
|
|
26818
26853
|
const nintv = ba.linearIndex.length;
|
|
26819
|
-
let lowest
|
|
26820
|
-
const minLin = Math.min(min >> 14, nintv - 1);
|
|
26854
|
+
let lowest;
|
|
26855
|
+
const minLin = Math.min(min >> 14, nintv - 1); // i.e. min / 16384
|
|
26821
26856
|
const maxLin = Math.min(max >> 14, nintv - 1);
|
|
26822
|
-
for (let i = minLin; i
|
|
26857
|
+
for (let i = minLin; i <= maxLin; i++) {
|
|
26823
26858
|
const vp = ba.linearIndex[i];
|
|
26824
26859
|
if (vp) {
|
|
26825
|
-
|
|
26826
|
-
|
|
26827
|
-
lowest = vp;
|
|
26828
|
-
}
|
|
26860
|
+
lowest = vp; // lowest file offset that contains alignments overlapping (min, max)
|
|
26861
|
+
break;
|
|
26829
26862
|
}
|
|
26830
26863
|
}
|
|
26831
26864
|
return optimizeChunks(chunks, lowest);
|
|
26832
26865
|
}
|
|
26833
26866
|
}
|
|
26834
26867
|
}
|
|
26835
|
-
function optimizeChunks(chunks, lowest) {
|
|
26836
|
-
const mergedChunks = [];
|
|
26837
|
-
let lastChunk = null;
|
|
26838
|
-
if (chunks.length === 0) return chunks;
|
|
26839
|
-
chunks.sort(function (c0, c1) {
|
|
26840
|
-
const dif = c0.minv.block - c1.minv.block;
|
|
26841
|
-
if (dif !== 0) {
|
|
26842
|
-
return dif;
|
|
26843
|
-
} else {
|
|
26844
|
-
return c0.minv.offset - c1.minv.offset;
|
|
26845
|
-
}
|
|
26846
|
-
});
|
|
26847
|
-
chunks.forEach(function (chunk) {
|
|
26848
|
-
if (!lowest || chunk.maxv.isGreaterThan(lowest)) {
|
|
26849
|
-
if (lastChunk === null) {
|
|
26850
|
-
mergedChunks.push(chunk);
|
|
26851
|
-
lastChunk = chunk;
|
|
26852
|
-
} else {
|
|
26853
|
-
if (canMerge(lastChunk, chunk)) {
|
|
26854
|
-
if (chunk.maxv.isGreaterThan(lastChunk.maxv)) {
|
|
26855
|
-
lastChunk.maxv = chunk.maxv;
|
|
26856
|
-
}
|
|
26857
|
-
} else {
|
|
26858
|
-
mergedChunks.push(chunk);
|
|
26859
|
-
lastChunk = chunk;
|
|
26860
|
-
}
|
|
26861
|
-
}
|
|
26862
|
-
}
|
|
26863
|
-
});
|
|
26864
|
-
return mergedChunks;
|
|
26865
|
-
}
|
|
26866
|
-
|
|
26867
|
-
/**
|
|
26868
|
-
* Merge 2 blocks if the gap between them is < 1kb and the total resulting size < 100mb
|
|
26869
|
-
* @param chunk1
|
|
26870
|
-
* @param chunk2
|
|
26871
|
-
* @returns {boolean|boolean}
|
|
26872
|
-
*/
|
|
26873
|
-
function canMerge(chunk1, chunk2) {
|
|
26874
|
-
const gap = chunk2.minv.block - chunk1.maxv.block;
|
|
26875
|
-
const total = chunk2.maxv.block - chunk1.minv.block;
|
|
26876
|
-
return gap < 30000 && total < 10 * MB;
|
|
26877
|
-
}
|
|
26878
26868
|
|
|
26879
26869
|
/**
|
|
26880
26870
|
* Calculate the list of bins that overlap with region [beg, end]
|
|
@@ -27006,7 +26996,7 @@
|
|
|
27006
26996
|
* @param min genomic start position
|
|
27007
26997
|
* @param max genomic end position
|
|
27008
26998
|
*/
|
|
27009
|
-
|
|
26999
|
+
chunksForRange(queryChr, min, max) {
|
|
27010
27000
|
const chrIdx = this.chrIndex[queryChr];
|
|
27011
27001
|
if (chrIdx) {
|
|
27012
27002
|
const blocks = chrIdx.blocks;
|
|
@@ -27166,7 +27156,12 @@
|
|
|
27166
27156
|
}
|
|
27167
27157
|
}
|
|
27168
27158
|
|
|
27169
|
-
|
|
27159
|
+
/**
|
|
27160
|
+
* Class to iterate line-by-line over a BGZipped text file. This class is useful for iterating from the start of
|
|
27161
|
+
* the file. Not useful for indexed queries.
|
|
27162
|
+
*/
|
|
27163
|
+
|
|
27164
|
+
class BGZLineReader {
|
|
27170
27165
|
constructor(config) {
|
|
27171
27166
|
this.config = config;
|
|
27172
27167
|
this.filePtr = 0;
|
|
@@ -27206,7 +27201,7 @@
|
|
|
27206
27201
|
}
|
|
27207
27202
|
});
|
|
27208
27203
|
const abuffer = await igvxhr.loadArrayBuffer(this.config.url, bsizeOptions);
|
|
27209
|
-
const bufferSize = bgzBlockSize(abuffer);
|
|
27204
|
+
const bufferSize = bgzBlockSize$1(abuffer);
|
|
27210
27205
|
//console.log(`next block ${this.filePtr} ${bufferSize}`);
|
|
27211
27206
|
|
|
27212
27207
|
if (bufferSize === 0) {
|
|
@@ -27231,6 +27226,244 @@
|
|
|
27231
27226
|
}
|
|
27232
27227
|
}
|
|
27233
27228
|
|
|
27229
|
+
function concatenateArrayBuffers(arrayBuffers) {
|
|
27230
|
+
if (arrayBuffers.length === 1) {
|
|
27231
|
+
return arrayBuffers[0];
|
|
27232
|
+
}
|
|
27233
|
+
let len = 0;
|
|
27234
|
+
for (const b of arrayBuffers) {
|
|
27235
|
+
len += b.byteLength;
|
|
27236
|
+
}
|
|
27237
|
+
const c = new Uint8Array(len);
|
|
27238
|
+
let offset = 0;
|
|
27239
|
+
for (const b of arrayBuffers) {
|
|
27240
|
+
c.set(new Uint8Array(b), offset);
|
|
27241
|
+
offset += b.byteLength;
|
|
27242
|
+
}
|
|
27243
|
+
return c.buffer;
|
|
27244
|
+
}
|
|
27245
|
+
|
|
27246
|
+
/**
|
|
27247
|
+
* Return the block size for the data buffer.
|
|
27248
|
+
* @param data
|
|
27249
|
+
* @returns {number}
|
|
27250
|
+
*/
|
|
27251
|
+
const bgzBlockSize = data => {
|
|
27252
|
+
const ba = ArrayBuffer.isView(data) ? data : new Uint8Array(data);
|
|
27253
|
+
const bsize = (ba[17] << 8 | ba[16]) + 1;
|
|
27254
|
+
return bsize;
|
|
27255
|
+
};
|
|
27256
|
+
class BGZBlockLoader {
|
|
27257
|
+
constructor(config) {
|
|
27258
|
+
this.config = config;
|
|
27259
|
+
this.cacheBlocks = false != config.cacheBlocks; // Default to true
|
|
27260
|
+
this.cache = undefined;
|
|
27261
|
+
}
|
|
27262
|
+
|
|
27263
|
+
/**
|
|
27264
|
+
* Return inflated data from startBlock through endBlock as an UInt8Array
|
|
27265
|
+
*
|
|
27266
|
+
* @param startBlock
|
|
27267
|
+
* @param endBlock
|
|
27268
|
+
* @returns {Promise<Uint8Array>}
|
|
27269
|
+
*/
|
|
27270
|
+
async getData(startBlock, endBlock) {
|
|
27271
|
+
const blocks = await this.getInflatedBlocks(startBlock, endBlock);
|
|
27272
|
+
if (blocks.length === 1) {
|
|
27273
|
+
return blocks[0];
|
|
27274
|
+
}
|
|
27275
|
+
let len = 0;
|
|
27276
|
+
for (const b of blocks) {
|
|
27277
|
+
len += b.byteLength;
|
|
27278
|
+
}
|
|
27279
|
+
const c = new Uint8Array(len);
|
|
27280
|
+
let offset = 0;
|
|
27281
|
+
for (const b of blocks) {
|
|
27282
|
+
c.set(b, offset);
|
|
27283
|
+
offset += b.byteLength;
|
|
27284
|
+
}
|
|
27285
|
+
return c;
|
|
27286
|
+
}
|
|
27287
|
+
|
|
27288
|
+
/**
|
|
27289
|
+
* Return the inflated data for the specified blocks as an array of Uint8Arrays. This method is public so
|
|
27290
|
+
* it can be unit tested. *
|
|
27291
|
+
* @param startBlock
|
|
27292
|
+
* @param endBlock
|
|
27293
|
+
* @returns {Promise<*[Uint8Array]>}
|
|
27294
|
+
*/
|
|
27295
|
+
async getInflatedBlocks(startBlock, endBlock) {
|
|
27296
|
+
if (!this.cacheBlocks) {
|
|
27297
|
+
const buffer = await this.loadBLockData(startBlock, endBlock);
|
|
27298
|
+
return inflateBlocks(buffer);
|
|
27299
|
+
} else {
|
|
27300
|
+
const c = this.cache;
|
|
27301
|
+
if (c && c.startBlock <= startBlock && c.endBlock >= endBlock) {
|
|
27302
|
+
//console.log("Complete overlap")
|
|
27303
|
+
const startOffset = startBlock - c.startBlock;
|
|
27304
|
+
const endOffset = endBlock - c.startBlock;
|
|
27305
|
+
return inflateBlocks(c.buffer, startOffset, endOffset);
|
|
27306
|
+
// Don't update cache, still valid
|
|
27307
|
+
} else {
|
|
27308
|
+
let buffer;
|
|
27309
|
+
if (!c || c.startBlock > endBlock || c.endBlock < startBlock) {
|
|
27310
|
+
// no overlap with cache
|
|
27311
|
+
buffer = await this.loadBLockData(startBlock, endBlock);
|
|
27312
|
+
} else {
|
|
27313
|
+
//console.log("Some overlap")
|
|
27314
|
+
const arrayBuffers = [];
|
|
27315
|
+
|
|
27316
|
+
// Load blocks preceding cache start, if any
|
|
27317
|
+
if (startBlock < c.startBlock) {
|
|
27318
|
+
// load first blocks
|
|
27319
|
+
const startBuffer = await this.loadBLockData(startBlock, c.startBlock, {
|
|
27320
|
+
skipEnd: true
|
|
27321
|
+
});
|
|
27322
|
+
arrayBuffers.push(startBuffer);
|
|
27323
|
+
}
|
|
27324
|
+
|
|
27325
|
+
// Slice cached buffer as needed
|
|
27326
|
+
let cachedBuffer;
|
|
27327
|
+
if (startBlock <= c.startBlock && endBlock >= c.endBlock) {
|
|
27328
|
+
cachedBuffer = c.buffer;
|
|
27329
|
+
} else {
|
|
27330
|
+
const start = Math.max(0, startBlock - c.startBlock);
|
|
27331
|
+
let end;
|
|
27332
|
+
if (endBlock >= c.endBlock) {
|
|
27333
|
+
end = c.buffer.byteLength;
|
|
27334
|
+
} else {
|
|
27335
|
+
// We need to find the byte position of the end of "endBlock"
|
|
27336
|
+
const boundaries = findBlockBoundaries(c.buffer);
|
|
27337
|
+
for (let i = 0; i < boundaries.length - 1; i++) {
|
|
27338
|
+
if (c.startBlock + boundaries[i] === endBlock) {
|
|
27339
|
+
end = boundaries[i + 1];
|
|
27340
|
+
break;
|
|
27341
|
+
}
|
|
27342
|
+
}
|
|
27343
|
+
// Do something if end not found
|
|
27344
|
+
}
|
|
27345
|
+
|
|
27346
|
+
cachedBuffer = c.buffer.slice(start, end);
|
|
27347
|
+
}
|
|
27348
|
+
arrayBuffers.push(cachedBuffer);
|
|
27349
|
+
|
|
27350
|
+
// Load end blocks, if any
|
|
27351
|
+
if (endBlock > c.endBlock) {
|
|
27352
|
+
const endBuffer = await this.loadBLockData(c.endBlock, endBlock, {
|
|
27353
|
+
skipStart: true
|
|
27354
|
+
});
|
|
27355
|
+
arrayBuffers.push(endBuffer);
|
|
27356
|
+
}
|
|
27357
|
+
buffer = concatenateArrayBuffers(arrayBuffers);
|
|
27358
|
+
}
|
|
27359
|
+
this.cache = {
|
|
27360
|
+
startBlock,
|
|
27361
|
+
endBlock,
|
|
27362
|
+
buffer
|
|
27363
|
+
};
|
|
27364
|
+
return inflateBlocks(buffer);
|
|
27365
|
+
}
|
|
27366
|
+
}
|
|
27367
|
+
}
|
|
27368
|
+
async loadBLockData(startBlock, endBlock, options) {
|
|
27369
|
+
const config = this.config;
|
|
27370
|
+
const skipStart = options && options.skipStart;
|
|
27371
|
+
const skipEnd = options && options.skipEnd;
|
|
27372
|
+
|
|
27373
|
+
// Get size of last block if not skipped
|
|
27374
|
+
let lastBlockSize = 0;
|
|
27375
|
+
if (!skipEnd) {
|
|
27376
|
+
const bsizeOptions = buildOptions(config, {
|
|
27377
|
+
range: {
|
|
27378
|
+
start: endBlock,
|
|
27379
|
+
size: 26
|
|
27380
|
+
}
|
|
27381
|
+
});
|
|
27382
|
+
const abuffer = await igvxhr.loadArrayBuffer(config.url, bsizeOptions);
|
|
27383
|
+
lastBlockSize = bgzBlockSize(abuffer);
|
|
27384
|
+
}
|
|
27385
|
+
if (skipStart) {
|
|
27386
|
+
const bsizeOptions = buildOptions(config, {
|
|
27387
|
+
range: {
|
|
27388
|
+
start: startBlock,
|
|
27389
|
+
size: 26
|
|
27390
|
+
}
|
|
27391
|
+
});
|
|
27392
|
+
const abuffer = await igvxhr.loadArrayBuffer(config.url, bsizeOptions);
|
|
27393
|
+
startBlock += bgzBlockSize(abuffer);
|
|
27394
|
+
}
|
|
27395
|
+
|
|
27396
|
+
// Load data for all blocks
|
|
27397
|
+
const loadOptions = buildOptions(config, {
|
|
27398
|
+
range: {
|
|
27399
|
+
start: startBlock,
|
|
27400
|
+
size: endBlock + lastBlockSize - startBlock
|
|
27401
|
+
}
|
|
27402
|
+
});
|
|
27403
|
+
|
|
27404
|
+
//console.log(`${this.config.name} Loaded ${startBlock} - ${endBlock + lastBlockSize} (${(endBlock + lastBlockSize - startBlock) / 1000} kb)`)
|
|
27405
|
+
|
|
27406
|
+
return igvxhr.loadArrayBuffer(config.url, loadOptions);
|
|
27407
|
+
}
|
|
27408
|
+
}
|
|
27409
|
+
function findBlockBoundaries(arrayBuffer) {
|
|
27410
|
+
const byteLengh = arrayBuffer.byteLength;
|
|
27411
|
+
let offset = 0;
|
|
27412
|
+
const blockBoundaries = [0];
|
|
27413
|
+
while (offset < byteLengh) {
|
|
27414
|
+
//console.log("Cache block " + offset)
|
|
27415
|
+
const ba = new Uint8Array(arrayBuffer, offset);
|
|
27416
|
+
const bsize = (ba[17] << 8 | ba[16]) + 1;
|
|
27417
|
+
offset += bsize;
|
|
27418
|
+
if (offset < byteLengh) {
|
|
27419
|
+
blockBoundaries.push(offset);
|
|
27420
|
+
}
|
|
27421
|
+
}
|
|
27422
|
+
return blockBoundaries;
|
|
27423
|
+
}
|
|
27424
|
+
|
|
27425
|
+
/**
|
|
27426
|
+
* Inflate compressed blocks within the data buffer*
|
|
27427
|
+
* @param data
|
|
27428
|
+
* @param startBlock - optional file location for start block. Default == 0
|
|
27429
|
+
* @param endBlock - optional file location for last block to decompress.
|
|
27430
|
+
* @returns {*[]}
|
|
27431
|
+
*/
|
|
27432
|
+
function inflateBlocks(data, startBlock, endBlock) {
|
|
27433
|
+
startBlock = startBlock || 0;
|
|
27434
|
+
const oBlockList = [];
|
|
27435
|
+
let ptr = startBlock;
|
|
27436
|
+
const lim = data.byteLength - 18;
|
|
27437
|
+
while (ptr < lim) {
|
|
27438
|
+
try {
|
|
27439
|
+
//console.log(113873 + ptr)
|
|
27440
|
+
const header = new Uint8Array(data, ptr, 18);
|
|
27441
|
+
const xlen = header[11] << 8 | header[10];
|
|
27442
|
+
const bsize = header[17] << 8 | header[16]; // Total block size, including header, minus 1
|
|
27443
|
+
const start = 12 + xlen + ptr; // Start of CDATA
|
|
27444
|
+
const bytesLeft = data.byteLength - start;
|
|
27445
|
+
const cDataSize = bsize - xlen - 18;
|
|
27446
|
+
if (bytesLeft < cDataSize || cDataSize <= 0) {
|
|
27447
|
+
// This is unexpected. Throw error?
|
|
27448
|
+
break;
|
|
27449
|
+
}
|
|
27450
|
+
const cdata = new Uint8Array(data, start, cDataSize);
|
|
27451
|
+
const unc = inflateRaw(cdata);
|
|
27452
|
+
oBlockList.push(unc);
|
|
27453
|
+
if (endBlock === ptr) {
|
|
27454
|
+
break;
|
|
27455
|
+
} else {
|
|
27456
|
+
// Advance to next block
|
|
27457
|
+
ptr += bsize + 1;
|
|
27458
|
+
}
|
|
27459
|
+
} catch (e) {
|
|
27460
|
+
console.error(e);
|
|
27461
|
+
break;
|
|
27462
|
+
}
|
|
27463
|
+
}
|
|
27464
|
+
return oBlockList;
|
|
27465
|
+
}
|
|
27466
|
+
|
|
27234
27467
|
/*
|
|
27235
27468
|
* The MIT License (MIT)
|
|
27236
27469
|
*
|
|
@@ -27332,7 +27565,8 @@
|
|
|
27332
27565
|
}
|
|
27333
27566
|
let dataWrapper;
|
|
27334
27567
|
if (index.tabix) {
|
|
27335
|
-
|
|
27568
|
+
this._blockLoader = new BGZBlockLoader(this.config);
|
|
27569
|
+
dataWrapper = new BGZLineReader(this.config);
|
|
27336
27570
|
} else {
|
|
27337
27571
|
// Tribble
|
|
27338
27572
|
const maxSize = Object.values(index.chrIndex).flatMap(chr => chr.blocks).map(block => block.max).reduce((previous, current) => Math.min(previous, current), Number.MAX_SAFE_INTEGER);
|
|
@@ -27408,46 +27642,25 @@
|
|
|
27408
27642
|
return [];
|
|
27409
27643
|
}
|
|
27410
27644
|
const genome = this.genome;
|
|
27411
|
-
const
|
|
27412
|
-
if (!
|
|
27645
|
+
const chunks = this.index.chunksForRange(refId, start, end);
|
|
27646
|
+
if (!chunks || chunks.length === 0) {
|
|
27413
27647
|
return [];
|
|
27414
27648
|
} else {
|
|
27415
27649
|
const allFeatures = [];
|
|
27416
|
-
for (let
|
|
27417
|
-
const startPos = block.minv.block;
|
|
27418
|
-
const startOffset = block.minv.offset;
|
|
27419
|
-
const endOffset = block.maxv.offset;
|
|
27420
|
-
let endPos;
|
|
27421
|
-
if (tabix) {
|
|
27422
|
-
let lastBlockSize = 0;
|
|
27423
|
-
if (endOffset > 0) {
|
|
27424
|
-
const bsizeOptions = buildOptions(config, {
|
|
27425
|
-
range: {
|
|
27426
|
-
start: block.maxv.block,
|
|
27427
|
-
size: 26
|
|
27428
|
-
}
|
|
27429
|
-
});
|
|
27430
|
-
const abuffer = await igvxhr.loadArrayBuffer(config.url, bsizeOptions);
|
|
27431
|
-
lastBlockSize = bgzBlockSize(abuffer);
|
|
27432
|
-
}
|
|
27433
|
-
endPos = block.maxv.block + lastBlockSize;
|
|
27434
|
-
} else {
|
|
27435
|
-
endPos = block.maxv.block;
|
|
27436
|
-
}
|
|
27437
|
-
const options = buildOptions(config, {
|
|
27438
|
-
range: {
|
|
27439
|
-
start: startPos,
|
|
27440
|
-
size: endPos - startPos + 1
|
|
27441
|
-
}
|
|
27442
|
-
});
|
|
27650
|
+
for (let chunk of chunks) {
|
|
27443
27651
|
let inflated;
|
|
27444
27652
|
if (tabix) {
|
|
27445
|
-
|
|
27446
|
-
inflated = unbgzf(data);
|
|
27653
|
+
inflated = await this._blockLoader.getData(chunk.minv.block, chunk.maxv.block);
|
|
27447
27654
|
} else {
|
|
27655
|
+
const options = buildOptions(config, {
|
|
27656
|
+
range: {
|
|
27657
|
+
start: chunk.minv.block,
|
|
27658
|
+
size: chunk.maxv.block - chunk.minv.block + 1
|
|
27659
|
+
}
|
|
27660
|
+
});
|
|
27448
27661
|
inflated = await igvxhr.loadString(config.url, options);
|
|
27449
27662
|
}
|
|
27450
|
-
const slicedData =
|
|
27663
|
+
const slicedData = chunk.minv.offset ? inflated.slice(chunk.minv.offset) : inflated;
|
|
27451
27664
|
const dataWrapper = getDataWrapper(slicedData);
|
|
27452
27665
|
let slicedFeatures = await parser.parseFeatures(dataWrapper);
|
|
27453
27666
|
|
|
@@ -29873,6 +30086,7 @@
|
|
|
29873
30086
|
var documentAll$2 = typeof document == 'object' && document.all;
|
|
29874
30087
|
|
|
29875
30088
|
// https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot
|
|
30089
|
+
// eslint-disable-next-line unicorn/no-typeof-undefined -- required for testing
|
|
29876
30090
|
var IS_HTMLDDA = typeof documentAll$2 == 'undefined' && documentAll$2 !== undefined;
|
|
29877
30091
|
var documentAll_1 = {
|
|
29878
30092
|
all: documentAll$2,
|
|
@@ -30127,10 +30341,10 @@
|
|
|
30127
30341
|
(module.exports = function (key, value) {
|
|
30128
30342
|
return sharedStore[key] || (sharedStore[key] = value !== undefined ? value : {});
|
|
30129
30343
|
})('versions', []).push({
|
|
30130
|
-
version: '3.
|
|
30344
|
+
version: '3.27.1',
|
|
30131
30345
|
mode: 'global',
|
|
30132
30346
|
copyright: '© 2014-2022 Denis Pushkarev (zloirock.ru)',
|
|
30133
|
-
license: 'https://github.com/zloirock/core-js/blob/v3.
|
|
30347
|
+
license: 'https://github.com/zloirock/core-js/blob/v3.27.1/LICENSE',
|
|
30134
30348
|
source: 'https://github.com/zloirock/core-js'
|
|
30135
30349
|
});
|
|
30136
30350
|
});
|
|
@@ -33368,6 +33582,7 @@
|
|
|
33368
33582
|
this.bamPath = config.url;
|
|
33369
33583
|
this.baiPath = config.indexURL;
|
|
33370
33584
|
BamUtils.setReaderDefaults(this, config);
|
|
33585
|
+
this._blockLoader = new BGZBlockLoader(config);
|
|
33371
33586
|
}
|
|
33372
33587
|
async readAlignments(chr, bpStart, bpEnd) {
|
|
33373
33588
|
const chrToIndex = await this.getChrIndex();
|
|
@@ -33378,37 +33593,14 @@
|
|
|
33378
33593
|
return alignmentContainer;
|
|
33379
33594
|
} else {
|
|
33380
33595
|
const bamIndex = await this.getIndex();
|
|
33381
|
-
const chunks = bamIndex.
|
|
33596
|
+
const chunks = bamIndex.chunksForRange(chrId, bpStart, bpEnd);
|
|
33382
33597
|
if (!chunks || chunks.length === 0) {
|
|
33383
33598
|
return alignmentContainer;
|
|
33384
33599
|
}
|
|
33385
33600
|
for (let c of chunks) {
|
|
33386
|
-
|
|
33387
|
-
if (c.maxv.offset === 0) {
|
|
33388
|
-
lastBlockSize = 0; // Don't need to read the last block.
|
|
33389
|
-
} else {
|
|
33390
|
-
const bsizeOptions = buildOptions(this.config, {
|
|
33391
|
-
range: {
|
|
33392
|
-
start: c.maxv.block,
|
|
33393
|
-
size: 26
|
|
33394
|
-
}
|
|
33395
|
-
});
|
|
33396
|
-
const abuffer = await igvxhr.loadArrayBuffer(this.bamPath, bsizeOptions);
|
|
33397
|
-
lastBlockSize = bgzBlockSize(abuffer);
|
|
33398
|
-
}
|
|
33399
|
-
const fetchMin = c.minv.block;
|
|
33400
|
-
const fetchMax = c.maxv.block + lastBlockSize;
|
|
33401
|
-
const range = {
|
|
33402
|
-
start: fetchMin,
|
|
33403
|
-
size: fetchMax - fetchMin + 1
|
|
33404
|
-
};
|
|
33405
|
-
const compressed = await igvxhr.loadArrayBuffer(this.bamPath, buildOptions(this.config, {
|
|
33406
|
-
range: range
|
|
33407
|
-
}));
|
|
33408
|
-
var ba = unbgzf(compressed); //new Uint8Array(BGZip.unbgzf(compressed)); //, c.maxv.block - c.minv.block + 1));
|
|
33601
|
+
const ba = await this._blockLoader.getData(c.minv.block, c.maxv.block);
|
|
33409
33602
|
const done = BamUtils.decodeBamRecords(ba, c.minv.offset, alignmentContainer, this.indexToChr, chrId, bpStart, bpEnd, this.filter);
|
|
33410
33603
|
if (done) {
|
|
33411
|
-
// console.log(`Loaded ${counter} chunks out of ${chunks.length}`);
|
|
33412
33604
|
break;
|
|
33413
33605
|
}
|
|
33414
33606
|
}
|
|
@@ -33429,7 +33621,7 @@
|
|
|
33429
33621
|
}
|
|
33430
33622
|
});
|
|
33431
33623
|
const abuffer = await igvxhr.loadArrayBuffer(this.bamPath, bsizeOptions);
|
|
33432
|
-
const bsize = bgzBlockSize(abuffer);
|
|
33624
|
+
const bsize = bgzBlockSize$1(abuffer);
|
|
33433
33625
|
len = index.firstBlockPosition + bsize; // Insure we get the complete compressed block containing the header
|
|
33434
33626
|
} else {
|
|
33435
33627
|
len = 64000;
|
|
@@ -33967,7 +34159,7 @@
|
|
|
33967
34159
|
var clear = global$1.clearImmediate;
|
|
33968
34160
|
var process$1 = global$1.process;
|
|
33969
34161
|
var Dispatch = global$1.Dispatch;
|
|
33970
|
-
var Function$
|
|
34162
|
+
var Function$2 = global$1.Function;
|
|
33971
34163
|
var MessageChannel$1 = global$1.MessageChannel;
|
|
33972
34164
|
var String$1 = global$1.String;
|
|
33973
34165
|
var counter = 0;
|
|
@@ -34002,7 +34194,7 @@
|
|
|
34002
34194
|
if (!set || !clear) {
|
|
34003
34195
|
set = function setImmediate(handler) {
|
|
34004
34196
|
validateArgumentsLength(arguments.length, 1);
|
|
34005
|
-
var fn = isCallable(handler) ? handler : Function$
|
|
34197
|
+
var fn = isCallable(handler) ? handler : Function$2(handler);
|
|
34006
34198
|
var args = arraySlice(arguments, 1);
|
|
34007
34199
|
queue[++counter] = function () {
|
|
34008
34200
|
functionApply(fn, undefined, args);
|
|
@@ -34068,7 +34260,36 @@
|
|
|
34068
34260
|
clearImmediate: clearImmediate
|
|
34069
34261
|
});
|
|
34070
34262
|
|
|
34071
|
-
|
|
34263
|
+
/* global Bun -- Deno case */
|
|
34264
|
+
var engineIsBun = typeof Bun == 'function' && Bun && typeof Bun.version == 'string';
|
|
34265
|
+
|
|
34266
|
+
var Function$1 = global$1.Function;
|
|
34267
|
+
// dirty IE9- and Bun 0.3.0- checks
|
|
34268
|
+
var WRAP = /MSIE .\./.test(engineUserAgent) || engineIsBun && function () {
|
|
34269
|
+
var version = global$1.Bun.version.split('.');
|
|
34270
|
+
return version.length < 3 || version[0] == 0 && (version[1] < 3 || version[1] == 3 && version[2] == 0);
|
|
34271
|
+
}();
|
|
34272
|
+
|
|
34273
|
+
// IE9- / Bun 0.3.0- setTimeout / setInterval / setImmediate additional parameters fix
|
|
34274
|
+
// https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#timers
|
|
34275
|
+
// https://github.com/oven-sh/bun/issues/1633
|
|
34276
|
+
var schedulersFix = function (scheduler, hasTimeArg) {
|
|
34277
|
+
var firstParamIndex = hasTimeArg ? 2 : 1;
|
|
34278
|
+
return WRAP ? function (handler, timeout /* , ...arguments */) {
|
|
34279
|
+
var boundArgs = validateArgumentsLength(arguments.length, 1) > firstParamIndex;
|
|
34280
|
+
var fn = isCallable(handler) ? handler : Function$1(handler);
|
|
34281
|
+
var params = boundArgs ? arraySlice(arguments, firstParamIndex) : [];
|
|
34282
|
+
var callback = boundArgs ? function () {
|
|
34283
|
+
functionApply(fn, this, params);
|
|
34284
|
+
} : fn;
|
|
34285
|
+
return hasTimeArg ? scheduler(callback, timeout) : scheduler(callback);
|
|
34286
|
+
} : scheduler;
|
|
34287
|
+
};
|
|
34288
|
+
|
|
34289
|
+
var setTask = task.set;
|
|
34290
|
+
|
|
34291
|
+
// https://github.com/oven-sh/bun/issues/1633
|
|
34292
|
+
var setImmediate = global$1.setImmediate ? schedulersFix(setTask, false) : setTask;
|
|
34072
34293
|
|
|
34073
34294
|
// `setImmediate` method
|
|
34074
34295
|
// http://w3c.github.io/setImmediate/#si-setImmediate
|
|
@@ -50411,7 +50632,9 @@
|
|
|
50411
50632
|
hoverText(clickState) {
|
|
50412
50633
|
if (true === this.showCoverage && clickState.y >= this.coverageTrack.top && clickState.y < this.coverageTrack.height) {
|
|
50413
50634
|
const clickedObject = this.coverageTrack.getClickedObject(clickState);
|
|
50414
|
-
|
|
50635
|
+
if (clickedObject) {
|
|
50636
|
+
return clickedObject.hoverText();
|
|
50637
|
+
}
|
|
50415
50638
|
}
|
|
50416
50639
|
}
|
|
50417
50640
|
menuItemList() {
|