# flash on 2011-1-9

`So this is some 'graph drawer' code. I just decided to post this code, but i nvm this work. Im starting a new one, so.. have fun, idk.`
by Thy 09 Jan 2011
Embed
```/**
* Copyright Thy ( http://wonderfl.net/user/Thy )
*/

// Saqoosha (http://wonderfl.net/user/Saqoosha) - Bresenham's line (http://wonderfl.net/c/lTpz)
package
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Shape;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageQuality;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.text.TextFormat;

/**
* ...
* @author Thi @Thyfl
* Graph 2.0
*
* Credit:
* Saqoosha (http://wonderfl.net/user/Saqoosha) - Bresenham's line (http://wonderfl.net/c/lTpz)
*
* expression sample:
* 4 + 3 * 2 ^ 1 - 10
* -1 ^ round (x) - sin (x) + asin(x²) + (.08x² + .1x - 1)
*
* features (adapted for English & Portuguese):
* pi = PI = 3.1415, e = E = 2.7182
* round (x), floor (x), ceil (x), log (x), exp (x)
* sen (x) = seno (x) = sin (x), cosseno (x) = cos (x)
* tangente (x) = tangent (x) = tgt (x) = tg (x) = tan (x)
* absoluto (x) = modulo (x) = abs (x)
* aleatorio = random, 0 <= random < 1, raiz (x) = sqrt (x) = x ^ (1/2)
* acos (x), asin (x), atan (x)
*
* syntax observations:
* a + b = a   +b, a-b, a*b = a(b) = (a)b = (a)(b), a/b, a^b
* 1*a = 1a = 1 a, a+b*c = a+(b+c), a*b^c = a(b^c), a² = a^2, a³ = a^3
*/
public class Main extends Sprite
{
public var  // libralies
sets:Settings = new Settings(), // program settings
textLibraly:Array = // text libralies
[new TextFormat("Tahoma", 12),
new TextFormat("Tahoma", 10)];

public var
vars:Vector.<Var> = new Vector.<Var>(),
points:Vector.<Point2> = new Vector.<Point2>(),
funcs:Vector.<Function2> = new Vector.<Function2>(),
graphs:Vector.<Graph> = new Vector.<Graph>(),
panels:Vector.<Panel2> = new Vector.<Panel2>(),
//
source:Array = new Array(6, true);

public var
// calculator functions: translate:Array, rpn:Array, calculate:Number
calc:Calculator = new Calculator(),
grid:Grid = new Grid(),
ballon:Ballon,
lineTo:Boolean = false, // if use or not the bresenham
lineToShape:Shape = new Shape();

public var
pointsData:BitmapData,
pointsBm:Bitmap,
graphsData:BitmapData,
graphsBm:Bitmap,
panelsData:BitmapData,
panelsBm:Bitmap;

private var
writing:Boolean = false,
textUpdate:int = 20;

private var // easyings
graphEase:int = 10;

public function Main():void
{
// setup all the setuptable stuff
setup();
// first draw the grid.
grid.draw();
// first draw the points.
drawPoints();

// make an update
update();

}

// setup
private function setup():void
{
// swf settings
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
stage.quality = StageQuality.MEDIUM;
stage.frameRate = 40;

// setup settings
sets.w = 465; // window width
sets.h = 465; // window height

// setup calculator
calc.src = source;

// setup variables
vars.push(new Var("x", " = ", "0")); // this 'x' is kinda 'protected'
vars.push(new Var("y", " = ", "0"));

// setup points
points.push(new Point2("0", ",", "0", 0x0));

// setup functions
funcs.push(new Function2("y", " =  ", "x"));

// setup graphs
graphs.push(new Graph("x", ",", "y", 0xFFFF0000, source));

// setup source
source[0] = vars;
source[1] = points;
source[2] = funcs;
source[3] = graphs;
source[4] = panels;
source[5] = grid;

// setup panels
panels.push(new Panel2(new Rectangle(0, 0, 465 - 60, 30), .1, 10)); // funcs (^)
panels.push(new Panel2(new Rectangle(0, 0, 30, 465 - 60), .1, 10)); // graphs (<)
panels.push(new Panel2(new Rectangle(0, 0, 465 - 60, 30), .1, 10)); // vars (v)
panels.push(new Panel2(new Rectangle(0, 0, 30, 465 - 30), .1, 10)); // points (>)
panelPosition();
//
//
panels[0].activated = true;
panels[0].active();
panels[1].activated = true;
panels[1].active();
panels[2].activated = true;
panels[2].active();
panels[3].activated = true;
panels[3].active();

// setup grid
grid.sets = sets;
grid.min = new Point( -10, -10);
grid.max = new Point(10, 10);
grid.d = new Point(grid.max.x - grid.min.x, grid.max.y - grid.min.y);
grid.step = new Point(grid.d.x / sets.w,
grid.d.y / sets.h),
grid.stepBack = new Point(1, 1);
grid.ms = new Point(grid.min.x / grid.step.x,
grid.min.y / grid.step.y); // min / step
grid.data = new BitmapData(sets.w, sets.h, false, 0xFFFFFF);
grid.bm = new Bitmap(grid.data, "auto", true);
grid.minCoord.x = grid.min.x / grid.step.x - grid.ms.x;
grid.minCoord.y = -(grid.min.y / grid.step.y + grid.ms.y);
grid.maxCoord.x = grid.max.x / grid.step.x - grid.ms.x;
grid.maxCoord.y = -(grid.max.y / grid.step.y + grid.ms.y);

// setup ballon
ballon = new Ballon(textLibraly, source);
ballon.delay = 60;

// setup Bm & Datas
pointsData = new BitmapData(sets.w, sets.h, true, 0xFFFFFF);
pointsBm = new Bitmap(pointsData, "auto", true);
graphsData = new BitmapData(sets.w, sets.h, true, 0xFFFFFF);
graphsBm = new Bitmap(graphsData, "auto", true);
panelsData = new BitmapData(sets.w, sets.h, true, 0xFFFFFF);
panelsBm = new Bitmap(panelsData, "auto", true);
//
drawPanelsData();

// Children
}

public function drawPanelsData():void
{
var r:Rectangle = new Rectangle();
r.width = panels[1].r.width; // 2
r.height = panels[0].r.height; // 30
panelsData.fillRect(r, 0xCC000000); // AF // (<^)
r.y = 465 - panels[2].r.height; // 465-2
r.height = panels[2].r.height; // 2
panelsData.fillRect(r, 0xCC000000); // (<v)
r.x = 465 - panels[3].r.width; // 465 - 2
r.width = panels[3].r.width; // 2
panelsData.fillRect(r, 0xCC000000); // (>v)
r.y = 0;
r.height = panels[0].r.height; // 30
panelsData.fillRect(r, 0xCC000000); // (>^)
}

private function drawPoints():void
{
var
i:int = -1,
l:int = points.length,
p:Point = new Point(),
p2:Point2,
X:Number,
Y:Number;

pointsData.lock();
pointsData.fillRect(pointsData.rect, 0xFFFFFF);
while (++i < l)
{
p2 = points[i];
X = findVar(p2.a) / grid.step.x - grid.ms.x;
Y = -(findVar(p2.c) / grid.step.y + grid.ms.y);

if (X < panels[1].r.width + 10)
{
X = panels[1].r.width + 10;
} else if (X > panels[3].r.x - 10)
{
X = panels[3].r.x - 10;
}
if (Y < panels[0].r.height + 10)
{
Y = panels[0].r.height + 10;
} else if (Y > panels[2].r.y + 10)
{
Y = panels[2].r.y + 10;
}

// center of circle
p.x = X - 4;
p.y = Y - 4;
pointsData.copyPixels(p2.data, p2.data.rect, p);

}
pointsData.unlock();
}

private function panelPosition():void
{
panels.push(new Panel2(new Rectangle(2 + (30), 0, 465 - 2 - 2 - (60), 0 + (30)), .1, 10)); // funcs (^)
panels.push(new Panel2(new Rectangle(0, 0 + (30), 2 + (30), 465 - 30 - 2), .1, 10)); // graphs (<)
panels.push(new Panel2(new Rectangle(2 + (30), 465 - 2 - (30), 465 - 2 - 2, 2 + 30), .1, 10)); // vars (v)
panels.push(new Panel2(new Rectangle(465 - 2 - (30), 0 + (30), 2 + (30), 465 - 30 - 2), .1, 10)); // points (>)

// panel movement easying - w,h,w,h,
panels[0].r.height += (panels[0].r2.height - panels[0].r.height) * .1;
panels[1].r.width += (panels[1].r2.width - panels[1].r.width) * .1;
panels[2].r.height += (panels[2].r2.height - panels[2].r.height) * .1;
panels[3].r.width += (panels[3].r2.width - panels[3].r.width) * .1;

// panel acomodation - xw,yh,xyw,xyh
panels[0].r.x = panels[1].r.width;
panels[0].r.width = 465 - panels[1].r.width - panels[3].r.width;
panels[1].r.y = panels[0].r.height;
panels[1].r.height = 465 - panels[0].r.height - panels[2].r.height;
panels[2].r.x = panels[0].r.x;
panels[2].r.width = panels[0].r.width;
panels[2].r.y = 465 - panels[2].r.height;
panels[3].r.x = 465 - panels[3].r.width;
panels[3].r.y = panels[1].r.y;
panels[3].r.height = panels[1].r.height;

// the graphic update
panels[0].draw();
panels[1].draw();
panels[2].draw();
panels[3].draw();
}

// Keyboard
private function keyDown(e:KeyboardEvent):void
{
writing = true;
}

private function keyUp(e:KeyboardEvent):void
{
writing = false;
}

// Mouse
private function mouseMove(e:MouseEvent):void
{
// ballon show
showBallon();

}

// Ballon
private function showBallon():void
{
ballon.delay = 60;
ballon.alpha = 1;
ballon.visible = true;
ballon.target.x = mouseX;
ballon.target.y = mouseY;

var X:Number = Math.round((mouseX + grid.ms.x) * grid.step.x * 10) / 10;
var Y:Number = Math.round( -(mouseY + grid.ms.y) * grid.step.y * 10) / 10;
ballon.title.text = "(" + String(X) + ", " + String(Y) + ")";

var i:int = -1, l:int = funcs.length;
vars[0].c = String(X);
while (++i < l)
{
updateVar(funcs[i].a, String(calc.calculate(funcs[i].array)))
}

i = 0, l = vars.length;
while (++i < l)
{
ballon.title.appendText("\n" + vars[i].a + ": " +
String(Math.round(Number(vars[i].c)*10)/10));
}

ballon.update();
}

private function ef(e:Event):void
{
// any text modification will change things.
if (writing) textUpdate = 20;
if (textUpdate > 0)
{
// panel position
panelPosition();
drawPanelsData();

if (--textUpdate == 0)
{
// do all the graph update
update();
// do all the points update
//update2();
}
}

// the graph easying
if (--graphEase > 0)
{
if (graphEase == 1)
{
lineGraph(1);
} else
{
lineGraph(.2);
}
}

// ballon
if (--ballon.delay < 0 && ballon.alpha > .1)
{
ballon.alpha *= .9;
if (ballon.alpha < .1)
{
ballon.alpha = 0;
ballon.visible = false;
}
}
ballon.move();

}

private function update():void
{
// graph update
var
i:int = -1,
l:int = funcs.length, m:int,
func:Function2;
while (++i < l)
{
// remake graphs array (RPN)
func = funcs[i];
if (!func.activated) continue;
trace("___\n"+func.c)
func.array = calc.translate(func.c);
func.preventError = calc.preventError;
func.array = calc.rpn(func.array, func.preventError);
trace(func.array);
trace(calc.calculate(func.array));
}

// clear graphs
m = graphs.length;
i = -1;
while (++i < l)
{
graphs[i].j = -1;
graphs[i].setTarget()
}

// get points of the graph
var X:Number = grid.min.x;
l = funcs.length;
while ((X += grid.step.x) < grid.max.x)
{
vars[0].c = String(X);
i = -1;
while (++i < l)
{
// ea function update an var.
if (!funcs[i].activated) continue;
updateVar(funcs[i].a, String(calc.calculate(funcs[i].array)));
}
i = -1;
while (++i < m)
{
// each graph recive its points (465)+(465)
graphs[i].recivePoints();
}
}
vars[0].c = String(0); // x = 0

// draw graph (to bitmapData)
graphEase = 30;

// ballon show
showBallon();
}

// graph
private function lineGraph(easying:Number = 1):void
{
var i:int = -1, j:int = -1, m:int = graphs.length,
graph:Graph;
var X:Number, Y:Number, X2:Number, Y2:Number;
graphsData.lock();
graphsData.fillRect(graphsData.rect, 0xFFFFFF);
i = -1;
while (++i < m)
{
graph = graphs[i];
graph.pointsEase(easying);
if (lineTo) lineToShape.graphics.lineStyle(1, graph.color);
j = 0;
Y2 = graph.pointsy[0];
Y2 = graph.pointsy[0];

while (++j < 465)
{

if (graph.nans[j])
{
while (graph.nans[++j] || graph.nans[++j] || j >= 463)
{
if (j > 463)
{
break;
}
}
X2 = graph.pointsx[--j] ;
Y2 = graph.pointsy[j];
++j;
}

X = graph.pointsx[j];
Y = graph.pointsy[j];

if (X < grid.minCoord.x && X2 < grid.minCoord.x || X > grid.maxCoord.x &&
X2 > grid.maxCoord.x ||    -Y < -grid.minCoord.y && -Y2 < -grid.minCoord.y ||
-Y > -grid.maxCoord.y && -Y2 > -grid.maxCoord.y)
{
X2 = X;
Y2 = Y;
continue;
}

if (lineTo)
{
lineToShape.graphics.moveTo(X2, Y2);
lineToShape.graphics.lineTo(X, Y);
} else
{
bresenham(X, Y, X2, Y2, graph.color);
}

X2 = X;
Y2 = Y;
}
}
if (lineTo)
{
graphsData.draw(lineToShape);
lineToShape.graphics.clear();
}
graphsData.unlock();
}

// Saqoosha's Bresenham's Line (modified)
public function bresenham(x0:int, y0:int, x1:int, y1:int, color:uint):void
{
var steep:Boolean = Math.abs(y1 - y0) > Math.abs(x1 - x0);
var tmp:int;
if (steep)
{
tmp = x0;
x0 = y0;
y0 = tmp;
tmp = x1;
x1 = y1;
y1 = tmp;
}
if (x0 > x1)
{
tmp = x0;
x0 = x1;
x1 = tmp;
tmp = y0;
y0 = y1;
y1 = tmp;
}
var deltax:int = x1 - x0;
var deltay:int = Math.abs(y1 - y0);
var error:int = deltax >> 1;
var ystep:int;
var b:int = y0;
if (y0 < y1)
{
ystep = 1;
} else
{
ystep = -1;
}
for (var a:int = x0; a <= x1; a++)
{
if (steep)
{
graphsData.setPixel32(b, a, color);
} else
{
graphsData.setPixel32(a, b, color);
}
error = error - deltay;
if (error < 0)
{
b = b + ystep;
error = error + deltax;
}
}

}

// Variables
private function updateVar(a:String = "x", c:String = "0"):void
{
var
i:int = -1,
l:int = vars.length;
while (++i < l)
{
if (a == vars[i].a)
{
vars[i].c = c;
return
}
}
}

public function findVar(name:String = "x"):Number
{
if (Number(name)) return Number(name);

var
i:int = -1,
l:int = vars.length;

while (++i < l)
{
if (name == vars[i].a)
{
return Number(vars[i].c);
}
}
return 0;
}

}

}

//package
//{
/**
* ...
* @author Thi
*/
/*public*/ class Settings
{
public var
w:Number,
h:Number;
}

//}

//package
//{
/**
* ...
* @author Thi
*/
/*public*/ class Var
{

public var // calculation
a:String, // y
b:String, // =
c:String; // 0

public function Var(a:String = "y", b:String = " = ", c:String = "0")
{
this.a = a;
this.b = b;
this.c = c;
}
}

//}

//package
//{
import flash.display.BitmapData;
import flash.display.Graphics;
import flash.display.Shape;
import flash.geom.Point;
/**
* ...
* @author Thi
*/
/*public*/ class Point2
{

public var // calculation
a:String, // x
b:String, // ,
c:String, // y
color:Number,
data:BitmapData = new BitmapData(9,9, true, 0xFFFFFF);

public function Point2(a:String = "x", b:String = ", ", c:String = "y", color:uint = 0)
{
var
s:Shape = new Shape(),
g:Graphics = s.graphics;

this.a = a;
this.b = b;
this.c = c;
this.color = color;

g.beginFill(color, .2);
g.drawCircle(5, 5, 4);
g.endFill();
data.draw(s);

g.clear();
s = null;
}

}

//}

//package
//{

/**
* ...
* @author Thi
*/
/*public*/ class Function2
{
public var // calculation
a:String, // y
b:String, // =
c:String, // x
array:Array,
preventError:Boolean;

public var // settings
activated:Boolean = true,
cache:Boolean; // consider chaching when graph scrool

private var
vars:Vector.<Var>;

public function Function2(a:String, b:String, c:String):void
{
this.a = a;
this.b = b;
this.c = c;

/*
title.defaultTextFormat = lib[0];
title.type = "input";
title.text = "y";
title.autoSize = TextFieldAutoSize.LEFT;
title.width = title.width;
title.autoSize = TextFieldAutoSize.NONE;
title.textColor = 0xFFFFFF;
title.multiline = false;
*/
}

}
//}

//package
//{

/**
* ...
* @author Thi
*/
/*public*/ class Graph
{
public var // calculation
a:String, // x
b:String, // ,
c:String; // y

public var // settings
cache:Boolean; // consider caching when graph scrool

public var
pointsx:Vector.<Number> = new Vector.<Number>(465, true),
pointsy:Vector.<Number> = new Vector.<Number>(465, true),
pointsx2:Vector.<Number> = new Vector.<Number>(465, true),
pointsy2:Vector.<Number> = new Vector.<Number>(465, true),
j:int,
target1:Var, target2:Var,
nans:Vector.<Boolean> = new Vector.<Boolean>(465, true);

public var
src:Array,
color:uint;

public function Graph(a:String, b:String, c:String, color:uint = 0xFFFF0000, source:Array = null):void
{
this.a = a;
this.b = b;
this.c = c;
this.color = color;
this.src = source;
}

public function setTarget():void
{
var
i:int = -1, l:int = src[0].length;
trace("procurando targets..", a, c)

if (Number(a) || a == "0")
{
target1 = null;
} else
{
while (++i < l)
{
if (src[0][i].a == a)
{
target1 = src[0][i];
}
}
}
i = -1;
if (Number(c) || c == "0")
{
target2 = null;
} else
{
while (++i < l)
{
if (src[0][i].a == c)
{
target2 = src[0][i];
}
}
}
}

public function recivePoints():void
{
var grid:Grid = src[5];
++j;
pointsx2[j] = search(a, 0);
pointsy2[j] = search(c, 1);
if (!Number(pointsx2[j]) && pointsx2[j] != 0 || !Number(pointsy2[j]) && pointsy2[j] != 0)
{
// we se who is NaN, then we dont draw.
nans[j] = true;
pointsx[j] = 0;
pointsx2[j] = 0;
pointsy[j] = 0;
pointsy2[j] = 0;
} else
{
nans[j] = false;
}
pointsx2[j] = pointsx2[j] / grid.step.x - grid.ms.x;
pointsy2[j] = -(pointsy2[j] / grid.step.y + grid.ms.y);
}

private function search(iten:String = "x", index:int = 0):Number
{
if (Number(iten) || iten == "0") return Number(iten);

if (index == 0)
{
return Number(target1.c);
} else
{
return Number(target2.c);
}
return NaN;
}

public function pointsEase(ease:Number = 1):void
{
var i:int = -1;
while (++i < 465)
{
pointsx[i] += (pointsx2[i] - pointsx[i]) * ease;
pointsy[i] += (pointsy2[i] - pointsy[i]) * ease;
}
}

}
//}

//package
//{
import flash.display.Graphics;
import flash.display.Sprite;
import flash.geom.Rectangle;
/**
* ...
* @author Thi
*/
/*public*/ class Panel2 extends Sprite
{
public var
r:Rectangle,
r2:Rectangle,
easying:Number,
iterations:int,
iterations2:int,
activated:Boolean;

public var
g:Graphics,
texts:Vector.<Text2> = new Vector.<Text2>(),
textsGround:Sprite = new Sprite();

public function Panel2(r:Rectangle = null, ease:Number = .5, iterations:int = 10)
{
this.r = r;
this.easying = ease;
this.iterations2 = iterations;
r2 = new Rectangle(r.x, r.y, r.width, r.height);

this.cacheAsBitmap = true;
g = this.graphics;
textsGround.x = r.x;
textsGround.y = r.y;

draw();
active();
}

public function draw():void
{
g.clear();
g.beginFill(0, .8);
g.drawRect(r.x, r.y, r.width, r.height);
g.endFill();
textsGround.x = r.x;
textsGround.y = r.y;
}

{
texts.push(text);
text.y = (texts.length - 1) * (text.ta.height - 4) - 2;
}

public function active():void
{
if (activated)
{
textsGround.visible = true;
} else
{
textsGround.visible = false;
}
}

}

//}

//package
//{
import flash.display.Sprite;
import flash.display.Shape
import flash.text.TextField;
import flash.display.Graphics;
import flash.text.TextFieldAutoSize;
import flash.geom.Point;
/**
* ...
* @author Thi
*/
/*public*/ class Calculator
{
public var
src:Array, preventError:Boolean;

private var
char:String, // used by several methods
e2:Array, e3:Array; // arrays, used by the #2 method

public function translate(expression:String = null):Array
{
var
// storage
s:String = expression,
e:Array = [], num:Array = [],
// loops
i:int = 0, j:int = 0,
// Other
length:int = s.length, last:String = "";
char = "";

preventError = false;

while ( i < length)
{
char = s.charAt(i);
if (Number(char) || char == "0")
{
// whos 'is' in the left of the char
last = e[e.length - 1];
if (last == ")")
{
e.push("*");
}

// we build the number, by each character
j = i;
while (Number(char) || char == "," || char == "." || char == "0")
{
num.push(char)
++j
char = s.charAt(j)
}
if (last == "-")
{
last = e[e.length - 2];
if (last == "+" || last == "-" || last == "*" || last == "/" || last == "^" ||
last == "(" || last == null)
{
// 2,*,-,1 -> 2,*,-1
e[e.length-1] = String(0-Number(num.join("")));
} else
{
e.push(num.join(""));
}
} else
{
e.push(num.join(""));
}
num = [];
i = j-1;
j = 0;

} else if (char == "*" || char == "+" || char == "-" || char == "/" || char == "^")
{
// push all operators
e.push(char);

} else if (char == "." || char == ",")
{
// create a decimal, example: .2 -> 0.2
num.push("0");
num.push(".");
//
j = i;
if (Number(char) || char == "0")
{
while (Number(char) || char == "0")
{
num.push(char);
++j;
char = s.charAt(j);
}
e.push(num.join(""));
i = j - 1;
num = [];
j = 0;
}

} else if (char == "(" || char == "[" || char == "{")
{
preventError = true
// take the last element
last = e[e.length - 1]

// if last cahr is different of an operator or 'function that uses ()'
if (last != "+" && last != "-" && last != "*" && last != "/" && last != "^" &&
last != "undefined" && last != null && last != "sin" && last != "cos" &&
last != "tan" && last != "log" && last != "asin" &&    last != "acos" &&
last != "atan" && last != "round" && last != "floor" &&
last != "ceil" && last != "exp" && last != "sqrt" && last != "abs")

{
e.push("*")
}
e.push("(")
// 2(x -> 2 * (x

} else if (char == "¹")
{
// ¹ ->

} else if (char == "²")
{
// ² -> ^ 2
e.push("^")
e.push("2")

} else if (char == "³")
{
// ³ -> ^ 3
e.push("^")
e.push("3")

} else if (char == ")" || char == "]" || char == "}")
{
// )]} -> )))
e.push(")")

} else if (char != " ")
{
last = e[e.length -1]
if (last != "+" && last != "-" && last != "*" && last != "/" && last != "^" &&
last != "undefined" && last != null && last != "(")
{
e.push("*")
// y x -> y * x
}
j = i
while (char != "," && char != "." && char != "+" && char != "-" && char != "*" && char != "/" && char != "^" && char != "(" && char != "[" && char != "{" && char != ")" && char != "]" && char != "}" && char != " " && char != null && char != "undefined" && char != "" && char != "¹" && char != "²" && char != "³")
{
num.push(char)
++j;
char = s.charAt(j)
}
// we just formed an word, char by char.

var temp:String = num.join("")
if (temp == "sen" || temp == "sine" || temp == "seno")
{
temp = "sin"
} else if (temp == "cosseno" || temp == "cossine")
{
temp = "cos"
} else if (temp == "tangent" || temp == "tangente" || temp == "tgt" || temp == "tg")
{
temp = "tan"
} else if (temp == "E")
{
temp = "e"
} else if (temp == "PI")
{
temp = "pi"
} else if (temp == "absoluto" || temp == "modulo" || temp == "absolute")
{
temp = "abs"
} else if (temp == "aleatorio")
{
temp = "random"
} else if (temp == "raiz" || temp == "raíz" || temp == "squareroot" || temp == "root")
{
temp = "sqrt"
}
e.push(temp)
num = []
temp = ""
i = j-1
}
++i
}
return e;
}

public function rpn(elements:Array = null, PreventError:Boolean = false):Array
{
e2 = []; // temp elements
e3 = []; // final (returned) elements
char = "";

var
e:Array = elements.concat(), // initial elements
i:int = 0, j:int = 0,
length:int = e.length;
preventError = PreventError;

while (i < length)
{
char = e[i];
if (Number(char) || char == "0")
{
e3.push(char)
} else if (char == "(")
{
e2.push(char)
} else if (char == "+" || char == "-" || char == "*" || char == "/" || char == "^" ||
char == "sin" || char == "cos" || char == "tan" || char == "acos" || char == "asin" ||
char == "atan" || char == "round" || char == "floor" ||
char == "ceil" || char == "log" || char == "exp" || char == "sqrt" || char == "abs"  )
{
e2.push(char)
// call a function that organizes the order
OperatorLevel() // send the e2 and e3 local vars
}  else if (char == ")")
{
e2.push(char)
CloseParantesis()
} else
{
e3.push(char)
}
++i
}

// now add 'calculation' array (reverse) to the result array
j = e2.length
while (j > 0)
{
if (e2[j - 1] != "")
{
e3.push(e2[j-1])
}
--j
}

return e3;
}

private function OperatorLevel():void
{
var
level1:int, level2:int;

if (char == "+" || char == "-")
{
level1 = 1;
} else if (char == "*" || char == "/")
{
level1 = 2;
} else if (char == "^")
{
level1 = 4;
} else if (char == "sin" || char == "cos" || char == "tan" || char == "asin" ||
char == "acos" || char == "atan" || char == "round" || char == "floor" || char == "ceil" ||
char == "log" || char == "exp" || char == "sqrt" || char == "abs")
{
level1 = 8
}
if (e2[e2.length - 2] == "+" || e2[e2.length - 2] == "-")
{
level2 = 1;
} else if (e2[e2.length - 2] == "*" || e2[e2.length - 2] == "/")
{
level2 = 2;
} else if (e2[e2.length - 2] == "^")
{
level2 = 3;
} else if (e2[e2.length - 2] == "sin" || e2[e2.length - 2] == "cos" || e2[e2.length - 2] == "tan" ||
e2[e2.length - 2] == "asin" || e2[e2.length - 2] == "acos" || e2[e2.length - 2] == "atan" ||
e2[e2.length - 2] == "round" || e2[e2.length - 2] == "floor" || e2[e2.length - 2] == "ceil" ||
e2[e2.length - 2] == "log" || e2[e2.length - 2] == "exp" || e2[e2.length - 2] == "sqrt" ||
e2[e2.length - 2] == "abs")
{
level2 = 4;
} else
{
level2 = 0;
}
if (level1 <= level2)
{
e3.push(e2[e2.length-2]);
e2.splice(e2.length - 2, 1);
// repeats
OperatorLevel();
}
}

private function CloseParantesis():void
{
if (e2[e2.length - 2] != "(")
{
e3.push(e2[e2.length - 2])
e2.splice(e2.length - 2, 1)
if (preventError)
{
CloseParantesis();
}
} else
{
e2.splice(e2.length-2,2)
}
}

public function calculate(elements:Array = null):Number
{
var
e:Array = elements.concat(),
n0:Boolean, n1:Boolean,
i:int, j:int, l:int,
num:Number;
char = "";

while (i < e.length)
{
char = e[i];
//{

if (char == "+")
{
e[i] = Number(e[i - 2]) + Number(e[i - 1]);
e.splice(i - 2, 2);
--i; --i;
} else if (char == "-")
{
if (Number(e[i - 2]))
{
e[i] = Number(e[i - 2]) - Number(e[i - 1]);
e.splice(i - 2, 2);
} else if (e[i - 2] == "0")
{
e[i] = - Number(e[i - 1]);
e.splice(i - 2, 2);
} else
{
e[i] = - Number(e[i - 1]);
e.splice(i - 1, 1);
}
--i; --i;
} else if (char == "*")
{
e[i] = Number(e[i - 2]) * Number(e[i - 1]);
e.splice(i - 2, 2);
--i; --i;
} else if (char == "/")
{
e[i] = Number(e[i - 2]) / Number(e[i - 1]);
e.splice(i - 2, 2);
--i; --i;
} else if (char == "^")
{
e[i] = Math.pow(Number(e[i - 2]) , Number(e[i - 1]));
e.splice(i - 2, 2);
--i; --i;
} else if (!Number(char) && char != "0")
{
if (char == "sin")
{
e[i] = Math.sin(Number(e[i - 1]));
e.splice(i - 1, 1);
--i;
} else if (char == "cos")
{
e[i] = Math.cos(Number(e[i - 1]));
e.splice(i - 1, 1);
--i;
} else if (char == "tan")
{
e[i] = Math.tan(Number(e[i - 1]));
e.splice(i - 1, 1);
--i;
} else if (char == "asin")
{
num = Number(e[i - 1]);
if (num * num <= 1)
{
e[i] = Math.asin( num );
} else
{
e[i] = 0;
}
e.splice(i - 1, 1);
--i;
} else if (char == "acos")
{
num = Number(e[i - 1]);
if (num * num <= 1)
{
e[i] = Math.acos( num );
} else
{
e[i] = 0;
}
e.splice(i - 1, 1);
--i;
} else if (char == "atan")
{
e[i] = Math.atan(Number(e[i - 1]));
e.splice(i - 1, 1);
--i;
} else if (char == "random")
{
e[i] = Math.random();
--i;
} else if (char == "pi")
{
e[i] = Math.PI;
--i;
} else if (char == "e")
{
e[i] = Math.E;
--i;
} else if (char == "round")
{
e[i] = Math.round(Number(e[i - 1]));
e.splice(i - 1, 1);
--i;
} else if (char == "floor")
{
e[i] = Math.floor(Number(e[i - 1]));
e.splice(i - 1, 1);
--i;
} else if (char == "ceil")
{
e[i] = Math.ceil(Number(e[i - 1]));
e.splice(i - 1, 1);
--i;
} else if (char == "log")
{
e[i] = Math.log(Number(e[i - 1]));
e.splice(i - 1, 1);
--i;
} else if (char == "exp")
{
e[i] = Math.exp(Number(e[i - 1]));
e.splice(i - 1, 1);
--i;
} else if (char == "sqrt")
{
e[i] = Math.sqrt(Number(e[i - 1]));
e.splice(i - 1, 1);
--i;
} else if (char == "abs")
{
e[i] = Math.abs(Number(e[i - 1]));
e.splice(i - 1, 1);
--i;
} else
{
// ITS A WORD, we search in the libraly for it
//var found:Boolean;
j = -1;
l = src[0].length
while (++j < l)
{
if (char == src[0][j].a)
{
e[i] = src[0][j].c;
--i
//found = true;
break;
}
}
// the index of the value has been found (--j)
if (--j == 0 && src[0][0].c != char)
{
++i
}
}
}

++i
if (e.length == 1)
{
return Number(e[0]);
}
}
return NaN;
}

}
//}

//package
//{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Graphics;
import flash.display.Shape;
import flash.display.Sprite;
import flash.geom.Point;
/**
* ...
* @author Thi
*/
/*public*/ class Grid extends Sprite
{
public var
sets:Settings;

public var
data:BitmapData,
bm:Bitmap;

public var
min:Point,
max:Point,
d:Point,
step:Point,
stepBack:Point,
ms:Point, // min / step
minCoord:Point = new Point(),
maxCoord:Point = new Point();

public var
velo:Point, // velocity
old:Point; // old position

public function draw():void
{

var
i:int = -1,
s:Shape = new Shape(),
g:Graphics = s.graphics;
var
n:Number,
n2:Number;

// draw vertical lines
n = Math.floor(((min.x - 1) / stepBack.x)) * stepBack.x,
n2 = sets.w / d.x;
g.lineStyle(1, 0, .2, true);
while (n <= max.x)
{
n += stepBack.x;
g.moveTo((n - min.x) * n2, 0);
g.lineTo((n - min.x) * n2, sets.h);
}
g.lineStyle(2, 0, 1, true); // zero vertical line
g.moveTo( -min.x * n2, 0);
g.lineTo( -min.x * n2, sets.h);

// horizontal lines
n = Math.ceil(min.y / stepBack.y) * stepBack.y;
n2 = sets.h / d.y;
g.lineStyle(1, 0, .2, true);
while (n < max.y)
{
n += stepBack.y;
g.moveTo(0,(n - min.y) * n2);
g.lineTo(sets.w,(n - min.y) * n2)
}
g.lineStyle(2, 0, 1, true); // zero horizontal line
g.moveTo(0, ( -min.y) * n2);
g.lineTo(sets.w, ( -min.y) * n2);

data.lock();
data.fillRect(data.rect, 0xFFFFFF);
data.draw(s);
data.unlock();
g.clear();
s = null;
}

public function walk():void
{

}

}

//}

//package
//{
import flash.display.Sprite;
import flash.events.Event;
import flash.events.FocusEvent;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
/**
* ...
* @author Thi
*/
/*public*/ class Text2 extends Sprite
{
public var
type:String,
index:int;

public var
a:String,
b:String,
c:String,
ta:TextField,
tb:TextField,
tc:TextField;

public var
src:Array,
f:TextFormat,
w:Number,
count:int = -1,
focus:Boolean,
a2:String,
c2:String,
thisW:Number;

public function Text2(source:Array = null, type:String = "", index:int = 0,
format:TextFormat = null)
{
this.src = source;
this.type = type;
this.index = index;
this.f = format;

if (type == "func")
{
a = src[2][index].a;
b = src[2][index].b;
c = src[2][index].c;
w = src[4][0].r.width;
} else if (type == "graph")
{
a = src[3][index].a;
b = src[3][index].b;
c = src[3][index].c;
w = src[4][1].r.width;
} else if (type == "var")
{
a = src[0][index].a;
b = src[0][index].b;
c = src[0][index].c;
w = src[4][2].r.width;
} else if (type == "point")
{
a = src[1][index].a;
b = src[1][index].b;
c = src[1][index].c;
w = src[4][3].r.width;
}

a2 = a;
c2 = c;

ta = new TextField();
ta.defaultTextFormat = f;
ta.type = "input";
ta.text = a;
ta.autoSize = TextFieldAutoSize.LEFT;
ta.width = ta.width;
ta.autoSize = TextFieldAutoSize.NONE;
ta.textColor = 0xFFFFFF;
ta.multiline = false;

tb = new TextField();
tb.defaultTextFormat = f;
tb.selectable = false;
tb.text = b;
tb.autoSize = TextFieldAutoSize.LEFT;
tb.width = tb.width;
tb.autoSize = TextFieldAutoSize.NONE;
tb.textColor = 0xFFFFFF;
tb.multiline = false;

tc = new TextField();
tc.defaultTextFormat = f;
tc.type = "input";
tc.text = c;
tc.autoSize = TextFieldAutoSize.LEFT;
tc.width = tc.width;
tc.autoSize = TextFieldAutoSize.NONE;
tc.textColor = 0xFFFFFF;
tc.multiline = false;

var w2:Number = w - tb.width;
if (ta.width + tb.width + tc.width > w)
{
// we make the width smaller
if (ta.width > w2 >> 1)
{
ta.width = w2 >> 1;
}
if (tc.width > w2 >> 1)
{
tc.width = w2 >> 1;
}
}

tb.x = ta.width;
tc.x = tb.x + tb.width;
thisW = ta.width + tb.width + tc.width;

widthUpdate()
}

private function focusIn(e:FocusEvent):void
{
if (count < 0)
{
}
focus = true;
}

private function focusOut(e:FocusEvent):void
{
focus = false;
}

private function ef(e:Event):void
{
--count;
if (ta.text != a2 || tc.text != c2)
{
// will update
a2 = a = ta.text;
c2 = c = tc.text;
count = 10;
widthUpdate()
return;
}
if (count == 1)
{
// the update process
if (type == "func")
{
src[2][index].a = a;
src[2][index].c = c;
} else if (type == "graph")
{
trace(src[3][index].a, src[3][index].c)
src[3][index].a = a;
src[3][index].c = c;
trace(src[3][index].a, src[3][index].c)
} else if (type == "var")
{
src[0][index].a = a;
src[0][index].c = c;
} else if (type == "point")
{
src[1][index].a = a;
src[1][index].c = c;
}
}
if (focus && count < 0)
{
// updated, but on focus
count = 0;
return;
}
if (count == -1)
{
// updated and out of focus
this.removeEventListener(Event.ENTER_FRAME, ef);
}

}

private function widthUpdate():void
{
ta.autoSize = TextFieldAutoSize.LEFT;
ta.width = ta.width;
ta.autoSize = TextFieldAutoSize.NONE;

tc.autoSize = TextFieldAutoSize.LEFT;
tc.width = tc.width;
tc.autoSize = TextFieldAutoSize.NONE;

thisW = ta.width + tb.width + tc.width;

var i:int = -1, l:int, n:Number;
if (type == "graph")
{
if (src[4][1].r2.width <= thisW)
{
src[4][1].r2.width = thisW;
} else
{
l = src[4][1].texts.length;
while (++i < l)
{
if (src[4][1].texts[i].thisW > thisW)
{

}
}
}
} else if (type == "point")
{
if (src[4][3].r2.width <= ta.width + tb.width + tc.width)
{
src[4][3].r2.width = ta.width + tb.width + tc.width;
} else
{

}
} else
{
var w2:Number = w - tb.width;
if (ta.width + tb.width + tc.width > w)
{
// we make the width smaller
if (ta.width > w2 >> 1)
{
ta.width = w2 >> 1;
}
if (tc.width > w2 >> 1)
{
tc.width = w2 >> 1;
}
ta.border = true;
tc.border = true;
} else
{
ta.border = false;
tc.border = false;
tc.width = w2 - ta.width;
}
}

tb.x = ta.width;
tc.x = tb.x + tb.width;
}
}

//}

//package
//{
import flash.display.Graphics;
import flash.display.Sprite;
import flash.geom.Point;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
/**
* ...
* @author Thi
*/
/*public*/ class Ballon extends Sprite
{
private var lib:Array;
public var
title:TextField = new TextField(),
src:Array;

private var
X:Number = 0, Y:Number = 0,
w:Number = 465, h:Number = 465;

public var
delay:int,
target:Point = new Point();

public function Ballon(lib:Array = null, source:Array = null)
{
this.lib = lib;
this.src = source;

var g:Graphics = this.graphics;
title.defaultTextFormat = lib[1];
title.selectable = false;
title.text = "Hello, I'm ballon";
title.autoSize = TextFieldAutoSize.LEFT;
title.textColor = 0xFFFFFF;
}

public function move():void
{
this.x += (target.x - this.x) * .5
this.y += (target.y - this.y) * .5
}

public function update():void
{

if (target.x + title.width + 17 > src[4][3].r.x)
{
target.x = (target.x - title.width ) - 17
} else
{
target.x += 15;
}
if (target.y + title.height + 17 > src[4][2].r.y)
{
target.y = (target.y - title.height) - 17
} else
{
target.y += 15;
}

if (target.x < src[4][1].r.width + 2)
{
target.x = src[4][1].r.width + 2;
} else if (target.x + title.width > src[4][3].r.x - 2)
{
target.x = src[4][3].r.x - title.width - 2;
}
if (target.y < src[4][0].r.height + 2)
{
target.y = src[4][0].r.height + 2;
} else if (target.y + title.height > src[4][2].r.y - 2)
{
target.y = src[4][2].r.y - title.height - 2;
}

var g:Graphics = this.graphics;
g.clear();
g.beginFill(0x000000, .8);
g.drawRoundRect( -2, -2, title.width + 4, title.height + 4, 10, 10);
g.endFill();
}
}
//}
```