icn3d 3.50.1 → 3.51.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/icn3d.module.js CHANGED
@@ -59492,7 +59492,7 @@ class ClickMenu {
59492
59492
  let definedAtomsHtml = ic.definedSetsCls.setAtomMenu(['protein'], bNucleotides);
59493
59493
  if($("#" + me.pre + "atomsCustomNucleotide").length && definedAtomsHtml) {
59494
59494
  $("#" + me.pre + "atomsCustomNucleotide").html(definedAtomsHtml);
59495
- me.htmlCls.dialogCls.openDlg('dl_2ddgm_r2dt', 'Show R2DT Diagram for Nucleotides');
59495
+ me.htmlCls.dialogCls.openDlg('dl_2ddgm_r2dt', 'Show R2DT Diagram for RNAs');
59496
59496
  $("#" + me.pre + "atomsCustomNucleotide").resizable();
59497
59497
  }
59498
59498
  else {
@@ -61421,7 +61421,7 @@ class SetMenu {
61421
61421
 
61422
61422
  html += this.getMenuText('2ddgmwrap', '2D Diagram', undefined, 1, 1);
61423
61423
  html += "<ul>";
61424
- html += this.getLink('2ddgm_r2dt', 'for Nucleotides' + me.htmlCls.wifiStr, 1, 2);
61424
+ html += this.getLink('2ddgm_r2dt', 'for RNAs' + me.htmlCls.wifiStr, 1, 2);
61425
61425
  html += this.getLink('2ddgm_igdgm', 'for Ig Domains' + me.htmlCls.wifiStr, 1, 2);
61426
61426
  if(me.cfg.mmdbid !== undefined || me.cfg.gi !== undefined || me.cfg.blast_rep_id !== undefined || me.cfg.align !== undefined || me.cfg.chainalign !== undefined) {
61427
61427
  html += this.getLink('mn2_2ddgm', 'for Chains ' + me.htmlCls.wifiStr, 1, 2);
@@ -61874,6 +61874,7 @@ class Dialog {
61874
61874
  let bLigplot = $('#' + me.pre + 'dl_ligplot').hasClass('ui-dialog-content'); // initialized
61875
61875
  let bContactmap = $('#' + me.pre + 'dl_contactmap').hasClass('ui-dialog-content'); // initialized
61876
61876
  let b2ddiagram = $('#' + me.pre + 'dl_2ddiagram').hasClass('ui-dialog-content'); // initialized
61877
+ let big2ddgm = $('#' + me.pre + 'dl_ig2ddgm').hasClass('ui-dialog-content'); // initialized
61877
61878
  let brnacanvas = $('#' + me.pre + 'dl_rnacanvas').hasClass('ui-dialog-content'); // initialized
61878
61879
  let bAlignerrormap = $('#' + me.pre + 'dl_alignerrormap').hasClass('ui-dialog-content'); // initialized
61879
61880
  let bTable = $('#' + me.pre + 'dl_interactionsorted').hasClass('ui-dialog-content'); // initialized
@@ -61896,6 +61897,7 @@ class Dialog {
61896
61897
  id2flag.dl_contactmap = 'bContactmap2';
61897
61898
  id2flag.dl_2ddiagram = 'b2ddiagram2';
61898
61899
  id2flag.dl_rnacanvas = 'brnacanvas2';
61900
+ id2flag.dl_ig2ddgm = 'big2ddgm2';
61899
61901
  id2flag.dl_alignerrormap = 'bAlignerrormap2';
61900
61902
  id2flag.dl_interactionsorted = 'bTable2';
61901
61903
  id2flag.dl_alignment = 'bAlignmentInit2';
@@ -61913,6 +61915,7 @@ class Dialog {
61913
61915
  if(bContactmap) status.bContactmap2 = $('#' + me.pre + 'dl_contactmap').dialog( 'isOpen' );
61914
61916
  if(b2ddiagram) status.b2ddiagram2 = $('#' + me.pre + 'dl_2ddiagram').dialog( 'isOpen' );
61915
61917
  if(brnacanvas) status.brnacanvas2 = $('#' + me.pre + 'dl_rnacanvas').dialog( 'isOpen' );
61918
+ if(big2ddgm) status.big2ddgm2 = $('#' + me.pre + 'dl_ig2ddgm').dialog( 'isOpen' );
61916
61919
  if(bAlignerrormap) status.bAlignerror2 = $('#' + me.pre + 'dl_alignerrormap').dialog( 'isOpen' );
61917
61920
  if(bTable) status.bTable2 = $('#' + me.pre + 'dl_interactionsorted').dialog( 'isOpen' );
61918
61921
  if(bAlignmentInit) status.bAlignmentInit2 = $('#' + me.pre + 'dl_alignment').dialog( 'isOpen' );
@@ -62100,7 +62103,7 @@ class Dialog {
62100
62103
 
62101
62104
  let status = this.getDialogStatus().status;
62102
62105
 
62103
- if(id === me.pre + 'dl_selectannotations' || id === me.pre + 'dl_graph' || id === me.pre + 'dl_linegraph' || id === me.pre + 'dl_scatterplot' || id === me.pre + 'dl_rmsdplot' || id === me.pre + 'dl_hbondplot' || id === me.pre + 'dl_ligplot' || id === me.pre + 'dl_contactmap' || id === me.pre + 'dl_2ddiagram' || id === me.pre + 'dl_rnacanvas' || id === me.pre + 'dl_alignerrormap' || id === me.pre + 'dl_interactionsorted' || id === me.pre + 'dl_alignment') {
62106
+ if(id === me.pre + 'dl_selectannotations' || id === me.pre + 'dl_graph' || id === me.pre + 'dl_linegraph' || id === me.pre + 'dl_scatterplot' || id === me.pre + 'dl_rmsdplot' || id === me.pre + 'dl_hbondplot' || id === me.pre + 'dl_ligplot' || id === me.pre + 'dl_contactmap' || id === me.pre + 'dl_2ddiagram' || id === me.pre + 'dl_rnacanvas' || id === me.pre + 'dl_ig2ddgm' || id === me.pre + 'dl_alignerrormap' || id === me.pre + 'dl_interactionsorted' || id === me.pre + 'dl_alignment') {
62104
62107
  //var dialogWidth = 0.5 *(me.htmlCls.WIDTH - me.htmlCls.LESSWIDTH) - twoddgmWidth * 0.5;
62105
62108
  let dialogWidth = 0.5 *(me.htmlCls.WIDTH) - twoddgmWidth * 0.5;
62106
62109
 
@@ -63066,19 +63069,19 @@ class SetDialog {
63066
63069
  html += "</div>";
63067
63070
 
63068
63071
  html += me.htmlCls.divStr + "dl_2ddgm_r2dt' class='" + dialogClass + "'>";
63069
- html += this.addNotebookTitle('dl_2ddgm_r2dt', '2D Diagram for Nucleotides (R2DT)');
63070
- html += "1. Select a nucleotide chain to show 2D diagram:<br>";
63072
+ html += this.addNotebookTitle('dl_2ddgm_r2dt', '2D Diagram for RNAs (R2DT)');
63073
+ html += "1. Select a RNA chain to show 2D diagram:<br>";
63071
63074
  html += "<select style='max-width:200px' id='" + me.pre + "atomsCustomNucleotide' size='5' style='min-width:130px;'>";
63072
63075
  html += "</select><br>";
63073
63076
  html += "2. " + me.htmlCls.buttonStr + "applyr2dt'>R2DT Diagram</button>" + me.htmlCls.buttonStr + "applyfr3d' style='margin-left:12px'>2D Diagram with RNAcanvas</button><br><br>(Hints: Click on Residues in 2D to highlight in 3D. <br>Ctrl + click to select multiple residues.)<br>";
63074
63077
  html += "</div>";
63075
63078
 
63076
63079
  html += me.htmlCls.divStr + "dl_2ddgm_igdgm' class='" + dialogClass + "'>";
63077
- html += this.addNotebookTitle('dl_2ddgm_igdgm', '2D Diagram for Ig Domains (R2DT)');
63080
+ html += this.addNotebookTitle('dl_2ddgm_igdgm', '2D Diagram for Ig Domains');
63078
63081
  html += "1. Select a protein chain to show Ig diagram. An Excel file containing <br>the Ig diagram will be saved to your computer.<br>";
63079
63082
  html += "<select style='max-width:200px' id='" + me.pre + "atomsCustomProtein' size='5' style='min-width:130px;'>";
63080
63083
  html += "</select><br>";
63081
- html += me.htmlCls.buttonStr + "applyigdgm'>Show Ig Diagram</button><br>";
63084
+ html += "2. " + me.htmlCls.buttonStr + "applyigdgm' style='margin-right:12px;'>Show Ig Diagram</button>" + me.htmlCls.buttonStr + "saveigdgm'>Download Ig Diagrams in Excel</button><br>";
63082
63085
  html += "</div>";
63083
63086
 
63084
63087
  html += me.htmlCls.divStr + "dl_hbonds' class='" + dialogClass + "'>";
@@ -63436,6 +63439,20 @@ class SetDialog {
63436
63439
  html += '<div id="' + me.pre + 'rnacanvasDiv"></div>';
63437
63440
  html += "</div>";
63438
63441
 
63442
+
63443
+ me.ig2ddgmid = me.pre + 'ig2ddgm';
63444
+ html += me.htmlCls.divStr + "dl_ig2ddgm' style='background-color:white' class='" + dialogClass + "'>";
63445
+ html += this.addNotebookTitle('dl_ig2ddgm', '2D Diagram for Ig domains');
63446
+
63447
+ html += "<table><tr><td>Select an Ig domain:<br>";
63448
+ html += me.htmlCls.divNowrapStr + "<select id='" + me.pre + "iglist' size='2' style='min-width:130px;'>";
63449
+ html += "</select></td><td valign='top'>";
63450
+ html += me.htmlCls.space2 + buttonStrTmp + me.ig2ddgmid + '_svg">Download SVG</button></td></tr></table><br>';
63451
+
63452
+ html += '<div id="' + me.pre + 'ig2ddgmDiv"></div>';
63453
+ html += "</div>";
63454
+
63455
+
63439
63456
  html += me.htmlCls.divStr + "dl_alignerrormap' style='background-color:white' class='" + dialogClass + "'>";
63440
63457
  html += this.addNotebookTitle('dl_alignerrormap', 'PAE Map');
63441
63458
 
@@ -66708,7 +66725,17 @@ class Events {
66708
66725
  thisClass.setLogCmd('diagram 2d fr3d | ' + chainid, true);
66709
66726
  });
66710
66727
 
66711
- me.myEventCls.onIds("#" + me.pre + "applyigdgm", "click", async function(e) { let ic = me.icn3d;
66728
+ me.myEventCls.onIds("#" + me.pre + "saveigdgm", "click", async function(e) { let ic = me.icn3d;
66729
+ e.preventDefault();
66730
+ //if(!me.cfg.notebook) dialog.dialog( "close" );
66731
+
66732
+ let chainid = $("#" + ic.pre + "atomsCustomProtein").val();
66733
+
66734
+ let bSave = true;
66735
+ await ic.diagram2dCls.drawIgdgm(chainid, bSave);
66736
+ thisClass.setLogCmd('download 2d ig | ' + chainid, true);
66737
+ });
66738
+ me.myEventCls.onIds("#" + me.pre + "applyigdgm", "click", async function(e) { let ic = me.icn3d;
66712
66739
  e.preventDefault();
66713
66740
  //if(!me.cfg.notebook) dialog.dialog( "close" );
66714
66741
 
@@ -66908,6 +66935,11 @@ class Events {
66908
66935
  ic.saveFileCls.saveFile(chainid + "_seq.txt", "text", [seq]);
66909
66936
  });
66910
66937
 
66938
+ me.myEventCls.onIds("#" + me.ig2ddgmid + "_svg", "click", function(e) { let ic = me.icn3d;
66939
+ e.preventDefault();
66940
+
66941
+ ic.saveFileCls.saveSvg("ig2ddgmSvg", ic.ig2ddgm_chainid + "_ig_2d.svg");
66942
+ });
66911
66943
 
66912
66944
  me.myEventCls.onIds("#" + me.linegraphid + "_svg", "click", function(e) { let ic = me.icn3d;
66913
66945
  e.preventDefault();
@@ -84990,9 +85022,82 @@ class ApplyClbonds {
84990
85022
  } // if
84991
85023
  } // if
84992
85024
 
85025
+ // add crosslink chemicals to the linked protein/nucleotide residues
85026
+ for(let structure in ic.structures) {
85027
+ let clbondArray = ic.clbondpnts[structure];
85028
+ if(clbondArray === undefined) {
85029
+ break;
85030
+ }
85031
+
85032
+ let clusterArray = this.clusterLinkedNodes(clbondArray);
85033
+
85034
+ for(let i = 0, il = clusterArray.length; i < il; ++i) {
85035
+ let rootResid = 0;
85036
+ for(let j = 0, jl = clusterArray[i].length; j < jl; ++j) {
85037
+ let resid = clusterArray[i][j];
85038
+ let atom = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[resid]);
85039
+
85040
+ if(ic.proteins.hasOwnProperty(atom.serial) || ic.nucleotides.hasOwnProperty(atom.serial)) {
85041
+ rootResid = resid;
85042
+ break;
85043
+ }
85044
+ }
85045
+
85046
+ if(rootResid) {
85047
+ for(let j = 0, jl = clusterArray[i].length; j < jl; ++j) {
85048
+ let resid = clusterArray[i][j];
85049
+ let atom = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[resid]);
85050
+
85051
+ if(ic.chemicals.hasOwnProperty(atom.serial)) {
85052
+ ic.residues[rootResid] = me.hashUtilsCls.unionHash(ic.residues[rootResid], ic.residues[resid]);
85053
+ }
85054
+ }
85055
+ }
85056
+ }
85057
+ }
85058
+
84993
85059
  return ic.residuesHashClbonds;
84994
85060
  }
84995
85061
 
85062
+ clusterLinkedNodes(clbondArray) { let ic = this.icn3d; ic.icn3dui;
85063
+ const parent = new Map();
85064
+
85065
+ // Find the root of a node, with path compression
85066
+ function find(node) {
85067
+ if (!parent.has(node)) parent.set(node, node);
85068
+ if (parent.get(node) !== node) {
85069
+ parent.set(node, find(parent.get(node))); // path compression
85070
+ }
85071
+ return parent.get(node);
85072
+ }
85073
+
85074
+ // Union two nodes into the same cluster
85075
+ function union(a, b) {
85076
+ const rootA = find(a);
85077
+ const rootB = find(b);
85078
+ if (rootA !== rootB) parent.set(rootA, rootB);
85079
+ }
85080
+
85081
+ // Process all pairs
85082
+ // for (const [a, b] of pairs) {
85083
+ // union(a, b);
85084
+ // }
85085
+
85086
+ for(let i = 0, il = clbondArray.length; i < il; i = i + 2) {
85087
+ union(clbondArray[i], clbondArray[i+1]);
85088
+ }
85089
+
85090
+ // Group nodes by their root
85091
+ const clusters = new Map();
85092
+ for (const node of parent.keys()) {
85093
+ const root = find(node);
85094
+ if (!clusters.has(root)) clusters.set(root, []);
85095
+ clusters.get(root).push(node);
85096
+ }
85097
+
85098
+ return Array.from(clusters.values());
85099
+ }
85100
+
84996
85101
  applyClbondsOptions_base(type) { let ic = this.icn3d, me = ic.icn3dui;
84997
85102
  // only apply to displayed atoms
84998
85103
  let atomHash = me.hashUtilsCls.cloneHash(ic.chemicals);
@@ -85095,6 +85200,9 @@ class ApplyMissingRes {
85095
85200
  let bStart = false;
85096
85201
  let startResid, currResid, prevResid;
85097
85202
  let bCurrCoord, bPrevCoord = false;
85203
+
85204
+ if(!ic.chainsSeq[chainid]) continue;
85205
+
85098
85206
  for(let i = 0, il = ic.chainsSeq[chainid].length; i < il; ++i) {
85099
85207
  currResid = chainid + '_' + ic.chainsSeq[chainid][i].resi;
85100
85208
 
@@ -85336,7 +85444,7 @@ class ApplyDisplay {
85336
85444
 
85337
85445
  // remove schematic labels
85338
85446
  //if(ic.labels !== undefined) ic.labels['schematic'] = undefined;
85339
- if(ic.labels !== undefined) delete ic.labels['schematic'];
85447
+ if(!bHighlight && ic.labels !== undefined) delete ic.labels['schematic'];
85340
85448
  /*
85341
85449
  if(bHighlight) {
85342
85450
  //let residueHashCalpha = ic.firstAtomObjCls.getResiduesFromCalphaAtoms(ic.hAtoms);
@@ -85357,6 +85465,7 @@ class ApplyDisplay {
85357
85465
  //var bPhosphorusOnly = me.utilsCls.isCalphaPhosOnly(me.hashUtilsCls.hash2Atoms(atomHash), "O3'", "O3*") || me.utilsCls.isCalphaPhosOnly(me.hashUtilsCls.hash2Atoms(atomHash), "P");
85358
85466
  //let bPhosphorusOnly = me.utilsCls.isCalphaPhosOnly(me.hashUtilsCls.hash2Atoms(atomHash, ic.atoms));
85359
85467
  let nucleotidesAtoms = me.hashUtilsCls.intHash(atomHash, ic.nucleotides);
85468
+
85360
85469
  let bPhosphorusOnly = me.utilsCls.isCalphaPhosOnly(me.hashUtilsCls.hash2Atoms(nucleotidesAtoms, ic.atoms));
85361
85470
 
85362
85471
  if(style === 'ribbon') {
@@ -85395,13 +85504,13 @@ class ApplyDisplay {
85395
85504
 
85396
85505
  //if(firstAtom.het) { // chemicals
85397
85506
  if(ic.chemicals.hasOwnProperty(firstAtom.serial)) { // chemicals
85398
- ic.residueLabelsCls.addNonCarbonAtomLabels(me.hashUtilsCls.hash2Atoms(atomHash, ic.atoms));
85507
+ if(!bHighlight) ic.residueLabelsCls.addNonCarbonAtomLabels(me.hashUtilsCls.hash2Atoms(atomHash, ic.atoms));
85399
85508
 
85400
85509
  let bSchematic = true;
85401
85510
  ic.stickCls.createStickRepresentation(me.hashUtilsCls.hash2Atoms(atomHash, ic.atoms), chemicalSchematicRadius, chemicalSchematicRadius, undefined, bHighlight, bSchematic);
85402
85511
  }
85403
85512
  else { // nucleotides or proteins
85404
- ic.residueLabelsCls.addResidueLabels(me.hashUtilsCls.hash2Atoms(atomHash, ic.atoms), true);
85513
+ if(!bHighlight) ic.residueLabelsCls.addResidueLabels(me.hashUtilsCls.hash2Atoms(atomHash, ic.atoms), true);
85405
85514
 
85406
85515
  if(bPhosphorusOnly) {
85407
85516
  ic.cylinderCls.createCylinderCurve(me.hashUtilsCls.hash2Atoms(atomHash, ic.atoms), ["P"], ic.traceRadius, false, bHighlight);
@@ -91017,7 +91126,7 @@ class SetOption {
91017
91126
  ic.atoms[i].style2 = style;
91018
91127
  }
91019
91128
  }
91020
- else {
91129
+ else {
91021
91130
  for(let i in atoms) {
91022
91131
  ic.atoms[i].style = style;
91023
91132
  }
@@ -108094,11 +108203,11 @@ class BcifParser {
108094
108203
 
108095
108204
  let chain1Array = struct_conn.getColumn("ptnr1_auth_asym_id");
108096
108205
  let name1Array = struct_conn.getColumn("ptnr1_label_atom_id");
108097
- let resi1Array = struct_conn.getColumn("ptnr1_label_seq_id");
108206
+ let resi1Array = struct_conn.getColumn("ptnr1_auth_seq_id");
108098
108207
 
108099
108208
  let chain2Array = struct_conn.getColumn("ptnr2_auth_asym_id");
108100
108209
  let name2Array = struct_conn.getColumn("ptnr2_label_atom_id");
108101
- let resi2Array = struct_conn.getColumn("ptnr2_label_seq_id");
108210
+ let resi2Array = struct_conn.getColumn("ptnr2_auth_seq_id");
108102
108211
 
108103
108212
  let connSize = struct_conn.rowCount;
108104
108213
  for (let i = 0; i < connSize; ++i) {
@@ -108290,7 +108399,7 @@ class BcifParser {
108290
108399
  else {
108291
108400
  // bond between this atom and all other atom in the same residue
108292
108401
  for(let j in mResi2Atoms[currResi]) { // j is atom.id
108293
- if(this.hasCovalentBond(atom, mResi2Atoms[currResi][j], para)) {
108402
+ if(this.hasCovalentBond2(atom, mResi2Atoms[currResi][j], para)) {
108294
108403
  if(!mId2Set.hasOwnProperty(atom.id)) mId2Set[atom.id] = {};
108295
108404
  if(!mId2Set.hasOwnProperty(mResi2Atoms[currResi][j].id)) mId2Set[mResi2Atoms[currResi][j].id] = {};
108296
108405
  mId2Set[atom.id][mResi2Atoms[currResi][j].id] = 1;
@@ -108303,7 +108412,7 @@ class BcifParser {
108303
108412
 
108304
108413
  // bond between N and previous C
108305
108414
  if(name == "N" && prevC.id != "") {
108306
- if(this.hasCovalentBond(atom, prevC, para)) {
108415
+ if(this.hasCovalentBond2(atom, prevC, para)) {
108307
108416
  if(!mId2Set.hasOwnProperty(atom.id)) mId2Set[atom.id] = {};
108308
108417
  if(!mId2Set.hasOwnProperty(prevC.id)) mId2Set[prevC.id] = {};
108309
108418
  mId2Set[atom.id][prevC.id] = 1;
@@ -108644,7 +108753,7 @@ class BcifParser {
108644
108753
  return text;
108645
108754
  }
108646
108755
 
108647
- hasCovalentBond(atom1, atom2, para) { let ic = this.icn3d; ic.icn3dui;
108756
+ hasCovalentBond2(atom1, atom2, para) { let ic = this.icn3d; ic.icn3dui;
108648
108757
  let r = this.mElem2Radius[atom1.elem] + this.mElem2Radius[atom2.elem];
108649
108758
 
108650
108759
  let dx = (atom1.x - atom2.x);
@@ -116918,6 +117027,10 @@ class LoadPDB {
116918
117027
  setResidMapping() { let ic = this.icn3d; ic.icn3dui;
116919
117028
  // set ic.ncbi2resid and ic.resid2ncbi
116920
117029
  for(let chainid in ic.chainsSeq) {
117030
+ if(!ic.chainsSeq[chainid]) {
117031
+ continue;
117032
+ }
117033
+
116921
117034
  for(let j = 0, jl = ic.chainsSeq[chainid].length; j < jl; ++j) {
116922
117035
  // NCBI residue number starts from 1 and increases continuously
116923
117036
  let residNCBI = chainid + '_' + (j+1).toString();
@@ -117267,6 +117380,7 @@ class LoadCIF {
117267
117380
  chain1Array = resi1Array = resi2Array = [];
117268
117381
  }
117269
117382
 
117383
+ // let vBonds = [];
117270
117384
  if(block.getCategory("_struct_conn")) {
117271
117385
  ic.bSsbondProvided = true;
117272
117386
 
@@ -117277,11 +117391,13 @@ class LoadCIF {
117277
117391
 
117278
117392
  let chain1Array = struct_conn.getColumn("ptnr1_auth_asym_id");
117279
117393
  let name1Array = struct_conn.getColumn("ptnr1_label_atom_id");
117280
- let resi1Array = struct_conn.getColumn("ptnr1_label_seq_id");
117394
+ let resi1Array = struct_conn.getColumn("ptnr1_auth_seq_id");
117395
+ // let resn1Array = struct_conn.getColumn("ptnr1_auth_comp_id");
117281
117396
 
117282
117397
  let chain2Array = struct_conn.getColumn("ptnr2_auth_asym_id");
117283
117398
  let name2Array = struct_conn.getColumn("ptnr2_label_atom_id");
117284
- let resi2Array = struct_conn.getColumn("ptnr2_label_seq_id");
117399
+ let resi2Array = struct_conn.getColumn("ptnr2_auth_seq_id");
117400
+ // let resn2Array = struct_conn.getColumn("ptnr2_auth_comp_id");
117285
117401
 
117286
117402
  let connSize = struct_conn.rowCount;
117287
117403
  for (let i = 0; i < connSize; ++i) {
@@ -117290,21 +117406,24 @@ class LoadCIF {
117290
117406
  let chain1 = chain1Array.getString(i);
117291
117407
  name1Array.getString(i);
117292
117408
  let resi1 = resi1Array.getString(i);
117409
+ // let resn1 = resn1Array.getString(i);
117293
117410
  let id1 = structure + '_' + chain1 + "_" + resi1;
117411
+
117412
+ // let chain1Tmp = (me.parasCls.residueAbbrev.hasOwnProperty(resn1)) ? chain1 : resn1;
117413
+ // let bondId1 = chain1Tmp + "_" + resi1 + "_" + name1;
117294
117414
 
117295
117415
  let chain2 = chain2Array.getString(i);
117296
117416
  name2Array.getString(i);
117297
117417
  let resi2 = resi2Array.getString(i);
117418
+ // let resn2 = resn2Array.getString(i);
117298
117419
  let id2 = structure + '_' + chain2 + "_" + resi2;
117299
-
117300
- // Verify that the linkage is covalent, as indicated by the conn_type_id attribute2
117301
-
117302
- // if (conn_type_id == "covale") {
117303
- // vBonds.push(id1);
117304
- // vBonds.push(id2);
117305
- // }
117306
-
117307
- if(conn_type_id == "disulf") {
117420
+
117421
+ // let chain2Tmp = (me.parasCls.residueAbbrev.hasOwnProperty(resn2)) ? chain2 : resn2;
117422
+ // let bondId2 = chain2Tmp + "_" + resi2 + "_" + name2;
117423
+
117424
+ // Verify that the linkage is covalent, as indicated by the conn_type_id attribute2
117425
+ if (conn_type_id == "covale") ;
117426
+ else if(conn_type_id == "disulf") {
117308
117427
  if(ic.ssbondpnts[structure] === undefined) ic.ssbondpnts[structure] = [];
117309
117428
 
117310
117429
  ic.ssbondpnts[structure].push(id1);
@@ -117437,6 +117556,7 @@ class LoadCIF {
117437
117556
  let nameArray = atom_site.getColumn("label_atom_id");
117438
117557
  let entiyidArray = atom_site.getColumn("label_entity_id");
117439
117558
 
117559
+ // check 3QUM
117440
117560
  let chainArray = atom_site.getColumn("auth_asym_id");
117441
117561
 
117442
117562
  let resiArray = atom_site.getColumn("label_seq_id");
@@ -117458,7 +117578,6 @@ class LoadCIF {
117458
117578
  let sChain = {};
117459
117579
  let prevModelNum = '';
117460
117580
  if(!ic.molid2chain) ic.molid2chain = {};
117461
-
117462
117581
  for (let i = 0; i < atomSize; ++i) {
117463
117582
  let modelNum = modelNumArray.getString(i);
117464
117583
  if(i > 0 && modelNum != prevModelNum) {
@@ -117486,7 +117605,6 @@ class LoadCIF {
117486
117605
 
117487
117606
  let autochain = autochainArray.getString(i);
117488
117607
 
117489
-
117490
117608
  resi = oriResi;
117491
117609
 
117492
117610
  let molecueType;
@@ -117505,7 +117623,7 @@ class LoadCIF {
117505
117623
  }
117506
117624
  else {
117507
117625
  molecueType = "ligand"; // ligands or ions
117508
- chain = resn;
117626
+ if(chain == "?" || chain == ".") chain = resn; // check 3QUM
117509
117627
  }
117510
117628
  }
117511
117629
  if(chain === '') chain = 'A';
@@ -117595,6 +117713,8 @@ class LoadCIF {
117595
117713
  let z = zArray.getFloat(i);
117596
117714
  let coord = new Vector3$1(x, y, z);
117597
117715
 
117716
+ let id = serial.toString();
117717
+
117598
117718
  let atomDetails = {
117599
117719
  het: (atom_hetatm == "HETATM"), // optional, used to determine chemicals, water, ions, etc
117600
117720
  serial: serial, // required, unique atom id
@@ -117751,6 +117871,30 @@ class LoadCIF {
117751
117871
  ic.residues[residueNum] = residuesTmp;
117752
117872
  if(ic.chains[chainNum] === undefined) ic.chains[chainNum] = {};
117753
117873
  ic.chains[chainNum] = me.hashUtilsCls.unionHash2Atoms(ic.chains[chainNum], chainsTmp, ic.atoms);
117874
+ /*
117875
+ /// add the defined bonds
117876
+ for(let i = 0; i < vBonds.length; i = i + 2) {
117877
+ let id1 = mName2Serial[vBonds[i]];
117878
+ let id2 = mName2Serial[vBonds[i+1]];
117879
+
117880
+ if(!mId2Set.hasOwnProperty(id1)) mId2Set[id1] = {};
117881
+ if(!mId2Set.hasOwnProperty(id2)) mId2Set[id2] = {};
117882
+ mId2Set[id1][id2] = 1;
117883
+ mId2Set[id2][id1] = 1;
117884
+ }
117885
+
117886
+ for(let id in mId2Set) {
117887
+ let sConnId = mId2Set[id];
117888
+ let vConnId = Object.keys(sConnId);
117889
+ let serial = parseInt(id);
117890
+
117891
+ for(let j = 0, jl = vConnId.length; j < jl; ++j) {
117892
+ if(vConnId[j] === 'undefined' || !ic.atoms[serial]) continue;
117893
+ if(!ic.atoms[serial].bonds) ic.atoms[serial].bonds = [];
117894
+ ic.atoms[serial].bonds.push(parseInt(vConnId[j]));
117895
+ }
117896
+ }
117897
+ */
117754
117898
 
117755
117899
  // clear memory
117756
117900
  atom_hetatmArray = resnArray = elemArray = nameArray = chainArray = resiArray = resiOriArray
@@ -117922,6 +118066,41 @@ class LoadCIF {
117922
118066
  }
117923
118067
  }
117924
118068
 
118069
+ // check the bonds between chemicals and all other atoms
118070
+ let processedChemicals = {};
118071
+ for(let i in ic.chemicals) {
118072
+ console.log(" i = ", i, " processedChemicals = ", processedChemicals);
118073
+ if(processedChemicals.hasOwnProperty(i)) continue;
118074
+
118075
+ let atom = ic.atoms[i];
118076
+ let resid = atom.structure + '_' + atom.chain + '_' + atom.resi;
118077
+
118078
+ let radius = 4;
118079
+ let residueAtoms = ic.residues[resid];
118080
+ let otherAtoms = me.hashUtilsCls.exclHash(ic.atoms, residueAtoms);
118081
+ let neighborAtoms = ic.contactCls.getAtomsWithinAtom(otherAtoms, residueAtoms, radius);
118082
+
118083
+ for(let j in residueAtoms) {
118084
+ let startAtom = ic.atoms[j];
118085
+ for(let k in neighborAtoms) {
118086
+ let neighborAtom = ic.atoms[k];
118087
+ let neighborResid = neighborAtom.structure + '_' + neighborAtom.chain + '_' + neighborAtom.resi;
118088
+ if(resid === neighborResid) continue;
118089
+
118090
+ if(me.utilsCls.hasCovalentBond(startAtom, neighborAtom)) {
118091
+ // Handle covalent bond
118092
+ if(!startAtom.bonds) startAtom.bonds = [];
118093
+ if(!neighborAtom.bonds) neighborAtom.bonds = [];
118094
+
118095
+ startAtom.bonds.push(neighborAtom.serial);
118096
+ neighborAtom.bonds.push(startAtom.serial);
118097
+ }
118098
+ }
118099
+ }
118100
+
118101
+ processedChemicals = me.hashUtilsCls.unionHash(processedChemicals, ic.residues[resid]);
118102
+ }
118103
+
117925
118104
  ic.pmin = pmin;
117926
118105
  ic.pmax = pmax;
117927
118106
 
@@ -119256,7 +119435,7 @@ class ApplyCommand {
119256
119435
  ic.definedSetsCls.deleteSelectedSets();
119257
119436
  }
119258
119437
  else if(command == 'view interactions' || command == 'view 2d diagram') {
119259
- if(me.cfg.mmdbid !== undefined || me.cfg.gi !== undefined) {
119438
+ if(me.cfg.mmdbid !== undefined || me.cfg.gi !== undefined || me.cfg.mmdbafid !== undefined) {
119260
119439
  ic.ParserUtilsCls.set2DDiagrams(ic.inputid);
119261
119440
  }
119262
119441
  }
@@ -120771,27 +120950,31 @@ class DefinedSets {
120771
120950
  let colorStr =(atom === undefined || atom.color === undefined || atom.color.getHexString().toUpperCase() === 'FFFFFF') ? 'DDDDDD' : atom.color.getHexString();
120772
120951
  let color =(atom !== undefined && atom.color !== undefined) ? colorStr : '000000';
120773
120952
 
120774
- if(bNucleotide && atom) {
120953
+ if(bNucleotide) {
120775
120954
  // Handle nucleotide-specific logic
120776
- if(ic.nucleotides.hasOwnProperty(atom.serial) && name.split('_').length == 2 && !ic.structures.hasOwnProperty(name)) {
120955
+ if(atom && ic.nucleotides.hasOwnProperty(atom.serial) && name.split('_').length == 2 && !ic.structures.hasOwnProperty(name)) {
120777
120956
  let selectStr = (cnt == 0) ? "selected" : "";
120778
120957
 
120958
+ if(cnt == 0) this.selectSets([name]);
120959
+
120779
120960
  html += "<option value='" + name + "' style='color:#" + color + "' " + selectStr + ">" + name + "</option>";
120780
120961
  bFoundNucleotide = true;
120781
120962
  ++cnt;
120782
120963
  }
120783
120964
  }
120784
- else if(bProtein && atom) {
120965
+ else if(bProtein) {
120785
120966
  // Handle protein-specific logic
120786
- if(ic.proteins.hasOwnProperty(atom.serial) && name.split('_').length == 2 && !ic.structures.hasOwnProperty(name)) {
120967
+ if(atom && ic.proteins.hasOwnProperty(atom.serial) && name.split('_').length == 2 && !ic.structures.hasOwnProperty(name)) {
120787
120968
  let selectStr = (cnt == 0) ? "selected" : "";
120788
120969
 
120970
+ if(cnt == 0) this.selectSets([name]);
120971
+
120789
120972
  html += "<option value='" + name + "' style='color:#" + color + "' " + selectStr + ">" + name + "</option>";
120790
120973
  bFoundProtein = true;
120791
120974
  ++cnt;
120792
120975
  }
120793
120976
  }
120794
- else {
120977
+ else {
120795
120978
  if(commandnameArray.indexOf(name) != -1) {
120796
120979
  html += "<option value='" + name + "' style='color:#" + color + "' selected='selected'>" + name + "</option>";
120797
120980
  }
@@ -121974,6 +122157,20 @@ class LoadScript {
121974
122157
  await ic.diagram2dCls.drawIgdgm(chainid);
121975
122158
  ic.bRender = false;
121976
122159
  }
122160
+ else if(command.indexOf('update ig') == 0) {
122161
+ let paraArray = command.split(' ');
122162
+ let igIndex_igType = (paraArray.length == 3) ? paraArray[2] : '';
122163
+ await ic.diagram2dCls.show2DdgmForIg(igIndex_igType[0], igIndex_igType[1]);
122164
+ }
122165
+ else if(command.indexOf('download 2d ig') == 0) {
122166
+ let paraArray = command.split(' | ');
122167
+ let pos = command.lastIndexOf(' ');
122168
+ let chainid = (paraArray.length == 2) ? paraArray[1] : command.substr(pos + 1);
122169
+
122170
+ ic.bRender = true;
122171
+ await ic.diagram2dCls.drawIgdgm(chainid, true);
122172
+ ic.bRender = false;
122173
+ }
121977
122174
  else if(command.indexOf('add msa track') == 0) {
121978
122175
  //add msa track | chainid " + chainid + " | startpos " + startpos + " | type " + type + " | fastaList " + fastaList
121979
122176
  let paraArray = command.split(' | ');
@@ -129320,6 +129517,74 @@ class Diagram2d {
129320
129517
  //}
129321
129518
  }
129322
129519
  });
129520
+
129521
+ //$("#" + me.pre + "ig2ddgmDiv").html(svgHtml);
129522
+ $(document).on("change", "#" + me.pre + "iglist", async function(e) { thisClass.icn3d;
129523
+ let igIndex_igType = $("#" + me.pre + "iglist").val().split('_');
129524
+
129525
+ await thisClass.show2DdgmForIg(igIndex_igType[0], igIndex_igType[1]);
129526
+
129527
+ me.htmlCls.clickMenuCls.setLogCmd('update ig ' + igIndex_igType, true);
129528
+ });
129529
+
129530
+ // ig 2D diagram: 2D -> 3D
129531
+ $(document).on('click', '#ig2ddgmSvg .node', function(e) { let ic = thisClass.icn3d;
129532
+ // clear all node color
129533
+ thisClass.resetAllNodes('ig2ddgmSvg');
129534
+
129535
+ $(this).css({'font-size': '20px', 'font-weight': 'bold'});
129536
+
129537
+ //<text x="502.1" y="301.8" class="s9 c8547"><title>Ref. Num. 8547</title> N99 </text>
129538
+ let text = $(this).html().trim();
129539
+ let resnresi = text.substr(text.lastIndexOf(' ') + 1);
129540
+
129541
+ let resid = ic.ncbi2resid[ic.ig2ddgm_chainid + '_' + resnresi.substr(1)];
129542
+
129543
+ // highlight the selected residue
129544
+ if(ic.bCtrl || ic.bShift) {
129545
+ ic.hAtoms = me.hashUtilsCls.unionHash(ic.hAtoms, ic.residues[resid]);
129546
+ }
129547
+ else {
129548
+ ic.hAtoms = ic.residues[resid];
129549
+ }
129550
+
129551
+ ic.hlUpdateCls.showHighlight();
129552
+ });
129553
+
129554
+ // $(document).on('mouseout', '#ig2ddgmSvg .node', function(e) { let ic = thisClass.icn3d;
129555
+ // thisClass.resetAllNodes('ig2ddgmSvg');
129556
+ // });
129557
+
129558
+ // ig 2D diagram: 3D -> 2D
129559
+ $(document).on('icn3d.pick.click icn3d.pick.mouseover', function(ev, data) { let ic = thisClass.icn3d;
129560
+ // get the residues in the selection
129561
+ let ncbiresid = data;
129562
+ let resid = ic.ncbi2resid[ncbiresid];
129563
+
129564
+ if(ic.ig2ddgm_chainid && ic.resid2refnum && ic.resid2refnum[resid]) {
129565
+ let refnumLabel = ic.resid2refnum[resid];
129566
+ let refnumStr = ic.refnumCls.rmStrandFromRefnumlabel(refnumLabel);
129567
+
129568
+ // clear all node color
129569
+ thisClass.resetAllNodes('ig2ddgmSvg');
129570
+
129571
+ // highlight the residue
129572
+ $("#ig2ddgmSvg .c" + refnumStr).css({'font-size': '20px', 'font-weight': 'bold'});
129573
+ }
129574
+ });
129575
+ }
129576
+
129577
+ // reset all nodes
129578
+ resetAllNodes(id) { let ic = this.icn3d; ic.icn3dui;
129579
+ // Select the SVG container
129580
+ const svg = document.getElementById(id);
129581
+
129582
+ // Select all text-related nodes: <text>
129583
+ const textElements = svg.querySelectorAll('text');
129584
+
129585
+ textElements.forEach((node) => {
129586
+ node.style = {};
129587
+ });
129323
129588
  }
129324
129589
 
129325
129590
  clickNode(node) { let ic = this.icn3d, me = ic.icn3dui;
@@ -129987,7 +130252,12 @@ class Diagram2d {
129987
130252
  html += " line.setAttribute('y2', node2.y);\n";
129988
130253
  html += " line.setAttribute('stroke', 'black');\n";
129989
130254
  html += " line.setAttribute('stroke-width', '1');\n";
129990
- html += " line.setAttribute('title', '" + type + "');\n";
130255
+ //html += " line.setAttribute('title', '" + type + "');\n";
130256
+
130257
+ html += " var title = document.createElementNS('http://www.w3.org/2000/svg', 'title');\n";
130258
+ html += " title.textContent = '" + pos1 + " - " + pos2 + "; " + type + "';\n";
130259
+ html += " line.appendChild(title);\n";
130260
+
129991
130261
  html += " rnaCanvas.drawing.domNode.appendChild(line);";
129992
130262
  html += "}\n";
129993
130263
  }
@@ -130008,10 +130278,12 @@ class Diagram2d {
130008
130278
  $("#" + me.pre + "rnacanvasDiv").html(html);
130009
130279
  }
130010
130280
 
130011
- async drawIgdgm(chainid) { let ic = this.icn3d, me = ic.icn3dui;
130281
+ async drawIgdgm(chainid, bDownload) { let ic = this.icn3d, me = ic.icn3dui;
130012
130282
  // select the current chain
130013
130283
  //ic.hAtoms = me.hashUtilsCls.cloneHash(ic.chains[chainid]);
130014
130284
 
130285
+ ic.ig2ddgm_chainid = chainid;
130286
+
130015
130287
  // run ig detection
130016
130288
  ic.bRunRefnumAgain = true;
130017
130289
  if(!ic.bAnnoShown) await ic.showAnnoCls.showAnnotations();
@@ -130035,7 +130307,7 @@ class Diagram2d {
130035
130307
 
130036
130308
  let igType = ic.ref2igtype[info.refpdbname];
130037
130309
 
130038
- if(igType == 'IgV' || igType == 'IgC1' || igType == 'IgC2' || igType == 'IgI') {
130310
+ if(igType == 'IgV' || igType == 'IgC1' || igType == 'IgC2' || igType == 'IgI' || igType == 'IgFN3') {
130039
130311
  bFound = true;
130040
130312
  }
130041
130313
 
@@ -130043,12 +130315,12 @@ class Diagram2d {
130043
130315
  }
130044
130316
 
130045
130317
  if(!bFound) {
130046
- var aaa = 1; //alert("The Ig type(s) for chain " + chainid + " is/are " + igTypeArray + ". Currently only IgV, IgC1, IgC2 and IgI types are supported for drawing Ig diagrams.");
130318
+ var aaa = 1; //alert("The Ig type(s) for chain " + chainid + " is/are " + igTypeArray + ". Currently only IgV, IgC1, IgC2, IgI and IgFN3 types are supported for drawing Ig diagrams.");
130047
130319
  return;
130048
130320
  }
130049
130321
 
130050
130322
  // get the hash of refnum to resn
130051
- let refnum2resn = {};
130323
+ ic.refnum2resn = {};
130052
130324
  for(let resid in ic.resid2refnum) {
130053
130325
  let atom = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[resid]);
130054
130326
  if(!atom) continue;
@@ -130061,88 +130333,154 @@ class Diagram2d {
130061
130333
 
130062
130334
  if(refnumLabel) {
130063
130335
  refnumStr = ic.refnumCls.rmStrandFromRefnumlabel(refnumLabel);
130064
- if(!refnum2resn[domainid]) refnum2resn[domainid] = {};
130065
- refnum2resn[domainid][refnumStr] = resn + resid.split('_')[2];
130336
+ if(!ic.refnum2resn[domainid]) ic.refnum2resn[domainid] = {};
130337
+ ic.refnum2resn[domainid][refnumStr] = resn + resid.split('_')[2];
130066
130338
  }
130067
130339
  }
130068
130340
 
130069
- if(ic.bXlsx === undefined) {
130070
- let urlScript = "/Structure/icn3d/script/exceljs.min.js";
130071
- await me.getAjaxPromise(urlScript, 'script');
130341
+ if(bDownload) {
130342
+ if(ic.bXlsx === undefined) {
130343
+ let urlScript = "/Structure/icn3d/script/exceljs.min.js";
130344
+ await me.getAjaxPromise(urlScript, 'script');
130072
130345
 
130073
- ic.bXlsx = true;
130074
- }
130346
+ ic.bXlsx = true;
130347
+ }
130075
130348
 
130076
- const mainWorkbook = new ExcelJS.Workbook();
130349
+ const mainWorkbook = new ExcelJS.Workbook();
130077
130350
 
130078
- let ig2width = {'IgC1': 17, 'IgC2': 18, 'IgI': 19, 'IgV': 19};
130351
+ let ig2width = {'IgC1': 17, 'IgC2': 18, 'IgI': 19, 'IgV': 19};
130079
130352
 
130080
- for(let i = 0, il = igArray.length; i < il; ++i) {
130081
- let domainid = igArray[i].domainid;
130082
- let igType = igTypeArray[i];
130083
- if(!(igType == 'IgV' || igType == 'IgC1' || igType == 'IgC2' || igType == 'IgI')) {
130084
- mainWorkbook.addWorksheet((i + 1) + ". " + igType);
130085
- }
130086
- else {
130087
- let url = "/Structure/icn3d/template/igstrand_template_" + igType + ".xlsx";
130088
- let arrayBuffer = await me.getXMLHttpRqstPromise(url, 'GET', 'arraybuffer', 'xlsx');
130089
-
130090
- const workbook = new ExcelJS.Workbook();
130091
- // Load the workbook from the buffer
130092
- await workbook.xlsx.load(arrayBuffer);
130093
- const worksheet = workbook.getWorksheet(1);
130094
-
130095
- const newSheet = mainWorkbook.addWorksheet();
130096
- // Clone the model to transfer styles and data
130097
- newSheet.model = worksheet.model;
130098
- newSheet.name = (i + 1) + ". " + igType;
130099
-
130100
- // Iterate over all rows that have values
130101
- newSheet.eachRow({ includeEmpty: true }, (row, rowNumber) => {
130102
- // Iterate over all cells in the row
130103
- row.eachCell({ includeEmpty: true }, (cell, colNumber) => {
130104
- //console.log(`Cell [${rowNumber}, ${colNumber}] = ${cell.value}`);
130105
- if (cell.value && !isNaN(cell.value) && cell.value > 1000 && cell.value < 10000) {
130106
- if(refnum2resn[domainid].hasOwnProperty(cell.value)) {
130107
- cell.value = refnum2resn[domainid][cell.value];
130353
+ for(let i = 0, il = igArray.length; i < il; ++i) {
130354
+ let domainid = igArray[i].domainid;
130355
+ let igType = igTypeArray[i];
130356
+ if(!(igType == 'IgV' || igType == 'IgC1' || igType == 'IgC2' || igType == 'IgI' || igType == 'IgFN3')) {
130357
+ mainWorkbook.addWorksheet((i + 1) + ". " + igType);
130358
+ }
130359
+ else {
130360
+ let url = "/Structure/icn3d/template/igstrand_template_" + igType + ".xlsx";
130361
+ let arrayBuffer = await me.getXMLHttpRqstPromise(url, 'GET', 'arraybuffer', 'xlsx');
130362
+
130363
+ const workbook = new ExcelJS.Workbook();
130364
+ // Load the workbook from the buffer
130365
+ await workbook.xlsx.load(arrayBuffer);
130366
+ const worksheet = workbook.getWorksheet(1);
130367
+
130368
+ const newSheet = mainWorkbook.addWorksheet();
130369
+ // Clone the model to transfer styles and data
130370
+ newSheet.model = worksheet.model;
130371
+ newSheet.name = (i + 1) + ". " + igType;
130372
+
130373
+ // Iterate over all rows that have values
130374
+ newSheet.eachRow({ includeEmpty: true }, (row, rowNumber) => {
130375
+ // Iterate over all cells in the row
130376
+ row.eachCell({ includeEmpty: true }, (cell, colNumber) => {
130377
+ //console.log(`Cell [${rowNumber}, ${colNumber}] = ${cell.value}`);
130378
+ if (cell.value && !isNaN(cell.value) && cell.value > 1000 && cell.value < 10000) {
130379
+ if(ic.refnum2resn[domainid].hasOwnProperty(cell.value)) {
130380
+ cell.value = ic.refnum2resn[domainid][cell.value];
130381
+ }
130382
+ else {
130383
+ cell.value = '';
130384
+ }
130108
130385
  }
130109
- else {
130386
+ else if(cell.value == 'NUMBERING') {
130110
130387
  cell.value = '';
130111
130388
  }
130112
- }
130113
- else if(cell.value == 'NUMBERING') {
130114
- cell.value = '';
130115
- }
130389
+ });
130116
130390
  });
130117
- });
130118
130391
 
130119
- // copy the original data
130120
- let colNum = ig2width[igType]; // some extra columns
130121
- for(let i = 1; i <= colNum; ++i) {
130122
- const sourceCol = worksheet.getColumn(i);
130392
+ // copy the original data
130393
+ let colNum = ig2width[igType]; // some extra columns
130394
+ for(let i = 1; i <= colNum; ++i) {
130395
+ const sourceCol = worksheet.getColumn(i);
130123
130396
 
130124
- // Copy values and styles
130125
- sourceCol.eachCell({ includeEmpty: true }, (cell, rowNumber) => {
130126
- const targetCell = newSheet.getRow(rowNumber).getCell(colNum + 2 + i);
130127
-
130128
- targetCell.value = cell.value;
130129
- targetCell.style = cell.style; // Copies font, borders, and fills
130130
- });
130397
+ // Copy values and styles
130398
+ sourceCol.eachCell({ includeEmpty: true }, (cell, rowNumber) => {
130399
+ const targetCell = newSheet.getRow(rowNumber).getCell(colNum + 2 + i);
130400
+
130401
+ targetCell.value = cell.value;
130402
+ targetCell.style = cell.style; // Copies font, borders, and fills
130403
+ });
130131
130404
 
130132
- // reset width for each column
130133
- newSheet.getColumn(colNum + 2 + i).width = worksheet.getColumn(i).width;
130405
+ // reset width for each column
130406
+ newSheet.getColumn(colNum + 2 + i).width = worksheet.getColumn(i).width;
130407
+ }
130134
130408
  }
130135
130409
  }
130136
- }
130137
130410
 
130138
- // Generate the workbook as a Buffer
130139
- const data = await mainWorkbook.xlsx.writeBuffer();
130411
+ // Generate the workbook as a Buffer
130412
+ const data = await mainWorkbook.xlsx.writeBuffer();
130413
+
130414
+ // Access the underlying ArrayBuffer
130415
+ ic.saveFileCls.saveFile(ic.inputid + '_ig_diagram.xlsx', 'xlsx', data);
130416
+ }
130417
+ else { // show interactive SVG
130418
+ // generate a dropdown menu
130419
+ let menuHtml = '';
130420
+ for(let i = 0, il = igArray.length; i < il; ++i) {
130421
+ igArray[i].domainid;
130422
+ let igType = igTypeArray[i];
130423
+
130424
+ let selStr = (i == 0) ? ' selected' : '';
130425
+ menuHtml += "<option value='" + i + '_' + igType + "' " + selStr + ">" + (i+1) + ". " + igType + "</option>";
130426
+ }
130427
+ $("#" + me.pre + "iglist").html(menuHtml);
130428
+
130429
+ await this.show2DdgmForIg(0, igTypeArray[0]); // default
130140
130430
 
130141
- // Access the underlying ArrayBuffer
130142
- ic.saveFileCls.saveFile(ic.inputid + '_ig_diagram.xlsx', 'xlsx', data);
130431
+ $("#" + me.pre + "iglist").resizable();
130432
+ }
130143
130433
 
130144
130434
  ic.drawCls.draw();
130145
130435
  }
130436
+
130437
+ async show2DdgmForIg(igIndex, igType) { let ic = this.icn3d, me = ic.icn3dui;
130438
+ if(!(igType == 'IgV' || igType == 'IgC1' || igType == 'IgC2' || igType == 'IgI' || igType == 'IgFN3')) {
130439
+ var aaa = 1; //alert("This Ig type " + igType + "has no 2D template yet...");
130440
+ return '';
130441
+ }
130442
+ else {
130443
+ let url = "/Structure/icn3d/template/igstrand_template_" + igType + ".svg";
130444
+ let svgHtml = await me.getAjaxPromise(url, 'text');
130445
+
130446
+ let igArray = ic.chain2igArray[ic.ig2ddgm_chainid];
130447
+ let domainid = igArray[igIndex].domainid;
130448
+
130449
+ // loop through all text node
130450
+ let lineArray = svgHtml.split('\n');
130451
+
130452
+ let html = '';
130453
+ for(let i = 0, il = lineArray.length; i < il; ++i) {
130454
+ let line = lineArray[i];
130455
+ if(line.indexOf('<text ') == 0) { // <text x="502.1" y="301.8" class="s9 c8547"><title>Ref. Num. 8547</title> 8547 </text>
130456
+ let pos = line.indexOf('</title> ');
130457
+ let refnumStr = line.substr(pos + 9).split(' ')[0];
130458
+ let refnum = parseInt(refnumStr);
130459
+
130460
+ if(!isNaN(refnumStr) && refnum > 1000 && refnum < 10000) {
130461
+ if(ic.refnum2resn[domainid].hasOwnProperty(refnumStr)) {
130462
+ let resn = ic.refnum2resn[domainid][refnumStr];
130463
+ let pos2 = line.indexOf('class=');
130464
+ html += line.substr(0, pos2) + 'class="node ' + line.substr(pos2 + 7, pos - (pos2 + 7)) + '</title> ' + resn + ' </text>';
130465
+ }
130466
+ else {
130467
+ html += line.substr(0, pos) + '</title> </text>';
130468
+ }
130469
+ }
130470
+ else {
130471
+ html += line + '\n';
130472
+ }
130473
+ }
130474
+ else {
130475
+ html += line + '\n';
130476
+ }
130477
+ }
130478
+
130479
+ $("#" + me.pre + "ig2ddgmDiv").html(html);
130480
+
130481
+ me.htmlCls.dialogCls.openDlg('dl_ig2ddgm', 'Show 2D diagram for Ig ' + (igIndex + 1) + '.' + igType + ' in ' + ic.ig2ddgm_chainid);
130482
+ }
130483
+ }
130146
130484
  }
130147
130485
 
130148
130486
  /**
@@ -136424,7 +136762,7 @@ class iCn3DUI {
136424
136762
  //even when multiple iCn3D viewers are shown together.
136425
136763
  this.pre = this.cfg.divid + "_";
136426
136764
 
136427
- this.REVISION = '3.50.0';
136765
+ this.REVISION = '3.51.0';
136428
136766
 
136429
136767
  // In nodejs, iCn3D defines "window = {navigator: {}}", and added window = {navigator: {}, "__THREE__":"177"}
136430
136768
  this.bNode = (Object.keys(window).length < 3) ? true : false;