Revision: 20960
          http://sourceforge.net/p/jmol/code/20960
Author:   hansonr
Date:     2016-02-15 01:27:16 +0000 (Mon, 15 Feb 2016)
Log Message:
-----------
Jmol.___JmolVersion="14.4.2_2016.02.14"

FEATURE CHANGE: JSmol default for Info._disableInitialConsole changed to true
 -- no longer necessary with JSmol_spinner.gif 

new feature: j2s/img/JSmol_spinner.gif implemented (Angel Herraez)
 -- as default for Info._appletLoadingImage
 -- use Info._appletLoadingImage = "none" to disable

new feature: j2s/img/cursor_wait.gif animation implemented

bug fix: EBI assembly CIF files that are multi-model files will be by chain, 
not by model.
  -- result was that each chain became a new model
  -- for example: see 
http://www.ebi.ac.uk/pdbe/static/entry/download/2lev-assembly-1.cif.gz

bug fix: XmlMolProReader does not recognize FILTER "NOMO"
bug fix: JSmol has never shown cursors

Modified Paths:
--------------
    branches/v14_4/Jmol/src/org/jmol/adapter/readers/cif/CifReader.java
    branches/v14_4/Jmol/src/org/jmol/adapter/readers/cif/MMCifReader.java
    branches/v14_4/Jmol/src/org/jmol/adapter/smarter/AtomIterator.java
    branches/v14_4/Jmol/src/org/jmol/adapter/smarter/AtomSetCollection.java
    
branches/v14_4/Jmol/src/org/jmol/adapter/smarter/AtomSetCollectionReader.java
    branches/v14_4/Jmol/src/org/jmol/adapter/smarter/Structure.java
    branches/v14_4/Jmol/src/org/jmol/viewer/Jmol.properties
    trunk/Jmol/src/org/jmol/adapter/readers/cif/CifReader.java
    trunk/Jmol/src/org/jmol/adapter/readers/cif/MMCifReader.java
    trunk/Jmol/src/org/jmol/adapter/smarter/AtomIterator.java
    trunk/Jmol/src/org/jmol/adapter/smarter/AtomSetCollection.java
    trunk/Jmol/src/org/jmol/adapter/smarter/AtomSetCollectionReader.java
    trunk/Jmol/src/org/jmol/adapter/smarter/Structure.java
    trunk/Jmol/src/org/jmol/viewer/Jmol.properties

Modified: branches/v14_4/Jmol/src/org/jmol/adapter/readers/cif/CifReader.java
===================================================================
--- branches/v14_4/Jmol/src/org/jmol/adapter/readers/cif/CifReader.java 
2016-02-14 19:27:32 UTC (rev 20959)
+++ branches/v14_4/Jmol/src/org/jmol/adapter/readers/cif/CifReader.java 
2016-02-15 01:27:16 UTC (rev 20960)
@@ -91,7 +91,7 @@
   private int configurationPtr = Integer.MIN_VALUE;
   private boolean useAuthorChainID = true;
 
-  private String thisDataSetName = "", lastDataSetName;
+  protected String thisDataSetName = "", lastDataSetName;
   private String chemicalName = "";
   private String thisStructuralFormula = "";
   private String thisFormula = "";
@@ -1043,7 +1043,7 @@
           continue;
         }
       }
-      String assemblyId = null;
+      String componentId = null;
       String strChain = null;
       String id = null;
       int seqID = 0;
@@ -1137,7 +1137,7 @@
           atom.group3 = field;
           break;
         case ASYM_ID:
-          assemblyId = field;
+          componentId = field;
           if (!useAuthorChainID)
             setChainID(atom, strChain = field);
           break;
@@ -1264,10 +1264,10 @@
       }
       if (atom.elementSymbol == null && atom.atomName != null)
         atom.getElementSymbol();
-      if (!filterCIFAtom(atom, assemblyId))
+      if (!filterCIFAtom(atom, componentId))
         continue;
       setAtomCoord(atom);
-      if (isMMCIF && !processSubclassAtom(atom, assemblyId, strChain))
+      if (isMMCIF && !processSubclassAtom(atom, componentId, strChain))
         continue;
       if (asc.iSet < 0)
         nextAtomSet();
@@ -1316,10 +1316,10 @@
     return true;
   }
 
-  protected boolean filterCIFAtom(Atom atom, String assemblyId) {
+  protected boolean filterCIFAtom(Atom atom, String componentId) {
     if (!filterAtom(atom, -1))
       return false;
-    if (filterAssembly && filterReject(filter, "$", assemblyId))
+    if (filterAssembly && filterReject(filter, "$", componentId))
       return false;
     if (configurationPtr > 0) {
       if (!disorderAssembly.equals(lastDisorderAssembly)) {

Modified: branches/v14_4/Jmol/src/org/jmol/adapter/readers/cif/MMCifReader.java
===================================================================
--- branches/v14_4/Jmol/src/org/jmol/adapter/readers/cif/MMCifReader.java       
2016-02-14 19:27:32 UTC (rev 20959)
+++ branches/v14_4/Jmol/src/org/jmol/adapter/readers/cif/MMCifReader.java       
2016-02-15 01:27:16 UTC (rev 20960)
@@ -164,6 +164,50 @@
 
   }
 
+  private boolean requiresSorting;
+
+  /**
+   * issue here is that mmCIF assembly atoms can be in different blocks by 
chain:
+   * Model1:Chain1 Model2:Chain1 Model1:Chain2 Model2:Chain2 ... and so 
assigned
+   * to too many atom sets.
+   * 
+   */
+  protected void sortAssemblyModels() {
+    int natoms = asc.ac;
+    int lastSet = -1;
+    Atom[] atoms = asc.atoms;
+    Atom[] newAtoms = new Atom[natoms];
+    String[] ids = PT.split("," + modelStrings + ",", ",,");
+    BS bsAtomsNew = (asc.bsAtoms == null ? null : BS.newN(asc.bsAtoms.size()));
+    for (int im = 1, n = 0; im < ids.length; im++) {
+      String sModel = ids[im];
+      int modelIndex = -1;
+      for (int is = 0; is < asc.atomSetCount; is++) {
+        int ia0 = asc.getAtomSetAtomIndex(is);
+        int ia1 = ia0 + asc.getAtomSetAtomCount(is);
+        String am = "" + modelMap.get("_" + is);
+        if (am.equals(sModel)) {
+          if (modelIndex < 0 && (modelIndex = is) > lastSet)
+            lastSet = is;
+          for (int i = ia0; i < ia1; i++) {
+            if (bsAtomsNew == null || asc.bsAtoms.get(i)) {
+              if (bsAtomsNew != null)
+                bsAtomsNew.set(n);
+              atoms[i].atomSetIndex = modelIndex;
+              newAtoms[n++] = atoms[i];
+            }
+          }
+        }
+      }
+
+    }
+    asc.atoms = newAtoms;
+    asc.bsAtoms = bsAtomsNew;
+    if (++lastSet < asc.atomSetCount)
+      asc.atomSetCount = lastSet;
+  }
+
+
   @Override
   protected boolean finalizeSubclass() throws Exception {
     if (byChain && !isBiomolecule)
@@ -172,7 +216,7 @@
     if (!isCourseGrained && asc.ac == nAtoms) {
       asc.removeCurrentAtomSet();
     } else {
-      if ((dssr != null || validation != null || addedData != null) && 
!isCourseGrained) {
+      if ((dssr != null || validation != null || addedData != null) && 
!isCourseGrained && !requiresSorting) {
         MMCifValidationParser vs = ((MMCifValidationParser) 
getInterface("org.jmol.adapter.readers.cif.MMCifValidationParser"))
             .set(this);
         String note = null;
@@ -204,6 +248,8 @@
         asc.xtalSymmetry = null;
       }
     }
+    if (requiresSorting)
+      sortAssemblyModels();
     return true;
   }
 
@@ -1110,16 +1156,31 @@
     return true;
   }
 
+  private String modelStrings = "";
+  
   @Override
   protected int checkPDBModelField(int modelField, int currentModelNo) throws 
Exception {
     // the model field value is only used if 
     // it is indicated AFTER the file name in the load command, 
     // not if we have a MODEL keyword before the file name.
-    // 
+    
     fieldProperty(modelField);
     int modelNo = parseIntStr(field);
     if (modelNo != currentModelNo) {
-      if (iHaveDesiredModel && asc.atomSetCount > 0) {
+      boolean isAssembly = (thisDataSetName != null && 
thisDataSetName.indexOf("-assembly-") >= 0);
+      if (isAssembly) {
+        // Files such as 
http://www.ebi.ac.uk/pdbe/static/entry/download/2lev-assembly-1.cif.gz
+        // may require sorting if there are multiple models, since the models 
are by chain, not by model.
+
+        useFileModelNumbers = true;
+        String key = "," + modelNo + ",";
+        if (modelStrings.indexOf(key) >= 0) {
+          requiresSorting = true;
+        } else {
+          modelStrings += key;
+        }
+      }      
+      if (iHaveDesiredModel && asc.atomSetCount > 0 && !isAssembly) {
         parser.skipLoop(false);
         // but only this atom loop
         skipping = false;

Modified: branches/v14_4/Jmol/src/org/jmol/adapter/smarter/AtomIterator.java
===================================================================
--- branches/v14_4/Jmol/src/org/jmol/adapter/smarter/AtomIterator.java  
2016-02-14 19:27:32 UTC (rev 20959)
+++ branches/v14_4/Jmol/src/org/jmol/adapter/smarter/AtomIterator.java  
2016-02-15 01:27:16 UTC (rev 20960)
@@ -46,7 +46,7 @@
 
        AtomIterator(AtomSetCollection asc) {
                ac = asc.ac;
-               atoms = asc.atoms;
+               atoms = asc.atoms;              
                bsAtoms = asc.bsAtoms;
                iatom = 0;
        }

Modified: 
branches/v14_4/Jmol/src/org/jmol/adapter/smarter/AtomSetCollection.java
===================================================================
--- branches/v14_4/Jmol/src/org/jmol/adapter/smarter/AtomSetCollection.java     
2016-02-14 19:27:32 UTC (rev 20959)
+++ branches/v14_4/Jmol/src/org/jmol/adapter/smarter/AtomSetCollection.java     
2016-02-15 01:27:16 UTC (rev 20960)
@@ -92,6 +92,7 @@
   public int atomSetCount;
   public int iSet = -1;
 
+
   public int[] atomSetNumbers = new int[16];
   public int[] atomSetAtomIndexes = new int[16];
   public int[] atomSetAtomCounts = new int[16];

Modified: 
branches/v14_4/Jmol/src/org/jmol/adapter/smarter/AtomSetCollectionReader.java
===================================================================
--- 
branches/v14_4/Jmol/src/org/jmol/adapter/smarter/AtomSetCollectionReader.java   
    2016-02-14 19:27:32 UTC (rev 20959)
+++ 
branches/v14_4/Jmol/src/org/jmol/adapter/smarter/AtomSetCollectionReader.java   
    2016-02-15 01:27:16 UTC (rev 20960)
@@ -195,6 +195,7 @@
   protected boolean forcePacked;
   public float packingError = 0.02f;
 
+
   // private state variables
 
   private SB loadNote = new SB();

Modified: branches/v14_4/Jmol/src/org/jmol/adapter/smarter/Structure.java
===================================================================
--- branches/v14_4/Jmol/src/org/jmol/adapter/smarter/Structure.java     
2016-02-14 19:27:32 UTC (rev 20959)
+++ branches/v14_4/Jmol/src/org/jmol/adapter/smarter/Structure.java     
2016-02-15 01:27:16 UTC (rev 20960)
@@ -66,7 +66,7 @@
     this.substructureType = substructureType;
     if (structureID == null)
       return;
-    setModels(modelIndex, 0);
+    modelStartEnd[0] = modelStartEnd[1] = modelIndex;
     this.structureID = structureID;
     this.strandCount = strandCount; // 1 for sheet initially; 0 for helix or 
turn
     this.serialID = serialID;
@@ -86,9 +86,4 @@
     atomStartEnd[1] = iend;
   }
   
-  public void setModels(int model1, int model2) {
-    modelStartEnd[0] = model1;
-    modelStartEnd[1] = (model2 == 0 ? model1 : model2);
-  }
-
 }

Modified: branches/v14_4/Jmol/src/org/jmol/viewer/Jmol.properties
===================================================================
--- branches/v14_4/Jmol/src/org/jmol/viewer/Jmol.properties     2016-02-14 
19:27:32 UTC (rev 20959)
+++ branches/v14_4/Jmol/src/org/jmol/viewer/Jmol.properties     2016-02-15 
01:27:16 UTC (rev 20960)
@@ -7,15 +7,21 @@
 
 # see also http://chemapps.stolaf.edu/jmol/zip for daily updates
        
-Jmol.___JmolVersion="14.5.2_2016.02.14"
+Jmol.___JmolVersion="14.4.2_2016.02.14"
 
 FEATURE CHANGE: JSmol default for Info._disableInitialConsole changed to true
- -- no longer necessary with JSmol_spinner.gif
+ -- no longer necessary with JSmol_spinner.gif 
 
-new feature: j2s/img/JSmol_spinner.gif implemented as default for 
Info._appletLoadingImage
+new feature: j2s/img/JSmol_spinner.gif implemented (Angel Herraez)
+ -- as default for Info._appletLoadingImage
+ -- use Info._appletLoadingImage = "none" to disable
 
 new feature: j2s/img/cursor_wait.gif animation implemented
 
+bug fix: EBI assembly CIF files that are multi-model files will be by chain, 
not by model.
+  -- result was that each chain became a new model
+  -- for example: see 
http://www.ebi.ac.uk/pdbe/static/entry/download/2lev-assembly-1.cif.gz
+
 bug fix: XmlMolProReader does not recognize FILTER "NOMO"
 bug fix: JSmol has never shown cursors
 

Modified: trunk/Jmol/src/org/jmol/adapter/readers/cif/CifReader.java
===================================================================
--- trunk/Jmol/src/org/jmol/adapter/readers/cif/CifReader.java  2016-02-14 
19:27:32 UTC (rev 20959)
+++ trunk/Jmol/src/org/jmol/adapter/readers/cif/CifReader.java  2016-02-15 
01:27:16 UTC (rev 20960)
@@ -91,7 +91,7 @@
   private int configurationPtr = Integer.MIN_VALUE;
   private boolean useAuthorChainID = true;
 
-  private String thisDataSetName = "", lastDataSetName;
+  protected String thisDataSetName = "", lastDataSetName;
   private String chemicalName = "";
   private String thisStructuralFormula = "";
   private String thisFormula = "";
@@ -1043,7 +1043,7 @@
           continue;
         }
       }
-      String assemblyId = null;
+      String componentId = null;
       String strChain = null;
       String id = null;
       int seqID = 0;
@@ -1137,7 +1137,7 @@
           atom.group3 = field;
           break;
         case ASYM_ID:
-          assemblyId = field;
+          componentId = field;
           if (!useAuthorChainID)
             setChainID(atom, strChain = field);
           break;
@@ -1264,10 +1264,10 @@
       }
       if (atom.elementSymbol == null && atom.atomName != null)
         atom.getElementSymbol();
-      if (!filterCIFAtom(atom, assemblyId))
+      if (!filterCIFAtom(atom, componentId))
         continue;
       setAtomCoord(atom);
-      if (isMMCIF && !processSubclassAtom(atom, assemblyId, strChain))
+      if (isMMCIF && !processSubclassAtom(atom, componentId, strChain))
         continue;
       if (asc.iSet < 0)
         nextAtomSet();
@@ -1316,10 +1316,10 @@
     return true;
   }
 
-  protected boolean filterCIFAtom(Atom atom, String assemblyId) {
+  protected boolean filterCIFAtom(Atom atom, String componentId) {
     if (!filterAtom(atom, -1))
       return false;
-    if (filterAssembly && filterReject(filter, "$", assemblyId))
+    if (filterAssembly && filterReject(filter, "$", componentId))
       return false;
     if (configurationPtr > 0) {
       if (!disorderAssembly.equals(lastDisorderAssembly)) {

Modified: trunk/Jmol/src/org/jmol/adapter/readers/cif/MMCifReader.java
===================================================================
--- trunk/Jmol/src/org/jmol/adapter/readers/cif/MMCifReader.java        
2016-02-14 19:27:32 UTC (rev 20959)
+++ trunk/Jmol/src/org/jmol/adapter/readers/cif/MMCifReader.java        
2016-02-15 01:27:16 UTC (rev 20960)
@@ -164,6 +164,50 @@
 
   }
 
+  private boolean requiresSorting;
+
+  /**
+   * issue here is that mmCIF assembly atoms can be in different blocks by 
chain:
+   * Model1:Chain1 Model2:Chain1 Model1:Chain2 Model2:Chain2 ... and so 
assigned
+   * to too many atom sets.
+   * 
+   */
+  protected void sortAssemblyModels() {
+    int natoms = asc.ac;
+    int lastSet = -1;
+    Atom[] atoms = asc.atoms;
+    Atom[] newAtoms = new Atom[natoms];
+    String[] ids = PT.split("," + modelStrings + ",", ",,");
+    BS bsAtomsNew = (asc.bsAtoms == null ? null : BS.newN(asc.bsAtoms.size()));
+    for (int im = 1, n = 0; im < ids.length; im++) {
+      String sModel = ids[im];
+      int modelIndex = -1;
+      for (int is = 0; is < asc.atomSetCount; is++) {
+        int ia0 = asc.getAtomSetAtomIndex(is);
+        int ia1 = ia0 + asc.getAtomSetAtomCount(is);
+        String am = "" + modelMap.get("_" + is);
+        if (am.equals(sModel)) {
+          if (modelIndex < 0 && (modelIndex = is) > lastSet)
+            lastSet = is;
+          for (int i = ia0; i < ia1; i++) {
+            if (bsAtomsNew == null || asc.bsAtoms.get(i)) {
+              if (bsAtomsNew != null)
+                bsAtomsNew.set(n);
+              atoms[i].atomSetIndex = modelIndex;
+              newAtoms[n++] = atoms[i];
+            }
+          }
+        }
+      }
+
+    }
+    asc.atoms = newAtoms;
+    asc.bsAtoms = bsAtomsNew;
+    if (++lastSet < asc.atomSetCount)
+      asc.atomSetCount = lastSet;
+  }
+
+
   @Override
   protected boolean finalizeSubclass() throws Exception {
     if (byChain && !isBiomolecule)
@@ -172,7 +216,7 @@
     if (!isCourseGrained && asc.ac == nAtoms) {
       asc.removeCurrentAtomSet();
     } else {
-      if ((dssr != null || validation != null || addedData != null) && 
!isCourseGrained) {
+      if ((dssr != null || validation != null || addedData != null) && 
!isCourseGrained && !requiresSorting) {
         MMCifValidationParser vs = ((MMCifValidationParser) 
getInterface("org.jmol.adapter.readers.cif.MMCifValidationParser"))
             .set(this);
         String note = null;
@@ -204,6 +248,8 @@
         asc.xtalSymmetry = null;
       }
     }
+    if (requiresSorting)
+      sortAssemblyModels();
     return true;
   }
 
@@ -1110,16 +1156,31 @@
     return true;
   }
 
+  private String modelStrings = "";
+  
   @Override
   protected int checkPDBModelField(int modelField, int currentModelNo) throws 
Exception {
     // the model field value is only used if 
     // it is indicated AFTER the file name in the load command, 
     // not if we have a MODEL keyword before the file name.
-    // 
+    
     fieldProperty(modelField);
     int modelNo = parseIntStr(field);
     if (modelNo != currentModelNo) {
-      if (iHaveDesiredModel && asc.atomSetCount > 0) {
+      boolean isAssembly = (thisDataSetName != null && 
thisDataSetName.indexOf("-assembly-") >= 0);
+      if (isAssembly) {
+        // Files such as 
http://www.ebi.ac.uk/pdbe/static/entry/download/2lev-assembly-1.cif.gz
+        // may require sorting if there are multiple models, since the models 
are by chain, not by model.
+
+        useFileModelNumbers = true;
+        String key = "," + modelNo + ",";
+        if (modelStrings.indexOf(key) >= 0) {
+          requiresSorting = true;
+        } else {
+          modelStrings += key;
+        }
+      }      
+      if (iHaveDesiredModel && asc.atomSetCount > 0 && !isAssembly) {
         parser.skipLoop(false);
         // but only this atom loop
         skipping = false;

Modified: trunk/Jmol/src/org/jmol/adapter/smarter/AtomIterator.java
===================================================================
--- trunk/Jmol/src/org/jmol/adapter/smarter/AtomIterator.java   2016-02-14 
19:27:32 UTC (rev 20959)
+++ trunk/Jmol/src/org/jmol/adapter/smarter/AtomIterator.java   2016-02-15 
01:27:16 UTC (rev 20960)
@@ -46,7 +46,7 @@
 
        AtomIterator(AtomSetCollection asc) {
                ac = asc.ac;
-               atoms = asc.atoms;
+               atoms = asc.atoms;              
                bsAtoms = asc.bsAtoms;
                iatom = 0;
        }

Modified: trunk/Jmol/src/org/jmol/adapter/smarter/AtomSetCollection.java
===================================================================
--- trunk/Jmol/src/org/jmol/adapter/smarter/AtomSetCollection.java      
2016-02-14 19:27:32 UTC (rev 20959)
+++ trunk/Jmol/src/org/jmol/adapter/smarter/AtomSetCollection.java      
2016-02-15 01:27:16 UTC (rev 20960)
@@ -92,6 +92,7 @@
   public int atomSetCount;
   public int iSet = -1;
 
+
   public int[] atomSetNumbers = new int[16];
   public int[] atomSetAtomIndexes = new int[16];
   public int[] atomSetAtomCounts = new int[16];

Modified: trunk/Jmol/src/org/jmol/adapter/smarter/AtomSetCollectionReader.java
===================================================================
--- trunk/Jmol/src/org/jmol/adapter/smarter/AtomSetCollectionReader.java        
2016-02-14 19:27:32 UTC (rev 20959)
+++ trunk/Jmol/src/org/jmol/adapter/smarter/AtomSetCollectionReader.java        
2016-02-15 01:27:16 UTC (rev 20960)
@@ -195,6 +195,7 @@
   protected boolean forcePacked;
   public float packingError = 0.02f;
 
+
   // private state variables
 
   private SB loadNote = new SB();

Modified: trunk/Jmol/src/org/jmol/adapter/smarter/Structure.java
===================================================================
--- trunk/Jmol/src/org/jmol/adapter/smarter/Structure.java      2016-02-14 
19:27:32 UTC (rev 20959)
+++ trunk/Jmol/src/org/jmol/adapter/smarter/Structure.java      2016-02-15 
01:27:16 UTC (rev 20960)
@@ -66,7 +66,7 @@
     this.substructureType = substructureType;
     if (structureID == null)
       return;
-    setModels(modelIndex, 0);
+    modelStartEnd[0] = modelStartEnd[1] = modelIndex;
     this.structureID = structureID;
     this.strandCount = strandCount; // 1 for sheet initially; 0 for helix or 
turn
     this.serialID = serialID;
@@ -86,9 +86,4 @@
     atomStartEnd[1] = iend;
   }
   
-  public void setModels(int model1, int model2) {
-    modelStartEnd[0] = model1;
-    modelStartEnd[1] = (model2 == 0 ? model1 : model2);
-  }
-
 }

Modified: trunk/Jmol/src/org/jmol/viewer/Jmol.properties
===================================================================
--- trunk/Jmol/src/org/jmol/viewer/Jmol.properties      2016-02-14 19:27:32 UTC 
(rev 20959)
+++ trunk/Jmol/src/org/jmol/viewer/Jmol.properties      2016-02-15 01:27:16 UTC 
(rev 20960)
@@ -67,12 +67,18 @@
 Jmol.___JmolVersion="14.5.2_2016.02.14"
 
 FEATURE CHANGE: JSmol default for Info._disableInitialConsole changed to true
- -- no longer necessary with JSmol_spinner.gif
+ -- no longer necessary with JSmol_spinner.gif 
 
-new feature: j2s/img/JSmol_spinner.gif implemented as default for 
Info._appletLoadingImage
+new feature: j2s/img/JSmol_spinner.gif implemented (Angel Herraez)
+ -- as default for Info._appletLoadingImage
+ -- use Info._appletLoadingImage = "none" to disable
 
 new feature: j2s/img/cursor_wait.gif animation implemented
 
+bug fix: EBI assembly CIF files that are multi-model files will be by chain, 
not by model.
+  -- result was that each chain became a new model
+  -- for example: see 
http://www.ebi.ac.uk/pdbe/static/entry/download/2lev-assembly-1.cif.gz
+
 bug fix: XmlMolProReader does not recognize FILTER "NOMO"
 bug fix: JSmol has never shown cursors
 

This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.


------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140
_______________________________________________
Jmol-commits mailing list
Jmol-commits@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jmol-commits

Reply via email to