    String.prototype.expandExponential = function(){//v1.0
      return this.replace(/^([+-])?(\d+).?(\d*)[eE]([-+]?\d+)$/, function(x, s, n, f, c){
        var l = +c < 0, i = n.length + +c, x = (l ? n : f).length,
            c = ((c = Math.abs(c)) >= x ? c - x + l : 0),
            z = (new Array(c + 1)).join("0"), r = n + f;
        return s + (l ? r = z + r : r += z).substr(0, i += l ? z.length : 0) + (i < r.length ? "." + r.substr(i) : "");
      });
    };


var regionArray=new Array("USA", "MEX", "CAN", "OCN", "JAP", "EAA", "SEA", "IND", "SOA", "BRA", "LAM", "WEU", "REU", "MNA", "AFR", "RUS");
var longRegionArray=new Array("United States", "Mexico", "Canada", "Oceania", "Japan", "China, rest of East Asia", "Southeast Asia", "India", "South Asia", "Brazil", "Latin America", "Rest of Western Europe", "Central Europe", "Middle East and N. Africa", "Subsaharan Africa", "Russia +"); 


    function getColumnsForView(toGroom, uncertainties, drawTotal, totalUncertainties, numRegions){
      var toReturn=new Array();
      if(uncertainties){
        toReturn[0]=0;
        var i;
        var counter=1;
        for (i in toGroom){
          toReturn[counter++]=3*toGroom[i]+1;
          toReturn[counter++]=3*toGroom[i]+2;
          toReturn[counter++]=3*toGroom[i]+3;
        }
        if(totalUncertainties){
          toReturn[counter++]=3*numRegions+1;
          toReturn[counter++]=3*numRegions+2;
          toReturn[counter++]=3*numRegions+3;
        }
        return toReturn;
      }
      else{
        toReturn=addOne(toGroom);
        toReturn.push(0);
        if(drawTotal)
          toReturn.push(numRegions+1);
        toReturn.sort();
        return toReturn;
      }
    }

    function scaleMatrix(toScale, factor){
      var i;
      var j;
      for(i in toScale){
        for(j in toScale[i])
          toScale[i][j]=toScale[i][j]*factor;
      }
      return toScale;

    }


    function addOne(toAdd){
      var i;
      for (i in toAdd)
        toAdd[i]=toAdd[i]+1;
      return toAdd;
    }

    
    function isNumeric(sText)
    {
       var ValidChars = "0123456789.";
       var IsNumber=true;
       var Char;

 
       for (i = 0; i < sText.length && IsNumber == true; i++) 
          { 
          Char = sText.charAt(i); 
          if (ValidChars.indexOf(Char) == -1) 
             {
             IsNumber = false;
             }
          }
       return IsNumber;
    }




/*    var CustomEvent = function() {
	//name of the event
	this.eventName = arguments[0];
	var mEventName = this.eventName;

	//function to call on event fire
	var eventAction = null;

	//subscribe a function to the event
	this.subscribe = function(fn) {
		eventAction = fn;
	};

	//fire the event
	this.fire = function(sender, eventArgs) {
		this.eventName = eventName2;
		if(eventAction != null) {
			eventAction(sender, eventArgs);
		}
		else {
			alert('There was no function subscribed to the ' + mEventName + ' event!');
		}
	};
    };

*/





    function convertList(formValues, first){//this takes the form elements and returns a numerical array indicating which countries' checkboxes are selected.  for example if USA CAN and AUS are selected, this function returns [0,2,3].  the second argument just tells the function where in the form the first checkboxes are located.
      var countryArray=new Array();
      //countryArray[0]=0;
      var i;
      var counter=0;
      for(i=first; i<((1*formValues.length)-1); i++){//should it be minus one? I think so
        if(formValues[i].checked){
          //alert(i-first);
          countryArray[counter]=(i-first);
          counter++;
        }
      }
      //alert(countryArray);
      return countryArray;
    }

    function calcMax(array, rows, error){//should get sent a matrix of zeros if you wanna find the max in a matrix
      var biggest=0;
      var i;
      var j;
      var curPlusErr;
      var rowIndex;
      for(i in rows){
        rowIndex=rows[i];
        for(j in array[rowIndex]){
          curPlusErr=(1*array[rowIndex][j])+(1*error[rowIndex][j]);
          if(j!=0){
            if(curPlusErr>(1*biggest))
              biggest=""+curPlusErr;//want the whole thing to stay strings so expandExponential() keeps working
          }
        }
      }
      return biggest;
    }


      function selectRich(form){
        form.USA.checked=true;
        form.JAP.checked=true;
        form.EAA.checked=true;
        form.WEU.checked=true;
      }
      function selectPoor(form){
        form.MEX.checked=true;
        form.CAN.checked=true;
        form.OCN.checked=true;
        form.SEA.checked=true;
        form.IND.checked=true;
        form.SOA.checked=true;
        form.BRA.checked=true;
        form.LAM.checked=true;
        form.REU.checked=true;
        form.MNA.checked=true;
        form.AFR.checked=true;
        form.RUS.checked=true;
      }
      function clearFrm(form, first){//takes index of the first thing to be cleared
        var i;
        for(i=first; i<form.length-1; i++)
          form.elements[i].checked=false;
      }



    function roundToFive(bigNum){
      bigNum=(""+bigNum).expandExponential();
      bigNum=(1*bigNum).toPrecision(5);
      bigNum=(""+bigNum).expandExponential();
      return bigNum;
    }


    function populateErrorMatrix(param){
    var alpha;
    var beta;
    var dummy;
    var tempMax;
    var errorMatrix=new Array();
    for(alpha=0; alpha<19; alpha++){
      errorMatrix[alpha]=new Array();
      tempMax=0;
      for(beta=0; beta<65; beta++){
        dummy=Math.floor(Math.random()*param);
        dummy=dummy.toPrecision(5);
        dummy=(""+dummy);
        dummy=dummy.expandExponential();
        dummy *= (beta/60);
        if(dummy > tempMax)
          tempMax=dummy;
        else
          dummy=tempMax;
        errorMatrix[alpha][beta]=(beta/60)*dummy;
      }

    }
    return errorMatrix;
    }


      function copyArray(toCpy){
        var i;
        var toReturn=new Array();
        for(i in toCpy)
          toReturn[i]=toCpy[i];
        return toReturn;
      }
    function custLog(x,base) {
	// Created 1997 by Brian Risk.  http://brianrisk.com
	return (Math.log(x))/(Math.log(base));
    }



    function getColor(i){//there might be too many things on the graph and this could Run Out! throw an exception!
      switch(i){
      case 0:
        return ("76A4FB");
      case 1:
        return ("0000FF");
      case 2:
        return ("FF0000");
      case 3:
        return ("00FF00");
      case 4:
        return ("99FF00");
      case 5:
        return ("660033");
      case 6:
        return ("33CCCC");
      case 7:
        return ("FF0066");
      default:
        return ("80C666");
      }
    }

    function oldSplitString(datStr){
      var toReturn=datStr.split(/\n/);
      for (x in toReturn){
        toReturn[x]=toReturn[x].split("\t");
        for (y in toReturn[x]){
          if(x!=0 && y!=0)
            toReturn[x][y]=toReturn[x][y].expandExponential();
        }
      }
      return toReturn;        
    }

    function splitString(datStr){
      var toReturn=datStr.split(/\n/);
      for (x in toReturn){
        toReturn[x]=toReturn[x].split(",");
        for (y in toReturn[x]){
          if(x!=0 && y!=0)
            toReturn[x][y]=toReturn[x][y].expandExponential();
        }
      }
      return toReturn;        
    }

        function findPos(obj) {
          var curleft = curtop = 0;
          if (obj.offsetParent) {
            do {
              curleft += obj.offsetLeft;
              curtop += obj.offsetTop;
            } while (obj = obj.offsetParent);
            return [curleft,curtop];
          }
        }
