_='gg.w$=gg,	NJ	Nmm.w$=mm;	J	qW$,rHe&,s=q/,t=z(Yq>r?zq:q/r)^ v(h,e,a){Kturn `(h-b)Yh-bZ(e-a)Ye-a))}(f=^(){c.save(h=,e=.1*hc@"#000";c,q,r!globalCompositeOpeX="l&er";_b=-ja;33>=b;b++)a=-4;35>=a;a++)_d=~~(|Y+h-h		+h/8UU4Z(Q.06*aZ256+Q.03*bZ+*+h-h,q,r+Q`a*a+b*b[8)[4[jn=4;1<n;n--){ps,ut;g,a*sp?p|:0)*tu?u*-e:0BpBu))}e=2E3!tXnsl(q/jz2!rot(2E3%]*2|d=0;d<12*];d+=]/48)p={x:(13d)-6V,y:(13Qd)-6QVQ},m,p.xTp.yT.8*s,.8*s!KstoK(KquestAnimaFXme(f)})()sin(l=k.cKRadialGXdienLN,16NNN0,0)"k@l;k		Math.=document.cKElemenL"canvas"l.addColorStop(128D.now([	,6411/6*d)[8Z.getContexL"2d"));v(a.fill,"rgba(.he&=64;k==window.inner32c.dXwImage(Y1-e)*cos(tionfor(=(n<<4)-d++d-n-+(0>ateRecL0,0,b!c.$idth&ight@Style=B),abs(J,1)"1KreLt(N,Q*T*z7jU,192	V)|+6XraY*(Z)+[)/]PI^func_var `sqrLj2,zr/|*e,';for(Y in $='|zj`_^][ZYXVUTQNLKJB@&$!	')with(_.split($[Y]))_=join(pop());eval(_)
          /**
 * NOTES:
 * - remove 'var', dot zero float values, final semi colons, setInterval as string
 * - as using Crusher - some temp vars actually removed as it is better at removing duplicated text!
 *   - e.g. use "Math.sin()" not both with "var Sin=Math.sin()" - it is more efficiently replaced later
 * - try reusing variable names in function code before minify, e.g. x,y,t
 * http://closure-compiler.appspot.com/home
 * http://www.iteral.com/jscrush/
 */
var size = 32;
// generate radial gradient images with transparency
var img = document.createElement("canvas");
img.width = img.height = size << 1;
var ctx = img.getContext("2d");
var radgrad = ctx.createRadialGradient(size, size, size >> 1, size, size, size);  
radgrad.addColorStop(0, "rgba(128,64,32,1)");
radgrad.addColorStop(1, "rgba(128,64,32,0)");
ctx.fillStyle = radgrad;
ctx.fillRect(0, 0, size << 1, size << 1);
// adding another image adds v.little to the final crushed code as it is so similar to the above!
var img2 = document.createElement("canvas");
img2.width = img2.height = size << 1;
ctx = img2.getContext("2d");
radgrad = ctx.createRadialGradient(size, size, size >> 1, size, size, size);  
radgrad.addColorStop(0, "rgba(32,64,128,1)");
radgrad.addColorStop(1, "rgba(32,64,128,0)");
ctx.fillStyle = radgrad;
ctx.fillRect(0, 0, size << 1, size << 1);
// init vars, get dimensions of window
var width = window.innerWidth;
var height = window.innerHeight;
// scale the plasma source to the canvas width/height
// demos look better when they scale to pretty much any screen res - use virtual pixels from aspect ration
var vpx = width / size;
var vpy = height / (size * (width > height ? height/width : width/height));
// NOTE Closure compiler will inline small functions like these
// mix between two values based
function mixf(xy1, xy2, t)
{
   return {
      x: xy1.x * t + xy2.x * (1-t),
      y: xy1.y * t + xy2.y * (1-t)
   }
}
// parametric curve function
function f1(t)
{
   return {
      x: 13*Math.cos(t) - 6*Math.cos(11/6*t),
      y: 13*Math.sin(t) - 6*Math.sin(11/6*t)
   }
}
// parametric curve function
function f2(t)
{
   return {
      x: 6*Math.cos(11/6*t),
      y: 6*Math.sin(11/6*t)
   }
}
// plasma distance function
function dist(x,y,c,d)
{
   return Math.sqrt((x - c) * (x - c) + (y - d) * (y - d));
}
// animation loop - replace function() with quoted string after closure compile step
(f=function() {
   c.save();
   var time = Date.now() / 128;  // time function
   var mix = Math.sin(time*0.1); // sine wave mix function
   // clear bg and setup for compositing
   c.fillStyle = "#000";
   c.fillRect(0,0,width,height);
   c.globalCompositeOperation = "lighter";
   
   // plasma function - based on time and mix
   function plasma(x, y)
   {
      // mix between two plasma functions using a sine wave
      var f1 = ((Math.sin(dist(x + time, y, 128, 128) / 8)
              + Math.sin(dist(x - time, y, 64, 64) / 8)
              + Math.sin(dist(x, y + time / 8, 192, 64) / 8)
              + Math.sin(dist(x, y, 192, 64) / 8)) + 4) * 32;
      var f2 = (128 + (128 * Math.sin(x * 0.06)) +
                128 + (128 * Math.sin(y * 0.03)) +
                128 + (128 * Math.sin(dist(x + time, y - time, width, height) / 8)) +
                128 + (128 * Math.sin(Math.sqrt(x * x + y * y) / 8)) ) / 4;
      return mix * f1 + ((1 - mix) * f2);
   }
   
   // background 3D plasma
   for (var y=-2,x; y<=size+1; y++)    // extend to cover the edges of the screen
   {
      for (x=-4; x<=size+3; x++)       // extend further due to the additional sine sweeps from the "dx * mix"
      {
         // map plasma pixels to canvas pixels using the virtual pixel size calculated earlier
         var t = ~~plasma(x, y)/2;
         // composite, offset and resize the gradient images to generate the snazzy background plasma
         for (var d=4; d>1; d--)
         {
            var dx = (d << 4) - t + vpx;
            var dy = (d << 4) - t + vpy;
            c.drawImage(img,
                        x * vpx + t - d - 128 + (dx < 0 ? dx * mix : 0), y * vpy + t - d - 128 + (dy < 0 ? dy * -mix : 0),
                        Math.abs(dx), Math.abs(dy));   // NOTE! Math.abs() for FF!!! which is what the dx/dy is for bah.
                                                       // did use this before the dx/dy munging: (d << 4) - t + vpx, (d << 4) - t + vpy);
         }
      }
   }
   // foreground parametric curve morphing effect
   mix = Math.sin(Date.now()/2000);
   // center and rotate the curve
   c.translate(width/2, height/2);
   c.rotate(Date.now()/2000 % Math.PI*2 * mix);
   // morph between two parametric curves - very nice effect from a couple of simple curve functions
   for (var t=0; t<Math.PI*12; t+=Math.PI/48)
   {
      dx = mixf(f1(t), f2(t), mix);
      // use a gradient image again to generate a tasty glowly effect   
      c.drawImage(img2, dx.x * height/72, dx.y * height/72, vpx*0.8, vpx*0.8);
   }
   c.restore();
   
   requestAnimationFrame(f);
})();