icn3d 3.4.12 → 3.7.1

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.
Files changed (2) hide show
  1. package/icn3d.js +1579 -578
  2. package/package.json +1 -1
package/icn3d.js CHANGED
@@ -2462,7 +2462,10 @@ THREE.TrackballControls = function ( object, domElement, icn3d ) {
2462
2462
 
2463
2463
  _eye.multiplyScalar( factor );
2464
2464
 
2465
- if(icn3d !== undefined && icn3d._zoomFactor !== undefined && (bUpdate === undefined || bUpdate === true)) icn3d._zoomFactor *= factor;
2465
+ if(icn3d !== undefined && icn3d._zoomFactor !== undefined && (bUpdate === undefined || bUpdate === true)) {
2466
+ icn3d._zoomFactor *= factor;
2467
+ icn3d.fogCls.setFog();
2468
+ }
2466
2469
 
2467
2470
  } else {
2468
2471
 
@@ -2475,7 +2478,10 @@ THREE.TrackballControls = function ( object, domElement, icn3d ) {
2475
2478
  factor = 1.0 + ( _this._zoomEnd.y - _this._zoomStart.y ) * _this.zoomSpeed;
2476
2479
  }
2477
2480
 
2478
- if(icn3d !== undefined && icn3d._zoomFactor !== undefined && (bUpdate === undefined || bUpdate === true)) icn3d._zoomFactor *= factor;
2481
+ if(icn3d !== undefined && icn3d._zoomFactor !== undefined && (bUpdate === undefined || bUpdate === true)) {
2482
+ icn3d._zoomFactor *= factor;
2483
+ icn3d.fogCls.setFog();
2484
+ }
2479
2485
 
2480
2486
  //if ( factor !== 1.0 && factor > 0.0 ) {
2481
2487
  if ( factor !== 1.0 ) {
@@ -3952,7 +3958,7 @@ class ParasCls {
3952
3958
  black: this.thr(0x000000),
3953
3959
  grey: this.thr(0xCCCCCC),
3954
3960
  white: this.thr(0xFFFFFF),
3955
- transparent: this.thr(0x000000)
3961
+ transparent: this.thr(0xFFFFFF) //this.thr(0x000000)
3956
3962
  };
3957
3963
 
3958
3964
  this.residueColors = {
@@ -4113,6 +4119,7 @@ class ParasCls {
4113
4119
  }
4114
4120
 
4115
4121
  thr(color) { this.icn3dui;
4122
+ if(color == '#0') color = '#000';
4116
4123
  return new THREE.Color(color);
4117
4124
  }
4118
4125
  }
@@ -4483,6 +4490,16 @@ class UtilsCls {
4483
4490
  if(viewer_width && me.htmlCls.WIDTH > viewer_width) me.htmlCls.WIDTH = viewer_width;
4484
4491
  if(viewer_height && me.htmlCls.HEIGHT > viewer_height) me.htmlCls.HEIGHT = viewer_height;
4485
4492
  }
4493
+
4494
+ sumArray(numArray) {
4495
+ let sum = 0;
4496
+
4497
+ for(let i = 0, il = numArray.length; i < il; ++i) {
4498
+ sum += numArray[i];
4499
+ }
4500
+
4501
+ return sum;
4502
+ }
4486
4503
  }
4487
4504
 
4488
4505
  /**
@@ -5843,7 +5860,8 @@ class Fog {
5843
5860
  if(bZoomin) {
5844
5861
  let centerAtomsResults = ic.applyCenterCls.centerAtoms(ic.hAtoms);
5845
5862
  ic.maxD = centerAtomsResults.maxD;
5846
- if (ic.maxD < 5) ic.maxD = 5;
5863
+ //if (ic.maxD < 5) ic.maxD = 5;
5864
+ if (ic.maxD < 25) ic.maxD = 25;
5847
5865
  }
5848
5866
 
5849
5867
  let bInstance = (ic.biomtMatrices !== undefined && ic.biomtMatrices.length * ic.cnt > ic.maxatomcnt) ? true : false;
@@ -5860,7 +5878,9 @@ class Fog {
5860
5878
  ic.bSetFog = false;
5861
5879
  }
5862
5880
  else {
5863
- ic.scene.fog = new THREE.Fog(background, 2.5*ic.maxD, 4*ic.maxD);
5881
+ // adjust
5882
+ let zoomFactor = (ic._zoomFactor > 1) ? ic._zoomFactor * 1.0 : ic._zoomFactor;
5883
+ ic.scene.fog = new THREE.Fog(background, 2.5 * ic.maxD * zoomFactor, 4 * ic.maxD * zoomFactor);
5864
5884
  ic.bSetFog = true;
5865
5885
  ic.camMaxDFactorFog = 3;
5866
5886
  }
@@ -5879,9 +5899,9 @@ class Fog {
5879
5899
  ic.bSetFog = false;
5880
5900
  }
5881
5901
 
5882
- if(bZoomin && !bInstance) {
5883
- ic.transformCls.zoominSelection();
5884
- }
5902
+ //if(bZoomin && !bInstance) {
5903
+ // ic.transformCls.zoominSelection();
5904
+ //}
5885
5905
  }
5886
5906
  }
5887
5907
 
@@ -7258,7 +7278,8 @@ class Strand {
7258
7278
  let atomsAdjust = {};
7259
7279
 
7260
7280
  //if( (bHighlight === 1 || bHighlight === 2) && !ic.bAllAtoms) {
7261
- if( !ic.bAllAtoms) {
7281
+ //if( !ic.bAllAtoms) {
7282
+ if( Object.keys(atoms).length < Object.keys(ic.atoms).length) {
7262
7283
  atomsAdjust = this.getSSExpandedAtoms(atoms);
7263
7284
  }
7264
7285
  else {
@@ -11885,7 +11906,8 @@ class ShareLink {
11885
11906
 
11886
11907
  if(ic.commands.length > start) {
11887
11908
  let command_tf = ic.commands[start].split('|||');
11888
- prevCommandStr = command_tf[0].trim();
11909
+ let command_tf2 = command_tf[0].split('&command=');
11910
+ prevCommandStr = command_tf2[0].trim();
11889
11911
 
11890
11912
  //statefile += ic.commands[start] + "\n";
11891
11913
 
@@ -11896,7 +11918,8 @@ class ShareLink {
11896
11918
  let tmpUrl = '';
11897
11919
  for(let il = ic.commands.length; i < il; ++i) {
11898
11920
  let command_tf = ic.commands[i].split('|||');
11899
- let commandStr = command_tf[0].trim();
11921
+ let command_tf2 = command_tf[0].split('&command=');
11922
+ let commandStr = command_tf2[0].trim();
11900
11923
 
11901
11924
  //statefile += ic.commands[i] + "\n";
11902
11925
 
@@ -11947,7 +11970,7 @@ class ShareLink {
11947
11970
  }
11948
11971
 
11949
11972
  statefile = statefile.replace(/!/g, Object.keys(ic.structures)[0] + '_');
11950
- if((ic.bInputfile && !ic.bInputUrlfile) || url.length > 4000) url = statefile;
11973
+ if((ic.bInputfile && !ic.bInputUrlfile) || (ic.bInputUrlfile && ic.bAppend) || url.length > 4000) url = statefile;
11951
11974
  let id;
11952
11975
  if(ic.structures !== undefined && Object.keys(ic.structures).length == 1 && ic.inputid !== undefined) {
11953
11976
  id = Object.keys(ic.structures)[0];
@@ -11967,22 +11990,27 @@ class ShareLink {
11967
11990
 
11968
11991
  let text = "";
11969
11992
  if(ic.bInputfile) {
11970
- url = this.shareLinkUrl(bAllCommands); // output state file if ic.bInputfile is true or the URL is mor than 4000 chars
11993
+ url = this.shareLinkUrl(bAllCommands); // output state file if ic.bInputfile is true or the URL is more than 4000 chars
11971
11994
 
11972
- text += "\nStart of type file======\n";
11973
- text += ic.InputfileType + "\n";
11974
- text += "End of type file======\n";
11995
+ if(url.substr(0,4) == 'http') {
11996
+ text += "\nShare Link: " + url;
11997
+ }
11998
+ else {
11999
+ text += "\nStart of type file======\n";
12000
+ text += ic.InputfileType + "\n";
12001
+ text += "End of type file======\n";
11975
12002
 
11976
- text += "Start of data file======\n";
11977
- //text += ic.InputfileData;
11978
- /// text += ic.saveFileCls.getPDBHeader();
11979
- text += ic.saveFileCls.getAtomPDB(ic.atoms);
12003
+ text += "Start of data file======\n";
12004
+ //text += ic.InputfileData;
12005
+ /// text += ic.saveFileCls.getPDBHeader();
12006
+ text += ic.saveFileCls.getAtomPDB(ic.atoms);
11980
12007
 
11981
- text += "End of data file======\n";
12008
+ text += "End of data file======\n";
11982
12009
 
11983
- text += "Start of state file======\n";
11984
- text += url;
11985
- text += "End of state file======\n";
12010
+ text += "Start of state file======\n";
12011
+ text += url + "\n";
12012
+ text += "End of state file======\n";
12013
+ }
11986
12014
  }
11987
12015
  else {
11988
12016
  url = this.shareLinkUrl();
@@ -11992,7 +12020,7 @@ class ShareLink {
11992
12020
 
11993
12021
  text += "\nStart of state file======\n";
11994
12022
 
11995
- text += url;
12023
+ text += url + "\n";
11996
12024
  text += "End of state file======\n";
11997
12025
  }
11998
12026
  else {
@@ -12018,11 +12046,14 @@ class HlObjects {
12018
12046
  //Show the highlight for the selected atoms: hAtoms.
12019
12047
  addHlObjects(color, bRender, atomsHash) { let ic = this.icn3d, me = ic.icn3dui;
12020
12048
  if(color === undefined) color = ic.hColor;
12021
- if(atomsHash === undefined) atomsHash = ic.hAtoms;
12049
+ //if(atomsHash === undefined) atomsHash = ic.hAtoms;
12050
+ let atomsHashDisplay = (atomsHash) ? me.hashUtilsCls.intHash(atomsHash, ic.dAtoms) : me.hashUtilsCls.intHash(ic.hAtoms, ic.dAtoms);
12022
12051
 
12023
- ic.applyDisplayCls.applyDisplayOptions(ic.opts, me.hashUtilsCls.intHash(atomsHash, ic.dAtoms), ic.bHighlight);
12052
+ ic.applyDisplayCls.applyDisplayOptions(ic.opts, atomsHashDisplay, ic.bHighlight);
12024
12053
 
12025
- if( (bRender) || (ic.bRender) ) ic.drawCls.render();
12054
+ if( (bRender) || (ic.bRender) ) {
12055
+ ic.drawCls.render();
12056
+ }
12026
12057
  };
12027
12058
 
12028
12059
  //Remove the highlight. The atom selection does not change.
@@ -14311,6 +14342,9 @@ class HBond {
14311
14342
  break;
14312
14343
  }
14313
14344
  }
14345
+
14346
+ if(!C_atom) continue;
14347
+
14314
14348
  let inAcceptorC = C_atom.coord;
14315
14349
  let inAcceptorO = inAcceptor.coord;
14316
14350
 
@@ -15468,7 +15502,7 @@ class GetGraph {
15468
15502
  let strokecolor = '#000';
15469
15503
  let strokewidth = '1';
15470
15504
  let textcolor = '#000';
15471
- let fontsize = '6';
15505
+ let fontsize = '6px'; // '6';
15472
15506
  let html = "<g class='icn3d-node' resid='" + resid + "' >";
15473
15507
  html += "<title>" + node.id + "</title>";
15474
15508
  if(bVertical) {
@@ -15482,23 +15516,31 @@ class GetGraph {
15482
15516
  html += "</g>";
15483
15517
  return html;
15484
15518
  }
15485
- getNodeTopBottom(nameHash, name2node, bReverseNode) { let ic = this.icn3d; ic.icn3dui;
15519
+ getNodeTopBottom(nameHash, name2node, bReverseNode, bCommon, nameHashCommon) { let ic = this.icn3d, me = ic.icn3dui;
15486
15520
  let thisClass = this;
15487
- let nodeArray1 = [], nodeArray2 = [];
15521
+ let nodeArray1 = [], nodeArray2 = [], name2nodeCommon = {};
15488
15522
  for(let name in nameHash) {
15489
15523
  let node = name2node[name];
15490
15524
  if(!node) continue;
15491
15525
 
15526
+ if(bCommon) {
15527
+ node = me.hashUtilsCls.cloneHash(node);
15528
+
15529
+ let mapping = (nameHashCommon[name]) ? nameHashCommon[name] : '-';
15530
+ node.id += ">" + mapping;
15531
+ name2nodeCommon[node.id] = node;
15532
+ }
15533
+
15492
15534
  if(node.s == 'a') {
15493
15535
  nodeArray1.push(node);
15494
15536
  }
15495
15537
  else if(node.s == 'b') {
15496
15538
  nodeArray2.push(node);
15497
15539
  }
15498
- else if(node.s == 'ab') {
15499
- nodeArray1.push(node);
15500
- nodeArray2.push(node);
15501
- }
15540
+ //else if(node.s == 'ab') {
15541
+ // nodeArray1.push(node);
15542
+ // nodeArray2.push(node);
15543
+ //}
15502
15544
  }
15503
15545
  // sort array
15504
15546
  nodeArray1.sort(function(a,b) {
@@ -15507,7 +15549,7 @@ class GetGraph {
15507
15549
  nodeArray2.sort(function(a,b) {
15508
15550
  return thisClass.compNode(a, b, bReverseNode);
15509
15551
  });
15510
- return {"nodeArray1": nodeArray1, "nodeArray2": nodeArray2}
15552
+ return {"nodeArray1": nodeArray1, "nodeArray2": nodeArray2, "name2node": name2nodeCommon};
15511
15553
  }
15512
15554
  updateGraphJson(struc, index, nodeArray1, nodeArray2, linkArray) { let ic = this.icn3d, me = ic.icn3dui;
15513
15555
  let lineGraphStr = '';
@@ -15830,22 +15872,31 @@ class LineGraph {
15830
15872
  let structureArray = ic.resid2specCls.atoms2structureArray(ic.hAtoms);
15831
15873
  //if(Object.keys(ic.structures).length > 1) {
15832
15874
  if(structureArray.length > 1) {
15833
- let nodeArray1a = [],
15834
- nodeArray1b = [],
15835
- nodeArray2a = [],
15836
- nodeArray2b = [],
15837
- nodeArray3a = [],
15838
- nodeArray3b = [];
15839
- //let struc1 = Object.keys(ic.structures)[0],
15840
- // struc2 = Object.keys(ic.structures)[1];
15841
- let struc1 = structureArray[0],
15842
- struc2 = structureArray[1];
15843
- let linkArrayA = [],
15844
- linkArrayB = [],
15845
- linkArrayAB = [];
15846
- let nameHashA = {},
15847
- nameHashB = {},
15848
- nameHashAB = {};
15875
+
15876
+ let struc2index= {};
15877
+ let nodeArray1Split = [], nodeArray2Split = [], linkArraySplit = [], nameHashSplit = [];
15878
+
15879
+ // show common interactions: nodes will be the same. The links/interactins are different.
15880
+ // The mapped residue name and number are attached to "id".
15881
+ // Original node: {id : "Q24.A.2AJF", r : "1_1_2AJF_A_24", s: "a", ...}
15882
+ // Node for common interaction: {id : "Q24.A.2AJF|Q24", r : "1_1_2AJF_A_24", s: "a", ...}
15883
+ let nodeArray1SplitCommon = [], nodeArray2SplitCommon = [], linkArraySplitCommon = [], nameHashSplitCommon = [];
15884
+ let linkedNodeCnt = {};
15885
+
15886
+ for(let i = 0, il = structureArray.length; i < il; ++i) {
15887
+ nodeArray1Split[i] = [];
15888
+ nodeArray2Split[i] = [];
15889
+ linkArraySplit[i] = [];
15890
+ nameHashSplit[i] = {};
15891
+
15892
+ nodeArray1SplitCommon[i] = [];
15893
+ nodeArray2SplitCommon[i] = [];
15894
+ linkArraySplitCommon[i] = [];
15895
+ nameHashSplitCommon[i] = {};
15896
+
15897
+ struc2index[structureArray[i]] = i;
15898
+ }
15899
+
15849
15900
  for(let i = 0, il = linkArray.length; i < il; ++i) {
15850
15901
  let link = linkArray[i];
15851
15902
  let nodeA = name2node[link.source];
@@ -15855,70 +15906,131 @@ class LineGraph {
15855
15906
  continue;
15856
15907
  }
15857
15908
 
15858
- //var idArrayA = nodeA.r.split('_'); // 1_1_1KQ2_A_1
15859
- let idArrayA = [];
15860
- idArrayA.push('');
15861
- idArrayA.push('');
15909
+ let idArrayA = this.getIdArrayFromNode(nodeA);
15910
+ let idArrayB = this.getIdArrayFromNode(nodeB);
15862
15911
 
15863
- let tmpStr = nodeA.r.substr(4);
15864
- idArrayA = idArrayA.concat(me.utilsCls.getIdArray(tmpStr));
15912
+ let index = struc2index[idArrayA[2]];
15865
15913
 
15866
- //var idArrayB = nodeB.r.split('_'); // 1_1_1KQ2_A_1
15867
- let idArrayB = [];
15868
- idArrayB.push('');
15869
- idArrayB.push('');
15914
+ if(idArrayA[2] == structureArray[index] && idArrayB[2] == structureArray[index]) {
15915
+ linkArraySplit[index].push(link);
15916
+ nameHashSplit[index][link.source] = 1;
15917
+ nameHashSplit[index][link.target] = 1;
15870
15918
 
15871
- tmpStr = nodeB.r.substr(4);
15872
- idArrayB = idArrayB.concat(me.utilsCls.getIdArray(tmpStr));
15919
+ let chainid1 = idArrayA[2] + '_' + idArrayA[3];
15920
+ let chainid2 = idArrayB[2] + '_' + idArrayB[3];
15921
+ let resid1 = chainid1 + '_' + idArrayA[4];
15922
+ let resid2 = chainid2 + '_' + idArrayB[4];
15873
15923
 
15874
- if(idArrayA[2] == struc1 && idArrayB[2] == struc1) {
15875
- linkArrayA.push(link);
15876
- nameHashA[link.source] = 1;
15877
- nameHashA[link.target] = 1;
15878
- } else if(idArrayA[2] == struc2 && idArrayB[2] == struc2) {
15879
- linkArrayB.push(link);
15880
- nameHashB[link.source] = 1;
15881
- nameHashB[link.target] = 1;
15882
- } else {
15883
- linkArrayAB.push(link);
15884
- nameHashAB[link.source] = 1;
15885
- nameHashAB[link.target] = 1;
15886
- }
15887
- }
15888
- let nodeArraysA = ic.getGraphCls.getNodeTopBottom(nameHashA, name2node);
15889
- nodeArray1a = nodeArraysA.nodeArray1;
15890
- nodeArray1b = nodeArraysA.nodeArray2;
15891
- let nodeArraysB = ic.getGraphCls.getNodeTopBottom(nameHashB, name2node);
15892
- nodeArray2a = nodeArraysB.nodeArray1;
15893
- nodeArray2b = nodeArraysB.nodeArray2;
15894
- let nodeArraysAB = ic.getGraphCls.getNodeTopBottom(nameHashAB, name2node, true);
15895
- nodeArray3a = nodeArraysAB.nodeArray1;
15896
- nodeArray3b = nodeArraysAB.nodeArray2;
15897
- let len1a = nodeArray1a.length,
15898
- len1b = nodeArray1b.length;
15899
- let len2a = nodeArray2a.length,
15900
- len2b = nodeArray2b.length;
15901
- let len3a = nodeArray3a.length,
15902
- len3b = nodeArray3b.length;
15903
- let maxLen = Math.max(len1a, len1b, len2a, len2b, len3a, len3b);
15924
+ let mapping1, mapping2;
15925
+
15926
+ if(ic.chainsMapping[chainid1] && ic.chainsMapping[chainid1][resid1]
15927
+ && ic.chainsMapping[chainid2] && ic.chainsMapping[chainid2][resid2]) {
15928
+ mapping1 = (nodeA.s == "a") ? ic.chainsMapping[chainid1][resid1] : ic.chainsMapping[chainid2][resid2];
15929
+ mapping2 = (nodeA.s == "a") ? ic.chainsMapping[chainid2][resid2] : ic.chainsMapping[chainid1][resid1];
15930
+
15931
+ let mappingid = mapping1 + '_' + mapping2 + '_' + link.c; // link.c determines the interaction type
15932
+ if(!linkedNodeCnt.hasOwnProperty(mappingid)) {
15933
+ linkedNodeCnt[mappingid] = 1;
15934
+ }
15935
+ else {
15936
+ ++linkedNodeCnt[mappingid];
15937
+ }
15938
+ }
15939
+ }
15940
+ }
15941
+
15942
+ // set linkArraySplitCommon and nameHashSplitCommon
15943
+ for(let i = 0, il = linkArray.length; i < il; ++i) {
15944
+ let link = linkArray[i];
15945
+ let nodeA = name2node[link.source];
15946
+ let nodeB = name2node[link.target];
15947
+
15948
+ if(!nodeA || !nodeB || !nodeA.r || !nodeB.r) {
15949
+ continue;
15950
+ }
15951
+
15952
+ let idArrayA = this.getIdArrayFromNode(nodeA);
15953
+ let idArrayB = this.getIdArrayFromNode(nodeB);
15954
+
15955
+ let index = struc2index[idArrayA[2]];
15956
+
15957
+ if(idArrayA[2] == structureArray[index] && idArrayB[2] == structureArray[index]) {
15958
+ let chainid1 = idArrayA[2] + '_' + idArrayA[3];
15959
+ let chainid2 = idArrayB[2] + '_' + idArrayB[3];
15960
+ let resid1 = chainid1 + '_' + idArrayA[4];
15961
+ let resid2 = chainid2 + '_' + idArrayB[4];
15962
+
15963
+ let mapping1, mapping2;
15964
+
15965
+ if(ic.chainsMapping[chainid1] && ic.chainsMapping[chainid1][resid1]
15966
+ && ic.chainsMapping[chainid2] && ic.chainsMapping[chainid2][resid2]) {
15967
+ mapping1 = (nodeA.s == "a") ? ic.chainsMapping[chainid1][resid1] : ic.chainsMapping[chainid2][resid2];
15968
+ mapping2 = (nodeA.s == "a") ? ic.chainsMapping[chainid2][resid2] : ic.chainsMapping[chainid1][resid1];
15969
+
15970
+ let mappingid = mapping1 + '_' + mapping2 + '_' + link.c; // link.c determines the interaction type
15971
+
15972
+ if(linkedNodeCnt[mappingid] == structureArray.length) {
15973
+ let linkCommon = me.hashUtilsCls.cloneHash(link);
15974
+ linkCommon.source += '>' + ic.chainsMapping[chainid1][resid1];
15975
+ linkCommon.target += '>' + ic.chainsMapping[chainid2][resid2];
15976
+
15977
+ linkArraySplitCommon[index].push(linkCommon);
15978
+ }
15979
+
15980
+ nameHashSplitCommon[index][link.source] = ic.chainsMapping[chainid1][resid1];
15981
+ nameHashSplitCommon[index][link.target] = ic.chainsMapping[chainid2][resid2];
15982
+ }
15983
+ }
15984
+ }
15985
+
15986
+ let len1Split = [], len2Split = [], maxWidth = 0;
15904
15987
  let strucArray = [];
15905
- if(linkArrayA.length > 0) strucArray.push(struc1);
15906
- if(linkArrayB.length > 0) strucArray.push(struc2);
15907
- if(linkArrayAB.length > 0) strucArray.push(struc1 + '_' + struc2);
15988
+ for(let i = 0, il = structureArray.length; i < il; ++i) {
15989
+ let nodeArraysTmp = ic.getGraphCls.getNodeTopBottom(nameHashSplit[i], name2node);
15990
+ nodeArray1Split[i] = nodeArraysTmp.nodeArray1;
15991
+ nodeArray2Split[i] = nodeArraysTmp.nodeArray2;
15992
+
15993
+ let bCommon = true;
15994
+ nodeArraysTmp = ic.getGraphCls.getNodeTopBottom(nameHashSplit[i], name2node, undefined, bCommon, nameHashSplitCommon[i]);
15995
+ nodeArray1SplitCommon[i] = nodeArraysTmp.nodeArray1;
15996
+ nodeArray2SplitCommon[i] = nodeArraysTmp.nodeArray2;
15997
+ name2node = me.hashUtilsCls.unionHash(name2node, nodeArraysTmp.name2node);
15998
+
15999
+ len1Split[i] = nodeArray1Split[i].length;
16000
+ len2Split[i] = nodeArray2Split[i].length;
16001
+
16002
+ maxWidth = Math.max(maxWidth, len2Split[i]);
16003
+
16004
+ //if(linkArraySplit[i].length > 0) strucArray.push(structureArray[i]);
16005
+ strucArray.push(structureArray[i]);
16006
+ }
16007
+
15908
16008
  let factor = 1;
15909
16009
  let r = 3 * factor;
15910
16010
  let gap = 7 * factor;
15911
16011
  let height, width, heightAll;
15912
16012
  let marginX = 10,
15913
16013
  marginY = 10,
15914
- legendWidth = 30;
16014
+ legendWidth = 30,
16015
+ textHeight = 20;
16016
+
15915
16017
  if(bScatterplot) {
15916
- heightAll =(len1a + 2 + len2a + 2) *(r + gap) + 4 * marginY + 2 * legendWidth;
15917
- width =(Math.max(len1b, len2b) + 2) *(r + gap) + 2 * marginX + legendWidth;
16018
+ //heightAll =(len1a + 2 + len2a + 2) *(r + gap) + 4 * marginY + 2 * legendWidth;
16019
+ //width =(Math.max(len1b, len2b) + 2) *(r + gap) + 2 * marginX + legendWidth;
16020
+ heightAll =(me.utilsCls.sumArray(len1Split) + 2*strucArray.length) *(r + gap) + 4 * marginY
16021
+ + 2 * legendWidth + textHeight*strucArray.length;
16022
+ // show common interaction as well
16023
+ heightAll *= 2;
16024
+
16025
+ width = (maxWidth + 2) * (r + gap) + 2 * marginX + legendWidth;
16026
+
15918
16027
  } else {
15919
- height = 110;
16028
+ height = 110 + textHeight;
15920
16029
  heightAll = height * strucArray.length;
15921
- width = maxLen *(r + gap) + 2 * marginX;
16030
+ // show common interaction as well
16031
+ heightAll *= 2;
16032
+
16033
+ width = (maxWidth + 2) * (r + gap) + 2 * marginX;
15922
16034
  }
15923
16035
  let id, graphWidth;
15924
16036
  if(bScatterplot) {
@@ -15931,43 +16043,42 @@ class LineGraph {
15931
16043
  id = me.linegraphid;
15932
16044
  }
15933
16045
  html =(strucArray.length == 0) ? "No interactions found for each structure<br><br>" :
15934
- "2D integration graph for structure(s) <b>" + strucArray + "</b><br><br>";
16046
+ "2D integration graph for " + strucArray.length + " structure(s) <b>" + strucArray + "</b>. Common interactions are shown in the last " + strucArray.length + " graphs.<br><br>";
15935
16047
  html += "<svg id='" + id + "' viewBox='0,0," + width + "," + heightAll + "' width='" + graphWidth + "px'>";
15936
- let heightFinal = 0;
15937
- if(linkArrayA.length > 0) {
16048
+
16049
+ let heightFinal = 0;
16050
+ for(let i = 0, il = structureArray.length; i < il; ++i) {
15938
16051
  if(bScatterplot) {
15939
- heightFinal -= 15;
15940
- html += this.drawScatterplot_base(nodeArray1a, nodeArray1b, linkArrayA, name2node, heightFinal);
15941
- heightFinal = 15;
15942
- height =(len1a + 1) *(r + gap) + 2 * marginY;
16052
+ //heightFinal -= 15;
16053
+ html += this.drawScatterplot_base(nodeArray1Split[i], nodeArray2Split[i], linkArraySplit[i], name2node, heightFinal, undefined, "Interactions in structure " + strucArray[i], textHeight);
16054
+ //heightFinal = 15;
16055
+ height =(len1Split[i] + 1) *(r + gap) + 2 * marginY + textHeight;
15943
16056
  } else {
15944
- html += this.drawLineGraph_base(nodeArray1a, nodeArray1b, linkArrayA, name2node, heightFinal);
16057
+ html += this.drawLineGraph_base(nodeArray1Split[i], nodeArray2Split[i], linkArraySplit[i], name2node, heightFinal, "Interactions in structure " + strucArray[i], textHeight);
15945
16058
  }
15946
16059
  heightFinal += height;
15947
- ic.lineGraphStr += ic.getGraphCls.updateGraphJson(struc1, 1, nodeArray1a, nodeArray1b, linkArrayA);
16060
+
16061
+ if(i > 0) ic.lineGraphStr += ', \n';
16062
+ ic.lineGraphStr += ic.getGraphCls.updateGraphJson(strucArray[i], i, nodeArray1Split[i], nodeArray2Split[i], linkArraySplit[i]);
15948
16063
  }
15949
- if(linkArrayB.length > 0) {
16064
+
16065
+ // draw common interaction
16066
+ for(let i = 0, il = structureArray.length; i < il; ++i) {
15950
16067
  if(bScatterplot) {
15951
- html += this.drawScatterplot_base(nodeArray2a, nodeArray2b, linkArrayB, name2node, heightFinal);
15952
- height =(len2a + 1) *(r + gap) + 2 * marginY;
16068
+ //heightFinal -= 15;
16069
+ html += this.drawScatterplot_base(nodeArray1SplitCommon[i], nodeArray2SplitCommon[i], linkArraySplitCommon[i], name2node, heightFinal, undefined, "Common interactions in structure " + strucArray[i], textHeight);
16070
+ //heightFinal = 15;
16071
+ height =(len1Split[i] + 1) *(r + gap) + 2 * marginY + textHeight;
15953
16072
  } else {
15954
- html += this.drawLineGraph_base(nodeArray2a, nodeArray2b, linkArrayB, name2node, heightFinal);
16073
+ html += this.drawLineGraph_base(nodeArray1SplitCommon[i], nodeArray2SplitCommon[i], linkArraySplitCommon[i], name2node, heightFinal, "Common interactions in structure " + strucArray[i], textHeight);
15955
16074
  }
15956
16075
  heightFinal += height;
15957
- if(linkArrayA.length > 0) ic.lineGraphStr += ', \n';
15958
- ic.lineGraphStr += ic.getGraphCls.updateGraphJson(struc2, 2, nodeArray2a, nodeArray2b, linkArrayB);
15959
- }
15960
- if(linkArrayAB.length > 0 && !bScatterplot) {
15961
- html += this.drawLineGraph_base(nodeArray3a, nodeArray3b, linkArrayAB, name2node, heightFinal);
15962
- if(linkArrayA.length > 0 || linkArrayB.length > 0) ic.lineGraphStr += ', \n';
15963
- ic.lineGraphStr += '"structure1_2": {"id1": "' + struc1 + '", "id2": "' + struc2 + '", "nodes1":[';
15964
- ic.lineGraphStr += me.utilsCls.getJSONFromArray(nodeArray3a);
15965
- ic.lineGraphStr += '], \n"nodes2":[';
15966
- ic.lineGraphStr += me.utilsCls.getJSONFromArray(nodeArray3b);
15967
- ic.lineGraphStr += '], \n"links":[';
15968
- ic.lineGraphStr += me.utilsCls.getJSONFromArray(linkArrayAB);
15969
- ic.lineGraphStr += ']}';
16076
+
16077
+ //if(i > 0) ic.lineGraphStr += ', \n';
16078
+ ic.lineGraphStr += ', \n';
16079
+ ic.lineGraphStr += ic.getGraphCls.updateGraphJson(strucArray[i], i + '_common', nodeArray1SplitCommon[i], nodeArray2SplitCommon[i], linkArraySplitCommon[i]);
15970
16080
  }
16081
+
15971
16082
  html += "</svg>";
15972
16083
  } else {
15973
16084
  if(!bScatterplot) {
@@ -16025,7 +16136,18 @@ class LineGraph {
16025
16136
  return html;
16026
16137
  }
16027
16138
 
16028
- drawLineGraph_base(nodeArray1, nodeArray2, linkArray, name2node, height) { let ic = this.icn3d, me = ic.icn3dui;
16139
+ getIdArrayFromNode(node) { let ic = this.icn3d, me = ic.icn3dui;
16140
+ let idArray = []; // 1_1_1KQ2_A_1
16141
+ idArray.push('');
16142
+ idArray.push('');
16143
+
16144
+ let tmpStr = node.r.substr(4);
16145
+ idArray = idArray.concat(me.utilsCls.getIdArray(tmpStr));
16146
+
16147
+ return idArray;
16148
+ }
16149
+
16150
+ drawLineGraph_base(nodeArray1, nodeArray2, linkArray, name2node, height, label, textHeight) { let ic = this.icn3d, me = ic.icn3dui;
16029
16151
  let html = '';
16030
16152
  let len1 = nodeArray1.length,
16031
16153
  len2 = nodeArray2.length;
@@ -16042,6 +16164,13 @@ class LineGraph {
16042
16164
  margin2 = margin;
16043
16165
  margin1 = Math.abs(len1 - len2) *(r + gap) * 0.5 + margin;
16044
16166
  }
16167
+
16168
+ // draw label
16169
+ if(label) {
16170
+ height += textHeight;
16171
+ html += "<text x='" + margin1 + "' y='" + height + "' style='font-size:8px; font-weight:bold'>" + label + "</text>";
16172
+ }
16173
+
16045
16174
  let h1 = 30 + height,
16046
16175
  h2 = 80 + height;
16047
16176
  let nodeHtml = '';
@@ -16097,7 +16226,7 @@ class LineGraph {
16097
16226
  return html;
16098
16227
  }
16099
16228
 
16100
- drawScatterplot_base(nodeArray1, nodeArray2, linkArray, name2node, height, bContactMap) { let ic = this.icn3d; ic.icn3dui;
16229
+ drawScatterplot_base(nodeArray1, nodeArray2, linkArray, name2node, height, bContactMap, label, textHeight) { let ic = this.icn3d; ic.icn3dui;
16101
16230
  let html = '';
16102
16231
  let len1 = nodeArray1.length,
16103
16232
  len2 = nodeArray2.length;
@@ -16108,12 +16237,20 @@ class LineGraph {
16108
16237
  let marginX = 10,
16109
16238
  marginY = 20;
16110
16239
  let heightTotal =(len1 + 1) *(r + gap) + legendWidth + 2 * marginY;
16240
+
16241
+ // draw label
16242
+ if(label) {
16243
+ height += textHeight;
16244
+ html += "<text x='" + marginX + "' y='" + (height + 15).toString() + "' style='font-size:8px; font-weight:bold'>" + label + "</text>";
16245
+ }
16246
+
16111
16247
  let margin1 = height + heightTotal -(legendWidth + marginY +(r + gap)); // y-axis
16112
16248
  let margin2 = legendWidth + marginX +(r + gap); // x-axis
16113
- let x = legendWidth + marginX;
16249
+
16114
16250
  let nodeHtml = '';
16115
16251
  let node2posSet1 = {},
16116
16252
  node2posSet2 = {};
16253
+ let x = legendWidth + marginX;
16117
16254
  for(let i = 0; i < len1; ++i) {
16118
16255
  nodeHtml += ic.getGraphCls.drawResNode(nodeArray1[i], i, r, gap, margin1, x, 'a', true);
16119
16256
  node2posSet1[nodeArray1[i].id] = { x: x, y: margin1 - i *(r + gap) };
@@ -16485,8 +16622,9 @@ class ViewInterPairs {
16485
16622
  tmpText = 'Set 2';
16486
16623
  }
16487
16624
  html += '<div style="text-align:center"><br><b>Interactions Sorted on ' + tmpText + '</b>: <button class="' + ic.pre + 'showintercntonly" style="margin-left:20px">Show Count Only</button><button class="' + ic.pre + 'showinterdetails" style="margin-left:20px">Show Details</button></div>';
16488
- html += this.getAllInteractionTable(type).html;
16489
- bondCnt = this.getAllInteractionTable(type).bondCnt;
16625
+ let result = this.getAllInteractionTable(type);
16626
+ html += result.html;
16627
+ bondCnt = result.bondCnt;
16490
16628
 
16491
16629
  $("#" + ic.pre + "dl_interactionsorted").html(html);
16492
16630
  me.htmlCls.dialogCls.openDlg('dl_interactionsorted', 'Show sorted interactions');
@@ -18359,7 +18497,7 @@ class ResidueLabels {
18359
18497
  if(me.bNode) return;
18360
18498
 
18361
18499
  let size = 18;
18362
- let background = "#CCCCCC";
18500
+ let background = "#FFFFFF"; //"#CCCCCC";
18363
18501
 
18364
18502
  let atomsHash = me.hashUtilsCls.intHash(ic.hAtoms, atoms);
18365
18503
 
@@ -18399,7 +18537,15 @@ class ResidueLabels {
18399
18537
  label.factor = 0.3;
18400
18538
 
18401
18539
  let atomColorStr = atom.color.getHexString().toUpperCase();
18402
- label.color = (atomColorStr === "CCCCCC" || atomColorStr === "C8C8C8") ? "#888888" : "#" + atomColorStr;
18540
+ //label.color = (ic.opts.background != 'black') ? ic.colorWhitebkgd : ic.colorBlackbkgd; //(atomColorStr === "CCCCCC" || atomColorStr === "C8C8C8") ? "#888888" : "#" + atomColorStr;
18541
+ //if(bSchematic) label.color = (atomColorStr === "CCCCCC" || atomColorStr === "C8C8C8") ? "#888888" : "#" + atomColorStr;
18542
+ // don't change residue labels
18543
+ if(bNumber) {
18544
+ label.color = (ic.opts.background != 'black') ? ic.colorWhitebkgd : ic.colorBlackbkgd;
18545
+ }
18546
+ else {
18547
+ label.color = (atomColorStr === "CCCCCC" || atomColorStr === "C8C8C8") ? "#888888" : "#" + atomColorStr;
18548
+ }
18403
18549
  label.background = background;
18404
18550
  //label.alpha = alpha; // ic.labelCls.hideLabels() didn't work. Remove this line for now
18405
18551
 
@@ -18443,7 +18589,7 @@ class ResidueLabels {
18443
18589
  label.text = atom.elem;
18444
18590
  label.size = size;
18445
18591
 
18446
- label.color = "#" + atom.color.getHexString();
18592
+ label.color = (ic.opts.background != 'black') ? ic.colorWhitebkgd : atom.color.getHexString();
18447
18593
  label.background = background;
18448
18594
 
18449
18595
  ic.labels['schematic'].push(label);
@@ -18481,7 +18627,8 @@ class ResidueLabels {
18481
18627
  }
18482
18628
 
18483
18629
  let atomColorStr = atom.color.getHexString().toUpperCase();
18484
- label.color = (atomColorStr === "CCCCCC" || atomColorStr === "C8C8C8") ? "#888888" : "#" + atomColorStr;
18630
+ label.color = (ic.opts.background != 'black') ? ic.colorWhitebkgd : ic.colorBlackbkgd; //(atomColorStr === "CCCCCC" || atomColorStr === "C8C8C8") ? "#888888" : "#" + atomColorStr;
18631
+ if(bElement) label.color = (atomColorStr === "CCCCCC" || atomColorStr === "C8C8C8") ? "#888888" : "#" + atomColorStr;
18485
18632
  label.background = background;
18486
18633
 
18487
18634
  ic.labels['residue'].push(label);
@@ -19260,7 +19407,8 @@ class Scap {
19260
19407
  if(!ic.alertAlt) {
19261
19408
  ic.alertAlt = true;
19262
19409
 
19263
- if(ic.bRender) var aaa = 1; //alert('Please press the letter "a" to alternate between wild type and mutant.');
19410
+ //if(ic.bRender) var aaa = 1; //alert('Please press the letter "a" to alternate between wild type and mutant.');
19411
+ var aaa = 1; //alert('Please press the letter "a" to alternate between wild type and mutant.');
19264
19412
  }
19265
19413
  }
19266
19414
 
@@ -19908,8 +20056,7 @@ class LoadPDB {
19908
20056
  // modified from iview (http://istar.cse.cuhk.edu.hk/iview/)
19909
20057
  //This PDB parser feeds the viewer with the content of a PDB file, pdbData.
19910
20058
  loadPDB(src, pdbid, bOpm, bVector, bMutation, bAppend) { let ic = this.icn3d, me = ic.icn3dui;
19911
- let helices = [], sheets = [];
19912
- //ic.atoms = {}
20059
+ let bNMR = false;
19913
20060
  let lines = src.split('\n');
19914
20061
 
19915
20062
  let chainsTmp = {}; // serial -> atom
@@ -19948,20 +20095,23 @@ class LoadPDB {
19948
20095
  serial = (ic.atoms) ? Object.keys(ic.atoms).length : 0;
19949
20096
  }
19950
20097
 
19951
- let sheetArray = [], sheetStart = [], sheetEnd = [], helixArray = [], helixStart = [], helixEnd = [];
20098
+ //let helices = [], sheets = [];
20099
+ let sheetArray = [], sheetStart = [], sheetEnd = [], helixArray = [], helixStart = [], helixEnd = [];
19952
20100
 
19953
20101
  let chainNum, residueNum, oriResidueNum;
19954
20102
  let prevChainNum = '', prevResidueNum = '', prevOriResidueNum = '';
19955
20103
 
19956
20104
  let oriSerial2NewSerial = {};
19957
20105
 
19958
- let chainMissingResidueArray = {};
20106
+ //let chainMissingResidueArray = {}
19959
20107
 
19960
20108
  let id = (pdbid) ? pdbid : 'stru';
19961
20109
 
19962
- let maxMissingResi = 0, prevMissingChain = '';
20110
+ let prevMissingChain = '';
19963
20111
  let CSerial, prevCSerial, OSerial, prevOSerial;
19964
20112
 
20113
+ let structure = "stru";
20114
+
19965
20115
  for (let i in lines) {
19966
20116
  let line = lines[i];
19967
20117
  let record = line.substr(0, 6);
@@ -19982,6 +20132,12 @@ class LoadPDB {
19982
20132
  }
19983
20133
  }
19984
20134
 
20135
+ structure = id;
20136
+
20137
+ if(id == 'stru' || bMutation || (bAppend && id.length != 4)) { // bMutation: side chain prediction
20138
+ structure = (moleculeNum === 1) ? id : id + moleculeNum.toString();
20139
+ }
20140
+
19985
20141
  ic.molTitle = '';
19986
20142
 
19987
20143
  } else if (record === 'TITLE ') {
@@ -19996,22 +20152,23 @@ class LoadPDB {
19996
20152
  let startResi = parseInt(line.substr(21, 4));
19997
20153
  let endResi = parseInt(line.substr(33, 4));
19998
20154
 
19999
- let chain_resi;
20000
20155
  for(let j = startResi; j <= endResi; ++j) {
20001
- chain_resi = startChain + "_" + j;
20002
- helixArray.push(chain_resi);
20156
+ let resid = structure + "_" + startChain + "_" + j;
20157
+ helixArray.push(resid);
20003
20158
 
20004
- if(j === startResi) helixStart.push(chain_resi);
20005
- if(j === endResi) helixEnd.push(chain_resi);
20159
+ if(j === startResi) helixStart.push(resid);
20160
+ if(j === endResi) helixEnd.push(resid);
20006
20161
  }
20007
-
20162
+ /*
20008
20163
  helices.push({
20164
+ structure: structure,
20009
20165
  chain: startChain,
20010
20166
  initialResidue: startResi,
20011
20167
  initialInscode: line.substr(25, 1),
20012
20168
  terminalResidue: endResi,
20013
20169
  terminalInscode: line.substr(37, 1),
20014
20170
  });
20171
+ */
20015
20172
  } else if (record === 'SHEET ') {
20016
20173
  //ic.bSecondaryStructure = true;
20017
20174
  if(bOpm === undefined || !bOpm) ic.bSecondaryStructure = true;
@@ -20022,20 +20179,22 @@ class LoadPDB {
20022
20179
  let endResi = parseInt(line.substr(33, 4));
20023
20180
 
20024
20181
  for(let j = startResi; j <= endResi; ++j) {
20025
- let chain_resi = startChain + "_" + j;
20026
- sheetArray.push(chain_resi);
20182
+ let resid = structure + "_" + startChain + "_" + j;
20183
+ sheetArray.push(resid);
20027
20184
 
20028
- if(j === startResi) sheetStart.push(chain_resi);
20029
- if(j === endResi) sheetEnd.push(chain_resi);
20185
+ if(j === startResi) sheetStart.push(resid);
20186
+ if(j === endResi) sheetEnd.push(resid);
20030
20187
  }
20031
-
20188
+ /*
20032
20189
  sheets.push({
20190
+ structure: structure,
20033
20191
  chain: startChain,
20034
20192
  initialResidue: startResi,
20035
20193
  initialInscode: line.substr(26, 1),
20036
20194
  terminalResidue: endResi,
20037
20195
  terminalInscode: line.substr(37, 1),
20038
20196
  });
20197
+ */
20039
20198
  } else if (record === 'HBOND ') {
20040
20199
  if(bOpm === undefined || !bOpm) ic.bSecondaryStructure = true;
20041
20200
  /*
@@ -20082,6 +20241,11 @@ class LoadPDB {
20082
20241
  if(line.indexOf('1/2 of bilayer thickness:') !== -1) { // OPM transmembrane protein
20083
20242
  ic.halfBilayerSize = parseFloat(line.substr(line.indexOf(':') + 1).trim());
20084
20243
  }
20244
+ else if (type == 210) {
20245
+ if((line.substr(11, 32).trim() == 'EXPERIMENT TYPE') && line.substr(45).trim() == 'NMR') {
20246
+ bNMR = true;
20247
+ }
20248
+ }
20085
20249
  else if (type == 350 && line.substr(13, 5) == 'BIOMT') {
20086
20250
  let n = parseInt(line[18]) - 1;
20087
20251
  //var m = parseInt(line.substr(21, 2));
@@ -20098,7 +20262,8 @@ class LoadPDB {
20098
20262
  let resn = line.substr(15, 3);
20099
20263
  //let chain = line.substr(19, 1);
20100
20264
  let chain = line.substr(18, 2).trim();
20101
- let resi = parseInt(line.substr(21, 5));
20265
+ //let resi = parseInt(line.substr(21, 5));
20266
+ let resi = line.substr(21, 5);
20102
20267
 
20103
20268
  //var structure = parseInt(line.substr(13, 1));
20104
20269
  //if(line.substr(13, 1) == ' ') structure = 1;
@@ -20106,20 +20271,15 @@ class LoadPDB {
20106
20271
  //var chainNum = structure + '_' + chain;
20107
20272
  let chainNum = id + '_' + chain;
20108
20273
 
20109
- if(chainMissingResidueArray[chainNum] === undefined) chainMissingResidueArray[chainNum] = [];
20274
+ if(ic.chainMissingResidueArray[chainNum] === undefined) ic.chainMissingResidueArray[chainNum] = [];
20110
20275
  let resObject = {};
20111
20276
  resObject.resi = resi;
20112
20277
  resObject.name = me.utilsCls.residueName2Abbr(resn).toLowerCase();
20113
20278
 
20114
- if(chain != prevMissingChain) {
20115
- maxMissingResi = 0;
20116
- }
20117
-
20118
20279
  // not all listed residues are considered missing, e.g., PDB ID 4OR2, only the firts four residues are considered missing
20119
- if(!isNaN(resi) && (prevMissingChain == '' || (chain != prevMissingChain) || (chain == prevMissingChain && resi > maxMissingResi)) ) {
20120
- chainMissingResidueArray[chainNum].push(resObject);
20121
-
20122
- maxMissingResi = resi;
20280
+ //if(!isNaN(resi) && (prevMissingChain == '' || (chain != prevMissingChain) || (chain == prevMissingChain && resi > maxMissingResi)) ) {
20281
+ if(prevMissingChain == '' || (chain != prevMissingChain) || (chain == prevMissingChain) ) {
20282
+ ic.chainMissingResidueArray[chainNum].push(resObject);
20123
20283
  prevMissingChain = chain;
20124
20284
  }
20125
20285
 
@@ -20135,21 +20295,27 @@ class LoadPDB {
20135
20295
  } else if (record === 'ENDMDL') {
20136
20296
  ++moleculeNum;
20137
20297
  id = 'stru';
20298
+
20299
+ structure = id;
20300
+ if(id == 'stru' || bMutation || (bAppend && id.length != 4)) { // bMutation: side chain prediction
20301
+ structure = (moleculeNum === 1) ? id : id + moleculeNum.toString();
20302
+ }
20303
+
20304
+ //helices = [];
20305
+ //sheets = [];
20306
+ if(!bNMR) {
20307
+ sheetArray = [];
20308
+ sheetStart = [];
20309
+ sheetEnd = [];
20310
+ helixArray = [];
20311
+ helixStart = [];
20312
+ helixEnd = [];
20313
+ }
20138
20314
  } else if (record === 'JRNL ') {
20139
20315
  if(line.substr(12, 4) === 'PMID') {
20140
20316
  ic.pmid = line.substr(19).trim();
20141
20317
  }
20142
20318
  } else if (record === 'ATOM ' || record === 'HETATM') {
20143
- //if(id == 'stru' && bOpm) {
20144
- // id = pdbid;
20145
- //}
20146
-
20147
- let structure = id;
20148
- //if(id == 'stru' || bMutation || (bAppend && id == 'stru')) { // bMutation: side chain prediction
20149
- if(id == 'stru' || bMutation || (bAppend)) { // bMutation: side chain prediction
20150
- structure = (moleculeNum === 1) ? id : id + moleculeNum.toString();
20151
- }
20152
-
20153
20319
  let alt = line.substr(16, 1);
20154
20320
  //if (alt !== " " && alt !== "A") continue;
20155
20321
 
@@ -20191,7 +20357,7 @@ class LoadPDB {
20191
20357
 
20192
20358
  residueNum = chainNum + "_" + resi;
20193
20359
 
20194
- let chain_resi = chain + "_" + resi;
20360
+ //let chain_resi = chain + "_" + resi;
20195
20361
 
20196
20362
  let x = parseFloat(line.substr(30, 8));
20197
20363
  let y = parseFloat(line.substr(38, 8));
@@ -20242,27 +20408,26 @@ class LoadPDB {
20242
20408
 
20243
20409
  // Assign secondary structures from the input
20244
20410
  // if a residue is assigned both sheet and helix, it is assigned as sheet
20245
- if($.inArray(chain_resi, sheetArray) !== -1) {
20411
+ if(this.isSecondary(residueNum, sheetArray, bNMR)) {
20246
20412
  ic.atoms[serial].ss = 'sheet';
20247
-
20248
- if($.inArray(chain_resi, sheetStart) !== -1) {
20413
+ if(this.isSecondary(residueNum, sheetStart, bNMR)) {
20249
20414
  ic.atoms[serial].ssbegin = true;
20250
20415
  }
20251
20416
 
20252
20417
  // do not use else if. Some residues are both start and end of secondary structure
20253
- if($.inArray(chain_resi, sheetEnd) !== -1) {
20418
+ if(this.isSecondary(residueNum, sheetEnd, bNMR)) {
20254
20419
  ic.atoms[serial].ssend = true;
20255
20420
  }
20256
20421
  }
20257
- else if($.inArray(chain_resi, helixArray) !== -1) {
20422
+ else if(this.isSecondary(residueNum, helixArray, bNMR)) {
20258
20423
  ic.atoms[serial].ss = 'helix';
20259
20424
 
20260
- if($.inArray(chain_resi, helixStart) !== -1) {
20425
+ if(this.isSecondary(residueNum, helixStart, bNMR)) {
20261
20426
  ic.atoms[serial].ssbegin = true;
20262
20427
  }
20263
20428
 
20264
20429
  // do not use else if. Some residues are both start and end of secondary structure
20265
- if($.inArray(chain_resi, helixEnd) !== -1) {
20430
+ if(this.isSecondary(residueNum, helixEnd, bNMR)) {
20266
20431
  ic.atoms[serial].ssend = true;
20267
20432
  }
20268
20433
  }
@@ -20360,7 +20525,7 @@ class LoadPDB {
20360
20525
  if(ic.chains[chainNum] === undefined) ic.chains[chainNum] = {};
20361
20526
  ic.chains[chainNum] = me.hashUtilsCls.unionHash2Atoms(ic.chains[chainNum], chainsTmp, ic.atoms);
20362
20527
 
20363
- if(!bMutation) this.adjustSeq(chainMissingResidueArray);
20528
+ if(!bMutation) this.adjustSeq(ic.chainMissingResidueArray);
20364
20529
 
20365
20530
  // ic.missingResidues = [];
20366
20531
  // for(let chainid in chainMissingResidueArray) {
@@ -20545,10 +20710,11 @@ class LoadPDB {
20545
20710
  for(let chainNum in ic.chainsSeq) {
20546
20711
  if(chainMissingResidueArray[chainNum] === undefined) continue;
20547
20712
 
20548
- let A = ic.chainsSeq[chainNum];
20549
- //var A2 = ic.chainsAn[chainNum][0];
20550
- //var A3 = ic.chainsAn[chainNum][1];
20551
- let B = chainMissingResidueArray[chainNum];
20713
+ //let A = ic.chainsSeq[chainNum];
20714
+ //let B = chainMissingResidueArray[chainNum];
20715
+
20716
+ let A = chainMissingResidueArray[chainNum];
20717
+ let B = ic.chainsSeq[chainNum];
20552
20718
 
20553
20719
  let m = A.length;
20554
20720
  let n = B.length;
@@ -20566,7 +20732,7 @@ class LoadPDB {
20566
20732
  j = 0;
20567
20733
  k = 0;
20568
20734
  while (i < m && j < n) {
20569
- if (A[i].resi <= B[j].resi) {
20735
+ if (parseInt(A[i].resi) <= parseInt(B[j].resi)) {
20570
20736
  C[k] = A[i];
20571
20737
  //C2[k] = A2[i];
20572
20738
  //C3[k] = A3[i];
@@ -20702,6 +20868,24 @@ class LoadPDB {
20702
20868
  return {'chainresiCalphaHash': chainCalphaHash, 'center': ic.center.clone()}
20703
20869
  }
20704
20870
 
20871
+ isSecondary(resid, residArray, bNMR) { let ic = this.icn3d; ic.icn3dui;
20872
+ if(!bNMR) {
20873
+ return $.inArray(resid, residArray) != -1;
20874
+ }
20875
+ else {
20876
+ let chain_resi = resid.substr(resid.indexOf('_') + 1);
20877
+
20878
+ let bFound = false;
20879
+ for(let i = 0, il = residArray.length; i < il; ++i) {
20880
+ if(chain_resi == residArray[i].substr(residArray[i].indexOf('_') + 1)) {
20881
+ bFound = true;
20882
+ break;
20883
+ }
20884
+ }
20885
+
20886
+ return bFound;
20887
+ }
20888
+ }
20705
20889
  }
20706
20890
 
20707
20891
  /**
@@ -20749,6 +20933,7 @@ class LoadAtomData {
20749
20933
  let refinedStr =(me.cfg.inpara && me.cfg.inpara.indexOf('atype=1') !== -1) ? 'Invariant Core ' : '';
20750
20934
  ic.molTitle = refinedStr + 'Structure Alignment of ';
20751
20935
 
20936
+ let bTitle = false;
20752
20937
  for(let i = 0, il = data.alignedStructures[0].length; i < il; ++i) {
20753
20938
  let structure = data.alignedStructures[0][i];
20754
20939
 
@@ -20786,10 +20971,13 @@ class LoadAtomData {
20786
20971
  ic.molTitle += " and ";
20787
20972
  if(structure.descr !== undefined) ic.pmid += "_";
20788
20973
  }
20974
+
20975
+ bTitle = true;
20789
20976
  }
20790
20977
 
20791
20978
  ic.molTitle += ' from VAST+';
20792
20979
 
20980
+ if(!bTitle) ic.molTitle = '';
20793
20981
  }
20794
20982
  else { // mmdbid or mmcifid
20795
20983
  if(data.descr !== undefined) ic.molTitle += data.descr.name;
@@ -22289,7 +22477,7 @@ class PdbParser {
22289
22477
  let url, dataType;
22290
22478
 
22291
22479
  if(bAf) {
22292
- url = "https://alphafold.ebi.ac.uk/files/AF-" + pdbid + "-F1-model_v1.pdb";
22480
+ url = "https://alphafold.ebi.ac.uk/files/AF-" + pdbid + "-F1-model_v2.pdb";
22293
22481
  ic.ParserUtilsCls.setYourNote(pdbid.toUpperCase() + '(AlphaFold) in iCn3D');
22294
22482
  }
22295
22483
  else {
@@ -22341,7 +22529,7 @@ class PdbParser {
22341
22529
 
22342
22530
  //Load structures from a "URL". Due to the same domain policy of Ajax call, the URL should be in the same
22343
22531
  //domain. "type" could be "pdb", "mol2", "sdf", or "xyz" for pdb file, mol2file, sdf file, and xyz file, respectively.
22344
- downloadUrl(url, type) { let ic = this.icn3d, me = ic.icn3dui;
22532
+ downloadUrl(url, type, command) { let ic = this.icn3d, me = ic.icn3dui;
22345
22533
  let thisClass = this;
22346
22534
 
22347
22535
  let pos = url.lastIndexOf('/');
@@ -22378,6 +22566,7 @@ class PdbParser {
22378
22566
 
22379
22567
  if(type === 'pdb') {
22380
22568
  thisClass.loadPdbData(data);
22569
+ ic.loadScriptCls.loadScript(command);
22381
22570
  }
22382
22571
  else if(type === 'mol2') {
22383
22572
  ic.mol2ParserCls.loadMol2Data(data);
@@ -22393,7 +22582,7 @@ class PdbParser {
22393
22582
  }
22394
22583
  else if(type === 'icn3dpng') {
22395
22584
  ic.mmcifParserCls.loadMmcifData(data);
22396
- me.htmlCls.setHtmlCls.loadPng(data);
22585
+ me.htmlCls.setHtmlCls.loadPng(data, command);
22397
22586
  }
22398
22587
  },
22399
22588
  error : function(xhr, textStatus, errorThrown ) {
@@ -23004,13 +23193,13 @@ class AlignParser {
23004
23193
 
23005
23194
  request
23006
23195
  .fail(function() {
23007
- var aaa = 1; //alert("These two MMDB IDs " + alignArray + " do not have 3D alignment data.");
23196
+ var aaa = 1; //alert("These two MMDB IDs " + alignArray + " do not have 3D alignment data in the VAST+ database. You can try the VAST alignment by visiting the VAST+ page https://www.ncbi.nlm.nih.gov/Structure/vastplus/vastplus.cgi?uid=[PDB ID] (e.g., uid=1KQ2), and clicking \"Original VAST\"");
23008
23197
  return false;
23009
23198
  })
23010
23199
  .then(function( data ) {
23011
23200
  seqalign = data.seqalign;
23012
23201
  if(seqalign === undefined) {
23013
- var aaa = 1; //alert("These two MMDB IDs " + alignArray + " do not have 3D alignment data.");
23202
+ var aaa = 1; //alert("These two MMDB IDs " + alignArray + " do not have 3D alignment data in the VAST+ database. You can try the VAST alignment by visiting the VAST+ page https://www.ncbi.nlm.nih.gov/Structure/vastplus/vastplus.cgi?uid=[PDB ID] (e.g., uid=1KQ2), and clicking \"Original VAST\"");
23014
23203
  return false;
23015
23204
  }
23016
23205
 
@@ -23093,11 +23282,11 @@ class AlignParser {
23093
23282
  ic.alignmolid2color.push(tmpHash);
23094
23283
  }
23095
23284
 
23096
- //var url3 = me.htmlCls.baseUrl + 'mmdb/mmdb_strview.cgi?v=2&program=icn3d&b=1&s=1&ft=1&atomonly=1&uid=' + ic.mmdbidArray[0];
23097
- //var url4 = me.htmlCls.baseUrl + 'mmdb/mmdb_strview.cgi?v=2&program=icn3d&b=1&s=1&ft=1&atomonly=1&uid=' + ic.mmdbidArray[1];
23285
+ //var url3 = me.htmlCls.baseUrl + "mmdb/mmdb_strview.cgi?v=2&program=icn3d&b=1&s=1&ft=1&buidx=" + me.cfg.buidx + "&atomonly=1&uid=" + ic.mmdbidArray[0];
23286
+ //var url4 = me.htmlCls.baseUrl + "mmdb/mmdb_strview.cgi?v=2&program=icn3d&b=1&s=1&ft=1&buidx=" + me.cfg.buidx + "&atomonly=1&uid=" + ic.mmdbidArray[1];
23098
23287
  // need the parameter moleculeInfor
23099
- let url3 = me.htmlCls.baseUrl + 'mmdb/mmdb_strview.cgi?v=2&program=icn3d&b=1&s=1&ft=1&uid=' + ic.mmdbidArray[0];
23100
- let url4 = me.htmlCls.baseUrl + 'mmdb/mmdb_strview.cgi?v=2&program=icn3d&b=1&s=1&ft=1&uid=' + ic.mmdbidArray[1];
23288
+ let url3 = me.htmlCls.baseUrl + "mmdb/mmdb_strview.cgi?v=2&program=icn3d&b=1&s=1&ft=1&buidx=" + me.cfg.buidx + "&uid=" + ic.mmdbidArray[0];
23289
+ let url4 = me.htmlCls.baseUrl + "mmdb/mmdb_strview.cgi?v=2&program=icn3d&b=1&s=1&ft=1&buidx=" + me.cfg.buidx + "&uid=" + ic.mmdbidArray[1];
23101
23290
 
23102
23291
  let d3 = $.ajax({
23103
23292
  url: url3,
@@ -23632,10 +23821,10 @@ class MmdbParser {
23632
23821
  // b: b-factor, s: water, ft: pdbsite
23633
23822
  //&ft=1
23634
23823
  if(bGi) {
23635
- url = me.htmlCls.baseUrl + "mmdb/mmdb_strview.cgi?v=2&program=icn3d&b=1&s=1&ft=1&simple=1&gi=" + mmdbid;
23824
+ url = me.htmlCls.baseUrl + "mmdb/mmdb_strview.cgi?v=2&program=icn3d&b=1&s=1&ft=1&buidx=" + me.cfg.buidx + "&simple=1&gi=" + mmdbid;
23636
23825
  }
23637
23826
  else {
23638
- url = me.htmlCls.baseUrl + "mmdb/mmdb_strview.cgi?v=2&program=icn3d&b=1&s=1&ft=1&simple=1&uid=" + mmdbid;
23827
+ url = me.htmlCls.baseUrl + "mmdb/mmdb_strview.cgi?v=2&program=icn3d&b=1&s=1&ft=1&buidx=" + me.cfg.buidx + "&simple=1&uid=" + mmdbid;
23639
23828
  }
23640
23829
 
23641
23830
  // use asymmetric unit for BLAST search, e.g., https://www.ncbi.nlm.nih.gov/Structure/icn3d/full.html?from=blast&blast_rep_id=5XZC_B&query_id=1TUP_A&command=view+annotations;set+annotation+cdd;set+annotation+site;set+view+detailed+view;select+chain+5XZC_B;show+selection&log$=align&blast_rank=1&RID=EPUCYNVV014&buidx=0
@@ -24521,7 +24710,7 @@ class ChainalignParser {
24521
24710
  let pos1 = alignArray[0].indexOf('_');
24522
24711
  ic.mmdbid_t = alignArray[0].substr(0, pos1).toUpperCase();
24523
24712
  ic.chain_t = alignArray[0].substr(pos1+1);
24524
- let url_t = me.htmlCls.baseUrl + "mmdb/mmdb_strview.cgi?v=2&program=icn3d&b=1&s=1&ft=1&uid=" + ic.mmdbid_t;
24713
+ let url_t = me.htmlCls.baseUrl + "mmdb/mmdb_strview.cgi?v=2&program=icn3d&b=1&s=1&ft=1&buidx=" + me.cfg.buidx + "&uid=" + ic.mmdbid_t;
24525
24714
  if(me.cfg.inpara !== undefined) url_t += me.cfg.inpara;
24526
24715
 
24527
24716
  let ajaxArray = [];
@@ -24547,7 +24736,7 @@ class ChainalignParser {
24547
24736
  let chainalignFinal = ic.mmdbid_q + "_" + ic.chain_q + "," + ic.mmdbid_t + "_" + ic.chain_t;
24548
24737
 
24549
24738
  let urlalign = me.htmlCls.baseUrl + "vastdyn/vastdyn.cgi?chainpairs=" + chainalignFinal;
24550
- let url_q = me.htmlCls.baseUrl + "mmdb/mmdb_strview.cgi?v=2&program=icn3d&b=1&s=1&ft=1&uid=" + ic.mmdbid_q;
24739
+ let url_q = me.htmlCls.baseUrl + "mmdb/mmdb_strview.cgi?v=2&program=icn3d&b=1&s=1&ft=1&buidx=" + me.cfg.buidx + "&uid=" + ic.mmdbid_q;
24551
24740
 
24552
24741
  if(me.cfg.inpara !== undefined) url_q += me.cfg.inpara;
24553
24742
 
@@ -26616,18 +26805,30 @@ class LoadScript {
26616
26805
  me.cfg.mmcifid = id;
26617
26806
  ic.mmcifParserCls.downloadMmcif(id);
26618
26807
  }
26619
- else if(command.indexOf('load mmdb') !== -1) {
26808
+ else if(command.indexOf('load mmdb') !== -1 || command.indexOf('load mmdb1') !== -1) {
26620
26809
  me.cfg.mmdbid = id;
26810
+ me.cfg.buidx = 1;
26621
26811
 
26622
26812
  ic.mmdbParserCls.downloadMmdb(id);
26623
26813
  }
26814
+ else if(command.indexOf('load mmdb0') !== -1) {
26815
+ me.cfg.mmdbid = id;
26816
+ me.cfg.buidx = 0;
26817
+
26818
+ ic.mmdbParserCls.downloadMmdb(id);
26819
+ }
26624
26820
  else if(command.indexOf('load gi') !== -1) {
26625
26821
  me.cfg.gi = id;
26626
26822
  ic.mmdbParserCls.downloadGi(id);
26627
26823
  }
26628
- else if(command.indexOf('load seq_struct_ids') !== -1) {
26824
+ else if(command.indexOf('load seq_struct_ids ') !== -1) {
26825
+ ic.bSmithwm = false;
26629
26826
  ic.mmdbParserCls.downloadBlast_rep_id(id);
26630
26827
  }
26828
+ else if(command.indexOf('load seq_struct_ids_smithwm ') !== -1) {
26829
+ ic.bSmithwm = true;
26830
+ ic.mmdbParserCls.downloadBlast_rep_id(id);
26831
+ }
26631
26832
  else if(command.indexOf('load cid') !== -1) {
26632
26833
  me.cfg.cid = id;
26633
26834
  ic.sdfParserCls.downloadCid(id);
@@ -27249,7 +27450,9 @@ class ShowSeq {
27249
27450
  }
27250
27451
  }
27251
27452
  giSeq = giSeqTmp;
27252
- let divLength = me.htmlCls.RESIDUE_WIDTH * ic.giSeq[chnid].length + 200;
27453
+ //let divLength = me.htmlCls.RESIDUE_WIDTH * ic.giSeq[chnid].length + 200;
27454
+ let divLength = me.htmlCls.RESIDUE_WIDTH * (ic.giSeq[chnid].length + ic.nTotalGap) + 200;
27455
+
27253
27456
  let seqLength = ic.giSeq[chnid].length;
27254
27457
  if(seqLength > ic.maxAnnoLength) {
27255
27458
  ic.maxAnnoLength = seqLength;
@@ -27402,7 +27605,7 @@ class ShowSeq {
27402
27605
  html += '</div>'; // corresponds to above: html += '<div class="icn3d-dl_sequence">';
27403
27606
  html3 += '</div></div>';
27404
27607
  if(me.cfg.blast_rep_id === chnid) {
27405
- htmlTmp = '<div id="' + ic.pre + 'giseq_sequence" class="icn3d-dl_sequence" style="border: solid 1px #000;">';
27608
+ htmlTmp = '<div id="' + ic.pre + 'giseq_sequence" class="icn3d-dl_sequence" style="border: solid 1px #000">';
27406
27609
  }
27407
27610
  else {
27408
27611
  htmlTmp = '<div id="' + ic.pre + 'giseq_sequence" class="icn3d-dl_sequence">';
@@ -28876,7 +29079,7 @@ class Analysis {
28876
29079
  //Display chain name in the 3D structure display for the chains intersecting with the atoms in "atomHash".
28877
29080
  addChainLabels(atoms) {var ic = this.icn3d, me = ic.icn3dui;
28878
29081
  let size = 18;
28879
- let background = "#CCCCCC";
29082
+ let background = "#FFFFFF"; //"#CCCCCC";
28880
29083
  let atomsHash = me.hashUtilsCls.intHash(ic.hAtoms, atoms);
28881
29084
  if(ic.labels['chain'] === undefined) ic.labels['chain'] = [];
28882
29085
  let chainHash = ic.firstAtomObjCls.getChainsFromAtoms(atomsHash);
@@ -28889,8 +29092,8 @@ class Analysis {
28889
29092
  if(proteinName.length > 20) proteinName = proteinName.substr(0, 20) + '...';
28890
29093
  label.text = 'Chain ' + chainName + ': ' + proteinName;
28891
29094
  label.size = size;
28892
- let atomColorStr = ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.chains[chainid]).color.getHexString().toUpperCase();
28893
- label.color =(atomColorStr === "CCCCCC" || atomColorStr === "C8C8C8") ? "#888888" : "#" + atomColorStr;
29095
+ ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.chains[chainid]).color.getHexString().toUpperCase();
29096
+ label.color = (ic.opts.background != 'black') ? ic.colorWhitebkgd : ic.colorBlackbkgd; //(atomColorStr === "CCCCCC" || atomColorStr === "C8C8C8") ? "#888888" : "#" + atomColorStr;
28894
29097
  label.background = background;
28895
29098
  ic.labels['chain'].push(label);
28896
29099
  }
@@ -28900,7 +29103,7 @@ class Analysis {
28900
29103
  //as "N-" and "C-". The termini of nucleotides are labeled as "5'" and "3'".
28901
29104
  addTerminiLabels(atoms) {var ic = this.icn3d, me = ic.icn3dui;
28902
29105
  let size = 18;
28903
- let background = "#CCCCCC";
29106
+ let background = "#FFFFFF"; //"#CCCCCC";
28904
29107
  let protNucl;
28905
29108
  protNucl = me.hashUtilsCls.unionHash(protNucl, ic.proteins);
28906
29109
  protNucl = me.hashUtilsCls.unionHash(protNucl, ic.nucleotides);
@@ -28924,10 +29127,10 @@ class Analysis {
28924
29127
  }
28925
29128
  labelN.size = size;
28926
29129
  labelC.size = size;
28927
- let atomNColorStr = firstAtom.color.getHexString().toUpperCase();
28928
- let atomCColorStr = lastAtom.color.getHexString().toUpperCase();
28929
- labelN.color =(atomNColorStr === "CCCCCC" || atomNColorStr === "C8C8C8") ? "#888888" : "#" + atomNColorStr;
28930
- labelC.color =(atomCColorStr === "CCCCCC" || atomCColorStr === "C8C8C8") ? "#888888" : "#" + atomCColorStr;
29130
+ firstAtom.color.getHexString().toUpperCase();
29131
+ lastAtom.color.getHexString().toUpperCase();
29132
+ labelN.color = (ic.opts.background != 'black') ? ic.colorWhitebkgd : ic.colorBlackbkgd; //(atomNColorStr === "CCCCCC" || atomNColorStr === "C8C8C8") ? "#888888" : "#" + atomNColorStr;
29133
+ labelC.color = (ic.opts.background != 'black') ? ic.colorWhitebkgd : ic.colorBlackbkgd; //(atomCColorStr === "CCCCCC" || atomCColorStr === "C8C8C8") ? "#888888" : "#" + atomCColorStr;
28931
29134
  labelN.background = background;
28932
29135
  labelC.background = background;
28933
29136
  ic.labels['chain'].push(labelN);
@@ -28962,11 +29165,44 @@ class AnnoCddSite {
28962
29165
  // live search for AlphaFold structures
28963
29166
  //if(me.cfg.afid) {
28964
29167
 
28965
- if(!me.cfg.mmtfid && !me.cfg.pdbid && !me.cfg.opmid && !me.cfg.mmdbid && !me.cfg.gi && !me.cfg.uniprotid && !me.cfg.blast_rep_id && !me.cfg.cid && !me.cfg.mmcifid && !me.cfg.align && !me.cfg.chainalign) {
29168
+ // use precalculated CDD annotation if
29169
+ if( (Object.keys(ic.structures).length == 1 && (me.cfg.mmtfid || me.cfg.pdbid || me.cfg.opmid || me.cfg.mmdbid || me.cfg.gi || me.cfg.uniprotid || me.cfg.blast_rep_id || me.cfg.cid || me.cfg.mmcifid))
29170
+ || (Object.keys(ic.structures).length == 2 && me.cfg.align) ) {
29171
+ $.ajax({
29172
+ url: url,
29173
+ dataType: 'jsonp',
29174
+ cache: true,
29175
+ tryCount : 0,
29176
+ retryLimit : 1,
29177
+ success: function(data) {
29178
+ thisClass.parseCddData([data], chnidArray);
29179
+ if(ic.deferredAnnoCddSite !== undefined) ic.deferredAnnoCddSite.resolve();
29180
+ },
29181
+ error : function(xhr, textStatus, errorThrown ) {
29182
+ this.tryCount++;
29183
+ if(this.tryCount <= this.retryLimit) {
29184
+ //try again
29185
+ $.ajax(this);
29186
+ return;
29187
+ }
29188
+
29189
+ thisClass.getNoCdd(chnidBaseArray);
29190
+ if(ic.deferredAnnoCddSite !== undefined) ic.deferredAnnoCddSite.resolve();
29191
+
29192
+ return;
29193
+ }
29194
+ });
29195
+ }
29196
+ else {
28966
29197
  let ajaxArray = [];
28967
29198
 
28968
29199
  for(let i = 0, il = chnidArray.length; i < il; ++i) {
28969
- let seq = Array.isArray(ic.giSeq[chnidArray[i]]) ? ic.giSeq[chnidArray[i]].join('') : ic.giSeq[chnidArray[i]];
29200
+ //let seq = Array.isArray(ic.giSeq[chnidArray[i]]) ? ic.giSeq[chnidArray[i]].join('') : ic.giSeq[chnidArray[i]];
29201
+ let seq = Array.isArray(ic.giSeq[chnidArray[i]]) ? ic.giSeq[chnidArray[i]].join('').toUpperCase() : ic.giSeq[chnidArray[i]].toUpperCase();
29202
+
29203
+ // remove water molecules
29204
+ seq = seq.replace(/O/g, '');
29205
+
28970
29206
  //url = me.htmlCls.baseUrl + "cdannots/cdannots.fcgi?fmt&live=lcl&queries=" + ic.giSeq[chnidArray[0]].join('');
28971
29207
  url = me.htmlCls.baseUrl + "cdannots/cdannots.fcgi?fmt&live=lcl&queries=" + seq;
28972
29208
 
@@ -28993,32 +29229,6 @@ class AnnoCddSite {
28993
29229
  return;
28994
29230
  });
28995
29231
  }
28996
- else {
28997
- $.ajax({
28998
- url: url,
28999
- dataType: 'jsonp',
29000
- cache: true,
29001
- tryCount : 0,
29002
- retryLimit : 1,
29003
- success: function(data) {
29004
- thisClass.parseCddData([data], chnidArray);
29005
- if(ic.deferredAnnoCddSite !== undefined) ic.deferredAnnoCddSite.resolve();
29006
- },
29007
- error : function(xhr, textStatus, errorThrown ) {
29008
- this.tryCount++;
29009
- if(this.tryCount <= this.retryLimit) {
29010
- //try again
29011
- $.ajax(this);
29012
- return;
29013
- }
29014
-
29015
- thisClass.getNoCdd(chnidBaseArray);
29016
- if(ic.deferredAnnoCddSite !== undefined) ic.deferredAnnoCddSite.resolve();
29017
-
29018
- return;
29019
- }
29020
- });
29021
- }
29022
29232
  }
29023
29233
 
29024
29234
  parseCddData(dataArray, chnidArray, bSeq) { let ic = this.icn3d, me = ic.icn3dui;
@@ -29509,7 +29719,7 @@ class Picking {
29509
29719
  let text =(ic.pk == 1) ? atom.resn + atom.resi + '@' + atom.name : atom.resn + atom.resi;
29510
29720
  if(ic.structures !== undefined && Object.keys(ic.structures).length > 1) {
29511
29721
  text = atom.structure + '_' + atom.chain + ' ' + text;
29512
- $("#" + ic.pre + "popup").css("width", "140px");
29722
+ $("#" + ic.pre + "popup").css("width", "160px");
29513
29723
  }
29514
29724
  else {
29515
29725
  $("#" + ic.pre + "popup").css("width", "80px");
@@ -29737,8 +29947,9 @@ class ApplyCommand {
29737
29947
  ic.bAddCommands = false;
29738
29948
 
29739
29949
  let commandTransformation = commandStr.split('|||');
29950
+ let commandTransformation2 = commandTransformation[0].split('%7C%7C%7C'); // sometimes encoded transformation is also included
29740
29951
 
29741
- let commandOri = commandTransformation[0].replace(/\s+/g, ' ').trim();
29952
+ let commandOri = commandTransformation2[0].replace(/\s+/g, ' ').trim();
29742
29953
  let command = commandOri.toLowerCase();
29743
29954
 
29744
29955
  // exact match =============
@@ -30334,15 +30545,18 @@ class ApplyCommand {
30334
30545
  let value = command.substr(command.lastIndexOf(' ') + 1);
30335
30546
  ic.opts['background'] = value;
30336
30547
 
30337
- if(value == 'white' || value == 'grey') {
30338
- $("#" + ic.pre + "title").css("color", "black");
30339
- $("#" + ic.pre + "titlelink").css("color", "black");
30548
+ if(value == 'black') {
30549
+ $("#" + ic.pre + "title").css("color", me.htmlCls.GREYD);
30550
+ $("#" + ic.pre + "titlelink").css("color", me.htmlCls.GREYD);
30340
30551
  }
30341
30552
  else {
30342
- $("#" + ic.pre + "title").css("color", me.htmlCls.GREYD);
30343
- $("#" + ic.pre + "titlelink").css("color", me.htmlCls.GREYD);
30553
+ $("#" + ic.pre + "title").css("color", "black");
30554
+ $("#" + ic.pre + "titlelink").css("color", "black");
30344
30555
  }
30345
30556
  }
30557
+ else if(command.indexOf('set label color') == 0) {
30558
+ ic.labelcolor = command.substr(command.lastIndexOf(' ') + 1);
30559
+ }
30346
30560
  else if(commandOri.indexOf('set thickness') == 0) {
30347
30561
  let paraArray = command.split(' | ');
30348
30562
 
@@ -30397,6 +30611,13 @@ class ApplyCommand {
30397
30611
 
30398
30612
  ic.drawCls.draw();
30399
30613
  }
30614
+ else if(commandOri.indexOf('set membrane') == 0) {
30615
+ let pos = command.lastIndexOf(' ');
30616
+
30617
+ ic.bMembrane = parseInt(command.substr(pos + 1));
30618
+
30619
+ ic.drawCls.draw();
30620
+ }
30400
30621
  else if(command.indexOf('set highlight color') == 0) {
30401
30622
  let color = command.substr(20);
30402
30623
  if(color === 'yellow') {
@@ -32167,6 +32388,8 @@ class SetSeqAlign {
32167
32388
  ic.alnChainsAnTtl[chainid1][6].push("");
32168
32389
 
32169
32390
  let alignIndex = 1;
32391
+ if(!ic.chainsMapping[chainid1]) ic.chainsMapping[chainid1] = {};
32392
+ if(!ic.chainsMapping[chainid2]) ic.chainsMapping[chainid2] = {};
32170
32393
  //for(let j = 0, jl = alignData.sseq.length; j < jl; ++j) {
32171
32394
  for(let j = start; j <= end; ++j) {
32172
32395
  // 0: internal resi id, 1: pdb resi id, 2: resn, 3: aligned or not
@@ -32198,6 +32421,10 @@ class SetSeqAlign {
32198
32421
  ic.nconsHash2[chainid2 + '_' + resi] = 1;
32199
32422
  }
32200
32423
 
32424
+ // mapping, use the firstsequence as the reference structure
32425
+ ic.chainsMapping[chainid1][chainid1 + '_' + id2aligninfo[j].resi] = id2aligninfo[j].resn + id2aligninfo[j].resi;
32426
+ ic.chainsMapping[chainid2][chainid2 + '_' + resi] = id2aligninfo[j].resn + id2aligninfo[j].resi;
32427
+
32201
32428
  color2 = '#' + ic.showAnnoCls.getColorhexFromBlosum62(id2aligninfo[j].resn, resn);
32202
32429
 
32203
32430
  // expensive and thus remove
@@ -32382,6 +32609,8 @@ class SetSeqAlign {
32382
32609
  if(ic.qt_start_end[chainIndex] === undefined) return;
32383
32610
 
32384
32611
  let alignIndex = 1;
32612
+ if(!ic.chainsMapping[chainid1]) ic.chainsMapping[chainid1] = {};
32613
+ if(!ic.chainsMapping[chainid2]) ic.chainsMapping[chainid2] = {};
32385
32614
  for(let i = 0, il = ic.qt_start_end[chainIndex].length; i < il; ++i) {
32386
32615
  //var start1 = ic.qt_start_end[chainIndex][i].q_start - 1;
32387
32616
  //var start2 = ic.qt_start_end[chainIndex][i].t_start - 1;
@@ -32475,6 +32704,10 @@ class SetSeqAlign {
32475
32704
  ic.nconsHash2[chainid2 + '_' + resi2] = 1;
32476
32705
  }
32477
32706
 
32707
+ // mapping, use the firstsequence as the reference structure
32708
+ ic.chainsMapping[chainid1][chainid1 + '_' + resi1] = resn1 + resi1;
32709
+ ic.chainsMapping[chainid2][chainid2 + '_' + resi2] = resn1 + resi1;
32710
+
32478
32711
  color2 = '#' + ic.showAnnoCls.getColorhexFromBlosum62(resn1, resn2);
32479
32712
 
32480
32713
  let bFirstResi =(i === 0 && j === 0) ? true : false;
@@ -32524,6 +32757,8 @@ class SetSeqAlign {
32524
32757
  // let prevChainid1 = '', prevChainid2 = '', cnt1 = 0, cnt2 = 0;
32525
32758
 
32526
32759
  let residuesHash = {};
32760
+ if(!ic.chainsMapping[chainid_t]) ic.chainsMapping[chainid_t] = {};
32761
+ if(!ic.chainsMapping[chainid]) ic.chainsMapping[chainid] = {};
32527
32762
 
32528
32763
  for(let i = 0, il = ic.realignResid[structure1].length; i < il; ++i) {
32529
32764
  let resObject1 = ic.realignResid[structure1][i];
@@ -32550,6 +32785,11 @@ class SetSeqAlign {
32550
32785
  else {
32551
32786
  color = "#0000FF";
32552
32787
  }
32788
+
32789
+ // mapping, use the firstsequence as the reference structure
32790
+ ic.chainsMapping[chainid_t][chainid_t + '_' + resObject1.resi] = resObject1.resn + resObject1.resi;
32791
+ ic.chainsMapping[chainid][chainid + '_' + resObject2.resi] = resObject1.resn + resObject1.resi;
32792
+
32553
32793
  let color2 = '#' + ic.showAnnoCls.getColorhexFromBlosum62(resObject1.resn, resObject2.resn);
32554
32794
 
32555
32795
  resObject1.color = color;
@@ -33434,13 +33674,16 @@ class MmcifParser {
33434
33674
  let thisClass = this;
33435
33675
 
33436
33676
  let url, dataType;
33437
-
33677
+ /*
33438
33678
  if(me.utilsCls.isMac()) { // safari has a problem in getting data from https://files.rcsb.org/header/
33439
33679
  url = "https://files.rcsb.org/view/" + mmcifid + ".cif";
33440
33680
  }
33441
33681
  else {
33442
33682
  url = "https://files.rcsb.org/header/" + mmcifid + ".cif";
33443
33683
  }
33684
+ */
33685
+
33686
+ url = "https://files.rcsb.org/header/" + mmcifid + ".cif";
33444
33687
 
33445
33688
  dataType = "text";
33446
33689
 
@@ -33565,7 +33808,7 @@ class MmcifParser {
33565
33808
  if(type === 'mmtfid' && missingseq !== undefined) {
33566
33809
  // adjust missing residues
33567
33810
  let maxMissingResi = 0, prevMissingChain = '';
33568
- let chainMissingResidueArray = {};
33811
+ //let chainMissingResidueArray = {}
33569
33812
  for(let i = 0, il = missingseq.length; i < il; ++i) {
33570
33813
 
33571
33814
  let resn = missingseq[i].resn;
@@ -33574,7 +33817,7 @@ class MmcifParser {
33574
33817
 
33575
33818
  let chainNum = mmcifid + '_' + chain;
33576
33819
 
33577
- if(chainMissingResidueArray[chainNum] === undefined) chainMissingResidueArray[chainNum] = [];
33820
+ if(ic.chainMissingResidueArray[chainNum] === undefined) ic.chainMissingResidueArray[chainNum] = [];
33578
33821
  let resObject = {};
33579
33822
  resObject.resi = resi;
33580
33823
  resObject.name = me.utilsCls.residueName2Abbr(resn).toLowerCase();
@@ -33585,14 +33828,14 @@ class MmcifParser {
33585
33828
 
33586
33829
  // not all listed residues are considered missing, e.g., PDB ID 4OR2, only the firts four residues are considered missing
33587
33830
  if(!isNaN(resi) &&(prevMissingChain == '' ||(chain != prevMissingChain) ||(chain == prevMissingChain && resi > maxMissingResi)) ) {
33588
- chainMissingResidueArray[chainNum].push(resObject);
33831
+ ic.chainMissingResidueArray[chainNum].push(resObject);
33589
33832
 
33590
33833
  maxMissingResi = resi;
33591
33834
  prevMissingChain = chain;
33592
33835
  }
33593
33836
  }
33594
33837
 
33595
- ic.loadPDBCls.adjustSeq(chainMissingResidueArray);
33838
+ ic.loadPDBCls.adjustSeq(ic.chainMissingResidueArray);
33596
33839
  }
33597
33840
 
33598
33841
  if(ic.deferredSymmetry !== undefined) ic.deferredSymmetry.resolve();
@@ -33617,7 +33860,7 @@ class MmcifParser {
33617
33860
  if(type === 'mmtfid' && data.missingseq !== undefined) {
33618
33861
  // adjust missing residues
33619
33862
  let maxMissingResi = 0, prevMissingChain = '';
33620
- let chainMissingResidueArray = {};
33863
+ //let chainMissingResidueArray = {}
33621
33864
  for(let i = 0, il = data.missingseq.length; i < il; ++i) {
33622
33865
 
33623
33866
  let resn = data.missingseq[i].resn;
@@ -33626,7 +33869,7 @@ class MmcifParser {
33626
33869
 
33627
33870
  let chainNum = mmcifid + '_' + chain;
33628
33871
 
33629
- if(chainMissingResidueArray[chainNum] === undefined) chainMissingResidueArray[chainNum] = [];
33872
+ if(ic.chainMissingResidueArray[chainNum] === undefined) ic.chainMissingResidueArray[chainNum] = [];
33630
33873
  let resObject = {};
33631
33874
  resObject.resi = resi;
33632
33875
  resObject.name = me.utilsCls.residueName2Abbr(resn).toLowerCase();
@@ -33644,7 +33887,7 @@ class MmcifParser {
33644
33887
  }
33645
33888
  }
33646
33889
 
33647
- ic.loadPDBCls.adjustSeq(chainMissingResidueArray);
33890
+ ic.loadPDBCls.adjustSeq(ic.chainMissingResidueArray);
33648
33891
  }
33649
33892
 
33650
33893
  if(ic.deferredSymmetry !== undefined) ic.deferredSymmetry.resolve();
@@ -33840,8 +34083,16 @@ class HlSeq {
33840
34083
  .on('click', '.icn3d-seqTitle', function(e) { let ic = thisClass.icn3d;
33841
34084
  e.stopImmediatePropagation();
33842
34085
 
33843
- ic.bAlignSeq = false;
33844
- ic.bAnnotations = true;
34086
+ //if($(this).attr('id') === ic.pre + "dl_sequence2") {
34087
+ if($(this).parents('div').attr('id') === ic.pre + "dl_sequence2") {
34088
+ ic.bAlignSeq = true;
34089
+ ic.bAnnotations = false;
34090
+ }
34091
+ //else if($(this).attr('id') === ic.pre + "dl_annotations") {
34092
+ else {
34093
+ ic.bAlignSeq = false;
34094
+ ic.bAnnotations = true;
34095
+ }
33845
34096
 
33846
34097
  // select annotation title
33847
34098
  //$("div .ui-selected", this).each(function() {
@@ -33870,8 +34121,9 @@ class HlSeq {
33870
34121
 
33871
34122
  $("#" + ic.pre + "dl_sequence2").add("[id^=" + ic.pre + "giseq]").add("[id^=" + ic.pre + "custom]").add("[id^=" + ic.pre + "site]").add("[id^=" + ic.pre + "clinvar]").add("[id^=" + ic.pre + "snp]").add("[id^=" + ic.pre + "cdd]").add("[id^=" + ic.pre + "domain]").add("[id^=" + ic.pre + "interaction]").add("[id^=" + ic.pre + "ssbond]").add("[id^=" + ic.pre + "crosslink]").add("[id^=" + ic.pre + "transmem]").on('click', '.icn3d-residue', function(e) { let ic = thisClass.icn3d;
33872
34123
  e.stopImmediatePropagation();
33873
-
33874
- if($(this).attr('id') === ic.pre + "dl_sequence2") {
34124
+ /*
34125
+ //if($(this).attr('id') === ic.pre + "dl_sequence2") {
34126
+ if($(this).parents('span').parents('div').attr('id') === ic.pre + "dl_sequence2") {
33875
34127
  ic.bAlignSeq = true;
33876
34128
  ic.bAnnotations = false;
33877
34129
  }
@@ -33880,7 +34132,7 @@ class HlSeq {
33880
34132
  ic.bAlignSeq = false;
33881
34133
  ic.bAnnotations = true;
33882
34134
  }
33883
-
34135
+ */
33884
34136
  // select residues
33885
34137
  //$("span.ui-selected", this).each(function() {
33886
34138
  let id = $(this).attr('id');
@@ -33919,7 +34171,8 @@ class HlSeq {
33919
34171
  $("#" + ic.pre + "dl_sequence2").add("[id^=" + ic.pre + "giseq]").add("[id^=" + ic.pre + "custom]").add("[id^=" + ic.pre + "site]").add("[id^=" + ic.pre + "feat]").add("[id^=" + ic.pre + "clinvar]").add("[id^=" + ic.pre + "snp]").add("[id^=" + ic.pre + "cdd]").add("[id^=" + ic.pre + "domain]").add("[id^=" + ic.pre + "interaction]").add("[id^=" + ic.pre + "ssbond]").add("[id^=" + ic.pre + "crosslink]").add("[id^=" + ic.pre + "transmem]").on('click', '.icn3d-seqTitle', function(e) { let ic = thisClass.icn3d;
33920
34172
  e.stopImmediatePropagation();
33921
34173
 
33922
- if($(this).attr('id') === ic.pre + "dl_sequence2") {
34174
+ //if($(this).attr('id') === ic.pre + "dl_sequence2") {
34175
+ if($(this).parents('div').attr('id') === ic.pre + "dl_sequence2") {
33923
34176
  ic.bAlignSeq = true;
33924
34177
  ic.bAnnotations = false;
33925
34178
  }
@@ -34116,7 +34369,7 @@ class HlSeq {
34116
34369
 
34117
34370
  //var size = parseInt(ic.LABELSIZE * 10 / commandname.length);
34118
34371
  let size = ic.LABELSIZE;
34119
- let color = "FFFF00";
34372
+ let color = (ic.opts.background != 'black') ? ic.colorWhitebkgd : ic.colorBlackbkgd; //"FFFF00";
34120
34373
  if(position !== undefined) ic.analysisCls.addLabel(commanddescr, position.center.x, position.center.y, position.center.z, size, color, undefined, 'custom');
34121
34374
 
34122
34375
  ic.drawCls.draw();
@@ -34150,6 +34403,10 @@ class HlSeq {
34150
34403
  selectResidues(id, that) { let ic = this.icn3d, me = ic.icn3dui;
34151
34404
  if(me.bNode) return;
34152
34405
 
34406
+ if(ic.bSelectResidue === false && !ic.bShift && !ic.bCtrl) {
34407
+ ic.selectionCls.removeSelection();
34408
+ }
34409
+
34153
34410
  if(id !== undefined && id !== '') {
34154
34411
  // add "align_" in front of id so that full sequence and aligned sequence will not conflict
34155
34412
  //if(id.substr(0, 5) === 'align') id = id.substr(5);
@@ -34322,7 +34579,7 @@ class ShowAnno {
34322
34579
  }
34323
34580
  }
34324
34581
  }
34325
- else if(me.cfg.blast_rep_id !== undefined) { // align sequence to structure
34582
+ else if(me.cfg.blast_rep_id !== undefined && !ic.bSmithwm) { // align sequence to structure
34326
34583
  let url = me.htmlCls.baseUrl + 'pwaln/pwaln.fcgi?from=querytarget';
34327
34584
  let dataObj = {'targets': me.cfg.blast_rep_id, 'queries': me.cfg.query_id};
34328
34585
  if(me.cfg.query_from_to !== undefined ) {
@@ -34364,6 +34621,63 @@ class ShowAnno {
34364
34621
  }
34365
34622
  });
34366
34623
  } // align seq to structure
34624
+ else if(me.cfg.blast_rep_id !== undefined && ic.bSmithwm) { // align sequence to structure
34625
+ //{'targets': me.cfg.blast_rep_id, 'queries': me.cfg.query_id}
34626
+ let idArray = [me.cfg.blast_rep_id];
34627
+
34628
+ let target, query;
34629
+ if(me.cfg.query_id.indexOf('>') != -1) { //FASTA with header
34630
+ query = me.cfg.query_id.substr(me.cfg.query_id.indexOf('\n') + 1);
34631
+ }
34632
+ else if(!(/\d/.test(me.cfg.query_id)) || me.cfg.query_id.length > 50) { //FASTA
34633
+ query = me.cfg.query_id;
34634
+ }
34635
+ else { // accession
34636
+ idArray.push(me.cfg.query_id);
34637
+ }
34638
+
34639
+ // show the sequence and 3D structure
34640
+ //var url = "https://eme.utilsCls.ncbi.nlm.nih.gov/entrez/eUtilsCls/efetch.fcgi?db=protein&retmode=json&rettype=fasta&id=" + chnidBaseArray;
34641
+ let url = me.htmlCls.baseUrl + "/vastdyn/vastdyn.cgi?chainlist=" + idArray;
34642
+
34643
+ $.ajax({
34644
+ url: url,
34645
+ dataType: 'jsonp', //'text',
34646
+ cache: true,
34647
+ tryCount : 0,
34648
+ retryLimit : 1,
34649
+ success: function(chainid_seq) {
34650
+ let index = 0;
34651
+ for(let acc in chainid_seq) {
34652
+ if(index == 0) {
34653
+ target = chainid_seq[acc];
34654
+ }
34655
+ else if(!query) {
34656
+ query = chainid_seq[acc];
34657
+ }
34658
+
34659
+ ++index;
34660
+ }
34661
+
34662
+ let match_score = 1, mismatch = -1, gap = -1, extension = -1;
34663
+ ic.seqStructAlignDataSmithwm = ic.alignSWCls.alignSW(target, query, match_score, mismatch, gap, extension);
34664
+
34665
+ thisClass.showAnnoSeqData(nucleotide_chainid, chemical_chainid, chemical_set);
34666
+ },
34667
+ error : function(xhr, textStatus, errorThrown ) {
34668
+ this.tryCount++;
34669
+ if(this.tryCount <= this.retryLimit) {
34670
+ //try again
34671
+ $.ajax(this);
34672
+ return;
34673
+ }
34674
+
34675
+ var aaa = 1; //alert("Can not retrieve the sequence of the accession(s) " + idArray.join(", "));
34676
+
34677
+ return;
34678
+ }
34679
+ });
34680
+ } // align seq to structure
34367
34681
  }
34368
34682
  ic.bAnnoShown = true;
34369
34683
  }
@@ -34459,7 +34773,7 @@ class ShowAnno {
34459
34773
  $.ajax(this);
34460
34774
  return;
34461
34775
  }
34462
- this.enableHlSeq();
34776
+ thisClass.enableHlSeq();
34463
34777
  console.log( "No data were found for the protein " + chnidBaseArray + "..." );
34464
34778
  for(let chnid in ic.protein_chainid) {
34465
34779
  let chnidBase = ic.protein_chainid[chnid];
@@ -34591,7 +34905,7 @@ class ShowAnno {
34591
34905
  if(me.cfg.blast_rep_id != chnid) {
34592
34906
  ic.showSeqCls.showSeq(chnid, chnidBase);
34593
34907
  }
34594
- else if(me.cfg.blast_rep_id == chnid && ic.seqStructAlignData.data === undefined) {
34908
+ else if(me.cfg.blast_rep_id == chnid && ic.seqStructAlignData === undefined && ic.seqStructAlignDataSmithwm === undefined) {
34595
34909
  let title;
34596
34910
  if(me.cfg.query_id.length > 14) {
34597
34911
  title = 'Query: ' + me.cfg.query_id.substr(0, 6) + '...';
@@ -34607,7 +34921,7 @@ class ShowAnno {
34607
34921
  var aaa = 1; //alert('The sequence can NOT be aligned to the structure');
34608
34922
  ic.showSeqCls.showSeq(chnid, chnidBase, undefined, title, compTitle, text, compText);
34609
34923
  }
34610
- else if(me.cfg.blast_rep_id == chnid && ic.seqStructAlignData.data !== undefined) { // align sequence to structure
34924
+ else if(me.cfg.blast_rep_id == chnid && (ic.seqStructAlignData !== undefined || ic.seqStructAlignDataSmithwm !== undefined) ) { // align sequence to structure
34611
34925
  //var title = 'Query: ' + me.cfg.query_id.substr(0, 6);
34612
34926
  let title;
34613
34927
  if(me.cfg.query_id.length > 14) {
@@ -34616,27 +34930,72 @@ class ShowAnno {
34616
34930
  else {
34617
34931
  title =(isNaN(me.cfg.query_id)) ? 'Query: ' + me.cfg.query_id : 'Query: gi ' + me.cfg.query_id;
34618
34932
  }
34619
- let data = ic.seqStructAlignData;
34620
34933
 
34621
- let query, target;
34622
- if(data.data !== undefined) {
34623
- query = data.data[0].query;
34624
- //target = data.data[0].targets[chnid.replace(/_/g, '')];
34625
- target = data.data[0].targets[chnid];
34626
- target =(target !== undefined && target.hsps.length > 0) ? target.hsps[0] : undefined;
34934
+
34935
+ let evalue, targetSeq, querySeq, segArray;
34936
+
34937
+ if(ic.seqStructAlignData !== undefined) {
34938
+ let query, target;
34939
+ let data = ic.seqStructAlignData;
34940
+ if(data.data !== undefined) {
34941
+ query = data.data[0].query;
34942
+ //target = data.data[0].targets[chnid.replace(/_/g, '')];
34943
+ target = data.data[0].targets[chnid];
34944
+ target =(target !== undefined && target.hsps.length > 0) ? target.hsps[0] : undefined;
34945
+ }
34946
+
34947
+ if(query !== undefined && target !== undefined) {
34948
+ evalue = target.scores.e_value.toPrecision(2);
34949
+ if(evalue > 1e-200) evalue = parseFloat(evalue).toExponential();
34950
+ target.scores.bit_score;
34951
+ //var targetSeq = data.targets[chnid.replace(/_/g, '')].seqdata;
34952
+ targetSeq = data.targets[chnid].seqdata;
34953
+ querySeq = query.seqdata;
34954
+ segArray = target.segs;
34955
+ }
34956
+ }
34957
+ else { // mimic the output of the cgi pwaln.fcgi
34958
+ let data = ic.seqStructAlignDataSmithwm;
34959
+ evalue = data.score;
34960
+ targetSeq = data.target.replace(/-/g, '');
34961
+ querySeq = data.query.replace(/-/g, '');
34962
+ segArray = [];
34963
+ // target, 0-based: orifrom, orito
34964
+ // query, 0-based: from, to
34965
+
34966
+ let targetCnt = -1, queryCnt = -1;
34967
+ let bAlign = false, seg = {};
34968
+ for(let i = 0, il = data.target.length; i < il; ++i) {
34969
+ if(data.target[i] != '-') ++targetCnt;
34970
+ if(data.query[i] != '-') ++queryCnt;
34971
+ if(!bAlign && data.target[i] != '-' && data.query[i] != '-') {
34972
+ bAlign = true;
34973
+ seg.orifrom = targetCnt;
34974
+ seg.from = queryCnt;
34975
+ }
34976
+ else if(bAlign && (data.target[i] == '-' || data.query[i] == '-') ) {
34977
+ bAlign = false;
34978
+ seg.orito = (data.target[i] == '-') ? targetCnt : targetCnt - 1;
34979
+ seg.to = (data.query[i] == '-') ? queryCnt : queryCnt - 1;
34980
+ segArray.push(seg);
34981
+ seg = {};
34982
+ }
34983
+ }
34984
+
34985
+ // end condition
34986
+ if(data.target[data.target.length - 1] != '-' && data.query[data.target.length - 1] != '-') {
34987
+ seg.orito = targetCnt;
34988
+ seg.to = queryCnt;
34989
+
34990
+ segArray.push(seg);
34991
+ }
34627
34992
  }
34993
+
34628
34994
  let text = '', compText = '';
34629
34995
  ic.queryStart = '';
34630
34996
  ic.queryEnd = '';
34631
- let evalue;
34632
- if(query !== undefined && target !== undefined) {
34633
- evalue = target.scores.e_value.toPrecision(2);
34634
- if(evalue > 1e-200) evalue = parseFloat(evalue).toExponential();
34635
- target.scores.bit_score;
34636
- //var targetSeq = data.targets[chnid.replace(/_/g, '')].seqdata;
34637
- let targetSeq = data.targets[chnid].seqdata;
34638
- let querySeq = query.seqdata;
34639
- let segArray = target.segs;
34997
+
34998
+ if(segArray !== undefined) {
34640
34999
  let target2queryHash = {};
34641
35000
  if(ic.targetGapHash === undefined) ic.targetGapHash = {};
34642
35001
  ic.fullpos2ConsTargetpos = {};
@@ -34664,6 +35023,7 @@ class ShowAnno {
34664
35023
  prevTargetTo = seg.orito;
34665
35024
  prevQueryTo = seg.to;
34666
35025
  }
35026
+
34667
35027
  // the missing residues at the end of the seq will be filled up in the API showNewTrack()
34668
35028
  let nGap = 0;
34669
35029
  ic.alnChainsSeq[chnid] = [];
@@ -34704,13 +35064,14 @@ class ShowAnno {
34704
35064
  compText += ' ';
34705
35065
  }
34706
35066
  }
35067
+
34707
35068
  //title += ', E: ' + evalue;
34708
35069
  }
34709
35070
  else {
34710
35071
  text += "cannot be aligned";
34711
35072
  var aaa = 1; //alert('The sequence can NOT be aligned to the structure');
34712
35073
  }
34713
- let compTitle = 'BLAST, E: ' + evalue;
35074
+ let compTitle = (ic.seqStructAlignData !== undefined) ? 'BLAST, E: ' + evalue : 'Score: ' + evalue;
34714
35075
  ic.showSeqCls.showSeq(chnid, chnidBase, undefined, title, compTitle, text, compText);
34715
35076
  let residueidHash = {};
34716
35077
  let residueid;
@@ -35102,7 +35463,7 @@ class AnnoDomain {
35102
35463
  }
35103
35464
  ic.showAnnoCls.enableHlSeq();
35104
35465
  ic.bAjax3ddomain = true;
35105
- bAjaxDone1 = true;
35466
+ //bAjaxDone1 = true;
35106
35467
  if(ic.deferred3ddomain !== undefined) {
35107
35468
  if(me.cfg.align === undefined || me.cfg.chainalign === undefined) {
35108
35469
  ic.deferred3ddomain.resolve();
@@ -35315,7 +35676,7 @@ class AnnoSnpClinVar {
35315
35676
  ic.labels['clinvar'] = [];
35316
35677
  //var size = Math.round(ic.LABELSIZE * 10 / label.length);
35317
35678
  let size = ic.LABELSIZE;
35318
- let color = "#FFFF00";
35679
+ let color = (ic.opts.background != 'black') ? ic.colorWhitebkgd : ic.colorBlackbkgd; //"#FFFF00";
35319
35680
  ic.analysisCls.addLabel(label, position.center.x + 1, position.center.y + 1, position.center.z + 1, size, color, undefined, 'clinvar');
35320
35681
  ic.hAtoms = {};
35321
35682
  for(let j in ic.residues[residueid]) {
@@ -37596,23 +37957,25 @@ class HlUpdate {
37596
37957
  $("#" + ic.pre + "atomsCustom")[0].blur();
37597
37958
  }
37598
37959
 
37960
+ //Update the highlight of 3D structure, 2D interaction, sequences, and the menu of defined sets
37961
+ //according to the current highlighted atoms.
37599
37962
  updateHlAll(commandnameArray, bSetMenu, bUnion, bForceHighlight) { let ic = this.icn3d, me = ic.icn3dui;
37600
- // update the previously highlisghted atoms for switching between all and selection
37601
- ic.prevHighlightAtoms = me.hashUtilsCls.cloneHash(ic.hAtoms);
37963
+ // update the previously highlisghted atoms for switching between all and selection
37964
+ ic.prevHighlightAtoms = me.hashUtilsCls.cloneHash(ic.hAtoms);
37602
37965
 
37603
- this.updateHlObjects(bForceHighlight);
37966
+ this.updateHlObjects(bForceHighlight);
37604
37967
 
37605
- if(commandnameArray !== undefined) {
37606
- this.updateHlSeqInChain(commandnameArray, bUnion);
37607
- }
37608
- else {
37609
- this.updateHlSeq(undefined, undefined, bUnion);
37610
- }
37968
+ if(commandnameArray !== undefined) {
37969
+ this.updateHlSeqInChain(commandnameArray, bUnion);
37970
+ }
37971
+ else {
37972
+ this.updateHlSeq(undefined, undefined, bUnion);
37973
+ }
37611
37974
 
37612
- this.updateHl2D();
37613
- if(bSetMenu === undefined || bSetMenu) this.updateHlMenus(commandnameArray);
37975
+ this.updateHl2D();
37976
+ if(bSetMenu === undefined || bSetMenu) this.updateHlMenus(commandnameArray);
37614
37977
 
37615
- //ic.annotationCls.showAnnoSelectedChains();
37978
+ //ic.annotationCls.showAnnoSelectedChains();
37616
37979
  }
37617
37980
 
37618
37981
  //Update the highlight of 3D structure display according to the current highlighted atoms.
@@ -37916,27 +38279,6 @@ class HlUpdate {
37916
38279
  $( this ).removeClass('icn3d-highlightSeq');
37917
38280
  });
37918
38281
  }
37919
-
37920
- //Update the highlight of 3D structure, 2D interaction, sequences, and the menu of defined sets
37921
- //according to the current highlighted atoms.
37922
- updateHlAll(commandnameArray, bSetMenu, bUnion, bForceHighlight) { let ic = this.icn3d, me = ic.icn3dui;
37923
- // update the previously highlisghted atoms for switching between all and selection
37924
- ic.prevHighlightAtoms = me.hashUtilsCls.cloneHash(ic.hAtoms);
37925
-
37926
- this.updateHlObjects(bForceHighlight);
37927
-
37928
- if(commandnameArray !== undefined) {
37929
- this.updateHlSeqInChain(commandnameArray, bUnion);
37930
- }
37931
- else {
37932
- this.updateHlSeq(undefined, undefined, bUnion);
37933
- }
37934
-
37935
- this.updateHl2D();
37936
- if(bSetMenu === undefined || bSetMenu) this.updateHlMenus(commandnameArray);
37937
-
37938
- //ic.annotationCls.showAnnoSelectedChains();
37939
- }
37940
38282
  }
37941
38283
 
37942
38284
  /**
@@ -38236,9 +38578,12 @@ class Selection {
38236
38578
  ic.graphStr = this.getGraphDataForDisplayed();
38237
38579
  }
38238
38580
 
38581
+ // don not redraw graphs after the selection changes
38582
+ /*
38239
38583
  if(ic.bGraph) ic.drawGraphCls.drawGraph(ic.graphStr, ic.pre + 'dl_graph');
38240
38584
  if(ic.bLinegraph) ic.lineGraphCls.drawLineGraph(ic.graphStr);
38241
38585
  if(ic.bScatterplot) ic.lineGraphCls.drawLineGraph(ic.graphStr, true);
38586
+ */
38242
38587
  }
38243
38588
 
38244
38589
  hideSelection() { let ic = this.icn3d, me = ic.icn3dui;
@@ -38319,6 +38664,9 @@ class Selection {
38319
38664
 
38320
38665
  ic.loadScriptCls.renderFinalStep(1);
38321
38666
  ic.definedSetsCls.setMode('all');
38667
+
38668
+ ic.selectionCls.selectAll();
38669
+
38322
38670
  me.htmlCls.clickMenuCls.setLogCmd("reset", true);
38323
38671
 
38324
38672
  ic.hlUpdateCls.removeSeqChainBkgd();
@@ -38442,7 +38790,7 @@ class Selection {
38442
38790
  ic.drawCls.draw();
38443
38791
  }
38444
38792
 
38445
- toggleMembrane() {var ic = this.icn3d, me = ic.icn3dui;
38793
+ toggleMembrane(bShowMembrane) {var ic = this.icn3d, me = ic.icn3dui;
38446
38794
  let structureArray = Object.keys(ic.structures);
38447
38795
 
38448
38796
  for(let i = 0, il = structureArray.length; i < il; ++i) {
@@ -38457,6 +38805,7 @@ class Selection {
38457
38805
  ic.dAtoms = me.hashUtilsCls.unionHash(ic.dAtoms, atomsHash);
38458
38806
  oriStyle = 'nothing';
38459
38807
  }
38808
+
38460
38809
  for(let j in atomsHash) {
38461
38810
  let atom = ic.atoms[j];
38462
38811
  if(oriStyle !== 'nothing') {
@@ -38465,10 +38814,14 @@ class Selection {
38465
38814
  else {
38466
38815
  atom.style = 'stick';
38467
38816
  }
38817
+
38818
+ if(bShowMembrane !== undefined) {
38819
+ atom.style = (bShowMembrane) ? 'stick' : 'nothing';
38820
+ }
38468
38821
  }
38469
38822
  }
38470
38823
 
38471
- ic.drawCls.draw();
38824
+ if(bShowMembrane === undefined) ic.drawCls.draw();
38472
38825
  }
38473
38826
 
38474
38827
  adjustMembrane(extra_mem_z, intra_mem_z) {var ic = this.icn3d; ic.icn3dui;
@@ -38759,7 +39112,8 @@ class SetStyle {
38759
39112
  setBackground(color) {var ic = this.icn3d, me = ic.icn3dui;
38760
39113
  ic.setOptionCls.setOption('background', color);
38761
39114
  me.htmlCls.clickMenuCls.setLogCmd('set background ' + color, true);
38762
- let titleColor =(color == 'black' || color == 'transparent') ? me.htmlCls.GREYD : 'black';
39115
+ //let titleColor =(color == 'black' || color == 'transparent') ? me.htmlCls.GREYD : 'black';
39116
+ let titleColor = (color == 'black') ? me.htmlCls.GREYD : 'black';
38763
39117
  $("#" + ic.pre + "title").css("color", titleColor);
38764
39118
  $("#" + ic.pre + "titlelink").css("color", titleColor);
38765
39119
  }
@@ -39282,10 +39636,11 @@ class TextSprite {
39282
39636
 
39283
39637
  let a = parameters.hasOwnProperty("alpha") ? parameters["alpha"] : 1.0;
39284
39638
 
39285
- let bBkgd = true;
39639
+ let bBkgd = false; //true;
39286
39640
  let bSchematic = false;
39287
39641
  if(parameters.hasOwnProperty("bSchematic") && parameters["bSchematic"]) {
39288
39642
  bSchematic = true;
39643
+ bBkgd = true;
39289
39644
 
39290
39645
  fontsize = 40;
39291
39646
  }
@@ -39305,9 +39660,13 @@ class TextSprite {
39305
39660
  }
39306
39661
 
39307
39662
  let textAlpha = 1.0;
39308
-
39309
- let textColor = parameters.hasOwnProperty("textColor") && parameters["textColor"] !== undefined ? me.utilsCls.hexToRgb(parameters["textColor"], textAlpha) : { r:255, g:255, b:0, a:1.0 };
39310
- if(!textColor) textColor = { r:255, g:255, b:0, a:1.0 };
39663
+ // default yellow
39664
+ //let textColor = parameters.hasOwnProperty("textColor") && parameters["textColor"] !== undefined ? me.utilsCls.hexToRgb(parameters["textColor"], textAlpha) : { r:255, g:255, b:0, a:1.0 };
39665
+ // default black or white
39666
+ let defaultColor = (ic.opts.background != 'black') ? { r:0, g:0, b:0, a:1.0 } : { r:255, g:255, b:0, a:1.0 };
39667
+ let textColor = parameters.hasOwnProperty("textColor") && parameters["textColor"] !== undefined ? me.utilsCls.hexToRgb(parameters["textColor"], textAlpha)
39668
+ : defaultColor;
39669
+ if(!textColor) textColor = defaultColor;
39311
39670
 
39312
39671
  let canvas = document.createElement('canvas');
39313
39672
 
@@ -39444,6 +39803,7 @@ class Label {
39444
39803
 
39445
39804
  for(let name in labels) {
39446
39805
  let labelArray = (labels[name] !== undefined) ? labels[name] : [];
39806
+ let defaultColor = (ic.opts.background != 'black') ? ic.colorWhitebkgd : ic.colorBlackbkgd;
39447
39807
 
39448
39808
  for (let i = 0, il = labelArray.length; i < il; ++i) {
39449
39809
  let label = labelArray[i];
@@ -39454,7 +39814,9 @@ class Label {
39454
39814
  if(label.background == 0) label.background = undefined;
39455
39815
 
39456
39816
  let labelsize = (label.size !== undefined) ? label.size : ic.LABELSIZE;
39457
- let labelcolor = (label.color !== undefined) ? label.color : '#ffff00';
39817
+ let labelcolor = (label.color !== undefined) ? label.color : defaultColor;
39818
+ if(ic.labelcolor) labelcolor = ic.labelcolor;
39819
+
39458
39820
  let labelbackground = (label.background !== undefined) ? label.background : '#cccccc';
39459
39821
  let labelalpha = (label.alpha !== undefined) ? label.alpha : 1.0;
39460
39822
 
@@ -39480,7 +39842,8 @@ class Label {
39480
39842
  }
39481
39843
  }
39482
39844
 
39483
- bb.position.set(label.position.x, label.position.y, label.position.z);
39845
+ let labelOffset = (name == 'schematic' || name == 'residue') ? 0 : ic.coilWidth; // 0.3
39846
+ bb.position.set(label.position.x + labelOffset, label.position.y + labelOffset, label.position.z + labelOffset);
39484
39847
  ic.mdl.add(bb);
39485
39848
  // do not add labels to objects for pk
39486
39849
  }
@@ -39655,49 +40018,68 @@ class ApplyDisplay {
39655
40018
  atomsObj = {};
39656
40019
  } // end if(bHighlight === 1)
39657
40020
 
39658
- ic.setStyleCls.setStyle2Atoms(atoms);
40021
+ if(ic.bInitial) {
40022
+ if(me.htmlCls.setHtmlCls.getCookie('membrane') != '') {
40023
+ let bMembrane = parseInt(me.htmlCls.setHtmlCls.getCookie('membrane'));
39659
40024
 
39660
- //ic.bAllAtoms = (Object.keys(atoms).length === Object.keys(ic.atoms).length);
39661
- ic.bAllAtoms = false;
39662
- if(atoms && atoms !== undefined ) {
39663
- ic.bAllAtoms = (Object.keys(atoms).length === Object.keys(ic.atoms).length);
40025
+ if(ic.bMembrane != bMembrane) {
40026
+ me.htmlCls.clickMenuCls.setLogCmd('set membrane ' + bMembrane, true);
40027
+ }
40028
+
40029
+ ic.bMembrane = (!isNaN(bMembrane)) ? parseInt(bMembrane) : 0;
40030
+ }
40031
+
40032
+ // show membrane
40033
+ if(ic.bMembrane) {
40034
+ ic.selectionCls.toggleMembrane(true);
40035
+ }
40036
+ else {
40037
+ ic.selectionCls.toggleMembrane(false);
40038
+ }
39664
40039
  }
39665
40040
 
40041
+ ic.setStyleCls.setStyle2Atoms(atoms);
40042
+
40043
+ //ic.bAllAtoms = false;
40044
+ //if(atoms && atoms !== undefined ) {
40045
+ // ic.bAllAtoms = (Object.keys(atoms).length === Object.keys(ic.atoms).length);
40046
+ //}
40047
+
39666
40048
  let chemicalSchematicRadius = ic.cylinderRadius * 0.5;
39667
40049
 
39668
40050
  // remove schematic labels
39669
40051
  //if(ic.labels !== undefined) ic.labels['schematic'] = undefined;
39670
40052
  if(ic.labels !== undefined) delete ic.labels['schematic'];
39671
-
39672
- let bOnlySideChains = false;
39673
-
40053
+ /*
39674
40054
  if(bHighlight) {
39675
- let residueHashCalpha = ic.firstAtomObjCls.getResiduesFromCalphaAtoms(ic.hAtoms);
40055
+ //let residueHashCalpha = ic.firstAtomObjCls.getResiduesFromCalphaAtoms(ic.hAtoms);
39676
40056
 
39677
40057
  let proteinAtoms = me.hashUtilsCls.intHash(ic.hAtoms, ic.proteins);
40058
+
39678
40059
  let residueHash = ic.firstAtomObjCls.getResiduesFromAtoms(proteinAtoms);
40060
+ let residueHashCalpha = ic.firstAtomObjCls.getResiduesFromCalphaAtoms(proteinAtoms);
39679
40061
 
39680
- if(Object.keys(residueHash) > Object.keys(residueHashCalpha)) { // some residues have only side chains
40062
+ if(Object.keys(residueHash).length > Object.keys(residueHashCalpha).length) { // some residues have only side chains
39681
40063
  bOnlySideChains = true;
39682
40064
  }
39683
40065
  }
39684
-
40066
+ */
39685
40067
  for(let style in ic.style2atoms) {
39686
40068
  // 14 styles: ribbon, strand, cylinder and plate, nucleotide cartoon, o3 trace, schematic, c alpha trace, b factor tube, lines, stick, ball and stick, sphere, dot, nothing
39687
40069
  let atomHash = ic.style2atoms[style];
39688
40070
  //var bPhosphorusOnly = me.utilsCls.isCalphaPhosOnly(me.hashUtilsCls.hash2Atoms(atomHash), "O3'", "O3*") || me.utilsCls.isCalphaPhosOnly(me.hashUtilsCls.hash2Atoms(atomHash), "P");
39689
40071
  let bPhosphorusOnly = me.utilsCls.isCalphaPhosOnly(me.hashUtilsCls.hash2Atoms(atomHash, ic.atoms));
39690
40072
 
39691
- //if(style === 'ribbon') {
39692
- if(style === 'ribbon' && (!bHighlight || (bHighlight && !bOnlySideChains))) {
40073
+ if(style === 'ribbon') {
40074
+ //if(style === 'ribbon' && (!bHighlight || (bHighlight && !bOnlySideChains))) {
39693
40075
  ic.strandCls.createStrand(me.hashUtilsCls.hash2Atoms(atomHash, ic.atoms), 2, undefined, true, undefined, undefined, false, ic.ribbonthickness, bHighlight);
39694
40076
  }
39695
- //else if(style === 'strand') {
39696
- else if(style === 'strand' && (!bHighlight || (bHighlight && !bOnlySideChains))) {
40077
+ else if(style === 'strand') {
40078
+ //else if(style === 'strand' && (!bHighlight || (bHighlight && !bOnlySideChains))) {
39697
40079
  ic.strandCls.createStrand(me.hashUtilsCls.hash2Atoms(atomHash, ic.atoms), null, null, null, null, null, false, undefined, bHighlight);
39698
40080
  }
39699
- //else if(style === 'cylinder and plate') {
39700
- else if(style === 'cylinder and plate' && (!bHighlight || (bHighlight && !bOnlySideChains))) {
40081
+ else if(style === 'cylinder and plate') {
40082
+ //else if(style === 'cylinder and plate' && (!bHighlight || (bHighlight && !bOnlySideChains))) {
39701
40083
  ic.cylinderCls.createCylinderHelix(me.hashUtilsCls.hash2Atoms(atomHash, ic.atoms), ic.cylinderHelixRadius, bHighlight);
39702
40084
  }
39703
40085
  else if(style === 'nucleotide cartoon') {
@@ -39788,11 +40170,30 @@ class ApplyDisplay {
39788
40170
  if(ic.labels !== undefined && Object.keys(ic.labels).length > 0) {
39789
40171
  ic.labelCls.hideLabels();
39790
40172
 
40173
+ // change label color
40174
+ for(let labeltype in ic.labels) {
40175
+ if(labeltype != 'schematic') this.changeLabelColor(ic.labels[labeltype]);
40176
+ }
40177
+
39791
40178
  // labels
39792
40179
  ic.labelCls.createLabelRepresentation(ic.labels);
39793
40180
  }
39794
40181
  }
39795
40182
 
40183
+ changeLabelColor(labelArray) { let ic = this.icn3d; ic.icn3dui;
40184
+ if(labelArray) {
40185
+ for(let i = 0, il = labelArray.length; i < il; ++i) {
40186
+ let label = labelArray[i];
40187
+ if((ic.opts.background != 'black') && label.color == ic.colorBlackbkgd) {
40188
+ label.color = ic.colorWhitebkgd;
40189
+ }
40190
+ else if((ic.opts.background == 'black') && label.color == ic.colorWhitebkgd) {
40191
+ label.color = ic.colorBlackbkgd;
40192
+ }
40193
+ }
40194
+ }
40195
+ }
40196
+
39796
40197
  selectMainChainSubset(atoms) { let ic = this.icn3d; ic.icn3dui;
39797
40198
  let nuclMainArray = ["C1'", "C1*", "C2'", "C2*", "C3'", "C3*", "C4'", "C4*", "C5'", "C5*", "O3'", "O3*", "O4'", "O4*", "O5'", "O5*", "P", "OP1", "O1P", "OP2", "O2P"];
39798
40199
 
@@ -40260,14 +40661,16 @@ class ApplyOther {
40260
40661
  }
40261
40662
  }
40262
40663
 
40263
- if(me.htmlCls.setHtmlCls.getCookie('glycan') != '') {
40264
- let bGlycansCartoon = parseInt(me.htmlCls.setHtmlCls.getCookie('glycan'));
40664
+ if(ic.bInitial) {
40665
+ if(me.htmlCls.setHtmlCls.getCookie('glycan') != '') {
40666
+ let bGlycansCartoon = parseInt(me.htmlCls.setHtmlCls.getCookie('glycan'));
40265
40667
 
40266
- if(ic.bGlycansCartoon != bGlycansCartoon) {
40267
- me.htmlCls.clickMenuCls.setLogCmd('set glycan ' + bGlycansCartoon, true);
40268
- }
40668
+ if(ic.bGlycansCartoon != bGlycansCartoon) {
40669
+ me.htmlCls.clickMenuCls.setLogCmd('set glycan ' + bGlycansCartoon, true);
40670
+ }
40269
40671
 
40270
- ic.bGlycansCartoon = bGlycansCartoon;
40672
+ ic.bGlycansCartoon = bGlycansCartoon;
40673
+ }
40271
40674
  }
40272
40675
 
40273
40676
  // add cartoon for glycans
@@ -41498,7 +41901,6 @@ class Instancing {
41498
41901
  let mdlImpostorTmp = new THREE.Object3D();
41499
41902
  let mdl_ghostTmp = new THREE.Object3D();
41500
41903
 
41501
- console.log("no instancing, Object.keys(ic.structures).length: " + Object.keys(ic.structures).length);
41502
41904
  // for (let i = 0; i < ic.biomtMatrices.length; i++) { // skip itself
41503
41905
  for (let i = 0; i < ic.biomtMatrices.length && Object.keys(ic.structures).length == 1; i++) { // skip itself
41504
41906
  let mat = ic.biomtMatrices[i];
@@ -41896,7 +42298,6 @@ console.log("no instancing, Object.keys(ic.structures).length: " + Object.keys(i
41896
42298
  let identity = new THREE.Matrix4();
41897
42299
  identity.identity();
41898
42300
 
41899
- console.log("instancing, Object.keys(ic.structures).length: " + Object.keys(ic.structures).length);
41900
42301
  for (let i = 0; i < ic.biomtMatrices.length && Object.keys(ic.structures).length == 1; i++) { // skip itself
41901
42302
  let mat = ic.biomtMatrices[i];
41902
42303
  if (mat === undefined) continue;
@@ -42056,7 +42457,9 @@ class Draw {
42056
42457
  // ic.renderer.gammaOutput = true
42057
42458
 
42058
42459
  ic.renderer.setPixelRatio( window.devicePixelRatio ); // r71
42059
- if(ic.scene) ic.renderer.render(ic.scene, cam);
42460
+ if(ic.scene) {
42461
+ ic.renderer.render(ic.scene, cam);
42462
+ }
42060
42463
  }
42061
42464
 
42062
42465
  }
@@ -42271,10 +42674,10 @@ class Transform {
42271
42674
 
42272
42675
  if(ic.bRender) ic.drawCls.render();
42273
42676
  }
42274
-
42677
+ /*
42275
42678
  //Zoom in the structure at certain ratio, e.g., 0.1 is a reasonable value.
42276
42679
  zoomIn(normalizedFactor) { let ic = this.icn3d, me = ic.icn3dui;
42277
- let para = {};
42680
+ let para = {}
42278
42681
  para._zoomFactor = 1 - normalizedFactor;
42279
42682
  para.update = true;
42280
42683
  if(ic.bControlGl && !me.bNode) {
@@ -42284,12 +42687,14 @@ class Transform {
42284
42687
  ic.controls.update(para);
42285
42688
  }
42286
42689
 
42287
- if(ic.bRender) ic.drawCls.render();
42690
+ if(ic.bRender) {
42691
+ ic.drawCls.render();
42692
+ }
42288
42693
  }
42289
42694
 
42290
42695
  //Zoom out the structure at certain ratio, e.g., 0.1 is a reasonable value.
42291
42696
  zoomOut(normalizedFactor) { let ic = this.icn3d, me = ic.icn3dui;
42292
- let para = {};
42697
+ let para = {}
42293
42698
  para._zoomFactor = 1 + normalizedFactor;
42294
42699
  para.update = true;
42295
42700
 
@@ -42299,8 +42704,11 @@ class Transform {
42299
42704
  else {
42300
42705
  ic.controls.update(para);
42301
42706
  }
42302
- if(ic.bRender) ic.drawCls.render();
42707
+ if(ic.bRender) {
42708
+ ic.drawCls.render();
42709
+ }
42303
42710
  }
42711
+ */
42304
42712
 
42305
42713
  //Center on the selected atoms and zoom in.
42306
42714
  zoominSelection(atoms) { let ic = this.icn3d, me = ic.icn3dui;
@@ -42580,7 +42988,7 @@ class SaveFile {
42580
42988
  };
42581
42989
  }
42582
42990
 
42583
- exportCustomAtoms() {var ic = this.icn3d; ic.icn3dui;
42991
+ exportCustomAtoms(bDetails) {var ic = this.icn3d; ic.icn3dui;
42584
42992
  let html = "";
42585
42993
  let nameArray =(ic.defNames2Residues !== undefined) ? Object.keys(ic.defNames2Residues).sort() : [];
42586
42994
  for(let i = 0, il = nameArray.length; i < il; ++i) {
@@ -42589,9 +42997,8 @@ class SaveFile {
42589
42997
  ic.defNames2Descr[name];
42590
42998
  let command = ic.defNames2Command[name];
42591
42999
  command = command.replace(/,/g, ', ');
42592
- html += name + "\tselect ";
42593
- html += ic.resid2specCls.residueids2spec(residueArray);
42594
- html += "\n";
43000
+
43001
+ html += this.exportResidues(name, residueArray, bDetails);
42595
43002
  } // outer for
42596
43003
  nameArray =(ic.defNames2Atoms !== undefined) ? Object.keys(ic.defNames2Atoms).sort() : [];
42597
43004
  for(let i = 0, il = nameArray.length; i < il; ++i) {
@@ -42601,15 +43008,51 @@ class SaveFile {
42601
43008
  let command = ic.defNames2Command[name];
42602
43009
  command = command.replace(/,/g, ', ');
42603
43010
  let residueArray = ic.resid2specCls.atoms2residues(atomArray);
42604
- if(residueArray.length > 0) {
42605
- html += name + "\tselect ";
42606
- html += ic.resid2specCls.residueids2spec(residueArray);
42607
- html += "\n";
42608
- }
43011
+
43012
+ html += this.exportResidues(name, residueArray, bDetails);
42609
43013
  } // outer for
42610
43014
  return html;
42611
43015
  }
42612
43016
 
43017
+ exportResidues(name, residueArray, bDetails) {var ic = this.icn3d, me = ic.icn3dui;
43018
+ let html = '';
43019
+
43020
+ if(residueArray.length > 0) {
43021
+ if(bDetails) {
43022
+ let chainidHash = {};
43023
+ for(let i = 0, il = residueArray.length; i < il; ++i) {
43024
+ let resid = residueArray[i];
43025
+ let atom = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[resid]);
43026
+ let chainid = atom.structure + '_' + atom.chain;
43027
+ let resnAbbr = me.utilsCls.residueName2Abbr(atom.resn);
43028
+ let resName = resnAbbr + atom.resi;
43029
+
43030
+ if(!chainidHash.hasOwnProperty(chainid)) {
43031
+ chainidHash[chainid] = [];
43032
+ }
43033
+
43034
+ chainidHash[chainid].push(resName);
43035
+ }
43036
+
43037
+ html += name + ":\n";
43038
+ for(let chainid in chainidHash) {
43039
+ let resStr = (chainidHash[chainid].length == 1) ? "residue" : "residues";
43040
+ html += chainid + " (" + chainidHash[chainid].length + " " + resStr + "): ";
43041
+ html += chainidHash[chainid].join(", ");
43042
+ html += "\n";
43043
+ }
43044
+ html += "\n";
43045
+ }
43046
+ else {
43047
+ html += name + "\tselect ";
43048
+ html += ic.resid2specCls.residueids2spec(residueArray);
43049
+ html += "\n";
43050
+ }
43051
+ }
43052
+
43053
+ return html;
43054
+ }
43055
+
42613
43056
  //getAtomPDB: function(atomHash, bPqr, bPdb, bNoChem) { let ic = this.icn3d, me = ic.icn3dui;
42614
43057
  getAtomPDB(atomHash, bPqr, bNoChem, bNoHeader) { let ic = this.icn3d, me = ic.icn3dui;
42615
43058
  let pdbStr = '';
@@ -42701,37 +43144,53 @@ class SaveFile {
42701
43144
  }
42702
43145
  }
42703
43146
 
43147
+ /*
42704
43148
  // get missing residues
42705
- let chainid2missingResi = {};
43149
+ let ic.chainMissingResidueArray = {};
42706
43150
  for(let chainid in ic.chainsSeq) {
42707
43151
  let pos = chainid.indexOf('_');
42708
- chainid.substr(0, pos);
43152
+ let chain = chainid.substr(0, pos);
42709
43153
 
42710
43154
  for(let i = 0, il = ic.chainsSeq[chainid].length; i < il; ++i) {
42711
43155
  let resi = ic.chainsSeq[chainid][i].resi;
42712
43156
  let resid = chainid + '_' + resi;
42713
43157
  if(!ic.firstAtomObjCls.getFirstAtomObj(ic.residues[resid])) { // mising coordinate
42714
- if(chainid2missingResi[chainid] === undefined) chainid2missingResi[chainid] = [];
43158
+ if(ic.chainMissingResidueArray[chainid] === undefined) ic.chainMissingResidueArray[chainid] = [];
42715
43159
  let seq = me.utilsCls.residueAbbr2Name(ic.chainsSeq[chainid][i].name);
42716
43160
  let resiObj = {'resi': resi, 'seq': seq};
42717
- chainid2missingResi[chainid].push(resiObj);
43161
+ ic.chainMissingResidueArray[chainid].push(resiObj);
42718
43162
  }
42719
43163
  }
42720
43164
  }
42721
43165
 
42722
43166
  // add missing residues "REMARK 465..."
42723
- for(let chainid in chainid2missingResi) {
43167
+ for(let chainid in ic.chainMissingResidueArray) {
42724
43168
  let pos = chainid.indexOf('_');
42725
43169
  let chain = chainid.substr(pos + 1, 2);
42726
43170
  let stru = chainid.substr(0, pos);
42727
43171
 
42728
- for(let i = 0, il = chainid2missingResi[chainid].length; i < il; ++i) {
42729
- let resi = chainid2missingResi[chainid][i].resi;
42730
- let seq = chainid2missingResi[chainid][i].seq;
43172
+ for(let i = 0, il = ic.chainMissingResidueArray[chainid].length; i < il; ++i) {
43173
+ let resi = ic.chainMissingResidueArray[chainid][i].resi;
43174
+ let seq = ic.chainMissingResidueArray[chainid][i].seq;
42731
43175
 
42732
43176
  stru2header[stru] += "REMARK 465 " + seq.padStart(3, " ") + chain.padStart(2, " ") + " " + resi.toString().padStart(5, " ") + "\n";
42733
43177
  }
42734
43178
  }
43179
+ */
43180
+
43181
+ // add missing residues "REMARK 465..."
43182
+ for(let chainid in ic.chainMissingResidueArray) {
43183
+ let pos = chainid.indexOf('_');
43184
+ let chain = chainid.substr(pos + 1, 2);
43185
+ let stru = chainid.substr(0, pos);
43186
+
43187
+ for(let i = 0, il = ic.chainMissingResidueArray[chainid].length; i < il; ++i) {
43188
+ let resi = ic.chainMissingResidueArray[chainid][i].resi;
43189
+ let resn = me.utilsCls.residueAbbr2Name(ic.chainMissingResidueArray[chainid][i].name);
43190
+
43191
+ stru2header[stru] += "REMARK 465 " + resn.padStart(3, " ") + chain.padStart(2, " ") + " " + resi.toString().padStart(5, " ") + "\n";
43192
+ }
43193
+ }
42735
43194
 
42736
43195
  let connStr = '';
42737
43196
  let struArray = Object.keys(ic.structures);
@@ -43010,7 +43469,7 @@ class SaveFile {
43010
43469
  if(ic.molTitle !== undefined && ic.molTitle !== '') {
43011
43470
  let title = ic.molTitle;
43012
43471
 
43013
- let titlelinkColor =(ic.opts['background'] == 'white' || ic.opts['background'] == 'grey') ? 'black' : me.htmlCls.GREYD;
43472
+ let titlelinkColor =(ic.opts['background'] == 'black') ? me.htmlCls.GREYD : 'black';
43014
43473
 
43015
43474
  if(ic.inputid === undefined) {
43016
43475
  if(ic.molTitle.length > 40) title = ic.molTitle.substr(0, 40) + "...";
@@ -43457,6 +43916,21 @@ class ClickMenu {
43457
43916
  let file_pref =(ic.inputid) ? ic.inputid : "custom";
43458
43917
  ic.saveFileCls.saveFile(file_pref + '_selections.txt', 'text', [text]);
43459
43918
  });
43919
+
43920
+ me.myEventCls.onIds("#" + me.pre + "mn1_exportSelDetails", "click", function(e) { let ic = me.icn3d;
43921
+ thisClass.setLogCmd("export all selections with details", false);
43922
+ if(ic.bSetChainsAdvancedMenu === undefined || !ic.bSetChainsAdvancedMenu) {
43923
+ let prevHAtoms = me.hashUtilsCls.cloneHash(ic.hAtoms);
43924
+ ic.definedSetsCls.setPredefinedInMenu();
43925
+ ic.bSetChainsAdvancedMenu = true;
43926
+ ic.hAtoms = me.hashUtilsCls.cloneHash(prevHAtoms);
43927
+ }
43928
+ let bDetails = true;
43929
+ let text = ic.saveFileCls.exportCustomAtoms(bDetails);
43930
+ let file_pref =(ic.inputid) ? ic.inputid : "custom";
43931
+ ic.saveFileCls.saveFile(file_pref + '_sel_details.txt', 'text', [text]);
43932
+ });
43933
+
43460
43934
  // },
43461
43935
  // clkMn1_sharelink: function() {
43462
43936
  me.myEventCls.onIds("#" + me.pre + "mn1_sharelink", "click", function(e) { let ic = me.icn3d;
@@ -44598,6 +45072,10 @@ class ClickMenu {
44598
45072
  me.myEventCls.onIds("#" + me.pre + "mn6_addlabelSelection", "click", function(e) { me.icn3d;
44599
45073
  me.htmlCls.dialogCls.openDlg('dl_addlabelselection', 'Add custom labels by the selected');
44600
45074
  });
45075
+
45076
+ me.myEventCls.onIds("#" + me.pre + "mn6_labelColor", "click", function(e) { me.icn3d;
45077
+ me.htmlCls.dialogCls.openDlg('dl_labelColor', 'Change color for all labels');
45078
+ });
44601
45079
  // },
44602
45080
  // clkMn2_saveselection: function() {
44603
45081
  me.myEventCls.onIds("#" + me.pre + "mn2_saveselection", "click", function(e) { me.icn3d;
@@ -44606,7 +45084,8 @@ class ClickMenu {
44606
45084
  // },
44607
45085
  // clkMn6_addlabelNo: function() {
44608
45086
  me.myEventCls.onIds(["#" + me.pre + "mn6_addlabelNo", "#" + me.pre + "removeLabels"], "click", function(e) { let ic = me.icn3d;
44609
- ic.pickpair = false;
45087
+ ic.labelcolor = undefined;
45088
+ ic.pickpair = false;
44610
45089
  //ic.labels['residue'] = [];
44611
45090
  //ic.labels['custom'] = [];
44612
45091
  let select = "set labels off";
@@ -45159,6 +45638,8 @@ class SetMenu {
45159
45638
  setTopMenusHtml(id, str1, str2) { let me = this.icn3dui;
45160
45639
  if(me.bNode) return '';
45161
45640
 
45641
+ let titleColor =(me.htmlCls.opts['background'] == 'black') ? me.htmlCls.GREYD : 'black';
45642
+
45162
45643
  let html = "";
45163
45644
 
45164
45645
  html += "<div style='position:relative;'>";
@@ -45174,15 +45655,15 @@ class SetMenu {
45174
45655
  let tdStr = '<td valign="top">';
45175
45656
  html += tdStr + this.setMenu1() + '</td>';
45176
45657
 
45177
- if(!me.cfg.simplemenu) {
45658
+ //if(!me.cfg.simplemenu) {
45178
45659
  html += tdStr + this.setMenu2() + '</td>';
45179
- }
45660
+ //}
45180
45661
 
45181
45662
  html += tdStr + this.setMenu2b() + '</td>';
45182
45663
  html += tdStr + this.setMenu3() + '</td>';
45183
45664
  html += tdStr + this.setMenu4() + '</td>';
45184
45665
 
45185
- if(!me.cfg.simplemenu) {
45666
+ //if(!me.cfg.simplemenu) {
45186
45667
  html += tdStr + this.setMenu5() + '</td>';
45187
45668
  //html += tdStr + this.setMenu5b() + '</td>';
45188
45669
  html += tdStr + this.setMenu6() + '</td>';
@@ -45193,7 +45674,7 @@ class SetMenu {
45193
45674
  html += tdStr + '<div class="icn3d-commandTitle" style="white-space:nowrap; margin-top:10px; border-left:solid 1px #888888"><span id="' + me.pre + 'selection_expand" class="icn3d-expand icn3d-link" title="Expand">' + me.htmlCls.space2 + 'Toolbar <span class="ui-icon ui-icon-plus" style="width:15px"></span>' + me.htmlCls.space2 + '</span><span id="' + me.pre + 'selection_shrink" class="icn3d-shrink icn3d-link" style="display:none;" title="Shrink">' + me.htmlCls.space2 + 'Toolbar <span class="ui-icon ui-icon-minus" style="width:15px"></span>' + me.htmlCls.space2 + '</span></div></td>';
45194
45675
 
45195
45676
  html += tdStr + '<div class="icn3d-commandTitle" style="white-space:nowrap; margin-top:8px; border-left:solid 1px #888888">' + me.htmlCls.space2 + '<input type="text" id="' + me.pre + 'search_seq" size="10" placeholder="one-letter seq."> <button style="white-space:nowrap;" id="' + me.pre + 'search_seq_button">Search</button> <a style="text-decoration: none;" href="' + me.htmlCls.baseUrl + 'icn3d/icn3d.html#selectb" target="_blank" title="Specification tips">?</a></div></td>';
45196
- }
45677
+ //}
45197
45678
 
45198
45679
  html += "</tr>";
45199
45680
  html += "</table>";
@@ -45202,7 +45683,7 @@ class SetMenu {
45202
45683
  html += this.setTools();
45203
45684
 
45204
45685
  // show title at the top left corner
45205
- html += me.htmlCls.divStr + "title' class='icn3d-commandTitle' style='font-size:1.2em; font-weight:normal; position:absolute; z-index:1; float:left; display:table-row; margin: 85px 0px 0px 5px; color:" + me.htmlCls.GREYD + "; width:" + me.htmlCls.WIDTH + "px'></div>";
45686
+ html += me.htmlCls.divStr + "title' class='icn3d-commandTitle' style='font-size:1.2em; font-weight:normal; position:absolute; z-index:1; float:left; display:table-row; margin: 85px 0px 0px 5px; color:" + titleColor + "; width:" + me.htmlCls.WIDTH + "px'></div>";
45206
45687
 
45207
45688
  html += me.htmlCls.divStr + "viewer' style='position:relative; width:100%; height:100%; background-color: " + me.htmlCls.GREYD + ";'>";
45208
45689
 
@@ -45219,7 +45700,7 @@ class SetMenu {
45219
45700
  let tmpStr = 'top:180px; font-size: 1.8em;';
45220
45701
  html += me.htmlCls.divStr + "wait' style='position:absolute; left:50px; " + tmpStr + " color: #444444;'>Loading data...</div>";
45221
45702
  }
45222
- html += "<canvas id='" + me.pre + "canvas' style='width:100%; height: 100%; background-color: #000;'>Your browser does not support WebGL.</canvas>";
45703
+ html += "<canvas id='" + me.pre + "canvas' style='width:100%; height: 100%; background-color: #FFF;'>Your browser does not support WebGL.</canvas>";
45223
45704
 
45224
45705
  // separate for the log box
45225
45706
  if(me.cfg.showcommand === undefined || me.cfg.showcommand) {
@@ -45255,6 +45736,8 @@ class SetMenu {
45255
45736
  setTopMenusHtmlMobile(id, str1, str2) { let me = this.icn3dui;
45256
45737
  if(me.bNode) return '';
45257
45738
 
45739
+ let titleColor =(me.htmlCls.opts['background'] == 'black') ? me.htmlCls.GREYD : 'black';
45740
+
45258
45741
  let html = "";
45259
45742
 
45260
45743
  html += "<div style='position:relative;'>";
@@ -45324,8 +45807,6 @@ class SetMenu {
45324
45807
  //html += me.htmlCls.setMenuCls.setTools();
45325
45808
 
45326
45809
  // show title at the top left corner
45327
- let titleColor =(me.htmlCls.opts['background'] == 'white' || me.htmlCls.opts['background'] == 'grey') ? 'black' : me.htmlCls.GREYD;
45328
-
45329
45810
  html += me.htmlCls.divStr + "title' class='icn3d-commandTitle' style='font-size:1.2em; font-weight:normal; position:absolute; z-index:1; float:left; display:block; margin: 12px 0px 0px 40px; color:" + titleColor + "; width:" +(me.htmlCls.WIDTH - 40).toString() + "px'></div>";
45330
45811
  html += me.htmlCls.divStr + "viewer' style='position:relative; width:100%; height:100%; background-color: " + me.htmlCls.GREYD + ";'>";
45331
45812
  html += me.htmlCls.divStr + "mnLogSection'>";
@@ -45337,7 +45818,7 @@ class SetMenu {
45337
45818
  let tmpStr = 'top:180px; font-size: 1.8em;';
45338
45819
  html += me.htmlCls.divStr + "wait' style='position:absolute; left:50px; " + tmpStr + " color: #444444;'>Loading data...</div>";
45339
45820
  }
45340
- html += "<canvas id='" + me.pre + "canvas' style='width:100%; height: 100%; background-color: #000;'>Your browser does not support WebGL.</canvas>";
45821
+ html += "<canvas id='" + me.pre + "canvas' style='width:100%; height: 100%; background-color: #FFF;'>Your browser does not support WebGL.</canvas>";
45341
45822
 
45342
45823
  // separate for the log box
45343
45824
  if(me.cfg.showcommand === undefined || me.cfg.showcommand) {
@@ -45529,15 +46010,18 @@ class SetMenu {
45529
46010
  let html = "";
45530
46011
 
45531
46012
  html += "<ul class='icn3d-mn-item'>";
46013
+ html += "<li><a href='https://www.ncbi.nlm.nih.gov/structure' target='_blank'>Search Structure " + me.htmlCls.wifiStr + "</a></li>";
45532
46014
  html += "<li><span>Retrieve by ID</span>";
45533
46015
  html += "<ul>";
45534
46016
  html += me.htmlCls.setHtmlCls.getLink('mn1_mmdbid', 'MMDB ID ' + me.htmlCls.wifiStr);
45535
46017
  html += me.htmlCls.setHtmlCls.getLink('mn1_mmtfid', 'MMTF ID ' + me.htmlCls.wifiStr);
45536
46018
  html += me.htmlCls.setHtmlCls.getLink('mn1_pdbid', 'PDB ID ' + me.htmlCls.wifiStr);
45537
46019
  html += me.htmlCls.setHtmlCls.getLink('mn1_afid', 'AlphaFold UniProt ID ' + me.htmlCls.wifiStr);
45538
- html += me.htmlCls.setHtmlCls.getLink('mn1_opmid', 'OPM PDB ID ' + me.htmlCls.wifiStr);
45539
- html += me.htmlCls.setHtmlCls.getLink('mn1_mmcifid', 'mmCIF ID ' + me.htmlCls.wifiStr);
45540
- html += me.htmlCls.setHtmlCls.getLink('mn1_gi', 'NCBI gi ' + me.htmlCls.wifiStr);
46020
+ if(!me.cfg.simplemenu) {
46021
+ html += me.htmlCls.setHtmlCls.getLink('mn1_opmid', 'OPM PDB ID ' + me.htmlCls.wifiStr);
46022
+ html += me.htmlCls.setHtmlCls.getLink('mn1_mmcifid', 'mmCIF ID ' + me.htmlCls.wifiStr);
46023
+ html += me.htmlCls.setHtmlCls.getLink('mn1_gi', 'NCBI gi ' + me.htmlCls.wifiStr);
46024
+ }
45541
46025
  html += me.htmlCls.setHtmlCls.getLink('mn1_uniprotid', 'UniProt ID ' + me.htmlCls.wifiStr);
45542
46026
  html += me.htmlCls.setHtmlCls.getLink('mn1_cid', 'PubChem CID ' + me.htmlCls.wifiStr);
45543
46027
  html += "</ul>";
@@ -45547,29 +46031,32 @@ class SetMenu {
45547
46031
  // html += me.htmlCls.setHtmlCls.getLink('mn1_pdbfile', 'PDB File');
45548
46032
  // html += me.htmlCls.setHtmlCls.getLink('mn1_pdbfile_app', 'PDB File (append)');
45549
46033
  html += me.htmlCls.setHtmlCls.getLink('mn1_pdbfile_app', 'PDB File (appendable)');
45550
- html += me.htmlCls.setHtmlCls.getLink('mn1_mmciffile', 'mmCIF File');
46034
+ if(!me.cfg.simplemenu) html += me.htmlCls.setHtmlCls.getLink('mn1_mmciffile', 'mmCIF File');
45551
46035
  html += me.htmlCls.setHtmlCls.getLink('mn1_mol2file', 'Mol2 File');
45552
46036
  html += me.htmlCls.setHtmlCls.getLink('mn1_sdffile', 'SDF File');
45553
46037
  html += me.htmlCls.setHtmlCls.getLink('mn1_xyzfile', 'XYZ File');
45554
- html += me.htmlCls.setHtmlCls.getLink('mn1_urlfile', 'URL(Same Host) ' + me.htmlCls.wifiStr);
46038
+ if(!me.cfg.simplemenu) html += me.htmlCls.setHtmlCls.getLink('mn1_urlfile', 'URL(Same Host) ' + me.htmlCls.wifiStr);
45555
46039
  html += "<li>-</li>";
45556
46040
  html += me.htmlCls.setHtmlCls.getLink('mn1_pngimage', 'iCn3D PNG Image');
45557
46041
  html += me.htmlCls.setHtmlCls.getLink('mn1_state', 'State/Script File');
45558
- html += me.htmlCls.setHtmlCls.getLink('mn1_fixedversion', 'Share Link in Archived Ver. ' + me.htmlCls.wifiStr);
46042
+ if(!me.cfg.simplemenu) html += me.htmlCls.setHtmlCls.getLink('mn1_fixedversion', 'Share Link in Archived Ver. ' + me.htmlCls.wifiStr);
45559
46043
  html += me.htmlCls.setHtmlCls.getLink('mn1_selection', 'Selection File');
45560
- html += "<li>-</li>";
46044
+
46045
+ if(!me.cfg.simplemenu) {
46046
+ html += "<li>-</li>";
45561
46047
 
45562
- html += "<li><span>Electron Density(DSN6)</span>";
45563
- html += "<ul>";
45564
- html += me.htmlCls.setHtmlCls.getLink('mn1_dsn6', 'Local File');
45565
- html += me.htmlCls.setHtmlCls.getLink('mn1_dsn6url', 'URL(Same Host) ' + me.htmlCls.wifiStr);
45566
- html += "</ul>";
46048
+ html += "<li><span>Electron Density(DSN6)</span>";
46049
+ html += "<ul>";
46050
+ html += me.htmlCls.setHtmlCls.getLink('mn1_dsn6', 'Local File');
46051
+ html += me.htmlCls.setHtmlCls.getLink('mn1_dsn6url', 'URL(Same Host) ' + me.htmlCls.wifiStr);
46052
+ html += "</ul>";
46053
+ }
45567
46054
 
45568
46055
  html += "</ul>";
45569
46056
  html += "</li>";
45570
46057
  html += "<li><span>Align</span>";
45571
46058
  html += "<ul>";
45572
- html += me.htmlCls.setHtmlCls.getLink('mn1_blast_rep_id', 'Sequence to Structure ' + me.htmlCls.wifiStr);
46059
+ html += me.htmlCls.setHtmlCls.getLink('mn1_blast_rep_id', 'Sequence to Structure');
45573
46060
  html += me.htmlCls.setHtmlCls.getLink('mn1_align', 'Structure to Structure ' + me.htmlCls.wifiStr);
45574
46061
  //html += me.htmlCls.setHtmlCls.getLink('mn1_chainalign', 'Chain to Chain');
45575
46062
  html += me.htmlCls.setHtmlCls.getLink('mn1_chainalign', 'Multiple Chains ' + me.htmlCls.wifiStr);
@@ -45594,15 +46081,18 @@ class SetMenu {
45594
46081
  html += "<li>-</li>";
45595
46082
  html += me.htmlCls.setHtmlCls.getLink('mn1_exportVrml', 'WRL/VRML(Color)');
45596
46083
  html += me.htmlCls.setHtmlCls.getLink('mn1_exportStl', 'STL');
45597
- html += "<li>-</li>";
45598
- html += me.htmlCls.setHtmlCls.getLink('mn1_stabilizerYes', 'Add All Stabilizers');
45599
- html += me.htmlCls.setHtmlCls.getLink('mn1_stabilizerNo', 'Remove All Stabilizers');
45600
- html += "<li>-</li>";
45601
- html += me.htmlCls.setHtmlCls.getLink('mn1_stabilizerOne', 'Add One Stabilizer');
45602
- html += me.htmlCls.setHtmlCls.getLink('mn1_stabilizerRmOne', 'Remove One Stabilizer');
45603
- html += "<li>-</li>";
45604
- html += me.htmlCls.setHtmlCls.getLink('mn1_thicknessSet', 'Set Thickness');
45605
- //html += me.htmlCls.setHtmlCls.getLink('mn1_thicknessReset', 'Reset Thickness');
46084
+
46085
+ if(!me.cfg.simplemenu) {
46086
+ html += "<li>-</li>";
46087
+ html += me.htmlCls.setHtmlCls.getLink('mn1_stabilizerYes', 'Add All Stabilizers');
46088
+ html += me.htmlCls.setHtmlCls.getLink('mn1_stabilizerNo', 'Remove All Stabilizers');
46089
+ html += "<li>-</li>";
46090
+ html += me.htmlCls.setHtmlCls.getLink('mn1_stabilizerOne', 'Add One Stabilizer');
46091
+ html += me.htmlCls.setHtmlCls.getLink('mn1_stabilizerRmOne', 'Remove One Stabilizer');
46092
+ html += "<li>-</li>";
46093
+ html += me.htmlCls.setHtmlCls.getLink('mn1_thicknessSet', 'Set Thickness');
46094
+ //html += me.htmlCls.setHtmlCls.getLink('mn1_thicknessReset', 'Reset Thickness');
46095
+ }
45606
46096
  }
45607
46097
  else {
45608
46098
  html += me.htmlCls.setHtmlCls.getLink('mn1_exportVrml', 'VRML(Color)');
@@ -45620,14 +46110,17 @@ class SetMenu {
45620
46110
  html += "<ul>";
45621
46111
  html += me.htmlCls.setHtmlCls.getLink('mn1_exportCanvas', 'Original Size & HTML');
45622
46112
  html += me.htmlCls.setHtmlCls.getLink('mn1_exportCanvas1', 'Original Size');
45623
- html += me.htmlCls.setHtmlCls.getLink('mn1_exportCanvas2', '2X Large');
45624
- html += me.htmlCls.setHtmlCls.getLink('mn1_exportCanvas4', '4X Large');
45625
- html += me.htmlCls.setHtmlCls.getLink('mn1_exportCanvas8', '8X Large');
46113
+ if(!me.cfg.simplemenu) {
46114
+ html += me.htmlCls.setHtmlCls.getLink('mn1_exportCanvas2', '2X Large');
46115
+ html += me.htmlCls.setHtmlCls.getLink('mn1_exportCanvas4', '4X Large');
46116
+ html += me.htmlCls.setHtmlCls.getLink('mn1_exportCanvas8', '8X Large');
46117
+ }
45626
46118
  html += "</ul>";
45627
46119
  html += "</li>";
45628
46120
 
45629
46121
  html += me.htmlCls.setHtmlCls.getLink('mn1_exportState', 'State File');
45630
46122
  html += me.htmlCls.setHtmlCls.getLink('mn1_exportSelections', 'Selection File');
46123
+ html += me.htmlCls.setHtmlCls.getLink('mn1_exportSelDetails', 'Selection Details');
45631
46124
  html += me.htmlCls.setHtmlCls.getLink('mn1_exportCounts', 'Residue Counts');
45632
46125
 
45633
46126
  /*
@@ -45689,9 +46182,9 @@ class SetMenu {
45689
46182
 
45690
46183
  html += "<ul class='icn3d-mn-item'>";
45691
46184
 
45692
- html += me.htmlCls.setHtmlCls.getLink('mn2_definedsets', 'Defined Sets');
46185
+ if(!me.cfg.simplemenu) html += me.htmlCls.setHtmlCls.getLink('mn2_definedsets', 'Defined Sets');
45693
46186
  html += me.htmlCls.setHtmlCls.getLink('mn2_selectall', 'All');
45694
- html += me.htmlCls.setHtmlCls.getLink('mn2_selectdisplayed', 'Displayed Set');
46187
+ if(!me.cfg.simplemenu) html += me.htmlCls.setHtmlCls.getLink('mn2_selectdisplayed', 'Displayed Set');
45695
46188
  html += me.htmlCls.setHtmlCls.getLink('mn2_aroundsphere', 'by Distance');
45696
46189
 
45697
46190
  html += "<li><span>by Property</span>";
@@ -45705,11 +46198,13 @@ class SetMenu {
45705
46198
  html += "</ul>";
45706
46199
  html += "</li>";
45707
46200
 
45708
- html += me.htmlCls.setHtmlCls.getLink('mn2_selectcomplement', 'Inverse');
45709
- html += me.htmlCls.setHtmlCls.getLink('mn2_selectmainchains', 'Main Chains');
45710
- html += me.htmlCls.setHtmlCls.getLink('mn2_selectsidechains', 'Side Chains');
45711
- html += me.htmlCls.setHtmlCls.getLink('mn2_selectmainsidechains', 'Main & Side Chains');
45712
- html += me.htmlCls.setHtmlCls.getLink('mn2_command', 'Advanced');
46201
+ if(!me.cfg.simplemenu) {
46202
+ html += me.htmlCls.setHtmlCls.getLink('mn2_selectcomplement', 'Inverse');
46203
+ html += me.htmlCls.setHtmlCls.getLink('mn2_selectmainchains', 'Main Chains');
46204
+ html += me.htmlCls.setHtmlCls.getLink('mn2_selectsidechains', 'Side Chains');
46205
+ html += me.htmlCls.setHtmlCls.getLink('mn2_selectmainsidechains', 'Main & Side Chains');
46206
+ html += me.htmlCls.setHtmlCls.getLink('mn2_command', 'Advanced');
46207
+ }
45713
46208
 
45714
46209
  if(me.cfg.cid === undefined) {
45715
46210
  html += "<li><span>Select on 3D</span>";
@@ -45746,22 +46241,24 @@ class SetMenu {
45746
46241
 
45747
46242
  html += "<li>-</li>";
45748
46243
 
45749
- html += "<li><span>Highlight Color</span>";
45750
- html += "<ul>";
45751
- html += me.htmlCls.setHtmlCls.getRadio('mn2_hl_clr', 'mn2_hl_clrYellow', 'Yellow', true);
45752
- html += me.htmlCls.setHtmlCls.getRadio('mn2_hl_clr', 'mn2_hl_clrGreen', 'Green');
45753
- html += me.htmlCls.setHtmlCls.getRadio('mn2_hl_clr', 'mn2_hl_clrRed', 'Red');
45754
- html += "</ul>";
45755
- html += "</li>";
45756
- html += "<li><span>Highlight Style</span>";
45757
- html += "<ul>";
46244
+ if(!me.cfg.simplemenu) {
46245
+ html += "<li><span>Highlight Color</span>";
46246
+ html += "<ul>";
46247
+ html += me.htmlCls.setHtmlCls.getRadio('mn2_hl_clr', 'mn2_hl_clrYellow', 'Yellow', true);
46248
+ html += me.htmlCls.setHtmlCls.getRadio('mn2_hl_clr', 'mn2_hl_clrGreen', 'Green');
46249
+ html += me.htmlCls.setHtmlCls.getRadio('mn2_hl_clr', 'mn2_hl_clrRed', 'Red');
46250
+ html += "</ul>";
46251
+ html += "</li>";
46252
+ html += "<li><span>Highlight Style</span>";
46253
+ html += "<ul>";
45758
46254
 
45759
- html += me.htmlCls.setHtmlCls.getRadio('mn2_hl_style', 'mn2_hl_styleOutline', 'Outline', true);
45760
- html += me.htmlCls.setHtmlCls.getRadio('mn2_hl_style', 'mn2_hl_styleObject', '3D Objects');
45761
- //html += me.htmlCls.setHtmlCls.getRadio('mn2_hl_style', 'mn2_hl_styleNone', 'No Highlight');
46255
+ html += me.htmlCls.setHtmlCls.getRadio('mn2_hl_style', 'mn2_hl_styleOutline', 'Outline', true);
46256
+ html += me.htmlCls.setHtmlCls.getRadio('mn2_hl_style', 'mn2_hl_styleObject', '3D Objects');
46257
+ //html += me.htmlCls.setHtmlCls.getRadio('mn2_hl_style', 'mn2_hl_styleNone', 'No Highlight');
45762
46258
 
45763
- html += "</ul>";
45764
- html += "</li>";
46259
+ html += "</ul>";
46260
+ html += "</li>";
46261
+ }
45765
46262
 
45766
46263
  //html += me.htmlCls.setHtmlCls.getLink('mn2_hl_styleNone', 'Clear Highlight');
45767
46264
 
@@ -45800,7 +46297,7 @@ class SetMenu {
45800
46297
  html += "<ul class='icn3d-mn-item'>";
45801
46298
 
45802
46299
  html += me.htmlCls.setHtmlCls.getLink('mn2_show_selected', 'View Selection');
45803
- html += me.htmlCls.setHtmlCls.getLink('mn2_hide_selected', 'Hide Selection');
46300
+ if(!me.cfg.simplemenu) html += me.htmlCls.setHtmlCls.getLink('mn2_hide_selected', 'Hide Selection');
45804
46301
  html += me.htmlCls.setHtmlCls.getLink('mn2_selectedcenter', 'Zoom in Selection');
45805
46302
  html += me.htmlCls.setHtmlCls.getLink('mn6_center', 'Center Selection');
45806
46303
  html += me.htmlCls.setHtmlCls.getLink('mn2_fullstru', 'View Full Structure');
@@ -45878,8 +46375,10 @@ class SetMenu {
45878
46375
  html += "</ul>";
45879
46376
  html += "</li>";
45880
46377
 
45881
- html += me.htmlCls.setHtmlCls.getLink('mn6_back', 'Undo');
45882
- html += me.htmlCls.setHtmlCls.getLink('mn6_forward', 'Redo');
46378
+ if(!me.cfg.simplemenu) {
46379
+ html += me.htmlCls.setHtmlCls.getLink('mn6_back', 'Undo');
46380
+ html += me.htmlCls.setHtmlCls.getLink('mn6_forward', 'Redo');
46381
+ }
45883
46382
 
45884
46383
  html += me.htmlCls.setHtmlCls.getLink('mn6_fullscreen', 'Full Screen');
45885
46384
  // html += me.htmlCls.setHtmlCls.getLink('mn6_exitfullscreen', 'Exit Full Screen');
@@ -46027,21 +46526,22 @@ class SetMenu {
46027
46526
 
46028
46527
  html += me.htmlCls.setHtmlCls.getLink('mn3_setThickness', 'Preferences');
46029
46528
 
46030
- html += "<li>-</li>";
46031
-
46032
- html += me.htmlCls.setHtmlCls.getLink('mn3_styleSave', 'Save Style');
46033
- html += me.htmlCls.setHtmlCls.getLink('mn3_styleApplySave', 'Apply Saved Style');
46529
+ if(!me.cfg.simplemenu) {
46530
+ html += "<li>-</li>";
46531
+ html += me.htmlCls.setHtmlCls.getLink('mn3_styleSave', 'Save Style');
46532
+ html += me.htmlCls.setHtmlCls.getLink('mn3_styleApplySave', 'Apply Saved Style');
46533
+ }
46034
46534
 
46035
46535
  html += "<li>-</li>";
46036
46536
 
46037
46537
  html += "<li><span>Surface Type</span>";
46038
46538
  html += "<ul>";
46039
46539
  html += me.htmlCls.setHtmlCls.getRadio('mn5_surface', 'mn5_surfaceVDW', 'Van der Waals');
46040
- html += me.htmlCls.setHtmlCls.getRadio('mn5_surface', 'mn5_surfaceVDWContext', 'VDW with Context');
46540
+ if(!me.cfg.simplemenu) html += me.htmlCls.setHtmlCls.getRadio('mn5_surface', 'mn5_surfaceVDWContext', 'VDW with Context');
46041
46541
  html += me.htmlCls.setHtmlCls.getRadio('mn5_surface', 'mn5_surfaceMolecular', 'Molecular Surface');
46042
- html += me.htmlCls.setHtmlCls.getRadio('mn5_surface', 'mn5_surfaceMolecularContext', 'MS with Context');
46542
+ if(!me.cfg.simplemenu) html += me.htmlCls.setHtmlCls.getRadio('mn5_surface', 'mn5_surfaceMolecularContext', 'MS with Context');
46043
46543
  html += me.htmlCls.setHtmlCls.getRadio('mn5_surface', 'mn5_surfaceSAS', 'Solvent Accessible');
46044
- html += me.htmlCls.setHtmlCls.getRadio('mn5_surface', 'mn5_surfaceSASContext', 'SA with Context');
46544
+ if(!me.cfg.simplemenu) html += me.htmlCls.setHtmlCls.getRadio('mn5_surface', 'mn5_surfaceSASContext', 'SA with Context');
46045
46545
  html += "</ul>";
46046
46546
  html += "</li>";
46047
46547
 
@@ -46064,36 +46564,38 @@ class SetMenu {
46064
46564
  html += "</li>";
46065
46565
 
46066
46566
  if(me.cfg.cid === undefined && me.cfg.align === undefined && me.cfg.chainalign === undefined) {
46067
- html += "<li>-</li>";
46068
-
46069
- html += "<li id='" + me.pre + "mapWrapper1'><span>Electron Density</span>";
46070
- html += "<ul>";
46071
- html += me.htmlCls.setHtmlCls.getRadio('mn5_elecmap', 'mn5_elecmap2fofc', '2Fo-Fc Map');
46072
- html += me.htmlCls.setHtmlCls.getRadio('mn5_elecmap', 'mn5_elecmapfofc', 'Fo-Fc Map');
46073
- html += "</ul>";
46074
- html += "</li>";
46075
-
46076
- html += me.htmlCls.setHtmlCls.getLinkWrapper('mn5_elecmapNo', 'Remove Map', 'mapWrapper2');
46077
-
46078
- html += "<li id='" + me.pre + "mapWrapper3'><span>Map Wireframe</span>";
46079
- html += "<ul>";
46080
- html += me.htmlCls.setHtmlCls.getRadio('mn5_mapwireframe', 'mn5_mapwireframeYes', 'Yes', true);
46081
- html += me.htmlCls.setHtmlCls.getRadio('mn5_mapwireframe', 'mn5_mapwireframeNo', 'No');
46082
- html += "</ul>";
46083
- html += "</li>";
46567
+ if(!me.cfg.simplemenu) {
46568
+ html += "<li>-</li>";
46084
46569
 
46085
- if(me.cfg.mmtfid === undefined) {
46086
- //html += "<li>-</li>";
46570
+ html += "<li id='" + me.pre + "mapWrapper1'><span>Electron Density</span>";
46571
+ html += "<ul>";
46572
+ html += me.htmlCls.setHtmlCls.getRadio('mn5_elecmap', 'mn5_elecmap2fofc', '2Fo-Fc Map');
46573
+ html += me.htmlCls.setHtmlCls.getRadio('mn5_elecmap', 'mn5_elecmapfofc', 'Fo-Fc Map');
46574
+ html += "</ul>";
46575
+ html += "</li>";
46087
46576
 
46088
- html += me.htmlCls.setHtmlCls.getLinkWrapper('mn5_emmap', 'EM Density Map', 'emmapWrapper1');
46089
- html += me.htmlCls.setHtmlCls.getLinkWrapper('mn5_emmapNo', 'Remove EM Map', 'emmapWrapper2');
46577
+ html += me.htmlCls.setHtmlCls.getLinkWrapper('mn5_elecmapNo', 'Remove Map', 'mapWrapper2');
46090
46578
 
46091
- html += "<li id='" + me.pre + "emmapWrapper3'><span>EM Map Wireframe</span>";
46579
+ html += "<li id='" + me.pre + "mapWrapper3'><span>Map Wireframe</span>";
46092
46580
  html += "<ul>";
46093
- html += me.htmlCls.setHtmlCls.getRadio('mn5_emmapwireframe', 'mn5_emmapwireframeYes', 'Yes', true);
46094
- html += me.htmlCls.setHtmlCls.getRadio('mn5_emmapwireframe', 'mn5_emmapwireframeNo', 'No');
46581
+ html += me.htmlCls.setHtmlCls.getRadio('mn5_mapwireframe', 'mn5_mapwireframeYes', 'Yes', true);
46582
+ html += me.htmlCls.setHtmlCls.getRadio('mn5_mapwireframe', 'mn5_mapwireframeNo', 'No');
46095
46583
  html += "</ul>";
46096
46584
  html += "</li>";
46585
+
46586
+ if(me.cfg.mmtfid === undefined) {
46587
+ //html += "<li>-</li>";
46588
+
46589
+ html += me.htmlCls.setHtmlCls.getLinkWrapper('mn5_emmap', 'EM Density Map', 'emmapWrapper1');
46590
+ html += me.htmlCls.setHtmlCls.getLinkWrapper('mn5_emmapNo', 'Remove EM Map', 'emmapWrapper2');
46591
+
46592
+ html += "<li id='" + me.pre + "emmapWrapper3'><span>EM Map Wireframe</span>";
46593
+ html += "<ul>";
46594
+ html += me.htmlCls.setHtmlCls.getRadio('mn5_emmapwireframe', 'mn5_emmapwireframeYes', 'Yes', true);
46595
+ html += me.htmlCls.setHtmlCls.getRadio('mn5_emmapwireframe', 'mn5_emmapwireframeNo', 'No');
46596
+ html += "</ul>";
46597
+ html += "</li>";
46598
+ }
46097
46599
  }
46098
46600
  }
46099
46601
 
@@ -46101,20 +46603,22 @@ class SetMenu {
46101
46603
 
46102
46604
  html += "<li><span>Background</span>";
46103
46605
  html += "<ul>";
46104
- html += me.htmlCls.setHtmlCls.getRadio('mn6_bkgd', 'mn6_bkgdTransparent', 'Transparent', true);
46105
- html += me.htmlCls.setHtmlCls.getRadio('mn6_bkgd', 'mn6_bkgdBlack', 'Black');
46606
+ html += me.htmlCls.setHtmlCls.getRadio('mn6_bkgd', 'mn6_bkgdTransparent', 'Transparent');
46607
+ html += me.htmlCls.setHtmlCls.getRadio('mn6_bkgd', 'mn6_bkgdBlack', 'Black', true);
46106
46608
  html += me.htmlCls.setHtmlCls.getRadio('mn6_bkgd', 'mn6_bkgdGrey', 'Gray');
46107
46609
  html += me.htmlCls.setHtmlCls.getRadio('mn6_bkgd', 'mn6_bkgdWhite', 'White');
46108
46610
  html += "</ul>";
46109
46611
  html += "</li>";
46110
46612
 
46111
- html += "<li><span>Dialog Color</span>";
46112
- html += "<ul>";
46113
- html += me.htmlCls.setHtmlCls.getRadio('mn6_theme', 'mn6_themeBlue', 'Blue', true);
46114
- html += me.htmlCls.setHtmlCls.getRadio('mn6_theme', 'mn6_themeOrange', 'Orange');
46115
- html += me.htmlCls.setHtmlCls.getRadio('mn6_theme', 'mn6_themeBlack', 'Black');
46116
- html += "</ul>";
46117
- html += "</li>";
46613
+ if(!me.cfg.simplemenu) {
46614
+ html += "<li><span>Dialog Color</span>";
46615
+ html += "<ul>";
46616
+ html += me.htmlCls.setHtmlCls.getRadio('mn6_theme', 'mn6_themeBlue', 'Blue', true);
46617
+ html += me.htmlCls.setHtmlCls.getRadio('mn6_theme', 'mn6_themeOrange', 'Orange');
46618
+ html += me.htmlCls.setHtmlCls.getRadio('mn6_theme', 'mn6_themeBlack', 'Black');
46619
+ html += "</ul>";
46620
+ html += "</li>";
46621
+ }
46118
46622
 
46119
46623
  // html += "<li><span>Two-color Helix</span>";
46120
46624
  // html += "<ul>";
@@ -46358,8 +46862,10 @@ class SetMenu {
46358
46862
 
46359
46863
  html += "</ul>";
46360
46864
 
46361
- html += me.htmlCls.setHtmlCls.getRadio('mn4_clr', 'mn4_clrCustom', 'Color Picker');
46362
- html += "<li>-</li>";
46865
+ if(!me.cfg.simplemenu) {
46866
+ html += me.htmlCls.setHtmlCls.getRadio('mn4_clr', 'mn4_clrCustom', 'Color Picker');
46867
+ html += "<li>-</li>";
46868
+ }
46363
46869
 
46364
46870
  if(me.cfg.cid === undefined) {
46365
46871
  //html += me.htmlCls.setHtmlCls.getRadio('mn4_clr', 'mn4_clrRainbow', 'Rainbow (R-V)');
@@ -46369,12 +46875,14 @@ class SetMenu {
46369
46875
  html += me.htmlCls.setHtmlCls.getRadio('mn4_clr', 'mn4_clrRainbowChain', 'for Chains');
46370
46876
  html += "</ul>";
46371
46877
 
46372
- //html += me.htmlCls.setHtmlCls.getRadio('mn4_clr', 'mn4_clrSpectrum', 'Spectrum (V-R)');
46373
- html += "<li><span style='padding-left:1.5em;'>Spectrum (V-R)</span>";
46374
- html += "<ul>";
46375
- html += me.htmlCls.setHtmlCls.getRadio('mn4_clr', 'mn4_clrSpectrum', 'for Selection');
46376
- html += me.htmlCls.setHtmlCls.getRadio('mn4_clr', 'mn4_clrSpectrumChain', 'for Chains');
46377
- html += "</ul>";
46878
+ if(!me.cfg.simplemenu) {
46879
+ //html += me.htmlCls.setHtmlCls.getRadio('mn4_clr', 'mn4_clrSpectrum', 'Spectrum (V-R)');
46880
+ html += "<li><span style='padding-left:1.5em;'>Spectrum (V-R)</span>";
46881
+ html += "<ul>";
46882
+ html += me.htmlCls.setHtmlCls.getRadio('mn4_clr', 'mn4_clrSpectrum', 'for Selection');
46883
+ html += me.htmlCls.setHtmlCls.getRadio('mn4_clr', 'mn4_clrSpectrumChain', 'for Chains');
46884
+ html += "</ul>";
46885
+ }
46378
46886
 
46379
46887
  html += "<li><span style='padding-left:1.5em;'>Secondary</span>";
46380
46888
  html += "<ul>";
@@ -46403,7 +46911,7 @@ class SetMenu {
46403
46911
  html += me.htmlCls.setHtmlCls.getRadio('mn4_clr', 'mn4_clrBfactorNorm', 'Percentile');
46404
46912
  html += "</ul>";
46405
46913
 
46406
- html += me.htmlCls.setHtmlCls.getRadio('mn4_clr', 'mn4_clrArea', 'Solvent<br><span style="padding-left:1.5em;">Accessibility</span>');
46914
+ if(!me.cfg.simplemenu) html += me.htmlCls.setHtmlCls.getRadio('mn4_clr', 'mn4_clrArea', 'Solvent<br><span style="padding-left:1.5em;">Accessibility</span>');
46407
46915
 
46408
46916
  if(me.cfg.align !== undefined || me.cfg.chainalign !== undefined || me.cfg.blast_rep_id !== undefined) {
46409
46917
  html += me.htmlCls.setHtmlCls.getRadio('mn4_clr', 'mn4_clrChain', 'Chain');
@@ -46417,10 +46925,12 @@ class SetMenu {
46417
46925
  }
46418
46926
 
46419
46927
  if(me.cfg.cid === undefined) {
46420
- html += "<li><span style='padding-left:1.5em;'>Defined Sets</span>";
46421
- html += "<ul>";
46422
- html += me.htmlCls.setHtmlCls.getRadio('mn4_clr', 'mn4_clrsets', 'Rainbow for Selected Sets<br>in "Analysis > Defined Sets"');
46423
- html += "</ul>";
46928
+ if(!me.cfg.simplemenu) {
46929
+ html += "<li><span style='padding-left:1.5em;'>Defined Sets</span>";
46930
+ html += "<ul>";
46931
+ html += me.htmlCls.setHtmlCls.getRadio('mn4_clr', 'mn4_clrsets', 'Rainbow for Selected Sets<br>in "Analysis > Defined Sets"');
46932
+ html += "</ul>";
46933
+ }
46424
46934
  }
46425
46935
 
46426
46936
  //html += me.htmlCls.setHtmlCls.getRadio('mn4_clr', 'mn4_clrResidue', 'Residue');
@@ -46443,17 +46953,21 @@ class SetMenu {
46443
46953
  }
46444
46954
 
46445
46955
  //if(me.cfg.afid) html += me.htmlCls.setHtmlCls.getRadio('mn4_clr', 'mn4_clrConfidence', 'AF Confidence');
46446
- if(!me.cfg.mmtfid && !me.cfg.pdbid && !me.cfg.opmid && !me.cfg.mmdbid && !me.cfg.gi && !me.cfg.uniprotid && !me.cfg.blast_rep_id && !me.cfg.cid && !me.cfg.mmcifid && !me.cfg.align && !me.cfg.chainalign) html += me.htmlCls.setHtmlCls.getRadio('mn4_clr', 'mn4_clrConfidence', 'AlphaFold<br><span style="padding-left:1.5em;">Confidence</span>');
46956
+ if(!me.cfg.mmtfid && !me.cfg.pdbid && !me.cfg.opmid && !me.cfg.mmdbid && !me.cfg.gi && !me.cfg.uniprotid && !me.cfg.blast_rep_id && !me.cfg.cid && !me.cfg.mmcifid && !me.cfg.align && !me.cfg.chainalign) {
46957
+ html += me.htmlCls.setHtmlCls.getRadio('mn4_clr', 'mn4_clrConfidence', 'AlphaFold<br><span style="padding-left:1.5em;">Confidence</span>');
46958
+ }
46447
46959
  }
46448
46960
  else {
46449
46961
  //if(!me.cfg.hidelicense) html += me.htmlCls.setHtmlCls.getRadio('mn4_clr', 'mn1_delphi2', 'DelPhi<br><span style="padding-left:1.5em;">Potential ' + me.htmlCls.licenseStr + '</span>');
46450
46962
  html += me.htmlCls.setHtmlCls.getRadio('mn4_clr', 'mn4_clrAtom', 'Atom', true);
46451
46963
  }
46452
46964
 
46453
- html += "<li>-</li>";
46965
+ if(!me.cfg.simplemenu) {
46966
+ html += "<li>-</li>";
46454
46967
 
46455
- html += me.htmlCls.setHtmlCls.getLink('mn4_clrSave', 'Save Color');
46456
- html += me.htmlCls.setHtmlCls.getLink('mn4_clrApplySave', 'Apply Saved Color');
46968
+ html += me.htmlCls.setHtmlCls.getLink('mn4_clrSave', 'Save Color');
46969
+ html += me.htmlCls.setHtmlCls.getLink('mn4_clrApplySave', 'Apply Saved Color');
46970
+ }
46457
46971
 
46458
46972
  html += "<li><br/></li>";
46459
46973
  html += "</ul>";
@@ -46514,8 +47028,8 @@ class SetMenu {
46514
47028
  html += me.htmlCls.setHtmlCls.getLink('mn6_hbondsYes', 'Interactions');
46515
47029
  //html += me.htmlCls.setHtmlCls.getLink('mn6_hbondsNo', 'Remove H-Bonds <br>& Interactions');
46516
47030
 
46517
- html += me.htmlCls.setHtmlCls.getLink('mn6_contactmap', 'Contact Map');
46518
-
47031
+ if(!me.cfg.simplemenu) html += me.htmlCls.setHtmlCls.getLink('mn6_contactmap', 'Contact Map');
47032
+ /*
46519
47033
  html += "<li><span>Bring to Front</span>";
46520
47034
  html += "<ul>";
46521
47035
  html += me.htmlCls.setHtmlCls.getLink('mn1_window_table', 'Interaction Table');
@@ -46524,22 +47038,26 @@ class SetMenu {
46524
47038
  html += me.htmlCls.setHtmlCls.getLink('mn1_window_graph', '2D Graph(Force-Directed)');
46525
47039
  html += "</ul>";
46526
47040
  html += "</li>";
47041
+ */
46527
47042
 
46528
47043
  if(!me.cfg.notebook) {
46529
47044
  html += me.htmlCls.setHtmlCls.getLink('mn1_mutation', 'Mutation ' + me.htmlCls.wifiStr);
46530
47045
  }
46531
47046
 
46532
- html += "<li>-</li>";
47047
+ if(!me.cfg.simplemenu) html += "<li>-</li>";
46533
47048
  }
46534
47049
 
46535
47050
  if(!me.cfg.notebook && !me.cfg.hidelicense) {
46536
47051
  html += me.htmlCls.setHtmlCls.getLink('mn1_delphi', 'DelPhi Potential ' + me.htmlCls.licenseStr);
46537
- html += "<li><span>Load PQR/Phi</span>";
46538
- html += "<ul>";
46539
- html += me.htmlCls.setHtmlCls.getLink('mn1_phi', 'Local PQR/Phi/Cube File');
46540
- html += me.htmlCls.setHtmlCls.getLink('mn1_phiurl', 'URL PQR/Phi/Cube File');
46541
- html += "</ul>";
46542
- html += me.htmlCls.setHtmlCls.getLink('delphipqr', 'Download PQR');
47052
+
47053
+ if(!me.cfg.simplemenu) {
47054
+ html += "<li><span>Load PQR/Phi</span>";
47055
+ html += "<ul>";
47056
+ html += me.htmlCls.setHtmlCls.getLink('mn1_phi', 'Local PQR/Phi/Cube File');
47057
+ html += me.htmlCls.setHtmlCls.getLink('mn1_phiurl', 'URL PQR/Phi/Cube File');
47058
+ html += "</ul>";
47059
+ html += me.htmlCls.setHtmlCls.getLink('delphipqr', 'Download PQR');
47060
+ }
46543
47061
 
46544
47062
  html += "<li>-</li>";
46545
47063
  }
@@ -46567,6 +47085,8 @@ class SetMenu {
46567
47085
  html += me.htmlCls.setHtmlCls.getRadio('mn6_addlabel', 'mn6_addlabelTermini', 'N- & C-Termini');
46568
47086
  }
46569
47087
 
47088
+ html += "<li>-</li>";
47089
+ html += me.htmlCls.setHtmlCls.getRadio('mn6_addlabel', 'mn6_labelColor', 'Change Label Color', true);
46570
47090
  html += me.htmlCls.setHtmlCls.getRadio('mn6_addlabel', 'mn6_addlabelNo', 'Remove', true);
46571
47091
  html += "</ul>";
46572
47092
  html += "</li>";
@@ -46594,12 +47114,14 @@ class SetMenu {
46594
47114
  html += "<li>-</li>";
46595
47115
 
46596
47116
  if(me.cfg.cid === undefined) {
46597
- html += "<li><span>Chem. Binding</span>";
46598
- html += "<ul>";
46599
- html += me.htmlCls.setHtmlCls.getRadio('mn6_chemicalbinding', 'mn6_chemicalbindingshow', 'Show');
46600
- html += me.htmlCls.setHtmlCls.getRadio('mn6_chemicalbinding', 'mn6_chemicalbindinghide', 'Hide', true);
46601
- html += "</ul>";
46602
- html += "</li>";
47117
+ if(!me.cfg.simplemenu) {
47118
+ html += "<li><span>Chem. Binding</span>";
47119
+ html += "<ul>";
47120
+ html += me.htmlCls.setHtmlCls.getRadio('mn6_chemicalbinding', 'mn6_chemicalbindingshow', 'Show');
47121
+ html += me.htmlCls.setHtmlCls.getRadio('mn6_chemicalbinding', 'mn6_chemicalbindinghide', 'Hide', true);
47122
+ html += "</ul>";
47123
+ html += "</li>";
47124
+ }
46603
47125
 
46604
47126
  html += "<li><span>Disulfide Bonds</span>";
46605
47127
  html += "<ul>";
@@ -46609,21 +47131,24 @@ class SetMenu {
46609
47131
  html += "</ul>";
46610
47132
  html += "</li>";
46611
47133
 
46612
- html += "<li><span>Cross-Linkages</span>";
46613
- html += "<ul>";
46614
- html += me.htmlCls.setHtmlCls.getRadio('mn6_clbonds', 'mn6_clbondsYes', 'Show', true);
46615
- html += me.htmlCls.setHtmlCls.getRadio('mn6_clbonds', 'mn6_clbondsExport', 'Export Pairs');
46616
- html += me.htmlCls.setHtmlCls.getRadio('mn6_clbonds', 'mn6_clbondsNo', 'Hide');
46617
- html += "</ul>";
46618
- html += "</li>";
47134
+ if(!me.cfg.simplemenu) {
47135
+ html += "<li><span>Cross-Linkages</span>";
47136
+ html += "<ul>";
47137
+ html += me.htmlCls.setHtmlCls.getRadio('mn6_clbonds', 'mn6_clbondsYes', 'Show', true);
47138
+ html += me.htmlCls.setHtmlCls.getRadio('mn6_clbonds', 'mn6_clbondsExport', 'Export Pairs');
47139
+ html += me.htmlCls.setHtmlCls.getRadio('mn6_clbonds', 'mn6_clbondsNo', 'Hide');
47140
+ html += "</ul>";
47141
+ html += "</li>";
47142
+ }
46619
47143
 
46620
47144
  let bOnePdb = me.cfg.mmtfid !== undefined || me.cfg.pdbid !== undefined || me.cfg.opmid !== undefined || me.cfg.mmcifid !== undefined || me.cfg.mmdbid !== undefined || me.cfg.gi !== undefined || me.cfg.blast_rep_id !== undefined;
47145
+
46621
47146
  if(bOnePdb) {
46622
47147
  html += "<li id='" + me.pre + "assemblyWrapper'><span>Assembly</span>";
46623
47148
  html += "<ul>";
46624
47149
 
46625
- html += me.htmlCls.setHtmlCls.getRadio('mn6_assembly', 'mn6_assemblyYes', 'Biological Assembly', true);
46626
- html += me.htmlCls.setHtmlCls.getRadio('mn6_assembly', 'mn6_assemblyNo', 'Asymmetric Unit');
47150
+ html += me.htmlCls.setHtmlCls.getRadio('mn6_assembly', 'mn6_assemblyYes', 'Biological Assembly');
47151
+ html += me.htmlCls.setHtmlCls.getRadio('mn6_assembly', 'mn6_assemblyNo', 'Asymmetric Unit', true);
46627
47152
 
46628
47153
  html += "</ul>";
46629
47154
  html += "</li>";
@@ -46633,16 +47158,18 @@ class SetMenu {
46633
47158
  html += "<li><span>Symmetry</span>";
46634
47159
  html += "<ul>";
46635
47160
  if(bOnePdb) html += me.htmlCls.setHtmlCls.getLink('mn6_symmetry', 'from PDB(precalculated) ' + me.htmlCls.wifiStr);
46636
- html += me.htmlCls.setHtmlCls.getLink('mn6_symd', 'from SymD(Dynamic) ' + me.htmlCls.wifiStr);
46637
- html += me.htmlCls.setHtmlCls.getLink('mn6_clear_sym', 'Clear SymD Symmetry');
46638
- html += me.htmlCls.setHtmlCls.getLink('mn6_axes_only', 'Show Axes Only');
47161
+ if(!me.cfg.simplemenu) {
47162
+ html += me.htmlCls.setHtmlCls.getLink('mn6_symd', 'from SymD(Dynamic) ' + me.htmlCls.wifiStr);
47163
+ html += me.htmlCls.setHtmlCls.getLink('mn6_clear_sym', 'Clear SymD Symmetry');
47164
+ html += me.htmlCls.setHtmlCls.getLink('mn6_axes_only', 'Show Axes Only');
47165
+ }
46639
47166
  html += "</ul>";
46640
47167
  html += "</li>";
46641
47168
 
46642
47169
  html += "<li>-</li>";
46643
47170
  }
46644
47171
 
46645
- html += me.htmlCls.setHtmlCls.getLink('mn6_yournote', 'Window Title');
47172
+ if(!me.cfg.simplemenu) html += me.htmlCls.setHtmlCls.getLink('mn6_yournote', 'Window Title');
46646
47173
 
46647
47174
  if(me.cfg.cid !== undefined) {
46648
47175
  html += "<li><span>Links</span>";
@@ -46726,16 +47253,18 @@ class SetMenu {
46726
47253
  html += "</ul>";
46727
47254
  html += "</li>";
46728
47255
 
46729
- html += "<li><span>Develop</span>";
46730
- html += "<ul>";
46731
- html += liStr + me.htmlCls.baseUrl + "icn3d/icn3d.html#HowToUse' target='_blank'>How to Embed</a></li>";
46732
- html += liStr + me.htmlCls.baseUrl + "icn3d/icn3d.html#datastructure' target='_blank'>Data Structure</a></li>";
46733
- html += liStr + me.htmlCls.baseUrl + "icn3d/icn3d.html#classstructure' target='_blank'>Class Structure</a></li>";
46734
- html += liStr + me.htmlCls.baseUrl + "icn3d/icn3d.html#addclass' target='_blank'>Add New Classes</a></li>";
46735
- html += liStr + me.htmlCls.baseUrl + "icn3d/icn3d.html#modifyfunction' target='_blank'>Modify Functions</a></li>";
46736
- html += liStr + me.htmlCls.baseUrl + "icn3d/icn3d.html#restfulapi' target='_blank'>RESTful APIs</a></li>";
46737
- html += "</ul>";
46738
- html += "</li>";
47256
+ if(!me.cfg.simplemenu) {
47257
+ html += "<li><span>Develop</span>";
47258
+ html += "<ul>";
47259
+ html += liStr + me.htmlCls.baseUrl + "icn3d/icn3d.html#HowToUse' target='_blank'>How to Embed</a></li>";
47260
+ html += liStr + me.htmlCls.baseUrl + "icn3d/icn3d.html#datastructure' target='_blank'>Data Structure</a></li>";
47261
+ html += liStr + me.htmlCls.baseUrl + "icn3d/icn3d.html#classstructure' target='_blank'>Class Structure</a></li>";
47262
+ html += liStr + me.htmlCls.baseUrl + "icn3d/icn3d.html#addclass' target='_blank'>Add New Classes</a></li>";
47263
+ html += liStr + me.htmlCls.baseUrl + "icn3d/icn3d.html#modifyfunction' target='_blank'>Modify Functions</a></li>";
47264
+ html += liStr + me.htmlCls.baseUrl + "icn3d/icn3d.html#restfulapi' target='_blank'>RESTful APIs</a></li>";
47265
+ html += "</ul>";
47266
+ html += "</li>";
47267
+ }
46739
47268
 
46740
47269
  html += liStr + me.htmlCls.baseUrl + "icn3d/docs/icn3d_help.html' target='_blank'>Help Doc " + me.htmlCls.wifiStr + "</a></li>";
46741
47270
 
@@ -46745,7 +47274,7 @@ class SetMenu {
46745
47274
  html += "<ul>";
46746
47275
  html += "<li><span>Rotate</span>";
46747
47276
  html += "<ul>";
46748
- html += "<li>Left Mouse</li>";
47277
+ html += "<li>Left Mouse (Click & Drag)</li>";
46749
47278
  html += "<li>Key l: Left</li>";
46750
47279
  html += "<li>Key j: Right</li>";
46751
47280
  html += "<li>Key i: Up</li>";
@@ -46758,20 +47287,20 @@ class SetMenu {
46758
47287
  html += "</li>";
46759
47288
  html += "<li><span>Zoom</span>";
46760
47289
  html += "<ul>";
46761
- html += "<li>Middle Mouse</li>";
47290
+ html += "<li>Middle Mouse <br>(Pinch & Spread)</li>";
46762
47291
  html += "<li>Key z: Zoom in</li>";
46763
47292
  html += "<li>Key x: Zoom out</li>";
46764
47293
  html += "</ul>";
46765
47294
  html += "</li>";
46766
47295
  html += "<li><span>Translate</span>";
46767
47296
  html += "<ul>";
46768
- html += "<li>Right Mouse</li>";
47297
+ html += "<li>Right Mouse <br>(Two Finger Click & Drag)</li>";
46769
47298
  html += "</ul>";
46770
47299
  html += "</li>";
46771
47300
  html += "</ul>";
46772
47301
  html += "</li>";
46773
47302
 
46774
- html += liStr + me.htmlCls.baseUrl + "icn3d/icn3d.html#HowToUseStep5' target='_blank'>Selection Hints</a></li>";
47303
+ if(!me.cfg.simplemenu) html += liStr + me.htmlCls.baseUrl + "icn3d/icn3d.html#HowToUseStep5' target='_blank'>Selection Hints</a></li>";
46775
47304
 
46776
47305
  html += "<li><br/></li>";
46777
47306
  html += "</ul>";
@@ -47372,6 +47901,8 @@ class SetDialog {
47372
47901
 
47373
47902
  let html = "";
47374
47903
 
47904
+ let defaultColor = "#ffff00"; //ic.colorBlackbkgd;
47905
+
47375
47906
  me.htmlCls.optionStr = "<option value=";
47376
47907
 
47377
47908
  html += "<!-- dialog will not be part of the form -->";
@@ -47527,7 +48058,7 @@ class SetDialog {
47527
48058
  html += "<b>Optional 1</b>, full chains are used for structure alignment<br/><br/>";
47528
48059
  html += "<b>Optional 2</b>, sequence alignment (followed by structure alignemnt) based on residue numbers in the First/Master chain: <br>" + me.htmlCls.inputTextStr + "id='" + me.pre + "resalignids' placeholder='1,5,10-50' size=50><br/><br/>";
47529
48060
  html += "<b>Optional 3</b>, predefined alignment with residue numbers in each chain specified (one chain per line): <br><textarea id='" + me.pre + "predefinedres' rows='5' style='width: 100%; height: " +(me.htmlCls.LOG_HEIGHT) + "px; padding: 0px; border: 0px;' placeholder='1,5,10-50\n1,5,10-50\n1,5,10-50'></textarea><br/><br/>";
47530
- html += me.htmlCls.buttonStr + "reload_chainalign'>Align Biological Unit</button>" + me.htmlCls.buttonStr + "reload_chainalign_asym' style='margin-left:30px'>Align Asymmetric Unit</button><br/><br/>";
48061
+ html += me.htmlCls.buttonStr + "reload_chainalign_asym'>Align Asymmetric Unit</button>" + me.htmlCls.buttonStr + "reload_chainalign' style='margin-left:30px'>Align Biological Unit</button><br/><br/>";
47531
48062
  html += "(Note: To align chains in custom PDB files, you could concatenate PDB files in a single PDB file with the separation line \"ENDMDL\". Then load it in \"Open File > PDB File\" in the \"File\" menu and click \"View Sequences & Annotations\" in the \"Window\" menu. Finally select multiple chains in the sequence window and click \"Realign Selection\" in the \"File\" menu.)<br><br>";
47532
48063
  html += "</div></div>";
47533
48064
 
@@ -47576,16 +48107,18 @@ class SetDialog {
47576
48107
  html += "</div>";
47577
48108
 
47578
48109
  html += me.htmlCls.divStr + "dl_mmdbid' class='" + dialogClass + "'>";
47579
- html += "MMDB or PDB ID: " + me.htmlCls.inputTextStr + "id='" + me.pre + "mmdbid' value='1TUP' size=8> ";
47580
- html += me.htmlCls.buttonStr + "reload_mmdb'>Load</button>";
48110
+ html += "MMDB or PDB ID: " + me.htmlCls.inputTextStr + "id='" + me.pre + "mmdbid' value='1TUP' size=8> <br><br>";
48111
+ html += me.htmlCls.buttonStr + "reload_mmdb_asym'>Load Asymmetric Unit (All Chains)</button>" + me.htmlCls.buttonStr + "reload_mmdb' style='margin-left:30px'>Load Biological Unit</button><br/><br/>";
47581
48112
  html += "</div>";
47582
48113
 
47583
48114
  html += me.htmlCls.divStr + "dl_blast_rep_id' style='max-width:500px;' class='" + dialogClass + "'>";
47584
- html += "Enter a Sequence ID(or FASTA sequence) and the aligned Structure ID, which can be found using the <a href='https://blast.ncbi.nlm.nih.gov/Blast.cgi?PROGRAM=blastp&PAGE_TYPE=BlastSearch&DATABASE=pdb' target='_blank'>BLAST</a> search against the pdb database with the Sequence ID or FASTA sequence as input.<br><br> ";
48115
+ html += "Enter a Sequence ID (or FASTA sequence) and the aligned Structure ID, which can be found using the <a href='https://blast.ncbi.nlm.nih.gov/Blast.cgi?PROGRAM=blastp&PAGE_TYPE=BlastSearch&DATABASE=pdb' target='_blank'>BLAST</a> search against the pdb database with the Sequence ID or FASTA sequence as input.<br><br> ";
47585
48116
  html += "<b>Sequence ID</b>(NCBI protein accession of a sequence): " + me.htmlCls.inputTextStr + "id='" + me.pre + "query_id' value='NP_001108451.1' size=8><br> ";
47586
48117
  html += "or FASTA sequence: <br><textarea id='" + me.pre + "query_fasta' rows='5' style='width: 100%; height: " +(me.htmlCls.LOG_HEIGHT) + "px; padding: 0px; border: 0px;'></textarea><br><br>";
47587
48118
  html += "<b>Structure ID</b>(NCBI protein accession of a chain of a 3D structure): " + me.htmlCls.inputTextStr + "id='" + me.pre + "blast_rep_id' value='1TSR_A' size=8><br> ";
47588
- html += me.htmlCls.buttonStr + "reload_blast_rep_id'>Load</button>";
48119
+ //html += me.htmlCls.buttonStr + "reload_blast_rep_id'>Load</button>";
48120
+ html += me.htmlCls.buttonStr + "reload_blast_rep_id'>Align with BLAST</button> " + me.htmlCls.wifiStr
48121
+ + me.htmlCls.buttonStr + "reload_alignsw' style='margin-left:30px'>Align with Smith-Waterman</button>";
47589
48122
  html += "</div>";
47590
48123
 
47591
48124
  html += me.htmlCls.divStr + "dl_yournote' class='" + dialogClass + "'>";
@@ -47966,23 +48499,28 @@ class SetDialog {
47966
48499
  html += me.htmlCls.divStr + "dl_addlabel' class='" + dialogClass + "'>";
47967
48500
  html += "1. Text: " + me.htmlCls.inputTextStr + "id='" + me.pre + "labeltext' value='Text' size=4><br/>";
47968
48501
  html += "2. Size: " + me.htmlCls.inputTextStr + "id='" + me.pre + "labelsize' value='18' size=4 maxlength=2><br/>";
47969
- html += "3. Color: " + me.htmlCls.inputTextStr + "id='" + me.pre + "labelcolor' value='ffff00' size=4><br/>";
47970
- html += "4. Background: " + me.htmlCls.inputTextStr + "id='" + me.pre + "labelbkgd' value='cccccc' size=4><br/>";
48502
+ html += "3. Color: " + me.htmlCls.inputTextStr + "id='" + me.pre + "labelcolor' value='" + defaultColor + "' size=4><br/>";
48503
+ //html += "4. Background: " + me.htmlCls.inputTextStr + "id='" + me.pre + "labelbkgd' value='' size=4><br/>";
47971
48504
  if(me.utilsCls.isMobile()) {
47972
- html += me.htmlCls.spanNowrapStr + "5. Touch TWO atoms</span><br/>";
48505
+ html += me.htmlCls.spanNowrapStr + "4. Touch TWO atoms</span><br/>";
47973
48506
  }
47974
48507
  else {
47975
- html += me.htmlCls.spanNowrapStr + "5. Pick TWO atoms while holding \"Alt\" key</span><br/>";
48508
+ html += me.htmlCls.spanNowrapStr + "4. Pick TWO atoms while holding \"Alt\" key</span><br/>";
47976
48509
  }
47977
- html += me.htmlCls.spanNowrapStr + "6. " + me.htmlCls.buttonStr + "applypick_labels'>Display</button></span>";
48510
+ html += me.htmlCls.spanNowrapStr + "5. " + me.htmlCls.buttonStr + "applypick_labels'>Display</button></span>";
47978
48511
  html += "</div>";
47979
48512
 
47980
48513
  html += me.htmlCls.divStr + "dl_addlabelselection' class='" + dialogClass + "'>";
47981
48514
  html += "1. Text: " + me.htmlCls.inputTextStr + "id='" + me.pre + "labeltext2' value='Text' size=4><br/>";
47982
48515
  html += "2. Size: " + me.htmlCls.inputTextStr + "id='" + me.pre + "labelsize2' value='18' size=4 maxlength=2><br/>";
47983
- html += "3. Color: " + me.htmlCls.inputTextStr + "id='" + me.pre + "labelcolor2' value='ffff00' size=4><br/>";
47984
- html += "4. Background: " + me.htmlCls.inputTextStr + "id='" + me.pre + "labelbkgd2' value='cccccc' size=4><br/>";
47985
- html += me.htmlCls.spanNowrapStr + "5. " + me.htmlCls.buttonStr + "applyselection_labels'>Display</button></span>";
48516
+ html += "3. Color: " + me.htmlCls.inputTextStr + "id='" + me.pre + "labelcolor2' value='" + defaultColor + "' size=4><br/>";
48517
+ //html += "4. Background: " + me.htmlCls.inputTextStr + "id='" + me.pre + "labelbkgd2' value='' size=4><br/>";
48518
+ html += me.htmlCls.spanNowrapStr + "4. " + me.htmlCls.buttonStr + "applyselection_labels'>Display</button></span>";
48519
+ html += "</div>";
48520
+
48521
+ html += me.htmlCls.divStr + "dl_labelColor' class='" + dialogClass + "'>";
48522
+ html += "Color for all labels: " + me.htmlCls.inputTextStr + "id='" + me.pre + "labelcolorall' value='" + defaultColor + "' size=4><br/><br/>";
48523
+ html += me.htmlCls.spanNowrapStr + me.htmlCls.buttonStr + "applylabelcolor'>Display</button></span>";
47986
48524
  html += "</div>";
47987
48525
 
47988
48526
  html += me.htmlCls.divStr + "dl_distance' class='" + dialogClass + "'>";
@@ -47992,7 +48530,7 @@ class SetDialog {
47992
48530
  else {
47993
48531
  html += me.htmlCls.spanNowrapStr + "1. Pick TWO atoms while holding \"Alt\" key</span><br/>";
47994
48532
  }
47995
- html += me.htmlCls.spanNowrapStr + "2. Color: " + me.htmlCls.inputTextStr + "id='" + me.pre + "distancecolor' value='ffff00' size=4><br/>";
48533
+ html += me.htmlCls.spanNowrapStr + "2. Line Color: " + me.htmlCls.inputTextStr + "id='" + me.pre + "distancecolor' value='" + defaultColor + "' size=4><br/>";
47996
48534
  html += me.htmlCls.spanNowrapStr + "3. " + me.htmlCls.buttonStr + "applypick_measuredistance'>Display</button></span>";
47997
48535
  html += "</div>";
47998
48536
 
@@ -48023,7 +48561,7 @@ class SetDialog {
48023
48561
 
48024
48562
  html += "</td></tr></table>";
48025
48563
 
48026
- html += me.htmlCls.spanNowrapStr + "2. Color: " + me.htmlCls.inputTextStr + "id='" + me.pre + "distancecolor2' value='ffff00' size=4><br/><br/>";
48564
+ html += me.htmlCls.spanNowrapStr + "2. Color: " + me.htmlCls.inputTextStr + "id='" + me.pre + "distancecolor2' value='" + defaultColor + "' size=4><br/><br/>";
48027
48565
  html += me.htmlCls.spanNowrapStr + "3. " + me.htmlCls.buttonStr + "applydist2'>Display</button></span>";
48028
48566
  html += "</div>";
48029
48567
 
@@ -48800,20 +49338,24 @@ class Events {
48800
49338
  me.myEventCls.onIds("#" + me.pre + "reload_mmdb", "click", function(e) { me.icn3d;
48801
49339
  e.preventDefault();
48802
49340
  if(!me.cfg.notebook) dialog.dialog( "close" );
48803
- me.htmlCls.clickMenuCls.setLogCmd("load mmdb " + $("#" + me.pre + "mmdbid").val(), false);
48804
- //ic.mmdbParserCls.downloadMmdb($("#" + me.pre + "mmdbid").val());
48805
- //window.open(me.htmlCls.baseUrl + 'icn3d/full.html?mmdbid=' + $("#" + me.pre + "mmdbid").val(), '_blank');
48806
- window.open(hostUrl + '?mmdbid=' + $("#" + me.pre + "mmdbid").val(), '_blank');
49341
+ me.htmlCls.clickMenuCls.setLogCmd("load mmdb1 " + $("#" + me.pre + "mmdbid").val(), false);
49342
+ window.open(hostUrl + '?mmdbid=' + $("#" + me.pre + "mmdbid").val() + '&buidx=1', '_blank');
48807
49343
  });
48808
49344
 
49345
+ me.myEventCls.onIds("#" + me.pre + "reload_mmdb_asym", "click", function(e) { me.icn3d;
49346
+ e.preventDefault();
49347
+ if(!me.cfg.notebook) dialog.dialog( "close" );
49348
+ me.htmlCls.clickMenuCls.setLogCmd("load mmdb0 " + $("#" + me.pre + "mmdbid").val(), false);
49349
+ window.open(hostUrl + '?mmdbid=' + $("#" + me.pre + "mmdbid").val() + '&buidx=0', '_blank');
49350
+ });
49351
+
48809
49352
  me.myEventCls.onIds("#" + me.pre + "mmdbid", "keyup", function(e) { me.icn3d;
48810
49353
  if (e.keyCode === 13) {
48811
49354
  e.preventDefault();
48812
49355
  if(!me.cfg.notebook) dialog.dialog( "close" );
48813
- me.htmlCls.clickMenuCls.setLogCmd("load mmdb " + $("#" + me.pre + "mmdbid").val(), false);
48814
- //window.open(me.htmlCls.baseUrl + 'icn3d/full.html?mmdbid=' + $("#" + me.pre + "mmdbid").val(), '_blank');
48815
- window.open(hostUrl + '?mmdbid=' + $("#" + me.pre + "mmdbid").val(), '_blank');
48816
- }
49356
+ me.htmlCls.clickMenuCls.setLogCmd("load mmdb0 " + $("#" + me.pre + "mmdbid").val(), false);
49357
+ window.open(hostUrl + '?mmdbid=' + $("#" + me.pre + "mmdbid").val() + '&buidx=0', '_blank');
49358
+ }
48817
49359
  });
48818
49360
 
48819
49361
  // },
@@ -48827,12 +49369,27 @@ class Events {
48827
49369
  me.htmlCls.clickMenuCls.setLogCmd("load seq_struct_ids " + query_id + "," + blast_rep_id, false);
48828
49370
  query_id =(query_id !== '' && query_id !== undefined) ? query_id : query_fasta;
48829
49371
  //window.open(me.htmlCls.baseUrl + 'icn3d/full.html?from=icn3d&blast_rep_id=' + blast_rep_id
48830
- window.open(hostUrl + '?from=icn3d&blast_rep_id=' + blast_rep_id
49372
+ window.open(hostUrl + '?from=icn3d&alg=blast&blast_rep_id=' + blast_rep_id
48831
49373
  + '&query_id=' + query_id
48832
49374
  + '&command=view annotations; set annotation cdd; set annotation site; set view detailed view; select chain '
48833
49375
  + blast_rep_id + '; show selection', '_blank');
48834
49376
  });
48835
49377
 
49378
+ me.myEventCls.onIds("#" + me.pre + "reload_alignsw", "click", function(e) { me.icn3d;
49379
+ e.preventDefault();
49380
+ if(!me.cfg.notebook) dialog.dialog( "close" );
49381
+ let query_id = $("#" + me.pre + "query_id").val();
49382
+ let query_fasta = encodeURIComponent($("#" + me.pre + "query_fasta").val());
49383
+ let blast_rep_id = $("#" + me.pre + "blast_rep_id").val();
49384
+ me.htmlCls.clickMenuCls.setLogCmd("load seq_struct_ids_smithwm " + query_id + "," + blast_rep_id, false);
49385
+ query_id =(query_id !== '' && query_id !== undefined) ? query_id : query_fasta;
49386
+
49387
+ window.open(hostUrl + '?from=icn3d&alg=smithwm&blast_rep_id=' + blast_rep_id
49388
+ + '&query_id=' + query_id
49389
+ + '&command=view annotations; set annotation cdd; set annotation site; set view detailed view; select chain '
49390
+ + blast_rep_id + '; show selection', '_blank');
49391
+ });
49392
+
48836
49393
  // },
48837
49394
  // clickReload_gi: function() {
48838
49395
  me.myEventCls.onIds("#" + me.pre + "reload_gi", "click", function(e) { me.icn3d;
@@ -49071,11 +49628,11 @@ class Events {
49071
49628
  thisClass.loadPdbFile(bAppend);
49072
49629
  });
49073
49630
 
49074
- me.myEventCls.onIds("#" + me.pre + "reload_pdbfile_app", "click", function(e) { me.icn3d;
49631
+ me.myEventCls.onIds("#" + me.pre + "reload_pdbfile_app", "click", function(e) { let ic = me.icn3d;
49075
49632
  e.preventDefault();
49076
49633
 
49077
- var bAppend = true;
49078
- thisClass.loadPdbFile(bAppend);
49634
+ ic.bAppend = true;
49635
+ thisClass.loadPdbFile(ic.bAppend);
49079
49636
  });
49080
49637
 
49081
49638
  // },
@@ -49659,6 +50216,15 @@ class Events {
49659
50216
  me.htmlCls.clickMenuCls.setLogCmd('add label ' + text + ' | x ' + x.toPrecision(4) + ' y ' + y.toPrecision(4) + ' z ' + z.toPrecision(4) + sizeStr + colorStr + backgroundStr + ' | type custom', true);
49660
50217
  ic.drawCls.draw();
49661
50218
  });
50219
+
50220
+ me.myEventCls.onIds("#" + me.pre + "applylabelcolor", "click", function(e) { let ic = me.icn3d;
50221
+ e.preventDefault();
50222
+ if(!me.cfg.notebook) dialog.dialog( "close" );
50223
+ ic.labelcolor = $("#" + me.pre + "labelcolorall" ).val();
50224
+
50225
+ me.htmlCls.clickMenuCls.setLogCmd('set label color ' + ic.labelcolor, true);
50226
+ ic.drawCls.draw();
50227
+ });
49662
50228
  // },
49663
50229
  // clickApplypick_stabilizer: function() {
49664
50230
  me.myEventCls.onIds("#" + me.pre + "applypick_stabilizer", "click", function(e) { let ic = me.icn3d;
@@ -50518,6 +51084,7 @@ class SetHtml {
50518
51084
  let light2 = 0.4;
50519
51085
  let light3 = 0.2;
50520
51086
  let bGlycansCartoon = 0;
51087
+ let bMembrane = 1;
50521
51088
 
50522
51089
  // retrieve from cache
50523
51090
  if(type == 'style') {
@@ -50546,6 +51113,10 @@ class SetHtml {
50546
51113
  bGlycansCartoon = parseFloat(this.getCookie('glycan'));
50547
51114
  }
50548
51115
 
51116
+ if(this.getCookie('membrane') != '') {
51117
+ bMembrane = parseFloat(this.getCookie('membrane'));
51118
+ }
51119
+
50549
51120
  html += "<b>Note</b>: The following parameters will be saved in cache. You just need to set them once. <br><br>";
50550
51121
 
50551
51122
  html += "<b>1. Shininess</b>: " + me.htmlCls.inputTextStr + "id='" + me.pre + "shininess' value='" + shininess + "' size=4>" + me.htmlCls.space3 + "(for the shininess of the 3D objects, default 40)<br/><br/>";
@@ -50568,7 +51139,9 @@ class SetHtml {
50568
51139
  html += "<b>Ball Scale</b>: " + me.htmlCls.inputTextStr + "id='" + me.pre + "ballscale_" + type + "' value='" + ballscale + "' size=4>" + me.htmlCls.space3 + "(for styles 'Ball and Stick' and 'Dot', default 0.3)<br/>";
50569
51140
 
50570
51141
  if(type == 'style') {
50571
- html += "<br><b>4. Show Glycan Cartoon</b>: " + me.htmlCls.inputTextStr + "id='" + me.pre + "glycan' value='" + bGlycansCartoon + "' size=4>" + me.htmlCls.space3 + "(0: hide, 1: show, default 0)<br/><br/>";
51142
+ html += "<br><b>4. Show Glycan Cartoon</b>: " + me.htmlCls.inputTextStr + "id='" + me.pre + "glycan' value='" + bGlycansCartoon + "' size=4>" + me.htmlCls.space3 + "(0: hide, 1: show, default 0)<br/>";
51143
+
51144
+ html += "<br><b>5. Show Membrane</b>: " + me.htmlCls.inputTextStr + "id='" + me.pre + "membrane' value='" + bMembrane + "' size=4>" + me.htmlCls.space3 + "(0: hide, 1: show, default 1)<br/><br/>";
50572
51145
  }
50573
51146
 
50574
51147
  html += me.htmlCls.spanNowrapStr + "" + me.htmlCls.buttonStr + "apply_thickness_" + type + "'>Apply</button></span>&nbsp;&nbsp;&nbsp;";
@@ -50761,8 +51334,8 @@ class SetHtml {
50761
51334
 
50762
51335
  html += "<span style='white-space:nowrap;font-weight:bold;'>Potential contour at: <select id='" + me.pre + name1 + "contour'>";
50763
51336
 
50764
- let optArray1b = ['0.5', '1', '2', '4', '6', '8', '10'];
50765
- html += this.getOptionHtml(optArray1b, 1);
51337
+ let optArray1b = ['0.5', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10'];
51338
+ html += this.getOptionHtml(optArray1b, 2);
50766
51339
 
50767
51340
  html += "</select> kT/e(25.6mV at 298K)</span><br/><br/>";
50768
51341
 
@@ -50826,7 +51399,7 @@ class SetHtml {
50826
51399
 
50827
51400
  html += "<span style='white-space:nowrap;font-weight:bold;'>Surface with max potential at: <select id='" + me.pre + name1 + "contour2'>";
50828
51401
 
50829
- let optArray1c = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10'];
51402
+ let optArray1c = ['0.5', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10'];
50830
51403
  html += this.getOptionHtml(optArray1c, 2);
50831
51404
 
50832
51405
  html += "</select> kT/e(25.6mV at 298K)</span><br/><br/>";
@@ -51039,7 +51612,7 @@ class SetHtml {
51039
51612
  });
51040
51613
  }
51041
51614
 
51042
- loadPng(imageStr) { let me = this.icn3dui, ic = me.icn3d;
51615
+ loadPng(imageStr, command) { let me = this.icn3dui, ic = me.icn3d;
51043
51616
  let matchedStr = 'Share Link: ';
51044
51617
  let pos = imageStr.indexOf(matchedStr);
51045
51618
  let matchedStrState = "Start of state file======\n";
@@ -51056,6 +51629,8 @@ class SetHtml {
51056
51629
  let matchedStrData = "Start of data file======\n";
51057
51630
  let posData = imageStr.indexOf(matchedStrData);
51058
51631
  ic.bInputfile =(posData == -1) ? false : true;
51632
+ let commandStr = (command) ? command.replace(/;/g, "\n") : '';
51633
+
51059
51634
  if(ic.bInputfile) {
51060
51635
  let posDataEnd = imageStr.indexOf("End of data file======\n");
51061
51636
  let data = imageStr.substr(posData + matchedStrData.length, posDataEnd - posData - matchedStrData.length);
@@ -51071,7 +51646,9 @@ class SetHtml {
51071
51646
  //var posState = imageStr.indexOf(matchedStrState);
51072
51647
  let posStateEnd = imageStr.indexOf("End of state file======\n");
51073
51648
  let statefile = imageStr.substr(posState + matchedStrState.length, posStateEnd - posState- matchedStrState.length);
51074
- statefile = decodeURIComponent(statefile);
51649
+ //statefile = decodeURIComponent(statefile);
51650
+ statefile = decodeURIComponent(statefile + "\n" + commandStr);
51651
+
51075
51652
  if(type === 'pdb') {
51076
51653
  $.when( ic.pdbParserCls.loadPdbData(data))
51077
51654
  .then(function() {
@@ -51103,7 +51680,9 @@ class SetHtml {
51103
51680
  //var posState = imageStr.indexOf(matchedStrState);
51104
51681
  let posStateEnd = imageStr.indexOf("End of state file======\n");
51105
51682
  let statefile = imageStr.substr(posState + matchedStrState.length, posStateEnd - posState- matchedStrState.length);
51106
- statefile = decodeURIComponent(statefile);
51683
+ //statefile = decodeURIComponent(statefile);
51684
+ statefile = decodeURIComponent(statefile + "\n" + commandStr);
51685
+
51107
51686
  ic.commands = [];
51108
51687
  ic.optsHistory = [];
51109
51688
  ic.loadScriptCls.loadScript(statefile, true);
@@ -51166,6 +51745,7 @@ class SetHtml {
51166
51745
  $("#" + me.pre + "light2").val('0.4');
51167
51746
  $("#" + me.pre + "light3").val('0.2');
51168
51747
  $("#" + me.pre + "glycan").val('0');
51748
+ $("#" + me.pre + "membrane").val('1');
51169
51749
  }
51170
51750
 
51171
51751
  ic.shininess = parseFloat($("#" + me.pre + "shininess").val()); //40;
@@ -51173,6 +51753,7 @@ class SetHtml {
51173
51753
  ic.light2 = parseFloat($("#" + me.pre + "light2").val()); //0.4;
51174
51754
  ic.light3 = parseFloat($("#" + me.pre + "light3").val()); //0.2;
51175
51755
  ic.bGlycansCartoon = parseInt($("#" + me.pre + "glycan").val()); //0;
51756
+ ic.bMembrane = parseInt($("#" + me.pre + "membrane").val()); //1;
51176
51757
  }
51177
51758
 
51178
51759
  if(bReset) {
@@ -51203,6 +51784,7 @@ class SetHtml {
51203
51784
  this.setCookie('light2', ic.light2, exdays);
51204
51785
  this.setCookie('light3', ic.light3, exdays);
51205
51786
  this.setCookie('glycan', ic.bGlycansCartoon, exdays);
51787
+ this.setCookie('membrane', ic.bMembrane, exdays);
51206
51788
  }
51207
51789
 
51208
51790
  this.setCookieForThickness();
@@ -51215,6 +51797,9 @@ class SetHtml {
51215
51797
  }
51216
51798
  else {
51217
51799
  me.htmlCls.clickMenuCls.setLogCmd('set thickness | linerad ' + ic.lineRadius + ' | coilrad ' + ic.coilWidth + ' | stickrad ' + ic.cylinderRadius + ' | tracerad ' + ic.traceRadius + ' | ribbonthick ' + ic.ribbonthickness + ' | proteinwidth ' + ic.helixSheetWidth + ' | nucleotidewidth ' + ic.nucleicAcidWidth + ' | ballscale ' + ic.dotSphereScale, true);
51800
+
51801
+ me.htmlCls.clickMenuCls.setLogCmd('set glycan ' + ic.bGlycansCartoon, true);
51802
+ me.htmlCls.clickMenuCls.setLogCmd('set membrane ' + ic.bMembrane, true);
51218
51803
  }
51219
51804
 
51220
51805
  ic.drawCls.draw();
@@ -51264,7 +51849,7 @@ class Html {
51264
51849
  this.cfg = this.icn3dui.cfg;
51265
51850
 
51266
51851
  this.opts = {};
51267
- this.opts['background'] = 'transparent'; //transparent, black, grey, white
51852
+ this.opts['background'] = 'black'; //transparent, black, grey, white
51268
51853
 
51269
51854
  this.WIDTH = 400; // total width of view area
51270
51855
  this.HEIGHT = 400; // total height of view area
@@ -53020,6 +53605,398 @@ class DensityCifParser {
53020
53605
  }
53021
53606
  }
53022
53607
 
53608
+ /**
53609
+ * @author Jack Lin, modified from https://github.com/lh3/bioseq-js/blob/master/bioseq.js
53610
+ */
53611
+
53612
+ //import { HashUtilsCls } from '../../utils/hashUtilsCls.js';
53613
+
53614
+ //import { Html } from '../../html/html.js';
53615
+
53616
+ //import { SaveFile } from '../export/saveFile.js';
53617
+ //import { PdbParser } from '../parsers/pdbParser.js';
53618
+
53619
+ class AlignSW {
53620
+ constructor(icn3d) {
53621
+ this.icn3d = icn3d;
53622
+ }
53623
+
53624
+ alignSW(target, query, match_score, mismatch, gap, extension, is_local = false) { let ic = this.icn3d; ic.icn3dui;
53625
+ //let time_start = new Date().getTime();
53626
+
53627
+ let rst = this.bsa_align(is_local, target, query, [match_score, mismatch], [gap, extension]);
53628
+ let str = 'score: ' + rst[0] + '\n';
53629
+ str += 'start: ' + rst[1] + '\n';
53630
+ str += 'cigar: ' + this.bsa_cigar2str(rst[2]) + '\n\n';
53631
+ str += 'alignment:\n\n';
53632
+ let fmt = this.bsa_cigar2gaps(target, query, rst[1], rst[2]);
53633
+
53634
+ /*
53635
+ //let anno_seq = document.getElementById("div0_dl_annotations")
53636
+ let algn = "<div id=waterman_alignment><span>" + 'score: ' + rst[0] + '<br>' + 'start: ' + rst[1] + '<br>' + 'cigar: ' + this.bsa_cigar2str(rst[2]) + '<br><br>' + 'alignment:' + '<br>'
53637
+
53638
+ let linelen = 100,
53639
+ n_lines = 10;
53640
+ for (let l = 0; l < fmt[0].length; l += linelen) {
53641
+ str += fmt[0].substr(l, linelen) + '\n';
53642
+ str += fmt[2].substr(l, linelen) + '\n';
53643
+ str += fmt[1].substr(l, linelen) + '\n\n';
53644
+ n_lines += 4;
53645
+ }
53646
+
53647
+ algn += '<pre>'
53648
+ algn += fmt[0] + '<br>';
53649
+ algn += fmt[2] + '<br>';
53650
+ algn += fmt[1] + '<br><br>';
53651
+ algn += '</pre><br>' + "</span></div>"
53652
+
53653
+ //anno_seq.innerHTML += algn
53654
+
53655
+ //let elapse = (new Date().getTime() - time_start) / 1000.0;
53656
+ //console.log("in " + elapse.toFixed(3) + "s");
53657
+ */
53658
+ let algn = {};
53659
+ algn.score = rst[0];
53660
+ algn.start = rst[1];
53661
+ algn.cigar = this.bsa_cigar2str(rst[2]);
53662
+ algn.target = fmt[0];
53663
+ algn.query = fmt[1];
53664
+
53665
+ return algn;
53666
+ }
53667
+
53668
+ /**
53669
+ * Encode a sequence string with table
53670
+ *
53671
+ * @param seq sequence
53672
+ * @param table encoding table; must be of size 256
53673
+ *
53674
+ * @return an integer array
53675
+ */
53676
+
53677
+ bsg_enc_seq(seq, table) { let ic = this.icn3d; ic.icn3dui;
53678
+ if (table == null) return null;
53679
+ let s = [];
53680
+ s.length = seq.length;
53681
+ for (let i = 0; i < seq.length; ++i)
53682
+ s[i] = table[seq.charCodeAt(i)];
53683
+ return s;
53684
+ }
53685
+
53686
+ /*
53687
+ ks_revcomp(s) { let ic = this.icn3d, me = ic.icn3dui;
53688
+ let ks_comp = {'A':'T','C':'G','G':'C','T':'A','M':'K','K':'M','Y':'R','R':'Y','V':'B','B':'V','H':'D','D':'H',
53689
+ 'a':'t','c':'g','g':'c','t':'a','m':'k','k':'m','y':'r','r':'y','v':'b','b':'v','h':'d','d':'h'};
53690
+
53691
+ let i, t = '';
53692
+ for (i = 0; i < s.length; ++i) {
53693
+ let c = s.charAt(s.length - 1 - i);
53694
+ let d = ks_comp[c];
53695
+ t += d? d : c;
53696
+ }
53697
+ return t;
53698
+ }
53699
+ */
53700
+
53701
+ /**************************
53702
+ *** Pairwise alignment ***
53703
+ **************************/
53704
+
53705
+ /*
53706
+ * The following implements local and global pairwise alignment with affine gap
53707
+ * penalties. There are two formulations: the Durbin formulation as is
53708
+ * described in his book and the Green formulation as is implemented in phrap.
53709
+ * The Durbin formulation is easier to understand, while the Green formulation
53710
+ * is simpler to code and probably faster in practice.
53711
+ *
53712
+ * The Durbin formulation is:
53713
+ *
53714
+ * M(i,j) = max{M(i-1,j-1)+S(i,j), E(i-1,j-1), F(i-1,j-1)}
53715
+ * E(i,j) = max{M(i-1,j)-q-r, F(i-1,j)-q-r, E(i-1,j)-r}
53716
+ * F(i,j) = max{M(i,j-1)-q-r, F(i,j-1)-r, E(i,j-1)-q-r}
53717
+ *
53718
+ * where q is the gap open penalty, r the gap extension penalty and S(i,j) is
53719
+ * the score between the i-th residue in the row sequence and the j-th residue
53720
+ * in the column sequence. Note that the original Durbin formulation disallows
53721
+ * transitions between between E and F states, but we allow them here.
53722
+ *
53723
+ * In the Green formulation, we introduce:
53724
+ *
53725
+ * H(i,j) = max{M(i,j), E(i,j), F(i,j)}
53726
+ *
53727
+ * The recursion becomes:
53728
+ *
53729
+ * H(i,j) = max{H(i-1,j-1)+S(i,j), E(i,j), F(i,j)}
53730
+ * E(i,j) = max{H(i-1,j)-q, E(i-1,j)} - r
53731
+ * F(i,j) = max{H(i,j-1)-q, F(i,j-1)} - r
53732
+ *
53733
+ * It is in fact equivalent to the Durbin formulation. In implementation, we
53734
+ * calculate the scores in a different order:
53735
+ *
53736
+ * H(i,j) = max{H(i-1,j-1)+S(i,j), E(i,j), F(i,j)}
53737
+ * E(i+1,j) = max{H(i,j)-q, E(i,j)} - r
53738
+ * F(i,j+1) = max{H(i,j)-q, F(i,j)} - r
53739
+ *
53740
+ * i.e. at cell (i,j), we compute E for the next row and F for the next column.
53741
+ * Please see inline comments below for details.
53742
+ *
53743
+ *
53744
+ * The following implementation is ported from klib/ksw.c. The original C
53745
+ * implementation has a few bugs which have been fixed here. Like the C
53746
+ * version, this implementation should be very efficient. It could be made more
53747
+ * efficient if we use typed integer arrays such as Uint8Array. In addition,
53748
+ * I mixed the local and global alignments together. For performance,
53749
+ * it would be preferred to separate them out.
53750
+ */
53751
+
53752
+ /**
53753
+ * Generate scoring matrix from match/mismatch score
53754
+ *
53755
+ * @param n size of the alphabet
53756
+ * @param a match score, positive
53757
+ * @param b mismatch score, negative
53758
+ *
53759
+ * @return sqaure scoring matrix. The last row and column are zero, for
53760
+ * matching an ambiguous residue.
53761
+ */
53762
+ bsa_gen_score_matrix(n, a, b) { let ic = this.icn3d; ic.icn3dui;
53763
+ let m = [];
53764
+ if (b > 0) b = -b; // mismatch score b should be non-positive
53765
+ let i, j;
53766
+ for (i = 0; i < n - 1; ++i) {
53767
+ m[i] = [];
53768
+ for (j = 0; j < n - 1; ++j)
53769
+ m[i][j] = i == j ? a : b;
53770
+ m[i][j] = 0;
53771
+ }
53772
+ m[n - 1] = [];
53773
+ for (let j = 0; j < n; ++j) m[n - 1][j] = 0;
53774
+ return m;
53775
+ }
53776
+
53777
+ /**
53778
+ * Generate query profile (a preprocessing step)
53779
+ *
53780
+ * @param _s sequence in string or post bsg_enc_seq()
53781
+ * @param _m score matrix or [match,mismatch] array
53782
+ * @param table encoding table; must be consistent with _s and _m
53783
+ *
53784
+ * @return query profile. It is a two-dimensional integer matrix.
53785
+ */
53786
+ bsa_gen_query_profile(_s, _m, table) { let ic = this.icn3d; ic.icn3dui;
53787
+ let s = typeof _s == 'string' ? this.bsg_enc_seq(_s, table) : _s;
53788
+ let qp = [],
53789
+ matrix;
53790
+ if (_m.length >= 2 && typeof _m[0] == 'number' && typeof _m[1] == 'number') { // match/mismatch score
53791
+ if (table == null) return null;
53792
+ let n = typeof table == 'number' ? table : table[table.length - 1] + 1;
53793
+ matrix = this.bsa_gen_score_matrix(n, _m[0], _m[1]);
53794
+ } else matrix = _m; // _m is already a matrix; FIXME: check if it is really a square matrix!
53795
+ for (let j = 0; j < matrix.length; ++j) {
53796
+ let qpj, mj = matrix[j];
53797
+ qpj = qp[j] = [];
53798
+ for (let i = 0; i < s.length; ++i)
53799
+ qpj[i] = mj[s[i]];
53800
+ }
53801
+ return qp;
53802
+ }
53803
+
53804
+ /**
53805
+ * Local or global pairwise alignemnt
53806
+ *
53807
+ * @param is_local perform local alignment
53808
+ * @param target target string
53809
+ * @param query query string or query profile
53810
+ * @param matrix square score matrix or [match,mismatch] array
53811
+ * @param gapsc [gap_open,gap_ext] array; k-length gap costs gap_open+gap_ext*k
53812
+ * @param w bandwidth, disabled by default
53813
+ * @param table encoding table. It defaults to bst_nt5.
53814
+ *
53815
+ * @return [score,target_start,cigar]. cigar is encoded in the BAM way, where
53816
+ * higher 28 bits keeps the length and lower 4 bits the operation in order of
53817
+ * "MIDNSH". See bsa_cigar2str() for converting cigar to string.
53818
+ */
53819
+ bsa_align(is_local, target, query, matrix, gapsc, w, table) { let ic = this.icn3d; ic.icn3dui;
53820
+ let bst_nt5 = [
53821
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
53822
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
53823
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
53824
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
53825
+ 4, 0, 4, 1, 4, 4, 4, 2, 4, 4, 4, 4, 4, 4, 4, 4,
53826
+ 4, 4, 4, 4, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
53827
+ 4, 0, 4, 1, 4, 4, 4, 2, 4, 4, 4, 4, 4, 4, 4, 4,
53828
+ 4, 4, 4, 4, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
53829
+
53830
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
53831
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
53832
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
53833
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
53834
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
53835
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
53836
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
53837
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4
53838
+ ];
53839
+
53840
+ // convert bases to integers
53841
+ if (table == null) table = bst_nt5;
53842
+ let t = this.bsg_enc_seq(target, table);
53843
+ let qp = this.bsa_gen_query_profile(query, matrix, table);
53844
+ let qlen = qp[0].length;
53845
+
53846
+ // adjust band width
53847
+ let max_len = qlen > t.length ? qlen : t.length;
53848
+ w = w == null || w < 0 ? max_len : w;
53849
+ let len_diff = t.target > qlen ? t.target - qlen : qlen - t.target;
53850
+ w = w > len_diff ? w : len_diff;
53851
+
53852
+ // set gap score
53853
+ let gapo, gape; // these are penalties which should be non-negative
53854
+ if (typeof gapsc == 'number') gapo = 0, gape = gapsc > 0 ? gapsc : -gapsc;
53855
+ else gapo = gapsc[0] > 0 ? gapsc[0] : -gapsc[0], gape = gapsc[1] > 0 ? gapsc[1] : -gapsc[1];
53856
+ let gapoe = gapo + gape; // penalty for opening the first gap
53857
+
53858
+ // initial values
53859
+ let NEG_INF = -0x40000000;
53860
+ let H = [],
53861
+ E = [],
53862
+ z = [],
53863
+ score, max = 0,
53864
+ end_i = -1,
53865
+ end_j = -1;
53866
+ if (is_local) {
53867
+ for (let j = 0; j <= qlen; ++j) H[j] = E[j] = 0;
53868
+ } else {
53869
+ H[0] = 0;
53870
+ E[0] = -gapoe - gapoe;
53871
+ for (let j = 1; j <= qlen; ++j) {
53872
+ if (j >= w) H[j] = E[j] = NEG_INF; // everything is -inf outside the band
53873
+ else H[j] = -(gapoe + gape * (j - 1)), E[j] = -(gapoe + gapoe + gape * j);
53874
+ }
53875
+ }
53876
+
53877
+ // the DP loop
53878
+ for (let i = 0; i < t.length; ++i) {
53879
+ let h1 = 0,
53880
+ f = 0,
53881
+ m = 0,
53882
+ mj = -1;
53883
+ let zi, qpi = qp[t[i]];
53884
+ zi = z[i] = [];
53885
+ let beg = i > w ? i - w : 0;
53886
+ let end = i + w + 1 < qlen ? i + w + 1 : qlen; // only loop through [beg,end) of the query sequence
53887
+ if (!is_local) {
53888
+ h1 = beg > 0 ? NEG_INF : -(gapoe + gape * i);
53889
+ f = beg > 0 ? NEG_INF : -(gapoe + gapoe + gape * i);
53890
+ }
53891
+ for (let j = beg; j < end; ++j) {
53892
+ // At the beginning of the loop: h=H[j]=H(i-1,j-1), e=E[j]=E(i,j), f=F(i,j) and h1=H(i,j-1)
53893
+ // If we only want to compute the max score, delete all lines involving direction "d".
53894
+ let e = E[j],
53895
+ h = H[j],
53896
+ d;
53897
+ H[j] = h1; // set H(i,j-1) for the next row
53898
+ h += qpi[j]; // h = H(i-1,j-1) + S(i,j)
53899
+ d = h >= e ? 0 : 1;
53900
+ h = h >= e ? h : e;
53901
+ d = h >= f ? d : 2;
53902
+ h = h >= f ? h : f; // h = H(i,j) = max{H(i-1,j-1)+S(i,j), E(i,j), F(i,j)}
53903
+ d = !is_local || h > 0 ? d : 1 << 6;
53904
+ h1 = h; // save H(i,j) to h1 for the next column
53905
+ mj = m > h ? mj : j;
53906
+ m = m > h ? m : h; // update the max score in this row
53907
+ h -= gapoe;
53908
+ h = !is_local || h > 0 ? h : 0;
53909
+ e -= gape;
53910
+ d |= e > h ? 1 << 2 : 0;
53911
+ e = e > h ? e : h; // e = E(i+1,j)
53912
+ E[j] = e; // save E(i+1,j) for the next row
53913
+ f -= gape;
53914
+ d |= f > h ? 2 << 4 : 0;
53915
+ f = f > h ? f : h; // f = F(i,j+1)
53916
+ zi[j] = d; // z[i,j] keeps h for the current cell and e/f for the next cell
53917
+ }
53918
+ H[end] = h1, E[end] = is_local ? 0 : NEG_INF;
53919
+ if (m > max) max = m, end_i = i, end_j = mj;
53920
+ }
53921
+ if (is_local && max == 0) return null;
53922
+ score = is_local ? max : H[qlen];
53923
+
53924
+ let cigar = [],
53925
+ tmp, which = 0,
53926
+ i, k, start_i = 0;
53927
+ if (is_local) {
53928
+ i = end_i, k = end_j;
53929
+ if (end_j != qlen - 1) // then add soft cliping
53930
+ this.push_cigar(cigar, 4, qlen - 1 - end_j);
53931
+ } else i = t.length - 1, k = (i + w + 1 < qlen ? i + w + 1 : qlen) - 1; // (i,k) points to the last cell
53932
+ while (i >= 0 && k >= 0) {
53933
+ tmp = z[i][k - (i > w ? i - w : 0)];
53934
+ which = tmp >> (which << 1) & 3;
53935
+ if (which == 0 && tmp >> 6) break;
53936
+ if (which == 0) which = tmp & 3;
53937
+ if (which == 0) { this.push_cigar(cigar, 0, 1);--i, --k; } // match
53938
+ else if (which == 1) { this.push_cigar(cigar, 2, 1);--i; } // deletion
53939
+ else { this.push_cigar(cigar, 1, 1), --k; } // insertion
53940
+ }
53941
+ if (is_local) {
53942
+ if (k >= 0) this.push_cigar(cigar, 4, k + 1); // add soft clipping
53943
+ start_i = i + 1;
53944
+ } else { // add the first insertion or deletion
53945
+ if (i >= 0) this.push_cigar(cigar, 2, i + 1);
53946
+ if (k >= 0) this.push_cigar(cigar, 1, k + 1);
53947
+ }
53948
+ for (let i = 0; i < cigar.length >> 1; ++i) // reverse CIGAR
53949
+ tmp = cigar[i], cigar[i] = cigar[cigar.length - 1 - i], cigar[cigar.length - 1 - i] = tmp;
53950
+ return [score, start_i, cigar];
53951
+ }
53952
+
53953
+ // backtrack to recover the alignment/cigar
53954
+ push_cigar(ci, op, len) { let ic = this.icn3d; ic.icn3dui;
53955
+ if (ci.length == 0 || op != (ci[ci.length - 1] & 0xf))
53956
+ ci.push(len << 4 | op);
53957
+ else ci[ci.length - 1] += len << 4;
53958
+ }
53959
+
53960
+ bsa_cigar2gaps(target, query, start, cigar) { let ic = this.icn3d; ic.icn3dui;
53961
+ let oq = '',
53962
+ ot = '',
53963
+ mid = '',
53964
+ lq = 0,
53965
+ lt = start;
53966
+ for (let k = 0; k < cigar.length; ++k) {
53967
+ let op = cigar[k] & 0xf,
53968
+ len = cigar[k] >> 4;
53969
+ if (op == 0) { // match
53970
+ oq += query.substr(lq, len);
53971
+ ot += target.substr(lt, len);
53972
+ lq += len, lt += len;
53973
+ } else if (op == 1) { // insertion
53974
+ oq += query.substr(lq, len);
53975
+ ot += Array(len + 1).join("-");
53976
+ lq += len;
53977
+ } else if (op == 2) { // deletion
53978
+ oq += Array(len + 1).join("-");
53979
+ ot += target.substr(lt, len);
53980
+ lt += len;
53981
+ } else if (op == 4) { // soft clip
53982
+ lq += len;
53983
+ }
53984
+ }
53985
+ let ut = ot.toUpperCase();
53986
+ let uq = oq.toUpperCase();
53987
+ for (let k = 0; k < ut.length; ++k)
53988
+ mid += ut.charAt(k) == uq.charAt(k) ? '|' : ' ';
53989
+ return [ot, oq, mid];
53990
+ }
53991
+
53992
+ bsa_cigar2str(cigar) { let ic = this.icn3d; ic.icn3dui;
53993
+ let s = [];
53994
+ for (let k = 0; k < cigar.length; ++k)
53995
+ s.push((cigar[k] >> 4).toString() + "MIDNSHP=XB".charAt(cigar[k] & 0xf));
53996
+ return s.join("");
53997
+ }
53998
+ }
53999
+
53023
54000
  /**
53024
54001
  * @author Jiyao Wang <wangjiy@ncbi.nlm.nih.gov> / https://github.com/ncbi/icn3d
53025
54002
  */
@@ -53115,7 +54092,7 @@ class Ray {
53115
54092
  // the intersections are sorted so that the closest point is the first one.
53116
54093
  intersects[ 0 ].point.sub(position); // mdl.position was moved to the original (0,0,0) after reading the molecule coordinates. The raycasting was done based on the original. The position of the original should be substracted.
53117
54094
 
53118
- let threshold = 0.5;
54095
+ let threshold = ic.rayThreshold; //0.5;
53119
54096
  let atom = this.getAtomsFromPosition(intersects[ 0 ].point, threshold); // the second parameter is the distance threshold. The first matched atom will be returned. Use 1 angstrom, not 2 angstrom. If it's 2 angstrom, other atom will be returned.
53120
54097
 
53121
54098
  while(!atom && threshold < 10) {
@@ -53644,6 +54621,9 @@ class iCn3D {
53644
54621
  this.bImpo = true;
53645
54622
  this.bInstanced = true;
53646
54623
 
54624
+ this.chainMissingResidueArray = {};
54625
+ this._zoomFactor = 1.0;
54626
+
53647
54627
  if(!this.icn3dui.bNode) {
53648
54628
  this.bExtFragDepth = this.renderer.extensions.get( "EXT_frag_depth" );
53649
54629
  if(!this.bExtFragDepth) {
@@ -53703,7 +54683,7 @@ class iCn3D {
53703
54683
  this.bCalphaOnly = false; // by default the input has both Calpha and O, used for drawing strands. If atoms have Calpha only, the orientation of the strands is random
53704
54684
  // this.bSSOnly = false; // a flag to turn on when only helix and bricks are available to draw 3D dgm
53705
54685
 
53706
- this.bAllAtoms = true; // no need to adjust atom for strand style
54686
+ // this.bAllAtoms = true; // no need to adjust atom for strand style
53707
54687
 
53708
54688
  this.bConsiderNeighbors = false; // a flag to show surface considering the neighboring atoms or not
53709
54689
 
@@ -53764,10 +54744,14 @@ class iCn3D {
53764
54744
 
53765
54745
  this.LABELSIZE = 30;
53766
54746
 
54747
+ this.rayThreshold = 0.5; // threadshold for raycast
54748
+ this.colorBlackbkgd = '#ffff00';
54749
+ this.colorWhitebkgd = '#000000';
54750
+
53767
54751
  //The default display options
53768
54752
  this.optsOri = {};
53769
54753
  this.optsOri['camera'] = 'perspective'; //perspective, orthographic
53770
- this.optsOri['background'] = 'transparent'; //transparent, black, grey, white
54754
+ this.optsOri['background'] = 'black'; //transparent, black, grey, white
53771
54755
  this.optsOri['color'] = 'chain'; //spectrum, secondary structure, charge, hydrophobic, conserved, chain, residue, atom, b factor, red, green, blue, magenta, yellow, cyan, white, grey, custom
53772
54756
  this.optsOri['proteins'] = 'ribbon'; //ribbon, strand, cylinder and plate, schematic, c alpha trace, backbone, b factor tube, lines, stick, ball and stick, sphere, nothing
53773
54757
  this.optsOri['sidec'] = 'nothing'; //lines, stick, ball and stick, sphere, nothing
@@ -53959,6 +54943,7 @@ class iCn3D {
53959
54943
  this.dsspCls = new Dssp(this);
53960
54944
  this.scapCls = new Scap(this);
53961
54945
  this.symdCls = new Symd(this);
54946
+ this.alignSWCls = new AlignSW(this);
53962
54947
 
53963
54948
  this.analysisCls = new Analysis(this);
53964
54949
  this.resizeCanvasCls = new ResizeCanvas(this);
@@ -54015,6 +55000,8 @@ iCn3D.prototype.init_base = function (bKeepCmd) {
54015
55000
  this.chainsAn = {}; // structure_chain name -> array of annotations, such as residue number
54016
55001
  this.chainsAnTitle = {}; // structure_chain name -> array of annotation title
54017
55002
 
55003
+ this.chainsMapping = {}; // structure_chain name -> residue id hash such as {'structure_chain_resi1': 'reference residue such as K10', ...}
55004
+
54018
55005
  this.alnChainsSeq = {}; // structure_chain name -> array of residue object: {mmdbid, chain, resi, resn, aligned}
54019
55006
  this.alnChainsAnno = {}; // structure_chain name -> array of annotations, such as residue number
54020
55007
  this.alnChainsAnTtl = {}; // structure_chain name -> array of annotation title
@@ -54091,9 +55078,13 @@ iCn3D.prototype.init_base = function (bKeepCmd) {
54091
55078
 
54092
55079
  this.axes = [];
54093
55080
 
54094
- this.bGlycansCartoon = false;
55081
+ this.bGlycansCartoon = 0;
55082
+ this.bMembrane = 1;
54095
55083
 
54096
55084
  this.chainid2offset = {};
55085
+
55086
+ this.chainMissingResidueArray = {};
55087
+ this.nTotalGap = 0;
54097
55088
  };
54098
55089
 
54099
55090
  //Reset parameters for displaying the loaded structure.
@@ -54160,7 +55151,7 @@ class iCn3DUI {
54160
55151
  //even when multiple iCn3D viewers are shown together.
54161
55152
  this.pre = this.cfg.divid + "_";
54162
55153
 
54163
- this.REVISION = '3.4.11';
55154
+ this.REVISION = '3.7.1';
54164
55155
 
54165
55156
  // In nodejs, iCn3D defines "window = {navigator: {}}"
54166
55157
  this.bNode = (Object.keys(window).length < 2) ? true : false;
@@ -54206,7 +55197,7 @@ class iCn3DUI {
54206
55197
  iCn3DUI.prototype.show3DStructure = function() { let me = this;
54207
55198
  let thisClass = this;
54208
55199
  me.deferred = $.Deferred(function() {
54209
- if(me.cfg.menumode == 1) {
55200
+ if(me.cfg.menuicon) {
54210
55201
  me.htmlCls.wifiStr = '<i class="icn3d-wifi" title="requires internet">&nbsp;</i>';
54211
55202
  me.htmlCls.licenseStr = '<i class="icn3d-license" title="requires license">&nbsp;</i>';
54212
55203
  }
@@ -54337,7 +55328,7 @@ iCn3DUI.prototype.show3DStructure = function() { let me = this;
54337
55328
 
54338
55329
  ic.loadCmd = 'load url ' + url + ' | type ' + type;
54339
55330
  me.htmlCls.clickMenuCls.setLogCmd(ic.loadCmd, true);
54340
- ic.pdbParserCls.downloadUrl(url, type);
55331
+ ic.pdbParserCls.downloadUrl(url, type, me.cfg.command);
54341
55332
  }
54342
55333
  else if(me.cfg.mmtfid !== undefined) {
54343
55334
  ic.inputid = me.cfg.mmtfid;
@@ -54388,7 +55379,16 @@ iCn3DUI.prototype.show3DStructure = function() { let me = this;
54388
55379
  // custom seqeunce has query_id such as "Query_78989" in BLAST
54389
55380
  if(me.cfg.query_id.substr(0,5) !== 'Query' && me.cfg.rid === undefined) {
54390
55381
  ic.inputid = me.cfg.query_id + '_' + me.cfg.blast_rep_id;
54391
- ic.loadCmd = 'load seq_struct_ids ' + me.cfg.query_id + ',' + me.cfg.blast_rep_id;
55382
+
55383
+ if(me.cfg.alg == 'smithwm') {
55384
+ ic.loadCmd = 'load seq_struct_ids_smithwm ' + me.cfg.query_id + ',' + me.cfg.blast_rep_id;
55385
+ ic.bSmithwm = true;
55386
+ }
55387
+ else {
55388
+ ic.loadCmd = 'load seq_struct_ids ' + me.cfg.query_id + ',' + me.cfg.blast_rep_id;
55389
+ ic.bSmithwm = false;
55390
+ }
55391
+
54392
55392
  me.htmlCls.clickMenuCls.setLogCmd(ic.loadCmd, true);
54393
55393
  ic.mmdbParserCls.downloadBlast_rep_id(me.cfg.query_id + ',' + me.cfg.blast_rep_id);
54394
55394
  }
@@ -54628,6 +55628,7 @@ class printMsg {
54628
55628
 
54629
55629
  exports.AddTrack = AddTrack;
54630
55630
  exports.AlignParser = AlignParser;
55631
+ exports.AlignSW = AlignSW;
54631
55632
  exports.AlignSeq = AlignSeq;
54632
55633
  exports.Alternate = Alternate;
54633
55634
  exports.Analysis = Analysis;