diff --git a/sagenb/data/sage/js/jmol_lib.js b/sagenb/data/sage/js/jmol_lib.js index ce5af5fdf..8b1c76103 100644 --- a/sagenb/data/sage/js/jmol_lib.js +++ b/sagenb/data/sage/js/jmol_lib.js @@ -1,45 +1,1232 @@ +/* +Based on the SAGE jmol_lib.js as of 12/13/09 +Modified by Jonathan Gutow +version 1.1.2 10/15/10 +version 1.1.3 1/22/11 - can use direct calls to jmolApplet when building page now, should + not have to extract any Jmol.js funtions and turn them into strings anymore. Also + code cleanup and changes to accommodate vocabulary changes in the file created by + SAGE. +version 1.1.6 4/2/11 - updates to asynchronous load to avoid memory problems with + worksheets that have lots of applets in them. Added warnings and special code + for particular browser/OS combinations. Problem systems FF/MacOS (intermittent), + Safari/MacOS (memory leak? workaround included), IE8/WinXP (many features just + do nothing, IE9/Win7 not tested yet). + + This version limits the number of Jmol applets that may simultaneously be live + on a page. The default is 4. This may be set by calling setMaxLiveJmol. + + NOTE THIS VERSION IGNORES THE SIZE AS SPECIFIED BY THE SAGE NOTEBOOK CODE. + + This version also allows turning on and off surfaces and meshes. Color of + the surfaces and meshes may also be controlled. Developed with Jmol version 11.9. + Recommend using Jmol version 12.0.35 or greater. +Version 1.1.7 12/29/11 - update to have initial 3-D view be static generated by server. + +REQUIRES: +Jmol.js + path must be specified in the of the page: use jmolInitialize(path), where + "path" = the relative path on the server to this file. + +notebook_lib.js + uses the get_element(Id) function from this library. + the delete_all_output() call must be modified to call jmol_delete_all_output() + the evaluate_cell() call and others that delete cell output must be modified + to call jmol_delete_check() + +main.css + where a +select.jmol { + border: #aaaaaa; + border-style: solid; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px +} + format is defined. If it doesn't exist it will still work, but not be as pretty. +*/ + /*global window */ /*jslint white: true, onevar: true, undef: true, nomen: true, eqeqeq: true, plusplus: true, bitwise: true, regexp: true, strict: true, newcap: true, immed: true */ //"use strict"; var jmol_count = 0; -//var allowedJmolSize = [1, 2048, 300]; -function jmol_applet(size, url) { - var s; - if (typeof(cell_writer) !== "undefined") { - jmolSetDocument(cell_writer); + +var jmolStatus = { + maxLiveAllowed: 4, + numLive: 0, + loadSigned: false, //when set to true will load signed applets. + signed: new Array(), //false for unsigned applets, true for signed applets. + jmolArray: new Array(),//-2 loading failed, -1 deleted, 0 awake, 1 sleeping, 2 loading, 3 waiting to load. + urls: new Array(), + defaultdirectory: new Array(), + widths: new Array(), + heights: new Array(), + controlStrs: new Array(), + captionStrs: new Array(), + pictureStrs: new Array(), + stateScripts: new Array(), + cntrls: new Array(), + attempts: new Array(), } - jmolSetAppletCssClass('jmol_applet'); - jmolApplet(size, "script " + url, jmol_count); - s = ' ' + translations["Get Image"] + ''; - if (typeof(cell_writer) !== "undefined") { - cell_writer.write(s); +//Some default constants +//applet sizes +miniature = 100; +small = 250; +medium = 400; +large = 600; +sleepMessage = "Click to Sleep this 3-D view"; +wakeMessage = "Wake this 3-D view"; +captionStr = ''; //empty no caption +controlStr = ' '; //could put special controls here. Must not be empty for default controls to appear, that is why it is a space. + +function jmol_checkbrowserOS(){ + jmolStatus.os = _jmol.os; + jmolStatus.browser=_jmol.browser; + if (_jmol.os=="mac"){ + if (_jmol.browser=="mozilla"){ + alert("You are using a Firefox/Mozilla browser on MacOS. Many people experience inconsistent behavior of the 3-D viewer or no images using this combination. It is recommended that you use Chrome (or another webkit browser) instead."); + } + if (navigator.userAgent.toLowerCase().indexOf('chrome') > -1){ + jmolStatus.browser="chrome"; + } + } + if (_jmol.os =="win"){ + if (_jmol.browser=="msie"){ + alert("Many of the advanced 3-D viewing functions DO NOT work in Internet Explorer. Until this is fixed please use FireFox or Chrome browsers which do work."); + } } +} - jmol_count += 1; - return s; +function toggling_button(element){//uses the jqueryui to toggle the element onoff. + //necessary because IE doesn't interpret the standard form correctly in a button element. THIS DIDN'T HELP! + $('#'+element).toggle(); +} + +function jmol_pulldown(theform) { + /* + This is called when the user selects a menu item. This just + evaluates the corresponding value, which results in running some + javascript code to do the action. + */ + with(theform) { + eval(options[selectedIndex].value); + } + } + +function jmol_spin (state, n) { + if(state == true){ + result = jmolScriptWait("spin on", n); + }else { + result = jmolScriptWait("spin off", n); + } + jmolUpdateState(n); + } + +function jmol_antialias(state,n) { + if(state == true){ + result = jmolScriptWait("set antialiasdisplay on", n); + }else { + result = jmolScriptWait("set antialiasdisplay off", n); + } + jmolUpdateState(n); + } + + +function jmol_show_element(state,whichsurface, type ,n) { + if(state == true){ + scriptStr = ''+type+' '+whichsurface+' on;'; + result = jmolScriptWait(scriptStr, n); + }else { + scriptStr = ''+type+' '+whichsurface+' off;'; + result = jmolScriptWait(scriptStr, n); + } + jmolUpdateState(n); + } + +function do_jmolScriptWait(scriptStr, n){ + result = jmolScriptWait(scriptStr,n); + jmolUpdateState(n); + } + +function jmolSurfColor(color,surface,n){ + scriptStr = 'color $'+surface+' '+color; + result = jmolScriptWait(scriptStr,n); + jmolUpdateState(n); + } + +function jmolFileDownload(n){//switches to the signed applet before downloading the fill if necessary + if (jmolStatus.signed[n]){ + jmolScript('write "JmolFromSage.jmol";',n);//TODO make unique + }else{ + switchToSigned('write "JmolFromSage.jmol";', n) + } + } + +function jmolCntrlPanel(state, panelID, tabID, tabName, panelHTML){ //The default definition for a jmolcontrolpanel + this.state = state; //0 active, 1 inactive, 2 hidden ...other numbers for future possibilities + this.panelID = panelID; + this.tabID = tabID; + this.tabName=tabName; + this.panelHTML=panelHTML; + } + +function jmolUpdateState(n){ + //make sure the default directory is correct +// jmolScript('x=defaultdirectory;data "directory @x";');<--this is done on launch of the applet. + jmolStatus.defaultdirectory[n] = jmolEvaluate("x",n); + var divID = 'jmolStateDiv'+n; + var stateStr ="#a comment to guarrantee one line\n"; + stateStr+= jmolGetPropertyAsString("stateInfo", "", n); + re_modelinline = /data "model list"(.|\n|\r)*end "model list"/; + if(stateStr.match(re_modelinline)){//If we didn't get a good response we'll ignore and get later + var modelStr = (stateStr.match(re_modelinline))[0]; + modelStr = modelStr.replace(/\r\n/g,'|').replace(/\r/g, '|').replace(/\n/g,'|').replace(/\|\|/g, '|'); +// modelStr = 'fix between here '+modelStr+' and here'; + stateStr = stateStr.replace(re_modelinline, modelStr); + } + re_endofline = /\n/g; + re_doublequote = /"/g; + get_element(divID).innerHTML = '
set defaultdirectory=\"'+ jmolStatus.defaultdirectory[n] +'\";
'+stateStr.replace(re_endofline,'
')+'
'; + jmolStatus.stateScripts[n] = 'set defaultdirectory=\"'+ jmolStatus.defaultdirectory[n] +'\";\n'+stateStr; + jmolStatus.defaultdirectory[n]="done";//update finished. + } + +var jmolLastDefaultDir = ''; + +function jmolMessageHandler(applet, messageStr, number) { + re_defaultdirectory =/defaultdirectory/i; + re_jmolApplet = /jmolApplet/i; + var javaScriptStr = ''+messageStr; + var appletname = ""+applet; + var messagenum = ""+number; + var appletN = appletname.substring(10); +// if (javaScriptStr.search(re_defaultdirectory)!=-1){ +// jmolLastDefaultDir = javaScriptStr; +// jmolStatus.defaultdirectory[appletN]= javaScriptStr; +// } + if (jmolStatus.jmolArray[appletN]==2) {//finishing load process + setTimeout('jmolUpdateState('+appletN+')',300); + } + } + +function jmolAppletReady_jmolUpdateState(n){ + jmolUpdateState(n); +// setTimeout('jmolAppletLive('+n+')',300); + } + +function jmol_numLiveUpdate(){ + var liveCount = 0; + for (i=0;i < jmolStatus.jmolArray.length; i++){ //reset the number of live Jmols + if (jmolStatus.jmolArray[i]==0) {liveCount = liveCount+1;} + } + jmolStatus.numLive = liveCount; + } + +function jmolCntrlPanels(whichActive,cntrlPanels){ //The default definition for a group of jmolCntrlPanels + this.whichActive = whichActive; //array index for the active, front, panel + this.cntrlPanels= cntrlPanels; //array of jmolCntrlPanel + } + +function jmolNewAppletSize(size,n){ + //update jmolStatus + jmolStatus.widths[n]=size; + jmolStatus.heights[n]=size; + jmolResizeApplet(size,n); + } + +function makeCntrlPanels(url, n, functionnames){ + var panels = new Array(); + //Applet options: size, background color, spinning etc... + panelID = 'size_jmol'+n; + tabID = 'tab_'+panelID; + //size control + if(_jmol.os=="mac" && _jmol.browser=="mozilla"){ + panelHTML =''; + }else{ + panelHTML ='3-D display size: Spin on'; + //antialaisdisplay (smoothing of objects) + panelHTML +='
High quality'; + //background color + panelHTML += ''; + panels[0] = new jmolCntrlPanel(0, panelID, tabID, "Display",panelHTML); + //Function Display Options + panelID = 'disp_jmol'+n; + tabID = 'tab_'+panelID; + if(functionnames ==''||functionnames==undefined){//no names for the functions so cannot build list, will have to get after Jmol launched + panelHTML = '

Click to request functions from Jmol so that you can adjust function color and mesh.

'; + }else{//step through functionnames and make list of functions. + panelHTML =''; + var funcs=functionnames.split(','); + for(i in funcs){ + } + str+='
Function NameOnColorTranslucentMeshMesh Color
'; + } + panels[1] = new jmolCntrlPanel(1, panelID, tabID, "Color & Mesh",panelHTML); + //Axes to be done + //State will be hidden long term + panelID = 'jmolStateDiv'+n; + tabID = 'tab_'+panelID; + panelHTML ='# Blank script'; + panels[2] = new jmolCntrlPanel(2, panelID, tabID,"State", panelHTML); + return (new jmolCntrlPanels(0, panels)); //this will then be plugged into jmolStatus.cntrls[n] + } + +function setMaxLiveJmol(maxLive) { //sets maximum applets live at once. + jmolStatus.maxLiveAllowed = maxLive; + } + +function jmol_launch(size, url, cell_num, functionnames){//hides static image before calling jmol_applet() + var cellID = 'jmol_static'+cell_num; + get_element(cellID).setAttribute("style","display: none;");//keep for reference in jmol_applet()...see below + jmol_applet(size, url, cell_num, functionnames); +} + +function jmol_applet(size, url, cell_num, functionnames) { //makes a new applet. Presently ignoring size, kept for backwards compatibility + var appletID = jmol_count; + if (jmol_count==0){//time to start the jmolQueueWatcher to manage multiple Jmol launches. + jmolQueue = setInterval('jmolQueueWatcher();',1500); + } + jmol_count = jmol_count + 1; + jmolStatus.jmolArray[appletID] = 3; //queued to load. + size = medium; //overriding value from server. Probably should accept server value. + jmolSetDocument(false); + //Where am I? Need to know in cases where I need to write directly to this cell. + cell_ID = 'cell_output_html_'+cell_num; + //however, I might be inside something else like an interact as well...so + parent = get_element('jmol_static'+cell_num).parentNode; + cntrlPanels = makeCntrlPanels(url, appletID, functionnames); + controlStr = makeControlStr(url, appletID, cntrlPanels); + parentStr = parent.innerHTML; + str = parentStr + newJmolTableStr(appletID, size, size, url, wakeMessage, sleepMessage, captionStr, controlStr); + //add debugging div + //str += '
Jmol Debugging goes here
'; + //now we can start the new one + //cell_writer.write(str); + parent.innerHTML = str; + jmolSetAppletColor("white"); + if (appletID==0){ + jmol_checkbrowserOS(); + } + //we will still set all the data for this applet so that other asynchronously created applets do not grab its ID. + jmolStatus.signed[appletID]=jmolStatus.loadSigned; + jmolStatus.urls[appletID]=url; + jmolStatus.widths[appletID] = size; + jmolStatus.heights[appletID]= size; + // jmolStatus.numLive = jmolStatus.numLive+1; + jmolStatus.controlStrs[appletID] = controlStr; + jmolStatus.captionStrs[appletID] = captionStr; + jmolStatus.cntrls[appletID]=cntrlPanels; +//Now we wait for the server by calling a function that waits if the div is not yet written. +// launchNewJmol(size,scriptStr,appletID); + return str; + } + +function jmolQueueWatcher(){ + //this function should be started on a 1500 ms interval as soon as the first Jmol applet is called for. + //This controls launch of applet timing and order when multiple Jmols are trying to launch. Necessary + //for the asynchronous launching caused by openning an old worksheet with lots of Jmols. + //Check for Jmols in the launching state (should be one or none) + jmol_numLiveUpdate(); + numAppletsAtStart =jmolStatus.jmolArray.length;//may change during checks...ignore new additions + loading = -1; + for (n=0;n=0){//we found a loading applet + jmolStatus.attempts[loading]+=1; //update number of checks for load completion. + if(jmolStatus.defaultdirectory[loading]=="done"){//Applet is ready. + jmolAppletLive(loading); + }else{ //Applet not ready. How many checks have we done? + if(jmolStatus.attempts[loading]==10){ + alert("Jmol Applet #"+loading+" is having trouble loading. Will retry once."); + var scriptStr = 'x=defaultdirectory; data "directory @x";'; + scriptStr += 'set MessageCallback "jmolMessageHandler"; show defaultdirectory;'; + jmolScript(scriptStr); + } + if(jmolStatus.attempts[loading]==20){ + alert("Second attempt to finish launch of Jmol Applet #"+loading+" failed. Recommend reevaluating the cell manually."); + jmolStatus.jmolArray[loading]=-2; //launch failed. + } + } + }else{//no loading applets. Search for queued applet. + queued = -1; + for (n=0;n=0){//we found a queued applet and can start its launch. + //alert("About to launch applet #"+queued); + var defaultdir = (jmolStatus.urls[queued]).substring(0,((jmolStatus.urls[queued]).lastIndexOf("?"))); + var scriptStr = 'set defaultdirectory "'+defaultdir+'";script "'+jmolStatus.urls[queued]+'"; isosurface fullylit; pmesh o* fullylit;'; + scriptStr +='set antialiasdisplay on; set repaintWaitMs 1500;'; + scriptStr +='x=defaultdirectory; data "directory @x";'; + scriptStr += 'set MessageCallback "jmolMessageHandler"; show defaultdirectory;'; + //alert("About to look for the div to put it in"); + if (get_element("Jmol"+ queued) ){//the div is ready + //sleep some if necessary + //alert("Found div. About to enter LimitLive."); + limitlive(queued, jmolStatus); + //alert("left LimitLive"); + jmolStatus.attempts[queued]=0; //no checks on load completion yet. + jmolStatus.jmolArray[queued]=2; //now it is loading + get_element("Jmol"+ queued).innerHTML = jmolApplet([jmolStatus.widths[queued], jmolStatus.heights[queued]], scriptStr, queued); + } + } + } + } + +function jmolAppletLive(n){//called after an applet is loaded to say set state to live + jmolStatus.jmolArray[n]=0; + jmol_numLiveUpdate(); + } + +function newJmolTableStr(n, width, height, url, wakeMessage, sleepMessage, captionStr, controlStr){ + //if captionStr or controlStr is the empty string, '', then the caption or the controls respectively will not be shown. + Id = 'Jmol'+n; + tableId = 'Jmol_Table_'+Id; + tableStr = ''; + if (controlStr!=''){ + var tempCntrlStr=''; + if(_jmol.browser=="msie"){ +// tempCntrlStr +=''+sleepMessage+'
'; + tempCntrlStr += controlStr; + }else{ +// tempCntrlStr +=''; + tempCntrlStr += controlStr; + } + if (_jmol.browser=="msie"){ + tableStr += ''; + }else{ + tableStr += ''; + } + } + tableStr += ''; + if (captionStr !=''){ + tableStr +=''; + } + tableStr += '
'; + if (controlStr!='') { + if(_jmol.browser=="msie"){//nothing until figure out how to get working... + //tableStr+=''; + tableStr +=''; + }else{ + tableStr+='
'; + tableStr +='
'; + } + } + tableStr +='
'; + tableStr += 'Loading Jmol 3-D viewer...
'; + tableStr+='
'+tempCntrlStr+'
'+captionStr+'
'; + return (tableStr); + } + +function makeControlStr(url, n, cntrlPanels){ + //This function makes the string that contains the controls other than the default wake and sleep links. + //These are extracted from the cntrlPanels structure passed from the calling routine + cntrlID= 'cntrl_jmol'+n; + str = '
'; + //make tab + str+= '
    '; + for (i in cntrlPanels.cntrlPanels){ + if(cntrlPanels.cntrlPanels[i].state==0){ + classStr = "ui-tabs-selected ui-widget-content"; + }else{ + classStr ="ui-state-default"; + } + if(cntrlPanels.cntrlPanels[i].state==2){ + classStr = "hidden"; + } + str+='
  • '; + whichWake = cntrlPanels.cntrlPanels[i].isActive; + tabName = cntrlPanels.cntrlPanels[i].tabName; + str+=''+tabName+'
  • '; + } + str += '
'; + //make panels + for (i in cntrlPanels.cntrlPanels){ + panelID = cntrlPanels.cntrlPanels[i].panelID; + if(cntrlPanels.cntrlPanels[i].state==0){ + classStr = "ui-tabs-panel"; + }else{ + classStr ="ui-tabs-panel ui-tabs-hide"; + } + str+='
'; + str+= cntrlPanels.cntrlPanels[i].panelHTML; + str+= '
'; + } + str+='
'; + return str; + } + +function getSurfacesFromJmol(n){ + var surfaceListStr = jmolGetPropertyAsString("stateInfo", "modelState", n); + var scriptArray=parseJmolStateInfoForSurfaces(surfaceListStr); + var surfaceArray = makeJmolSurfaceArray2(scriptArray); + var tdstr =''; + var dispStr=''; + if (scriptArray[0]==''||scriptArray[0]==null||scriptArray[0]=='null'||scriptArray[0]==undefined||scriptArray[0]=='undefined') {//no surfaces ?! + dispStr = 'No surfaces recovered from Jmol. Sorry.'; + } + dispStr +=''+tdstr+'Function'+tdstr+'Color'+tdstr+'On?'+tdstr+'Opacity'+tdstr+'Mesh Color'+tdstr+'Mesh on?'; + for (i in surfaceArray){ + dispStr +=''; + dispStr +=''+tdstr+''+surfaceArray[i].ID+''; + var scriptStr = 'color $'+surfaceArray[i].ID+' $COLOR$'; + var boxIdStr = 'colorBox_'+n+'_'+i; + dispStr +=''+tdstr+''+JmolColorPickerBoxStr(scriptStr,surfaceArray[i].color,boxIdStr,n)+''; + var checkedStr = 'checked = "true"'; + re_off = /off/i; + if (surfaceArray[i].visibility.match(re_off)){ + checkedStr = ''; + } + dispStr +=''+tdstr+''; + dispStr +=''+tdstr+''; + dispStr +=''; + } + dispStr +='
'; + displayID = 'disp_jmol'+n; + get_element(displayID).innerHTML= dispStr; + } + +function parseJmolStateInfoForSurfaces(stateInfoStr){ + //Returns an array of strings containing the script commands for creating and loading surfaces, pmesh or isosurface. + var tempStrArray=stateInfoStr.split(';'); + scriptArray = new Array(); + re_isosurface = /\s*isosurface/; + re_pmesh =/\s*pmesh/; + linecount = 0; + for (i in tempStrArray){ + if(tempStrArray[i].match(re_isosurface)||tempStrArray[i].match(re_pmesh)){ + scriptArray[linecount]=tempStrArray[i]; //Safari doesn't like .append()? + linecount=linecount+1; + } + } + return scriptArray; + } + +function makeJmolSurfaceArray2(scriptArray){ + //generates an array of surfaceState objects. One for each surface. + var surfaceArray = new Array(); + var surface_count = 0; + var lastID = ''; + var lastSurface = -1; + var lastIsMesh = false; + for (i in scriptArray){ + properties = parseScriptLine(scriptArray[i],lastIsMesh); + k = 0; + which = -1; + while (k < surface_count){//if we get a match we're looking at a second load, so just update info. + if((properties.ID == surfaceArray[k].ID && surfaceArray[k].ID!='')||(properties.mesh_ID==surfaceArray[k].mesh_ID && surfaceArray[k].mesh_ID!='') + ||(properties.source == surfaceArray[k].source && surfaceArray[k].source!='')){ + which = k; + k=surface_count; // found a match we're done + } else { + k=k+1; + } //end if + }//end while k=0) {//this is just update to previous line... + which = lastSurface; + }//end update to previous line + if (which == -1) {//new surface + surfaceArray[surface_count] = new surfaceState(properties.type, properties.ID, properties.source, properties.sourceType, + properties.color, properties.fillState, properties.visibility, properties.mesh_ID, properties.meshColor, + properties.meshState, properties.mesh_visibility); + lastSurface = surface_count; + surface_count = surface_count + 1; + } else {//existing surface update only things that are not empty strings and don't corrupt existing labels. + if (properties.type!=''){ + surfaceArray[which].type = properties.type; + } + if (properties.sourceType!=''&& surfaceArray[which].sourceType==''){ + surfaceArray[which].sourceType = properties.sourceType; + } + if (properties.ID!='' && surfaceArray[which].ID==''){ + surfaceArray[which] = properties.ID; + } + if (properties.source!='' && surfaceArray[which].source==''){ + surfaceArray[which].source = properties.source; + } + if (properties.color!='') { + surfaceArray[which].color = properties.color; + } + if (properties.fillState!=''){ + surfaceArray[which].fillState = properties.fillState; + } + if (properties.visibility!='') { + surfaceArray[which].visibility = properties.visibility; + } + if (properties.mesh_ID!='' && surfaceArray[which].mesh_ID=='') { + surfaceArray[which].mesh_ID = properties.mesh_ID; + } + if (properties.meshColor!='') { + surfaceArray[which].meshColor = properties.meshColor; + } + if (properties.mesh_visibility!='') { + surfaceArray[which].mesh_visibility = properties.mesh_visibility; + } + if (properties.meshState!='') { + surfaceArray[which].meshState = properties.meshState; + } + lastSurface = which; + }//end new or old surface + if (properties.ID=='' && properties.mesh_ID!='') { + lastIsMesh=true; + }else{ + lastIsMesh=false; + } + }//end stepping through scriptArray + return (surfaceArray); + } + +function parseScriptLine(scriptLine, lastIsMesh){ + var properties = { + type: '', + source: '', + sourceType: '', + ID: '', + color: '', + fillState: '', + visibility: '', + mesh_ID: '', + meshColor: '', + meshState: '', + mesh_visibility: '', + } + re_wordboundary = /\s+/; + var wordList = scriptLine.split(re_wordboundary); + firstIndex = 0; + if (wordList[0]=='') { + firstIndex = 1; + } + if (wordList[firstIndex] == 'isosurface') { + properties.type = 'isosurface'; + properties = parseIsosurfaceCmd(properties, wordList); + } + if (wordList[firstIndex] == 'pmesh') { + properties.type = 'pmesh'; + properties = parsePmeshCmd(properties, wordList); + } + if (wordList[firstIndex] == 'color') { + properties = parseColorCmd(properties, wordList); + } + if (lastIsMesh == true) {//check that the mesh values and non-mesh are not flipped + if(properties.color!=''&&properties.meshColor==''){ + properties.meshColor=properties.color; + properties.color=''; + } + if(properties.visibility!=''&&properties.mesh_visibility==''){ + properties.mesh_visibility =properties.visibility; + properties.visibility =''; + } + if(properties.fillState!=''&&properties.meshState==''){ + properties.meshState =properties.fillState; + properties.fillState =''; + } + } + return (properties); + } + +function parseColorCmd(properties, wordList){ + re_dollarsign = /^$/; + re_colorcode=/\[x.{6}\]/; + re_translucent =/translucent/i; + firstIndex = 0; + if (wordList[0]=='') { + firstIndex = 1; + } + parseFrom = firstIndex+2; + if(wordList[firstIndex+1].match(re_dollarsign)) { + properties.ID = wordList[firstIndex+1].replace('$','').toLowerCase(); + } + for (i=parseFrom; i