igv 3.2.4 → 3.2.6
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 +246 -55
- package/dist/igv.esm.min.js +9 -9
- package/dist/igv.esm.min.js.map +1 -1
- package/dist/igv.js +246 -55
- 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
|
@@ -8629,6 +8629,7 @@
|
|
|
8629
8629
|
}
|
|
8630
8630
|
|
|
8631
8631
|
|
|
8632
|
+
let promise;
|
|
8632
8633
|
/**
|
|
8633
8634
|
* Return a promise for an access token for the given scope. If the user hasn't authorized the scope request it
|
|
8634
8635
|
*
|
|
@@ -8647,22 +8648,27 @@
|
|
|
8647
8648
|
return google.igv.tokenResponse.access_token
|
|
8648
8649
|
} else {
|
|
8649
8650
|
const tokenClient = google.igv.tokenClient;
|
|
8650
|
-
|
|
8651
|
-
|
|
8652
|
-
|
|
8653
|
-
|
|
8654
|
-
|
|
8655
|
-
|
|
8656
|
-
|
|
8657
|
-
|
|
8658
|
-
|
|
8659
|
-
|
|
8660
|
-
|
|
8661
|
-
|
|
8662
|
-
|
|
8663
|
-
|
|
8664
|
-
|
|
8665
|
-
|
|
8651
|
+
if(!promise) {
|
|
8652
|
+
promise = new Promise((resolve, reject) => {
|
|
8653
|
+
try {
|
|
8654
|
+
// Settle this promise in the response callback for requestAccessToken()
|
|
8655
|
+
tokenClient.callback = (tokenResponse) => {
|
|
8656
|
+
if (tokenResponse.error !== undefined) {
|
|
8657
|
+
reject(tokenResponse);
|
|
8658
|
+
}
|
|
8659
|
+
google.igv.tokenResponse = tokenResponse;
|
|
8660
|
+
google.igv.tokenExpiresAt = Date.now() + tokenResponse.expires_in * 1000;
|
|
8661
|
+
console.log("Access token expires at " + new Date(google.igv.tokenExpiresAt));
|
|
8662
|
+
resolve(tokenResponse.access_token);
|
|
8663
|
+
};
|
|
8664
|
+
console.log("Requesting access token");
|
|
8665
|
+
tokenClient.requestAccessToken({scope});
|
|
8666
|
+
} catch (err) {
|
|
8667
|
+
console.log(err);
|
|
8668
|
+
}
|
|
8669
|
+
});
|
|
8670
|
+
}
|
|
8671
|
+
return promise
|
|
8666
8672
|
}
|
|
8667
8673
|
}
|
|
8668
8674
|
|
|
@@ -10946,7 +10952,7 @@
|
|
|
10946
10952
|
return list;
|
|
10947
10953
|
}
|
|
10948
10954
|
|
|
10949
|
-
/*! @license DOMPurify 3.2.
|
|
10955
|
+
/*! @license DOMPurify 3.2.5 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.2.5/LICENSE */
|
|
10950
10956
|
|
|
10951
10957
|
const {
|
|
10952
10958
|
entries,
|
|
@@ -11006,6 +11012,9 @@
|
|
|
11006
11012
|
*/
|
|
11007
11013
|
function unapply(func) {
|
|
11008
11014
|
return function (thisArg) {
|
|
11015
|
+
if (thisArg instanceof RegExp) {
|
|
11016
|
+
thisArg.lastIndex = 0;
|
|
11017
|
+
}
|
|
11009
11018
|
for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
|
11010
11019
|
args[_key - 1] = arguments[_key];
|
|
11011
11020
|
}
|
|
@@ -11244,7 +11253,7 @@
|
|
|
11244
11253
|
function createDOMPurify() {
|
|
11245
11254
|
let window = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getGlobal();
|
|
11246
11255
|
const DOMPurify = root => createDOMPurify(root);
|
|
11247
|
-
DOMPurify.version = '3.2.
|
|
11256
|
+
DOMPurify.version = '3.2.5';
|
|
11248
11257
|
DOMPurify.removed = [];
|
|
11249
11258
|
if (!window || !window.document || window.document.nodeType !== NODE_TYPE.document || !window.Element) {
|
|
11250
11259
|
// Not running in a browser, provide a factory function
|
|
@@ -11849,7 +11858,7 @@
|
|
|
11849
11858
|
allowedTags: ALLOWED_TAGS
|
|
11850
11859
|
});
|
|
11851
11860
|
/* Detect mXSS attempts abusing namespace confusion */
|
|
11852
|
-
if (currentNode.hasChildNodes() && !_isNode(currentNode.firstElementChild) && regExpTest(/<[/\w]/g, currentNode.innerHTML) && regExpTest(/<[/\w]/g, currentNode.textContent)) {
|
|
11861
|
+
if (currentNode.hasChildNodes() && !_isNode(currentNode.firstElementChild) && regExpTest(/<[/\w!]/g, currentNode.innerHTML) && regExpTest(/<[/\w!]/g, currentNode.textContent)) {
|
|
11853
11862
|
_forceRemove(currentNode);
|
|
11854
11863
|
return true;
|
|
11855
11864
|
}
|
|
@@ -16343,7 +16352,10 @@
|
|
|
16343
16352
|
}
|
|
16344
16353
|
} else {
|
|
16345
16354
|
// All directives that could change the format, and thus decoder, should have been read by now.
|
|
16346
|
-
|
|
16355
|
+
// Set the decoder, unless it is explicitly set in the track configuration (not common)
|
|
16356
|
+
if(!this.config.decode) {
|
|
16357
|
+
this.setDecoder(header.format);
|
|
16358
|
+
}
|
|
16347
16359
|
|
|
16348
16360
|
// If the line can be parsed as a feature assume we are beyond the header, if any
|
|
16349
16361
|
const tokens = line.split(this.delimiter || "\t");
|
|
@@ -30852,6 +30864,7 @@
|
|
|
30852
30864
|
}
|
|
30853
30865
|
|
|
30854
30866
|
const DEFAULT_GENOMES_URL = "https://igv.org/genomes/genomes.json";
|
|
30867
|
+
const BACKUP_GENOMES_URL = "https://raw.githubusercontent.com/igvteam/igv-genomes/refs/heads/main/dist/genomes.json";
|
|
30855
30868
|
|
|
30856
30869
|
const GenomeUtils = {
|
|
30857
30870
|
|
|
@@ -30859,34 +30872,42 @@
|
|
|
30859
30872
|
|
|
30860
30873
|
if (!GenomeUtils.KNOWN_GENOMES) {
|
|
30861
30874
|
|
|
30862
|
-
|
|
30875
|
+
let table = {};
|
|
30876
|
+
|
|
30877
|
+
const processJson = (jsonArray, table) => {
|
|
30878
|
+
jsonArray.forEach(function (json) {
|
|
30879
|
+
table[json.id] = json;
|
|
30880
|
+
});
|
|
30881
|
+
return table
|
|
30882
|
+
};
|
|
30863
30883
|
|
|
30864
30884
|
// Get default genomes
|
|
30865
30885
|
if (config.loadDefaultGenomes !== false) {
|
|
30866
|
-
|
|
30867
|
-
|
|
30868
|
-
|
|
30886
|
+
try {
|
|
30887
|
+
const jsonArray = await igvxhr.loadJson(DEFAULT_GENOMES_URL, {timeout: 2000});
|
|
30888
|
+
processJson(jsonArray, table);
|
|
30889
|
+
} catch (error) {
|
|
30890
|
+
try {
|
|
30891
|
+
console.error("Error initializing default genomes:", error);
|
|
30892
|
+
const jsonArray = await igvxhr.loadJson(BACKUP_GENOMES_URL, {timeout: 2000});
|
|
30893
|
+
processJson(jsonArray, table);
|
|
30894
|
+
} catch (e) {
|
|
30895
|
+
console.error("Error initializing backup genomes:", error);
|
|
30896
|
+
}
|
|
30897
|
+
}
|
|
30869
30898
|
}
|
|
30870
30899
|
|
|
30871
|
-
//
|
|
30900
|
+
// Append user-defined genomes, which might override defaults
|
|
30872
30901
|
const genomeList = config.genomeList || config.genomes;
|
|
30873
30902
|
if (genomeList) {
|
|
30874
30903
|
if (typeof genomeList === 'string') {
|
|
30875
30904
|
const jsonArray = await igvxhr.loadJson(genomeList, {});
|
|
30876
|
-
|
|
30905
|
+
processJson(jsonArray, table);
|
|
30877
30906
|
} else {
|
|
30878
|
-
|
|
30907
|
+
processJson(genomeList, table);
|
|
30879
30908
|
}
|
|
30880
30909
|
}
|
|
30881
|
-
|
|
30882
30910
|
GenomeUtils.KNOWN_GENOMES = table;
|
|
30883
|
-
|
|
30884
|
-
function processJson(jsonArray) {
|
|
30885
|
-
jsonArray.forEach(function (json) {
|
|
30886
|
-
table[json.id] = json;
|
|
30887
|
-
});
|
|
30888
|
-
return table
|
|
30889
|
-
}
|
|
30890
30911
|
}
|
|
30891
30912
|
},
|
|
30892
30913
|
|
|
@@ -30912,7 +30933,7 @@
|
|
|
30912
30933
|
} else if (idOrConfig.genome) {
|
|
30913
30934
|
genomeID = idOrConfig.genome;
|
|
30914
30935
|
} else if (idOrConfig.id !== undefined && !(idOrConfig.fastaURL || idOrConfig.twobitURL)) {
|
|
30915
|
-
// Backward
|
|
30936
|
+
// Backward compatibility
|
|
30916
30937
|
genomeID = idOrConfig.id;
|
|
30917
30938
|
}
|
|
30918
30939
|
|
|
@@ -47613,7 +47634,7 @@
|
|
|
47613
47634
|
if (!this.colorBy) {
|
|
47614
47635
|
this.colorBy = this.hasPairs ? "unexpectedPair" : "none";
|
|
47615
47636
|
}
|
|
47616
|
-
|
|
47637
|
+
|
|
47617
47638
|
let pixelTop = options.pixelTop - BAMTrack.coverageTrackHeight;
|
|
47618
47639
|
if (this.top) {
|
|
47619
47640
|
ctx.translate(0, this.top);
|
|
@@ -48320,7 +48341,12 @@
|
|
|
48320
48341
|
this.trackView.repaintViews();
|
|
48321
48342
|
}
|
|
48322
48343
|
|
|
48323
|
-
return {
|
|
48344
|
+
return {
|
|
48345
|
+
name: undefined,
|
|
48346
|
+
element: createCheckbox(menuItem.label, showCheck),
|
|
48347
|
+
click: clickHandler,
|
|
48348
|
+
init: undefined
|
|
48349
|
+
}
|
|
48324
48350
|
}
|
|
48325
48351
|
|
|
48326
48352
|
|
|
@@ -48367,7 +48393,12 @@
|
|
|
48367
48393
|
}
|
|
48368
48394
|
}
|
|
48369
48395
|
|
|
48370
|
-
return {
|
|
48396
|
+
return {
|
|
48397
|
+
name: undefined,
|
|
48398
|
+
element: createCheckbox(menuItem.label, showCheck),
|
|
48399
|
+
dialog: clickHandler,
|
|
48400
|
+
init: undefined
|
|
48401
|
+
}
|
|
48371
48402
|
|
|
48372
48403
|
}
|
|
48373
48404
|
|
|
@@ -48489,38 +48520,88 @@
|
|
|
48489
48520
|
});
|
|
48490
48521
|
}
|
|
48491
48522
|
|
|
48523
|
+
list.push('<hr/>');
|
|
48524
|
+
const softClips = clickedAlignment.softClippedBlocks();
|
|
48492
48525
|
list.push({
|
|
48493
48526
|
label: 'View read sequence',
|
|
48494
48527
|
click: () => {
|
|
48495
|
-
const seqstring = clickedAlignment.seq;
|
|
48496
|
-
|
|
48497
|
-
this.browser.alert.present("Read sequence: *");
|
|
48498
|
-
} else {
|
|
48499
|
-
this.browser.alert.present(seqstring);
|
|
48500
|
-
}
|
|
48528
|
+
const seqstring = clickedAlignment.seq;
|
|
48529
|
+
this.browser.alert.present(seqstring && seqstring !== "*" ? seqstring : "Read sequence: *");
|
|
48501
48530
|
}
|
|
48502
48531
|
});
|
|
48503
48532
|
|
|
48533
|
+
if (softClips.left && softClips.left.len > 0) {
|
|
48534
|
+
list.push({
|
|
48535
|
+
label: 'View left soft-clipped sequence',
|
|
48536
|
+
click: () => {
|
|
48537
|
+
const clippedSequence = clickedAlignment.seq.substring(softClips.left.seqOffset, softClips.left.seqOffset + softClips.left.len);
|
|
48538
|
+
this.browser.alert.present(clippedSequence);
|
|
48539
|
+
}
|
|
48540
|
+
});
|
|
48541
|
+
}
|
|
48542
|
+
|
|
48543
|
+
if (softClips.right && softClips.right.len > 0) {
|
|
48544
|
+
list.push({
|
|
48545
|
+
label: 'View right soft-clipped sequence',
|
|
48546
|
+
click: () => {
|
|
48547
|
+
const clippedSequence = clickedAlignment.seq.substring(softClips.right.seqOffset, softClips.right.seqOffset + softClips.right.len);
|
|
48548
|
+
this.browser.alert.present(clippedSequence);
|
|
48549
|
+
}
|
|
48550
|
+
});
|
|
48551
|
+
}
|
|
48552
|
+
|
|
48553
|
+
list.push('<hr/>');
|
|
48554
|
+
|
|
48504
48555
|
if (isSecureContext()) {
|
|
48505
48556
|
list.push({
|
|
48506
48557
|
label: 'Copy read sequence',
|
|
48507
48558
|
click: async () => {
|
|
48508
|
-
const seq = clickedAlignment.seq; //.map(b => String.fromCharCode(b)).join("");
|
|
48509
48559
|
try {
|
|
48510
|
-
await navigator.clipboard.writeText(seq);
|
|
48560
|
+
await navigator.clipboard.writeText(clickedAlignment.seq);
|
|
48511
48561
|
} catch (e) {
|
|
48512
48562
|
console.error(e);
|
|
48513
48563
|
this.browser.alert.present(`error copying sequence to clipboard ${e}`);
|
|
48514
48564
|
}
|
|
48515
|
-
|
|
48516
48565
|
}
|
|
48517
48566
|
});
|
|
48567
|
+
|
|
48568
|
+
if (softClips.left && softClips.left.len > 0) {
|
|
48569
|
+
list.push({
|
|
48570
|
+
label: 'Copy left soft-clipped sequence',
|
|
48571
|
+
click: async () => {
|
|
48572
|
+
try {
|
|
48573
|
+
const clippedSequence = clickedAlignment.seq.substring(softClips.left.seqOffset, softClips.left.seqOffset + softClips.left.len);
|
|
48574
|
+
await navigator.clipboard.writeText(clippedSequence);
|
|
48575
|
+
} catch (e) {
|
|
48576
|
+
console.error(e);
|
|
48577
|
+
this.browser.alert.present(`error copying sequence to clipboard ${e}`);
|
|
48578
|
+
}
|
|
48579
|
+
}
|
|
48580
|
+
});
|
|
48581
|
+
}
|
|
48582
|
+
|
|
48583
|
+
if (softClips.right && softClips.right.len > 0) {
|
|
48584
|
+
list.push({
|
|
48585
|
+
label: 'Copy right soft-clipped sequence',
|
|
48586
|
+
click: async () => {
|
|
48587
|
+
try {
|
|
48588
|
+
const clippedSequence = clickedAlignment.seq.substring(softClips.right.seqOffset, softClips.right.seqOffset + softClips.right.len);
|
|
48589
|
+
await navigator.clipboard.writeText(clippedSequence);
|
|
48590
|
+
} catch (e) {
|
|
48591
|
+
console.error(e);
|
|
48592
|
+
this.browser.alert.present(`error copying sequence to clipboard ${e}`);
|
|
48593
|
+
}
|
|
48594
|
+
}
|
|
48595
|
+
});
|
|
48596
|
+
}
|
|
48518
48597
|
}
|
|
48519
48598
|
|
|
48520
|
-
// TODO if genome supports blat
|
|
48599
|
+
// TODO test if genome supports blat
|
|
48521
48600
|
const seqstring = clickedAlignment.seq;
|
|
48522
48601
|
if (seqstring && "*" !== seqstring) {
|
|
48523
48602
|
|
|
48603
|
+
list.push('<hr/>');
|
|
48604
|
+
|
|
48524
48605
|
if (seqstring.length < maxSequenceSize$1) {
|
|
48525
48606
|
list.push({
|
|
48526
48607
|
label: 'BLAT read sequence',
|
|
@@ -48538,7 +48619,7 @@
|
|
|
48538
48619
|
list.push({
|
|
48539
48620
|
label: 'BLAT left soft-clipped sequence',
|
|
48540
48621
|
click: () => {
|
|
48541
|
-
const clippedSequence = seqstring.
|
|
48622
|
+
const clippedSequence = seqstring.substring(softClips.left.seqOffset, softClips.left.seqOffset + softClips.left.len);
|
|
48542
48623
|
const sequence = clickedAlignment.isNegativeStrand() ? reverseComplementSequence(clippedSequence) : clippedSequence;
|
|
48543
48624
|
const name = `${clickedAlignment.readName} - blat left clip`;
|
|
48544
48625
|
const title = `${this.name} - ${name}`;
|
|
@@ -48550,7 +48631,7 @@
|
|
|
48550
48631
|
list.push({
|
|
48551
48632
|
label: 'BLAT right soft-clipped sequence',
|
|
48552
48633
|
click: () => {
|
|
48553
|
-
const clippedSequence = seqstring.
|
|
48634
|
+
const clippedSequence = seqstring.substring(softClips.right.seqOffset, softClips.right.seqOffset + softClips.right.len);
|
|
48554
48635
|
const sequence = clickedAlignment.isNegativeStrand() ? reverseComplementSequence(clippedSequence) : clippedSequence;
|
|
48555
48636
|
const name = `${clickedAlignment.readName} - blat right clip`;
|
|
48556
48637
|
const title = `${this.name} - ${name}`;
|
|
@@ -48599,7 +48680,7 @@
|
|
|
48599
48680
|
const offsetY = y - this.top;
|
|
48600
48681
|
const genomicLocation = clickState.genomicLocation;
|
|
48601
48682
|
|
|
48602
|
-
if(features.packedGroups) {
|
|
48683
|
+
if (features.packedGroups) {
|
|
48603
48684
|
let minGroupY = Number.MAX_VALUE;
|
|
48604
48685
|
for (let group of features.packedGroups.values()) {
|
|
48605
48686
|
minGroupY = Math.min(minGroupY, group.pixelTop);
|
|
@@ -68825,6 +68906,115 @@ ${indent}columns: ${matrix.columns}
|
|
|
68825
68906
|
}
|
|
68826
68907
|
}
|
|
68827
68908
|
|
|
68909
|
+
/**
|
|
68910
|
+
* Configurable properties
|
|
68911
|
+
* Locus {chr, start, end}
|
|
68912
|
+
* url - url to image. Later url to webservice to fetch image
|
|
68913
|
+
*/
|
|
68914
|
+
|
|
68915
|
+
class ImageTrack extends TrackBase {
|
|
68916
|
+
|
|
68917
|
+
static defaults = {}
|
|
68918
|
+
|
|
68919
|
+
constructor(config, browser) {
|
|
68920
|
+
super(config, browser);
|
|
68921
|
+
}
|
|
68922
|
+
|
|
68923
|
+
init(config) {
|
|
68924
|
+
|
|
68925
|
+
super.init(config);
|
|
68926
|
+
|
|
68927
|
+
if (!config.images) {
|
|
68928
|
+
throw Error("images are required")
|
|
68929
|
+
}
|
|
68930
|
+
|
|
68931
|
+
this.locus = config.locus;
|
|
68932
|
+
this.type = "image";
|
|
68933
|
+
this.resolutionAware = true;
|
|
68934
|
+
}
|
|
68935
|
+
|
|
68936
|
+
|
|
68937
|
+
async postInit() {
|
|
68938
|
+
|
|
68939
|
+
this._images = [];
|
|
68940
|
+
|
|
68941
|
+
for (let i of this.config.images) {
|
|
68942
|
+
const img = new Image();
|
|
68943
|
+
img.onload = () => {
|
|
68944
|
+
i.img = img;
|
|
68945
|
+
i.bpPerPixel = (i.end - i.start) / img.width;
|
|
68946
|
+
this._images.push(i);
|
|
68947
|
+
};
|
|
68948
|
+
img.onerror = (err) => {
|
|
68949
|
+
console.error(err);
|
|
68950
|
+
};
|
|
68951
|
+
//if (img.complete) { //cached image
|
|
68952
|
+
// img.onload()
|
|
68953
|
+
// }
|
|
68954
|
+
img.src = i.src;
|
|
68955
|
+
}
|
|
68956
|
+
|
|
68957
|
+
}
|
|
68958
|
+
|
|
68959
|
+
computePixelHeight(features) {
|
|
68960
|
+
return features ? features.height : 0
|
|
68961
|
+
}
|
|
68962
|
+
|
|
68963
|
+
|
|
68964
|
+
menuItemList() {
|
|
68965
|
+
|
|
68966
|
+
const menuItems = [];
|
|
68967
|
+
|
|
68968
|
+
return menuItems
|
|
68969
|
+
}
|
|
68970
|
+
|
|
68971
|
+
|
|
68972
|
+
async getFeatures(chr, start, end, bpPerPixel) {
|
|
68973
|
+
// Return image. Scaled or not?
|
|
68974
|
+
return this.selectImage(chr, start, end, bpPerPixel)
|
|
68975
|
+
}
|
|
68976
|
+
|
|
68977
|
+
selectImage(chr, start, end, bpPerPixel) {
|
|
68978
|
+
|
|
68979
|
+
// Select the highest resolution image containing the interval. If no image contains the interval return
|
|
68980
|
+
// the lowest resolution image if it overlaps
|
|
68981
|
+
if(this._images.length == 0) {
|
|
68982
|
+
return null
|
|
68983
|
+
}
|
|
68984
|
+
this._images.sort((a, b) => a.bpPerPixel < b.bpPerPixel ? -1 : 1);
|
|
68985
|
+
for(let i of this._images) {
|
|
68986
|
+
if(i.bpPerPixel > bpPerPixel) {
|
|
68987
|
+
return i
|
|
68988
|
+
}
|
|
68989
|
+
}
|
|
68990
|
+
const lowRes = this._images[this._images.length-1];
|
|
68991
|
+
if(lowRes.chr === chr) {
|
|
68992
|
+
return lowRes
|
|
68993
|
+
} else {
|
|
68994
|
+
return null
|
|
68995
|
+
}
|
|
68996
|
+
}
|
|
68997
|
+
|
|
68998
|
+
draw({context, pixelTop, pixelWidth, pixelHeight, features, bpPerPixel, bpStart}) {
|
|
68999
|
+
|
|
69000
|
+
const image = features.img;
|
|
69001
|
+
if (image) {
|
|
69002
|
+
const nw = image.width;
|
|
69003
|
+
const nh = image.height;
|
|
69004
|
+
const imageBpPerPixel = (features.end - features.start) / nw;
|
|
69005
|
+
const scale = imageBpPerPixel / bpPerPixel;
|
|
69006
|
+
const x = (features.start - bpStart) / bpPerPixel;
|
|
69007
|
+
context.drawImage(image, x, 0, scale * nw, nh);
|
|
69008
|
+
}
|
|
69009
|
+
|
|
69010
|
+
}
|
|
69011
|
+
|
|
69012
|
+
get supportsWholeGenome() {
|
|
69013
|
+
return false
|
|
69014
|
+
}
|
|
69015
|
+
|
|
69016
|
+
}
|
|
69017
|
+
|
|
68828
69018
|
//import CNVPytorTrack from "./CNVpytor/cnvpytorTrack.js"
|
|
68829
69019
|
|
|
68830
69020
|
|
|
@@ -68850,7 +69040,8 @@ ${indent}columns: ${matrix.columns}
|
|
|
68850
69040
|
['gcnv', (config, browser) => new GCNVTrack(config, browser)],
|
|
68851
69041
|
['junction', (config, browser) => new SpliceJunctionTrack(config, browser)],
|
|
68852
69042
|
['blat', (config, browser) => new BlatTrack(config, browser)],
|
|
68853
|
-
['cnvpytor', (config, browser) => new CNVPytorTrack(config, browser)]
|
|
69043
|
+
['cnvpytor', (config, browser) => new CNVPytorTrack(config, browser)],
|
|
69044
|
+
['image', (config, browser) => new ImageTrack(config, browser)]
|
|
68854
69045
|
]);
|
|
68855
69046
|
|
|
68856
69047
|
|
|
@@ -69328,7 +69519,7 @@ ${indent}columns: ${matrix.columns}
|
|
|
69328
69519
|
})
|
|
69329
69520
|
}
|
|
69330
69521
|
|
|
69331
|
-
const _version = "3.2.
|
|
69522
|
+
const _version = "3.2.6";
|
|
69332
69523
|
function version() {
|
|
69333
69524
|
return _version
|
|
69334
69525
|
}
|
|
@@ -73871,7 +74062,7 @@ ${indent}columns: ${matrix.columns}
|
|
|
73871
74062
|
async loadTrackList(configList) {
|
|
73872
74063
|
|
|
73873
74064
|
// Impose an order if not specified
|
|
73874
|
-
let order =
|
|
74065
|
+
let order = this.trackViews.length + 1;
|
|
73875
74066
|
for (let c of configList) {
|
|
73876
74067
|
if (c.order === undefined) {
|
|
73877
74068
|
c.order = order++;
|