icn3d 3.54.2 → 3.54.4

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
@@ -2550,7 +2550,147 @@ var CIFTools;
2550
2550
  }
2551
2551
  return result(file);
2552
2552
  }
2553
+ /**
2554
+ * Small-molecule / crystallographic ("core") CIF support, e.g. files from COD.
2555
+ * Core CIF uses underscore names (_atom_site_label, _atom_site_fract_x) and fractional
2556
+ * coordinates, while iCn3D's loadCIF expects mmCIF names (_atom_site.label_atom_id)
2557
+ * and Cartesian coordinates. Without conversion getCategory("_atom_site") returns undefined.
2558
+ * This converts such a file to a minimal mmCIF text before it is parsed.
2559
+ */
2560
+ function isCoreCif(data) {
2561
+ return /^\s*_atom_site_fract_x\b/m.test(data) && !/^\s*_atom_site\./m.test(data);
2562
+ }
2563
+ // tokenize one CIF text keeping quotes; returns {tags:[...], loops:[{cols, rows}], singles:{}}
2564
+ function coreTokens(data) {
2565
+ var tokens = [], lines = data.split(/\r?\n/), i, line, m, re = /'([^']*)'(?=\s|$)|"([^"]*)"(?=\s|$)|(\S+)/g;
2566
+ for (i = 0; i < lines.length; i++) {
2567
+ line = lines[i];
2568
+ if (line.charAt(0) === ';') { // multi-line text field, skip it
2569
+ i++;
2570
+ while (i < lines.length && lines[i].charAt(0) !== ';') i++;
2571
+ tokens.push({ v: '?', t: 'text' });
2572
+ continue;
2573
+ }
2574
+ re.lastIndex = 0;
2575
+ while ((m = re.exec(line)) !== null) {
2576
+ if (m[3] !== undefined && m[3].charAt(0) === '#') break; // comment
2577
+ tokens.push(m[3] !== undefined ? { v: m[3] } : { v: (m[1] !== undefined ? m[1] : m[2]), t: 'quoted' });
2578
+ }
2579
+ }
2580
+ return tokens;
2581
+ }
2582
+ function coreToNumber(s) {
2583
+ var v = parseFloat(String(s).replace(/\(\d+\)$/, '')); // 0.7556(3) -> 0.7556
2584
+ return isNaN(v) ? 0 : v;
2585
+ }
2586
+ // symmetry operator like "1/2-x,y,1/2+z" -> function(frac) -> frac
2587
+ function coreSymop(str) {
2588
+ var parts = str.replace(/\s+/g, '').toLowerCase().split(','), rows = [], p, k, re = /([+-]?)(?:(\d+(?:\.\d+)?)(?:\/(\d+))?|([xyz]))/g, m, row, c;
2589
+ if (parts.length !== 3) return null;
2590
+ for (p = 0; p < 3; p++) {
2591
+ row = [0, 0, 0, 0]; // x y z const
2592
+ re.lastIndex = 0;
2593
+ while ((m = re.exec(parts[p])) !== null) {
2594
+ c = (m[1] === '-') ? -1 : 1;
2595
+ if (m[4]) { row['xyz'.indexOf(m[4])] += c; }
2596
+ else { row[3] += c * parseFloat(m[2]) / (m[3] ? parseFloat(m[3]) : 1); }
2597
+ }
2598
+ rows.push(row);
2599
+ }
2600
+ return function (f) {
2601
+ var out = [];
2602
+ for (k = 0; k < 3; k++) out.push(rows[k][0] * f[0] + rows[k][1] * f[1] + rows[k][2] * f[2] + rows[k][3]);
2603
+ return out;
2604
+ };
2605
+ }
2606
+ function convertCoreCif(data) {
2607
+ var tk = coreTokens(data), i = 0, n = tk.length, single = {}, loops = [], name = 'data_core', t, cols, rows, cur;
2608
+ function isTag(x) { return x && !x.t && x.v.charAt(0) === '_'; }
2609
+ while (i < n) {
2610
+ t = tk[i];
2611
+ if (!t.t && /^data_/i.test(t.v)) { name = t.v; i++; }
2612
+ else if (!t.t && /^loop_$/i.test(t.v)) {
2613
+ i++; cols = []; rows = [];
2614
+ while (i < n && isTag(tk[i])) cols.push(tk[i++].v.toLowerCase());
2615
+ cur = [];
2616
+ while (i < n && !isTag(tk[i]) && !(/^(loop_|data_)/i.test(tk[i].v) && !tk[i].t)) {
2617
+ cur.push(tk[i++].v);
2618
+ if (cur.length === cols.length) { rows.push(cur); cur = []; }
2619
+ }
2620
+ loops.push({ cols: cols, rows: rows });
2621
+ }
2622
+ else if (isTag(t)) { single[t.v.toLowerCase()] = (tk[i + 1] ? tk[i + 1].v : '?'); i += 2; }
2623
+ else i++;
2624
+ }
2625
+ var atoms = null, symops = [], l, c;
2626
+ for (l = 0; l < loops.length; l++) {
2627
+ if (loops[l].cols.indexOf('_atom_site_fract_x') >= 0) atoms = loops[l];
2628
+ c = loops[l].cols.indexOf('_symmetry_equiv_pos_as_xyz');
2629
+ if (c < 0) c = loops[l].cols.indexOf('_space_group_symop_operation_xyz');
2630
+ if (c >= 0) loops[l].rows.forEach(function (r) { var f = coreSymop(r[c]); if (f) symops.push(f); });
2631
+ }
2632
+ if (!atoms) return null;
2633
+ if (!symops.length) symops.push(coreSymop('x,y,z'));
2634
+
2635
+ // orthogonalization matrix (a along x, c* along z)
2636
+ var a = coreToNumber(single['_cell_length_a']), b = coreToNumber(single['_cell_length_b']), cc = coreToNumber(single['_cell_length_c']);
2637
+ var al = coreToNumber(single['_cell_angle_alpha'] || 90) * Math.PI / 180, be = coreToNumber(single['_cell_angle_beta'] || 90) * Math.PI / 180, ga = coreToNumber(single['_cell_angle_gamma'] || 90) * Math.PI / 180;
2638
+ var cosa = Math.cos(al), cosb = Math.cos(be), cosg = Math.cos(ga), sing = Math.sin(ga);
2639
+ var vol = Math.sqrt(1 - cosa * cosa - cosb * cosb - cosg * cosg + 2 * cosa * cosb * cosg);
2640
+ function toCart(f) {
2641
+ return [a * f[0] + b * cosg * f[1] + cc * cosb * f[2],
2642
+ b * sing * f[1] + cc * (cosa - cosb * cosg) / sing * f[2],
2643
+ cc * vol / sing * f[2]];
2644
+ }
2645
+ var col = {}; atoms.cols.forEach(function (x, k) { col[x] = k; });
2646
+ function get(r, key) { return (col[key] === undefined) ? '?' : r[col[key]]; }
2647
+
2648
+ var out = [name, '#', '_entry.id ' + name.substr(5), '#'];
2649
+ // core CIF "_cell_length_a" -> mmCIF "_cell.length_a" so iCn3D can parse the unit cell
2650
+ Object.keys(single).forEach(function (key) {
2651
+ if (/^_cell_/.test(key)) out.push(key.replace(/^_cell_/, '_cell.') + ' ' + String(single[key]).replace(/\(\d+\)$/, ''));
2652
+ });
2653
+ out.push('#');
2654
+ out.push(
2655
+ 'loop_', '_atom_site.group_PDB', '_atom_site.id', '_atom_site.type_symbol', '_atom_site.label_atom_id', '_atom_site.label_alt_id',
2656
+ '_atom_site.label_comp_id', '_atom_site.label_asym_id', '_atom_site.label_entity_id', '_atom_site.label_seq_id',
2657
+ '_atom_site.Cartn_x', '_atom_site.Cartn_y', '_atom_site.Cartn_z', '_atom_site.occupancy', '_atom_site.B_iso_or_equiv',
2658
+ '_atom_site.auth_seq_id', '_atom_site.auth_asym_id', '_atom_site.pdbx_PDB_model_num');
2659
+ var serial = 0, seen = [], r, s, f, g, k, dup, j, sym, el, lab, cart;
2660
+ for (r = 0; r < atoms.rows.length; r++) {
2661
+ var row = atoms.rows[r];
2662
+ if (get(row, '_atom_site_calc_flag') === 'dum') continue; // dummy atoms
2663
+ f = [coreToNumber(get(row, '_atom_site_fract_x')), coreToNumber(get(row, '_atom_site_fract_y')), coreToNumber(get(row, '_atom_site_fract_z'))];
2664
+ lab = get(row, '_atom_site_label');
2665
+ sym = get(row, '_atom_site_type_symbol'); if (sym === '?') sym = lab;
2666
+ el = (sym.match(/^[A-Za-z]{1,2}/) || ['X'])[0];
2667
+ el = el.charAt(0).toUpperCase() + el.substr(1).toLowerCase();
2668
+ var mySeen = [];
2669
+ for (s = 0; s < symops.length; s++) {
2670
+ g = symops[s](f).map(function (v) { return v - Math.floor(v + 1e-6); });
2671
+ dup = false;
2672
+ for (j = 0; j < mySeen.length; j++) {
2673
+ if (Math.abs(mySeen[j][0] - g[0]) < 1e-3 && Math.abs(mySeen[j][1] - g[1]) < 1e-3 && Math.abs(mySeen[j][2] - g[2]) < 1e-3) { dup = true; break; }
2674
+ }
2675
+ if (dup) continue;
2676
+ mySeen.push(g);
2677
+ cart = toCart(g);
2678
+ out.push(['HETATM', ++serial, el, lab, '.', 'MOL', 'A', 1, '.', cart[0].toFixed(3), cart[1].toFixed(3), cart[2].toFixed(3),
2679
+ coreToNumber(get(row, '_atom_site_occupancy') === '?' ? 1 : get(row, '_atom_site_occupancy')), '0.00', 1, 'A', 1].join(' '));
2680
+ }
2681
+ }
2682
+ out.push('#');
2683
+ return out.join('\n') + '\n';
2684
+ }
2553
2685
  function parse(data) {
2686
+ if (isCoreCif(data)) {
2687
+ var converted = convertCoreCif(data);
2688
+ if (converted) data = converted;
2689
+ }
2690
+ else {
2691
+ // "_cell_angle_alpha" -> "_cell.angle_alpha"
2692
+ data = data.replace(/^(\s*_cell)_(?=\w)/gm, '$1.');
2693
+ }
2554
2694
  return parseInternal(data);
2555
2695
  }
2556
2696
  Text.parse = parse;
@@ -60275,6 +60415,16 @@ class ClickMenu {
60275
60415
  thisClass.setLogCmd('set axis off', true);
60276
60416
  });
60277
60417
 
60418
+ me.myEventCls.onIds("#" + me.pre + "mn6_showucYes", "click", function(e) { let ic = me.icn3d; //e.preventDefault();
60419
+ ic.setOptionCls.setOption('unitcell', 'yes');
60420
+ thisClass.setLogCmd('set unitcell on', true);
60421
+ });
60422
+
60423
+ me.myEventCls.onIds("#" + me.pre + "mn6_showucNo", "click", function(e) { let ic = me.icn3d; //e.preventDefault();
60424
+ ic.setOptionCls.setOption('unitcell', 'no');
60425
+ thisClass.setLogCmd('set unitcell off', true);
60426
+ });
60427
+
60278
60428
  me.myEventCls.onIds("#" + me.pre + "mn6_symmetry", "click", async function(e) { let ic = me.icn3d; //e.preventDefault();
60279
60429
  ic.bAxisOnly = false;
60280
60430
  await ic.symdCls.retrieveSymmetry(Object.keys(ic.structures)[0]);
@@ -61594,6 +61744,15 @@ class SetMenu {
61594
61744
  html += "</ul>";
61595
61745
  html += "</li>";
61596
61746
 
61747
+ // if(me.cfg.mmcifid !== undefined) {
61748
+ html += this.getMenuText('mn2_unitcell', 'Unit Cell', undefined, undefined, 1);
61749
+ html += "<ul>";
61750
+ html += this.getRadio('mn6_showuc', 'mn6_showucYes', 'Show', undefined, undefined, 2);
61751
+ html += this.getRadio('mn6_showuc', 'mn6_showucNo', 'Hide', true, undefined, 2);
61752
+ html += "</ul>";
61753
+ html += "</li>";
61754
+ // }
61755
+
61597
61756
  html += this.getMenuSep();
61598
61757
 
61599
61758
  html += this.getMenuText('mn2_resetwrap', 'Reset', undefined, 1, 1);
@@ -82557,6 +82716,57 @@ class Axes {
82557
82716
 
82558
82717
  return axisPos;
82559
82718
  }
82719
+
82720
+ buildUnitcell() { let ic = this.icn3d, me = ic.icn3dui;
82721
+ if(!ic.cell) {
82722
+ var aaa = 1; //alert("Unit cell information is available for structures from mmCIF files. Please load a structure from mmCIF file.");
82723
+ return;
82724
+ }
82725
+
82726
+ let a = ic.cell.length_a;
82727
+ let b = ic.cell.length_b;
82728
+ let c = ic.cell.length_c;
82729
+ let alpha = ic.cell.angle_alpha;
82730
+ let beta = ic.cell.angle_beta;
82731
+ let gamma = ic.cell.angle_gamma;
82732
+
82733
+ const rad = d => d * Math.PI / 180;
82734
+ const ca = Math.cos(rad(alpha));
82735
+ const cb = Math.cos(rad(beta));
82736
+ const cg = Math.cos(rad(gamma));
82737
+ const sg = Math.sin(rad(gamma));
82738
+
82739
+ // Lattice vectors
82740
+ const va = [a, 0, 0];
82741
+ const vb = [b * cg, b * sg, 0];
82742
+ const cx = c * cb;
82743
+ const cy = c * (ca - cb * cg) / sg;
82744
+ const cz = Math.sqrt(c * c - cx * cx - cy * cy);
82745
+ const vc = [cx, cy, cz];
82746
+
82747
+ // 8 corners, indexed by bits (i, j, k) -> i*va + j*vb + k*vc
82748
+ const corner = (i, j, k) => [0, 1, 2].map(n => i * va[n] + j * vb[n] + k * vc[n]);
82749
+
82750
+ let color = me.htmlCls.ORANGE, radius = 0.1;
82751
+ let atomColor = me.parasCls.thr(color);
82752
+
82753
+ for (let i = 0; i < 2; i++) {
82754
+ for (let j = 0; j < 2; j++) {
82755
+ ic.analysisCls.addLine(corner(0, i, j)[0], corner(0, i, j)[1], corner(0, i, j)[2], corner(1, i, j)[0], corner(1, i, j)[1], corner(1, i, j)[2], color, false, 'unitcell', radius); // edges along a
82756
+ ic.analysisCls.addLine(corner(i, 0, j)[0], corner(i, 0, j)[1], corner(i, 0, j)[2], corner(i, 1, j)[0], corner(i, 1, j)[1], corner(i, 1, j)[2], color, false, 'unitcell', radius); // edges along b
82757
+ ic.analysisCls.addLine(corner(i, j, 0)[0], corner(i, j, 0)[1], corner(i, j, 0)[2], corner(i, j, 1)[0], corner(i, j, 1)[1], corner(i, j, 1)[2], color, false, 'unitcell', radius); // edges along c
82758
+ }
82759
+ }
82760
+
82761
+ // add sphere at each corner
82762
+ for (let i = 0; i < 2; i++) {
82763
+ for (let j = 0; j < 2; j++) {
82764
+ for (let k = 0; k < 2; k++) {
82765
+ ic.sphereCls.createSphereBase(new Vector3$1(corner(i, j, k)[0], corner(i, j, k)[1], corner(i, j, k)[2]), atomColor, radius, 1, false, false, 1);
82766
+ }
82767
+ }
82768
+ }
82769
+ }
82560
82770
  }
82561
82771
 
82562
82772
  /**
@@ -86553,7 +86763,7 @@ class ApplyOther {
86553
86763
  ic.applyCenterCls.applyCenterOptions(options);
86554
86764
 
86555
86765
  ic.axesCls.buildAllAxes(undefined, true);
86556
-
86766
+
86557
86767
  switch (options.axis.toLowerCase()) {
86558
86768
  case 'yes':
86559
86769
  ic.axis = true;
@@ -86564,6 +86774,19 @@ class ApplyOther {
86564
86774
  ic.axis = false;
86565
86775
  break;
86566
86776
  }
86777
+
86778
+ ic.lines['unitcell'] = []; // reset
86779
+
86780
+ switch (options.unitcell.toLowerCase()) {
86781
+ case 'yes':
86782
+ ic.unitcell = true;
86783
+ ic.axesCls.buildUnitcell();
86784
+
86785
+ break;
86786
+ case 'no':
86787
+ ic.unitcell = false;
86788
+ break;
86789
+ }
86567
86790
  switch (options.pk.toLowerCase()) {
86568
86791
  case 'atom':
86569
86792
  ic.pk = 1;
@@ -105949,14 +106172,7 @@ class WebGLPathTracer {
105949
106172
  ic.setOptionCls.setStyle("proteins", atom.style);
105950
106173
  }
105951
106174
 
105952
- //Render the scene and objects into pixels.
105953
- render_base(bPathTracer) { let ic = this.icn3d, me = ic.icn3dui;
105954
- let thisClass = this;
105955
-
105956
- if(me.bNode) return;
105957
-
105958
- let cam = (ic.bControlGl && !me.bNode) ? window.cam : ic.cam;
105959
-
106175
+ setDirectLight(cam) { let ic = this.icn3d; ic.icn3dui;
105960
106176
  if(ic.directionalLight) {
105961
106177
  let quaternion = new Quaternion();
105962
106178
  quaternion.setFromUnitVectors( new Vector3$1(0, 0, ic.cam_z).normalize(), cam.position.clone().normalize() );
@@ -105971,6 +106187,19 @@ class WebGLPathTracer {
105971
106187
  ic.directionalLight3.applyMatrix4(cam.matrixWorld);
105972
106188
  }
105973
106189
 
106190
+ return cam;
106191
+ }
106192
+
106193
+ //Render the scene and objects into pixels.
106194
+ render_base(bPathTracer) { let ic = this.icn3d, me = ic.icn3dui;
106195
+ let thisClass = this;
106196
+
106197
+ if(me.bNode) return;
106198
+
106199
+ let cam = (ic.bControlGl && !me.bNode) ? window.cam : ic.cam;
106200
+
106201
+ cam = this.setDirectLight(cam);
106202
+
105974
106203
  if(!ic.bVr) ic.renderer.setPixelRatio( window.devicePixelRatio ); // r71
105975
106204
 
105976
106205
  if(ic.bVr) {
@@ -106012,8 +106241,14 @@ class WebGLPathTracer {
106012
106241
  else {
106013
106242
  if(bPathTracer) {
106014
106243
  ic.bImpo = false; // disable impostor for path tracing
106244
+ // remove the highlights since they are not 3D objects
106245
+ ic.hlUpdateCls.clearHighlight();
106246
+
106015
106247
  const pathTracer = new WebGLPathTracer(ic.renderer);
106016
106248
  pathTracer.setScene(ic.scene, cam);
106249
+
106250
+ cam = this.setDirectLight(cam);
106251
+
106017
106252
  //pathTracer.renderUpdates(); // Updates samples if the scene/camera changes
106018
106253
  //pathTracer.render(ic.scene, cam);
106019
106254
 
@@ -127072,7 +127307,10 @@ class PdbParser {
127072
127307
 
127073
127308
  ic.saveFileCls.showTitle();
127074
127309
 
127075
- if(me.cfg.rotate !== undefined) ic.resizeCanvasCls.rotStruc(me.cfg.rotate, true);
127310
+ // if(me.cfg.rotate !== undefined) {
127311
+ if(me.cfg.rotate !== undefined && !(me.cfg.url && me.cfg.url.indexOf('membranome') != -1)) {
127312
+ ic.resizeCanvasCls.rotStruc(me.cfg.rotate, true);
127313
+ }
127076
127314
 
127077
127315
  if(bAppend && Object.keys(ic.structures).length == 1 && !me.bNode) {
127078
127316
  // show all
@@ -131325,6 +131563,7 @@ class ParserUtils {
131325
131563
  let angle = -0.5 * Math.PI;
131326
131564
  ic.transformCls.setRotation(axis, angle);
131327
131565
  }
131566
+
131328
131567
  //if(Object.keys(ic.structures).length > 1) {
131329
131568
  // $("#" + ic.pre + "alternate").show();
131330
131569
  //}
@@ -135287,6 +135526,16 @@ class LoadCIF {
135287
135526
  = m24Array = m31Array = m32Array = m33Array = m34Array = [];
135288
135527
  }
135289
135528
 
135529
+ if(block.getCategory("_cell")) {
135530
+ ic.cell = {};
135531
+ ic.cell.length_a = parseFloat(block.getCategory("_cell").getColumn("length_a").getString(0));
135532
+ ic.cell.length_b = parseFloat(block.getCategory("_cell").getColumn("length_b").getString(0));
135533
+ ic.cell.length_c = parseFloat(block.getCategory("_cell").getColumn("length_c").getString(0));
135534
+ ic.cell.angle_alpha = parseFloat(block.getCategory("_cell").getColumn("angle_alpha").getString(0));
135535
+ ic.cell.angle_beta = parseFloat(block.getCategory("_cell").getColumn("angle_beta").getString(0));
135536
+ ic.cell.angle_gamma = parseFloat(block.getCategory("_cell").getColumn("angle_gamma").getString(0));
135537
+ }
135538
+
135290
135539
  // if (record === 'ENDMDL') {
135291
135540
  // ++moleculeNum;
135292
135541
  // id = ic.defaultPdbId;
@@ -136905,6 +137154,12 @@ class ApplyCommand {
136905
137154
  ic.opts['axis'] = 'no';
136906
137155
  ic.pc1 = false;
136907
137156
  }
137157
+ else if(command == 'set unitcell on') {
137158
+ ic.opts['unitcell'] = 'yes';
137159
+ }
137160
+ else if(command == 'set unitcell off') {
137161
+ ic.opts['unitcell'] = 'no';
137162
+ }
136908
137163
  else if(command == 'set fog on') {
136909
137164
  ic.opts['fog'] = 'yes';
136910
137165
  ic.fogCls.setFog(true);
@@ -147387,9 +147642,10 @@ class Diagram2d {
147387
147642
  // get the residues in the selection
147388
147643
  let ncbiresid = data;
147389
147644
  let resid = ic.ncbi2resid[ncbiresid];
147390
- let resi = resid.substr(resid.lastIndexOf('_') + 1);
147391
147645
 
147392
- if(ic.ig2ddgm_chainid && ic.resid2refnum && ic.resid2refnum[resid]) {
147646
+ if(resid && ic.ig2ddgm_chainid && ic.resid2refnum && ic.resid2refnum[resid]) {
147647
+ let resi = resid.substr(resid.lastIndexOf('_') + 1);
147648
+
147393
147649
  let refnumLabel = ic.resid2refnum[resid];
147394
147650
  let refnumStr = ic.refnumCls.rmStrandFromRefnumlabel(refnumLabel);
147395
147651
 
@@ -151162,7 +151418,8 @@ class SaveFile {
151162
151418
  idName = "PDB ID";
151163
151419
  }
151164
151420
  else if(bAlphaFold) {
151165
- idName = "AlphaFold ID";
151421
+ // idName = "AlphaFold ID";
151422
+ idName = "ID";
151166
151423
  }
151167
151424
 
151168
151425
  if(structureidArray.length > 1) {
@@ -154083,6 +154340,7 @@ class iCn3D {
154083
154340
  this.radiusArraySphere = new Array();
154084
154341
 
154085
154342
  this.axis = false; // used to turn on and off xyz axes
154343
+ this.unitcell = false; // used to turn on and off unit cell
154086
154344
 
154087
154345
  // pk
154088
154346
  //If its value is 1, selecting an atom will select the atom. If its value is 2, selecting an atom
@@ -154204,6 +154462,7 @@ class iCn3D {
154204
154462
  this.optsOri['clbonds'] = 'yes'; //yes, no
154205
154463
  this.optsOri['rotationcenter'] = 'molecule center'; //molecule center, pick center, display center
154206
154464
  this.optsOri['axis'] = 'no'; //yes, no
154465
+ this.optsOri['unitcell'] = 'no'; //yes, no
154207
154466
  this.optsOri['fog'] = 'no'; //yes, no
154208
154467
  this.optsOri['slab'] = 'no'; //yes, no
154209
154468
  this.optsOri['pk'] = 'residue'; //no, atom, residue, strand, chain
@@ -154621,7 +154880,7 @@ class iCn3DUI {
154621
154880
  //even when multiple iCn3D viewers are shown together.
154622
154881
  this.pre = this.cfg.divid + "_";
154623
154882
 
154624
- this.REVISION = '3.54.0';
154883
+ this.REVISION = '3.54.2';
154625
154884
 
154626
154885
  // In nodejs, iCn3D defines "window = {navigator: {}}", and added window = {navigator: {}, "__THREE__":"177"}
154627
154886
  this.bNode = (Object.keys(window).length < 3) ? true : false;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "icn3d",
3
- "version": "3.54.2",
3
+ "version": "3.54.4",
4
4
  "main": "./icn3d.js",
5
5
  "exports": {
6
6
  ".": {