igv 2.12.2 → 2.12.5
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 +194 -160
- package/dist/igv.esm.min.js +9 -9
- package/dist/igv.esm.min.js.map +1 -1
- package/dist/igv.js +4565 -4435
- package/dist/igv.min.js +7 -7
- package/dist/igv.min.js.map +1 -1
- package/package.json +2 -2
package/dist/igv.esm.js
CHANGED
|
@@ -16468,8 +16468,12 @@ const IGVColor = {
|
|
|
16468
16468
|
|
|
16469
16469
|
let dragData$1; // Its assumed we are only dragging one element at a time.
|
|
16470
16470
|
|
|
16471
|
+
let bbox = undefined;
|
|
16471
16472
|
|
|
16472
|
-
function makeDraggable$1(target, handle) {
|
|
16473
|
+
function makeDraggable$1(target, handle, constraint) {
|
|
16474
|
+
if (constraint) {
|
|
16475
|
+
bbox = Object.assign({}, constraint);
|
|
16476
|
+
}
|
|
16473
16477
|
handle.addEventListener('mousedown', dragStart$1.bind(target));
|
|
16474
16478
|
}
|
|
16475
16479
|
|
|
@@ -16512,8 +16516,13 @@ function drag$1(event) {
|
|
|
16512
16516
|
event.preventDefault();
|
|
16513
16517
|
const dx = event.screenX - dragData$1.screenX;
|
|
16514
16518
|
const dy = event.screenY - dragData$1.screenY;
|
|
16515
|
-
|
|
16516
|
-
|
|
16519
|
+
|
|
16520
|
+
// const left = bbox ? Math.max(bbox.minX, dragData.left + dx) : dragData.left + dx
|
|
16521
|
+
const left = dragData$1.left + dx;
|
|
16522
|
+
const top = bbox ? Math.max(bbox.minY, dragData$1.top + dy) : dragData$1.top + dy;
|
|
16523
|
+
|
|
16524
|
+
this.style.left = `${ left }px`;
|
|
16525
|
+
this.style.top = `${ top }px`;
|
|
16517
16526
|
}
|
|
16518
16527
|
|
|
16519
16528
|
function dragEnd$1(event) {
|
|
@@ -16801,9 +16810,9 @@ const igvxhr = {
|
|
|
16801
16810
|
options.responseType = "arraybuffer";
|
|
16802
16811
|
}
|
|
16803
16812
|
if (isFile(url)) {
|
|
16804
|
-
return loadFileSlice(url, options)
|
|
16813
|
+
return loadFileSlice(url, options)
|
|
16805
16814
|
} else {
|
|
16806
|
-
return load(url, options)
|
|
16815
|
+
return load(url, options)
|
|
16807
16816
|
}
|
|
16808
16817
|
},
|
|
16809
16818
|
|
|
@@ -16815,18 +16824,18 @@ const igvxhr = {
|
|
|
16815
16824
|
}
|
|
16816
16825
|
const result = await this.loadString(url, options);
|
|
16817
16826
|
if (result) {
|
|
16818
|
-
return JSON.parse(result)
|
|
16827
|
+
return JSON.parse(result)
|
|
16819
16828
|
} else {
|
|
16820
|
-
return result
|
|
16829
|
+
return result
|
|
16821
16830
|
}
|
|
16822
16831
|
},
|
|
16823
16832
|
|
|
16824
16833
|
loadString: async function (path, options) {
|
|
16825
16834
|
options = options || {};
|
|
16826
16835
|
if (path instanceof File) {
|
|
16827
|
-
return loadStringFromFile(path, options)
|
|
16836
|
+
return loadStringFromFile(path, options)
|
|
16828
16837
|
} else {
|
|
16829
|
-
return loadStringFromUrl(path, options)
|
|
16838
|
+
return loadStringFromUrl(path, options)
|
|
16830
16839
|
}
|
|
16831
16840
|
}
|
|
16832
16841
|
};
|
|
@@ -16840,15 +16849,15 @@ async function load(url, options) {
|
|
|
16840
16849
|
url = await (typeof url === 'function' ? url() : url);
|
|
16841
16850
|
|
|
16842
16851
|
if (isFile(url)) {
|
|
16843
|
-
return loadFileSlice(url, options)
|
|
16852
|
+
return loadFileSlice(url, options)
|
|
16844
16853
|
} else if (typeof url.startsWith === 'function') { // Test for string
|
|
16845
16854
|
if (url.startsWith("data:")) {
|
|
16846
16855
|
const buffer = decodeDataURI$1(url).buffer;
|
|
16847
|
-
if(options.range) {
|
|
16856
|
+
if (options.range) {
|
|
16848
16857
|
const rangeEnd = options.range.size ? options.range.start + options.range.size : buffer.byteLength;
|
|
16849
|
-
return buffer.slice(options.range.start, rangeEnd)
|
|
16858
|
+
return buffer.slice(options.range.start, rangeEnd)
|
|
16850
16859
|
} else {
|
|
16851
|
-
return buffer
|
|
16860
|
+
return buffer
|
|
16852
16861
|
}
|
|
16853
16862
|
} else {
|
|
16854
16863
|
if (url.startsWith("https://drive.google.com")) {
|
|
@@ -16859,11 +16868,11 @@ async function load(url, options) {
|
|
|
16859
16868
|
return loadURL(url, options)
|
|
16860
16869
|
})
|
|
16861
16870
|
} else {
|
|
16862
|
-
return loadURL(url, options)
|
|
16871
|
+
return loadURL(url, options)
|
|
16863
16872
|
}
|
|
16864
16873
|
}
|
|
16865
16874
|
} else {
|
|
16866
|
-
throw Error(`url must be either a 'File', 'string', 'function', or 'Promise'. Actual type: ${urlType}`)
|
|
16875
|
+
throw Error(`url must be either a 'File', 'string', 'function', or 'Promise'. Actual type: ${urlType}`)
|
|
16867
16876
|
}
|
|
16868
16877
|
}
|
|
16869
16878
|
|
|
@@ -16882,7 +16891,7 @@ async function loadURL(url, options) {
|
|
|
16882
16891
|
return new Promise(function (resolve, reject) {
|
|
16883
16892
|
|
|
16884
16893
|
// Various Google tansformations
|
|
16885
|
-
if (isGoogleURL(url)) {
|
|
16894
|
+
if (isGoogleURL(url) && !isGoogleStorageSigned(url)) {
|
|
16886
16895
|
if (isGoogleStorageURL(url)) {
|
|
16887
16896
|
url = translateGoogleCloudURL(url);
|
|
16888
16897
|
}
|
|
@@ -16906,7 +16915,7 @@ async function loadURL(url, options) {
|
|
|
16906
16915
|
const isChrome = navigator.userAgent.indexOf('Chrome') > -1;
|
|
16907
16916
|
navigator.vendor.indexOf("Apple") === 0 && /\sSafari\//.test(navigator.userAgent);
|
|
16908
16917
|
|
|
16909
|
-
if (range && isChrome && !isAmazonV4Signed(url)) {
|
|
16918
|
+
if (range && isChrome && !isAmazonV4Signed(url) && !isGoogleStorageSigned(url)) {
|
|
16910
16919
|
// Hack to prevent caching for byte-ranges. Attempt to fix net:err-cache errors in Chrome
|
|
16911
16920
|
url += url.includes("?") ? "&" : "?";
|
|
16912
16921
|
url += "someRandomSeed=" + Math.random().toString(36);
|
|
@@ -17011,7 +17020,7 @@ async function loadURL(url, options) {
|
|
|
17011
17020
|
if (reject) {
|
|
17012
17021
|
reject(error);
|
|
17013
17022
|
} else {
|
|
17014
|
-
throw error
|
|
17023
|
+
throw error
|
|
17015
17024
|
}
|
|
17016
17025
|
}
|
|
17017
17026
|
|
|
@@ -17043,60 +17052,38 @@ async function loadFileSlice(localfile, options) {
|
|
|
17043
17052
|
localfile.slice(options.range.start, options.range.start + options.range.size) :
|
|
17044
17053
|
localfile;
|
|
17045
17054
|
|
|
17055
|
+
const arrayBuffer = await blob.arrayBuffer();
|
|
17056
|
+
|
|
17046
17057
|
if ("arraybuffer" === options.responseType) {
|
|
17047
|
-
return
|
|
17058
|
+
return arrayBuffer
|
|
17048
17059
|
} else {
|
|
17049
|
-
|
|
17050
|
-
return new Promise(function (resolve, reject) {
|
|
17051
|
-
const fileReader = new FileReader();
|
|
17052
|
-
fileReader.onload = function (e) {
|
|
17053
|
-
resolve(fileReader.result);
|
|
17054
|
-
};
|
|
17055
|
-
fileReader.onerror = function (e) {
|
|
17056
|
-
console.error("reject uploading local file " + localfile.name);
|
|
17057
|
-
reject(null, fileReader);
|
|
17058
|
-
};
|
|
17059
|
-
fileReader.readAsBinaryString(blob);
|
|
17060
|
-
console.warn("Deprecated method used: readAsBinaryString");
|
|
17061
|
-
})
|
|
17060
|
+
return arrayBufferToString(arrayBuffer)
|
|
17062
17061
|
}
|
|
17063
17062
|
}
|
|
17064
17063
|
|
|
17065
17064
|
async function loadStringFromFile(localfile, options) {
|
|
17066
17065
|
|
|
17067
17066
|
const blob = options.range ? localfile.slice(options.range.start, options.range.start + options.range.size) : localfile;
|
|
17068
|
-
const arrayBuffer = await
|
|
17069
|
-
return arrayBufferToString(arrayBuffer)
|
|
17067
|
+
const arrayBuffer = await blob.arrayBuffer();
|
|
17068
|
+
return arrayBufferToString(arrayBuffer)
|
|
17070
17069
|
}
|
|
17071
17070
|
|
|
17072
|
-
async function blobToArrayBuffer(blob) {
|
|
17073
|
-
if (typeof blob.arrayBuffer === 'function') {
|
|
17074
|
-
return blob.arrayBuffer();
|
|
17075
|
-
}
|
|
17076
|
-
return new Promise(function (resolve, reject) {
|
|
17077
|
-
const fileReader = new FileReader();
|
|
17078
|
-
fileReader.onload = function (e) {
|
|
17079
|
-
resolve(fileReader.result);
|
|
17080
|
-
};
|
|
17081
|
-
fileReader.onerror = function (e) {
|
|
17082
|
-
console.error("reject uploading local file " + localfile.name);
|
|
17083
|
-
reject(null, fileReader);
|
|
17084
|
-
};
|
|
17085
|
-
fileReader.readAsArrayBuffer(blob);
|
|
17086
|
-
})
|
|
17087
|
-
}
|
|
17088
17071
|
|
|
17089
17072
|
async function loadStringFromUrl(url, options) {
|
|
17090
17073
|
|
|
17091
17074
|
options = options || {};
|
|
17092
17075
|
options.responseType = "arraybuffer";
|
|
17093
17076
|
const data = await igvxhr.load(url, options);
|
|
17094
|
-
return arrayBufferToString(data)
|
|
17077
|
+
return arrayBufferToString(data)
|
|
17095
17078
|
}
|
|
17096
17079
|
|
|
17097
17080
|
|
|
17098
17081
|
function isAmazonV4Signed(url) {
|
|
17099
|
-
return url.indexOf("X-Amz-Signature") > -1
|
|
17082
|
+
return url.indexOf("X-Amz-Signature") > -1
|
|
17083
|
+
}
|
|
17084
|
+
|
|
17085
|
+
function isGoogleStorageSigned(url) {
|
|
17086
|
+
return url.indexOf("X-Goog-Signature") > -1
|
|
17100
17087
|
}
|
|
17101
17088
|
|
|
17102
17089
|
function getOauthToken(url) {
|
|
@@ -17107,11 +17094,11 @@ function getOauthToken(url) {
|
|
|
17107
17094
|
parseUri(url).host;
|
|
17108
17095
|
let token = oauth.getToken(host);
|
|
17109
17096
|
if (token) {
|
|
17110
|
-
return token
|
|
17097
|
+
return token
|
|
17111
17098
|
} else if (host === undefined) {
|
|
17112
17099
|
const googleToken = getCurrentGoogleAccessToken();
|
|
17113
17100
|
if (googleToken && googleToken.expires_at > Date.now()) {
|
|
17114
|
-
return googleToken.access_token
|
|
17101
|
+
return googleToken.access_token
|
|
17115
17102
|
}
|
|
17116
17103
|
}
|
|
17117
17104
|
}
|
|
@@ -17127,7 +17114,7 @@ async function fetchGoogleAccessToken(url) {
|
|
|
17127
17114
|
if (isInitialized()) {
|
|
17128
17115
|
const scope = getScopeForURL(url);
|
|
17129
17116
|
const googleToken = await getAccessToken(scope);
|
|
17130
|
-
return googleToken ? googleToken.access_token : undefined
|
|
17117
|
+
return googleToken ? googleToken.access_token : undefined
|
|
17131
17118
|
} else {
|
|
17132
17119
|
throw Error(
|
|
17133
17120
|
`Authorization is required, but Google oAuth has not been initalized. Contact your site administrator for assistance.`)
|
|
@@ -17141,9 +17128,9 @@ async function fetchGoogleAccessToken(url) {
|
|
|
17141
17128
|
function getCurrentGoogleAccessToken() {
|
|
17142
17129
|
if (isInitialized()) {
|
|
17143
17130
|
const googleToken = getCurrentAccessToken();
|
|
17144
|
-
return googleToken ? googleToken.access_token : undefined
|
|
17131
|
+
return googleToken ? googleToken.access_token : undefined
|
|
17145
17132
|
} else {
|
|
17146
|
-
return undefined
|
|
17133
|
+
return undefined
|
|
17147
17134
|
}
|
|
17148
17135
|
}
|
|
17149
17136
|
|
|
@@ -17152,7 +17139,7 @@ function addOauthHeaders(headers, acToken) {
|
|
|
17152
17139
|
headers["Cache-Control"] = "no-cache";
|
|
17153
17140
|
headers["Authorization"] = "Bearer " + acToken;
|
|
17154
17141
|
}
|
|
17155
|
-
return headers
|
|
17142
|
+
return headers
|
|
17156
17143
|
}
|
|
17157
17144
|
|
|
17158
17145
|
|
|
@@ -17165,12 +17152,12 @@ function addApiKey(url) {
|
|
|
17165
17152
|
const paramSeparator = url.includes("?") ? "&" : "?";
|
|
17166
17153
|
url = url + paramSeparator + "key=" + apiKey;
|
|
17167
17154
|
}
|
|
17168
|
-
return url
|
|
17155
|
+
return url
|
|
17169
17156
|
}
|
|
17170
17157
|
|
|
17171
17158
|
function addTeamDrive(url) {
|
|
17172
17159
|
if (url.includes("supportsTeamDrive")) {
|
|
17173
|
-
return url
|
|
17160
|
+
return url
|
|
17174
17161
|
} else {
|
|
17175
17162
|
const paramSeparator = url.includes("?") ? "&" : "?";
|
|
17176
17163
|
url = url + paramSeparator + "supportsTeamDrive=true";
|
|
@@ -17184,17 +17171,17 @@ function addTeamDrive(url) {
|
|
|
17184
17171
|
function mapUrl(url) {
|
|
17185
17172
|
|
|
17186
17173
|
if (url.includes("//www.dropbox.com")) {
|
|
17187
|
-
return url.replace("//www.dropbox.com", "//dl.dropboxusercontent.com")
|
|
17174
|
+
return url.replace("//www.dropbox.com", "//dl.dropboxusercontent.com")
|
|
17188
17175
|
} else if (url.includes("//drive.google.com")) {
|
|
17189
|
-
return driveDownloadURL(url)
|
|
17176
|
+
return driveDownloadURL(url)
|
|
17190
17177
|
} else if (url.includes("//www.broadinstitute.org/igvdata")) {
|
|
17191
|
-
return url.replace("//www.broadinstitute.org/igvdata", "//data.broadinstitute.org/igvdata")
|
|
17178
|
+
return url.replace("//www.broadinstitute.org/igvdata", "//data.broadinstitute.org/igvdata")
|
|
17192
17179
|
} else if (url.includes("//igvdata.broadinstitute.org")) {
|
|
17193
17180
|
return url.replace("//igvdata.broadinstitute.org", "https://dn7ywbm9isq8j.cloudfront.net")
|
|
17194
17181
|
} else if (url.startsWith("ftp://ftp.ncbi.nlm.nih.gov/geo")) {
|
|
17195
17182
|
return url.replace("ftp://", "https://")
|
|
17196
17183
|
} else {
|
|
17197
|
-
return url
|
|
17184
|
+
return url
|
|
17198
17185
|
}
|
|
17199
17186
|
}
|
|
17200
17187
|
|
|
@@ -17209,9 +17196,9 @@ function arrayBufferToString(arraybuffer) {
|
|
|
17209
17196
|
}
|
|
17210
17197
|
|
|
17211
17198
|
if ('TextDecoder' in getGlobalObject()) {
|
|
17212
|
-
return new TextDecoder().decode(plain)
|
|
17199
|
+
return new TextDecoder().decode(plain)
|
|
17213
17200
|
} else {
|
|
17214
|
-
return decodeUTF8(plain)
|
|
17201
|
+
return decodeUTF8(plain)
|
|
17215
17202
|
}
|
|
17216
17203
|
}
|
|
17217
17204
|
|
|
@@ -17263,12 +17250,12 @@ function decodeUTF8(octets) {
|
|
|
17263
17250
|
|
|
17264
17251
|
function getGlobalObject() {
|
|
17265
17252
|
if (typeof self !== 'undefined') {
|
|
17266
|
-
return self
|
|
17253
|
+
return self
|
|
17267
17254
|
}
|
|
17268
17255
|
if (typeof global !== 'undefined') {
|
|
17269
|
-
return global
|
|
17256
|
+
return global
|
|
17270
17257
|
} else {
|
|
17271
|
-
return window
|
|
17258
|
+
return window
|
|
17272
17259
|
}
|
|
17273
17260
|
}
|
|
17274
17261
|
|
|
@@ -20251,6 +20238,12 @@ for (let i = 0; i < t1.length; i++) {
|
|
|
20251
20238
|
complement[t1[i].toLowerCase()] = t2[i].toLowerCase();
|
|
20252
20239
|
}
|
|
20253
20240
|
|
|
20241
|
+
const DEFAULT_HEIGHT = 25;
|
|
20242
|
+
const TRANSLATED_HEIGHT = 115;
|
|
20243
|
+
const SEQUENCE_HEIGHT = 15;
|
|
20244
|
+
const FRAME_HEIGHT = 25;
|
|
20245
|
+
const FRAME_BORDER = 5;
|
|
20246
|
+
|
|
20254
20247
|
class SequenceTrack {
|
|
20255
20248
|
|
|
20256
20249
|
constructor(config, browser) {
|
|
@@ -20262,13 +20255,13 @@ class SequenceTrack {
|
|
|
20262
20255
|
this.name = "Sequence";
|
|
20263
20256
|
this.id = "sequence";
|
|
20264
20257
|
this.sequenceType = config.sequenceType || "dna"; // dna | rna | prot
|
|
20265
|
-
this.height = 25;
|
|
20266
20258
|
this.disableButtons = false;
|
|
20267
20259
|
this.order = config.order || defaultSequenceTrackOrder;
|
|
20268
20260
|
this.ignoreTrackMenu = false;
|
|
20269
20261
|
|
|
20270
|
-
this.reversed =
|
|
20271
|
-
this.frameTranslate =
|
|
20262
|
+
this.reversed = config.reversed === true;
|
|
20263
|
+
this.frameTranslate = config.frameTranslate === true;
|
|
20264
|
+
this.height = this.frameTranslate ? TRANSLATED_HEIGHT : DEFAULT_HEIGHT;
|
|
20272
20265
|
|
|
20273
20266
|
}
|
|
20274
20267
|
|
|
@@ -20287,14 +20280,14 @@ class SequenceTrack {
|
|
|
20287
20280
|
this.frameTranslate = !this.frameTranslate;
|
|
20288
20281
|
if (this.frameTranslate) {
|
|
20289
20282
|
for (let vp of this.trackView.viewports) {
|
|
20290
|
-
vp.setContentHeight(
|
|
20283
|
+
vp.setContentHeight(TRANSLATED_HEIGHT);
|
|
20291
20284
|
}
|
|
20292
|
-
this.trackView.setTrackHeight(
|
|
20285
|
+
this.trackView.setTrackHeight(TRANSLATED_HEIGHT);
|
|
20293
20286
|
} else {
|
|
20294
20287
|
for (let vp of this.trackView.viewports) {
|
|
20295
|
-
vp.setContentHeight(
|
|
20288
|
+
vp.setContentHeight(DEFAULT_HEIGHT);
|
|
20296
20289
|
}
|
|
20297
|
-
this.trackView.setTrackHeight(
|
|
20290
|
+
this.trackView.setTrackHeight(DEFAULT_HEIGHT);
|
|
20298
20291
|
}
|
|
20299
20292
|
this.trackView.repaintViews();
|
|
20300
20293
|
|
|
@@ -20377,7 +20370,8 @@ class SequenceTrack {
|
|
|
20377
20370
|
}
|
|
20378
20371
|
|
|
20379
20372
|
async getFeatures(chr, start, end, bpPerPixel) {
|
|
20380
|
-
|
|
20373
|
+
start = Math.floor(start);
|
|
20374
|
+
end = Math.floor(end);
|
|
20381
20375
|
if (bpPerPixel && bpPerPixel > 1) {
|
|
20382
20376
|
return null
|
|
20383
20377
|
} else {
|
|
@@ -20395,89 +20389,79 @@ class SequenceTrack {
|
|
|
20395
20389
|
|
|
20396
20390
|
if (options.features) {
|
|
20397
20391
|
|
|
20398
|
-
|
|
20399
|
-
const sequenceBpStart = options.features.bpStart;
|
|
20400
|
-
const bpEnd = 1 + options.bpStart + (options.pixelWidth * options.bpPerPixel);
|
|
20401
|
-
|
|
20402
|
-
let height = 15;
|
|
20403
|
-
for (let bp = sequenceBpStart; bp <= bpEnd; bp++) {
|
|
20392
|
+
let sequence = options.features.sequence;
|
|
20404
20393
|
|
|
20405
|
-
|
|
20394
|
+
if (this.reversed) {
|
|
20395
|
+
sequence = sequence.split('').map(function (cv) {
|
|
20396
|
+
return complement[cv]
|
|
20397
|
+
}).join('');
|
|
20398
|
+
}
|
|
20406
20399
|
|
|
20407
|
-
|
|
20408
|
-
|
|
20400
|
+
const sequenceBpStart = options.features.bpStart; // genomic position at start of sequence
|
|
20401
|
+
const bpEnd = 1 + options.bpStart + (options.pixelWidth * options.bpPerPixel);
|
|
20409
20402
|
|
|
20410
|
-
|
|
20411
|
-
letter = complement[letter] || "";
|
|
20412
|
-
}
|
|
20403
|
+
for (let bp = Math.floor(options.bpStart); bp <= bpEnd; bp++) {
|
|
20413
20404
|
|
|
20414
|
-
|
|
20415
|
-
let aPixel = offsetBP / options.bpPerPixel;
|
|
20416
|
-
let bPixel = (offsetBP + 1) / options.bpPerPixel;
|
|
20417
|
-
let color = this.fillColor(letter);
|
|
20405
|
+
const seqIdx = Math.floor(bp - sequenceBpStart);
|
|
20418
20406
|
|
|
20419
|
-
|
|
20407
|
+
if (seqIdx >= 0 && seqIdx < sequence.length) {
|
|
20408
|
+
const baseLetter = sequence[seqIdx];
|
|
20409
|
+
const offsetBP = bp - options.bpStart;
|
|
20410
|
+
const aPixel = offsetBP / options.bpPerPixel;
|
|
20411
|
+
const pixelWidth = 1 / options.bpPerPixel;
|
|
20412
|
+
const color = this.fillColor(baseLetter);
|
|
20420
20413
|
|
|
20421
20414
|
if (options.bpPerPixel > 1 / 10) {
|
|
20422
|
-
IGVGraphics.fillRect(ctx, aPixel, 5,
|
|
20415
|
+
IGVGraphics.fillRect(ctx, aPixel, 5, pixelWidth, SEQUENCE_HEIGHT - 5, {fillStyle: color});
|
|
20423
20416
|
} else {
|
|
20424
|
-
let
|
|
20425
|
-
IGVGraphics.strokeText(ctx,
|
|
20417
|
+
let textPixel = aPixel + 0.5 * (pixelWidth - ctx.measureText(baseLetter).width);
|
|
20418
|
+
IGVGraphics.strokeText(ctx, baseLetter, textPixel, SEQUENCE_HEIGHT, {strokeStyle: color});
|
|
20426
20419
|
}
|
|
20427
20420
|
}
|
|
20428
20421
|
}
|
|
20429
20422
|
|
|
20430
20423
|
if (this.frameTranslate) {
|
|
20431
20424
|
|
|
20432
|
-
let
|
|
20433
|
-
|
|
20434
|
-
transSeq = sequence.split('').map(function (cv) {
|
|
20435
|
-
return complement[cv]
|
|
20436
|
-
});
|
|
20437
|
-
transSeq = transSeq.join('');
|
|
20438
|
-
} else {
|
|
20439
|
-
transSeq = sequence;
|
|
20440
|
-
}
|
|
20441
|
-
|
|
20442
|
-
let y = height;
|
|
20443
|
-
let translatedSequence = this.translateSequence(transSeq);
|
|
20444
|
-
for (let arr of translatedSequence) {
|
|
20425
|
+
let y = SEQUENCE_HEIGHT + 2 * FRAME_BORDER;
|
|
20426
|
+
const translatedSequence = this.translateSequence(sequence);
|
|
20445
20427
|
|
|
20446
|
-
|
|
20447
|
-
let fNum = i;
|
|
20448
|
-
let h = 25;
|
|
20428
|
+
for (let fNum = 0; fNum < translatedSequence.length; fNum++) { // == 3, 1 for each frame
|
|
20449
20429
|
|
|
20450
|
-
|
|
20430
|
+
const aaSequence = translatedSequence[fNum]; // AA sequence for this frame
|
|
20451
20431
|
|
|
20452
|
-
for (let
|
|
20432
|
+
for (let idx = 0; idx < aaSequence.length; idx++) {
|
|
20453
20433
|
|
|
20454
|
-
let aaS;
|
|
20455
|
-
let idx = arr.indexOf(cv);
|
|
20456
|
-
let xSeed = (idx + fNum) + (2 * idx);
|
|
20457
20434
|
let color = 0 === idx % 2 ? 'rgb(160,160,160)' : 'rgb(224,224,224)';
|
|
20435
|
+
const cv = aaSequence[idx];
|
|
20436
|
+
|
|
20437
|
+
const bpPos = sequenceBpStart + fNum + (idx * 3);
|
|
20438
|
+
const bpOffset = bpPos - options.bpStart;
|
|
20439
|
+
const p0 = Math.floor(bpOffset / options.bpPerPixel);
|
|
20440
|
+
const p1 = Math.floor((bpOffset + 3) / options.bpPerPixel);
|
|
20441
|
+
const pc = Math.round((p0 + p1) / 2);
|
|
20442
|
+
|
|
20443
|
+
if (p1 < 0) {
|
|
20444
|
+
continue // off left edge
|
|
20445
|
+
} else if (p0 > options.pixelWidth) {
|
|
20446
|
+
break // off right edge
|
|
20447
|
+
}
|
|
20458
20448
|
|
|
20459
|
-
let
|
|
20460
|
-
let p1 = Math.floor((xSeed + 3) / options.bpPerPixel);
|
|
20461
|
-
let pc = Math.round((p0 + p1) / 2);
|
|
20462
|
-
|
|
20449
|
+
let aaLabel = cv.aminoA;
|
|
20463
20450
|
if (cv.aminoA.indexOf('STOP') > -1) {
|
|
20464
20451
|
color = 'rgb(255, 0, 0)';
|
|
20465
|
-
|
|
20466
|
-
} else {
|
|
20467
|
-
aaS = cv.aminoA;
|
|
20468
|
-
}
|
|
20469
|
-
|
|
20470
|
-
if (cv.aminoA === 'M') {
|
|
20452
|
+
aaLabel = 'STOP'; //Color blind accessible
|
|
20453
|
+
} else if (cv.aminoA === 'M') {
|
|
20471
20454
|
color = 'rgb(0, 153, 0)';
|
|
20472
|
-
|
|
20455
|
+
aaLabel = 'START'; //Color blind accessible
|
|
20473
20456
|
}
|
|
20474
20457
|
|
|
20475
|
-
IGVGraphics.fillRect(ctx, p0, y, p1 - p0,
|
|
20458
|
+
IGVGraphics.fillRect(ctx, p0, y, p1 - p0, FRAME_HEIGHT, {fillStyle: color});
|
|
20476
20459
|
|
|
20477
20460
|
if (options.bpPerPixel <= 1 / 10) {
|
|
20478
|
-
IGVGraphics.strokeText(ctx,
|
|
20461
|
+
IGVGraphics.strokeText(ctx, aaLabel, pc - (ctx.measureText(aaLabel).width / 2), y + 15);
|
|
20479
20462
|
}
|
|
20480
20463
|
}
|
|
20464
|
+
y += (FRAME_HEIGHT + FRAME_BORDER);
|
|
20481
20465
|
}
|
|
20482
20466
|
}
|
|
20483
20467
|
}
|
|
@@ -20488,6 +20472,7 @@ class SequenceTrack {
|
|
|
20488
20472
|
}
|
|
20489
20473
|
|
|
20490
20474
|
computePixelHeight(ignore) {
|
|
20475
|
+
this.height = this.frameTranslate ? TRANSLATED_HEIGHT : DEFAULT_HEIGHT;
|
|
20491
20476
|
return this.height
|
|
20492
20477
|
}
|
|
20493
20478
|
|
|
@@ -20500,8 +20485,26 @@ class SequenceTrack {
|
|
|
20500
20485
|
} else {
|
|
20501
20486
|
return 'rgb(0, 0, 150)'
|
|
20502
20487
|
}
|
|
20488
|
+
}
|
|
20503
20489
|
|
|
20490
|
+
/**
|
|
20491
|
+
* Return the current state of the track. Used to create sessions and bookmarks.
|
|
20492
|
+
*
|
|
20493
|
+
* @returns {*|{}}
|
|
20494
|
+
*/
|
|
20495
|
+
getState() {
|
|
20496
|
+
const config = {
|
|
20497
|
+
type: "sequence"
|
|
20498
|
+
};
|
|
20499
|
+
if (this.order !== defaultSequenceTrackOrder) {
|
|
20500
|
+
config.order = this.order;
|
|
20501
|
+
}
|
|
20502
|
+
if (this.reversed) {
|
|
20503
|
+
config.revealed = true;
|
|
20504
|
+
}
|
|
20505
|
+
return config
|
|
20504
20506
|
}
|
|
20507
|
+
|
|
20505
20508
|
}
|
|
20506
20509
|
|
|
20507
20510
|
/*
|
|
@@ -22337,7 +22340,9 @@ class FastaSequence {
|
|
|
22337
22340
|
|
|
22338
22341
|
async getSequence(chr, start, end) {
|
|
22339
22342
|
|
|
22340
|
-
|
|
22343
|
+
const hasCachedSquence = this.interval && this.interval.contains(chr, start, end);
|
|
22344
|
+
|
|
22345
|
+
if (!hasCachedSquence) {
|
|
22341
22346
|
|
|
22342
22347
|
// Expand query, to minimum of 50kb
|
|
22343
22348
|
let qstart = start;
|
|
@@ -22796,7 +22801,7 @@ const Cytoband = function (start, end, name, typestain) {
|
|
|
22796
22801
|
}
|
|
22797
22802
|
};
|
|
22798
22803
|
|
|
22799
|
-
const _version = "2.12.
|
|
22804
|
+
const _version = "2.12.5";
|
|
22800
22805
|
function version() {
|
|
22801
22806
|
return _version
|
|
22802
22807
|
}
|
|
@@ -23460,6 +23465,17 @@ class TrackViewport extends Viewport {
|
|
|
23460
23465
|
}
|
|
23461
23466
|
}
|
|
23462
23467
|
|
|
23468
|
+
repaintDimensions() {
|
|
23469
|
+
const isWGV = GenomeUtils.isWholeGenomeView(this.referenceFrame.chr);
|
|
23470
|
+
const pixelWidth = isWGV ? this.$viewport.width() : 3 * this.$viewport.width();
|
|
23471
|
+
const bpPerPixel = this.referenceFrame.bpPerPixel;
|
|
23472
|
+
const startBP = this.referenceFrame.start - (isWGV ? 0 : pixelWidth / 3 * bpPerPixel);
|
|
23473
|
+
const endBP = this.referenceFrame.end + (isWGV ? 0 : pixelWidth / 3 * bpPerPixel);
|
|
23474
|
+
return {
|
|
23475
|
+
startBP, endBP, pixelWidth
|
|
23476
|
+
}
|
|
23477
|
+
}
|
|
23478
|
+
|
|
23463
23479
|
/**
|
|
23464
23480
|
* Repaint the canvas using the cached features
|
|
23465
23481
|
*
|
|
@@ -23474,11 +23490,11 @@ class TrackViewport extends Viewport {
|
|
|
23474
23490
|
//this.tile.bpPerPixel = this.referenceFrame.bpPerPixel
|
|
23475
23491
|
|
|
23476
23492
|
// const isWGV = GenomeUtils.isWholeGenomeView(this.browser.referenceFrameList[0].chr)
|
|
23477
|
-
|
|
23493
|
+
GenomeUtils.isWholeGenomeView(this.referenceFrame.chr);
|
|
23478
23494
|
|
|
23479
23495
|
// Canvas dimensions. There is no left-right panning for WGV so canvas width is viewport width.
|
|
23480
23496
|
// For deep tracks we paint a canvas == 3*viewportHeight centered on the current vertical scroll position
|
|
23481
|
-
const pixelWidth =
|
|
23497
|
+
const {startBP, endBP, pixelWidth} = this.repaintDimensions();
|
|
23482
23498
|
const viewportHeight = this.$viewport.height();
|
|
23483
23499
|
const contentHeight = this.getContentHeight();
|
|
23484
23500
|
const minHeight = roiFeatures ? Math.max(contentHeight, viewportHeight) : contentHeight; // Need to fill viewport for ROIs.
|
|
@@ -23492,8 +23508,8 @@ class TrackViewport extends Viewport {
|
|
|
23492
23508
|
const canvasTop = Math.max(0, -(this.$content.position().top) - viewportHeight);
|
|
23493
23509
|
|
|
23494
23510
|
const bpPerPixel = this.referenceFrame.bpPerPixel;
|
|
23495
|
-
const startBP = this.referenceFrame.start - (isWGV ? 0 : pixelWidth / 3 * bpPerPixel)
|
|
23496
|
-
const endBP = this.referenceFrame.end + (isWGV ? 0 : pixelWidth / 3 * bpPerPixel)
|
|
23511
|
+
//const startBP = this.referenceFrame.start - (isWGV ? 0 : pixelWidth / 3 * bpPerPixel)
|
|
23512
|
+
//const endBP = this.referenceFrame.end + (isWGV ? 0 : pixelWidth / 3 * bpPerPixel)
|
|
23497
23513
|
const pixelXOffset = Math.round((startBP - this.referenceFrame.start) / bpPerPixel);
|
|
23498
23514
|
|
|
23499
23515
|
const newCanvas = $$1('<canvas class="igv-canvas">').get(0);
|
|
@@ -23756,10 +23772,9 @@ class TrackViewport extends Viewport {
|
|
|
23756
23772
|
if (!this.featureCache) return true
|
|
23757
23773
|
const referenceFrame = this.referenceFrame;
|
|
23758
23774
|
const chr = this.referenceFrame.chr;
|
|
23759
|
-
const start = referenceFrame.start;
|
|
23760
|
-
const end = start + referenceFrame.toBP($$1(this.contentDiv).width());
|
|
23761
23775
|
const bpPerPixel = referenceFrame.bpPerPixel;
|
|
23762
|
-
|
|
23776
|
+
const {startBP, endBP} = this.repaintDimensions();
|
|
23777
|
+
return (!this.featureCache.containsRange(chr, startBP, endBP, bpPerPixel))
|
|
23763
23778
|
}
|
|
23764
23779
|
|
|
23765
23780
|
createZoomInNotice($parent) {
|
|
@@ -29025,8 +29040,12 @@ class BamSource {
|
|
|
29025
29040
|
*/
|
|
29026
29041
|
|
|
29027
29042
|
const fixColor = (colorString) => {
|
|
29028
|
-
|
|
29029
|
-
|
|
29043
|
+
if(isString$3(colorString)) {
|
|
29044
|
+
return (colorString.indexOf(",") > 0 && !colorString.startsWith("rgb(")) ?
|
|
29045
|
+
`rgb(${colorString})` : colorString
|
|
29046
|
+
} else {
|
|
29047
|
+
return colorString;
|
|
29048
|
+
}
|
|
29030
29049
|
};
|
|
29031
29050
|
|
|
29032
29051
|
/**
|
|
@@ -29180,7 +29199,7 @@ class TrackBase {
|
|
|
29180
29199
|
}
|
|
29181
29200
|
|
|
29182
29201
|
get supportsWholeGenome() {
|
|
29183
|
-
return
|
|
29202
|
+
return this.config.supportsWholeGenome === true
|
|
29184
29203
|
}
|
|
29185
29204
|
|
|
29186
29205
|
/**
|
|
@@ -39436,7 +39455,7 @@ function pack(featureList, maxRows) {
|
|
|
39436
39455
|
let r = 0;
|
|
39437
39456
|
const len = Math.min(rows.length, maxRows);
|
|
39438
39457
|
for (r = 0; r < len; r++) {
|
|
39439
|
-
if (feature.start
|
|
39458
|
+
if (feature.start >= rows[r]) {
|
|
39440
39459
|
feature.row = r;
|
|
39441
39460
|
rows[r] = feature.end;
|
|
39442
39461
|
break
|
|
@@ -40953,7 +40972,7 @@ class BWSource {
|
|
|
40953
40972
|
}
|
|
40954
40973
|
|
|
40955
40974
|
supportsWholeGenome() {
|
|
40956
|
-
return this.reader.type === "bigwig"
|
|
40975
|
+
return this.reader.type === "bigwig"
|
|
40957
40976
|
}
|
|
40958
40977
|
|
|
40959
40978
|
async trackType() {
|
|
@@ -42188,7 +42207,15 @@ class FeatureTrack extends TrackBase {
|
|
|
42188
42207
|
}
|
|
42189
42208
|
|
|
42190
42209
|
get supportsWholeGenome() {
|
|
42191
|
-
|
|
42210
|
+
if (this.config.supportsWholeGenome !== undefined) {
|
|
42211
|
+
return this.config.supportsWholeGenome
|
|
42212
|
+
} else if (this.featureSource && typeof this.featureSource.supportsWholeGenome === 'function') {
|
|
42213
|
+
return this.featureSource.supportsWholeGenome()
|
|
42214
|
+
} else {
|
|
42215
|
+
if (this.visibilityWindow === undefined && (this.config.indexed === false || !this.config.indexURL)) {
|
|
42216
|
+
return true
|
|
42217
|
+
}
|
|
42218
|
+
}
|
|
42192
42219
|
}
|
|
42193
42220
|
|
|
42194
42221
|
async getFeatures(chr, start, end, bpPerPixel) {
|
|
@@ -42245,7 +42272,7 @@ class FeatureTrack extends TrackBase {
|
|
|
42245
42272
|
options.rowLastX = [];
|
|
42246
42273
|
options.rowLastLabelX = [];
|
|
42247
42274
|
for (let feature of featureList) {
|
|
42248
|
-
if(feature.start > bpStart && feature.end < bpEnd) {
|
|
42275
|
+
if (feature.start > bpStart && feature.end < bpEnd) {
|
|
42249
42276
|
const row = this.displayMode === "COLLAPSED" ? 0 : feature.row || 0;
|
|
42250
42277
|
if (rowFeatureCount[row] === undefined) {
|
|
42251
42278
|
rowFeatureCount[row] = 1;
|
|
@@ -44509,6 +44536,8 @@ const isString = isString$3;
|
|
|
44509
44536
|
|
|
44510
44537
|
const DEFAULT_VISIBILITY_WINDOW = 1000000;
|
|
44511
44538
|
const TOP_MARGIN = 10;
|
|
44539
|
+
const STANDARD_FIELDS = new Map([["REF", "referenceBases"], ["ALT", "alternateBases"], ["QUAL", "quality"], ["FILTER", "filter"]]);
|
|
44540
|
+
|
|
44512
44541
|
|
|
44513
44542
|
class VariantTrack extends TrackBase {
|
|
44514
44543
|
|
|
@@ -44550,7 +44579,6 @@ class VariantTrack extends TrackBase {
|
|
|
44550
44579
|
this.colorTables = new Map();
|
|
44551
44580
|
this.colorTables.set(config.colorBy, new ColorTable(config.colorTable));
|
|
44552
44581
|
}
|
|
44553
|
-
this._color = config.color;
|
|
44554
44582
|
|
|
44555
44583
|
this.showGenotypes = config.showGenotypes === undefined ? true : config.showGenotypes;
|
|
44556
44584
|
|
|
@@ -44659,9 +44687,9 @@ class VariantTrack extends TrackBase {
|
|
|
44659
44687
|
IGVGraphics.fillRect(context, 0, pixelTop, pixelWidth, pixelHeight, {'fillStyle': "rgb(255, 255, 255)"});
|
|
44660
44688
|
|
|
44661
44689
|
const vGap = ("SQUISHED" === this.displayMode) ? this.squishedVGap : this.expandedVGap;
|
|
44662
|
-
const
|
|
44690
|
+
const rowCount = ("COLLAPSED" === this.displayMode) ? 1 : this.nVariantRows;
|
|
44663
44691
|
const variantHeight = ("SQUISHED" === this.displayMode) ? this.squishedVariantHeight : this.expandedVariantHeight;
|
|
44664
|
-
this.variantBandHeight = TOP_MARGIN +
|
|
44692
|
+
this.variantBandHeight = TOP_MARGIN + rowCount * (variantHeight + vGap);
|
|
44665
44693
|
|
|
44666
44694
|
const callSets = this.callSets;
|
|
44667
44695
|
const nCalls = this.getCallsetsLength();
|
|
@@ -44761,14 +44789,21 @@ class VariantTrack extends TrackBase {
|
|
|
44761
44789
|
let variantColor;
|
|
44762
44790
|
|
|
44763
44791
|
if (this.colorBy) {
|
|
44764
|
-
const
|
|
44765
|
-
|
|
44792
|
+
const colorBy = this.colorBy;
|
|
44793
|
+
let value;
|
|
44794
|
+
if (v.info.hasOwnProperty(colorBy)) {
|
|
44795
|
+
value = v.info[colorBy];
|
|
44796
|
+
} else if (STANDARD_FIELDS.has(colorBy)) {
|
|
44797
|
+
const key = STANDARD_FIELDS.get(colorBy);
|
|
44798
|
+
value = v[key];
|
|
44799
|
+
}
|
|
44800
|
+
variantColor = this.getVariantColorTable(colorBy).getColor(value);
|
|
44766
44801
|
if (!variantColor) {
|
|
44767
44802
|
variantColor = "gray";
|
|
44768
44803
|
}
|
|
44769
44804
|
|
|
44770
44805
|
} else if (this._color) {
|
|
44771
|
-
variantColor = this.
|
|
44806
|
+
variantColor = (typeof this._color === "function") ? this._color(variant) : this._color;
|
|
44772
44807
|
} else if ("NONVARIANT" === v.type) {
|
|
44773
44808
|
variantColor = this.nonRefColor;
|
|
44774
44809
|
} else if ("MIXED" === v.type) {
|
|
@@ -44779,9 +44814,6 @@ class VariantTrack extends TrackBase {
|
|
|
44779
44814
|
return variantColor
|
|
44780
44815
|
}
|
|
44781
44816
|
|
|
44782
|
-
get color() {
|
|
44783
|
-
return this._color ? ((typeof this._color === "function") ? this._color(v) : this._color) : this.defaultColor
|
|
44784
|
-
}
|
|
44785
44817
|
|
|
44786
44818
|
clickedFeatures(clickState, features) {
|
|
44787
44819
|
|
|
@@ -44794,15 +44826,17 @@ class VariantTrack extends TrackBase {
|
|
|
44794
44826
|
if (yOffset <= this.variantBandHeight) {
|
|
44795
44827
|
// Variant
|
|
44796
44828
|
const variantHeight = ("SQUISHED" === this.displayMode) ? this.squishedVariantHeight : this.expandedVariantHeight;
|
|
44797
|
-
const variantRow =
|
|
44798
|
-
|
|
44829
|
+
const variantRow = Math.floor((yOffset - TOP_MARGIN) / (variantHeight + vGap));
|
|
44830
|
+
if ("COLLAPSED" !== this.displayMode) {
|
|
44831
|
+
featureList = featureList.filter(f => f.row === variantRow);
|
|
44832
|
+
}
|
|
44799
44833
|
} else if (this.callSets) {
|
|
44800
44834
|
const callSets = this.callSets;
|
|
44801
44835
|
const sampleY = yOffset - this.variantBandHeight;
|
|
44802
44836
|
const sampleRow = Math.floor(sampleY / this.sampleHeight);
|
|
44803
44837
|
if (sampleRow >= 0 && sampleRow < callSets.length) {
|
|
44804
44838
|
const variantRow = Math.floor((sampleY - sampleRow * this.sampleHeight) / callHeight);
|
|
44805
|
-
const variants = featureList.filter(f => f.row === variantRow);
|
|
44839
|
+
const variants = "COLLAPSED" === this.displayMode ? featureList : featureList.filter(f => f.row === variantRow);
|
|
44806
44840
|
const cs = callSets[sampleRow];
|
|
44807
44841
|
featureList = variants.map(v => {
|
|
44808
44842
|
const call = v.calls[cs.id];
|
|
@@ -45016,7 +45050,7 @@ class VariantTrack extends TrackBase {
|
|
|
45016
45050
|
label: 'Add SVs to circular view',
|
|
45017
45051
|
click: () => {
|
|
45018
45052
|
for (let viewport of this.trackView.viewports) {
|
|
45019
|
-
|
|
45053
|
+
this.sendChordsForViewport(viewport);
|
|
45020
45054
|
}
|
|
45021
45055
|
}
|
|
45022
45056
|
});
|