icn3d 3.40.4 → 3.41.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/icn3d.module.js CHANGED
@@ -9728,9 +9728,9 @@ class ClickMenu {
9728
9728
  }
9729
9729
 
9730
9730
  getHiddenMenusFromCache() { let me = this.icn3dui; me.icn3d;
9731
- // me.htmlCls.shownMenus = {};
9731
+ me.htmlCls.shownMenus = {};
9732
9732
 
9733
- // let mode = me.htmlCls.setHtmlCls.getCookie('menumode');
9733
+ let mode = me.htmlCls.setHtmlCls.getCookie('menumode');
9734
9734
 
9735
9735
  let idArrayStr = (localStorage) ? localStorage.getItem('hiddenmenus') : '';
9736
9736
 
@@ -9739,31 +9739,23 @@ class ClickMenu {
9739
9739
 
9740
9740
  let idArray = JSON.parse(idArrayStr);
9741
9741
 
9742
- // for(let i = 0, il = idArray.length; i < il; ++i) {
9743
- // me.htmlCls.shownMenus[idArray[i]] = 1;
9744
- // }
9745
9742
  for(let menu in me.htmlCls.allMenus) {
9746
9743
  if(idArray.indexOf(menu) == -1) {
9747
9744
  me.htmlCls.shownMenus[menu] = 1;
9748
9745
  }
9749
9746
  }
9750
9747
  }
9751
- //###
9752
9748
  else {
9753
- me.htmlCls.shownMenus = me.hashUtilsCls.cloneHash(me.htmlCls.allMenus);
9749
+ if(mode == 'all') {
9750
+ me.htmlCls.shownMenus = me.hashUtilsCls.cloneHash(me.htmlCls.allMenus);
9751
+ }
9752
+ else if(!mode || mode == 'simple') {
9753
+ me.htmlCls.shownMenus = me.hashUtilsCls.cloneHash(me.htmlCls.simpleMenus);
9754
+ }
9755
+ else {
9756
+ me.htmlCls.shownMenus = me.hashUtilsCls.cloneHash(me.htmlCls.simpleMenus);
9757
+ }
9754
9758
  }
9755
-
9756
- // else {
9757
- // if(mode == 'all') {
9758
- // me.htmlCls.shownMenus = me.hashUtilsCls.cloneHash(me.htmlCls.allMenus);
9759
- // }
9760
- // else if(!mode || mode == 'simple') {
9761
- // me.htmlCls.shownMenus = me.hashUtilsCls.cloneHash(me.htmlCls.simpleMenus);
9762
- // }
9763
- // else {
9764
- // me.htmlCls.shownMenus = me.hashUtilsCls.cloneHash(me.htmlCls.simpleMenus);
9765
- // }
9766
- // }
9767
9759
  }
9768
9760
 
9769
9761
  displayShownMenus() { let me = this.icn3dui; me.icn3d;
@@ -11723,12 +11715,17 @@ class ClickMenu {
11723
11715
  // alert("The url is more than 4000 characters and may not work.");
11724
11716
  //}
11725
11717
  //else {
11726
- url = url.replace("icn3d/full.html?", "icn3d/full2.html?");
11718
+ // url = url.replace("icn3d/full.html?", "icn3d/full2.html?");
11719
+
11720
+ url = url.replace(/icn3d\/full[_\d\.]*\.html\?/, "icn3d/full2.html?");
11721
+
11727
11722
  url = url.replace("icn3d/?", "icn3d/full2.html?");
11723
+
11728
11724
  url += '&closepopup=1';
11729
11725
  let urlTarget = (ic.structures && Object.keys(ic.structures).length > 0) ? '_blank' : '_self';
11730
11726
  window.open(url, urlTarget);
11731
- thisClass.setLogCmd('side by side | ' + url, true);
11727
+ // thisClass.setLogCmd('side by side | ' + url, true);
11728
+ thisClass.setLogCmd('side by side | ' + url, false);
11732
11729
  //}
11733
11730
  });
11734
11731
 
@@ -12237,7 +12234,7 @@ class SetMenu {
12237
12234
 
12238
12235
  let tdStr = '<td valign="top">';
12239
12236
 
12240
- // html += tdStr + this.setMenuMode() + '</td>';
12237
+ html += tdStr + this.setMenuMode() + '</td>';
12241
12238
 
12242
12239
  html += tdStr + this.setMenu1() + '</td>';
12243
12240
 
@@ -12248,12 +12245,11 @@ class SetMenu {
12248
12245
  html += tdStr + this.setMenu4() + '</td>';
12249
12246
 
12250
12247
  html += tdStr + this.setMenu5() + '</td>';
12251
- //html += tdStr + this.setMenu5b() + '</td>';
12252
12248
  html += tdStr + this.setMenu6() + '</td>';
12253
12249
 
12254
12250
  // reset the menus at the end of the menus
12255
- // let mode = me.htmlCls.setHtmlCls.getCookie('menumode');
12256
- // this.resetMenu(mode);
12251
+ let mode = me.htmlCls.setHtmlCls.getCookie('menumode');
12252
+ this.resetMenu(mode);
12257
12253
 
12258
12254
  // me.htmlCls.shownMenus = me.hashUtilsCls.cloneHash(me.htmlCls.simpleMenus);
12259
12255
 
@@ -12361,7 +12357,7 @@ class SetMenu {
12361
12357
  }
12362
12358
  html += "<div>";
12363
12359
 
12364
- // html += '<li>' + this.setMenuMode(true);
12360
+ html += '<li>' + this.setMenuMode(true);
12365
12361
 
12366
12362
  let liStr = "<li><span class='icn3d-menu-color'";
12367
12363
 
@@ -12382,8 +12378,8 @@ class SetMenu {
12382
12378
  html += this.setMenu6_base();
12383
12379
 
12384
12380
  // reset the menus at the end of the menus
12385
- // let mode = me.htmlCls.setHtmlCls.getCookie('menumode');
12386
- // this.resetMenu(mode);
12381
+ let mode = me.htmlCls.setHtmlCls.getCookie('menumode');
12382
+ this.resetMenu(mode);
12387
12383
 
12388
12384
  // me.htmlCls.shownMenus = me.hashUtilsCls.cloneHash(me.htmlCls.simpleMenus);
12389
12385
 
@@ -12473,7 +12469,7 @@ class SetMenu {
12473
12469
 
12474
12470
  html += me.htmlCls.divStr + "selection' style='display:none;'><div style='position:absolute; z-index:555; float:left; display:table-row; margin: 32px 0px 0px 0px;'>";
12475
12471
  //html += "<table style='margin-top: 3px; width:100px;'>";
12476
- html += "<table style='margin-top: 3px; width:770px; background-color:#EEE;'>";
12472
+ html += "<table style='margin: 3px 0px 0px 76px; width:770px; background-color:#EEE;'>";
12477
12473
 
12478
12474
  html += this.setTools_base();
12479
12475
 
@@ -12789,9 +12785,9 @@ class SetMenu {
12789
12785
  html += "</ul>";
12790
12786
  html += "</li>";
12791
12787
 
12792
- html += this.getMenuText('mn1_aligntwostru', 'Protein Complexes', undefined, undefined, 2);
12788
+ html += this.getMenuText('mn1_aligntwostru', 'Protein Complexes', undefined, 1, 2);
12793
12789
  html += "<ul>";
12794
- html += this.getLink('mn1_align', 'Two PDB Structures ' + me.htmlCls.wifiStr, undefined, 3);
12790
+ html += this.getLink('mn1_align', 'Two PDB Structures ' + me.htmlCls.wifiStr, 1, 3);
12795
12791
  html += this.getLink('mn1_alignaf', 'Two AlphaFold Structures ' + me.htmlCls.wifiStr, undefined, 3);
12796
12792
  html += "</ul>";
12797
12793
 
@@ -12845,8 +12841,8 @@ class SetMenu {
12845
12841
  html += "<ul>";
12846
12842
  html += this.getMenuText('mn1_savepngimage', 'iCn3D PNG Image', undefined, 1, 2);
12847
12843
  html += "<ul>";
12848
- html += this.getLink('mn1_exportCanvas', 'Original Size & HTML', 1, 3);
12849
- html += this.getLink('mn1_exportCanvas1', 'Original Size', undefined, 3);
12844
+ html += this.getLink('mn1_exportCanvas', 'Original Size & HTML', undefined, 3);
12845
+ html += this.getLink('mn1_exportCanvas1', 'Original Size', 1, 3);
12850
12846
 
12851
12847
  html += this.getLink('mn1_exportCanvas2', '2X Large', undefined, 3);
12852
12848
  html += this.getLink('mn1_exportCanvas4', '4X Large', undefined, 3);
@@ -12933,7 +12929,7 @@ class SetMenu {
12933
12929
  html += "<ul class='icn3d-mn-item'>";
12934
12930
 
12935
12931
  html += this.getLink('mn2_definedsets', 'Defined Sets', 1, 1);
12936
- html += this.getLink('mn2_selectall', 'All', undefined, 1);
12932
+ html += this.getLink('mn2_selectall', 'All', 1, 1);
12937
12933
  html += this.getLink('mn2_selectdisplayed', 'Displayed Set', undefined, 1);
12938
12934
  html += this.getLink('mn2_aroundsphere', 'by Distance', 1, 1);
12939
12935
 
@@ -12949,10 +12945,10 @@ class SetMenu {
12949
12945
  html += "</li>";
12950
12946
 
12951
12947
  html += this.getLink('mn2_selectcomplement', 'Inverse', undefined, 1);
12952
- html += this.getLink('mn2_selectmainchains', 'Main Chains', undefined, 1);
12953
- html += this.getLink('mn2_selectsidechains', 'Side Chains', undefined, 1);
12948
+ html += this.getLink('mn2_selectmainchains', 'Main Chains', 1, 1);
12949
+ html += this.getLink('mn2_selectsidechains', 'Side Chains', 1, 1);
12954
12950
  html += this.getLink('mn2_selectmainsidechains', 'Main & Side Chains', undefined, 1);
12955
- html += this.getLink('mn2_command', 'Advanced', undefined, 1);
12951
+ html += this.getLink('mn2_command', 'Advanced', 1, 1);
12956
12952
 
12957
12953
  if(me.cfg.cid === undefined) {
12958
12954
  html += this.getMenuText('mn2_selon3d', 'Select on 3D', undefined, 1, 1);
@@ -12985,7 +12981,7 @@ class SetMenu {
12985
12981
  html += this.getMenuSep();
12986
12982
 
12987
12983
  html += this.getLink('mn2_saveselection', 'Save Selection', 1, 1);
12988
- html += this.getLink('clearall', 'Clear Selection', undefined, 1);
12984
+ html += this.getLink('clearall', 'Clear Selection', 1, 1);
12989
12985
  html += this.getLink('mn2_saveresidue', 'Save Res. in Sel.', 1, 1);
12990
12986
 
12991
12987
  html += this.getMenuSep();
@@ -13050,7 +13046,7 @@ class SetMenu {
13050
13046
  html += this.getLinkWrapper('mn2_alternate', 'Alternate(Key "a")', 'mn2_alternateWrap', undefined, 1);
13051
13047
 
13052
13048
  if(me.cfg.opmid !== undefined) {
13053
- html += this.getLinkWrapper('togglemem', 'Toggle Membrane', 'togglememli', undefined, 1);
13049
+ html += this.getLinkWrapper('togglemem', 'Toggle Membrane', 'togglememli', 1, 1);
13054
13050
  }
13055
13051
  //else if(me.cfg.mmdbafid !== undefined || me.cfg.afid !== undefined) {
13056
13052
  else if(me.cfg.cid === undefined) {
@@ -13065,14 +13061,14 @@ class SetMenu {
13065
13061
 
13066
13062
  html += this.getMenuSep();
13067
13063
 
13068
- html += this.getMenuText('mn2_vrarhints', 'VR & AR Hints', undefined, 1, 1);
13064
+ html += this.getMenuText('mn2_vrarhints', 'VR & AR Hints', undefined, undefined, 1);
13069
13065
  html += "<ul>";
13070
- html += this.getMenuUrl("vrhint", me.htmlCls.baseUrl + "icn3d/icn3d.html#vr", "VR: VR Headsets", 1, 2);
13071
- html += this.getMenuUrl("arhint", me.htmlCls.baseUrl + "icn3d/icn3d.html#ar", "AR: Chrome in Android", 1, 2);
13066
+ html += this.getMenuUrl("vrhint", me.htmlCls.baseUrl + "icn3d/icn3d.html#vr", "VR: VR Headsets", undefined, 2);
13067
+ html += this.getMenuUrl("arhint", me.htmlCls.baseUrl + "icn3d/icn3d.html#ar", "AR: Chrome in Android", undefined, 2);
13072
13068
  html += "</ul>";
13073
13069
  html += "</li>";
13074
13070
 
13075
- html += this.getLink('mn6_sidebyside', 'Side by Side', 1, 1);
13071
+ html += this.getLink('mn6_sidebyside', 'Side by Side', undefined, 1);
13076
13072
 
13077
13073
  html += this.getMenuText('mn2_rotate', 'Rotate', undefined, 1, 1);
13078
13074
  html += "<ul>";
@@ -13184,7 +13180,7 @@ class SetMenu {
13184
13180
  html += this.getRadio('mn3_proteins', 'mn3_proteinsRibbon', 'Ribbon', true, 1, 2);
13185
13181
  }
13186
13182
 
13187
- html += this.getRadio('mn3_proteins', 'mn3_proteinsStrand', 'Strand', undefined, undefined, 2);
13183
+ html += this.getRadio('mn3_proteins', 'mn3_proteinsStrand', 'Strand', undefined, 1, 2);
13188
13184
  html += this.getRadio('mn3_proteins', 'mn3_proteinsCylinder', 'Cylinder and Plate', undefined, undefined, 2);
13189
13185
  html += this.getRadio('mn3_proteins', 'mn3_proteinsSchematic', 'Schematic', undefined, 1, 2);
13190
13186
 
@@ -13196,7 +13192,7 @@ class SetMenu {
13196
13192
  }
13197
13193
 
13198
13194
  html += this.getRadio('mn3_proteins', 'mn3_proteinsBackbone', 'Backbone', undefined, undefined, 2);
13199
- html += this.getRadio('mn3_proteins', 'mn3_proteinsBfactor', 'B-factor Tube', undefined, 1, 2);
13195
+ html += this.getRadio('mn3_proteins', 'mn3_proteinsBfactor', 'B-factor Tube', undefined, undefined, 2);
13200
13196
  html += this.getRadio('mn3_proteins', 'mn3_proteinsLines', 'Lines', undefined, 1, 2);
13201
13197
  html += this.getRadio('mn3_proteins', 'mn3_proteinsStick', 'Stick', undefined, 1, 2);
13202
13198
  html += this.getRadio('mn3_proteins', 'mn3_proteinsBallstick', 'Ball and Stick', undefined, 1, 2);
@@ -13260,10 +13256,10 @@ class SetMenu {
13260
13256
  html += "</li>";
13261
13257
 
13262
13258
  //if(me.cfg.cid !== undefined) {
13263
- html += this.getMenuText('mn3_hydrogenswrap', 'Hydrogens', undefined, 1, 1);
13259
+ html += this.getMenuText('mn3_hydrogenswrap', 'Hydrogens', undefined, undefined, 1);
13264
13260
  html += "<ul>";
13265
- html += this.getRadio('mn3_hydrogens', 'mn3_hydrogensYes', 'Show', true, 1, 2);
13266
- html += this.getRadio('mn3_hydrogens', 'mn3_hydrogensNo', 'Hide', undefined, 1, 2);
13261
+ html += this.getRadio('mn3_hydrogens', 'mn3_hydrogensYes', 'Show', true, undefined, 2);
13262
+ html += this.getRadio('mn3_hydrogens', 'mn3_hydrogensNo', 'Hide', undefined, undefined, 2);
13267
13263
  html += "</ul>";
13268
13264
  html += "</li>";
13269
13265
  //}
@@ -13638,7 +13634,7 @@ class SetMenu {
13638
13634
 
13639
13635
  html += "</ul>";
13640
13636
 
13641
- html += this.getRadio('mn4_clr', 'mn4_clrCustom', 'Color Picker', undefined, undefined, 1);
13637
+ html += this.getRadio('mn4_clr', 'mn4_clrCustom', 'Color Picker', undefined, 1, 1);
13642
13638
  html += this.getMenuSep();
13643
13639
 
13644
13640
  if(me.cfg.cid === undefined) {
@@ -13679,7 +13675,7 @@ class SetMenu {
13679
13675
  html += this.getRadio('mn4_clr', 'mn4_clrBfactorNorm', 'Percentile', undefined, 1, 2);
13680
13676
  html += "</ul>";
13681
13677
 
13682
- html += this.getRadio('mn4_clr', 'mn4_clrArea', 'Solvent<br><span style="padding-left:1.5em;">Accessibility</span>', undefined, undefined, 1);
13678
+ html += this.getRadio('mn4_clr', 'mn4_clrArea', 'Solvent<br><span style="padding-left:1.5em;">Accessibility</span>', undefined, 1, 1);
13683
13679
 
13684
13680
  html += this.getRadio('mn4_clr', 'mn4_clrStructure', 'Structure', undefined, 1, 1);
13685
13681
 
@@ -13691,7 +13687,7 @@ class SetMenu {
13691
13687
  }
13692
13688
 
13693
13689
  //if(me.cfg.mmdbid !== undefined || me.cfg.gi !== undefined) {
13694
- html += this.getRadio('mn4_clr', 'mn4_clrdomain', '3D Domain', undefined, undefined, 1);
13690
+ html += this.getRadio('mn4_clr', 'mn4_clrdomain', '3D Domain', undefined, 1, 1);
13695
13691
  //}
13696
13692
 
13697
13693
  if(me.cfg.cid === undefined) {
@@ -13711,16 +13707,16 @@ class SetMenu {
13711
13707
  html += this.getRadio('mn4_clr', 'mn4_clrAtom', 'Atom', undefined, 1, 1);
13712
13708
 
13713
13709
  if(me.cfg.align !== undefined || me.cfg.chainalign !== undefined) {
13714
- html += this.getRadio('mn4_clr', 'mn4_clrIdentity', 'Identity', true, undefined, 2);
13715
- html += this.getRadio('mn4_clr', 'mn4_clrConserved', 'Conservation', undefined, undefined, 2);
13710
+ html += this.getRadio('mn4_clr', 'mn4_clrIdentity', 'Identity', true, undefined, 1);
13711
+ html += this.getRadio('mn4_clr', 'mn4_clrConserved', 'Conservation', undefined, undefined, 1);
13716
13712
  }
13717
13713
  else if(me.cfg.blast_rep_id !== undefined) {
13718
- html += this.getRadio('mn4_clr', 'mn4_clrIdentity', 'Identity', undefined, undefined, 2);
13719
- html += this.getRadio('mn4_clr', 'mn4_clrConserved', 'Conservation', true, undefined, 2);
13714
+ html += this.getRadio('mn4_clr', 'mn4_clrIdentity', 'Identity', undefined, undefined, 1);
13715
+ html += this.getRadio('mn4_clr', 'mn4_clrConserved', 'Conservation', true, undefined, 1);
13720
13716
  }
13721
13717
  else {
13722
- html += this.getRadio('mn4_clr', 'mn4_clrIdentity', 'Identity', undefined, undefined, 2);
13723
- html += this.getRadio('mn4_clr', 'mn4_clrConserved', 'Conservation', undefined, undefined, 2);
13718
+ html += this.getRadio('mn4_clr', 'mn4_clrIdentity', 'Identity', undefined, undefined, 1);
13719
+ html += this.getRadio('mn4_clr', 'mn4_clrConserved', 'Conservation', undefined, undefined, 1);
13724
13720
  }
13725
13721
 
13726
13722
  //if(me.cfg.afid) html += this.getRadio('mn4_clr', 'mn4_clrConfidence', 'AF Confidence');
@@ -13728,8 +13724,8 @@ class SetMenu {
13728
13724
  html += this.getRadio('mn4_clr', 'mn4_clrConfidence', 'pLDDT', undefined, 1, 1);
13729
13725
  //}
13730
13726
 
13731
- html += this.getRadio('mn4_clr', 'mn4_clrIgstrand', 'Ig Strand', undefined, undefined, 2);
13732
- html += this.getRadio('mn4_clr', 'mn4_clrIgproto', 'Ig Protodomain', undefined, undefined, 2);
13727
+ html += this.getRadio('mn4_clr', 'mn4_clrIgstrand', 'Ig Strand', undefined, undefined, 1);
13728
+ html += this.getRadio('mn4_clr', 'mn4_clrIgproto', 'Ig Protodomain', undefined, undefined, 1);
13733
13729
  }
13734
13730
  else {
13735
13731
  //if(!me.cfg.hidelicense) html += this.getRadio('mn4_clr', 'mn1_delphi2', 'DelPhi<br><span style="padding-left:1.5em;">Potential ' + me.htmlCls.licenseStr + '</span>');
@@ -13782,7 +13778,7 @@ class SetMenu {
13782
13778
  html += this.getLink('mn6_selectannotations', 'Seq. & Annotations ' + me.htmlCls.wifiStr, 1, 1);
13783
13779
 
13784
13780
  //if(me.cfg.align !== undefined || me.cfg.chainalign !== undefined) { // || ic.bRealign || ic.bSymd || ic.bInputfile) {
13785
- html += this.getLink('mn2_alignment', 'Aligned Seq. ' + me.htmlCls.wifiStr, undefined, 1);
13781
+ html += this.getLink('mn2_alignment', 'Aligned Seq. ' + me.htmlCls.wifiStr, 1, 1);
13786
13782
  //}
13787
13783
 
13788
13784
  if(me.cfg.mmdbid !== undefined || me.cfg.gi !== undefined || me.cfg.blast_rep_id !== undefined || me.cfg.align !== undefined || me.cfg.chainalign !== undefined) {
@@ -13852,27 +13848,27 @@ class SetMenu {
13852
13848
  html += "</ul>";
13853
13849
  html += "</li>";
13854
13850
 
13855
- html += this.getMenuText('mn6_anglewrap', 'Angle', undefined, 1, 1);
13851
+ html += this.getMenuText('mn6_anglewrap', 'Angle', undefined, undefined, 1);
13856
13852
  html += "<ul>";
13857
- html += this.getRadio('mn6_angle', 'mn6_angleManySets', 'among Many Sets', undefined, 1, 2);
13853
+ html += this.getRadio('mn6_angle', 'mn6_angleManySets', 'among Many Sets', undefined, undefined, 2);
13858
13854
  html += this.getRadio('mn6_angle', 'mn6_angleTwoSets', 'b/w Two Vectors', undefined, undefined, 2);
13859
13855
  html += "</ul>";
13860
13856
  html += "</li>";
13861
13857
 
13862
- html += this.getLink('mn6_area', 'Surface Area', 1, 1);
13858
+ html += this.getLink('mn6_area', 'Surface Area', undefined, 1);
13863
13859
 
13864
13860
  html += this.getMenuText('mn6_addlabelwrap', 'Label', undefined, 1, 1);
13865
13861
  html += "<ul>";
13866
13862
  html += this.getRadio('mn6_addlabel', 'mn6_addlabelYes', 'by Picking Atoms', undefined, undefined, 2);
13867
13863
  html += this.getRadio('mn6_addlabel', 'mn6_addlabelSelection', 'per Selection', undefined, undefined, 2);
13868
13864
  html += this.getRadio('mn6_addlabel', 'mn6_addlabelAtoms', 'per Atom', undefined, undefined, 2);
13869
- html += this.getRadio('mn6_addlabel', 'mn6_addlabelElements', 'per Atom Element', undefined, 1, 2);
13865
+ html += this.getRadio('mn6_addlabel', 'mn6_addlabelElements', 'per Atom Element', undefined, undefined, 2);
13870
13866
  if(me.cfg.cid === undefined) {
13871
13867
  html += this.getRadio('mn6_addlabel', 'mn6_addlabelResidues', 'per Residue', undefined, 1, 2);
13872
13868
  html += this.getRadio('mn6_addlabel', 'mn6_addlabelResnum', 'per Residue & Number', undefined, 1, 2);
13873
13869
 
13874
- html += this.getRadio('mn6_addlabel', 'mn6_addlabelRefnum', 'per Reference Number', undefined, 1, 2);
13875
- html += this.getRadio('mn6_addlabel', 'mn6_addlabelIg', 'per Ig Domain', undefined, 1, 2);
13870
+ html += this.getRadio('mn6_addlabel', 'mn6_addlabelRefnum', 'per Reference Number', undefined, undefined, 2);
13871
+ html += this.getRadio('mn6_addlabel', 'mn6_addlabelIg', 'per Ig Domain', undefined, undefined, 2);
13876
13872
 
13877
13873
  html += this.getRadio('mn6_addlabel', 'mn6_addlabelChains', 'per Chain', undefined, undefined, 2);
13878
13874
  html += this.getRadio('mn6_addlabel', 'mn6_addlabelTermini', 'N- & C-Termini', undefined, 1, 2);
@@ -13909,10 +13905,10 @@ class SetMenu {
13909
13905
  html += this.getMenuSep();
13910
13906
 
13911
13907
  if(me.cfg.cid === undefined) {
13912
- html += this.getMenuText('mn6_chemicalbindingwrap', 'Chem. Binding', undefined, undefined, 1);
13908
+ html += this.getMenuText('mn6_chemicalbindingwrap', 'Chem. Binding', undefined, 1, 1);
13913
13909
  html += "<ul>";
13914
- html += this.getRadio('mn6_chemicalbinding', 'mn6_chemicalbindingshow', 'Show', undefined, undefined, 2);
13915
- html += this.getRadio('mn6_chemicalbinding', 'mn6_chemicalbindinghide', 'Hide', true, undefined, 2);
13910
+ html += this.getRadio('mn6_chemicalbinding', 'mn6_chemicalbindingshow', 'Show', undefined, 1, 2);
13911
+ html += this.getRadio('mn6_chemicalbinding', 'mn6_chemicalbindinghide', 'Hide', true, 1, 2);
13916
13912
  html += "</ul>";
13917
13913
  html += "</li>";
13918
13914
 
@@ -14071,7 +14067,7 @@ class SetMenu {
14071
14067
 
14072
14068
  //html += liStr + "https://www.ncbi.nlm.nih.gov/structure' target='_blank'>Search Structure " + me.htmlCls.wifiStr + "</a></li>";
14073
14069
  //html += liStr + me.htmlCls.baseUrl + "icn3d/icn3d.html#citing' target='_blank'>Citing iCn3D</a></li>";
14074
- html += this.getMenuUrl('citing', me.htmlCls.baseUrl + "icn3d/icn3d.html#citing", "Citing iCn3D", undefined, 1);
14070
+ html += this.getMenuUrl('citing', me.htmlCls.baseUrl + "icn3d/icn3d.html#citing", "Citing iCn3D", 1, 1);
14075
14071
 
14076
14072
  html += this.getMenuText('mn6_source', 'Source Code', undefined, 1, 1);
14077
14073
  html += "<ul>";
@@ -16633,6 +16629,13 @@ class Events {
16633
16629
  $("#" + me.pre + id).resizable();
16634
16630
  }
16635
16631
 
16632
+ exportMsa(type) { let me = this.icn3dui, ic = me.icn3d;
16633
+ let text = ic.msa[type].join('\n\n');
16634
+ let fileType = (type == 'fasta') ? '.fasta' : (type == 'clustal') ? '.aln' : '.txt';
16635
+
16636
+ ic.saveFileCls.saveFile(ic.inputid + '_align' + fileType, 'text', [text]);
16637
+ }
16638
+
16636
16639
  async launchMmdb(ids, bBiounit, hostUrl, bAppend) { let me = this.icn3dui, ic = me.icn3d, thisClass = this;
16637
16640
  if(!me.cfg.notebook) dialog.dialog( "close" );
16638
16641
 
@@ -19383,6 +19386,24 @@ class Events {
19383
19386
  ic.selectionCls.saveSelection(name, name);
19384
19387
  });
19385
19388
 
19389
+ me.myEventCls.onIds("#" + me.pre + "saveFasta", "click", function(e) { me.icn3d;
19390
+ e.stopImmediatePropagation();
19391
+ thisClass.exportMsa('fasta');
19392
+ thisClass.setLogCmd('Save alignment in FASTA format', false);
19393
+ });
19394
+
19395
+ me.myEventCls.onIds("#" + me.pre + "saveClustal", "click", function(e) { me.icn3d;
19396
+ e.stopImmediatePropagation();
19397
+ thisClass.exportMsa('clustal');
19398
+ thisClass.setLogCmd('Save alignment in CLUSTALW format', false);
19399
+ });
19400
+
19401
+ me.myEventCls.onIds("#" + me.pre + "saveResbyres", "click", function(e) { me.icn3d;
19402
+ e.stopImmediatePropagation();
19403
+ thisClass.exportMsa('resbyres');
19404
+ thisClass.setLogCmd('Save alignment in Residue by Residue format to be used in File > Align (or Realign) > Multiple Chain > Residue by Residue', false);
19405
+ });
19406
+
19386
19407
  $(document).on("click", "." + me.pre + "outputselection", function(e) { let ic = me.icn3d;
19387
19408
  e.stopImmediatePropagation();
19388
19409
  ic.bSelectResidue = false;
@@ -20242,7 +20263,9 @@ class SetHtml {
20242
20263
 
20243
20264
  sequencesHtml += '<div style="width:20px; margin-left:3px; display:inline-block;"><span id="' + me.pre + 'alignseqguide' + suffix + '_expand" class="ui-icon ui-icon-plus icn3d-expand icn3d-link" style="width:15px;" title="Expand"></span><span id="' + me.pre + 'alignseqguide' + suffix + '_shrink" class="ui-icon ui-icon-minus icn3d-shrink icn3d-link" style="display:none; width:15px;" title="Shrink"></span></div> ';
20244
20265
 
20245
- sequencesHtml += "<div style='min-width:200px; display:inline-block;''><b>Selection:</b> Name: " + me.htmlCls.inputTextStr + "id='" + me.pre + "alignseq_command_name' value='alseq_" + index + "' size='10'> " + me.htmlCls.space2 + "<button style='white-space:nowrap;' id='" + me.pre + "alignseq_saveselection'>Save</button> <button style='white-space:nowrap; margin-left:20px;' id='" + me.pre + "alignseq_clearselection'>Clear</button></div><br/>";
20266
+ sequencesHtml += "<div style='min-width:200px; display:inline-block;'><b>Selection:</b> Name: " + me.htmlCls.inputTextStr + "id='" + me.pre + "alignseq_command_name' value='alseq_" + index + "' size='10'> " + me.htmlCls.space2 + "<button style='white-space:nowrap;' id='" + me.pre + "alignseq_saveselection'>Save</button> <button style='white-space:nowrap; margin-left:20px;' id='" + me.pre + "alignseq_clearselection'>Clear</button></div><br/>";
20267
+
20268
+ sequencesHtml += "<div style='min-width:200px; display:inline-block; margin-top:3px'><b>Save Alignment</b>: " + "<button style='white-space:nowrap;' id='" + me.pre + "saveFasta'>FASTA</button> <button style='white-space:nowrap; margin-left:20px;' id='" + me.pre + "saveClustal'>CLUSTAL</button> <button style='white-space:nowrap; margin-left:20px;' id='" + me.pre + "saveResbyres'>Residue by Residue</button></div><br/>";
20246
20269
 
20247
20270
  sequencesHtml += me.htmlCls.divStr + "alignseqguide" + suffix + "' style='display:none; white-space:normal;' class='icn3d-box'>";
20248
20271
 
@@ -20251,7 +20274,9 @@ class SetHtml {
20251
20274
  let resCategories = "<b>Residue labeling:</b> aligned residue with coordinates: UPPER case letter; non-aligned residue with coordinates: lower case letter which can be highlighted; residue missing coordinates: lower case letter which can NOT be highlighted.";
20252
20275
  let scroll =(me.utilsCls.isMac() && !me.utilsCls.isMobile()) ? "<br/><br/><b>Turn on scroll bar:</b> System preferences -> General -> show scroll bars -> check Always" : "";
20253
20276
 
20254
- sequencesHtml += resCategories + scroll + "<br/></div>";
20277
+ sequencesHtml += resCategories + scroll + "<br/>";
20278
+
20279
+ sequencesHtml += "</div>";
20255
20280
 
20256
20281
  return sequencesHtml;
20257
20282
  }
@@ -34150,7 +34175,6 @@ ElectronMap.prototype.fillvoxels = function(atoms, atomlist) { //(int seqinit,in
34150
34175
  //this.vpAtomID[index] =(this.dataArray[index] >= 0) ? 1 : 0; // determine whether it's positive
34151
34176
  }
34152
34177
  }
34153
-
34154
34178
  }
34155
34179
  }
34156
34180
 
@@ -60542,12 +60566,15 @@ class DensityCifParser {
60542
60566
  let thisClass = this;
60543
60567
 
60544
60568
  let url;
60545
- let detail = (me.utilsCls.isMobile() || me.cfg.notebook) ? 0 : 4; //4;
60569
+ let detail = (me.utilsCls.isMobile() || me.cfg.notebook) ? 2 : 4; //0 : 4;
60546
60570
 
60547
60571
  //https://www.ebi.ac.uk/pdbe/densities/doc.html
60548
60572
  if(type == '2fofc' || type == 'fofc') {
60549
- detail = 0;
60550
- url = "https://www.ebi.ac.uk/pdbe/densities/x-ray/" + pdbid.toLowerCase() + "/cell?detail=" + detail;
60573
+ //detail = 0;
60574
+
60575
+ // url = "https://www.ebi.ac.uk/pdbe/densities/x-ray/" + pdbid.toLowerCase() + "/cell?detail=" + detail;
60576
+ let min_max = ic.contactCls.getExtent(ic.atoms);
60577
+ url = "https://www.ebi.ac.uk/pdbe/volume-server/x-ray/" + pdbid.toLowerCase() + "/box/" + min_max[0][0] + "," + min_max[0][1] + "," + min_max[0][2] + "/" + min_max[1][0] + "," + min_max[1][1] + "," + min_max[1][2] + "?detail=" + detail;
60551
60578
  }
60552
60579
  else if(type == 'em') {
60553
60580
  url = "https://www.ebi.ac.uk/pdbe/densities/emd/" + emd.toLowerCase() + "/cell?detail=" + detail;
@@ -60620,6 +60647,33 @@ class DensityCifParser {
60620
60647
  // return sigma;
60621
60648
  }
60622
60649
 
60650
+ setMatrix(density) { let ic = this.icn3d; ic.icn3dui;
60651
+ let sampleCount = density.box.sampleCount;
60652
+ let header = {xExtent: sampleCount[0], yExtent: sampleCount[1], zExtent: sampleCount[2], mean: density.valuesInfo.mean, sigma: density.valuesInfo.sigma, max: density.valuesInfo.max, min: density.valuesInfo.min};
60653
+ for(let i = 0; i < density.data.length; ++i) {
60654
+ density.data[i];
60655
+ }
60656
+
60657
+ let origin = density.box.origin;
60658
+ let dimensions = density.box.dimensions;
60659
+ let basis = density.spacegroup.basis;
60660
+ let scale = new THREE.Matrix4().makeScale(
60661
+ dimensions[0] / (sampleCount[0] ),
60662
+ dimensions[1] / (sampleCount[1] ),
60663
+ dimensions[2] / (sampleCount[2] ));
60664
+ let translate = new THREE.Matrix4().makeTranslation(origin[0], origin[1], origin[2]);
60665
+ let fromFrac = new THREE.Matrix4().set(
60666
+ basis.x[0], basis.y[0], basis.z[0], 0.0,
60667
+ 0.0, basis.y[1], basis.z[1], 0.0,
60668
+ 0.0, 0.0, basis.z[2], 0.0,
60669
+ 0.0, 0.0, 0.0, 1.0);
60670
+
60671
+ //var toFrac = new LiteMol.Visualization.THREE.Matrix4().getInverse(fromFrac);
60672
+ let matrix = fromFrac.multiply(translate).multiply(scale);
60673
+
60674
+ return {matrix: matrix, header: header};
60675
+ }
60676
+
60623
60677
  parseChannels(densitydata, type, sigma) { let ic = this.icn3d; ic.icn3dui;
60624
60678
  let cif = this.BinaryParse(densitydata);
60625
60679
 
@@ -60629,92 +60683,35 @@ class DensityCifParser {
60629
60683
 
60630
60684
  // '2fofc'
60631
60685
  let density = twoDensity;
60632
- let sampleCount = density.box.sampleCount;
60633
- let header = {xExtent: sampleCount[0], yExtent: sampleCount[1], zExtent: sampleCount[2], mean: density.valuesInfo.mean, sigma: density.valuesInfo.sigma};
60634
- ic.mapData.header2 = header;
60635
-
60636
- ic.mapData.data2 = density.data;
60637
- for(let i = 0; i < density.data.length; ++i) {
60638
- density.data[i];
60639
- }
60640
-
60641
- let origin = density.box.origin;
60642
- let dimensions = density.box.dimensions;
60643
- let basis = density.spacegroup.basis;
60644
- let scale = new THREE.Matrix4().makeScale(
60645
- dimensions[0] / (sampleCount[0] ),
60646
- dimensions[1] / (sampleCount[1] ),
60647
- dimensions[2] / (sampleCount[2] ));
60648
- let translate = new THREE.Matrix4().makeTranslation(origin[0], origin[1], origin[2]);
60649
- let fromFrac = new THREE.Matrix4().set(
60650
- basis.x[0], basis.y[0], basis.z[0], 0.0,
60651
- 0.0, basis.y[1], basis.z[1], 0.0,
60652
- 0.0, 0.0, basis.z[2], 0.0,
60653
- 0.0, 0.0, 0.0, 1.0);
60686
+ let result = this.setMatrix(density);
60654
60687
 
60655
- //var toFrac = new LiteMol.Visualization.THREE.Matrix4().getInverse(fromFrac);
60656
- let matrix = fromFrac.multiply(translate).multiply(scale);
60657
-
60658
- ic.mapData.matrix2 = matrix;
60688
+ ic.mapData.matrix2 = result.matrix;
60689
+ ic.mapData.header2 = result.header;
60659
60690
 
60691
+ ic.mapData.data2 = density.data;
60660
60692
  ic.mapData.type2 = type;
60661
60693
  ic.mapData.sigma2 = sigma;
60662
60694
 
60663
60695
  // 'fofc'
60664
60696
  density = oneDensity;
60665
- sampleCount = density.box.sampleCount;
60666
- header = {xExtent: sampleCount[0], yExtent: sampleCount[1], zExtent: sampleCount[2], mean: density.valuesInfo.mean, sigma: density.valuesInfo.sigma};
60667
- ic.mapData.header = header;
60668
-
60669
- ic.mapData.data = density.data;
60697
+ result = this.setMatrix(density);
60670
60698
 
60671
- origin = density.box.origin;
60672
- dimensions = density.box.dimensions;
60673
- basis = density.spacegroup.basis;
60674
-
60675
- scale = new THREE.Matrix4().makeScale(
60676
- dimensions[0] / (sampleCount[0] ),
60677
- dimensions[1] / (sampleCount[1] ),
60678
- dimensions[2] / (sampleCount[2] ));
60679
- translate = new THREE.Matrix4().makeTranslation(origin[0], origin[1], origin[2]);
60680
- fromFrac = new THREE.Matrix4().set(
60681
- basis.x[0], basis.y[0], basis.z[0], 0.0,
60682
- 0.0, basis.y[1], basis.z[1], 0.0,
60683
- 0.0, 0.0, basis.z[2], 0.0,
60684
- 0.0, 0.0, 0.0, 1.0);
60685
- //var toFrac = new LiteMol.Visualization.THREE.Matrix4().getInverse(fromFrac);
60686
- matrix = fromFrac.multiply(translate).multiply(scale);
60687
- ic.mapData.matrix = matrix;
60699
+ ic.mapData.matrix = result.matrix;
60700
+ ic.mapData.header = result.header;
60688
60701
 
60702
+ ic.mapData.data = density.data;
60689
60703
  ic.mapData.type = type;
60690
60704
  ic.mapData.sigma = sigma;
60691
60705
  }
60692
60706
  else if(type == 'em') {
60693
60707
  let density = this.getChannel(cif, 'EM');
60694
60708
 
60695
- let sampleCount = density.box.sampleCount;
60696
- let header = {xExtent: sampleCount[0], yExtent: sampleCount[1], zExtent: sampleCount[2], max: density.valuesInfo.max, min: density.valuesInfo.min};
60697
- ic.mapData.headerEm = header;
60709
+ let result = this.setMatrix(density);
60698
60710
 
60699
- ic.mapData.dataEm = density.data;
60700
-
60701
- let origin = density.box.origin;
60702
- let dimensions = density.box.dimensions;
60703
- let basis = density.spacegroup.basis;
60704
- let scale = new THREE.Matrix4().makeScale(
60705
- dimensions[0] / (sampleCount[0] ),
60706
- dimensions[1] / (sampleCount[1] ),
60707
- dimensions[2] / (sampleCount[2] ));
60708
- let translate = new THREE.Matrix4().makeTranslation(origin[0], origin[1], origin[2]);
60709
- let fromFrac = new THREE.Matrix4().set(
60710
- basis.x[0], basis.y[0], basis.z[0], 0.0,
60711
- 0.0, basis.y[1], basis.z[1], 0.0,
60712
- 0.0, 0.0, basis.z[2], 0.0,
60713
- 0.0, 0.0, 0.0, 1.0);
60714
- //var toFrac = new LiteMol.Visualization.THREE.Matrix4().getInverse(fromFrac);
60715
- let matrix = fromFrac.multiply(translate).multiply(scale);
60716
- ic.mapData.matrixEm = matrix;
60711
+ ic.mapData.matrixEm = result.matrix;
60712
+ ic.mapData.headerEm = result.header;
60717
60713
 
60714
+ ic.mapData.dataEm = density.data;
60718
60715
  ic.mapData.typeEm = type;
60719
60716
  ic.mapData.sigmaEm = sigma;
60720
60717
  }
@@ -63194,6 +63191,7 @@ class SetSeqAlign {
63194
63191
  setSeqAlign(seqalign, alignedStructures) { let ic = this.icn3d, me = ic.icn3dui;
63195
63192
  let mmdbid1 = alignedStructures[0][0].pdbId;
63196
63193
  let mmdbid2 = alignedStructures[0][1].pdbId;
63194
+ let chainid1, chainid2;
63197
63195
 
63198
63196
  ic.conservedName1 = mmdbid1 + '_cons';
63199
63197
  ic.nonConservedName1 = mmdbid1 + '_ncons';
@@ -63217,7 +63215,7 @@ class SetSeqAlign {
63217
63215
  let molid1 = alignData.moleculeId;
63218
63216
 
63219
63217
  let chain1 = ic.pdbid_molid2chain[mmdbid1 + '_' + molid1];
63220
- let chainid1 = mmdbid1 + '_' + chain1;
63218
+ chainid1 = mmdbid1 + '_' + chain1;
63221
63219
 
63222
63220
  let id2aligninfo = {};
63223
63221
  let start = alignData.sequence.length, end = -1;
@@ -63249,7 +63247,7 @@ class SetSeqAlign {
63249
63247
  let molid2 = alignData.moleculeId;
63250
63248
 
63251
63249
  let chain2 = ic.pdbid_molid2chain[mmdbid2 + '_' + molid2];
63252
- let chainid2 = mmdbid2 + '_' + chain2;
63250
+ chainid2 = mmdbid2 + '_' + chain2;
63253
63251
 
63254
63252
  // annotation title for the master seq only
63255
63253
  if(ic.alnChainsAnTtl[chainid1] === undefined ) ic.alnChainsAnTtl[chainid1] = [];
@@ -63417,7 +63415,9 @@ class SetSeqAlign {
63417
63415
  ic.alnChainsAnno[chainid1][3].push(numberStr); // symbol: 10, 20, etc, empty for rest
63418
63416
 
63419
63417
  ++alignIndex;
63420
- } // end for(let j
63418
+ } // end for(let j
63419
+
63420
+ this.setMsaFormat([chainid1, chainid2]);
63421
63421
  } // end for(let i
63422
63422
 
63423
63423
  seqalign = {};
@@ -63497,7 +63497,7 @@ class SetSeqAlign {
63497
63497
  }
63498
63498
 
63499
63499
  setSeqAlignChain(chainid, chainIndex, chainidArray) { let ic = this.icn3d, me = ic.icn3dui;
63500
- let hAtoms = {};
63500
+ let hAtoms = {};
63501
63501
 
63502
63502
  let bRealign = (chainidArray) ? true : false;
63503
63503
  let mmdbid1, mmdbid2, chain1, chain2, chainid1, chainid2, pos1, pos2;
@@ -63718,23 +63718,6 @@ class SetSeqAlign {
63718
63718
  ///if(ic.chainsSeq[chainid1] === undefined || ic.chainsSeq[chainid2] === undefined) break;
63719
63719
 
63720
63720
  let resi1, resi2, resn1, resn2;
63721
- /*
63722
- if(bRealign) { // tmalign: just one residue in this for loop
63723
- if(me.cfg.aligntool == 'tmalign') {
63724
- resi1 = ic.qt_start_end[chainIndex][i].t_start;
63725
- resi2 = ic.qt_start_end[chainIndex][i].q_start;
63726
- }
63727
- else {
63728
- resi1 = j + start1;
63729
- resi2 = j + start2;
63730
- }
63731
-
63732
- resn1 = this.getResnFromResi(chainid1, resi1).toUpperCase();
63733
- resn2 = this.getResnFromResi(chainid2, resi2).toUpperCase();
63734
-
63735
- if(resn1 == '?' || resn2 == '?') continue;
63736
- }
63737
- */
63738
63721
  if(bRealign && me.cfg.aligntool == 'tmalign') { // tmalign: just one residue in this for loop
63739
63722
  resi1 = ic.qt_start_end[chainIndex][i].t_start;
63740
63723
  resi2 = ic.qt_start_end[chainIndex][i].q_start;
@@ -63745,15 +63728,6 @@ class SetSeqAlign {
63745
63728
  if(resn1 == '?' || resn2 == '?') continue;
63746
63729
  }
63747
63730
  else {
63748
- ///if(ic.chainsSeq[chainid1][j + start1] === undefined || ic.chainsSeq[chainid2][j + start2] === undefined) continue;
63749
-
63750
- // resi1 = ic.chainsSeq[chainid1][j + start1].resi;
63751
- // resi2 = ic.chainsSeq[chainid2][j + start2].resi;
63752
- // resn1 = ic.chainsSeq[chainid1][j + start1].name.toUpperCase();
63753
- // resn2 = ic.chainsSeq[chainid2][j + start2].name.toUpperCase();
63754
-
63755
- // resi1 = this.getResiAferAlign(chainid1, bRealign, j + start1 + 1);
63756
- // resi2 = this.getResiAferAlign(chainid2, bRealign, j + start2 + 1);
63757
63731
  resi1 = this.getResiAferAlign(chainid1, bRealign, j + start1);
63758
63732
  resi2 = this.getResiAferAlign(chainid2, bRealign, j + start2);
63759
63733
  resn1 = this.getResnFromResi(chainid1, resi1).toUpperCase();
@@ -63793,14 +63767,15 @@ class SetSeqAlign {
63793
63767
 
63794
63768
  prevIndex1 = end1;
63795
63769
  prevIndex2 = end2;
63796
- } // end for(let i
63770
+ } // end for(let i
63771
+
63772
+ this.setMsaFormat([chainid1, chainid2]);
63797
63773
 
63798
63774
  return hAtoms;
63799
63775
  }
63800
63776
 
63801
63777
  setSeqAlignChainForAll(chainidArray, index_alignLen, bRealign) { let ic = this.icn3d, me = ic.icn3dui;
63802
63778
  let hAtoms = {};
63803
-
63804
63779
  let chainid1 = chainidArray[0];
63805
63780
 
63806
63781
  ic.alnChainsAnno[chainid1] = [];
@@ -63954,7 +63929,8 @@ class SetSeqAlign {
63954
63929
  resObject.aligned = (resid2range_t[resid]) ? true : false;
63955
63930
  resObject.color = (resid2range_t[resid]) ? '#FF0000' : me.htmlCls.GREYC; // color by identity
63956
63931
  resObject.color2 = (resid2range_t[resid]) ? '#FF0000' : me.htmlCls.GREYC; // color by conservation
63957
- resObject.class = (resid2range_t[resid]) ? 'icn3d-align' : 'icn3d-nalign';
63932
+ // resObject.class = (resid2range_t[resid]) ? 'icn3d-align' : 'icn3d-nalign';
63933
+ resObject.class = (resid2range_t[resid]) ? 'icn3d-cons' : 'icn3d-nalign';
63958
63934
 
63959
63935
  ic.alnChainsSeq[chainid1].push(resObject);
63960
63936
 
@@ -63973,7 +63949,9 @@ class SetSeqAlign {
63973
63949
  let hAtomsTmp = this.mergeTwoSeqForAll(chainidArray, index, alignedChainIndice, resid2range_t, start_t, end_t, bRealign);
63974
63950
 
63975
63951
  hAtoms = me.hashUtilsCls.unionHash(hAtoms, hAtomsTmp);
63976
- }
63952
+ }
63953
+
63954
+ this.setMsaFormat(chainidArray);
63977
63955
 
63978
63956
  // 3. assign the variable ic.alnChainsAnno
63979
63957
  for(let i = 0; i < 3 + 2*n; ++i) {
@@ -64044,7 +64022,7 @@ class SetSeqAlign {
64044
64022
  resObject.aligned = (bGap) ? false : bAligned;
64045
64023
  resObject.color = (bGap || !bAligned) ? me.htmlCls.GREYC : ((resn == resn_t) ? "#FF0000" : "#0000FF"); // color by identity
64046
64024
  resObject.color2 = (bGap || !bAligned) ? me.htmlCls.GREYC : '#' + ic.showAnnoCls.getColorhexFromBlosum62(resn, resn_t); // color by conservation
64047
- resObject.class = (bGap || !bAligned) ? 'icn3d-nalign' : 'icn3d-align';
64025
+ resObject.class = (bGap || !bAligned) ? 'icn3d-nalign' : ((resn == resn_t) ? "icn3d-cons" : "icn3d-ncons");
64048
64026
 
64049
64027
  return resObject;
64050
64028
  }
@@ -64318,7 +64296,7 @@ class SetSeqAlign {
64318
64296
  pos2 = result.pos2;
64319
64297
  for(let i = pos1; i < pos2; ++i) {
64320
64298
  //for(let i = pos1; i <= pos2; ++i) {
64321
- ic.alnChainsSeq[chainid2].push(gapResObject2);
64299
+ ic.alnChainsSeq[chainid2].push(gapResObject2);
64322
64300
  }
64323
64301
 
64324
64302
  return hAtoms;
@@ -64645,6 +64623,107 @@ class SetSeqAlign {
64645
64623
  }
64646
64624
  }
64647
64625
  }
64626
+
64627
+ setMsaFormat(chainidArray) { let ic = this.icn3d; ic.icn3dui;
64628
+ //set MSA
64629
+ let fastaFormat = '', clustalFormat = 'CLUSTALW\n\n', resbyresFormat = '';
64630
+ let chainArrayClustal = [];
64631
+
64632
+ let consArray = [], resiArrayTemplate = [];
64633
+ let chainidTemplate = chainidArray[0];
64634
+ for(let i = 0, il = chainidArray.length; i < il; ++i) {
64635
+ let chainid = chainidArray[i];
64636
+ fastaFormat += '>' + chainid + '\n';
64637
+
64638
+ let clustalArray = [];
64639
+ let clustalLine = chainid.padEnd(20, ' ');
64640
+ let consLine = ''.padEnd(20, ' ');
64641
+
64642
+ let resiArrayTarget = [], resiArrayQuery = [];
64643
+
64644
+ let cnt = 0;
64645
+ for(let j = 0, jl = ic.alnChainsSeq[chainid].length; j < jl; ++j) {
64646
+ let resn = ic.alnChainsSeq[chainid][j].resn;
64647
+ fastaFormat += resn;
64648
+ clustalLine += resn;
64649
+ if(i == il - 1) {
64650
+ let alignedClass = ic.alnChainsSeq[chainid][j].class;
64651
+ if(alignedClass == 'icn3d-cons') {
64652
+ consLine += '*';
64653
+ }
64654
+ else if(alignedClass == 'icn3d-ncons') {
64655
+ consLine += '.';
64656
+ }
64657
+ else {
64658
+ consLine += ' ';
64659
+ }
64660
+ }
64661
+
64662
+ // residue by residue
64663
+ if(i == 0) {
64664
+ resiArrayTemplate.push(ic.alnChainsSeq[chainid][j].resi);
64665
+ }
64666
+ else {
64667
+ if(ic.alnChainsSeq[chainid][j].aligned) {
64668
+ resiArrayTarget.push(ic.alnChainsSeq[chainidTemplate][j].resi);
64669
+ resiArrayQuery.push(ic.alnChainsSeq[chainid][j].resi);
64670
+ }
64671
+ }
64672
+
64673
+ ++cnt;
64674
+
64675
+ if(cnt % 60 == 0) {
64676
+ fastaFormat += '\n';
64677
+ clustalLine += ' ' + String(parseInt(cnt / 60) * 60);
64678
+ clustalArray.push(clustalLine);
64679
+ clustalLine = chainid.padEnd(20, ' ');
64680
+
64681
+ if(i == il - 1) {
64682
+ consArray.push(consLine);
64683
+ consLine = ''.padEnd(20, ' ');
64684
+ }
64685
+ }
64686
+ }
64687
+
64688
+ // add last line
64689
+ if(cnt % 60 != 0) {
64690
+ clustalArray.push(clustalLine);
64691
+ if(i == il - 1) {
64692
+ consArray.push(consLine);
64693
+ }
64694
+ }
64695
+
64696
+ fastaFormat += '\n';
64697
+
64698
+ chainArrayClustal.push(clustalArray);
64699
+ if(i == il - 1) chainArrayClustal.push(consArray);
64700
+
64701
+ // residue by residue
64702
+ let resiRangeStr1 = ic.resid2specCls.resi2range(resiArrayTarget, true);
64703
+ let resiRangeStr2 = ic.resid2specCls.resi2range(resiArrayQuery, true);
64704
+
64705
+ if(i > 0) resbyresFormat += resiRangeStr1 + ' | ' + resiRangeStr2 + '\n';
64706
+ }
64707
+
64708
+ // CLUSTALW
64709
+ for(let j = 0, jl = chainArrayClustal[0].length; j < jl; ++j) {
64710
+ for(let i = 0, il = chainArrayClustal.length; i < il; ++i) {
64711
+ clustalFormat += chainArrayClustal[i][j] + '\n';
64712
+ }
64713
+ clustalFormat += '\n';
64714
+ }
64715
+
64716
+ // seq MSA
64717
+ if(!ic.msa) ic.msa = {};
64718
+
64719
+ if(!ic.msa['fasta']) ic.msa['fasta'] = [];
64720
+ if(!ic.msa['clustal']) ic.msa['clustal'] = [];
64721
+ if(!ic.msa['resbyres']) ic.msa['resbyres'] = [];
64722
+
64723
+ ic.msa['fasta'].push(fastaFormat);
64724
+ ic.msa['clustal'].push(clustalFormat);
64725
+ ic.msa['resbyres'].push(resbyresFormat);
64726
+ }
64648
64727
  }
64649
64728
 
64650
64729
  /**
@@ -72269,8 +72348,8 @@ class Resid2spec {
72269
72348
  return spec;
72270
72349
  }
72271
72350
 
72272
- resi2range(resiArray) {var ic = this.icn3d; ic.icn3dui;
72273
- let range = [];
72351
+ resi2range(resiArray, bString) {var ic = this.icn3d; ic.icn3dui;
72352
+ let range = [], rangeStr = '';
72274
72353
 
72275
72354
  let resiArraySorted = resiArray.sort(function(a, b) {
72276
72355
  return parseInt(a) - parseInt(b);
@@ -72281,9 +72360,14 @@ class Resid2spec {
72281
72360
  for(let j = 0, jl = resiArraySorted.length; j < jl; ++j) {
72282
72361
  resi = resiArraySorted[j];
72283
72362
 
72284
- if(j != 0 && resi != prevResi + 1) {
72363
+ if(j != 0 && parseInt(resi) != parseInt(prevResi) + 1) {
72285
72364
  range.push(startResi);
72286
72365
  range.push(prevResi);
72366
+
72367
+ if(rangeStr) rangeStr += ',';
72368
+ if(startResi == prevResi) rangeStr += startResi;
72369
+ else rangeStr += startResi + '-' + prevResi;
72370
+
72287
72371
  startResi = resi;
72288
72372
  }
72289
72373
 
@@ -72293,8 +72377,13 @@ class Resid2spec {
72293
72377
  // last residue
72294
72378
  range.push(startResi);
72295
72379
  range.push(prevResi);
72296
-
72297
- return range;
72380
+
72381
+ if(rangeStr) rangeStr += ',';
72382
+ if(startResi == prevResi) rangeStr += startResi;
72383
+ else rangeStr += startResi + '-' + prevResi;
72384
+
72385
+ if(bString) return rangeStr;
72386
+ else return range;
72298
72387
  }
72299
72388
 
72300
72389
  atoms2spec(atomHash) {var ic = this.icn3d; ic.icn3dui;
@@ -79907,6 +79996,8 @@ class SaveFile {
79907
79996
  for(let i = 0, il = residueArray.length; i < il; ++i) {
79908
79997
  let resid = residueArray[i];
79909
79998
  let atom = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[resid]);
79999
+ if(!atom) continue;
80000
+
79910
80001
  let chainid = atom.structure + '_' + atom.chain;
79911
80002
  let resnAbbr = me.utilsCls.residueName2Abbr(atom.resn);
79912
80003
  let resName = resnAbbr + atom.resi;
@@ -83887,7 +83978,7 @@ class iCn3DUI {
83887
83978
  //even when multiple iCn3D viewers are shown together.
83888
83979
  this.pre = this.cfg.divid + "_";
83889
83980
 
83890
- this.REVISION = '3.40.3';
83981
+ this.REVISION = '3.41.0';
83891
83982
 
83892
83983
  // In nodejs, iCn3D defines "window = {navigator: {}}"
83893
83984
  this.bNode = (Object.keys(window).length < 2) ? true : false;