master 72513c3cc927 cached
121 files
963.5 KB
307.8k tokens
250 symbols
1 requests
Download .txt
Showing preview only (1,006K chars total). Download the full file or copy to clipboard to get everything.
Repository: pyalot/webgl-deferred-irradiance-volumes
Branch: master
Commit: 72513c3cc927
Files: 121
Total size: 963.5 KB

Directory structure:
gitextract_c0t50r9u/

├── README.md
├── build
├── build.sh
├── compile
├── extra/
│   ├── Stats.js
│   ├── jquery.js
│   ├── loader.coffee
│   ├── loader.js
│   ├── matrix.coffee
│   ├── matrix.js
│   ├── shims.coffee
│   ├── shims.js
│   ├── vector.coffee
│   └── vector.js
├── lib/
│   ├── audio.coffee
│   ├── audio.js
│   ├── camera.coffee
│   ├── camera.js
│   ├── events.coffee
│   ├── events.js
│   ├── geometry.js
│   ├── hdr_clear.shader
│   ├── keys.coffee
│   ├── keys.js
│   ├── loading.coffee
│   ├── loading.js
│   ├── rendernode.coffee
│   ├── rendernode.js
│   ├── schedule.coffee
│   ├── schedule.js
│   ├── webgl/
│   │   ├── cube.coffee
│   │   ├── cube.js
│   │   ├── drawable.coffee
│   │   ├── drawable.js
│   │   ├── framebuffer.coffee
│   │   ├── framebuffer.js
│   │   ├── hexgrid.coffee
│   │   ├── hexgrid.js
│   │   ├── model.coffee
│   │   ├── model.js
│   │   ├── plane.coffee
│   │   ├── plane.js
│   │   ├── quad.coffee
│   │   ├── quad.js
│   │   ├── shader.coffee
│   │   ├── shader.js
│   │   ├── sphere.coffee
│   │   ├── sphere.js
│   │   ├── texture.coffee
│   │   └── texture.js
│   ├── webgl-nuke-vendor-prefix.coffee
│   ├── webgl-nuke-vendor-prefix.js
│   ├── webgl-texture-float-extension-shims.coffee
│   └── webgl-texture-float-extension-shims.js
├── license/
│   ├── bsd-license
│   ├── gplv2-license
│   ├── gplv3-license
│   ├── mit-license
│   └── readme
├── pack
├── src/
│   ├── albedo.shader
│   ├── antialias/
│   │   ├── fxaa2_0.shader
│   │   ├── fxaa3_11.shader
│   │   ├── fxaa3_11.shaderlib
│   │   ├── fxaa3_11_preprocessed.shaderlib
│   │   ├── fxaa3_11_stripped.shaderlib
│   │   ├── module.coffee
│   │   └── module.js
│   ├── application.coffee
│   ├── application.js
│   ├── blur/
│   │   ├── blur.shader
│   │   ├── module.coffee
│   │   └── module.js
│   ├── composit.shader
│   ├── deferred_model.coffee
│   ├── deferred_model.js
│   ├── depth/
│   │   ├── deferred_shadow_map.shader
│   │   ├── depth.shader
│   │   ├── lightmap_shadow_map.shader
│   │   ├── module.coffee
│   │   ├── module.js
│   │   └── variance.shaderlib
│   ├── direct_illumination.shader
│   ├── dist3d.coffee
│   ├── dist3d.js
│   ├── global_illumination.shader
│   ├── harmonics.shaderlib
│   ├── illumination/
│   │   ├── bounce.shader
│   │   ├── bounce_model.coffee
│   │   ├── bounce_model.js
│   │   ├── cube_diffuse.shader
│   │   ├── cubeprobe.shader
│   │   ├── debug.shader
│   │   ├── harmonics.shader
│   │   ├── module.coffee
│   │   ├── module.js
│   │   ├── shadow.shader
│   │   └── transfer.shader
│   ├── main.coffee
│   ├── main.js
│   ├── model/
│   │   ├── lowres.vertices
│   │   ├── materials.json
│   │   ├── module.coffee
│   │   ├── module.js
│   │   ├── sponza.indices
│   │   └── sponza.vertices
│   ├── normaldepth.shader
│   ├── presets/
│   │   ├── default.json
│   │   └── new.json
│   ├── ssao/
│   │   ├── module.coffee
│   │   ├── module.js
│   │   ├── moments.shader
│   │   └── ssao.shader
│   ├── sun.coffee
│   ├── sun.js
│   └── windows/
│       ├── module.coffee
│       ├── module.js
│       └── window.shader
└── www/
    ├── assets.pack
    ├── code.js
    └── index.html

================================================
FILE CONTENTS
================================================

================================================
FILE: README.md
================================================
WebGL Deferred Irradiance Volumes
=================================

An implementation of global illumination using deferred application of irradiance probes.

Documentation
-------------

Blog entry outlining the basic principle: http://codeflow.org/entries/2012/aug/25/webgl-deferred-irradiance-volumes/

Demo
----

Live Demo at: http://codeflow.org/webgl/deferred-irradiance-volumes/www/

License
-------

Copyright (c) 2012, Florian Boesch <pyalot@gmail.com> http://codeflow.org/

WebGL Deferred Irradiance Volumes is licensed under any of the following licenses at your choosing:

 * MIT: see mit-license
 * GPL: see gplv*-license
 * BSD: see bsd-license


================================================
FILE: build
================================================
#!/usr/bin/env python

'''
Copy this into your bin directory for convenient building
'''

import os, subprocess

here = os.getcwd()
folders = here.split('/')

while folders:
    path = '/'.join(folders)
    scriptpath = os.path.join(path, 'build.sh')
    if os.path.exists(scriptpath):
        os.chdir(path)
        subprocess.call(['bash', 'build.sh'])
        break
    folders.pop()


================================================
FILE: build.sh
================================================
./compile
./pack


================================================
FILE: compile
================================================
#!/usr/bin/env python

import os, sys, stat, subprocess
from datetime import datetime

here = os.path.dirname(os.path.abspath(__file__))

message_count = 0
def message(text):
    global message_count
    now = datetime.now().strftime('%H:%M:%S')
    print '[%04i %s] %s' % (message_count, now, text)
    message_count+=1

def error(text):
    sys.stdout.write('\x1b[31m%s\x1b[39m' % text)
    sys.stdout.flush()

def coffee_compile(path, bare):
    message('compiling: %s' % path)
    if bare:
        command = ['coffee', '--compile', '--bare', path]
    else:
        command = ['coffee', '--compile', path]

    process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    out, err = process.communicate()
    if process.returncode:
        error(err)

def get_mtime(name):
    return os.stat(name)[stat.ST_MTIME]

def listfiles(folder, *exts):
    for path, dirs, names in os.walk(os.path.join(here, folder)):
        for name in names:
            ext = os.path.splitext(name)[-1].lstrip('.')
            if ext in exts:
                yield path, name, os.path.join(path, name)

def check_files(folder, bare):
    for path, name, loc in listfiles(folder, 'coffee'):
        js_path = os.path.join(path, os.path.splitext(name)[0] + '.js')
        coffee_mtime = get_mtime(loc)
        if os.path.exists(js_path):
            js_mtime = get_mtime(js_path)
            if coffee_mtime > js_mtime:
                coffee_compile(loc, bare=bare)
        else:
            coffee_compile(loc, bare=bare)

if __name__ == '__main__':
    check_files('src', bare=True)
    check_files('lib', bare=True)
    check_files('extra', bare=False)


================================================
FILE: extra/Stats.js
================================================
/**
 * @author mrdoob / http://mrdoob.com/
 */

var Stats = function () {

	var startTime = Date.now(), prevTime = startTime;
	var ms = 0, msMin = 1000, msMax = 0;
	var fps = 0, fpsMin = 1000, fpsMax = 0;
	var frames = 0, mode = 0;	

	var container = document.createElement( 'div' );
	container.id = 'stats';
	container.addEventListener( 'mousedown', function ( event ) { event.preventDefault(); setMode( ++ mode % 2 ) }, false );
	container.style.cssText = 'width:80px;opacity:0.9;cursor:pointer';

	var fpsDiv = document.createElement( 'div' );
	fpsDiv.id = 'fps';
	fpsDiv.style.cssText = 'padding:0 0 3px 3px;text-align:left;background-color:#002';
	container.appendChild( fpsDiv );

	var fpsText = document.createElement( 'div' );
	fpsText.id = 'fpsText';
	fpsText.style.cssText = 'color:#0ff;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px';
	fpsText.innerHTML = 'FPS';
	fpsDiv.appendChild( fpsText );

	var fpsGraph = document.createElement( 'div' );
	fpsGraph.id = 'fpsGraph';
	fpsGraph.style.cssText = 'position:relative;width:74px;height:30px;background-color:#0ff';
	fpsDiv.appendChild( fpsGraph );

	while ( fpsGraph.children.length < 74 ) {

		var bar = document.createElement( 'span' );
		bar.style.cssText = 'width:1px;height:30px;float:left;background-color:#113';
		fpsGraph.appendChild( bar );

	}

	var msDiv = document.createElement( 'div' );
	msDiv.id = 'ms';
	msDiv.style.cssText = 'padding:0 0 3px 3px;text-align:left;background-color:#020;display:none';
	container.appendChild( msDiv );

	var msText = document.createElement( 'div' );
	msText.id = 'msText';
	msText.style.cssText = 'color:#0f0;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px';
	msText.innerHTML = 'MS';
	msDiv.appendChild( msText );

	var msGraph = document.createElement( 'div' );
	msGraph.id = 'msGraph';
	msGraph.style.cssText = 'position:relative;width:74px;height:30px;background-color:#0f0';
	msDiv.appendChild( msGraph );

	while ( msGraph.children.length < 74 ) {

		var bar = document.createElement( 'span' );
		bar.style.cssText = 'width:1px;height:30px;float:left;background-color:#131';
		msGraph.appendChild( bar );

	}

	var setMode = function ( value ) {

		mode = value;

		switch ( mode ) {

			case 0:
				fpsDiv.style.display = 'block';
				msDiv.style.display = 'none';
				break;
			case 1:
				fpsDiv.style.display = 'none';
				msDiv.style.display = 'block';
				break;
		}

	}

	var updateGraph = function ( dom, value ) {

		var child = dom.appendChild( dom.firstChild );
		child.style.height = value + 'px';

	}

	return {

		domElement: container,

		setMode: setMode,

		begin: function () {

			startTime = Date.now();

		},

		end: function () {

			var time = Date.now();

			ms = time - startTime;
			msMin = Math.min( msMin, ms );
			msMax = Math.max( msMax, ms );

			msText.textContent = ms + ' MS (' + msMin + '-' + msMax + ')';
			updateGraph( msGraph, Math.min( 30, 30 - ( ms / 200 ) * 30 ) );

			frames ++;

			if ( time > prevTime + 1000 ) {

				fps = Math.round( ( frames * 1000 ) / ( time - prevTime ) );
				fpsMin = Math.min( fpsMin, fps );
				fpsMax = Math.max( fpsMax, fps );

				fpsText.textContent = fps + ' FPS (' + fpsMin + '-' + fpsMax + ')';
				updateGraph( fpsGraph, Math.min( 30, 30 - ( fps / 100 ) * 30 ) );

				prevTime = time;
				frames = 0;

			}

			return time;

		},

		update: function () {

			startTime = this.end();
			
		}

	}
	
};


================================================
FILE: extra/jquery.js
================================================
/*! jQuery v1.7.2 jquery.com | jquery.org/license */
(function(a,b){function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cu(a){if(!cj[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){ck||(ck=c.createElement("iframe"),ck.frameBorder=ck.width=ck.height=0),b.appendChild(ck);if(!cl||!ck.createElement)cl=(ck.contentWindow||ck.contentDocument).document,cl.write((f.support.boxModel?"<!doctype html>":"")+"<html><body>"),cl.close();d=cl.createElement(a),cl.body.appendChild(d),e=f.css(d,"display"),b.removeChild(ck)}cj[a]=e}return cj[a]}function ct(a,b){var c={};f.each(cp.concat.apply([],cp.slice(0,b)),function(){c[this]=a});return c}function cs(){cq=b}function cr(){setTimeout(cs,0);return cq=f.now()}function ci(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ch(){try{return new a.XMLHttpRequest}catch(b){}}function cb(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g<i;g++){if(g===1)for(h in a.converters)typeof h=="string"&&(e[h.toLowerCase()]=a.converters[h]);l=k,k=d[g];if(k==="*")k=l;else if(l!=="*"&&l!==k){m=l+" "+k,n=e[m]||e["* "+k];if(!n){p=b;for(o in e){j=o.split(" ");if(j[0]===l||j[0]==="*"){p=e[j[1]+" "+k];if(p){o=e[o],o===!0?n=p:p===!0&&(n=o);break}}}}!n&&!p&&f.error("No conversion from "+m.replace(" "," to ")),n!==!0&&(c=n?n(c):p(o(c)))}}return c}function ca(a,c,d){var e=a.contents,f=a.dataTypes,g=a.responseFields,h,i,j,k;for(i in g)i in d&&(c[g[i]]=d[i]);while(f[0]==="*")f.shift(),h===b&&(h=a.mimeType||c.getResponseHeader("content-type"));if(h)for(i in e)if(e[i]&&e[i].test(h)){f.unshift(i);break}if(f[0]in d)j=f[0];else{for(i in d){if(!f[0]||a.converters[i+" "+f[0]]){j=i;break}k||(k=i)}j=j||k}if(j){j!==f[0]&&f.unshift(j);return d[j]}}function b_(a,b,c,d){if(f.isArray(b))f.each(b,function(b,e){c||bD.test(a)?d(a,e):b_(a+"["+(typeof e=="object"?b:"")+"]",e,c,d)});else if(!c&&f.type(b)==="object")for(var e in b)b_(a+"["+e+"]",b[e],c,d);else d(a,b)}function b$(a,c){var d,e,g=f.ajaxSettings.flatOptions||{};for(d in c)c[d]!==b&&((g[d]?a:e||(e={}))[d]=c[d]);e&&f.extend(!0,a,e)}function bZ(a,c,d,e,f,g){f=f||c.dataTypes[0],g=g||{},g[f]=!0;var h=a[f],i=0,j=h?h.length:0,k=a===bS,l;for(;i<j&&(k||!l);i++)l=h[i](c,d,e),typeof l=="string"&&(!k||g[l]?l=b:(c.dataTypes.unshift(l),l=bZ(a,c,d,e,l,g)));(k||!l)&&!g["*"]&&(l=bZ(a,c,d,e,"*",g));return l}function bY(a){return function(b,c){typeof b!="string"&&(c=b,b="*");if(f.isFunction(c)){var d=b.toLowerCase().split(bO),e=0,g=d.length,h,i,j;for(;e<g;e++)h=d[e],j=/^\+/.test(h),j&&(h=h.substr(1)||"*"),i=a[h]=a[h]||[],i[j?"unshift":"push"](c)}}}function bB(a,b,c){var d=b==="width"?a.offsetWidth:a.offsetHeight,e=b==="width"?1:0,g=4;if(d>0){if(c!=="border")for(;e<g;e+=2)c||(d-=parseFloat(f.css(a,"padding"+bx[e]))||0),c==="margin"?d+=parseFloat(f.css(a,c+bx[e]))||0:d-=parseFloat(f.css(a,"border"+bx[e]+"Width"))||0;return d+"px"}d=by(a,b);if(d<0||d==null)d=a.style[b];if(bt.test(d))return d;d=parseFloat(d)||0;if(c)for(;e<g;e+=2)d+=parseFloat(f.css(a,"padding"+bx[e]))||0,c!=="padding"&&(d+=parseFloat(f.css(a,"border"+bx[e]+"Width"))||0),c==="margin"&&(d+=parseFloat(f.css(a,c+bx[e]))||0);return d+"px"}function bo(a){var b=c.createElement("div");bh.appendChild(b),b.innerHTML=a.outerHTML;return b.firstChild}function bn(a){var b=(a.nodeName||"").toLowerCase();b==="input"?bm(a):b!=="script"&&typeof a.getElementsByTagName!="undefined"&&f.grep(a.getElementsByTagName("input"),bm)}function bm(a){if(a.type==="checkbox"||a.type==="radio")a.defaultChecked=a.checked}function bl(a){return typeof a.getElementsByTagName!="undefined"?a.getElementsByTagName("*"):typeof a.querySelectorAll!="undefined"?a.querySelectorAll("*"):[]}function bk(a,b){var c;b.nodeType===1&&(b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase(),c==="object"?b.outerHTML=a.outerHTML:c!=="input"||a.type!=="checkbox"&&a.type!=="radio"?c==="option"?b.selected=a.defaultSelected:c==="input"||c==="textarea"?b.defaultValue=a.defaultValue:c==="script"&&b.text!==a.text&&(b.text=a.text):(a.checked&&(b.defaultChecked=b.checked=a.checked),b.value!==a.value&&(b.value=a.value)),b.removeAttribute(f.expando),b.removeAttribute("_submit_attached"),b.removeAttribute("_change_attached"))}function bj(a,b){if(b.nodeType===1&&!!f.hasData(a)){var c,d,e,g=f._data(a),h=f._data(b,g),i=g.events;if(i){delete h.handle,h.events={};for(c in i)for(d=0,e=i[c].length;d<e;d++)f.event.add(b,c,i[c][d])}h.data&&(h.data=f.extend({},h.data))}}function bi(a,b){return f.nodeName(a,"table")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function U(a){var b=V.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}function T(a,b,c){b=b||0;if(f.isFunction(b))return f.grep(a,function(a,d){var e=!!b.call(a,d,a);return e===c});if(b.nodeType)return f.grep(a,function(a,d){return a===b===c});if(typeof b=="string"){var d=f.grep(a,function(a){return a.nodeType===1});if(O.test(b))return f.filter(b,d,!c);b=f.filter(b,d)}return f.grep(a,function(a,d){return f.inArray(a,b)>=0===c})}function S(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function K(){return!0}function J(){return!1}function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);h&&(c==="queue"||!f._data(a,e))&&(c==="mark"||!f._data(a,g))&&setTimeout(function(){!f._data(a,e)&&!f._data(a,g)&&(f.removeData(a,d,!0),h.fire())},0)}function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNumeric(d)?+d:j.test(d)?f.parseJSON(d):d}catch(g){}f.data(a,c,d)}else d=b}return d}function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c<d;c++)b[a[c]]=!0;return b}var c=a.document,d=a.navigator,e=a.location,f=function(){function J(){if(!e.isReady){try{c.documentElement.doScroll("left")}catch(a){setTimeout(J,1);return}e.ready()}}var e=function(a,b){return new e.fn.init(a,b,h)},f=a.jQuery,g=a.$,h,i=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,n=/^[\],:{}\s]*$/,o=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,p=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,q=/(?:^|:|,)(?:\s*\[)+/g,r=/(webkit)[ \/]([\w.]+)/,s=/(opera)(?:.*version)?[ \/]([\w.]+)/,t=/(msie) ([\w.]+)/,u=/(mozilla)(?:.*? rv:([\w.]+))?/,v=/-([a-z]|[0-9])/ig,w=/^-ms-/,x=function(a,b){return(b+"").toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.prototype.trim,H=Array.prototype.indexOf,I={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=m.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.7.2",length:0,size:function(){return this.length},toArray:function(){return F.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?E.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),A.add(a);return this},eq:function(a){a=+a;return a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(F.apply(this,arguments),"slice",F.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:E,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j<k;j++)if((a=arguments[j])!=null)for(c in a){d=i[c],f=a[c];if(i===f)continue;l&&f&&(e.isPlainObject(f)||(g=e.isArray(f)))?(g?(g=!1,h=d&&e.isArray(d)?d:[]):h=d&&e.isPlainObject(d)?d:{},i[c]=e.extend(l,h,f)):f!==b&&(i[c]=f)}return i},e.extend({noConflict:function(b){a.$===e&&(a.$=g),b&&a.jQuery===e&&(a.jQuery=f);return e},isReady:!1,readyWait:1,holdReady:function(a){a?e.readyWait++:e.ready(!0)},ready:function(a){if(a===!0&&!--e.readyWait||a!==!0&&!e.isReady){if(!c.body)return setTimeout(e.ready,1);e.isReady=!0;if(a!==!0&&--e.readyWait>0)return;A.fireWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").off("ready")}},bindReady:function(){if(!A){A=e.Callbacks("once memory");if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",B,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",B),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a!=null&&a==a.window},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):I[C.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||D.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw new Error(a)},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(n.test(b.replace(o,"@").replace(p,"]").replace(q,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){if(typeof c!="string"||!c)return null;var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(w,"ms-").replace(v,x)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g<h;)if(c.apply(a[g++],d)===!1)break}else if(i){for(f in a)if(c.call(a[f],f,a[f])===!1)break}else for(;g<h;)if(c.call(a[g],g,a[g++])===!1)break;return a},trim:G?function(a){return a==null?"":G.call(a)}:function(a){return a==null?"":(a+"").replace(k,"").replace(l,"")},makeArray:function(a,b){var c=b||[];if(a!=null){var d=e.type(a);a.length==null||d==="string"||d==="function"||d==="regexp"||e.isWindow(a)?E.call(c,a):e.merge(c,a)}return c},inArray:function(a,b,c){var d;if(b){if(H)return H.call(b,a,c);d=b.length,c=c?c<0?Math.max(0,d+c):c:0;for(;c<d;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,c){var d=a.length,e=0;if(typeof c.length=="number")for(var f=c.length;e<f;e++)a[d++]=c[e];else while(c[e]!==b)a[d++]=c[e++];a.length=d;return a},grep:function(a,b,c){var d=[],e;c=!!c;for(var f=0,g=a.length;f<g;f++)e=!!b(a[f],f),c!==e&&d.push(a[f]);return d},map:function(a,c,d){var f,g,h=[],i=0,j=a.length,k=a instanceof e||j!==b&&typeof j=="number"&&(j>0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i<j;i++)f=c(a[i],i,d),f!=null&&(h[h.length]=f);else for(g in a)f=c(a[g],g,d),f!=null&&(h[h.length]=f);return h.concat.apply([],h)},guid:1,proxy:function(a,c){if(typeof c=="string"){var d=a[c];c=a,a=d}if(!e.isFunction(a))return b;var f=F.call(arguments,2),g=function(){return a.apply(c,f.concat(F.call(arguments)))};g.guid=a.guid=a.guid||g.guid||e.guid++;return g},access:function(a,c,d,f,g,h,i){var j,k=d==null,l=0,m=a.length;if(d&&typeof d=="object"){for(l in d)e.access(a,c,l,d[l],1,h,f);g=1}else if(f!==b){j=i===b&&e.isFunction(f),k&&(j?(j=c,c=function(a,b,c){return j.call(e(a),c)}):(c.call(a,f),c=null));if(c)for(;l<m;l++)c(a[l],d,j?f.call(a[l],l,c(a[l],d)):f,i);g=1}return g?a:k?c.call(a):m?c(a[0],d):h},now:function(){return(new Date).getTime()},uaMatch:function(a){a=a.toLowerCase();var b=r.exec(a)||s.exec(a)||t.exec(a)||a.indexOf("compatible")<0&&u.exec(a)||[];return{browser:b[1]||"",version:b[2]||"0"}},sub:function(){function a(b,c){return new a.fn.init(b,c)}e.extend(!0,a,this),a.superclass=this,a.fn=a.prototype=this(),a.fn.constructor=a,a.sub=this.sub,a.fn.init=function(d,f){f&&f instanceof e&&!(f instanceof a)&&(f=a(f));return e.fn.init.call(this,d,f,b)},a.fn.init.prototype=a.fn;var b=a(c);return a},browser:{}}),e.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(a,b){I["[object "+b+"]"]=b.toLowerCase()}),z=e.uaMatch(y),z.browser&&(e.browser[z.browser]=!0,e.browser.version=z.version),e.browser.webkit&&(e.browser.safari=!0),j.test(" ")&&(k=/^[\s\xA0]+/,l=/[\s\xA0]+$/),h=e(c),c.addEventListener?B=function(){c.removeEventListener("DOMContentLoaded",B,!1),e.ready()}:c.attachEvent&&(B=function(){c.readyState==="complete"&&(c.detachEvent("onreadystatechange",B),e.ready())});return e}(),g={};f.Callbacks=function(a){a=a?g[a]||h(a):{};var c=[],d=[],e,i,j,k,l,m,n=function(b){var d,e,g,h,i;for(d=0,e=b.length;d<e;d++)g=b[d],h=f.type(g),h==="array"?n(g):h==="function"&&(!a.unique||!p.has(g))&&c.push(g)},o=function(b,f){f=f||[],e=!a.memory||[b,f],i=!0,j=!0,m=k||0,k=0,l=c.length;for(;c&&m<l;m++)if(c[m].apply(b,f)===!1&&a.stopOnFalse){e=!0;break}j=!1,c&&(a.once?e===!0?p.disable():c=[]:d&&d.length&&(e=d.shift(),p.fireWith(e[0],e[1])))},p={add:function(){if(c){var a=c.length;n(arguments),j?l=c.length:e&&e!==!0&&(k=a,o(e[0],e[1]))}return this},remove:function(){if(c){var b=arguments,d=0,e=b.length;for(;d<e;d++)for(var f=0;f<c.length;f++)if(b[d]===c[f]){j&&f<=l&&(l--,f<=m&&m--),c.splice(f--,1);if(a.unique)break}}return this},has:function(a){if(c){var b=0,d=c.length;for(;b<d;b++)if(a===c[b])return!0}return!1},empty:function(){c=[];return this},disable:function(){c=d=e=b;return this},disabled:function(){return!c},lock:function(){d=b,(!e||e===!0)&&p.disable();return this},locked:function(){return!d},fireWith:function(b,c){d&&(j?a.once||d.push([b,c]):(!a.once||!e)&&o(b,c));return this},fire:function(){p.fireWith(this,arguments);return this},fired:function(){return!!i}};return p};var i=[].slice;f.extend({Deferred:function(a){var b=f.Callbacks("once memory"),c=f.Callbacks("once memory"),d=f.Callbacks("memory"),e="pending",g={resolve:b,reject:c,notify:d},h={done:b.add,fail:c.add,progress:d.add,state:function(){return e},isResolved:b.fired,isRejected:c.fired,then:function(a,b,c){i.done(a).fail(b).progress(c);return this},always:function(){i.done.apply(i,arguments).fail.apply(i,arguments);return this},pipe:function(a,b,c){return f.Deferred(function(d){f.each({done:[a,"resolve"],fail:[b,"reject"],progress:[c,"notify"]},function(a,b){var c=b[0],e=b[1],g;f.isFunction(c)?i[a](function(){g=c.apply(this,arguments),g&&f.isFunction(g.promise)?g.promise().then(d.resolve,d.reject,d.notify):d[e+"With"](this===i?d:this,[g])}):i[a](d[e])})}).promise()},promise:function(a){if(a==null)a=h;else for(var b in h)a[b]=h[b];return a}},i=h.promise({}),j;for(j in g)i[j]=g[j].fire,i[j+"With"]=g[j].fireWith;i.done(function(){e="resolved"},c.disable,d.lock).fail(function(){e="rejected"},b.disable,d.lock),a&&a.call(i,i);return i},when:function(a){function m(a){return function(b){e[a]=arguments.length>1?i.call(arguments,0):b,j.notifyWith(k,e)}}function l(a){return function(c){b[a]=arguments.length>1?i.call(arguments,0):c,--g||j.resolveWith(j,b)}}var b=i.call(arguments,0),c=0,d=b.length,e=Array(d),g=d,h=d,j=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred(),k=j.promise();if(d>1){for(;c<d;c++)b[c]&&b[c].promise&&f.isFunction(b[c].promise)?b[c].promise().then(l(c),j.reject,m(c)):--g;g||j.resolveWith(j,b)}else j!==a&&j.resolveWith(j,d?[a]:[]);return k}}),f.support=function(){var b,d,e,g,h,i,j,k,l,m,n,o,p=c.createElement("div"),q=c.documentElement;p.setAttribute("className","t"),p.innerHTML="   <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>",d=p.getElementsByTagName("*"),e=p.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=p.getElementsByTagName("input")[0],b={leadingWhitespace:p.firstChild.nodeType===3,tbody:!p.getElementsByTagName("tbody").length,htmlSerialize:!!p.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:p.className!=="t",enctype:!!c.createElement("form").enctype,html5Clone:c.createElement("nav").cloneNode(!0).outerHTML!=="<:nav></:nav>",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,pixelMargin:!0},f.boxModel=b.boxModel=c.compatMode==="CSS1Compat",i.checked=!0,b.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,b.optDisabled=!h.disabled;try{delete p.test}catch(r){b.deleteExpando=!1}!p.addEventListener&&p.attachEvent&&p.fireEvent&&(p.attachEvent("onclick",function(){b.noCloneEvent=!1}),p.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),b.radioValue=i.value==="t",i.setAttribute("checked","checked"),i.setAttribute("name","t"),p.appendChild(i),j=c.createDocumentFragment(),j.appendChild(p.lastChild),b.checkClone=j.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=i.checked,j.removeChild(i),j.appendChild(p);if(p.attachEvent)for(n in{submit:1,change:1,focusin:1})m="on"+n,o=m in p,o||(p.setAttribute(m,"return;"),o=typeof p[m]=="function"),b[n+"Bubbles"]=o;j.removeChild(p),j=g=h=p=i=null,f(function(){var d,e,g,h,i,j,l,m,n,q,r,s,t,u=c.getElementsByTagName("body")[0];!u||(m=1,t="padding:0;margin:0;border:",r="position:absolute;top:0;left:0;width:1px;height:1px;",s=t+"0;visibility:hidden;",n="style='"+r+t+"5px solid #000;",q="<div "+n+"display:block;'><div style='"+t+"0;display:block;overflow:hidden;'></div></div>"+"<table "+n+"' cellpadding='0' cellspacing='0'>"+"<tr><td></td></tr></table>",d=c.createElement("div"),d.style.cssText=s+"width:0;height:0;position:static;top:0;margin-top:"+m+"px",u.insertBefore(d,u.firstChild),p=c.createElement("div"),d.appendChild(p),p.innerHTML="<table><tr><td style='"+t+"0;display:none'></td><td>t</td></tr></table>",k=p.getElementsByTagName("td"),o=k[0].offsetHeight===0,k[0].style.display="",k[1].style.display="none",b.reliableHiddenOffsets=o&&k[0].offsetHeight===0,a.getComputedStyle&&(p.innerHTML="",l=c.createElement("div"),l.style.width="0",l.style.marginRight="0",p.style.width="2px",p.appendChild(l),b.reliableMarginRight=(parseInt((a.getComputedStyle(l,null)||{marginRight:0}).marginRight,10)||0)===0),typeof p.style.zoom!="undefined"&&(p.innerHTML="",p.style.width=p.style.padding="1px",p.style.border=0,p.style.overflow="hidden",p.style.display="inline",p.style.zoom=1,b.inlineBlockNeedsLayout=p.offsetWidth===3,p.style.display="block",p.style.overflow="visible",p.innerHTML="<div style='width:5px;'></div>",b.shrinkWrapBlocks=p.offsetWidth!==3),p.style.cssText=r+s,p.innerHTML=q,e=p.firstChild,g=e.firstChild,i=e.nextSibling.firstChild.firstChild,j={doesNotAddBorder:g.offsetTop!==5,doesAddBorderForTableAndCells:i.offsetTop===5},g.style.position="fixed",g.style.top="20px",j.fixedPosition=g.offsetTop===20||g.offsetTop===15,g.style.position=g.style.top="",e.style.overflow="hidden",e.style.position="relative",j.subtractsBorderForOverflowNotVisible=g.offsetTop===-5,j.doesNotIncludeMarginInBodyOffset=u.offsetTop!==m,a.getComputedStyle&&(p.style.marginTop="1%",b.pixelMargin=(a.getComputedStyle(p,null)||{marginTop:0}).marginTop!=="1%"),typeof d.style.zoom!="undefined"&&(d.style.zoom=1),u.removeChild(d),l=p=d=null,f.extend(b,j))});return b}();var j=/^(?:\{.*\}|\[.*\])$/,k=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[j]:a[j]&&j,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].data)&&k&&d===b)return;n||(l?a[j]=n=++f.uuid:n=j),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[h]:h;if(!j[k])return;if(b){d=c?j[k]:j[k].data;if(d){f.isArray(b)||(b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,g=b.length;e<g;e++)delete d[b[e]];if(!(c?m:f.isEmptyObject)(d))return}}if(!c){delete j[k].data;if(!m(j[k]))return}f.support.deleteExpando||!j.setInterval?delete j[k]:j[k]=null,i&&(f.support.deleteExpando?delete a[h]:a.removeAttribute?a.removeAttribute(h):a[h]=null)}},_data:function(a,b,c){return f.data(a,b,c,!0)},acceptData:function(a){if(a.nodeName){var b=f.noData[a.nodeName.toLowerCase()];if(b)return b!==!0&&a.getAttribute("classid")===b}return!0}}),f.fn.extend({data:function(a,c){var d,e,g,h,i,j=this[0],k=0,m=null;if(a===b){if(this.length){m=f.data(j);if(j.nodeType===1&&!f._data(j,"parsedAttrs")){g=j.attributes;for(i=g.length;k<i;k++)h=g[k].name,h.indexOf("data-")===0&&(h=f.camelCase(h.substring(5)),l(j,h,m[h]));f._data(j,"parsedAttrs",!0)}}return m}if(typeof a=="object")return this.each(function(){f.data(this,a)});d=a.split(".",2),d[1]=d[1]?"."+d[1]:"",e=d[1]+"!";return f.access(this,function(c){if(c===b){m=this.triggerHandler("getData"+e,[d[0]]),m===b&&j&&(m=f.data(j,a),m=l(j,a,m));return m===b&&d[1]?this.data(d[0]):m}d[1]=c,this.each(function(){var b=f(this);b.triggerHandler("setData"+e,d),f.data(this,a,c),b.triggerHandler("changeData"+e,d)})},null,c,arguments.length>1,null,!1)},removeData:function(a){return this.each(function(){f.removeData(this,a)})}}),f.extend({_mark:function(a,b){a&&(b=(b||"fx")+"mark",f._data(a,b,(f._data(a,b)||0)+1))},_unmark:function(a,b,c){a!==!0&&(c=b,b=a,a=!1);if(b){c=c||"fx";var d=c+"mark",e=a?0:(f._data(b,d)||1)-1;e?f._data(b,d,e):(f.removeData(b,d,!0),n(b,c,"mark"))}},queue:function(a,b,c){var d;if(a){b=(b||"fx")+"queue",d=f._data(a,b),c&&(!d||f.isArray(c)?d=f._data(a,b,f.makeArray(c)):d.push(c));return d||[]}},dequeue:function(a,b){b=b||"fx";var c=f.queue(a,b),d=c.shift(),e={};d==="inprogress"&&(d=c.shift()),d&&(b==="fx"&&c.unshift("inprogress"),f._data(a,b+".run",e),d.call(a,function(){f.dequeue(a,b)},e)),c.length||(f.removeData(a,b+"queue "+b+".run",!0),n(a,b,"queue"))}}),f.fn.extend({queue:function(a,c){var d=2;typeof a!="string"&&(c=a,a="fx",d--);if(arguments.length<d)return f.queue(this[0],a);return c===b?this:this.each(function(){var b=f.queue(this,a,c);a==="fx"&&b[0]!=="inprogress"&&f.dequeue(this,a)})},dequeue:function(a){return this.each(function(){f.dequeue(this,a)})},delay:function(a,b){a=f.fx?f.fx.speeds[a]||a:a,b=b||"fx";return this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,c){function m(){--h||d.resolveWith(e,[e])}typeof a!="string"&&(c=a,a=b),a=a||"fx";var d=f.Deferred(),e=this,g=e.length,h=1,i=a+"defer",j=a+"queue",k=a+"mark",l;while(g--)if(l=f.data(e[g],i,b,!0)||(f.data(e[g],j,b,!0)||f.data(e[g],k,b,!0))&&f.data(e[g],i,f.Callbacks("once memory"),!0))h++,l.add(m);m();return d.promise(c)}});var o=/[\n\t\r]/g,p=/\s+/,q=/\r/g,r=/^(?:button|input)$/i,s=/^(?:button|input|object|select|textarea)$/i,t=/^a(?:rea)?$/i,u=/^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,v=f.support.getSetAttribute,w,x,y;f.fn.extend({attr:function(a,b){return f.access(this,f.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){f.removeAttr(this,a)})},prop:function(a,b){return f.access(this,f.prop,a,b,arguments.length>1)},removeProp:function(a){a=f.propFix[a]||a;return this.each(function(){try{this[a]=b,delete this[a]}catch(c){}})},addClass:function(a){var b,c,d,e,g,h,i;if(f.isFunction(a))return this.each(function(b){f(this).addClass(a.call(this,b,this.className))});if(a&&typeof a=="string"){b=a.split(p);for(c=0,d=this.length;c<d;c++){e=this[c];if(e.nodeType===1)if(!e.className&&b.length===1)e.className=a;else{g=" "+e.className+" ";for(h=0,i=b.length;h<i;h++)~g.indexOf(" "+b[h]+" ")||(g+=b[h]+" ");e.className=f.trim(g)}}}return this},removeClass:function(a){var c,d,e,g,h,i,j;if(f.isFunction(a))return this.each(function(b){f(this).removeClass(a.call(this,b,this.className))});if(a&&typeof a=="string"||a===b){c=(a||"").split(p);for(d=0,e=this.length;d<e;d++){g=this[d];if(g.nodeType===1&&g.className)if(a){h=(" "+g.className+" ").replace(o," ");for(i=0,j=c.length;i<j;i++)h=h.replace(" "+c[i]+" "," ");g.className=f.trim(h)}else g.className=""}}return this},toggleClass:function(a,b){var c=typeof a,d=typeof b=="boolean";if(f.isFunction(a))return this.each(function(c){f(this).toggleClass(a.call(this,c,this.className,b),b)});return this.each(function(){if(c==="string"){var e,g=0,h=f(this),i=b,j=a.split(p);while(e=j[g++])i=d?i:!h.hasClass(e),h[i?"addClass":"removeClass"](e)}else if(c==="undefined"||c==="boolean")this.className&&f._data(this,"__className__",this.className),this.className=this.className||a===!1?"":f._data(this,"__className__")||""})},hasClass:function(a){var b=" "+a+" ",c=0,d=this.length;for(;c<d;c++)if(this[c].nodeType===1&&(" "+this[c].className+" ").replace(o," ").indexOf(b)>-1)return!0;return!1},val:function(a){var c,d,e,g=this[0];{if(!!arguments.length){e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.type]||f.valHooks[this.nodeName.toLowerCase()];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}if(g){c=f.valHooks[g.type]||f.valHooks[g.nodeName.toLowerCase()];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}}}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;c<d;c++){e=i[c];if(e.selected&&(f.support.optDisabled?!e.disabled:e.getAttribute("disabled")===null)&&(!e.parentNode.disabled||!f.nodeName(e.parentNode,"optgroup"))){b=f(e).val();if(j)return b;h.push(b)}}if(j&&!h.length&&i.length)return f(i[g]).val();return h},set:function(a,b){var c=f.makeArray(b);f(a).find("option").each(function(){this.selected=f.inArray(f(this).val(),c)>=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!!a&&j!==3&&j!==8&&j!==2){if(e&&c in f.attrFn)return f(a)[c](d);if(typeof a.getAttribute=="undefined")return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g}},removeAttr:function(a,b){var c,d,e,g,h,i=0;if(b&&a.nodeType===1){d=b.toLowerCase().split(p),g=d.length;for(;i<g;i++)e=d[i],e&&(c=f.propFix[e]||e,h=u.test(e),h||f.attr(a,e,""),a.removeAttribute(v?e:c),h&&c in a&&(a[c]=!1))}},attrHooks:{type:{set:function(a,b){if(r.test(a.nodeName)&&a.parentNode)f.error("type property can't be changed");else if(!f.support.radioValue&&b==="radio"&&f.nodeName(a,"input")){var c=a.value;a.setAttribute("type",b),c&&(a.value=c);return b}}},value:{get:function(a,b){if(w&&f.nodeName(a,"button"))return w.get(a,b);return b in a?a.value:null},set:function(a,b,c){if(w&&f.nodeName(a,"button"))return w.set(a,b,c);a.value=b}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(a,c,d){var e,g,h,i=a.nodeType;if(!!a&&i!==3&&i!==8&&i!==2){h=i!==1||!f.isXMLDoc(a),h&&(c=f.propFix[c]||c,g=f.propHooks[c]);return d!==b?g&&"set"in g&&(e=g.set(a,d,c))!==b?e:a[c]=d:g&&"get"in g&&(e=g.get(a,c))!==null?e:a[c]}},propHooks:{tabIndex:{get:function(a){var c=a.getAttributeNode("tabindex");return c&&c.specified?parseInt(c.value,10):s.test(a.nodeName)||t.test(a.nodeName)&&a.href?0:b}}}}),f.attrHooks.tabindex=f.propHooks.tabIndex,x={get:function(a,c){var d,e=f.prop(a,c);return e===!0||typeof e!="boolean"&&(d=a.getAttributeNode(c))&&d.nodeValue!==!1?c.toLowerCase():b},set:function(a,b,c){var d;b===!1?f.removeAttr(a,c):(d=f.propFix[c]||c,d in a&&(a[d]=!0),a.setAttribute(c,c.toLowerCase()));return c}},v||(y={name:!0,id:!0,coords:!0},w=f.valHooks.button={get:function(a,c){var d;d=a.getAttributeNode(c);return d&&(y[c]?d.nodeValue!=="":d.specified)?d.nodeValue:b},set:function(a,b,d){var e=a.getAttributeNode(d);e||(e=c.createAttribute(d),a.setAttributeNode(e));return e.nodeValue=b+""}},f.attrHooks.tabindex.set=w.set,f.each(["width","height"],function(a,b){f.attrHooks[b]=f.extend(f.attrHooks[b],{set:function(a,c){if(c===""){a.setAttribute(b,"auto");return c}}})}),f.attrHooks.contenteditable={get:w.get,set:function(a,b,c){b===""&&(b="false"),w.set(a,b,c)}}),f.support.hrefNormalized||f.each(["href","src","width","height"],function(a,c){f.attrHooks[c]=f.extend(f.attrHooks[c],{get:function(a){var d=a.getAttribute(c,2);return d===null?b:d}})}),f.support.style||(f.attrHooks.style={get:function(a){return a.style.cssText.toLowerCase()||b},set:function(a,b){return a.style.cssText=""+b}}),f.support.optSelected||(f.propHooks.selected=f.extend(f.propHooks.selected,{get:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex);return null}})),f.support.enctype||(f.propFix.enctype="encoding"),f.support.checkOn||f.each(["radio","checkbox"],function(){f.valHooks[this]={get:function(a){return a.getAttribute("value")===null?"on":a.value}}}),f.each(["radio","checkbox"],function(){f.valHooks[this]=f.extend(f.valHooks[this],{set:function(a,b){if(f.isArray(b))return a.checked=f.inArray(f(a).val(),b)>=0}})});var z=/^(?:textarea|input|select)$/i,A=/^([^\.]*)?(?:\.(.+))?$/,B=/(?:^|\s)hover(\.\S+)?\b/,C=/^key/,D=/^(?:mouse|contextmenu)|click/,E=/^(?:focusinfocus|focusoutblur)$/,F=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,G=function(
a){var b=F.exec(a);b&&(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},H=function(a,b){var c=a.attributes||{};return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||(c.id||{}).value===b[2])&&(!b[3]||b[3].test((c["class"]||{}).value))},I=function(a){return f.event.special.hover?a:a.replace(B,"mouseenter$1 mouseleave$1")};f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler,g=p.selector),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=f.trim(I(c)).split(" ");for(k=0;k<c.length;k++){l=A.exec(c[k])||[],m=l[1],n=(l[2]||"").split(".").sort(),s=f.event.special[m]||{},m=(g?s.delegateType:s.bindType)||m,s=f.event.special[m]||{},o=f.extend({type:m,origType:l[1],data:e,handler:d,guid:d.guid,selector:g,quick:g&&G(g),namespace:n.join(".")},p),r=j[m];if(!r){r=j[m]=[],r.delegateCount=0;if(!s.setup||s.setup.call(a,e,n,i)===!1)a.addEventListener?a.addEventListener(m,i,!1):a.attachEvent&&a.attachEvent("on"+m,i)}s.add&&(s.add.call(a,o),o.handler.guid||(o.handler.guid=d.guid)),g?r.splice(r.delegateCount++,0,o):r.push(o),f.event.global[m]=!0}a=null}},global:{},remove:function(a,b,c,d,e){var g=f.hasData(a)&&f._data(a),h,i,j,k,l,m,n,o,p,q,r,s;if(!!g&&!!(o=g.events)){b=f.trim(I(b||"")).split(" ");for(h=0;h<b.length;h++){i=A.exec(b[h])||[],j=k=i[1],l=i[2];if(!j){for(j in o)f.event.remove(a,j+b[h],c,d,!0);continue}p=f.event.special[j]||{},j=(d?p.delegateType:p.bindType)||j,r=o[j]||[],m=r.length,l=l?new RegExp("(^|\\.)"+l.split(".").sort().join("\\.(?:.*\\.)?")+"(\\.|$)"):null;for(n=0;n<r.length;n++)s=r[n],(e||k===s.origType)&&(!c||c.guid===s.guid)&&(!l||l.test(s.namespace))&&(!d||d===s.selector||d==="**"&&s.selector)&&(r.splice(n--,1),s.selector&&r.delegateCount--,p.remove&&p.remove.call(a,s));r.length===0&&m!==r.length&&((!p.teardown||p.teardown.call(a,l)===!1)&&f.removeEvent(a,j,g.handle),delete o[j])}f.isEmptyObject(o)&&(q=g.handle,q&&(q.elem=null),f.removeData(a,["events","handle"],!0))}},customEvent:{getData:!0,setData:!0,changeData:!0},trigger:function(c,d,e,g){if(!e||e.nodeType!==3&&e.nodeType!==8){var h=c.type||c,i=[],j,k,l,m,n,o,p,q,r,s;if(E.test(h+f.event.triggered))return;h.indexOf("!")>=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"";if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,m=E.test(s+h)?e:e.parentNode,n=null;for(;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;l<r.length&&!c.isPropagationStopped();l++)m=r[l][0],c.type=r[l][1],q=(f._data(m,"events")||{})[c.type]&&f._data(m,"handle"),q&&q.apply(m,d),q=o&&m[o],q&&f.acceptData(m)&&q.apply(m,d)===!1&&c.preventDefault();c.type=h,!g&&!c.isDefaultPrevented()&&(!p._default||p._default.apply(e.ownerDocument,d)===!1)&&(h!=="click"||!f.nodeName(e,"a"))&&f.acceptData(e)&&o&&e[h]&&(h!=="focus"&&h!=="blur"||c.target.offsetWidth!==0)&&!f.isWindow(e)&&(n=e[o],n&&(e[o]=null),f.event.triggered=h,e[h](),f.event.triggered=b,n&&(e[o]=n));return c.result}},dispatch:function(c){c=f.event.fix(c||a.event);var d=(f._data(this,"events")||{})[c.type]||[],e=d.delegateCount,g=[].slice.call(arguments,0),h=!c.exclusive&&!c.namespace,i=f.event.special[c.type]||{},j=[],k,l,m,n,o,p,q,r,s,t,u;g[0]=c,c.delegateTarget=this;if(!i.preDispatch||i.preDispatch.call(this,c)!==!1){if(e&&(!c.button||c.type!=="click")){n=f(this),n.context=this.ownerDocument||this;for(m=c.target;m!=this;m=m.parentNode||this)if(m.disabled!==!0){p={},r=[],n[0]=m;for(k=0;k<e;k++)s=d[k],t=s.selector,p[t]===b&&(p[t]=s.quick?H(m,s.quick):n.is(t)),p[t]&&r.push(s);r.length&&j.push({elem:m,matches:r})}}d.length>e&&j.push({elem:this,matches:d.slice(e)});for(k=0;k<j.length&&!c.isPropagationStopped();k++){q=j[k],c.currentTarget=q.elem;for(l=0;l<q.matches.length&&!c.isImmediatePropagationStopped();l++){s=q.matches[l];if(h||!c.namespace&&!s.namespace||c.namespace_re&&c.namespace_re.test(s.namespace))c.data=s.data,c.handleObj=s,o=((f.event.special[s.origType]||{}).handle||s.handler).apply(q.elem,g),o!==b&&(c.result=o,o===!1&&(c.preventDefault(),c.stopPropagation()))}}i.postDispatch&&i.postDispatch.call(this,c);return c.result}},props:"attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){a.which==null&&(a.which=b.charCode!=null?b.charCode:b.keyCode);return a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,d){var e,f,g,h=d.button,i=d.fromElement;a.pageX==null&&d.clientX!=null&&(e=a.target.ownerDocument||c,f=e.documentElement,g=e.body,a.pageX=d.clientX+(f&&f.scrollLeft||g&&g.scrollLeft||0)-(f&&f.clientLeft||g&&g.clientLeft||0),a.pageY=d.clientY+(f&&f.scrollTop||g&&g.scrollTop||0)-(f&&f.clientTop||g&&g.clientTop||0)),!a.relatedTarget&&i&&(a.relatedTarget=i===a.target?d.toElement:i),!a.which&&h!==b&&(a.which=h&1?1:h&2?3:h&4?2:0);return a}},fix:function(a){if(a[f.expando])return a;var d,e,g=a,h=f.event.fixHooks[a.type]||{},i=h.props?this.props.concat(h.props):this.props;a=f.Event(g);for(d=i.length;d;)e=i[--d],a[e]=g[e];a.target||(a.target=g.srcElement||c),a.target.nodeType===3&&(a.target=a.target.parentNode),a.metaKey===b&&(a.metaKey=a.ctrlKey);return h.filter?h.filter(a,g):a},special:{ready:{setup:f.bindReady},load:{noBubble:!0},focus:{delegateType:"focusin"},blur:{delegateType:"focusout"},beforeunload:{setup:function(a,b,c){f.isWindow(this)&&(this.onbeforeunload=c)},teardown:function(a,b){this.onbeforeunload===b&&(this.onbeforeunload=null)}}},simulate:function(a,b,c,d){var e=f.extend(new f.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?f.event.trigger(e,null,b):f.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},f.event.handle=f.event.dispatch,f.removeEvent=c.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){a.detachEvent&&a.detachEvent("on"+b,c)},f.Event=function(a,b){if(!(this instanceof f.Event))return new f.Event(a,b);a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||a.returnValue===!1||a.getPreventDefault&&a.getPreventDefault()?K:J):this.type=a,b&&f.extend(this,b),this.timeStamp=a&&a.timeStamp||f.now(),this[f.expando]=!0},f.Event.prototype={preventDefault:function(){this.isDefaultPrevented=K;var a=this.originalEvent;!a||(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){this.isPropagationStopped=K;var a=this.originalEvent;!a||(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=K,this.stopPropagation()},isDefaultPrevented:J,isPropagationStopped:J,isImmediatePropagationStopped:J},f.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){f.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c=this,d=a.relatedTarget,e=a.handleObj,g=e.selector,h;if(!d||d!==c&&!f.contains(c,d))a.type=e.origType,h=e.handler.apply(this,arguments),a.type=b;return h}}}),f.support.submitBubbles||(f.event.special.submit={setup:function(){if(f.nodeName(this,"form"))return!1;f.event.add(this,"click._submit keypress._submit",function(a){var c=a.target,d=f.nodeName(c,"input")||f.nodeName(c,"button")?c.form:b;d&&!d._submit_attached&&(f.event.add(d,"submit._submit",function(a){a._submit_bubble=!0}),d._submit_attached=!0)})},postDispatch:function(a){a._submit_bubble&&(delete a._submit_bubble,this.parentNode&&!a.isTrigger&&f.event.simulate("submit",this.parentNode,a,!0))},teardown:function(){if(f.nodeName(this,"form"))return!1;f.event.remove(this,"._submit")}}),f.support.changeBubbles||(f.event.special.change={setup:function(){if(z.test(this.nodeName)){if(this.type==="checkbox"||this.type==="radio")f.event.add(this,"propertychange._change",function(a){a.originalEvent.propertyName==="checked"&&(this._just_changed=!0)}),f.event.add(this,"click._change",function(a){this._just_changed&&!a.isTrigger&&(this._just_changed=!1,f.event.simulate("change",this,a,!0))});return!1}f.event.add(this,"beforeactivate._change",function(a){var b=a.target;z.test(b.nodeName)&&!b._change_attached&&(f.event.add(b,"change._change",function(a){this.parentNode&&!a.isSimulated&&!a.isTrigger&&f.event.simulate("change",this.parentNode,a,!0)}),b._change_attached=!0)})},handle:function(a){var b=a.target;if(this!==b||a.isSimulated||a.isTrigger||b.type!=="radio"&&b.type!=="checkbox")return a.handleObj.handler.apply(this,arguments)},teardown:function(){f.event.remove(this,"._change");return z.test(this.nodeName)}}),f.support.focusinBubbles||f.each({focus:"focusin",blur:"focusout"},function(a,b){var d=0,e=function(a){f.event.simulate(b,a.target,f.event.fix(a),!0)};f.event.special[b]={setup:function(){d++===0&&c.addEventListener(a,e,!0)},teardown:function(){--d===0&&c.removeEventListener(a,e,!0)}}}),f.fn.extend({on:function(a,c,d,e,g){var h,i;if(typeof a=="object"){typeof c!="string"&&(d=d||c,c=b);for(i in a)this.on(i,c,d,a[i],g);return this}d==null&&e==null?(e=c,d=c=b):e==null&&(typeof c=="string"?(e=d,d=b):(e=d,d=c,c=b));if(e===!1)e=J;else if(!e)return this;g===1&&(h=e,e=function(a){f().off(a);return h.apply(this,arguments)},e.guid=h.guid||(h.guid=f.guid++));return this.each(function(){f.event.add(this,a,e,d,c)})},one:function(a,b,c,d){return this.on(a,b,c,d,1)},off:function(a,c,d){if(a&&a.preventDefault&&a.handleObj){var e=a.handleObj;f(a.delegateTarget).off(e.namespace?e.origType+"."+e.namespace:e.origType,e.selector,e.handler);return this}if(typeof a=="object"){for(var g in a)this.off(g,c,a[g]);return this}if(c===!1||typeof c=="function")d=c,c=b;d===!1&&(d=J);return this.each(function(){f.event.remove(this,a,d,c)})},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},live:function(a,b,c){f(this.context).on(a,this.selector,b,c);return this},die:function(a,b){f(this.context).off(a,this.selector||"**",b);return this},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return arguments.length==1?this.off(a,"**"):this.off(b,a,c)},trigger:function(a,b){return this.each(function(){f.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0])return f.event.trigger(a,b,this[0],!0)},toggle:function(a){var b=arguments,c=a.guid||f.guid++,d=0,e=function(c){var e=(f._data(this,"lastToggle"+a.guid)||0)%d;f._data(this,"lastToggle"+a.guid,e+1),c.preventDefault();return b[e].apply(this,arguments)||!1};e.guid=c;while(d<b.length)b[d++].guid=c;return this.click(e)},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),f.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){f.fn[b]=function(a,c){c==null&&(c=a,a=null);return arguments.length>0?this.on(b,null,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),C.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),D.test(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h<i;h++){var j=e[h];if(j){var k=!1;j=j[a];while(j){if(j[d]===c){k=e[j.sizset];break}if(j.nodeType===1){g||(j[d]=c,j.sizset=h);if(typeof b!="string"){if(j===b){k=!0;break}}else if(m.filter(b,[j]).length>0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h<i;h++){var j=e[h];if(j){var k=!1;j=j[a];while(j){if(j[d]===c){k=e[j.sizset];break}j.nodeType===1&&!g&&(j[d]=c,j.sizset=h);if(j.nodeName.toLowerCase()===b){k=j;break}j=j[a]}e[h]=k}}}var a=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n.expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t]!=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b<a.length;b++)a[b]===a[b-1]&&a.splice(b--,1)}return a},m.matches=function(a,b){return m(a,null,null,b)},m.matchesSelector=function(a,b){return m(b,null,null,[a]).length>0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e<f;e++){h=o.order[e];if(g=o.leftMatch[h].exec(a)){i=g[1],g.splice(1,1);if(i.substr(i.length-1)!=="\\"){g[1]=(g[1]||"").replace(j,""),d=o.find[h](g,b,c);if(d!=null){a=a.replace(o.match[h],"");break}}}}d||(d=typeof b.getElementsByTagName!="undefined"?b.getElementsByTagName("*"):[]);return{set:d,expr:a}},m.filter=function(a,c,d,e){var f,g,h,i,j,k,l,n,p,q=a,r=[],s=c,t=c&&c[0]&&m.isXML(c[0]);while(a&&c.length){for(h in o.filter)if((f=o.leftMatch[h].exec(a))!=null&&f[2]){k=o.filter[h],l=f[1],g=!1,f.splice(1,1);if(l.substr(l.length-1)==="\\")continue;s===r&&(r=[]);if(o.preFilter[h]){f=o.preFilter[h](f,s,d,r,e,t);if(!f)g=i=!0;else if(f===!0)continue}if(f)for(n=0;(j=s[n])!=null;n++)j&&(i=k(j,f,n,s),p=e^i,d&&i!=null?p?g=!0:s[n]=!1:p&&(r.push(j),g=!0));if(i!==b){d||(s=r),a=a.replace(o.match[h],"");if(!g)return[];break}}if(a===q)if(g==null)m.error(a);else break;q=a}return s},m.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)};var n=m.getText=function(a){var b,c,d=a.nodeType,e="";if(d){if(d===1||d===9||d===11){if(typeof a.textContent=="string")return a.textContent;if(typeof a.innerText=="string")return a.innerText.replace(k,"");for(a=a.firstChild;a;a=a.nextSibling)e+=n(a)}else if(d===3||d===4)return a.nodeValue}else for(b=0;c=a[b];b++)c.nodeType!==8&&(e+=n(c));return e},o=m.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(a){return a.getAttribute("href")},type:function(a){return a.getAttribute("type")}},relative:{"+":function(a,b){var c=typeof b=="string",d=c&&!l.test(b),e=c&&!d;d&&(b=b.toLowerCase());for(var f=0,g=a.length,h;f<g;f++)if(h=a[f]){while((h=h.previousSibling)&&h.nodeType!==1);a[f]=e||h&&h.nodeName.toLowerCase()===b?h||!1:h===b}e&&m.filter(b,a,!0)},">":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e<f;e++){c=a[e];if(c){var g=c.parentNode;a[e]=g.nodeName.toLowerCase()===b?g:!1}}}else{for(;e<f;e++)c=a[e],c&&(a[e]=d?c.parentNode:c.parentNode===b);d&&m.filter(b,a,!0)}},"":function(a,b,c){var d,f=e++,g=x;typeof b=="string"&&!l.test(b)&&(b=b.toLowerCase(),d=b,g=w),g("parentNode",b,f,a,d,c)},"~":function(a,b,c){var d,f=e++,g=x;typeof b=="string"&&!l.test(b)&&(b=b.toLowerCase(),d=b,g=w),g("previousSibling",b,f,a,d,c)}},find:{ID:function(a,b,c){if(typeof b.getElementById!="undefined"&&!c){var d=b.getElementById(a[1]);return d&&d.parentNode?[d]:[]}},NAME:function(a,b){if(typeof b.getElementsByName!="undefined"){var c=[],d=b.getElementsByName(a[1]);for(var e=0,f=d.length;e<f;e++)d[e].getAttribute("name")===a[1]&&c.push(d[e]);return c.length===0?null:c}},TAG:function(a,b){if(typeof b.getElementsByTagName!="undefined")return b.getElementsByTagName(a[1])}},preFilter:{CLASS:function(a,b,c,d,e,f){a=" "+a[1].replace(j,"")+" ";if(f)return a;for(var g=0,h;(h=b[g])!=null;g++)h&&(e^(h.className&&(" "+h.className+" ").replace(/[\t\n\r]/g," ").indexOf(a)>=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG:function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!m(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return b<c[3]-0},gt:function(a,b,c){return b>c[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=o.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h<i;h++)if(g[h]===a)return!1;return!0}m.error(e)},CHILD:function(a,b){var c,e,f,g,h,i,j,k=b[1],l=a;switch(k){case"only":case"first":while(l=l.previousSibling)if(l.nodeType===1)return!1;if(k==="first")return!0;l=a;case"last":while(l=l.nextSibling)if(l.nodeType===1)return!1;return!0;case"nth":c=b[2],e=b[3];if(c===1&&e===0)return!0;f=b[0],g=a.parentNode;if(g&&(g[d]!==f||!a.nodeIndex)){i=0;for(l=g.firstChild;l;l=l.nextSibling)l.nodeType===1&&(l.nodeIndex=++i);g[d]=f}j=a.nodeIndex-e;return c===0?j===0:j%c===0&&j/c>=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null:f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=o.setFilters[e];if(f)return f(a,c,b,d)}}},p=o.match.POS,q=function(a,b){return"\\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^\[]*\])(?![^\(]*\))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\\(\d+)/g,q));o.match.globalPOS=p;var s=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c<e;c++)d.push(a[c]);else for(;a[c];c++)d.push(a[c]);return d}}var u,v;c.documentElement.compareDocumentPosition?u=function(a,b){if(a===b){h=!0;return 0}if(!a.compareDocumentPosition||!b.compareDocumentPosition)return a.compareDocumentPosition?-1:1;return a.compareDocumentPosition(b)&4?-1:1}:(u=function(a,b){if(a===b){h=!0;return 0}if(a.sourceIndex&&b.sourceIndex)return a.sourceIndex-b.sourceIndex;var c,d,e=[],f=[],g=a.parentNode,i=b.parentNode,j=g;if(g===i)return v(a,b);if(!g)return-1;if(!i)return 1;while(j)e.unshift(j),j=j.parentNode;j=i;while(j)f.unshift(j),j=j.parentNode;c=e.length,d=f.length;for(var k=0;k<c&&k<d;k++)if(e[k]!==f[k])return v(e[k],f[k]);return k===c?v(a,f[k],-1):v(e[k],b,1)},v=function(a,b,c){if(a===b)return c;var d=a.nextSibling;while(d){if(d===b)return-1;d=d.nextSibling}return 1}),function(){var a=c.createElement("div"),d="script"+(new Date).getTime(),e=c.documentElement;a.innerHTML="<a name='"+d+"'/>",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},o.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(o.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="<a href='#'></a>",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="<p class='TEST'></p>";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=function(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagName(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}m.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return m(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="<div class='test e'></div><div class='test'></div>";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.contains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){var d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h<i;h++)m(a,g[h],e,c);return m.filter(f,e)};m.attr=f.attr,m.selectors.attrMap={},f.find=m,f.expr=m.selectors,f.expr[":"]=f.expr.filters,f.unique=m.uniqueSort,f.text=m.getText,f.isXMLDoc=m.isXML,f.contains=m.contains}();var L=/Until$/,M=/^(?:parents|prevUntil|prevAll)/,N=/,/,O=/^.[^:#\[\.,]*$/,P=Array.prototype.slice,Q=f.expr.match.globalPOS,R={children:!0,contents:!0,next:!0,prev:!0};f.fn.extend({find:function(a){var b=this,c,d;if(typeof a!="string")return f(a).filter(function(){for(c=0,d=b.length;c<d;c++)if(f.contains(b[c],this))return!0});var e=this.pushStack("","find",a),g,h,i;for(c=0,d=this.length;c<d;c++){g=e.length,f.find(a,this[c],e);if(c>0)for(h=g;h<e.length;h++)for(i=0;i<g;i++)if(e[i]===e[h]){e.splice(h--,1);break}}return e},has:function(a){var b=f(a);return this.filter(function(){for(var a=0,c=b.length;a<c;a++)if(f.contains(this,b[a]))return!0})},not:function(a){return this.pushStack(T(this,a,!1),"not",a)},filter:function(a){return this.pushStack(T(this,a,!0),"filter",a)},is:function(a){return!!a&&(typeof a=="string"?Q.test(a)?f(a,this.context).index(this[0])>=0:f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d<a.length;d++)f(g).is(a[d])&&c.push({selector:a[d],elem:g,level:h});g=g.parentNode,h++}return c}var i=Q.test(a)||typeof a!="string"?f(a,b||this.context):0;for(d=0,e=this.length;d<e;d++){g=this[d];while(g){if(i?i.index(g)>-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(S(c[0])||S(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c);L.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!R[a]?f.unique(e):e,(this.length>1||N.test(d))&&M.test(a)&&(e=e.reverse());return this.pushStack(e,a,P.call(arguments).join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var V="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/<tbody/i,_=/<|&#?\w+;/,ba=/<(?:script|style)/i,bb=/<(?:script|object|embed|option|style)/i,bc=new RegExp("<(?:"+V+")[\\s/>]","i"),bd=/checked\s*(?:[^=]|=\s*.checked.)/i,be=/\/(java|ecma)script/i,bf=/^\s*<!(?:\[CDATA\[|\-\-)/,bg={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]},bh=U(c);bg.optgroup=bg.option,bg.tbody=bg.tfoot=bg.colgroup=bg.caption=bg.thead,bg.th=bg.td,f.support.htmlSerialize||(bg._default=[1,"div<div>","</div>"]),f.fn.extend({text:function(a){return f.access(this,function(a){return a===b?f.text(this):this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a))},null,a,arguments.length)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=f.isFunction(a);return this.each(function(c){f(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f
.clean(arguments);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f.clean(arguments));return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){return f.access(this,function(a){var c=this[0]||{},d=0,e=this.length;if(a===b)return c.nodeType===1?c.innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!bg[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1></$2>");try{for(;d<e;d++)c=this[d]||{},c.nodeType===1&&(f.cleanData(c.getElementsByTagName("*")),c.innerHTML=a);c=0}catch(g){}}c&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(a){if(this[0]&&this[0].parentNode){if(f.isFunction(a))return this.each(function(b){var c=f(this),d=c.html();c.replaceWith(a.call(this,b,d))});typeof a!="string"&&(a=f(a).detach());return this.each(function(){var b=this.nextSibling,c=this.parentNode;f(this).remove(),b?f(b).before(a):f(c).append(a)})}return this.length?this.pushStack(f(f.isFunction(a)?a():a),"replaceWith",a):this},detach:function(a){return this.remove(a,!0)},domManip:function(a,c,d){var e,g,h,i,j=a[0],k=[];if(!f.support.checkClone&&arguments.length===3&&typeof j=="string"&&bd.test(j))return this.each(function(){f(this).domManip(a,c,d,!0)});if(f.isFunction(j))return this.each(function(e){var g=f(this);a[0]=j.call(this,e,c?g.html():b),g.domManip(a,c,d)});if(this[0]){i=j&&j.parentNode,f.support.parentNode&&i&&i.nodeType===11&&i.childNodes.length===this.length?e={fragment:i}:e=f.buildFragment(a,this,k),h=e.fragment,h.childNodes.length===1?g=h=h.firstChild:g=h.firstChild;if(g){c=c&&f.nodeName(g,"tr");for(var l=0,m=this.length,n=m-1;l<m;l++)d.call(c?bi(this[l],g):this[l],e.cacheable||m>1&&l<n?f.clone(h,!0,!0):h)}k.length&&f.each(k,function(a,b){b.src?f.ajax({type:"GET",global:!1,url:b.src,async:!1,dataType:"script"}):f.globalEval((b.text||b.textContent||b.innerHTML||"").replace(bf,"/*$0*/")),b.parentNode&&b.parentNode.removeChild(b)})}return this}}),f.buildFragment=function(a,b,d){var e,g,h,i,j=a[0];b&&b[0]&&(i=b[0].ownerDocument||b[0]),i.createDocumentFragment||(i=c),a.length===1&&typeof j=="string"&&j.length<512&&i===c&&j.charAt(0)==="<"&&!bb.test(j)&&(f.support.checkClone||!bd.test(j))&&(f.support.html5Clone||!bc.test(j))&&(g=!0,h=f.fragments[j],h&&h!==1&&(e=h)),e||(e=i.createDocumentFragment(),f.clean(a,i,e,d)),g&&(f.fragments[j]=h?e:1);return{fragment:e,cacheable:g}},f.fragments={},f.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){f.fn[a]=function(c){var d=[],e=f(c),g=this.length===1&&this[0].parentNode;if(g&&g.nodeType===11&&g.childNodes.length===1&&e.length===1){e[b](this[0]);return this}for(var h=0,i=e.length;h<i;h++){var j=(h>0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d,e,g,h=f.support.html5Clone||f.isXMLDoc(a)||!bc.test("<"+a.nodeName+">")?a.cloneNode(!0):bo(a);if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bk(a,h),d=bl(a),e=bl(h);for(g=0;d[g];++g)e[g]&&bk(d[g],e[g])}if(b){bj(a,h);if(c){d=bl(a),e=bl(h);for(g=0;d[g];++g)bj(d[g],e[g])}}d=e=null;return h},clean:function(a,b,d,e){var g,h,i,j=[];b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);for(var k=0,l;(l=a[k])!=null;k++){typeof l=="number"&&(l+="");if(!l)continue;if(typeof l=="string")if(!_.test(l))l=b.createTextNode(l);else{l=l.replace(Y,"<$1></$2>");var m=(Z.exec(l)||["",""])[1].toLowerCase(),n=bg[m]||bg._default,o=n[0],p=b.createElement("div"),q=bh.childNodes,r;b===c?bh.appendChild(p):U(b).appendChild(p),p.innerHTML=n[1]+l+n[2];while(o--)p=p.lastChild;if(!f.support.tbody){var s=$.test(l),t=m==="table"&&!s?p.firstChild&&p.firstChild.childNodes:n[1]==="<table>"&&!s?p.childNodes:[];for(i=t.length-1;i>=0;--i)f.nodeName(t[i],"tbody")&&!t[i].childNodes.length&&t[i].parentNode.removeChild(t[i])}!f.support.leadingWhitespace&&X.test(l)&&p.insertBefore(b.createTextNode(X.exec(l)[0]),p.firstChild),l=p.childNodes,p&&(p.parentNode.removeChild(p),q.length>0&&(r=q[q.length-1],r&&r.parentNode&&r.parentNode.removeChild(r)))}var u;if(!f.support.appendChecked)if(l[0]&&typeof (u=l.length)=="number")for(i=0;i<u;i++)bn(l[i]);else bn(l);l.nodeType?j.push(l):j=f.merge(j,l)}if(d){g=function(a){return!a.type||be.test(a.type)};for(k=0;j[k];k++){h=j[k];if(e&&f.nodeName(h,"script")&&(!h.type||be.test(h.type)))e.push(h.parentNode?h.parentNode.removeChild(h):h);else{if(h.nodeType===1){var v=f.grep(h.getElementsByTagName("script"),g);j.splice.apply(j,[k+1,0].concat(v))}d.appendChild(h)}}}return j},cleanData:function(a){var b,c,d=f.cache,e=f.event.special,g=f.support.deleteExpando;for(var h=0,i;(i=a[h])!=null;h++){if(i.nodeName&&f.noData[i.nodeName.toLowerCase()])continue;c=i[f.expando];if(c){b=d[c];if(b&&b.events){for(var j in b.events)e[j]?f.event.remove(i,j):f.removeEvent(i,j,b.handle);b.handle&&(b.handle.elem=null)}g?delete i[f.expando]:i.removeAttribute&&i.removeAttribute(f.expando),delete d[c]}}}});var bp=/alpha\([^)]*\)/i,bq=/opacity=([^)]*)/,br=/([A-Z]|^ms)/g,bs=/^[\-+]?(?:\d*\.)?\d+$/i,bt=/^-?(?:\d*\.)?\d+(?!px)[^\d\s]+$/i,bu=/^([\-+])=([\-+.\de]+)/,bv=/^margin/,bw={position:"absolute",visibility:"hidden",display:"block"},bx=["Top","Right","Bottom","Left"],by,bz,bA;f.fn.css=function(a,c){return f.access(this,function(a,c,d){return d!==b?f.style(a,c,d):f.css(a,c)},a,c,arguments.length>1)},f.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=by(a,"opacity");return c===""?"1":c}return a.style.opacity}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":f.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,c,d,e){if(!!a&&a.nodeType!==3&&a.nodeType!==8&&!!a.style){var g,h,i=f.camelCase(c),j=a.style,k=f.cssHooks[i];c=f.cssProps[i]||i;if(d===b){if(k&&"get"in k&&(g=k.get(a,!1,e))!==b)return g;return j[c]}h=typeof d,h==="string"&&(g=bu.exec(d))&&(d=+(g[1]+1)*+g[2]+parseFloat(f.css(a,c)),h="number");if(d==null||h==="number"&&isNaN(d))return;h==="number"&&!f.cssNumber[i]&&(d+="px");if(!k||!("set"in k)||(d=k.set(a,d))!==b)try{j[c]=d}catch(l){}}},css:function(a,c,d){var e,g;c=f.camelCase(c),g=f.cssHooks[c],c=f.cssProps[c]||c,c==="cssFloat"&&(c="float");if(g&&"get"in g&&(e=g.get(a,!0,d))!==b)return e;if(by)return by(a,c)},swap:function(a,b,c){var d={},e,f;for(f in b)d[f]=a.style[f],a.style[f]=b[f];e=c.call(a);for(f in b)a.style[f]=d[f];return e}}),f.curCSS=f.css,c.defaultView&&c.defaultView.getComputedStyle&&(bz=function(a,b){var c,d,e,g,h=a.style;b=b.replace(br,"-$1").toLowerCase(),(d=a.ownerDocument.defaultView)&&(e=d.getComputedStyle(a,null))&&(c=e.getPropertyValue(b),c===""&&!f.contains(a.ownerDocument.documentElement,a)&&(c=f.style(a,b))),!f.support.pixelMargin&&e&&bv.test(b)&&bt.test(c)&&(g=h.width,h.width=c,c=e.width,h.width=g);return c}),c.documentElement.currentStyle&&(bA=function(a,b){var c,d,e,f=a.currentStyle&&a.currentStyle[b],g=a.style;f==null&&g&&(e=g[b])&&(f=e),bt.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f,f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f===""?"auto":f}),by=bz||bA,f.each(["height","width"],function(a,b){f.cssHooks[b]={get:function(a,c,d){if(c)return a.offsetWidth!==0?bB(a,b,d):f.swap(a,bw,function(){return bB(a,b,d)})},set:function(a,b){return bs.test(b)?b+"px":b}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return bq.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNumeric(b)?"alpha(opacity="+b*100+")":"",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bp,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bp.test(g)?g.replace(bp,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){return f.swap(a,{display:"inline-block"},function(){return b?by(a,"margin-right"):a.style.marginRight})}})}),f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style&&a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)}),f.each({margin:"",padding:"",border:"Width"},function(a,b){f.cssHooks[a+b]={expand:function(c){var d,e=typeof c=="string"?c.split(" "):[c],f={};for(d=0;d<4;d++)f[a+bx[d]+b]=e[d]||e[d-2]||e[0];return f}}});var bC=/%20/g,bD=/\[\]$/,bE=/\r?\n/g,bF=/#.*$/,bG=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bH=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bI=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bJ=/^(?:GET|HEAD)$/,bK=/^\/\//,bL=/\?/,bM=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,bN=/^(?:select|textarea)/i,bO=/\s+/,bP=/([?&])_=[^&]*/,bQ=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bR=f.fn.load,bS={},bT={},bU,bV,bW=["*/"]+["*"];try{bU=e.href}catch(bX){bU=c.createElement("a"),bU.href="",bU=bU.href}bV=bQ.exec(bU.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bR)return bR.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("<div>").append(c.replace(bM,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bN.test(this.nodeName)||bH.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bE,"\r\n")}}):{name:b.name,value:c.replace(bE,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.on(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?b$(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),b$(a,b);return a},ajaxSettings:{url:bU,isLocal:bI.test(bV[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded; charset=UTF-8",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bW},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:bY(bS),ajaxTransport:bY(bT),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?ca(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=cb(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.fireWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f.Callbacks("once memory"),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bG.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.add,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bF,"").replace(bK,bV[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bO),d.crossDomain==null&&(r=bQ.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bV[1]&&r[2]==bV[2]&&(r[3]||(r[1]==="http:"?80:443))==(bV[3]||(bV[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),bZ(bS,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bJ.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bL.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bP,"$1_="+x);d.url=y+(y===d.url?(bL.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bW+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=bZ(bT,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){if(s<2)w(-1,z);else throw z}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)b_(g,a[g],c,e);return d.join("&").replace(bC,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cc=f.now(),cd=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cc++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=typeof b.data=="string"&&/^application\/x\-www\-form\-urlencoded/.test(b.contentType);if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(cd.test(b.url)||e&&cd.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(cd,l),b.url===j&&(e&&(k=k.replace(cd,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var ce=a.ActiveXObject?function(){for(var a in cg)cg[a](0,1)}:!1,cf=0,cg;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ch()||ci()}:ch,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,ce&&delete cg[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n);try{m.text=h.responseText}catch(a){}try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cf,ce&&(cg||(cg={},f(a).unload(ce)),cg[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var cj={},ck,cl,cm=/^(?:toggle|show|hide)$/,cn=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,co,cp=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cq;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(ct("show",3),a,b,c);for(var g=0,h=this.length;g<h;g++)d=this[g],d.style&&(e=d.style.display,!f._data(d,"olddisplay")&&e==="none"&&(e=d.style.display=""),(e===""&&f.css(d,"display")==="none"||!f.contains(d.ownerDocument.documentElement,d))&&f._data(d,"olddisplay",cu(d.nodeName)));for(g=0;g<h;g++){d=this[g];if(d.style){e=d.style.display;if(e===""||e==="none")d.style.display=f._data(d,"olddisplay")||""}}return this},hide:function(a,b,c){if(a||a===0)return this.animate(ct("hide",3),a,b,c);var d,e,g=0,h=this.length;for(;g<h;g++)d=this[g],d.style&&(e=f.css(d,"display"),e!=="none"&&!f._data(d,"olddisplay")&&f._data(d,"olddisplay",e));for(g=0;g<h;g++)this[g].style&&(this[g].style.display="none");return this},_toggle:f.fn.toggle,toggle:function(a,b,c){var d=typeof a=="boolean";f.isFunction(a)&&f.isFunction(b)?this._toggle.apply(this,arguments):a==null||d?this.each(function(){var b=d?a:f(this).is(":hidden");f(this)[b?"show":"hide"]()}):this.animate(ct("toggle",3),a,b,c);return this},fadeTo:function(a,b,c,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){function g(){e.queue===!1&&f._mark(this);var b=f.extend({},e),c=this.nodeType===1,d=c&&f(this).is(":hidden"),g,h,i,j,k,l,m,n,o,p,q;b.animatedProperties={};for(i in a){g=f.camelCase(i),i!==g&&(a[g]=a[i],delete a[i]);if((k=f.cssHooks[g])&&"expand"in k){l=k.expand(a[g]),delete a[g];for(i in l)i in a||(a[i]=l[i])}}for(g in a){h=a[g],f.isArray(h)?(b.animatedProperties[g]=h[1],h=a[g]=h[0]):b.animatedProperties[g]=b.specialEasing&&b.specialEasing[g]||b.easing||"swing";if(h==="hide"&&d||h==="show"&&!d)return b.complete.call(this);c&&(g==="height"||g==="width")&&(b.overflow=[this.style.overflow,this.style.overflowX,this.style.overflowY],f.css(this,"display")==="inline"&&f.css(this,"float")==="none"&&(!f.support.inlineBlockNeedsLayout||cu(this.nodeName)==="inline"?this.style.display="inline-block":this.style.zoom=1))}b.overflow!=null&&(this.style.overflow="hidden");for(i in a)j=new f.fx(this,b,i),h=a[i],cm.test(h)?(q=f._data(this,"toggle"+i)||(h==="toggle"?d?"show":"hide":0),q?(f._data(this,"toggle"+i,q==="show"?"hide":"show"),j[q]()):j[h]()):(m=cn.exec(h),n=j.cur(),m?(o=parseFloat(m[2]),p=m[3]||(f.cssNumber[i]?"":"px"),p!=="px"&&(f.style(this,i,(o||1)+p),n=(o||1)/j.cur()*n,f.style(this,i,n+p)),m[1]&&(o=(m[1]==="-="?-1:1)*o+n),j.custom(n,o,p)):j.custom(n,h,""));return!0}var e=f.speed(b,c,d);if(f.isEmptyObject(a))return this.each(e.complete,[!1]);a=f.extend({},a);return e.queue===!1?this.each(g):this.queue(e.queue,g)},stop:function(a,c,d){typeof a!="string"&&(d=c,c=a,a=b),c&&a!==!1&&this.queue(a||"fx",[]);return this.each(function(){function h(a,b,c){var e=b[c];f.removeData(a,c,!0),e.stop(d)}var b,c=!1,e=f.timers,g=f._data(this);d||f._unmark(!0,this);if(a==null)for(b in g)g[b]&&g[b].stop&&b.indexOf(".run")===b.length-4&&h(this,g,b);else g[b=a+".run"]&&g[b].stop&&h(this,g,b);for(b=e.length;b--;)e[b].elem===this&&(a==null||e[b].queue===a)&&(d?e[b](!0):e[b].saveState(),c=!0,e.splice(b,1));(!d||!c)&&f.dequeue(this,a)})}}),f.each({slideDown:ct("show",1),slideUp:ct("hide",1),slideToggle:ct("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){f.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),f.extend({speed:function(a,b,c){var d=a&&typeof a=="object"?f.extend({},a):{complete:c||!c&&b||f.isFunction(a)&&a,duration:a,easing:c&&b||b&&!f.isFunction(b)&&b};d.duration=f.fx.off?0:typeof d.duration=="number"?d.duration:d.duration in f.fx.speeds?f.fx.speeds[d.duration]:f.fx.speeds._default;if(d.queue==null||d.queue===!0)d.queue="fx";d.old=d.complete,d.complete=function(a){f.isFunction(d.old)&&d.old.call(this),d.queue?f.dequeue(this,d.queue):a!==!1&&f._unmark(this)};return d},easing:{linear:function(a){return a},swing:function(a){return-Math.cos(a*Math.PI)/2+.5}},timers:[],fx:function(a,b,c){this.options=b,this.elem=a,this.prop=c,b.orig=b.orig||{}}}),f.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this),(f.fx.step[this.prop]||f.fx.step._default)(this)},cur:function(){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];var a,b=f.css(this.elem,this.prop);return isNaN(a=parseFloat(b))?!b||b==="auto"?0:b:a},custom:function(a,c,d){function h(a){return e.step(a)}var e=this,g=f.fx;this.startTime=cq||cr(),this.end=c,this.now=this.start=a,this.pos=this.state=0,this.unit=d||this.unit||(f.cssNumber[this.prop]?"":"px"),h.queue=this.options.queue,h.elem=this.elem,h.saveState=function(){f._data(e.elem,"fxshow"+e.prop)===b&&(e.options.hide?f._data(e.elem,"fxshow"+e.prop,e.start):e.options.show&&f._data(e.elem,"fxshow"+e.prop,e.end))},h()&&f.timers.push(h)&&!co&&(co=setInterval(g.tick,g.interval))},show:function(){var a=f._data(this.elem,"fxshow"+this.prop);this.options.orig[this.prop]=a||f.style(this.elem,this.prop),this.options.show=!0,a!==b?this.custom(this.cur(),a):this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur()),f(this.elem).show()},hide:function(){this.options.orig[this.prop]=f._data(this.elem,"fxshow"+this.prop)||f.style(this.elem,this.prop),this.options.hide=!0,this.custom(this.cur(),0)},step:function(a){var b,c,d,e=cq||cr(),g=!0,h=this.elem,i=this.options;if(a||e>=i.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),i.animatedProperties[this.prop]=!0;for(b in i.animatedProperties)i.animatedProperties[b]!==!0&&(g=!1);if(g){i.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){h.style["overflow"+b]=i.overflow[a]}),i.hide&&f(h).hide();if(i.hide||i.show)for(b in i.animatedProperties)f.style(h,b,i.orig[b]),f.removeData(h,"fxshow"+b,!0),f.removeData(h,"toggle"+b,!0);d=i.complete,d&&(i.complete=!1,d.call(h))}return!1}i.duration==Infinity?this.now=e:(c=e-this.startTime,this.state=c/i.duration,this.pos=f.easing[i.animatedProperties[this.prop]](this.state,c,0,1,i.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a,b=f.timers,c=0;for(;c<b.length;c++)a=b[c],!a()&&b[c]===a&&b.splice(c--,1);b.length||f.fx.stop()},interval:13,stop:function(){clearInterval(co),co=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){f.style(a.elem,"opacity",a.now)},_default:function(a){a.elem.style&&a.elem.style[a.prop]!=null?a.elem.style[a.prop]=a.now+a.unit:a.elem[a.prop]=a.now}}}),f.each(cp.concat.apply([],cp),function(a,b){b.indexOf("margin")&&(f.fx.step[b]=function(a){f.style(a.elem,b,Math.max(0,a.now)+a.unit)})}),f.expr&&f.expr.filters&&(f.expr.filters.animated=function(a){return f.grep(f.timers,function(b){return a===b.elem}).length});var cv,cw=/^t(?:able|d|h)$/i,cx=/^(?:body|html)$/i;"getBoundingClientRect"in c.documentElement?cv=function(a,b,c,d){try{d=a.getBoundingClientRect()}catch(e){}if(!d||!f.contains(c,a))return d?{top:d.top,left:d.left}:{top:0,left:0};var g=b.body,h=cy(b),i=c.clientTop||g.clientTop||0,j=c.clientLeft||g.clientLeft||0,k=h.pageYOffset||f.support.boxModel&&c.scrollTop||g.scrollTop,l=h.pageXOffset||f.support.boxModel&&c.scrollLeft||g.scrollLeft,m=d.top+k-i,n=d.left+l-j;return{top:m,left:n}}:cv=function(a,b,c){var d,e=a.offsetParent,g=a,h=b.body,i=b.defaultView,j=i?i.getComputedStyle(a,null):a.currentStyle,k=a.offsetTop,l=a.offsetLeft;while((a=a.parentNode)&&a!==h&&a!==c){if(f.support.fixedPosition&&j.position==="fixed")break;d=i?i.getComputedStyle(a,null):a.currentStyle,k-=a.scrollTop,l-=a.scrollLeft,a===e&&(k+=a.offsetTop,l+=a.offsetLeft,f.support.doesNotAddBorder&&(!f.support.doesAddBorderForTableAndCells||!cw.test(a.nodeName))&&(k+=parseFloat(d.borderTopWidth)||0,l+=parseFloat(d.borderLeftWidth)||0),g=e,e=a.offsetParent),f.support.subtractsBorderForOverflowNotVisible&&d.overflow!=="visible"&&(k+=parseFloat(d.borderTopWidth)||0,l+=parseFloat(d.borderLeftWidth)||0),j=d}if(j.position==="relative"||j.position==="static")k+=h.offsetTop,l+=h.offsetLeft;f.support.fixedPosition&&j.position==="fixed"&&(k+=Math.max(c.scrollTop,h.scrollTop),l+=Math.max(c.scrollLeft,h.scrollLeft));return{top:k,left:l}},f.fn.offset=function(a){if(arguments.length)return a===b?this:this.each(function(b){f.offset.setOffset(this,a,b)});var c=this[0],d=c&&c.ownerDocument;if(!d)return null;if(c===d.body)return f.offset.bodyOffset(c);return cv(c,d,d.documentElement)},f.offset={bodyOffset:function(a){var b=a.offsetTop,c=a.offsetLeft;f.support.doesNotIncludeMarginInBodyOffset&&(b+=parseFloat(f.css(a,"marginTop"))||0,c+=parseFloat(f.css(a,"marginLeft"))||0);return{top:b,left:c}},setOffset:function(a,b,c){var d=f.css(a,"position");d==="static"&&(a.style.position="relative");var e=f(a),g=e.offset(),h=f.css(a,"top"),i=f.css(a,"left"),j=(d==="absolute"||d==="fixed")&&f.inArray("auto",[h,i])>-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cx.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cx.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,c){var d=/Y/.test(c);f.fn[a]=function(e){return f.access(this,function(a,e,g){var h=cy(a);if(g===b)return h?c in h?h[c]:f.support.boxModel&&h.document.documentElement[e]||h.document.body[e]:a[e];h?h.scrollTo(d?f(h).scrollLeft():g,d?g:f(h).scrollTop()):a[e]=g},a,e,arguments.length,null)}}),f.each({Height:"height",Width:"width"},function(a,c){var d="client"+a,e="scroll"+a,g="offset"+a;f.fn["inner"+a]=function(){var a=this[0];return a?a.style?parseFloat(f.css(a,c,"padding")):this[c]():null},f.fn["outer"+a]=function(a){var b=this[0];return b?b.style?parseFloat(f.css(b,c,a?"margin":"border")):this[c]():null},f.fn[c]=function(a){return f.access(this,function(a,c,h){var i,j,k,l;if(f.isWindow(a)){i=a.document,j=i.documentElement[d];return f.support.boxModel&&j||i.body&&i.body[d]||j}if(a.nodeType===9){i=a.documentElement;if(i[d]>=i[e])return i[d];return Math.max(a.body[e],i[e],a.body[g],i[g])}if(h===b){k=f.css(a,c),l=parseFloat(k);return f.isNumeric(l)?l:k}f(a).css(c,h)},c,a,arguments.length,null)}}),a.jQuery=a.$=f,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return f})})(window);

================================================
FILE: extra/loader.coffee
================================================
fs = {}

makeURL = (blob) ->
    return URL.createObjectURL blob

makeBlob = (data, type) ->
    #builder = new BlobBuilder()
    #builder.append(data)
    #blob = builder.getBlob(type)
    #is recommended, but doesn't work in either Firefox or Chrome o_O
    blob = new Blob([data], type:type)
    return blob

window.getURL = (data, mime) ->
    blob = makeBlob data, mime
    return makeURL blob

resolvePath = (base, path) ->
    if path[0] == '/'
        return path
    else
        path = path.split '/'
        if base == '/'
            base = ['']
        else
            base = base.split '/'

        while base.length > 0 and path.length > 0 and path[0] == '..'
            base.pop()
            path.shift()

        if base.length == 0 || path.length == 0 || base[0] != ''
            throw "Invalid path: #{base.join '/'}/#{path.join '/'}"
        return "#{base.join('/')}/#{path.join('/')}"

getJSON = (url, callback) ->
    request = new XMLHttpRequest()
    request.open 'GET', url, true
    request.onload = ->
        callback(JSON.parse(request.response))
    request.send()

getBuffer = (url, progress, callback) ->
    request = new XMLHttpRequest()
    request.open 'GET', url, true
    request.responseType = 'arraybuffer'
    request.onload = ->
        callback(request.response)
    request.onprogress = (event) ->
        if event.lengthComputable
            progress event.loaded/event.total
    request.send()

isImage = (path) ->
    return path.match('\.jpg$|\.jpeg|\.gif$|\.png')

window.loader =
    resolvePath: resolvePath
    main: ->
        main = @require 'main'
        if main.main
            main.main()
        else
            throw 'Main function is not defined in main module.'

    define: (path, code) ->
        dirname = path.split '/'
        dirname.pop()
        dirname = dirname.join '/'

        require = (modpath) ->
            abspath = resolvePath dirname, modpath
            node = fs["#{abspath}.js"]
            if not node
                node = fs["#{abspath}/module.js"]
            if not node then throw "Module not found: #{abspath}"
            if !node.value then node.create()
            return node.value

        get = (respath) ->
            abspath = resolvePath dirname, respath
            node = fs[abspath]
            if not node then throw "Resource not found: #{abspath}"
            return node

        get.exists = (respath) ->
            abspath = resolvePath dirname, respath
            node = fs[abspath]
            return node != undefined

        folder = get.folder = (folderpath) ->
            folder_abs = resolvePath dirname, folderpath
            return {
                path: folder_abs,
                name: folder_abs.split('/')[folder_abs.split('/').length-1]
                get: (respath) ->
                    nodepath = resolvePath folder_abs, respath
                    node = fs[nodepath]
                    if not node then throw "Resource not found: #{nodepath}"
                    return node

                exists: (respath) ->
                    nodepath = resolvePath folder_abs, respath
                    return fs[nodepath] != undefined
                    
                listdir: (respath) ->
                    if respath then nodepath = resolvepath folder_abs, respath
                    else nodepath = folder_abs

                    result = []
                    for name of fs
                        match = name.match "#{folder_abs}/[a-zA-Z0-9-\.]+"
                        if match
                            match = match[0]
                            if result.indexOf(match) == -1
                                result.push match

                    translated = []
                    for name in result
                        if name.match /\.[a-z]+$/
                            translated.push name
                        else
                            translated.push folder name
                    return translated
            }

        get.listdir = (respath, match) ->
            if respath
                abspath = resolvePath dirname, respath
            else
                abspath = dirname

            result = []
            for name of fs
                if name.search(abspath) == 0
                    if match
                        if name.match match
                            result.push name
                    else
                        result.push name
            return result

        fs[path] =
            path: path
            type: 'code'
            data: code
            create: ->
                @value = {}
                retval = code @value, require, get
                if retval
                    @value = retval

    require: (modpath) ->
        abspath = resolvePath '/', modpath
        node = fs["#{abspath}.js"]
        if not node
            node = fs["#{abspath}/module.js"]

        if not node then throw "Module not found: #{abspath}"
        if !node.value then node.create()
        return node.value

    loadPack: ({url, progress, loaded}) ->
        files = {}
        hooks = @hooks
        getBuffer url, ((factor) -> if progress then progress(factor*0.5, 'network')), (data) ->
            decoding = 0
            decoded = 0

            doLoad = (name, info) ->
                if typeof info == 'object' and info.offset != undefined and info.size != undefined
                    storage = new ArrayBuffer info.size
                    dst = new Uint8Array storage
                    src = new Uint8Array data, 8+length+info.offset, info.size
                    dst.set src
                    dst = dst.buffer

                    if hooks
                        for matcher, decode of hooks
                            if name.match(matcher)
                                decoding += 1
                                decode name, dst, (result) ->
                                    decoded += 1
                                    files[name] = result
                                    if progress then progress(0.5+(decoded/decoding)*0.5, 'decode')
                                    if decoding == decoded and loaded then loaded(files)
                                return
                    files[name] = dst
                else
                    if hooks
                        for matcher, decode of hooks
                            if name.match(matcher)
                                decode name, info, (result) ->
                                    files[name] = result
                                return
                    files[name] = info

            length = new Uint32Array(data, 4, 1)[0]
            metadata = new Uint8Array(data, 8, length)
            result = ''
            for i in [0...length]
                result += String.fromCharCode(metadata[i])
            result = JSON.parse(result)

            for name, info of result
                doLoad name, info, data

            if decoding == decoded and loaded then loaded(files)

    hooks: (@hooks) -> return @

    mount: ({url, mountpoint, progress, loaded}) ->
        mountpoint ?= '/'
        @loadPack url: url, progress: progress, loaded: (data) ->
            for name, value of data
                fs[name] = value
            loaded(data, fs)


================================================
FILE: extra/loader.js
================================================
// Generated by CoffeeScript 1.3.3
(function() {
  var fs, getBuffer, getJSON, isImage, makeBlob, makeURL, resolvePath;

  fs = {};

  makeURL = function(blob) {
    return URL.createObjectURL(blob);
  };

  makeBlob = function(data, type) {
    var blob;
    blob = new Blob([data], {
      type: type
    });
    return blob;
  };

  window.getURL = function(data, mime) {
    var blob;
    blob = makeBlob(data, mime);
    return makeURL(blob);
  };

  resolvePath = function(base, path) {
    if (path[0] === '/') {
      return path;
    } else {
      path = path.split('/');
      if (base === '/') {
        base = [''];
      } else {
        base = base.split('/');
      }
      while (base.length > 0 && path.length > 0 && path[0] === '..') {
        base.pop();
        path.shift();
      }
      if (base.length === 0 || path.length === 0 || base[0] !== '') {
        throw "Invalid path: " + (base.join('/')) + "/" + (path.join('/'));
      }
      return "" + (base.join('/')) + "/" + (path.join('/'));
    }
  };

  getJSON = function(url, callback) {
    var request;
    request = new XMLHttpRequest();
    request.open('GET', url, true);
    request.onload = function() {
      return callback(JSON.parse(request.response));
    };
    return request.send();
  };

  getBuffer = function(url, progress, callback) {
    var request;
    request = new XMLHttpRequest();
    request.open('GET', url, true);
    request.responseType = 'arraybuffer';
    request.onload = function() {
      return callback(request.response);
    };
    request.onprogress = function(event) {
      if (event.lengthComputable) {
        return progress(event.loaded / event.total);
      }
    };
    return request.send();
  };

  isImage = function(path) {
    return path.match('\.jpg$|\.jpeg|\.gif$|\.png');
  };

  window.loader = {
    resolvePath: resolvePath,
    main: function() {
      var main;
      main = this.require('main');
      if (main.main) {
        return main.main();
      } else {
        throw 'Main function is not defined in main module.';
      }
    },
    define: function(path, code) {
      var dirname, folder, get, require;
      dirname = path.split('/');
      dirname.pop();
      dirname = dirname.join('/');
      require = function(modpath) {
        var abspath, node;
        abspath = resolvePath(dirname, modpath);
        node = fs["" + abspath + ".js"];
        if (!node) {
          node = fs["" + abspath + "/module.js"];
        }
        if (!node) {
          throw "Module not found: " + abspath;
        }
        if (!node.value) {
          node.create();
        }
        return node.value;
      };
      get = function(respath) {
        var abspath, node;
        abspath = resolvePath(dirname, respath);
        node = fs[abspath];
        if (!node) {
          throw "Resource not found: " + abspath;
        }
        return node;
      };
      get.exists = function(respath) {
        var abspath, node;
        abspath = resolvePath(dirname, respath);
        node = fs[abspath];
        return node !== void 0;
      };
      folder = get.folder = function(folderpath) {
        var folder_abs;
        folder_abs = resolvePath(dirname, folderpath);
        return {
          path: folder_abs,
          name: folder_abs.split('/')[folder_abs.split('/').length - 1],
          get: function(respath) {
            var node, nodepath;
            nodepath = resolvePath(folder_abs, respath);
            node = fs[nodepath];
            if (!node) {
              throw "Resource not found: " + nodepath;
            }
            return node;
          },
          exists: function(respath) {
            var nodepath;
            nodepath = resolvePath(folder_abs, respath);
            return fs[nodepath] !== void 0;
          },
          listdir: function(respath) {
            var match, name, nodepath, result, translated, _i, _len;
            if (respath) {
              nodepath = resolvepath(folder_abs, respath);
            } else {
              nodepath = folder_abs;
            }
            result = [];
            for (name in fs) {
              match = name.match("" + folder_abs + "/[a-zA-Z0-9-\.]+");
              if (match) {
                match = match[0];
                if (result.indexOf(match) === -1) {
                  result.push(match);
                }
              }
            }
            translated = [];
            for (_i = 0, _len = result.length; _i < _len; _i++) {
              name = result[_i];
              if (name.match(/\.[a-z]+$/)) {
                translated.push(name);
              } else {
                translated.push(folder(name));
              }
            }
            return translated;
          }
        };
      };
      get.listdir = function(respath, match) {
        var abspath, name, result;
        if (respath) {
          abspath = resolvePath(dirname, respath);
        } else {
          abspath = dirname;
        }
        result = [];
        for (name in fs) {
          if (name.search(abspath) === 0) {
            if (match) {
              if (name.match(match)) {
                result.push(name);
              }
            } else {
              result.push(name);
            }
          }
        }
        return result;
      };
      return fs[path] = {
        path: path,
        type: 'code',
        data: code,
        create: function() {
          var retval;
          this.value = {};
          retval = code(this.value, require, get);
          if (retval) {
            return this.value = retval;
          }
        }
      };
    },
    require: function(modpath) {
      var abspath, node;
      abspath = resolvePath('/', modpath);
      node = fs["" + abspath + ".js"];
      if (!node) {
        node = fs["" + abspath + "/module.js"];
      }
      if (!node) {
        throw "Module not found: " + abspath;
      }
      if (!node.value) {
        node.create();
      }
      return node.value;
    },
    loadPack: function(_arg) {
      var files, hooks, loaded, progress, url;
      url = _arg.url, progress = _arg.progress, loaded = _arg.loaded;
      files = {};
      hooks = this.hooks;
      return getBuffer(url, (function(factor) {
        if (progress) {
          return progress(factor * 0.5, 'network');
        }
      }), function(data) {
        var decoded, decoding, doLoad, i, info, length, metadata, name, result, _i;
        decoding = 0;
        decoded = 0;
        doLoad = function(name, info) {
          var decode, dst, matcher, src, storage;
          if (typeof info === 'object' && info.offset !== void 0 && info.size !== void 0) {
            storage = new ArrayBuffer(info.size);
            dst = new Uint8Array(storage);
            src = new Uint8Array(data, 8 + length + info.offset, info.size);
            dst.set(src);
            dst = dst.buffer;
            if (hooks) {
              for (matcher in hooks) {
                decode = hooks[matcher];
                if (name.match(matcher)) {
                  decoding += 1;
                  decode(name, dst, function(result) {
                    decoded += 1;
                    files[name] = result;
                    if (progress) {
                      progress(0.5 + (decoded / decoding) * 0.5, 'decode');
                    }
                    if (decoding === decoded && loaded) {
                      return loaded(files);
                    }
                  });
                  return;
                }
              }
            }
            return files[name] = dst;
          } else {
            if (hooks) {
              for (matcher in hooks) {
                decode = hooks[matcher];
                if (name.match(matcher)) {
                  decode(name, info, function(result) {
                    return files[name] = result;
                  });
                  return;
                }
              }
            }
            return files[name] = info;
          }
        };
        length = new Uint32Array(data, 4, 1)[0];
        metadata = new Uint8Array(data, 8, length);
        result = '';
        for (i = _i = 0; 0 <= length ? _i < length : _i > length; i = 0 <= length ? ++_i : --_i) {
          result += String.fromCharCode(metadata[i]);
        }
        result = JSON.parse(result);
        for (name in result) {
          info = result[name];
          doLoad(name, info, data);
        }
        if (decoding === decoded && loaded) {
          return loaded(files);
        }
      });
    },
    hooks: function(hooks) {
      this.hooks = hooks;
      return this;
    },
    mount: function(_arg) {
      var loaded, mountpoint, progress, url;
      url = _arg.url, mountpoint = _arg.mountpoint, progress = _arg.progress, loaded = _arg.loaded;
      if (mountpoint == null) {
        mountpoint = '/';
      }
      return this.loadPack({
        url: url,
        progress: progress,
        loaded: function(data) {
          var name, value;
          for (name in data) {
            value = data[name];
            fs[name] = value;
          }
          return loaded(data, fs);
        }
      });
    }
  };

}).call(this);


================================================
FILE: extra/matrix.coffee
================================================
pi = Math.PI
tau = 2*pi
deg = 360/tau
arc = tau/360

window.Mat3 = class Mat3
    constructor: (@data) ->
        @data ?= new Float32Array 9
        @identity()
    
    identity: ->
        d = @data
        d[0]  = 1; d[1]  =0; d[2]  = 0
        d[3]  = 0; d[4]  =1; d[5]  = 0
        d[6]  = 0; d[7]  =0; d[8]  = 1
        return @

    transpose: ->
        d = @data
        a01 = d[1]; a02 = d[2]; a12 = d[5]

        d[1] = d[3]
        d[2] = d[6]
        d[3] = a01
        d[5] = d[7]
        d[6] = a02
        d[7] = a12
        return @
   
    mulVec3: (vec, dst=vec) ->
        @mulVal3 vec.x, vec.y, vec.z, dst
        return dst

    mulVal3: (x, y, z, dst) ->
        dst = dst.data
        d = @data
        dst[0] = d[0]*x + d[3]*y + d[6]*z
        dst[1] = d[1]*x + d[4]*y + d[7]*z
        dst[2] = d[2]*x + d[5]*y + d[8]*z

        return @

    rotatex: (angle) ->
        s = Math.sin angle*arc
        c = Math.cos angle*arc
        return @amul(
             1,  0,  0,
             0,  c,  s,
             0, -s,  c
        )
    
    rotatey: (angle) ->
        s = Math.sin angle*arc
        c = Math.cos angle*arc
        return @amul(
             c,  0, -s,
             0,  1,  0,
             s,  0,  c
        )
    
    rotatez: (angle) ->
        s = Math.sin angle*arc
        c = Math.cos angle*arc
        return @amul(
             c,  s,  0,
            -s,  c,  0,
             0,  0,  1
        )
       
    amul: (
        b00, b10, b20,
        b01, b11, b21,
        b02, b12, b22,
        b03, b13, b23
    ) ->
        a = @data

        a00 = a[0]
        a10 = a[1]
        a20 = a[2]
        
        a01 = a[3]
        a11 = a[4]
        a21 = a[5]
        
        a02 = a[6]
        a12 = a[7]
        a22 = a[8]
        
        a[0]  = a00*b00 + a01*b10 + a02*b20
        a[1]  = a10*b00 + a11*b10 + a12*b20
        a[2]  = a20*b00 + a21*b10 + a22*b20
        
        a[3]  = a00*b01 + a01*b11 + a02*b21
        a[4]  = a10*b01 + a11*b11 + a12*b21
        a[5]  = a20*b01 + a21*b11 + a22*b21
        
        a[6]  = a00*b02 + a01*b12 + a02*b22
        a[7]  = a10*b02 + a11*b12 + a12*b22
        a[8]  = a20*b02 + a21*b12 + a22*b22

        return @

    log: ->
        d = @data
        console.log '%f, %f, %f,\n%f, %f, %f, \n%f, %f, %f, ', d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8]

window.Mat4 = class Mat4
    constructor: (@data) ->
        @data ?= new Float32Array 16
        @identity()

    identity: ->
        d = @data
        d[0]  = 1; d[1]  =0; d[2]  = 0; d[3]  = 0
        d[4]  = 0; d[5]  =1; d[6]  = 0; d[7]  = 0
        d[8]  = 0; d[9]  =0; d[10] = 1; d[11] = 0
        d[12] = 0; d[13] =0; d[14] = 0; d[15] = 1
        return @

    zero: ->
        d = @data
        d[0]  = 0; d[1]  =0; d[2]  = 0; d[3]  = 0
        d[4]  = 0; d[5]  =0; d[6]  = 0; d[7]  = 0
        d[8]  = 0; d[9]  =0; d[10] = 0; d[11] = 0
        d[12] = 0; d[13] =0; d[14] = 0; d[15] = 0
        return @

    copy: (dest) ->
        src = @data
        dst = dest.data
        dst[0] = src[0]
        dst[1] = src[1]
        dst[2] = src[2]
        dst[3] = src[3]
        dst[4] = src[4]
        dst[5] = src[5]
        dst[6] = src[6]
        dst[7] = src[7]
        dst[8] = src[8]
        dst[9] = src[9]
        dst[10] = src[10]
        dst[11] = src[11]
        dst[12] = src[12]
        dst[13] = src[13]
        dst[14] = src[14]
        dst[15] = src[15]
        return dest

    toMat3: (dest) ->
        src = @data
        dst = dest.data
        dst[0] = src[0]
        dst[1] = src[1]
        dst[2] = src[2]
        dst[3] = src[4]
        dst[4] = src[5]
        dst[5] = src[6]
        dst[6] = src[8]
        dst[7] = src[9]
        dst[8] = src[10]
        
        return dest

    toMat3Rot: (dest) ->
        dst = dest.data
        src = @data
        a00 = src[0]; a01 = src[1]; a02 = src[2]
        a10 = src[4]; a11 = src[5]; a12 = src[6]
        a20 = src[8]; a21 = src[9]; a22 = src[10]

        b01 = a22 * a11 - a12 * a21
        b11 = -a22 * a10 + a12 * a20
        b21 = a21 * a10 - a11 * a20

        d = a00 * b01 + a01 * b11 + a02 * b21
        id = 1 / d

        dst[0] = b01 * id
        dst[3] = (-a22 * a01 + a02 * a21) * id
        dst[6] = (a12 * a01 - a02 * a11) * id
        dst[1] = b11 * id
        dst[4] = (a22 * a00 - a02 * a20) * id
        dst[7] = (-a12 * a00 + a02 * a10) * id
        dst[2] = b21 * id
        dst[5] = (-a21 * a00 + a01 * a20) * id
        dst[8] = (a11 * a00 - a01 * a10) * id

        return dest

    perspective: (fov, aspect, near, far) ->
        @zero()
        d = @data
        top = near * Math.tan(fov*Math.PI/360)
        right = top*aspect
        left = -right
        bottom = -top

        d[0] = (2*near)/(right-left)
        d[5] = (2*near)/(top-bottom)
        d[8] = (right+left)/(right-left)
        d[9] = (top+bottom)/(top-bottom)
        d[10] = -(far+near)/(far-near)
        d[11] = -1
        d[14] = -(2*far*near)/(far-near)
       
        return @
        
    inversePerspective: (fov, aspect, near, far) ->
        @zero()
        dst = @data
        top = near * Math.tan(fov*Math.PI/360)
        right = top*aspect
        left = -right
        bottom = -top

        dst[0] = (right-left)/(2*near)
        dst[5] = (top-bottom)/(2*near)
        dst[11] = -(far-near)/(2*far*near)
        dst[12] = (right+left)/(2*near)
        dst[13] = (top+bottom)/(2*near)
        dst[14] = -1
        dst[15] = (far+near)/(2*far*near)

        return @
       
    ortho: (near=-1, far=1, top=-1, bottom=1, left=-1, right=1) ->
        rl = right-left
        tb = top - bottom
        fn = far - near

        return @set(
            2/rl,   0,      0,      -(left+right)/rl,
            0,      2/tb,   0,      -(top+bottom)/tb,
            0,      0,      -2/fn,  -(far+near)/fn,
            0,      0,      0,      1,
        )
        
    inverseOrtho: (near=-1, far=1, top=-1, bottom=1, left=-1, right=1) ->
        a = (right-left)/2
        b = (right+left)/2
        c = (top-bottom)/2
        d = (top+bottom)/2
        e = (far-near)/-2
        f = (near+far)/2
        g = 1

        return @set(
            a, 0, 0, b,
            0, c, 0, d,
            0, 0, e, f,
            0, 0, 0, g
        )

    fromRotationTranslation: (quat, vec) ->
        x = quat.x; y = quat.y; z = quat.z; w = quat.w
        x2 = x + x
        y2 = y + y
        z2 = z + z

        xx = x * x2
        xy = x * y2
        xz = x * z2
        yy = y * y2
        yz = y * z2
        zz = z * z2
        wx = w * x2
        wy = w * y2
        wz = w * z2

        dest = @data
       
        ''' 
        dest[0] = 1 - 2.0 * y * y - 2.0 * y * y
        dest[1] = 2 * x * y - 2.0 * w * z
        dest[3] = 2 * x * z + 2.0 * w * y
        
        dest[4] = 2 * x * y + 2.0 * w * z
        dest[5] = 1 - 2.0 * x * x - 2.0 * z * z
        dest[6] = 2 * y * z - 2.0 * w * x

        dest[8] = 2 * x * z - 2.0 * w * y
        dest[9] = 2 * y * z + 2.0 * w * x
        dest[10] = 1 - 2.0 * x * x - 2.0 * y * y
        '''

        '''
        dest[0] = 1 - 2.0 * y * y - 2.0 * y * y
        dest[1] = 2 * x * y + 2.0 * w * z
        dest[2] = 2 * x * z - 2.0 * w * y

        dest[4] = 2 * x * y - 2.0 * w * z
        dest[5] = 1 - 2.0 * x * x - 2.0 * z * z
        dest[6] = 2 * y * z + 2.0 * w * x

        dest[8] = 2 * x * z + 2.0 * w * y
        dest[9] = 2 * y * z - 2.0 * w * x
        dest[10] = 1 - 2.0 * x * x - 2.0 * y * y
        '''

        dest[0] = 1 - (yy + zz)
        dest[1] = xy + wz
        dest[2] = xz - wy
        dest[3] = 0
        dest[4] = xy - wz
        dest[5] = 1 - (xx + zz)
        dest[6] = yz + wx
        dest[7] = 0
        dest[8] = xz + wy
        dest[9] = yz - wx
        dest[10] = 1 - (xx + yy)
        dest[11] = 0
        
        dest[12] = vec.x
        dest[13] = vec.y
        dest[14] = vec.z
        dest[15] = 1
        
        return @
    
    translateVec3: (vec) ->
        return @translateVal3 vec.x, vec.y, vec.z

    translateVal3: (x, y, z) ->
        d = @data
        a00 = d[0]; a01 = d[1]; a02 = d[2]; a03 = d[3]
        a10 = d[4]; a11 = d[5]; a12 = d[6]; a13 = d[7]
        a20 = d[8]; a21 = d[9]; a22 = d[10]; a23 = d[11]

        d[12] = a00 * x + a10 * y + a20 * z + d[12]
        d[13] = a01 * x + a11 * y + a21 * z + d[13]
        d[14] = a02 * x + a12 * y + a22 * z + d[14]
        d[15] = a03 * x + a13 * y + a23 * z + d[15]

        return @

    rotatex: (angle) ->
        d = @data
        rad = tau*(angle/360)
        s = Math.sin rad
        c = Math.cos rad

        a10 = d[4]
        a11 = d[5]
        a12 = d[6]
        a13 = d[7]
        a20 = d[8]
        a21 = d[9]
        a22 = d[10]
        a23 = d[11]

        d[4] = a10 * c + a20 * s
        d[5] = a11 * c + a21 * s
        d[6] = a12 * c + a22 * s
        d[7] = a13 * c + a23 * s

        d[8] = a10 * -s + a20 * c
        d[9] = a11 * -s + a21 * c
        d[10] = a12 * -s + a22 * c
        d[11] = a13 * -s + a23 * c

        return @

    rotatey: (angle) ->
        d = @data
        rad = tau*(angle/360)
        s = Math.sin rad
        c = Math.cos rad

        a00 = d[0]
        a01 = d[1]
        a02 = d[2]
        a03 = d[3]
        a20 = d[8]
        a21 = d[9]
        a22 = d[10]
        a23 = d[11]

        d[0] = a00 * c + a20 * -s
        d[1] = a01 * c + a21 * -s
        d[2] = a02 * c + a22 * -s
        d[3] = a03 * c + a23 * -s

        d[8] = a00 * s + a20 * c
        d[9] = a01 * s + a21 * c
        d[10] = a02 * s + a22 * c
        d[11] = a03 * s + a23 * c

        return @
    
    rotatez: (angle) ->
        d = @data
        rad = tau*(angle/360)
        s = Math.sin rad
        c = Math.cos rad

        a00 = d[0]
        a01 = d[1]
        a02 = d[2]
        a03 = d[3]
        a10 = d[4]
        a11 = d[5]
        a12 = d[6]
        a13 = d[7]

        d[0] = a00 * c + a10 * s
        d[1] = a01 * c + a11 * s
        d[2] = a02 * c + a12 * s
        d[3] = a03 * c + a13 * s
        d[4] = a00 * -s + a10 * c
        d[5] = a01 * -s + a11 * c
        d[6] = a02 * -s + a12 * c
        d[7] = a03 * -s + a13 * c
                 
        return @

    scale: (scalar) ->
        d = @data

        a00 = d[0]; a01 = d[1]; a02 = d[2]; a03 = d[3]
        a10 = d[4]; a11 = d[5]; a12 = d[6]; a13 = d[7]
        a20 = d[8]; a21 = d[9]; a22 = d[10]; a23 = d[11]

        d[0] = a00 * scalar
        d[1] = a01 * scalar
        d[2] = a02 * scalar
        d[3] = a03 * scalar

        d[4] = a10 * scalar
        d[5] = a11 * scalar
        d[6] = a12 * scalar
        d[7] = a13 * scalar

        d[8] = a20 * scalar
        d[9] = a21 * scalar
        d[10] = a22 * scalar
        d[11] = a23 * scalar
        
        return @

    mulMat4: (other, dst=@) ->
        dest = dst.data
        mat = @data
        mat2 = other.data

        a00 = mat[ 0]; a01 = mat[ 1]; a02 = mat[ 2]; a03 = mat[3]
        a10 = mat[ 4]; a11 = mat[ 5]; a12 = mat[ 6]; a13 = mat[7]
        a20 = mat[ 8]; a21 = mat[ 9]; a22 = mat[10]; a23 = mat[11]
        a30 = mat[12]; a31 = mat[13]; a32 = mat[14]; a33 = mat[15]

        b0  = mat2[0]; b1 = mat2[1]; b2 = mat2[2]; b3 = mat2[3]
        dest[0] = b0*a00 + b1*a10 + b2*a20 + b3*a30
        dest[1] = b0*a01 + b1*a11 + b2*a21 + b3*a31
        dest[2] = b0*a02 + b1*a12 + b2*a22 + b3*a32
        dest[3] = b0*a03 + b1*a13 + b2*a23 + b3*a33

        b0 = mat2[4]
        b1 = mat2[5]
        b2 = mat2[6]
        b3 = mat2[7]
        dest[4] = b0*a00 + b1*a10 + b2*a20 + b3*a30
        dest[5] = b0*a01 + b1*a11 + b2*a21 + b3*a31
        dest[6] = b0*a02 + b1*a12 + b2*a22 + b3*a32
        dest[7] = b0*a03 + b1*a13 + b2*a23 + b3*a33

        b0 = mat2[8]
        b1 = mat2[9]
        b2 = mat2[10]
        b3 = mat2[11]
        dest[8] = b0*a00 + b1*a10 + b2*a20 + b3*a30
        dest[9] = b0*a01 + b1*a11 + b2*a21 + b3*a31
        dest[10] = b0*a02 + b1*a12 + b2*a22 + b3*a32
        dest[11] = b0*a03 + b1*a13 + b2*a23 + b3*a33

        b0 = mat2[12]
        b1 = mat2[13]
        b2 = mat2[14]
        b3 = mat2[15]
        dest[12] = b0*a00 + b1*a10 + b2*a20 + b3*a30
        dest[13] = b0*a01 + b1*a11 + b2*a21 + b3*a31
        dest[14] = b0*a02 + b1*a12 + b2*a22 + b3*a32
        dest[15] = b0*a03 + b1*a13 + b2*a23 + b3*a33

        return dst
   
    mulVec3: (vec, dst=vec) ->
        return @mulVal3 vec.x, vec.y, vec.z, dst

    mulVal3: (x, y, z, dst) ->
        dst = dst.data
        d = @data
        dst[0] = d[0]*x + d[4]*y + d[8] *z
        dst[1] = d[1]*x + d[5]*y + d[9] *z
        dst[2] = d[2]*x + d[6]*y + d[10]*z

        return dst

    mulVec4: (vec, dst) ->
        dst ?= vec
        return @mulVal4 vec.x, vec.y, vec.z, vec.w, dst

    mulVal4: (x, y, z, w, dst) ->
        dst = dst.data
        d = @data
        dst[0] = d[0]*x + d[4]*y + d[8] *z + d[12]*w
        dst[1] = d[1]*x + d[5]*y + d[9] *z + d[13]*w
        dst[2] = d[2]*x + d[6]*y + d[10]*z + d[14]*w
        dst[3] = d[3]*x + d[7]*y + d[11]*z + d[15]*w

        return dst

    invert: (dst=@) ->
        mat = @data
        dest = dst.data

        a00 = mat[0]; a01 = mat[1]; a02 = mat[2]; a03 = mat[3]
        a10 = mat[4]; a11 = mat[5]; a12 = mat[6]; a13 = mat[7]
        a20 = mat[8]; a21 = mat[9]; a22 = mat[10]; a23 = mat[11]
        a30 = mat[12]; a31 = mat[13]; a32 = mat[14]; a33 = mat[15]

        b00 = a00 * a11 - a01 * a10
        b01 = a00 * a12 - a02 * a10
        b02 = a00 * a13 - a03 * a10
        b03 = a01 * a12 - a02 * a11
        b04 = a01 * a13 - a03 * a11
        b05 = a02 * a13 - a03 * a12
        b06 = a20 * a31 - a21 * a30
        b07 = a20 * a32 - a22 * a30
        b08 = a20 * a33 - a23 * a30
        b09 = a21 * a32 - a22 * a31
        b10 = a21 * a33 - a23 * a31
        b11 = a22 * a33 - a23 * a32

        d = (b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06)
            
        if d==0 then return
        invDet = 1 / d

        dest[0] = (a11 * b11 - a12 * b10 + a13 * b09) * invDet
        dest[1] = (-a01 * b11 + a02 * b10 - a03 * b09) * invDet
        dest[2] = (a31 * b05 - a32 * b04 + a33 * b03) * invDet
        dest[3] = (-a21 * b05 + a22 * b04 - a23 * b03) * invDet
        dest[4] = (-a10 * b11 + a12 * b08 - a13 * b07) * invDet
        dest[5] = (a00 * b11 - a02 * b08 + a03 * b07) * invDet
        dest[6] = (-a30 * b05 + a32 * b02 - a33 * b01) * invDet
        dest[7] = (a20 * b05 - a22 * b02 + a23 * b01) * invDet
        dest[8] = (a10 * b10 - a11 * b08 + a13 * b06) * invDet
        dest[9] = (-a00 * b10 + a01 * b08 - a03 * b06) * invDet
        dest[10] = (a30 * b04 - a31 * b02 + a33 * b00) * invDet
        dest[11] = (-a20 * b04 + a21 * b02 - a23 * b00) * invDet
        dest[12] = (-a10 * b09 + a11 * b07 - a12 * b06) * invDet
        dest[13] = (a00 * b09 - a01 * b07 + a02 * b06) * invDet
        dest[14] = (-a30 * b03 + a31 * b01 - a32 * b00) * invDet
        dest[15] = (a20 * b03 - a21 * b01 + a22 * b00) * invDet

        return dst

    set: (
        a00, a10, a20, a30,
        a01, a11, a21, a31,
        a02, a12, a22, a32,
        a03, a13, a23, a33,
    ) ->
        d = @data
        d[0]=a00; d[4]=a10; d[8]=a20; d[12]=a30
        d[1]=a01; d[5]=a11; d[9]=a21; d[13]=a31
        d[2]=a02; d[6]=a12; d[10]=a22; d[14]=a32
        d[3]=a03; d[7]=a13; d[11]=a23; d[15]=a33

        return @


================================================
FILE: extra/matrix.js
================================================
// Generated by CoffeeScript 1.3.3
(function() {
  var Mat3, Mat4, arc, deg, pi, tau;

  pi = Math.PI;

  tau = 2 * pi;

  deg = 360 / tau;

  arc = tau / 360;

  window.Mat3 = Mat3 = (function() {

    function Mat3(data) {
      var _ref;
      this.data = data;
      if ((_ref = this.data) == null) {
        this.data = new Float32Array(9);
      }
      this.identity();
    }

    Mat3.prototype.identity = function() {
      var d;
      d = this.data;
      d[0] = 1;
      d[1] = 0;
      d[2] = 0;
      d[3] = 0;
      d[4] = 1;
      d[5] = 0;
      d[6] = 0;
      d[7] = 0;
      d[8] = 1;
      return this;
    };

    Mat3.prototype.transpose = function() {
      var a01, a02, a12, d;
      d = this.data;
      a01 = d[1];
      a02 = d[2];
      a12 = d[5];
      d[1] = d[3];
      d[2] = d[6];
      d[3] = a01;
      d[5] = d[7];
      d[6] = a02;
      d[7] = a12;
      return this;
    };

    Mat3.prototype.mulVec3 = function(vec, dst) {
      if (dst == null) {
        dst = vec;
      }
      this.mulVal3(vec.x, vec.y, vec.z, dst);
      return dst;
    };

    Mat3.prototype.mulVal3 = function(x, y, z, dst) {
      var d;
      dst = dst.data;
      d = this.data;
      dst[0] = d[0] * x + d[3] * y + d[6] * z;
      dst[1] = d[1] * x + d[4] * y + d[7] * z;
      dst[2] = d[2] * x + d[5] * y + d[8] * z;
      return this;
    };

    Mat3.prototype.rotatex = function(angle) {
      var c, s;
      s = Math.sin(angle * arc);
      c = Math.cos(angle * arc);
      return this.amul(1, 0, 0, 0, c, s, 0, -s, c);
    };

    Mat3.prototype.rotatey = function(angle) {
      var c, s;
      s = Math.sin(angle * arc);
      c = Math.cos(angle * arc);
      return this.amul(c, 0, -s, 0, 1, 0, s, 0, c);
    };

    Mat3.prototype.rotatez = function(angle) {
      var c, s;
      s = Math.sin(angle * arc);
      c = Math.cos(angle * arc);
      return this.amul(c, s, 0, -s, c, 0, 0, 0, 1);
    };

    Mat3.prototype.amul = function(b00, b10, b20, b01, b11, b21, b02, b12, b22, b03, b13, b23) {
      var a, a00, a01, a02, a10, a11, a12, a20, a21, a22;
      a = this.data;
      a00 = a[0];
      a10 = a[1];
      a20 = a[2];
      a01 = a[3];
      a11 = a[4];
      a21 = a[5];
      a02 = a[6];
      a12 = a[7];
      a22 = a[8];
      a[0] = a00 * b00 + a01 * b10 + a02 * b20;
      a[1] = a10 * b00 + a11 * b10 + a12 * b20;
      a[2] = a20 * b00 + a21 * b10 + a22 * b20;
      a[3] = a00 * b01 + a01 * b11 + a02 * b21;
      a[4] = a10 * b01 + a11 * b11 + a12 * b21;
      a[5] = a20 * b01 + a21 * b11 + a22 * b21;
      a[6] = a00 * b02 + a01 * b12 + a02 * b22;
      a[7] = a10 * b02 + a11 * b12 + a12 * b22;
      a[8] = a20 * b02 + a21 * b12 + a22 * b22;
      return this;
    };

    Mat3.prototype.log = function() {
      var d;
      d = this.data;
      return console.log('%f, %f, %f,\n%f, %f, %f, \n%f, %f, %f, ', d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8]);
    };

    return Mat3;

  })();

  window.Mat4 = Mat4 = (function() {

    function Mat4(data) {
      var _ref;
      this.data = data;
      if ((_ref = this.data) == null) {
        this.data = new Float32Array(16);
      }
      this.identity();
    }

    Mat4.prototype.identity = function() {
      var d;
      d = this.data;
      d[0] = 1;
      d[1] = 0;
      d[2] = 0;
      d[3] = 0;
      d[4] = 0;
      d[5] = 1;
      d[6] = 0;
      d[7] = 0;
      d[8] = 0;
      d[9] = 0;
      d[10] = 1;
      d[11] = 0;
      d[12] = 0;
      d[13] = 0;
      d[14] = 0;
      d[15] = 1;
      return this;
    };

    Mat4.prototype.zero = function() {
      var d;
      d = this.data;
      d[0] = 0;
      d[1] = 0;
      d[2] = 0;
      d[3] = 0;
      d[4] = 0;
      d[5] = 0;
      d[6] = 0;
      d[7] = 0;
      d[8] = 0;
      d[9] = 0;
      d[10] = 0;
      d[11] = 0;
      d[12] = 0;
      d[13] = 0;
      d[14] = 0;
      d[15] = 0;
      return this;
    };

    Mat4.prototype.copy = function(dest) {
      var dst, src;
      src = this.data;
      dst = dest.data;
      dst[0] = src[0];
      dst[1] = src[1];
      dst[2] = src[2];
      dst[3] = src[3];
      dst[4] = src[4];
      dst[5] = src[5];
      dst[6] = src[6];
      dst[7] = src[7];
      dst[8] = src[8];
      dst[9] = src[9];
      dst[10] = src[10];
      dst[11] = src[11];
      dst[12] = src[12];
      dst[13] = src[13];
      dst[14] = src[14];
      dst[15] = src[15];
      return dest;
    };

    Mat4.prototype.toMat3 = function(dest) {
      var dst, src;
      src = this.data;
      dst = dest.data;
      dst[0] = src[0];
      dst[1] = src[1];
      dst[2] = src[2];
      dst[3] = src[4];
      dst[4] = src[5];
      dst[5] = src[6];
      dst[6] = src[8];
      dst[7] = src[9];
      dst[8] = src[10];
      return dest;
    };

    Mat4.prototype.toMat3Rot = function(dest) {
      var a00, a01, a02, a10, a11, a12, a20, a21, a22, b01, b11, b21, d, dst, id, src;
      dst = dest.data;
      src = this.data;
      a00 = src[0];
      a01 = src[1];
      a02 = src[2];
      a10 = src[4];
      a11 = src[5];
      a12 = src[6];
      a20 = src[8];
      a21 = src[9];
      a22 = src[10];
      b01 = a22 * a11 - a12 * a21;
      b11 = -a22 * a10 + a12 * a20;
      b21 = a21 * a10 - a11 * a20;
      d = a00 * b01 + a01 * b11 + a02 * b21;
      id = 1 / d;
      dst[0] = b01 * id;
      dst[3] = (-a22 * a01 + a02 * a21) * id;
      dst[6] = (a12 * a01 - a02 * a11) * id;
      dst[1] = b11 * id;
      dst[4] = (a22 * a00 - a02 * a20) * id;
      dst[7] = (-a12 * a00 + a02 * a10) * id;
      dst[2] = b21 * id;
      dst[5] = (-a21 * a00 + a01 * a20) * id;
      dst[8] = (a11 * a00 - a01 * a10) * id;
      return dest;
    };

    Mat4.prototype.perspective = function(fov, aspect, near, far) {
      var bottom, d, left, right, top;
      this.zero();
      d = this.data;
      top = near * Math.tan(fov * Math.PI / 360);
      right = top * aspect;
      left = -right;
      bottom = -top;
      d[0] = (2 * near) / (right - left);
      d[5] = (2 * near) / (top - bottom);
      d[8] = (right + left) / (right - left);
      d[9] = (top + bottom) / (top - bottom);
      d[10] = -(far + near) / (far - near);
      d[11] = -1;
      d[14] = -(2 * far * near) / (far - near);
      return this;
    };

    Mat4.prototype.inversePerspective = function(fov, aspect, near, far) {
      var bottom, dst, left, right, top;
      this.zero();
      dst = this.data;
      top = near * Math.tan(fov * Math.PI / 360);
      right = top * aspect;
      left = -right;
      bottom = -top;
      dst[0] = (right - left) / (2 * near);
      dst[5] = (top - bottom) / (2 * near);
      dst[11] = -(far - near) / (2 * far * near);
      dst[12] = (right + left) / (2 * near);
      dst[13] = (top + bottom) / (2 * near);
      dst[14] = -1;
      dst[15] = (far + near) / (2 * far * near);
      return this;
    };

    Mat4.prototype.ortho = function(near, far, top, bottom, left, right) {
      var fn, rl, tb;
      if (near == null) {
        near = -1;
      }
      if (far == null) {
        far = 1;
      }
      if (top == null) {
        top = -1;
      }
      if (bottom == null) {
        bottom = 1;
      }
      if (left == null) {
        left = -1;
      }
      if (right == null) {
        right = 1;
      }
      rl = right - left;
      tb = top - bottom;
      fn = far - near;
      return this.set(2 / rl, 0, 0, -(left + right) / rl, 0, 2 / tb, 0, -(top + bottom) / tb, 0, 0, -2 / fn, -(far + near) / fn, 0, 0, 0, 1);
    };

    Mat4.prototype.inverseOrtho = function(near, far, top, bottom, left, right) {
      var a, b, c, d, e, f, g;
      if (near == null) {
        near = -1;
      }
      if (far == null) {
        far = 1;
      }
      if (top == null) {
        top = -1;
      }
      if (bottom == null) {
        bottom = 1;
      }
      if (left == null) {
        left = -1;
      }
      if (right == null) {
        right = 1;
      }
      a = (right - left) / 2;
      b = (right + left) / 2;
      c = (top - bottom) / 2;
      d = (top + bottom) / 2;
      e = (far - near) / -2;
      f = (near + far) / 2;
      g = 1;
      return this.set(a, 0, 0, b, 0, c, 0, d, 0, 0, e, f, 0, 0, 0, g);
    };

    Mat4.prototype.fromRotationTranslation = function(quat, vec) {
      var dest, w, wx, wy, wz, x, x2, xx, xy, xz, y, y2, yy, yz, z, z2, zz;
      x = quat.x;
      y = quat.y;
      z = quat.z;
      w = quat.w;
      x2 = x + x;
      y2 = y + y;
      z2 = z + z;
      xx = x * x2;
      xy = x * y2;
      xz = x * z2;
      yy = y * y2;
      yz = y * z2;
      zz = z * z2;
      wx = w * x2;
      wy = w * y2;
      wz = w * z2;
      dest = this.data;
      ' \ndest[0] = 1 - 2.0 * y * y - 2.0 * y * y\ndest[1] = 2 * x * y - 2.0 * w * z\ndest[3] = 2 * x * z + 2.0 * w * y\n\ndest[4] = 2 * x * y + 2.0 * w * z\ndest[5] = 1 - 2.0 * x * x - 2.0 * z * z\ndest[6] = 2 * y * z - 2.0 * w * x\n\ndest[8] = 2 * x * z - 2.0 * w * y\ndest[9] = 2 * y * z + 2.0 * w * x\ndest[10] = 1 - 2.0 * x * x - 2.0 * y * y';

      'dest[0] = 1 - 2.0 * y * y - 2.0 * y * y\ndest[1] = 2 * x * y + 2.0 * w * z\ndest[2] = 2 * x * z - 2.0 * w * y\n\ndest[4] = 2 * x * y - 2.0 * w * z\ndest[5] = 1 - 2.0 * x * x - 2.0 * z * z\ndest[6] = 2 * y * z + 2.0 * w * x\n\ndest[8] = 2 * x * z + 2.0 * w * y\ndest[9] = 2 * y * z - 2.0 * w * x\ndest[10] = 1 - 2.0 * x * x - 2.0 * y * y';

      dest[0] = 1 - (yy + zz);
      dest[1] = xy + wz;
      dest[2] = xz - wy;
      dest[3] = 0;
      dest[4] = xy - wz;
      dest[5] = 1 - (xx + zz);
      dest[6] = yz + wx;
      dest[7] = 0;
      dest[8] = xz + wy;
      dest[9] = yz - wx;
      dest[10] = 1 - (xx + yy);
      dest[11] = 0;
      dest[12] = vec.x;
      dest[13] = vec.y;
      dest[14] = vec.z;
      dest[15] = 1;
      return this;
    };

    Mat4.prototype.translateVec3 = function(vec) {
      return this.translateVal3(vec.x, vec.y, vec.z);
    };

    Mat4.prototype.translateVal3 = function(x, y, z) {
      var a00, a01, a02, a03, a10, a11, a12, a13, a20, a21, a22, a23, d;
      d = this.data;
      a00 = d[0];
      a01 = d[1];
      a02 = d[2];
      a03 = d[3];
      a10 = d[4];
      a11 = d[5];
      a12 = d[6];
      a13 = d[7];
      a20 = d[8];
      a21 = d[9];
      a22 = d[10];
      a23 = d[11];
      d[12] = a00 * x + a10 * y + a20 * z + d[12];
      d[13] = a01 * x + a11 * y + a21 * z + d[13];
      d[14] = a02 * x + a12 * y + a22 * z + d[14];
      d[15] = a03 * x + a13 * y + a23 * z + d[15];
      return this;
    };

    Mat4.prototype.rotatex = function(angle) {
      var a10, a11, a12, a13, a20, a21, a22, a23, c, d, rad, s;
      d = this.data;
      rad = tau * (angle / 360);
      s = Math.sin(rad);
      c = Math.cos(rad);
      a10 = d[4];
      a11 = d[5];
      a12 = d[6];
      a13 = d[7];
      a20 = d[8];
      a21 = d[9];
      a22 = d[10];
      a23 = d[11];
      d[4] = a10 * c + a20 * s;
      d[5] = a11 * c + a21 * s;
      d[6] = a12 * c + a22 * s;
      d[7] = a13 * c + a23 * s;
      d[8] = a10 * -s + a20 * c;
      d[9] = a11 * -s + a21 * c;
      d[10] = a12 * -s + a22 * c;
      d[11] = a13 * -s + a23 * c;
      return this;
    };

    Mat4.prototype.rotatey = function(angle) {
      var a00, a01, a02, a03, a20, a21, a22, a23, c, d, rad, s;
      d = this.data;
      rad = tau * (angle / 360);
      s = Math.sin(rad);
      c = Math.cos(rad);
      a00 = d[0];
      a01 = d[1];
      a02 = d[2];
      a03 = d[3];
      a20 = d[8];
      a21 = d[9];
      a22 = d[10];
      a23 = d[11];
      d[0] = a00 * c + a20 * -s;
      d[1] = a01 * c + a21 * -s;
      d[2] = a02 * c + a22 * -s;
      d[3] = a03 * c + a23 * -s;
      d[8] = a00 * s + a20 * c;
      d[9] = a01 * s + a21 * c;
      d[10] = a02 * s + a22 * c;
      d[11] = a03 * s + a23 * c;
      return this;
    };

    Mat4.prototype.rotatez = function(angle) {
      var a00, a01, a02, a03, a10, a11, a12, a13, c, d, rad, s;
      d = this.data;
      rad = tau * (angle / 360);
      s = Math.sin(rad);
      c = Math.cos(rad);
      a00 = d[0];
      a01 = d[1];
      a02 = d[2];
      a03 = d[3];
      a10 = d[4];
      a11 = d[5];
      a12 = d[6];
      a13 = d[7];
      d[0] = a00 * c + a10 * s;
      d[1] = a01 * c + a11 * s;
      d[2] = a02 * c + a12 * s;
      d[3] = a03 * c + a13 * s;
      d[4] = a00 * -s + a10 * c;
      d[5] = a01 * -s + a11 * c;
      d[6] = a02 * -s + a12 * c;
      d[7] = a03 * -s + a13 * c;
      return this;
    };

    Mat4.prototype.scale = function(scalar) {
      var a00, a01, a02, a03, a10, a11, a12, a13, a20, a21, a22, a23, d;
      d = this.data;
      a00 = d[0];
      a01 = d[1];
      a02 = d[2];
      a03 = d[3];
      a10 = d[4];
      a11 = d[5];
      a12 = d[6];
      a13 = d[7];
      a20 = d[8];
      a21 = d[9];
      a22 = d[10];
      a23 = d[11];
      d[0] = a00 * scalar;
      d[1] = a01 * scalar;
      d[2] = a02 * scalar;
      d[3] = a03 * scalar;
      d[4] = a10 * scalar;
      d[5] = a11 * scalar;
      d[6] = a12 * scalar;
      d[7] = a13 * scalar;
      d[8] = a20 * scalar;
      d[9] = a21 * scalar;
      d[10] = a22 * scalar;
      d[11] = a23 * scalar;
      return this;
    };

    Mat4.prototype.mulMat4 = function(other, dst) {
      var a00, a01, a02, a03, a10, a11, a12, a13, a20, a21, a22, a23, a30, a31, a32, a33, b0, b1, b2, b3, dest, mat, mat2;
      if (dst == null) {
        dst = this;
      }
      dest = dst.data;
      mat = this.data;
      mat2 = other.data;
      a00 = mat[0];
      a01 = mat[1];
      a02 = mat[2];
      a03 = mat[3];
      a10 = mat[4];
      a11 = mat[5];
      a12 = mat[6];
      a13 = mat[7];
      a20 = mat[8];
      a21 = mat[9];
      a22 = mat[10];
      a23 = mat[11];
      a30 = mat[12];
      a31 = mat[13];
      a32 = mat[14];
      a33 = mat[15];
      b0 = mat2[0];
      b1 = mat2[1];
      b2 = mat2[2];
      b3 = mat2[3];
      dest[0] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
      dest[1] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
      dest[2] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
      dest[3] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
      b0 = mat2[4];
      b1 = mat2[5];
      b2 = mat2[6];
      b3 = mat2[7];
      dest[4] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
      dest[5] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
      dest[6] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
      dest[7] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
      b0 = mat2[8];
      b1 = mat2[9];
      b2 = mat2[10];
      b3 = mat2[11];
      dest[8] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
      dest[9] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
      dest[10] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
      dest[11] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
      b0 = mat2[12];
      b1 = mat2[13];
      b2 = mat2[14];
      b3 = mat2[15];
      dest[12] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
      dest[13] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
      dest[14] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
      dest[15] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
      return dst;
    };

    Mat4.prototype.mulVec3 = function(vec, dst) {
      if (dst == null) {
        dst = vec;
      }
      return this.mulVal3(vec.x, vec.y, vec.z, dst);
    };

    Mat4.prototype.mulVal3 = function(x, y, z, dst) {
      var d;
      dst = dst.data;
      d = this.data;
      dst[0] = d[0] * x + d[4] * y + d[8] * z;
      dst[1] = d[1] * x + d[5] * y + d[9] * z;
      dst[2] = d[2] * x + d[6] * y + d[10] * z;
      return dst;
    };

    Mat4.prototype.mulVec4 = function(vec, dst) {
      if (dst == null) {
        dst = vec;
      }
      return this.mulVal4(vec.x, vec.y, vec.z, vec.w, dst);
    };

    Mat4.prototype.mulVal4 = function(x, y, z, w, dst) {
      var d;
      dst = dst.data;
      d = this.data;
      dst[0] = d[0] * x + d[4] * y + d[8] * z + d[12] * w;
      dst[1] = d[1] * x + d[5] * y + d[9] * z + d[13] * w;
      dst[2] = d[2] * x + d[6] * y + d[10] * z + d[14] * w;
      dst[3] = d[3] * x + d[7] * y + d[11] * z + d[15] * w;
      return dst;
    };

    Mat4.prototype.invert = function(dst) {
      var a00, a01, a02, a03, a10, a11, a12, a13, a20, a21, a22, a23, a30, a31, a32, a33, b00, b01, b02, b03, b04, b05, b06, b07, b08, b09, b10, b11, d, dest, invDet, mat;
      if (dst == null) {
        dst = this;
      }
      mat = this.data;
      dest = dst.data;
      a00 = mat[0];
      a01 = mat[1];
      a02 = mat[2];
      a03 = mat[3];
      a10 = mat[4];
      a11 = mat[5];
      a12 = mat[6];
      a13 = mat[7];
      a20 = mat[8];
      a21 = mat[9];
      a22 = mat[10];
      a23 = mat[11];
      a30 = mat[12];
      a31 = mat[13];
      a32 = mat[14];
      a33 = mat[15];
      b00 = a00 * a11 - a01 * a10;
      b01 = a00 * a12 - a02 * a10;
      b02 = a00 * a13 - a03 * a10;
      b03 = a01 * a12 - a02 * a11;
      b04 = a01 * a13 - a03 * a11;
      b05 = a02 * a13 - a03 * a12;
      b06 = a20 * a31 - a21 * a30;
      b07 = a20 * a32 - a22 * a30;
      b08 = a20 * a33 - a23 * a30;
      b09 = a21 * a32 - a22 * a31;
      b10 = a21 * a33 - a23 * a31;
      b11 = a22 * a33 - a23 * a32;
      d = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
      if (d === 0) {
        return;
      }
      invDet = 1 / d;
      dest[0] = (a11 * b11 - a12 * b10 + a13 * b09) * invDet;
      dest[1] = (-a01 * b11 + a02 * b10 - a03 * b09) * invDet;
      dest[2] = (a31 * b05 - a32 * b04 + a33 * b03) * invDet;
      dest[3] = (-a21 * b05 + a22 * b04 - a23 * b03) * invDet;
      dest[4] = (-a10 * b11 + a12 * b08 - a13 * b07) * invDet;
      dest[5] = (a00 * b11 - a02 * b08 + a03 * b07) * invDet;
      dest[6] = (-a30 * b05 + a32 * b02 - a33 * b01) * invDet;
      dest[7] = (a20 * b05 - a22 * b02 + a23 * b01) * invDet;
      dest[8] = (a10 * b10 - a11 * b08 + a13 * b06) * invDet;
      dest[9] = (-a00 * b10 + a01 * b08 - a03 * b06) * invDet;
      dest[10] = (a30 * b04 - a31 * b02 + a33 * b00) * invDet;
      dest[11] = (-a20 * b04 + a21 * b02 - a23 * b00) * invDet;
      dest[12] = (-a10 * b09 + a11 * b07 - a12 * b06) * invDet;
      dest[13] = (a00 * b09 - a01 * b07 + a02 * b06) * invDet;
      dest[14] = (-a30 * b03 + a31 * b01 - a32 * b00) * invDet;
      dest[15] = (a20 * b03 - a21 * b01 + a22 * b00) * invDet;
      return dst;
    };

    Mat4.prototype.set = function(a00, a10, a20, a30, a01, a11, a21, a31, a02, a12, a22, a32, a03, a13, a23, a33) {
      var d;
      d = this.data;
      d[0] = a00;
      d[4] = a10;
      d[8] = a20;
      d[12] = a30;
      d[1] = a01;
      d[5] = a11;
      d[9] = a21;
      d[13] = a31;
      d[2] = a02;
      d[6] = a12;
      d[10] = a22;
      d[14] = a32;
      d[3] = a03;
      d[7] = a13;
      d[11] = a23;
      d[15] = a33;
      return this;
    };

    return Mat4;

  })();

}).call(this);


================================================
FILE: extra/shims.coffee
================================================
if window.performance
    if window.performance.now
        now = -> window.performance.now()
    else if window.performance.webkitNow
        now = -> window.performance.webkitNow()
    else if window.performance.mozNow
        now = -> window.performance.mozNow()
    else if window.performance.oNow
        now = -> window.performance.oNow()
    else
        now = -> Date.now()
else
    now = -> Date.now()

start = now()
window.gettime = -> (now() - start)/1000

if not window.requestAnimationFrame
    if window.webkitRequestAnimationFrame
        window.requestAnimationFrame = window.webkitRequestAnimationFrame
    else if window.mozRequestAnimationFrame
        window.requestAnimationFrame = window.mozRequestAnimationFrame
    else if window.oRequestAnimationFrame
        window.requestAnimationFrame = window.oRequestAnimationFrame
    else
        window.requestAnimationFrame = (fun) ->
            setTimeout(fun, 1000/30)

window.URL = window.URL or window.mozURL or window.webkitURL or window.oURL
window.BlobBuilder = window.BlobBuilder or window.MozBlobBuilder or window.WebKitBlobBuilder or window.OBlobBuilder

log_count = 0
window.console.logN = (n) ->
    if log_count < n
        log_count += 1
        args = [].slice.call(arguments, 1)
        console.log.apply console, args


================================================
FILE: extra/shims.js
================================================
// Generated by CoffeeScript 1.3.3
(function() {
  var log_count, now, start;

  if (window.performance) {
    if (window.performance.now) {
      now = function() {
        return window.performance.now();
      };
    } else if (window.performance.webkitNow) {
      now = function() {
        return window.performance.webkitNow();
      };
    } else if (window.performance.mozNow) {
      now = function() {
        return window.performance.mozNow();
      };
    } else if (window.performance.oNow) {
      now = function() {
        return window.performance.oNow();
      };
    } else {
      now = function() {
        return Date.now();
      };
    }
  } else {
    now = function() {
      return Date.now();
    };
  }

  start = now();

  window.gettime = function() {
    return (now() - start) / 1000;
  };

  if (!window.requestAnimationFrame) {
    if (window.webkitRequestAnimationFrame) {
      window.requestAnimationFrame = window.webkitRequestAnimationFrame;
    } else if (window.mozRequestAnimationFrame) {
      window.requestAnimationFrame = window.mozRequestAnimationFrame;
    } else if (window.oRequestAnimationFrame) {
      window.requestAnimationFrame = window.oRequestAnimationFrame;
    } else {
      window.requestAnimationFrame = function(fun) {
        return setTimeout(fun, 1000 / 30);
      };
    }
  }

  window.URL = window.URL || window.mozURL || window.webkitURL || window.oURL;

  window.BlobBuilder = window.BlobBuilder || window.MozBlobBuilder || window.WebKitBlobBuilder || window.OBlobBuilder;

  log_count = 0;

  window.console.logN = function(n) {
    var args;
    if (log_count < n) {
      log_count += 1;
      args = [].slice.call(arguments, 1);
      return console.log.apply(console, args);
    }
  };

}).call(this);


================================================
FILE: extra/vector.coffee
================================================
window.Vec3 = class Vec3
    @property 'x'
        get: -> @data[0]
        set: (val) -> @data[0] = val
    @property 'y'
        get: -> @data[1]
        set: (val) -> @data[1] = val
    @property 'z'
        get: -> @data[2]
        set: (val) -> @data[2] = val

    @property 'length'
        get: -> Math.sqrt(@x*@x + @y*@y + @z*@z)

    constructor: (@data) ->
        @data ?= new Float32Array 3

    sub: (other, dst=@) ->
        dst.x = @x - other.x
        dst.y = @y - other.y
        dst.z = @z - other.z
        return dst

    add: (other, dst=@) ->
        dst.x = @x + other.x
        dst.y = @y + other.y
        dst.z = @z + other.z
        return dst

    addVal3: (x, y, z, dst=@) ->
        dst.x = @x + x
        dst.y = @y + y
        dst.z = @z + z
        return dst

    mul: (scalar, dst=@) ->
        dst.x = @x * scalar
        dst.y = @y * scalar
        dst.z = @z * scalar
        return dst
    
    div: (scalar, dst=@) ->
        dst.x = @x / scalar
        dst.y = @y / scalar
        dst.z = @z / scalar
        return dst

    divVal3: (x, y, z, dst=@) ->
        dst.x = @x/x
        dst.y = @y/y
        dst.z = @z/z
        return dst
    
    dot: (other) ->
        return @x*other.x + @y*other.y + @z*other.z

    normalize: (dst=@) ->
        l = @length
        if l > 0 then @mul 1/@length, dst
        return dst

    set: (x,y,z) ->
        @x = x
        @y = y
        @z = z
        return @

window.Vec4 = class Vec4
    @property 'x'
        get: -> @data[0]
        set: (val) -> @data[0] = val
    @property 'y'
        get: -> @data[1]
        set: (val) -> @data[1] = val
    @property 'z'
        get: -> @data[2]
        set: (val) -> @data[2] = val
    @property 'w'
        get: -> @data[3]
        set: (val) -> @data[3] = val

    constructor: (@data) ->
        @data ?= new Float32Array 4

    sub: (other, dst=@) ->
        dst.x = @x - other.x
        dst.y = @y - other.y
        dst.z = @z - other.z
        dst.w = @w - other.w

        return dst

    dot: (other) ->
        return @x*other.x + @y*other.y + @z*other.z + @w*other.w

    toVec3: (dst) ->
        dst ?= new Vec3()
        dst.x = @x
        dst.y = @y
        dst.z = @z

        return dst


================================================
FILE: extra/vector.js
================================================
// Generated by CoffeeScript 1.3.3
(function() {
  var Vec3, Vec4;

  window.Vec3 = Vec3 = (function() {

    Vec3.property('x', {
      get: function() {
        return this.data[0];
      },
      set: function(val) {
        return this.data[0] = val;
      }
    });

    Vec3.property('y', {
      get: function() {
        return this.data[1];
      },
      set: function(val) {
        return this.data[1] = val;
      }
    });

    Vec3.property('z', {
      get: function() {
        return this.data[2];
      },
      set: function(val) {
        return this.data[2] = val;
      }
    });

    Vec3.property('length', {
      get: function() {
        return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z);
      }
    });

    function Vec3(data) {
      var _ref;
      this.data = data;
      if ((_ref = this.data) == null) {
        this.data = new Float32Array(3);
      }
    }

    Vec3.prototype.sub = function(other, dst) {
      if (dst == null) {
        dst = this;
      }
      dst.x = this.x - other.x;
      dst.y = this.y - other.y;
      dst.z = this.z - other.z;
      return dst;
    };

    Vec3.prototype.add = function(other, dst) {
      if (dst == null) {
        dst = this;
      }
      dst.x = this.x + other.x;
      dst.y = this.y + other.y;
      dst.z = this.z + other.z;
      return dst;
    };

    Vec3.prototype.addVal3 = function(x, y, z, dst) {
      if (dst == null) {
        dst = this;
      }
      dst.x = this.x + x;
      dst.y = this.y + y;
      dst.z = this.z + z;
      return dst;
    };

    Vec3.prototype.mul = function(scalar, dst) {
      if (dst == null) {
        dst = this;
      }
      dst.x = this.x * scalar;
      dst.y = this.y * scalar;
      dst.z = this.z * scalar;
      return dst;
    };

    Vec3.prototype.div = function(scalar, dst) {
      if (dst == null) {
        dst = this;
      }
      dst.x = this.x / scalar;
      dst.y = this.y / scalar;
      dst.z = this.z / scalar;
      return dst;
    };

    Vec3.prototype.divVal3 = function(x, y, z, dst) {
      if (dst == null) {
        dst = this;
      }
      dst.x = this.x / x;
      dst.y = this.y / y;
      dst.z = this.z / z;
      return dst;
    };

    Vec3.prototype.dot = function(other) {
      return this.x * other.x + this.y * other.y + this.z * other.z;
    };

    Vec3.prototype.normalize = function(dst) {
      var l;
      if (dst == null) {
        dst = this;
      }
      l = this.length;
      if (l > 0) {
        this.mul(1 / this.length, dst);
      }
      return dst;
    };

    Vec3.prototype.set = function(x, y, z) {
      this.x = x;
      this.y = y;
      this.z = z;
      return this;
    };

    return Vec3;

  })();

  window.Vec4 = Vec4 = (function() {

    Vec4.property('x', {
      get: function() {
        return this.data[0];
      },
      set: function(val) {
        return this.data[0] = val;
      }
    });

    Vec4.property('y', {
      get: function() {
        return this.data[1];
      },
      set: function(val) {
        return this.data[1] = val;
      }
    });

    Vec4.property('z', {
      get: function() {
        return this.data[2];
      },
      set: function(val) {
        return this.data[2] = val;
      }
    });

    Vec4.property('w', {
      get: function() {
        return this.data[3];
      },
      set: function(val) {
        return this.data[3] = val;
      }
    });

    function Vec4(data) {
      var _ref;
      this.data = data;
      if ((_ref = this.data) == null) {
        this.data = new Float32Array(4);
      }
    }

    Vec4.prototype.sub = function(other, dst) {
      if (dst == null) {
        dst = this;
      }
      dst.x = this.x - other.x;
      dst.y = this.y - other.y;
      dst.z = this.z - other.z;
      dst.w = this.w - other.w;
      return dst;
    };

    Vec4.prototype.dot = function(other) {
      return this.x * other.x + this.y * other.y + this.z * other.z + this.w * other.w;
    };

    Vec4.prototype.toVec3 = function(dst) {
      if (dst == null) {
        dst = new Vec3();
      }
      dst.x = this.x;
      dst.y = this.y;
      dst.z = this.z;
      return dst;
    };

    return Vec4;

  })();

}).call(this);


================================================
FILE: lib/audio.coffee
================================================
class Backend
    constructor: ->
        @loading = 0
        @handlers = []
    
    loaded: ->
        if @loading == 0
            for handler in @handlers
                if handler.event == 'loaded' then handler.callback.apply(handler)
        return

    bind: (event, callback) ->
        handler =
            event: event
            callback: callback
        @handlers.push handler
        return handler

    unbind: (handler) ->
        index = @handlers.indexOf handler
        if index >= 0 then @handlers.splice index, 1

class HTMLAudio extends Backend
    @available = (
        (window.Audio != undefined) and
        (window.URL != undefined) and
        (window.BlobBuilder != undefined)
    )

    class Sample
        constructor: (@backend, data) ->
            @backend.loading += 1
            @url = blob.pack data, 'audio/ogg'
        
        play: (looping) ->
            voice = @backend.getFree()
            voice.play(@url, looping) if voice

    class Voice
        constructor: (backend, @id) ->
            self = @
            @audio = new Audio()
            @audio.onended = ->
                backend.ended(self)

        play: (url) ->
            @audio.src = url
            @audio.play()

    constructor: ->
        @free = {}
        @playing = {}

        for id in [0...20]
            @free[id] = new Voice(@, id)

        setInterval @check, 100

    check: =>
        #for id, voice of @playing
            #console.log voice.audio.duration

    getFree: ->
        for id, voice of @free
            delete @free[id]
            @playing[id] = voice
            return voice

    ended: (voice) ->
        @free[voice.id] = voice
        delete @playing[voice.id]
    
    createSample: (data) ->
        @start_time = gettime()
        return new Sample @, data

class WebAudio extends Backend
    @available = window.webkitAudioContext != undefined
    
    constructor: ->
        super()
        @ctx = new webkitAudioContext()

    play: (buffer, looping=false) ->
        source = @ctx.createBufferSource()
        source.buffer = buffer
        source.loop = looping
        source.connect(@ctx.destination)
        source.noteOn(@ctx.currentTime)
   
    decode: (data, callback) ->
        @ctx.decodeAudioData data, (buffer) ->
            callback(buffer)

if WebAudio.available
    backend = new WebAudio()

    exports.decode = (data, callback) ->
        backend.decode data, callback

    exports.play = (buffer) ->
        backend.play buffer
else
    exports.decode = (data, callback) ->
    exports.play = (buffer) ->


================================================
FILE: lib/audio.js
================================================
// Generated by CoffeeScript 1.3.3
var Backend, HTMLAudio, WebAudio, backend,
  __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
  __hasProp = {}.hasOwnProperty,
  __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };

Backend = (function() {

  function Backend() {
    this.loading = 0;
    this.handlers = [];
  }

  Backend.prototype.loaded = function() {
    var handler, _i, _len, _ref;
    if (this.loading === 0) {
      _ref = this.handlers;
      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
        handler = _ref[_i];
        if (handler.event === 'loaded') {
          handler.callback.apply(handler);
        }
      }
    }
  };

  Backend.prototype.bind = function(event, callback) {
    var handler;
    handler = {
      event: event,
      callback: callback
    };
    this.handlers.push(handler);
    return handler;
  };

  Backend.prototype.unbind = function(handler) {
    var index;
    index = this.handlers.indexOf(handler);
    if (index >= 0) {
      return this.handlers.splice(index, 1);
    }
  };

  return Backend;

})();

HTMLAudio = (function(_super) {
  var Sample, Voice;

  __extends(HTMLAudio, _super);

  HTMLAudio.available = (window.Audio !== void 0) && (window.URL !== void 0) && (window.BlobBuilder !== void 0);

  Sample = (function() {

    function Sample(backend, data) {
      this.backend = backend;
      this.backend.loading += 1;
      this.url = blob.pack(data, 'audio/ogg');
    }

    Sample.prototype.play = function(looping) {
      var voice;
      voice = this.backend.getFree();
      if (voice) {
        return voice.play(this.url, looping);
      }
    };

    return Sample;

  })();

  Voice = (function() {

    function Voice(backend, id) {
      var self;
      this.id = id;
      self = this;
      this.audio = new Audio();
      this.audio.onended = function() {
        return backend.ended(self);
      };
    }

    Voice.prototype.play = function(url) {
      this.audio.src = url;
      return this.audio.play();
    };

    return Voice;

  })();

  function HTMLAudio() {
    this.check = __bind(this.check, this);

    var id, _i;
    this.free = {};
    this.playing = {};
    for (id = _i = 0; _i < 20; id = ++_i) {
      this.free[id] = new Voice(this, id);
    }
    setInterval(this.check, 100);
  }

  HTMLAudio.prototype.check = function() {};

  HTMLAudio.prototype.getFree = function() {
    var id, voice, _ref;
    _ref = this.free;
    for (id in _ref) {
      voice = _ref[id];
      delete this.free[id];
      this.playing[id] = voice;
      return voice;
    }
  };

  HTMLAudio.prototype.ended = function(voice) {
    this.free[voice.id] = voice;
    return delete this.playing[voice.id];
  };

  HTMLAudio.prototype.createSample = function(data) {
    this.start_time = gettime();
    return new Sample(this, data);
  };

  return HTMLAudio;

})(Backend);

WebAudio = (function(_super) {

  __extends(WebAudio, _super);

  WebAudio.available = window.webkitAudioContext !== void 0;

  function WebAudio() {
    WebAudio.__super__.constructor.call(this);
    this.ctx = new webkitAudioContext();
  }

  WebAudio.prototype.play = function(buffer, looping) {
    var source;
    if (looping == null) {
      looping = false;
    }
    source = this.ctx.createBufferSource();
    source.buffer = buffer;
    source.loop = looping;
    source.connect(this.ctx.destination);
    return source.noteOn(this.ctx.currentTime);
  };

  WebAudio.prototype.decode = function(data, callback) {
    return this.ctx.decodeAudioData(data, function(buffer) {
      return callback(buffer);
    });
  };

  return WebAudio;

})(Backend);

if (WebAudio.available) {
  backend = new WebAudio();
  exports.decode = function(data, callback) {
    return backend.decode(data, callback);
  };
  exports.play = function(buffer) {
    return backend.play(buffer);
  };
} else {
  exports.decode = function(data, callback) {};
  exports.play = function(buffer) {};
}


================================================
FILE: lib/camera.coffee
================================================
keys = require 'keys'

class MouseDrag
    constructor: (@which) ->
        @x = 0
        @y = 0

        @lx = 0
        @ly = 0
        @pressed = false

        if navigator.appVersion.indexOf('Mac') != -1
            $('#ui').bind 'mousewheel', (event) =>
                event.preventDefault()
                event.stopImmediatePropagation()
                event.stopPropagation()
                
                @x += event.originalEvent.wheelDeltaX*0.25
                @y += event.originalEvent.wheelDeltaY*0.25
                return false

        $('#ui').mousedown (event) =>
            if event.which == @which
                @lx = event.pageX
                @ly = event.pageY
                @pressed = true
            return undefined

        $(document).mouseup =>
            @pressed = false
            return undefined

        $(document).mousemove (event) =>
            if @pressed and event.which == @which
                x = event.pageX
                y = event.pageY
                @x += x - @lx
                @y += y - @ly
                @lx = x
                @ly = y
                return false
            return undefined

    reset: ->
        @x = 0
        @y = 0

class Camera
    constructor: (@delta=1/180, @near=0.1, @far=1000) ->
        @last_gui_update = gettime()
        @time = gettime()
        @proj = new Mat4()
        @inv_proj = new Mat4()
        @view = new Mat4()
        @inv_view = new Mat4()
        @rot = new Mat3()
        @inv_rot = new Mat3()
        @acc = new Vec3()

    aspect: (width, height) ->
        @proj.perspective 75, width/height, @near, @far
        @inv_proj.inversePerspective 75, width/height, @near, @far
    
    step: ->
        @accelerate()
        @limit()
        @move()
        @limit()
        @time += @delta
    
    update: ->
        now = gettime()

        if now - @last_gui_update > 0.5
            @guiUpdate()
            @last_gui_update = now

        if now - @time > @delta*30
            @time = now - @delta*30

        while @time < now
            @step()
        @finish()

        @view.invert @inv_view.identity()
        @view.toMat3 @rot.identity()
        @inv_view.toMat3 @inv_rot.identity()

    limit: ->
    guiUpdate: ->

exports.GameCam = class GameCam extends Camera
    constructor: ({@sl, @sr, delta, x, y, z}={}) ->
        super(delta)
        @realpos = new Vec4()
        @sl ?= 200
        @sr ?= 100
        x ?= 0
        y ?= 0
        z ?= 0

        @mouse = new MouseDrag(3)

        @target_height = 0
        @height = 0

        @x=x; @lx=x
        #@y=y; @ly=y
        @z=z; @lz=z
        @o=0; @lo=0
        @d=0; @ld=0; @ad=0
            
        $(document).bind 'mousewheel', (event) =>
            event.preventDefault()
            event.stopImmediatePropagation()
            event.stopPropagation()
            
            @ad -= event.originalEvent.wheelDeltaY
            return false

    accelerate: ->
        sl = @delta*@delta*@sl
        sr = @delta*@delta*@sr
        
        ctrl_x = if keys.a then -1 else if keys.d then 1 else 0
        ctrl_y = if keys.q then -1 else if keys.e then 1 else 0
        ctrl_z = if keys.w then -1 else if keys.s then 1 else 0

        ax = ctrl_x * sl
        #ay = ctrl_y * sl
        az = ctrl_z * sl
        
        @rot
            .identity()
            .rotatey(-@o)
            .mulVal3(ax, 0, az, @acc)

        @x += @acc.x
        #@y += @acc.y
        @z += @acc.z
        @o += @mouse.x * sr
        @d += @ad * @delta * @delta * 20
       
        move = @delta*@delta*4000
        if move > 1 then move = 1
        @height = @height + (@target_height - @height) * move

    move: ->
        retl = 0.97
        retr = 0.94
        x = @x + (@x - @lx) * retl
        #y = @y + (@y - @ly) * retl
        z = @z + (@z - @lz) * retl
        d = @d + (@d - @ld) * retl
        o = @o + (@o - @lo) * retr

        @lx = @x; @x = x
        #@ly = @y; @y = y
        @lz = @z; @z = z
        @lo = @o; @o = o
        @ld = @d; @d = d


    limit: ->
        if @d < 0 then @d = 0
        else if @d > 30 then @d = 30

        high = 128+64
        low = 128-64
        if @x < low then @x = low
        else if @x > high then @x = high
        
        if @z < low then @z = low
        else if @z > high then @z = high

    finish: ->
        @mouse.reset()
        @ad = 0
        @view
            .identity()
            .translateVal3(0, 0, -@d-5)
            .rotatex(25+(@d/30)*40)
            .rotatey(@o)
            .translateVal3(-@x, -@height, -@z)

    update: (picker) ->
        @view
            .identity()
            .translateVal3(0, 0, -@d-5)
            .rotatex(25+(@d/30)*40)
            .rotatey(@o)
            .translateVal3(-@x, 0, -@z)
        @view.invert @inv_view.identity()

        h1 = picker.getHeight @x, @z
        @inv_view.mulVal4 0, 0, 0, 1, @realpos
        h2 = picker.getHeight(@realpos.x, @realpos.z)+2
        real_height = h1+@realpos.y
        if real_height < h2
            diff = h2 - real_height
            @target_height = h1 + diff
        else
            @target_height = h1

        super()

exports.Orbit = class Orbit extends Camera
    constructor: ({@sr, delta, x, y, z, @dist}={}) ->
        super(delta)
        @sr ?= 100
        @dist ?= 0.6

        @mouse = new MouseDrag(1)

        @o=0; @lo=0
        @p=0; @lp=0
            
    accelerate: ->
        sr = @delta*@delta*@sr
        @o += @mouse.x * sr
        @p += @mouse.y * sr

    move: ->
        retr = 0.94
        o = @o + (@o - @lo) * retr
        p = @p + (@p - @lp) * retr

        @lo = @o; @o = o
        @lp = @p; @p = p

    finish: ->
        @mouse.reset()

    update: () ->
        @view
            .identity()
            .translateVal3(0, 0, -@dist)
            .rotatex(@p)
            .rotatey(@o)
        @view.invert @inv_view.identity()

        super()

exports.FlyCam = class FlyCam extends Camera
    constructor: ({@sl, @gui, @sr, delta, near, far, lookbutton, x, y, z, o, p}={}) ->
        super(delta, near, far)
        @sl ?= 50
        @sr ?= 100
        lookbutton ?= 1
        x ?= 0
        y ?= 0
        z ?= 0
        o ?= 0
        p ?= 0

        @mouse = new MouseDrag(lookbutton)

        @x=x; @lx=x
        @y=y; @ly=y
        @z=z; @lz=z
        @o=o; @lo=o
        @p=p; @lp=p

        folder = @gui.addFolder('Camera')
        @gui.remember @
        @xgui = folder.add(@, 'x', -30.0, 30.0).onChange(@guiChanged)
        @ygui = folder.add(@, 'y', -30.0, 30.0).onChange(@guiChanged)
        @zgui = folder.add(@, 'z', -30.0, 30.0).onChange(@guiChanged)
        @go = @o
        @ogui = folder.add(@, 'go', 0.0, 360.0).name('Orientation').onChange(@guiChanged)
        @pgui = folder.add(@, 'p', -80.0, 80.0).name('Pitch').onChange(@guiChanged)
        @guiChanged()

    guiChanged: =>
        @lx=@x
        @ly=@y
        @lz=@z
        @o=@go; @lo=@go
        @lp=@p

    guiUpdate: ->
        @go = @o % 360
        @xgui.updateDisplay()
        @ygui.updateDisplay()
        @zgui.updateDisplay()
        @ogui.updateDisplay()
        @pgui.updateDisplay()

    accelerate: ->
        sl = @delta*@delta*@sl
        sr = @delta*@delta*@sr
        
        ctrl_x = if keys.a then -1 else if keys.d then 1 else 0
        ctrl_y = if keys.q then -1 else if keys.e then 1 else 0
        ctrl_z = if keys.w then -1 else if keys.s then 1 else 0

        ax = ctrl_x * sl
        ay = ctrl_y * sl
        az = ctrl_z * sl
        
        @rot
            .identity()
            .rotatey(-@o)
            .rotatex(-@p)
            .mulVal3(ax, ay, az, @acc)

        @x += @acc.x
        @y += @acc.y
        @z += @acc.z
        @o += @mouse.x * sr
        @p += @mouse.y * sr

    move: ->
        retl = 0.97
        retr = 0.94
        x = @x + (@x - @lx) * retl
        y = @y + (@y - @ly) * retl
        z = @z + (@z - @lz) * retl
        o = @o + (@o - @lo) * retr
        p = @p + (@p - @lp) * retr

        if p > 80 then p = 80
        else if p < -80 then p = -80

        @lx = @x; @x = x
        @ly = @y; @y = y
        @lz = @z; @z = z
        @lo = @o; @o = o
        @lp = @p; @p = p

    finish: ->
        @mouse.reset()
        @view
            .identity()
            .rotatex(@p)
            .rotatey(@o)
            .translateVal3(-@x, -@y, -@z)


================================================
FILE: lib/camera.js
================================================
// Generated by CoffeeScript 1.3.3
var Camera, FlyCam, GameCam, MouseDrag, Orbit, keys,
  __hasProp = {}.hasOwnProperty,
  __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
  __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };

keys = require('keys');

MouseDrag = (function() {

  function MouseDrag(which) {
    var _this = this;
    this.which = which;
    this.x = 0;
    this.y = 0;
    this.lx = 0;
    this.ly = 0;
    this.pressed = false;
    if (navigator.appVersion.indexOf('Mac') !== -1) {
      $('#ui').bind('mousewheel', function(event) {
        event.preventDefault();
        event.stopImmediatePropagation();
        event.stopPropagation();
        _this.x += event.originalEvent.wheelDeltaX * 0.25;
        _this.y += event.originalEvent.wheelDeltaY * 0.25;
        return false;
      });
    }
    $('#ui').mousedown(function(event) {
      if (event.which === _this.which) {
        _this.lx = event.pageX;
        _this.ly = event.pageY;
        _this.pressed = true;
      }
      return void 0;
    });
    $(document).mouseup(function() {
      _this.pressed = false;
      return void 0;
    });
    $(document).mousemove(function(event) {
      var x, y;
      if (_this.pressed && event.which === _this.which) {
        x = event.pageX;
        y = event.pageY;
        _this.x += x - _this.lx;
        _this.y += y - _this.ly;
        _this.lx = x;
        _this.ly = y;
        return false;
      }
      return void 0;
    });
  }

  MouseDrag.prototype.reset = function() {
    this.x = 0;
    return this.y = 0;
  };

  return MouseDrag;

})();

Camera = (function() {

  function Camera(delta, near, far) {
    this.delta = delta != null ? delta : 1 / 180;
    this.near = near != null ? near : 0.1;
    this.far = far != null ? far : 1000;
    this.last_gui_update = gettime();
    this.time = gettime();
    this.proj = new Mat4();
    this.inv_proj = new Mat4();
    this.view = new Mat4();
    this.inv_view = new Mat4();
    this.rot = new Mat3();
    this.inv_rot = new Mat3();
    this.acc = new Vec3();
  }

  Camera.prototype.aspect = function(width, height) {
    this.proj.perspective(75, width / height, this.near, this.far);
    return this.inv_proj.inversePerspective(75, width / height, this.near, this.far);
  };

  Camera.prototype.step = function() {
    this.accelerate();
    this.limit();
    this.move();
    this.limit();
    return this.time += this.delta;
  };

  Camera.prototype.update = function() {
    var now;
    now = gettime();
    if (now - this.last_gui_update > 0.5) {
      this.guiUpdate();
      this.last_gui_update = now;
    }
    if (now - this.time > this.delta * 30) {
      this.time = now - this.delta * 30;
    }
    while (this.time < now) {
      this.step();
    }
    this.finish();
    this.view.invert(this.inv_view.identity());
    this.view.toMat3(this.rot.identity());
    return this.inv_view.toMat3(this.inv_rot.identity());
  };

  Camera.prototype.limit = function() {};

  Camera.prototype.guiUpdate = function() {};

  return Camera;

})();

exports.GameCam = GameCam = (function(_super) {

  __extends(GameCam, _super);

  function GameCam(_arg) {
    var delta, x, y, z, _ref, _ref1, _ref2,
      _this = this;
    _ref = _arg != null ? _arg : {}, this.sl = _ref.sl, this.sr = _ref.sr, delta = _ref.delta, x = _ref.x, y = _ref.y, z = _ref.z;
    GameCam.__super__.constructor.call(this, delta);
    this.realpos = new Vec4();
    if ((_ref1 = this.sl) == null) {
      this.sl = 200;
    }
    if ((_ref2 = this.sr) == null) {
      this.sr = 100;
    }
    if (x == null) {
      x = 0;
    }
    if (y == null) {
      y = 0;
    }
    if (z == null) {
      z = 0;
    }
    this.mouse = new MouseDrag(3);
    this.target_height = 0;
    this.height = 0;
    this.x = x;
    this.lx = x;
    this.z = z;
    this.lz = z;
    this.o = 0;
    this.lo = 0;
    this.d = 0;
    this.ld = 0;
    this.ad = 0;
    $(document).bind('mousewheel', function(event) {
      event.preventDefault();
      event.stopImmediatePropagation();
      event.stopPropagation();
      _this.ad -= event.originalEvent.wheelDeltaY;
      return false;
    });
  }

  GameCam.prototype.accelerate = function() {
    var ax, az, ctrl_x, ctrl_y, ctrl_z, move, sl, sr;
    sl = this.delta * this.delta * this.sl;
    sr = this.delta * this.delta * this.sr;
    ctrl_x = keys.a ? -1 : keys.d ? 1 : 0;
    ctrl_y = keys.q ? -1 : keys.e ? 1 : 0;
    ctrl_z = keys.w ? -1 : keys.s ? 1 : 0;
    ax = ctrl_x * sl;
    az = ctrl_z * sl;
    this.rot.identity().rotatey(-this.o).mulVal3(ax, 0, az, this.acc);
    this.x += this.acc.x;
    this.z += this.acc.z;
    this.o += this.mouse.x * sr;
    this.d += this.ad * this.delta * this.delta * 20;
    move = this.delta * this.delta * 4000;
    if (move > 1) {
      move = 1;
    }
    return this.height = this.height + (this.target_height - this.height) * move;
  };

  GameCam.prototype.move = function() {
    var d, o, retl, retr, x, z;
    retl = 0.97;
    retr = 0.94;
    x = this.x + (this.x - this.lx) * retl;
    z = this.z + (this.z - this.lz) * retl;
    d = this.d + (this.d - this.ld) * retl;
    o = this.o + (this.o - this.lo) * retr;
    this.lx = this.x;
    this.x = x;
    this.lz = this.z;
    this.z = z;
    this.lo = this.o;
    this.o = o;
    this.ld = this.d;
    return this.d = d;
  };

  GameCam.prototype.limit = function() {
    var high, low;
    if (this.d < 0) {
      this.d = 0;
    } else if (this.d > 30) {
      this.d = 30;
    }
    high = 128 + 64;
    low = 128 - 64;
    if (this.x < low) {
      this.x = low;
    } else if (this.x > high) {
      this.x = high;
    }
    if (this.z < low) {
      return this.z = low;
    } else if (this.z > high) {
      return this.z = high;
    }
  };

  GameCam.prototype.finish = function() {
    this.mouse.reset();
    this.ad = 0;
    return this.view.identity().translateVal3(0, 0, -this.d - 5).rotatex(25 + (this.d / 30) * 40).rotatey(this.o).translateVal3(-this.x, -this.height, -this.z);
  };

  GameCam.prototype.update = function(picker) {
    var diff, h1, h2, real_height;
    this.view.identity().translateVal3(0, 0, -this.d - 5).rotatex(25 + (this.d / 30) * 40).rotatey(this.o).translateVal3(-this.x, 0, -this.z);
    this.view.invert(this.inv_view.identity());
    h1 = picker.getHeight(this.x, this.z);
    this.inv_view.mulVal4(0, 0, 0, 1, this.realpos);
    h2 = picker.getHeight(this.realpos.x, this.realpos.z) + 2;
    real_height = h1 + this.realpos.y;
    if (real_height < h2) {
      diff = h2 - real_height;
      this.target_height = h1 + diff;
    } else {
      this.target_height = h1;
    }
    return GameCam.__super__.update.call(this);
  };

  return GameCam;

})(Camera);

exports.Orbit = Orbit = (function(_super) {

  __extends(Orbit, _super);

  function Orbit(_arg) {
    var delta, x, y, z, _ref, _ref1, _ref2;
    _ref = _arg != null ? _arg : {}, this.sr = _ref.sr, delta = _ref.delta, x = _ref.x, y = _ref.y, z = _ref.z, this.dist = _ref.dist;
    Orbit.__super__.constructor.call(this, delta);
    if ((_ref1 = this.sr) == null) {
      this.sr = 100;
    }
    if ((_ref2 = this.dist) == null) {
      this.dist = 0.6;
    }
    this.mouse = new MouseDrag(1);
    this.o = 0;
    this.lo = 0;
    this.p = 0;
    this.lp = 0;
  }

  Orbit.prototype.accelerate = function() {
    var sr;
    sr = this.delta * this.delta * this.sr;
    this.o += this.mouse.x * sr;
    return this.p += this.mouse.y * sr;
  };

  Orbit.prototype.move = function() {
    var o, p, retr;
    retr = 0.94;
    o = this.o + (this.o - this.lo) * retr;
    p = this.p + (this.p - this.lp) * retr;
    this.lo = this.o;
    this.o = o;
    this.lp = this.p;
    return this.p = p;
  };

  Orbit.prototype.finish = function() {
    return this.mouse.reset();
  };

  Orbit.prototype.update = function() {
    this.view.identity().translateVal3(0, 0, -this.dist).rotatex(this.p).rotatey(this.o);
    this.view.invert(this.inv_view.identity());
    return Orbit.__super__.update.call(this);
  };

  return Orbit;

})(Camera);

exports.FlyCam = FlyCam = (function(_super) {

  __extends(FlyCam, _super);

  function FlyCam(_arg) {
    var delta, far, folder, lookbutton, near, o, p, x, y, z, _ref, _ref1, _ref2;
    _ref = _arg != null ? _arg : {}, this.sl = _ref.sl, this.gui = _ref.gui, this.sr = _ref.sr, delta = _ref.delta, near = _ref.near, far = _ref.far, lookbutton = _ref.lookbutton, x = _ref.x, y = _ref.y, z = _ref.z, o = _ref.o, p = _ref.p;
    this.guiChanged = __bind(this.guiChanged, this);

    FlyCam.__super__.constructor.call(this, delta, near, far);
    if ((_ref1 = this.sl) == null) {
      this.sl = 50;
    }
    if ((_ref2 = this.sr) == null) {
      this.sr = 100;
    }
    if (lookbutton == null) {
      lookbutton = 1;
    }
    if (x == null) {
      x = 0;
    }
    if (y == null) {
      y = 0;
    }
    if (z == null) {
      z = 0;
    }
    if (o == null) {
      o = 0;
    }
    if (p == null) {
      p = 0;
    }
    this.mouse = new MouseDrag(lookbutton);
    this.x = x;
    this.lx = x;
    this.y = y;
    this.ly = y;
    this.z = z;
    this.lz = z;
    this.o = o;
    this.lo = o;
    this.p = p;
    this.lp = p;
    folder = this.gui.addFolder('Camera');
    this.gui.remember(this);
    this.xgui = folder.add(this, 'x', -30.0, 30.0).onChange(this.guiChanged);
    this.ygui = folder.add(this, 'y', -30.0, 30.0).onChange(this.guiChanged);
    this.zgui = folder.add(this, 'z', -30.0, 30.0).onChange(this.guiChanged);
    this.go = this.o;
    this.ogui = folder.add(this, 'go', 0.0, 360.0).name('Orientation').onChange(this.guiChanged);
    this.pgui = folder.add(this, 'p', -80.0, 80.0).name('Pitch').onChange(this.guiChanged);
    this.guiChanged();
  }

  FlyCam.prototype.guiChanged = function() {
    this.lx = this.x;
    this.ly = this.y;
    this.lz = this.z;
    this.o = this.go;
    this.lo = this.go;
    return this.lp = this.p;
  };

  FlyCam.prototype.guiUpdate = function() {
    this.go = this.o % 360;
    this.xgui.updateDisplay();
    this.ygui.updateDisplay();
    this.zgui.updateDisplay();
    this.ogui.updateDisplay();
    return this.pgui.updateDisplay();
  };

  FlyCam.prototype.accelerate = function() {
    var ax, ay, az, ctrl_x, ctrl_y, ctrl_z, sl, sr;
    sl = this.delta * this.delta * this.sl;
    sr = this.delta * this.delta * this.sr;
    ctrl_x = keys.a ? -1 : keys.d ? 1 : 0;
    ctrl_y = keys.q ? -1 : keys.e ? 1 : 0;
    ctrl_z = keys.w ? -1 : keys.s ? 1 : 0;
    ax = ctrl_x * sl;
    ay = ctrl_y * sl;
    az = ctrl_z * sl;
    this.rot.identity().rotatey(-this.o).rotatex(-this.p).mulVal3(ax, ay, az, this.acc);
    this.x += this.acc.x;
    this.y += this.acc.y;
    this.z += this.acc.z;
    this.o += this.mouse.x * sr;
    return this.p += this.mouse.y * sr;
  };

  FlyCam.prototype.move = function() {
    var o, p, retl, retr, x, y, z;
    retl = 0.97;
    retr = 0.94;
    x = this.x + (this.x - this.lx) * retl;
    y = this.y + (this.y - this.ly) * retl;
    z = this.z + (this.z - this.lz) * retl;
    o = this.o + (this.o - this.lo) * retr;
    p = this.p + (this.p - this.lp) * retr;
    if (p > 80) {
      p = 80;
    } else if (p < -80) {
      p = -80;
    }
    this.lx = this.x;
    this.x = x;
    this.ly = this.y;
    this.y = y;
    this.lz = this.z;
    this.z = z;
    this.lo = this.o;
    this.o = o;
    this.lp = this.p;
    return this.p = p;
  };

  FlyCam.prototype.finish = function() {
    this.mouse.reset();
    return this.view.identity().rotatex(this.p).rotatey(this.o).translateVal3(-this.x, -this.y, -this.z);
  };

  return FlyCam;

})(Camera);


================================================
FILE: lib/events.coffee
================================================
return class Emitter
    constructor: ->
        @handlers = {}

    on: (name, callback) ->
        handlers = @handlers[name]
        if handlers == undefined
            handlers = @handlers[name] = []
        handlers.push callback
        return @

    trigger: (name, a1, a2, a3, a4, a5, a6) ->
        handlers = @handlers[name]
        if handlers != undefined
            for handler in handlers
                handler(a1, a2, a3, a4, a5, a6)
        return @



================================================
FILE: lib/events.js
================================================
// Generated by CoffeeScript 1.3.3
var Emitter;

return Emitter = (function() {

  function Emitter() {
    this.handlers = {};
  }

  Emitter.prototype.on = function(name, callback) {
    var handlers;
    handlers = this.handlers[name];
    if (handlers === void 0) {
      handlers = this.handlers[name] = [];
    }
    handlers.push(callback);
    return this;
  };

  Emitter.prototype.trigger = function(name, a1, a2, a3, a4, a5, a6) {
    var handler, handlers, _i, _len;
    handlers = this.handlers[name];
    if (handlers !== void 0) {
      for (_i = 0, _len = handlers.length; _i < _len; _i++) {
        handler = handlers[_i];
        handler(a1, a2, a3, a4, a5, a6);
      }
    }
    return this;
  };

  return Emitter;

})();


================================================
FILE: lib/geometry.js
================================================
// Generated by CoffeeScript 1.3.3

exports.AABB = (function() {

  function AABB(xmin, xmax, ymin, ymax, zmin, zmax) {
    this.xmin = xmin;
    this.xmax = xmax;
    this.ymin = ymin;
    this.ymax = ymax;
    this.zmin = zmin;
    this.zmax = zmax;
  }

  AABB.prototype.ray_intersect = function(ray) {
    var d, inv_x, inv_y, inv_z, o, tmax, tmin, ymax, ymin, zmax, zmin, _ref, _ref1, _ref2;
    o = ray.origin;
    d = ray.direction;
    inv_x = 1.0 / d.x;
    tmin = (this.xmin - o.x) * inv_x;
    tmax = (this.xmax - o.x) * inv_x;
    if (inv_x < 0) {
      _ref = [tmax, tmin], tmin = _ref[0], tmax = _ref[1];
    }
    inv_y = 1.0 / d.y;
    ymin = (this.ymin - o.y) * inv_y;
    ymax = (this.ymax - o.y) * inv_y;
    if (inv_y < 0) {
      _ref1 = [ymax, ymin], ymin = _ref1[0], ymax = _ref1[1];
    }
    if (tmin > ymax || ymin > tmax) {
      return null;
    }
    if (ymin > tmin) {
      tmin = ymin;
    }
    if (ymax < tmax) {
      tmax = ymax;
    }
    inv_z = 1.0 / d.z;
    zmin = (this.zmin - o.z) * inv_z;
    zmax = (this.zmax - o.z) * inv_z;
    if (inv_z < 0) {
      _ref2 = [zmax, zmin], zmin = _ref2[0], zmax = _ref2[1];
    }
    if (tmin > zmax || zmin > tmax) {
      return null;
    }
    if (zmin > tmin) {
      tmin = zmin;
    }
    if (zmax < tmax) {
      tmax = zmax;
    }
    return [tmin, tmax];
  };

  return AABB;

})();

exports.Ray = (function() {

  function Ray(origin, direction) {
    var _ref, _ref1;
    this.origin = origin;
    this.direction = direction;
    if ((_ref = this.origin) == null) {
      this.origin = new Vec4();
    }
    if ((_ref1 = this.direction) == null) {
      this.direction = new Vec4();
    }
  }

  Ray.prototype.interpolate = function(interval, vector) {
    var d, o, v;
    if (vector == null) {
      vector = new Vec4();
    }
    o = this.origin;
    d = this.direction;
    v = vector;
    v.x = o.x + d.x * interval;
    v.y = o.y + d.y * interval;
    v.z = o.z + d.z * interval;
    v.w = o.w + d.w * interval;
    return vector;
  };

  Ray.prototype.ray_nearest = function(ray) {
    var U, V, W, a, b, c, d, det, e, s, t;
    W = this.origin.sub(ray.origin, new Vec4);
    U = this.direction;
    V = ray.direction;
    a = U.dot(U);
    b = U.dot(V);
    c = V.dot(V);
    d = U.dot(W);
    e = V.dot(W);
    det = a * c - b * b;
    if (det === 0) {
      return null;
    }
    s = (b * e - c * d) / det;
    t = (a * e - b * d) / det;
    return [s, t];
  };

  Ray.prototype.point_distance = function(point) {
    var W, s;
    W = point.sub(this.origin, new Vec4);
    s = W.dot(this.direction) / this.direction.dot(this.direction);
    W.x -= this.direction.x * s;
    W.y -= this.direction.y * s;
    W.z -= this.direction.z * s;
    return Math.sqrt(W.dot(W));
  };

  return Ray;

})();

exports.get_mouseray = function(x, y, inv_proj, inv_view, ray) {
  if (ray == null) {
    ray = new exports.Ray;
  }
  inv_proj.mulVal4(x, y, -1, 1, ray.direction);
  inv_view.mulVec3(ray.direction);
  ray.direction.w = 0;
  inv_view.mulVal4(0, 0, 0, 1, ray.origin);
  return ray;
};


================================================
FILE: lib/hdr_clear.shader
================================================
vertex:
    attribute vec2 position;
    void main(){
        gl_Position = vec4(position, 0.0, 1.0);
    }

fragment:
    uniform vec4 clear_color;
    void main(){
        gl_FragColor = clear_color;
    }


================================================
FILE: lib/keys.coffee
================================================
keymap = ({
    87: 'w',
    65: 'a',
    83: 's',
    68: 'd',
    81: 'q',
    69: 'e',
    37: 'left',
    39: 'right',
    38: 'up',
    40: 'down',
    13: 'enter',
    27: 'esc',
    32: 'space',
    8: 'backspace',
    16: 'shift',
    17: 'ctrl',
    18: 'alt',
    91: 'start',
    0: 'altc',
    20: 'caps',
    9: 'tab',
    49: 'key1',
    50: 'key2',
    51: 'key3',
    52: 'key4'
})

key_handlers = {}

keys = {
    press: (name, callback) ->
        handlers = key_handlers[name] = key_handlers[name] or []
        handlers.push(callback)
}

$(document).keydown (event) ->
    if event.target == document.body
        name = keymap[event.which]
        keys[name] = true
        handlers = key_handlers[name]
        if handlers
            for handler in handlers
                handler()

$(document).keyup (event) ->
    name = keymap[event.which]
    keys[name] = false

return keys


================================================
FILE: lib/keys.js
================================================
// Generated by CoffeeScript 1.3.3
var key_handlers, keymap, keys;

keymap = {
  87: 'w',
  65: 'a',
  83: 's',
  68: 'd',
  81: 'q',
  69: 'e',
  37: 'left',
  39: 'right',
  38: 'up',
  40: 'down',
  13: 'enter',
  27: 'esc',
  32: 'space',
  8: 'backspace',
  16: 'shift',
  17: 'ctrl',
  18: 'alt',
  91: 'start',
  0: 'altc',
  20: 'caps',
  9: 'tab',
  49: 'key1',
  50: 'key2',
  51: 'key3',
  52: 'key4'
};

key_handlers = {};

keys = {
  press: function(name, callback) {
    var handlers;
    handlers = key_handlers[name] = key_handlers[name] || [];
    return handlers.push(callback);
  }
};

$(document).keydown(function(event) {
  var handler, handlers, name, _i, _len, _results;
  if (event.target === document.body) {
    name = keymap[event.which];
    keys[name] = true;
    handlers = key_handlers[name];
    if (handlers) {
      _results = [];
      for (_i = 0, _len = handlers.length; _i < _len; _i++) {
        handler = handlers[_i];
        _results.push(handler());
      }
      return _results;
    }
  }
});

$(document).keyup(function(event) {
  var name;
  name = keymap[event.which];
  return keys[name] = false;
});

return keys;


================================================
FILE: lib/loading.coffee
================================================
ui = $('#ui')
hidden = true

container = $('<div></div>').css
    position: 'absolute'
    top: '50%'
    left: '50%'
    width: 200
    height: 40
    marginLeft: -100
    marginTop: -20

label = $('<div></div>').appendTo(container).css
    position: 'absolute'
    top: 0
    left: 0
    width: 200
    height: 20
    textAlign: 'center'
    color: 'white'

loading = $('<div></div>').appendTo(container).css
    position: 'absolute'
    top: 20
    left: 0
    width: 200
    height: 20
    border: '1px solid white'

bar = null
makeBar = ->
    loading.empty()
    bar = $('<div></div>').appendTo(loading).css
        position: 'absolute'
        top: 0
        left: 0
        width: 0
        height: 20
        backgroundColor: 'white'
        '-webkit-transition': 'width 0.7s'

exports.show = (text) ->
    label.text text
    makeBar()
    container
        .fadeIn('slow')
        .appendTo(ui)

exports.hide = ->
    container.fadeOut 'slow', ->
        container.detach()

exports.progress = (factor) ->
    bar.width(factor*200)


================================================
FILE: lib/loading.js
================================================
// Generated by CoffeeScript 1.3.3
var bar, container, hidden, label, loading, makeBar, ui;

ui = $('#ui');

hidden = true;

container = $('<div></div>').css({
  position: 'absolute',
  top: '50%',
  left: '50%',
  width: 200,
  height: 40,
  marginLeft: -100,
  marginTop: -20
});

label = $('<div></div>').appendTo(container).css({
  position: 'absolute',
  top: 0,
  left: 0,
  width: 200,
  height: 20,
  textAlign: 'center',
  color: 'white'
});

loading = $('<div></div>').appendTo(container).css({
  position: 'absolute',
  top: 20,
  left: 0,
  width: 200,
  height: 20,
  border: '1px solid white'
});

bar = null;

makeBar = function() {
  loading.empty();
  return bar = $('<div></div>').appendTo(loading).css({
    position: 'absolute',
    top: 0,
    left: 0,
    width: 0,
    height: 20,
    backgroundColor: 'white',
    '-webkit-transition': 'width 0.7s'
  });
};

exports.show = funct
Download .txt
gitextract_c0t50r9u/

├── README.md
├── build
├── build.sh
├── compile
├── extra/
│   ├── Stats.js
│   ├── jquery.js
│   ├── loader.coffee
│   ├── loader.js
│   ├── matrix.coffee
│   ├── matrix.js
│   ├── shims.coffee
│   ├── shims.js
│   ├── vector.coffee
│   └── vector.js
├── lib/
│   ├── audio.coffee
│   ├── audio.js
│   ├── camera.coffee
│   ├── camera.js
│   ├── events.coffee
│   ├── events.js
│   ├── geometry.js
│   ├── hdr_clear.shader
│   ├── keys.coffee
│   ├── keys.js
│   ├── loading.coffee
│   ├── loading.js
│   ├── rendernode.coffee
│   ├── rendernode.js
│   ├── schedule.coffee
│   ├── schedule.js
│   ├── webgl/
│   │   ├── cube.coffee
│   │   ├── cube.js
│   │   ├── drawable.coffee
│   │   ├── drawable.js
│   │   ├── framebuffer.coffee
│   │   ├── framebuffer.js
│   │   ├── hexgrid.coffee
│   │   ├── hexgrid.js
│   │   ├── model.coffee
│   │   ├── model.js
│   │   ├── plane.coffee
│   │   ├── plane.js
│   │   ├── quad.coffee
│   │   ├── quad.js
│   │   ├── shader.coffee
│   │   ├── shader.js
│   │   ├── sphere.coffee
│   │   ├── sphere.js
│   │   ├── texture.coffee
│   │   └── texture.js
│   ├── webgl-nuke-vendor-prefix.coffee
│   ├── webgl-nuke-vendor-prefix.js
│   ├── webgl-texture-float-extension-shims.coffee
│   └── webgl-texture-float-extension-shims.js
├── license/
│   ├── bsd-license
│   ├── gplv2-license
│   ├── gplv3-license
│   ├── mit-license
│   └── readme
├── pack
├── src/
│   ├── albedo.shader
│   ├── antialias/
│   │   ├── fxaa2_0.shader
│   │   ├── fxaa3_11.shader
│   │   ├── fxaa3_11.shaderlib
│   │   ├── fxaa3_11_preprocessed.shaderlib
│   │   ├── fxaa3_11_stripped.shaderlib
│   │   ├── module.coffee
│   │   └── module.js
│   ├── application.coffee
│   ├── application.js
│   ├── blur/
│   │   ├── blur.shader
│   │   ├── module.coffee
│   │   └── module.js
│   ├── composit.shader
│   ├── deferred_model.coffee
│   ├── deferred_model.js
│   ├── depth/
│   │   ├── deferred_shadow_map.shader
│   │   ├── depth.shader
│   │   ├── lightmap_shadow_map.shader
│   │   ├── module.coffee
│   │   ├── module.js
│   │   └── variance.shaderlib
│   ├── direct_illumination.shader
│   ├── dist3d.coffee
│   ├── dist3d.js
│   ├── global_illumination.shader
│   ├── harmonics.shaderlib
│   ├── illumination/
│   │   ├── bounce.shader
│   │   ├── bounce_model.coffee
│   │   ├── bounce_model.js
│   │   ├── cube_diffuse.shader
│   │   ├── cubeprobe.shader
│   │   ├── debug.shader
│   │   ├── harmonics.shader
│   │   ├── module.coffee
│   │   ├── module.js
│   │   ├── shadow.shader
│   │   └── transfer.shader
│   ├── main.coffee
│   ├── main.js
│   ├── model/
│   │   ├── lowres.vertices
│   │   ├── materials.json
│   │   ├── module.coffee
│   │   ├── module.js
│   │   ├── sponza.indices
│   │   └── sponza.vertices
│   ├── normaldepth.shader
│   ├── presets/
│   │   ├── default.json
│   │   └── new.json
│   ├── ssao/
│   │   ├── module.coffee
│   │   ├── module.js
│   │   ├── moments.shader
│   │   └── ssao.shader
│   ├── sun.coffee
│   ├── sun.js
│   └── windows/
│       ├── module.coffee
│       ├── module.js
│       └── window.shader
└── www/
    ├── assets.pack
    ├── code.js
    └── index.html
Download .txt
SYMBOL INDEX (250 symbols across 30 files)

FILE: extra/jquery.js
  function cy (line 2) | function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.pa...
  function cu (line 2) | function cu(a){if(!cj[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.cs...
  function ct (line 2) | function ct(a,b){var c={};f.each(cp.concat.apply([],cp.slice(0,b)),funct...
  function cs (line 2) | function cs(){cq=b}
  function cr (line 2) | function cr(){setTimeout(cs,0);return cq=f.now()}
  function ci (line 2) | function ci(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(...
  function ch (line 2) | function ch(){try{return new a.XMLHttpRequest}catch(b){}}
  function cb (line 2) | function cb(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.da...
  function ca (line 2) | function ca(a,c,d){var e=a.contents,f=a.dataTypes,g=a.responseFields,h,i...
  function b_ (line 2) | function b_(a,b,c,d){if(f.isArray(b))f.each(b,function(b,e){c||bD.test(a...
  function b$ (line 2) | function b$(a,c){var d,e,g=f.ajaxSettings.flatOptions||{};for(d in c)c[d...
  function bZ (line 2) | function bZ(a,c,d,e,f,g){f=f||c.dataTypes[0],g=g||{},g[f]=!0;var h=a[f],...
  function bY (line 2) | function bY(a){return function(b,c){typeof b!="string"&&(c=b,b="*");if(f...
  function bB (line 2) | function bB(a,b,c){var d=b==="width"?a.offsetWidth:a.offsetHeight,e=b===...
  function bo (line 2) | function bo(a){var b=c.createElement("div");bh.appendChild(b),b.innerHTM...
  function bn (line 2) | function bn(a){var b=(a.nodeName||"").toLowerCase();b==="input"?bm(a):b!...
  function bm (line 2) | function bm(a){if(a.type==="checkbox"||a.type==="radio")a.defaultChecked...
  function bl (line 2) | function bl(a){return typeof a.getElementsByTagName!="undefined"?a.getEl...
  function bk (line 2) | function bk(a,b){var c;b.nodeType===1&&(b.clearAttributes&&b.clearAttrib...
  function bj (line 2) | function bj(a,b){if(b.nodeType===1&&!!f.hasData(a)){var c,d,e,g=f._data(...
  function bi (line 2) | function bi(a,b){return f.nodeName(a,"table")?a.getElementsByTagName("tb...
  function U (line 2) | function U(a){var b=V.split("|"),c=a.createDocumentFragment();if(c.creat...
  function T (line 2) | function T(a,b,c){b=b||0;if(f.isFunction(b))return f.grep(a,function(a,d...
  function S (line 2) | function S(a){return!a||!a.parentNode||a.parentNode.nodeType===11}
  function K (line 2) | function K(){return!0}
  function J (line 2) | function J(){return!1}
  function n (line 2) | function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);...
  function m (line 2) | function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))conti...
  function l (line 2) | function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-...
  function h (line 2) | function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c<d;...
  function J (line 2) | function J(){if(!e.isReady){try{c.documentElement.doScroll("left")}catch...
  function a (line 2) | function a(b,c){return new a.fn.init(b,c)}
  function m (line 2) | function m(a){return function(b){e[a]=arguments.length>1?i.call(argument...
  function l (line 2) | function l(a){return function(c){b[a]=arguments.length>1?i.call(argument...
  function m (line 2) | function m(){--h||d.resolveWith(e,[e])}
  function x (line 3) | function x(a,b,c,e,f,g){for(var h=0,i=e.length;h<i;h++){var j=e[h];if(j)...
  function w (line 3) | function w(a,b,c,e,f,g){for(var h=0,i=e.length;h<i;h++){var j=e[h];if(j)...
  function w (line 4) | function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.ready...
  function g (line 4) | function g(){e.queue===!1&&f._mark(this);var b=f.extend({},e),c=this.nod...
  function h (line 4) | function h(a,b,c){var e=b[c];f.removeData(a,c,!0),e.stop(d)}
  function h (line 4) | function h(a){return e.step(a)}

FILE: extra/matrix.js
  function Mat3 (line 15) | function Mat3(data) {
  function Mat4 (line 129) | function Mat4(data) {

FILE: extra/vector.js
  function Vec3 (line 40) | function Vec3(data) {
  function Vec4 (line 173) | function Vec4(data) {

FILE: lib/audio.js
  function ctor (line 5) | function ctor() { this.constructor = child; }
  function Backend (line 9) | function Backend() {
  function Sample (line 58) | function Sample(backend, data) {
  function Voice (line 78) | function Voice(backend, id) {
  function HTMLAudio (line 97) | function HTMLAudio() {
  function WebAudio (line 142) | function WebAudio() {

FILE: lib/camera.js
  function ctor (line 4) | function ctor() { this.constructor = child; }
  function MouseDrag (line 11) | function MouseDrag(which) {
  function Camera (line 67) | function Camera(delta, near, far) {
  function GameCam (line 126) | function GameCam(_arg) {
  function Orbit (line 259) | function Orbit(_arg) {
  function FlyCam (line 312) | function FlyCam(_arg) {

FILE: lib/events.js
  function Emitter (line 6) | function Emitter() {

FILE: lib/geometry.js
  function AABB (line 5) | function AABB(xmin, xmax, ymin, ymax, zmin, zmax) {
  function Ray (line 63) | function Ray(origin, direction) {

FILE: lib/rendernode.js
  function State (line 12) | function State(gl) {
  function Rendernode (line 93) | function Rendernode(gl, _arg) {

FILE: lib/webgl/cube.js
  function ctor (line 4) | function ctor() { this.constructor = child; }
  function Cube (line 31) | function Cube(gl, s) {

FILE: lib/webgl/drawable.js
  function Drawable (line 9) | function Drawable() {

FILE: lib/webgl/framebuffer.js
  function ctor (line 4) | function ctor() { this.constructor = child; }
  function Framebuffer (line 10) | function Framebuffer(gl) {
  function Renderbuffer (line 75) | function Renderbuffer(gl) {
  function _Class (line 106) | function _Class() {

FILE: lib/webgl/hexgrid.js
  function ctor (line 4) | function ctor() { this.constructor = child; }
  function Hexgrid (line 22) | function Hexgrid(gl, xsize, ysize, width, height) {

FILE: lib/webgl/model.js
  function ctor (line 4) | function ctor() { this.constructor = child; }
  function Model (line 12) | function Model(gl, data) {

FILE: lib/webgl/plane.js
  function ctor (line 4) | function ctor() { this.constructor = child; }
  function Plane (line 12) | function Plane(gl, s) {

FILE: lib/webgl/quad.js
  function ctor (line 4) | function ctor() { this.constructor = child; }
  function Quad (line 21) | function Quad(gl) {

FILE: lib/webgl/shader.js
  function Shader (line 29) | function Shader(gl, path, source) {

FILE: lib/webgl/sphere.js
  function ctor (line 4) | function ctor() { this.constructor = child; }
  function Sphere (line 137) | function Sphere(gl, radius, subdivisions) {

FILE: lib/webgl/texture.js
  function ctor (line 4) | function ctor() { this.constructor = child; }
  function Texture (line 15) | function Texture() {
  function Texture2D (line 102) | function Texture2D(gl, _arg) {
  function Cubemap (line 185) | function Cubemap(gl) {

FILE: src/antialias/module.js
  function AntiAlias (line 10) | function AntiAlias(gl, gui, source) {

FILE: src/application.js
  function ctor (line 5) | function ctor() { this.constructor = child; }
  function CompositingControl (line 37) | function CompositingControl(gui) {
  function Lighting (line 59) | function Lighting(gui) {
  function PictureSettings (line 115) | function PictureSettings(gui) {
  function SHConstants (line 135) | function SHConstants(app, gui) {
  function _Class (line 196) | function _Class(canvas) {

FILE: src/blur/module.js
  function Blur (line 8) | function Blur(gl, _arg) {

FILE: src/deferred_model.js
  function ctor (line 4) | function ctor() { this.constructor = child; }
  function DeferredModel (line 28) | function DeferredModel(gl, probes) {

FILE: src/depth/module.js
  function DepthRender (line 10) | function DepthRender(gl, width, height, drawable, _arg) {
  function DeferredShadowMap (line 54) | function DeferredShadowMap(gl, _arg) {
  function LightmappedShadowMap (line 85) | function LightmappedShadowMap(gl, _arg) {

FILE: src/illumination/bounce_model.js
  function ctor (line 4) | function ctor() { this.constructor = child; }
  function BounceModel (line 38) | function BounceModel(gl, model, probes) {

FILE: src/illumination/module.js
  function Illumination (line 18) | function Illumination(gl, sun, lighting, model, highresmodel, normaldept...

FILE: src/model/module.js
  function ctor (line 4) | function ctor() { this.constructor = child; }
  function Materials (line 21) | function Materials(gl) {
  function LowresModel (line 97) | function LowresModel(gl) {
  function Model (line 134) | function Model(gl) {

FILE: src/ssao/module.js
  function SSAO (line 10) | function SSAO(gl, normaldepth) {

FILE: src/sun.js
  function ctor (line 5) | function ctor() { this.constructor = child; }
  function Sun (line 11) | function Sun(gui, orientation, elevation) {

FILE: src/windows/module.js
  function Window (line 13) | function Window(index, texture, node, x, y) {
  function Windows (line 58) | function Windows(gl, gui, textures) {

FILE: www/code.js
  function a (line 24) | function a(b){if(b==="0"||e.isUndefined(b))return 0;b=b.match(d);return!...
  function h (line 34) | function h(){var a=parseFloat(l.__input.value);c.isNaN(a)||l.setValue(a)}
  function j (line 34) | function j(a){var b=o-a.clientY;l.setValue(l.getValue()+b*l.__impliedSte...
  function m (line 34) | function m(){a.unbind(window,"mousemove",j);a.unbind(window,"mouseup",m)}
  function o (line 37) | function o(b){b.preventDefault();var d=a.getOffset(g.__background),c=a.g...
  function y (line 37) | function y(){a.unbind(window,"mousemove",o);a.unbind(window,"mouseup",y)...
  function q (line 50) | function q(a,b,r,c){if(b[r]===void 0)throw Error("Object "+b+' has no pr...
  function s (line 51) | function s(a,b,d){var c=document.createElement("li");b&&c.appendChild(b)...
  function p (line 51) | function p(a,d,c){c.__li=d;c.__gui=a;i.extend(c,{options:function(b){if(...
  function t (line 55) | function t(a,b){var c=a.getRoot(),d=c.__rememberedObjects.indexOf(b.obje...
  function I (line 55) | function I(a){var b=a.__save_row=document.createElement("li");g.addClass...
  function J (line 59) | function J(a){function b(f){f.preventDefault();e=f.clientX;g.addClass(a....
  function D (line 60) | function D(a,b){a.domElement.style.width=b+"px";if(a.__save_row&&a.autoP...
  function z (line 61) | function z(a,b){var c={};i.each(a.__rememberedObjects,function(d,e){var ...
  function C (line 61) | function C(a,b,c){var d=document.createElement("option");d.innerHTML=b;d...
  function B (line 61) | function B(a,b){var c=a.__preset_select[a.__preset_select.selectedIndex]...
  function E (line 61) | function E(a){a.length!=
  function b (line 62) | function b(){localStorage.setItem(document.location.href+".gui",JSON.str...
  function c (line 62) | function c(){var a=d.getRoot();a.width+=1;i.defer(function(){a.width-=1})}
  function e (line 78) | function e(){h.setValue(h.__input.value)}
  function b (line 80) | function b(a,b,c,d){a.style.background="";f.each(j,function(e){a.style.c...
  function n (line 80) | function n(a){a.style.background="";a.style.cssText+="background: -moz-l...
  function o (line 81) | function o(b){q(b);a.bind(window,"mousemove",q);a.bind(window,
  function j (line 82) | function j(){a.unbind(window,"mousemove",q);a.unbind(window,"mouseup",j)}
  function g (line 82) | function g(){var a=d(this.value);a!==false?(p.__color.__state=a,p.setVal...
  function i (line 82) | function i(){a.unbind(window,"mousemove",s);a.unbind(window,"mouseup",i)}
  function q (line 82) | function q(b){b.preventDefault();var c=a.getWidth(p.__saturation_field),...
  function s (line 83) | function s(b){b.preventDefault();var c=a.getHeight(p.__hue_field),d=a.ge...
  function f (line 90) | function f(a,
  function b (line 91) | function b(a,b){Object.defineProperty(a,b,{get:function(){if(this.__stat...
  function n (line 91) | function n(b,c,e){if(b.__state.space===
  function h (line 92) | function h(b){var c=a.rgb_to_hsv(b.r,b.g,b.b);d.extend(b.__state,{s:c.s,...
  function Vec3 (line 674) | function Vec3(data) {
  function Vec4 (line 807) | function Vec4(data) {
  function Mat3 (line 861) | function Mat3(data) {
  function Mat4 (line 975) | function Mat4(data) {
  function cy (line 1545) | function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.pa...
  function cu (line 1545) | function cu(a){if(!cj[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.cs...
  function ct (line 1545) | function ct(a,b){var c={};f.each(cp.concat.apply([],cp.slice(0,b)),funct...
  function cs (line 1545) | function cs(){cq=b}
  function cr (line 1545) | function cr(){setTimeout(cs,0);return cq=f.now()}
  function ci (line 1545) | function ci(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(...
  function ch (line 1545) | function ch(){try{return new a.XMLHttpRequest}catch(b){}}
  function cb (line 1545) | function cb(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.da...
  function ca (line 1545) | function ca(a,c,d){var e=a.contents,f=a.dataTypes,g=a.responseFields,h,i...
  function b_ (line 1545) | function b_(a,b,c,d){if(f.isArray(b))f.each(b,function(b,e){c||bD.test(a...
  function b$ (line 1545) | function b$(a,c){var d,e,g=f.ajaxSettings.flatOptions||{};for(d in c)c[d...
  function bZ (line 1545) | function bZ(a,c,d,e,f,g){f=f||c.dataTypes[0],g=g||{},g[f]=!0;var h=a[f],...
  function bY (line 1545) | function bY(a){return function(b,c){typeof b!="string"&&(c=b,b="*");if(f...
  function bB (line 1545) | function bB(a,b,c){var d=b==="width"?a.offsetWidth:a.offsetHeight,e=b===...
  function bo (line 1545) | function bo(a){var b=c.createElement("div");bh.appendChild(b),b.innerHTM...
  function bn (line 1545) | function bn(a){var b=(a.nodeName||"").toLowerCase();b==="input"?bm(a):b!...
  function bm (line 1545) | function bm(a){if(a.type==="checkbox"||a.type==="radio")a.defaultChecked...
  function bl (line 1545) | function bl(a){return typeof a.getElementsByTagName!="undefined"?a.getEl...
  function bk (line 1545) | function bk(a,b){var c;b.nodeType===1&&(b.clearAttributes&&b.clearAttrib...
  function bj (line 1545) | function bj(a,b){if(b.nodeType===1&&!!f.hasData(a)){var c,d,e,g=f._data(...
  function bi (line 1545) | function bi(a,b){return f.nodeName(a,"table")?a.getElementsByTagName("tb...
  function U (line 1545) | function U(a){var b=V.split("|"),c=a.createDocumentFragment();if(c.creat...
  function T (line 1545) | function T(a,b,c){b=b||0;if(f.isFunction(b))return f.grep(a,function(a,d...
  function S (line 1545) | function S(a){return!a||!a.parentNode||a.parentNode.nodeType===11}
  function K (line 1545) | function K(){return!0}
  function J (line 1545) | function J(){return!1}
  function n (line 1545) | function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);...
  function m (line 1545) | function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))conti...
  function l (line 1545) | function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-...
  function h (line 1545) | function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c<d;...
  function J (line 1545) | function J(){if(!e.isReady){try{c.documentElement.doScroll("left")}catch...
  function a (line 1545) | function a(b,c){return new a.fn.init(b,c)}
  function m (line 1545) | function m(a){return function(b){e[a]=arguments.length>1?i.call(argument...
  function l (line 1545) | function l(a){return function(c){b[a]=arguments.length>1?i.call(argument...
  function m (line 1545) | function m(){--h||d.resolveWith(e,[e])}
  function x (line 1546) | function x(a,b,c,e,f,g){for(var h=0,i=e.length;h<i;h++){var j=e[h];if(j)...
  function w (line 1546) | function w(a,b,c,e,f,g){for(var h=0,i=e.length;h<i;h++){var j=e[h];if(j)...
  function w (line 1547) | function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.ready...
  function g (line 1547) | function g(){e.queue===!1&&f._mark(this);var b=f.extend({},e),c=this.nod...
  function h (line 1547) | function h(a,b,c){var e=b[c];f.removeData(a,c,!0),e.stop(d)}
  function h (line 1547) | function h(a){return e.step(a)}
  function ctor (line 1554) | function ctor() { this.constructor = child; }
  function CompositingControl (line 1586) | function CompositingControl(gui) {
  function Lighting (line 1608) | function Lighting(gui) {
  function PictureSettings (line 1664) | function PictureSettings(gui) {
  function SHConstants (line 1684) | function SHConstants(app, gui) {
  function _Class (line 1745) | function _Class(canvas) {
  function ctor (line 2030) | function ctor() { this.constructor = child; }
  function DeferredModel (line 2054) | function DeferredModel(gl, probes) {
  function ctor (line 2250) | function ctor() { this.constructor = child; }
  function Sun (line 2256) | function Sun(gui, orientation, elevation) {
  function Window (line 2411) | function Window(index, texture, node, x, y) {
  function Windows (line 2456) | function Windows(gl, gui, textures) {
  function DepthRender (line 2675) | function DepthRender(gl, width, height, drawable, _arg) {
  function DeferredShadowMap (line 2719) | function DeferredShadowMap(gl, _arg) {
  function LightmappedShadowMap (line 2750) | function LightmappedShadowMap(gl, _arg) {
  function AntiAlias (line 2788) | function AntiAlias(gl, gui, source) {
  function Illumination (line 2837) | function Illumination(gl, sun, lighting, model, highresmodel, normaldept...
  function ctor (line 3048) | function ctor() { this.constructor = child; }
  function BounceModel (line 3082) | function BounceModel(gl, model, probes) {
  function SSAO (line 3190) | function SSAO(gl, normaldepth) {
  function Blur (line 3235) | function Blur(gl, _arg) {
  function ctor (line 3271) | function ctor() { this.constructor = child; }
  function Materials (line 3288) | function Materials(gl) {
  function LowresModel (line 3364) | function LowresModel(gl) {
  function Model (line 3401) | function Model(gl) {
  function AABB (line 3704) | function AABB(xmin, xmax, ymin, ymax, zmin, zmax) {
  function Ray (line 3762) | function Ray(origin, direction) {
  function ctor (line 3906) | function ctor() { this.constructor = child; }
  function MouseDrag (line 3913) | function MouseDrag(which) {
  function Camera (line 3969) | function Camera(delta, near, far) {
  function GameCam (line 4028) | function GameCam(_arg) {
  function Orbit (line 4161) | function Orbit(_arg) {
  function FlyCam (line 4214) | function FlyCam(_arg) {
  function ctor (line 4743) | function ctor() { this.constructor = child; }
  function Backend (line 4747) | function Backend() {
  function Sample (line 4796) | function Sample(backend, data) {
  function Voice (line 4816) | function Voice(backend, id) {
  function HTMLAudio (line 4835) | function HTMLAudio() {
  function WebAudio (line 4880) | function WebAudio() {
  function Emitter (line 4927) | function Emitter() {
  function State (line 4970) | function State(gl) {
  function Rendernode (line 5051) | function Rendernode(gl, _arg) {
  function ctor (line 5425) | function ctor() { this.constructor = child; }
  function Plane (line 5433) | function Plane(gl, s) {
  function ctor (line 5462) | function ctor() { this.constructor = child; }
  function Model (line 5470) | function Model(gl, data) {
  function ctor (line 5494) | function ctor() { this.constructor = child; }
  function Cube (line 5521) | function Cube(gl, s) {
  function ctor (line 5542) | function ctor() { this.constructor = child; }
  function Framebuffer (line 5548) | function Framebuffer(gl) {
  function Renderbuffer (line 5613) | function Renderbuffer(gl) {
  function _Class (line 5644) | function _Class() {
  function ctor (line 5659) | function ctor() { this.constructor = child; }
  function Quad (line 5676) | function Quad(gl) {
  function ctor (line 5694) | function ctor() { this.constructor = child; }
  function Hexgrid (line 5712) | function Hexgrid(gl, xsize, ysize, width, height) {
  function Drawable (line 5767) | function Drawable() {
  function Shader (line 5883) | function Shader(gl, path, source) {
  function ctor (line 6212) | function ctor() { this.constructor = child; }
  function Sphere (line 6345) | function Sphere(gl, radius, subdivisions) {
  function ctor (line 6369) | function ctor() { this.constructor = child; }
  function Texture (line 6380) | function Texture() {
  function Texture2D (line 6467) | function Texture2D(gl, _arg) {
  function Cubemap (line 6550) | function Cubemap(gl) {
Condensed preview — 121 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,024K chars).
[
  {
    "path": "README.md",
    "chars": 660,
    "preview": "WebGL Deferred Irradiance Volumes\n=================================\n\nAn implementation of global illumination using defe"
  },
  {
    "path": "build",
    "chars": 387,
    "preview": "#!/usr/bin/env python\n\n'''\nCopy this into your bin directory for convenient building\n'''\n\nimport os, subprocess\n\nhere = "
  },
  {
    "path": "build.sh",
    "chars": 17,
    "preview": "./compile\n./pack\n"
  },
  {
    "path": "compile",
    "chars": 1665,
    "preview": "#!/usr/bin/env python\n\nimport os, sys, stat, subprocess\nfrom datetime import datetime\n\nhere = os.path.dirname(os.path.ab"
  },
  {
    "path": "extra/Stats.js",
    "chars": 3473,
    "preview": "/**\n * @author mrdoob / http://mrdoob.com/\n */\n\nvar Stats = function () {\n\n\tvar startTime = Date.now(), prevTime = start"
  },
  {
    "path": "extra/jquery.js",
    "chars": 94839,
    "preview": "/*! jQuery v1.7.2 jquery.com | jquery.org/license */\n(function(a,b){function cy(a){return f.isWindow(a)?a:a.nodeType===9"
  },
  {
    "path": "extra/loader.coffee",
    "chars": 7316,
    "preview": "fs = {}\n\nmakeURL = (blob) ->\n    return URL.createObjectURL blob\n\nmakeBlob = (data, type) ->\n    #builder = new BlobBuil"
  },
  {
    "path": "extra/loader.js",
    "chars": 9209,
    "preview": "// Generated by CoffeeScript 1.3.3\n(function() {\n  var fs, getBuffer, getJSON, isImage, makeBlob, makeURL, resolvePath;\n"
  },
  {
    "path": "extra/matrix.coffee",
    "chars": 15358,
    "preview": "pi = Math.PI\ntau = 2*pi\ndeg = 360/tau\narc = tau/360\n\nwindow.Mat3 = class Mat3\n    constructor: (@data) ->\n        @data "
  },
  {
    "path": "extra/matrix.js",
    "chars": 18820,
    "preview": "// Generated by CoffeeScript 1.3.3\n(function() {\n  var Mat3, Mat4, arc, deg, pi, tau;\n\n  pi = Math.PI;\n\n  tau = 2 * pi;\n"
  },
  {
    "path": "extra/shims.coffee",
    "chars": 1304,
    "preview": "if window.performance\n    if window.performance.now\n        now = -> window.performance.now()\n    else if window.perform"
  },
  {
    "path": "extra/shims.js",
    "chars": 1782,
    "preview": "// Generated by CoffeeScript 1.3.3\n(function() {\n  var log_count, now, start;\n\n  if (window.performance) {\n    if (windo"
  },
  {
    "path": "extra/vector.coffee",
    "chars": 2231,
    "preview": "window.Vec3 = class Vec3\n    @property 'x'\n        get: -> @data[0]\n        set: (val) -> @data[0] = val\n    @property '"
  },
  {
    "path": "extra/vector.js",
    "chars": 4223,
    "preview": "// Generated by CoffeeScript 1.3.3\n(function() {\n  var Vec3, Vec4;\n\n  window.Vec3 = Vec3 = (function() {\n\n    Vec3.prope"
  },
  {
    "path": "lib/audio.coffee",
    "chars": 2591,
    "preview": "class Backend\n    constructor: ->\n        @loading = 0\n        @handlers = []\n    \n    loaded: ->\n        if @loading =="
  },
  {
    "path": "lib/audio.js",
    "chars": 4216,
    "preview": "// Generated by CoffeeScript 1.3.3\nvar Backend, HTMLAudio, WebAudio, backend,\n  __bind = function(fn, me){ return functi"
  },
  {
    "path": "lib/camera.coffee",
    "chars": 8359,
    "preview": "keys = require 'keys'\n\nclass MouseDrag\n    constructor: (@which) ->\n        @x = 0\n        @y = 0\n\n        @lx = 0\n     "
  },
  {
    "path": "lib/camera.js",
    "chars": 11878,
    "preview": "// Generated by CoffeeScript 1.3.3\nvar Camera, FlyCam, GameCam, MouseDrag, Orbit, keys,\n  __hasProp = {}.hasOwnProperty,"
  },
  {
    "path": "lib/events.coffee",
    "chars": 471,
    "preview": "return class Emitter\n    constructor: ->\n        @handlers = {}\n\n    on: (name, callback) ->\n        handlers = @handler"
  },
  {
    "path": "lib/events.js",
    "chars": 743,
    "preview": "// Generated by CoffeeScript 1.3.3\nvar Emitter;\n\nreturn Emitter = (function() {\n\n  function Emitter() {\n    this.handler"
  },
  {
    "path": "lib/geometry.js",
    "chars": 3083,
    "preview": "// Generated by CoffeeScript 1.3.3\n\nexports.AABB = (function() {\n\n  function AABB(xmin, xmax, ymin, ymax, zmin, zmax) {\n"
  },
  {
    "path": "lib/hdr_clear.shader",
    "chars": 208,
    "preview": "vertex:\n    attribute vec2 position;\n    void main(){\n        gl_Position = vec4(position, 0.0, 1.0);\n    }\n\nfragment:\n "
  },
  {
    "path": "lib/keys.coffee",
    "chars": 904,
    "preview": "keymap = ({\n    87: 'w',\n    65: 'a',\n    83: 's',\n    68: 'd',\n    81: 'q',\n    69: 'e',\n    37: 'left',\n    39: 'right"
  },
  {
    "path": "lib/keys.js",
    "chars": 1164,
    "preview": "// Generated by CoffeeScript 1.3.3\nvar key_handlers, keymap, keys;\n\nkeymap = {\n  87: 'w',\n  65: 'a',\n  83: 's',\n  68: 'd"
  },
  {
    "path": "lib/loading.coffee",
    "chars": 1043,
    "preview": "ui = $('#ui')\nhidden = true\n\ncontainer = $('<div></div>').css\n    position: 'absolute'\n    top: '50%'\n    left: '50%'\n  "
  },
  {
    "path": "lib/loading.js",
    "chars": 1192,
    "preview": "// Generated by CoffeeScript 1.3.3\nvar bar, container, hidden, label, loading, makeBar, ui;\n\nui = $('#ui');\n\nhidden = tr"
  },
  {
    "path": "lib/rendernode.coffee",
    "chars": 7188,
    "preview": "{Framebuffer, Depthbuffer} = require 'webgl/framebuffer'\n{Texture2D, Cubemap} = require 'webgl/texture'\nQuad = require '"
  },
  {
    "path": "lib/rendernode.js",
    "chars": 10805,
    "preview": "// Generated by CoffeeScript 1.3.3\nvar Cubemap, Depthbuffer, Framebuffer, Quad, Rendernode, State, Texture2D, default_st"
  },
  {
    "path": "lib/schedule.coffee",
    "chars": 243,
    "preview": "exports.run = (callback) ->\n    last = gettime()\n\n    step = ->\n        current = gettime()\n        delta = current-last"
  },
  {
    "path": "lib/schedule.js",
    "chars": 344,
    "preview": "// Generated by CoffeeScript 1.3.3\n\nexports.run = function(callback) {\n  var last, step;\n  last = gettime();\n  step = fu"
  },
  {
    "path": "lib/webgl/cube.coffee",
    "chars": 2170,
    "preview": "return class Cube extends require('drawable')\n    attribs: ['position', 'normal', 'barycentric']\n    pointers: [\n       "
  },
  {
    "path": "lib/webgl/cube.js",
    "chars": 2088,
    "preview": "// Generated by CoffeeScript 1.3.3\nvar Cube,\n  __hasProp = {}.hasOwnProperty,\n  __extends = function(child, parent) { fo"
  },
  {
    "path": "lib/webgl/drawable.coffee",
    "chars": 1424,
    "preview": "return class Drawable\n    float_size = Float32Array.BYTES_PER_ELEMENT\n\n    constructor: () ->\n        @first = 0\n       "
  },
  {
    "path": "lib/webgl/drawable.js",
    "chars": 2371,
    "preview": "// Generated by CoffeeScript 1.3.3\nvar Drawable;\n\nreturn Drawable = (function() {\n  var float_size;\n\n  float_size = Floa"
  },
  {
    "path": "lib/webgl/framebuffer.coffee",
    "chars": 1915,
    "preview": "framebufferBinding = null\n\nexports.Framebuffer = class Framebuffer\n    constructor: (@gl) ->\n        @buffer = @gl.creat"
  },
  {
    "path": "lib/webgl/framebuffer.js",
    "chars": 3189,
    "preview": "// Generated by CoffeeScript 1.3.3\nvar Framebuffer, Renderbuffer, framebufferBinding,\n  __hasProp = {}.hasOwnProperty,\n "
  },
  {
    "path": "lib/webgl/hexgrid.coffee",
    "chars": 1715,
    "preview": "clamp = (value, left, right) ->\n    return if value < left then left else if value > right then right else value\n\nreturn"
  },
  {
    "path": "lib/webgl/hexgrid.js",
    "chars": 2443,
    "preview": "// Generated by CoffeeScript 1.3.3\nvar Hexgrid, clamp,\n  __hasProp = {}.hasOwnProperty,\n  __extends = function(child, pa"
  },
  {
    "path": "lib/webgl/model.coffee",
    "chars": 480,
    "preview": "return class Model extends require('drawable')\n    attribs: ['position', 'normal', 'texcoord']\n\n    constructor: (@gl, d"
  },
  {
    "path": "lib/webgl/model.js",
    "chars": 1024,
    "preview": "// Generated by CoffeeScript 1.3.3\nvar Model,\n  __hasProp = {}.hasOwnProperty,\n  __extends = function(child, parent) { f"
  },
  {
    "path": "lib/webgl/plane.coffee",
    "chars": 724,
    "preview": "return class Plane extends require('drawable')\n    attribs: ['position', 'normal', 'texcoord']\n\n    constructor: (@gl, s"
  },
  {
    "path": "lib/webgl/plane.js",
    "chars": 1201,
    "preview": "// Generated by CoffeeScript 1.3.3\nvar Plane,\n  __hasProp = {}.hasOwnProperty,\n  __extends = function(child, parent) { f"
  },
  {
    "path": "lib/webgl/quad.coffee",
    "chars": 346,
    "preview": "return class Quad extends require('drawable')\n    attribs: ['position']\n    pointers: [\n        {name: 'position', size:"
  },
  {
    "path": "lib/webgl/quad.js",
    "chars": 851,
    "preview": "// Generated by CoffeeScript 1.3.3\nvar Quad,\n  __hasProp = {}.hasOwnProperty,\n  __extends = function(child, parent) { fo"
  },
  {
    "path": "lib/webgl/shader.coffee",
    "chars": 6934,
    "preview": "directives = [\n    '#ifdef GL_FRAGMENT_PRECISION_HIGH',\n    'precision highp int;',\n    'precision highp float;',\n    '#"
  },
  {
    "path": "lib/webgl/shader.js",
    "chars": 9060,
    "preview": "// Generated by CoffeeScript 1.3.3\nvar Shader, directives, in_use;\n\ndirectives = ['#ifdef GL_FRAGMENT_PRECISION_HIGH', '"
  },
  {
    "path": "lib/webgl/sphere.coffee",
    "chars": 2555,
    "preview": "phi = (1+Math.sqrt(5))/2\n        \nmidp = (v1, v2) ->\n    x1 = v1[0]\n    y1 = v1[1]\n    z1 = v1[2]\n  \n    x2 = v2[0]\n    "
  },
  {
    "path": "lib/webgl/sphere.js",
    "chars": 3877,
    "preview": "// Generated by CoffeeScript 1.3.3\nvar Sphere, faces, icosahedron, midp, normalize, phi, subdivide, v1, v10, v11, v12, v"
  },
  {
    "path": "lib/webgl/texture.coffee",
    "chars": 5376,
    "preview": "{Framebuffer} = require 'framebuffer'\n\nclass Texture\n    bound = []\n    ids = 0\n\n    constructor: ->\n        @handle = @"
  },
  {
    "path": "lib/webgl/texture.js",
    "chars": 7903,
    "preview": "// Generated by CoffeeScript 1.3.3\nvar Cubemap, Framebuffer, Texture, Texture2D,\n  __hasProp = {}.hasOwnProperty,\n  __ex"
  },
  {
    "path": "lib/webgl-nuke-vendor-prefix.coffee",
    "chars": 1113,
    "preview": "if window.WebGLRenderingContext?\n    vendors = ['WEBKIT', 'MOZ', 'MS', 'O']\n    vendorRe = /^WEBKIT_(.*)|MOZ_(.*)|MS_(.*"
  },
  {
    "path": "lib/webgl-nuke-vendor-prefix.js",
    "chars": 1613,
    "preview": "// Generated by CoffeeScript 1.3.3\nvar getExtension, getSupportedExtensions, vendorRe, vendors,\n  __indexOf = [].indexOf"
  },
  {
    "path": "lib/webgl-texture-float-extension-shims.coffee",
    "chars": 13307,
    "preview": "createSourceCanvas = ->\n    canvas = document.createElement 'canvas'\n    canvas.width = 2\n    canvas.height = 2\n    ctx "
  },
  {
    "path": "lib/webgl-texture-float-extension-shims.js",
    "chars": 14033,
    "preview": "// Generated by CoffeeScript 1.3.3\nvar checkColorBuffer, checkFloatLinear, checkSupport, checkTexture, createSourceCanva"
  },
  {
    "path": "license/bsd-license",
    "chars": 1511,
    "preview": "Copyright (c) 2012, Florian Boesch <pyalot@gmail.com> http://codeflow.org/\nAll rights reserved.\n\nRedistribution and use "
  },
  {
    "path": "license/gplv2-license",
    "chars": 15099,
    "preview": "        GNU GENERAL PUBLIC LICENSE\n           Version 2, June 1991\n\n Copyright (C) 1989, 1991 Free Software Foundation, "
  },
  {
    "path": "license/gplv3-license",
    "chars": 35147,
    "preview": "                    GNU GENERAL PUBLIC LICENSE\n                       Version 3, 29 June 2007\n\n Copyright (C) 2007 Free "
  },
  {
    "path": "license/mit-license",
    "chars": 1098,
    "preview": "Copyright (c) 2012 Florian Boesch <pyalot@gmail.com>\nhttp://codeflow.com/\n\nPermission is hereby granted, free of charge,"
  },
  {
    "path": "license/readme",
    "chars": 236,
    "preview": "Copyright (c) 2012, Florian Boesch <pyalot@gmail.com> http://codeflow.org/\n\nDeferred Irradiance Volumes is licensed unde"
  },
  {
    "path": "pack",
    "chars": 4505,
    "preview": "#!/usr/bin/env python\n\nimport os, sys, struct, cjson, stat\nfrom os.path import join\n\nhere = os.path.dirname(os.path.absp"
  },
  {
    "path": "src/albedo.shader",
    "chars": 741,
    "preview": "varying vec2 vTexcoord;\nvarying vec3 vPosition, vViewPosition, vNormal;\nuniform mat4 proj, view;\nuniform mat3 view_rot;\n"
  },
  {
    "path": "src/antialias/fxaa2_0.shader",
    "chars": 2490,
    "preview": "vertex:\n    attribute vec2 position;\n\n    void main(){\n        gl_Position = vec4(position, 0.0, 1.0);\n    }\n\nfragment:\n"
  },
  {
    "path": "src/antialias/fxaa3_11.shader",
    "chars": 652,
    "preview": "vertex:\n    attribute vec2 position;\n\n    void main(){\n        gl_Position = vec4(position, 0.0, 1.0);\n    }\n\nfragment:\n"
  },
  {
    "path": "src/antialias/fxaa3_11.shaderlib",
    "chars": 86786,
    "preview": "/*============================================================================\n\n\n                    NVIDIA FXAA 3.11 by"
  },
  {
    "path": "src/antialias/fxaa3_11_preprocessed.shaderlib",
    "chars": 7301,
    "preview": "float FxaaLuma(vec4 rgba) { return rgba.y; }\nvec4 FxaaPixelShader(\n    vec2 pos\n    ,sampler2D tex\n    ,vec2 fxaaQuality"
  },
  {
    "path": "src/antialias/fxaa3_11_stripped.shaderlib",
    "chars": 41357,
    "preview": "#ifndef FXAA_PS3\n    #define FXAA_PS3 0\n#endif\n#ifndef FXAA_360\n    #define FXAA_360 0\n#endif\n#ifndef FXAA_360_OPT\n    #"
  },
  {
    "path": "src/antialias/module.coffee",
    "chars": 1022,
    "preview": "Rendernode = require '/rendernode'\nQuad = require '/webgl/quad'\n\nreturn class AntiAlias\n    constructor: (@gl, gui, @sou"
  },
  {
    "path": "src/antialias/module.js",
    "chars": 1158,
    "preview": "// Generated by CoffeeScript 1.3.3\nvar AntiAlias, Quad, Rendernode;\n\nRendernode = require('/rendernode');\n\nQuad = requir"
  },
  {
    "path": "src/application.coffee",
    "chars": 13949,
    "preview": "schedule = require 'schedule'\nloading = require 'loading'\ncamera = require 'camera'\n\nQuad = require '/webgl/quad'\nCube ="
  },
  {
    "path": "src/application.js",
    "chars": 15658,
    "preview": "// Generated by CoffeeScript 1.3.3\nvar Antialias, CompositingControl, Cube, DeferredModel, DeferredShadowMap, Illuminati"
  },
  {
    "path": "src/blur/blur.shader",
    "chars": 659,
    "preview": "vertex:\n    attribute vec2 position;\n\n    void main(){\n        gl_Position = vec4(position, 0.0, 1.0);\n    }\n\nfragment:\n"
  },
  {
    "path": "src/blur/module.coffee",
    "chars": 586,
    "preview": "Rendernode = require '/rendernode'\n\nreturn class Blur\n    constructor: (gl, {width, height, type, filter}) ->\n        ty"
  },
  {
    "path": "src/blur/module.js",
    "chars": 832,
    "preview": "// Generated by CoffeeScript 1.3.3\nvar Blur, Rendernode;\n\nRendernode = require('/rendernode');\n\nreturn Blur = (function("
  },
  {
    "path": "src/composit.shader",
    "chars": 1453,
    "preview": "vertex:\n    attribute vec2 position;\n\n    void main(){\n        gl_Position = vec4(position, 0.0, 1.0);\n    }\n\nfragment:\n"
  },
  {
    "path": "src/deferred_model.coffee",
    "chars": 773,
    "preview": "Sphere = require '/webgl/sphere'\n\nreturn class DeferredModel extends require('webgl/drawable')\n    attribs: ['position',"
  },
  {
    "path": "src/deferred_model.js",
    "chars": 1538,
    "preview": "// Generated by CoffeeScript 1.3.3\nvar DeferredModel, Sphere,\n  __hasProp = {}.hasOwnProperty,\n  __extends = function(ch"
  },
  {
    "path": "src/depth/deferred_shadow_map.shader",
    "chars": 770,
    "preview": "varying vec2 clip;\n\nvertex:\n    attribute vec2 position;\n\n    void main(){\n        clip = position;\n        gl_Position "
  },
  {
    "path": "src/depth/depth.shader",
    "chars": 510,
    "preview": "varying vec3 vViewPosition;\nuniform mat4 proj, view;\n\nvertex:\n    attribute vec3 position;\n\n    void main(){\n        vVi"
  },
  {
    "path": "src/depth/lightmap_shadow_map.shader",
    "chars": 390,
    "preview": "varying vec3 vPosition, vNormal;\n\nvertex:\n    attribute vec3 position, normal;\n    attribute vec2 texcoord;\n\n    void ma"
  },
  {
    "path": "src/depth/module.coffee",
    "chars": 3043,
    "preview": "Rendernode = require '/rendernode'\nBlur = require '/blur'\n\nexports.DepthRender = class DepthRender\n    constructor: (gl,"
  },
  {
    "path": "src/depth/module.js",
    "chars": 3704,
    "preview": "// Generated by CoffeeScript 1.3.3\nvar Blur, DeferredShadowMap, DepthRender, LightmappedShadowMap, Rendernode;\n\nRenderno"
  },
  {
    "path": "src/depth/variance.shaderlib",
    "chars": 930,
    "preview": "uniform sampler2D light_depth;\nuniform mat4 light_view, light_proj;\nuniform mat3 light_rot;\n\nfloat getOcclusion(vec2 uv,"
  },
  {
    "path": "src/direct_illumination.shader",
    "chars": 2461,
    "preview": "varying vec2 clip;\n\nvertex:\n    attribute vec2 position;\n\n    void main(){\n        clip = position;\n        gl_Position "
  },
  {
    "path": "src/dist3d.coffee",
    "chars": 2026,
    "preview": "vsub = (p1, p2) ->\n    return [\n        p1[0] - p2[0],\n        p1[1] - p2[1],\n        p1[2] - p2[2],\n    ]\n\nvadd = (p1, "
  },
  {
    "path": "src/dist3d.js",
    "chars": 2560,
    "preview": "// Generated by CoffeeScript 1.3.3\nvar cross, dot, length, sadd, slength, smul, vadd, vsub;\n\nvsub = function(p1, p2) {\n "
  },
  {
    "path": "src/global_illumination.shader",
    "chars": 2472,
    "preview": "\n/*\n    Conclusion of is that the shader is fillrate bound, not lookup bound\n\n    42 fps without GI\n    42 fps when disc"
  },
  {
    "path": "src/harmonics.shaderlib",
    "chars": 1139,
    "preview": "uniform vec2 coefficients_size;\nuniform sampler2D coefficients;\nuniform float shconst[5];\n\nvec3 getCoefficient(float ind"
  },
  {
    "path": "src/illumination/bounce.shader",
    "chars": 1084,
    "preview": "varying vec3 vPosition, vNormal;\nvarying vec4 vLightprobe;\n\nvertex:\n    attribute vec3 position, normal;\n    attribute v"
  },
  {
    "path": "src/illumination/bounce_model.coffee",
    "chars": 3496,
    "preview": "{pointTriangleDist} = require '/dist3d'\n\nreturn class BounceModel extends require('/webgl/drawable')\n    attribs: ['posi"
  },
  {
    "path": "src/illumination/bounce_model.js",
    "chars": 4366,
    "preview": "// Generated by CoffeeScript 1.3.3\nvar BounceModel, pointTriangleDist,\n  __hasProp = {}.hasOwnProperty,\n  __extends = fu"
  },
  {
    "path": "src/illumination/cube_diffuse.shader",
    "chars": 541,
    "preview": "varying vec2 vTexcoord;\nvarying vec3 vPosition;\nuniform mat4 proj, view;\n\nvertex:\n    attribute vec3 position;\n    attri"
  },
  {
    "path": "src/illumination/cubeprobe.shader",
    "chars": 365,
    "preview": "varying vec2 vTexcoord;\nvarying vec3 vPosition;\nuniform mat4 proj, view;\n\nvertex:\n    attribute vec3 position;\n    attri"
  },
  {
    "path": "src/illumination/debug.shader",
    "chars": 780,
    "preview": "varying vec3 vPosition, vViewPosition;\nuniform mat4 proj, view;\n\nvertex:\n    attribute vec3 position;\n    uniform vec3 o"
  },
  {
    "path": "src/illumination/harmonics.shader",
    "chars": 4090,
    "preview": "vertex:\n    attribute vec2 position;\n\n    void main(){\n        gl_Position = vec4(position, 0.0, 1.0);\n    }\n\nfragment:\n"
  },
  {
    "path": "src/illumination/module.coffee",
    "chars": 8528,
    "preview": "Quad = require '/webgl/quad'\nSphere = require '/webgl/sphere'\n{Texture2D} = require '/webgl/texture'\n\nRendernode = requi"
  },
  {
    "path": "src/illumination/module.js",
    "chars": 8204,
    "preview": "// Generated by CoffeeScript 1.3.3\nvar BounceModel, DepthRender, Illumination, LightmapShadowMap, Quad, Rendernode, Sphe"
  },
  {
    "path": "src/illumination/shadow.shader",
    "chars": 1556,
    "preview": "varying vec2 vTexcoord;\nvarying vec3 vPosition, vNormal;\nvarying vec3 vViewPosition;\n\nvertex:\n    attribute vec3 positio"
  },
  {
    "path": "src/illumination/transfer.shader",
    "chars": 1082,
    "preview": "vertex:\n    attribute vec2 position;\n\n    void main(){\n        gl_Position = vec4(position, 0.0, 1.0);\n    }\n\nfragment:\n"
  },
  {
    "path": "src/main.coffee",
    "chars": 5937,
    "preview": "audio = require 'audio'\nloading = require 'loading'\nShader = require 'webgl/shader'\nQuad = require 'webgl/quad'\nrequire "
  },
  {
    "path": "src/main.js",
    "chars": 5566,
    "preview": "// Generated by CoffeeScript 1.3.3\nvar Quad, Shader, audio, disableSelect, enableSelect, errorContainer, load_hooks, loa"
  },
  {
    "path": "src/model/materials.json",
    "chars": 4567,
    "preview": "[{\"specular_color\": {\"r\": 0.0, \"b\": 0.0, \"g\": 0.0}, \"specularity\": 50.0, \"diffuse_texture\": \"00_skap.jpg\", \"diffuse_colo"
  },
  {
    "path": "src/model/module.coffee",
    "chars": 8111,
    "preview": "{Texture2D} = require '/webgl/texture'\n\nMaterials = class Materials\n    createTexture: (path) ->\n        texture = @text"
  },
  {
    "path": "src/model/module.js",
    "chars": 10213,
    "preview": "// Generated by CoffeeScript 1.3.3\nvar LowresModel, Materials, Model, Texture2D,\n  __hasProp = {}.hasOwnProperty,\n  __ex"
  },
  {
    "path": "src/normaldepth.shader",
    "chars": 1471,
    "preview": "varying vec2 vTexcoord;\nvarying vec3 vPosition, vViewPosition, vNormal, vViewNormal;\nuniform mat4 proj, view;\nuniform ma"
  },
  {
    "path": "src/presets/default.json",
    "chars": 2373,
    "preview": "{\n  \"remembered\": {\n    \"Default\": {\n      \"0\": {\n        \"resolution_label\": \"1:2 default\",\n        \"show_fps\": false\n "
  },
  {
    "path": "src/presets/new.json",
    "chars": 3957,
    "preview": "{\n  \"remembered\": {\n    \"Apple Gamma\": {\n      \"1\": {\n        \"outputGamma\": 2.5,\n        \"brightness\": 1.32189781021897"
  },
  {
    "path": "src/ssao/module.coffee",
    "chars": 1061,
    "preview": "Rendernode = require '/rendernode'\nBlur = require '/blur'\n\nreturn class SSAO\n    constructor: (gl, @normaldepth) ->\n    "
  },
  {
    "path": "src/ssao/module.js",
    "chars": 1195,
    "preview": "// Generated by CoffeeScript 1.3.3\nvar Blur, Rendernode, SSAO;\n\nRendernode = require('/rendernode');\n\nBlur = require('/b"
  },
  {
    "path": "src/ssao/moments.shader",
    "chars": 620,
    "preview": "vertex:\n    attribute vec2 position;\n\n    void main(){\n        gl_Position = vec4(position, 0.0, 1.0);\n    }\n\nfragment:\n"
  },
  {
    "path": "src/ssao/ssao.shader",
    "chars": 1175,
    "preview": "vertex:\n    attribute vec2 position;\n\n    void main(){\n        gl_Position = vec4(position, 0.0, 1.0);\n    }\n\nfragment:\n"
  },
  {
    "path": "src/sun.coffee",
    "chars": 743,
    "preview": "return class Sun extends require('events')\n    constructor: (gui, @orientation=104, @elevation=60) ->\n        gui.rememb"
  },
  {
    "path": "src/sun.js",
    "chars": 1450,
    "preview": "// Generated by CoffeeScript 1.3.3\nvar Sun,\n  __bind = function(fn, me){ return function(){ return fn.apply(me, argument"
  },
  {
    "path": "src/windows/module.coffee",
    "chars": 6251,
    "preview": "Quad = require '/webgl/quad'\nRendernode = require '/rendernode'\nkeys = require '/keys'\n\nclass Window\n    constructor: (@"
  },
  {
    "path": "src/windows/module.js",
    "chars": 8026,
    "preview": "// Generated by CoffeeScript 1.3.3\nvar Quad, Rendernode, Window, Windows, keys,\n  __bind = function(fn, me){ return func"
  },
  {
    "path": "src/windows/window.shader",
    "chars": 1347,
    "preview": "varying vec2 vTexcoord, vPosition;\n\nvertex:\n    attribute vec2 position;\n    uniform vec2 size;\n    uniform vec2 offset;"
  },
  {
    "path": "www/code.js",
    "chars": 328238,
    "preview": "\nFunction.prototype.property = function(prop, desc) {\n    Object.defineProperty(this.prototype, prop, desc);\n};\n\n/**\n * "
  },
  {
    "path": "www/index.html",
    "chars": 2271,
    "preview": "<!doctype HTML>\n<html>\n    <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n    <title>Deferred Irrad"
  }
]

// ... and 4 more files (download for full content)

About this extraction

This page contains the full source code of the pyalot/webgl-deferred-irradiance-volumes GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 121 files (963.5 KB), approximately 307.8k tokens, and a symbol index with 250 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!