icn3d 3.41.0 → 3.43.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.js CHANGED
@@ -2539,7 +2539,6 @@ THREE.TrackballControls = function ( object, domElement, icn3d ) {
2539
2539
  _this._panStart.add( mouseChange.subVectors( _this._panEnd, _this._panStart ).multiplyScalar( _this.dynamicDampingFactor ) );
2540
2540
 
2541
2541
  }
2542
-
2543
2542
  }
2544
2543
  }
2545
2544
 
@@ -3576,6 +3575,103 @@ THREE.OrthographicTrackballControls = function ( object, domElement, icn3d ) { v
3576
3575
  THREE.OrthographicTrackballControls.prototype = Object.create( THREE.EventDispatcher.prototype );
3577
3576
  THREE.OrthographicTrackballControls.prototype.constructor = THREE.OrthographicTrackballControls;
3578
3577
 
3578
+ /**
3579
+ * @author alteredq / http://alteredqualia.com/
3580
+ * @authod mrdoob / http://mrdoob.com/
3581
+ * @authod arodic / http://aleksandarrodic.com/
3582
+ * modified by Jiyao Wang
3583
+ */
3584
+
3585
+ THREE.StereoEffect = function ( renderer ) {
3586
+ var _this = this;
3587
+ // API
3588
+
3589
+ _this.separation = 3; // 1;
3590
+
3591
+ // internals
3592
+
3593
+ // _this._width, _this._height;
3594
+
3595
+ _this._position = new THREE.Vector3();
3596
+ _this._quaternion = new THREE.Quaternion();
3597
+ _this._scale = new THREE.Vector3();
3598
+
3599
+ _this._cameraL = new THREE.PerspectiveCamera();
3600
+ _this._cameraR = new THREE.PerspectiveCamera();
3601
+
3602
+ // initialization
3603
+
3604
+ renderer.autoClear = false;
3605
+
3606
+ _this.setSize = function ( width, height ) {
3607
+
3608
+ _this._width = width / 2;
3609
+ _this._height = height;
3610
+
3611
+ renderer.setSize( width, height );
3612
+
3613
+ };
3614
+
3615
+ _this.render = function ( scene, camera ) {
3616
+
3617
+ scene.updateMatrixWorld();
3618
+
3619
+ if ( camera.parent === undefined ) camera.updateMatrixWorld();
3620
+
3621
+ camera.matrixWorld.decompose( _this._position, _this._quaternion, _this._scale );
3622
+
3623
+ // left
3624
+ _this._cameraL.copy(camera);
3625
+ _this._cameraL.aspect = 0.5 * camera.aspect;
3626
+ _this._cameraL.updateProjectionMatrix();
3627
+
3628
+ /*
3629
+ _this._cameraL.fov = camera.fov;
3630
+ _this._cameraL.aspect = 0.5 * camera.aspect;
3631
+ _this._cameraL.near = camera.near;
3632
+ _this._cameraL.far = camera.far;
3633
+ _this._cameraL.updateProjectionMatrix();
3634
+
3635
+ _this._cameraL.position.copy( _this._position );
3636
+ // _this._cameraL.quaternion.copy( _this._quaternion );
3637
+ */
3638
+ _this._cameraL.translateX( - _this.separation );
3639
+
3640
+ // right
3641
+ _this._cameraR.copy(camera);
3642
+ _this._cameraR.aspect = 0.5 * camera.aspect;
3643
+ _this._cameraR.updateProjectionMatrix();
3644
+
3645
+ /*
3646
+ _this._cameraR.fov = camera.fov;
3647
+ _this._cameraR.aspect = 0.5 * camera.aspect;
3648
+ _this._cameraR.near = camera.near;
3649
+ _this._cameraR.far = camera.far;
3650
+ // _this._cameraR.projectionMatrix = _this._cameraL.projectionMatrix;
3651
+ _this._cameraR.updateProjectionMatrix();
3652
+
3653
+ _this._cameraR.position.copy( _this._position );
3654
+ // _this._cameraR.quaternion.copy( _this._quaternion );
3655
+ */
3656
+
3657
+ _this._cameraR.translateX( _this.separation );
3658
+
3659
+ //
3660
+
3661
+ renderer.setViewport( 0, 0, _this._width * 2, _this._height );
3662
+ renderer.clear();
3663
+
3664
+ renderer.setViewport( 0, 0, _this._width, _this._height );
3665
+ renderer.render( scene, _this._cameraL );
3666
+
3667
+ renderer.setViewport( _this._width, 0, _this._width, _this._height );
3668
+ renderer.render( scene, _this._cameraR );
3669
+
3670
+ };
3671
+
3672
+ };
3673
+
3674
+
3579
3675
 
3580
3676
  // ; var __CIFTools = function () {
3581
3677
  // 'use strict';
@@ -8805,6 +8901,7 @@ class ClickMenu {
8805
8901
 
8806
8902
  applyShownMenus(bNoSave) { let me = this.icn3dui; me.icn3d;
8807
8903
  let idArray = [];
8904
+
8808
8905
  for(let id in me.htmlCls.allMenus) {
8809
8906
  if(me.htmlCls.shownMenus.hasOwnProperty(id)) {
8810
8907
  $("#" + me.pre + id).parent().show();
@@ -9035,6 +9132,14 @@ class ClickMenu {
9035
9132
  me.htmlCls.dialogCls.openDlg('dl_urlfile', 'Load data by URL');
9036
9133
  });
9037
9134
 
9135
+ me.myEventCls.onIds("#" + me.pre + "mn1_clustalwfile", "click", function(e) { me.icn3d; //e.preventDefault();
9136
+ me.htmlCls.dialogCls.openDlg('dl_clustalwfile', 'Please input CLUSTALW MSA File');
9137
+ });
9138
+
9139
+ me.myEventCls.onIds("#" + me.pre + "mn1_fastafile", "click", function(e) { me.icn3d; //e.preventDefault();
9140
+ me.htmlCls.dialogCls.openDlg('dl_fastafile', 'Please input FASTA MSA File');
9141
+ });
9142
+
9038
9143
  me.myEventCls.onIds("#" + me.pre + "mn1_fixedversion", "click", function(e) { me.icn3d; //e.preventDefault();
9039
9144
  me.htmlCls.dialogCls.openDlg('dl_fixedversion', 'Open Share Link URL in the archived version of iCn3D');
9040
9145
  });
@@ -9136,6 +9241,11 @@ class ClickMenu {
9136
9241
  ic.saveFileCls.saveFile(file_pref + '_statefile.txt', 'command');
9137
9242
  });
9138
9243
 
9244
+ me.myEventCls.onIds("#" + me.pre + "mn1_exportVideo", "click", function(e) { me.icn3d; //e.preventDefault();
9245
+ thisClass.setLogCmd("export video", false);
9246
+ me.htmlCls.dialogCls.openDlg('dl_video', 'Save canvas changes in a video');
9247
+ });
9248
+
9139
9249
 
9140
9250
  me.myEventCls.onIds("#" + me.pre + "mn1_exportPdbRes", "click", function(e) { me.icn3d; //e.preventDefault();
9141
9251
  me.htmlCls.setHtmlCls.exportPdb();
@@ -10828,6 +10938,18 @@ class ClickMenu {
10828
10938
  //}
10829
10939
  });
10830
10940
 
10941
+ me.myEventCls.onIds("#" + me.pre + "mn6_stereoYes", "click", function(e) { let ic = me.icn3d; //e.preventDefault();
10942
+ ic.opts['effect'] = 'stereo';
10943
+ ic.drawCls.draw();
10944
+ thisClass.setLogCmd('stereo on', true);
10945
+ });
10946
+
10947
+ me.myEventCls.onIds("#" + me.pre + "mn6_stereoNo", "click", function(e) { let ic = me.icn3d; //e.preventDefault();
10948
+ ic.opts['effect'] = 'none';
10949
+ ic.drawCls.draw();
10950
+ thisClass.setLogCmd('stereo off', true);
10951
+ });
10952
+
10831
10953
  $(document).on("click", "#" + me.pre + "mn2_translate", function(e) { me.icn3d; //e.preventDefault();
10832
10954
  me.htmlCls.dialogCls.openDlg('dl_translate', 'Translate the X,Y,Z coordinates of the structure');
10833
10955
  });
@@ -11841,9 +11963,19 @@ class SetMenu {
11841
11963
  html += this.getLink('mn1_mol2file', 'Mol2 File', undefined, 2);
11842
11964
  html += this.getLink('mn1_sdffile', 'SDF File', undefined, 2);
11843
11965
  html += this.getLink('mn1_xyzfile', 'XYZ File', undefined, 2);
11966
+
11967
+ html += this.getMenuSep();
11968
+
11969
+ html += this.getMenuText('mn1_msawrap', 'Multiple Seq. Alignment', undefined, undefined, 2);
11970
+ html += "<ul>";
11971
+ html += this.getLink('mn1_clustalwfile', 'CLUSTALW Format', undefined, 3);
11972
+ html += this.getLink('mn1_fastafile', 'FASTA Format', undefined, 3);
11973
+ html += "</ul>";
11974
+
11844
11975
  html += this.getLink('mn1_afmapfile', 'AlphaFold PAE File', undefined, 2);
11845
11976
 
11846
11977
  html += this.getLink('mn1_urlfile', 'URL(CORS) ' + me.htmlCls.wifiStr, undefined, 2);
11978
+
11847
11979
  html += this.getMenuSep();
11848
11980
  html += this.getLink('mn1_pngimage', 'iCn3D PNG (appendable)', 1, 2);
11849
11981
  html += this.getLink('mn1_state', 'State/Script File', undefined, 2);
@@ -11950,6 +12082,7 @@ class SetMenu {
11950
12082
  html += "</ul>";
11951
12083
  html += "</li>";
11952
12084
 
12085
+ html += this.getLink('mn1_exportVideo', 'Video', undefined, 2);
11953
12086
  html += this.getLink('mn1_exportState', 'State File', undefined, 2);
11954
12087
  html += this.getLink('mn1_exportSelections', 'Selection File', undefined, 2);
11955
12088
  html += this.getLink('mn1_exportSelDetails', 'Selection Details', undefined, 2);
@@ -12167,6 +12300,13 @@ class SetMenu {
12167
12300
  html += "</ul>";
12168
12301
  html += "</li>";
12169
12302
 
12303
+ html += this.getMenuText('mn6_stereoWrapper', 'Stereo View', undefined, undefined, 1);
12304
+ html += "<ul>";
12305
+ html += this.getRadio('mn6_stereo', 'mn6_stereoYes', 'On', undefined, undefined, 2);
12306
+ html += this.getRadio('mn6_stereo', 'mn6_stereoNo', 'Off', true, undefined, 2);
12307
+ html += "</ul>";
12308
+ html += "</li>";
12309
+
12170
12310
  html += this.getLink('mn6_sidebyside', 'Side by Side', undefined, 1);
12171
12311
 
12172
12312
  html += this.getMenuText('mn2_rotate', 'Rotate', undefined, 1, 1);
@@ -14196,6 +14336,19 @@ class SetDialog {
14196
14336
  html += me.htmlCls.buttonStr + "reload_xyzfile'>Load</button>";
14197
14337
  html += "</div>";
14198
14338
 
14339
+ html += me.htmlCls.divStr + "dl_clustalwfile' class='" + dialogClass + "' style='max-width:500px'>";
14340
+ html += this.addNotebookTitle('dl_clustalwfile', 'Please input a CLUSTALW MSA file');
14341
+ html += "Note the sequence names are either UniProt ID (e.g., A4D1S0 or A4D1S0_A), RefSeq ID (e.g., NP_001743), or PDB chain ID (e.g., 1HHO_A).<br><br>";
14342
+ html += "CLUSTALW File: " + me.htmlCls.inputFileStr + "id='" + me.pre + "clustalwfile' size=8> ";
14343
+ html += me.htmlCls.buttonStr + "reload_clustalwfile'>Load</button><br>";
14344
+ html += "</div>";
14345
+ html += me.htmlCls.divStr + "dl_fastafile' class='" + dialogClass + "' style='max-width:500px'>";
14346
+ html += this.addNotebookTitle('dl_fastafile', 'Please input a FASTA file');
14347
+ html += "Note the sequence IDs following the symbol \">\" contain either UniProt ID (e.g., sp| or tr|), RefSeq ID (e.g., ref|), PDB chain ID (e.g., pdb|1HHO|A), or iCn3D chain ID (e.g., A4D1S0_A, 1HHO_A).<br><br>";
14348
+ html += "FASTA File: " + me.htmlCls.inputFileStr + "id='" + me.pre + "fastafile' size=8> ";
14349
+ html += me.htmlCls.buttonStr + "reload_fastafile'>Load</button><br>";
14350
+ html += "</div>";
14351
+
14199
14352
  html += me.htmlCls.divStr + "dl_afmapfile' class='" + dialogClass + "'>";
14200
14353
  html += this.addNotebookTitle('dl_afmapfile', 'Please input an AlphaFold PAE file');
14201
14354
  html += "AlphaFold PAE File: " + me.htmlCls.inputFileStr + "id='" + me.pre + "afmapfile' size=8> <br><br>";
@@ -14315,6 +14468,13 @@ class SetDialog {
14315
14468
  html += me.htmlCls.buttonStr + "reload_state' style='margin-top: 6px;'>Load</button>";
14316
14469
  html += "</div>";
14317
14470
 
14471
+ html += me.htmlCls.divStr + "dl_video' class='" + dialogClass + "'>";
14472
+ html += this.addNotebookTitle('dl_video', 'Save canvas changes in a video');
14473
+ html += "State file: " + me.htmlCls.inputFileStr + "id='" + me.pre + "state'><br/>";
14474
+ html += me.htmlCls.buttonStr + "video_start' style='margin-top: 6px;'>Video Start</button>";
14475
+ html += me.htmlCls.buttonStr + "video_end' style='margin: 6px 0px 0px 30px;'>Video End</button>";
14476
+ html += "</div>";
14477
+
14318
14478
  html += me.htmlCls.divStr + "dl_fixedversion' style='max-width:500px' class='" + dialogClass + "'>";
14319
14479
  html += this.addNotebookTitle('dl_fixedversion', 'Use fixed version of iCn3D');
14320
14480
  html += "Since January 6, 2021, you can show the original view with the archived version of iCn3D by pasting your URL below and click \"Show Originial View\". Note the version in the parameter \"v\" was used to replace \"full.html\" with \"full_[v].html\" in the URL.<br><br>";
@@ -15674,17 +15834,10 @@ class Events {
15674
15834
  }
15675
15835
  }
15676
15836
 
15677
- async loadPdbFile(bAppend, fileId, bmmCIF) { let me = this.icn3dui, ic = me.icn3d;
15837
+ async loadPdbFile(bAppend, fileId, bmmCIF) { let me = this.icn3dui, ic = me.icn3d, thisClass = this;
15678
15838
  //me = ic.setIcn3dui(this.id);
15679
15839
  ic.bInitial = true;
15680
- if(!me.cfg.notebook) dialog.dialog( "close" );
15681
- //close all dialog
15682
- if(!me.cfg.notebook) {
15683
- $(".ui-dialog-content").dialog("close");
15684
- }
15685
- else {
15686
- ic.resizeCanvasCls.closeDialogs();
15687
- }
15840
+ thisClass.iniFileLoad();
15688
15841
  let files = $("#" + me.pre + fileId)[0].files;
15689
15842
  if(!files[0]) {
15690
15843
  var aaa = 1; //alert("Please select a file before clicking 'Load'");
@@ -15730,11 +15883,22 @@ class Events {
15730
15883
 
15731
15884
  exportMsa(type) { let me = this.icn3dui, ic = me.icn3d;
15732
15885
  let text = ic.msa[type].join('\n\n');
15733
- let fileType = (type == 'fasta') ? '.fasta' : (type == 'clustal') ? '.aln' : '.txt';
15886
+ let fileType = (type == 'fasta') ? '.fasta' : (type == 'clustalw') ? '.aln' : '.txt';
15734
15887
 
15735
15888
  ic.saveFileCls.saveFile(ic.inputid + '_align' + fileType, 'text', [text]);
15736
15889
  }
15737
15890
 
15891
+ iniFileLoad() { let me = this.icn3dui, ic = me.icn3d;
15892
+ if(!me.cfg.notebook) dialog.dialog( "close" );
15893
+ //close all dialog
15894
+ if(!me.cfg.notebook) {
15895
+ $(".ui-dialog-content").dialog("close");
15896
+ }
15897
+ else {
15898
+ ic.resizeCanvasCls.closeDialogs();
15899
+ }
15900
+ }
15901
+
15738
15902
  async launchMmdb(ids, bBiounit, hostUrl, bAppend) { let me = this.icn3dui, ic = me.icn3d, thisClass = this;
15739
15903
  if(!me.cfg.notebook) dialog.dialog( "close" );
15740
15904
 
@@ -16830,16 +16994,40 @@ class Events {
16830
16994
 
16831
16995
  me.htmlCls.setHtmlCls.clickReload_pngimage();
16832
16996
 
16997
+ me.myEventCls.onIds("#" + me.pre + "video_start", "click", function(e) { let ic = me.icn3d;
16998
+ e.preventDefault();
16999
+
17000
+ const canvas = document.getElementById(ic.pre + "canvas");
17001
+ ic.videoRecorder = new MediaRecorder(canvas.captureStream());
17002
+ const recordedChunks = [];
17003
+
17004
+ // Collect data chunks
17005
+ ic.videoRecorder.ondataavailable = event => {
17006
+ recordedChunks.push(event.data);
17007
+ };
17008
+
17009
+ ic.videoRecorder.onstop = event => {
17010
+ // Code to save the recordedChunks as a video file
17011
+ const blob = new Blob(recordedChunks, {type: ic.videoRecorder.mimeType});
17012
+ let fileName = ic.inputid + '_video';
17013
+ saveAs(blob, fileName);
17014
+ };
17015
+
17016
+ // Start recording
17017
+ ic.videoRecorder.start();
17018
+ thisClass.setLogCmd('Video revording started', false);
17019
+ });
17020
+
17021
+ me.myEventCls.onIds("#" + me.pre + "video_end", "click", function(e) { let ic = me.icn3d;
17022
+ e.preventDefault();
17023
+
17024
+ ic.videoRecorder.stop();
17025
+ thisClass.setLogCmd('Video revording ended', false);
17026
+ });
17027
+
16833
17028
  me.myEventCls.onIds("#" + me.pre + "reload_state", "click", function(e) { let ic = me.icn3d;
16834
17029
  e.preventDefault();
16835
- if(!me.cfg.notebook) dialog.dialog( "close" );
16836
- //close all dialog
16837
- if(!me.cfg.notebook) {
16838
- $(".ui-dialog-content").dialog("close");
16839
- }
16840
- else {
16841
- ic.resizeCanvasCls.closeDialogs();
16842
- }
17030
+ thisClass.iniFileLoad();
16843
17031
  // initialize icn3dui
16844
17032
  //Do NOT clear data if iCn3D loads a pdb or other data file and then load a state file
16845
17033
  if(!ic.bInputfile) {
@@ -16891,12 +17079,7 @@ class Events {
16891
17079
  if (!file) {
16892
17080
  var aaa = 1; //alert("Please select a file before clicking 'Load'");
16893
17081
  } else {
16894
- if (!me.cfg.notebook) dialog.dialog("close");
16895
- if (!me.cfg.notebook) {
16896
- $(".ui-dialog-content").dialog("close");
16897
- } else {
16898
- ic.resizeCanvasCls.closeDialogs();
16899
- }
17082
+ thisClass.iniFileLoad();
16900
17083
 
16901
17084
  ic.dAtoms = me.hashUtilsCls.cloneHash(ic.atoms);
16902
17085
  ic.hAtoms = me.hashUtilsCls.cloneHash(ic.atoms);
@@ -17451,14 +17634,7 @@ class Events {
17451
17634
  me.myEventCls.onIds("#" + me.pre + "reload_mol2file", "click", function(e) { let ic = me.icn3d;
17452
17635
  e.preventDefault();
17453
17636
  ic.bInitial = true;
17454
- if(!me.cfg.notebook) dialog.dialog( "close" );
17455
- //close all dialog
17456
- if(!me.cfg.notebook) {
17457
- $(".ui-dialog-content").dialog("close");
17458
- }
17459
- else {
17460
- ic.resizeCanvasCls.closeDialogs();
17461
- }
17637
+ thisClass.iniFileLoad();
17462
17638
  let file = $("#" + me.pre + "mol2file")[0].files[0];
17463
17639
  if(!file) {
17464
17640
  var aaa = 1; //alert("Please select a file before clicking 'Load'");
@@ -17485,14 +17661,7 @@ class Events {
17485
17661
  me.myEventCls.onIds("#" + me.pre + "reload_sdffile", "click", function(e) { let ic = me.icn3d;
17486
17662
  e.preventDefault();
17487
17663
  ic.bInitial = true;
17488
- if(!me.cfg.notebook) dialog.dialog( "close" );
17489
- //close all dialog
17490
- if(!me.cfg.notebook) {
17491
- $(".ui-dialog-content").dialog("close");
17492
- }
17493
- else {
17494
- ic.resizeCanvasCls.closeDialogs();
17495
- }
17664
+ thisClass.iniFileLoad();
17496
17665
  let file = $("#" + me.pre + "sdffile")[0].files[0];
17497
17666
  if(!file) {
17498
17667
  var aaa = 1; //alert("Please select a file before clicking 'Load'");
@@ -17519,14 +17688,7 @@ class Events {
17519
17688
  me.myEventCls.onIds("#" + me.pre + "reload_xyzfile", "click", function(e) { let ic = me.icn3d;
17520
17689
  e.preventDefault();
17521
17690
  ic.bInitial = true;
17522
- if(!me.cfg.notebook) dialog.dialog( "close" );
17523
- //close all dialog
17524
- if(!me.cfg.notebook) {
17525
- $(".ui-dialog-content").dialog("close");
17526
- }
17527
- else {
17528
- ic.resizeCanvasCls.closeDialogs();
17529
- }
17691
+ thisClass.iniFileLoad();
17530
17692
  let file = $("#" + me.pre + "xyzfile")[0].files[0];
17531
17693
  if(!file) {
17532
17694
  var aaa = 1; //alert("Please select a file before clicking 'Load'");
@@ -17550,17 +17712,64 @@ class Events {
17550
17712
  }
17551
17713
  });
17552
17714
 
17553
- me.myEventCls.onIds("#" + me.pre + "reload_afmapfile", "click", function(e) { let ic = me.icn3d;
17715
+ me.myEventCls.onIds("#" + me.pre + "reload_clustalwfile", "click", function(e) { let ic = me.icn3d;
17554
17716
  e.preventDefault();
17555
17717
  ic.bInitial = true;
17556
- if(!me.cfg.notebook) dialog.dialog( "close" );
17557
- //close all dialog
17558
- if(!me.cfg.notebook) {
17559
- $(".ui-dialog-content").dialog("close");
17718
+ thisClass.iniFileLoad();
17719
+
17720
+ let file = $("#" + me.pre + "clustalwfile")[0].files[0];
17721
+ if(!file) {
17722
+ var aaa = 1; //alert("Please select a file before clicking 'Load'");
17560
17723
  }
17561
17724
  else {
17562
- ic.resizeCanvasCls.closeDialogs();
17725
+ me.htmlCls.setHtmlCls.fileSupport();
17726
+ let reader = new FileReader();
17727
+ reader.onload = async function(e) {
17728
+ let dataStr = e.target.result; // or = reader.result;
17729
+ thisClass.setLogCmd('load CLUSTALW file ' + $("#" + me.pre + "clustalwfile").val(), false);
17730
+ ic.molTitle = "";
17731
+ ic.inputid = undefined;
17732
+ //ic.initUI();
17733
+ ic.init();
17734
+ ic.bInputfile = false; //true;
17735
+ ic.InputfileType = 'clustalw';
17736
+ await ic.msaParserCls.loadMsaData(dataStr, 'clustalw');
17737
+ };
17738
+ reader.readAsText(file);
17739
+ }
17740
+ });
17741
+
17742
+ me.myEventCls.onIds("#" + me.pre + "reload_fastafile", "click", function(e) { let ic = me.icn3d;
17743
+ e.preventDefault();
17744
+ ic.bInitial = true;
17745
+ thisClass.iniFileLoad();
17746
+
17747
+ let file = $("#" + me.pre + "fastafile")[0].files[0];
17748
+ if(!file) {
17749
+ var aaa = 1; //alert("Please select a file before clicking 'Load'");
17750
+ }
17751
+ else {
17752
+ me.htmlCls.setHtmlCls.fileSupport();
17753
+ let reader = new FileReader();
17754
+ reader.onload = async function(e) {
17755
+ let dataStr = e.target.result; // or = reader.result;
17756
+ thisClass.setLogCmd('load FASTA file ' + $("#" + me.pre + "fastafile").val(), false);
17757
+ ic.molTitle = "";
17758
+ ic.inputid = undefined;
17759
+ //ic.initUI();
17760
+ ic.init();
17761
+ ic.bInputfile = false; //true;
17762
+ ic.InputfileType = 'fasta';
17763
+ await ic.msaParserCls.loadMsaData(dataStr, 'fasta');
17764
+ };
17765
+ reader.readAsText(file);
17563
17766
  }
17767
+ });
17768
+
17769
+ me.myEventCls.onIds("#" + me.pre + "reload_afmapfile", "click", function(e) { let ic = me.icn3d;
17770
+ e.preventDefault();
17771
+ ic.bInitial = true;
17772
+ thisClass.iniFileLoad();
17564
17773
  let file = $("#" + me.pre + "afmapfile")[0].files[0];
17565
17774
  if(!file) {
17566
17775
  var aaa = 1; //alert("Please select a file before clicking 'Load'");
@@ -17582,14 +17791,7 @@ class Events {
17582
17791
  me.myEventCls.onIds("#" + me.pre + "reload_afmapfilefull", "click", function(e) { let ic = me.icn3d;
17583
17792
  e.preventDefault();
17584
17793
  ic.bInitial = true;
17585
- if(!me.cfg.notebook) dialog.dialog( "close" );
17586
- //close all dialog
17587
- if(!me.cfg.notebook) {
17588
- $(".ui-dialog-content").dialog("close");
17589
- }
17590
- else {
17591
- ic.resizeCanvasCls.closeDialogs();
17592
- }
17794
+ thisClass.iniFileLoad();
17593
17795
  let file = $("#" + me.pre + "afmapfile")[0].files[0];
17594
17796
  if(!file) {
17595
17797
  var aaa = 1; //alert("Please select a file before clicking 'Load'");
@@ -17611,14 +17813,7 @@ class Events {
17611
17813
  me.myEventCls.onIds("#" + me.pre + "reload_urlfile", "click", async function(e) { let ic = me.icn3d;
17612
17814
  e.preventDefault();
17613
17815
  ic.bInitial = true;
17614
- if(!me.cfg.notebook) dialog.dialog( "close" );
17615
- //close all dialog
17616
- if(!me.cfg.notebook) {
17617
- $(".ui-dialog-content").dialog("close");
17618
- }
17619
- else {
17620
- ic.resizeCanvasCls.closeDialogs();
17621
- }
17816
+ thisClass.iniFileLoad();
17622
17817
  let type = $("#" + me.pre + "filetype").val();
17623
17818
  let url = $("#" + me.pre + "urlfile").val();
17624
17819
  ic.inputurl = 'type=' + type + '&url=' + encodeURIComponent(url);
@@ -18493,8 +18688,8 @@ class Events {
18493
18688
 
18494
18689
  me.myEventCls.onIds("#" + me.pre + "saveClustal", "click", function(e) { me.icn3d;
18495
18690
  e.stopImmediatePropagation();
18496
- thisClass.exportMsa('clustal');
18497
- thisClass.setLogCmd('Save alignment in CLUSTALW format', false);
18691
+ thisClass.exportMsa('clustalw');
18692
+ thisClass.setLogCmd('Save alignment in CLUSTALWW format', false);
18498
18693
  });
18499
18694
 
18500
18695
  me.myEventCls.onIds("#" + me.pre + "saveResbyres", "click", function(e) { me.icn3d;
@@ -19364,7 +19559,7 @@ class SetHtml {
19364
19559
 
19365
19560
  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/>";
19366
19561
 
19367
- 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/>";
19562
+ 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'>CLUSTALW</button> <button style='white-space:nowrap; margin-left:20px;' id='" + me.pre + "saveResbyres'>Residue by Residue</button></div><br/>";
19368
19563
 
19369
19564
  sequencesHtml += me.htmlCls.divStr + "alignseqguide" + suffix + "' style='display:none; white-space:normal;' class='icn3d-box'>";
19370
19565
 
@@ -20057,9 +20252,9 @@ class Html {
20057
20252
  this.MENU_WIDTH = 750;
20058
20253
  //The width (in px) that was left empty by the 3D viewer. The default is 20px.
20059
20254
  this.LESSWIDTH = 20;
20060
- this.LESSWIDTH_RESIZE = 20;
20255
+ this.LESSWIDTH_RESIZE = 30; //20;
20061
20256
  //The height (in px) that was left empty by the 3D viewer. The default is 20px.
20062
- this.LESSHEIGHT = 20;
20257
+ this.LESSHEIGHT = (me.cfg.showlogo) ? 60 : 20; //20; // NCBI log is 40px high
20063
20258
 
20064
20259
  // size of 2D cartoons
20065
20260
  this.width2d = 200;
@@ -26620,7 +26815,12 @@ class Scene {
26620
26815
  ic.cams = {
26621
26816
  perspective: ic.perspectiveCamera,
26622
26817
  orthographic: ic.orthographicCamera,
26623
- };
26818
+ };
26819
+
26820
+ if(!me.bNode && ic.opts['effect'] == 'stereo' && !window.icn3duiHash) {
26821
+ ic.effect = ic.effects[options.effect];
26822
+ ic.effect.setSize(ic.container.width(), ic.container.height());
26823
+ }
26624
26824
  };
26625
26825
 
26626
26826
  setVrAr() { let ic = this.icn3d; ic.icn3dui;
@@ -30342,8 +30542,9 @@ class Strand {
30342
30542
  }
30343
30543
  }
30344
30544
 
30345
- // add one extra residue for coils between strands/helix
30346
- if(!isNaN(firstAtom.resi) && ic.pk === 3 && bHighlight === 1 && firstAtom.ss === 'coil') {
30545
+ // add one extra residue for coils between strands/helix if the style is NOT stick, ball and stick, lines, sphere, and dot
30546
+ // if(!isNaN(firstAtom.resi) && ic.pk === 3 && bHighlight === 1 && firstAtom.ss === 'coil') {
30547
+ if(!isNaN(firstAtom.resi) && ic.pk === 3 && bHighlight === 1 && firstAtom.ss === 'coil' && firstAtom.style != 'stick' && firstAtom.style != 'ball and stick' && firstAtom.style != 'lines' && firstAtom.style != 'sphere' && firstAtom.style != 'dot') {
30347
30548
  let residueid = firstAtom.structure + '_' + firstAtom.chain + '_' + (parseInt(firstAtom.resi) - 1).toString();
30348
30549
  if(ic.residues.hasOwnProperty(residueid)) {
30349
30550
  atomsAdjust = me.hashUtilsCls.unionHash(atomsAdjust, me.hashUtilsCls.hash2Atoms(ic.residues[residueid],
@@ -30378,8 +30579,8 @@ class Strand {
30378
30579
  }
30379
30580
  }
30380
30581
 
30381
- // add one extra residue for coils between strands/helix
30382
- if(ic.pk === 3 && bHighlight === 1 && lastAtom.ss === 'coil') {
30582
+ // add one extra residue for coils between strands/helix if the style is NOT stick, ball and stick, lines, sphere, and dot
30583
+ if(ic.pk === 3 && bHighlight === 1 && lastAtom.ss === 'coil' && firstAtom.style != 'stick' && firstAtom.style != 'ball and stick' && firstAtom.style != 'lines' && firstAtom.style != 'sphere' && firstAtom.style != 'dot') {
30383
30584
  let residueid = lastAtom.structure + '_' + lastAtom.chain + '_' + (parseInt(lastAtom.resi) + 1).toString();
30384
30585
  if(ic.residues.hasOwnProperty(residueid)) {
30385
30586
  atomsAdjust = me.hashUtilsCls.unionHash(atomsAdjust, me.hashUtilsCls.hash2Atoms(ic.residues[residueid],
@@ -33229,6 +33430,7 @@ ElectronMap.prototype.fillvoxels = function(atoms, atomlist) { //(int seqinit,in
33229
33430
  }
33230
33431
  else {
33231
33432
  // let index2ori = {};
33433
+ let maxdist = this.maxdist;
33232
33434
  for(let serial in atomlist) {
33233
33435
  let atom = atoms[atomlist[serial]];
33234
33436
 
@@ -33245,11 +33447,11 @@ ElectronMap.prototype.fillvoxels = function(atoms, atomlist) { //(int seqinit,in
33245
33447
  }
33246
33448
 
33247
33449
  // show map near the structure
33248
- for(i = Math.floor(r.x) - this.maxdist, il = Math.ceil(r.x) + this.maxdist; i <= il; ++i) {
33450
+ for(i = Math.floor(r.x) - maxdist, il = Math.ceil(r.x) + maxdist; i <= il; ++i) {
33249
33451
  if(i < 0 || i > this.header.xExtent*this.scaleFactor - 1) continue;
33250
- for(j = Math.floor(r.y) - this.maxdist, jl = Math.ceil(r.y) + this.maxdist; j<= jl; ++j) {
33452
+ for(j = Math.floor(r.y) - maxdist, jl = Math.ceil(r.y) + maxdist; j<= jl; ++j) {
33251
33453
  if(j < 0 || j > this.header.yExtent*this.scaleFactor - 1) continue;
33252
- for(k = Math.floor(r.z) - this.maxdist, kl = Math.ceil(r.z) + this.maxdist; k<= kl; ++k) {
33454
+ for(k = Math.floor(r.z) - maxdist, kl = Math.ceil(r.z) + maxdist; k<= kl; ++k) {
33253
33455
  if(k < 0 || k > this.header.zExtent*this.scaleFactor - 1) continue;
33254
33456
  let index = i * widthHeight + j * height + k;
33255
33457
  indexArray.push(index);
@@ -33258,6 +33460,16 @@ ElectronMap.prototype.fillvoxels = function(atoms, atomlist) { //(int seqinit,in
33258
33460
  }
33259
33461
  }
33260
33462
 
33463
+ // show all
33464
+ // for(i = 0; i < this.pLength; ++i) {
33465
+ // for(j = 0; j < this.pWidth; ++j) {
33466
+ // for(k = 0; k < this.pHeight; ++k) {
33467
+ // let index = i * widthHeight + j * height + k;
33468
+ // indexArray.push(index);
33469
+ // }
33470
+ // }
33471
+ // }
33472
+
33261
33473
  for(i = 0, il = indexArray.length; i < il; ++i) {
33262
33474
  let index = indexArray[i];
33263
33475
 
@@ -34519,6 +34731,7 @@ class ApplyDisplay {
34519
34731
  for(let residueid in singletonResidueHash) {
34520
34732
  // get calpha
34521
34733
  let calpha = ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.residues[residueid]);
34734
+ let sideAtom = ic.firstAtomObjCls.getFirstAtomObj(ic.selectionCls.getSideAtoms(ic.residues[residueid]));
34522
34735
  let atom = calpha;
34523
34736
 
34524
34737
  let prevResidueid = atom.structure + '_' + atom.chain + '_' + (parseInt(atom.resi) - 1).toString();
@@ -34535,7 +34748,7 @@ class ApplyDisplay {
34535
34748
  }
34536
34749
  else if( (atom.style === 'ribbon' && atom.ss === 'coil') || (atom.style === 'strand' && atom.ss === 'coil') || atom.style === 'o3 trace' || atom.style === 'schematic' || atom.style === 'c alpha trace' || atom.style === 'b factor tube' || (atom.style === 'cylinder and plate' && atom.ss !== 'helix') ) {
34537
34750
  // do not add extra residue if the side chain is shown
34538
- if(calpha !== undefined && calpha.style2 !== undefined && calpha.style2 !== 'nothing') continue;
34751
+ if(sideAtom !== undefined && sideAtom.style2 !== undefined && sideAtom.style2 !== 'nothing') continue;
34539
34752
 
34540
34753
  let bAddResidue = false;
34541
34754
  // add the next residue with same style
@@ -34570,7 +34783,7 @@ class ApplyDisplay {
34570
34783
  }
34571
34784
  else if( (atom.style === 'ribbon' && atom.ss !== 'coil' && atom.ssend) || (atom.style === 'strand' && atom.ss !== 'coil' && atom.ssend)) {
34572
34785
  // do not add extra residue if the side chain is shown
34573
- if(calpha !== undefined && calpha.style2 !== undefined && calpha.style2 !== 'nothing') continue;
34786
+ if(sideAtom !== undefined && sideAtom.style2 !== undefined && sideAtom.style2 !== 'nothing') continue;
34574
34787
 
34575
34788
  let bAddResidue = false;
34576
34789
  // add the next residue with same style
@@ -37455,11 +37668,18 @@ class Alternate {
37455
37668
  }
37456
37669
 
37457
37670
  if(ic.scene) {
37671
+ ic.renderer.clear();
37672
+
37458
37673
  // https://github.com/gkjohnson/three-gpu-pathtracer/blob/main/example/basic.js
37459
37674
  ic.renderer.outputEncoding = THREE.sRGBEncoding;
37460
37675
  //ic.renderer.outputEncoding = THREE.LinearEncoding
37461
37676
 
37462
- ic.renderer.render(ic.scene, cam);
37677
+ if(ic.opts['effect'] == 'stereo' && !window.icn3duiHash) {
37678
+ ic.effect.render(ic.scene, cam);
37679
+ }
37680
+ else {
37681
+ ic.renderer.render(ic.scene, cam);
37682
+ }
37463
37683
  }
37464
37684
  }
37465
37685
 
@@ -51836,13 +52056,20 @@ class ShowInter {
51836
52056
  }
51837
52057
  // do not change the set of displaying atoms
51838
52058
  //ic.dAtoms = me.hashUtilsCls.cloneHash(ic.atoms);
51839
- let commandname, commanddesc;
52059
+ let commandname, commanddesc, commandname2;
51840
52060
  let firstAtom = ic.firstAtomObjCls.getFirstAtomObj(atomlistTarget);
52061
+
51841
52062
  if(firstAtom !== undefined) {
51842
52063
  commandname = "sphere." + firstAtom.chain + ":" + me.utilsCls.residueName2Abbr(firstAtom.resn.substr(0, 3)).trim() + firstAtom.resi + "-" + radius + "A";
51843
- if(bInteraction) commandname = "interactions." + firstAtom.chain + ":" + me.utilsCls.residueName2Abbr(firstAtom.resn.substr(0, 3)).trim() + firstAtom.resi + "-" + $("#" + ic.pre + "contactthreshold").val() + "A";
52064
+ //sometimes firstAtom.resi changed, thus we add a general name
52065
+ commandname2 = "sphere-" + radius + "A";
52066
+ if(bInteraction) {
52067
+ commandname = "interactions." + firstAtom.chain + ":" + me.utilsCls.residueName2Abbr(firstAtom.resn.substr(0, 3)).trim() + firstAtom.resi + "-" + $("#" + ic.pre + "contactthreshold").val() + "A";
52068
+ commandname2 = "interactions-" + $("#" + ic.pre + "contactthreshold").val() + "A";
52069
+ }
51844
52070
  commanddesc = commandname;
51845
52071
  ic.selectionCls.addCustomSelection(residueArray, commandname, commanddesc, select, true);
52072
+ ic.selectionCls.addCustomSelection(residueArray, commandname2, commanddesc, select, true);
51846
52073
  }
51847
52074
  ic.selectionCls.saveSelectionIfSelected();
51848
52075
  ic.drawCls.draw();
@@ -54020,6 +54247,7 @@ class ChainalignParser {
54020
54247
 
54021
54248
  ajaxArray.push(alignAjax);
54022
54249
  indexArray.push(index - 1);
54250
+ mmdbid_q = chainidArray[index].substr(0, chainidArray[index].indexOf('_'));
54023
54251
  struArray.push(mmdbid_q);
54024
54252
  }
54025
54253
 
@@ -54048,7 +54276,8 @@ class ChainalignParser {
54048
54276
  let mmdbid_q = struArray[i];
54049
54277
  let index = indexArray[i];
54050
54278
 
54051
- let bEqualMmdbid = (mmdbid_q == mmdbid_t);
54279
+ // let bEqualMmdbid = (mmdbid_q == mmdbid_t);
54280
+ let bEqualMmdbid = (mmdbid_q.substr(0,4) == mmdbid_t.substr(0,4));
54052
54281
  let bEqualChain = false;
54053
54282
 
54054
54283
  let queryData = {}; // check whether undefined
@@ -54298,7 +54527,7 @@ class ChainalignParser {
54298
54527
 
54299
54528
  transformStructure(mmdbid, index, alignType, bForce) { let ic = this.icn3d, me = ic.icn3dui;
54300
54529
  let chainidArray = ic.structures[mmdbid];
54301
-
54530
+
54302
54531
  for(let i = 0, il = chainidArray.length; i < il; ++i) {
54303
54532
  for(let serial in ic.chains[chainidArray[i]]) {
54304
54533
  let atm = ic.atoms[serial];
@@ -54430,6 +54659,26 @@ class ChainalignParser {
54430
54659
  return chainidArray;
54431
54660
  }
54432
54661
 
54662
+ addPostfixForStructureids(structArray) { let ic = this.icn3d; ic.icn3dui;
54663
+ let struct2cnt = {};
54664
+ for(let i = 0, il = structArray.length; i < il; ++i) {
54665
+ let struct = structArray[i].toUpperCase();
54666
+
54667
+ if(!struct2cnt.hasOwnProperty(struct)) {
54668
+ struct2cnt[struct] = 1;
54669
+ }
54670
+ else {
54671
+ ++struct2cnt[struct];
54672
+ }
54673
+
54674
+ struct = (struct2cnt[struct] == 1) ? struct : struct + struct2cnt[struct];
54675
+
54676
+ structArray[i] = struct;
54677
+ }
54678
+
54679
+ return structArray;
54680
+ }
54681
+
54433
54682
  async downloadChainalignment(chainalign) { let ic = this.icn3d, me = ic.icn3dui;
54434
54683
  let thisClass = this;
54435
54684
 
@@ -54471,6 +54720,7 @@ class ChainalignParser {
54471
54720
 
54472
54721
  ic.afChainIndexHash = {};
54473
54722
  ic.pdbChainIndexHash = {};
54723
+
54474
54724
  for(let index = 1, indexLen = alignArray.length; index < indexLen; ++index) {
54475
54725
  let pos2 = alignArray[index].indexOf('_');
54476
54726
  let mmdbid_q_tmp = alignArray[index].substr(0, pos2).toUpperCase();
@@ -54578,7 +54828,8 @@ class ChainalignParser {
54578
54828
 
54579
54829
  if(queryData !== undefined && JSON.stringify(queryData).indexOf('Oops there was a problem') === -1
54580
54830
  ) {
54581
- ic.mmdbidArray.push(mmdbid_q);
54831
+ // ic.mmdbidArray.push(mmdbid_q);
54832
+ ic.mmdbidArray.push(mmdbid_q.substr(0,4));
54582
54833
  queryDataArray.push(queryData);
54583
54834
  }
54584
54835
  else {
@@ -54617,7 +54868,8 @@ class ChainalignParser {
54617
54868
  // let align = (me.bNode) ? dataArray[index2 - missedChainCnt] : dataArray[index2 - missedChainCnt].value;//[0];
54618
54869
  let align = dataArray[index2 - missedChainCnt].value;//[0];
54619
54870
 
54620
- let bEqualMmdbid = (mmdbid_q == mmdbid_t);
54871
+ // let bEqualMmdbid = (mmdbid_q == mmdbid_t);
54872
+ let bEqualMmdbid = (mmdbid_q.substr(0,4) == mmdbid_t.substr(0,4));
54621
54873
  let bEqualChain = (chain_q == chain_t);
54622
54874
 
54623
54875
  me.htmlCls.clickMenuCls.setLogCmd("Align " + mmdbid_t + " with " + mmdbid_q, false);
@@ -54788,15 +55040,14 @@ class ChainalignParser {
54788
55040
 
54789
55041
  let structArray = [];
54790
55042
 
54791
- for(let i = 0, il = structArrayTmp.length; i < il; ++i) {
54792
- let id = structArrayTmp[i].toUpperCase();
54793
- // sometimes we want to load same structure multiple times
54794
- if(!ic.structures.hasOwnProperty(id) && structArray.indexOf(id) == -1) {
54795
- structArray.push(structArrayTmp[i]);
54796
- }
54797
- else {
54798
- // only when bNoDuplicate is undefined/false, it's allowed to load multiple copies of the same structure
54799
- if(!bNoDuplicate) structArray.push(structArrayTmp[i] + me.htmlCls.postfix);
55043
+ // only when bNoDuplicate is undefined/false, it's allowed to load multiple copies of the same structure
55044
+ if(!bNoDuplicate) {
55045
+ structArray = this.addPostfixForStructureids(structArrayTmp);
55046
+ }
55047
+ else {
55048
+ for(let i = 0, il = structArrayTmp.length; i < il; ++i) {
55049
+ let id = structArrayTmp[i].toUpperCase();
55050
+ if(!ic.structures.hasOwnProperty(id)) structArray.push(structArrayTmp[i]);
54800
55051
  }
54801
55052
  }
54802
55053
 
@@ -58791,6 +59042,283 @@ class XyzParser {
58791
59042
  }
58792
59043
  }
58793
59044
 
59045
+ /**
59046
+ * @author Jiyao Wang <wangjiy@ncbi.nlm.nih.gov> / https://github.com/ncbi/icn3d
59047
+ */
59048
+
59049
+ class MsaParser {
59050
+ constructor(icn3d) {
59051
+ this.icn3d = icn3d;
59052
+ }
59053
+
59054
+ async loadMsaData(data, type) { let ic = this.icn3d, me = ic.icn3dui;
59055
+ let bResult = await this.loadMsaSeqData(data, type);
59056
+
59057
+ if(me.cfg.align === undefined && Object.keys(ic.structures).length == 1) {
59058
+ $("#" + ic.pre + "alternateWrapper").hide();
59059
+ }
59060
+
59061
+ let typeStr = type.toUpperCase();
59062
+
59063
+ if(!bResult) {
59064
+ var aaa = 1; //alert('The ' + typeStr + ' file has the wrong format...');
59065
+ }
59066
+ else {
59067
+ // retrieve the structures
59068
+ me.cfg.bu = 0; // show all chains
59069
+ await ic.chainalignParserCls.downloadMmdbAf(ic.struArray.join(','));
59070
+ me.htmlCls.clickMenuCls.setLogCmd('load mmdbaf0 ' + ic.struArray.join(','), true);
59071
+
59072
+ // get the position of the first MSA residue in the full sequence
59073
+ let startPosArray = [];
59074
+ for(let i = 0, il = ic.inputChainidArray.length; i < il; ++i) {
59075
+ let chainid = ic.inputChainidArray[i];
59076
+ let inputSeqNoGap = ic.inputSeqArray[i].replace(/-/g, '');
59077
+
59078
+ // get the full seq
59079
+ let fullSeq = '';
59080
+ for(let j = 0, jl = ic.chainsSeq[chainid].length; j < jl; ++j) {
59081
+ fullSeq += ic.chainsSeq[chainid][j].name;
59082
+ }
59083
+
59084
+ // find the starting position of "inputSeq" in "fullSeq"
59085
+ let pos = fullSeq.toUpperCase().indexOf(inputSeqNoGap.substr(0, 20).toUpperCase());
59086
+ if(pos == -1) {
59087
+ console.log("The sequence of the aligned chain " + chainid + " (" + inputSeqNoGap.toUpperCase() + ") is different from the sequence from the structure (" + fullSeq.toUpperCase() + "), and is thus not aligned correctly...");
59088
+ pos = 0;
59089
+ }
59090
+ startPosArray.push(pos);
59091
+ }
59092
+
59093
+ // define residue mapping
59094
+ // The format is ": "-separated pairs: "1,5,10-50 | 1,5,10-50: 2,6,11-51 | 1,5,10-50"
59095
+ let predefinedres = '';
59096
+
59097
+ let chainid1 = ic.inputChainidArray[0], inputSeq1 = ic.inputSeqArray[0], pos1 = startPosArray[0];
59098
+ // loop through 2nd and forward
59099
+ for(let i = 1, il = ic.inputChainidArray.length; i < il; ++i) {
59100
+ let chainid2 = ic.inputChainidArray[i];
59101
+ let inputSeq2 = ic.inputSeqArray[i];
59102
+ let pos2 = startPosArray[i];
59103
+
59104
+ let index1 = pos1, index2 = pos2;
59105
+ let resiArray1 = [], resiArray2 = [];
59106
+ for(let j = 0, jl = inputSeq2.length; j < jl; ++j) {
59107
+ if(inputSeq1[j] != '-' && inputSeq2[j] != '-' && ic.chainsSeq[chainid1][index1] && ic.chainsSeq[chainid2][index2]) {
59108
+ let resi1 = ic.chainsSeq[chainid1][index1].resi;
59109
+ let resi2 = ic.chainsSeq[chainid2][index2].resi;
59110
+ if(ic.residues[chainid1 + '_' + resi1] && ic.residues[chainid2 + '_' + resi2]) {
59111
+ resiArray1.push(ic.chainsSeq[chainid1][index1].resi);
59112
+ resiArray2.push(ic.chainsSeq[chainid2][index2].resi);
59113
+ }
59114
+ }
59115
+
59116
+ if(inputSeq1[j] != '-') ++index1;
59117
+ if(inputSeq2[j] != '-') ++index2;
59118
+ }
59119
+ let resiRangeStr1 = ic.resid2specCls.resi2range(resiArray1, true);
59120
+ let resiRangeStr2 = ic.resid2specCls.resi2range(resiArray2, true);
59121
+
59122
+ predefinedres += resiRangeStr1 + ' | ' + resiRangeStr2;
59123
+ if(i < il -1) predefinedres += ': ';
59124
+ }
59125
+
59126
+ // realign based on residue by residue
59127
+ let alignment_final = ic.inputChainidArray.join(',');
59128
+
59129
+ if(predefinedres && (alignment_final.split(',').length - 1) != predefinedres.split(': ').length) {
59130
+ var aaa = 1; //alert("Please make sure the number of chains and the lines of predefined residues are the same...");
59131
+ return;
59132
+ }
59133
+
59134
+ me.cfg.resdef = predefinedres.replace(/:/gi, ';');
59135
+
59136
+ let bRealign = true, bPredefined = true;
59137
+ let chainidArray = alignment_final.split(',');
59138
+ await ic.realignParserCls.realignChainOnSeqAlign(undefined, chainidArray, bRealign, bPredefined);
59139
+
59140
+ me.htmlCls.clickMenuCls.setLogCmd("realign predefined " + alignment_final + " " + predefinedres, true);
59141
+
59142
+
59143
+ ic.opts['color'] = 'identity';
59144
+ ic.setColorCls.setColorByOptions(ic.opts, ic.hAtoms);
59145
+ me.htmlCls.clickMenuCls.setLogCmd("color identity", true);
59146
+
59147
+ // show selection
59148
+ ic.selectionCls.showSelection();
59149
+ me.htmlCls.clickMenuCls.setLogCmd("show selection", true);
59150
+ }
59151
+ }
59152
+
59153
+ async loadMsaSeqData(data, type) { let ic = this.icn3d; ic.icn3dui;
59154
+ let lines = data.split(/\r?\n|\r/);
59155
+ if(lines.length < 2) return false;
59156
+
59157
+ ic.init();
59158
+
59159
+ ic.molTitle = "";
59160
+
59161
+ let seqHash = {};
59162
+
59163
+ let bStart = false, bSecBlock = false, chainid = '', seq = '', bFound = false;
59164
+
59165
+ if(type == 'clustalw' && lines[0].substr(0,7) != 'CLUSTAL') { // CLUSTAL W or CLUSTALW
59166
+ return false;
59167
+ }
59168
+
59169
+ let startLineNum = (type == 'clustalw') ? 1 : 0;
59170
+
59171
+ // 1. parse input msa
59172
+ for(let i = startLineNum, il = lines.length; i < il; ++i) {
59173
+ let line = lines[i].trim();
59174
+ if(line === '') {
59175
+ if(bStart) bSecBlock = true;
59176
+ bStart = false;
59177
+ continue;
59178
+ }
59179
+
59180
+ if(!bStart) { // first line
59181
+ if(type == 'fasta' && line.substr(0,1) != '>') {
59182
+ return false;
59183
+ }
59184
+ bStart = true;
59185
+ }
59186
+
59187
+ if(type == 'clustalw') {
59188
+ if(line.substr(0, 1) != ' ' && line.substr(0, 1) != '\t') {
59189
+ let chainid_seq = line.split(/\s+/);
59190
+ let idArray = chainid_seq[0].split('|');
59191
+ let result = this.getChainid(idArray, bStart && !bSecBlock);
59192
+ bFound = result.bFound;
59193
+ chainid = result.chainid;
59194
+
59195
+ if(bFound) {
59196
+ if(!seqHash.hasOwnProperty(chainid)) {
59197
+ seqHash[chainid] = chainid_seq[1];
59198
+ }
59199
+ else {
59200
+ seqHash[chainid] += chainid_seq[1];
59201
+ }
59202
+ }
59203
+ }
59204
+ }
59205
+ else if(type == 'fasta') {
59206
+ if(line.substr(0,1) == ">") {
59207
+ // add the previous seq
59208
+ if(chainid && seq && bFound) seqHash[chainid] = seq;
59209
+ chainid = '';
59210
+ seq = '';
59211
+
59212
+ let pos = line.indexOf(' ');
59213
+ let idArray = line.substr(1, pos).split('|');
59214
+
59215
+ if(idArray.length == 1) {
59216
+ chainid = idArray[0];
59217
+ }
59218
+ else {
59219
+ let result = this.getChainid(idArray, true);
59220
+ bFound = result.bFound;
59221
+ chainid = result.chainid;
59222
+ }
59223
+ }
59224
+ else {
59225
+ seq += line;
59226
+ }
59227
+ }
59228
+ }
59229
+
59230
+ // add the last seq
59231
+ if(type == 'fasta' && chainid && seq && bFound) seqHash[chainid] = seq;
59232
+
59233
+ // 2. get the PDB ID or RefSeqID or AlphaFold ID
59234
+ ic.inputChainidArray = [];
59235
+ ic.inputSeqArray = [];
59236
+ ic.struArray = [];
59237
+
59238
+ // find the tempate where the first residue is not gap
59239
+ let template = '';
59240
+ for(let chainid in seqHash) {
59241
+ let seq = seqHash[chainid];
59242
+ if(seq.substr(0,1) != '-') {
59243
+ template = chainid;
59244
+ await this.processOneChain(chainid, seqHash);
59245
+ break;
59246
+ }
59247
+ }
59248
+ if(!template) template = Object.keys(seqHash)[0];
59249
+
59250
+ for(let chainid in seqHash) {
59251
+ if(chainid != template) await this.processOneChain(chainid, seqHash);
59252
+ }
59253
+
59254
+ return true;
59255
+ }
59256
+
59257
+ async processOneChain(chainid, seqHash) { let ic = this.icn3d, me = ic.icn3dui;
59258
+ ic.inputSeqArray.push(seqHash[chainid]);
59259
+ // ic.inputSeqArray.push(seqHash[chainid].replace(/-/g, '')); // remove the gaps in seq
59260
+
59261
+ if(chainid.lastIndexOf('_') == 2) { // refseq ID
59262
+ // convert refseq to uniprot id
59263
+ let url = me.htmlCls.baseUrl + "vastdyn/vastdyn.cgi?refseq2uniprot=" + chainid;
59264
+
59265
+ let data = await me.getAjaxPromise(url, 'jsonp', false, 'The protein accession ' + chainid + ' can not be mapped to AlphaFold UniProt ID...');
59266
+ if(data && data.uniprot) {
59267
+ if(!ic.uniprot2acc) ic.uniprot2acc = {};
59268
+ let uniprot = data.uniprot;
59269
+ ic.uniprot2acc[uniprot] = chainid;
59270
+ ic.struArray.push(uniprot);
59271
+ ic.inputChainidArray.push(uniprot + '_A');
59272
+ }
59273
+ else {
59274
+ console.log('The accession ' + refseqid + ' can not be mapped to AlphaFold UniProt ID. It will be treated as a UniProt ID instead.');
59275
+ ic.struArray.push(chainid);
59276
+ ic.inputChainidArray.push(chainid + '_A');
59277
+ }
59278
+ }
59279
+ else if(chainid.indexOf('_') != -1) { // PDB ID
59280
+ let stru = chainid.substr(0, chainid.indexOf('_')).substr(0, 4);
59281
+ ic.struArray.push(stru);
59282
+ ic.inputChainidArray.push(chainid);
59283
+ }
59284
+ else if(chainid.length > 5) { // UniProt ID
59285
+ ic.struArray.push(chainid);
59286
+ ic.inputChainidArray.push(chainid + '_A');
59287
+ }
59288
+ }
59289
+
59290
+ getChainid(idArray, bWarning) { let ic = this.icn3d; ic.icn3dui;
59291
+ let bFound = false;
59292
+ let chainid = idArray[0];
59293
+
59294
+ for(let j = 0, jl = idArray.length; j < jl; ++j) {
59295
+ if(idArray[j] == 'pdb') {
59296
+ chainid = idArray[j+1] + '_' + idArray[j+2];
59297
+ bFound = true;
59298
+ break;
59299
+ }
59300
+ else if(idArray[j] == 'ref') { // refseq
59301
+ let refseq = idArray[j+1].split('.')[0];
59302
+ chainid = refseq; // + '_A';
59303
+ bFound = true;
59304
+ break;
59305
+ }
59306
+ else if(idArray[j] == 'sp' || idArray[j] == 'tr') { // uniprot
59307
+ let uniprot = idArray[j+1];
59308
+ chainid = uniprot;
59309
+ bFound = true;
59310
+ break;
59311
+ }
59312
+ }
59313
+
59314
+ if(!bFound && bWarning) {
59315
+ var aaa = 1; //alert("The sequence ID " + idArray.join('|') + " does not have the correctly formatted PDB, UniProt or RefSeq ID...");
59316
+ }
59317
+
59318
+ return {chainid: chainid, bFound: bFound};
59319
+ }
59320
+ }
59321
+
58794
59322
  /**
58795
59323
  * @author Jiyao Wang <wangjiy@ncbi.nlm.nih.gov> / https://github.com/ncbi/icn3d
58796
59324
  */
@@ -58932,7 +59460,7 @@ class RealignParser {
58932
59460
  // If rmsd from vastsrv is too large, realign the chains
58933
59461
  //if(me.cfg.chainalign && !me.cfg.usepdbnum && me.cfg.resdef && rmsd > 5) {
58934
59462
  // redo algnment only for VAST serv page
58935
- if(!me.cfg.usepdbnum && me.cfg.resdef && rmsd > 5) {
59463
+ if(!me.cfg.usepdbnum && me.cfg.resdef && rmsd > 5 && me.cfg.chainalign) {
58936
59464
  console.log("RMSD from VAST is larger than 5. Realign the chains with TM-align.");
58937
59465
  //let nameArray = me.cfg.chainalign.split(',');
58938
59466
  let nameArray = Object.keys(chainidHash);
@@ -59388,7 +59916,8 @@ let resRangeArray = (me.cfg.resrange) ? decodeURIComponent(me.cfg.resrange).spli
59388
59916
  let predefinedResArray, predefinedResPair;
59389
59917
 
59390
59918
  if(bPredefined) {
59391
- predefinedResArray = decodeURIComponent(me.cfg.resdef).trim().replace(/\+/gi, ' ').split(': ');
59919
+ // predefinedResArray = decodeURIComponent(me.cfg.resdef).trim().replace(/\+/gi, ' ').split(': ');
59920
+ predefinedResArray = decodeURIComponent(me.cfg.resdef).trim().replace(/\+/gi, ' ').split('; ');
59392
59921
 
59393
59922
  if(predefinedResArray.length != chainidArray.length - 1) {
59394
59923
  var aaa = 1; //alert("Please make sure the number of chains and the lines of predefined residues are the same...");
@@ -59665,7 +60194,7 @@ class DensityCifParser {
59665
60194
  let thisClass = this;
59666
60195
 
59667
60196
  let url;
59668
- let detail = (me.utilsCls.isMobile() || me.cfg.notebook) ? 2 : 4; //0 : 4;
60197
+ let detail = (me.utilsCls.isMobile() || me.cfg.notebook) ? 0 : 4; // max 6
59669
60198
 
59670
60199
  //https://www.ebi.ac.uk/pdbe/densities/doc.html
59671
60200
  if(type == '2fofc' || type == 'fofc') {
@@ -59676,6 +60205,7 @@ class DensityCifParser {
59676
60205
  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;
59677
60206
  }
59678
60207
  else if(type == 'em') {
60208
+ detail = (me.utilsCls.isMobile() || me.cfg.notebook) ? 0: 5; // max 6
59679
60209
  url = "https://www.ebi.ac.uk/pdbe/densities/emd/" + emd.toLowerCase() + "/cell?detail=" + detail;
59680
60210
  }
59681
60211
 
@@ -61035,7 +61565,8 @@ class ParserUtils {
61035
61565
  ic.rmsd_supr = me.rmsdSuprCls.getRmsdSuprCls(coordsFrom, coordsTo, n);
61036
61566
 
61037
61567
  // apply matrix for each atom
61038
- if(ic.rmsd_supr.rot !== undefined && ic.rmsd_supr.rmsd < 0.1) {
61568
+ // if(ic.rmsd_supr.rot !== undefined && ic.rmsd_supr.rmsd < 0.1) {
61569
+ if(ic.rmsd_supr.rot !== undefined && ic.rmsd_supr.rmsd < 1) { // 6M17 has some coordinates change and rmsd is 0.3
61039
61570
  let rot = ic.rmsd_supr.rot;
61040
61571
  let centerFrom = ic.rmsd_supr.trans1;
61041
61572
  let centerTo = ic.rmsd_supr.trans2;
@@ -61249,11 +61780,12 @@ class ParserUtils {
61249
61780
 
61250
61781
  // set defined sets before loadScript
61251
61782
  if(ic.bInitial) {
61252
- if(me.cfg.mobilemenu) {
61253
- me.htmlCls.shownMenus = me.hashUtilsCls.cloneHash(me.htmlCls.simpleMenus);
61254
- let bNoSave = true;
61255
- me.htmlCls.clickMenuCls.applyShownMenus(bNoSave);
61256
- }
61783
+ // if(me.cfg.mobilemenu) {
61784
+ // me.htmlCls.shownMenus = me.hashUtilsCls.cloneHash(me.htmlCls.simpleMenus);
61785
+ // let bNoSave = true;
61786
+ // me.htmlCls.clickMenuCls.applyShownMenus(bNoSave);
61787
+ // }
61788
+
61257
61789
  // else {
61258
61790
  // me.htmlCls.shownMenus = me.hashUtilsCls.cloneHash(me.htmlCls.allMenus);
61259
61791
  // me.htmlCls.clickMenuCls.applyShownMenus();
@@ -61310,6 +61842,10 @@ class ParserUtils {
61310
61842
  if(me.cfg.closepopup || me.cfg.imageonly) {
61311
61843
  ic.resizeCanvasCls.closeDialogs();
61312
61844
  }
61845
+
61846
+ if(!me.cfg.showlogo) {
61847
+ $("#ncbi_logo").hide();
61848
+ }
61313
61849
  }
61314
61850
  else {
61315
61851
  ic.hlUpdateCls.updateHlAll();
@@ -63725,7 +64261,7 @@ class SetSeqAlign {
63725
64261
 
63726
64262
  setMsaFormat(chainidArray) { let ic = this.icn3d; ic.icn3dui;
63727
64263
  //set MSA
63728
- let fastaFormat = '', clustalFormat = 'CLUSTALW\n\n', resbyresFormat = '';
64264
+ let fastaFormat = '', clustalwFormat = 'CLUSTALWW\n\n', resbyresFormat = '';
63729
64265
  let chainArrayClustal = [];
63730
64266
 
63731
64267
  let consArray = [], resiArrayTemplate = [];
@@ -63734,8 +64270,8 @@ class SetSeqAlign {
63734
64270
  let chainid = chainidArray[i];
63735
64271
  fastaFormat += '>' + chainid + '\n';
63736
64272
 
63737
- let clustalArray = [];
63738
- let clustalLine = chainid.padEnd(20, ' ');
64273
+ let clustalwArray = [];
64274
+ let clustalwLine = chainid.padEnd(20, ' ');
63739
64275
  let consLine = ''.padEnd(20, ' ');
63740
64276
 
63741
64277
  let resiArrayTarget = [], resiArrayQuery = [];
@@ -63744,7 +64280,7 @@ class SetSeqAlign {
63744
64280
  for(let j = 0, jl = ic.alnChainsSeq[chainid].length; j < jl; ++j) {
63745
64281
  let resn = ic.alnChainsSeq[chainid][j].resn;
63746
64282
  fastaFormat += resn;
63747
- clustalLine += resn;
64283
+ clustalwLine += resn;
63748
64284
  if(i == il - 1) {
63749
64285
  let alignedClass = ic.alnChainsSeq[chainid][j].class;
63750
64286
  if(alignedClass == 'icn3d-cons') {
@@ -63763,7 +64299,8 @@ class SetSeqAlign {
63763
64299
  resiArrayTemplate.push(ic.alnChainsSeq[chainid][j].resi);
63764
64300
  }
63765
64301
  else {
63766
- if(ic.alnChainsSeq[chainid][j].aligned) {
64302
+ // if(ic.alnChainsSeq[chainid][j].aligned) {
64303
+ if(ic.alnChainsSeq[chainid][j].aligned && ic.alnChainsSeq[chainidTemplate][j] && ic.alnChainsSeq[chainid][j]) {
63767
64304
  resiArrayTarget.push(ic.alnChainsSeq[chainidTemplate][j].resi);
63768
64305
  resiArrayQuery.push(ic.alnChainsSeq[chainid][j].resi);
63769
64306
  }
@@ -63773,9 +64310,9 @@ class SetSeqAlign {
63773
64310
 
63774
64311
  if(cnt % 60 == 0) {
63775
64312
  fastaFormat += '\n';
63776
- clustalLine += ' ' + String(parseInt(cnt / 60) * 60);
63777
- clustalArray.push(clustalLine);
63778
- clustalLine = chainid.padEnd(20, ' ');
64313
+ clustalwLine += ' ' + String(parseInt(cnt / 60) * 60);
64314
+ clustalwArray.push(clustalwLine);
64315
+ clustalwLine = chainid.padEnd(20, ' ');
63779
64316
 
63780
64317
  if(i == il - 1) {
63781
64318
  consArray.push(consLine);
@@ -63786,7 +64323,7 @@ class SetSeqAlign {
63786
64323
 
63787
64324
  // add last line
63788
64325
  if(cnt % 60 != 0) {
63789
- clustalArray.push(clustalLine);
64326
+ clustalwArray.push(clustalwLine);
63790
64327
  if(i == il - 1) {
63791
64328
  consArray.push(consLine);
63792
64329
  }
@@ -63794,7 +64331,7 @@ class SetSeqAlign {
63794
64331
 
63795
64332
  fastaFormat += '\n';
63796
64333
 
63797
- chainArrayClustal.push(clustalArray);
64334
+ chainArrayClustal.push(clustalwArray);
63798
64335
  if(i == il - 1) chainArrayClustal.push(consArray);
63799
64336
 
63800
64337
  // residue by residue
@@ -63804,23 +64341,23 @@ class SetSeqAlign {
63804
64341
  if(i > 0) resbyresFormat += resiRangeStr1 + ' | ' + resiRangeStr2 + '\n';
63805
64342
  }
63806
64343
 
63807
- // CLUSTALW
64344
+ // CLUSTALWW
63808
64345
  for(let j = 0, jl = chainArrayClustal[0].length; j < jl; ++j) {
63809
64346
  for(let i = 0, il = chainArrayClustal.length; i < il; ++i) {
63810
- clustalFormat += chainArrayClustal[i][j] + '\n';
64347
+ clustalwFormat += chainArrayClustal[i][j] + '\n';
63811
64348
  }
63812
- clustalFormat += '\n';
64349
+ clustalwFormat += '\n';
63813
64350
  }
63814
64351
 
63815
64352
  // seq MSA
63816
64353
  if(!ic.msa) ic.msa = {};
63817
64354
 
63818
64355
  if(!ic.msa['fasta']) ic.msa['fasta'] = [];
63819
- if(!ic.msa['clustal']) ic.msa['clustal'] = [];
64356
+ if(!ic.msa['clustalw']) ic.msa['clustalw'] = [];
63820
64357
  if(!ic.msa['resbyres']) ic.msa['resbyres'] = [];
63821
64358
 
63822
64359
  ic.msa['fasta'].push(fastaFormat);
63823
- ic.msa['clustal'].push(clustalFormat);
64360
+ ic.msa['clustalw'].push(clustalwFormat);
63824
64361
  ic.msa['resbyres'].push(resbyresFormat);
63825
64362
  }
63826
64363
  }
@@ -66576,6 +67113,12 @@ class ApplyCommand {
66576
67113
  else if(command == 'set slab off') {
66577
67114
  ic.opts['slab'] = 'no';
66578
67115
  }
67116
+ else if(command == 'stereo on') {
67117
+ ic.opts['effect'] = 'stereo';
67118
+ }
67119
+ else if(command == 'stereo off') {
67120
+ ic.opts['effect'] = 'none';
67121
+ }
66579
67122
  else if(command == 'set assembly on') {
66580
67123
  ic.bAssembly = true;
66581
67124
  }
@@ -68649,16 +69192,26 @@ class DefinedSets {
68649
69192
  } // outer for
68650
69193
  }
68651
69194
 
68652
- setHAtomsFromSets(nameArray, type) { let ic = this.icn3d, me = ic.icn3dui;
69195
+ setHAtomsFromSets(nameArray, type) { let ic = this.icn3d; ic.icn3dui;
68653
69196
  for(let i = 0; i < nameArray.length; ++i) {
68654
69197
  let selectedSet = nameArray[i];
68655
69198
 
68656
- if((ic.defNames2Atoms === undefined || !ic.defNames2Atoms.hasOwnProperty(selectedSet)) &&(ic.defNames2Residues === undefined || !ic.defNames2Residues.hasOwnProperty(selectedSet)) ) continue;
69199
+ this.setHAtomsFromSets_base(selectedSet, type);
68657
69200
 
69201
+ // sometimes the "resi" changed and thus the name changed
69202
+ //"sphere." + firstAtom.chain + ":" + me.utilsCls.residueName2Abbr(firstAtom.resn.substr(0, 3)).trim() + firstAtom.resi + "-" + radius + "A";
69203
+ if(Object.keys(ic.hAtoms).length == 0 && (selectedSet.split('.')[0] == 'sphere' || selectedSet.split('.')[0] == 'interactions')) {
69204
+ let pos = selectedSet.lastIndexOf('-');
69205
+ selectedSet = selectedSet.split('.')[0] + selectedSet.substr(pos);
69206
+ this.setHAtomsFromSets_base(selectedSet, type);
69207
+ }
69208
+ } // outer for
69209
+ }
69210
+
69211
+ setHAtomsFromSets_base(selectedSet, type) { let ic = this.icn3d, me = ic.icn3dui;
68658
69212
  if(ic.defNames2Atoms !== undefined && ic.defNames2Atoms.hasOwnProperty(selectedSet)) {
68659
69213
 
68660
69214
  let atomArray = ic.defNames2Atoms[selectedSet];
68661
-
68662
69215
  if(type === 'or') {
68663
69216
  for(let j = 0, jl = atomArray.length; j < jl; ++j) {
68664
69217
  ic.hAtoms[atomArray[j]] = 1;
@@ -68704,7 +69257,6 @@ class DefinedSets {
68704
69257
  ic.hAtoms = me.hashUtilsCls.exclHash(ic.hAtoms, atomHash);
68705
69258
  }
68706
69259
  }
68707
- } // outer for
68708
69260
  }
68709
69261
 
68710
69262
  updateAdvancedCommands(nameArray, type) { let ic = this.icn3d; ic.icn3dui;
@@ -68727,6 +69279,7 @@ class DefinedSets {
68727
69279
 
68728
69280
  combineSets(orArray, andArray, notArray, commandname) { let ic = this.icn3d, me = ic.icn3dui;
68729
69281
  ic.hAtoms = {};
69282
+
68730
69283
  this.setHAtomsFromSets(orArray, 'or');
68731
69284
 
68732
69285
  if(Object.keys(ic.hAtoms).length == 0) {
@@ -70165,6 +70718,10 @@ class LoadScript {
70165
70718
  ic.resizeCanvasCls.resizeCanvas(me.htmlCls.WIDTH, me.htmlCls.HEIGHT, true);
70166
70719
  }
70167
70720
 
70721
+ if(!me.cfg.showlogo) {
70722
+ $("#ncbi_logo").hide();
70723
+ }
70724
+
70168
70725
  // an extra render to remove artifacts in transparent surface
70169
70726
  if(ic.bTransparentSurface && ic.bRender) ic.drawCls.render();
70170
70727
 
@@ -70822,19 +71379,22 @@ class Selection {
70822
71379
  selectSideChains() { let ic = this.icn3d, me = ic.icn3dui;
70823
71380
  let currHAtoms = me.hashUtilsCls.cloneHash(ic.hAtoms);
70824
71381
 
70825
- //let nuclMainArray = ["C1'", "C1*", "C2'", "C2*", "C3'", "C3*", "C4'", "C4*", "C5'", "C5*", "O3'", "O3*", "O4'", "O4*", "O5'", "O5*", "P", "OP1", "O1P", "OP2", "O2P"];
71382
+ ic.hAtoms = this.getSideAtoms(currHAtoms);
71383
+ ic.hlUpdateCls.showHighlight();
71384
+ }
70826
71385
 
70827
- ic.hAtoms = {};
70828
- for(let i in currHAtoms) {
71386
+ getSideAtoms(atoms) { let ic = this.icn3d, me = ic.icn3dui;
71387
+ let sideAtoms = {};
71388
+ for(let i in atoms) {
70829
71389
  if((ic.proteins.hasOwnProperty(i) && ic.atoms[i].name !== "N" && ic.atoms[i].name !== "H"
70830
71390
  && ic.atoms[i].name !== "C" && ic.atoms[i].name !== "O"
70831
71391
  && !(ic.atoms[i].name === "CA" && ic.atoms[i].elem === "C") && ic.atoms[i].name !== "HA")
70832
71392
  ||(ic.nucleotides.hasOwnProperty(i) && me.parasCls.nuclMainArray.indexOf(ic.atoms[i].name) === -1) ) {
70833
- ic.hAtoms[i] = 1;
71393
+ sideAtoms[i] = 1;
70834
71394
  }
70835
71395
  }
70836
71396
 
70837
- ic.hlUpdateCls.showHighlight();
71397
+ return sideAtoms;
70838
71398
  }
70839
71399
 
70840
71400
  selectMainSideChains() { let ic = this.icn3d, me = ic.icn3dui;
@@ -71450,9 +72010,12 @@ class Resid2spec {
71450
72010
  resi2range(resiArray, bString) {var ic = this.icn3d; ic.icn3dui;
71451
72011
  let range = [], rangeStr = '';
71452
72012
 
71453
- let resiArraySorted = resiArray.sort(function(a, b) {
71454
- return parseInt(a) - parseInt(b);
71455
- });
72013
+ // some chains such as 3SN6_R start with residues with high residue numbers, then end with residues with low residue numbers
72014
+ // let resiArraySorted = resiArray.sort(function(a, b) {
72015
+ // return parseInt(a) - parseInt(b);
72016
+ // });
72017
+
72018
+ let resiArraySorted = resiArray;
71456
72019
 
71457
72020
  let startResi = resiArraySorted[0];
71458
72021
  let prevResi, resi;
@@ -72737,18 +73300,29 @@ class Dssp {
72737
73300
 
72738
73301
  ic.pdbDataArray = await this.promiseWithFixedJobs(pdbAjaxArray);
72739
73302
 
72740
- let bNoMoreIg = await thisClass.parseRefPdbData(ic.pdbDataArray, template);
72741
73303
  let numRound = 0;
73304
+ let bNoMoreIg = await thisClass.parseRefPdbData(ic.pdbDataArray, template, undefined, numRound);
73305
+ ++numRound;
72742
73306
 
72743
73307
  //while(!bNoMoreIg) {
72744
73308
  while(!bNoMoreIg && numRound < 15) {
72745
73309
  let bRerun = true;
72746
- bNoMoreIg = await thisClass.parseRefPdbData(ic.pdbDataArray, template, bRerun);
73310
+ bNoMoreIg = await thisClass.parseRefPdbData(ic.pdbDataArray, template, bRerun, numRound);
72747
73311
  ++numRound;
72748
73312
  }
72749
73313
  }
72750
73314
  else {
72751
- await thisClass.parseRefPdbData(undefined, template);
73315
+ await thisClass.parseRefPdbData(undefined, template, undefined, numRound);
73316
+ }
73317
+
73318
+ // refnum should be adjusted after all Ig are detected since sometimes the sheet extension may affect another Ig domain
73319
+ if(!ic.chainid2igtrack) ic.chainid2igtrack = {};
73320
+ for(let chainid in ic.chains) {
73321
+ let atom = ic.firstAtomObjCls.getFirstAtomObj(ic.chains[chainid]);
73322
+ if(ic.proteins.hasOwnProperty(atom.serial)) {
73323
+ let giSeq = ic.showSeqCls.getSeq(chainid);
73324
+ ic.chainid2igtrack[chainid] = this.ajdustRefnum(giSeq, chainid);
73325
+ }
72752
73326
  }
72753
73327
  // }
72754
73328
  // catch(err) {
@@ -72757,7 +73331,7 @@ class Dssp {
72757
73331
  // }
72758
73332
  }
72759
73333
 
72760
- async parseRefPdbData(dataArray, template, bRerun) { let ic = this.icn3d, me = ic.icn3dui;
73334
+ async parseRefPdbData(dataArray, template, bRerun, numRound) { let ic = this.icn3d, me = ic.icn3dui;
72761
73335
  let thisClass = this;
72762
73336
 
72763
73337
  let struArray = Object.keys(ic.structures);
@@ -72851,7 +73425,7 @@ class Dssp {
72851
73425
  dataArray2 = await this.promiseWithFixedJobs(ajaxArray);
72852
73426
 
72853
73427
  let bRound1 = true;
72854
- bNoMoreIg = await thisClass.parseAlignData(dataArray2, domainidpairArray, bRound1);
73428
+ bNoMoreIg = await thisClass.parseAlignData(dataArray2, domainidpairArray, bRound1, numRound);
72855
73429
 
72856
73430
  /// if(ic.deferredRefnum !== undefined) ic.deferredRefnum.resolve();
72857
73431
  }
@@ -72897,7 +73471,7 @@ class Dssp {
72897
73471
 
72898
73472
  dataArray3 = await this.promiseWithFixedJobs(ajaxArray);
72899
73473
 
72900
- bNoMoreIg = await thisClass.parseAlignData(dataArray3, domainidpairArray3);
73474
+ bNoMoreIg = await thisClass.parseAlignData(dataArray3, domainidpairArray3, undefined, numRound);
72901
73475
  }
72902
73476
 
72903
73477
  return bNoMoreIg;
@@ -73125,7 +73699,7 @@ class Dssp {
73125
73699
  delete ic.domainid2refpdbname[domainid];
73126
73700
  delete ic.domainid2score[domainid];
73127
73701
  }
73128
- continue;
73702
+ continue;
73129
73703
  }
73130
73704
  // }
73131
73705
  }
@@ -73189,7 +73763,7 @@ class Dssp {
73189
73763
  return domainid2segs; // only used in round 2
73190
73764
  }
73191
73765
 
73192
- async parseAlignData(dataArray, domainidpairArray, bRound1) { let ic = this.icn3d, me = ic.icn3dui;
73766
+ async parseAlignData(dataArray, domainidpairArray, bRound1, numRound) { let ic = this.icn3d, me = ic.icn3dui;
73193
73767
  let bNoMoreIg = false;
73194
73768
 
73195
73769
  let domainid2segs = this.parseAlignData_part1(dataArray, domainidpairArray, bRound1);
@@ -73214,7 +73788,8 @@ class Dssp {
73214
73788
  //let pdbid = domainid.substr(0, domainid.indexOf('_'));
73215
73789
  let chainid = domainid.substr(0, domainid.indexOf(','));
73216
73790
 
73217
- if(ic.refpdbHash.hasOwnProperty(chainid)) {
73791
+ // Adjusted refpdbname in the first try
73792
+ if(ic.refpdbHash.hasOwnProperty(chainid) && numRound == 0) {
73218
73793
  refpdbnameList = [chainid];
73219
73794
 
73220
73795
  if(!me.bNode) console.log("Adjusted refpdbname for domainid " + domainid + ": " + chainid);
@@ -73267,7 +73842,7 @@ class Dssp {
73267
73842
 
73268
73843
  dataArray3 = await this.promiseWithFixedJobs(ajaxArray);
73269
73844
 
73270
- bNoMoreIg = await this.parseAlignData(dataArray3, domainidpairArray3, false);
73845
+ bNoMoreIg = await this.parseAlignData(dataArray3, domainidpairArray3, false, numRound);
73271
73846
 
73272
73847
  // end of round 2
73273
73848
  return bNoMoreIg;
@@ -73512,6 +74087,8 @@ class Dssp {
73512
74087
  }
73513
74088
  }
73514
74089
 
74090
+ // refnum should be adjusted after all Ig are detected since sometimes the sheet extension may affect another Ig domain
74091
+ /*
73515
74092
  if(!ic.chainid2igtrack) ic.chainid2igtrack = {};
73516
74093
  for(let chainid in ic.chains) {
73517
74094
  let atom = ic.firstAtomObjCls.getFirstAtomObj(ic.chains[chainid]);
@@ -73520,6 +74097,7 @@ class Dssp {
73520
74097
  ic.chainid2igtrack[chainid] = this.ajdustRefnum(giSeq, chainid);
73521
74098
  }
73522
74099
  }
74100
+ */
73523
74101
  }
73524
74102
 
73525
74103
  getStrandFromRefnum(oriRefnum, finalStrand) { let ic = this.icn3d; ic.icn3dui;
@@ -78452,7 +79030,7 @@ class ResizeCanvas {
78452
79030
  //let itemArray = ['dl_selectannotations', 'dl_alignment', 'dl_2ddgm', 'dl_definedsets', 'dl_graph',
78453
79031
  // 'dl_linegraph', 'dl_scatterplot', 'dl_contactmap', 'dl_allinteraction', 'dl_copyurl',
78454
79032
  // 'dl_symmetry', 'dl_symd', 'dl_rmsd', 'dl_legend', 'dl_disttable'];
78455
- let itemArray = ['dl_2ddgm', 'dl_2dctn', 'dl_alignment', 'dl_sequence2', 'dl_definedsets', 'dl_setsmenu', 'dl_command', 'dl_setoperations', 'dl_vast', 'dl_foldseek', 'dl_mmtfid', 'dl_pdbid', 'dl_afid', 'dl_opmid', 'dl_pdbfile', 'dl_pdbfile_app', 'dl_rescolorfile', 'dl_customcolor', 'dl_align', 'dl_alignaf', 'dl_chainalign', 'dl_chainalign2', 'dl_chainalign3', 'dl_mutation', 'dl_mol2file', 'dl_sdffile', 'dl_xyzfile', 'dl_afmapfile', 'dl_urlfile', 'dl_mmciffile', 'dl_mmcifid', 'dl_mmdbid', 'dl_mmdbafid', 'dl_blast_rep_id', 'dl_yournote', 'dl_proteinname', 'dl_refseqid', 'dl_cid', 'dl_pngimage', 'dl_state', 'dl_fixedversion', 'dl_selection', 'dl_dsn6', 'dl_dsn6url', 'dl_clr', 'dl_symmetry', 'dl_symd', 'dl_contact', 'dl_hbonds', 'dl_realign', 'dl_realignbystruct', 'dl_allinteracton', 'dl_interactionsorted', 'dl_linegraph', 'dl_linegraphcolor', 'dl_scatterplot', 'dl_scatterploitcolor', 'dl_contactmap', 'dl_alignerrormap', 'dl_elecmap2fofc', 'dl_elecmapfofc', 'dl_emmap', 'dl_aroundsphere', 'dl_adjustmem', 'dl_selectplane', 'dl_addlabel', 'dl_addlabelselection', 'dl_labelColor', 'dl_distance', 'dl_stabilizer', 'dl_disttwosets', 'dl_distmanysets', 'dl_stabilizer_rm', 'dl_thickness', 'dl_thickness2', 'dl_addtrack', 'dl_addtrack_tabs', 'dl_saveselection', 'dl_copyurl', 'dl_selectannotations', 'dl_annotations_tabs', 'dl_anno_view_tabs', 'dl_annotations', 'dl_graph', 'dl_svgcolor', 'dl_area', 'dl_colorbyarea', 'dl_rmsd', 'dl_buriedarea', 'dl_propbypercentout', 'dl_propbybfactor', 'dl_legend', 'dl_disttable', 'dl_translate'];
79033
+ let itemArray = ['dl_2ddgm', 'dl_2dctn', 'dl_alignment', 'dl_sequence2', 'dl_definedsets', 'dl_setsmenu', 'dl_command', 'dl_setoperations', 'dl_vast', 'dl_foldseek', 'dl_mmtfid', 'dl_pdbid', 'dl_afid', 'dl_opmid', 'dl_pdbfile', 'dl_pdbfile_app', 'dl_rescolorfile', 'dl_customcolor', 'dl_align', 'dl_alignaf', 'dl_chainalign', 'dl_chainalign2', 'dl_chainalign3', 'dl_mutation', 'dl_mol2file', 'dl_sdffile', 'dl_xyzfile', 'dl_clustalwfile', 'dl_fastafile', 'dl_afmapfile', 'dl_urlfile', 'dl_mmciffile', 'dl_mmcifid', 'dl_mmdbid', 'dl_mmdbafid', 'dl_blast_rep_id', 'dl_yournote', 'dl_proteinname', 'dl_refseqid', 'dl_cid', 'dl_pngimage', 'dl_state', 'dl_fixedversion', 'dl_selection', 'dl_dsn6', 'dl_dsn6url', 'dl_clr', 'dl_symmetry', 'dl_symd', 'dl_contact', 'dl_hbonds', 'dl_realign', 'dl_realignbystruct', 'dl_allinteracton', 'dl_interactionsorted', 'dl_linegraph', 'dl_linegraphcolor', 'dl_scatterplot', 'dl_scatterploitcolor', 'dl_contactmap', 'dl_alignerrormap', 'dl_elecmap2fofc', 'dl_elecmapfofc', 'dl_emmap', 'dl_aroundsphere', 'dl_adjustmem', 'dl_selectplane', 'dl_addlabel', 'dl_addlabelselection', 'dl_labelColor', 'dl_distance', 'dl_stabilizer', 'dl_disttwosets', 'dl_distmanysets', 'dl_stabilizer_rm', 'dl_thickness', 'dl_thickness2', 'dl_addtrack', 'dl_addtrack_tabs', 'dl_saveselection', 'dl_copyurl', 'dl_selectannotations', 'dl_annotations_tabs', 'dl_anno_view_tabs', 'dl_annotations', 'dl_graph', 'dl_svgcolor', 'dl_area', 'dl_colorbyarea', 'dl_rmsd', 'dl_buriedarea', 'dl_propbypercentout', 'dl_propbybfactor', 'dl_legend', 'dl_disttable', 'dl_translate'];
78456
79034
 
78457
79035
  for(let i in itemArray) {
78458
79036
  let item = itemArray[i];
@@ -79198,9 +79776,10 @@ class SaveFile {
79198
79776
  ssObj.resn = atom.resn;
79199
79777
  ssObj.resi = atom.resi;
79200
79778
 
79201
- if(parseInt(atom.resi) > parseInt(prevResi) + 1) {
79202
- ssObj.ss = ' ';
79203
- ssArray.push(ssObj);
79779
+ if(parseInt(atom.resi) > parseInt(prevResi) + 1 || atom.ssbegin) {
79780
+ let ssObj2 = me.hashUtilsCls.cloneHash(ssObj);
79781
+ ssObj2.ss = ' ';
79782
+ ssArray.push(ssObj2);
79204
79783
  }
79205
79784
 
79206
79785
  if(atom.ss == 'helix') {
@@ -79211,13 +79790,13 @@ class SaveFile {
79211
79790
  ssObj.ss = 'S';
79212
79791
  ssArray.push(ssObj);
79213
79792
  }
79214
-
79793
+ /*
79215
79794
  if(atom.ssend) {
79216
79795
  let ssObj2 = me.hashUtilsCls.cloneHash(ssObj);
79217
79796
  ssObj2.ss = ' ';
79218
79797
  ssArray.push(ssObj2);
79219
79798
  }
79220
-
79799
+ */
79221
79800
  prevResi = atom.resi;
79222
79801
  }
79223
79802
 
@@ -79225,9 +79804,9 @@ class SaveFile {
79225
79804
  for(let i = 0, il = ssArray.length; i < il; ++i) {
79226
79805
  let ssObj = ssArray[i];
79227
79806
 
79228
- if(ssObj.ss != prevSs || ssObj.ssbegin) {
79807
+ if(ssObj.ss != prevSs) {
79229
79808
  // print prev
79230
- stru2header[stru] += this.printPrevSecondary(bHelix, bSheet, prevRealSsObj, ssCnt);
79809
+ if(prevSs !== ' ') stru2header[stru] += this.printPrevSecondary(bHelix, bSheet, prevRealSsObj, ssCnt);
79231
79810
 
79232
79811
  // print current
79233
79812
  ssCnt = 0;
@@ -79235,7 +79814,7 @@ class SaveFile {
79235
79814
  bSheet = false;
79236
79815
  prevRealSsObj = undefined;
79237
79816
 
79238
- if(ssObj.ss != ' ') {
79817
+ if(ssObj.ss !== ' ') {
79239
79818
  if(ssObj.ss == 'H') {
79240
79819
  bHelix = true;
79241
79820
  prevRealSsObj = ssObj;
@@ -79251,7 +79830,7 @@ class SaveFile {
79251
79830
  }
79252
79831
  }
79253
79832
 
79254
- if(ssObj.ss != ' ') {
79833
+ if(ssObj.ss !== ' ') {
79255
79834
  ++ssCnt;
79256
79835
  prevRealSsObj = ssObj;
79257
79836
  }
@@ -79899,7 +80478,7 @@ class ShareLink {
79899
80478
  let shortName = strArray[strArray.length - 1];
79900
80479
  ic.saveFileCls.saveFile(inputid + '-' + shortName + '.png', 'png');
79901
80480
  let text = '<div style="float:left; border: solid 1px #0000ff; padding: 5px; margin: 10px; text-align:center;">';
79902
- text += '<a href="https://www.ncbi.nlm.nih.gov/Structure/icn3d/share.html?' + shortName + '" target="_blank">';
80481
+ text += '<a href="https://www.ncbi.nlm.nih.gov/Structure/icn3d/share2.html?' + shortName + '" target="_blank">';
79903
80482
  text += '<img style="height:300px" src ="' + inputid + '-' + shortName + '.png"><br>\n';
79904
80483
  text += '<!--Start of your comments==================-->\n';
79905
80484
  let yournote =(ic.yournote) ? ': ' + ic.yournote.replace(/\n/g, "<br>").replace(/; /g, ", ") : '';
@@ -79914,13 +80493,14 @@ class ShareLink {
79914
80493
  if(bPngHtml && data.shortLink === undefined) {
79915
80494
  ic.saveFileCls.saveFile(inputid + '_icn3d_loadable.png', 'png');
79916
80495
  }
79917
-
80496
+ /*
79918
80497
  //shorturl: https://icn3d.page.link/NvbAh1Vmiwc4bgX87
79919
80498
  let urlArray = shorturl.split('page.link/');
79920
- //if(urlArray.length == 2) shorturl = me.htmlCls.baseUrl + 'icn3d/share.html?' + urlArray[1];
79921
80499
  // When the baseURL is structure.ncbi.nlm.nih.gov, mmcifparser.cgi has a problem to pass posted data in Mac/iphone
79922
80500
  // So the base URL is still www.ncbi.nlm.nih.gov/Structure,just use short URL here
79923
80501
  if(urlArray.length == 2) shorturl = 'https://www.ncbi.nlm.nih.gov/Structure/icn3d/share.html?' + urlArray[1];
80502
+ */
80503
+ shorturl = 'https://www.ncbi.nlm.nih.gov/Structure/icn3d/share2.html?' + shorturl;
79924
80504
 
79925
80505
  $("#" + ic.pre + "short_url").val(shorturl);
79926
80506
  $("#" + ic.pre + "short_url_title").val(shorturl + '&t=' + ic.yournote);
@@ -79939,6 +80519,7 @@ class ShareLink {
79939
80519
  }
79940
80520
 
79941
80521
  getShareLinkPrms(url, bPngHtml) { let ic = this.icn3d, me = ic.icn3dui;
80522
+ /*
79942
80523
  //https://firebase.google.com/docs/dynamic-links/rest
79943
80524
  //Web API Key: AIzaSyBxl9CgM0dY5lagHL4UOhEpLWE1fuwdnvc
79944
80525
  let fdlUrl = "https://firebasedynamiclinks.googleapis.com/v1/shortLinks?key=AIzaSyBxl9CgM0dY5lagHL4UOhEpLWE1fuwdnvc";
@@ -79962,6 +80543,26 @@ class ShareLink {
79962
80543
  }
79963
80544
  });
79964
80545
  });
80546
+ */
80547
+
80548
+ let serviceUrl = "https://icn3d.link/?longurl=" + encodeURIComponent(url);
80549
+ return new Promise(function(resolve, reject) {
80550
+ $.ajax({
80551
+ url: serviceUrl,
80552
+ dataType: 'json',
80553
+ cache: true,
80554
+ success: function(data) {
80555
+ resolve(data);
80556
+ },
80557
+ error : function(xhr, textStatus, errorThrown ) {
80558
+ let shorturl = 'Problem in getting shortened URL';
80559
+ $("#" + ic.pre + "ori_url").val(url);
80560
+ $("#" + ic.pre + "short_url").val(shorturl);
80561
+ $("#" + ic.pre + "short_url_title").val(shorturl + '&t=' + ic.yournote);
80562
+ if(!bPngHtml) me.htmlCls.dialogCls.openDlg('dl_copyurl', 'Copy a Share Link URL');
80563
+ }
80564
+ });
80565
+ });
79965
80566
  }
79966
80567
 
79967
80568
  shareLinkUrl(bAllCommands, bOutputCmd, bStatefile) { let ic = this.icn3d, me = ic.icn3dui;
@@ -79988,6 +80589,7 @@ class ShareLink {
79988
80589
  if(key === 'height' && value === '100%') continue;
79989
80590
 
79990
80591
  if(key === 'resize' && value === true) continue;
80592
+ if(key === 'showlogo' && value === true) continue;
79991
80593
  if(key === 'showmenu' && value === true) continue;
79992
80594
  if(key === 'showtitle' && value === true) continue;
79993
80595
  if(key === 'showcommand' && value === true) continue;
@@ -81100,8 +81702,10 @@ class Ray {
81100
81702
  this.icn3d = icn3d;
81101
81703
  }
81102
81704
 
81103
- rayCaster(e, bClick) {
81705
+ rayCaster(e, bClick) { let ic = this.icn3d; ic.icn3dui;
81706
+ if(!ic.opts || ic.opts['effect'] == 'none') {
81104
81707
  this.rayCasterBase(e, bClick);
81708
+ }
81105
81709
  }
81106
81710
 
81107
81711
  rayCasterBase(e, bClick) { let ic = this.icn3d; ic.icn3dui;
@@ -82422,6 +83026,14 @@ class iCn3D {
82422
83026
  });
82423
83027
  }
82424
83028
 
83029
+ this.effects = {
83030
+ //'anaglyph': new THREE.AnaglyphEffect(this.renderer),
83031
+ //'parallax barrier': new THREE.ParallaxBarrierEffect(this.renderer),
83032
+ //'oculus rift': new THREE.OculusRiftEffect(this.renderer),
83033
+ 'stereo': new THREE.StereoEffect(this.renderer),
83034
+ 'none': this.renderer
83035
+ };
83036
+
82425
83037
  this.overdraw = 0;
82426
83038
  }
82427
83039
  else {
@@ -82568,14 +83180,6 @@ class iCn3D {
82568
83180
 
82569
83181
  this.bExtrude = true;
82570
83182
 
82571
- this.effects = {
82572
- //'anaglyph': new THREE.AnaglyphEffect(this.renderer),
82573
- //'parallax barrier': new THREE.ParallaxBarrierEffect(this.renderer),
82574
- //'oculus rift': new THREE.OculusRiftEffect(this.renderer),
82575
- //'stereo': new THREE.StereoEffect(this.renderer),
82576
- 'none': this.renderer
82577
- };
82578
-
82579
83183
  this.maxD = 500; // size of the molecule
82580
83184
  this.oriMaxD = this.maxD; // size of the molecule
82581
83185
  //this.cam_z = -150;
@@ -82628,6 +83232,7 @@ class iCn3D {
82628
83232
  //The default display options
82629
83233
  this.optsOri = {};
82630
83234
  this.optsOri['camera'] = 'perspective'; //perspective, orthographic
83235
+ this.optsOri['effect'] = 'none'; //stereo, none
82631
83236
  this.optsOri['background'] = 'black'; //transparent, black, grey, white
82632
83237
  this.optsOri['color'] = 'chain'; //spectrum, secondary structure, charge, hydrophobic, conserved, chain, residue, atom, b factor, red, green, blue, magenta, yellow, cyan, white, grey, custom, ig strand
82633
83238
  this.optsOri['proteins'] = 'ribbon'; //ribbon, strand, cylinder and plate, schematic, c alpha trace, backbone, b factor tube, lines, stick, ball and stick, sphere, nothing
@@ -82821,6 +83426,7 @@ class iCn3D {
82821
83426
  this.pdbParserCls = new PdbParser(this);
82822
83427
  this.sdfParserCls = new SdfParser(this);
82823
83428
  this.xyzParserCls = new XyzParser(this);
83429
+ this.msaParserCls = new MsaParser(this);
82824
83430
  this.realignParserCls = new RealignParser(this);
82825
83431
  this.densityCifParserCls = new DensityCifParser(this);
82826
83432
  this.ParserUtilsCls = new ParserUtils(this);
@@ -83077,7 +83683,7 @@ class iCn3DUI {
83077
83683
  //even when multiple iCn3D viewers are shown together.
83078
83684
  this.pre = this.cfg.divid + "_";
83079
83685
 
83080
- this.REVISION = '3.41.0';
83686
+ this.REVISION = '3.43.0';
83081
83687
 
83082
83688
  // In nodejs, iCn3D defines "window = {navigator: {}}"
83083
83689
  this.bNode = (Object.keys(window).length < 2) ? true : false;
@@ -83086,6 +83692,7 @@ class iCn3DUI {
83086
83692
  if(this.cfg.width === undefined) this.cfg.width = '100%';
83087
83693
  if(this.cfg.height === undefined) this.cfg.height = '100%';
83088
83694
  if(this.cfg.resize === undefined) this.cfg.resize = true;
83695
+ if(this.cfg.showlogo === undefined) this.cfg.showlogo = true;
83089
83696
  if(this.cfg.showmenu === undefined) this.cfg.showmenu = true;
83090
83697
  if(this.cfg.showtitle === undefined) this.cfg.showtitle = true;
83091
83698
  if(this.cfg.showcommand === undefined) this.cfg.showcommand = true;
@@ -83506,8 +84113,12 @@ iCn3DUI.prototype.show3DStructure = async function(pdbStr) { let me = this;
83506
84113
  }
83507
84114
  else if(me.cfg.align !== undefined) {
83508
84115
  // ic.bNCBI = true;
83509
-
84116
+ if(me.cfg.align.indexOf('185055,') != -1) {
84117
+ me.cfg.align = me.cfg.align.replace('185055,', '199731,'); //the mmdbid of PDB 6M17 was changed from 185055 to 199731
84118
+ }
84119
+
83510
84120
  let alignArray = me.cfg.align.split(','); // e.g., 6 IDs: 103701,1,4,68563,1,167 [mmdbid1,biounit,molecule,mmdbid2,biounit,molecule], or 2IDs: 103701,68563 [mmdbid1,mmdbid2]
84121
+
83511
84122
  if(alignArray.length === 6) {
83512
84123
  ic.inputid = alignArray[0] + "_" + alignArray[3];
83513
84124
  }
@@ -83900,6 +84511,7 @@ exports.MarchingCube = MarchingCube;
83900
84511
  exports.MmcifParser = MmcifParser;
83901
84512
  exports.MmdbParser = MmdbParser;
83902
84513
  exports.Mol2Parser = Mol2Parser;
84514
+ exports.MsaParser = MsaParser;
83903
84515
  exports.MyEventCls = MyEventCls;
83904
84516
  exports.OpmParser = OpmParser;
83905
84517
  exports.ParasCls = ParasCls;