// ***************** COPYRIGHT (c) 2007 STEFAN WANER ******************// *********************** ALL RIGHTS RESERVED ************************// ***  IT ALSO REMAINS TO DO THE TOPMATTER// Globals// window.onerror = myErrorTrap;var e = 2.718281828459045;var pi = 3.141592653589793;var epsilon = .000000000001;var canvas, ctx; // for excanvasvar cs = Math.cos(.3); var sn = Math.sin(.3); // angles of arrows = .3 radiansvar canvasWidth = 400;var canvasHeight = 400;var numPoints = 40; // number of points for Runge-Kuttavar smoothFactor = 1; // smoothing facctor for beziervar theColor = 0; // the color of a pixelvar numColors = 7;var lineColor = new Array();	lineColor[0] = 	"red";	lineColor[1] = 	"blue";	lineColor[2] = 	"purple";	lineColor[3] = 	"green";	lineColor[4] = 	"magenta";	lineColor[5] = 	"grey";	lineColor[6] = 	"orange";	lineColor[7] = 	"yellow";var theDigit = new Array();var counter = 0; // for debugging	theDigit[0] = new Image();	theDigit[0].src = "digits/0.gif"	theDigit[1] = new Image();	theDigit[1].src = "digits/1.gif"; 	theDigit[2] = new Image();	theDigit[2].src = "digits/2.gif"; 	theDigit[3] = new Image();	theDigit[3].src = "digits/3.gif";	theDigit[4] = new Image();	theDigit[4].src = "digits/4.gif";	theDigit[5] = new Image();	theDigit[5].src = "digits/5.gif";	theDigit[6] = new Image();	theDigit[6].src = "digits/6.gif";	theDigit[7] = new Image();	theDigit[7].src = "digits/7.gif";	theDigit[8] = new Image();	theDigit[8].src = "digits/8.gif"; 	theDigit[9] = new Image();	theDigit[9].src = "digits/9.gif"; 	theDigit[10] = new Image();	theDigit[10].src = "digits/point.gif";	theDigit[11] = new Image();	theDigit[11].src = "digits/plus.gif";	theDigit[12] = new Image();	theDigit[12].src = "digits/minus.gif";	theDigit[13] = new Image();	theDigit[13].src = "digits/infinity.gif";	theDigit[14] = new Image();	theDigit[14].src = "digits/e.gif";var digitWidth = [9, 6, 9, 8, 9, 8, 8, 9, 8, 8, 3, 9, 9, 12, 8];var tMin = 0;var tMax = 0;var X = 0;var x = 0;var y = 0;var x1 = 0;var x2 = 0;var y1 = 0;var y2 = 0;var h = 0;var xh = 0;var hx = 0;var t = 0;var th = 0;var ht = 0;var a = 0;var b = 0; // end points of graphvar c = 0;var d = 0;var A = 0;var p1 = 0;var numDivisions = 250; // for each curvevar quoteMark = unescape( '%22' );var singlequoteMark = unescape( '%27' );var numX = canvasWidth; // picure width in pixels -- old canvasvar numY = canvasHeight;; // picture heightvar infinity = 10000000000000  // 10^13;var windowcropTally = 20; 	// will not cut a window in half if more than this number of      // pixels pop out of range as a resultvar theCanvas = new makeArray2(numX,numY);var autoY = true;var autoX = true;var autoGridline = true;var theCombinedResult = new Array(); // an array containing all the solutionsvar okToRoll = true;var solvingSystem = true; // means you are solving a syswtemvar theXPrimeFun = ''; // the right-hand sides of the system DEsvar theYPrimeFun = '';var theString = "";var theFunction = ""; // the functionvar xGridLines = new Array(); // these are screen coordinatesvar yGridLines = new Array();var xGridLinesActual = new Array(); // these are actual coordinatesvar yGridLinesActual = new Array();// var lineColor = 2; // red// var lineColorLite = lineColor + 7;var xAxisPosition = 50; // position of axes = -1 if not visiblevar yAxisPosition = 100;var xGridStep = 10;var yGridStep = 10;var sigDigNumx = 2;  // for rounding of tick marksvar sigDigNumy = 2;var xVals = new Array(); // to store the values of x for evaluatingvar yVals = new Array();  // to store the functionsvar tminVals = new Array(); var tmaxVals = new Array();var x0Vals = new Array(); // initial conditions arraysvar y0Vals = new Array();var t0Vals = new Array();var numCurves = 0; // number of solution curvesvar xArraysize = 0; // number of x-values in evalautorvar maxNum = 6;  // max number of initial conditions allowedvar maxnumX = 12; // max number of x-values allowedvar theValues = new makeArray2(maxnumX, maxNum); // copy of evalauator datavar fracMode = false; // fraction mode off defaultvar numSigDigs = 5;  // rounding of y-values defaultvar maxDenom = 99999;// *** end globals// *** Error Handler ******function myErrorTrap(message,url,linenumber) {alert("It looks like you have entered something wrongly (or perhaps need to use an older version). Press 'Show Examples' to see examples of how to format functions.");return (true);} // end of on error// ********************// **********Utilities to read in data *********// ********************************************************************function setUp(){	canvas = document.getElementById("cv");	ctx = canvas.getContext("2d");	okToRoll = true;	with(Math){		// read in tmin and tmax:		for (var k = 1; k <= 1; k++)	{	var aa = document.theFormA.tmin.value; // alert(aa);	if (aa == "") { alert("You have not entered a number for tMin."); okToRoll = false; break;}//alert(aa);	tMin = myEval(aa);	if (isNaN(tMin) ) { alert("You have not entered a number for tMin."); okToRoll = false; break;}	var bb = document.theFormA.tmax.value; 	if (bb == "") { alert("You have not entered a number for tMax."); okToRoll = false; break}	tMax = myEval(bb); 	if (isNaN(tMax) ) { alert("You have not entered a number for tMax."); okToRoll = false; break;}	if ( (okToRoll) && (tMin >= tMax)) { alert("tMax should be larger than tMin"); okToRoll = false; break;}	} // k		//Step 1: read the inputs into an array and decide		// how many points there are		var thexCellName = ""; // these are strings to names x1, x2,.. 		var theInstruction = ""; // a javascript instuction		var doIt = 0; // a dummy variable						//Step 2: read the values into the initial conditions array 		for (var i = 1; i <= maxNum; i++) {			theInstruction = "x0Vals["+i+"] = stripSpaces(document.theInitConds.x"+i+".value);"			theInstruction += "y0Vals["+i+"] = stripSpaces(document.theInitConds.y"+i+".value);"			doIt = eval(theInstruction);			} // i		// Step 3: Compute how many initial conditions there are		for (i = 1; i <= maxNum; i++) {			if (x0Vals[i] == "") {				numCurves = i-1;				i = maxNum}		else if (i == maxNum) {numCurves = maxNum}			} // i		if (numCurves == 0) {alert("You must enter at least one initial condition"); okToRoll = false}	} //with math} // setup// ***********************************************************************// ************** End of Reading-in Data Utility ******// ***********************************************************************// **************** Plot All Curves ********************function plotAllCurves(){// alert(a + " , " + b + " , " + c + " , " + d);if (okToRoll) {for (var i = 1; i <= numCurves; i++) {// alert(x0Vals[i] + "," + y0Vals[i] + tMin + tMax);	var theResult = theCombinedResult[i];// now compute window bounds if auto// now the data for bezier curve	var theVectorx = new Array(),theVectory = new Array();	for (var k = 1; k <= numPoints-1; k++ ) {		theVectorx[k] = .5*(theResult[2][k+1] - theResult[2][k-1]);		theVectory[k] = .5*(theResult[3][k+1] - theResult[3][k-1]);				} // k	// now end vectors	theVectorx[0] = 2*theVectorx[1]- theVectorx[2];	theVectory[0] = 2*theVectory[1]- theVectory[2];	theVectorx[numPoints] = 2*theVectorx[numPoints-1]- theVectorx[numPoints-2];	theVectory[numPoints] = 2*theVectory[numPoints-1]- theVectory[numPoints-2];// scale the vectors: 	for (var k = 0; k <= numPoints; k++ ) 		{theVectorx[k] *= smoothFactor; theVectory[k] *= smoothFactor }// displayResults(theResult);//Now draw the curve	var xc = 0; yc = 0; // current	var xp = 0; yp = 0; // previous	theResult[2][ numPoints +1] = 2*theResult[2][ numPoints] - theResult[2][ numPoints -1]; // extending a bit	theResult[3][ numPoints +1] = 2*theResult[3][ numPoints] - theResult[3][ numPoints -1];	for (var j = 1; j <= numPoints; j++) {// alert(myParse(theXPrimeFun));// alert(myParse(theYPrimeFun));// alert(theResult[2][j]);// alert(theResult[1][j-1] + "," + theResult[2][j-1] + " to " + theResult[1][j] + "," +  theResult[2][j]);		xp = theResult[2][j-1];		yp = theResult[3][j-1];		xc = theResult[2][j];		yc = theResult[3][j];				 var p= bezier(xp, yp, xc, yc, theVectorx[j-1], theVectory[j-1], theVectorx[j], theVectory[j], lineColor[i-1]);// now arrowheads		if ((j == 1) || (j == numPoints-1)) {			var theModSq = Math.sqrt(theVectorx[j]*theVectorx[j] + theVectory[j]*theVectory[j]);			var theFactor = 9*(b-a)/canvasWidth;			var xvold = -theVectorx[j]*theFactor/theModSq;			var yvold = -theVectory[j]*theFactor/theModSq;			var xv = xvold *cs + yvold *sn;			var yv = -xvold *sn + yvold *cs;			segment(xc, yc, xc+xv,yc+yv, lineColor[i-1]);			xv = xvold *cs - yvold *sn;			yv = xvold *sn + yvold *cs;			segment(xc, yc, xc+xv,yc+yv, lineColor[i-1]);		} /// if we need an arrowhead		// var q= bezier(xp, yp, xc, yc, 0,0,0,0, lineColor[i-1]);		// var q= segment(xp, yp, xc, yc, lineColor[i-1]);		// var p = segment(theResult[2][j-1], theResult[3][j-1], theResult[2][j], theResult[3][j], lineColor[i-1]);		} // j	} // i// Now write the xMin, xMax info on the pagevar xMinValue = document.getElementById('xMin'); xMinValue.innerHTML = '<b>xMin&nbsp;=&nbsp;'+roundSigDig(a, sigDigNumx) + '</b>';var xMaxValue = document.getElementById('xMax'); xMaxValue.innerHTML = '<b>xMax&nbsp;=&nbsp;'+ roundSigDig(b, sigDigNumx) + '</b>';var yMinValue = document.getElementById('yMin'); yMinValue.innerHTML = '<b>yMin = '+ roundSigDig(c, sigDigNumy) + '</b>';var yMaxValue = document.getElementById('yMax'); yMaxValue.innerHTML = '<b>yMax = '+ roundSigDig(d , sigDigNumy) + '</b>';// now put up the datadisplayResults();	} // if OkToRoll} // end of plot// ******************End of Plot All Curves ***********// ******************Draw Gridlines and Axes ***********function drawDecorations() {ctx.clearRect(0,0,canvasWidth, canvasHeight);// First determine the vertical position of the x-tick marks// and horiz position of y-tick marksvar xMarksPosition = canvasHeight-15;if (xAxisPosition != -1) xMarksPosition = xAxisPosition + 8;if (xMarksPosition > canvasHeight - 5) xMarksPosition -= 23;var yMarksPosition = 5;// *** First the x-tick marks ***// first figure out how many significant digits to displaysigDigNumx = 2;// minimumvar mustIncrease = true;for (var i = sigDigNumx; i <= 12; i++) { 	sigDigNumx = i;	if(!mustIncrease) break;	else {		for (var j = 1; j <= xGridLines[0]-1; j++) {			if ((roundSigDig(xGridLinesActual[j],i) == roundSigDig(xGridLinesActual[j+1],i)) && (xGridLinesActual[j] != xGridLinesActual[j+1])) break;			mustIncrease = false;			} // j		} // if mustIncrease	} // i// need max length of the lables first -- roughly 8.5 pts/charvar maxLength = 0;for (var i = 1; i <= xGridLines[0]; i++) {	var theStr = (roundSigDig(xGridLinesActual[i], sigDigNumx)).toString();	var theLen = theStr.length*8.5;	if(theLen > maxLength) maxLength = theLen;	}// i// alert(theLen);var thexMultiple = 6666;if (xGridStep > 0) thexMultiple  = Math.round((b-a)*theLen*1.5/(canvasWidth *xGridStep) + .5);// alert(thexMultiple);if (thexMultiple < 6666) {	// now actually put in the tick marks		var theCharPosn = 0; 		var deltaCharPos =0;		var skipThis = false;	for (var i = 1; i <= xGridLines[0]; i+= thexMultiple) {		skipThis = false;// alert("i = " + i + " tha actual coord of the gridline is " + xGridLinesActual[i] + " and the screen coord is " + xGridLines[i]);		if ((xGridLines[i] <= 0) || (xGridLines[i] >= canvasWidth)) skipThis = true;		if (!skipThis) {			var theStr = (roundSigDig(xGridLinesActual[i], sigDigNumx)).toString();			var theLen2 = theStr.length;			var theDig = '';			var theCmd = '';			theCharPosn = Math.round(-theLen2*3.5);			if(xGridLines[i] + theCharPosn < 0) theCharPosn = 3;			else if (xGridLines[i] + theCharPosn + maxLength > canvasWidth) theCharPosn = Math.round(-theLen2*8);			deltaCharPos =0;			for (var j = 0; j < theLen2; j++) {				theCmd = 'ctx.drawImage(theDigit[';				theDig = theStr.charAt(j);				if (isNumberChar(theDig)) {theCmd += theDig; deltaCharPos = 9}				else if (theDig == ".") {theCmd += "10"; deltaCharPos = 3}				else if (theDig == "e") {theCmd += "14"; deltaCharPos = 8}				else if (theDig == "-") {theCmd += "12"; deltaCharPos = 9}				else if (theDig == "+") {theCmd += "11"; deltaCharPos = 9}				else {theCmd += "13"; deltaCharPos = 8}; // should not happen							theCmd += "]," + (xGridLines[i] + theCharPosn) + "," + xMarksPosition + ")";				eval(theCmd);				theCharPosn += deltaCharPos;				} // j			} // if not skipThis		} // i	} // if thexMultiple < 6666// *** End of the x-tick marks ***// *** Now the y-tick marks ***// first figure out how many significant digits to displaysigDigNumy = 2;// minimumvar mustIncrease = true;for (var i = sigDigNumy; i <= 12; i++) { 	sigDigNumy = i;	if(!mustIncrease) break;	else {		for (var j = 1; j <= yGridLines[0]-1; j++) {			if ((roundSigDig(yGridLinesActual[j],i) == roundSigDig(yGridLinesActual[j+1],i)) && (yGridLinesActual[j] != yGridLinesActual[j+1])) break;			mustIncrease = false;			} // j		} // if mustIncrease	} // ivar theHeight = 20; // rough height of a digitvar theyMultiple = 6666;if (yGridStep > 0) theyMultiple  = Math.round((d-c)*theHeight*1.5/(canvasWidth *yGridStep) + .5);// alert(theyMultiple);if (theyMultiple < 6666) {	// now actually put in the tick marks		var theCharPosn = 0; 		var deltaCharPos =0;		var skipThis = false;	for (var i = 1; i <= yGridLines[0]; i+= theyMultiple) {		skipThis = false;// alert("i = " + i + " tha actual coord of the gridline is " + yGridLinesActual[i] + " and the screen coord is " + yGridLines[i]);		if ((yGridLines[i] <= 0) || (yGridLines[i] >= canvasHeight)) skipThis = true;		if (!skipThis) {			var theStr = (roundSigDig(yGridLinesActual[i], sigDigNumy)).toString();			var theLen = theStr.length;			var theDig = '';			var theCmd = '';			theCharPosn = 5;			if (yAxisPosition != -1) {				if (yAxisPosition <= canvasWidth/2) yMarksPosition = yAxisPosition +5;				else yMarksPosition = yAxisPosition - 10- theLen*8.5				}			deltaCharPos =0;			for (var j = 0; j < theLen; j++) {				theCmd = 'ctx.drawImage(theDigit[';				theDig = theStr.charAt(j);				if (isNumberChar(theDig)) {theCmd += theDig; deltaCharPos = 9}				else if (theDig == ".") {theCmd += "10"; deltaCharPos = 3}				else if (theDig == "e") {theCmd += "14"; deltaCharPos = 8}				else if (theDig == "-") {theCmd += "12"; deltaCharPos = 9}				else if (theDig == "+") {theCmd += "11"; deltaCharPos = 9}				else {theCmd += "13"; deltaCharPos = 8}; // should not happen							theCmd += "]," + (yMarksPosition + theCharPosn) + "," + (yGridLines[i] -5) + ")";				eval(theCmd);				theCharPosn += deltaCharPos;				} // j			} // if not skipThis		} // i	} // if theyMultiple < 6666// *** End of the y-tick marks ***// Next the gridlines themselvesctx.strokeStyle = "rgb(200,200,0)"; // yellowfor (var i = 1; i <= xGridLines[0]; i++) 		{// alert("i = " + i + " : " + xGridLines[i] + "of " + xGridLines[0]);		var p = xGridLines[i];		if (p > 0) {			ctx.beginPath();			ctx.moveTo(xGridLines[i], canvasHeight);			ctx.lineTo(xGridLines[i], 0);			ctx.stroke();			ctx.closePath();			} // if p is positive		} // i// alert("here");	for (var i = 1; i <= yGridLines[0]; i++) 		{		var p = yGridLines[i];		if (p > 0) {			ctx.beginPath();			ctx.moveTo(0, yGridLines[i]);			ctx.lineTo(canvasWidth, yGridLines[i]);			ctx.stroke();			ctx.closePath();			} // IF P IS POSITIVE		} // i// Next the axes// alert(yAxisPosition);if (yAxisPosition != -1) {	ctx.strokeStyle = "rgb(0,0,0)";	ctx.beginPath();	ctx.moveTo(yAxisPosition, canvasHeight);	ctx.lineTo(yAxisPosition, 0);	ctx.lineTo(yAxisPosition+3, 8);	ctx.moveTo(yAxisPosition, 0);	ctx.lineTo(yAxisPosition-3, 8);	ctx.stroke();	ctx.closePath();	} // x axisif (xAxisPosition != -1) {	ctx.strokeStyle = "rgb(0,0,0)";	ctx.beginPath();	ctx.moveTo(0, xAxisPosition);	ctx.lineTo(canvasWidth, xAxisPosition);	ctx.lineTo(canvasWidth-8, xAxisPosition+3);	ctx.moveTo(canvasWidth, xAxisPosition);	ctx.lineTo(canvasWidth-8, xAxisPosition-3);	ctx.stroke();	ctx.closePath();	} // x axis} // drawDecorations// ******************Enf of Draw Gridlines and Axes ***********// *************** Utilities follow ***************************function sesame(url,hsize,vsize){ // Default size is 550 x 400        var tb="toolbar=0,directories=0,status=0,menubar=0"        tb+=",scrollbars=1,resizable=1,"    var tbend="width="+hsize+",height="+vsize;    if(tbend.indexOf("<undefined>")!=-1){tbend="width=550,height=400"}        tb+=tbend        Win_2 = window.open("","win2",tb);        Win_2 = window.open(url,"win2",tb);	Win_2.focus();    }function stripSpaces (InString)  {	OutString=""; 	if (InString == "") return (OutString);	for (Count=0; Count < InString.length; Count++)  {		TempChar=InString.substring (Count, Count+1);		if (TempChar!=" ")			OutString=OutString+TempChar;	}	return (OutString);}function stripChar (InString,symbol)  {	OutString="";	for (Count=0; Count < InString.length; Count++)  {		TempChar=InString.substring (Count, Count+1);		if (TempChar!=symbol)			OutString=OutString+TempChar;	}	return (OutString);}function replaceChar (InString,oldSymbol,newSymbol)  {	OutString="";	for (Count=0; Count < InString.length; Count++)  {		TempChar=InString.substring (Count, Count+1);		if (TempChar!=oldSymbol)			OutString=OutString+TempChar		else OutString=OutString+newSymbol;	}	return (OutString);}function makeArray2 (X,Y)	{	var count;	this.length = X+1;	for (var count = 1; count <= X+1; count++)		// to allow starting at 1		this[count] = new makeArray(Y);	} // makeArray2function makeArray (Y)	{	var count;	this.length = Y+1;	for (var count = 1; count <= Y+1; count++)		this[count] = 0;	} // makeArrayfunction rightString (InString, num)  {	OutString=InString.substring (InString.length-num, InString.length);	return (OutString);}function rightTrim (InString)  {	var length = InString.length;	OutString=InString.substring(0,length-1);	return (OutString);}function checkString(InString,subString,backtrack)// check for subString// if backtrack = false, returns -1 if not found, and left-most location in string if found// if backtrack = true, returns -1 if not found, and right-most location in string if found// note that location is to the left of the substring in both cases{var found = -1;var theString = InString;var Length = theString.length;var symbLength = subString.length;for (var i = Length- symbLength; i >-1; i--)	{		TempChar=theString.substring (i, i+ symbLength);	if (TempChar == subString) 			{			found = i;			if (backtrack) i = -1			}	} // ireturn(found);} // checkfunction replaceSubstring (InString,oldSubstring,newSubstring)  {	OutString="";	var sublength = oldSubstring.length;	for (Count=0; Count < InString.length; Count++)  {		TempStr=InString.substring (Count, Count+sublength);		TempChar=InString.substring (Count, Count+1);		if (TempStr!= oldSubstring)			OutString=OutString+TempChar		else 			{			OutString=OutString+ newSubstring;			Count +=sublength-1			}	}	return (OutString);} function parser (InString, Sep)  {	NumSeps=1;	for (Count=1; Count < InString.length; Count++)  {		if (InString.charAt(Count)==Sep)			NumSeps++;	}	parse = new makeArray (NumSeps+4, "");		// my adjustments	Start=0; Count=1; ParseMark=0;	LoopCtrl=1;	while (LoopCtrl==1)  {		ParseMark = InString.indexOf(Sep, ParseMark);		TestMark=ParseMark+0;		if ((TestMark==0) || (TestMark==-1)){			parse[Count]= InString.substring (Start, InString.length);			LoopCtrl=0;			break;		}		parse[Count] = InString.substring (Start, ParseMark);		Start=ParseMark+1;		ParseMark=Start;		Count++;	}	parse[0]=Count;	return (parse);}function winopen(){// opens a window in the bottom frame	var str = winopen.arguments[0];	var loc = winopen.arguments[1];	if (navigator.appName == "Microsoft Internet Explorer") this.parent.bottom.window.location = str;	else window.open(str,loc);} // winopenfunction looksLikeANumber(theString) {// returns true if theString looks like it can be evaluatedvar result = true;var length = theString.length;var x = ""var y = "1234567890-+/*. "var yLength = y.length;for (var i = 0; i <= length; i++)	{ 	x = theString.charAt(i);		result = false;		for (var j = 0; j <= yLength; j++) 			{			if (x == y.charAt(j)) {result = true; break}			} // j	if (result == false) return(false);	} // ireturn(result);} // looks like a numberfunction shiftRight(theNumber, k) {	if (k == 0) return (theNumber)	else		{		var k2 = 1;		var num = k;		if (num < 0) num = -num;		for (var i = 1; i <= num; i++)			{			k2 = k2*10			}		}	if (k>0) 		{return(k2*theNumber)}	else 		{return(theNumber/k2)}	}function roundSigDig(theNumber, numDigits) {	with (Math)		{// alert(theNumber);		if (isBad(theNumber)) return theNumber;		else if (theNumber == 0) return(0);		else if(abs(theNumber) < 0.000000000001) return(0);// WARNING: ignores numbers less than 10^(-12)		else			{			var k = floor(log(abs(theNumber))/log(10))-numDigits+1			var k2 = shiftRight(round(shiftRight(abs(theNumber),-k)),k)			if (theNumber > 0) return(k2);			else return(-k2)			} // end else		}} // roundSigDig// ********* FUNCTION PARSER ***********function myEval(theString){// if (isBad(theString)) return theString;// alert(myParse(theString));return(eval(myParse(theString)))}function checkEval(theString){with (Math) {	return(eval(theString));	}}// The above function requires all the following routinesfunction breakApart(InString) {	// ******* Input: any string such as aaa*bbb or (aa*aa)*bbb	// *** This Routine Retuns two pieces	// *** bbb starts at the left-most operation *, /,  - or +	// *** if it sees a paren, it stops after closure.	theString = InString;	var Length = theString.length;	var outArray = new Array();	outArray[1] = theString;	outArray[2] = "";	var parenCount = 0;	var parenWatch = false;	var looking = true;			if (theString.substring (0,1) == "(")		{		parenCount++;		parenWatch = true;		looking = false;		}	// Look for operators		for (Count=1; Count < Length; Count++)  		{		TempChar=theString.substring (Count, Count+1);		if (TempChar == "(") 			{parenCount ++;}		else if (TempChar == ")") {parenCount = parenCount-1};		if ((parenCount == 0) && (parenWatch == true))			 {			parenWatch = false;			outArray[1] = theString.substring (0, Count+1);			outArray[2] = theString.substring (Count+1, Length);			}		if (looking == true)			{		if ( ( (TempChar == "*") || (TempChar == "/") || (TempChar == "-")  ) || ( (TempChar == "+") || (TempChar == ')' )  )  )				{ 									{					// alert(Count);					looking = false;					outArray[1] = theString.substring (0, Count);					outArray[2] = theString.substring (Count, Length);					// alert (outArray[1]);					// alert(outArray[2]);					} // end if hit one				} 			} // end if looking		} // end of loop	return (outArray);} // end of breakApartfunction isNumberChar (InString)  {	if(InString.length!=1) 		return (false);	RefString="1234567890)";	if (RefString.indexOf (InString, 0)==-1) 		return (false);	return (true);}function isCharHere (InString, RefString)  {	if(InString.length!=1) 		return (false);	if (RefString.indexOf (InString, 0)==-1) 		return (false);	return (true);}function putProduct(InString) {OutString="";for (Count=0; Count < InString.length; Count++)  {		TempChar=InString.substring (Count, Count+1);		if (!isCharHere(TempChar,"xXeslcapdDuUhHtT(") || (Count == 0) )			{OutString=OutString+TempChar}		else 			{			if (isNumberChar(InString.substring(Count-1,Count)))				{OutString=OutString+"*"+TempChar}			else OutString=OutString+TempChar			}	}	return (OutString);}function reverse (InString)  {	OutString="";	var Length = InString.length;	for (Count=Length; Count > -1; Count--)  {		TempChar=InString.substring (Count, Count+1);		if (TempChar == "(") {TempChar = ")"}		else if  (TempChar == ")") {TempChar = "("}		OutString=OutString+TempChar;		}	return (OutString);	}function powFix2(InString) {	// ****Replaces one "^" by "pow"	theString = InString;	var Length = theString.length;	outString = theString; 		// in case nothing happens			// Look for wedge	var looking = true;	for (Count=0; Count < Length; Count++)  		{		if (looking)			{			TempChar=theString.substring (Count, Count+1);			if (TempChar == "^")				{				looking = false;				rightStr = theString.substring (Count+1,Length);				leftStr = theString.substring (0,Count);				// deal with right-hand string				Aray = breakApart(rightStr);				Arg2 = Aray[1];				rightRest = Aray[2];							backString = reverse(leftStr);				Aray = breakApart(backString);				Arg1 = reverse(Aray[1]);				leftRest = reverse(Aray[2]);				outString = leftRest+"Math.pow("+Arg1+","+Arg2+")"+rightRest;								} // end hif hit a wedge			} // end of looking for a wedge		} // end of loop// ****** testing *******// document.Extra.diagnostics.value += outString + cr;// ***** end testing *****return (outString);} // end of powFix2function powCheck(InString) {	// ****checks for ^		theString = InString;	var Length = theString.length;		// Look for wedge	var found = false;	for (Count=0; Count < Length; Count++)  		{		TempChar=theString.substring (Count, Count+1);		if (TempChar == "^")			{			found = true;			} // end if hit a wedge		} // end of looking for a wedge	return(found);} // end of powCheckfunction isBad(x) {// alert(x);var xa = replaceSubstring(x,"pi",3.14);if((isNaN(xa)) || (xa > infinity) || (xa < -infinity)) return(true);else return(false)}function myParse(expression){// alert('here')		var theString = stripSpaces(expression);				with (Math)			{		// now convert formatting from GC formatting				theString = putProduct(theString);		theString = replaceSubstring(theString,"log","(1/Math.log(10))*Math.log");		theString = replaceSubstring(theString,"ln","Math.log");		theString = replaceSubstring(theString,"abs","Math.abs");			while (powCheck(theString))				{				theString = powFix2(theString);				// alert(theString);				}		theString = theString.toLowerCase();		theString = replaceSubstring (theString,"math.","Math."); 		// in case the user put in a math. something// alert(theString);			} // with Math		theString = replaceSubstring (theString,"exp","Math.exp");		theString = replaceSubstring (theString,"cos","Math.cos");		theString = replaceSubstring (theString,"sin","Math.sin");		theString = replaceSubstring (theString,")(",")*(");		theString = replaceSubstring (theString,")ln",")*ln");		theString = replaceSubstring (theString,"sqrt","Math.sqrt");		return(theString);} // myParse// ******** END FUNCTION PARSER **************function toFrac(x, maxDenom) {	if (isBad(x)) return x;	var theFrac = new Array();	theFrac[1] = 0;	theFrac[2] = 0;	var p1 = 1;	var p2 = 0;	var q1 = 0;		var q2 = 1;		var u =0;	var t = 0;	var flag = true;	var negflag = false;	var a = 0;	var xIn = x; // variable for later	var n = 0;	var d = 0;	var p = 0;	var q = 0;	if (x >10000000000) return(theFrac);while (flag)	{	if (x<0) {x = -x; negflag = true; p1 = -p1}	var intPart = Math.floor(x);	var decimalPart = roundSigDig((x - intPart),15);	x = decimalPart;	a = intPart;		t = a*p1 + p2;	u = a*q1 + q2;	if  ( (Math.abs(t) > 10000000000 ) || (u > maxDenom ) ) 		{			n = p1;			d = q1;			break;		}		p = t;		q = u;			//		cout << "cf coeff: " << a << endl; // for debugging//		cout << p << "/" << q << endl;	// for debugging			if ( x == 0 )		{		n = p;		d = q;		break;		}		p2 = p1;		p1 = p;		q2 = q1;		q1 = q;		x = 1/x;		} // while ( true );		theFrac[1] = n;	theFrac[2] = d;	if (theFrac[2] == 1) return (theFrac[1].toString());	else return (theFrac[1] + "/" + theFrac[2]);} // toFrac// ***********************************************// **** Graphing Routine// ***********************************************function readBasics() {// alert("here");var theStrg = "";  // dummy string for evaluating functionsautoY = document.theFormB.autoYButton.checked;autoX = document.theFormB.autoXButton.checked;autoGridline = document.theFormB.autoGridButton.checked;// get the graph window information	for (var k = 1; k <= 1; k++)	{	if(!autoX) {		var aa = document.theFormB.a.value; // alert(aa);		if (aa == "") { alert("You have not entered a number for xMin."); okToRoll = false; break;}//alert(aa);		a = myEval(aa);		if (isNaN(a) ) { alert("You have not entered a number for xMin."); okToRoll = false; break;}		var bb = document.theFormB.b.value; 		if (bb == "") { alert("You have not entered a number for xMax."); okToRoll = false; break}		b = myEval(bb); 		if (isNaN(b) ) { alert("You have not entered a number for xMax."); okToRoll = false; break;}		if ( (okToRoll) && (a >= b)) { alert("xMax should be larger than xMin"); okToRoll = false; break;}		} // if not autoX	if(!autoY) {// alert("Here autoY is off");		var cc = document.theFormB.c.value; 		if (cc == "") { alert("You have not entered a number for yMin. (Otherwise click on 'Auto'.)"); okToRoll = false; break}		c = myEval(cc); 		if (isNaN(c) ) { alert("You have not entered a number for yMin. (Otherwise click on 'Auto'.)"); okToRoll = false; break;}		var dd = document.theFormB.d.value; 		if (dd == "") { alert("You have not entered a number for yMax. (Otherwise click on 'Auto'.)"); okToRoll = false; break}		d = myEval(dd); 		if (isNaN(d) ) { alert("You have not entered a number for yMax. (Otherwise click on 'Auto'.)"); okToRoll = false; break;}		if ( (okToRoll) && (c >= d)) { alert("yMax should be larger than yMin"); okToRoll = false; break;}// alert(a + " , " + b + " , " + c + " , " + d);		} // end of if not autoY	// if auto we need to read in the DEs and solve them first// first convert to a system if in DE modeif (!solvingSystem) {	// replace it by a system	theXPrimeFun = "y";	var theString = stripSpaces(document.theFormA.xdd.value);	theYPrimeFun = replaceSubstring(theString,"x'","y");	}else {	theXPrimeFun = stripSpaces(document.theFormA.x.value);	theYPrimeFun = stripSpaces(document.theFormA.y.value);	}if ((solvingSystem) && ((theXPrimeFun == "") || (theYPrimeFun == ""))) {	alert("You did not enter functions for both x' and y'."); okToRoll = false;	}else if ((!solvingSystem) && (theYPrimeFun == ""))  {	alert("You did not enter a function for x''."); okToRoll = false;	}if (okToRoll) {for (var i = 1; i <= numCurves; i++) {	theCombinedResult[i] = RungeKutta2(theXPrimeFun, theYPrimeFun, x0Vals[i], y0Vals[i], tMin, tMax, numPoints);	} // iif(document.theFormB.autoXButton.checked) {	for (var i = 1; i <= numCurves; i++) {		if (i == 1) {a = theCombinedResult[1][2][0]; b = a }		for (var w = 0; w <= numPoints; w++) {			a = Math.min(a, theCombinedResult[i] [2][w]);			b = Math.max(b, theCombinedResult[i] [2][w]);			} // w		} // i	b = b + .1*Math.abs(b); a = a - .1*Math.abs(a);	a = parseFloat(roundSigDig(a,2));	b = parseFloat(roundSigDig(b,2));	if (b == a) {b+= .1; a-= .1} // could be both zero	} // if autoxif(document.theFormB.autoYButton.checked) {	for (var i = 1; i <= numCurves; i++) {		if (i == 1) {c = theCombinedResult[1][3][0]; d = c }		for (var w = 0; w <= numPoints; w++) {			c = Math.min(c, theCombinedResult[i] [3][w]);			d = Math.max(d, theCombinedResult[i] [3][w]);			} // w		} // i	d = d + .1*Math.abs(d); c = c - .1*Math.abs(c);	c = parseFloat(roundSigDig(c,2));	d = parseFloat(roundSigDig(d,2));	if (c == d) {d+= .1; c-= .1} // could be both zero	} // if autoy	} // if okToRoll// alert("c = " + c + " d = " + d);// At this point we have the globals a, b, c, d we need	if(!autoGridline) {		var xk = document.theFormB.xg.value;		if (xk == "") xGridStep = 0;		else xGridStep = eval(xk);		var yk = document.theFormB.yg.value;		if (yk == "") yGridStep = 0;		else yGridStep = eval(yk);		} // end of if not autoGridline	else {		document.theFormB.xg.value = ''; 		document.theFormB.yg.value = ''; // cannnot have it both ways.		var pq = Math.round((b-a)/8);		if (pq == 0) pq = (b-a)/8;		xGridStep = pq;		pq = Math.round((d-c)/8);		if (pq == 0) pq = (d-c)/8;		yGridStep = pq;		} // end of else for autoGridline	} // end of single loop (k)}// ********************************************************************// *********** Initilaize the Canvas & Set up the Axes and Gridlines ****// ********************************************************************function makeGraph2(){readBasics();// alert(roundSigDig(.000001, 1));if (okToRoll) {// alert("a = "+a+"b="+b+"c="+c+"d = "+d);// initialize the canvas	// alert("a = "+a+"b="+b+"c="+c+"d = "+d);	// now set up the axes & gridlines	// gridlines first	// setup position of gridlines	if (xGridStep > 0) xGridLines[0] = Math.floor(  (b-a)/xGridStep );	else xGridLines[0] = 0;	if (yGridStep > 0) yGridLines[0] = Math.floor(  (d-c)/yGridStep );	else yGridLines[0] = 0;	// initialize these arrays to zero 	for (var i = 1; i <= xGridLines[0]; i++) {xGridLines[i] = 0; xGridLinesActual[i] = a}	for (var i = 1; i <= yGridLines[0]; i++) {yGridLines[i] = 0; yGridLinesActual[i] = d}	var pq = 0; // just a dummy variable	if (a*b >= 0) {		// no y-axis appears in the interior in this case		for (var i = 1; i <= xGridLines[0]; i++)			{			xGridLines[i] = Math.round( i*xGridStep*canvasWidth/(b-a)  );			xGridLinesActual[i] = a + i*xGridStep;// alert("i = " + i + " : " + xGridLines[i] + cr);			} // x Grid Line Positions		} // if a and b have the same sign	else 		{ // want the y-axis to be one of the gridlines		for (var i = 1; i <= xGridLines[0]; i++)			{			pq = Math.round((i*xGridStep - a)*canvasWidth/(b-a));			if ((pq <= canvasWidth) && (pq >= 0)) {				xGridLines[i] = pq;				xGridLinesActual[i] = i*xGridStep;				}			else break;			} // loop i		i -= 1; //overstepped i		for (var j = 1; j <= xGridLines[0] - i; j++)			{			pq = Math.round((-j*xGridStep - a)*canvasWidth/(b-a));// alert("j = " + j + "pq = " + pq);			if ((pq <= canvasWidth) && (pq >= 0)) 				{				xGridLines[j+i] = pq;				xGridLinesActual[j+i] = -j*xGridStep;				}			else {				xGridLines[j+i] = 0;				xGridLinesActual[j+i] = a;				}			} // loop j		} // a and b have opposite sign	if (c*d >= 0) {		for (var i = 1; i <= yGridLines[0]; i++)			{			yGridLines[i] = Math.round( i*yGridStep*canvasHeight/(d-c)  );			yGridLinesActual[i] = d - i*yGridStep;			} // y Grid Line Positions		} // if c and d have the same sign	else {		for (var i = 1; i <= yGridLines[0]; i++)			{			pq = Math.round((i*yGridStep - c)*canvasHeight/(d-c));			if ((pq <= canvasHeight) && (pq >= 0)) {				yGridLines[i] = canvasHeight - pq;				yGridLinesActual[i] = i*yGridStep;				}			else break;			} // loop i		for (var j = 1; j <= yGridLines[0] - i; j++)			{			pq = Math.round((-j*yGridStep - c)*canvasHeight/(d-c));// alert("j = " + j + "pq = " + pq);			if ((pq <= canvasHeight) && (pq >= 0)) {				yGridLines[j+i] = canvasHeight - pq;				yGridLinesActual[j+i] = -j*yGridStep;				}			else {				yGridLines[j+i] = 0;				yGridLinesActual[j+i] = d;				}			} // loop j		} // if c and d have oppositve sign		// now the axes	if ((a <= 0) && (b >= 0)) yAxisPosition = Math.round((-a)*canvasWidth/(b-a));else yAxisPosition = -1;	if ((c <= 0) && (d >= 0)) xAxisPosition = Math.round(d*canvasHeight/(d-c));else xAxisPosition = -1;// alert("here");	} // if okToRoll } // maheGraph2// ************** GRAPH in EXCANVAS *************function refreshGraph()  {// nothing here} // End of refreshGraph// ************** DISPLAY GRAPH *************// For old browsersfunction displayTheGraph()  {// puts up the graph in the appropriate window, and extra things as needed	// *** Open a window	var tb="toolbar=0,directories=0,status=0,menubar=0"	tb+=",scrollbars=1,resizable=1,"	var tbend="width=350,height=300"	tb+=tbend	Win_1 = window.open("","win1",tb);	Win_1.document.open();	// ** Window is openedvar theString  = '<html><title>Your Graph</title><body bgcolor = "FFFFFF"><p><center><table><tr>'theString += '<td></td><td align = center>' + roundSigDig(d,4) + '</td></tr><tr><td valign = center>'+ roundSigDig(a,4)+'</td><td>';theString += '<table border = 1><tr><td>';theString += formatGraph2();			// the actual graphtheString += '</td></tr></table>';theString += '</td><td valign = center>' + roundSigDig(b,4) + '</td></tr><tr><td><td align = center>' + roundSigDig(c,4) + '</td></tr></table></center></body></html>';Win_1.document.write(theString);Win_1.document.close();Win_1.focus();} // displayTheGraph// ********** END DISPLAY GRAPH *************// ************** FORMAT GRAPH *************// Requires the following global variables:// 1. theCanvas = the matrix of pixels -- entries are the colors 0-numCols// 2. numX, numY, the dimensions of the canvas// 3. theDot: an array of pixel images (gif) -- little swaths of color// Returns the html for the actual graphfunction formatGraph2() {var theString = "";var repeats = new Array(); // this contains a list of different rows in theCanvasvar theRow1 = new makeArray(numY);repeats[1] = 1; // first rowvar numRepeats = 1; var oldVal = 0;var newVal = 0;var theLength = 0;var theHeight = 0;for (var k = 1; k <= numY; k++) theRow1[k] = theCanvas[k][1];for (var i = 1; i <= numY; i++)	{// if (i == 100) alert('Here i = ' + i);	for (var j = i+1; j <= numY; j++)		{// if (j == 100) alert('Here j = ' + j);		for (var k = 1; k <= numX; k++)			{// if (k == 100) alert('Here k = ' + k);			if (theRow1[k] != theCanvas[k][j])				{				numRepeats++;				repeats[numRepeats] = j;				for (var p = 1; p <= numY; p++) theRow1[p] = theCanvas[p][j]; 				i = j-1;				k = numX;				j = numY;				} // if			} // k		} // j	} // irepeats[numRepeats+1] = numY+1; // for last line height// var theTestString = '';// for (var i = 1; i <= numRepeats; i++) theTestString += "," + repeats[i];// document.theForm.output.value += theTestString;// alert("here. numRepeats = " + numRepeats );var theRow = 1;for (var i = 1; i <= numRepeats; i++)	{ 	theLength = 1;	theRow = repeats[i];	theHeight = repeats[i+1] - repeats[i];	oldVal = theCanvas[1][theRow];	for (var j = 2; j <= numX; j++)		{		 if ((j == numX)  && ( theCanvas[j][theRow] != oldVal) )			{			var LL = theLength-1;			theString += '<img src = "' + theDot[oldVal].src + '" width = ' + LL + ' height = ' + theHeight + '>'			theString += '<img src = "' + theDot[theCanvas[j][theRow]].src + '" width = 1 height = ' + theHeight + '>'						} // change on last pixel		else if(( theCanvas[j][theRow] != oldVal) || (j == numX))			{			// saw a change// alert(i);// alert(j);			// make a string of the right length			theString += '<img src = "' + theDot[oldVal].src + '" width = ' + theLength + ' height = ' + theHeight + '>'			oldVal = theCanvas[j][theRow];			theLength = 0;			} 		theLength++;		} // j	theString += '<br>';	} // ireturn(theString);} // formatGraph// ********** END FORMAT GRAPH *************// *************** OUTOFBOUNDS ************function outOfBounds(x1,x2,y1,y2) {if ((x1 < a) && (x2 < a)) return(true);else if ((y1 < c) && (y2 < c)) return(true);else if ((y1 > d) && (y2 > d)) return(true);else if ((x1 > b) && (x2 > b)) return(true);else return(false);}// ************** SEGMENT *************// creates a clipped segment in the window// note that the segment is automatically clipped by excanvas // so there is no work for us herefunction segment(x1,y1,x2,y2, col) {if (col == "magenta") {colr = 200; colg = 0; colb = 100}else if (col == "yellow")  {colr = 200; colg = 200; colb = 0}else if (col == "black")  {colr = 0; colg = 0; colb = 0}else if (col == "blue")  {colr = 0; colg = 0; colb = 255}else if (col == "red")  {colr = 255; colg = 0; colb = 0}else if (col == "green")  {colr = 0; colg = 255; colb = 0}else if (col == "aqua")  {colr = 0; colg = 200; colb = 200}else if (col == "purple")  {colr = 200; colg = 0; colb = 250}else if (col == "grey")  {colr = 100; colg = 100; colb = 100}else if (col == "pink")  {colr = 125; colg = 0; colb = 0}else if (col == "orange")  {colr = 255; colg = 125; colb = 0}else {colr = 0; colg = 0; colb = 0} // black defaultvar xMin = a;var xMax = b;var yMin = c;var yMax = d; // alert(a + " , " + b + " , " + c + " , " + d);var x1bar = Math.round(canvasWidth*(x1-xMin)/(xMax-xMin) );var x2bar = Math.round(canvasWidth*(x2-xMin)/(xMax-xMin) );var y1bar = Math.round(canvasHeight*(yMax-y1)/(yMax-yMin) );var y2bar = Math.round(canvasHeight*(yMax-y2)/(yMax-yMin) );var style = ["rgb(",colr, ",", colg, ",", colb, ")"].join("");ctx.strokeStyle = style;ctx.beginPath();ctx.moveTo(x1bar, y1bar);ctx.lineTo(x2bar, y2bar);ctx.stroke();ctx.closePath();} // segment// ************** BEZIER **********************************function bezier(x1,y1,x2,y2,a1,b1,a2,b2, color) {// a2 *= -1;// b2 *= -1;// calculate number of t-stepsvar numTSteps = 1;if (outOfBounds(x1,x2,y1,y2)) numTSteps = 1;else {	var x1bar = Math.round(canvasWidth*(x1-a)/(b-a) );	var x2bar = Math.round(canvasWidth*(x2-a)/(b-a) );	var y1bar = Math.round(canvasHeight*(d-y1)/(d-c) );	var y2bar = Math.round(canvasHeight*(d-y2)/(d-c) );	numTSteps = Math.round(.5 + Math.max(Math.abs(x2bar-x1bar),Math.abs(y2bar-y1bar))/2); // 2 pixel segments		} // else// alert(numTSteps);// numTSteps = 1; // testingvar deltaT = 1/numTSteps;var u1 = x1; var v1 = y1;var u2 = 0; var v2 = 0;var tval = 0;for (var kk = 1; kk <= numTSteps; kk++) {	tval+= deltaT;	u2 = (2*(x1-x2) + (a1+a2))*tval*tval*tval + (3*(x2-x1) - (a2 + 2*a1))*tval *tval + a1*tval + x1;	v2 = (2*(y1-y2) + (b1+b2))*tval*tval*tval + (3*(y2-y1) - (b2 + 2*b1))*tval *tval + b1*tval + y1;	segment(u1,v1,u2,v2, color);	u1 = u2; v1 = v2;	} // kk} // bezier// **************** DRAWCURVE ******************************// *** Draws a graph of a given funtionfunction drawCurve(theyString, thexMin, thexMax, theCurveColor) {// alert(a + " , " + b + " , " + c + " , " + d);// alert("at DrawCurve; theyString = " + theyString + " thexMin = "+ thexMin + " thexMax = "+ thexMax + " theCurveColor = " + theCurveColor);// Draws curve using function segment(x1,y1,x2,y2, theCurveColor) repeatedly// a and b are Xmin and Xmax respectivelyokToRoll = true;var theStrg = myParse(theyString);if (thexMax <= thexMin) {alert("Xmin must be less than Xmax. Correct this and try again."); okToRoll = false}if (okToRoll) {			// Search for a place to start the graph 			// (in case initial y-coords are undefined or infinite.) 			var deltax = (thexMax - thexMin)/numDivisions;// alert(deltax);// deltax = .25; // testing			x1 = thexMin;			x = x1;			y1 = checkEval(theStrg);// alert(y1);// alert("x1 = " + x1 + "y1 = "+ y1 + (y1 > infinity));			if(isBad(y1)) {// alert("**HERE**")				for (var k = thexMin; k <= thexMax; k+=deltax) {					x = k;					x1 = k;					y1 = checkEval(theStrg);					if(!isBad(y1)) break;					} // end count// alert(x1);				if (k >= thexMax) {alert("Y is not defined for your given X-range."); okToRoll = false}				if (y1 > infinity) y1 = infinity;				else if (y1 < -infinity) y1 = -infinity;				} // y1 is not a number						} // if OKtoRollif (okToRoll) {		// now plot the points// alert(x);			var thecount = 0; /// testing		var startingX = x + deltax;		for (var k = startingX; k <= thexMax; k+=deltax) {			thecount++;// if (thecount == 35) alert("thcount = " + thecount + "k = "+k);// if (thecount == 41) alert("thcount = " + thecount + "k = "+k);			x2 = k;			x = x2;			y2 = checkEval(theStrg);			if (!isBad(y2)) {				if (y2 > infinity) y2 = infinity;				else if (y2 < -infinity) y2 = -infinity; // alert(x1 + "," + y1 + "," + x2 + "," + y2);				var p = segment(x1,y1,x2,y2,theCurveColor);				x1 = x2;				y1 = y2;				} // If second point is defined			else {				for (var p = x2+deltax; p <= thexMax; p+=deltax) {					x = p;					y1 = checkEval(theStrg);					if(!isBad(y1)) break;					} // end count				k = p; // reset k further along the loop				x1 = p;  // y1 is already what it is supposed to be				} // second point was undefined							if(thecount >= numDivisions + 2) k = thexMax+1;			} // k// alert("k over");	} // if okToRoll} // function drawCurve// ************** various miscellaneous routines *************function rememberValues() {if (document.theFormC.y1x1.value != "") {	var theInstruction = ""; // a javascript instuction	var doIt = 0; // a dummy variable	for (var i = 1; i <= maxnumX; i++) {		for (var j = 0; j <= maxNum; j++) {		if (j > 0) theInstruction = " theValues[i][j] = document.theFormC.y"+j+"x"+i+".value";		else theInstruction = " theValues[i][j] = document.theFormC.x"+i+".value";		doIt = eval(theInstruction);		} // j	} // i} // IF THERE IS SOMETHING IN THE FIRST CELL} // remember valuesfunction bringBackValues() {	if (document.theFormC.y1x1.value == "") {		var theInstruction = ""; // a javascript instuction		var doIt = 0; // a dummy variable		for (var i = 1; i <= maxnumX; i++) {			for (var j = 0; j <= maxNum; j++) {			if (j > 0) theInstruction = " document.theFormC.y"+j+"x"+i+".value = theValues[i][j]";			else theInstruction = " document.theFormC.x"+i+".value = theValues[i][j]";			doIt = eval(theInstruction);			} // j		} // i	} // if there is nothing in the first cell} // remember values