igv 3.5.3 → 3.5.4
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 +220 -366
- package/dist/igv.esm.min.js +9 -9
- package/dist/igv.esm.min.js.map +1 -1
- package/dist/igv.js +220 -366
- package/dist/igv.min.js +9 -9
- package/dist/igv.min.js.map +1 -1
- package/package.json +2 -2
package/dist/igv.js
CHANGED
|
@@ -392,12 +392,12 @@
|
|
|
392
392
|
decsep = '.';
|
|
393
393
|
|
|
394
394
|
return dec[0].split('').reverse().reduce(function (prev, now, i) {
|
|
395
|
-
return i % 3 === 0 ? prev + sep + now : prev + now
|
|
396
|
-
}).split('').reverse().join('') + (dec[1] ? decsep + dec[1] : '')
|
|
395
|
+
return i % 3 === 0 ? prev + sep + now : prev + now
|
|
396
|
+
}).split('').reverse().join('') + (dec[1] ? decsep + dec[1] : '')
|
|
397
397
|
}
|
|
398
398
|
|
|
399
399
|
const splitLines$3 = function (string) {
|
|
400
|
-
return string.split(/\n|\r\n|\r/g)
|
|
400
|
+
return string.split(/\n|\r\n|\r/g)
|
|
401
401
|
};
|
|
402
402
|
|
|
403
403
|
|
|
@@ -425,24 +425,24 @@
|
|
|
425
425
|
}
|
|
426
426
|
}
|
|
427
427
|
}
|
|
428
|
-
return tokens
|
|
428
|
+
return tokens
|
|
429
429
|
}
|
|
430
430
|
|
|
431
431
|
function stripQuotes$2(str) {
|
|
432
|
-
if(str === undefined) {
|
|
433
|
-
return str
|
|
432
|
+
if (str === undefined) {
|
|
433
|
+
return str
|
|
434
434
|
}
|
|
435
|
-
if(str.startsWith("'") || str.startsWith('"')) {
|
|
435
|
+
if (str.startsWith("'") || str.startsWith('"')) {
|
|
436
436
|
str = str.substring(1);
|
|
437
437
|
}
|
|
438
438
|
if (str.endsWith("'") || str.endsWith('"')) {
|
|
439
439
|
str = str.substring(0, str.length - 1);
|
|
440
440
|
}
|
|
441
|
-
return str
|
|
441
|
+
return str
|
|
442
442
|
}
|
|
443
443
|
|
|
444
444
|
function capitalize(str) {
|
|
445
|
-
return str.length > 0 ? str.charAt(0).toUpperCase() + str.slice(1) : str
|
|
445
|
+
return str.length > 0 ? str.charAt(0).toUpperCase() + str.slice(1) : str
|
|
446
446
|
}
|
|
447
447
|
|
|
448
448
|
|
|
@@ -466,7 +466,7 @@
|
|
|
466
466
|
range.end = range.start + 1;
|
|
467
467
|
}
|
|
468
468
|
|
|
469
|
-
return range
|
|
469
|
+
return range
|
|
470
470
|
}
|
|
471
471
|
|
|
472
472
|
/**
|
|
@@ -475,7 +475,7 @@
|
|
|
475
475
|
* @param urlOrFile
|
|
476
476
|
*/
|
|
477
477
|
|
|
478
|
-
function getFilename$
|
|
478
|
+
function getFilename$1(urlOrFile) {
|
|
479
479
|
|
|
480
480
|
if (urlOrFile.name !== undefined) {
|
|
481
481
|
return urlOrFile.name
|
|
@@ -502,8 +502,8 @@
|
|
|
502
502
|
* @param object
|
|
503
503
|
*/
|
|
504
504
|
function isFile(object) {
|
|
505
|
-
if(!object) {
|
|
506
|
-
return false
|
|
505
|
+
if (!object) {
|
|
506
|
+
return false
|
|
507
507
|
}
|
|
508
508
|
return typeof object !== 'function' &&
|
|
509
509
|
(object instanceof File ||
|
|
@@ -523,7 +523,7 @@
|
|
|
523
523
|
|
|
524
524
|
if (typeof process === 'object' && typeof window === 'undefined') {
|
|
525
525
|
global.atob = function (str) {
|
|
526
|
-
return Buffer.from(str, 'base64').toString('binary')
|
|
526
|
+
return Buffer.from(str, 'base64').toString('binary')
|
|
527
527
|
};
|
|
528
528
|
}
|
|
529
529
|
|
|
@@ -542,7 +542,7 @@
|
|
|
542
542
|
if ($1) uri[o.q.name][$1] = $2;
|
|
543
543
|
});
|
|
544
544
|
|
|
545
|
-
return uri
|
|
545
|
+
return uri
|
|
546
546
|
}
|
|
547
547
|
|
|
548
548
|
const options = {
|
|
@@ -565,7 +565,7 @@
|
|
|
565
565
|
* @returns {Promise<*>}
|
|
566
566
|
*/
|
|
567
567
|
async function resolveURL(url) {
|
|
568
|
-
return (typeof url === 'function')
|
|
568
|
+
return (typeof url === 'function') ? url() : url
|
|
569
569
|
}
|
|
570
570
|
|
|
571
571
|
/*! pako 2.1.0 https://github.com/nodeca/pako @license (MIT AND Zlib) */
|
|
@@ -7427,7 +7427,7 @@
|
|
|
7427
7427
|
|
|
7428
7428
|
function isgzipped(data) {
|
|
7429
7429
|
const b = ArrayBuffer.isView(data) ? data : new Uint8Array(data);
|
|
7430
|
-
return b[0] ===31 && b[1] === 139
|
|
7430
|
+
return b[0] === 31 && b[1] === 139
|
|
7431
7431
|
}
|
|
7432
7432
|
|
|
7433
7433
|
/**
|
|
@@ -7437,9 +7437,9 @@
|
|
|
7437
7437
|
const ba = ArrayBuffer.isView(data) ? data : new Uint8Array(data);
|
|
7438
7438
|
const b = ba[3] & FEXTRA$1;
|
|
7439
7439
|
if (b !== 0 && ba[12] === 66 && ba[13] === 67) {
|
|
7440
|
-
return unbgzf(ba.buffer)
|
|
7440
|
+
return unbgzf(ba.buffer)
|
|
7441
7441
|
} else {
|
|
7442
|
-
return ungzip_1$1(ba)
|
|
7442
|
+
return ungzip_1$1(ba)
|
|
7443
7443
|
}
|
|
7444
7444
|
}
|
|
7445
7445
|
|
|
@@ -7465,7 +7465,7 @@
|
|
|
7465
7465
|
const start = 12 + xlen + ptr; // Start of CDATA
|
|
7466
7466
|
const bytesLeft = data.byteLength - start;
|
|
7467
7467
|
const cDataSize = bsize - xlen - 19;
|
|
7468
|
-
if (bytesLeft < cDataSize || cDataSize <= 0) break
|
|
7468
|
+
if (bytesLeft < cDataSize || cDataSize <= 0) break
|
|
7469
7469
|
|
|
7470
7470
|
const a = new Uint8Array(data, start, cDataSize);
|
|
7471
7471
|
const unc = inflateRaw_1(a);
|
|
@@ -7478,13 +7478,13 @@
|
|
|
7478
7478
|
oBlockList.push(unc);
|
|
7479
7479
|
} catch (e) {
|
|
7480
7480
|
console.error(e);
|
|
7481
|
-
break
|
|
7481
|
+
break
|
|
7482
7482
|
}
|
|
7483
7483
|
}
|
|
7484
7484
|
|
|
7485
7485
|
// Concatenate decompressed blocks
|
|
7486
7486
|
if (oBlockList.length === 1) {
|
|
7487
|
-
return oBlockList[0]
|
|
7487
|
+
return oBlockList[0]
|
|
7488
7488
|
} else {
|
|
7489
7489
|
const out = new Uint8Array(totalSize);
|
|
7490
7490
|
let cursor = 0;
|
|
@@ -7493,14 +7493,14 @@
|
|
|
7493
7493
|
arrayCopy(b, 0, out, cursor, b.length);
|
|
7494
7494
|
cursor += b.length;
|
|
7495
7495
|
}
|
|
7496
|
-
return out
|
|
7496
|
+
return out
|
|
7497
7497
|
}
|
|
7498
7498
|
}
|
|
7499
7499
|
|
|
7500
7500
|
function bgzBlockSize$1(data) {
|
|
7501
7501
|
const ba = ArrayBuffer.isView(data) ? data : new Uint8Array(data);
|
|
7502
7502
|
const bsize = (ba[17] << 8 | ba[16]) + 1;
|
|
7503
|
-
return bsize
|
|
7503
|
+
return bsize
|
|
7504
7504
|
}
|
|
7505
7505
|
|
|
7506
7506
|
// From Thomas Down's zlib implementation
|
|
@@ -7510,12 +7510,12 @@
|
|
|
7510
7510
|
|
|
7511
7511
|
function arrayCopy(src, srcOffset, dest, destOffset, count) {
|
|
7512
7512
|
if (count === 0) {
|
|
7513
|
-
return
|
|
7513
|
+
return
|
|
7514
7514
|
}
|
|
7515
7515
|
if (!src) {
|
|
7516
|
-
throw "Undef src"
|
|
7516
|
+
throw "Undef src"
|
|
7517
7517
|
} else if (!dest) {
|
|
7518
|
-
throw "Undef dest"
|
|
7518
|
+
throw "Undef dest"
|
|
7519
7519
|
}
|
|
7520
7520
|
if (srcOffset === 0 && count === src.length) {
|
|
7521
7521
|
arrayCopy_fast(src, dest, destOffset);
|
|
@@ -7552,7 +7552,7 @@
|
|
|
7552
7552
|
const compressedBytes = new deflateRaw_1(bytes); // UInt8Arry
|
|
7553
7553
|
const compressedString = String.fromCharCode.apply(null, compressedBytes); // Convert to string
|
|
7554
7554
|
let enc = btoa(compressedString);
|
|
7555
|
-
return enc.replace(/\+/g, '.').replace(/\//g, '_').replace(/=/g, '-')
|
|
7555
|
+
return enc.replace(/\+/g, '.').replace(/\//g, '_').replace(/=/g, '-') // URL safe
|
|
7556
7556
|
}
|
|
7557
7557
|
|
|
7558
7558
|
/**
|
|
@@ -7577,7 +7577,7 @@
|
|
|
7577
7577
|
for (let b of bytes) {
|
|
7578
7578
|
str += String.fromCharCode(b);
|
|
7579
7579
|
}
|
|
7580
|
-
return str
|
|
7580
|
+
return str
|
|
7581
7581
|
}
|
|
7582
7582
|
|
|
7583
7583
|
|
|
@@ -7607,7 +7607,7 @@
|
|
|
7607
7607
|
}
|
|
7608
7608
|
return plain
|
|
7609
7609
|
} else {
|
|
7610
|
-
return decodeURIComponent(dataString)
|
|
7610
|
+
return decodeURIComponent(dataString) // URL encoded string -- not currently used or tested
|
|
7611
7611
|
}
|
|
7612
7612
|
}
|
|
7613
7613
|
|
|
@@ -7639,7 +7639,7 @@
|
|
|
7639
7639
|
const IGVMath = {
|
|
7640
7640
|
|
|
7641
7641
|
lerp: (v0, v1, t) => {
|
|
7642
|
-
return (1 - t) * v0 + t * v1
|
|
7642
|
+
return (1 - t) * v0 + t * v1
|
|
7643
7643
|
},
|
|
7644
7644
|
|
|
7645
7645
|
mean: function (array) {
|
|
@@ -7652,7 +7652,7 @@
|
|
|
7652
7652
|
n++;
|
|
7653
7653
|
}
|
|
7654
7654
|
}
|
|
7655
|
-
return n > 0 ? t / n : 0
|
|
7655
|
+
return n > 0 ? t / n : 0
|
|
7656
7656
|
},
|
|
7657
7657
|
|
|
7658
7658
|
meanAndStdev: function (array) {
|
|
@@ -7669,7 +7669,7 @@
|
|
|
7669
7669
|
n++;
|
|
7670
7670
|
}
|
|
7671
7671
|
}
|
|
7672
|
-
return n > 0 ? {mean: t / n, stdev: Math.sqrt(t2 - t * t / n)} : {mean: 0, stdev: 0}
|
|
7672
|
+
return n > 0 ? {mean: t / n, stdev: Math.sqrt(t2 - t * t / n)} : {mean: 0, stdev: 0}
|
|
7673
7673
|
},
|
|
7674
7674
|
|
|
7675
7675
|
median: function (numbers) {
|
|
@@ -7687,33 +7687,33 @@
|
|
|
7687
7687
|
median = numbers[(numsLen - 1) / 2];
|
|
7688
7688
|
}
|
|
7689
7689
|
|
|
7690
|
-
return median
|
|
7690
|
+
return median
|
|
7691
7691
|
},
|
|
7692
7692
|
|
|
7693
7693
|
// Fast percentile function for "p" near edges. This needs profiled for p in middle (e.g. median)
|
|
7694
7694
|
percentile: function (array, p) {
|
|
7695
7695
|
|
|
7696
|
-
if (array.length === 0) return undefined
|
|
7696
|
+
if (array.length === 0) return undefined
|
|
7697
7697
|
|
|
7698
7698
|
var k = Math.floor(array.length * ((100 - p) / 100));
|
|
7699
7699
|
if (k === 0) {
|
|
7700
7700
|
array.sort(function (a, b) {
|
|
7701
7701
|
return b - a
|
|
7702
7702
|
});
|
|
7703
|
-
return array[k]
|
|
7703
|
+
return array[k]
|
|
7704
7704
|
} else {
|
|
7705
|
-
return selectElement(array, k)
|
|
7705
|
+
return selectElement(array, k)
|
|
7706
7706
|
}
|
|
7707
7707
|
|
|
7708
7708
|
},
|
|
7709
7709
|
|
|
7710
7710
|
|
|
7711
7711
|
clamp: function (value, min, max) {
|
|
7712
|
-
return Math.min(Math.max(value, min), max)
|
|
7712
|
+
return Math.min(Math.max(value, min), max)
|
|
7713
7713
|
},
|
|
7714
7714
|
|
|
7715
7715
|
log2: function (x) {
|
|
7716
|
-
return Math.log(x) / Math.LN2
|
|
7716
|
+
return Math.log(x) / Math.LN2
|
|
7717
7717
|
}
|
|
7718
7718
|
|
|
7719
7719
|
};
|
|
@@ -7739,7 +7739,7 @@
|
|
|
7739
7739
|
}
|
|
7740
7740
|
}
|
|
7741
7741
|
|
|
7742
|
-
return heap.content[0]
|
|
7742
|
+
return heap.content[0]
|
|
7743
7743
|
}
|
|
7744
7744
|
|
|
7745
7745
|
|
|
@@ -7766,7 +7766,7 @@
|
|
|
7766
7766
|
this.content[0] = end;
|
|
7767
7767
|
this.sinkDown(0);
|
|
7768
7768
|
}
|
|
7769
|
-
return result
|
|
7769
|
+
return result
|
|
7770
7770
|
},
|
|
7771
7771
|
|
|
7772
7772
|
remove: function (node) {
|
|
@@ -7774,24 +7774,24 @@
|
|
|
7774
7774
|
// To remove a value, we must search through the array to find
|
|
7775
7775
|
// it.
|
|
7776
7776
|
for (var i = 0; i < length; i++) {
|
|
7777
|
-
if (this.content[i] !== node) continue
|
|
7777
|
+
if (this.content[i] !== node) continue
|
|
7778
7778
|
// When it is found, the process seen in 'pop' is repeated
|
|
7779
7779
|
// to fill up the hole.
|
|
7780
7780
|
var end = this.content.pop();
|
|
7781
7781
|
// If the element we popped was the one we needed to remove,
|
|
7782
7782
|
// we're done.
|
|
7783
|
-
if (i === length - 1) break
|
|
7783
|
+
if (i === length - 1) break
|
|
7784
7784
|
// Otherwise, we replace the removed element with the popped
|
|
7785
7785
|
// one, and allow it to float up or sink down as appropriate.
|
|
7786
7786
|
this.content[i] = end;
|
|
7787
7787
|
this.bubbleUp(i);
|
|
7788
7788
|
this.sinkDown(i);
|
|
7789
|
-
break
|
|
7789
|
+
break
|
|
7790
7790
|
}
|
|
7791
7791
|
},
|
|
7792
7792
|
|
|
7793
7793
|
size: function () {
|
|
7794
|
-
return this.content.length
|
|
7794
|
+
return this.content.length
|
|
7795
7795
|
},
|
|
7796
7796
|
|
|
7797
7797
|
bubbleUp: function (n) {
|
|
@@ -7805,7 +7805,7 @@
|
|
|
7805
7805
|
// If the parent has a lesser score, things are in order and we
|
|
7806
7806
|
// are done.
|
|
7807
7807
|
if (score >= parent)
|
|
7808
|
-
break
|
|
7808
|
+
break
|
|
7809
7809
|
|
|
7810
7810
|
// Otherwise, swap the parent with the current element and
|
|
7811
7811
|
// continue.
|
|
@@ -7845,7 +7845,7 @@
|
|
|
7845
7845
|
}
|
|
7846
7846
|
|
|
7847
7847
|
// No need to swap further, we are done.
|
|
7848
|
-
if (swap == null) break
|
|
7848
|
+
if (swap == null) break
|
|
7849
7849
|
|
|
7850
7850
|
// Otherwise, swap and continue.
|
|
7851
7851
|
this.content[n] = this.content[swap];
|
|
@@ -8439,145 +8439,78 @@
|
|
|
8439
8439
|
}
|
|
8440
8440
|
|
|
8441
8441
|
function isGoogleURL(url) {
|
|
8442
|
-
|
|
8443
|
-
|
|
8444
|
-
|
|
8445
|
-
|
|
8446
|
-
|
|
8447
|
-
|
|
8448
|
-
|
|
8449
|
-
|
|
8450
|
-
|
|
8451
|
-
|
|
8452
|
-
|
|
8453
|
-
|
|
8454
|
-
|
|
8455
|
-
|
|
8456
|
-
|
|
8457
|
-
|
|
8458
|
-
|
|
8459
|
-
|
|
8460
|
-
|
|
8461
|
-
|
|
8462
|
-
|
|
8463
|
-
|
|
8464
|
-
|
|
8465
|
-
|
|
8466
|
-
|
|
8467
|
-
|
|
8468
|
-
|
|
8469
|
-
const qIdx = gsUrl.indexOf('?');
|
|
8470
|
-
const paramString = (qIdx > 0) ? gsUrl.substring(qIdx) + "&alt=media" : "?alt=media";
|
|
8471
|
-
|
|
8472
|
-
return `https://storage.googleapis.com/storage/v1/b/${bucket}/o/${object}${paramString}`
|
|
8473
|
-
}
|
|
8474
|
-
|
|
8475
|
-
/**
|
|
8476
|
-
* Parse a google bucket and object name from a google storage URL. Known forms include
|
|
8477
|
-
*
|
|
8478
|
-
* gs://BUCKET_NAME/OBJECT_NAME
|
|
8479
|
-
* https://storage.googleapis.com/BUCKET_NAME/OBJECT_NAME
|
|
8480
|
-
* https://storage.googleapis.com/storage/v1/b/BUCKET_NAME/o/OBJECT_NAME
|
|
8481
|
-
* https://www.googleapis.com/storage/v1/b/BUCKET_NAME/o/OBJECT_NAME"
|
|
8482
|
-
* https://storage.googleapis.com/download/storage/v1/b/BUCKET_NAME/o/OBJECT_NAME
|
|
8483
|
-
*
|
|
8484
|
-
* @param url
|
|
8485
|
-
*/
|
|
8486
|
-
function parseBucketName(url) {
|
|
8487
|
-
|
|
8488
|
-
let bucket;
|
|
8489
|
-
let object;
|
|
8490
|
-
|
|
8491
|
-
if (url.startsWith("gs://")) {
|
|
8492
|
-
const i = url.indexOf('/', 5);
|
|
8493
|
-
if (i >= 0) {
|
|
8494
|
-
bucket = url.substring(5, i);
|
|
8495
|
-
const qIdx = url.indexOf('?');
|
|
8496
|
-
object = (qIdx < 0) ? url.substring(i + 1) : url.substring(i + 1, qIdx);
|
|
8497
|
-
}
|
|
8498
|
-
|
|
8499
|
-
} else if (url.startsWith("https://storage.googleapis.com") || url.startsWith("https://storage.cloud.google.com")) {
|
|
8500
|
-
const bucketIdx = url.indexOf("/v1/b/", 8);
|
|
8501
|
-
if (bucketIdx > 0) {
|
|
8502
|
-
const objIdx = url.indexOf("/o/", bucketIdx);
|
|
8503
|
-
if (objIdx > 0) {
|
|
8504
|
-
const queryIdx = url.indexOf("?", objIdx);
|
|
8505
|
-
bucket = url.substring(bucketIdx + 6, objIdx);
|
|
8506
|
-
object = queryIdx > 0 ? url.substring(objIdx + 3, queryIdx) : url.substring(objIdx + 3);
|
|
8507
|
-
}
|
|
8508
|
-
|
|
8509
|
-
} else {
|
|
8510
|
-
const idx1 = url.indexOf("/", 8);
|
|
8511
|
-
const idx2 = url.indexOf("/", idx1+1);
|
|
8512
|
-
const idx3 = url.indexOf("?", idx2);
|
|
8513
|
-
if (idx2 > 0) {
|
|
8514
|
-
bucket = url.substring(idx1+1, idx2);
|
|
8515
|
-
object = idx3 < 0 ? url.substring(idx2+1) : url.substring(idx2+1, idx3);
|
|
8516
|
-
}
|
|
8517
|
-
}
|
|
8442
|
+
return (url.includes("googleapis") && !url.includes("urlshortener")) ||
|
|
8443
|
+
isGoogleStorageURL(url) ||
|
|
8444
|
+
isGoogleDriveURL(url);
|
|
8445
|
+
}
|
|
8446
|
+
|
|
8447
|
+
function isGoogleStorageURL(url) {
|
|
8448
|
+
return url.startsWith("gs://") ||
|
|
8449
|
+
url.startsWith("https://www.googleapis.com/storage") ||
|
|
8450
|
+
url.startsWith("https://storage.cloud.google.com") ||
|
|
8451
|
+
url.startsWith("https://storage.googleapis.com");
|
|
8452
|
+
}
|
|
8453
|
+
|
|
8454
|
+
function isGoogleDriveURL(url) {
|
|
8455
|
+
return url.startsWith("https://www.googleapis.com/drive/v3/files");
|
|
8456
|
+
}
|
|
8457
|
+
|
|
8458
|
+
/**
|
|
8459
|
+
* Translate gs:// urls to https
|
|
8460
|
+
* See https://cloud.google.com/storage/docs/json_api/v1
|
|
8461
|
+
* @param gsUrl
|
|
8462
|
+
* @returns {string|*}
|
|
8463
|
+
*/
|
|
8464
|
+
function translateGoogleCloudURL(gsUrl) {
|
|
8465
|
+
try {
|
|
8466
|
+
let {bucket, object} = parseBucketName(gsUrl);
|
|
8467
|
+
object = encode(object);
|
|
8518
8468
|
|
|
8519
|
-
|
|
8520
|
-
|
|
8521
|
-
const objIdx = url.indexOf("/o/", bucketIdx);
|
|
8522
|
-
if (objIdx > 0) {
|
|
8523
|
-
const queryIdx = url.indexOf("?", objIdx);
|
|
8524
|
-
bucket = url.substring(bucketIdx + 6, objIdx);
|
|
8525
|
-
object = queryIdx > 0 ? url.substring(objIdx + 3, queryIdx) : url.substring(objIdx + 3);
|
|
8526
|
-
}
|
|
8527
|
-
}
|
|
8469
|
+
const qIdx = gsUrl.indexOf('?');
|
|
8470
|
+
let paramString = (qIdx > 0) ? gsUrl.substring(qIdx) : "";
|
|
8528
8471
|
|
|
8529
|
-
|
|
8530
|
-
|
|
8531
|
-
|
|
8532
|
-
}
|
|
8533
|
-
} else {
|
|
8534
|
-
throw Error(`Unrecognized Google Storage URI: ${url}`)
|
|
8535
|
-
}
|
|
8472
|
+
if (!paramString.includes("alt=media")) {
|
|
8473
|
+
paramString = paramString ? `${paramString}&alt=media` : "?alt=media";
|
|
8474
|
+
}
|
|
8536
8475
|
|
|
8537
|
-
|
|
8538
|
-
|
|
8539
|
-
|
|
8540
|
-
|
|
8541
|
-
|
|
8542
|
-
* !, #, $, &, ', (, ), *, +, ,, /, :, ;, =, ?, @, [, ], and space characters.
|
|
8543
|
-
* @param obj
|
|
8544
|
-
*/
|
|
8476
|
+
return `https://storage.googleapis.com/storage/v1/b/${bucket}/o/${object}${paramString}`;
|
|
8477
|
+
} catch (error) {
|
|
8478
|
+
throw new Error(`Failed to translate Google Cloud URL: ${error.message}`);
|
|
8479
|
+
}
|
|
8480
|
+
}
|
|
8545
8481
|
|
|
8546
|
-
|
|
8482
|
+
/**
|
|
8483
|
+
* Parse a google bucket and object name from a google storage URL.
|
|
8484
|
+
* @param url
|
|
8485
|
+
*/
|
|
8486
|
+
function parseBucketName(url) {
|
|
8487
|
+
const regex = /gs:\/\/([a-zA-Z0-9._-]+)\/([^?]+)|https?:\/\/(?:storage\.googleapis\.com|storage\.cloud\.google\.com|www\.googleapis\.com)\/(?:storage\/v1\/b\/)?([a-zA-Z0-9._-]+)\/(?:o\/)?([^?]+)/;
|
|
8488
|
+
const match = url.match(regex);
|
|
8489
|
+
|
|
8490
|
+
if (match) {
|
|
8491
|
+
const bucket = match[1] || match[3];
|
|
8492
|
+
const object = match[2] || match[4];
|
|
8493
|
+
if (bucket && object) {
|
|
8494
|
+
return { bucket, object };
|
|
8495
|
+
}
|
|
8496
|
+
}
|
|
8497
|
+
throw new Error(`Unrecognized Google Storage URI: ${url}`);
|
|
8498
|
+
}
|
|
8547
8499
|
|
|
8548
|
-
|
|
8549
|
-
|
|
8550
|
-
|
|
8551
|
-
|
|
8552
|
-
|
|
8553
|
-
|
|
8554
|
-
|
|
8555
|
-
});
|
|
8556
|
-
return result;
|
|
8557
|
-
}
|
|
8500
|
+
/**
|
|
8501
|
+
* Percent a GCS object name. See https://cloud.google.com/storage/docs/request-endpoints
|
|
8502
|
+
* @param objectName
|
|
8503
|
+
*/
|
|
8504
|
+
function encode(objectName) {
|
|
8505
|
+
return objectName.split('').map(letter => encodings$1.get(letter) || letter).join('');
|
|
8506
|
+
}
|
|
8558
8507
|
|
|
8559
|
-
|
|
8560
|
-
|
|
8561
|
-
|
|
8562
|
-
|
|
8563
|
-
|
|
8564
|
-
|
|
8565
|
-
encodings$1.set("&", "%26");
|
|
8566
|
-
encodings$1.set("'", "%27");
|
|
8567
|
-
encodings$1.set("(", "%28");
|
|
8568
|
-
encodings$1.set(")", "%29");
|
|
8569
|
-
encodings$1.set("*", "%2A");
|
|
8570
|
-
encodings$1.set("+", "%2B");
|
|
8571
|
-
encodings$1.set(",", "%2C");
|
|
8572
|
-
encodings$1.set("/", "%2F");
|
|
8573
|
-
encodings$1.set(":", "%3A");
|
|
8574
|
-
encodings$1.set(";", "%3B");
|
|
8575
|
-
encodings$1.set("=", "%3D");
|
|
8576
|
-
encodings$1.set("?", "%3F");
|
|
8577
|
-
encodings$1.set("@", "%40");
|
|
8578
|
-
encodings$1.set("[", "%5B");
|
|
8579
|
-
encodings$1.set("]", "%5D");
|
|
8580
|
-
encodings$1.set(" ", "%20");
|
|
8508
|
+
const encodings$1 = new Map([
|
|
8509
|
+
["!", "%21"], ["#", "%23"], ["$", "%24"], ["%", "%25"], ["&", "%26"],
|
|
8510
|
+
["'", "%27"], ["(", "%28"], [")", "%29"], ["*", "%2A"], ["+", "%2B"],
|
|
8511
|
+
[",", "%2C"], ["/", "%2F"], [":", "%3A"], [";", "%3B"], ["=", "%3D"],
|
|
8512
|
+
["?", "%3F"], ["@", "%40"], ["[", "%5B"], ["]", "%5D"], [" ", "%20"]
|
|
8513
|
+
]);
|
|
8581
8514
|
|
|
8582
8515
|
// Convenience functions for the gapi oAuth library.
|
|
8583
8516
|
|
|
@@ -8608,7 +8541,8 @@
|
|
|
8608
8541
|
// Attach an object to keep igv state
|
|
8609
8542
|
google.igv = {
|
|
8610
8543
|
tokenClient: tokenClient,
|
|
8611
|
-
apiKey: config.apiKey
|
|
8544
|
+
apiKey: config.apiKey,
|
|
8545
|
+
appId: config.appId
|
|
8612
8546
|
};
|
|
8613
8547
|
}
|
|
8614
8548
|
|
|
@@ -8628,8 +8562,6 @@
|
|
|
8628
8562
|
undefined
|
|
8629
8563
|
}
|
|
8630
8564
|
|
|
8631
|
-
|
|
8632
|
-
let promise;
|
|
8633
8565
|
/**
|
|
8634
8566
|
* Return a promise for an access token for the given scope. If the user hasn't authorized the scope request it
|
|
8635
8567
|
*
|
|
@@ -8648,27 +8580,21 @@
|
|
|
8648
8580
|
return google.igv.tokenResponse.access_token
|
|
8649
8581
|
} else {
|
|
8650
8582
|
const tokenClient = google.igv.tokenClient;
|
|
8651
|
-
|
|
8652
|
-
|
|
8653
|
-
|
|
8654
|
-
|
|
8655
|
-
|
|
8656
|
-
|
|
8657
|
-
|
|
8658
|
-
|
|
8659
|
-
|
|
8660
|
-
|
|
8661
|
-
|
|
8662
|
-
|
|
8663
|
-
|
|
8664
|
-
|
|
8665
|
-
|
|
8666
|
-
} catch (err) {
|
|
8667
|
-
console.log(err);
|
|
8668
|
-
}
|
|
8669
|
-
});
|
|
8670
|
-
}
|
|
8671
|
-
return promise
|
|
8583
|
+
return new Promise((resolve, reject) => {
|
|
8584
|
+
tokenClient.callback = (tokenResponse) => {
|
|
8585
|
+
if (tokenResponse.error !== undefined) {
|
|
8586
|
+
return reject(tokenResponse)
|
|
8587
|
+
}
|
|
8588
|
+
google.igv.tokenResponse = tokenResponse;
|
|
8589
|
+
google.igv.tokenExpiresAt = Date.now() + tokenResponse.expires_in * 1000;
|
|
8590
|
+
resolve(tokenResponse.access_token);
|
|
8591
|
+
};
|
|
8592
|
+
try {
|
|
8593
|
+
tokenClient.requestAccessToken({scope});
|
|
8594
|
+
} catch (err) {
|
|
8595
|
+
reject(err);
|
|
8596
|
+
}
|
|
8597
|
+
})
|
|
8672
8598
|
}
|
|
8673
8599
|
}
|
|
8674
8600
|
|
|
@@ -8687,90 +8613,6 @@
|
|
|
8687
8613
|
}
|
|
8688
8614
|
}
|
|
8689
8615
|
|
|
8690
|
-
function getApiKey() {
|
|
8691
|
-
return google.igv.apiKey
|
|
8692
|
-
}
|
|
8693
|
-
|
|
8694
|
-
/**
|
|
8695
|
-
* Return information about a specific google drive URL
|
|
8696
|
-
*
|
|
8697
|
-
* @param googleDriveURL
|
|
8698
|
-
* @returns {Promise<any>}
|
|
8699
|
-
*/
|
|
8700
|
-
async function getDriveFileInfo(googleDriveURL) {
|
|
8701
|
-
|
|
8702
|
-
const id = getGoogleDriveFileID(googleDriveURL);
|
|
8703
|
-
let endPoint = "https://www.googleapis.com/drive/v3/files/" + id + "?supportsTeamDrives=true";
|
|
8704
|
-
const apiKey = getApiKey();
|
|
8705
|
-
if (apiKey) {
|
|
8706
|
-
endPoint += "&key=" + apiKey;
|
|
8707
|
-
}
|
|
8708
|
-
const response = await fetch(endPoint);
|
|
8709
|
-
let json = await response.json();
|
|
8710
|
-
if (json.error && json.error.code === 404) {
|
|
8711
|
-
let scope = "https://www.googleapis.com/auth/drive.file";
|
|
8712
|
-
const access_token = await getAccessToken(scope);
|
|
8713
|
-
if (access_token) {
|
|
8714
|
-
const response = await fetch(endPoint, {
|
|
8715
|
-
headers: {
|
|
8716
|
-
'Authorization': `Bearer ${access_token}`
|
|
8717
|
-
}
|
|
8718
|
-
});
|
|
8719
|
-
json = await response.json();
|
|
8720
|
-
if (json.error) {
|
|
8721
|
-
throw Error(json.error);
|
|
8722
|
-
}
|
|
8723
|
-
} else {
|
|
8724
|
-
throw Error(json.error);
|
|
8725
|
-
}
|
|
8726
|
-
}
|
|
8727
|
-
return json;
|
|
8728
|
-
}
|
|
8729
|
-
|
|
8730
|
-
|
|
8731
|
-
function getDriveDownloadURL(link) {
|
|
8732
|
-
// Return a google drive download url for the sharable link
|
|
8733
|
-
//https://drive.google.com/open?id=0B-lleX9c2pZFbDJ4VVRxakJzVGM
|
|
8734
|
-
//https://drive.google.com/file/d/1_FC4kCeO8E3V4dJ1yIW7A0sn1yURKIX-/view?usp=sharing
|
|
8735
|
-
var id = getGoogleDriveFileID(link);
|
|
8736
|
-
return id ? "https://www.googleapis.com/drive/v3/files/" + id + "?alt=media&supportsTeamDrives=true" : link;
|
|
8737
|
-
}
|
|
8738
|
-
|
|
8739
|
-
function getGoogleDriveFileID(link) {
|
|
8740
|
-
|
|
8741
|
-
//https://drive.google.com/file/d/1_FC4kCeO8E3V4dJ1yIW7A0sn1yURKIX-/view?usp=sharing
|
|
8742
|
-
//https://www.googleapis.com/drive/v3/files/1w-tvo6p1SH4p1OaQSVxpkV_EJgGIstWF?alt=media&supportsTeamDrives=true"
|
|
8743
|
-
|
|
8744
|
-
if (link.includes("/open?id=")) {
|
|
8745
|
-
const i1 = link.indexOf("/open?id=") + 9;
|
|
8746
|
-
const i2 = link.indexOf("&");
|
|
8747
|
-
if (i1 > 0 && i2 > i1) {
|
|
8748
|
-
return link.substring(i1, i2)
|
|
8749
|
-
} else if (i1 > 0) {
|
|
8750
|
-
return link.substring(i1);
|
|
8751
|
-
}
|
|
8752
|
-
|
|
8753
|
-
} else if (link.includes("/file/d/")) {
|
|
8754
|
-
const i1 = link.indexOf("/file/d/") + 8;
|
|
8755
|
-
const i2 = link.lastIndexOf("/");
|
|
8756
|
-
return link.substring(i1, i2);
|
|
8757
|
-
|
|
8758
|
-
} else if (link.startsWith("https://www.googleapis.com/drive")) {
|
|
8759
|
-
let i1 = link.indexOf("/files/");
|
|
8760
|
-
const i2 = link.indexOf("?");
|
|
8761
|
-
if (i1 > 0) {
|
|
8762
|
-
i1 += 7;
|
|
8763
|
-
return i2 > 0 ?
|
|
8764
|
-
link.substring(i1, i2) :
|
|
8765
|
-
link.substring(i1)
|
|
8766
|
-
}
|
|
8767
|
-
}
|
|
8768
|
-
|
|
8769
|
-
throw Error("Unknown Google Drive url format: " + link);
|
|
8770
|
-
|
|
8771
|
-
|
|
8772
|
-
}
|
|
8773
|
-
|
|
8774
8616
|
// The MIT License (MIT)
|
|
8775
8617
|
|
|
8776
8618
|
/**
|
|
@@ -8802,7 +8644,7 @@
|
|
|
8802
8644
|
asyncFunction: asyncFunction,
|
|
8803
8645
|
});
|
|
8804
8646
|
self.dequeue();
|
|
8805
|
-
})
|
|
8647
|
+
})
|
|
8806
8648
|
}
|
|
8807
8649
|
|
|
8808
8650
|
/**
|
|
@@ -8815,10 +8657,10 @@
|
|
|
8815
8657
|
*/
|
|
8816
8658
|
addAll(promises, options) {
|
|
8817
8659
|
var addedPromises = promises.map(function (promise) {
|
|
8818
|
-
return this.add(promise, options)
|
|
8660
|
+
return this.add(promise, options)
|
|
8819
8661
|
}.bind(this));
|
|
8820
8662
|
|
|
8821
|
-
return Promise.all(addedPromises)
|
|
8663
|
+
return Promise.all(addedPromises)
|
|
8822
8664
|
};
|
|
8823
8665
|
|
|
8824
8666
|
/**
|
|
@@ -8981,9 +8823,6 @@
|
|
|
8981
8823
|
return buffer
|
|
8982
8824
|
}
|
|
8983
8825
|
} else {
|
|
8984
|
-
if (url.startsWith("https://drive.google.com")) {
|
|
8985
|
-
url = getDriveDownloadURL(url);
|
|
8986
|
-
}
|
|
8987
8826
|
if (isGoogleDriveURL(url) || url.startsWith("https://www.dropbox.com")) {
|
|
8988
8827
|
return this.googleThrottle.add(async () => {
|
|
8989
8828
|
return this._loadURL(url, options)
|
|
@@ -9007,9 +8846,15 @@
|
|
|
9007
8846
|
|
|
9008
8847
|
options = options || {};
|
|
9009
8848
|
|
|
9010
|
-
let oauthToken
|
|
9011
|
-
if (
|
|
9012
|
-
|
|
8849
|
+
let oauthToken;
|
|
8850
|
+
if (isGoogleDriveURL(url)) {
|
|
8851
|
+
// Google drive urls always require oAuth
|
|
8852
|
+
oauthToken = await getAccessToken("https://www.googleapis.com/auth/drive.file");
|
|
8853
|
+
} else {
|
|
8854
|
+
oauthToken = options.oauthToken || this.getOauthToken(url);
|
|
8855
|
+
if (oauthToken) {
|
|
8856
|
+
oauthToken = await (typeof oauthToken === 'function' ? oauthToken() : oauthToken);
|
|
8857
|
+
}
|
|
9013
8858
|
}
|
|
9014
8859
|
|
|
9015
8860
|
return new Promise(function (resolve, reject) {
|
|
@@ -9370,8 +9215,10 @@
|
|
|
9370
9215
|
}
|
|
9371
9216
|
|
|
9372
9217
|
function addTeamDrive(url) {
|
|
9373
|
-
if (url.includes("
|
|
9218
|
+
if (url.includes("supportsAllDrives")) {
|
|
9374
9219
|
return url
|
|
9220
|
+
} else if (url.includes("supportsTeamDrives")) {
|
|
9221
|
+
return url.replaceAll("supportsTeamDrives", "supportsAllDrives")
|
|
9375
9222
|
} else {
|
|
9376
9223
|
const paramSeparator = url.includes("?") ? "&" : "?";
|
|
9377
9224
|
url = url + paramSeparator + "supportsTeamDrive=true";
|
|
@@ -9386,8 +9233,6 @@
|
|
|
9386
9233
|
|
|
9387
9234
|
if (url.startsWith("https://www.dropbox.com")) {
|
|
9388
9235
|
return url.replace("//www.dropbox.com", "//dl.dropboxusercontent.com")
|
|
9389
|
-
} else if (url.startsWith("https://drive.google.com")) {
|
|
9390
|
-
return getDriveDownloadURL(url)
|
|
9391
9236
|
} else if (url.includes("//www.broadinstitute.org/igvdata")) {
|
|
9392
9237
|
return url.replace("//www.broadinstitute.org/igvdata", "//data.broadinstitute.org/igvdata")
|
|
9393
9238
|
} else if (url.includes("//igvdata.broadinstitute.org")) {
|
|
@@ -9583,17 +9428,17 @@
|
|
|
9583
9428
|
|
|
9584
9429
|
var searchInterval = new Interval$1(start, end, 0);
|
|
9585
9430
|
|
|
9586
|
-
if (this.root === NIL$1) return []
|
|
9431
|
+
if (this.root === NIL$1) return []
|
|
9587
9432
|
|
|
9588
9433
|
var intervals = searchAll$1.call(this, searchInterval, this.root, []);
|
|
9589
9434
|
|
|
9590
9435
|
if (intervals.length > 1) {
|
|
9591
9436
|
intervals.sort(function (i1, i2) {
|
|
9592
|
-
return i1.low - i2.low
|
|
9437
|
+
return i1.low - i2.low
|
|
9593
9438
|
});
|
|
9594
9439
|
}
|
|
9595
9440
|
|
|
9596
|
-
return intervals
|
|
9441
|
+
return intervals
|
|
9597
9442
|
}
|
|
9598
9443
|
|
|
9599
9444
|
/**
|
|
@@ -9678,7 +9523,7 @@
|
|
|
9678
9523
|
searchAll$1.call(this, interval, node.right, results);
|
|
9679
9524
|
}
|
|
9680
9525
|
|
|
9681
|
-
return results
|
|
9526
|
+
return results
|
|
9682
9527
|
}
|
|
9683
9528
|
|
|
9684
9529
|
function leftRotate$1(x) {
|
|
@@ -9757,35 +9602,35 @@
|
|
|
9757
9602
|
|
|
9758
9603
|
equals(other) {
|
|
9759
9604
|
if (!other) {
|
|
9760
|
-
return false
|
|
9605
|
+
return false
|
|
9761
9606
|
}
|
|
9762
9607
|
if (this === other) {
|
|
9763
|
-
return true
|
|
9608
|
+
return true
|
|
9764
9609
|
}
|
|
9765
9610
|
return (this.low === other.low &&
|
|
9766
|
-
this.high === other.high)
|
|
9611
|
+
this.high === other.high)
|
|
9767
9612
|
|
|
9768
9613
|
}
|
|
9769
9614
|
|
|
9770
9615
|
compareTo(other) {
|
|
9771
9616
|
if (this.low < other.low)
|
|
9772
|
-
return -1
|
|
9617
|
+
return -1
|
|
9773
9618
|
if (this.low > other.low)
|
|
9774
|
-
return 1
|
|
9619
|
+
return 1
|
|
9775
9620
|
|
|
9776
9621
|
if (this.high < other.high)
|
|
9777
|
-
return -1
|
|
9622
|
+
return -1
|
|
9778
9623
|
if (this.high > other.high)
|
|
9779
|
-
return 1
|
|
9624
|
+
return 1
|
|
9780
9625
|
|
|
9781
|
-
return 0
|
|
9626
|
+
return 0
|
|
9782
9627
|
}
|
|
9783
9628
|
|
|
9784
9629
|
/**
|
|
9785
9630
|
* Returns true if this interval overlaps the other.
|
|
9786
9631
|
*/
|
|
9787
9632
|
overlaps(other) {
|
|
9788
|
-
|
|
9633
|
+
return (this.low <= other.high && other.low <= this.high)
|
|
9789
9634
|
}
|
|
9790
9635
|
}
|
|
9791
9636
|
|
|
@@ -9830,19 +9675,19 @@
|
|
|
9830
9675
|
var start;
|
|
9831
9676
|
var end;
|
|
9832
9677
|
|
|
9833
|
-
if (!features) return
|
|
9678
|
+
if (!features) return
|
|
9834
9679
|
|
|
9835
9680
|
maxRows = maxRows || 10000;
|
|
9836
9681
|
|
|
9837
9682
|
if (!sorted) {
|
|
9838
9683
|
features.sort(function (a, b) {
|
|
9839
|
-
return a.start - b.start
|
|
9684
|
+
return a.start - b.start
|
|
9840
9685
|
});
|
|
9841
9686
|
}
|
|
9842
9687
|
|
|
9843
9688
|
|
|
9844
9689
|
if (features.length === 0) {
|
|
9845
|
-
return []
|
|
9690
|
+
return []
|
|
9846
9691
|
|
|
9847
9692
|
} else {
|
|
9848
9693
|
|
|
@@ -9895,7 +9740,7 @@
|
|
|
9895
9740
|
} // while (bucket)
|
|
9896
9741
|
|
|
9897
9742
|
if (!bucket) {
|
|
9898
|
-
break
|
|
9743
|
+
break
|
|
9899
9744
|
}
|
|
9900
9745
|
feature = bucket.pop();
|
|
9901
9746
|
if (0 === bucket.length) {
|
|
@@ -9912,7 +9757,7 @@
|
|
|
9912
9757
|
row++;
|
|
9913
9758
|
nextStart = bucketStart;
|
|
9914
9759
|
|
|
9915
|
-
if (allocatedCount === lastAllocatedCount) break
|
|
9760
|
+
if (allocatedCount === lastAllocatedCount) break // Protect from infinite loops
|
|
9916
9761
|
|
|
9917
9762
|
lastAllocatedCount = allocatedCount;
|
|
9918
9763
|
|
|
@@ -9934,13 +9779,13 @@
|
|
|
9934
9779
|
findOverlapping: function (featureList, start, end) {
|
|
9935
9780
|
|
|
9936
9781
|
if (!featureList || featureList.length === 0) {
|
|
9937
|
-
return []
|
|
9782
|
+
return []
|
|
9938
9783
|
} else {
|
|
9939
9784
|
const tree = buildIntervalTree$1(featureList);
|
|
9940
9785
|
const intervals = tree.findOverlapping(start, end);
|
|
9941
9786
|
|
|
9942
9787
|
if (intervals.length === 0) {
|
|
9943
|
-
return []
|
|
9788
|
+
return []
|
|
9944
9789
|
} else {
|
|
9945
9790
|
// Trim the list of features in the intervals to those
|
|
9946
9791
|
// overlapping the requested range.
|
|
@@ -9953,7 +9798,7 @@
|
|
|
9953
9798
|
const len = intervalFeatures.length;
|
|
9954
9799
|
for (let i = 0; i < len; i++) {
|
|
9955
9800
|
const feature = intervalFeatures[i];
|
|
9956
|
-
if (feature.start > end) break
|
|
9801
|
+
if (feature.start > end) break
|
|
9957
9802
|
else if (feature.end > start) {
|
|
9958
9803
|
featureList.push(feature);
|
|
9959
9804
|
}
|
|
@@ -9961,10 +9806,10 @@
|
|
|
9961
9806
|
});
|
|
9962
9807
|
|
|
9963
9808
|
featureList.sort(function (a, b) {
|
|
9964
|
-
return a.start - b.start
|
|
9809
|
+
return a.start - b.start
|
|
9965
9810
|
});
|
|
9966
9811
|
|
|
9967
|
-
return featureList
|
|
9812
|
+
return featureList
|
|
9968
9813
|
}
|
|
9969
9814
|
}
|
|
9970
9815
|
|
|
@@ -9985,7 +9830,7 @@
|
|
|
9985
9830
|
const chunkSize = Math.max(10, Math.round(len / 100));
|
|
9986
9831
|
|
|
9987
9832
|
featureList.sort(function (f1, f2) {
|
|
9988
|
-
return (f1.start === f2.start ? 0 : (f1.start > f2.start ? 1 : -1))
|
|
9833
|
+
return (f1.start === f2.start ? 0 : (f1.start > f2.start ? 1 : -1))
|
|
9989
9834
|
});
|
|
9990
9835
|
|
|
9991
9836
|
for (let i = 0; i < len; i += chunkSize) {
|
|
@@ -9999,7 +9844,7 @@
|
|
|
9999
9844
|
tree.insert(iStart, iEnd, subArray);
|
|
10000
9845
|
}
|
|
10001
9846
|
|
|
10002
|
-
return tree
|
|
9847
|
+
return tree
|
|
10003
9848
|
}
|
|
10004
9849
|
|
|
10005
9850
|
function hexToRGB(hex) {
|
|
@@ -10450,7 +10295,7 @@
|
|
|
10450
10295
|
min = Number.MAX_VALUE;
|
|
10451
10296
|
max = -Number.MAX_VALUE;
|
|
10452
10297
|
|
|
10453
|
-
for(let f of features) {
|
|
10298
|
+
for (let f of features) {
|
|
10454
10299
|
if (!Number.isNaN(f.value)) {
|
|
10455
10300
|
min = Math.min(min, f.value);
|
|
10456
10301
|
max = Math.max(max, f.value);
|
|
@@ -10524,19 +10369,6 @@
|
|
|
10524
10369
|
return false
|
|
10525
10370
|
};
|
|
10526
10371
|
|
|
10527
|
-
async function getFilename$1(url) {
|
|
10528
|
-
if (isString$3(url) && url.startsWith("https://drive.google.com")) {
|
|
10529
|
-
// This will fail if Google API key is not defined
|
|
10530
|
-
if (getApiKey() === undefined) {
|
|
10531
|
-
throw Error("Google drive is referenced, but API key is not defined. An API key is required for Google Drive access")
|
|
10532
|
-
}
|
|
10533
|
-
const json = await getDriveFileInfo(url);
|
|
10534
|
-
return json.originalFileName || json.name
|
|
10535
|
-
} else {
|
|
10536
|
-
return getFilename$2(url)
|
|
10537
|
-
}
|
|
10538
|
-
}
|
|
10539
|
-
|
|
10540
10372
|
function prettyBasePairNumber(raw) {
|
|
10541
10373
|
|
|
10542
10374
|
var denom,
|
|
@@ -10599,12 +10431,12 @@
|
|
|
10599
10431
|
const marginTop = parseInt(style.marginTop);
|
|
10600
10432
|
const marginBottom = parseInt(style.marginBottom);
|
|
10601
10433
|
|
|
10602
|
-
const {
|
|
10434
|
+
const {top, bottom, height} = element.getBoundingClientRect();
|
|
10603
10435
|
return {
|
|
10604
10436
|
top: Math.floor(top) - marginTop,
|
|
10605
10437
|
bottom: Math.floor(bottom) + marginBottom,
|
|
10606
10438
|
height: Math.floor(height) + marginTop + marginBottom
|
|
10607
|
-
}
|
|
10439
|
+
}
|
|
10608
10440
|
}
|
|
10609
10441
|
|
|
10610
10442
|
class Popover {
|
|
@@ -10794,7 +10626,7 @@
|
|
|
10794
10626
|
return list;
|
|
10795
10627
|
}
|
|
10796
10628
|
|
|
10797
|
-
/*! @license DOMPurify 3.
|
|
10629
|
+
/*! @license DOMPurify 3.3.0 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.3.0/LICENSE */
|
|
10798
10630
|
|
|
10799
10631
|
const {
|
|
10800
10632
|
entries,
|
|
@@ -10980,7 +10812,7 @@
|
|
|
10980
10812
|
}
|
|
10981
10813
|
|
|
10982
10814
|
const html$1 = freeze(['a', 'abbr', 'acronym', 'address', 'area', 'article', 'aside', 'audio', 'b', 'bdi', 'bdo', 'big', 'blink', 'blockquote', 'body', 'br', 'button', 'canvas', 'caption', 'center', 'cite', 'code', 'col', 'colgroup', 'content', 'data', 'datalist', 'dd', 'decorator', 'del', 'details', 'dfn', 'dialog', 'dir', 'div', 'dl', 'dt', 'element', 'em', 'fieldset', 'figcaption', 'figure', 'font', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'i', 'img', 'input', 'ins', 'kbd', 'label', 'legend', 'li', 'main', 'map', 'mark', 'marquee', 'menu', 'menuitem', 'meter', 'nav', 'nobr', 'ol', 'optgroup', 'option', 'output', 'p', 'picture', 'pre', 'progress', 'q', 'rp', 'rt', 'ruby', 's', 'samp', 'search', 'section', 'select', 'shadow', 'slot', 'small', 'source', 'spacer', 'span', 'strike', 'strong', 'style', 'sub', 'summary', 'sup', 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot', 'th', 'thead', 'time', 'tr', 'track', 'tt', 'u', 'ul', 'var', 'video', 'wbr']);
|
|
10983
|
-
const svg$1 = freeze(['svg', 'a', 'altglyph', 'altglyphdef', 'altglyphitem', 'animatecolor', 'animatemotion', 'animatetransform', 'circle', 'clippath', 'defs', 'desc', 'ellipse', 'enterkeyhint', 'exportparts', 'filter', 'font', 'g', 'glyph', 'glyphref', 'hkern', 'image', 'inputmode', 'line', 'lineargradient', 'marker', 'mask', 'metadata', 'mpath', 'part', 'path', 'pattern', 'polygon', 'polyline', 'radialgradient', 'rect', '
|
|
10815
|
+
const svg$1 = freeze(['svg', 'a', 'altglyph', 'altglyphdef', 'altglyphitem', 'animatecolor', 'animatemotion', 'animatetransform', 'circle', 'clippath', 'defs', 'desc', 'ellipse', 'enterkeyhint', 'exportparts', 'filter', 'font', 'g', 'glyph', 'glyphref', 'hkern', 'image', 'inputmode', 'line', 'lineargradient', 'marker', 'mask', 'metadata', 'mpath', 'part', 'path', 'pattern', 'polygon', 'polyline', 'radialgradient', 'rect', 'stop', 'style', 'switch', 'symbol', 'text', 'textpath', 'title', 'tref', 'tspan', 'view', 'vkern']);
|
|
10984
10816
|
const svgFilters = freeze(['feBlend', 'feColorMatrix', 'feComponentTransfer', 'feComposite', 'feConvolveMatrix', 'feDiffuseLighting', 'feDisplacementMap', 'feDistantLight', 'feDropShadow', 'feFlood', 'feFuncA', 'feFuncB', 'feFuncG', 'feFuncR', 'feGaussianBlur', 'feImage', 'feMerge', 'feMergeNode', 'feMorphology', 'feOffset', 'fePointLight', 'feSpecularLighting', 'feSpotLight', 'feTile', 'feTurbulence']);
|
|
10985
10817
|
// List of SVG elements that are disallowed by default.
|
|
10986
10818
|
// We still need to know them so that we can do namespace
|
|
@@ -10994,7 +10826,7 @@
|
|
|
10994
10826
|
const text = freeze(['#text']);
|
|
10995
10827
|
|
|
10996
10828
|
const html = freeze(['accept', 'action', 'align', 'alt', 'autocapitalize', 'autocomplete', 'autopictureinpicture', 'autoplay', 'background', 'bgcolor', 'border', 'capture', 'cellpadding', 'cellspacing', 'checked', 'cite', 'class', 'clear', 'color', 'cols', 'colspan', 'controls', 'controlslist', 'coords', 'crossorigin', 'datetime', 'decoding', 'default', 'dir', 'disabled', 'disablepictureinpicture', 'disableremoteplayback', 'download', 'draggable', 'enctype', 'enterkeyhint', 'exportparts', 'face', 'for', 'headers', 'height', 'hidden', 'high', 'href', 'hreflang', 'id', 'inert', 'inputmode', 'integrity', 'ismap', 'kind', 'label', 'lang', 'list', 'loading', 'loop', 'low', 'max', 'maxlength', 'media', 'method', 'min', 'minlength', 'multiple', 'muted', 'name', 'nonce', 'noshade', 'novalidate', 'nowrap', 'open', 'optimum', 'part', 'pattern', 'placeholder', 'playsinline', 'popover', 'popovertarget', 'popovertargetaction', 'poster', 'preload', 'pubdate', 'radiogroup', 'readonly', 'rel', 'required', 'rev', 'reversed', 'role', 'rows', 'rowspan', 'spellcheck', 'scope', 'selected', 'shape', 'size', 'sizes', 'slot', 'span', 'srclang', 'start', 'src', 'srcset', 'step', 'style', 'summary', 'tabindex', 'title', 'translate', 'type', 'usemap', 'valign', 'value', 'width', 'wrap', 'xmlns', 'slot']);
|
|
10997
|
-
const svg = freeze(['accent-height', 'accumulate', 'additive', 'alignment-baseline', 'amplitude', 'ascent', 'attributename', 'attributetype', 'azimuth', 'basefrequency', 'baseline-shift', 'begin', 'bias', 'by', 'class', 'clip', 'clippathunits', 'clip-path', 'clip-rule', 'color', 'color-interpolation', 'color-interpolation-filters', 'color-profile', 'color-rendering', 'cx', 'cy', 'd', 'dx', 'dy', 'diffuseconstant', 'direction', 'display', 'divisor', 'dur', 'edgemode', 'elevation', 'end', 'exponent', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'filterunits', 'flood-color', 'flood-opacity', 'font-family', 'font-size', 'font-size-adjust', 'font-stretch', 'font-style', 'font-variant', 'font-weight', 'fx', 'fy', 'g1', 'g2', 'glyph-name', 'glyphref', 'gradientunits', 'gradienttransform', 'height', 'href', 'id', 'image-rendering', 'in', 'in2', 'intercept', 'k', 'k1', 'k2', 'k3', 'k4', 'kerning', 'keypoints', 'keysplines', 'keytimes', 'lang', 'lengthadjust', 'letter-spacing', 'kernelmatrix', 'kernelunitlength', 'lighting-color', 'local', 'marker-end', 'marker-mid', 'marker-start', 'markerheight', 'markerunits', 'markerwidth', 'maskcontentunits', 'maskunits', 'max', 'mask', 'media', 'method', 'mode', 'min', 'name', 'numoctaves', 'offset', 'operator', 'opacity', 'order', 'orient', 'orientation', 'origin', 'overflow', 'paint-order', 'path', 'pathlength', 'patterncontentunits', 'patterntransform', 'patternunits', 'points', 'preservealpha', 'preserveaspectratio', 'primitiveunits', 'r', 'rx', 'ry', 'radius', 'refx', 'refy', 'repeatcount', 'repeatdur', 'restart', 'result', 'rotate', 'scale', 'seed', 'shape-rendering', 'slope', 'specularconstant', 'specularexponent', 'spreadmethod', 'startoffset', 'stddeviation', 'stitchtiles', 'stop-color', 'stop-opacity', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke', 'stroke-width', 'style', 'surfacescale', 'systemlanguage', 'tabindex', 'tablevalues', 'targetx', 'targety', 'transform', 'transform-origin', 'text-anchor', 'text-decoration', 'text-rendering', 'textlength', 'type', 'u1', 'u2', 'unicode', 'values', 'viewbox', 'visibility', 'version', 'vert-adv-y', 'vert-origin-x', 'vert-origin-y', 'width', 'word-spacing', 'wrap', 'writing-mode', 'xchannelselector', 'ychannelselector', 'x', 'x1', 'x2', 'xmlns', 'y', 'y1', 'y2', 'z', 'zoomandpan']);
|
|
10829
|
+
const svg = freeze(['accent-height', 'accumulate', 'additive', 'alignment-baseline', 'amplitude', 'ascent', 'attributename', 'attributetype', 'azimuth', 'basefrequency', 'baseline-shift', 'begin', 'bias', 'by', 'class', 'clip', 'clippathunits', 'clip-path', 'clip-rule', 'color', 'color-interpolation', 'color-interpolation-filters', 'color-profile', 'color-rendering', 'cx', 'cy', 'd', 'dx', 'dy', 'diffuseconstant', 'direction', 'display', 'divisor', 'dur', 'edgemode', 'elevation', 'end', 'exponent', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'filterunits', 'flood-color', 'flood-opacity', 'font-family', 'font-size', 'font-size-adjust', 'font-stretch', 'font-style', 'font-variant', 'font-weight', 'fx', 'fy', 'g1', 'g2', 'glyph-name', 'glyphref', 'gradientunits', 'gradienttransform', 'height', 'href', 'id', 'image-rendering', 'in', 'in2', 'intercept', 'k', 'k1', 'k2', 'k3', 'k4', 'kerning', 'keypoints', 'keysplines', 'keytimes', 'lang', 'lengthadjust', 'letter-spacing', 'kernelmatrix', 'kernelunitlength', 'lighting-color', 'local', 'marker-end', 'marker-mid', 'marker-start', 'markerheight', 'markerunits', 'markerwidth', 'maskcontentunits', 'maskunits', 'max', 'mask', 'mask-type', 'media', 'method', 'mode', 'min', 'name', 'numoctaves', 'offset', 'operator', 'opacity', 'order', 'orient', 'orientation', 'origin', 'overflow', 'paint-order', 'path', 'pathlength', 'patterncontentunits', 'patterntransform', 'patternunits', 'points', 'preservealpha', 'preserveaspectratio', 'primitiveunits', 'r', 'rx', 'ry', 'radius', 'refx', 'refy', 'repeatcount', 'repeatdur', 'restart', 'result', 'rotate', 'scale', 'seed', 'shape-rendering', 'slope', 'specularconstant', 'specularexponent', 'spreadmethod', 'startoffset', 'stddeviation', 'stitchtiles', 'stop-color', 'stop-opacity', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke', 'stroke-width', 'style', 'surfacescale', 'systemlanguage', 'tabindex', 'tablevalues', 'targetx', 'targety', 'transform', 'transform-origin', 'text-anchor', 'text-decoration', 'text-rendering', 'textlength', 'type', 'u1', 'u2', 'unicode', 'values', 'viewbox', 'visibility', 'version', 'vert-adv-y', 'vert-origin-x', 'vert-origin-y', 'width', 'word-spacing', 'wrap', 'writing-mode', 'xchannelselector', 'ychannelselector', 'x', 'x1', 'x2', 'xmlns', 'y', 'y1', 'y2', 'z', 'zoomandpan']);
|
|
10998
10830
|
const mathMl = freeze(['accent', 'accentunder', 'align', 'bevelled', 'close', 'columnsalign', 'columnlines', 'columnspan', 'denomalign', 'depth', 'dir', 'display', 'displaystyle', 'encoding', 'fence', 'frame', 'height', 'href', 'id', 'largeop', 'length', 'linethickness', 'lspace', 'lquote', 'mathbackground', 'mathcolor', 'mathsize', 'mathvariant', 'maxsize', 'minsize', 'movablelimits', 'notation', 'numalign', 'open', 'rowalign', 'rowlines', 'rowspacing', 'rowspan', 'rspace', 'rquote', 'scriptlevel', 'scriptminsize', 'scriptsizemultiplier', 'selection', 'separator', 'separators', 'stretchy', 'subscriptshift', 'supscriptshift', 'symmetric', 'voffset', 'width', 'xmlns']);
|
|
10999
10831
|
const xml = freeze(['xlink:href', 'xml:id', 'xlink:title', 'xml:space', 'xmlns:xlink']);
|
|
11000
10832
|
|
|
@@ -11101,7 +10933,7 @@
|
|
|
11101
10933
|
function createDOMPurify() {
|
|
11102
10934
|
let window = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getGlobal();
|
|
11103
10935
|
const DOMPurify = root => createDOMPurify(root);
|
|
11104
|
-
DOMPurify.version = '3.
|
|
10936
|
+
DOMPurify.version = '3.3.0';
|
|
11105
10937
|
DOMPurify.removed = [];
|
|
11106
10938
|
if (!window || !window.document || window.document.nodeType !== NODE_TYPE.document || !window.Element) {
|
|
11107
10939
|
// Not running in a browser, provide a factory function
|
|
@@ -11212,6 +11044,21 @@
|
|
|
11212
11044
|
let FORBID_TAGS = null;
|
|
11213
11045
|
/* Explicitly forbidden attributes (overrides ALLOWED_ATTR/ADD_ATTR) */
|
|
11214
11046
|
let FORBID_ATTR = null;
|
|
11047
|
+
/* Config object to store ADD_TAGS/ADD_ATTR functions (when used as functions) */
|
|
11048
|
+
const EXTRA_ELEMENT_HANDLING = Object.seal(create(null, {
|
|
11049
|
+
tagCheck: {
|
|
11050
|
+
writable: true,
|
|
11051
|
+
configurable: false,
|
|
11052
|
+
enumerable: true,
|
|
11053
|
+
value: null
|
|
11054
|
+
},
|
|
11055
|
+
attributeCheck: {
|
|
11056
|
+
writable: true,
|
|
11057
|
+
configurable: false,
|
|
11058
|
+
enumerable: true,
|
|
11059
|
+
value: null
|
|
11060
|
+
}
|
|
11061
|
+
}));
|
|
11215
11062
|
/* Decide if ARIA attributes are okay */
|
|
11216
11063
|
let ALLOW_ARIA_ATTR = true;
|
|
11217
11064
|
/* Decide if custom data attributes are okay */
|
|
@@ -11404,16 +11251,24 @@
|
|
|
11404
11251
|
}
|
|
11405
11252
|
/* Merge configuration parameters */
|
|
11406
11253
|
if (cfg.ADD_TAGS) {
|
|
11407
|
-
if (
|
|
11408
|
-
|
|
11254
|
+
if (typeof cfg.ADD_TAGS === 'function') {
|
|
11255
|
+
EXTRA_ELEMENT_HANDLING.tagCheck = cfg.ADD_TAGS;
|
|
11256
|
+
} else {
|
|
11257
|
+
if (ALLOWED_TAGS === DEFAULT_ALLOWED_TAGS) {
|
|
11258
|
+
ALLOWED_TAGS = clone(ALLOWED_TAGS);
|
|
11259
|
+
}
|
|
11260
|
+
addToSet(ALLOWED_TAGS, cfg.ADD_TAGS, transformCaseFunc);
|
|
11409
11261
|
}
|
|
11410
|
-
addToSet(ALLOWED_TAGS, cfg.ADD_TAGS, transformCaseFunc);
|
|
11411
11262
|
}
|
|
11412
11263
|
if (cfg.ADD_ATTR) {
|
|
11413
|
-
if (
|
|
11414
|
-
|
|
11264
|
+
if (typeof cfg.ADD_ATTR === 'function') {
|
|
11265
|
+
EXTRA_ELEMENT_HANDLING.attributeCheck = cfg.ADD_ATTR;
|
|
11266
|
+
} else {
|
|
11267
|
+
if (ALLOWED_ATTR === DEFAULT_ALLOWED_ATTR) {
|
|
11268
|
+
ALLOWED_ATTR = clone(ALLOWED_ATTR);
|
|
11269
|
+
}
|
|
11270
|
+
addToSet(ALLOWED_ATTR, cfg.ADD_ATTR, transformCaseFunc);
|
|
11415
11271
|
}
|
|
11416
|
-
addToSet(ALLOWED_ATTR, cfg.ADD_ATTR, transformCaseFunc);
|
|
11417
11272
|
}
|
|
11418
11273
|
if (cfg.ADD_URI_SAFE_ATTR) {
|
|
11419
11274
|
addToSet(URI_SAFE_ATTRIBUTES, cfg.ADD_URI_SAFE_ATTR, transformCaseFunc);
|
|
@@ -11721,7 +11576,7 @@
|
|
|
11721
11576
|
return true;
|
|
11722
11577
|
}
|
|
11723
11578
|
/* Remove element if anything forbids its presence */
|
|
11724
|
-
if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) {
|
|
11579
|
+
if (!(EXTRA_ELEMENT_HANDLING.tagCheck instanceof Function && EXTRA_ELEMENT_HANDLING.tagCheck(tagName)) && (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName])) {
|
|
11725
11580
|
/* Check if we have a custom element to handle */
|
|
11726
11581
|
if (!FORBID_TAGS[tagName] && _isBasicCustomElement(tagName)) {
|
|
11727
11582
|
if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName)) {
|
|
@@ -11793,7 +11648,7 @@
|
|
|
11793
11648
|
(https://html.spec.whatwg.org/multipage/dom.html#embedding-custom-non-visible-data-with-the-data-*-attributes)
|
|
11794
11649
|
XML-compatible (https://html.spec.whatwg.org/multipage/infrastructure.html#xml-compatible and http://www.w3.org/TR/xml/#d0e804)
|
|
11795
11650
|
We don't need to check the value; it's always URI safe. */
|
|
11796
|
-
if (ALLOW_DATA_ATTR && !FORBID_ATTR[lcName] && regExpTest(DATA_ATTR, lcName)) ; else if (ALLOW_ARIA_ATTR && regExpTest(ARIA_ATTR, lcName)) ; else if (!ALLOWED_ATTR[lcName] || FORBID_ATTR[lcName]) {
|
|
11651
|
+
if (ALLOW_DATA_ATTR && !FORBID_ATTR[lcName] && regExpTest(DATA_ATTR, lcName)) ; else if (ALLOW_ARIA_ATTR && regExpTest(ARIA_ATTR, lcName)) ; else if (EXTRA_ELEMENT_HANDLING.attributeCheck instanceof Function && EXTRA_ELEMENT_HANDLING.attributeCheck(lcName, lcTag)) ; else if (!ALLOWED_ATTR[lcName] || FORBID_ATTR[lcName]) {
|
|
11797
11652
|
if (
|
|
11798
11653
|
// First condition does a very basic check if a) it's basically a valid custom element tagname AND
|
|
11799
11654
|
// b) if the tagName passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck
|
|
@@ -17200,7 +17055,7 @@
|
|
|
17200
17055
|
} else if (isFile(config.url)) {
|
|
17201
17056
|
this.name = config.url.name;
|
|
17202
17057
|
} else if (isString$3(config.url) && !config.url.startsWith("data:")) {
|
|
17203
|
-
this.name = getFilename$
|
|
17058
|
+
this.name = getFilename$1(config.url);
|
|
17204
17059
|
}
|
|
17205
17060
|
|
|
17206
17061
|
this.url = config.url;
|
|
@@ -21160,7 +21015,7 @@
|
|
|
21160
21015
|
config.format = format.toLowerCase();
|
|
21161
21016
|
config.sourceType = "htsget";
|
|
21162
21017
|
if (!config.name) {
|
|
21163
|
-
config.name =
|
|
21018
|
+
config.name = getFilename$1(config.url);
|
|
21164
21019
|
}
|
|
21165
21020
|
}
|
|
21166
21021
|
} catch (e) {
|
|
@@ -31695,7 +31550,7 @@
|
|
|
31695
31550
|
|
|
31696
31551
|
this.overlayElement.style.top = `-${contentTop}px`;
|
|
31697
31552
|
|
|
31698
|
-
if(!this.checkZoomIn()) return
|
|
31553
|
+
if (!this.checkZoomIn()) return
|
|
31699
31554
|
|
|
31700
31555
|
if (!this.canvas) {
|
|
31701
31556
|
this.repaint();
|
|
@@ -32334,7 +32189,7 @@
|
|
|
32334
32189
|
|
|
32335
32190
|
popupTimerID = setTimeout(() => {
|
|
32336
32191
|
|
|
32337
|
-
const content = this.
|
|
32192
|
+
const content = this.handleTrackClick(event);
|
|
32338
32193
|
if (content) {
|
|
32339
32194
|
|
|
32340
32195
|
if (false === event.shiftKey) {
|
|
@@ -32499,7 +32354,7 @@
|
|
|
32499
32354
|
|
|
32500
32355
|
}
|
|
32501
32356
|
|
|
32502
|
-
|
|
32357
|
+
handleTrackClick(event) {
|
|
32503
32358
|
|
|
32504
32359
|
const clickState = this.createClickState(event);
|
|
32505
32360
|
|
|
@@ -42647,7 +42502,7 @@
|
|
|
42647
42502
|
let format;
|
|
42648
42503
|
|
|
42649
42504
|
// First try determining format from file extension
|
|
42650
|
-
const filename = config.filename ||
|
|
42505
|
+
const filename = config.filename || getFilename$1(config.url);
|
|
42651
42506
|
if(filename) {
|
|
42652
42507
|
format = await inferFileFormatFromName(filename);
|
|
42653
42508
|
}
|
|
@@ -67136,7 +66991,7 @@ ${indent}columns: ${matrix.columns}
|
|
|
67136
66991
|
})
|
|
67137
66992
|
}
|
|
67138
66993
|
|
|
67139
|
-
const _version = "3.5.
|
|
66994
|
+
const _version = "3.5.4";
|
|
67140
66995
|
function version() {
|
|
67141
66996
|
return _version
|
|
67142
66997
|
}
|
|
@@ -69040,7 +68895,7 @@ ${indent}columns: ${matrix.columns}
|
|
|
69040
68895
|
|
|
69041
68896
|
for (let config of configs) {
|
|
69042
68897
|
if (!config.name && config.url) {
|
|
69043
|
-
config.name =
|
|
68898
|
+
config.name = getFilename$1(config.url);
|
|
69044
68899
|
}
|
|
69045
68900
|
if (config.url && !config.format) {
|
|
69046
68901
|
config.format = await inferFileFormat(config);
|
|
@@ -73827,7 +73682,8 @@ ${indent}columns: ${matrix.columns}
|
|
|
73827
73682
|
return handler.apply(scope, args)
|
|
73828
73683
|
});
|
|
73829
73684
|
|
|
73830
|
-
return
|
|
73685
|
+
// The only event that uses the return value is "trackclick", which implicitly assumes a single handler
|
|
73686
|
+
return results[0]
|
|
73831
73687
|
}
|
|
73832
73688
|
}
|
|
73833
73689
|
|
|
@@ -74198,7 +74054,7 @@ ${indent}columns: ${matrix.columns}
|
|
|
74198
74054
|
} else {
|
|
74199
74055
|
let filename = options.filename;
|
|
74200
74056
|
if (!filename) {
|
|
74201
|
-
filename = (options.url ?
|
|
74057
|
+
filename = (options.url ? getFilename$1(options.url) : options.file.name);
|
|
74202
74058
|
}
|
|
74203
74059
|
|
|
74204
74060
|
if (filename.endsWith(".xml")) {
|
|
@@ -74212,10 +74068,8 @@ ${indent}columns: ${matrix.columns}
|
|
|
74212
74068
|
config = {
|
|
74213
74069
|
reference: genomeConfig
|
|
74214
74070
|
};
|
|
74215
|
-
} else
|
|
74071
|
+
} else {
|
|
74216
74072
|
config = await igvxhr.loadJson(urlOrFile);
|
|
74217
|
-
} else {
|
|
74218
|
-
throw Error("Unrecognized session file format:" + filename)
|
|
74219
74073
|
}
|
|
74220
74074
|
}
|
|
74221
74075
|
setDefaults(config, defaults);
|