igv 3.3.0 → 3.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/igv.d.ts +665 -0
- package/dist/igv.esm.js +464 -150
- package/dist/igv.esm.min.js +9 -9
- package/dist/igv.esm.min.js.map +1 -1
- package/dist/igv.js +464 -150
- package/dist/igv.min.js +9 -9
- package/dist/igv.min.js.map +1 -1
- package/package.json +5 -3
package/dist/igv.js
CHANGED
|
@@ -379,7 +379,7 @@
|
|
|
379
379
|
* @param x
|
|
380
380
|
* @returns {boolean}
|
|
381
381
|
*/
|
|
382
|
-
function isString$
|
|
382
|
+
function isString$3(x) {
|
|
383
383
|
return typeof x === "string" || x instanceof String
|
|
384
384
|
}
|
|
385
385
|
|
|
@@ -479,7 +479,7 @@
|
|
|
479
479
|
|
|
480
480
|
if (urlOrFile.name !== undefined) {
|
|
481
481
|
return urlOrFile.name
|
|
482
|
-
} else if (isString$
|
|
482
|
+
} else if (isString$3(urlOrFile)) {
|
|
483
483
|
|
|
484
484
|
let index = urlOrFile.lastIndexOf("/");
|
|
485
485
|
let filename = index < 0 ? urlOrFile : urlOrFile.substr(index + 1);
|
|
@@ -10684,7 +10684,7 @@
|
|
|
10684
10684
|
};
|
|
10685
10685
|
|
|
10686
10686
|
async function getFilename$1(url) {
|
|
10687
|
-
if (isString$
|
|
10687
|
+
if (isString$3(url) && url.startsWith("https://drive.google.com")) {
|
|
10688
10688
|
// This will fail if Google API key is not defined
|
|
10689
10689
|
if (getApiKey() === undefined) {
|
|
10690
10690
|
throw Error("Google drive is referenced, but API key is not defined. An API key is required for Google Drive access")
|
|
@@ -10726,7 +10726,7 @@
|
|
|
10726
10726
|
|
|
10727
10727
|
|
|
10728
10728
|
function isDataURL(obj) {
|
|
10729
|
-
return (isString$
|
|
10729
|
+
return (isString$3(obj) && obj.startsWith("data:"))
|
|
10730
10730
|
}
|
|
10731
10731
|
|
|
10732
10732
|
function createColumn(columnContainer, className) {
|
|
@@ -10952,7 +10952,7 @@
|
|
|
10952
10952
|
return list;
|
|
10953
10953
|
}
|
|
10954
10954
|
|
|
10955
|
-
/*! @license DOMPurify 3.2.
|
|
10955
|
+
/*! @license DOMPurify 3.2.6 | (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.6/LICENSE */
|
|
10956
10956
|
|
|
10957
10957
|
const {
|
|
10958
10958
|
entries,
|
|
@@ -11156,7 +11156,7 @@
|
|
|
11156
11156
|
const TMPLIT_EXPR = seal(/\$\{[\w\W]*/gm); // eslint-disable-line unicorn/better-regex
|
|
11157
11157
|
const DATA_ATTR = seal(/^data-[\-\w.\u00B7-\uFFFF]+$/); // eslint-disable-line no-useless-escape
|
|
11158
11158
|
const ARIA_ATTR = seal(/^aria-[\-\w]+$/); // eslint-disable-line no-useless-escape
|
|
11159
|
-
const IS_ALLOWED_URI = seal(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i // eslint-disable-line no-useless-escape
|
|
11159
|
+
const IS_ALLOWED_URI = seal(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp|matrix):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i // eslint-disable-line no-useless-escape
|
|
11160
11160
|
);
|
|
11161
11161
|
const IS_SCRIPT_OR_DATA = seal(/^(?:\w+script|data):/i);
|
|
11162
11162
|
const ATTR_WHITESPACE = seal(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g // eslint-disable-line no-control-regex
|
|
@@ -11253,7 +11253,7 @@
|
|
|
11253
11253
|
function createDOMPurify() {
|
|
11254
11254
|
let window = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getGlobal();
|
|
11255
11255
|
const DOMPurify = root => createDOMPurify(root);
|
|
11256
|
-
DOMPurify.version = '3.2.
|
|
11256
|
+
DOMPurify.version = '3.2.6';
|
|
11257
11257
|
DOMPurify.removed = [];
|
|
11258
11258
|
if (!window || !window.document || window.document.nodeType !== NODE_TYPE.document || !window.Element) {
|
|
11259
11259
|
// Not running in a browser, provide a factory function
|
|
@@ -11492,8 +11492,8 @@
|
|
|
11492
11492
|
URI_SAFE_ATTRIBUTES = objectHasOwnProperty(cfg, 'ADD_URI_SAFE_ATTR') ? addToSet(clone(DEFAULT_URI_SAFE_ATTRIBUTES), cfg.ADD_URI_SAFE_ATTR, transformCaseFunc) : DEFAULT_URI_SAFE_ATTRIBUTES;
|
|
11493
11493
|
DATA_URI_TAGS = objectHasOwnProperty(cfg, 'ADD_DATA_URI_TAGS') ? addToSet(clone(DEFAULT_DATA_URI_TAGS), cfg.ADD_DATA_URI_TAGS, transformCaseFunc) : DEFAULT_DATA_URI_TAGS;
|
|
11494
11494
|
FORBID_CONTENTS = objectHasOwnProperty(cfg, 'FORBID_CONTENTS') ? addToSet({}, cfg.FORBID_CONTENTS, transformCaseFunc) : DEFAULT_FORBID_CONTENTS;
|
|
11495
|
-
FORBID_TAGS = objectHasOwnProperty(cfg, 'FORBID_TAGS') ? addToSet({}, cfg.FORBID_TAGS, transformCaseFunc) : {};
|
|
11496
|
-
FORBID_ATTR = objectHasOwnProperty(cfg, 'FORBID_ATTR') ? addToSet({}, cfg.FORBID_ATTR, transformCaseFunc) : {};
|
|
11495
|
+
FORBID_TAGS = objectHasOwnProperty(cfg, 'FORBID_TAGS') ? addToSet({}, cfg.FORBID_TAGS, transformCaseFunc) : clone({});
|
|
11496
|
+
FORBID_ATTR = objectHasOwnProperty(cfg, 'FORBID_ATTR') ? addToSet({}, cfg.FORBID_ATTR, transformCaseFunc) : clone({});
|
|
11497
11497
|
USE_PROFILES = objectHasOwnProperty(cfg, 'USE_PROFILES') ? cfg.USE_PROFILES : false;
|
|
11498
11498
|
ALLOW_ARIA_ATTR = cfg.ALLOW_ARIA_ATTR !== false; // Default true
|
|
11499
11499
|
ALLOW_DATA_ATTR = cfg.ALLOW_DATA_ATTR !== false; // Default true
|
|
@@ -11858,7 +11858,7 @@
|
|
|
11858
11858
|
allowedTags: ALLOWED_TAGS
|
|
11859
11859
|
});
|
|
11860
11860
|
/* Detect mXSS attempts abusing namespace confusion */
|
|
11861
|
-
if (currentNode.hasChildNodes() && !_isNode(currentNode.firstElementChild) && regExpTest(/<[/\w!]/g, currentNode.innerHTML) && regExpTest(/<[/\w!]/g, currentNode.textContent)) {
|
|
11861
|
+
if (SAFE_FOR_XML && currentNode.hasChildNodes() && !_isNode(currentNode.firstElementChild) && regExpTest(/<[/\w!]/g, currentNode.innerHTML) && regExpTest(/<[/\w!]/g, currentNode.textContent)) {
|
|
11862
11862
|
_forceRemove(currentNode);
|
|
11863
11863
|
return true;
|
|
11864
11864
|
}
|
|
@@ -12010,7 +12010,8 @@
|
|
|
12010
12010
|
value: attrValue
|
|
12011
12011
|
} = attr;
|
|
12012
12012
|
const lcName = transformCaseFunc(name);
|
|
12013
|
-
|
|
12013
|
+
const initValue = attrValue;
|
|
12014
|
+
let value = name === 'value' ? initValue : stringTrim(initValue);
|
|
12014
12015
|
/* Execute a hook if present */
|
|
12015
12016
|
hookEvent.attrName = lcName;
|
|
12016
12017
|
hookEvent.attrValue = value;
|
|
@@ -12036,10 +12037,9 @@
|
|
|
12036
12037
|
if (hookEvent.forceKeepAttr) {
|
|
12037
12038
|
continue;
|
|
12038
12039
|
}
|
|
12039
|
-
/* Remove attribute */
|
|
12040
|
-
_removeAttribute(name, currentNode);
|
|
12041
12040
|
/* Did the hooks approve of the attribute? */
|
|
12042
12041
|
if (!hookEvent.keepAttr) {
|
|
12042
|
+
_removeAttribute(name, currentNode);
|
|
12043
12043
|
continue;
|
|
12044
12044
|
}
|
|
12045
12045
|
/* Work around a security issue in jQuery 3.0 */
|
|
@@ -12056,6 +12056,7 @@
|
|
|
12056
12056
|
/* Is `value` valid for this attribute? */
|
|
12057
12057
|
const lcTag = transformCaseFunc(currentNode.nodeName);
|
|
12058
12058
|
if (!_isValidAttribute(lcTag, lcName, value)) {
|
|
12059
|
+
_removeAttribute(name, currentNode);
|
|
12059
12060
|
continue;
|
|
12060
12061
|
}
|
|
12061
12062
|
/* Handle attributes that require Trusted Types */
|
|
@@ -12076,19 +12077,23 @@
|
|
|
12076
12077
|
}
|
|
12077
12078
|
}
|
|
12078
12079
|
/* Handle invalid data-* attribute set by try-catching it */
|
|
12079
|
-
|
|
12080
|
-
|
|
12081
|
-
|
|
12082
|
-
|
|
12083
|
-
|
|
12084
|
-
|
|
12085
|
-
|
|
12086
|
-
|
|
12087
|
-
|
|
12088
|
-
|
|
12089
|
-
|
|
12080
|
+
if (value !== initValue) {
|
|
12081
|
+
try {
|
|
12082
|
+
if (namespaceURI) {
|
|
12083
|
+
currentNode.setAttributeNS(namespaceURI, name, value);
|
|
12084
|
+
} else {
|
|
12085
|
+
/* Fallback to setAttribute() for browser-unrecognized namespaces e.g. "x-schema". */
|
|
12086
|
+
currentNode.setAttribute(name, value);
|
|
12087
|
+
}
|
|
12088
|
+
if (_isClobbered(currentNode)) {
|
|
12089
|
+
_forceRemove(currentNode);
|
|
12090
|
+
} else {
|
|
12091
|
+
arrayPop(DOMPurify.removed);
|
|
12092
|
+
}
|
|
12093
|
+
} catch (_) {
|
|
12094
|
+
_removeAttribute(name, currentNode);
|
|
12090
12095
|
}
|
|
12091
|
-
}
|
|
12096
|
+
}
|
|
12092
12097
|
}
|
|
12093
12098
|
/* Execute a hook if present */
|
|
12094
12099
|
_executeHooks(hooks.afterSanitizeAttributes, currentNode, null);
|
|
@@ -16909,7 +16914,7 @@
|
|
|
16909
16914
|
*/
|
|
16910
16915
|
|
|
16911
16916
|
const fixColor = (colorString) => {
|
|
16912
|
-
if (isString$
|
|
16917
|
+
if (isString$3(colorString)) {
|
|
16913
16918
|
return (colorString.indexOf(",") > 0 && !(colorString.startsWith("rgb(") || colorString.startsWith("rgba("))) ?
|
|
16914
16919
|
`rgb(${colorString})` : colorString
|
|
16915
16920
|
} else {
|
|
@@ -16981,7 +16986,7 @@
|
|
|
16981
16986
|
this.name = config.name || config.label;
|
|
16982
16987
|
} else if (isFile(config.url)) {
|
|
16983
16988
|
this.name = config.url.name;
|
|
16984
|
-
} else if (isString$
|
|
16989
|
+
} else if (isString$3(config.url) && !config.url.startsWith("data:")) {
|
|
16985
16990
|
this.name = getFilename$2(config.url);
|
|
16986
16991
|
}
|
|
16987
16992
|
|
|
@@ -20903,7 +20908,7 @@
|
|
|
20903
20908
|
* THE SOFTWARE.
|
|
20904
20909
|
*/
|
|
20905
20910
|
|
|
20906
|
-
const isString$
|
|
20911
|
+
const isString$2 = isString$3;
|
|
20907
20912
|
|
|
20908
20913
|
|
|
20909
20914
|
class CustomServiceReader {
|
|
@@ -20942,7 +20947,7 @@
|
|
|
20942
20947
|
if (data) {
|
|
20943
20948
|
if (typeof this.config.parser === "function") {
|
|
20944
20949
|
features = this.config.parser(data);
|
|
20945
|
-
} else if (isString$
|
|
20950
|
+
} else if (isString$2(data)) {
|
|
20946
20951
|
features = JSON.parse(data);
|
|
20947
20952
|
} else {
|
|
20948
20953
|
features = data;
|
|
@@ -23025,7 +23030,7 @@
|
|
|
23025
23030
|
// TODO -- align all feature attribute names with UCSC, an use specific column
|
|
23026
23031
|
for (let key of Object.keys(f)) {
|
|
23027
23032
|
const v = f[key];
|
|
23028
|
-
if (isString$
|
|
23033
|
+
if (isString$3(v) && v.toLowerCase() === term.toLowerCase()) {
|
|
23029
23034
|
return true
|
|
23030
23035
|
}
|
|
23031
23036
|
}
|
|
@@ -23323,7 +23328,7 @@
|
|
|
23323
23328
|
class ZoomLevelHeader {
|
|
23324
23329
|
constructor(index, byteBuffer) {
|
|
23325
23330
|
this.index = index;
|
|
23326
|
-
this.reductionLevel = byteBuffer.
|
|
23331
|
+
this.reductionLevel = byteBuffer.getUInt();
|
|
23327
23332
|
this.reserved = byteBuffer.getInt();
|
|
23328
23333
|
this.dataOffset = byteBuffer.getLong();
|
|
23329
23334
|
this.indexOffset = byteBuffer.getLong();
|
|
@@ -27649,7 +27654,7 @@
|
|
|
27649
27654
|
fd.name &&
|
|
27650
27655
|
fd.name.toLowerCase() === "name" &&
|
|
27651
27656
|
fd.value &&
|
|
27652
|
-
isString$
|
|
27657
|
+
isString$3(fd.value) &&
|
|
27653
27658
|
!fd.value.startsWith("<")) {
|
|
27654
27659
|
const href = infoURL.replace("$$", feature.name);
|
|
27655
27660
|
fd.value = `<a target=_blank href=${href}>${fd.value}</a>`;
|
|
@@ -28293,7 +28298,7 @@
|
|
|
28293
28298
|
async postInit() {
|
|
28294
28299
|
if(!this.featureSource) {
|
|
28295
28300
|
// This will be the case when restoring from a session
|
|
28296
|
-
const db = this.browser.genome.
|
|
28301
|
+
const db = this.browser.genome.ucscID; // TODO -- blat specific property
|
|
28297
28302
|
const url = this.browser.config["blatServerURL"];
|
|
28298
28303
|
const features = await blat({url, userSeq: this.sequence, db});
|
|
28299
28304
|
this._features = features;
|
|
@@ -28310,7 +28315,7 @@
|
|
|
28310
28315
|
if (undefined === this.table) {
|
|
28311
28316
|
|
|
28312
28317
|
const rows = this._features.map(f => [
|
|
28313
|
-
f.chr,
|
|
28318
|
+
this.browser.genome.getChromosomeDisplayName(f.chr),
|
|
28314
28319
|
(f.start + 1),
|
|
28315
28320
|
f.end,
|
|
28316
28321
|
f.strand,
|
|
@@ -28385,7 +28390,7 @@
|
|
|
28385
28390
|
|
|
28386
28391
|
try {
|
|
28387
28392
|
|
|
28388
|
-
const db = browser.genome.
|
|
28393
|
+
const db = browser.genome.ucscID; // TODO -- blat specific property
|
|
28389
28394
|
const url = browser.config["blatServerURL"] || defaultBlatServer;
|
|
28390
28395
|
const features = await blat({url, userSeq: sequence, db});
|
|
28391
28396
|
|
|
@@ -30615,13 +30620,6 @@
|
|
|
30615
30620
|
this.trackStanzas = trackStanzas;
|
|
30616
30621
|
}
|
|
30617
30622
|
|
|
30618
|
-
findCytobandURL() {
|
|
30619
|
-
for (const t of this.trackStanzas) {
|
|
30620
|
-
if (t.name === "cytoBandIdeo" && t.hasProperty("bigDataUrl")) {
|
|
30621
|
-
return t.getProperty("bigDataUrl")
|
|
30622
|
-
}
|
|
30623
|
-
}
|
|
30624
|
-
}
|
|
30625
30623
|
|
|
30626
30624
|
getSupportedTrackCount() {
|
|
30627
30625
|
let count = 0;
|
|
@@ -30961,6 +30959,7 @@
|
|
|
30961
30959
|
|
|
30962
30960
|
const idMappings = new Map([
|
|
30963
30961
|
["hg38", "GCF_000001405.40"],
|
|
30962
|
+
["hg38_1kg", "GCF_000001405.40"],
|
|
30964
30963
|
["mm39", "GCF_000001635.27"],
|
|
30965
30964
|
["mm10", "GCF_000001635.26"],
|
|
30966
30965
|
["bosTau9", "GCF_002263795.1"],
|
|
@@ -30997,12 +30996,16 @@
|
|
|
30997
30996
|
this.genomeStanzas = genomeStanzas;
|
|
30998
30997
|
this.trackStanzas = trackStanzas;
|
|
30999
30998
|
this.groupStanzas = groupStanzas;
|
|
30999
|
+
this.cytobandStanza = null;
|
|
31000
31000
|
this.trackHubMap = new Map();
|
|
31001
31001
|
|
|
31002
31002
|
// trackStanzas will not be null if this is a "onefile" hub
|
|
31003
31003
|
if (trackStanzas) {
|
|
31004
31004
|
const genomeId = genomeStanzas[0].getProperty("genome"); // Assumption here this is a single genome hub
|
|
31005
31005
|
this.trackHubMap.set(genomeId, new TrackDbHub(trackStanzas, groupStanzas));
|
|
31006
|
+
|
|
31007
|
+
// Search for cytoband track. This supports a special but important case -- Genark assembly hubs
|
|
31008
|
+
this.cytobandStanza = this.trackStanzas.find(t => t.name === "cytoBandIdeo" && t.hasProperty("bigDataUrl")) || null;
|
|
31006
31009
|
}
|
|
31007
31010
|
}
|
|
31008
31011
|
|
|
@@ -31104,6 +31107,10 @@
|
|
|
31104
31107
|
config.twoBitBptURL = genomeStanza.getProperty("twoBitBptUrl");
|
|
31105
31108
|
}
|
|
31106
31109
|
|
|
31110
|
+
if(this.cytobandStanza){
|
|
31111
|
+
config.cytobandBbURL = this.cytobandStanza.getProperty("bigDataUrl");
|
|
31112
|
+
}
|
|
31113
|
+
|
|
31107
31114
|
if (this.hubStanza.hasProperty("longLabel")) {
|
|
31108
31115
|
config.description = this.hubStanza.getProperty("longLabel").replace("/", "\n");
|
|
31109
31116
|
} else {
|
|
@@ -31497,8 +31504,8 @@
|
|
|
31497
31504
|
return host
|
|
31498
31505
|
}
|
|
31499
31506
|
|
|
31500
|
-
const DEFAULT_GENOMES_URL = "https://igv.org/genomes/
|
|
31501
|
-
const BACKUP_GENOMES_URL = "https://raw.githubusercontent.com/igvteam/igv-
|
|
31507
|
+
const DEFAULT_GENOMES_URL = "https://igv.org/genomes/genomes3.json";
|
|
31508
|
+
const BACKUP_GENOMES_URL = "https://raw.githubusercontent.com/igvteam/igv-data/refs/heads/main/genomes/web/genomes.json";
|
|
31502
31509
|
|
|
31503
31510
|
const GenomeUtils = {
|
|
31504
31511
|
|
|
@@ -31523,7 +31530,7 @@
|
|
|
31523
31530
|
} catch (error) {
|
|
31524
31531
|
try {
|
|
31525
31532
|
console.error("Error initializing default genomes:", error);
|
|
31526
|
-
const jsonArray = await igvxhr.loadJson(BACKUP_GENOMES_URL, {timeout:
|
|
31533
|
+
const jsonArray = await igvxhr.loadJson(BACKUP_GENOMES_URL, {timeout: 10000});
|
|
31527
31534
|
processJson(jsonArray, table);
|
|
31528
31535
|
} catch (e) {
|
|
31529
31536
|
console.error("Error initializing backup genomes:", error);
|
|
@@ -31553,7 +31560,7 @@
|
|
|
31553
31560
|
expandReference: async function (alert, idOrConfig) {
|
|
31554
31561
|
|
|
31555
31562
|
// idOrConfig might be a json string? I'm actually not sure how this arises.
|
|
31556
|
-
if (isString$
|
|
31563
|
+
if (isString$3(idOrConfig) && idOrConfig.startsWith("{")) {
|
|
31557
31564
|
try {
|
|
31558
31565
|
idOrConfig = JSON.parse(idOrConfig);
|
|
31559
31566
|
} catch (e) {
|
|
@@ -31562,7 +31569,7 @@
|
|
|
31562
31569
|
}
|
|
31563
31570
|
|
|
31564
31571
|
let genomeID;
|
|
31565
|
-
if (isString$
|
|
31572
|
+
if (isString$3(idOrConfig)) {
|
|
31566
31573
|
genomeID = idOrConfig;
|
|
31567
31574
|
} else if (idOrConfig.genome) {
|
|
31568
31575
|
genomeID = idOrConfig.genome;
|
|
@@ -32508,7 +32515,7 @@
|
|
|
32508
32515
|
let track = this.trackView.track;
|
|
32509
32516
|
const dataList = track.popupData(clickState);
|
|
32510
32517
|
|
|
32511
|
-
const popupClickHandlerResult = this.browser.fireEvent('trackclick', [track, dataList]);
|
|
32518
|
+
const popupClickHandlerResult = this.browser.fireEvent('trackclick', [track, dataList, clickState.genomicLocation]);
|
|
32512
32519
|
|
|
32513
32520
|
let content;
|
|
32514
32521
|
if (undefined === popupClickHandlerResult || true === popupClickHandlerResult) {
|
|
@@ -40998,6 +41005,9 @@
|
|
|
40998
41005
|
return true
|
|
40999
41006
|
}
|
|
41000
41007
|
|
|
41008
|
+
/**
|
|
41009
|
+
* Track for segmented copy number, mut, maf and shoebox files.
|
|
41010
|
+
*/
|
|
41001
41011
|
class SegTrack extends TrackBase {
|
|
41002
41012
|
|
|
41003
41013
|
#sortDirections = new Map()
|
|
@@ -41145,7 +41155,10 @@
|
|
|
41145
41155
|
}, e);
|
|
41146
41156
|
}
|
|
41147
41157
|
|
|
41148
|
-
menuItems.push({
|
|
41158
|
+
menuItems.push({
|
|
41159
|
+
element: createElementWithString('<div>Set color scale threshold</div>'),
|
|
41160
|
+
dialog: dialogPresentationHandler
|
|
41161
|
+
});
|
|
41149
41162
|
}
|
|
41150
41163
|
|
|
41151
41164
|
menuItems.push('<hr/>');
|
|
@@ -41176,12 +41189,75 @@
|
|
|
41176
41189
|
|
|
41177
41190
|
getSamples() {
|
|
41178
41191
|
return {
|
|
41179
|
-
names: this.
|
|
41192
|
+
names: this.filteredSampleKeys,
|
|
41180
41193
|
height: this.sampleHeight,
|
|
41181
41194
|
yOffset: 0
|
|
41182
41195
|
}
|
|
41183
41196
|
}
|
|
41184
41197
|
|
|
41198
|
+
/**
|
|
41199
|
+
* Set the sample filter object. This is used to filter samples from the set based on values over a specified
|
|
41200
|
+
* genomic region. The values compared depend on the track data type:
|
|
41201
|
+
* - "seg" and "shoebox" -- average value over the region
|
|
41202
|
+
* - "mut" and "maf" -- count of features overlapping the region
|
|
41203
|
+
*
|
|
41204
|
+
* The method is asynchronous because it may need to fetch data from the server to compute the scores.
|
|
41205
|
+
* Computed scores are stored and used to filter the sample keys on demand.
|
|
41206
|
+
*
|
|
41207
|
+
* @param filterObject
|
|
41208
|
+
* @returns {Promise<void>}
|
|
41209
|
+
*/
|
|
41210
|
+
async setSampleFilter(filterObject) {
|
|
41211
|
+
if (!filterObject) {
|
|
41212
|
+
this.config.filterObject = undefined;
|
|
41213
|
+
this.filterObject = undefined;
|
|
41214
|
+
this.trackView.repaintViews();
|
|
41215
|
+
} else {
|
|
41216
|
+
const filterObjectCopy = Object.assign({}, filterObject);
|
|
41217
|
+
this.config.filterObject = filterObjectCopy;
|
|
41218
|
+
|
|
41219
|
+
filterObject.scores = await this.computeRegionScores(filterObject);
|
|
41220
|
+
this.filterObject = filterObject;
|
|
41221
|
+
this.trackView.checkContentHeight();
|
|
41222
|
+
this.trackView.repaintViews();
|
|
41223
|
+
}
|
|
41224
|
+
// TODO - store filter object in session
|
|
41225
|
+
}
|
|
41226
|
+
|
|
41227
|
+
|
|
41228
|
+
/**
|
|
41229
|
+
* Filter function for sample keys.
|
|
41230
|
+
*
|
|
41231
|
+
* @param sampleKey
|
|
41232
|
+
* @returns {boolean}
|
|
41233
|
+
*/
|
|
41234
|
+
filter(sampleKey) {
|
|
41235
|
+
if (this.filterObject) {
|
|
41236
|
+
const filterObject = this.filterObject;
|
|
41237
|
+
const scores = filterObject.scores;
|
|
41238
|
+
const score = scores[sampleKey];
|
|
41239
|
+
|
|
41240
|
+
if (this.type === 'seg') {
|
|
41241
|
+
if (filterObject.op === '>') {
|
|
41242
|
+
return score > filterObject.value
|
|
41243
|
+
} else if (filterObject.op === '<') {
|
|
41244
|
+
return score < filterObject.value
|
|
41245
|
+
}
|
|
41246
|
+
} else if (this.type === 'mut' || this.type === 'maf') {
|
|
41247
|
+
return 'HAS' === filterObject.op ? score : !score
|
|
41248
|
+
}
|
|
41249
|
+
}
|
|
41250
|
+
// else if (this.config.sampleFilter) {
|
|
41251
|
+
// return this.config.sampleFilter(sampleKey)
|
|
41252
|
+
// }
|
|
41253
|
+
return true
|
|
41254
|
+
}
|
|
41255
|
+
|
|
41256
|
+
get filteredSampleKeys() {
|
|
41257
|
+
return this.sampleKeys.filter(sampleKey => this.filter(sampleKey))
|
|
41258
|
+
}
|
|
41259
|
+
|
|
41260
|
+
|
|
41185
41261
|
async getFeatures(chr, start, end) {
|
|
41186
41262
|
const features = await this.featureSource.getFeatures({chr, start, end});
|
|
41187
41263
|
// New segments could conceivably add new samples
|
|
@@ -41189,8 +41265,10 @@
|
|
|
41189
41265
|
|
|
41190
41266
|
if (this.initialSort) {
|
|
41191
41267
|
const sort = this.initialSort;
|
|
41268
|
+
|
|
41192
41269
|
if (sort.option === undefined || sort.option.toUpperCase() === "VALUE") {
|
|
41193
|
-
|
|
41270
|
+
const sortFeatures = (sort.chr === chr && sort.start >= start && sort.end <= end) ? features : undefined;
|
|
41271
|
+
this.sortByValue(sort, sortFeatures);
|
|
41194
41272
|
} else if ("ATTRIBUTE" === sort.option.toUpperCase() && sort.attribute) {
|
|
41195
41273
|
const sortDirection = "DESC" === sort.direction ? 1 : -1;
|
|
41196
41274
|
this.sortByAttribute(sort.attribute, sortDirection);
|
|
@@ -41205,6 +41283,7 @@
|
|
|
41205
41283
|
|
|
41206
41284
|
IGVGraphics.fillRect(context, 0, pixelTop, pixelWidth, pixelHeight, {'fillStyle': "rgb(255, 255, 255)"});
|
|
41207
41285
|
|
|
41286
|
+
|
|
41208
41287
|
if (features && features.length > 0) {
|
|
41209
41288
|
|
|
41210
41289
|
this.checkForLog(features);
|
|
@@ -41216,14 +41295,15 @@
|
|
|
41216
41295
|
|
|
41217
41296
|
// Create a map for fast id -> row lookup
|
|
41218
41297
|
const samples = {};
|
|
41219
|
-
|
|
41298
|
+
const filteredKeys = this.filteredSampleKeys;
|
|
41299
|
+
filteredKeys.forEach(function (id, index) {
|
|
41220
41300
|
samples[id] = index;
|
|
41221
41301
|
});
|
|
41222
41302
|
|
|
41223
41303
|
let border;
|
|
41224
41304
|
switch (this.displayMode) {
|
|
41225
41305
|
case "FILL":
|
|
41226
|
-
this.sampleHeight = pixelHeight /
|
|
41306
|
+
this.sampleHeight = pixelHeight / filteredKeys.length;
|
|
41227
41307
|
border = 0;
|
|
41228
41308
|
break
|
|
41229
41309
|
|
|
@@ -41361,7 +41441,7 @@
|
|
|
41361
41441
|
if (!features) return 0
|
|
41362
41442
|
const sampleHeight = ("SQUISHED" === this.displayMode) ? this.squishedRowHeight : this.expandedRowHeight;
|
|
41363
41443
|
this.updateSampleKeys(features);
|
|
41364
|
-
return this.
|
|
41444
|
+
return this.filteredSampleKeys.length * sampleHeight
|
|
41365
41445
|
}
|
|
41366
41446
|
|
|
41367
41447
|
/**
|
|
@@ -41370,16 +41450,38 @@
|
|
|
41370
41450
|
async sortByValue(sort, featureList) {
|
|
41371
41451
|
|
|
41372
41452
|
const chr = sort.chr;
|
|
41453
|
+
const start = sort.position !== undefined ? sort.position - 1 : sort.start;
|
|
41454
|
+
const end = sort.end === undefined ? start + 1 : sort.end;
|
|
41455
|
+
const scores = await this.computeRegionScores({chr, start, end}, featureList);
|
|
41456
|
+
const d2 = (sort.direction === "ASC" ? 1 : -1);
|
|
41457
|
+
|
|
41458
|
+
this.sampleKeys.sort(function (a, b) {
|
|
41459
|
+
let s1 = scores[a];
|
|
41460
|
+
let s2 = scores[b];
|
|
41461
|
+
if (!s1) s1 = d2 * Number.MAX_VALUE;
|
|
41462
|
+
if (!s2) s2 = d2 * Number.MAX_VALUE;
|
|
41463
|
+
if (s1 === s2) return 0
|
|
41464
|
+
else if (s1 > s2) return d2
|
|
41465
|
+
else return d2 * -1
|
|
41466
|
+
});
|
|
41467
|
+
|
|
41468
|
+
this.config.sort = sort;
|
|
41469
|
+
this.trackView.repaintViews();
|
|
41470
|
+
}
|
|
41471
|
+
|
|
41472
|
+
|
|
41473
|
+
async computeRegionScores(filterObject, featureList) {
|
|
41474
|
+
|
|
41475
|
+
const chr = filterObject.chr;
|
|
41373
41476
|
let start, end;
|
|
41374
|
-
if (
|
|
41375
|
-
start =
|
|
41477
|
+
if (filterObject.position) {
|
|
41478
|
+
start = filterObject.position - 1;
|
|
41376
41479
|
end = start + 1;
|
|
41377
41480
|
} else {
|
|
41378
|
-
start =
|
|
41379
|
-
end =
|
|
41481
|
+
start = filterObject.start;
|
|
41482
|
+
end = filterObject.end;
|
|
41380
41483
|
}
|
|
41381
41484
|
|
|
41382
|
-
|
|
41383
41485
|
if (!featureList) {
|
|
41384
41486
|
featureList = await this.featureSource.getFeatures({chr, start, end});
|
|
41385
41487
|
}
|
|
@@ -41388,62 +41490,40 @@
|
|
|
41388
41490
|
this.updateSampleKeys(featureList);
|
|
41389
41491
|
|
|
41390
41492
|
const scores = {};
|
|
41391
|
-
const
|
|
41493
|
+
const bpLength = end - start + 1;
|
|
41494
|
+
|
|
41495
|
+
const mutationTypes = filterObject.value ? new Set(filterObject.value) : undefined;
|
|
41496
|
+
|
|
41497
|
+
for (let segment of featureList) {
|
|
41498
|
+
if (segment.end < start) continue
|
|
41499
|
+
if (segment.start > end) break
|
|
41500
|
+
const sampleKey = segment.sampleKey || segment.sample;
|
|
41501
|
+
|
|
41502
|
+
if ("mut" === this.type) {
|
|
41503
|
+
if (mutationTypes) {
|
|
41504
|
+
const mutationType = segment.getAttribute("Variant_Classification");
|
|
41505
|
+
if (mutationTypes.has(mutationType)) {
|
|
41506
|
+
// Just count features overlapping region per sample
|
|
41507
|
+
scores[sampleKey] = (scores[sampleKey] || 0) + 1;
|
|
41508
|
+
}
|
|
41509
|
+
} else {
|
|
41510
|
+
// Just count features overlapping region per sample
|
|
41511
|
+
scores[sampleKey] = (scores[sampleKey] || 0) + 1;
|
|
41512
|
+
}
|
|
41513
|
+
} else {
|
|
41392
41514
|
|
|
41393
|
-
const sortSeg = () => {
|
|
41394
|
-
// Compute weighted average score for each sample
|
|
41395
|
-
const bpLength = end - start + 1;
|
|
41396
|
-
for (let segment of featureList) {
|
|
41397
|
-
if (segment.end < start) continue
|
|
41398
|
-
if (segment.start > end) break
|
|
41399
41515
|
const min = Math.max(start, segment.start);
|
|
41400
41516
|
const max = Math.min(end, segment.end);
|
|
41401
41517
|
const f = (max - min) / bpLength;
|
|
41402
|
-
|
|
41403
|
-
|
|
41404
|
-
scores[sampleKey] = s + f * segment.value;
|
|
41405
|
-
}
|
|
41406
|
-
|
|
41407
|
-
// Now sort sample names by score
|
|
41408
|
-
this.sampleKeys.sort(function (a, b) {
|
|
41409
|
-
let s1 = scores[a];
|
|
41410
|
-
let s2 = scores[b];
|
|
41411
|
-
if (!s1) s1 = d2 * Number.MAX_VALUE;
|
|
41412
|
-
if (!s2) s2 = d2 * Number.MAX_VALUE;
|
|
41413
|
-
if (s1 === s2) return 0
|
|
41414
|
-
else if (s1 > s2) return d2
|
|
41415
|
-
else return d2 * -1
|
|
41416
|
-
});
|
|
41417
|
-
};
|
|
41418
|
-
|
|
41419
|
-
const sortMut = () => {
|
|
41420
|
-
// Compute weighted average score for each sample
|
|
41421
|
-
for (let segment of featureList) {
|
|
41422
|
-
if (segment.end < start) continue
|
|
41423
|
-
if (segment.start > end) break
|
|
41424
|
-
const sampleKey = segment.sampleKey || segment.sample;
|
|
41425
|
-
if (!scores.hasOwnProperty(sampleKey) || segment.value.localeCompare(scores[sampleKey]) > 0) {
|
|
41426
|
-
scores[sampleKey] = segment.value;
|
|
41427
|
-
}
|
|
41428
|
-
}
|
|
41429
|
-
// Now sort sample names by score
|
|
41430
|
-
this.sampleKeys.sort(function (a, b) {
|
|
41431
|
-
let sa = scores[a] || "";
|
|
41432
|
-
let sb = scores[b] || "";
|
|
41433
|
-
return d2 * (sa.localeCompare(sb))
|
|
41434
|
-
});
|
|
41435
|
-
};
|
|
41436
|
-
|
|
41437
|
-
if ("mut" === this.type) {
|
|
41438
|
-
sortMut();
|
|
41439
|
-
} else {
|
|
41440
|
-
sortSeg();
|
|
41518
|
+
scores[sampleKey] = (scores[sampleKey] || 0) + f * segment.value;
|
|
41519
|
+
}
|
|
41441
41520
|
}
|
|
41442
41521
|
|
|
41443
|
-
|
|
41522
|
+
return scores
|
|
41444
41523
|
|
|
41445
41524
|
}
|
|
41446
41525
|
|
|
41526
|
+
|
|
41447
41527
|
sortByAttribute(attribute, sortDirection) {
|
|
41448
41528
|
|
|
41449
41529
|
this.sampleKeys = this.browser.sampleInfo.getSortedSampleKeysByAttribute(this.sampleKeys, attribute, sortDirection);
|
|
@@ -41512,7 +41592,7 @@
|
|
|
41512
41592
|
const dirLabel = direction === "DESC" ? "descending" : "ascending";
|
|
41513
41593
|
const sortLabel = this.type === 'seg' || this.type === 'shoebox' ?
|
|
41514
41594
|
`Sort by value (${dirLabel})` :
|
|
41515
|
-
`Sort by
|
|
41595
|
+
`Sort by count (${dirLabel})`;
|
|
41516
41596
|
return {
|
|
41517
41597
|
label: sortLabel,
|
|
41518
41598
|
click: () => {
|
|
@@ -41524,7 +41604,6 @@
|
|
|
41524
41604
|
end: Math.floor(genomicLocation + bpWidth)
|
|
41525
41605
|
};
|
|
41526
41606
|
sortHandler(sort);
|
|
41527
|
-
this.config.sort = sort;
|
|
41528
41607
|
}
|
|
41529
41608
|
}
|
|
41530
41609
|
})
|
|
@@ -41694,13 +41773,13 @@
|
|
|
41694
41773
|
}
|
|
41695
41774
|
}
|
|
41696
41775
|
|
|
41697
|
-
popupData(genomicLocation) {
|
|
41776
|
+
popupData(genomicLocation, hiddenTags, showTags) {
|
|
41698
41777
|
|
|
41699
|
-
let nameValues = this.firstAlignment.popupData(genomicLocation);
|
|
41778
|
+
let nameValues = this.firstAlignment.popupData(genomicLocation, hiddenTags, showTags);
|
|
41700
41779
|
|
|
41701
41780
|
if (this.secondAlignment) {
|
|
41702
41781
|
nameValues.push("-------------------------------");
|
|
41703
|
-
nameValues = nameValues.concat(this.secondAlignment.popupData(genomicLocation));
|
|
41782
|
+
nameValues = nameValues.concat(this.secondAlignment.popupData(genomicLocation, hiddenTags, showTags));
|
|
41704
41783
|
}
|
|
41705
41784
|
return nameValues
|
|
41706
41785
|
}
|
|
@@ -43414,7 +43493,7 @@
|
|
|
43414
43493
|
isNegativeStrand() {
|
|
43415
43494
|
return (this.flags & READ_STRAND_FLAG$2) !== 0
|
|
43416
43495
|
}
|
|
43417
|
-
|
|
43496
|
+
|
|
43418
43497
|
isMateNegativeStrand() {
|
|
43419
43498
|
return (this.flags & MATE_STRAND_FLAG$2) !== 0
|
|
43420
43499
|
}
|
|
@@ -43462,7 +43541,7 @@
|
|
|
43462
43541
|
return (genomicLocation >= s && genomicLocation <= (s + l))
|
|
43463
43542
|
}
|
|
43464
43543
|
|
|
43465
|
-
popupData(genomicLocation) {
|
|
43544
|
+
popupData(genomicLocation, hiddenTags, showTags) {
|
|
43466
43545
|
|
|
43467
43546
|
// if the user clicks on a base next to an insertion, show just the
|
|
43468
43547
|
// inserted bases in a popup (like in desktop IGV).
|
|
@@ -43545,15 +43624,20 @@
|
|
|
43545
43624
|
}
|
|
43546
43625
|
}
|
|
43547
43626
|
|
|
43548
|
-
const hiddenTags = new Set(['SA', 'MD']);
|
|
43549
43627
|
nameValues.push('<hr/>');
|
|
43550
43628
|
for (let key in tagDict) {
|
|
43551
|
-
if (
|
|
43629
|
+
if (showTags?.has(key)) {
|
|
43630
|
+
nameValues.push({name: key, value: tagDict[key]});
|
|
43631
|
+
} else if (showTags) {
|
|
43632
|
+
hiddenTags.add(key);
|
|
43633
|
+
} else if (!hiddenTags.has(key)) {
|
|
43552
43634
|
nameValues.push({name: key, value: tagDict[key]});
|
|
43553
43635
|
}
|
|
43554
43636
|
}
|
|
43555
43637
|
|
|
43556
|
-
|
|
43638
|
+
if (hiddenTags && hiddenTags.size > 0) {
|
|
43639
|
+
nameValues.push({name: 'Hidden Tags', value: Array.from(hiddenTags).join(", ")});
|
|
43640
|
+
}
|
|
43557
43641
|
|
|
43558
43642
|
nameValues.push('<hr/>');
|
|
43559
43643
|
nameValues.push({name: 'Genomic Location: ', value: numberFormatter$1(1 + genomicLocation)});
|
|
@@ -43561,18 +43645,18 @@
|
|
|
43561
43645
|
nameValues.push({name: 'Base Quality:', value: this.readBaseQualityAt(genomicLocation)});
|
|
43562
43646
|
|
|
43563
43647
|
const bmSets = this.getBaseModificationSets();
|
|
43564
|
-
if(bmSets) {
|
|
43648
|
+
if (bmSets) {
|
|
43565
43649
|
const i = this.positionToReadIndex(genomicLocation);
|
|
43566
|
-
if(undefined !== i) {
|
|
43650
|
+
if (undefined !== i) {
|
|
43567
43651
|
let found = false;
|
|
43568
43652
|
for (let bmSet of bmSets) {
|
|
43569
43653
|
if (bmSet.containsPosition(i)) {
|
|
43570
|
-
if(!found) {
|
|
43654
|
+
if (!found) {
|
|
43571
43655
|
nameValues.push('<hr/>');
|
|
43572
43656
|
nameValues.push('<b>Base modifications:</b>');
|
|
43573
43657
|
found = true;
|
|
43574
43658
|
}
|
|
43575
|
-
const lh = Math.round((100/255) * byteToUnsignedInt(bmSet.likelihoods.get(i)));
|
|
43659
|
+
const lh = Math.round((100 / 255) * byteToUnsignedInt(bmSet.likelihoods.get(i)));
|
|
43576
43660
|
nameValues.push(`${bmSet.fullName()} @ likelihood = ${lh}%`);
|
|
43577
43661
|
}
|
|
43578
43662
|
}
|
|
@@ -43662,7 +43746,7 @@
|
|
|
43662
43746
|
const mm = this.tagDict["MM"] || this.tagDict["Mm"];
|
|
43663
43747
|
const ml = this.tagDict["ML"] || this.tagDict["Ml"];
|
|
43664
43748
|
|
|
43665
|
-
if (isString$
|
|
43749
|
+
if (isString$3(mm) && (!ml || Array.isArray(ml))) { // minimal validation, 10X uses these reserved tags for something completely different
|
|
43666
43750
|
if (mm.length === 0) {
|
|
43667
43751
|
this.baseModificationSets = EMPTY_SET;
|
|
43668
43752
|
} else {
|
|
@@ -43675,7 +43759,7 @@
|
|
|
43675
43759
|
return this.baseModificationSets
|
|
43676
43760
|
}
|
|
43677
43761
|
|
|
43678
|
-
|
|
43762
|
+
getGroupValue(groupBy, tag, expectedPairOrientation) {
|
|
43679
43763
|
|
|
43680
43764
|
const al = this;
|
|
43681
43765
|
switch (groupBy) {
|
|
@@ -43712,7 +43796,7 @@
|
|
|
43712
43796
|
}
|
|
43713
43797
|
}
|
|
43714
43798
|
|
|
43715
|
-
positionToReadIndex(
|
|
43799
|
+
positionToReadIndex(position) {
|
|
43716
43800
|
const block = blockAtGenomicLocation(this.blocks, position);
|
|
43717
43801
|
if (block) {
|
|
43718
43802
|
return (position - block.start) + block.seqOffset
|
|
@@ -45691,7 +45775,7 @@
|
|
|
45691
45775
|
|
|
45692
45776
|
function inferIndexPath(url, extension) {
|
|
45693
45777
|
|
|
45694
|
-
if (isString$
|
|
45778
|
+
if (isString$3(url)) {
|
|
45695
45779
|
if (url.includes("?")) {
|
|
45696
45780
|
const idx = url.indexOf("?");
|
|
45697
45781
|
return url.substring(0, idx) + "." + extension + url.substring(idx)
|
|
@@ -45850,7 +45934,7 @@
|
|
|
45850
45934
|
this.bamReader = new CramReader(config, genome, browser);
|
|
45851
45935
|
} else {
|
|
45852
45936
|
if (!this.config.indexURL && config.indexed !== false) {
|
|
45853
|
-
if (isString$
|
|
45937
|
+
if (isString$3(this.config.url)) {
|
|
45854
45938
|
const indexPath = inferIndexPath(this.config.url, "bai");
|
|
45855
45939
|
if (indexPath) {
|
|
45856
45940
|
console.warn(`Warning: no indexURL specified for ${this.config.url}. Guessing ${indexPath}`);
|
|
@@ -48162,7 +48246,7 @@
|
|
|
48162
48246
|
highlightColor: undefined,
|
|
48163
48247
|
minTLEN: undefined,
|
|
48164
48248
|
maxTLEN: undefined,
|
|
48165
|
-
tagColorPallete: "Set1"
|
|
48249
|
+
tagColorPallete: "Set1",
|
|
48166
48250
|
}
|
|
48167
48251
|
|
|
48168
48252
|
_colorTables = new Map()
|
|
@@ -48177,6 +48261,18 @@
|
|
|
48177
48261
|
this.colorTable = new ColorTable(config.tagColorTable);
|
|
48178
48262
|
}
|
|
48179
48263
|
|
|
48264
|
+
// Only one of showTags / hideTags should be specified. If both are specified showTags takes precedence.
|
|
48265
|
+
if (config.showTags && config.hideTags) {
|
|
48266
|
+
console.warn("Both showTags and hideTags specified. showTags will be used.");
|
|
48267
|
+
}
|
|
48268
|
+
if (config.showTags) {
|
|
48269
|
+
this.showTags = new Set(config.showTags);
|
|
48270
|
+
this.hiddenTags = new Set();
|
|
48271
|
+
} else {
|
|
48272
|
+
this.hiddenTags = new Set(config.hideTags || ["SA", "MD"]);
|
|
48273
|
+
}
|
|
48274
|
+
|
|
48275
|
+
|
|
48180
48276
|
// Backward compatibility overrides
|
|
48181
48277
|
if (config.largeFragmentLengthColor) this.largeTLENColor = config.largeFragmentLengthColor;
|
|
48182
48278
|
if (config.pairOrienation) this.expectedPairOrientation = config.pairOrientation;
|
|
@@ -48737,7 +48833,7 @@
|
|
|
48737
48833
|
|
|
48738
48834
|
popupData(clickState) {
|
|
48739
48835
|
const clickedObject = this.getClickedObject(clickState);
|
|
48740
|
-
return clickedObject
|
|
48836
|
+
return clickedObject?.popupData(clickState.genomicLocation, this.hiddenTags, this.showTags)
|
|
48741
48837
|
};
|
|
48742
48838
|
|
|
48743
48839
|
/**
|
|
@@ -48768,7 +48864,10 @@
|
|
|
48768
48864
|
colorByMenuItems.push({key: 'tlen', label: 'insert size (TLEN)'});
|
|
48769
48865
|
colorByMenuItems.push({key: 'unexpectedPair', label: 'pair orientation & insert size (TLEN)'});
|
|
48770
48866
|
}
|
|
48771
|
-
|
|
48867
|
+
if(this.colorBy && this.colorBy.startsWith("tag:")) {
|
|
48868
|
+
colorByMenuItems.push({key: this.colorBy, label: this.colorBy});
|
|
48869
|
+
}
|
|
48870
|
+
colorByMenuItems.push({key: 'tag', label: 'tag...'});
|
|
48772
48871
|
for (let item of colorByMenuItems) {
|
|
48773
48872
|
const selected = (this.colorBy === undefined && item.key === 'none') || this.colorBy === item.key;
|
|
48774
48873
|
menuItems.push(this.colorByCB(item, selected));
|
|
@@ -49494,14 +49593,19 @@
|
|
|
49494
49593
|
case "tag":
|
|
49495
49594
|
const tagValue = alignment.tags()[tag];
|
|
49496
49595
|
if (tagValue !== undefined) {
|
|
49497
|
-
|
|
49596
|
+
|
|
49597
|
+
// If the tag value can be interpreted as a color, use it
|
|
49598
|
+
if(typeof tagValue.startsWith === 'function') {
|
|
49498
49599
|
color = IGVColor.createColorStringSafe(tagValue);
|
|
49499
49600
|
}
|
|
49500
|
-
if (!this.colorTable) {
|
|
49501
|
-
this.colorTable = new PaletteColorTable(this.tagColorPallete);
|
|
49502
|
-
}
|
|
49503
|
-
color = this.colorTable.getColor(tagValue);
|
|
49504
49601
|
|
|
49602
|
+
// Tag value is not a color, use a color table
|
|
49603
|
+
if (!color) {
|
|
49604
|
+
if (!this.colorTable) {
|
|
49605
|
+
this.colorTable = new PaletteColorTable(this.tagColorPallete);
|
|
49606
|
+
}
|
|
49607
|
+
color = this.colorTable.getColor(tagValue);
|
|
49608
|
+
}
|
|
49505
49609
|
}
|
|
49506
49610
|
break
|
|
49507
49611
|
}
|
|
@@ -65718,7 +65822,7 @@ ${indent}columns: ${matrix.columns}
|
|
|
65718
65822
|
* THE SOFTWARE.
|
|
65719
65823
|
*/
|
|
65720
65824
|
|
|
65721
|
-
const isString = isString$
|
|
65825
|
+
const isString$1 = isString$3;
|
|
65722
65826
|
|
|
65723
65827
|
const DEFAULT_VISIBILITY_WINDOW = 1000000;
|
|
65724
65828
|
const TOP_MARGIN = 10;
|
|
@@ -65841,7 +65945,7 @@ ${indent}columns: ${matrix.columns}
|
|
|
65841
65945
|
}
|
|
65842
65946
|
if (undefined === this.visibilityWindow && this.config.indexed !== false) {
|
|
65843
65947
|
const fn = isFile(this.config.url) ? this.config.url.name : this.config.url;
|
|
65844
|
-
if (isString(fn) && fn.toLowerCase().includes("gnomad")) {
|
|
65948
|
+
if (isString$1(fn) && fn.toLowerCase().includes("gnomad")) {
|
|
65845
65949
|
this.visibilityWindow = 1000; // these are known to be very dense
|
|
65846
65950
|
} else if (typeof this.featureSource.defaultVisibilityWindow === 'function') {
|
|
65847
65951
|
this.visibilityWindow = await this.featureSource.defaultVisibilityWindow();
|
|
@@ -69725,6 +69829,9 @@ ${indent}columns: ${matrix.columns}
|
|
|
69725
69829
|
['image', (config, browser) => new ImageTrack(config, browser)]
|
|
69726
69830
|
]);
|
|
69727
69831
|
|
|
69832
|
+
function knownTrackTypes () {
|
|
69833
|
+
return new Set(trackFunctions.keys())
|
|
69834
|
+
}
|
|
69728
69835
|
|
|
69729
69836
|
/**
|
|
69730
69837
|
* Return a track of the given type, passing configuration and a point to the IGV "Browser" object to its constructor function*
|
|
@@ -70217,7 +70324,7 @@ ${indent}columns: ${matrix.columns}
|
|
|
70217
70324
|
})
|
|
70218
70325
|
}
|
|
70219
70326
|
|
|
70220
|
-
const _version = "3.
|
|
70327
|
+
const _version = "3.4.0";
|
|
70221
70328
|
function version() {
|
|
70222
70329
|
return _version
|
|
70223
70330
|
}
|
|
@@ -70268,7 +70375,7 @@ ${indent}columns: ${matrix.columns}
|
|
|
70268
70375
|
if (this.select.value.trim().toLowerCase() === "all" || this.select.value === "*") {
|
|
70269
70376
|
if (browser.genome.wholeGenomeView) {
|
|
70270
70377
|
const wgChr = browser.genome.getChromosome("all");
|
|
70271
|
-
|
|
70378
|
+
browser.updateLoci([{chr: "all", start: 0, end: wgChr.bpLength}]);
|
|
70272
70379
|
}
|
|
70273
70380
|
} else {
|
|
70274
70381
|
const chromosome = await browser.genome.loadChromosome(this.select.value);
|
|
@@ -72073,6 +72180,26 @@ ${indent}columns: ${matrix.columns}
|
|
|
72073
72180
|
}
|
|
72074
72181
|
|
|
72075
72182
|
|
|
72183
|
+
const found = this.browser.findTracks(track => typeof track.sortByValue === 'function');
|
|
72184
|
+
if (found.length > 0) {
|
|
72185
|
+
const { chr, start, end } = feature;
|
|
72186
|
+
items.push(
|
|
72187
|
+
'<hr/>',
|
|
72188
|
+
{
|
|
72189
|
+
label: 'Sort by value (ascending)',
|
|
72190
|
+
click: () => Promise.all(found.map(track => track.sortByValue({ option: 'VALUE', direction: 'ASC', chr, start, end })))
|
|
72191
|
+
});
|
|
72192
|
+
|
|
72193
|
+
items.push(
|
|
72194
|
+
'<hr/>',
|
|
72195
|
+
{
|
|
72196
|
+
label: 'Sort by value (descending)',
|
|
72197
|
+
click: () => Promise.all(found.map(track => track.sortByValue({ option: 'VALUE', direction: 'DESC', chr, start, end })))
|
|
72198
|
+
});
|
|
72199
|
+
|
|
72200
|
+
}
|
|
72201
|
+
|
|
72202
|
+
|
|
72076
72203
|
if (roiSet.isUserDefined) {
|
|
72077
72204
|
items.push(
|
|
72078
72205
|
'<hr/>',
|
|
@@ -72081,7 +72208,7 @@ ${indent}columns: ${matrix.columns}
|
|
|
72081
72208
|
click: async () => {
|
|
72082
72209
|
roiSet.removeFeature(feature);
|
|
72083
72210
|
const userDefinedFeatures = await roiSet.getAllFeatures();
|
|
72084
|
-
|
|
72211
|
+
|
|
72085
72212
|
// Delete user defined ROI Set if it is empty
|
|
72086
72213
|
if (Object.keys(userDefinedFeatures).length === 0) {
|
|
72087
72214
|
roiManager.deleteUserDefinedROISet();
|
|
@@ -73254,6 +73381,189 @@ ${indent}columns: ${matrix.columns}
|
|
|
73254
73381
|
|
|
73255
73382
|
}
|
|
73256
73383
|
|
|
73384
|
+
/**
|
|
73385
|
+
* Update deprecated fasta & index urls in the reference object.
|
|
73386
|
+
*/
|
|
73387
|
+
|
|
73388
|
+
const isString = (x) => {
|
|
73389
|
+
return (x && typeof x === "string") || x instanceof String
|
|
73390
|
+
};
|
|
73391
|
+
|
|
73392
|
+
/**
|
|
73393
|
+
* Replaces deprecated s3 fasta URLs with twoBitURLs. The purpose here is to rescue references from saved sessions
|
|
73394
|
+
* that contain pointers to deprectated IGV s3 buckets. These buckets will eventually be deleted
|
|
73395
|
+
*
|
|
73396
|
+
* @param reference
|
|
73397
|
+
*/
|
|
73398
|
+
function updateReference(reference) {
|
|
73399
|
+
|
|
73400
|
+
if (!(requiresUpdate(reference) && updates[reference.id])) {
|
|
73401
|
+
return
|
|
73402
|
+
}
|
|
73403
|
+
|
|
73404
|
+
const updatedReference = updates[reference.id];
|
|
73405
|
+
if (updatedReference) {
|
|
73406
|
+
delete reference.fastaURL;
|
|
73407
|
+
if (reference.indexURL) delete reference.indexURL;
|
|
73408
|
+
reference.twoBitURL = updatedReference.twoBitURL;
|
|
73409
|
+
if (updatedReference.twoBitBptURL) reference.twoBitBptURL = updatedReference.twoBitBptURL;
|
|
73410
|
+
if (updatedReference.chromSizesURL) reference.chromSizesURL = updatedReference.chromSizesURL;
|
|
73411
|
+
}
|
|
73412
|
+
}
|
|
73413
|
+
|
|
73414
|
+
function requiresUpdate(reference) {
|
|
73415
|
+
return isString(reference.fastaURL) &&
|
|
73416
|
+
(reference.fastaURL.startsWith("https://igv.org") ||
|
|
73417
|
+
["igv.org.genomes", "igv.broadinstitute.org", "igv.genepattern.org", "igvdata.broadinstitute.org",
|
|
73418
|
+
"igv-genepattern-org"].some(bucket => reference.fastaURL.includes(bucket)))
|
|
73419
|
+
}
|
|
73420
|
+
|
|
73421
|
+
const updates = {
|
|
73422
|
+
"hs1": {
|
|
73423
|
+
"twoBitURL": "https://hgdownload.soe.ucsc.edu/goldenPath/hs1/bigZips/hs1.2bit",
|
|
73424
|
+
"twoBitBptURL": "https://hgdownload.soe.ucsc.edu/goldenPath/hs1/bigZips/hs1.2bit.bpt",
|
|
73425
|
+
"chromSizesURL": "https://hgdownload.soe.ucsc.edu/goldenPath/hs1/bigZips/hs1.chrom.sizes.txt"
|
|
73426
|
+
},
|
|
73427
|
+
"hg38": {
|
|
73428
|
+
"twoBitURL": "https://hgdownload.soe.ucsc.edu/goldenPath/hg38/bigZips/hg38.2bit",
|
|
73429
|
+
"chromSizesURL": "https://hgdownload.soe.ucsc.edu/goldenPath/hg38/bigZips/hg38.chrom.sizes"
|
|
73430
|
+
},
|
|
73431
|
+
"hg19": {
|
|
73432
|
+
"twoBitURL": "https://hgdownload.soe.ucsc.edu/goldenPath/hg19/bigZips/hg19.2bit",
|
|
73433
|
+
"chromSizesURL": "https://hgdownload.soe.ucsc.edu/goldenPath/hg19/bigZips/hg19.chrom.sizes"
|
|
73434
|
+
},
|
|
73435
|
+
"hg18": {
|
|
73436
|
+
"twoBitURL": "https://hgdownload.soe.ucsc.edu/goldenPath/hg18/bigZips/hg18.2bit",
|
|
73437
|
+
"chromSizesURL": "https://hgdownload.soe.ucsc.edu/goldenPath/hg18/bigZips/hg18.chrom.sizes"
|
|
73438
|
+
},
|
|
73439
|
+
"mm39": {
|
|
73440
|
+
"twoBitURL": "https://hgdownload.soe.ucsc.edu/goldenPath/mm39/bigZips/mm39.2bit",
|
|
73441
|
+
"chromSizesURL": "https://hgdownload.soe.ucsc.edu/goldenPath/mm39/bigZips/mm39.chrom.sizes"
|
|
73442
|
+
},
|
|
73443
|
+
"mm10": {
|
|
73444
|
+
"twoBitURL": "https://hgdownload.soe.ucsc.edu/goldenPath/mm10/bigZips/mm10.2bit",
|
|
73445
|
+
"chromSizesURL": "https://hgdownload.soe.ucsc.edu/goldenPath/mm10/bigZips/mm10.chrom.sizes"
|
|
73446
|
+
},
|
|
73447
|
+
"mm9": {
|
|
73448
|
+
"twoBitURL": "https://hgdownload.soe.ucsc.edu/goldenPath/mm9/bigZips/mm9.2bit",
|
|
73449
|
+
"chromSizesURL": "https://hgdownload.soe.ucsc.edu/goldenPath/mm9/bigZips/mm9.chrom.sizes"
|
|
73450
|
+
},
|
|
73451
|
+
"rn7": {
|
|
73452
|
+
"twoBitURL": "https://hgdownload.soe.ucsc.edu/hubs/GCF/015/227/675/GCF_015227675.2/GCF_015227675.2.2bit",
|
|
73453
|
+
"twoBitBptURL": "https://hgdownload.soe.ucsc.edu/hubs/GCF/015/227/675/GCF_015227675.2/GCF_015227675.2.2bit.bpt",
|
|
73454
|
+
"chromSizesURL": "https://hgdownload.soe.ucsc.edu/hubs/GCF/015/227/675/GCF_015227675.2/GCF_015227675.2.chrom.sizes.txt"
|
|
73455
|
+
},
|
|
73456
|
+
"rn6": {
|
|
73457
|
+
"twoBitURL": "https://hgdownload.soe.ucsc.edu/hubs/GCF/000/001/895/GCF_000001895.5/GCF_000001895.5.2bit",
|
|
73458
|
+
"twoBitBptURL": "https://hgdownload.soe.ucsc.edu/hubs/GCF/000/001/895/GCF_000001895.5/GCF_000001895.5.2bit.bpt",
|
|
73459
|
+
"chromSizesURL": "https://hgdownload.soe.ucsc.edu/hubs/GCF/000/001/895/GCF_000001895.5/GCF_000001895.5.chrom.sizes.txt"
|
|
73460
|
+
},
|
|
73461
|
+
"gorGor6": {
|
|
73462
|
+
"twoBitURL": "https://hgdownload.soe.ucsc.edu/goldenPath/gorGor6/bigZips/gorGor6.2bit",
|
|
73463
|
+
"chromSizesURL": "https://hgdownload.soe.ucsc.edu/goldenPath/gorGor6/bigZips/gorGor6.chrom.sizes"
|
|
73464
|
+
},
|
|
73465
|
+
"gorGor4": {
|
|
73466
|
+
"twoBitURL": "https://hgdownload.soe.ucsc.edu/goldenPath/gorGor4/bigZips/gorGor4.2bit",
|
|
73467
|
+
"chromSizesURL": "https://hgdownload.soe.ucsc.edu/goldenPath/gorGor4/bigZips/gorGor4.chrom.sizes"
|
|
73468
|
+
},
|
|
73469
|
+
"panTro6": {
|
|
73470
|
+
"twoBitURL": "https://hgdownload.soe.ucsc.edu/goldenPath/panTro6/bigZips/panTro6.2bit",
|
|
73471
|
+
"chromSizesURL": "https://hgdownload.soe.ucsc.edu/goldenPath/panTro6/bigZips/panTro6.chrom.sizes"
|
|
73472
|
+
},
|
|
73473
|
+
"panTro5": {
|
|
73474
|
+
"twoBitURL": "https://hgdownload.soe.ucsc.edu/goldenPath/panTro5/bigZips/panTro5.2bit",
|
|
73475
|
+
"chromSizesURL": "https://hgdownload.soe.ucsc.edu/goldenPath/panTro5/bigZips/panTro5.chrom.sizes"
|
|
73476
|
+
},
|
|
73477
|
+
"panTro4": {
|
|
73478
|
+
"twoBitURL": "https://hgdownload.soe.ucsc.edu/goldenPath/panTro4/bigZips/panTro4.2bit",
|
|
73479
|
+
"chromSizesURL": "https://hgdownload.soe.ucsc.edu/goldenPath/panTro4/bigZips/panTro4.chrom.sizes"
|
|
73480
|
+
},
|
|
73481
|
+
"macFas5": {
|
|
73482
|
+
"twoBitURL": "https://hgdownload.soe.ucsc.edu/goldenPath/macFas5/bigZips/macFas5.2bit",
|
|
73483
|
+
"chromSizesURL": "https://hgdownload.soe.ucsc.edu/goldenPath/macFas5/bigZips/macFas5.chrom.sizes"
|
|
73484
|
+
},
|
|
73485
|
+
"panPan2": {
|
|
73486
|
+
"twoBitURL": "https://hgdownload.soe.ucsc.edu/goldenPath/panPan2/bigZips/panPan2.2bit",
|
|
73487
|
+
"chromSizesURL": "https://hgdownload.soe.ucsc.edu/goldenPath/panPan2/bigZips/panPan2.chrom.sizes"
|
|
73488
|
+
},
|
|
73489
|
+
"canFam6": {
|
|
73490
|
+
"twoBitURL": "https://hgdownload.soe.ucsc.edu/goldenPath/canFam6/bigZips/canFam6.2bit",
|
|
73491
|
+
"chromSizesURL": "https://hgdownload.soe.ucsc.edu/goldenPath/canFam6/bigZips/canFam6.chrom.sizes"
|
|
73492
|
+
},
|
|
73493
|
+
"canFam5": {
|
|
73494
|
+
"twoBitURL": "https://hgdownload.soe.ucsc.edu/goldenPath/canFam5/bigZips/canFam5.2bit",
|
|
73495
|
+
"chromSizesURL": "https://hgdownload.soe.ucsc.edu/goldenPath/canFam5/bigZips/canFam5.chrom.sizes"
|
|
73496
|
+
},
|
|
73497
|
+
"canFam4": {
|
|
73498
|
+
"twoBitURL": "https://hgdownload.soe.ucsc.edu/goldenPath/canFam4/bigZips/canFam4.2bit",
|
|
73499
|
+
"chromSizesURL": "https://hgdownload.soe.ucsc.edu/goldenPath/canFam4/bigZips/canFam4.chrom.sizes"
|
|
73500
|
+
},
|
|
73501
|
+
"canFam3": {
|
|
73502
|
+
"twoBitURL": "https://hgdownload.soe.ucsc.edu/goldenPath/canFam3/bigZips/canFam3.2bit",
|
|
73503
|
+
"chromSizesURL": "https://hgdownload.soe.ucsc.edu/goldenPath/canFam3/bigZips/canFam3.chrom.sizes"
|
|
73504
|
+
},
|
|
73505
|
+
"bosTau9": {
|
|
73506
|
+
"twoBitURL": "https://hgdownload.soe.ucsc.edu/goldenPath/bosTau9/bigZips/bosTau9.2bit",
|
|
73507
|
+
"chromSizesURL": "https://hgdownload.soe.ucsc.edu/goldenPath/bosTau9/bigZips/bosTau9.chrom.sizes"
|
|
73508
|
+
},
|
|
73509
|
+
"bosTau8": {
|
|
73510
|
+
"twoBitURL": "https://hgdownload.soe.ucsc.edu/goldenPath/bosTau8/bigZips/bosTau8.2bit",
|
|
73511
|
+
"chromSizesURL": "https://hgdownload.soe.ucsc.edu/goldenPath/bosTau8/bigZips/bosTau8.chrom.sizes"
|
|
73512
|
+
},
|
|
73513
|
+
"susScr11": {
|
|
73514
|
+
"twoBitURL": "https://hgdownload.soe.ucsc.edu/goldenPath/susScr11/bigZips/susScr11.2bit",
|
|
73515
|
+
"chromSizesURL": "https://hgdownload.soe.ucsc.edu/goldenPath/susScr11/bigZips/susScr11.chrom.sizes"
|
|
73516
|
+
},
|
|
73517
|
+
"galGal6": {
|
|
73518
|
+
"twoBitURL": "https://hgdownload.soe.ucsc.edu/goldenPath/galGal6/bigZips/galGal6.2bit",
|
|
73519
|
+
"chromSizesURL": "https://hgdownload.soe.ucsc.edu/goldenPath/galGal6/bigZips/galGal6.chrom.sizes"
|
|
73520
|
+
},
|
|
73521
|
+
"danRer11": {
|
|
73522
|
+
"twoBitURL": "https://hgdownload.soe.ucsc.edu/goldenPath/danRer11/bigZips/danRer11.2bit",
|
|
73523
|
+
"chromSizesURL": "https://hgdownload.soe.ucsc.edu/goldenPath/danRer11/bigZips/danRer11.chrom.sizes"
|
|
73524
|
+
},
|
|
73525
|
+
"danRer10": {
|
|
73526
|
+
"twoBitURL": "https://hgdownload.soe.ucsc.edu/goldenPath/danRer10/bigZips/danRer10.2bit",
|
|
73527
|
+
"chromSizesURL": "https://hgdownload.soe.ucsc.edu/goldenPath/danRer10/bigZips/danRer10.chrom.sizes"
|
|
73528
|
+
},
|
|
73529
|
+
"ce11": {
|
|
73530
|
+
"twoBitURL": "https://hgdownload.soe.ucsc.edu/goldenPath/ce11/bigZips/ce11.2bit",
|
|
73531
|
+
"chromSizesURL": "https://hgdownload.soe.ucsc.edu/goldenPath/ce11/bigZips/ce11.chrom.sizes"
|
|
73532
|
+
},
|
|
73533
|
+
"dm6": {
|
|
73534
|
+
"twoBitURL": "https://hgdownload.soe.ucsc.edu/goldenPath/dm6/bigZips/dm6.2bit",
|
|
73535
|
+
"chromSizesURL": "https://hgdownload.soe.ucsc.edu/goldenPath/dm6/bigZips/dm6.chrom.sizes"
|
|
73536
|
+
},
|
|
73537
|
+
"dm3": {
|
|
73538
|
+
"twoBitURL": "https://hgdownload.soe.ucsc.edu/goldenPath/dm3/bigZips/dm3.2bit",
|
|
73539
|
+
"chromSizesURL": "https://hgdownload.soe.ucsc.edu/goldenPath/dm3/bigZips/dm3.chrom.sizes"
|
|
73540
|
+
},
|
|
73541
|
+
"sacCer3": {
|
|
73542
|
+
"twoBitURL": "https://hgdownload.soe.ucsc.edu/hubs/GCF/000/146/045/GCF_000146045.2/GCF_000146045.2.2bit",
|
|
73543
|
+
"twoBitBptURL": "https://hgdownload.soe.ucsc.edu/hubs/GCF/000/146/045/GCF_000146045.2/GCF_000146045.2.2bit.bpt",
|
|
73544
|
+
"chromSizesURL": "https://hgdownload.soe.ucsc.edu/hubs/GCF/000/146/045/GCF_000146045.2/GCF_000146045.2.chrom.sizes.txt"
|
|
73545
|
+
},
|
|
73546
|
+
"GCF_000002945.1": {
|
|
73547
|
+
"twoBitURL": "https://hgdownload.soe.ucsc.edu/hubs/GCF/000/002/945/GCF_000002945.1/GCF_000002945.1.2bit",
|
|
73548
|
+
"twoBitBptURL": "https://hgdownload.soe.ucsc.edu/hubs/GCF/000/002/945/GCF_000002945.1/GCF_000002945.1.2bit.bpt",
|
|
73549
|
+
"chromSizesURL": "https://hgdownload.soe.ucsc.edu/hubs/GCF/000/002/945/GCF_000002945.1/GCF_000002945.1.chrom.sizes.txt"
|
|
73550
|
+
},
|
|
73551
|
+
"GCF_009858895.2": {
|
|
73552
|
+
"twoBitURL": "https://hgdownload.soe.ucsc.edu/hubs/GCF/009/858/895/GCF_009858895.2/GCF_009858895.2.2bit",
|
|
73553
|
+
"twoBitBptURL": "https://hgdownload.soe.ucsc.edu/hubs/GCF/009/858/895/GCF_009858895.2/GCF_009858895.2.2bit.bpt",
|
|
73554
|
+
"chromSizesURL": "https://hgdownload.soe.ucsc.edu/hubs/GCF/009/858/895/GCF_009858895.2/GCF_009858895.2.chrom.sizes.txt"
|
|
73555
|
+
},
|
|
73556
|
+
"tair10": {
|
|
73557
|
+
"twoBitURL": "https://hgdownload.soe.ucsc.edu/hubs/GCF/000/001/735/GCF_000001735.3/GCF_000001735.3.2bit",
|
|
73558
|
+
"chromSizesURL": "https://hgdownload.soe.ucsc.edu/hubs/GCF/000/001/735/GCF_000001735.3/GCF_000001735.3.chrom.sizes.txt"
|
|
73559
|
+
},
|
|
73560
|
+
"GCA_000022165.1": {
|
|
73561
|
+
"twoBitURL": "https://hgdownload.soe.ucsc.edu/hubs/GCA/000/022/165/GCA_000022165.1/GCA_000022165.1.2bit",
|
|
73562
|
+
"twoBitBptURL": "https://hgdownload.soe.ucsc.edu/hubs/GCA/000/022/165/GCA_000022165.1/GCA_000022165.1.2bit.bpt",
|
|
73563
|
+
"chromSizesURL": "https://hgdownload.soe.ucsc.edu/hubs/GCA/000/022/165/GCA_000022165.1/GCA_000022165.1.chrom.sizes.txt"
|
|
73564
|
+
}
|
|
73565
|
+
};
|
|
73566
|
+
|
|
73257
73567
|
const ucsdIDMap = new Map([
|
|
73258
73568
|
["1kg_ref", "hg18"],
|
|
73259
73569
|
["1kg_v37", "hg19"],
|
|
@@ -73275,6 +73585,7 @@ ${indent}columns: ${matrix.columns}
|
|
|
73275
73585
|
|
|
73276
73586
|
static async createGenome(options, browser) {
|
|
73277
73587
|
|
|
73588
|
+
updateReference(options);
|
|
73278
73589
|
const genome = new Genome(options, browser);
|
|
73279
73590
|
await genome.init();
|
|
73280
73591
|
return genome
|
|
@@ -73298,7 +73609,6 @@ ${indent}columns: ${matrix.columns}
|
|
|
73298
73609
|
// Load sequence
|
|
73299
73610
|
this.sequence = await loadSequence(config, this.browser);
|
|
73300
73611
|
|
|
73301
|
-
|
|
73302
73612
|
// Load cytobands. This is optional but required to support the ideogram. Only needed for whole genome view
|
|
73303
73613
|
if(false !== config.showIdeogram && false !== config.wholeGenomeView) {
|
|
73304
73614
|
if (config.cytobandURL) {
|
|
@@ -73342,10 +73652,14 @@ ${indent}columns: ${matrix.columns}
|
|
|
73342
73652
|
} else {
|
|
73343
73653
|
this.#wgChromosomeNames = config.chromosomeOrder.split(',').map(nm => nm.trim());
|
|
73344
73654
|
}
|
|
73655
|
+
// Trim to remove non-existent chromosomes
|
|
73656
|
+
await this.chromAlias.preload(this.#wgChromosomeNames);
|
|
73657
|
+
this.#wgChromosomeNames =
|
|
73658
|
+
this.#wgChromosomeNames.map(c => this.getChromosomeName(c)).filter(c => this.chromosomes.has(c));
|
|
73345
73659
|
} else {
|
|
73346
73660
|
this.#wgChromosomeNames = trimSmallChromosomes(this.chromosomes);
|
|
73661
|
+
await this.chromAlias.preload(this.#wgChromosomeNames);
|
|
73347
73662
|
}
|
|
73348
|
-
await this.chromAlias.preload(this.#wgChromosomeNames);
|
|
73349
73663
|
}
|
|
73350
73664
|
|
|
73351
73665
|
// Optionally create the psuedo chromosome "all" to support whole genome view
|
|
@@ -73618,7 +73932,7 @@ ${indent}columns: ${matrix.columns}
|
|
|
73618
73932
|
function generateGenomeID(config) {
|
|
73619
73933
|
if (config.id !== undefined) {
|
|
73620
73934
|
return config.id
|
|
73621
|
-
} else if (config.fastaURL && isString$
|
|
73935
|
+
} else if (config.fastaURL && isString$3(config.fastaURL) && !config.fastaURL.startsWith("data:")) {
|
|
73622
73936
|
return config.fastaURL
|
|
73623
73937
|
} else if (config.fastaURL && config.fastaURL.name) {
|
|
73624
73938
|
return config.fastaURL.name
|
|
@@ -74351,7 +74665,7 @@ ${indent}columns: ${matrix.columns}
|
|
|
74351
74665
|
const urlOrFile = options.url || options.file;
|
|
74352
74666
|
|
|
74353
74667
|
let config;
|
|
74354
|
-
if (options.url && isString$
|
|
74668
|
+
if (options.url && isString$3(options.url) && (options.url.startsWith("blob:") || options.url.startsWith("data:"))) {
|
|
74355
74669
|
const json = Browser.uncompressSession(options.url);
|
|
74356
74670
|
config = JSON.parse(json);
|
|
74357
74671
|
} else {
|
|
@@ -74430,7 +74744,7 @@ ${indent}columns: ${matrix.columns}
|
|
|
74430
74744
|
return
|
|
74431
74745
|
}
|
|
74432
74746
|
|
|
74433
|
-
const genomeConfig = isString$
|
|
74747
|
+
const genomeConfig = isString$3(genomeOrReference) ?
|
|
74434
74748
|
await GenomeUtils.expandReference(this.alert, genomeOrReference) :
|
|
74435
74749
|
genomeOrReference;
|
|
74436
74750
|
|
|
@@ -74552,7 +74866,7 @@ ${indent}columns: ${matrix.columns}
|
|
|
74552
74866
|
}
|
|
74553
74867
|
|
|
74554
74868
|
/**
|
|
74555
|
-
* Load a reference genome object. This includes the
|
|
74869
|
+
* Load a reference genome object. This includes the sequence, and optional cytoband, but no tracks. This method
|
|
74556
74870
|
* is used by loadGenome and loadSession.
|
|
74557
74871
|
*
|
|
74558
74872
|
* @param genomeConfig
|
|
@@ -74617,7 +74931,7 @@ ${indent}columns: ${matrix.columns}
|
|
|
74617
74931
|
|
|
74618
74932
|
// Translate the generic "url" field, used by clients such as igv-webapp
|
|
74619
74933
|
if (idOrConfig.url) {
|
|
74620
|
-
if (isString$
|
|
74934
|
+
if (isString$3(idOrConfig.url) && idOrConfig.url.endsWith("/hub.txt")) {
|
|
74621
74935
|
idOrConfig.hubURL = idOrConfig.url;
|
|
74622
74936
|
delete idOrConfig.url;
|
|
74623
74937
|
} else if ("gbk" === getFileExtension(idOrConfig.url)) {
|
|
@@ -74627,11 +74941,11 @@ ${indent}columns: ${matrix.columns}
|
|
|
74627
74941
|
}
|
|
74628
74942
|
|
|
74629
74943
|
let genomeConfig;
|
|
74630
|
-
const isHubGenome = idOrConfig.hubURL || (idOrConfig.url && isString$
|
|
74944
|
+
const isHubGenome = idOrConfig.hubURL || (idOrConfig.url && isString$3(idOrConfig.url) && idOrConfig.url.endsWith("/hub.txt"));
|
|
74631
74945
|
if (isHubGenome) {
|
|
74632
74946
|
const hub = await loadHub(idOrConfig.hubURL || idOrConfig.url);
|
|
74633
74947
|
genomeConfig = hub.getGenomeConfig();
|
|
74634
|
-
} else if (isString$
|
|
74948
|
+
} else if (isString$3(idOrConfig) || !(idOrConfig.url || idOrConfig.fastaURL || idOrConfig.twoBitURL || idOrConfig.gbkURL)) {
|
|
74635
74949
|
// Either an ID, a json string, or an object missing required properties.
|
|
74636
74950
|
genomeConfig = await GenomeUtils.expandReference(this.alert, idOrConfig);
|
|
74637
74951
|
} else {
|
|
@@ -74798,7 +75112,7 @@ ${indent}columns: ${matrix.columns}
|
|
|
74798
75112
|
async #loadTrackHelper(config) {
|
|
74799
75113
|
|
|
74800
75114
|
// config might be json
|
|
74801
|
-
if (isString$
|
|
75115
|
+
if (isString$3(config)) {
|
|
74802
75116
|
config = JSON.parse(config);
|
|
74803
75117
|
}
|
|
74804
75118
|
|
|
@@ -74928,7 +75242,7 @@ ${indent}columns: ${matrix.columns}
|
|
|
74928
75242
|
|
|
74929
75243
|
// Resolve function and promise urls
|
|
74930
75244
|
let url = await resolveURL(config.url || config.fastaURL);
|
|
74931
|
-
if (isString$
|
|
75245
|
+
if (isString$3(url)) {
|
|
74932
75246
|
url = url.trim();
|
|
74933
75247
|
}
|
|
74934
75248
|
|
|
@@ -74976,7 +75290,7 @@ ${indent}columns: ${matrix.columns}
|
|
|
74976
75290
|
const featureSource = FeatureSource(config, this.genome);
|
|
74977
75291
|
config._featureSource = featureSource; // This is a temp variable, bit of a hack
|
|
74978
75292
|
const trackType = await featureSource.trackType();
|
|
74979
|
-
if (trackType) {
|
|
75293
|
+
if (trackType && knownTrackTypes().has(trackType)) {
|
|
74980
75294
|
type = trackType;
|
|
74981
75295
|
} else {
|
|
74982
75296
|
type = "annotation";
|