<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>.gitignore</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -1,1966 +1,2116 @@
 /*
- * Processing.js - John Resig (http://ejohn.org/)
- * MIT Licensed
- * http://ejohn.org/blog/processingjs/
- *
- * This is a port of the Processing Visualization Language.
- * More information: http://processing.org/
- */
 
-(function(){
-this.Processing = function Processing( aElement, aCode) {
-
-  if ( typeof aElement == &quot;string&quot; )
-    aElement = document.getElementById( aElement );
-    
-  var p = buildProcessing( aElement );  
-
-  if ( aCode )
-    p.init( aCode );
+  P R O C E S S I N G . J S
+  a port of the Processing visualization language
+  
+  License       : MIT 
+  Developer     : John Resig - eJohn.org
+  Web Site      : http://processingjs.org  
+  Java Version  : http://processing.org
+  Github Repo.  : http://github.com/jeresig/processing-js
+  Mozilla POW!  : http://wiki.Mozilla.org/Education/Projects/ProcessingForTheWeb
+  Maintained by : F1LT3R &amp; the students of Open Seneca...
+                  http://zenit.senecac.on.ca/wiki/index.php/Processing.js
 
-  return p;
-};
+*/
 
-function log() {
-  try {
-    console.log.apply( console, arguments );
-  } catch(e) {
-    try {
-      opera.postError.apply( opera, arguments );
-    } catch(e){}
-  }
-}
 
-var parse = Processing.parse = function parse( aCode, p ) {
-  // Angels weep at this parsing code :-(
+(function(){
+  
 
-  // Remove end-of-line comments
-  aCode = aCode.replace(/\/\/ .*\n/g, &quot;\n&quot;);
+  // Attach Processing to the window 
+  this.Processing = function Processing( aElement, aCode ){
 
-  // Weird parsing errors with %
-  aCode = aCode.replace(/([^\s])%([^\s])/g, &quot;$1 % $2&quot;);
- 
-  // Simple convert a function-like thing to function
-  aCode = aCode.replace(/(?:static )?(\w+ )(\w+)\s*(\([^\)]*\)\s*{)/g, function(all, type, name, args) {
-    if ( name == &quot;if&quot; || name == &quot;for&quot; || name == &quot;while&quot; ) {
-      return all;
-    } else {
-      return &quot;Processing.&quot; + name + &quot; = function &quot; + name + args;
+    // Get the DOM element if string was passed
+    if( typeof aElement == &quot;string&quot; ){
+      aElement = document.getElementById( aElement );
     }
-  });
+      
+    // Build an Processing functions and env. vars into 'p'  
+    var p = buildProcessing( aElement );  
+
+    // Send aCode Processing syntax to be converted to JavaScript
+    if( aCode ){ p.init( aCode ); }
     
-  // Attach import() to p{} bypassing JS command, allowing for extrernal library loading
-  aCode = aCode.replace(/import \(|import\(/g, &quot;p.Import(&quot;);
+    return p;
+    
+  };
   
-  // Force .length() to be .length
-  aCode = aCode.replace(/\.length\(\)/g, &quot;.length&quot;);
-
-  // foo( int foo, float bar )
-  aCode = aCode.replace(/([\(,]\s*)(\w+)((?:\[\])+| )\s*(\w+\s*[\),])/g, &quot;$1$4&quot;);
-  aCode = aCode.replace(/([\(,]\s*)(\w+)((?:\[\])+| )\s*(\w+\s*[\),])/g, &quot;$1$4&quot;);
-
-  // float[] foo = new float[5];
-  aCode = aCode.replace(/new (\w+)((?:\[([^\]]*)\])+)/g, function(all, name, args) {
-    return &quot;new ArrayList(&quot; + args.slice(1,-1).split(&quot;][&quot;).join(&quot;, &quot;) + &quot;)&quot;;
-  });
+  // Auto-load Processing sketches
+  addEventListener( 'DOMContentLoaded', USInit, false );
   
-  aCode = aCode.replace(/(?:static )?\w+\[\]\s*(\w+)\[?\]?\s*=\s*{.*?};/g, function(all) {
-    return all.replace(/{/g, &quot;[&quot;).replace(/}/g, &quot;]&quot;);
-  });
-
-  // int|float foo;
-  var intFloat = /(\n\s*(?:int|float)(?:\[\])?(?:\s*|[^\(]*?,\s*))([a-z]\w*)(;|,)/i;
-  while ( intFloat.test(aCode) ) {
-    aCode = aCode.replace(new RegExp(intFloat), function(all, type, name, sep) {
-      return type + &quot; &quot; + name + &quot; = 0&quot; + sep;
-    });
+  // IE Unfriendly AJAX Method
+  var ajax=function( url ){
+    var AJAX;
+    if( AJAX = new XMLHttpRequest() ){
+      AJAX.open( &quot;GET&quot;, url, false );
+      AJAX.send( null );
+      return AJAX.responseText;
+    }else{
+      return false;
+    }
   }
+ 
+  // Parse Processing (Java-like) syntax to JavaScript syntax with Regex
+  var parse = Processing.parse = function parse( aCode, p ){
 
-  // float foo = 5;
-  aCode = aCode.replace(/(?:static )?(\w+)((?:\[\])+| ) *(\w+)\[?\]?(\s*[=,;])/g, function(all, type, arr, name, sep) {
-    if ( type == &quot;return&quot; )
-      return all;
-    else
-      return &quot;var &quot; + name + sep;
-  });
-
-  // Fix Array[] foo = {...} to [...]
-  aCode = aCode.replace(/=\s*{((.|\s)*?)};/g, function(all,data) {
-    return &quot;= [&quot; + data.replace(/{/g, &quot;[&quot;).replace(/}/g, &quot;]&quot;) + &quot;]&quot;;
-  });
-  
-  // static { ... } blocks
-  aCode = aCode.replace(/static\s*{((.|\n)*?)}/g, function(all, init) {
-    // Convert the static definitons to variable assignments
-    //return init.replace(/\((.*?)\)/g, &quot; = $1&quot;);
-    return init;
-  });
+    // Remove end-of-line comments
+    aCode = aCode.replace( /\/\/ .*\n/g, &quot;\n&quot; );
 
-  // super() is a reserved word
-  aCode = aCode.replace(/super\(/g, &quot;superMethod(&quot;);
+    // Weird parsing errors with %
+    aCode = aCode.replace( /([^\s])%([^\s])/g, &quot;$1 % $2&quot; );
+   
+    // Simple convert a function-like thing to function
+    aCode = aCode.replace( /(?:static )?(\w+ )(\w+)\s*(\([^\)]*\)\s*{)/g, function( all, type, name, args ){
+      if ( name == &quot;if&quot; || name == &quot;for&quot; || name == &quot;while&quot; ) {
+        return all;
+      } else {
+        return &quot;Processing.&quot; + name + &quot; = function &quot; + name + args;
+      }
+    });
+      
+    // Attach import() to p{} bypassing JS command, allowing for extrernal library loading
+    aCode = aCode.replace( /import \(|import\(/g, &quot;p.Import(&quot; );
+    
+    // Force .length() to be .length
+    aCode = aCode.replace( /\.length\(\)/g, &quot;.length&quot; );
 
-  var classes = [&quot;int&quot;, &quot;float&quot;, &quot;boolean&quot;, &quot;string&quot;];
+    // foo( int foo, float bar )
+    aCode = aCode.replace( /([\(,]\s*)(\w+)((?:\[\])+| )\s*(\w+\s*[\),])/g, &quot;$1$4&quot; );
+    aCode = aCode.replace( /([\(,]\s*)(\w+)((?:\[\])+| )\s*(\w+\s*[\),])/g, &quot;$1$4&quot; );
 
-  function ClassReplace(all, name, extend, vars, last) {
-    classes.push( name );
+    // float[] foo = new float[5];
+    aCode = aCode.replace( /new (\w+)((?:\[([^\]]*)\])+)/g, function( all, name, args ){
+      return &quot;new ArrayList(&quot; + args.slice(1,-1).split(&quot;][&quot;).join(&quot;, &quot;) + &quot;)&quot;;
+    });
+    
+    // What does this do?
+    aCode = aCode.replace( /(?:static )?\w+\[\]\s*(\w+)\[?\]?\s*=\s*{.*?};/g, function( all ){
+      return all.replace( /{/g, &quot;[&quot;).replace(/}/g, &quot;]&quot; );
+    });
 
-    var static = &quot;&quot;;
+    // int|float foo;
+    var intFloat = /(\n\s*(?:int|float)(?:\[\])?(?:\s*|[^\(]*?,\s*))([a-z]\w*)(;|,)/i;
+    while( intFloat.test(aCode) ){
+      aCode = aCode.replace( new RegExp( intFloat ), function( all, type, name, sep ){
+        return type + &quot; &quot; + name + &quot; = 0&quot; + sep;
+      });
+    }
 
-    vars = vars.replace(/final\s+var\s+(\w+\s*=\s*.*?;)/g, function(all,set) {
-      static += &quot; &quot; + name + &quot;.&quot; + set;
-      return &quot;&quot;;
+    // float foo = 5;
+    aCode = aCode.replace( /(?:static )?(\w+)((?:\[\])+| ) *(\w+)\[?\]?(\s*[=,;])/g, function( all, type, arr, name, sep ){
+      if ( type == &quot;return&quot; )
+        return all;
+      else
+        return &quot;var &quot; + name + sep;
     });
 
-    // Move arguments up from constructor and wrap contents with
-    // a with(this), and unwrap constructor
-    return &quot;function &quot; + name + &quot;() {with(this){\n  &quot; +
-      (extend ? &quot;var __self=this;function superMethod(){extendClass(__self,arguments,&quot; + extend + &quot;);}\n&quot; : &quot;&quot;) +
-      // Replace var foo = 0; with this.foo = 0;
-      // and force var foo; to become this.foo = null;
-      vars
-        .replace(/,\s?/g, &quot;;\n  this.&quot;)
-        .replace(/\b(var |final |public )+\s*/g, &quot;this.&quot;)
-        .replace(/\b(var |final |public )+\s*/g, &quot;this.&quot;)
-        .replace(/this.(\w+);/g, &quot;this.$1 = null;&quot;) + 
-        (extend ? &quot;extendClass(this, &quot; + extend + &quot;);\n&quot; : &quot;&quot;) +
-        &quot;&lt;CLASS &quot; + name + &quot; &quot; + static + &quot;&gt;&quot; + (typeof last == &quot;string&quot; ? last : name + &quot;(&quot;);
-  }
+    // Fix Array[] foo = {...} to [...]
+    aCode = aCode.replace( /=\s*{((.|\s)*?)};/g, function(all,data){
+      return &quot;= [&quot; + data.replace(/{/g, &quot;[&quot;).replace(/}/g, &quot;]&quot;) + &quot;]&quot;;
+    });
+    
+    // super() is a reserved word
+    aCode = aCode.replace( /super\(/g, &quot;superMethod(&quot; );
 
-  var matchClasses = /(?:public |abstract |static )*class (\w+)\s*(?:extends\s*(\w+)\s*)?{\s*((?:.|\n)*?)\b\1\s*\(/g;
-  var matchNoCon = /(?:public |abstract |static )*class (\w+)\s*(?:extends\s*(\w+)\s*)?{\s*((?:.|\n)*?)(Processing)/g;
-  
-  aCode = aCode.replace(matchClasses, ClassReplace);
-  aCode = aCode.replace(matchNoCon, ClassReplace);
+    var classes = [ &quot;int&quot;, &quot;float&quot;, &quot;boolean&quot;, &quot;string&quot; ];
 
-  var matchClass = /&lt;CLASS (\w+) (.*?)&gt;/, m;
-  
-  while ( (m = aCode.match( matchClass )) ) {
-    var left = RegExp.leftContext,
-      allRest = RegExp.rightContext,
-      rest = nextBrace(allRest),
-      className = m[1],
-      staticVars = m[2] || &quot;&quot;;
+    function ClassReplace( all, name, extend, vars, last ){
       
-    allRest = allRest.slice( rest.length + 1 );
+      classes.push( name );
+
+      var static = &quot;&quot;;
+
+      vars = vars.replace( /final\s+var\s+(\w+\s*=\s*.*?;)/g, function( all, set ){
+        static += &quot; &quot; + name + &quot;.&quot; + set;
+        return &quot;&quot;;
+      });
 
-    rest = rest.replace(new RegExp(&quot;\\b&quot; + className + &quot;\\(([^\\)]*?)\\)\\s*{&quot;, &quot;g&quot;), function(all, args) {
-      args = args.split(/,\s*?/);
+      // Move arguments up from constructor and wrap contents with
+      // a with(this), and unwrap constructor
+      return &quot;function &quot; + name + &quot;() {with(this){\n  &quot; +
+        ( extend ? &quot;var __self=this;function superMethod(){extendClass(__self,arguments,&quot; + extend + &quot;);}\n&quot; : &quot;&quot; ) +
+        // Replace var foo = 0; with this.foo = 0;
+        // and force var foo; to become this.foo = null;
+        vars
+          .replace( /,\s?/g, &quot;;\n  this.&quot; )
+          .replace( /\b(var |final |public )+\s*/g, &quot;this.&quot; )
+          .replace( /\b(var |final |public )+\s*/g, &quot;this.&quot; )
+          .replace( /this.(\w+);/g, &quot;this.$1 = null;&quot; ) + 
+          ( extend ? &quot;extendClass(this, &quot; + extend + &quot;);\n&quot; : &quot;&quot; ) +
+          &quot;&lt;CLASS &quot; + name + &quot; &quot; + static + &quot;&gt;&quot; + ( typeof last == &quot;string&quot; ? last : name + &quot;(&quot; );
+      }
+
+      var matchClasses = /(?:public |abstract |static )*class (\w+)\s*(?:extends\s*(\w+)\s*)?{\s*((?:.|\n)*?)\b\1\s*\(/g;
+      var matchNoCon = /(?:public |abstract |static )*class (\w+)\s*(?:extends\s*(\w+)\s*)?{\s*((?:.|\n)*?)(Processing)/g;
       
-      if ( args[0].match(/^\s*$/) )
-        args.shift();
+      aCode = aCode.replace( matchClasses, ClassReplace );
+      aCode = aCode.replace( matchNoCon, ClassReplace );
+
+      var matchClass = /&lt;CLASS (\w+) (.*?)&gt;/, m;
       
-      var fn = &quot;if ( arguments.length == &quot; + args.length + &quot; ) {\n&quot;;
+      while ( ( m = aCode.match( matchClass ) ) ){
         
-      for ( var i = 0; i &lt; args.length; i++ ) {
-        fn += &quot;    var &quot; + args[i] + &quot; = arguments[&quot; + i + &quot;];\n&quot;;
-      }
+        var left        = RegExp.leftContext,
+            allRest     = RegExp.rightContext,
+            rest        = nextBrace( allRest ),
+            className   = m[ 1 ],
+            staticVars  = m[ 2 ] || &quot;&quot;;
+          
+        allRest = allRest.slice( rest.length + 1 );
+
+        rest = rest.replace( new RegExp(&quot;\\b&quot; + className + &quot;\\(([^\\)]*?)\\)\\s*{&quot;, &quot;g&quot;), function( all, args ){
+          args = args.split( /,\s*?/ );
+          
+          if( args[ 0 ].match( /^\s*$/ ) ){
+            args.shift();
+          }
+          
+          var fn = &quot;if ( arguments.length == &quot; + args.length + &quot; ) {\n&quot;;
+            
+          for ( var i = 0; i &lt; args.length; i++ ) {
+            fn += &quot;    var &quot; + args[ i ] + &quot; = arguments[&quot;+ i +&quot;];\n&quot;;
+          }
+            
+          return fn;
+        });
         
-      return fn;
-    });
-    
-    // Fix class method names
-    // this.collide = function() { ... }
-    // and add closing } for with(this) ...
-    rest = rest.replace(/(?:public )?Processing.\w+ = function (\w+)\((.*?)\)/g, function(all, name, args) {
-      return &quot;ADDMETHOD(this, '&quot; + name + &quot;', function(&quot; + args + &quot;)&quot;;
-    });
-    
-    var matchMethod = /ADDMETHOD([\s\S]*?{)/, mc;
-    var methods = &quot;&quot;;
-    
-    while ( (mc = rest.match( matchMethod )) ) {
-      var prev = RegExp.leftContext,
-        allNext = RegExp.rightContext,
-        next = nextBrace(allNext);
+        // Fix class method names
+        // this.collide = function() { ... }
+        // and add closing } for with(this) ...
+        rest = rest.replace( /(?:public )?Processing.\w+ = function (\w+)\((.*?)\)/g, function( all, name, args ){
+          return &quot;ADDMETHOD(this, '&quot; + name + &quot;', function(&quot; + args + &quot;)&quot;;
+        });
+        
+        var matchMethod = /ADDMETHOD([\s\S]*?{)/, mc;
+        var methods = &quot;&quot;;
+        
+        while ( ( mc = rest.match( matchMethod ) ) ){
+          var prev    = RegExp.leftContext,
+              allNext = RegExp.rightContext,
+              next    = nextBrace(allNext);
+
+          methods += &quot;addMethod&quot; + mc[ 1 ] + next + &quot;});&quot;;
+          
+          rest = prev + allNext.slice( next.length + 1 );
+        }
 
-      methods += &quot;addMethod&quot; + mc[1] + next + &quot;});&quot;
+        rest = methods + rest;
+        
+        aCode = left + rest + &quot;\n}}&quot; + staticVars + allRest;
+      }
+
+      // Do some tidying up, where necessary
+      aCode = aCode.replace( /Processing.\w+ = function addMethod/g, &quot;addMethod&quot; );
       
-      rest = prev + allNext.slice( next.length + 1 );
-    }
+      function nextBrace( right ) {
 
-    rest = methods + rest;
-    
-    aCode = left + rest + &quot;\n}}&quot; + staticVars + allRest;
-  }
+        var rest      = right,
+            position  = 0,
+            leftCount = 1,
+            rightCount = 0;
+        
+        while( leftCount != rightCount ) {
+        
+        var nextLeft  = rest.indexOf( &quot;{&quot; ),
+            nextRight = rest.indexOf( &quot;}&quot; );
+        
+        if( nextLeft &lt; nextRight &amp;&amp; nextLeft != - 1 ) {
 
-  // Do some tidying up, where necessary
-  aCode = aCode.replace(/Processing.\w+ = function addMethod/g, &quot;addMethod&quot;);
-  
-  function nextBrace( right ) {
-    var rest = right;
-    var position = 0;
-    var leftCount = 1, rightCount = 0;
-    
-    while ( leftCount != rightCount ) {
-      var nextLeft = rest.indexOf(&quot;{&quot;);
-      var nextRight = rest.indexOf(&quot;}&quot;);
-      
-      if ( nextLeft &lt; nextRight &amp;&amp; nextLeft != -1 ) {
-        leftCount++;
-        rest = rest.slice( nextLeft + 1 );
-        position += nextLeft + 1;
-      } else {
-        rightCount++;
-        rest = rest.slice( nextRight + 1 );
-        position += nextRight + 1;
+          leftCount++;
+          rest = rest.slice( nextLeft + 1 );
+          position += nextLeft + 1;
+
+        }else{
+
+          rightCount++;
+          rest = rest.slice( nextRight + 1 );
+          position += nextRight + 1;
+
+        }
+        
       }
+        
+      return right.slice( 0, position - 1 );
     }
-    
-    return right.slice(0, position - 1);
-  }
-
-  // Handle (int) Casting
-  aCode = aCode.replace(/\(int\)/g, &quot;0|&quot;);
 
-  // Remove Casting
-  aCode = aCode.replace(new RegExp(&quot;\\((&quot; + classes.join(&quot;|&quot;) + &quot;)(\\[\\])?\\)&quot;, &quot;g&quot;), &quot;&quot;);
-  
-  // Convert 3.0f to just 3.0
-  aCode = aCode.replace(/(\d+)f[^a-zA-Z0-9]/g, &quot;$1&quot;);
+    // Handle (int) Casting
+    aCode = aCode.replace( /\(int\)/g, &quot;0|&quot; );
 
-  // Force numbers to exist
-  //aCode = aCode.replace(/([^.])(\w+)\s*\+=/g, &quot;$1$2 = ($2||0) +&quot;);
+    // Remove Casting
+    aCode = aCode.replace( new RegExp(&quot;\\((&quot; + classes.join(&quot;|&quot;) + &quot;)(\\[\\])?\\)&quot;, &quot;g&quot;), &quot;&quot; );
+    
+    // Convert 3.0f to just 3.0
+    aCode = aCode.replace( /(\d+)f[^a-zA-Z0-9]/g, &quot;$1&quot; );
 
-  // Force characters-as-bytes to work
-  aCode = aCode.replace(/('[a-zA-Z0-9]')/g, &quot;$1.charCodeAt(0)&quot;);
+    // Force numbers to exist //
+    //aCode = aCode.replace(/([^.])(\w+)\s*\+=/g, &quot;$1$2 = ($2||0) +&quot;);
 
-  // Convert #aaaaaa into color
-  aCode = aCode.replace(/#([a-f0-9]{6})/ig, function(m, hex){
-    var num = toNumbers(hex);
-    return &quot;DefaultColor(&quot; + num[0] + &quot;,&quot; + num[1] + &quot;,&quot; + num[2] + &quot;)&quot;;
-  });
+//!  // Force characters-as-bytes to work --&gt; Ping: Andor
+    aCode = aCode.replace(/('[a-zA-Z0-9]')/g, &quot;$1.charCodeAt(0)&quot;);
 
-  function toNumbers( str ){
-    var ret = [];
-     str.replace(/(..)/g, function(str){
-      ret.push( parseInt( str, 16 ) );
+    // Convert #aaaaaa into color
+    aCode = aCode.replace(/#([a-f0-9]{6})/ig, function(m, hex){
+      var num = toNumbers(hex);
+      return &quot;DefaultColor(&quot; + num[0] + &quot;,&quot; + num[1] + &quot;,&quot; + num[2] + &quot;)&quot;;
     });
-    return ret;
-  }
 
-//log(aCode);
+    function toNumbers( str ){
+      var ret = [];
+      
+      str.replace( /(..)/g, function( str ){
+        ret.push( parseInt( str, 16 ) );
+      });
+      
+      return ret;
+    }
 
-  return aCode;
-};
+    return aCode;
 
-function buildProcessing( curElement ){        
-            
-  var p = {};
-  
-  // Eval imported libraries  
-  //for( var i = 0; var len = libs
-  
-  // init
-  p.PI = Math.PI;
-  p.TWO_PI = 2 * p.PI;
-  p.HALF_PI = p.PI / 2;
-  p.P3D = 3;
-  p.CORNER = 0;
-  p.RADIUS = 1;
-  p.CENTER_RADIUS = 1;
-  p.CENTER = 2;
-  p.POLYGON = 2;
-  p.QUADS = 5;
-  p.TRIANGLES = 6;
-  p.POINTS = 7;
-  p.LINES = 8;
-  p.TRIANGLE_STRIP = 9;
-  p.TRIANGLE_FAN = 4;
-  p.QUAD_STRIP = 3;
-  p.CORNERS = 10;
-  p.CLOSE = true;
-  p.RGB = 1;
-  p.HSB = 2;  
-
-  // mouseButton constants: values adjusted to come directly from e.which
-  // CONFLICT: LEFT and RIGHT are keyboard values in Processing already. - F1lT3R         
-  // RESOLUTION: Extended Keyboard &amp; Mouse variables  
-  p.CENTER = 88888880;
-  p.CODED  = 88888888;
-  p.UP      = 88888870;
-  p.RIGHT   = 88888871;
-  p.DOWN    = 88888872;
-  p.LEFT    = 88888869;
-  p.codedKeys = [69, 70, 71, 72];
-
-  // &quot;Private&quot; variables used to maintain state
-  var curContext = curElement.getContext(&quot;2d&quot;);
-  var doFill = true;
-  var doStroke = true;
-  var loopStarted = false;
-  var hasBackground = false;
-  var doLoop = true;
-  var looping = 0;
-  var curRectMode = p.CORNER;
-  var curEllipseMode = p.CENTER;
-  var inSetup = false;
-  var inDraw = false;
-  var curBackground = &quot;rgba(204,204,204,1)&quot;;
-  var curFrameRate = 1000;
-  var curShape = p.POLYGON;
-  var curShapeCount = 0;
-  var curvePoints = [];
-  var curTightness = 0;
-  var opacityRange = 255;
-  var redRange = 255;
-  var greenRange = 255;
-  var blueRange = 255;
-  var pathOpen = false;
-  var mousePressed = false;
-  var keyPressed = false;
-  var firstX, firstY, secondX, secondY, prevX, prevY;
-  var curColorMode = p.RGB;
-  var curTint = -1;
-  var curTextSize = 12;
-  var curTextFont = &quot;Arial&quot;;
-  var getLoaded = false;
-  var start = (new Date).getTime();
-  
-  // println(), print()
-  p.ln = &quot;&quot;;
-  
-  // Glyph path storage for quick rendering  
-  p.glyphTable = {};
-  
-  // Global vars for tracking mouse position
-  p.pmouseX = 0;
-  p.pmouseY = 0;
-  p.mouseX = 0;
-  p.mouseY = 0;
-  p.mouseButton = 0;
-  p.mouseDown = false;
-
-  // Will be replaced by the user, most likely
-  p.mouseClicked = undefined;
-  p.mouseDragged = undefined;
-  p.mouseMoved = undefined;
-  p.mousePressed = undefined;
-  p.mouseReleased = undefined;
-  p.keyPressed = undefined;
-  p.keyReleased = undefined;
-  p.draw = undefined;
-  p.setup = undefined;
-
-  // The height/width of the canvas
-  p.width = curElement.width - 0;
-  p.height = curElement.height - 0;
-
-  // The current animation frame
-  p.frameCount = 0;
-  
-  // Forced default color mode for #aaaaaa style
-  p.DefaultColor = function ( aValue1, aValue2, aValue3) {
-    var tmpColorMode = curColorMode;
-    curColorMode = p.RGB;
-    var c = p.color( ((aValue1 / 255) * redRange), ((aValue2 / 255) * greenRange), ((aValue3 / 255) * blueRange));
-    curColorMode = tmpColorMode;
-    return c;
-  }      
-    
-  p.ajax=function(url){
-    if(window.XMLHttpRequest){AJAX=new XMLHttpRequest();}
-    else{AJAX=new ActiveXObject(&quot;Microsoft.XMLHTTP&quot;);}
-    if(AJAX){
-       AJAX.open(&quot;GET&quot;,url,false);
-       AJAX.send(null);
-       return AJAX.responseText;
-    }else{return false;}
-  }
-  
-  p.Import=function Import(lib){
-    eval(p.ajax(lib));
-  }
-  
-  // Load a file or URL into strings     
-  p.loadStrings = function loadStrings(url) {
-    return p.ajax(url).split(&quot;\n&quot;);              
   };
-  
-  // In case I ever need to do HSV conversion:
-  // http://srufaculty.sru.edu/david.dailey/javascript/js/5rml.js
-  p.color = function color( aValue1, aValue2, aValue3, aValue4 ) {
-    var aColor = &quot;&quot;;
-    
-    if ( arguments.length == 3 ) {
-      aColor = p.color( aValue1, aValue2, aValue3, opacityRange );
-    } else if ( arguments.length == 4 ) {
-      var a = aValue4 / opacityRange;
-      a = isNaN(a) ? 1 : a;
-
-      if ( curColorMode == p.HSB ) {
-        var rgb = HSBtoRGB(aValue1, aValue2, aValue3);
-        var r = rgb[0], g = rgb[1], b = rgb[2];
-      } else {
-        var r = getColor(aValue1, redRange);
-        var g = getColor(aValue2, greenRange);
-        var b = getColor(aValue3, blueRange);
-      }
 
-      aColor = &quot;rgba(&quot; + r + &quot;,&quot; + g + &quot;,&quot; + b + &quot;,&quot; + a + &quot;)&quot;;
-    } else if ( typeof aValue1 == &quot;string&quot; ) {
-      aColor = aValue1;
 
-      if ( arguments.length == 2 ) {
-        var c = aColor.split(&quot;,&quot;);
-        c[3] = (aValue2 / opacityRange) + &quot;)&quot;;
-        aColor = c.join(&quot;,&quot;);
-      }
-    } else if ( arguments.length == 2 ) {
-      aColor = p.color( aValue1, aValue1, aValue1, aValue2 );
-    } else if ( typeof aValue1 == &quot;number&quot; ) {
-      aColor = p.color( aValue1, aValue1, aValue1, opacityRange );
-    } else {
-      aColor = p.color( redRange, greenRange, blueRange, opacityRange );
-    }
+  // Attach Processing functions to 'p' 
+  function buildProcessing( curElement ){
+              
+    // Create the 'p' object
+    var p = {};
+    
+    // Set Processing defaults / environment variables
+    p.PI              = Math.PI;
+    p.TWO_PI          = 2 * p.PI;
+    p.HALF_PI         = p.PI / 2;
+    p.P3D             = 3;
+    p.CORNER          = 0;
+    p.RADIUS          = 1;
+    p.CENTER_RADIUS   = 1;
+    p.CENTER          = 2;
+    p.POLYGON         = 2;
+    p.QUADS           = 5;
+    p.TRIANGLES       = 6;
+    p.POINTS          = 7;
+    p.LINES           = 8;
+    p.TRIANGLE_STRIP  = 9;
+    p.TRIANGLE_FAN    = 4;
+    p.QUAD_STRIP      = 3;
+    p.CORNERS         = 10;
+    p.CLOSE           = true;
+    p.RGB             = 1;
+    p.HSB             = 2;  
+
+    // KeyCode table  
+    p.CENTER  = 88888880;
+    p.CODED   = 88888888;
+    p.UP      = 88888870;
+    p.RIGHT   = 88888871;
+    p.DOWN    = 88888872;
+    p.LEFT    = 88888869;
+    
+//! // Description required...
+    p.codedKeys = [ 69, 70, 71, 72  ];
+
+    // &quot;Private&quot; variables used to maintain state
+    var curContext      = curElement.getContext( &quot;2d&quot; ),
+        doFill          = true,
+        doStroke        = true,
+        loopStarted     = false,
+        hasBackground   = false,
+        doLoop          = true,
+        looping         = 0,
+        curRectMode     = p.CORNER,
+        curEllipseMode  = p.CENTER,
+        inSetup         = false,
+        inDraw          = false,
+        curBackground   = &quot;rgba( 204, 204, 204, 1 )&quot;,
+        curFrameRate    = 1000,
+        curMsPerFrame   = 1,
+        curShape        = p.POLYGON,
+        curShapeCount   = 0,
+        curvePoints     = [],
+        curTightness    = 0,
+        opacityRange    = 255,
+        redRange        = 255,
+        greenRange      = 255,
+        blueRange       = 255,
+        pathOpen        = false,
+        mousePressed    = false,
+        keyPressed      = false,
+        curColorMode    = p.RGB;
+        curTint         = - 1,
+        curTextSize     = 12,
+        curTextFont     = &quot;Arial&quot;,
+        getLoaded       = false,
+        start           = ( new Date ).getTime();
+
+    var firstX,
+        firstY,
+        secondX,
+        secondY,
+        prevX,
+        prevY;
+    
+    // Store a line for println(), print() handline
+    p.ln = &quot;&quot;;
+    
+    // Glyph path storage for textFonts
+    p.glyphTable = {};
+    
+    // Global vars for tracking mouse position
+    p.pmouseX     = 0;
+    p.pmouseY     = 0;
+    p.mouseX      = 0;
+    p.mouseY      = 0;
+    p.mouseButton = 0;
+    p.mouseDown   = false;
+
+    // Undefined event handlers to be replaced by user when needed
+    p.mouseClicked = undefined;
+    p.mouseDragged = undefined;
+    p.mouseMoved = undefined;
+    p.mousePressed = undefined;
+    p.mouseReleased = undefined;
+    p.keyPressed = undefined;
+    p.keyReleased = undefined;
+    p.draw = undefined;
+    p.setup = undefined;
+
+    // The height/width of the canvas
+    p.width  = curElement.width  - 0;
+    p.height = curElement.height - 0;
+
+    // The current animation frame
+    p.frameCount = 0;            
+    
+    
 
-    // HSB conversion function from Mootools, MIT Licensed
-    function HSBtoRGB(h, s, b) {
-      h = (h / redRange) * 360;
-      s = (s / greenRange) * 100;
-      b = (b / blueRange) * 100;
-      var br = Math.round(b / 100 * 255);
-      if (s == 0){
-        return [br, br, br];
-      } else {
-        var hue = h % 360;
-        var f = hue % 60;
-        var p = Math.round((b * (100 - s)) / 10000 * 255);
-        var q = Math.round((b * (6000 - s * f)) / 600000 * 255);
-        var t = Math.round((b * (6000 - s * (60 - f))) / 600000 * 255);
-        switch (Math.floor(hue / 60)){
-          case 0: return [br, t, p];
-          case 1: return [q, br, p];
-          case 2: return [p, br, t];
-          case 3: return [p, q, br];
-          case 4: return [t, p, br];
-          case 5: return [br, p, q];
-        }
-      }
-    }
+    ////////////////////////////////////////////////////////////////////////////
+    // Array handling
+    ////////////////////////////////////////////////////////////////////////////
 
-    function getColor( aValue, range ) {
-      return Math.round(255 * (aValue / range));
-    }
+    p.ArrayList = function ArrayList( size, size2, size3 ){
     
-    return aColor;
-  }
-  
-  p.red = function( aColor ) {        
-    return parseInt( verifyChannel(aColor).slice(5) );
-  };
+      var array = new Array( 0 | size );
+      
+      if( size2 ){
+        
+        for( var i = 0; i &lt; size; i++ ){
+          
+          array[ i ] = [];
 
-  p.green = function( aColor ) {     
-    return parseInt( verifyChannel(aColor).split(&quot;,&quot;)[1] );
-  };
+          for( var j = 0; j &lt; size2; j++ ){
+            var a = array[ i ][ j ] = size3 ? new Array( size3 ) : 0 ;  
+            for( var k = 0; k &lt; size3; k++ ){ a[ k ] = 0; }
+          }
+          
+        }
+        
+      }else{
+        
+        for( var i = 0; i &lt; size; i++ ){ array[ i ] = 0; }        
+      }
+      
+      array.get     = function( i    ){ return this[ i ];           };
+      array.add     = function( item ){ return this.push( item );   };
+      array.size    = function(      ){ return this.length;         };      
+      array.clear   = function(      ){ this.length = 0;            };
+      array.remove  = function( i    ){ return this.splice( i, 1 ); };
+      array.isEmpty = function(      ){ return !this.length;        };
+      array.clone   = function(      ){
+                                        var a = new ArrayList( size );
+                                        for( var i = 0; i &lt; size; i++ ){
+                                          a[ i ] = this[ i ];
+                                        }
+                                        return a;
+                                      };
+      
+      return array;
+    };
 
-  p.blue = function( aColor ) {
-    return parseInt( verifyChannel(aColor).split(&quot;,&quot;)[2] );
-  };
 
-  p.alpha = function( aColor ) {    
-    return parseInt( parseFloat(verifyChannel(aColor).split(&quot;,&quot;)[3])*255 );
-  };
 
-  function verifyChannel(aColor){
-    if(aColor.constructor == Array){    
-      return aColor;
-    } else {
-      return p.color(aColor);
-    }
-  }
+    ////////////////////////////////////////////////////////////////////////////
+    // Color functions
+    ////////////////////////////////////////////////////////////////////////////
 
-  
-  // Added lerpColor() - F1LT3R - 08.11.14
-  p.lerpColor = function lerpColor( c1, c2, amt ){
+    p.color = function color( aValue1, aValue2, aValue3, aValue4 ){
+      var aColor = &quot;&quot;;
       
-      // Get RGBA values for Color 1 to floats
-      var colors1 = p.color(c1).split(&quot;,&quot;);
-      var r1 = parseInt( colors1[0].split(&quot;(&quot;)[1] ); 
-      var g1 = parseInt( colors1[1] );
-      var b1 = parseInt( colors1[2] );
-      var a1 = parseFloat( colors1[3].split(&quot;)&quot;)[0] );
-          
-      // Get RGBA values for Color 2 to floats
-      var colors2 = p.color(c2).split(&quot;,&quot;);
-      var r2 = parseInt( colors2[0].split(&quot;(&quot;)[1] ); 
-      var g2 = parseInt( colors2[1] );
-      var b2 = parseInt( colors2[2] );
-      var a2 = parseFloat( colors2[3].split(&quot;)&quot;)[0] );            
-                        
-      // Return lerp value for each channel, INT for color, Float for Alpha-range
-      var r = parseInt( p.lerp(r1, r2, amt) );
-      var g = parseInt( p.lerp(g1, g2, amt) );
-      var b = parseInt( p.lerp(b1, b2, amt) );
-      var a = parseFloat( p.lerp(a1, a2, amt) );
+      if( arguments.length == 3 ){
       
-      aColor = &quot;rgba(&quot; + r + &quot;,&quot; + g + &quot;,&quot; + b + &quot;,&quot; + a + &quot;)&quot;;
-      return aColor;
-  }
-  
-  p.nf = function( num, pad ) {
-    var str = &quot;&quot; + num;
-    while ( pad - str.length )
-      str = &quot;0&quot; + str;
-    return str;
-  };
+        aColor = p.color( aValue1, aValue2, aValue3, opacityRange );
+      
+      } else if ( arguments.length == 4 ){
+       
+        var a = aValue4 / opacityRange;
+        
+        a = isNaN( a ) ? 1 : a ;
+
+        if( curColorMode == p.HSB ){
+          var rgb = HSBtoRGB( aValue1, aValue2, aValue3 )
+              r   = rgb[ 0 ],
+              g   = rgb[ 1 ],
+              b   = rgb[ 2 ];
+        }else{
+          var r = getColor( aValue1, redRange );
+          var g = getColor( aValue2, greenRange );
+          var b = getColor( aValue3, blueRange );
+        }
 
-  p.AniSprite = function( prefix, frames ) {    
-    this.images = [];
-    this.pos = 0;
+        aColor = &quot;rgba(&quot;+ r +&quot;,&quot;+ g +&quot;,&quot;+ b +&quot;,&quot;+ a +&quot;)&quot;;
+      
+      }else if( typeof aValue1 == &quot;string&quot; ){
+        aColor = aValue1;
 
-    for ( var i = 0; i &lt; frames; i++ ) {
-      this.images.push( prefix + p.nf( i, (&quot;&quot; + frames).length ) + &quot;.gif&quot; );
-    }
+        if( arguments.length == 2 ){
+          var c = aColor.split( &quot;,&quot; );
+          c[ 3 ] = ( aValue2 / opacityRange ) + &quot;)&quot;;
+          aColor = c.join( &quot;,&quot; );
+        }
+      }else if( arguments.length == 2 ){
+        aColor = p.color( aValue1, aValue1, aValue1, aValue2 );
+      }else if( typeof aValue1 == &quot;number&quot; ){
+        aColor = p.color( aValue1, aValue1, aValue1, opacityRange );
+      }else{
+        aColor = p.color( redRange, greenRange, blueRange, opacityRange );
+      }
 
-    this.display = function( x, y ) {
-      p.image( this.images[ this.pos ], x, y );
+      // HSB conversion function from Mootools, MIT Licensed
+      function HSBtoRGB( h, s, b ){
 
-      if ( ++this.pos &gt;= frames )
-        this.pos = 0;
-    };
+        h = ( h / redRange   ) * 360;
+        s = ( s / greenRange ) * 100;
+        b = ( b / blueRange  ) * 100;
 
-    this.getWidth = function() {
-      return getImage(this.images[0]).width;
-    };
+        var br = Math.round( b / 100 * 255 );
 
-    this.getHeight = function() {
-      return getImage(this.images[0]).height;
-    };
-  };
+        if( s == 0 ){
 
-  function buildImageObject( obj ) {
-    var pixels = obj.data;
-    var data = p.createImage( obj.width, obj.height );
+          return [ br, br, br ];
 
-    if ( data.__defineGetter__ &amp;&amp; data.__lookupGetter__ &amp;&amp; !data.__lookupGetter__(&quot;pixels&quot;) ) {
-      var pixelsDone;
-      data.__defineGetter__(&quot;pixels&quot;, function() {
-        if ( pixelsDone )
-          return pixelsDone;
+        }else{
 
-        pixelsDone = [];
+          var hue = h % 360;
+          var f   = hue % 60;
+          var p   = Math.round( ( b * ( 100  - s ) ) / 10000 * 255 );
+          var q   = Math.round( ( b * ( 6000 - s * f ) ) / 600000 * 255 );
+          var t   = Math.round( ( b * ( 6000 - s * ( 60 - f ) ) ) / 600000 * 255 );
 
-        for ( var i = 0; i &lt; pixels.length; i += 4 ) {
-          pixelsDone.push( p.color(pixels[i], pixels[i+1], pixels[i+2], pixels[i+3]) );
+          switch ( Math.floor( hue / 60 ) ){
+            case 0: return [ br, t, p ];
+            case 1: return [ q, br, p ];
+            case 2: return [ p, br, t ];
+            case 3: return [ p, q, br ];
+            case 4: return [ t, p, br ];
+            case 5: return [ br, p, q ];
+          }
+          
         }
+        
+      }
 
-        return pixelsDone;
-      });
-    } else {
-      data.pixels = [];
-
-      for ( var i = 0; i &lt; pixels.length; i += 4 ) {
-        data.pixels.push( p.color(pixels[i], pixels[i+1], pixels[i+2], pixels[i+3]) );
+      function getColor( aValue, range ){
+        return Math.round( 255 * ( aValue / range ) );
       }
+      
+      return aColor;
+    }
+    
+    p.red   = function( aColor ){ return parseInt( verifyChannel( aColor ).slice( 5 ) ); };
+    p.green = function( aColor ){ return parseInt( verifyChannel( aColor ).split( &quot;,&quot; )[ 1 ] ); };
+    p.blue  = function( aColor ){ return parseInt( verifyChannel( aColor ).split( &quot;,&quot; )[ 2 ] ); };
+    p.alpha = function( aColor ){ return parseInt( parseFloat( verifyChannel( aColor ).split( &quot;,&quot; )[ 3 ] ) * 255 ); };
+
+    function verifyChannel( aColor ){ 
+      if( aColor.constructor == Array ){    
+        return aColor;
+      } else {
+        return p.color( aColor );
+      } 
+    }
+    
+    p.lerpColor = function lerpColor( c1, c2, amt ){
+        
+      // Get RGBA values for Color 1 to floats
+      var colors1 = p.color( c1 ).split( &quot;,&quot; );
+      var r1 =   parseInt( colors1[ 0 ].split( &quot;(&quot; )[ 1 ] ); 
+      var g1 =   parseInt( colors1[ 1 ] );
+      var b1 =   parseInt( colors1[ 2 ] );
+      var a1 = parseFloat( colors1[ 3 ].split( &quot;)&quot; )[ 0 ] );
+          
+      // Get RGBA values for Color 2 to floats
+      var colors2 = p.color( c2 ).split( &quot;,&quot; );
+      var r2 =   parseInt( colors2[ 0 ].split( &quot;(&quot; )[ 1 ] ); 
+      var g2 =   parseInt( colors2[ 1 ] );
+      var b2 =   parseInt( colors2[ 2 ] );
+      var a2 = parseFloat( colors2[ 3 ].split( &quot;)&quot; )[ 0 ] );            
+                        
+      // Return lerp value for each channel, INT for color, Float for Alpha-range
+      var r =   parseInt( p.lerp( r1, r2, amt ) );
+      var g =   parseInt( p.lerp( g1, g2, amt ) );
+      var b =   parseInt( p.lerp( b1, b2, amt ) );
+      var a = parseFloat( p.lerp( a1, a2, amt ) );
+      
+      return aColor = &quot;rgba(&quot;+ r +&quot;,&quot;+ g +&quot;,&quot;+ b +&quot;,&quot;+ a +&quot;)&quot;;
+   
     }
 
-    return data;
-  }
+    // Forced default color mode for #aaaaaa style
+    p.DefaultColor = function( aValue1, aValue2, aValue3 ){
+      var tmpColorMode = curColorMode;
+      curColorMode = p.RGB;
+      var c = p.color(aValue1 / 255 * redRange, aValue2 / 255 * greenRange, aValue3 / 255 * blueRange );
+      curColorMode = tmpColorMode;
+      return c;
+    }
+    
+    p.colorMode = function colorMode( mode, range1, range2, range3, range4 ){
+      curColorMode = mode;
+      if( arguments.length &gt;= 4 ){ redRange     = range1; greenRange = range2; blueRange  = range3; }
+      if( arguments.length == 5 ){ opacityRange = range4; }
+      if( arguments.length == 2 ){ p.colorMode( mode, range1, range1, range1, range1 ); }    
+    };
+    
 
-  p.createImage = function createImage( w, h, mode ) {
-    var data = {};
-    data.width = w;
-    data.height = h;
-    data.data = [];
+    ////////////////////////////////////////////////////////////////////////////
+    // Canvas-Matrix manipulation
+    ////////////////////////////////////////////////////////////////////////////
+
+    p.translate   = function translate( x, y ){ curContext.translate( x, y );   };    
+    p.scale       = function scale( x, y )    { curContext.scale( x, y || x );  };    
+    p.rotate      = function rotate( aAngle ) { curContext.rotate( aAngle );    };    
+    p.pushMatrix  = function pushMatrix()     { curContext.save();              };
+    p.popMatrix   = function popMatrix()      { curContext.restore();           };
+    p.ortho       = function ortho(){};
 
-    if ( curContext.createImageData ) {
-      data = curContext.createImageData( w, h );
-    }
 
-    data.pixels = new Array( w * h );
-    data.get = function(x,y) {
-      return this.pixels[w*y+x];
+    
+    ////////////////////////////////////////////////////////////////////////////
+    //Time based functions
+    ////////////////////////////////////////////////////////////////////////////
+
+    p.year    = function year()  { return ( new Date ).getYear() + 1900;   };
+    p.month   = function month() { return ( new Date ).getMonth();         };
+    p.day     = function day()   { return ( new Date ).getDay();           };
+    p.hour    = function hour()  { return ( new Date ).getHours();         };
+    p.minute  = function minute(){ return ( new Date ).getMinutes();       };
+    p.second  = function second(){ return ( new Date ).getSeconds();       };
+    p.millis  = function millis(){ return ( new Date ) .getTime() - start; };
+    
+    p.noLoop  = function noLoop(){ doLoop = false; };
+         
+    p.redraw = function redraw(){
+      if( hasBackground ){ p.background(); }
+      p.frameCount++;      
+      inDraw = true;
+      p.pushMatrix();
+      p.draw();
+      p.popMatrix();
+      inDraw = false;      
+    };
+    
+    p.loop = function loop(){
+      
+      if( loopStarted ){ return; }
+      
+      looping = setInterval( function(){
+         
+          try {
+                      p.redraw();
+              }
+          catch( e ){
+                      clearInterval( looping );
+                      throw e;
+                    }
+      }, curMsPerFrame );
+      
+      loopStarted = true;
+      
     };
-    data._mask = null;
-    data.mask = function(img) {
-      this._mask = img;
+    
+    p.frameRate = function frameRate( aRate ){
+      curFrameRate = aRate;
+      curMsPerFrame = 1000 / curFrameRate;
     };
-    data.loadPixels = function(){};
-    data.updatePixels = function(){};
 
-    return data;
-  };
+    p.exit = function exit(){
+      clearInterval( looping );
+    };
+    
+    
+    
+    ////////////////////////////////////////////////////////////////////////////
+    // MISC functions
+    ////////////////////////////////////////////////////////////////////////////
+    p.cursor = function(mode){ document.body.style.cursor=mode; }
+    p.link = function( href, target ) { window.location = href; };
+    p.beginDraw = function beginDraw(){};
+    p.endDraw = function endDraw(){};
+    
+    p.ajax = ajax;
+    
+    // Imports an external Processing.js library
+    p.Import = function Import( lib ){
+      eval( p.ajax( lib ) );
+    }
 
-  p.createGraphics = function createGraphics( w, h ) {
-    var canvas = document.createElement(&quot;canvas&quot;);
-    var ret = buildProcessing( canvas );
-    ret.size( w, h );
-    ret.canvas = canvas;
-    return ret;
-  };
+    
 
-  p.beginDraw = function beginDraw(){};
+    ////////////////////////////////////////////////////////////////////////////
+    // String functions
+    ////////////////////////////////////////////////////////////////////////////
 
-  p.endDraw = function endDraw(){};
+    // Load a file or URL into strings     
+    p.loadStrings = function loadStrings( url ){
+      return p.ajax( url ).split( &quot;\n&quot; );              
+    };
 
-  p.tint = function tint( rgb, a ) {
-    curTint = a;
-  };
+    p.nf = function( num, pad ){
+      var str = &quot;&quot; + num;
+      while ( pad - str.length ){
+        str = &quot;0&quot; + str;
+      }
+      return str;
+    };
 
-  function getImage( img ) {
-    if ( typeof img == &quot;string&quot; ) {
-      return document.getElementById(img);
-    }
+    String.prototype.replaceAll = function( re, replace ){
+      return this.replace( new RegExp( re, &quot;g&quot; ), replace );
+    };
+        
+    // Returns a line to lnPrinted() for user handling 
+    p.lnPrinted = function lnPrinted(){};
+    p.printed   = function printed()  {};  
+    
+    // Event to send output to user control function print()/println()
+    p.println = function println(){
+      
+      var Caller = arguments.callee.caller.name.toString();
+      
+      if( arguments.length &gt; 1 ){
 
-    if ( img.img || img.canvas ) {
-      return img.img || img.canvas;
-    }
+        Caller != &quot;print&quot;        ?
+          p.ln  = arguments      :
+          p.ln  = arguments[ 0 ] ;
 
-    for ( var i = 0, l = img.pixels.length; i &lt; l; i++ ) {
-      var pos = i * 4;
-      var c = (img.pixels[i] || &quot;rgba(0,0,0,1)&quot;).slice(5,-1).split(&quot;,&quot;);
-      img.data[pos] = parseInt(c[0]);
-      img.data[pos+1] = parseInt(c[1]);
-      img.data[pos+2] = parseInt(c[2]);
-      img.data[pos+3] = parseFloat(c[3]) * 100;
-    }
+      }else{
 
-    var canvas = document.createElement(&quot;canvas&quot;)
-    canvas.width = img.width;
-    canvas.height = img.height;
-    var context = canvas.getContext(&quot;2d&quot;);
-    context.putImageData( img, 0, 0 );
+          p.ln  = arguments[ 0 ] ;
+      }
+      
+      //Returns a line to lnPrinted() for user error handling/debugging
+      Caller == &quot;print&quot;          ?        
+        p.printed( arguments )   :
+        p.lnPrinted()            ;
 
-    img.canvas = canvas;
+    };    
 
-    return canvas;
-  }
+    // Converts a number to a string
+    p.str = function str( aNumber ){ return aNumber+''; }   
+    
+    p.print = function print(){ p.println(arguments[ 0 ] ) };
+    
+    p.char = function char( key ){ return key; };
+    
+    
+    
+    ////////////////////////////////////////////////////////////////////////////
+    // Math functions
+    ////////////////////////////////////////////////////////////////////////////
+    
+    p.sq      = function sq     ( aNumber             ){ return aNumber * aNumber;                       };
+    p.sqrt    = function sqrt   ( aNumber             ){ return Math.sqrt( aNumber );                    };
+    p.int     = function int    ( aNumber             ){ return Math.floor( aNumber );                   };
+    p.min     = function min    ( aNumber, aNumber2   ){ return Math.min( aNumber, aNumber2 );           };
+    p.max     = function max    ( aNumber, aNumber2   ){ return Math.max( aNumber, aNumber2 );           };
+    p.floor   = function floor  ( aNumber             ){ return Math.floor( aNumber );                   };
+    p.float   = function float  ( aNumber             ){ return parseFloat( aNumber );                   };
+    p.ceil    = function ceil   ( aNumber             ){ return Math.ceil( aNumber );                    };    
+    p.round   = function round  ( aNumber             ){ return Math.round( aNumber );                   };
+    p.lerp    = function lerp   ( value1, value2, amt ){ return ( ( value2 - value1 ) * amt ) + value1;  };
+     p.abs    = function abs    ( aNumber             ){ return Math.abs( aNumber );                     };
+    p.cos     = function cos    ( aNumber             ){ return Math.cos( aNumber );                     };
+    p.sin     = function sin    ( aNumber             ){ return Math.sin( aNumber );                     };
+    p.pow     = function pow    ( aNumber, aExponent  ){ return Math.pow( aNumber, aExponent );          };
+    p.sqrt    = function sqrt   ( aNumber             ){ return Math.sqrt( aNumber );                    };
+    p.atan2   = function atan2  ( aNumber, aNumber2   ){ return Math.atan2( aNumber, aNumber2 );         };
+    p.radians = function radians( aAngle              ){ return ( aAngle / 180 ) * p.PI;                 };
+
+    p.dist = function dist( x1, y1, x2, y2 ){
+      return Math.sqrt( Math.pow( x2 - x1, 2 ) + Math.pow( y2 - y1, 2 ) );
+    };
 
-  p.image = function image( img, x, y, w, h ) {
-    x = x || 0;
-    y = y || 0;
+    p.map = function map( value, istart, istop, ostart, ostop ){
+      return ostart + ( ostop - ostart ) * ( ( value - istart ) / ( istop - istart ) );
+    };
 
-    var obj = getImage(img);
+    p.Random = function(){
 
-    if ( curTint &gt;= 0 ) {
-      var oldAlpha = curContext.globalAlpha;
-      curContext.globalAlpha = curTint / opacityRange;
-    }
+      var haveNextNextGaussian = false,
+          nextNextGaussian;
 
-    if ( arguments.length == 3 ) {
-      curContext.drawImage( obj, x, y );
-    } else {
-      curContext.drawImage( obj, x, y, w, h );
-    }
+      this.nextGaussian = function(){
+        
+        if( haveNextNextGaussian ){
+        
+          haveNextNextGaussian = false;
+          return nextNextGaussian;
+        
+        }else{
+          
+          var v1, v2, s;
+          do{ 
+              v1 = 2 * p.random( 1 ) - 1;   // between -1.0 and 1.0
+              v2 = 2 * p.random( 1 ) - 1;   // between -1.0 and 1.0
+              s = v1 * v1 + v2 * v2;
+          }
+          while( s &gt;= 1 || s == 0 );
+          
+          var multiplier = Math.sqrt( - 2 * Math.log( s ) / s );
+          nextNextGaussian = v2 * multiplier;
+          haveNextNextGaussian = true;
 
-    if ( curTint &gt;= 0 ) {
-      curContext.globalAlpha = oldAlpha;
-    }
+          return v1 * multiplier;
+        
+        }
+        
+      };
+      
+    };
 
-    if ( img._mask ) {
-      var oldComposite = curContext.globalCompositeOperation;
-      curContext.globalCompositeOperation = &quot;darker&quot;;
-      p.image( img._mask, x, y );
-      curContext.globalCompositeOperation = oldComposite;
-    }
-  };
+//! This can't be right... right?
+    p.byte     = function byte( aNumber               ){ return aNumber || 0;                           };
 
-  p.exit = function exit() {
-    clearInterval(looping);
-  };
+    p.norm     = function norm( aNumber, low, high   ){
+      var range = high-low;
+      return ( ( 1 / range ) * aNumber ) - ( ( 1 / range ) * low );
+    };        
+    
+    p.random = function random( aMin, aMax ) {
+      return arguments.length == 2                   ?
+        aMin + ( Math.random() * ( aMax - aMin ) )  :
+        Math.random() * aMin                        ;
+    };
 
-  p.save = function save( file ){};
+    // From: http://freespace.virgin.net/hugo.elias/models/m_perlin.htm
+    p.noise = function( x, y, z ){
+      return arguments.length &gt;= 2  ?
+        PerlinNoise_2D( x, y, z )    :
+        PerlinNoise_3D( x, x, z )    ;
+    };
 
-  p.loadImage = function loadImage( file ) {
-    var img = document.getElementById(file);
-    if ( !img )
-      return;
+    function Noise( x, y ){
+      var n = x + y * 57;
+      n = ( n &lt;&lt; 13 ) ^ n;
+      return Math.abs( 1.0 - ( ( ( n * ( ( n * n * 15731 ) + 789221 ) + 1376312589 ) &amp; 0x7fffffff ) / 1073741824.0 ) );
+    };
 
-    var h = img.height, w = img.width;
+    function SmoothedNoise( x, y ){
+      var corners = ( Noise( x - 1, y - 1 ) + Noise( x + 1, y - 1 ) + Noise( x - 1, y + 1 ) + Noise( x + 1, y + 1 ) ) / 16,
+          sides   = ( Noise( x - 1, y ) + Noise( x + 1, y ) + Noise( x, y - 1 ) + Noise( x, y + 1 ) ) / 8,
+          center  = Noise( x, y ) / 4;
+      return corners + sides + center;
+    };
 
-    var canvas = document.createElement(&quot;canvas&quot;);
-    canvas.width = w;
-    canvas.height = h;
-    var context = canvas.getContext(&quot;2d&quot;);
+    function InterpolatedNoise( x, y ){
 
-    context.drawImage( img, 0, 0 );
-    var data = buildImageObject( context.getImageData( 0, 0, w, h ) );
-    data.img = img;
-    return data;
-  };
+      var integer_X    = Math.floor( x );
+      var fractional_X = x - integer_X;
 
-  p.loadFont = function loadFont( name ) {
-    if(name.indexOf(&quot;.svg&quot;)==-1){
-      return {
-        name: name,
-        width: function( str ) {
-          if ( curContext.mozMeasureText )
-            return curContext.mozMeasureText( typeof str == &quot;number&quot; ?
-              String.fromCharCode( str ) :
-              str) / curTextSize;
-          else
-            return 0;
-        }
-      };
-    }else{// If the font is a glyph, calculate by SVG table 
-      var font=p.loadGlyphs(name);
-      return {
-      name: name,
-      glyph: true,
-      units_per_em: font.units_per_em,
-      horiz_adv_x: 1/font.units_per_em*font.horiz_adv_x,
-      ascent: font.ascent,
-      descent: font.descent,
-      width: function( str ) {
-        var width=0;
-        var len = str.length;
-        for(var i=0;i &lt; len;i++){                          
-          try{width+=parseFloat(p.glyphLook(p.glyphTable[name],str[i]).horiz_adv_x);}
-          catch(e){;}
-        }
-        return width/p.glyphTable[name].units_per_em;
-        }
-      }
-    }
-  };
+      var integer_Y    = Math.floor( y );
+      var fractional_Y = y - integer_Y;
 
-  p.textFont = function textFont( name, size ) {
-    curTextFont = name;
-    p.textSize( size );
-  };
+      var v1 = SmoothedNoise( integer_X,     integer_Y     ),
+          v2 = SmoothedNoise( integer_X + 1, integer_Y     ),
+          v3 = SmoothedNoise( integer_X,     integer_Y + 1 ),
+          v4 = SmoothedNoise( integer_X + 1, integer_Y + 1 );
 
-  p.textSize = function textSize( size ) {
-    if ( size ) {
-      curTextSize = size;
-    }
-  };
+      var i1 = Interpolate( v1, v2, fractional_X ),
+          i2 = Interpolate( v3, v4, fractional_X );
 
-  p.textAlign = function textAlign(){};
-
-  p.glyphLook = function glyphLook(font,chr){
-    try{
-      switch(chr){
-        case &quot;1&quot;:return font[&quot;one&quot;];break;
-        case &quot;2&quot;:return font[&quot;two&quot;];break;
-        case &quot;3&quot;:return font[&quot;three&quot;];break;
-        case &quot;4&quot;:return font[&quot;four&quot;];break;
-        case &quot;5&quot;:return font[&quot;five&quot;];break;
-        case &quot;6&quot;:return font[&quot;six&quot;];break;
-        case &quot;7&quot;:return font[&quot;seven&quot;];break;
-        case &quot;8&quot;:return font[&quot;eight&quot;];break;
-        case &quot;9&quot;:return font[&quot;nine&quot;];break;
-        case &quot;0&quot;:return font[&quot;zero&quot;];break;
-        case &quot; &quot;:return font[&quot;space&quot;];break;
-        case &quot;$&quot;:return font[&quot;dollar&quot;];break;
-        case &quot;!&quot;:return font[&quot;exclam&quot;];break;
-        case '&quot;':return font[&quot;quotedbl&quot;];break;
-        case &quot;#&quot;:return font[&quot;numbersign&quot;];break;
-        case &quot;%&quot;:return font[&quot;percent&quot;];break;
-        case &quot;&amp;&quot;:return font[&quot;ampersand&quot;];break;
-        case &quot;'&quot;:return font[&quot;quotesingle&quot;];break;
-        case &quot;(&quot;:return font[&quot;parenleft&quot;];break;
-        case &quot;)&quot;:return font[&quot;parenright&quot;];break;
-        case &quot;*&quot;:return font[&quot;asterisk&quot;];break;
-        case &quot;+&quot;:return font[&quot;plus&quot;];break;
-        case &quot;,&quot;:return font[&quot;comma&quot;];break;
-        case &quot;-&quot;:return font[&quot;hyphen&quot;];break;
-        case &quot;.&quot;:return font[&quot;period&quot;];break;
-        case &quot;/&quot;:return font[&quot;slash&quot;];break;
-        case &quot;_&quot;:return font[&quot;underscore&quot;];break;
-        case &quot;:&quot;:return font[&quot;colon&quot;];break;
-        case &quot;;&quot;:return font[&quot;semicolon&quot;];break;
-        case &quot;&lt;&quot;:return font[&quot;less&quot;];break;
-        case &quot;=&quot;:return font[&quot;equal&quot;];break;
-        case &quot;&gt;&quot;:return font[&quot;greater&quot;];break;
-        case &quot;?&quot;:return font[&quot;question&quot;];break;
-        case &quot;@&quot;:return font[&quot;at&quot;];break;
-        case &quot;[&quot;:return font[&quot;bracketleft&quot;];break;
-        case &quot;\\&quot;:return font[&quot;backslash&quot;];break;
-        case &quot;]&quot;:return font[&quot;bracketright&quot;];break;
-        case &quot;^&quot;:return font[&quot;asciicircum&quot;];break;
-        case &quot;`&quot;:return font[&quot;grave&quot;];break;
-        case &quot;{&quot;:return font[&quot;braceleft&quot;];break;
-        case &quot;|&quot;:return font[&quot;bar&quot;];break;
-        case &quot;}&quot;:return font[&quot;braceright&quot;];break;
-        case &quot;~&quot;:return font[&quot;asciitilde&quot;];break;
-        default:return font[chr]; break;
-      }
-    }catch(e){;}
-  }
-  
-  p.text = function text( str, x, y ) {
-    if(!curTextFont.glyph){
-      if ( str &amp;&amp; curContext.mozDrawText ) {
-        curContext.save();
-        curContext.mozTextStyle = curTextSize + &quot;px &quot; + curTextFont.name;
-        curContext.translate(x, y);
-        curContext.mozDrawText( typeof str == &quot;number&quot; ?
-          String.fromCharCode( str ) :
-          str );
-        curContext.restore();
-      }
-    }else{
-      var font=p.glyphTable[curTextFont.name];
-        curContext.save();
-        curContext.translate(x,y+curTextSize);
-        var upem = font[&quot;units_per_em&quot;];
-        var newScale=1/upem*curTextSize;
-        curContext.scale(newScale,newScale);
-        var len = str.length;
-        for(var i=0;i &lt; len;i++){
-          try{p.glyphLook(font,str[i]).draw();}
-          catch(e){;}
-        }
-      curContext.restore();
-    }
-  };
-  
-  
-  // Load Batik SVG Fonts and parse to pre-def objects for quick rendering - F1LT3R 
-  p.loadGlyphs=function loadGlyph(url){
-      // SJAX SVG as XML D.O.
-      var loadXML=function loadXML(){
-        try{var xmlDoc=new ActiveXObject(&quot;Microsoft.XMLDOM&quot;);}
-        catch(e){try{xmlDoc=document.implementation.createDocument(&quot;&quot;,&quot;&quot;,null);}
-        catch(e){p.println(e.message);return;}}
-          try{// Firefox, Mozilla, Opera, etc.
-            xmlDoc.async=false;
-            xmlDoc.load(url);
-            parse(xmlDoc.getElementsByTagName(&quot;svg&quot;)[0]);
-            }
-          catch(e){try{// Google Chrome, Safari etc.
-             try{console.log(e)}catch(e){alert(e);}
-             var xmlhttp = new window.XMLHttpRequest();
-             xmlhttp.open(&quot;GET&quot;,url,false);
-             xmlhttp.send(null);
-             parse(xmlhttp.responseXML.documentElement);
-            }catch(e){}
-          }
-      }
+      return Interpolate( i1, i2, fractional_Y );
       
-      // Return arrays of SVG commands and coords
-      var regex=function regex(needle,hay){
-        var regexp=new RegExp(needle,&quot;g&quot;);
-        var i=0;
-        var results=[];
-        while(results[i]=regexp.exec(hay)){i++;}
-        return results;
-      }        
-      
-      // Parse SVG font-file
-      var parse=function parse(svg){
-        
-        // Store font attributes
-        var font=svg.getElementsByTagName(&quot;font&quot;);
-        p.glyphTable[url][&quot;horiz_adv_x&quot;]=font[0].getAttribute(&quot;horiz-adv-x&quot;);      
-        var font_face=svg.getElementsByTagName(&quot;font-face&quot;)[0];                  
-        p.glyphTable[url][&quot;units_per_em&quot;]=parseFloat(font_face.getAttribute(&quot;units-per-em&quot;));
-        p.glyphTable[url][&quot;ascent&quot;]=parseFloat(font_face.getAttribute(&quot;ascent&quot;));
-        p.glyphTable[url][&quot;descent&quot;]=parseFloat(font_face.getAttribute(&quot;descent&quot;));          
-        
-        var getXY = &quot;[0-9\-]+&quot;;
-        var glyph = svg.getElementsByTagName(&quot;glyph&quot;);
-        
-        // Loop through each glyph in the SVG
-        var len = glyph.length;
-        for(var i=0;i &lt; len;i++){
-          
-          // Store attributes for this glyph
-          var unicode = glyph[i].getAttribute(&quot;unicode&quot;);
-          var name = glyph[i].getAttribute(&quot;glyph-name&quot;);
-          var horiz_adv_x = glyph[i].getAttribute(&quot;horiz-adv-x&quot;);
-          if(horiz_adv_x==null){var horiz_adv_x=p.glyphTable[url]['horiz_adv_x'];}
-          
-          var buildPath = function buildPath(d){ 
-            var c = regex(&quot;[A-Za-z][0-9\- ]+|Z&quot;,d);                                                    
-            // Begin storing path object 
-            var path=&quot;var path={draw:function(){curContext.beginPath();curContext.save();&quot;;//curContext.beginPath();
-            // Loop through SVG commands translating to canvas eqivs functions in path object
-            var x=0,y=0,cx=0,cy=0,nx=0,ny=0,d=0,a=0,lastCom=&quot;&quot;;
-            var lenC = c.length-1;
-            for(var j=0;j &lt; lenC;j++){
-              var com=c[j][0];
-              var xy=regex(getXY,com);
-              switch(com[0]){            
-                case &quot;M&quot;://curContext.moveTo(x,-y);
-                  x=parseFloat( xy[0][0] );
-                  y=parseFloat( xy[1][0] );              
-                  path+=&quot;curContext.moveTo(&quot;+(x)+&quot;,&quot;+(-y)+&quot;);&quot;;
-                  break;
-                case &quot;L&quot;://curContext.lineTo(x,-y);
-                  x=parseFloat( xy[0][0] );
-                  y=parseFloat( xy[1][0] );
-                  path+=&quot;curContext.lineTo(&quot;+(x)+&quot;,&quot;+(-y)+&quot;);&quot;;
-                  break;
-                case &quot;H&quot;://curContext.lineTo(x,-y)
-                  x=parseFloat( xy[0][0] );
-                  path+=&quot;curContext.lineTo(&quot;+(x)+&quot;,&quot;+(-y)+&quot;);&quot;;
-                  break;
-                case &quot;V&quot;://curContext.lineTo(x,-y);
-                  y=parseFloat( xy[0][0] );              
-                  path+=&quot;curContext.lineTo(&quot;+(x)+&quot;,&quot;+(-y)+&quot;);&quot;;
-                  break;
-                case &quot;T&quot;://curContext.quadraticCurveTo(cx,-cy,nx,-ny);
-                  nx=parseFloat( xy[0][0] );
-                  ny=parseFloat( xy[1][0] );
-                  if(lastCom==&quot;Q&quot;||lastCom==&quot;T&quot;){
-                    d=Math.sqrt(Math.pow(x-cx,2)+Math.pow(cy-y,2));
-                    a=Math.PI+Math.atan2(cx-x,cy-y);
-                    cx=x+(Math.sin(a)*(d));
-                    cy=y+(Math.cos(a)*(d));
-                  }else{cx=x;cy=y;}       
-                  path+=&quot;curContext.quadraticCurveTo(&quot;+(cx)+&quot;,&quot;+(-cy)+&quot;,&quot;+(nx)+&quot;,&quot;+(-ny)+&quot;);&quot;;
-                  x=nx;y=ny;
-                  break; 
-                case &quot;Q&quot;://curContext.quadraticCurveTo(cx,-cy,nx,-ny);
-                  cx=parseFloat( xy[0][0] );
-                  cy=parseFloat( xy[1][0] );
-                  nx=parseFloat( xy[2][0] );
-                  ny=parseFloat( xy[3][0] );  
-                  path+=&quot;curContext.quadraticCurveTo(&quot;+(cx)+&quot;,&quot;+(-cy)+&quot;,&quot;+(nx)+&quot;,&quot;+(-ny)+&quot;);&quot;;              
-                  x=nx;y=ny;
-                  break;
-                case &quot;Z&quot;://curContext.closePath();
-                  path+=&quot;curContext.closePath();&quot;;
-                  break;
-              }
-              lastCom=com[0];
-            }
-            path+=&quot;doStroke?curContext.stroke():0;&quot;;
-            path+=&quot;doFill?curContext.fill():0;&quot;;
-            path+=&quot;curContext.restore();&quot;;
-            path+=&quot;curContext.translate(&quot;+(horiz_adv_x)+&quot;,0);&quot;;            
-            path+=&quot;}}&quot;;
-            return path;
-          }
-          
-          // Split path commands in glpyh          
-          var d=glyph[i].getAttribute(&quot;d&quot;);
-          if(d!==undefined){
-            var path=buildPath(d);
-            eval(path);
-            // Store glyph data to table object
-            p.glyphTable[url][name]={
-              name:name,
-              unicode:unicode,
-              horiz_adv_x:horiz_adv_x,
-              draw:path.draw
-            }
-          }                  
-        } // finished adding glyphs to table
-      }
-      
-      // Create a new object in glyphTable to store this font
-      p.glyphTable[url]={};
-      
-      // Begin loading the Batik SVG font... 
-      loadXML(url);
-      
-      // Return the loaded font for attribute grabbing
-      return p.glyphTable[url];
-  }
-  
-  
-  // Returns a line to lnPrinted() for user handling 
-  p.lnPrinted = function lnPrinted(){};
-  p.printed = function printed(){};  
-  p.println = function println(){
-    var Caller = arguments.callee.caller.name.toString();
-    if ( arguments.length &gt; 1 ) {
-      Caller!=&quot;print&quot;?
-        p.ln = arguments:
-        p.ln = arguments[0];
-    } else {
-      p.ln = arguments[0];
     }
-    Caller==&quot;print&quot;?        
-      p.printed(arguments):
-      p.lnPrinted();
-  };
-  p.print = function print(){ p.println(arguments[0])};
-  
-  p.char = function char( key ) {
-    return key;
-  };
 
-  p.map = function map( value, istart, istop, ostart, ostop ) {
-    return ostart + (ostop - ostart) * ((value - istart) / (istop - istart));
-  };
 
-  String.prototype.replaceAll = function(re, replace) {
-    return this.replace(new RegExp(re, &quot;g&quot;), replace);
-  };
+    function PerlinNoise_2D( x, y ){
 
-  p.Point = function Point( x, y ) {
-    this.x = x;
-    this.y = y;
-    this.copy = function() {
-      return new Point( x, y );
-    }
-  };
+        var total = 0,
+            p     = 0.25,
+            n     = 3;
 
-  p.Random = function() {
-    var haveNextNextGaussian = false;
-    var nextNextGaussian;
+        for( var i = 0; i &lt;= n; i++ ){
+          var frequency = Math.pow( 2, i );
+          var amplitude = Math.pow( p, i );
+          total += InterpolatedNoise( x * frequency, y * frequency ) * amplitude;
+        }
 
-    this.nextGaussian = function() {
-      if (haveNextNextGaussian) {
-        haveNextNextGaussian = false;
+        return total;
+    }
 
-        return nextNextGaussian;
-      } else {
-        var v1, v2, s;
-        do { 
-          v1 = 2 * p.random(1) - 1;   // between -1.0 and 1.0
-          v2 = 2 * p.random(1) - 1;   // between -1.0 and 1.0
-          s = v1 * v1 + v2 * v2;
-        } while (s &gt;= 1 || s == 0);
-        var multiplier = Math.sqrt(-2 * Math.log(s)/s);
-        nextNextGaussian = v2 * multiplier;
-        haveNextNextGaussian = true;
-
-        return v1 * multiplier;
-      }
+    function Interpolate( a, b, x ){
+      var ft   = x * p.PI;
+      var f   = (1 - Math.cos( ft ) ) * .5;
+      return  a * ( 1 - f ) + b * f;
+    }
+   
+    p.constrain = function constrain( aNumber, aMin, aMax ){
+      return Math.min( Math.max( aNumber, aMin ), aMax );
     };
-  };
+          
+    p.degrees = function degrees( aAngle ){
+      aAngle = ( aAngle * 180 ) / p.PI;  
+      if (aAngle &lt; 0) {aAngle = 360 + aAngle}    
+      return aAngle;
+    };
+    
+    p.size = function size( aWidth, aHeight ){    
+      var fillStyle = curContext.fillStyle,
+          strokeStyle = curContext.strokeStyle;
+
+      curElement.width = p.width = aWidth;
+      curElement.height = p.height = aHeight;
 
-  p.ArrayList = function ArrayList( size, size2, size3 ) {
-    var array = new Array( 0 | size );
+      curContext.fillStyle = fillStyle;
+      curContext.strokeStyle = strokeStyle;
+    };
     
-    if ( size2 ) {
-      for ( var i = 0; i &lt; size; i++ ) {
-        array[i] = [];
 
-        for ( var j = 0; j &lt; size2; j++ ) {
-          var a = array[i][j] = size3 ? new Array( size3 ) : 0;
-          for ( var k = 0; k &lt; size3; k++ ) {
-            a[k] = 0;
-          }
-        }
-      }
-    } else {
-      for ( var i = 0; i &lt; size; i++ ) {
-        array[i] = 0;
-      }
-    }
     
-    array.size = function() {
-      return this.length;
-    };
-    array.get = function( i ) {
-      return this[ i ];
+    ////////////////////////////////////////////////////////////////////////////
+    // Style functions
+    ////////////////////////////////////////////////////////////////////////////
+    
+    p.noStroke   = function noStroke()  { doStroke = false; };    
+    p.noFill     = function noFill()    { doFill = false;   };
+    p.smooth     = function smooth()    {};
+    p.noSmooth   = function noSmooth()  {};        
+    
+    p.fill = function fill(){
+      doFill = true;
+      curContext.fillStyle = p.color.apply( this, arguments );    
     };
-    array.remove = function( i ) {
-      return this.splice( i, 1 );
+    
+    p.stroke = function stroke(){
+      doStroke = true;
+      curContext.strokeStyle = p.color.apply( this, arguments );
     };
-    array.add = function( item ) {
-      return this.push( item );
+
+    p.strokeWeight = function strokeWeight( w ){
+      curContext.lineWidth = w;
     };
-    array.clone = function() {
-      var a = new ArrayList( size );
-      for ( var i = 0; i &lt; size; i++ ) {
-        a[ i ] = this[ i ];
+
+       
+        
+    ////////////////////////////////////////////////////////////////////////////
+    // Vector drawing functions
+    ////////////////////////////////////////////////////////////////////////////
+
+    p.Point = function Point( x, y ){
+      this.x = x;
+      this.y = y;
+      this.copy = function(){
+        return new Point( x, y );
       }
-      return a;
     };
-    array.isEmpty = function() {
-      return !this.length;
+    
+    p.point = function point( x, y ){
+      var oldFill = curContext.fillStyle;
+      curContext.fillStyle = curContext.strokeStyle;
+      curContext.fillRect( Math.round( x ), Math.round( y ), 1, 1 );
+      curContext.fillStyle = oldFill;
     };
-    array.clear = function() {
-      this.length = 0;
+    
+    p.beginShape = function beginShape( type ){
+      curShape = type;
+      curShapeCount = 0; 
+      curvePoints = [];
     };
     
-    return array;
-  };
-  
-  p.colorMode = function colorMode( mode, range1, range2, range3, range4 ) {
-    curColorMode = mode;
-
-    if ( arguments.length &gt;= 4 ) {
-      redRange = range1;
-      greenRange = range2;
-      blueRange = range3;
-    }
-
-    if ( arguments.length == 5 ) {
-      opacityRange = range4;
-    }
+    p.endShape = function endShape( close ){
+      
+      if( curShapeCount != 0 ){
+        
+        if( close || doFill ){ curContext.lineTo( firstX, firstY ); }
+        if( doFill          ){ curContext.fill();                   }          
+        if( doStroke        ){ curContext.stroke();                 }
+      
+        curContext.closePath();
+        curShapeCount = 0;
+        pathOpen = false;
+        
+      }
 
-    if ( arguments.length == 2 ) {
-      p.colorMode( mode, range1, range1, range1, range1 );
-    }
-  };
-  
-  p.beginShape = function beginShape( type ) {
-    curShape = type;
-    curShapeCount = 0; 
-    curvePoints = [];
-  };
-  
-  p.endShape = function endShape( close ) {
-    if ( curShapeCount != 0 ) {
-      if ( close || doFill ) 
-      curContext.lineTo( firstX, firstY );
+      if( pathOpen ){
+        
+        if ( doFill   ){ curContext.fill();   }
+        if ( doStroke ){ curContext.stroke(); }
 
-      if ( doFill )
-        curContext.fill();
+        curContext.closePath();
+        curShapeCount = 0;
+        pathOpen = false;
         
-      if ( doStroke )
-        curContext.stroke();
+      }
+      
+    };
     
-      curContext.closePath();
-      curShapeCount = 0;
-      pathOpen = false;
-    }
+    p.vertex = function vertex( x, y, x2, y2, x3, y3 ){    
+      
+      if( curShapeCount == 0 &amp;&amp; curShape != p.POINTS ){
 
-    if ( pathOpen ) {
-      if ( doFill )
-        curContext.fill();
+        pathOpen = true;
+        curContext.beginPath();
+        curContext.moveTo( x, y );
+        firstX = x;
+        firstY = y;
 
-      if ( doStroke )
-        curContext.stroke();
+      }else{
 
-      curContext.closePath();
-      curShapeCount = 0;
-      pathOpen = false;
-    }
-  };
-  
-  p.vertex = function vertex( x, y, x2, y2, x3, y3 ) {    
-    if ( curShapeCount == 0 &amp;&amp; curShape != p.POINTS ) {
-      pathOpen = true;
-      curContext.beginPath();
-      curContext.moveTo( x, y );
-      firstX = x;
-      firstY = y;
-    } else {
-      if ( curShape == p.POINTS ) {
-        p.point( x, y );
-      } else if ( arguments.length == 2 ) {
-        if ( curShape != p.QUAD_STRIP || curShapeCount != 2 )
-          curContext.lineTo( x, y );
-        if ( curShape == p.TRIANGLE_STRIP ) {
-          if ( curShapeCount == 2 ) {
+        if( curShape == p.POINTS ){
+
+          p.point( x, y );
+
+        }else if( arguments.length == 2 ){
+          
+          if( curShape != p.QUAD_STRIP || curShapeCount != 2 ){
+
+            curContext.lineTo( x, y );
+
+          }
+          
+          if( curShape == p.TRIANGLE_STRIP ){
+            
+            if( curShapeCount == 2 ){
+              
+              // finish shape
+              p.endShape( p.CLOSE );
+              pathOpen = true;
+              curContext.beginPath();
+              
+              // redraw last line to start next shape
+              curContext.moveTo( prevX, prevY );
+              curContext.lineTo( x, y );
+              curShapeCount = 1;
+              
+            }
+            
+            firstX = prevX;
+            firstY = prevY;
+          
+          }
+
+          if( curShape == p.TRIANGLE_FAN &amp;&amp; curShapeCount == 2 ){
+            
             // finish shape
-            p.endShape(p.CLOSE);
+            p.endShape( p.CLOSE) ;
             pathOpen = true;
             curContext.beginPath();
-            
+        
             // redraw last line to start next shape
+            curContext.moveTo( firstX, firstY );
+            curContext.lineTo( x, y );
+            curShapeCount = 1;
+          
+          }
+      
+          if( curShape == p.QUAD_STRIP &amp;&amp; curShapeCount == 3 ){
+            
+            // finish shape
+            curContext.lineTo( prevX, prevY );
+            p.endShape(p.CLOSE);
+            pathOpen = true;
+            curContext.beginPath();
+      
+            // redraw lines to start next shape
             curContext.moveTo( prevX, prevY );
             curContext.lineTo( x, y );
             curShapeCount = 1;
+          
+          }
+
+          if( curShape == p.QUAD_STRIP ){
+            
+            firstX  = secondX;
+            firstY  = secondY;
+            secondX = prevX;
+            secondY = prevY;
+            
+          }
+        
+        }else if( arguments.length == 4 ){
+        
+          if( curShapeCount &gt; 1 ){
+            
+            curContext.moveTo( prevX, prevY );
+            curContext.quadraticCurveTo( firstX, firstY, x, y );
+            curShapeCount = 1;
+          
           }
-          firstX = prevX;
-          firstY = prevY;
+        
+        }else if( arguments.length == 6 ){
+          
+          curContext.bezierCurveTo( x, y, x2, y2, x3, y3 );
+
         }
+      }
 
-        if ( curShape == p.TRIANGLE_FAN &amp;&amp; curShapeCount == 2 ) {
-          // finish shape
-          p.endShape(p.CLOSE);
-          pathOpen = true;
-          curContext.beginPath();
+      prevX = x;
+      prevY = y;
+      curShapeCount ++;
       
-          // redraw last line to start next shape
-          curContext.moveTo( firstX, firstY );
-          curContext.lineTo( x, y );
-          curShapeCount = 1;
+      if(   curShape == p.LINES &amp;&amp; curShapeCount == 2       ||
+          ( curShape == p.TRIANGLES ) &amp;&amp; curShapeCount == 3 ||
+          ( curShape == p.QUADS     ) &amp;&amp; curShapeCount == 4 
+        ){
+          p.endShape( p.CLOSE );
         }
     
-        if ( curShape == p.QUAD_STRIP &amp;&amp; curShapeCount == 3 ) {
-          // finish shape
-          curContext.lineTo( prevX, prevY );
-          p.endShape(p.CLOSE);
-          pathOpen = true;
-          curContext.beginPath();
-    
-          // redraw lines to start next shape
-          curContext.moveTo( prevX, prevY );
-          curContext.lineTo( x, y );
-          curShapeCount = 1;
-        }
+    };
 
-        if ( curShape == p.QUAD_STRIP) {
-          
-          firstX = secondX;
-          firstY = secondY;
-          secondX = prevX;
-          secondY = prevY;
-        }
-      } else if ( arguments.length == 4 ) {
-        if ( curShapeCount &gt; 1 ) {
-          curContext.moveTo( prevX, prevY );
-          curContext.quadraticCurveTo( firstX, firstY, x, y );
+    p.curveVertex = function( x, y, x2, y2 ){
+      
+      if( curvePoints.length &lt; 3 ){
+        
+        curvePoints.push( [ x, y ] );
+      
+      }else{
+      
+        var b = [], s = 1 - curTightness;
+
+        /*
+         * Matrix to convert from Catmull-Rom to cubic Bezier
+         * where t = curTightness
+         * |0         1          0         0       |
+         * |(t-1)/6   1          (1-t)/6   0       |
+         * |0         (1-t)/6    1         (t-1)/6 |
+         * |0         0          0         0       |
+         */
+
+        curvePoints.push( [ x, y ] );
+
+        b[ 0 ] = [ curvePoints[ 1 ][ 0 ], curvePoints[ 1 ][ 1 ] ];
+        b[ 1 ] = [ curvePoints[ 1 ][ 0 ] + ( s * curvePoints[ 2 ][ 0 ] - s * curvePoints[ 0 ][ 0 ] ) / 6, curvePoints[ 1 ][ 1 ] + ( s * curvePoints[ 2 ][ 1 ] - s * curvePoints[ 0 ][ 1 ] ) / 6 ];
+        b[ 2 ] = [ curvePoints[ 2 ][ 0 ] + ( s * curvePoints[ 1 ][ 0 ] - s * curvePoints[ 3 ][ 0 ] ) / 6, curvePoints[ 2 ][ 1 ] + ( s * curvePoints[ 1 ][ 1 ] - s * curvePoints[ 3 ][ 1 ] ) / 6 ];
+        b[ 3 ] = [ curvePoints[ 2 ][ 0 ], curvePoints[ 2 ][ 1 ] ];
+
+        if( !pathOpen ){
+          p.vertex( b[ 0 ][ 0 ], b[ 0 ][ 1 ] );
+        }else{
           curShapeCount = 1;
         }
-      } else if ( arguments.length == 6 ) {
-        curContext.bezierCurveTo( x, y, x2, y2, x3, y3 );
-        //curShapeCount = -1; // Removed due to Heart-Shape issue. - F1LT3R
+
+        p.vertex(
+          b[ 1 ][ 0 ],
+          b[ 1 ][ 1 ],
+          b[ 2 ][ 0 ],
+          b[ 2 ][ 1 ],
+          b[ 3 ][ 0 ],
+          b[ 3 ][ 1 ]
+        );
+        
+        curvePoints.shift();      
       }
-    }
+    
+    };
 
-    prevX = x;
-    prevY = y;
-    curShapeCount++;
+    p.curveTightness = function( tightness ){ curTightness = tightness; };
+
+    p.bezierVertex = p.vertex;    
     
-    if ( curShape == p.LINES &amp;&amp; curShapeCount == 2 ||
-         (curShape == p.TRIANGLES) &amp;&amp; curShapeCount == 3 ||
-     (curShape == p.QUADS) &amp;&amp; curShapeCount == 4 ) {
-      p.endShape(p.CLOSE);
-    }
-  };
+    p.rectMode     = function rectMode( aRectMode ){ curRectMode = aRectMode; };
+    p.imageMode   = function (){};    
+    p.ellipseMode = function ellipseMode( aEllipseMode ) { curEllipseMode = aEllipseMode; };        
+    
+    p.arc = function arc( x, y, width, height, start, stop ){
 
-  p.curveVertex = function( x, y, x2, y2 ) {
-    if ( curvePoints.length &lt; 3 ) {
-      curvePoints.push([x,y]);
-    } else {
-      var b = [], s = 1 - curTightness;
-
-      /*
-       * Matrix to convert from Catmull-Rom to cubic Bezier
-       * where t = curTightness
-       * |0         1          0         0       |
-       * |(t-1)/6   1          (1-t)/6   0       |
-       * |0         (1-t)/6    1         (t-1)/6 |
-       * |0         0          0         0       |
-       */
-
-      curvePoints.push([x,y]);
-
-      b[0] = [curvePoints[1][0],curvePoints[1][1]];
-      b[1] = [curvePoints[1][0]+(s*curvePoints[2][0]-s*curvePoints[0][0])/6,curvePoints[1][1]+(s*curvePoints[2][1]-s*curvePoints[0][1])/6];
-      b[2] = [curvePoints[2][0]+(s*curvePoints[1][0]-s*curvePoints[3][0])/6,curvePoints[2][1]+(s*curvePoints[1][1]-s*curvePoints[3][1])/6];
-      b[3] = [curvePoints[2][0],curvePoints[2][1]];
-
-      if ( !pathOpen ) {
-        p.vertex( b[0][0], b[0][1] );
-      } else {
-        curShapeCount = 1;
+      if( width &lt;= 0 ){ return; }
+
+      if( curEllipseMode == p.CORNER ){
+       x += width / 2;
+       y += height / 2;
       }
+      
+      curContext.moveTo( x, y );
+      curContext.beginPath();   
+      curContext.arc( x, y, curEllipseMode == p.CENTER_RADIUS ? width : width/2, start, stop, false );
 
-      p.vertex( b[1][0], b[1][1], b[2][0], b[2][1], b[3][0], b[3][1] );
-      curvePoints.shift();
-    }
-  };
+      if( doStroke ){ curContext.stroke(); }
+      curContext.lineTo( x, y );
 
-  p.curveTightness = function( tightness ) {
-    curTightness = tightness;
-  };
+      if( doFill ){ curContext.fill(); }
+      curContext.closePath();
+      
+    };
+    
+    p.line = function line( x1, y1, x2, y2 ){
+      curContext.lineCap = &quot;round&quot;;
+      curContext.beginPath();    
+      curContext.moveTo( x1 || 0, y1 || 0 );
+      curContext.lineTo( x2 || 0, y2 || 0 );      
+      curContext.stroke();      
+      curContext.closePath();
+    };
 
-  p.bezierVertex = p.vertex;
-  
-  p.rectMode = function rectMode( aRectMode ) {
-    curRectMode = aRectMode;
-  };
+    p.bezier = function bezier( x1, y1, x2, y2, x3, y3, x4, y4 ){
+      curContext.lineCap = &quot;butt&quot;;
+      curContext.beginPath();    
+      curContext.moveTo( x1, y1 );
+      curContext.bezierCurveTo( x2, y2, x3, y3, x4, y4 );      
+      curContext.stroke();      
+      curContext.closePath();
+    };
 
-  p.imageMode = function(){};
-  
-  p.ellipseMode = function ellipseMode( aEllipseMode ) {
-    curEllipseMode = aEllipseMode;
-  };
-  
-  p.dist = function dist( x1, y1, x2, y2 ) {
-    return Math.sqrt( Math.pow( x2 - x1, 2 ) + Math.pow( y2 - y1, 2 ) );
-  };
+    p.triangle = function triangle( x1, y1, x2, y2, x3, y3 ){
+      p.beginShape();
+      p.vertex( x1, y1 );
+      p.vertex( x2, y2 );
+      p.vertex( x3, y3 );
+      p.endShape();
+    };
 
-  p.year = function year() {
-    return (new Date).getYear() + 1900;
-  };
+    p.quad = function quad( x1, y1, x2, y2, x3, y3, x4, y4 ){
+      curContext.lineCap = &quot;square&quot;;
+      p.beginShape();
+      p.vertex( x1, y1 );
+      p.vertex( x2, y2 );
+      p.vertex( x3, y3 );
+      p.vertex( x4, y4 );
+      p.endShape();
+    };
+    
+    p.rect = function rect( x, y, width, height ){
 
-  p.month = function month() {
-    return (new Date).getMonth();
-  };
+      if( width + height ){ return; }       
 
-  p.day = function day() {
-    return (new Date).getDay();
-  };
+      curContext.beginPath();
+      
+      var offsetStart = 0;
+      var offsetEnd = 0;
 
-  p.hour = function hour() {
-    return (new Date).getHours();
-  };
+      if( curRectMode == p.CORNERS ){
+        width -= x;
+        height -= y;
+      }
+      
+      if( curRectMode == p.RADIUS ){
+        width *= 2;
+        height *= 2;
+      }
+      
+      if( curRectMode == p.CENTER || curRectMode == p.RADIUS ){
+        x -= width / 2;
+        y -= height / 2;
+      }
+    
+      curContext.rect(
+        Math.round( x ) - offsetStart,
+        Math.round( y ) - offsetStart,
+        Math.round( width ) + offsetEnd,
+        Math.round( height ) + offsetEnd
+      );
+        
+      if( doFill     ){ curContext.fill();   }        
+      if( doStroke   ){  curContext.stroke() };
+      
+      curContext.closePath();
+      
+    };
+    
+    p.ellipse = function ellipse( x, y, width, height ){
 
-  p.minute = function minute() {
-    return (new Date).getMinutes();
-  };
+      x = x || 0;
+      y = y || 0;
 
-  p.second = function second() {
-    return (new Date).getSeconds();
-  };
+      if( width &lt;= 0 &amp;&amp; height &lt;= 0 ){ return; }
 
-  p.millis = function millis() {
-    return (new Date).getTime() - start;
-  };
-  
-  p.ortho = function ortho(){};
-  
-  p.translate = function translate( x, y ) {
-    curContext.translate( x, y );
-  };
-  
-  p.scale = function scale( x, y ) {
-    curContext.scale( x, y || x );
-  };
-  
-  p.rotate = function rotate( aAngle ) {
-    curContext.rotate( aAngle );
-  };
-  
-  p.pushMatrix = function pushMatrix() {
-    curContext.save();
-  };
-  
-  p.popMatrix = function popMatrix() {
-    curContext.restore();
-  };
-  
-  p.redraw = function redraw() {
+      curContext.beginPath();
+      
+      if( curEllipseMode == p.RADIUS ){
+        width *= 2;
+        height *= 2;
+      }     
+      
+      var offsetStart = 0;
+      
+      // Shortcut for drawing a circle
+      if( width == height ){
+      
+        curContext.arc( x - offsetStart, y - offsetStart, width / 2, 0, p.TWO_PI, false );
+      
+      }else{
+      
+        var w = width/2,
+            h = height/2,
+            C = 0.5522847498307933;
+        var c_x = C * w,
+            c_y = C * h;
+
+//!      Do we still need this? I hope the Canvas arc() more capable by now?
+        curContext.moveTo( x + w, y );
+        curContext.bezierCurveTo( x+w    ,   y-c_y  ,   x+c_x  ,   y-h   ,   x    ,   y-h  );
+        curContext.bezierCurveTo( x-c_x  ,   y-h    ,   x-w    ,   y-c_y ,   x-w  ,   y    );
+        curContext.bezierCurveTo( x-w    ,   y+c_y  ,   x-c_x  ,   y+h, x,   y+h           );
+        curContext.bezierCurveTo( x+c_x  ,   y+h    ,   x+w    ,   y+c_y ,   x+w  ,   y    );
+      
+      }
     
-    if ( hasBackground ) {
-      p.background();
-    }
+      if( doFill    ){ curContext.fill();   }
+      if( doStroke  ){ curContext.stroke(); }
+      
+      curContext.closePath();
+      
+    };
 
-    p.frameCount++;
-    
-    inDraw = true;
-    p.pushMatrix();
-    p.draw();
-    p.popMatrix();
-    inDraw = false;
-  };
-  
-  p.loop = function loop() {
-    if (loopStarted)
-      return;
-    
-    looping = setInterval(function() {
-      try {
-        p.redraw();  
+
+
+    ////////////////////////////////////////////////////////////////////////////
+    // Raster drawing functions
+    ////////////////////////////////////////////////////////////////////////////
+
+    p.save = function save( file ){};
+
+    p.loadImage = function loadImage( file ){
+      var img = document.getElementById( file );
+      
+      if ( !img ){ return; }
+      
+      var h = img.height,
+          w = img.width;
+
+      var canvas = document.createElement( &quot;canvas&quot; );
+      canvas.width = w;
+      canvas.height = h;
+      var context = canvas.getContext( &quot;2d&quot; );
+
+      context.drawImage( img, 0, 0 );
+      var data = buildImageObject( context.getImageData( 0, 0, w, h ) );
+      data.img = img;
+      return data;
+    };
+
+    // Gets a single pixel from Canvas
+    p.get = function get( x, y ){
+      
+      if( !arguments.length ){
+        var c = p.createGraphics( p.width, p.height );
+        c.image( curContext, 0, 0 );
+        return c;
       }
-      catch(e) {
-        clearInterval( looping );
-        throw e;
+
+      if( !getLoaded ){
+        getLoaded = buildImageObject( curContext.getImageData( 0, 0, p.width, p.height ) );
       }
-    }, 1000 / curFrameRate );
-    
-    loopStarted = true;
-  };
-  
-  p.frameRate = function frameRate( aRate ) {
-    curFrameRate = aRate;
-  };
-  
-  p.background = function background( img ) {
-    if ( arguments.length ) {
-      if ( img &amp;&amp; img.img ) {
-        curBackground = img;
-      } else {
-        curBackground = p.color.apply( this, arguments );
+
+      return getLoaded.get( x, y );
+      
+    };
+
+    // Paints a pixel array into the canvas
+    p.set = function set( x, y, obj ){
+      
+      if( obj &amp;&amp; obj.img ){
+        
+        p.image( obj, x, y );
+        
+      }else{
+      
+        var oldFill = curContext.fillStyle,
+            color   = obj;
+            
+        curContext.fillStyle = color;
+        curContext.fillRect( Math.round( x ), Math.round( y ), 1, 1 );
+        curContext.fillStyle = oldFill;
+        
       }
-    }    
+      
+    };
 
-    if ( curBackground.img ) {
-      p.image( curBackground, 0, 0 );
-    } else {
-      var oldFill = curContext.fillStyle;
-      curContext.fillStyle = curBackground + &quot;&quot;;
-      curContext.fillRect( 0, 0, p.width, p.height );
-      curContext.fillStyle = oldFill;
-    }
-  };
-  
-  // Clear function - F1LT3R - Not native to Processing
-  p.clear = function clear ( x, y, width, height ) {    
-    arguments.length==0?
-      curContext.clearRect(0,0,p.width,p.height):
-      curContext.clearRect(x,y,width,height);     
-  }
-  
-  // Str() - F1LT3R
-  p.str = function str( aNumber ){
-      return aNumber+'';
-  }
-  
-  p.sq = function sq( aNumber ) {
-    return aNumber * aNumber;
-  };
+    // Gets a 1-Dimensional pixel array from Canvas
+    p.loadPixels = function(){
+      p.pixels = buildImageObject( curContext.getImageData(0, 0, p.width, p.height) ).pixels;
+    };
 
-  p.sqrt = function sqrt( aNumber ) {
-    return Math.sqrt( aNumber );
-  };
+    // Draws a 1-Dimensional pixel array to Canvas
+    p.updatePixels = function() {
+    
+      var colors = /(\d+),(\d+),(\d+),(\d+)/,
+          pixels = {};
+          
+      pixels.width   = p.width;
+      pixels.height = p.height;
+      pixels.data   = [];
 
-  // ngsqrt() - Personal Function - F1LT3R // Allows me to calculate the positive square root of a negative number
-  p.ngsqrt = function ngsqrt( aNumber ) {
-    if (aNumber &lt;= 0){
-      return Math.sqrt( -aNumber );
-    } else {
-      return Math.sqrt( aNumber );
-    }
-  };
-  
-  p.int = function int( aNumber ) {
-    return Math.floor( aNumber );    
-  };
+      if( curContext.createImageData ){
+        pixels = curContext.createImageData( p.width, p.height );
+      }
 
-  p.min = function min( aNumber, aNumber2 ) {
-    return Math.min( aNumber, aNumber2 );
-  };
+      var data   = pixels.data,
+          pos   = 0;
 
-  p.max = function max( aNumber, aNumber2 ) {
-    return Math.max( aNumber, aNumber2 );
-  };
+      for( var i = 0, l = p.pixels.length; i &lt; l; i++ ){
 
-  p.ceil = function ceil( aNumber ) {
-    return Math.ceil( aNumber );
-  };
-  
-  p.round = function round( aNumber ) {
-    return Math.round( aNumber );
-  };
+        var c = ( p.pixels[i] || &quot;rgba(0,0,0,1)&quot; ).match( colors );
 
-  p.norm = function norm( aNumber, low, high ) {
-    var range = high-low;
-    return ( ( 1 / range ) * aNumber ) - ( ( 1 / range ) * low );
-  };
+        data[ pos + 0 ] =   parseInt( c[ 1 ] );
+        data[ pos + 1 ] =   parseInt( c[ 2 ] );
+        data[ pos + 2 ] =   parseInt( c[ 3 ] );
+        data[ pos + 3 ] = parseFloat( c[ 4 ] ) * 255;
 
-  p.lerp = function lerp( value1, value2, amt ) {
-    var range = value2 - value1;
-    return ( range * amt ) + value1;
-  }
-  
-  p.floor = function floor( aNumber ) {
-    return Math.floor( aNumber );
-  };
+        pos += 4;
+        
+      }
 
-  p.float = function float( aNumber ) {
-      return parseFloat( aNumber );
-      /*
-      return typeof aNumber == &quot;string&quot; ?
-      p.float( aNumber.charCodeAt(0) ) :
-      parseFloat( aNumber );
-      */
-  };
+      curContext.putImageData( pixels, 0, 0 );
+      
+    };
 
-  p.byte = function byte( aNumber ) {
-    return aNumber || 0;
-  };
-  
-  p.random = function random( aMin, aMax ) {
-    return arguments.length == 2 ?
-      aMin + (Math.random() * (aMax - aMin)) :
-      Math.random() * aMin;
-  };
+    p.background = function background( img ) {
+      
+      if( arguments.length ){
+        
+        if( img &amp;&amp; img.img ){
+          curBackground = img;
+        }else{
+          curBackground = p.color.apply( this, arguments );
+        }
+      
+      }
 
-  // From: http://freespace.virgin.net/hugo.elias/models/m_perlin.htm
-  p.noise = function( x, y, z ) {
-    return arguments.length &gt;= 2 ?
-      PerlinNoise_2D( x, y ) :
-      PerlinNoise_2D( x, x );
-  };
+      if( curBackground.img ){
+        p.image( curBackground, 0, 0 );
+      }else{
+        var oldFill = curContext.fillStyle;
+        curContext.fillStyle = curBackground + &quot;&quot;;
+        curContext.fillRect( 0, 0, p.width, p.height );
+        curContext.fillStyle = oldFill;
+      }
+      
+    };
+    
+    // Clears hole in the Canvas or the whole Canvas
+    p.clear = function clear ( x, y, width, height ) {    
+      if( arguments.length == 0 ){
+        curContext.clearRect( x, y, width, height );
+      }else{
+        curContext.clearRect( 0, 0, p.width, p.height );
+      }
+    }
+    
+    p.AniSprite = function( prefix, frames ){    
+      this.images = [];
+      this.pos = 0;
 
-  function Noise(x, y) {
-    var n = x + y * 57;
-    n = (n&lt;&lt;13) ^ n;
-    return Math.abs(1.0 - (((n * ((n * n * 15731) + 789221) + 1376312589) &amp; 0x7fffffff) / 1073741824.0));
-  };
+      for( var i = 0; i &lt; frames; i++ ){
+        this.images.push( prefix + p.nf( i, ( &quot;&quot; + frames ).length ) + &quot;.gif&quot; );
+      }
 
-  function SmoothedNoise(x, y) {
-    var corners = ( Noise(x-1, y-1)+Noise(x+1, y-1)+Noise(x-1, y+1)+Noise(x+1, y+1) ) / 16;
-    var sides   = ( Noise(x-1, y)  +Noise(x+1, y)  +Noise(x, y-1)  +Noise(x, y+1) ) /  8;
-    var center  =  Noise(x, y) / 4;
-    return corners + sides + center;
-  };
+      this.display = function( x, y ){
+        p.image( this.images[ this.pos ], x, y );
 
-  function InterpolatedNoise(x, y) {
-    var integer_X    = Math.floor(x);
-    var fractional_X = x - integer_X;
+        if( ++this.pos &gt;= frames ){
+          this.pos = 0;
+        }
+      };
 
-    var integer_Y    = Math.floor(y);
-    var fractional_Y = y - integer_Y;
+      this.getWidth   = function(){ return getImage( this.images[ 0 ] ).width;  };
+      this.getHeight  = function(){ return getImage( this.images[ 0 ] ).height; };
+    };
 
-    var v1 = SmoothedNoise(integer_X,     integer_Y);
-    var v2 = SmoothedNoise(integer_X + 1, integer_Y);
-    var v3 = SmoothedNoise(integer_X,     integer_Y + 1);
-    var v4 = SmoothedNoise(integer_X + 1, integer_Y + 1);
+    function buildImageObject( obj ){
+ 
+      var pixels = obj.data;
+      var data = p.createImage( obj.width, obj.height );
 
-    var i1 = Interpolate(v1 , v2 , fractional_X);
-    var i2 = Interpolate(v3 , v4 , fractional_X);
+      if( data.__defineGetter__ &amp;&amp; data.__lookupGetter__ &amp;&amp; !data.__lookupGetter__( &quot;pixels&quot; ) ){
+        
+        var pixelsDone;
+        
+        data.__defineGetter__( &quot;pixels&quot;, function(){
+          
+          if( pixelsDone ){
+            return pixelsDone;
+          }
+          pixelsDone = [];
+
+          for( var i = 0; i &lt; pixels.length; i += 4 ){
+            pixelsDone.push(
+              p.color(
+                pixels[ i ],
+                pixels[ i + 1 ],
+                pixels[ i + 2 ],
+                pixels[ i + 3 ])
+              );
+          }
 
-    return Interpolate(i1 , i2 , fractional_Y);
-  }
+          return pixelsDone;
+        
+        });
+        
+      }else{
+        
+        data.pixels = [];
+
+        for ( var i = 0; i &lt; pixels.length; i += 4 ){
+          data.pixels.push( p.color(
+            pixels[ i ],
+            pixels[ i + 1 ],
+            pixels[ i + 2 ],
+            pixels[ i + 3 ]
+          ));
+        }
+      
+      }
 
-  function PerlinNoise_2D(x, y) {
-      var total = 0;
-      var p = 0.25;
-      var n = 3;
+      return data;
+    }
 
-      for ( var i = 0; i &lt;= n; i++ ) {
-          var frequency = Math.pow(2, i);
-          var amplitude = Math.pow(p, i);
+    p.createImage = function createImage( w, h, mode ){
+      
+      var data    = {};
+      data.width  = w;
+      data.height = h;
+      data.data   = [];
 
-          total = total + InterpolatedNoise(x * frequency, y * frequency) * amplitude;
+      if( curContext.createImageData ) {
+        data = curContext.createImageData( w, h );
       }
 
-      return total;
-  }
+      data.pixels = new Array( w * h );
+      
+      data.get = function( x, y ){
+        return this.pixels[ w * y + x ];
+      };
+      
+      data._mask = null;
+      
+      data.mask = function( img ){
+        this._mask = img;
+      };
+      
+      data.loadPixels = function(){};
+      data.updatePixels = function(){};
 
-  function Interpolate(a, b, x) {
-    var ft = x * p.PI;
-    var f = (1 - p.cos(ft)) * .5;
-    return  a*(1-f) + b*f;
-  }
+      return data;
+      
+    };
 
-  p.abs = function abs( aNumber ) {
-    return Math.abs( aNumber );
-  };
-  
-  p.cos = function cos( aNumber ) {
-    return Math.cos( aNumber );
-  };
-  
-  p.sin = function sin( aNumber ) {
-    return Math.sin( aNumber );
-  };
-  
-  p.pow = function pow( aNumber, aExponent ) {
-    return Math.pow( aNumber, aExponent );
-  };
-  
-  p.constrain = function constrain( aNumber, aMin, aMax ) {
-    return Math.min( Math.max( aNumber, aMin ), aMax );
-  };
-  
-  p.sqrt = function sqrt( aNumber ) {
-    return Math.sqrt( aNumber );
-  };
-  
-  p.atan2 = function atan2( aNumber, aNumber2 ) {
-    return Math.atan2( aNumber, aNumber2 );
-  };
-  
-  p.radians = function radians( aAngle ) {
-    return ( aAngle / 180 ) * p.PI;
-  };
-  
-  p.degrees = function degrees( aAngle ) {
-    aAngle = ( aAngle * 180 ) / p.PI;  
-    if (aAngle &lt; 0) {aAngle = 360 + aAngle}    
-    return aAngle;
-  };
-  
-  p.size = function size( aWidth, aHeight ) {
-    var fillStyle = curContext.fillStyle;
-    var strokeStyle = curContext.strokeStyle;
+    p.createGraphics = function createGraphics( w, h ){
+ 
+      var canvas = document.createElement( &quot;canvas&quot; );
+      var ret = buildProcessing( canvas );
+      ret.size( w, h );
+      ret.canvas = canvas;
+      return ret;
+ 
+    };
 
-    curElement.width = p.width = aWidth;
-    curElement.height = p.height = aHeight;
 
-    curContext.fillStyle = fillStyle;
-    curContext.strokeStyle = strokeStyle;
-  };
-  
-  p.noStroke = function noStroke() {
-    doStroke = false;
-  };
-  
-  p.noFill = function noFill() {
-    doFill = false;
-  };
-  
-  p.smooth = function smooth(){};
-  
-  p.noSmooth = function noSmooth(){
+    p.tint = function tint( rgb, a ){
+      curTint = a;
+    };
+
+    function getImage( img ){
+ 
+      if( typeof img == &quot;string&quot; ){
+        return document.getElementById( img );
+      }
+
+      if( img.img || img.canvas ){
+        return img.img || img.canvas;
+      }
+
+      for( var i = 0, l = img.pixels.length; i &lt; l; i++ ){
+        
+        var pos = i * 4;
+        var c = ( img.pixels[ i ] || &quot;rgba(0,0,0,1)&quot; ).slice( 5, - 1 ).split( &quot;,&quot; );
+        
+        img.data[ pos + 0 ] =   parseInt( c[ 0 ] );
+        img.data[ pos + 1 ] =   parseInt( c[ 1 ] );
+        img.data[ pos + 2 ] =   parseInt( c[ 2 ] );
+        img.data[ pos + 3 ] = parseFloat( c[ 3 ] ) * 100;
       
-  };
-  
-  
-  p.noLoop = function noLoop() {
-    doLoop = false;
-  };
-  
-  p.fill = function fill() {
-    doFill = true;
-    curContext.fillStyle = p.color.apply( this, arguments );    
-  };
-  
-  p.stroke = function stroke() {
-    doStroke = true;
-    curContext.strokeStyle = p.color.apply( this, arguments );
-  };
+      }
 
-  p.strokeWeight = function strokeWeight( w ) {
-    curContext.lineWidth = w;
-  };
-  
-  p.point = function point( x, y ) {
-    var oldFill = curContext.fillStyle;
-    curContext.fillStyle = curContext.strokeStyle;
-    curContext.fillRect( Math.round( x ), Math.round( y ), 1, 1 );
-    curContext.fillStyle = oldFill;
-  };
+      var canvas = document.createElement( &quot;canvas&quot; );
+      canvas.width = img.width;
+      canvas.height = img.height;
+      
+      var context = canvas.getContext( &quot;2d&quot; );
+      context.putImageData( img, 0, 0 );
 
-  p.get = function get( x, y ) {
-    if ( arguments.length == 0 ) {
-      var c = p.createGraphics( p.width, p.height );
-      c.image( curContext, 0, 0 );
-      return c;
-    }
+      img.canvas = canvas;
 
-    if ( !getLoaded ) {
-      getLoaded = buildImageObject( curContext.getImageData(0, 0, p.width, p.height) );
+      return canvas;
     }
 
-    return getLoaded.get( x, y );
-  };
+    p.image = function image( img, x, y, w, h ){
+      
+      x = x || 0;
+      y = y || 0;
 
-  p.set = function set( x, y, obj ) {
-    if ( obj &amp;&amp; obj.img ) {
-      p.image( obj, x, y );
-    } else {
-      var oldFill = curContext.fillStyle;
-      var color = obj;
-      curContext.fillStyle = color;
-      curContext.fillRect( Math.round( x ), Math.round( y ), 1, 1 );
-      curContext.fillStyle = oldFill;
-    }
-  };
-  
-  p.arc = function arc( x, y, width, height, start, stop ) {       if ( width &lt;= 0 )
-     return;
+      var obj = getImage( img );
 
-   if ( curEllipseMode == p.CORNER ) {
-     x += width / 2;
-     y += height / 2;
-   }
-      curContext.moveTo( x, y );
-   curContext.beginPath();   
-   curContext.arc( x, y, curEllipseMode == p.CENTER_RADIUS ? width : width/2, start, stop, false );
+      if( curTint &gt;= 0 ){
+        var oldAlpha = curContext.globalAlpha;
+        curContext.globalAlpha = curTint / opacityRange;
+      }
 
-   if ( doStroke )
-     curContext.stroke();
+      if( arguments.length == 3 ){
+        curContext.drawImage( obj, x, y );
+      }else{
+        curContext.drawImage( obj, x, y, w, h );
+      }
 
-   curContext.lineTo( x, y );
+      if( curTint &gt;= 0 ){
+        curContext.globalAlpha = oldAlpha;
+      }
 
-   if ( doFill )
-     curContext.fill();
-   
-   curContext.closePath();
-  };
-  
-  p.line = function line( x1, y1, x2, y2 ) {   
-    curContext.lineCap = &quot;round&quot;;
-    curContext.beginPath();
-  
-    curContext.moveTo( x1 || 0, y1 || 0 );
-    curContext.lineTo( x2 || 0, y2 || 0 );
-    
-    curContext.stroke();
-    
-    curContext.closePath();
-  };
+      if( img._mask ){
+        var oldComposite = curContext.globalCompositeOperation;
+        curContext.globalCompositeOperation = &quot;darker&quot;;
+        p.image( img._mask, x, y );
+        curContext.globalCompositeOperation = oldComposite;
+      }
+      
+    };    
 
-  p.bezier = function bezier( x1, y1, x2, y2, x3, y3, x4, y4 ) {
-    curContext.lineCap = &quot;butt&quot;;
-    curContext.beginPath();
-  
-    curContext.moveTo( x1, y1 );
-    curContext.bezierCurveTo( x2, y2, x3, y3, x4, y4 );
+
+
+    ////////////////////////////////////////////////////////////////////////////
+    // Font handling
+    ////////////////////////////////////////////////////////////////////////////
     
-    curContext.stroke();
+    // Loads a font from an SVG or Canvas API
+    p.loadFont = function loadFont( name ){
+      
+      if( name.indexOf( &quot;.svg&quot; ) == - 1 ){
+
+        return {
+          name: name,
+          width: function( str ){
+            if( curContext.mozMeasureText ){
+              return curContext.mozMeasureText(
+                typeof str == &quot;number&quot; ?
+                  String.fromCharCode( str ) :
+                  str
+              ) / curTextSize;
+            }else{
+              return 0;
+            }
+          }
+        };
+        
+      }else{
+        
+        // If the font is a glyph, calculate by SVG table     
+        var font = p.loadGlyphs( name );
+
+        return {
+          name          : name,
+          glyph         : true,
+          units_per_em  : font.units_per_em,
+          horiz_adv_x   : 1 / font.units_per_em * font.horiz_adv_x,
+          ascent        : font.ascent,
+          descent       : font.descent,
+          width         :
+            function( str ){
+              var width = 0;
+              var len   = str.length;
+              for( var i = 0; i &lt; len; i++ ){                          
+                try{ width += parseFloat( p.glyphLook( p.glyphTable[ name ], str[ i ] ).horiz_adv_x ); }
+                catch( e ){ ; }
+              }
+              return width / p.glyphTable[ name ].units_per_em;
+            }
+        }
+        
+      }
     
-    curContext.closePath();
-  };
-
-  p.triangle = function triangle( x1, y1, x2, y2, x3, y3 ) {
-    p.beginShape();
-    p.vertex( x1, y1 );
-    p.vertex( x2, y2 );
-    p.vertex( x3, y3 );
-    p.endShape();
-  };
+    };
 
-  p.quad = function quad( x1, y1, x2, y2, x3, y3, x4, y4 ) {
-    curContext.lineCap = &quot;square&quot;;
-    p.beginShape();
-    p.vertex( x1, y1 );
-    p.vertex( x2, y2 );
-    p.vertex( x3, y3 );
-    p.vertex( x4, y4 );
-    p.endShape();
-  };
-  
-  p.rect = function rect( x, y, width, height ) {
-    if ( width == 0 &amp;&amp; height == 0 )
-      return;
+    // Sets a 'current font' for use
+    p.textFont = function textFont( name, size ){
+      curTextFont = name;
+      p.textSize( size );
+    };
 
-    curContext.beginPath();
-    
-    var offsetStart = 0;
-    var offsetEnd = 0;
+    // Sets the font size
+    p.textSize = function textSize( size ){
+//!   Was this meant to return textSize value if no arguments were passed?
+      if( size ){
+        curTextSize = size;
+      }
+    };
 
-    if ( curRectMode == p.CORNERS ) {
-      width -= x;
-      height -= y;
-    }
+    p.textAlign = function textAlign(){};
+
+    // A lookup table for characters that can not be referenced by Object 
+    p.glyphLook = function glyphLook( font, chr ){
+
+      try{
+        switch( chr ){
+          case &quot;1&quot;  : return font[ &quot;one&quot;          ]; break;
+          case &quot;2&quot;  : return font[ &quot;two&quot;          ]; break;
+          case &quot;3&quot;  : return font[ &quot;three&quot;        ]; break;
+          case &quot;4&quot;  : return font[ &quot;four&quot;         ]; break;
+          case &quot;5&quot;  : return font[ &quot;five&quot;         ]; break;
+          case &quot;6&quot;  : return font[ &quot;six&quot;          ]; break;
+          case &quot;7&quot;  : return font[ &quot;seven&quot;        ]; break;
+          case &quot;8&quot;  : return font[ &quot;eight&quot;        ]; break;
+          case &quot;9&quot;  : return font[ &quot;nine&quot;         ]; break;
+          case &quot;0&quot;  : return font[ &quot;zero&quot;         ]; break;
+          case &quot; &quot;  : return font[ &quot;space&quot;        ]; break;
+          case &quot;$&quot;  : return font[ &quot;dollar&quot;       ]; break;
+          case &quot;!&quot;  : return font[ &quot;exclam&quot;       ]; break;
+          case '&quot;'  : return font[ &quot;quotedbl&quot;     ]; break;
+          case &quot;#&quot;  : return font[ &quot;numbersign&quot;   ]; break;
+          case &quot;%&quot;  : return font[ &quot;percent&quot;      ]; break;
+          case &quot;&amp;&quot;  : return font[ &quot;ampersand&quot;    ]; break;
+          case &quot;'&quot;  : return font[ &quot;quotesingle&quot;  ]; break;
+          case &quot;(&quot;  : return font[ &quot;parenleft&quot;    ]; break;
+          case &quot;)&quot;  : return font[ &quot;parenright&quot;   ]; break;
+          case &quot;*&quot;  : return font[ &quot;asterisk&quot;     ]; break;
+          case &quot;+&quot;  : return font[ &quot;plus&quot;         ]; break;
+          case &quot;,&quot;  : return font[ &quot;comma&quot;        ]; break;
+          case &quot;-&quot;  : return font[ &quot;hyphen&quot;       ]; break;
+          case &quot;.&quot;  : return font[ &quot;period&quot;       ]; break;
+          case &quot;/&quot;  : return font[ &quot;slash&quot;        ]; break;
+          case &quot;_&quot;  : return font[ &quot;underscore&quot;   ]; break;
+          case &quot;:&quot;  : return font[ &quot;colon&quot;        ]; break;
+          case &quot;;&quot;  : return font[ &quot;semicolon&quot;    ]; break;
+          case &quot;&lt;&quot;  : return font[ &quot;less&quot;         ]; break;
+          case &quot;=&quot;  : return font[ &quot;equal&quot;        ]; break;
+          case &quot;&gt;&quot;  : return font[ &quot;greater&quot;      ]; break;
+          case &quot;?&quot;  : return font[ &quot;question&quot;     ]; break;
+          case &quot;@&quot;  : return font[ &quot;at&quot;           ]; break;
+          case &quot;[&quot;  : return font[ &quot;bracketleft&quot;  ]; break;
+          case &quot;\\&quot; : return font[ &quot;backslash&quot;    ]; break;
+          case &quot;]&quot;  : return font[ &quot;bracketright&quot; ]; break;
+          case &quot;^&quot;  : return font[ &quot;asciicircum&quot;  ]; break;
+          case &quot;`&quot;  : return font[ &quot;grave&quot;        ]; break;
+          case &quot;{&quot;  : return font[ &quot;braceleft&quot;    ]; break;
+          case &quot;|&quot;  : return font[ &quot;bar&quot;          ]; break;
+          case &quot;}&quot;  : return font[ &quot;braceright&quot;   ]; break;
+          case &quot;~&quot;  : return font[ &quot;asciitilde&quot;   ]; break;
+          // If the character is not 'special', access it by object reference
+          default   : return font[ chr            ]; break;
+        }
+      }catch( e ){ ; }
     
-    if ( curRectMode == p.RADIUS ) {
-      width *= 2;
-      height *= 2;
     }
     
-    if ( curRectMode == p.CENTER || curRectMode == p.RADIUS ) {
-      x -= width / 2;
-      y -= height / 2;
-    }
-  
-    curContext.rect(
-      Math.round( x ) - offsetStart,
-      Math.round( y ) - offsetStart,
-      Math.round( width ) + offsetEnd,
-      Math.round( height ) + offsetEnd
-    );
+    // Print some text to the Canvas
+    p.text = function text( str, x, y ){
       
-    if ( doFill )
-      curContext.fill();
+      // If the font is a standard Canvas font...
+      if( !curTextFont.glyph ){
       
-    if ( doStroke )
-      curContext.stroke();
-    
-    curContext.closePath();
-  };
-  
-  p.ellipse = function ellipse( x, y, width, height ) {
-    x = x || 0;
-    y = y || 0;
-
-    if ( width &lt;= 0 &amp;&amp; height &lt;= 0 )
-      return;
-
-    curContext.beginPath();
-    
-    if ( curEllipseMode == p.RADIUS ) {
-      width *= 2;
-      height *= 2;
-    }     
-    
-    var offsetStart = 0;
-    
-    // Shortcut for drawing a circle
-    if ( width == height ) {
-      curContext.arc( x - offsetStart, y - offsetStart, width / 2, 0, Math.PI * 2, false );
-    } else {
-      var w = width/2;
-      var h = height/2;
-      var C = 0.5522847498307933;
-      var c_x = C * w;
-      var c_y = C * h;
-      curContext.moveTo(x+w, y);
-      curContext.bezierCurveTo(x+w, y-c_y, x+c_x, y-h, x, y-h);
-      curContext.bezierCurveTo(x-c_x, y-h, x-w, y-c_y, x-w, y);
-      curContext.bezierCurveTo(x-w, y+c_y, x-c_x, y+h, x, y+h);
-      curContext.bezierCurveTo(x+c_x, y+h, x+w, y+c_y, x+w, y);
-    }
-  
-    if ( doFill )
-      curContext.fill();
+        if( str &amp;&amp; curContext.mozDrawText ){
+
+          curContext.save();
+          curContext.mozTextStyle = curTextSize + &quot;px &quot; + curTextFont.name;
+          curContext.translate( x, y );
+          curContext.mozDrawText( 
+            typeof str == &quot;number&quot; ?
+            String.fromCharCode( str ) :
+            str ) ;
+          curContext.restore();
+
+        }
+        
+      }else{
+        
+        // If the font is a Batik SVG font...
+        var font = p.glyphTable[ curTextFont.name ];
+        curContext.save();
+        curContext.translate( x, y + curTextSize );
+        
+        var upem      = font[ &quot;units_per_em&quot; ],
+            newScale = 1 / upem * curTextSize;
+        
+        curContext.scale( newScale, newScale );
+        
+        var len = str.length;
+        
+        for(var i = 0; i &lt; len; i++ ){
+          // Test character against glyph table
+          try{ p.glyphLook( font, str[ i ] ).draw(); }
+          catch( e ){ ; }
+        }
+        
+        curContext.restore();
+      }
       
-    if ( doStroke )
-      curContext.stroke();
+    };
     
-    curContext.closePath();
-  };
+    // Load Batik SVG Fonts and parse to pre-def objects for quick rendering 
+    p.loadGlyphs = function loadGlyph( url ){
+        
+        // Load and parse Batik SVG font as XML into a Processing Glyph object
+        var loadXML = function loadXML(){
+        
+          try{
+                      var xmlDoc = new ActiveXObject( &quot;Microsoft.XMLDOM&quot; );
+          }
+          catch( e ){ 
+                      try{
+                            xmlDoc=document.implementation.createDocument( &quot;&quot;, &quot;&quot;, null );
+                      }
+                      catch( e ){
+                            p.println( e.message );
+                            return;
+                      }
+          };
+          
+          try{
+                      xmlDoc.async = false;
+                      xmlDoc.load( url );
+                      parse( xmlDoc.getElementsByTagName( &quot;svg&quot; )[ 0 ] );
+          }
+          catch( e ){
+                      // Google Chrome, Safari etc.
+                      try{
+                            p.println( e.message );
+                            var xmlhttp = new window.XMLHttpRequest();
+                            xmlhttp.open( &quot;GET&quot;, url, false );
+                            xmlhttp.send( null );
+                            parse( xmlhttp.responseXML.documentElement );
+                      }
+                      catch( e ){ ; }
+          }
+        };
+        
+        // Return arrays of SVG commands and coords
+        var regex = function regex( needle, hay ){
+          
+          var regexp  = new RegExp( needle, &quot;g&quot; ),
+              results = [],
+              i       = 0;
+              
+          while( results[ i ] = regexp.exec( hay ) ){ i++; }
+          return results;
+        
+        }
 
-  p.cursor = function(mode){
-    document.body.style.cursor=mode;
-  }
+        // Parse SVG font-file into block of Canvas commands
+        var parse = function parse( svg ){
+          
+          // Store font attributes
+          var font = svg.getElementsByTagName( &quot;font&quot; );
+          p.glyphTable[ url ][ &quot;horiz_adv_x&quot;  ] = font[ 0 ].getAttribute( &quot;horiz-adv-x&quot; );      
+          
+          var font_face = svg.getElementsByTagName( &quot;font-face&quot; )[ 0 ];                  
+          p.glyphTable[ url ][ &quot;units_per_em&quot; ] = parseFloat( font_face.getAttribute( &quot;units-per-em&quot;) );
+          p.glyphTable[ url ][ &quot;ascent&quot;       ] = parseFloat( font_face.getAttribute( &quot;ascent&quot;      ) );
+          p.glyphTable[ url ][ &quot;descent&quot;      ] = parseFloat( font_face.getAttribute( &quot;descent&quot;     ) );          
+          
+          var getXY = &quot;[0-9\-]+&quot;,
+              glyph = svg.getElementsByTagName( &quot;glyph&quot; ),
+              len   = glyph.length;
 
-  p.link = function( href, target ) {
-    window.location = href;
-  };
+          // Loop through each glyph in the SVG
+          for( var i = 0; i &lt; len; i++ ){
+            
+            // Store attributes for this glyph
+            var unicode = glyph[ i ].getAttribute( &quot;unicode&quot; );
+            var name = glyph[ i ].getAttribute( &quot;glyph-name&quot; );
+            var horiz_adv_x = glyph[ i ].getAttribute( &quot;horiz-adv-x&quot; );
+            if( horiz_adv_x == null ){ var horiz_adv_x = p.glyphTable[ url ][ 'horiz_adv_x' ]; }
+            
+            var buildPath = function buildPath( d ){ 
+              
+              var c = regex( &quot;[A-Za-z][0-9\- ]+|Z&quot;, d );                                                    
+              
+              // Begin storing path object 
+              var path = &quot;var path={draw:function(){curContext.beginPath();curContext.save();&quot;;
+              
+              var x       = 0,
+                  y       = 0,
+                  cx      = 0,
+                  cy      = 0,
+                  nx      = 0,
+                  ny      = 0,
+                  d       = 0,
+                  a       = 0,
+                  lastCom = &quot;&quot;,
+                  lenC    = c.length - 1;
+              
+              // Loop through SVG commands translating to canvas eqivs functions in path object
+              for( var j = 0; j &lt; lenC; j++ ){
+                
+                var com = c[ j ][ 0 ],
+                    xy   = regex( getXY, com );
+       
+                switch( com[ 0 ] ){
+                
+                  case &quot;M&quot;: //curContext.moveTo(x,-y);
+                    x = parseFloat( xy[ 0 ][ 0 ] );
+                    y = parseFloat( xy[ 1 ][ 0 ] );              
+//!                 Brackets needed on (-y)?
+                    path += &quot;curContext.moveTo(&quot;+ x +&quot;,&quot;+ (-y) +&quot;);&quot;;
+                    break;
+
+                  case &quot;L&quot;: //curContext.lineTo(x,-y);
+                    x = parseFloat( xy[ 0 ][ 0 ] );
+                    y = parseFloat( xy[ 1 ][ 0 ] );
+                    path += &quot;curContext.lineTo(&quot;+ x +&quot;,&quot;+ (-y) +&quot;);&quot;;
+                    break;
+
+                  case &quot;H&quot;://curContext.lineTo(x,-y)
+                    x = parseFloat( xy[ 0 ][ 0 ] );
+                    path += &quot;curContext.lineTo(&quot;+ x +&quot;,&quot;+ (-y) +&quot;);&quot;;
+                    break;
+
+                  case &quot;V&quot;://curContext.lineTo(x,-y);
+                    y = parseFloat( xy[ 0 ][ 0 ] );              
+                    path += &quot;curContext.lineTo(&quot;+ x +&quot;,&quot;+ (-y) +&quot;);&quot;;
+                    break;
+
+                  case &quot;T&quot;://curContext.quadraticCurveTo(cx,-cy,nx,-ny);
+                    nx = parseFloat( xy[ 0 ][ 0 ] );
+                    ny = parseFloat( xy[ 1 ][ 0 ] );
+
+                    if( lastCom == &quot;Q&quot; || lastCom == &quot;T&quot; ){
+
+                      d = Math.sqrt( Math.pow( x - cx, 2 ) + Math.pow( cy - y, 2 ) );
+                      a = Math.PI+Math.atan2( cx - x, cy - y );
+                      cx = x + ( Math.sin( a ) * ( d ) );
+                      cy = y + ( Math.cos( a ) * ( d ) );
+
+                    }else{
+                      cx = x;
+                      cy = y;
+                    }
+                    
+                    path += &quot;curContext.quadraticCurveTo(&quot;+ cx +&quot;,&quot;+ (-cy) +&quot;,&quot;+ nx +&quot;,&quot;+ (-ny) +&quot;);&quot;;
+                    x = nx;
+                    y = ny;
+                    break;
+                     
+                  case &quot;Q&quot;://curContext.quadraticCurveTo(cx,-cy,nx,-ny);
+                    cx = parseFloat( xy[ 0 ][ 0 ] );
+                    cy = parseFloat( xy[ 1 ][ 0 ] );
+                    nx = parseFloat( xy[ 2 ][ 0 ] );
+                    ny = parseFloat( xy[ 3 ][ 0 ] ); 
+                    path += &quot;curContext.quadraticCurveTo(&quot;+ cx +&quot;,&quot;+ (-cy) +&quot;,&quot;+ nx +&quot;,&quot;+ (-ny) +&quot;);&quot;;              
+                    x = nx;
+                    y = ny;
+                    break;
+
+                  case &quot;Z&quot;://curContext.closePath();
+                    path += &quot;curContext.closePath();&quot;;
+                    break;
+
+                }
+
+                lastCom = com[ 0 ];
 
-  p.loadPixels = function() {
-    p.pixels = buildImageObject( curContext.getImageData(0, 0, p.width, p.height) ).pixels;
-  };
+              }
 
-  p.updatePixels = function() {
-    var colors = /(\d+),(\d+),(\d+),(\d+)/;
-    var pixels = {};
-    pixels.width = p.width;
-    pixels.height = p.height;
-    pixels.data = [];
+              path += &quot;doStroke?curContext.stroke():0;&quot;;
+              path += &quot;doFill?curContext.fill():0;&quot;;
+              path += &quot;curContext.restore();&quot;;
+              path += &quot;curContext.translate(&quot;+ horiz_adv_x  +&quot;,0);&quot;;            
+              path += &quot;}}&quot;;
 
-    if ( curContext.createImageData ) {
-      pixels = curContext.createImageData( p.width, p.height );
-    }
+              return path;
 
-    var data = pixels.data;
-    var pos = 0;
+            }
+                     
+            var d = glyph[ i ].getAttribute( &quot;d&quot; );
+            
+            // Split path commands in glpyh 
+            if( d !== undefined ){
+            
+              var path = buildPath( d );
+              eval( path );
+              
+              // Store glyph data to table object
+              p.glyphTable[ url ][ name ] = {
+                name        : name,
+                unicode     : unicode,
+                horiz_adv_x : horiz_adv_x,
+                draw        : path.draw
+              }
 
-    for ( var i = 0, l = p.pixels.length; i &lt; l; i++ ) {
-      var c = (p.pixels[i] || &quot;rgba(0,0,0,1)&quot;).match(colors);
-      data[pos] = parseInt(c[1]);
-      data[pos+1] = parseInt(c[2]);
-      data[pos+2] = parseInt(c[3]);
-      data[pos+3] = parseFloat(c[4]) * 255; // changed to 255 - F1LT3R 08.11.15
-      pos += 4;
+            }
+         
+          } // finished adding glyphs to table
+          
+        }
+        
+        // Create a new object in glyphTable to store this font
+        p.glyphTable[ url ] = {};
+        
+        // Begin loading the Batik SVG font... 
+        loadXML( url );
+        
+        // Return the loaded font for attribute grabbing
+        return p.glyphTable[ url ];
     }
 
-    curContext.putImageData(pixels, 0, 0);
-  };
 
-  p.extendClass = function extendClass( obj, args, fn ) {
-    if ( arguments.length == 3 ) {
-      fn.apply( obj, args );
-    } else {
-      args.call( obj );
-    }
-  };
 
-  p.addMethod = function addMethod( object, name, fn ) {
-    if ( object[ name ] ) {
-      var args = fn.length;
+    ////////////////////////////////////////////////////////////////////////////
+    // Class methods
+    ////////////////////////////////////////////////////////////////////////////
+    
+    p.extendClass = function extendClass( obj, args, fn ){
+      if( arguments.length == 3 ){
+        fn.apply( obj, args );
+      }else{
+        args.call( obj );
+      }
+    };
+
+    p.addMethod = function addMethod( object, name, fn ){
+
+      if( object[ name ] ){
       
-      var oldfn = object[ name ];
-      object[ name ] = function() {
-        if ( arguments.length == args )
-          return fn.apply( this, arguments );
-        else
-          return oldfn.apply( this, arguments );
-      };
-    } else {
-       object[ name ] = fn;
-    }
-  };
+        var args   = fn.length,
+            oldfn = object[ name ];
+        
+        object[ name ] = function(){
+          
+          if( arguments.length == args ){
 
-  p.init = function init(code){
-    p.stroke( 0 );
-    p.fill( 255 );
-  
-    // Canvas has trouble rendering single pixel stuff on whole-pixel
-    // counts, so we slightly offset it (this is super lame).
-     curContext.translate( 0.5, 0.5 );    
-        
-    if ( code ) {      
-      (function(Processing){with (p){        
-        eval(parse(code, p));        
-      }})(p);      
-    }
-  
-    if (p.setup) {
-      inSetup = true;
-      p.setup();
-    }
+            return fn.apply( this, arguments );
+
+          }else{
+
+            return oldfn.apply( this, arguments );
+
+          }
+        
+        };
+      
+      }else{
+      
+        object[ name ] = fn;
+      
+      }
     
-    inSetup = false;
+    };
     
-    if ( p.draw ) {
-      if ( !doLoop ) {
-        p.redraw();
-      } else {
-        p.loop();
-      }
-    }
     
-    attach( curElement, &quot;mousemove&quot;, function(e) {
-      var scrollX = window.scrollX != null ? window.scrollX : window.pageXOffset;
-      var scrollY = window.scrollY != null ? window.scrollY : window.pageYOffset;            
-      p.pmouseX = p.mouseX;
-      p.pmouseY = p.mouseY;
-      p.mouseX = e.clientX - curElement.offsetLeft + scrollX;
-      p.mouseY = e.clientY - curElement.offsetTop + scrollY;    
 
-      if ( p.mouseMoved ) {
-        p.mouseMoved();
-      }
+    ////////////////////////////////////////////////////////////////////////////
+    // Set up environment
+    ////////////////////////////////////////////////////////////////////////////
+    
+    p.init = function init(code){
 
-      if ( mousePressed &amp;&amp; p.mouseDragged ) {
-        p.mouseDragged();
-      }    
-    });
+      p.stroke( 0 );
+      p.fill( 255 );
     
-    attach( curElement, &quot;mouseout&quot;, function(e) {
-      p.cursor(&quot;auto&quot;);
-    });
+      // Canvas has trouble rendering single pixel stuff on whole-pixel
+      // counts, so we slightly offset it (this is super lame).
+      
+      curContext.translate( 0.5, 0.5 );    
+          
+      // The fun bit!
+      if( code ){
+        (function( Processing ){
+          with ( p ){
+            eval(parse(code, p));
+          }
+        })( p );
+      }
     
-    attach( curElement, &quot;mousedown&quot;, function(e) {
-      mousePressed = true;
-      switch(e.which){
-        case 1: p.mouseButton = p.LEFT; break;
-        case 2: p.mouseButton = p.CENTER; break;
-        case 3: p.mouseButton = p.RIGHT; break; 
+      if( p.setup ){
+        inSetup = true;
+        p.setup();
       }
       
-      p.mouseDown = true;
+      inSetup = false;
       
-      if ( typeof p.mousePressed == &quot;function&quot; ) {
-        p.mousePressed();
-      } else {
-        p.mousePressed = true;
+      if( p.draw ){
+        if( !doLoop ){
+          p.redraw();
+        } else {
+          p.loop();
+        }
       }
-    });
-
-    attach( curElement, &quot;contextmenu&quot;, function(e) {
-      e.preventDefault();
-      e.stopPropagation();
-    });
+      
 
-    attach( curElement, &quot;mouseup&quot;, function(e) {
-      mousePressed = false;
+      //////////////////////////////////////////////////////////////////////////
+      // Event handling
+      //////////////////////////////////////////////////////////////////////////
       
-      if ( p.mouseClicked ) {
-        p.mouseClicked();
-      }
+      attach( curElement, &quot;mousemove&quot;  , function(e){
       
-      if ( typeof p.mousePressed != &quot;function&quot; ) {
-        p.mousePressed = false;
-      }
-
-      if ( p.mouseReleased ) {
-        p.mouseReleased();
-      }
-    });
-
-    attach( document, &quot;keydown&quot;, function(e) {
-      keyPressed = true;
+        var scrollX = window.scrollX != null ? window.scrollX : window.pageXOffset;
+        var scrollY = window.scrollY != null ? window.scrollY : window.pageYOffset;            
+      
+        p.pmouseX = p.mouseX;
+        p.pmouseY = p.mouseY;
+        p.mouseX   = e.clientX - curElement.offsetLeft + scrollX;
+        p.mouseY   = e.clientY - curElement.offsetTop + scrollY;    
 
-      p.key = e.keyCode + 32;
+        if( p.mouseMoved ){ p.mouseMoved(); }
+        if( mousePressed &amp;&amp; p.mouseDragged ){ p.mouseDragged(); }
+        
+      });
       
-      var i; 
-      for (i=0; i &lt; p.codedKeys.length; i++){                                        
-          if (p.key == p.codedKeys[i]){
-            switch(p.key){
-            case 70: p.keyCode = p.UP; break;
-            case 71: p.keyCode = p.RIGHT; break;
-            case 72: p.keyCode = p.DOWN; break;
-            case 69: p.keyCode = p.LEFT; break;          
-            }
-            p.key=p.CODED;
-          }
-      }
+      attach( curElement, &quot;mouseout&quot; , function( e ){ p.cursor(&quot;auto&quot;); });      
+      
+      attach( curElement, &quot;mousedown&quot;, function( e ){      
+        mousePressed = true;      
+        switch(e.which){
+          case 1: p.mouseButton = p.LEFT; break;
+          case 2: p.mouseButton = p.CENTER; break;
+          case 3: p.mouseButton = p.RIGHT; break; 
+        }        
+        p.mouseDown = true;        
+        if( typeof p.mousePressed == &quot;function&quot; ){ p.mousePressed(); }
+        else{ p.mousePressed = true; }
+      });
 
-      if ( e.shiftKey ) {
-        p.key = String.fromCharCode(p.key).toUpperCase().charCodeAt(0);
-      }
+      attach( curElement, &quot;contextmenu&quot;, function( e ){
+        e.preventDefault();
+        e.stopPropagation();
+      });
 
-      if ( typeof p.keyPressed == &quot;function&quot; ) {
-        p.keyPressed();
-      } else {
-        p.keyPressed = true;
-      }
-      
-    });
+      attach( curElement, &quot;mouseup&quot;, function( e ){
+        mousePressed = false;
+        if( p.mouseClicked ){ p.mouseClicked(); }        
+        if( typeof p.mousePressed != &quot;function&quot; ){ p.mousePressed = false; }
+        if( p.mouseReleased ){ p.mouseReleased(); }
+      });
 
-    attach( document, &quot;keyup&quot;, function(e) {
-      keyPressed = false;
+      attach( document, &quot;keydown&quot;, function( e ){
+        keyPressed = true;
+        p.key = e.keyCode + 32;               
+        var i, len = p.codedKeys.length;        
+        for( i=0; i &lt; len; i++ ){
+            if( p.key == p.codedKeys[ i ] ){
+              switch(p.key){
+              case 70: p.keyCode = p.UP        ; break;
+              case 71: p.keyCode = p.RIGHT    ; break;
+              case 72: p.keyCode = p.DOWN      ; break;
+              case 69: p.keyCode = p.LEFT      ; break;
+              }
+              p.key=p.CODED;
+            }
+        }
+        if( e.shiftKey ){ p.key = String.fromCharCode(p.key).toUpperCase().charCodeAt( 0 ); }
+        if( typeof p.keyPressed == &quot;function&quot; ){ p.keyPressed(); }
+        else{ p.keyPressed = true; }
+      });
 
-      if ( typeof p.keyPressed != &quot;function&quot; ) {
-        p.keyPressed = false;
-      }
+      attach( document, &quot;keyup&quot;, function( e ){
+        keyPressed = false;
+        if( typeof p.keyPressed != &quot;function&quot; ){ p.keyPressed = false; }
+        if( p.keyReleased ){ p.keyReleased(); }
+      });
 
-      if ( p.keyReleased ) {
-        p.keyReleased();
+      function attach(elem, type, fn) {
+        if( elem.addEventListener ){ elem.addEventListener( type, fn, false ); }
+        else{ elem.attachEvent( &quot;on&quot; + type, fn ); }
       }
-    });
 
-    function attach(elem, type, fn) {
-      if ( elem.addEventListener )
-        elem.addEventListener( type, fn, false );
-      else
-        elem.attachEvent( &quot;on&quot; + type, fn );
-    }
-
-  };
+    };
 
-  return p;
-}
+    return p;
+    
+  }
 
 })();</diff>
      <filename>processing.js</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>789bf7897cbf78c813c16b74bfc70c59c562ae15</id>
    </parent>
  </parents>
  <author>
    <name>f1lt3r</name>
    <email>f1lt3r@f1lt3r-desktop.(none)</email>
  </author>
  <url>http://github.com/jeresig/processing-js/commit/30200170c7904936d75d6ff32811e7870c93f173</url>
  <id>30200170c7904936d75d6ff32811e7870c93f173</id>
  <committed-date>2009-10-26T12:37:03-07:00</committed-date>
  <authored-date>2009-10-26T12:37:03-07:00</authored-date>
  <message>Cleaning code for readability.</message>
  <tree>6a6cb6a7fec7b14a159f3e615e6f593d3fc69411</tree>
  <committer>
    <name>f1lt3r</name>
    <email>f1lt3r@f1lt3r-desktop.(none)</email>
  </committer>
</commit>
