Ticket #9238: trac_9238-jmol-for-review-only.patch

File trac_9238-jmol-for-review-only.patch, 52.5 KB (added by kcrisman, 10 years ago)

For review purposes only! Diffs with previous files, apparently.

  • sagenb/data/jmol/jmol

    # HG changeset patch
    # User Karl-Dieter Crisman <kcrisman@gmail.com>
    # Date 1298396960 18000
    # Node ID ec65029b2038c3495a2d7811c8c47a84c236655a
    # Parent  ac9fcbe78299d82a4ed739c63c6debff07786e4b
    Trac 9238 Jmol update - for review purposes only!
    
    diff -r ac9fcbe78299 -r ec65029b2038 sagenb/data/jmol/jmol
    a b  
    11#!/bin/sh
    22#JMOL_HOME=`dirname "$0"`
    3 JMOL_HOME="`"$SAGE_LOCAL"/bin/sage-pypkg-location sagenb`""/sagenb/data/jmol"
     3JMOL_HOME="`"$SAGE_ROOT"/devel/sagenb/sagenb/data/jmol""`"
    44
    55# Collect -D & -m options as java arguments
    66command=java
  • sagenb/data/sage/js/jmol_lib.js

    diff -r ac9fcbe78299 -r ec65029b2038 sagenb/data/sage/js/jmol_lib.js
    a b  
     1/*
     2Based on the SAGE jmol_lib.js as of 12/13/09
     3Modified by Jonathan Gutow <gutow@uwosh.edu>
     4version 1.1.2 10/15/10
     5version 1.1.3 1/22/11 - can use direct calls to jmolApplet when building page now, should
     6        not have to extract any Jmol.js funtions and turn them into strings anymore. Also
     7        code cleanup and changes to accommodate vocabulary changes in the file created by
     8        SAGE.
     9       
     10        This version limits the number of Jmol applets that may simultaneously be live
     11        on a page.  The default is 5.  This may be set by calling setMaxLiveJmol.
     12
     13        This version places the applet in a div within a table.  The applet is resized to specific
     14        sizes other approaches seem to run amok of the updates from the server.  The default
     15        sizes are miniature (100 x 100 px), small (250 x 250 px), medium (400 x 400 px)
     16        and large (600 x 600 px) choices.   User may choose a random size by using the
     17        "open in separate window" option.
     18        NOTE THIS VERSION IGNORES THE SIZE AS SPECIFIED BY THE SAGE NOTEBOOK CODE.
     19
     20        This version also allows turning on and off surfaces and meshes.  Color of
     21        the surfaces and meshes may also be controlled.  Developed with Jmol version 11.9.
     22        Recommend using 11.8 at least and 11.10 preferably as the minimum.
     23
     24        Things to do:
     25        at present it is using the script saved in the JmolStatus structure to avoid problems
     26        with the scrolling div added to the applet tab.
     27        fix in new window to cleanly use script in JmolStatus structure
     28        make settings save with worksheet.
     29
     30REQUIRES:
     31Jmol.js
     32        path must be specified in the <head> of the page: use jmolInitialize(path), where
     33        "path" = the relative path on the server to this file.
     34
     35notebook_lib.js
     36        uses the get_element(Id) function from this library.
     37        the delete_all_output() call must be modified to call jmol_delete_all_output()
     38        the evaluate_cell() call must be modified to call jmol_delete_check()
     39
     40main.css
     41        where a
     42select.jmol {
     43  border: #aaaaaa;
     44  border-style: solid;
     45  border-top-width: 1px;
     46  border-right-width: 1px;
     47  border-bottom-width: 1px;
     48  border-left-width: 1px
     49}
     50 format is defined.  If it doesn't exist it will still work, but not be as pretty.
     51*/
     52
    153/*global window */
    254/*jslint white: true, onevar: true, undef: true, nomen: true, eqeqeq: true, plusplus: true, bitwise: true, regexp: true, strict: true, newcap: true, immed: true */
    355//"use strict";
    456
    557var jmol_count = 0;
    6 //var allowedJmolSize = [1, 2048, 300];
    7 function jmol_applet(size, url) {
    8     var s;
    9     jmolSetDocument(cell_writer);
    10     jmolSetAppletCssClass('jmol_applet');
    11     jmolApplet(size, "script " + url, jmol_count);
    12     s = ' <a href="#" onclick="jmol_image(' + jmol_count +
    13         ');return false;">Get Image</a>';
    14     cell_writer.write(s);
     58
     59var jmolStatus = {
     60    maxLiveAllowed: 5,
     61    numLive: 0,
     62    jmolArray: new Array(),//-1 deleted, 0 awake, 1 sleeping, 2 loading.
     63    urls: new Array(),
     64    defaultdirectory: new Array(),
     65    widths: new Array(),
     66    heights: new Array(),
     67    controlStrs: new Array(),
     68    captionStrs: new Array(),
     69    pictureStrs: new Array(),
     70    stateScripts: new Array(),
     71    cntrls: new Array(),
     72    }
     73
     74//Some default constants
     75//applet sizes
     76miniature = 100;
     77small = 250;
     78medium = 400;
     79large = 600;
     80sleepMessage = "Click to Sleep this 3-D view";
     81wakeMessage = "Wake this 3-D view";
     82captionStr = ''; //empty no caption
     83controlStr = ' '; //could put special controls here.  Must not be empty for default controls to appear, that is why it is a space.
     84
     85function jmol_pulldown(theform) {
     86    /*
     87    This is called when the user selects a menu item.  This just
     88    evaluates the corresponding value, which results in running some
     89    javascript code to do the action.
     90    */
     91    with(theform) {
     92        eval(options[selectedIndex].value);
     93        }
     94    }
     95
     96function jmol_spin (state, n) {
     97    if(state == true){
     98        result = jmolScriptWait("spin on", n);
     99        }else {
     100        result = jmolScriptWait("spin off", n);
     101        }
     102    storeDefaultDir(n);
     103    jmolUpdateState(n);
     104    }
     105
     106function jmol_show_element(state,whichsurface, type ,n) {
     107    if(state == true){
     108        scriptStr = ''+type+' '+whichsurface+' on;';
     109        result = jmolScriptWait(scriptStr, n);
     110        }else {
     111        scriptStr = ''+type+' '+whichsurface+' off;';
     112        result = jmolScriptWait(scriptStr, n);
     113        }
     114    storeDefaultDir(n);
     115    jmolUpdateState(n);
     116    }
     117
     118function do_jmolScriptWait(scriptStr, n){
     119    result = jmolScriptWait(scriptStr,n);
     120    storeDefaultDir(n);
     121    jmolUpdateState(n);
     122    }
     123
     124function jmolSurfColor(color,surface,n){
     125    scriptStr = 'color $'+surface+' '+color;
     126    result = jmolScriptWait(scriptStr,n);
     127    storeDefaultDir(n);
     128    jmolUpdateState(n);
     129    }
     130
     131function jmolCntrlPanel(state, panelID, tabID, tabName, panelHTML){ //The default definition for a jmolcontrolpanel
     132    this.state = state; //0 active, 1 inactive ...other numbers for future possibilities
     133    this.panelID = panelID;
     134    this.tabID = tabID;
     135    this.tabName=tabName;
     136    this.panelHTML=panelHTML;
     137    }
     138
     139function jmolUpdateState(n){
     140    var divID = 'jmolStateDiv'+n;
     141    var stateStr ="#a comment to guarrantee one line";
     142    stateStr+= jmolGetPropertyAsString("stateInfo", "", n);
     143    re_modelinline = /data "model list"(.|\n|\r)*end "model list"/;
     144    var modelStr = (stateStr.match(re_modelinline))[0];
     145    modelStr = modelStr.replace(/\r\n/g,'|').replace(/\r/g, '|').replace(/\n/g,'|').replace(/\|\|/g, '|');
     146//    modelStr = 'fix between here '+modelStr+' and here';
     147    stateStr = stateStr.replace(re_modelinline, modelStr);
     148    re_endofline = /\n/g;
     149    re_doublequote = /"/g;
     150    get_element(divID).innerHTML = '<div style="overflow:scroll;max-height:400px;">set '+ jmolStatus.defaultdirectory[n] +';<br>'+stateStr.replace(re_endofline,'<br>')+'</div>';
     151    jmolStatus.stateScripts[n] = 'set '+ jmolStatus.defaultdirectory[n] +';\n'+stateStr;
     152    }
     153
     154function storeDefaultDir(n) {
     155    result = jmolScript('set MessageCallback "jmolMessageHandler"; show defaultdirectory; delay 1;',n);
     156    }
     157
     158var jmolLastDefaultDir = '';
     159
     160function jmolMessageHandler(applet, messageStr, number) {
     161    re_defaultdirectory =/defaultdirectory/i;
     162    re_jmolApplet = /jmolApplet/i;
     163    var javaScriptStr = ''+messageStr;
     164    var appletname = ""+applet;
     165    var messagenum = ""+number;
     166    if (javaScriptStr.search(re_defaultdirectory)!=-1){
     167        jmolLastDefaultDir = javaScriptStr;
     168        appletN = appletname[appletname.search(re_jmolApplet),(appletname.length-1)];
     169        jmolStatus.defaultdirectory[appletN]= javaScriptStr;
     170        }
     171   }
     172
     173
     174function jmolCntrlPanels(whichActive,cntrlPanels){ //The default definition for a group of jmolCntrlPanels
     175    this.whichActive = whichActive; //array index for the active, front, panel
     176    this.cntrlPanels= cntrlPanels; //array of jmolCntrlPanel
     177    }
     178
     179function makeCntrlPanels(url, n, functionnames){
     180    var panels = new Array();
     181    //Applet options: size, background color, spinning etc...
     182    panelID = 'size_jmol'+n;
     183    tabID = 'tab_'+panelID;
     184    //size control
     185    panelHTML ='3-D display size: <select class="jmol" title ="Select a size" onchange="jmol_pulldown(this);">';
     186    panelHTML += '<option value = "jmolResizeApplet('+miniature+','+n+');"> Miniature ('+miniature+'px)</option>';
     187    panelHTML += '<option  value = "jmolResizeApplet('+small+','+n+');"> Small ('+small+'px)</option>';
     188    panelHTML += '<option selected = "" value = "jmolResizeApplet('+medium+','+n+');"> Medium ('+medium+'px)</option>';
     189    panelHTML += '<option value = "jmolResizeApplet('+large+','+n+');"> Large ('+large+'px)</option>';
     190    panelHTML += '</';
     191    panelHTML += 'select><br/>';
     192    panelHTML +='<ul><li><a href="javascript:void(jmol_popup(\''+n+'\'))">Arbitrarily resizable in own window</a></li>';
     193    //static image to save
     194    panelHTML +='<li><a href="javascript:void(jmol_image('+n+'))">Get static image to save</a></li>';
     195    panelHTML +='<hr/>';
     196    //spin on
     197    panelHTML +='<input class="worksheet" type="checkbox" value="spin on" onchange="jmol_spin(this.checked,'+n+');" title="Enable/disable spin"/>Spin on';
     198    //background color
     199    panelHTML += '';
     200    panels[0] = new jmolCntrlPanel(0, panelID, tabID, "Applet",panelHTML);
     201    //Function Display Options
     202    panelID = 'disp_jmol'+n;
     203    tabID = 'tab_'+panelID;
     204    if(functionnames ==''||functionnames==undefined){//no names for the functions so cannot build list, will have to get after Jmol launched
     205        panelHTML = '<a href="javascript:void(getSurfacesFromJmol('+n+'))">Click to request functions from Jmol</a> so that you can adjust function color and mesh.';
     206        }else{//step through functionnames and make list of functions.
     207        panelHTML ='<table><tr><td>Function Name</td><td>On</td><td>Color</td><td>Translucent</td><td>Mesh</td><td>Mesh Color</td></tr>';
     208        var funcs=functionnames.split(',');
     209        for(i in funcs){
     210            }
     211        str+='</table>';
     212        }
     213    panels[1] = new jmolCntrlPanel(1, panelID, tabID, "Functions",panelHTML);
     214    //Axes to be done
     215    //State will be hidden long term
     216    panelID = 'jmolStateDiv'+n;
     217    tabID = 'tab_'+panelID;
     218    panelHTML ='# Blank script';
     219    panels[2] = new jmolCntrlPanel(2, panelID, tabID,"State", panelHTML);
     220    return (new jmolCntrlPanels(0, panels)); //this will then be plugged into jmolStatus.cntrls[n]
     221    }
     222
     223function setMaxLiveJmol(maxLive) { //sets maximum applets live at once.
     224    jmolStatus.maxLiveAllowed = maxLive;
     225    }
     226
     227function jmol_applet(size, url, cell_num, functionnames) { //makes a new applet. Presently ignoring size, kept for backwards compatibility
     228    size = medium; //overriding value from server.  Probably should accept server value.
     229    jmolSetDocument(false);
     230    //Where am I?  Need to know in cases where I need to write directly to this cell.  Not used initially.
     231    cell_ID = 'cell_output_html_'+cell_num;
     232    //write everything to the cell using cell writer so that it will appear next time the cell is opened.
     233    cntrlPanels = makeCntrlPanels(url, jmol_count, functionnames);
     234    controlStr = makeControlStr(url, jmol_count, cntrlPanels);
     235    str = newJmolTableStr(jmolStatus, size, size, url, wakeMessage, sleepMessage, captionStr, controlStr);
     236    //add debugging div
     237    //str += '<div id="JmolDebug">Jmol Debugging goes here</div>';
     238    //sleep some if necessary
     239    limitlive(jmol_count, jmolStatus);
     240    //now we can start the new one
     241    cell_writer.write(str);
     242    var scriptStr = 'script "'+url+'"; isosurface fullylit; pmesh o* fullylit; set antialiasdisplay on;';
     243    scriptStr += 'set MessageCallback "jmolMessageHandler"; show defaultdirectory; delay 1; javascript "jmolAppletLive('+ jmol_count +');jmolUpdateState('+ jmol_count +')";';
     244    jmolSetAppletColor("white");
     245    //Now we wait for the server by calling a function that waits if the div is not yet written.
     246    launchNewJmol(size,scriptStr,jmol_count);
     247    //we will still set all the data for this applet so that other asynchronously created applets do not grab its ID.
     248    jmolStatus.urls[jmol_count]=url;
     249    jmolStatus.widths[jmol_count] = size;
     250    jmolStatus.heights[jmol_count]= size;
     251    jmolStatus.numLive = jmolStatus.numLive+1;
     252    jmolStatus.jmolArray[jmol_count] = 2; //it's now  "loading".
     253    jmolStatus.controlStrs[jmol_count] = controlStr;
     254    jmolStatus.captionStrs[jmol_count] = captionStr;
     255    jmolStatus.cntrls[jmol_count]=cntrlPanels;
    15256    jmol_count += 1;
    16     return s;
     257    return str;
     258    }
     259
     260function launchNewJmol(size,scriptStr,n){
     261        if (!get_element("Jmol"+ n)){
     262            var launchStr = 'launchNewJmol('+size+',\''+scriptStr+'\','+n+')';
     263//            alert("Waiting for Jmol"+n+" div.");
     264            setTimeout(launchStr, 500);
     265        }else{
     266            get_element("Jmol"+ n).innerHTML = jmolApplet([size, size], scriptStr, n);
     267//            jmolStatus.jmolArray[n]=0; //it's done loading and is "live".
     268        }
     269    }
     270
     271function jmolAppletLive(n){//called after an applet is loaded to say set state to live
     272        jmolStatus.jmolArray[n]=0;
     273    }
     274function newJmolTableStr(jmolStatus, width, height, url, wakeMessage, sleepMessage, captionStr, controlStr){
     275    //if captionStr or controlStr is the empty string, '', then the caption or the controls  respectively will not be shown.
     276    n = jmolStatus.jmolArray.length;
     277    Id = 'Jmol'+n;
     278    tableId = 'Jmol_Table_'+Id;
     279    tableStr = '<table id="'+tableId+'" border="1"><tr><td id="'+tableId+'_cell_0_0">';
     280    tableStr +='<div id = '+Id+'>';
     281    tableStr += 'Loading Jmol 3-D viewer...</div></td>';
     282    if (controlStr!=''){
     283        tempCntrlStr = '<a href="javascript:void(wakeJmol('+n+',jmolStatus))">'+ wakeMessage +'</a>';
     284        tempCntrlStr +='<br/><a href="javascript:void(sleepJmol('+n+',jmolStatus))">'+sleepMessage+'</a>';
     285        tempCntrlStr += '<br/><a href="javascript:void(jmol_help())">Help for Jmol 3-D viewer</a>'+controlStr;
     286        tableStr += '<td id="'+tableId+'_cell_0_1">'+tempCntrlStr+'</td>';
     287        }
     288    tableStr += '</tr>';
     289    if (captionStr !=''){
     290        tableStr +='<tr><td>'+captionStr+'</td></tr>';
     291        }
     292    tableStr += '</table>';
     293    return (tableStr);
     294    }
     295
     296function makeControlStr(url, n, cntrlPanels){
     297    //This function makes the string that contains the controls other than the default wake and sleep links.
     298    //These are extracted from the cntrlPanels structure passed from the calling routine
     299    cntrlID= 'cntrl_jmol'+n;
     300    str = '<div id="'+cntrlID+'" class="ui-tabs">';
     301    //make tabs
     302    str+= '<ul class="ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header">';
     303    for (i in cntrlPanels.cntrlPanels){
     304        if(cntrlPanels.cntrlPanels[i].state==0){
     305            classStr = "ui-tabs-selected ui-widget-content";
     306            }else{
     307            classStr ="ui-state-default";
     308            }
     309        str+='<li id="'+cntrlPanels.cntrlPanels[i].tabID+'" class="'+classStr+'">';
     310        whichWake = cntrlPanels.cntrlPanels[i].isActive;
     311        tabName = cntrlPanels.cntrlPanels[i].tabName;
     312        str+='<a href="javascript:void(switchJmolCntrl(jmolStatus,'+n+','+i+'))">'+tabName+'</a></li>';
     313        }
     314    str += '</ul>';
     315    //make panels
     316    for (i in cntrlPanels.cntrlPanels){
     317        panelID = cntrlPanels.cntrlPanels[i].panelID;
     318        if(cntrlPanels.cntrlPanels[i].state==0){
     319            classStr = "ui-tabs-panel";
     320            }else{
     321            classStr ="ui-tabs-panel ui-tabs-hide";
     322            }       
     323        str+='<div id="'+panelID+'" class ="'+classStr+'">';
     324        str+= cntrlPanels.cntrlPanels[i].panelHTML;
     325        str+= '</div>';
     326        }
     327    str+='</div>';
     328    return str;
     329    }
     330
     331function getSurfacesFromJmol(n){
     332    var surfaceListStr = jmolGetPropertyAsString("stateInfo", "modelState", n);
     333    var scriptArray=parseJmolStateInfoForSurfaces(surfaceListStr);
     334    var surfaceArray = makeJmolSurfaceArray2(scriptArray);
     335    var dispStr='';
     336    if (scriptArray[0]==''||scriptArray[0]==null||scriptArray[0]=='null'||scriptArray[0]==undefined||scriptArray[0]=='undefined') {//no surfaces ?!
     337        dispStr = 'No surfaces recovered from Jmol.  Sorry.';
     338        }
     339//    for (i in scriptArray){
     340//        dispStr +=scriptArray[i]+'<br/>';
     341//        }
     342    dispStr +='<table  border="1"><tr><td>Function</td><td>Color</td><td>Translucency</td><td>On?</td><td>Mesh Color</td><td>Mesh on?</td></tr>';
     343    for (i in surfaceArray){
     344//        dispStr +='Surface #'+i+'<br/>';
     345        dispStr +='<tr>';
     346//        dispStr +='Type:'+surfaceArray[i].type+'<br/>';
     347//        dispStr +='ID:' +surfaceArray[i].ID+'<br/>';
     348        dispStr +='<td>'+surfaceArray[i].ID+'</td>';
     349//        dispStr +='Source:' +surfaceArray[i].source+'<br/>';
     350//        dispStr +='Source Type:'+surfaceArray[i].sourceType+'<br/>';
     351//        dispStr +='Color:' +surfaceArray[i].color+'<br/>';
     352        var scriptStr = 'color $'+surfaceArray[i].ID+' $COLOR$';
     353        var boxIdStr = 'colorBox_'+n+'_'+i;
     354        dispStr +='<td>'+JmolColorPickerBoxStr(scriptStr,surfaceArray[i].color,boxIdStr,n)+'</td>';
     355//        dispStr +='Fill State:' +surfaceArray[i].fillState+'<br/>';
     356        dispStr +='<td><select class="jmol" title ="Select transparency" onchange="jmolSurfColor(this.value,\''+surfaceArray[i].ID+'\','+n+');">';
     357        dispStr +='<option selected="" value ="'+surfaceArray[i].fillState+'">Default</option>';
     358        var fillState='opaque';
     359        dispStr +='<option value = "'+ fillState +'">opaque</option>';
     360        fillState = 'translucent 32';
     361        dispStr +='<option value = "'+ fillState +'">translucent 32</option>';
     362        fillState ='translucent 64';
     363        dispStr +='<option value = "'+ fillState +'">translucent 64</option>';
     364        fillState = 'translucent 96';
     365        dispStr +='<option value = "'+ fillState +'">translucent 96</option>';
     366        fillState ='translucent 128';
     367        dispStr +='<option value = "'+ fillState +'">translucent 128</option>';
     368        dispStr +='</';
     369        dispStr += 'select></td>';
     370//        dispStr +='Visibility:' +surfaceArray[i].visibility+'<br/>';
     371        var checkedStr = 'checked = "true"';
     372        re_off = /off/i;
     373        if (surfaceArray[i].visibility.match(re_off)){
     374            checkedStr = '';
     375            }
     376        dispStr +='<td><input class="worksheet" type="checkbox" '+checkedStr+' onchange="jmol_show_element(this.checked,\''+surfaceArray[i].ID+'\',\''+surfaceArray[i].type+'\','+n+');" title="Show function"/></td>';
     377//        dispStr +='Mesh ID:' +surfaceArray[i].mesh_ID+'<br/>';
     378//        dispStr +='Mesh Color:' +surfaceArray[i].meshColor+'<br/>';
     379        if (surfaceArray[i].mesh_ID ==''){//we don't have a mesh so  need to make one
     380            scriptStr = surfaceArray[i].type+' '+surfaceArray[i].ID+'_mesh '+surfaceArray[i].sourceType+' '+surfaceArray[i].source+'noFill mesh;';
     381            scriptStr += surfaceArray[i].type+' fullylit off;';
     382            scriptStr += 'color '+surfaceArray[i].type+' opaque [x000000];';
     383            result = jmolScriptWait(scriptStr, n);
     384            surfaceArray[i].mesh_ID=surfaceArray[i].ID+'_mesh';
     385            //mesh doesn't stay off
     386//            scriptStr = surfaceArray[i].type+' '+surfaceArray[i].mesh_ID+' off;';
     387//            result = jmolScriptWait(scriptStr, n);
     388            surfaceArray[i].meshColor = '[x000000]';
     389            surfaceArray[i].mesh_visibility = 'off';
     390            //we've changed the state, so save
     391            storeDefaultDir(n);
     392            jmolUpdateState(n);
     393            }
     394        scriptStr = 'color $'+surfaceArray[i].mesh_ID+' $COLOR$';
     395        boxIdStr = 'colorBox_'+n+'_'+i+'_mesh';
     396        dispStr +='<td>'+JmolColorPickerBoxStr(scriptStr,surfaceArray[i].meshColor,boxIdStr,n)+'</td>';
     397//        dispStr +='Mesh Fill State:' +surfaceArray[i].meshState+'<br/>';
     398//        dispStr +='Mesh Visibility:' +surfaceArray[i].mesh_visibility+'<br/>';
     399        checkedStr = 'checked = "true"';
     400        if (surfaceArray[i].mesh_visibility.match(re_off)){
     401            checkedStr = '';
     402            }
     403        dispStr +='<td><input class="worksheet" type="checkbox" '+checkedStr+' onchange="jmol_show_element(this.checked,\''+surfaceArray[i].mesh_ID+'\',\''+surfaceArray[i].type+'\','+n+');" title="Show mesh"/></td>';
     404         dispStr +='</tr>';
     405        }
     406    dispStr +='</table>';
     407    displayID = 'disp_jmol'+n;
     408    get_element(displayID).innerHTML= dispStr;
     409    }
     410
     411function parseJmolStateInfoForSurfaces(stateInfoStr){
     412    //Returns an array of strings containing the script commands for creating and loading surfaces, pmesh or isosurface.
     413    var tempStrArray=stateInfoStr.split(';');
     414    scriptArray = new Array();
     415    re_isosurface = /\s*isosurface/;
     416    re_pmesh =/\s*pmesh/;
     417    linecount = 0;
     418    for (i in tempStrArray){
     419        if(tempStrArray[i].match(re_isosurface)||tempStrArray[i].match(re_pmesh)){
     420            scriptArray[linecount]=tempStrArray[i]; //Safari doesn't like .append()?
     421            linecount=linecount+1;
     422            }
     423        }
     424    return scriptArray;
     425    }
     426
     427function makeJmolSurfaceArray2(scriptArray){
     428    //generates an array of surfaceState objects.  One for each surface.
     429    var surfaceArray = new Array();
     430    var surface_count = 0;
     431    var lastID = '';
     432    var lastSurface = -1;
     433    var lastIsMesh = false;
     434    for (i in scriptArray){
     435        properties = parseScriptLine(scriptArray[i],lastIsMesh);
     436        k = 0;
     437        which = -1;
     438        while (k < surface_count){//if we get a match we're looking at a second load, so just update info.
     439           if((properties.ID == surfaceArray[k].ID && surfaceArray[k].ID!='')||(properties.mesh_ID==surfaceArray[k].mesh_ID && surfaceArray[k].mesh_ID!='')
     440                  ||(properties.source == surfaceArray[k].source && surfaceArray[k].source!='')){
     441               which = k;
     442               k=surface_count; // found a match we're done
     443               } else {
     444               k=k+1;
     445               } //end if
     446            }//end while k<surface_count
     447        if (properties.ID=='' && properties.mesh_ID=='' && properties.source == '' && lastSurface>=0) {//this is just update to previous line...
     448             which = lastSurface;
     449             }//end update to previous line
     450        if (which == -1) {//new surface
     451            surfaceArray[surface_count] = new surfaceState(properties.type, properties.ID, properties.source, properties.sourceType,
     452                     properties.color, properties.fillState, properties.visibility, properties.mesh_ID, properties.meshColor,
     453                     properties.meshState, properties.mesh_visibility);
     454            lastSurface = surface_count;
     455            surface_count = surface_count + 1;
     456            } else {//existing surface update only things that are not empty strings and don't corrupt existing labels.
     457            if (properties.type!=''){
     458                surfaceArray[which].type = properties.type;
     459               }
     460            if (properties.sourceType!=''&& surfaceArray[which].sourceType==''){
     461                surfaceArray[which].sourceType = properties.sourceType;
     462               }
     463            if (properties.ID!='' && surfaceArray[which].ID==''){
     464               surfaceArray[which] = properties.ID;
     465               }
     466            if (properties.source!='' && surfaceArray[which].source==''){
     467               surfaceArray[which].source = properties.source;
     468               }
     469            if (properties.color!='') {
     470               surfaceArray[which].color = properties.color;
     471               }
     472            if (properties.fillState!=''){
     473               surfaceArray[which].fillState = properties.fillState;
     474               }
     475            if (properties.visibility!='') {
     476               surfaceArray[which].visibility = properties.visibility;
     477               }
     478            if (properties.mesh_ID!='' && surfaceArray[which].mesh_ID=='') {
     479               surfaceArray[which].mesh_ID = properties.mesh_ID;
     480               }
     481            if (properties.meshColor!='') {
     482               surfaceArray[which].meshColor = properties.meshColor;
     483               }
     484            if (properties.mesh_visibility!='') {
     485               surfaceArray[which].mesh_visibility = properties.mesh_visibility;
     486               }
     487            if (properties.meshState!='') {
     488               surfaceArray[which].meshState = properties.meshState;
     489               }
     490            lastSurface = which;
     491            }//end new or old surface
     492            if (properties.ID=='' && properties.mesh_ID!='') {
     493                lastIsMesh=true;
     494                }else{
     495                lastIsMesh=false;
     496                }     
     497        }//end stepping through scriptArray
     498    return (surfaceArray);
     499    }
     500
     501function parseScriptLine(scriptLine, lastIsMesh){
     502    var properties = {
     503        type: '',
     504        source: '',
     505        sourceType: '',
     506        ID: '',
     507        color: '',
     508        fillState: '',
     509        visibility: '',
     510        mesh_ID: '',
     511        meshColor: '',
     512        meshState: '',
     513        mesh_visibility: '',
     514        }
     515    re_wordboundary = /\s+/;
     516    var wordList = scriptLine.split(re_wordboundary);
     517    firstIndex = 0;
     518    if (wordList[0]=='') {
     519        firstIndex = 1;
     520        }
     521    if (wordList[firstIndex] == 'isosurface') {
     522       properties.type = 'isosurface';
     523       properties = parseIsosurfaceCmd(properties, wordList);
     524       }
     525    if (wordList[firstIndex] == 'pmesh') {
     526       properties.type = 'pmesh';
     527       properties = parsePmeshCmd(properties, wordList);
     528       }
     529    if (wordList[firstIndex] == 'color') {
     530       properties = parseColorCmd(properties, wordList);
     531       }
     532    if (lastIsMesh == true) {//check that the mesh values and non-mesh are not flipped
     533       if(properties.color!=''&&properties.meshColor==''){
     534           properties.meshColor=properties.color;
     535           properties.color='';
     536           }
     537       if(properties.visibility!=''&&properties.mesh_visibility==''){
     538           properties.mesh_visibility =properties.visibility;
     539           properties.visibility ='';
     540           }
     541       if(properties.fillState!=''&&properties.meshState==''){
     542           properties.meshState =properties.fillState;
     543           properties.fillState ='';
     544           }
     545       }
     546    return (properties);
     547    }
     548
     549function parseColorCmd(properties, wordList){
     550    re_dollarsign = /^$/;
     551    re_colorcode=/\[x.{6}\]/;
     552    re_translucent =/translucent/i;
     553    firstIndex = 0;
     554    if (wordList[0]=='') {
     555        firstIndex = 1;
     556        }
     557    parseFrom = firstIndex+2;
     558    if(wordList[firstIndex+1].match(re_dollarsign)) {
     559        properties.ID = wordList[firstIndex+1].replace('$','').toLowerCase();
     560        }
     561    for (i=parseFrom; i<wordList.length; i++){
     562        if (wordList[i]=='opaque') {
     563           properties.fillState = 'opaque';
     564           }//end opaque
     565        if (wordList[i].match(re_translucent)){
     566           properties.fillState = 'translucent';
     567           if (wordList[i+1].match(re_number)){
     568               properties.fillState='translucent '+wordList[i+1];
     569               }//end is it followed by number?
     570           }//end translucent
     571        if (wordList[i].match(re_colorcode)){
     572           properties.color = wordList[i];
     573           }//end colorcode
     574        }
     575    return properties;
     576    }
     577
     578function parsePmeshCmd(properties, wordList){
     579    return (parseIsosurfaceCmd(properties,wordList));
     580    }
     581
     582function parseIsosurfaceCmd(properties, wordList){
     583    firstIndex = 0;
     584    if (wordList[0]=='') {
     585        firstIndex = 1;
     586        }
     587    parseFrom = firstIndex+3;
     588    re_quoted = /".*"/;
     589    re_number = /d*\.*d*/;
     590    re_quote_global = /"/g;
     591    re_mesh = /mesh/i;
     592    re_nomesh = /nomesh/i;
     593    re_fill = /fill/i;
     594    re_nofill = /nofill/i;
     595    re_hidden = /hidden/i;
     596    if (wordList[firstIndex + 1]=='ID') {//modifying an existing surface
     597        properties.ID = (wordList[firstIndex + 2].replace(re_quote_global,'')).toLowerCase(); //if we're lucky and the name is not broken into two words?
     598        }else{
     599        properties.ID = (wordList[firstIndex + 1].replace(re_quote_global,'')).toLowerCase(); //if it is the loaded object name we will have to remove the quotes.
     600        if (wordList[firstIndex + 1].match(re_quoted)) {
     601            properties.source = wordList[firstIndex + 1];
     602            }//end if this word is in quotes
     603        parseFrom = firstIndex + 2;
     604        } //end wordList[firstIndex + 1]=='ID'
     605    for (i=parseFrom; i<wordList.length; i++){
     606        if (wordList[i].match(re_mesh)) {
     607           properties.mesh_visibility = 'on';
     608           }//end mesh
     609        if (wordList[i].match(re_nomesh)){
     610           properties.mesh_visibility = 'off';
     611           }//end nomesh
     612        if (wordList[i].match(re_fill)){
     613           properties.visibility = 'on';
     614           }//end fill
     615        if (wordList[i].match(re_nofill)){
     616           properties.visibility = 'off';
     617           }//end nofill
     618        if (wordList[i]=='opaque') {
     619           properties.fillState = 'opaque';
     620           }//end opaque
     621        if (wordList[i]=='translucent'){
     622           if (wordList[i+1].match(re_number)){
     623               properties.fillState='translucent '+wordList[i+1];
     624               }else{
     625               properties.fillState = 'translucent';
     626               }//end is it followed by number?
     627           }//end translucent
     628        if (wordList[i].match(re_quoted)) {
     629            properties.source = wordList[i];
     630            //check for sourceType
     631            re_pmesh = /pmesh/i;
     632            if(wordList[i-1].match(re_pmesh)){
     633                properties.sourceType = 'pmesh';
     634                }//end check for pmesh source type.
     635            if(properties.type=='pmesh'){
     636                properties.sourceType = 'pmesh';
     637                }//setting to match type if pmesh.
     638            }//end if this word is in quotes
     639        if (wordList[i].match(re_hidden)) {
     640            properties.visibility='off';
     641            }//end hidden
     642        }//end for
     643    //decide if this is only a mesh surface.
     644    if (properties.mesh_visibility=='on' && (properties.visibility=='off')) {//just mesh
     645        properties.mesh_ID = properties.ID;
     646        properties.ID = '';
     647        properties.meshColor = properties.color;
     648        properties.color = '';
     649        properties.mesh_visibility = properties.visibility;
     650        properties.visibility = '';
     651        }//end if mesh
     652    return properties;
     653    }
     654
     655function surfaceState(type, ID, source, sourceType, color, fillState, visibility, mesh_ID, meshColor, meshState, mesh_visibility){
     656    this.type = type; //'isosurface' or 'pmesh'
     657    this.ID = ID; //the ID string used by Jmol
     658    this.source=source; //the source filename (not the full path, should it be?)
     659    this.sourceType = sourceType; // "pmesh" if necessary for isosurface command
     660    this.color = color; //hex value for the color of the surface, default is yellow [xFFFF00]
     661    this.fillState = fillState; // "opaque" or "transparent" or "transparent 0.XX"
     662    this.visibility = visibility; //"on" or "off"
     663    this.mesh_ID = mesh_ID; //the ID string used by Jmol
     664    this.meshColor = meshColor; //hex value for the color of the mesh, default is black [x000000]
     665    this.meshState = meshState; //  "opaque" or "transparent" or "transparent 0.XX"
     666    this.mesh_visibility = mesh_visibility; // "on" or "off"
     667    }
     668
     669function switchJmolCntrl(jmolStatus,n,whichWake){//whichWake is the numerical index of the panel to wake
     670    //making use of the jsquery-ui defaults loaded in with SAGE, but cannot use their functions to switch tabs (don't know why).
     671    //Check to see if whichWake is already awake
     672    isActive = jmolStatus.cntrls[n].whichActive
     673    if(whichWake== isActive){
     674        return;
     675        }
     676    //first sleep the active panel.
     677    get_element(jmolStatus.cntrls[n].cntrlPanels[isActive].panelID).setAttribute('class','ui-tabs-panel ui-tabs-hide');
     678    get_element(jmolStatus.cntrls[n].cntrlPanels[isActive].tabID).setAttribute('class', 'ui-state-default');
     679    jmolStatus.cntrls[n].cntrlPanels[isActive].state=1;
     680    //Now unhide the control requested.
     681    get_element(jmolStatus.cntrls[n].cntrlPanels[whichWake].tabID).setAttribute('class', 'ui-tabs-selected ui-widget-content');
     682    get_element(jmolStatus.cntrls[n].cntrlPanels[whichWake].panelID).setAttribute('class','ui-tabs-panel');
     683    jmolStatus.cntrls[n].cntrlPanels[whichWake].state=0;
     684    jmolStatus.cntrls[n].whichActive=whichWake;
     685    }
     686
     687function sleepJmol(n,jmolStatus) {
     688    if(jmolStatus.jmolArray[n]==0){//it's awake, so put to sleep
     689        //get a picture to replace the applet
     690        jmolStatus.pictureStrs[n] = get_jmol_image(n, jmolStatus);
     691        //make sure the state is up-to-date
     692        jmolUpdateState(n);
     693        //Different browsers pass different versions of null and undefined.
     694        if(jmolStatus.pictureStrs[n]=="null"||jmolStatus.pictureStrs[n]==""||jmolStatus.pictureStrs[n]==undefined||jmolStatus.pictureStrs[n]==null||jmolStatus.pictureStrs[n]=="undefined"){//don't have a picture put up text instead
     695            get_element("Jmol"+n).innerHTML = 'Sleeping...<br/>Static plot unavailable. <br/>  Click Wake/Reset to get live plot.';
     696            }else{
     697            var imageID = 'Jmol_Image'+n;
     698            //The below does not work with Safari, doesn't show alternate text when no image data.
     699            var imageStr = '<image id='+imageID+' alt="If no plot appears here click Wake/Reset" src="data:image/jpeg;base64, ' + jmolStatus.pictureStrs[n] + '">';
     700            get_element("Jmol"+n).innerHTML = 'Sleeping...<br/>'+imageStr;
     701           }
     702        jmolStatus.jmolArray[n]=1; //we've turned it off
     703        jmolStatus.numLive = jmolStatus.numLive-1;
     704       }
     705    }
     706
     707function wakeJmol(n,jmolStatus) {
     708        if (jmolStatus.jmolArray[n] == -1) return; //this one has been deleted cannot wake.
     709        limitlive(n, jmolStatus);
     710        width = jmolStatus.widths[n];
     711        height = jmolStatus.heights[n];
     712        url = jmolStatus.urls[n];
     713        jmolSetDocument(false);
     714//      scriptStr = 'script "'+url+'"; isosurface fullylit; pmesh o* fullylit; set antialiasdisplay on;';
     715        re_linebreak = /<br>/gi;
     716//        scriptStr = get_element("jmolStateDiv"+n).innerHTML.replace(re_linebreak,'\n');
     717        var scriptStr = jmolStatus.stateScripts[n];
     718//to avoid a problem with testing of numbers in Jmol.js  quote the appletID #
     719        var nquote = n;
     720        get_element("Jmol"+ nquote).innerHTML = jmolApplet([width,height], scriptStr, nquote);
     721        if (jmolStatus.jmolArray[n]!=0){//it wasn't on, if it was we've just done a reset so don't need to update status
     722                jmolStatus.jmolArray[n]=0; //we've turned it on
     723                jmolStatus.numLive = jmolStatus.numLive+1;
     724                }
     725        }
     726
     727function limitlive(nWake, jmolStatus){
     728        //called before waking an old or initiating a new Jmol
     729        //nWake = index of the Jmol being initiated or wakened.
     730        //will attempt to shut down a Jmol as far away as possible.
     731        //needs to be more sophisticated about updating jmolStatus because
     732        //applets may have been removed without updating.
     733        while (jmolStatus.numLive >= jmolStatus.maxLiveAllowed) {
     734                //search only from zero
     735                k=0;
     736                while (jmolStatus.jmolArray[k]!=0){
     737                        k = k +1;
     738                        }
     739                //search only from max
     740                i = jmolStatus.jmolArray.length-1;
     741                while (jmolStatus.jmolArray[i]!=0){
     742                                i = i -1;
     743                        }
     744                if (Math.abs(nWake-i) > Math.abs(nWake-k)){
     745                        nSleep = i;}else{
     746                        nSleep = k;}
     747                sleepJmol(nSleep, jmolStatus);
     748                }
     749        }
     750
     751function jmol_delete_all_output() {
     752    //called by the delete_all_output function of the notebook to get jmol parameters cleaned up.
     753    jmol_count=0;
     754    jmolStatus.numLive=0;
     755    jmolStatus.jmolArray=new Array();
     756}
     757
     758function jmol_delete_check() {
     759    //called when cells are evaluated to see if any jmols have been deleted.  If so update their status.
     760    liveCount = jmolStatus.jmolArray.length;
     761    for ( k = 0; k< liveCount; k++) {
     762        testId= 'Jmol_Table_Jmol'+k; //looking for the whole table Jmol is in, since if the table is there it is sleeping.
     763        if (!get_element(testId)) { //we need to set this as deleted and maybe free up the ID?
     764            jmolStatus.jmolArray[k] = -1;
     765            //for the time being old IDs will not be reused.  Shouldn't be real big problem as completely resets
     766            //each time a page is opened.
     767        }
     768    }
     769    for ( i = 0; i < liveCount; i++){ //reset the number of live Jmols
     770        if (jmolStatus.jmolArray[i]!=0) {liveCount = liveCount-1;}
     771    }
     772    jmolStatus.numLive = liveCount;
    17773}
    18774
    19775function jmol_image(jmol_count) {
    20     var myImage = jmolGetPropertyAsString("image", "", jmol_count), s;
    21     mywindow = window.open("", "Jmol Image",
    22                            "menubar=no,width=600,height=600,toolbar=no");
    23     s = '<HTML><TITLE>Jmol Image</TITLE><BODY>';
    24     s += '<img src="data:image/jpeg;base64,' + myImage + '">';
    25     s += '<p>To save this image, you can try right-clicking on the image to copy it or save it to a file, or you may be able to just drag the image to your desktop.</p>';
    26     s += '</BODY></HTML>';
    27     mywindow.document.write(s);
     776  var myImage = jmolGetPropertyAsString("image","",jmol_count)
     777  mywindow = window.open("","Jmol Image","menubar=no,width=600,height=600,toolbar=no");
     778  s = '<HTML><TITLE>Jmol Image</TITLE><BODY>';
     779  s += '<img src="data:image/jpeg;base64,' + myImage + '">';
     780  s += '<p>To save this image, you can try right-clicking on the image to copy it or save it to a file, or you may be able to just drag the image to your desktop.</p>';
     781  s += '</BODY></HTML>';
     782  mywindow.document.write(s);
    28783}
    29784
    30 function jmol_popup(url) {
    31     var win = window.open("", "jmol viewer",
    32                           "width=600,height=600,resizable=1,statusbar=0");
     785
     786function get_jmol_image(n, jmolStatus){
     787    var pictureStr="";
     788    if(jmolStatus.jmolArray[n] == 0) {//it's live
     789        pictureStr = jmolGetPropertyAsString("image","",n);
     790        }
     791    return(pictureStr);
     792    }
     793
     794function jmol_popup(n) {
     795    win = window.open ("", "jmol viewer", "width=600,height=600,resizable=1,statusbar=0");
    33796    win.document.body.innerHTML = "";
    34797    win.document.title = "Sage 3d Viewer";
    35798    win.document.writeln("<h1 align=center>Sage 3d Viewer</h1>");
    36799    jmolSetDocument(win.document);
    37     jmolApplet("100%", "script" + url, jmol_count);
     800//    scriptStr = 'script "'+url+'"; isosurface fullylit; pmesh o* fullylit; set antialiasdisplay on;';
     801    re_linebreak = /<br>/gi;
     802    var scriptStr = get_element("jmolStateDiv"+n).innerHTML;
     803    scriptStr = scriptStr.replace(re_linebreak,'\n')
     804    scriptStr = jmolStatus.stateScripts[n];//comment out to use the script in jmolStateDiv.
     805    jmolApplet("100%", scriptStr, n);
    38806    win.focus();
    39807}
     808
     809function jmol_help(){
     810    win = window.open("/java/jmol/appletweb/JmolHelp.html","Jmol Help","width=400, height=600");
     811    win.focus();
     812}
     813
     814/* Tools adapted from the Jmol Widgets Libray
     815Jmol JAVASCRIPT WIDGET LIBRARY
     816
     817This is a compilation of Javascript widgets modified to follow the standard syntax from
     818Jmol.js and to work with Jmol.js.  These widgets have been taken from a number of places. 
     819Sources are acknowledged immediately before each block of code.  As you update please keep
     820the source of the code up-to-date as well.
     821
     822The widgets
     823USE OTHER FUNCTIONS IN THIS JAVASCRIPT LIBRARY AT YOUR OWN RISK AS THEIR FUNCTION AND
     824SYNTAX MAY CHANGE!!!
     825
     826------
     827JmolColorPickerBoxStr(scriptStr, rgb, boxIdStr,  appletId).
     828Returns a string that builds a colorpicker box.
     829All parameters are strings although appletId could potentially be a number, but it is used to make a string.
     830  scriptStr should contain $COLOR$ where you wish the color string to be passed to Jmol in the script you provide.
     831  rgb  (in this version expect hex color in Jmol format)
     832    is the browser standard 0-255 red-green-blue values specified as and array [red, green, blue] default = [127,127,127] a dark grey.
     833  boxIdStr should be a string that is unique to the web document, if not provided it will be set to colorBoxJ, J=0, 1, 2... in the order created.
     834  appletId is the standard Jmol id of applet you want the colorpicker to send the script to.  Default = "0".
     835------
     836
     837Updates & versions (most recent first please):
     838/* Jmol Simple JavaScript Color Picker
     839 by Jonathan Gutow, IE fixes thanks to Angel Herraez
     840V1.1
     841June 15, 2010
     842
     843requires
     844   Jmol.js
     845
     846Usage
     847Where ever you want a popup color picker box include a script like
     848
     849<script type="text/javascript">
     850var scriptStr2 = 'select carbon; color atom $COLOR$;';
     851JmolColorPickerBox("colorBox1", "rgb(100,100,100)", scriptStr2, "0");
     852</script>
     853
     854The only function that will not change name or syntax is JmolColorPickerBox(scriptStr, rgb, boxIdStr,  appletId).
     855
     856USE OTHER FUNCTIONS IN THE JAVASCRIPT LIBRARY AT YOUR OWN RISK.
     857All parameters are strings although appletId could potentially be a number, but it is used to make a string.
     858  scriptStr should contain $COLOR$ where you wish the color string to be passed to Jmol in the script you provide.
     859  rgb is the browser standard 0-255 red-green-blue values specified as an array [red, green, blue] default = [127,127,127] a dark grey.
     860  boxIdStr should be a string that is unique to the web document, if not provided it will be set to colorBoxJ, J=0, 1, 2... in the order created.
     861  appletId is the standard Jmol id of applet you want the colorpicker to send the script to.  Default = "0".
     862
     863
     864*/
     865
     866//globals and their defaults
     867
     868var JmolColorPickerStatus = {
     869    lastPicked: '', //last picked color...not used at present
     870    funcName: '', //where to pass to next after pickedColor()
     871    passThrough: '' //name of the global variable or structure containing information to be passed
     872    }
     873
     874var JmolColorPickerBoxes=new Array();//array of boxInfo
     875
     876function boxInfo(boxID, appletID, scriptStr){//used when using a predefined colorPickerBox
     877    this.boxID=boxID;
     878    this.appletID=appletID; //applet ID
     879    this.scriptStr=scriptStr; //script with $COLOR$ where the color should be placed.
     880    }
     881
     882function changeClass(someObj,someClassName) {
     883    someObj.setAttribute("class",someClassName);
     884    someObj.setAttribute("className",someClassName);  // this is for IE
     885}
     886
     887//Build the ColorPicker Div.
     888
     889// detect if browser supports data:URI   (IE6 & IE7 do not)
     890    var dataURIsupported = true;
     891    var testImg64 = new Image();
     892    testImg64.onload = testImg64.onerror = function() {
     893        if(this.width != 1 || this.height != 1) { dataURIsupported = false; }
     894    }
     895    testImg64.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==";
     896
     897function makeColorPicker(){
     898    JmolColorPickerDiv = get_element("JmolColorPickerDiv");
     899    if(! JmolColorPickerDiv){
     900        var colorPickerCSS = document.createElement('style');
     901        colorPickerCSS.type = 'text/css';
     902        CSSStr ='.JmolColorPicker_vis {border-style:solid;border-width:thin;clear:both;display:block;overflow:visible;position:absolute;margin-left:-52px;width:104px;z-index:2;}';
     903        CSSStr +='.JmolColorPicker_hid {height:0;min-height:0;display:none;overflow:hidden;z-index:0;}';
     904        if (colorPickerCSS.styleSheet) { // IE
     905            colorPickerCSS.styleSheet.cssText = CSSStr;
     906        } else { // W3C
     907            content = document.createTextNode(CSSStr);
     908            colorPickerCSS.appendChild(content);
     909        }
     910        document.getElementsByTagName('head')[0].appendChild(colorPickerCSS);
     911        JmolColorPickerDiv = document.createElement("div");
     912        JmolColorPickerDiv.setAttribute("id", "JmolColorPickerDiv");
     913        changeClass(JmolColorPickerDiv,"JmolColorPicker_hid");
     914        }
     915   var rgbs=[[255,0,0]
     916       ,[255,128,0]
     917       ,[255,255,0]
     918       ,[128,255,0]
     919       ,[0,255,0]
     920       ,[0,255,128]
     921       ,[0,255,255]
     922       ,[0,128,255]
     923       ,[0,0,255]
     924       ,[128,0,255]
     925       ,[255,0,255]
     926       ,[255,0,128]
     927       ,[255,255,255]
     928   ];
     929   var hues=[[190,100],
     930             [175,95],
     931             [150,90],
     932             [135,80],
     933             [100,68],
     934             [85,55],
     935             [70,40],
     936             [60,30],
     937             [50,20],
     938             [35,0]
     939     ];
     940    var tempwidth = 8*(rgbs.length);
     941    var htmlStr = '<div id="JmolColorPickerHover" style="font-size:2px;width:'+tempwidth+'px;text-align:right;background-color:white;cursor:default;">';
     942    if (dataURIsupported) {
     943        htmlStr += '<image id="JmolColorPickerCancel" onclick="pickedColor(\'cancel\');" src="data:image/bmp;base64,Qk3CAQAAAAAAADYAAAAoAAAACwAAAAsAAAABABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdnZ2j4+PoKCgqampqampoKCgj4+PAAAAAAAAAAAAAAAAAAAAAAAAsbGxwsLCysrKysrKwsLCAAAAAAAAAAAAAAAAZWVlAAAAAAAAAAAA29vb5OTk5OTkAAAAAAAAAAAAj4+PAAAAdnZ2oKCgAAAAAAAAAAAA9PT0AAAAAAAAAAAAwsLCoKCgAAAAfn5+qampysrKAAAAAAAAAAAAAAAAAAAA5OTkysrKqampAAAAfn5+qampysrK5OTkAAAAAAAAAAAA9PT05OTkysrKqampAAAAdnZ2oKCgwsLCAAAAAAAAAAAAAAAAAAAA29vbwsLCoKCgAAAAZWVlj4+PAAAAAAAAAAAA5OTkAAAAAAAAAAAAsbGxj4+PAAAATExMAAAAAAAAAAAAwsLCysrKysrKAAAAAAAAAAAAdnZ2AAAAAAAAAAAAAAAAj4+PoKCgqampqampoKCgAAAAAAAAAAAAAAAAAAAAAAAATExMZWVldnZ2fn5+fn5+dnZ2ZWVlAAAAAAAAAAAA">';
     944    } else {
     945        htmlStr += '<span id="JmolColorPickerCancel" onclick="pickedColor(\'cancel\');" style="font-size:10px; padding:0 2px; background-color:#A0A0A0; font-family:Verdana, Arial, Helvetica, sans-serif;">X</span>';
     946    }
     947    htmlStr += '</div>';         
     948    htmlStr += '<table cellspacing="0" cellpadding="0" border="0" style="font-size:2px; cursor:default;"><tbody>';
     949    for (j = 0; j < hues.length;j++){
     950    htmlStr += '<tr>'
     951    var f = (hues[j][0])/100.0;
     952       for (k = 0; k < rgbs.length; k++){
     953       if(rgbs[k][0]==255&&rgbs[k][1]==255&&rgbs[k][2]==255) f =(hues[j][1])/100.0;;
     954       r = Math.min(Math.max(Math.round(rgbs[k][0] * f),Math.round(255-rgbs[k][0])*(f-1)^2),255);
     955       g = Math.min(Math.max(Math.round(rgbs[k][1] * f),Math.round(255-rgbs[k][1])*(f-1)^2),255);
     956       b = Math.min(Math.max(Math.round(rgbs[k][2] * f),Math.round(255-rgbs[k][2])*(f-1)^2),255);
     957          htmlStr +='<td style="background-color: rgb(' + r + "," + g + ","+ b + ');">';
     958          htmlStr +='<div style="width: 8px; height: 8px;" onclick=\'pickedColor("rgb('+r+','+g+','+b+')");\' ';
     959          htmlStr +='onmouseover=\'hoverColor("rgb('+r+','+g+','+b+')");\'></div>';
     960          htmlStr +='</td>';
     961       }//for k
     962   htmlStr +='</tr>';
     963   }//for j
     964   htmlStr += '</tbody></table>';
     965    content = document.createTextNode("loading color picker...");
     966    JmolColorPickerDiv.appendChild(content);
     967    JmolColorPickerDiv.innerHTML = htmlStr;
     968    return(JmolColorPickerDiv);   
     969}
     970
     971// IE6 puts the SELECT control on top of the popup colorpicker DIV, so we trick that:
     972var IEversion = 999;
     973if (/MSIE (\d+\.\d+);/.test(navigator.userAgent)) { //test for MSIE x.x;
     974    IEversion=new Number(RegExp.$1); // capture x.x portion and store as a number
     975}
     976
     977function pickedColor(colorStr){
     978    var pickerDiv = get_element("JmolColorPickerDiv");
     979//    var debug = get_element("JmolDebug");
     980//    var tempStr = debug.innerHTML;
     981//    tempStr+='<br/>The parent of the picker div is on reaching pickedColor is: '+pickerDiv.parentNode.id;
     982    if(colorStr!='cancel'){
     983        var boxNum = JmolColorPickerStatus.passThrough;
     984        get_element(JmolColorPickerBoxes[boxNum].boxID).style.background = colorStr;
     985        var rgbCodes = colorStr.replace(/rgb/i,'').replace('(','[').replace(')',']');
     986        var scriptStr = JmolColorPickerBoxes[boxNum].scriptStr.replace('$COLOR$', rgbCodes);
     987        jmolScript(scriptStr,JmolColorPickerBoxes[boxNum].appletID);
     988        storeDefaultDir(JmolColorPickerBoxes[boxNum].appletID);
     989        jmolUpdateState(JmolColorPickerBoxes[boxNum].appletID);
     990    }
     991//    tempStr += '<br/>The picked color is: '+colorStr+'.<br/>'+pickerDiv.id; 
     992    pickerDiv.setAttribute("class","JmolColorPicker_hid");
     993//    tempStr += ' has class: '+pickerDiv.getAttribute("class")+' after call to pickedColor.'
     994//    debug.innerHTML = tempStr;
     995}
     996function hoverColor(colorStr){
     997    get_element("JmolColorPickerHover").style.background = colorStr;
     998}
     999
     1000function popUpPicker(whereID, funcName, passThrough){
     1001    var pickerDiv = get_element("JmolColorPickerDiv");
     1002    if (!pickerDiv) {//make a new picker
     1003        pickerDiv =  makeColorPicker();
     1004        }
     1005    JmolColorPickerStatus.funcName = funcName;
     1006    JmolColorPickerStatus.passThrough = passThrough;
     1007    var where = get_element(whereID);
     1008    where.appendChild(pickerDiv);
     1009    changeClass(pickerDiv,"JmolColorPicker_vis");
     1010}
     1011
     1012
     1013function JmolColorPickerBoxStr(scriptStr, startColor, boxID, appletID){
     1014    if (!appletID) appletID = "0";
     1015    var boxNum = JmolColorPickerBoxes.length;
     1016    if (!boxID) boxID = 'colorBox'+boxNum;
     1017    if (!startColor) startColor = '[x999999]';
     1018    var presentColor = startColor.replace('\[x','#').replace('\]','');
     1019    var colorBoxId = ''+boxID+'_color';
     1020    JmolColorPickerBoxes[boxNum]= new boxInfo(colorBoxId, appletID, scriptStr);   
     1021    var htmlStr = '<div id='+boxID+'><table style="font-size:0px; cursor:default;" cellspacing="0" cellpadding="0" border="1" onclick=\'popUpPicker(';
     1022    htmlStr += '"'+boxID+'","colorBoxUpdate",'+boxNum+');\' ';
     1023    htmlStr += '><tbody>';
     1024    htmlStr += '<tr><td><div id ="'+colorBoxId+'" style="height: 12px; width: 12px;background-color:'+presentColor+';"></div></td><td>';
     1025    var boxArrowName = 'colorBoxArrow'+boxNum;
     1026    if (dataURIsupported) {
     1027        // up arrowhead:   "data:image/bmp;base64,Qk3mAQAAAAAAADYAAAAoAAAACwAAAAwAAAABABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIAAAAyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIAAAAyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIAAAAyMjIyMjIAAAAAAAAAAAAAAAAAAAAAAAAAAAAyMjIyMjIAAAAyMjIyMjIyMjIAAAAAAAAAAAAAAAAAAAAyMjIyMjIyMjIAAAAyMjIyMjIyMjIyMjIAAAAAAAAAAAAyMjIyMjIyMjIyMjIAAAAyMjIyMjIyMjIyMjIyMjIAAAAyMjIyMjIyMjIyMjIyMjIAAAAyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIAAAAyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIAAAAyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIAAAAyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIAAAAyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIAAAA"
     1028        // down arrowhead: "data:image/bmp;base64,Qk3mAQAAAAAAADYAAAAoAAAACwAAAAwAAAABABgAAAAAALABAAAAAAAAAAAAAAAAAAAAAAAAyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIAAAAyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIAAAAyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIAAAAyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIAAAAyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIAAAAyMjIyMjIyMjIyMjIyMjIAAAAyMjIyMjIyMjIyMjIyMjIAAAAyMjIyMjIyMjIyMjIAAAAAAAAAAAAyMjIyMjIyMjIyMjIAAAAyMjIyMjIyMjIAAAAAAAAAAAAAAAAAAAAyMjIyMjIyMjIAAAAyMjIyMjIAAAAAAAAAAAAAAAAAAAAAAAAAAAAyMjIyMjIAAAAyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIAAAAyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIAAAAyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIAAAA"
     1029        htmlStr += '<image id="'+ boxArrowName+'" src="data:image/bmp;base64,Qk3mAQAAAAAAADYAAAAoAAAACwAAAAwAAAABABgAAAAAALABAAAAAAAAAAAAAAAAAAAAAAAAyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIAAAAyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIAAAAyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIAAAAyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIAAAAyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIAAAAyMjIyMjIyMjIyMjIyMjIAAAAyMjIyMjIyMjIyMjIyMjIAAAAyMjIyMjIyMjIyMjIAAAAAAAAAAAAyMjIyMjIyMjIyMjIAAAAyMjIyMjIyMjIAAAAAAAAAAAAAAAAAAAAyMjIyMjIyMjIAAAAyMjIyMjIAAAAAAAAAAAAAAAAAAAAAAAAAAAAyMjIyMjIAAAAyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIAAAAyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIAAAAyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIAAAA">';
     1030    } else {
     1031        htmlStr += '<span id="'+ boxArrowName+'" style="font-size:10px; padding:0 2px; background-color:#A0A0A0; font-family:Verdana, Arial, Helvetica, sans-serif;">V</span>';
     1032    }
     1033    htmlStr += '</td></tr></tbody></table></div>';
     1034    return(htmlStr);
     1035}
     1036
     1037
     1038function colorBoxUpdate(pickedColor, boxNum){
     1039    get_element(JmolColorPickerBoxes[boxNum].boxID).style.background = pickedColor;
     1040    var pickerDiv = get_element("JmolColorPickerDiv");
     1041    changeClass(pickerDiv, "JmolColorPicker_hid");
     1042    var rgbCodes = pickedColor.replace(/rgb/i,'').replace('(','[').replace(')',']');
     1043    var scriptStr = JmolColorPickerBoxes[boxNum].scriptStr.replace('$COLOR$', rgbCodes);
     1044    jmolScript(scriptStr,JmolColorPickerBoxes[boxNum].appletID);
     1045    storeDefaultDir(JmolColorPickerBoxes[boxNum].appletID);
     1046    jmolUpdateState(JmolColorPickerBoxes[boxNum].appletID);
     1047}
     1048
     1049/* End of Jmol Simple JavaScript Color Picker
     1050*/
  • sagenb/data/sage/js/notebook_lib.js

    diff -r ac9fcbe78299 -r ec65029b2038 sagenb/data/sage/js/notebook_lib.js
    a b  
    23492349
    23502350    // Set the cell to not evaluated.
    23512351    cell_set_not_evaluated(id);
     2352
     2353    // Check if the cell contained a Jmol
     2354    jmol_delete_check();
    23522355}
    23532356
    23542357
     
    30423045    // a running cell.
    30433046    cell_set_running(id);
    30443047
     3048    // Check if a Jmol has been deleted
     3049    jmol_delete_check();
     3050
    30453051    // Finally make the request back to the server to do the actual calculation.
    30463052    cell_input = get_cell(id);
    30473053    if (newcell) {
     
    45344540        // produced that output.
    45354541        cell_set_not_evaluated(id);
    45364542    }
     4543    // Update the jmol handler so that it knows there are no Jmols left
     4544    jmol_delete_all_output();
     4545
    45374546    // Finally tell the server to do the actual delete.  We first
    45384547    // delete from DOM then contact the server for maximum snappiness
    45394548    // of the user interface.