Diff for /loncom/html/adm/jmol/Jmol.js between versions 1.2 and 1.4

version 1.2, 2005/07/05 14:11:47 version 1.4, 2014/08/22 17:57:54
Line 1 Line 1
 /* $RCSfile$  /* Jmol 12.0 script library Jmol.js 5/20/2013 7:34:08 AM Bob Hanson
  * $Author$  
  * $Date$  
  * $Revision$  NOTE: THIS LIBRARY IS DEPRECATED STARTING WITH Jmol 13.0.
  *        IT STILL WORKS (AND ALWAYS WILL, PROBABLY).
  * Copyright (C) 2004  The Jmol Development Team        PLEASE USE the set JmolCore.js/JmolApplet.js/JmolControls.js/JmolApi.js
  *        WITH OPTIONAL JmolCD.js (ChemDoodle Canvas and Canvas2D options) and JmolJSV.js (JSpecView)
  * Contact: jmol-developers@lists.sf.net  
  *        SEE http://chemapps.stolaf.edu/jmol/files/JmolCore.js for details
  *  This library is free software; you can redistribute it and/or        SEE http://chemapps.stolaf.edu/jmol/examples-12/simple2.htm for an example
  *  modify it under the terms of the GNU Lesser General Public  
  *  License as published by the Free Software Foundation; either   checkbox heirarchy -- see http://chemapps.stolaf.edu/jmol/docs/examples-11/check.htm
  *  version 2.1 of the License, or (at your option) any later version.  
  *      based on:
  *  This library is distributed in the hope that it will be useful,   *
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of   * Copyright (C) 2004-2005  Miguel, Jmol Development, www.jmol.org
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU   *
  *  Lesser General Public License for more details.   * Contact: hansonr@stolaf.edu
  *   *
  *  You should have received a copy of the GNU Lesser General Public   *  This library is free software; you can redistribute it and/or
  *  License along with this library; if not, write to the Free Software   *  modify it under the terms of the GNU Lesser General Public
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA   *  License as published by the Free Software Foundation; either
  *  02111-1307  USA.   *  version 2.1 of the License, or (at your option) any later version.
  */   *
    *  This library is distributed in the hope that it will be useful,
 // for documentation see www.jmol.org/jslibrary   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
    *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 var undefined; // for IE 5 ... wherein undefined is undefined   *  Lesser General Public License for more details.
    *
 ////////////////////////////////////////////////////////////////   *  You should have received a copy of the GNU Lesser General Public
 // Basic Scripting infrastruture   *  License along with this library; if not, write to the Free Software
 ////////////////////////////////////////////////////////////////   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    *  02111-1307  USA.
 function jmolInitialize(codebaseDirectory) {   */
   if (_jmol.initialized) {  
     alert("jmolInitialize() should only be called *ONCE* within a page");  // for documentation see www.jmol.org/jslibrary
     return;  
   }  try{if(typeof(_jmol)!="undefined")exit()
   if (! codebaseDirectory) {  
     alert("codebaseDirectory is a required parameter to jmolInitialize");  // place "?NOAPPLET" on your command line to check applet control action with a textarea
     codebaseDirectory = ".";  // place "?JMOLJAR=xxxxx" to use a specific jar file
   }  
   if (codebaseDirectory.indexOf("http://") == 0 ||  // bob hanson -- jmolResize(w,h) -- resizes absolutely or by percent (w or h 0.5 means 50%)
       codebaseDirectory.indexOf("https://") == 0)  //    angel herraez -- update of jmolResize(w,h,targetSuffix) so it is not tied to first applet
     alert("codebaseDirectory should be directory relative,\n" +  // bob hanson -- jmolEvaluate -- evaluates molecular math 8:37 AM 2/23/2007
   "not be an absolute URL : " + codebaseDirectory);  // bob hanson -- jmolScriptMessage -- returns all "scriptStatus" messages 8:37 AM 2/23/2007
 //  else if (codebaseDirectory.charAt(0) == '/')  // bob hanson -- jmolScriptEcho -- returns all "scriptEcho" messages 8:37 AM 2/23/2007
 //    alert("codebaseDirectory should be directory relative,\n" +  // bob hanson -- jmolScriptWait -- 11:31 AM 5/2/2006
 //  "not relative to the root of the web server : " + codebaseDirectory);  // bob hanson -- remove trailing separatorHTML in radio groups -- 12:18 PM 5/6/2006
   _jmolSetCodebase(codebaseDirectory);  // bob hanson -- adds support for dynamic DOM script nodes 7:04 AM 5/19/2006
   _jmolOnloadResetForms();  // bob hanson -- adds try/catch for wiki - multiple code passes 7:05 AM 5/19/2006
   _jmol.initialized = true;  // bob hanson -- auto-initiates to defaultdir/defaultjar -- change as desired.
 }  // bob hanson -- adding save/restore orientation w/ and w/o delay 11:49 AM 5/25/2006
   // bob hanson -- adding AjaxJS service 11:16 AM 6/3/2006
 function jmolSetAppletColor(boxbgcolor, boxfgcolor, progresscolor) {  // bob hanson -- fix for iframes not available for finding applet
   _jmolInitCheck();  // bob hanson -- added applet fake ?NOAPPLET URL flag
   _jmol.boxbgcolor = boxbgcolor;  // bob hanson -- added jmolSetCallback(calbackName, funcName) 3:32 PM 6/13/2006
   if (boxfgcolor)  //      used PRIOR to jmolApplet() or jmolAppletInline()
     _jmol.boxfgcolor = boxfgcolor  //               added 4th array element in jmolRadioGroup -- title
   else if (boxbgcolor == "white" || boxbgcolor == "#FFFFFF")  //               added <span> and id around link, checkbox, radio, menu
     _jmol.boxfgcolor = "black";  //               fixing AJAX loads for MSIE/Opera-Mozilla incompatibility
   else  //            -- renamed Jmol-11.js from Jmol-new.js; JmolApplet.jar from JmolAppletProto.jar
     _jmol.boxfgcolor = "white";  //      renamed Jmol.js for Jmol 11 distribution
   if (progresscolor)  //            -- modified jmolRestoreOrientation() to be immediate, no 1-second delay
     _jmol.progresscolor = progresscolor;  // bob hanson -- jmolScriptWait always returns a string -- 11:23 AM 9/16/2006
   if (_jmol.debugAlert)  // bh         -- jmolCommandInput()
     alert(" boxbgcolor=" + _jmol.boxbgcolor +  // bh         -- jmolSetTranslation(TF) -- forces translation even if there might be message callback issues
           " boxfgcolor=" + _jmol.boxfgcolor +  // bh         -- minor fixes suggested by Angel
           " progresscolor=" + _jmol.progresscolor);  // bh         -- adds jmolSetSyncId() and jmolGetSyncId()
 }  // bh 3/2008  -- adds jmolAppendInlineScript() and jmolAppendInlineArray()
   // bh 3/2008  -- fixes IE7 bug in relation to jmolLoadInlineArray()
 function jmolApplet(size, script, nameSuffix) {  // bh 6/2008  -- adds jmolSetAppletWindow()
   _jmolInitCheck();  // Angel H. 6/2008  -- added html <label> tags to checkboxes and radio buttons [in jmolCheckbox() and _jmolRadio() functions]
   _jmolApplet(size, null, script, nameSuffix);  // bh 7/2008  -- code fix "for(i..." not "for(var i..."
 }  // bh 12/2008 -- jmolLoadInline, jmolLoadInlineArray, jmolLoadInlineScript, jmolAppendInlineScript, jmolAppendInlineArray all return error message or null (Jmol 11.7.16)
   // bh 12/2008 -- jmolScriptWaitOutput() -- waits for script to complete and delivers output normally sent to console
 ////////////////////////////////////////////////////////////////  
 // Basic controls  // bh 5/2009  -- Support for XHTML using jmolSetXHTML(id)
 ////////////////////////////////////////////////////////////////  // ah & bh 6/2009 -- New jmolResizeApplet() more flexible, similar to jmolApplet() size syntax
   // bh 11/2009 -- care in accessing top.document
 function jmolButton(script, label, id) {  // bh 12/2009 -- added jmolSetParameter(name, value)
   _jmolInitCheck();  // bh 12/2009 -- added PARAMS=name:value;name:value;name:value... for command line
   var scriptIndex = _jmolAddScript(script);  // bh 12/2009 -- overhaul of target checking
   if (label == undefined || label == null)  // bh 1/2010  -- all _xxxx() methods ALWAYS have complete argument list
     label = script.substring(0, 32);  // bh 1/2010  -- adds option to run a JavaScript function from any Jmol control.
   if (id == undefined || id == null)  //               This is accomplished by passing an array rather than a script:
     id = "jmolButton" + _jmol.buttonCount;  //               jmolHref([myfunc,"my param 1", "my param 2"], "testing")
   ++_jmol.buttonCount;  //               function myfunc(jmolControlObject, [myfunc,"my param 1", "my param 2"], target){...}
   var t = "<input type='button' name='" + id + "' id='" + id +  //               and allows much more flexibility with responding to controls
           "' value='" + label +  // bh 4/2010  -- added jmolSetMemoryMb(nMb)
           "' onClick='_jmolClick(" + scriptIndex + _jmol.targetText +  // ah 1/2011  -- wider detection of browsers; more browsers now use the object tag instead of the applet tag;
           ")' onMouseover='_jmolMouseOver(" + scriptIndex +  //               fix of object tag (removed classid) accounts for change of behavior in Chrome
           ");return true' onMouseout='_jmolMouseOut()' " +  // bh 5/2013  -- fix for master checkbox click not actuating checkboxes
           _jmol.buttonCssText + "/>";  
   if (_jmol.debugAlert)  var defaultdir = "."
     alert(t);  var defaultjar = "JmolApplet.jar"
   document.write(t);  
 }  
   // Note added 12:41 PM 9/21/2008 by Bob Hanson, hansonr@stolaf.edu:
 function jmolCheckbox(scriptWhenChecked, scriptWhenUnchecked,  
                       labelHtml, isChecked, id) {  // JMOLJAR=xxxxx.jar on the URL for this page will override
   _jmolInitCheck();  // the JAR file specified in the jmolInitialize() call.
   if (id == undefined || id == null)  
     id = "jmolCheckbox" + _jmol.checkboxCount;  // The idea is that it can be very useful to test a web page with different JAR files
   ++_jmol.checkboxCount;  // Or for an expert user to substitute a signed applet for an unsigned one
   if (scriptWhenChecked == undefined || scriptWhenChecked == null ||  // so as to use a broader range of models or to create JPEG files, for example.
       scriptWhenUnchecked == undefined || scriptWhenUnchecked == null) {  
     alert("jmolCheckbox requires two scripts");  // If the JAR file is not in the current directory (has any sort of "/" in its name)
     return;  // then the user is presented with a warning and asked whether it is OK to change Jar files.
   }  // The default action, if the user just presses "OK" is to NOT allow the change.
   if (labelHtml == undefined || labelHtml == null) {  // The user must type the word "yes" in the prompt box for the change to be approved.
     alert("jmolCheckbox requires a label");  
     return;  // If you don't want people to be able to switch in their own JAR file on your page,
   }  // simply set this next line to read "var allowJMOLJAR = false".
   var indexChecked = _jmolAddScript(scriptWhenChecked);  
   var indexUnchecked = _jmolAddScript(scriptWhenUnchecked);  
   var t = "<input type='checkbox' name='" + id + "' id='" + id +  var undefined; // for IE 5 ... wherein undefined is undefined
           "' onClick='_jmolCbClick(this," +  
           indexChecked + "," + indexUnchecked + _jmol.targetText +  ////////////////////////////////////////////////////////////////
           ")' onMouseover='_jmolCbOver(this," + indexChecked + "," +  // Basic Scripting infrastruture
           indexUnchecked +  ////////////////////////////////////////////////////////////////
           ");return true' onMouseout='_jmolMouseOut()' " +  
   (isChecked ? "checked " : "") + _jmol.checkboxCssText + "/>" +  function jmolInitialize(codebaseDirectory, fileNameOrUseSignedApplet) {
           labelHtml;    if (_jmol.initialized)
   if (_jmol.debugAlert)      return;
     alert(t);    _jmol.initialized = true;
   document.write(t);    if(_jmol.jmoljar) {
 }      var f = _jmol.jmoljar;
       if (f.indexOf("/") >= 0) {
 function jmolRadioGroup(arrayOfRadioButtons, separatorHtml, groupName) {        alert ("This web page URL is requesting that the applet used be " + f + ". This is a possible security risk, particularly if the applet is signed, because signed applets can read and write files on your local machine or network.")
   _jmolInitCheck();        var ok = prompt("Do you want to use applet " + f + "? ","yes or no")
   var type = typeof arrayOfRadioButtons;        if (ok == "yes") {
   if (type != "object" || type == null || ! arrayOfRadioButtons.length) {          codebaseDirectory = f.substring(0, f.lastIndexOf("/"));
     alert("invalid arrayOfRadioButtons");          fileNameOrUseSignedApplet = f.substring(f.lastIndexOf("/") + 1);
     return;        } else {
   }    _jmolGetJarFilename(fileNameOrUseSignedApplet);
   if (separatorHtml == undefined || separatorHtml == null)          alert("The web page URL was ignored. Continuing using " + _jmol.archivePath + ' in directory "' + codebaseDirectory + '"');
     separatorHtml = "&nbsp; ";        }
   var length = arrayOfRadioButtons.length;      } else {
   var t = "";        fileNameOrUseSignedApplet = f;
   jmolStartNewRadioGroup();      }
   for (var i = 0; i < length; ++i) {    }
     var radio = arrayOfRadioButtons[i];    _jmolSetCodebase(codebaseDirectory);
     type = typeof radio;    _jmolGetJarFilename(fileNameOrUseSignedApplet);
     if (type == "object") {    _jmolOnloadResetForms();
       t += _jmolRadio(radio[0], radio[1], radio[2], separatorHtml, groupName);  }
     } else {  
       t += _jmolRadio(radio, null, null, separatorHtml, groupName);  function jmolSetTranslation(TF) {
     }    _jmol.params.doTranslate = ''+TF;
   }  }
   if (_jmol.debugAlert)  
     alert(t);  function _jmolGetJarFilename(fileNameOrFlag) {
   document.write(t);    _jmol.archivePath =
 }      (typeof(fileNameOrFlag) == "string"  ? fileNameOrFlag : (fileNameOrFlag ?  "JmolAppletSigned" : "JmolApplet") + "0.jar");
   }
 function jmolLink(script, text, id) {  
   _jmolInitCheck();  function jmolSetDocument(doc) {
   if (id == undefined || id == null)    _jmol.currentDocument = doc;
     id = "jmolLink" + _jmol.linkCount;  }
   ++_jmol.linkCount;  
   var scriptIndex = _jmolAddScript(script);  function jmolSetAppletColor(boxbgcolor, boxfgcolor, progresscolor) {
   var t = "<a name='" + id + "' id='" + id +     _jmolInitCheck();
           "' href='javascript:_jmolClick(" + scriptIndex +    _jmol.params.boxbgcolor = boxbgcolor;
           _jmol.targetText +    if (boxfgcolor)
           ");' onMouseover='_jmolMouseOver(" + scriptIndex +      _jmol.params.boxfgcolor = boxfgcolor
           ");return true;' onMouseout='_jmolMouseOut()' " +    else if (boxbgcolor == "white" || boxbgcolor == "#FFFFFF")
           _jmol.linkCssText + ">" + text + "</a>";      _jmol.params.boxfgcolor = "black";
   if (_jmol.debugAlert)    else
     alert(t);      _jmol.params.boxfgcolor = "white";
   document.write(t);    if (progresscolor)
 }      _jmol.params.progresscolor = progresscolor;
     if (_jmol.debugAlert)
 function jmolMenu(arrayOfMenuItems, size, id) {      alert(" boxbgcolor=" + _jmol.params.boxbgcolor +
   _jmolInitCheck();            " boxfgcolor=" + _jmol.params.boxfgcolor +
   if (id == undefined || id == null)            " progresscolor=" + _jmol.params.progresscolor);
     id = "jmolMenu" + _jmol.menuCount;  }
   ++_jmol.menuCount;  
   var type = typeof arrayOfMenuItems;  function jmolSetAppletWindow(w) {
   if (type != null && type == "object" && arrayOfMenuItems.length) {    _jmol.appletWindow = w;
     var length = arrayOfMenuItems.length;  }
     if (typeof size != "number" || size == 1)  
       size = null;  function jmolApplet(size, script, nameSuffix) {
     else if (size < 0)    _jmolInitCheck();
       size = length;    return _jmolApplet(size, null, script, nameSuffix);
     var sizeText = size ? " size='" + size + "' " : "";  }
     var t = "<select name='" + id + "' id='" + id +  
             "' onChange='_jmolMenuSelected(this" +  ////////////////////////////////////////////////////////////////
             _jmol.targetText + ")'" +  // Basic controls
             sizeText + _jmol.menuCssText + ">";  ////////////////////////////////////////////////////////////////
     for (var i = 0; i < length; ++i) {  
       var menuItem = arrayOfMenuItems[i];  // undefined means it wasn't there; null means it was explicitly listed as null (so as to skip it)
       type = typeof menuItem;  
       var script, text;  function jmolButton(script, label, id, title) {
       var isSelected = undefined;    _jmolInitCheck();
       if (type == "object" && menuItem != null) {    id != undefined && id != null || (id = "jmolButton" + _jmol.buttonCount);
         script = menuItem[0];    label != undefined && label != null || (label = script.substring(0, 32));
         text = menuItem[1];    ++_jmol.buttonCount;
         isSelected = menuItem[2];    var scriptIndex = _jmolAddScript(script);
       } else {    var t = "<span id=\"span_"+id+"\""+(title ? " title=\"" + title + "\"":"")+"><input type='button' name='" + id + "' id='" + id +
         script = text = menuItem;            "' value='" + label +
       }            "' onclick='_jmolClick(this," + scriptIndex + _jmol.targetText +
       if (text == undefined || text == null)            ")' onmouseover='_jmolMouseOver(" + scriptIndex +
         text = script;            ");return true' onmouseout='_jmolMouseOut()' " +
       var scriptIndex = _jmolAddScript(script);            _jmol.buttonCssText + " /></span>";
       var selectedText = isSelected ? "' selected>" : "'>";    if (_jmol.debugAlert)
       t += "<option value='" + scriptIndex + selectedText + text + "</option>";      alert(t);
     }    return _jmolDocumentWrite(t);
     t += "</select>";  }
     if (_jmol.debugAlert)  
       alert(t);  function jmolCheckbox(scriptWhenChecked, scriptWhenUnchecked,
     document.write(t);                        labelHtml, isChecked, id, title) {
   }    _jmolInitCheck();
 }    id != undefined && id != null || (id = "jmolCheckbox" + _jmol.checkboxCount);
     ++_jmol.checkboxCount;
 function jmolHtml(html) {    if (scriptWhenChecked == undefined || scriptWhenChecked == null ||
   document.write(html);        scriptWhenUnchecked == undefined || scriptWhenUnchecked == null) {
 }      alert("jmolCheckbox requires two scripts");
       return;
 function jmolBr() {    }
   document.write("<br />");    if (labelHtml == undefined || labelHtml == null) {
 }      alert("jmolCheckbox requires a label");
       return;
 ////////////////////////////////////////////////////////////////    }
 // advanced scripting functions    var indexChecked = _jmolAddScript(scriptWhenChecked);
 ////////////////////////////////////////////////////////////////    var indexUnchecked = _jmolAddScript(scriptWhenUnchecked);
     var eospan = "</span>"
 function jmolDebugAlert(enableAlerts) {    var t = "<span id=\"span_"+id+"\""+(title ? " title=\"" + title + "\"":"")+"><input type='checkbox' name='" + id + "' id='" + id +
   _jmol.debugAlert = (enableAlerts == undefined || enableAlerts)            "' onclick='_jmolCbClick(this," +
 }            indexChecked + "," + indexUnchecked + _jmol.targetText +
             ")' onmouseover='_jmolCbOver(this," + indexChecked + "," +
 function jmolAppletInline(size, inlineModel, script, nameSuffix) {            indexUnchecked +
   _jmolApplet(size, _jmolConvertInline(inlineModel), script, nameSuffix);            ");return true' onmouseout='_jmolMouseOut()' " +
 }      (isChecked ? "checked='true' " : "")+ _jmol.checkboxCssText + " />"
     if (labelHtml.toLowerCase().indexOf("<td>")>=0) {
 function jmolSetTarget(targetSuffix) {    t += eospan
   _jmol.targetSuffix = targetSuffix;    eospan = "";
   _jmol.targetText = targetSuffix ? ",\"" + targetSuffix + "\"" : "";    }
 }    t += "<label for=\"" + id + "\">" + labelHtml + "</label>" +eospan;
     if (_jmol.debugAlert)
 function jmolScript(script, targetSuffix) {      alert(t);
   if (script) {    return _jmolDocumentWrite(t);
     _jmolCheckBrowser();  }
     var target = "jmolApplet" + (targetSuffix ? targetSuffix : "0");  
     var applet = _jmolFindApplet(target);  function jmolStartNewRadioGroup() {
     if (applet)    ++_jmol.radioGroupCount;
       return applet.script(script);  }
     else  
       alert("could not find applet " + target);  function jmolRadioGroup(arrayOfRadioButtons, separatorHtml, groupName, id, title) {
   }    /*
 }  
       array: [radio1,radio2,radio3...]
 function jmolLoadInline(model, targetSuffix) {      where radioN = ["script","label",isSelected,"id","title"]
   if (model) {  
     var target = "jmolApplet" + (targetSuffix ? targetSuffix : "0");    */
 //    while (! _jmol.ready[target])  
 //      alert("The Jmol applet " + target + " is not loaded yet");    _jmolInitCheck();
 //    if (! _jmol.ready[target])    var type = typeof arrayOfRadioButtons;
 //      alert("The Jmol applet " + target + " is not loaded yet");    if (type != "object" || type == null || ! arrayOfRadioButtons.length) {
 //    if (document.applets[target] && ! document.applets[target].isActive())      alert("invalid arrayOfRadioButtons");
 //       alert("The Jmol applet " + target + " is not yet active");      return;
 //    else {    }
       var applet = _jmolFindApplet(target);    separatorHtml != undefined && separatorHtml != null || (separatorHtml = "&nbsp; ");
       if (applet)    var len = arrayOfRadioButtons.length;
         return applet.loadInline(model);    jmolStartNewRadioGroup();
       else    groupName || (groupName = "jmolRadioGroup" + (_jmol.radioGroupCount - 1));
         alert("could not find applet " + target);    var t = "<span id='"+(id ? id : groupName)+"'>";
 //    }    for (var i = 0; i < len; ++i) {
   }      if (i == len - 1)
 }        separatorHtml = "";
       var radio = arrayOfRadioButtons[i];
 function jmolStartNewRadioGroup() {      type = typeof radio;
   ++_jmol.radioGroupCount;      if (type == "object") {
 }        t += _jmolRadio(radio[0], radio[1], radio[2], separatorHtml, groupName, (radio.length > 3 ? radio[3]: (id ? id : groupName)+"_"+i), (radio.length > 4 ? radio[4] : 0), title);
       } else {
 function jmolRadio(script, labelHtml, isChecked, separatorHtml, groupName) {        t += _jmolRadio(radio, null, null, separatorHtml, groupName, (id ? id : groupName)+"_"+i, title);
   _jmolInitCheck();      }
   if (_jmol.radioGroupCount == 0)    }
     ++_jmol.radioGroupCount;    t+="</span>"
   var t = _jmolRadio(script, labelHtml, isChecked, separatorHtml, groupName);    if (_jmol.debugAlert)
   if (_jmol.debugAlert)      alert(t);
     alert(t);    return _jmolDocumentWrite(t);
   document.write(t);  }
 }  
   
 function jmolCheckBrowser(action, urlOrMessage, nowOrLater) {  function jmolRadio(script, labelHtml, isChecked, separatorHtml, groupName, id, title) {
   if (typeof action == "string") {    _jmolInitCheck();
     action = action.toLowerCase();    if (_jmol.radioGroupCount == 0)
     if (action != "alert" && action != "redirect" && action != "popup")      ++_jmol.radioGroupCount;
       action = null;    var t = _jmolRadio(script, labelHtml, isChecked, separatorHtml, groupName, (id ? id : groupName + "_" + _jmol.radioCount), title ? title : 0);
   }    if (_jmol.debugAlert)
   if (typeof action != "string")      alert(t);
     alert("jmolCheckBrowser(action, urlOrMessage, nowOrLater)\n\n" +    return _jmolDocumentWrite(t);
           "action must be 'alert', 'redirect', or 'popup'");  }
   else {  
     if (typeof urlOrMessage != "string")  function jmolLink(script, label, id, title) {
       alert("jmolCheckBrowser(action, urlOrMessage, nowOrLater)\n\n" +    _jmolInitCheck();
             "urlOrMessage must be a string");    id != undefined && id != null || (id = "jmolLink" + _jmol.linkCount);
     else {    label != undefined && label != null || (label = script.substring(0, 32));
       _jmol.checkBrowserAction = action;    ++_jmol.linkCount;
       _jmol.checkBrowserUrlOrMessage = urlOrMessage;    var scriptIndex = _jmolAddScript(script);
     }    var t = "<span id=\"span_"+id+"\""+(title ? " title=\"" + title + "\"":"")+"><a name='" + id + "' id='" + id +
   }            "' href='javascript:_jmolClick(this," + scriptIndex + _jmol.targetText + ");' onmouseover='_jmolMouseOver(" + scriptIndex +
   if (typeof nowOrLater == "string" && nowOrLater.toLowerCase() == "now")            ");return true;' onmouseout='_jmolMouseOut()' " +
     _jmolCheckBrowser();            _jmol.linkCssText + ">" + label + "</a></span>";
 }    if (_jmol.debugAlert)
       alert(t);
 ////////////////////////////////////////////////////////////////    return _jmolDocumentWrite(t);
 // Cascading Style Sheet Class support  }
 ////////////////////////////////////////////////////////////////  
   function jmolCommandInput(label, size, id, title) {
 function jmolSetAppletCssClass(appletCssClass) {    _jmolInitCheck();
   if (_jmol.hasGetElementById) {    id != undefined && id != null || (id = "jmolCmd" + _jmol.cmdCount);
     _jmol.appletCssClass = appletCssClass;    label != undefined && label != null || (label = "Execute");
     _jmol.appletCssText = appletCssClass ? "class='" + appletCssClass + "' " : "";    size != undefined && !isNaN(size) || (size = 60);
   }    ++_jmol.cmdCount;
 }    var t = "<span id=\"span_"+id+"\""+(title ? " title=\"" + title + "\"":"")+"><input name='" + id + "' id='" + id +
             "' size='"+size+"' onkeypress='_jmolCommandKeyPress(event,\""+id+"\"" + _jmol.targetText + ")'><input type=button value = '"+label+"' onclick='jmolScript(document.getElementById(\""+id+"\").value" + _jmol.targetText + ")' /></span>";
 function jmolSetButtonCssClass(buttonCssClass) {    if (_jmol.debugAlert)
   if (_jmol.hasGetElementById) {      alert(t);
     _jmol.buttonCssClass = buttonCssClass;    return _jmolDocumentWrite(t);
     _jmol.buttonCssText = buttonCssClass ? "class='" + buttonCssClass + "' " : "";  }
   }  
 }  function _jmolCommandKeyPress(e, id, target) {
     var keycode = (window.event ? window.event.keyCode : e ? e.which : 0);
 function jmolSetCheckboxCssClass(checkboxCssClass) {    if (keycode == 13) {
   if (_jmol.hasGetElementById) {      var inputBox = document.getElementById(id)
     _jmol.checkboxCssClass = checkboxCssClass;      _jmolScriptExecute(inputBox, inputBox.value, target)
     _jmol.checkboxCssText = checkboxCssClass ? "class='" + checkboxCssClass + "' " : "";    }
   }  }
 }  
   function _jmolScriptExecute(element,script,target) {
 function jmolSetRadioCssClass(radioCssClass) {    if (typeof(script) == "object")
   if (_jmol.hasGetElementById) {      script[0](element, script, target)
     _jmol.radioCssClass = radioCssClass;   else if (typeof(script) == "function")
     _jmol.radioCssText = radioCssClass ? "class='" + radioCssClass + "' " : "";    script(target);
   }    else
 }      jmolScript(script, target)
   }
 function jmolSetLinkCssClass(linkCssClass) {  
   if (_jmol.hasGetElementById) {  function jmolMenu(arrayOfMenuItems, size, id, title) {
     _jmol.linkCssClass = linkCssClass;    _jmolInitCheck();
     _jmol.linkCssText = linkCssClass ? "class='" + linkCssClass + "' " : "";    id != undefined && id != null || (id = "jmolMenu" + _jmol.menuCount);
   }    ++_jmol.menuCount;
 }    var type = typeof arrayOfMenuItems;
     if (type != null && type == "object" && arrayOfMenuItems.length) {
 function jmolSetMenuCssClass(menuCssClass) {      var len = arrayOfMenuItems.length;
   if (_jmol.hasGetElementById) {      if (typeof size != "number" || size == 1)
     _jmol.menuCssClass = menuCssClass;        size = null;
     _jmol.menuCssText = menuCssClass ? "class='" + menuCssClass + "' " : "";      else if (size < 0)
   }        size = len;
 }      var sizeText = size ? " size='" + size + "' " : "";
       var t = "<span id=\"span_"+id+"\""+(title ? " title=\"" + title + "\"":"")+"><select name='" + id + "' id='" + id +
 ////////////////////////////////////////////////////////////////              "' onChange='_jmolMenuSelected(this" + _jmol.targetText + ")'" +
 // functions for INTERNAL USE ONLY which are subject to change              sizeText + _jmol.menuCssText + ">";
 // use at your own risk ... you have been WARNED!      for (var i = 0; i < len; ++i) {
 ////////////////////////////////////////////////////////////////        var menuItem = arrayOfMenuItems[i];
         type = typeof menuItem;
 var _jmol = {        var script, text;
         var isSelected = undefined;
 debugAlert: false,        if (type == "object" && menuItem != null) {
 bgcolor: "black",          script = menuItem[0];
 progresscolor: "blue",          text = menuItem[1];
 boxbgcolor: "black",          isSelected = menuItem[2];
 boxfgcolor: "white",        } else {
 boxmessage: "Downloading JmolApplet ...",          script = text = menuItem;
         }
 codebase: ".",        text != undefined && text != null || (text = script);
 modelbase: ".",        if (script=="#optgroup") {
           t += "<optgroup label='" + text + "'>";
 appletCount: 0,      } else if (script=="#optgroupEnd") {
           t += "</optgroup>";
 buttonCount: 0,      } else {
 checkboxCount: 0,          var scriptIndex = _jmolAddScript(script);
 linkCount: 0,          var selectedText = isSelected ? "' selected='true'>" : "'>";
 menuCount: 0,          t += "<option value='" + scriptIndex + selectedText + text + "</option>";
 radioCount: 0,        }
 radioGroupCount: 0,      }
       t += "</select></span>";
 appletCssClass: null,      if (_jmol.debugAlert)
 appletCssText: "",        alert(t);
 buttonCssClass: null,      return _jmolDocumentWrite(t);
 buttonCssText: "",    }
 checkboxCssClass: null,  }
 checkboxCssText: "",  
 radioCssClass: null,  function jmolHtml(html) {
 radioCssText: "",    return _jmolDocumentWrite(html);
 linkCssClass: null,  }
 linkCssText: "",  
 menuCssClass: null,  function jmolBr() {
 menuCssText: "",    return _jmolDocumentWrite("<br />");
   }
 targetSuffix: 0,  
 targetText: "",  ////////////////////////////////////////////////////////////////
 scripts: [""],  // advanced scripting functions
   ////////////////////////////////////////////////////////////////
 ua: navigator.userAgent.toLowerCase(),  
 uaVersion: parseFloat(navigator.appVersion),  function jmolDebugAlert(enableAlerts) {
     _jmol.debugAlert = (enableAlerts == undefined || enableAlerts)
 os: "unknown",  }
 browser: "unknown",  
 browserVersion: 0,  function jmolAppletInline(size, inlineModel, script, nameSuffix) {
 hasGetElementById: !!document.getElementById,    _jmolInitCheck();
 isJavaEnabled: navigator.javaEnabled(),    return _jmolApplet(size, _jmolSterilizeInline(inlineModel),
 isNetscape47Win: false,                       script, nameSuffix);
   }
 isBrowserCompliant: false,  
 isJavaCompliant: false,  function jmolSetTarget(targetSuffix) {
 isFullyCompliant: false,    _jmol.targetSuffix = targetSuffix;
     _jmol.targetText = targetSuffix ? ",\"" + targetSuffix + "\"" : ",0";
 initialized: false,  }
 initChecked: false,  
   function jmolScript(script, targetSuffix) {
 browserChecked: false,    if (script) {
 checkBrowserAction: "alert",      _jmolCheckBrowser();
 checkBrowserUrlOrMessage: null,      if (targetSuffix == "all") {
         with (_jmol) {
 previousOnloadHandler: null,    for (var i = 0; i < appletSuffixes.length; ++i) {
 ready: {}      var applet = _jmolGetApplet(appletSuffixes[i]);
 }            if (applet) applet.script(script);
           }
 with (_jmol) {        }
   function _jmolTestUA(candidate) {      } else {
     var ua = _jmol.ua;        var applet=_jmolGetApplet(targetSuffix);
     var index = ua.indexOf(candidate);        if (applet) applet.script(script);
     if (index < 0)      }
       return false;    }
     _jmol.browser = candidate;  }
     _jmol.browserVersion = parseFloat(ua.substring(index + candidate.length+1));  
     return true;  function jmolLoadInline(model, targetSuffix) {
   }    if (!model)return "ERROR: NO MODEL"
       var applet=_jmolGetApplet(targetSuffix);
   function _jmolTestOS(candidate) {    if (!applet)return "ERROR: NO APPLET"
     if (_jmol.ua.indexOf(candidate) < 0)    if (typeof(model) == "string")
       return false;      return applet.loadInlineString(model, "", false);
     _jmol.os = candidate;    else
     return true;      return applet.loadInlineArray(model, "", false);
   }  }
     
   _jmolTestUA("konqueror") ||  
   _jmolTestUA("safari") ||  function jmolLoadInlineScript(model, script, targetSuffix) {
   _jmolTestUA("omniweb") ||    if (!model)return "ERROR: NO MODEL"
   _jmolTestUA("opera") ||    var applet=_jmolGetApplet(targetSuffix);
   _jmolTestUA("webtv") ||    if (!applet)return "ERROR: NO APPLET"
   _jmolTestUA("icab") ||    return applet.loadInlineString(model, script, false);
   _jmolTestUA("msie") ||  }
   (_jmol.ua.indexOf("compatible") < 0 && _jmolTestUA("mozilla"));  
     
   _jmolTestOS("linux") ||  function jmolLoadInlineArray(ModelArray, script, targetSuffix) {
   _jmolTestOS("unix") ||    if (!model)return "ERROR: NO MODEL"
   _jmolTestOS("mac") ||    script || (script="")
   _jmolTestOS("win");    var applet=_jmolGetApplet(targetSuffix);
     if (!applet)return "ERROR: NO APPLET"
   isNetscape47Win = (os == "win" && browser == "mozilla" &&    try {
                      browserVersion >= 4.78 && browserVersion <= 4.8);      return applet.loadInlineArray(ModelArray, script, false);
     } catch (err) {
   if (os == "win") {      //IE 7 bug
     isBrowserCompliant = hasGetElementById || isNetscape47Win;      return applet.loadInlineString(ModelArray.join("\n"), script, false);
   } else if (os == "mac") { // mac is the problem child :-(    }
     if (browser == "mozilla" && browserVersion >= 5) {  }
       // miguel 2004 11 17  
       // checking the plugins array does not work because  function jmolAppendInlineArray(ModelArray, script, targetSuffix) {
       // Netscape 7.2 OS X still has Java 1.3.1 listed even though    if (!model)return "ERROR: NO MODEL"
       // javaplugin.sf.net is installed to upgrade to 1.4.2    script || (script="")
       eval("try {var v = java.lang.System.getProperty('java.version');" +    var applet=_jmolGetApplet(targetSuffix);
            " _jmol.isBrowserCompliant = v >= '1.4.2';" +    if (!applet)return "ERROR: NO APPLET"
            " } catch (e) { }");    try {
     } else if (browser == "opera" && browserVersion <= 7.54) {      return applet.loadInlineArray(ModelArray, script, true);
       isBrowserCompliant = false;    } catch (err) {
     } else {      //IE 7 bug
       isBrowserCompliant = hasGetElementById &&      return applet.loadInlineString(ModelArray.join("\n"), script, true);
         !((browser == "msie") ||    }
           (browser == "safari" && browserVersion < 125.1));  }
     }  
   } else if (os == "linux" || os == "unix") {  function jmolAppendInlineScript(model, script, targetSuffix) {
     if (browser == "konqueror" && browserVersion <= 3.3)    if (!model)return "ERROR: NO MODEL"
       isBrowserCompliant = false;    var applet=_jmolGetApplet(targetSuffix);
     else    if (!applet)return "ERROR: NO APPLET"
       isBrowserCompliant = hasGetElementById;    return applet.loadInlineString(model, script, true);
   } else { // other OS  }
     isBrowserCompliant = hasGetElementById;  
   }  function jmolCheckBrowser(action, urlOrMessage, nowOrLater) {
     if (typeof action == "string") {
   // possibly more checks in the future for this      action = action.toLowerCase();
   isJavaCompliant = isJavaEnabled;      action == "alert" || action == "redirect" || action == "popup" || (action = null);
     }
   isFullyCompliant = isBrowserCompliant && isJavaCompliant;    if (typeof action != "string")
 }      alert("jmolCheckBrowser(action, urlOrMessage, nowOrLater)\n\n" +
             "action must be 'alert', 'redirect', or 'popup'");
 function _jmolApplet(size, inlineModel, script, nameSuffix) {    else {
   with (_jmol) {      if (typeof urlOrMessage != "string")
     if (! nameSuffix)        alert("jmolCheckBrowser(action, urlOrMessage, nowOrLater)\n\n" +
       nameSuffix = appletCount;              "urlOrMessage must be a string");
     ++appletCount;      else {
     if (! script)        _jmol.checkBrowserAction = action;
       script = "select *";        _jmol.checkBrowserUrlOrMessage = urlOrMessage;
     var sz = _jmolGetAppletSize(size);      }
     var t;    }
     t = "<applet name='jmolApplet" + nameSuffix + "' id='jmolApplet" + nameSuffix +    if (typeof nowOrLater == "string" && nowOrLater.toLowerCase() == "now")
         "' " + appletCssText +      _jmolCheckBrowser();
         " code='JmolApplet' archive='JmolApplet.jar'\n" +  }
         " codebase='" + codebase + "'\n" +  
         " width='" + sz[0] + "' height='" + sz[1] +  ////////////////////////////////////////////////////////////////
         "' mayscript='true'>\n" +  // Cascading Style Sheet Class support
         "  <param name='progressbar' value='true' />\n" +  ////////////////////////////////////////////////////////////////
         "  <param name='progresscolor' value='" +  
         progresscolor + "' />\n" +  function jmolSetAppletCssClass(appletCssClass) {
         "  <param name='boxmessage' value='" +    if (_jmol.hasGetElementById) {
         boxmessage + "' />\n" +      _jmol.appletCssClass = appletCssClass;
         "  <param name='boxbgcolor' value='" +      _jmol.appletCssText = appletCssClass ? "class='" + appletCssClass + "' " : "";
         boxbgcolor + "' />\n" +    }
         "  <param name='boxfgcolor' value='" +  }
         boxfgcolor + "' />\n" +  
         "  <param name='ReadyCallback' value='_jmolReadyCallback' />\n";  function jmolSetButtonCssClass(buttonCssClass) {
     if (_jmol.hasGetElementById) {
     if (inlineModel)      _jmol.buttonCssClass = buttonCssClass;
       t += "  <param name='loadInline' value='" + inlineModel + "' />\n";      _jmol.buttonCssText = buttonCssClass ? "class='" + buttonCssClass + "' " : "";
     if (script)    }
       t += "  <param name='script' value='" + script + "' />\n";  }
     t += "</applet>";  
     jmolSetTarget(nameSuffix);  function jmolSetCheckboxCssClass(checkboxCssClass) {
     ready["jmolApplet" + nameSuffix] = false;    if (_jmol.hasGetElementById) {
     if (_jmol.debugAlert)      _jmol.checkboxCssClass = checkboxCssClass;
       alert(t);      _jmol.checkboxCssText = checkboxCssClass ? "class='" + checkboxCssClass + "' " : "";
     document.write(t);    }
   }  }
 }  
   function jmolSetRadioCssClass(radioCssClass) {
 function _jmolInitCheck() {    if (_jmol.hasGetElementById) {
   if (_jmol.initChecked)      _jmol.radioCssClass = radioCssClass;
     return;      _jmol.radioCssText = radioCssClass ? "class='" + radioCssClass + "' " : "";
   _jmol.initChecked = true;    }
   if (_jmol.initialized)  }
     return;  
   alert("jmolInitialize({codebase}, {badBrowseURL}, {badJavaURL})\n" +  function jmolSetLinkCssClass(linkCssClass) {
         "  must be called before any other Jmol.js functions");    if (_jmol.hasGetElementById) {
 }      _jmol.linkCssClass = linkCssClass;
       _jmol.linkCssText = linkCssClass ? "class='" + linkCssClass + "' " : "";
 function _jmolCheckBrowser() {    }
   with (_jmol) {  }
     if (browserChecked)  
       return;  function jmolSetMenuCssClass(menuCssClass) {
     browserChecked = true;    if (_jmol.hasGetElementById) {
         _jmol.menuCssClass = menuCssClass;
     if (isFullyCompliant)      _jmol.menuCssText = menuCssClass ? "class='" + menuCssClass + "' " : "";
       return true;    }
   }
     if (checkBrowserAction == "redirect")  
       location.href = checkBrowserUrlOrMessage;  ////////////////////////////////////////////////////////////////
     else if (checkBrowserAction == "popup")  // functions for INTERNAL USE ONLY which are subject to change
       _jmolPopup(checkBrowserUrlOrMessage);  // use at your own risk ... you have been WARNED!
     else {  ////////////////////////////////////////////////////////////////
       var msg = checkBrowserUrlOrMessage;  var _jmol = {
       if (msg == null)    currentDocument: document,
         msg = "Your web browser is not fully compatible with Jmol\n\n" +  
               "brower: " + browser +    debugAlert: false,
               "   version: " + browserVersion +  
               "   os: " + os +    codebase: "",
               "\n\n" + ua;    modelbase: ".",
       alert(msg);  
     }    appletCount: 0,
   }    appletSuffixes: [],
   return false;    appletWindow: null,
 }    allowedJmolSize: [25, 2048, 300],   // min, max, default (pixels)
       /*  By setting the _jmol.allowedJmolSize[] variable in the webpage
 function _jmolPopup(url) {          before calling jmolApplet(), limits for applet size can be overriden.
   var popup = window.open(url, "JmolPopup",          2048 standard for GeoWall (http://geowall.geo.lsa.umich.edu/home.html)
                           "left=150,top=150,height=400,width=600," +      */
                           "directories=yes,location=yes,menubar=yes," +    buttonCount: 0,
                           "toolbar=yes," +    checkboxCount: 0,
                           "resizable=yes,scrollbars=yes,status=yes");    linkCount: 0,
   if (popup.focus)    cmdCount: 0,
     poup.focus();    menuCount: 0,
 }    radioCount: 0,
     radioGroupCount: 0,
 function _jmolReadyCallback(name) {  
   if (_jmol.debugAlert)    appletCssClass: null,
     alert(name + " is ready");    appletCssText: "",
   _jmol.ready["" + name] = true;    buttonCssClass: null,
 }    buttonCssText: "",
     checkboxCssClass: null,
 function _jmolConvertInline(model) {    checkboxCssText: "",
   var inlineModel = model.replace(/\r|\n|\r\n/g, "|");    java_arguments: "-Xmx512m",
   if (_jmol.debugAlert)    radioCssClass: null,
     alert("inline model:\n" + inlineModel);    radioCssText: "",
   return inlineModel;    linkCssClass: null,
 }    linkCssText: "",
     menuCssClass: null,
 function _jmolGetAppletSize(size) {    menuCssText: "",
   var width, height;  
   var type = typeof size;    targetSuffix: 0,
   if (type == "number")    targetText: ",0",
     width = height = size;    scripts: [""],
   else if (type == "object" && size != null) {    params: {
     width = size[0]; height = size[1];    syncId: ("" + Math.random()).substring(3),
   }    progressbar: "true",
   if (! (width >= 25 && width <= 2000))    progresscolor: "blue",
     width = 300;    boxbgcolor: "black",
   if (! (height >= 25 && height <= 2000))    boxfgcolor: "white",
     height = 300;    boxmessage: "Downloading JmolApplet ..."
   return [width, height];    },
 }    ua: navigator.userAgent.toLowerCase(),
     // uaVersion: parseFloat(navigator.appVersion),  // not used
 function _jmolRadio(script, labelHtml, isChecked, separatorHtml, groupName) {  
   ++_jmol.radioCount;    os: "unknown",
   if (groupName == undefined || groupName == null)    browser: "unknown",
     groupName = "jmolRadioGroup" + (_jmol.radioGroupCount - 1);    browserVersion: 0,
   if (!script)    hasGetElementById: !!document.getElementById,
     return "";    isJavaEnabled: navigator.javaEnabled(),
   if (labelHtml == undefined || labelHtml == null)    // isNetscape47Win: false,  // not used, N4.7 is no longer supported even for detection
     labelHtml = script.substring(0, 32);    useIEObject: false,
   if (! separatorHtml)    useHtml4Object: false,
     separatorHtml = "";  
   var scriptIndex = _jmolAddScript(script);    windowsClassId: "clsid:8AD9C840-044E-11D1-B3E9-00805F499D93",
   return "<input name='" + groupName +    windowsCabUrl:
          "' type='radio' onClick='_jmolClick(" +     "http://java.sun.com/update/1.6.0/jinstall-6u22-windows-i586.cab",
          scriptIndex + _jmol.targetText +  
          ");return true;' onMouseover='_jmolMouseOver(" +    isBrowserCompliant: false,
          scriptIndex +    isJavaCompliant: false,
          ");return true;' onMouseout='_jmolMouseOut()' " +    isFullyCompliant: false,
  (isChecked ? "checked " : "") + _jmol.radioCssText + "/>" +  
          labelHtml + separatorHtml;    initialized: false,
 }    initChecked: false,
   
 function _jmolFindApplet(target) {    browserChecked: false,
   // first look for the target in the current window    checkBrowserAction: "alert",
   var applet = _jmolSearchFrames(window, target);    checkBrowserUrlOrMessage: null,
   if (applet == undefined)  
     applet = _jmolSearchFrames(top, target); // look starting in top frame    archivePath: null, // JmolApplet0.jar OR JmolAppletSigned0.jar
   return applet;  
 }    previousOnloadHandler: null,
   
 function _jmolSearchFrames(win, target) {    jmoljar: null,
   var applet;    useNoApplet: false,
   var frames = win.frames;  
   if (frames && frames.length) { // look in all the frames below this window    ready: {}
     for (var i = 0; i < frames.length; ++i) {  }
       applet = _jmolSearchFrames(frames[i++], target);  
       if (applet)  with (_jmol) {
         break;    function _jmolTestUA(candidate) {
     }      var ua = _jmol.ua;
   } else { // look for the applet in this window      var index = ua.indexOf(candidate);
     var doc = win.document;      if (index < 0)
 // getElementById fails on MacOSX Safari & Mozilla        return false;
     if (doc.applets)      _jmol.browser = candidate;
       applet = doc.applets[target];      _jmol.browserVersion = parseFloat(ua.substring(index+candidate.length+1));
     else      return true;
       applet = doc[target];    }
   }  
   return applet;    function _jmolTestOS(candidate) {
 }      if (_jmol.ua.indexOf(candidate) < 0)
         return false;
 function _jmolAddScript(script) {      _jmol.os = candidate;
   if (! script)      return true;
     return 0;    }
   var index = _jmol.scripts.length;  
   _jmol.scripts[index] = script;    _jmolTestUA("konqueror") ||
   return index;    _jmolTestUA("webkit") ||
 }    _jmolTestUA("omniweb") ||
     _jmolTestUA("opera") ||
 function _jmolClick(scriptIndex, targetSuffix) {    _jmolTestUA("webtv") ||
   jmolScript(_jmol.scripts[scriptIndex], targetSuffix);    _jmolTestUA("icab") ||
 }    _jmolTestUA("msie") ||
     (_jmol.ua.indexOf("compatible") < 0 && _jmolTestUA("mozilla")); //Netscape, Mozilla, Seamonkey, Firefox and anything assimilated
 function _jmolMenuSelected(menuObject, targetSuffix) {  
   var scriptIndex = menuObject.value;    _jmolTestOS("linux") ||
   if (scriptIndex != undefined) {    _jmolTestOS("unix") ||
     jmolScript(_jmol.scripts[scriptIndex], targetSuffix);    _jmolTestOS("mac") ||
     return;    _jmolTestOS("win");
   }  
   var length = menuObject.length;    isBrowserCompliant = hasGetElementById;
   if (typeof length == "number") {    // known exceptions (old browsers):
     for (var i = 0; i < length; ++i) {    if (browser == "opera" && browserVersion <= 7.54 && os == "mac"
       if (menuObject[i].selected) {        || browser == "webkit" && browserVersion < 125.12
         _jmolClick(menuObject[i].value, targetSuffix);        || browser == "msie" && os == "mac"
  return;        || browser == "konqueror" && browserVersion <= 3.3
       }      ) {
     }      isBrowserCompliant = false;
   }    }
   alert("?Que? menu selected bug #8734");  
 }    // possibly more checks in the future for this
     isJavaCompliant = isJavaEnabled;
 function _jmolCbClick(ckbox, whenChecked, whenUnchecked, targetSuffix) {  
   _jmolClick(ckbox.checked ? whenChecked : whenUnchecked, targetSuffix);    isFullyCompliant = isBrowserCompliant && isJavaCompliant;
 }  
     useIEObject = (os == "win" && browser == "msie" && browserVersion >= 5.5);
 function _jmolCbOver(ckbox, whenChecked, whenUnchecked) {    useHtml4Object =
   window.status = _jmol.scripts[ckbox.checked ? whenUnchecked : whenChecked];     (browser == "mozilla" && browserVersion >= 5) ||
 }     (browser == "opera" && browserVersion >= 8) ||
      (browser == "webkit" && browserVersion >= 412.2);
 function _jmolMouseOver(scriptIndex) {   try {
   window.status = _jmol.scripts[scriptIndex];    if (top.location.search.indexOf("JMOLJAR=")>=0)
 }      jmoljar = top.location.search.split("JMOLJAR=")[1].split("&")[0];
    } catch(e) {
 function _jmolMouseOut() {    // can't access top.location
   window.status = " ";   }
   return true;   try {
 }    useNoApplet = (top.location.search.indexOf("NOAPPLET")>=0);
    } catch(e) {
 function _jmolSetCodebase(codebase) {    // can't access top.document
   _jmol.codebase = codebase ? codebase : ".";   }
   if (_jmol.debugAlert)  }
     alert("jmolCodebase=" + _jmol.codebase);  
 }  function jmolSetMemoryMb(nMb) {
     _jmol.java_arguments = "-Xmx" + Math.round(nMb) + "m"
 function _jmolOnloadResetForms() {  }
   _jmol.previousOnloadHandler = window.onload;  
   window.onload =  function jmolSetParameter(name,value) {
   function() {    _jmol.params[name] = value
 //    alert("onloadResetForms");  }
     with (_jmol) {  
       if (buttonCount+checkboxCount+menuCount+radioCount+radioGroupCount > 0) {  function jmolSetCallback(callbackName,funcName) {
         var forms = document.forms;    _jmol.params[callbackName] = funcName
         if (!forms || forms.length == 0) {  }
           alert("<form> tags seem to be missing\n" +  
                 "Jmol/HTML input controls must be contained " +   try {
                 "within form tags"  // note this is done FIRST, so it cannot override a setting done by the developer
 //                + "\n\n" + forms + " forms.length=" + forms.length +    if (top.location.search.indexOf("PARAMS=")>=0) {
 //                " typeof=" + (typeof forms)      var pars = unescape(top.location.search.split("PARAMS=")[1].split("&")[0]).split(";");
                 );      for (var i = 0; i < pars.length; i++) {
         } else {        var p = pars[i].split(":");
           for (var i = forms.length; --i >= 0; )        jmolSetParameter(p[0],p[1]);
             forms[i].reset();      }
         }    }
       }   } catch(e) {
       if (previousOnloadHandler)    // can't access top.location
         previousOnloadHandler();   }
     }  
   }  function jmolSetSyncId(n) {
 }    return _jmol.params["syncId"] = n
   }
   
   function jmolGetSyncId() {
     return _jmol.params["syncId"]
   }
   
   function jmolSetLogLevel(n) {
     _jmol.params.logLevel = ''+n;
   }
   
     /*  AngelH, mar2007:
       By (re)setting these variables in the webpage before calling jmolApplet(),
       a custom message can be provided (e.g. localized for user's language) when no Java is installed.
     */
   if (noJavaMsg==undefined) var noJavaMsg =
           "You do not have Java applets enabled in your web browser, or your browser is blocking this applet.<br />\n" +
           "Check the warning message from your browser and/or enable Java applets in<br />\n" +
           "your web browser preferences, or install the Java Runtime Environment from <a href='http://www.java.com'>www.java.com</a><br />";
   if (noJavaMsg2==undefined) var noJavaMsg2 =
           "You do not have the<br />\n" +
           "Java Runtime Environment<br />\n" +
           "installed for applet support.<br />\n" +
           "Visit <a href='http://www.java.com'>www.java.com</a>";
   function _jmolApplet(size, inlineModel, script, nameSuffix) {
     /*  AngelH, mar2007
       Fixed percent / pixel business, to avoid browser errors:
       put "px" where needed, avoid where not.
   
         Bob Hanson, 1/2010
       Fixed inline escape changing returns to |
     */
     with (_jmol) {
       nameSuffix == undefined && (nameSuffix = appletCount);
       appletSuffixes.push(nameSuffix);
       ++appletCount;
       script || (script = "select *");
       var sz = _jmolGetAppletSize(size);
       var widthAndHeight = " width='" + sz[0] + "' height='" + sz[1] + "' ";
       var tHeader, tFooter;
       codebase || jmolInitialize(".");
       params.name = "jmolApplet" + nameSuffix
       params.permissions = (archivePath.indexOf("Signed") >= 0 ? "all-permissions" : "sandbox");
      
       if (useIEObject || useHtml4Object) {
         params.archive = archivePath;
         params.mayscript = 'true';
         params.codebase = codebase;
         params.code = 'JmolApplet.class';
         tHeader =
           "<object name='jmolApplet" + nameSuffix +
           "' id='jmolApplet" + nameSuffix + "' " + appletCssText + "\n" +
           widthAndHeight + "\n";
         tFooter = "</object>";
       }
       if (java_arguments)
         params.java_arguments = java_arguments;
       if (useIEObject) { // use MSFT IE6 object tag with .cab file reference
         tHeader += " classid='" + windowsClassId + "'\n" +
         (windowsCabUrl ? " codebase='" + windowsCabUrl + "'\n" : "") + ">\n";
       } else if (useHtml4Object) { // use HTML4 object tag
         tHeader += " type='application/x-java-applet'\n>\n";
           /*  " classid='java:JmolApplet'\n" +  AH removed this
             Chromium Issue 62076:   Java Applets using an <object> with a classid paramater don't load.
             http://code.google.com/p/chromium/issues/detail?id=62076
             They say this is the correct behavior according to the spec, and there's no indication at this point
             that WebKit will be changing the handling, so eventually Safari will acquire this behavior too.
             Removing the classid parameter seems to be well tolerated by all browsers (even IE!).
           */
       } else { // use applet tag
         tHeader =
           "<applet name='jmolApplet" + nameSuffix +
           "' id='jmolApplet" + nameSuffix + "' " + appletCssText + "\n" +
           widthAndHeight + "\n" +
           " code='JmolApplet'" +
           " archive='" + archivePath + "' codebase='" + codebase + "'\n" +
           " mayscript='true'>\n";
         tFooter = "</applet>";
       }
       var visitJava;
       if (useIEObject || useHtml4Object) {
       var szX = "width:" + sz[0]
       if ( szX.indexOf("%")==-1 ) szX+="px"
       var szY = "height:" + sz[1]
       if ( szY.indexOf("%")==-1 ) szY+="px"
         visitJava =
           "<p style='background-color:yellow; color:black; " +
       szX + ";" + szY + ";" +
           // why doesn't this vertical-align work?
     "text-align:center;vertical-align:middle;'>\n" +
       noJavaMsg +
           "</p>";
       } else {
         visitJava =
           "<table bgcolor='yellow'><tr>" +
           "<td align='center' valign='middle' " + widthAndHeight + "><font color='black'>\n" +
       noJavaMsg2 +
           "</font></td></tr></table>";
       }
       params.loadInline = (inlineModel ? inlineModel : "");
       params.script = (script ? _jmolSterilizeScript(script) : "");
       var t = tHeader + _jmolParams() + visitJava + tFooter;
       jmolSetTarget(nameSuffix);
       ready["jmolApplet" + nameSuffix] = false;
       if (_jmol.debugAlert)
         alert(t);
       return _jmolDocumentWrite(t);
     }
   }
   
   function _jmolParams() {
    var t = "";
    for (var i in _jmol.params)
     if(_jmol.params[i]!="")
        t+="  <param name='"+i+"' value='"+_jmol.params[i]+"' />\n";
    return t
   }
   
   function _jmolInitCheck() {
     if (_jmol.initChecked)
       return;
     _jmol.initChecked = true;
     jmolInitialize(defaultdir, defaultjar)
   }
   
   function _jmolCheckBrowser() {
     with (_jmol) {
       if (browserChecked)
         return;
       browserChecked = true;
   
       if (isFullyCompliant)
         return true;
   
       if (checkBrowserAction == "redirect")
         location.href = checkBrowserUrlOrMessage;
       else if (checkBrowserAction == "popup")
         _jmolPopup(checkBrowserUrlOrMessage);
       else {
         var msg = checkBrowserUrlOrMessage;
         if (msg == null)
           msg = "Your web browser is not fully compatible with Jmol\n\n" +
                 "browser: " + browser +
                 "   version: " + browserVersion +
                 "   os: " + os +
                 "   isBrowserCompliant: " + isBrowserCompliant +
                 "   isJavaCompliant: " + isJavaCompliant +
                 "\n\n" + ua;
         alert(msg);
       }
     }
     return false;
   }
   
   function jmolSetXHTML(id) {
     _jmol.isXHTML = true
     _jmol.XhtmlElement = null
     _jmol.XhtmlAppendChild = false
     if (id){
       _jmol.XhtmlElement = document.getElementById(id)
       _jmol.XhtmlAppendChild = true
     }
   }
   
   function _jmolDocumentWrite(text) {
     if (_jmol.currentDocument) {
       if (_jmol.isXHTML && !_jmol.XhtmlElement) {
         var s = document.getElementsByTagName("script")
         _jmol.XhtmlElement = s.item(s.length - 1)
         _jmol.XhtmlAppendChild = false
       }
       if (_jmol.XhtmlElement) {
         _jmolDomDocumentWrite(text)
       } else {
         _jmol.currentDocument.write(text);
       }
     }
     return text;
   }
   
   function _jmolDomDocumentWrite(data) {
     var pt = 0
     var Ptr = []
     Ptr[0] = 0
     while (Ptr[0] < data.length) {
       var child = _jmolGetDomElement(data, Ptr)
       if (!child)break
       if (_jmol.XhtmlAppendChild)
         _jmol.XhtmlElement.appendChild(child)
       else
         _jmol.XhtmlElement.parentNode.insertBefore(child, _jmol.XhtmlElement);
     }
   }
   function _jmolGetDomElement(data, Ptr, closetag, lvel) {
     var e = document.createElement("span")
     e.innerHTML = data
     Ptr[0] = data.length
     return e
   
   //unnecessary?
   
     closetag || (closetag = "")
     lvel || (lvel = 0)
     var pt0 = Ptr[0]
     var pt = pt0
     while (pt < data.length && data.charAt(pt) != "<") pt++
     if (pt != pt0) {
       var text = data.substring(pt0, pt)
       Ptr[0] = pt
       return document.createTextNode(text)
     }
     pt0 = ++pt
     var ch
     while (pt < data.length && "\n\r\t >".indexOf(ch = data.charAt(pt)) < 0) pt++
     var tagname = data.substring(pt0, pt)
     var e = (tagname == closetag  || tagname == "/" ? ""
       : document.createElementNS ? document.createElementNS('http://www.w3.org/1999/xhtml', tagname)
       : document.createElement(tagname));
     if (ch == ">") {
       Ptr[0] = ++pt
       return e
     }
     while (pt < data.length && (ch = data.charAt(pt)) != ">") {
       while (pt < data.length && "\n\r\t ".indexOf(ch = data.charAt(pt)) >= 0) pt++
       pt0 = pt
       while (pt < data.length && "\n\r\t =/>".indexOf(ch = data.charAt(pt)) < 0) pt++
       var attrname = data.substring(pt0, pt).toLowerCase()
       if (attrname && ch != "=")
         e.setAttribute(attrname, "true")
       while (pt < data.length && "\n\r\t ".indexOf(ch = data.charAt(pt)) >= 0) pt++
       if (ch == "/") {
         Ptr[0] = pt + 2
         return e
       } else if (ch == "=") {
         var quote = data.charAt(++pt)
         pt0 = ++pt
         while (pt < data.length && (ch = data.charAt(pt)) != quote) pt++
         var attrvalue = data.substring(pt0, pt)
         e.setAttribute(attrname, attrvalue)
         pt++
       }
     }
     Ptr[0] = ++pt
     while (Ptr[0] < data.length) {
       var child = _jmolGetDomElement(data, Ptr, "/" + tagname, lvel+1)
       if (!child)break
       e.appendChild(child)
     }
     return e
   }
   
   function _jmolPopup(url) {
     var popup = window.open(url, "JmolPopup",
                             "left=150,top=150,height=400,width=600," +
                             "directories=yes,location=yes,menubar=yes," +
                             "toolbar=yes," +
                             "resizable=yes,scrollbars=yes,status=yes");
     if (popup.focus)
       poup.focus();
   }
   
   function _jmolReadyCallback(name) {
     if (_jmol.debugAlert)
       alert(name + " is ready");
     _jmol.ready["" + name] = true;
   }
   
   function _jmolSterilizeScript(script) {
     script = script.replace(/'/g, "&#39;");
     if (_jmol.debugAlert)
       alert("script:\n" + script);
     return script;
   }
   
   function _jmolSterilizeInline(model) {
     model = model.replace(/\r|\n|\r\n/g, (model.indexOf("|") >= 0 ? "\\/n" : "|")).replace(/'/g, "&#39;");
     if (_jmol.debugAlert)
       alert("inline model:\n" + model);
     return model;
   }
   
   function _jmolRadio(script, labelHtml, isChecked, separatorHtml, groupName, id, title) {
     ++_jmol.radioCount;
     groupName != undefined && groupName != null || (groupName = "jmolRadioGroup" + (_jmol.radioGroupCount - 1));
     if (!script)
       return "";
     labelHtml != undefined && labelHtml != null || (labelHtml = script.substring(0, 32));
     separatorHtml || (separatorHtml = "")
     var scriptIndex = _jmolAddScript(script);
     var eospan = "</span>"
     var t = "<span id=\"span_"+id+"\""+(title ? " title=\"" + title + "\"":"")+"><input name='"
     + groupName + "' id='"+id+"' type='radio' onclick='_jmolClick(this," +
            scriptIndex + _jmol.targetText + ");return true;' onmouseover='_jmolMouseOver(" +
            scriptIndex + ");return true;' onmouseout='_jmolMouseOut()' " +
      (isChecked ? "checked='true' " : "") + _jmol.radioCssText + " />"
     if (labelHtml.toLowerCase().indexOf("<td>")>=0) {
     t += eospan
     eospan = "";
     }
     t += "<label for=\"" + id + "\">" + labelHtml + "</label>" +eospan + separatorHtml;
   
     return t;
   }
   
   function _jmolFindApplet(target) {
     // first look for the target in the current window
     var applet = _jmolFindAppletInWindow(_jmol.appletWindow != null ? _jmol.appletWindow : window, target);
     // THEN look for the target in child frames
     if (applet == undefined)
       applet = _jmolSearchFrames(window, target);
     // FINALLY look for the target in sibling frames
     if (applet == undefined)
       applet = _jmolSearchFrames(top, target); // look starting in top frame
     return applet;
   }
   
   function _jmolGetApplet(targetSuffix){
    var target = "jmolApplet" + (targetSuffix ? targetSuffix : "0");
    var applet = _jmolFindApplet(target);
    if (applet) return applet
    _jmol.alerted || alert("could not find applet " + target);
    _jmol.alerted = true;
    return null
   }
   
   function _jmolSearchFrames(win, target) {
     var applet;
     var frames = win.frames;
     if (frames && frames.length) { // look in all the frames below this window
      try{
       for (var i = 0; i < frames.length; ++i) {
         applet = _jmolSearchFrames(frames[i], target);
         if (applet)
           return applet;
       }
      }catch(e) {
     if (_jmol.debugAlert)
       alert("Jmol.js _jmolSearchFrames cannot access " + win.name + ".frame[" + i + "] consider using jmolSetAppletWindow()")
      }
     }
     return applet = _jmolFindAppletInWindow(win, target)
   }
   
   function _jmolFindAppletInWindow(win, target) {
       var doc = win.document;
       if (doc.getElementById(target))
         return doc.getElementById(target);
       if (doc.applets)
         return doc.applets[target];
       return doc[target];
   }
   
   function _jmolAddScript(script) {
     if (!script)
       return 0;
     var index = _jmol.scripts.length;
     _jmol.scripts[index] = script;
     return index;
   }
   
   function _jmolClick(elementClicked, scriptIndex, targetSuffix) {
     _jmol.element = elementClicked;
     _jmolScriptExecute(elementClicked, _jmol.scripts[scriptIndex], targetSuffix);
   }
   
   function _jmolMenuSelected(menuObject, targetSuffix) {
     var scriptIndex = menuObject.value;
     if (scriptIndex != undefined) {
       _jmolScriptExecute(menuObject, _jmol.scripts[scriptIndex], targetSuffix);
       return;
     }
     var len = menuObject.length;
     if (typeof len == "number") {
       for (var i = 0; i < len; ++i) {
         if (menuObject[i].selected) {
           _jmolClick(menuObject[i], menuObject[i].value, targetSuffix);
     return;
         }
       }
     }
     alert("?Que? menu selected bug #8734");
   }
   
   
   _jmol.checkboxMasters = {};
   _jmol.checkboxItems = {};
   
   function jmolSetCheckboxGroup(chkMaster,chkBox) {
     var id = chkMaster;
     if(typeof(id)=="number")id = "jmolCheckbox" + id;
     chkMaster = document.getElementById(id);
     if (!chkMaster)alert("jmolSetCheckboxGroup: master checkbox not found: " + id);
     var m = _jmol.checkboxMasters[id] = {};
     m.chkMaster = chkMaster;
     m.chkGroup = {};
     for (var i = 1; i < arguments.length; i++){
       var id = arguments[i];
       if(typeof(id)=="number")id = "jmolCheckbox" + id;
       checkboxItem = document.getElementById(id);
       if (!checkboxItem)alert("jmolSetCheckboxGroup: group checkbox not found: " + id);
       m.chkGroup[id] = checkboxItem;
       _jmol.checkboxItems[id] = m;
     }
   }
   
   function _jmolNotifyMaster(m){
     //called when a group item is checked
     var allOn = true;
     var allOff = true;
     for (var chkBox in m.chkGroup){
       if(m.chkGroup[chkBox].checked)
         allOff = false;
       else
         allOn = false;
     }
     if (allOn)m.chkMaster.checked = true;
     if (allOff)m.chkMaster.checked = false;
     if ((allOn || allOff) && _jmol.checkboxItems[m.chkMaster.id])
       _jmolNotifyMaster(_jmol.checkboxItems[m.chkMaster.id])
   }
   
   function _jmolNotifyGroup(m, isOn){
     //called when a master item is checked
     for (var chkBox in m.chkGroup){
       var item = m.chkGroup[chkBox]    
       if (item.checked != isOn)
         item.click();
       if (_jmol.checkboxMasters[item.id])
         _jmolNotifyGroup(_jmol.checkboxMasters[item.id], isOn)
     }
   }
   
   function _jmolCbClick(ckbox, whenChecked, whenUnchecked, targetSuffix) {
     _jmol.control = ckbox
     _jmolClick(ckbox, ckbox.checked ? whenChecked : whenUnchecked, targetSuffix);
     if(_jmol.checkboxMasters[ckbox.id])
     _jmolNotifyGroup(_jmol.checkboxMasters[ckbox.id], ckbox.checked)
     if(_jmol.checkboxItems[ckbox.id])
     _jmolNotifyMaster(_jmol.checkboxItems[ckbox.id])
   }
   
   function _jmolCbOver(ckbox, whenChecked, whenUnchecked) {
     window.status = _jmol.scripts[ckbox.checked ? whenUnchecked : whenChecked];
   }
   
   function _jmolMouseOver(scriptIndex) {
     window.status = _jmol.scripts[scriptIndex];
   }
   
   function _jmolMouseOut() {
     window.status = " ";
     return true;
   }
   
   function _jmolSetCodebase(codebase) {
     _jmol.codebase = codebase ? codebase : ".";
     if (_jmol.debugAlert)
       alert("jmolCodebase=" + _jmol.codebase);
   }
   
   function _jmolOnloadResetForms() {
     // must be evaluated ONLY once
     _jmol.previousOnloadHandler = window.onload;
     window.onload =
     function() {
       with (_jmol) {
         if (buttonCount+checkboxCount+menuCount+radioCount+radioGroupCount > 0) {
           var forms = document.forms;
           for (var i = forms.length; --i >= 0; )
             forms[i].reset();
         }
         if (previousOnloadHandler)
           previousOnloadHandler();
       }
     }
   }
   
   ////////////////////////////////////
   /////extensions for getProperty/////
   ////////////////////////////////////
   
   
   function _jmolEvalJSON(s,key){
    s=s+""
   
    if(!s)return []
    if(s.charAt(0)!="{"){
     if(s.indexOf(" | ")>=0)s=s.replace(/\ \|\ /g, "\n")
     return s
    }
    var A = eval("("+s+")")
    if(!A)return
    if(key && A[key])A=A[key]
    return A
   }
   
   function _jmolEnumerateObject(A,key){
    var sout=""
    if(typeof(A) == "string" && A!="null"){
     sout+="\n"+key+"=\""+A+"\""
    }else if(!isNaN(A)||A==null){
     sout+="\n"+key+"="+(A+""==""?"null":A)
    }else if(A.length){
       sout+=key+"=[]"
       for(var i=0;i<A.length;i++){
     sout+="\n"
     if(typeof(A[i]) == "object"||typeof(A[i]) == "array"){
       sout+=_jmolEnumerateObject(A[i],key+"["+i+"]")
     }else{
       sout+=key+"["+i+"]="+(typeof(A[i]) == "string" && A[i]!="null"?"\""+A[i].replace(/\"/g,"\\\"")+"\"":A[i])
     }
       }
    }else{
       if(key != ""){
     sout+=key+"={}"
     key+="."
       }
   
       for(var i in A){
     sout+="\n"
     if(typeof(A[i]) == "object"||typeof(A[i]) == "array"){
       sout+=_jmolEnumerateObject(A[i],key+i)
     }else{
       sout+=key+i+"="+(typeof(A[i]) == "string" && A[i]!="null"?"\""+A[i].replace(/\"/g,"\\\"")+"\"":A[i])
     }
       }
    }
    return sout
   }
   
   
   function _jmolSortKey0(a,b){
    return (a[0]<b[0]?1:a[0]>b[0]?-1:0)
   }
   
   function _jmolSortMessages(A){
    if(!A || typeof(A)!="object")return []
    var B = []
    for(var i=A.length-1;i>=0;i--)for(var j=0;j<A[i].length;j++)B[B.length]=A[i][j]
    if(B.length == 0) return
    B=B.sort(_jmolSortKey0)
    return B
   }
   
   /////////additional extensions //////////
   
   
   function _jmolDomScriptLoad(URL){
    //open(URL) //to debug
    _jmol.servercall=URL
    var node = document.getElementById("_jmolScriptNode")
    if (node && _jmol.browser!="msie"){
       document.getElementsByTagName("HEAD")[0].removeChild(node)
       node=null
    }
    if (node) {
      node.setAttribute("src",URL)
    } else {
      node=document.createElement("script")
      node.setAttribute("id","_jmolScriptNode")
      node.setAttribute("type","text/javascript")
      node.setAttribute("src",URL)
      document.getElementsByTagName("HEAD")[0].appendChild(node)
    }
   }
   
   
   function _jmolExtractPostData(url){
    S=url.split("&POST:")
    var s=""
    for(var i=1;i<S.length;i++){
     KV=S[i].split("=")
     s+="&POSTKEY"+i+"="+KV[0]
     s+="&POSTVALUE"+i+"="+KV[1]
    }
    return "&url="+escape(S[0])+s
   }
   
   function _jmolLoadModel(targetSuffix,remoteURL,array,isError,errorMessage){
    //called by server, but in client
    //overload this function to customize return
    _jmol.remoteURL=remoteURL
    isError && alert(errorMessage)
    jmolLoadInlineScript(array.join("\n"),_jmol.optionalscript,targetSuffix)
   }
   
   //////////user property/status functions/////////
   
   function jmolGetStatus(strStatus,targetSuffix){
    return _jmolSortMessages(jmolGetPropertyAsArray("jmolStatus",strStatus,targetSuffix))
   }
   
   function jmolGetPropertyAsArray(sKey,sValue,targetSuffix) {
    return _jmolEvalJSON(jmolGetPropertyAsJSON(sKey,sValue,targetSuffix),sKey)
   }
   
   function jmolGetPropertyAsString(sKey,sValue,targetSuffix) {
    var applet = _jmolGetApplet(targetSuffix);
    sValue == undefined && (sValue="");
    return (applet ? applet.getPropertyAsString(sKey,sValue) + "" : "")
   }
   
   function jmolGetPropertyAsJSON(sKey,sValue,targetSuffix) {
    sValue == undefined && (sValue = "")
    var applet = _jmolGetApplet(targetSuffix);
    try {
     return (applet ? applet.getPropertyAsJSON(sKey,sValue) + "" : "")
    } catch(e) {
     return ""
    }
   }
   
   function jmolGetPropertyAsJavaObject(sKey,sValue,targetSuffix) {
    sValue == undefined && (sValue = "")
    var applet = _jmolGetApplet(targetSuffix);
    return (applet ? applet.getProperty(sKey,sValue) : null)
   }
   
   
   function jmolDecodeJSON(s) {
    return _jmolEnumerateObject(_jmolEvalJSON(s),"")
   }
   
   
   ///////// synchronous scripting ////////
   
   function jmolScriptWait(script, targetSuffix) {
     targetSuffix == undefined && (targetSuffix="0")
     var Ret=jmolScriptWaitAsArray(script, targetSuffix)
     var s = ""
     for(var i=Ret.length;--i>=0;)
     for(var j=0;j< Ret[i].length;j++)
     s+=Ret[i][j]+"\n"
     return s
   }
   
   function jmolScriptWaitOutput(script, targetSuffix) {
     targetSuffix == undefined && (targetSuffix="0")
     var ret = ""
     try{
      if (script) {
       _jmolCheckBrowser();
       var applet=_jmolGetApplet(targetSuffix);
       if (applet) ret += applet.scriptWaitOutput(script);
      }
     }catch(e){
     }
    return ret;
   }
   
   function jmolEvaluate(molecularMath, targetSuffix) {
   
     //carries out molecular math on a model
   
     targetSuffix == undefined && (targetSuffix="0")
     var result = "" + jmolGetPropertyAsJavaObject("evaluate", molecularMath, targetSuffix);
     var s = result.replace(/\-*\d+/,"")
     if (s == "" && !isNaN(parseInt(result)))return parseInt(result);
     var s = result.replace(/\-*\d*\.\d*/,"")
     if (s == "" && !isNaN(parseFloat(result)))return parseFloat(result);
     return result;
   }
   
   function jmolScriptEcho(script, targetSuffix) {
     // returns a newline-separated list of all echos from a script
     targetSuffix == undefined && (targetSuffix="0")
     var Ret=jmolScriptWaitAsArray(script, targetSuffix)
     var s = ""
     for(var i=Ret.length;--i>=0;)
     for(var j=Ret[i].length;--j>=0;)
           if (Ret[i][j][1] == "scriptEcho")s+=Ret[i][j][3]+"\n"
     return s.replace(/ \| /g, "\n")
   }
   
   
   function jmolScriptMessage(script, targetSuffix) {
     // returns a newline-separated list of all messages from a script, ending with "script completed\n"
     targetSuffix == undefined && (targetSuffix="0")
     var Ret=jmolScriptWaitAsArray(script, targetSuffix)
     var s = ""
     for(var i=Ret.length;--i>=0;)
     for(var j=Ret[i].length;--j>=0;)
           if (Ret[i][j][1] == "scriptStatus")s+=Ret[i][j][3]+"\n"
     return s.replace(/ \| /g, "\n")
   }
   
   
   function jmolScriptWaitAsArray(script, targetSuffix) {
    var ret = ""
    try{
     jmolGetStatus("scriptEcho,scriptMessage,scriptStatus,scriptError",targetSuffix)
     if (script) {
       _jmolCheckBrowser();
       var applet=_jmolGetApplet(targetSuffix);
       if (applet) ret += applet.scriptWait(script);
       ret = _jmolEvalJSON(ret,"jmolStatus")
       if(typeof ret == "object")
     return ret
     }
    }catch(e){
    }
     return [[ret]]
   }
   
   
   
   ////////////   save/restore orientation   /////////////
   
   function jmolSaveOrientation(id, targetSuffix) {
    targetSuffix == undefined && (targetSuffix="0")
    return _jmol["savedOrientation"+id] = jmolGetPropertyAsArray("orientationInfo","info",targetSuffix).moveTo
   }
   
   function jmolRestoreOrientation(id, targetSuffix) {
    targetSuffix == undefined && (targetSuffix="0")
    var s=_jmol["savedOrientation"+id]
    if (!s || s == "")return
    s=s.replace(/1\.0/,"0")
    return jmolScriptWait(s,targetSuffix)
   }
   
   function jmolRestoreOrientationDelayed(id, delay, targetSuffix) {
    arguments.length < 2 && (delay=1)
    targetSuffix == undefined && (targetSuffix="0")
    var s=_jmol["savedOrientation"+id]
    if (!s || s == "")return
    s=s.replace(/1\.0/,delay)
    return jmolScriptWait(s,targetSuffix)
   }
   
   ////////////  add parameter /////////////
   /*
    * for adding callbacks or other parameters. Use:
   
      jmolSetDocument(0)
      var s= jmolApplet(....)
      s = jmolAppletAddParam(s,"messageCallback", "myFunctionName")
      document.write(s)
      jmolSetDocument(document) // if you want to then write buttons and such normally
   
    */
   
   function jmolAppletAddParam(appletCode,name,value){
     return (value == "" ? appletCode : appletCode.replace(/\<param/,"\n<param name='"+name+"' value='"+value+"' />\n<param"))
   }
   
   ///////////////auto load Research Consortium for Structural Biology (RCSB) data ///////////
   
   function jmolLoadAjax_STOLAF_RCSB(fileformat,pdbid,optionalscript,targetSuffix){
   
    _jmol.thismodel || (_jmol.thismodel = "1crn")
    _jmol.serverURL || (_jmol.serverURL="http://fusion.stolaf.edu/chemistry/jmol/getajaxjs.cfm")
    _jmol.RCSBserver || (_jmol.RCSBserver="http://www.rcsb.org")
    _jmol.defaultURL_RCSB || (_jmol.defaultURL_RCSB=_jmol.RCSBserver+"/pdb/files/1CRN.CIF")
    fileformat || (fileformat="PDB")
    pdbid || (pdbid=prompt("Enter a 4-digit PDB ID:",_jmol.thismodel))
    if(!pdbid || pdbid.length != 4)return ""
    targetSuffix || (targetSuffix="0")
    optionalscript || (optionalscript="")
    var url=_jmol.defaultURL_RCSB.replace(/1CRN/g,pdbid.toUpperCase())
    fileformat=="CIF" || (url=url.replace(/CIF/,fileformat))
    _jmol.optionalscript=optionalscript
    _jmol.thismodel=pdbid
    _jmol.thistargetsuffix=targetSuffix
    _jmol.thisurl=url
    _jmol.modelArray = []
    url=_jmol.serverURL+"?returnfunction=_jmolLoadModel&returnArray=_jmol.modelArray&id="+targetSuffix+_jmolExtractPostData(url)
    _jmolDomScriptLoad(url)
    return url
   }
   
   /////////////// St. Olaf College AJAX server -- ANY URL ///////////
   
   function jmolLoadAjax_STOLAF_ANY(url, userid, optionalscript,targetSuffix){
    _jmol.serverURL="http://fusion.stolaf.edu/chemistry/jmol/getajaxjs.cfm"
    _jmol.thisurlANY || (_jmol.thisurlANY = "http://www.stolaf.edu/depts/chemistry/mo/struc/data/ycp3-1.mol")
    url || (url=prompt("Enter any (uncompressed file) URL:", _jmol.thisurlANY))
    userid || (userid="0")
    targetSuffix || (targetSuffix="0")
    optionalscript || (optionalscript="")
    _jmol.optionalscript=optionalscript
    _jmol.thistargetsuffix=targetSuffix
    _jmol.modelArray = []
    _jmol.thisurl = url
    url=_jmol.serverURL+"?returnfunction=_jmolLoadModel&returnArray=_jmol.modelArray&id="+targetSuffix+_jmolExtractPostData(url)
    _jmolDomScriptLoad(url)
   }
   
   
   /////////////// Mineralogical Society of America (MSA) data /////////
   
   function jmolLoadAjax_MSA(key,value,optionalscript,targetSuffix){
   
    _jmol.thiskeyMSA || (_jmol.thiskeyMSA = "mineral")
    _jmol.thismodelMSA || (_jmol.thismodelMSA = "quartz")
    _jmol.ajaxURL_MSA || (_jmol.ajaxURL_MSA="http://rruff.geo.arizona.edu/AMS/result.php?mineral=quartz&viewing=ajaxjs")
    key || (key=prompt("Enter a field:", _jmol.thiskeyMSA))
    if(!key)return ""
    value || (value=prompt("Enter a "+key+":", _jmol.thismodelMSA))
    if(!value)return ""
    targetSuffix || (targetSuffix="0")
    optionalscript || (optionalscript="")
    optionalscript == 1 && (optionalscript='load "" {1 1 1}')
    var url=_jmol.ajaxURL_MSA.replace(/mineral/g,key).replace(/quartz/g,value)
    _jmol.optionalscript=optionalscript
    _jmol.thiskeyMSA=key
    _jmol.thismodelMSA=value
    _jmol.thistargetsuffix=targetSuffix
    _jmol.thisurl=url
    _jmol.modelArray = []
    loadModel=_jmolLoadModel
    _jmolDomScriptLoad(url)
    return url
   }
   
   
   
   function jmolLoadAjaxJS(url, userid, optionalscript,targetSuffix){
    userid || (userid="0")
    targetSuffix || (targetSuffix="0")
    optionalscript || (optionalscript="")
    _jmol.optionalscript=optionalscript
    _jmol.thismodel=userid
    _jmol.thistargetsuffix=targetSuffix
    _jmol.modelArray = []
    _jmol.thisurl = url
    url+="&returnFunction=_jmolLoadModel&returnArray=_jmol.modelArray&id="+targetSuffix
    _jmolDomScriptLoad(url)
   }
   
   
   //// in case Jmol library has already been loaded:
   
   }catch(e){}
   
   ///////////////moving atoms //////////////
   
   // HIGHLY experimental!!
   
   function jmolSetAtomCoord(i,x,y,z,targetSuffix){
       _jmolCheckBrowser();
         var applet=_jmolGetApplet(targetSuffix);
         if (applet) applet.getProperty('jmolViewer').setAtomCoord(i,x,y,z)
   }
   
   function jmolSetAtomCoordRelative(i,x,y,z,targetSuffix){
       _jmolCheckBrowser();
         var applet=_jmolGetApplet(targetSuffix);
         if (applet) applet.getProperty('jmolViewer').setAtomCoordRelative(i,x,y,z)
   }
   
   
   ///////////////applet fake for testing buttons/////////////
   
   
   if(_jmol.useNoApplet){
     jmolApplet = function(w){
       var s="<table style='background-color:black' width="+w+"><tr height="+w+">"
       +"<td align=center valign=center style='background-color:white'>"
       +"Applet would be here"
       +"<p><textarea id=fakeApplet rows=5 cols=50></textarea>"
       +"</td></tr></table>"
       return _jmolDocumentWrite(s)
     }
   
     _jmolFindApplet = function(){return jmolApplet0}
   
     jmolApplet0 = {
      script: function(script){document.getElementById("fakeApplet").value="\njmolScript:\n"+script}
     ,scriptWait: function(script){document.getElementById("fakeApplet").value="\njmolScriptWait:\n"+script}
     ,loadInline: function(data,script){document.getElementById("fakeApplet").value="\njmolLoadInline data:\n"+data+"\n\nscript:\n"+script}
     }
   }
   
   
   ///////////////////////////////////////////
   
     //  This should no longer be needed, jmolResizeApplet() is better; kept for backwards compatibility
     /*
     Resizes absolutely (pixels) or by percent of window (w or h 0.5 means 50%).
     targetSuffix is optional and defaults to zero (first applet in page).
     Both w and h are optional, but needed if you want to use targetSuffix.
       h defaults to w
       w defaults to 100% of window
     If either w or h is between 0 and 1, then it is taken as percent/100.
     If either w or h is greater than 1, then it is taken as a size (pixels).
     */
   function jmolResize(w,h,targetSuffix) {
    _jmol.alerted = true;
    var percentW = (!w ? 100 : w <= 1  && w > 0 ? w * 100 : 0);
    var percentH = (!h ? percentW : h <= 1 && h > 0 ? h * 100 : 0);
    if (_jmol.browser=="msie") {
      var width=document.body.clientWidth;
      var height=document.body.clientHeight;
    } else {
      var netscapeScrollWidth=15;
      var width=window.innerWidth - netscapeScrollWidth;
      var height=window.innerHeight-netscapeScrollWidth;
    }
    var applet = _jmolGetApplet(targetSuffix);
    if(!applet)return;
    applet.style.width = (percentW ? width * percentW/100 : w)+"px";
    applet.style.height = (percentH ? height * percentH/100 : (h ? h : w))+"px";
    //title=width +  " " + height + " " + (new Date());
   }
   
   // 13 Jun 09 -- makes jmolResize() obsolete  (kept for backwards compatibility)
   function jmolResizeApplet(size,targetSuffix) {
    // See _jmolGetAppletSize() for the formats accepted as size [same used by jmolApplet()]
    //  Special case: an empty value for width or height is accepted, meaning no change in that dimension.
    _jmol.alerted = true;
    var applet = _jmolGetApplet(targetSuffix);
    if(!applet)return;
    var sz = _jmolGetAppletSize(size, "px");
    sz[0] && (applet.style.width = sz[0]);
    sz[1] && (applet.style.height = sz[1]);
   }
   
   function _jmolGetAppletSize(size, units) {
     /* Accepts single number or 2-value array, each one can be one of:
        percent (text string ending %), decimal 0 to 1 (percent/100), number, or text string (interpreted as nr.)
        [width, height] array of strings is returned, with units added if specified.
        Percent is relative to container div or element (which should have explicitly set size).
     */
     var width, height;
     if ( (typeof size) == "object" && size != null ) {
       width = size[0]; height = size[1];
     } else {
       width = height = size;
     }
     return [_jmolFixDim(width, units), _jmolFixDim(height, units)];
   }
   
   function _jmolFixDim(x, units) {
     var sx = "" + x;
     return (sx.length == 0 ? (units ? "" : _jmol.allowedJmolSize[2])
     : sx.indexOf("%") == sx.length-1 ? sx
       : (x = parseFloat(x)) <= 1 && x > 0 ? x * 100 + "%"
       : (isNaN(x = Math.floor(x)) ? _jmol.allowedJmolSize[2]
         : x < _jmol.allowedJmolSize[0] ? _jmol.allowedJmolSize[0]
           : x > _jmol.allowedJmolSize[1] ? _jmol.allowedJmolSize[1]
           : x) + (units ? units : ""));
   }
   
   
   

Removed from v.1.2  
changed lines
  Added in v.1.4


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>